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