Zoltán Borók-Nagy created IMPALA-15618:
------------------------------------------

             Summary: Iceberg: UUID-typed DEFAULT on a UUID column passes 
analysis and fails late in catalogd
                 Key: IMPALA-15618
                 URL: https://issues.apache.org/jira/browse/IMPALA-15618
             Project: IMPALA
          Issue Type: Bug
          Components: Frontend
            Reporter: Zoltán Borók-Nagy


On Iceberg V3 tables, analysis rejects a DEFAULT on a UUID column only when the 
default is a STRING literal. A UUID-typed default such as {{DEFAULT CAST('...' 
AS UUID)}} passes analysis and fails in catalogd with a confusing 
literal-parsing error. For CREATE TABLE the error is wrapped as an HMS RPC 
failure. {{DEFAULT NULL}} on a UUID column fails the same way.

Repro on master:
{code:sql}
create table t (id int, u uuid default 
cast('12345678-1234-5678-1234-567812345678' as uuid))
  stored by iceberg tblproperties('format-version'='3');
{code}
{noformat}
ImpalaRuntimeException: Error making 'createTable' RPC to Hive Metastore:
CAUSED BY: ImpalaRuntimeException: Cannot parse default value 
'12345678-1234-5678-1234-567812345678' as UUID: Literals of type 'UUID' not 
supported.
{noformat}

{code:sql}
create table t (id int, u uuid) stored by iceberg 
tblproperties('format-version'='3');
alter table t add column u2 uuid default 
cast('12345678-1234-5678-1234-567812345678' as uuid);
alter table t alter column u set default 
cast('12345678-1234-5678-1234-567812345678' as uuid);
{code}
{noformat}
ImpalaRuntimeException: Failed to parse default value 
'12345678-1234-5678-1234-567812345678' for column 'u2': Cannot parse default 
value '12345678-1234-5678-1234-567812345678' as UUID: Literals of type 'UUID' 
not supported.
ImpalaRuntimeException: Cannot parse default value 
'12345678-1234-5678-1234-567812345678' as UUID: Literals of type 'UUID' not 
supported.
{noformat}

With {{default null}} instead of the CAST, all three statements fail with 
"Cannot parse default value 'NULL' as UUID: Literals of type 'UUID' not 
supported." (DEFAULT NULL is mishandled for other column types too; that is a 
separate issue.)

A STRING default is rejected during analysis, as expected:
{code:sql}
create table t2 (id int, u uuid default '12345678-1234-5678-1234-567812345678')
  stored by iceberg tblproperties('format-version'='3');
{code}
{noformat}
AnalysisException: Default value '12345678-1234-5678-1234-567812345678' (type: 
STRING) is not compatible with column 'u' (type: UUID).
{noformat}

Expected: every DEFAULT on a UUID column is rejected during analysis with a 
clear AnalysisException, as for BINARY ("Default values are not supported for 
type: BINARY").

*Analysis*
CreateTableStmt.analyzeIcebergColumns(), AlterTableAddColsStmt.analyze() and 
AlterTableAlterColStmt.analyze() call 
IcebergSchemaConverter.validateIcebergDdlDefaultType() for columns with a 
DEFAULT. It rejects complex types, TIMESTAMP and BINARY, but not UUID. 
ColumnDef.analyze() rejects only STRING defaults for UUID columns. So the 
default reaches catalogd, where 
IcebergSchemaConverter.parseStringToIcebergLiteral() (called from 
createIcebergField(), IcebergCatalogOpExecutor.addColumns() and 
IcebergCatalogOpExecutor.alterColumn()) calls 
LiteralExpr.createFromUnescapedStr(). LiteralExpr.createFromStr() has no UUID 
case and throws "Literals of type 'UUID' not supported." 
IcebergSchemaConverter.literalExprToIcebergLiteral() has no UUID case either.

Impala cannot write tables that have UUID columns 
(IcebergUtil.validateIcebergTableForInsert(): "Impala does not support writing 
UUID columns"), so a UUID write default would be of no use to Impala.

*Suggested fix*
Reject UUID in IcebergSchemaConverter.validateIcebergDdlDefaultType() with 
"Default values are not supported for type: UUID". This also covers DEFAULT 
NULL. Add AnalyzeDDLTest cases for CREATE TABLE, ADD COLUMN and ALTER COLUMN 
SET DEFAULT with CAST(... AS UUID) and NULL defaults. Today only CREATE TABLE 
with a STRING default is tested.

While there:
* The UUID branch in IcebergUtil.resolveWriteDefault() is unreachable. INSERT 
(InsertStmt.analyzeTableForInsert()) and MERGE (IcebergMergeImpl.analyze()) 
call IcebergUtil.validateIcebergTableForInsert() before they resolve write 
defaults, and it rejects every table with a UUID column.
* No test reads a UUID initial-default for a data file that lacks the column. 
The iceberg_uuid_test fixture defines an initial-default for uuid_col, but 
every data file in it contains uuid_col.




--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to