use of org.apache.calcite.sql.ddl.SqlColumnDeclaration in project ignite-3 by apache.
the class DdlSqlToCommandConverter method convertAlterTableAdd.
/**
* Converts a given IgniteSqlAlterTableAddColumn AST to a AlterTableAddCommand.
*
* @param alterTblNode Root node of the given AST.
* @param ctx Planning context.
*/
private AlterTableAddCommand convertAlterTableAdd(IgniteSqlAlterTableAddColumn alterTblNode, PlanningContext ctx) {
AlterTableAddCommand alterTblCmd = new AlterTableAddCommand();
alterTblCmd.schemaName(deriveSchemaName(alterTblNode.name(), ctx));
alterTblCmd.tableName(deriveObjectName(alterTblNode.name(), ctx, "table name"));
alterTblCmd.ifTableExists(alterTblNode.ifExists());
alterTblCmd.ifColumnNotExists(alterTblNode.ifNotExistsColumn());
List<ColumnDefinition> cols = new ArrayList<>(alterTblNode.columns().size());
for (SqlNode colNode : alterTblNode.columns()) {
assert colNode instanceof SqlColumnDeclaration : colNode.getClass();
SqlColumnDeclaration col = (SqlColumnDeclaration) colNode;
assert col.name.isSimple();
Object dflt = null;
if (col.expression != null) {
dflt = ((SqlLiteral) col.expression).getValue();
}
String name = col.name.getSimple();
RelDataType relType = ctx.planner().convert(col.dataType, true);
cols.add(new ColumnDefinition(name, relType, dflt));
}
alterTblCmd.columns(cols);
return alterTblCmd;
}
use of org.apache.calcite.sql.ddl.SqlColumnDeclaration in project dingo by dingodb.
the class DingoDdlExecutor method execute.
@SuppressWarnings({ "unused", "MethodMayBeStatic" })
public void execute(SqlCreateTable create, CalcitePrepare.Context context) {
log.info("DDL execute: {}", create);
final String tableName = getTableName(create.name, context);
TableDefinition td = new TableDefinition(tableName);
List<String> keyList = null;
SqlNodeList columnList = create.columnList;
if (columnList == null) {
throw SqlUtil.newContextException(create.name.getParserPosition(), RESOURCE.createTableRequiresColumnList());
}
for (SqlNode sqlNode : create.columnList) {
if (sqlNode instanceof SqlKeyConstraint) {
SqlKeyConstraint constraint = (SqlKeyConstraint) sqlNode;
if (constraint.getOperator().getKind() == SqlKind.PRIMARY_KEY) {
// The 0th element is the name of the constraint
keyList = ((SqlNodeList) constraint.getOperandList().get(1)).getList().stream().map(t -> ((SqlIdentifier) Objects.requireNonNull(t)).getSimple()).collect(Collectors.toList());
break;
}
}
}
SqlValidator validator = new ContextSqlValidator(context, true);
for (SqlNode sqlNode : create.columnList) {
if (sqlNode.getKind() == SqlKind.COLUMN_DECL) {
SqlColumnDeclaration scd = (SqlColumnDeclaration) sqlNode;
ColumnDefinition cd = fromSqlColumnDeclaration(scd, validator, keyList);
td.addColumn(cd);
}
}
if (td.getColumns().stream().noneMatch(ColumnDefinition::isPrimary)) {
throw new RuntimeException("Not have primary key!");
}
final MutableSchema schema = getSchema(context);
if (schema.getTable(tableName) != null) {
if (!create.ifNotExists) {
// They did not specify IF NOT EXISTS, so give error.
throw SqlUtil.newContextException(create.name.getParserPosition(), RESOURCE.tableExists(tableName));
}
}
schema.createTable(tableName, td);
}
use of org.apache.calcite.sql.ddl.SqlColumnDeclaration in project calcite by apache.
the class ServerDdlExecutor method execute.
/**
* Executes a {@code CREATE TABLE} command.
*/
public void execute(SqlCreateTable create, CalcitePrepare.Context context) {
final Pair<CalciteSchema, String> pair = schema(context, true, create.name);
final JavaTypeFactory typeFactory = context.getTypeFactory();
final RelDataType queryRowType;
if (create.query != null) {
// A bit of a hack: pretend it's a view, to get its row type
final String sql = create.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 (create.columnList != null && queryRowType.getFieldCount() != create.columnList.size()) {
throw SqlUtil.newContextException(create.columnList.getParserPosition(), RESOURCE.columnCountMismatch());
}
} else {
queryRowType = null;
}
final List<SqlNode> columnList;
if (create.columnList != null) {
columnList = create.columnList;
} else {
if (queryRowType == null) {
// a list of column names and types, "CREATE TABLE t (INT c)".
throw SqlUtil.newContextException(create.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();
// REVIEW 2019-08-19 Danny Chan: Should we implement the
// #validate(SqlValidator) to get the SqlValidator instance?
final SqlValidator validator = validator(context, true);
for (Ord<SqlNode> c : Ord.zip(columnList)) {
if (c.e instanceof SqlColumnDeclaration) {
final SqlColumnDeclaration d = (SqlColumnDeclaration) c.e;
final RelDataType type = d.dataType.deriveType(validator, 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) {
// REVIEW Danny 2019-10-09: Should we support validation for DDL nodes?
final SqlNode validated = context.validateExpression(storedRowType, c.expr);
// actually they should be exactly the same.
return context.convertExpression(validated);
}
return super.newColumnDefaultValue(table, iColumn, context);
}
};
if (pair.left.plus().getTable(pair.right) != null) {
// Table exists.
if (create.ifNotExists) {
return;
}
if (!create.getReplace()) {
// They did not specify IF NOT EXISTS, so give error.
throw SqlUtil.newContextException(create.name.getParserPosition(), RESOURCE.tableExists(pair.right));
}
}
// Table does not exist. Create it.
pair.left.add(pair.right, new MutableArrayTable(pair.right, RelDataTypeImpl.proto(storedRowType), RelDataTypeImpl.proto(rowType), ief));
if (create.query != null) {
populate(create.name, create.query, context);
}
}
use of org.apache.calcite.sql.ddl.SqlColumnDeclaration in project ignite-3 by apache.
the class DdlSqlToCommandConverter method convertCreateTable.
/**
* Converts a given CreateTable AST to a CreateTable command.
*
* @param createTblNode Root node of the given AST.
* @param ctx Planning context.
*/
private CreateTableCommand convertCreateTable(IgniteSqlCreateTable createTblNode, PlanningContext ctx) {
CreateTableCommand createTblCmd = new CreateTableCommand();
createTblCmd.schemaName(deriveSchemaName(createTblNode.name(), ctx));
createTblCmd.tableName(deriveObjectName(createTblNode.name(), ctx, "tableName"));
createTblCmd.ifTableExists(createTblNode.ifNotExists());
if (createTblNode.createOptionList() != null) {
for (SqlNode optNode : createTblNode.createOptionList().getList()) {
IgniteSqlCreateTableOption opt = (IgniteSqlCreateTableOption) optNode;
tblOptionProcessors.getOrDefault(opt.key(), UNSUPPORTED_OPTION_PROCESSOR).process(opt, ctx, createTblCmd);
}
}
List<SqlKeyConstraint> pkConstraints = createTblNode.columnList().getList().stream().filter(SqlKeyConstraint.class::isInstance).map(SqlKeyConstraint.class::cast).collect(Collectors.toList());
if (nullOrEmpty(pkConstraints)) {
throw new IgniteException("Table without PRIMARY KEY is not supported");
} else if (pkConstraints.size() > 1) {
throw new IgniteException("Unexpected amount of primary key constraints [" + "expected at most one, but was " + pkConstraints.size() + "; " + "querySql=\"" + ctx.query() + "\"]");
}
Set<String> dedupSetPk = new HashSet<>();
List<String> pkCols = pkConstraints.stream().map(pk -> pk.getOperandList().get(1)).map(SqlNodeList.class::cast).flatMap(l -> l.getList().stream()).map(SqlIdentifier.class::cast).map(SqlIdentifier::getSimple).filter(dedupSetPk::add).collect(Collectors.toList());
createTblCmd.primaryKeyColumns(pkCols);
List<SqlColumnDeclaration> colDeclarations = createTblNode.columnList().getList().stream().filter(SqlColumnDeclaration.class::isInstance).map(SqlColumnDeclaration.class::cast).collect(Collectors.toList());
IgnitePlanner planner = ctx.planner();
List<ColumnDefinition> cols = new ArrayList<>(colDeclarations.size());
for (SqlColumnDeclaration col : colDeclarations) {
if (!col.name.isSimple()) {
throw new IgniteException("Unexpected value of columnName [" + "expected a simple identifier, but was " + col.name + "; " + "querySql=\"" + ctx.query() + "\"]");
}
String name = col.name.getSimple();
if (col.dataType.getNullable() != null && col.dataType.getNullable() && dedupSetPk.contains(name)) {
throw new IgniteException("Primary key cannot contain nullable column [col=" + name + "]");
}
RelDataType relType = planner.convert(col.dataType, !dedupSetPk.contains(name));
dedupSetPk.remove(name);
Object dflt = null;
if (col.expression != null) {
dflt = ((SqlLiteral) col.expression).getValue();
}
cols.add(new ColumnDefinition(name, relType, dflt));
}
if (!dedupSetPk.isEmpty()) {
throw new IgniteException("Primary key constrain contains undefined columns: [cols=" + dedupSetPk + "]");
}
createTblCmd.columns(cols);
return createTblCmd;
}
Aggregations