On Mon, Dec 16, 2024 at 2:15 PM Michael Paquier <mich...@paquier.xyz> wrote:
>
> -        likeType = typenameType(NULL, defGetTypeName(likeTypeEl), NULL);
> +        likeType = typenameType(pstate, defGetTypeName(likeTypeEl), NULL);
>
> The only test impacted by this change is the CREATE TYPE (LIKE) in
> float8.  It seems like this should be separated as a change of its own
> as it impacts its own command.
>
> For the rest, we're just manipulating ATExecAddOf(),
> ATPrepAlterColumnType() and ATExecAlterColumnType().  FWIW, I'm
> feeling annoyed with these new make_parsestate() calls, also knowing
> that we do it twice for the prep and exec parts of AlterColumnType.
> Perhaps that's fine at the end, that's just an increase of calls to
> make_parsestate(), still...
>

I've removed code changes related to ATExecAddOf.
ATPrepAlterColumnType will catch most of the error, so
ATExecAlterColumnType related change is not necessary.

i've split into 3 patches, feel free to merge them in any way.
v12-0001:  add error position for ATPrepAlterColumnType.

v12-0002:  add error position for these 3 functions:
transformColumnDefinition, transformAlterTableStmt, transformTableConstraint.

v12-0003: add error position for these 2 functions:
DefineType, transformOfType


> > like this command will fail, so we don't need to change
> > create_domain.sgml synopsis section?
>
> Yep, right.  I was getting the impression that it would be possible to
> have these ones go through with the parser allowed them when I looked
> at that last Thursday.  Will double-check to be sure.
> --
v6-0001-print-out-error-position-for-some-DDL-command.patch
at 
https://postgr.es/m/CACJufxGQtN2YzecMx=Odk8+kCTeoN7f=m_km5e05udw1h1p...@mail.gmail.com
have extensive tests.
From d3bd24b36868186c45183d2ae0bf7e8cc5720dfd Mon Sep 17 00:00:00 2001
From: jian he <jian.universal...@gmail.com>
Date: Mon, 16 Dec 2024 16:11:30 +0800
Subject: [PATCH v12 1/3] add error position for ATPrepAlterColumnType:
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Author: Kirill Reshke <reshkekir...@gmail.com>
Author: Jian He <jian.universal...@gmail.com>
Reviewed-By: Michaël Paquier <mich...@paquier.xyz>
Reviewed-By: Álvaro Herrera <alvhe...@alvh.no-ip.org>

discussion: https://postgr.es/m/CALdSSPhqfvKbDwqJaY=yeepi_aq61gmmpw88i6zh7cmg_2z...@mail.gmail.com
---
 src/backend/commands/tablecmds.c          | 12 +++++++-----
 src/test/regress/expected/alter_table.out |  6 ++++++
 src/test/regress/expected/typed_table.out |  2 ++
 3 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 6ccae4cb4a..b5e00a9f28 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -13218,10 +13218,12 @@ ATPrepAlterColumnType(List **wqueue,
 	AclResult	aclresult;
 	bool		is_expr;
 
+	pstate->p_sourcetext = context->queryString;
 	if (rel->rd_rel->reloftype && !recursing)
 		ereport(ERROR,
 				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
-				 errmsg("cannot alter column type of typed table")));
+				 errmsg("cannot alter column type of typed table"),
+				 parser_errposition(pstate, def->location)));
 
 	/* lookup the attribute so we can check inheritance status */
 	tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName);
@@ -13237,8 +13239,8 @@ ATPrepAlterColumnType(List **wqueue,
 	if (attnum <= 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-				 errmsg("cannot alter system column \"%s\"",
-						colName)));
+				 errmsg("cannot alter system column \"%s\"",colName),
+				 parser_errposition(pstate, def->location)));
 
 	/*
 	 * Cannot specify USING when altering type of a generated column, because
@@ -13271,14 +13273,14 @@ ATPrepAlterColumnType(List **wqueue,
 						colName, RelationGetRelationName(rel))));
 
 	/* Look up the target type */
