Skip to content

Commit 5bb6271

Browse files
dbtsaiviirya
authored andcommitted
[SPARK-56207][SQL] Replace legacy error codes with named errors in DSv2 connector API
### What changes were proposed in this pull request? Replaced 18 _LEGACY_ERROR_TEMP_* error codes in the Data Source V2 (DSv2) connector API with properly named, descriptive error conditions. The affected interfaces are all in sql/catalyst/src/main/java/org/apache/spark/sql/connector/: - Read: Scan, PartitionReaderFactory, ContinuousPartitionReaderFactory - Write: Write, WriteBuilder, DeltaWrite, DeltaWriteBuilder, LogicalWriteInfo - Catalog: SupportsPartitionManagement, SupportsAtomicPartitionManagement - Util: V2ExpressionSQLBuilder New error names follow established Spark conventions (DATASOURCE_*, PARTITION_*, V2_EXPRESSION_SQL_BUILDER_*, UNEXPECTED_*) and are inserted alphabetically into error-conditions.json. All new entries include a sqlState (0A000 for unsupported operations, 42000 for illegal arguments) and messages ending with a period. ### Why are the changes needed? Legacy error codes (_LEGACY_ERROR_TEMP_*) are opaque and hard to search, cross-reference, or document. Named error codes make it easier for users and downstream connectors to identify and handle specific error conditions. ### Does this PR introduce _any_ user-facing change? Yes — error messages now include a sqlState and names are surfaced in error output, but the message text is preserved (with minor normalization: trailing periods added for consistency). ### How was this patch tested? Existing unit and integration tests cover these code paths. No behavioral changes were made. ### Was this patch authored or co-authored using generative AI tooling? Generated-by: Claude Code Closes #54971 from dbtsai/sqlState. Authored-by: DB Tsai <dbtsai@dbtsai.com> Signed-off-by: Liang-Chi Hsieh <viirya@gmail.com>
1 parent f184c25 commit 5bb6271

12 files changed

Lines changed: 134 additions & 111 deletions

File tree

common/utils/src/main/resources/error/error-conditions.json

