Repository navigation
[SPARK-60386][SQL] Enforce FILE EXTERNAL in table columns and reject FILE where it would need an ordering - #59640
Open
dejankrak-db wants to merge 2 commits into
Open
dejankrak-db wants to merge 2 commits into
dejankrak-db wants to merge 2 commits into
Conversation
…FILE where it would need an ordering Co-authored-by: Isaac <no-reply@databricks.com>
…tion and clustering columns Co-authored-by: Isaac <no-reply@databricks.com>
Contributor
Author
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes were proposed in this pull request?
Part 2 of the FileType SPIP (SPARK-59132), following the Catalyst type added in #59305. The SPIP requires the
EXTERNALkeyword when a FILE column is declared in a table, and gives FileType no defined ordering. This PR enforces both at analysis time.Table columns:
FILE EXTERNAL:CREATE TABLE,REPLACE TABLE,ALTER TABLE ADD COLUMNSandALTER TABLE REPLACE COLUMNSfail withFILE_TYPE_MISSING_QUALIFIER. The check is inCheckAnalysisfor V2 tables, inPreprocessTableCreationfor V1 tables, and next to the existingfailUnsupportedDataTypecall inAddColumns/ReplaceColumns.CREATE TABLE AS SELECTcannot store a FILE without a qualifier, as one produced byCAST(... AS FILE)(FILE_TYPE_UNKNOWN_WRITE).CREATE TABLEfor V1 and V2 tables (including V2 transforms such asbucket) and inALTER TABLE ... CLUSTER BY(FILE_TYPE_UNSUPPORTED_COLUMN_USAGE.PARTITION_COLUMNand.CLUSTERING_COLUMN). A FILE-specific error is used rather thanINVALID_PARTITION_COLUMN_DATA_TYPE, which V1 file sources raised before, so the error says why the column is rejected.Routines:
FILE, as the SPIP specifies.CREATE FUNCTIONrejectsFILE EXTERNALin its parameter or return types (FILE_TYPE_IN_ROUTINE_SIGNATURE_UNSUPPORTED_QUALIFIER), and a FILE in a map key of its return type (FILE_TYPE_IN_ROUTINE_SIGNATURE_UNSUPPORTED_MAP_KEY).spark.udf.register/spark.udtf.registerand, for UDFs that are not registered, whenCheckAnalysissees them in a query. A non-scalar Python UDF is skipped, as its data type is the schema of the rows it returns.No ordering, following the existing checks for VARIANT:
TypeUtils.checkForMapKeyType(DATATYPE_MISMATCH.INVALID_MAP_KEY_TYPE).ExprUtils.checkValidGroupingExprs(GROUP_EXPRESSION_TYPE_IS_NOT_ORDERABLE).INTERSECT,EXCEPTandDISTINCT:CheckAnalysisandOperatorWithUncomparableTypeValidatorof the single-pass resolver (UNSUPPORTED_FEATURE.SET_OPERATION_ON_FILE_TYPE).DISTRIBUTE BY/repartition:CheckAnalysisandRepartitionByExpressionResolver(UNSUPPORTED_FEATURE.PARTITION_BY_FILE).HashExpression.checkInputDataTypes(DATATYPE_MISMATCH.HASH_FILE_TYPE), which also guards hashes the planner inserts.PARTITION BY/ORDER BYneed no change: FileType is not orderable, so they already fail withDATATYPE_MISMATCH.INVALID_ORDERING_TYPEorEXPRESSION_TYPE_IS_NOT_ORDERABLE.ALTER COLUMN ... TYPE FILEalready fails withNOT_SUPPORTED_CHANGE_COLUMN. This PR adds tests for these.count(DISTINCT f)andcollect_set(f), are not rejected here. They cannot run before FILE has a physical representation, and whether to reject them is left to that part.The
FileTypeScaladoc is updated to describe these rules as current rather than planned.Why are the changes needed?
The SPIP defines a FILE column of a table as an external file reference, and a bare
FILE(the unknown mode) as the type of an expression or a UDF result, so a table should never store a bareFILE. FileType has no defined ordering, so operations that compare, group or hash values must fail clearly rather than operate on the underlying struct.Does this PR introduce any user-facing change?
No relative to released versions. The FILE type is only recognized when
spark.sql.fileType.enabledis true, which is the default only in tests. Relative to master, the statements and operations listed above now fail with the errors listed above when the type is enabled.How was this patch tested?
Added
FileTypeRestrictionsSuite, covering each rule for V1 and V2 tables where both apply, nested FILE types, and the cases that are still accepted (FILE EXTERNALcolumns, a FILE map value, a function declaring a plainFILE). Also ranSparkThrowableSuite,AnalysisErrorSuite,ComplexTypeSuite,HashExpressionsSuite,TypeUtilsSuite,UDFSuite,SQLFunctionSuite,VariantSuite,DataSourceV2SQLSuiteV1Filter,CreateTableAsSelectSuite,PartitionedWriteSuiteand the V1 and V2 command suites underorg.apache.spark.sql.execution.command.Was this patch authored or co-authored using generative AI tooling?
Generated-by: Isaac
This pull request and its description were written by Isaac.