Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,29 @@
/** Utility class for parsing CREATE statements into a {@link CalciteCatalogReader} */
public class SubstraitCreateStatementParser {

/** An empty catalog reader used for validating CREATE statements. */
public static final CalciteCatalogReader EMPTY_CATALOG =
new CalciteCatalogReader(
CalciteSchema.createRootSchema(false),
List.of(),
SubstraitTypeSystem.TYPE_FACTORY,
SqlConverterBase.CONNECTION_CONFIG);

// A validator is needed to convert the types in column declarations to Calcite types
/** SQL validator configured for validating CREATE statements against the empty catalog. */
public static final SqlValidator VALIDATOR =
new SubstraitSqlValidator(
// as we are validating CREATE statements, an empty catalog suffices
EMPTY_CATALOG);

/**
* Parses a SQL string containing only CREATE statements into a list of {@link SubstraitTable}s
* Parses a SQL string containing only CREATE statements into a list of {@link SubstraitTable}s.
*
* <p>This method only supports simple table names without any additional qualifiers. Only used
* with {@link io.substrait.isthmus.SqlExpressionToSubstrait}.
*
* @param createStatements a SQL string containing only CREATE statements, must not be null
* @return a list of {@link SubstraitTable}s generated from the CREATE statements
* @throws SqlParseException
* @param createStatements a SQL string containing only CREATE statements; must not be null
* @return list of {@link SubstraitTable}s generated from the CREATE statements
* @throws SqlParseException if parsing fails or statements are invalid
*/
public static List<SubstraitTable> processCreateStatements(@NonNull final String createStatements)
throws SqlParseException {
Expand Down Expand Up @@ -75,7 +76,7 @@ public static List<SubstraitTable> processCreateStatements(@NonNull final String

/**
* Parses one or more SQL strings containing only CREATE statements into a {@link
* CalciteCatalogReader}
* CalciteCatalogReader}.
*
* <p>This method expects the use of fully qualified table names in the CREATE statements.
*
Expand All @@ -96,7 +97,7 @@ public static CalciteCatalogReader processCreateStatementsToCatalog(
*
* @param createStatements a SQL string containing only CREATE statements, must not be null
* @return a {@link CalciteCatalogReader} generated from the CREATE statements
* @throws SqlParseException
* @throws SqlParseException if parsing fails or statements are invalid
*/
public static CalciteCatalogReader processCreateStatementsToCatalog(
@NonNull final String... createStatements) throws SqlParseException {
Expand All @@ -112,9 +113,9 @@ public static CalciteCatalogReader processCreateStatementsToCatalog(
/**
* Creates a new {@link SqlParseException} with the given message and {@link SqlParserPos}.
*
* @param message the exception message, may be null
* @param pos the position where this error occured, may be null
* @return the {@link SqlParseException} with the given message and {@link SqlParserPos}
* @param message the exception message; may be null
* @param pos the position where this error occurred; may be null
* @return a {@link SqlParseException} with the given message and position
*/
private static SqlParseException fail(
@Nullable final String message, @Nullable final SqlParserPos pos) {
Expand All @@ -124,8 +125,8 @@ private static SqlParseException fail(
/**
* Creates a new {@link SqlParseException} with the given message.
*
* @param message the exception message, may be null
* @return the {@link SqlParseException} with the given message
* @param message the exception message; may be null
* @return a {@link SqlParseException} with the given message
*/
private static SqlParseException fail(@Nullable final String message) {
return fail(message, SqlParserPos.ZERO);
Expand All @@ -134,9 +135,10 @@ private static SqlParseException fail(@Nullable final String message) {
/**
* Parses one or more SQL strings containing only CREATE statements into a {@link CalciteSchema}.
*
* @param createStatements a SQL string containing only CREATE statements, must not be null
* @param createStatements one or more SQL strings containing only CREATE statements; must not be
* null
* @return a {@link CalciteSchema} generated from the CREATE statements
* @throws SqlParseException
* @throws SqlParseException if parsing fails or statements are invalid
*/
private static CalciteSchema processCreateStatementsToSchema(
@NonNull final String... createStatements) throws SqlParseException {
Expand Down Expand Up @@ -173,11 +175,11 @@ private static CalciteSchema processCreateStatementsToSchema(
* Creates a new {@link SubstraitTable} with the given table name and the table schema from the
* given {@link SqlNodeList} containing {@link SqlColumnDeclaration}s.
*
* @param tableName the table name to use, must not be null
* @param columnList the {@link SqlNodeList} containing {@link SqlColumnDeclaration}s to create
* the table schema from, must not be null
* @return the {@link SubstraitTable}
* @throws SqlParseException
* @param tableName the table name to use; must not be null
* @param columnList the {@link SqlNodeList} containing {@link SqlColumnDeclaration}s to build the
* table schema from; must not be null
* @return the constructed {@link SubstraitTable}
* @throws SqlParseException if the column list contains unexpected nodes or invalid names
*/
private static SubstraitTable createSubstraitTable(
@NonNull final String tableName, @NonNull final SqlNodeList columnList)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,25 @@
import org.apache.calcite.sql.util.SqlString;

/**
* {@link SqlDialect} used by Isthmus for parsing
* {@link SqlDialect} implementation used by Isthmus for SQL parsing and generation.
*
* <p>Intended primarily for internal testing
* <p>Primarily intended for internal testing and conversion of Calcite {@link RelNode} trees to
* SQL.
*/
public class SubstraitSqlDialect extends SqlDialect {

/** Default context for the Substrait SQL dialect. */
public static SqlDialect.Context DEFAULT_CONTEXT = SqlDialect.EMPTY_CONTEXT;

/** Default instance of Substrait SQL dialect. */
public static SqlDialect DEFAULT = new SubstraitSqlDialect(DEFAULT_CONTEXT);

/**
* Converts a Calcite {@link RelNode} to its SQL representation using the default dialect.
*
* @param relNode The Calcite relational node to convert.
* @return A {@link SqlString} representing the SQL equivalent of the given {@link RelNode}.
*/
public static SqlString toSql(RelNode relNode) {
RelToSqlConverter relToSql = new RelToSqlConverter(DEFAULT);
SqlNode sqlNode = relToSql.visitRoot(relNode).asStatement();
Expand All @@ -28,10 +37,20 @@ public static SqlString toSql(RelNode relNode) {
.withIndentation(0));
}

/**
* Constructs a Substrait SQL dialect with the given context.
*
* @param context The {@link SqlDialect.Context} providing configuration for SQL generation.
*/
public SubstraitSqlDialect(Context context) {
super(context);
}

/**
* Indicates whether this dialect supports approximate COUNT(DISTINCT) operations.
*
* @return always {@code true}, as Substrait SQL dialect supports approximate count distinct.
*/
@Override
public boolean supportsApproxCountDistinct() {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,32 @@
import org.apache.calcite.sql.validate.SqlValidator;
import org.apache.calcite.sql.validate.SqlValidatorImpl;

/**
* Custom SQL validator for Substrait SQL dialect.
*
* <p>Uses {@link SubstraitOperatorTable} and Calcite's validation framework to validate SQL
* statements for Substrait-specific operators.
*/
public class SubstraitSqlValidator extends SqlValidatorImpl {

/** Default configuration for the validator with identifier expansion enabled. */
static SqlValidator.Config CONFIG = Config.DEFAULT.withIdentifierExpansion(true);

/**
* Creates a Substrait SQL validator using the default operator table.
*
* @param catalogReader The {@link Prepare.CatalogReader} providing schema and type information.
*/
public SubstraitSqlValidator(Prepare.CatalogReader catalogReader) {
super(SubstraitOperatorTable.INSTANCE, catalogReader, catalogReader.getTypeFactory(), CONFIG);
}

/**
* Creates a Substrait SQL validator using a custom operator table.
*
* @param catalogReader The {@link Prepare.CatalogReader} providing schema and type information.
* @param opTable The {@link SqlOperatorTable} containing SQL operators for validation.
*/
public SubstraitSqlValidator(Prepare.CatalogReader catalogReader, SqlOperatorTable opTable) {
super(opTable, catalogReader, catalogReader.getTypeFactory(), CONFIG);
}
Expand Down
Loading