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.parser.SQLStatementParser; 17 18 import hunt.collection; 19 20 import hunt.sql.ast; 21 import hunt.sql.ast.expr; 22 import hunt.sql.ast.statement; 23 import hunt.sql.ast.statement.SQLCreateTriggerStatement; 24 // import hunt.sql.dialect.hive.ast.HiveInsert; 25 // import hunt.sql.dialect.hive.ast.HiveInsertStatement; 26 import hunt.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; 27 import hunt.sql.dialect.mysql.parser.MySqlExprParser; 28 // import hunt.sql.dialect.oracle.parser.OracleExprParser; 29 import hunt.sql.util.FnvHash; 30 import hunt.sql.util.DBType; 31 import hunt.sql.parser.SQLParser; 32 import hunt.sql.parser.SQLExprParser; 33 import hunt.sql.parser.SQLSelectListCache; 34 import hunt.sql.parser.SQLCreateTableParser; 35 import hunt.sql.parser.SQLSelectParser; 36 import hunt.sql.ast.statement.SQLInsertStatement; 37 import hunt.sql.parser.InsertColumnsCache; 38 import hunt.sql.parser.Lexer; 39 import hunt.sql.parser.Token; 40 import hunt.String; 41 import hunt.sql.parser.ParserException; 42 //import hunt.lang; 43 import hunt.sql.parser.SQLParserFeature; 44 import hunt.text; 45 import hunt.Boolean; 46 import hunt.Integer; 47 48 public class SQLStatementParser : SQLParser { 49 50 protected SQLExprParser exprParser; 51 protected bool parseCompleteValues = true; 52 protected int parseValuesSize = 3; 53 protected SQLSelectListCache selectListCache = null; 54 protected InsertColumnsCache insertColumnsCache = null; 55 56 public this(string sql){ 57 import std.stdio; 58 this(sql, null); 59 } 60 61 public this(string sql, string dbType){ 62 this(new SQLExprParser(sql, dbType)); 63 } 64 65 public this(SQLExprParser exprParser){ 66 super(exprParser.getLexer(), exprParser.getDbType()); 67 this.exprParser = exprParser; 68 } 69 70 protected this(Lexer lexer, string dbType){ 71 super(lexer, dbType); 72 } 73 74 public bool isKeepComments() { 75 return lexer.isKeepComments(); 76 } 77 78 public void setKeepComments(bool keepComments) { 79 this.lexer.setKeepComments(keepComments); 80 } 81 82 public SQLExprParser getExprParser() { 83 return exprParser; 84 } 85 86 public List!(SQLStatement) parseStatementList() { 87 List!(SQLStatement) statementList = new ArrayList!(SQLStatement)(); 88 parseStatementList(statementList, -1, null); 89 return statementList; 90 } 91 92 public List!(SQLStatement) parseStatementList(SQLObject parent) { 93 List!(SQLStatement) statementList = new ArrayList!(SQLStatement)(); 94 parseStatementList(statementList, -1, parent); 95 return statementList; 96 } 97 98 public void parseStatementList(List!(SQLStatement) statementList) { 99 parseStatementList(statementList, -1, null); 100 } 101 102 public void parseStatementList(List!(SQLStatement) statementList, int max) { 103 parseStatementList(statementList, max, null); 104 } 105 106 public void parseStatementList(List!(SQLStatement) statementList, int max, SQLObject parent) { 107 import std.stdio; 108 // writeln("#####"); 109 if ("select @@session.tx_read_only" == (lexer.text) 110 && lexer.token == Token.SELECT) { 111 SQLSelect select = new SQLSelect(); 112 MySqlSelectQueryBlock queryBlock = new MySqlSelectQueryBlock(); 113 queryBlock.addSelectItem(new SQLPropertyExpr(new SQLVariantRefExpr("@@session"), "tx_read_only")); 114 select.setQuery(queryBlock); 115 116 SQLSelectStatement stmt = new SQLSelectStatement(select); 117 statementList.add(stmt); 118 119 lexer.reset(29, '\u001A', Token.EOF); 120 return; 121 } 122 123 for (;;) { 124 // writeln("token : ",lexer.token); 125 if (max != -1) { 126 if (statementList.size() >= max) { 127 return; 128 } 129 } 130 131 switch (lexer.token) { 132 case Token.EOF: 133 case Token.END: 134 case Token.UNTIL: 135 case Token.ELSE: 136 case Token.WHEN: 137 if (lexer.isKeepComments() && lexer.hasComment() && statementList.size() > 0) { 138 SQLStatement stmt = statementList.get(statementList.size() - 1); 139 stmt.addAfterComment(lexer.readAndResetComments()); 140 } 141 return; 142 case Token.SEMI: { 143 int line0 = lexer.getLine(); 144 lexer.nextToken(); 145 int line1 = lexer.getLine(); 146 147 if(statementList.size() > 0) { 148 SQLStatement lastStmt = statementList.get(statementList.size() - 1); 149 lastStmt.setAfterSemi(true); 150 151 if (lexer.isKeepComments()) { 152 SQLStatement stmt = statementList.get(statementList.size() - 1); 153 if (line1 - line0 <= 1) { 154 stmt.addAfterComment(lexer.readAndResetComments()); 155 } 156 } 157 } 158 159 continue; 160 } 161 case Token.WITH: { 162 SQLStatement stmt = parseWith(); 163 stmt.setParent(parent); 164 statementList.add(stmt); 165 continue; 166 } 167 case Token.SELECT: { 168 SQLStatement stmt = parseSelect(); 169 stmt.setParent(parent); 170 statementList.add(stmt); 171 continue; 172 } 173 case Token.UPDATE: { 174 SQLStatement stmt = parseUpdateStatement(); 175 stmt.setParent(parent); 176 statementList.add(stmt); 177 continue; 178 } 179 case Token.CREATE: { 180 SQLStatement stmt = parseCreate(); 181 stmt.setParent(parent); 182 statementList.add(stmt); 183 continue; 184 } 185 case Token.INSERT: { 186 SQLStatement stmt = parseInsert(); 187 stmt.setParent(parent); 188 statementList.add(stmt); 189 continue; 190 } 191 case Token.DELETE: { 192 SQLStatement stmt = parseDeleteStatement(); 193 stmt.setParent(parent); 194 statementList.add(stmt); 195 continue; 196 } 197 case Token.EXPLAIN: { 198 SQLStatement stmt = parseExplain(); 199 stmt.setParent(parent); 200 statementList.add(stmt); 201 continue; 202 } 203 case Token.SET: { 204 SQLStatement stmt = parseSet(); 205 stmt.setParent(parent); 206 statementList.add(stmt); 207 continue; 208 } 209 case Token.ALTER: { 210 SQLStatement stmt = parseAlter(); 211 stmt.setParent(parent); 212 statementList.add(stmt); 213 continue; 214 } 215 case Token.TRUNCATE: { 216 SQLStatement stmt = parseTruncate(); 217 stmt.setParent(parent); 218 statementList.add(stmt); 219 continue; 220 } 221 case Token.USE: { 222 SQLStatement stmt = parseUse(); 223 stmt.setParent(parent); 224 statementList.add(stmt); 225 continue; 226 } 227 case Token.GRANT: { 228 SQLStatement stmt = parseGrant(); 229 stmt.setParent(parent); 230 statementList.add(stmt); 231 continue; 232 } 233 case Token.REVOKE: { 234 SQLStatement stmt = parseRevoke(); 235 stmt.setParent(parent); 236 statementList.add(stmt); 237 continue; 238 } 239 case Token.SHOW: { 240 SQLStatement stmt = parseShow(); 241 stmt.setParent(parent); 242 statementList.add(stmt); 243 continue; 244 } 245 case Token.MERGE: { 246 SQLStatement stmt = parseMerge(); 247 stmt.setParent(parent); 248 statementList.add(stmt); 249 continue; 250 } 251 case Token.REPEAT: { 252 SQLStatement stmt = parseRepeat(); 253 stmt.setParent(parent); 254 statementList.add(stmt); 255 continue; 256 } 257 case Token.DECLARE: { 258 SQLStatement stmt = parseDeclare(); 259 stmt.setParent(parent); 260 statementList.add(stmt); 261 continue; 262 } 263 case Token.WHILE: { 264 SQLStatement stmt = parseWhile(); 265 stmt.setParent(parent); 266 statementList.add(stmt); 267 continue; 268 } 269 case Token.IF: { 270 SQLStatement stmt = parseIf(); 271 stmt.setParent(parent); 272 statementList.add(stmt); 273 continue; 274 } 275 case Token.CASE: { 276 SQLStatement stmt = parseCase(); 277 stmt.setParent(parent); 278 statementList.add(stmt); 279 continue; 280 } 281 case Token.OPEN: { 282 SQLStatement stmt = parseOpen(); 283 stmt.setParent(parent); 284 statementList.add(stmt); 285 continue; 286 } 287 case Token.FETCH: { 288 SQLStatement stmt = parseFetch(); 289 stmt.setParent(parent); 290 statementList.add(stmt); 291 continue; 292 } 293 case Token.DROP: { 294 SQLStatement stmt = parseDrop(); 295 stmt.setParent(parent); 296 statementList.add(stmt); 297 continue; 298 } 299 case Token.COMMENT: { 300 if(DBType.MYSQL.opEquals(this.dbType)){//mysql 关键字 comment 没有这个语法,oracle才有 301 return; 302 } 303 SQLStatement stmt = parseComment(); 304 stmt.setParent(parent); 305 statementList.add(stmt); 306 continue; 307 } 308 case Token.KILL: { 309 SQLStatement stmt = parseKill(); 310 stmt.setParent(parent); 311 statementList.add(stmt); 312 continue; 313 } 314 case Token.CLOSE: { 315 SQLStatement stmt = parseClose(); 316 stmt.setParent(parent); 317 statementList.add(stmt); 318 continue; 319 } 320 case Token.RETURN: { 321 SQLStatement stmt = parseReturn(); 322 stmt.setParent(parent); 323 statementList.add(stmt); 324 continue; 325 } 326 case Token.UPSERT: { 327 SQLStatement stmt = parseUpsert(); 328 stmt.setParent(parent); 329 statementList.add(stmt); 330 continue; 331 } 332 case Token.LEAVE: { 333 SQLStatement stmt = parseLeave(); 334 stmt.setParent(parent); 335 statementList.add(stmt); 336 continue; 337 } 338 default: 339 break; 340 } 341 342 if (lexer.token == Token.LBRACE || lexer.identifierEquals("CALL")) { 343 SQLCallStatement stmt = parseCall(); 344 statementList.add(stmt); 345 continue; 346 } 347 348 349 if (lexer.identifierEquals("UPSERT")) { 350 SQLStatement stmt = parseUpsert(); 351 statementList.add(stmt); 352 continue; 353 } 354 355 if (lexer.identifierEquals("RENAME")) { 356 SQLStatement stmt = parseRename(); 357 statementList.add(stmt); 358 continue; 359 } 360 361 if (lexer.identifierEquals(FnvHash.Constants.RELEASE)) { 362 SQLStatement stmt = parseReleaseSavePoint(); 363 statementList.add(stmt); 364 continue; 365 } 366 367 if (lexer.identifierEquals(FnvHash.Constants.SAVEPOINT)) { 368 SQLStatement stmt = parseSavePoint(); 369 statementList.add(stmt); 370 continue; 371 } 372 373 if (lexer.identifierEquals(FnvHash.Constants.ROLLBACK)) { 374 SQLRollbackStatement stmt = parseRollback(); 375 statementList.add(stmt); 376 377 if (cast(SQLBlockStatement)(parent) !is null 378 && DBType.MYSQL.opEquals(dbType)) { 379 return; 380 } 381 382 continue; 383 } 384 385 if (lexer.identifierEquals(FnvHash.Constants.MERGE)) { 386 SQLStatement stmt = parseMerge(); 387 stmt.setParent(parent); 388 statementList.add(stmt); 389 continue; 390 } 391 392 if (lexer.identifierEquals("DUMP")) { 393 SQLStatement stmt = parseDump(); 394 statementList.add(stmt); 395 396 continue; 397 } 398 399 if (lexer.identifierEquals(FnvHash.Constants.COMMIT)) { 400 SQLStatement stmt = parseCommit(); 401 402 statementList.add(stmt); 403 404 if (cast(SQLBlockStatement)(parent) !is null 405 && DBType.MYSQL.opEquals(dbType)) { 406 return; 407 } 408 409 continue; 410 } 411 412 if (lexer.identifierEquals("RETURN")) { 413 SQLStatement stmt = parseReturn(); 414 statementList.add(stmt); 415 continue; 416 } 417 418 if (lexer.token == Token.LPAREN) { 419 char markChar = lexer.current(); 420 int markBp = lexer.bp(); 421 422 do { 423 lexer.nextToken(); 424 } while (lexer.token == Token.LPAREN); 425 426 if (lexer.token == Token.SELECT) { 427 lexer.reset(markBp, markChar, Token.LPAREN); 428 SQLStatement stmt = parseSelect(); 429 statementList.add(stmt); 430 continue; 431 } else { 432 throw new ParserException("TODO " ~ lexer.info()); 433 } 434 } 435 436 int size = statementList.size(); 437 if (parseStatementListDialect(statementList)) { 438 if (parent !is null) { 439 for (int i = size; i < statementList.size(); ++i) { 440 SQLStatement dialectStmt = statementList.get(i); 441 dialectStmt.setParent(parent); 442 } 443 } 444 445 continue; 446 } 447 448 // throw new ParserException("syntax error, " ~ lexer.token ~ " " 449 // + lexer.stringVal() ~ ", pos " 450 // + lexer.pos()); 451 //throw new ParserException("not supported." ~ lexer.info()); 452 printError(lexer.token); 453 } 454 } 455 456 public SQLStatement parseDump() { 457 SQLDumpStatement stmt = new SQLDumpStatement(); 458 acceptIdentifier("DUMP"); 459 acceptIdentifier("DATA"); 460 461 if (lexer.identifierEquals(FnvHash.Constants.OVERWRITE)) { 462 lexer.nextToken(); 463 stmt.setOverwrite(true); 464 } 465 466 if (lexer.token == Token.INTO) { 467 lexer.nextToken(); 468 stmt.setInto(this.exprParser.expr()); 469 } 470 471 SQLSelect select = createSQLSelectParser().select(); 472 stmt.setSelect(select); 473 return stmt; 474 } 475 476 477 public SQLStatement parseDrop() { 478 List!(string) beforeComments = null; 479 if (lexer.isKeepComments() && lexer.hasComment()) { 480 beforeComments = lexer.readAndResetComments(); 481 } 482 483 lexer.nextToken(); 484 485 SQLStatement stmt; 486 487 List!(SQLCommentHint) hints = null; 488 if (lexer.token == Token.HINT) { 489 hints = this.exprParser.parseHints(); 490 } 491 492 if (lexer.token == Token.TABLE || lexer.identifierEquals("TEMPORARY")) { 493 SQLDropTableStatement dropTable = parseDropTable(false); 494 if (hints !is null) { 495 dropTable.setHints(hints); 496 } 497 stmt = dropTable; 498 } else if (lexer.token == Token.USER) { 499 stmt = parseDropUser(); 500 } else if (lexer.token == Token.INDEX) { 501 stmt = parseDropIndex(); 502 } else if (lexer.token == Token.VIEW) { 503 stmt = parseDropView(false); 504 } else if (lexer.token == Token.TRIGGER) { 505 stmt = parseDropTrigger(false); 506 } else if (lexer.token == Token.DATABASE || lexer.token == Token.SCHEMA) { 507 stmt = parseDropDatabase(false); 508 } else if (lexer.token == Token.FUNCTION) { 509 stmt = parseDropFunction(false); 510 } else if (lexer.token == Token.TABLESPACE) { 511 stmt = parseDropTablespace(false); 512 513 } else if (lexer.token == Token.PROCEDURE) { 514 stmt = parseDropProcedure(false); 515 516 } else if (lexer.token == Token.SEQUENCE) { 517 stmt = parseDropSequence(false); 518 519 } else if (lexer.identifierEquals(FnvHash.Constants.EVENT)) { 520 stmt = parseDropEvent(); 521 522 } else if (lexer.identifierEquals(FnvHash.Constants.LOGFILE)) { 523 stmt = parseDropLogFileGroup(); 524 525 } else if (lexer.identifierEquals(FnvHash.Constants.SERVER)) { 526 stmt = parseDropServer(); 527 528 } else { 529 throw new ParserException("TODO " ~ lexer.info()); 530 } 531 532 if (beforeComments !is null) { 533 stmt.addBeforeComment(beforeComments); 534 } 535 return stmt; 536 } 537 538 protected SQLStatement parseDropServer() { 539 if (lexer.token == Token.DROP) { 540 lexer.nextToken(); 541 } 542 543 acceptIdentifier("SERVER"); 544 545 SQLDropServerStatement stmt = new SQLDropServerStatement(); 546 stmt.setDbType(dbType); 547 548 if (lexer.token == Token.IF) { 549 lexer.nextToken(); 550 accept(Token.EXISTS); 551 stmt.setIfExists(true); 552 } 553 554 SQLName name = this.exprParser.name(); 555 stmt.setName(name); 556 557 return stmt; 558 } 559 560 protected SQLStatement parseDropLogFileGroup() { 561 if (lexer.token == Token.DROP) { 562 lexer.nextToken(); 563 } 564 565 acceptIdentifier("LOGFILE"); 566 accept(Token.GROUP); 567 568 SQLDropLogFileGroupStatement stmt = new SQLDropLogFileGroupStatement(); 569 stmt.setDbType(dbType); 570 571 SQLName name = this.exprParser.name(); 572 stmt.setName(name); 573 574 if (lexer.identifierEquals(FnvHash.Constants.ENGINE)) { 575 lexer.nextToken(); 576 if (lexer.token == Token.EQ) { 577 lexer.nextToken(); 578 } 579 SQLExpr engine = this.exprParser.primary(); 580 stmt.setEngine(engine); 581 } 582 583 return stmt; 584 } 585 586 protected SQLStatement parseDropEvent() { 587 if (lexer.token == Token.DROP) { 588 lexer.nextToken(); 589 } 590 591 acceptIdentifier("EVENT"); 592 593 SQLDropEventStatement stmt = new SQLDropEventStatement(); 594 stmt.setDbType(dbType); 595 596 if (lexer.token == Token.IF) { 597 lexer.nextToken(); 598 accept(Token.EXISTS); 599 stmt.setIfExists(true); 600 } 601 602 SQLName name = this.exprParser.name(); 603 stmt.setName(name); 604 605 return stmt; 606 } 607 608 protected SQLStatement parseAlterFunction() { 609 throw new ParserException("TODO " ~ lexer.info()); 610 } 611 612 public SQLStatement parseKill() { 613 throw new ParserException("not supported. " ~ lexer.info()); 614 } 615 616 public SQLStatement parseCase() { 617 throw new ParserException("not supported. " ~ lexer.info()); 618 } 619 620 public SQLStatement parseIf() { 621 throw new ParserException("not supported. " ~ lexer.info()); 622 } 623 624 public SQLStatement parseWhile() { 625 throw new ParserException("not supported. " ~ lexer.info()); 626 } 627 628 public SQLStatement parseDeclare() { 629 throw new ParserException("not supported. " ~ lexer.info()); 630 } 631 632 public SQLStatement parseRepeat() { 633 throw new ParserException("not supported. " ~ lexer.info()); 634 } 635 636 public SQLStatement parseLeave() { 637 throw new ParserException("not supported. " ~ lexer.info()); 638 } 639 640 public SQLStatement parseReturn() { 641 if (lexer.token == Token.RETURN 642 || lexer.identifierEquals("RETURN")) { 643 lexer.nextToken(); 644 } 645 646 SQLReturnStatement stmt = new SQLReturnStatement(); 647 if (lexer.token != Token.SEMI) { 648 SQLExpr expr = this.exprParser.expr(); 649 stmt.setExpr(expr); 650 } 651 652 if (lexer.token == Token.SEMI) { 653 lexer.nextToken(); 654 stmt.setAfterSemi(true); 655 } 656 657 return stmt; 658 } 659 660 public SQLStatement parseUpsert() { 661 SQLInsertStatement insertStatement = new SQLInsertStatement(); 662 663 if (lexer.token == Token.UPSERT || lexer.identifierEquals("UPSERT")) { 664 lexer.nextToken(); 665 insertStatement.setUpsert(true); 666 } 667 668 parseInsert0(insertStatement); 669 return insertStatement; 670 } 671 672 public SQLRollbackStatement parseRollback() { 673 lexer.nextToken(); 674 675 if (lexer.identifierEquals("WORK")) { 676 lexer.nextToken(); 677 } 678 679 SQLRollbackStatement stmt = new SQLRollbackStatement(getDbType()); 680 681 if (lexer.token == Token.TO) { 682 lexer.nextToken(); 683 684 if (lexer.identifierEquals("SAVEPOINT") || lexer.token == Token.SAVEPOINT) { 685 lexer.nextToken(); 686 } 687 688 stmt.setTo(this.exprParser.name()); 689 } 690 return stmt; 691 } 692 693 public SQLStatement parseCommit() { 694 throw new ParserException("TODO " ~ lexer.info()); 695 } 696 697 public SQLStatement parseShow() { 698 throw new ParserException("TODO " ~ lexer.info()); 699 } 700 701 public SQLUseStatement parseUse() { 702 accept(Token.USE); 703 SQLUseStatement stmt = new SQLUseStatement(getDbType()); 704 stmt.setDatabase(this.exprParser.name()); 705 return stmt; 706 } 707 708 public SQLGrantStatement parseGrant() { 709 accept(Token.GRANT); 710 SQLGrantStatement stmt = new SQLGrantStatement(getDbType()); 711 712 parsePrivileages(stmt.getPrivileges(), stmt); 713 714 if (lexer.token == Token.ON) { 715 lexer.nextToken(); 716 717 if (lexer.token == Token.PROCEDURE) { 718 lexer.nextToken(); 719 stmt.setObjectType(SQLObjectType.PROCEDURE); 720 } else if (lexer.token == Token.FUNCTION) { 721 lexer.nextToken(); 722 stmt.setObjectType(SQLObjectType.FUNCTION); 723 } else if (lexer.token == Token.TABLE) { 724 lexer.nextToken(); 725 stmt.setObjectType(SQLObjectType.TABLE); 726 } else if (lexer.token == Token.USER) { 727 lexer.nextToken(); 728 stmt.setObjectType(SQLObjectType.USER); 729 } else if (lexer.token == Token.DATABASE) { 730 lexer.nextToken(); 731 stmt.setObjectType(SQLObjectType.DATABASE); 732 } 733 734 if (stmt.getObjectType().name.length != 0 && lexer.token == Token.COLONCOLON) { 735 lexer.nextToken(); // sql server 736 } 737 738 SQLExpr expr; 739 if (lexer.token == Token.DOT) { 740 expr = new SQLAllColumnExpr(); 741 lexer.nextToken(); 742 } else { 743 expr = this.exprParser.expr(); 744 } 745 746 if (stmt.getObjectType() == SQLObjectType.TABLE || stmt.getObjectType().name.length == 0) { 747 stmt.setOn(new SQLExprTableSource(expr)); 748 } else { 749 stmt.setOn(expr); 750 } 751 } 752 753 if (lexer.token == Token.TO) { 754 lexer.nextToken(); 755 stmt.setTo(this.exprParser.expr()); 756 } 757 758 if (lexer.token == Token.WITH) { 759 lexer.nextToken(); 760 761 if (lexer.token == Token.GRANT) { 762 lexer.nextToken(); 763 acceptIdentifier("OPTION"); 764 } 765 766 for (;;) { 767 if (lexer.identifierEquals("MAX_QUERIES_PER_HOUR")) { 768 lexer.nextToken(); 769 stmt.setMaxQueriesPerHour(this.exprParser.primary()); 770 continue; 771 } 772 773 if (lexer.identifierEquals("MAX_UPDATES_PER_HOUR")) { 774 lexer.nextToken(); 775 stmt.setMaxUpdatesPerHour(this.exprParser.primary()); 776 continue; 777 } 778 779 if (lexer.identifierEquals("MAX_CONNECTIONS_PER_HOUR")) { 780 lexer.nextToken(); 781 stmt.setMaxConnectionsPerHour(this.exprParser.primary()); 782 continue; 783 } 784 785 if (lexer.identifierEquals("MAX_USER_CONNECTIONS")) { 786 lexer.nextToken(); 787 stmt.setMaxUserConnections(this.exprParser.primary()); 788 continue; 789 } 790 791 break; 792 } 793 } 794 795 if (lexer.identifierEquals("ADMIN")) { 796 lexer.nextToken(); 797 acceptIdentifier("OPTION"); 798 stmt.setAdminOption(true); 799 } 800 801 if (lexer.token == Token.IDENTIFIED) { 802 lexer.nextToken(); 803 accept(Token.BY); 804 805 if (lexer.identifierEquals("PASSWORD")) { 806 lexer.nextToken(); 807 string password = lexer.stringVal(); 808 accept(Token.LITERAL_CHARS); 809 stmt.setIdentifiedByPassword(password); 810 } else { 811 stmt.setIdentifiedBy(this.exprParser.expr()); 812 } 813 } 814 815 if (lexer.token == Token.WITH) { 816 lexer.nextToken(); 817 if (lexer.token == Token.GRANT) { 818 lexer.nextToken(); 819 acceptIdentifier("OPTION"); 820 stmt.setWithGrantOption(true); 821 } 822 } 823 824 return stmt; 825 } 826 827 protected void parsePrivileages(List!(SQLExpr) privileges, SQLObject parent) { 828 for (;;) { 829 string privilege = null; 830 if (lexer.token == Token.ALL) { 831 lexer.nextToken(); 832 if (lexer.identifierEquals("PRIVILEGES")) { 833 privilege = "ALL PRIVILEGES"; 834 lexer.nextToken(); 835 } else { 836 privilege = "ALL"; 837 } 838 } else if (lexer.token == Token.SELECT) { 839 privilege = "SELECT"; 840 lexer.nextToken(); 841 } else if (lexer.token == Token.UPDATE) { 842 privilege = "UPDATE"; 843 lexer.nextToken(); 844 } else if (lexer.token == Token.DELETE) { 845 privilege = "DELETE"; 846 lexer.nextToken(); 847 } else if (lexer.token == Token.INSERT) { 848 privilege = "INSERT"; 849 lexer.nextToken(); 850 } else if (lexer.token == Token.INDEX) { 851 lexer.nextToken(); 852 privilege = "INDEX"; 853 } else if (lexer.token == Token.TRIGGER) { 854 lexer.nextToken(); 855 privilege = "TRIGGER"; 856 } else if (lexer.token == Token.REFERENCES) { 857 privilege = "REFERENCES"; 858 lexer.nextToken(); 859 } else if (lexer.token == Token.CREATE) { 860 lexer.nextToken(); 861 862 if (lexer.token == Token.TABLE) { 863 privilege = "CREATE TABLE"; 864 lexer.nextToken(); 865 } else if (lexer.token == Token.SESSION) { 866 privilege = "CREATE SESSION"; 867 lexer.nextToken(); 868 } else if (lexer.token == Token.TABLESPACE) { 869 privilege = "CREATE TABLESPACE"; 870 lexer.nextToken(); 871 } else if (lexer.token == Token.USER) { 872 privilege = "CREATE USER"; 873 lexer.nextToken(); 874 } else if (lexer.token == Token.VIEW) { 875 privilege = "CREATE VIEW"; 876 lexer.nextToken(); 877 } else if (lexer.token == Token.PROCEDURE) { 878 privilege = "CREATE PROCEDURE"; 879 lexer.nextToken(); 880 } else if (lexer.token == Token.SEQUENCE) { 881 privilege = "CREATE SEQUENCE"; 882 lexer.nextToken(); 883 } else if (lexer.token == Token.ANY) { 884 lexer.nextToken(); 885 886 if (lexer.token == Token.TABLE) { 887 lexer.nextToken(); 888 privilege = "CREATE ANY TABLE"; 889 } else if (lexer.identifierEquals("MATERIALIZED")) { 890 lexer.nextToken(); 891 accept(Token.VIEW); 892 privilege = "CREATE ANY MATERIALIZED VIEW"; 893 } else { 894 throw new ParserException("TODO : " ~ lexer.token ~ " " ~ lexer.stringVal()); 895 } 896 } else if (lexer.identifierEquals("SYNONYM")) { 897 privilege = "CREATE SYNONYM"; 898 lexer.nextToken(); 899 } else if (lexer.identifierEquals("ROUTINE")) { 900 privilege = "CREATE ROUTINE"; 901 lexer.nextToken(); 902 } else if (lexer.identifierEquals("TEMPORARY")) { 903 lexer.nextToken(); 904 accept(Token.TABLE); 905 privilege = "CREATE TEMPORARY TABLE"; 906 } else if (lexer.token == Token.ON) { 907 privilege = "CREATE"; 908 } else { 909 throw new ParserException("TODO : " ~ lexer.token ~ " " ~ lexer.stringVal()); 910 } 911 } else if (lexer.token == Token.ALTER) { 912 lexer.nextToken(); 913 if (lexer.token == Token.TABLE) { 914 privilege = "ALTER TABLE"; 915 lexer.nextToken(); 916 } else if (lexer.token == Token.SESSION) { 917 privilege = "ALTER SESSION"; 918 lexer.nextToken(); 919 } else if (lexer.identifierEquals(FnvHash.Constants.ROUTINE)) { 920 privilege = "ALTER ROUTINE"; 921 lexer.nextToken(); 922 } else if (lexer.token == Token.ANY) { 923 lexer.nextToken(); 924 925 if (lexer.token == Token.TABLE) { 926 lexer.nextToken(); 927 privilege = "ALTER ANY TABLE"; 928 } else if (lexer.identifierEquals("MATERIALIZED")) { 929 lexer.nextToken(); 930 accept(Token.VIEW); 931 privilege = "ALTER ANY MATERIALIZED VIEW"; 932 } else { 933 throw new ParserException("TODO : " ~ lexer.token ~ " " ~ lexer.stringVal()); 934 } 935 } else if (lexer.token == Token.ON) { 936 privilege = "ALTER"; 937 } else { 938 throw new ParserException("TODO : " ~ lexer.token ~ " " ~ lexer.stringVal()); 939 } 940 } else if (lexer.token == Token.DROP) { 941 lexer.nextToken(); 942 if (lexer.token == Token.DROP) { 943 privilege = "DROP TABLE"; 944 lexer.nextToken(); 945 } else if (lexer.token == Token.SESSION) { 946 privilege = "DROP SESSION"; 947 lexer.nextToken(); 948 } else if (lexer.token == Token.ANY) { 949 lexer.nextToken(); 950 951 if (lexer.token == Token.TABLE) { 952 lexer.nextToken(); 953 privilege = "DROP ANY TABLE"; 954 } else if (lexer.identifierEquals("MATERIALIZED")) { 955 lexer.nextToken(); 956 accept(Token.VIEW); 957 privilege = "DROP ANY MATERIALIZED VIEW"; 958 } else { 959 throw new ParserException("TODO : " ~ lexer.token ~ " " ~ lexer.stringVal()); 960 } 961 } else { 962 privilege = "DROP"; 963 } 964 } else if (lexer.identifierEquals("USAGE")) { 965 privilege = "USAGE"; 966 lexer.nextToken(); 967 } else if (lexer.identifierEquals("EXECUTE")) { 968 privilege = "EXECUTE"; 969 lexer.nextToken(); 970 } else if (lexer.identifierEquals("PROXY")) { 971 privilege = "PROXY"; 972 lexer.nextToken(); 973 } else if (lexer.identifierEquals("QUERY")) { 974 lexer.nextToken(); 975 acceptIdentifier("REWRITE"); 976 privilege = "QUERY REWRITE"; 977 } else if (lexer.identifierEquals("GLOBAL")) { 978 lexer.nextToken(); 979 acceptIdentifier("QUERY"); 980 acceptIdentifier("REWRITE"); 981 privilege = "GLOBAL QUERY REWRITE"; 982 } else if (lexer.identifierEquals("INHERIT")) { 983 lexer.nextToken(); 984 acceptIdentifier("PRIVILEGES"); 985 privilege = "INHERIT PRIVILEGES"; 986 } else if (lexer.identifierEquals("EVENT")) { 987 lexer.nextToken(); 988 privilege = "EVENT"; 989 } else if (lexer.identifierEquals("FILE")) { 990 lexer.nextToken(); 991 privilege = "FILE"; 992 } else if (lexer.token == Token.GRANT) { 993 lexer.nextToken(); 994 acceptIdentifier("OPTION"); 995 privilege = "GRANT OPTION"; 996 } else if (lexer.token == Token.LOCK) { 997 lexer.nextToken(); 998 acceptIdentifier("TABLES"); 999 privilege = "LOCK TABLES"; 1000 } else if (lexer.identifierEquals("PROCESS")) { 1001 lexer.nextToken(); 1002 privilege = "PROCESS"; 1003 } else if (lexer.identifierEquals("RELOAD")) { 1004 lexer.nextToken(); 1005 privilege = "RELOAD"; 1006 } else if (lexer.identifierEquals("RESOURCE")) { 1007 lexer.nextToken(); 1008 privilege = "RESOURCE"; 1009 } else if (lexer.token == Token.CONNECT) { 1010 lexer.nextToken(); 1011 privilege = "CONNECT"; 1012 } else if (lexer.identifierEquals("REPLICATION")) { 1013 lexer.nextToken(); 1014 if (lexer.identifierEquals("SLAVE")) { 1015 lexer.nextToken(); 1016 privilege = "REPLICATION SLAVE"; 1017 } else { 1018 acceptIdentifier("CLIENT"); 1019 privilege = "REPLICATION CLIENT"; 1020 } 1021 } else if (lexer.token == Token.SHOW) { 1022 lexer.nextToken(); 1023 1024 if (lexer.token == Token.VIEW) { 1025 lexer.nextToken(); 1026 privilege = "SHOW VIEW"; 1027 } else { 1028 acceptIdentifier("DATABASES"); 1029 privilege = "SHOW DATABASES"; 1030 } 1031 } else if (lexer.identifierEquals("SHUTDOWN")) { 1032 lexer.nextToken(); 1033 privilege = "SHUTDOWN"; 1034 } else if (lexer.identifierEquals("SUPER")) { 1035 lexer.nextToken(); 1036 privilege = "SUPER"; 1037 1038 } else if (lexer.identifierEquals("CONTROL")) { // sqlserver 1039 lexer.nextToken(); 1040 privilege = "CONTROL"; 1041 } else if (lexer.identifierEquals("IMPERSONATE")) { // sqlserver 1042 lexer.nextToken(); 1043 privilege = "IMPERSONATE"; 1044 } 1045 1046 if (privilege !is null) { 1047 SQLExpr expr = new SQLIdentifierExpr(privilege); 1048 1049 if (lexer.token == Token.LPAREN) { 1050 expr = this.exprParser.primaryRest(expr); 1051 } 1052 1053 expr.setParent(parent); 1054 privileges.add(expr); 1055 } 1056 1057 if (lexer.token == Token.COMMA) { 1058 lexer.nextToken(); 1059 continue; 1060 } 1061 break; 1062 } 1063 } 1064 1065 public SQLRevokeStatement parseRevoke() { 1066 accept(Token.REVOKE); 1067 1068 SQLRevokeStatement stmt = new SQLRevokeStatement(getDbType()); 1069 1070 parsePrivileages(stmt.getPrivileges(), stmt); 1071 1072 if (lexer.token == Token.ON) { 1073 lexer.nextToken(); 1074 1075 if (lexer.token == Token.PROCEDURE) { 1076 lexer.nextToken(); 1077 stmt.setObjectType(SQLObjectType.PROCEDURE); 1078 } else if (lexer.token == Token.FUNCTION) { 1079 lexer.nextToken(); 1080 stmt.setObjectType(SQLObjectType.FUNCTION); 1081 } else if (lexer.token == Token.TABLE) { 1082 lexer.nextToken(); 1083 stmt.setObjectType(SQLObjectType.TABLE); 1084 } else if (lexer.token == Token.USER) { 1085 lexer.nextToken(); 1086 stmt.setObjectType(SQLObjectType.USER); 1087 } 1088 1089 SQLExpr expr = this.exprParser.expr(); 1090 if (stmt.getObjectType() == SQLObjectType.TABLE || stmt.getObjectType().name.length == 0) { 1091 stmt.setOn(new SQLExprTableSource(expr)); 1092 } else { 1093 stmt.setOn(expr); 1094 } 1095 } 1096 1097 if (lexer.token == Token.FROM) { 1098 lexer.nextToken(); 1099 stmt.setFrom(this.exprParser.expr()); 1100 } 1101 1102 return stmt; 1103 } 1104 1105 public SQLStatement parseSavePoint() { 1106 acceptIdentifier("SAVEPOINT"); 1107 SQLSavePointStatement stmt = new SQLSavePointStatement(getDbType()); 1108 stmt.setName(this.exprParser.name()); 1109 return stmt; 1110 } 1111 1112 public SQLStatement parseReleaseSavePoint() { 1113 acceptIdentifier("RELEASE"); 1114 acceptIdentifier("SAVEPOINT"); 1115 SQLReleaseSavePointStatement stmt = new SQLReleaseSavePointStatement(getDbType()); 1116 stmt.setName(this.exprParser.name()); 1117 return stmt; 1118 } 1119 1120 public SQLStatement parseAlter() { 1121 accept(Token.ALTER); 1122 1123 if (lexer.token == Token.TABLE) { 1124 lexer.nextToken(); 1125 1126 SQLAlterTableStatement stmt = new SQLAlterTableStatement(getDbType()); 1127 stmt.setName(this.exprParser.name()); 1128 1129 for (;;) { 1130 if (lexer.token == Token.DROP) { 1131 parseAlterDrop(stmt); 1132 } else if (lexer.identifierEquals("ADD")) { 1133 lexer.nextToken(); 1134 1135 bool ifNotExists = false; 1136 1137 if (lexer.token == Token.IF) { 1138 lexer.nextToken(); 1139 accept(Token.NOT); 1140 accept(Token.EXISTS); 1141 ifNotExists = true; 1142 } 1143 1144 if (lexer.token == Token.PRIMARY) { 1145 SQLPrimaryKey primaryKey = this.exprParser.parsePrimaryKey(); 1146 SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(primaryKey); 1147 stmt.addItem(item); 1148 } else if (lexer.token == Token.IDENTIFIER) { 1149 SQLAlterTableAddColumn item = parseAlterTableAddColumn(); 1150 stmt.addItem(item); 1151 } else if (lexer.token == Token.COLUMN) { 1152 lexer.nextToken(); 1153 SQLAlterTableAddColumn item = parseAlterTableAddColumn(); 1154 stmt.addItem(item); 1155 } else if (lexer.token == Token.CHECK) { 1156 SQLCheck check = this.exprParser.parseCheck(); 1157 SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(check); 1158 stmt.addItem(item); 1159 } else if (lexer.token == Token.CONSTRAINT) { 1160 SQLConstraint constraint = this.exprParser.parseConstaint(); 1161 SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(constraint); 1162 stmt.addItem(item); 1163 } else if (lexer.token == Token.FOREIGN) { 1164 SQLConstraint constraint = this.exprParser.parseForeignKey(); 1165 SQLAlterTableAddConstraint item = new SQLAlterTableAddConstraint(constraint); 1166 stmt.addItem(item); 1167 } else if (lexer.token == Token.PARTITION) { 1168 lexer.nextToken(); 1169 SQLAlterTableAddPartition addPartition = new SQLAlterTableAddPartition(); 1170 1171 addPartition.setIfNotExists(ifNotExists); 1172 1173 accept(Token.LPAREN); 1174 1175 parseAssignItems(cast(List!SQLAssignItem)(addPartition.getPartitions()), cast(SQLObject)addPartition); 1176 1177 accept(Token.RPAREN); 1178 1179 stmt.addItem(addPartition); 1180 } else { 1181 throw new ParserException("TODO " ~ lexer.info()); 1182 } 1183 } else if (lexer.token == Token.DISABLE) { 1184 lexer.nextToken(); 1185 1186 if (lexer.token == Token.CONSTRAINT) { 1187 lexer.nextToken(); 1188 SQLAlterTableDisableConstraint item = new SQLAlterTableDisableConstraint(); 1189 item.setConstraintName(this.exprParser.name()); 1190 stmt.addItem(item); 1191 } else if (lexer.identifierEquals("LIFECYCLE")) { 1192 lexer.nextToken(); 1193 SQLAlterTableDisableLifecycle item = new SQLAlterTableDisableLifecycle(); 1194 stmt.addItem(item); 1195 } else { 1196 acceptIdentifier("KEYS"); 1197 SQLAlterTableDisableKeys item = new SQLAlterTableDisableKeys(); 1198 stmt.addItem(item); 1199 } 1200 } else if (lexer.token == Token.ENABLE) { 1201 lexer.nextToken(); 1202 if (lexer.token == Token.CONSTRAINT) { 1203 lexer.nextToken(); 1204 SQLAlterTableEnableConstraint item = new SQLAlterTableEnableConstraint(); 1205 item.setConstraintName(this.exprParser.name()); 1206 stmt.addItem(item); 1207 } else if (lexer.identifierEquals("LIFECYCLE")) { 1208 lexer.nextToken(); 1209 SQLAlterTableEnableLifecycle item = new SQLAlterTableEnableLifecycle(); 1210 stmt.addItem(item); 1211 } else { 1212 acceptIdentifier("KEYS"); 1213 SQLAlterTableEnableKeys item = new SQLAlterTableEnableKeys(); 1214 stmt.addItem(item); 1215 } 1216 } else if (lexer.token == Token.ALTER) { 1217 lexer.nextToken(); 1218 if (lexer.token == Token.COLUMN) { 1219 SQLAlterTableAlterColumn alterColumn = parseAlterColumn(); 1220 stmt.addItem(alterColumn); 1221 } else if (lexer.token == Token.LITERAL_ALIAS) { 1222 SQLAlterTableAlterColumn alterColumn = parseAlterColumn(); 1223 stmt.addItem(alterColumn); 1224 } else { 1225 throw new ParserException("TODO " ~ lexer.info()); 1226 } 1227 } else if (lexer.identifierEquals("CHANGE")) { 1228 lexer.nextToken(); 1229 accept(Token.COLUMN); 1230 SQLName columnName = this.exprParser.name(); 1231 1232 if (lexer.identifierEquals("RENAME")) { 1233 lexer.nextToken(); 1234 accept(Token.TO); 1235 SQLName toName = this.exprParser.name(); 1236 SQLAlterTableRenameColumn renameColumn = new SQLAlterTableRenameColumn(); 1237 1238 renameColumn.setColumn(columnName); 1239 renameColumn.setTo(toName); 1240 1241 stmt.addItem(renameColumn); 1242 } else if (lexer.token == Token.COMMENT) { 1243 lexer.nextToken(); 1244 1245 SQLExpr comment; 1246 if (lexer.token == Token.LITERAL_ALIAS) { 1247 string _alias = lexer.stringVal(); 1248 if (_alias.length > 2 && charAt(_alias, 0) == '"' && charAt(_alias, _alias.length - 1) == '"') { 1249 _alias = _alias.substring(1, cast(int)(_alias.length - 1)); 1250 } 1251 comment = new SQLCharExpr(_alias); 1252 lexer.nextToken(); 1253 } else { 1254 comment = this.exprParser.primary(); 1255 } 1256 1257 SQLColumnDefinition column = new SQLColumnDefinition(); 1258 column.setDbType(dbType); 1259 column.setName(columnName); 1260 column.setComment(comment); 1261 1262 SQLAlterTableAlterColumn changeColumn = new SQLAlterTableAlterColumn(); 1263 1264 changeColumn.setColumn(column); 1265 1266 stmt.addItem(changeColumn); 1267 } else { 1268 SQLColumnDefinition column = this.exprParser.parseColumn(); 1269 1270 SQLAlterTableAlterColumn alterColumn = new SQLAlterTableAlterColumn(); 1271 alterColumn.setColumn(column); 1272 alterColumn.setOriginColumn(columnName); 1273 stmt.addItem(alterColumn); 1274 } 1275 } else if (lexer.token == Token.WITH) { 1276 lexer.nextToken(); 1277 acceptIdentifier("NOCHECK"); 1278 acceptIdentifier("ADD"); 1279 SQLConstraint check = this.exprParser.parseConstaint(); 1280 1281 SQLAlterTableAddConstraint addCheck = new SQLAlterTableAddConstraint(); 1282 addCheck.setWithNoCheck(true); 1283 addCheck.setConstraint(check); 1284 stmt.addItem(addCheck); 1285 } else if (lexer.identifierEquals("RENAME")) { 1286 stmt.addItem(parseAlterTableRename()); 1287 } else if (lexer.token == Token.SET) { 1288 lexer.nextToken(); 1289 1290 if (lexer.token == Token.COMMENT) { 1291 lexer.nextToken(); 1292 SQLAlterTableSetComment setComment = new SQLAlterTableSetComment(); 1293 setComment.setComment(this.exprParser.primary()); 1294 stmt.addItem(setComment); 1295 } else if (lexer.identifierEquals("LIFECYCLE")) { 1296 lexer.nextToken(); 1297 SQLAlterTableSetLifecycle setLifecycle = new SQLAlterTableSetLifecycle(); 1298 setLifecycle.setLifecycle(this.exprParser.primary()); 1299 stmt.addItem(setLifecycle); 1300 } else { 1301 throw new ParserException("TODO " ~ lexer.info()); 1302 } 1303 } else if (lexer.token == Token.PARTITION) { 1304 lexer.nextToken(); 1305 1306 SQLAlterTableRenamePartition renamePartition = new SQLAlterTableRenamePartition(); 1307 1308 accept(Token.LPAREN); 1309 1310 parseAssignItems(renamePartition.getPartition(), renamePartition); 1311 1312 accept(Token.RPAREN); 1313 1314 if (lexer.token == Token.ENABLE) { 1315 lexer.nextToken(); 1316 if (lexer.identifierEquals("LIFECYCLE")) { 1317 lexer.nextToken(); 1318 } 1319 1320 SQLAlterTableEnableLifecycle enableLifeCycle = new SQLAlterTableEnableLifecycle(); 1321 foreach(SQLAssignItem condition ; renamePartition.getPartition()) { 1322 enableLifeCycle.getPartition().add(condition); 1323 condition.setParent(enableLifeCycle); 1324 } 1325 stmt.addItem(enableLifeCycle); 1326 1327 continue; 1328 } 1329 1330 if (lexer.token == Token.DISABLE) { 1331 lexer.nextToken(); 1332 if (lexer.identifierEquals("LIFECYCLE")) { 1333 lexer.nextToken(); 1334 } 1335 1336 SQLAlterTableDisableLifecycle disableLifeCycle = new SQLAlterTableDisableLifecycle(); 1337 foreach(SQLAssignItem condition ; renamePartition.getPartition()) { 1338 disableLifeCycle.getPartition().add(condition); 1339 condition.setParent(disableLifeCycle); 1340 } 1341 stmt.addItem(disableLifeCycle); 1342 1343 continue; 1344 } 1345 1346 acceptIdentifier("RENAME"); 1347 accept(Token.TO); 1348 accept(Token.PARTITION); 1349 1350 accept(Token.LPAREN); 1351 1352 parseAssignItems(renamePartition.getTo(), renamePartition); 1353 1354 accept(Token.RPAREN); 1355 1356 stmt.addItem(renamePartition); 1357 } else if (lexer.identifierEquals("TOUCH")) { 1358 lexer.nextToken(); 1359 SQLAlterTableTouch item = new SQLAlterTableTouch(); 1360 1361 if (lexer.token == Token.PARTITION) { 1362 lexer.nextToken(); 1363 1364 accept(Token.LPAREN); 1365 parseAssignItems(item.getPartition(), item); 1366 accept(Token.RPAREN); 1367 } 1368 1369 stmt.addItem(item); 1370 } else if (DBType.ODPS.opEquals(dbType) && lexer.identifierEquals("MERGE")) { 1371 lexer.nextToken(); 1372 acceptIdentifier("SMALLFILES"); 1373 stmt.setMergeSmallFiles(true); 1374 } else { 1375 break; 1376 } 1377 } 1378 1379 return stmt; 1380 } else if (lexer.token == Token.VIEW) { 1381 lexer.nextToken(); 1382 SQLName viewName = this.exprParser.name(); 1383 1384 if (lexer.identifierEquals("RENAME")) { 1385 lexer.nextToken(); 1386 accept(Token.TO); 1387 1388 SQLAlterViewRenameStatement stmt = new SQLAlterViewRenameStatement(); 1389 stmt.setName(viewName); 1390 1391 SQLName newName = this.exprParser.name(); 1392 1393 stmt.setTo(newName); 1394 1395 return stmt; 1396 } 1397 throw new ParserException("TODO " ~ lexer.info()); 1398 } 1399 throw new ParserException("TODO " ~ lexer.info()); 1400 } 1401 1402 protected SQLAlterTableItem parseAlterTableRename() { 1403 acceptIdentifier("RENAME"); 1404 1405 if (lexer.token == Token.COLUMN) { 1406 lexer.nextToken(); 1407 SQLAlterTableRenameColumn renameColumn = new SQLAlterTableRenameColumn(); 1408 renameColumn.setColumn(this.exprParser.name()); 1409 accept(Token.TO); 1410 renameColumn.setTo(this.exprParser.name()); 1411 return renameColumn; 1412 } 1413 1414 if (lexer.token == Token.TO) { 1415 lexer.nextToken(); 1416 SQLAlterTableRename item = new SQLAlterTableRename(); 1417 item.setTo(this.exprParser.name()); 1418 return item; 1419 } 1420 1421 throw new ParserException("TODO " ~ lexer.info()); 1422 } 1423 1424 protected SQLAlterTableAlterColumn parseAlterColumn() { 1425 lexer.nextToken(); 1426 SQLColumnDefinition column = this.exprParser.parseColumn(); 1427 1428 SQLAlterTableAlterColumn alterColumn = new SQLAlterTableAlterColumn(); 1429 alterColumn.setColumn(column); 1430 return alterColumn; 1431 } 1432 1433 public void parseAlterDrop(SQLAlterTableStatement stmt) { 1434 lexer.nextToken(); 1435 1436 bool ifExists = false; 1437 1438 if (lexer.token == Token.IF) { 1439 lexer.nextToken(); 1440 1441 accept(Token.EXISTS); 1442 ifExists = true; 1443 } 1444 1445 if (lexer.token == Token.CONSTRAINT) { 1446 lexer.nextToken(); 1447 SQLAlterTableDropConstraint item = new SQLAlterTableDropConstraint(); 1448 item.setConstraintName(this.exprParser.name()); 1449 stmt.addItem(item); 1450 } else if (lexer.token == Token.COLUMN) { 1451 lexer.nextToken(); 1452 SQLAlterTableDropColumnItem item = new SQLAlterTableDropColumnItem(); 1453 this.exprParser.names(item.getColumns()); 1454 1455 if (lexer.token == Token.CASCADE) { 1456 item.setCascade(true); 1457 lexer.nextToken(); 1458 } 1459 1460 stmt.addItem(item); 1461 } else if (lexer.token == Token.LITERAL_ALIAS) { 1462 SQLAlterTableDropColumnItem item = new SQLAlterTableDropColumnItem(); 1463 this.exprParser.names(item.getColumns()); 1464 1465 if (lexer.token == Token.CASCADE) { 1466 item.setCascade(true); 1467 lexer.nextToken(); 1468 } 1469 1470 stmt.addItem(item); 1471 } else if (lexer.token == Token.PARTITION) { 1472 SQLAlterTableDropPartition dropPartition = parseAlterTableDropPartition(ifExists); 1473 1474 stmt.addItem(dropPartition); 1475 } else if (lexer.token == Token.INDEX) { 1476 lexer.nextToken(); 1477 SQLName indexName = this.exprParser.name(); 1478 SQLAlterTableDropIndex item = new SQLAlterTableDropIndex(); 1479 item.setIndexName(indexName); 1480 stmt.addItem(item); 1481 } else if (lexer.token() == Token.PRIMARY) { 1482 lexer.nextToken(); 1483 accept(Token.KEY); 1484 SQLAlterTableDropPrimaryKey item = new SQLAlterTableDropPrimaryKey(); 1485 stmt.addItem(item); 1486 } else { 1487 throw new ParserException("TODO " ~ lexer.info()); 1488 } 1489 } 1490 1491 protected SQLAlterTableDropPartition parseAlterTableDropPartition(bool ifExists) { 1492 lexer.nextToken(); 1493 SQLAlterTableDropPartition dropPartition = new SQLAlterTableDropPartition(); 1494 1495 dropPartition.setIfExists(ifExists); 1496 1497 if (lexer.token == Token.LPAREN) { 1498 accept(Token.LPAREN); 1499 1500 parseAssignItems(cast(List!SQLAssignItem)(dropPartition.getPartitions()), cast(SQLObject)dropPartition); 1501 1502 accept(Token.RPAREN); 1503 1504 if (lexer.identifierEquals("PURGE")) { 1505 lexer.nextToken(); 1506 dropPartition.setPurge(true); 1507 } 1508 } else { 1509 SQLName partition = this.exprParser.name(); 1510 dropPartition.addPartition(partition); 1511 } 1512 1513 1514 return dropPartition; 1515 } 1516 1517 public SQLStatement parseRename() { 1518 throw new ParserException("TODO " ~ lexer.info()); 1519 } 1520 1521 protected SQLDropTableStatement parseDropTable(bool acceptDrop) { 1522 if (acceptDrop) { 1523 accept(Token.DROP); 1524 } 1525 1526 SQLDropTableStatement stmt = new SQLDropTableStatement(getDbType()); 1527 1528 if (lexer.identifierEquals("TEMPORARY")) { 1529 lexer.nextToken(); 1530 stmt.setTemporary(true); 1531 } 1532 1533 accept(Token.TABLE); 1534 1535 if (lexer.token == Token.IF) { 1536 lexer.nextToken(); 1537 accept(Token.EXISTS); 1538 stmt.setIfExists(true); 1539 } 1540 1541 for (;;) { 1542 SQLName name = this.exprParser.name(); 1543 stmt.addPartition(new SQLExprTableSource(name)); 1544 if (lexer.token == Token.COMMA) { 1545 lexer.nextToken(); 1546 continue; 1547 } 1548 break; 1549 } 1550 1551 for (;;) { 1552 if (lexer.identifierEquals("RESTRICT")) { 1553 lexer.nextToken(); 1554 stmt.setRestrict(true); 1555 continue; 1556 } 1557 1558 if (lexer.identifierEquals("CASCADE")) { 1559 lexer.nextToken(); 1560 stmt.setCascade(true); 1561 1562 if (lexer.identifierEquals("CONSTRAINTS")) { // for oracle 1563 lexer.nextToken(); 1564 } 1565 1566 continue; 1567 } 1568 1569 if (lexer.token == Token.PURGE || lexer.identifierEquals("PURGE")) { 1570 lexer.nextToken(); 1571 stmt.setPurge(true); 1572 continue; 1573 } 1574 1575 break; 1576 } 1577 1578 return stmt; 1579 } 1580 1581 protected SQLDropSequenceStatement parseDropSequence(bool acceptDrop) { 1582 if (acceptDrop) { 1583 accept(Token.DROP); 1584 } 1585 1586 lexer.nextToken(); 1587 1588 SQLName name = this.exprParser.name(); 1589 1590 SQLDropSequenceStatement stmt = new SQLDropSequenceStatement(getDbType()); 1591 stmt.setName(name); 1592 return stmt; 1593 } 1594 1595 protected SQLDropTriggerStatement parseDropTrigger(bool acceptDrop) { 1596 if (acceptDrop) { 1597 accept(Token.DROP); 1598 } 1599 1600 lexer.nextToken(); 1601 SQLDropTriggerStatement stmt = new SQLDropTriggerStatement(getDbType()); 1602 1603 if (lexer.token == Token.IF) { 1604 lexer.nextToken(); 1605 accept(Token.EXISTS); 1606 stmt.setIfExists(true); 1607 } 1608 1609 SQLName name = this.exprParser.name(); 1610 1611 1612 stmt.setName(name); 1613 return stmt; 1614 } 1615 1616 protected SQLDropViewStatement parseDropView(bool acceptDrop) { 1617 if (acceptDrop) { 1618 accept(Token.DROP); 1619 } 1620 1621 SQLDropViewStatement stmt = new SQLDropViewStatement(getDbType()); 1622 1623 accept(Token.VIEW); 1624 1625 if (lexer.token == Token.IF) { 1626 lexer.nextToken(); 1627 accept(Token.EXISTS); 1628 stmt.setIfExists(true); 1629 } 1630 1631 for (;;) { 1632 SQLName name = this.exprParser.name(); 1633 stmt.addPartition(new SQLExprTableSource(name)); 1634 if (lexer.token == Token.COMMA) { 1635 lexer.nextToken(); 1636 continue; 1637 } 1638 break; 1639 } 1640 1641 if (lexer.identifierEquals("RESTRICT")) { 1642 lexer.nextToken(); 1643 stmt.setRestrict(true); 1644 } else if (lexer.identifierEquals("CASCADE")) { 1645 lexer.nextToken(); 1646 1647 if (lexer.identifierEquals("CONSTRAINTS")) { // for oracle 1648 lexer.nextToken(); 1649 } 1650 1651 stmt.setCascade(true); 1652 } 1653 1654 return stmt; 1655 } 1656 1657 protected SQLDropDatabaseStatement parseDropDatabase(bool acceptDrop) { 1658 if (acceptDrop) { 1659 accept(Token.DROP); 1660 } 1661 1662 SQLDropDatabaseStatement stmt = new SQLDropDatabaseStatement(getDbType()); 1663 1664 if (lexer.token == Token.SCHEMA) { 1665 lexer.nextToken(); 1666 } else { 1667 accept(Token.DATABASE); 1668 } 1669 1670 if (lexer.token == Token.IF) { 1671 lexer.nextToken(); 1672 accept(Token.EXISTS); 1673 stmt.setIfExists(true); 1674 } 1675 1676 SQLName name = this.exprParser.name(); 1677 stmt.setDatabase(name); 1678 1679 return stmt; 1680 } 1681 1682 protected SQLDropFunctionStatement parseDropFunction(bool acceptDrop) { 1683 if (acceptDrop) { 1684 accept(Token.DROP); 1685 } 1686 1687 SQLDropFunctionStatement stmt = new SQLDropFunctionStatement(getDbType()); 1688 1689 accept(Token.FUNCTION); 1690 1691 if (lexer.token == Token.IF) { 1692 lexer.nextToken(); 1693 accept(Token.EXISTS); 1694 stmt.setIfExists(true); 1695 } 1696 1697 SQLName name = this.exprParser.name(); 1698 stmt.setName(name); 1699 1700 return stmt; 1701 } 1702 1703 protected SQLDropTableSpaceStatement parseDropTablespace(bool acceptDrop) { 1704 SQLDropTableSpaceStatement stmt = new SQLDropTableSpaceStatement(getDbType()); 1705 1706 if (lexer.isKeepComments() && lexer.hasComment()) { 1707 stmt.addBeforeComment(lexer.readAndResetComments()); 1708 } 1709 1710 if (acceptDrop) { 1711 accept(Token.DROP); 1712 } 1713 1714 accept(Token.TABLESPACE); 1715 1716 if (lexer.token == Token.IF) { 1717 lexer.nextToken(); 1718 accept(Token.EXISTS); 1719 stmt.setIfExists(true); 1720 } 1721 1722 SQLName name = this.exprParser.name(); 1723 stmt.setName(name); 1724 1725 if (lexer.identifierEquals(FnvHash.Constants.ENGINE)) { 1726 lexer.nextToken(); 1727 if (lexer.token == Token.EQ) { 1728 lexer.nextToken(); 1729 } 1730 SQLExpr engine = this.exprParser.primary(); 1731 stmt.setEngine(engine); 1732 } 1733 1734 return stmt; 1735 } 1736 1737 protected SQLDropProcedureStatement parseDropProcedure(bool acceptDrop) { 1738 if (acceptDrop) { 1739 accept(Token.DROP); 1740 } 1741 1742 SQLDropProcedureStatement stmt = new SQLDropProcedureStatement(getDbType()); 1743 1744 accept(Token.PROCEDURE); 1745 1746 if (lexer.token == Token.IF) { 1747 lexer.nextToken(); 1748 accept(Token.EXISTS); 1749 stmt.setIfExists(true); 1750 } 1751 1752 SQLName name = this.exprParser.name(); 1753 stmt.setName(name); 1754 1755 return stmt; 1756 } 1757 1758 public SQLStatement parseTruncate() { 1759 accept(Token.TRUNCATE); 1760 if (lexer.token == Token.TABLE) { 1761 lexer.nextToken(); 1762 } 1763 SQLTruncateStatement stmt = new SQLTruncateStatement(getDbType()); 1764 1765 if (lexer.token == Token.ONLY) { 1766 lexer.nextToken(); 1767 stmt.setOnly(true); 1768 } 1769 1770 for (;;) { 1771 SQLName name = this.exprParser.name(); 1772 stmt.addTableSource(name); 1773 1774 if (lexer.token == Token.COMMA) { 1775 lexer.nextToken(); 1776 continue; 1777 } 1778 1779 break; 1780 } 1781 1782 for (;;) { 1783 if (lexer.token == Token.PURGE) { 1784 lexer.nextToken(); 1785 1786 if (lexer.identifierEquals("SNAPSHOT")) { 1787 lexer.nextToken(); 1788 acceptIdentifier("LOG"); 1789 stmt.setPurgeSnapshotLog(true); 1790 } else { 1791 throw new ParserException("TODO : " ~ lexer.token ~ " " ~ lexer.stringVal()); 1792 } 1793 continue; 1794 } 1795 1796 if (lexer.token == Token.RESTART) { 1797 lexer.nextToken(); 1798 accept(Token.IDENTITY); 1799 stmt.setRestartIdentity(Boolean.TRUE); 1800 continue; 1801 } else if (lexer.token == Token.SHARE) { 1802 lexer.nextToken(); 1803 accept(Token.IDENTITY); 1804 stmt.setRestartIdentity(Boolean.FALSE); 1805 continue; 1806 } 1807 1808 if (lexer.token == Token.CASCADE) { 1809 lexer.nextToken(); 1810 stmt.setCascade(Boolean.TRUE); 1811 continue; 1812 } else if (lexer.token == Token.RESTRICT) { 1813 lexer.nextToken(); 1814 stmt.setCascade(Boolean.FALSE); 1815 continue; 1816 } 1817 1818 if (lexer.token == Token.DROP) { 1819 lexer.nextToken(); 1820 acceptIdentifier("STORAGE"); 1821 stmt.setDropStorage(true); 1822 continue; 1823 } 1824 1825 if (lexer.identifierEquals("REUSE")) { 1826 lexer.nextToken(); 1827 acceptIdentifier("STORAGE"); 1828 stmt.setReuseStorage(true); 1829 continue; 1830 } 1831 1832 if (lexer.identifierEquals("IGNORE")) { 1833 lexer.nextToken(); 1834 accept(Token.DELETE); 1835 acceptIdentifier("TRIGGERS"); 1836 stmt.setIgnoreDeleteTriggers(true); 1837 continue; 1838 } 1839 1840 if (lexer.identifierEquals("RESTRICT")) { 1841 lexer.nextToken(); 1842 accept(Token.WHEN); 1843 accept(Token.DELETE); 1844 acceptIdentifier("TRIGGERS"); 1845 stmt.setRestrictWhenDeleteTriggers(true); 1846 continue; 1847 } 1848 1849 if (lexer.token == Token.CONTINUE) { 1850 lexer.nextToken(); 1851 accept(Token.IDENTITY); 1852 continue; 1853 } 1854 1855 if (lexer.identifierEquals("IMMEDIATE")) { 1856 lexer.nextToken(); 1857 stmt.setImmediate(true); 1858 continue; 1859 } 1860 1861 break; 1862 } 1863 1864 return stmt; 1865 } 1866 1867 public SQLStatement parseInsert() { 1868 SQLInsertStatement stmt = new SQLInsertStatement(); 1869 1870 if (lexer.token == Token.INSERT) { 1871 accept(Token.INSERT); 1872 } 1873 1874 parseInsert0(stmt); 1875 return stmt; 1876 } 1877 1878 protected void parseInsert0(SQLInsertInto insertStatement) { 1879 parseInsert0(insertStatement, true); 1880 } 1881 1882 protected void parseInsert0_hinits(SQLInsertInto insertStatement) { 1883 1884 } 1885 1886 protected void parseInsert0(SQLInsertInto insertStatement, bool acceptSubQuery) { 1887 if (lexer.token == Token.INTO) { 1888 lexer.nextToken(); 1889 1890 SQLName tableName = this.exprParser.name(); 1891 insertStatement.setTableName(tableName); 1892 1893 if (lexer.token == Token.LITERAL_ALIAS) { 1894 insertStatement.setAlias(tableAlias()); 1895 } 1896 1897 parseInsert0_hinits(insertStatement); 1898 1899 if (lexer.token == Token.IDENTIFIER) { 1900 insertStatement.setAlias(lexer.stringVal()); 1901 lexer.nextToken(); 1902 } 1903 } 1904 1905 if (lexer.token == (Token.LPAREN)) { 1906 lexer.nextToken(); 1907 parseInsertColumns(insertStatement); 1908 accept(Token.RPAREN); 1909 } 1910 1911 if (lexer.token == Token.VALUES) { 1912 lexer.nextToken(); 1913 for (;;) { 1914 if (lexer.token == Token.LPAREN) { 1915 lexer.nextToken(); 1916 1917 ValuesClause values = new ValuesClause(); 1918 this.exprParser.exprList(values.getValues(), values); 1919 insertStatement.addValueCause(values); 1920 accept(Token.RPAREN); 1921 } else { // oracle 1922 ValuesClause values = new ValuesClause(); 1923 SQLExpr value = this.exprParser.expr(); 1924 values.addValue(value); 1925 insertStatement.addValueCause(values); 1926 } 1927 1928 if (lexer.token == Token.COMMA) { 1929 lexer.nextToken(); 1930 continue; 1931 } else { 1932 break; 1933 } 1934 } 1935 } else if (acceptSubQuery && (lexer.token == Token.SELECT || lexer.token == Token.LPAREN)) { 1936 SQLSelect select = this.createSQLSelectParser().select(); 1937 insertStatement.setQuery(select); 1938 } 1939 } 1940 1941 protected void parseInsertColumns(SQLInsertInto insert) { 1942 this.exprParser.exprList(insert.getColumns(), insert); 1943 } 1944 1945 public bool parseStatementListDialect(List!(SQLStatement) statementList) { 1946 return false; 1947 } 1948 1949 public SQLDropUserStatement parseDropUser() { 1950 accept(Token.USER); 1951 1952 SQLDropUserStatement stmt = new SQLDropUserStatement(getDbType()); 1953 for (;;) { 1954 SQLExpr expr = this.exprParser.expr(); 1955 stmt.addUser(expr); 1956 if (lexer.token == Token.COMMA) { 1957 lexer.nextToken(); 1958 continue; 1959 } 1960 break; 1961 } 1962 1963 return stmt; 1964 } 1965 1966 public SQLStatement parseDropIndex() { 1967 accept(Token.INDEX); 1968 SQLDropIndexStatement stmt = new SQLDropIndexStatement(getDbType()); 1969 stmt.setIndexName(this.exprParser.name()); 1970 1971 if (lexer.token == Token.ON) { 1972 lexer.nextToken(); 1973 stmt.setTableName(this.exprParser.name()); 1974 } 1975 1976 if (lexer.identifierEquals(FnvHash.Constants.ALGORITHM)) { 1977 lexer.nextToken(); 1978 if (lexer.token == Token.EQ) { 1979 lexer.nextToken(); 1980 } 1981 SQLExpr algorithm = this.exprParser.primary(); 1982 stmt.setAlgorithm(algorithm); 1983 } 1984 1985 if (lexer.token == Token.LOCK) { 1986 lexer.nextToken(); 1987 if (lexer.token == Token.EQ) { 1988 lexer.nextToken(); 1989 } 1990 SQLExpr option = this.exprParser.primary(); 1991 stmt.setLockOption(option); 1992 } 1993 // for mysql 1994 return stmt; 1995 } 1996 1997 public SQLCallStatement parseCall() { 1998 1999 bool brace = false; 2000 if (lexer.token == Token.LBRACE) { 2001 lexer.nextToken(); 2002 brace = true; 2003 } 2004 2005 SQLCallStatement stmt = new SQLCallStatement(getDbType()); 2006 2007 if (lexer.token == Token.QUES) { 2008 lexer.nextToken(); 2009 accept(Token.EQ); 2010 stmt.setOutParameter(new SQLVariantRefExpr("?")); 2011 } 2012 2013 acceptIdentifier("CALL"); 2014 2015 stmt.setProcedureName(exprParser.name()); 2016 2017 if (lexer.token == Token.LPAREN) { 2018 lexer.nextToken(); 2019 exprParser.exprList(stmt.getParameters(), stmt); 2020 accept(Token.RPAREN); 2021 } 2022 2023 if (brace) { 2024 accept(Token.RBRACE); 2025 stmt.setBrace(true); 2026 } 2027 2028 return stmt; 2029 } 2030 2031 public SQLStatement parseSet() { 2032 accept(Token.SET); 2033 SQLSetStatement stmt = new SQLSetStatement(getDbType()); 2034 2035 parseAssignItems(stmt.getItems(), stmt); 2036 2037 return stmt; 2038 } 2039 2040 public void parseAssignItems(List!(SQLAssignItem) items, SQLObject parent) { 2041 for (;;) { 2042 SQLAssignItem item = exprParser.parseAssignItem(); 2043 item.setParent(parent); 2044 items.add(item); 2045 2046 if (lexer.token == Token.COMMA) { 2047 lexer.nextToken(); 2048 continue; 2049 } else { 2050 break; 2051 } 2052 } 2053 } 2054 2055 public SQLStatement parseCreatePackage() { 2056 throw new ParserException("TODO " ~ lexer.info()); 2057 } 2058 2059 public SQLStatement parseCreate() { 2060 char markChar = lexer.current(); 2061 int markBp = lexer.bp(); 2062 2063 List!(string) comments = null; 2064 if (lexer.isKeepComments() && lexer.hasComment()) { 2065 comments = lexer.readAndResetComments(); 2066 } 2067 2068 accept(Token.CREATE); 2069 2070 Token token = lexer.token; 2071 2072 if (token == Token.TABLE || lexer.identifierEquals("GLOBAL")) { 2073 SQLCreateTableParser createTableParser = getSQLCreateTableParser(); 2074 SQLCreateTableStatement stmt = createTableParser.parseCreateTable(false); 2075 2076 if (comments !is null) { 2077 stmt.addBeforeComment(comments); 2078 } 2079 2080 return stmt; 2081 } else if (token == Token.INDEX // 2082 || token == Token.UNIQUE // 2083 || lexer.identifierEquals("NONCLUSTERED") // sql server 2084 ) { 2085 return parseCreateIndex(false); 2086 } else if (lexer.token == Token.SEQUENCE) { 2087 return parseCreateSequence(false); 2088 } else if (token == Token.OR) { 2089 lexer.nextToken(); 2090 accept(Token.REPLACE); 2091 2092 if (lexer.identifierEquals("FORCE")) { 2093 lexer.nextToken(); 2094 } 2095 if (lexer.token == Token.PROCEDURE) { 2096 lexer.reset(markBp, markChar, Token.CREATE); 2097 return parseCreateProcedure(); 2098 } 2099 2100 if (lexer.token == Token.VIEW) { 2101 lexer.reset(markBp, markChar, Token.CREATE); 2102 return parseCreateView(); 2103 } 2104 2105 if (lexer.token == Token.TRIGGER) { 2106 lexer.reset(markBp, markChar, Token.CREATE); 2107 return parseCreateTrigger(); 2108 } 2109 2110 if (lexer.token == Token.FUNCTION) { 2111 lexer.reset(markBp, markChar, Token.CREATE); 2112 return parseCreateFunction(); 2113 } 2114 2115 if (lexer.identifierEquals(FnvHash.Constants.PACKAGE)) { 2116 lexer.reset(markBp, markChar, Token.CREATE); 2117 return parseCreatePackage(); 2118 } 2119 2120 if (lexer.identifierEquals(FnvHash.Constants.TYPE)) { 2121 lexer.reset(markBp, markChar, Token.CREATE); 2122 return parseCreateType(); 2123 } 2124 2125 if (lexer.identifierEquals(FnvHash.Constants.PUBLIC)) { 2126 lexer.reset(markBp, markChar, Token.CREATE); 2127 return parseCreateSynonym(); 2128 } 2129 2130 if (lexer.identifierEquals(FnvHash.Constants.SYNONYM)) { 2131 lexer.reset(markBp, markChar, Token.CREATE); 2132 return parseCreateSynonym(); 2133 } 2134 2135 // lexer.reset(mark_bp, mark_ch, Token.CREATE); 2136 throw new ParserException("TODO " ~ lexer.info()); 2137 } else if (token == Token.DATABASE) { 2138 lexer.nextToken(); 2139 if (lexer.identifierEquals("LINK")) { 2140 lexer.reset(markBp, markChar, Token.CREATE); 2141 return parseCreateDbLink(); 2142 } 2143 2144 lexer.reset(markBp, markChar, Token.CREATE); 2145 return parseCreateDatabase(); 2146 } else if (lexer.token == Token.USER) { 2147 lexer.reset(markBp, markChar, Token.CREATE); 2148 return parseCreateUser(); 2149 } else if (lexer.identifierEquals(FnvHash.Constants.PUBLIC)) { 2150 lexer.nextToken(); 2151 if (lexer.identifierEquals("SYNONYM")) { 2152 lexer.reset(markBp, markChar, Token.CREATE); 2153 return parseCreateSynonym(); 2154 } else { 2155 lexer.reset(markBp, markChar, Token.CREATE); 2156 return parseCreateDbLink(); 2157 } 2158 } else if (lexer.identifierEquals("SHARE")) { 2159 lexer.reset(markBp, markChar, Token.CREATE); 2160 return parseCreateDbLink(); 2161 } else if (lexer.identifierEquals("SYNONYM")) { 2162 lexer.reset(markBp, markChar, Token.CREATE); 2163 return parseCreateSynonym(); 2164 } else if (token == Token.VIEW) { 2165 return parseCreateView(); 2166 } else if (token == Token.TRIGGER) { 2167 lexer.reset(markBp, markChar, Token.CREATE); 2168 return parseCreateTrigger(); 2169 } else if (token == Token.PROCEDURE) { 2170 SQLCreateProcedureStatement stmt = parseCreateProcedure(); 2171 stmt.setCreate(true); 2172 return stmt; 2173 } else if (token == Token.FUNCTION) { 2174 lexer.reset(markBp, markChar, Token.CREATE); 2175 SQLStatement stmt = this.parseCreateFunction(); 2176 return stmt; 2177 } else if (lexer.identifierEquals(FnvHash.Constants.BITMAP)) { 2178 lexer.reset(markBp, markChar, Token.CREATE); 2179 return parseCreateIndex(true); 2180 } else if (lexer.identifierEquals(FnvHash.Constants.MATERIALIZED)) { 2181 lexer.reset(markBp, markChar, Token.CREATE); 2182 return parseCreateMaterializedView(); 2183 } else if (lexer.identifierEquals(FnvHash.Constants.TYPE)) { 2184 lexer.reset(markBp, markChar, Token.CREATE); 2185 return parseCreateType(); 2186 } 2187 2188 throw new ParserException("TODO " ~ lexer.token); 2189 } 2190 2191 public SQLStatement parseCreateType() { 2192 throw new ParserException("TODO " ~ lexer.token); 2193 } 2194 2195 public SQLStatement parseCreateUser() { 2196 accept(Token.CREATE); 2197 accept(Token.USER); 2198 2199 SQLCreateUserStatement stmt = new SQLCreateUserStatement(); 2200 stmt.setUser(this.exprParser.name()); 2201 2202 accept(Token.IDENTIFIED); 2203 accept(Token.BY); 2204 stmt.setPassword(this.exprParser.primary()); 2205 2206 return stmt; 2207 } 2208 2209 public SQLCreateFunctionStatement parseCreateFunction() { 2210 throw new ParserException("TODO " ~ lexer.token); 2211 } 2212 2213 public SQLStatement parseCreateMaterializedView() { 2214 accept(Token.CREATE); 2215 acceptIdentifier("MATERIALIZED"); 2216 accept(Token.VIEW); 2217 2218 SQLCreateMaterializedViewStatement stmt = new SQLCreateMaterializedViewStatement(); 2219 stmt.setName(this.exprParser.name()); 2220 2221 if (lexer.token == Token.PARTITION) { 2222 SQLPartitionBy partitionBy = this.exprParser.parsePartitionBy(); 2223 stmt.setPartitionBy(partitionBy); 2224 } 2225 2226 for (;;) { 2227 // if (cast(OracleExprParser)(exprParser) !is null) { 2228 // ((OracleExprParser) exprParser).parseSegmentAttributes(stmt); 2229 // } 2230 2231 if (lexer.identifierEquals("REFRESH")) { 2232 lexer.nextToken(); 2233 2234 for (; ; ) { 2235 if (lexer.identifierEquals("FAST")) { 2236 lexer.nextToken(); 2237 stmt.setRefreshFast(true); 2238 } else if (lexer.identifierEquals("COMPLETE")) { 2239 lexer.nextToken(); 2240 stmt.setRefreshComlete(true); 2241 } else if (lexer.identifierEquals("FORCE")) { 2242 lexer.nextToken(); 2243 stmt.setRefreshForce(true); 2244 } else if (lexer.token == Token.ON) { 2245 lexer.nextToken(); 2246 if (lexer.token == Token.COMMIT) { 2247 lexer.nextToken(); 2248 stmt.setRefreshOnCommit(true); 2249 } else { 2250 acceptIdentifier("DEMAND"); 2251 stmt.setRefreshOnDemand(true); 2252 } 2253 } else { 2254 break; 2255 } 2256 } 2257 } else if (lexer.identifierEquals(FnvHash.Constants.BUILD)) { 2258 lexer.nextToken(); 2259 2260 if (lexer.identifierEquals("IMMEDIATE") || lexer.token == Token.IMMEDIATE) { 2261 lexer.nextToken(); 2262 stmt.setBuildImmediate(true); 2263 } else { 2264 accept(Token.DEFERRED); 2265 stmt.setBuildDeferred(true); 2266 } 2267 } else if (lexer.identifierEquals(FnvHash.Constants.PARALLEL)) { 2268 lexer.nextToken(); 2269 stmt.setParallel(true); 2270 if (lexer.token == Token.LITERAL_INT) { 2271 stmt.setParallelValue(cast(Integer)(lexer.integerValue())); 2272 lexer.nextToken(); 2273 } 2274 } else if (lexer.identifierEquals(FnvHash.Constants.NOCACHE) || lexer.token == Token.NOCACHE) { 2275 lexer.nextToken(); 2276 stmt.setCache(false); 2277 } else if (lexer.identifierEquals(FnvHash.Constants.NOPARALLEL)) { 2278 lexer.nextToken(); 2279 stmt.setParallel(false); 2280 } else if (lexer.token == Token.WITH) { 2281 lexer.nextToken(); 2282 acceptIdentifier("ROWID"); 2283 stmt.setWithRowId(true); 2284 } else { 2285 break; 2286 } 2287 } 2288 2289 if (lexer.token == Token.ENABLE) { 2290 lexer.nextToken(); 2291 acceptIdentifier("QUERY"); 2292 acceptIdentifier("REWRITE"); 2293 stmt.setEnableQueryRewrite(true); 2294 } 2295 2296 accept(Token.AS); 2297 SQLSelect select = this.createSQLSelectParser().select(); 2298 stmt.setQuery(select); 2299 2300 return stmt; 2301 } 2302 2303 2304 public SQLStatement parseCreateDbLink() { 2305 throw new ParserException("TODO " ~ lexer.token); 2306 } 2307 2308 public SQLStatement parseCreateSynonym() { 2309 throw new ParserException("TODO " ~ lexer.token); 2310 } 2311 2312 public SQLStatement parseCreateTrigger() { 2313 SQLCreateTriggerStatement stmt = new SQLCreateTriggerStatement(getDbType()); 2314 2315 if (lexer.token == Token.CREATE) { 2316 lexer.nextToken(); 2317 2318 if (lexer.token == Token.OR) { 2319 lexer.nextToken(); 2320 accept(Token.REPLACE); 2321 2322 stmt.setOrReplace(true); 2323 } 2324 } 2325 2326 if (lexer.identifierEquals(FnvHash.Constants.DEFINER)) { 2327 lexer.nextToken(); 2328 accept(Token.EQ); 2329 SQLName definer = (cast(MySqlExprParser) this.exprParser).userName(); 2330 stmt.setDefiner(definer); 2331 2332 if (lexer.token() == Token.LPAREN) { 2333 lexer.nextToken(); 2334 accept(Token.RPAREN); 2335 } 2336 } 2337 2338 accept(Token.TRIGGER); 2339 2340 2341 stmt.setName(this.exprParser.name()); 2342 2343 if (lexer.identifierEquals(FnvHash.Constants.BEFORE)) { 2344 stmt.setTriggerType(SQLCreateTriggerStatement.TriggerType.BEFORE); 2345 lexer.nextToken(); 2346 } else if (lexer.identifierEquals(FnvHash.Constants.AFTER)) { 2347 stmt.setTriggerType(SQLCreateTriggerStatement.TriggerType.AFTER); 2348 lexer.nextToken(); 2349 } else if (lexer.identifierEquals(FnvHash.Constants.INSTEAD)) { 2350 lexer.nextToken(); 2351 accept(Token.OF); 2352 stmt.setTriggerType(SQLCreateTriggerStatement.TriggerType.INSTEAD_OF); 2353 } 2354 2355 for (;;) { 2356 if (lexer.token == Token.INSERT) { 2357 lexer.nextToken(); 2358 stmt.setInsert(true); 2359 } else if (lexer.token == Token.UPDATE) { 2360 lexer.nextToken(); 2361 stmt.setUpdate(true); 2362 2363 if (lexer.token == Token.OF) { 2364 lexer.nextToken(); 2365 this.exprParser.names(stmt.getUpdateOfColumns(), stmt); 2366 } 2367 } else if (lexer.token == Token.DELETE) { 2368 lexer.nextToken(); 2369 stmt.setDelete(true); 2370 } 2371 2372 if (lexer.token == Token.COMMA 2373 || lexer.token == Token.OR) { 2374 lexer.nextToken(); 2375 continue; 2376 } 2377 2378 break; 2379 } 2380 2381 accept(Token.ON); 2382 stmt.setOn(this.exprParser.name()); 2383 2384 if (lexer.token == Token.FOR) { 2385 lexer.nextToken(); 2386 acceptIdentifier("EACH"); 2387 accept(Token.ROW); 2388 stmt.setForEachRow(true); 2389 } 2390 2391 if (lexer.token == Token.WHEN) { 2392 lexer.nextToken(); 2393 SQLExpr condition = this.exprParser.expr(); 2394 stmt.setWhen(condition); 2395 } 2396 2397 List!(SQLStatement) body = this.parseStatementList(); 2398 if (body is null || body.isEmpty()) { 2399 throw new ParserException("syntax error"); 2400 } 2401 stmt.setBody(body.get(0)); 2402 return stmt; 2403 } 2404 2405 public SQLStatement parseBlock() { 2406 throw new ParserException("TODO " ~ lexer.token); 2407 } 2408 2409 public SQLStatement parseCreateDatabase() { 2410 if (lexer.token == Token.CREATE) { 2411 lexer.nextToken(); 2412 } 2413 2414 accept(Token.DATABASE); 2415 2416 SQLCreateDatabaseStatement stmt = new SQLCreateDatabaseStatement(getDbType()); 2417 stmt.setName(this.exprParser.name()); 2418 return stmt; 2419 } 2420 2421 public SQLCreateProcedureStatement parseCreateProcedure() { 2422 throw new ParserException("TODO " ~ lexer.token); 2423 } 2424 2425 public SQLStatement parseCreateSequence(bool acceptCreate) { 2426 throw new ParserException("TODO " ~ lexer.token); 2427 } 2428 2429 public SQLStatement parseCreateIndex(bool acceptCreate) { 2430 if (acceptCreate) { 2431 accept(Token.CREATE); 2432 } 2433 2434 SQLCreateIndexStatement stmt = new SQLCreateIndexStatement(getDbType()); 2435 if (lexer.token == Token.UNIQUE) { 2436 lexer.nextToken(); 2437 if (lexer.identifierEquals("CLUSTERED")) { 2438 lexer.nextToken(); 2439 stmt.setType("UNIQUE CLUSTERED"); 2440 } else { 2441 stmt.setType("UNIQUE"); 2442 } 2443 } else if (lexer.identifierEquals("FULLTEXT")) { 2444 stmt.setType("FULLTEXT"); 2445 lexer.nextToken(); 2446 } else if (lexer.identifierEquals("NONCLUSTERED")) { 2447 stmt.setType("NONCLUSTERED"); 2448 lexer.nextToken(); 2449 } 2450 2451 accept(Token.INDEX); 2452 2453 stmt.setName(this.exprParser.name()); 2454 2455 accept(Token.ON); 2456 2457 stmt.setTable(this.exprParser.name()); 2458 2459 accept(Token.LPAREN); 2460 2461 for (;;) { 2462 SQLSelectOrderByItem item = this.exprParser.parseSelectOrderByItem(); 2463 item.setParent(stmt); 2464 stmt.addItem(item); 2465 if (lexer.token == Token.COMMA) { 2466 lexer.nextToken(); 2467 continue; 2468 } 2469 break; 2470 } 2471 accept(Token.RPAREN); 2472 2473 return stmt; 2474 } 2475 2476 public SQLCreateTableParser getSQLCreateTableParser() { 2477 return new SQLCreateTableParser(this.exprParser); 2478 } 2479 2480 public SQLStatement parseSelect() { 2481 SQLSelectParser selectParser = createSQLSelectParser(); 2482 SQLSelect select = selectParser.select(); 2483 return new SQLSelectStatement(select,getDbType()); 2484 } 2485 2486 public SQLSelectParser createSQLSelectParser() { 2487 return new SQLSelectParser(this.exprParser, selectListCache); 2488 } 2489 2490 public SQLUpdateStatement parseUpdateStatement() { 2491 SQLUpdateStatement udpateStatement = createUpdateStatement(); 2492 2493 if (lexer.token == Token.UPDATE) { 2494 lexer.nextToken(); 2495 2496 SQLTableSource tableSource = this.exprParser.createSelectParser().parseTableSource(); 2497 udpateStatement.setTableSource(tableSource); 2498 } 2499 2500 parseUpdateSet(udpateStatement); 2501 2502 if (lexer.token == (Token.WHERE)) { 2503 lexer.nextToken(); 2504 udpateStatement.setWhere(this.exprParser.expr()); 2505 } 2506 2507 return udpateStatement; 2508 } 2509 2510 protected void parseUpdateSet(SQLUpdateStatement update) { 2511 accept(Token.SET); 2512 2513 for (;;) { 2514 SQLUpdateSetItem item = this.exprParser.parseUpdateSetItem(); 2515 update.addItem(item); 2516 2517 if (lexer.token != Token.COMMA) { 2518 break; 2519 } 2520 2521 lexer.nextToken(); 2522 } 2523 } 2524 2525 protected SQLUpdateStatement createUpdateStatement() { 2526 return new SQLUpdateStatement(getDbType()); 2527 } 2528 2529 public SQLDeleteStatement parseDeleteStatement() { 2530 SQLDeleteStatement deleteStatement = new SQLDeleteStatement(getDbType()); 2531 2532 if (lexer.token == Token.DELETE) { 2533 lexer.nextToken(); 2534 if (lexer.token == (Token.FROM)) { 2535 lexer.nextToken(); 2536 } 2537 2538 if (lexer.token == Token.COMMENT) { 2539 lexer.nextToken(); 2540 } 2541 2542 SQLName tableName = exprParser.name(); 2543 2544 deleteStatement.setTableName(tableName); 2545 2546 if (lexer.token == Token.FROM) { 2547 lexer.nextToken(); 2548 SQLTableSource tableSource = createSQLSelectParser().parseTableSource(); 2549 deleteStatement.setFrom(tableSource); 2550 } 2551 } 2552 2553 if (lexer.token == (Token.WHERE)) { 2554 lexer.nextToken(); 2555 SQLExpr where = this.exprParser.expr(); 2556 deleteStatement.setWhere(where); 2557 } 2558 2559 return deleteStatement; 2560 } 2561 2562 public SQLCreateTableStatement parseCreateTable() { 2563 // SQLCreateTableParser parser = new SQLCreateTableParser(this.lexer); 2564 // return parser.parseCreateTable(); 2565 throw new ParserException("TODO"); 2566 } 2567 2568 public SQLCreateViewStatement parseCreateView() { 2569 SQLCreateViewStatement createView = new SQLCreateViewStatement(getDbType()); 2570 2571 if (lexer.token == Token.CREATE) { 2572 lexer.nextToken(); 2573 } 2574 2575 if (lexer.token == Token.OR) { 2576 lexer.nextToken(); 2577 accept(Token.REPLACE); 2578 createView.setOrReplace(true); 2579 } 2580 2581 if (lexer.identifierEquals("ALGORITHM")) { 2582 lexer.nextToken(); 2583 accept(Token.EQ); 2584 string algorithm = lexer.stringVal(); 2585 createView.setAlgorithm(algorithm); 2586 lexer.nextToken(); 2587 } 2588 2589 if (lexer.identifierEquals(FnvHash.Constants.DEFINER)) { 2590 lexer.nextToken(); 2591 accept(Token.EQ); 2592 SQLName definer = cast(SQLName) (cast(MySqlExprParser) this.exprParser).userName(); 2593 createView.setDefiner(definer); 2594 } 2595 2596 if (lexer.identifierEquals(FnvHash.Constants.SQL)) { 2597 lexer.nextToken(); 2598 acceptIdentifier("SECURITY"); 2599 string sqlSecurity = lexer.stringVal(); 2600 createView.setSqlSecurity(sqlSecurity); 2601 lexer.nextToken(); 2602 } 2603 2604 if (lexer.identifierEquals("FORCE")) { 2605 lexer.nextToken(); 2606 createView.setForce(true); 2607 } 2608 2609 this.accept(Token.VIEW); 2610 2611 if (lexer.token == Token.IF || lexer.identifierEquals("IF")) { 2612 lexer.nextToken(); 2613 accept(Token.NOT); 2614 accept(Token.EXISTS); 2615 createView.setIfNotExists(true); 2616 } 2617 2618 createView.setName(exprParser.name()); 2619 2620 if (lexer.token == Token.LPAREN) { 2621 lexer.nextToken(); 2622 2623 for (;;) { 2624 2625 if (lexer.token == Token.CONSTRAINT) { 2626 SQLTableConstraint constraint = cast(SQLTableConstraint) this.exprParser.parseConstaint(); 2627 createView.addColumn(constraint); 2628 } else { 2629 SQLColumnDefinition column = new SQLColumnDefinition(); 2630 column.setDbType(dbType); 2631 SQLName expr = this.exprParser.name(); 2632 column.setName(expr); 2633 2634 this.exprParser.parseColumnRest(column); 2635 2636 if (lexer.token == Token.COMMENT) { 2637 lexer.nextToken(); 2638 2639 SQLExpr comment; 2640 if (lexer.token == Token.LITERAL_ALIAS) { 2641 string _alias = lexer.stringVal(); 2642 if (_alias.length > 2 && charAt(_alias, 0) == '"' && charAt(_alias, _alias.length - 1) == '"') { 2643 _alias = _alias.substring(1, _alias.length - 1); 2644 } 2645 comment = new SQLCharExpr(_alias); 2646 lexer.nextToken(); 2647 } else { 2648 comment = this.exprParser.primary(); 2649 } 2650 column.setComment(comment); 2651 } 2652 2653 column.setParent(createView); 2654 createView.addColumn(column); 2655 } 2656 2657 if (lexer.token == Token.COMMA) { 2658 lexer.nextToken(); 2659 } else { 2660 break; 2661 } 2662 } 2663 2664 accept(Token.RPAREN); 2665 } 2666 2667 if (lexer.token == Token.COMMENT) { 2668 lexer.nextToken(); 2669 SQLCharExpr comment = cast(SQLCharExpr) exprParser.primary(); 2670 createView.setComment(comment); 2671 } 2672 2673 this.accept(Token.AS); 2674 2675 SQLSelectParser selectParser = this.createSQLSelectParser(); 2676 createView.setSubQuery(selectParser.select()); 2677 2678 if (lexer.token == Token.WITH) { 2679 lexer.nextToken(); 2680 2681 if (lexer.identifierEquals("CASCADED")) { 2682 createView.setWithCascaded(true); 2683 lexer.nextToken(); 2684 } else if (lexer.identifierEquals("LOCAL")){ 2685 createView.setWithLocal(true); 2686 lexer.nextToken(); 2687 } else if (lexer.identifierEquals("READ")) { 2688 lexer.nextToken(); 2689 accept(Token.ONLY); 2690 createView.setWithReadOnly(true); 2691 } 2692 2693 if (lexer.token == Token.CHECK) { 2694 lexer.nextToken(); 2695 acceptIdentifier("OPTION"); 2696 createView.setWithCheckOption(true); 2697 } 2698 } 2699 2700 return createView; 2701 } 2702 2703 public SQLCommentStatement parseComment() { 2704 accept(Token.COMMENT); 2705 SQLCommentStatement stmt = new SQLCommentStatement(); 2706 2707 accept(Token.ON); 2708 2709 if (lexer.token == Token.TABLE) { 2710 stmt.setType(SQLCommentStatement.Type.TABLE); 2711 lexer.nextToken(); 2712 } else if (lexer.token == Token.COLUMN) { 2713 stmt.setType(SQLCommentStatement.Type.COLUMN); 2714 lexer.nextToken(); 2715 } 2716 2717 stmt.setOn(this.exprParser.name()); 2718 2719 accept(Token.IS); 2720 stmt.setComment(this.exprParser.expr()); 2721 2722 return stmt; 2723 } 2724 2725 protected SQLAlterTableAddColumn parseAlterTableAddColumn() { 2726 bool odps = DBType.ODPS.opEquals(dbType); 2727 2728 if (odps) { 2729 acceptIdentifier("COLUMNS"); 2730 accept(Token.LPAREN); 2731 } 2732 2733 SQLAlterTableAddColumn item = new SQLAlterTableAddColumn(); 2734 2735 for (;;) { 2736 SQLColumnDefinition columnDef = this.exprParser.parseColumn(); 2737 item.addColumn(columnDef); 2738 if (lexer.token == Token.COMMA) { 2739 lexer.nextToken(); 2740 if (lexer.identifierEquals("ADD")) { 2741 break; 2742 } 2743 continue; 2744 } 2745 break; 2746 } 2747 2748 if (odps) { 2749 accept(Token.RPAREN); 2750 } 2751 return item; 2752 } 2753 2754 public SQLStatement parseStatement() { 2755 if (lexer.token == Token.SELECT) { 2756 return this.parseSelect(); 2757 } 2758 2759 if (lexer.token == Token.INSERT) { 2760 return this.parseInsert(); 2761 } 2762 2763 2764 if (lexer.token == Token.UPDATE) { 2765 return this.parseUpdateStatement(); 2766 } 2767 2768 if (lexer.token == Token.DELETE) { 2769 return this.parseDeleteStatement(); 2770 } 2771 2772 List!(SQLStatement) list = new ArrayList!(SQLStatement)(1); 2773 this.parseStatementList(list, 1, null); 2774 return list.get(0); 2775 } 2776 2777 /** 2778 * @param tryBest - 为true去解析并忽略之后的错误 2779 * 强制建议除非明确知道可以忽略才传tryBest=true, 2780 * 不然会忽略语法错误,且截断sql,导致update和delete无where条件下执行!!! 2781 */ 2782 public SQLStatement parseStatement( bool tryBest) { 2783 List!(SQLStatement) list = new ArrayList!(SQLStatement)(); 2784 this.parseStatementList(list, 1, null); 2785 if (tryBest) { 2786 if (lexer.token != Token.EOF) { 2787 throw new ParserException("sql syntax error, no terminated. " ~ lexer.token); 2788 } 2789 } 2790 return list.get(0); 2791 } 2792 2793 public SQLExplainStatement parseExplain() { 2794 accept(Token.EXPLAIN); 2795 if (lexer.identifierEquals("PLAN")) { 2796 lexer.nextToken(); 2797 } 2798 2799 if (lexer.token == Token.FOR) { 2800 lexer.nextToken(); 2801 } 2802 2803 SQLExplainStatement explain = new SQLExplainStatement(getDbType()); 2804 2805 if (lexer.token == Token.HINT) { 2806 explain.setHints(this.exprParser.parseHints()); 2807 } 2808 2809 if (DBType.MYSQL.opEquals(dbType)) { 2810 if (lexer.identifierEquals("FORMAT") 2811 || lexer.identifierEquals("EXTENDED") 2812 || lexer.identifierEquals("PARTITIONS")) { 2813 explain.setType(lexer.stringVal); 2814 lexer.nextToken(); 2815 } 2816 } 2817 2818 explain.setStatement(parseStatement()); 2819 2820 return explain; 2821 } 2822 2823 protected SQLAlterTableAddIndex parseAlterTableAddIndex() { 2824 SQLAlterTableAddIndex item = new SQLAlterTableAddIndex(); 2825 2826 if (lexer.token == Token.FULLTEXT) { 2827 lexer.nextToken(); 2828 item.setType("FULLTEXT"); 2829 } else if (lexer.identifierEquals(FnvHash.Constants.SPATIAL)) { 2830 lexer.nextToken(); 2831 item.setType("SPATIAL"); 2832 } 2833 2834 if (lexer.token == Token.UNIQUE) { 2835 item.setUnique(true); 2836 lexer.nextToken(); 2837 if (lexer.token == Token.INDEX) { 2838 lexer.nextToken(); 2839 } else if (lexer.token == Token.KEY) { 2840 item.setKey(true); 2841 lexer.nextToken(); 2842 } 2843 } else { 2844 if (lexer.token == Token.INDEX) { 2845 accept(Token.INDEX); 2846 } else if (lexer.token == Token.KEY) { 2847 item.setKey(true); 2848 accept(Token.KEY); 2849 } 2850 } 2851 2852 if (lexer.token == Token.LPAREN) { 2853 lexer.nextToken(); 2854 } else { 2855 item.setName(this.exprParser.name()); 2856 2857 if (DBType.MYSQL.opEquals(dbType)) { 2858 if (lexer.identifierEquals("USING")) { 2859 lexer.nextToken(); 2860 string indexType = lexer.stringVal; 2861 item.setType(indexType); 2862 accept(Token.IDENTIFIER); 2863 } 2864 } 2865 2866 accept(Token.LPAREN); 2867 } 2868 2869 for (;;) { 2870 SQLSelectOrderByItem column = this.exprParser.parseSelectOrderByItem(); 2871 item.addItem(column); 2872 if (lexer.token == Token.COMMA) { 2873 lexer.nextToken(); 2874 continue; 2875 } 2876 break; 2877 } 2878 accept(Token.RPAREN); 2879 2880 if (DBType.MYSQL.opEquals(dbType)) { 2881 if (lexer.identifierEquals(FnvHash.Constants.USING)) { 2882 lexer.nextToken(); 2883 string indexType = lexer.stringVal; 2884 item.setType(indexType); 2885 accept(Token.IDENTIFIER); 2886 } 2887 } 2888 2889 if (lexer.token == Token.COMMENT) { 2890 lexer.nextToken(); 2891 SQLExpr comment = this.exprParser.primary(); 2892 item.setComment(comment); 2893 } 2894 return item; 2895 } 2896 2897 /** 2898 * parse cursor open statement 2899 * 2900 * @return 2901 */ 2902 public SQLOpenStatement parseOpen() { 2903 SQLOpenStatement stmt = new SQLOpenStatement(); 2904 accept(Token.OPEN); 2905 stmt.setCursorName(exprParser.name()); 2906 2907 if (lexer.token == Token.LPAREN) { 2908 lexer.nextToken(); 2909 this.exprParser.names(stmt.getColumns(), stmt); 2910 accept(Token.RPAREN); 2911 } 2912 2913 if (lexer.token == Token.FOR) { 2914 lexer.nextToken(); 2915 if (lexer.token == Token.SELECT) { 2916 SQLSelectParser selectParser = createSQLSelectParser(); 2917 SQLSelect select = selectParser.select(); 2918 SQLQueryExpr queryExpr = new SQLQueryExpr(select); 2919 stmt.setFor(queryExpr); 2920 } else { 2921 throw new ParserException("TODO " ~ lexer.info()); 2922 } 2923 } 2924 accept(Token.SEMI); 2925 stmt.setAfterSemi(true); 2926 return stmt; 2927 } 2928 2929 public SQLFetchStatement parseFetch() { 2930 accept(Token.FETCH); 2931 2932 SQLFetchStatement stmt = new SQLFetchStatement(); 2933 stmt.setCursorName(this.exprParser.name()); 2934 2935 if (lexer.identifierEquals("BULK")) { 2936 lexer.nextToken(); 2937 acceptIdentifier("COLLECT"); 2938 stmt.setBulkCollect(true); 2939 } 2940 2941 accept(Token.INTO); 2942 for (;;) { 2943 stmt.getInto().add(this.exprParser.name()); 2944 if (lexer.token == Token.COMMA) { 2945 lexer.nextToken(); 2946 continue; 2947 } 2948 2949 break; 2950 } 2951 2952 return stmt; 2953 } 2954 2955 public SQLStatement parseClose() { 2956 SQLCloseStatement stmt = new SQLCloseStatement(); 2957 accept(Token.CLOSE); 2958 stmt.setCursorName(exprParser.name()); 2959 accept(Token.SEMI); 2960 stmt.setAfterSemi(true); 2961 return stmt; 2962 } 2963 2964 public bool isParseCompleteValues() { 2965 return parseCompleteValues; 2966 } 2967 2968 public void setParseCompleteValues(bool parseCompleteValues) { 2969 this.parseCompleteValues = parseCompleteValues; 2970 } 2971 2972 public int getParseValuesSize() { 2973 return parseValuesSize; 2974 } 2975 2976 public void setParseValuesSize(int parseValuesSize) { 2977 this.parseValuesSize = parseValuesSize; 2978 } 2979 2980 public SQLStatement parseMerge() { 2981 accept(Token.MERGE); 2982 2983 SQLMergeStatement stmt = new SQLMergeStatement(); 2984 stmt.setDbType(dbType); 2985 2986 parseHints((stmt.getHints())); 2987 2988 accept(Token.INTO); 2989 2990 if (lexer.token == Token.LPAREN) { 2991 lexer.nextToken(); 2992 SQLSelect select = this.createSQLSelectParser().select(); 2993 SQLSubqueryTableSource tableSource = new SQLSubqueryTableSource(select); 2994 stmt.setInto(tableSource); 2995 accept(Token.RPAREN); 2996 } else { 2997 stmt.setInto(exprParser.name()); 2998 } 2999 3000 stmt.getInto().setAlias(tableAlias()); 3001 3002 accept(Token.USING); 3003 3004 SQLTableSource using = this.createSQLSelectParser().parseTableSource(); 3005 stmt.setUsing(using); 3006 3007 accept(Token.ON); 3008 stmt.setOn(exprParser.expr()); 3009 3010 for (;;) { 3011 bool insertFlag = false; 3012 if (lexer.token == Token.WHEN) { 3013 lexer.nextToken(); 3014 if (lexer.token == Token.MATCHED) { 3015 SQLMergeStatement.MergeUpdateClause updateClause = new SQLMergeStatement.MergeUpdateClause(); 3016 lexer.nextToken(); 3017 accept(Token.THEN); 3018 accept(Token.UPDATE); 3019 accept(Token.SET); 3020 3021 for (; ; ) { 3022 SQLUpdateSetItem item = this.exprParser.parseUpdateSetItem(); 3023 3024 updateClause.addItem(item); 3025 item.setParent(updateClause); 3026 3027 if (lexer.token == (Token.COMMA)) { 3028 lexer.nextToken(); 3029 continue; 3030 } 3031 3032 break; 3033 } 3034 3035 if (lexer.token == Token.WHERE) { 3036 lexer.nextToken(); 3037 updateClause.setWhere(exprParser.expr()); 3038 } 3039 3040 if (lexer.token == Token.DELETE) { 3041 lexer.nextToken(); 3042 accept(Token.WHERE); 3043 updateClause.setWhere(exprParser.expr()); 3044 } 3045 3046 stmt.setUpdateClause(updateClause); 3047 } else if (lexer.token == Token.NOT) { 3048 lexer.nextToken(); 3049 insertFlag = true; 3050 } 3051 } 3052 3053 if (!insertFlag) { 3054 if (lexer.token == Token.WHEN) { 3055 lexer.nextToken(); 3056 } 3057 3058 if (lexer.token == Token.NOT) { 3059 lexer.nextToken(); 3060 insertFlag = true; 3061 } 3062 } 3063 3064 if (insertFlag) { 3065 SQLMergeStatement.MergeInsertClause insertClause = new SQLMergeStatement.MergeInsertClause(); 3066 3067 accept(Token.MATCHED); 3068 accept(Token.THEN); 3069 accept(Token.INSERT); 3070 3071 if (lexer.token == Token.LPAREN) { 3072 accept(Token.LPAREN); 3073 exprParser.exprList(insertClause.getColumns(), insertClause); 3074 accept(Token.RPAREN); 3075 } 3076 accept(Token.VALUES); 3077 accept(Token.LPAREN); 3078 exprParser.exprList(insertClause.getValues(), insertClause); 3079 accept(Token.RPAREN); 3080 3081 if (lexer.token == Token.WHERE) { 3082 lexer.nextToken(); 3083 insertClause.setWhere(exprParser.expr()); 3084 } 3085 3086 stmt.setInsertClause(insertClause); 3087 } 3088 3089 if (lexer.token == Token.WHEN) { 3090 continue; 3091 } 3092 3093 break; 3094 } 3095 3096 SQLErrorLoggingClause errorClause = parseErrorLoggingClause(); 3097 stmt.setErrorLoggingClause(errorClause); 3098 3099 return stmt; 3100 } 3101 3102 protected SQLErrorLoggingClause parseErrorLoggingClause() { 3103 if (lexer.identifierEquals("LOG")) { 3104 SQLErrorLoggingClause errorClause = new SQLErrorLoggingClause(); 3105 3106 lexer.nextToken(); 3107 accept(Token.ERRORS); 3108 if (lexer.token == Token.INTO) { 3109 lexer.nextToken(); 3110 errorClause.setInto(exprParser.name()); 3111 } 3112 3113 if (lexer.token == Token.LPAREN) { 3114 lexer.nextToken(); 3115 errorClause.setSimpleExpression(exprParser.expr()); 3116 accept(Token.RPAREN); 3117 } 3118 3119 if (lexer.token == Token.REJECT) { 3120 lexer.nextToken(); 3121 accept(Token.LIMIT); 3122 errorClause.setLimit(exprParser.expr()); 3123 } 3124 3125 return errorClause; 3126 } 3127 return null; 3128 } 3129 3130 public void parseHints(List!(SQLHint) hints) { 3131 this.getExprParser().parseHints!(SQLHint)((hints)); 3132 } 3133 3134 public SQLStatement parseDescribe() { 3135 if (lexer.token == Token.DESC || lexer.identifierEquals("DESCRIBE")) { 3136 lexer.nextToken(); 3137 } else { 3138 throw new ParserException("expect DESC, actual " ~ lexer.token); 3139 } 3140 3141 SQLDescribeStatement stmt = new SQLDescribeStatement(); 3142 stmt.setDbType(dbType); 3143 3144 if (lexer.identifierEquals("ROLE")) { 3145 lexer.nextToken(); 3146 stmt.setObjectType(SQLObjectType.ROLE); 3147 } else if (lexer.identifierEquals("PACKAGE")) { 3148 lexer.nextToken(); 3149 stmt.setObjectType(SQLObjectType.PACKAGE); 3150 } else if (lexer.identifierEquals("INSTANCE")) { 3151 lexer.nextToken(); 3152 stmt.setObjectType(SQLObjectType.INSTANCE); 3153 } 3154 stmt.setObject(this.exprParser.name()); 3155 3156 Token token = lexer.token; 3157 if (token == Token.PARTITION) { 3158 lexer.nextToken(); 3159 this.accept(Token.LPAREN); 3160 for (;;) { 3161 stmt.getPartition().add(this.exprParser.expr()); 3162 if (lexer.token == Token.COMMA) { 3163 lexer.nextToken(); 3164 continue; 3165 } 3166 if (lexer.token == Token.RPAREN) { 3167 lexer.nextToken(); 3168 break; 3169 } 3170 } 3171 } else if (token == Token.IDENTIFIER) { 3172 SQLName column = this.exprParser.name(); 3173 stmt.setColumn(column); 3174 } 3175 return stmt; 3176 } 3177 3178 public SQLWithSubqueryClause parseWithQuery() { 3179 accept(Token.WITH); 3180 3181 SQLWithSubqueryClause withQueryClause = new SQLWithSubqueryClause(); 3182 3183 if (lexer.token == Token.RECURSIVE || lexer.identifierEquals("RECURSIVE")) { 3184 lexer.nextToken(); 3185 withQueryClause.setRecursive(true); 3186 } 3187 3188 for (;;) { 3189 SQLWithSubqueryClause.Entry entry = new SQLWithSubqueryClause.Entry(); 3190 entry.setParent(withQueryClause); 3191 3192 string _alias = this.lexer.stringVal(); 3193 lexer.nextToken(); 3194 entry.setAlias(_alias); 3195 3196 if (lexer.token == Token.LPAREN) { 3197 lexer.nextToken(); 3198 exprParser.names(entry.getColumns()); 3199 accept(Token.RPAREN); 3200 } 3201 3202 accept(Token.AS); 3203 accept(Token.LPAREN); 3204 3205 switch (lexer.token) { 3206 case Token.VALUES: 3207 case Token.SELECT: 3208 entry.setSubQuery( 3209 this.createSQLSelectParser() 3210 .select()); 3211 break; 3212 case Token.INSERT: 3213 entry.setReturningStatement( 3214 this.parseInsert() 3215 ); 3216 break; 3217 case Token.UPDATE: 3218 entry.setReturningStatement( 3219 this.parseUpdateStatement() 3220 ); 3221 break; 3222 case Token.DELETE: 3223 entry.setReturningStatement( 3224 this.parseDeleteStatement() 3225 ); 3226 break; 3227 default: 3228 break; 3229 } 3230 3231 accept(Token.RPAREN); 3232 3233 withQueryClause.addEntry(entry); 3234 3235 if (lexer.token == Token.COMMA) { 3236 lexer.nextToken(); 3237 continue; 3238 } 3239 3240 break; 3241 } 3242 3243 return withQueryClause; 3244 } 3245 3246 public SQLStatement parseWith() { 3247 SQLWithSubqueryClause _with = this.parseWithQuery(); 3248 3249 if (lexer.token == Token.SELECT) { 3250 SQLSelectParser selectParser = createSQLSelectParser(); 3251 SQLSelect select = selectParser.select(); 3252 select.setWithSubQuery(_with); 3253 return new SQLSelectStatement(select, dbType); 3254 } 3255 3256 throw new ParserException("TODO. " ~ lexer.info()); 3257 } 3258 3259 protected void parseValueClause(List!(ValuesClause) valueClauseList, int columnSize, SQLObject parent) { 3260 bool optimizedForParameterized = lexer.isEnabled(SQLParserFeature.OptimizedForForParameterizedSkipValue); 3261 3262 for (int i = 0; ; ++i) { 3263 int startPos = lexer.pos() - 1; 3264 3265 if (lexer.token() != Token.LPAREN) { 3266 throw new ParserException("syntax error, expect ')', " ~ lexer.info()); 3267 } 3268 lexer.nextTokenValue(); 3269 3270 if (lexer.token() != Token.RPAREN) { 3271 List!(SQLExpr) valueExprList; 3272 if (columnSize > 0) { 3273 valueExprList = new ArrayList!(SQLExpr)(columnSize); 3274 } else { 3275 valueExprList = new ArrayList!(SQLExpr)(); 3276 } 3277 ValuesClause values = new ValuesClause(valueExprList); 3278 values.setParent(parent); 3279 3280 for (; ; ) { 3281 SQLExpr expr; 3282 if (lexer.token() == Token.LITERAL_INT) { 3283 if (optimizedForParameterized) { 3284 expr = new SQLVariantRefExpr("?"); 3285 values.incrementReplaceCount(); 3286 } else { 3287 expr = new SQLIntegerExpr(lexer.integerValue()); 3288 } 3289 lexer.nextTokenCommaValue(); 3290 3291 if (lexer.token != Token.COMMA && lexer.token != Token.RPAREN) { 3292 expr = this.exprParser.exprRest(expr); 3293 } 3294 } else if (lexer.token() == Token.LITERAL_CHARS) { 3295 if (optimizedForParameterized) { 3296 expr = new SQLVariantRefExpr("?"); 3297 values.incrementReplaceCount(); 3298 } else { 3299 expr = new SQLCharExpr(lexer.stringVal()); 3300 } 3301 lexer.nextTokenCommaValue(); 3302 if (lexer.token != Token.COMMA && lexer.token != Token.RPAREN) { 3303 expr = this.exprParser.exprRest(expr); 3304 } 3305 } else if (lexer.token() == Token.LITERAL_NCHARS) { 3306 if (optimizedForParameterized) { 3307 expr = new SQLVariantRefExpr("?"); 3308 values.incrementReplaceCount(); 3309 } else { 3310 expr = new SQLNCharExpr(lexer.stringVal()); 3311 } 3312 lexer.nextTokenCommaValue(); 3313 if (lexer.token != Token.COMMA && lexer.token != Token.RPAREN) { 3314 expr = this.exprParser.exprRest(expr); 3315 } 3316 } else if (lexer.token == Token.NULL) { 3317 if (optimizedForParameterized) { 3318 expr = new SQLVariantRefExpr("?"); 3319 values.incrementReplaceCount(); 3320 } else { 3321 expr = new SQLNullExpr(); 3322 } 3323 lexer.nextTokenCommaValue(); 3324 if (lexer.token != Token.COMMA && lexer.token != Token.RPAREN) { 3325 expr = this.exprParser.exprRest(expr); 3326 } 3327 } else { 3328 expr = exprParser.expr(); 3329 } 3330 3331 if (lexer.token() == Token.COMMA) { 3332 valueExprList.add(expr); 3333 expr.setParent(values); 3334 lexer.nextTokenValue(); 3335 continue; 3336 } else if (lexer.token() == Token.RPAREN) { 3337 valueExprList.add(expr); 3338 expr.setParent(values); 3339 break; 3340 } else { 3341 expr = this.exprParser.primaryRest(expr); 3342 if (lexer.token() != Token.COMMA && lexer.token() != Token.RPAREN) { 3343 expr = this.exprParser.exprRest(expr); 3344 } 3345 3346 valueExprList.add(expr); 3347 if (lexer.token() == Token.COMMA) { 3348 lexer.nextTokenValue(); 3349 continue; 3350 } else { 3351 break; 3352 } 3353 } 3354 } 3355 3356 if (lexer.isEnabled(SQLParserFeature.KeepInsertValueClauseOriginalString)) { 3357 int endPos = lexer.pos(); 3358 string orginalString = lexer.subString(startPos, endPos - startPos); 3359 values.setOriginalString(orginalString); 3360 } 3361 3362 valueClauseList.add(values); 3363 } else { 3364 ValuesClause values = new ValuesClause(new ArrayList!(SQLExpr)(0)); 3365 valueClauseList.add(values); 3366 } 3367 3368 if (lexer.token() != Token.RPAREN) { 3369 throw new ParserException("syntax error. " ~ lexer.info()); 3370 } 3371 3372 if (!parseCompleteValues && valueClauseList.size() >= parseValuesSize) { 3373 lexer.skipToEOF(); 3374 break; 3375 } 3376 3377 lexer.nextTokenComma(); 3378 if (lexer.token() == Token.COMMA) { 3379 lexer.nextTokenLParen(); 3380 continue; 3381 } else { 3382 break; 3383 } 3384 } 3385 } 3386 3387 // protected HiveInsertStatement parseHiveInsertStmt() { 3388 // HiveInsertStatement insert = new HiveInsertStatement(); 3389 3390 // if (lexer.isKeepComments() && lexer.hasComment()) { 3391 // insert.addBeforeComment(lexer.readAndResetComments()); 3392 // } 3393 3394 // SQLSelectParser selectParser = createSQLSelectParser(); 3395 3396 // accept(Token.INSERT); 3397 3398 // if (lexer.token() == Token.INTO) { 3399 // lexer.nextToken(); 3400 // } else { 3401 // accept(Token.OVERWRITE); 3402 // insert.setOverwrite(true); 3403 // } 3404 3405 // accept(Token.TABLE); 3406 // insert.setTableSource(this.exprParser.name()); 3407 3408 // if (lexer.token() == Token.PARTITION) { 3409 // lexer.nextToken(); 3410 // accept(Token.LPAREN); 3411 // for (;;) { 3412 // SQLAssignItem ptExpr = new SQLAssignItem(); 3413 // ptExpr.setTarget(this.exprParser.name()); 3414 // if (lexer.token() == Token.EQ) { 3415 // lexer.nextToken(); 3416 // SQLExpr ptValue = this.exprParser.expr(); 3417 // ptExpr.setValue(ptValue); 3418 // } 3419 // insert.addPartition(ptExpr); 3420 // if (!(lexer.token() == (Token.COMMA))) { 3421 // break; 3422 // } else { 3423 // lexer.nextToken(); 3424 // } 3425 // } 3426 // accept(Token.RPAREN); 3427 // } 3428 3429 // if (lexer.token() == Token.VALUES) { 3430 // lexer.nextToken(); 3431 3432 // for (;;) { 3433 // if (lexer.token() == Token.LPAREN) { 3434 // lexer.nextToken(); 3435 3436 // ValuesClause values = new ValuesClause(); 3437 // this.exprParser.exprList(values.getValues(), values); 3438 // insert.addValueCause(values); 3439 // accept(Token.RPAREN); 3440 // } 3441 3442 // if (lexer.token() == Token.COMMA) { 3443 // lexer.nextToken(); 3444 // continue; 3445 // } else { 3446 // break; 3447 // } 3448 // } 3449 // } else { 3450 // SQLSelect query = selectParser.select(); 3451 // insert.setQuery(query); 3452 // } 3453 3454 // return insert; 3455 // } 3456 3457 // protected HiveInsert parseHiveInsert() { 3458 // HiveInsert insert = new HiveInsert(); 3459 3460 // if (lexer.isKeepComments() && lexer.hasComment()) { 3461 // insert.addBeforeComment(lexer.readAndResetComments()); 3462 // } 3463 3464 // SQLSelectParser selectParser = createSQLSelectParser(); 3465 3466 // accept(Token.INSERT); 3467 3468 // if (lexer.token() == Token.INTO) { 3469 // lexer.nextToken(); 3470 // } else { 3471 // accept(Token.OVERWRITE); 3472 // insert.setOverwrite(true); 3473 // } 3474 3475 // accept(Token.TABLE); 3476 // insert.setTableSource(this.exprParser.name()); 3477 3478 // if (lexer.token() == Token.PARTITION) { 3479 // lexer.nextToken(); 3480 // accept(Token.LPAREN); 3481 // for (;;) { 3482 // SQLAssignItem ptExpr = new SQLAssignItem(); 3483 // ptExpr.setTarget(this.exprParser.name()); 3484 // if (lexer.token() == Token.EQ) { 3485 // lexer.nextToken(); 3486 // SQLExpr ptValue = this.exprParser.expr(); 3487 // ptExpr.setValue(ptValue); 3488 // } 3489 // insert.addPartition(ptExpr); 3490 // if (!(lexer.token() == (Token.COMMA))) { 3491 // break; 3492 // } else { 3493 // lexer.nextToken(); 3494 // } 3495 // } 3496 // accept(Token.RPAREN); 3497 // } 3498 3499 // if (lexer.token() == Token.VALUES) { 3500 // lexer.nextToken(); 3501 3502 // for (;;) { 3503 // if (lexer.token() == Token.LPAREN) { 3504 // lexer.nextToken(); 3505 3506 // ValuesClause values = new ValuesClause(); 3507 // this.exprParser.exprList(values.getValues(), values); 3508 // insert.addValueCause(values); 3509 // accept(Token.RPAREN); 3510 // } 3511 3512 // if (lexer.token() == Token.COMMA) { 3513 // lexer.nextToken(); 3514 // continue; 3515 // } else { 3516 // break; 3517 // } 3518 // } 3519 // } else { 3520 // SQLSelect query = selectParser.select(); 3521 // insert.setQuery(query); 3522 // } 3523 3524 // return insert; 3525 // } 3526 3527 public SQLSelectListCache getSelectListCache() { 3528 return selectListCache; 3529 } 3530 3531 public void setSelectListCache(SQLSelectListCache selectListCache) { 3532 this.selectListCache = selectListCache; 3533 } 3534 }