001package gudusoft.gsqlparser.stmt; 002 003import gudusoft.gsqlparser.*; 004import gudusoft.gsqlparser.nodes.*; 005import gudusoft.gsqlparser.nodes.hana.TTimeTravel; 006import gudusoft.gsqlparser.nodes.hive.*; 007import gudusoft.gsqlparser.nodes.mssql.TOptionClause; 008import gudusoft.gsqlparser.nodes.THierarchical; 009import gudusoft.gsqlparser.nodes.teradata.TExpandOnClause; 010import gudusoft.gsqlparser.sqlenv.ESQLDataObjectType; 011import gudusoft.gsqlparser.sqlenv.TSQLEnv; 012import gudusoft.gsqlparser.sqlenv.TSQLTable; 013 014import java.util.ArrayList; 015import java.util.Collections; 016import java.util.TreeMap; 017 018 019/** 020 * Class {@link gudusoft.gsqlparser.stmt.TSelectSqlStatement } represents query specification, query expression and select statement. 021 * <br><br><b>query specification</b> including following clause: 022 * <ul> 023 * <li>select list {@link #getResultColumnList}</li> 024 * <li>from clause {@link #joins}</li> 025 * <li>where clause {@link #getWhereClause}</li> 026 * <li>group clause {@link #getGroupByClause}</li> 027 * <li>having clause {@link #getGroupByClause}</li> 028 * </ul> 029 * In some databases, query specification also known as sub-select. 030 * 031 * <br><br><b>query expression</b> including all elements in query specification and following clause: 032 * <ul> 033 * <li>order by clause {@link #getOrderbyClause}</li> 034 * <li>offset clause {@link #getOffsetClause}</li> 035 * <li>for clause</li> 036 * </ul> 037 * In some databases, query expression also known as full-select. 038 * <br>It is a component of the select-statement, the INSERT statement, and the CREATE VIEW statement. 039 * And a full-select that is enclosed in parentheses is sometimes called a sub-query. 040 * 041 * <br><br>select statement including all elements in query expression and following clause: 042 * <ul> 043 * <li>compute clause {@link #getComputeClause}</li> 044 * <li>for update clause {@link #getForUpdateClause}</li> 045 * <li>optimizer hint</li> 046 * <li>ctes {@link #getCteList}</li> 047 * </ul> 048 * Lots of clauses on this level are db vendors specific. 049 * 050 051 * <br><br> 052 * Use {@link #isCombinedQuery} to check whether UNION, EXCEPT and INTERSECT operators is used. 053 * If returns true, use {@link #getLeftStmt} and {@link #getRightStmt} to get query expression. 054 * You need to check {@link #isCombinedQuery} recursively, all clauses of {@link gudusoft.gsqlparser.stmt.TSelectSqlStatement} 055 * only available when this function returns false. 056 * 057 */ 058 059public class TSelectSqlStatement extends TCustomSqlStatement { 060 061 // 如果是 combined query, 并且当前select 没有预先设定的 endToken, 则取最右边 query 的 endToken 062 public TSourceToken getEndToken() { 063 if (super.getEndToken() != null) return super.getEndToken(); 064 if (this.isCombinedQuery()){ 065 return this.getRightStmt().getEndToken(); 066 }else{ 067 return super.getEndToken(); 068 } 069 } 070 071 public void setSubQueryInFromClauseCanUseParentSelectAsEnclosingScope(boolean subQueryInFromClauseCanUseParentSelectAsEnclosingScope) { 072 this.subQueryInFromClauseCanUseParentSelectAsEnclosingScope = subQueryInFromClauseCanUseParentSelectAsEnclosingScope; 073 } 074 075 public boolean isSubQueryInFromClauseCanUseParentSelectAsEnclosingScope() { 076 return subQueryInFromClauseCanUseParentSelectAsEnclosingScope; 077 } 078 079 private boolean subQueryInFromClauseCanUseParentSelectAsEnclosingScope = false; 080 081 boolean starColumnPushedDown = false; 082 083 public boolean isStarColumnPushedDown() { 084 return starColumnPushedDown; 085 } 086 087 public void setStarColumnPushedDown(boolean starColumnPushedDown) { 088 this.starColumnPushedDown = starColumnPushedDown; 089 } 090 091 /** 092 * 在 sql script 中,和该 relation 关联的 attribute。 093 * select a from t; 094 * attribute a 就是 relation t 的 referenceAttribute, 如果没有 metadata and ddl, 095 * relation t 的 getAttributes() 应该可以推断出包含 a, 但 t 是否还包含其他的 attribute 就无从得知。 096 */ 097 098 @Override 099 public ArrayList<TAttributeNode> getAttributes(){ 100 if (this.getFromClause() == null) return null; 101 102 return this.getFromClause().getAttributes(); 103 104// relationAttributes.clear(); 105// for(TTable table:getRelations()){ 106// relationAttributes.addAll(table.getAttributes()); 107// } 108// 109// if (relationAttributes.size() > 0){ 110// TBaseType.log ("relationAttributes.size() in select is :"+relationAttributes.size() 111// +", relation size: "+getRelations().size() 112// +", relation 0 type:"+getRelations().get(0).getTableType() 113// ,1); 114// // System.out.println(this.toString()); 115// } 116// 117// return relationAttributes; 118 } 119 120 ArrayList<TAttributeNode> relationAttributes = new ArrayList<>(); 121 122// private TExpression skipOffset; 123// private TExpression firstMax; 124// private TExpression limitMax; 125// 126// public void setSkipOffset(TExpression skipOffset) { 127// this.skipOffset = skipOffset; 128// } 129// 130// public void setFirstMax(TExpression firstMax) { 131// this.firstMax = firstMax; 132// } 133// 134// public void setLimitMax(TExpression limitMax) { 135// this.limitMax = limitMax; 136// } 137// 138// /** 139// * Informix skip offset 140// * @return skip offset 141// */ 142// public TExpression getSkipOffset() { 143// 144// return skipOffset; 145// } 146// 147// /** 148// * Informix first Max 149// * @return first Max 150// */ 151// public TExpression getFirstMax() { 152// return firstMax; 153// } 154// 155// /** 156// * Informix limit max 157// * @return limit max 158// */ 159// public TExpression getLimitMax() { 160// return limitMax; 161// } 162 163 private ArrayList<TSelectSqlStatement> multiSelectStatements; 164 165 /** 166 * Hive, from ... select, select,... 167 * <br> Multiple select statement in Hive from query syntax 168 * 169 * @return Multiple select statement in Hive from query syntax 170 */ 171 public ArrayList<TSelectSqlStatement> getMultiSelectStatements() { 172 if(multiSelectStatements == null){ 173 multiSelectStatements = new ArrayList<>(); 174 } 175 return multiSelectStatements; 176 } 177 178 private TClusterBy clusterBy; 179 180 public void setClusterBy(TClusterBy clusterBy) { 181 this.clusterBy = clusterBy; 182 } 183 184 public TClusterBy getClusterBy() { 185 return clusterBy; 186 } 187 188 private boolean isConsume; 189 190 public void setConsume(boolean consume) { 191 isConsume = consume; 192 } 193 194 public boolean isConsume() { 195 return isConsume; 196 } 197 198 private TStatementList hiveBodyList = null; 199 200 /** 201 * @deprecated since 2.6.3.5, please use {@link #getMultiSelectStatements()} to retrieve 202 * multimple select statement in Hive from query ... select, select, ... 203 * 204 * @return 205 */ 206 public TStatementList getHiveBodyList() { 207 if (hiveBodyList == null) 208 hiveBodyList = new TStatementList(); 209 return hiveBodyList; 210 } 211 212 public void setSelectModifiers(ArrayList<TSelectModifier> selectModifiers) { 213 this.selectModifiers = selectModifiers; 214 } 215 216 public ArrayList<TSelectModifier> getSelectModifiers() { 217 return selectModifiers; 218 } 219 220 private ArrayList<TSelectModifier> selectModifiers; 221 222 223 private TTimeTravel timeTravel; // hana 224 private THintClause hintClause; //hana 225 226 public void setTimeTravel(TTimeTravel timeTravel) { 227 setNewSubNode(this.timeTravel,timeTravel,getAnchorNode()); 228 this.timeTravel = timeTravel; 229 } 230 231 public void setHintClause(THintClause hintClause) { 232 setNewSubNode(this.hintClause,hintClause,getAnchorNode()); 233 this.hintClause = hintClause; 234 } 235 236 237 public TTimeTravel getTimeTravel() { 238 239 return timeTravel; 240 } 241 242 public THintClause getHintClause() { 243 return hintClause; 244 } 245 246 private int parenthesisCount = 0; 247 private int parenthesisCountBeforeOrder = 0; 248 249 public void setFetchFirstClause(TFetchFirstClause fetchFirstClause) { 250 setNewSubNode(this.fetchFirstClause,fetchFirstClause,getAnchorNode()); 251 this.fetchFirstClause = fetchFirstClause; 252 } 253 254 255 public void setParenthesisCount(int parenthesisCount) { 256 this.parenthesisCount = parenthesisCount; 257 } 258 259 public void setParenthesisCountBeforeOrder(int parenthesisCountBeforeOrder) { 260 this.parenthesisCountBeforeOrder = parenthesisCountBeforeOrder; 261 } 262 263 public void setAll(boolean all) { 264 this.all = all; 265 } 266 267 public void setSetOperatorType(ESetOperatorType setOperatorType) { 268 this.setOperatorType = setOperatorType; 269 } 270 271 public void setWindowClause(TWindowClause windowClause) { 272 setNewSubNode(this.windowClause,windowClause,getAnchorNode()); 273 this.windowClause = windowClause; 274 } 275 276 public void setLockingClauses(TPTNodeList<TLockingClause> lockingClauses) { 277 this.lockingClauses = lockingClauses; 278 } 279 280 public void setSelectDistinct(TSelectDistinct selectDistinct) { 281 setNewSubNode(this.selectDistinct,selectDistinct,getAnchorNode()); 282 this.selectDistinct = selectDistinct; 283 } 284 285 public void setExpandOnClause(TExpandOnClause expandOnClause) { 286 setNewSubNode(this.expandOnClause,expandOnClause,getAnchorNode()); 287 this.expandOnClause = expandOnClause; 288 } 289 290 291 public void setSetOperator(int setOperator) { 292 this.setOperator = setOperator; 293 } 294 295 public void setLeftStmt(TSelectSqlStatement leftStmt) { 296 this.leftStmt = leftStmt; 297 } 298 299 public void setRightStmt(TSelectSqlStatement rightStmt) { 300 this.rightStmt = rightStmt; 301 } 302 303 public void setValueClause(TValueClause valueClause) { 304 setNewSubNode(this.valueClause,valueClause,getAnchorNode()); 305 this.valueClause = valueClause; 306 } 307 308 public void setOracleHint(String oracleHint) { 309 this.oracleHint = oracleHint; 310 } 311 312 public void setHiveHintClause(THiveHintClause hiveHintClause) { 313 setNewSubNode(this.hiveHintClause,hiveHintClause,getAnchorNode()); 314 this.hiveHintClause = hiveHintClause; 315 } 316 317 318 public void setTransformClause(THiveTransformClause transformClause) { 319 setNewSubNode(this.transformClause,transformClause,getAnchorNode()); 320 this.transformClause = transformClause; 321 } 322 323 public void setDistributeBy(TDistributeBy distributeBy) { 324 setNewSubNode(this.distributeBy,distributeBy,getAnchorNode()); 325 this.distributeBy = distributeBy; 326 } 327 328 329 public void setIntoClause(TIntoClause intoClause) { 330 setNewSubNode(this.intoClause,intoClause,getAnchorNode()); 331 this.intoClause = intoClause; 332 } 333 334 public void setOrderbyClause(TOrderBy newOrderbyClause) { 335 setNewSubNode(this.orderbyClause,newOrderbyClause,getAnchorNode()); 336 this.orderbyClause = newOrderbyClause; 337 } 338 339// public void setOrderbyClause(TOrderBy newOrderbyClause, TParseTreeNode anchorNode) { 340// if (newOrderbyClause == null){ 341// //remove 342// this.orderbyClause.removeTokens(); 343// this.orderbyClause = null; 344// }else{ 345// if (this.orderbyClause != null){ 346// this.orderbyClause.replaceWithNewNode(newOrderbyClause); 347// }else{ 348// doAppendNewNode(newOrderbyClause,anchorNode,false); 349// } 350// this.orderbyClause = newOrderbyClause; 351// } 352// } 353 354 public void setQualifyClause(TQualifyClause qualifyClause) { 355 setNewSubNode(this.qualifyClause,qualifyClause,getAnchorNode()); 356 this.qualifyClause = qualifyClause; 357 } 358 359 public void setSampleClause(TSampleClause sampleClause) { 360 setNewSubNode(this.sampleClause,sampleClause,getAnchorNode()); 361 this.sampleClause = sampleClause; 362 } 363 364 public void setTeradataWithClause(TTeradataWithClause teradataWithClause) { 365 setNewSubNode(this.teradataWithClause,teradataWithClause,getAnchorNode()); 366 this.teradataWithClause = teradataWithClause; 367 } 368 369 public void setForUpdateClause(TForUpdate forUpdateClause) { 370 setNewSubNode(this.forUpdateClause,forUpdateClause,getAnchorNode()); 371 this.forUpdateClause = forUpdateClause; 372 } 373 374 375 public void setComputeClause(TComputeClause computeClause) { 376 this.computeClause = computeClause; 377 } 378 379 public void setGroupByClause(TGroupBy groupByClause) { 380 setNewSubNode(this.groupByClause,groupByClause,getAnchorNode()); 381 this.groupByClause = groupByClause; 382 } 383 384 385 public void setHierarchicalClause(THierarchical hierarchicalClause) { 386 setNewSubNode(this.hierarchicalClause,hierarchicalClause,getAnchorNode()); 387 this.hierarchicalClause = hierarchicalClause; 388 } 389 390 391 public void setLimitClause(TLimitClause limitClause) { 392 setNewSubNode(this.limitClause,limitClause,getAnchorNode()); 393 this.limitClause = limitClause; 394 } 395 396 public void setOffsetClause(TOffsetClause offsetClause) { 397 setNewSubNode(this.offsetClause,offsetClause,getAnchorNode()); 398 this.offsetClause = offsetClause; 399 } 400 401 public void setOptionClause(TOptionClause optionClause) { 402 setNewSubNode(this.optionClause,optionClause,getAnchorNode()); 403 this.optionClause = optionClause; 404 } 405 406 public void setIsolationClause(TIsolationClause isolationClause) { 407 setNewSubNode(this.isolationClause,isolationClause,getAnchorNode()); 408 this.isolationClause = isolationClause; 409 } 410 411// public void setHiveClusterBy(THiveClusterBy hiveClusterBy) { 412// setNewSubNode(this.hiveClusterBy,hiveClusterBy,getAnchorNode()); 413// this.hiveClusterBy = hiveClusterBy; 414// } 415 416 417 public void setSortBy(TSortBy sortBy) { 418 setNewSubNode(this.sortBy,sortBy,getAnchorNode()); 419 this.sortBy = sortBy; 420 } 421 422 public void setIntoTableClause(TIntoTableClause intoTableClause) { 423 setNewSubNode(this.intoTableClause,intoTableClause,getAnchorNode()); 424 this.intoTableClause = intoTableClause; 425 } 426 427 public int getParenthesisCountBeforeOrder() { 428 return parenthesisCountBeforeOrder; 429 } 430 431 public int getParenthesisCount() { 432 return parenthesisCount; 433 } 434 435 private boolean queryOfCTE; 436 437 public void setQueryOfCTE(boolean queryOfCTE) { 438 this.queryOfCTE = queryOfCTE; 439 } 440 441 public boolean isQueryOfCTE() { 442 return queryOfCTE; 443 } 444 445 /** 446 * Offset clause. 447 * <br> 448 * <pre>OFFSET 2 ROWS FETCH NEXT 4 ROWS ONLY;</pre> 449 * @return {@link TOffsetClause offset clause} 450 */ 451 public TOffsetClause getOffsetClause() { 452 return offsetClause; 453 } 454 455 /** 456 * Fetch first/next clause 457 * <br> 458 * <pre>OFFSET 2 ROWS FETCH NEXT 4 ROWS ONLY;</pre> 459 * @return {@link TFetchFirstClause fetch first/next clause} 460 */ 461 public TFetchFirstClause getFetchFirstClause() { 462 463 return fetchFirstClause; 464 } 465 466 private TFetchFirstClause fetchFirstClause; 467 private TOffsetClause offsetClause; 468 469 private TOptionClause optionClause; 470 471 /** 472 * 473 * @return {@link TOptionClause sql server option clause} 474 * 475 * @see gudusoft.gsqlparser.nodes.mssql.TOptionClause 476 */ 477 public TOptionClause getOptionClause() { 478 return optionClause; 479 } 480 481 482 /** 483 * 484 * @return {@link TIsolationClause isolation clause} 485 */ 486 public TIsolationClause getIsolationClause() { 487 return isolationClause; 488 } 489 490 private TIsolationClause isolationClause; 491 492// private THiveClusterBy hiveClusterBy; 493// 494// /** 495// * 496// * @return {@link THiveClusterBy Hive cluster by clause} 497// */ 498// public THiveClusterBy getHiveClusterBy() { 499// return hiveClusterBy; 500// } 501 502 private TSortBy sortBy; 503 504 /** 505 * 506 * @return {@link TSortBy Hive sort by clause} 507 */ 508 public TSortBy getSortBy() { 509 return sortBy; 510 } 511 512 private TIntoTableClause intoTableClause; 513 514 /** 515 * 516 * @return {@link TIntoTableClause informix into table clause} 517 */ 518 public TIntoTableClause getIntoTableClause() { 519 return intoTableClause; 520 } 521 522 public void setSelectToken(TSourceToken selectToken) { 523 this.selectToken = selectToken; 524 } 525 526 /** 527 * 528 * @return SELECT token of this query. 529 */ 530 public TSourceToken getSelectToken() { 531 return selectToken; 532 } 533 534 private TSourceToken selectToken = null; 535 536 public static final int SET_OPERATOR_NONE = 0; 537 538 public static final int setOperator_union = 1; 539 public static final int setOperator_unionall = 2; 540 public static final int SET_OPERATOR_UNIONDISTINCT = 9; 541 542 public static final int setOperator_intersect = 3; 543 public static final int setOperator_intersectall = 4; 544 public static final int SET_OPERATOR_INTERSECTDISTINCT = 10; 545 546 public static final int setOperator_minus = 5; 547 public static final int setOperator_minusall = 6; 548 public static final int SET_OPERATOR_MINUSDISTINCT = 11; 549 550 public static final int setOperator_except = 7; 551 public static final int setOperator_exceptall = 8; 552 public static final int SET_OPERATOR_EXCEPTDISTINCT = 11; 553 554 public boolean isAll() { 555 return all; 556 } 557 558 private boolean all = false; 559 560 public boolean isSetOpDistinct() { 561 return setOpDistinct; 562 } 563 564 private boolean setOpDistinct = false; 565 private ESetOperatorType setOperatorType = ESetOperatorType.none; 566 567 public ESetOperatorType getSetOperatorType() { 568 return setOperatorType; 569 } 570 571 private TWindowClause windowClause; 572 573 /** 574 * 575 * @return {@link TWindowClause window clause.} 576 */ 577 public TWindowClause getWindowClause() { 578 return windowClause; 579 } 580 581 private TPTNodeList <TLockingClause> lockingClauses; 582 583 /** 584 * PostgreSQL, for update of, for read only. 585 * <br> 586 * @return list of {@link TLockingClause} 587 */ 588 public TPTNodeList<TLockingClause> getLockingClauses() { 589 return lockingClauses; 590 } 591 592 /** 593 * 594 * @return {@link TSelectDistinct distinct clause} 595 */ 596 public TSelectDistinct getSelectDistinct() { 597 return selectDistinct; 598 } 599 600 private TSelectDistinct selectDistinct = null; 601 602 /** 603 * 604 * @return {@link gudusoft.gsqlparser.nodes.TIntoClause into clause} 605 */ 606 public TIntoClause getIntoClause() { 607 return intoClause; 608 } 609 610 private TIntoClause intoClause = null; 611 612 613 private TOrderBy orderbyClause; 614 615 /** 616 * @return {@link TOrderBy order by clause} 617 */ 618 public TOrderBy getOrderbyClause() { 619 return orderbyClause; 620 } 621 622 public TSelectSqlStatement(EDbVendor dbvendor) { 623 super(dbvendor); 624 sqlstatementtype = ESqlStatementType.sstselect; 625 } 626 627 void buildsql() { 628 } 629 630 void clear() { 631 } 632 633 String getasprettytext() { 634 return ""; 635 } 636 637 void iterate(TVisitorAbs pvisitor) { 638 } 639 640 /** 641 * 642 * @return {@link TQualifyClause teradata qualify clause} 643 */ 644 public TQualifyClause getQualifyClause() { 645 return qualifyClause; 646 } 647 648 private TQualifyClause qualifyClause = null; 649 private TSampleClause sampleClause = null; 650 private TTeradataWithClause teradataWithClause = null; 651 652 /** 653 * @return {@link TTeradataWithClause Teradata with clause } 654 */ 655 public TTeradataWithClause getTeradataWithClause() { 656 return teradataWithClause; 657 } 658 659 /** 660 * 661 * @return {@link gudusoft.gsqlparser.nodes.TSampleClause SQL Server sample clause} 662 */ 663 public TSampleClause getSampleClause() { 664 return sampleClause; 665 } 666 667 /** 668 * @return {@link gudusoft.gsqlparser.nodes.TForUpdate for update clause} 669 */ 670 public TForUpdate getForUpdateClause() { 671 return forUpdateClause; 672 } 673 674 private TForUpdate forUpdateClause; 675 676 /** 677 * 678 * @return {@link TComputeClause SQL Server compute clause} 679 */ 680 public TComputeClause getComputeClause() { 681 return computeClause; 682 } 683 684 private TComputeClause computeClause = null; 685 686 /** 687 * @return {@link TGroupBy group by clause and having clause} 688 */ 689 public TGroupBy getGroupByClause() { 690 return groupByClause; 691 } 692 693 private TGroupBy groupByClause = null; 694 695 696 /** 697 * Oracle hierarchical_query_clause 698 * @return {@link gudusoft.gsqlparser.nodes.THierarchical Oracle hierarchical_query_clause} 699 */ 700 public THierarchical getHierarchicalClause() { 701 return hierarchicalClause; 702 } 703 704 private THierarchical hierarchicalClause = null; 705 706 /** 707 * MySQL,PostgreSQL limit clause 708 * @return {@link TLimitClause MySQL,PostgreSQL limit clause} 709 */ 710 public TLimitClause getLimitClause() { 711 return limitClause; 712 } 713 714 private TLimitClause limitClause = null; 715 716 717 private TExpandOnClause expandOnClause; 718 719 /** 720 * 721 * @return {@link TExpandOnClause Teradata expand on clause} 722 */ 723 public TExpandOnClause getExpandOnClause() { 724 return expandOnClause; 725 } 726 727 /** 728 * 729 * The set operators UNION, EXCEPT, and INTERSECT correspond to the relational operators union, difference, and intersection. 730 * @return set operator of this statement.If a set operator is not used, setOperator_none will be returned. 731 * otherwise, set operand can be fetched by using getLeftStmt() and getRightStmt(). 732 * 733 * @deprecated As of v1.6.4.2, use {@link #getSetOperatorType()} and {@link #isAll()} instead. 734 */ 735 public int getSetOperator() { 736 return setOperator; 737 } 738 739 private int setOperator = 0; 740 741 /** 742 * Valid when {@link #getSetOperator} is not setOperator_none. 743 * @return left side query expression 744 */ 745 public TSelectSqlStatement getLeftStmt() { 746 return leftStmt; 747 } 748 749 public TSelectSqlStatement getFarLeftStmt() { 750 if (leftStmt.isCombinedQuery()) return leftStmt.getFarLeftStmt(); 751 else return leftStmt; 752 } 753 754 /** 755 * Valid when {@link #getSetOperator} is not setOperator_none. 756 * @return right side query expression. 757 */ 758 public TSelectSqlStatement getRightStmt() { 759 return rightStmt; 760 } 761 762 private TSelectSqlStatement leftStmt; 763 private TSelectSqlStatement rightStmt; 764 765 private TValueClause valueClause = null; 766 767 private String oracleHint; 768 769 private String hint; 770 771 private boolean isValueClause = false; 772 773 public boolean isValueClause() { 774 return isValueClause; 775 } 776 777 /** 778 * Hint for Oracle and MySQL 779 * 780 * @return hint string 781 */ 782 public String getHint() { 783 return hint; 784 } 785 786 /** 787 * Hint for Oracle and MySQL 788 * 789 * @return hint string. 790 */ 791 /** 792 * @deprecated As of 2.0.4.5, replaced by {@link #getHint()} 793 */ 794 public String getOracleHint() { 795 return oracleHint; 796 } 797 798 private THiveHintClause hiveHintClause; 799 800 /** 801 * 802 * @return {@link THiveHintClause Hive hint clause} 803 */ 804 public THiveHintClause getHiveHintClause() { 805 return hiveHintClause; 806 } 807 808 private THiveTransformClause transformClause; 809 810 /** 811 * 812 * @return {@link THiveTransformClause Hive from clause} 813 */ 814 public THiveTransformClause getTransformClause() { 815 return transformClause; 816 } 817 818 private TDistributeBy distributeBy; 819 820 /** 821 * 822 * @return {@link TDistributeBy Hive distribute by clause} 823 */ 824 public TDistributeBy getDistributeBy() { 825 return distributeBy; 826 } 827 828 /** 829 * DB2 value clause 830 * @return {@link TValueClause DB2 value clause} 831 */ 832 public TValueClause getValueClause() { 833 return valueClause; 834 } 835 836 public void setChildOfCombinedQuery(boolean childOfCombinedQuery) { 837 this.childOfCombinedQuery = childOfCombinedQuery; 838 } 839 840 public boolean isChildOfCombinedQuery() { 841 842 return childOfCombinedQuery; 843 } 844 845 private boolean childOfCombinedQuery = false; 846 847 848 @Override 849 public TreeMap<String,TResultColumn> getExpandedResultColumns() { 850 if (this.setOperatorType == ESetOperatorType.none){ 851 return super.getExpandedResultColumns(); 852 }else{ 853 return this.getLeftStmt().getExpandedResultColumns(); 854 } 855 } 856 857 private ArrayList<TSelectSqlStatement> flattenSelects = null; 858 859 public ArrayList<TSelectSqlStatement> getFlattenedSelects() { 860 if (!isCombinedQuery()) return null; 861 if (this.flattenSelects != null) return this.flattenSelects; 862 863 this.flattenSelects = new ArrayList<TSelectSqlStatement>(); 864 this.flattenSelects.add(this.rightStmt); 865 doFlattenCombinedSelect(this.leftStmt,this.flattenSelects); 866 867 Collections.reverse(this.flattenSelects); 868 return flattenSelects; 869 } 870 871 void doFlattenCombinedSelect(TSelectSqlStatement select, ArrayList<TSelectSqlStatement> container){ 872 if (select.isCombinedQuery()){ 873 container.add(select.getRightStmt()); 874 doFlattenCombinedSelect(select.getLeftStmt(),container); 875 }else{ 876 container.add(select); 877 } 878 } 879 880 /** 881 * This function is used internal. DON'T call it explicitly. 882 * 883 * @param psql input query. 884 * @return zero means there is no syntax error detected. 885 */ 886 public int doParseStatement(TCustomSqlStatement psql) { 887 if (rootNode == null) return -1; 888 TSelectSqlNode selectNode = (TSelectSqlNode)rootNode; 889 890 if (this.sourcetokenlist.size() == 0){ 891 // subquery nested in other statements. 892 this.setStartToken(selectNode.getStartToken()); 893 this.setEndToken(selectNode.getEndToken()); 894 } 895 896 super.doParseStatement(psql); 897 this.selectToken = selectNode.getSelectToken(); 898 parenthesisCount = selectNode.getParenthesisCount(); 899 parenthesisCountBeforeOrder = selectNode.getParenthissisCountBeforeOrder(); 900 901 setOperator = selectNode.getSetOperator(); 902 switch (setOperator){ 903 case SET_OPERATOR_NONE: 904 setOperatorType = ESetOperatorType.none; 905 all = false; 906 break; 907 case setOperator_union: 908 setOperatorType = ESetOperatorType.union; 909 all = false; 910 break; 911 case setOperator_unionall: 912 setOperatorType = ESetOperatorType.union; 913 all = true; 914 break; 915 case SET_OPERATOR_UNIONDISTINCT: 916 setOperatorType = ESetOperatorType.union; 917 setOpDistinct = true; 918 break; 919 case setOperator_intersect: 920 setOperatorType = ESetOperatorType.intersect; 921 all = false; 922 break; 923 case setOperator_intersectall: 924 setOperatorType = ESetOperatorType.intersect; 925 all = true; 926 break; 927 case setOperator_except: 928 setOperatorType = ESetOperatorType.except; 929 all = false; 930 break; 931 case setOperator_exceptall: 932 setOperatorType = ESetOperatorType.except; 933 all = true; 934 break; 935 case setOperator_minus: 936 setOperatorType = ESetOperatorType.minus; 937 all = false; 938 break; 939 case setOperator_minusall: 940 setOperatorType = ESetOperatorType.minus; 941 all = true; 942 break; 943 case SET_OPERATOR_INTERSECTDISTINCT: 944 setOperatorType = ESetOperatorType.intersect; 945 setOpDistinct = true; 946 break; 947 case SET_OPERATOR_EXCEPTDISTINCT: 948 setOperatorType = ESetOperatorType.except; 949 setOpDistinct = true; 950 break; 951 } 952 953 if(selectNode.isCombinedQuery()){ 954 TCustomSqlStatement lcParentSql = psql; 955 if ((lcParentSql == null)||(!childOfCombinedQuery)){ 956 lcParentSql = this; 957 } 958 959 if (selectNode.cteList != null){ 960 this.setCteList(selectNode.cteList); 961 for(int i=0;i<getCteList().size();i++){ 962 // System.out.println("cte "+i); 963 getCteList().getCTE(i).doParse(this,ESqlClause.cte); 964 } 965 //this.getCteList().doParse(this,ESqlClause.cte); 966 } 967 968 //System.out.println("in union:"+ TBaseType.dummyInt++); 969 970 leftStmt = new TSelectSqlStatement(dbvendor); 971 leftStmt.rootNode = selectNode.getLeftNode(); 972// leftStmt.setStartToken(selectNode.getLeftNode().getStartToken()); 973// leftStmt.setEndToken(selectNode.getLeftNode().getEndToken()); 974 leftStmt.setChildOfCombinedQuery(true); 975 leftStmt.doParseStatement(lcParentSql); 976 977 rightStmt = new TSelectSqlStatement(dbvendor); 978 rightStmt.rootNode = selectNode.getRightNode(); 979// rightStmt.setStartToken(selectNode.getRightNode().getStartToken()); 980// rightStmt.setEndToken(selectNode.getRightNode().getEndToken()); 981 rightStmt.setChildOfCombinedQuery(true); 982 rightStmt.doParseStatement(lcParentSql); 983 984 if (selectNode.getOrderbyClause() != null){ 985 selectNode.getOrderbyClause().doParse(this,ESqlClause.orderby); 986 this.orderbyClause = selectNode.getOrderbyClause(); 987 } 988 989 this.limitClause = selectNode.getLimitClause(); 990 991 if (selectNode.getForupdateClause() != null){ 992 selectNode.getForupdateClause().doParse(this,ESqlClause.forUpdate); 993 this.forUpdateClause = selectNode.getForupdateClause(); 994 } 995 996 if (selectNode.getComputeClause() != null){ 997 selectNode.getComputeClause().doParse(this,ESqlClause.compute); 998 this.computeClause = selectNode.getComputeClause(); 999 } 1000 1001 1002// if (selectNode.getIntoClause() != null){ 1003// this.intoClause = selectNode.getIntoClause(); 1004// this.intoClause.doParse(this,ESqlClause.selectInto); 1005// } 1006 1007 this.optionClause = selectNode.getOptionClause(); 1008 1009 this.timeTravel = selectNode.getTimeTravel(); 1010 this.hintClause = selectNode.getHintClause(); 1011 1012 return 0; 1013 } 1014 1015 if (selectNode.getValueClause() != null){ 1016 this.valueClause = selectNode.getValueClause(); 1017 this.valueClause.doParse(this,ESqlClause.selectValue); 1018 isValueClause = true; 1019 return 0; 1020 } 1021 1022 if (selectNode.getTransformClause() != null){ 1023 this.transformClause = selectNode.getTransformClause(); 1024 this.transformClause.doParse(this,ESqlClause.transformClause); 1025 } 1026 1027 if (selectNode.cteList != null){ 1028 this.setCteList(selectNode.cteList); 1029 this.getCteList().doParse(this,ESqlClause.cte); 1030 } 1031 1032 if (selectNode.isHiveFromQuery()){ 1033 if(selectNode.getSelectSqlNodes() != null){ 1034 for(int i=1;i<selectNode.getSelectSqlNodes().size();i++){ 1035 //start from the second, the first select statement is represented by this class instance. 1036 1037 TSelectSqlStatement select = new TSelectSqlStatement(EDbVendor.dbvhive); 1038 select.rootNode = selectNode.getSelectSqlNodes().get(i); 1039 select.doParseStatement(this); 1040 this.getMultiSelectStatements().add(select); 1041 } 1042 } 1043 1044 // Hive: from query insert... 1045// if (selectNode.getFromTableList() != null){ 1046// TFromTable lcFromTable; 1047// TJoin lcJoin; 1048// 1049// for(int i=0; i<selectNode.getFromTableList().size();i++){ 1050// lcFromTable = selectNode.getFromTableList().getFromTable(i); 1051// TTable lcTable = null; 1052// 1053// if (lcFromTable.getFromtableType() != ETableSource.join){ 1054// lcJoin = new TJoin(); 1055// lcTable = analyzeFromTable(lcFromTable,true); 1056// lcTable.setEffectType(ETableEffectType.tetSelect); 1057// lcJoin.setTable(lcTable); 1058// lcJoin.setStartToken(lcJoin.getTable().getStartToken()); 1059// lcJoin.setEndToken(lcJoin.getTable().getEndToken()); 1060// lcJoin.setGsqlparser(getGsqlparser()); 1061// }else{ 1062// lcJoin = analyzeJoin(lcFromTable.getJoinExpr(),null,true); 1063// lcJoin.doParse(this, ESqlClause.join); 1064// 1065// if (lcFromTable.getLateralViewList() != null){ 1066// for(TLateralView lateralView:lcFromTable.getLateralViewList()){ 1067// addToTables(lateralView.createATable(this)); 1068// } 1069// } 1070// } 1071// 1072// joins.addJoin(lcJoin); 1073// } 1074// } 1075 1076 1077// if (selectNode.getHiveBodyList() != null){ 1078// for(int i = 0; i<selectNode.getHiveBodyList().size();i++){ 1079// TParseTreeNode node1 = selectNode.getHiveBodyList().get(i); 1080// switch (node1.getNodeType()){ 1081// case TStatementSqlNode.select: 1082// TSelectSqlStatement select = new TSelectSqlStatement(EDbVendor.dbvhive); 1083// select.rootNode = node1; 1084// select.doParseStatement(this); 1085// this.getHiveBodyList().add(select); 1086// 1087// break; 1088// case TStatementSqlNode.insert: 1089// 1090// TInsertSqlStatement insert = new TInsertSqlStatement(EDbVendor.dbvhive); 1091// insert.rootNode = node1; 1092// insert.doParseStatement(this); 1093// this.getHiveBodyList().add(insert); 1094// break; 1095// default: 1096// break; 1097// } 1098// } 1099// } 1100 // return 0; 1101 } 1102 1103 // get oracle hint 1104 if((dbvendor == EDbVendor.dbvoracle)||(dbvendor == EDbVendor.dbvmysql)){ 1105 TSourceToken lcnextst = this.selectToken.container.nextsolidtoken(this.selectToken.posinlist,1,true); 1106 while (lcnextst != null){ 1107 if (!((lcnextst.tokentype == ETokenType.ttsimplecomment) || (lcnextst.tokentype == ETokenType.ttbracketedcomment))) break; 1108 1109 if (lcnextst.tokentype == ETokenType.ttbracketedcomment){ 1110 if (lcnextst.toString().startsWith("/*+")){ 1111 //lcnextst.setDbObjType(TObjectName.ttObjOracleHint); 1112 lcnextst.setDbObjectType(EDbObjectType.oracleHint); 1113 if (oracleHint == null){ 1114 oracleHint = lcnextst.toString(); 1115 }else { 1116 oracleHint = oracleHint + " " + lcnextst.toString(); 1117 } 1118 } 1119 } 1120 1121 if (lcnextst.tokentype == ETokenType.ttsimplecomment){ 1122 if (lcnextst.toString().startsWith("--+")){ 1123 //lcnextst.setDbObjType(TObjectName.ttObjOracleHint); 1124 lcnextst.setDbObjectType(EDbObjectType.oracleHint); 1125 if (oracleHint == null){ 1126 oracleHint = lcnextst.toString(); 1127 }else { 1128 oracleHint = oracleHint + " " + lcnextst.toString(); 1129 } 1130 } 1131 } 1132 1133 lcnextst = lcnextst.container.nextsolidtoken(lcnextst,1,true); 1134 } 1135 1136 hint = oracleHint; 1137 } 1138 1139 if (selectNode.getHiveHintClause() != null){ 1140 hiveHintClause = selectNode.getHiveHintClause(); 1141 } 1142 1143 isConsume = selectNode.isConsume(); 1144 1145 if (selectNode.getTopClause() != null){ 1146 selectNode.getTopClause().doParse(this,ESqlClause.top); 1147 this.setTopClause(selectNode.getTopClause()); 1148 } 1149 1150 // this.skipOffset = selectNode.getSkipOffset(); 1151// this.firstMax = selectNode.getFirstMax(); 1152// this.limitMax = selectNode.getLimitMax(); 1153 1154 if (selectNode.getSelectDistinct() != null){ 1155 this.selectDistinct = selectNode.getSelectDistinct(); 1156 } 1157 1158 this.selectModifiers = selectNode.getSelectModifiers(); 1159 1160 TFromTable lcFromTable = null; 1161 TJoin lcJoin = null; 1162 1163 if (selectNode.getFromTableList() != null){ 1164 fromClause = new TFromClause(this.getRelations()); 1165 fromClause.setStartToken(selectNode.getFromTableList().getStartToken()); 1166 fromClause.setEndToken(selectNode.getFromTableList().getEndToken()); 1167 1168 for(int i=0; i<selectNode.getFromTableList().size();i++){ 1169 lcFromTable = selectNode.getFromTableList().getFromTable(i); 1170 lcJoin = analyzeTableOrJoin(lcFromTable); 1171 joins.addJoin(lcJoin); 1172 } 1173 } 1174 1175 if (selectNode.getResultColumnList() != null){ 1176 this.setResultColumnList(selectNode.getResultColumnList()); 1177 1178// if ((this.getResultColumnList().size() > 10) 1179// &&(this.getTables().size() == 1) 1180// &&(this.getTables().getTable(0).getTableType() == ETableSource.subquery) 1181// &&( this.getTables().getTable(0).getSubquery().getResultColumnList().size() == this.getResultColumnList().size() ) 1182// ){ 1183// TTable t0 = this.getTables().getTable(0); 1184// ArrayList<TResultColumn> targetColumnArrayList = this.getResultColumnList().getSortedColumns(); 1185// ArrayList<TResultColumn> sourceColumnArrayList = t0.getSubquery().getResultColumnList().getSortedColumns(); 1186// int i=0; 1187// for(TResultColumn rc:targetColumnArrayList){ 1188// TObjectName targetColumn = rc.getExpr().getObjectOperand(); 1189// TResultColumn sourceResultColumn = sourceColumnArrayList.get(i++); 1190// //TObjectName sourceColumn = sourceResultColumn.getExpr().getObjectOperand(); 1191// if (targetColumn != null){ 1192// //System.out.println(targetColumn+"\t->\t"+sourceResultColumn.getDisplayName()); 1193// targetColumn.setSourceTable(t0); 1194// t0.getLinkedColumns().addObjectName(targetColumn); 1195// targetColumn.setSourceColumn(sourceResultColumn); 1196// sourceResultColumn.getTargetColumns().addObjectName(targetColumn); 1197// } 1198// } 1199// } 1200 1201 selectNode.getResultColumnList().doParse(this,ESqlClause.selectList); 1202 1203 for(int i=0;i<selectNode.getResultColumnList().size();i++){ 1204 TResultColumn resultColumn = selectNode.getResultColumnList().getResultColumn(i); 1205 if (resultColumn.getExpr().toString().endsWith("*")){ 1206 //System.out.println(resultColumn.toString()+":"+resultColumn.getStartToken().lineNo+","+resultColumn.getStartToken().columnNo); 1207 if (resultColumn.getExpr().toString().startsWith("*")){ 1208 // add all result columns in from tables 1209 for(int j=0;j<getTables().size();j++){ 1210 if (getTables().getTable(j).getTableType() == ETableSource.subquery){ 1211 getExpandedResultColumns().putAll(getTables().getTable(j).getSubquery().getExpandedResultColumns()); 1212 }else{ 1213 // ToDo for real table 1214 } 1215 //System.out.println("\t"+getTables().getTable(j).toString()+",\t"+getTables().getTable(j).getTableType()+",\t"+getTables().getTable(j).isCTEName()); 1216 } 1217 if (getTables().size() == 1){ 1218 resultColumn.getExpr().getObjectOperand().setSourceTable(getTables().getTable(0)); 1219 } 1220 1221 }else{ 1222 for(int j=0;j<getTables().size();j++){ 1223 if (getTables().getTable(j).getAliasName().equalsIgnoreCase( resultColumn.toString().split("[.]")[0])){ 1224 if (getTables().getTable(j).getTableType() == ETableSource.subquery){ 1225 getExpandedResultColumns().putAll(getTables().getTable(j).getSubquery().getExpandedResultColumns()); 1226 }else{ 1227 // ToDo for real table 1228 } 1229 resultColumn.getExpr().getObjectOperand().setSourceTable(getTables().getTable(j)); 1230 break; 1231 } 1232 } 1233 } 1234 }else{ 1235 getExpandedResultColumns().put(TSQLEnv.normalizeIdentifier(this.dbvendor, ESQLDataObjectType.dotColumn,resultColumn.getDisplayName()),resultColumn); 1236 } 1237 } 1238 } 1239 1240 if (selectNode.getIntoClause() != null){ 1241 this.intoClause = selectNode.getIntoClause(); 1242 this.intoClause.doParse(this,ESqlClause.selectInto); 1243 } 1244 1245 1246 if (selectNode.getWhereCondition() != null){ 1247 selectNode.getWhereCondition().doParse(this,ESqlClause.where); 1248 this.setWhereClause( selectNode.getWhereCondition()); 1249 } 1250 1251 if (selectNode.getHierarchicalClause() != null){ 1252 selectNode.getHierarchicalClause().doParse(this,ESqlClause.hierarchical); 1253 this.hierarchicalClause = selectNode.getHierarchicalClause(); 1254 } 1255 1256 if (selectNode.getGroupByClause() != null){ 1257 selectNode.getGroupByClause().doParse(this,ESqlClause.groupby); 1258 this.groupByClause = selectNode.getGroupByClause(); 1259 } 1260 1261 if (selectNode.getQualifyClause() != null){ 1262 selectNode.getQualifyClause().doParse(this,ESqlClause.qualify); 1263 this.qualifyClause = selectNode.getQualifyClause(); 1264 } 1265 1266 if (selectNode.getSampleClause() != null){ 1267 selectNode.getSampleClause().doParse(this,ESqlClause.sample); 1268 this.sampleClause = selectNode.getSampleClause(); 1269 } 1270 1271 if (selectNode.getExpandOnClause() != null){ 1272 selectNode.getExpandOnClause().doParse(this,ESqlClause.expandOn); 1273 this.expandOnClause = selectNode.getExpandOnClause(); 1274 } 1275 1276 if (selectNode.getWithClause() != null){ 1277 selectNode.getWithClause().doParse(this,ESqlClause.teradataWith); 1278 this.teradataWithClause = selectNode.getWithClause(); 1279 } 1280 1281 if (selectNode.getOrderbyClause() != null){ 1282 selectNode.getOrderbyClause().doParse(this,ESqlClause.orderby); 1283 this.orderbyClause = selectNode.getOrderbyClause(); 1284 } 1285 1286 if (selectNode.getLockingClauses() != null){ 1287 selectNode.getLockingClauses().doParse(this,ESqlClause.lockingClause); 1288 this.lockingClauses = selectNode.getLockingClauses(); 1289 } 1290 1291 this.sortBy = selectNode.getSortBy(); 1292 if (this.sortBy != null){ 1293 this.sortBy.doParse(this,ESqlClause.sortby); 1294 } 1295 1296 this.clusterBy = selectNode.getClusterBy(); 1297 if (this.clusterBy != null){ 1298 this.clusterBy.doParse(this,ESqlClause.cluster); 1299 } 1300 1301 this.windowClause = selectNode.getWindowClause(); 1302 if (this.windowClause != null){ 1303 this.windowClause.doParse(this,ESqlClause.windowClause); 1304 } 1305 this.limitClause = selectNode.getLimitClause(); 1306 if (this.limitClause != null){ 1307 this.limitClause.doParse(this,ESqlClause.limit); 1308 } 1309 1310 if (selectNode.getForupdateClause() != null){ 1311 selectNode.getForupdateClause().doParse(this,ESqlClause.forUpdate); 1312 this.forUpdateClause = selectNode.getForupdateClause(); 1313 } 1314 1315 if (selectNode.getComputeClause() != null){ 1316 selectNode.getComputeClause().doParse(this,ESqlClause.compute); 1317 this.computeClause = selectNode.getComputeClause(); 1318 } 1319 1320 this.intoTableClause = selectNode.getIntoTableClause(); 1321 1322 if (selectNode.getDistributeBy() != null){ 1323 this.distributeBy = selectNode.getDistributeBy(); 1324 this.distributeBy.doParse(this,ESqlClause.distributeBy); 1325 } 1326 1327 1328 this.isolationClause = selectNode.getIsolationClause(); 1329 1330 this.optionClause = selectNode.getOptionClause(); 1331 1332 this.offsetClause = selectNode.getOffsetClause(); 1333 this.fetchFirstClause = selectNode.getFetchFirstClause(); 1334 1335 this.timeTravel = selectNode.getTimeTravel(); 1336 this.hintClause = selectNode.getHintClause(); 1337 1338 if (selectNode.getForXMLClause() != null){ 1339 if (tables.size() > 0){ 1340 tables.getTable(0).setForXMLClause(selectNode.getForXMLClause()); 1341 } 1342 } 1343 1344 1345 return 0; 1346 } 1347 1348 /** 1349 * Determine whether The UNION, EXCEPT and INTERSECT operators were used. 1350 * @return true if one of those operators were used. 1351 */ 1352 public boolean isCombinedQuery(){ 1353 // combine multiple queries using the set operators UNION, UNION ALL, INTERSECT, and MINUS. 1354 return (setOperator > 0); 1355 } 1356 1357 public void accept(TParseTreeVisitor v) 1358 { 1359 v.preVisit(this); 1360 v.postVisit(this); 1361 } 1362 1363 /** 1364 * Accept visitor to visit this class. 1365 * @param v user defined visitor. 1366 */ 1367 public void acceptChildren(TParseTreeVisitor v) 1368 { 1369 1370 if(this.isCombinedQuery()){ 1371 1372 v.preVisit(this); 1373 1374 if (this.getCteList() != null){ 1375 this.getCteList().acceptChildren(v); 1376 } 1377 1378 leftStmt.acceptChildren(v); 1379 1380 rightStmt.acceptChildren(v); 1381 1382 if (this.getOrderbyClause() != null){ 1383 this.getOrderbyClause().acceptChildren(v); 1384 } 1385 1386 if (this.getLimitClause() != null){ 1387 this.getLimitClause().acceptChildren(v); 1388 } 1389 1390 if (this.getForUpdateClause() != null){ 1391 this.getForUpdateClause().acceptChildren(v); 1392 } 1393 1394 if (this.getComputeClause() != null){ 1395 this.getComputeClause().acceptChildren(v); 1396 } 1397 1398 v.postVisit(this); 1399 1400 return ; 1401 } 1402 1403 // System.out.println(this.toString().hashCode()+" "+ this.toString().substring(0,50)); 1404 1405 v.preVisit(this); 1406 1407 if (this.getTransformClause() != null){ 1408 this.getTransformClause().acceptChildren(v); 1409 } 1410 1411 if (this.getCteList() != null){ 1412 this.getCteList().acceptChildren(v); 1413 } 1414 1415 if (TBaseType.USE_JOINEXPR_INSTEAD_OF_JOIN){ 1416// fromClause.acceptChildren(v); 1417 v.preVisit(fromClause); 1418 for(TTable table:getRelations()){ 1419 table.acceptChildren(v); 1420 } 1421 v.postVisit(fromClause); 1422 }else{ 1423 if (this.getJoins() != null){ 1424 this.getJoins().acceptChildren(v); 1425 } 1426 } 1427 1428 if (this.getHiveHintClause() != null){ 1429 this.getHiveHintClause().acceptChildren(v); 1430 } 1431 1432 1433 if (this.getTopClause() != null){ 1434 this.getTopClause().acceptChildren(v); 1435 } 1436 1437 if (this.getSelectDistinct() != null){ 1438 this.getSelectDistinct().acceptChildren(v); 1439 } 1440 1441 if (this.getResultColumnList() != null){ 1442 this.getResultColumnList().acceptChildren(v); 1443 } 1444 1445 if (this.getIntoClause() != null){ 1446 this.getIntoClause().acceptChildren(v); 1447 } 1448 1449 1450 if (this.getWhereClause() != null){ 1451 this.getWhereClause().acceptChildren(v); 1452 } 1453 1454 if (this.getHierarchicalClause() != null){ 1455 this.getHierarchicalClause().acceptChildren(v); 1456 } 1457 1458 if (this.getGroupByClause() != null){ 1459 this.getGroupByClause().acceptChildren(v); 1460 } 1461 1462 if (this.getQualifyClause() != null){ 1463 this.getQualifyClause().acceptChildren(v); 1464 } 1465 1466 if (this.getSampleClause() != null){ 1467 this.getSampleClause().acceptChildren(v); 1468 } 1469 1470 if (this.getExpandOnClause() != null){ 1471 this.getExpandOnClause().acceptChildren(v); 1472 } 1473 1474 if (this.getTeradataWithClause() != null){ 1475 this.getTeradataWithClause().acceptChildren(v); 1476 } 1477 1478 if (this.getOrderbyClause() != null){ 1479 this.getOrderbyClause().acceptChildren(v); 1480 } 1481 1482 if (this.getLockingClauses() != null){ 1483 this.getLockingClauses().acceptChildren(v); 1484 } 1485 1486 if (this.getSortBy() != null){ 1487 this.getSortBy().acceptChildren(v); 1488 } 1489 1490 if (this.getClusterBy() != null){ 1491 this.getClusterBy().acceptChildren(v); 1492 } 1493 1494 if (this.getWindowClause() != null){ 1495 this.getWindowClause().acceptChildren(v); 1496 } 1497 1498 if (this.getLimitClause() != null){ 1499 this.getLimitClause().acceptChildren(v); 1500 } 1501 1502 if (this.getForUpdateClause() != null){ 1503 this.getForUpdateClause().acceptChildren(v); 1504 } 1505 1506 if (this.getComputeClause() != null){ 1507 this.getComputeClause().acceptChildren(v); 1508 } 1509 1510 if (this.getIntoTableClause() != null){ 1511 this.getIntoTableClause().acceptChildren(v); 1512 } 1513 1514 if (this.getDistributeBy() != null){ 1515 this.getDistributeBy().acceptChildren(v); 1516 } 1517 1518 if (this.getIsolationClause() != null){ 1519 this.getIsolationClause().acceptChildren(v); 1520 } 1521 1522 if (this.getOptionClause() != null){ 1523 this.getOptionClause().acceptChildren(v); 1524 } 1525 1526 if (this.getOffsetClause() != null){ 1527 this.getOffsetClause().acceptChildren(v); 1528 } 1529 1530 if (this.getFetchFirstClause() != null){ 1531 this.getFetchFirstClause().acceptChildren(v); 1532 } 1533 1534 if (this.getTimeTravel() != null){ 1535 this.getTimeTravel().acceptChildren(v); 1536 } 1537 1538 if (this.getHintClause() != null){ 1539 this.getHintClause().acceptChildren(v); 1540 } 1541 1542 v.postVisit(this); 1543 return ; 1544 1545 }; 1546 1547 /** 1548 * Add an order by clause to this class. 1549 * @param orderByStr new order by string 1550 * @return added order by clause. 1551 */ 1552 public TOrderBy addOrderBy(String orderByStr){ 1553 if (this.getOrderbyClause() != null){ 1554 this.getOrderbyClause().addOrderByItem(orderByStr); 1555 }else{ 1556 1557 TOrderBy orderBy = new TOrderBy(); 1558 orderBy.setGsqlparser(this.getGsqlparser()); 1559 orderBy.setString(" order by "+orderByStr); 1560 this.orderbyClause = orderBy; 1561 TSourceToken last_token = null; 1562 if (this.getGroupByClause() != null){ 1563 last_token = this.getGroupByClause().getEndToken(); 1564 }else if (this.getWhereClause() != null){ 1565 last_token = this.getWhereClause().getEndToken(); 1566 }else{ 1567 last_token = joins.getEndToken(); 1568 } 1569 1570 orderbyClause.addAllMyTokensToTokenList(last_token.container, last_token.posinlist+1); 1571 1572 for(int i=0;i<last_token.getNodesEndWithThisToken().size();i++){ 1573 TParseTreeNode node = last_token.getNodesEndWithThisToken().get(i); 1574 if (node instanceof TSelectSqlStatement) 1575 { 1576 // change all end token of parse tree node except the last order by item 1577 node.setEndToken(orderbyClause.getEndToken()); 1578 } 1579 } 1580 } 1581 1582 return this.getOrderbyClause(); 1583 } 1584 1585 /** 1586 * this function is alias of addWhereClause 1587 * @param condition new condition 1588 * @return new where clause 1589 */ 1590 public TWhereClause addCondition(String condition){ 1591 return addWhereClause(condition); 1592 } 1593 1594 public TWhereClause addConditionOR(String condition){ 1595 return addWhereClauseOR(condition); 1596 } 1597 1598 public TWhereClause addWhereClause(String condition){ 1599 return doAddWhereClause(condition,true); 1600 } 1601 1602 public TWhereClause addWhereClauseOR(String condition){ 1603 return doAddWhereClause(condition,false); 1604 } 1605 1606 protected TWhereClause doAddWhereClause(String condition, boolean isAnd){ 1607 1608 if (this.getWhereClause() != null){ 1609 if (isAnd){ 1610 this.getWhereClause().getCondition().addANDCondition(condition); 1611 }else{ 1612 this.getWhereClause().getCondition().addORCondition(condition); 1613 } 1614 1615 }else{ 1616 TWhereClause whereClause = new TWhereClause(); 1617 whereClause.setGsqlparser(this.getGsqlparser()); 1618 whereClause.setString(" where "+condition); 1619 this.setWhereClause(whereClause); 1620 1621 TSourceToken last_token = null; 1622 TJoin lastjoin = joins.getJoin(joins.size()-1); 1623 if (lastjoin.getJoinItems().size() > 0){ 1624 TJoinItem lastitem = lastjoin.getJoinItems().getJoinItem(lastjoin.getJoinItems().size()-1); 1625 last_token = lastitem.getEndToken(); 1626 }else { 1627 last_token = joins.getEndToken(); 1628 } 1629 1630 whereClause.addAllMyTokensToTokenList(last_token.container, last_token.posinlist+1); 1631 1632 for(int i=0;i<last_token.getNodesEndWithThisToken().size();i++){ 1633 TParseTreeNode node = last_token.getNodesEndWithThisToken().get(i); 1634 if (!((node instanceof TJoinList) 1635 ||(node instanceof TJoin) 1636 ||(node instanceof TJoinItemList) 1637 ||(node instanceof TJoinItem) 1638 )) 1639 { 1640 // change all end token of parse tree node except the last order by item 1641 node.setEndToken(whereClause.getEndToken()); 1642 } 1643 } 1644 1645 } 1646 return this.getWhereClause(); 1647 } 1648 1649 private ArrayList<String> columnsInFromClause = null; 1650 1651 1652 @Override 1653 public TFromClause getFromClause() { 1654 // #todo , select union 类型的 sql 语句,需要穿透到低层的各个 子 select 语句,需要进一步完善 1655 TFromClause ret = super.getFromClause(); 1656 if ((ret == null)&&(isCombinedQuery()&&(this.getRightStmt()!=null))){ 1657 return this.getRightStmt().getFromClause(); 1658 }else{ 1659 return ret; 1660 } 1661 } 1662 1663 @Override 1664 public TResultColumnList getResultColumnList() { 1665 TResultColumnList ret = super.getResultColumnList(); 1666 if ((ret == null)&&(isCombinedQuery()&&(this.getRightStmt()!=null))){ 1667 return this.getRightStmt().getResultColumnList(); 1668 }else{ 1669 return ret; 1670 } 1671 } 1672 1673 public ArrayList<String> getColumnsInFromClause() { 1674 if (columnsInFromClause != null) return columnsInFromClause; 1675 columnsInFromClause = new ArrayList<String>(); 1676 TTable lcTable; 1677 for(int j=0;j<tables.size();j++){ 1678 lcTable = tables.getTable(j); 1679 switch (lcTable.getTableType()){ 1680 case objectname: 1681 break; 1682 case subquery: 1683 TSelectSqlStatement subQuery = lcTable.getSubquery(); 1684 if (subQuery.getResultColumnList() != null) 1685 for(int i=0;i<subQuery.getResultColumnList().size();i++){ 1686 TResultColumn resultColumn = subQuery.getResultColumnList().getResultColumn(i); 1687 String aliasName = null; 1688 if (resultColumn.getAliasClause() != null){ 1689 aliasName = resultColumn.getAliasClause().getAliasName().toString(); 1690 }else{ 1691 if (resultColumn.getExpr().getObjectOperand() != null){ 1692 aliasName = resultColumn.getExpr().getObjectOperand().toString(); 1693 } 1694 } 1695 if (aliasName != null){ 1696 columnsInFromClause.add(TSQLEnv.getObjectName(aliasName)); 1697 } 1698 } 1699 break; 1700 } 1701 } 1702 return columnsInFromClause; 1703 } 1704 1705 public void addColumnInSelectListToSQLEnv(TSQLTable sqlTable){ 1706 1707 if (this.getValueClause() != null) return; 1708 1709 if (this.getResultColumnList() != null) 1710 for(int i=0;i<this.getResultColumnList().size();i++){ 1711 TResultColumn resultColumn = this.getResultColumnList().getResultColumn(i); 1712 String aliasName = null; 1713 if (resultColumn.getAliasClause() != null){ 1714 aliasName = resultColumn.getAliasClause().getAliasName().toString(); 1715 }else{ 1716 if (resultColumn.getExpr().getObjectOperand() != null){ 1717 aliasName = resultColumn.getExpr().getObjectOperand().toString(); 1718 } 1719 } 1720 if (aliasName != null){ 1721 sqlTable.addColumn(TSQLEnv.getObjectName(aliasName)); 1722 } 1723 } 1724 } 1725 1726 /** 1727 * search column in the select list 1728 * 1729 * Internal function, DON'T call it explicitly. 1730 * @param pColumn 1731 * @param pMustIn 1732 * @return true if found. 1733 */ 1734 public boolean searchColumnInResultSet(TObjectName pColumn,boolean pMustIn){ 1735 boolean lcResult = false; 1736 int candidateTableCnt = 0; 1737 int numOfColumnStar = 0; 1738 TResultColumn columnStar = null; 1739 1740 1741 1742 TResultColumn c = null; 1743 if ( (c= this.getExpandedResultColumns().get(TSQLEnv.normalizeIdentifier(this.dbvendor, ESQLDataObjectType.dotColumn,pColumn.getColumnNameOnly()))) != null) 1744 { 1745 //System.out.println("Found:"+pColumn.toString()); 1746 pColumn.setSourceColumn(c); 1747 c.getTargetColumns().addObjectName(pColumn); 1748 1749 return true; 1750 }else{ 1751 // System.out.println("NotCatch:"+pColumn.toString()); 1752 } 1753 1754 if (isCombinedQuery()){ 1755 boolean lcResult1;//,lcResult2; 1756 // search column in all select 1757 lcResult1 = getFarLeftStmt().searchColumnInResultSet(pColumn,pMustIn); 1758 if (!lcResult1) 1759 lcResult1 = rightStmt.searchColumnInResultSet(pColumn,pMustIn); 1760 return lcResult1; 1761 } 1762 1763 if (getResultColumnList() == null) return false; 1764 1765 if (pColumn.toString().endsWith("*")){ 1766 // pColumn here is o1.* 1767 // select o1.*, o2.c1 1768 // from (select c123, c345 from some_table) o1, other_table o2 1769 pColumn.setColumnsLinkedToStar(this.getResultColumnList()); 1770 return true; 1771 } 1772 1773 // search columns in select list, skip t.* but count it for later use 1774 for(int i=0;i<getResultColumnList().size();i++){ 1775 TResultColumn lcField = getResultColumnList().getResultColumn(i); 1776 if (lcField.toString().endsWith("*")){ 1777 numOfColumnStar++; 1778 columnStar = lcField; 1779 continue; 1780 } 1781 lcResult = lcField.isMatchedWithResultColumn(this.dbvendor, pColumn); 1782 if (lcResult){ 1783 pColumn.setSourceColumn(lcField); 1784 lcField.getTargetColumns().addObjectName(pColumn); 1785 break; 1786 } 1787 } 1788 1789 if (lcResult) return true; 1790 1791// // search in * column, including t.* and * 1792 for(int i=0;i<getResultColumnList().size();i++){ 1793 TResultColumn lcField = getResultColumnList().getResultColumn(i); 1794 if (lcField.toString().endsWith("*")){ 1795 // search column in t.*, have to check column in table t 1796 String prefixTableName = ""; 1797 if (lcField.toString().endsWith(".*")){ 1798 String[] a = lcField.toString().split("[.]"); 1799 prefixTableName = a[a.length - 2]; 1800 } 1801 for(int j=0;j<tables.size();j++){ 1802 lcResult = tables.getTable(j).searchColumn(this,prefixTableName,pColumn,false); 1803 if (lcResult) { 1804// tables.getTable(j).getLinkedColumns().addObjectName(pColumn); 1805// pColumn.setSourceTable(tables.getTable(j)); 1806 pColumn.setSourceColumn(lcField); 1807 lcField.getTargetColumns().addObjectName(pColumn); 1808 break; 1809 } 1810 } 1811 }else{ 1812 continue; 1813 } 1814 if (lcResult) break; 1815 } 1816 1817 if (lcResult) return true; 1818 1819 if (pMustIn){ 1820 if (tables.size() == 1){ // only a single table in from clause 1821 lcResult = true; 1822 boolean inStarColumn = false; 1823// tables.getTable(0).getLinkedColumns().addObjectName(pColumn); 1824// pColumn.setSourceTable(tables.getTable(0)); 1825 for(int i=0;i<getResultColumnList().size();i++) { 1826 TResultColumn lcField = getResultColumnList().getResultColumn(i); 1827 if (lcField.toString().endsWith("*")) { 1828 String prefixTableName = ""; 1829 if (lcField.toString().endsWith(".*")){ 1830 String[] a = lcField.toString().split("[.]"); 1831 prefixTableName = a[a.length - 2]; 1832 } 1833 tables.getTable(0).searchColumn(this,prefixTableName,pColumn,true); 1834 pColumn.setSourceColumn(lcField); 1835 lcField.getTargetColumns().addObjectName(pColumn); 1836 inStarColumn = true; 1837 break; 1838 } 1839 } 1840 if (!inStarColumn){ 1841 1842 if (!locateVariableOrParameter(pColumn)){ 1843 // check variable before raise error 1844 1845 // raise 1846 TSyntaxError err = new TSyntaxError(pColumn.getStartToken().toString() 1847 ,pColumn.getStartToken().lineNo,pColumn.getStartToken().columnNo 1848 ,String.format("Column %s is not found in subquery",pColumn.toString()) 1849 ,EErrorType.sphint ,TBaseType.MSG_ERROR_COLUMN_NOT_FOUND,this,pColumn.getStartToken().posinlist); 1850 this.parseerrormessagehandle( err); 1851 } 1852 1853 } 1854 }else if (numOfColumnStar == 1){// only a single * column in select list, but more than one table in from clause 1855 1856 pColumn.setSourceColumn(columnStar); 1857 columnStar.getTargetColumns().addObjectName(pColumn); 1858 if (columnStar.toString().endsWith(".*")){ 1859 lcResult = true; 1860 String[] a = columnStar.toString().split("[.]"); 1861 String prefixTableName = a[a.length - 2]; 1862 for(int i=0;i<tables.size();i++){ 1863 if (tables.getTable(i).checkTableByName(prefixTableName)){ 1864 tables.getTable(i).searchColumn(this,prefixTableName,pColumn,true); 1865// tables.getTable(i).getLinkedColumns().addObjectName(pColumn); 1866// pColumn.setSourceTable(tables.getTable(i)); 1867 pColumn.setSourceColumn(columnStar); 1868 columnStar.getTargetColumns().addObjectName(pColumn); 1869 break; 1870 } 1871 } 1872 }else{ 1873 lcResult = false; 1874 // * column, no table prefix, this column can only be in one of tables 1875 for(int i=0;i<tables.size();i++){ 1876 lcResult = tables.getTable(i).searchColumn(this,"",pColumn,false); 1877 //tables.getTable(i).getLinkedColumns().addObjectName(pColumn); 1878 //pColumn.setSourceTable(tables.getTable(i)); 1879 pColumn.setSourceColumn(columnStar); 1880 columnStar.getTargetColumns().addObjectName(pColumn); 1881 } 1882 } 1883 if (!lcResult) { 1884 lcResult = linkToFirstTable(pColumn,0); 1885 } 1886 }else{ 1887 // multi tables in from clause and multi * column in select list. 1888 lcResult = linkToFirstTable(pColumn,0); 1889 } 1890 } 1891 1892 return lcResult; 1893 1894 //if (lcResult) return true; 1895 1896 // From now on, let's search in * column, there maybe more than one * column in the select list, such as t1.*, t2.* 1897// TResultColumn resultColumn = getResultColumnList().getResultColumn(0); 1898// if ((getResultColumnList().size() == 1) &&(resultColumn.toString().equalsIgnoreCase("*") )){ 1899// // search in * or t1.* in the select list 1900// int tableCntInFromClause = 0; 1901// TTable tableInFromClause = null; 1902// for(int i=0;i<tables.size();i++){ 1903// TTable tn = tables.getTable(i); 1904// if (tn.getEffectType() == ETableEffectType.tetTeradataReference) continue; 1905// tableInFromClause = tn; 1906// tableCntInFromClause++; 1907// } 1908// //if (tables.size() == 1){ 1909// if (tableCntInFromClause == 1){ 1910// //TTable t0 = tables.getTable(0); 1911// TTable t0 = tableInFromClause; 1912// 1913// if (t0.isBaseTable()){ 1914// lcResult = fireOnMetaDatabaseTableColumn(t0.getPrefixServer(),t0.getPrefixDatabase(),t0.getPrefixSchema(),t0.getName(),pColumn.getColumnNameOnly()); 1915// if (! lcResult) candidateTableCnt++; 1916// }else{ 1917// if (t0.getTableType() == ETableSource.subquery){ 1918// if (t0.isIncludeColumnAlias()){ 1919// lcResult = t0.searchColumnInAlias(pColumn); 1920// }else{ 1921// lcResult = t0.getSubquery().searchColumnInResultSet(pColumn,pMustIn); 1922// if (! lcResult) candidateTableCnt++; 1923// } 1924// }else if (t0.isCTEName()){ 1925// lcResult = t0.getCTE().searchColumnInResultSet(this,t0,pColumn,pMustIn); 1926// if (! lcResult) candidateTableCnt++; 1927// } 1928// } 1929// if (pMustIn) lcResult = true; 1930// if (lcResult){ 1931// t0.getLinkedColumns().addObjectName(pColumn); 1932// pColumn.setSourceTable(t0); 1933// pColumn.setSourceColumn(resultColumn); 1934// resultColumn.getTargetColumns().addObjectName(pColumn); 1935// } 1936// }else{ // more than one table 1937// candidateTableCnt = 0; 1938// for(int i=0;i<tables.size();i++){ 1939// TTable tn = tables.getTable(i); 1940// if (tn.isBaseTable()){ 1941// lcResult = fireOnMetaDatabaseTableColumn(tn.getPrefixServer(),tn.getPrefixDatabase(),tn.getPrefixSchema(),tn.getName(),pColumn.getColumnNameOnly()); 1942// if (!lcResult) candidateTableCnt++; 1943// }else{ 1944// if (tn.getTableType() == ETableSource.subquery){ 1945// if (tn.isIncludeColumnAlias()){ 1946// lcResult = tn.searchColumnInAlias(pColumn); 1947// }else{ 1948// lcResult = tn.getSubquery().searchColumnInResultSet(pColumn,false); 1949// if (!lcResult) candidateTableCnt++; 1950// } 1951// }else if (tn.isCTEName()){ 1952// lcResult = tn.getCTE().searchColumnInResultSet(this,tn,pColumn,false); 1953// if (!lcResult) candidateTableCnt++; 1954// } 1955// } 1956// 1957// if (lcResult){ 1958// tn.getLinkedColumns().addObjectName(pColumn); 1959// pColumn.setSourceTable(tn); 1960// pColumn.setSourceColumn(resultColumn); 1961// resultColumn.getTargetColumns().addObjectName(pColumn); 1962// break; 1963// } 1964// } 1965// if ((!lcResult) && (pMustIn)) linkToFirstTable(pColumn,candidateTableCnt); 1966// } 1967// // } 1968// } 1969// 1970// if (lcResult) return true; 1971// 1972// // search t.* 1973// //int starColumnPos = 0, 1974// int numOfTableDotStar=0; 1975// for (int i=0;i<getResultColumnList().size();i++){ 1976// if (getResultColumnList().getResultColumn(i).toString().endsWith(".*")){ 1977// numOfTableDotStar++; 1978// } 1979// } 1980// 1981// TResultColumn rc = null; 1982// TTable tn = null; 1983// for (int i=0;i<getResultColumnList().size();i++){ 1984// if (!getResultColumnList().getResultColumn(i).toString().endsWith(".*")) continue; 1985// rc = getResultColumnList().getResultColumn(i); 1986// // starColumnPos = i; 1987// 1988// for (int j=0;j<tables.size();j++){ 1989// if (! tables.getTable(j).equalByName(rc.getPrefixTable())) continue; 1990// tn = tables.getTable(j); 1991// 1992// if (tn.isBaseTable()){ 1993// lcResult = fireOnMetaDatabaseTableColumn(tn.getPrefixServer(),tn.getPrefixDatabase(),tn.getPrefixSchema(),tn.getName(),pColumn.getColumnNameOnly()); 1994// if (!lcResult) candidateTableCnt++; 1995// }else{ 1996// if (tn.getTableType() == ETableSource.subquery){ 1997// if (tn.isIncludeColumnAlias()){ 1998// lcResult = tn.searchColumnInAlias(pColumn); 1999// }else{ 2000// lcResult = tn.getSubquery().searchColumnInResultSet(pColumn,((pMustIn)&&(numOfTableDotStar == 1))); 2001// if (!lcResult) candidateTableCnt++; 2002// } 2003// }else if (tn.isCTEName()){ 2004// lcResult = tn.getCTE().searchColumnInResultSet(this,tn,pColumn,((pMustIn)&&(numOfTableDotStar == 1))); 2005// if (!lcResult) candidateTableCnt++; 2006// } 2007// } 2008// 2009// if (lcResult){ 2010// tn.getLinkedColumns().addObjectName(pColumn); 2011// pColumn.setSourceTable(tn); 2012// pColumn.setSourceColumn(rc); 2013// rc.getTargetColumns().addObjectName(pColumn); 2014// break; 2015// } 2016// } 2017// if (lcResult) break; 2018// } 2019// 2020// if (lcResult) return true; 2021// 2022// if ((pMustIn) && (numOfTableDotStar == 1) && (tn != null)){ 2023// tn.getLinkedColumns().addObjectName(pColumn); 2024// pColumn.setSourceTable(tn); 2025// pColumn.setSourceColumn(rc); 2026// rc.getTargetColumns().addObjectName(pColumn); 2027// lcResult = true; 2028// } 2029// 2030// if (lcResult) return true; 2031// 2032// if ((pMustIn) && (numOfTableDotStar > 0)) lcResult = linkToFirstTable(pColumn,candidateTableCnt); 2033// 2034// if ((pMustIn)&&(!lcResult)) try { 2035// throw new Exception(" column must be found in the select list:"+pColumn.toString()); 2036// } catch (Exception e) { 2037// e.printStackTrace(); 2038// } 2039// 2040// return lcResult; 2041 } 2042 2043 2044}