agora inbox for [email protected]
help / color / mirror / Atom feedFrom: Kyotaro Horiguchi <[email protected]>
Subject: [PATCH] Emit meaningful message for reference to concurrently added column.
Date: Wed, 27 Nov 2019 11:16:07 +0900
In ALTER TABLE ADD COLUMN, expressions cannot refer to columns
concurrently added by other subcommands. Currently we get an improper
message like "attribute number 6 exceeds number of columns 5" for the
case. Fix it.
---
src/backend/commands/tablecmds.c | 28 ++++++++++++++++++++++++-
src/test/regress/expected/generated.out | 3 +++
src/test/regress/sql/generated.sql | 1 +
3 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 5440eb9015..f75ca74c6b 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -5891,10 +5891,36 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
if (defval)
{
NewColumnValue *newval;
+ List *varlist;
+ ListCell *lc;
+ Expr *newexpr;
+
+ newexpr = expression_planner(defval);
+
+ /*
+ * The expression may reference columns added by concurrent
+ * subcommands, which leads to internal error on table
+ * rewrite. Check them out here to emit meaningful error message.
+ */
+ varlist = pull_var_clause((Node *) newexpr, 0);
+ foreach (lc, varlist)
+ {
+ Var *var = (Var *) lfirst(lc);
+
+ /* System columns are rejected ealier. */
+ Assert(var->varattno > 0);
+
+ if (var->varattno > tab->oldDesc->natts)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
+ errmsg ("column \"%s\" does not exist",
+ NameStr(TupleDescAttr(rel->rd_att, var->varattno - 1)->attname)),
+ errdetail("An expression cannot reference columns added in the same command.")));
+ }
newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
newval->attnum = attribute.attnum;
- newval->expr = expression_planner(defval);
+ newval->expr = newexpr;
tab->newvals = lappend(tab->newvals, newval);
}
diff --git a/src/test/regress/expected/generated.out b/src/test/regress/expected/generated.out
index f62c93f468..b5e58991bd 100644
--- a/src/test/regress/expected/generated.out
+++ b/src/test/regress/expected/generated.out
@@ -593,6 +593,9 @@ ERROR: cannot use generated column "b" in column generation expression
DETAIL: A generated column cannot reference another generated column.
ALTER TABLE gtest25 ADD COLUMN x int GENERATED ALWAYS AS (z * 4) STORED; -- error
ERROR: column "z" does not exist
+ALTER TABLE gtest25 ADD COLUMN x int, ADD COLUMN y int GENERATED ALWAYS AS (x * 4) STORED; -- error
+ERROR: column "x" does not exist
+DETAIL: An expression cannot reference columns added in the same command.
-- ALTER TABLE ... ALTER COLUMN
CREATE TABLE gtest27 (
a int,
diff --git a/src/test/regress/sql/generated.sql b/src/test/regress/sql/generated.sql
index 6a56ae260f..3b00f81b54 100644
--- a/src/test/regress/sql/generated.sql
+++ b/src/test/regress/sql/generated.sql
@@ -316,6 +316,7 @@ ALTER TABLE gtest25 ADD COLUMN b int GENERATED ALWAYS AS (a * 3) STORED;
SELECT * FROM gtest25 ORDER BY a;
ALTER TABLE gtest25 ADD COLUMN x int GENERATED ALWAYS AS (b * 4) STORED; -- error
ALTER TABLE gtest25 ADD COLUMN x int GENERATED ALWAYS AS (z * 4) STORED; -- error
+ALTER TABLE gtest25 ADD COLUMN x int, ADD COLUMN y int GENERATED ALWAYS AS (x * 4) STORED; -- error
-- ALTER TABLE ... ALTER COLUMN
CREATE TABLE gtest27 (
--
2.23.0
----Next_Part(Wed_Nov_27_12_00_34_2019_233)----
view thread (2+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [PATCH] Emit meaningful message for reference to concurrently added column.
In-Reply-To: <no-message-id-1883389@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox