1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Remove add_missing_from GUC and associated parser support for "implicit RTEs".

Per recent discussion, add_missing_from has been deprecated for long enough to
consider removing, and it's getting in the way of planned parser refactoring.
The system now always behaves as though add_missing_from were OFF.
This commit is contained in:
Tom Lane
2009-10-21 20:22:38 +00:00
parent e1c96527c7
commit 289e2905c8
17 changed files with 57 additions and 204 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.244 2009/10/08 02:39:23 tgl Exp $
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.245 2009/10/21 20:22:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -500,14 +500,13 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
name2 = strVal(field2);
/* Try to identify as a once-qualified column */
node = qualifiedNameToVar(pstate, NULL, name1, name2, true,
node = qualifiedNameToVar(pstate, NULL, name1, name2,
cref->location);
if (node == NULL)
{
/*
* Not known as a column of any range-table entry, so try
* it as a function call. Here, we will create an
* implicit RTE for tables not already entered.
* it as a function call.
*/
node = transformWholeRowRef(pstate, NULL, name1,
cref->location);
@ -545,7 +544,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
name3 = strVal(field3);
/* Try to identify as a twice-qualified column */
node = qualifiedNameToVar(pstate, name1, name2, name3, true,
node = qualifiedNameToVar(pstate, name1, name2, name3,
cref->location);
if (node == NULL)
{
@ -600,7 +599,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
name4 = strVal(field4);
/* Try to identify as a twice-qualified column */
node = qualifiedNameToVar(pstate, name2, name3, name4, true,
node = qualifiedNameToVar(pstate, name2, name3, name4,
cref->location);
if (node == NULL)
{
@ -1906,14 +1905,14 @@ transformWholeRowRef(ParseState *pstate, char *schemaname, char *relname,
int sublevels_up;
Oid toid;
/* Look up the referenced RTE, creating it if needed */
/* Look up the referenced RTE, failing if not present */
rte = refnameRangeTblEntry(pstate, schemaname, relname, location,
&sublevels_up);
if (rte == NULL)
rte = addImplicitRTE(pstate,
makeRangeVar(schemaname, relname, location));
errorMissingRTE(pstate,
makeRangeVar(schemaname, relname, location));
vnum = RTERangeTablePosn(pstate, rte, &sublevels_up);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.143 2009/07/16 06:33:43 petere Exp $
* $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.144 2009/10/21 20:22:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -32,9 +32,6 @@
#include "utils/syscache.h"
/* GUC parameter */
bool add_missing_from;
static RangeTblEntry *scanNameSpaceForRefname(ParseState *pstate,
const char *refname, int location);
static RangeTblEntry *scanNameSpaceForRelid(ParseState *pstate, Oid relid,
@ -51,7 +48,6 @@ static void expandTupleDesc(TupleDesc tupdesc, Alias *eref,
int location, bool include_dropped,
List **colnames, List **colvars);
static int specialAttNum(const char *attname);
static void warnAutoRange(ParseState *pstate, RangeVar *relation);
/*
@ -249,7 +245,7 @@ isFutureCTE(ParseState *pstate, const char *refname)
* visible in the p_relnamespace lists. This behavior is invalid per the SQL
* spec, and it may give ambiguous results (there might be multiple equally
* valid matches, but only one will be returned). This must be used ONLY
* as a heuristic in giving suitable error messages. See warnAutoRange.
* as a heuristic in giving suitable error messages. See errorMissingRTE.
*
* Notice that we consider both matches on actual relation (or CTE) name
* and matches on alias.
@ -573,7 +569,6 @@ qualifiedNameToVar(ParseState *pstate,
char *schemaname,
char *refname,
char *colname,
bool implicitRTEOK,
int location)
{
RangeTblEntry *rte;
@ -581,14 +576,8 @@ qualifiedNameToVar(ParseState *pstate,
rte = refnameRangeTblEntry(pstate, schemaname, refname, location,
&sublevels_up);
if (rte == NULL)
{
if (!implicitRTEOK)
return NULL;
rte = addImplicitRTE(pstate,
makeRangeVar(schemaname, refname, location));
}
return NULL;
return scanRTEForColumn(pstate, rte, colname, location);
}
@ -1527,42 +1516,6 @@ addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte,
pstate->p_varnamespace = lappend(pstate->p_varnamespace, rte);
}
/*
* Add a POSTQUEL-style implicit RTE.
*
* We assume caller has already checked that there is no RTE or join with
* a conflicting name.
*/
RangeTblEntry *
addImplicitRTE(ParseState *pstate, RangeVar *relation)
{
CommonTableExpr *cte = NULL;
Index levelsup = 0;
RangeTblEntry *rte;
/* issue warning or error as needed */
warnAutoRange(pstate, relation);
/* if it is an unqualified name, it might be a CTE reference */
if (!relation->schemaname)
cte = scanNameSpaceForCTE(pstate, relation->relname, &levelsup);
/*
* Note that we set inFromCl true, so that the RTE will be listed
* explicitly if the parsetree is ever decompiled by ruleutils.c. This
* provides a migration path for views/rules that were originally written
* with implicit-RTE syntax.
*/
if (cte)
rte = addRangeTableEntryForCTE(pstate, cte, levelsup, NULL, true);
else
rte = addRangeTableEntry(pstate, relation, NULL, false, true);
/* Add to joinlist and relnamespace, but not varnamespace */
addRTEtoQuery(pstate, rte, true, true, false);
return rte;
}
/*
* expandRTE -- expand the columns of a rangetable entry
*
@ -2417,13 +2370,13 @@ attnumTypeId(Relation rd, int attid)
}
/*
* Generate a warning or error about an implicit RTE, if appropriate.
* Generate a suitable error about a missing RTE.
*
* If ADD_MISSING_FROM is not enabled, raise an error. Otherwise, emit
* a warning.
* Since this is a very common type of error, we work rather hard to
* produce a helpful message.
*/
static void
warnAutoRange(ParseState *pstate, RangeVar *relation)
void
errorMissingRTE(ParseState *pstate, RangeVar *relation)
{
RangeTblEntry *rte;
int sublevels_up;
@ -2431,7 +2384,7 @@ warnAutoRange(ParseState *pstate, RangeVar *relation)
/*
* Check to see if there are any potential matches in the query's
* rangetable. This affects the message we provide.
* rangetable.
*/
rte = searchRangeTable(pstate, relation);
@ -2452,39 +2405,21 @@ warnAutoRange(ParseState *pstate, RangeVar *relation)
&sublevels_up) == rte)
badAlias = rte->eref->aliasname;
if (!add_missing_from)
{
if (rte)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_TABLE),
errmsg("invalid reference to FROM-clause entry for table \"%s\"",
relation->relname),
(badAlias ?
errhint("Perhaps you meant to reference the table alias \"%s\".",
badAlias) :
errhint("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.",
rte->eref->aliasname)),
parser_errposition(pstate, relation->location)));
else
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_TABLE),
errmsg("missing FROM-clause entry for table \"%s\"",
relation->relname),
parser_errposition(pstate, relation->location)));
}
else
{
/* just issue a warning */
ereport(NOTICE,
if (rte)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_TABLE),
errmsg("adding missing FROM-clause entry for table \"%s\"",
errmsg("invalid reference to FROM-clause entry for table \"%s\"",
relation->relname),
(badAlias ?
errhint("Perhaps you meant to reference the table alias \"%s\".",
badAlias) :
(rte ?
errhint("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.",
rte->eref->aliasname) : 0)),
errhint("Perhaps you meant to reference the table alias \"%s\".",
badAlias) :
errhint("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.",
rte->eref->aliasname)),
parser_errposition(pstate, relation->location)));
else
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_TABLE),
errmsg("missing FROM-clause entry for table \"%s\"",
relation->relname),
parser_errposition(pstate, relation->location)));
}
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.172 2009/07/16 06:33:43 petere Exp $
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.173 2009/10/21 20:22:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -927,9 +927,8 @@ ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref,
rte = refnameRangeTblEntry(pstate, schemaname, relname, cref->location,
&sublevels_up);
if (rte == NULL)
rte = addImplicitRTE(pstate,
makeRangeVar(schemaname, relname,
cref->location));
errorMissingRTE(pstate,
makeRangeVar(schemaname, relname, cref->location));
rtindex = RTERangeTablePosn(pstate, rte, &sublevels_up);
@ -973,8 +972,7 @@ ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref,
*
* 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, implicit RTEs,
* etc.
* input tables of aliasless JOINs, NEW/OLD pseudo-entries, etc.
*
* The referenced relations/columns are marked as requiring SELECT access.
*/