Lines changed: 108 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,12 +1773,66 @@
17731773
],
17741774
"sqlState" : "42710"
17751775
},
1776+
"DATA_SOURCE_BATCH_SCAN_NOT_SUPPORTED" : {
1777+
"message" : [
1778+
"<description>: Batch scan is not supported."
1779+
],
1780+
"sqlState" : "0A000"
1781+
},
1782+
"DATA_SOURCE_BATCH_WRITE_BUILDER_NOT_SUPPORTED" : {
1783+
"message" : [
1784+
"<class> does not support batch write."
1785+
],
1786+
"sqlState" : "0A000"
1787+
},
1788+
"DATA_SOURCE_BATCH_WRITE_NOT_SUPPORTED" : {
1789+
"message" : [
1790+
"<description>: Batch write is not supported."
1791+
],
1792+
"sqlState" : "0A000"
1793+
},
1794+
"DATA_SOURCE_COLUMNAR_READER_NOT_SUPPORTED" : {
1795+
"message" : [
1796+
"<class> cannot create columnar reader."
1797+
],
1798+
"sqlState" : "0A000"
1799+
},
1800+
"DATA_SOURCE_CONTINUOUS_SCAN_NOT_SUPPORTED" : {
1801+
"message" : [
1802+
"<description>: Continuous scan is not supported."
1803+
],
1804+
"sqlState" : "0A000"
1805+
},
1806+
"DATA_SOURCE_DELTA_BATCH_WRITE_NOT_SUPPORTED" : {
1807+
"message" : [
1808+
"<description>: Delta batch write is not supported."
1809+
],
1810+
"sqlState" : "0A000"
1811+
},
1812+
"DATA_SOURCE_DELTA_WRITE_BUILD_NOT_IMPLEMENTED" : {
1813+
"message" : [
1814+
"<class> does not implement build."
1815+
],
1816+
"sqlState" : "0A000"
1817+
},
17761818
"DATA_SOURCE_EXTERNAL_ERROR" : {
17771819
"message" : [
17781820
"Encountered error when saving to external data source."
17791821
],
17801822
"sqlState" : "KD010"
17811823
},
1824+
"DATA_SOURCE_METADATA_SCHEMA_NOT_IMPLEMENTED" : {
1825+
"message" : [
1826+
"<class> does not implement metadataSchema."
1827+
],
1828+
"sqlState" : "0A000"
1829+
},
1830+
"DATA_SOURCE_MICRO_BATCH_SCAN_NOT_SUPPORTED" : {
1831+
"message" : [
1832+
"<description>: Micro-batch scan is not supported."
1833+
],
1834+
"sqlState" : "0A000"
1835+
},
17821836
"DATA_SOURCE_NOT_EXIST" : {
17831837
"message" : [
17841838
"Data source '<provider>' not found. Please make sure the data source is registered."
@@ -1791,6 +1845,24 @@
17911845
],
17921846
"sqlState" : "42K02"
17931847
},
1848+
"DATA_SOURCE_ROW_ID_SCHEMA_NOT_IMPLEMENTED" : {
1849+
"message" : [
1850+
"<class> does not implement rowIdSchema."
1851+
],
1852+
"sqlState" : "0A000"
1853+
},
1854+
"DATA_SOURCE_STREAMING_WRITE_BUILD_NOT_SUPPORTED" : {
1855+
"message" : [
1856+
"<class> does not support streaming write."
1857+
],
1858+
"sqlState" : "0A000"
1859+
},
1860+
"DATA_SOURCE_STREAMING_WRITE_NOT_SUPPORTED" : {
1861+
"message" : [
1862+
"<description>: Streaming write is not supported."
1863+
],
1864+
"sqlState" : "0A000"
1865+
},
17941866
"DATA_SOURCE_TABLE_SCHEMA_MISMATCH" : {
17951867
"message" : [
17961868
"The schema of the data source table does not match the expected schema. If you are using the DataFrameReader.schema API or creating a table, avoid specifying the schema.",
@@ -5619,6 +5691,12 @@
56195691
],
56205692
"sqlState" : "42000"
56215693
},
5694+
"PARTITION_RENAME_NOT_SUPPORTED" : {
5695+
"message" : [
5696+
"Partition renaming is not supported."
5697+
],
5698+
"sqlState" : "0A000"
5699+
},
56225700
"PARTITION_TRANSFORM_EXPRESSION_NOT_IN_PARTITIONED_BY" : {
56235701
"message" : [
56245702
"The expression <expression> must be inside 'partitionedBy'."
@@ -6952,6 +7030,18 @@
69527030
],
69537031
"sqlState" : "42K09"
69547032
},
7033+
"TRUNCATE_PARTITIONS_NOT_SUPPORTED" : {
7034+
"message" : [
7035+
"Truncating partitions is not supported."
7036+
],
7037+
"sqlState" : "0A000"
7038+
},
7039+
"TRUNCATE_PARTITION_NOT_SUPPORTED" : {
7040+
"message" : [
7041+
"Truncating partition is not supported."
7042+
],
7043+
"sqlState" : "0A000"
7044+
},
69557045
"TUPLE_INVALID_INPUT_SKETCH_BUFFER" : {
69567046
"message" : [
69577047
"Invalid call to <function>; only valid Tuple sketch buffers are supported as inputs (such as those produced by the corresponding `tuple_sketch_agg_*` function)."
@@ -7082,6 +7172,12 @@
70827172
],
70837173
"sqlState" : "XX000"
70847174
},
7175+
"UNEXPECTED_V2_EXPRESSION" : {
7176+
"message" : [
7177+
"Unexpected V2 expression: <expr>."
7178+
],
7179+
"sqlState" : "XX000"
7180+
},
70857181
"UNION_NOT_SUPPORTED_IN_RECURSIVE_CTE" : {
70867182
"message" : [
70877183
"The UNION operator is not yet supported within recursive common table expressions (WITH clauses that refer to themselves, directly or indirectly). Please use UNION ALL instead."
@@ -8314,6 +8410,18 @@
83148410
],
83158411
"sqlState" : "42000"
83168412
},
8413+
"V2_EXPRESSION_SQL_BUILDER_UDAF_NOT_SUPPORTED" : {
8414+
"message" : [
8415+
"<class> does not support user defined aggregate function: <funcName>."
8416+
],
8417+
"sqlState" : "0A000"
8418+
},
8419+
"V2_EXPRESSION_SQL_BUILDER_UDF_NOT_SUPPORTED" : {
8420+
"message" : [
8421+
"<class> does not support user defined function: <funcName>."
8422+
],
8423+
"sqlState" : "0A000"
8424+
},
83178425
"VARIABLE_ALREADY_EXISTS" : {
83188426
"message" : [
83198427
"Cannot create the variable <variableName> because it already exists.",
@@ -10787,91 +10895,6 @@
1078710895
"CaseInsensitiveStringMap is read-only."
1078810896
]
1078910897
},
10790-
"_LEGACY_ERROR_TEMP_3133" : {
10791-
"message" : [
10792-
"<class> does not implement rowIdSchema"
10793-
]
10794-
},
10795-
"_LEGACY_ERROR_TEMP_3134" : {
10796-
"message" : [
10797-
"<class> does not implement metadataSchema"
10798-
]
10799-
},
10800-
"_LEGACY_ERROR_TEMP_3135" : {
10801-
"message" : [
10802-
"<class> does not support batch write"
10803-
]
10804-
},
10805-
"_LEGACY_ERROR_TEMP_3136" : {
10806-
"message" : [
10807-
"<class> does not support streaming write"
10808-
]
10809-
},
10810-
"_LEGACY_ERROR_TEMP_3137" : {
10811-
"message" : [
10812-
"<description>: Batch write is not supported"
10813-
]
10814-
},
10815-
"_LEGACY_ERROR_TEMP_3138" : {
10816-
"message" : [
10817-
"<description>: Streaming write is not supported"
10818-
]
10819-
},
10820-
"_LEGACY_ERROR_TEMP_3139" : {
10821-
"message" : [
10822-
"<description>: Delta batch write is not supported"
10823-
]
10824-
},
10825-
"_LEGACY_ERROR_TEMP_3140" : {
10826-
"message" : [
10827-
"<class> does not implement build"
10828-
]
10829-
},
10830-
"_LEGACY_ERROR_TEMP_3141" : {
10831-
"message" : [
10832-
"<class> does not support user defined function: <funcName>"
10833-
]
10834-
},
10835-
"_LEGACY_ERROR_TEMP_3142" : {
10836-
"message" : [
10837-
"<class> does not support user defined aggregate function: <funcName>"
10838-
]
10839-
},
10840-
"_LEGACY_ERROR_TEMP_3143" : {
10841-
"message" : [
10842-
"Partition renaming is not supported"
10843-
]
10844-
},
10845-
"_LEGACY_ERROR_TEMP_3144" : {
10846-
"message" : [
10847-
"Partition truncate is not supported"
10848-
]
10849-
},
10850-
"_LEGACY_ERROR_TEMP_3145" : {
10851-
"message" : [
10852-
"Partitions truncate is not supported"
10853-
]
10854-
},
10855-
"_LEGACY_ERROR_TEMP_3147" : {
10856-
"message" : [
10857-
"<description>: Batch scan are not supported"
10858-
]
10859-
},
10860-
"_LEGACY_ERROR_TEMP_3148" : {
10861-
"message" : [
10862-
"<description>: Micro-batch scan are not supported"
10863-
]
10864-
},
10865-
"_LEGACY_ERROR_TEMP_3149" : {
10866-
"message" : [
10867-
"<description>: Continuous scan are not supported"
10868-
]
10869-
},
10870-
"_LEGACY_ERROR_TEMP_3150" : {
10871-
"message" : [
10872-
"Cannot create columnar reader."
10873-
]
10874-
},
1087510898
"_LEGACY_ERROR_TEMP_3152" : {
1087610899
"message" : [
1087710900
"Datatype not supported <dataType>"
@@ -11077,11 +11100,6 @@
1107711100
"<value> is not a boolean string."
1107811101
]
1107911102
},
11080-
"_LEGACY_ERROR_TEMP_3207" : {
11081-
"message" : [
11082-
"Unexpected V2 expression: <expr>"
11083-
]
11084-
},
1108511103
"_LEGACY_ERROR_TEMP_3208" : {
1108611104
"message" : [
1108711105
"The number of fields (<numFields>) in the partition identifier is not equal to the partition schema length (<schemaLen>). The identifier might not refer to one partition."

sql/catalyst/src/main/java/org/apache/spark/sql/connector/catalog/SupportsAtomicPartitionManagement.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,6 @@ default boolean purgePartitions(InternalRow[] idents)
127127
*/
128128
default boolean truncatePartitions(InternalRow[] idents)
129129
throws NoSuchPartitionException, SparkUnsupportedOperationException {
130-
throw new SparkUnsupportedOperationException("_LEGACY_ERROR_TEMP_3145");
130+
throw new SparkUnsupportedOperationException("TRUNCATE_PARTITIONS_NOT_SUPPORTED");
131131
}
132132
}

sql/catalyst/src/main/java/org/apache/spark/sql/connector/catalog/SupportsPartitionManagement.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ default boolean renamePartition(InternalRow from, InternalRow to)
157157
throws SparkUnsupportedOperationException,
158158
PartitionsAlreadyExistException,
159159
NoSuchPartitionException {
160-
throw new SparkUnsupportedOperationException("_LEGACY_ERROR_TEMP_3143");
160+
throw new SparkUnsupportedOperationException("PARTITION_RENAME_NOT_SUPPORTED");
161161
}
162162

163163
/**
@@ -172,6 +172,6 @@ default boolean renamePartition(InternalRow from, InternalRow to)
172172
*/
173173
default boolean truncatePartition(InternalRow ident)
174174
throws NoSuchPartitionException, SparkUnsupportedOperationException {
175-
throw new SparkUnsupportedOperationException("_LEGACY_ERROR_TEMP_3144");
175+
throw new SparkUnsupportedOperationException("TRUNCATE_PARTITION_NOT_SUPPORTED");
176176
}
177177
}

