mirror of
https://github.com/postgres/postgres.git
synced 2026-07-07 00:30:57 -04:00
Forbid FOR PORTION OF with WHERE CURRENT OF
It is not clear how the implicit condition of FOR PORTION OF should interact with the use of a cursor. Normally, we forbid combining WHERE CURRENT OF with other WHERE conditions. The SQL standard only includes FOR PORTION OF with <update statement: searched> and <delete statement: searched>, not <update statement: positioned> or <delete statement: positioned>, so it is easy for us to exclude the functionality, at least for now. Author: Paul A. Jungwirth <pj@illuminatedcomputing.com> Discussion: https://www.postgresql.org/message-id/flat/CA%2BrenyUEKPexUYsH4qeU8_o1jqKsUkEWca1keS6n21shgG1g%2BA%40mail.gmail.com
This commit is contained in:
parent
994f770a0f
commit
bc3ae886a7
5 changed files with 86 additions and 8 deletions
|
|
@ -231,10 +231,9 @@ DELETE FROM [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ *
|
|||
from this cursor. The cursor must be a non-grouping
|
||||
query on the <command>DELETE</command>'s target table.
|
||||
Note that <literal>WHERE CURRENT OF</literal> cannot be
|
||||
specified together with a Boolean condition. See
|
||||
<xref linkend="sql-declare"/>
|
||||
for more information about using cursors with
|
||||
<literal>WHERE CURRENT OF</literal>.
|
||||
specified together with a Boolean condition or <literal>FOR PORTION
|
||||
OF</literal>. See <xref linkend="sql-declare"/> for more information
|
||||
about using cursors with <literal>WHERE CURRENT OF</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
|
|
|||
|
|
@ -287,10 +287,9 @@ UPDATE [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ]
|
|||
from this cursor. The cursor must be a non-grouping
|
||||
query on the <command>UPDATE</command>'s target table.
|
||||
Note that <literal>WHERE CURRENT OF</literal> cannot be
|
||||
specified together with a Boolean condition. See
|
||||
<xref linkend="sql-declare"/>
|
||||
for more information about using cursors with
|
||||
<literal>WHERE CURRENT OF</literal>.
|
||||
specified together with a Boolean condition or <literal>FOR PORTION
|
||||
OF</literal>. See <xref linkend="sql-declare"/> for more information
|
||||
about using cursors with <literal>WHERE CURRENT OF</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ static OnConflictExpr *transformOnConflictClause(ParseState *pstate,
|
|||
static ForPortionOfExpr *transformForPortionOfClause(ParseState *pstate,
|
||||
int rtindex,
|
||||
const ForPortionOfClause *forPortionOf,
|
||||
const Node *whereClause,
|
||||
bool isUpdate);
|
||||
static int count_rowexpr_columns(ParseState *pstate, Node *expr);
|
||||
static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt,
|
||||
|
|
@ -626,6 +627,7 @@ transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
|
|||
qry->forPortionOf = transformForPortionOfClause(pstate,
|
||||
qry->resultRelation,
|
||||
stmt->forPortionOf,
|
||||
stmt->whereClause,
|
||||
false);
|
||||
|
||||
qual = transformWhereClause(pstate, stmt->whereClause,
|
||||
|
|
@ -1319,6 +1321,7 @@ static ForPortionOfExpr *
|
|||
transformForPortionOfClause(ParseState *pstate,
|
||||
int rtindex,
|
||||
const ForPortionOfClause *forPortionOf,
|
||||
const Node *whereClause,
|
||||
bool isUpdate)
|
||||
{
|
||||
Relation targetrel = pstate->p_target_relation;
|
||||
|
|
@ -1335,6 +1338,12 @@ transformForPortionOfClause(ParseState *pstate,
|
|||
ForPortionOfExpr *result;
|
||||
Var *rangeVar;
|
||||
|
||||
/* disallow FOR PORTION OF ... WHERE CURRENT OF */
|
||||
if (whereClause && IsA(whereClause, CurrentOfExpr))
|
||||
ereport(ERROR,
|
||||
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("WHERE CURRENT OF with FOR PORTION OF is not implemented"));
|
||||
|
||||
result = makeNode(ForPortionOfExpr);
|
||||
|
||||
/* Look up the FOR PORTION OF name requested. */
|
||||
|
|
@ -2875,6 +2884,7 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
|
|||
qry->forPortionOf = transformForPortionOfClause(pstate,
|
||||
qry->resultRelation,
|
||||
stmt->forPortionOf,
|
||||
stmt->whereClause,
|
||||
true);
|
||||
|
||||
nsitem = pstate->p_target_nsitem;
|
||||
|
|
|
|||
|
|
@ -2446,4 +2446,46 @@ NOTICE: fpo_before_row1: BEFORE UPDATE ROW:
|
|||
NOTICE: old: [10,100)
|
||||
NOTICE: new: [30,70)
|
||||
DROP TABLE fpo_update_of_trigger;
|
||||
-- CURSORs
|
||||
CREATE TABLE fpo_cursed (
|
||||
id int,
|
||||
valid_at int4range
|
||||
);
|
||||
INSERT INTO fpo_cursed (id, valid_at) VALUES (1, '[10,100)');
|
||||
-- UPDATE FOR PORTION OF is not permitted with a CURSOR:
|
||||
BEGIN;
|
||||
DECLARE fpo_cur CURSOR FOR SELECT * FROM fpo_cursed;
|
||||
FETCH NEXT FROM fpo_cur;
|
||||
id | valid_at
|
||||
----+----------
|
||||
1 | [10,100)
|
||||
(1 row)
|
||||
|
||||
UPDATE fpo_cursed
|
||||
FOR PORTION OF valid_at FROM 5 TO 6
|
||||
SET id = 2
|
||||
WHERE CURRENT OF fpo_cur;
|
||||
ERROR: WHERE CURRENT OF with FOR PORTION OF is not implemented
|
||||
ROLLBACK;
|
||||
-- DELETE FOR PORTION OF is not permitted with a CURSOR:
|
||||
BEGIN;
|
||||
DECLARE fpo_cur CURSOR FOR SELECT * FROM fpo_cursed;
|
||||
FETCH NEXT FROM fpo_cur;
|
||||
id | valid_at
|
||||
----+----------
|
||||
1 | [10,100)
|
||||
(1 row)
|
||||
|
||||
DELETE FROM fpo_cursed
|
||||
FOR PORTION OF valid_at FROM 8 TO 9
|
||||
WHERE CURRENT OF fpo_cur;
|
||||
ERROR: WHERE CURRENT OF with FOR PORTION OF is not implemented
|
||||
ROLLBACK;
|
||||
SELECT * FROM fpo_cursed;
|
||||
id | valid_at
|
||||
----+----------
|
||||
1 | [10,100)
|
||||
(1 row)
|
||||
|
||||
DROP TABLE fpo_cursed;
|
||||
RESET datestyle;
|
||||
|
|
|
|||
|
|
@ -1591,4 +1591,32 @@ UPDATE fpo_update_of_trigger
|
|||
SET id = 2;
|
||||
DROP TABLE fpo_update_of_trigger;
|
||||
|
||||
-- CURSORs
|
||||
CREATE TABLE fpo_cursed (
|
||||
id int,
|
||||
valid_at int4range
|
||||
);
|
||||
INSERT INTO fpo_cursed (id, valid_at) VALUES (1, '[10,100)');
|
||||
|
||||
-- UPDATE FOR PORTION OF is not permitted with a CURSOR:
|
||||
BEGIN;
|
||||
DECLARE fpo_cur CURSOR FOR SELECT * FROM fpo_cursed;
|
||||
FETCH NEXT FROM fpo_cur;
|
||||
UPDATE fpo_cursed
|
||||
FOR PORTION OF valid_at FROM 5 TO 6
|
||||
SET id = 2
|
||||
WHERE CURRENT OF fpo_cur;
|
||||
ROLLBACK;
|
||||
|
||||
-- DELETE FOR PORTION OF is not permitted with a CURSOR:
|
||||
BEGIN;
|
||||
DECLARE fpo_cur CURSOR FOR SELECT * FROM fpo_cursed;
|
||||
FETCH NEXT FROM fpo_cur;
|
||||
DELETE FROM fpo_cursed
|
||||
FOR PORTION OF valid_at FROM 8 TO 9
|
||||
WHERE CURRENT OF fpo_cur;
|
||||
ROLLBACK;
|
||||
SELECT * FROM fpo_cursed;
|
||||
DROP TABLE fpo_cursed;
|
||||
|
||||
RESET datestyle;
|
||||
|
|
|
|||
Loading…
Reference in a new issue