View File

@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.521 2009/10/13 14:18:40 alvherre Exp $
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.522 2009/10/21 20:22:38 tgl Exp $
*
*--------------------------------------------------------------------
*/
@ -45,7 +45,6 @@
#include "optimizer/paths.h"
#include "optimizer/planmain.h"
#include "parser/parse_expr.h"
#include "parser/parse_relation.h"
#include "parser/parse_type.h"
#include "parser/parser.h"
#include "parser/scansup.h"
@ -1057,14 +1056,6 @@ static struct config_bool ConfigureNamesBool[] =
&XactReadOnly,
false, assign_transaction_read_only, NULL
},
{
{"add_missing_from", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
gettext_noop("Automatically adds missing table references to FROM clauses."),
NULL
},
&add_missing_from,
false, NULL, NULL
},
{
{"check_function_bodies", PGC_USERSET, CLIENT_CONN_STATEMENT,
gettext_noop("Check function bodies during CREATE FUNCTION."),

View File

@ -484,7 +484,6 @@
# - Previous PostgreSQL Versions -
#add_missing_from = off
#array_nulls = on
#backslash_quote = safe_encoding # on, off, or safe_encoding
#default_with_oids = off

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/parser/parse_node.h,v 1.63 2009/09/09 03:32:52 tgl Exp $
* $PostgreSQL: pgsql/src/include/parser/parse_node.h,v 1.64 2009/10/21 20:22:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -50,9 +50,8 @@
* This is different from p_relnamespace because a JOIN without an alias does
* not hide the contained tables (so they must still be in p_relnamespace)
* but it does hide their columns (unqualified references to the columns must
* refer to the JOIN, not the member tables). Also, we put POSTQUEL-style
* implicit RTEs into p_relnamespace but not p_varnamespace, so that they
* do not affect the set of columns available for unqualified references.
* refer to the JOIN, not the member tables). Other special RTEs such as
* NEW/OLD for rules may also appear in just one of these lists.
*
* p_ctenamespace: list of CommonTableExprs (WITH items) that are visible
* at the moment. This is different from p_relnamespace because you have

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/parser/parse_relation.h,v 1.64 2009/06/11 14:49:11 momjian Exp $
* $PostgreSQL: pgsql/src/include/parser/parse_relation.h,v 1.65 2009/10/21 20:22:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -16,8 +16,6 @@
#include "parser/parse_node.h"
extern bool add_missing_from;
extern RangeTblEntry *refnameRangeTblEntry(ParseState *pstate,
const char *schemaname,
const char *refname,
@ -44,7 +42,6 @@ extern Node *qualifiedNameToVar(ParseState *pstate,
char *schemaname,
char *refname,
char *colname,
bool implicitRTEOK,
int location);
extern void markVarForSelectPriv(ParseState *pstate, Var *var,
RangeTblEntry *rte);
@ -87,7 +84,7 @@ extern RangeTblEntry *addRangeTableEntryForCTE(ParseState *pstate,
extern void addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte,
bool addToJoinList,
bool addToRelNameSpace, bool addToVarNameSpace);
extern RangeTblEntry *addImplicitRTE(ParseState *pstate, RangeVar *relation);
extern void errorMissingRTE(ParseState *pstate, RangeVar *relation);
extern void expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
int location, bool include_dropped,
List **colnames, List **colvars);

View File

@ -11,14 +11,11 @@ INSERT INTO delete_test (a) VALUES (100);
DELETE FROM delete_test AS dt WHERE dt.a > 75;
-- if an alias is specified, don't allow the original table name
-- to be referenced
BEGIN;
SET LOCAL add_missing_from = false;
DELETE FROM delete_test dt WHERE delete_test.a > 25;
ERROR: invalid reference to FROM-clause entry for table "delete_test"
LINE 1: DELETE FROM delete_test dt WHERE delete_test.a > 25;
^
HINT: Perhaps you meant to reference the table alias "dt".
ROLLBACK;
SELECT * FROM delete_test;
id | a
----+----

View File

@ -63,13 +63,10 @@ select * from quadtable;
2 | ("(,4.4)","(5.5,6.6)")
(2 rows)
begin;
set local add_missing_from = false;
select f1, q.c1 from quadtable; -- fails, q is a table reference
ERROR: missing FROM-clause entry for table "q"
LINE 1: select f1, q.c1 from quadtable;
^
rollback;
select f1, (q).c1, (qq.q).c1.i from quadtable qq;
f1 | c1 | i
----+-----------+-----

View File

@ -82,12 +82,9 @@ LINE 1: UPDATE update_test SET (a,b) = (select a,b FROM update_test ...
^
-- if an alias for the target table is specified, don't allow references
-- to the original table name
BEGIN;
SET LOCAL add_missing_from = false;
UPDATE update_test AS t SET b = update_test.b + 10 WHERE t.a = 10;
ERROR: invalid reference to FROM-clause entry for table "update_test"
LINE 1: UPDATE update_test AS t SET b = update_test.b + 10 WHERE t.a...
^
HINT: Perhaps you meant to reference the table alias "t".
ROLLBACK;
DROP TABLE update_test;

View File

@ -12,11 +12,8 @@ DELETE FROM delete_test AS dt WHERE dt.a > 75;
-- if an alias is specified, don't allow the original table name
-- to be referenced
BEGIN;
SET LOCAL add_missing_from = false;
DELETE FROM delete_test dt WHERE delete_test.a > 25;
ROLLBACK;
SELECT * FROM delete_test;
DROP TABLE delete_test;
DROP TABLE delete_test;

View File

@ -35,10 +35,7 @@ insert into quadtable values (2, ((null,4.4),(5.5,6.6)));
select * from quadtable;
begin;
set local add_missing_from = false;
select f1, q.c1 from quadtable; -- fails, q is a table reference
rollback;
select f1, (q).c1, (qq.q).c1.i from quadtable qq;

View File

@ -52,9 +52,6 @@ UPDATE update_test SET (a,b) = (select a,b FROM update_test where c = 'foo')
-- if an alias for the target table is specified, don't allow references
-- to the original table name
BEGIN;
SET LOCAL add_missing_from = false;
UPDATE update_test AS t SET b = update_test.b + 10 WHERE t.a = 10;
ROLLBACK;
DROP TABLE update_test;