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.sql.dictionary.DataDictionary; 27 import org.apache.derby.iapi.services.sanity.SanityManager; 28 import org.apache.derby.iapi.error.StandardException; 29 30 import java.util.Vector ; 31 32 public class OrNode extends BinaryLogicalOperatorNode 33 { 34 35 private boolean firstOr; 36 37 43 44 public void init(Object leftOperand, Object rightOperand) 45 { 46 super.init(leftOperand, rightOperand, "or"); 47 this.shortCircuitValue = true; 48 } 49 50 56 void setFirstOr() 57 { 58 firstOr = true; 59 } 60 61 74 75 public ValueNode bindExpression( 76 FromList fromList, SubqueryList subqueryList, 77 Vector aggregateVector) 78 throws StandardException 79 { 80 super.bindExpression(fromList, subqueryList, aggregateVector); 81 postBindFixup(); 82 return this; 83 } 84 85 100 public ValueNode preprocess(int numTables, 101 FromList outerFromList, 102 SubqueryList outerSubqueryList, 103 PredicateList outerPredicateList) 104 throws StandardException 105 { 106 super.preprocess(numTables, 107 outerFromList, outerSubqueryList, 108 outerPredicateList); 109 110 120 if (firstOr) 121 { 122 boolean convert = true; 123 ColumnReference cr = null; 124 int columnNumber = -1; 125 int tableNumber = -1; 126 127 for (ValueNode vn = this; vn instanceof OrNode; vn = ((OrNode) vn).getRightOperand()) 128 { 129 OrNode on = (OrNode) vn; 130 ValueNode left = on.getLeftOperand(); 131 132 if (!left.isRelationalOperator()) 134 { 135 convert = false; 136 break; 137 } 138 139 if (!(((RelationalOperator)left).getOperator() == RelationalOperator.EQUALS_RELOP)) 140 { 141 convert = false; 142 break; 143 } 144 145 BinaryRelationalOperatorNode beon = (BinaryRelationalOperatorNode)left; 146 147 if (beon.getLeftOperand() instanceof ColumnReference) 148 { 149 cr = (ColumnReference) beon.getLeftOperand(); 150 if (tableNumber == -1) 151 { 152 tableNumber = cr.getTableNumber(); 153 columnNumber = cr.getColumnNumber(); 154 } 155 else if (tableNumber != cr.getTableNumber() || 156 columnNumber != cr.getColumnNumber()) 157 { 158 convert = false; 159 break; 160 } 161 } 162 else if (beon.getRightOperand() instanceof ColumnReference) 163 { 164 cr = (ColumnReference) beon.getRightOperand(); 165 if (tableNumber == -1) 166 { 167 tableNumber = cr.getTableNumber(); 168 columnNumber = cr.getColumnNumber(); 169 } 170 else if (tableNumber != cr.getTableNumber() || 171 columnNumber != cr.getColumnNumber()) 172 { 173 convert = false; 174 break; 175 } 176 } 177 else 178 { 179 convert = false; 180 break; 181 } 182 } 183 184 185 if (convert) 186 { 187 ValueNodeList vnl = (ValueNodeList) getNodeFactory().getNode( 188 C_NodeTypes.VALUE_NODE_LIST, 189 getContextManager()); 190 for (ValueNode vn = this; vn instanceof OrNode; vn = ((OrNode) vn).getRightOperand()) 192 { 193 OrNode on = (OrNode) vn; 194 BinaryRelationalOperatorNode beon = (BinaryRelationalOperatorNode) on.getLeftOperand(); 195 if (beon.getLeftOperand() instanceof ColumnReference) 196 { 197 vnl.addValueNode(beon.getRightOperand()); 198 } 199 else 200 { 201 vnl.addValueNode(beon.getLeftOperand()); 202 } 203 } 204 205 InListOperatorNode ilon = 206 (InListOperatorNode) getNodeFactory().getNode( 207 C_NodeTypes.IN_LIST_OPERATOR_NODE, 208 cr, 209 vnl, 210 getContextManager()); 211 212 ilon.setType(getTypeServices()); 214 215 219 return ilon.preprocess(numTables, 220 outerFromList, outerSubqueryList, 221 outerPredicateList); 222 } 223 } 224 225 return this; 226 } 227 228 244 ValueNode eliminateNots(boolean underNotNode) 245 throws StandardException 246 { 247 leftOperand = leftOperand.eliminateNots(underNotNode); 248 rightOperand = rightOperand.eliminateNots(underNotNode); 249 if (! underNotNode) 250 { 251 return this; 252 } 253 254 255 AndNode andNode; 256 257 andNode = (AndNode) getNodeFactory().getNode( 258 C_NodeTypes.AND_NODE, 259 leftOperand, 260 rightOperand, 261 getContextManager()); 262 andNode.setType(dataTypeServices); 263 return andNode; 264 } 265 266 294 public ValueNode changeToCNF(boolean underTopAndNode) 295 throws StandardException 296 { 297 OrNode curOr = this; 298 299 302 if (rightOperand instanceof AndNode) 303 { 304 BooleanConstantNode falseNode; 305 306 falseNode = (BooleanConstantNode) getNodeFactory().getNode( 307 C_NodeTypes.BOOLEAN_CONSTANT_NODE, 308 Boolean.FALSE, 309 getContextManager()); 310 rightOperand = (ValueNode) getNodeFactory().getNode( 311 C_NodeTypes.OR_NODE, 312 rightOperand, 313 falseNode, 314 getContextManager()); 315 ((OrNode) rightOperand).postBindFixup(); 316 } 317 318 321 while (curOr.getRightOperand() instanceof OrNode) 322 { 323 curOr = (OrNode) curOr.getRightOperand(); 324 } 325 326 327 if (!(curOr.getRightOperand().isBooleanFalse())) 328 { 329 BooleanConstantNode falseNode; 330 331 falseNode = (BooleanConstantNode) getNodeFactory().getNode( 332 C_NodeTypes.BOOLEAN_CONSTANT_NODE, 333 Boolean.FALSE, 334 getContextManager()); 335 curOr.setRightOperand( 336 (ValueNode) getNodeFactory().getNode( 337 C_NodeTypes.OR_NODE, 338 curOr.getRightOperand(), 339 falseNode, 340 getContextManager())); 341 ((OrNode) curOr.getRightOperand()).postBindFixup(); 342 } 343 344 363 364 while (leftOperand instanceof OrNode) 365 { 366 ValueNode newLeft; 367 OrNode oldLeft; 368 OrNode newRight; 369 ValueNode oldRight; 370 371 372 newLeft = ((OrNode) leftOperand).getLeftOperand(); 373 oldLeft = (OrNode) leftOperand; 374 newRight = (OrNode) leftOperand; 375 oldRight = rightOperand; 376 377 378 leftOperand = newLeft; 379 rightOperand = newRight; 380 newRight.setLeftOperand(oldLeft.getRightOperand()); 381 newRight.setRightOperand(oldRight); 382 } 383 384 385 leftOperand = leftOperand.changeToCNF(false); 386 rightOperand = rightOperand.changeToCNF(false); 387 388 return this; 389 } 390 391 400 public boolean verifyChangeToCNF() 401 { 402 boolean isValid = true; 403 404 if (SanityManager.ASSERT) 405 { 406 isValid = ((rightOperand instanceof OrNode) || 407 (rightOperand.isBooleanFalse())); 408 if (rightOperand instanceof OrNode) 409 { 410 isValid = rightOperand.verifyChangeToCNF(); 411 } 412 if (leftOperand instanceof OrNode) 413 { 414 isValid = false; 415 } 416 else 417 { 418 isValid = leftOperand.verifyChangeToCNF(); 419 } 420 } 421 422 return isValid; 423 } 424 425 431 void postBindFixup() 432 throws StandardException 433 { 434 setType(resolveLogicalBinaryOperator( 435 leftOperand.getTypeServices(), 436 rightOperand.getTypeServices() 437 ) 438 ); 439 } 440 } 441 | Popular Tags |