-	typenameTypeIdAndMod(NULL, typeName, &targettype, &targettypmod);
+	typenameTypeIdAndMod(pstate, typeName, &targettype, &targettypmod);
 
 	aclresult = object_aclcheck(TypeRelationId, targettype, GetUserId(), ACL_USAGE);
 	if (aclresult != ACLCHECK_OK)
 		aclcheck_error_type(aclresult, targettype);
 
 	/* And the collation */
-	targetcollid = GetColumnDefCollation(NULL, def, targettype);
+	targetcollid = GetColumnDefCollation(pstate, def, targettype);
 
 	/* make sure datatype is legal for a column */
 	CheckAttributeType(colName, targettype, targetcollid,
diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out
index 12852aa612..57263f0709 100644
--- a/src/test/regress/expected/alter_table.out
+++ b/src/test/regress/expected/alter_table.out
@@ -3416,10 +3416,16 @@ ALTER TABLE comment_test ALTER COLUMN positive_col SET DATA TYPE bigint;
 -- Some error cases.
 ALTER TABLE comment_test ALTER COLUMN xmin SET DATA TYPE x;
 ERROR:  cannot alter system column "xmin"
+LINE 1: ALTER TABLE comment_test ALTER COLUMN xmin SET DATA TYPE x;
+                                              ^
 ALTER TABLE comment_test ALTER COLUMN id SET DATA TYPE x;
 ERROR:  type "x" does not exist
+LINE 1: ALTER TABLE comment_test ALTER COLUMN id SET DATA TYPE x;
+                                                               ^
 ALTER TABLE comment_test ALTER COLUMN id SET DATA TYPE int COLLATE "C";
 ERROR:  collations are not supported by type integer
+LINE 1: ...LE comment_test ALTER COLUMN id SET DATA TYPE int COLLATE "C...
+                                                             ^
 -- Check that the comments are intact.
 SELECT col_description('comment_test'::regclass, 1) as comment;
            comment           
diff --git a/src/test/regress/expected/typed_table.out b/src/test/regress/expected/typed_table.out
index b6fbda3f21..5a81ae202e 100644
--- a/src/test/regress/expected/typed_table.out
+++ b/src/test/regress/expected/typed_table.out
@@ -36,6 +36,8 @@ ALTER TABLE persons RENAME COLUMN id TO num;
 ERROR:  cannot rename column of typed table
 ALTER TABLE persons ALTER COLUMN name TYPE varchar;
 ERROR:  cannot alter column type of typed table
+LINE 1: ALTER TABLE persons ALTER COLUMN name TYPE varchar;
+                                         ^
 CREATE TABLE stuff (id int);
 ALTER TABLE persons INHERIT stuff;
 ERROR:  cannot change inheritance of typed table
-- 
2.34.1

From d6b15cc964cecc9f5b9ac9104f2c3e01db66d029 Mon Sep 17 00:00:00 2001
From: jian he <jian.universal...@gmail.com>
Date: Mon, 16 Dec 2024 16:59:07 +0800
Subject: [PATCH v12 3/3] add error position for these two functions:
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

DefineType
transformOfType

instead of passing NULL to typenameType, pass the
ParseState available to typenameType, so error happen
typenameType can report the error position.

Author: Kirill Reshke <reshkekir...@gmail.com>
Author: Jian He <jian.universal...@gmail.com>
Reviewed-By: Michaël Paquier <mich...@paquier.xyz>
Reviewed-By: Álvaro Herrera <alvhe...@alvh.no-ip.org>

discussion: https://postgr.es/m/CALdSSPhqfvKbDwqJaY=yeepi_aq61gmmpw88i6zh7cmg_2z...@mail.gmail.com
---
 src/backend/commands/typecmds.c           | 2 +-
 src/backend/parser/parse_utilcmd.c        | 2 +-
 src/test/regress/expected/float8.out      | 2 ++
 src/test/regress/expected/typed_table.out | 2 ++
 4 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 6127313956..4f20b5be06 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -348,7 +348,7 @@ DefineType(ParseState *pstate, List *names, List *parameters)
 		Type		likeType;
 		Form_pg_type likeForm;
 
-		likeType = typenameType(NULL, defGetTypeName(likeTypeEl), NULL);
+		likeType = typenameType(pstate, defGetTypeName(likeTypeEl), NULL);
 		likeForm = (Form_pg_type) GETSTRUCT(likeType);
 		internalLength = likeForm->typlen;
 		byValue = likeForm->typbyval;
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index b43923c21d..58536b1fe7 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -1619,7 +1619,7 @@ transformOfType(CreateStmtContext *cxt, TypeName *ofTypename)
 
 	Assert(ofTypename);
 
-	tuple = typenameType(NULL, ofTypename, NULL);
+	tuple = typenameType(cxt->pstate, ofTypename, NULL);
 	check_of_type(tuple);
 	ofTypeId = ((Form_pg_type) GETSTRUCT(tuple))->oid;
 	ofTypename->typeOid = ofTypeId; /* cached for later */
diff --git a/src/test/regress/expected/float8.out b/src/test/regress/expected/float8.out
index 4965ee5554..9ef9793fe9 100644
--- a/src/test/regress/expected/float8.out
+++ b/src/test/regress/expected/float8.out
@@ -1026,6 +1026,8 @@ LINE 1: create function xfloat8out(xfloat8) returns cstring immutabl...
                                    ^
 create type xfloat8 (input = xfloat8in, output = xfloat8out, like = no_such_type);
 ERROR:  type "no_such_type" does not exist
+LINE 1: ...8 (input = xfloat8in, output = xfloat8out, like = no_such_ty...
+                                                             ^
 create type xfloat8 (input = xfloat8in, output = xfloat8out, like = float8);
 create cast (xfloat8 as float8) without function;
 create cast (float8 as xfloat8) without function;
diff --git a/src/test/regress/expected/typed_table.out b/src/test/regress/expected/typed_table.out
index 5a81ae202e..885f085e15 100644
--- a/src/test/regress/expected/typed_table.out
+++ b/src/test/regress/expected/typed_table.out
@@ -1,5 +1,7 @@
 CREATE TABLE ttable1 OF nothing;
 ERROR:  type "nothing" does not exist
+LINE 1: CREATE TABLE ttable1 OF nothing;
+                                ^
 CREATE TYPE person_type AS (id int, name text);
 CREATE TABLE persons OF person_type;
 CREATE TABLE IF NOT EXISTS persons OF person_type;
-- 
2.34.1

From 80ead181462d1ed4f897a96c6d9fe8ac74249cb3 Mon Sep 17 00:00:00 2001
From: jian he <jian.universal...@gmail.com>
Date: Mon, 16 Dec 2024 16:27:48 +0800
Subject: [PATCH v12 2/3] add error position for these 3 functions:
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

transformColumnDefinition
transformAlterTableStmt
transformTableConstraint

Author: Kirill Reshke <reshkekir...@gmail.com>
Author: Jian He <jian.universal...@gmail.com>
Reviewed-By: Michaël Paquier <mich...@paquier.xyz>
Reviewed-By: Álvaro Herrera <alvhe...@alvh.no-ip.org>

discussion: https://postgr.es/m/CALdSSPhqfvKbDwqJaY=yeepi_aq61gmmpw88i6zh7cmg_2z...@mail.gmail.com
---
 src/backend/parser/parse_utilcmd.c        | 18 ++++++++++++------
 src/test/regress/expected/constraints.out | 14 ++++++++++++++
 src/test/regress/expected/identity.out    |  2 ++
 3 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 0f324ee4e3..b43923c21d 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -756,7 +756,8 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
 				if (cxt->ispartitioned && constraint->is_no_inherit)
 					ereport(ERROR,
 							errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-							errmsg("not-null constraints on partitioned tables cannot be NO INHERIT"));
+							errmsg("not-null constraints on partitioned tables cannot be NO INHERIT"),
+							parser_errposition(cxt->pstate, constraint->location));
 
 				/* Disallow conflicting [NOT] NULL markings */
 				if (saw_nullable && !column->is_not_null)
@@ -771,7 +772,8 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
 					ereport(ERROR,
 							errcode(ERRCODE_SYNTAX_ERROR),
 							errmsg("conflicting NO INHERIT declarations for not-null constraints on column \"%s\"",
-								   column->colname));
+								   column->colname),
+							parser_errposition(cxt->pstate, constraint->location));
 
 				/*
 				 * If this is the first time we see this column being marked
@@ -806,7 +808,8 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
 						ereport(ERROR,
 								errcode(ERRCODE_SYNTAX_ERROR),
 								errmsg("conflicting NO INHERIT declarations for not-null constraints on column \"%s\"",
-									   column->colname));
+									   column->colname),
+								parser_errposition(cxt->pstate, constraint->location));
 
 					if (!notnull_constraint->conname && constraint->conname)
 						notnull_constraint->conname = constraint->conname;
@@ -1072,7 +1075,8 @@ transformTableConstraint(CreateStmtContext *cxt, Constraint *constraint)
 			if (cxt->ispartitioned && constraint->is_no_inherit)
 				ereport(ERROR,
 						errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-						errmsg("not-null constraints on partitioned tables cannot be NO INHERIT"));
+						errmsg("not-null constraints on partitioned tables cannot be NO INHERIT"),
+						parser_errposition(cxt->pstate, constraint->location));
 
 			cxt->nnconstraints = lappend(cxt->nnconstraints, constraint);
 			break;
@@ -3627,7 +3631,8 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt,
 							ereport(ERROR,
 									(errcode(ERRCODE_UNDEFINED_COLUMN),
 									 errmsg("column \"%s\" of relation \"%s\" does not exist",
-											cmd->name, RelationGetRelationName(rel))));
+											cmd->name, RelationGetRelationName(rel)),
+									 parser_errposition(pstate, def->location)));
 
 						if (attnum > 0 &&
 							TupleDescAttr(tupdesc, attnum - 1)->attidentity)
@@ -3667,7 +3672,8 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt,
 						ereport(ERROR,
 								(errcode(ERRCODE_UNDEFINED_COLUMN),
 								 errmsg("column \"%s\" of relation \"%s\" does not exist",
-										cmd->name, RelationGetRelationName(rel))));
+										cmd->name, RelationGetRelationName(rel)),
+								 parser_errposition(pstate, def->location)));
 
 					generateSerialExtraStmts(&cxt, newdef,
 											 get_atttype(relid, attnum),
diff --git a/src/test/regress/expected/constraints.out b/src/test/regress/expected/constraints.out
index 71200c90ed..ff3b710468 100644
--- a/src/test/regress/expected/constraints.out
+++ b/src/test/regress/expected/constraints.out
@@ -925,6 +925,8 @@ create table notnull_tbl_fail (a serial constraint foo not null constraint bar n
 ERROR:  conflicting not-null constraint names "foo" and "bar"
 create table notnull_tbl_fail (a serial constraint foo not null no inherit constraint foo not null);
 ERROR:  conflicting NO INHERIT declarations for not-null constraints on column "a"
+LINE 1: create table notnull_tbl_fail (a serial constraint foo not n...
+                                                ^
 create table notnull_tbl_fail (a int constraint foo not null, constraint foo not null a no inherit);
 ERROR:  conflicting NO INHERIT declaration for not-null constraint on column "a"
 create table notnull_tbl_fail (a serial constraint foo not null, constraint bar not null a);
@@ -935,12 +937,18 @@ create table notnull_tbl_fail (a serial, constraint foo not null a no inherit);
 ERROR:  conflicting NO INHERIT declaration for not-null constraint on column "a"
 create table notnull_tbl_fail (a serial not null no inherit);
 ERROR:  conflicting NO INHERIT declarations for not-null constraints on column "a"
+LINE 1: create table notnull_tbl_fail (a serial not null no inherit)...
+                                                ^
 create table notnull_tbl_fail (like notnull_tbl1, constraint foo2 not null a);
 ERROR:  conflicting not-null constraint names "foo" and "foo2"
 create table notnull_tbl_fail (a int primary key constraint foo not null no inherit);
 ERROR:  conflicting NO INHERIT declarations for not-null constraints on column "a"
+LINE 1: create table notnull_tbl_fail (a int primary key constraint ...
+                                                         ^
 create table notnull_tbl_fail (a int not null no inherit primary key);
 ERROR:  conflicting NO INHERIT declarations for not-null constraints on column "a"
+LINE 1: create table notnull_tbl_fail (a int not null no inherit pri...
+                                             ^
 create table notnull_tbl_fail (a int primary key, not null a no inherit);
 ERROR:  conflicting NO INHERIT declaration for not-null constraint on column "a"
 create table notnull_tbl_fail (a int, primary key(a), not null a no inherit);
@@ -949,6 +957,8 @@ create table notnull_tbl_fail (a int generated by default as identity, constrain
 ERROR:  conflicting NO INHERIT declaration for not-null constraint on column "a"
 create table notnull_tbl_fail (a int generated by default as identity not null no inherit);
 ERROR:  conflicting NO INHERIT declarations for not-null constraints on column "a"
+LINE 1: ..._tbl_fail (a int generated by default as identity not null n...
+                                                             ^
 drop table notnull_tbl1;
 -- NOT NULL NO INHERIT
 CREATE TABLE ATACC1 (a int, NOT NULL a NO INHERIT);
@@ -998,8 +1008,12 @@ DROP TABLE ATACC1, ATACC2, ATACC3;
 -- NOT NULL NO INHERIT is not possible on partitioned tables
 CREATE TABLE ATACC1 (a int NOT NULL NO INHERIT) PARTITION BY LIST (a);
 ERROR:  not-null constraints on partitioned tables cannot be NO INHERIT
+LINE 1: CREATE TABLE ATACC1 (a int NOT NULL NO INHERIT) PARTITION BY...
+                                   ^
 CREATE TABLE ATACC1 (a int, NOT NULL a NO INHERIT) PARTITION BY LIST (a);
 ERROR:  not-null constraints on partitioned tables cannot be NO INHERIT
+LINE 1: CREATE TABLE ATACC1 (a int, NOT NULL a NO INHERIT) PARTITION...
+                                    ^
 -- it's not possible to override a no-inherit constraint with an inheritable one
 CREATE TABLE ATACC2 (a int, CONSTRAINT a_is_not_null NOT NULL a NO INHERIT);
 CREATE TABLE ATACC1 (a int);
diff --git a/src/test/regress/expected/identity.out b/src/test/regress/expected/identity.out
index 0398a19484..0b370235ea 100644
--- a/src/test/regress/expected/identity.out
+++ b/src/test/regress/expected/identity.out
@@ -45,6 +45,8 @@ ERROR:  column "a" of relation "itest4" must be declared NOT NULL before identit
 ALTER TABLE itest4 ALTER COLUMN a SET NOT NULL;
 ALTER TABLE itest4 ALTER COLUMN c ADD GENERATED ALWAYS AS IDENTITY;  -- error, column c does not exist
 ERROR:  column "c" of relation "itest4" does not exist
+LINE 1: ALTER TABLE itest4 ALTER COLUMN c ADD GENERATED ALWAYS AS ID...
+                                              ^
 ALTER TABLE itest4 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY;  -- ok
 ALTER TABLE itest4 ALTER COLUMN a DROP NOT NULL;  -- error, disallowed
 ERROR:  column "a" of relation "itest4" is an identity column
-- 
2.34.1

Reply via email to