trial of accepting empty project

This commit is contained in:
Zoltan Haindrich 2024-12-13 10:06:24 +00:00
parent ef12701816
commit 19609943aa
4 changed files with 53 additions and 30 deletions

View File

@ -296,7 +296,7 @@ public class CalciteRulesManager
cleanupRules.addRuleInstance(AggregateProjectMergeRule.Config.DEFAULT.toRule());
return Programs.sequence(
Programs.of(builder.build(), true, DefaultRelMetadataProvider.INSTANCE),
new DruidTrimFieldsProgram(true),
new DruidTrimFieldsProgram(false),
Programs.of(cleanupRules.build(), true, DefaultRelMetadataProvider.INSTANCE)
);
}
@ -553,7 +553,7 @@ public class CalciteRulesManager
{
final RelBuilder relBuilder = RelFactories.LOGICAL_BUILDER.create(rel.getCluster(), null);
final RelNode decorrelatedRel = RelDecorrelator.decorrelateQuery(rel, relBuilder);
RelNode ret = new DruidRelFieldTrimmer(null, relBuilder, true).trim(decorrelatedRel);
RelNode ret = new DruidRelFieldTrimmer(null, relBuilder, false).trim(decorrelatedRel);
return ret;
}

View File

@ -19,6 +19,7 @@
package org.apache.druid.sql.calcite.rule.logical;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import org.apache.calcite.plan.RelOptRule;
import org.apache.calcite.plan.RelOptRuleCall;
@ -82,14 +83,16 @@ public class LogicalUnnestRule extends RelOptRule implements SubstitutionRule
throw DruidException.defensive("Couldn't process possible unnest for reltree: \n%s", RelOptUtil.toString(cor));
}
unnestConfig.expr = new DruidCorrelateUnnestRel.CorrelatedFieldAccessToInputRef(cor.getCorrelationId())
.apply(unnestConfig.expr);
unnestConfig = unnestConfig.withExpr(
new DruidCorrelateUnnestRel.CorrelatedFieldAccessToInputRef(cor.getCorrelationId())
.apply(unnestConfig.expr)
);
RelDataTypeField unnestFieldType = Iterables.getLast(cor.getRowType().getFieldList());
RelBuilder builder = call.builder();
builder.push(cor.getLeft());
RelNode newNode = builder.push(
builder.push(
new LogicalUnnest(
cor.getCluster(),
cor.getTraitSet(),
@ -98,35 +101,59 @@ public class LogicalUnnestRule extends RelOptRule implements SubstitutionRule
unnestFieldType,
unnestConfig.condition
)
).build();
call.transformTo(newNode);
);
if (unnestConfig.discard) {
// drop unnested output column
ImmutableList<RexNode> fields = builder.fields();
builder.project(fields.subList(0, fields.size() - 1));
}
call.transformTo(builder.build());
}
private static class UnnestConfiguration
{
public RexNode expr;
private RexNode condition;
protected final RexNode expr;
protected final RexNode condition;
protected final boolean discard;
public UnnestConfiguration(RexNode unnestExpression, RexNode condition)
public UnnestConfiguration(RexNode unnestExpression, RexNode condition, boolean discard)
{
this.expr = unnestExpression;
this.condition = condition;
this.discard = discard;
}
public UnnestConfiguration withExpr(RexNode expr)
{
return new UnnestConfiguration(expr, condition, discard);
}
public static UnnestConfiguration ofExpression(RexNode unnestExpression)
{
return new UnnestConfiguration(unnestExpression, null);
return new UnnestConfiguration(unnestExpression, null, false);
}
public UnnestConfiguration withFilter(RexNode condition)
{
return new UnnestConfiguration(expr, condition);
return new UnnestConfiguration(expr, condition, discard);
}
public UnnestConfiguration withDiscard()
{
return new UnnestConfiguration(expr, condition, true);
}
}
private UnnestConfiguration unwrapUnnestConfigurationExpression(RelNode rel)
{
rel = rel.stripped();
if (rel instanceof Project) {
Project project = (Project) rel;
if (project.getProjects().size() == 0) {
return unwrapUnnestConfigurationExpression(project.getInput()).withDiscard();
}
}
if (rel instanceof Filter) {
Filter filter = (Filter) rel;
UnnestConfiguration conf = unwrapUnnestConfigurationExpression(filter.getInput());

View File

@ -30,11 +30,10 @@ LogicalProject(arrayString=[CAST(ARRAY('a':VARCHAR, 'b':VARCHAR)):VARCHAR ARRAY]
LogicalProject(arrayStringNulls=[$0], uln=[$2], udn=[$3])
LogicalFilter(condition=[OR(=($2, 1), =($3, 2.2))])
LogicalUnnest(unnestExpr=[$1])
LogicalProject(arrayStringNulls=[$0], arrayDoubleNulls=[$2], uln=[$3])
LogicalUnnest(unnestExpr=[$1])
LogicalProject(arrayStringNulls=[$2], arrayLongNulls=[$4], arrayDoubleNulls=[$6])
LogicalFilter(condition=[=($1, CAST(ARRAY('a', 'b')):VARCHAR ARRAY NOT NULL)])
LogicalTableScan(table=[[druid, arrays]])
LogicalProject(arrayStringNulls=[$2], arrayDoubleNulls=[$6], uln=[$12])
LogicalUnnest(unnestExpr=[$4])
LogicalFilter(condition=[=($1, CAST(ARRAY('a', 'b')):VARCHAR ARRAY NOT NULL)])
LogicalTableScan(table=[[druid, arrays]])
!logicalPlan
DruidProject(arrayString=[CAST(ARRAY('a':VARCHAR, 'b':VARCHAR)):VARCHAR ARRAY], uln=[$1], udn=[$2], usn=[$3], druid=[logical])
@ -42,11 +41,10 @@ DruidProject(arrayString=[CAST(ARRAY('a':VARCHAR, 'b':VARCHAR)):VARCHAR ARRAY],
DruidProject(arrayStringNulls=[$0], uln=[$2], udn=[$3], druid=[logical])
DruidFilter(condition=[OR(=($2, 1), =($3, 2.2))])
DruidUnnest(unnestExpr=[$1])
DruidProject(arrayStringNulls=[$0], arrayDoubleNulls=[$2], uln=[$3], druid=[logical])
DruidUnnest(unnestExpr=[$1])
DruidProject(arrayStringNulls=[$2], arrayLongNulls=[$4], arrayDoubleNulls=[$6], druid=[logical])
DruidFilter(condition=[=($1, CAST(ARRAY('a', 'b')):VARCHAR ARRAY NOT NULL)])
DruidTableScan(table=[[druid, arrays]], druid=[logical])
DruidProject(arrayStringNulls=[$2], arrayDoubleNulls=[$6], uln=[$12], druid=[logical])
DruidUnnest(unnestExpr=[$4])
DruidFilter(condition=[=($1, CAST(ARRAY('a', 'b')):VARCHAR ARRAY NOT NULL)])
DruidTableScan(table=[[druid, arrays]], druid=[logical])
!druidPlan
{

View File

@ -18,16 +18,14 @@ SELECT uln, COUNT(*) FROM druid.arrays, UNNEST(arrayLongNulls) AS unnested(uln)
(1 row)
!ok
LogicalAggregate(group=[{1}], EXPR$1=[COUNT()])
LogicalUnnest(unnestExpr=[$0], filter=[=($0, 1)])
LogicalProject(arrayLongNulls=[$4])
LogicalTableScan(table=[[druid, arrays]])
LogicalAggregate(group=[{12}], EXPR$1=[COUNT()])
LogicalUnnest(unnestExpr=[$4], filter=[=($0, 1)])
LogicalTableScan(table=[[druid, arrays]])
!logicalPlan
DruidAggregate(group=[{1}], EXPR$1=[COUNT()], druid=[logical])
DruidUnnest(unnestExpr=[$0], filter=[=($0, 1)])
DruidProject(arrayLongNulls=[$4], druid=[logical])
DruidTableScan(table=[[druid, arrays]], druid=[logical])
DruidAggregate(group=[{12}], EXPR$1=[COUNT()], druid=[logical])
DruidUnnest(unnestExpr=[$4], filter=[=($0, 1)])
DruidTableScan(table=[[druid, arrays]], druid=[logical])
!druidPlan
{