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)