private GridSqlCreateTable parseCreateTable()

in modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java [1095:1290]


    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(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
            res.wrapValue(true); // By default value is always wrapped to allow for ALTER TABLE ADD COLUMN commands.

        if (!F.isEmpty(res.valueTypeName()) && Objects.equals(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;
    }