Fix MERGE's test for unreachable WHEN clauses.
authorDean Rasheed <dean.a.rasheed@gmail.com>
Tue, 10 Jan 2023 14:17:47 +0000 (14:17 +0000)
committerDean Rasheed <dean.a.rasheed@gmail.com>
Tue, 10 Jan 2023 14:17:47 +0000 (14:17 +0000)
The former code would only detect an unreachable WHEN clause if it had
an AND condition. Fix, so that unreachable unconditional WHEN clauses
are also detected.

Back-patch to v15, where MERGE was added.

Discussion: https://postgr.es/m/CAEZATCVQ=7E2z4cSBB49jjeGGsB6WeoYQY32NDeSvcHiLUZ=ow@mail.gmail.com

src/backend/parser/parse_merge.c
src/test/regress/expected/merge.out
src/test/regress/sql/merge.sql

index 611dfce1d6b799d8dad1d4b2d2c6388367790869..d8866373b8f6764d04772bc4cba0cc6dc7635347 100644 (file)
@@ -155,12 +155,12 @@ transformMergeStmt(ParseState *pstate, MergeStmt *stmt)
        /*
         * Check for unreachable WHEN clauses
         */
-       if (mergeWhenClause->condition == NULL)
-           is_terminal[when_type] = true;
-       else if (is_terminal[when_type])
+       if (is_terminal[when_type])
            ereport(ERROR,
                    (errcode(ERRCODE_SYNTAX_ERROR),
                     errmsg("unreachable WHEN clause specified after unconditional WHEN clause")));
+       if (mergeWhenClause->condition == NULL)
+           is_terminal[when_type] = true;
    }
 
    /*
index 6c8a18f7b54f92f7062e3812da94182b54fe4856..bc53b2105b493ecab63db4990fc4deb533a1cda7 100644 (file)
@@ -659,7 +659,7 @@ USING source AS s
 ON t.tid = s.sid
 WHEN MATCHED THEN /* Terminal WHEN clause for MATCHED */
    DELETE
-WHEN MATCHED AND s.delta > 0 THEN
+WHEN MATCHED THEN
    UPDATE SET balance = t.balance - s.delta;
 ERROR:  unreachable WHEN clause specified after unconditional WHEN clause
 ROLLBACK;
index 98fe1040bd4e91eebbab2812b327e0741a83062c..fdbcd708823100c3ff7c789f0273e107247f0893 100644 (file)
@@ -438,7 +438,7 @@ USING source AS s
 ON t.tid = s.sid
 WHEN MATCHED THEN /* Terminal WHEN clause for MATCHED */
    DELETE
-WHEN MATCHED AND s.delta > 0 THEN
+WHEN MATCHED THEN
    UPDATE SET balance = t.balance - s.delta;
 ROLLBACK;