Disallow USING clause when altering type of generated column
authorPeter Eisentraut <[email protected]>
Thu, 29 Aug 2024 06:38:29 +0000 (08:38 +0200)
committerPeter Eisentraut <[email protected]>
Thu, 29 Aug 2024 07:03:06 +0000 (09:03 +0200)
This does not make sense.  It would write the output of the USING
clause into the converted column, which would violate the generation
expression.  This adds a check to error out if this is specified.

There was a test for this, but that test errored out for a different
reason, so it was not effective.

Reported-by: Jian He <[email protected]>
Reviewed-by: Yugo NAGATA <[email protected]>
Discussion: https://www.postgresql.org/message-id/flat/c7083982-69f4-4b14-8315-f9ddb20b9834%40eisentraut.org

src/backend/commands/tablecmds.c
src/test/regress/expected/generated.out

index d3d9e2a89b442516a794e6ed91ba2e667427a5dd..78d529c22c022370379fd1cc628edce91b9f3937 100644 (file)
@@ -10953,6 +10953,16 @@ ATPrepAlterColumnType(List **wqueue,
                 errmsg("cannot alter system column \"%s\"",
                        colName)));
 
+   /*
+    * Cannot specify USING when altering type of a generated column, because
+    * that would violate the generation expression.
+    */
+   if (attTup->attgenerated && def->cooked_default)
+       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)));
+
    /*
     * Don't alter inherited columns.  At outer level, there had better not be
     * any inherited definition; when recursing, we assume this was checked at
@@ -11029,11 +11039,12 @@ ATPrepAlterColumnType(List **wqueue,
                        (errcode(ERRCODE_DATATYPE_MISMATCH),
                         errmsg("column \"%s\" cannot be cast automatically to type %s",
                                colName, format_type_be(targettype)),
+                        !attTup->attgenerated ?
                /* translator: USING is SQL, don't translate it */
                         errhint("You might need to specify \"USING %s::%s\".",
                                 quote_identifier(colName),
                                 format_type_with_typemod(targettype,
-                                                         targettypmod))));
+                                                         targettypmod)) : 0));
        }
 
        /* Fix collations after all else */
index 242cb6fc553f60edaa10d1e3c1acac58d03dfcdd..1c06683c9d09bb680f1022bc8a182d13d25c04e3 100644 (file)
@@ -747,7 +747,8 @@ SELECT * FROM gtest27;
 (2 rows)
 
 ALTER TABLE gtest27 ALTER COLUMN x TYPE boolean USING x <> 0;  -- error
-ERROR:  generation expression for column "x" cannot be cast automatically to type boolean
+ERROR:  cannot specify USING when altering type of generated column
+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
 -- It's possible to alter the column types this way: