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.SQLExprParser; 17 18 import hunt.collection; 19 20 import hunt.sql.SQLUtils; 21 import hunt.sql.ast; 22 import hunt.sql.ast.expr; 23 import hunt.sql.ast.statement; 24 // import hunt.sql.dialect.oracle.ast.expr.OracleArgumentExpr; 25 import hunt.sql.dialect.postgresql.ast.expr.PGTypeCastExpr; 26 import hunt.sql.util.FnvHash; 27 import hunt.sql.util.DBType; 28 import hunt.sql.parser.SQLParser; 29 import hunt.sql.parser.Lexer; 30 import hunt.sql.parser.SQLSelectParser; 31 import hunt.sql.parser.Token; 32 import hunt.sql.ast.SQLObject; 33 import hunt.sql.util.Utils; 34 import hunt.Number; 35 import hunt.Integer; 36 import hunt.text; 37 import hunt.Boolean; 38 import hunt.Long; 39 import hunt.sql.parser.ParserException; 40 import hunt.String; 41 import std.algorithm.searching; 42 import hunt.sql.parser.SQLParserFeature; 43 import hunt.Exceptions; 44 import hunt.math; 45 46 import hunt.logging; 47 48 import std.concurrency : initOnce; 49 50 public class SQLExprParser : SQLParser { 51 52 private enum string[] strings = [ "AVG", "COUNT", "MAX", "MIN", "STDDEV", "SUM" ]; 53 54 static string[] AGGREGATE_FUNCTIONS() { 55 __gshared string[] inst; 56 return initOnce!inst({ 57 long[] codes = AGGREGATE_FUNCTIONS_CODES(); 58 string[] r = new string[codes.length]; 59 60 foreach(string str ; strings) { 61 long hash = FnvHash.fnv1a_64_lower(str); 62 int index = search(codes, hash); 63 r[index] = str; 64 } 65 return r; 66 }()); 67 } 68 69 static long[] AGGREGATE_FUNCTIONS_CODES() { 70 __gshared long[] inst; 71 return initOnce!inst({ 72 return FnvHash.fnv1a_64_lower(strings, true); 73 }()); 74 } 75 76 77 // public static string[] AGGREGATE_FUNCTIONS =[]; 78 79 // public static long[] AGGREGATE_FUNCTIONS_CODES = []; 80 81 // static this(){ 82 // string[] strings = [ "AVG", "COUNT", "MAX", "MIN", "STDDEV", "SUM" ]; 83 // AGGREGATE_FUNCTIONS_CODES = FnvHash.fnv1a_64_lower(strings, true); 84 // AGGREGATE_FUNCTIONS = new string[AGGREGATE_FUNCTIONS_CODES.length]; 85 // foreach(string str ; strings) { 86 // long hash = FnvHash.fnv1a_64_lower(str); 87 // int index = search(AGGREGATE_FUNCTIONS_CODES, hash); 88 // AGGREGATE_FUNCTIONS[index] = str; 89 // } 90 // } 91 92 protected string[] aggregateFunctions; 93 94 protected long[] aggregateFunctionHashCodes; 95 96 public this(string sql){ 97 import std.stdio; 98 aggregateFunctions = AGGREGATE_FUNCTIONS; 99 aggregateFunctionHashCodes = AGGREGATE_FUNCTIONS_CODES; 100 super(sql); 101 } 102 103 public this(string sql, string dbType){ 104 aggregateFunctions = AGGREGATE_FUNCTIONS; 105 aggregateFunctionHashCodes = AGGREGATE_FUNCTIONS_CODES; 106 super(sql, dbType); 107 } 108 109 public this(Lexer lexer){ 110 aggregateFunctions = AGGREGATE_FUNCTIONS; 111 aggregateFunctionHashCodes = AGGREGATE_FUNCTIONS_CODES; 112 super(lexer); 113 } 114 115 public this(Lexer lexer, string dbType){ 116 aggregateFunctions = AGGREGATE_FUNCTIONS; 117 aggregateFunctionHashCodes = AGGREGATE_FUNCTIONS_CODES; 118 super(lexer, dbType); 119 } 120 121 public SQLExpr expr() { 122 if (lexer.token == Token.STAR) { 123 lexer.nextToken(); 124 125 SQLExpr expr = new SQLAllColumnExpr(); 126 127 if (lexer.token == Token.DOT) { 128 lexer.nextToken(); 129 accept(Token.STAR); 130 return new SQLPropertyExpr(expr, "*"); 131 } 132 133 return expr; 134 } 135 136 SQLExpr expr = primary(); 137 138 Token token = lexer.token; 139 if (token == Token.COMMA) { 140 return expr; 141 } else if (token == Token.EQ) { 142 expr = relationalRest(expr); 143 expr = andRest(expr); 144 expr = xorRest(expr); 145 expr = orRest(expr); 146 return expr; 147 } else { 148 return exprRest(expr); 149 } 150 } 151 152 public SQLExpr exprRest(SQLExpr expr) { 153 expr = bitXorRest(expr); 154 expr = multiplicativeRest(expr); 155 expr = additiveRest(expr); 156 expr = shiftRest(expr); 157 expr = bitAndRest(expr); 158 expr = bitOrRest(expr); 159 expr = inRest(expr); 160 expr = relationalRest(expr); 161 // expr = equalityRest(expr); 162 expr = andRest(expr); 163 expr = xorRest(expr); 164 expr = orRest(expr); 165 166 return expr; 167 } 168 169 public SQLExpr bitXor() { 170 SQLExpr expr = primary(); 171 return bitXorRest(expr); 172 } 173 174 public SQLExpr bitXorRest(SQLExpr expr) { 175 Token token = lexer.token; 176 switch (token) { 177 case Token.CARET: { 178 lexer.nextToken(); 179 SQLBinaryOperator op; 180 if (lexer.token == Token.EQ) { 181 lexer.nextToken(); 182 op = SQLBinaryOperator.BitwiseXorEQ; 183 } else { 184 op = SQLBinaryOperator.BitwiseXor; 185 } 186 SQLExpr rightExp = primary(); 187 expr = new SQLBinaryOpExpr(expr, op, rightExp, dbType); 188 expr = bitXorRest(expr); 189 break; 190 } 191 case Token.SUBGT:{ 192 lexer.nextToken(); 193 SQLExpr rightExp = primary(); 194 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.SubGt, rightExp, dbType); 195 expr = bitXorRest(expr); 196 break; 197 } 198 case Token.LT_SUB_GT: { 199 lexer.nextToken(); 200 SQLExpr rightExp = primary(); 201 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.PG_ST_DISTANCE, rightExp, dbType); 202 expr = bitXorRest(expr); 203 break; 204 } 205 case Token.SUBGTGT:{ 206 lexer.nextToken(); 207 SQLExpr rightExp = primary(); 208 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.SubGtGt, rightExp, dbType); 209 expr = bitXorRest(expr); 210 break; 211 } 212 case Token.POUNDGT: { 213 lexer.nextToken(); 214 SQLExpr rightExp = primary(); 215 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.PoundGt, rightExp, dbType); 216 expr = bitXorRest(expr); 217 break; 218 } 219 case Token.POUNDGTGT: { 220 lexer.nextToken(); 221 SQLExpr rightExp = primary(); 222 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.PoundGtGt, rightExp, dbType); 223 expr = bitXorRest(expr); 224 break; 225 } 226 case Token.QUESQUES: { 227 lexer.nextToken(); 228 SQLExpr rightExp = primary(); 229 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.QuesQues, rightExp, dbType); 230 expr = bitXorRest(expr); 231 break; 232 } 233 case Token.QUESBAR: { 234 lexer.nextToken(); 235 SQLExpr rightExp = primary(); 236 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.QuesBar, rightExp, dbType); 237 expr = bitXorRest(expr); 238 break; 239 } 240 case Token.QUESAMP: { 241 lexer.nextToken(); 242 SQLExpr rightExp = primary(); 243 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.QuesAmp, rightExp, dbType); 244 expr = bitXorRest(expr); 245 break; 246 } 247 248 default: 249 break; 250 } 251 252 253 return expr; 254 } 255 256 public SQLExpr multiplicative() { 257 SQLExpr expr = bitXor(); 258 return multiplicativeRest(expr); 259 } 260 261 public SQLExpr multiplicativeRest(SQLExpr expr) { 262 Token token = lexer.token; 263 if (token == Token.STAR) { 264 lexer.nextToken(); 265 SQLExpr rightExp = bitXor(); 266 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Multiply, rightExp, getDbType()); 267 expr = multiplicativeRest(expr); 268 } else if (token == Token.SLASH) { 269 lexer.nextToken(); 270 SQLExpr rightExp = bitXor(); 271 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Divide, rightExp, getDbType()); 272 expr = multiplicativeRest(expr); 273 } else if (token == Token.PERCENT) { 274 lexer.nextToken(); 275 SQLExpr rightExp = bitXor(); 276 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Modulus, rightExp, getDbType()); 277 expr = multiplicativeRest(expr); 278 } else if (token == Token.DIV) { 279 lexer.nextToken(); 280 SQLExpr rightExp = bitXor(); 281 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.DIV, rightExp, getDbType()); 282 expr = multiplicativeRest(expr); 283 } else if (lexer.identifierEquals(FnvHash.Constants.MOD) || lexer.token == Token.MOD) { 284 Lexer.SavePoint savePoint = lexer.mark(); 285 lexer.nextToken(); 286 287 if (lexer.token == Token.COMMA || lexer.token == Token.EOF) { 288 lexer.reset(savePoint); 289 return expr; 290 } 291 292 SQLExpr rightExp = bitXor(); 293 294 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Modulus, rightExp, dbType); 295 296 expr = multiplicativeRest(expr); 297 } 298 return expr; 299 } 300 301 public SQLIntegerExpr integerExpr() { 302 SQLIntegerExpr intExpr = new SQLIntegerExpr(lexer.integerValue()); 303 accept(Token.LITERAL_INT); 304 return intExpr; 305 } 306 307 public int parseIntValue() { 308 if (lexer.token == Token.LITERAL_INT) { 309 Number number = this.lexer.integerValue(); 310 int intVal = (cast(Integer) number).intValue(); 311 lexer.nextToken(); 312 return intVal; 313 } else { 314 throw new ParserException("not int. " ~ lexer.info()); 315 } 316 } 317 318 public SQLExpr primary() { 319 List!(string) beforeComments = null; 320 if (lexer.isKeepComments() && lexer.hasComment()) { 321 beforeComments = lexer.readAndResetComments(); 322 } 323 324 SQLExpr sqlExpr = null; 325 326 Token tok = lexer.token; 327 328 switch (tok) { 329 case Token.LPAREN: 330 lexer.nextToken(); 331 332 sqlExpr = this.expr(); 333 if (lexer.token == Token.COMMA) { 334 SQLListExpr listExpr = new SQLListExpr(); 335 listExpr.addItem(sqlExpr); 336 do { 337 lexer.nextToken(); 338 listExpr.addItem(this.expr()); 339 } while (lexer.token == Token.COMMA); 340 341 sqlExpr = listExpr; 342 } 343 344 if (cast(SQLBinaryOpExpr)(sqlExpr) !is null) { 345 (cast(SQLBinaryOpExpr) sqlExpr).setBracket(true); 346 } 347 348 accept(Token.RPAREN); 349 350 if (lexer.token == Token.UNION && cast(SQLQueryExpr)(sqlExpr) !is null) { 351 SQLQueryExpr queryExpr = cast(SQLQueryExpr) sqlExpr; 352 353 SQLSelectQuery query = this.createSelectParser().queryRest(queryExpr.getSubQuery().getQuery()); 354 queryExpr.getSubQuery().setQuery(query); 355 } 356 break; 357 case Token.INSERT: 358 lexer.nextToken(); 359 if (lexer.token != Token.LPAREN) { 360 throw new ParserException("syntax error. " ~ lexer.info()); 361 } 362 sqlExpr = new SQLIdentifierExpr("INSERT"); 363 break; 364 case Token.IDENTIFIER: 365 string ident = lexer.stringVal(); 366 long hash_lower = lexer.hash_lower; 367 lexer.nextToken(); 368 369 if (hash_lower == FnvHash.Constants.DATE 370 && (lexer.token == Token.LITERAL_CHARS || lexer.token == Token.VARIANT) 371 && (DBType.ORACLE.name == (dbType) 372 || DBType.POSTGRESQL.name == (dbType) 373 || DBType.MYSQL.name == (dbType))) { 374 SQLExpr literal = this.primary(); 375 SQLDateExpr dateExpr = new SQLDateExpr(); 376 dateExpr.setLiteral(literal); 377 sqlExpr = dateExpr; 378 } else if (hash_lower == FnvHash.Constants.TIMESTAMP 379 && (lexer.token == Token.LITERAL_CHARS || lexer.token == Token.VARIANT) 380 && !(DBType.ORACLE.name == (dbType))) { 381 SQLTimestampExpr dateExpr = new SQLTimestampExpr(lexer.stringVal()); 382 lexer.nextToken(); 383 sqlExpr = dateExpr; 384 } else if (equalsIgnoreCase(DBType.MYSQL.name, dbType) && ident.startsWith("0x") && (ident.length % 2) == 0) { 385 sqlExpr = new SQLHexExpr(ident.substring(2)); 386 } else { 387 sqlExpr = new SQLIdentifierExpr(ident, hash_lower); 388 } 389 break; 390 case Token.NEW: 391 throw new ParserException("TODO " ~ lexer.info()); 392 case Token.LITERAL_INT: 393 sqlExpr = new SQLIntegerExpr(lexer.integerValue()); 394 lexer.nextToken(); 395 break; 396 case Token.LITERAL_FLOAT: 397 sqlExpr = lexer.numberExpr(); 398 lexer.nextToken(); 399 break; 400 case Token.LITERAL_CHARS: { 401 sqlExpr = new SQLCharExpr(lexer.stringVal()); 402 403 if (DBType.MYSQL.name == (dbType)) { 404 lexer.nextTokenValue(); 405 406 for (; ; ) { 407 if (lexer.token == Token.LITERAL_ALIAS) { 408 string concat = (cast(SQLCharExpr) sqlExpr).getText().value(); 409 concat ~= lexer.stringVal(); 410 lexer.nextTokenValue(); 411 sqlExpr = new SQLCharExpr(concat); 412 } else if (lexer.token == Token.LITERAL_CHARS || lexer.token == Token.LITERAL_NCHARS) { 413 string concat = (cast(SQLCharExpr) sqlExpr).getText().value(); 414 concat ~= lexer.stringVal(); 415 lexer.nextTokenValue(); 416 sqlExpr = new SQLCharExpr(concat); 417 } else { 418 break; 419 } 420 } 421 } else { 422 lexer.nextToken(); 423 } 424 break; 425 } case Token.LITERAL_NCHARS: 426 sqlExpr = new SQLNCharExpr(lexer.stringVal()); 427 lexer.nextToken(); 428 429 if (DBType.MYSQL.name == (dbType)) { 430 SQLMethodInvokeExpr concat = null; 431 for (; ; ) { 432 if (lexer.token == Token.LITERAL_ALIAS) { 433 if (concat is null) { 434 concat = new SQLMethodInvokeExpr("CONCAT"); 435 concat.addParameter(sqlExpr); 436 sqlExpr = concat; 437 } 438 string _alias = lexer.stringVal(); 439 lexer.nextToken(); 440 SQLCharExpr concat_right = new SQLCharExpr(_alias.substring(1, cast(int)(_alias.length - 1))); 441 concat.addParameter(concat_right); 442 } else if (lexer.token == Token.LITERAL_CHARS || lexer.token == Token.LITERAL_NCHARS) { 443 if (concat is null) { 444 concat = new SQLMethodInvokeExpr("CONCAT"); 445 concat.addParameter(sqlExpr); 446 sqlExpr = concat; 447 } 448 449 string chars = lexer.stringVal(); 450 lexer.nextToken(); 451 SQLCharExpr concat_right = new SQLCharExpr(chars); 452 concat.addParameter(concat_right); 453 } else { 454 break; 455 } 456 } 457 } 458 break; 459 case Token.VARIANT: { 460 string varName = lexer.stringVal(); 461 lexer.nextToken(); 462 463 if (varName == (":") && lexer.token == Token.IDENTIFIER && DBType.ORACLE.name == (dbType)) { 464 string part2 = lexer.stringVal(); 465 lexer.nextToken(); 466 varName ~= part2; 467 } 468 469 SQLVariantRefExpr varRefExpr = new SQLVariantRefExpr(varName); 470 if (varName.startsWith(":")) { 471 varRefExpr.setIndex(lexer.nextVarIndex()); 472 } 473 if (varRefExpr.getName() == ("@") && lexer.token == Token.LITERAL_CHARS) { 474 varRefExpr.setName("@'" ~ lexer.stringVal() ~ "'"); 475 lexer.nextToken(); 476 } else if (varRefExpr.getName() == ("@@") && lexer.token == Token.LITERAL_CHARS) { 477 varRefExpr.setName("@@'" ~ lexer.stringVal() ~ "'"); 478 lexer.nextToken(); 479 } 480 sqlExpr = varRefExpr; 481 } 482 break; 483 case Token.DEFAULT: 484 sqlExpr = new SQLDefaultExpr(); 485 lexer.nextToken(); 486 break; 487 case Token.DUAL: 488 case Token.KEY: 489 case Token.DISTINCT: 490 case Token.LIMIT: 491 case Token.SCHEMA: 492 case Token.COLUMN: 493 case Token.IF: 494 case Token.END: 495 case Token.COMMENT: 496 case Token.COMPUTE: 497 case Token.ENABLE: 498 case Token.DISABLE: 499 case Token.INITIALLY: 500 case Token.SEQUENCE: 501 case Token.USER: 502 case Token.EXPLAIN: 503 case Token.WITH: 504 case Token.GRANT: 505 case Token.REPLACE: 506 case Token.INDEX: 507 case Token.MODEL: 508 case Token.PCTFREE: 509 case Token.INITRANS: 510 case Token.MAXTRANS: 511 case Token.SEGMENT: 512 case Token.CREATION: 513 case Token.IMMEDIATE: 514 case Token.DEFERRED: 515 case Token.STORAGE: 516 case Token.NEXT: 517 case Token.MINEXTENTS: 518 case Token.MAXEXTENTS: 519 case Token.MAXSIZE: 520 case Token.PCTINCREASE: 521 case Token.FLASH_CACHE: 522 case Token.CELL_FLASH_CACHE: 523 case Token.NONE: 524 case Token.LOB: 525 case Token.STORE: 526 case Token.ROW: 527 case Token.CHUNK: 528 case Token.CACHE: 529 case Token.NOCACHE: 530 case Token.LOGGING: 531 case Token.NOCOMPRESS: 532 case Token.KEEP_DUPLICATES: 533 case Token.EXCEPTIONS: 534 case Token.PURGE: 535 case Token.FULL: 536 case Token.TO: 537 case Token.IDENTIFIED: 538 case Token.PASSWORD: 539 case Token.BINARY: 540 case Token.WINDOW: 541 case Token.OFFSET: 542 case Token.SHARE: 543 case Token.START: 544 case Token.CONNECT: 545 case Token.MATCHED: 546 case Token.ERRORS: 547 case Token.REJECT: 548 case Token.UNLIMITED: 549 case Token.BEGIN: 550 case Token.EXCLUSIVE: 551 case Token.MODE: 552 case Token.ADVISE: 553 case Token.VIEW: 554 case Token.ESCAPE: 555 case Token.OVER: 556 case Token.ORDER: 557 case Token.CONSTRAINT: 558 case Token.TYPE: 559 case Token.OPEN: 560 case Token.REPEAT: 561 case Token.TABLE: 562 case Token.TRUNCATE: 563 case Token.EXCEPTION: 564 case Token.FUNCTION: 565 case Token.IDENTITY: 566 case Token.EXTRACT: 567 case Token.DESC: 568 case Token.DO: 569 case Token.GROUP: 570 case Token.MOD: 571 case Token.CONCAT: 572 sqlExpr = new SQLIdentifierExpr(lexer.stringVal()); 573 lexer.nextToken(); 574 break; 575 case Token.CASE: 576 SQLCaseExpr caseExpr = new SQLCaseExpr(); 577 lexer.nextToken(); 578 if (lexer.token != Token.WHEN) { 579 caseExpr.setValueExpr(this.expr()); 580 } 581 582 accept(Token.WHEN); 583 SQLExpr testExpr = this.expr(); 584 accept(Token.THEN); 585 SQLExpr valueExpr = this.expr(); 586 SQLCaseExpr.Item caseItem = new SQLCaseExpr.Item(testExpr, valueExpr); 587 caseExpr.addItem(caseItem); 588 589 while (lexer.token == Token.WHEN) { 590 lexer.nextToken(); 591 testExpr = this.expr(); 592 accept(Token.THEN); 593 valueExpr = this.expr(); 594 caseItem = new SQLCaseExpr.Item(testExpr, valueExpr); 595 caseExpr.addItem(caseItem); 596 } 597 598 if (lexer.token == Token.ELSE) { 599 lexer.nextToken(); 600 caseExpr.setElseExpr(this.expr()); 601 } 602 603 accept(Token.END); 604 605 sqlExpr = caseExpr; 606 break; 607 case Token.EXISTS: 608 lexer.nextToken(); 609 accept(Token.LPAREN); 610 sqlExpr = new SQLExistsExpr(createSelectParser().select()); 611 accept(Token.RPAREN); 612 break; 613 case Token.NOT: 614 lexer.nextToken(); 615 if (lexer.token == Token.EXISTS) { 616 lexer.nextToken(); 617 accept(Token.LPAREN); 618 sqlExpr = new SQLExistsExpr(createSelectParser().select(), true); 619 accept(Token.RPAREN); 620 } else if (lexer.token == Token.LPAREN) { 621 lexer.nextToken(); 622 623 SQLExpr notTarget = this.expr(); 624 625 accept(Token.RPAREN); 626 notTarget = relationalRest(notTarget); 627 sqlExpr = new SQLNotExpr(notTarget); 628 629 return primaryRest(sqlExpr); 630 } else { 631 SQLExpr restExpr = relational(); 632 sqlExpr = new SQLNotExpr(restExpr); 633 } 634 break; 635 case Token.SELECT: 636 SQLQueryExpr queryExpr = new SQLQueryExpr( 637 createSelectParser() 638 .select()); 639 sqlExpr = queryExpr; 640 break; 641 case Token.CAST: 642 lexer.nextToken(); 643 accept(Token.LPAREN); 644 SQLCastExpr _cast = new SQLCastExpr(); 645 _cast.setExpr(this.expr()); 646 accept(Token.AS); 647 _cast.setDataType(parseDataType(false)); 648 accept(Token.RPAREN); 649 650 sqlExpr = _cast; 651 break; 652 case Token.SUB: 653 lexer.nextToken(); 654 switch (lexer.token) { 655 case Token.LITERAL_INT: 656 Number integerValue = lexer.integerValue(); 657 if (cast(Integer)(integerValue) !is null) { 658 int intVal = (cast(Integer) integerValue).intValue(); 659 if (intVal == Integer.MIN_VALUE) { 660 integerValue = Long.valueOf((cast(long) intVal) * -1); 661 } else { 662 integerValue = Integer.valueOf(intVal * -1); 663 } 664 } else if (cast(Long)(integerValue) !is null) { 665 long longVal = (cast(Long) integerValue).longValue(); 666 if (longVal == 2147483648L) { 667 integerValue = Integer.valueOf(cast(int) ((cast(long) longVal) * -1)); 668 } else { 669 integerValue = Long.valueOf(longVal * -1); 670 } 671 } else { 672 integerValue = (cast(BigInteger) integerValue).negate(); 673 } 674 sqlExpr = new SQLIntegerExpr(integerValue); 675 lexer.nextToken(); 676 break; 677 case Token.LITERAL_FLOAT: 678 sqlExpr = lexer.numberExpr(true); 679 lexer.nextToken(); 680 break; 681 case Token.IDENTIFIER: // 当负号后面为字段的情况 682 sqlExpr = new SQLIdentifierExpr(lexer.stringVal()); 683 lexer.nextToken(); 684 685 if (lexer.token == Token.LPAREN || lexer.token == Token.LBRACKET) { 686 sqlExpr = primaryRest(sqlExpr); 687 } 688 sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Negative, sqlExpr); 689 690 break; 691 case Token.QUES: { 692 SQLVariantRefExpr variantRefExpr = new SQLVariantRefExpr("?"); 693 variantRefExpr.setIndex(lexer.nextVarIndex()); 694 sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Negative, variantRefExpr); 695 lexer.nextToken(); 696 break; 697 } 698 case Token.LPAREN: 699 lexer.nextToken(); 700 sqlExpr = this.expr(); 701 accept(Token.RPAREN); 702 sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Negative, sqlExpr); 703 break; 704 case Token.BANG: 705 sqlExpr = this.expr(); 706 sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Negative, sqlExpr); 707 break; 708 default: 709 throw new ParserException("TODO : " ~ lexer.info()); 710 } 711 break; 712 case Token.PLUS: 713 lexer.nextToken(); 714 switch (lexer.token) { 715 case Token.LITERAL_INT: 716 sqlExpr = new SQLIntegerExpr(lexer.integerValue()); 717 lexer.nextToken(); 718 break; 719 case Token.LITERAL_FLOAT: 720 sqlExpr = lexer.numberExpr(); 721 lexer.nextToken(); 722 break; 723 case Token.IDENTIFIER: // 当~号后面为字段的情况 724 sqlExpr = new SQLIdentifierExpr(lexer.stringVal()); 725 sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Plus, sqlExpr); 726 lexer.nextToken(); 727 break; 728 case Token.LPAREN: 729 lexer.nextToken(); 730 sqlExpr = this.expr(); 731 accept(Token.RPAREN); 732 sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Plus, sqlExpr); 733 break; 734 case Token.SUB: 735 sqlExpr = this.expr(); 736 sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Plus, sqlExpr); 737 break; 738 default: 739 throw new ParserException("TODO " ~ lexer.info()); 740 } 741 break; 742 case Token.TILDE: 743 lexer.nextToken(); 744 SQLExpr unaryValueExpr = primary(); 745 SQLUnaryExpr unary = new SQLUnaryExpr(SQLUnaryOperator.Compl, unaryValueExpr); 746 sqlExpr = unary; 747 break; 748 case Token.QUES: 749 if (DBType.MYSQL.name == (dbType)) { 750 lexer.nextTokenValue(); 751 } else { 752 lexer.nextToken(); 753 } 754 SQLVariantRefExpr quesVarRefExpr = new SQLVariantRefExpr("?"); 755 quesVarRefExpr.setIndex(lexer.nextVarIndex()); 756 sqlExpr = quesVarRefExpr; 757 break; 758 case Token.LEFT: 759 sqlExpr = new SQLIdentifierExpr("LEFT"); 760 lexer.nextToken(); 761 break; 762 case Token.RIGHT: 763 sqlExpr = new SQLIdentifierExpr("RIGHT"); 764 lexer.nextToken(); 765 break; 766 case Token.DATABASE: 767 sqlExpr = new SQLIdentifierExpr("DATABASE"); 768 lexer.nextToken(); 769 break; 770 case Token.LOCK: 771 sqlExpr = new SQLIdentifierExpr("LOCK"); 772 lexer.nextToken(); 773 break; 774 case Token.NULL: 775 sqlExpr = new SQLNullExpr(); 776 lexer.nextToken(); 777 break; 778 case Token.BANG: 779 lexer.nextToken(); 780 SQLExpr bangExpr = primary(); 781 sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Not, bangExpr); 782 break; 783 case Token.LITERAL_HEX: 784 string hex = lexer.hexString(); 785 sqlExpr = new SQLHexExpr(hex); 786 lexer.nextToken(); 787 break; 788 case Token.INTERVAL: 789 sqlExpr = parseInterval(); 790 break; 791 case Token.COLON: 792 lexer.nextToken(); 793 if (lexer.token == Token.LITERAL_ALIAS) { 794 sqlExpr = new SQLVariantRefExpr(":\"" ~ lexer.stringVal() ~ "\""); 795 lexer.nextToken(); 796 } 797 break; 798 case Token.ANY: 799 sqlExpr = parseAny(); 800 break; 801 case Token.SOME: 802 sqlExpr = parseSome(); 803 break; 804 case Token.ALL: 805 sqlExpr = parseAll(); 806 break; 807 case Token.LITERAL_ALIAS: 808 sqlExpr = parseAliasExpr(lexer.stringVal()); 809 lexer.nextToken(); 810 break; 811 case Token.EOF: 812 throw new ParserException("EOF"); 813 case Token.TRUE: 814 lexer.nextToken(); 815 sqlExpr = new SQLBooleanExpr(true); 816 break; 817 case Token.FALSE: 818 lexer.nextToken(); 819 sqlExpr = new SQLBooleanExpr(false); 820 break; 821 case Token.BITS: { 822 string strVal = lexer.stringVal(); 823 lexer.nextToken(); 824 sqlExpr = new SQLBinaryExpr(strVal); 825 break; 826 } 827 case Token.CONTAINS: 828 sqlExpr = inRest(null); 829 break; 830 case Token.SET: { 831 Lexer.SavePoint savePoint = lexer.mark(); 832 lexer.nextToken(); 833 if (lexer.token() == Token.LPAREN) { 834 sqlExpr = new SQLIdentifierExpr("SET"); 835 } else { 836 lexer.reset(savePoint); 837 throw new ParserException("ERROR. " ~ lexer.info()); 838 } 839 break; 840 } 841 842 default: 843 throw new ParserException("ERROR. " ~ lexer.info()); 844 } 845 846 SQLExpr expr = primaryRest(sqlExpr); 847 848 if (beforeComments !is null) { 849 expr.addBeforeComment(beforeComments); 850 } 851 852 return expr; 853 } 854 855 protected SQLExpr parseAll() { 856 SQLExpr sqlExpr; 857 lexer.nextToken(); 858 SQLAllExpr allExpr = new SQLAllExpr(); 859 860 accept(Token.LPAREN); 861 SQLSelect allSubQuery = createSelectParser().select(); 862 allExpr.setSubQuery(allSubQuery); 863 accept(Token.RPAREN); 864 865 allSubQuery.setParent(allExpr); 866 867 sqlExpr = allExpr; 868 return sqlExpr; 869 } 870 871 protected SQLExpr parseSome() { 872 SQLExpr sqlExpr; 873 lexer.nextToken(); 874 SQLSomeExpr someExpr = new SQLSomeExpr(); 875 876 accept(Token.LPAREN); 877 SQLSelect someSubQuery = createSelectParser().select(); 878 someExpr.setSubQuery(someSubQuery); 879 accept(Token.RPAREN); 880 881 someSubQuery.setParent(someExpr); 882 883 sqlExpr = someExpr; 884 return sqlExpr; 885 } 886 887 protected SQLExpr parseAny() { 888 SQLExpr sqlExpr; 889 lexer.nextToken(); 890 if (lexer.token == Token.LPAREN) { 891 accept(Token.LPAREN); 892 893 if (lexer.token == Token.ARRAY || lexer.token == Token.IDENTIFIER) { 894 SQLExpr expr = this.expr(); 895 SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr("ANY"); 896 methodInvokeExpr.addParameter(expr); 897 accept(Token.RPAREN); 898 return methodInvokeExpr; 899 } 900 901 SQLSelect anySubQuery = createSelectParser().select(); 902 SQLAnyExpr anyExpr = new SQLAnyExpr(anySubQuery); 903 accept(Token.RPAREN); 904 905 sqlExpr = anyExpr; 906 } else { 907 sqlExpr = new SQLIdentifierExpr("ANY"); 908 } 909 return sqlExpr; 910 } 911 912 protected SQLExpr parseAliasExpr(string _alias) { 913 return new SQLIdentifierExpr(_alias); 914 } 915 916 protected SQLExpr parseInterval() { 917 throw new ParserException("TODO. " ~ lexer.info()); 918 } 919 920 public SQLSelectParser createSelectParser() { 921 return new SQLSelectParser(this); 922 } 923 924 public SQLExpr primaryRest(SQLExpr expr) { 925 if (expr is null) { 926 throw new Exception("expr"); 927 } 928 929 Token token = lexer.token; 930 if (token == Token.OF) { 931 if (cast(SQLIdentifierExpr)(expr) !is null) { 932 long hashCode64 = (cast(SQLIdentifierExpr) expr).hashCode64(); 933 if (hashCode64 == FnvHash.Constants.CURRENT) { 934 lexer.nextToken(); 935 SQLName cursorName = this.name(); 936 return new SQLCurrentOfCursorExpr(cursorName); 937 } 938 } 939 } else if (token == Token.FOR) { 940 if (cast(SQLIdentifierExpr)(expr) !is null) { 941 SQLIdentifierExpr idenExpr = cast(SQLIdentifierExpr) expr; 942 if (idenExpr.hashCode64() == FnvHash.Constants.NEXTVAL) { 943 lexer.nextToken(); 944 SQLName seqName = this.name(); 945 SQLSequenceExpr seqExpr = new SQLSequenceExpr(seqName, SQLSequenceExpr.Function.NextVal); 946 return seqExpr; 947 } else if (idenExpr.hashCode64() == FnvHash.Constants.CURRVAL) { 948 lexer.nextToken(); 949 SQLName seqName = this.name(); 950 SQLSequenceExpr seqExpr = new SQLSequenceExpr(seqName, SQLSequenceExpr.Function.CurrVal); 951 return seqExpr; 952 } else if (idenExpr.hashCode64() == FnvHash.Constants.PREVVAL) { 953 lexer.nextToken(); 954 SQLName seqName = this.name(); 955 SQLSequenceExpr seqExpr = new SQLSequenceExpr(seqName, SQLSequenceExpr.Function.PrevVal); 956 return seqExpr; 957 } 958 } 959 } 960 961 if (token == Token.DOT) { 962 lexer.nextToken(); 963 964 if (cast(SQLCharExpr)(expr) !is null) { 965 string text = (cast(SQLCharExpr) expr).getText().value(); 966 expr = new SQLIdentifierExpr(text); 967 } 968 969 expr = dotRest(expr); 970 return primaryRest(expr); 971 } else if (lexer.identifierEquals(FnvHash.Constants.SETS) // 972 && typeid(expr) == typeid(SQLIdentifierExpr) // 973 && "GROUPING".equalsIgnoreCase((cast(SQLIdentifierExpr) expr).getName())) { 974 SQLGroupingSetExpr groupingSets = new SQLGroupingSetExpr(); 975 lexer.nextToken(); 976 977 accept(Token.LPAREN); 978 979 for (; ; ) { 980 SQLExpr item; 981 if (lexer.token == Token.LPAREN) { 982 lexer.nextToken(); 983 984 SQLListExpr listExpr = new SQLListExpr(); 985 this.exprList(listExpr.getItems(), listExpr); 986 item = listExpr; 987 988 accept(Token.RPAREN); 989 } else { 990 item = this.expr(); 991 } 992 993 item.setParent(groupingSets); 994 groupingSets.addParameter(item); 995 996 if (lexer.token == Token.RPAREN) { 997 break; 998 } 999 1000 accept(Token.COMMA); 1001 } 1002 1003 this.exprList(groupingSets.getParameters(), groupingSets); 1004 1005 accept(Token.RPAREN); 1006 1007 return groupingSets; 1008 } else { 1009 if (lexer.token == Token.LPAREN) { 1010 return methodRest(expr, true); 1011 } 1012 } 1013 1014 return expr; 1015 } 1016 1017 protected SQLExpr parseExtract() { 1018 throw new ParserException("not supported."); 1019 } 1020 1021 protected SQLExpr parsePosition() { 1022 throw new ParserException("not supported."); 1023 } 1024 1025 protected SQLExpr parseMatch() { 1026 throw new ParserException("not supported."); 1027 } 1028 1029 protected SQLExpr methodRest(SQLExpr expr, bool acceptLPAREN) { 1030 if (acceptLPAREN) { 1031 accept(Token.LPAREN); 1032 } 1033 1034 bool distinct = false; 1035 if (lexer.token == Token.DISTINCT) { 1036 lexer.nextToken(); 1037 distinct = true; 1038 } 1039 1040 string methodName = null; 1041 string aggMethodName = null; 1042 SQLMethodInvokeExpr methodInvokeExpr; 1043 SQLExpr owner = null; 1044 string trimOption = null; 1045 1046 long hash_lower = 0L; 1047 if (cast(SQLIdentifierExpr)(expr) !is null) { 1048 SQLIdentifierExpr identifierExpr = cast(SQLIdentifierExpr) expr; 1049 methodName = identifierExpr.getName(); 1050 hash_lower = identifierExpr.nameHashCode64(); 1051 1052 if (hash_lower == FnvHash.Constants.TRIM) { 1053 if (lexer.identifierEquals(FnvHash.Constants.LEADING)) { 1054 trimOption = lexer.stringVal(); 1055 lexer.nextToken(); 1056 } else if (lexer.identifierEquals(FnvHash.Constants.BOTH)) { 1057 trimOption = lexer.stringVal(); 1058 lexer.nextToken(); 1059 } else if (lexer.identifierEquals(FnvHash.Constants.TRAILING)) { 1060 trimOption = lexer.stringVal(); 1061 lexer.nextToken(); 1062 } 1063 } else if (hash_lower == FnvHash.Constants.MATCH 1064 && DBType.MYSQL.name == (dbType)) { 1065 return parseMatch(); 1066 } else if (hash_lower == FnvHash.Constants.EXTRACT 1067 && DBType.MYSQL.name == (dbType)) { 1068 return parseExtract(); 1069 } else if (hash_lower == FnvHash.Constants.POSITION 1070 && DBType.MYSQL.name == (dbType)) { 1071 return parsePosition(); 1072 } else if (hash_lower == FnvHash.Constants.INT4 && DBType.POSTGRESQL.name == (dbType)) { 1073 PGTypeCastExpr castExpr = new PGTypeCastExpr(); 1074 castExpr.setExpr(this.expr()); 1075 castExpr.setDataType(new SQLDataTypeImpl(methodName)); 1076 accept(Token.RPAREN); 1077 return castExpr; 1078 } else if (hash_lower == FnvHash.Constants.VARBIT && DBType.POSTGRESQL.name == (dbType)) { 1079 PGTypeCastExpr castExpr = new PGTypeCastExpr(); 1080 SQLExpr len = this.primary(); 1081 castExpr.setDataType(new SQLDataTypeImpl(methodName, len)); 1082 accept(Token.RPAREN); 1083 castExpr.setExpr(this.expr()); 1084 return castExpr; 1085 } 1086 aggMethodName = getAggreateFunction(hash_lower); 1087 } else if (cast(SQLPropertyExpr)(expr) !is null) { 1088 methodName = (cast(Object)(expr)).toString(); 1089 aggMethodName = SQLUtils.normalize(methodName); 1090 hash_lower = FnvHash.fnv1a_64_lower(aggMethodName); 1091 aggMethodName = getAggreateFunction(hash_lower); 1092 1093 owner = (cast(SQLPropertyExpr) expr).getOwner(); 1094 } else if (cast(SQLDefaultExpr)(expr) !is null) { 1095 methodName = "DEFAULT"; 1096 } else if (cast(SQLCharExpr)(expr) !is null) { 1097 methodName = (cast(SQLCharExpr) expr).getText().value(); 1098 } 1099 1100 if (aggMethodName !is null) { 1101 SQLAggregateExpr aggregateExpr = parseAggregateExpr(aggMethodName); 1102 if (distinct) { 1103 aggregateExpr.setOption(SQLAggregateOption.DISTINCT); 1104 } 1105 1106 1107 return aggregateExpr; 1108 } 1109 1110 methodInvokeExpr = new SQLMethodInvokeExpr(methodName, hash_lower); 1111 if (owner !is null) { 1112 methodInvokeExpr.setOwner(owner); 1113 } 1114 if (trimOption !is null) { 1115 methodInvokeExpr.setTrimOption(trimOption); 1116 } 1117 1118 Token token = lexer.token; 1119 if (token != Token.RPAREN && token != Token.FROM) { 1120 exprList(methodInvokeExpr.getParameters(), methodInvokeExpr); 1121 } 1122 1123 if (hash_lower == FnvHash.Constants.EXIST 1124 && methodInvokeExpr.getParameters().size() == 1 1125 && methodInvokeExpr.getParameters().get(0) !is null) { 1126 throw new ParserException("exists syntax error."); 1127 } 1128 1129 if (lexer.token == Token.FROM) { 1130 lexer.nextToken(); 1131 SQLExpr from = this.expr(); 1132 methodInvokeExpr.setFrom(from); 1133 1134 if (lexer.token == Token.FOR) { 1135 lexer.nextToken(); 1136 SQLExpr forExpr = this.expr(); 1137 methodInvokeExpr.setFor(forExpr); 1138 } 1139 } 1140 1141 if (lexer.token == Token.USING || lexer.identifierEquals(FnvHash.Constants.USING)) { 1142 lexer.nextToken(); 1143 SQLExpr using; 1144 if (lexer.token == Token.STAR) { 1145 lexer.nextToken(); 1146 using = new SQLAllColumnExpr(); 1147 } else if (lexer.token == Token.BINARY) { 1148 using = new SQLIdentifierExpr(lexer.stringVal()); 1149 lexer.nextToken(); 1150 } else { 1151 using = this.primary(); 1152 } 1153 methodInvokeExpr.setUsing(using); 1154 } 1155 1156 SQLAggregateExpr aggregateExpr = null; 1157 if (lexer.token == Token.ORDER) { 1158 lexer.nextToken(); 1159 accept(Token.BY); 1160 1161 aggregateExpr = new SQLAggregateExpr(methodName); 1162 aggregateExpr.getArguments().addAll(methodInvokeExpr.getParameters()); 1163 1164 SQLOrderBy orderBy = new SQLOrderBy(); 1165 this.orderBy(orderBy.getItems(), orderBy); 1166 aggregateExpr.setWithinGroup(orderBy); 1167 } 1168 1169 accept(Token.RPAREN); 1170 1171 if (lexer.token == Token.OVER) { 1172 if (aggregateExpr is null) { 1173 aggregateExpr = new SQLAggregateExpr(methodName); 1174 aggregateExpr.getArguments().addAll(methodInvokeExpr.getParameters()); 1175 } 1176 over(aggregateExpr); 1177 } 1178 1179 if (aggregateExpr !is null) { 1180 return primaryRest(aggregateExpr); 1181 } 1182 1183 return primaryRest(methodInvokeExpr); 1184 1185 //throw new ParserException("not support token:" ~ lexer.token ~ ", " ~ lexer.info()); 1186 } 1187 1188 protected SQLExpr dotRest(SQLExpr expr) { 1189 if (lexer.token == Token.STAR) { 1190 lexer.nextToken(); 1191 expr = new SQLPropertyExpr(expr, "*"); 1192 } else { 1193 string name; 1194 long hash_lower = 0L; 1195 1196 if (lexer.token == Token.IDENTIFIER) { 1197 name = lexer.stringVal(); 1198 hash_lower = lexer.hash_lower; 1199 lexer.nextToken(); 1200 } else if (lexer.token == Token.LITERAL_CHARS 1201 || lexer.token == Token.LITERAL_ALIAS) { 1202 name = lexer.stringVal(); 1203 lexer.nextToken(); 1204 } else if (lexer.getKeywods().containsValue(lexer.token)) { 1205 name = lexer.stringVal(); 1206 lexer.nextToken(); 1207 } else { 1208 throw new ParserException("error : " ~ lexer.info()); 1209 } 1210 1211 if (lexer.token == Token.LPAREN) { 1212 bool aggregate = hash_lower == FnvHash.Constants.WM_CONCAT 1213 && cast(SQLIdentifierExpr)(expr) !is null 1214 && (cast(SQLIdentifierExpr) expr).nameHashCode64() == FnvHash.Constants.WMSYS; 1215 expr = methodRest(expr, name, aggregate); 1216 } else { 1217 expr = new SQLPropertyExpr(expr, name, hash_lower); 1218 } 1219 } 1220 1221 expr = primaryRest(expr); 1222 return expr; 1223 } 1224 1225 private SQLExpr methodRest(SQLExpr expr, string name, bool aggregate) { 1226 lexer.nextToken(); 1227 1228 if (lexer.token == Token.DISTINCT) { 1229 lexer.nextToken(); 1230 1231 string aggreateMethodName = (cast(Object)(expr)).toString() ~ "." ~ name; 1232 SQLAggregateExpr aggregateExpr = new SQLAggregateExpr(aggreateMethodName, SQLAggregateOption.DISTINCT); 1233 1234 if (lexer.token == Token.RPAREN) { 1235 lexer.nextToken(); 1236 } else { 1237 if (lexer.token == Token.PLUS) { 1238 aggregateExpr.getArguments().add(new SQLIdentifierExpr("~")); 1239 lexer.nextToken(); 1240 } else { 1241 exprList(aggregateExpr.getArguments(), aggregateExpr); 1242 } 1243 accept(Token.RPAREN); 1244 } 1245 expr = aggregateExpr; 1246 } else if (aggregate) { 1247 SQLAggregateExpr methodInvokeExpr = new SQLAggregateExpr(name); 1248 methodInvokeExpr.setMethodName((cast(Object)(expr)).toString() ~ "." ~ name); 1249 if (lexer.token == Token.RPAREN) { 1250 lexer.nextToken(); 1251 } else { 1252 if (lexer.token == Token.PLUS) { 1253 methodInvokeExpr.addArgument(new SQLIdentifierExpr("~")); 1254 lexer.nextToken(); 1255 } else { 1256 exprList(methodInvokeExpr.getArguments(), methodInvokeExpr); 1257 } 1258 accept(Token.RPAREN); 1259 } 1260 1261 if (lexer.token == Token.OVER) { 1262 over(methodInvokeExpr); 1263 } 1264 1265 expr = methodInvokeExpr; 1266 } else { 1267 SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr(name); 1268 methodInvokeExpr.setOwner(expr); 1269 if (lexer.token == Token.RPAREN) { 1270 lexer.nextToken(); 1271 } else { 1272 if (lexer.token == Token.PLUS) { 1273 methodInvokeExpr.addParameter(new SQLIdentifierExpr("~")); 1274 lexer.nextToken(); 1275 } else { 1276 exprList(methodInvokeExpr.getParameters(), methodInvokeExpr); 1277 } 1278 accept(Token.RPAREN); 1279 } 1280 expr = methodInvokeExpr; 1281 } 1282 return expr; 1283 } 1284 1285 public SQLExpr groupComparisionRest(SQLExpr expr) { 1286 return expr; 1287 } 1288 1289 public void names(Collection!(SQLName) exprCol) { 1290 names(exprCol, null); 1291 } 1292 1293 public void names(Collection!(SQLName) exprCol, SQLObject parent) { 1294 if (lexer.token == Token.RBRACE) { 1295 return; 1296 } 1297 1298 if (lexer.token == Token.EOF) { 1299 return; 1300 } 1301 1302 SQLName name = name(); 1303 name.setParent(parent); 1304 exprCol.add(name); 1305 1306 while (lexer.token == Token.COMMA) { 1307 lexer.nextToken(); 1308 1309 name = this.name(); 1310 name.setParent(parent); 1311 exprCol.add(name); 1312 } 1313 } 1314 1315 //@Deprecated 1316 public void exprList(Collection!(SQLExpr) exprCol) { 1317 exprList(exprCol, null); 1318 } 1319 1320 public void exprList(Collection!(SQLExpr) exprCol, SQLObject parent) { 1321 if (lexer.token == Token.RPAREN || lexer.token == Token.RBRACKET) { 1322 return; 1323 } 1324 1325 if (lexer.token == Token.EOF) { 1326 return; 1327 } 1328 1329 SQLExpr expr = expr(); 1330 expr.setParent(parent); 1331 exprCol.add(expr); 1332 1333 while (lexer.token == Token.COMMA) { 1334 lexer.nextToken(); 1335 expr = this.expr(); 1336 expr.setParent(parent); 1337 exprCol.add(expr); 1338 } 1339 } 1340 1341 public SQLName name() { 1342 string identName; 1343 long hash = 0; 1344 if (lexer.token == Token.LITERAL_ALIAS) { 1345 identName = lexer.stringVal(); 1346 lexer.nextToken(); 1347 } else if (lexer.token == Token.IDENTIFIER) { 1348 identName = lexer.stringVal(); 1349 1350 char c0 = charAt(identName, 0); 1351 if (c0 != '[') { 1352 hash = lexer.hash_lower(); 1353 } 1354 lexer.nextToken(); 1355 } else if (lexer.token == Token.LITERAL_CHARS) { 1356 identName = '\'' ~ lexer.stringVal() ~ '\''; 1357 lexer.nextToken(); 1358 } else if (lexer.token == Token.VARIANT) { 1359 identName = lexer.stringVal(); 1360 lexer.nextToken(); 1361 } else { 1362 switch (lexer.token) { 1363 case Token.MODEL: 1364 case Token.PCTFREE: 1365 case Token.INITRANS: 1366 case Token.MAXTRANS: 1367 case Token.SEGMENT: 1368 case Token.CREATION: 1369 case Token.IMMEDIATE: 1370 case Token.DEFERRED: 1371 case Token.STORAGE: 1372 case Token.NEXT: 1373 case Token.MINEXTENTS: 1374 case Token.MAXEXTENTS: 1375 case Token.MAXSIZE: 1376 case Token.PCTINCREASE: 1377 case Token.FLASH_CACHE: 1378 case Token.CELL_FLASH_CACHE: 1379 case Token.NONE: 1380 case Token.LOB: 1381 case Token.STORE: 1382 case Token.ROW: 1383 case Token.CHUNK: 1384 case Token.CACHE: 1385 case Token.NOCACHE: 1386 case Token.LOGGING: 1387 case Token.NOCOMPRESS: 1388 case Token.KEEP_DUPLICATES: 1389 case Token.EXCEPTIONS: 1390 case Token.PURGE: 1391 case Token.INITIALLY: 1392 case Token.END: 1393 case Token.COMMENT: 1394 case Token.ENABLE: 1395 case Token.DISABLE: 1396 case Token.SEQUENCE: 1397 case Token.USER: 1398 case Token.ANALYZE: 1399 case Token.OPTIMIZE: 1400 case Token.GRANT: 1401 case Token.REVOKE: 1402 // binary有很多含义,lexer识别了这个token,实际上应该当做普通IDENTIFIER 1403 case Token.BINARY: 1404 case Token.OVER: 1405 case Token.ORDER: 1406 case Token.DO: 1407 case Token.JOIN: 1408 case Token.TYPE: 1409 case Token.FUNCTION: 1410 case Token.KEY: 1411 case Token.SCHEMA: 1412 case Token.INTERVAL: 1413 case Token.EXPLAIN: 1414 case Token.PARTITION: 1415 case Token.SET: 1416 identName = lexer.stringVal(); 1417 lexer.nextToken(); 1418 break; 1419 default: 1420 throw new ParserException("error " ~ lexer.info()); 1421 } 1422 } 1423 1424 SQLName name = new SQLIdentifierExpr(identName, hash); 1425 1426 name = nameRest(name); 1427 1428 return name; 1429 } 1430 1431 public SQLName nameRest(SQLName name) { 1432 if (lexer.token == Token.DOT) { 1433 lexer.nextToken(); 1434 1435 if (lexer.token == Token.KEY) { 1436 name = new SQLPropertyExpr(name, "KEY"); 1437 lexer.nextToken(); 1438 return name; 1439 } 1440 1441 if (lexer.token != Token.LITERAL_ALIAS && lexer.token != Token.IDENTIFIER 1442 && (!lexer.getKeywods().containsValue(lexer.token))) { 1443 throw new ParserException("error, " ~ lexer.info()); 1444 } 1445 1446 if (lexer.token == Token.LITERAL_ALIAS) { 1447 name = new SQLPropertyExpr(name, lexer.stringVal()); 1448 } else { 1449 name = new SQLPropertyExpr(name, lexer.stringVal()); 1450 } 1451 lexer.nextToken(); 1452 name = nameRest(name); 1453 } 1454 1455 return name; 1456 } 1457 1458 public bool isAggreateFunction(string word) { 1459 long hash_lower = FnvHash.fnv1a_64_lower(word); 1460 return isAggreateFunction(hash_lower); 1461 } 1462 1463 protected bool isAggreateFunction(long hash_lower) { 1464 return search(aggregateFunctionHashCodes, hash_lower) >= 0; 1465 } 1466 1467 protected string getAggreateFunction(long hash_lower) { 1468 int index = search(aggregateFunctionHashCodes, hash_lower); 1469 if (index < 0) { 1470 return null; 1471 } 1472 return aggregateFunctions[index]; 1473 } 1474 1475 protected SQLAggregateExpr parseAggregateExpr(string methodName) { 1476 SQLAggregateExpr aggregateExpr; 1477 if (lexer.token == Token.ALL) { 1478 aggregateExpr = new SQLAggregateExpr(methodName, SQLAggregateOption.ALL); 1479 lexer.nextToken(); 1480 } else if (lexer.token == Token.DISTINCT) { 1481 aggregateExpr = new SQLAggregateExpr(methodName, SQLAggregateOption.DISTINCT); 1482 lexer.nextToken(); 1483 } else if (lexer.identifierEquals(FnvHash.Constants.DEDUPLICATION)) { // just for nut 1484 aggregateExpr = new SQLAggregateExpr(methodName, SQLAggregateOption.DEDUPLICATION); 1485 lexer.nextToken(); 1486 } else { 1487 aggregateExpr = new SQLAggregateExpr(methodName); 1488 } 1489 1490 exprList(aggregateExpr.getArguments(), aggregateExpr); 1491 1492 if (lexer.token != Token.RPAREN) { 1493 parseAggregateExprRest(aggregateExpr); 1494 } 1495 1496 accept(Token.RPAREN); 1497 1498 if (lexer.identifierEquals(FnvHash.Constants.FILTER)) { 1499 filter(aggregateExpr); 1500 } 1501 1502 if (lexer.token == Token.OVER) { 1503 over(aggregateExpr); 1504 } 1505 1506 return aggregateExpr; 1507 } 1508 1509 protected void filter(SQLAggregateExpr aggregateExpr) { 1510 1511 } 1512 1513 public void over(SQLAggregateExpr aggregateExpr) { 1514 lexer.nextToken(); 1515 1516 if (lexer.token != Token.LPAREN) { 1517 SQLName overRef = this.name(); 1518 aggregateExpr.setOverRef(overRef); 1519 return; 1520 } 1521 1522 SQLOver Sover = new SQLOver(); 1523 over(Sover); 1524 aggregateExpr.setOver(Sover); 1525 } 1526 1527 public void over(SQLOver over) { 1528 lexer.nextToken(); 1529 1530 if (lexer.token == Token.PARTITION || lexer.identifierEquals("PARTITION")) { 1531 lexer.nextToken(); 1532 accept(Token.BY); 1533 1534 if (lexer.token == (Token.LPAREN)) { 1535 lexer.nextToken(); 1536 exprList(over.getPartitionBy(), over); 1537 accept(Token.RPAREN); 1538 } else { 1539 exprList(over.getPartitionBy(), over); 1540 } 1541 } 1542 1543 over.setOrderBy(parseOrderBy()); 1544 1545 if (lexer.token == Token.OF) { 1546 lexer.nextToken(); 1547 SQLName of = this.name(); 1548 over.setOf(of); 1549 } 1550 1551 SQLOver.WindowingType windowingType; 1552 bool is_set =false; 1553 if (lexer.identifierEquals(FnvHash.Constants.ROWS) || lexer.token == Token.ROWS) { 1554 windowingType = SQLOver.WindowingType.ROWS; 1555 is_set =true; 1556 1557 } else if (lexer.identifierEquals(FnvHash.Constants.RANGE)) { 1558 windowingType = SQLOver.WindowingType.RANGE; 1559 is_set =true; 1560 } 1561 1562 if (is_set) { 1563 over.setWindowingType(windowingType); 1564 lexer.nextToken(); 1565 1566 if (lexer.token == Token.BETWEEN) { 1567 lexer.nextToken(); 1568 SQLExpr rowsBegin = this.primary(); 1569 over.setWindowingBetweenBegin(rowsBegin); 1570 1571 if (lexer.identifierEquals(FnvHash.Constants.PRECEDING)) { 1572 over.setWindowingBetweenBeginPreceding(true); 1573 lexer.nextToken(); 1574 } else if (lexer.identifierEquals(FnvHash.Constants.FOLLOWING)) { 1575 over.setWindowingBetweenBeginFollowing(true); 1576 lexer.nextToken(); 1577 } 1578 1579 accept(Token.AND); 1580 1581 SQLExpr betweenEnd; 1582 if (lexer.identifierEquals(FnvHash.Constants.CURRENT) || lexer.token == Token.CURRENT) { 1583 lexer.nextToken(); 1584 if (lexer.identifierEquals(FnvHash.Constants.ROW)) { 1585 lexer.nextToken(); 1586 } else { 1587 accept(Token.ROW); 1588 } 1589 betweenEnd = new SQLIdentifierExpr("CURRENT ROW"); 1590 } else { 1591 betweenEnd = this.primary(); 1592 } 1593 over.setWindowingBetweenEnd(betweenEnd); 1594 1595 if (lexer.identifierEquals(FnvHash.Constants.PRECEDING)) { 1596 over.setWindowingBetweenEndPreceding(true); 1597 lexer.nextToken(); 1598 } else if (lexer.identifierEquals(FnvHash.Constants.FOLLOWING)) { 1599 over.setWindowingBetweenEndFollowing(true); 1600 lexer.nextToken(); 1601 } 1602 1603 } else { 1604 1605 if (lexer.identifierEquals(FnvHash.Constants.CURRENT)) { 1606 lexer.nextToken(); 1607 if (lexer.identifierEquals(FnvHash.Constants.ROW)) { 1608 lexer.nextToken(); 1609 } else { 1610 accept(Token.ROW); 1611 } 1612 over.setWindowing(new SQLIdentifierExpr("CURRENT ROW")); 1613 } else if (lexer.identifierEquals(FnvHash.Constants.UNBOUNDED)) { 1614 lexer.nextToken(); 1615 over.setWindowing(new SQLIdentifierExpr("UNBOUNDED")); 1616 1617 if (lexer.identifierEquals(FnvHash.Constants.PRECEDING)) { 1618 over.setWindowingPreceding(true); 1619 lexer.nextToken(); 1620 } else if (lexer.identifierEquals("FOLLOWING")) { 1621 over.setWindowingFollowing(true); 1622 lexer.nextToken(); 1623 } 1624 } else { 1625 SQLIntegerExpr rowsExpr = cast(SQLIntegerExpr) this.primary(); 1626 over.setWindowing(rowsExpr); 1627 1628 if (lexer.identifierEquals(FnvHash.Constants.PRECEDING)) { 1629 over.setWindowingPreceding(true); 1630 lexer.nextToken(); 1631 } else if (lexer.identifierEquals(FnvHash.Constants.FOLLOWING)) { 1632 over.setWindowingFollowing(true); 1633 lexer.nextToken(); 1634 } 1635 } 1636 } 1637 } 1638 1639 accept(Token.RPAREN); 1640 } 1641 1642 protected SQLAggregateExpr parseAggregateExprRest(SQLAggregateExpr aggregateExpr) { 1643 return aggregateExpr; 1644 } 1645 1646 public SQLOrderBy parseOrderBy() { 1647 if (lexer.token == Token.ORDER) { 1648 SQLOrderBy SorderBy = new SQLOrderBy(); 1649 1650 lexer.nextToken(); 1651 1652 if (lexer.identifierEquals(FnvHash.Constants.SIBLINGS)) { 1653 lexer.nextToken(); 1654 SorderBy.setSibings(true); 1655 } 1656 1657 accept(Token.BY); 1658 1659 orderBy(SorderBy.getItems(), SorderBy); 1660 1661 return SorderBy; 1662 } 1663 1664 return null; 1665 } 1666 1667 public void orderBy(List!(SQLSelectOrderByItem) items, SQLObject parent) { 1668 SQLSelectOrderByItem item = parseSelectOrderByItem(); 1669 item.setParent(parent); 1670 items.add(item); 1671 while (lexer.token == Token.COMMA) { 1672 lexer.nextToken(); 1673 item = parseSelectOrderByItem(); 1674 item.setParent(parent); 1675 items.add(item); 1676 } 1677 } 1678 1679 public SQLSelectOrderByItem parseSelectOrderByItem() { 1680 SQLSelectOrderByItem item = new SQLSelectOrderByItem(); 1681 1682 item.setExpr(this.expr()); 1683 1684 if (lexer.token == Token.ASC) { 1685 lexer.nextToken(); 1686 item.setType(SQLOrderingSpecification.ASC); 1687 } else if (lexer.token == Token.DESC) { 1688 lexer.nextToken(); 1689 item.setType(SQLOrderingSpecification.DESC); 1690 } 1691 1692 if (lexer.identifierEquals(FnvHash.Constants.NULLS)) { 1693 lexer.nextToken(); 1694 if (lexer.identifierEquals(FnvHash.Constants.FIRST)) { 1695 lexer.nextToken(); 1696 item.setNullsOrderType(SQLSelectOrderByItem.NullsOrderType.NullsFirst); 1697 } else if (lexer.identifierEquals(FnvHash.Constants.LAST)) { 1698 lexer.nextToken(); 1699 item.setNullsOrderType(SQLSelectOrderByItem.NullsOrderType.NullsLast); 1700 } else { 1701 throw new ParserException("TODO " ~ lexer.info()); 1702 } 1703 } 1704 1705 return item; 1706 } 1707 1708 public SQLUpdateSetItem parseUpdateSetItem() { 1709 SQLUpdateSetItem item = new SQLUpdateSetItem(); 1710 1711 if (lexer.token == (Token.LPAREN)) { 1712 lexer.nextToken(); 1713 SQLListExpr list = new SQLListExpr(); 1714 this.exprList(list.getItems(), list); 1715 accept(Token.RPAREN); 1716 item.setColumn(list); 1717 } else { 1718 string identName; 1719 long hash; 1720 1721 Token token = lexer.token(); 1722 if (token == Token.IDENTIFIER) { 1723 identName = lexer.stringVal(); 1724 hash = lexer.hash_lower(); 1725 } else if (token == Token.LITERAL_CHARS) { 1726 identName = '\'' ~ lexer.stringVal() ~ '\''; 1727 hash = 0; 1728 } else { 1729 identName = lexer.stringVal(); 1730 hash = 0; 1731 } 1732 lexer.nextTokenEq(); 1733 SQLExpr expr = new SQLIdentifierExpr(identName, hash); 1734 while (lexer.token() == Token.DOT) { 1735 lexer.nextToken(); 1736 string propertyName = lexer.stringVal(); 1737 lexer.nextTokenEq(); 1738 expr = new SQLPropertyExpr(expr, propertyName); 1739 } 1740 1741 item.setColumn(expr); 1742 } 1743 if (lexer.token == Token.COLONEQ) { 1744 lexer.nextTokenValue(); 1745 } else if (lexer.token == Token.EQ) { 1746 lexer.nextTokenValue(); 1747 } else { 1748 throw new ParserException("syntax error, expect EQ, actual " ~ lexer.token ~ " " 1749 ~ lexer.info()); 1750 } 1751 1752 item.setValue(this.expr()); 1753 return item; 1754 } 1755 1756 public SQLExpr bitAnd() { 1757 SQLExpr expr = shift(); 1758 return bitAndRest(expr); 1759 } 1760 1761 public SQLExpr bitAndRest(SQLExpr expr) { 1762 while (lexer.token == Token.AMP) { 1763 lexer.nextToken(); 1764 SQLExpr rightExp = shift(); 1765 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BitwiseAnd, rightExp, getDbType()); 1766 } 1767 return expr; 1768 } 1769 1770 public SQLExpr bitOr() { 1771 SQLExpr expr = bitAnd(); 1772 return bitOrRest(expr); 1773 } 1774 1775 public SQLExpr bitOrRest(SQLExpr expr) { 1776 while (lexer.token == Token.BAR) { 1777 lexer.nextToken(); 1778 SQLBinaryOperator op = SQLBinaryOperator.BitwiseOr; 1779 if (lexer.token == Token.BAR) { 1780 lexer.nextToken(); 1781 op = SQLBinaryOperator.Concat; 1782 } 1783 SQLExpr rightExp = bitAnd(); 1784 expr = new SQLBinaryOpExpr(expr, op, rightExp, getDbType()); 1785 expr = bitAndRest(expr); 1786 } 1787 return expr; 1788 } 1789 1790 public SQLExpr inRest(SQLExpr expr) { 1791 if (lexer.token == Token.IN) { 1792 lexer.nextTokenLParen(); 1793 1794 SQLInListExpr inListExpr = new SQLInListExpr(expr); 1795 List!(SQLExpr) targetList = inListExpr.getTargetList(); 1796 if (lexer.token == Token.LPAREN) { 1797 lexer.nextTokenValue(); 1798 1799 if (lexer.token == Token.WITH) { 1800 SQLSelect select = this.createSelectParser().select(); 1801 SQLInSubQueryExpr queryExpr = new SQLInSubQueryExpr(select); 1802 queryExpr.setExpr(expr); 1803 accept(Token.RPAREN); 1804 return queryExpr; 1805 } 1806 1807 for (;;) { 1808 SQLExpr item; 1809 if (lexer.token == Token.LITERAL_INT) { 1810 item = new SQLIntegerExpr(lexer.integerValue()); 1811 lexer.nextToken(); 1812 if (lexer.token != Token.COMMA && lexer.token != Token.RPAREN) { 1813 item = this.primaryRest(item); 1814 item = this.exprRest(item); 1815 } 1816 } else { 1817 item = this.expr(); 1818 } 1819 1820 item.setParent(inListExpr); 1821 targetList.add(item); 1822 if (lexer.token == Token.COMMA) { 1823 lexer.nextTokenValue(); 1824 continue; 1825 } 1826 break; 1827 } 1828 1829 accept(Token.RPAREN); 1830 } else { 1831 SQLExpr itemExpr = primary(); 1832 itemExpr.setParent(inListExpr); 1833 targetList.add(itemExpr); 1834 } 1835 1836 expr = inListExpr; 1837 1838 if (targetList.size() == 1) { 1839 SQLExpr targetExpr = targetList.get(0); 1840 if (cast(SQLQueryExpr)(targetExpr) !is null) { 1841 SQLInSubQueryExpr inSubQueryExpr = new SQLInSubQueryExpr(); 1842 inSubQueryExpr.setExpr(inListExpr.getExpr()); 1843 inSubQueryExpr.setSubQuery((cast(SQLQueryExpr) targetExpr).getSubQuery()); 1844 expr = inSubQueryExpr; 1845 } 1846 } 1847 } else if (lexer.token == Token.CONTAINS) { 1848 lexer.nextTokenLParen(); 1849 1850 SQLContainsExpr containsExpr = new SQLContainsExpr(expr); 1851 List!(SQLExpr) targetList = containsExpr.getTargetList(); 1852 if (lexer.token == Token.LPAREN) { 1853 lexer.nextTokenValue(); 1854 1855 if (lexer.token == Token.WITH) { 1856 SQLSelect select = this.createSelectParser().select(); 1857 SQLInSubQueryExpr queryExpr = new SQLInSubQueryExpr(select); 1858 queryExpr.setExpr(expr); 1859 accept(Token.RPAREN); 1860 return queryExpr; 1861 } 1862 1863 for (;;) { 1864 SQLExpr item; 1865 if (lexer.token == Token.LITERAL_INT) { 1866 item = new SQLIntegerExpr(lexer.integerValue()); 1867 lexer.nextToken(); 1868 if (lexer.token != Token.COMMA && lexer.token != Token.RPAREN) { 1869 item = this.primaryRest(item); 1870 item = this.exprRest(item); 1871 } 1872 } else { 1873 item = this.expr(); 1874 } 1875 1876 item.setParent(containsExpr); 1877 targetList.add(item); 1878 if (lexer.token == Token.COMMA) { 1879 lexer.nextTokenValue(); 1880 continue; 1881 } 1882 break; 1883 } 1884 1885 accept(Token.RPAREN); 1886 } else { 1887 SQLExpr itemExpr = primary(); 1888 itemExpr.setParent(containsExpr); 1889 targetList.add(itemExpr); 1890 } 1891 1892 expr = containsExpr; 1893 } 1894 1895 return expr; 1896 } 1897 1898 public SQLExpr additive() { 1899 SQLExpr expr = multiplicative(); 1900 1901 if (lexer.token == Token.PLUS 1902 || lexer.token == Token.BARBAR 1903 || lexer.token == Token.CONCAT 1904 || lexer.token == Token.SUB) { 1905 expr = additiveRest(expr); 1906 } 1907 1908 return expr; 1909 } 1910 1911 public SQLExpr additiveRest(SQLExpr expr) { 1912 Token token = lexer.token; 1913 if (token == Token.PLUS) { 1914 lexer.nextToken(); 1915 SQLExpr rightExp = multiplicative(); 1916 1917 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Add, rightExp, dbType); 1918 expr = additiveRest(expr); 1919 } else if ((token == Token.BARBAR || token == Token.CONCAT) 1920 && (isEnabled(SQLParserFeature.PipesAsConcat) || !(DBType.MYSQL.name == (dbType)))) { 1921 lexer.nextToken(); 1922 SQLExpr rightExp = multiplicative(); 1923 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Concat, rightExp, dbType); 1924 expr = additiveRest(expr); 1925 } else if (token == Token.SUB) { 1926 lexer.nextToken(); 1927 SQLExpr rightExp = multiplicative(); 1928 1929 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Subtract, rightExp, dbType); 1930 expr = additiveRest(expr); 1931 } 1932 1933 return expr; 1934 } 1935 1936 public SQLExpr shift() { 1937 SQLExpr expr = additive(); 1938 return shiftRest(expr); 1939 } 1940 1941 public SQLExpr shiftRest(SQLExpr expr) { 1942 if (lexer.token == Token.LTLT) { 1943 lexer.nextToken(); 1944 SQLExpr rightExp = additive(); 1945 1946 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LeftShift, rightExp, dbType); 1947 expr = shiftRest(expr); 1948 } else if (lexer.token == Token.GTGT) { 1949 lexer.nextToken(); 1950 SQLExpr rightExp = additive(); 1951 1952 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.RightShift, rightExp, dbType); 1953 expr = shiftRest(expr); 1954 } 1955 1956 return expr; 1957 } 1958 1959 public SQLExpr and() { 1960 SQLExpr expr = relational(); 1961 if (lexer.token == Token.AND || lexer.token == Token.AMPAMP) { 1962 expr = andRest(expr); 1963 } 1964 return expr; 1965 } 1966 1967 public SQLExpr andRest(SQLExpr expr) { 1968 for (;;) { 1969 Token token = lexer.token; 1970 if (token == Token.AND) { 1971 if (lexer.isKeepComments() && lexer.hasComment()) { 1972 expr.addAfterComment(lexer.readAndResetComments()); 1973 } 1974 1975 lexer.nextToken(); 1976 1977 SQLExpr rightExp = relational(); 1978 1979 if (lexer.token == Token.AND 1980 && lexer.isEnabled(SQLParserFeature.EnableSQLBinaryOpExprGroup)) { 1981 1982 SQLBinaryOpExprGroup group = new SQLBinaryOpExprGroup(SQLBinaryOperator.BooleanAnd, dbType); 1983 group.add(expr); 1984 group.add(rightExp); 1985 1986 if (lexer.isKeepComments() && lexer.hasComment()) { 1987 rightExp.addAfterComment(lexer.readAndResetComments()); 1988 } 1989 1990 for (;;) { 1991 lexer.nextToken(); 1992 SQLExpr more = relational(); 1993 group.add(more); 1994 1995 if (lexer.token == Token.AND) { 1996 if (lexer.isKeepComments() && lexer.hasComment()) { 1997 more.addAfterComment(lexer.readAndResetComments()); 1998 } 1999 2000 continue; 2001 } 2002 break; 2003 } 2004 2005 expr = group; 2006 } else { 2007 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanAnd, rightExp, dbType); 2008 } 2009 } else if (token == Token.AMPAMP) { 2010 if (lexer.isKeepComments() && lexer.hasComment()) { 2011 expr.addAfterComment(lexer.readAndResetComments()); 2012 } 2013 2014 lexer.nextToken(); 2015 2016 SQLExpr rightExp = relational(); 2017 2018 SQLBinaryOperator operator = DBType.POSTGRESQL.name == (dbType) 2019 ? SQLBinaryOperator.PG_And 2020 : SQLBinaryOperator.BooleanAnd; 2021 2022 expr = new SQLBinaryOpExpr(expr, operator, rightExp, dbType); 2023 } else { 2024 break; 2025 } 2026 } 2027 2028 return expr; 2029 } 2030 2031 2032 public SQLExpr xor() { 2033 SQLExpr expr = and(); 2034 if (lexer.token == Token.XOR) { 2035 expr = xorRest(expr); 2036 } 2037 return expr; 2038 } 2039 2040 public SQLExpr xorRest(SQLExpr expr) { 2041 for (;;) { 2042 if (lexer.token == Token.XOR) { 2043 lexer.nextToken(); 2044 SQLExpr rightExp = and(); 2045 2046 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanXor, rightExp, dbType); 2047 } else { 2048 break; 2049 } 2050 } 2051 2052 return expr; 2053 } 2054 2055 public SQLExpr or() { 2056 SQLExpr expr = xor(); 2057 if (lexer.token == Token.OR || lexer.token == Token.BARBAR) { 2058 expr = orRest(expr); 2059 } 2060 return expr; 2061 } 2062 2063 public SQLExpr orRest(SQLExpr expr) { 2064 for (;;) { 2065 if (lexer.token == Token.OR) { 2066 lexer.nextToken(); 2067 SQLExpr rightExp = xor(); 2068 2069 if (lexer.token == Token.OR 2070 && lexer.isEnabled(SQLParserFeature.EnableSQLBinaryOpExprGroup)) { 2071 2072 SQLBinaryOpExprGroup group = new SQLBinaryOpExprGroup(SQLBinaryOperator.BooleanOr, dbType); 2073 group.add(expr); 2074 group.add(rightExp); 2075 2076 if (lexer.isKeepComments() && lexer.hasComment()) { 2077 rightExp.addAfterComment(lexer.readAndResetComments()); 2078 } 2079 2080 for (;;) { 2081 lexer.nextToken(); 2082 SQLExpr more = xor(); 2083 group.add(more); 2084 if (lexer.token == Token.OR) { 2085 if (lexer.isKeepComments() && lexer.hasComment()) { 2086 more.addAfterComment(lexer.readAndResetComments()); 2087 } 2088 2089 continue; 2090 } 2091 break; 2092 } 2093 2094 expr = group; 2095 } else { 2096 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanOr, rightExp, dbType); 2097 } 2098 } else if (lexer.token == Token.BARBAR) { 2099 lexer.nextToken(); 2100 SQLExpr rightExp = xor(); 2101 2102 SQLBinaryOperator op = DBType.MYSQL.name == (dbType) && !isEnabled(SQLParserFeature.PipesAsConcat) 2103 ? SQLBinaryOperator.BooleanOr 2104 : SQLBinaryOperator.Concat; 2105 2106 expr = new SQLBinaryOpExpr(expr, op, rightExp, dbType); 2107 } else { 2108 break; 2109 } 2110 } 2111 2112 return expr; 2113 } 2114 2115 public SQLExpr relational() { 2116 SQLExpr expr = bitOr(); 2117 2118 return relationalRest(expr); 2119 } 2120 2121 public SQLExpr relationalRest(SQLExpr expr) { 2122 SQLExpr rightExp; 2123 2124 Token token = lexer.token; 2125 2126 switch (token) { 2127 case Token.EQ:{ 2128 lexer.nextToken(); 2129 try { 2130 rightExp = bitOr(); 2131 } catch (ParserException e) { 2132 throw new ParserException("EOF, " ~ expr.stringof ~ "=", e); 2133 } 2134 2135 if (lexer.token == Token.COLONEQ) { 2136 lexer.nextToken(); 2137 SQLExpr colonExpr = this.expr(); 2138 rightExp = new SQLBinaryOpExpr(rightExp, SQLBinaryOperator.Assignment, colonExpr, dbType); 2139 } 2140 2141 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Equality, rightExp, dbType); 2142 } 2143 break; 2144 case Token.IS: { 2145 lexer.nextTokenNotOrNull(); 2146 2147 SQLBinaryOperator op; 2148 if (lexer.token == Token.NOT) { 2149 op = SQLBinaryOperator.IsNot; 2150 lexer.nextTokenNotOrNull(); 2151 } else { 2152 op = SQLBinaryOperator.Is; 2153 } 2154 rightExp = primary(); 2155 expr = new SQLBinaryOpExpr(expr, op, rightExp, dbType); 2156 } 2157 break; 2158 case Token.EQGT: { 2159 lexer.nextToken(); 2160 rightExp = this.expr(); 2161 string argumentName = (cast(SQLIdentifierExpr) expr).getName(); 2162 // expr = new OracleArgumentExpr(argumentName, rightExp); 2163 implementationMissing(false); 2164 } 2165 break; 2166 case Token.BANGEQ: 2167 case Token.CARETEQ: { 2168 lexer.nextToken(); 2169 rightExp = bitOr(); 2170 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotEqual, rightExp, dbType); 2171 } 2172 break; 2173 case Token.COLONEQ:{ 2174 lexer.nextToken(); 2175 rightExp = this.expr(); 2176 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Assignment, rightExp, dbType); 2177 } 2178 break; 2179 case Token.LT:{ 2180 SQLBinaryOperator op = SQLBinaryOperator.LessThan; 2181 2182 lexer.nextToken(); 2183 if (lexer.token == Token.EQ) { 2184 lexer.nextToken(); 2185 op = SQLBinaryOperator.LessThanOrEqual; 2186 } 2187 2188 rightExp = bitOr(); 2189 expr = new SQLBinaryOpExpr(expr, op, rightExp, getDbType()); 2190 } 2191 break; 2192 case Token.LTEQ: { 2193 lexer.nextToken(); 2194 rightExp = bitOr(); 2195 2196 // rightExp = relationalRest(rightExp); 2197 2198 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrEqual, rightExp, getDbType()); 2199 } 2200 break; 2201 case Token.LTEQGT: { 2202 lexer.nextToken(); 2203 rightExp = bitOr(); 2204 2205 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrEqualOrGreaterThan, rightExp, getDbType()); 2206 } 2207 break; 2208 case Token.GT: { 2209 SQLBinaryOperator op = SQLBinaryOperator.GreaterThan; 2210 2211 lexer.nextToken(); 2212 2213 if (lexer.token == Token.EQ) { 2214 lexer.nextToken(); 2215 op = SQLBinaryOperator.GreaterThanOrEqual; 2216 } 2217 2218 rightExp = bitOr(); 2219 2220 expr = new SQLBinaryOpExpr(expr, op, rightExp, getDbType()); 2221 } 2222 break; 2223 case Token.GTEQ:{ 2224 lexer.nextToken(); 2225 rightExp = bitOr(); 2226 2227 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.GreaterThanOrEqual, rightExp, getDbType()); 2228 } 2229 break; 2230 case Token.BANGLT:{ 2231 lexer.nextToken(); 2232 rightExp = bitOr(); 2233 2234 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotLessThan, rightExp, getDbType()); 2235 } 2236 break; 2237 case Token.BANGGT: 2238 lexer.nextToken(); 2239 rightExp = bitOr(); 2240 2241 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotGreaterThan, rightExp, getDbType()); 2242 break; 2243 case Token.LTGT: 2244 lexer.nextToken(); 2245 rightExp = bitOr(); 2246 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrGreater, rightExp, getDbType()); 2247 break; 2248 case Token.LIKE: 2249 lexer.nextTokenValue(); 2250 rightExp = bitOr(); 2251 2252 if (typeid(rightExp) == typeid(SQLIdentifierExpr)) { 2253 string name = (cast(SQLIdentifierExpr) rightExp).getName(); 2254 int length = cast(int)(name.length); 2255 if(length > 1 && charAt(name, 0) == charAt(name, length -1 )) { 2256 rightExp = new SQLCharExpr(name.substring(1, length - 1)); 2257 } 2258 } 2259 2260 // rightExp = relationalRest(rightExp); 2261 2262 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Like, rightExp, getDbType()); 2263 2264 if (lexer.token == Token.ESCAPE) { 2265 lexer.nextToken(); 2266 rightExp = primary(); 2267 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Escape, rightExp, getDbType()); 2268 } 2269 break; 2270 case Token.ILIKE: 2271 lexer.nextToken(); 2272 rightExp = bitOr(); 2273 2274 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.ILike, rightExp, getDbType()); 2275 break; 2276 case Token.MONKEYS_AT_AT: 2277 lexer.nextToken(); 2278 rightExp = bitOr(); 2279 2280 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.AT_AT, rightExp, getDbType()); 2281 break; 2282 case Token.MONKEYS_AT_GT: 2283 lexer.nextToken(); 2284 rightExp = bitOr(); 2285 2286 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Array_Contains, rightExp, getDbType()); 2287 break; 2288 case Token.LT_MONKEYS_AT: 2289 lexer.nextToken(); 2290 rightExp = bitOr(); 2291 2292 rightExp = relationalRest(rightExp); 2293 2294 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Array_ContainedBy, rightExp, getDbType()); 2295 break; 2296 case Token.NOT: 2297 lexer.nextToken(); 2298 expr = notRationalRest(expr); 2299 break; 2300 case Token.BETWEEN: 2301 lexer.nextToken(); 2302 SQLExpr beginExpr = relational(); 2303 accept(Token.AND); 2304 SQLExpr endExpr = relational(); 2305 expr = new SQLBetweenExpr(expr, beginExpr, endExpr); 2306 break; 2307 case Token.IN: 2308 case Token.CONTAINS: 2309 expr = inRest(expr); 2310 break; 2311 case Token.EQEQ: 2312 /* if (DBType.ODPS.name == (dbType)) { 2313 lexer.nextToken(); 2314 try { 2315 rightExp = bitOr(); 2316 } catch (ParserException e) { 2317 throw new ParserException("EOF, " ~ expr.stringof ~ "=", e); 2318 } 2319 2320 if (lexer.token == Token.COLONEQ) { 2321 lexer.nextToken(); 2322 SQLExpr colonExpr = this.expr(); 2323 rightExp = new SQLBinaryOpExpr(rightExp, SQLBinaryOperator.Assignment, colonExpr, dbType); 2324 } 2325 2326 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Equality, rightExp, dbType); 2327 } else */ { 2328 return expr; 2329 } 2330 case Token.TILDE: 2331 if (DBType.POSTGRESQL == (lexer.dbType)) { 2332 lexer.nextToken(); 2333 2334 rightExp = relational(); 2335 2336 rightExp = relationalRest(rightExp); 2337 2338 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.POSIX_Regular_Match, rightExp, getDbType()); 2339 } else { 2340 return expr; 2341 } 2342 break; 2343 case Token.TILDE_STAR: 2344 if (DBType.POSTGRESQL.name == (lexer.dbType)) { 2345 lexer.nextToken(); 2346 rightExp = relational(); 2347 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.POSIX_Regular_Match_Insensitive, rightExp, getDbType()); 2348 } else { 2349 return expr; 2350 } 2351 break; 2352 case Token.BANG_TILDE: 2353 if (DBType.POSTGRESQL.name == (lexer.dbType)) { 2354 lexer.nextToken(); 2355 rightExp = relational(); 2356 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.POSIX_Regular_Not_Match, rightExp, getDbType()); 2357 } else { 2358 return expr; 2359 } 2360 break; 2361 case Token.BANG_TILDE_STAR: 2362 if (DBType.POSTGRESQL.name == (lexer.dbType)) { 2363 lexer.nextToken(); 2364 rightExp = relational(); 2365 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.POSIX_Regular_Not_Match_POSIX_Regular_Match_Insensitive, rightExp, getDbType()); 2366 } else { 2367 return expr; 2368 } 2369 break; 2370 case Token.TILDE_EQ: 2371 if (DBType.POSTGRESQL.name == (lexer.dbType)) { 2372 lexer.nextToken(); 2373 rightExp = relational(); 2374 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.SAME_AS, rightExp, getDbType()); 2375 } else { 2376 return expr; 2377 } 2378 break; 2379 case Token.RLIKE: 2380 lexer.nextToken(); 2381 rightExp = relational(); 2382 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.RLike, rightExp, getDbType()); 2383 break; 2384 case Token.IDENTIFIER: 2385 long hash = lexer.hash_lower; 2386 if (hash == FnvHash.Constants.SOUNDS) { 2387 lexer.nextToken(); 2388 accept(Token.LIKE); 2389 2390 rightExp = relational(); 2391 2392 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.SoudsLike, rightExp, getDbType()); 2393 } else if (hash == FnvHash.Constants.REGEXP) { 2394 lexer.nextToken(); 2395 rightExp = relational(); 2396 2397 return new SQLBinaryOpExpr(expr, SQLBinaryOperator.RegExp, rightExp, DBType.MYSQL.name); 2398 2399 } else if (hash == FnvHash.Constants.SIMILAR && DBType.POSTGRESQL.name == (lexer.dbType)) { 2400 lexer.nextToken(); 2401 accept(Token.TO); 2402 2403 rightExp = relational(); 2404 2405 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.SIMILAR_TO, rightExp, getDbType()); 2406 } else { 2407 return expr; 2408 } 2409 break; 2410 default: 2411 break; 2412 } 2413 2414 switch (lexer.token) { 2415 case Token.BETWEEN: 2416 case Token.IS: 2417 case Token.EQ: 2418 case Token.IN: 2419 case Token.CONTAINS: 2420 case Token.BANG_TILDE_STAR: 2421 case Token.TILDE_EQ: 2422 case Token.LT: 2423 case Token.LTEQ: 2424 case Token.LTEQGT: 2425 case Token.GT: 2426 case Token.GTEQ: 2427 case Token.LTGT: 2428 case Token.BANGEQ: 2429 case Token.LIKE: 2430 case Token.NOT: 2431 expr = relationalRest(expr); 2432 break; 2433 default: 2434 break; 2435 } 2436 2437 return expr; 2438 } 2439 2440 public SQLExpr notRationalRest(SQLExpr expr) { 2441 SQLExpr rightExp; 2442 switch (lexer.token) { 2443 case Token.LIKE: 2444 lexer.nextTokenValue(); 2445 rightExp = bitOr(); 2446 2447 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotLike, rightExp, getDbType()); 2448 2449 if (lexer.token == Token.ESCAPE) { 2450 lexer.nextToken(); 2451 rightExp = bitOr(); 2452 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Escape, rightExp, getDbType()); 2453 } 2454 break; 2455 case Token.IN: 2456 lexer.nextToken(); 2457 2458 SQLInListExpr inListExpr = new SQLInListExpr(expr, true); 2459 if (lexer.token == Token.LPAREN) { 2460 lexer.nextToken(); 2461 2462 exprList(inListExpr.getTargetList(), inListExpr); 2463 expr = inListExpr; 2464 2465 accept(Token.RPAREN); 2466 } else { 2467 SQLExpr valueExpr = this.primary(); 2468 valueExpr.setParent(inListExpr); 2469 inListExpr.getTargetList().add(valueExpr); 2470 expr = inListExpr; 2471 } 2472 2473 if (inListExpr.getTargetList().size() == 1) { 2474 SQLExpr targetExpr = inListExpr.getTargetList().get(0); 2475 if (cast(SQLQueryExpr)(targetExpr) !is null) { 2476 SQLInSubQueryExpr inSubQueryExpr = new SQLInSubQueryExpr(); 2477 inSubQueryExpr.setNot(true); 2478 inSubQueryExpr.setExpr(inListExpr.getExpr()); 2479 inSubQueryExpr.setSubQuery((cast(SQLQueryExpr) targetExpr).getSubQuery()); 2480 expr = inSubQueryExpr; 2481 } 2482 } 2483 2484 break; 2485 case Token.CONTAINS: 2486 lexer.nextToken(); 2487 2488 SQLContainsExpr containsExpr = new SQLContainsExpr(expr, true); 2489 if (lexer.token == Token.LPAREN) { 2490 lexer.nextToken(); 2491 2492 exprList(containsExpr.getTargetList(), containsExpr); 2493 expr = containsExpr; 2494 2495 accept(Token.RPAREN); 2496 } else { 2497 SQLExpr valueExpr = this.primary(); 2498 valueExpr.setParent(containsExpr); 2499 containsExpr.getTargetList().add(valueExpr); 2500 expr = containsExpr; 2501 } 2502 2503 if (containsExpr.getTargetList().size() == 1) { 2504 SQLExpr targetExpr = containsExpr.getTargetList().get(0); 2505 if (cast(SQLQueryExpr)(targetExpr) !is null) { 2506 SQLInSubQueryExpr inSubQueryExpr = new SQLInSubQueryExpr(); 2507 inSubQueryExpr.setNot(true); 2508 inSubQueryExpr.setExpr(containsExpr.getExpr()); 2509 inSubQueryExpr.setSubQuery((cast(SQLQueryExpr) targetExpr).getSubQuery()); 2510 expr = inSubQueryExpr; 2511 } 2512 } 2513 2514 break; 2515 case Token.BETWEEN: 2516 lexer.nextToken(); 2517 SQLExpr beginExpr = relational(); 2518 accept(Token.AND); 2519 SQLExpr endExpr = relational(); 2520 2521 expr = new SQLBetweenExpr(expr, true, beginExpr, endExpr); 2522 break; 2523 case Token.ILIKE: 2524 lexer.nextToken(); 2525 rightExp = bitOr(); 2526 2527 return new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotILike, rightExp, getDbType()); 2528 case Token.LPAREN: 2529 expr = this.primary(); 2530 break; 2531 case Token.RLIKE: 2532 lexer.nextToken(); 2533 rightExp = bitOr(); 2534 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotRLike, rightExp, getDbType()); 2535 break; 2536 case Token.IDENTIFIER: 2537 long hash = lexer.hash_lower; 2538 if (hash == FnvHash.Constants.REGEXP) { 2539 lexer.nextToken(); 2540 rightExp = bitOr(); 2541 expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotRegExp, rightExp, getDbType()); 2542 } 2543 break; 2544 default: 2545 throw new ParserException("TODO " ~ lexer.info()); 2546 } 2547 2548 return expr; 2549 } 2550 2551 public SQLDataType parseDataType() { 2552 return parseDataType(true); 2553 } 2554 2555 public SQLDataType parseDataType(bool restrict) { 2556 Token token = lexer.token; 2557 if (token == Token.DEFAULT || token == Token.NOT || token == Token.NULL) { 2558 return null; 2559 } 2560 2561 SQLName typeExpr = name(); 2562 string typeName = (cast(Object)(typeExpr)).toString(); 2563 2564 version(HUNT_SQL_PARSER_DEBUG) warningf("typename: %s", typeName); 2565 2566 if ("long".equalsIgnoreCase(typeName) // 2567 && lexer.identifierEquals("byte") // 2568 && DBType.MYSQL.name == (getDbType()) // 2569 ) { 2570 typeName ~= (' ' ~ lexer.stringVal()); 2571 lexer.nextToken(); 2572 } else if ("double".equalsIgnoreCase(typeName) 2573 && DBType.POSTGRESQL.name == (getDbType()) // 2574 ) { 2575 typeName ~= (' ' ~ lexer.stringVal()); 2576 lexer.nextToken(); 2577 } 2578 2579 if (isCharType(typeName)) { 2580 SQLCharacterDataType charType = new SQLCharacterDataType(typeName); 2581 2582 if (lexer.token == Token.LPAREN) { 2583 lexer.nextToken(); 2584 SQLExpr arg = this.expr(); 2585 arg.setParent(charType); 2586 charType.addArgument(arg); 2587 accept(Token.RPAREN); 2588 } 2589 2590 charType = cast(SQLCharacterDataType) parseCharTypeRest(charType); 2591 2592 if (lexer.token == Token.HINT) { 2593 List!(SQLCommentHint) hints = this.parseHints(); 2594 charType.setHints(hints); 2595 } 2596 2597 return charType; 2598 } 2599 2600 if ("character".equalsIgnoreCase(typeName) && "varying".equalsIgnoreCase(lexer.stringVal())) { 2601 typeName ~= ' ' ~ lexer.stringVal(); 2602 lexer.nextToken(); 2603 } 2604 2605 SQLDataTypeImpl dataType = new SQLDataTypeImpl(typeName); 2606 dataType.setDbType(dbType); 2607 2608 version(HUNT_SQL_PARSER_DEBUG) infof("token: %s, value: %s", lexer.token, cast(string)lexer.token); 2609 2610 // FIXME: Needing refactor or cleanup -@zhangxueping at 2020-08-05T18:03:58+08:00 2611 // 2612 // if (lexer.token == Token.LPAREN) { 2613 // lexer.nextToken(); 2614 // SQLExpr arg = this.expr(); 2615 // arg.setParent(dataType); 2616 // dataType.addArgument(arg); 2617 // accept(Token.RPAREN); 2618 // } 2619 2620 return parseDataTypeRest(dataType); 2621 } 2622 2623 protected SQLDataType parseDataTypeRest(SQLDataType dataType) { 2624 if (lexer.token == Token.LPAREN) { 2625 lexer.nextToken(); 2626 exprList(dataType.getArguments(), dataType); 2627 accept(Token.RPAREN); 2628 } 2629 2630 if (lexer.identifierEquals(FnvHash.Constants.PRECISION) 2631 && dataType.nameHashCode64() == FnvHash.Constants.DOUBLE) { 2632 lexer.nextToken(); 2633 dataType.setName("DOUBLE PRECISION"); 2634 } 2635 2636 if (FnvHash.Constants.TIMESTAMP == dataType.nameHashCode64()) { 2637 if (lexer.identifierEquals(FnvHash.Constants.WITHOUT)) { 2638 lexer.nextToken(); 2639 acceptIdentifier("TIME"); 2640 acceptIdentifier("ZONE"); 2641 dataType.setWithTimeZone(Boolean.FALSE); 2642 } else if (lexer.token == Token.WITH) { 2643 lexer.nextToken(); 2644 acceptIdentifier("TIME"); 2645 acceptIdentifier("ZONE"); 2646 dataType.setWithTimeZone(Boolean.TRUE); 2647 } 2648 } 2649 2650 return dataType; 2651 } 2652 2653 protected bool isCharType(string dataTypeName) { 2654 long hash = FnvHash.hashCode64(dataTypeName); 2655 return isCharType(hash); 2656 } 2657 2658 2659 protected bool isCharType(long hash) { 2660 return hash == FnvHash.Constants.CHAR 2661 || hash == FnvHash.Constants.VARCHAR 2662 || hash == FnvHash.Constants.NCHAR 2663 || hash == FnvHash.Constants.NVARCHAR 2664 || hash == FnvHash.Constants.TINYTEXT 2665 || hash == FnvHash.Constants.TEXT 2666 || hash == FnvHash.Constants.MEDIUMTEXT 2667 || hash == FnvHash.Constants.LONGTEXT 2668 ; 2669 } 2670 2671 protected SQLDataType parseCharTypeRest(SQLCharacterDataType charType) { 2672 if (lexer.token == Token.BINARY) { 2673 charType.setHasBinary(true); 2674 lexer.nextToken(); 2675 } 2676 2677 if (lexer.identifierEquals(FnvHash.Constants.CHARACTER)) { 2678 lexer.nextToken(); 2679 2680 accept(Token.SET); 2681 2682 if (lexer.token != Token.IDENTIFIER 2683 && lexer.token != Token.LITERAL_CHARS 2684 && lexer.token != Token.BINARY) { 2685 throw new ParserException(lexer.info()); 2686 } 2687 charType.setCharSetName(lexer.stringVal()); 2688 lexer.nextToken(); 2689 } else if (lexer.identifierEquals(FnvHash.Constants.CHARSET)) { 2690 lexer.nextToken(); 2691 2692 if (lexer.token != Token.IDENTIFIER 2693 && lexer.token != Token.LITERAL_CHARS 2694 && lexer.token != Token.BINARY) { 2695 throw new ParserException(lexer.info()); 2696 } 2697 charType.setCharSetName(lexer.stringVal()); 2698 lexer.nextToken(); 2699 } 2700 2701 if (lexer.token == Token.BINARY) { 2702 charType.setHasBinary(true); 2703 lexer.nextToken(); 2704 } 2705 2706 if (lexer.identifierEquals(FnvHash.Constants.COLLATE)) { 2707 lexer.nextToken(); 2708 2709 if (lexer.token == Token.LITERAL_ALIAS) { 2710 charType.setCollate(lexer.stringVal()); 2711 } else if (lexer.token == Token.IDENTIFIER) { 2712 charType.setCollate(lexer.stringVal()); 2713 } else { 2714 throw new ParserException(); 2715 } 2716 2717 lexer.nextToken(); 2718 } 2719 2720 return charType; 2721 } 2722 2723 override public void accept(Token token) { 2724 if (lexer.token == token) { 2725 lexer.nextToken(); 2726 } else { 2727 throw new ParserException("syntax error, expect:{" ~ token ~ "}, actual:{" ~ lexer.token ~ "}, " 2728 ~ lexer.info()); 2729 } 2730 } 2731 2732 public SQLColumnDefinition parseColumn() { 2733 SQLColumnDefinition column = createColumnDefinition(); 2734 column.setName(name()); 2735 2736 Token token = lexer.token; 2737 if (token != Token.SET // 2738 && token != Token.DROP 2739 && token != Token.PRIMARY 2740 && token != Token.RPAREN) { 2741 column.setDataType(parseDataType()); 2742 } 2743 return parseColumnRest(column); 2744 } 2745 2746 public SQLColumnDefinition createColumnDefinition() { 2747 SQLColumnDefinition column = new SQLColumnDefinition(); 2748 column.setDbType(dbType); 2749 return column; 2750 } 2751 2752 public SQLColumnDefinition parseColumnRest(SQLColumnDefinition column) { 2753 if (lexer.token == Token.DEFAULT) { 2754 lexer.nextToken(); 2755 column.setDefaultExpr(bitOr()); 2756 return parseColumnRest(column); 2757 } 2758 2759 if (lexer.token == Token.NOT) { 2760 lexer.nextToken(); 2761 accept(Token.NULL); 2762 SQLNotNullConstraint notNull = new SQLNotNullConstraint(); 2763 if (lexer.token == Token.HINT) { 2764 List!(SQLCommentHint) hints = this.parseHints(); 2765 notNull.setHints(hints); 2766 } 2767 column.addConstraint(notNull); 2768 return parseColumnRest(column); 2769 } 2770 2771 if (lexer.token == Token.NULL) { 2772 lexer.nextToken(); 2773 column.getConstraints().add(new SQLNullConstraint()); 2774 return parseColumnRest(column); 2775 } 2776 2777 if (lexer.token == Token.PRIMARY) { 2778 lexer.nextToken(); 2779 accept(Token.KEY); 2780 column.addConstraint(new SQLColumnPrimaryKey()); 2781 return parseColumnRest(column); 2782 } 2783 2784 if (lexer.token == Token.UNIQUE) { 2785 lexer.nextToken(); 2786 if (lexer.token == Token.KEY) { 2787 lexer.nextToken(); 2788 } 2789 column.addConstraint(new SQLColumnUniqueKey()); 2790 return parseColumnRest(column); 2791 } 2792 2793 if (lexer.token == Token.KEY) { 2794 lexer.nextToken(); 2795 column.addConstraint(new SQLColumnUniqueKey()); 2796 return parseColumnRest(column); 2797 } 2798 2799 if (lexer.token == Token.REFERENCES) { 2800 SQLColumnReference _ref = parseReference(); 2801 column.addConstraint(_ref); 2802 return parseColumnRest(column); 2803 } 2804 2805 if (lexer.token == Token.CONSTRAINT) { 2806 lexer.nextToken(); 2807 2808 SQLName name = this.name(); 2809 2810 if (lexer.token == Token.PRIMARY) { 2811 lexer.nextToken(); 2812 accept(Token.KEY); 2813 SQLColumnPrimaryKey pk = new SQLColumnPrimaryKey(); 2814 pk.setName(name); 2815 column.addConstraint(pk); 2816 return parseColumnRest(column); 2817 } 2818 2819 if (lexer.token == Token.UNIQUE) { 2820 lexer.nextToken(); 2821 SQLColumnUniqueKey uk = new SQLColumnUniqueKey(); 2822 uk.setName(name); 2823 2824 column.addConstraint(uk); 2825 return parseColumnRest(column); 2826 } 2827 2828 if (lexer.token == Token.REFERENCES) { 2829 SQLColumnReference _ref = parseReference(); 2830 _ref.setName(name); 2831 column.addConstraint(_ref); 2832 return parseColumnRest(column); 2833 } 2834 2835 if (lexer.token == Token.NOT) { 2836 lexer.nextToken(); 2837 accept(Token.NULL); 2838 SQLNotNullConstraint notNull = new SQLNotNullConstraint(); 2839 notNull.setName(name); 2840 column.addConstraint(notNull); 2841 return parseColumnRest(column); 2842 } 2843 2844 if (lexer.token == Token.CHECK) { 2845 SQLColumnCheck check = parseColumnCheck(); 2846 check.setName(name); 2847 check.setParent(column); 2848 column.addConstraint(check); 2849 return parseColumnRest(column); 2850 } 2851 2852 if (lexer.token == Token.DEFAULT) { 2853 lexer.nextToken(); 2854 SQLExpr expr = this.expr(); 2855 column.setDefaultExpr(expr); 2856 return parseColumnRest(column); 2857 } 2858 2859 throw new ParserException("TODO : " ~ lexer.info()); 2860 } 2861 2862 if (lexer.token == Token.CHECK) { 2863 SQLColumnCheck check = parseColumnCheck(); 2864 column.addConstraint(check); 2865 return parseColumnRest(column); 2866 } 2867 2868 if (lexer.token == Token.COMMENT) { 2869 lexer.nextToken(); 2870 2871 if (lexer.token == Token.LITERAL_ALIAS) { 2872 string _alias = lexer.stringVal(); 2873 if (_alias.length > 2 && charAt(_alias, 0) == '"' && charAt(_alias, _alias.length - 1) == '"') { 2874 _alias = _alias.substring(1, cast(int)(_alias.length - 1)); 2875 } 2876 column.setComment(_alias); 2877 lexer.nextToken(); 2878 } else { 2879 column.setComment(primary()); 2880 } 2881 return parseColumnRest(column); 2882 } 2883 2884 if (lexer.identifierEquals(FnvHash.Constants.AUTO_INCREMENT)) { 2885 lexer.nextToken(); 2886 column.setAutoIncrement(true); 2887 return parseColumnRest(column); 2888 } 2889 2890 return column; 2891 } 2892 2893 private SQLColumnReference parseReference() { 2894 SQLColumnReference fk = new SQLColumnReference(); 2895 2896 lexer.nextToken(); 2897 fk.setTable(this.name()); 2898 accept(Token.LPAREN); 2899 this.names(fk.getColumns(), fk); 2900 accept(Token.RPAREN); 2901 2902 if (lexer.identifierEquals(FnvHash.Constants.MATCH)) { 2903 lexer.nextToken(); 2904 if (lexer.identifierEquals("FULL") || lexer.token() == Token.FULL) { 2905 fk.setReferenceMatch(SQLForeignKeyImpl.Match.FULL); 2906 lexer.nextToken(); 2907 } else if (lexer.identifierEquals(FnvHash.Constants.PARTIAL)) { 2908 fk.setReferenceMatch(SQLForeignKeyImpl.Match.PARTIAL); 2909 lexer.nextToken(); 2910 } else if (lexer.identifierEquals(FnvHash.Constants.SIMPLE)) { 2911 fk.setReferenceMatch(SQLForeignKeyImpl.Match.SIMPLE); 2912 lexer.nextToken(); 2913 } else { 2914 throw new ParserException("TODO : " ~ lexer.info()); 2915 } 2916 } 2917 2918 while (lexer.token() == Token.ON) { 2919 lexer.nextToken(); 2920 2921 if (lexer.token() == Token.DELETE) { 2922 lexer.nextToken(); 2923 2924 SQLForeignKeyImpl.Option option = parseReferenceOption(); 2925 fk.setOnDelete(option); 2926 } else if (lexer.token() == Token.UPDATE) { 2927 lexer.nextToken(); 2928 2929 SQLForeignKeyImpl.Option option = parseReferenceOption(); 2930 fk.setOnUpdate(option); 2931 } else { 2932 throw new ParserException("syntax error, expect DELETE or UPDATE, actual " ~ lexer.token() ~ " " 2933 ~ lexer.info()); 2934 } 2935 } 2936 2937 return fk; 2938 } 2939 2940 protected SQLForeignKeyImpl.Option parseReferenceOption() { 2941 SQLForeignKeyImpl.Option option; 2942 if (lexer.token() == Token.RESTRICT || lexer.identifierEquals(FnvHash.Constants.RESTRICT)) { 2943 option = SQLForeignKeyImpl.Option.RESTRICT; 2944 lexer.nextToken(); 2945 } else if (lexer.identifierEquals(FnvHash.Constants.CASCADE)) { 2946 option = SQLForeignKeyImpl.Option.CASCADE; 2947 lexer.nextToken(); 2948 } else if (lexer.token() == Token.SET) { 2949 lexer.nextToken(); 2950 accept(Token.NULL); 2951 option = SQLForeignKeyImpl.Option.SET_NULL; 2952 } else if (lexer.identifierEquals(FnvHash.Constants.NO)) { 2953 lexer.nextToken(); 2954 if (lexer.identifierEquals(FnvHash.Constants.ACTION)) { 2955 option = SQLForeignKeyImpl.Option.NO_ACTION; 2956 lexer.nextToken(); 2957 } else { 2958 throw new ParserException("syntax error, expect ACTION, actual " ~ lexer.token() ~ " " 2959 ~ lexer.info()); 2960 } 2961 } else { 2962 throw new ParserException("syntax error, expect ACTION, actual " ~ lexer.token() ~ " " 2963 ~ lexer.info()); 2964 } 2965 2966 return option; 2967 } 2968 2969 protected SQLColumnCheck parseColumnCheck() { 2970 lexer.nextToken(); 2971 SQLExpr expr = this.expr(); 2972 SQLColumnCheck check = new SQLColumnCheck(expr); 2973 2974 if (lexer.token == Token.DISABLE) { 2975 lexer.nextToken(); 2976 check.setEnable(Boolean.FALSE); 2977 } else if (lexer.token == Token.ENABLE) { 2978 lexer.nextToken(); 2979 check.setEnable(Boolean.TRUE); 2980 } else if (lexer.identifierEquals(FnvHash.Constants.VALIDATE)) { 2981 lexer.nextToken(); 2982 check.setValidate(Boolean.TRUE); 2983 } else if (lexer.identifierEquals(FnvHash.Constants.NOVALIDATE)) { 2984 lexer.nextToken(); 2985 check.setValidate(Boolean.FALSE); 2986 } else if (lexer.identifierEquals(FnvHash.Constants.RELY)) { 2987 lexer.nextToken(); 2988 check.setRely(Boolean.TRUE); 2989 } else if (lexer.identifierEquals(FnvHash.Constants.NORELY)) { 2990 lexer.nextToken(); 2991 check.setRely(Boolean.FALSE); 2992 } 2993 return check; 2994 } 2995 2996 public SQLPrimaryKey parsePrimaryKey() { 2997 accept(Token.PRIMARY); 2998 accept(Token.KEY); 2999 3000 SQLPrimaryKeyImpl pk = new SQLPrimaryKeyImpl(); 3001 3002 if (lexer.identifierEquals(FnvHash.Constants.CLUSTERED)) { 3003 lexer.nextToken(); 3004 pk.setClustered(true); 3005 } 3006 3007 accept(Token.LPAREN); 3008 orderBy(pk.getColumns(), pk); 3009 accept(Token.RPAREN); 3010 3011 return pk; 3012 } 3013 3014 public SQLUnique parseUnique() { 3015 accept(Token.UNIQUE); 3016 3017 SQLUnique unique = new SQLUnique(); 3018 accept(Token.LPAREN); 3019 orderBy(unique.getColumns(), unique); 3020 accept(Token.RPAREN); 3021 3022 if (lexer.token == Token.DISABLE) { 3023 lexer.nextToken(); 3024 unique.setEnable(Boolean.FALSE); 3025 } else if (lexer.token == Token.ENABLE) { 3026 lexer.nextToken(); 3027 unique.setEnable(Boolean.TRUE); 3028 } else if (lexer.identifierEquals(FnvHash.Constants.VALIDATE)) { 3029 lexer.nextToken(); 3030 unique.setValidate(Boolean.TRUE); 3031 } else if (lexer.identifierEquals(FnvHash.Constants.NOVALIDATE)) { 3032 lexer.nextToken(); 3033 unique.setValidate(Boolean.FALSE); 3034 } else if (lexer.identifierEquals(FnvHash.Constants.RELY)) { 3035 lexer.nextToken(); 3036 unique.setRely(Boolean.TRUE); 3037 } else if (lexer.identifierEquals(FnvHash.Constants.NORELY)) { 3038 lexer.nextToken(); 3039 unique.setRely(Boolean.FALSE); 3040 } 3041 3042 return unique; 3043 } 3044 3045 public SQLAssignItem parseAssignItem() { 3046 SQLAssignItem item = new SQLAssignItem(); 3047 3048 SQLExpr var = primary(); 3049 3050 if (cast(SQLIdentifierExpr)(var) !is null) { 3051 var = new SQLVariantRefExpr((cast(SQLIdentifierExpr) var).getName()); 3052 } 3053 item.setTarget(var); 3054 if (lexer.token == Token.COLONEQ) { 3055 lexer.nextToken(); 3056 } else if (lexer.token == Token.TRUE || lexer.identifierEquals(FnvHash.Constants.TRUE)) { 3057 lexer.nextToken(); 3058 item.setValue(new SQLBooleanExpr(true)); 3059 return item; 3060 } else if (lexer.token == Token.ON) { 3061 lexer.nextToken(); 3062 item.setValue(new SQLIdentifierExpr("ON")); 3063 return item; 3064 } else { 3065 if (lexer.token == Token.EQ) { 3066 lexer.nextToken(); 3067 } else { 3068 accept(Token.EQ); 3069 } 3070 } 3071 3072 if (lexer.token == Token.ON) { 3073 item.setValue(new SQLIdentifierExpr(lexer.stringVal())); 3074 lexer.nextToken(); 3075 } else { 3076 if (lexer.token == Token.ALL) { 3077 item.setValue(new SQLIdentifierExpr(lexer.stringVal())); 3078 lexer.nextToken(); 3079 } else { 3080 SQLExpr expr = this.expr(); 3081 3082 if (lexer.token == Token.COMMA && DBType.POSTGRESQL.name == (dbType)) { 3083 SQLListExpr listExpr = new SQLListExpr(); 3084 listExpr.addItem(expr); 3085 expr.setParent(listExpr); 3086 do { 3087 lexer.nextToken(); 3088 SQLExpr listItem = this.expr(); 3089 listItem.setParent(listExpr); 3090 listExpr.addItem(listItem); 3091 } while (lexer.token == Token.COMMA); 3092 item.setValue(listExpr); 3093 } else { 3094 item.setValue(expr); 3095 } 3096 } 3097 } 3098 3099 return item; 3100 } 3101 3102 public List!(SQLCommentHint) parseHints() { 3103 List!(SQLCommentHint) hints = new ArrayList!(SQLCommentHint)(); 3104 parseHints!(SQLCommentHint)((hints)); 3105 return hints; 3106 } 3107 3108 //@SuppressWarnings({ "unchecked", "rawtypes" }) 3109 public void parseHints(T)(List!(T) hints) { 3110 if (lexer.token == Token.HINT) { 3111 SQLCommentHint hint = new SQLCommentHint(lexer.stringVal()); 3112 3113 if (lexer.commentCount > 0) { 3114 hint.addBeforeComment(lexer.comments); 3115 } 3116 3117 hints.add(hint); 3118 lexer.nextToken(); 3119 } 3120 } 3121 3122 public SQLConstraint parseConstaint() { 3123 SQLName name = null; 3124 3125 if (lexer.token == Token.CONSTRAINT) { 3126 lexer.nextToken(); 3127 name = this.name(); 3128 } 3129 3130 SQLConstraint constraint; 3131 if (lexer.token == Token.PRIMARY) { 3132 constraint = parsePrimaryKey(); 3133 } else if (lexer.token == Token.UNIQUE) { 3134 constraint = parseUnique(); 3135 } else if (lexer.token == Token.KEY) { 3136 constraint = parseUnique(); 3137 } else if (lexer.token == Token.FOREIGN) { 3138 constraint = parseForeignKey(); 3139 } else if (lexer.token == Token.CHECK) { 3140 constraint = parseCheck(); 3141 } else { 3142 throw new ParserException("TODO : " ~ lexer.info()); 3143 } 3144 3145 constraint.setName(name); 3146 3147 return constraint; 3148 } 3149 3150 public SQLCheck parseCheck() { 3151 accept(Token.CHECK); 3152 SQLCheck check = createCheck(); 3153 accept(Token.LPAREN); 3154 check.setExpr(this.expr()); 3155 accept(Token.RPAREN); 3156 return check; 3157 } 3158 3159 protected SQLCheck createCheck() { 3160 return new SQLCheck(); 3161 } 3162 3163 public SQLForeignKeyConstraint parseForeignKey() { 3164 accept(Token.FOREIGN); 3165 accept(Token.KEY); 3166 3167 SQLForeignKeyImpl fk = createForeignKey(); 3168 3169 accept(Token.LPAREN); 3170 this.names(fk.getReferencingColumns(), fk); 3171 accept(Token.RPAREN); 3172 3173 accept(Token.REFERENCES); 3174 3175 fk.setReferencedTableName(this.name()); 3176 3177 if (lexer.token == Token.LPAREN) { 3178 lexer.nextToken(); 3179 this.names(fk.getReferencedColumns(), fk); 3180 accept(Token.RPAREN); 3181 } 3182 3183 if (lexer.token == Token.ON) { 3184 lexer.nextToken(); 3185 accept(Token.DELETE); 3186 if (lexer.identifierEquals(FnvHash.Constants.CASCADE)) { 3187 lexer.nextToken(); 3188 fk.setOnDeleteCascade(true); 3189 } else { 3190 accept(Token.SET); 3191 accept(Token.NULL); 3192 fk.setOnDeleteSetNull(true); 3193 } 3194 } 3195 3196 return fk; 3197 } 3198 3199 protected SQLForeignKeyImpl createForeignKey() { 3200 return new SQLForeignKeyImpl(); 3201 } 3202 3203 public SQLSelectItem parseSelectItem() { 3204 SQLExpr expr; 3205 bool connectByRoot = false; 3206 Token token = lexer.token; 3207 if (token == Token.IDENTIFIER) { 3208 string ident = lexer.stringVal(); 3209 long hash_lower = lexer.hash_lower(); 3210 lexer.nextTokenComma(); 3211 3212 if (hash_lower == FnvHash.Constants.CONNECT_BY_ROOT) { 3213 connectByRoot = lexer.token != Token.LPAREN; 3214 if (connectByRoot) { 3215 expr = new SQLIdentifierExpr(lexer.stringVal()); 3216 lexer.nextToken(); 3217 } else { 3218 expr = new SQLIdentifierExpr(ident); 3219 } 3220 } else if (FnvHash.Constants.DATE == hash_lower 3221 && lexer.token == Token.LITERAL_CHARS 3222 && (DBType.ORACLE.name == (getDbType()) 3223 || DBType.POSTGRESQL.name == (getDbType()))) { 3224 string literal = lexer.stringVal(); 3225 lexer.nextToken(); 3226 3227 SQLDateExpr dateExpr = new SQLDateExpr(); 3228 dateExpr.setLiteral(new String(literal)); 3229 3230 expr = dateExpr; 3231 } else { 3232 expr = new SQLIdentifierExpr(ident, hash_lower); 3233 } 3234 3235 token = lexer.token; 3236 3237 if (token == Token.DOT) { 3238 lexer.nextTokenIdent(); 3239 string name; 3240 long name_hash_lower; 3241 3242 if (lexer.token == Token.STAR) { 3243 name = "*"; 3244 name_hash_lower = FnvHash.Constants.STAR; 3245 } else { 3246 name = lexer.stringVal(); 3247 name_hash_lower = lexer.hash_lower(); 3248 } 3249 3250 lexer.nextTokenComma(); 3251 3252 token = lexer.token; 3253 if (token == Token.LPAREN) { 3254 bool aggregate = hash_lower == FnvHash.Constants.WMSYS && name_hash_lower == FnvHash.Constants.WM_CONCAT; 3255 expr = methodRest(expr, name, aggregate); 3256 token = lexer.token; 3257 } else { 3258 if (name_hash_lower == FnvHash.Constants.NEXTVAL) { 3259 expr = new SQLSequenceExpr(cast(SQLIdentifierExpr) expr, SQLSequenceExpr.Function.NextVal); 3260 } else if (name_hash_lower == FnvHash.Constants.CURRVAL) { 3261 expr = new SQLSequenceExpr(cast(SQLIdentifierExpr) expr, SQLSequenceExpr.Function.CurrVal); 3262 } else if (name_hash_lower == FnvHash.Constants.PREVVAL) { 3263 expr = new SQLSequenceExpr(cast(SQLIdentifierExpr) expr, SQLSequenceExpr.Function.PrevVal); 3264 } else { 3265 expr = new SQLPropertyExpr(expr, name, name_hash_lower); 3266 } 3267 } 3268 } 3269 3270 if (token == Token.COMMA) { 3271 return new SQLSelectItem(expr, null, connectByRoot); 3272 } 3273 3274 if (token == Token.AS) { 3275 lexer.nextToken(); 3276 string as = null; 3277 if (lexer.token != Token.COMMA && lexer.token != Token.FROM) { 3278 as = lexer.stringVal(); 3279 3280 lexer.nextTokenComma(); 3281 3282 if (lexer.token == Token.DOT) { 3283 lexer.nextToken(); 3284 as ~= '.' ~ lexer.stringVal(); 3285 lexer.nextToken(); 3286 } 3287 } 3288 3289 return new SQLSelectItem(expr, as, connectByRoot); 3290 } 3291 3292 if (token == Token.LITERAL_ALIAS) { 3293 string as = lexer.stringVal(); 3294 lexer.nextTokenComma(); 3295 return new SQLSelectItem(expr, as, connectByRoot); 3296 } 3297 3298 if ((token == Token.IDENTIFIER && hash_lower != FnvHash.Constants.CURRENT) 3299 || token == Token.MODEL) { 3300 string as; 3301 if (lexer.hash_lower == FnvHash.Constants.FORCE && DBType.MYSQL.name == (dbType)) { 3302 string force = lexer.stringVal(); 3303 3304 Lexer.SavePoint savePoint = lexer.mark(); 3305 lexer.nextToken(); 3306 3307 if (lexer.token == Token.PARTITION) { 3308 lexer.reset(savePoint); 3309 as = null; 3310 } else { 3311 as = force; 3312 lexer.nextTokenComma(); 3313 } 3314 } else { 3315 as = lexer.stringVal(); 3316 lexer.nextTokenComma(); 3317 } 3318 return new SQLSelectItem(expr, as, connectByRoot); 3319 } 3320 3321 if (token == Token.LPAREN) { 3322 lexer.nextToken(); 3323 expr = this.methodRest(expr, false); 3324 } else { 3325 expr = this.primaryRest(expr); 3326 } 3327 expr = this.exprRest(expr); 3328 } else if (token == Token.STAR) { 3329 expr = new SQLAllColumnExpr(); 3330 lexer.nextToken(); 3331 return new SQLSelectItem(expr, null, connectByRoot); 3332 } else if (token == Token.DO || token == Token.JOIN) { 3333 expr = this.name(); 3334 expr = this.exprRest(expr); 3335 } else { 3336 expr = this.expr(); 3337 } 3338 3339 string _alias; 3340 switch (lexer.token) { 3341 case Token.FULL: 3342 case Token.MODEL: 3343 case Token.TABLESPACE: 3344 _alias = lexer.stringVal(); 3345 lexer.nextToken(); 3346 break; 3347 default: 3348 _alias = as(); 3349 break; 3350 } 3351 3352 SQLSelectItem selectItem = new SQLSelectItem(expr, _alias, connectByRoot); 3353 if (lexer.token == Token.HINT && !lexer.isEnabled(SQLParserFeature.StrictForWall)) { 3354 string comment = "/*" ~ lexer.stringVal() ~ "*/"; 3355 selectItem.addAfterComment(comment); 3356 lexer.nextToken(); 3357 } 3358 3359 return selectItem; 3360 } 3361 3362 public SQLExpr parseGroupingSet() { 3363 string tmp = lexer.stringVal(); 3364 acceptIdentifier("GROUPING"); 3365 3366 SQLGroupingSetExpr expr = new SQLGroupingSetExpr(); 3367 3368 if (lexer.token == Token.SET || lexer.identifierEquals(FnvHash.Constants.SET)) { 3369 lexer.nextToken(); 3370 } else { 3371 return new SQLIdentifierExpr(tmp); 3372 } 3373 3374 accept(Token.LPAREN); 3375 3376 this.exprList(expr.getParameters(), expr); 3377 3378 accept(Token.RPAREN); 3379 3380 return expr; 3381 } 3382 3383 protected SQLPartition parsePartition() { 3384 throw new ParserException("TODO"); 3385 } 3386 3387 public SQLPartitionBy parsePartitionBy() { 3388 throw new ParserException("TODO"); 3389 } 3390 3391 public SQLPartitionValue parsePartitionValues() { 3392 if (lexer.token != Token.VALUES) { 3393 return null; 3394 } 3395 lexer.nextToken(); 3396 3397 SQLPartitionValue values = null; 3398 3399 if (lexer.token == Token.IN) { 3400 lexer.nextToken(); 3401 values = new SQLPartitionValue(SQLPartitionValue.Operator.In); 3402 3403 accept(Token.LPAREN); 3404 this.exprList(values.getItems(), values); 3405 accept(Token.RPAREN); 3406 } else if (lexer.identifierEquals(FnvHash.Constants.LESS)) { 3407 lexer.nextToken(); 3408 acceptIdentifier("THAN"); 3409 3410 values = new SQLPartitionValue(SQLPartitionValue.Operator.LessThan); 3411 3412 if (lexer.identifierEquals(FnvHash.Constants.MAXVALUE)) { 3413 SQLIdentifierExpr maxValue = new SQLIdentifierExpr(lexer.stringVal()); 3414 lexer.nextToken(); 3415 maxValue.setParent(values); 3416 values.addItem(maxValue); 3417 } else { 3418 accept(Token.LPAREN); 3419 this.exprList(values.getItems(), values); 3420 accept(Token.RPAREN); 3421 } 3422 } else if (lexer.token == Token.LPAREN) { 3423 values = new SQLPartitionValue(SQLPartitionValue.Operator.List); 3424 lexer.nextToken(); 3425 this.exprList(values.getItems(), values); 3426 accept(Token.RPAREN); 3427 } 3428 3429 return values; 3430 } 3431 3432 protected static bool isIdent(SQLExpr expr, string name) { 3433 if (cast(SQLIdentifierExpr)(expr) !is null) { 3434 SQLIdentifierExpr identExpr = cast(SQLIdentifierExpr) expr; 3435 return identExpr.getName().equalsIgnoreCase(name); 3436 } 3437 return false; 3438 } 3439 3440 public SQLLimit parseLimit() { 3441 if (lexer.token == Token.LIMIT) { 3442 lexer.nextTokenValue(); 3443 3444 SQLLimit limit = new SQLLimit(); 3445 3446 SQLExpr temp; 3447 if (lexer.token == Token.LITERAL_INT) { 3448 temp = new SQLIntegerExpr(lexer.integerValue()); 3449 lexer.nextTokenComma(); 3450 if (lexer.token != Token.COMMA && lexer.token != Token.EOF && lexer.token != Token.IDENTIFIER) { 3451 temp = this.primaryRest(temp); 3452 temp = this.exprRest(temp); 3453 } 3454 } else { 3455 temp = this.expr(); 3456 } 3457 3458 if (lexer.token == (Token.COMMA)) { 3459 limit.setOffset(temp); 3460 lexer.nextTokenValue(); 3461 3462 SQLExpr rowCount; 3463 if (lexer.token == Token.LITERAL_INT) { 3464 rowCount = new SQLIntegerExpr(lexer.integerValue()); 3465 lexer.nextToken(); 3466 if (lexer.token != Token.EOF && lexer.token != Token.IDENTIFIER) { 3467 rowCount = this.primaryRest(rowCount); 3468 rowCount = this.exprRest(rowCount); 3469 } 3470 } else { 3471 rowCount = this.expr(); 3472 } 3473 3474 limit.setRowCount(rowCount); 3475 } else if (lexer.identifierEquals(FnvHash.Constants.OFFSET)) { 3476 limit.setRowCount(temp); 3477 lexer.nextToken(); 3478 limit.setOffset(this.expr()); 3479 } else { 3480 limit.setRowCount(temp); 3481 } 3482 return limit; 3483 } 3484 3485 return null; 3486 } 3487 }