1 2 12 package com.versant.core.jdbc.query; 13 14 import com.versant.core.jdo.query.*; 15 import com.versant.core.jdbc.sql.exp.*; 16 import com.versant.core.jdbc.sql.exp.AggregateCountStarExp; 17 import com.versant.core.jdbc.sql.conv.DummyPreparedStmt; 18 import com.versant.core.jdbc.metadata.*; 19 import com.versant.core.common.BindingSupportImpl; 20 import com.versant.core.metadata.MDStatics; 21 import com.versant.core.metadata.MDStaticUtils; 22 import com.versant.core.metadata.ClassMetaData; 23 24 import java.sql.SQLException ; 25 26 29 public class JDOQLNodeToSqlExp extends NodeVisitorAdapter { 30 31 private final JdbcJDOQLCompiler comp; 32 33 37 public static final JDOQLNodeToSqlExp INSTANCE = new JDOQLNodeToSqlExp(); 38 39 43 private static class Context { 44 45 public SelectExp root; 46 public SqlExp leftSibling; 47 public int method; 48 public Node args; 49 50 public Context(SelectExp root) { 51 this.root = root; 52 } 53 54 public Context(SelectExp root, SqlExp leftSibling, int method, Node args) { 55 this.root = root; 56 this.leftSibling = leftSibling; 57 this.method = method; 58 this.args = args; 59 } 60 } 61 62 public JDOQLNodeToSqlExp(JdbcJDOQLCompiler comp) { 63 this.comp = comp; 64 } 65 66 private JDOQLNodeToSqlExp() { 67 this(null); 68 } 69 70 73 public SqlExp toSqlExp(Node node, SelectExp root, SqlExp leftSibling, 74 int method, Node args) { 75 return (SqlExp)node.arrive(this, new Context(root, leftSibling, 76 method, args)); 77 } 78 79 protected Object defaultArrive(Node node, Object msg) { 80 throw BindingSupportImpl.getInstance().internal("Not implemented: " + 81 node.getClass()); 82 } 83 84 public Object arriveFieldNavNode(FieldNavNode node, Object msg) { 85 Context ctx = (Context)msg; 86 SelectExp root = ctx.root; 87 if (node.var == null) { 88 JdbcField jdbcField = (JdbcField)node.fmd.storeField; 89 JdbcClass targetClass = (JdbcClass)node.targetClass.storeClass; 90 SelectExp se; 91 Join j = root.findJoin(jdbcField); 92 if (j == null) { 93 SelectExp leftTableSE = root.findTable(jdbcField.mainTable); 94 if (leftTableSE == null) { 95 throw BindingSupportImpl.getInstance().runtime( 96 "No join to '" 97 + jdbcField.mainTable + "' for nav field '" + jdbcField.fmd.name); 98 } 99 100 se = new SelectExp(); 101 se.table = targetClass.table; 102 se.jdbcField = jdbcField; 103 if (jdbcField instanceof JdbcPolyRefField) { 104 JdbcPolyRefField pf = (JdbcPolyRefField)jdbcField; 105 j = leftTableSE.addJoin(pf.refCols, se.table.pk, se); 106 j.appendJoinExp( 109 pf.createClassIdMatchExp(root, targetClass.cmd)); 110 } else { 111 j = leftTableSE.addJoin(jdbcField.mainTableCols, 112 se.table.pk, se); 113 if (node.cast != null && targetClass.cmd.isInHeirachy()) { 114 if (targetClass.classIdCol != null && targetClass.classIdCol.table != se.table) { 116 SelectExp bSe = (SelectExp)root.findTable(targetClass.classIdCol.table); 117 if (bSe == null) { 118 bSe = new SelectExp(); 119 bSe.outer = se.outer; 120 bSe.table = targetClass.classIdCol.table; 121 j = se.addJoin(se.table.pk, bSe.table.pk, bSe); 122 } 123 } 124 125 j.appendJoinExp(targetClass.getCheckClassIdExp(se)); 128 } 129 } 130 } else { 131 se = j.selectExp; 132 } 133 if (node.childList == null) { 134 return null; 135 } else { 136 return toSqlExp(node.childList, se, ctx.leftSibling, 137 ctx.method, ctx.args); 138 } 139 } else { 140 return toSqlExp(node.childList, (SelectExp)node.var.getStoreExtent(), 141 ctx.leftSibling, ctx.method, ctx.args); 142 } 143 } 144 145 public Object arriveLiteralNode(LiteralNode node, Object msg) { 146 Context ctx = (Context)msg; 147 SqlExp leftSibling = ctx.leftSibling; 148 String value = node.value; 149 int t; 150 switch (node.type) { 151 case LiteralNode.TYPE_OTHER: t = LiteralExp.TYPE_OTHER; break; 152 case LiteralNode.TYPE_STRING: t = LiteralExp.TYPE_STRING; break; 153 case LiteralNode.TYPE_NULL: t = LiteralExp.TYPE_NULL; break; 154 case LiteralNode.TYPE_BOOLEAN: 155 t = LiteralExp.TYPE_OTHER; 156 157 163 if (ctx.leftSibling instanceof ColumnExp) { 164 ColumnExp cExp = (ColumnExp)leftSibling; 165 if (cExp.col.converter == null) break; 166 DummyPreparedStmt pstmt = new DummyPreparedStmt(); 167 try { 168 cExp.col.converter.set(pstmt, 0, cExp.col, 169 new Boolean (value)); 170 } catch (SQLException e) { 171 } 173 value = pstmt.value; 174 if (pstmt.toQuote) { 175 t = LiteralExp.TYPE_STRING; 176 } else { 177 t = LiteralExp.TYPE_OTHER; 178 } 179 } 180 break; 181 case LiteralNode.TYPE_CHAR: 182 case LiteralNode.TYPE_DOUBLE: 183 case LiteralNode.TYPE_LONG: t = LiteralExp.TYPE_OTHER; break; 184 default: 185 throw BindingSupportImpl.getInstance().internal( 186 "Unknown literal type: " + node.type); 187 } 188 189 LiteralExp ans = new LiteralExp(t, value); 190 if (node.type == LiteralNode.TYPE_NULL) { 191 for (SqlExp pos = ans; (leftSibling = leftSibling.next) != null; ) { 195 pos = pos.next = new LiteralExp(t, value); 196 } 197 } 198 return ans; 199 } 200 201 public Object arriveMethodNode(MethodNode node, Object msg) { 202 Context ctx = (Context)msg; 203 SelectExp root = ctx.root; 204 int method = node.getMethod(); 205 Node childList = node.childList; 206 switch (method) { 207 case MethodNode.STARTS_WITH: return toSqlLike(childList, method, root, false); 208 case MethodNode.ENDS_WITH: return toSqlLike(childList, method, root, true); 209 case MethodNode.CONTAINS: 210 case MethodNode.CONTAINS_KEY: return toSqlContains(childList, method, root); 211 case MethodNode.IS_EMPTY: return toSqlIsEmpty(childList, root); 212 case MethodNode.TO_LOWER_CASE: return toSqlToLowerCase(childList, method, root); 213 case MethodNode.SQL: return toSqlInline(childList, method, root); 214 } 215 throw BindingSupportImpl.getInstance().internal("Unknown method: " + method); 216 } 217 218 private SqlExp toSqlInline(Node childList, int method, SelectExp root) { 219 SqlExp left = toSqlExp(childList, root, null, method, null); 220 SqlExp right; 221 if (childList.next != null) { 222 right = toSqlExp(childList.next, root, left, method, null); 223 } else { 224 right = null; 225 } 226 String template; 227 if (right == null) { 228 template = "$1"; 229 } else if (right instanceof LiteralExp) { 230 template = ((LiteralExp)right).value; 231 } else { 232 throw BindingSupportImpl.getInstance().invalidOperation("Expected literal expression: " + right); 233 } 234 return new InlineSqlExp(template, left); 235 } 236 237 private SqlExp toSqlLike(Node childList, int method, SelectExp root, 238 boolean endsWith) { 239 SqlExp left = toSqlExp(childList, root, null, method, null); 240 SqlExp right = toSqlExp(childList.next, root, left, method, null); 241 if (right instanceof LiteralExp 242 && ((LiteralExp)right).type == LiteralExp.TYPE_STRING) { 243 LiteralExp le = (LiteralExp)right; 245 if (endsWith) le.value = "%" + le.value; 246 else le.value = le.value + "%"; 247 } else { 248 LiteralExp pe = new LiteralExp(LiteralExp.TYPE_STRING, "%"); 250 if (endsWith) right = new BinaryOpExp(pe, BinaryOpExp.CONCAT, right); 251 else right = new BinaryOpExp(right, BinaryOpExp.CONCAT, pe); 252 } 253 return new BinaryOpExp(left, BinaryOpExp.LIKE, right); 254 } 255 256 private SqlExp toSqlIsEmpty(Node childList, SelectExp root) { 257 if (childList.next != null) { 258 throw BindingSupportImpl.getInstance().runtime( 259 "isEmpty() does not accept arguments"); 260 } 261 return toSqlExp(childList, root, null, MethodNode.IS_EMPTY, null); 262 } 263 264 private SqlExp toSqlContains(Node childList, int method, SelectExp root) { 265 return toSqlExp(childList, root, null, method, childList.next); 266 } 267 268 private SqlExp toSqlToLowerCase(Node childList, int method, SelectExp root) { 269 if (childList.next != null) { 270 throw BindingSupportImpl.getInstance().runtime( 271 "toLowerCase() does not accept arguments"); 272 } 273 SqlExp left = toSqlExp(childList, root, null, method, null); 274 return new UnaryFunctionExp(left, UnaryFunctionExp.FUNC_TO_LOWER_CASE); 275 } 276 277 public Object arriveFieldNode(FieldNode node, Object msg) { 278 Context ctx = (Context)msg; 279 int method = ctx.method; 280 SelectExp root = ctx.root; 281 Node args = ctx.args; 282 JdbcField jdbcField = (JdbcField)node.fmd.storeField; 283 284 switch (method) { 285 case MethodNode.IS_EMPTY: 286 return jdbcField.toIsEmptySqlExp(comp, root); 287 case MethodNode.CONTAINS: 288 return jdbcField.toContainsSqlExp(comp, root, args); 289 case MethodNode.CONTAINS_KEY: 290 return jdbcField.toContainsKeySqlExp(comp, root, args); 291 case MethodNode.CONTAINS_PARAM: 292 if (jdbcField.mainTableCols.length > 1) { 293 throw BindingSupportImpl.getInstance().invalidOperation( 294 "This is only supported for single column instances"); 295 } 296 return new CollectionParamExp(jdbcField.toColumnExp( 297 SelectExp.createJoinToSuperTable(root, jdbcField), true)); 298 }; 299 300 if (isUnaryBoolExp(node, jdbcField)) { 303 ColumnExp cExp = jdbcField.toColumnExp(root, true); 304 305 LiteralExp lExp = new LiteralExp(); 306 if (cExp.col.converter != null) { 307 DummyPreparedStmt pstmt = new DummyPreparedStmt(); 308 try { 309 cExp.col.converter.set(pstmt, 0, cExp.col, new Boolean (true)); 310 } catch (SQLException e) { 311 } 313 314 lExp.value = pstmt.value; 315 if (pstmt.toQuote) { 316 lExp.type = LiteralExp.TYPE_STRING; 317 } else { 318 lExp.type = LiteralExp.TYPE_OTHER; 319 } 320 return new BinaryOpExp(cExp, BinaryOpExp.EQUAL, lExp); 321 } else { 322 lExp.type = LiteralExp.TYPE_OTHER; 323 lExp.value = "true"; 324 return new BinaryOpExp(cExp, BinaryOpExp.EQUAL, lExp); 325 } 326 } 327 328 SelectExp fSe = node.useCandidateExtent ? comp.getCandidateSelectExp() : root; 329 ColumnExp columnExp = jdbcField.toColumnExp(SelectExp.createJoinToSuperTable(fSe, jdbcField), true); 330 if (!isPartOfAggregate(node.parent)) columnExp.setColAlias(node.asValue); 331 return columnExp; 332 } 333 334 private static boolean isUnaryBoolExp(Node node, JdbcField jdbcField) { 335 if (isBooleanType(jdbcField) && !(node.parent instanceof OrderNode)) { 336 if (node.parent instanceof FieldNavNode) { 337 return isUnaryBoolExp(node.parent, jdbcField); 338 } else if ((node.parent instanceof AndNode) 339 || (node.parent instanceof OrNode) 340 || (node.parent != null && node.parent.parent == null)) { 341 return true; 342 } 343 } 344 return false; 345 } 346 347 private static boolean isBooleanType(JdbcField jdbcField) { 348 if (jdbcField == null) return false; 349 return ((jdbcField.fmd.typeCode == MDStatics.BOOLEAN) 350 || (jdbcField.fmd.typeCode == MDStatics.BOOLEANW)); 351 } 352 353 private static boolean isPartOfAggregate(Node n) { 354 if (n == null) return false; 355 if (n instanceof AggregateNode) return true; 356 return isPartOfAggregate(n.parent); 357 } 358 359 public Object arriveEqualNode(EqualNode node, Object msg) { 360 return arriveEqualOrNotEqual(node, msg, BinaryOpExp.EQUAL); 361 } 362 363 public Object arriveLikeNode(LikeNode node, Object msg) { 364 return arriveEqualOrNotEqual(node, msg, BinaryOpExp.LIKE); 365 } 366 367 private Object arriveEqualOrNotEqual(EqualNode node, Object msg, int op) { 368 Context ctx = (Context)msg; 369 SelectExp root = ctx.root; 370 371 SqlExp left; 375 Node childList = node.childList; 376 if (isNullLiteral(childList.next) && childList instanceof FieldNode) { 377 JdbcField f = (JdbcField)((FieldNode)childList).fmd.storeField; 378 left = f.toColumnExpForNullLiteralCompare(root); 379 } else { 380 left = toSqlExp(childList, root, null, ctx.method, ctx.args); 381 } 382 383 SqlExp right = toSqlExp(childList.next, root, left, ctx.method, ctx.args); 384 return SqlExp.createBinaryOpExp(left, op, right); 385 } 386 387 private static boolean isNullLiteral(Node n) { 388 return n instanceof LiteralNode 389 && ((LiteralNode)n).type == LiteralNode.TYPE_NULL; 390 } 391 392 public Object arriveNotEqualNode(NotEqualNode node, Object msg) { 393 return arriveEqualOrNotEqual(node, msg, BinaryOpExp.NOT_EQUAL); 394 } 395 396 public Object arriveAndNode(AndNode node, Object msg) { 397 Context ctx = (Context)msg; 398 Node childList = node.childList; 399 400 SqlExp prev = null, first = null; 402 for (Node cn = childList; cn != null;) { 403 SqlExp e = toSqlExp(cn, ctx.root, prev, ctx.method, ctx.args); 404 if (first == null) { 405 first = e; 406 } else if ( prev != null ) { 407 prev.next = e; 408 } 409 prev = e; 410 411 VarNode vn = extractVar(e); 415 if (vn != null) { 416 cn = processVarNode(ctx.root, ctx.method, ctx.args, cn, vn, e); 417 } else { 418 cn = cn.next; 419 } 420 } 421 422 if (first.next == null) { 425 return first; 426 } else { 427 return new AndExp(first); 428 } 429 } 430 431 private static VarNode extractVar(SqlExp e) { 432 if (e instanceof ExistsExp && e.childList instanceof SelectExp) { 433 return ((SelectExp) e.childList).var; 434 } else { 435 return null; 436 } 437 } 438 439 447 private Node processVarNode(SelectExp root, int method, Node args, 448 Node cn, VarNode var, SqlExp vare) { 449 450 SelectExp varSelectExp = (SelectExp)var.getStoreExtent(); 451 452 SelectExp exclude; 458 if (root.table.sqlDriver.isSubQueryJoinMayUseOuterQueryCols()) { 459 exclude = root; 460 } else { 461 exclude = null; 462 } 463 464 SqlExp prev = null, first = null; 466 SqlExp leftSibling = vare; 467 Node ans = cn.next; 468 for (; ans != null;) { 469 SqlExp e = toSqlExp(ans, root, leftSibling, method, args); 470 if (e == null) { 471 break; 472 } 473 474 SelectExp single = e.getSingleSelectExp(exclude); 475 if (single != null) { 476 Join join; 477 if (single.jdbcField != null) { 478 join = varSelectExp.findJoinRec(single.jdbcField); 479 } else if (vare instanceof ExistsExp) { 480 join = ((SelectExp) vare.childList).findJoin(single); 481 } else { 482 join = null; 483 } 484 ans = ans.next; 485 if (join != null) { 486 join.appendJoinExp(e); 487 continue; 488 } else if (var.getCmd() == null) { 489 ((SelectExp) ((ExistsExp)vare).childList).appendToWhereExp(e); 490 } 491 } else { 492 VarNode nested = extractVar(e); 494 if (nested != null) { 495 ans = processVarNode(root, method, args, ans, nested, e); 496 } else { 497 ans = ans.next; 498 } 499 } 500 if (first == null) { 501 first = e; 502 } else { 503 prev.next = e; 504 } 505 leftSibling = e; 506 prev = e; 507 } 508 509 if (first != null) varSelectExp.appendToWhereExp(first); 511 512 return ans; 513 } 514 515 public Object arriveOrNode(OrNode node, Object msg) { 516 Context ctx = (Context)msg; 517 Node childList = node.childList; 518 519 SqlExp e = processOrNodeChild(ctx.root, childList, ctx.args); 520 if (e == null) { 521 return null; 522 } 523 524 SqlExp base = e; 525 for (Node c = childList.next; c != null; c = c.next) { 526 e = e.next = processOrNodeChild(ctx.root, c, ctx.args); 527 } 528 mergeOrNodeRedundantExistsSelects(base); 529 if (base.next == null) return base; 530 return new OrExp(base); 531 } 532 533 private SqlExp processOrNodeChild(SelectExp root, Node c, Node args) { 534 Join rootJoinList = root.joinList; 535 root.joinList = null; 536 SqlExp e = toSqlExp(c, root, null, 0, args); 537 Join j = root.joinList; 540 if (j != null) { 541 SelectExp se = j.selectExp; 543 se.subSelectJoinExp = j.exp; 544 se.whereExp = e; 545 j = se.joinList; 547 if (j == null) { 548 se.joinList = root.joinList.next; 549 } else { 550 for (; j.next != null; j = j.next); 551 j.next = root.joinList.next; 552 } 553 e = new ExistsExp(se, false); 555 } 556 root.joinList = rootJoinList; 557 return e; 558 } 559 560 564 private void mergeOrNodeRedundantExistsSelects(SqlExp base) { 565 for (; base != null; ) { 566 if (base instanceof ExistsExp) { 567 SqlExp prev = base; 568 for (SqlExp target = base.next; target != null; ) { 569 if (mergeOrNodeRedundantExistsSelects(base, target)) { 570 target = prev.next = target.next; 571 } else { 572 prev = target; 573 target = target.next; 574 } 575 } 576 } 577 base = base.next; 578 } 579 } 580 581 590 private boolean mergeOrNodeRedundantExistsSelects(SqlExp base, SqlExp e) { 591 if (!(e instanceof ExistsExp)) return false; 592 SelectExp se = (SelectExp)base.childList; 593 SelectExp ese = (SelectExp)e.childList; 594 if (se.jdbcField != ese.jdbcField) return false; 595 if (!Join.isEqaul(se.joinList, ese.joinList)) return false; 597 SqlExp we = se.whereExp; 598 if (we instanceof OrExp) { SqlExp pos; 600 for (pos = we.childList; pos.next != null; pos = pos.next); 601 pos.next = ese.whereExp; 602 } else if ( se.whereExp != null ) { se.whereExp.next = ese.whereExp; 604 se.whereExp = new OrExp(se.whereExp); 605 } 606 if ( ese.whereExp != null ) 608 ese.whereExp.replaceSelectExpRef(ese, se); 609 return true; 610 } 611 612 public Object arriveMultiplyNode(MultiplyNode node, Object msg) { 613 Context ctx = (Context)msg; 614 Node childList = node.childList; 615 616 SqlExp e = processMultiplyNodeChild(ctx.root, childList, null, ctx.args); 617 MultiplyExp ans = new MultiplyExp(e, node.ops); 618 for (Node c = childList.next; c != null; c = c.next) { 619 e = e.next = processMultiplyNodeChild(ctx.root, c, e, ctx.args); 620 } 621 return ans; 622 } 623 624 private SqlExp processMultiplyNodeChild(SelectExp root, Node c, 625 SqlExp leftSibling, Node args) { 626 SqlExp e = toSqlExp(c, root, leftSibling, 0, args); 627 if (e.next != null) { 628 throw BindingSupportImpl.getInstance().runtime( 629 "Expressions consisting of multiple columns may not be used" + 630 "with * or /"); 631 } 632 return e; 633 } 634 635 public Object arriveAddNode(AddNode node, Object msg) { 636 Context ctx = (Context)msg; 637 Node childList = node.childList; 638 SqlExp e = processAddNodeChild(ctx.root, childList, null, ctx.args); 639 AddExp ans = new AddExp(e, node.ops); 640 if (node.asValue != null) ans.setExpAlias(node.asValue); 641 for (Node c = childList.next; c != null; c = c.next) { 642 e = e.next = processAddNodeChild(ctx.root, c, e, ctx.args); 643 } 644 return ans; 645 } 646 647 private SqlExp processAddNodeChild(SelectExp root, Node c, SqlExp leftSibling, 648 Node args) { 649 SqlExp e = toSqlExp(c, root, leftSibling, 0, args); 650 if (e.next != null) { 651 throw BindingSupportImpl.getInstance().runtime( 652 "Expressions consisting of multiple columns may not be used" + 653 "with + or -"); 654 } 655 return e; 656 } 657 658 public Object arriveUnaryOpNode(UnaryOpNode node, Object msg) { 659 Context ctx = (Context)msg; 660 return new UnaryOpExp(toSqlExp(node.childList, ctx.root, 661 ctx.leftSibling, ctx.method, ctx.args), node.op); 662 } 663 664 public Object arriveCompareOpNode(CompareOpNode node, Object msg) { 665 Context ctx = (Context)msg; 666 Node childList = node.childList; 667 SqlExp left = toSqlExp(childList, ctx.root, null, ctx.method, ctx.args); 668 SqlExp right = toSqlExp(childList.next, ctx.root, left, ctx.method, ctx.args); 669 if (left.next == null && right.next == null) { 670 int op; 671 switch (node.op) { 672 case CompareOpNode.GT: op = BinaryOpExp.GT; break; 673 case CompareOpNode.LT: op = BinaryOpExp.LT; break; 674 case CompareOpNode.GE: op = BinaryOpExp.GE; break; 675 case CompareOpNode.LE: op = BinaryOpExp.LE; break; 676 default: 677 throw BindingSupportImpl.getInstance().internal( 678 "Unknown op: " + node.op); 679 } 680 return new BinaryOpExp(left, op, right); 681 } 682 throw BindingSupportImpl.getInstance().runtime( 683 "Expressions consisting of multiple columns may not be compared " + 684 "with >, <, >= or <=\n"); 685 } 686 687 public Object arriveUnaryNode(UnaryNode node, Object msg) { 688 Context ctx = (Context)msg; 689 return toSqlExp(node.childList, ctx.root, ctx.leftSibling, 690 ctx.method, ctx.args); 691 } 692 693 public Object arriveCastNode(CastNode node, Object msg) { 694 Context ctx = (Context)msg; 695 return toSqlExp(node.childList, ctx.root, ctx.leftSibling, 696 ctx.method, ctx.args); 697 } 698 699 702 private void addToParamNode(SqlParamUsage u, ParamNode n) { 703 if (n.usageList == null) { 704 n.usageList = u; 705 } else { 706 SqlParamUsage p = (SqlParamUsage)n.usageList; 707 for (; p.next != null; p = p.next); 708 p.next = u; 709 } 710 } 711 712 public Object arriveParamNode(ParamNode node, Object msg) { 713 Context ctx = (Context)msg; 714 SqlExp leftSibling = ctx.leftSibling; 715 SelectExp root = ctx.root; 716 Node args = ctx.args; 717 718 SqlParamUsage u = new SqlParamUsage(); 719 addToParamNode(u, node); 720 if (leftSibling instanceof ColumnExp) { 721 ColumnExp left = (ColumnExp)leftSibling; 722 u.jdbcField = left.jdbcField; 723 u.col = left.col; 724 SqlExp pos = u.expList = new ParamExp(u.jdbcType, u); 725 for (;;) { 726 if ((left = (ColumnExp)left.next) == null) break; 727 pos = pos.next = new ParamExp(left.getJdbcType(), u); 728 } 729 } else { 730 if (leftSibling == null) { 731 735 if (java.util.Collection .class.isAssignableFrom( 736 MDStaticUtils.toSimpleClass(node.getType())) 737 && (args instanceof FieldNode || args instanceof FieldNavNode)) { 738 CollectionParamExp collectionParamExp = 739 (CollectionParamExp)toSqlExp(args, 740 root, leftSibling, MethodNode.CONTAINS_PARAM, null); 741 u.expList = collectionParamExp; 742 u.jdbcField = collectionParamExp.field.jdbcField; 743 u.col = collectionParamExp.field.col; 744 u.jdbcType = collectionParamExp.field.getJdbcType(); 745 u.javaTypeCode = collectionParamExp.field.getJavaTypeCode(); 746 u.classIndex = collectionParamExp.field.getClassIndex(); 747 return collectionParamExp; 748 } 749 throw BindingSupportImpl.getInstance().internal( 750 "not implemented (leftSibling == null)"); 751 } 752 if (leftSibling.next != null) { 753 throw BindingSupportImpl.getInstance().internal( 754 "not implemented (leftSibling.next != null)"); 755 } 756 u.expList = new ParamExp(leftSibling.getJdbcType(), u); 757 } 758 if (u.jdbcField == null) { 759 u.jdbcType = leftSibling.getJdbcType(); 760 u.javaTypeCode = leftSibling.getJavaTypeCode(); 761 u.classIndex = leftSibling.getClassIndex(); 762 } 763 return u.expList; 764 } 765 766 public Object arriveParamNodeProxy(ParamNodeProxy node, Object msg) { 767 Context ctx = (Context)msg; 768 return toSqlExp(node.getParamNode(), ctx.root, ctx.leftSibling, 769 ctx.method, ctx.args); 770 } 771 772 public Object arriveVarNode(VarNode node, Object msg) { 773 SelectExp jdbcSelectExp = (SelectExp)node.getStoreExtent(); 774 if (node.getCmd() != null) { 776 JdbcColumn[] cols = jdbcSelectExp.table.pk; 777 ColumnExp ans = new ColumnExp(cols[0], jdbcSelectExp, null); 778 SqlExp e = ans; 779 int nc = cols.length; 780 for (int i = 1; i < nc; i++) { 781 e = e.next = new ColumnExp(cols[i], jdbcSelectExp, null); 782 } 783 return ans; 784 } else { 785 JdbcLinkCollectionField jdbcField = 786 (JdbcLinkCollectionField)node.getFmd().storeField; 787 return new ColumnExp(jdbcField.valueColumns[0], 788 (SelectExp)node.getFieldExtent(), null); 789 } 790 } 791 792 public Object arriveVarNodeProxy(VarNodeProxy node, Object msg) { 793 Context ctx = (Context)msg; 794 return toSqlExp(node.getVarNode(), ctx.root, ctx.leftSibling, 795 ctx.method, ctx.args); 796 } 797 798 public Object arriveReservedFieldNode(ReservedFieldNode node, Object msg) { 799 ClassMetaData target = node.getTarget(); 800 SelectExp candidateSelectExp = comp.getCandidateSelectExp(); 801 JdbcColumn[] pk = ((JdbcClass)target.storeClass).table.pk; 802 ColumnExp list = new ColumnExp(pk[0], candidateSelectExp, null); 803 list.cmd = target; 804 SqlExp e = list; 805 int nc = pk.length; 806 for (int i = 1; i < nc; i++) { 807 e = e.next = new ColumnExp(pk[i], candidateSelectExp, null); 808 } 809 return list; 810 } 811 812 public Object arriveAggregateCountStarNode(AggregateCountStarNode node, 813 Object msg) { 814 return new AggregateCountStarExp(node.asValue); 815 } 816 817 public Object arriveAggregateNode(AggregateNode node, Object msg) { 818 Context ctx = (Context)msg; 819 SqlExp se = toSqlExp(node.childList, ctx.root, ctx.leftSibling, 820 ctx.method, ctx.args); 821 String op; 822 switch (node.getType()) { 823 case AggregateNode.TYPE_AVG: 824 op = "AVG"; 825 break; 826 case AggregateNode.TYPE_COUNT: 827 op = "COUNT"; 828 break; 829 case AggregateNode.TYPE_MAX: 830 op = "MAX"; 831 break; 832 case AggregateNode.TYPE_MIN: 833 op = "MIN"; 834 break; 835 case AggregateNode.TYPE_SUM: 836 op = "SUM"; 837 break; 838 default: 839 throw BindingSupportImpl.getInstance().internal( 840 "Uknown AggregateNode type " + node.getType()); 841 }; 842 return new AggregateExp(se, op, node.asValue); 843 } 844 845 public Object arriveAsValueNode(AsValueNode node, Object msg) { 846 return new ColumnExp(node.value); 847 } 848 849 public Object arriveGroupingNode(GroupingNode node, Object msg) { 850 Context ctx = (Context)msg; 851 SqlExp head = new SqlExp(); 852 SqlExp current = head; 853 for (Node n = node.childList; n != null; n = n.next) { 854 if (n instanceof ReservedFieldNode) { 855 current.next = new GroupByThisExp(); 856 current = current.next; 857 } else { 858 current.next = toSqlExp(n, ctx.root, ctx.leftSibling, 859 ctx.method, ctx.args); 860 current = current.next; 861 } 862 } 863 return head.next; 864 } 865 866 public Object arriveResultNode(ResultNode node, Object msg) { 867 Context ctx = (Context)msg; 868 SqlExp head = new SqlExp(); 869 SqlExp current = head; 870 for (Node n = node.childList; n != null; n = n.next) { 871 if (n instanceof ReservedFieldNode) continue; 872 current.next = toSqlExp(n, ctx.root, ctx.leftSibling, ctx.method, 873 ctx.args); 874 current = current.next; 875 } 876 return head.next; 877 } 878 879 public Object arriveVarBindingNode(VarBindingNode node, Object msg) { 880 SelectExp se = (SelectExp)node.getVar().getStoreExtent(); 881 return new ExistsExp(se, true); 882 } 883 884 } 885 886 | Popular Tags |