Search in sources :

Example 1 with DefineCommand

use of org.h2.command.ddl.DefineCommand in project h2database by h2database.

the class Parser method parseTableColumnDefinition.

private void parseTableColumnDefinition(CommandWithColumns command, Schema schema, String tableName) {
    DefineCommand c = parseAlterTableAddConstraintIf(tableName, schema, false);
    if (c != null) {
        command.addConstraintCommand(c);
    } else {
        String columnName = readColumnIdentifier();
        Column column = parseColumnForTable(columnName, true);
        if (column.isAutoIncrement() && column.isPrimaryKey()) {
            column.setPrimaryKey(false);
            IndexColumn[] cols = { new IndexColumn() };
            cols[0].columnName = column.getName();
            AlterTableAddConstraint pk = new AlterTableAddConstraint(session, schema, false);
            pk.setType(CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_PRIMARY_KEY);
            pk.setTableName(tableName);
            pk.setIndexColumns(cols);
            command.addConstraintCommand(pk);
        }
        command.addColumn(column);
        String constraintName = null;
        if (readIf("CONSTRAINT")) {
            constraintName = readColumnIdentifier();
        }
        // For compatibility with Apache Ignite.
        boolean allowAffinityKey = database.getMode().allowAffinityKey;
        boolean affinity = allowAffinityKey && readIfAffinity();
        if (readIf("PRIMARY")) {
            read("KEY");
            boolean hash = readIf("HASH");
            IndexColumn[] cols = { new IndexColumn() };
            cols[0].columnName = column.getName();
            AlterTableAddConstraint pk = new AlterTableAddConstraint(session, schema, false);
            pk.setConstraintName(constraintName);
            pk.setPrimaryKeyHash(hash);
            pk.setType(CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_PRIMARY_KEY);
            pk.setTableName(tableName);
            pk.setIndexColumns(cols);
            command.addConstraintCommand(pk);
            if (readIf("AUTO_INCREMENT")) {
                parseAutoIncrement(column);
            }
            if (affinity) {
                CreateIndex idx = createAffinityIndex(schema, tableName, cols);
                command.addConstraintCommand(idx);
            }
        } else if (affinity) {
            read("KEY");
            IndexColumn[] cols = { new IndexColumn() };
            cols[0].columnName = column.getName();
            CreateIndex idx = createAffinityIndex(schema, tableName, cols);
            command.addConstraintCommand(idx);
        } else if (readIf("UNIQUE")) {
            AlterTableAddConstraint unique = new AlterTableAddConstraint(session, schema, false);
            unique.setConstraintName(constraintName);
            unique.setType(CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_UNIQUE);
            IndexColumn[] cols = { new IndexColumn() };
            cols[0].columnName = columnName;
            unique.setIndexColumns(cols);
            unique.setTableName(tableName);
            command.addConstraintCommand(unique);
        }
        if (NullConstraintType.NULL_IS_NOT_ALLOWED == parseNotNullConstraint()) {
            column.setNullable(false);
        }
        if (readIf("CHECK")) {
            Expression expr = readExpression();
            column.addCheckConstraint(session, expr);
        }
        if (readIf("REFERENCES")) {
            AlterTableAddConstraint ref = new AlterTableAddConstraint(session, schema, false);
            ref.setConstraintName(constraintName);
            ref.setType(CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_REFERENTIAL);
            IndexColumn[] cols = { new IndexColumn() };
            cols[0].columnName = columnName;
            ref.setIndexColumns(cols);
            ref.setTableName(tableName);
            parseReferences(ref, schema, tableName);
            command.addConstraintCommand(ref);
        }
    }
}
Also used : AlterTableAddConstraint(org.h2.command.ddl.AlterTableAddConstraint) CreateIndex(org.h2.command.ddl.CreateIndex) AlterTableRenameColumn(org.h2.command.ddl.AlterTableRenameColumn) AlterTableAlterColumn(org.h2.command.ddl.AlterTableAlterColumn) Column(org.h2.table.Column) ExpressionColumn(org.h2.expression.ExpressionColumn) IndexColumn(org.h2.table.IndexColumn) Expression(org.h2.expression.Expression) ValueExpression(org.h2.expression.ValueExpression) ValueString(org.h2.value.ValueString) DefineCommand(org.h2.command.ddl.DefineCommand) IndexColumn(org.h2.table.IndexColumn)

Example 2 with DefineCommand

use of org.h2.command.ddl.DefineCommand in project h2database by h2database.

the class Parser method parseAlterTableAddConstraintIf.

