1 65 66 67 package org.hsqldb; 68 69 import java.io.IOException ; 70 import java.io.LineNumberReader ; 71 import java.io.StringReader ; 72 import java.util.Locale ; 73 74 import org.hsqldb.HsqlNameManager.HsqlName; 75 import org.hsqldb.lib.ArrayUtil; 76 import org.hsqldb.lib.HashMappedList; 77 import org.hsqldb.lib.HsqlArrayList; 78 import org.hsqldb.lib.StringUtil; 79 import org.hsqldb.lib.java.JavaSystem; 80 import org.hsqldb.persist.HsqlDatabaseProperties; 81 import org.hsqldb.scriptio.ScriptWriterBase; 82 import org.hsqldb.scriptio.ScriptWriterText; 83 84 95 96 class DatabaseCommandInterpreter { 113 114 private Tokenizer tokenizer = new Tokenizer(); 115 private Database database; 116 private Session session; 117 118 123 DatabaseCommandInterpreter(Session s) { 124 session = s; 125 database = s.getDatabase(); 126 } 127 128 135 Result execute(String sql) { 136 137 Result result; 138 String token; 139 int cmd; 140 141 JavaSystem.gc(); 142 143 result = null; 144 cmd = Token.UNKNOWNTOKEN; 145 146 try { 147 tokenizer.reset(sql); 148 149 while (true) { 150 tokenizer.setPartMarker(); 151 session.setScripting(false); 152 153 token = tokenizer.getSimpleToken(); 154 155 if (token.length() == 0) { 156 session.endSchemaDefinition(); 157 158 break; 159 } 160 161 cmd = Token.get(token); 162 163 if (cmd == Token.SEMICOLON) { 164 session.endSchemaDefinition(); 165 166 continue; 167 } 168 169 result = executePart(cmd, token); 170 171 if (result.isError()) { 172 session.endSchemaDefinition(); 173 174 break; 175 } 176 177 if (session.getScripting()) { 178 database.logger.writeToLog(session, 179 tokenizer.getLastPart()); 180 } 181 } 182 } catch (Throwable t) { 183 try { 184 if (session.isSchemaDefintion()) { 185 HsqlName schemaName = session.getSchemaHsqlName(null); 186 187 database.schemaManager.dropSchema(schemaName.name, true); 188 database.logger.writeToLog(session, 189 Token.T_DROP + ' ' 190 + Token.T_SCHEMA + ' ' 191 + schemaName.statementName 192 + ' ' + Token.T_CASCADE); 193 session.endSchemaDefinition(); 194 } 195 } catch (HsqlException e) {} 196 197 result = new Result(t, tokenizer.getLastPart()); 198 } 199 200 return result == null ? Session.emptyUpdateCount 201 : result; 202 } 203 204 private Result executePart(int cmd, String token) throws Throwable { 205 206 Result result = Session.emptyUpdateCount; 207 int brackets = 0; 208 209 if (session.isSchemaDefintion()) { 210 switch (cmd) { 211 212 case Token.CREATE : 213 case Token.GRANT : 214 break; 215 216 default : 217 throw Trace.error(Trace.INVALID_IDENTIFIER, 218 Trace.IN_SCHEMA_DEFINITION, 219 new Object []{ token }); 220 } 221 } 222 223 switch (cmd) { 224 225 case Token.OPENBRACKET : { 226 Parser parser = new Parser(session, database, tokenizer); 227 228 brackets = parser.parseOpenBracketsSelect() + 1; 229 } 230 case Token.SELECT : { 231 Parser parser = new Parser(session, database, tokenizer); 232 CompiledStatement cStatement = 233 parser.compileSelectStatement(brackets); 234 235 if (cStatement.parameters.length != 0) { 236 Trace.doAssert( 237 false, 238 Trace.getMessage( 239 Trace.ASSERT_DIRECT_EXEC_WITH_PARAM)); 240 } 241 242 result = session.sqlExecuteCompiledNoPreChecks(cStatement, 243 null); 244 245 break; 246 } 247 case Token.INSERT : { 248 Parser parser = new Parser(session, database, tokenizer); 249 CompiledStatement cStatement = 250 parser.compileInsertStatement(); 251 252 if (cStatement.parameters.length != 0) { 253 Trace.doAssert( 254 false, 255 Trace.getMessage( 256 Trace.ASSERT_DIRECT_EXEC_WITH_PARAM)); 257 } 258 259 result = session.sqlExecuteCompiledNoPreChecks(cStatement, 260 null); 261 262 break; 263 } 264 case Token.UPDATE : { 265 Parser parser = new Parser(session, database, tokenizer); 266 CompiledStatement cStatement = 267 parser.compileUpdateStatement(); 268 269 if (cStatement.parameters.length != 0) { 270 Trace.doAssert( 271 false, 272 Trace.getMessage( 273 Trace.ASSERT_DIRECT_EXEC_WITH_PARAM)); 274 } 275 276 result = session.sqlExecuteCompiledNoPreChecks(cStatement, 277 null); 278 279 break; 280 } 281 case Token.DELETE : { 282 Parser parser = new Parser(session, database, tokenizer); 283 CompiledStatement cStatement = 284 parser.compileDeleteStatement(); 285 286 if (cStatement.parameters.length != 0) { 287 Trace.doAssert( 288 false, 289 Trace.getMessage( 290 Trace.ASSERT_DIRECT_EXEC_WITH_PARAM)); 291 } 292 293 result = session.sqlExecuteCompiledNoPreChecks(cStatement, 294 null); 295 296 break; 297 } 298 case Token.CALL : { 299 Parser parser = new Parser(session, database, tokenizer); 300 CompiledStatement cStatement = parser.compileCallStatement(); 301 302 if (cStatement.parameters.length != 0) { 303 Trace.doAssert( 304 false, 305 Trace.getMessage( 306 Trace.ASSERT_DIRECT_EXEC_WITH_PARAM)); 307 } 308 309 result = session.sqlExecuteCompiledNoPreChecks(cStatement, 310 null); 311 312 break; 313 } 314 case Token.SET : 315 processSet(); 316 break; 317 318 case Token.COMMIT : 319 processCommit(); 320 break; 321 322 case Token.ROLLBACK : 323 processRollback(); 324 break; 325 326 case Token.SAVEPOINT : 327 processSavepoint(); 328 break; 329 330 case Token.RELEASE : 331 processReleaseSavepoint(); 332 break; 333 334 case Token.CREATE : 335 processCreate(); 336 database.setMetaDirty(false); 337 break; 338 339 case Token.ALTER : 340 processAlter(); 341 database.setMetaDirty(true); 342 break; 343 344 case Token.DROP : 345 processDrop(); 346 database.setMetaDirty(true); 347 break; 348 349 case Token.GRANT : 350 processGrantOrRevoke(true); 351 database.setMetaDirty(false); 352 break; 353 354 case Token.REVOKE : 355 processGrantOrRevoke(false); 356 database.setMetaDirty(true); 357 break; 358 359 case Token.CONNECT : 360 processConnect(); 361 database.setMetaDirty(false); 362 session.setScripting(false); 363 break; 364 365 case Token.DISCONNECT : 366 processDisconnect(); 367 session.setScripting(true); 368 break; 369 370 case Token.SCRIPT : 371 result = processScript(); 372 break; 373 374 case Token.SHUTDOWN : 375 processShutdown(); 376 break; 377 378 case Token.CHECKPOINT : 379 processCheckpoint(); 380 break; 381 382 case Token.EXPLAIN : 383 result = processExplainPlan(); 384 break; 385 386 default : 387 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 388 } 389 390 return result; 391 } 392 393 400 private Result processScript() throws IOException , HsqlException { 401 402 String token = tokenizer.getString(); 403 ScriptWriterText dsw = null; 404 405 session.checkAdmin(); 406 407 try { 408 if (tokenizer.wasValue()) { 409 if (tokenizer.getType() != Types.VARCHAR) { 410 throw Trace.error(Trace.INVALID_IDENTIFIER); 411 } 412 413 dsw = new ScriptWriterText(database, token, true, true, true); 414 415 dsw.writeAll(); 416 417 return new Result(ResultConstants.UPDATECOUNT); 418 } else { 419 tokenizer.back(); 420 421 return DatabaseScript.getScript(database, false); 422 } 423 } finally { 424 if (dsw != null) { 425 dsw.close(); 426 } 427 } 428 } 429 430 441 private void processCreate() throws HsqlException { 442 443 boolean unique = false; 444 int tableType; 445 boolean isTempTable = false; 446 String token; 447 448 session.checkAdmin(); 449 session.checkDDLWrite(); 450 session.setScripting(true); 451 452 if (tokenizer.isGetThis(Token.T_GLOBAL)) { 453 tokenizer.getThis(Token.T_TEMPORARY); 454 455 isTempTable = true; 456 } else if (tokenizer.isGetThis(Token.T_TEMP)) { 457 isTempTable = true; 458 } else if (tokenizer.isGetThis(Token.T_TEMPORARY)) { 459 isTempTable = true; 460 } 461 462 token = tokenizer.getSimpleToken(); 463 464 switch (Token.get(token)) { 465 466 case Token.MEMORY : 468 tokenizer.getThis(Token.T_TABLE); 469 case Token.TABLE : 470 tableType = isTempTable ? Table.TEMP_TABLE 471 : database.getDefaultTableType(); 472 473 processCreateTable(tableType); 474 475 return; 476 477 case Token.CACHED : 478 if (isTempTable) { 479 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 480 } 481 482 tokenizer.getThis(Token.T_TABLE); 483 processCreateTable(Table.CACHED_TABLE); 484 485 return; 486 487 case Token.TEXT : 488 if (isTempTable) { 489 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 490 } 491 492 tokenizer.getThis(Token.T_TABLE); 493 processCreateTable(Table.TEXT_TABLE); 494 495 return; 496 497 default : 498 if (isTempTable) { 499 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 500 } 501 } 502 503 switch (Token.get(token)) { 504 505 case Token.ALIAS : 507 processCreateAlias(); 508 break; 509 510 case Token.SEQUENCE : 511 processCreateSequence(); 512 break; 513 514 case Token.SCHEMA : 515 session.setScripting(false); 516 processCreateSchema(); 517 break; 518 519 case Token.TRIGGER : 520 processCreateTrigger(); 521 break; 522 523 case Token.USER : 524 processCreateUser(); 525 break; 526 527 case Token.ROLE : 528 database.getGranteeManager().addRole(getUserIdentifier()); 529 break; 530 531 case Token.VIEW : 532 processCreateView(); 533 break; 534 535 case Token.UNIQUE : 537 unique = true; 538 539 tokenizer.getThis(Token.T_INDEX); 540 541 case Token.INDEX : 543 processCreateIndex(unique); 544 break; 545 546 default : { 547 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 548 } 549 } 550 } 551 552 561 private int[] processColumnList(Table t, 562 boolean acceptAscDesc) 563 throws HsqlException { 564 565 HashMappedList list = Parser.processColumnList(tokenizer, 566 acceptAscDesc); 567 int size = list.size(); 568 int[] col = new int[size]; 569 570 for (int i = 0; i < size; i++) { 571 col[i] = t.getColumnNr((String ) list.getKey(i)); 572 } 573 574 return col; 575 } 576 577 585 private void processCreateTrigger() throws HsqlException { 586 587 Table t; 588 boolean isForEach; 589 boolean isNowait; 590 int queueSize; 591 String triggerName; 592 boolean isQuoted; 593 String sWhen; 594 String sOper; 595 String tableName; 596 String token; 597 String className; 598 TriggerDef td; 599 Trigger o; 600 601 triggerName = tokenizer.getName(); 602 603 String schemaname = tokenizer.getLongNameFirst(); 604 605 database.schemaManager.checkTriggerExists(triggerName, 606 session.getSchemaNameForWrite(schemaname), false); 607 608 isQuoted = tokenizer.wasQuotedIdentifier(); 609 isForEach = false; 610 isNowait = false; 611 queueSize = TriggerDef.getDefaultQueueSize(); 612 sWhen = tokenizer.getSimpleToken(); 613 sOper = tokenizer.getSimpleToken(); 614 615 tokenizer.getThis(Token.T_ON); 616 617 tableName = tokenizer.getName(); 618 619 if (schemaname == null) { 620 schemaname = 621 session.getSchemaNameForWrite(tokenizer.getLongNameFirst()); 622 } else if (!schemaname.equals( 623 session.getSchemaNameForWrite( 624 tokenizer.getLongNameFirst()))) { 625 throw Trace.error(Trace.INVALID_SCHEMA_NAME_NO_SUBCLASS); 626 } 627 628 t = database.schemaManager.getUserTable(session, tableName, 629 schemaname); 630 631 if (t.isView()) { 632 throw Trace.error(Trace.NOT_A_TABLE); 633 } 634 635 session.setScripting(true); 636 637 token = tokenizer.getSimpleToken(); 639 640 if (token.equals(Token.T_FOR)) { 641 token = tokenizer.getSimpleToken(); 642 643 if (token.equals(Token.T_EACH)) { 644 token = tokenizer.getSimpleToken(); 645 646 if (token.equals(Token.T_ROW)) { 647 isForEach = true; 648 649 token = tokenizer.getSimpleToken(); 651 } else { 652 throw Trace.error(Trace.UNEXPECTED_END_OF_COMMAND, token); 653 } 654 } else { 655 throw Trace.error(Trace.UNEXPECTED_END_OF_COMMAND, token); 656 } 657 } 658 659 if (token.equals(Token.T_NOWAIT)) { 660 isNowait = true; 661 662 token = tokenizer.getSimpleToken(); 664 } 665 666 if (token.equals(Token.T_QUEUE)) { 667 queueSize = tokenizer.getInt(); 668 669 token = tokenizer.getSimpleToken(); 671 } 672 673 if (!token.equals(Token.T_CALL)) { 674 throw Trace.error(Trace.UNEXPECTED_END_OF_COMMAND, token); 675 } 676 677 className = tokenizer.getSimpleName(); 678 679 if (!tokenizer.wasQuotedIdentifier()) { 680 throw Trace.error(Trace.UNEXPECTED_END_OF_COMMAND, className); 681 } 682 683 HsqlName name = database.nameManager.newHsqlName(triggerName, 684 isQuoted); 685 686 td = new TriggerDef(name, sWhen, sOper, isForEach, t, className, 687 isNowait, queueSize, database.classLoader); 688 689 t.addTrigger(td); 690 691 if (td.isValid()) { 692 try { 693 694 td.start(); 696 } catch (Exception e) { 697 throw Trace.error(Trace.UNKNOWN_FUNCTION, e.toString()); 698 } 699 } 700 701 database.schemaManager.registerTriggerName(triggerName, t.getName()); 702 703 } 705 706 private Column processCreateColumn() throws HsqlException { 707 708 String token = tokenizer.getSimpleName(); 709 boolean isQuoted = tokenizer.wasQuotedIdentifier(); 710 HsqlName hsqlName = database.nameManager.newHsqlName(token, isQuoted); 711 712 return processCreateColumn(hsqlName); 713 } 714 715 723 private Column processCreateColumn(HsqlName hsqlName) 724 throws HsqlException { 725 726 boolean isIdentity = false; 727 long identityStart = database.firstIdentity; 728 long identityIncrement = 1; 729 boolean isPrimaryKey = false; 730 String typeName; 731 int type; 732 int length = 0; 733 int scale = 0; 734 boolean hasLength = false; 735 boolean isNullable = true; 736 Expression defaultExpr = null; 737 String token; 738 739 typeName = tokenizer.getSimpleToken(); 740 type = Types.getTypeNr(typeName); 741 742 if (type == Types.CHAR) { 743 if (tokenizer.isGetThis(Token.T_VARYING)) { 744 type = Types.VARCHAR; 745 } 746 } 747 748 if (typeName.equals(Token.T_IDENTITY)) { 749 isIdentity = true; 750 isPrimaryKey = true; 751 } 752 753 if (type == Types.DOUBLE) { 755 tokenizer.isGetThis(Token.T_PRECISION); 756 } 757 758 if (tokenizer.isGetThis(Token.T_OPENBRACKET)) { 759 hasLength = true; 760 length = tokenizer.getInt(); 761 762 Trace.check(Types.acceptsPrecisionCreateParam(type), 763 Trace.UNEXPECTED_TOKEN); 764 765 if (type != Types.TIMESTAMP && type != Types.TIME 766 && length == 0) { 767 throw Trace.error(Trace.INVALID_SIZE_PRECISION); 768 } 769 770 if (tokenizer.isGetThis(Token.T_COMMA)) { 771 Trace.check(Types.acceptsScaleCreateParam(type), 772 Trace.UNEXPECTED_TOKEN); 773 774 scale = tokenizer.getInt(); 775 } 776 777 tokenizer.getThis(Token.T_CLOSEBRACKET); 778 } else if (type == Types.CHAR && database.sqlEnforceStrictSize) { 779 length = 1; 780 } else if (type == Types.VARCHAR && database.sqlEnforceStrictSize) { 781 throw Trace.error(Trace.COLUMN_SIZE_REQUIRED); 782 } 783 784 788 if (type == Types.VARCHAR && database.isIgnoreCase()) { 789 type = Types.VARCHAR_IGNORECASE; 790 } 791 792 if (type == Types.FLOAT && length > 53) { 793 throw Trace.error(Trace.NUMERIC_VALUE_OUT_OF_RANGE); 794 } 795 796 if (type == Types.TIMESTAMP) { 797 if (!hasLength) { 798 length = 6; 799 } else if (length != 0 && length != 6) { 800 throw Trace.error(Trace.NUMERIC_VALUE_OUT_OF_RANGE); 801 } 802 } 803 804 if (type == Types.TIME) { 805 if (length != 0) { 806 throw Trace.error(Trace.NUMERIC_VALUE_OUT_OF_RANGE); 807 } 808 } 809 810 token = tokenizer.getSimpleToken(); 811 812 if (token.equals(Token.T_DEFAULT)) { 813 defaultExpr = processCreateDefaultExpression(type, length, scale); 814 token = tokenizer.getSimpleToken(); 815 } else if (token.equals(Token.T_GENERATED)) { 816 tokenizer.getThis(Token.T_BY); 817 tokenizer.getThis(Token.T_DEFAULT); 818 tokenizer.getThis(Token.T_AS); 819 tokenizer.getThis(Token.T_IDENTITY); 820 821 if (tokenizer.isGetThis(Token.T_OPENBRACKET)) { 822 tokenizer.getThis(Token.T_START); 823 tokenizer.getThis(Token.T_WITH); 824 825 identityStart = tokenizer.getBigint(); 826 827 if (tokenizer.isGetThis(Token.T_COMMA)) { 828 tokenizer.getThis(Token.T_INCREMENT); 829 tokenizer.getThis(Token.T_BY); 830 831 identityIncrement = tokenizer.getBigint(); 832 } 833 834 tokenizer.getThis(Token.T_CLOSEBRACKET); 835 } 836 837 isIdentity = true; 838 isPrimaryKey = true; 839 token = tokenizer.getSimpleToken(); 840 } 841 842 if (token.equals(Token.T_IDENTITY)) { 844 isIdentity = true; 845 isPrimaryKey = true; 846 token = tokenizer.getSimpleToken(); 847 } 848 849 if (token.equals(Token.T_NULL)) { 850 token = tokenizer.getSimpleToken(); 851 } else if (token.equals(Token.T_NOT)) { 852 tokenizer.getThis(Token.T_NULL); 853 854 isNullable = false; 855 token = tokenizer.getSimpleToken(); 856 } 857 858 if (token.equals(Token.T_IDENTITY)) { 859 if (isIdentity) { 860 throw Trace.error(Trace.SECOND_PRIMARY_KEY, Token.T_IDENTITY); 861 } 862 863 isIdentity = true; 864 isPrimaryKey = true; 865 token = tokenizer.getSimpleToken(); 866 } 867 868 if (token.equals(Token.T_PRIMARY)) { 869 tokenizer.getThis(Token.T_KEY); 870 871 isPrimaryKey = true; 872 } else { 873 tokenizer.back(); 874 } 875 876 if (isIdentity && defaultExpr != null) { 878 throw Trace.error(Trace.UNEXPECTED_TOKEN, Token.T_DEFAULT); 879 } 880 881 Column column = new Column(hsqlName, isNullable, type, length, scale, 882 isPrimaryKey, defaultExpr); 883 884 column.setIdentity(isIdentity, identityStart, identityIncrement); 885 886 return column; 887 } 888 889 895 private Expression processCreateDefaultExpression(int type, int length, 896 int scale) throws HsqlException { 897 898 if (type == Types.OTHER) { 899 throw Trace.error(Trace.WRONG_DEFAULT_CLAUSE); 900 } 901 902 Parser parser = new Parser(session, database, tokenizer); 903 Expression expr = parser.readDefaultClause(type); 904 905 expr.resolveTypes(session); 906 907 int newType = expr.getType(); 908 909 if (newType == Expression.VALUE || newType == Expression.TRUE 910 || newType == Expression.FALSE 911 || (newType == Expression.FUNCTION 912 && expr.function.isSimple)) { 913 Object defValTemp; 914 915 try { 916 defValTemp = expr.getValue(session, type); 917 } catch (HsqlException e) { 918 throw Trace.error(Trace.WRONG_DEFAULT_CLAUSE); 919 } 920 921 if (defValTemp != null && database.sqlEnforceStrictSize) { 922 try { 923 Column.enforceSize(defValTemp, type, length, scale, true); 924 } catch (HsqlException e) { 925 926 throw Trace.error(Trace.WRONG_DEFAULT_CLAUSE); 928 } 929 } 930 931 return expr; 932 } 933 934 throw Trace.error(Trace.WRONG_DEFAULT_CLAUSE); 935 } 936 937 public static void checkBooleanDefault(String s, 938 int type) throws HsqlException { 939 940 if (type != Types.BOOLEAN || s == null) { 941 return; 942 } 943 944 s = s.toUpperCase(); 945 946 if (s.equals(Token.T_TRUE) || s.equals(Token.T_FALSE)) { 947 return; 948 } 949 950 if (s.equals("0") || s.equals("1")) { 951 return; 952 } 953 954 throw Trace.error(Trace.WRONG_DEFAULT_CLAUSE, s); 955 } 956 957 966 private HsqlArrayList processCreateConstraints(Table t, 967 boolean constraint, int[] primarykeycolumn) throws HsqlException { 968 969 String token; 970 HsqlArrayList tcList; 971 Constraint tempConst; 972 HsqlName pkHsqlName; 973 974 tcList = new HsqlArrayList(); 979 tempConst = new Constraint(null, primarykeycolumn, null, null, 980 Constraint.MAIN, Constraint.NO_ACTION, 981 Constraint.NO_ACTION); 982 983 pkHsqlName = null; 985 986 tcList.add(tempConst); 987 988 if (!constraint) { 989 return tcList; 990 } 991 992 while (true) { 993 HsqlName cname = null; 994 995 if (tokenizer.isGetThis(Token.T_CONSTRAINT)) { 996 token = tokenizer.getName(); 997 998 String constraintSchema = tokenizer.getLongNameFirst(); 999 1000 if (constraintSchema != null) { 1001 constraintSchema = session.getSchemaNameForWrite( 1002 tokenizer.getLongNameFirst()); 1003 1004 if (!t.getSchemaName().equals(constraintSchema)) { 1005 throw Trace.error( 1006 Trace.INVALID_SCHEMA_NAME_NO_SUBCLASS, 1007 constraintSchema); 1008 } 1009 } 1010 1011 cname = database.nameManager.newHsqlName(token, 1012 tokenizer.wasQuotedIdentifier()); 1013 } 1014 1015 token = tokenizer.getSimpleToken(); 1016 1017 switch (Token.get(token)) { 1018 1019 case Token.PRIMARY : { 1020 tokenizer.getThis(Token.T_KEY); 1021 1022 pkHsqlName = cname; 1024 1025 int[] cols = processColumnList(t, false); 1026 Constraint mainConst; 1027 1028 mainConst = (Constraint) tcList.get(0); 1029 1030 if (mainConst.core.mainColArray != null) { 1031 if (!ArrayUtil.areEqual(mainConst.core.mainColArray, 1032 cols, cols.length, true)) { 1033 throw Trace.error(Trace.SECOND_PRIMARY_KEY); 1034 } 1035 } 1036 1037 mainConst.core.mainColArray = cols; 1038 mainConst.constName = pkHsqlName; 1039 1040 break; 1041 } 1042 case Token.UNIQUE : { 1043 int[] col = processColumnList(t, false); 1044 1045 if (cname == null) { 1046 cname = database.nameManager.newAutoName("CT"); 1047 } 1048 1049 tempConst = new Constraint(cname, col, null, null, 1050 Constraint.UNIQUE, 1051 Constraint.NO_ACTION, 1052 Constraint.NO_ACTION); 1053 1054 tcList.add(tempConst); 1055 1056 break; 1057 } 1058 case Token.FOREIGN : { 1059 tokenizer.getThis(Token.T_KEY); 1060 1061 tempConst = processCreateFK(t, cname); 1062 1063 if (tempConst.core.refColArray == null) { 1064 Constraint mainConst = (Constraint) tcList.get(0); 1065 1066 tempConst.core.refColArray = 1067 mainConst.core.mainColArray; 1068 1069 if (tempConst.core.refColArray == null) { 1070 throw Trace.error(Trace.CONSTRAINT_NOT_FOUND, 1071 Trace.TABLE_HAS_NO_PRIMARY_KEY); 1072 } 1073 } 1074 1075 checkFKColumnDefaults(t, tempConst); 1076 t.checkColumnsMatch(tempConst.core.mainColArray, 1077 tempConst.core.refTable, 1078 tempConst.core.refColArray); 1079 tcList.add(tempConst); 1080 1081 break; 1082 } 1083 case Token.CHECK : { 1084 if (cname == null) { 1085 cname = database.nameManager.newAutoName("CT"); 1086 } 1087 1088 tempConst = new Constraint(cname, null, null, null, 1089 Constraint.CHECK, 1090 Constraint.NO_ACTION, 1091 Constraint.NO_ACTION); 1092 1093 processCreateCheckConstraintCondition(tempConst); 1094 tcList.add(tempConst); 1095 1096 break; 1097 } 1098 } 1099 1100 token = tokenizer.getSimpleToken(); 1101 1102 if (token.equals(Token.T_COMMA)) { 1103 continue; 1104 } 1105 1106 if (token.equals(Token.T_CLOSEBRACKET)) { 1107 break; 1108 } 1109 1110 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 1111 } 1112 1113 return tcList; 1114 } 1115 1116 1122 private void processCreateCheckConstraintCondition(Constraint c) 1123 throws HsqlException { 1124 1125 tokenizer.getThis(Token.T_OPENBRACKET); 1126 1127 Parser parser = new Parser(session, database, tokenizer); 1128 Expression condition = parser.parseExpression(); 1129 1130 tokenizer.getThis(Token.T_CLOSEBRACKET); 1131 1132 c.core.check = condition; 1133 } 1134 1135 1141 private void processCreateTable(int type) throws HsqlException { 1142 1143 String token = tokenizer.getName(); 1144 HsqlName schemaname = 1145 session.getSchemaHsqlNameForWrite(tokenizer.getLongNameFirst()); 1146 1147 database.schemaManager.checkUserTableNotExists(session, token, 1148 schemaname.name); 1149 1150 boolean isnamequoted = tokenizer.wasQuotedIdentifier(); 1151 int[] pkCols = null; 1152 int colIndex = 0; 1153 boolean constraint = false; 1154 Table t = newTable(type, token, isnamequoted, schemaname); 1155 1156 tokenizer.getThis(Token.T_OPENBRACKET); 1157 1158 while (true) { 1159 token = tokenizer.getString(); 1160 1161 switch (Token.get(token)) { 1162 1163 case Token.CONSTRAINT : 1164 case Token.PRIMARY : 1165 case Token.FOREIGN : 1166 case Token.UNIQUE : 1167 case Token.CHECK : 1168 1169 constraint = !tokenizer.wasQuotedIdentifier() 1171 &&!tokenizer.wasLongName(); 1172 } 1173 1174 tokenizer.back(); 1175 1176 if (constraint) { 1177 break; 1178 } 1179 1180 Column newcolumn = processCreateColumn(); 1181 1182 t.addColumn(newcolumn); 1183 1184 if (newcolumn.isPrimaryKey()) { 1185 Trace.check(pkCols == null, Trace.SECOND_PRIMARY_KEY, 1186 newcolumn.columnName.name); 1187 1188 pkCols = new int[]{ colIndex }; 1189 } 1190 1191 token = tokenizer.getSimpleToken(); 1192 1193 if (token.equals(Token.T_COMMA)) { 1194 colIndex++; 1195 1196 continue; 1197 } 1198 1199 if (token.equals(Token.T_CLOSEBRACKET)) { 1200 break; 1201 } 1202 1203 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 1204 } 1205 1206 HsqlArrayList tempConstraints = processCreateConstraints(t, 1207 constraint, pkCols); 1208 1209 if (tokenizer.isGetThis(Token.T_ON)) { 1210 if (!t.isTemp) { 1211 throw Trace.error(Trace.UNEXPECTED_TOKEN, Token.T_ON); 1212 } 1213 1214 tokenizer.getThis(Token.T_COMMIT); 1215 1216 token = tokenizer.getSimpleToken(); 1217 1218 if (token.equals(Token.T_DELETE)) {} 1219 else if (token.equals(Token.T_PRESERVE)) { 1220 t.onCommitPreserve = true; 1221 } else { 1222 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 1223 } 1224 1225 tokenizer.getThis(Token.T_ROWS); 1226 } 1227 1228 try { 1229 session.commit(); 1230 1231 Constraint primaryConst = (Constraint) tempConstraints.get(0); 1232 1233 t.createPrimaryKey(null, primaryConst.core.mainColArray, true); 1234 1235 if (primaryConst.core.mainColArray != null) { 1236 if (primaryConst.constName == null) { 1237 primaryConst.constName = t.makeSysPKName(); 1238 } 1239 1240 Constraint newconstraint = 1241 new Constraint(primaryConst.constName, t, t.getPrimaryIndex(), 1242 Constraint.PRIMARY_KEY); 1243 1244 t.addConstraint(newconstraint); 1245 database.schemaManager.registerConstraintName( 1246 primaryConst.constName.name, t.getName()); 1247 } 1248 1249 for (int i = 1; i < tempConstraints.size(); i++) { 1250 Constraint tempConst = (Constraint) tempConstraints.get(i); 1251 1252 if (tempConst.constType == Constraint.UNIQUE) { 1253 TableWorks tableWorks = new TableWorks(session, t); 1254 1255 tableWorks.createUniqueConstraint( 1256 tempConst.core.mainColArray, tempConst.constName); 1257 1258 t = tableWorks.getTable(); 1259 } 1260 1261 if (tempConst.constType == Constraint.FOREIGN_KEY) { 1262 TableWorks tableWorks = new TableWorks(session, t); 1263 1264 tableWorks.createForeignKey(tempConst.core.mainColArray, 1265 tempConst.core.refColArray, 1266 tempConst.constName, 1267 tempConst.core.refTable, 1268 tempConst.core.deleteAction, 1269 tempConst.core.updateAction); 1270 1271 t = tableWorks.getTable(); 1272 } 1273 1274 if (tempConst.constType == Constraint.CHECK) { 1275 TableWorks tableWorks = new TableWorks(session, t); 1276 1277 tableWorks.createCheckConstraint(tempConst, 1278 tempConst.constName); 1279 1280 t = tableWorks.getTable(); 1281 } 1282 } 1283 1284 database.schemaManager.linkTable(t); 1285 } catch (HsqlException e) { 1286 1287 database.schemaManager.removeExportedKeys(t); 1292 database.schemaManager.removeIndexNames(t.tableName); 1293 database.schemaManager.removeConstraintNames(t.tableName); 1294 1295 throw e; 1296 } 1297 } 1298 1299 1302 1308 private Constraint processCreateFK(Table t, 1309 HsqlName cname) throws HsqlException { 1310 1311 int[] localcol; 1312 int[] expcol; 1313 String expTableName; 1314 Table expTable; 1315 String token; 1316 1317 localcol = processColumnList(t, false); 1318 1319 tokenizer.getThis(Token.T_REFERENCES); 1320 1321 expTableName = tokenizer.getName(); 1322 1323 String constraintSchema = tokenizer.getLongNameFirst(); 1324 1325 if (constraintSchema != null) { 1326 constraintSchema = 1327 session.getSchemaNameForWrite(tokenizer.getLongNameFirst()); 1328 1329 if (!t.getSchemaName().equals(constraintSchema)) { 1330 throw Trace.error(Trace.INVALID_SCHEMA_NAME_NO_SUBCLASS, 1331 constraintSchema); 1332 } 1333 } 1334 1335 if (t.getName().name.equals(expTableName)) { 1336 expTable = t; 1337 } else { 1338 expTable = database.schemaManager.getTable(session, expTableName, 1339 t.getSchemaName()); 1340 } 1341 1342 expcol = null; 1343 token = tokenizer.getSimpleToken(); 1344 1345 tokenizer.back(); 1346 1347 if (token.equals(Token.T_OPENBRACKET)) { 1348 expcol = processColumnList(expTable, false); 1349 } else { 1350 if (expTable.getPrimaryKey() == null) { 1351 1352 Trace.check(t == expTable, Trace.TABLE_HAS_NO_PRIMARY_KEY); 1357 } else { 1358 if (expTable.hasPrimaryKey()) { 1359 expcol = expTable.getPrimaryKey(); 1360 } else { 1361 throw Trace.error(Trace.CONSTRAINT_NOT_FOUND, 1362 Trace.TABLE_HAS_NO_PRIMARY_KEY); 1363 } 1364 } 1365 } 1366 1367 token = tokenizer.getSimpleToken(); 1368 1369 int deleteAction = Constraint.NO_ACTION; 1374 int updateAction = Constraint.NO_ACTION; 1375 1376 while (token.equals(Token.T_ON)) { 1377 token = tokenizer.getSimpleToken(); 1378 1379 if (deleteAction == Constraint.NO_ACTION 1380 && token.equals(Token.T_DELETE)) { 1381 token = tokenizer.getSimpleToken(); 1382 1383 if (token.equals(Token.T_SET)) { 1384 token = tokenizer.getSimpleToken(); 1385 1386 if (token.equals(Token.T_DEFAULT)) { 1387 deleteAction = Constraint.SET_DEFAULT; 1388 } else if (token.equals(Token.T_NULL)) { 1389 deleteAction = Constraint.SET_NULL; 1390 } else { 1391 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 1392 } 1393 } else if (token.equals(Token.T_CASCADE)) { 1394 deleteAction = Constraint.CASCADE; 1395 } else if (token.equals(Token.T_RESTRICT)) { 1396 1397 } else { 1400 tokenizer.matchThis(Token.T_NO); 1401 tokenizer.getThis(Token.T_ACTION); 1402 } 1403 } else if (updateAction == Constraint.NO_ACTION 1404 && token.equals(Token.T_UPDATE)) { 1405 token = tokenizer.getSimpleToken(); 1406 1407 if (token.equals(Token.T_SET)) { 1408 token = tokenizer.getSimpleToken(); 1409 1410 if (token.equals(Token.T_DEFAULT)) { 1411 updateAction = Constraint.SET_DEFAULT; 1412 } else if (token.equals(Token.T_NULL)) { 1413 updateAction = Constraint.SET_NULL; 1414 } else { 1415 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 1416 } 1417 } else if (token.equals(Token.T_CASCADE)) { 1418 updateAction = Constraint.CASCADE; 1419 } else if (token.equals(Token.T_RESTRICT)) { 1420 1421 } else { 1424 tokenizer.matchThis(Token.T_NO); 1425 tokenizer.getThis(Token.T_ACTION); 1426 } 1427 } else { 1428 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 1429 } 1430 1431 token = tokenizer.getSimpleToken(); 1432 } 1433 1434 tokenizer.back(); 1435 1436 if (cname == null) { 1437 cname = database.nameManager.newAutoName("FK"); 1438 } 1439 1440 return new Constraint(cname, localcol, expTable, expcol, 1441 Constraint.FOREIGN_KEY, deleteAction, 1442 updateAction); 1443 } 1444 1445 1450 private void processCreateView() throws HsqlException { 1451 1452 String name = tokenizer.getName(); 1453 HsqlName schemaname = 1454 session.getSchemaHsqlNameForWrite(tokenizer.getLongNameFirst()); 1455 int logposition = tokenizer.getPartMarker(); 1456 1457 database.schemaManager.checkUserViewNotExists(session, name, 1458 schemaname.name); 1459 1460 HsqlName viewHsqlName = database.nameManager.newHsqlName(name, 1461 tokenizer.wasQuotedIdentifier()); 1462 1463 viewHsqlName.schema = schemaname; 1464 1465 HsqlName[] colList = null; 1466 1467 if (tokenizer.isGetThis(Token.T_OPENBRACKET)) { 1472 try { 1473 HsqlArrayList list = Parser.getColumnNames(database, null, 1474 tokenizer, true); 1475 1476 colList = new HsqlName[list.size()]; 1477 colList = (HsqlName[]) list.toArray(colList); 1478 1479 if (database.isStoredFileAccess()) { 1481 for (int i = 0; i < colList.length; i++) { 1482 if (!colList[i].isNameQuoted) { 1483 colList = null; 1484 1485 break; 1486 } 1487 } 1488 } 1489 } catch (HsqlException e) { 1490 1491 if (database.isStoredFileAccess()) { 1493 while (!tokenizer.getString().equals( 1494 Token.T_CLOSEBRACKET)) {} 1495 } else { 1496 throw e; 1497 } 1498 } 1499 } 1500 1501 tokenizer.getThis(Token.T_AS); 1502 tokenizer.setPartMarker(); 1503 1504 Parser parser = new Parser(session, database, tokenizer); 1505 int brackets = parser.parseOpenBracketsSelect(); 1506 Select select; 1507 1508 select = parser.parseSelect(brackets, true, false, true, true); 1510 1511 if (select.sIntoTable != null) { 1512 throw (Trace.error(Trace.INVALID_IDENTIFIER, Token.INTO)); 1513 } 1514 1515 select.prepareResult(session); 1516 1517 View view = new View(session, database, viewHsqlName, 1518 tokenizer.getLastPart(), colList); 1519 1520 session.commit(); 1521 database.schemaManager.linkTable(view); 1522 tokenizer.setPartMarker(logposition); 1523 } 1524 1525 1530 private void processAlterTableRename(Table t) throws HsqlException { 1531 1532 String schema = t.getSchemaName(); 1533 String newName; 1534 boolean isquoted; 1535 1536 1542 tokenizer.getThis(Token.T_TO); 1543 1544 newName = tokenizer.getName(); 1545 1546 String newSchema = tokenizer.getLongNameFirst(); 1547 1548 isquoted = tokenizer.wasQuotedIdentifier(); 1549 newSchema = newSchema == null ? schema 1550 : session.getSchemaNameForWrite( 1551 newSchema); 1552 1553 if (!schema.equals(newSchema)) { 1554 throw Trace.error(Trace.INVALID_SCHEMA_NAME_NO_SUBCLASS); 1555 } 1556 1557 database.schemaManager.checkUserTableNotExists(session, newName, 1558 schema); 1559 session.commit(); 1560 session.setScripting(true); 1561 database.schemaManager.renameTable(session, t, newName, isquoted); 1562 } 1563 1564 1577 private void processAlter() throws HsqlException { 1578 1579 String token; 1580 1581 session.checkAdmin(); 1582 session.checkDDLWrite(); 1583 session.setScripting(true); 1584 1585 token = tokenizer.getSimpleToken(); 1586 1587 switch (Token.get(token)) { 1588 1589 case Token.INDEX : { 1590 processAlterIndex(); 1591 1592 break; 1593 } 1594 case Token.SCHEMA : { 1595 processAlterSchema(); 1596 1597 break; 1598 } 1599 case Token.SEQUENCE : { 1600 processAlterSequence(); 1601 1602 break; 1603 } 1604 case Token.TABLE : { 1605 processAlterTable(); 1606 1607 break; 1608 } 1609 case Token.USER : { 1610 processAlterUser(); 1611 1612 break; 1613 } 1614 default : { 1615 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 1616 } 1617 } 1618 } 1619 1620 1625 private void processAlterTable() throws HsqlException { 1626 1627 String tableName = tokenizer.getName(); 1628 String schema = 1629 session.getSchemaNameForWrite(tokenizer.getLongNameFirst()); 1630 Table t = database.schemaManager.getUserTable(session, tableName, 1631 schema); 1632 String token; 1633 1634 if (t.isView()) { 1635 throw Trace.error(Trace.NOT_A_TABLE); 1636 } 1637 1638 session.setScripting(true); 1639 1640 token = tokenizer.getSimpleToken(); 1641 1642 switch (Token.get(token)) { 1643 1644 case Token.RENAME : { 1645 processAlterTableRename(t); 1646 1647 return; 1648 } 1649 case Token.ADD : { 1650 HsqlName cname = null; 1651 1652 if (tokenizer.isGetThis(Token.T_CONSTRAINT)) { 1653 token = tokenizer.getName(); 1654 1655 String constraintSchema = tokenizer.getLongNameFirst(); 1656 1657 if (constraintSchema != null) { 1658 constraintSchema = session.getSchemaNameForWrite( 1659 tokenizer.getLongNameFirst()); 1660 1661 if (!t.getSchemaName().equals(constraintSchema)) { 1662 throw Trace.error( 1663 Trace.INVALID_SCHEMA_NAME_NO_SUBCLASS, 1664 constraintSchema); 1665 } 1666 } 1667 1668 cname = database.nameManager.newHsqlName(token, 1669 tokenizer.wasQuotedIdentifier()); 1670 } 1671 1672 token = tokenizer.getString(); 1673 1674 if (tokenizer.wasQuotedIdentifier() 1675 && tokenizer.wasSimpleName()) { 1676 tokenizer.back(); 1677 processAlterTableAddColumn(t); 1678 1679 return; 1680 } 1681 1682 if (!tokenizer.wasSimpleToken()) { 1683 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 1684 } 1685 1686 switch (Token.get(token)) { 1687 1688 case Token.FOREIGN : 1689 tokenizer.getThis(Token.T_KEY); 1690 processAlterTableAddForeignKeyConstraint(t, cname); 1691 1692 return; 1693 1694 case Token.UNIQUE : 1695 processAlterTableAddUniqueConstraint(t, cname); 1696 1697 return; 1698 1699 case Token.CHECK : 1700 processAlterTableAddCheckConstraint(t, cname); 1701 1702 return; 1703 1704 case Token.PRIMARY : 1705 tokenizer.getThis(Token.T_KEY); 1706 processAlterTableAddPrimaryKey(t, cname); 1707 1708 return; 1709 1710 default : 1711 if (cname != null) { 1712 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 1713 } 1714 1715 tokenizer.back(); 1716 case Token.COLUMN : 1717 processAlterTableAddColumn(t); 1718 1719 return; 1720 } 1721 } 1722 case Token.DROP : { 1723 token = tokenizer.getString(); 1724 1725 if (tokenizer.wasQuotedIdentifier() 1726 && tokenizer.wasSimpleName()) { 1727 tokenizer.back(); 1728 processAlterTableDropColumn(t); 1729 1730 return; 1731 } 1732 1733 if (!tokenizer.wasSimpleToken()) { 1734 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 1735 } 1736 1737 switch (Token.get(token)) { 1738 1739 case Token.PRIMARY : 1740 tokenizer.getThis(Token.T_KEY); 1741 1742 if (t.hasPrimaryKey()) { 1743 processAlterTableDropConstraint( 1744 t, t.getPrimaryConstraint().getName().name); 1745 } else { 1746 throw Trace.error(Trace.CONSTRAINT_NOT_FOUND, 1747 Trace.TABLE_HAS_NO_PRIMARY_KEY, 1748 new Object [] { 1749 "PRIMARY KEY", t.getName().name 1750 }); 1751 } 1752 1753 return; 1754 1755 case Token.CONSTRAINT : 1756 processAlterTableDropConstraint(t); 1757 1758 return; 1759 1760 default : 1761 tokenizer.back(); 1762 case Token.COLUMN : 1763 processAlterTableDropColumn(t); 1764 1765 return; 1766 } 1767 } 1768 case Token.ALTER : { 1769 tokenizer.isGetThis(Token.T_COLUMN); 1770 processAlterColumn(t); 1771 1772 return; 1773 } 1774 default : { 1775 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 1776 } 1777 } 1778 } 1779 1780 1786 private void processAlterColumn(Table t) throws HsqlException { 1787 1788 String columnName = tokenizer.getSimpleName(); 1789 int columnIndex = t.getColumnNr(columnName); 1790 Column column = t.getColumn(columnIndex); 1791 String token = tokenizer.getSimpleToken(); 1792 1793 switch (Token.get(token)) { 1794 1795 case Token.RENAME : { 1796 tokenizer.getThis(Token.T_TO); 1797 processAlterColumnRename(t, column); 1798 1799 return; 1800 } 1801 case Token.DROP : { 1802 tokenizer.getThis(Token.T_DEFAULT); 1803 1804 TableWorks tw = new TableWorks(session, t); 1805 1806 tw.setColDefaultExpression(columnIndex, null); 1807 1808 return; 1809 } 1810 case Token.SET : { 1811 1812 token = tokenizer.getSimpleToken(); 1814 1815 if (token.equals(Token.T_NOT)) { 1816 tokenizer.getThis(Token.T_NULL); 1817 1818 TableWorks tw = new TableWorks(session, t); 1819 1820 tw.setColNullability(column, false); 1821 } else if (token.equals(Token.T_NULL)) { 1822 TableWorks tw = new TableWorks(session, t); 1823 1824 tw.setColNullability(column, true); 1825 } else if (token.equals(Token.T_DEFAULT)) { 1826 1827 TableWorks tw = new TableWorks(session, t); 1829 int type = column.getType(); 1830 int length = column.getSize(); 1831 int scale = column.getScale(); 1832 Expression expr = processCreateDefaultExpression(type, 1833 length, scale); 1834 1835 tw.setColDefaultExpression(columnIndex, expr); 1836 } else { 1837 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 1838 } 1839 1840 return; 1841 } 1842 case Token.RESTART : { 1843 tokenizer.getThis(Token.T_WITH); 1844 1845 long identityStart = tokenizer.getBigint(); 1846 int id = t.getIdentityColumn(); 1847 1848 if (id == -1) { 1849 throw Trace.error(Trace.OPERATION_NOT_SUPPORTED); 1850 } 1851 1852 t.identitySequence.reset(identityStart); 1853 1854 return; 1855 } 1856 default : { 1857 tokenizer.back(); 1858 processAlterColumnType(t, column); 1859 } 1860 } 1861 } 1862 1863 private void processAlterColumnType(Table table, 1864 Column oldCol) throws HsqlException { 1865 1866 Column newCol = processCreateColumn(oldCol.columnName); 1867 TableWorks tw = new TableWorks(session, table); 1868 1869 tw.reTypeColumn(oldCol, newCol); 1870 } 1871 1872 1878 private void processAlterColumnRename(Table t, 1879 Column column) 1880 throws HsqlException { 1881 1882 String newName = tokenizer.getSimpleName(); 1883 boolean isquoted = tokenizer.wasQuotedIdentifier(); 1884 1885 if (t.findColumn(newName) > -1) { 1886 throw Trace.error(Trace.COLUMN_ALREADY_EXISTS, newName); 1887 } 1888 1889 t.database.schemaManager.checkColumnIsInView(t, 1890 column.columnName.name); 1891 session.commit(); 1892 session.setScripting(true); 1893 t.renameColumn(column, newName, isquoted); 1894 } 1895 1896 1901 private void processAlterIndex() throws HsqlException { 1902 1903 processAlterIndexRename(); 1905 } 1906 1907 private void processAlterSchema() throws HsqlException { 1908 1909 processAlterSchemaRename(); 1911 } 1912 1913 1918 private void processDrop() throws HsqlException { 1919 1920 String token; 1921 boolean isview; 1922 1923 session.checkReadWrite(); 1924 session.checkAdmin(); 1925 session.setScripting(true); 1926 1927 token = tokenizer.getSimpleToken(); 1928 isview = false; 1929 1930 switch (Token.get(token)) { 1931 1932 case Token.INDEX : { 1933 processDropIndex(); 1934 1935 break; 1936 } 1937 case Token.SCHEMA : { 1938 processDropSchema(); 1939 1940 break; 1941 } 1942 case Token.SEQUENCE : { 1943 processDropSequence(); 1944 1945 break; 1946 } 1947 case Token.TRIGGER : { 1948 processDropTrigger(); 1949 1950 break; 1951 } 1952 case Token.USER : { 1953 processDropUser(); 1954 1955 break; 1956 } 1957 case Token.ROLE : { 1958 database.getGranteeManager().dropRole( 1959 tokenizer.getSimpleName()); 1960 1961 break; 1962 } 1963 case Token.VIEW : { 1964 isview = true; 1965 } case Token.TABLE : { 1967 processDropTable(isview); 1968 1969 break; 1970 } 1971 default : { 1972 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 1973 } 1974 } 1975 } 1976 1977 1984 private void processGrantOrRevoke(boolean grant) throws HsqlException { 1985 1986 int right; 1987 Object accessKey; 1988 String token; 1989 1990 session.checkAdmin(); 1991 session.checkDDLWrite(); 1992 session.setScripting(true); 1993 1994 right = 0; 1995 token = tokenizer.getSimpleToken(); 1996 1997 tokenizer.back(); 1998 1999 if (!GranteeManager.validRightString(token)) { 2000 processRoleGrantOrRevoke(grant); 2001 2002 return; 2003 } 2004 2005 do { 2006 token = tokenizer.getSimpleToken(); 2007 right |= GranteeManager.getCheckRight(token); 2008 } while (tokenizer.isGetThis(Token.T_COMMA)); 2009 2010 tokenizer.getThis(Token.T_ON); 2011 2012 accessKey = null; 2013 2014 if (tokenizer.isGetThis(Token.T_CLASS)) { 2015 accessKey = tokenizer.getSimpleName(); 2016 2017 if (!tokenizer.wasQuotedIdentifier()) { 2018 throw Trace.error(Trace.QUOTED_IDENTIFIER_REQUIRED); 2019 } 2020 } else { 2021 token = tokenizer.getName(); 2022 2023 String schema = 2024 session.getSchemaName(tokenizer.getLongNameFirst()); 2025 Table t = database.schemaManager.getTable(session, token, schema); 2026 2027 accessKey = t.getName(); 2028 2029 session.setScripting(true); 2030 } 2031 2032 tokenizer.getThis(grant ? Token.T_TO 2033 : Token.T_FROM); 2034 2035 token = getUserIdentifier(); 2036 2037 GranteeManager gm = database.getGranteeManager(); 2038 2039 if (grant) { 2040 gm.grant(token, accessKey, right); 2041 } else { 2042 gm.revoke(token, accessKey, right); 2043 } 2044 } 2045 2046 2051 private void processConnect() throws HsqlException { 2052 2053 String userName; 2054 String password; 2055 User user; 2056 2057 tokenizer.getThis(Token.T_USER); 2058 2059 userName = getUserIdentifier(); 2060 2061 if (tokenizer.isGetThis(Token.T_PASSWORD)) { 2062 2063 password = getPassword(); 2065 user = database.getUserManager().getUser(userName, password); 2066 2067 session.commit(); 2068 session.setUser(user); 2069 database.logger.logConnectUser(session); 2070 } else if (session.isProcessingLog) { 2071 2072 session.commit(); 2075 } else { 2076 2077 tokenizer.getThis(Token.T_PASSWORD); 2079 } 2080 } 2081 2082 2087 private void processSet() throws HsqlException { 2088 2089 String token; 2090 2091 session.setScripting(true); 2092 2093 token = tokenizer.getSimpleToken(); 2094 2095 switch (Token.get(token)) { 2096 2097 case Token.PROPERTY : { 2098 HsqlDatabaseProperties p; 2099 2100 session.checkAdmin(); 2101 2102 token = tokenizer.getSimpleName(); 2103 2104 if (!tokenizer.wasQuotedIdentifier()) { 2105 throw Trace.error(Trace.QUOTED_IDENTIFIER_REQUIRED); 2106 } 2107 2108 p = database.getProperties(); 2109 2110 boolean isboolean = p.isBoolean(token); 2111 boolean isintegral = p.isIntegral(token); 2112 boolean isstring = p.isString(token); 2113 2114 Trace.check(isboolean || isintegral || isstring, 2115 Trace.ACCESS_IS_DENIED, token); 2116 2117 int type = isboolean ? Types.BOOLEAN 2118 : isintegral ? Types.INTEGER 2119 : Types.VARCHAR; 2120 Object value = tokenizer.getInType(type); 2121 2122 if (HsqlDatabaseProperties.hsqldb_cache_file_scale.equals( 2123 token)) { 2124 if (database.logger.hasCache() 2125 || ((Integer ) value).intValue() != 8) { 2126 Trace.throwerror(Trace.ACCESS_IS_DENIED, token); 2127 } 2128 } 2129 2130 p.setDatabaseProperty(token, value.toString().toLowerCase()); 2131 p.setDatabaseVariables(); 2132 2133 break; 2134 } 2135 case Token.SCHEMA : { 2136 session.setScripting(false); 2137 session.setSchema(tokenizer.getSimpleName()); 2138 2139 break; 2140 } 2141 case Token.PASSWORD : { 2142 session.checkDDLWrite(); 2143 session.getUser().setPassword(getPassword()); 2144 2145 break; 2146 } 2147 case Token.READONLY : { 2148 session.commit(); 2149 session.setReadOnly(processTrueOrFalse()); 2150 2151 break; 2152 } 2153 case Token.LOGSIZE : { 2154 session.checkAdmin(); 2155 session.checkDDLWrite(); 2156 2157 int i = tokenizer.getInt(); 2158 2159 database.logger.setLogSize(i); 2160 2161 break; 2162 } 2163 case Token.SCRIPTFORMAT : { 2164 session.checkAdmin(); 2165 session.checkDDLWrite(); 2166 session.setScripting(false); 2167 2168 token = tokenizer.getSimpleToken(); 2169 2170 int i = ArrayUtil.find(ScriptWriterBase.LIST_SCRIPT_FORMATS, 2171 token); 2172 2173 if (i == 0 || i == 1 || i == 3) { 2174 database.logger.setScriptType(i); 2175 } else { 2176 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 2177 } 2178 2179 break; 2180 } 2181 case Token.IGNORECASE : { 2182 session.checkAdmin(); 2183 session.checkDDLWrite(); 2184 database.setIgnoreCase(processTrueOrFalse()); 2185 2186 break; 2187 } 2188 case Token.MAXROWS : { 2189 session.setScripting(false); 2190 2191 int i = tokenizer.getInt(); 2192 2193 session.setSQLMaxRows(i); 2194 2195 break; 2196 } 2197 case Token.AUTOCOMMIT : { 2198 session.setAutoCommit(processTrueOrFalse()); 2199 2200 break; 2201 } 2202 case Token.TABLE : { 2203 session.checkAdmin(); 2204 session.checkDDLWrite(); 2205 2206 token = tokenizer.getName(); 2207 2208 String schema = session.getSchemaNameForWrite( 2209 tokenizer.getLongNameFirst()); 2210 Table t = database.schemaManager.getTable(session, token, 2211 schema); 2212 2213 token = tokenizer.getSimpleToken(); 2214 2215 session.setScripting(true); 2216 2217 switch (Token.get(token)) { 2218 2219 default : { 2220 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 2221 } 2222 case Token.SOURCE : { 2223 session.checkAdmin(); 2224 2225 if (tokenizer.isGetThis(Token.T_HEADER)) { 2226 token = tokenizer.getString(); 2227 2228 if (!tokenizer.wasQuotedIdentifier()) { 2229 throw Trace.error(Trace.TEXT_TABLE_SOURCE); 2230 } 2231 2232 t.setHeader(token); 2233 2234 break; 2235 } 2236 2237 token = tokenizer.getString(); 2238 2239 if (!tokenizer.wasQuotedIdentifier()) { 2240 throw Trace.error(Trace.TEXT_TABLE_SOURCE); 2241 } 2242 2243 boolean isDesc = false; 2244 2245 isDesc = tokenizer.isGetThis(Token.T_DESC); 2246 2247 t.setDataSource(session, token, isDesc, false); 2248 2249 break; 2250 } 2251 case Token.READONLY : { 2252 session.checkAdmin(); 2253 t.setDataReadOnly(processTrueOrFalse()); 2254 2255 break; 2256 } 2257 case Token.INDEX : { 2258 session.checkAdmin(); 2259 2260 String roots = 2261 (String ) tokenizer.getInType(Types.VARCHAR); 2262 2263 t.setIndexRoots(roots); 2264 2265 break; 2266 } 2267 } 2268 2269 break; 2270 } 2271 case Token.REFERENTIAL_INTEGRITY : { 2272 session.checkAdmin(); 2273 session.checkDDLWrite(); 2274 session.setScripting(false); 2275 database.setReferentialIntegrity(processTrueOrFalse()); 2276 2277 break; 2278 } 2279 case Token.CHECKPOINT : { 2280 session.checkAdmin(); 2281 session.checkDDLWrite(); 2282 tokenizer.getThis(Token.T_DEFRAG); 2283 2284 int size = tokenizer.getInt(); 2285 2286 database.getProperties().setProperty( 2287 HsqlDatabaseProperties.hsqldb_defrag_limit, size); 2288 2289 break; 2290 } 2291 case Token.WRITE_DELAY : { 2292 session.checkAdmin(); 2293 session.checkDDLWrite(); 2294 2295 int delay = 0; 2296 2297 tokenizer.getString(); 2298 2299 Object value = tokenizer.getAsValue(); 2300 2301 if (tokenizer.getType() == Types.INTEGER) { 2302 delay = ((Integer ) value).intValue(); 2303 } else if (Boolean.TRUE.equals(value)) { 2304 delay = database.getProperties().getDefaultWriteDelay(); 2305 } else if (Boolean.FALSE.equals(value)) { 2306 delay = 0; 2307 } else { 2308 throw Trace.error(Trace.UNEXPECTED_TOKEN); 2309 } 2310 2311 if (!tokenizer.isGetThis("MILLIS")) { 2312 delay *= 1000; 2313 } 2314 2315 database.logger.setWriteDelay(delay); 2316 2317 break; 2318 } 2319 case Token.DATABASE : { 2320 session.checkAdmin(); 2321 session.checkDDLWrite(); 2322 tokenizer.getThis(Token.T_COLLATION); 2323 2324 String cname = tokenizer.getSimpleName(); 2325 2326 if (!tokenizer.wasQuotedIdentifier()) { 2327 throw Trace.error(Trace.INVALID_IDENTIFIER); 2328 } 2329 2330 database.collation.setCollation(cname); 2331 2332 break; 2333 } 2334 default : { 2335 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 2336 } 2337 } 2338 } 2339 2340 2346 private boolean processTrueOrFalse() throws HsqlException { 2347 2348 String sToken = tokenizer.getSimpleToken(); 2349 2350 if (sToken.equals(Token.T_TRUE)) { 2351 return true; 2352 } else if (sToken.equals(Token.T_FALSE)) { 2353 return false; 2354 } else { 2355 throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken); 2356 } 2357 } 2358 2359 2364 private void processCommit() throws HsqlException { 2365 tokenizer.isGetThis(Token.T_WORK); 2366 session.commit(); 2367 } 2368 2369 2374 private void processRollback() throws HsqlException { 2375 2376 String token; 2377 boolean toSavepoint; 2378 2379 token = tokenizer.getSimpleToken(); 2380 toSavepoint = false; 2381 2382 if (token.equals(Token.T_WORK)) { 2383 2384 } else if (token.equals(Token.T_TO)) { 2386 tokenizer.getThis(Token.T_SAVEPOINT); 2387 2388 token = tokenizer.getSimpleName(); 2389 toSavepoint = true; 2390 } else { 2391 tokenizer.back(); 2392 } 2393 2394 if (toSavepoint) { 2395 session.rollbackToSavepoint(token); 2396 } else { 2397 session.rollback(); 2398 } 2399 } 2400 2401 2406 private void processSavepoint() throws HsqlException { 2407 2408 String token; 2409 2410 token = tokenizer.getSimpleName(); 2411 2412 session.savepoint(token); 2413 } 2414 2415 2420 private void processShutdown() throws HsqlException { 2421 2422 int closemode; 2423 String token; 2424 2425 if (!session.isClosed()) { 2427 session.checkAdmin(); 2428 } 2429 2430 closemode = Database.CLOSEMODE_NORMAL; 2431 token = tokenizer.getSimpleToken(); 2432 2433 if (token.equals(Token.T_IMMEDIATELY)) { 2435 closemode = Database.CLOSEMODE_IMMEDIATELY; 2436 } else if (token.equals(Token.T_COMPACT)) { 2437 closemode = Database.CLOSEMODE_COMPACT; 2438 } else if (token.equals(Token.T_SCRIPT)) { 2439 closemode = Database.CLOSEMODE_SCRIPT; 2440 } else if (token.equals(Token.T_SEMICOLON)) { 2441 2442 } else if (token.length() != 0) { 2444 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 2445 } 2446 2447 database.close(closemode); 2448 } 2449 2450 2455 private void processCheckpoint() throws HsqlException { 2456 2457 boolean defrag; 2458 String token; 2459 2460 session.checkAdmin(); 2461 session.checkDDLWrite(); 2462 2463 defrag = false; 2464 token = tokenizer.getSimpleToken(); 2465 2466 if (token.equals(Token.T_DEFRAG)) { 2467 defrag = true; 2468 } else if (token.equals(Token.T_SEMICOLON)) { 2469 2470 } else if (token.length() != 0) { 2472 throw Trace.error(Trace.UNEXPECTED_TOKEN, token); 2473 } 2474 2475 database.logger.checkpoint(defrag); 2476 } 2477 2478 private HsqlName newIndexHsqlName(String name, 2480 boolean isQuoted) throws HsqlException { 2481 2482 return HsqlName.isReservedIndexName(name) 2483 ? database.nameManager.newAutoName("USER", name) 2484 : database.nameManager.newHsqlName(name, isQuoted); 2485 } 2486 2487 private Table newTable(int type, String name, boolean quoted, 2488 HsqlName schema) throws HsqlException { 2489 2490 HsqlName tableHsqlName = database.nameManager.newHsqlName(name, 2491 quoted); 2492 2493 tableHsqlName.schema = schema; 2494 2495 switch (type) { 2496 2497 case Table.TEMP_TEXT_TABLE : 2498 case Table.TEXT_TABLE : { 2499 return new TextTable(database, tableHsqlName, type); 2500 } 2501 default : { 2502 return new Table(database, tableHsqlName, type); 2503 } 2504 } 2505 } 2506 2507 2516 private void checkAddColumn(Table t, Column c) throws HsqlException { 2517 2518 boolean canAdd = true; 2519 2520 if (t.findColumn(c.columnName.name) != -1) { 2521 throw Trace.error(Trace.COLUMN_ALREADY_EXISTS); 2522 } 2523 2524 if (c.isPrimaryKey() && t.hasPrimaryKey()) { 2525 canAdd = false; 2526 } 2527 2528 if (canAdd &&!t.isEmpty(session)) { 2529 canAdd = c.isNullable() || c.getDefaultExpression() != null; 2530 } 2531 2532 if (!canAdd) { 2533 throw Trace.error(Trace.BAD_ADD_COLUMN_DEFINITION); 2534 } 2535 } 2536 2537 private void checkFKColumnDefaults(Table t, 2538 Constraint tc) throws HsqlException { 2539 2540 boolean check = tc.core.updateAction == Constraint.SET_DEFAULT; 2541 2542 check = check || tc.core.deleteAction == Constraint.SET_DEFAULT; 2543 2544 if (check) { 2545 int[] localCol = tc.core.mainColArray; 2546 2547 for (int j = 0; j < localCol.length; j++) { 2548 Column column = t.getColumn(localCol[j]); 2549 Expression defExpr = column.getDefaultExpression(); 2550 2551 if (defExpr == null) { 2552 String columnName = column.columnName.name; 2553 2554 throw Trace.error(Trace.NO_DEFAULT_VALUE_FOR_COLUMN, 2555 new Object []{ columnName }); 2556 } 2557 } 2558 } 2559 } 2560 2561 private void processAlterSequence() throws HsqlException { 2562 2563 long start; 2564 String name = tokenizer.getName(); 2565 String schemaname = tokenizer.getLongNameFirst(); 2566 2567 schemaname = session.getSchemaNameForWrite(schemaname); 2568 2569 tokenizer.getThis(Token.T_RESTART); 2570 tokenizer.getThis(Token.T_WITH); 2571 2572 start = tokenizer.getBigint(); 2573 2574 NumberSequence seq = database.schemaManager.getSequence(name, 2575 schemaname); 2576 2577 seq.reset(start); 2578 } 2579 2580 2585 private void processAlterIndexRename() throws HsqlException { 2586 2587 String name = tokenizer.getName(); 2588 String schema = 2589 session.getSchemaNameForWrite(tokenizer.getLongNameFirst()); 2590 2591 tokenizer.getThis(Token.T_RENAME); 2592 tokenizer.getThis(Token.T_TO); 2593 2594 String newName = tokenizer.getName(); 2595 String newSchema = tokenizer.getLongNameFirst(); 2596 2597 newSchema = newSchema == null ? schema 2598 : session.getSchemaNameForWrite( 2599 newSchema); 2600 2601 boolean isQuoted = tokenizer.wasQuotedIdentifier(); 2602 2603 if (!schema.equals(newSchema)) { 2604 throw Trace.error(Trace.INVALID_SCHEMA_NAME_NO_SUBCLASS); 2605 } 2606 2607 Table t = database.schemaManager.findUserTableForIndex(session, name, 2608 schema); 2609 2610 if (t == null) { 2611 throw Trace.error(Trace.INDEX_NOT_FOUND, name); 2612 } 2613 2614 database.schemaManager.checkIndexExists(name, t.getSchemaName(), 2615 true); 2616 2617 if (HsqlName.isReservedIndexName(name)) { 2618 throw Trace.error(Trace.SYSTEM_INDEX, name); 2619 } 2620 2621 if (HsqlName.isReservedIndexName(newName)) { 2622 throw Trace.error(Trace.BAD_INDEX_CONSTRAINT_NAME, newName); 2623 } 2624 2625 session.setScripting(true); 2626 session.commit(); 2627 t.getIndex(name).setName(newName, isQuoted); 2628 database.schemaManager.renameIndex(name, newName, t.getName()); 2629 } 2630 2631 2636 private void processAlterSchemaRename() throws HsqlException { 2637 2638 String name = tokenizer.getSimpleName(); 2639 2640 tokenizer.getThis(Token.T_RENAME); 2641 tokenizer.getThis(Token.T_TO); 2642 2643 String newName = tokenizer.getSimpleName(); 2644 boolean isQuoted = tokenizer.wasQuotedIdentifier(); 2645 2646 database.schemaManager.renameSchema(name, newName, isQuoted); 2647 } 2648 2649 2654 private void processAlterTableAddColumn(Table t) throws HsqlException { 2655 2656 String token; 2657 int colindex = t.getColumnCount(); 2658 Column column = processCreateColumn(); 2659 2660 checkAddColumn(t, column); 2661 2662 if (tokenizer.isGetThis(Token.T_BEFORE)) { 2663 token = tokenizer.getSimpleName(); 2664 colindex = t.getColumnNr(token); 2665 } 2666 2667 session.commit(); 2668 2669 TableWorks tableWorks = new TableWorks(session, t); 2670 2671 tableWorks.addColumn(column, colindex); 2672 2673 return; 2674 } 2675 2676 2682 private void processAlterTableDropColumn(Table t) throws HsqlException { 2683 2684 String token; 2685 int colindex; 2686 2687 token = tokenizer.getName(); 2688 colindex = t.getColumnNr(token); 2689 2690 session.commit(); 2691 2692 TableWorks tableWorks = new TableWorks(session, t); 2693 2694 tableWorks.dropColumn(colindex); 2695 } 2696 2697 2703 private void processAlterTableDropConstraint(Table t) 2704 throws HsqlException { 2705 processAlterTableDropConstraint(t, tokenizer.getName()); 2706 } 2707 2708 2715 private void processAlterTableDropConstraint(Table t, 2716 String cname) throws HsqlException { 2717 2718 session.commit(); 2719 2720 TableWorks tableWorks = new TableWorks(session, t); 2721 2722 tableWorks.dropConstraint(cname); 2723 2724 return; 2725 } 2726 2727 2731 private void processCreateAlias() throws HsqlException { 2732 2733 String alias; 2734 String methodFQN; 2735 2736 try { 2737 alias = tokenizer.getSimpleName(); 2738 } catch (HsqlException e) { 2739 if (session.isProcessingScript()) { 2740 alias = null; 2741 } else { 2742 throw e; 2743 } 2744 } 2745 2746 tokenizer.getThis(Token.T_FOR); 2747 2748 methodFQN = upgradeMethodFQN(tokenizer.getSimpleName()); 2749 2750 if (alias != null) { 2751 database.getAliasMap().put(alias, methodFQN); 2752 } 2753 } 2754 2755 private void processCreateIndex(boolean unique) throws HsqlException { 2756 2757 Table t; 2758 String indexName = tokenizer.getName(); 2759 String schema = tokenizer.getLongNameFirst(); 2760 boolean indexNameQuoted = tokenizer.wasQuotedIdentifier(); 2761 2762 tokenizer.getThis(Token.T_ON); 2763 2764 String tablename = tokenizer.getName(); 2765 String tableschema = 2766 session.getSchemaNameForWrite(tokenizer.getLongNameFirst()); 2767 2768 if (schema != null &&!schema.equals(tableschema)) { 2769 throw Trace.error(Trace.INVALID_SCHEMA_NAME_NO_SUBCLASS); 2770 } 2771 2772 t = database.schemaManager.getTable(session, tablename, tableschema); 2773 2774 database.schemaManager.checkIndexExists(indexName, t.getSchemaName(), 2775 false); 2776 2777 HsqlName indexHsqlName = newIndexHsqlName(indexName, indexNameQuoted); 2778 int[] indexColumns = processColumnList(t, true); 2779 String extra = tokenizer.getSimpleToken(); 2780 2781 if (!Token.T_DESC.equals(extra) &&!Token.T_ASC.equals(extra)) { 2782 tokenizer.back(); 2783 } 2784 2785 session.commit(); 2786 session.setScripting(true); 2787 2788 TableWorks tableWorks = new TableWorks(session, t); 2789 2790 tableWorks.createIndex(indexColumns, indexHsqlName, unique, false, 2791 false); 2792 } 2793 2794 2799 private void processCreateSequence() throws HsqlException { 2800 2801 2807 int type = Types.INTEGER; 2808 long increment = 1; 2809 long start = 0; 2810 String name = tokenizer.getName(); 2811 boolean isquoted = tokenizer.wasQuotedIdentifier(); 2812 HsqlName schemaname = 2813 session.getSchemaHsqlNameForWrite(tokenizer.getLongNameFirst()); 2814 2815 if (tokenizer.isGetThis(Token.T_AS)) { 2816 String typestring = tokenizer.getSimpleToken(); 2817 2818 type = Types.getTypeNr(typestring); 2819 2820 Trace.check(type == Types.INTEGER || type == Types.BIGINT, 2821 Trace.WRONG_DATA_TYPE); 2822 } 2823 2824 if (tokenizer.isGetThis(Token.T_START)) { 2825 tokenizer.getThis(Token.T_WITH); 2826 2827 start = tokenizer.getBigint(); 2828 } 2829 2830 if (tokenizer.isGetThis(Token.T_INCREMENT)) { 2831 tokenizer.getThis(Token.T_BY); 2832 2833 increment = tokenizer.getBigint(); 2834 } 2835 2836 HsqlName hsqlname = database.nameManager.newHsqlName(name, isquoted); 2837 2838 hsqlname.schema = schemaname; 2839 2840 database.schemaManager.createSequence(hsqlname, start, increment, 2841 type); 2842 } 2843 2844 2848 private void processCreateSchema() throws HsqlException { 2849 2850 String name = tokenizer.getSimpleName(); 2851 boolean isquoted = tokenizer.wasQuotedIdentifier(); 2852 2853 if (session.isSchemaDefintion()) { 2854 throw Trace.error(Trace.INVALID_IDENTIFIER); 2855 } 2856 2857 tokenizer.getThis(Token.T_AUTHORIZATION); 2858 tokenizer.getThis(GranteeManager.DBA_ADMIN_ROLE_NAME); 2859 2860 if (database.schemaManager.schemaExists(name)) { 2861 if (!session.isProcessingScript) { 2862 throw Trace.error(Trace.INVALID_SCHEMA_NAME_NO_SUBCLASS); 2863 } 2864 } else { 2865 database.schemaManager.createSchema(name, isquoted); 2866 } 2867 2868 HsqlName schemaName = database.schemaManager.getSchemaHsqlName(name); 2869 2870 database.logger.writeToLog(session, 2871 DatabaseScript.getSchemaCreateDDL(database, 2872 schemaName)); 2873 database.logger.writeToLog(session, 2874 "SET SCHEMA " + schemaName.statementName); 2875 session.startSchemaDefinition(name); 2876 2877 session.loggedSchema = session.currentSchema; 2878 } 2879 2880 private void processCreateUser() throws HsqlException { 2881 2882 String name; 2883 String password; 2884 boolean admin; 2885 2886 name = getUserIdentifier(); 2887 2888 tokenizer.getThis(Token.T_PASSWORD); 2889 2890 password = getPassword(); 2891 admin = tokenizer.isGetThis(Token.T_ADMIN); 2892 2893 database.getUserManager().createUser(name, password); 2894 2895 if (admin) { 2896 database.getGranteeManager().grant( 2897 name, GranteeManager.DBA_ADMIN_ROLE_NAME); 2898 } 2899 } 2900 2901 private void processDisconnect() throws HsqlException { 2902 session.close(); 2903 } 2904 2905 private void processDropTable(boolean isView) throws HsqlException { 2906 2907 boolean ifexists = false; 2908 boolean cascade = false; 2909 2910 if (tokenizer.isGetThis(Token.T_IF)) { 2911 tokenizer.getThis(Token.T_EXISTS); 2912 2913 ifexists = true; 2914 } 2915 2916 String name = tokenizer.getName(); 2917 String schema = tokenizer.getLongNameFirst(); 2918 2919 if (tokenizer.isGetThis(Token.T_IF)) { 2920 tokenizer.getThis(Token.T_EXISTS); 2921 2922 ifexists = true; 2923 } 2924 2925 cascade = tokenizer.isGetThis(Token.T_CASCADE); 2926 2927 if (!cascade) { 2928 tokenizer.isGetThis(Token.T_RESTRICT); 2929 } 2930 2931 if (ifexists && schema != null 2932 &&!database.schemaManager.schemaExists(schema)) { 2933 return; 2934 } 2935 2936 schema = session.getSchemaNameForWrite(schema); 2937 2938 database.schemaManager.dropTable(session, name, schema, ifexists, 2939 isView, cascade); 2940 } 2941 2942 private void processDropUser() throws HsqlException { 2943 2944 session.checkAdmin(); 2945 session.checkDDLWrite(); 2946 2947 String userName = getPassword(); 2948 2949 if (database.getSessionManager().isUserActive(userName)) { 2950 2951 throw Trace.error(Trace.ACCESS_IS_DENIED); 2953 } 2954 2955 database.getUserManager().dropUser(userName); 2956 } 2957 2958 private void processDropSequence() throws HsqlException { 2959 2960 boolean ifexists = false; 2961 2962 session.checkAdmin(); 2963 session.checkDDLWrite(); 2964 2965 String name = tokenizer.getName(); 2966 String schemaname = 2967 session.getSchemaNameForWrite(tokenizer.getLongNameFirst()); 2968 2969 if (tokenizer.isGetThis(Token.T_IF)) { 2970 tokenizer.getThis(Token.T_EXISTS); 2971 2972 ifexists = true; 2973 } 2974 2975 boolean cascade = tokenizer.isGetThis(Token.T_CASCADE); 2976 2977 if (!cascade) { 2978 tokenizer.isGetThis(Token.T_RESTRICT); 2979 } 2980 2981 NumberSequence sequence = database.schemaManager.findSequence(name, 2982 schemaname); 2983 2984 if (sequence == null) { 2985 if (ifexists) { 2986 return; 2987 } else { 2988 throw Trace.error(Trace.SEQUENCE_NOT_FOUND); 2989 } 2990 } 2991 2992 database.schemaManager.checkCascadeDropViews(sequence, cascade); 2993 database.schemaManager.dropSequence(sequence); 2994 } 2995 2996 private void processDropTrigger() throws HsqlException { 2997 2998 session.checkAdmin(); 2999 session.checkDDLWrite(); 3000 3001 String triggername = tokenizer.getName(); 3002 String schemaname = 3003 session.getSchemaNameForWrite(tokenizer.getLongNameFirst()); 3004 3005 database.schemaManager.dropTrigger(session, triggername, schemaname); 3006 } 3007 3008 private void processDropIndex() throws HsqlException { 3009 3010 String name = tokenizer.getName(); 3011 String schema = 3012 session.getSchemaNameForWrite(tokenizer.getLongNameFirst()); 3013 boolean ifexists = false; 3014 3015 if (tokenizer.isGetThis(Token.T_ON)) { 3017 tokenizer.getName(); 3018 } 3019 3020 if (tokenizer.isGetThis(Token.T_IF)) { 3021 tokenizer.getThis(Token.T_EXISTS); 3022 3023 ifexists = true; 3024 } 3025 3026 session.checkAdmin(); 3027 session.checkDDLWrite(); 3028 database.schemaManager.dropIndex(session, name, schema, ifexists); 3029 } 3030 3031 private void processDropSchema() throws HsqlException { 3032 3033 String name = tokenizer.getSimpleName(); 3034 boolean cascade = tokenizer.isGetThis(Token.T_CASCADE); 3035 3036 if (!cascade) { 3037 tokenizer.isGetThis(Token.T_RESTRICT); 3038 } 3039 3040 processDropSchema(name, cascade); 3041 } 3042 3043 private void processDropSchema(String name, 3044 boolean cascade) throws HsqlException { 3045 3046 if (!database.schemaManager.schemaExists(name)) { 3047 throw Trace.error(Trace.INVALID_SCHEMA_NAME_NO_SUBCLASS); 3048 } 3049 3050 database.schemaManager.dropSchema(name, cascade); 3051 3052 if (name.equals(session.getSchemaName(null))) { 3053 session.setSchema(database.schemaManager.getDefaultSchemaName()); 3054 } 3055 } 3056 3057 private Result processExplainPlan() throws IOException , HsqlException { 3058 3059 String token; 3063 Parser parser; 3064 int cmd; 3065 CompiledStatement cs; 3066 Result result; 3067 String line; 3068 LineNumberReader lnr; 3069 3070 tokenizer.getThis(Token.T_PLAN); 3071 tokenizer.getThis(Token.T_FOR); 3072 3073 parser = new Parser(session, database, tokenizer); 3074 token = tokenizer.getSimpleToken(); 3075 cmd = Token.get(token); 3076 result = Result.newSingleColumnResult("OPERATION", Types.VARCHAR); 3077 3078 int brackets = 0; 3079 3080 switch (cmd) { 3081 3082 case Token.OPENBRACKET : 3083 brackets = parser.parseOpenBracketsSelect() + 1; 3084 case Token.SELECT : 3085 cs = parser.compileSelectStatement(brackets); 3086 break; 3087 3088 case Token.INSERT : 3089 cs = parser.compileInsertStatement(); 3090 break; 3091 3092 case Token.UPDATE : 3093 cs = parser.compileUpdateStatement(); 3094 break; 3095 3096 case Token.DELETE : 3097 cs = parser.compileDeleteStatement(); 3098 break; 3099 3100 case Token.CALL : 3101 cs = parser.compileCallStatement(); 3102 break; 3103 3104 default : 3105 3106 return result; 3111 } 3112 3113 lnr = new LineNumberReader (new StringReader (cs.describe(session))); 3114 3115 while (null != (line = lnr.readLine())) { 3116 result.add(new Object []{ line }); 3117 } 3118 3119 return result; 3120 } 3121 3122 static final String oldLib = "org.hsql.Library."; 3126 static final int oldLibLen = oldLib.length(); 3127 static final String newLib = "org.hsqldb.Library."; 3128 3129 private static String upgradeMethodFQN(String fqn) { 3130 3131 if (fqn.startsWith(oldLib)) { 3132 fqn = newLib + fqn.substring(oldLibLen); 3133 } else if (fqn.equals("java.lang.Math.abs")) { 3134 fqn = "org.hsqldb.Library.abs"; 3135 } 3136 3137 return fqn; 3138 } 3139 3140 3143 Result processSelectInto(Result result, HsqlName intoHsqlName, 3144 int intoType) throws HsqlException { 3145 3146 int colCount = result.getColumnCount(); 3149 3150 for (int i = 0; i < colCount; i++) { 3151 if (result.metaData.colLabels[i].length() == 0) { 3152 throw Trace.error(Trace.LABEL_REQUIRED); 3153 } 3154 } 3155 3156 Table t = (intoType == Table.TEXT_TABLE) 3158 ? new TextTable(database, intoHsqlName, intoType) 3159 : new Table(database, intoHsqlName, intoType); 3160 3161 t.addColumns(result.metaData, result.getColumnCount()); 3162 t.createPrimaryKey(); 3163 database.schemaManager.linkTable(t); 3164 3165 if (intoType == Table.TEXT_TABLE) { 3167 try { 3168 3169 String txtSrc = 3172 StringUtil.toLowerSubset(intoHsqlName.name, '_') + ".csv"; 3173 3174 t.setDataSource(session, txtSrc, false, true); 3175 logTableDDL(t); 3176 t.insertIntoTable(session, result); 3177 } catch (HsqlException e) { 3178 database.schemaManager.dropTable(session, intoHsqlName.name, 3179 null, false, false, false); 3180 3181 throw (e); 3182 } 3183 } else { 3184 logTableDDL(t); 3185 3186 t.insertIntoTable(session, result); 3188 } 3189 3190 Result uc = new Result(ResultConstants.UPDATECOUNT); 3191 3192 uc.updateCount = result.getSize(); 3193 3194 return uc; 3195 } 3196 3197 3206 private void logTableDDL(Table t) throws HsqlException { 3207 3208 StringBuffer tableDDL; 3209 String sourceDDL; 3210 3211 tableDDL = new StringBuffer (); 3212 3213 DatabaseScript.getTableDDL(database, t, 0, null, true, tableDDL); 3214 3215 sourceDDL = DatabaseScript.getDataSource(t); 3216 3217 database.logger.writeToLog(session, tableDDL.toString()); 3218 3219 if (sourceDDL != null) { 3220 database.logger.writeToLog(session, sourceDDL); 3221 } 3222 } 3223 3224 private void processAlterTableAddUniqueConstraint(Table t, 3225 HsqlName n) throws HsqlException { 3226 3227 int[] col; 3228 3229 col = processColumnList(t, false); 3230 3231 if (n == null) { 3232 n = database.nameManager.newAutoName("CT"); 3233 } 3234 3235 session.commit(); 3236 3237 TableWorks tableWorks = new TableWorks(session, t); 3238 3239 tableWorks.createUniqueConstraint(col, n); 3240 } 3241 3242 private void processAlterTableAddForeignKeyConstraint(Table t, 3243 HsqlName n) throws HsqlException { 3244 3245 Constraint tc; 3246 3247 if (n == null) { 3248 n = database.nameManager.newAutoName("FK"); 3249 } 3250 3251 tc = processCreateFK(t, n); 3252 3253 checkFKColumnDefaults(t, tc); 3254 t.checkColumnsMatch(tc.core.mainColArray, tc.core.refTable, 3255 tc.core.refColArray); 3256 session.commit(); 3257 3258 TableWorks tableWorks = new TableWorks(session, t); 3259 3260 tableWorks.createForeignKey(tc.core.mainColArray, 3261 tc.core.refColArray, tc.constName, 3262 tc.core.refTable, tc.core.deleteAction, 3263 tc.core.updateAction); 3264 } 3265 3266 private void processAlterTableAddCheckConstraint(Table table, 3267 HsqlName name) throws HsqlException { 3268 3269 Constraint check; 3270 3271 if (name == null) { 3272 name = database.nameManager.newAutoName("CT"); 3273 } 3274 3275 check = new Constraint(name, null, null, null, Constraint.CHECK, 3276 Constraint.NO_ACTION, Constraint.NO_ACTION); 3277 3278 processCreateCheckConstraintCondition(check); 3279 session.commit(); 3280 3281 TableWorks tableWorks = new TableWorks(session, table); 3282 3283 tableWorks.createCheckConstraint(check, name); 3284 } 3285 3286 private void processAlterTableAddPrimaryKey(Table t, 3287 HsqlName n) throws HsqlException { 3288 3289 int[] col; 3290 3291 col = processColumnList(t, false); 3292 3293 session.commit(); 3294 3295 TableWorks tableWorks = new TableWorks(session, t); 3296 3297 tableWorks.addPrimaryKey(col, n); 3298 } 3299 3300 private void processReleaseSavepoint() throws HsqlException { 3301 3302 String token; 3303 3304 tokenizer.getThis(Token.T_SAVEPOINT); 3305 3306 token = tokenizer.getSimpleName(); 3307 3308 session.releaseSavepoint(token); 3309 } 3310 3311 private void processAlterUser() throws HsqlException { 3312 3313 String userName; 3314 String password; 3315 User userObject; 3316 3317 userName = getUserIdentifier(); 3318 userObject = 3319 (User) database.getUserManager().getUsers().get(userName); 3320 3321 Trace.check(userObject != null, Trace.USER_NOT_FOUND, userName); 3322 tokenizer.getThis(Token.T_SET); 3323 tokenizer.getThis(Token.T_PASSWORD); 3324 3325 password = getPassword(); 3326 3327 userObject.setPassword(password); 3328 database.logger.writeToLog(session, userObject.getAlterUserDDL()); 3329 session.setScripting(false); 3330 } 3331 3332 private String getUserIdentifier() throws HsqlException { 3333 3334 String token = tokenizer.getString(); 3335 Tokenizer t = new Tokenizer(token); 3336 3337 return t.getSimpleName(); 3338 } 3339 3340 private String getPassword() throws HsqlException { 3341 3342 String token = tokenizer.getString(); 3343 3344 return token.toUpperCase(Locale.ENGLISH); 3345 } 3346 3347 3353 private void processRoleGrantOrRevoke(boolean grant) 3354 throws HsqlException { 3355 3356 String token; 3357 HsqlArrayList list = new HsqlArrayList(); 3358 String role; 3359 GranteeManager granteeManager = database.getGranteeManager(); 3360 3361 do { 3362 role = tokenizer.getSimpleToken(); 3363 3364 Trace.check(granteeManager.isRole(role), 3365 (grant ? Trace.NO_SUCH_ROLE_GRANT 3366 : Trace.NO_SUCH_ROLE_REVOKE)); 3367 list.add(role); 3368 } while (tokenizer.isGetThis(Token.T_COMMA)); 3369 3370 tokenizer.getThis(grant ? Token.T_TO 3371 : Token.T_FROM); 3372 3373 token = getUserIdentifier(); 3374 3375 GranteeManager gm = database.getGranteeManager(); 3376 3377 for (int i = 0; i < list.size(); i++) { 3378 if (grant) { 3379 gm.grant(token, (String ) list.get(i)); 3380 } else { 3381 gm.revoke(token, (String ) list.get(i)); 3382 } 3383 } 3384 } 3385} 3386 | Popular Tags |