1 23 24 30 31 package com.sun.jdo.spi.persistence.support.sqlstore.sql.generator; 32 33 import org.netbeans.modules.dbschema.ColumnElement; 34 import org.netbeans.modules.dbschema.TableElement; 35 import com.sun.jdo.api.persistence.support.JDOFatalInternalException; 36 import com.sun.jdo.spi.persistence.support.sqlstore.ActionDesc; 37 import com.sun.jdo.spi.persistence.support.sqlstore.database.DBVendorType; 38 import com.sun.jdo.spi.persistence.support.sqlstore.model.LocalFieldDesc; 39 import com.sun.jdo.spi.persistence.support.sqlstore.sql.constraint.*; 40 import com.sun.jdo.spi.persistence.utility.I18NHelper; 41 42 import java.sql.SQLException ; 43 import java.util.ArrayList ; 44 import java.util.Iterator ; 45 import java.util.List ; 46 import java.util.ResourceBundle ; 47 48 51 public abstract class Statement extends Object implements Cloneable { 52 53 private static final Integer ONE = new Integer (1); 54 55 protected static final int OP_PREFIX_MASK = 0x001; 57 protected static final int OP_INFIX_MASK = 0x002; 59 protected static final int OP_POSTFIX_MASK = 0x004; 61 protected static final int OP_PAREN_MASK = 0x008; 63 protected static final int OP_ORDERBY_MASK = 0x010; 65 protected static final int OP_WHERE_MASK = 0x020; 67 protected static final int OP_IRREGULAR_MASK = 0x040; 69 protected static final int OP_OTHER_MASK = 0x080; 71 protected static final int OP_PARAM_MASK = 0x100; 73 protected static final int OP_BINOP_MASK = 2 * OP_PARAM_MASK | OP_WHERE_MASK | OP_INFIX_MASK; 75 protected static final int OP_FUNC_MASK = OP_PARAM_MASK | OP_PREFIX_MASK | OP_PAREN_MASK | OP_WHERE_MASK; 77 protected static final int OP_PCOUNT_MASK = 3 * OP_PARAM_MASK; 79 protected StringBuffer statementText; 80 81 private String quoteCharStart; 82 83 private String quoteCharEnd; 84 85 86 protected ArrayList columns; 87 88 Constraint constraint; 89 90 protected InputDesc inputDesc; 91 92 int action; 93 94 95 public ArrayList tableList; 96 97 protected DBVendorType vendorType; 98 99 protected ArrayList secondaryTableStatements; 100 101 104 protected final static ResourceBundle messages = I18NHelper.loadBundle( 105 "com.sun.jdo.spi.persistence.support.sqlstore.Bundle", Statement.class.getClassLoader()); 107 108 109 public Statement(DBVendorType vendorType) { 110 111 inputDesc = new InputDesc(); 112 columns = new ArrayList (); 113 constraint = new Constraint(); 114 tableList = new ArrayList (); 115 this.vendorType = vendorType; 116 117 if (vendorType.getQuoteSpecialOnly() == false) { 118 this.quoteCharStart = vendorType.getQuoteCharStart(); 120 this.quoteCharEnd = vendorType.getQuoteCharEnd(); 121 } 122 } 123 124 public void addQueryTable(QueryTable table) { 125 if (tableList.indexOf(table) == -1) { 129 tableList.add(table); 130 } 131 } 132 133 protected ColumnRef getColumnRef(ColumnElement columnElement) { 134 int size = columns.size(); 139 140 for (int i = 0; i < size; i++) { 141 ColumnRef cref = (ColumnRef) columns.get(i); 142 143 if (cref.getColumnElement() == columnElement) return cref; 144 } 145 146 return null; 147 } 148 149 protected void addColumnRef(ColumnRef columnRef) { 150 columnRef.setIndex(columns.size()+1); 151 columns.add(columnRef); 152 } 153 154 157 public void addConstraint(LocalFieldDesc lf, Object value) { 158 int operation; 159 if (value == null) { 160 operation = ActionDesc.OP_NULL; 161 } else { 162 constraint.addValue(value, lf); 163 if (lf.isPrimitiveMappedToNullableColumn() || 164 (vendorType.mapEmptyStringToNull() && lf.getType() == String .class)) { 165 operation = ActionDesc.OP_MAYBE_NULL; 169 } else { 170 operation = ActionDesc.OP_EQ; 173 } 174 } 175 constraint.addField(lf); 176 constraint.addOperation(operation); 177 } 178 179 public DBVendorType getVendorType() { 180 return vendorType; 181 } 182 183 public void appendTableText(StringBuffer text, QueryTable table) { 184 appendQuotedText(text, table.getTableDesc().getName()); 185 text.append(" t"); text.append(table.getTableIndex()); 187 } 188 189 194 protected void appendQuotedText(StringBuffer buffer, String text) { 195 buffer.append(quoteCharStart); 196 buffer.append(text); 197 buffer.append(quoteCharEnd); 198 } 199 200 205 public String getText() { 206 207 if (statementText == null) { 208 generateStatementText(); 209 } 210 211 212 return statementText.toString(); 213 } 214 215 218 protected abstract void generateStatementText(); 219 220 227 public StringBuffer processConstraints() { 228 StringBuffer whereText = new StringBuffer (); 229 List stack = constraint.getConstraints(); 230 231 while (stack.size() > 0) { 232 ConstraintNode node = (ConstraintNode) stack.get(stack.size() - 1); 233 234 if (!(node instanceof ConstraintOperation)) { 235 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 236 "core.generic.notinstanceof", node.getClass().getName(), "ConstraintOperation")); } 239 240 processRootConstraint((ConstraintOperation) node, stack, whereText); 241 } 242 243 return whereText; 244 } 245 246 protected void processRootConstraint(ConstraintOperation opNode, 247 List stack, 248 StringBuffer whereText) { 249 int op = opNode.operation; 250 int opInfo = operationFormat(op); 251 252 if ((opInfo & OP_WHERE_MASK) > 0) { 253 String constraint = getWhereText(stack); 254 if (whereText.length() > 0 && constraint.length() > 0) { 255 whereText.append(" and "); 258 } 259 whereText.append(constraint); 260 } else { 261 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 262 "sqlstore.sql.generator.statement.unexpectedconstraint", op)); } 264 } 265 266 270 public abstract QueryPlan getQueryPlan(); 271 272 283 protected String getWhereText(List stack) { 284 285 StringBuffer result = new StringBuffer (); 286 ConstraintNode node; 287 288 if (stack.size() == 0) { 289 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 290 "core.constraint.stackempty")); } 292 293 node = (ConstraintNode) stack.get(stack.size() - 1); 294 stack.remove(stack.size() - 1); 295 296 if (node instanceof ConstraintParamIndex) { 297 processConstraintParamIndex((ConstraintParamIndex) node, result); 298 } else if (node instanceof ConstraintValue) { 299 processConstraintValue((ConstraintValue) node, result); 300 } else if (node instanceof ConstraintField) { 301 processConstraintField((ConstraintField) node, result); 302 } else if (node instanceof ConstraintConstant) { 303 result.append(((ConstraintConstant) node).value.toString()); 304 } else if (node instanceof ConstraintOperation) { 305 processConstraintOperation((ConstraintOperation) node, stack, result); 306 } else { 307 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 308 "core.constraint.illegalnode", node.getClass().getName())); 310 } 311 312 return result.toString(); 313 } 314 315 protected void processConstraintParamIndex(ConstraintParamIndex node, StringBuffer result) { 316 result.append(vendorType.getParameterMarker(node.getType())); 318 Integer index = node.getIndex(); 319 inputDesc.values.add(new InputParamValue(index, getColumnElementForValueNode(node) )); 320 } 321 322 protected void processConstraintValue(ConstraintValue node, StringBuffer result) { 323 boolean generateValueInSQLStatement = false; 324 String strToAppend = "?"; 326 330 if (vendorType.isInlineNumeric()) { 331 Object value = node.getValue(); 335 if (value != null && value instanceof Number ) { 336 generateValueInSQLStatement = true; 337 strToAppend = value.toString(); 338 } 339 } 340 result.append(strToAppend); 341 342 if(!generateValueInSQLStatement) { 343 generateInputValueForConstraintValueNode(node); 345 } 346 } 347 348 protected QueryPlan getOriginalPlan(ConstraintField fieldNode) { 349 return (fieldNode.originalPlan != null) ? fieldNode.originalPlan : getQueryPlan(); 350 } 351 352 private void processConstraintField(ConstraintField fieldNode, StringBuffer result) { 353 LocalFieldDesc desc = null; 354 355 QueryPlan thePlan = getOriginalPlan(fieldNode); 356 357 if (fieldNode instanceof ConstraintFieldDesc) { 358 desc = ((ConstraintFieldDesc) fieldNode).desc; 359 } else if (fieldNode instanceof ConstraintFieldName) { 360 desc = thePlan.config.getLocalFieldDesc(((ConstraintFieldName) fieldNode).name); 361 } else { 362 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 363 "core.generic.notinstanceof", fieldNode.getClass().getName(), 365 "ConstraintFieldDesc/ConstraintFieldName")); } 367 generateColumnText(desc, thePlan, result); 368 } 369 370 381 protected void generateColumnText(LocalFieldDesc desc, QueryPlan thePlan, 382 StringBuffer sb) { 383 QueryTable table = null; 384 ColumnElement column = null; 385 Iterator iter = desc.getColumnElements(); 386 387 while (iter.hasNext() && table == null) { 388 column = (ColumnElement) iter.next(); 389 390 if (action == QueryPlan.ACT_SELECT) { 396 table = thePlan.findQueryTable(column.getDeclaringTable()); 397 } else { 398 table = findQueryTable(column.getDeclaringTable()); 399 } 400 } 401 402 if (table == null) { 403 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 404 "core.configuration.fieldnotable", desc.getName())); 406 } 407 408 if (action == QueryPlan.ACT_SELECT) { 411 sb.append("t").append(table.getTableIndex()).append("."); } 413 414 appendQuotedText(sb, column.getName().getName()); 415 } 416 417 425 protected QueryTable findQueryTable(TableElement tableElement) { 426 QueryTable table = null; 427 428 for (Iterator iter = tableList.iterator(); iter.hasNext() && table == null; ) { 429 QueryTable t = (QueryTable) iter.next(); 430 if (t.getTableDesc().getTableElement() == tableElement) { 431 table = t; 433 } 434 } 435 436 return table; 437 } 438 439 private void processConstraintOperation(ConstraintOperation opNode, 440 List stack, 441 StringBuffer result) { 442 int opCode = opNode.operation; 443 int format = operationFormat(opCode); 444 445 if ((format & OP_IRREGULAR_MASK) == 0) { 446 processFunctionOrBinaryOperation(format, opCode, stack, result); 447 } else { 448 processIrregularOperation(opNode, opCode, stack, result); 449 } 450 } 451 452 private void processFunctionOrBinaryOperation(int format, 453 int opCode, 454 List stack, 455 StringBuffer result) { 456 457 if ((format & OP_PREFIX_MASK) > 0) { 458 result.append(prefixOperator(opCode)); 459 } 460 461 if ((format & OP_PCOUNT_MASK) > 0) { 462 if ((format & OP_PAREN_MASK) > 0) { 463 result.append("("); } 465 466 result.append(getWhereText(stack)); 467 468 for (int i = 0; i < ((format & OP_PCOUNT_MASK) / OP_PARAM_MASK) - 1; i++) { 469 if ((format & OP_INFIX_MASK) > 0) { 470 result.append(infixOperator(opCode, i - 1)); 472 } else { 473 result.append(", "); } 476 477 result.append(getWhereText(stack)); 478 } 479 480 if ((format & OP_PAREN_MASK) > 0) { 481 result.append(")"); } 483 } 484 485 if ((format & OP_POSTFIX_MASK) > 0) { 486 result.append(postfixOperator(opCode)); 487 } 488 } 489 490 protected void processIrregularOperation(ConstraintOperation opNode, 491 int opCode, 492 List stack, 493 StringBuffer result) { 494 switch (opCode) { 495 case ActionDesc.OP_NULL: 496 case ActionDesc.OP_NOTNULL: 497 processNullOperation(opCode, stack, result); 498 break; 499 case ActionDesc.OP_BETWEEN: 500 if (stack.size() < 3) { 501 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 502 "core.constraint.stackempty")); } 504 505 if (!(stack.get(stack.size() - 1) instanceof ConstraintField)) { 506 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 507 "core.constraint.needfieldnode")); } else { 509 result.append(getWhereText(stack)); 510 result.append(" between "); } 512 result.append(getWhereText(stack)); 513 result.append(" and "); 514 result.append(getWhereText(stack)); 515 break; 516 case ActionDesc.OP_IN: 517 case ActionDesc.OP_NOTIN: 518 processInOperation(opCode, stack, result); 519 break; 520 case ActionDesc.OP_NOTEXISTS: 521 case ActionDesc.OP_EXISTS: 522 if (!(opNode instanceof ConstraintSubquery)) { 523 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 524 "core.generic.notinstanceof", opNode.getClass().getName(), "ConstraintSubquery")); } 527 528 ConstraintSubquery sqNode = (ConstraintSubquery) opNode; 529 530 result.append(prefixOperator(opCode)); 531 result.append("("); 533 Statement sqstmt = (Statement) sqNode.plan.statements.get(0); 534 535 result.append(sqstmt.getText()); 536 537 result.append(")"); break; 539 case ActionDesc.OP_LIKE_ESCAPE: 540 if (stack.size() < 3) { 541 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 542 "core.constraint.stackempty")); } 544 545 if (vendorType.supportsLikeEscape()) { 546 if (!(stack.get(stack.size() - 1) instanceof ConstraintField)) { 547 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 548 "core.constraint.needfieldnode")); } else { 550 result.append(getWhereText(stack)); 551 result.append(" LIKE "); } 553 result.append(getWhereText(stack)); 554 result.append(vendorType.getLeftLikeEscape()); 555 result.append(" ESCAPE "); result.append(getWhereText(stack)); 557 result.append(vendorType.getRightLikeEscape()); 558 } else { 559 throw new JDOFatalInternalException( 560 I18NHelper.getMessage(messages, 561 "sqlstore.sql.generator.statement.likeescapenotsupported")); } 563 564 break; 565 case ActionDesc.OP_SUBSTRING: 566 if (stack.size() < 3) { 567 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 568 "core.constraint.stackempty")); } 570 571 result.append(vendorType.getSubstring()); 572 result.append("("); result.append(getWhereText(stack)); 574 result.append(vendorType.getSubstringFrom()); 575 result.append(getWhereText(stack)); 576 result.append(vendorType.getSubstringFor()); 577 result.append(getWhereText(stack)); 578 result.append(")"); break; 580 case ActionDesc.OP_POSITION: 581 if (stack.size() < 2) { 582 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 583 "core.constraint.stackempty")); } 585 586 result.append(vendorType.getPosition()); 587 result.append("("); boolean swap = vendorType.isPositionSearchSource(); 589 if (swap) { 590 ConstraintNode expr = 591 (ConstraintNode)stack.remove(stack.size() - 1); 592 ConstraintNode pattern = 593 (ConstraintNode)stack.remove(stack.size() - 1); 594 stack.add(expr); 595 stack.add(pattern); 596 } 597 598 result.append(getWhereText(stack)); 599 result.append(vendorType.getPositionSep()); 600 result.append(" ").append(getWhereText(stack)); result.append(")"); break; 603 case ActionDesc.OP_POSITION_START: 604 if (stack.size() < 3) { 605 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 606 "core.constraint.stackempty")); } 608 609 boolean swapArgs = vendorType.isPositionSearchSource(); 610 boolean threeArgs = vendorType.isPositionThreeArgs(); 611 612 if (threeArgs) { 613 if (swapArgs) { 614 ConstraintNode expr = 615 (ConstraintNode)stack.remove(stack.size() - 1); 616 ConstraintNode pattern = 617 (ConstraintNode)stack.remove(stack.size() - 1); 618 stack.add(expr); 619 stack.add(pattern); 620 } 621 result.append(vendorType.getPosition()); 622 result.append("("); result.append(getWhereText(stack)); 624 result.append(vendorType.getPositionSep()); 625 result.append(" ").append(getWhereText(stack)); result.append(vendorType.getPositionSep()); 627 result.append(" ").append(getWhereText(stack)); result.append(")"); } else { ConstraintValue valueNode = 631 (ConstraintValue)stack.remove(stack.size() - 3); 632 if (valueNode != null && ONE.equals(valueNode.getValue())) { 633 stack.add(new ConstraintOperation(ActionDesc.OP_POSITION)); 634 result.append(getWhereText(stack)); 635 } else { 636 throw new JDOFatalInternalException( 637 I18NHelper.getMessage(messages, 638 "sqlstore.sql.generator.statement.positionthreeargsnotsupported")); } 640 } 641 break; 642 case ActionDesc.OP_MAYBE_NULL: 643 processMaybeNullOperation(stack, result); 644 break; 645 case ActionDesc.OP_MOD: 646 if (stack.size() < 2) { 647 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 648 "core.constraint.stackempty")); } 650 result.append(prefixOperator(opCode)); 651 result.append("("); result.append(getWhereText(stack)); 653 result.append(", "); result.append(getWhereText(stack)); 655 result.append(")"); break; 657 case ActionDesc.OP_CONCAT: 658 processConcatOperation(opCode, stack, result); 659 break; 660 661 default: 662 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 663 "core.constraint.illegalop", "" + opCode)); } 666 } 667 668 private void processConcatOperation(int opCode, List stack, 669 StringBuffer result) { 670 671 if (stack.size() < 2) { 672 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 673 "core.constraint.stackempty")); } 675 String concatCast = vendorType.getConcatCast(); 676 if (concatCast.length() != 0) { 677 result.append(concatCast); 678 result.append("( "); } 681 result.append("( "); result.append(getWhereText(stack)); 686 result.append(infixOperator(opCode, 0)); 687 result.append(getWhereText(stack)); 688 result.append(" ) "); 691 if (concatCast.length() != 0) { 692 result.append(" ) "); } 695 } 696 697 private void processMaybeNullOperation(List stack, StringBuffer result) { 698 ConstraintValue valueNode = null; 699 ConstraintField fieldNode = null; 700 701 if (stack.size() < 2) { 702 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 703 "core.constraint.stackempty")); } 705 706 if (!(stack.get(stack.size() - 1) instanceof ConstraintField)) { 707 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 708 "core.constraint.needfieldnode")); } else { 710 fieldNode = (ConstraintField) stack.get(stack.size() - 1); 711 stack.remove(stack.size() - 1); 712 } 713 714 if (!(stack.get(stack.size() - 1) instanceof ConstraintValue)) { 715 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 716 "core.constraint.needvalnode")); } else { 718 valueNode = (ConstraintValue) stack.get(stack.size() - 1); 719 stack.remove(stack.size() - 1); 720 } 721 722 Object value = valueNode.getValue(); 723 if (value instanceof String ) { 724 String v = (String ) value; 725 726 if (v.length() == 0) { 727 stack.add(fieldNode); 728 stack.add(new ConstraintOperation(ActionDesc.OP_NULL)); 729 } else { 730 stack.add(valueNode); 731 stack.add(fieldNode); 732 stack.add(new ConstraintOperation(ActionDesc.OP_EQ)); 733 } 734 } else { 735 stack.add(valueNode); 736 stack.add(fieldNode); 737 stack.add(new ConstraintOperation(ActionDesc.OP_EQ)); 738 739 boolean maybeNull = false; 750 751 if ((value instanceof Number ) && 752 ((Number ) value).doubleValue() == 0) { 753 maybeNull = true; 754 } else if ((value instanceof Boolean ) && 755 ((Boolean ) value).booleanValue() == false) { 756 maybeNull = true; 757 } else if ((value instanceof Character ) && 758 ((Character ) value).charValue() == '\0') { 759 maybeNull = true; 760 } 761 762 if (maybeNull) { 763 stack.add(fieldNode); 764 stack.add(new ConstraintOperation(ActionDesc.OP_NULL)); 765 stack.add(new ConstraintOperation(ActionDesc.OP_OR)); 766 } 767 } 768 769 if (stack.size() > 0) { 770 result.append(getWhereText(stack)); 771 } 772 } 773 774 private void processNullOperation(int opCode, List stack, StringBuffer result) { 775 String nullComparisionFunctionName = 776 vendorType.getNullComparisonFunctionName(); 777 if( nullComparisionFunctionName.length() != 0) { 778 Object nextNode = stack.get(stack.size() - 1); 781 if( nextNode != null) { 782 if ( nextNode instanceof ConstraintFieldName) { 783 ConstraintFieldName fieldNode = 784 (ConstraintFieldName) nextNode; 785 QueryPlan originalPlan = getQueryPlan(); 786 if (fieldNode.originalPlan != null) { 787 originalPlan = fieldNode.originalPlan; 788 } 789 LocalFieldDesc desc = (LocalFieldDesc) originalPlan.config.getField(fieldNode.name); 790 if ( desc.isMappedToLob() ) { 791 stack.add (new ConstraintOperation( 794 ActionDesc.OP_NULL_COMPARISION_FUNCTION) ); 795 } 796 } 797 } else { 798 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 799 "core.constraint.stackempty")); } 801 } 802 result.append (getWhereText(stack)); 803 String str = (opCode == ActionDesc.OP_NULL) ? vendorType.getIsNull() : vendorType.getIsNotNull(); 804 result.append(str); 805 } 806 807 private void processInOperation(int opCode, List stack, StringBuffer result) { 808 812 StringBuffer c = new StringBuffer (); 813 814 if (stack.size() < 2) { 815 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 816 "core.constraint.stackempty")); } 818 819 result.append("("); 822 if (!(stack.get(stack.size() - 1) instanceof ConstraintField)) { 823 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 824 "core.constraint.needfieldnode")); } else { 826 c.append(getWhereText(stack)); 828 } 829 830 while (stack.size() > 1 && (stack.get(stack.size() - 1) instanceof ConstraintField)) { 832 c.replace(0, 0, ", "); c.replace(0, 0, getWhereText(stack)); 834 } 835 result.append(c.toString()); 836 result.append(") "); if (opCode == ActionDesc.OP_NOTIN) { 838 result.append("not "); } 840 result.append("in ("); 842 843 ConstraintNode currentNode = (ConstraintNode)stack.remove(stack.size() - 1); 844 if ( ! ( currentNode instanceof ConstraintSubquery)) { 845 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 846 "core.generic.notinstanceof", currentNode.getClass().getName(), "ConstraintSubquery")); } else { 849 850 ConstraintSubquery sqnode = (ConstraintSubquery) currentNode; 851 852 Statement sqstmt = (Statement) sqnode.plan.statements.get(0); 853 result.append(sqstmt.getText()); 855 856 result.append(")"); 859 inputDesc.values.addAll(sqstmt.inputDesc.values); 861 } 862 863 877 } 878 879 887 private static ColumnElement getColumnElementForValueNode(ConstraintValue node) { 888 ColumnElement columnElement = null; 889 LocalFieldDesc field = node.getLocalField(); 890 if(field != null) { 891 columnElement = field.getPrimaryColumn(); 895 } 896 return columnElement; 897 } 898 899 903 protected void generateInputValueForConstraintValueNode(ConstraintValue node) { 904 inputDesc.values.add(new InputValue(node.getValue(), getColumnElementForValueNode(node) )); 905 } 906 907 protected String infixOperator(int operation, int position) { 909 StringBuffer result = new StringBuffer (); 919 920 switch (operation) { 921 case ActionDesc.OP_ADD: 922 result.append(" + "); break; 924 case ActionDesc.OP_AND: 925 result.append(" and "); 926 break; 927 case ActionDesc.OP_DIV: 928 result.append(" / "); break; 930 case ActionDesc.OP_EQ: 931 result.append(" = "); break; 933 case ActionDesc.OP_GE: 934 result.append(" >= "); break; 936 case ActionDesc.OP_GT: 937 result.append(" > "); break; 939 case ActionDesc.OP_LE: 940 result.append(" <= "); break; 942 case ActionDesc.OP_LT: 943 result.append(" < "); break; 945 case ActionDesc.OP_NE: 946 result.append(" != "); break; 948 case ActionDesc.OP_OR: 949 result.append(" or "); break; 951 case ActionDesc.OP_LIKE: 952 result.append(" like "); break; 954 case ActionDesc.OP_MUL: 955 result.append(" * "); break; 957 case ActionDesc.OP_SUB: 958 result.append(" - "); break; 960 case ActionDesc.OP_MOD: 961 result.append(" % "); break; 963 case ActionDesc.OP_BETWEEN: 964 if (position == 1) { 965 result.append(" between "); } else { 967 result.append(" and "); 968 } 969 break; 970 case ActionDesc.OP_CONCAT: 971 result.append(vendorType.getStringConcat()); 972 break; 973 default: 974 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 975 "core.constraint.illegalop", "" + operation)); } 978 979 return result.toString(); 980 } 981 982 983 protected int operationFormat(int operation) { 984 int format = 0; 985 switch (operation) { 986 case ActionDesc.OP_EQ: 988 case ActionDesc.OP_NE: 989 case ActionDesc.OP_GT: 990 case ActionDesc.OP_GE: 991 case ActionDesc.OP_LT: 992 case ActionDesc.OP_LE: 993 case ActionDesc.OP_AND: 994 case ActionDesc.OP_MUL: 995 case ActionDesc.OP_LIKE: 996 format = OP_BINOP_MASK; 997 break; 998 999 case ActionDesc.OP_ADD: 1001 case ActionDesc.OP_SUB: 1002 case ActionDesc.OP_DIV: 1003 case ActionDesc.OP_OR: 1004 format = OP_BINOP_MASK | OP_PAREN_MASK; 1005 break; 1006 1007 case ActionDesc.OP_ABS: 1009 case ActionDesc.OP_SQRT: 1010 case ActionDesc.OP_LENGTH: 1011 case ActionDesc.OP_LTRIM: 1012 case ActionDesc.OP_NOT: 1013 case ActionDesc.OP_NULL_COMPARISION_FUNCTION: 1014 format = OP_FUNC_MASK; 1015 break; 1016 1017 case ActionDesc.OP_BETWEEN: 1019 case ActionDesc.OP_LIKE_ESCAPE: 1020 case ActionDesc.OP_IN: 1021 case ActionDesc.OP_NOTIN: 1022 case ActionDesc.OP_NULL: 1023 case ActionDesc.OP_NOTNULL: 1024 case ActionDesc.OP_MAYBE_NULL: 1025 case ActionDesc.OP_CONCAT: 1026 case ActionDesc.OP_EQUIJOIN: 1027 format = OP_IRREGULAR_MASK | OP_WHERE_MASK; 1028 break; 1029 1030 case ActionDesc.OP_SUBSTRING: 1033 case ActionDesc.OP_POSITION: 1034 case ActionDesc.OP_POSITION_START: 1035 format = OP_IRREGULAR_MASK; 1036 break; 1037 1038 case ActionDesc.OP_NOTEXISTS: 1039 case ActionDesc.OP_EXISTS: 1040 format = OP_IRREGULAR_MASK | OP_WHERE_MASK | OP_PREFIX_MASK; 1041 break; 1042 1043 case ActionDesc.OP_MOD: 1044 format = vendorType.isModOperationUsingFunction() ? 1045 OP_IRREGULAR_MASK : OP_BINOP_MASK | OP_PAREN_MASK; 1046 break; 1047 1048 case ActionDesc.OP_DISTINCT: 1049 format = OP_OTHER_MASK; 1050 break; 1051 1052 case ActionDesc.OP_ORDERBY: 1053 case ActionDesc.OP_ORDERBY_DESC: 1054 format = OP_ORDERBY_MASK; 1055 break; 1056 1057 case ActionDesc.OP_RTRIM: 1058 case ActionDesc.OP_RTRIMFIXED: 1059 if (vendorType.isAnsiTrim()) { 1060 format = OP_WHERE_MASK | OP_PREFIX_MASK | OP_POSTFIX_MASK | OP_PARAM_MASK; 1061 } else { 1062 format = OP_FUNC_MASK; 1063 } 1064 break; 1065 1066 case ActionDesc.OP_LEFTJOIN: 1068 format = OP_IRREGULAR_MASK | OP_WHERE_MASK | OP_INFIX_MASK; 1069 format = format | OP_POSTFIX_MASK; 1070 break; 1071 case ActionDesc.OP_RIGHTJOIN: 1072 format = OP_IRREGULAR_MASK | OP_WHERE_MASK | OP_INFIX_MASK; 1073 format = format | OP_PREFIX_MASK; 1074 break; 1075 1076 default: 1077 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 1078 "core.constraint.illegalop", "" + operation)); } 1081 1082 return format; 1083 } 1084 1085 protected String postfixOperator(int operation) { 1086 StringBuffer result = new StringBuffer (); 1096 1097 switch (operation) { 1098 case ActionDesc.OP_RTRIM: 1099 result.append(vendorType.getRtrimPost()); 1100 break; 1101 case ActionDesc.OP_RTRIMFIXED: 1102 result.append(postfixOperator(ActionDesc.OP_RTRIM)); 1103 break; 1104 case ActionDesc.OP_LEFTJOIN: 1105 result.append(vendorType.getLeftJoinPost()); 1106 break; 1107 default: 1108 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 1109 "core.constraint.illegalop", "" + operation)); } 1112 1113 return result.toString(); 1114 } 1115 1116 protected String prefixOperator(int operation) { 1117 StringBuffer result = new StringBuffer (); 1127 1128 switch (operation) { 1129 case ActionDesc.OP_ABS: 1130 result.append(vendorType.getAbs()); break; 1132 case ActionDesc.OP_LENGTH: 1133 result.append(vendorType.getCharLength()); break; 1135 case ActionDesc.OP_RTRIM: 1136 result.append(vendorType.getRtrim()); 1137 break; 1138 case ActionDesc.OP_RTRIMFIXED: 1139 result.append(prefixOperator(ActionDesc.OP_RTRIM)); 1140 break; 1141 case ActionDesc.OP_NOT: 1142 result.append("not "); break; 1144 case ActionDesc.OP_SQRT: 1145 result.append(vendorType.getSqrt()); 1146 break; 1147 case ActionDesc.OP_NOTEXISTS: 1148 result.append("not exists "); break; 1150 case ActionDesc.OP_EXISTS: 1151 result.append("exists "); break; 1153 case ActionDesc.OP_NULL_COMPARISION_FUNCTION: 1154 result.append(vendorType.getNullComparisonFunctionName()); 1155 break; 1156 case ActionDesc.OP_MOD: 1157 result.append(vendorType.getModFunctionName()); break; 1159 1160 default: 1161 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 1162 "core.constraint.illegalop", "" + operation)); } 1164 1165 return result.toString(); 1166 } 1167 1168 public void addSecondaryTableStatement(Statement s) { 1169 if (s == null) return; 1170 1171 if (secondaryTableStatements == null) 1172 secondaryTableStatements = new ArrayList (); 1173 1174 secondaryTableStatements.add(s); 1175 } 1176 1177 public ArrayList getSecondaryTableStatements() { 1178 return secondaryTableStatements; 1179 } 1180 1181 public ArrayList getQueryTables() { 1182 return tableList; 1183 } 1184 1185 public ArrayList getColumnRefs() { 1186 return columns; 1187 } 1188 1189 public void setAction(int action) { 1190 this.action = action; 1191 } 1192 1193 public int getAction() { 1194 return action; 1195 } 1196 1197 public Object clone() { 1198 try { 1199 return super.clone(); 1200 } catch (CloneNotSupportedException e) { 1201 return null; 1205 } 1206 } 1207 1208 1214 public void bindInputValues(DBStatement s) throws SQLException { 1215 for (int i = 0, size = inputDesc.values.size(); i < size; i++) { 1216 InputValue inputVal = (InputValue) inputDesc.values.get(i); 1217 s.bindInputColumn(i + 1, inputVal.getValue(), 1218 inputVal.getColumnElement(), vendorType); 1219 } 1220 } 1221 1222 1226 private Object [] getInputValues() { 1227 final int size = inputDesc.values.size(); 1228 Object [] inputValues = new Object [size]; 1229 for (int i = 0; i < size; i++) { 1230 InputValue inputValue = (InputValue) inputDesc.values.get(i); 1231 inputValues[i] = inputValue.getValue(); 1232 } 1233 return inputValues; 1234 } 1235 1236 1241 public String getFormattedSQLText() { 1242 return formatSqlText(getText(), getInputValues()); 1243 } 1244 1245 1254 static protected String formatSqlText(String sqlText, Object [] input) { 1255 StringBuffer str = new StringBuffer (); 1256 1257 str.append(I18NHelper.getMessage(messages, 1258 "sqlstore.sql.generator.statement.sqlStatement") ); str.append("<").append(sqlText).append("> "); 1261 if (input != null && input.length > 0) { 1262 str.append(I18NHelper.getMessage(messages, 1263 "sqlstore.sql.generator.statement.withinputvalues")); for (int i = 0; i < input.length; i++) { 1265 if (i > 0) { 1266 str.append(", "); } 1268 Object inputValue = input[i]; 1269 if (inputValue == null) { 1270 str.append("<null>"); } else { 1272 str.append(inputValue.getClass().getName()); 1273 str.append(":"); str.append(inputValue.toString()); 1275 } 1276 } 1277 } else { 1278 str.append(I18NHelper.getMessage(messages, 1279 "sqlstore.sql.generator.statement.withnoinputvalues")); } 1281 1282 return str.toString(); 1283 } 1284 1285} 1286 | Popular Tags |