private DefineCommand parseAlterTableAddConstraintIf(String tableName, Schema schema, boolean ifTableExists) {
    String constraintName = null, comment = null;
    boolean ifNotExists = false;
    boolean allowIndexDefinition = database.getMode().indexDefinitionInCreateTable;
    boolean allowAffinityKey = database.getMode().allowAffinityKey;
    if (readIf("CONSTRAINT")) {
        ifNotExists = readIfNotExists();
        constraintName = readIdentifierWithSchema(schema.getName());
        checkSchema(schema);
        comment = readCommentIf();
        allowIndexDefinition = true;
    }
    if (readIf("PRIMARY")) {
        read("KEY");
        AlterTableAddConstraint command = new AlterTableAddConstraint(session, schema, ifNotExists);
        command.setType(CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_PRIMARY_KEY);
        command.setComment(comment);
        command.setConstraintName(constraintName);
        command.setTableName(tableName);
        command.setIfTableExists(ifTableExists);
        if (readIf("HASH")) {
            command.setPrimaryKeyHash(true);
        }
        read("(");
        command.setIndexColumns(parseIndexColumnList());
        if (readIf("INDEX")) {
            String indexName = readIdentifierWithSchema();
            command.setIndex(getSchema().findIndex(session, indexName));
        }
        return command;
    } else if (allowIndexDefinition && (isToken("INDEX") || isToken("KEY"))) {
        // MySQL
        // need to read ahead, as it could be a column name
        int start = lastParseIndex;
        read();
        if (DataType.getTypeByName(currentToken, database.getMode()) != null) {
            // known data type
            parseIndex = start;
            read();
            return null;
        }
        CreateIndex command = new CreateIndex(session, schema);
        command.setComment(comment);
        command.setTableName(tableName);
        command.setIfTableExists(ifTableExists);
        if (!readIf("(")) {
            command.setIndexName(readUniqueIdentifier());
            read("(");
        }
        command.setIndexColumns(parseIndexColumnList());
        // MySQL compatibility
        if (readIf("USING")) {
            read("BTREE");
        }
        return command;
    } else if (allowAffinityKey && readIfAffinity()) {
        read("KEY");
        read("(");
        CreateIndex command = createAffinityIndex(schema, tableName, parseIndexColumnList());
        command.setIfTableExists(ifTableExists);
        return command;
    }
    AlterTableAddConstraint command;
    if (readIf("CHECK")) {
        command = new AlterTableAddConstraint(session, schema, ifNotExists);
        command.setType(CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_CHECK);
        command.setCheckExpression(readExpression());
    } else if (readIf("UNIQUE")) {
        readIf("KEY");
        readIf("INDEX");
        command = new AlterTableAddConstraint(session, schema, ifNotExists);
        command.setType(CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_UNIQUE);
        if (!readIf("(")) {
            constraintName = readUniqueIdentifier();
            read("(");
        }
        command.setIndexColumns(parseIndexColumnList());
        if (readIf("INDEX")) {
            String indexName = readIdentifierWithSchema();
            command.setIndex(getSchema().findIndex(session, indexName));
        }
        // MySQL compatibility
        if (readIf("USING")) {
            read("BTREE");
        }
    } else if (readIf("FOREIGN")) {
        command = new AlterTableAddConstraint(session, schema, ifNotExists);
        command.setType(CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_REFERENTIAL);
        read("KEY");
        read("(");
        command.setIndexColumns(parseIndexColumnList());
        if (readIf("INDEX")) {
            String indexName = readIdentifierWithSchema();
            command.setIndex(schema.findIndex(session, indexName));
        }
        read("REFERENCES");
        parseReferences(command, schema, tableName);
    } else {
        if (constraintName != null) {
            throw getSyntaxError();
        }
        return null;
    }
    if (readIf("NOCHECK")) {
        command.setCheckExisting(false);
    } else {
        readIf("CHECK");
        command.setCheckExisting(true);
    }
    command.setTableName(tableName);
    command.setIfTableExists(ifTableExists);
    command.setConstraintName(constraintName);
    command.setComment(comment);
    return command;
}
Also used : AlterTableAddConstraint(org.h2.command.ddl.AlterTableAddConstraint) CreateIndex(org.h2.command.ddl.CreateIndex) ValueString(org.h2.value.ValueString)

Example 3 with DefineCommand

use of org.h2.command.ddl.DefineCommand in project ignite by apache.

the class GridSqlQueryParser method parseCreateTable.

/**
 * Parse {@code CREATE TABLE} statement.
 *
 * @param createTbl {@code CREATE TABLE} statement.
 * @see <a href="http://h2database.com/html/grammar.html#create_table">H2 {@code CREATE TABLE} spec.</a>
 */
