mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-30 14:52:30 +02: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:
parent
e1c96527c7
commit
289e2905c8
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.230 2009/10/03 23:10:47 momjian Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.231 2009/10/21 20:22:38 tgl Exp $ -->
|
||||||
|
|
||||||
<chapter Id="runtime-config">
|
<chapter Id="runtime-config">
|
||||||
<title>Server Configuration</title>
|
<title>Server Configuration</title>
|
||||||
@ -4659,37 +4659,6 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
|
|||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
|
|
||||||
<varlistentry id="guc-add-missing-from" xreflabel="add_missing_from">
|
|
||||||
<term><varname>add_missing_from</varname> (<type>boolean</type>)</term>
|
|
||||||
<indexterm><primary>FROM</><secondary>missing</></>
|
|
||||||
<indexterm>
|
|
||||||
<primary><varname>add_missing_from</> configuration parameter</primary>
|
|
||||||
</indexterm>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
When on, tables that are referenced by a query will be
|
|
||||||
automatically added to the <literal>FROM</> clause if not
|
|
||||||
already present. This behavior does not comply with the SQL
|
|
||||||
standard and many people dislike it because it can mask mistakes
|
|
||||||
(such as referencing a table where you should have referenced
|
|
||||||
its alias). The default is <literal>off</>. This variable can be
|
|
||||||
enabled for compatibility with releases of
|
|
||||||
<productname>PostgreSQL</> prior to 8.1, where this behavior was
|
|
||||||
allowed by default.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Note that even when this variable is enabled, a warning
|
|
||||||
message will be emitted for each implicit <literal>FROM</>
|
|
||||||
entry referenced by a query. Users are encouraged to update
|
|
||||||
their applications to not rely on this behavior, by adding all
|
|
||||||
tables referenced by a query to the query's <literal>FROM</>
|
|
||||||
clause (or its <literal>USING</> clause in the case of
|
|
||||||
<command>DELETE</>).
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry id="guc-array-nulls" xreflabel="array_nulls">
|
<varlistentry id="guc-array-nulls" xreflabel="array_nulls">
|
||||||
<term><varname>array_nulls</varname> (<type>boolean</type>)</term>
|
<term><varname>array_nulls</varname> (<type>boolean</type>)</term>
|
||||||
<indexterm>
|
<indexterm>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/queries.sgml,v 1.55 2009/06/17 21:58:49 tgl Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/queries.sgml,v 1.56 2009/10/21 20:22:38 tgl Exp $ -->
|
||||||
|
|
||||||
<chapter id="queries">
|
<chapter id="queries">
|
||||||
<title>Queries</title>
|
<title>Queries</title>
|
||||||
@ -521,23 +521,13 @@ SELECT * FROM some_very_long_table_name s JOIN another_fairly_long_name a ON s.i
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The alias becomes the new name of the table reference for the
|
The alias becomes the new name of the table reference so far as the
|
||||||
current query — it is no longer possible to refer to the table
|
current query is concerned — it is not allowed to refer to the
|
||||||
by the original name. Thus:
|
table by the original name elsewhere in the query. Thus, this is not
|
||||||
|
valid:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
SELECT * FROM my_table AS m WHERE my_table.a > 5;
|
SELECT * FROM my_table AS m WHERE my_table.a > 5; -- wrong
|
||||||
</programlisting>
|
</programlisting>
|
||||||
is not valid according to the SQL standard. In
|
|
||||||
<productname>PostgreSQL</productname> this will draw an error, assuming the
|
|
||||||
<xref linkend="guc-add-missing-from"> configuration variable is
|
|
||||||
<literal>off</> (as it is by default). If it is <literal>on</>,
|
|
||||||
an implicit table reference will be added to the
|
|
||||||
<literal>FROM</literal> clause, so the query is processed as if
|
|
||||||
it were written as:
|
|
||||||
<programlisting>
|
|
||||||
SELECT * FROM my_table AS m, my_table AS my_table WHERE my_table.a > 5;
|
|
||||||
</programlisting>
|
|
||||||
That will result in a cross join, which is usually not what you want.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/select.sgml,v 1.125 2009/09/18 05:00:42 petere Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/select.sgml,v 1.126 2009/10/21 20:22:38 tgl Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -1451,12 +1451,7 @@ SELECT distributors.* WHERE distributors.name = 'Westward';
|
|||||||
<productname>PostgreSQL</productname> releases prior to
|
<productname>PostgreSQL</productname> releases prior to
|
||||||
8.1 would accept queries of this form, and add an implicit entry
|
8.1 would accept queries of this form, and add an implicit entry
|
||||||
to the query's <literal>FROM</literal> clause for each table
|
to the query's <literal>FROM</literal> clause for each table
|
||||||
referenced by the query. This is no longer the default behavior,
|
referenced by the query. This is no longer allowed.
|
||||||
because it does not comply with the SQL standard, and is
|
|
||||||
considered by many to be error-prone. For compatibility with
|
|
||||||
applications that rely on this behavior the <xref
|
|
||||||
linkend="guc-add-missing-from"> configuration variable can be
|
|
||||||
enabled.
|
|
||||||
</para>
|
</para>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/show.sgml,v 1.47 2008/11/14 10:22:47 petere Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/show.sgml,v 1.48 2009/10/21 20:22:38 tgl Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -169,15 +169,14 @@ SHOW geqo;
|
|||||||
<programlisting>
|
<programlisting>
|
||||||
SHOW ALL;
|
SHOW ALL;
|
||||||
name | setting | description
|
name | setting | description
|
||||||
--------------------------------+--------------------------------+----------------------------------------------------------------------------------------------
|
---------------------------------+-------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------
|
||||||
add_missing_from | off | Automatically adds missing table references to FROM clauses.
|
|
||||||
allow_system_table_mods | off | Allows modifications of the structure of system tables.
|
allow_system_table_mods | off | Allows modifications of the structure of system tables.
|
||||||
.
|
.
|
||||||
.
|
.
|
||||||
.
|
.
|
||||||
work_mem | 1024 | Sets the maximum memory to be used for query workspaces.
|
xmloption | content | Sets whether XML data in implicit parsing and serialization operations is to be considered as documents or content fragments.
|
||||||
zero_damaged_pages | off | Continues processing past damaged page headers.
|
zero_damaged_pages | off | Continues processing past damaged page headers.
|
||||||
(146 rows)
|
(196 rows)
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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);
|
name2 = strVal(field2);
|
||||||
|
|
||||||
/* Try to identify as a once-qualified column */
|
/* Try to identify as a once-qualified column */
|
||||||
node = qualifiedNameToVar(pstate, NULL, name1, name2, true,
|
node = qualifiedNameToVar(pstate, NULL, name1, name2,
|
||||||
cref->location);
|
cref->location);
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Not known as a column of any range-table entry, so try
|
* Not known as a column of any range-table entry, so try
|
||||||
* it as a function call. Here, we will create an
|
* it as a function call.
|
||||||
* implicit RTE for tables not already entered.
|
|
||||||
*/
|
*/
|
||||||
node = transformWholeRowRef(pstate, NULL, name1,
|
node = transformWholeRowRef(pstate, NULL, name1,
|
||||||
cref->location);
|
cref->location);
|
||||||
@ -545,7 +544,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
|
|||||||
name3 = strVal(field3);
|
name3 = strVal(field3);
|
||||||
|
|
||||||
/* Try to identify as a twice-qualified column */
|
/* Try to identify as a twice-qualified column */
|
||||||
node = qualifiedNameToVar(pstate, name1, name2, name3, true,
|
node = qualifiedNameToVar(pstate, name1, name2, name3,
|
||||||
cref->location);
|
cref->location);
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
{
|
{
|
||||||
@ -600,7 +599,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
|
|||||||
name4 = strVal(field4);
|
name4 = strVal(field4);
|
||||||
|
|
||||||
/* Try to identify as a twice-qualified column */
|
/* Try to identify as a twice-qualified column */
|
||||||
node = qualifiedNameToVar(pstate, name2, name3, name4, true,
|
node = qualifiedNameToVar(pstate, name2, name3, name4,
|
||||||
cref->location);
|
cref->location);
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
{
|
{
|
||||||
@ -1906,13 +1905,13 @@ transformWholeRowRef(ParseState *pstate, char *schemaname, char *relname,
|
|||||||
int sublevels_up;
|
int sublevels_up;
|
||||||
Oid toid;
|
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,
|
rte = refnameRangeTblEntry(pstate, schemaname, relname, location,
|
||||||
&sublevels_up);
|
&sublevels_up);
|
||||||
|
|
||||||
if (rte == NULL)
|
if (rte == NULL)
|
||||||
rte = addImplicitRTE(pstate,
|
errorMissingRTE(pstate,
|
||||||
makeRangeVar(schemaname, relname, location));
|
makeRangeVar(schemaname, relname, location));
|
||||||
|
|
||||||
vnum = RTERangeTablePosn(pstate, rte, &sublevels_up);
|
vnum = RTERangeTablePosn(pstate, rte, &sublevels_up);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
|
||||||
/* GUC parameter */
|
|
||||||
bool add_missing_from;
|
|
||||||
|
|
||||||
static RangeTblEntry *scanNameSpaceForRefname(ParseState *pstate,
|
static RangeTblEntry *scanNameSpaceForRefname(ParseState *pstate,
|
||||||
const char *refname, int location);
|
const char *refname, int location);
|
||||||
static RangeTblEntry *scanNameSpaceForRelid(ParseState *pstate, Oid relid,
|
static RangeTblEntry *scanNameSpaceForRelid(ParseState *pstate, Oid relid,
|
||||||
@ -51,7 +48,6 @@ static void expandTupleDesc(TupleDesc tupdesc, Alias *eref,
|
|||||||
int location, bool include_dropped,
|
int location, bool include_dropped,
|
||||||
List **colnames, List **colvars);
|
List **colnames, List **colvars);
|
||||||
static int specialAttNum(const char *attname);
|
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
|
* 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
|
* 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
|
* 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
|
* Notice that we consider both matches on actual relation (or CTE) name
|
||||||
* and matches on alias.
|
* and matches on alias.
|
||||||
@ -573,7 +569,6 @@ qualifiedNameToVar(ParseState *pstate,
|
|||||||
char *schemaname,
|
char *schemaname,
|
||||||
char *refname,
|
char *refname,
|
||||||
char *colname,
|
char *colname,
|
||||||
bool implicitRTEOK,
|
|
||||||
int location)
|
int location)
|
||||||
{
|
{
|
||||||
RangeTblEntry *rte;
|
RangeTblEntry *rte;
|
||||||
@ -581,14 +576,8 @@ qualifiedNameToVar(ParseState *pstate,
|
|||||||
|
|
||||||
rte = refnameRangeTblEntry(pstate, schemaname, refname, location,
|
rte = refnameRangeTblEntry(pstate, schemaname, refname, location,
|
||||||
&sublevels_up);
|
&sublevels_up);
|
||||||
|
|
||||||
if (rte == NULL)
|
if (rte == NULL)
|
||||||
{
|
|
||||||
if (!implicitRTEOK)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
rte = addImplicitRTE(pstate,
|
|
||||||
makeRangeVar(schemaname, refname, location));
|
|
||||||
}
|
|
||||||
|
|
||||||
return scanRTEForColumn(pstate, rte, colname, location);
|
return scanRTEForColumn(pstate, rte, colname, location);
|
||||||
}
|
}
|
||||||
@ -1527,42 +1516,6 @@ addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte,
|
|||||||
pstate->p_varnamespace = lappend(pstate->p_varnamespace, 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
|
* 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
|
* Since this is a very common type of error, we work rather hard to
|
||||||
* a warning.
|
* produce a helpful message.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
warnAutoRange(ParseState *pstate, RangeVar *relation)
|
errorMissingRTE(ParseState *pstate, RangeVar *relation)
|
||||||
{
|
{
|
||||||
RangeTblEntry *rte;
|
RangeTblEntry *rte;
|
||||||
int sublevels_up;
|
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
|
* 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);
|
rte = searchRangeTable(pstate, relation);
|
||||||
|
|
||||||
@ -2452,8 +2405,6 @@ warnAutoRange(ParseState *pstate, RangeVar *relation)
|
|||||||
&sublevels_up) == rte)
|
&sublevels_up) == rte)
|
||||||
badAlias = rte->eref->aliasname;
|
badAlias = rte->eref->aliasname;
|
||||||
|
|
||||||
if (!add_missing_from)
|
|
||||||
{
|
|
||||||
if (rte)
|
if (rte)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_UNDEFINED_TABLE),
|
(errcode(ERRCODE_UNDEFINED_TABLE),
|
||||||
@ -2472,19 +2423,3 @@ warnAutoRange(ParseState *pstate, RangeVar *relation)
|
|||||||
relation->relname),
|
relation->relname),
|
||||||
parser_errposition(pstate, relation->location)));
|
parser_errposition(pstate, relation->location)));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
/* just issue a warning */
|
|
||||||
ereport(NOTICE,
|
|
||||||
(errcode(ERRCODE_UNDEFINED_TABLE),
|
|
||||||
errmsg("adding missing 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)),
|
|
||||||
parser_errposition(pstate, relation->location)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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,
|
rte = refnameRangeTblEntry(pstate, schemaname, relname, cref->location,
|
||||||
&sublevels_up);
|
&sublevels_up);
|
||||||
if (rte == NULL)
|
if (rte == NULL)
|
||||||
rte = addImplicitRTE(pstate,
|
errorMissingRTE(pstate,
|
||||||
makeRangeVar(schemaname, relname,
|
makeRangeVar(schemaname, relname, cref->location));
|
||||||
cref->location));
|
|
||||||
|
|
||||||
rtindex = RTERangeTablePosn(pstate, rte, &sublevels_up);
|
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
|
* tlist entries are generated for each relation appearing in the query's
|
||||||
* varnamespace. We do not consider relnamespace because that would include
|
* varnamespace. We do not consider relnamespace because that would include
|
||||||
* input tables of aliasless JOINs, NEW/OLD pseudo-entries, implicit RTEs,
|
* input tables of aliasless JOINs, NEW/OLD pseudo-entries, etc.
|
||||||
* etc.
|
|
||||||
*
|
*
|
||||||
* The referenced relations/columns are marked as requiring SELECT access.
|
* The referenced relations/columns are marked as requiring SELECT access.
|
||||||
*/
|
*/
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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/paths.h"
|
||||||
#include "optimizer/planmain.h"
|
#include "optimizer/planmain.h"
|
||||||
#include "parser/parse_expr.h"
|
#include "parser/parse_expr.h"
|
||||||
#include "parser/parse_relation.h"
|
|
||||||
#include "parser/parse_type.h"
|
#include "parser/parse_type.h"
|
||||||
#include "parser/parser.h"
|
#include "parser/parser.h"
|
||||||
#include "parser/scansup.h"
|
#include "parser/scansup.h"
|
||||||
@ -1057,14 +1056,6 @@ static struct config_bool ConfigureNamesBool[] =
|
|||||||
&XactReadOnly,
|
&XactReadOnly,
|
||||||
false, assign_transaction_read_only, NULL
|
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,
|
{"check_function_bodies", PGC_USERSET, CLIENT_CONN_STATEMENT,
|
||||||
gettext_noop("Check function bodies during CREATE FUNCTION."),
|
gettext_noop("Check function bodies during CREATE FUNCTION."),
|
||||||
|
@ -484,7 +484,6 @@
|
|||||||
|
|
||||||
# - Previous PostgreSQL Versions -
|
# - Previous PostgreSQL Versions -
|
||||||
|
|
||||||
#add_missing_from = off
|
|
||||||
#array_nulls = on
|
#array_nulls = on
|
||||||
#backslash_quote = safe_encoding # on, off, or safe_encoding
|
#backslash_quote = safe_encoding # on, off, or safe_encoding
|
||||||
#default_with_oids = off
|
#default_with_oids = off
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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
|
* 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)
|
* 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
|
* 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
|
* refer to the JOIN, not the member tables). Other special RTEs such as
|
||||||
* implicit RTEs into p_relnamespace but not p_varnamespace, so that they
|
* NEW/OLD for rules may also appear in just one of these lists.
|
||||||
* do not affect the set of columns available for unqualified references.
|
|
||||||
*
|
*
|
||||||
* p_ctenamespace: list of CommonTableExprs (WITH items) that are visible
|
* p_ctenamespace: list of CommonTableExprs (WITH items) that are visible
|
||||||
* at the moment. This is different from p_relnamespace because you have
|
* at the moment. This is different from p_relnamespace because you have
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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"
|
#include "parser/parse_node.h"
|
||||||
|
|
||||||
extern bool add_missing_from;
|
|
||||||
|
|
||||||
extern RangeTblEntry *refnameRangeTblEntry(ParseState *pstate,
|
extern RangeTblEntry *refnameRangeTblEntry(ParseState *pstate,
|
||||||
const char *schemaname,
|
const char *schemaname,
|
||||||
const char *refname,
|
const char *refname,
|
||||||
@ -44,7 +42,6 @@ extern Node *qualifiedNameToVar(ParseState *pstate,
|
|||||||
char *schemaname,
|
char *schemaname,
|
||||||
char *refname,
|
char *refname,
|
||||||
char *colname,
|
char *colname,
|
||||||
bool implicitRTEOK,
|
|
||||||
int location);
|
int location);
|
||||||
extern void markVarForSelectPriv(ParseState *pstate, Var *var,
|
extern void markVarForSelectPriv(ParseState *pstate, Var *var,
|
||||||
RangeTblEntry *rte);
|
RangeTblEntry *rte);
|
||||||
@ -87,7 +84,7 @@ extern RangeTblEntry *addRangeTableEntryForCTE(ParseState *pstate,
|
|||||||
extern void addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte,
|
extern void addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte,
|
||||||
bool addToJoinList,
|
bool addToJoinList,
|
||||||
bool addToRelNameSpace, bool addToVarNameSpace);
|
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,
|
extern void expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
|
||||||
int location, bool include_dropped,
|
int location, bool include_dropped,
|
||||||
List **colnames, List **colvars);
|
List **colnames, List **colvars);
|
||||||
|
@ -11,14 +11,11 @@ INSERT INTO delete_test (a) VALUES (100);
|
|||||||
DELETE FROM delete_test AS dt WHERE dt.a > 75;
|
DELETE FROM delete_test AS dt WHERE dt.a > 75;
|
||||||
-- if an alias is specified, don't allow the original table name
|
-- if an alias is specified, don't allow the original table name
|
||||||
-- to be referenced
|
-- to be referenced
|
||||||
BEGIN;
|
|
||||||
SET LOCAL add_missing_from = false;
|
|
||||||
DELETE FROM delete_test dt WHERE delete_test.a > 25;
|
DELETE FROM delete_test dt WHERE delete_test.a > 25;
|
||||||
ERROR: invalid reference to FROM-clause entry for table "delete_test"
|
ERROR: invalid reference to FROM-clause entry for table "delete_test"
|
||||||
LINE 1: DELETE FROM delete_test dt WHERE delete_test.a > 25;
|
LINE 1: DELETE FROM delete_test dt WHERE delete_test.a > 25;
|
||||||
^
|
^
|
||||||
HINT: Perhaps you meant to reference the table alias "dt".
|
HINT: Perhaps you meant to reference the table alias "dt".
|
||||||
ROLLBACK;
|
|
||||||
SELECT * FROM delete_test;
|
SELECT * FROM delete_test;
|
||||||
id | a
|
id | a
|
||||||
----+----
|
----+----
|
||||||
|
@ -63,13 +63,10 @@ select * from quadtable;
|
|||||||
2 | ("(,4.4)","(5.5,6.6)")
|
2 | ("(,4.4)","(5.5,6.6)")
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
begin;
|
|
||||||
set local add_missing_from = false;
|
|
||||||
select f1, q.c1 from quadtable; -- fails, q is a table reference
|
select f1, q.c1 from quadtable; -- fails, q is a table reference
|
||||||
ERROR: missing FROM-clause entry for table "q"
|
ERROR: missing FROM-clause entry for table "q"
|
||||||
LINE 1: select f1, q.c1 from quadtable;
|
LINE 1: select f1, q.c1 from quadtable;
|
||||||
^
|
^
|
||||||
rollback;
|
|
||||||
select f1, (q).c1, (qq.q).c1.i from quadtable qq;
|
select f1, (q).c1, (qq.q).c1.i from quadtable qq;
|
||||||
f1 | c1 | i
|
f1 | c1 | i
|
||||||
----+-----------+-----
|
----+-----------+-----
|
||||||
|
@ -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
|
-- if an alias for the target table is specified, don't allow references
|
||||||
-- to the original table name
|
-- 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;
|
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"
|
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...
|
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".
|
HINT: Perhaps you meant to reference the table alias "t".
|
||||||
ROLLBACK;
|
|
||||||
DROP TABLE update_test;
|
DROP TABLE update_test;
|
||||||
|
@ -12,10 +12,7 @@ DELETE FROM delete_test AS dt WHERE dt.a > 75;
|
|||||||
|
|
||||||
-- if an alias is specified, don't allow the original table name
|
-- if an alias is specified, don't allow the original table name
|
||||||
-- to be referenced
|
-- to be referenced
|
||||||
BEGIN;
|
|
||||||
SET LOCAL add_missing_from = false;
|
|
||||||
DELETE FROM delete_test dt WHERE delete_test.a > 25;
|
DELETE FROM delete_test dt WHERE delete_test.a > 25;
|
||||||
ROLLBACK;
|
|
||||||
|
|
||||||
SELECT * FROM delete_test;
|
SELECT * FROM delete_test;
|
||||||
|
|
||||||
|
@ -35,10 +35,7 @@ insert into quadtable values (2, ((null,4.4),(5.5,6.6)));
|
|||||||
|
|
||||||
select * from quadtable;
|
select * from quadtable;
|
||||||
|
|
||||||
begin;
|
|
||||||
set local add_missing_from = false;
|
|
||||||
select f1, q.c1 from quadtable; -- fails, q is a table reference
|
select f1, q.c1 from quadtable; -- fails, q is a table reference
|
||||||
rollback;
|
|
||||||
|
|
||||||
select f1, (q).c1, (qq.q).c1.i from quadtable qq;
|
select f1, (q).c1, (qq.q).c1.i from quadtable qq;
|
||||||
|
|
||||||
|
@ -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
|
-- if an alias for the target table is specified, don't allow references
|
||||||
-- to the original table name
|
-- 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;
|
UPDATE update_test AS t SET b = update_test.b + 10 WHERE t.a = 10;
|
||||||
ROLLBACK;
|
|
||||||
|
|
||||||
DROP TABLE update_test;
|
DROP TABLE update_test;
|
||||||
|
Loading…
Reference in New Issue
Block a user