Created
December 8, 2025 15:09
-
-
Save mbwhite/4899dfd959839a6eedd6ee1542c9fb08 to your computer and use it in GitHub Desktop.
Calcite Optimizer Removes Correlation Variable Context
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class FromSqlTests { | |
| @Test | |
| void calciterelNode() { | |
| try { | |
| final String sql = """ | |
| SELECT | |
| P.P_PARTKEY | |
| FROM | |
| PART P | |
| JOIN PARTSUPP PS ON P.P_PARTKEY = PS.PS_PARTKEY | |
| WHERE | |
| PS.PS_SUPPLYCOST = ( | |
| SELECT | |
| MIN(PS_INNER.PS_SUPPLYCOST) | |
| FROM | |
| PARTSUPP PS_INNER | |
| WHERE | |
| PS_INNER.PS_PARTKEY = P.P_PARTKEY | |
| ) | |
| """; | |
| final SqlParser.Config parserCfg = SqlParser.config() | |
| .withCaseSensitive(false) | |
| .withConformance(SqlConformanceEnum.DEFAULT); | |
| SqlNode parsed; | |
| parsed = SqlParser.create(sql, parserCfg).parseQuery(); | |
| final CatalogReader tpchCatalogReader = Schemas.fromTpcH(); | |
| final RelDataTypeFactory typeFactory = new JavaTypeFactoryImpl(); | |
| final SqlValidator validator = SqlValidatorUtil.newValidator( | |
| SqlStdOperatorTable.instance(), // built-in operators | |
| tpchCatalogReader, // our schema/catalog | |
| typeFactory, | |
| SqlValidator.Config.DEFAULT | |
| .withConformance(SqlConformanceEnum.DEFAULT) | |
| .withIdentifierExpansion(true) // expands aliases / qualifiers | |
| ); | |
| final SqlNode validated = validator.validate(parsed); | |
| System.out.println("SqlNode Parsed to >>"); | |
| System.out.println(validated.toString()); | |
| final HepProgram program = HepProgram.builder() | |
| .build(); | |
| final HepPlanner planner = new HepPlanner(program); | |
| final RelOptCluster cluster = RelOptCluster.create(planner, new RexBuilder(typeFactory)); | |
| final SqlToRelConverter.Config convertCfg = SqlToRelConverter.config() | |
| .withExpand(false); // typical defaults | |
| final SqlToRelConverter toRel = new SqlToRelConverter( | |
| null, // ViewExpander (null if unused) | |
| validator, | |
| tpchCatalogReader, // same catalog reader | |
| cluster, | |
| StandardConvertletTable.INSTANCE, | |
| convertCfg); | |
| final RelRoot relRoot = toRel.convertQuery(validated, false, true); | |
| final RelNode rel = relRoot.project(); // drop hidden sort keys if needed | |
| System.out.println("-----"); | |
| System.out.println("Converted to CalciteRelNodes"); | |
| System.out.println(rel.explain()); // print logical plan | |
| final HepProgram hepProgram = HepProgram.builder() | |
| .addRuleInstance(CoreRules.FILTER_INTO_JOIN) | |
| // .addRuleInstance(CoreRules.FILTER_REDUCE_EXPRESSIONS) | |
| // .addRuleInstance(CoreRules.FILTER_SCAN) | |
| .build(); | |
| // Build a copy hook to keep correlation maps aligned as nodes are copied | |
| Function2<RelNode, RelNode, Void> onCopyHook = (oldNode, newNode) -> { | |
| // Mimics RelDecorrelator#createCopyHook: update CorelMap entries | |
| // when a LogicalCorrelate or a referencing node is replaced. | |
| // (See RelDecorrelator source for exact logic.) | |
| return null; | |
| }; | |
| final HepPlanner hepPlanner = new HepPlanner(hepProgram, null, true, onCopyHook,RelOptCostImpl.FACTORY); | |
| hepPlanner.setRoot(relRoot.rel); | |
| final RelNode bestRelNode = hepPlanner.findBestExp(); | |
| final RelRoot optimizedf = RelRoot.of(bestRelNode, relRoot.kind); | |
| System.out.println("-----"); | |
| System.out.println("Optimised CalciteRelNodes"); | |
| System.out.println(optimizedf.rel.explain()); // print logical plan | |
| SqlDialect dialect = AnsiSqlDialect.DEFAULT; | |
| // 2) Convert RelRoot -> SqlNode | |
| RelToSqlConverter converter = new RelToSqlConverter(dialect); | |
| // visitRoot handles RelRoot; for a bare RelNode, use visitChild(0, rel) | |
| SqlNode sqlNode = converter.visitRoot(optimizedf.rel).asStatement(); | |
| System.out.println(sqlNode); | |
| assert (true); | |
| } catch (SqlParseException e) { | |
| e.printStackTrace(); | |
| // throw new RuntimeException(e); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment