Skip to content

Commit fdd3651

Browse files
committed
[SQL] Do not lose IF NOT EXISTS and OR REPLACE
Signed-off-by: Mihai Budiu <mbudiu@feldera.com>
1 parent d506652 commit fdd3651

File tree

14 files changed

+135
-60
lines changed

14 files changed

+135
-60
lines changed

sql-to-dbsp-compiler/SQL-compiler/src/main/codegen/includes/ddl.ftl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ SqlCreateIndex SqlCreateIndex(Span s, boolean replace) :
353353
indexed = CompoundIdentifier()
354354
columnList = ParenthesizedSimpleIdentifierList()
355355
{
356-
return new SqlCreateIndex(s.end(this), id, indexed, columnList);
356+
return new SqlCreateIndex(s.end(this), id, indexed, columnList, replace, false);
357357
}
358358
}
359359

sql-to-dbsp-compiler/SQL-compiler/src/main/java/org/dbsp/sqlCompiler/compiler/ProgramMetadata.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,9 @@ public void addTable(IHasSchema description) {
157157
this.inputTables.put(description.getName(), description);
158158
}
159159

160-
public void removeTable(ProgramIdentifier name) {
161-
this.inputTables.remove(name);
160+
public boolean removeTable(ProgramIdentifier name) {
161+
IHasSchema removed = this.inputTables.remove(name);
162+
return removed != null;
162163
}
163164

164165
public void addView(IHasSchema description) {

sql-to-dbsp-compiler/SQL-compiler/src/main/java/org/dbsp/sqlCompiler/compiler/frontend/CalciteToDBSPCompiler.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3209,12 +3209,16 @@ DBSPNode compileCreateType(CreateTypeStatement stat) {
32093209
@Nullable
32103210
DBSPNode compileDropTable(DropTableStatement drop) {
32113211
ProgramIdentifier tableName = drop.tableName;
3212-
this.metadata.removeTable(tableName);
3212+
boolean removed = this.metadata.removeTable(tableName);
3213+
if (!drop.ifExists && !removed)
3214+
throw new CompilationError("DROPping table " + tableName.singleQuote() + " which does not exist");
32133215
DBSPCircuit circuit = this.getCircuit();
32143216
IInputOperator input = circuit.getInput(tableName);
3215-
Objects.requireNonNull(input);
3216-
circuit.allOperators.remove(input.asOperator());
3217-
circuit.sourceOperators.remove(tableName);
3217+
if (removed) {
3218+
Objects.requireNonNull(input);
3219+
circuit.allOperators.remove(input.asOperator());
3220+
circuit.sourceOperators.remove(tableName);
3221+
}
32183222
return null;
32193223
}
32203224

sql-to-dbsp-compiler/SQL-compiler/src/main/java/org/dbsp/sqlCompiler/compiler/frontend/calciteCompiler/Catalog.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,10 @@ protected Multimap<String, Function> getFunctionMultimap() {
9898
return this.functionMap;
9999
}
100100

101-
public void dropTable(ProgramIdentifier tableName) {
102-
this.tableMap.remove(tableName.name());
101+
public boolean dropTable(ProgramIdentifier tableName) {
102+
Table original = this.tableMap.remove(tableName.name());
103103
this.definition.remove(tableName.name());
104+
return original != null;
104105
}
105106

106107
public boolean addType(ProgramIdentifier name, IErrorReporter reporter, RelStatement statement) {

sql-to-dbsp-compiler/SQL-compiler/src/main/java/org/dbsp/sqlCompiler/compiler/frontend/calciteCompiler/SqlToRelCompiler.java

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1750,16 +1750,20 @@ CalciteContextException rewriteException(
17501750
private DropTableStatement compileDropTable(ParsedStatement node) {
17511751
SqlDropTable dt = (SqlDropTable) node.statement();
17521752
ProgramIdentifier tableName = ProgramIdentifier.fromSqlId(dt.name);
1753-
this.calciteCatalog.dropTable(tableName);
1754-
return new DropTableStatement(node, tableName);
1753+
boolean dropped = this.calciteCatalog.dropTable(tableName);
1754+
if (!dt.ifExists && dropped)
1755+
throw new CompilationError("DROPping table " + tableName.singleQuote() + " which does not exist");
1756+
return new DropTableStatement(node, tableName, dt.ifExists);
17551757
}
17561758

17571759
@Nullable
17581760
private CreateIndexStatement compileCreateIndex(ParsedStatement node) {
17591761
CalciteObject object = CalciteObject.create(node);
17601762
SqlCreateIndex ci = (SqlCreateIndex) node.statement();
17611763
if (ci.ifNotExists)
1762-
throw new UnsupportedException("IF NOT EXISTS not supported for INDEX", object);
1764+
throw new UnsupportedException("IF NOT EXISTS not supported for CREATE INDEX", object);
1765+
if (ci.getReplace())
1766+
throw new UnsupportedException("OR REPLACE not supported for CREATE INDEX", object);
17631767
Map<ProgramIdentifier, SqlIdentifier> columns = new HashMap<>();
17641768
if (ci.columns.isEmpty()) {
17651769
this.errorReporter.reportError(new SourcePositionRange(ci.getParserPosition()),
@@ -1798,7 +1802,9 @@ private CreateTableStatement compileCreateTable(ParsedStatement node, SourceFile
17981802
CalciteObject object = CalciteObject.create(node);
17991803
SqlCreateTable ct = (SqlCreateTable) node.statement();
18001804
if (ct.ifNotExists)
1801-
throw new UnsupportedException("IF NOT EXISTS not supported for TABLE", object);
1805+
throw new UnsupportedException("IF NOT EXISTS not supported for CREATE TABLE", object);
1806+
if (ct.getReplace())
1807+
throw new UnsupportedException("REPLACE not supported for CREATE TABLE", object);
18021808
ProgramIdentifier tableName = ProgramIdentifier.fromSqlId(ct.name);
18031809
if (node.visible() && this.functionExists(tableName.name())) {
18041810
this.errorReporter.reportError(new SourcePositionRange(ct.name.getParserPosition()),
@@ -1827,6 +1833,11 @@ private CreateTableStatement compileCreateTable(ParsedStatement node, SourceFile
18271833

18281834
public CreateAggregateStatement compileCreateAggregate(ParsedStatement node, SourceFileContents ignoredSources) {
18291835
SqlCreateAggregate decl = (SqlCreateAggregate) node.statement();
1836+
CalciteObject object = CalciteObject.create(node);
1837+
if (decl.ifNotExists)
1838+
throw new UnsupportedException("IF NOT EXISTS not supported for CREATE AGGREGATE", object);
1839+
if (decl.getReplace())
1840+
throw new UnsupportedException("REPLACE not supported for CREATE AGGREGATE", object);
18301841
List<Map.Entry<String, RelDataType>> parameters = Linq.map(
18311842
decl.getParameters(), param -> {
18321843
SqlAttributeDefinition attr = (SqlAttributeDefinition) param;
@@ -1841,12 +1852,17 @@ public CreateAggregateStatement compileCreateAggregate(ParsedStatement node, Sou
18411852
if (nullableResult != null && nullableResult)
18421853
returnType = this.createNullableType(returnType);
18431854
SqlUserDefinedAggregationFunction function = this.customFunctions.createAggregate(
1844-
CalciteObject.create(node), decl.getName(), decl.isLinear(), structType, returnType);
1855+
object, decl.getName(), decl.isLinear(), structType, returnType);
18451856
return new CreateAggregateStatement(node, function);
18461857
}
18471858

18481859
public CreateFunctionStatement compileCreateFunction(ParsedStatement node, SourceFileContents sources) {
18491860
SqlCreateFunctionDeclaration decl = (SqlCreateFunctionDeclaration) node.statement();
1861+
CalciteObject object = CalciteObject.create(node);
1862+
if (decl.ifNotExists)
1863+
throw new UnsupportedException("IF NOT EXISTS not supported for CREATE FUNCTION", object);
1864+
if (decl.getReplace())
1865+
throw new UnsupportedException("OR REPLACE not supported for CREATE FUNCTION", object);
18501866
List<Map.Entry<String, RelDataType>> parameters = Linq.map(
18511867
decl.getParameters(), param -> {
18521868
SqlAttributeDefinition attr = (SqlAttributeDefinition) param;
@@ -1972,7 +1988,9 @@ public CreateViewStatement compileCreateView(
19721988
SqlCreateView cv = (SqlCreateView) node.statement();
19731989
SqlNode query = cv.query;
19741990
if (cv.getReplace())
1975-
throw new UnsupportedException("OR REPLACE not supported", object);
1991+
throw new UnsupportedException("OR REPLACE not supported for CREATE VIEW", object);
1992+
if (cv.ifNotExists)
1993+
throw new UnsupportedException("IF NOT EXISTS not supported for CREATE VIEW", object);
19761994
if (node.visible())
19771995
Logger.INSTANCE.belowLevel(this, 2)
19781996
.appendSupplier(node.statement()::toString)
@@ -2205,6 +2223,11 @@ else if (name.equalsIgnoreCase("off"))
22052223
@Nullable
22062224
public CreateTypeStatement compileCreateType(ParsedStatement node) {
22072225
SqlCreateType ct = (SqlCreateType) node.statement();
2226+
CalciteObject object = CalciteObject.create(node);
2227+
if (ct.ifNotExists)
2228+
throw new UnsupportedException("IF NOT EXISTS not supported for CREATE TYPE", object);
2229+
if (ct.getReplace())
2230+
throw new UnsupportedException("REPLACE not supported for CREATE TYPE", object);
22082231
RelProtoDataType proto = typeFactory -> {
22092232
if (ct.dataType != null) {
22102233
return this.specToRel(ct.dataType, false);

sql-to-dbsp-compiler/SQL-compiler/src/main/java/org/dbsp/sqlCompiler/compiler/frontend/parser/SqlCreateAggregate.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import java.util.List;
2020
import java.util.Objects;
2121

22+
import static java.util.Objects.requireNonNull;
23+
2224
/** Result produced by a CREATE AGGREGATE statement */
2325
public class SqlCreateAggregate extends SqlCreate {
2426
private final SqlIdentifier name;
@@ -31,12 +33,14 @@ public class SqlCreateAggregate extends SqlCreate {
3133
@Override
3234
public SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos,
3335
@Nullable SqlNode... operands) {
34-
Utilities.enforce(operands.length == 4);
35-
return new SqlCreateAggregate(pos, false, false,
36-
((SqlLiteral) Objects.requireNonNull(operands[0])).booleanValue(),
37-
(SqlIdentifier) Objects.requireNonNull(operands[1]),
38-
(SqlNodeList) Objects.requireNonNull(operands[2]),
39-
(SqlDataTypeSpec) Objects.requireNonNull(operands[3]));
36+
Utilities.enforce(operands.length == 6);
37+
return new SqlCreateAggregate(pos,
38+
((SqlLiteral) requireNonNull(operands[0], "replace")).booleanValue(),
39+
((SqlLiteral) requireNonNull(operands[1], "ifNotExists")).booleanValue(),
40+
((SqlLiteral) Objects.requireNonNull(operands[2])).booleanValue(),
41+
(SqlIdentifier) Objects.requireNonNull(operands[3]),
42+
(SqlNodeList) Objects.requireNonNull(operands[4]),
43+
(SqlDataTypeSpec) Objects.requireNonNull(operands[5]));
4044
}
4145
};
4246

@@ -92,6 +96,8 @@ public SqlIdentifier getName() {
9296

9397
@Override public List<SqlNode> getOperandList() {
9498
return Arrays.asList(
99+
SqlLiteral.createBoolean(this.getReplace(), SqlParserPos.ZERO),
100+
SqlLiteral.createBoolean(this.ifNotExists, SqlParserPos.ZERO),
95101
SqlLiteral.createBoolean(this.linear, SqlParserPos.ZERO),
96102
this.name, this.parameters, this.returnType);
97103
}

sql-to-dbsp-compiler/SQL-compiler/src/main/java/org/dbsp/sqlCompiler/compiler/frontend/parser/SqlCreateFunctionDeclaration.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@
1212
import org.apache.calcite.sql.SqlSpecialOperator;
1313
import org.apache.calcite.sql.SqlWriter;
1414
import org.apache.calcite.sql.parser.SqlParserPos;
15+
import org.dbsp.util.Linq;
1516
import org.dbsp.util.Utilities;
1617

1718
import javax.annotation.Nullable;
1819
import java.util.Arrays;
1920
import java.util.List;
2021
import java.util.Objects;
2122

23+
import static java.util.Objects.requireNonNull;
24+
2225
/** Our own version of CREATE FUNCTION, different from Calcite. */
2326
public class SqlCreateFunctionDeclaration extends SqlCreate {
2427
private final SqlIdentifier name;
@@ -31,12 +34,14 @@ public class SqlCreateFunctionDeclaration extends SqlCreate {
3134
@Override
3235
public SqlCall createCall(@org.checkerframework.checker.nullness.qual.Nullable SqlLiteral functionQualifier,
3336
SqlParserPos pos, @org.checkerframework.checker.nullness.qual.Nullable SqlNode... operands) {
34-
Utilities.enforce(operands.length == 4);
35-
return new SqlCreateFunctionDeclaration(pos, false, false,
36-
(SqlIdentifier) Objects.requireNonNull(operands[0]),
37-
(SqlNodeList) Objects.requireNonNull(operands[1]),
38-
(SqlDataTypeSpec) Objects.requireNonNull(operands[2]),
39-
operands[3]);
37+
Utilities.enforce(operands.length == 6);
38+
return new SqlCreateFunctionDeclaration(pos,
39+
((SqlLiteral) requireNonNull(operands[0], "replace")).booleanValue(),
40+
((SqlLiteral) requireNonNull(operands[1], "ifNotExists")).booleanValue(),
41+
(SqlIdentifier) Objects.requireNonNull(operands[2]),
42+
(SqlNodeList) Objects.requireNonNull(operands[3]),
43+
(SqlDataTypeSpec) Objects.requireNonNull(operands[4]),
44+
operands[5]);
4045
}
4146
};
4247

@@ -90,7 +95,10 @@ public SqlIdentifier getName() {
9095
}
9196

9297
@Override public List<SqlNode> getOperandList() {
93-
return Arrays.asList(this.name, this.parameters, this.returnType, this.body);
98+
return Linq.list(
99+
SqlLiteral.createBoolean(getReplace(), SqlParserPos.ZERO),
100+
SqlLiteral.createBoolean(this.ifNotExists, SqlParserPos.ZERO),
101+
this.name, this.parameters, this.returnType, this.body);
94102
}
95103

96104
@Nullable public SqlNode getBody() { return this.body; }

sql-to-dbsp-compiler/SQL-compiler/src/main/java/org/dbsp/sqlCompiler/compiler/frontend/parser/SqlCreateIndex.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import java.util.List;
1919
import java.util.Objects;
2020

21+
import static java.util.Objects.requireNonNull;
22+
2123
/** Parse tree for {@code CREATE INDEX} statement. */
2224
public class SqlCreateIndex extends SqlCreate {
2325
public final SqlIdentifier name;
@@ -29,24 +31,30 @@ public class SqlCreateIndex extends SqlCreate {
2931
@Override
3032
public SqlCall createCall(
3133
@Nullable SqlLiteral functionQualifier, SqlParserPos pos, @Nullable SqlNode... operands) {
32-
Utilities.enforce(operands.length == 3);
34+
Utilities.enforce(operands.length == 5);
3335
return new SqlCreateIndex(pos,
3436
(SqlIdentifier) Objects.requireNonNull(operands[0]),
3537
(SqlIdentifier) Objects.requireNonNull(operands[1]),
36-
(SqlNodeList) Objects.requireNonNull(operands[2]));
38+
(SqlNodeList) Objects.requireNonNull(operands[2]),
39+
((SqlLiteral) requireNonNull(operands[3], "replace")).booleanValue(),
40+
((SqlLiteral) requireNonNull(operands[4], "ifNotExists")).booleanValue());
3741
}
3842
};
3943

40-
public SqlCreateIndex(SqlParserPos pos, SqlIdentifier name, SqlIdentifier indexed, SqlNodeList columns) {
41-
super(OPERATOR, pos, false, false);
44+
public SqlCreateIndex(SqlParserPos pos, SqlIdentifier name, SqlIdentifier indexed, SqlNodeList columns,
45+
boolean replace, boolean ifNotExists) {
46+
super(OPERATOR, pos, replace, ifNotExists);
4247
this.name = Objects.requireNonNull(name, "name");
4348
this.indexed = indexed;
4449
this.columns = columns;
4550
}
4651

4752
@SuppressWarnings("nullness")
4853
@Override public List<SqlNode> getOperandList() {
49-
return ImmutableNullableList.of(this.name, this.indexed, this.columns);
54+
return ImmutableNullableList.of(
55+
this.name, this.indexed, this.columns,
56+
SqlLiteral.createBoolean(getReplace(), SqlParserPos.ZERO),
57+
SqlLiteral.createBoolean(ifNotExists, SqlParserPos.ZERO));
5058
}
5159

5260
@Override public void unparse(SqlWriter writer, int leftPrec, int rightPrec) {

sql-to-dbsp-compiler/SQL-compiler/src/main/java/org/dbsp/sqlCompiler/compiler/frontend/parser/SqlCreateTable.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import java.util.List;
2020
import java.util.Objects;
2121

22+
import static java.util.Objects.requireNonNull;
23+
2224
/** Parse tree for {@code CREATE TABLE} statement. */
2325
public class SqlCreateTable extends SqlCreate {
2426
public final SqlIdentifier name;
@@ -31,11 +33,13 @@ public class SqlCreateTable extends SqlCreate {
3133
new SqlSpecialOperator("CREATE TABLE", SqlKind.CREATE_TABLE) {
3234
@Override
3335
public SqlCall createCall(@Nullable SqlLiteral functionQualifier, SqlParserPos pos, @Nullable SqlNode... operands) {
34-
Utilities.enforce(operands.length == 3);
35-
return new SqlCreateTable(pos, false, false,
36-
(SqlIdentifier) Objects.requireNonNull(operands[0]),
37-
(SqlNodeList) Objects.requireNonNull(operands[1]),
38-
(SqlNodeList) operands[2]);
36+
Utilities.enforce(operands.length == 5);
37+
return new SqlCreateTable(pos,
38+
((SqlLiteral) requireNonNull(operands[0], "replace")).booleanValue(),
39+
((SqlLiteral) requireNonNull(operands[1], "ifNotExists")).booleanValue(),
40+
(SqlIdentifier) Objects.requireNonNull(operands[2]),
41+
(SqlNodeList) Objects.requireNonNull(operands[3]),
42+
(SqlNodeList) operands[4]);
3943
}
4044
};
4145

@@ -51,7 +55,10 @@ public SqlCreateTable(SqlParserPos pos, boolean replace, boolean ifNotExists,
5155

5256
@SuppressWarnings("nullness")
5357
@Override public List<SqlNode> getOperandList() {
54-
return ImmutableNullableList.of(this.name, this.columnsOrForeignKeys, this.tableProperties);
58+
return ImmutableNullableList.of(
59+
SqlLiteral.createBoolean(getReplace(), SqlParserPos.ZERO),
60+
SqlLiteral.createBoolean(this.ifNotExists, SqlParserPos.ZERO),
61+
this.name, this.columnsOrForeignKeys, this.tableProperties);
5562
}
5663

5764
public static void writeProperties(SqlWriter writer, @Nullable SqlNodeList properties) {

sql-to-dbsp-compiler/SQL-compiler/src/main/java/org/dbsp/sqlCompiler/compiler/frontend/parser/SqlCreateType.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import java.util.List;
2020
import java.util.Objects;
2121

22+
import static java.util.Objects.requireNonNull;
23+
2224
public class SqlCreateType extends SqlCreate {
2325
public final SqlIdentifier name;
2426
public final @Nullable SqlNodeList attributeDefs;
@@ -27,11 +29,12 @@ public class SqlCreateType extends SqlCreate {
2729
@Override
2830
public SqlCall createCall(
2931
@Nullable SqlLiteral functionQualifier, SqlParserPos pos, @Nullable SqlNode... operands) {
30-
Utilities.enforce(operands.length == 3);
31-
return new SqlCreateType(pos, false,
32-
(SqlIdentifier) Objects.requireNonNull(operands[0]),
33-
(SqlNodeList) operands[1],
34-
(SqlDataTypeSpec) operands[2]);
32+
Utilities.enforce(operands.length == 4);
33+
return new SqlCreateType(pos,
34+
((SqlLiteral) requireNonNull(operands[0], "replace")).booleanValue(),
35+
(SqlIdentifier) Objects.requireNonNull(operands[1]),
36+
(SqlNodeList) operands[2],
37+
(SqlDataTypeSpec) operands[3]);
3538
}
3639
};
3740

@@ -44,7 +47,9 @@ public SqlCreateType(SqlParserPos pos, boolean replace, SqlIdentifier name,
4447
}
4548

4649
public List<SqlNode> getOperandList() {
47-
return ImmutableNullableList.of(this.name, this.attributeDefs, this.dataType);
50+
return ImmutableNullableList.of(
51+
SqlLiteral.createBoolean(getReplace(), SqlParserPos.ZERO),
52+
this.name, this.attributeDefs, this.dataType);
4853
}
4954

5055
public void unparse(SqlWriter writer, int leftPrec, int rightPrec) {

0 commit comments

Comments
 (0)