[ https://issues.apache.org/jira/browse/CALCITE-3301?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Water Cut Off updated CALCITE-3301: ----------------------------------- Description: * *{color:#00875a}I want to use calcite to parse view, and convert view to my own RelNode, but I am not sure how to use ViewExpander ,can you give me an example to solve this problem, thanks ?{color}* public class PrestoView implements RelOptTable.ViewExpander { private final SqlValidator validator; private final Prepare.CatalogReader catalogReader; private final RelOptCluster cluster; private final SqlToRelConverter.Config config; public PrestoView(SqlValidator validator, Prepare.CatalogReader catalogReader, RelOptCluster cluster, SqlToRelConverter.Config config) { this.validator = validator; this.catalogReader = catalogReader; this.cluster = cluster; this.config = config; } @Override public RelRoot expandView(RelDataType rowType, String queryString, List<String> schemaPath, List<String> viewPath) { try { SqlNode parsedNode = SqlParser.create(queryString).parseStmt(); SqlNode validatedNode = validator.validate(parsedNode); SqlToRelConverter converter = new SqlToRelConverter(this, validator, catalogReader, cluster, StandardConvertletTable.INSTANCE, config); return converter.convertQuery(validatedNode, false, true); } catch (SqlParseException e) { throw new RuntimeException("Error happened while expanding view.", e); } } -------------------------------------------------------------- public class PrestoViewTable extends AbstractTable implements TranslatableTable { private final String vName; private final String viewSql; public PrestoViewTable(String vName, String viewSql) { super(); this.vName = vName; this.viewSql = viewSql; } public String getVName() { return vName; } @Override public RelNode toRel(RelOptTable.ToRelContext context, RelOptTable relOptTable) { return expandView(context, relOptTable.getRowType(), viewSql).rel; } @Override public RelDataType getRowType(final RelDataTypeFactory typeFactory) { RelDataTypeFactory.Builder builder = typeFactory.builder(); builder.add("empid", new BasicSqlType(new RelDataTypeSystemImpl() { }, SqlTypeName.INTEGER)); builder.add("deptno", new BasicSqlType(new RelDataTypeSystemImpl() { }, SqlTypeName.VARCHAR)); return builder.build(); } @Override public Schema.TableType getJdbcTableType() { return Schema.TableType.VIEW; } private RelRoot expandView(RelOptTable.ToRelContext context, RelDataType rowType, String queryString) { try { final RelRoot root = context.expandView(rowType, queryString, null, null); final RelNode rel = RelOptUtil.createCastRel(root.rel, rowType, true); // Expand any views final RelNode rel2 = rel.accept(new RelShuttleImpl() { @Override public RelNode visit(TableScan scan) { final RelOptTable table = scan.getTable(); final TranslatableTable translatableTable = table.unwrap(TranslatableTable.class); if (translatableTable != null) { return translatableTable.toRel(context, table); } return super.visit(scan); } }); return root.withRel(rel2); } catch (Exception e) { throw new RuntimeException("Error while parsing view definition: " + queryString, e); } } } --------------------------------------------------------------------------- public static SchemaPlus registerRootSchema(List<PrestoTable> tabList, List<PrestoViewTable> viewTables) { SchemaPlus rootSchema = Frameworks.createRootSchema(true); for (PrestoTable table : tabList) { rootSchema.add(table.getTableName(), table); } List<PrestoViewTable> vts = new ArrayList<>(); PrestoViewTable pt = new PrestoViewTable("V_EMP", "select * from emp where empid>10"); vts.add(pt); // // for (PrestoViewTable pv : viewTables) { // rootSchema.add(pv.getVName(), pv); // } return rootSchema; } {color:#00875a}----------------------------*Test----*---------------------------------------------------------------------------------------------------{color} public class CalciteTest { public static void main(String[] args) { // String sql = "select * from dept "; String sql1 = "select a.* from dept a left join emp b on a.deptno=b.deptno where a.name in('compute','aab') and b.deptno='aa' order by a.deptno limit 10"; String sql2 = "select a.name from dept a left join emp b on a.deptno=b.deptno where a.name in('compute','aab') and b.deptno='aa'"; String sql3 = "select count(distinct deptno) from dept where deptno='aa'"; String sql4 = "select * from v_emp"; // sqlToRelNode(sql); sqlToRelNode(sql4); } private static RelNode sqlToRelNode(String sql) { SchemaPlus rootSchema = CalciteUtils.registerRootSchema(createTables(), createVTables()); //expandView(rootSchema); final FrameworkConfig fromworkConfig = Frameworks.newConfigBuilder().parserConfig(SqlParser.Config.DEFAULT).defaultSchema(rootSchema).traitDefs(ConventionTraitDef.INSTANCE, RelDistributionTraitDef.INSTANCE).build(); try { //---------------------SQL to SqlNode--------------------------------- SqlTypeFactoryImpl factory = new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT); // sql parser SqlParser parser = SqlParser.create(sql, SqlParser.Config.DEFAULT); SqlNode parsed = parser.parseStmt(); CalciteCatalogReader calciteCatalogReader = new CalciteCatalogReader(CalciteSchema.from(rootSchema), CalciteSchema.from(rootSchema).path(null), factory, new CalciteConnectionConfigImpl(new Properties())); // sql validate SqlValidator validator = SqlValidatorUtil.newValidator(SqlStdOperatorTable.instance(), calciteCatalogReader, factory, CalciteUtils.conformance(fromworkConfig)); SqlNode validated = validator.validate(parsed); //---------------------Planner--------------------------------- VolcanoPlanner planner = new PrestoVolcanoPlanner(); planner.addRelTraitDef(ConventionTraitDef.INSTANCE); planner.addRelTraitDef(RelDistributionTraitDef.INSTANCE); final RelOptCluster relOptCluster = RelOptCluster.create(planner, new RexBuilder(new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT))); //add RelMetadataProvider relOptCluster.setMetadataProvider(PrestoRelMetaDataProvider.INSTANCE); // SqlNode toRelNode final SqlToRelConverter.Config config = SqlToRelConverter.configBuilder().withConfig(fromworkConfig.getSqlToRelConverterConfig()).withTrimUnusedFields(false).withExpand(true).withConvertTableAccess(false).build(); final SqlToRelConverter sqlToRelConverter = new SqlToRelConverter(new PrestoView(validator, calciteCatalogReader, relOptCluster, config), validator, calciteCatalogReader, relOptCluster, fromworkConfig.getConvertletTable(), config); RelRoot root = sqlToRelConverter.convertQuery(validated, false, true); root = root.withRel(sqlToRelConverter.flattenTypes(root.rel, true)); RelNode relNode = root.rel; HepProgramBuilder builder = HepProgram.builder().addRuleInstance(FilterJoinRule.FilterIntoJoinRule.FILTER_ON_JOIN).addRuleInstance(FilterProjectTransposeRule.INSTANCE).addRuleInstance(FilterJoinRule.FILTER_ON_JOIN).addRuleInstance(ProjectMergeRule.INSTANCE).addRuleInstance(SemiJoinRule.PROJECT); HepPlanner hepPlanner = new HepPlanner(builder.build()); hepPlanner.setRoot(relNode); relNode = hepPlanner.findBestExp(); RelTraitSet desiredTraits = relOptCluster.traitSetOf(PrestoRel.CONVENTION); if (!relNode.getTraitSet().equals(desiredTraits)) { relNode = planner.changeTraits(relNode, desiredTraits); } planner.setRoot(relNode); relNode = planner.findBestExp(); System.out.println("-----------------------------------------------------------"); System.out.println("The Best relational expression string:"); System.out.println(RelOptUtil.toString(relNode, SqlExplainLevel.ALL_ATTRIBUTES)); System.out.println("-----------------------------------------------------------"); RelOptCost cost = planner.getCost(relNode, PrestoRelMetadataQuery.INSTANCE); System.out.println(cost.toString()); System.out.println("-----------------------------------------------------------"); } catch (Exception e) { e.printStackTrace(); } return null; } private static List<PrestoTable> createTables() { List<PrestoTable> tabList = new ArrayList<>(); String[] fields = new String[]\\{"DEPTNO", "NAME", "LEADER"} ; String[] fieldTypes = new String[]\{"int", "string", "string"}; List<ColStatistics> cols = new ArrayList<>(); cols.add(new ColStatistics("DEPTNO", 5)); cols.add(new ColStatistics("NAME", 5)); cols.add(new ColStatistics("LEADER", 5)); PrestoTableInfo info1 = new PrestoTableInfo(); info1.setFields(fields); info1.setFieldTypes(fieldTypes); info1.setRowCount(5d); info1.setTableName("DEPT"); info1.setStatistics(cols); PrestoTable t1 = new PrestoTable(info1); String[] fields2 = new String[]\{"EMPID", "NAME", "DEPTNO", "SALARY"}; String[] fieldTypes2 = new String[]\{"int", "string", "int", "double"}; List<ColStatistics> cols2 = new ArrayList<>(); cols2.add(new ColStatistics("EMPID", 50)); cols2.add(new ColStatistics("NAME", 50)); cols2.add(new ColStatistics("DEPTNO", 5)); cols2.add(new ColStatistics("SALARY", 5)); PrestoTableInfo info2 = new PrestoTableInfo(); info2.setFields(fields2); info2.setFieldTypes(fieldTypes2); info2.setRowCount(50d); info2.setTableName("EMP"); info2.setStatistics(cols2); PrestoTable t2 = new PrestoTable(info2); tabList.add(t1); tabList.add(t2); return tabList; } =============================================== *{color:#ff0000}ERROR:{color}* Exception in thread "main" java.lang.AssertionErrorException in thread "main" java.lang.AssertionError at org.apache.calcite.util.Pair.zip(Pair.java:202) at org.apache.calcite.rex.RexUtil.generateCastExpressions(RexUtil.java:134) at org.apache.calcite.rex.RexUtil.generateCastExpressions(RexUtil.java:116) at org.apache.calcite.plan.RelOptUtil.createCastRel(RelOptUtil.java:749) at org.apache.calcite.plan.RelOptUtil.createCastRel(RelOptUtil.java:722) at com.niwodai.pangu.datasearch.calcite.PrestoViewTable.expandView(PrestoViewTable.java:64) at com.niwodai.pangu.datasearch.calcite.PrestoViewTable.toRel(PrestoViewTable.java:42) at org.apache.calcite.prepare.RelOptTableImpl.toRel(RelOptTableImpl.java:269) at org.apache.calcite.sql2rel.RelStructuredTypeFlattener.rewriteRel(RelStructuredTypeFlattener.java:694) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.calcite.util.ReflectUtil.invokeVisitorInternal(ReflectUtil.java:257) at org.apache.calcite.util.ReflectUtil.invokeVisitor(ReflectUtil.java:214) at org.apache.calcite.util.ReflectUtil$1.invokeVisitor(ReflectUtil.java:464) at org.apache.calcite.sql2rel.RelStructuredTypeFlattener$RewriteRelVisitor.visit(RelStructuredTypeFlattener.java:768) at org.apache.calcite.rel.SingleRel.childrenAccept(SingleRel.java:72) at org.apache.calcite.rel.RelVisitor.visit(RelVisitor.java:44) at org.apache.calcite.sql2rel.RelStructuredTypeFlattener$RewriteRelVisitor.visit(RelStructuredTypeFlattener.java:763) at org.apache.calcite.sql2rel.RelStructuredTypeFlattener.rewrite(RelStructuredTypeFlattener.java:195) at org.apache.calcite.sql2rel.SqlToRelConverter.flattenTypes(SqlToRelConverter.java:468) at com.niwodai.pangu.datasearch.calcite.CalciteTest.sqlToRelNode(CalciteTest.java:97) at com.niwodai.pangu.datasearch.calcite.CalciteTest.main(CalciteTest.java:59) was: public class PrestoView implements RelOptTable.ViewExpander { private final SqlValidator validator; private final Prepare.CatalogReader catalogReader; private final RelOptCluster cluster; private final SqlToRelConverter.Config config; public PrestoView(SqlValidator validator, Prepare.CatalogReader catalogReader, RelOptCluster cluster, SqlToRelConverter.Config config) { this.validator = validator; this.catalogReader = catalogReader; this.cluster = cluster; this.config = config; } @Override public RelRoot expandView(RelDataType rowType, String queryString, List<String> schemaPath, List<String> viewPath) { try { SqlNode parsedNode = SqlParser.create(queryString).parseStmt(); SqlNode validatedNode = validator.validate(parsedNode); SqlToRelConverter converter = new SqlToRelConverter(this, validator, catalogReader, cluster, StandardConvertletTable.INSTANCE, config); return converter.convertQuery(validatedNode, false, true); } catch (SqlParseException e) { throw new RuntimeException("Error happened while expanding view.", e); } } -------------------------------------------------------------- public class PrestoViewTable extends AbstractTable implements TranslatableTable { private final String vName; private final String viewSql; public PrestoViewTable(String vName, String viewSql) { super(); this.vName = vName; this.viewSql = viewSql; } public String getVName() { return vName; } @Override public RelNode toRel(RelOptTable.ToRelContext context, RelOptTable relOptTable) { return expandView(context, relOptTable.getRowType(), viewSql).rel; } @Override public RelDataType getRowType(final RelDataTypeFactory typeFactory) { RelDataTypeFactory.Builder builder = typeFactory.builder(); builder.add("empid", new BasicSqlType(new RelDataTypeSystemImpl() { }, SqlTypeName.INTEGER)); builder.add("deptno", new BasicSqlType(new RelDataTypeSystemImpl() { }, SqlTypeName.VARCHAR)); return builder.build(); } @Override public Schema.TableType getJdbcTableType() { return Schema.TableType.VIEW; } private RelRoot expandView(RelOptTable.ToRelContext context, RelDataType rowType, String queryString) { try { final RelRoot root = context.expandView(rowType, queryString, null, null); final RelNode rel = RelOptUtil.createCastRel(root.rel, rowType, true); // Expand any views final RelNode rel2 = rel.accept(new RelShuttleImpl() { @Override public RelNode visit(TableScan scan) { final RelOptTable table = scan.getTable(); final TranslatableTable translatableTable = table.unwrap(TranslatableTable.class); if (translatableTable != null) { return translatableTable.toRel(context, table); } return super.visit(scan); } }); return root.withRel(rel2); } catch (Exception e) { throw new RuntimeException("Error while parsing view definition: " + queryString, e); } } } --------------------------------------------------------------------------- public static SchemaPlus registerRootSchema(List<PrestoTable> tabList, List<PrestoViewTable> viewTables) { SchemaPlus rootSchema = Frameworks.createRootSchema(true); for (PrestoTable table : tabList) { rootSchema.add(table.getTableName(), table); } List<PrestoViewTable> vts = new ArrayList<>(); PrestoViewTable pt = new PrestoViewTable("V_EMP", "select * from emp where empid>10"); vts.add(pt); // // for (PrestoViewTable pv : viewTables) { // rootSchema.add(pv.getVName(), pv); // } return rootSchema; } -------------------------------------------------------------------------- MyTest: public class CalciteTest { public static void main(String[] args) { // String sql = "select * from dept "; String sql1 = "select a.* from dept a left join emp b on a.deptno=b.deptno where a.name in('compute','aab') and b.deptno='aa' order by a.deptno limit 10"; String sql2 = "select a.name from dept a left join emp b on a.deptno=b.deptno where a.name in('compute','aab') and b.deptno='aa'"; String sql3 = "select count(distinct deptno) from dept where deptno='aa'"; String sql4 = "select * from v_emp"; // sqlToRelNode(sql); sqlToRelNode(sql4); } private static RelNode sqlToRelNode(String sql) { SchemaPlus rootSchema = CalciteUtils.registerRootSchema(createTables(), createVTables()); //expandView(rootSchema); final FrameworkConfig fromworkConfig = Frameworks.newConfigBuilder().parserConfig(SqlParser.Config.DEFAULT).defaultSchema(rootSchema).traitDefs(ConventionTraitDef.INSTANCE, RelDistributionTraitDef.INSTANCE).build(); try { //---------------------SQL to SqlNode--------------------------------- SqlTypeFactoryImpl factory = new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT); // sql parser SqlParser parser = SqlParser.create(sql, SqlParser.Config.DEFAULT); SqlNode parsed = parser.parseStmt(); CalciteCatalogReader calciteCatalogReader = new CalciteCatalogReader(CalciteSchema.from(rootSchema), CalciteSchema.from(rootSchema).path(null), factory, new CalciteConnectionConfigImpl(new Properties())); // sql validate SqlValidator validator = SqlValidatorUtil.newValidator(SqlStdOperatorTable.instance(), calciteCatalogReader, factory, CalciteUtils.conformance(fromworkConfig)); SqlNode validated = validator.validate(parsed); //---------------------Planner--------------------------------- VolcanoPlanner planner = new PrestoVolcanoPlanner(); planner.addRelTraitDef(ConventionTraitDef.INSTANCE); planner.addRelTraitDef(RelDistributionTraitDef.INSTANCE); final RelOptCluster relOptCluster = RelOptCluster.create(planner, new RexBuilder(new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT))); //add RelMetadataProvider relOptCluster.setMetadataProvider(PrestoRelMetaDataProvider.INSTANCE); // SqlNode toRelNode final SqlToRelConverter.Config config = SqlToRelConverter.configBuilder().withConfig(fromworkConfig.getSqlToRelConverterConfig()).withTrimUnusedFields(false).withExpand(true).withConvertTableAccess(false).build(); final SqlToRelConverter sqlToRelConverter = new SqlToRelConverter(new PrestoView(validator, calciteCatalogReader, relOptCluster, config), validator, calciteCatalogReader, relOptCluster, fromworkConfig.getConvertletTable(), config); RelRoot root = sqlToRelConverter.convertQuery(validated, false, true); root = root.withRel(sqlToRelConverter.flattenTypes(root.rel, true)); RelNode relNode = root.rel; //使用启发式实现谓词下推 HepProgramBuilder builder = HepProgram.builder().addRuleInstance(FilterJoinRule.FilterIntoJoinRule.FILTER_ON_JOIN).addRuleInstance(FilterProjectTransposeRule.INSTANCE).addRuleInstance(FilterJoinRule.FILTER_ON_JOIN).addRuleInstance(ProjectMergeRule.INSTANCE).addRuleInstance(SemiJoinRule.PROJECT); HepPlanner hepPlanner = new HepPlanner(builder.build()); hepPlanner.setRoot(relNode); relNode = hepPlanner.findBestExp(); //关键逻辑 RelTraitSet desiredTraits = relOptCluster.traitSetOf(PrestoRel.CONVENTION); if (!relNode.getTraitSet().equals(desiredTraits)) { relNode = planner.changeTraits(relNode, desiredTraits); } planner.setRoot(relNode); relNode = planner.findBestExp(); System.out.println("-----------------------------------------------------------"); System.out.println("The Best relational expression string:"); System.out.println(RelOptUtil.toString(relNode, SqlExplainLevel.ALL_ATTRIBUTES)); System.out.println("-----------------------------------------------------------"); RelOptCost cost = planner.getCost(relNode, PrestoRelMetadataQuery.INSTANCE); System.out.println(cost.toString()); System.out.println("-----------------------------------------------------------"); } catch (Exception e) { e.printStackTrace(); } return null; } private static List<PrestoTable> createTables() { List<PrestoTable> tabList = new ArrayList<>(); String[] fields = new String[]\{"DEPTNO", "NAME", "LEADER"}; String[] fieldTypes = new String[]\{"int", "string", "string"}; List<ColStatistics> cols = new ArrayList<>(); cols.add(new ColStatistics("DEPTNO", 5)); cols.add(new ColStatistics("NAME", 5)); cols.add(new ColStatistics("LEADER", 5)); PrestoTableInfo info1 = new PrestoTableInfo(); info1.setFields(fields); info1.setFieldTypes(fieldTypes); info1.setRowCount(5d); info1.setTableName("DEPT"); info1.setStatistics(cols); PrestoTable t1 = new PrestoTable(info1); String[] fields2 = new String[]\{"EMPID", "NAME", "DEPTNO", "SALARY"}; String[] fieldTypes2 = new String[]\{"int", "string", "int", "double"}; List<ColStatistics> cols2 = new ArrayList<>(); cols2.add(new ColStatistics("EMPID", 50)); cols2.add(new ColStatistics("NAME", 50)); cols2.add(new ColStatistics("DEPTNO", 5)); cols2.add(new ColStatistics("SALARY", 5)); PrestoTableInfo info2 = new PrestoTableInfo(); info2.setFields(fields2); info2.setFieldTypes(fieldTypes2); info2.setRowCount(50d); info2.setTableName("EMP"); info2.setStatistics(cols2); PrestoTable t2 = new PrestoTable(info2); tabList.add(t1); tabList.add(t2); return tabList; } =============================================== *{color:#FF0000}ERROR:{color}* Exception in thread "main" java.lang.AssertionErrorException in thread "main" java.lang.AssertionError at org.apache.calcite.util.Pair.zip(Pair.java:202) at org.apache.calcite.rex.RexUtil.generateCastExpressions(RexUtil.java:134) at org.apache.calcite.rex.RexUtil.generateCastExpressions(RexUtil.java:116) at org.apache.calcite.plan.RelOptUtil.createCastRel(RelOptUtil.java:749) at org.apache.calcite.plan.RelOptUtil.createCastRel(RelOptUtil.java:722) at com.niwodai.pangu.datasearch.calcite.PrestoViewTable.expandView(PrestoViewTable.java:64) at com.niwodai.pangu.datasearch.calcite.PrestoViewTable.toRel(PrestoViewTable.java:42) at org.apache.calcite.prepare.RelOptTableImpl.toRel(RelOptTableImpl.java:269) at org.apache.calcite.sql2rel.RelStructuredTypeFlattener.rewriteRel(RelStructuredTypeFlattener.java:694) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.calcite.util.ReflectUtil.invokeVisitorInternal(ReflectUtil.java:257) at org.apache.calcite.util.ReflectUtil.invokeVisitor(ReflectUtil.java:214) at org.apache.calcite.util.ReflectUtil$1.invokeVisitor(ReflectUtil.java:464) at org.apache.calcite.sql2rel.RelStructuredTypeFlattener$RewriteRelVisitor.visit(RelStructuredTypeFlattener.java:768) at org.apache.calcite.rel.SingleRel.childrenAccept(SingleRel.java:72) at org.apache.calcite.rel.RelVisitor.visit(RelVisitor.java:44) at org.apache.calcite.sql2rel.RelStructuredTypeFlattener$RewriteRelVisitor.visit(RelStructuredTypeFlattener.java:763) at org.apache.calcite.sql2rel.RelStructuredTypeFlattener.rewrite(RelStructuredTypeFlattener.java:195) at org.apache.calcite.sql2rel.SqlToRelConverter.flattenTypes(SqlToRelConverter.java:468) at com.niwodai.pangu.datasearch.calcite.CalciteTest.sqlToRelNode(CalciteTest.java:97) at com.niwodai.pangu.datasearch.calcite.CalciteTest.main(CalciteTest.java:59) > View test when it occur java.lang.AssertionError > -------------------------------------------------- > > Key: CALCITE-3301 > URL: https://issues.apache.org/jira/browse/CALCITE-3301 > Project: Calcite > Issue Type: Bug > Components: core > Reporter: Water Cut Off > Priority: Major > > * *{color:#00875a}I want to use calcite to parse view, and convert view to my > own RelNode, but I am not sure how to use ViewExpander ,can you give me an > example to solve this problem, thanks ?{color}* > > public class PrestoView implements RelOptTable.ViewExpander { > private final SqlValidator validator; > private final Prepare.CatalogReader catalogReader; > private final RelOptCluster cluster; > private final SqlToRelConverter.Config config; > public PrestoView(SqlValidator validator, Prepare.CatalogReader > catalogReader, RelOptCluster cluster, SqlToRelConverter.Config config) > { this.validator = validator; this.catalogReader = catalogReader; > this.cluster = cluster; this.config = config; } > @Override > public RelRoot expandView(RelDataType rowType, String queryString, > List<String> schemaPath, List<String> viewPath) { > try > { SqlNode parsedNode = SqlParser.create(queryString).parseStmt(); SqlNode > validatedNode = validator.validate(parsedNode); SqlToRelConverter converter = > new SqlToRelConverter(this, validator, catalogReader, cluster, > StandardConvertletTable.INSTANCE, config); return > converter.convertQuery(validatedNode, false, true); } > catch (SqlParseException e) > { throw new RuntimeException("Error happened while expanding view.", e); } > } > -------------------------------------------------------------- > public class PrestoViewTable extends AbstractTable implements > TranslatableTable { > private final String vName; > private final String viewSql; > public PrestoViewTable(String vName, String viewSql) > { super(); this.vName = vName; this.viewSql = viewSql; } > public String getVName() > { return vName; } > @Override > public RelNode toRel(RelOptTable.ToRelContext context, RelOptTable > relOptTable) > { return expandView(context, relOptTable.getRowType(), viewSql).rel; } > @Override > public RelDataType getRowType(final RelDataTypeFactory typeFactory) { > RelDataTypeFactory.Builder builder = typeFactory.builder(); > builder.add("empid", new BasicSqlType(new RelDataTypeSystemImpl() { > }, SqlTypeName.INTEGER)); > builder.add("deptno", new BasicSqlType(new RelDataTypeSystemImpl() { > }, SqlTypeName.VARCHAR)); > return builder.build(); > } > @Override > public Schema.TableType getJdbcTableType() > { return Schema.TableType.VIEW; } > private RelRoot expandView(RelOptTable.ToRelContext context, RelDataType > rowType, String queryString) { > try { > final RelRoot root = context.expandView(rowType, queryString, null, null); > final RelNode rel = RelOptUtil.createCastRel(root.rel, rowType, true); > // Expand any views > final RelNode rel2 = rel.accept(new RelShuttleImpl() { > @Override > public RelNode visit(TableScan scan) { > final RelOptTable table = scan.getTable(); > final TranslatableTable translatableTable = > table.unwrap(TranslatableTable.class); > if (translatableTable != null) > { return translatableTable.toRel(context, table); } > return super.visit(scan); > } > }); > return root.withRel(rel2); > } catch (Exception e) > { throw new RuntimeException("Error while parsing view definition: " + > queryString, e); } > } > } > --------------------------------------------------------------------------- > public static SchemaPlus registerRootSchema(List<PrestoTable> tabList, > List<PrestoViewTable> viewTables) { > SchemaPlus rootSchema = Frameworks.createRootSchema(true); > for (PrestoTable table : tabList) > { rootSchema.add(table.getTableName(), table); } > List<PrestoViewTable> vts = new ArrayList<>(); > PrestoViewTable pt = new PrestoViewTable("V_EMP", "select * from emp where > empid>10"); > vts.add(pt); > // > // for (PrestoViewTable pv : viewTables) > { // rootSchema.add(pv.getVName(), pv); // } > return rootSchema; > } > > {color:#00875a}----------------------------*Test----*---------------------------------------------------------------------------------------------------{color} > > public class CalciteTest { > public static void main(String[] args) > { // String sql = "select * from dept "; String sql1 = "select a.* from dept > a left join emp b on a.deptno=b.deptno where a.name in('compute','aab') and > b.deptno='aa' order by a.deptno limit 10"; String sql2 = "select a.name from > dept a left join emp b on a.deptno=b.deptno where a.name in('compute','aab') > and b.deptno='aa'"; String sql3 = "select count(distinct deptno) from dept > where deptno='aa'"; String sql4 = "select * from v_emp"; // > sqlToRelNode(sql); sqlToRelNode(sql4); } > private static RelNode sqlToRelNode(String sql) { > SchemaPlus rootSchema = CalciteUtils.registerRootSchema(createTables(), > createVTables()); > //expandView(rootSchema); > final FrameworkConfig fromworkConfig = > Frameworks.newConfigBuilder().parserConfig(SqlParser.Config.DEFAULT).defaultSchema(rootSchema).traitDefs(ConventionTraitDef.INSTANCE, > RelDistributionTraitDef.INSTANCE).build(); > try { > //---------------------SQL to SqlNode--------------------------------- > SqlTypeFactoryImpl factory = new > SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT); > // sql parser > SqlParser parser = SqlParser.create(sql, SqlParser.Config.DEFAULT); > SqlNode parsed = parser.parseStmt(); > CalciteCatalogReader calciteCatalogReader = new > CalciteCatalogReader(CalciteSchema.from(rootSchema), > CalciteSchema.from(rootSchema).path(null), factory, new > CalciteConnectionConfigImpl(new Properties())); > // sql validate > SqlValidator validator = > SqlValidatorUtil.newValidator(SqlStdOperatorTable.instance(), > calciteCatalogReader, factory, CalciteUtils.conformance(fromworkConfig)); > SqlNode validated = validator.validate(parsed); > //---------------------Planner--------------------------------- > VolcanoPlanner planner = new PrestoVolcanoPlanner(); > planner.addRelTraitDef(ConventionTraitDef.INSTANCE); > planner.addRelTraitDef(RelDistributionTraitDef.INSTANCE); > final RelOptCluster relOptCluster = RelOptCluster.create(planner, new > RexBuilder(new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT))); > //add RelMetadataProvider > relOptCluster.setMetadataProvider(PrestoRelMetaDataProvider.INSTANCE); > // SqlNode toRelNode > final SqlToRelConverter.Config config = > SqlToRelConverter.configBuilder().withConfig(fromworkConfig.getSqlToRelConverterConfig()).withTrimUnusedFields(false).withExpand(true).withConvertTableAccess(false).build(); > final SqlToRelConverter sqlToRelConverter = new SqlToRelConverter(new > PrestoView(validator, calciteCatalogReader, relOptCluster, config), > validator, calciteCatalogReader, relOptCluster, > fromworkConfig.getConvertletTable(), config); > RelRoot root = sqlToRelConverter.convertQuery(validated, false, true); > root = root.withRel(sqlToRelConverter.flattenTypes(root.rel, true)); > RelNode relNode = root.rel; > HepProgramBuilder builder = > HepProgram.builder().addRuleInstance(FilterJoinRule.FilterIntoJoinRule.FILTER_ON_JOIN).addRuleInstance(FilterProjectTransposeRule.INSTANCE).addRuleInstance(FilterJoinRule.FILTER_ON_JOIN).addRuleInstance(ProjectMergeRule.INSTANCE).addRuleInstance(SemiJoinRule.PROJECT); > HepPlanner hepPlanner = new HepPlanner(builder.build()); > hepPlanner.setRoot(relNode); > relNode = hepPlanner.findBestExp(); > RelTraitSet desiredTraits = relOptCluster.traitSetOf(PrestoRel.CONVENTION); > if (!relNode.getTraitSet().equals(desiredTraits)) > { relNode = planner.changeTraits(relNode, desiredTraits); } > planner.setRoot(relNode); > relNode = planner.findBestExp(); > System.out.println("-----------------------------------------------------------"); > System.out.println("The Best relational expression string:"); > System.out.println(RelOptUtil.toString(relNode, > SqlExplainLevel.ALL_ATTRIBUTES)); > > System.out.println("-----------------------------------------------------------"); > RelOptCost cost = planner.getCost(relNode, PrestoRelMetadataQuery.INSTANCE); > System.out.println(cost.toString()); > > System.out.println("-----------------------------------------------------------"); > } catch (Exception e) > { e.printStackTrace(); } > return null; > } > private static List<PrestoTable> createTables() > { List<PrestoTable> tabList = new ArrayList<>(); String[] fields = new > String[]\\{"DEPTNO", "NAME", "LEADER"} > ; > String[] fieldTypes = new String[]\{"int", "string", "string"}; > List<ColStatistics> cols = new ArrayList<>(); > cols.add(new ColStatistics("DEPTNO", 5)); > cols.add(new ColStatistics("NAME", 5)); > cols.add(new ColStatistics("LEADER", 5)); > PrestoTableInfo info1 = new PrestoTableInfo(); > info1.setFields(fields); > info1.setFieldTypes(fieldTypes); > info1.setRowCount(5d); > info1.setTableName("DEPT"); > info1.setStatistics(cols); > PrestoTable t1 = new PrestoTable(info1); > String[] fields2 = new String[]\{"EMPID", "NAME", "DEPTNO", "SALARY"}; > String[] fieldTypes2 = new String[]\{"int", "string", "int", "double"}; > List<ColStatistics> cols2 = new ArrayList<>(); > cols2.add(new ColStatistics("EMPID", 50)); > cols2.add(new ColStatistics("NAME", 50)); > cols2.add(new ColStatistics("DEPTNO", 5)); > cols2.add(new ColStatistics("SALARY", 5)); > PrestoTableInfo info2 = new PrestoTableInfo(); > info2.setFields(fields2); > info2.setFieldTypes(fieldTypes2); > info2.setRowCount(50d); > info2.setTableName("EMP"); > info2.setStatistics(cols2); > PrestoTable t2 = new PrestoTable(info2); > tabList.add(t1); > tabList.add(t2); > return tabList; > } > =============================================== > *{color:#ff0000}ERROR:{color}* > Exception in thread "main" java.lang.AssertionErrorException in thread "main" > java.lang.AssertionError at org.apache.calcite.util.Pair.zip(Pair.java:202) > at org.apache.calcite.rex.RexUtil.generateCastExpressions(RexUtil.java:134) > at org.apache.calcite.rex.RexUtil.generateCastExpressions(RexUtil.java:116) > at org.apache.calcite.plan.RelOptUtil.createCastRel(RelOptUtil.java:749) at > org.apache.calcite.plan.RelOptUtil.createCastRel(RelOptUtil.java:722) at > com.niwodai.pangu.datasearch.calcite.PrestoViewTable.expandView(PrestoViewTable.java:64) > at > com.niwodai.pangu.datasearch.calcite.PrestoViewTable.toRel(PrestoViewTable.java:42) > at > org.apache.calcite.prepare.RelOptTableImpl.toRel(RelOptTableImpl.java:269) at > org.apache.calcite.sql2rel.RelStructuredTypeFlattener.rewriteRel(RelStructuredTypeFlattener.java:694) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:498) at > org.apache.calcite.util.ReflectUtil.invokeVisitorInternal(ReflectUtil.java:257) > at org.apache.calcite.util.ReflectUtil.invokeVisitor(ReflectUtil.java:214) > at org.apache.calcite.util.ReflectUtil$1.invokeVisitor(ReflectUtil.java:464) > at > org.apache.calcite.sql2rel.RelStructuredTypeFlattener$RewriteRelVisitor.visit(RelStructuredTypeFlattener.java:768) > at org.apache.calcite.rel.SingleRel.childrenAccept(SingleRel.java:72) at > org.apache.calcite.rel.RelVisitor.visit(RelVisitor.java:44) at > org.apache.calcite.sql2rel.RelStructuredTypeFlattener$RewriteRelVisitor.visit(RelStructuredTypeFlattener.java:763) > at > org.apache.calcite.sql2rel.RelStructuredTypeFlattener.rewrite(RelStructuredTypeFlattener.java:195) > at > org.apache.calcite.sql2rel.SqlToRelConverter.flattenTypes(SqlToRelConverter.java:468) > at > com.niwodai.pangu.datasearch.calcite.CalciteTest.sqlToRelNode(CalciteTest.java:97) > at com.niwodai.pangu.datasearch.calcite.CalciteTest.main(CalciteTest.java:59) > -- This message was sent by Atlassian Jira (v8.3.2#803003)