diff options
Diffstat (limited to 'src/backend/parser/parse_target.c')
-rw-r--r-- | src/backend/parser/parse_target.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index 4d9e6e61066..ccd97fc845d 100644 --- a/src/backend/parser/parse_target.c +++ b/src/backend/parser/parse_target.c @@ -1108,9 +1108,10 @@ ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref, * ExpandAllTables() * Transforms '*' (in the target list) into a list of targetlist entries. * - * tlist entries are generated for each relation appearing in the query's - * varnamespace. We do not consider relnamespace because that would include - * input tables of aliasless JOINs, NEW/OLD pseudo-entries, etc. + * tlist entries are generated for each relation visible for unqualified + * column name access. We do not consider qualified-name-only entries because + * that would include input tables of aliasless JOINs, NEW/OLD pseudo-entries, + * etc. * * The referenced relations/columns are marked as requiring SELECT access. */ @@ -1118,29 +1119,42 @@ static List * ExpandAllTables(ParseState *pstate, int location) { List *target = NIL; + bool found_table = false; ListCell *l; - /* Check for SELECT *; */ - if (!pstate->p_varnamespace) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("SELECT * with no tables specified is not valid"), - parser_errposition(pstate, location))); - - foreach(l, pstate->p_varnamespace) + foreach(l, pstate->p_namespace) { ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l); RangeTblEntry *rte = nsitem->p_rte; - int rtindex = RTERangeTablePosn(pstate, rte, NULL); + /* Ignore table-only items */ + if (!nsitem->p_cols_visible) + continue; /* Should not have any lateral-only items when parsing targetlist */ Assert(!nsitem->p_lateral_only); + /* Remember we found a p_cols_visible item */ + found_table = true; target = list_concat(target, - expandRelAttrs(pstate, rte, rtindex, 0, + expandRelAttrs(pstate, + rte, + RTERangeTablePosn(pstate, rte, + NULL), + 0, location)); } + /* + * Check for "SELECT *;". We do it this way, rather than checking for + * target == NIL, because we want to allow SELECT * FROM a zero_column + * table. + */ + if (!found_table) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("SELECT * with no tables specified is not valid"), + parser_errposition(pstate, location))); + return target; } |