Skip to content

Commit 289e290

Browse files
committed
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.
1 parent e1c9652 commit 289e290

File tree

17 files changed

+57
-204
lines changed

17 files changed

+57
-204
lines changed

doc/src/sgml/config.sgml

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.230 2009/10/03 23:10:47 momjian Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.231 2009/10/21 20:22:38 tgl Exp $ -->
22

33
<chapter Id="runtime-config">
44
<title>Server Configuration</title>
@@ -4659,37 +4659,6 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
46594659

46604660
<variablelist>
46614661

4662-
<varlistentry id="guc-add-missing-from" xreflabel="add_missing_from">
4663-
<term><varname>add_missing_from</varname> (<type>boolean</type>)</term>
4664-
<indexterm><primary>FROM</><secondary>missing</></>
4665-
<indexterm>
4666-
<primary><varname>add_missing_from</> configuration parameter</primary>
4667-
</indexterm>
4668-
<listitem>
4669-
<para>
4670-
When on, tables that are referenced by a query will be
4671-
automatically added to the <literal>FROM</> clause if not
4672-
already present. This behavior does not comply with the SQL
4673-
standard and many people dislike it because it can mask mistakes
4674-
(such as referencing a table where you should have referenced
4675-
its alias). The default is <literal>off</>. This variable can be
4676-
enabled for compatibility with releases of
4677-
<productname>PostgreSQL</> prior to 8.1, where this behavior was
4678-
allowed by default.
4679-
</para>
4680-
4681-
<para>
4682-
Note that even when this variable is enabled, a warning
4683-
message will be emitted for each implicit <literal>FROM</>
4684-
entry referenced by a query. Users are encouraged to update
4685-
their applications to not rely on this behavior, by adding all
4686-
tables referenced by a query to the query's <literal>FROM</>
4687-
clause (or its <literal>USING</> clause in the case of
4688-
<command>DELETE</>).
4689-
</para>
4690-
</listitem>
4691-
</varlistentry>
4692-
46934662
<varlistentry id="guc-array-nulls" xreflabel="array_nulls">
46944663
<term><varname>array_nulls</varname> (<type>boolean</type>)</term>
46954664
<indexterm>

doc/src/sgml/queries.sgml

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/queries.sgml,v 1.55 2009/06/17 21:58:49 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/queries.sgml,v 1.56 2009/10/21 20:22:38 tgl Exp $ -->
22

33
<chapter id="queries">
44
<title>Queries</title>
@@ -521,23 +521,13 @@ SELECT * FROM some_very_long_table_name s JOIN another_fairly_long_name a ON s.i
521521
</para>
522522

523523
<para>
524-
The alias becomes the new name of the table reference for the
525-
current query &mdash; it is no longer possible to refer to the table
526-
by the original name. Thus:
524+
The alias becomes the new name of the table reference so far as the
525+
current query is concerned &mdash; it is not allowed to refer to the
526+
table by the original name elsewhere in the query. Thus, this is not
527+
valid:
527528
<programlisting>
528-
SELECT * FROM my_table AS m WHERE my_table.a &gt; 5;
529+
SELECT * FROM my_table AS m WHERE my_table.a &gt; 5; -- wrong
529530
</programlisting>
530-
is not valid according to the SQL standard. In
531-
<productname>PostgreSQL</productname> this will draw an error, assuming the
532-
<xref linkend="guc-add-missing-from"> configuration variable is
533-
<literal>off</> (as it is by default). If it is <literal>on</>,
534-
an implicit table reference will be added to the
535-
<literal>FROM</literal> clause, so the query is processed as if
536-
it were written as:
537-
<programlisting>
538-
SELECT * FROM my_table AS m, my_table AS my_table WHERE my_table.a &gt; 5;
539-
</programlisting>
540-
That will result in a cross join, which is usually not what you want.
541531
</para>
542532

543533
<para>

