Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 8 additions & 11 deletions core/src/main/resources/error/error-classes.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
{
"AES_CRYPTO_ERROR" : {
"message" : [ "AES crypto operation failed with: %s" ]
},
"AMBIGUOUS_FIELD_NAME" : {
"message" : [ "Field name %s is ambiguous and has %s matching fields in the struct." ],
"sqlState" : "42000"
Expand Down Expand Up @@ -74,10 +71,6 @@
"INTERNAL_ERROR" : {
"message" : [ "%s" ]
},
"INVALID_AES_KEY_LENGTH" : {
"message" : [ "The key length of aes_encrypt/aes_decrypt should be one of 16, 24 or 32 bytes, but got: %s" ],
"sqlState" : "42000"
},
"INVALID_ARRAY_INDEX" : {
"message" : [ "Invalid index: %s, numElements: %s. If necessary set %s to false to bypass this error." ]
},
Expand All @@ -99,6 +92,10 @@
"INVALID_JSON_SCHEMA_MAPTYPE" : {
"message" : [ "Input schema %s can only contain StringType as a key type for a MapType." ]
},
"INVALID_PARAMETER_VALUE" : {
"message" : [ "The value of parameter(s) '%s' in %s is invalid: %s" ],
"sqlState" : "22023"
},
"MAP_KEY_DOES_NOT_EXIST" : {
"message" : [ "Key %s does not exist. If necessary set %s to false to bypass this error." ]
},
Expand Down Expand Up @@ -144,10 +141,6 @@
"message" : [ "Unrecognized SQL type %s" ],
"sqlState" : "42000"
},
"UNSUPPORTED_AES_MODE" : {
"message" : [ "The AES mode %s with the padding %s is not supported" ],
"sqlState" : "0A000"
},
"UNSUPPORTED_CHANGE_COLUMN" : {
"message" : [ "Please add an implementation for a column change here" ],
"sqlState" : "0A000"
Expand All @@ -156,6 +149,10 @@
"message" : [ "Unsupported data type %s" ],
"sqlState" : "0A000"
},
"UNSUPPORTED_FEATURE" : {
"message" : [ "The feature is not supported: %s" ],
"sqlState" : "0A000"
},
"UNSUPPORTED_LITERAL_TYPE" : {
"message" : [ "Unsupported literal type %s %s" ],
"sqlState" : "0A000"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1905,15 +1905,28 @@ object QueryExecutionErrors {
}

def invalidAesKeyLengthError(actualLength: Int): RuntimeException = {
new SparkRuntimeException("INVALID_AES_KEY_LENGTH", Array(actualLength.toString))
new SparkRuntimeException(
errorClass = "INVALID_PARAMETER_VALUE",
messageParameters = Array(
"key",
"the aes_encrypt/aes_decrypt function",
s"expects a binary value with 16, 24 or 32 bytes, but got ${actualLength.toString} bytes."))
}

def aesModeUnsupportedError(mode: String, padding: String): RuntimeException = {
new SparkRuntimeException("UNSUPPORTED_AES_MODE", Array(mode, padding))
new SparkRuntimeException(
errorClass = "UNSUPPORTED_FEATURE",
messageParameters = Array(
s"AES-$mode with the padding $padding by the aes_encrypt/aes_decrypt function."))
}

def aesCryptoError(detailMessage: String): RuntimeException = {
new SparkRuntimeException("AES_CRYPTO_ERROR", Array(detailMessage))
new SparkRuntimeException(
errorClass = "INVALID_PARAMETER_VALUE",
messageParameters = Array(
"expr, key",
"the aes_encrypt/aes_decrypt function",
s"Detail message: $detailMessage"))
}

def hiveTableWithAnsiIntervalsError(tableName: String): Throwable = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,17 @@ class QueryExecutionErrorsSuite extends QueryTest with SharedSparkSession {
(df1, df2)
}

test("INVALID_AES_KEY_LENGTH: invalid key lengths in AES functions") {
test("INVALID_PARAMETER_VALUE: invalid key lengths in AES functions") {
val (df1, df2) = getAesInputs()
def checkInvalidKeyLength(df: => DataFrame): Unit = {
val e = intercept[SparkException] {
df.collect
}.getCause.asInstanceOf[SparkRuntimeException]
assert(e.getErrorClass === "INVALID_AES_KEY_LENGTH")
assert(e.getSqlState === "42000")
assert(e.getErrorClass === "INVALID_PARAMETER_VALUE")
assert(e.getSqlState === "22023")
assert(e.getMessage.contains(
"The key length of aes_encrypt/aes_decrypt should be one of 16, 24 or 32 bytes"))
"The value of parameter(s) 'key' in the aes_encrypt/aes_decrypt function is invalid: " +
"expects a binary value with 16, 24 or 32 bytes, but got"))
}

// Encryption failure - invalid key length
Expand All @@ -71,17 +72,35 @@ class QueryExecutionErrorsSuite extends QueryTest with SharedSparkSession {
}
}

test("UNSUPPORTED_AES_MODE: unsupported combinations of AES modes and padding") {
test("INVALID_PARAMETER_VALUE: AES decrypt failure - key mismatch") {
val (_, df2) = getAesInputs()
Seq(
("value16", "1234567812345678"),
("value24", "123456781234567812345678"),
("value32", "12345678123456781234567812345678")).foreach { case (colName, key) =>
val e = intercept[SparkException] {
df2.selectExpr(s"aes_decrypt(unbase64($colName), binary('$key'), 'ECB')").collect
}.getCause.asInstanceOf[SparkRuntimeException]
assert(e.getErrorClass === "INVALID_PARAMETER_VALUE")
assert(e.getSqlState === "22023")
assert(e.getMessage.contains(
"The value of parameter(s) 'expr, key' in the aes_encrypt/aes_decrypt function " +
"is invalid: Detail message:"))
}
}

test("UNSUPPORTED_MODE: unsupported combinations of AES modes and padding") {
val key16 = "abcdefghijklmnop"
val key32 = "abcdefghijklmnop12345678ABCDEFGH"
val (df1, df2) = getAesInputs()
def checkUnsupportedMode(df: => DataFrame): Unit = {
val e = intercept[SparkException] {
df.collect
}.getCause.asInstanceOf[SparkRuntimeException]
assert(e.getErrorClass === "UNSUPPORTED_AES_MODE")
assert(e.getErrorClass === "UNSUPPORTED_FEATURE")
assert(e.getSqlState === "0A000")
assert(e.getMessage.matches("""The AES mode \w+ with the padding \w+ is not supported"""))
assert(e.getMessage.matches("""The feature is not supported: AES-\w+ with the padding \w+""" +
" by the aes_encrypt/aes_decrypt function."))
}

// Unsupported AES mode and padding in encrypt
Expand All @@ -93,19 +112,4 @@ class QueryExecutionErrorsSuite extends QueryTest with SharedSparkSession {
checkUnsupportedMode(df2.selectExpr(s"aes_decrypt(value16, '$key16', 'GCM', 'PKCS')"))
checkUnsupportedMode(df2.selectExpr(s"aes_decrypt(value32, '$key32', 'ECB', 'None')"))
}

test("AES_CRYPTO_ERROR: AES decrypt failure - key mismatch") {
val (_, df2) = getAesInputs()
Seq(
("value16", "1234567812345678"),
("value24", "123456781234567812345678"),
("value32", "12345678123456781234567812345678")).foreach { case (colName, key) =>
val e = intercept[SparkException] {
df2.selectExpr(s"aes_decrypt(unbase64($colName), binary('$key'), 'ECB')").collect
}.getCause.asInstanceOf[SparkRuntimeException]
assert(e.getErrorClass === "AES_CRYPTO_ERROR")
assert(e.getSqlState === null)
assert(e.getMessage.contains("AES crypto operation failed"))
}
}
}