diff --git a/isthmus/src/main/java/io/substrait/isthmus/calcite/rel/CreateTable.java b/isthmus/src/main/java/io/substrait/isthmus/calcite/rel/CreateTable.java index 627b8f1e3..71a01ca1a 100644 --- a/isthmus/src/main/java/io/substrait/isthmus/calcite/rel/CreateTable.java +++ b/isthmus/src/main/java/io/substrait/isthmus/calcite/rel/CreateTable.java @@ -17,21 +17,45 @@ private CreateTable( this.tableName = tableName; } + /** + * CreateTable Constructor. + * + * @param tableName tablename components + * @param input RelNode input + */ public CreateTable(List tableName, RelNode input) { this(input.getCluster(), input.getTraitSet(), tableName, input); } + /** + * Explains the node terms for plan output. + * + * @param pw plan writer + * @return the plan writer with this node's fields added + */ @Override public RelWriter explainTerms(RelWriter pw) { return super.explainTerms(pw).item("tableName", getTableName()); } + /** + * Returns the inputs to this node (single input). + * + * @param traitSet the RelTraitSet + * @param inputs List of RelNodes + * @return the input relation + */ @Override public RelNode copy(RelTraitSet traitSet, List inputs) { assert inputs.size() == 1; return new CreateTable(getCluster(), traitSet, tableName, inputs.get(0)); } + /** + * Returns the fully qualified table name parts. + * + * @return table name components (e.g., [schema, table]) + */ public List getTableName() { return tableName; } diff --git a/isthmus/src/main/java/io/substrait/isthmus/calcite/rel/CreateView.java b/isthmus/src/main/java/io/substrait/isthmus/calcite/rel/CreateView.java index 2c575c4f6..0fe8dbc8b 100644 --- a/isthmus/src/main/java/io/substrait/isthmus/calcite/rel/CreateView.java +++ b/isthmus/src/main/java/io/substrait/isthmus/calcite/rel/CreateView.java @@ -20,17 +20,33 @@ public CreateView(List viewName, RelNode input) { this(input.getCluster(), input.getTraitSet(), viewName, input); } + /** + * Explains the node terms for plan output. + * + * @param pw plan writer + * @return the plan writer with this node's fields added + */ @Override public RelWriter explainTerms(RelWriter pw) { return super.explainTerms(pw).item("viewName", getViewName()); } + /** + * Returns the inputs to this node (single input). + * + * @return a list containing the input relation + */ @Override public RelNode copy(RelTraitSet traitSet, List inputs) { assert inputs.size() == 1; return new CreateView(getCluster(), traitSet, viewName, inputs.get(0)); } + /** + * Returns the fully qualified view name parts. + * + * @return view name components (e.g., [schema, view]) + */ public List getViewName() { return viewName; } diff --git a/isthmus/src/main/java/io/substrait/isthmus/calcite/rel/DdlSqlToRelConverter.java b/isthmus/src/main/java/io/substrait/isthmus/calcite/rel/DdlSqlToRelConverter.java index 8c53e731b..07ea353d5 100644 --- a/isthmus/src/main/java/io/substrait/isthmus/calcite/rel/DdlSqlToRelConverter.java +++ b/isthmus/src/main/java/io/substrait/isthmus/calcite/rel/DdlSqlToRelConverter.java @@ -12,10 +12,22 @@ import org.apache.calcite.sql.util.SqlBasicVisitor; import org.apache.calcite.sql2rel.SqlToRelConverter; +/** + * Visitor that converts DDL {@link SqlCall}s to {@link RelRoot}, delegating to specific handlers + * for supported statements (CREATE TABLE AS SELECT, CREATE VIEW). + * + *

Non-DDL statements are passed through to {@link SqlToRelConverter#convertQuery(SqlNode, + * boolean, boolean)}. + */ public class DdlSqlToRelConverter extends SqlBasicVisitor { + /** + * Registry mapping DDL {@link SqlCall} classes to handler functions that convert them into {@link + * RelRoot} instances. + */ protected final Map, Function> ddlHandlers = new ConcurrentHashMap<>(); + private final SqlToRelConverter converter; private Function findDdlHandler(final SqlCall call) { @@ -30,6 +42,11 @@ private Function findDdlHandler(final SqlCall call) { return null; } + /** + * Creates a DDL SQL-to-Rel converter using the given {@link SqlToRelConverter}. + * + * @param converter the converter used for non-DDL and query parts of DDL (e.g., CTAS) + */ public DdlSqlToRelConverter(SqlToRelConverter converter) { this.converter = converter; @@ -37,6 +54,12 @@ public DdlSqlToRelConverter(SqlToRelConverter converter) { ddlHandlers.put(SqlCreateView.class, sqlCall -> handleCreateView((SqlCreateView) sqlCall)); } + /** + * Dispatches a {@link SqlCall} to an appropriate DDL handler; falls back to non-DDL handling. + * + * @param sqlCall the SQL call node + * @return the converted relational root + */ @Override public RelRoot visit(SqlCall sqlCall) { Function ddlHandler = findDdlHandler(sqlCall); @@ -46,10 +69,23 @@ public RelRoot visit(SqlCall sqlCall) { return handleNonDdl(sqlCall); } + /** + * Handles non-DDL SQL nodes via the underlying {@link SqlToRelConverter}. + * + * @param sqlNode the SQL node to convert + * @return the converted relational root + */ protected RelRoot handleNonDdl(final SqlNode sqlNode) { return converter.convertQuery(sqlNode, true, true); } + /** + * Handles {@code CREATE TABLE AS SELECT} statements. + * + * @param sqlCreateTable the CREATE TABLE node + * @return a {@link RelRoot} wrapping a synthetic {@code CreateTable} relational node + * @throws IllegalArgumentException if the statement is not a CTAS + */ protected RelRoot handleCreateTable(final SqlCreateTable sqlCreateTable) { if (sqlCreateTable.query == null) { throw new IllegalArgumentException("Only create table as select statements are supported"); @@ -58,6 +94,13 @@ protected RelRoot handleCreateTable(final SqlCreateTable sqlCreateTable) { return RelRoot.of(new CreateTable(sqlCreateTable.name.names, input), sqlCreateTable.getKind()); } + /** + * Handles {@code CREATE VIEW} statements. + * + * @param sqlCreateView the CREATE VIEW node + * @return a {@link RelRoot} wrapping a synthetic {@code CreateTable} relational node representing + * the view definition + */ protected RelRoot handleCreateView(final SqlCreateView sqlCreateView) { final RelNode input = converter.convertQuery(sqlCreateView.query, true, true).rel; return RelRoot.of(new CreateView(sqlCreateView.name.names, input), sqlCreateView.getKind());