sql/catalyst/src/main/java/org/apache/spark/sql/connector/read/PartitionReaderFactory.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.apache.spark.sql.connector.read;
1919

2020
import java.io.Serializable;
21+
import java.util.Map;
2122

2223
import org.apache.spark.SparkUnsupportedOperationException;
2324
import org.apache.spark.annotation.Evolving;
@@ -51,7 +52,8 @@ public interface PartitionReaderFactory extends Serializable {
5152
* {@link InputPartition} class defined for the data source.
5253
*/
5354
default PartitionReader<ColumnarBatch> createColumnarReader(InputPartition partition) {
54-
throw new SparkUnsupportedOperationException("_LEGACY_ERROR_TEMP_3150");
55+
throw new SparkUnsupportedOperationException(
56+
"DATA_SOURCE_COLUMNAR_READER_NOT_SUPPORTED", Map.of("class", getClass().getName()));
5557
}
5658

5759
/**

sql/catalyst/src/main/java/org/apache/spark/sql/connector/read/Scan.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ default String description() {
7878
*/
7979
default Batch toBatch() {
8080
throw new SparkUnsupportedOperationException(
81-
"_LEGACY_ERROR_TEMP_3147", Map.of("description", description()));
81+
"DATA_SOURCE_BATCH_SCAN_NOT_SUPPORTED", Map.of("description", description()));
8282
}
8383