doc/src/sgml/ref/select.sgml

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/ref/select.sgml,v 1.125 2009/09/18 05:00:42 petere Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/select.sgml,v 1.126 2009/10/21 20:22:38 tgl Exp $
33
PostgreSQL documentation
44
-->
55

@@ -1451,12 +1451,7 @@ SELECT distributors.* WHERE distributors.name = 'Westward';
14511451
<productname>PostgreSQL</productname> releases prior to
14521452
8.1 would accept queries of this form, and add an implicit entry
14531453
to the query's <literal>FROM</literal> clause for each table
1454-
referenced by the query. This is no longer the default behavior,
1455-
because it does not comply with the SQL standard, and is
1456-
considered by many to be error-prone. For compatibility with
1457-
applications that rely on this behavior the <xref
1458-
linkend="guc-add-missing-from"> configuration variable can be
1459-
enabled.
1454+
referenced by the query. This is no longer allowed.
14601455
</para>
14611456
</refsect2>
14621457

doc/src/sgml/ref/show.sgml

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/ref/show.sgml,v 1.47 2008/11/14 10:22:47 petere Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/show.sgml,v 1.48 2009/10/21 20:22:38 tgl Exp $
33
PostgreSQL documentation
44
-->
55

@@ -168,16 +168,15 @@ SHOW geqo;
168168
Show all settings:
169169
<programlisting>
170170
SHOW ALL;
171-
name | setting | description
172-
--------------------------------+--------------------------------+----------------------------------------------------------------------------------------------
173-
add_missing_from | off | Automatically adds missing table references to FROM clauses.
174-
allow_system_table_mods | off | Allows modifications of the structure of system tables.
171+
name | setting | description
172+
---------------------------------+-------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------
173+
allow_system_table_mods | off | Allows modifications of the structure of system tables.
175174
.
176175
.
177176
.
178-
work_mem | 1024 | Sets the maximum memory to be used for query workspaces.
179-
zero_damaged_pages | off | Continues processing past damaged page headers.
180-
(146 rows)
177+
xmloption | content | Sets whether XML data in implicit parsing and serialization operations is to be considered as documents or content fragments.
178+
zero_damaged_pages | off | Continues processing past damaged page headers.
179+
(196 rows)
181180
</programlisting>
182181
</para>
183182
</refsect1>

src/backend/parser/parse_expr.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.244 2009/10/08 02:39:23 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.245 2009/10/21 20:22:38 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -500,14 +500,13 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
500500
name2 = strVal(field2);
501501

