diff --git a/deploy/samples/subscriptions.yaml b/deploy/samples/subscriptions.yaml index 6e897c3..224f1f0 100644 --- a/deploy/samples/subscriptions.yaml +++ b/deploy/samples/subscriptions.yaml @@ -4,7 +4,7 @@ kind: Subscription metadata: name: names spec: - sql: SELECT NAME, NAME AS KEY FROM DATAGEN.PERSON + sql: SELECT NAME, NULL AS KEY FROM DATAGEN.PERSON database: RAWKAFKA diff --git a/hoptimator-catalog/src/main/java/com/linkedin/hoptimator/catalog/ScriptImplementor.java b/hoptimator-catalog/src/main/java/com/linkedin/hoptimator/catalog/ScriptImplementor.java index 72474be..9aa25fe 100644 --- a/hoptimator-catalog/src/main/java/com/linkedin/hoptimator/catalog/ScriptImplementor.java +++ b/hoptimator-catalog/src/main/java/com/linkedin/hoptimator/catalog/ScriptImplementor.java @@ -171,6 +171,7 @@ public SqlNode visit(SqlCall call) { * * N.B. the following magic: * - field 'PRIMARY_KEY' is treated as a PRIMARY KEY + * - field 'NULL_KEY' is treated as a COMPUTED COLUMN with value NULL */ class ConnectorImplementor implements ScriptImplementor { private final String database; @@ -288,7 +289,11 @@ public void implement(SqlWriter w) { } } - /** Implements row type specs, e.g. `NAME VARCHAR(20), AGE INTEGER` */ + /** Implements row type specs, e.g. `NAME VARCHAR(20), AGE INTEGER`. + * + * N.B. the following magic: + * - field 'NULL_KEY' is treated as a COMPUTED COLUMN with value NULL + */ class RowTypeSpecImplementor implements ScriptImplementor { private final RelDataType dataType; @@ -308,8 +313,12 @@ public void implement(SqlWriter w) { .collect(Collectors.toList()); for (int i = 0; i < fieldNames.size(); i++) { w.sep(","); - fieldNames.get(i).unparse(w, 0, 0); - fieldTypes.get(i).unparse(w, 0, 0); + if (fieldNames.get(i).toString().equals("NULL_KEY")) { + w.literal("KEY AS NULL"); + } else { + fieldNames.get(i).unparse(w, 0, 0); + fieldTypes.get(i).unparse(w, 0, 0); + } } } diff --git a/hoptimator-catalog/src/test/java/com/linkedin/hoptimator/catalog/ScriptImplementorTest.java b/hoptimator-catalog/src/test/java/com/linkedin/hoptimator/catalog/ScriptImplementorTest.java index 763bc1e..9c585db 100644 --- a/hoptimator-catalog/src/test/java/com/linkedin/hoptimator/catalog/ScriptImplementorTest.java +++ b/hoptimator-catalog/src/test/java/com/linkedin/hoptimator/catalog/ScriptImplementorTest.java @@ -34,4 +34,26 @@ public void implementsFlinkCreateTableDDL() { assertTrue(out, out.contains("'topic'='topic1'")); assertFalse(out, out.contains("Row")); } + + @Test + public void magicPrimaryKey() { + SqlWriter w = new SqlPrettyWriter(); + RelDataType rowType = DataType.struct().with("F1", DataType.VARCHAR) + .with("PRIMARY_KEY", DataType.VARCHAR).rel(); + HopTable table = new HopTable("DATABASE", "TABLE1", rowType, ConfigProvider.empty().config("x")); + table.implement(w); + String out = w.toString(); + assertTrue(out, out.contains("PRIMARY KEY (PRIMARY_KEY)")); + } + + @Test + public void magicNullKey() { + SqlWriter w = new SqlPrettyWriter(); + RelDataType rowType = DataType.struct().with("F1", DataType.VARCHAR) + .with("NULL_KEY", DataType.VARCHAR).rel(); + HopTable table = new HopTable("DATABASE", "TABLE1", rowType, ConfigProvider.empty().config("x")); + table.implement(w); + String out = w.toString(); + assertTrue(out, out.contains("KEY AS NULL")); + } }