private GridSqlCreateTable parseCreateTable(CreateTable createTbl) {
    GridSqlCreateTable res = new GridSqlCreateTable();
    res.templateName(QueryUtils.TEMPLATE_PARTITIONED);
    Query qry = CREATE_TABLE_QUERY.get(createTbl);
    if (qry != null) {
        throw new IgniteSQLException("CREATE TABLE ... AS ... syntax is not supported", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
    }
    List<DefineCommand> constraints = CREATE_TABLE_CONSTRAINTS.get(createTbl);
    if (F.isEmpty(constraints)) {
        throw new IgniteSQLException("No PRIMARY KEY defined for CREATE TABLE", IgniteQueryErrorCode.PARSING);
    }
    if (constraints.size() > 1) {
        throw new IgniteSQLException("Too many constraints - only PRIMARY KEY is supported for CREATE TABLE", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
    }
    DefineCommand constraint = constraints.get(0);
    if (!(constraint instanceof AlterTableAddConstraint)) {
        throw new IgniteSQLException("Unsupported type of constraint for CREATE TABLE - only PRIMARY KEY " + "is supported", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
    }
    AlterTableAddConstraint alterTbl = (AlterTableAddConstraint) constraint;
    if (alterTbl.getType() != Command.ALTER_TABLE_ADD_CONSTRAINT_PRIMARY_KEY) {
        throw new IgniteSQLException("Unsupported type of constraint for CREATE TABLE - only PRIMARY KEY " + "is supported", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
    }
    Schema schema = SCHEMA_COMMAND_SCHEMA.get(createTbl);
    res.schemaName(schema.getName());
    CreateTableData data = CREATE_TABLE_DATA.get(createTbl);
    if (data.globalTemporary) {
        throw new IgniteSQLException("GLOBAL TEMPORARY keyword is not supported", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
    }
    if (data.temporary) {
        throw new IgniteSQLException("TEMPORARY keyword is not supported", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
    }
    if (data.isHidden) {
        throw new IgniteSQLException("HIDDEN keyword is not supported", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
    }
    if (!data.persistIndexes) {
        throw new IgniteSQLException("MEMORY and NOT PERSISTENT keywords are not supported", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
    }
    LinkedHashMap<String, GridSqlColumn> cols = new LinkedHashMap<>(data.columns.size());
    for (Column col : data.columns) {
        if (cols.put(col.getName(), parseColumn(col)) != null)
            throw new IgniteSQLException("Duplicate column name: " + col.getName(), IgniteQueryErrorCode.PARSING);
    }
    if (cols.containsKey(QueryUtils.KEY_FIELD_NAME.toUpperCase()) || cols.containsKey(QueryUtils.VAL_FIELD_NAME.toUpperCase())) {
        throw new IgniteSQLException("Direct specification of _KEY and _VAL columns is forbidden", IgniteQueryErrorCode.PARSING);
    }
    IndexColumn[] pkIdxCols = CREATE_TABLE_PK.get(createTbl);
    if (F.isEmpty(pkIdxCols))
        throw new AssertionError("No PRIMARY KEY columns specified");
    LinkedHashSet<String> pkCols = new LinkedHashSet<>();
    for (IndexColumn pkIdxCol : pkIdxCols) {
        GridSqlColumn gridCol = cols.get(pkIdxCol.columnName);
        if (gridCol == null) {
            throw new IgniteSQLException("PRIMARY KEY column is not defined: " + pkIdxCol.columnName, IgniteQueryErrorCode.PARSING);
        }
        pkCols.add(gridCol.columnName());
    }
    int keyColsNum = pkCols.size();
    int valColsNum = cols.size() - keyColsNum;
    if (valColsNum == 0) {
        throw new IgniteSQLException("Table must have at least one non PRIMARY KEY column.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
    }
    res.columns(cols);
    res.primaryKeyColumns(pkCols);
    res.tableName(data.tableName);
    res.ifNotExists(CREATE_TABLE_IF_NOT_EXISTS.get(createTbl));
    List<String> extraParams = data.tableEngineParams != null ? new ArrayList<String>() : null;
    if (data.tableEngineParams != null)
        for (String s : data.tableEngineParams) extraParams.addAll(F.asList(s.split(",")));
    res.params(extraParams);
    if (!F.isEmpty(extraParams)) {
        Map<String, String> params = new HashMap<>();
        for (String p : extraParams) {
            String[] parts = p.split(PARAM_NAME_VALUE_SEPARATOR);
            if (parts.length > 2) {
                throw new IgniteSQLException("Invalid parameter (key[=value] expected): " + p, IgniteQueryErrorCode.PARSING);
            }
            String name = parts[0].trim().toUpperCase();
            String val = parts.length > 1 ? parts[1].trim() : null;
            if (F.isEmpty(name)) {
                throw new IgniteSQLException("Invalid parameter (key[=value] expected): " + p, IgniteQueryErrorCode.PARSING);
            }
            if (params.put(name, val) != null)
                throw new IgniteSQLException("Duplicate parameter: " + p, IgniteQueryErrorCode.PARSING);
        }
        for (Map.Entry<String, String> e : params.entrySet()) processExtraParam(e.getKey(), e.getValue(), res);
    }
    // Process key wrapping.
    Boolean wrapKey = res.wrapKey();
    if (wrapKey != null && !wrapKey) {
        if (keyColsNum > 1) {
            throw new IgniteSQLException(PARAM_WRAP_KEY + " cannot be false when composite primary key exists.", IgniteQueryErrorCode.PARSING);
        }
        if (!F.isEmpty(res.keyTypeName())) {
            throw new IgniteSQLException(PARAM_WRAP_KEY + " cannot be false when " + PARAM_KEY_TYPE + " is set.", IgniteQueryErrorCode.PARSING);
        }
    }
    boolean wrapKey0 = (res.wrapKey() != null && res.wrapKey()) || !F.isEmpty(res.keyTypeName()) || keyColsNum > 1;
    res.wrapKey(wrapKey0);
    // Process value wrapping.
    Boolean wrapVal = res.wrapValue();
    if (wrapVal != null && !wrapVal) {
        if (valColsNum > 1) {
            throw new IgniteSQLException(PARAM_WRAP_VALUE + " cannot be false when multiple non-primary key " + "columns exist.", IgniteQueryErrorCode.PARSING);
        }
        if (!F.isEmpty(res.valueTypeName())) {
            throw new IgniteSQLException(PARAM_WRAP_VALUE + " cannot be false when " + PARAM_VAL_TYPE + " is set.", IgniteQueryErrorCode.PARSING);
        }
        res.wrapValue(false);
    } else
        // By default value is always wrapped to allow for ALTER TABLE ADD COLUMN commands.
        res.wrapValue(true);
    if (!F.isEmpty(res.valueTypeName()) && F.eq(res.keyTypeName(), res.valueTypeName())) {
        throw new IgniteSQLException("Key and value type names " + "should be different for CREATE TABLE: " + res.valueTypeName(), IgniteQueryErrorCode.PARSING);
    }
    if (res.affinityKey() == null) {
        LinkedHashSet<String> pkCols0 = res.primaryKeyColumns();
        if (!F.isEmpty(pkCols0) && pkCols0.size() == 1 && wrapKey0)
            res.affinityKey(pkCols0.iterator().next());
    }
    return res;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Query(org.h2.command.dml.Query) LinkedHashMap(java.util.LinkedHashMap) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) Schema(org.h2.schema.Schema) DefineCommand(org.h2.command.ddl.DefineCommand) LinkedHashMap(java.util.LinkedHashMap) IndexColumn(org.h2.table.IndexColumn) GridSqlType.fromColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlType.fromColumn) AlterTableAlterColumn(org.h2.command.ddl.AlterTableAlterColumn) Column(org.h2.table.Column) ExpressionColumn(org.h2.expression.ExpressionColumn) IndexColumn(org.h2.table.IndexColumn) AlterTableAddConstraint(org.h2.command.ddl.AlterTableAddConstraint) CreateTableData(org.h2.command.ddl.CreateTableData) AlterTableAddConstraint(org.h2.command.ddl.AlterTableAddConstraint) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap)

Aggregations

AlterTableAddConstraint (org.h2.command.ddl.AlterTableAddConstraint)3 AlterTableAlterColumn (org.h2.command.ddl.AlterTableAlterColumn)2 CreateIndex (org.h2.command.ddl.CreateIndex)2 DefineCommand (org.h2.command.ddl.DefineCommand)2 ExpressionColumn (org.h2.expression.ExpressionColumn)2 Column (org.h2.table.Column)2 IndexColumn (org.h2.table.IndexColumn)2 ValueString (org.h2.value.ValueString)2 HashMap (java.util.HashMap)1 IdentityHashMap (java.util.IdentityHashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 LinkedHashSet (java.util.LinkedHashSet)1 Map (java.util.Map)1 IgniteSQLException (org.apache.ignite.internal.processors.query.IgniteSQLException)1 GridSqlType.fromColumn (org.apache.ignite.internal.processors.query.h2.sql.GridSqlType.fromColumn)1 AlterTableRenameColumn (org.h2.command.ddl.AlterTableRenameColumn)1 CreateTableData (org.h2.command.ddl.CreateTableData)1 Query (org.h2.command.dml.Query)1 Expression (org.h2.expression.Expression)1 ValueExpression (org.h2.expression.ValueExpression)1