You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@calcite.apache.org by Egor Ryashin <ri...@gmail.com> on 2022/08/23 09:22:42 UTC

validation for multiple statements

Hi all,

I try to use validation with multi-statement AST but it fails when I call validate() with NPE about namespace, I wonder how should I set this namespace:
NlsString ';'
BigDecimal 1
Exception in thread "main" java.lang.NullPointerException: namespace for SELECT ';', scope org.apache.calcite.sql.validate.CatalogScope@2f7a7219
	at java.base/java.util.Objects.requireNonNull(Objects.java:334)
	at org.apache.calcite.sql.validate.SqlValidatorImpl.getNamespaceOrThrow(SqlValidatorImpl.java:1273)
	at org.apache.calcite.sql.validate.SqlValidatorImpl.validateQuery(SqlValidatorImpl.java:1058)
	at org.apache.calcite.sql.SqlSelect.validate(SqlSelect.java:247)
	at org.apache.calcite.sql.SqlNodeList.validate(SqlNodeList.java:261)
	at org.apache.calcite.sql.validate.SqlValidatorImpl.validateScopedExpression(SqlValidatorImpl.java:1046)
	at org.apache.calcite.sql.validate.SqlValidatorImpl.validate(SqlValidatorImpl.java:752)
	at org.example.CalciteMultiStatementValidationExample2.main(CalciteMultiStatementValidationExample.java:116)

The example source code:
public class CalciteMultiStatementValidationExample
{
    public static void main( String[] args )
        throws SQLException, SqlParseException, ValidationException, RelConversionException, IOException,
               ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException,
               IllegalAccessException
    {
        SqlParser.Config parserConfig = SqlParser
            .config()
            .withConformance(SqlConformanceEnum.BABEL)
            .withParserFactory(SqlDdlParserImpl.FACTORY);

        SqlNodeList list = SqlParser.create(new SourceStringReader("select ';' ; select 1"), parserConfig).parseStmtList();
        for (SqlNode stmt : list.stream().toList()) {
            for (SqlNode sqlNode1 : ((SqlSelect)stmt).getSelectList()) {
                SqlLiteral sqlNode11 = (SqlLiteral) sqlNode1;
                System.out.println(sqlNode11.getValue().getClass().getSimpleName() + " " + sqlNode11.getValue());
            }
        }

        RelDataTypeSystem DEFAULT = new RelDataTypeSystemImpl() { };
        JavaTypeFactoryImpl javaTypeFactory = new JavaTypeFactoryImpl(DEFAULT);
        Connection connection = DriverManager.getConnection("jdbc:calcite:");
        CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class);
        SchemaPlus rootSchema = calciteConnection.getRootSchema();
        final DataSource ds = JdbcSchema.dataSource(
            "jdbc:hsqldb:mem:db",
            "org.hsqldb.jdbc.JDBCDriver",
            "SA",
            "");
        JdbcSchema schema = JdbcSchema.create(rootSchema, "main", ds, null, "INFORMATION_SCHEMA");
        rootSchema.add("main", schema);
        Properties properties = new Properties();
        properties.setProperty(CalciteConnectionProperty.CASE_SENSITIVE.camelName(), String.valueOf(false));
        properties.setProperty(CalciteConnectionProperty.CONFORMANCE.camelName(), SqlConformanceEnum.LENIENT.name());
        CalciteConnectionConfigImpl cc = new CalciteConnectionConfigImpl(properties);
        CalciteCatalogReader cr = new CalciteCatalogReader(
            CalciteSchema.from(rootSchema),
            Collections.singletonList("main"),
            javaTypeFactory,
            cc
        );

        class CalciteSqlValidator extends SqlValidatorImpl
        {
            CalciteSqlValidator(SqlOperatorTable opTab,
                                CalciteCatalogReader catalogReader, JavaTypeFactory typeFactory,
                                Config config) {
                super(opTab, catalogReader, typeFactory, config);
            }

            @Override protected RelDataType getLogicalSourceRowType(
                RelDataType sourceRowType, SqlInsert insert) {
                final RelDataType superType =
                    super.getLogicalSourceRowType(sourceRowType, insert);
                return ((JavaTypeFactory) typeFactory).toSql(superType);
            }

            @Override protected RelDataType getLogicalTargetRowType(
                RelDataType targetRowType, SqlInsert insert) {
                final RelDataType superType =
                    super.getLogicalTargetRowType(targetRowType, insert);
                return ((JavaTypeFactory) typeFactory).toSql(superType);
            }
        }
        SqlOperatorTable chain = SqlOperatorTables.chain(SqlStdOperatorTable.instance(), cr);

        SqlValidator.Config config = SqlValidator.Config.DEFAULT
            .withConformance(SqlConformanceEnum.BABEL)
            .withDefaultNullCollation(cc.defaultNullCollation())
            .withLenientOperatorLookup(cc.lenientOperatorLookup())
            .withConformance(cc.conformance())
            .withIdentifierExpansion(true);
        SqlNode validate = new CalciteSqlValidator(chain, cr, javaTypeFactory, config).validate(list);

        System.out.println(validate.toString());
    }
}


Re: validation for multiple statements

Posted by Benchao Li <li...@apache.org>.
Egor,

Calcite's `SqlValidatorImpl` does not support to validate a statement list
now.
You can loop over the list by yourself, and validate one query at a time.

Egor Ryashin <ri...@gmail.com> 于2022年8月23日周二 17:23写道:

