1 65 66 67 package org.hsqldb; 68 69 import java.util.Locale ; 70 71 import org.hsqldb.HsqlNameManager.HsqlName; 72 import org.hsqldb.lib.ArrayUtil; 73 import org.hsqldb.lib.HashMap; 74 import org.hsqldb.lib.HashMappedList; 75 import org.hsqldb.lib.HsqlArrayList; 76 import org.hsqldb.lib.IntValueHashMap; 77 import org.hsqldb.store.ValuePool; 78 import org.hsqldb.lib.HashSet; 79 80 113 114 123 class Parser { 124 125 private Database database; 126 private Tokenizer tokenizer; 127 private Session session; 128 private String sSchema; 129 private String sTable; 130 private String sToken; 131 private boolean wasQuoted; 132 private Object oData; 133 private int iType; 134 private int iToken; 135 136 private int subQueryLevel; 138 private HsqlArrayList subQueryList = new HsqlArrayList(); 139 140 148 Parser(Session session, Database db, Tokenizer t) { 149 150 database = db; 151 tokenizer = t; 152 this.session = session; 153 } 154 155 163 void reset(String sql) { 164 165 sTable = null; 166 sToken = null; 167 oData = null; 168 169 tokenizer.reset(sql); 170 subQueryList.clear(); 171 172 subQueryLevel = 0; 173 174 parameters.clear(); 175 } 176 177 187 void checkTableWriteAccess(Table table, 188 int userRight) throws HsqlException { 189 190 session.checkReadWrite(); 192 193 session.check(table.getName(), userRight); 195 196 if (table.isView()) { 198 throw Trace.error(Trace.NOT_A_TABLE, table.getName().name); 199 } 200 201 table.checkDataReadOnly(); 203 } 204 205 215 static HsqlArrayList getColumnNames(Database db, Table table, 216 Tokenizer t, 217 boolean full) throws HsqlException { 218 219 HsqlArrayList columns = new HsqlArrayList(); 220 221 while (true) { 222 if (full) { 223 String token = t.getSimpleName(); 224 boolean quoted = t.wasQuotedIdentifier(); 225 HsqlName name = db.nameManager.newHsqlName(token, quoted); 226 227 columns.add(name); 228 } else { 229 columns.add(t.getName()); 230 231 if (t.wasLongName() 232 &&!t.getLongNameFirst().equals( 233 table.getName().name)) { 234 throw (Trace.error(Trace.TABLE_NOT_FOUND, 235 t.getLongNameFirst())); 236 } 237 } 238 239 String token = t.getSimpleToken(); 240 241 if (token.equals(Token.T_COMMA)) { 242 continue; 243 } 244 245 if (token.equals(Token.T_CLOSEBRACKET)) { 246 break; 247 } 248 249 t.throwUnexpected(); 250 } 251 252 return columns; 253 } 254 255 262 SubQuery parseSubquery(int brackets, HsqlName[] colNames, 263 boolean resolveAll, 264 int predicateType) throws HsqlException { 265 266 SubQuery sq; 267 268 sq = new SubQuery(); 269 270 subQueryLevel++; 271 272 boolean canHaveOrder = predicateType == Expression.VIEW; 273 boolean limitWithOrder = predicateType == Expression.VIEW 274 || predicateType == Expression.QUERY 275 || predicateType == Expression.IN 276 || predicateType == Expression.ALL 277 || predicateType == Expression.ANY 278 || predicateType == Expression.SELECT; 279 Select s = parseSelect(brackets, canHaveOrder, false, limitWithOrder, 280 true); 281 282 sq.level = subQueryLevel; 283 284 subQueryLevel--; 285 286 boolean isResolved = s.resolveAll(session, resolveAll); 287 288 sq.select = s; 289 sq.isResolved = isResolved; 290 291 HsqlName sqtablename = 293 database.nameManager.newHsqlName("SYSTEM_SUBQUERY", false); 294 295 sqtablename.schema = database.schemaManager.SYSTEM_SCHEMA_HSQLNAME; 296 297 Table table = new Table(database, sqtablename, Table.SYSTEM_SUBQUERY); 298 299 if (colNames != null) { 300 if (colNames.length != s.iResultLen) { 301 throw Trace.error(Trace.COLUMN_COUNT_DOES_NOT_MATCH); 302 } 303 304 for (int i = 0; i < s.iResultLen; i++) { 305 HsqlName name = colNames[i]; 306 307 s.exprColumns[i].setAlias(name.name, name.isNameQuoted); 308 } 309 } else { 310 for (int i = 0; i < s.iResultLen; i++) { 311 String colname = s.exprColumns[i].getAlias(); 312 313 if (colname == null || colname.length() == 0) { 314 315 colname = "COL_" + String.valueOf(i + 1); 318 319 s.exprColumns[i].setAlias(colname, false); 320 } 321 } 322 } 323 324 table.addColumns(s); 325 326 boolean uniqueValues = predicateType == Expression.EXISTS 327 || predicateType == Expression.IN 328 || predicateType == Expression.ALL 329 || predicateType == Expression.ANY; 330 int[] pcol = null; 331 332 if (uniqueValues) { 333 pcol = new int[s.iResultLen]; 334 335 ArrayUtil.fillSequence(pcol); 336 } 337 338 table.createPrimaryKey(pcol); 339 340 sq.table = table; 341 sq.uniqueRows = uniqueValues; 342 343 subQueryList.add(sq); 344 345 return sq; 346 } 347 348 SubQuery getViewSubquery(View v) { 349 350 SubQuery sq = v.viewSubQuery; 351 352 for (int i = 0; i < v.viewSubqueries.length; i++) { 353 subQueryList.add(v.viewSubqueries[i]); 354 } 355 356 return sq; 357 } 358 359 370 Select parseSelect(int brackets, boolean canHaveOrder, 371 boolean canHaveLimit, boolean limitWithOrder, 372 boolean isMain) throws HsqlException { 373 374 Select select = new Select(); 375 String token = tokenizer.getString(); 376 377 if (canHaveLimit || limitWithOrder) { 378 if (tokenizer.wasThis(Token.T_LIMIT) 379 || tokenizer.wasThis(Token.T_TOP)) { 380 parseLimit(token, select, false); 381 382 token = tokenizer.getString(); 383 } 384 } 385 386 if (tokenizer.wasThis(Token.T_DISTINCT)) { 387 select.isDistinctSelect = true; 388 } else if (tokenizer.wasThis(Token.T_ALL)) {} 389 else { 390 tokenizer.back(); 391 } 392 393 HsqlArrayList vcolumn = new HsqlArrayList(); 395 396 do { 397 Expression e = parseExpression(); 398 399 token = tokenizer.getString(); 400 401 if (tokenizer.wasThis(Token.T_AS)) { 402 e.setAlias(tokenizer.getSimpleName(), 403 tokenizer.wasQuotedIdentifier()); 404 405 token = tokenizer.getString(); 406 } else if (tokenizer.wasSimpleName()) { 407 e.setAlias(token, tokenizer.wasQuotedIdentifier()); 408 409 token = tokenizer.getString(); 410 } 411 412 vcolumn.add(e); 413 } while (tokenizer.wasThis(Token.T_COMMA)); 414 415 if (token.equals(Token.T_INTO)) { 416 boolean getname = true; 417 418 token = tokenizer.getString(); 419 420 if (tokenizer.wasSimpleToken()) { 421 switch (Token.get(token)) { 422 423 case Token.CACHED : 424 select.intoType = Table.CACHED_TABLE; 425 break; 426 427 case Token.TEMP : 428 select.intoType = Table.TEMP_TABLE; 429 break; 430 431 case Token.TEXT : 432 select.intoType = Table.TEXT_TABLE; 433 break; 434 435 case Token.MEMORY : 436 select.intoType = Table.MEMORY_TABLE; 437 break; 438 439 default : 440 select.intoType = database.getDefaultTableType(); 441 getname = false; 442 break; 443 } 444 445 if (getname) { 446 token = tokenizer.getName(); 447 } else { 448 if (!tokenizer.wasName()) { 449 tokenizer.throwUnexpected(); 450 } 451 } 452 } 453 454 select.sIntoTable = database.nameManager.newHsqlName(token, 455 tokenizer.wasQuotedIdentifier()); 456 select.sIntoTable.schema = 457 session.getSchemaHsqlName(tokenizer.getLongNameFirst()); 458 token = tokenizer.getString(); 459 } 460 461 tokenizer.matchThis(Token.T_FROM); 462 463 Expression condition = null; 464 465 HsqlArrayList vfilter = new HsqlArrayList(); 467 468 vfilter.add(parseTableFilter(false)); 469 470 while (true) { 471 token = tokenizer.getString(); 472 473 boolean cross = false; 474 475 if (tokenizer.wasThis(Token.T_INNER)) { 476 tokenizer.getThis(Token.T_JOIN); 477 478 token = Token.T_JOIN; 479 } else if (tokenizer.wasThis(Token.T_CROSS)) { 480 tokenizer.getThis(Token.T_JOIN); 481 482 token = Token.T_JOIN; 483 cross = true; 484 } 485 486 if (token.equals(Token.T_LEFT) 487 &&!tokenizer.wasQuotedIdentifier()) { 488 tokenizer.isGetThis(Token.T_OUTER); 489 tokenizer.getThis(Token.T_JOIN); 490 491 TableFilter tf = parseTableFilter(true); 492 493 vfilter.add(tf); 494 tokenizer.getThis(Token.T_ON); 495 496 Expression newcondition = parseExpression(); 497 498 newcondition.checkTables(vfilter); 499 500 condition = addJoinCondition(condition, newcondition, tf, 501 true); 502 503 } else if (token.equals(Token.T_RIGHT) 505 &&!tokenizer.wasQuotedIdentifier()) { 506 tokenizer.isGetThis(Token.T_OUTER); 507 tokenizer.getThis(Token.T_JOIN); 508 509 TableFilter tf = parseTableFilter(false); 511 512 HsqlArrayList nvfilter = new HsqlArrayList(); 514 515 nvfilter.add(tf); 516 nvfilter.addAll(vfilter); 517 518 vfilter = nvfilter; 519 520 ((TableFilter) vfilter.get(1)).isOuterJoin = true; 522 523 tokenizer.getThis(Token.T_ON); 524 525 Expression newcondition = parseExpression(); 526 527 newcondition.checkTables(vfilter); 528 529 condition = addJoinCondition(condition, newcondition, 530 ((TableFilter) vfilter.get(1)), 531 true); 532 } else if (tokenizer.wasThis(Token.T_JOIN)) { 533 vfilter.add(parseTableFilter(false)); 534 535 if (!cross) { 536 tokenizer.getThis(Token.T_ON); 537 538 Expression newcondition = parseExpression(); 539 540 newcondition.checkTables(vfilter); 541 542 condition = addJoinCondition(condition, newcondition, 543 null, false); 544 } 545 } else if (tokenizer.wasThis(Token.T_COMMA)) { 546 vfilter.add(parseTableFilter(false)); 547 } else { 548 tokenizer.back(); 549 550 break; 551 } 552 } 553 554 resolveSelectTableFilter(select, vcolumn, vfilter); 555 556 token = tokenizer.getString(); 558 559 if (tokenizer.wasThis(Token.T_WHERE)) { 560 Expression newcondition = parseExpression(); 561 562 condition = addCondition(condition, newcondition); 563 token = tokenizer.getString(); 564 } 565 566 select.queryCondition = condition; 567 568 if (tokenizer.wasThis(Token.T_GROUP)) { 570 tokenizer.getThis(Token.T_BY); 571 572 int len = 0; 573 574 do { 575 Expression e = parseExpression(); 576 577 vcolumn.add(e); 578 579 token = tokenizer.getString(); 580 581 len++; 582 } while (tokenizer.wasThis(Token.T_COMMA)); 583 584 select.iGroupLen = len; 585 } 586 587 if (tokenizer.wasThis(Token.T_HAVING)) { 589 select.iHavingLen = 1; 590 select.havingCondition = parseExpression(); 591 token = tokenizer.getString(); 592 593 vcolumn.add(select.havingCondition); 594 } 595 596 if (isMain || limitWithOrder) { 597 if (tokenizer.wasThis(Token.T_ORDER)) { 598 tokenizer.getThis(Token.T_BY); 599 parseOrderBy(select, vcolumn); 600 601 token = tokenizer.getString(); 602 } 603 604 if (tokenizer.wasThis(Token.T_LIMIT)) { 605 parseLimit(token, select, true); 606 607 token = tokenizer.getString(); 608 } 609 } 610 611 boolean closebrackets = false; 612 613 if (brackets > 0 && token.equals(Token.T_CLOSEBRACKET)) { 614 closebrackets = true; 615 brackets -= parseCloseBrackets(brackets - 1) + 1; 616 token = tokenizer.getString(); 617 } 618 619 select.unionDepth = brackets; 620 621 if (!(isMain || closebrackets)) { 623 limitWithOrder = false; 624 } 625 626 boolean hasOrder = select.iOrderLen != 0; 627 boolean hasLimit = select.limitCondition != null; 628 629 if (limitWithOrder) { 630 if (hasLimit &&!hasOrder) { 631 throw Trace.error(Trace.ORDER_LIMIT_REQUIRED); 632 } 633 } else { 634 if (hasOrder &&!canHaveOrder) { 635 throw Trace.error(Trace.INVALID_ORDER_BY); 636 } 637 638 if (hasLimit &&!canHaveLimit) { 639 throw Trace.error(Trace.INVALID_LIMIT); 640 } 641 } 642 643 int unionType = parseUnion(token); 644 645 if (unionType != Select.NOUNION) { 646 boolean openbracket = false; 647 648 select.unionType = unionType; 649 650 if (tokenizer.isGetThis(Token.T_OPENBRACKET)) { 651 openbracket = true; 652 brackets += parseOpenBrackets() + 1; 653 } 654 655 tokenizer.getThis(Token.T_SELECT); 656 657 select.unionSelect = parseSelect(brackets, false, false, 659 openbracket, false); 660 token = tokenizer.getString(); 661 } 662 663 if (isMain && (canHaveOrder || limitWithOrder) 664 && select.iOrderLen == 0) { 665 if (tokenizer.wasThis(Token.T_ORDER)) { 666 tokenizer.getThis(Token.T_BY); 667 parseOrderBy(select, vcolumn); 668 669 token = tokenizer.getString(); 670 select.sortUnion = true; 671 } 672 673 if (tokenizer.wasThis(Token.T_LIMIT)) { 674 parseLimit(token, select, true); 675 676 token = tokenizer.getString(); 677 } 678 } 679 680 tokenizer.back(); 681 682 if (isMain) { 683 select.prepareUnions(); 684 } 685 686 int len = vcolumn.size(); 687 688 select.exprColumns = new Expression[len]; 689 690 vcolumn.toArray(select.exprColumns); 691 692 return select; 693 } 694 695 699 int parseUnion(String token) throws HsqlException { 700 701 int unionType = Select.NOUNION; 702 703 if (tokenizer.wasSimpleToken()) { 704 switch (Token.get(token)) { 705 706 case Token.UNION : 707 token = tokenizer.getSimpleToken(); 708 709 if (token.equals(Token.T_ALL)) { 710 unionType = Select.UNIONALL; 711 } else if (token.equals(Token.T_DISTINCT)) { 712 unionType = Select.UNION; 713 } else { 714 unionType = Select.UNION; 715 716 tokenizer.back(); 717 } 718 break; 719 720 case Token.INTERSECT : 721 tokenizer.isGetThis(Token.T_DISTINCT); 722 723 unionType = Select.INTERSECT; 724 break; 725 726 case Token.EXCEPT : 727 case Token.MINUS : 728 tokenizer.isGetThis(Token.T_DISTINCT); 729 730 unionType = Select.EXCEPT; 731 break; 732 733 default : 734 break; 735 } 736 } 737 738 return unionType; 739 } 740 741 private void parseLimit(String token, Select select, 750 boolean isEnd) throws HsqlException { 751 752 if (select.limitCondition != null) { 753 return; 754 } 755 756 Expression e1 = null; 757 Expression e2; 758 boolean islimit = false; 759 760 if (isEnd) { 761 if (token.equals(Token.T_LIMIT)) { 762 islimit = true; 763 764 read(); 765 766 e2 = readTerm(); 767 768 if (sToken.equals(Token.T_OFFSET)) { 769 read(); 770 771 e1 = readTerm(); 772 } 773 774 tokenizer.back(); 775 } else { 776 return; 777 } 778 } else if (token.equals(Token.T_LIMIT)) { 779 read(); 780 781 e1 = readTerm(); 782 e2 = readTerm(); 783 islimit = true; 784 785 tokenizer.back(); 786 } else if (token.equals(Token.T_TOP)) { 787 read(); 788 789 e2 = readTerm(); 790 791 tokenizer.back(); 792 } else { 793 return; 794 } 795 796 if (e1 == null) { 797 e1 = new Expression(Types.INTEGER, ValuePool.getInt(0)); 798 } 799 800 if (e1.isParam() 801 || (e1.getType() == Expression.VALUE 802 && e1.getDataType() == Types.INTEGER 803 && e1.getValue(null) != null 804 && ((Integer ) e1.getValue(null)).intValue() >= 0)) { 805 if (e2.isParam() 806 || (e2.getType() == Expression.VALUE 807 && e2.getDataType() == Types.INTEGER 808 && e2.getValue(null) != null 809 && ((Integer ) e2.getValue(null)).intValue() >= 0)) { 810 811 e1.setDataType(Types.INTEGER); 813 e2.setDataType(Types.INTEGER); 814 815 select.limitCondition = new Expression(Expression.LIMIT, e1, 816 e2); 817 818 return; 819 } 820 } 821 822 int messageid = islimit ? Trace.INVALID_LIMIT_EXPRESSION 823 : Trace.INVALID_TOP_EXPRESSION; 824 825 throw Trace.error(Trace.WRONG_DATA_TYPE, messageid); 826 } 827 828 private void parseOrderBy(Select select, 829 HsqlArrayList vcolumn) throws HsqlException { 830 831 String token; 832 int len = 0; 833 834 do { 835 Expression e = parseExpression(); 836 837 e = resolveOrderByExpression(e, select, vcolumn); 838 token = tokenizer.getString(); 839 840 if (token.equals(Token.T_DESC)) { 841 e.setDescending(); 842 843 token = tokenizer.getString(); 844 } else if (token.equals(Token.T_ASC)) { 845 token = tokenizer.getString(); 846 } 847 848 vcolumn.add(e); 849 850 len++; 851 } while (token.equals(Token.T_COMMA)); 852 853 tokenizer.back(); 854 855 select.iOrderLen = len; 856 } 857 858 private void resolveSelectTableFilter(Select select, 859 HsqlArrayList vcolumn, 860 HsqlArrayList vfilter) 861 throws HsqlException { 862 863 int colcount; 864 TableFilter[] filters = new TableFilter[vfilter.size()]; 865 866 vfilter.toArray(filters); 867 868 select.tFilter = filters; 869 870 colcount = vcolumn.size(); 872 873 for (int pos = 0; pos < colcount; ) { 874 Expression e = (Expression) (vcolumn.get(pos)); 875 876 if (e.getType() == Expression.ASTERISK) { 877 vcolumn.remove(pos); 878 879 colcount = vcolumn.size(); 880 881 String tablename = e.getTableName(); 882 883 if (tablename == null) { 884 for (int i = 0; i < filters.length; i++) { 885 pos = addFilterColumns(filters[i], vcolumn, pos); 886 colcount = vcolumn.size(); 887 } 888 } else { 889 TableFilter f = e.findTableFilter(filters); 890 891 if (f == null) { 892 throw Trace.error(Trace.TABLE_NOT_FOUND, tablename); 893 } 894 895 pos = addFilterColumns(f, vcolumn, pos); 896 colcount = vcolumn.size(); 897 } 898 } else { 899 if (e.getFilter() == null) { 900 for (int i = 0; i < filters.length; i++) { 901 e.resolveTables(filters[i]); 902 } 903 } 904 905 pos++; 906 } 907 } 908 909 for (int i = 0; i < colcount; i++) { 910 Expression e = (Expression) (vcolumn.get(i)); 911 912 e.resolveTypes(session); 913 } 914 915 select.iResultLen = colcount; 916 } 917 918 921 static int addFilterColumns(TableFilter filter, HsqlArrayList columnList, 922 int position) { 923 924 Table table = filter.getTable(); 925 int count = table.getColumnCount(); 926 927 for (int i = 0; i < count; i++) { 928 Expression e = new Expression(filter, table.getColumn(i)); 929 930 columnList.add(position++, e); 931 } 932 933 return position; 934 } 935 936 950 private static Expression resolveOrderByExpression(Expression e, 951 Select select, HsqlArrayList vcolumn) throws HsqlException { 952 953 int visiblecols = select.iResultLen; 954 boolean union = select.unionSelect != null; 955 956 if (e.getType() == Expression.VALUE) { 957 return resolveOrderByColumnIndex(e, vcolumn, visiblecols); 958 } 959 960 if (e.getType() != Expression.COLUMN) { 961 if (union) { 962 throw Trace.error(Trace.INVALID_ORDER_BY); 963 } 964 965 return e; 966 } 967 968 String ecolname = e.getColumnName(); 969 String etablename = e.getTableName(); 970 971 for (int i = 0, size = visiblecols; i < size; i++) { 972 Expression colexpr = (Expression) vcolumn.get(i); 973 String colalias = colexpr.getDefinedAlias(); 974 String colname = colexpr.getColumnName(); 975 String tablename = colexpr.getTableName(); 976 String filtername = colexpr.getFilterTableName(); 977 978 if ((ecolname.equals(colalias) || ecolname.equals(colname)) 979 && (etablename == null || etablename.equals(tablename) 980 || etablename.equals(filtername))) { 981 colexpr.joinedTableColumnIndex = i; 982 983 return colexpr; 984 } 985 } 986 987 if (union) { 988 throw Trace.error(Trace.INVALID_ORDER_BY, ecolname); 989 } 990 991 return e; 992 } 993 994 private static Expression resolveOrderByColumnIndex(Expression e, 995 HsqlArrayList vcolumn, int visiblecols) throws HsqlException { 996 997 if (e.getDataType() == Types.INTEGER) { 999 int i = ((Integer ) e.getValue(null)).intValue(); 1000 1001 if (0 < i && i <= visiblecols) { 1002 Expression colexpr = (Expression) vcolumn.get(i - 1); 1003 1004 colexpr.joinedTableColumnIndex = i - 1; 1005 1006 return colexpr; 1007 } 1008 } 1009 1010 throw Trace.error(Trace.INVALID_ORDER_BY); 1011 } 1012 1013 private TableFilter parseSimpleTableFilter(int type) 1014 throws HsqlException { 1015 1016 String alias = null; 1017 String token = tokenizer.getName(); 1018 String schema = session.getSchemaName(tokenizer.getLongNameFirst()); 1019 Table table = database.schemaManager.getTable(session, token, schema); 1020 1021 checkTableWriteAccess(table, type); 1022 1023 token = tokenizer.getString(); 1025 1026 if (token.equals(Token.T_AS)) { 1027 alias = tokenizer.getSimpleName(); 1028 } else if (tokenizer.wasSimpleName()) { 1029 alias = token; 1030 } else { 1031 tokenizer.back(); 1032 } 1033 1034 return new TableFilter(table, alias, null, false); 1035 } 1036 1037 1045 private TableFilter parseTableFilter(boolean outerjoin) 1046 throws HsqlException { 1047 1048 Table t = null; 1049 SubQuery sq = null; 1050 String sAlias = null; 1051 HashMappedList columnList = null; 1052 1053 if (tokenizer.isGetThis(Token.T_OPENBRACKET)) { 1054 int brackets = parseOpenBrackets(); 1055 1056 tokenizer.getThis(Token.T_SELECT); 1057 1058 sq = parseSubquery(brackets, null, true, Expression.QUERY); 1060 1061 tokenizer.getThis(Token.T_CLOSEBRACKET); 1062 1063 t = sq.table; 1064 } else { 1065 String token = tokenizer.getName(); 1066 String schema = 1067 session.getSchemaName(tokenizer.getLongNameFirst()); 1068 1069 t = database.schemaManager.getTable(session, token, schema); 1070 1071 session.check(t.getName(), UserManager.SELECT); 1072 1073 if (t.isView()) { 1074 sq = getViewSubquery((View) t); 1075 sq.select = ((View) t).viewSelect; 1076 t = sq.table; 1077 sAlias = token; 1078 } 1079 } 1080 1081 String token = tokenizer.getString(); 1085 1086 if (tokenizer.wasLongName()) { 1087 tokenizer.throwUnexpected(); 1088 } 1089 1090 if ((token.equals(Token.T_LEFT) || token.equals(Token.T_RIGHT)) 1091 &&!tokenizer.wasQuotedIdentifier()) { 1092 tokenizer.back(); 1093 } else if (token.equals(Token.T_AS) 1094 &&!tokenizer.wasQuotedIdentifier()) { 1095 sAlias = tokenizer.getSimpleName(); 1096 1097 if (tokenizer.isGetThis(Token.T_OPENBRACKET)) { 1098 tokenizer.back(); 1099 1100 columnList = parseColumnList(); 1101 } 1102 } else if (tokenizer.wasSimpleName()) { 1103 sAlias = token; 1104 1105 if (tokenizer.isGetThis(Token.T_OPENBRACKET)) { 1106 tokenizer.back(); 1107 1108 columnList = parseColumnList(); 1109 } 1110 } else { 1111 tokenizer.back(); 1112 } 1113 1114 if (columnList != null && t.getColumnCount() != columnList.size()) { 1115 throw Trace.error(Trace.COLUMN_COUNT_DOES_NOT_MATCH); 1116 } 1117 1118 return new TableFilter(t, sAlias, columnList, outerjoin); 1119 } 1120 1121 1128 private static Expression addCondition(Expression e1, Expression e2) { 1129 1130 if (e1 == null) { 1131 return e2; 1132 } else if (e2 == null) { 1133 return e1; 1134 } else { 1135 return new Expression(Expression.AND, e1, e2); 1136 } 1137 } 1138 1139 1152 private static Expression addJoinCondition(Expression e1, Expression e2, 1153 TableFilter tf, boolean outer) throws HsqlException { 1154 1155 if (!e2.setForJoin(tf, outer)) { 1156 throw Trace.error(Trace.OUTER_JOIN_CONDITION); 1157 } 1158 1159 return addCondition(e1, e2); 1160 } 1161 1162 1168 Expression parseExpression() throws HsqlException { 1169 1170 read(); 1171 1172 Expression r = readOr(); 1173 1174 tokenizer.back(); 1175 1176 return r; 1177 } 1178 1179 private Expression readAggregate() throws HsqlException { 1180 1181 boolean distinct = false; 1182 boolean all = false; 1183 int type = iToken; 1184 1185 read(); 1186 1187 String token = tokenizer.getString(); 1188 1189 if (token.equals(Token.T_DISTINCT)) { 1190 distinct = true; 1191 } else if (token.equals(Token.T_ALL)) { 1192 all = true; 1193 } else { 1194 tokenizer.back(); 1195 } 1196 1197 readThis(Expression.OPEN); 1198 1199 Expression s = readOr(); 1200 1201 readThis(Expression.CLOSE); 1202 1203 if ((all || distinct) 1204 && (type == Expression.STDDEV_POP 1205 || type == Expression.STDDEV_SAMP 1206 || type == Expression.VAR_POP 1207 || type == Expression.VAR_SAMP)) { 1208 throw Trace.error(Trace.INVALID_FUNCTION_ARGUMENT); 1209 } 1210 1211 Expression aggregateExp = new Expression(type, s, null); 1212 1213 aggregateExp.setDistinctAggregate(distinct); 1214 1215 return aggregateExp; 1216 } 1217 1218 1224 private Expression readOr() throws HsqlException { 1225 1226 Expression r = readAnd(); 1227 1228 while (iToken == Expression.OR) { 1229 int type = iToken; 1230 Expression a = r; 1231 1232 read(); 1233 1234 r = new Expression(type, a, readAnd()); 1235 } 1236 1237 return r; 1238 } 1239 1240 1246 private Expression readAnd() throws HsqlException { 1247 1248 Expression r = readCondition(); 1249 1250 while (iToken == Expression.AND) { 1251 int type = iToken; 1252 Expression a = r; 1253 1254 read(); 1255 1256 r = new Expression(type, a, readCondition()); 1257 } 1258 1259 return r; 1260 } 1261 1262 1268 private Expression readCondition() throws HsqlException { 1269 1270 switch (iToken) { 1271 1272 case Expression.NOT : { 1273 int type = iToken; 1274 1275 read(); 1276 1277 return new Expression(type, readCondition(), null); 1278 } 1279 case Expression.EXISTS : { 1280 int type = iToken; 1281 1282 read(); 1283 readThis(Expression.OPEN); 1284 1285 int brackets = 0; 1286 1287 if (iToken == Expression.OPEN) { 1288 brackets += parseOpenBrackets() + 1; 1289 1290 read(); 1291 } 1292 1293 Trace.check(iToken == Expression.SELECT, 1294 Trace.UNEXPECTED_TOKEN); 1295 1296 SubQuery sq = parseSubquery(brackets, null, false, 1297 Expression.EXISTS); 1298 Expression s = new Expression(sq); 1299 1300 read(); 1301 readThis(Expression.CLOSE); 1302 1303 return new Expression(type, s, null); 1304 } 1305 default : { 1306 Expression a = readConcat(); 1307 1308 if (iToken == Expression.IS) { 1309 read(); 1310 1311 boolean not; 1312 1313 if (iToken == Expression.NOT) { 1314 not = true; 1315 1316 read(); 1317 } else { 1318 not = false; 1319 } 1320 1321 Trace.check(iToken == Expression.VALUE && oData == null, 1322 Trace.UNEXPECTED_TOKEN); 1323 read(); 1324 1325 a = new Expression(Expression.IS_NULL, a, 1327 new Expression(Types.NULL, null)); 1328 1329 if (not) { 1330 a = new Expression(Expression.NOT, a, null); 1331 } 1332 1333 return a; 1334 } 1335 1336 boolean not = false; 1337 1338 if (iToken == Expression.NOT) { 1339 not = true; 1340 1341 read(); 1342 } 1343 1344 switch (iToken) { 1345 1346 case Expression.LIKE : { 1347 a = parseLikePredicate(a); 1348 1349 break; 1350 } 1351 case Expression.BETWEEN : { 1352 a = parseBetweenPredicate(a); 1353 1354 break; 1355 } 1356 case Expression.IN : { 1357 a = this.parseInPredicate(a); 1358 1359 break; 1360 } 1361 default : { 1362 Trace.check(!not, Trace.UNEXPECTED_TOKEN); 1363 1364 if (Expression.isCompare(iToken)) { 1365 int type = iToken; 1366 1367 read(); 1368 1369 return new Expression(type, a, readConcat()); 1370 } 1371 1372 return a; 1373 } 1374 } 1375 1376 if (not) { 1377 a = new Expression(Expression.NOT, a, null); 1378 } 1379 1380 return a; 1381 } 1382 } 1383 } 1384 1385 private Expression parseLikePredicate(Expression a) throws HsqlException { 1386 1387 read(); 1388 1389 Expression b = readConcat(); 1390 Character escape = null; 1391 1392 if (sToken.equals(Token.T_ESCAPE)) { 1393 read(); 1394 1395 Expression c = readTerm(); 1396 1397 Trace.check(c.getType() == Expression.VALUE, 1398 Trace.INVALID_ESCAPE); 1399 1400 String s = (String ) c.getValue(session, Types.VARCHAR); 1401 1402 if (s == null || s.length() < 1) { 1410 throw Trace.error(Trace.INVALID_ESCAPE, s); 1411 } 1412 1413 escape = new Character (s.charAt(0)); 1414 } 1415 1416 boolean hasCollation = database.collation.name != null; 1417 1418 a = new Expression(a, b, escape, hasCollation); 1419 1420 return a; 1421 } 1422 1423 private Expression parseBetweenPredicate(Expression a) 1424 throws HsqlException { 1425 1426 read(); 1427 1428 Expression l = new Expression(Expression.BIGGER_EQUAL, a, 1429 readConcat()); 1430 1431 readThis(Expression.AND); 1432 1433 Expression h = new Expression(Expression.SMALLER_EQUAL, a, 1434 readConcat()); 1435 1436 if (l.getArg().isParam() && l.getArg2().isParam()) { 1437 throw Trace.error(Trace.UNRESOLVED_PARAMETER_TYPE, 1438 Trace.Parser_ambiguous_between1); 1439 } 1440 1441 if (h.getArg().isParam() && h.getArg2().isParam()) { 1442 throw Trace.error(Trace.UNRESOLVED_PARAMETER_TYPE, 1443 Trace.Parser_ambiguous_between1); 1444 } 1445 1446 return new Expression(Expression.AND, l, h); 1447 } 1448 1449 private Expression parseInPredicate(Expression a) throws HsqlException { 1450 1451 int type = iToken; 1452 1453 read(); 1454 readThis(Expression.OPEN); 1455 1456 Expression b = null; 1457 int brackets = 0; 1458 1459 if (iToken == Expression.OPEN) { 1460 brackets += parseOpenBrackets() + 1; 1461 1462 read(); 1463 } 1464 1465 if (iToken == Expression.SELECT) { 1466 SubQuery sq = parseSubquery(brackets, null, false, Expression.IN); 1467 1468 Trace.check(sq.select.iResultLen == 1, 1470 Trace.SINGLE_COLUMN_EXPECTED); 1471 1472 b = new Expression(sq); 1473 1474 read(); 1475 } else { 1476 tokenizer.back(); 1477 1478 HsqlArrayList v = new HsqlArrayList(); 1479 1480 while (true) { 1481 Expression value = parseExpression(); 1482 1483 if (value.exprType == Expression.VALUE 1484 && value.valueData == null &&!value.isParam()) { 1485 throw Trace.error(Trace.NULL_IN_VALUE_LIST); 1486 } 1487 1488 v.add(value); 1489 read(); 1490 1491 if (iToken != Expression.COMMA) { 1492 break; 1493 } 1494 } 1495 1496 Expression[] valueList; 1497 1498 valueList = (Expression[]) v.toArray(new Expression[v.size()]); 1499 b = new Expression(valueList); 1500 } 1501 1502 readThis(Expression.CLOSE); 1503 1504 return new Expression(type, a, b); 1505 } 1506 1507 private Expression parseAllAnyPredicate() throws HsqlException { 1508 1509 int type = iToken; 1510 1511 read(); 1512 readThis(Expression.OPEN); 1513 1514 Expression b = null; 1515 int brackets = 0; 1516 1517 if (iToken == Expression.OPEN) { 1518 brackets += parseOpenBrackets() + 1; 1519 1520 read(); 1521 } 1522 1523 if (iToken != Expression.SELECT) { 1524 throw Trace.error(Trace.INVALID_IDENTIFIER); 1525 } 1526 1527 SubQuery sq = parseSubquery(brackets, null, false, type); 1528 Select select = sq.select; 1529 1530 Trace.check(sq.select.iResultLen == 1, Trace.SINGLE_COLUMN_EXPECTED); 1532 1533 b = new Expression(sq); 1534 1535 read(); 1536 readThis(Expression.CLOSE); 1537 1538 return new Expression(type, b, null); 1539 } 1540 1541 1547 private void readThis(int type) throws HsqlException { 1548 Trace.check(iToken == type, Trace.UNEXPECTED_TOKEN); 1549 read(); 1550 } 1551 1552 1558 private Expression readConcat() throws HsqlException { 1559 1560 Expression r = readSum(); 1561 1562 while (iToken == Expression.CONCAT) { 1563 int type = Expression.CONCAT; 1564 Expression a = r; 1565 1566 read(); 1567 1568 r = new Expression(type, a, readSum()); 1569 } 1570 1571 return r; 1572 } 1573 1574 static HashMap simpleFunctions = new HashMap(); 1575 1576 static { 1577 simpleFunctions.put(Token.T_CURRENT_DATE, 1578 "org.hsqldb.Library.curdate"); 1579 simpleFunctions.put(Token.T_CURRENT_TIME, 1580 "org.hsqldb.Library.curtime"); 1581 simpleFunctions.put(Token.T_CURRENT_TIMESTAMP, 1582 "org.hsqldb.Library.now"); 1583 simpleFunctions.put(Token.T_CURRENT_USER, "org.hsqldb.Library.user"); 1584 simpleFunctions.put(Token.T_SYSDATE, "org.hsqldb.Library.curdate"); 1585 simpleFunctions.put(Token.T_NOW, "org.hsqldb.Library.now"); 1586 simpleFunctions.put(Token.T_TODAY, "org.hsqldb.Library.curdate"); 1587 } 1588 1589 1595 private Expression readSum() throws HsqlException { 1596 1597 Expression r = readFactor(); 1598 1599 while (true) { 1600 int type; 1601 1602 if (iToken == Expression.PLUS) { 1603 type = Expression.ADD; 1604 } else if (iToken == Expression.NEGATE) { 1605 type = Expression.SUBTRACT; 1606 } else { 1607 break; 1608 } 1609 1610 Expression a = r; 1611 1612 read(); 1613 1614 r = new Expression(type, a, readFactor()); 1615 } 1616 1617 return r; 1618 } 1619 1620 1626 private Expression readFactor() throws HsqlException { 1627 1628 Expression r = readTerm(); 1629 1630 while (iToken == Expression.MULTIPLY || iToken == Expression.DIVIDE) { 1631 int type = iToken; 1632 Expression a = r; 1633 1634 read(); 1635 1636 r = new Expression(type, a, readTerm()); 1637 } 1638 1639 return r; 1640 } 1641 1642 1648 private Expression readTerm() throws HsqlException { 1649 1650 Expression r = null; 1651 1652 switch (iToken) { 1653 1654 case Expression.COLUMN : { 1655 r = readColumnExpression(); 1656 1657 break; 1658 } 1659 case Expression.NEGATE : { 1660 int type = iToken; 1661 1662 read(); 1663 1664 r = new Expression(type, readTerm(), null); 1665 1666 Trace.check(!r.getArg().isParam(), 1667 Trace.Expression_resolveTypes1); 1668 1669 break; 1670 } 1671 case Expression.PLUS : { 1672 read(); 1673 1674 r = readTerm(); 1675 1676 Trace.check(!r.isParam(), Trace.UNRESOLVED_PARAMETER_TYPE, 1677 Trace.getMessage(Trace.Expression_resolveTypes1)); 1678 1679 break; 1680 } 1681 case Expression.OPEN : { 1682 read(); 1683 1684 r = readOr(); 1685 1686 if (iToken != Expression.CLOSE) { 1687 throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken); 1688 } 1689 1690 read(); 1691 1692 break; 1693 } 1694 case Expression.VALUE : { 1695 r = new Expression(iType, oData); 1696 1697 read(); 1698 1699 break; 1700 } 1701 case Expression.PARAM : { 1702 r = new Expression(Types.NULL, null, true); 1703 1704 parameters.add(r); 1705 read(); 1706 1707 break; 1708 } 1709 case Expression.SELECT : { 1710 1720 SubQuery sq = parseSubquery(0, null, false, 1721 Expression.SELECT); 1722 1723 r = new Expression(sq); 1724 1725 read(); 1726 1727 break; 1728 } 1729 case Expression.ANY : 1730 case Expression.ALL : { 1731 r = parseAllAnyPredicate(); 1732 1733 break; 1735 } 1736 case Expression.MULTIPLY : { 1737 r = new Expression(sSchema, sTable, (String ) null); 1738 1739 read(); 1740 1741 break; 1742 } 1743 case Expression.CASEWHEN : 1744 return readCaseWhenExpression(); 1745 1746 case Expression.CASE : 1747 return readCaseExpression(); 1748 1749 case Expression.NULLIF : 1750 return readNullIfExpression(); 1751 1752 case Expression.COALESCE : 1753 case Expression.IFNULL : 1754 return readCoalesceExpression(); 1755 1756 case Expression.SEQUENCE : 1757 return readSequenceExpression(); 1758 1759 case Expression.CAST : 1760 case Expression.CONVERT : 1761 return readCastExpression(); 1762 1763 case Expression.EXTRACT : 1764 return readExtractExpression(); 1765 1766 case Expression.TRIM : 1767 return readTrimExpression(); 1768 1769 case Expression.POSITION : 1770 return readPositionExpression(); 1771 1772 case Expression.SUBSTRING : 1773 return readSubstringExpression(); 1774 1775 default : 1776 if (Expression.isAggregate(iToken)) { 1777 return readAggregate(); 1778 } else { 1779 throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken); 1780 } 1781 } 1782 1783 return r; 1784 } 1785 1786 1789 Expression readCaseExpression() throws HsqlException { 1790 1791 int type = Expression.CASEWHEN; 1792 Expression r = null; 1793 Expression predicand = null; 1794 1795 read(); 1796 1797 if (iToken != Expression.WHEN) { 1798 predicand = readOr(); 1799 } 1800 1801 Expression leaf = null; 1802 1803 while (true) { 1804 Expression casewhen = parseCaseWhen(predicand); 1805 1806 if (r == null) { 1807 r = casewhen; 1808 } else { 1809 leaf.setRightExpression(casewhen); 1810 } 1811 1812 leaf = casewhen.getRightExpression(); 1813 1814 if (iToken != Expression.WHEN) { 1815 break; 1816 } 1817 } 1818 1819 if (iToken == Expression.ELSE) { 1820 readThis(Expression.ELSE); 1821 1822 Expression elsexpr = readOr(); 1823 1824 leaf.setRightExpression(elsexpr); 1825 } 1826 1827 readThis(Expression.ENDWHEN); 1828 1829 return r; 1830 } 1831 1832 1835 private Expression parseCaseWhen(Expression r) throws HsqlException { 1836 1837 readThis(Expression.WHEN); 1838 1839 Expression condition; 1840 1841 if (r == null) { 1842 condition = readOr(); 1843 } else { 1844 condition = new Expression(Expression.EQUAL, r, readOr()); 1845 } 1846 1847 readThis(Expression.THEN); 1848 1849 Expression current = readOr(); 1850 Expression alternatives = new Expression(Expression.ALTERNATIVE, 1851 current, new Expression(Types.NULL, null)); 1852 Expression casewhen = new Expression(Expression.CASEWHEN, condition, 1853 alternatives); 1854 1855 return casewhen; 1856 } 1857 1858 1861 private Expression readCaseWhenExpression() throws HsqlException { 1862 1863 int type = iToken; 1864 Expression r = null; 1865 1866 read(); 1867 readThis(Expression.OPEN); 1868 1869 r = readOr(); 1870 1871 readThis(Expression.COMMA); 1872 1873 Expression thenelse = readOr(); 1874 1875 readThis(Expression.COMMA); 1876 1877 thenelse = new Expression(Expression.ALTERNATIVE, thenelse, readOr()); 1879 r = new Expression(type, r, thenelse); 1880 1881 readThis(Expression.CLOSE); 1882 1883 return r; 1884 } 1885 1886 1889 private Expression readCastExpression() throws HsqlException { 1890 1891 boolean isConvert = iToken == Expression.CONVERT; 1892 1893 read(); 1894 readThis(Expression.OPEN); 1895 1896 Expression r = readOr(); 1897 1898 if (isConvert) { 1899 readThis(Expression.COMMA); 1900 } else { 1901 readThis(Expression.AS); 1902 } 1903 1904 int typeNr = Types.getTypeNr(sToken); 1905 int length = 0; 1906 int scale = 0; 1907 boolean hasLength = false; 1908 1909 if (Types.acceptsPrecisionCreateParam(typeNr) 1910 && tokenizer.isGetThis(Token.T_OPENBRACKET)) { 1911 length = tokenizer.getInt(); 1912 hasLength = true; 1913 1914 if (Types.acceptsScaleCreateParam(typeNr) 1915 && tokenizer.isGetThis(Token.T_COMMA)) { 1916 scale = tokenizer.getInt(); 1917 } 1918 1919 tokenizer.getThis(Token.T_CLOSEBRACKET); 1920 } 1921 1922 if (typeNr == Types.FLOAT && length > 53) { 1923 throw Trace.error(Trace.NUMERIC_VALUE_OUT_OF_RANGE); 1924 } 1925 1926 if (typeNr == Types.TIMESTAMP) { 1927 if (!hasLength) { 1928 length = 6; 1929 } else if (length != 0 && length != 6) { 1930 throw Trace.error(Trace.NUMERIC_VALUE_OUT_OF_RANGE); 1931 } 1932 } 1933 1934 if (r.isParam()) { 1935 r.setDataType(typeNr); 1936 } 1937 1938 r = new Expression(r, typeNr, length, scale); 1939 1940 read(); 1941 readThis(Expression.CLOSE); 1942 1943 return r; 1944 } 1945 1946 1949 private Expression readColumnExpression() throws HsqlException { 1950 1951 String name = sToken; 1952 Expression r = new Expression(sTable, name, wasQuoted); 1953 1954 read(); 1955 1956 if (iToken == Expression.OPEN) { 1957 String javaName = database.getJavaName(name); 1958 Function f = new Function(name, javaName, false); 1959 1960 session.check(javaName); 1961 1962 int len = f.getArgCount(); 1963 int i = 0; 1964 1965 read(); 1966 1967 if (iToken != Expression.CLOSE) { 1968 while (true) { 1969 f.setArgument(i++, readOr()); 1970 1971 if (iToken != Expression.COMMA) { 1972 break; 1973 } 1974 1975 read(); 1976 } 1977 } 1978 1979 readThis(Expression.CLOSE); 1980 1981 r = new Expression(f); 1982 } else { 1983 String javaName = (String ) simpleFunctions.get(name); 1984 1985 if (javaName != null) { 1986 Function f = new Function(name, javaName, true); 1987 1988 r = new Expression(f); 1989 } 1990 } 1991 1992 return r; 1993 } 1994 1995 1998 private Expression readConcatExpression() throws HsqlException { 1999 2000 int type = iToken; 2001 2002 read(); 2003 readThis(Expression.OPEN); 2004 2005 Expression r = readOr(); 2006 2007 readThis(Expression.COMMA); 2008 2009 r = new Expression(type, r, readOr()); 2010 2011 readThis(Expression.CLOSE); 2012 2013 return r; 2014 } 2015 2016 2019 private Expression readNullIfExpression() throws HsqlException { 2020 2021 read(); 2023 readThis(Expression.OPEN); 2024 2025 Expression r = readOr(); 2026 2027 readThis(Expression.COMMA); 2028 2029 Expression thenelse = new Expression(Expression.ALTERNATIVE, 2030 new Expression(Types.NULL, null), 2031 r); 2032 2033 r = new Expression(Expression.EQUAL, r, readOr()); 2034 r = new Expression(Expression.CASEWHEN, r, thenelse); 2035 2036 readThis(Expression.CLOSE); 2037 2038 return r; 2039 } 2040 2041 2044 private Expression readCoalesceExpression() throws HsqlException { 2045 2046 Expression r = null; 2047 2048 read(); 2050 readThis(Expression.OPEN); 2051 2052 Expression leaf = null; 2053 2054 while (true) { 2055 Expression current = readOr(); 2056 2057 if (leaf != null && iToken == Expression.CLOSE) { 2058 readThis(Expression.CLOSE); 2059 leaf.setLeftExpression(current); 2060 2061 break; 2062 } 2063 2064 Expression condition = new Expression(Expression.IS_NULL, 2065 current, null); 2066 Expression alternatives = new Expression(Expression.ALTERNATIVE, 2067 new Expression(Types.NULL, null), current); 2068 Expression casewhen = new Expression(Expression.CASEWHEN, 2069 condition, alternatives); 2070 2071 if (r == null) { 2072 r = casewhen; 2073 } else { 2074 leaf.setLeftExpression(casewhen); 2075 } 2076 2077 leaf = alternatives; 2078 2079 readThis(Expression.COMMA); 2080 } 2081 2082 return r; 2083 } 2084 2085 2088 private Expression readExtractExpression() throws HsqlException { 2089 2090 read(); 2091 readThis(Expression.OPEN); 2092 2093 String name = sToken; 2094 2095 if (!Expression.SQL_EXTRACT_FIELD_NAMES.contains(name)) { 2097 throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken); 2098 } 2099 2100 readToken(); 2101 readThis(Expression.FROM); 2102 2103 Function f = new Function(name, database.getJavaName(name), false); 2105 2106 f.setArgument(0, readOr()); 2107 readThis(Expression.CLOSE); 2108 2109 return new Expression(f); 2110 } 2111 2112 2115 private Expression readPositionExpression() throws HsqlException { 2116 2117 read(); 2118 readThis(Expression.OPEN); 2119 2120 Function f = new Function(Token.T_POSITION, 2121 "org.hsqldb.Library.position", false); 2122 2123 f.setArgument(0, readTerm()); 2124 readThis(Expression.IN); 2125 f.setArgument(1, readOr()); 2126 readThis(Expression.CLOSE); 2127 2128 return new Expression(f); 2129 } 2130 2131 2134 private Expression readSubstringExpression() throws HsqlException { 2135 2136 boolean commas = false; 2137 2138 read(); 2139 readThis(Expression.OPEN); 2140 2141 Function f = new Function(Token.T_SUBSTRING, 2143 "org.hsqldb.Library.substring", false); 2144 2145 f.setArgument(0, readTerm()); 2146 2147 if (iToken == Expression.FROM) { 2148 readThis(Expression.FROM); 2149 } else { 2150 readThis(Expression.COMMA); 2151 2152 commas = true; 2153 } 2154 2155 f.setArgument(1, readOr()); 2156 2157 Expression count = null; 2158 2159 if (!commas && iToken == Expression.FOR) { 2160 readThis(Expression.FOR); 2161 2162 count = readTerm(); 2163 } else if (commas && iToken == Expression.COMMA) { 2164 readThis(Expression.COMMA); 2165 2166 count = readTerm(); 2167 } 2168 2169 f.setArgument(2, count); 2170 readThis(Expression.CLOSE); 2171 2172 return new Expression(f); 2173 } 2174 2175 private Expression readSequenceExpression() throws HsqlException { 2176 2177 tokenizer.getThis(Token.T_VALUE); 2178 tokenizer.getThis(Token.T_FOR); 2179 2180 String name = tokenizer.getName(); 2181 String schemaname = tokenizer.getLongNameFirst(); 2182 2183 schemaname = session.getSchemaName(schemaname); 2184 2185 tokenizer.getString(); 2189 2190 NumberSequence sequence = database.schemaManager.getSequence(name, 2191 schemaname); 2192 2193 return new Expression(sequence); 2194 } 2195 2196 2199 private Expression readTrimExpression() throws HsqlException { 2200 2201 read(); 2202 readThis(Expression.OPEN); 2203 2204 String type = sToken; 2205 2206 if (Expression.SQL_TRIM_SPECIFICATION.contains(type)) { 2207 read(); 2208 } else { 2209 type = Token.T_BOTH; 2210 } 2211 2212 String trimstr; 2213 2214 if (sToken.length() == 1) { 2215 trimstr = sToken; 2216 2217 read(); 2218 } else { 2219 trimstr = " "; 2220 } 2221 2222 readThis(Expression.FROM); 2223 2224 Expression trim = new Expression(Types.CHAR, trimstr); 2225 Expression leading; 2226 Expression trailing; 2227 2228 if (type.equals(Token.T_LEADING)) { 2229 leading = new Expression(true); 2230 trailing = new Expression(false); 2231 } else if (type.equals(Token.T_TRAILING)) { 2232 leading = new Expression(false); 2233 trailing = new Expression(true); 2234 } else { 2235 leading = trailing = new Expression(true); 2236 } 2237 2238 Function f = new Function(Token.T_TRIM, "org.hsqldb.Library.trim", 2240 false); 2241 2242 f.setArgument(0, readOr()); 2243 f.setArgument(1, trim); 2244 f.setArgument(2, leading); 2245 f.setArgument(3, trailing); 2246 readThis(Expression.CLOSE); 2247 2248 return new Expression(f); 2249 } 2250 2251 2254 Expression readDefaultClause(int dataType) throws HsqlException { 2255 2256 Expression r = null; 2257 2258 read(); 2259 2260 switch (iToken) { 2261 2262 case Expression.COLUMN : { 2263 String name = sToken; 2264 String javaName = (String ) simpleFunctions.get(name); 2265 2266 if (javaName != null) { 2267 Function f = new Function(name, javaName, true); 2268 2269 return new Expression(f); 2270 } 2271 2272 break; 2273 } 2274 case Expression.NEGATE : { 2275 int exprType = iToken; 2276 2277 read(); 2278 2279 if (iToken == Expression.VALUE) { 2280 oData = Column.convertObject(oData, dataType); 2281 2282 return new Expression(exprType, 2283 new Expression(dataType, oData), 2284 null); 2285 } 2286 2287 break; 2288 } 2289 case Expression.VALUE : { 2290 String name = sToken.toUpperCase(Locale.ENGLISH); 2291 String javaName = (String ) simpleFunctions.get(name); 2292 2293 if (Types.isDatetimeType(dataType) && javaName != null) { 2294 Function f = new Function(name, javaName, true); 2295 2296 return new Expression(f); 2297 } 2298 2299 oData = Column.convertObject(oData, dataType); 2300 2301 return new Expression(dataType, oData); 2302 } 2303 } 2304 2305 throw Trace.error(Trace.WRONG_DEFAULT_CLAUSE, sToken); 2306 } 2307 2308 2313 private void read() throws HsqlException { 2314 2315 sToken = tokenizer.getString(); 2316 wasQuoted = tokenizer.wasQuotedIdentifier(); 2317 2318 if (tokenizer.wasValue()) { 2319 iToken = Expression.VALUE; 2320 oData = tokenizer.getAsValue(); 2321 iType = tokenizer.getType(); 2322 } else if (tokenizer.wasSimpleName()) { 2323 iToken = Expression.COLUMN; 2324 sTable = null; 2325 } else if (tokenizer.wasLongName()) { 2326 sSchema = tokenizer.getLongNamePre(); 2327 sTable = tokenizer.getLongNameFirst(); 2328 2329 if (sToken.equals(Token.T_MULTIPLY)) { 2330 iToken = Expression.MULTIPLY; 2331 } else { 2332 iToken = Expression.COLUMN; 2333 } 2334 } else if (tokenizer.wasParameter()) { 2335 iToken = Expression.PARAM; 2336 } else if (sToken.length() == 0) { 2337 iToken = Expression.END; 2338 } else { 2339 iToken = tokenSet.get(sToken, -1); 2340 2341 if (iToken == -1) { 2342 iToken = Expression.END; 2343 } 2344 2345 switch (iToken) { 2346 2347 case Expression.COMMA : 2348 case Expression.EQUAL : 2349 case Expression.NOT_EQUAL : 2350 case Expression.SMALLER : 2351 case Expression.BIGGER : 2352 case Expression.SMALLER_EQUAL : 2353 case Expression.BIGGER_EQUAL : 2354 case Expression.AND : 2355 case Expression.OR : 2356 case Expression.NOT : 2357 case Expression.ALL : 2358 case Expression.ANY : 2359 case Expression.IN : 2360 case Expression.EXISTS : 2361 case Expression.BETWEEN : 2362 case Expression.PLUS : 2363 case Expression.NEGATE : 2364 case Expression.DIVIDE : 2365 case Expression.CONCAT : 2366 case Expression.OPEN : 2367 case Expression.CLOSE : 2368 case Expression.SELECT : 2369 case Expression.LIKE : 2370 case Expression.COUNT : 2371 case Expression.SUM : 2372 case Expression.MIN : 2373 case Expression.MAX : 2374 case Expression.AVG : 2375 case Expression.EVERY : 2376 case Expression.SOME : 2377 case Expression.STDDEV_POP : 2378 case Expression.STDDEV_SAMP : 2379 case Expression.VAR_POP : 2380 case Expression.VAR_SAMP : 2381 case Expression.CONVERT : 2382 case Expression.CAST : 2383 case Expression.SEQUENCE : 2384 case Expression.IFNULL : 2385 case Expression.COALESCE : 2386 case Expression.NULLIF : 2387 case Expression.CASE : 2388 case Expression.WHEN : 2389 case Expression.THEN : 2390 case Expression.ELSE : 2391 case Expression.ENDWHEN : 2392 case Expression.CASEWHEN : 2393 case Expression.EXTRACT : 2394 case Expression.POSITION : 2395 case Expression.SUBSTRING : 2396 case Expression.FROM : 2397 case Expression.FOR : 2398 case Expression.END : 2399 case Expression.PARAM : 2400 case Expression.TRIM : 2401 case Expression.LEADING : 2402 case Expression.TRAILING : 2403 case Expression.BOTH : 2404 case Expression.AS : 2405 case Expression.IS : 2406 case Expression.DISTINCT : 2407 break; 2409 case Expression.MULTIPLY : 2410 sTable = null; break; 2412 2413 default : 2414 iToken = Expression.END; 2415 } 2416 } 2417 } 2418 2419 2425 private void readToken() throws HsqlException { 2426 sToken = tokenizer.getString(); 2427 iToken = tokenSet.get(sToken, -1); 2428 } 2429 2430 private static IntValueHashMap tokenSet = new IntValueHashMap(37); 2431 2432 static { 2433 tokenSet.put(Token.T_COMMA, Expression.COMMA); 2434 tokenSet.put(Token.T_EQUALS, Expression.EQUAL); 2435 tokenSet.put("!=", Expression.NOT_EQUAL); 2436 tokenSet.put("<>", Expression.NOT_EQUAL); 2437 tokenSet.put("<", Expression.SMALLER); 2438 tokenSet.put(">", Expression.BIGGER); 2439 tokenSet.put("<=", Expression.SMALLER_EQUAL); 2440 tokenSet.put(">=", Expression.BIGGER_EQUAL); 2441 tokenSet.put(Token.T_AND, Expression.AND); 2442 tokenSet.put(Token.T_NOT, Expression.NOT); 2443 tokenSet.put(Token.T_OR, Expression.OR); 2444 tokenSet.put(Token.T_ALL, Expression.ALL); 2445 tokenSet.put(Token.T_ANY, Expression.ANY); 2446 tokenSet.put(Token.T_IN, Expression.IN); 2447 tokenSet.put(Token.T_EXISTS, Expression.EXISTS); 2448 tokenSet.put(Token.T_BETWEEN, Expression.BETWEEN); 2449 tokenSet.put(Token.T_PLUS, Expression.PLUS); 2450 tokenSet.put("-", Expression.NEGATE); 2451 tokenSet.put(Token.T_MULTIPLY, Expression.MULTIPLY); 2452 tokenSet.put("/", Expression.DIVIDE); 2453 tokenSet.put("||", Expression.CONCAT); 2454 tokenSet.put(Token.T_OPENBRACKET, Expression.OPEN); 2455 tokenSet.put(Token.T_CLOSEBRACKET, Expression.CLOSE); 2456 tokenSet.put(Token.T_SELECT, Expression.SELECT); 2457 tokenSet.put(Token.T_LIKE, Expression.LIKE); 2458 tokenSet.put(Token.T_COUNT, Expression.COUNT); 2459 tokenSet.put(Token.T_SUM, Expression.SUM); 2460 tokenSet.put(Token.T_MIN, Expression.MIN); 2461 tokenSet.put(Token.T_MAX, Expression.MAX); 2462 tokenSet.put(Token.T_AVG, Expression.AVG); 2463 tokenSet.put(Token.T_EVERY, Expression.EVERY); 2464 tokenSet.put(Token.T_SOME, Expression.SOME); 2465 tokenSet.put(Token.T_STDDEV_POP, Expression.STDDEV_POP); 2466 tokenSet.put(Token.T_STDDEV_SAMP, Expression.STDDEV_SAMP); 2467 tokenSet.put(Token.T_VAR_POP, Expression.VAR_POP); 2468 tokenSet.put(Token.T_VAR_SAMP, Expression.VAR_SAMP); 2469 tokenSet.put(Token.T_IFNULL, Expression.IFNULL); 2470 tokenSet.put(Token.T_NVL, Expression.IFNULL); 2471 tokenSet.put(Token.T_NULLIF, Expression.NULLIF); 2472 tokenSet.put(Token.T_CONVERT, Expression.CONVERT); 2473 tokenSet.put(Token.T_CAST, Expression.CAST); 2474 tokenSet.put(Token.T_NEXT, Expression.SEQUENCE); 2475 tokenSet.put(Token.T_CASE, Expression.CASE); 2476 tokenSet.put(Token.T_WHEN, Expression.WHEN); 2477 tokenSet.put(Token.T_THEN, Expression.THEN); 2478 tokenSet.put(Token.T_ELSE, Expression.ELSE); 2479 tokenSet.put(Token.T_END, Expression.ENDWHEN); 2480 tokenSet.put(Token.T_CASEWHEN, Expression.CASEWHEN); 2481 tokenSet.put(Token.T_COALESCE, Expression.COALESCE); 2482 tokenSet.put(Token.T_EXTRACT, Expression.EXTRACT); 2483 tokenSet.put(Token.T_POSITION, Expression.POSITION); 2484 tokenSet.put(Token.T_FROM, Expression.FROM); 2485 tokenSet.put(Token.T_TRIM, Expression.TRIM); 2486 tokenSet.put(Token.T_SUBSTRING, Expression.SUBSTRING); 2487 tokenSet.put(Token.T_FOR, Expression.FOR); 2488 tokenSet.put(Token.T_AS, Expression.AS); 2489 tokenSet.put(Token.T_IS, Expression.IS); 2490 tokenSet.put(Token.T_QUESTION, Expression.PARAM); 2491 } 2492 2493 HsqlArrayList parameters = new HsqlArrayList(); 2496 private static final Expression[] noParameters = new Expression[0]; 2497 private static final SubQuery[] noSubqueries = new SubQuery[0]; 2498 2499 2502 Expression[] getParameters() { 2503 2504 Expression[] result = parameters.size() == 0 ? noParameters 2505 : (Expression[]) parameters.toArray( 2506 new Expression[parameters.size()]); 2507 2508 parameters.clear(); 2509 2510 return result; 2511 } 2512 2513 void clearParameters() { 2514 parameters.clear(); 2515 } 2516 2517 2519 2522 void setAsView(View view) { 2523 2524 for (int i = 0; i < subQueryList.size(); i++) { 2525 SubQuery sq = (SubQuery) subQueryList.get(i); 2526 2527 if (sq.view == null) { 2528 sq.view = view; 2529 } 2530 } 2531 } 2532 2533 2537 SubQuery[] getSortedSubqueries() { 2538 2539 if (subQueryList.size() == 0) { 2540 return noSubqueries; 2541 } 2542 2543 subQueryList.sort((SubQuery) subQueryList.get(0)); 2544 2545 SubQuery[] subqueries = new SubQuery[subQueryList.size()]; 2546 2547 subQueryList.toArray(subqueries); 2548 subQueryList.clear(); 2549 2550 return subqueries; 2551 } 2552 2553 2556 CompiledStatement compileCallStatement() throws HsqlException { 2557 2558 clearParameters(); 2559 2560 Expression expression = parseExpression(); 2561 CompiledStatement cs = new CompiledStatement(session, database, 2562 session.currentSchema, expression, getSortedSubqueries(), 2563 getParameters()); 2564 2565 return cs; 2566 } 2567 2568 2571 CompiledStatement compileDeleteStatement() throws HsqlException { 2572 2573 String token; 2574 Expression condition = null; 2575 TableFilter tableFilter; 2576 2577 clearParameters(); 2578 tokenizer.getThis(Token.T_FROM); 2579 2580 tableFilter = parseSimpleTableFilter(UserManager.DELETE); 2581 token = tokenizer.getString(); 2582 2583 if (token.equals(Token.T_WHERE)) { 2584 condition = parseExpression(); 2585 } else { 2586 tokenizer.back(); 2587 } 2588 2589 CompiledStatement cs = new CompiledStatement(session, database, 2590 session.currentSchema, tableFilter, condition, 2591 getSortedSubqueries(), getParameters()); 2592 2593 return cs; 2594 } 2595 2596 private void getInsertColumnValueExpressions(Table t, Expression[] acve, 2597 int len) throws HsqlException { 2598 2599 tokenizer.getThis(Token.T_OPENBRACKET); 2600 2601 for (int i = 0; i < len; i++) { 2602 Expression columnValExpression = parseExpression(); 2603 2604 columnValExpression.resolveTables(null); 2605 columnValExpression.resolveTypes(session); 2606 2607 acve[i] = columnValExpression; 2608 2609 String token = tokenizer.getSimpleToken(); 2610 2611 if (token.equals(Token.T_COMMA)) { 2612 continue; 2613 } 2614 2615 if (token.equals(Token.T_CLOSEBRACKET)) { 2616 if (i == len - 1) { 2617 return; 2618 } else { 2619 break; 2620 } 2621 } 2622 2623 tokenizer.throwUnexpected(); 2624 } 2625 2626 throw Trace.error(Trace.COLUMN_COUNT_DOES_NOT_MATCH); 2627 } 2628 2629 2632 CompiledStatement compileInsertStatement() throws HsqlException { 2633 2634 clearParameters(); 2635 tokenizer.getThis(Token.T_INTO); 2636 2637 HsqlArrayList columnNames; 2638 boolean[] columnCheckList; 2639 int[] columnMap; 2640 int len; 2641 String token = tokenizer.getName(); 2642 String schema = session.getSchemaName(tokenizer.getLongNameFirst()); 2643 Table table = database.schemaManager.getTable(session, token, schema); 2644 2645 checkTableWriteAccess(table, UserManager.INSERT); 2646 2647 columnNames = null; 2648 columnCheckList = null; 2649 columnMap = table.getColumnMap(); 2650 len = table.getColumnCount(); 2651 2652 int brackets = parseOpenBrackets(); 2653 2654 token = tokenizer.getString(); 2655 2656 if (brackets == 1 &&!tokenizer.wasThis(Token.T_SELECT)) { 2657 brackets = 0; 2658 2659 tokenizer.back(); 2660 2661 columnNames = getColumnNames(database, table, tokenizer, false); 2662 2663 if (columnNames.size() > len) { 2664 throw Trace.error(Trace.COLUMN_COUNT_DOES_NOT_MATCH); 2665 } 2666 2667 len = columnNames.size(); 2668 columnCheckList = table.getNewColumnCheckList(); 2669 columnMap = new int[len]; 2670 2671 for (int i = 0; i < len; i++) { 2672 int ci = table.getColumnNr((String ) columnNames.get(i)); 2673 2674 columnMap[i] = ci; 2675 columnCheckList[ci] = true; 2676 } 2677 2678 token = tokenizer.getSimpleToken(); 2679 } else if (!tokenizer.wasSimpleToken()) { 2680 tokenizer.throwUnexpected(); 2681 } 2682 2683 int command = Token.get(token); 2684 2685 switch (command) { 2686 2687 case Token.VALUES : { 2688 Expression[] acve = new Expression[len]; 2689 2690 getInsertColumnValueExpressions(table, acve, len); 2691 2692 CompiledStatement cs = 2693 new CompiledStatement(session.currentSchema, table, 2694 columnMap, acve, columnCheckList, 2695 getSortedSubqueries(), 2696 getParameters()); 2697 2698 return cs; 2699 } 2700 case Token.OPENBRACKET : { 2701 brackets = parseOpenBrackets() + 1; 2702 2703 tokenizer.getThis(Token.T_SELECT); 2704 } 2705 case Token.SELECT : { 2706 2707 Select select = parseSelect(brackets, true, false, true, 2709 true); 2710 2711 if (len != select.iResultLen) { 2712 throw Trace.error(Trace.COLUMN_COUNT_DOES_NOT_MATCH); 2713 } 2714 2715 CompiledStatement cs = new CompiledStatement(session, 2716 database, session.currentSchema, table, columnMap, 2717 columnCheckList, select, getSortedSubqueries(), 2718 getParameters()); 2719 2720 return cs; 2721 } 2722 default : { 2723 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 2724 } 2725 } 2726 } 2727 2728 2731 CompiledStatement compileSelectStatement(int brackets) 2732 throws HsqlException { 2733 2734 clearParameters(); 2735 2736 Select select = parseSelect(brackets, true, true, false, true); 2737 2738 if (select.sIntoTable != null) { 2739 String name = select.sIntoTable.name; 2740 String schema = select.sIntoTable.schema.name; 2741 2742 if (database.schemaManager.findUserTable(session, name, schema) 2743 != null) { 2744 throw Trace.error(Trace.TABLE_ALREADY_EXISTS, name); 2745 } 2746 } 2747 2748 CompiledStatement cs = new CompiledStatement(session, database, 2749 session.currentSchema, select, getSortedSubqueries(), 2750 getParameters()); 2751 2752 return cs; 2753 } 2754 2755 2758 CompiledStatement compileUpdateStatement() throws HsqlException { 2759 2760 String token; 2761 Table table; 2762 int[] colList; 2763 Expression[] exprList; 2764 int len; 2765 Expression cve; 2766 Expression condition; 2767 2768 clearParameters(); 2769 2770 TableFilter tableFilter = parseSimpleTableFilter(UserManager.UPDATE); 2771 2772 table = tableFilter.filterTable; 2773 2774 tokenizer.getThis(Token.T_SET); 2775 2776 colList = table.getNewColumnMap(); 2777 exprList = new Expression[colList.length]; 2778 len = 0; 2779 token = null; 2780 2781 do { 2782 int ci = table.getColumnNr(tokenizer.getName()); 2783 String tablename = tokenizer.getLongNameFirst(); 2784 2785 if (tablename != null 2786 &&!tableFilter.getName().equals(tablename)) { 2787 throw Trace.error(Trace.TABLE_NOT_FOUND); 2788 } 2789 2790 tokenizer.getThis(Token.T_EQUALS); 2791 2792 cve = parseExpression(); 2793 2794 if (len == colList.length) { 2795 2796 throw Trace.error(Trace.COLUMN_COUNT_DOES_NOT_MATCH); 2798 } 2799 2800 colList[len] = ci; 2801 exprList[len] = cve; 2802 token = tokenizer.getSimpleToken(); 2803 2804 len++; 2805 } while (token.equals(Token.T_COMMA)); 2806 2807 condition = null; 2808 2809 if (token.equals(Token.T_WHERE)) { 2810 condition = parseExpression(); 2811 } else { 2812 tokenizer.back(); 2813 } 2814 2815 colList = (int[]) ArrayUtil.resizeArray(colList, len); 2816 exprList = (Expression[]) ArrayUtil.resizeArray(exprList, len); 2817 2818 CompiledStatement cs = new CompiledStatement(session, database, 2819 session.currentSchema, tableFilter, colList, exprList, condition, 2820 getSortedSubqueries(), getParameters()); 2821 2822 return cs; 2823 } 2824 2825 int parseOpenBracketsSelect() throws HsqlException { 2826 2827 int count = parseOpenBrackets(); 2828 2829 tokenizer.getThis(Token.T_SELECT); 2830 2831 return count; 2832 } 2833 2834 int parseOpenBrackets() throws HsqlException { 2835 2836 int count = 0; 2837 2838 while (tokenizer.isGetThis(Token.T_OPENBRACKET)) { 2839 count++; 2840 } 2841 2842 return count; 2843 } 2844 2845 int parseCloseBrackets(int limit) throws HsqlException { 2846 2847 int count = 0; 2848 2849 while (count < limit && tokenizer.isGetThis(Token.T_CLOSEBRACKET)) { 2850 count++; 2851 } 2852 2853 return count; 2854 } 2855 2856 HashMappedList parseColumnList() throws HsqlException { 2857 return processColumnList(tokenizer, false); 2858 } 2859 2860 static HashMappedList processColumnList(Tokenizer tokenizer, 2861 boolean acceptAscDesc) throws HsqlException { 2862 2863 HashMappedList list; 2864 String token; 2865 2866 list = new HashMappedList(); 2867 2868 tokenizer.getThis(Token.T_OPENBRACKET); 2869 2870 while (true) { 2871 token = tokenizer.getSimpleName(); 2872 2873 boolean result = list.add(token, null); 2874 2875 if (!result) { 2876 throw Trace.error(Trace.COLUMN_ALREADY_EXISTS, token); 2877 } 2878 2879 token = tokenizer.getSimpleToken(); 2880 2881 if (acceptAscDesc 2882 && (token.equals(Token.T_DESC) 2883 || token.equals(Token.T_ASC))) { 2884 token = tokenizer.getSimpleToken(); } 2886 2887 if (token.equals(Token.T_COMMA)) { 2888 continue; 2889 } 2890 2891 if (token.equals(Token.T_CLOSEBRACKET)) { 2892 break; 2893 } 2894 2895 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 2896 } 2897 2898 return list; 2899 } 2900} 2901 | Popular Tags |