Hi, Alena!

On Sat, Mar 29, 2025 at 9:03 PM Alena Rybakina
<a.rybak...@postgrespro.ru> wrote:
> On 29.03.2025 14:03, Alexander Korotkov wrote:
>> One thing I have to fix: we must do
>> IncrementVarSublevelsUp() unconditionally for all expressions as Vars
>> could be deeper inside.
>
> Yes, I'm looking at it too, I've just understood that it was needed for 
> subqueries - they can contain var elements which needs decrease the sublevel 
> parameter.
>
> for example for the query:
>
> EXPLAIN (COSTS OFF)
> SELECT ten FROM onek t
> WHERE unique1 IN (VALUES (0), ((2 IN (SELECT unique2 FROM onek c
>   WHERE c.unique2 = t.unique1))::integer));
>
> We are interested in this element: ((2 IN (SELECT unique2 FROM onek c  WHERE 
> c.unique2 = t.unique1))
>
> It is funcexpr object with RabgeTblEntry variable. I highlighted
>
> WARNING:  1{FUNCEXPR :funcid 2558 :funcresulttype 23 :funcretset false 
> :funcvariadic false :funcformat 1 :funccollid 0 :inputcollid 0 :args 
> ({SUBLINK :subLinkType 2 :subLinkId 0 :testexpr {OPEXPR :opno 96 :opfuncid 65 
> :opresulttype 16 :opretset false :opcollid 0 :inputcollid 0 :args ({CONST 
> :consttype 23 :consttypmod -1 :constcollid 0 :constlen 4 :constbyval true 
> :constisnull false :location -1 :constvalue 4 [ 2 0 0 0 0 0 0 0 ]} {PARAM 
> :paramkind 2 :paramid 1 :paramtype 23 :paramtypmod -1 :paramcollid 0 
> :location -1}) :location -1} :operName ("=") :subselect {QUERY :commandType 1 
> :querySource 0 :canSetTag true :utilityStmt <> :resultRelation 0 :hasAggs 
> false :hasWindowFuncs false :hasTargetSRFs false :hasSubLinks false 
> :hasDistinctOn false :hasRecursive false :hasModifyingCTE false :hasForUpdate 
> false :hasRowSecurity false :hasGroupRTE false :isReturn false :cteList <> 
> :rtable ({RANGETBLENTRY :alias {ALIAS :aliasname c :colnames <>} :eref {ALIAS 
> :aliasname c :colnames ("unique1" "unique2" "two" "four" "ten" "twenty" 
> "hundred" "thousand" "twothousand" "fivethous" "tenthous" "odd" "even" 
> "stringu1" "stringu2" "string4")} :rtekind 0 :relid 32795 :inh true :relkind 
> r :rellockmode 1 :perminfoindex 1 :tablesample <> :lateral false :inFromCl 
> true :securityQuals <>}) :rteperminfos ({RTEPERMISSIONINFO :relid 32795 :inh 
> true :requiredPerms 2 :checkAsUser 0 :selectedCols (b 9) :insertedCols (b) 
> :updatedCols (b)}) :jointree {FROMEXPR :fromlist ({RANGETBLREF :rtindex 1}) 
> :quals {OPEXPR :opno 96 :opfuncid 65 :opresulttype 16 :opretset false 
> :opcollid 0 :inputcollid 0 :args ({VAR :varno 1 :varattno 2 :vartype 23 
> :vartypmod -1 :varcollid 0 :varnullingrels (b) :varlevelsup 0 
> :varreturningtype 0 :varnosyn 1 :varattnosyn 2 :location -1} {VAR :varno 1 
> :varattno 1 :vartype 23 :vartypmod -1 :varcollid 0 :varnullingrels (b) 
> :varlevelsup 2 :varreturningtype 0 :varnosyn 1 :varattnosyn 1 :location -1}) 
> :location -1}} :mergeActionList <> :mergeTargetRelation 0 :mergeJoinCondition 
> <> :targetList ({TARGETENTRY :expr {VAR :varno 1 :varattno 2 :vartype 23 
> :vartypmod -1 :varcollid 0 :varnullingrels (b) :varlevelsup 0 
> :varreturningtype 0 :varnosyn 1 :varattnosyn 2 :location -1} :resno 1 
> :resname unique2 :ressortgroupref 0 :resorigtbl 32795 :resorigcol 2 :resjunk 
> false}) :override 0 :onConflict <> :returningOldAlias <> :returningNewAlias 
> <> :returningList <> :groupClause <> :groupDistinct false :groupingSets <> 
> :havingQual <> :windowClause <> :distinctClause <> :sortClause <> 
> :limitOffset <> :limitCount <> :limitOption 0 :rowMarks <> :setOperations <> 
> :constraintDeps <> :withCheckOptions <> :stmt_location -1 :stmt_len -1} 
> :location -1}) :location -1}
>
>
> I highlighted in bold the var we need - since it is in a subquery in the in 
> expression will be flattened, all elements contained in it should decrease 
> the level number by one, since they will belong to the subtree located above 
> it. Because of that condition, this did not happen.
>
> I generally agree with you that it is better to remove that condition. The 
> function IncrementVarSublevelsUp essentially goes through the structures 
> below and will decrease the level of only the vars for which this needs to be 
> done, and the condition with 1 will protect us from touching those vars that 
> should not. So the varlevelsup for this var should be 1.
>
> I am currently investigating whether this transformation will be fair for all 
> cases; I have not found any problems yet.

Thank you for your feedback.  I appreciate you're also looking for the
potential problems.  On thing to highlight: doing
IncrementVarSublevelsUp() unconditionally is required not just for
subqueries.  Consider the following example.

SELECT * FROM t WHERE val1 IN (VALUES (val2), (val2 +1));

The second value contain Var, which needs IncrementVarSublevelsUp(),
but the top node is OpExpr.

------
Regards,
Alexander Korotkov
Supabase


Reply via email to