[fix](planner) conjuncts of the outer query block didn't work when it's on the results expr of inline view (#17036)
Here is a cases: select id, name from (select '123' as id, '1234' as name, age from test_insert ) a where name != '1234';
This commit is contained in:
@ -1206,7 +1206,8 @@ public class Analyzer {
|
||||
}
|
||||
}
|
||||
|
||||
public void registerMigrateFailedConjuncts(InlineViewRef ref, Expr e) {
|
||||
public void registerMigrateFailedConjuncts(InlineViewRef ref, Expr e) throws AnalysisException {
|
||||
markConstantConjunct(e, false);
|
||||
Set<Expr> exprSet = globalState.migrateFailedConjuncts.computeIfAbsent(ref, (k) -> new HashSet<>());
|
||||
exprSet.add(e);
|
||||
}
|
||||
@ -1371,7 +1372,8 @@ public class Analyzer {
|
||||
&& !e.isAuxExpr()
|
||||
&& !globalState.assignedConjuncts.contains(e.getId())
|
||||
&& ((inclOjConjuncts && !e.isConstant())
|
||||
|| !globalState.ojClauseByConjunct.containsKey(e.getId()))) {
|
||||
|| (!globalState.ojClauseByConjunct.containsKey(e.getId())
|
||||
&& !globalState.sjClauseByConjunct.containsKey(e.getId())))) {
|
||||
result.add(e);
|
||||
}
|
||||
}
|
||||
@ -1848,7 +1850,8 @@ public class Analyzer {
|
||||
// aliases and having it analyzed is needed for the following EvalPredicate() call
|
||||
conjunct.analyze(this);
|
||||
}
|
||||
final Expr newConjunct = conjunct.getResultValue();
|
||||
Expr newConjunct = conjunct.getResultValue(true);
|
||||
newConjunct = FoldConstantsRule.INSTANCE.apply(newConjunct, this, null);
|
||||
if (newConjunct instanceof BoolLiteral || newConjunct instanceof NullLiteral) {
|
||||
boolean evalResult = true;
|
||||
if (newConjunct instanceof BoolLiteral) {
|
||||
@ -2414,7 +2417,7 @@ public class Analyzer {
|
||||
|
||||
if (tids.size() > 1 || globalState.ojClauseByConjunct.containsKey(e.getId())
|
||||
|| globalState.outerJoinedTupleIds.containsKey(e.getId()) && whereClauseConjuncts.contains(e.getId())
|
||||
|| globalState.conjunctsByOjClause.containsKey(e.getId())) {
|
||||
|| globalState.conjunctsByOjClause.containsKey(e.getId())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -675,8 +675,8 @@ public class BinaryPredicate extends Predicate implements Writable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expr getResultValue() throws AnalysisException {
|
||||
recursiveResetChildrenResult();
|
||||
public Expr getResultValue(boolean inView) throws AnalysisException {
|
||||
recursiveResetChildrenResult(inView);
|
||||
final Expr leftChildValue = getChild(0);
|
||||
final Expr rightChildValue = getChild(1);
|
||||
if (!(leftChildValue instanceof LiteralExpr)
|
||||
|
||||
@ -412,8 +412,8 @@ public class CastExpr extends Expr {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expr getResultValue() throws AnalysisException {
|
||||
recursiveResetChildrenResult();
|
||||
public Expr getResultValue(boolean inView) throws AnalysisException {
|
||||
recursiveResetChildrenResult(inView);
|
||||
final Expr value = children.get(0);
|
||||
if (!(value instanceof LiteralExpr)) {
|
||||
return this;
|
||||
|
||||
@ -230,8 +230,8 @@ public class CompoundPredicate extends Predicate {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expr getResultValue() throws AnalysisException {
|
||||
recursiveResetChildrenResult();
|
||||
public Expr getResultValue(boolean inView) throws AnalysisException {
|
||||
recursiveResetChildrenResult(inView);
|
||||
boolean compoundResult = false;
|
||||
if (op == Operator.NOT) {
|
||||
final Expr childValue = getChild(0);
|
||||
|
||||
@ -1945,10 +1945,10 @@ public abstract class Expr extends TreeNode<Expr> implements ParseNode, Cloneabl
|
||||
}
|
||||
|
||||
|
||||
protected void recursiveResetChildrenResult() throws AnalysisException {
|
||||
protected void recursiveResetChildrenResult(boolean inView) throws AnalysisException {
|
||||
for (int i = 0; i < children.size(); i++) {
|
||||
final Expr child = children.get(i);
|
||||
final Expr newChild = child.getResultValue();
|
||||
final Expr newChild = child.getResultValue(inView);
|
||||
if (newChild != child) {
|
||||
setChild(i, newChild);
|
||||
}
|
||||
@ -1960,8 +1960,8 @@ public abstract class Expr extends TreeNode<Expr> implements ParseNode, Cloneabl
|
||||
* @return value returned can't be null, if this and it's children are't constant expr, return this.
|
||||
* @throws AnalysisException
|
||||
*/
|
||||
public Expr getResultValue() throws AnalysisException {
|
||||
recursiveResetChildrenResult();
|
||||
public Expr getResultValue(boolean forPushDownPredicatesToView) throws AnalysisException {
|
||||
recursiveResetChildrenResult(forPushDownPredicatesToView);
|
||||
final Expr newExpr = ExpressionFunctions.INSTANCE.evalExpr(this);
|
||||
return newExpr != null ? newExpr : this;
|
||||
}
|
||||
|
||||
@ -1409,7 +1409,7 @@ public class FunctionCallExpr extends Expr {
|
||||
* Return type is DATETIME
|
||||
*/
|
||||
if (fn.getFunctionName().getFunction().equals("str_to_date")) {
|
||||
Expr child1Result = getChild(1).getResultValue();
|
||||
Expr child1Result = getChild(1).getResultValue(false);
|
||||
if (child1Result instanceof StringLiteral) {
|
||||
if (DateLiteral.hasTimePart(child1Result.getStringValue())) {
|
||||
this.type = Type.DATETIME;
|
||||
|
||||
@ -291,8 +291,8 @@ public class InPredicate extends Predicate {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expr getResultValue() throws AnalysisException {
|
||||
recursiveResetChildrenResult();
|
||||
public Expr getResultValue(boolean inView) throws AnalysisException {
|
||||
recursiveResetChildrenResult(inView);
|
||||
final Expr leftChildValue = getChild(0);
|
||||
if (!(leftChildValue instanceof LiteralExpr) || !isLiteralChildren()) {
|
||||
return this;
|
||||
|
||||
@ -154,8 +154,8 @@ public class IsNullPredicate extends Predicate {
|
||||
* fix issue 6390
|
||||
*/
|
||||
@Override
|
||||
public Expr getResultValue() throws AnalysisException {
|
||||
recursiveResetChildrenResult();
|
||||
public Expr getResultValue(boolean inView) throws AnalysisException {
|
||||
recursiveResetChildrenResult(inView);
|
||||
final Expr childValue = getChild(0);
|
||||
if (!(childValue instanceof LiteralExpr)) {
|
||||
return this;
|
||||
|
||||
@ -109,7 +109,7 @@ public class SetVar {
|
||||
throw new AnalysisException("Set statement does't support non-constant expr.");
|
||||
}
|
||||
|
||||
final Expr literalExpr = value.getResultValue();
|
||||
final Expr literalExpr = value.getResultValue(false);
|
||||
if (!(literalExpr instanceof LiteralExpr)) {
|
||||
throw new AnalysisException("Set statement does't support computing expr:" + literalExpr.toSql());
|
||||
}
|
||||
|
||||
@ -576,4 +576,26 @@ public class SlotRef extends Expr {
|
||||
}
|
||||
return !CreateMaterializedViewStmt.isMVColumn(name) && exprs.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expr getResultValue(boolean foldSlot) throws AnalysisException {
|
||||
if (!foldSlot) {
|
||||
return this;
|
||||
}
|
||||
if (!isConstant() || desc == null) {
|
||||
return this;
|
||||
}
|
||||
List<Expr> exprs = desc.getSourceExprs();
|
||||
if (CollectionUtils.isEmpty(exprs)) {
|
||||
return this;
|
||||
}
|
||||
Expr expr = exprs.get(0);
|
||||
if (expr instanceof SlotRef) {
|
||||
return expr.getResultValue(foldSlot);
|
||||
}
|
||||
if (expr.isConstant()) {
|
||||
return expr;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,7 +116,7 @@ public class SysVariableDesc extends Expr {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expr getResultValue() throws AnalysisException {
|
||||
public Expr getResultValue(boolean inView) throws AnalysisException {
|
||||
if (!Strings.isNullOrEmpty(name) && VariableVarConverters.hasConverter(name)) {
|
||||
// Return the string type here so that it can correctly match the subsequent function signature.
|
||||
// And we also set `beConverted` to session variable name in StringLiteral, so that it can be cast back
|
||||
@ -129,7 +129,7 @@ public class SysVariableDesc extends Expr {
|
||||
throw new AnalysisException(e.getMessage());
|
||||
}
|
||||
}
|
||||
return super.getResultValue();
|
||||
return super.getResultValue(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -40,6 +40,9 @@ import java.util.List;
|
||||
public class SelectNode extends PlanNode {
|
||||
private static final Logger LOG = LogManager.getLogger(SelectNode.class);
|
||||
|
||||
/**
|
||||
* Used by nereids only.
|
||||
*/
|
||||
public SelectNode(PlanNodeId id, PlanNode child) {
|
||||
super(id, child.getTupleIds(), "SELECT", StatisticalType.SELECT_NODE);
|
||||
addChild(child);
|
||||
|
||||
@ -122,7 +122,7 @@ public class FoldConstantsRule implements ExprRewriteRule {
|
||||
return expr;
|
||||
}
|
||||
}
|
||||
return expr.getResultValue();
|
||||
return expr.getResultValue(false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
-- This file is automatically generated. You should know what you did if you want to edit this
|
||||
-- !sql --
|
||||
|
||||
-- !sql1 --
|
||||
|
||||
|
||||
@ -85,4 +85,35 @@ suite("literal_view_test") {
|
||||
FROM test_v
|
||||
WHERE substring('2022-12',6,2)='01';
|
||||
"""
|
||||
|
||||
sql """DROP TABLE IF EXISTS `test_insert`"""
|
||||
|
||||
sql """
|
||||
CREATE TABLE `test_insert` (
|
||||
`id` varchar(11) NULL COMMENT '唯一标识',
|
||||
`name` varchar(10) NULL COMMENT '采集时间',
|
||||
`age` int(11) NULL
|
||||
) ENGINE=OLAP
|
||||
UNIQUE KEY(`id`)
|
||||
COMMENT 'test'
|
||||
DISTRIBUTED BY HASH(`id`) BUCKETS 10
|
||||
PROPERTIES (
|
||||
"replication_allocation" = "tag.location.default: 1"
|
||||
);
|
||||
"""
|
||||
|
||||
sql """
|
||||
insert into test_insert values (1,'doris',10),(2,'spark',2),(3,'flink',20);
|
||||
"""
|
||||
|
||||
qt_sql1 """
|
||||
select id, name
|
||||
from (
|
||||
select '123' as id,
|
||||
'1234' as name,
|
||||
age
|
||||
from test_insert
|
||||
) a
|
||||
where name != '1234';
|
||||
"""
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user