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