Print out error position for some ALTER TABLE ALTER COLUMN type
authorMichael Paquier <michael@paquier.xyz>
Mon, 27 Jan 2025 04:51:23 +0000 (13:51 +0900)
committerMichael Paquier <michael@paquier.xyz>
Mon, 27 Jan 2025 04:51:23 +0000 (13:51 +0900)
A ParseState exists in ATPrepAlterColumnType() since its introduction
in 077db40fa1f3, and it has never relied on a query string that could be
used to point at a location in the origin string on error.

The output of some regression tests are updated, showing the error
location where applicable.  Six error strings are upgraded with the
error location.

Author: Jian He
Discussion: https://postgr.es/m/CACJufxGfbPfWLjcEz33G9eW_epDW0UDi2H05i9eSTPKGJ4rxSA@mail.gmail.com

src/backend/commands/tablecmds.c
src/test/regress/expected/alter_table.out
src/test/regress/expected/generated_stored.out
src/test/regress/expected/typed_table.out

index 96a48ba82c1261d063d8bf1daa9a00989ffe80c5..d617c4bc63df23132b9e4bf82dc1dd08ff510f93 100644 (file)
@@ -13410,10 +13410,13 @@ 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);
@@ -13421,7 +13424,8 @@ ATPrepAlterColumnType(List **wqueue,
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_COLUMN),
                 errmsg("column \"%s\" of relation \"%s\" does not exist",
-                       colName, RelationGetRelationName(rel))));
+                       colName, RelationGetRelationName(rel)),
+                parser_errposition(pstate, def->location)));
    attTup = (Form_pg_attribute) GETSTRUCT(tuple);
    attnum = attTup->attnum;
 
@@ -13429,8 +13433,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
@@ -13440,7 +13444,8 @@ ATPrepAlterColumnType(List **wqueue,
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_COLUMN_DEFINITION),
                 errmsg("cannot specify USING when altering type of generated column"),
-                errdetail("Column \"%s\" is a generated column.", colName)));
+                errdetail("Column \"%s\" is a generated column.", colName),
+                parser_errposition(pstate, def->location)));
 
    /*
     * Don't alter inherited columns.  At outer level, there had better not be
@@ -13450,8 +13455,8 @@ ATPrepAlterColumnType(List **wqueue,
    if (attTup->attinhcount > 0 && !recursing)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
-                errmsg("cannot alter inherited column \"%s\"",
-                       colName)));
+                errmsg("cannot alter inherited column \"%s\"", colName),
+                parser_errposition(pstate, def->location)));
 
    /* Don't alter columns used in the partition key */
    if (has_partition_attrs(rel,
@@ -13460,17 +13465,18 @@ ATPrepAlterColumnType(List **wqueue,
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
                 errmsg("cannot alter column \"%s\" because it is part of the partition key of relation \"%s\"",
-                       colName, RelationGetRelationName(rel))));
+                       colName, RelationGetRelationName(rel)),
+                parser_errposition(pstate, def->location)));
 
    /* 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,
index dd8cdec29057d68dee6a43709aa825c1980445bb..362f38856d294a4ee9c38cc11c8f2c8fea5f1cef 100644 (file)
@@ -3426,10 +3426,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           
@@ -3895,10 +3901,14 @@ ALTER TABLE partitioned DROP COLUMN a;
 ERROR:  cannot drop column "a" because it is part of the partition key of relation "partitioned"
 ALTER TABLE partitioned ALTER COLUMN a TYPE char(5);
 ERROR:  cannot alter column "a" because it is part of the partition key of relation "partitioned"
+LINE 1: ALTER TABLE partitioned ALTER COLUMN a TYPE char(5);
+                                             ^
 ALTER TABLE partitioned DROP COLUMN b;
 ERROR:  cannot drop column "b" because it is part of the partition key of relation "partitioned"
 ALTER TABLE partitioned ALTER COLUMN b TYPE char(5);
 ERROR:  cannot alter column "b" because it is part of the partition key of relation "partitioned"
+LINE 1: ALTER TABLE partitioned ALTER COLUMN b TYPE char(5);
+                                             ^
 -- specifying storage parameters for partitioned tables is not supported
 ALTER TABLE partitioned SET (fillfactor=100);
 ERROR:  cannot specify storage parameters for a partitioned table
@@ -4423,6 +4433,8 @@ ALTER TABLE part_2 RENAME COLUMN b to c;
 ERROR:  cannot rename inherited column "b"
 ALTER TABLE part_2 ALTER COLUMN b TYPE text;
 ERROR:  cannot alter inherited column "b"
+LINE 1: ALTER TABLE part_2 ALTER COLUMN b TYPE text;
+                                        ^
 -- cannot add NOT NULL or check constraints to *only* the parent, when
 -- partitions exist
 ALTER TABLE ONLY list_parted2 ALTER b SET NOT NULL;
@@ -4484,6 +4496,8 @@ ALTER TABLE list_parted2 DROP COLUMN b;
 ERROR:  cannot drop column "b" because it is part of the partition key of relation "part_5"
 ALTER TABLE list_parted2 ALTER COLUMN b TYPE text;
 ERROR:  cannot alter column "b" because it is part of the partition key of relation "part_5"
+LINE 1: ALTER TABLE list_parted2 ALTER COLUMN b TYPE text;
+                                              ^
 -- dropping non-partition key columns should be allowed on the parent table.
 ALTER TABLE list_parted DROP COLUMN b;
 SELECT * FROM list_parted;
index 43db7442a670b339ca9d7bbdb97bdcb72f2c332f..7653326420e7d6c1c0f5f789e70204394ce60e2b 100644 (file)
@@ -1124,6 +1124,8 @@ SELECT * FROM gtest27;
 
 ALTER TABLE gtest27 ALTER COLUMN x TYPE boolean USING x <> 0;  -- error
 ERROR:  cannot specify USING when altering type of generated column
+LINE 1: ALTER TABLE gtest27 ALTER COLUMN x TYPE boolean USING x <> 0...
+                                         ^
 DETAIL:  Column "x" is a generated column.
 ALTER TABLE gtest27 ALTER COLUMN x DROP DEFAULT;  -- error
 ERROR:  column "x" of relation "gtest27" is a generated column
index aa6150b853c60e637c01b4dd10726eca8b9efed3..885f085e15421597b1da52129304992b7ef66bba 100644 (file)
@@ -38,6 +38,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