📄 databasecommandinterpreter.java
字号:
} } } /** * Responsible for handling CREATE ... * * All CREATE command require an ADMIN user except: <p> * * <pre> * CREATE TEMP [MEMORY] TABLE * </pre> * * @throws HsqlException */ private void processCreate() throws HsqlException { boolean unique = false; int tableType; boolean isTempTable = false; String token; session.checkAdmin(); session.checkDDLWrite(); session.setScripting(true); if (tokenizer.isGetThis(Token.T_GLOBAL)) { tokenizer.getThis(Token.T_TEMPORARY); isTempTable = true; } else if (tokenizer.isGetThis(Token.T_TEMP)) { isTempTable = true; } else if (tokenizer.isGetThis(Token.T_TEMPORARY)) { isTempTable = true; } token = tokenizer.getSimpleToken(); switch (Token.get(token)) { // table case Token.MEMORY : tokenizer.getThis(Token.T_TABLE); case Token.TABLE : tableType = isTempTable ? Table.TEMP_TABLE : database.getDefaultTableType(); processCreateTable(tableType); return; case Token.CACHED : if (isTempTable) { throw Trace.error(Trace.UNEXPECTED_TOKEN, token); } tokenizer.getThis(Token.T_TABLE); processCreateTable(Table.CACHED_TABLE); return; case Token.TEXT : if (isTempTable) { throw Trace.error(Trace.UNEXPECTED_TOKEN, token); } tokenizer.getThis(Token.T_TABLE); processCreateTable(Table.TEXT_TABLE); return; default : if (isTempTable) { throw Trace.error(Trace.UNEXPECTED_TOKEN, token); } } switch (Token.get(token)) { // other objects case Token.ALIAS : processCreateAlias(); break; case Token.SEQUENCE : processCreateSequence(); break; case Token.SCHEMA : processCreateSchema(); break; case Token.TRIGGER : processCreateTrigger(); break; case Token.USER : processCreateUser(); break; case Token.ROLE : database.getGranteeManager().createRole(getUserIdentifier()); break; case Token.VIEW : processCreateView(); break; // index case Token.UNIQUE : unique = true; tokenizer.getThis(Token.T_INDEX); //fall thru case Token.INDEX : processCreateIndex(unique); break; default : { throw Trace.error(Trace.UNEXPECTED_TOKEN, token); } } } /** * Process a bracketed column list as used in the declaration of SQL * CONSTRAINTS and return an array containing the indexes of the columns * within the table. * * @param t table that contains the columns * @return column index map * @throws HsqlException if a column is not found or is duplicate */ private int[] processColumnList(Table t) throws HsqlException { HsqlArrayList list; HashSet set; String token; int[] col; int size; list = new HsqlArrayList(); set = new HashSet(); tokenizer.getThis(Token.T_OPENBRACKET); while (true) { token = tokenizer.getSimpleName(); list.add(token); set.add(token); if (list.size() != set.size()) { throw Trace.error(Trace.COLUMN_ALREADY_EXISTS, Trace.ERROR_IN_CONSTRAINT_COLUMN_LIST); } token = tokenizer.getSimpleToken(); if (token.equals(Token.T_DESC) || token.equals(Token.T_ASC)) { token = tokenizer.getSimpleToken(); // OJ: eat it up } if (token.equals(Token.T_COMMA)) { continue; } if (token.equals(Token.T_CLOSEBRACKET)) { break; } throw Trace.error(Trace.UNEXPECTED_TOKEN, token); } size = list.size(); col = new int[size]; for (int i = 0; i < size; i++) { col[i] = t.getColumnNr((String) list.get(i)); } return col; } /** * Responsible for tail end of CREATE INDEX DDL. <p> * * Indexes defined in DDL scripts are handled by this method. If the * name of an existing index begins with "SYS_", the name is changed to * begin with "USER_". The name should be unique within the database. * For compatibility with old database, non-unique names are modified * and assigned a new name. <p> * * In 1.7.2 no new index is created if an equivalent already exists. <p> * * (fredt@users) <p> * * @param t table * @param indexName index * * @param indexNameQuoted is quoted * @param unique is unique * @throws HsqlException */ private void addIndexOn(Table t, String indexName, boolean indexNameQuoted, boolean unique) throws HsqlException { HsqlName indexHsqlName; int[] indexColumns; database.schemaManager.checkIndexExists(indexName, t.getSchemaName(), false); indexHsqlName = newIndexHsqlName(indexName, indexNameQuoted); indexColumns = processColumnList(t); session.commit(); session.setScripting(true); TableWorks tableWorks = new TableWorks(session, t); tableWorks.createIndex(indexColumns, indexHsqlName, unique, false, false); } /** * Responsible for handling the execution of CREATE TRIGGER SQL * statements. <p> * * typical sql is: CREATE TRIGGER tr1 AFTER INSERT ON tab1 CALL "pkg.cls" * * @throws HsqlException */ private void processCreateTrigger() throws HsqlException { Table t; boolean isForEach; boolean isNowait; int queueSize; String triggerName; boolean isQuoted; String sWhen; String sOper; String tableName; String token; String className; TriggerDef td; Trigger o; triggerName = tokenizer.getName(); String schemaname = tokenizer.getLongNameFirst(); database.schemaManager.checkTriggerExists(triggerName, session.getSchemaNameForWrite(schemaname), false); isQuoted = tokenizer.wasQuotedIdentifier(); isForEach = false; isNowait = false; queueSize = TriggerDef.getDefaultQueueSize(); sWhen = tokenizer.getSimpleToken(); sOper = tokenizer.getSimpleToken(); tokenizer.getThis(Token.T_ON); tableName = tokenizer.getName(); if (schemaname == null) { schemaname = session.getSchemaNameForWrite(tokenizer.getLongNameFirst()); } else if (!schemaname.equals( session.getSchemaNameForWrite( tokenizer.getLongNameFirst()))) { throw Trace.error(Trace.INVALID_SCHEMA_NAME_NO_SUBCLASS); } t = database.schemaManager.getUserTable(session, tableName, schemaname); if (t.isView()) { throw Trace.error(Trace.NOT_A_TABLE); } session.setScripting(true); // "FOR EACH ROW" or "CALL" token = tokenizer.getSimpleToken(); if (token.equals(Token.T_FOR)) { token = tokenizer.getSimpleToken(); if (token.equals(Token.T_EACH)) { token = tokenizer.getSimpleToken(); if (token.equals(Token.T_ROW)) { isForEach = true; // should be 'NOWAIT' or 'QUEUE' or 'CALL' token = tokenizer.getSimpleToken(); } else { throw Trace.error(Trace.UNEXPECTED_END_OF_COMMAND, token); } } else { throw Trace.error(Trace.UNEXPECTED_END_OF_COMMAND, token); } } if (token.equals(Token.T_NOWAIT)) { isNowait = true; // should be 'CALL' or 'QUEUE' token = tokenizer.getSimpleToken(); } if (token.equals(Token.T_QUEUE)) { queueSize = tokenizer.getInt(); // should be 'CALL' token = tokenizer.getSimpleToken(); } if (!token.equals(Token.T_CALL)) { throw Trace.error(Trace.UNEXPECTED_END_OF_COMMAND, token); } className = tokenizer.getSimpleName(); if (!tokenizer.wasQuotedIdentifier()) { throw Trace.error(Trace.UNEXPECTED_END_OF_COMMAND, className); } HsqlName name = database.nameManager.newHsqlName(triggerName, isQuoted); td = new TriggerDef(name, sWhen, sOper, isForEach, t, className, isNowait, queueSize, database.classLoader); t.addTrigger(td); if (td.isValid()) { try { // start the trigger thread td.start(); } catch (Exception e) { throw Trace.error(Trace.UNKNOWN_FUNCTION, e.getMessage()); } } database.schemaManager.registerTriggerName(triggerName, t.getName());// -- } private Column processCreateColumn() throws HsqlException { String token = tokenizer.getSimpleName(); boolean isQuoted = tokenizer.wasQuotedIdentifier(); HsqlName hsqlName = database.nameManager.newHsqlName(token, isQuoted); return processCreateColumn(hsqlName); } /** * Responsible for handling the creation of table columns during the * process of executing CREATE TABLE DDL statements. * * @param hsqlName name of the column * @return a Column object with indicated attributes * @throws HsqlException */ private Column processCreateColumn(HsqlName hsqlName) throws HsqlException { boolean isIdentity = false; long identityStart = database.firstIdentity; long identityIncrement = 1; boolean isPrimaryKey = false; String typeName; int type; int length = 0; int scale = 0; boolean hasLength = false; boolean isNullable = true; Expression defaultExpr = null; String token; typeName = tokenizer.getSimpleToken(); type = Types.getTypeNr(typeName); if (type == Types.CHAR) { if (tokenizer.isGetThis(Token.T_VARYING)) { type = Types.VARCHAR; } } if (typeName.equals(Token.T_IDENTITY)) { isIdentity = true; isPrimaryKey = true; } // fredt - when SET IGNORECASE is in effect, all new VARCHAR columns are defined as VARCHAR_IGNORECASE if (type == Types.DOUBLE) { tokenizer.isGetThis(Token.T_PRECISION); } if (tokenizer.isGetThis(Token.T_OPENBRACKET)) { hasLength = true; length = tokenizer.getInt(); Trace.check(Types.acceptsPrecisionCreateParam(type), Trace.UNEXPECTED_TOKEN);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -