Skip to content

Commit

Permalink
[feat](nereids) support create view in nereids
Browse files Browse the repository at this point in the history
  • Loading branch information
feiniaofeiafei committed Apr 1, 2024
1 parent 4a941dd commit 2e40f0f
Show file tree
Hide file tree
Showing 42 changed files with 23 additions and 493 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,11 @@ public class LogicalProperties {
protected final Supplier<Map<Slot, Slot>> outputMapSupplier;
protected final Supplier<Set<ExprId>> outputExprIdSetSupplier;
protected final Supplier<FunctionalDependencies> fdSupplier;
protected final Supplier<List<NamedExpression>> outputExpressionSupplier;
private Integer hashCode = null;

public LogicalProperties(Supplier<List<Slot>> outputSupplier,
Supplier<FunctionalDependencies> fdSupplier, Supplier<List<NamedExpression>> outputExpressionSupplier) {
this(outputSupplier, fdSupplier, outputExpressionSupplier, ImmutableList::of);
}

public LogicalProperties(Supplier<List<Slot>> outputSupplier,
Supplier<FunctionalDependencies> fdSupplier) {
this(outputSupplier, fdSupplier, null, ImmutableList::of);
this(outputSupplier, fdSupplier, ImmutableList::of);
}

/**
Expand All @@ -64,7 +58,6 @@ public LogicalProperties(Supplier<List<Slot>> outputSupplier,
*/
public LogicalProperties(Supplier<List<Slot>> outputSupplier,
Supplier<FunctionalDependencies> fdSupplier,
Supplier<List<NamedExpression>> outputExpressionSupplier,
Supplier<List<Slot>> nonUserVisibleOutputSupplier) {
this.outputSupplier = Suppliers.memoize(
Objects.requireNonNull(outputSupplier, "outputSupplier can not be null")
Expand All @@ -87,8 +80,6 @@ public LogicalProperties(Supplier<List<Slot>> outputSupplier,
this.fdSupplier = Suppliers.memoize(
Objects.requireNonNull(fdSupplier, "FunctionalDependencies can not be null")
);
this.outputExpressionSupplier = Suppliers.memoize(Objects.requireNonNull(outputExpressionSupplier,
"outputExpressionSupplier can not be null"));
}

public List<Slot> getOutput() {
Expand All @@ -115,10 +106,6 @@ public List<Id> getOutputExprIds() {
return outputExprIdsSupplier.get();
}

public List<NamedExpression> getOutputExpression() {
return outputExpressionSupplier.get();
}

@Override
public String toString() {
return "LogicalProperties{"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import org.apache.doris.nereids.properties.UnboundLogicalProperties;
import org.apache.doris.nereids.trees.AbstractTreeNode;
import org.apache.doris.nereids.trees.expressions.ExprId;
import org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.expressions.StatementScopeIdGenerator;
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
Expand Down Expand Up @@ -156,11 +155,6 @@ public Set<ExprId> getOutputExprIdSet() {
return getLogicalProperties().getOutputExprIdSet();
}

@Override
public List<NamedExpression> getOutputExpression() {
return getLogicalProperties().getOutputExpression();
}

@Override
public LogicalProperties getLogicalProperties() {
// TODO: use bound()?
Expand All @@ -187,8 +181,7 @@ public LogicalProperties computeLogicalProperties() {
Supplier<FunctionalDependencies> fdSupplier = () -> this instanceof LogicalPlan
? ((LogicalPlan) this).computeFuncDeps(outputSupplier)
: FunctionalDependencies.EMPTY_FUNC_DEPS;
Supplier<List<NamedExpression>> outputExpressionSupplier = Suppliers.memoize(this::computeOutputExpression);
return new LogicalProperties(outputSupplier, fdSupplier, outputExpressionSupplier);
return new LogicalProperties(outputSupplier, fdSupplier);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import org.apache.doris.nereids.properties.FunctionalDependencies;
import org.apache.doris.nereids.properties.LogicalProperties;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
import org.apache.doris.nereids.util.MutableState;
Expand Down Expand Up @@ -92,11 +91,6 @@ public List<Slot> getOutput() {
return new ArrayList<>();
}

@Override
public List<NamedExpression> getOutputExpression() {
return new ArrayList<>();
}

@Override
public String treeString() {
return "DUMMY";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,6 @@ default boolean displayExtraPlanFirst() {
*/
List<Slot> getOutput();

List<NamedExpression> getOutputExpression();

/**
* Get output slot set of the plan.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public CreateViewCommand(CreateViewInfo createViewInfo) {

@Override
public void run(ConnectContext ctx, StmtExecutor executor) throws Exception {
createViewInfo.init(ctx);
createViewInfo.validate(ctx);
CreateViewStmt createViewStmt = createViewInfo.translateToLegacyStmt(ctx);
Env.getCurrentEnv().createView(createViewStmt);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@
import org.apache.doris.nereids.rules.analysis.BindRelationForCreateView;
import org.apache.doris.nereids.rules.analysis.CheckPolicy;
import org.apache.doris.nereids.rules.analysis.EliminateLogicalSelectHint;
import org.apache.doris.nereids.trees.expressions.Alias;
import org.apache.doris.nereids.trees.expressions.BoundStar;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.plans.Plan;
Expand All @@ -60,7 +58,6 @@
import org.apache.doris.nereids.trees.plans.logical.LogicalFileSink;
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
import org.apache.doris.nereids.trees.plans.logical.LogicalSetOperation;
import org.apache.doris.nereids.trees.plans.visitor.DefaultPlanVisitor;
import org.apache.doris.nereids.util.Utils;
import org.apache.doris.qe.ConnectContext;
Expand Down Expand Up @@ -90,9 +87,8 @@ public class CreateViewInfo {
private final List<SimpleColumnDefinition> simpleColumnDefinitions;
private final List<Column> finalCols = Lists.newArrayList();
private final List<Slot> outputs = Lists.newArrayList();
private final List<NamedExpression> projects = Lists.newArrayList();
private Plan analyzedPlan;
private Map<Pair<Integer, Integer>, String> relationMap;
private Map<Pair<Integer, Integer>, String> rewriteSqlMap;

/** constructor*/
public CreateViewInfo(boolean ifNotExists, TableNameInfo viewName, String comment, LogicalPlan logicalQuery,
Expand All @@ -108,6 +104,16 @@ public CreateViewInfo(boolean ifNotExists, TableNameInfo viewName, String commen
this.simpleColumnDefinitions = simpleColumnDefinitions;
}

/** init */
public void init(ConnectContext ctx) throws UserException {
analyzeAndFillRewriteSqlMap(querySql, ctx);
OutermostPlanFinder outermostPlanFinder = new OutermostPlanFinder();
AtomicReference<Plan> outermostPlan = new AtomicReference<>();
analyzedPlan.accept(outermostPlanFinder, outermostPlan);
outputs.addAll(outermostPlan.get().getOutput());
createFinalCols();
}

/**validate*/
public void validate(ConnectContext ctx) throws UserException {
NereidsPlanner planner = new NereidsPlanner(ctx.getStatementContext());
Expand All @@ -121,14 +127,6 @@ public void validate(ConnectContext ctx) throws UserException {
viewName.getTbl(), PrivPredicate.CREATE)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "CREATE");
}

analyzedPlan = parseAndAnalyzeView(querySql, ctx);
OutermostPlanFinder outermostPlanFinder = new OutermostPlanFinder();
AtomicReference<Plan> outermostPlan = new AtomicReference<>();
analyzedPlan.accept(outermostPlanFinder, outermostPlan);
outputs.addAll(outermostPlan.get().getOutput());
projects.addAll(outermostPlan.get().getOutputExpression());
createFinalCols();
Set<String> colSets = Sets.newTreeSet(String.CASE_INSENSITIVE_ORDER);
for (Column col : finalCols) {
if (!colSets.add(col.getName())) {
Expand All @@ -145,23 +143,20 @@ public CreateViewStmt translateToLegacyStmt(ConnectContext ctx) {
}
CreateViewStmt createViewStmt = new CreateViewStmt(ifNotExists, viewName.transferToTableName(), cols, comment,
null);
// expand star(*) in project list
Map<Pair<Integer, Integer>, String> indexStringSqlMap = collectBoundStar(analyzedPlan);
indexStringSqlMap.putAll(relationMap);
String rewrittenSql = rewriteStarToColumn(indexStringSqlMap);
// expand star(*) in project list and replace table name with qualifier
String rewrittenSql = rewriteSql(rewriteSqlMap);

// rewrite project alias
rewrittenSql = rewriteProjectsToUserDefineAlias2(rewrittenSql);
rewrittenSql = rewriteProjectsToUserDefineAlias(rewrittenSql);

createViewStmt.setInlineViewDef(rewrittenSql);
createViewStmt.setFinalColumns(finalCols);
return createViewStmt;
}

private Plan parseAndAnalyzeView(String ddlSql, ConnectContext ctx) {
private void analyzeAndFillRewriteSqlMap(String sql, ConnectContext ctx) {
StatementContext stmtCtx = ctx.getStatementContext();
LogicalPlan parsedViewPlan = new NereidsParser().parseSingle(ddlSql);
// TODO: use a good to do this, such as eliminate UnboundResultSink
LogicalPlan parsedViewPlan = new NereidsParser().parseSingle(sql);
if (parsedViewPlan instanceof UnboundResultSink) {
parsedViewPlan = (LogicalPlan) ((UnboundResultSink<?>) parsedViewPlan).child();
}
Expand All @@ -170,15 +165,16 @@ private Plan parseAndAnalyzeView(String ddlSql, ConnectContext ctx) {
AnalyzerForCreateView analyzer = new AnalyzerForCreateView(viewContext, true);
analyzer.analyze();
Plan planForRelation = viewContext.getRewritePlan();
relationMap = collectUnBoundRelation(planForRelation);
rewriteSqlMap = collectUnBoundRelation(planForRelation);
CascadesContext viewContextForStar = CascadesContext.initContext(
stmtCtx, planForRelation, PhysicalProperties.ANY);
AnalyzerForCreateView analyzerForStar = new AnalyzerForCreateView(viewContextForStar, false);
analyzerForStar.analyze();
return viewContextForStar.getRewritePlan();
analyzedPlan = viewContextForStar.getRewritePlan();
rewriteSqlMap.putAll(collectBoundStar(analyzedPlan));
}

private String rewriteStarToColumn(Map<Pair<Integer, Integer>, String> indexStringSqlMap) {
private String rewriteSql(Map<Pair<Integer, Integer>, String> indexStringSqlMap) {
StringBuilder builder = new StringBuilder();
int beg = 0;
for (Map.Entry<Pair<Integer, Integer>, String> entry : indexStringSqlMap.entrySet()) {
Expand All @@ -192,35 +188,6 @@ private String rewriteStarToColumn(Map<Pair<Integer, Integer>, String> indexStri
}

private String rewriteProjectsToUserDefineAlias(String resSql) {
List<Expression> projectExprs = Lists.newArrayList();
for (int i = 0; i < projects.size(); i++) {
NamedExpression namedExpression = projects.get(i);
if (namedExpression instanceof Alias) {
projectExprs.add(namedExpression.child(0));
} else {
projectExprs.add(namedExpression);
}
}
IndexFinder finder = new IndexFinder();
ParserRuleContext tree = NereidsParser.toAst(resSql, DorisParser::singleStatement);
finder.visit(tree);
StringBuilder replaceWithColsBuilder = new StringBuilder();
for (int i = 0; i < projectExprs.size(); ++i) {
replaceWithColsBuilder.append(projectExprs.get(i).toSql());
replaceWithColsBuilder.append(" AS `");
String escapeBacktick = finalCols.get(i).getName().replace("`", "``");
replaceWithColsBuilder.append(escapeBacktick);
replaceWithColsBuilder.append('`');
if (i != projectExprs.size() - 1) {
replaceWithColsBuilder.append(", ");
}
}
String replaceWithCols = replaceWithColsBuilder.toString();
return StringUtils.overlay(resSql, replaceWithCols, finder.getIndex().first,
finder.getIndex().second + 1);
}

private String rewriteProjectsToUserDefineAlias2(String resSql) {
IndexFinder finder = new IndexFinder();
ParserRuleContext tree = NereidsParser.toAst(resSql, DorisParser::singleStatement);
finder.visit(tree);
Expand Down Expand Up @@ -324,14 +291,6 @@ public Void visitLogicalCTEProducer(LogicalCTEProducer<? extends Plan> cteProduc
AtomicReference<Plan> target) {
return null;
}

@Override
public Void visitLogicalSetOperation(LogicalSetOperation setOperation, AtomicReference<Plan> target) {
if (found) {
return null;
}
return super.visit(setOperation, target);
}
}

/** traverse ast to find the outermost project list location information in sql*/
Expand Down Expand Up @@ -368,7 +327,6 @@ public Void visitSelectColumnClause(DorisParser.SelectColumnClauseContext ctx) {
stopIndex = ctx.getStop().getStopIndex();
found = true;

// 这里默认*已经被替换了,不存在*或者* except
NamedExpressionSeqContext namedExpressionSeqContext = ctx.namedExpressionSeq();
namedExpressionContexts = namedExpressionSeqContext.namedExpression();
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -390,9 +390,4 @@ public ImmutableSet<FdItem> computeFdItems(Supplier<List<Slot>> outputSupplier)

return builder.build();
}

@Override
public List<NamedExpression> computeOutputExpression() {
return outputExpressions;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.InSubquery;
import org.apache.doris.nereids.trees.expressions.MarkJoinSlotReference;
import org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.expressions.ScalarSubquery;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.expressions.SubqueryExpr;
Expand Down Expand Up @@ -162,17 +161,6 @@ public List<Slot> computeOutput() {
.build();
}

@Override
public List<NamedExpression> computeOutputExpression() {
return ImmutableList.<NamedExpression>builder()
.addAll(left().getOutputExpression())
.addAll(markJoinSlotReference.isPresent()
? ImmutableList.of(markJoinSlotReference.get()) : ImmutableList.of())
.addAll(needAddSubOutputToProjects
? ImmutableList.of(right().getOutputExpression().get(0)) : ImmutableList.of())
.build();
}

@Override
public String toString() {
return Utils.toSqlString("LogicalApply",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import org.apache.doris.nereids.properties.LogicalProperties;
import org.apache.doris.nereids.trees.expressions.AssertNumRowsElement;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.PlanType;
Expand Down Expand Up @@ -119,10 +118,4 @@ public Plan withGroupExprLogicalPropChildren(Optional<GroupExpression> groupExpr
public List<Slot> computeOutput() {
return child().getOutput().stream().map(o -> o.withNullable(true)).collect(Collectors.toList());
}

@Override
public List<NamedExpression> computeOutputExpression() {
return child().getOutputExpression();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import org.apache.doris.nereids.memo.GroupExpression;
import org.apache.doris.nereids.properties.LogicalProperties;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.PlanType;
Expand Down Expand Up @@ -71,11 +70,6 @@ public List<Slot> computeOutput() {
return child().getOutput();
}

@Override
public List<NamedExpression> computeOutputExpression() {
return child().getOutputExpression();
}

@Override
public String toString() {
return Utils.toSqlString("LogicalCTE",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import org.apache.doris.nereids.properties.LogicalProperties;
import org.apache.doris.nereids.trees.expressions.CTEId;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.PlanType;
Expand Down Expand Up @@ -84,11 +83,6 @@ public List<Slot> computeOutput() {
return right().getOutput();
}

@Override
public List<NamedExpression> computeOutputExpression() {
return right().getOutputExpression();
}

public CTEId getCteId() {
return cteId;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import org.apache.doris.nereids.memo.GroupExpression;
import org.apache.doris.nereids.properties.LogicalProperties;
import org.apache.doris.nereids.trees.expressions.CTEId;
import org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.expressions.SlotReference;
import org.apache.doris.nereids.trees.expressions.StatementScopeIdGenerator;
Expand Down Expand Up @@ -146,11 +145,6 @@ public List<Slot> computeOutput() {
return ImmutableList.copyOf(producerToConsumerOutputMap.values());
}

@Override
public List<NamedExpression> computeOutputExpression() {
return ImmutableList.copyOf(producerToConsumerOutputMap.values());
}

public CTEId getCteId() {
return cteId;
}
Expand Down
Loading

0 comments on commit 2e40f0f

Please sign in to comment.