1 22 package org.jboss.ejb.plugins.cmp.jdbc; 23 24 import java.io.StringReader ; 25 import java.util.ArrayList ; 26 import java.util.List ; 27 import java.util.Set ; 28 import java.util.HashSet ; 29 import java.util.Map ; 30 import java.util.HashMap ; 31 import java.util.Iterator ; 32 33 import org.jboss.ejb.plugins.cmp.ejbql.*; 34 import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCFieldBridge; 35 import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCAbstractEntityBridge; 36 import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCAbstractCMRFieldBridge; 37 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCReadAheadMetaData; 38 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCTypeMappingMetaData; 39 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCRelationMetaData; 40 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCFunctionMappingMetaData; 41 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCQueryMetaData; 42 import org.jboss.ejb.EntityPersistenceStore; 43 import org.jboss.logging.Logger; 44 45 51 public final class EJBQLToSQL92Compiler 52 implements QLCompiler, JBossQLParserVisitor 53 { 54 private static final Logger log = Logger.getLogger(EJBQLToSQL92Compiler.class); 55 56 private final Catalog catalog; 58 private Class returnType; 59 private Class [] parameterTypes; 60 private JDBCReadAheadMetaData readAhead; 61 62 private AliasManager aliasManager; 64 private Map joinPaths = new HashMap (); 65 private Map identifierToTable = new HashMap (); 66 private Set joinedAliases = new HashSet (); 67 68 private JDBCTypeMappingMetaData typeMapping; 70 private JDBCTypeFactory typeFactory; 71 72 private boolean forceDistinct; 74 private String sql; 75 private int offsetParam; 76 private int offsetValue; 77 private int limitParam; 78 private int limitValue; 79 private JDBCEntityPersistenceStore selectManager; 80 private Object selectObject; 81 private List inputParameters = new ArrayList (); 82 83 private List leftJoinCMRList = new ArrayList (); 84 private StringBuffer onFindCMRJoin; 85 86 private boolean countCompositePk; 87 private boolean selectDistinct; 88 89 public EJBQLToSQL92Compiler(Catalog catalog) 90 { 91 this.catalog = catalog; 92 } 93 94 public void compileEJBQL(String ejbql, Class returnType, Class [] parameterTypes, JDBCQueryMetaData metadata) 95 throws Exception 96 { 97 reset(); 99 100 this.returnType = returnType; 102 this.parameterTypes = parameterTypes; 103 this.readAhead = metadata.getReadAhead(); 104 105 EJBQLParser parser = new EJBQLParser(new StringReader ("")); 107 108 try 109 { 110 ASTEJBQL ejbqlNode = parser.parse(catalog, parameterTypes, ejbql); 112 113 sql = ejbqlNode.jjtAccept(this, new StringBuffer ()).toString(); 115 } 116 catch(Exception e) 117 { 118 reset(); 120 throw e; 121 } 122 catch(Error e) 123 { 124 reset(); 126 throw e; 127 } 128 } 129 130 public void compileJBossQL(String ejbql, Class returnType, Class [] parameterTypes, JDBCQueryMetaData metadata) 131 throws Exception 132 { 133 reset(); 135 136 this.returnType = returnType; 138 this.parameterTypes = parameterTypes; 139 this.readAhead = metadata.getReadAhead(); 140 141 JBossQLParser parser = new JBossQLParser(new StringReader ("")); 143 144 try 145 { 146 ASTEJBQL ejbqlNode = parser.parse(catalog, parameterTypes, ejbql); 148 149 sql = ejbqlNode.jjtAccept(this, new StringBuffer ()).toString(); 151 152 if(log.isTraceEnabled()) 153 { 154 log.trace("ejbql: " + ejbql); 155 log.trace("sql: " + sql); 156 } 157 } 158 catch(Exception e) 159 { 160 reset(); 162 throw e; 163 } 164 catch(Error e) 165 { 166 reset(); 168 throw e; 169 } 170 } 171 172 public String getSQL() 173 { 174 return sql; 175 } 176 177 public int getOffsetValue() 178 { 179 return offsetValue; 180 } 181 182 public int getOffsetParam() 183 { 184 return offsetParam; 185 } 186 187 public int getLimitValue() 188 { 189 return limitValue; 190 } 191 192 public int getLimitParam() 193 { 194 return limitParam; 195 } 196 197 public boolean isSelectEntity() 198 { 199 return selectObject instanceof JDBCAbstractEntityBridge; 200 } 201 202 public JDBCAbstractEntityBridge getSelectEntity() 203 { 204 return (JDBCAbstractEntityBridge) selectObject; 205 } 206 207 public boolean isSelectField() 208 { 209 boolean result; 210 if(selectObject instanceof JDBCFieldBridge) 211 { 212 JDBCFieldBridge field = (JDBCFieldBridge) selectObject; 213 result = field.isCMPField(); 214 } 215 else 216 { 217 result = false; 218 } 219 return result; 220 } 221 222 public JDBCFieldBridge getSelectField() 223 { 224 return (JDBCFieldBridge) selectObject; 225 } 226 227 public SelectFunction getSelectFunction() 228 { 229 return (SelectFunction) selectObject; 230 } 231 232 public EntityPersistenceStore getStoreManager() 233 { 234 return selectManager; 235 } 236 237 public List getInputParameters() 238 { 239 return inputParameters; 240 } 241 242 public List getLeftJoinCMRList() 243 { 244 return leftJoinCMRList; 245 } 246 247 public boolean isSelectDistinct() 248 { 249 return selectDistinct; 250 } 251 252 public Object visit(SimpleNode node, Object data) 253 { 254 throw new RuntimeException ("Internal error: Found unknown node type in " + 255 "EJB-QL abstract syntax tree: node=" + node); 256 } 257 258 public Object visit(ASTEJBQL node, Object data) 259 { 260 Node selectNode = node.jjtGetChild(0); 261 Node fromNode = node.jjtGetChild(1); 262 263 StringBuffer selectClause = new StringBuffer (50); 265 selectNode.jjtAccept(this, selectClause); 266 267 StringBuffer whereClause = null; 268 StringBuffer orderByClause = null; 269 for(int i = 2; i < node.jjtGetNumChildren(); ++i) 270 { 271 Node childNode = node.jjtGetChild(i); 272 if(childNode instanceof ASTWhere) 273 { 274 whereClause = new StringBuffer (20); 275 childNode.jjtAccept(this, whereClause); 276 } 277 else if(childNode instanceof ASTOrderBy) 278 { 279 orderByClause = new StringBuffer (); 280 childNode.jjtAccept(this, orderByClause); 281 } 282 else if(childNode instanceof ASTLimitOffset) 283 { 284 childNode.jjtAccept(this, null); 285 } 286 } 287 288 StringBuffer fromClause = new StringBuffer (30); 290 fromNode.jjtAccept(this, fromClause); 291 292 for(Iterator iter = identifierToTable.entrySet().iterator(); iter.hasNext();) 294 { 295 final Map.Entry entry = (Map.Entry ) iter.next(); 296 final String identifier = (String ) entry.getKey(); 297 final String table = (String ) entry.getValue(); 298 final String alias = aliasManager.getAlias(identifier); 299 300 fromClause.append(table).append(' ').append(alias); 301 join(alias, fromClause); 302 303 if(iter.hasNext()) 304 { 305 fromClause.append(SQLUtil.COMMA); 306 } 307 } 308 309 selectDistinct = ((ASTSelect) selectNode).distinct || returnType == Set .class || forceDistinct; 310 311 StringBuffer sql = (StringBuffer ) data; 313 if(selectManager.getMetaData().hasRowLocking() && !(selectObject instanceof SelectFunction)) 314 { 315 JDBCFunctionMappingMetaData rowLockingTemplate = typeMapping.getRowLockingTemplate(); 316 if(rowLockingTemplate == null) 317 { 318 throw new IllegalStateException ("Row locking template is not defined for given mapping: " + typeMapping.getName()); 319 } 320 321 boolean distinct = selectDistinct; 322 323 Object args[] = new Object []{ 324 distinct ? SQLUtil.DISTINCT + selectClause : selectClause.toString(), 325 fromClause, 326 whereClause == null || whereClause.length() == 0 ? null : whereClause, 327 orderByClause == null || orderByClause.length() == 0 ? null : orderByClause 328 }; 329 rowLockingTemplate.getFunctionSql(args, sql); 330 } 331 else 332 { 333 sql.append(SQLUtil.SELECT); 334 if(selectDistinct) 335 { 336 sql.append(SQLUtil.DISTINCT); 337 } 338 sql.append(selectClause) 339 .append(SQLUtil.FROM) 340 .append(fromClause); 341 342 if(whereClause != null && whereClause.length() > 0) 343 { 344 sql.append(SQLUtil.WHERE).append(whereClause); 345 } 346 347 if(orderByClause != null && orderByClause.length() > 0) 348 { 349 sql.append(SQLUtil.ORDERBY).append(orderByClause); 350 } 351 } 352 353 if(countCompositePk) 354 { 355 sql.insert(0, "SELECT COUNT(*) FROM (").append(") t_count"); 356 } 357 358 return data; 359 } 360 361 public Object visit(ASTOrderBy node, Object data) 362 { 363 StringBuffer buf = (StringBuffer ) data; 364 node.jjtGetChild(0).jjtAccept(this, data); 365 for(int i = 1; i < node.jjtGetNumChildren(); i++) 366 { 367 buf.append(SQLUtil.COMMA); 368 node.jjtGetChild(i).jjtAccept(this, data); 369 } 370 return data; 371 } 372 373 public Object visit(ASTOrderByPath node, Object data) 374 { 375 StringBuffer buf = (StringBuffer ) data; 376 node.jjtGetChild(0).jjtAccept(this, data); 377 if(node.ascending) 378 { 379 buf.append(SQLUtil.ASC); 380 } 381 else 382 { 383 buf.append(SQLUtil.DESC); 384 } 385 return data; 386 } 387 388 public Object visit(ASTLimitOffset node, Object data) 389 { 390 int child = 0; 391 if(node.hasOffset) 392 { 393 Node offsetNode = node.jjtGetChild(child++); 394 if(offsetNode instanceof ASTParameter) 395 { 396 ASTParameter param = (ASTParameter) offsetNode; 397 Class parameterType = getParameterType(param.number); 398 if(int.class != parameterType && Integer .class != parameterType) 399 { 400 throw new IllegalStateException ("OFFSET parameter must be an int"); 401 } 402 offsetParam = param.number; 403 } 404 else 405 { 406 ASTExactNumericLiteral param = (ASTExactNumericLiteral) offsetNode; 407 offsetValue = (int) param.value; 408 } 409 } 410 411 if(node.hasLimit) 412 { 413 Node limitNode = node.jjtGetChild(child); 414 if(limitNode instanceof ASTParameter) 415 { 416 ASTParameter param = (ASTParameter) limitNode; 417 Class parameterType = getParameterType(param.number); 418 if(int.class != parameterType && Integer .class != parameterType) 419 { 420 throw new IllegalStateException ("LIMIT parameter must be an int"); 421 } 422 limitParam = param.number; 423 } 424 else 425 { 426 ASTExactNumericLiteral param = (ASTExactNumericLiteral) limitNode; 427 limitValue = (int) param.value; 428 } 429 } 430 return data; 431 } 432 433 public Object visit(ASTSelect select, Object data) 434 { 435 StringBuffer sql = (StringBuffer ) data; 436 437 final Node child0 = select.jjtGetChild(0); 438 final ASTPath path; 439 if(child0 instanceof ASTPath) 440 { 441 path = (ASTPath) child0; 442 443 if(path.isCMPField()) 444 { 445 JDBCFieldBridge selectField = (JDBCFieldBridge) path.getCMPField(); 447 selectManager = selectField.getManager(); 448 selectObject = selectField; 449 setTypeFactory(selectManager.getJDBCTypeFactory()); 450 451 addInnerJoinPath(path); 454 455 String alias = aliasManager.getAlias(path.getPath(path.size() - 2)); 456 SQLUtil.getColumnNamesClause(selectField, alias, sql); 457 } 458 else 459 { 460 JDBCAbstractEntityBridge selectEntity = (JDBCAbstractEntityBridge) path.getEntity(); 461 selectManager = selectEntity.getManager(); 462 selectObject = selectEntity; 463 setTypeFactory(selectEntity.getManager().getJDBCTypeFactory()); 464 465 final String alias = aliasManager.getAlias(path.getPath()); 466 if(select.distinct) 467 { 468 SQLUtil.getSearchableColumnNamesClause(selectEntity.getTableFields(), alias, sql); 469 } 470 else 471 { 472 SQLUtil.getColumnNamesClause(selectEntity.getTableFields(), alias, sql); 473 } 474 475 488 489 addLeftJoinPath(path); 490 } 491 } 492 else 493 { 494 path = getPathFromChildren(child0); 496 497 if(path == null) 498 { 499 throw new IllegalStateException ("The function in SELECT clause does not contain a path expression."); 500 } 501 502 if(path.isCMPField()) 503 { 504 JDBCFieldBridge selectField = (JDBCFieldBridge) path.getCMPField(); 505 selectManager = selectField.getManager(); 506 setTypeFactory(selectManager.getJDBCTypeFactory()); 507 } 508 else if(path.isCMRField()) 509 { 510 JDBCFieldBridge cmrField = (JDBCFieldBridge) path.getCMRField(); 511 selectManager = cmrField.getManager(); 512 setTypeFactory(selectManager.getJDBCTypeFactory()); 513 addLeftJoinPath(path); 514 } 515 else 516 { 517 final JDBCAbstractEntityBridge entity = (JDBCAbstractEntityBridge) path.getEntity(); 518 selectManager = entity.getManager(); 519 setTypeFactory(selectManager.getJDBCTypeFactory()); 520 addLeftJoinPath(path); 521 } 522 523 selectObject = child0; 524 child0.jjtAccept(this, data); 525 } 526 527 return data; 528 } 529 530 public Object visit(ASTWhere node, Object data) 531 { 532 node.jjtGetChild(0).jjtAccept(this, data); 533 return data; 534 } 535 536 public Object visit(ASTOr node, Object data) 537 { 538 StringBuffer buf = (StringBuffer ) data; 539 node.jjtGetChild(0).jjtAccept(this, data); 540 for(int i = 1; i < node.jjtGetNumChildren(); ++i) 541 { 542 buf.append(SQLUtil.OR); 543 node.jjtGetChild(i).jjtAccept(this, data); 544 } 545 return data; 546 } 547 548 public Object visit(ASTWhereConditionalTerm node, Object data) 549 { 550 for(int i = 0; i < node.jjtGetNumChildren(); ++i) 551 { 552 node.jjtGetChild(i).jjtAccept(this, data); 553 } 554 return data; 555 } 556 557 public Object visit(ASTAnd node, Object data) 558 { 559 StringBuffer buf = (StringBuffer ) data; 560 node.jjtGetChild(0).jjtAccept(this, data); 561 for(int i = 1; i < node.jjtGetNumChildren(); i++) 562 { 563 buf.append(SQLUtil.AND); 564 node.jjtGetChild(i).jjtAccept(this, data); 565 } 566 return data; 567 } 568 569 public Object visit(ASTNot node, Object data) 570 { 571 StringBuffer buf = (StringBuffer ) data; 572 buf.append(SQLUtil.NOT); 573 node.jjtGetChild(0).jjtAccept(this, data); 574 return data; 575 } 576 577 public Object visit(ASTConditionalParenthetical node, Object data) 578 { 579 StringBuffer buf = (StringBuffer ) data; 580 buf.append('('); 581 node.jjtGetChild(0).jjtAccept(this, data); 582 buf.append(')'); 583 return data; 584 } 585 586 public Object visit(ASTBetween node, Object data) 587 { 588 StringBuffer buf = (StringBuffer ) data; 589 node.jjtGetChild(0).jjtAccept(this, data); 590 if(node.not) 591 { 592 buf.append(SQLUtil.NOT); 593 } 594 buf.append(SQLUtil.BETWEEN); 595 node.jjtGetChild(1).jjtAccept(this, data); 596 buf.append(SQLUtil.AND); 597 node.jjtGetChild(2).jjtAccept(this, data); 598 return data; 599 } 600 601 public Object visit(ASTIn node, Object data) 602 { 603 StringBuffer buf = (StringBuffer ) data; 604 node.jjtGetChild(0).jjtAccept(this, data); 605 if(node.not) 606 { 607 buf.append(SQLUtil.NOT); 608 } 609 buf.append(SQLUtil.IN).append('('); 610 node.jjtGetChild(1).jjtAccept(this, data); 611 for(int i = 2; i < node.jjtGetNumChildren(); i++) 612 { 613 buf.append(SQLUtil.COMMA); 614 node.jjtGetChild(i).jjtAccept(this, data); 615 } 616 buf.append(')'); 617 return data; 618 } 619 620 public Object visit(ASTLike node, Object data) 621 { 622 StringBuffer buf = (StringBuffer ) data; 623 node.jjtGetChild(0).jjtAccept(this, data); 624 if(node.not) 625 { 626 buf.append(SQLUtil.NOT); 627 } 628 buf.append(SQLUtil.LIKE); 629 node.jjtGetChild(1).jjtAccept(this, data); 630 if(node.jjtGetNumChildren() == 3) 631 { 632 buf.append(SQLUtil.ESCAPE); 633 node.jjtGetChild(2).jjtAccept(this, data); 634 } 635 return data; 636 } 637 638 public Object visit(ASTNullComparison node, Object data) 639 { 640 StringBuffer sql = (StringBuffer ) data; 641 642 final Node child0 = node.jjtGetChild(0); 643 if(child0 instanceof ASTPath) 644 { 645 ASTPath path = (ASTPath) child0; 646 addLeftJoinPath(path); 647 648 JDBCFieldBridge field = (JDBCFieldBridge) path.getField(); 649 650 if(field instanceof JDBCAbstractCMRFieldBridge) 651 { 652 JDBCAbstractCMRFieldBridge cmrField = (JDBCAbstractCMRFieldBridge)field; 653 final String alias; 654 final JDBCFieldBridge[] keyFields; 655 656 if(cmrField.hasForeignKey()) 657 { 658 alias = aliasManager.getAlias(path.getPath(path.size() - 2)); 659 keyFields = cmrField.getForeignKeyFields(); 660 } 661 else 662 { 663 alias = aliasManager.getAlias(path.getPath()); 664 if(cmrField.getMetaData().getRelationMetaData().isTableMappingStyle()) 665 { 666 keyFields = cmrField.getRelatedCMRField().getEntity().getPrimaryKeyFields(); 667 } 668 else 669 { 670 keyFields = cmrField.getRelatedCMRField().getForeignKeyFields(); 671 } 672 } 673 674 SQLUtil.getIsNullClause(node.not, keyFields, alias, sql); 675 } 676 else 677 { 678 String alias = aliasManager.getAlias(path.getPath(path.size() - 2)); 679 SQLUtil.getIsNullClause(node.not, field, alias, sql); 680 } 681 } 682 else if(child0 instanceof ASTParameter) 683 { 684 ASTParameter param = (ASTParameter) child0; 685 Class type = getParameterType(param.number); 686 687 QueryParameter queryParam = new QueryParameter(param.number - 1, typeFactory.getJDBCType(type)); 688 inputParameters.add(queryParam); 689 690 sql.append("? IS "); 691 if(node.not) 692 { 693 sql.append(SQLUtil.NOT); 694 } 695 sql.append(SQLUtil.NULL); 696 } 697 else 698 { 699 throw new IllegalStateException ("Unexpected node in IS NULL clause: " + node); 700 } 701 702 return data; 703 } 704 705 public Object visit(ASTIsEmpty node, Object data) 706 { 707 ASTPath path = (ASTPath) node.jjtGetChild(0); 708 if(!path.isCMRField()) 709 { 710 throw new IllegalStateException ("IS EMPTY can be applied only to collection valued CMR field."); 711 } 712 713 addLeftJoinPath(path); 714 715 StringBuffer sql = (StringBuffer ) data; 716 JDBCAbstractCMRFieldBridge cmrField = (JDBCAbstractCMRFieldBridge) path.getCMRField(); 717 JDBCAbstractEntityBridge relatedEntity = (JDBCAbstractEntityBridge) cmrField.getRelatedEntity(); 718 String alias = aliasManager.getAlias(path.getPath()); 719 SQLUtil.getIsNullClause(node.not, relatedEntity.getPrimaryKeyFields(), alias, sql); 720 721 return data; 722 } 723 724 public Object visit(ASTMemberOf node, Object data) 725 { 726 Node member = node.jjtGetChild(0); 727 ASTPath colPath = (ASTPath) node.jjtGetChild(1); 728 JDBCAbstractEntityBridge colEntity = (JDBCAbstractEntityBridge) colPath.getEntity(); 729 730 StringBuffer sql = (StringBuffer ) data; 731 732 if(node.not) 733 { 734 sql.append(SQLUtil.NOT); 735 } 736 737 sql.append(SQLUtil.EXISTS).append('(').append(SQLUtil.SELECT); 738 739 if(member instanceof ASTParameter) 740 { 741 ASTParameter toParam = (ASTParameter) member; 742 verifyParameterEntityType(toParam.number, colEntity); 743 inputParameters.addAll(QueryParameter.createParameters(toParam.number - 1, colEntity)); 744 745 String parentAlias = aliasManager.getAlias(colPath.getPath(0)); 746 String localParentAlias = aliasManager.getAlias(colPath.getPath(0) + "_local"); 747 JDBCAbstractEntityBridge parentEntity = (JDBCAbstractEntityBridge) colPath.getEntity(0); 748 SQLUtil.getColumnNamesClause(parentEntity.getPrimaryKeyFields(), localParentAlias, sql); 749 sql.append(SQLUtil.FROM) 750 .append(parentEntity.getQualifiedTableName()).append(' ').append(localParentAlias); 751 innerJoinPath(colPath, sql); 752 753 sql.append(SQLUtil.WHERE); 754 755 JDBCAbstractEntityBridge col0 = (JDBCAbstractEntityBridge)colPath.getEntity(0); 756 SQLUtil.getSelfCompareWhereClause(col0.getPrimaryKeyFields(), parentAlias, localParentAlias, sql); 757 sql.append(SQLUtil.AND); 758 759 String localColAlias = aliasManager.getAlias(colPath.getPath() + "_local"); 760 SQLUtil.getWhereClause(colEntity.getPrimaryKeyFields(), localColAlias, sql); 761 } 762 else 763 { 764 ASTPath memberPath = (ASTPath) member; 765 JDBCAbstractEntityBridge memberEntity = (JDBCAbstractEntityBridge) memberPath.getEntity(); 766 767 if(!memberEntity.equals(colEntity)) 768 { 769 throw new IllegalStateException ("Member must be if the same type as the collection, got: member=" 770 + 771 memberEntity.getEntityName() 772 + ", collection=" + colEntity.getEntityName()); 773 } 774 775 String memberAlias = aliasManager.getAlias(memberPath.getPath()); 776 777 if(memberPath.size() > 1) 778 { 779 String parentAlias = aliasManager.getAlias(memberPath.getPath(0) + "_local"); 780 JDBCAbstractEntityBridge parentEntity = (JDBCAbstractEntityBridge) memberPath.getEntity(0); 781 SQLUtil.getColumnNamesClause(parentEntity.getPrimaryKeyFields(), parentAlias, sql); 782 sql.append(SQLUtil.FROM) 783 .append(parentEntity.getQualifiedTableName()).append(' ').append(parentAlias); 784 innerJoinPath(memberPath, sql); 785 innerJoinPath(colPath, sql); 786 } 787 else if(colPath.size() > 1) 788 { 789 String parentAlias = aliasManager.getAlias(colPath.getPath(0) + "_local"); 790 JDBCAbstractEntityBridge parentEntity = (JDBCAbstractEntityBridge) colPath.getEntity(0); 791 SQLUtil.getColumnNamesClause(parentEntity.getPrimaryKeyFields(), parentAlias, sql); 792 sql.append(SQLUtil.FROM) 793 .append(parentEntity.getQualifiedTableName()).append(' ').append(parentAlias); 794 innerJoinPath(colPath, sql); 795 } 796 else 797 { 798 throw new IllegalStateException ( 799 "There should be collection valued path expression, not identification variable."); 800 } 801 802 sql.append(SQLUtil.WHERE); 803 804 JDBCAbstractEntityBridge member0 = (JDBCAbstractEntityBridge)memberPath.getEntity(0); 805 String colAliasLocal = aliasManager.getAlias(colPath.getPath() + "_local"); 806 if(memberPath.size() > 1) 807 { 808 String memberAliasLocal = aliasManager.getAlias(memberPath.getPath() + "_local"); 809 SQLUtil.getSelfCompareWhereClause(colEntity.getPrimaryKeyFields(), 810 memberAliasLocal, 811 colAliasLocal, 812 sql); 813 814 sql.append(SQLUtil.AND); 815 816 String member0Alias = aliasManager.getAlias(memberPath.getPath(0)); 817 String member0AliasLocal = aliasManager.getAlias(memberPath.getPath(0) + "_local"); 818 SQLUtil.getSelfCompareWhereClause(member0.getPrimaryKeyFields(), 819 member0Alias, 820 member0AliasLocal, 821 sql); 822 } 823 else 824 { 825 SQLUtil.getSelfCompareWhereClause(member0.getPrimaryKeyFields(), memberAlias, colAliasLocal, sql); 826 } 827 } 828 829 sql.append(')'); 830 831 return data; 832 } 833 834 private void innerJoinPath(ASTPath path, StringBuffer sql) 835 { 836 if(path.size() < 2) 837 { 838 return; 839 } 840 841 String parentAlias = aliasManager.getAlias(path.getPath(0) + "_local"); 842 String leftAlias = parentAlias; 843 for(int i = 1; i < path.size(); ++i) 844 { 845 String curPath = path.getPath(i); 846 final String joinAlias = aliasManager.getAlias(curPath + "_local"); 847 848 final JDBCAbstractCMRFieldBridge cmrField = (JDBCAbstractCMRFieldBridge) path.getCMRField(i); 849 final JDBCAbstractEntityBridge joinEntity = (JDBCAbstractEntityBridge) cmrField.getRelatedEntity(); 850 851 JDBCRelationMetaData relation = cmrField.getMetaData().getRelationMetaData(); 852 853 String join = " INNER JOIN "; 854 855 if(relation.isTableMappingStyle()) 856 { 857 String relTableAlias = aliasManager.getRelationTableAlias(curPath + "_local"); 858 sql.append(join) 859 .append(cmrField.getQualifiedTableName()) 860 .append(' ') 861 .append(relTableAlias) 862 .append(" ON "); 863 SQLUtil.getRelationTableJoinClause(cmrField, leftAlias, relTableAlias, sql); 864 865 sql.append(join) 866 .append(joinEntity.getQualifiedTableName()) 867 .append(' ') 868 .append(joinAlias) 869 .append(" ON "); 870 SQLUtil.getRelationTableJoinClause(cmrField.getRelatedCMRField(), joinAlias, relTableAlias, sql); 871 } 872 else 873 { 874 sql.append(join) 875 .append(joinEntity.getQualifiedTableName()) 876 .append(' ') 877 .append(joinAlias) 878 .append(" ON "); 879 880 SQLUtil.getJoinClause(cmrField, leftAlias, joinAlias, sql); 881 } 882 883 leftAlias = joinAlias; 884 } 885 } 886 887 public Object visit(ASTStringComparison node, Object data) 888 { 889 StringBuffer buf = (StringBuffer ) data; 890 node.jjtGetChild(0).jjtAccept(this, data); 891 buf.append(' ').append(node.opp).append(' '); 892 node.jjtGetChild(1).jjtAccept(this, data); 893 return data; 894 } 895 896 public Object visit(ASTBooleanComparison node, Object data) 897 { 898 StringBuffer buf = (StringBuffer ) data; 899 node.jjtGetChild(0).jjtAccept(this, data); 900 if(node.jjtGetNumChildren() == 2) 901 { 902 buf.append(' ').append(node.opp).append(' '); 903 node.jjtGetChild(1).jjtAccept(this, data); 904 } 905 return data; 906 } 907 908 public Object visit(ASTDatetimeComparison node, Object data) 909 { 910 StringBuffer buf = (StringBuffer ) data; 911 node.jjtGetChild(0).jjtAccept(this, data); 912 buf.append(' ').append(node.opp).append(' '); 913 node.jjtGetChild(1).jjtAccept(this, data); 914 return data; 915 } 916 917 public Object visit(ASTValueClassComparison node, Object data) 918 { 919 throw new IllegalStateException ("Value class comparison is not yet supported."); 920 } 921 922 public Object visit(ASTEntityComparison node, Object data) 923 { 924 StringBuffer buf = (StringBuffer ) data; 925 Node arg0 = node.jjtGetChild(0); 926 Node arg1 = node.jjtGetChild(1); 927 if(node.opp.equals(SQLUtil.NOT_EQUAL)) 928 { 929 compareEntity(true, arg0, arg1, buf); 930 } 931 else 932 { 933 compareEntity(false, arg0, arg1, buf); 934 } 935 return data; 936 } 937 938 public Object visit(ASTArithmeticComparison node, Object data) 939 { 940 StringBuffer buf = (StringBuffer ) data; 941 node.jjtGetChild(0).jjtAccept(this, data); 942 buf.append(' ').append(node.opp).append(' '); 943 node.jjtGetChild(1).jjtAccept(this, data); 944 return data; 945 } 946 947 public Object visit(ASTPlusMinus node, Object data) 948 { 949 StringBuffer buf = (StringBuffer ) data; 950 node.jjtGetChild(0).jjtAccept(this, data); 951 for(int i = 1; i < node.jjtGetNumChildren(); i++) 952 { 953 buf.append(' ').append(node.opps.get(i - 1)).append(' '); 954 node.jjtGetChild(i).jjtAccept(this, data); 955 } 956 return data; 957 } 958 959 public Object visit(ASTMultDiv node, Object data) 960 { 961 StringBuffer buf = (StringBuffer ) data; 962 node.jjtGetChild(0).jjtAccept(this, data); 963 for(int i = 1; i < node.jjtGetNumChildren(); i++) 964 { 965 buf.append(' ').append(node.opps.get(i - 1)).append(' '); 966 node.jjtGetChild(i).jjtAccept(this, data); 967 } 968 return data; 969 } 970 971 public Object visit(ASTNegation node, Object data) 972 { 973 StringBuffer buf = (StringBuffer ) data; 974 buf.append('-'); 975 node.jjtGetChild(0).jjtAccept(this, data); 976 return data; 977 } 978 979 public Object visit(ASTArithmeticParenthetical node, Object data) 980 { 981 StringBuffer buf = (StringBuffer ) data; 982 buf.append('('); 983 node.jjtGetChild(0).jjtAccept(this, data); 984 buf.append(')'); 985 return data; 986 } 987 988 public Object visit(ASTStringParenthetical node, Object data) 989 { 990 StringBuffer buf = (StringBuffer ) data; 991 buf.append('('); 992 node.jjtGetChild(0).jjtAccept(this, data); 993 buf.append(')'); 994 return data; 995 } 996 997 public Object visit(ASTConcat node, Object data) 998 { 999 StringBuffer buf = (StringBuffer ) data; 1000 JDBCFunctionMappingMetaData function = typeMapping.getFunctionMapping(JDBCTypeMappingMetaData.CONCAT); 1001 Object [] args = childrenToStringArr(2, node); 1002 function.getFunctionSql(args, buf); 1003 return data; 1004 } 1005 1006 public Object visit(ASTSubstring node, Object data) 1007 { 1008 StringBuffer buf = (StringBuffer ) data; 1009 JDBCFunctionMappingMetaData function = typeMapping.getFunctionMapping(JDBCTypeMappingMetaData.SUBSTRING); 1010 Object [] args = childrenToStringArr(3, node); 1011 function.getFunctionSql(args, buf); 1012 return data; 1013 } 1014 1015 public Object visit(ASTUCase node, Object data) 1016 { 1017 StringBuffer buf = (StringBuffer ) data; 1018 JDBCFunctionMappingMetaData function = typeMapping.getFunctionMapping(JDBCTypeMappingMetaData.UCASE); 1019 Object [] args = childrenToStringArr(1, node); 1020 function.getFunctionSql(args, buf); 1021 return data; 1022 } 1023 1024 public Object visit(ASTLCase node, Object data) 1025 { 1026 StringBuffer buf = (StringBuffer ) data; 1027 JDBCFunctionMappingMetaData function = typeMapping.getFunctionMapping(JDBCTypeMappingMetaData.LCASE); 1028 Object [] args = childrenToStringArr(1, node); 1029 function.getFunctionSql(args, buf); 1030 return data; 1031 } 1032 1033 public Object visit(ASTLength node, Object data) 1034 { 1035 StringBuffer buf = (StringBuffer ) data; 1036 JDBCFunctionMappingMetaData function = typeMapping.getFunctionMapping(JDBCTypeMappingMetaData.LENGTH); 1037 Object [] args = childrenToStringArr(1, node); 1038 function.getFunctionSql(args, buf); 1039 return data; 1040 } 1041 1042 public Object visit(ASTLocate node, Object data) 1043 { 1044 StringBuffer buf = (StringBuffer ) data; 1045 JDBCFunctionMappingMetaData function = typeMapping.getFunctionMapping(JDBCTypeMappingMetaData.LOCATE); 1046 Object [] args = new Object [3]; 1047 args[0] = node.jjtGetChild(0).jjtAccept(this, new StringBuffer ()).toString(); 1048 args[1] = node.jjtGetChild(1).jjtAccept(this, new StringBuffer ()).toString(); 1049 if(node.jjtGetNumChildren() == 3) 1050 { 1051 args[2] = node.jjtGetChild(2).jjtAccept(this, new StringBuffer ()).toString(); 1052 } 1053 else 1054 { 1055 args[2] = "1"; 1056 } 1057 function.getFunctionSql(args, buf); 1058 return data; 1059 } 1060 1061 public Object visit(ASTAbs node, Object data) 1062 { 1063 StringBuffer buf = (StringBuffer ) data; 1064 JDBCFunctionMappingMetaData function = typeMapping.getFunctionMapping(JDBCTypeMappingMetaData.ABS); 1065 Object [] args = childrenToStringArr(1, node); 1066 function.getFunctionSql(args, buf); 1067 return data; 1068 } 1069 1070 public Object visit(ASTSqrt node, Object data) 1071 { 1072 StringBuffer buf = (StringBuffer ) data; 1073 JDBCFunctionMappingMetaData function = typeMapping.getFunctionMapping(JDBCTypeMappingMetaData.SQRT); 1074 Object [] args = childrenToStringArr(1, node); 1075 function.getFunctionSql(args, buf); 1076 return data; 1077 } 1078 1079 public Object visit(ASTMod node, Object data) 1080 { 1081 StringBuffer buf = (StringBuffer ) data; 1082 JDBCFunctionMappingMetaData function = JDBCTypeMappingMetaData.MOD_FUNC; 1083 Object [] args = childrenToStringArr(2, node); 1084 function.getFunctionSql(args, buf); 1085 return data; 1086 } 1087 1088 public Object visit(ASTAvg node, Object data) 1089 { 1090 node.setResultType(returnType); 1091 StringBuffer buf = (StringBuffer ) data; 1092 Object [] args = new Object []{ 1093 node.distinct, 1094 node.jjtGetChild(0).jjtAccept(this, new StringBuffer ()).toString(), 1095 }; 1096 JDBCTypeMappingMetaData.AVG_FUNC.getFunctionSql(args, buf); 1097 return data; 1098 } 1099 1100 public Object visit(ASTMax node, Object data) 1101 { 1102 node.setResultType(returnType); 1103 StringBuffer buf = (StringBuffer ) data; 1104 Object [] args = new Object []{ 1105 node.distinct, 1106 node.jjtGetChild(0).jjtAccept(this, new StringBuffer ()).toString(), 1107 }; 1108 JDBCTypeMappingMetaData.MAX_FUNC.getFunctionSql(args, buf); 1109 return data; 1110 } 1111 1112 public Object visit(ASTMin node, Object data) 1113 { 1114 node.setResultType(returnType); 1115 StringBuffer buf = (StringBuffer ) data; 1116 Object [] args = new Object []{ 1117 node.distinct, 1118 node.jjtGetChild(0).jjtAccept(this, new StringBuffer ()).toString(), 1119 }; 1120 JDBCTypeMappingMetaData.MIN_FUNC.getFunctionSql(args, buf); 1121 return data; 1122 } 1123 1124 public Object visit(ASTSum node, Object data) 1125 { 1126 node.setResultType(returnType); 1127 StringBuffer buf = (StringBuffer ) data; 1128 Object [] args = new Object []{ 1129 node.distinct, 1130 node.jjtGetChild(0).jjtAccept(this, new StringBuffer ()).toString(), 1131 }; 1132 JDBCTypeMappingMetaData.SUM_FUNC.getFunctionSql(args, buf); 1133 return data; 1134 } 1135 1136 public Object visit(ASTCount node, Object data) 1137 { 1138 StringBuffer buf = (StringBuffer ) data; 1139 node.setResultType(returnType); 1140 1141 Object args[]; 1142 final ASTPath cntPath = (ASTPath) node.jjtGetChild(0); 1143 if(cntPath.isCMPField()) 1144 { 1145 args = new Object []{node.distinct, node.jjtGetChild(0).jjtAccept(this, new StringBuffer ()).toString()}; 1146 } 1147 else 1148 { 1149 JDBCAbstractEntityBridge entity = (JDBCAbstractEntityBridge) cntPath.getEntity(); 1150 final JDBCFieldBridge[] pkFields = entity.getPrimaryKeyFields(); 1151 if(pkFields.length > 1) 1152 { 1153 countCompositePk = true; 1154 forceDistinct = node.distinct.length() > 0; 1155 1156 addLeftJoinPath(cntPath); 1157 1158 String alias = aliasManager.getAlias(cntPath.getPath()); 1159 SQLUtil.getColumnNamesClause(entity.getPrimaryKeyFields(), 1160 alias, 1161 buf); 1162 1163 return buf; 1164 } 1165 else 1166 { 1167 final String alias = aliasManager.getAlias(cntPath.getPath()); 1168 StringBuffer keyColumn = new StringBuffer (20); 1169 SQLUtil.getColumnNamesClause(pkFields[0], alias, keyColumn); 1170 args = new Object []{node.distinct, keyColumn.toString()}; 1171 } 1172 } 1173 1174 JDBCTypeMappingMetaData.COUNT_FUNC.getFunctionSql(args, buf); 1175 return data; 1176 } 1177 1178 public Object visit(ASTPath node, Object data) 1179 { 1180 StringBuffer buf = (StringBuffer ) data; 1181 if(!node.isCMPField()) 1182 { 1183 throw new IllegalStateException ("Can only visit cmp valued path node. " 1184 + "Should have been handled at a higher level."); 1185 } 1186 1187 switch(node.type) 1189 { 1190 case EJBQLTypes.ENTITY_TYPE: 1191 case EJBQLTypes.VALUE_CLASS_TYPE: 1192 case EJBQLTypes.UNKNOWN_TYPE: 1193 throw new IllegalStateException ("Can not visit multi-column path " + 1194 "node. Should have been handled at a higher level."); 1195 } 1196 1197 addLeftJoinPath(node); 1198 JDBCFieldBridge cmpField = (JDBCFieldBridge) node.getCMPField(); 1199 String alias = aliasManager.getAlias(node.getPath(node.size() - 2)); 1200 SQLUtil.getColumnNamesClause(cmpField, alias, buf); 1201 return data; 1202 } 1203 1204 public Object visit(ASTAbstractSchema node, Object data) 1205 { 1206 throw new IllegalStateException ("Can not visit abstract schema node. " 1207 + " Should have been handled at a higher level."); 1208 } 1209 1210 public Object visit(ASTIdentifier node, Object data) 1211 { 1212 throw new UnsupportedOperationException ("Must not visit ASTIdentifier noe."); 1213 } 1214 1215 public Object visit(ASTParameter node, Object data) 1216 { 1217 StringBuffer buf = (StringBuffer ) data; 1218 Class type = getParameterType(node.number); 1219 1220 int ejbqlType = EJBQLTypes.getEJBQLType(type); 1222 if(ejbqlType == EJBQLTypes.ENTITY_TYPE 1223 || 1224 ejbqlType == EJBQLTypes.VALUE_CLASS_TYPE || 1225 ejbqlType == EJBQLTypes.UNKNOWN_TYPE) 1226 { 1227 throw new IllegalStateException ("Can not visit multi-column " + 1228 "parameter node. Should have been handled at a higher level."); 1229 } 1230 1231 QueryParameter param = new QueryParameter(node.number - 1, typeFactory.getJDBCType(type)); 1232 inputParameters.add(param); 1233 buf.append('?'); 1234 1235 return data; 1236 } 1237 1238 public Object visit(ASTExactNumericLiteral node, Object data) 1239 { 1240 StringBuffer buf = (StringBuffer ) data; 1241 buf.append(node.literal); 1242 return data; 1243 } 1244 1245 public Object visit(ASTApproximateNumericLiteral node, Object data) 1246 { 1247 StringBuffer buf = (StringBuffer ) data; 1248 buf.append(node.literal); 1249 return data; 1250 } 1251 1252 public Object visit(ASTStringLiteral node, Object data) 1253 { 1254 StringBuffer buf = (StringBuffer ) data; 1255 buf.append(node.value); 1256 return data; 1257 } 1258 1259 public Object visit(ASTBooleanLiteral node, Object data) 1260 { 1261 StringBuffer buf = (StringBuffer ) data; 1262 if(node.value) 1263 { 1264 buf.append(typeMapping.getTrueMapping()); 1265 } 1266 else 1267 { 1268 buf.append(typeMapping.getFalseMapping()); 1269 } 1270 return data; 1271 } 1272 1273 public Object visit(ASTFrom from, Object data) 1274 { 1275 StringBuffer sql = (StringBuffer ) data; 1276 from.jjtGetChild(0).jjtAccept(this, data); 1277 for(int i = 1; i < from.jjtGetNumChildren(); ++i) 1278 { 1279 from.jjtGetChild(i).jjtAccept(this, data); 1280 } 1281 1282 return data; 1283 } 1284 1285 public Object visit(ASTCollectionMemberDeclaration node, Object data) 1286 { 1287 ASTPath path = (ASTPath) node.jjtGetChild(0); 1288 1289 ASTIdentifier id = (ASTIdentifier) node.jjtGetChild(1); 1291 String alias = aliasManager.getAlias(id.identifier); 1292 aliasManager.addAlias(path.getPath(), alias); 1293 1294 addInnerJoinPath(path); 1295 1296 return data; 1297 } 1298 1299 public Object visit(ASTRangeVariableDeclaration node, Object data) 1300 { 1301 ASTAbstractSchema schema = (ASTAbstractSchema) node.jjtGetChild(0); 1302 JDBCAbstractEntityBridge entity = (JDBCAbstractEntityBridge) schema.entity; 1303 ASTIdentifier id = (ASTIdentifier) node.jjtGetChild(1); 1304 declareTable(id.identifier, entity.getQualifiedTableName()); 1305 return data; 1306 } 1307 1308 1310 private void compareEntity(boolean not, Node fromNode, Node toNode, StringBuffer buf) 1311 { 1312 buf.append('('); 1313 if(not) 1314 { 1315 buf.append(SQLUtil.NOT).append('('); 1316 } 1317 1318 ASTPath fromPath = (ASTPath) fromNode; 1319 addLeftJoinPath(fromPath); 1320 String fromAlias = aliasManager.getAlias(fromPath.getPath()); 1321 JDBCAbstractEntityBridge fromEntity = (JDBCAbstractEntityBridge) fromPath.getEntity(); 1322 1323 if(toNode instanceof ASTParameter) 1324 { 1325 ASTParameter toParam = (ASTParameter) toNode; 1326 1327 verifyParameterEntityType(toParam.number, fromEntity); 1329 1330 inputParameters.addAll(QueryParameter.createParameters(toParam.number - 1, fromEntity)); 1331 1332 SQLUtil.getWhereClause(fromEntity.getPrimaryKeyFields(), fromAlias, buf); 1333 } 1334 else 1335 { 1336 ASTPath toPath = (ASTPath) toNode; 1337 addLeftJoinPath(toPath); 1338 String toAlias = aliasManager.getAlias(toPath.getPath()); 1339 JDBCAbstractEntityBridge toEntity = (JDBCAbstractEntityBridge) toPath.getEntity(); 1340 1341 if(!fromEntity.equals(toEntity)) 1343 { 1344 throw new IllegalStateException ("Only like types can be " 1345 + 1346 "compared: from entity=" 1347 + 1348 fromEntity.getEntityName() 1349 + " to entity=" + toEntity.getEntityName()); 1350 } 1351 1352 SQLUtil.getSelfCompareWhereClause(fromEntity.getPrimaryKeyFields(), fromAlias, toAlias, buf); 1353 } 1354 1355 if(not) 1356 { 1357 buf.append(')'); 1358 } 1359 buf.append(')'); 1360 } 1361 1362 private void join(String alias, StringBuffer sql) 1363 { 1364 Map paths = (Map ) joinPaths.get(alias); 1365 if(paths == null || paths.isEmpty()) 1366 { 1367 return; 1368 } 1369 1370 for(Iterator iter = paths.values().iterator(); iter.hasNext();) 1371 { 1372 String leftAlias = alias; 1373 ASTPath path = (ASTPath) iter.next(); 1374 for(int i = 1; i < path.size(); ++i) 1375 { 1376 if(path.isCMRField(i)) 1377 { 1378 final String curPath = path.getPath(i); 1379 final String joinAlias = aliasManager.getAlias(curPath); 1380 1381 if(joinedAliases.add(joinAlias)) 1382 { 1383 final JDBCAbstractCMRFieldBridge cmrField = (JDBCAbstractCMRFieldBridge) path.getCMRField(i); 1384 final JDBCAbstractEntityBridge joinEntity = (JDBCAbstractEntityBridge) cmrField.getRelatedEntity(); 1385 1386 JDBCRelationMetaData relation = cmrField.getMetaData().getRelationMetaData(); 1387 1388 String join = (path.innerJoin ? " INNER JOIN " : " LEFT OUTER JOIN "); 1389 1390 if(relation.isTableMappingStyle()) 1391 { 1392 String relTableAlias = aliasManager.getRelationTableAlias(curPath); 1393 sql.append(join) 1394 .append(cmrField.getQualifiedTableName()) 1395 .append(' ') 1396 .append(relTableAlias) 1397 .append(" ON "); 1398 SQLUtil.getRelationTableJoinClause(cmrField, leftAlias, relTableAlias, sql); 1399 1400 sql.append(join) 1401 .append(joinEntity.getQualifiedTableName()) 1402 .append(' ') 1403 .append(joinAlias) 1404 .append(" ON "); 1405 SQLUtil.getRelationTableJoinClause(cmrField.getRelatedCMRField(), joinAlias, relTableAlias, sql); 1406 } 1407 else 1408 { 1409 sql.append(join) 1410 .append(joinEntity.getQualifiedTableName()) 1411 .append(' ') 1412 .append(joinAlias) 1413 .append(" ON "); 1414 1415 SQLUtil.getJoinClause(cmrField, leftAlias, joinAlias, sql); 1416 } 1417 1418 join(joinAlias, sql); 1419 } 1420 leftAlias = joinAlias; 1421 } 1422 } 1423 } 1424 } 1425 1426 private void declareTable(String alias, String table) 1427 { 1428 identifierToTable.put(alias, table); 1429 } 1430 1431 private void addLeftJoinPath(ASTPath path) 1432 { 1433 if(path.size() > 1 && path.isCMRField(1)) 1434 { 1435 final String identifier = path.getPath(0); 1436 final String alias = aliasManager.getAlias(identifier); 1437 Map paths = (Map ) joinPaths.get(alias); 1438 if(paths == null) 1439 { 1440 paths = new HashMap (); 1441 joinPaths.put(alias, paths); 1442 } 1443 1444 ASTPath oldPath = (ASTPath) paths.put(path, path); 1445 if(oldPath != null && oldPath.innerJoin) 1446 { 1447 path.innerJoin = true; 1448 } 1449 } 1450 } 1451 1452 private void addInnerJoinPath(ASTPath path) 1453 { 1454 if(path.size() > 1 && path.isCMRField(1)) 1455 { 1456 final String identifier = path.getPath(0); 1457 final String alias = aliasManager.getAlias(identifier); 1458 Map paths = (Map ) joinPaths.get(alias); 1459 if(paths == null) 1460 { 1461 paths = new HashMap (); 1462 joinPaths.put(alias, paths); 1463 } 1464 1465 path.innerJoin = true; 1466 paths.put(path, path); 1467 } 1468 } 1469 1470 private Object [] childrenToStringArr(int numChildren, Node node) 1471 { 1472 Object [] args = new Object [numChildren]; 1473 for(int i = 0; i < numChildren; ++i) 1474 { 1475 args[i] = node.jjtGetChild(i).jjtAccept(this, new StringBuffer ()).toString(); 1476 } 1477 return args; 1478 } 1479 1480 1486 private ASTPath getPathFromChildren(Node selectFunction) 1487 { 1488 for(int childInd = 0; childInd < selectFunction.jjtGetNumChildren(); ++childInd) 1489 { 1490 Node child = selectFunction.jjtGetChild(childInd); 1491 if(child instanceof ASTPath) 1492 { 1493 return (ASTPath) child; 1494 } 1495 else if(child instanceof SelectFunction) 1496 { 1497 Node path = getPathFromChildren(child); 1498 if(path != null) 1499 { 1500 return (ASTPath) path; 1501 } 1502 } 1503 } 1504 return null; 1505 } 1506 1507 private void setTypeFactory(JDBCTypeFactory typeFactory) 1508 { 1509 this.typeFactory = typeFactory; 1510 this.typeMapping = typeFactory.getTypeMapping(); 1511 aliasManager = new AliasManager(typeMapping.getAliasHeaderPrefix(), 1512 typeMapping.getAliasHeaderSuffix(), 1513 typeMapping.getAliasMaxLength()); 1514 } 1515 1516 private Class getParameterType(int index) 1517 { 1518 int zeroBasedIndex = index - 1; 1519 Class [] params = parameterTypes; 1520 if(zeroBasedIndex < params.length) 1521 { 1522 return params[zeroBasedIndex]; 1523 } 1524 return null; 1525 } 1526 1527 private void verifyParameterEntityType(int number, JDBCAbstractEntityBridge entity) 1529 { 1530 Class parameterType = getParameterType(number); 1531 Class remoteClass = entity.getRemoteInterface(); 1532 Class localClass = entity.getLocalInterface(); 1533 if((localClass == null || !localClass.isAssignableFrom(parameterType)) && 1534 (remoteClass == null || !remoteClass.isAssignableFrom(parameterType))) 1535 { 1536 throw new IllegalStateException ("Only like types can be compared: from entity=" + 1537 entity.getEntityName() + " to parameter type=" + parameterType); 1538 } 1539 } 1540 1541 private void reset() 1542 { 1543 returnType = null; 1544 parameterTypes = null; 1545 readAhead = null; 1546 inputParameters.clear(); 1547 selectObject = null; 1548 selectManager = null; 1549 typeFactory = null; 1550 typeMapping = null; 1551 aliasManager = null; 1552 forceDistinct = false; 1553 limitParam = 0; 1554 limitValue = 0; 1555 offsetParam = 0; 1556 offsetValue = 0; 1557 leftJoinCMRList.clear(); 1558 onFindCMRJoin = null; 1559 countCompositePk = false; 1560 joinPaths.clear(); 1561 identifierToTable.clear(); 1562 joinedAliases.clear(); 1563 selectDistinct = false; 1564 } 1565} 1566 | Popular Tags |