Commit 0daeba0e authored by Tom Lane's avatar Tom Lane

Be more paranoid in ruleutils.c's get_variable().

We were merely Assert'ing that the Var matched the RTE it's supposedly
from.  But if the user passes incorrect information to pg_get_expr(),
the RTE might in fact not match; this led either to Assert failures
or core dumps, as reported by Chris Hanks in bug #14220.  To fix, just
convert the Asserts to test-and-elog.  Adjust an existing test-and-elog
elsewhere in the same function to be consistent in wording.

(If we really felt these were user-facing errors, we might promote them to
ereport's; but I can't convince myself that they're worth translating.)

Back-patch to 9.3; the problematic code doesn't exist before that, and
a quick check says that 9.2 doesn't crash on such cases.

Michael Paquier and Thomas Munro

Report: <20160629224349.1407.32667@wrigleys.postgresql.org>
parent 86437ddf
...@@ -5967,7 +5967,8 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context) ...@@ -5967,7 +5967,8 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
tle = get_tle_by_resno(dpns->inner_tlist, var->varattno); tle = get_tle_by_resno(dpns->inner_tlist, var->varattno);
if (!tle) if (!tle)
elog(ERROR, "bogus varattno for subquery var: %d", var->varattno); elog(ERROR, "invalid attnum %d for relation \"%s\"",
var->varattno, rte->eref->aliasname);
Assert(netlevelsup == 0); Assert(netlevelsup == 0);
push_child_plan(dpns, dpns->inner_planstate, &save_dpns); push_child_plan(dpns, dpns->inner_planstate, &save_dpns);
...@@ -6028,9 +6029,13 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context) ...@@ -6028,9 +6029,13 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
else if (attnum > 0) else if (attnum > 0)
{ {
/* Get column name to use from the colinfo struct */ /* Get column name to use from the colinfo struct */
Assert(attnum <= colinfo->num_cols); if (attnum > colinfo->num_cols)
elog(ERROR, "invalid attnum %d for relation \"%s\"",
attnum, rte->eref->aliasname);
attname = colinfo->colnames[attnum - 1]; attname = colinfo->colnames[attnum - 1];
Assert(attname != NULL); if (attname == NULL) /* dropped column? */
elog(ERROR, "invalid attnum %d for relation \"%s\"",
attnum, rte->eref->aliasname);
} }
else else
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment