1 21 22 package org.apache.derby.impl.sql.compile; 23 24 import org.apache.derby.iapi.sql.compile.C_NodeTypes; 25 26 import org.apache.derby.iapi.error.StandardException; 27 28 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 29 30 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 31 import org.apache.derby.iapi.reference.ClassName; 32 33 import org.apache.derby.iapi.types.TypeId; 34 import org.apache.derby.iapi.types.DataValueDescriptor; 35 36 import org.apache.derby.iapi.services.compiler.MethodBuilder; 37 import org.apache.derby.iapi.services.compiler.LocalField; 38 39 import org.apache.derby.iapi.services.sanity.SanityManager; 40 41 import org.apache.derby.iapi.sql.compile.Optimizable; 42 43 import org.apache.derby.impl.sql.compile.ExpressionClassBuilder; 44 45 import org.apache.derby.iapi.util.JBitSet; 46 import org.apache.derby.iapi.services.classfile.VMOpcode; 47 48 import java.lang.reflect.Modifier ; 49 50 55 56 public final class InListOperatorNode extends BinaryListOperatorNode 57 { 58 private boolean isOrdered; 59 60 66 67 public void init(Object leftOperand, Object rightOperandList) 68 { 69 init(leftOperand, rightOperandList, "IN", "in"); 70 } 71 72 78 79 public String toString() 80 { 81 if (SanityManager.DEBUG) 82 { 83 return "isOrdered: " + isOrdered + "\n" + 84 super.toString(); 85 } 86 else 87 { 88 return ""; 89 } 90 } 91 92 107 public ValueNode preprocess(int numTables, 108 FromList outerFromList, 109 SubqueryList outerSubqueryList, 110 PredicateList outerPredicateList) 111 throws StandardException 112 { 113 super.preprocess(numTables, 114 outerFromList, outerSubqueryList, 115 outerPredicateList); 116 117 120 if (rightOperandList.size() == 1) 121 { 122 BinaryComparisonOperatorNode equal = 123 (BinaryComparisonOperatorNode) getNodeFactory().getNode( 124 C_NodeTypes.BINARY_EQUALS_OPERATOR_NODE, 125 leftOperand, 126 (ValueNode) rightOperandList.elementAt(0), 127 getContextManager()); 128 129 equal.bindComparisonOperator(); 130 return equal; 131 } 132 else if ((leftOperand instanceof ColumnReference) && 133 rightOperandList.containsAllConstantNodes()) 134 { 135 139 TypeId judgeTypeId = leftOperand.getTypeServices().getTypeId(); 140 DataValueDescriptor judgeODV = null; if (! rightOperandList.allSamePrecendence(judgeTypeId.typePrecedence())) 142 judgeODV = (DataValueDescriptor) judgeTypeId.getNull(); 143 144 rightOperandList.sortInAscendingOrder(judgeODV); 146 isOrdered = true; 147 148 153 ValueNode leftClone = leftOperand.getClone(); 154 ValueNode minValue = (ValueNode) rightOperandList.elementAt(0); ValueNode maxValue = (ValueNode) rightOperandList.elementAt(rightOperandList.size() - 1); 156 157 160 DataValueDescriptor minODV = 161 ((ConstantNode) minValue).getValue(); 162 DataValueDescriptor maxODV = 163 ((ConstantNode) maxValue).getValue(); 164 if ((judgeODV == null && minODV.compare(maxODV) == 0) || 165 (judgeODV != null && judgeODV.equals(minODV, maxODV).equals(true))) 166 { 167 BinaryComparisonOperatorNode equal = 168 (BinaryComparisonOperatorNode) getNodeFactory().getNode( 169 C_NodeTypes.BINARY_EQUALS_OPERATOR_NODE, 170 leftOperand, 171 minValue, 172 getContextManager()); 173 174 equal.bindComparisonOperator(); 175 return equal; 176 } 177 178 ValueNodeList vnl = (ValueNodeList) getNodeFactory().getNode( 180 C_NodeTypes.VALUE_NODE_LIST, 181 getContextManager()); 182 vnl.addValueNode(minValue); 183 vnl.addValueNode(maxValue); 184 185 BetweenOperatorNode bon = 186 (BetweenOperatorNode) getNodeFactory().getNode( 187 C_NodeTypes.BETWEEN_OPERATOR_NODE, 188 leftClone, 189 vnl, 190 getContextManager()); 191 192 201 202 203 AndNode newAnd; 204 205 newAnd = (AndNode) getNodeFactory().getNode( 206 C_NodeTypes.AND_NODE, 207 this, 208 bon.preprocess(numTables, 209 outerFromList, 210 outerSubqueryList, 211 outerPredicateList), 212 getContextManager()); 213 newAnd.postBindFixup(); 214 215 218 setTransformed(); 219 220 return newAnd; 222 } 223 else 224 { 225 return this; 226 } 227 } 228 229 245 ValueNode eliminateNots(boolean underNotNode) 246 throws StandardException 247 { 248 AndNode newAnd = null; 249 BinaryComparisonOperatorNode leftBCO; 250 BinaryComparisonOperatorNode rightBCO; 251 int listSize = rightOperandList.size(); 252 ValueNode leftSide; 253 254 if (SanityManager.DEBUG) 255 SanityManager.ASSERT(listSize > 0, 256 "rightOperandList.size() is expected to be > 0"); 257 258 if (! underNotNode) 259 { 260 return this; 261 } 262 263 266 267 275 276 277 280 ValueNode leftClone = (leftOperand instanceof ColumnReference) ? leftOperand.getClone() : leftOperand; 281 leftBCO = (BinaryComparisonOperatorNode) 282 getNodeFactory().getNode( 283 C_NodeTypes.BINARY_NOT_EQUALS_OPERATOR_NODE, 284 leftClone, 285 (ValueNode) rightOperandList.elementAt(0), 286 getContextManager()); 287 288 leftBCO.bindComparisonOperator(); 289 290 leftSide = leftBCO; 291 292 for (int elemsDone = 1; elemsDone < listSize; elemsDone++) 293 { 294 295 296 leftClone = (leftOperand instanceof ColumnReference) ? leftOperand.getClone() : leftOperand; 297 rightBCO = (BinaryComparisonOperatorNode) 298 getNodeFactory().getNode( 299 C_NodeTypes.BINARY_NOT_EQUALS_OPERATOR_NODE, 300 leftClone, 301 (ValueNode) rightOperandList.elementAt(elemsDone), 302 getContextManager()); 303 304 rightBCO.bindComparisonOperator(); 305 306 307 newAnd = (AndNode) getNodeFactory().getNode( 308 C_NodeTypes.AND_NODE, 309 leftSide, 310 rightBCO, 311 getContextManager()); 312 newAnd.postBindFixup(); 313 314 leftSide = newAnd; 315 } 316 317 return leftSide; 318 } 319 320 329 public boolean selfReference(ColumnReference cr) 330 throws StandardException 331 { 332 int size = rightOperandList.size(); 333 for (int i = 0; i < size; i++) 334 { 335 ValueNode vn = (ValueNode) rightOperandList.elementAt(i); 336 if (vn.getTablesReferenced().get(cr.getTableNumber())) 337 return true; 338 } 339 return false; 340 } 341 342 346 public double selectivity(Optimizable optTable) 347 { 348 return 0.3d; 349 } 350 351 359 360 public void generateExpression(ExpressionClassBuilder acb, 361 MethodBuilder mb) 362 throws StandardException 363 { 364 int listSize = rightOperandList.size(); 365 String resultTypeName; 366 String receiverType = ClassName.DataValueDescriptor; 367 368 String leftInterfaceType = ClassName.DataValueDescriptor; 369 String rightInterfaceType = ClassName.DataValueDescriptor + "[]"; 370 371 if (SanityManager.DEBUG) 372 { 373 SanityManager.ASSERT(listSize > 0, 374 "listSize is expected to be > 0"); 375 } 376 377 394 395 receiver = leftOperand; 396 397 398 resultTypeName = getTypeCompiler().interfaceName(); 399 400 LocalField arrayField = 402 acb.newFieldDeclaration(Modifier.PRIVATE, rightInterfaceType); 403 404 409 410 MethodBuilder cb = acb.getConstructor(); 411 cb.pushNewArray(ClassName.DataValueDescriptor, listSize); 412 cb.setField(arrayField); 413 414 415 int numConstants = 0; 416 MethodBuilder nonConstantMethod = null; 417 MethodBuilder currentConstMethod = cb; 418 for (int index = 0; index < listSize; index++) 419 { 420 MethodBuilder setArrayMethod; 421 422 if (rightOperandList.elementAt(index) instanceof ConstantNode) 423 { 424 numConstants++; 425 426 434 if(currentConstMethod.statementNumHitLimit(1)) 435 { 436 MethodBuilder genConstantMethod = acb.newGeneratedFun("void", Modifier.PRIVATE); 437 currentConstMethod.pushThis(); 438 currentConstMethod.callMethod(VMOpcode.INVOKEVIRTUAL, 439 (String ) null, 440 genConstantMethod.getName(), 441 "void", 0); 442 if(currentConstMethod != cb){ 444 currentConstMethod.methodReturn(); 445 currentConstMethod.complete(); 446 } 447 currentConstMethod = genConstantMethod; 448 } 449 setArrayMethod = currentConstMethod; 450 } else { 451 if (nonConstantMethod == null) 452 nonConstantMethod = acb.newGeneratedFun("void", Modifier.PROTECTED); 453 setArrayMethod = nonConstantMethod; 454 455 } 456 457 setArrayMethod.getField(arrayField); ((ValueNode) rightOperandList.elementAt(index)).generateExpression(acb, setArrayMethod); 459 setArrayMethod.upCast(receiverType); setArrayMethod.setArrayElement(index); 461 } 462 463 if(currentConstMethod != cb){ 465 currentConstMethod.methodReturn(); 466 currentConstMethod.complete(); 467 } 468 469 if (nonConstantMethod != null) { 470 nonConstantMethod.methodReturn(); 471 nonConstantMethod.complete(); 472 mb.pushThis(); 473 mb.callMethod(VMOpcode.INVOKEVIRTUAL, (String ) null, nonConstantMethod.getName(), "void", 0); 474 } 475 476 479 486 487 490 leftOperand.generateExpression(acb, mb); 491 mb.dup(); 492 mb.upCast(leftInterfaceType); mb.getField(arrayField); mb.push(isOrdered); mb.callMethod(VMOpcode.INVOKEINTERFACE, receiverType, methodName, resultTypeName, 3); 497 498 499 } 500 501 502 512 public void generateStartStopKey(boolean isAsc, boolean isStartKey, 513 ExpressionClassBuilder acb, 514 MethodBuilder mb) 515 throws StandardException 516 { 517 521 int leftTypeFormatId = leftOperand.getTypeId().getTypeFormatId(); 522 int leftJDBCTypeId = leftOperand.getTypeId().isUserDefinedTypeId() ? 523 leftOperand.getTypeId().getJDBCTypeId() : -1; 524 525 int listSize = rightOperandList.size(); 526 int numLoops, numValInLastLoop, currentOpnd = 0; 527 528 535 if (listSize < 5) 536 { 537 numLoops = 1; 538 numValInLastLoop = (listSize - 1) % 4 + 1; 539 } 540 else 541 { 542 numLoops = (listSize - 5) / 3 + 2; 543 numValInLastLoop = (listSize - 5) % 3 + 1; 544 } 545 546 for (int i = 0; i < numLoops; i++) 547 { 548 550 int numVals = (i == numLoops - 1) ? numValInLastLoop : 551 ((i == 0) ? 4 : 3); 552 for (int j = 0; j < numVals; j++) 553 { 554 ValueNode vn = (ValueNode) rightOperandList.elementAt(currentOpnd++); 555 vn.generateExpression(acb, mb); 556 mb.upCast(ClassName.DataValueDescriptor); 557 } 558 559 562 int numNulls = (i < numLoops - 1) ? 0 : 563 ((i == 0) ? 4 - numValInLastLoop : 3 - numValInLastLoop); 564 for (int j = 0; j < numNulls; j++) 565 mb.pushNull(ClassName.DataValueDescriptor); 566 567 569 mb.push(leftTypeFormatId); 570 mb.push(leftJDBCTypeId); 571 572 574 String methodName; 575 if ((isAsc && isStartKey) || (! isAsc && ! isStartKey)) 576 methodName = "minValue"; 577 else 578 methodName = "maxValue"; 579 580 mb.callMethod(VMOpcode.INVOKESTATIC, ClassName.BaseExpressionActivation, methodName, ClassName.DataValueDescriptor, 6); 581 582 } 583 } 584 } 585 | Popular Tags |