aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_relation.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2013-07-23 16:23:01 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2013-07-23 16:23:45 -0400
commita7cd853b75d01666135ca87353cee83b99d06b9b (patch)
tree04e1610ac70c4d368982694b733073f7e46a2340 /src/backend/parser/parse_relation.c
parentc359a1b0823f798fc419adea5da7991845c915aa (diff)
downloadpostgresql-a7cd853b75d01666135ca87353cee83b99d06b9b.tar.gz
postgresql-a7cd853b75d01666135ca87353cee83b99d06b9b.zip
Change post-rewriter representation of dropped columns in joinaliasvars.
It's possible to drop a column from an input table of a JOIN clause in a view, if that column is nowhere actually referenced in the view. But it will still be there in the JOIN clause's joinaliasvars list. We used to replace such entries with NULL Const nodes, which is handy for generation of RowExpr expansion of a whole-row reference to the view. The trouble with that is that it can't be distinguished from the situation after subquery pull-up of a constant subquery output expression below the JOIN. Instead, replace such joinaliasvars with null pointers (empty expression trees), which can't be confused with pulled-up expressions. expandRTE() still emits the old convention, though, for convenience of RowExpr generation and to reduce the risk of breaking extension code. In HEAD and 9.3, this patch also fixes a problem with some new code in ruleutils.c that was failing to cope with implicitly-casted joinaliasvars entries, as per recent report from Feike Steenbergen. That oversight was because of an inadequate description of the data structure in parsenodes.h, which I've now corrected. There were some pre-existing oversights of the same ilk elsewhere, which I believe are now all fixed.
Diffstat (limited to 'src/backend/parser/parse_relation.c')
-rw-r--r--src/backend/parser/parse_relation.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index a9254c8c3a2..42de89f5101 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -24,6 +24,7 @@
#include "funcapi.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
+#include "optimizer/clauses.h"
#include "parser/parsetree.h"
#include "parser/parse_relation.h"
#include "parser/parse_type.h"
@@ -749,14 +750,15 @@ markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte,
* The aliasvar could be either a Var or a COALESCE expression,
* but in the latter case we should already have marked the two
* referent variables as being selected, due to their use in the
- * JOIN clause. So we need only be concerned with the simple Var
- * case.
+ * JOIN clause. So we need only be concerned with the Var case.
+ * But we do need to drill down through implicit coercions.
*/
Var *aliasvar;
Assert(col > 0 && col <= list_length(rte->joinaliasvars));
aliasvar = (Var *) list_nth(rte->joinaliasvars, col - 1);
- if (IsA(aliasvar, Var))
+ aliasvar = (Var *) strip_implicit_coercions((Node *) aliasvar);
+ if (aliasvar && IsA(aliasvar, Var))
markVarForSelectPriv(pstate, aliasvar, NULL);
}
}
@@ -1841,10 +1843,10 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
* deleted columns in the join; but we have to check since
* this routine is also used by the rewriter, and joins
* found in stored rules might have join columns for
- * since-deleted columns. This will be signaled by a NULL
- * Const in the alias-vars list.
+ * since-deleted columns. This will be signaled by a null
+ * pointer in the alias-vars list.
*/
- if (IsA(avar, Const))
+ if (avar == NULL)
{
if (include_dropped)
{
@@ -1852,8 +1854,16 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
*colnames = lappend(*colnames,
makeString(pstrdup("")));
if (colvars)
+ {
+ /*
+ * Can't use join's column type here (it might
+ * be dropped!); but it doesn't really matter
+ * what type the Const claims to be.
+ */
*colvars = lappend(*colvars,
- copyObject(avar));
+ makeNullConst(INT4OID, -1,
+ InvalidOid));
+ }
}
continue;
}
@@ -2242,6 +2252,7 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars));
aliasvar = (Node *) list_nth(rte->joinaliasvars, attnum - 1);
+ Assert(aliasvar != NULL);
*vartype = exprType(aliasvar);
*vartypmod = exprTypmod(aliasvar);
*varcollid = exprCollation(aliasvar);
@@ -2304,7 +2315,7 @@ get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
* but one in a stored rule might contain columns that were
* dropped from the underlying tables, if said columns are
* nowhere explicitly referenced in the rule. This will be
- * signaled to us by a NULL Const in the joinaliasvars list.
+ * signaled to us by a null pointer in the joinaliasvars list.
*/
Var *aliasvar;
@@ -2313,7 +2324,7 @@ get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
elog(ERROR, "invalid varattno %d", attnum);
aliasvar = (Var *) list_nth(rte->joinaliasvars, attnum - 1);
- result = IsA(aliasvar, Const);
+ result = (aliasvar == NULL);
}
break;
case RTE_FUNCTION: