Skip to content

Commit 1c4ecae

Browse files
disallow set type using (expr)
Signed-off-by: Aykut Bozkurt <aykut.bozkurt@snowflake.com>
1 parent 91c6093 commit 1c4ecae

2 files changed

Lines changed: 72 additions & 8 deletions

File tree

pg_lake_table/src/ddl/alter_table.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -872,14 +872,29 @@ ErrorIfUnsupportedAlterWritablePgLakeTableStmt(AlterTableStmt *alterStmt,
872872
if (cmd->subtype == AT_AlterColumnType &&
873873
tableType == PG_LAKE_ICEBERG_TABLE_TYPE)
874874
{
875-
ereport(ERROR,
876-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
877-
errmsg("ALTER TABLE %s command not supported for "
878-
"%s tables", cmdTypeStr, tableTypeStr),
879-
errdetail("Allowed type promotions for Iceberg tables are: "
880-
"int -> bigint, float -> double, and "
881-
"decimal(P,S) -> decimal(P',S) where P' > P "
882-
"(wider precision, same scale).")));
875+
ColumnDef *def = (ColumnDef *) cmd->def;
876+
877+
if (def->raw_default != NULL)
878+
{
879+
ereport(ERROR,
880+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
881+
errmsg("ALTER TABLE %s command not supported for "
882+
"%s tables", cmdTypeStr, tableTypeStr),
883+
errdetail("USING requires rewriting data files, "
884+
"but Iceberg schema evolution is a "
885+
"metadata-only operation.")));
886+
}
887+
else
888+
{
889+
ereport(ERROR,
890+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
891+
errmsg("ALTER TABLE %s command not supported for "
892+
"%s tables", cmdTypeStr, tableTypeStr),
893+
errdetail("Allowed type promotions for Iceberg tables "
894+
"are: int -> bigint, float -> double, and "
895+
"decimal(P,S) -> decimal(P',S) where P' > P "
896+
"(wider precision, same scale).")));
897+
}
883898
}
884899
else
885900
{
@@ -1108,6 +1123,13 @@ AllowedAlterColumnTypeForIceberg(Node *arg, Oid relationId)
11081123
ColumnDef *def = (ColumnDef *) cmd->def;
11091124
TypeName *newTypeName = def->typeName;
11101125

1126+
/*
1127+
* Reject USING clause. USING requires rewriting data files, but Iceberg
1128+
* schema evolution is metadata-only so data files are never rewritten.
1129+
*/
1130+
if (def->raw_default != NULL)
1131+
return false;
1132+
11111133
/* resolve the new type OID and typmod */
11121134
int32 newTypMod = 0;
11131135
Oid newTypeOid = InvalidOid;

pg_lake_table/tests/pytests/test_iceberg_ddl.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1832,6 +1832,48 @@ def test_alter_column_type_disallowed_promotions(pg_conn, s3, with_default_locat
18321832
pg_conn.commit()
18331833

18341834

1835+
def test_alter_column_type_using_clause_rejected(pg_conn, s3, with_default_location):
1836+
"""Test that USING clause is rejected for Iceberg type promotions.
1837+
1838+
Iceberg schema evolution is metadata-only; data files are never rewritten,
1839+
so arbitrary USING expressions are not supported.
1840+
"""
1841+
run_command("CREATE SCHEMA test_alter_using;", pg_conn)
1842+
run_command(
1843+
"CREATE TABLE test_alter_using.tbl (a int, b real) USING iceberg;",
1844+
pg_conn,
1845+
)
1846+
run_command("INSERT INTO test_alter_using.tbl VALUES (1, 1.5);", pg_conn)
1847+
pg_conn.commit()
1848+
1849+
# USING with an otherwise-allowed promotion (int -> bigint)
1850+
error = run_command(
1851+
"ALTER TABLE test_alter_using.tbl ALTER COLUMN a TYPE bigint USING a::bigint;",
1852+
pg_conn,
1853+
raise_error=False,
1854+
)
1855+
assert "command not supported for pg_lake_iceberg tables" in str(error)
1856+
assert "USING requires rewriting data files" in str(error)
1857+
pg_conn.rollback()
1858+
1859+
# USING with an expression on an allowed promotion (float -> double)
1860+
error = run_command(
1861+
"ALTER TABLE test_alter_using.tbl ALTER COLUMN b TYPE double precision USING b * 2;",
1862+
pg_conn,
1863+
raise_error=False,
1864+
)
1865+
assert "command not supported for pg_lake_iceberg tables" in str(error)
1866+
assert "USING requires rewriting data files" in str(error)
1867+
pg_conn.rollback()
1868+
1869+
# Verify the table is intact (nothing changed)
1870+
result = run_query("SELECT a, b FROM test_alter_using.tbl;", pg_conn)
1871+
assert result == [[1, 1.5]]
1872+
1873+
run_command("DROP SCHEMA test_alter_using CASCADE;", pg_conn)
1874+
pg_conn.commit()
1875+
1876+
18351877
def test_alter_column_type_same_type_noop(pg_conn, s3, with_default_location):
18361878
"""Test that changing to the same type is allowed (no-op)"""
18371879
run_command("CREATE SCHEMA test_alter_type_noop;", pg_conn)

0 commit comments

Comments
 (0)