Search in sources :

Example 1 with InitializerContext

use of org.apache.calcite.sql2rel.InitializerContext in project calcite by apache.

the class SqlCreateTable method execute.

public void execute(CalcitePrepare.Context context) {
    final Pair<CalciteSchema, String> pair = SqlDdlNodes.schema(context, true, name);
    final JavaTypeFactory typeFactory = new JavaTypeFactoryImpl();
    final RelDataType queryRowType;
    if (query != null) {
        // A bit of a hack: pretend it's a view, to get its row type
        final String sql = query.toSqlString(CalciteSqlDialect.DEFAULT).getSql();
        final ViewTableMacro viewTableMacro = ViewTable.viewMacro(pair.left.plus(), sql, pair.left.path(null), context.getObjectPath(), false);
        final TranslatableTable x = viewTableMacro.apply(ImmutableList.of());
        queryRowType = x.getRowType(typeFactory);
        if (columnList != null && queryRowType.getFieldCount() != columnList.size()) {
            throw SqlUtil.newContextException(columnList.getParserPosition(), RESOURCE.columnCountMismatch());
        }
    } else {
        queryRowType = null;
    }
    final List<SqlNode> columnList;
    if (this.columnList != null) {
        columnList = this.columnList.getList();
    } else {
        if (queryRowType == null) {
            // a list of column names and types, "CREATE TABLE t (INT c)".
            throw SqlUtil.newContextException(name.getParserPosition(), RESOURCE.createTableRequiresColumnList());
        }
        columnList = new ArrayList<>();
        for (String name : queryRowType.getFieldNames()) {
            columnList.add(new SqlIdentifier(name, SqlParserPos.ZERO));
        }
    }
    final ImmutableList.Builder<ColumnDef> b = ImmutableList.builder();
    final RelDataTypeFactory.Builder builder = typeFactory.builder();
    final RelDataTypeFactory.Builder storedBuilder = typeFactory.builder();
    for (Ord<SqlNode> c : Ord.zip(columnList)) {
        if (c.e instanceof SqlColumnDeclaration) {
            final SqlColumnDeclaration d = (SqlColumnDeclaration) c.e;
            final RelDataType type = d.dataType.deriveType(typeFactory, true);
            builder.add(d.name.getSimple(), type);
            if (d.strategy != ColumnStrategy.VIRTUAL) {
                storedBuilder.add(d.name.getSimple(), type);
            }
            b.add(ColumnDef.of(d.expression, type, d.strategy));
        } else if (c.e instanceof SqlIdentifier) {
            final SqlIdentifier id = (SqlIdentifier) c.e;
            if (queryRowType == null) {
                throw SqlUtil.newContextException(id.getParserPosition(), RESOURCE.createTableRequiresColumnTypes(id.getSimple()));
            }
            final RelDataTypeField f = queryRowType.getFieldList().get(c.i);
            final ColumnStrategy strategy = f.getType().isNullable() ? ColumnStrategy.NULLABLE : ColumnStrategy.NOT_NULLABLE;
            b.add(ColumnDef.of(c.e, f.getType(), strategy));
            builder.add(id.getSimple(), f.getType());
            storedBuilder.add(id.getSimple(), f.getType());
        } else {
            throw new AssertionError(c.e.getClass());
        }
    }
    final RelDataType rowType = builder.build();
    final RelDataType storedRowType = storedBuilder.build();
    final List<ColumnDef> columns = b.build();
    final InitializerExpressionFactory ief = new NullInitializerExpressionFactory() {

        @Override
        public ColumnStrategy generationStrategy(RelOptTable table, int iColumn) {
            return columns.get(iColumn).strategy;
        }

        @Override
        public RexNode newColumnDefaultValue(RelOptTable table, int iColumn, InitializerContext context) {
            final ColumnDef c = columns.get(iColumn);
            if (c.expr != null) {
                return context.convertExpression(c.expr);
            }
            return super.newColumnDefaultValue(table, iColumn, context);
        }
    };
    if (pair.left.plus().getTable(pair.right) != null) {
        // Table exists.
        if (!ifNotExists) {
            // They did not specify IF NOT EXISTS, so give error.
            throw SqlUtil.newContextException(name.getParserPosition(), RESOURCE.tableExists(pair.right));
        }
        return;
    }
    // Table does not exist. Create it.
    pair.left.add(pair.right, new MutableArrayTable(pair.right, RelDataTypeImpl.proto(storedRowType), RelDataTypeImpl.proto(rowType), ief));
    if (query != null) {
        SqlDdlNodes.populate(name, query, context);
    }
}
Also used : NullInitializerExpressionFactory(org.apache.calcite.sql2rel.NullInitializerExpressionFactory) NullInitializerExpressionFactory(org.apache.calcite.sql2rel.NullInitializerExpressionFactory) InitializerExpressionFactory(org.apache.calcite.sql2rel.InitializerExpressionFactory) ImmutableList(com.google.common.collect.ImmutableList) ViewTableMacro(org.apache.calcite.schema.impl.ViewTableMacro) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) JavaTypeFactoryImpl(org.apache.calcite.jdbc.JavaTypeFactoryImpl) JavaTypeFactory(org.apache.calcite.adapter.java.JavaTypeFactory) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) TranslatableTable(org.apache.calcite.schema.TranslatableTable) SqlNode(org.apache.calcite.sql.SqlNode) ColumnStrategy(org.apache.calcite.schema.ColumnStrategy) InitializerContext(org.apache.calcite.sql2rel.InitializerContext) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) CalciteSchema(org.apache.calcite.jdbc.CalciteSchema) RelOptTable(org.apache.calcite.plan.RelOptTable)

Example 2 with InitializerContext

use of org.apache.calcite.sql2rel.InitializerContext in project calcite by apache.

the class SqlValidatorImpl method checkFieldCount.

private void checkFieldCount(SqlNode node, SqlValidatorTable table, SqlNode source, RelDataType logicalSourceRowType, RelDataType logicalTargetRowType) {
    final int sourceFieldCount = logicalSourceRowType.getFieldCount();
    final int targetFieldCount = logicalTargetRowType.getFieldCount();
    if (sourceFieldCount != targetFieldCount) {
        throw newValidationError(node, RESOURCE.unmatchInsertColumn(targetFieldCount, sourceFieldCount));
    }
    // Ensure that non-nullable fields are targeted.
    final InitializerContext rexBuilder = new InitializerContext() {

        public RexBuilder getRexBuilder() {
            return new RexBuilder(typeFactory);
        }

        public RexNode convertExpression(SqlNode e) {
            throw new UnsupportedOperationException();
        }
    };
    final List<ColumnStrategy> strategies = table.unwrap(RelOptTable.class).getColumnStrategies();
    for (final RelDataTypeField field : table.getRowType().getFieldList()) {
        final RelDataTypeField targetField = logicalTargetRowType.getField(field.getName(), true, false);
        switch(strategies.get(field.getIndex())) {
            case NOT_NULLABLE:
                assert !field.getType().isNullable();
                if (targetField == null) {
                    throw newValidationError(node, RESOURCE.columnNotNullable(field.getName()));
                }
                break;
            case NULLABLE:
                assert field.getType().isNullable();
                break;
            case VIRTUAL:
            case STORED:
                if (targetField != null && !isValuesWithDefault(source, targetField.getIndex())) {
                    throw newValidationError(node, RESOURCE.insertIntoAlwaysGenerated(field.getName()));
                }
        }
    }
}
Also used : ColumnStrategy(org.apache.calcite.schema.ColumnStrategy) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) InitializerContext(org.apache.calcite.sql2rel.InitializerContext) RexBuilder(org.apache.calcite.rex.RexBuilder) RelOptTable(org.apache.calcite.plan.RelOptTable) SqlNode(org.apache.calcite.sql.SqlNode)

Aggregations

RelOptTable (org.apache.calcite.plan.RelOptTable)2 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)2 ColumnStrategy (org.apache.calcite.schema.ColumnStrategy)2 SqlNode (org.apache.calcite.sql.SqlNode)2 InitializerContext (org.apache.calcite.sql2rel.InitializerContext)2 ImmutableList (com.google.common.collect.ImmutableList)1 JavaTypeFactory (org.apache.calcite.adapter.java.JavaTypeFactory)1 CalciteSchema (org.apache.calcite.jdbc.CalciteSchema)1 JavaTypeFactoryImpl (org.apache.calcite.jdbc.JavaTypeFactoryImpl)1 RelDataType (org.apache.calcite.rel.type.RelDataType)1 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)1 RexBuilder (org.apache.calcite.rex.RexBuilder)1 TranslatableTable (org.apache.calcite.schema.TranslatableTable)1 ViewTableMacro (org.apache.calcite.schema.impl.ViewTableMacro)1 SqlIdentifier (org.apache.calcite.sql.SqlIdentifier)1 InitializerExpressionFactory (org.apache.calcite.sql2rel.InitializerExpressionFactory)1 NullInitializerExpressionFactory (org.apache.calcite.sql2rel.NullInitializerExpressionFactory)1