1 21 22 package org.apache.derby.impl.sql.compile; 23 24 import org.apache.derby.iapi.store.access.Qualifier; 25 26 import org.apache.derby.iapi.sql.compile.Visitable; 27 import org.apache.derby.iapi.sql.compile.Visitor; 28 29 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 30 31 import org.apache.derby.iapi.reference.SQLState; 32 import org.apache.derby.iapi.reference.ClassName; 33 import org.apache.derby.iapi.error.StandardException; 34 import org.apache.derby.iapi.services.sanity.SanityManager; 35 import org.apache.derby.iapi.services.compiler.MethodBuilder; 36 import org.apache.derby.iapi.services.compiler.LocalField; 37 import org.apache.derby.iapi.services.io.StoredFormatIds; 38 39 import org.apache.derby.iapi.types.TypeId; 40 import org.apache.derby.iapi.types.DataTypeDescriptor; 41 import org.apache.derby.iapi.types.SqlXmlUtil; 42 43 import java.lang.reflect.Modifier ; 44 import org.apache.derby.impl.sql.compile.ExpressionClassBuilder; 45 46 import org.apache.derby.iapi.util.JBitSet; 47 import org.apache.derby.iapi.services.classfile.VMOpcode; 48 49 import java.sql.Types ; 50 import java.util.Vector ; 51 52 60 61 public class UnaryOperatorNode extends ValueNode 62 { 63 String operator; 64 String methodName; 65 int operatorType; 66 67 String resultInterfaceType; 68 String receiverInterfaceType; 69 70 73 ValueNode operand; 74 75 public final static int UNARY_PLUS = 1; 76 public final static int UNARY_MINUS = 2; 77 public final static int NOT = 3; 78 public final static int IS_NULL = 4; 79 80 88 public final static int XMLPARSE_OP = 0; 89 public final static int XMLSERIALIZE_OP = 1; 90 91 94 static final String [] UnaryOperators = { 95 "xmlparse", 96 "xmlserialize" 97 }; 98 99 static final String [] UnaryMethodNames = { 100 "XMLParse", 101 "XMLSerialize" 102 }; 103 104 static final String [] UnaryResultTypes = { 105 ClassName.XMLDataValue, ClassName.StringDataValue }; 108 109 static final String [] UnaryArgTypes = { 110 ClassName.StringDataValue, ClassName.XMLDataValue }; 113 114 private Object [] additionalArgs; 117 118 private SqlXmlUtil sqlxUtil; 121 122 134 135 public void init( 136 Object operand, 137 Object operatorOrOpType, 138 Object methodNameOrAddedArgs) 139 { 140 this.operand = (ValueNode) operand; 141 if (operatorOrOpType instanceof String ) { 142 this.operator = (String ) operatorOrOpType; 145 this.methodName = (String ) methodNameOrAddedArgs; 146 this.operatorType = -1; 147 } 148 else { 149 if (SanityManager.DEBUG) { 152 SanityManager.ASSERT( 153 ((operatorOrOpType instanceof Integer ) && 154 ((methodNameOrAddedArgs == null) || 155 (methodNameOrAddedArgs instanceof Object []))), 156 "Init params in UnaryOperator node have the " + 157 "wrong type."); 158 } 159 this.operatorType = ((Integer ) operatorOrOpType).intValue(); 160 this.operator = UnaryOperators[this.operatorType]; 161 this.methodName = UnaryMethodNames[this.operatorType]; 162 this.resultInterfaceType = UnaryResultTypes[this.operatorType]; 163 this.receiverInterfaceType = UnaryArgTypes[this.operatorType]; 164 this.additionalArgs = (Object [])methodNameOrAddedArgs; 165 } 166 } 167 168 173 public void init(Object operand) 174 { 175 this.operand = (ValueNode) operand; 176 this.operatorType = -1; 177 } 178 179 184 void setOperator(String operator) 185 { 186 this.operator = operator; 187 this.operatorType = -1; 188 } 189 190 195 String getOperatorString() 196 { 197 return operator; 198 } 199 200 205 void setMethodName(String methodName) 206 { 207 this.methodName = methodName; 208 this.operatorType = -1; 209 } 210 211 217 218 public String toString() 219 { 220 if (SanityManager.DEBUG) 221 { 222 return "operator: " + operator + "\n" + 223 "methodName: " + methodName + "\n" + 224 super.toString(); 225 } 226 else 227 { 228 return ""; 229 } 230 } 231 232 238 239 public void printSubNodes(int depth) 240 { 241 if (SanityManager.DEBUG) 242 { 243 super.printSubNodes(depth); 244 245 if (operand != null) 246 { 247 printLabel(depth, "operand: "); 248 operand.treePrint(depth + 1); 249 } 250 } 251 } 252 253 258 public ValueNode getOperand() 259 { 260 return operand; 261 } 262 263 273 public ParameterNode getParameterOperand() 274 { 275 if (requiresTypeFromContext() == false) 276 return null; 277 else { 278 UnaryOperatorNode tempUON = this; 279 while (!(tempUON.getOperand() instanceof ParameterNode)) 280 tempUON = (UnaryOperatorNode)tempUON.getOperand(); 281 return (ParameterNode)(tempUON.getOperand()); 282 } 283 } 284 285 290 public void setClause(int clause) 291 { 292 super.setClause(clause); 293 294 297 if (operand != null) 298 { 299 operand.setClause(clause); 300 } 301 } 302 303 316 317 public ValueNode bindExpression( 318 FromList fromList, SubqueryList subqueryList, 319 Vector aggregateVector) 320 throws StandardException 321 { 322 return bindUnaryOperator(fromList, subqueryList, aggregateVector); 323 } 324 325 329 protected ValueNode bindUnaryOperator( 330 FromList fromList, SubqueryList subqueryList, 331 Vector aggregateVector) 332 throws StandardException 333 { 334 338 if (operand == null) 339 { 340 return this; 341 } 342 343 if (operand.requiresTypeFromContext() && ((operator.equals("-") || operator.equals("+"))) && operand.getTypeServices() == null) 345 return this; 346 347 operand = operand.bindExpression(fromList, subqueryList, 348 aggregateVector); 349 350 if (operand.requiresTypeFromContext()) 351 bindParameter(); 352 353 356 if (! (operand instanceof UntypedNullConstantNode) && 357 operand.getTypeId().userType() && 358 ! (this instanceof IsNullNode)) 359 { 360 operand = operand.genSQLJavaSQLTree(); 361 } 362 363 if (operatorType == XMLPARSE_OP) 364 bindXMLParse(); 365 else if (operatorType == XMLSERIALIZE_OP) 366 bindXMLSerialize(); 367 368 return this; 369 } 370 371 377 public void bindXMLParse() throws StandardException 378 { 379 TypeId operandType = operand.getTypeId(); 382 if (operandType != null) { 383 switch (operandType.getJDBCTypeId()) 384 { 385 case Types.CHAR: 386 case Types.VARCHAR: 387 case Types.LONGVARCHAR: 388 case Types.CLOB: 389 break; 390 default: 391 { 392 throw StandardException.newException( 393 SQLState.LANG_UNARY_FUNCTION_BAD_TYPE, 394 methodName, 395 operandType.getSQLTypeName()); 396 } 397 } 398 } 399 400 sqlxUtil = new SqlXmlUtil(); 405 406 setType(DataTypeDescriptor.getBuiltInDataTypeDescriptor( 408 StoredFormatIds.XML_TYPE_ID)); 409 } 410 411 417 public void bindXMLSerialize() throws StandardException 418 { 419 TypeId operandType; 420 421 operandType = operand.getTypeId(); 424 if ((operandType != null) && !operandType.isXMLTypeId()) 425 { 426 throw StandardException.newException( 427 SQLState.LANG_UNARY_FUNCTION_BAD_TYPE, 428 methodName, 429 operandType.getSQLTypeName()); 430 } 431 432 if (SanityManager.DEBUG) { 437 SanityManager.ASSERT( 438 ((additionalArgs != null) && (additionalArgs.length > 0)), 439 "Failed to locate target type for XMLSERIALIZE operator"); 440 } 441 442 DataTypeDescriptor targetType = 443 (DataTypeDescriptor)additionalArgs[0]; 444 445 TypeId targetTypeId = targetType.getTypeId(); 446 switch (targetTypeId.getJDBCTypeId()) 447 { 448 case Types.CHAR: 449 case Types.VARCHAR: 450 case Types.LONGVARCHAR: 451 case Types.CLOB: 452 break; 453 default: 454 { 455 throw StandardException.newException( 456 SQLState.LANG_INVALID_XMLSERIALIZE_TYPE, 457 targetTypeId.getSQLTypeName()); 458 } 459 } 460 461 setType(targetType); 464 } 465 466 481 public ValueNode preprocess(int numTables, 482 FromList outerFromList, 483 SubqueryList outerSubqueryList, 484 PredicateList outerPredicateList) 485 throws StandardException 486 { 487 if (operand != null) 488 { 489 operand = operand.preprocess(numTables, 490 outerFromList, outerSubqueryList, 491 outerPredicateList); 492 } 493 return this; 494 } 495 496 522 public boolean categorize(JBitSet referencedTabs, boolean simplePredsOnly) 523 throws StandardException 524 { 525 return (operand == null) ? 526 false : 527 operand.categorize(referencedTabs, simplePredsOnly); 528 } 529 530 538 public ValueNode remapColumnReferencesToExpressions() 539 throws StandardException 540 { 541 if (operand != null) 542 { 543 operand = operand.remapColumnReferencesToExpressions(); 544 } 545 return this; 546 } 547 548 553 public boolean isConstantExpression() 554 { 555 return (operand == null) ? true: operand.isConstantExpression(); 556 } 557 558 559 public boolean constantExpression(PredicateList whereClause) 560 { 561 return (operand == null) ? 562 true : 563 operand.constantExpression(whereClause); 564 } 565 566 569 public boolean requiresTypeFromContext() 570 { 571 if (operand == null) 572 return false; 573 else 574 return (operand.requiresTypeFromContext()); 575 } 576 577 578 585 public boolean isUnaryMinusOrPlusWithParameter() 586 { 587 if (operand !=null && operand instanceof ParameterNode && operand.requiresTypeFromContext() && 588 (operator!= null && (operator.equals("-") || operator.equals("+")))) 589 return true; 590 else 591 return false; 592 } 593 594 605 606 void bindParameter() throws StandardException 607 { 608 if (operatorType == XMLPARSE_OP) 609 { 610 637 throw StandardException.newException( 638 SQLState.LANG_XMLPARSE_UNKNOWN_PARAM_TYPE); 639 } 640 else if (operatorType == XMLSERIALIZE_OP) { 641 throw StandardException.newException( 644 SQLState.LANG_ATTEMPT_TO_BIND_XML); 645 } 646 else if (operand.getTypeServices() == null) 647 { 648 throw StandardException.newException(SQLState.LANG_UNARY_OPERAND_PARM, operator); 649 } 650 } 651 652 661 662 public void generateExpression(ExpressionClassBuilder acb, 663 MethodBuilder mb) 664 throws StandardException 665 { 666 if (operand == null) 667 return; 668 669 boolean xmlGen = (operatorType == XMLPARSE_OP) || 671 (operatorType == XMLSERIALIZE_OP); 672 673 if (xmlGen) { 674 mb.pushNewStart( 685 "org.apache.derby.impl.sql.execute.SqlXmlExecutor"); 686 mb.pushNewComplete(addXmlOpMethodParams(acb, mb)); 687 } 688 689 String resultTypeName = 690 (operatorType == -1) 691 ? getTypeCompiler().interfaceName() 692 : resultInterfaceType; 693 694 697 boolean needField = !getTypeId().isBooleanTypeId(); 698 699 String receiverType = getReceiverInterfaceName(); 700 operand.generateExpression(acb, mb); 701 mb.cast(receiverType); 702 703 if (needField) { 704 705 706 LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, resultTypeName); 707 mb.getField(field); 708 709 720 if (xmlGen) { 721 mb.callMethod(VMOpcode.INVOKEVIRTUAL, null, 722 methodName, resultTypeName, 2); 723 } 724 else { 725 mb.callMethod(VMOpcode.INVOKEINTERFACE, 726 (String ) null, methodName, resultTypeName, 1); 727 } 728 729 733 mb.putField(field); 734 } else { 735 mb.callMethod(VMOpcode.INVOKEINTERFACE, (String ) null, 736 methodName, resultTypeName, 0); 737 } 738 } 739 740 749 public String getReceiverInterfaceName() throws StandardException { 750 if (SanityManager.DEBUG) 751 { 752 SanityManager.ASSERT(operand!=null, 753 "cannot get interface without operand"); 754 } 755 756 if (operatorType != -1) 757 return receiverInterfaceType; 758 759 return operand.getTypeCompiler().interfaceName(); 760 } 761 762 776 protected int getOrderableVariantType() throws StandardException 777 { 778 782 return (operand != null) ? 783 operand.getOrderableVariantType() : 784 Qualifier.CONSTANT; 785 } 786 787 795 public Visitable accept(Visitor v) 796 throws StandardException 797 { 798 Visitable returnNode = v.visit(this); 799 800 if (v.skipChildren(this)) 801 { 802 return returnNode; 803 } 804 805 if (operand != null && !v.stopTraversal()) 806 { 807 operand = (ValueNode)operand.accept(v); 808 } 809 810 return returnNode; 811 } 812 813 819 protected int addXmlOpMethodParams(ExpressionClassBuilder acb, 820 MethodBuilder mb) throws StandardException 821 { 822 if ((operatorType != XMLPARSE_OP) && (operatorType != XMLSERIALIZE_OP)) 823 return 0; 825 826 if (operatorType == XMLSERIALIZE_OP) { 827 DataTypeDescriptor targetType = 837 (DataTypeDescriptor)additionalArgs[0]; 838 mb.push(targetType.getJDBCTypeId()); 839 mb.push(targetType.getMaximumWidth()); 840 return 2; 841 } 842 843 844 845 acb.pushThisAsActivation(mb); 849 850 mb.push(getCompilerContext().addSavedObject(sqlxUtil)); 855 856 mb.push(((Boolean )additionalArgs[0]).booleanValue()); 858 return 3; 859 } 860 861 865 protected boolean isEquivalent(ValueNode o) throws StandardException 866 { 867 if (isSameNodeType(o)) 868 { 869 UnaryOperatorNode other = (UnaryOperatorNode)o; 872 return (operator.equals(other.operator) && 873 ((operand == other.operand)|| 874 ((operand != null) && operand.isEquivalent(other.operand)))); 875 } 876 return false; 877 } 878 } 879 | Popular Tags |