public SqlToRelConverter( RelOptTable.ViewExpander viewExpander, SqlValidator validator, Prepare.CatalogReader catalogReader, RelOptCluster cluster, SqlRexConvertletTable convertletTable, Config config) { this.viewExpander = viewExpander; this.opTab = (validator == null) ? SqlStdOperatorTable.instance() : validator.getOperatorTable(); this.validator = validator; this.catalogReader = catalogReader; this.subQueryConverter = new NoOpSubQueryConverter(); this.rexBuilder = cluster.getRexBuilder(); this.typeFactory = rexBuilder.getTypeFactory(); this.cluster = Objects.requireNonNull(cluster); this.exprConverter = new SqlNodeToRexConverterImpl(convertletTable); this.explainParamCount = 0; this.config = new ConfigBuilder().withConfig(config).build(); this.relBuilder = config.getRelBuilderFactory().create(cluster, null); }
/** * Walks over a tree of relational expressions, replacing each * {@link org.apache.calcite.rel.RelNode} with a 'slimmed down' relational * expression that projects * only the columns required by its consumer. * * @param root Root of relational expression tree * @return Trimmed relational expression */ protected RelRoot trimUnusedFields(RelRoot root) { final SqlToRelConverter.Config config = SqlToRelConverter.configBuilder() .withTrimUnusedFields(shouldTrim(root.rel)) .withExpand(THREAD_EXPAND.get()) .build(); final SqlToRelConverter converter = getSqlToRelConverter(getSqlValidator(), catalogReader, config); final boolean ordered = !root.collation.getFieldCollations().isEmpty(); final boolean dml = SqlKind.DML.contains(root.kind); return root.withRel(converter.trimUnusedFields(dml || ordered, root.rel)); }
@Deprecated // to be removed before 2.0 public ConfigBuilder withInSubqueryThreshold(int inSubQueryThreshold) { return withInSubQueryThreshold(inSubQueryThreshold); }
.withTrimUnusedFields(true) .withExpand(THREAD_EXPAND.get()) .withExplain(sqlQuery.getKind() == SqlKind.EXPLAIN); final SqlToRelConverter sqlToRelConverter = getSqlToRelConverter(validator, catalogReader, builder.build());
.withTrimUnusedFields(true) .withExpand(THREAD_EXPAND.get()) .withExplain(sqlQuery.getKind() == SqlKind.EXPLAIN); final SqlToRelConverter sqlToRelConverter = getSqlToRelConverter(validator, catalogReader, builder.build());
final SqlToRelConverter.Config sqlToRelConverterConfig = SqlToRelConverter .configBuilder() .withExpand(false) .withDecorrelationEnabled(false) .withTrimUnusedFields(false) .withInSubQueryThreshold(Integer.MAX_VALUE) .build(); final FrameworkConfig frameworkConfig = Frameworks .newConfigBuilder()
.withTrimUnusedFields(true).withExpand(enableExpand).build(); } else { localConfig = config;
.withTrimUnusedFields(true).withExpand(enableExpand).build(); } else { localConfig = config;
diffRepos.assertEquals("planBefore", "${planBefore}", planBefore); converter = t.createSqlToRelConverter(validator, catalogReader, typeFactory, SqlToRelConverter.configBuilder().withTrimUnusedFields(true).build()); root = root.withRel(converter.trimUnusedFields(false, root.rel)); String planAfter = NL + RelOptUtil.toString(root.rel);
diffRepos.assertEquals("planBefore", "${planBefore}", planBefore); converter = t.createSqlToRelConverter(validator, catalogReader, typeFactory, SqlToRelConverter.configBuilder().withTrimUnusedFields(true).build()); root = root.withRel(converter.trimUnusedFields(false, root.rel)); String planAfter = NL + RelOptUtil.toString(root.rel);
final SqlToRelConverter.Config config = SqlToRelConverter .configBuilder() .withConfig(sqlToRelConverterConfig) .withTrimUnusedFields(false) .withConvertTableAccess(false) .build(); final SqlToRelConverter sqlToRelConverter = new SqlToRelConverter(this, validator,
/** Populates a materialization record, converting a table path * (essentially a list of strings, like ["hr", "sales"]) into a table object * that can be used in the planning process. */ void populate(Materialization materialization) { SqlParser parser = SqlParser.create(materialization.sql); SqlNode node; try { node = parser.parseStmt(); } catch (SqlParseException e) { throw new RuntimeException("parse failed", e); } final SqlToRelConverter.Config config = SqlToRelConverter.configBuilder() .withTrimUnusedFields(true).build(); SqlToRelConverter sqlToRelConverter2 = getSqlToRelConverter(getSqlValidator(), catalogReader, config); materialization.queryRel = sqlToRelConverter2.convertQuery(node, true, true).rel; // Identify and substitute a StarTable in queryRel. // // It is possible that no StarTables match. That is OK, but the // materialization patterns that are recognized will not be as rich. // // It is possible that more than one StarTable matches. TBD: should we // take the best (whatever that means), or all of them? useStar(schema, materialization); RelOptTable table = this.catalogReader.getTable(materialization.materializedTable.path()); materialization.tableRel = sqlToRelConverter2.toRel(table); }
private ParseResult convert_(Context context, String sql, boolean analyze, boolean fail, CalciteCatalogReader catalogReader, SqlValidator validator, SqlNode sqlNode1) { final JavaTypeFactory typeFactory = context.getTypeFactory(); final Convention resultConvention = enableBindable ? BindableConvention.INSTANCE : EnumerableConvention.INSTANCE; final HepPlanner planner = new HepPlanner(new HepProgramBuilder().build()); planner.addRelTraitDef(ConventionTraitDef.INSTANCE); final SqlToRelConverter.ConfigBuilder configBuilder = SqlToRelConverter.configBuilder().withTrimUnusedFields(true); if (analyze) { configBuilder.withConvertTableAccess(false); } final CalcitePreparingStmt preparingStmt = new CalcitePreparingStmt(this, context, catalogReader, typeFactory, context.getRootSchema(), null, planner, resultConvention, createConvertletTable()); final SqlToRelConverter converter = preparingStmt.getSqlToRelConverter(validator, catalogReader, configBuilder.build()); final RelRoot root = converter.convertQuery(sqlNode1, false, true); if (analyze) { return analyze_(validator, sql, sqlNode1, root, fail); } return new ConvertResult(this, validator, sql, sqlNode1, validator.getValidatedNodeType(sqlNode1), root); }
final SqlToRelConverter.Config config = SqlToRelConverter .configBuilder() .withConfig(sqlToRelConverterConfig) .withTrimUnusedFields(false) .withConvertTableAccess(false) .build(); final SqlToRelConverter sqlToRelConverter = new SqlToRelConverter(new ViewExpanderImpl(), validator,
private ParseResult convert_(Context context, String sql, boolean analyze, boolean fail, CalciteCatalogReader catalogReader, SqlValidator validator, SqlNode sqlNode1) { final JavaTypeFactory typeFactory = context.getTypeFactory(); final Convention resultConvention = enableBindable ? BindableConvention.INSTANCE : EnumerableConvention.INSTANCE; final HepPlanner planner = new HepPlanner(new HepProgramBuilder().build()); planner.addRelTraitDef(ConventionTraitDef.INSTANCE); final SqlToRelConverter.ConfigBuilder configBuilder = SqlToRelConverter.configBuilder().withTrimUnusedFields(true); if (analyze) { configBuilder.withConvertTableAccess(false); } final CalcitePreparingStmt preparingStmt = new CalcitePreparingStmt(this, context, catalogReader, typeFactory, context.getRootSchema(), null, planner, resultConvention, createConvertletTable()); final SqlToRelConverter converter = preparingStmt.getSqlToRelConverter(validator, catalogReader, configBuilder.build()); final RelRoot root = converter.convertQuery(sqlNode1, false, true); if (analyze) { return analyze_(validator, sql, sqlNode1, root, fail); } return new ConvertResult(this, validator, sql, sqlNode1, validator.getValidatedNodeType(sqlNode1), root); }
/** Populates a materialization record, converting a table path * (essentially a list of strings, like ["hr", "sales"]) into a table object * that can be used in the planning process. */ void populate(Materialization materialization) { SqlParser parser = SqlParser.create(materialization.sql); SqlNode node; try { node = parser.parseStmt(); } catch (SqlParseException e) { throw new RuntimeException("parse failed", e); } final SqlToRelConverter.Config config = SqlToRelConverter.configBuilder() .withTrimUnusedFields(true).build(); SqlToRelConverter sqlToRelConverter2 = getSqlToRelConverter(getSqlValidator(), catalogReader, config); materialization.queryRel = sqlToRelConverter2.convertQuery(node, true, true).rel; // Identify and substitute a StarTable in queryRel. // // It is possible that no StarTables match. That is OK, but the // materialization patterns that are recognized will not be as rich. // // It is possible that more than one StarTable matches. TBD: should we // take the best (whatever that means), or all of them? useStar(schema, materialization); RelOptTable table = this.catalogReader.getTable(materialization.materializedTable.path()); materialization.tableRel = sqlToRelConverter2.toRel(table); }
private ParseResult convert_(Context context, String sql, boolean analyze, boolean fail, CalciteCatalogReader catalogReader, SqlValidator validator, SqlNode sqlNode1) { final JavaTypeFactory typeFactory = context.getTypeFactory(); final Convention resultConvention = enableBindable ? BindableConvention.INSTANCE : EnumerableConvention.INSTANCE; final HepPlanner planner = new HepPlanner(new HepProgramBuilder().build()); planner.addRelTraitDef(ConventionTraitDef.INSTANCE); final SqlToRelConverter.ConfigBuilder configBuilder = SqlToRelConverter.configBuilder().withTrimUnusedFields(true); if (analyze) { configBuilder.withConvertTableAccess(false); } final CalcitePreparingStmt preparingStmt = new CalcitePreparingStmt(this, context, catalogReader, typeFactory, context.getRootSchema(), null, planner, resultConvention, createConvertletTable()); final SqlToRelConverter converter = preparingStmt.getSqlToRelConverter(validator, catalogReader, configBuilder.build()); final RelRoot root = converter.convertQuery(sqlNode1, false, true); if (analyze) { return analyze_(validator, sql, sqlNode1, root, fail); } return new ConvertResult(this, validator, sql, sqlNode1, validator.getValidatedNodeType(sqlNode1), root); }
@Override public RelRoot expandView(RelDataType rowType, String queryString, List<String> schemaPath, List<String> viewPath) { expansionDepth++; SqlParser parser = prepare.createParser(queryString); SqlNode sqlNode; try { sqlNode = parser.parseQuery(); } catch (SqlParseException e) { throw new RuntimeException("parse failed", e); } // View may have different schema path than current connection. final CatalogReader catalogReader = this.catalogReader.withSchemaPath(schemaPath); SqlValidator validator = createSqlValidator(catalogReader); final SqlToRelConverter.Config config = SqlToRelConverter.configBuilder() .withTrimUnusedFields(true).build(); SqlToRelConverter sqlToRelConverter = getSqlToRelConverter(validator, catalogReader, config); RelRoot root = sqlToRelConverter.convertQuery(sqlNode, true, false); --expansionDepth; return root; }
/** * Returns a rel root that defers materialization of scans via {@link com.dremio.exec.planner.logical.ConvertibleScan} * * Used for serialization. */ public RelRootPlus toConvertibleRelRoot(final SqlNode validatedNode, boolean expand) { final OptionManager o = settings.getOptions(); final boolean useLegacyDecorrelator = o.getOption(PlannerSettings.USE_LEGACY_DECORRELATOR); final long inSubQueryThreshold = o.getOption(ExecConstants.FAST_OR_ENABLE) ? o.getOption(ExecConstants.FAST_OR_MAX_THRESHOLD) : settings.getOptions().getOption(ExecConstants.PLANNER_IN_SUBQUERY_THRESHOLD); final SqlToRelConverter.Config config = SqlToRelConverter.configBuilder() .withInSubQueryThreshold((int) inSubQueryThreshold) .withTrimUnusedFields(true) .withConvertTableAccess(false) .withExpand(expand) .build(); final ReflectionAllowedMonitoringConvertletTable convertletTable = new ReflectionAllowedMonitoringConvertletTable(new ConvertletTable(functionContext.getContextInformation())); final SqlToRelConverter sqlToRelConverter = new DremioSqlToRelConverter(this, validator, convertletTable, config); // Previously we had "top" = !innerQuery, but calcite only adds project if it is not a top query. final RelRoot rel = sqlToRelConverter.convertQuery(validatedNode, false /* needs validate */, false /* top */); final RelNode rel2 = sqlToRelConverter.flattenTypes(rel.rel, true); final RelNode rel3; rel3 = expand ? rel2 : rel2.accept(new RelsWithRexSubQueryFlattener(sqlToRelConverter)); final RelNode rel4 = RelDecorrelator.decorrelateQuery(rel3, useLegacyDecorrelator); if (logger.isDebugEnabled()) { logger.debug("ConvertQuery with expand = {}:\n{}", expand, RelOptUtil.toString(rel4, SqlExplainLevel.ALL_ATTRIBUTES)); } return RelRootPlus.of(rel4, rel.kind, convertletTable.isReflectionDisallowed()); }
@Override public RelRoot expandView(RelDataType rowType, String queryString, List<String> schemaPath, List<String> viewPath) { expansionDepth++; SqlParser parser = prepare.createParser(queryString); SqlNode sqlNode; try { sqlNode = parser.parseQuery(); } catch (SqlParseException e) { throw new RuntimeException("parse failed", e); } // View may have different schema path than current connection. final CatalogReader catalogReader = this.catalogReader.withSchemaPath(schemaPath); SqlValidator validator = createSqlValidator(catalogReader); SqlNode sqlNode1 = validator.validate(sqlNode); final SqlToRelConverter.Config config = SqlToRelConverter.configBuilder() .withTrimUnusedFields(true).build(); SqlToRelConverter sqlToRelConverter = getSqlToRelConverter(validator, catalogReader, config); RelRoot root = sqlToRelConverter.convertQuery(sqlNode1, true, false); --expansionDepth; return root; }