Skip to content

Commit a381102

Browse files
committed
Fix crash when a special var points to another special var
When a var has a special varno (ie a negative varno), we need to resolve the actual underlying Var, as we would otherwise end up reading random memory when trying to access the associated RangeTblEntry. The previous code was correctly resolving such Var, but didn't consider the possibility that the resolved Var could itself have a special varno which needs to be resolved again. Thanks to Kenny Chen for the report.
1 parent e5e1f60 commit a381102

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

CONTRIBUTORS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@
1717
* github user RekGRpth
1818
* Zhihong Yu
1919
* github user romanstingler
20+
* Kenny Chen

pg_qualstats.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2391,6 +2391,17 @@ pgqs_resolve_var(Var *var, pgqsWalkerContext *context)
23912391
List *tlist = NULL;
23922392
PlanState *planstate = context->planstate;
23932393

2394+
/*
2395+
* This function can recurse, so this can prevent infinite loop in case of
2396+
* any problem.
2397+
*/
2398+
CHECK_FOR_INTERRUPTS();
2399+
2400+
#if PG_VERSION_NUM >= 140000
2401+
/* ROWID_VAR is only used during planning, so we shouldn't see it. */
2402+
Assert(var->varno != ROWID_VAR);
2403+
#endif
2404+
23942405
pgqs_set_planstates(context->planstate, context);
23952406
switch (var->varno)
23962407
{
@@ -2437,6 +2448,13 @@ pgqs_resolve_var(Var *var, pgqsWalkerContext *context)
24372448

24382449
pgqs_set_planstates(planstate, context);
24392450

2451+
/*
2452+
* If the resolved var is still a var with a special varno, we need to
2453+
* resolve it again.
2454+
*/
2455+
if (IsA(var, Var) && IS_SPECIAL_VARNO(var->varno))
2456+
return pgqs_resolve_var(var, context);
2457+
24402458
return (Expr *) var;
24412459
}
24422460

0 commit comments

Comments
 (0)