1 21 22 package org.apache.derby.impl.sql.compile; 23 24 import org.apache.derby.iapi.types.DataTypeDescriptor; 25 import org.apache.derby.iapi.types.TypeId; 26 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 27 import org.apache.derby.iapi.error.StandardException; 28 29 import org.apache.derby.iapi.sql.compile.TypeCompiler; 30 import org.apache.derby.iapi.types.DataValueFactory; 31 32 import org.apache.derby.iapi.types.SQLChar; 33 34 import org.apache.derby.iapi.services.sanity.SanityManager; 35 36 import org.apache.derby.iapi.sql.compile.CompilerContext; 37 import org.apache.derby.iapi.sql.compile.Optimizable; 38 import org.apache.derby.iapi.sql.compile.C_NodeTypes; 39 import org.apache.derby.iapi.sql.compile.NodeFactory; 40 41 import org.apache.derby.iapi.reference.SQLState; 42 43 import org.apache.derby.iapi.store.access.Qualifier; 44 45 import org.apache.derby.impl.sql.compile.ActivationClassBuilder; 46 import org.apache.derby.impl.sql.compile.ExpressionClassBuilder; 47 48 import org.apache.derby.iapi.services.compiler.MethodBuilder; 49 50 import org.apache.derby.iapi.util.JBitSet; 51 import org.apache.derby.iapi.services.i18n.MessageService; 52 53 import java.lang.reflect.Modifier ; 54 55 import java.sql.Date ; 56 import java.sql.Time ; 57 import java.sql.Timestamp ; 58 59 import java.util.Vector ; 60 61 67 68 public abstract class ValueNode extends QueryTreeNode 69 { 70 public static final int IN_UNKNOWN_CLAUSE = 0; 71 public static final int IN_SELECT_LIST = 1; 72 public static final int IN_WHERE_CLAUSE = 2; 73 public static final int IN_HAVING_CLAUSE = 3; 74 75 protected DataTypeDescriptor dataTypeServices; 76 private TypeId typeId; 77 private TypeCompiler typeCompiler; 78 protected int clause = IN_UNKNOWN_CLAUSE; 79 80 boolean transformed; 82 83 90 public ValueNode() 91 { 92 } 93 94 106 107 public void init( 108 Object typeId, 109 Object precision, 110 Object scale, 111 Object isNullable, 112 Object maximumWidth) 113 throws StandardException 114 { 115 setType( 116 new DataTypeDescriptor( 117 (TypeId) typeId, 118 ((Integer ) precision).intValue(), 119 ((Integer ) scale).intValue(), 120 ((Boolean ) isNullable).booleanValue(), 121 ((Integer ) maximumWidth).intValue() 122 ) 123 ); 124 } 125 126 138 139 ValueNode( 140 Object tcf, 141 Object typeId, 142 Object isNullable, 143 Object maximumWidth) 144 throws StandardException 145 { 146 setType(new DataTypeDescriptor( 147 (TypeId) typeId, 148 ((Boolean ) isNullable).booleanValue(), 149 ((Integer ) maximumWidth).intValue() 150 ) 151 ); 152 } 153 154 155 161 162 public String toString() 163 { 164 if (SanityManager.DEBUG) 165 { 166 return "dataTypeServices: " + 167 ( ( dataTypeServices != null) ? 168 dataTypeServices.toString() : "null" ) + "\n" + 169 "clause: " + clause + "\n" + 170 super.toString(); 171 } 172 else 173 { 174 return ""; 175 } 176 } 177 178 184 public DataTypeDescriptor getTypeServices() throws StandardException 185 { 186 return dataTypeServices; 187 } 188 189 195 public TypeId getTypeId() throws StandardException 196 { 197 return typeId; 198 } 199 200 201 204 protected final DataValueFactory getDataValueFactory() { 205 return getLanguageConnectionContext().getDataValueFactory(); 206 } 207 208 214 public TypeCompiler getTypeCompiler() throws StandardException 215 { 216 if (typeCompiler == null) 217 { 218 222 typeCompiler = getTypeCompiler(getTypeId()); 223 } 224 225 return typeCompiler; 226 } 227 228 235 236 public void setType(DataTypeDescriptor dataTypeServices) throws StandardException 237 { 238 this.dataTypeServices = dataTypeServices; 239 240 241 if (dataTypeServices == null) 242 typeId = null; 243 else 244 typeId = dataTypeServices.getTypeId(); 245 246 typeCompiler = null; 248 } 249 250 251 256 257 public ResultColumn getSourceResultColumn() 258 { 259 if (SanityManager.DEBUG) 260 SanityManager.ASSERT(false, 261 "getSourceResultColumn() not expected to be called for this node - " + 262 getClass().toString()); 263 return null; 264 } 265 266 271 public int getClause() 272 { 273 return clause; 274 } 275 276 281 public void setClause(int clause) 282 { 283 this.clause = clause; 284 } 285 286 292 void setTransformed() 293 { 294 transformed = true; 295 } 296 297 302 boolean getTransformed() 303 { 304 return transformed; 305 } 306 307 308 public ValueNode bindExpression( 309 FromList fromList, SubqueryList subqueryList, 310 Vector aggregateVector) 311 throws StandardException 312 { 313 return bindExpression(fromList, subqueryList, aggregateVector,false); 314 } 315 316 317 330 331 public ValueNode bindExpression( 332 FromList fromList, SubqueryList subqueryList, 333 Vector aggregateVector, boolean forQueryRewrite) 334 throws StandardException 335 { 336 343 if (SanityManager.DEBUG) 344 { 345 SanityManager.ASSERT(false, 346 "bindExpression() not expected to be called on a " + 347 this.getClass().toString()); 348 } 349 350 return this; 351 } 352 353 363 public ValueNode genSQLJavaSQLTree() 364 throws StandardException 365 { 366 if (SanityManager.DEBUG) 367 { 368 SanityManager.ASSERT(typeId != null, 369 "genSQLJavaSQLTree() only expected to be called on a bound node"); 370 SanityManager.ASSERT(typeId.userType(), 371 "genSQLJavaSQLTree() only expected to be called on user types"); 372 } 373 374 JavaValueNode stjvn = (JavaValueNode) getNodeFactory().getNode( 375 C_NodeTypes.SQL_TO_JAVA_VALUE_NODE, 376 this, 377 getContextManager()); 378 379 ValueNode jtsvn = (ValueNode) getNodeFactory().getNode( 380 C_NodeTypes.JAVA_TO_SQL_VALUE_NODE, 381 stjvn, 382 getContextManager()); 383 jtsvn.setType(DataTypeDescriptor.getSQLDataTypeDescriptor(stjvn.getJavaTypeName())); 384 return jtsvn; 385 } 386 387 402 public ValueNode preprocess(int numTables, 403 FromList outerFromList, 404 SubqueryList outerSubqueryList, 405 PredicateList outerPredicateList) 406 throws StandardException 407 { 408 return this; 409 } 410 411 427 ValueNode eliminateNots(boolean underNotNode) 428 throws StandardException 429 { 430 if (! underNotNode) 431 { 432 return this; 433 } 434 435 436 if (SanityManager.DEBUG) 437 SanityManager.ASSERT( 438 dataTypeServices.getTypeId().equals( 439 TypeId.BOOLEAN_ID), 440 "Node's type (" + 441 dataTypeServices.getTypeId().getSQLTypeName() + 442 ") is expected to be boolean"); 443 444 445 return genEqualsFalseTree(); 446 } 447 448 456 public ValueNode genEqualsFalseTree() 457 throws StandardException 458 { 459 BinaryRelationalOperatorNode equalsNode; 460 BooleanConstantNode falseNode; 461 boolean nullableResult; 462 NodeFactory nodeFactory = getNodeFactory(); 463 464 falseNode = (BooleanConstantNode) nodeFactory.getNode( 465 C_NodeTypes.BOOLEAN_CONSTANT_NODE, 466 Boolean.FALSE, 467 getContextManager()); 468 equalsNode = (BinaryRelationalOperatorNode) 469 nodeFactory.getNode( 470 C_NodeTypes.BINARY_EQUALS_OPERATOR_NODE, 471 this, 472 falseNode, 473 getContextManager()); 474 nullableResult = dataTypeServices.isNullable(); 475 equalsNode.setType(new DataTypeDescriptor( 476 TypeId.BOOLEAN_ID, 477 nullableResult) 478 ); 479 return equalsNode; 480 } 481 482 489 public ValueNode genIsNullTree() 490 throws StandardException 491 { 492 IsNullNode isNullNode; 493 494 isNullNode = (IsNullNode) 495 getNodeFactory().getNode( 496 C_NodeTypes.IS_NULL_NODE, 497 this, 498 getContextManager()); 499 isNullNode.setType(new DataTypeDescriptor( 500 TypeId.BOOLEAN_ID, 501 false) 502 ); 503 return isNullNode; 504 } 505 506 513 boolean verifyEliminateNots() 514 { 515 if (SanityManager.ASSERT) 516 { 517 return (! (this instanceof NotNode)); 518 } 519 else 520 { 521 return true; 522 } 523 } 524 525 534 public ValueNode putAndsOnTop() 535 throws StandardException 536 { 537 NodeFactory nodeFactory = getNodeFactory(); 538 539 QueryTreeNode trueNode = nodeFactory.getNode( 540 C_NodeTypes.BOOLEAN_CONSTANT_NODE, 541 Boolean.TRUE, 542 getContextManager()); 543 AndNode andNode = (AndNode) nodeFactory.getNode( 544 C_NodeTypes.AND_NODE, 545 this, 546 trueNode, 547 getContextManager()); 548 andNode.postBindFixup(); 549 return andNode; 550 } 551 552 558 public boolean verifyPutAndsOnTop() 559 { 560 return true; 561 } 562 563 591 public ValueNode changeToCNF(boolean underTopAndNode) 592 throws StandardException 593 { 594 return this; 595 } 596 597 606 public boolean verifyChangeToCNF() 607 { 608 return true; 609 } 610 611 637 public boolean categorize(JBitSet referencedTabs, boolean simplePredsOnly) 638 throws StandardException 639 { 640 return true; 641 } 642 643 658 public String getSchemaName() throws StandardException 659 { 660 return null; 661 } 662 663 678 public String getTableName() 679 { 680 return null; 681 } 682 683 686 public boolean updatableByCursor() 687 { 688 return false; 689 } 690 691 697 public String getColumnName() 698 { 699 return null; 700 } 701 702 709 JBitSet getTablesReferenced() 710 throws StandardException 711 { 712 ReferencedTablesVisitor rtv = new ReferencedTablesVisitor(new JBitSet(0)); 713 accept(rtv); 714 return rtv.getTableMap(); 715 } 716 717 722 public boolean isCloneable() 723 { 724 return false; 725 } 726 727 734 public ValueNode getClone() throws StandardException 735 { 736 if (SanityManager.DEBUG) 737 { 738 SanityManager.ASSERT(false, 739 "getClone() not expected to be called for " + 740 getClass().getName()); 741 } 742 return null; 743 } 744 745 751 public void copyFields(ValueNode oldVN) throws StandardException 752 { 753 dataTypeServices = oldVN.getTypeServices(); 754 typeId = oldVN.getTypeId(); 755 } 756 757 765 public ValueNode remapColumnReferencesToExpressions() throws StandardException 766 { 767 return this; 768 } 769 770 775 public boolean isConstantExpression() 776 { 777 return false; 778 } 779 780 788 public boolean constantExpression(PredicateList whereClause) 789 { 790 return false; 791 } 792 793 805 public void checkReliability( String fragmentType, int fragmentBitMask ) 806 throws StandardException 807 { 808 if ( ( getCompilerContext().getReliability() & fragmentBitMask ) != 0 ) 810 { 811 throwReliabilityException( fragmentType ); 812 } 813 } 814 815 827 public void checkReliability( int fragmentBitMask, String fragmentType ) 828 throws StandardException 829 { 830 if ( ( getCompilerContext().getReliability() & fragmentBitMask ) != 0 ) 832 { 833 String fragmentTypeTxt = MessageService.getTextMessage( fragmentType ); 834 throwReliabilityException( fragmentTypeTxt ); 835 } 836 } 837 838 844 private void throwReliabilityException( String fragmentType ) throws StandardException 845 { 846 String sqlState; 847 850 if (getCompilerContext().getReliability() == CompilerContext.DEFAULT_RESTRICTION) 851 { 852 sqlState = SQLState.LANG_INVALID_DEFAULT_DEFINITION; 853 } 854 else 855 { 856 sqlState = SQLState.LANG_UNRELIABLE_QUERY_FRAGMENT; 857 } 858 throw StandardException.newException(sqlState, fragmentType); 859 } 860 861 874 protected int getOrderableVariantType() throws StandardException 875 { 876 return Qualifier.VARIANT; 878 } 879 880 881 889 public ValueNode checkIsBoolean() 890 throws StandardException 891 { 892 ValueNode whereClause = this; 893 894 903 TypeId whereTypeId = whereClause.getTypeId(); 904 905 908 if (whereTypeId.userType()) 909 { 910 whereClause = whereClause.genSQLJavaSQLTree(); 911 whereTypeId = whereClause.getTypeId(); 912 } 913 914 if (! whereTypeId.equals(TypeId.BOOLEAN_ID)) 915 { 916 throw StandardException.newException(SQLState.LANG_NON_BOOLEAN_WHERE_CLAUSE, 917 whereTypeId.getSQLTypeName() 918 ); 919 } 920 921 return whereClause; 922 } 923 924 936 Object getConstantValueAsObject() 937 throws StandardException 938 { 939 return null; 940 } 941 942 951 952 962 963 protected final void generate(ActivationClassBuilder acb, 964 MethodBuilder mb) 965 throws StandardException 966 { 967 generateExpression( acb, mb ); 968 } 969 970 980 public void generateFilter(ExpressionClassBuilder ecb, 981 MethodBuilder mb) 982 throws StandardException 983 { 984 generateExpression( ecb, mb ); 985 } 986 987 988 992 public double selectivity(Optimizable optTable) 993 throws StandardException 994 { 995 if (transformed) 997 { 998 return 1.0; 999 } 1000 else 1001 { 1002 return 0.5d; 1003 } 1004 } 1005 1006 1028 void checkTopPredicatesForEqualsConditions( 1029 int tableNumber, boolean[] eqOuterCols, int[] tableNumbers, 1030 JBitSet[] tableColMap, boolean resultColTable) 1031 throws StandardException 1032 { 1033 for (ValueNode whereWalker = this; whereWalker instanceof AndNode; 1034 whereWalker = ((AndNode) whereWalker).getRightOperand()) 1035 { 1036 AndNode and = (AndNode) whereWalker; 1038 1039 if (!and.getLeftOperand().isRelationalOperator() || 1040 !(((RelationalOperator)(and.getLeftOperand())).getOperator() == RelationalOperator.EQUALS_RELOP)) 1041 { 1042 continue; 1043 } 1044 1045 BinaryRelationalOperatorNode beon = 1046 (BinaryRelationalOperatorNode) and.getLeftOperand(); 1047 ValueNode left = beon.getLeftOperand(); 1048 ValueNode right = beon.getRightOperand(); 1049 int resultTable = 0; 1050 if (resultColTable) 1051 { 1052 for ( ; resultTable < tableNumbers.length; resultTable++) 1053 { 1054 if (tableNumbers[resultTable] == tableNumber) 1055 break; 1056 } 1057 } 1058 else 1059 resultTable = -1; 1060 1061 1062 if ((left instanceof ColumnReference) && 1063 ((ColumnReference) left).getTableNumber() == tableNumber) 1064 { 1065 updateMaps(tableColMap, eqOuterCols, tableNumbers, tableNumber, 1066 resultTable, right, left); 1067 } 1068 else if ((right instanceof ColumnReference) && 1069 ((ColumnReference) right).getTableNumber() == tableNumber) 1070 { 1071 updateMaps(tableColMap, eqOuterCols, tableNumbers, tableNumber, 1072 resultTable, left, right); 1073 } 1074 } 1075 } 1076 1077 1082 boolean isBooleanTrue() 1083 { 1084 return false; 1085 } 1086 1087 1092 boolean isBooleanFalse() 1093 { 1094 return false; 1095 } 1096 1097 1107 1108 public void generateExpression(ExpressionClassBuilder acb, 1109 MethodBuilder mb) 1110 throws StandardException 1111 { 1112 if (SanityManager.DEBUG) 1113 SanityManager.ASSERT(false, "Code generation for this type of ValueNode is unimplemented"); 1114 } 1115 1116 1142 private void updateMaps(JBitSet[] tableColMap, boolean[] eqOuterCols, 1143 int[] tableNumbers, int tableNumber, int resultTable, 1144 ValueNode arg1, ValueNode arg2) 1145 throws StandardException 1146 { 1147 1154 if ((arg1 instanceof ConstantNode) || (arg1.requiresTypeFromContext())) 1155 { 1156 setValueCols(tableColMap, eqOuterCols, 1157 ((ColumnReference) arg2).getColumnNumber(), resultTable); 1158 } 1159 else if((arg1 instanceof ColumnReference && 1160 ((ColumnReference) arg1).getTableNumber() != tableNumber)) 1161 { 1162 1163 int otherTN = ((ColumnReference) arg1).getTableNumber(); 1164 int index = 0; 1165 int colNumber = ((ColumnReference) arg2).getColumnNumber(); 1166 1167 for ( ; index < tableNumbers.length; index++) 1168 { 1169 if (otherTN == tableNumbers[index]) 1170 { 1171 break; 1172 } 1173 } 1174 1175 if (index == tableNumbers.length) 1176 { 1177 setValueCols(tableColMap, eqOuterCols, colNumber, resultTable); 1178 } 1179 else if (tableColMap != null) 1180 { 1181 tableColMap[index].set(colNumber); 1182 } 1183 1184 } 1185 else 1186 { 1187 1188 JBitSet referencedTables = arg1.getTablesReferenced(); 1189 1190 int index = 0; 1191 int colNumber = ((ColumnReference) arg2).getColumnNumber(); 1192 for ( ; index < tableNumbers.length; index++) 1193 { 1194 if (referencedTables.get(tableNumbers[index])) 1195 { 1196 break; 1197 } 1198 } 1199 1200 if (index == tableNumbers.length) 1201 { 1202 setValueCols(tableColMap, eqOuterCols, colNumber, resultTable); 1203 } 1204 else if (tableColMap != null && !referencedTables.get(tableNumber)) 1205 { 1206 tableColMap[index].set(colNumber); 1207 } 1208 } 1209 } 1210 1243 private void setValueCols(JBitSet[] tableColMap, boolean[] eqOuterCols, 1244 int colReference, int resultTable) 1245 { 1246 if (eqOuterCols != null) 1247 eqOuterCols[colReference] = true; 1248 1249 if (tableColMap != null) 1250 { 1251 if (resultTable == -1) 1252 { 1253 for (int i = 0; i < tableColMap.length; i++) 1254 tableColMap[i].set(colReference); 1255 } 1256 else 1257 tableColMap[resultTable].set(colReference); 1258 } 1259 } 1260 1261 1270 public boolean isRelationalOperator() 1271 { 1272 return false; 1273 } 1274 1275 1280 public boolean isBinaryEqualsOperatorNode() 1281 { 1282 return false; 1283 } 1284 1285 1304 public boolean optimizableEqualityNode(Optimizable optTable, 1305 int columnNumber, 1306 boolean isNullOkay) 1307 throws StandardException 1308 { 1309 return false; 1310 } 1311 1312 1318 public boolean requiresTypeFromContext() 1319 { 1320 return false; 1321 } 1322 1323 1328 public boolean isParameterNode() 1329 { 1330 return false; 1331 } 1332 1333 1382 protected abstract boolean isEquivalent(ValueNode other) 1383 throws StandardException; 1384 1385 1393 protected final boolean isSameNodeType(ValueNode other) 1394 { 1395 if (other != null) { 1396 return other.getNodeType() == getNodeType(); 1397 } 1398 return false; 1399 } 1400 1401} 1402 | Popular Tags |