> Hi all,
>
> I try to use validation with multi-statement AST but it fails when I call
> validate() with NPE about namespace, I wonder how should I set this
> namespace:
> NlsString ';'
> BigDecimal 1
> Exception in thread "main" java.lang.NullPointerException: namespace for
> SELECT ';', scope org.apache.calcite.sql.validate.CatalogScope@2f7a7219
>         at java.base/java.util.Objects.requireNonNull(Objects.java:334)
>         at
> org.apache.calcite.sql.validate.SqlValidatorImpl.getNamespaceOrThrow(SqlValidatorImpl.java:1273)
>         at
> org.apache.calcite.sql.validate.SqlValidatorImpl.validateQuery(SqlValidatorImpl.java:1058)
>         at org.apache.calcite.sql.SqlSelect.validate(SqlSelect.java:247)
>         at
> org.apache.calcite.sql.SqlNodeList.validate(SqlNodeList.java:261)
>         at
> org.apache.calcite.sql.validate.SqlValidatorImpl.validateScopedExpression(SqlValidatorImpl.java:1046)
>         at
> org.apache.calcite.sql.validate.SqlValidatorImpl.validate(SqlValidatorImpl.java:752)
>         at
> org.example.CalciteMultiStatementValidationExample2.main(CalciteMultiStatementValidationExample.java:116)
>
> The example source code:
> public class CalciteMultiStatementValidationExample
> {
>     public static void main( String[] args )
>         throws SQLException, SqlParseException, ValidationException,
> RelConversionException, IOException,
>                ClassNotFoundException, NoSuchMethodException,
> InvocationTargetException, InstantiationException,
>                IllegalAccessException
>     {
>         SqlParser.Config parserConfig = SqlParser
>             .config()
>             .withConformance(SqlConformanceEnum.BABEL)
>             .withParserFactory(SqlDdlParserImpl.FACTORY);
>
>         SqlNodeList list = SqlParser.create(new SourceStringReader("select
> ';' ; select 1"), parserConfig).parseStmtList();
>         for (SqlNode stmt : list.stream().toList()) {
>             for (SqlNode sqlNode1 : ((SqlSelect)stmt).getSelectList()) {
>                 SqlLiteral sqlNode11 = (SqlLiteral) sqlNode1;
>
> System.out.println(sqlNode11.getValue().getClass().getSimpleName() + " " +
> sqlNode11.getValue());
>             }
>         }
>
>         RelDataTypeSystem DEFAULT = new RelDataTypeSystemImpl() { };
>         JavaTypeFactoryImpl javaTypeFactory = new
> JavaTypeFactoryImpl(DEFAULT);
>         Connection connection =
> DriverManager.getConnection("jdbc:calcite:");
>         CalciteConnection calciteConnection =
> connection.unwrap(CalciteConnection.class);
>         SchemaPlus rootSchema = calciteConnection.getRootSchema();
>         final DataSource ds = JdbcSchema.dataSource(
>             "jdbc:hsqldb:mem:db",
>             "org.hsqldb.jdbc.JDBCDriver",
>             "SA",
>             "");
>         JdbcSchema schema = JdbcSchema.create(rootSchema, "main", ds,
> null, "INFORMATION_SCHEMA");
>         rootSchema.add("main", schema);
>         Properties properties = new Properties();
>
> properties.setProperty(CalciteConnectionProperty.CASE_SENSITIVE.camelName(),
> String.valueOf(false));
>
> properties.setProperty(CalciteConnectionProperty.CONFORMANCE.camelName(),
> SqlConformanceEnum.LENIENT.name());
>         CalciteConnectionConfigImpl cc = new
> CalciteConnectionConfigImpl(properties);
>         CalciteCatalogReader cr = new CalciteCatalogReader(
>             CalciteSchema.from(rootSchema),
>             Collections.singletonList("main"),
>             javaTypeFactory,
>             cc
>         );
>
>         class CalciteSqlValidator extends SqlValidatorImpl
>         {
>             CalciteSqlValidator(SqlOperatorTable opTab,
>                                 CalciteCatalogReader catalogReader,
> JavaTypeFactory typeFactory,
>                                 Config config) {
>                 super(opTab, catalogReader, typeFactory, config);
>             }
>
>             @Override protected RelDataType getLogicalSourceRowType(
>                 RelDataType sourceRowType, SqlInsert insert) {
>                 final RelDataType superType =
>                     super.getLogicalSourceRowType(sourceRowType, insert);
>                 return ((JavaTypeFactory) typeFactory).toSql(superType);
>             }
>
>             @Override protected RelDataType getLogicalTargetRowType(
>                 RelDataType targetRowType, SqlInsert insert) {
>                 final RelDataType superType =
>                     super.getLogicalTargetRowType(targetRowType, insert);
>                 return ((JavaTypeFactory) typeFactory).toSql(superType);
>             }
>         }
>         SqlOperatorTable chain =
> SqlOperatorTables.chain(SqlStdOperatorTable.instance(), cr);
>
>         SqlValidator.Config config = SqlValidator.Config.DEFAULT
>             .withConformance(SqlConformanceEnum.BABEL)
>             .withDefaultNullCollation(cc.defaultNullCollation())
>             .withLenientOperatorLookup(cc.lenientOperatorLookup())
>             .withConformance(cc.conformance())
>             .withIdentifierExpansion(true);
>         SqlNode validate = new CalciteSqlValidator(chain, cr,
> javaTypeFactory, config).validate(list);
>
>         System.out.println(validate.toString());
>     }
> }
>
>

-- 

Best,
Benchao Li