8484
/**
@@ -95,7 +95,7 @@ default Batch toBatch() {
9595
*/
9696
default MicroBatchStream toMicroBatchStream(String checkpointLocation) {
9797
throw new SparkUnsupportedOperationException(
98-
"_LEGACY_ERROR_TEMP_3148", Map.of("description", description()));
98+
"DATA_SOURCE_MICRO_BATCH_SCAN_NOT_SUPPORTED", Map.of("description", description()));
9999
}
100100

101101
/**
@@ -112,7 +112,7 @@ default MicroBatchStream toMicroBatchStream(String checkpointLocation) {
112112
*/
113113
default ContinuousStream toContinuousStream(String checkpointLocation) {
114114
throw new SparkUnsupportedOperationException(
115-
"_LEGACY_ERROR_TEMP_3149", Map.of("description", description()));
115+
"DATA_SOURCE_CONTINUOUS_SCAN_NOT_SUPPORTED", Map.of("description", description()));
116116
}
117117

118118
/**

sql/catalyst/src/main/java/org/apache/spark/sql/connector/read/streaming/ContinuousPartitionReaderFactory.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
package org.apache.spark.sql.connector.read.streaming;
1919

20+
import java.util.Map;
21+
2022
import org.apache.spark.SparkUnsupportedOperationException;
2123
import org.apache.spark.annotation.Evolving;
2224
import org.apache.spark.sql.catalyst.InternalRow;
@@ -38,6 +40,7 @@ public interface ContinuousPartitionReaderFactory extends PartitionReaderFactory
3840

3941
@Override
4042
default ContinuousPartitionReader<ColumnarBatch> createColumnarReader(InputPartition partition) {
41-
throw new SparkUnsupportedOperationException("_LEGACY_ERROR_TEMP_3150");
43+
throw new SparkUnsupportedOperationException(
44+
"DATA_SOURCE_COLUMNAR_READER_NOT_SUPPORTED", Map.of("class", getClass().getName()));
4245
}
4346
}

sql/catalyst/src/main/java/org/apache/spark/sql/connector/util/V2ExpressionSQLBuilder.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -319,20 +319,20 @@ protected String visitInverseDistributionFunction(
319319
protected String visitUserDefinedScalarFunction(
320320
String funcName, String canonicalName, String[] inputs) {
321321
throw new SparkUnsupportedOperationException(
322-
"_LEGACY_ERROR_TEMP_3141",
323-
Map.of("class", this.getClass().getSimpleName(), "funcName", funcName));
322+
"V2_EXPRESSION_SQL_BUILDER_UDF_NOT_SUPPORTED",
323+
Map.of("class", this.getClass().getName(), "funcName", funcName));
324324
}
325325

326326
protected String visitUserDefinedAggregateFunction(
327327
String funcName, String canonicalName, boolean isDistinct, String[] inputs) {
328328
throw new SparkUnsupportedOperationException(
329-
"_LEGACY_ERROR_TEMP_3142",
330-
Map.of("class", this.getClass().getSimpleName(), "funcName", funcName));
329+
"V2_EXPRESSION_SQL_BUILDER_UDAF_NOT_SUPPORTED",
330+
Map.of("class", this.getClass().getName(), "funcName", funcName));
331331
}
332332

333333
protected String visitUnexpectedExpr(Expression expr) throws IllegalArgumentException {
334334
throw new SparkIllegalArgumentException(
335-
"_LEGACY_ERROR_TEMP_3207", Map.of("expr", String.valueOf(expr)));
335+
"UNEXPECTED_V2_EXPRESSION", Map.of("expr", String.valueOf(expr)));
336336
}
337337

338338
protected String visitPartitionPredicate(PartitionPredicate partitionPredicate) {

sql/catalyst/src/main/java/org/apache/spark/sql/connector/write/DeltaWrite.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@ public interface DeltaWrite extends Write {
3232
@Override
3333
default DeltaBatchWrite toBatch() {
3434
throw new SparkUnsupportedOperationException(
35-
"_LEGACY_ERROR_TEMP_3139", Map.of("description", description()));
35+
"DATA_SOURCE_DELTA_BATCH_WRITE_NOT_SUPPORTED", Map.of("description", description()));
3636
}
3737
}

sql/catalyst/src/main/java/org/apache/spark/sql/connector/write/DeltaWriteBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@ public interface DeltaWriteBuilder extends WriteBuilder {
3232
@Override
3333
default DeltaWrite build() {
3434
throw new SparkUnsupportedOperationException(
35-
"_LEGACY_ERROR_TEMP_3140", Map.of("class", getClass().getName()));
35+
"DATA_SOURCE_DELTA_WRITE_BUILD_NOT_IMPLEMENTED", Map.of("class", getClass().getName()));
3636
}
3737
}

0 commit comments

Comments
 (0)