1 33 package smallsql.database; 34 35 import java.util.List ; 36 import java.sql.*; 37 38 39 public class SQLParser { 40 41 SSConnection con; 42 private char[] sql; 43 private List tokens; 44 private int tokenIdx; 45 46 Command parse(SSConnection con, String sql) throws SQLException{ 47 this.con = con; 48 Command cmd = parse( sql.toCharArray() ); 49 SQLToken token = nextToken(); 50 if(token != null){ 51 throw createSyntaxError( token, "Additional token after end of SQL statement"); 52 } 53 return cmd; 54 } 55 56 57 final private Command parse(char[] sql) throws SQLException{ 58 this.sql = sql; 59 this.tokens = SQLTokenizer.parseSQL( sql ); 60 tokenIdx = 0; 61 62 SQLToken token = nextToken(COMMANDS); 63 switch (token.value){ 64 case SQLTokenizer.SELECT: 65 return select(); 66 case SQLTokenizer.DELETE: 67 return delete(); 68 case SQLTokenizer.INSERT: 69 return insert(); 70 case SQLTokenizer.UPDATE: 71 return update(); 72 case SQLTokenizer.CREATE: 73 return create(); 74 case SQLTokenizer.DROP: 75 return drop(); 76 case SQLTokenizer.ALTER: 77 return alter(); 78 case SQLTokenizer.SET: 79 return set(); 80 case SQLTokenizer.USE: 81 token = nextToken(MISSING_EXPRESSION); 82 String name = token.getName( sql ); 83 checkValidIdentifer( name, token ); 84 CommandSet set = new CommandSet( con.log, SQLTokenizer.USE); 85 set.name = name; 86 return set; 87 case SQLTokenizer.EXECUTE: 88 return execute(); 89 case SQLTokenizer.TRUNCATE: 90 return truncate(); 91 default: 92 throw new Error (); 93 } 94 } 95 96 97 Expression parseExpression(String expr) throws SQLException{ 98 this.sql = expr.toCharArray(); 99 this.tokens = SQLTokenizer.parseSQL( sql ); 100 tokenIdx = 0; 101 return expression( null, 0); 102 } 103 104 private StringBuffer getSyntaxError( SQLToken token ){ 105 StringBuffer msg = new StringBuffer (256); 106 if(token != null){ 107 msg.append( "Syntax error at offset ").append( token.offset ) 108 .append( " on '" ).append( sql, token.offset, token.length ).append("'. "); 109 }else{ 110 msg.append( "Syntax error, unexpected end of SQL string. "); 111 } 112 return msg; 113 } 114 115 private SQLException createSyntaxError(SQLToken token, int[] validValues){ 116 StringBuffer msg = getSyntaxError( token ); 117 118 msg.append( "Requied keywords are: " ); 119 for(int i=0; i<validValues.length; i++){ 120 String name = SQLTokenizer.getKeyWord(validValues[i]); 121 if(name == null) name = String.valueOf( (char)validValues[i] ); 122 msg.append( name ); 123 if (i < validValues.length - 2) 124 msg.append( ", "); 125 else 126 if ( i == validValues.length - 2 ) 127 msg.append( " or "); 128 } 129 130 return createSyntaxError( msg, token ); 131 } 132 133 private SQLException createSyntaxError( StringBuffer msg, SQLToken token){ 134 int offset = (token != null) ? token.offset : sql.length; 135 int begin = Math.max( 0, offset-40); 136 int end = Math.min( offset+20, sql.length ); 137 String lineSeparator = System.getProperty( "line.separator" ); 138 msg.append( lineSeparator ); 139 msg.append( sql, begin, end-begin); 140 msg.append( lineSeparator ); 141 for(; begin<offset; begin++) msg.append(' '); 142 msg.append('^'); 143 return Utils.createSQLException( msg.toString() ); 144 } 145 146 private SQLException createSyntaxError(SQLToken token, String errorMsg){ 147 StringBuffer msg = getSyntaxError( token ).append(errorMsg); 148 return createSyntaxError( msg, token ); 149 } 150 151 152 private void checkValidIdentifer(String name, SQLToken token) throws SQLException{ 153 if(token.value == SQLTokenizer.ASTERISK) return; 154 if(token.value != SQLTokenizer.VALUE && 155 token.value != SQLTokenizer.IDENTIFER && 156 token.value < 200){ 157 throw createSyntaxError( token, "Identifer expected."); 158 } 159 if(name.length() == 0) 160 throw createSyntaxError( token, "Empty Identifer."); 161 if(name.charAt(0) < '@') 162 throw createSyntaxError( token, "Wrong Identifer '" + name + "'."); 163 } 164 165 166 final private boolean isKeyword(SQLToken token){ 167 if(token == null) return false; 168 switch(token.value){ 169 case SQLTokenizer.SELECT: 170 case SQLTokenizer.INSERT: 171 case SQLTokenizer.UPDATE: 172 case SQLTokenizer.UNION: 173 case SQLTokenizer.FROM: 174 case SQLTokenizer.WHERE: 175 case SQLTokenizer.GROUP: 176 case SQLTokenizer.HAVING: 177 case SQLTokenizer.ORDER: 178 case SQLTokenizer.COMMA: 179 case SQLTokenizer.SET: 180 return true; 181 } 182 return false; 183 } 184 185 188 private SQLToken lastToken(){ 189 if(tokenIdx > tokens.size()){ 190 return null; 191 } 192 return (SQLToken)tokens.get( tokenIdx-1 ); 193 } 194 private void previousToken(){ 195 tokenIdx--; 196 } 197 198 private SQLToken nextToken(){ 199 if(tokenIdx >= tokens.size()){ 200 tokenIdx++; return null; 202 } 203 return (SQLToken)tokens.get( tokenIdx++ ); 204 } 205 206 private SQLToken nextToken( int[] validValues) throws SQLException{ 207 SQLToken token = nextToken(); 208 if(token == null) throw createSyntaxError( token, validValues); 209 if(validValues == MISSING_EXPRESSION) return token; if(validValues == MISSING_IDENTIFER){ 211 switch(token.value){ 213 case SQLTokenizer.PARENTHESIS_L: 214 case SQLTokenizer.PARENTHESIS_R: 215 case SQLTokenizer.COMMA: 216 throw createSyntaxError( token, validValues); 217 } 218 return token; 219 } 220 for(int i=validValues.length-1; i>=0; i--){ 221 if(token.value == validValues[i]) return token; 222 } 223 throw createSyntaxError( token, validValues); 224 } 225 226 227 232 private CommandSelect singleSelect() throws SQLException{ 233 CommandSelect selCmd = new CommandSelect(con.log); 234 SQLToken token; 235 Switch: while(true){ 237 token = nextToken(MISSING_EXPRESSION); 238 switch(token.value){ 239 case SQLTokenizer.TOP: 240 token = nextToken(MISSING_EXPRESSION); 241 try{ 242 int maxRows = Integer.parseInt(token.getName(sql)); 243 selCmd.setMaxRows(maxRows); 244 }catch(Exception e){ 245 throw createSyntaxError(token, e.getMessage()); 246 } 247 break; 248 case SQLTokenizer.ALL: 249 selCmd.setDistinct(false); 250 break; 251 case SQLTokenizer.DISTINCT: 252 selCmd.setDistinct(true); 253 break; 254 default: 255 previousToken(); 256 break Switch; 257 } 258 } 259 260 while(true){ 261 Expression column = expression(selCmd, 0); 262 selCmd.addColumnExpression( column ); 263 264 token = nextToken(); 265 if(token == null) return selCmd; 267 boolean as = false; 268 if(token.value == SQLTokenizer.AS){ 269 token = nextToken(MISSING_EXPRESSION); 270 as = true; 271 } 272 273 if(as || (!isKeyword(token))){ 274 String alias = token.getName( sql ); 275 checkValidIdentifer( alias, token); 276 column.setAlias( alias ); 277 token = nextToken(); 278 if(token == null) return selCmd; } 280 281 switch(token.value){ 282 case SQLTokenizer.COMMA: 283 if(column == null) throw createSyntaxError( token, MISSING_EXPRESSION ); 284 column = null; 285 break; 286 case SQLTokenizer.FROM: 287 if(column == null) throw createSyntaxError( token, MISSING_EXPRESSION ); 288 column = null; 289 from(selCmd); 290 return selCmd; 291 292 default: 293 if(!isKeyword(token)) 294 throw createSyntaxError( token, new int[]{SQLTokenizer.COMMA, SQLTokenizer.FROM} ); 295 previousToken(); 296 return selCmd; 297 } 298 } 299 } 300 301 302 final private CommandSelect select() throws SQLException{ 303 CommandSelect selCmd = singleSelect(); 304 SQLToken token = nextToken(); 305 306 UnionAll union = null; 307 308 while(token != null && token.value == SQLTokenizer.UNION){ 309 if(union == null){ 310 union = new UnionAll(); 311 union.addDataSource(new ViewResult( con, selCmd )); 312 selCmd = new CommandSelect(con.log); 313 selCmd.setSource( union ); 314 DataSources from = new DataSources(); 315 from.add(union); 316 selCmd.setFrom( from ); 317 selCmd.addColumnExpression( new ExpressionName("*") ); 318 } 319 nextToken(MISSING_ALL); 320 nextToken(MISSING_SELECT); 321 union.addDataSource( new ViewResult( con, singleSelect() ) ); 322 token = nextToken(); 323 } 324 if(token != null && token.value == SQLTokenizer.ORDER){ 325 order( selCmd ); 326 }else{ 327 previousToken(); 328 } 329 return selCmd; 330 } 331 332 333 private Command delete() throws SQLException{ 334 CommandDelete cmd = new CommandDelete(con.log); 335 nextToken(MISSING_FROM); 336 from(cmd); 337 SQLToken token = nextToken(); 338 if(token != null){ 339 if(token.value != SQLTokenizer.WHERE) 340 throw this.createSyntaxError(token, MISSING_WHERE); 341 where(cmd); 342 } 343 return cmd; 344 } 345 346 347 private Command truncate() throws SQLException{ 348 CommandDelete cmd = new CommandDelete(con.log); 349 nextToken(MISSING_TABLE); 350 from(cmd); 351 return cmd; 352 } 353 354 355 private Command insert() throws SQLException{ 356 SQLToken token = nextToken( MISSING_INTO ); 357 token = nextToken( MISSING_IDENTIFER ); 358 CommandInsert cmd = new CommandInsert( con.log, token.getName(sql) ); 359 360 int parthesisCount = 0; 361 362 token = nextToken(MISSING_PARENTHESIS_VALUES_SELECT); 363 if(token.value == SQLTokenizer.PARENTHESIS_L){ 364 token = nextToken(MISSING_EXPRESSION); 365 if(token.value == SQLTokenizer.SELECT){ 366 parthesisCount++; 367 cmd.noColumns = true; 368 }else{ 369 previousToken(); 370 Expressions list = expressionParenthesisList(cmd); 371 for(int i=0; i<list.size(); i++){ 372 cmd.addColumnExpression( list.get( i ) ); 373 } 374 token = nextToken(MISSING_PARENTHESIS_VALUES_SELECT); 375 } 376 }else cmd.noColumns = true; 377 378 Switch: while(true) 379 switch(token.value){ 380 case SQLTokenizer.VALUES:{ 381 token = nextToken(MISSING_PARENTHESIS_L); 382 cmd.addValues( expressionParenthesisList(cmd) ); 383 return cmd; 384 } 385 case SQLTokenizer.SELECT: 386 cmd.addValues( select() ); 387 while(parthesisCount-- > 0){ 388 nextToken(MISSING_PARENTHESIS_R); 389 } 390 return cmd; 391 case SQLTokenizer.PARENTHESIS_L: 392 token = nextToken(MISSING_PARENTHESIS_VALUES_SELECT); 393 parthesisCount++; 394 continue Switch; 395 default: 396 throw new Error (); 397 } 398 } 399 400 401 private Command update() throws SQLException{ 402 CommandUpdate cmd = new CommandUpdate(con.log); 403 DataSources tables = new DataSources(); 405 cmd.setFrom( tables ); 406 cmd.setSource( rowSource( cmd, tables, 0 ) ); 407 408 SQLToken token = nextToken(MISSING_SET); 409 while(true){ 410 token = nextToken(); 411 Expression dest = expressionSingle( cmd, token); 412 if(dest.getType() != Expression.NAME) throw createSyntaxError( token, MISSING_IDENTIFER ); 413 nextToken(MISSING_EQUALS); 414 Expression src = expression(cmd, 0); 415 cmd.addSetting( dest, src); 416 token = nextToken(); 417 if(token == null) break; 418 switch(token.value){ 419 case SQLTokenizer.WHERE: 420 where(cmd); 421 return cmd; 422 case SQLTokenizer.COMMA: 423 continue; 424 default: throw createSyntaxError( token, MISSING_WHERE_COMMA ); 425 } 426 } 427 return cmd; 428 } 429 430 431 private Command create() throws SQLException{ 432 SQLToken token = nextToken(); 433 if(token == null) throw createSyntaxError( token, COMMANDS_CREATE ); 434 switch(token.value){ 435 case SQLTokenizer.DATABASE: 436 return createDatabase(); 437 case SQLTokenizer.TABLE: 438 return createTable(); 439 case SQLTokenizer.VIEW: 440 return createView(); 441 case SQLTokenizer.INDEX: 442 return createIndex(); 443 case SQLTokenizer.PROCEDURE: 444 return createProcedure(); 445 default: 446 throw createSyntaxError( token, COMMANDS_CREATE ); 447 } 448 } 449 450 451 private CommandCreateDatabase createDatabase() throws SQLException{ 452 SQLToken token = nextToken(); 453 if(token == null) throw createSyntaxError( token, MISSING_EXPRESSION ); 454 return new CommandCreateDatabase( con.log, token.getName(sql)); 455 } 456 457 458 private CommandCreateTable createTable() throws SQLException{ 459 SQLToken token = nextToken( MISSING_IDENTIFER ); String tableName = token.getName(sql); 461 CommandCreateTable cmdCreate = new CommandCreateTable( con.log, tableName); 462 token = nextToken( MISSING_PARENTHESIS_L ); 463 464 nextCol: 465 while(true){ 466 token = nextToken( MISSING_EXPRESSION ); 467 468 String constraintName; 469 if(token.value == SQLTokenizer.CONSTRAINT){ 470 token = nextToken( MISSING_IDENTIFER ); 472 constraintName = token.getName(sql); 473 checkValidIdentifer( constraintName, token ); 474 475 token = nextToken( MISSING_KEYTYPE ); 476 }else{ 477 constraintName = null; 478 } 479 switch(token.value){ 480 case SQLTokenizer.PRIMARY: 481 case SQLTokenizer.UNIQUE: 482 case SQLTokenizer.FOREIGN: 483 IndexDescription index = index(cmdCreate, token.value, tableName, constraintName, null); 484 if(token.value == SQLTokenizer.FOREIGN){ 485 nextToken( MISSING_REFERENCES ); 486 token = nextToken( MISSING_IDENTIFER ); 487 String pk = token.getName(sql); 488 Expressions expressions = new Expressions(); 489 Strings columns = new Strings(); 490 expressionDefList( cmdCreate, expressions, columns ); 491 IndexDescription pkIndex = new IndexDescription( null, pk, SQLTokenizer.UNIQUE, expressions, columns); 492 ForeignKey foreignKey = new ForeignKey(pk, pkIndex, tableName, index); 493 cmdCreate.addForeingnKey(foreignKey); 494 }else{ 495 cmdCreate.addIndex( index ); 496 } 497 498 token = nextToken( MISSING_COMMA_PARENTHESIS ); 499 switch(token.value){ 500 case SQLTokenizer.PARENTHESIS_R: 501 return cmdCreate; 502 case SQLTokenizer.COMMA: 503 continue nextCol; 504 } 505 } 506 String colName = token.getName( sql ); 508 509 Column col = datatype(false); 510 col.setName( colName ); 511 512 token = nextToken(MISSING_OPTIONS_DATATYPE); 513 boolean nullableWasSet = false; 514 boolean defaultWasSet = col.isAutoIncrement(); while(true){ 516 switch(token.value){ 517 case SQLTokenizer.PARENTHESIS_R: 518 cmdCreate.addColumn( col ); 519 return cmdCreate; 520 case SQLTokenizer.COMMA: 521 cmdCreate.addColumn( col ); 522 continue nextCol; 523 case SQLTokenizer.DEFAULT: 524 if(defaultWasSet) throw createSyntaxError( token, MISSING_COMMA_PARENTHESIS ); 525 int offset = token.offset + token.length; 526 token = nextToken(); 527 if(token != null) offset = token.offset; 528 previousToken(); 529 Expression expr = expression(cmdCreate, 0); 530 SQLToken last = lastToken(); 531 int length = last.offset + last.length - offset; 532 String def = new String ( sql, offset, length ); 533 col.setDefaultValue( expr, def ); 534 defaultWasSet = true; 535 break; 536 case SQLTokenizer.IDENTITY: 537 if(defaultWasSet) throw createSyntaxError( token, MISSING_COMMA_PARENTHESIS ); 538 col.setAutoIncrement(true); 539 defaultWasSet = true; 540 break; 541 case SQLTokenizer.NULL: 542 if(nullableWasSet) throw createSyntaxError( token, MISSING_COMMA_PARENTHESIS ); 543 nullableWasSet = true; 545 break; 546 case SQLTokenizer.NOT: 547 if(nullableWasSet) throw createSyntaxError( token, MISSING_COMMA_PARENTHESIS ); 548 token = nextToken( MISSING_NULL ); 549 col.setNullable(false); 550 nullableWasSet = true; 551 break; 552 case SQLTokenizer.PARENTHESIS_L: 553 throw createSyntaxError(token, MISSING_COMMA_PARENTHESIS); 554 case SQLTokenizer.PRIMARY: 555 case SQLTokenizer.UNIQUE: 556 IndexDescription index = index(cmdCreate, token.value, tableName, null, colName); 557 cmdCreate.addIndex( index ); 558 break; 559 default: 560 throw new Error (); 561 } 562 token = nextToken( MISSING_OPTIONS_DATATYPE ); 563 } 564 } 565 } 566 567 577 private IndexDescription index(Command cmd, int constraintType, String tableName, String contrainName, String columnName) throws SQLException{ 578 if(constraintType != SQLTokenizer.UNIQUE) nextToken( MISSING_KEY ); 579 SQLToken token = nextToken( MISSING_EXPRESSION ); 580 switch(token.value){ 581 case SQLTokenizer.CLUSTERED: 582 case SQLTokenizer.NONCLUSTERED: 583 token = nextToken( MISSING_EXPRESSION ); 585 break; 586 } 587 Strings columns = new Strings(); 588 Expressions expressions = new Expressions(); 589 if(columnName != null){ 590 columns.add(columnName); 592 expressions.add(new ExpressionName(columnName)); 593 previousToken(); 594 }else{ 595 previousToken(); 597 expressionDefList( cmd, expressions, columns ); 598 } 599 return new IndexDescription( contrainName, tableName, constraintType, expressions, columns); 600 } 601 602 603 607 private Column datatype(boolean isEscape) throws SQLException{ 608 SQLToken token; 609 int dataType; 610 if(isEscape){ 611 token = nextToken( MISSING_SQL_DATATYPE ); 612 switch(token.value){ 613 case SQLTokenizer.SQL_BIGINT: dataType = SQLTokenizer.BIGINT; break; 614 case SQLTokenizer.SQL_BINARY: dataType = SQLTokenizer.BINARY; break; 615 case SQLTokenizer.SQL_BIT: dataType = SQLTokenizer.BIT; break; 616 case SQLTokenizer.SQL_CHAR: dataType = SQLTokenizer.CHAR; break; 617 case SQLTokenizer.SQL_DATE: dataType = SQLTokenizer.DATE; break; 618 case SQLTokenizer.SQL_DECIMAL: dataType = SQLTokenizer.DECIMAL; break; 619 case SQLTokenizer.SQL_DOUBLE: dataType = SQLTokenizer.DOUBLE; break; 620 case SQLTokenizer.SQL_FLOAT: dataType = SQLTokenizer.FLOAT; break; 621 case SQLTokenizer.SQL_INTEGER: dataType = SQLTokenizer.INT; break; 622 case SQLTokenizer.SQL_LONGVARBINARY: dataType = SQLTokenizer.LONGVARBINARY;break; 623 case SQLTokenizer.SQL_LONGVARCHAR: dataType = SQLTokenizer.LONGVARCHAR;break; 624 case SQLTokenizer.SQL_REAL: dataType = SQLTokenizer.REAL; break; 625 case SQLTokenizer.SQL_SMALLINT: dataType = SQLTokenizer.SMALLINT; break; 626 case SQLTokenizer.SQL_TIME: dataType = SQLTokenizer.TIME; break; 627 case SQLTokenizer.SQL_TIMESTAMP: dataType = SQLTokenizer.TIMESTAMP; break; 628 case SQLTokenizer.SQL_TINYINT: dataType = SQLTokenizer.TINYINT; break; 629 case SQLTokenizer.SQL_VARBINARY: dataType = SQLTokenizer.VARBINARY; break; 630 case SQLTokenizer.SQL_VARCHAR: dataType = SQLTokenizer.VARCHAR; break; 631 default: throw new Error (); 632 } 633 }else{ 634 token = nextToken( MISSING_DATATYPE ); 635 dataType = token.value; 636 } 637 Column col = new Column(); 638 639 if(dataType == SQLTokenizer.LONG){ 641 token = nextToken(); 642 if(token != null && token.value == SQLTokenizer.RAW){ 643 dataType = SQLTokenizer.LONGVARBINARY; 644 }else{ 645 dataType = SQLTokenizer.LONGVARCHAR; 646 previousToken(); 647 } 648 } 649 650 token = nextToken( MISSING_OPTIONS_DATATYPE ); 651 switch(dataType){ 652 case SQLTokenizer.RAW: 653 dataType = SQLTokenizer.VARBINARY; 654 case SQLTokenizer.CHAR: 656 case SQLTokenizer.VARCHAR: 657 case SQLTokenizer.NCHAR: 658 case SQLTokenizer.NVARCHAR: 659 case SQLTokenizer.BINARY: 660 case SQLTokenizer.VARBINARY: 661 { 662 int displaySize; 664 if(token.value != SQLTokenizer.PARENTHESIS_L){ 665 displaySize = 30; 666 }else{ 667 token = nextToken( MISSING_EXPRESSION ); 668 try{ 669 displaySize = Integer.parseInt(token.getName(sql) ); 670 }catch(Exception e){ 671 throw createSyntaxError(token, MISSING_NUMBERVALUE ); 672 } 673 nextToken( MISSING_PARENTHESIS_R ); 674 token = nextToken(MISSING_OPTIONS_DATATYPE); 675 } 676 col.setPrecision( displaySize ); 677 break; 678 } 679 case SQLTokenizer.SYSNAME: 680 col.setPrecision(255); 681 dataType = SQLTokenizer.VARCHAR; 682 break; 683 case SQLTokenizer.COUNTER: 684 col.setAutoIncrement(true); 685 dataType = SQLTokenizer.INT; 686 break; 687 case SQLTokenizer.NUMERIC: 688 case SQLTokenizer.DECIMAL: 689 if(token.value == SQLTokenizer.PARENTHESIS_L){ 690 token = nextToken( MISSING_EXPRESSION ); 692 int value; 693 try{ 694 value = Integer.parseInt(token.getName(sql) ); 695 }catch(Exception e){ 696 throw createSyntaxError(token, MISSING_NUMBERVALUE ); 697 } 698 col.setPrecision(value); 699 token = nextToken( MISSING_COMMA_PARENTHESIS ); 700 if(token.value == SQLTokenizer.COMMA){ 701 token = nextToken( MISSING_EXPRESSION ); 703 try{ 704 value = Integer.parseInt(token.getName(sql) ); 705 }catch(Exception e){ 706 throw createSyntaxError(token, MISSING_NUMBERVALUE ); 707 } 708 col.setScale(value); 709 nextToken( MISSING_PARENTHESIS_R ); 710 } 711 token = nextToken(MISSING_OPTIONS_DATATYPE); 712 }else{ 713 col.setPrecision(18); } 715 break; 716 } 717 col.setDataType( dataType ); 718 this.previousToken(); 719 return col; 720 } 721 722 private CommandCreateView createView() throws SQLException{ 723 SQLToken token = nextToken(MISSING_IDENTIFER ); 724 String viewName = token.getName(sql); 725 checkValidIdentifer( viewName, token ); 726 727 nextToken(MISSING_AS); 728 token = nextToken(MISSING_SELECT); 729 CommandCreateView cmd = new CommandCreateView( con.log, viewName ); 730 731 cmd.sql = new String (sql, token.offset, sql.length-token.offset ); 732 select(); return cmd; 734 } 735 736 737 private CommandCreateDatabase createIndex() throws SQLException{ 738 throw Utils.createSQLException("UnsupportedOperation Create Index"); 740 } 741 742 private CommandCreateDatabase createProcedure() throws SQLException{ 743 throw Utils.createSQLException("UnsupportedOperation Create Procedure"); 745 } 746 747 private Command drop() throws SQLException{ 748 SQLToken tokenType = nextToken(COMMANDS_CREATE); 749 750 SQLToken token = nextToken( MISSING_EXPRESSION ); 751 String catalog = null; 752 String name = token.getName( sql ); 753 checkValidIdentifer( name, token ); 754 token = nextToken(); 755 if(token != null && token.value == SQLTokenizer.POINT){ 757 token = nextToken(MISSING_EXPRESSION); 758 catalog = name; 759 name = token.getName( sql ); 760 checkValidIdentifer( name, token ); 761 token = nextToken(); 762 } 763 previousToken(); 764 765 switch(tokenType.value){ 766 case SQLTokenizer.DATABASE: 767 case SQLTokenizer.TABLE: 768 case SQLTokenizer.VIEW: 769 case SQLTokenizer.INDEX: 770 case SQLTokenizer.PROCEDURE: 771 return new CommandDrop( con.log, catalog, name, tokenType.value); 772 default: 773 throw createSyntaxError( tokenType, COMMANDS_CREATE ); 774 } 775 } 776 777 778 private Command alter() throws SQLException{ 779 throw Utils.createSQLException("UnsupportedOperation Alter"); 781 } 782 783 784 private CommandSet set() throws SQLException{ 785 SQLToken token = nextToken( COMMANDS_SET ); 786 switch(token.value){ 787 case SQLTokenizer.TRANSACTION: 788 return setTransaction(); 789 default: 790 throw new Error (); 791 } 792 } 793 794 private CommandSet setTransaction() throws SQLException{ 795 SQLToken token = nextToken( MISSING_ISOLATION ); 796 token = nextToken( MISSING_LEVEL ); 797 token = nextToken( COMMANDS_TRANS_LEVEL ); 798 CommandSet cmd = new CommandSet( con.log, SQLTokenizer.LEVEL ); 799 switch(token.value){ 800 case SQLTokenizer.READ: 801 token = nextToken( MISSING_COMM_UNCOMM ); 802 switch(token.value){ 803 case SQLTokenizer.COMMITTED: 804 cmd.isolationLevel = Connection.TRANSACTION_READ_COMMITTED; 805 break; 806 case SQLTokenizer.UNCOMMITTED: 807 cmd.isolationLevel = Connection.TRANSACTION_READ_UNCOMMITTED; 808 break; 809 default: 810 throw new Error (); 811 } 812 return cmd; 813 case SQLTokenizer.REPEATABLE: 814 token = nextToken( MISSING_READ ); 815 cmd.isolationLevel = Connection.TRANSACTION_REPEATABLE_READ; 816 return cmd; 817 case SQLTokenizer.SERIALIZABLE: 818 cmd.isolationLevel = Connection.TRANSACTION_SERIALIZABLE; 819 return cmd; 820 default: 821 throw new Error (); 822 } 823 824 825 } 826 827 private Command execute() throws SQLException{ 828 throw Utils.createSQLException("UnsupportedOperation Execute"); 830 } 831 832 839 private Expressions expressionParenthesisList(Command cmd) throws SQLException{ 840 Expressions list = new Expressions(); 841 { 842 SQLToken token = nextToken(); 843 if(token != null && token.value == SQLTokenizer.PARENTHESIS_R){ 844 return list; 846 } 847 previousToken(); 848 } 849 while(true){ 850 list.add( expression(cmd, 0) ); 851 SQLToken token = nextToken(MISSING_COMMA_PARENTHESIS); 852 switch(token.value){ 853 case SQLTokenizer.PARENTHESIS_R: 854 return list; 855 case SQLTokenizer.COMMA: 856 continue; 857 default: 858 throw new Error (); 859 } 860 } 861 } 862 863 864 867 private Expressions expressionTokenList(Command cmd, int listType) throws SQLException{ 868 Expressions list = new Expressions(); 869 while(true){ 870 Expression expr = expression(cmd, 0); 871 list.add( expr ); 872 SQLToken token = nextToken(); 873 874 if(listType == SQLTokenizer.ORDER && token != null){ 875 switch(token.value){ 876 case SQLTokenizer.DESC: 877 expr.setAlias(SQLTokenizer.DESC_STR); 878 case SQLTokenizer.ASC: 880 token = nextToken(); 881 } 882 } 883 884 if(token == null) { 885 previousToken(); 886 return list; 887 } 888 889 switch(token.value){ 890 case SQLTokenizer.COMMA: 891 continue; 892 default: 893 if(isKeyword(token) ){ 894 previousToken(); 895 return list; 896 } 897 throw createSyntaxError( token, MISSING_TOKEN_LIST); 898 } 899 } 900 } 901 902 903 private void expressionDefList(Command cmd, Expressions expressions, Strings columns) throws SQLException{ 904 SQLToken token = nextToken(); 905 if(token.value != SQLTokenizer.PARENTHESIS_L) throw createSyntaxError(token, MISSING_PARENTHESIS_L ); 906 Loop: 907 while(true){ 908 int offset = token.offset + token.length; 909 token = nextToken(); 910 if(token != null) offset = token.offset; 911 previousToken(); 912 913 expressions.add( expression(cmd, 0) ); 914 SQLToken last = lastToken(); 915 int length = last.offset + last.length - offset; 916 columns.add( new String ( sql, offset, length ) ); 917 918 token = nextToken(MISSING_COMMA_PARENTHESIS); 919 switch(token.value){ 920 case SQLTokenizer.PARENTHESIS_R: 921 break Loop; 922 case SQLTokenizer.COMMA: 923 continue; 924 default: 925 throw new Error (); 926 } 927 } 928 } 929 930 931 936 private Expression expression(Command cmd, int previousOperationLevel) throws SQLException{ 937 SQLToken token = nextToken(); 938 if(token == null) return null; 939 Expression leftExpr; 940 switch(token.value){ 941 case SQLTokenizer.NOT: 942 leftExpr = new ExpressionArithmetic( expression( cmd, ExpressionArithmetic.NOT / 10), ExpressionArithmetic.NOT); 943 break; 944 case SQLTokenizer.MINUS: 945 leftExpr = new ExpressionArithmetic( expression( cmd, ExpressionArithmetic.NEGATIVE / 10), ExpressionArithmetic.NEGATIVE); 946 break; 947 case SQLTokenizer.TILDE: 948 leftExpr = new ExpressionArithmetic( expression( cmd, ExpressionArithmetic.BIT_NOT / 10), ExpressionArithmetic.BIT_NOT); 949 break; 950 case SQLTokenizer.PARENTHESIS_L: 951 leftExpr = expression( cmd, 0); 952 token = nextToken(MISSING_PARENTHESIS_R); 953 break; 954 default: 955 leftExpr = expressionSingle( cmd, token); 956 } 957 boolean isNot = false; 958 while((token = nextToken()) != null){ 959 Expression rightExpr; 960 int operation = ExpressionArithmetic.getOperationFromToken(token.value); 961 int level = operation / 10; 962 if(previousOperationLevel >= level){ 963 previousToken(); 964 return leftExpr; 965 } 966 switch(token.value){ 967 case SQLTokenizer.PLUS: 968 case SQLTokenizer.MINUS: 969 case SQLTokenizer.ASTERISK: 970 case SQLTokenizer.SLACH: 971 case SQLTokenizer.PERCENT: 972 case SQLTokenizer.EQUALS: 973 case SQLTokenizer.LESSER: 974 case SQLTokenizer.LESSER_EQU: 975 case SQLTokenizer.GREATER: 976 case SQLTokenizer.GREATER_EQU: 977 case SQLTokenizer.UNEQUALS: 978 case SQLTokenizer.LIKE: 979 case SQLTokenizer.OR: 980 case SQLTokenizer.AND: 981 case SQLTokenizer.BIT_AND: 982 case SQLTokenizer.BIT_OR: 983 case SQLTokenizer.BIT_XOR: 984 rightExpr = expression( cmd, level ); 985 leftExpr = new ExpressionArithmetic( leftExpr, rightExpr, operation ); 986 break; 987 case SQLTokenizer.BETWEEN: 988 rightExpr = expression( cmd, ExpressionArithmetic.AND ); 989 nextToken( MISSING_AND ); 990 Expression rightExpr2 = expression( cmd, level ); 991 leftExpr = new ExpressionArithmetic( leftExpr, rightExpr, rightExpr2, operation ); 992 break; 993 case SQLTokenizer.IN: 994 nextToken(MISSING_PARENTHESIS_L); 995 token = nextToken(MISSING_EXPRESSION); 996 if(token.value == SQLTokenizer.SELECT){ 997 CommandSelect cmdSel = select(); 998 leftExpr = new ExpressionInSelect( con, leftExpr, cmdSel, operation ); 999 nextToken(MISSING_PARENTHESIS_R); 1000 }else{ 1001 previousToken(); 1002 Expressions list = expressionParenthesisList( cmd ); 1003 leftExpr = new ExpressionArithmetic( leftExpr, list, operation ); 1004 } 1005 break; 1006 case SQLTokenizer.IS: 1007 token = nextToken(MISSING_NOT_NULL); 1008 if(token.value == SQLTokenizer.NOT){ 1009 nextToken(MISSING_NULL); 1010 operation++; 1011 } 1012 leftExpr = new ExpressionArithmetic( leftExpr, operation ); 1013 break; 1014 case SQLTokenizer.NOT: 1015 token = nextToken(MISSING_BETWEEN_IN); 1016 previousToken(); 1017 isNot = true; 1018 continue; 1019 default: 1020 previousToken(); 1021 return leftExpr; 1022 } 1023 if(isNot){ 1024 isNot = false; 1025 leftExpr = new ExpressionArithmetic( leftExpr, ExpressionArithmetic.NOT); 1026 } 1027 } 1028 previousToken(); 1029 return leftExpr; 1030 } 1031 1032 1037 private Expression expressionSingle(Command cmd, SQLToken token) throws SQLException{ 1038 boolean isMinus = false; 1039 if(token != null){ 1040 switch(token.value){ 1041 case SQLTokenizer.NULL: 1042 return new ExpressionValue( null, SQLTokenizer.NULL ); 1043 case SQLTokenizer.STRING: 1044 return new ExpressionValue( token.getName(null), SQLTokenizer.VARCHAR ); 1045 case SQLTokenizer.IDENTIFER: 1046 { 1047 String name = token.getName(null); 1048 checkValidIdentifer( name, token ); 1049 ExpressionName expr = new ExpressionName( name ); 1050 SQLToken token2 = nextToken(); 1051 if(token2 != null && token2.value == SQLTokenizer.POINT){ 1052 token = nextToken(MISSING_EXPRESSION); 1053 expr.setNameAfterTableAlias( token.getName( sql ) ); 1054 }else{ 1055 previousToken(); 1056 } 1057 return expr; 1058 } 1059 case SQLTokenizer.TRUE: 1060 return new ExpressionValue( Boolean.TRUE, SQLTokenizer.BOOLEAN ); 1061 case SQLTokenizer.FALSE: 1062 return new ExpressionValue( Boolean.FALSE, SQLTokenizer.BOOLEAN ); 1063 case SQLTokenizer.ESCAPE_L:{ 1064 token = nextToken(COMMANDS_ESCAPE); 1065 SQLToken para = nextToken(MISSING_EXPRESSION); 1066 Expression expr; 1067 switch(token.value){ 1068 case SQLTokenizer.D: expr = new ExpressionValue( DateTime.valueOf(para.getName(sql), SQLTokenizer.DATE), SQLTokenizer.DATE ); 1070 break; 1071 case SQLTokenizer.T: expr = new ExpressionValue( DateTime.valueOf(para.getName(sql), SQLTokenizer.TIME), SQLTokenizer.TIME ); 1073 break; 1074 case SQLTokenizer.TS: expr = new ExpressionValue( DateTime.valueOf(para.getName(sql), SQLTokenizer.TIMESTAMP), SQLTokenizer.TIMESTAMP ); 1076 break; 1077 case SQLTokenizer.FN: nextToken(MISSING_PARENTHESIS_L); 1079 expr = function(cmd, para, true); 1080 break; 1081 case SQLTokenizer.CALL: throw new java.lang.UnsupportedOperationException ("call escape sequence"); 1083 default: throw new Error (); 1084 } 1085 token = nextToken( ESCAPE_MISSING_CLOSE ); 1086 return expr; 1087 } 1088 case SQLTokenizer.QUESTION: 1089 ExpressionValue param = new ExpressionValue(); 1090 cmd.addParameter( param ); 1091 return param; 1092 case SQLTokenizer.CASE: 1093 return caseExpr(cmd); 1094 case SQLTokenizer.MINUS: 1095 case SQLTokenizer.PLUS: 1096 do{ 1098 if(token.value == SQLTokenizer.MINUS) 1099 isMinus = !isMinus; 1100 token = nextToken(); 1101 if(token == null) throw createSyntaxError( token, MISSING_EXPRESSION ); 1102 }while(token.value == SQLTokenizer.MINUS || token.value == SQLTokenizer.PLUS); 1103 default: 1105 SQLToken token2 = nextToken(); 1106 if(token2 != null && token2.value == SQLTokenizer.PARENTHESIS_L){ 1107 if(isMinus) 1108 return new ExpressionArithmetic( function( cmd, token, false ), ExpressionArithmetic.NEGATIVE ); 1109 return function( cmd, token, false ); 1110 }else{ 1111 char chr1 = sql[ token.offset ]; 1113 if(chr1 == '$'){ 1114 previousToken(); 1115 String tok = new String (sql, token.offset+1, token.length-1); 1116 if(isMinus) tok = "-" + tok; 1117 return new ExpressionValue( new Money(Double.parseDouble(tok)), SQLTokenizer.MONEY ); 1118 } 1119 String tok = new String (sql, token.offset, token.length); 1120 if((chr1 >= '0' && '9' >= chr1) || chr1 == '.'){ 1121 previousToken(); 1122 if(token.length>1 && (sql[ token.offset +1 ] | 0x20) == 'x'){ 1124 if(isMinus) throw createSyntaxError( token, "Invalid operator binary for data type varbinary."); 1126 return new ExpressionValue( Utils.hex2bytes( sql, token.offset+2, token.length-2), SQLTokenizer.BINARY ); 1127 } 1128 if(isMinus) tok = "-" + tok; 1129 if(Utils.indexOf( '.', sql, token.offset, token.length ) >= 0 || 1130 Utils.indexOf( 'e', sql, token.offset, token.length ) >= 0){ 1131 return new ExpressionValue( new Double (tok), SQLTokenizer.DOUBLE ); 1132 }else{ 1133 try{ 1134 return new ExpressionValue( new Integer (tok), SQLTokenizer.INT ); 1135 }catch(NumberFormatException e){ 1136 return new ExpressionValue( new Long (tok), SQLTokenizer.BIGINT ); 1137 } 1138 } 1139 }else{ 1140 checkValidIdentifer( tok, token ); 1142 ExpressionName expr = new ExpressionName(tok); 1143 if(token2 != null && token2.value == SQLTokenizer.POINT){ 1144 token = nextToken(MISSING_EXPRESSION); 1145 expr.setNameAfterTableAlias( token.getName( sql ) ); 1146 }else{ 1147 previousToken(); 1148 } 1149 if(isMinus) 1150 return new ExpressionArithmetic( expr, ExpressionArithmetic.NEGATIVE ); 1151 return expr; 1152 } 1153 } 1154 } 1155 } 1156 return null; 1157 } 1158 1159 1160 ExpressionFunctionCase caseExpr(final Command cmd) throws SQLException{ 1161 ExpressionFunctionCase expr = new ExpressionFunctionCase(); 1162 SQLToken token = nextToken(MISSING_EXPRESSION); 1163 1164 Expression input = null; 1165 if(token.value != SQLTokenizer.WHEN){ 1166 previousToken(); 1168 input = expression(cmd, 0); 1169 token = nextToken(MISSING_WHEN_ELSE_END); 1170 } 1171 1172 while(true){ 1173 switch(token.value){ 1174 case SQLTokenizer.WHEN: 1175 Expression condition = expression(cmd, 0); 1176 if(input != null){ 1177 condition = new ExpressionArithmetic( input, condition, ExpressionArithmetic.EQUALS); 1179 } 1180 nextToken(MISSING_THEN); 1181 Expression result = expression(cmd, 0); 1182 expr.addCase(condition, result); 1183 break; 1184 case SQLTokenizer.ELSE: 1185 expr.setElseResult(expression(cmd, 0)); 1186 break; 1187 case SQLTokenizer.END: 1188 expr.setEnd(); 1189 return expr; 1190 default: 1191 throw new Error (); 1192 } 1193 token = nextToken(MISSING_WHEN_ELSE_END); 1194 } 1195 } 1196 1197 1198 1203 private Expression function( Command cmd, SQLToken token, boolean isEscape ) throws SQLException{ 1204 Expression expr; 1205 switch(token.value){ 1206 case SQLTokenizer.CONVERT:{ 1207 Column col; 1208 Expression style = null; 1209 if(isEscape){ 1210 expr = expression( cmd, 0); 1211 nextToken(MISSING_COMMA); 1212 col = datatype(isEscape); 1213 }else{ 1214 col = datatype(isEscape); 1215 nextToken(MISSING_COMMA); 1216 expr = expression( cmd, 0); 1217 token = nextToken(MISSING_COMMA_PARENTHESIS); 1218 if(token.value == SQLTokenizer.COMMA){ 1219 style = expression( cmd, 0); 1220 }else 1221 previousToken(); 1222 } 1223 nextToken(MISSING_PARENTHESIS_R); 1224 return new ExpressionFunctionConvert( col, expr, style ); 1225 } 1226 case SQLTokenizer.CAST: 1227 expr = expression( cmd, 0); 1228 nextToken(MISSING_AS); 1229 Column col = datatype(false); 1230 nextToken(MISSING_PARENTHESIS_R); 1231 return new ExpressionFunctionConvert( col, expr, null ); 1232 case SQLTokenizer.TIMESTAMPDIFF: 1233 token = nextToken(MISSING_INTERVALS); 1234 nextToken(MISSING_COMMA); 1235 expr = expression( cmd, 0); 1236 nextToken(MISSING_COMMA); 1237 expr = new ExpressionFunctionTimestampDiff( token.value, expr, expression( cmd, 0)); 1238 nextToken(MISSING_PARENTHESIS_R); 1239 return expr; 1240 case SQLTokenizer.TIMESTAMPADD: 1241 token = nextToken(MISSING_INTERVALS); 1242 nextToken(MISSING_COMMA); 1243 expr = expression( cmd, 0); 1244 nextToken(MISSING_COMMA); 1245 expr = new ExpressionFunctionTimestampAdd( token.value, expr, expression( cmd, 0)); 1246 nextToken(MISSING_PARENTHESIS_R); 1247 return expr; 1248 } 1249 Expressions paramList = expressionParenthesisList(cmd); 1250 int paramCount = paramList.size(); 1251 Expression[] params = paramList.toArray(); 1252 boolean invalidParamCount; 1253 switch(token.value){ 1254 case SQLTokenizer.ABS: 1256 invalidParamCount = (paramCount != 1); 1257 expr = new ExpressionFunctionAbs(); 1258 break; 1259 case SQLTokenizer.ACOS: 1260 invalidParamCount = (paramCount != 1); 1261 expr = new ExpressionFunctionACos(); 1262 break; 1263 case SQLTokenizer.ASIN: 1264 invalidParamCount = (paramCount != 1); 1265 expr = new ExpressionFunctionASin(); 1266 break; 1267 case SQLTokenizer.ATAN: 1268 invalidParamCount = (paramCount != 1); 1269 expr = new ExpressionFunctionATan(); 1270 break; 1271 case SQLTokenizer.ATAN2: 1272 invalidParamCount = (paramCount != 2); 1273 expr = new ExpressionFunctionATan2(); 1274 break; 1275 case SQLTokenizer.CEILING: 1276 invalidParamCount = (paramCount != 1); 1277 expr = new ExpressionFunctionCeiling(); 1278 break; 1279 case SQLTokenizer.COS: 1280 invalidParamCount = (paramCount != 1); 1281 expr = new ExpressionFunctionCos(); 1282 break; 1283 case SQLTokenizer.COT: 1284 invalidParamCount = (paramCount != 1); 1285 expr = new ExpressionFunctionCot(); 1286 break; 1287 case SQLTokenizer.DEGREES: 1288 invalidParamCount = (paramCount != 1); 1289 expr = new ExpressionFunctionDegrees(); 1290 break; 1291 case SQLTokenizer.EXP: 1292 invalidParamCount = (paramCount != 1); 1293 expr = new ExpressionFunctionExp(); 1294 break; 1295 case SQLTokenizer.FLOOR: 1296 invalidParamCount = (paramCount != 1); 1297 expr = new ExpressionFunctionFloor(); 1298 break; 1299 case SQLTokenizer.LOG: 1300 invalidParamCount = (paramCount != 1); 1301 expr = new ExpressionFunctionLog(); 1302 break; 1303 case SQLTokenizer.LOG10: 1304 invalidParamCount = (paramCount != 1); 1305 expr = new ExpressionFunctionLog10(); 1306 break; 1307 case SQLTokenizer.MOD: 1308 invalidParamCount = (paramCount != 2); 1309 expr = new ExpressionFunctionMod(); 1310 break; 1311 case SQLTokenizer.PI: 1312 invalidParamCount = (paramCount != 0); 1313 expr = new ExpressionFunctionPI(); 1314 break; 1315 case SQLTokenizer.POWER: 1316 invalidParamCount = (paramCount != 2); 1317 expr = new ExpressionFunctionPower(); 1318 break; 1319 case SQLTokenizer.RADIANS: 1320 invalidParamCount = (paramCount != 1); 1321 expr = new ExpressionFunctionRadians(); 1322 break; 1323 case SQLTokenizer.RAND: 1324 invalidParamCount = (paramCount != 0) && (paramCount != 1); 1325 expr = new ExpressionFunctionRand(); 1326 break; 1327 case SQLTokenizer.ROUND: 1328 invalidParamCount = (paramCount != 2); 1329 expr = new ExpressionFunctionRound(); 1330 break; 1331 case SQLTokenizer.SIN: 1332 invalidParamCount = (paramCount != 1); 1333 expr = new ExpressionFunctionSin(); 1334 break; 1335 case SQLTokenizer.SIGN: 1336 invalidParamCount = (paramCount != 1); 1337 expr = new ExpressionFunctionSign(); 1338 break; 1339 case SQLTokenizer.SQRT: 1340 invalidParamCount = (paramCount != 1); 1341 expr = new ExpressionFunctionSqrt(); 1342 break; 1343 case SQLTokenizer.TAN: 1344 invalidParamCount = (paramCount != 1); 1345 expr = new ExpressionFunctionTan(); 1346 break; 1347 case SQLTokenizer.TRUNCATE: 1348 invalidParamCount = (paramCount != 2); 1349 expr = new ExpressionFunctionTruncate(); 1350 break; 1351 1352 case SQLTokenizer.ASCII: 1354 invalidParamCount = (paramCount != 1); 1355 expr = new ExpressionFunctionAscii(); 1356 break; 1357 case SQLTokenizer.CHAR: 1358 invalidParamCount = (paramCount != 1); 1359 expr = new ExpressionFunctionChar(); 1360 break; 1361 case SQLTokenizer.CONCAT: 1362 if(paramCount != 2){ 1363 invalidParamCount = true; 1364 expr = null; break; 1366 } 1367 invalidParamCount = false; 1368 expr = new ExpressionArithmetic( params[0], params[1], ExpressionArithmetic.ADD); 1369 break; 1370 case SQLTokenizer.DIFFERENCE: 1371 invalidParamCount = (paramCount != 2); 1372 expr = new ExpressionFunctionDifference(); 1373 break; 1374 case SQLTokenizer.INSERT: 1375 invalidParamCount = (paramCount != 4); 1376 expr = new ExpressionFunctionInsert(); 1377 break; 1378 case SQLTokenizer.LCASE: 1379 invalidParamCount = (paramCount != 1); 1380 expr = new ExpressionFunctionLCase(); 1381 break; 1382 case SQLTokenizer.LEFT: 1383 invalidParamCount = (paramCount != 2); 1384 expr = new ExpressionFunctionLeft(); 1385 break; 1386 case SQLTokenizer.LENGTH: 1387 invalidParamCount = (paramCount != 1); 1388 expr = new ExpressionFunctionLength(); 1389 break; 1390 case SQLTokenizer.LOCATE: 1391 invalidParamCount = (paramCount != 2) && (paramCount != 3); 1392 expr = new ExpressionFunctionLocate(); 1393 break; 1394 case SQLTokenizer.LTRIM: 1395 invalidParamCount = (paramCount != 1); 1396 expr = new ExpressionFunctionLTrim(); 1397 break; 1398 case SQLTokenizer.REPEAT: 1399 invalidParamCount = (paramCount != 2); 1400 expr = new ExpressionFunctionRepeat(); 1401 break; 1402 case SQLTokenizer.REPLACE: 1403 invalidParamCount = (paramCount != 3); 1404 expr = new ExpressionFunctionReplace(); 1405 break; 1406 case SQLTokenizer.RIGHT: 1407 invalidParamCount = (paramCount != 2); 1408 expr = new ExpressionFunctionRight(); 1409 break; 1410 case SQLTokenizer.RTRIM: 1411 invalidParamCount = (paramCount != 1); 1412 expr = new ExpressionFunctionRTrim(); 1413 break; 1414 case SQLTokenizer.SPACE: 1415 invalidParamCount = (paramCount != 1); 1416 expr = new ExpressionFunctionSpace(); 1417 break; 1418 case SQLTokenizer.SOUNDEX: 1419 invalidParamCount = (paramCount != 1); 1420 expr = new ExpressionFunctionSoundex(); 1421 break; 1422 case SQLTokenizer.SUBSTRING: 1423 invalidParamCount = (paramCount != 3); 1424 expr = new ExpressionFunctionSubstring(); 1425 break; 1426 case SQLTokenizer.UCASE: 1427 invalidParamCount = (paramCount != 1); 1428 expr = new ExpressionFunctionUCase(); 1429 break; 1430 1431 case SQLTokenizer.CURDATE: 1433 invalidParamCount = (paramCount != 0); 1434 expr = new ExpressionValue( new DateTime(DateTime.now(), SQLTokenizer.DATE), SQLTokenizer.DATE); 1435 break; 1436 case SQLTokenizer.CURTIME: 1437 invalidParamCount = (paramCount != 0); 1438 expr = new ExpressionValue( new DateTime(DateTime.now(), SQLTokenizer.TIME), SQLTokenizer.TIME); 1439 break; 1440 case SQLTokenizer.DAYOFMONTH: 1441 invalidParamCount = (paramCount != 1); 1442 expr = new ExpressionFunctionDayOfMonth(); 1443 break; 1444 case SQLTokenizer.DAYOFWEEK: 1445 invalidParamCount = (paramCount != 1); 1446 expr = new ExpressionFunctionDayOfWeek(); 1447 break; 1448 case SQLTokenizer.DAYOFYEAR: 1449 invalidParamCount = (paramCount != 1); 1450 expr = new ExpressionFunctionDayOfYear(); 1451 break; 1452 case SQLTokenizer.HOUR: 1453 invalidParamCount = (paramCount != 1); 1454 expr = new ExpressionFunctionHour(); 1455 break; 1456 case SQLTokenizer.MINUTE: 1457 invalidParamCount = (paramCount != 1); 1458 expr = new ExpressionFunctionMinute(); 1459 break; 1460 case SQLTokenizer.MONTH: 1461 invalidParamCount = (paramCount != 1); 1462 expr = new ExpressionFunctionMonth(); 1463 break; 1464 case SQLTokenizer.NOW: 1465 invalidParamCount = (paramCount != 0); 1466 expr = new ExpressionValue( new DateTime(DateTime.now(), SQLTokenizer.TIMESTAMP), SQLTokenizer.TIMESTAMP); 1467 break; 1468 1469 case SQLTokenizer.IIF: 1471 invalidParamCount = (paramCount != 3); 1472 expr = new ExpressionFunctionIIF(); 1473 break; 1474 case SQLTokenizer.SWITCH: 1475 invalidParamCount = (paramCount % 2 != 0); 1476 ExpressionFunctionCase exprCase = new ExpressionFunctionCase(); 1477 for(int i=0; i < paramCount-1; i +=2) 1478 exprCase.addCase(params[i], params[i+1] ); 1479 exprCase.setEnd(); 1480 expr = exprCase; 1481 break; 1482 case SQLTokenizer.IFNULL: 1483 switch(paramCount){ 1484 case 1: 1485 return new ExpressionArithmetic( params[0], ExpressionArithmetic.ISNULL ); 1486 case 2: 1487 invalidParamCount = false; 1488 expr = new ExpressionFunctionIIF(); 1489 Expression[] newParams = new Expression[3]; 1490 newParams[0] = new ExpressionArithmetic( params[0], ExpressionArithmetic.ISNULL ); 1491 newParams[1] = params[1]; 1492 newParams[2] = params[0]; 1493 params = newParams; 1494 paramCount = 3; 1495 break; 1496 default: 1497 invalidParamCount = true; 1498 expr = null; } 1500 break; 1501 1502 case SQLTokenizer.COUNT: 1504 invalidParamCount = (paramCount != 1); 1505 if(params[0].getType() == Expression.NAME){ 1506 ExpressionName param = (ExpressionName)params[0]; 1508 if("*".equals(param.getName()) && param.getTableAlias() == null){ 1509 params[0] = new ExpressionValue(); 1510 } 1511 } 1512 expr = new ExpressionName( Expression.COUNT ); 1513 break; 1514 case SQLTokenizer.SUM: 1515 invalidParamCount = (paramCount != 1); 1516 expr = new ExpressionName( Expression.SUM ); 1517 break; 1518 case SQLTokenizer.MAX: 1519 invalidParamCount = (paramCount != 1); 1520 expr = new ExpressionName( Expression.MAX ); 1521 break; 1522 case SQLTokenizer.MIN: 1523 invalidParamCount = (paramCount != 1); 1524 expr = new ExpressionName( Expression.MIN ); 1525 break; 1526 case SQLTokenizer.FIRST: 1527 invalidParamCount = (paramCount != 1); 1528 expr = new ExpressionName( Expression.FIRST ); 1529 break; 1530 case SQLTokenizer.LAST: 1531 invalidParamCount = (paramCount != 1); 1532 expr = new ExpressionName( Expression.LAST ); 1533 break; 1534 case SQLTokenizer.AVG: 1535 if(paramCount != 1){ 1536 invalidParamCount = true; 1537 expr = null; break; 1539 } 1540 expr = new ExpressionName( Expression.SUM ); 1541 expr.setParams( params ); 1542 Expression expr2 = new ExpressionName( Expression.COUNT ); 1543 expr2.setParams( params ); 1544 expr = new ExpressionArithmetic( expr, expr2, ExpressionArithmetic.DIV ); 1545 return expr; 1546 default: throw createSyntaxError(token, "Unknown function."); 1547 } 1548 if(invalidParamCount) throw createSyntaxError( token, "Invalid parameter count." ); 1549 expr.setParams( params ); 1550 return expr; 1551 } 1552 1553 1556 private RowSource tableSource( Command cmd, DataSources tables) throws SQLException{ 1557 SQLToken token = nextToken(MISSING_EXPRESSION); 1558 switch(token.value){ 1559 case SQLTokenizer.PARENTHESIS_L: return rowSource( cmd, tables, SQLTokenizer.PARENTHESIS_R ); 1561 case SQLTokenizer.ESCAPE_L: token = nextToken(MISSING_OJ); 1563 return rowSource( cmd, tables, SQLTokenizer.ESCAPE_R ); 1564 case SQLTokenizer.SELECT: 1565 ViewResult viewResult = new ViewResult( con, select() ); 1567 tables.add(viewResult); 1568 return viewResult; 1569 } 1570 String catalog = null; 1571 String name = token.getName( sql ); 1572 checkValidIdentifer( name, token ); 1573 token = nextToken(); 1574 if(token != null && token.value == SQLTokenizer.POINT){ 1576 token = nextToken(MISSING_EXPRESSION); 1577 catalog = name; 1578 name = token.getName( sql ); 1579 checkValidIdentifer( name, token ); 1580 token = nextToken(); 1581 } 1582 TableView tableView = Database.getTableView( con, catalog, name); 1585 TableViewResult table = TableViewResult.createResult(tableView); 1586 tables.add( table ); 1587 1588 if(token != null && token.value == SQLTokenizer.AS){ 1589 token = nextToken(MISSING_EXPRESSION); 1591 table.setAlias( token.getName( sql ) ); 1592 }else{ 1593 previousToken(); 1594 } 1595 return table; 1596 } 1597 1598 1601 private Join join(Command cmd, DataSources tables, RowSource left, int type) throws SQLException{ 1602 RowSource right = rowSource(cmd, tables, 0); 1603 SQLToken token = nextToken(); 1604 1605 while(true){ 1606 if(token == null) throw createSyntaxError(null, "Invalid Join Syntax"); 1607 1608 switch(token.value){ 1609 case SQLTokenizer.ON: 1610 if(type == Join.RIGHT_JOIN) 1611 return new Join( Join.LEFT_JOIN, right, left, expression( cmd, 0 ) ); 1612 return new Join( type, left, right, expression( cmd, 0 ) ); 1613 default: 1614 if(!right.hasAlias()){ 1615 right.setAlias( token.getName( sql ) ); 1616 token = nextToken(); 1617 continue; 1618 } 1619 throw createSyntaxError( token, new int[]{SQLTokenizer.ON} ); 1620 } 1621 } 1622 } 1623 1624 1628 private RowSource rowSource(Command cmd, DataSources tables, int parenthesis) throws SQLException{ 1629 RowSource fromSource = null; 1630 fromSource = tableSource(cmd, tables); 1631 1632 while(true){ 1633 SQLToken token = nextToken(); 1634 if(token == null) return fromSource; 1635 switch(token.value){ 1636 case SQLTokenizer.ON: 1637 previousToken(); 1638 return fromSource; 1639 case SQLTokenizer.CROSS: 1640 nextToken(MISSING_JOIN); 1641 case SQLTokenizer.COMMA: 1643 fromSource = new Join( Join.CROSS_JOIN, fromSource, tableSource(cmd, tables), null); 1644 break; 1645 case SQLTokenizer.INNER: 1646 nextToken(MISSING_JOIN); 1647 fromSource = join( cmd, tables, fromSource, Join.INNER_JOIN ); 1648 break; 1649 case SQLTokenizer.LEFT: 1650 token = nextToken(MISSING_OUTER_JOIN); 1651 if(token.value == SQLTokenizer.OUTER) 1652 token = nextToken(MISSING_JOIN); 1653 fromSource = join( cmd, tables, fromSource, Join.LEFT_JOIN ); 1654 break; 1655 case SQLTokenizer.RIGHT: 1656 token = nextToken(MISSING_OUTER_JOIN); 1657 if(token.value == SQLTokenizer.OUTER) 1658 token = nextToken(MISSING_JOIN); 1659 fromSource = join( cmd, tables, fromSource, Join.RIGHT_JOIN ); 1660 break; 1661 case SQLTokenizer.FULL: 1662 token = nextToken(MISSING_OUTER_JOIN); 1663 if(token.value == SQLTokenizer.OUTER) 1664 token = nextToken(MISSING_JOIN); 1665 fromSource = join( cmd, tables, fromSource, Join.FULL_JOIN ); 1666 break; 1667 case SQLTokenizer.PARENTHESIS_R: 1668 case SQLTokenizer.ESCAPE_R: 1669 if(parenthesis == token.value) return fromSource; 1670 if(parenthesis == 0){ 1671 previousToken(); 1672 return fromSource; 1673 } 1674 throw createSyntaxError( token, "Unexpexted closing parethesis in from clause." ); 1675 default: 1676 if(isKeyword(token)){ 1677 previousToken(); 1678 return fromSource; 1679 } 1680 if(!fromSource.hasAlias()){ 1681 fromSource.setAlias( token.getName( sql ) ); 1682 break; 1683 } 1684 throw createSyntaxError( token, new int[]{SQLTokenizer.COMMA, SQLTokenizer.GROUP, SQLTokenizer.ORDER, SQLTokenizer.HAVING} ); 1685 } 1686 } 1687 } 1688 1689 private void from(CommandSelect cmd) throws SQLException{ 1690 DataSources tables = new DataSources(); 1691 cmd.setFrom(tables); 1692 cmd.setSource( rowSource( cmd, tables, 0 ) ); 1693 1694 SQLToken token; 1695 while(null != (token = nextToken())){ 1696 switch(token.value){ 1697 case SQLTokenizer.WHERE: 1698 where( cmd ); 1699 break; 1700 case SQLTokenizer.GROUP: 1701 group( cmd ); 1702 break; 1703 case SQLTokenizer.HAVING: 1704 having( cmd ); 1705 break; 1706 default: 1707 previousToken(); 1708 return; 1709 } 1710 } 1711 } 1712 1713 private void order(CommandSelect cmd) throws SQLException{ 1714 nextToken(MISSING_BY); 1715 cmd.setOrder( expressionTokenList(cmd, SQLTokenizer.ORDER) ); 1716 } 1717 1718 private void group(CommandSelect cmd) throws SQLException{ 1719 nextToken(MISSING_BY); 1720 cmd.setGroup( expressionTokenList(cmd, SQLTokenizer.GROUP) ); 1721 } 1722 1723 private void where(CommandSelect cmd) throws SQLException{ 1724 cmd.setWhere( expression(cmd, 0) ); 1725 } 1726 1727 private void having(CommandSelect cmd) throws SQLException{ 1728 cmd.setHaving( expression(cmd, 0) ); 1729 } 1730 1731 1732 private static final int[] COMMANDS = {SQLTokenizer.SELECT, SQLTokenizer.DELETE, SQLTokenizer.INSERT, SQLTokenizer.UPDATE, SQLTokenizer.CREATE, SQLTokenizer.DROP, SQLTokenizer.ALTER, SQLTokenizer.SET, SQLTokenizer.USE, SQLTokenizer.EXECUTE, SQLTokenizer.TRUNCATE}; 1733 private static final int[] COMMANDS_ESCAPE = {SQLTokenizer.D, SQLTokenizer.T, SQLTokenizer.TS, SQLTokenizer.FN, SQLTokenizer.CALL}; 1734 private static final int[] COMMANDS_CREATE = {SQLTokenizer.DATABASE, SQLTokenizer.TABLE, SQLTokenizer.VIEW, SQLTokenizer.INDEX, SQLTokenizer.PROCEDURE}; 1735 private static final int[] COMMANDS_SET = {SQLTokenizer.TRANSACTION}; 1736 private static final int[] MISSING_TABLE = {SQLTokenizer.TABLE}; 1737 private static final int[] ESCAPE_MISSING_CLOSE = {SQLTokenizer.ESCAPE_R}; 1738 private static final int[] MISSING_EXPRESSION = {SQLTokenizer.VALUE}; 1739 private static final int[] MISSING_IDENTIFER = {SQLTokenizer.IDENTIFER}; 1740 private static final int[] MISSING_BY = {SQLTokenizer.BY}; 1741 private static final int[] MISSING_PARENTHESIS_L = {SQLTokenizer.PARENTHESIS_L}; 1742 private static final int[] MISSING_PARENTHESIS_R = {SQLTokenizer.PARENTHESIS_R}; 1743 private static final int[] MISSING_DATATYPE = {SQLTokenizer.BIT, SQLTokenizer.BOOLEAN, SQLTokenizer.BINARY, SQLTokenizer.VARBINARY, SQLTokenizer.RAW, SQLTokenizer.LONGVARBINARY, SQLTokenizer.BLOB, SQLTokenizer.TINYINT, SQLTokenizer.SMALLINT, SQLTokenizer.INT, SQLTokenizer.COUNTER, SQLTokenizer. BIGINT, SQLTokenizer.SMALLMONEY, SQLTokenizer.MONEY, SQLTokenizer.DECIMAL, SQLTokenizer.NUMERIC, SQLTokenizer.REAL, SQLTokenizer.FLOAT, SQLTokenizer.DOUBLE, SQLTokenizer.DATE, SQLTokenizer.TIME, SQLTokenizer.TIMESTAMP, SQLTokenizer.SMALLDATETIME, SQLTokenizer.CHAR, SQLTokenizer.NCHAR, SQLTokenizer.VARCHAR, SQLTokenizer.NVARCHAR, SQLTokenizer.LONG, SQLTokenizer.LONGNVARCHAR, SQLTokenizer.LONGVARCHAR, SQLTokenizer.CLOB, SQLTokenizer.NCLOB, SQLTokenizer.UNIQUEIDENTIFIER, SQLTokenizer.JAVA_OBJECT, SQLTokenizer.SYSNAME}; 1744 private static final int[] MISSING_SQL_DATATYPE = { SQLTokenizer.SQL_BIGINT , SQLTokenizer.SQL_BINARY , SQLTokenizer.SQL_BIT , SQLTokenizer.SQL_CHAR , SQLTokenizer.SQL_DATE , SQLTokenizer.SQL_DECIMAL , SQLTokenizer.SQL_DOUBLE , SQLTokenizer.SQL_FLOAT , SQLTokenizer.SQL_INTEGER , SQLTokenizer.SQL_LONGVARBINARY , SQLTokenizer.SQL_LONGVARCHAR , SQLTokenizer.SQL_REAL , SQLTokenizer.SQL_SMALLINT , SQLTokenizer.SQL_TIME , SQLTokenizer.SQL_TIMESTAMP , SQLTokenizer.SQL_TINYINT , SQLTokenizer.SQL_VARBINARY , SQLTokenizer.SQL_VARCHAR }; 1745 private static final int[] MISSING_INTO = {SQLTokenizer.INTO}; 1746 private static final int[] MISSING_BETWEEN_IN = {SQLTokenizer.BETWEEN, SQLTokenizer.IN}; 1747 private static final int[] MISSING_NOT_NULL = {SQLTokenizer.NOT, SQLTokenizer.NULL}; 1748 private static final int[] MISSING_NULL = {SQLTokenizer.NULL}; 1749 private static final int[] MISSING_COMMA = {SQLTokenizer.COMMA}; 1750 private static final int[] MISSING_COMMA_PARENTHESIS = {SQLTokenizer.COMMA, SQLTokenizer.PARENTHESIS_R}; 1751 private static final int[] MISSING_PARENTHESIS_VALUES_SELECT = {SQLTokenizer.PARENTHESIS_L, SQLTokenizer.VALUES, SQLTokenizer.SELECT}; 1752 private static final int[] MISSING_TOKEN_LIST = {SQLTokenizer.COMMA, SQLTokenizer.FROM, SQLTokenizer.GROUP, SQLTokenizer.HAVING, SQLTokenizer.ORDER}; 1753 private static final int[] MISSING_FROM = {SQLTokenizer.FROM}; 1754 private static final int[] MISSING_SET = {SQLTokenizer.SET}; 1755 private static final int[] MISSING_EQUALS = {SQLTokenizer.EQUALS}; 1756 private static final int[] MISSING_WHERE = {SQLTokenizer.WHERE}; 1757 private static final int[] MISSING_WHERE_COMMA = {SQLTokenizer.WHERE, SQLTokenizer.COMMA}; 1758 private static final int[] MISSING_ISOLATION = {SQLTokenizer.ISOLATION}; 1759 private static final int[] MISSING_LEVEL = {SQLTokenizer.LEVEL}; 1760 private static final int[] COMMANDS_TRANS_LEVEL = {SQLTokenizer.READ, SQLTokenizer.REPEATABLE, SQLTokenizer.SERIALIZABLE}; 1761 private static final int[] MISSING_READ = {SQLTokenizer.READ}; 1762 private static final int[] MISSING_COMM_UNCOMM = {SQLTokenizer.COMMITTED, SQLTokenizer.UNCOMMITTED}; 1763 private static final int[] MISSING_OPTIONS_DATATYPE = { SQLTokenizer.DEFAULT, SQLTokenizer.IDENTITY, SQLTokenizer.NOT, SQLTokenizer.NULL, SQLTokenizer.PRIMARY, SQLTokenizer.UNIQUE, SQLTokenizer.COMMA, SQLTokenizer.PARENTHESIS_R, SQLTokenizer.PARENTHESIS_L}; 1764 private static final int[] MISSING_NUMBERVALUE = {SQLTokenizer.NUMBERVALUE}; 1765 private static final int[] MISSING_AND = {SQLTokenizer.AND}; 1766 private static final int[] MISSING_JOIN = {SQLTokenizer.JOIN}; 1767 private static final int[] MISSING_OUTER_JOIN = {SQLTokenizer.OUTER, SQLTokenizer.JOIN}; 1768 private static final int[] MISSING_OJ = {SQLTokenizer.OJ}; 1769 private static final int[] MISSING_KEYTYPE = {SQLTokenizer.PRIMARY, SQLTokenizer.UNIQUE, SQLTokenizer.FOREIGN}; 1770 private static final int[] MISSING_KEY = {SQLTokenizer.KEY}; 1771 private static final int[] MISSING_REFERENCES = {SQLTokenizer.REFERENCES}; 1772 private static final int[] MISSING_AS = {SQLTokenizer.AS}; 1773 private static final int[] MISSING_SELECT = {SQLTokenizer.SELECT}; 1774 private static final int[] MISSING_INTERVALS = {SQLTokenizer.SQL_TSI_FRAC_SECOND, SQLTokenizer.SQL_TSI_SECOND, SQLTokenizer.SQL_TSI_MINUTE, SQLTokenizer.SQL_TSI_HOUR, SQLTokenizer.SQL_TSI_DAY, SQLTokenizer.SQL_TSI_WEEK, SQLTokenizer.SQL_TSI_MONTH, SQLTokenizer.SQL_TSI_QUARTER, SQLTokenizer.SQL_TSI_YEAR, SQLTokenizer.MILLISECOND, SQLTokenizer.SECOND, SQLTokenizer.MINUTE, SQLTokenizer.HOUR, SQLTokenizer.DAY, SQLTokenizer.WEEK, SQLTokenizer.MONTH, SQLTokenizer.QUARTER, SQLTokenizer.YEAR, SQLTokenizer.D}; 1775 private static final int[] MISSING_ALL = {SQLTokenizer.ALL}; 1776 private static final int[] MISSING_THEN = {SQLTokenizer.THEN}; 1777 private static final int[] MISSING_WHEN_ELSE_END = {SQLTokenizer.WHEN, SQLTokenizer.ELSE, SQLTokenizer.END}; 1778 1779 1780} | Popular Tags |