diff options
Diffstat (limited to 'src/backend/parser/parse_relation.c')
-rw-r--r-- | src/backend/parser/parse_relation.c | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index b490541f03d..52b4a6e89df 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -763,6 +763,9 @@ scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem, } var->location = location; + /* Mark Var if it's nulled by any outer joins */ + markNullableIfNeeded(pstate, var); + /* Require read access to the column */ markVarForSelectPriv(pstate, var); @@ -1024,6 +1027,35 @@ searchRangeTableForCol(ParseState *pstate, const char *alias, const char *colnam } /* + * markNullableIfNeeded + * If the RTE referenced by the Var is nullable by outer join(s) + * at this point in the query, set var->varnullingrels to show that. + */ +void +markNullableIfNeeded(ParseState *pstate, Var *var) +{ + int rtindex = var->varno; + Bitmapset *relids; + + /* Find the appropriate pstate */ + for (int lv = 0; lv < var->varlevelsup; lv++) + pstate = pstate->parentParseState; + + /* Find currently-relevant join relids for the Var's rel */ + if (rtindex > 0 && rtindex <= list_length(pstate->p_nullingrels)) + relids = (Bitmapset *) list_nth(pstate->p_nullingrels, rtindex - 1); + else + relids = NULL; + + /* + * Merge with any already-declared nulling rels. (Typically there won't + * be any, but let's get it right if there are.) + */ + if (relids != NULL) + var->varnullingrels = bms_union(var->varnullingrels, relids); +} + +/* * markRTEForSelectPriv * Mark the specified column of the RTE with index rtindex * as requiring SELECT privilege @@ -3087,7 +3119,7 @@ expandTupleDesc(TupleDesc tupdesc, Alias *eref, int count, int offset, * the list elements mustn't be modified. */ List * -expandNSItemVars(ParseNamespaceItem *nsitem, +expandNSItemVars(ParseState *pstate, ParseNamespaceItem *nsitem, int sublevels_up, int location, List **colnames) { @@ -3123,6 +3155,10 @@ expandNSItemVars(ParseNamespaceItem *nsitem, var->varnosyn = nscol->p_varnosyn; var->varattnosyn = nscol->p_varattnosyn; var->location = location; + + /* ... and update varnullingrels */ + markNullableIfNeeded(pstate, var); + result = lappend(result, var); if (colnames) *colnames = lappend(*colnames, colnameval); @@ -3158,7 +3194,7 @@ expandNSItemAttrs(ParseState *pstate, ParseNamespaceItem *nsitem, *var; List *te_list = NIL; - vars = expandNSItemVars(nsitem, sublevels_up, location, &names); + vars = expandNSItemVars(pstate, nsitem, sublevels_up, location, &names); /* * Require read access to the table. This is normally redundant with the |