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 <[email protected]> 于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