502502
/* Try to identify as a once-qualified column */
503-
node = qualifiedNameToVar(pstate, NULL, name1, name2, true,
503+
node = qualifiedNameToVar(pstate, NULL, name1, name2,
504504
cref->location);
505505
if (node == NULL)
506506
{
507507
/*
508508
* Not known as a column of any range-table entry, so try
509-
* it as a function call. Here, we will create an
510-
* implicit RTE for tables not already entered.
509+
* it as a function call.
511510
*/
512511
node = transformWholeRowRef(pstate, NULL, name1,
513512
cref->location);
@@ -545,7 +544,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
545544
name3 = strVal(field3);
546545

547546
/* Try to identify as a twice-qualified column */
548-
node = qualifiedNameToVar(pstate, name1, name2, name3, true,
547+
node = qualifiedNameToVar(pstate, name1, name2, name3,
549548
cref->location);
550549
if (node == NULL)
551550
{
@@ -600,7 +599,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
600599
name4 = strVal(field4);
601600

602601
/* Try to identify as a twice-qualified column */
603-
node = qualifiedNameToVar(pstate, name2, name3, name4, true,
602+
node = qualifiedNameToVar(pstate, name2, name3, name4,
604603
cref->location);
605604
if (node == NULL)
606605
{
@@ -1906,14 +1905,14 @@ transformWholeRowRef(ParseState *pstate, char *schemaname, char *relname,
19061905
int sublevels_up;
19071906
Oid toid;
19081907

1909-
/* Look up the referenced RTE, creating it if needed */
1908+
/* Look up the referenced RTE, failing if not present */
19101909

19111910
rte = refnameRangeTblEntry(pstate, schemaname, relname, location,
19121911
&sublevels_up);
19131912

19141913
if (rte == NULL)
1915-
rte = addImplicitRTE(pstate,
1916-
makeRangeVar(schemaname, relname, location));
1914+
errorMissingRTE(pstate,
1915+
makeRangeVar(schemaname, relname, location));
19171916

19181917
vnum = RTERangeTablePosn(pstate, rte, &sublevels_up);
19191918

src/backend/parser/parse_relation.c

Lines changed: 22 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.143 2009/07/16 06:33:43 petere Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.144 2009/10/21 20:22:38 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -32,9 +32,6 @@
3232
#include "utils/syscache.h"
3333

3434

35-
/* GUC parameter */
36-
bool add_missing_from;
37-
3835
static RangeTblEntry *scanNameSpaceForRefname(ParseState *pstate,
3936
const char *refname, int location);
4037
static RangeTblEntry *scanNameSpaceForRelid(ParseState *pstate, Oid relid,
@@ -51,7 +48,6 @@ static void expandTupleDesc(TupleDesc tupdesc, Alias *eref,
5148
int location, bool include_dropped,
5249
List **colnames, List **colvars);
5350
static int specialAttNum(const char *attname);
54-
static void warnAutoRange(ParseState *pstate, RangeVar *relation);
5551

5652

5753
/*
@@ -249,7 +245,7 @@ isFutureCTE(ParseState *pstate, const char *refname)
249245
* visible in the p_relnamespace lists. This behavior is invalid per the SQL
250246
* spec, and it may give ambiguous results (there might be multiple equally
251247
* valid matches, but only one will be returned). This must be used ONLY
252-
* as a heuristic in giving suitable error messages. See warnAutoRange.
248+
* as a heuristic in giving suitable error messages. See errorMissingRTE.
253249
*
254250
* Notice that we consider both matches on actual relation (or CTE) name
255251
* and matches on alias.
@@ -573,22 +569,15 @@ qualifiedNameToVar(ParseState *pstate,
573569
char *schemaname,
574570
char *refname,
575571
char *colname,
576-
bool implicitRTEOK,
577572
int location)
578573
{
579574
RangeTblEntry *rte;
580575
int sublevels_up;
581576

582577
rte = refnameRangeTblEntry(pstate, schemaname, refname, location,
583578
&sublevels_up);
584-
585579
if (rte == NULL)
586-
{
587-
if (!implicitRTEOK)
588-
return NULL;
589-
rte = addImplicitRTE(pstate,
590-
makeRangeVar(schemaname, refname, location));
591-
}
580+
return NULL;
592581

593582
return scanRTEForColumn(pstate, rte, colname, location);
594583
}
@@ -1527,42 +1516,6 @@ addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte,
15271516
pstate->p_varnamespace = lappend(pstate->p_varnamespace, rte);
15281517
}
15291518

1530-
/*
1531-
* Add a POSTQUEL-style implicit RTE.
1532-
*
1533-
* We assume caller has already checked that there is no RTE or join with
1534-
* a conflicting name.
1535-
*/
1536-
RangeTblEntry *
1537-
addImplicitRTE(ParseState *pstate, RangeVar *relation)
1538-
{
1539-
CommonTableExpr *cte = NULL;
1540-
Index levelsup = 0;
1541-
RangeTblEntry *rte;
1542-
1543-
/* issue warning or error as needed */
1544-
warnAutoRange(pstate, relation);
1545-
1546-
/* if it is an unqualified name, it might be a CTE reference */
1547-
if (!relation->schemaname)
1548-
cte = scanNameSpaceForCTE(pstate, relation->relname, &levelsup);
1549-
1550-
/*
1551-
* Note that we set inFromCl true, so that the RTE will be listed
1552-
* explicitly if the parsetree is ever decompiled by ruleutils.c. This
1553-
* provides a migration path for views/rules that were originally written
1554-
* with implicit-RTE syntax.
1555-
*/
1556-
if (cte)
1557-
rte = addRangeTableEntryForCTE(pstate, cte, levelsup, NULL, true);
1558-
else
1559-
rte = addRangeTableEntry(pstate, relation, NULL, false, true);
1560-
/* Add to joinlist and relnamespace, but not varnamespace */
1561-
addRTEtoQuery(pstate, rte, true, true, false);
1562-
1563-
return rte;
1564-
}
1565-
15661519
/*
15671520
* expandRTE -- expand the columns of a rangetable entry
15681521
*
@@ -2417,21 +2370,21 @@ attnumTypeId(Relation rd, int attid)
24172370
}
24182371

24192372
/*
2420-
* Generate a warning or error about an implicit RTE, if appropriate.
2373+
* Generate a suitable error about a missing RTE.
24212374
*
2422-
* If ADD_MISSING_FROM is not enabled, raise an error. Otherwise, emit
2423-
* a warning.
2375+
* Since this is a very common type of error, we work rather hard to
2376+
* produce a helpful message.
24242377
*/
2425-
static void
2426-
warnAutoRange(ParseState *pstate, RangeVar *relation)
2378+
void
2379+
errorMissingRTE(ParseState *pstate, RangeVar *relation)
24272380
{
24282381
RangeTblEntry *rte;
24292382
int sublevels_up;
24302383
const char *badAlias = NULL;
24312384

24322385
/*
24332386
* Check to see if there are any potential matches in the query's
2434-
* rangetable. This affects the message we provide.
2387+
* rangetable.
24352388
*/
24362389
rte = searchRangeTable(pstate, relation);
24372390

@@ -2452,39 +2405,21 @@ warnAutoRange(ParseState *pstate, RangeVar *relation)
24522405
&sublevels_up) == rte)
24532406
badAlias = rte->eref->aliasname;
24542407

2455-
if (!add_missing_from)
2456-
{
2457-
if (rte)
2458-
ereport(ERROR,
2459-
(errcode(ERRCODE_UNDEFINED_TABLE),
2460-
errmsg("invalid reference to FROM-clause entry for table \"%s\"",
2461-
relation->relname),
2462-
(badAlias ?
2463-
errhint("Perhaps you meant to reference the table alias \"%s\".",
2464-
badAlias) :
2465-
errhint("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.",
2466-
rte->eref->aliasname)),
2467-
parser_errposition(pstate, relation->location)));
2468-
else
2469-
ereport(ERROR,
2470-
(errcode(ERRCODE_UNDEFINED_TABLE),
2471-
errmsg("missing FROM-clause entry for table \"%s\"",
2472-
relation->relname),
2473-
parser_errposition(pstate, relation->location)));
2474-
}
2475-
else
2476-
{
2477-
/* just issue a warning */
2478-
ereport(NOTICE,
2408+
if (rte)
2409+
ereport(ERROR,
24792410
(errcode(ERRCODE_UNDEFINED_TABLE),
2480-
errmsg("adding missing FROM-clause entry for table \"%s\"",
2411+
errmsg("invalid reference to FROM-clause entry for table \"%s\"",
24812412
relation->relname),
24822413
(badAlias ?
2483-
errhint("Perhaps you meant to reference the table alias \"%s\".",
2484-
badAlias) :
2485-
(rte ?
2486-
errhint("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.",
2487-
rte->eref->aliasname) : 0)),
2414+
errhint("Perhaps you meant to reference the table alias \"%s\".",
2415+
badAlias) :
2416+
errhint("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.",
2417+
rte->eref->aliasname)),
2418+
parser_errposition(pstate, relation->location)));
2419+
else
2420+
ereport(ERROR,
2421+
(errcode(ERRCODE_UNDEFINED_TABLE),
2422+
errmsg("missing FROM-clause entry for table \"%s\"",
2423+
relation->relname),
24882424
parser_errposition(pstate, relation->location)));
2489-
}
24902425
}

0 commit comments

Comments
 (0)