Milos Stojanovic created SPARK-60089:
----------------------------------------

             Summary: Surface remote JDBC insufficient-privilege errors as a 
dedicated error class
                 Key: SPARK-60089
                 URL: https://issues.apache.org/jira/browse/SPARK-60089
             Project: Spark
          Issue Type: Improvement
          Components: SQL
    Affects Versions: 4.2.0
            Reporter: Milos Stojanovic


When \{{JDBCRDD.resolveTable}} resolves the output schema of a JDBC read, it 
classifies driver errors through dialect hooks: \{{isObjectNotFoundException}}, 
\{{isNotSelectableObjectException}} and \{{isSyntaxErrorBestEffort}}. The last 
one raises \{{JDBC_EXTERNAL_ENGINE_SYNTAX_ERROR}}.

A permission denial from the remote engine has no hook of its own, so it ends 
up as a different error depending on the dialect:
* Dialects that treat class-42 or \{{42000}} SQLSTATEs as syntax errors (MySQL, 
Oracle, Snowflake, Teradata, DB2, Databricks) report it as 
\{{JDBC_EXTERNAL_ENGINE_SYNTAX_ERROR}}. MySQL, for example, returns SQLSTATE 
\{{42000}} for both syntax errors and access-denied errors.
* PostgreSQL has propagated \{{42501}} as an unclassified driver error since 
SPARK-59336. Through the JDBC catalog it surfaces as 
\{{FAILED_JDBC.LOAD_TABLE}}, and the driver message is only in the cause chain.

In both cases callers can't tell "the user lacks privileges" apart from "the 
SQL is invalid".

h3. Proposal

Follow the existing syntax-error path:
* Add \{{JdbcDialect.isInsufficientPrivilegeException(e: SQLException): 
Boolean}}, defaulting to \{{false}}.
* Check it first in \{{JDBCRDD.resolveTable}}, before the not-found and 
syntax-error checks, and raise a new 
\{{JDBC_EXTERNAL_ENGINE_INSUFFICIENT_PRIVILEGE}} error (SQLSTATE \{{42501}}). 
The error carries the pushed-down query, the remote SQLSTATE and the remote 
message.
* \{{AggregatedDialect}} returns true if any of its delegate dialects 
recognizes the error, so a user-registered dialect that doesn't override the 
hook can't turn off built-in detection.
* Per-dialect detection:

||Dialect||Codes||
|PostgreSQL|SQLSTATE 42501|
|MySQL / MariaDB|1044, 1142, 1143, 1227, 1370|
|SQL Server|229, 230, 262, 297, 300|
|Oracle|ORA-01031|
|Snowflake|3001|
|Teradata|3523, 3524, 5315|
|DB2|-551, -552|
|Databricks|SQLSTATE 42501, or INSUFFICIENT_PERMISSIONS in the message|

Oracle ORA-00942 and Snowflake 2003 ("does not exist or not authorized") are 
ambiguous, so they stay classified as object-not-found.

This can't be a new subclass of \{{JDBC_EXTERNAL_ENGINE_SYNTAX_ERROR}}, because 
SQLSTATE is defined per error class and that class uses \{{42000}}.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to