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