1 21 22 package org.apache.derby.impl.sql.compile; 23 24 import org.apache.derby.iapi.services.compiler.MethodBuilder; 25 26 import org.apache.derby.iapi.services.monitor.Monitor; 27 28 import org.apache.derby.iapi.services.sanity.SanityManager; 29 30 import org.apache.derby.iapi.error.StandardException; 31 32 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 33 34 import org.apache.derby.iapi.types.TypeId; 35 36 import org.apache.derby.iapi.types.BooleanDataValue; 37 import org.apache.derby.iapi.types.DataTypeDescriptor; 38 import org.apache.derby.iapi.types.DataValueFactory; 39 40 import org.apache.derby.iapi.reference.SQLState; 41 42 import org.apache.derby.iapi.types.DataValueDescriptor; 43 import org.apache.derby.iapi.types.TypeId; 44 45 import org.apache.derby.iapi.services.loader.ClassInspector; 46 47 import org.apache.derby.impl.sql.compile.ExpressionClassBuilder; 48 49 import org.apache.derby.iapi.sql.compile.Visitable; 50 import org.apache.derby.iapi.sql.compile.Visitor; 51 import org.apache.derby.iapi.sql.compile.C_NodeTypes; 52 import org.apache.derby.iapi.reference.ClassName; 53 54 55 import org.apache.derby.iapi.util.JBitSet; 56 import org.apache.derby.iapi.services.classfile.VMOpcode; 57 58 import java.util.Vector ; 59 60 67 68 public class ConditionalNode extends ValueNode 69 { 70 ValueNode testCondition; 71 ValueNodeList thenElseList; 72 boolean thisIsNullIfNode; 75 76 82 83 public void init(Object testCondition, Object thenElseList, Object thisIsNullIfNode) 84 { 85 this.testCondition = (ValueNode) testCondition; 86 this.thenElseList = (ValueNodeList) thenElseList; 87 this.thisIsNullIfNode = ((Boolean ) thisIsNullIfNode).booleanValue(); 88 } 89 90 96 97 public void printSubNodes(int depth) 98 { 99 if (SanityManager.DEBUG) 100 { 101 super.printSubNodes(depth); 102 103 if (testCondition != null) 104 { 105 printLabel(depth, "testCondition: "); 106 testCondition.treePrint(depth + 1); 107 } 108 109 if (thenElseList != null) 110 { 111 printLabel(depth, "thenElseList: "); 112 thenElseList.treePrint(depth + 1); 113 } 114 } 115 } 116 117 122 public void setClause(int clause) 123 { 124 super.setClause(clause); 125 testCondition.setClause(clause); 126 thenElseList.setClause(clause); 127 } 128 129 142 143 public ValueNode bindExpression(FromList fromList, SubqueryList subqueryList, 144 Vector aggregateVector) 145 throws StandardException 146 { 147 testCondition = testCondition.bindExpression(fromList, 148 subqueryList, 149 aggregateVector); 150 151 if (thisIsNullIfNode) { 152 BinaryComparisonOperatorNode bcon = (BinaryComparisonOperatorNode)testCondition; 156 157 165 QueryTreeNode cast = getNodeFactory().getNode( 166 C_NodeTypes.CAST_NODE, 167 thenElseList.elementAt(0), 168 new DataTypeDescriptor( 169 bcon.getLeftOperand().getTypeServices(), true), 170 getContextManager()); 171 thenElseList.setElementAt(cast,0); 172 } 173 thenElseList.bindExpression(fromList, 174 subqueryList, 175 aggregateVector); 176 177 ValueNode thenExpression = (ValueNode) thenElseList.elementAt(0); 179 ValueNode elseExpression = (ValueNode) thenElseList.elementAt(1); 180 181 185 if (testCondition.requiresTypeFromContext()) 186 { 187 testCondition.setType( 188 new DataTypeDescriptor( 189 TypeId.BOOLEAN_ID, 190 true)); 191 } 192 else 193 { 194 if ( ! testCondition.getTypeServices().getTypeId().equals( 195 TypeId.BOOLEAN_ID)) 196 { 197 throw StandardException.newException(SQLState.LANG_CONDITIONAL_NON_BOOLEAN); 198 } 199 } 200 201 204 if (thenElseList.containsAllParameterNodes()) 205 { 206 throw StandardException.newException(SQLState.LANG_ALL_RESULT_EXPRESSIONS_PARAMS, "conditional"); 207 } 208 else if (thenElseList.containsParameterNode()) 209 { 210 213 214 DataTypeDescriptor dts; 215 ValueNode typeExpression; 216 217 if (thenExpression.requiresTypeFromContext()) 218 { 219 dts = elseExpression.getTypeServices(); 220 } 221 else 222 { 223 dts = thenExpression.getTypeServices(); 224 } 225 226 thenElseList.setParameterDescriptor(dts); 227 } 228 229 230 ClassInspector cu = getClassFactory().getClassInspector(); 231 232 238 239 if (! thenExpression.getTypeCompiler(). 242 comparable(elseExpression.getTypeId(), false, getClassFactory()) && 243 ! cu.assignableTo(thenExpression.getTypeId().getCorrespondingJavaTypeName(), 244 elseExpression.getTypeId().getCorrespondingJavaTypeName()) && 245 ! cu.assignableTo(elseExpression.getTypeId().getCorrespondingJavaTypeName(), 246 thenExpression.getTypeId().getCorrespondingJavaTypeName())) 247 { 248 throw StandardException.newException(SQLState.LANG_NOT_TYPE_COMPATIBLE, 249 thenExpression.getTypeId().getSQLTypeName(), 250 elseExpression.getTypeId().getSQLTypeName() 251 ); 252 } 253 254 258 setType(thenElseList.getDominantTypeServices()); 259 260 264 TypeId condTypeId = getTypeId(); 265 TypeId thenTypeId = ((ValueNode) thenElseList.elementAt(0)).getTypeId(); 266 TypeId elseTypeId = ((ValueNode) thenElseList.elementAt(1)).getTypeId(); 267 268 271 if (thenTypeId.typePrecedence() != condTypeId.typePrecedence()) 272 { 273 ValueNode cast = (ValueNode) getNodeFactory().getNode( 274 C_NodeTypes.CAST_NODE, 275 thenElseList.elementAt(0), 276 dataTypeServices, getContextManager()); 278 cast = cast.bindExpression(fromList, 279 subqueryList, 280 aggregateVector); 281 282 thenElseList.setElementAt(cast, 0); 283 } 284 285 else if (elseTypeId.typePrecedence() != condTypeId.typePrecedence()) 286 { 287 ValueNode cast = (ValueNode) getNodeFactory().getNode( 288 C_NodeTypes.CAST_NODE, 289 thenElseList.elementAt(1), 290 dataTypeServices, getContextManager()); 292 cast = cast.bindExpression(fromList, 293 subqueryList, 294 aggregateVector); 295 296 thenElseList.setElementAt(cast, 1); 297 } 298 299 return this; 300 } 301 302 317 public ValueNode preprocess(int numTables, 318 FromList outerFromList, 319 SubqueryList outerSubqueryList, 320 PredicateList outerPredicateList) 321 throws StandardException 322 { 323 testCondition = testCondition.preprocess(numTables, 324 outerFromList, outerSubqueryList, 325 outerPredicateList); 326 thenElseList.preprocess(numTables, 327 outerFromList, outerSubqueryList, 328 outerPredicateList); 329 return this; 330 } 331 332 357 public boolean categorize(JBitSet referencedTabs, boolean simplePredsOnly) 358 throws StandardException 359 { 360 364 if (simplePredsOnly) 365 { 366 return false; 367 } 368 369 boolean pushable; 370 371 pushable = testCondition.categorize(referencedTabs, simplePredsOnly); 372 pushable = (thenElseList.categorize(referencedTabs, simplePredsOnly) && pushable); 373 return pushable; 374 } 375 376 384 public ValueNode remapColumnReferencesToExpressions() 385 throws StandardException 386 { 387 testCondition = testCondition.remapColumnReferencesToExpressions(); 388 thenElseList = thenElseList.remapColumnReferencesToExpressions(); 389 return this; 390 } 391 392 397 public boolean isConstantExpression() 398 { 399 return (testCondition.isConstantExpression() && 400 thenElseList.isConstantExpression()); 401 } 402 403 404 public boolean constantExpression(PredicateList whereClause) 405 { 406 return (testCondition.constantExpression(whereClause) && 407 thenElseList.constantExpression(whereClause)); 408 } 409 410 426 ValueNode eliminateNots(boolean underNotNode) 427 throws StandardException 428 { 429 ValueNode thenExpression; 430 ValueNode elseExpression; 431 432 if (! underNotNode) 433 { 434 return this; 435 } 436 437 438 thenExpression = (ValueNode) thenElseList.elementAt(0); 439 elseExpression = (ValueNode) thenElseList.elementAt(1); 440 thenElseList.setElementAt(elseExpression, 0); 441 thenElseList.setElementAt(thenExpression, 1); 442 443 return this; 444 } 445 446 454 455 public void generateExpression(ExpressionClassBuilder acb, 456 MethodBuilder mb) 457 throws StandardException 458 { 459 testCondition.generateExpression(acb, mb); 460 mb.cast(ClassName.BooleanDataValue); 461 mb.push(true); 462 mb.callMethod(VMOpcode.INVOKEINTERFACE, (String ) null, "equals", "boolean", 1); 463 464 mb.conditionalIf(); 465 ((ValueNode) thenElseList.elementAt(0)).generateExpression(acb, mb); 466 mb.startElseCode(); 467 ((ValueNode) thenElseList.elementAt(1)).generateExpression(acb, mb); 468 mb.completeConditional(); 469 } 470 471 479 public Visitable accept(Visitor v) 480 throws StandardException 481 { 482 Visitable returnNode = v.visit(this); 483 484 if (v.skipChildren(this)) 485 { 486 return returnNode; 487 } 488 489 if (testCondition != null && !v.stopTraversal()) 490 { 491 testCondition = (ValueNode)testCondition.accept(v); 492 } 493 494 if (thenElseList != null && !v.stopTraversal()) 495 { 496 thenElseList = (ValueNodeList)thenElseList.accept(v); 497 } 498 499 return returnNode; 500 } 501 502 505 protected boolean isEquivalent(ValueNode o) throws StandardException 506 { 507 if (isSameNodeType(o)) 508 { 509 ConditionalNode other = (ConditionalNode)o; 510 if (thenElseList.size() == other.thenElseList.size() 511 && (testCondition.isEquivalent(other.testCondition))) 512 { 513 int sz = thenElseList.size(); 514 for (int i = 0; i < sz; i++) 515 { 516 ValueNode v1 = (ValueNode)thenElseList.elementAt(i); 517 ValueNode v2 = (ValueNode)other.thenElseList.elementAt(i); 518 if (!v1.isEquivalent(v2)) 519 { 520 return false; 521 } 522 523 } 524 return true; 525 } 526 } 527 return false; 528 } 529 } 530 | Popular Tags |