Description
This is a sub-issue of #10632 to narrow down a specific problem.
Say you have a query of the form:
SELECT * FROM (SELECT a+2, b*3 FROM foo) AS bar(x,y) WHERE x = y
and we want to propagate x=y
to the data source SELECT b+2, a*3 FROM foo
.
In the initial query the WHERE predicate is an expression expressed as ComparisonExpr{Eq, @1, @2}
(using the @ syntax for indexed vars introduced in #10729). In this context the Indexedvars refer to positions in the outer select's data source, which is opaque at that level. The only thing the outer select knows is that its data source returns two columns, and thus the references @1 and @2 are valid.
Based on the interface described in #10632, the pushPredicateDown
method is called on the inner selectNode, with the aforementioned filter expression ComparisonExpr{Eq, @1, @2}
. Within the context of the inner select, the indexedvars in this predicate now refer to the two rendered expressions b+2
and a*3
.
So first thing the pushPredicateDown
method must translate the predicate to refer to the inner select's data sources. That is it needs to translate @1=@2
to b+2=a*3
(which in turn will be encoded as @2+2 = @1*3
, now referring to the inner select's own data source).
This is the issue being described here: implement the substitution of indexedvars incoming from the outer context in selectNode.pushPredicateDown
by the render expressions that already exist in the current selectNode.
The resulting expressions must be normalized (simplified) after the substitution, before further recursing with pushPredicateDown
as indicated in #10632.