<!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/delete.sgml,v 1.25 2005/11/01 21:09:50 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/delete.sgml,v 1.26 2006/01/22 05:20:33 neilc Exp $
PostgreSQL documentation
-->
<refsynopsisdiv>
<synopsis>
-DELETE FROM [ ONLY ] <replaceable class="PARAMETER">table</replaceable>
+DELETE FROM [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ [ AS ] <replaceable class="parameter">alias</replaceable> ]
[ USING <replaceable class="PARAMETER">usinglist</replaceable> ]
[ WHERE <replaceable class="PARAMETER">condition</replaceable> ]
</synopsis>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><replaceable class="parameter">alias</replaceable></term>
+ <listitem>
+ <para>
+ A substitute name for the target table. When an alias is
+ provided, it completely hides the actual name of the table. For
+ example, given <literal>DELETE FROM foo AS f</>, the remainder
+ of the <command>DELETE</command> statement must refer to this
+ table as <literal>f</> not <literal>foo</>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><replaceable class="PARAMETER">usinglist</replaceable></term>
<listitem>
<!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/update.sgml,v 1.34 2006/01/19 23:09:42 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/update.sgml,v 1.35 2006/01/22 05:20:33 neilc Exp $
PostgreSQL documentation
-->
<refsynopsisdiv>
<synopsis>
-UPDATE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> SET <replaceable class="PARAMETER">column</replaceable> = { <replaceable class="PARAMETER">expression</replaceable> | DEFAULT } [, ...]
+UPDATE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ [ AS ] <replaceable class="parameter">alias</replaceable> ]
+ SET <replaceable class="PARAMETER">column</replaceable> = { <replaceable class="PARAMETER">expression</replaceable> | DEFAULT } [, ...]
[ FROM <replaceable class="PARAMETER">fromlist</replaceable> ]
[ WHERE <replaceable class="PARAMETER">condition</replaceable> ]
</synopsis>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><replaceable class="parameter">alias</replaceable></term>
+ <listitem>
+ <para>
+ A substitute name for the target table. When an alias is
+ provided, it completely hides the actual name of the table. For
+ example, given <literal>UPDATE foo AS f</>, the remainder of the
+ <command>UPDATE</command> statement must refer to this table as
+ <literal>f</> not <literal>foo</>. You cannot use the alias in
+ the <literal>SET</literal> clause. For example, <literal>SET
+ f.col = 1</> is invalid.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><replaceable class="PARAMETER">column</replaceable></term>
<listitem>
-<!-- $PostgreSQL: pgsql/doc/src/sgml/regress.sgml,v 1.49 2005/10/18 21:43:33 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/regress.sgml,v 1.50 2006/01/22 05:20:32 neilc Exp $ -->
<chapter id="regress">
<title id="regress-title">Regression Tests</title>
<screen>
<computeroutput>
======================
- All 98 tests passed.
+ All 100 tests passed.
======================
</computeroutput>
</screen>
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.522 2006/01/21 02:16:19 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.523 2006/01/22 05:20:33 neilc Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
%type <node> table_ref
%type <jexpr> joined_table
%type <range> relation_expr
+%type <range> relation_expr_opt_alias
%type <target> target_el insert_target_el update_target_el insert_column_item
%type <typnam> Typename SimpleTypename ConstTypename
*
*****************************************************************************/
-DeleteStmt: DELETE_P FROM relation_expr using_clause where_clause
+DeleteStmt: DELETE_P FROM relation_expr_opt_alias
+ using_clause where_clause
{
DeleteStmt *n = makeNode(DeleteStmt);
n->relation = $3;
*
*****************************************************************************/
-UpdateStmt: UPDATE relation_expr
+UpdateStmt: UPDATE relation_expr_opt_alias
SET update_target_list
from_clause
where_clause
;
+relation_expr_opt_alias: relation_expr
+ {
+ $$ = $1;
+ }
+ | relation_expr opt_as IDENT
+ {
+ Alias *alias = makeNode(Alias);
+ alias->aliasname = $3;
+ $1->alias = alias;
+ $$ = $1;
+ }
+ ;
+
+
func_table: func_expr { $$ = $1; }
;
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.144 2005/11/22 18:17:16 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.145 2006/01/22 05:20:34 neilc Exp $
*
*-------------------------------------------------------------------------
*/
* Now build an RTE.
*/
rte = addRangeTableEntryForRelation(pstate, pstate->p_target_relation,
- NULL, inh, false);
+ relation->alias, inh, false);
pstate->p_target_rangetblentry = rte;
/* assume new rte is at end */
--- /dev/null
+CREATE TABLE delete_test (
+ id SERIAL PRIMARY KEY,
+ a INT
+);
+NOTICE: CREATE TABLE will create implicit sequence "delete_test_id_seq" for serial column "delete_test.id"
+NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "delete_test_pkey" for table "delete_test"
+INSERT INTO delete_test (a) VALUES (10);
+INSERT INTO delete_test (a) VALUES (50);
+INSERT INTO delete_test (a) VALUES (100);
+-- allow an alias to be specified for DELETE's target table
+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"
+HINT: Perhaps you meant to reference the table alias "dt".
+ROLLBACK;
+SELECT * FROM delete_test;
+ id | a
+----+----
+ 1 | 10
+ 2 | 50
+(2 rows)
+
+DROP TABLE delete_test;
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"
+rollback;
select f1, (q).c1, (qq.q).c1.i from quadtable qq;
f1 | c1 | i
----+-----------+-----
10 |
(2 rows)
+-- aliases for the UPDATE target table
+UPDATE update_test AS t SET b = 10 WHERE t.a = 10;
+SELECT * FROM update_test;
+ a | b
+----+----
+ 10 | 10
+ 10 | 10
+(2 rows)
+
+UPDATE update_test t SET b = t.b + 10 WHERE t.a = 10;
+SELECT * FROM update_test;
+ a | b
+----+----
+ 10 | 20
+ 10 | 20
+(2 rows)
+
+-- 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"
+HINT: Perhaps you meant to reference the table alias "t".
+ROLLBACK;
DROP TABLE update_test;
# ----------
# The fourth group of parallel test
# ----------
-test: select_into select_distinct select_distinct_on select_implicit select_having subselect union case join aggregates transactions random portals arrays btree_index hash_index update namespace prepared_xacts
+test: select_into select_distinct select_distinct_on select_implicit select_having subselect union case join aggregates transactions random portals arrays btree_index hash_index update namespace prepared_xacts delete
test: privileges
test: misc
-# $PostgreSQL: pgsql/src/test/regress/serial_schedule,v 1.29 2005/11/19 17:39:45 adunstan Exp $
+# $PostgreSQL: pgsql/src/test/regress/serial_schedule,v 1.30 2006/01/22 05:20:34 neilc Exp $
# This should probably be in an order similar to parallel_schedule.
test: boolean
test: char
test: btree_index
test: hash_index
test: update
+test: delete
test: namespace
test: prepared_xacts
test: privileges
--- /dev/null
+CREATE TABLE delete_test (
+ id SERIAL PRIMARY KEY,
+ a INT
+);
+
+INSERT INTO delete_test (a) VALUES (10);
+INSERT INTO delete_test (a) VALUES (50);
+INSERT INTO delete_test (a) VALUES (100);
+
+-- allow an alias to be specified for DELETE's target table
+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;
\ No newline at end of file
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;
SELECT * FROM update_test;
+-- aliases for the UPDATE target table
+UPDATE update_test AS t SET b = 10 WHERE t.a = 10;
+
+SELECT * FROM update_test;
+
+UPDATE update_test t SET b = t.b + 10 WHERE t.a = 10;
+
+SELECT * 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;
+ROLLBACK;
+
DROP TABLE update_test;