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());
    }
}

Reply via email to