1 /* 2 * Copyright 2015-2018 HuntLabs.cn 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 module hunt.sql.visitor.SQLASTOutputVisitor; 17 18 19 import std.uni; 20 import hunt.sql.SQLUtils; 21 import hunt.sql.ast; 22 import hunt.sql.ast.expr; 23 import hunt.sql.ast.statement; 24 import hunt.sql.ast.statement.SQLCreateTriggerStatement; 25 // import hunt.sql.ast.statement.SQLCreateTriggerStatement.TriggerEvent; 26 // import hunt.sql.ast.statement.SQLCreateTriggerStatement.TriggerType; 27 // import hunt.sql.ast.statement.ValuesClause; 28 // import hunt.sql.ast.statement.SQLJoinTableSource.JoinType; 29 import hunt.sql.ast.statement.SQLInsertStatement; 30 import hunt.sql.ast.statement.SQLJoinTableSource; 31 // import hunt.sql.ast.statement.SQLMergeStatement.MergeInsertClause; 32 // import hunt.sql.ast.statement.SQLMergeStatement.MergeUpdateClause; 33 import hunt.sql.ast.statement.SQLMergeStatement; 34 import hunt.sql.ast.statement.SQLWhileStatement; 35 // import hunt.sql.dialect.oracle.ast.OracleSegmentAttributes; 36 import hunt.sql.ast.statement.SQLDeclareStatement; 37 // import hunt.sql.dialect.oracle.ast.expr.OracleCursorExpr; 38 // import hunt.sql.dialect.oracle.ast.expr.OracleDatetimeExpr; 39 // import hunt.sql.dialect.oracle.ast.stmt.OracleCreatePackageStatement; 40 // import hunt.sql.dialect.oracle.ast.stmt.OracleForStatement; 41 // import hunt.sql.dialect.oracle.ast.stmt.OracleSelectPivot; 42 // import hunt.sql.dialect.oracle.parser.OracleFunctionDataType; 43 // import hunt.sql.dialect.oracle.parser.OracleProcedureDataType; 44 import hunt.sql.util.DBType; 45 import hunt.sql.visitor.SQLASTVisitorAdapter; 46 import hunt.sql.visitor.ParameterizedVisitor; 47 import hunt.sql.visitor.PrintableVisitor; 48 import hunt.sql.visitor.VisitorFeature; 49 import hunt.sql.ast.expr.SQLCaseStatement; 50 import hunt.sql.visitor.ExportParameterVisitorUtils; 51 52 import hunt.collection; 53 import hunt.Byte; 54 import hunt.Exceptions; 55 import hunt.logging; 56 import hunt.String; 57 import hunt.Boolean; 58 import hunt.Number; 59 import hunt.Integer; 60 import hunt.Float; 61 import hunt.math; 62 import hunt.util.Common; 63 import hunt.util.Appendable; 64 import hunt.text; 65 import hunt.collection.Collections; 66 67 import std.array; 68 import std.concurrency : initOnce; 69 import std.conv; 70 import std.datetime; 71 import std.string; 72 73 74 75 class SQLASTOutputVisitor : SQLASTVisitorAdapter , ParameterizedVisitor, PrintableVisitor { 76 77 alias visit = SQLASTVisitorAdapter.visit; 78 alias endVisit = SQLASTVisitorAdapter.endVisit; 79 80 static string[] variantValuesCache() { 81 __gshared string[] inst; 82 return initOnce!inst(initializeCache()); 83 } 84 85 private static string[] initializeCache() { 86 string[] v = new string[64]; 87 for (int len = 0; len < v.length; ++len) { 88 StringBuilder buf = new StringBuilder(); 89 buf.append('('); 90 for (int i = 0; i < len; ++i) { 91 if (i != 0) { 92 if (i % 5 == 0) { 93 buf.append("\n\t\t"); 94 } 95 buf.append(", "); 96 } 97 buf.append('?'); 98 } 99 buf.append(')'); 100 v[len] = buf.toString(); 101 } 102 103 return v; 104 } 105 106 protected Appendable appender; 107 protected int indentCount = 0; 108 protected bool ucase = true; 109 protected int selectListNumberOfLine = 5; 110 111 protected bool groupItemSingleLine = false; 112 113 protected List!Object parameters; 114 protected List!Object inputParameters; 115 protected Set!string tables; 116 protected string table; // for improved 117 118 protected bool exportTables = false; 119 120 protected string dbType; 121 122 protected Map!(string,string)tableMapping; 123 124 protected int replaceCount; 125 126 protected bool parameterizedMergeInList = false; 127 protected bool parameterizedQuesUnMergeInList = false; 128 129 protected bool parameterized = false; 130 protected bool shardingSupport = false; 131 132 protected int lines = 0; 133 134 protected Boolean printStatementAfterSemi ; 135 private bool _haveQuotes = false; 136 private char _quotes = '"'; 137 138 139 this() { 140 printStatementAfterSemi = Boolean.FALSE; 141 // features |= VisitorFeature.OutputPrettyFormat.mask; 142 config(VisitorFeature.OutputPrettyFormat, true); 143 initialization(); 144 } 145 146 this(Appendable appender){ 147 this.appender = appender; 148 initialization(); 149 } 150 151 this(Appendable appender, string dbType){ 152 this.appender = appender; 153 this.dbType = dbType; 154 initialization(); 155 } 156 157 this(Appendable appender, bool parameterized){ 158 this.appender = appender; 159 this.config(VisitorFeature.OutputParameterized, parameterized); 160 this.config(VisitorFeature.OutputParameterizedQuesUnMergeInList, parameterizedQuesUnMergeInList); 161 initialization(); 162 } 163 164 private void initialization() { 165 if(dbType == DBType.MYSQL.name) { 166 _quotes = '`'; 167 } else if(dbType == DBType.POSTGRESQL.name) { 168 // https://stackoverflow.com/questions/20878932/are-postgresql-column-names-case-sensitive 169 // https://blog.xojo.com/2016/09/28/about-postgresql-case-sensitivity/ 170 // https://lerner.co.il/2013/11/30/quoting-postgresql/ 171 _quotes = '"'; 172 } 173 174 // config(VisitorFeature.OutputQuotedIdentifier, false); 175 } 176 177 // bool haveQuotes() { 178 // return _haveQuotes; 179 // } 180 181 int getReplaceCount() { 182 return this.replaceCount; 183 } 184 185 void incrementReplaceCunt() { 186 replaceCount++; 187 } 188 189 void addTableMapping(string srcTable, string destTable) { 190 if (tableMapping is null) { 191 tableMapping = new HashMap!(string, string)(); 192 } 193 194 if (indexOf(srcTable,'.') >= 0) { 195 SQLExpr expr = SQLUtils.toSQLExpr(srcTable, dbType); 196 if (cast(SQLPropertyExpr)expr !is null){ 197 srcTable = (cast(SQLPropertyExpr) expr).simplify().toString(); 198 } 199 } else { 200 srcTable = SQLUtils.normalize(srcTable); 201 } 202 tableMapping.put(srcTable, destTable); 203 } 204 205 void setTableMapping(Map!(string,string)tableMapping) { 206 this.tableMapping = tableMapping; 207 } 208 209 List!Object getParameters() { 210 if (parameters is null) { 211 parameters = new ArrayList!Object(); 212 } 213 214 return parameters; 215 } 216 217 bool isDesensitize() { 218 return isEnabled(VisitorFeature.OutputDesensitize); 219 } 220 221 void setDesensitize(bool desensitize) { 222 config(VisitorFeature.OutputDesensitize, desensitize); 223 } 224 225 Set!string getTables() { 226 if (this.table !is null && this.tables is null) { 227 return Collections.singleton!string(this.table); 228 } 229 return this.tables; 230 } 231 232 //@Deprecated 233 void setParameters(List!Object parameters) { 234 if (parameters !is null && parameters.size() > 0) { 235 this.inputParameters = parameters; 236 } else { 237 this.parameters = parameters; 238 } 239 } 240 241 void setInputParameters(List!Object parameters) { 242 this.inputParameters = parameters; 243 } 244 245 /** 246 * 247 * @since 1.1.5 248 */ 249 void setOutputParameters(List!Object parameters) { 250 this.parameters = parameters; 251 } 252 253 int getIndentCount() { 254 return indentCount; 255 } 256 257 Appendable getAppender() { 258 return appender; 259 } 260 261 bool isPrettyFormat() { 262 return isEnabled(VisitorFeature.OutputPrettyFormat); 263 } 264 265 void setPrettyFormat(bool prettyFormat) { 266 config(VisitorFeature.OutputPrettyFormat, prettyFormat); 267 } 268 269 void decrementIndent() { 270 this.indentCount--; 271 } 272 273 void incrementIndent() { 274 this.indentCount++; 275 } 276 277 bool isParameterized() { 278 return isEnabled(VisitorFeature.OutputParameterized); 279 } 280 281 void setParameterized(bool parameterized) { 282 config(VisitorFeature.OutputParameterized, parameterized); 283 } 284 285 bool isParameterizedMergeInList() { 286 return parameterizedMergeInList; 287 } 288 289 void setParameterizedMergeInList(bool parameterizedMergeInList) { 290 this.parameterizedMergeInList = parameterizedMergeInList; 291 } 292 293 bool isParameterizedQuesUnMergeInList() { 294 return isEnabled(VisitorFeature.OutputParameterizedQuesUnMergeInList); 295 } 296 297 void setParameterizedQuesUnMergeInList(bool parameterizedQuesUnMergeInList) { 298 config(VisitorFeature.OutputParameterizedQuesUnMergeInList, parameterizedQuesUnMergeInList); 299 } 300 301 bool isExportTables() { 302 return exportTables; 303 } 304 305 void setExportTables(bool exportTables) { 306 this.exportTables = exportTables; 307 } 308 309 void print(char value) { 310 if (this.appender is null) { 311 warning("The appender is null"); 312 return; 313 } 314 315 try { 316 version(HUNT_SQL_DEBUG_MORE) tracef("Appending: %s", value); 317 this.appender.append(value); 318 } catch (Exception e) { 319 warning(e.msg); 320 throw new Exception("print error", e); 321 } 322 } 323 324 void print(int value) { 325 version(HUNT_SQL_DEBUG_MORE) tracef("Appending: %s", value); 326 if (this.appender is null) { 327 warning("The appender is null"); 328 return; 329 } 330 331 if (cast(StringBuilder)appender !is null) { 332 (cast(StringBuilder) appender).append(value); 333 } else if (cast(StringBuilder)appender !is null) { 334 (cast(StringBuilder) appender).append(value); 335 } else { 336 print0(to!string(value)); 337 } 338 } 339 340 void print(long value) { 341 version(HUNT_SQL_DEBUG_MORE) tracef("Appending: %s", value); 342 if (this.appender is null) { 343 warning("The appender is null"); 344 return; 345 } 346 347 if (cast(StringBuilder)appender !is null) { 348 (cast(StringBuilder) appender).append(cast(int)value); 349 } else if (cast(StringBuilder)appender !is null) { 350 (cast(StringBuilder) appender).append(cast(int)value); 351 } else { 352 print0(to!string(value)); 353 } 354 } 355 356 357 // void print(Date date) { 358 // if (this.appender is null) { 359 // return; 360 // } 361 362 // SimpleDateFormat dateFormat; 363 // if (cast(java.sql.Timestamp)date !is null) { 364 // dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 365 // } else { 366 // dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 367 // } 368 // print0("'" ~ dateFormat.format(date) ~ "'"); 369 // } 370 371 void print(String text) 372 { 373 print(text.value()); 374 } 375 376 void print(string text) { 377 if (this.appender is null) { 378 return; 379 } 380 print0(text); 381 } 382 protected void print0(String text) 383 { 384 print0(text.value()); 385 } 386 387 protected void print0(string text) { 388 version(HUNT_SQL_DEBUG_MORE) tracef("Appending: %s", text); 389 if (appender is null) { 390 warning("appender is null"); 391 return; 392 } 393 394 this.appender.append(text); 395 } 396 397 protected void print0(Bytes data) { 398 implementationMissing(false); 399 } 400 401 protected void printAlias(string _alias) { 402 if ((_alias !is null) && (_alias.length > 0)) { 403 print(' '); 404 print0(_alias); 405 } 406 } 407 408 protected void printAndAccept(T = SQLObject)(List!(T) nodes, string seperator) { 409 for (int i = 0, size = nodes.size(); i < size; ++i) { 410 if (i != 0) { 411 print0(seperator); 412 } 413 nodes.get(i).accept(this); 414 } 415 } 416 417 private static int paramCount(SQLExpr x) { 418 if (cast(SQLName)x !is null) { 419 return 1; 420 } 421 422 if (cast(SQLMethodInvokeExpr)x !is null) { 423 List!SQLExpr params = (cast(SQLMethodInvokeExpr) x).getParameters(); 424 int t_paramCount = 1; 425 foreach(SQLExpr param ; params) { 426 t_paramCount += paramCount(param); 427 } 428 return t_paramCount; 429 } 430 431 if (cast(SQLAggregateExpr)x !is null) { 432 List!SQLExpr params = (cast(SQLAggregateExpr) x).getArguments(); 433 int t_paramCount = 1; 434 foreach(SQLExpr param ; params) { 435 t_paramCount += paramCount(param); 436 } 437 return t_paramCount; 438 } 439 440 if (cast(SQLBinaryOpExpr)x !is null) { 441 return paramCount((cast(SQLBinaryOpExpr) x).getLeft()) 442 + paramCount((cast(SQLBinaryOpExpr) x).getRight()); 443 } 444 445 return 1; 446 } 447 448 protected void printSelectList(List!SQLSelectItem selectList) { 449 this.indentCount++; 450 for (int i = 0, lineItemCount = 0, size = selectList.size() 451 ; i < size 452 ; ++i, ++lineItemCount) 453 { 454 SQLSelectItem selectItem = selectList.get(i); 455 SQLExpr selectItemExpr = selectItem.getExpr(); 456 457 int paramCount = paramCount(selectItemExpr); 458 459 bool methodOrBinary = (!(cast(SQLName)selectItemExpr !is null)) 460 && (cast(SQLMethodInvokeExpr)selectItemExpr !is null 461 || cast(SQLAggregateExpr)selectItemExpr !is null 462 || cast(SQLBinaryOpExpr)selectItemExpr !is null); 463 464 if (methodOrBinary) { 465 lineItemCount += (paramCount - 1); 466 } 467 468 if (i != 0) { 469 SQLSelectItem preSelectItem = selectList.get(i - 1); 470 if (preSelectItem.getAfterCommentsDirect() !is null) { 471 lineItemCount = 0; 472 println(); 473 } else if (methodOrBinary) { 474 if (lineItemCount >= selectListNumberOfLine) { 475 lineItemCount = paramCount; 476 println(); 477 } 478 } else if (lineItemCount >= selectListNumberOfLine 479 || cast(SQLQueryExpr)selectItemExpr !is null 480 || cast(SQLCaseExpr)selectItemExpr !is null) { 481 lineItemCount = 0; 482 println(); 483 } 484 485 print0(", "); 486 } 487 488 if (typeid(selectItem) == typeid(SQLSelectItem)) { 489 this.visit(selectItem); 490 } else { 491 selectItem.accept(this); 492 } 493 494 if (selectItem.hasAfterComment()) { 495 print(' '); 496 printlnComment(selectItem.getAfterCommentsDirect()); 497 } 498 } 499 this.indentCount--; 500 } 501 502 protected void printlnAndAccept(T = SQLObject)(List!(T) nodes, string seperator) { 503 for (int i = 0, size = nodes.size(); i < size; ++i) { 504 if (i != 0) { 505 println(seperator); 506 } 507 508 (cast(T) nodes.get(i)).accept(this); 509 } 510 } 511 512 protected void printIndent() { 513 if (this.appender is null) { 514 return; 515 } 516 517 try { 518 for (int i = 0; i < this.indentCount; ++i) { 519 this.appender.append('\t'); 520 } 521 } catch (Exception e) { 522 throw new Exception("print error", e); 523 } 524 } 525 526 void println() { 527 if (!isPrettyFormat()) { 528 print(' '); 529 return; 530 } 531 532 print('\n'); 533 lines++; 534 printIndent(); 535 } 536 537 void println(string text) { 538 print(text); 539 println(); 540 } 541 542 // //////////////////// 543 544 override bool visit(SQLBetweenExpr x) { 545 SQLExpr testExpr = x.getTestExpr(); 546 SQLExpr beginExpr = x.getBeginExpr(); 547 SQLExpr endExpr = x.getEndExpr(); 548 549 bool quote = false; 550 if (cast(SQLBinaryOpExpr)testExpr !is null) { 551 SQLBinaryOperator t_operator = (cast(SQLBinaryOpExpr) testExpr).getOperator(); 552 switch (t_operator.name) { 553 case SQLBinaryOperator.BooleanAnd.name: 554 case SQLBinaryOperator.BooleanOr.name: 555 case SQLBinaryOperator.BooleanXor.name: 556 case SQLBinaryOperator.Assignment.name: 557 quote = true; 558 break; 559 default: 560 quote = (cast(SQLBinaryOpExpr) testExpr).isBracket(); 561 break; 562 } 563 } else if (cast(SQLNotExpr)testExpr !is null){ 564 quote = true; 565 } 566 567 if (testExpr !is null) { 568 if (quote) { 569 print('('); 570 printExpr(testExpr); 571 print(')'); 572 } else { 573 printExpr(testExpr); 574 } 575 } 576 577 if (x.isNot()) { 578 print0(ucase ? " NOT BETWEEN " : " not between "); 579 } else { 580 print0(ucase ? " BETWEEN " : " between "); 581 } 582 583 int lines = this.lines; 584 if (cast(SQLBinaryOpExpr)beginExpr !is null) { 585 SQLBinaryOpExpr binaryOpBegin = cast(SQLBinaryOpExpr) beginExpr; 586 incrementIndent(); 587 if (binaryOpBegin.isBracket() || binaryOpBegin.getOperator().isLogical()) { 588 print('('); 589 printExpr(beginExpr); 590 print(')'); 591 } else { 592 printExpr(beginExpr); 593 } 594 decrementIndent(); 595 } else { 596 printExpr(beginExpr); 597 } 598 599 if (lines != this.lines) { 600 println(); 601 print0(ucase ? "AND " : "and "); 602 } else { 603 print0(ucase ? " AND " : " and "); 604 } 605 606 printExpr(endExpr); 607 608 return false; 609 } 610 611 override bool visit(SQLBinaryOpExprGroup x) { 612 SQLObject parent = x.getParent(); 613 SQLBinaryOperator operator = x.getOperator(); 614 615 bool isRoot = cast(SQLSelectQueryBlock)parent !is null || cast(SQLBinaryOpExprGroup)parent !is null; 616 617 List!SQLExpr items = x.getItems(); 618 if (isRoot) { 619 this.indentCount++; 620 } 621 622 if (this.parameterized) { 623 SQLExpr firstLeft = null; 624 SQLBinaryOperator firstOp; 625 List!Object parameters = new ArrayList!Object(items.size()); 626 627 List!SQLBinaryOpExpr literalItems = null; 628 629 if (operator != SQLBinaryOperator.BooleanOr || !isEnabled(VisitorFeature.OutputParameterizedQuesUnMergeOr)) { 630 for (int i = 0; i < items.size(); i++) { 631 SQLExpr item = items.get(i); 632 if (cast(SQLBinaryOpExpr)item !is null) { 633 SQLBinaryOpExpr binaryItem = cast(SQLBinaryOpExpr) item; 634 SQLExpr left = binaryItem.getLeft(); 635 SQLExpr right = binaryItem.getRight(); 636 637 if (cast(SQLLiteralExpr)right !is null && !(cast(SQLNullExpr)right !is null)) { 638 if (cast(SQLLiteralExpr)left !is null) { 639 if (literalItems is null) { 640 literalItems = new ArrayList!SQLBinaryOpExpr(); 641 } 642 literalItems.add(binaryItem); 643 continue; 644 } 645 646 if (this.parameters !is null) { 647 ExportParameterVisitorUtils.exportParameter(parameters, right); 648 } 649 } else if (cast(SQLVariantRefExpr)right !is null) { 650 // skip 651 } else { 652 firstLeft = null; 653 break; 654 } 655 656 657 if (firstLeft is null) { 658 firstLeft = binaryItem.getLeft(); 659 firstOp = binaryItem.getOperator(); 660 } else { 661 if (!SQLExprUtils.opEquals(firstLeft, left)) { 662 firstLeft = null; 663 break; 664 } 665 } 666 } else { 667 firstLeft = null; 668 break; 669 } 670 } 671 } 672 673 if (firstLeft !is null) { 674 if (literalItems !is null) { 675 foreach(SQLBinaryOpExpr literalItem ; literalItems) { 676 visit(literalItem); 677 println(); 678 printOperator(operator); 679 print(' '); 680 681 } 682 } 683 printExpr(firstLeft); 684 print(' '); 685 printOperator(firstOp); 686 print0(" ?"); 687 688 if (this.parameters !is null) { 689 if (parameters.size() > 0) { 690 this.parameters.addAll(parameters); 691 } 692 } 693 694 incrementReplaceCunt(); 695 if (isRoot) { 696 this.indentCount--; 697 } 698 return false; 699 } 700 } 701 702 for (int i = 0; i < items.size(); i++) { 703 SQLExpr item = items.get(i); 704 705 if (i != 0) { 706 println(); 707 printOperator(operator); 708 print(' '); 709 } 710 711 if (item.hasBeforeComment()) { 712 printlnComments(item.getBeforeCommentsDirect()); 713 } 714 715 if (cast(SQLBinaryOpExpr)item !is null) { 716 SQLBinaryOpExpr binaryOpExpr = cast(SQLBinaryOpExpr) item; 717 SQLExpr binaryOpExprRight = binaryOpExpr.getRight(); 718 SQLBinaryOperator itemOp = binaryOpExpr.getOperator(); 719 720 bool isLogic = itemOp.isLogical(); 721 if (isLogic) { 722 indentCount++; 723 } 724 725 bool bracket; 726 if (itemOp.priority > operator.priority) { 727 bracket = true; 728 } else { 729 bracket = binaryOpExpr.isBracket() & !parameterized; 730 } 731 if (bracket) { 732 print('('); 733 visit(binaryOpExpr); 734 print(')'); 735 } else { 736 visit(binaryOpExpr); 737 } 738 739 if (item.hasAfterComment()) { 740 print(' '); 741 printlnComment(item.getAfterCommentsDirect()); 742 } 743 744 if (isLogic) { 745 indentCount--; 746 } 747 } else if (cast(SQLBinaryOpExprGroup)item !is null) { 748 print('('); 749 visit(cast(SQLBinaryOpExprGroup) item); 750 print(')'); 751 } else { 752 printExpr(item); 753 } 754 } 755 if (isRoot) { 756 this.indentCount--; 757 } 758 return false; 759 } 760 761 override bool visit(SQLBinaryOpExpr x) { 762 SQLBinaryOperator operator = x.getOperator(); 763 if (this.parameterized 764 && operator == SQLBinaryOperator.BooleanOr 765 && !isEnabled(VisitorFeature.OutputParameterizedQuesUnMergeOr)) { 766 x = SQLBinaryOpExpr.merge(this, x); 767 768 operator = x.getOperator(); 769 } 770 771 if (inputParameters !is null 772 && inputParameters.size() > 0 773 && operator == SQLBinaryOperator.Equality 774 && cast(SQLVariantRefExpr)x.getRight() !is null 775 ) { 776 SQLVariantRefExpr right = cast(SQLVariantRefExpr) x.getRight(); 777 int index = right.getIndex(); 778 if (index >= 0 && index < inputParameters.size()) { 779 Object param = inputParameters.get(index); 780 if (cast(Collection!Object)param !is null) { 781 x.getLeft().accept(this); 782 print0(" IN ("); 783 right.accept(this); 784 print(')'); 785 return false; 786 } 787 } 788 } 789 790 SQLObject parent = x.getParent(); 791 bool isRoot = cast(SQLSelectQueryBlock)parent !is null; 792 bool relational = operator == SQLBinaryOperator.BooleanAnd 793 || operator == SQLBinaryOperator.BooleanOr; 794 795 if (isRoot && relational) { 796 this.indentCount++; 797 } 798 799 List!SQLExpr groupList = new ArrayList!SQLExpr(); 800 SQLExpr left = x.getLeft(); 801 SQLExpr right = x.getRight(); 802 803 if (inputParameters !is null 804 && operator != SQLBinaryOperator.Equality) { 805 int varIndex = -1; 806 if (cast(SQLVariantRefExpr)right !is null) { 807 varIndex = (cast(SQLVariantRefExpr) right).getIndex(); 808 } 809 810 Object param = null; 811 if (varIndex >= 0 && varIndex < inputParameters.size()) { 812 param = inputParameters.get(varIndex); 813 } 814 815 if (cast(Collection!Object)param !is null) { 816 Collection!Object values = cast(Collection!Object) param; 817 818 if (values.size() > 0) { 819 print('('); 820 int valIndex = 0; 821 foreach(Object value ; values) { 822 if (valIndex++ != 0) { 823 print0(ucase ? " OR " : " or "); 824 } 825 printExpr(left); 826 print(' '); 827 if (operator == SQLBinaryOperator.Is) { 828 print('='); 829 } else { 830 printOperator(operator); 831 } 832 print(' '); 833 printParameter(value); 834 } 835 print(')'); 836 return false; 837 } 838 } 839 } 840 841 if (operator.isRelational() 842 && cast(SQLIntegerExpr)left !is null 843 && cast(SQLIntegerExpr)right !is null) { 844 print((cast(SQLIntegerExpr) left).getNumber().longValue()); 845 print(' '); 846 printOperator(operator); 847 print(' '); 848 print((cast(SQLIntegerExpr) right).getNumber().longValue()); 849 return false; 850 } 851 852 for (;;) { 853 if (cast(SQLBinaryOpExpr)left !is null && (cast(SQLBinaryOpExpr) left).getOperator() == operator) { 854 SQLBinaryOpExpr binaryLeft = cast(SQLBinaryOpExpr) left; 855 groupList.add(binaryLeft.getRight()); 856 left = binaryLeft.getLeft(); 857 } else { 858 groupList.add(left); 859 break; 860 } 861 } 862 863 for (int i = groupList.size() - 1; i >= 0; --i) { 864 SQLExpr item = groupList.get(i); 865 866 if (relational) { 867 if (isPrettyFormat() && item.hasBeforeComment()) { 868 printlnComments(item.getBeforeCommentsDirect()); 869 } 870 } 871 872 if (isPrettyFormat() && item.hasBeforeComment()) { 873 printlnComments(item.getBeforeCommentsDirect()); 874 } 875 876 visitBinaryLeft(item, operator); 877 878 if (isPrettyFormat() && item.hasAfterComment()) { 879 print(' '); 880 printlnComment(item.getAfterCommentsDirect()); 881 } 882 883 if (i != groupList.size() - 1 && isPrettyFormat() && item.getParent().hasAfterComment()) { 884 print(' '); 885 printlnComment(item.getParent().getAfterCommentsDirect()); 886 } 887 888 bool printOpSpace = true; 889 if (relational) { 890 println(); 891 } else { 892 if (operator == SQLBinaryOperator.Modulus 893 && DBType.ORACLE.opEquals(dbType) 894 && cast(SQLIdentifierExpr)left !is null 895 && cast(SQLIdentifierExpr)right !is null 896 && (cast(SQLIdentifierExpr) right).getName().equalsIgnoreCase("NOTFOUND")) { 897 printOpSpace = false; 898 } 899 if (printOpSpace) { 900 print(' '); 901 } 902 } 903 printOperator(operator); 904 if (printOpSpace) { 905 print(' '); 906 } 907 } 908 909 visitorBinaryRight(x); 910 911 if (isRoot && relational) { 912 this.indentCount--; 913 } 914 915 return false; 916 } 917 918 protected void printOperator(SQLBinaryOperator operator) { 919 print0(ucase ? operator.name : operator.name_lcase); 920 } 921 922 private void visitorBinaryRight(SQLBinaryOpExpr x) { 923 if (isPrettyFormat() && x.getRight().hasBeforeComment()) { 924 printlnComments(x.getRight().getBeforeCommentsDirect()); 925 } 926 927 if ( cast(SQLBinaryOpExpr)x.getRight() !is null) { 928 SQLBinaryOpExpr right = cast(SQLBinaryOpExpr) x.getRight(); 929 SQLBinaryOperator rightOp = right.getOperator(); 930 SQLBinaryOperator op = x.getOperator(); 931 bool rightRational = rightOp == SQLBinaryOperator.BooleanAnd 932 || rightOp == SQLBinaryOperator.BooleanOr; 933 934 if (rightOp.priority >= op.priority 935 || (right.isBracket() 936 && rightOp != op 937 && rightOp.isLogical() 938 && op.isLogical() 939 )) { 940 if (rightRational) { 941 this.indentCount++; 942 } 943 944 print('('); 945 printExpr(right); 946 print(')'); 947 948 if (rightRational) { 949 this.indentCount--; 950 } 951 } else { 952 printExpr(right); 953 } 954 } else { 955 printExpr(x.getRight()); 956 } 957 958 if (x.getRight().hasAfterComment() && isPrettyFormat()) { 959 print(' '); 960 printlnComment(x.getRight().getAfterCommentsDirect()); 961 } 962 } 963 964 private void visitBinaryLeft(SQLExpr left, SQLBinaryOperator op) { 965 if (cast(SQLBinaryOpExpr)left !is null) { 966 SQLBinaryOpExpr binaryLeft = cast(SQLBinaryOpExpr) left; 967 SQLBinaryOperator leftOp = binaryLeft.getOperator(); 968 bool leftRational = leftOp == SQLBinaryOperator.BooleanAnd 969 || leftOp == SQLBinaryOperator.BooleanOr; 970 971 if (leftOp.priority > op.priority 972 || (binaryLeft.isBracket() 973 && leftOp != op 974 && leftOp.isLogical() 975 && op.isLogical() 976 )) { 977 if (leftRational) { 978 this.indentCount++; 979 } 980 print('('); 981 printExpr(left); 982 print(')'); 983 984 if (leftRational) { 985 this.indentCount--; 986 } 987 } else { 988 printExpr(left); 989 } 990 } else { 991 printExpr(left); 992 } 993 } 994 995 protected void printTableSource(SQLTableSource x) { 996 auto clazz = typeid(cast(Object)x); 997 if (clazz == typeid(SQLJoinTableSource)) { 998 visit(cast(SQLJoinTableSource) x); 999 } else if (clazz == typeid(SQLExprTableSource)) { 1000 visit(cast(SQLExprTableSource) x); 1001 } else if (clazz == typeid(SQLSubqueryTableSource)) { 1002 visit(cast(SQLSubqueryTableSource) x); 1003 } else { 1004 x.accept(this); 1005 } 1006 } 1007 1008 protected void printQuery(SQLSelectQuery x) { 1009 auto clazz = typeid(cast(Object)x); 1010 if (clazz == typeid(SQLSelectQueryBlock)) { 1011 visit(cast(SQLSelectQueryBlock) x); 1012 } else if (clazz == typeid(SQLUnionQuery)) { 1013 visit(cast(SQLUnionQuery) x); 1014 } else { 1015 x.accept(this); 1016 } 1017 } 1018 1019 protected void printExpr(SQLExpr x) { 1020 auto clazz = typeid((cast(Object)x)); //typeid(x); 1021 version(HUNT_DEBUG) { 1022 // tracef("SQLExpr: %s", clazz.name); 1023 // tracef("SQLExpr2: %s", typeid((cast(Object)x)).name); 1024 } 1025 1026 if (clazz == typeid(SQLIdentifierExpr)) { 1027 visit(cast(SQLIdentifierExpr) x); 1028 } else if (clazz == typeid(SQLPropertyExpr)) { 1029 visit(cast(SQLPropertyExpr) x); 1030 } else if (clazz == typeid(SQLAllColumnExpr)) { 1031 print('*'); 1032 } else if (clazz == typeid(SQLAggregateExpr)) { 1033 visit(cast(SQLAggregateExpr) x); 1034 } else if (clazz == typeid(SQLBinaryOpExpr)) { 1035 visit(cast(SQLBinaryOpExpr) x); 1036 } else if (clazz == typeid(SQLCharExpr)) { 1037 visit(cast(SQLCharExpr) x); 1038 } else if (clazz == typeid(SQLNullExpr)) { 1039 visit(cast(SQLNullExpr) x); 1040 } else if (clazz == typeid(SQLIntegerExpr)) { 1041 visit(cast(SQLIntegerExpr) x); 1042 } else if (clazz == typeid(SQLNumberExpr)) { 1043 visit(cast(SQLNumberExpr) x); 1044 } else if (clazz == typeid(SQLMethodInvokeExpr)) { 1045 visit(cast(SQLMethodInvokeExpr) x); 1046 } else if (clazz == typeid(SQLVariantRefExpr)) { 1047 visit(cast(SQLVariantRefExpr) x); 1048 } else if (clazz == typeid(SQLBinaryOpExprGroup)) { 1049 visit(cast(SQLBinaryOpExprGroup) x); 1050 } else if (clazz == typeid(SQLCaseExpr)) { 1051 visit(cast(SQLCaseExpr) x); 1052 } else if (clazz == typeid(SQLInListExpr)) { 1053 visit(cast(SQLInListExpr) x); 1054 } else if (clazz == typeid(SQLNotExpr)) { 1055 visit(cast(SQLNotExpr) x); 1056 } else { 1057 x.accept(this); 1058 } 1059 } 1060 1061 override bool visit(SQLCaseExpr x) { 1062 this.indentCount++; 1063 print0(ucase ? "CASE " : "case "); 1064 1065 SQLExpr valueExpr = x.getValueExpr(); 1066 if (valueExpr !is null) { 1067 printExpr(valueExpr); 1068 } 1069 1070 List!(SQLCaseExpr.Item) items = x.getItems(); 1071 for (int i = 0, size = items.size(); i < size; ++i) { 1072 println(); 1073 visit(items.get(i)); 1074 } 1075 1076 SQLExpr elExpr = x.getElseExpr(); 1077 if (elExpr !is null) { 1078 println(); 1079 print0(ucase ? "ELSE " : "else "); 1080 if (cast(SQLCaseExpr)elExpr !is null) { 1081 this.indentCount++; 1082 println(); 1083 visit(cast(SQLCaseExpr) elExpr); 1084 this.indentCount--; 1085 } else { 1086 printExpr(elExpr); 1087 } 1088 } 1089 1090 this.indentCount--; 1091 println(); 1092 print0(ucase ? "END" : "end"); 1093 1094 return false; 1095 } 1096 1097 override bool visit(SQLCaseExpr.Item x) { 1098 print0(ucase ? "WHEN " : "when "); 1099 SQLExpr conditionExpr = x.getConditionExpr(); 1100 printExpr(conditionExpr); 1101 1102 print0(ucase ? " THEN " : " then "); 1103 SQLExpr valueExpr = x.getValueExpr(); 1104 if (cast(SQLCaseExpr)valueExpr !is null) { 1105 this.indentCount++; 1106 println(); 1107 visit(cast(SQLCaseExpr) valueExpr); 1108 this.indentCount--; 1109 } else { 1110 printExpr(valueExpr); 1111 } 1112 1113 return false; 1114 } 1115 1116 override bool visit(SQLCaseStatement x) { 1117 print0(ucase ? "CASE" : "case"); 1118 SQLExpr valueExpr = x.getValueExpr(); 1119 if (valueExpr !is null) { 1120 print(' '); 1121 printExpr(valueExpr); 1122 } 1123 this.indentCount++; 1124 println(); 1125 printlnAndAccept!(SQLCaseStatement.Item)((x.getItems()), " "); 1126 1127 if (x.getElseStatements().size() > 0) { 1128 println(); 1129 print0(ucase ? "ELSE " : "else "); 1130 printlnAndAccept!(SQLStatement)((x.getElseStatements()), ""); 1131 } 1132 1133 this.indentCount--; 1134 1135 println(); 1136 print0(ucase ? "END CASE" : "end case"); 1137 if (DBType.ORACLE.opEquals(dbType)) { 1138 print(';'); 1139 } 1140 return false; 1141 } 1142 1143 override bool visit(SQLCaseStatement.Item x) { 1144 print0(ucase ? "WHEN " : "when "); 1145 printExpr(x.getConditionExpr()); 1146 print0(ucase ? " THEN " : " then "); 1147 1148 SQLStatement stmt = x.getStatement(); 1149 if (stmt !is null) { 1150 stmt.accept(this); 1151 print(';'); 1152 } 1153 return false; 1154 } 1155 1156 override bool visit(SQLCastExpr x) { 1157 print0(ucase ? "CAST(" : "cast("); 1158 x.getExpr().accept(this); 1159 print0(ucase ? " AS " : " as "); 1160 x.getDataType().accept(this); 1161 print0(")"); 1162 1163 return false; 1164 } 1165 1166 override bool visit(SQLCharExpr x) { 1167 if (this.parameterized) { 1168 print('?'); 1169 incrementReplaceCunt(); 1170 if (this.parameters !is null) { 1171 ExportParameterVisitorUtils.exportParameter(this.parameters, x); 1172 } 1173 return false; 1174 } 1175 1176 printChars(x.getText().value()); 1177 1178 return false; 1179 } 1180 1181 protected void printChars(string text) { 1182 if (text is null) { 1183 print0(ucase ? "NULL" : "null"); 1184 } else { 1185 print('\''); 1186 int index = cast(int)(text.indexOf('\'')); 1187 if (index >= 0) { 1188 text = text.replace("'", "''");//@gxc 1189 } 1190 print0(text); 1191 print('\''); 1192 } 1193 } 1194 1195 override bool visit(SQLDataType x) { 1196 printDataType(x); 1197 1198 return false; 1199 } 1200 1201 protected void printDataType(SQLDataType x) { 1202 bool parameterized = this.parameterized; 1203 this.parameterized = false; 1204 1205 print0(x.getName()); 1206 if (x.getArguments().size() > 0) { 1207 print('('); 1208 printAndAccept!SQLExpr(x.getArguments(), ", "); 1209 print(')'); 1210 } 1211 1212 Boolean withTimeZone = x.getWithTimeZone(); 1213 if (withTimeZone !is null) { 1214 if (withTimeZone.value()) { 1215 if (x.isWithLocalTimeZone()) { 1216 print0(ucase ? " WITH LOCAL TIME ZONE" : " with local time zone"); 1217 } else { 1218 print0(ucase ? " WITH TIME ZONE" : " with time zone"); 1219 } 1220 } else { 1221 print0(ucase ? " WITHOUT TIME ZONE" : " without time zone"); 1222 } 1223 } 1224 1225 this.parameterized = parameterized; 1226 } 1227 1228 override bool visit(SQLCharacterDataType x) { 1229 visit(cast(SQLDataType) x); 1230 1231 List!SQLCommentHint hints = (cast(SQLCharacterDataType) x).hints; 1232 if (hints !is null) { 1233 print(' '); 1234 foreach(SQLCommentHint hint ; hints) { 1235 hint.accept(this); 1236 } 1237 } 1238 1239 return false; 1240 } 1241 1242 override bool visit(SQLExistsExpr x) { 1243 if (x.isNot()) { 1244 print0(ucase ? "NOT EXISTS (" : "not exists ("); 1245 } else { 1246 print0(ucase ? "EXISTS (" : "exists ("); 1247 } 1248 this.indentCount++; 1249 println(); 1250 visit(x.getSubQuery()); 1251 this.indentCount--; 1252 println(); 1253 print(')'); 1254 return false; 1255 } 1256 1257 override bool visit(SQLIdentifierExpr x) { 1258 string name = x.getName(); 1259 if(isEnabled(VisitorFeature.OutputQuotedIdentifier)) { 1260 print0(_quotes ~ name ~ _quotes); 1261 } else { 1262 print0(name); 1263 } 1264 return false; 1265 } 1266 1267 protected bool printName(SQLName x, string name) { 1268 bool shardingSupport = this.shardingSupport 1269 && this.parameterized; 1270 return printName(x, name, shardingSupport); 1271 } 1272 1273 string unwrapShardingTable(string name) { 1274 char c0 = charAt(name, 0); 1275 char c_last = charAt(name, name.length - 1); 1276 bool quote = (c0 == '`' && c_last == '`') || (c0 == '"' && c_last == '"'); 1277 1278 int end = cast(int)(name.length); 1279 if (quote) { 1280 end--; 1281 } 1282 1283 int num_cnt = 0, postfixed_cnt = 0; 1284 for (int i = end - 1; i > 0; --i, postfixed_cnt++) { 1285 char ch = charAt(name, i); 1286 if (ch >= '0' && ch <= '9') { 1287 num_cnt++; 1288 } 1289 1290 if (ch != '_' && (ch < '0' || ch > '9')) { 1291 break; 1292 } 1293 } 1294 if (num_cnt < 1 || postfixed_cnt < 2) { 1295 return name; 1296 } 1297 1298 int start = end - postfixed_cnt; 1299 if (start < 1) { 1300 return name; 1301 } 1302 1303 string realName = name.substring(quote ? 1 : 0, start); 1304 return realName; 1305 } 1306 1307 protected bool printName(SQLName x, string name, bool shardingSupport) { 1308 1309 if (shardingSupport) { 1310 SQLObject parent = x.getParent(); 1311 shardingSupport = cast(SQLExprTableSource)parent !is null || cast(SQLPropertyExpr)parent !is null; 1312 1313 if (cast(SQLPropertyExpr)parent !is null && cast(SQLExprTableSource)parent.getParent() !is null) { 1314 shardingSupport = false; 1315 } 1316 } 1317 1318 if (shardingSupport) { 1319 bool quote = charAt(name, 0) == '`' && charAt(name, name.length - 1) == '`'; 1320 1321 string unwrappedName = unwrapShardingTable(name); 1322 if (unwrappedName != name) { 1323 bool isAlias = false; 1324 for (SQLObject parent = x.getParent(); parent !is null; parent = parent.getParent()) { 1325 if (cast(SQLSelectQueryBlock)parent !is null) { 1326 SQLTableSource from = (cast(SQLSelectQueryBlock) parent).getFrom(); 1327 if (quote) { 1328 // string name2 = name.substring(1, name.length - 1); 1329 string name2 = name[1 .. $-1]; 1330 if (isTableSourceAlias(from, name, name2)) { 1331 isAlias = true; 1332 } 1333 } else { 1334 if (isTableSourceAlias(from, name)) { 1335 isAlias = true; 1336 } 1337 } 1338 break; 1339 } 1340 } 1341 1342 if (!isAlias) { 1343 print0(unwrappedName); 1344 incrementReplaceCunt(); 1345 return false; 1346 } else { 1347 print0(name); 1348 return false; 1349 } 1350 } 1351 } 1352 1353 print0(name); 1354 return false; 1355 } 1356 1357 override bool visit(SQLInListExpr x) { 1358 if (this.parameterized) { 1359 List!SQLExpr targetList = x.getTargetList(); 1360 1361 bool allLiteral = true; 1362 foreach(SQLExpr item ; targetList) { 1363 if (!(cast(SQLLiteralExpr)item !is null || cast(SQLVariantRefExpr)item !is null)) { 1364 if (cast(SQLListExpr)item !is null) { 1365 SQLListExpr list = cast(SQLListExpr) item; 1366 foreach(SQLExpr listItem ;list.getItems()) { 1367 if (!(cast(SQLLiteralExpr)listItem !is null || cast(SQLVariantRefExpr)listItem !is null)) { 1368 allLiteral = false; 1369 break; 1370 } 1371 } 1372 if (allLiteral) { 1373 break; 1374 } 1375 continue; 1376 } 1377 allLiteral = false; 1378 break; 1379 } 1380 } 1381 1382 if (allLiteral) { 1383 bool changed = true; 1384 if (targetList.size() == 1 && cast(SQLVariantRefExpr)targetList.get(0) !is null) { 1385 changed = false; 1386 } 1387 1388 printExpr(x.getExpr()); 1389 1390 if (x.isNot()) { 1391 print(ucase ? " NOT IN" : " not in"); 1392 } else { 1393 print(ucase ? " IN" : " in"); 1394 } 1395 1396 if(!isParameterizedQuesUnMergeInList() || targetList.size() == 1) { 1397 print(" (?)"); 1398 } else { 1399 print(" ("); 1400 for (int i = 0; i < targetList.size(); i++) { 1401 if(i != 0) { 1402 print(","); 1403 } 1404 print(" ?"); 1405 } 1406 print(")"); 1407 } 1408 1409 if (changed) { 1410 incrementReplaceCunt(); 1411 if (this.parameters !is null) { 1412 if (parameterizedMergeInList) { 1413 List!Object subList = new ArrayList!Object(x.getTargetList().size()); 1414 foreach (SQLExpr target ; x.getTargetList()) { 1415 ExportParameterVisitorUtils.exportParameter(subList, target); 1416 } 1417 if (subList !is null) { 1418 parameters.addAll(subList); 1419 } 1420 } else { 1421 foreach (SQLExpr target ; x.getTargetList()) { 1422 ExportParameterVisitorUtils.exportParameter(this.parameters, target); 1423 } 1424 } 1425 } 1426 } 1427 1428 return false; 1429 } 1430 } 1431 1432 printExpr(x.getExpr()); 1433 1434 if (x.isNot()) { 1435 print0(ucase ? " NOT IN (" : " not in ("); 1436 } else { 1437 print0(ucase ? " IN (" : " in ("); 1438 } 1439 1440 List!SQLExpr list = x.getTargetList(); 1441 1442 bool _printLn = false; 1443 if (list.size() > 5) { 1444 _printLn = true; 1445 for (int i = 0, size = list.size(); i < size; ++i) { 1446 if (!(cast(SQLCharExpr)list.get(i) !is null)) { 1447 _printLn = false; 1448 break; 1449 } 1450 } 1451 } 1452 1453 if (_printLn) { 1454 this.indentCount++; 1455 println(); 1456 for (int i = 0, size = list.size(); i < size; ++i) { 1457 if (i != 0) { 1458 print0(", "); 1459 println(); 1460 } 1461 SQLExpr item = list.get(i); 1462 printExpr(item); 1463 } 1464 this.indentCount--; 1465 println(); 1466 } else { 1467 List!SQLExpr targetList = x.getTargetList(); 1468 for (int i = 0; i < targetList.size(); i++) { 1469 if (i != 0) { 1470 print0(", "); 1471 } 1472 printExpr(targetList.get(i)); 1473 } 1474 } 1475 1476 print(')'); 1477 return false; 1478 } 1479 1480 override bool visit(SQLIntegerExpr x) { 1481 bool parameterized = this.parameterized; 1482 printInteger(x, parameterized); 1483 return false; 1484 } 1485 1486 protected void printInteger(SQLIntegerExpr x, bool parameterized) { 1487 Number number = x.getNumber(); 1488 1489 if (number == (Integer.valueOf(1))) { 1490 if (DBType.ORACLE.opEquals(dbType)) { 1491 SQLObject parent = x.getParent(); 1492 if (cast(SQLBinaryOpExpr)parent !is null) { 1493 SQLBinaryOpExpr binaryOpExpr = cast(SQLBinaryOpExpr) parent; 1494 SQLExpr left = binaryOpExpr.getLeft(); 1495 SQLBinaryOperator op = binaryOpExpr.getOperator(); 1496 if (cast(SQLIdentifierExpr)left !is null 1497 && op == SQLBinaryOperator.Equality) { 1498 string name = (cast(SQLIdentifierExpr) left).getName(); 1499 if ("rownum" == (name)) { 1500 print(1); 1501 return; 1502 } 1503 } 1504 } 1505 } 1506 } 1507 if (parameterized) { 1508 print('?'); 1509 incrementReplaceCunt(); 1510 1511 if(this.parameters !is null){ 1512 ExportParameterVisitorUtils.exportParameter(this.parameters, x); 1513 } 1514 return; 1515 } 1516 1517 if (cast(BigDecimal)number !is null || cast(BigInteger)number !is null) { 1518 print((cast(Object)(number)).toString()); 1519 } else { 1520 print(number.longValue()); 1521 } 1522 } 1523 1524 override bool visit(SQLMethodInvokeExpr x) { 1525 SQLExpr owner = x.getOwner(); 1526 if (owner !is null) { 1527 printMethodOwner(owner); 1528 } 1529 1530 string _function = x.getMethodName(); 1531 List!SQLExpr parameters = x.getParameters(); 1532 1533 printFunctionName(_function); 1534 print('('); 1535 1536 string trimOption = x.getTrimOption(); 1537 if (trimOption !is null) { 1538 print0(trimOption); 1539 1540 if (parameters.size() > 0) { 1541 print(' '); 1542 } 1543 } 1544 1545 1546 for (int i = 0, size = parameters.size(); i < size; ++i) { 1547 if (i != 0) { 1548 print0(", "); 1549 } 1550 SQLExpr param = parameters.get(i); 1551 1552 if (this.parameterized) { 1553 if (size == 2 && i == 1 && cast(SQLCharExpr)param !is null) { 1554 if (DBType.ORACLE.opEquals(dbType)) { 1555 if ("TO_CHAR".equalsIgnoreCase(_function) 1556 || "TO_DATE".equalsIgnoreCase(_function)) { 1557 printChars((cast(SQLCharExpr) param).getText().value()); 1558 continue; 1559 } 1560 } else if (DBType.MYSQL.opEquals(dbType)) { 1561 if ("DATE_FORMAT".equalsIgnoreCase(_function)) { 1562 printChars((cast(SQLCharExpr) param).getText().value()); 1563 continue; 1564 } 1565 } 1566 } 1567 1568 } 1569 1570 if (cast(SQLBinaryOpExpr)param !is null) { 1571 SQLBinaryOpExpr binaryOpExpr = cast(SQLBinaryOpExpr) param; 1572 SQLBinaryOperator op = binaryOpExpr.getOperator(); 1573 if (op == SQLBinaryOperator.BooleanAnd || op == SQLBinaryOperator.BooleanOr) { 1574 this.indentCount++; 1575 printExpr(param); 1576 this.indentCount--; 1577 continue; 1578 } 1579 } 1580 1581 printExpr(param); 1582 } 1583 1584 SQLExpr from = x.getFrom(); 1585 if (from !is null) { 1586 print0(ucase ? " FROM " : " from "); 1587 printExpr(from); 1588 1589 SQLExpr _for = x.getFor(); 1590 if (_for !is null) { 1591 print0(ucase ? " FOR " : " for "); 1592 printExpr(_for); 1593 } 1594 } 1595 1596 SQLExpr using = x.getUsing(); 1597 if (using !is null) { 1598 print0(ucase ? " USING " : " using "); 1599 printExpr(using); 1600 } 1601 1602 print(')'); 1603 return false; 1604 } 1605 1606 protected void printMethodOwner(SQLExpr owner) { 1607 printExpr(owner); 1608 print('.'); 1609 } 1610 1611 protected void printFunctionName(string name) { 1612 print0(name); 1613 } 1614 1615 override bool visit(SQLAggregateExpr x) { 1616 bool parameterized = this.parameterized; 1617 this.parameterized = false; 1618 1619 string methodName = x.getMethodName(); 1620 print0(ucase ? methodName : toLower(methodName)); 1621 print('('); 1622 1623 SQLAggregateOption option = x.getOption(); 1624 if (option.name.length != 0) { 1625 print0(option.name); 1626 print(' '); 1627 } 1628 1629 List!SQLExpr arguments = x.getArguments(); 1630 for (int i = 0, size = arguments.size(); i < size; ++i) { 1631 if (i != 0) { 1632 print0(", "); 1633 } 1634 printExpr(arguments.get(i)); 1635 } 1636 1637 visitAggreateRest(x); 1638 1639 print(')'); 1640 1641 if (DBType.POSTGRESQL != dbType) { 1642 SQLOrderBy withGroup = x.getWithinGroup(); 1643 if (withGroup !is null) { 1644 print0(ucase ? " WITHIN GROUP (" : " within group ("); 1645 visit(withGroup); 1646 print(')'); 1647 } 1648 } 1649 1650 SQLKeep keep = x.getKeep(); 1651 if (keep !is null) { 1652 print(' '); 1653 visit(keep); 1654 } 1655 1656 SQLOver over = x.getOver(); 1657 if (over !is null) { 1658 print(' '); 1659 over.accept(this); 1660 } 1661 1662 SQLExpr filter = x.getFilter(); 1663 if (filter !is null) { 1664 print0(ucase ? "FILTER (WHERE " : "filter (where "); 1665 printExpr(filter); 1666 print(')'); 1667 } 1668 1669 this.parameterized = parameterized; 1670 return false; 1671 } 1672 1673 protected void visitAggreateRest(SQLAggregateExpr aggregateExpr) { 1674 1675 } 1676 1677 override bool visit(SQLAllColumnExpr x) { 1678 print('*'); 1679 return true; 1680 } 1681 1682 override bool visit(SQLNCharExpr x) { 1683 if (this.parameterized) { 1684 print('?'); 1685 incrementReplaceCunt(); 1686 1687 if(this.parameters !is null){ 1688 ExportParameterVisitorUtils.exportParameter(this.parameters, x); 1689 } 1690 return false; 1691 } 1692 1693 if ((x.getText() is null) || (x.getText().value.length == 0)) { 1694 print0(ucase ? "NULL" : "null"); 1695 } else { 1696 print0(ucase ? "N'" : "n'"); 1697 print0(x.getText().value().replace("'", "''")); 1698 print('\''); 1699 } 1700 return false; 1701 } 1702 1703 override bool visit(SQLNotExpr x) { 1704 print0(ucase ? "NOT " : "not "); 1705 SQLExpr expr = x.getExpr(); 1706 1707 bool needQuote = false; 1708 1709 if (cast(SQLBinaryOpExpr)expr !is null) { 1710 SQLBinaryOpExpr binaryOpExpr = cast(SQLBinaryOpExpr) expr; 1711 needQuote = binaryOpExpr.getOperator().isLogical(); 1712 } else if (cast(SQLInListExpr)expr !is null || cast(SQLNotExpr)expr !is null) { 1713 needQuote = true; 1714 } 1715 1716 if (needQuote) { 1717 print('('); 1718 } 1719 printExpr(expr); 1720 1721 if (needQuote) { 1722 print(')'); 1723 } 1724 return false; 1725 } 1726 1727 override bool visit(SQLNullExpr x) { 1728 if (this.parameterized 1729 && cast(ValuesClause)x.getParent() !is null) { 1730 print('?'); 1731 incrementReplaceCunt(); 1732 1733 if(this.parameters !is null){ 1734 this.getParameters().add(null); 1735 } 1736 return false; 1737 } 1738 1739 print0(ucase ? "NULL" : "null"); 1740 return false; 1741 } 1742 1743 override bool visit(SQLNumberExpr x) { 1744 if (this.parameterized) { 1745 print('?'); 1746 incrementReplaceCunt(); 1747 1748 if(this.parameters !is null){ 1749 ExportParameterVisitorUtils.exportParameter((this).getParameters(), x); 1750 } 1751 return false; 1752 } 1753 1754 if (cast(StringBuilder)appender !is null) { 1755 x.output(cast(StringBuilder) appender); 1756 } else if (cast(StringBuilder)appender !is null) { 1757 x.output(cast(StringBuilder) appender); 1758 } else { 1759 print0(x.getNumber().toString()); 1760 } 1761 return false; 1762 } 1763 1764 override bool visit(SQLPropertyExpr x) { 1765 SQLExpr owner = x.getOwner(); 1766 SQLIdentifierExpr ownerIdent = cast(SQLIdentifierExpr)owner; 1767 1768 string mapTableName = null, ownerName = null; 1769 if (ownerIdent !is null) { 1770 ownerName = ownerIdent.getName(); 1771 if (tableMapping !is null) { 1772 mapTableName = tableMapping.get(ownerName); 1773 1774 //tracef("mapTableName: %s, ownerName=%s", mapTableName, ownerName); 1775 if (mapTableName.empty() 1776 && ownerName.length > 2 1777 && ownerName[0] == '`' 1778 && ownerName[$-1] == '`') { 1779 ownerName = ownerName[1 .. $ - 1]; 1780 mapTableName = tableMapping.get(ownerName); 1781 } 1782 } 1783 } 1784 1785 1786 if (!mapTableName.empty()) { 1787 for (SQLObject parent = x.getParent();parent !is null; parent = parent.getParent()) { 1788 if (cast(SQLSelectQueryBlock)parent !is null) { 1789 SQLTableSource from = (cast(SQLSelectQueryBlock) parent).getFrom(); 1790 if (isTableSourceAlias(from, mapTableName, ownerName)) { 1791 mapTableName = null; 1792 } 1793 break; 1794 } 1795 } 1796 } 1797 1798 // version(HUNT_SQL_DEBUG_MORE) tracef("mapTableName: %s, ownerName=%s", mapTableName, ownerName); 1799 1800 if (!mapTableName.empty()) { 1801 print0(mapTableName); 1802 print('.'); 1803 } else if (ownerIdent !is null) { 1804 ownerName = ownerIdent.getName(); 1805 if(!ownerName.empty()) { 1806 if(isEnabled(VisitorFeature.OutputQuotedIdentifier)) { 1807 print(_quotes); 1808 printName(ownerIdent, ownerName, this.shardingSupport && this.parameterized); 1809 print(_quotes); 1810 } else { 1811 printName(ownerIdent, ownerName, this.shardingSupport && this.parameterized); 1812 } 1813 1814 print('.'); 1815 } 1816 } else { 1817 printExpr(owner); 1818 print('.'); 1819 } 1820 1821 string name = x.getName(); 1822 if(isEnabled(VisitorFeature.OutputQuotedIdentifier)) { 1823 print0(_quotes ~ name ~ _quotes); 1824 } else { 1825 print0(name); 1826 } 1827 1828 return false; 1829 } 1830 1831 protected bool isTableSourceAlias(SQLTableSource from, string[] tableNames...) { 1832 string _alias = from.getAlias(); 1833 1834 if (_alias !is null) { 1835 foreach(string tableName ; tableNames) { 1836 if (equalsIgnoreCase(_alias, tableName)) { 1837 return true; 1838 } 1839 } 1840 1841 if (_alias.length > 2 && charAt(_alias, 0) == '`' && charAt(_alias, _alias.length -1) == '`') { 1842 _alias = _alias.substring(1, _alias.length -1); 1843 foreach(string tableName ; tableNames) { 1844 if (equalsIgnoreCase(_alias, tableName)) { 1845 return true; 1846 } 1847 } 1848 } 1849 } 1850 if (cast(SQLJoinTableSource)from !is null) { 1851 SQLJoinTableSource join = cast(SQLJoinTableSource) from; 1852 return isTableSourceAlias(join.getLeft(), tableNames) 1853 || isTableSourceAlias(join.getRight(), tableNames); 1854 } 1855 return false; 1856 } 1857 1858 override bool visit(SQLQueryExpr x) { 1859 SQLObject parent = x.getParent(); 1860 if (cast(SQLSelect)parent !is null) { 1861 parent = parent.getParent(); 1862 } 1863 1864 SQLSelect subQuery = x.getSubQuery(); 1865 if (cast(ValuesClause)parent !is null) { 1866 println(); 1867 print('('); 1868 visit(subQuery); 1869 print(')'); 1870 println(); 1871 // } else if ((cast(SQLStatement)parent !is null 1872 // && !(cast(OracleForStatement)parent !is null)) 1873 // || cast(OracleSelectPivot.Item)parent !is null) { 1874 // this.indentCount++; 1875 1876 // println(); 1877 // visit(subQuery); 1878 1879 // this.indentCount--; 1880 } else if (cast(SQLOpenStatement)parent !is null) { 1881 visit(subQuery); 1882 } else { 1883 print('('); 1884 this.indentCount++; 1885 println(); 1886 visit(subQuery); 1887 this.indentCount--; 1888 println(); 1889 print(')'); 1890 } 1891 return false; 1892 } 1893 1894 override bool visit(SQLSelectGroupByClause x) { 1895 1896 bool oracle = DBType.ORACLE.opEquals(dbType); 1897 bool rollup = x.isWithRollUp(); 1898 bool cube = x.isWithCube(); 1899 1900 int itemSize = x.getItems().size(); 1901 if (itemSize > 0) { 1902 print0(ucase ? "GROUP BY " : "group by "); 1903 if (oracle && rollup) { 1904 print0(ucase ? "ROLLUP (" : "rollup ("); 1905 } else if (oracle && cube) { 1906 print0(ucase ? "CUBE (" : "cube ("); 1907 } 1908 this.indentCount++; 1909 for (int i = 0; i < itemSize; ++i) { 1910 if (i != 0) { 1911 if (groupItemSingleLine) { 1912 println(", "); 1913 } else { 1914 print(", "); 1915 } 1916 } 1917 x.getItems().get(i).accept(this); 1918 } 1919 if (oracle && rollup) { 1920 print(')'); 1921 } 1922 this.indentCount--; 1923 } 1924 1925 if (x.getHaving() !is null) { 1926 println(); 1927 print0(ucase ? "HAVING " : "having "); 1928 x.getHaving().accept(this); 1929 } 1930 1931 if (x.isWithRollUp() && !oracle) { 1932 print0(ucase ? " WITH ROLLUP" : " with rollup"); 1933 } 1934 1935 if (x.isWithCube() && !oracle) { 1936 print0(ucase ? " WITH CUBE" : " with cube"); 1937 } 1938 1939 return false; 1940 } 1941 1942 override bool visit(SQLSelect x) { 1943 SQLWithSubqueryClause withSubQuery = x.getWithSubQuery(); 1944 if (withSubQuery !is null) { 1945 withSubQuery.accept(this); 1946 println(); 1947 } 1948 1949 printQuery(x.getQuery()); 1950 1951 SQLOrderBy orderBy = x.getOrderBy(); 1952 if (orderBy !is null) { 1953 println(); 1954 orderBy.accept(this); 1955 } 1956 1957 if (x.getHintsSize() > 0) { 1958 printAndAccept!SQLHint((x.getHints()), ""); 1959 } 1960 1961 return false; 1962 } 1963 1964 override bool visit(SQLSelectQueryBlock x) { 1965 if (isPrettyFormat() && x.hasBeforeComment()) { 1966 printlnComments(x.getBeforeCommentsDirect()); 1967 } 1968 1969 print0(ucase ? "SELECT " : "select "); 1970 1971 bool informix =DBType.INFORMIX.opEquals(dbType); 1972 if (informix) { 1973 printFetchFirst(x); 1974 } 1975 1976 int distinctOption = x.getDistionOption(); 1977 if (SQLSetQuantifier.ALL == distinctOption) { 1978 print0(ucase ? "ALL " : "all "); 1979 } else if (SQLSetQuantifier.DISTINCT == distinctOption) { 1980 print0(ucase ? "DISTINCT " : "distinct "); 1981 } else if (SQLSetQuantifier.UNIQUE == distinctOption) { 1982 print0(ucase ? "UNIQUE " : "unique "); 1983 } 1984 1985 printSelectList( 1986 x.getSelectList()); 1987 1988 SQLExprTableSource into = x.getInto(); 1989 if (into !is null) { 1990 println(); 1991 print0(ucase ? "INTO " : "into "); 1992 into.accept(this); 1993 } 1994 1995 SQLTableSource from = x.getFrom(); 1996 if (from !is null) { 1997 println(); 1998 print0(ucase ? "FROM " : "from "); 1999 printTableSource(from); 2000 } 2001 2002 SQLExpr where = x.getWhere(); 2003 if (where !is null) { 2004 println(); 2005 print0(ucase ? "WHERE " : "where "); 2006 printExpr(where); 2007 } 2008 2009 printHierarchical(x); 2010 2011 SQLSelectGroupByClause groupBy = x.getGroupBy(); 2012 if (groupBy !is null) { 2013 println(); 2014 visit(groupBy); 2015 } 2016 2017 SQLOrderBy orderBy = x.getOrderBy(); 2018 if (orderBy !is null) { 2019 println(); 2020 orderBy.accept(this); 2021 } 2022 2023 if (!informix) { 2024 printFetchFirst(x); 2025 } 2026 2027 if (x.isForUpdate()) { 2028 println(); 2029 print0(ucase ? "FOR UPDATE" : "for update"); 2030 } 2031 2032 return false; 2033 } 2034 2035 protected void printFetchFirst(SQLSelectQueryBlock x) { 2036 SQLLimit limit = x.getLimit(); 2037 if (limit is null) { 2038 return; 2039 } 2040 2041 SQLExpr offset = limit.getOffset(); 2042 SQLExpr first = limit.getRowCount(); 2043 2044 if (limit !is null) { 2045 if (DBType.INFORMIX.opEquals(dbType)) { 2046 if (offset !is null) { 2047 print0(ucase ? "SKIP " : "skip "); 2048 offset.accept(this); 2049 } 2050 2051 print0(ucase ? " FIRST " : " first "); 2052 first.accept(this); 2053 print(' '); 2054 } else if (DBType.DB2.opEquals(dbType) 2055 || DBType.ORACLE.opEquals(dbType) 2056 || DBType.SQL_SERVER.opEquals(dbType)) { 2057 //order by 语句必须在FETCH FIRST ROWS ONLY之前 2058 SQLObject parent = x.getParent(); 2059 if (cast(SQLSelect)parent !is null) { 2060 SQLOrderBy orderBy = (cast(SQLSelect) parent).getOrderBy(); 2061 if (orderBy !is null && orderBy.getItems().size() > 0) { 2062 println(); 2063 print0(ucase ? "ORDER BY " : "order by "); 2064 printAndAccept!SQLSelectOrderByItem((orderBy.getItems()), ", "); 2065 } 2066 } 2067 2068 println(); 2069 2070 if (offset !is null) { 2071 print0(ucase ? "OFFSET " : "offset "); 2072 offset.accept(this); 2073 print0(ucase ? " ROWS" : " rows"); 2074 } 2075 2076 if (first !is null) { 2077 if (offset !is null) { 2078 print(' '); 2079 } 2080 if (DBType.SQL_SERVER.opEquals(dbType) && offset !is null) { 2081 print0(ucase ? "FETCH NEXT " : "fetch next "); 2082 } else { 2083 print0(ucase ? "FETCH FIRST " : "fetch first "); 2084 } 2085 first.accept(this); 2086 print0(ucase ? " ROWS ONLY" : " rows only"); 2087 } 2088 } else { 2089 println(); 2090 limit.accept(this); 2091 } 2092 } 2093 } 2094 2095 override bool visit(SQLSelectItem x) { 2096 if (x.isConnectByRoot()) { 2097 print0(ucase ? "CONNECT_BY_ROOT " : "connect_by_root "); 2098 } 2099 2100 SQLExpr expr = x.getExpr(); 2101 SQLIdentifierExpr identifierExpr = cast(SQLIdentifierExpr)expr; 2102 2103 if (identifierExpr !is null) { 2104 string name = identifierExpr.getName(); 2105 print0(name); 2106 // if(isEnabled(VisitorFeature.OutputQuotedIdentifier)) { 2107 // print0(_quotes ~ name ~ _quotes); 2108 // } else { 2109 // print0(name); 2110 // } 2111 } else if (cast(SQLPropertyExpr)expr !is null) { 2112 visit(cast(SQLPropertyExpr) expr); 2113 } else { 2114 printExpr(expr); 2115 } 2116 2117 string _alias = x.getAlias(); 2118 if (!_alias.empty) { 2119 print0(ucase ? " AS " : " as "); 2120 _alias = _alias.strip(); 2121 char c0 = _alias[0]; 2122 if (c0 == '"' || c0 == '\'') { // _alias.indexOf(' ') == -1 || 2123 print0(_alias); 2124 } else { 2125 if(isEnabled(VisitorFeature.OutputQuotedIdentifier)) { 2126 print0(_quotes ~ _alias ~ _quotes); 2127 } else { 2128 print0(_alias); 2129 } 2130 } 2131 } 2132 return false; 2133 } 2134 2135 override bool visit(SQLOrderBy x) { 2136 List!SQLSelectOrderByItem items = x.getItems(); 2137 2138 if (items.size() > 0) { 2139 if (x.isSibings()) { 2140 print0(ucase ? "ORDER SIBLINGS BY " : "order siblings by "); 2141 } else { 2142 print0(ucase ? "ORDER BY " : "order by "); 2143 } 2144 2145 for (int i = 0, size = items.size(); i < size; ++i) { 2146 if (i != 0) { 2147 print0(", "); 2148 } 2149 SQLSelectOrderByItem item = items.get(i); 2150 visit(item); 2151 } 2152 } 2153 return false; 2154 } 2155 2156 override bool visit(SQLSelectOrderByItem x) { 2157 SQLExpr expr = x.getExpr(); 2158 2159 if (cast(SQLIntegerExpr)expr !is null) { 2160 print((cast(SQLIntegerExpr) expr).getNumber().longValue()); 2161 } else { 2162 printExpr(expr); 2163 } 2164 2165 SQLOrderingSpecification type = x.getType(); 2166 if (type !is null) { 2167 print(' '); 2168 print0(ucase ? type.name : type.name_lcase); 2169 } 2170 2171 string collate = x.getCollate(); 2172 if (collate !is null) { 2173 print0(ucase ? " COLLATE " : " collate "); 2174 print0(collate); 2175 } 2176 2177 SQLSelectOrderByItem.NullsOrderType nullsOrderType = x.getNullsOrderType(); 2178 if (nullsOrderType.name.length != 0) { 2179 print(' '); 2180 print0(nullsOrderType.toFormalString()); 2181 } 2182 2183 return false; 2184 } 2185 2186 protected void addTable(string table) { 2187 if (tables is null) { 2188 if (this.table is null) { 2189 this.table = table; 2190 return; 2191 } else { 2192 tables = new LinkedHashSet!string(); 2193 tables.add(this.table); 2194 } 2195 } 2196 this.tables.add(table); 2197 } 2198 2199 protected void printTableSourceExpr(SQLExpr expr) { 2200 if (exportTables) { 2201 addTable((cast(Object)(expr)).toString()); 2202 } 2203 2204 if (isEnabled(VisitorFeature.OutputDesensitize)) { 2205 string ident = null; 2206 if (cast(SQLIdentifierExpr)expr !is null) { 2207 ident = (cast(SQLIdentifierExpr) expr).getName(); 2208 } else if (cast(SQLPropertyExpr)expr !is null) { 2209 SQLPropertyExpr propertyExpr = cast(SQLPropertyExpr) expr; 2210 propertyExpr.getOwner().accept(this); 2211 print('.'); 2212 2213 ident = propertyExpr.getName(); 2214 } 2215 2216 if (ident !is null) { 2217 string desensitizeTable = SQLUtils.desensitizeTable(ident); 2218 print0(desensitizeTable); 2219 return; 2220 } 2221 } 2222 2223 if (tableMapping !is null && cast(SQLName)expr !is null) { 2224 string tableName; 2225 if (cast(SQLIdentifierExpr)expr !is null) { 2226 tableName = (cast(SQLIdentifierExpr) expr).normalizedName(); 2227 } else if (cast(SQLPropertyExpr)expr !is null) { 2228 tableName = (cast(SQLPropertyExpr) expr).normalizedName(); 2229 } else { 2230 tableName = (cast(Object)(expr)).toString(); 2231 } 2232 2233 string destTableName = tableMapping.get(tableName); 2234 if (destTableName is null) { 2235 if (cast(SQLPropertyExpr)expr !is null) { 2236 SQLPropertyExpr propertyExpr = cast(SQLPropertyExpr) expr; 2237 string propName = propertyExpr.getName(); 2238 destTableName = tableMapping.get(propName); 2239 if (destTableName is null 2240 && propName.length > 2 && charAt(propName, 0) == '`' && charAt(propName, propName.length - 1) == '`') { 2241 destTableName = tableMapping.get(propName.substring(1, propName.length - 1)); 2242 } 2243 2244 if (destTableName !is null) { 2245 propertyExpr.getOwner().accept(this); 2246 print('.'); 2247 print(destTableName); 2248 return; 2249 } 2250 } else if (cast(SQLIdentifierExpr)expr !is null) { 2251 bool quote = tableName.length > 2 && charAt(tableName, 0) == '`' && charAt(tableName, tableName.length - 1) == '`'; 2252 if (quote) { 2253 destTableName = tableMapping.get(tableName.substring(1, tableName.length - 1)); 2254 } 2255 } 2256 } 2257 if (destTableName !is null) { 2258 tableName = destTableName; 2259 print0(tableName); 2260 return; 2261 } 2262 } 2263 2264 SQLIdentifierExpr identifierExpr = cast(SQLIdentifierExpr) expr; 2265 SQLPropertyExpr propertyExpr = cast(SQLPropertyExpr) expr; 2266 2267 if (identifierExpr !is null) { 2268 string name = identifierExpr.getName(); 2269 if (!this.parameterized) { 2270 if(isEnabled(VisitorFeature.OutputQuotedIdentifier)) { 2271 print0(_quotes ~ name ~ _quotes); 2272 } else { 2273 print0(name); 2274 } 2275 return; 2276 } 2277 2278 bool shardingSupport = this.shardingSupport 2279 && this.parameterized; 2280 2281 if (shardingSupport) { 2282 string nameUnwrappe = unwrapShardingTable(name); 2283 2284 if (!(name == nameUnwrappe)) { 2285 incrementReplaceCunt(); 2286 } 2287 2288 print0(nameUnwrappe); 2289 } else { 2290 print0(name); 2291 } 2292 } else if (propertyExpr !is null) { 2293 SQLExpr owner = propertyExpr.getOwner(); 2294 2295 printTableSourceExpr(owner); 2296 print('.'); 2297 2298 string name = propertyExpr.getName(); 2299 if (!this.parameterized) { 2300 print0(propertyExpr.getName()); 2301 return; 2302 } 2303 2304 bool shardingSupport = this.shardingSupport 2305 && this.parameterized; 2306 2307 if (shardingSupport) { 2308 string nameUnwrappe = unwrapShardingTable(name); 2309 2310 if (!(name == nameUnwrappe)) { 2311 incrementReplaceCunt(); 2312 } 2313 2314 print0(nameUnwrappe); 2315 } else { 2316 print0(name); 2317 } 2318 } else { 2319 expr.accept(this); 2320 } 2321 2322 } 2323 2324 override bool visit(SQLExprTableSource x) { 2325 printTableSourceExpr(x.getExpr()); 2326 2327 string _alias = x.getAlias(); 2328 if (_alias !is null) { 2329 print(' '); 2330 print0(_alias); 2331 } 2332 2333 if (isPrettyFormat() && x.hasAfterComment()) { 2334 print(' '); 2335 printlnComment(x.getAfterCommentsDirect()); 2336 } 2337 2338 return false; 2339 } 2340 2341 override bool visit(SQLSelectStatement stmt) { 2342 List!SQLCommentHint headHints = stmt.getHeadHintsDirect(); 2343 if (headHints !is null) { 2344 foreach(SQLCommentHint hint ; headHints) { 2345 hint.accept(this); 2346 println(); 2347 } 2348 } 2349 2350 SQLSelect select = stmt.getSelect(); 2351 this.visit(select); 2352 2353 return false; 2354 } 2355 2356 override bool visit(SQLVariantRefExpr x) { 2357 int index = x.getIndex(); 2358 2359 if (index < 0 || inputParameters is null || index >= inputParameters.size()) { 2360 print0(x.getName()); 2361 return false; 2362 } 2363 2364 Object param = inputParameters.get(index); 2365 2366 SQLObject parent = x.getParent(); 2367 2368 bool _in; 2369 if (cast(SQLInListExpr)parent !is null) { 2370 _in = true; 2371 } else if (cast(SQLBinaryOpExpr)parent !is null) { 2372 SQLBinaryOpExpr binaryOpExpr = cast(SQLBinaryOpExpr) parent; 2373 if (binaryOpExpr.getOperator() == SQLBinaryOperator.Equality) { 2374 _in = true; 2375 } else { 2376 _in = false; 2377 } 2378 } else { 2379 _in = false; 2380 } 2381 2382 if (_in && cast(Collection!Object)param !is null) { 2383 bool first = true; 2384 foreach (Object item ; cast(Collection!Object) param) { 2385 if (!first) { 2386 print0(", "); 2387 } 2388 printParameter(item); 2389 first = false; 2390 } 2391 } else { 2392 printParameter(param); 2393 } 2394 return false; 2395 } 2396 2397 void printParameter(Object param) { 2398 if (param is null) { 2399 print0(ucase ? "NULL" : "null"); 2400 return; 2401 } 2402 2403 if (cast(String)param !is null) { 2404 SQLCharExpr charExpr = new SQLCharExpr(cast(String) param); 2405 visit(charExpr); 2406 return; 2407 } 2408 2409 if (cast(Number)param !is null // 2410 || cast(Boolean)param !is null) { 2411 print0((cast(Object)(param)).toString()); 2412 return; 2413 } 2414 2415 Bytes bytesData = cast(Bytes)param; 2416 if(bytesData !is null) { 2417 print0(bytesData); 2418 return; 2419 } 2420 2421 //@gxc 2422 // if (cast(Date)param !is null) { 2423 // print(cast(Date) param); 2424 // return; 2425 // } 2426 2427 // if (cast(InputStream)param !is null) { 2428 // print0("'!(InputStream)"); 2429 // return; 2430 // } 2431 2432 // if (cast(Reader)param !is null) { 2433 // print0("'!(Reader)"); 2434 // return; 2435 // } 2436 2437 // if (cast(Blob)param !is null) { 2438 // print0("'!(Blob)"); 2439 // return; 2440 // } 2441 2442 // if (cast(NClob)param !is null) { 2443 // print0("'!(NClob)"); 2444 // return; 2445 // } 2446 2447 // if (cast(Clob)param !is null) { 2448 // print0("'!(Clob)"); 2449 // return; 2450 // } 2451 2452 // if (cast(byte[])param !is null) { 2453 // byte[] bytes = cast(byte[]) param; 2454 // int bytesLen = bytes.length; 2455 // char[] chars = new char[bytesLen * 2 + 3]; 2456 // chars[0] = 'x'; 2457 // chars[1] = '\''; 2458 // for (int i = 0; i < bytes.length; i++) { 2459 // int a = bytes[i] & 0xFF; 2460 // int b0 = a >> 4; 2461 // int b1 = a & 0xf; 2462 2463 // chars[i * 2 + 2] = cast(char) (b0 + (b0 < 10 ? 48 : 55)); //hexChars[b0]; 2464 // chars[i * 2 + 3] = cast(char) (b1 + (b1 < 10 ? 48 : 55)); 2465 // } 2466 // chars[chars.length - 1] = '\''; 2467 // print0(new String(chars)); 2468 // return; 2469 // } 2470 warningf("unhandled parameter: %s", typeid(param).name); 2471 print0("'" ~ typeid(param).name ~ "'"); 2472 } 2473 2474 override bool visit(SQLDropTableStatement x) { 2475 print0(ucase ? "DROP " : "drop "); 2476 List!SQLCommentHint hints = x.getHints(); 2477 if (hints !is null) { 2478 printAndAccept!SQLCommentHint(hints, " "); 2479 print(' '); 2480 } 2481 2482 if (x.isTemporary()) { 2483 print0(ucase ? "TEMPORARY TABLE " : "temporary table "); 2484 } else { 2485 print0(ucase ? "TABLE " : "table "); 2486 } 2487 2488 if (x.isIfExists()) { 2489 print0(ucase ? "IF EXISTS " : "if exists "); 2490 } 2491 2492 printAndAccept!SQLExprTableSource((x.getTableSources()), ", "); 2493 2494 if (x.isCascade()) { 2495 printCascade(); 2496 } 2497 2498 if (x.isRestrict()) { 2499 print0(ucase ? " RESTRICT" : " restrict"); 2500 } 2501 2502 if (x.isPurge()) { 2503 print0(ucase ? " PURGE" : " purge"); 2504 } 2505 2506 return false; 2507 } 2508 2509 protected void printCascade() { 2510 print0(ucase ? " CASCADE" : " cascade"); 2511 } 2512 2513 override bool visit(SQLDropViewStatement x) { 2514 print0(ucase ? "DROP VIEW " : "drop view "); 2515 2516 if (x.isIfExists()) { 2517 print0(ucase ? "IF EXISTS " : "if exists "); 2518 } 2519 2520 printAndAccept!SQLExprTableSource((x.getTableSources()), ", "); 2521 2522 if (x.isCascade()) { 2523 printCascade(); 2524 } 2525 return false; 2526 } 2527 2528 override bool visit(SQLDropMaterializedViewStatement x) { 2529 print0(ucase ? "DROP VIEW " : "drop view "); 2530 2531 if (x.isIfExists()) { 2532 print0(ucase ? "IF EXISTS " : "if exists "); 2533 } 2534 2535 x.getName().accept(this); 2536 2537 return false; 2538 } 2539 2540 override bool visit(SQLDropEventStatement x) { 2541 print0(ucase ? "DROP EVENT " : "drop event "); 2542 2543 if (x.isIfExists()) { 2544 print0(ucase ? "IF EXISTS " : "if exists "); 2545 } 2546 2547 printExpr(x.getName()); 2548 return false; 2549 } 2550 2551 override bool visit(SQLColumnDefinition x) { 2552 bool parameterized = this.parameterized; 2553 this.parameterized = false; 2554 2555 x.getName().accept(this); 2556 2557 if (x.getDataType() !is null) { 2558 print(' '); 2559 x.getDataType().accept(this); 2560 } 2561 2562 if (x.getDefaultExpr() !is null) { 2563 visitColumnDefault(x); 2564 } 2565 2566 if (x.isAutoIncrement()) { 2567 print0(ucase ? " AUTO_INCREMENT" : " auto_increment"); 2568 } 2569 2570 foreach (SQLColumnConstraint item ; x.getConstraints()) { 2571 bool newLine = cast(SQLForeignKeyConstraint)item !is null // 2572 || cast(SQLPrimaryKey)item !is null // 2573 || cast(SQLColumnCheck)item !is null // 2574 || cast(SQLColumnCheck)item !is null // 2575 || item.getName() !is null; 2576 if (newLine) { 2577 this.indentCount++; 2578 println(); 2579 } else { 2580 print(' '); 2581 } 2582 2583 item.accept(this); 2584 2585 if (newLine) { 2586 this.indentCount--; 2587 } 2588 } 2589 2590 SQLExpr generatedAlawsAs = x.getGeneratedAlawsAs(); 2591 if (generatedAlawsAs !is null) { 2592 print0(ucase ? " GENERATED ALWAYS AS " : " generated always as "); 2593 printExpr(generatedAlawsAs); 2594 } 2595 2596 SQLColumnDefinition.Identity identity = x.getIdentity(); 2597 if (identity !is null) { 2598 print(' '); 2599 identity.accept(this); 2600 } 2601 2602 if (x.getEnable() !is null) { 2603 if (x.getEnable().booleanValue()) { 2604 print0(ucase ? " ENABLE" : " enable"); 2605 } 2606 } 2607 2608 if (x.getComment() !is null) { 2609 print0(ucase ? " COMMENT " : " comment "); 2610 x.getComment().accept(this); 2611 } 2612 2613 this.parameterized = parameterized; 2614 2615 return false; 2616 } 2617 2618 override 2619 bool visit(SQLColumnDefinition.Identity x) { 2620 print0(ucase ? "IDENTITY" : "identity"); 2621 if (x.getSeed() !is null) { 2622 print0(" ("); 2623 print(x.getSeed().intValue()); 2624 print0(", "); 2625 print(x.getIncrement().intValue()); 2626 print(')'); 2627 } 2628 return false; 2629 } 2630 2631 protected void visitColumnDefault(SQLColumnDefinition x) { 2632 print0(ucase ? " DEFAULT " : " default "); 2633 x.getDefaultExpr().accept(this); 2634 } 2635 2636 override bool visit(SQLDeleteStatement x) { 2637 SQLTableSource from = x.getFrom(); 2638 string _alias = x.getAlias(); 2639 2640 if (from is null) { 2641 print0(ucase ? "DELETE FROM " : "delete from "); 2642 printTableSourceExpr(x.getTableName()); 2643 2644 if (_alias !is null) { 2645 print(' '); 2646 print0(_alias); 2647 } 2648 } else { 2649 print0(ucase ? "DELETE " : "delete "); 2650 printTableSourceExpr(x.getTableName()); 2651 print0(ucase ? " FROM " : " from "); 2652 from.accept(this); 2653 } 2654 2655 SQLExpr where = x.getWhere(); 2656 if (where !is null) { 2657 println(); 2658 print0(ucase ? "WHERE " : "where "); 2659 this.indentCount++; 2660 where.accept(this); 2661 this.indentCount--; 2662 } 2663 2664 return false; 2665 } 2666 2667 override bool visit(SQLCurrentOfCursorExpr x) { 2668 print0(ucase ? "CURRENT OF " : "current of "); 2669 printExpr(x.getCursorName()); 2670 return false; 2671 } 2672 2673 override bool visit(SQLInsertStatement x) { 2674 if (x.isUpsert()) { 2675 print0(ucase ? "UPSERT INTO " : "upsert into "); 2676 } else { 2677 print0(ucase ? "INSERT INTO " : "insert into "); 2678 } 2679 2680 x.getTableSource().accept(this); 2681 2682 string columnsString = x.getColumnsString(); 2683 if (columnsString !is null) { 2684 print0(columnsString); 2685 } else { 2686 printInsertColumns(x.getColumns()); 2687 } 2688 2689 if (!x.getValuesList().isEmpty()) { 2690 println(); 2691 print0(ucase ? "VALUES " : "values "); 2692 printAndAccept!ValuesClause((x.getValuesList()), ", "); 2693 } else { 2694 if (x.getQuery() !is null) { 2695 println(); 2696 x.getQuery().accept(this); 2697 } 2698 } 2699 2700 return false; 2701 } 2702 2703 void printInsertColumns(List!SQLExpr columns) { 2704 int size = columns.size(); 2705 if (size > 0) { 2706 if (size > 5) { 2707 this.indentCount++; 2708 println(); 2709 } else { 2710 print(' '); 2711 } 2712 print('('); 2713 for (int i = 0; i < size; ++i) { 2714 if (i != 0) { 2715 if (i % 5 == 0) { 2716 println(); 2717 } 2718 print0(", "); 2719 } 2720 2721 SQLExpr column = columns.get(i); 2722 if (cast(SQLIdentifierExpr)column !is null) { 2723 visit(cast(SQLIdentifierExpr) column); 2724 } else { 2725 printExpr(column); 2726 } 2727 2728 String dataType = cast(String) column.getAttribute("dataType"); 2729 if (dataType !is null) { 2730 print(' '); 2731 print(dataType.value()); 2732 } 2733 } 2734 print(')'); 2735 if (size > 5) { 2736 this.indentCount--; 2737 } 2738 } 2739 } 2740 2741 override bool visit(SQLUpdateSetItem x) { 2742 printExpr(x.getColumn()); 2743 print0(" = "); 2744 printExpr(x.getValue()); 2745 return false; 2746 } 2747 2748 override bool visit(SQLUpdateStatement x) { 2749 print0(ucase ? "UPDATE " : "update "); 2750 2751 printTableSource(x.getTableSource()); 2752 2753 println(); 2754 print0(ucase ? "SET " : "set "); 2755 for (int i = 0, size = x.getItems().size(); i < size; ++i) { 2756 if (i != 0) { 2757 print0(", "); 2758 } 2759 SQLUpdateSetItem item = x.getItems().get(i); 2760 visit(item); 2761 } 2762 2763 SQLExpr where = x.getWhere(); 2764 if (where !is null) { 2765 println(); 2766 indentCount++; 2767 print0(ucase ? "WHERE " : "where "); 2768 printExpr(where); 2769 indentCount--; 2770 } 2771 2772 return false; 2773 } 2774 2775 protected void printTableElements(List!SQLTableElement tableElementList) { 2776 int size = tableElementList.size(); 2777 if (size == 0) { 2778 return; 2779 } 2780 2781 print0(" ("); 2782 2783 this.indentCount++; 2784 println(); 2785 for (int i = 0; i < size; ++i) { 2786 SQLTableElement element = tableElementList.get(i); 2787 element.accept(this); 2788 2789 if (i != size - 1) { 2790 print(','); 2791 } 2792 if (this.isPrettyFormat() && element.hasAfterComment()) { 2793 print(' '); 2794 printlnComment(element.getAfterCommentsDirect()); 2795 } 2796 2797 if (i != size - 1) { 2798 println(); 2799 } 2800 } 2801 this.indentCount--; 2802 println(); 2803 print(')'); 2804 } 2805 2806 override bool visit(SQLCreateTableStatement x) { 2807 printCreateTable(x, true); 2808 2809 Map!(string, SQLObject) options = x.getTableOptions(); 2810 if (options.size() > 0) { 2811 println(); 2812 print0(ucase ? "WITH (" : "with ("); 2813 int i = 0; 2814 foreach (string key, SQLObject v ; x.getTableOptions()) { 2815 if (i > 0) { 2816 print0(", "); 2817 } 2818 // string key = option.getKey(); 2819 print0(key); 2820 2821 print0(" = "); 2822 2823 v.accept(this); 2824 ++i; 2825 } 2826 print(')'); 2827 } 2828 2829 return false; 2830 } 2831 2832 protected void printCreateTable(SQLCreateTableStatement x, bool printSelect) { 2833 print0(ucase ? "CREATE " : "create "); 2834 2835 SQLCreateTableStatement.Type tableType = x.getType(); 2836 if (SQLCreateTableStatement.Type.GLOBAL_TEMPORARY == (tableType)) { 2837 print0(ucase ? "GLOBAL TEMPORARY " : "global temporary "); 2838 } else if (SQLCreateTableStatement.Type.LOCAL_TEMPORARY == (tableType)) { 2839 print0(ucase ? "LOCAL TEMPORARY " : "local temporary "); 2840 } 2841 print0(ucase ? "TABLE " : "table "); 2842 2843 if (x.isIfNotExiists()) { 2844 print0(ucase ? "IF NOT EXISTS " : "if not exists "); 2845 } 2846 2847 printTableSourceExpr(x.getName()); 2848 2849 printTableElements(x.getTableElementList()); 2850 2851 SQLExprTableSource inherits = x.getInherits(); 2852 if (inherits !is null) { 2853 print0(ucase ? " INHERITS (" : " inherits ("); 2854 inherits.accept(this); 2855 print(')'); 2856 } 2857 2858 SQLName storedAs = x.getStoredAs(); 2859 if (storedAs !is null) { 2860 print0(ucase ? " STORE AS " : " store as "); 2861 printExpr(storedAs); 2862 } 2863 2864 SQLSelect select = x.getSelect(); 2865 if (printSelect && select !is null) { 2866 println(); 2867 print0(ucase ? "AS" : "as"); 2868 2869 println(); 2870 visit(select); 2871 } 2872 } 2873 2874 bool visit(SQLUniqueConstraint x) { 2875 if (x.getName() !is null) { 2876 print0(ucase ? "CONSTRAINT " : "constraint "); 2877 x.getName().accept(this); 2878 print(' '); 2879 } 2880 2881 print0(ucase ? "UNIQUE (" : "unique ("); 2882 List!SQLSelectOrderByItem columns = x.getColumns(); 2883 for (int i = 0, size = columns.size(); i < size; ++i) { 2884 if (i != 0) { 2885 print0(", "); 2886 } 2887 visit(columns.get(i)); 2888 } 2889 print(')'); 2890 return false; 2891 } 2892 2893 override bool visit(SQLNotNullConstraint x) { 2894 SQLName name = x.getName(); 2895 if (name !is null) { 2896 print0(ucase ? "CONSTRAINT " : "constraint "); 2897 name.accept(this); 2898 print(' '); 2899 } 2900 print0(ucase ? "NOT NULL" : "not null"); 2901 2902 List!SQLCommentHint hints = x.hints; 2903 if (hints !is null) { 2904 print(' '); 2905 foreach (SQLCommentHint hint ; hints) { 2906 hint.accept(this); 2907 } 2908 } 2909 2910 return false; 2911 } 2912 2913 override bool visit(SQLNullConstraint x) { 2914 SQLName name = x.getName(); 2915 if (name !is null) { 2916 print0(ucase ? "CONSTRAINT " : "constraint "); 2917 name.accept(this); 2918 print(' '); 2919 } 2920 print0(ucase ? "NULL" : "null"); 2921 return false; 2922 } 2923 2924 override 2925 bool visit(SQLUnionQuery x) { 2926 SQLUnionOperator operator = x.getOperator(); 2927 SQLSelectQuery left = x.getLeft(); 2928 SQLSelectQuery right = x.getRight(); 2929 2930 bool bracket = x.isBracket() && !( cast(SQLUnionQueryTableSource)x.getParent() !is null); 2931 2932 SQLOrderBy orderBy = x.getOrderBy(); 2933 if ((!bracket) 2934 && cast(SQLUnionQuery)left !is null 2935 && (cast(SQLUnionQuery) left).getOperator() == operator 2936 && !right.isBracket() 2937 && orderBy is null) { 2938 2939 SQLUnionQuery leftUnion = cast(SQLUnionQuery) left; 2940 2941 List!SQLSelectQuery rights = new ArrayList!SQLSelectQuery(); 2942 rights.add(right); 2943 2944 for (;;) { 2945 SQLSelectQuery leftLeft = leftUnion.getLeft(); 2946 SQLSelectQuery leftRight = leftUnion.getRight(); 2947 2948 if ((!leftUnion.isBracket()) 2949 && leftUnion.getOrderBy() is null 2950 && (!leftLeft.isBracket()) 2951 && (!leftRight.isBracket()) 2952 && cast(SQLUnionQuery)leftLeft !is null 2953 && (cast(SQLUnionQuery) leftLeft).getOperator() == operator) { 2954 rights.add(leftRight); 2955 leftUnion = cast(SQLUnionQuery) leftLeft; 2956 continue; 2957 } else { 2958 rights.add(leftRight); 2959 rights.add(leftLeft); 2960 } 2961 break; 2962 } 2963 2964 for (int i = rights.size() - 1; i >= 0; i--) { 2965 SQLSelectQuery item = rights.get(i); 2966 item.accept(this); 2967 2968 if (i > 0) { 2969 println(); 2970 print0(ucase ? operator.name : operator.name_lcase); 2971 println(); 2972 } 2973 } 2974 return false; 2975 } 2976 2977 if (bracket) { 2978 print('('); 2979 } 2980 2981 if (left !is null) { 2982 for (;;) { 2983 if (typeid(left) == typeid(SQLUnionQuery)) { 2984 SQLUnionQuery leftUnion = cast(SQLUnionQuery) left; 2985 SQLSelectQuery leftLeft = leftUnion.getLeft(); 2986 SQLSelectQuery leftRigt = leftUnion.getRight(); 2987 if ((!leftUnion.isBracket()) 2988 && cast(SQLSelectQueryBlock)leftUnion.getRight() !is null 2989 && leftUnion.getLeft() !is null 2990 && leftUnion.getOrderBy() is null) 2991 { 2992 if (typeid(leftLeft) == typeid(SQLUnionQuery)) { 2993 visit(cast(SQLUnionQuery) leftLeft); 2994 } else { 2995 printQuery(leftLeft); 2996 } 2997 println(); 2998 print0(ucase ? leftUnion.getOperator().name : leftUnion.getOperator().name_lcase); 2999 println(); 3000 leftRigt.accept(this); 3001 } else { 3002 visit(leftUnion); 3003 } 3004 } else { 3005 left.accept(this); 3006 } 3007 break; 3008 } 3009 } 3010 3011 if (right is null) { 3012 return false; 3013 } 3014 3015 println(); 3016 print0(ucase ? operator.name : operator.name_lcase); 3017 println(); 3018 3019 bool needParen = false; 3020 if (orderBy !is null 3021 && (!right.isBracket()) && cast(SQLSelectQueryBlock)right !is null) { 3022 SQLSelectQueryBlock rightQuery = cast(SQLSelectQueryBlock) right; 3023 if (rightQuery.getOrderBy() !is null || rightQuery.getLimit() !is null) { 3024 needParen = true; 3025 } 3026 } 3027 3028 if (needParen) { 3029 print('('); 3030 right.accept(this); 3031 print(')'); 3032 } else { 3033 right.accept(this); 3034 } 3035 3036 if (orderBy !is null) { 3037 println(); 3038 orderBy.accept(this); 3039 } 3040 3041 SQLLimit limit = x.getLimit(); 3042 if (limit !is null) { 3043 println(); 3044 limit.accept(this); 3045 } 3046 3047 if (bracket) { 3048 print(')'); 3049 } 3050 3051 return false; 3052 } 3053 3054 override 3055 bool visit(SQLUnaryExpr x) { 3056 print0(x.getOperator().name); 3057 3058 SQLExpr expr = x.getExpr(); 3059 3060 switch (x.getOperator().name) { 3061 case SQLUnaryOperator.BINARY.name: 3062 case SQLUnaryOperator.Prior.name: 3063 case SQLUnaryOperator.ConnectByRoot.name: 3064 print(' '); 3065 expr.accept(this); 3066 return false; 3067 default: 3068 break; 3069 } 3070 3071 if (cast(SQLBinaryOpExpr)expr !is null) { 3072 print('('); 3073 expr.accept(this); 3074 print(')'); 3075 } else if (cast(SQLUnaryExpr)expr !is null) { 3076 print('('); 3077 expr.accept(this); 3078 print(')'); 3079 } else { 3080 expr.accept(this); 3081 } 3082 return false; 3083 } 3084 3085 override 3086 bool visit(SQLHexExpr x) { 3087 if (this.parameterized) { 3088 print('?'); 3089 incrementReplaceCunt(); 3090 3091 if(this.parameters !is null){ 3092 ExportParameterVisitorUtils.exportParameter(this.parameters, x); 3093 } 3094 return false; 3095 } 3096 3097 print0("0x"); 3098 print0(x.getHex()); 3099 3100 String charset = cast(String) x.getAttribute("USING"); 3101 if (charset !is null) { 3102 print0(ucase ? " USING " : " using "); 3103 print0(charset.value()); 3104 } 3105 3106 return false; 3107 } 3108 3109 3110 override 3111 bool visit(SQLBlobExpr x) { 3112 if (this.parameterized) { 3113 print('?'); 3114 incrementReplaceCunt(); 3115 3116 if(this.parameters !is null){ 3117 ExportParameterVisitorUtils.exportParameter(this.parameters, x); 3118 } 3119 return false; 3120 } 3121 3122 print0("0x"); 3123 print0(x.getHex()); 3124 3125 String charset = cast(String) x.getAttribute("USING"); 3126 if (charset !is null) { 3127 print0(ucase ? " USING " : " using "); 3128 print0(charset.value()); 3129 } 3130 3131 return false; 3132 } 3133 3134 override 3135 bool visit(SQLSetStatement x) { 3136 bool printSet = x.getAttribute("parser.set") == Boolean.TRUE || !DBType.ORACLE.opEquals(dbType); 3137 if (printSet) { 3138 print0(ucase ? "SET " : "set "); 3139 } 3140 SQLSetStatement.Option option = x.getOption(); 3141 if (option.name.length != 0) { 3142 print(option.name()); 3143 print(' '); 3144 } 3145 3146 printAndAccept!SQLAssignItem((x.getItems()), ", "); 3147 3148 if (x.getHints() !is null && x.getHints().size() > 0) { 3149 print(' '); 3150 printAndAccept!SQLCommentHint((x.getHints()), " "); 3151 } 3152 3153 return false; 3154 } 3155 3156 override 3157 bool visit(SQLAssignItem x) { 3158 x.getTarget().accept(this); 3159 print0(" = "); 3160 x.getValue().accept(this); 3161 return false; 3162 } 3163 3164 override 3165 bool visit(SQLCallStatement x) { 3166 if (x.isBrace()) { 3167 print('{'); 3168 } 3169 if (x.getOutParameter() !is null) { 3170 x.getOutParameter().accept(this); 3171 print0(" = "); 3172 } 3173 3174 print0(ucase ? "CALL " : "call "); 3175 x.getProcedureName().accept(this); 3176 print('('); 3177 3178 printAndAccept!SQLExpr((x.getParameters()), ", "); 3179 print(')'); 3180 if (x.isBrace()) { 3181 print('}'); 3182 } 3183 return false; 3184 } 3185 3186 override 3187 bool visit(SQLJoinTableSource x) { 3188 SQLTableSource left = x.getLeft(); 3189 3190 if (cast(SQLJoinTableSource)left !is null 3191 && (cast(SQLJoinTableSource) left).getJoinType() == SQLJoinTableSource.JoinType.COMMA 3192 && x.getJoinType() != SQLJoinTableSource.JoinType.COMMA 3193 && !DBType.POSTGRESQL.opEquals(dbType)) { 3194 print('('); 3195 printTableSource(left); 3196 print(')'); 3197 } else { 3198 printTableSource(left); 3199 } 3200 this.indentCount++; 3201 3202 if (x.getJoinType() == SQLJoinTableSource.JoinType.COMMA) { 3203 print(','); 3204 } else { 3205 println(); 3206 3207 if (x.isNatural()) { 3208 print0(ucase ? "NATURAL " : "natural "); 3209 } 3210 3211 printJoinType(x.getJoinType()); 3212 } 3213 print(' '); 3214 3215 SQLTableSource right = x.getRight(); 3216 if (cast(SQLJoinTableSource)right !is null) { 3217 print('('); 3218 printTableSource(right); 3219 print(')'); 3220 } else { 3221 printTableSource(right); 3222 } 3223 3224 SQLExpr condition = x.getCondition(); 3225 if (condition !is null) { 3226 bool newLine = false; 3227 3228 if(cast(SQLSubqueryTableSource)right !is null) { 3229 newLine = true; 3230 } else if (cast(SQLBinaryOpExpr)condition !is null) { 3231 SQLBinaryOperator op = (cast(SQLBinaryOpExpr) condition).getOperator(); 3232 if (op == SQLBinaryOperator.BooleanAnd || op == SQLBinaryOperator.BooleanOr) { 3233 newLine = true; 3234 } 3235 } else if (cast(SQLBinaryOpExprGroup)condition !is null) { 3236 newLine = true; 3237 } 3238 if (newLine) { 3239 println(); 3240 } else { 3241 print(' '); 3242 } 3243 this.indentCount++; 3244 print0(ucase ? "ON " : "on "); 3245 printExpr(condition); 3246 this.indentCount--; 3247 } 3248 3249 if (x.getUsing().size() > 0) { 3250 print0(ucase ? " USING (" : " using ("); 3251 printAndAccept!SQLExpr((x.getUsing()), ", "); 3252 print(')'); 3253 } 3254 3255 if (x.getAlias() !is null) { 3256 print0(ucase ? " AS " : " as "); 3257 print0(x.getAlias()); 3258 } 3259 3260 this.indentCount--; 3261 3262 return false; 3263 } 3264 3265 protected void printJoinType(SQLJoinTableSource.JoinType joinType) { 3266 print0(ucase ? joinType.name : joinType.name_lcase); 3267 } 3268 3269 // static { 3270 // for (int len = 0; len < variantValuesCache.length; ++len) { 3271 // StringBuilder buf = new StringBuilder(); 3272 // buf.append('('); 3273 // for (int i = 0; i < len; ++i) { 3274 // if (i != 0) { 3275 // if (i % 5 == 0) { 3276 // buf.append("\n\t\t"); 3277 // } 3278 // buf.append(", "); 3279 // } 3280 // buf.append('?'); 3281 // } 3282 // buf.append(')'); 3283 // variantValuesCache[len] = buf.toString(); 3284 // } 3285 // } 3286 3287 override 3288 bool visit(ValuesClause x) { 3289 if ((!this.parameterized) 3290 && isEnabled(VisitorFeature.OutputUseInsertValueClauseOriginalString) 3291 && x.getOriginalString() !is null) { 3292 print0(x.getOriginalString()); 3293 return false; 3294 } 3295 3296 int xReplaceCount = x.getReplaceCount(); 3297 List!SQLExpr values = x.getValues(); 3298 3299 this.replaceCount += xReplaceCount; 3300 3301 if (xReplaceCount == values.size() && xReplaceCount < variantValuesCache.length) { 3302 string variantValues = variantValuesCache[xReplaceCount]; 3303 print0(variantValues); 3304 return false; 3305 } 3306 3307 print('('); 3308 this.indentCount++; 3309 3310 3311 for (int i = 0, size = values.size(); i < size; ++i) { 3312 if (i != 0) { 3313 if (i % 5 == 0) { 3314 println(); 3315 } 3316 print0(", "); 3317 } 3318 3319 SQLExpr expr = values.get(i); 3320 if (cast(SQLIntegerExpr)expr !is null) { 3321 printInteger(cast(SQLIntegerExpr) expr, parameterized); 3322 } else if (cast(SQLCharExpr)expr !is null) { 3323 visit(cast(SQLCharExpr) expr); 3324 } else if (cast(SQLBooleanExpr)expr !is null) { 3325 visit(cast(SQLBooleanExpr) expr); 3326 } else if (cast(SQLNumberExpr)expr !is null) { 3327 visit(cast(SQLNumberExpr) expr); 3328 } else if (cast(SQLNullExpr)expr !is null) { 3329 visit(cast(SQLNullExpr) expr); 3330 } else if (cast(SQLVariantRefExpr)expr !is null) { 3331 visit(cast(SQLVariantRefExpr) expr); 3332 } else if (cast(SQLNCharExpr)expr !is null) { 3333 visit(cast(SQLNCharExpr) expr); 3334 } else { 3335 expr.accept(this); 3336 } 3337 } 3338 3339 this.indentCount--; 3340 print(')'); 3341 return false; 3342 } 3343 3344 override 3345 bool visit(SQLSomeExpr x) { 3346 print0(ucase ? "SOME (" : "some ("); 3347 this.indentCount++; 3348 println(); 3349 x.getSubQuery().accept(this); 3350 this.indentCount--; 3351 println(); 3352 print(')'); 3353 return false; 3354 } 3355 3356 override 3357 bool visit(SQLAnyExpr x) { 3358 print0(ucase ? "ANY (" : "any ("); 3359 this.indentCount++; 3360 println(); 3361 x.getSubQuery().accept(this); 3362 this.indentCount--; 3363 println(); 3364 print(')'); 3365 return false; 3366 } 3367 3368 override 3369 bool visit(SQLAllExpr x) { 3370 print0(ucase ? "ALL (" : "all ("); 3371 this.indentCount++; 3372 println(); 3373 x.getSubQuery().accept(this); 3374 this.indentCount--; 3375 println(); 3376 print(')'); 3377 return false; 3378 } 3379 3380 override 3381 bool visit(SQLInSubQueryExpr x) { 3382 x.getExpr().accept(this); 3383 if (x.isNot()) { 3384 print0(ucase ? " NOT IN (" : " not in ("); 3385 } else { 3386 print0(ucase ? " IN (" : " in ("); 3387 } 3388 3389 this.indentCount++; 3390 println(); 3391 x.getSubQuery().accept(this); 3392 this.indentCount--; 3393 println(); 3394 print(')'); 3395 3396 return false; 3397 } 3398 3399 override 3400 bool visit(SQLListExpr x) { 3401 print('('); 3402 printAndAccept!SQLExpr((x.getItems()), ", "); 3403 print(')'); 3404 3405 return false; 3406 } 3407 3408 override 3409 bool visit(SQLSubqueryTableSource x) { 3410 print('('); 3411 this.indentCount++; 3412 println(); 3413 this.visit(x.getSelect()); 3414 this.indentCount--; 3415 println(); 3416 print(')'); 3417 3418 if (x.getAlias() !is null) { 3419 print(' '); 3420 print0(x.getAlias()); 3421 } 3422 3423 return false; 3424 } 3425 3426 override 3427 bool visit(SQLTruncateStatement x) { 3428 print0(ucase ? "TRUNCATE TABLE " : "truncate table "); 3429 printAndAccept!SQLExprTableSource((x.getTableSources()), ", "); 3430 3431 if (x.isDropStorage()) { 3432 print0(ucase ? " DROP STORAGE" : " drop storage"); 3433 } 3434 3435 if (x.isReuseStorage()) { 3436 print0(ucase ? " REUSE STORAGE" : " reuse storage"); 3437 } 3438 3439 if (x.isIgnoreDeleteTriggers()) { 3440 print0(ucase ? " IGNORE DELETE TRIGGERS" : " ignore delete triggers"); 3441 } 3442 3443 if (x.isRestrictWhenDeleteTriggers()) { 3444 print0(ucase ? " RESTRICT WHEN DELETE TRIGGERS" : " restrict when delete triggers"); 3445 } 3446 3447 if (x.isContinueIdentity()) { 3448 print0(ucase ? " CONTINUE IDENTITY" : " continue identity"); 3449 } 3450 3451 if (x.isImmediate()) { 3452 print0(ucase ? " IMMEDIATE" : " immediate"); 3453 } 3454 3455 return false; 3456 } 3457 3458 override 3459 bool visit(SQLDefaultExpr x) { 3460 print0(ucase ? "DEFAULT" : "default"); 3461 return false; 3462 } 3463 3464 override 3465 void endVisit(SQLCommentStatement x) { 3466 3467 } 3468 3469 override 3470 bool visit(SQLCommentStatement x) { 3471 print0(ucase ? "COMMENT ON " : "comment on "); 3472 if (x.getType().name.length != 0) { 3473 print0(x.getType().name); 3474 print(' '); 3475 } 3476 x.getOn().accept(this); 3477 3478 print0(ucase ? " IS " : " is "); 3479 x.getComment().accept(this); 3480 3481 return false; 3482 } 3483 3484 override 3485 bool visit(SQLUseStatement x) { 3486 print0(ucase ? "USE " : "use "); 3487 x.getDatabase().accept(this); 3488 return false; 3489 } 3490 3491 protected bool isOdps() { 3492 return DBType.ODPS.opEquals(dbType); 3493 } 3494 3495 override 3496 bool visit(SQLAlterTableAddColumn x) { 3497 bool odps = isOdps(); 3498 if (odps) { 3499 print0(ucase ? "ADD COLUMNS (" : "add columns ("); 3500 } else { 3501 print0(ucase ? "ADD (" : "add ("); 3502 } 3503 printAndAccept!SQLColumnDefinition((x.getColumns()), ", "); 3504 print(')'); 3505 return false; 3506 } 3507 3508 override 3509 bool visit(SQLAlterTableDropColumnItem x) { 3510 print0(ucase ? "DROP COLUMN " : "drop column "); 3511 this.printAndAccept!SQLName((x.getColumns()), ", "); 3512 3513 if (x.isCascade()) { 3514 print0(ucase ? " CASCADE" : " cascade"); 3515 } 3516 return false; 3517 } 3518 3519 override 3520 void endVisit(SQLAlterTableAddColumn x) { 3521 3522 } 3523 3524 override 3525 bool visit(SQLDropIndexStatement x) { 3526 print0(ucase ? "DROP INDEX " : "drop index "); 3527 x.getIndexName().accept(this); 3528 3529 SQLExprTableSource table = x.getTableName(); 3530 if (table !is null) { 3531 print0(ucase ? " ON " : " on "); 3532 table.accept(this); 3533 } 3534 3535 SQLExpr algorithm = x.getAlgorithm(); 3536 if (algorithm !is null) { 3537 print0(ucase ? " ALGORITHM " : " algorithm "); 3538 algorithm.accept(this); 3539 } 3540 3541 SQLExpr lockOption = x.getLockOption(); 3542 if (lockOption !is null) { 3543 print0(ucase ? " LOCK " : " lock "); 3544 lockOption.accept(this); 3545 } 3546 3547 return false; 3548 } 3549 3550 override 3551 bool visit(SQLDropLogFileGroupStatement x) { 3552 print0(ucase ? "DROP LOGFILE GROUP " : "drop logfile group "); 3553 x.getName().accept(this); 3554 3555 return false; 3556 } 3557 3558 override 3559 bool visit(SQLDropServerStatement x) { 3560 print0(ucase ? "DROP SERVER " : "drop server "); 3561 if (x.isIfExists()) { 3562 print0(ucase ? "IF EXISTS " : "if exists "); 3563 } 3564 x.getName().accept(this); 3565 3566 return false; 3567 } 3568 3569 override 3570 bool visit(SQLDropTypeStatement x) { 3571 print0(ucase ? "DROP TYPE " : "drop type "); 3572 if (x.isIfExists()) { 3573 print0(ucase ? "IF EXISTS " : "if exists "); 3574 } 3575 x.getName().accept(this); 3576 3577 return false; 3578 } 3579 3580 override 3581 bool visit(SQLDropSynonymStatement x) { 3582 if (x.isPublic()) { 3583 print0(ucase ? "DROP PUBLIC SYNONYM " : "drop synonym "); 3584 } else { 3585 print0(ucase ? "DROP SYNONYM " : "drop synonym "); 3586 } 3587 3588 if (x.isIfExists()) { 3589 print0(ucase ? "IF EXISTS " : "if exists "); 3590 } 3591 3592 x.getName().accept(this); 3593 3594 if (x.isForce()) { 3595 print0(ucase ? " FORCE" : " force"); 3596 } 3597 3598 return false; 3599 } 3600 3601 override 3602 bool visit(SQLSavePointStatement x) { 3603 print0(ucase ? "SAVEPOINT" : "savepoint"); 3604 if (x.getName() !is null) { 3605 print(' '); 3606 x.getName().accept(this); 3607 } 3608 return false; 3609 } 3610 3611 override 3612 bool visit(SQLReleaseSavePointStatement x) { 3613 print0(ucase ? "RELEASE SAVEPOINT " : "release savepoint "); 3614 x.getName().accept(this); 3615 return false; 3616 } 3617 3618 override 3619 bool visit(SQLRollbackStatement x) { 3620 print0(ucase ? "ROLLBACK" : "rollback"); 3621 if (x.getTo() !is null) { 3622 print0(ucase ? " TO " : " to "); 3623 x.getTo().accept(this); 3624 } 3625 return false; 3626 } 3627 3628 override bool visit(SQLCommentHint x) { 3629 if (x.hasBeforeComment()) { 3630 printlnComment(x.getBeforeCommentsDirect()); 3631 print0(" "); 3632 } 3633 3634 print0("/*"); 3635 print0(x.getText()); 3636 print0("*/"); 3637 return false; 3638 } 3639 3640 override 3641 bool visit(SQLCreateDatabaseStatement x) { 3642 print0(ucase ? "CREATE DATABASE " : "create database "); 3643 if (x.isIfNotExists()) { 3644 print0(ucase ? "IF NOT EXISTS " : "if not exists "); 3645 } 3646 x.getName().accept(this); 3647 3648 if (x.getCharacterSet() !is null) { 3649 print0(ucase ? " CHARACTER SET " : " character set "); 3650 print0(x.getCharacterSet()); 3651 } 3652 3653 if (x.getCollate() !is null) { 3654 print0(ucase ? " COLLATE " : " collate "); 3655 print0(x.getCollate()); 3656 } 3657 3658 return false; 3659 } 3660 3661 override 3662 bool visit(SQLAlterViewStatement x) { 3663 print0(ucase ? "ALTER " : "atler "); 3664 3665 this.indentCount++; 3666 string algorithm = x.getAlgorithm(); 3667 if (algorithm !is null && algorithm.length > 0) { 3668 print0(ucase ? "ALGORITHM = " : "algorithm = "); 3669 print0(algorithm); 3670 println(); 3671 } 3672 3673 SQLName definer = x.getDefiner(); 3674 if (definer !is null) { 3675 print0(ucase ? "DEFINER = " : "definer = "); 3676 definer.accept(this); 3677 println(); 3678 } 3679 3680 string sqlSecurity = x.getSqlSecurity(); 3681 if (sqlSecurity !is null && sqlSecurity.length > 0) { 3682 print0(ucase ? "SQL SECURITY = " : "sql security = "); 3683 print0(sqlSecurity); 3684 println(); 3685 } 3686 3687 this.indentCount--; 3688 3689 print0(ucase ? "VIEW " : "view "); 3690 3691 if (x.isIfNotExists()) { 3692 print0(ucase ? "IF NOT EXISTS " : "if not exists "); 3693 } 3694 3695 x.getTableSource().accept(this); 3696 3697 if (x.getColumns().size() > 0) { 3698 print0(" ("); 3699 this.indentCount++; 3700 println(); 3701 for (int i = 0; i < x.getColumns().size(); ++i) { 3702 if (i != 0) { 3703 print0(", "); 3704 println(); 3705 } 3706 x.getColumns().get(i).accept(this); 3707 } 3708 this.indentCount--; 3709 println(); 3710 print(')'); 3711 } 3712 3713 if (x.getComment() !is null) { 3714 println(); 3715 print0(ucase ? "COMMENT " : "comment "); 3716 x.getComment().accept(this); 3717 } 3718 3719 println(); 3720 print0(ucase ? "AS" : "as"); 3721 println(); 3722 3723 x.getSubQuery().accept(this); 3724 3725 if (x.isWithCheckOption()) { 3726 println(); 3727 print0(ucase ? "WITH CHECK OPTION" : "with check option"); 3728 } 3729 3730 return false; 3731 } 3732 3733 override 3734 bool visit(SQLCreateViewStatement x) { 3735 print0(ucase ? "CREATE " : "create "); 3736 if (x.isOrReplace()) { 3737 print0(ucase ? "OR REPLACE " : "or replace "); 3738 } 3739 3740 this.indentCount++; 3741 string algorithm = x.getAlgorithm(); 3742 if (algorithm !is null && algorithm.length > 0) { 3743 print0(ucase ? "ALGORITHM = " : "algorithm = "); 3744 print0(algorithm); 3745 println(); 3746 } 3747 3748 SQLName definer = x.getDefiner(); 3749 if (definer !is null) { 3750 print0(ucase ? "DEFINER = " : "definer = "); 3751 definer.accept(this); 3752 println(); 3753 } 3754 3755 string sqlSecurity = x.getSqlSecurity(); 3756 if (sqlSecurity !is null && sqlSecurity.length > 0) { 3757 print0(ucase ? "SQL SECURITY = " : "sql security = "); 3758 print0(sqlSecurity); 3759 println(); 3760 } 3761 3762 this.indentCount--; 3763 3764 print0(ucase ? "VIEW " : "view "); 3765 3766 if (x.isIfNotExists()) { 3767 print0(ucase ? "IF NOT EXISTS " : "if not exists "); 3768 } 3769 3770 x.getTableSource().accept(this); 3771 3772 if (x.getColumns().size() > 0) { 3773 print0(" ("); 3774 this.indentCount++; 3775 println(); 3776 for (int i = 0; i < x.getColumns().size(); ++i) { 3777 if (i != 0) { 3778 print0(", "); 3779 println(); 3780 } 3781 x.getColumns().get(i).accept(this); 3782 } 3783 this.indentCount--; 3784 println(); 3785 print(')'); 3786 } 3787 3788 if (x.getComment() !is null) { 3789 println(); 3790 print0(ucase ? "COMMENT " : "comment "); 3791 x.getComment().accept(this); 3792 } 3793 3794 println(); 3795 print0(ucase ? "AS" : "as"); 3796 println(); 3797 3798 x.getSubQuery().accept(this); 3799 3800 if (x.isWithCheckOption()) { 3801 println(); 3802 print0(ucase ? "WITH CHECK OPTION" : "with check option"); 3803 } 3804 3805 return false; 3806 } 3807 3808 override bool visit(SQLCreateViewStatement.Column x) { 3809 x.getExpr().accept(this); 3810 3811 if (x.getComment() !is null) { 3812 print0(ucase ? " COMMENT " : " comment "); 3813 x.getComment().accept(this); 3814 } 3815 3816 return false; 3817 } 3818 3819 override 3820 bool visit(SQLAlterTableDropIndex x) { 3821 print0(ucase ? "DROP INDEX " : "drop index "); 3822 x.getIndexName().accept(this); 3823 return false; 3824 } 3825 3826 override 3827 bool visit(SQLOver x) { 3828 print0(ucase ? "OVER (" : "over ("); 3829 if (x.getPartitionBy().size() > 0) { 3830 print0(ucase ? "PARTITION BY " : "partition by "); 3831 printAndAccept!SQLExpr((x.getPartitionBy()), ", "); 3832 print(' '); 3833 } 3834 3835 if (x.getOrderBy() !is null) { 3836 x.getOrderBy().accept(this); 3837 } 3838 3839 if (x.getOf() !is null) { 3840 print0(ucase ? " OF " : " of "); 3841 x.getOf().accept(this); 3842 } 3843 3844 if (x.getWindowing() !is null) { 3845 if (SQLOver.WindowingType.ROWS == (x.getWindowingType())) { 3846 print0(ucase ? " ROWS " : " rows "); 3847 } else if (SQLOver.WindowingType.RANGE == (x.getWindowingType())) { 3848 print0(ucase ? " RANGE " : " range "); 3849 } 3850 3851 printWindowingExpr(x.getWindowing()); 3852 3853 if (x.isWindowingPreceding()) { 3854 print0(ucase ? " PRECEDING" : " preceding"); 3855 } else if (x.isWindowingFollowing()) { 3856 print0(ucase ? " FOLLOWING" : " following"); 3857 } 3858 } 3859 3860 if (x.getWindowingBetweenBegin() !is null) { 3861 if (SQLOver.WindowingType.ROWS == (x.getWindowingType())) { 3862 print0(ucase ? " ROWS BETWEEN " : " rows between "); 3863 } else if (SQLOver.WindowingType.RANGE == (x.getWindowingType())) { 3864 print0(ucase ? " RANGE BETWEEN " : " range between "); 3865 } 3866 3867 printWindowingExpr(x.getWindowingBetweenBegin()); 3868 3869 if (x.isWindowingBetweenBeginPreceding()) { 3870 print0(ucase ? " PRECEDING" : " preceding"); 3871 } else if (x.isWindowingBetweenBeginFollowing()) { 3872 print0(ucase ? " FOLLOWING" : " following"); 3873 } 3874 3875 print0(ucase ? " AND " : " and "); 3876 3877 printWindowingExpr(x.getWindowingBetweenEnd()); 3878 3879 if (x.isWindowingBetweenEndPreceding()) { 3880 print0(ucase ? " PRECEDING" : " preceding"); 3881 } else if (x.isWindowingBetweenEndFollowing()) { 3882 print0(ucase ? " FOLLOWING" : " following"); 3883 } 3884 } 3885 3886 print(')'); 3887 return false; 3888 } 3889 3890 void printWindowingExpr(SQLExpr expr) { 3891 if (cast(SQLIdentifierExpr)expr !is null) { 3892 string ident = (cast(SQLIdentifierExpr) expr).getName(); 3893 print0(ucase ? ident : toLower(ident)); 3894 } else { 3895 expr.accept(this); 3896 } 3897 } 3898 3899 override 3900 bool visit(SQLKeep x) { 3901 if (x.getDenseRank() == SQLKeep.DenseRank.FIRST) { 3902 print0(ucase ? "KEEP (DENSE_RANK FIRST " : "keep (dense_rank first "); 3903 } else { 3904 print0(ucase ? "KEEP (DENSE_RANK LAST " : "keep (dense_rank last "); 3905 } 3906 3907 x.getOrderBy().accept(this); 3908 print(')'); 3909 3910 return false; 3911 } 3912 3913 override 3914 bool visit(SQLColumnPrimaryKey x) { 3915 if (x.getName() !is null) { 3916 print0(ucase ? "CONSTRAINT " : "constraint "); 3917 x.getName().accept(this); 3918 print(' '); 3919 } 3920 print0(ucase ? "PRIMARY KEY" : "primary key"); 3921 return false; 3922 } 3923 3924 override 3925 bool visit(SQLColumnUniqueKey x) { 3926 if (x.getName() !is null) { 3927 print0(ucase ? "CONSTRAINT " : "constraint "); 3928 x.getName().accept(this); 3929 print(' '); 3930 } 3931 print0(ucase ? "UNIQUE" : "unique"); 3932 return false; 3933 } 3934 3935 override 3936 bool visit(SQLColumnCheck x) { 3937 if (x.getName() !is null) { 3938 print0(ucase ? "CONSTRAINT " : "constraint "); 3939 x.getName().accept(this); 3940 print(' '); 3941 } 3942 print0(ucase ? "CHECK (" : "check ("); 3943 x.getExpr().accept(this); 3944 print(')'); 3945 3946 if (x.getEnable() !is null) { 3947 if (x.getEnable().booleanValue()) { 3948 print0(ucase ? " ENABLE" : " enable"); 3949 } else { 3950 print0(ucase ? " DISABLE" : " disable"); 3951 } 3952 } 3953 return false; 3954 } 3955 3956 override 3957 bool visit(SQLWithSubqueryClause x) { 3958 print0(ucase ? "WITH " : "with "); 3959 if (x.getRecursive() == true) { 3960 print0(ucase ? "RECURSIVE " : "recursive "); 3961 } 3962 this.indentCount++; 3963 printlnAndAccept!(SQLWithSubqueryClause.Entry)((x.getEntries()), ", "); 3964 this.indentCount--; 3965 return false; 3966 } 3967 3968 override 3969 bool visit(SQLWithSubqueryClause.Entry x) { 3970 print0(x.getAlias()); 3971 3972 if (x.getColumns().size() > 0) { 3973 print0(" ("); 3974 printAndAccept!SQLName((x.getColumns()), ", "); 3975 print(')'); 3976 } 3977 print(' '); 3978 print0(ucase ? "AS " : "as "); 3979 print('('); 3980 this.indentCount++; 3981 println(); 3982 SQLSelect query = x.getSubQuery(); 3983 if (query !is null) { 3984 query.accept(this); 3985 } else { 3986 x.getReturningStatement().accept(this); 3987 } 3988 this.indentCount--; 3989 println(); 3990 print(')'); 3991 3992 return false; 3993 } 3994 3995 override 3996 bool visit(SQLAlterTableAlterColumn x) { 3997 bool odps = isOdps(); 3998 if (odps) { 3999 print0(ucase ? "CHANGE COLUMN " : "change column "); 4000 } else { 4001 print0(ucase ? "ALTER COLUMN " : "alter column "); 4002 } 4003 x.getColumn().accept(this); 4004 4005 if (x.isSetNotNull()) { // postgresql 4006 print0(ucase ? " SET NOT NULL" : " set not null"); 4007 } 4008 4009 if (x.isDropNotNull()) { // postgresql 4010 print0(ucase ? " DROP NOT NULL" : " drop not null"); 4011 } 4012 4013 if (x.getSetDefault() !is null) { // postgresql 4014 print0(ucase ? " SET DEFAULT " : " set default "); 4015 x.getSetDefault().accept(this); 4016 } 4017 4018 SQLDataType dataType = x.getDataType(); 4019 if (dataType !is null) { 4020 print0(ucase ? " SET DATA TYPE " : " set data type "); 4021 dataType.accept(this); 4022 } 4023 4024 if (x.isDropDefault()) { // postgresql 4025 print0(ucase ? " DROP DEFAULT" : " drop default"); 4026 } 4027 4028 return false; 4029 } 4030 4031 override 4032 bool visit(SQLCheck x) { 4033 if (x.getName() !is null) { 4034 print0(ucase ? "CONSTRAINT " : "constraint "); 4035 x.getName().accept(this); 4036 print(' '); 4037 } 4038 print0(ucase ? "CHECK (" : "check ("); 4039 this.indentCount++; 4040 x.getExpr().accept(this); 4041 this.indentCount--; 4042 print(')'); 4043 return false; 4044 } 4045 4046 override 4047 bool visit(SQLAlterTableDropForeignKey x) { 4048 print0(ucase ? "DROP FOREIGN KEY " : "drop foreign key "); 4049 x.getIndexName().accept(this); 4050 return false; 4051 } 4052 4053 override 4054 bool visit(SQLAlterTableDropPrimaryKey x) { 4055 print0(ucase ? "DROP PRIMARY KEY" : "drop primary key"); 4056 return false; 4057 } 4058 4059 override 4060 bool visit(SQLAlterTableDropKey x) { 4061 print0(ucase ? "DROP KEY " : "drop key "); 4062 x.getKeyName().accept(this); 4063 return false; 4064 } 4065 4066 override 4067 bool visit(SQLAlterTableEnableKeys x) { 4068 print0(ucase ? "ENABLE KEYS" : "enable keys"); 4069 return false; 4070 } 4071 4072 override 4073 bool visit(SQLAlterTableDisableKeys x) { 4074 print0(ucase ? "DISABLE KEYS" : "disable keys"); 4075 return false; 4076 } 4077 4078 override bool visit(SQLAlterTableDisableConstraint x) { 4079 print0(ucase ? "DISABLE CONSTRAINT " : "disable constraint "); 4080 x.getConstraintName().accept(this); 4081 return false; 4082 } 4083 4084 override bool visit(SQLAlterTableEnableConstraint x) { 4085 print0(ucase ? "ENABLE CONSTRAINT " : "enable constraint "); 4086 x.getConstraintName().accept(this); 4087 return false; 4088 } 4089 4090 override 4091 bool visit(SQLAlterTableDropConstraint x) { 4092 print0(ucase ? "DROP CONSTRAINT " : "drop constraint "); 4093 x.getConstraintName().accept(this); 4094 return false; 4095 } 4096 4097 override 4098 bool visit(SQLAlterTableStatement x) { 4099 print0(ucase ? "ALTER TABLE " : "alter table "); 4100 printTableSourceExpr(x.getName()); 4101 this.indentCount++; 4102 for (int i = 0; i < x.getItems().size(); ++i) { 4103 SQLAlterTableItem item = x.getItems().get(i); 4104 if (i != 0) { 4105 print(','); 4106 } 4107 println(); 4108 item.accept(this); 4109 } 4110 this.indentCount--; 4111 4112 if (x.isMergeSmallFiles()) { 4113 print0(ucase ? " MERGE SMALLFILES" : " merge smallfiles"); 4114 } 4115 return false; 4116 } 4117 4118 override 4119 bool visit(SQLExprHint x) { 4120 x.getExpr().accept(this); 4121 return false; 4122 } 4123 4124 override 4125 bool visit(SQLCreateIndexStatement x) { 4126 print0(ucase ? "CREATE " : "create "); 4127 if (x.getType() !is null) { 4128 print0(x.getType()); 4129 print(' '); 4130 } 4131 4132 print0(ucase ? "INDEX " : "index "); 4133 4134 x.getName().accept(this); 4135 print0(ucase ? " ON " : " on "); 4136 x.getTable().accept(this); 4137 print0(" ("); 4138 printAndAccept!SQLSelectOrderByItem((x.getItems()), ", "); 4139 print(')'); 4140 4141 // for mysql 4142 if (x.getUsing() !is null) { 4143 print0(ucase ? " USING " : " using "); 4144 // ; 4145 print0(x.getUsing()); 4146 } 4147 4148 SQLExpr comment = x.getComment(); 4149 if (comment !is null) { 4150 print0(ucase ? " COMMENT " : " comment "); 4151 comment.accept(this); 4152 } 4153 4154 return false; 4155 } 4156 4157 override 4158 bool visit(SQLUnique x) { 4159 SQLName name = x.getName(); 4160 if (name !is null) { 4161 print0(ucase ? "CONSTRAINT " : "constraint "); 4162 name.accept(this); 4163 print(' '); 4164 } 4165 4166 print0(ucase ? "UNIQUE (" : "unique ("); 4167 printAndAccept!SQLSelectOrderByItem((x.getColumns()), ", "); 4168 print(')'); 4169 return false; 4170 } 4171 4172 override 4173 bool visit(SQLPrimaryKeyImpl x) { 4174 SQLName name = x.getName(); 4175 if (name !is null) { 4176 print0(ucase ? "CONSTRAINT " : "constraint "); 4177 name.accept(this); 4178 print(' '); 4179 } 4180 4181 print0(ucase ? "PRIMARY KEY " : "primary key "); 4182 4183 if (x.isClustered()) { 4184 print0(ucase ? "CLUSTERED " : "clustered "); 4185 } 4186 4187 print('('); 4188 printAndAccept!SQLSelectOrderByItem((x.getColumns()), ", "); 4189 print(')'); 4190 4191 return false; 4192 } 4193 4194 override 4195 bool visit(SQLAlterTableRenameColumn x) { 4196 print0(ucase ? "RENAME COLUMN " : "rename column "); 4197 x.getColumn().accept(this); 4198 print0(ucase ? " TO " : " to "); 4199 x.getTo().accept(this); 4200 return false; 4201 } 4202 4203 override 4204 bool visit(SQLColumnReference x) { 4205 SQLName name = x.getName(); 4206 if (name !is null) { 4207 print0(ucase ? "CONSTRAINT " : "constraint "); 4208 name.accept(this); 4209 print(' '); 4210 } 4211 4212 print0(ucase ? "REFERENCES " : "references "); 4213 x.getTable().accept(this); 4214 print0(" ("); 4215 printAndAccept!SQLName((x.getColumns()), ", "); 4216 print(')'); 4217 4218 SQLForeignKeyImpl.Match match = x.getReferenceMatch(); 4219 if (match.name.length != 0) { 4220 print0(ucase ? " MATCH " : " match "); 4221 print0(ucase ? match.name : match.name_lcase); 4222 } 4223 4224 if (x.getOnDelete().name.length != 0) { 4225 print0(ucase ? " ON DELETE " : " on delete "); 4226 print0(ucase ? x.getOnDelete().name : x.getOnDelete().name_lcase); 4227 } 4228 4229 if (x.getOnUpdate().name.length != 0) { 4230 print0(ucase ? " ON UPDATE " : " on update "); 4231 print0(ucase ? x.getOnUpdate().name : x.getOnUpdate().name_lcase); 4232 } 4233 4234 return false; 4235 } 4236 4237 override 4238 bool visit(SQLForeignKeyImpl x) { 4239 if (x.getName() !is null) { 4240 print0(ucase ? "CONSTRAINT " : "constraint "); 4241 x.getName().accept(this); 4242 print(' '); 4243 } 4244 4245 print0(ucase ? "FOREIGN KEY (" : "foreign key ("); 4246 printAndAccept!SQLName((x.getReferencingColumns()), ", "); 4247 print(')'); 4248 4249 this.indentCount++; 4250 println(); 4251 print0(ucase ? "REFERENCES " : "references "); 4252 x.getReferencedTableName().accept(this); 4253 4254 if (x.getReferencedColumns().size() > 0) { 4255 print0(" ("); 4256 printAndAccept!SQLName((x.getReferencedColumns()), ", "); 4257 print(')'); 4258 } 4259 4260 if (x.isOnDeleteCascade()) { 4261 println(); 4262 print0(ucase ? "ON DELETE CASCADE" : "on delete cascade"); 4263 } else if (x.isOnDeleteSetNull()) { 4264 print0(ucase ? "ON DELETE SET NULL" : "on delete set null"); 4265 } 4266 this.indentCount--; 4267 return false; 4268 } 4269 4270 override 4271 bool visit(SQLDropSequenceStatement x) { 4272 print0(ucase ? "DROP SEQUENCE " : "drop sequence "); 4273 if (x.isIfExists()) { 4274 print0(ucase ? "IF EXISTS " : "if exists "); 4275 } 4276 x.getName().accept(this); 4277 return false; 4278 } 4279 4280 override 4281 void endVisit(SQLDropSequenceStatement x) { 4282 4283 } 4284 4285 override 4286 bool visit(SQLDropTriggerStatement x) { 4287 print0(ucase ? "DROP TRIGGER " : "drop trigger "); 4288 if (x.isIfExists()) { 4289 print0(ucase ? "IF EXISTS " : "if exists "); 4290 } 4291 4292 x.getName().accept(this); 4293 return false; 4294 } 4295 4296 override 4297 void endVisit(SQLDropUserStatement x) { 4298 4299 } 4300 4301 override 4302 bool visit(SQLDropUserStatement x) { 4303 print0(ucase ? "DROP USER " : "drop user "); 4304 printAndAccept!SQLExpr((x.getUsers()), ", "); 4305 return false; 4306 } 4307 4308 override 4309 bool visit(SQLExplainStatement x) { 4310 print0(ucase ? "EXPLAIN" : "explain"); 4311 if (x.getHints() !is null && x.getHints().size() > 0) { 4312 print(' '); 4313 printAndAccept!SQLCommentHint((x.getHints()), " "); 4314 } 4315 4316 if (x.getType() !is null) { 4317 print(' '); 4318 print0(x.getType()); 4319 } 4320 println(); 4321 x.getStatement().accept(this); 4322 return false; 4323 } 4324 4325 protected void printGrantPrivileges(SQLGrantStatement x) { 4326 4327 } 4328 4329 override 4330 bool visit(SQLGrantStatement x) { 4331 print0(ucase ? "GRANT " : "grant "); 4332 printAndAccept!SQLExpr((x.getPrivileges()), ", "); 4333 4334 printGrantOn(x); 4335 4336 if (x.getTo() !is null) { 4337 print0(ucase ? " TO " : " to "); 4338 x.getTo().accept(this); 4339 } 4340 4341 bool _with = false; 4342 if (x.getMaxQueriesPerHour() !is null) { 4343 if (!_with) { 4344 print0(ucase ? " WITH" : " with"); 4345 _with = true; 4346 } 4347 print0(ucase ? " MAX_QUERIES_PER_HOUR " : " max_queries_per_hour "); 4348 x.getMaxQueriesPerHour().accept(this); 4349 } 4350 4351 if (x.getMaxUpdatesPerHour() !is null) { 4352 if (!_with) { 4353 print0(ucase ? " WITH" : " with"); 4354 _with = true; 4355 } 4356 print0(ucase ? " MAX_UPDATES_PER_HOUR " : " max_updates_per_hour "); 4357 x.getMaxUpdatesPerHour().accept(this); 4358 } 4359 4360 if (x.getMaxConnectionsPerHour() !is null) { 4361 if (!_with) { 4362 print0(ucase ? " WITH" : " with"); 4363 _with = true; 4364 } 4365 print0(ucase ? " MAX_CONNECTIONS_PER_HOUR " : " max_connections_per_hour "); 4366 x.getMaxConnectionsPerHour().accept(this); 4367 } 4368 4369 if (x.getMaxUserConnections() !is null) { 4370 if (!_with) { 4371 print0(ucase ? " WITH" : " with"); 4372 _with = true; 4373 } 4374 print0(ucase ? " MAX_USER_CONNECTIONS " : " max_user_connections "); 4375 x.getMaxUserConnections().accept(this); 4376 } 4377 4378 if (x.isAdminOption()) { 4379 if (!_with) { 4380 print0(ucase ? " WITH" : " with"); 4381 _with = true; 4382 } 4383 print0(ucase ? " ADMIN OPTION" : " admin option"); 4384 } 4385 4386 if (x.getIdentifiedBy() !is null) { 4387 print0(ucase ? " IDENTIFIED BY " : " identified by "); 4388 x.getIdentifiedBy().accept(this); 4389 } 4390 4391 return false; 4392 } 4393 4394 protected void printGrantOn(SQLGrantStatement x) { 4395 if (x.getOn() !is null) { 4396 print0(ucase ? " ON " : " on "); 4397 4398 SQLObjectType objectType = x.getObjectType(); 4399 if (objectType.name.length != 0) { 4400 print0(ucase ? objectType.name : objectType.name_lcase); 4401 print(' '); 4402 } 4403 4404 x.getOn().accept(this); 4405 } 4406 } 4407 4408 override 4409 bool visit(SQLRevokeStatement x) { 4410 print0(ucase ? "REVOKE " : "revoke "); 4411 printAndAccept!SQLExpr((x.getPrivileges()), ", "); 4412 4413 if (x.getOn() !is null) { 4414 print0(ucase ? " ON " : " on "); 4415 4416 if (x.getObjectType().name.length != 0) { 4417 print0(x.getObjectType().name); 4418 print(' '); 4419 } 4420 4421 x.getOn().accept(this); 4422 } 4423 4424 if (x.getFrom() !is null) { 4425 print0(ucase ? " FROM " : " from "); 4426 x.getFrom().accept(this); 4427 } 4428 4429 return false; 4430 } 4431 4432 override 4433 bool visit(SQLDropDatabaseStatement x) { 4434 print0(ucase ? "DROP DATABASE " : "drop databasE "); 4435 4436 if (x.isIfExists()) { 4437 print0(ucase ? "IF EXISTS " : "if exists "); 4438 } 4439 4440 x.getDatabase().accept(this); 4441 4442 return false; 4443 } 4444 4445 override 4446 bool visit(SQLDropFunctionStatement x) { 4447 print0(ucase ? "DROP FUNCTION " : "drop function "); 4448 4449 if (x.isIfExists()) { 4450 print0(ucase ? "IF EXISTS " : "if exists "); 4451 } 4452 4453 x.getName().accept(this); 4454 4455 return false; 4456 } 4457 4458 override 4459 bool visit(SQLDropTableSpaceStatement x) { 4460 print0(ucase ? "DROP TABLESPACE " : "drop tablespace "); 4461 4462 if (x.isIfExists()) { 4463 print0(ucase ? "IF EXISTS " : "if exists "); 4464 } 4465 4466 x.getName().accept(this); 4467 4468 SQLExpr engine = x.getEngine(); 4469 if (engine !is null) { 4470 print0(ucase ? " ENGINE " : " engine "); 4471 engine.accept(this); 4472 } 4473 4474 return false; 4475 } 4476 4477 override 4478 bool visit(SQLDropProcedureStatement x) { 4479 print0(ucase ? "DROP PROCEDURE " : "drop procedure "); 4480 4481 if (x.isIfExists()) { 4482 print0(ucase ? "IF EXISTS " : "if exists "); 4483 } 4484 4485 x.getName().accept(this); 4486 4487 return false; 4488 } 4489 4490 override 4491 bool visit(SQLAlterTableAddIndex x) { 4492 print0(ucase ? "ADD " : "add "); 4493 string type = x.getType(); 4494 4495 bool mysql = DBType.MYSQL.opEquals(dbType); 4496 4497 if (type !is null && !mysql) { 4498 print0(type); 4499 print(' '); 4500 } 4501 4502 if (x.isUnique()) { 4503 print0(ucase ? "UNIQUE " : "unique "); 4504 } 4505 4506 if (x.isKey()) { 4507 print0(ucase ? "KEY " : "key "); 4508 } else { 4509 print0(ucase ? "INDEX " : "index "); 4510 } 4511 4512 if (x.getName() !is null) { 4513 x.getName().accept(this); 4514 print(' '); 4515 } 4516 4517 if (type !is null && mysql) { 4518 print0(ucase ? "USING " : "using "); 4519 print0(type); 4520 print(' '); 4521 } 4522 4523 print('('); 4524 printAndAccept!SQLSelectOrderByItem((x.getItems()), ", "); 4525 print(')'); 4526 4527 if (x.getUsing() !is null) { 4528 print0(ucase ? " USING " : " using "); 4529 print0(x.getUsing()); 4530 } 4531 4532 SQLExpr comment = x.getComment(); 4533 if (comment !is null) { 4534 print0(ucase ? " COMMENT " : " comment "); 4535 printExpr(comment); 4536 } 4537 return false; 4538 } 4539 4540 override 4541 bool visit(SQLAlterTableAddConstraint x) { 4542 if (x.isWithNoCheck()) { 4543 print0(ucase ? "WITH NOCHECK " : "with nocheck "); 4544 } 4545 4546 print0(ucase ? "ADD " : "add "); 4547 4548 x.getConstraint().accept(this); 4549 return false; 4550 } 4551 4552 override bool visit(SQLCreateTriggerStatement x) { 4553 print0(ucase ? "CREATE " : "create "); 4554 4555 if (x.isOrReplace()) { 4556 print0(ucase ? "OR REPLACE " : "or replace "); 4557 } 4558 4559 print0(ucase ? "TRIGGER " : "trigger "); 4560 4561 x.getName().accept(this); 4562 4563 this.indentCount++; 4564 println(); 4565 if (SQLCreateTriggerStatement.TriggerType.INSTEAD_OF == (x.getTriggerType())) { 4566 print0(ucase ? "INSTEAD OF" : "instead of"); 4567 } else { 4568 string triggerTypeName = x.getTriggerType().name; 4569 print0(ucase ? triggerTypeName : toLower(triggerTypeName)); 4570 } 4571 4572 if (x.isInsert()) { 4573 print0(ucase ? " INSERT" : " insert"); 4574 } 4575 4576 if (x.isDelete()) { 4577 if (x.isInsert()) { 4578 print0(ucase ? " OR" : " or"); 4579 } 4580 print0(ucase ? " DELETE" : " delete"); 4581 } 4582 4583 if (x.isUpdate()) { 4584 if (x.isInsert() || x.isDelete()) { 4585 print0(ucase ? " OR" : " or"); 4586 } 4587 print0(ucase ? " UPDATE" : " update"); 4588 4589 List!SQLName colums = x.getUpdateOfColumns(); 4590 foreach(SQLName colum ; colums) { 4591 print(' '); 4592 colum.accept(this); 4593 } 4594 } 4595 4596 println(); 4597 print0(ucase ? "ON " : "on "); 4598 x.getOn().accept(this); 4599 4600 if (x.isForEachRow()) { 4601 println(); 4602 print0(ucase ? "FOR EACH ROW" : "for each row"); 4603 } 4604 4605 SQLExpr when = x.getWhen(); 4606 if (when !is null) { 4607 println(); 4608 print0(ucase ? "WHEN " : "when "); 4609 when.accept(this); 4610 } 4611 this.indentCount--; 4612 println(); 4613 x.getBody().accept(this); 4614 return false; 4615 } 4616 4617 override bool visit(SQLBooleanExpr x) { 4618 print0(x.getBooleanValue().booleanValue ? "true" : "false"); 4619 return false; 4620 } 4621 4622 override void endVisit(SQLBooleanExpr x) { 4623 } 4624 4625 override 4626 bool visit(SQLUnionQueryTableSource x) { 4627 print('('); 4628 this.indentCount++; 4629 println(); 4630 x.getUnion().accept(this); 4631 this.indentCount--; 4632 println(); 4633 print(')'); 4634 4635 if (x.getAlias() !is null) { 4636 print(' '); 4637 print0(x.getAlias()); 4638 } 4639 4640 return false; 4641 } 4642 4643 override 4644 bool visit(SQLTimestampExpr x) { 4645 if (this.parameterized) { 4646 print('?'); 4647 incrementReplaceCunt(); 4648 4649 if(this.parameters !is null){ 4650 ExportParameterVisitorUtils.exportParameter(this.parameters, x); 4651 } 4652 return false; 4653 } 4654 4655 print0(ucase ? "TIMESTAMP " : "timestamp "); 4656 4657 if (x.isWithTimeZone()) { 4658 print0(ucase ? " WITH TIME ZONE " : " with time zone "); 4659 } 4660 4661 print('\''); 4662 print0(x.getLiteral()); 4663 print('\''); 4664 4665 if (x.getTimeZone() !is null) { 4666 print0(ucase ? " AT TIME ZONE '" : " at time zone '"); 4667 print0(x.getTimeZone()); 4668 print('\''); 4669 } 4670 4671 return false; 4672 } 4673 4674 override 4675 bool visit(SQLBinaryExpr x) { 4676 print0("b'"); 4677 print0(x.getText()); 4678 print('\''); 4679 4680 return false; 4681 } 4682 4683 override 4684 bool visit(SQLAlterTableRename x) { 4685 print0(ucase ? "RENAME TO " : "rename to "); 4686 x.getTo().accept(this); 4687 return false; 4688 } 4689 4690 override 4691 bool visit(SQLShowTablesStatement x) { 4692 print0(ucase ? "SHOW TABLES" : "show tables"); 4693 if (x.getDatabase() !is null) { 4694 print0(ucase ? " FROM " : " from "); 4695 x.getDatabase().accept(this); 4696 } 4697 4698 if (x.getLike() !is null) { 4699 print0(ucase ? " LIKE " : " like "); 4700 x.getLike().accept(this); 4701 } 4702 return false; 4703 } 4704 4705 protected void printlnComment(List!string comments) { 4706 if (comments !is null) { 4707 for (int i = 0; i < comments.size(); ++i) { 4708 string comment = comments.get(i); 4709 if (i != 0 && comment.startsWith("--")) { 4710 println(); 4711 } 4712 4713 printComment(comment); 4714 } 4715 } 4716 } 4717 4718 void printComment(string comment) { 4719 if (comment is null) { 4720 return; 4721 } 4722 4723 if (comment.startsWith("--") && comment.length > 2 && charAt(comment, 2) != ' ') { 4724 print0("-- "); 4725 print0(comment.substring(2)); 4726 } else { 4727 print0(comment); 4728 } 4729 } 4730 4731 protected void printlnComments(List!string comments) { 4732 if (comments !is null) { 4733 for (int i = 0; i < comments.size(); ++i) { 4734 string comment = comments.get(i); 4735 printComment(comment); 4736 println(); 4737 } 4738 } 4739 } 4740 4741 override 4742 bool visit(SQLAlterViewRenameStatement x) { 4743 print0(ucase ? "ALTER VIEW " : "alter view "); 4744 x.getName().accept(this); 4745 print0(ucase ? " RENAME TO " : " rename to "); 4746 x.getTo().accept(this); 4747 return false; 4748 } 4749 4750 override 4751 bool visit(SQLAlterTableAddPartition x) { 4752 print0(ucase ? "ADD " : "add "); 4753 if (x.isIfNotExists()) { 4754 print0(ucase ? "IF NOT EXISTS " : "if not exists "); 4755 } 4756 4757 if (x.getPartitionCount() !is null) { 4758 print0(ucase ? "PARTITION PARTITIONS " : "partition partitions "); 4759 x.getPartitionCount().accept(this); 4760 } 4761 4762 if (x.getPartitions().size() > 0) { 4763 print0(ucase ? "PARTITION (" : "partition ("); 4764 printAndAccept((x.getPartitions()), ", "); 4765 print(')'); 4766 } 4767 4768 return false; 4769 } 4770 4771 override 4772 bool visit(SQLAlterTableReOrganizePartition x) { 4773 print0(ucase ? "REORGANIZE " : "reorganize "); 4774 4775 printAndAccept!SQLName((x.getNames()), ", "); 4776 4777 print0(ucase ? " INTO (" : " into ("); 4778 printAndAccept((x.getPartitions()), ", "); 4779 print(')'); 4780 return false; 4781 } 4782 4783 override 4784 bool visit(SQLAlterTableDropPartition x) { 4785 print0(ucase ? "DROP " : "drop "); 4786 if (x.isIfExists()) { 4787 print0(ucase ? "IF EXISTS " : "if exists "); 4788 } 4789 print0(ucase ? "PARTITION " : "partition "); 4790 4791 if (x.getPartitions().size() == 1 && cast(SQLName)x.getPartitions().get(0) !is null) { 4792 x.getPartitions().get(0).accept(this); 4793 } else { 4794 print('('); 4795 printAndAccept((x.getPartitions()), ", "); 4796 print(')'); 4797 } 4798 4799 if (x.isPurge()) { 4800 print0(ucase ? " PURGE" : " purge"); 4801 } 4802 return false; 4803 } 4804 4805 override 4806 bool visit(SQLAlterTableRenamePartition x) { 4807 print0(ucase ? "PARTITION (" : "partition ("); 4808 printAndAccept!SQLAssignItem((x.getPartition()), ", "); 4809 print0(ucase ? ") RENAME TO PARTITION(" : ") rename to partition("); 4810 printAndAccept!SQLAssignItem((x.getTo()), ", "); 4811 print(')'); 4812 return false; 4813 } 4814 4815 override 4816 bool visit(SQLAlterTableSetComment x) { 4817 print0(ucase ? "SET COMMENT " : "set comment "); 4818 x.getComment().accept(this); 4819 return false; 4820 } 4821 4822 override 4823 bool visit(SQLAlterTableSetLifecycle x) { 4824 print0(ucase ? "SET LIFECYCLE " : "set lifecycle "); 4825 x.getLifecycle().accept(this); 4826 return false; 4827 } 4828 4829 override 4830 bool visit(SQLAlterTableEnableLifecycle x) { 4831 if (x.getPartition().size() != 0) { 4832 print0(ucase ? "PARTITION (" : "partition ("); 4833 printAndAccept!SQLAssignItem((x.getPartition()), ", "); 4834 print0(") "); 4835 } 4836 4837 print0(ucase ? "ENABLE LIFECYCLE" : "enable lifecycle"); 4838 return false; 4839 } 4840 4841 override 4842 bool visit(SQLAlterTableDisableLifecycle x) { 4843 if (x.getPartition().size() != 0) { 4844 print0(ucase ? "PARTITION (" : "partition ("); 4845 printAndAccept!SQLAssignItem((x.getPartition()), ", "); 4846 print0(") "); 4847 } 4848 4849 print0(ucase ? "DISABLE LIFECYCLE" : "disable lifecycle"); 4850 return false; 4851 } 4852 4853 override 4854 bool visit(SQLAlterTableTouch x) { 4855 print0(ucase ? "TOUCH" : "touch"); 4856 if (x.getPartition().size() != 0) { 4857 print0(ucase ? " PARTITION (" : " partition ("); 4858 printAndAccept!SQLAssignItem((x.getPartition()), ", "); 4859 print(')'); 4860 } 4861 return false; 4862 } 4863 4864 override 4865 bool visit(SQLArrayExpr x) { 4866 x.getExpr().accept(this); 4867 print('['); 4868 printAndAccept!SQLExpr((x.getValues()), ", "); 4869 print(']'); 4870 return false; 4871 } 4872 4873 override 4874 bool visit(SQLOpenStatement x) { 4875 print0(ucase ? "OPEN " : "open "); 4876 printExpr(x.getCursorName()); 4877 4878 List!SQLName columns = x.getColumns(); 4879 if (columns.size() > 0) { 4880 print('('); 4881 printAndAccept!SQLName((columns), ", "); 4882 print(')'); 4883 } 4884 4885 SQLExpr forExpr = x.getFor(); 4886 if (forExpr !is null) { 4887 print0(ucase ? " FOR " : "for "); 4888 forExpr.accept(this); 4889 } 4890 return false; 4891 } 4892 4893 override 4894 bool visit(SQLFetchStatement x) { 4895 print0(ucase ? "FETCH " : "fetch "); 4896 x.getCursorName().accept(this); 4897 if (x.isBulkCollect()) { 4898 print0(ucase ? " BULK COLLECT INTO " : " bulk collect into "); 4899 } else { 4900 print0(ucase ? " INTO " : " into "); 4901 } 4902 printAndAccept!SQLExpr((x.getInto()), ", "); 4903 return false; 4904 } 4905 4906 override 4907 bool visit(SQLCloseStatement x) { 4908 print0(ucase ? "CLOSE " : "close "); 4909 printExpr(x.getCursorName()); 4910 return false; 4911 } 4912 4913 override 4914 bool visit(SQLGroupingSetExpr x) { 4915 print0(ucase ? "GROUPING SETS" : "grouping sets"); 4916 print0(" ("); 4917 printAndAccept!SQLExpr((x.getParameters()), ", "); 4918 print(')'); 4919 return false; 4920 } 4921 4922 override 4923 bool visit(SQLIfStatement x) { 4924 print0(ucase ? "IF " : "if "); 4925 x.getCondition().accept(this); 4926 this.indentCount++; 4927 println(); 4928 for (int i = 0, size = x.getStatements().size(); i < size; ++i) { 4929 SQLStatement item = x.getStatements().get(i); 4930 item.accept(this); 4931 if (i != size - 1) { 4932 println(); 4933 } 4934 } 4935 this.indentCount--; 4936 4937 foreach (SQLIfStatement.ElseIf elseIf ; x.getElseIfList()) { 4938 println(); 4939 elseIf.accept(this); 4940 } 4941 4942 if (x.getElseItem() !is null) { 4943 println(); 4944 x.getElseItem().accept(this); 4945 } 4946 return false; 4947 } 4948 4949 override 4950 bool visit(SQLIfStatement.Else x) { 4951 print0(ucase ? "ELSE" : "else"); 4952 this.indentCount++; 4953 println(); 4954 4955 for (int i = 0, size = x.getStatements().size(); i < size; ++i) { 4956 if (i != 0) { 4957 println(); 4958 } 4959 SQLStatement item = x.getStatements().get(i); 4960 item.accept(this); 4961 } 4962 4963 this.indentCount--; 4964 return false; 4965 } 4966 4967 override 4968 bool visit(SQLIfStatement.ElseIf x) { 4969 print0(ucase ? "ELSE IF" : "else if"); 4970 x.getCondition().accept(this); 4971 print0(ucase ? " THEN" : " then"); 4972 this.indentCount++; 4973 println(); 4974 4975 for (int i = 0, size = x.getStatements().size(); i < size; ++i) { 4976 if (i != 0) { 4977 println(); 4978 } 4979 SQLStatement item = x.getStatements().get(i); 4980 item.accept(this); 4981 } 4982 4983 this.indentCount--; 4984 return false; 4985 } 4986 4987 override 4988 bool visit(SQLLoopStatement x) { 4989 print0(ucase ? "LOOP" : "loop"); 4990 this.indentCount++; 4991 println(); 4992 4993 4994 for (int i = 0, size = x.getStatements().size(); i < size; ++i) { 4995 SQLStatement item = x.getStatements().get(i); 4996 item.accept(this); 4997 4998 if (i != size - 1) { 4999 println(); 5000 } 5001 } 5002 5003 this.indentCount--; 5004 println(); 5005 print0(ucase ? "END LOOP" : "end loop"); 5006 if (x.getLabelName() !is null) { 5007 print(' '); 5008 print0(x.getLabelName()); 5009 } 5010 return false; 5011 } 5012 5013 // bool visit(OracleFunctionDataType x) { 5014 // if (x.isStatic()) { 5015 // print0(ucase ? "STATIC " : "static "); 5016 // } 5017 5018 // print0(ucase ? "FUNCTION " : "function "); 5019 5020 // print0(x.getName()); 5021 5022 // print(" ("); 5023 // printAndAccept(x.getParameters(), ", "); 5024 // print(")"); 5025 // print0(ucase ? " RETURN " : " return "); 5026 // x.getReturnDataType().accept(this); 5027 5028 // SQLStatement block = x.getBlock(); 5029 // if (block !is null) { 5030 // println(); 5031 // print0(ucase ? "IS" : "is"); 5032 // println(); 5033 // block.accept(this); 5034 // } 5035 5036 // return false; 5037 // } 5038 5039 // bool visit(OracleProcedureDataType x) { 5040 // if (x.isStatic()) { 5041 // print0(ucase ? "STATIC " : "static "); 5042 // } 5043 5044 // print0(ucase ? "PROCEDURE " : "procedure "); 5045 5046 // print0(x.getName()); 5047 5048 // if (x.getParameters().size() > 0) { 5049 // print(" ("); 5050 // printAndAccept(x.getParameters(), ", "); 5051 // print(")"); 5052 // } 5053 5054 // SQLStatement block = x.getBlock(); 5055 // if (block !is null) { 5056 // println(); 5057 // print0(ucase ? "IS" : "is"); 5058 // println(); 5059 // block.accept(this); 5060 // } 5061 5062 // return false; 5063 // } 5064 5065 override 5066 bool visit(SQLParameter x) { 5067 SQLName name = x.getName(); 5068 if (x.getDataType().getName().equalsIgnoreCase("CURSOR")) { 5069 print0(ucase ? "CURSOR " : "cursor "); 5070 x.getName().accept(this); 5071 print0(ucase ? " IS" : " is"); 5072 this.indentCount++; 5073 println(); 5074 SQLSelect select = (cast(SQLQueryExpr) x.getDefaultValue()).getSubQuery(); 5075 select.accept(this); 5076 this.indentCount--; 5077 5078 } else { 5079 if (x.isMap()) { 5080 print0(ucase ? "MAP MEMBER " : "map member "); 5081 } else if (x.isOrder()) { 5082 print0(ucase ? "ORDER MEMBER " : "order member "); 5083 } else if (x.isMember()) { 5084 print0(ucase ? "MEMBER " : "member "); 5085 } 5086 SQLDataType dataType = x.getDataType(); 5087 5088 /*if (DBType.ORACLE.opEquals(dbType) 5089 || cast(OracleFunctionDataType)dataType !is null 5090 || cast(OracleProcedureDataType)dataType !is null) { 5091 if (cast(OracleFunctionDataType)dataType !is null) { 5092 OracleFunctionDataType functionDataType = cast(OracleFunctionDataType) dataType; 5093 visit(functionDataType); 5094 return false; 5095 } 5096 5097 if (cast(OracleProcedureDataType)dataType !is null) { 5098 OracleProcedureDataType procedureDataType = cast(OracleProcedureDataType) dataType; 5099 visit(procedureDataType); 5100 return false; 5101 } 5102 5103 string dataTypeName = dataType.getName(); 5104 bool printType = (dataTypeName.startsWith("TABLE OF") && x.getDefaultValue() is null) 5105 || equalsIgnoreCase(dataTypeName, "REF CURSOR") 5106 || dataTypeName.startsWith("VARRAY("); 5107 if (printType) { 5108 print0(ucase ? "TYPE " : "type "); 5109 } 5110 5111 name.accept(this); 5112 if (x.getParamType() == SQLParameter.ParameterType.IN) { 5113 print0(ucase ? " IN " : " in "); 5114 } else if (x.getParamType() == SQLParameter.ParameterType.OUT) { 5115 print0(ucase ? " OUT " : " out "); 5116 } else if (x.getParamType() == SQLParameter.ParameterType.INOUT) { 5117 print0(ucase ? " IN OUT " : " in out "); 5118 } else { 5119 print(' '); 5120 } 5121 5122 if (x.isNoCopy()) { 5123 print0(ucase ? "NOCOPY " : "nocopy "); 5124 } 5125 5126 if (x.isConstant()) { 5127 print0(ucase ? "CONSTANT " : "constant "); 5128 } 5129 5130 if (printType) { 5131 print0(ucase ? "IS " : "is "); 5132 } 5133 } else */{ 5134 if (x.getParamType() == SQLParameter.ParameterType.IN) { 5135 bool skip = DBType.MYSQL.opEquals(dbType) 5136 && cast(SQLCreateFunctionStatement)x.getParent() !is null; 5137 5138 if (!skip) { 5139 print0(ucase ? "IN " : "in "); 5140 } 5141 } else if (x.getParamType() == SQLParameter.ParameterType.OUT) { 5142 print0(ucase ? "OUT " : "out "); 5143 } else if (x.getParamType() == SQLParameter.ParameterType.INOUT) { 5144 print0(ucase ? "INOUT " : "inout "); 5145 } 5146 x.getName().accept(this); 5147 print(' '); 5148 } 5149 5150 dataType.accept(this); 5151 5152 printParamDefaultValue(x); 5153 } 5154 5155 return false; 5156 } 5157 5158 protected void printParamDefaultValue(SQLParameter x) { 5159 if (x.getDefaultValue() !is null) { 5160 print0(" := "); 5161 x.getDefaultValue().accept(this); 5162 } 5163 } 5164 5165 override 5166 bool visit(SQLDeclareItem x) { 5167 SQLDataType dataType = x.getDataType(); 5168 5169 if (cast(SQLRecordDataType)dataType !is null) { 5170 print0(ucase ? "TYPE " : "type "); 5171 } 5172 5173 x.getName().accept(this); 5174 5175 5176 if (x.getType() == SQLDeclareItem.Type.TABLE) { 5177 print0(ucase ? " TABLE" : " table"); 5178 int size = x.getTableElementList().size(); 5179 5180 if (size > 0) { 5181 print0(" ("); 5182 this.indentCount++; 5183 println(); 5184 for (int i = 0; i < size; ++i) { 5185 if (i != 0) { 5186 print(','); 5187 println(); 5188 } 5189 x.getTableElementList().get(i).accept(this); 5190 } 5191 this.indentCount--; 5192 println(); 5193 print(')'); 5194 } 5195 } else if (x.getType() == SQLDeclareItem.Type.CURSOR) { 5196 print0(ucase ? " CURSOR" : " cursor"); 5197 } else { 5198 5199 if (dataType !is null) { 5200 if (cast(SQLRecordDataType)dataType !is null) { 5201 print0(ucase ? " IS " : " is "); 5202 } else { 5203 print(' '); 5204 } 5205 dataType.accept(this); 5206 } 5207 if (x.getValue() !is null) { 5208 if (DBType.MYSQL.opEquals(getDbType())) { 5209 print0(ucase ? " DEFAULT " : " default "); 5210 } else { 5211 print0(" = "); 5212 } 5213 x.getValue().accept(this); 5214 } 5215 } 5216 5217 return false; 5218 } 5219 5220 override 5221 bool visit(SQLPartitionValue x) { 5222 if (x.getOperator() == SQLPartitionValue.Operator.LessThan // 5223 && (!DBType.ORACLE.opEquals(getDbType())) && x.getItems().size() == 1 // 5224 && cast(SQLIdentifierExpr)x.getItems().get(0) !is null) { 5225 SQLIdentifierExpr ident = cast(SQLIdentifierExpr) x.getItems().get(0); 5226 if ("MAXVALUE".equalsIgnoreCase(ident.getName())) { 5227 print0(ucase ? "VALUES LESS THAN MAXVALUE" : "values less than maxvalue"); 5228 return false; 5229 } 5230 } 5231 5232 if (x.getOperator() == SQLPartitionValue.Operator.LessThan) { 5233 print0(ucase ? "VALUES LESS THAN (" : "values less than ("); 5234 } else if (x.getOperator() == SQLPartitionValue.Operator.In) { 5235 print0(ucase ? "VALUES IN (" : "values in ("); 5236 } else { 5237 print(ucase ? "VALUES (" : "values ("); 5238 } 5239 printAndAccept!SQLExpr((x.getItems()), ", "); 5240 print(')'); 5241 return false; 5242 } 5243 5244 string getDbType() { 5245 return dbType; 5246 } 5247 5248 bool isUppCase() { 5249 return ucase; 5250 } 5251 5252 void setUppCase(bool val) { 5253 this.config(VisitorFeature.OutputUCase, true); 5254 } 5255 5256 override 5257 bool visit(SQLPartition x) { 5258 print0(ucase ? "PARTITION " : "partition "); 5259 x.getName().accept(this); 5260 if (x.getValues() !is null) { 5261 print(' '); 5262 x.getValues().accept(this); 5263 } 5264 5265 if (x.getDataDirectory() !is null) { 5266 this.indentCount++; 5267 println(); 5268 print0(ucase ? "DATA DIRECTORY " : "data directory "); 5269 x.getDataDirectory().accept(this); 5270 this.indentCount--; 5271 } 5272 5273 if (x.getIndexDirectory() !is null) { 5274 this.indentCount++; 5275 println(); 5276 print0(ucase ? "INDEX DIRECTORY " : "index directory "); 5277 x.getIndexDirectory().accept(this); 5278 this.indentCount--; 5279 } 5280 5281 this.indentCount++; 5282 // printOracleSegmentAttributes(x);//@gxc 5283 5284 5285 if (x.getEngine() !is null) { 5286 println(); 5287 print0(ucase ? "STORAGE ENGINE " : "storage engine "); 5288 x.getEngine().accept(this); 5289 } 5290 this.indentCount--; 5291 5292 if (x.getMaxRows() !is null) { 5293 print0(ucase ? " MAX_ROWS " : " max_rows "); 5294 x.getMaxRows().accept(this); 5295 } 5296 5297 if (x.getMinRows() !is null) { 5298 print0(ucase ? " MIN_ROWS " : " min_rows "); 5299 x.getMinRows().accept(this); 5300 } 5301 5302 if (x.getComment() !is null) { 5303 print0(ucase ? " COMMENT " : " comment "); 5304 x.getComment().accept(this); 5305 } 5306 5307 if (x.getSubPartitionsCount() !is null) { 5308 this.indentCount++; 5309 println(); 5310 print0(ucase ? "SUBPARTITIONS " : "subpartitions "); 5311 x.getSubPartitionsCount().accept(this); 5312 this.indentCount--; 5313 } 5314 5315 if (x.getSubPartitions().size() > 0) { 5316 print(" ("); 5317 this.indentCount++; 5318 for (int i = 0; i < x.getSubPartitions().size(); ++i) { 5319 if (i != 0) { 5320 print(','); 5321 } 5322 println(); 5323 x.getSubPartitions().get(i).accept(this); 5324 } 5325 this.indentCount--; 5326 println(); 5327 print(')'); 5328 } 5329 5330 return false; 5331 } 5332 5333 override 5334 bool visit(SQLPartitionByRange x) { 5335 print0(ucase ? "RANGE" : "range"); 5336 if (x.getColumns().size() == 1) { 5337 print0(" ("); 5338 x.getColumns().get(0).accept(this); 5339 print(')'); 5340 } else { 5341 if (DBType.MYSQL.opEquals(getDbType())) { 5342 print0(ucase ? " COLUMNS (" : " columns ("); 5343 } else { 5344 print0(" ("); 5345 } 5346 printAndAccept!SQLExpr((x.getColumns()), ", "); 5347 print(')'); 5348 } 5349 5350 SQLExpr interval = x.getInterval(); 5351 if (interval !is null) { 5352 print0(ucase ? " INTERVAL (" : " interval ("); 5353 interval.accept(this); 5354 print(')'); 5355 } 5356 5357 printPartitionsCountAndSubPartitions(x); 5358 5359 print(" ("); 5360 this.indentCount++; 5361 for (int i = 0, size = x.getPartitions().size(); i < size; ++i) { 5362 if (i != 0) { 5363 print(','); 5364 } 5365 println(); 5366 x.getPartitions().get(i).accept(this); 5367 } 5368 this.indentCount--; 5369 println(); 5370 print(')'); 5371 5372 return false; 5373 } 5374 5375 override 5376 bool visit(SQLPartitionByList x) { 5377 print0(ucase ? "LIST " : "list "); 5378 if (x.getColumns().size() == 1) { 5379 print('('); 5380 x.getColumns().get(0).accept(this); 5381 print0(")"); 5382 } else { 5383 print0(ucase ? "COLUMNS (" : "columns ("); 5384 printAndAccept!SQLExpr((x.getColumns()), ", "); 5385 print0(")"); 5386 } 5387 5388 printPartitionsCountAndSubPartitions(x); 5389 5390 printSQLPartitions(x.getPartitions()); 5391 return false; 5392 } 5393 5394 override 5395 bool visit(SQLPartitionByHash x) { 5396 if (x.isLinear()) { 5397 print0(ucase ? "LINEAR HASH " : "linear hash "); 5398 } else { 5399 print0(ucase ? "HASH " : "hash "); 5400 } 5401 5402 if (x.isKey()) { 5403 print0(ucase ? "KEY" : "key"); 5404 } 5405 5406 print('('); 5407 printAndAccept!SQLExpr((x.getColumns()), ", "); 5408 print(')'); 5409 5410 printPartitionsCountAndSubPartitions(x); 5411 5412 printSQLPartitions(x.getPartitions()); 5413 5414 return false; 5415 } 5416 5417 private void printSQLPartitions(List!SQLPartition partitions) { 5418 int partitionsSize = partitions.size(); 5419 if (partitionsSize > 0) { 5420 print0(" ("); 5421 this.indentCount++; 5422 for (int i = 0; i < partitionsSize; ++i) { 5423 println(); 5424 partitions.get(i).accept(this); 5425 if (i != partitionsSize - 1) { 5426 print0(", "); 5427 } 5428 } 5429 this.indentCount--; 5430 println(); 5431 print(')'); 5432 } 5433 } 5434 5435 protected void printPartitionsCountAndSubPartitions(SQLPartitionBy x) { 5436 if (x.getPartitionsCount() !is null) { 5437 5438 if (Boolean.TRUE.opEquals(x.getAttribute("ads.partition"))) { 5439 print0(ucase ? " PARTITION NUM " : " partition num "); 5440 } else { 5441 print0(ucase ? " PARTITIONS " : " partitions "); 5442 } 5443 5444 x.getPartitionsCount().accept(this); 5445 } 5446 5447 if (x.getSubPartitionBy() !is null) { 5448 println(); 5449 x.getSubPartitionBy().accept(this); 5450 } 5451 5452 if (x.getStoreIn().size() > 0) { 5453 println(); 5454 print0(ucase ? "STORE IN (" : "store in ("); 5455 printAndAccept!SQLName((x.getStoreIn()), ", "); 5456 print(')'); 5457 } 5458 } 5459 5460 override 5461 bool visit(SQLSubPartitionByHash x) { 5462 if (x.isLinear()) { 5463 print0(ucase ? "SUBPARTITION BY LINEAR HASH " : "subpartition by linear hash "); 5464 } else { 5465 print0(ucase ? "SUBPARTITION BY HASH " : "subpartition by hash "); 5466 } 5467 5468 if (x.isKey()) { 5469 print0(ucase ? "KEY" : "key"); 5470 } 5471 5472 print('('); 5473 x.getExpr().accept(this); 5474 print(')'); 5475 5476 if (x.getSubPartitionsCount() !is null) { 5477 print0(ucase ? " SUBPARTITIONS " : " subpartitions "); 5478 x.getSubPartitionsCount().accept(this); 5479 } 5480 5481 return false; 5482 } 5483 5484 override 5485 bool visit(SQLSubPartitionByList x) { 5486 if (x.isLinear()) { 5487 print0(ucase ? "SUBPARTITION BY LINEAR HASH " : "subpartition by linear hash "); 5488 } else { 5489 print0(ucase ? "SUBPARTITION BY HASH " : "subpartition by hash "); 5490 } 5491 5492 print('('); 5493 x.getColumn().accept(this); 5494 print(')'); 5495 5496 if (x.getSubPartitionsCount() !is null) { 5497 print0(ucase ? " SUBPARTITIONS " : " subpartitions "); 5498 x.getSubPartitionsCount().accept(this); 5499 } 5500 5501 if (x.getSubPartitionTemplate().size() > 0) { 5502 this.indentCount++; 5503 println(); 5504 print0(ucase ? "SUBPARTITION TEMPLATE (" : "subpartition template ("); 5505 this.indentCount++; 5506 println(); 5507 printlnAndAccept!(SQLSubPartition)((x.getSubPartitionTemplate()), ","); 5508 this.indentCount--; 5509 println(); 5510 print(')'); 5511 this.indentCount--; 5512 } 5513 5514 return false; 5515 } 5516 5517 override 5518 bool visit(SQLSubPartition x) { 5519 print0(ucase ? "SUBPARTITION " : "subpartition "); 5520 x.getName().accept(this); 5521 5522 if (x.getValues() !is null) { 5523 print(' '); 5524 x.getValues().accept(this); 5525 } 5526 5527 SQLName tableSpace = x.getTableSpace(); 5528 if (tableSpace !is null) { 5529 print0(ucase ? " TABLESPACE " : " tablespace "); 5530 tableSpace.accept(this); 5531 } 5532 5533 return false; 5534 } 5535 5536 override 5537 bool visit(SQLAlterDatabaseStatement x) { 5538 print0(ucase ? "ALTER DATABASE " : "alter database "); 5539 x.getName().accept(this); 5540 if (x.isUpgradeDataDirectoryName()) { 5541 print0(ucase ? " UPGRADE DATA DIRECTORY NAME" : " upgrade data directory name"); 5542 } 5543 5544 SQLAlterCharacter character = x.getCharacter(); 5545 if (character !is null) { 5546 print(' '); 5547 character.accept(this); 5548 } 5549 return false; 5550 } 5551 5552 override 5553 bool visit(SQLAlterTableConvertCharSet x) { 5554 print0(ucase ? "CONVERT TO CHARACTER SET " : "convert to character set "); 5555 x.getCharset().accept(this); 5556 5557 if (x.getCollate() !is null) { 5558 print0(ucase ? "COLLATE " : "collate "); 5559 x.getCollate().accept(this); 5560 } 5561 return false; 5562 } 5563 5564 override 5565 bool visit(SQLAlterTableCoalescePartition x) { 5566 print0(ucase ? "COALESCE PARTITION " : "coalesce partition "); 5567 x.getCount().accept(this); 5568 return false; 5569 } 5570 5571 override 5572 bool visit(SQLAlterTableTruncatePartition x) { 5573 print0(ucase ? "TRUNCATE PARTITION " : "truncate partition "); 5574 printPartitions(x.getPartitions()); 5575 return false; 5576 } 5577 5578 override 5579 bool visit(SQLAlterTableDiscardPartition x) { 5580 print0(ucase ? "DISCARD PARTITION " : "discard partition "); 5581 printPartitions(x.getPartitions()); 5582 5583 if (x.isTablespace()) { 5584 print0(ucase ? " TABLESPACE" : " tablespace"); 5585 } 5586 5587 return false; 5588 } 5589 5590 override 5591 bool visit(SQLAlterTableImportPartition x) { 5592 print0(ucase ? "IMPORT PARTITION " : "import partition "); 5593 printPartitions(x.getPartitions()); 5594 return false; 5595 } 5596 5597 override 5598 bool visit(SQLAlterTableAnalyzePartition x) { 5599 print0(ucase ? "ANALYZE PARTITION " : "analyze partition "); 5600 5601 printPartitions(x.getPartitions()); 5602 return false; 5603 } 5604 5605 protected void printPartitions(List!SQLName partitions) { 5606 if (partitions.size() == 1 && "ALL".equalsIgnoreCase(partitions.get(0).getSimpleName())) { 5607 print0(ucase ? "ALL" : "all"); 5608 } else { 5609 printAndAccept!SQLName((partitions), ", "); 5610 } 5611 } 5612 5613 override 5614 bool visit(SQLAlterTableCheckPartition x) { 5615 print0(ucase ? "CHECK PARTITION " : "check partition "); 5616 printPartitions(x.getPartitions()); 5617 return false; 5618 } 5619 5620 override 5621 bool visit(SQLAlterTableOptimizePartition x) { 5622 print0(ucase ? "OPTIMIZE PARTITION " : "optimize partition "); 5623 printPartitions(x.getPartitions()); 5624 return false; 5625 } 5626 5627 override 5628 bool visit(SQLAlterTableRebuildPartition x) { 5629 print0(ucase ? "REBUILD PARTITION " : "rebuild partition "); 5630 printPartitions(x.getPartitions()); 5631 return false; 5632 } 5633 5634 override 5635 bool visit(SQLAlterTableRepairPartition x) { 5636 print0(ucase ? "REPAIR PARTITION " : "repair partition "); 5637 printPartitions(x.getPartitions()); 5638 return false; 5639 } 5640 5641 override 5642 bool visit(SQLSequenceExpr x) { 5643 x.getSequence().accept(this); 5644 print('.'); 5645 print0(ucase ? x.getFunction().name : x.getFunction().name_lcase); 5646 return false; 5647 } 5648 5649 override 5650 bool visit(SQLMergeStatement x) { 5651 print0(ucase ? "MERGE " : "merge "); 5652 if (x.getHints().size() > 0) { 5653 printAndAccept!SQLHint((x.getHints()), ", "); 5654 print(' '); 5655 } 5656 5657 print0(ucase ? "INTO " : "into "); 5658 x.getInto().accept(this); 5659 5660 println(); 5661 print0(ucase ? "USING " : "using "); 5662 x.getUsing().accept(this); 5663 5664 print0(ucase ? " ON (" : " on ("); 5665 x.getOn().accept(this); 5666 print0(") "); 5667 5668 if (x.getUpdateClause() !is null) { 5669 println(); 5670 x.getUpdateClause().accept(this); 5671 } 5672 5673 if (x.getInsertClause() !is null) { 5674 println(); 5675 x.getInsertClause().accept(this); 5676 } 5677 5678 if (x.getErrorLoggingClause() !is null) { 5679 println(); 5680 x.getErrorLoggingClause().accept(this); 5681 } 5682 5683 return false; 5684 } 5685 5686 override 5687 bool visit(SQLMergeStatement.MergeUpdateClause x) { 5688 print0(ucase ? "WHEN MATCHED THEN UPDATE SET " : "when matched then update set "); 5689 printAndAccept!SQLUpdateSetItem((x.getItems()), ", "); 5690 5691 SQLExpr where = x.getWhere(); 5692 if (where !is null) { 5693 this.indentCount++; 5694 println(); 5695 print0(ucase ? "WHERE " : "where "); 5696 printExpr(where); 5697 this.indentCount--; 5698 } 5699 5700 SQLExpr deleteWhere = x.getDeleteWhere(); 5701 if (deleteWhere !is null) { 5702 this.indentCount++; 5703 println(); 5704 print0(ucase ? "DELETE WHERE " : "delete where "); 5705 printExpr(deleteWhere); 5706 this.indentCount--; 5707 } 5708 5709 return false; 5710 } 5711 5712 override 5713 bool visit(SQLMergeStatement.MergeInsertClause x) { 5714 print0(ucase ? "WHEN NOT MATCHED THEN INSERT" : "when not matched then insert"); 5715 if (x.getColumns().size() > 0) { 5716 print(" ("); 5717 printAndAccept!SQLExpr((x.getColumns()), ", "); 5718 print(')'); 5719 } 5720 print0(ucase ? " VALUES (" : " values ("); 5721 printAndAccept!SQLExpr((x.getValues()), ", "); 5722 print(')'); 5723 if (x.getWhere() !is null) { 5724 this.indentCount++; 5725 println(); 5726 print0(ucase ? "WHERE " : "where "); 5727 x.getWhere().accept(this); 5728 this.indentCount--; 5729 } 5730 5731 return false; 5732 } 5733 5734 override 5735 bool visit(SQLErrorLoggingClause x) { 5736 print0(ucase ? "LOG ERRORS " : "log errors "); 5737 if (x.getInto() !is null) { 5738 print0(ucase ? "INTO " : "into "); 5739 x.getInto().accept(this); 5740 print(' '); 5741 } 5742 5743 if (x.getSimpleExpression() !is null) { 5744 print('('); 5745 x.getSimpleExpression().accept(this); 5746 print(')'); 5747 } 5748 5749 if (x.getLimit() !is null) { 5750 print0(ucase ? " REJECT LIMIT " : " reject limit "); 5751 x.getLimit().accept(this); 5752 } 5753 5754 return false; 5755 } 5756 5757 override 5758 bool visit(SQLCreateSequenceStatement x) { 5759 print0(ucase ? "CREATE SEQUENCE " : "create sequence "); 5760 x.getName().accept(this); 5761 5762 if (x.getStartWith() !is null) { 5763 print0(ucase ? " START WITH " : " start with "); 5764 x.getStartWith().accept(this); 5765 } 5766 5767 if (x.getIncrementBy() !is null) { 5768 print0(ucase ? " INCREMENT BY " : " increment by "); 5769 x.getIncrementBy().accept(this); 5770 } 5771 5772 if (x.getMaxValue() !is null) { 5773 print0(ucase ? " MAXVALUE " : " maxvalue "); 5774 x.getMaxValue().accept(this); 5775 } 5776 5777 if (x.isNoMaxValue()) { 5778 if (DBType.POSTGRESQL.opEquals(dbType)) { 5779 print0(ucase ? " NO MAXVALUE" : " no maxvalue"); 5780 } else { 5781 print0(ucase ? " NOMAXVALUE" : " nomaxvalue"); 5782 } 5783 } 5784 5785 if (x.getMinValue() !is null) { 5786 print0(ucase ? " MINVALUE " : " minvalue "); 5787 x.getMinValue().accept(this); 5788 } 5789 5790 if (x.isNoMinValue()) { 5791 if (DBType.POSTGRESQL.opEquals(dbType)) { 5792 print0(ucase ? " NO MINVALUE" : " no minvalue"); 5793 } else { 5794 print0(ucase ? " NOMINVALUE" : " nominvalue"); 5795 } 5796 } 5797 5798 if (x.getCycle() !is null) { 5799 if (x.getCycle().booleanValue()) { 5800 print0(ucase ? " CYCLE" : " cycle"); 5801 } else { 5802 if (DBType.POSTGRESQL.opEquals(dbType)) { 5803 print0(ucase ? " NO CYCLE" : " no cycle"); 5804 } else { 5805 print0(ucase ? " NOCYCLE" : " nocycle"); 5806 } 5807 } 5808 } 5809 5810 Boolean cache = x.getCache(); 5811 if (cache !is null) { 5812 if (cache.booleanValue()) { 5813 print0(ucase ? " CACHE" : " cache"); 5814 5815 SQLExpr cacheValue = x.getCacheValue(); 5816 if (cacheValue !is null) { 5817 print(' '); 5818 cacheValue.accept(this); 5819 } 5820 } else { 5821 print0(ucase ? " NOCACHE" : " nocache"); 5822 } 5823 } 5824 5825 Boolean order = x.getOrder(); 5826 if (order !is null) { 5827 if (order.booleanValue()) { 5828 print0(ucase ? " ORDER" : " order"); 5829 } else { 5830 print0(ucase ? " NOORDER" : " noorder"); 5831 } 5832 } 5833 5834 return false; 5835 } 5836 5837 override 5838 bool visit(SQLAlterSequenceStatement x) { 5839 print0(ucase ? "ALTER SEQUENCE " : "alter sequence "); 5840 x.getName().accept(this); 5841 5842 if (x.getStartWith() !is null) { 5843 print0(ucase ? " START WITH " : " start with "); 5844 x.getStartWith().accept(this); 5845 } 5846 5847 if (x.getIncrementBy() !is null) { 5848 print0(ucase ? " INCREMENT BY " : " increment by "); 5849 x.getIncrementBy().accept(this); 5850 } 5851 5852 if (x.getMaxValue() !is null) { 5853 print0(ucase ? " MAXVALUE " : " maxvalue "); 5854 x.getMaxValue().accept(this); 5855 } 5856 5857 if (x.isNoMaxValue()) { 5858 if (DBType.POSTGRESQL.opEquals(dbType)) { 5859 print0(ucase ? " NO MAXVALUE" : " no maxvalue"); 5860 } else { 5861 print0(ucase ? " NOMAXVALUE" : " nomaxvalue"); 5862 } 5863 } 5864 5865 if (x.getMinValue() !is null) { 5866 print0(ucase ? " MINVALUE " : " minvalue "); 5867 x.getMinValue().accept(this); 5868 } 5869 5870 if (x.isNoMinValue()) { 5871 if (DBType.POSTGRESQL.opEquals(dbType)) { 5872 print0(ucase ? " NO MINVALUE" : " no minvalue"); 5873 } else { 5874 print0(ucase ? " NOMINVALUE" : " nominvalue"); 5875 } 5876 } 5877 5878 if (x.getCycle() !is null) { 5879 if (x.getCycle().booleanValue()) { 5880 print0(ucase ? " CYCLE" : " cycle"); 5881 } else { 5882 if (DBType.POSTGRESQL.opEquals(dbType)) { 5883 print0(ucase ? " NO CYCLE" : " no cycle"); 5884 } else { 5885 print0(ucase ? " NOCYCLE" : " nocycle"); 5886 } 5887 } 5888 } 5889 5890 Boolean cache = x.getCache(); 5891 if (cache !is null) { 5892 if (cache.booleanValue()) { 5893 print0(ucase ? " CACHE" : " cache"); 5894 5895 SQLExpr cacheValue = x.getCacheValue(); 5896 if (cacheValue !is null) { 5897 print(' '); 5898 cacheValue.accept(this); 5899 } 5900 } else { 5901 print0(ucase ? " NOCACHE" : " nocache"); 5902 } 5903 } 5904 5905 Boolean order = x.getOrder(); 5906 if (order !is null) { 5907 if (order.booleanValue()) { 5908 print0(ucase ? " ORDER" : " order"); 5909 } else { 5910 print0(ucase ? " NOORDER" : " noorder"); 5911 } 5912 } 5913 5914 return false; 5915 } 5916 5917 override bool visit(SQLDateExpr x) { 5918 if (this.parameterized) { 5919 print('?'); 5920 incrementReplaceCunt(); 5921 5922 if(this.parameters !is null){ 5923 ExportParameterVisitorUtils.exportParameter(this.parameters, x); 5924 } 5925 return false; 5926 } 5927 5928 SQLExpr literal = x.getLiteral(); 5929 print0(ucase ? "DATE " : "date "); 5930 printExpr(literal); 5931 5932 return false; 5933 } 5934 5935 override bool visit(SQLLimit x) { 5936 print0(ucase ? "LIMIT " : "limit "); 5937 SQLExpr offset = x.getOffset(); 5938 if (offset !is null) { 5939 printExpr(offset); 5940 print0(", "); 5941 } 5942 5943 SQLExpr rowCount = x.getRowCount(); 5944 printExpr(rowCount); 5945 5946 return false; 5947 } 5948 5949 override bool visit(SQLDescribeStatement x) { 5950 print0(ucase ? "DESC " : "desc "); 5951 if (x.getObjectType().name.length != 0) { 5952 print0(x.getObjectType().name); 5953 print(' '); 5954 } 5955 5956 if(x.getObject() !is null) { 5957 x.getObject().accept(this); 5958 } 5959 5960 if (x.getPartition().size() > 0) { 5961 print0(ucase ? " PARTITION (" : " partition ("); 5962 printAndAccept!SQLExpr((x.getPartition()), ", "); 5963 print(')'); 5964 } 5965 return false; 5966 } 5967 5968 protected void printHierarchical(SQLSelectQueryBlock x) { 5969 SQLExpr startWith = x.getStartWith(), connectBy = x.getConnectBy(); 5970 if (startWith !is null || connectBy !is null){ 5971 println(); 5972 if (x.getStartWith() !is null) { 5973 print0(ucase ? "START WITH " : "start with "); 5974 x.getStartWith().accept(this); 5975 println(); 5976 } 5977 5978 print0(ucase ? "CONNECT BY " : "connect by "); 5979 5980 if (x.isNoCycle()) { 5981 print0(ucase ? "NOCYCLE " : "nocycle "); 5982 } 5983 5984 if (x.isPrior()) { 5985 print0(ucase ? "PRIOR " : "prior "); 5986 } 5987 5988 x.getConnectBy().accept(this); 5989 } 5990 } 5991 5992 // void printOracleSegmentAttributes(OracleSegmentAttributes x) { 5993 5994 // if (x.getPctfree() !is null) { 5995 // println(); 5996 // print0(ucase ? "PCTFREE " : "pctfree "); 5997 // print(x.getPctfree()); 5998 // } 5999 6000 // if (x.getPctused() !is null) { 6001 // println(); 6002 // print0(ucase ? "PCTUSED " : "pctused "); 6003 // print(x.getPctused()); 6004 // } 6005 6006 // if (x.getInitrans() !is null) { 6007 // println(); 6008 // print0(ucase ? "INITRANS " : "initrans "); 6009 // print(x.getInitrans()); 6010 // } 6011 6012 // if (x.getMaxtrans() !is null) { 6013 // println(); 6014 // print0(ucase ? "MAXTRANS " : "maxtrans "); 6015 // print(x.getMaxtrans()); 6016 // } 6017 6018 // if (x.getCompress() == bool.FALSE) { 6019 // println(); 6020 // print0(ucase ? "NOCOMPRESS" : "nocompress"); 6021 // } else if (x.getCompress() == bool.TRUE) { 6022 // println(); 6023 // print0(ucase ? "COMPRESS" : "compress"); 6024 6025 // if (x.getCompressLevel() !is null) { 6026 // print(' '); 6027 // print(x.getCompressLevel()); 6028 // } 6029 // } 6030 6031 // if (x.getLogging() == bool.TRUE) { 6032 // println(); 6033 // print0(ucase ? "LOGGING" : "logging"); 6034 // } else if (x.getLogging() == bool.FALSE) { 6035 // println(); 6036 // print0(ucase ? "NOLOGGING" : "nologging"); 6037 // } 6038 6039 // if (x.getTablespace() !is null) { 6040 // println(); 6041 // print0(ucase ? "TABLESPACE " : "tablespace "); 6042 // x.getTablespace().accept(this); 6043 // } 6044 6045 // if (x.getStorage() !is null) { 6046 // println(); 6047 // x.getStorage().accept(this); 6048 // } 6049 // } 6050 6051 override 6052 bool visit(SQLWhileStatement x) { 6053 string label = x.getLabelName(); 6054 6055 if (label !is null && label.length != 0) { 6056 print0(x.getLabelName()); 6057 print0(": "); 6058 } 6059 print0(ucase ? "WHILE " : "while "); 6060 x.getCondition().accept(this); 6061 print0(ucase ? " DO" : " do"); 6062 println(); 6063 for (int i = 0, size = x.getStatements().size(); i < size; ++i) { 6064 SQLStatement item = x.getStatements().get(i); 6065 item.accept(this); 6066 if (i != size - 1) { 6067 println(); 6068 } 6069 } 6070 println(); 6071 print0(ucase ? "END WHILE" : "end while"); 6072 if (label !is null && label.length != 0) { 6073 print(' '); 6074 print0(label); 6075 } 6076 return false; 6077 } 6078 6079 override 6080 bool visit(SQLDeclareStatement x) { 6081 // bool printDeclare = !(cast(OracleCreatePackageStatement)x.getParent() !is null); 6082 // if (printDeclare) { 6083 // print0(ucase ? "DECLARE " : "declare "); 6084 // } //@gxc 6085 this.printAndAccept!SQLDeclareItem((x.getItems()), ", "); 6086 return false; 6087 } 6088 6089 override 6090 bool visit(SQLReturnStatement x) { 6091 print0(ucase ? "RETURN" : "return"); 6092 6093 if (x.getExpr() !is null) { 6094 print(' '); 6095 x.getExpr().accept(this); 6096 } 6097 return false; 6098 } 6099 6100 override void postVisit(SQLObject x) { 6101 if (cast(SQLStatement)x !is null) { 6102 SQLStatement stmt = cast(SQLStatement) x; 6103 bool printSemi = printStatementAfterSemi is null 6104 ? stmt.isAfterSemi() 6105 : printStatementAfterSemi.booleanValue(); 6106 if (printSemi) { 6107 print(';'); 6108 } 6109 } 6110 } 6111 6112 override 6113 bool visit(SQLArgument x) { 6114 SQLParameter.ParameterType type = x.getType(); 6115 if (type.name.length != 0) { 6116 print0(type.name); 6117 print(' '); 6118 } 6119 6120 x.getExpr().accept(this); 6121 return false; 6122 } 6123 6124 override 6125 bool visit(SQLCommitStatement x) { 6126 print0(ucase ? "COMMIT" : "commit"); 6127 6128 if (x.isWrite()) { 6129 print0(ucase ? " WRITE" : " write"); 6130 if (x.getWait() !is null) { 6131 if (x.getWait().booleanValue()) { 6132 print0(ucase ? " WAIT" : " wait"); 6133 } else { 6134 print0(ucase ? " NOWAIT" : " nowait"); 6135 } 6136 } 6137 6138 if (x.getImmediate() !is null) { 6139 if (x.getImmediate().booleanValue()) { 6140 print0(ucase ? " IMMEDIATE" : " immediate"); 6141 } else { 6142 print0(ucase ? " BATCH" : " batch"); 6143 } 6144 } 6145 } 6146 6147 if (x.isWork()) { 6148 print0(ucase ? " WORK" : " work"); 6149 } 6150 6151 if (x.getChain() !is null) { 6152 if (x.getChain().booleanValue()) { 6153 print0(ucase ? " AND CHAIN" : " and chain"); 6154 } else { 6155 print0(ucase ? " AND NO CHAIN" : " and no chain"); 6156 } 6157 } 6158 6159 if (x.getRelease() !is null) { 6160 if (x.getRelease().booleanValue()) { 6161 print0(ucase ? " AND RELEASE" : " and release"); 6162 } else { 6163 print0(ucase ? " AND NO RELEASE" : " and no release"); 6164 } 6165 } 6166 6167 return false; 6168 } 6169 6170 override bool visit(SQLFlashbackExpr x) { 6171 print0(x.getType().name); 6172 print(' '); 6173 SQLExpr expr = x.getExpr(); 6174 if (cast(SQLBinaryOpExpr)expr !is null) { 6175 print('('); 6176 expr.accept(this); 6177 print(')'); 6178 } else { 6179 expr.accept(this); 6180 } 6181 return false; 6182 } 6183 6184 override bool visit(SQLCreateMaterializedViewStatement x) { 6185 print0(ucase ? "CREATE MATERIALIZED VIEW " : "create materialized view "); 6186 x.getName().accept(this); 6187 6188 SQLPartitionBy partitionBy = x.getPartitionBy(); 6189 if (partitionBy !is null) { 6190 println(); 6191 print0(ucase ? "PARTITION BY " : "partition by "); 6192 partitionBy.accept(this); 6193 } 6194 6195 // this.printOracleSegmentAttributes(x);//@gxc 6196 println(); 6197 6198 Boolean cache = x.getCache(); 6199 if (cache !is null) { 6200 print(cache.booleanValue ? "CACHE" : "NOCACHE"); 6201 println(); 6202 } 6203 6204 auto parallel = x.getParallel(); 6205 if (parallel !is null) { 6206 if (parallel.booleanValue) { 6207 print(ucase ? "PARALLEL" : "parallel"); 6208 Integer parallelValue = x.getParallelValue(); 6209 if (parallelValue !is null) { 6210 print(' '); 6211 print(parallelValue.intValue()); 6212 } 6213 } else { 6214 print(ucase ? "NOPARALLEL" : "noparallel"); 6215 } 6216 println(); 6217 } 6218 6219 if (x.isBuildImmediate()) { 6220 println(ucase ? "BUILD IMMEDIATE" : "build immediate"); 6221 } 6222 6223 if (x.isRefresh()) { 6224 print(ucase ? "REFRESH" : "refresh"); 6225 6226 if (x.isRefreshFast()) { 6227 print(ucase ? " FAST" : " fast"); 6228 } else if (x.isRefreshComlete()) { 6229 print(ucase ? " COMPLETE" : " complete"); 6230 } else if (x.isRefreshForce()) { 6231 print(ucase ? " FORCE" : " force"); 6232 } 6233 6234 if (x.isRefreshOnCommit()) { 6235 print(ucase ? " ON COMMIT" : " on commit"); 6236 } else if (x.isRefreshOnDemand()) { 6237 print(ucase ? " ON DEMAND" : " on demand"); 6238 } 6239 6240 println(); 6241 } 6242 6243 Boolean enableQueryRewrite = x.getEnableQueryRewrite(); 6244 if (enableQueryRewrite !is null) { 6245 if (enableQueryRewrite.booleanValue) { 6246 print(ucase ? "ENABLE QUERY REWRITE" : "enable query rewrite"); 6247 } else { 6248 print(ucase ? "DISABLE QUERY REWRITE" : "disable query rewrite"); 6249 } 6250 println(); 6251 } 6252 6253 println(ucase ? "AS" : "as"); 6254 x.getQuery().accept(this); 6255 return false; 6256 } 6257 6258 override bool visit(SQLCreateUserStatement x) { 6259 print0(ucase ? "CREATE USER " : "create user "); 6260 x.getUser().accept(this); 6261 print0(ucase ? " IDENTIFIED BY " : " identified by "); 6262 x.getPassword().accept(this); 6263 return false; 6264 } 6265 6266 override bool visit(SQLAlterFunctionStatement x) { 6267 print0(ucase ? "ALTER FUNCTION " : "alter function "); 6268 x.getName().accept(this); 6269 6270 if (x.isDebug()) { 6271 print0(ucase ? " DEBUG" : " debug"); 6272 } 6273 6274 if (x.isReuseSettings()) { 6275 print0(ucase ? " REUSE SETTINGS" : " reuse settings"); 6276 } 6277 6278 return false; 6279 } 6280 6281 override bool visit(SQLAlterTypeStatement x) { 6282 print0(ucase ? "ALTER TYPE " : "alter type "); 6283 x.getName().accept(this); 6284 6285 if (x.isCompile()) { 6286 print0(ucase ? " COMPILE" : " compile"); 6287 } 6288 6289 if (x.isBody()) { 6290 print0(ucase ? " BODY" : " body"); 6291 } 6292 6293 if (x.isDebug()) { 6294 print0(ucase ? " DEBUG" : " debug"); 6295 } 6296 6297 if (x.isReuseSettings()) { 6298 print0(ucase ? " REUSE SETTINGS" : " reuse settings"); 6299 } 6300 6301 return false; 6302 } 6303 6304 override 6305 bool visit(SQLIntervalExpr x) { 6306 print0(ucase ? "INTERVAL " : "interval "); 6307 SQLExpr value = x.getValue(); 6308 value.accept(this); 6309 6310 SQLIntervalUnit unit = x.getUnit(); 6311 if (unit.name.length != 0) { 6312 print(' '); 6313 print0(ucase ? unit.name : unit.name_lcase); 6314 } 6315 return false; 6316 } 6317 6318 Boolean getPrintStatementAfterSemi() { 6319 return printStatementAfterSemi; 6320 } 6321 6322 void setPrintStatementAfterSemi(Boolean printStatementAfterSemi) { 6323 this.printStatementAfterSemi = printStatementAfterSemi; 6324 } 6325 6326 override void config(VisitorFeature feature, bool state) { 6327 super.config(feature, state); 6328 if (feature == VisitorFeature.OutputUCase) { 6329 this.ucase = state; 6330 } else if (feature == VisitorFeature.OutputParameterized) { 6331 this.parameterized = state; 6332 } 6333 } 6334 6335 override void setFeatures(int features) { 6336 super.setFeatures(features); 6337 this.ucase = isEnabled(VisitorFeature.OutputUCase); 6338 this.parameterized = isEnabled(VisitorFeature.OutputParameterized); 6339 this.parameterizedQuesUnMergeInList = isEnabled(VisitorFeature.OutputParameterizedQuesUnMergeInList); 6340 } 6341 6342 /////////////// for oracle 6343 // bool visit(OracleCursorExpr x) { 6344 // print0(ucase ? "CURSOR(" : "cursor("); 6345 // this.indentCount++; 6346 // println(); 6347 // x.getQuery().accept(this); 6348 // this.indentCount--; 6349 // println(); 6350 // print(')'); 6351 // return false; 6352 // } 6353 6354 // bool visit(OracleDatetimeExpr x) { 6355 // x.getExpr().accept(this); 6356 // SQLExpr timeZone = x.getTimeZone(); 6357 6358 // if (cast(SQLIdentifierExpr)timeZone !is null) { 6359 // if ((cast(SQLIdentifierExpr) timeZone).getName().equalsIgnoreCase("LOCAL")) { 6360 // print0(ucase ? " AT LOCAL" : "alter session set "); 6361 // return false; 6362 // } 6363 // } 6364 6365 // print0(ucase ? " AT TIME ZONE " : " at time zone "); 6366 // timeZone.accept(this); 6367 6368 // return false; 6369 // } 6370 6371 ///////////// for odps & hive 6372 override 6373 bool visit(SQLLateralViewTableSource x) { 6374 x.getTableSource().accept(this); 6375 this.indentCount++; 6376 println(); 6377 print0(ucase ? "LATERAL VIEW " : "lateral view "); 6378 x.getMethod().accept(this); 6379 print(' '); 6380 print0(x.getAlias()); 6381 print0(ucase ? " AS " : " as "); 6382 printAndAccept!SQLName((x.getColumns()), ", "); 6383 this.indentCount--; 6384 return false; 6385 } 6386 6387 override 6388 bool visit(SQLShowErrorsStatement x) { 6389 print0(ucase ? "SHOW ERRORS" : "show errors"); 6390 return true; 6391 } 6392 6393 override 6394 bool visit(SQLAlterCharacter x) { 6395 print0(ucase ? "CHARACTER SET = " : "character set = "); 6396 x.getCharacterSet().accept(this); 6397 6398 if (x.getCollate() !is null) { 6399 print0(ucase ? ", COLLATE = " : ", collate = "); 6400 x.getCollate().accept(this); 6401 } 6402 6403 return false; 6404 } 6405 6406 override 6407 bool visit(SQLRecordDataType x) { 6408 print0(ucase ? "RECORD (" : "record ("); 6409 indentCount++; 6410 println(); 6411 List!SQLColumnDefinition columns = x.getColumns(); 6412 for (int i = 0; i < columns.size(); i++) { 6413 if (i != 0) { 6414 println(); 6415 } 6416 columns.get(i).accept(this); 6417 if (i != columns.size() - 1) { 6418 print0(", "); 6419 } 6420 } 6421 indentCount--; 6422 println(); 6423 print(')'); 6424 6425 return false; 6426 } 6427 6428 override 6429 bool visit(SQLExprStatement x) { 6430 x.getExpr().accept(this); 6431 return false; 6432 } 6433 6434 override 6435 bool visit(SQLBlockStatement x) { 6436 if (x.getParameters().size() != 0) { 6437 this.indentCount++; 6438 if (cast(SQLCreateProcedureStatement)x.getParent() !is null) { 6439 SQLCreateProcedureStatement procedureStatement = cast(SQLCreateProcedureStatement) x.getParent(); 6440 if (procedureStatement.isCreate()) { 6441 printIndent(); 6442 } 6443 } 6444 if (!( cast(SQLCreateProcedureStatement)x.getParent() !is null 6445 || cast(SQLCreateFunctionStatement)x.getParent() !is null 6446 /*|| cast(OracleFunctionDataType)x.getParent() !is null 6447 || cast(OracleProcedureDataType)x.getParent() !is null*/) 6448 ) { 6449 print0(ucase ? "DECLARE" : "declare"); 6450 println(); 6451 } 6452 6453 for (int i = 0, size = x.getParameters().size(); i < size; ++i) { 6454 if (i != 0) { 6455 println(); 6456 } 6457 SQLParameter param = x.getParameters().get(i); 6458 param.accept(this); 6459 print(';'); 6460 } 6461 6462 this.indentCount--; 6463 println(); 6464 } 6465 print0(ucase ? "BEGIN" : "begin"); 6466 this.indentCount++; 6467 6468 for (int i = 0, size = x.getStatementList().size(); i < size; ++i) { 6469 println(); 6470 SQLStatement stmt = x.getStatementList().get(i); 6471 stmt.accept(this); 6472 } 6473 this.indentCount--; 6474 6475 SQLStatement exception = x.getException(); 6476 if (exception !is null) { 6477 println(); 6478 exception.accept(this); 6479 } 6480 6481 println(); 6482 print0(ucase ? "END;" : "end;"); 6483 return false; 6484 } 6485 6486 override 6487 bool visit(SQLCreateProcedureStatement x) { 6488 bool create = x.isCreate(); 6489 if (!create) { 6490 print0(ucase ? "PROCEDURE " : "procedure "); 6491 } else if (x.isOrReplace()) { 6492 print0(ucase ? "CREATE OR REPLACE PROCEDURE " : "create or replace procedure "); 6493 } else { 6494 print0(ucase ? "CREATE PROCEDURE " : "create procedure "); 6495 } 6496 x.getName().accept(this); 6497 6498 int paramSize = x.getParameters().size(); 6499 6500 if (paramSize > 0) { 6501 print0(" ("); 6502 this.indentCount++; 6503 println(); 6504 6505 for (int i = 0; i < paramSize; ++i) { 6506 if (i != 0) { 6507 print0(", "); 6508 println(); 6509 } 6510 SQLParameter param = x.getParameters().get(i); 6511 param.accept(this); 6512 } 6513 6514 this.indentCount--; 6515 println(); 6516 print(')'); 6517 } 6518 6519 SQLName authid = x.getAuthid(); 6520 if (authid !is null) { 6521 print(ucase ? " AUTHID " : " authid "); 6522 authid.accept(this); 6523 } 6524 6525 SQLStatement block = x.getBlock(); 6526 string wrappedSource = x.getWrappedSource(); 6527 if (wrappedSource !is null) { 6528 print0(ucase ? " WRAPPED " : " wrapped "); 6529 print0(wrappedSource); 6530 } else { 6531 if (block !is null && !create) { 6532 println(); 6533 print("IS"); 6534 println(); 6535 } else { 6536 println(); 6537 if (cast(SQLBlockStatement)block !is null) { 6538 SQLBlockStatement blockStatement = cast(SQLBlockStatement) block; 6539 if (blockStatement.getParameters().size() > 0 || authid !is null) { 6540 println(ucase ? "AS" : "as"); 6541 } else { 6542 println(ucase ? "IS" : "is"); 6543 } 6544 } 6545 } 6546 6547 string javaCallSpec = x.getJavaCallSpec(); 6548 if (javaCallSpec !is null) { 6549 print0(ucase ? "LANGUAGE JAVA NAME '" : "language java name '"); 6550 print0(javaCallSpec); 6551 print('\''); 6552 return false; 6553 } 6554 } 6555 6556 bool afterSemi = false; 6557 if (block !is null) { 6558 block.accept(this); 6559 6560 if (cast(SQLBlockStatement)block !is null 6561 && (cast(SQLBlockStatement) block).getStatementList().size() > 0) { 6562 afterSemi = (cast(SQLBlockStatement) block).getStatementList().get(0).isAfterSemi(); 6563 } 6564 } 6565 6566 // if ((!afterSemi) && cast(OracleCreatePackageStatement)x.getParent() !is null) { 6567 // print(';'); 6568 // } 6569 return false; 6570 } 6571 6572 override bool visit(SQLExternalRecordFormat x) { 6573 if (x.getDelimitedBy() !is null) { 6574 println(); 6575 print0(ucase ? "RECORDS DELIMITED BY " : "records delimited by "); 6576 x.getDelimitedBy().accept(this); 6577 } 6578 6579 if (x.getTerminatedBy() !is null) { 6580 println(); 6581 print0(ucase ? "FIELDS TERMINATED BY " : "fields terminated by "); 6582 x.getTerminatedBy().accept(this); 6583 } 6584 6585 return false; 6586 } 6587 6588 override 6589 bool visit(SQLArrayDataType x) { 6590 print0(ucase ? "ARRAY<" : "array<"); 6591 x.getComponentType().accept(this); 6592 print('>'); 6593 return false; 6594 } 6595 6596 override 6597 bool visit(SQLMapDataType x) { 6598 print0(ucase ? "MAP<" : "map<"); 6599 x.getKeyType().accept(this); 6600 print0(", "); 6601 x.getValueType().accept(this); 6602 print('>'); 6603 return false; 6604 } 6605 6606 override 6607 bool visit(SQLStructDataType x) { 6608 print0(ucase ? "STRUCT<" : "struct<"); 6609 printAndAccept!(SQLStructDataType.Field)((x.getFields()), ", "); 6610 print('>'); 6611 return false; 6612 } 6613 6614 override 6615 bool visit(SQLStructDataType.Field x) { 6616 x.getName().accept(this); 6617 print(':'); 6618 x.getDataType().accept(this); 6619 print('>'); 6620 return false; 6621 } 6622 6623 override bool visit(SQLAlterTableRenameIndex x) { 6624 print0(ucase ? "RENAME INDEX " : "rename index "); 6625 x.getName().accept(this); 6626 print0(ucase ? " TO " : " to "); 6627 x.getTo().accept(this); 6628 return false; 6629 } 6630 6631 override 6632 bool visit(SQLAlterTableExchangePartition x) { 6633 print0(ucase ? "EXCHANGE PARTITION " : "exchange partition "); 6634 x.getPartition().accept(this); 6635 print0(ucase ? " WITH TABLE " : " with table "); 6636 x.getTable().accept(this); 6637 6638 auto validation = x.getValidation(); 6639 if (validation !is null) { 6640 if (validation.booleanValue) { 6641 print0(ucase ? " WITH VALIDATION" : " with validation"); 6642 } else { 6643 print0(ucase ? " WITHOUT VALIDATION" : " without validation"); 6644 } 6645 } 6646 6647 return false; 6648 } 6649 6650 override 6651 bool visit(SQLValuesExpr x) { 6652 print0(ucase ? "VALUES (" : "values ("); 6653 printAndAccept!SQLListExpr((x.getValues()), ", "); 6654 return false; 6655 } 6656 6657 override 6658 bool visit(SQLValuesTableSource x) { 6659 List!SQLName columns = x.getColumns(); 6660 6661 if (columns.size() > 0) { 6662 print('('); 6663 } 6664 print0(ucase ? "VALUES " : "values "); 6665 printAndAccept!SQLListExpr((x.getValues()), ", "); 6666 6667 if (columns.size() > 0) { 6668 print(") "); 6669 } 6670 6671 print0(ucase ? "AS " : "as "); 6672 print0(x.getAlias()); 6673 print0(" ("); 6674 printAndAccept!SQLName(columns, ", "); 6675 print(')'); 6676 6677 return false; 6678 } 6679 6680 override bool visit(SQLContainsExpr x) { 6681 SQLExpr expr = x.getExpr(); 6682 if (expr !is null) { 6683 printExpr(expr); 6684 print(' '); 6685 } 6686 6687 if (x.isNot()) { 6688 print0(ucase ? "NOT CONTAINS (" : " not contains ("); 6689 } else { 6690 print0(ucase ? "CONTAINS (" : " contains ("); 6691 } 6692 6693 List!SQLExpr list = x.getTargetList(); 6694 6695 bool printLn = false; 6696 if (list.size() > 5) { 6697 printLn = true; 6698 for (int i = 0, size = list.size(); i < size; ++i) { 6699 if (!(cast(SQLCharExpr)list.get(i) !is null)) { 6700 printLn = false; 6701 break; 6702 } 6703 } 6704 } 6705 6706 if (printLn) { 6707 this.indentCount++; 6708 println(); 6709 for (int i = 0, size = list.size(); i < size; ++i) { 6710 if (i != 0) { 6711 print0(", "); 6712 println(); 6713 } 6714 SQLExpr item = list.get(i); 6715 printExpr(item); 6716 } 6717 this.indentCount--; 6718 println(); 6719 } else { 6720 List!SQLExpr targetList = x.getTargetList(); 6721 for (int i = 0; i < targetList.size(); i++) { 6722 if (i != 0) { 6723 print0(", "); 6724 } 6725 printExpr(targetList.get(i)); 6726 } 6727 } 6728 6729 print(')'); 6730 return false; 6731 } 6732 6733 override bool visit(SQLRealExpr x) { 6734 float value = (cast(Float)(x.getValue())).floatValue; 6735 print0(ucase ? "REAL '" : "real '"); 6736 print(value); 6737 print('\''); 6738 6739 return false; 6740 } 6741 6742 override 6743 bool visit(SQLWindow x) { 6744 x.getName().accept(this); 6745 print0(ucase ? " AS " : " as "); 6746 x.getOver().accept(this); 6747 return false; 6748 } 6749 6750 override 6751 bool visit(SQLDumpStatement x) { 6752 List!SQLCommentHint headHints = x.getHeadHintsDirect(); 6753 if (headHints !is null) { 6754 foreach(SQLCommentHint hint ; headHints) { 6755 hint.accept(this); 6756 println(); 6757 } 6758 } 6759 6760 print0(ucase ? "DUMP DATA " : "dump data "); 6761 6762 6763 if (x.isOverwrite()) { 6764 print0(ucase ? "OVERWRITE " : "overwrite "); 6765 } 6766 6767 SQLExprTableSource into = x.getInto(); 6768 if (into !is null) { 6769 into.accept(this); 6770 } 6771 6772 x.getSelect().accept(this); 6773 return false; 6774 } 6775 6776 void print(float value) { 6777 if (this.appender is null) { 6778 return; 6779 } 6780 6781 if (cast(StringBuilder)appender !is null) { 6782 (cast(StringBuilder) appender).append(value); 6783 } else if (cast(StringBuilder)appender !is null) { 6784 (cast(StringBuilder) appender).append(value); 6785 } else { 6786 print0(to!string(value)); 6787 } 6788 } 6789 }