-
Notifications
You must be signed in to change notification settings - Fork 28.6k
[SPARK-33074][SQL] Classify dialect exceptions in JDBC v2 Table Catalog #29952
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
921f88f
b2e7a72
d44ec4c
90fcaf3
ac55879
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one or more | ||
* contributor license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright ownership. | ||
* The ASF licenses this file to You under the Apache License, Version 2.0 | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.apache.spark.sql.jdbc | ||
|
||
import java.sql.SQLException | ||
import java.util.Locale | ||
|
||
import org.apache.spark.sql.AnalysisException | ||
import org.apache.spark.sql.catalyst.analysis.{NoSuchNamespaceException, NoSuchTableException, TableAlreadyExistsException} | ||
|
||
private object H2Dialect extends JdbcDialect { | ||
override def canHandle(url: String): Boolean = | ||
url.toLowerCase(Locale.ROOT).startsWith("jdbc:h2") | ||
|
||
override def classifyException(message: String, e: Throwable): AnalysisException = { | ||
if (e.isInstanceOf[SQLException]) { | ||
// Error codes are from https://www.h2database.com/javadoc/org/h2/api/ErrorCode.html | ||
e.asInstanceOf[SQLException].getErrorCode match { | ||
// TABLE_OR_VIEW_ALREADY_EXISTS_1 | ||
case 42101 => | ||
throw new TableAlreadyExistsException(message, cause = Some(e)) | ||
// TABLE_OR_VIEW_NOT_FOUND_1 | ||
case 42102 => | ||
throw new NoSuchTableException(message, cause = Some(e)) | ||
// SCHEMA_NOT_FOUND_1 | ||
case 90079 => | ||
throw new NoSuchNamespaceException(message, cause = Some(e)) | ||
case _ => | ||
} | ||
} | ||
super.classifyException(message, e) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,7 @@ import scala.collection.mutable.ArrayBuilder | |
import org.apache.commons.lang3.StringUtils | ||
|
||
import org.apache.spark.annotation.{DeveloperApi, Since} | ||
import org.apache.spark.sql.AnalysisException | ||
import org.apache.spark.sql.connector.catalog.TableChange | ||
import org.apache.spark.sql.connector.catalog.TableChange._ | ||
import org.apache.spark.sql.execution.datasources.jdbc.JdbcUtils | ||
|
@@ -253,6 +254,16 @@ abstract class JdbcDialect extends Serializable { | |
val nullable = if (isNullable) "NULL" else "NOT NULL" | ||
s"ALTER TABLE $tableName ALTER COLUMN $columnName SET $nullable" | ||
} | ||
|
||
/** | ||
* Gets a dialect exception, classifies it and wraps it by `AnalysisException`. | ||
* @param message The error message to be placed to the returned exception. | ||
* @param e The dialect specific exception. | ||
* @return `AnalysisException` or its sub-class. | ||
*/ | ||
def classifyException(message: String, e: Throwable): AnalysisException = { | ||
new AnalysisException(message, cause = Some(e)) | ||
} | ||
} | ||
|
||
/** | ||
|
@@ -297,6 +308,7 @@ object JdbcDialects { | |
registerDialect(DerbyDialect) | ||
registerDialect(OracleDialect) | ||
registerDialect(TeradataDialect) | ||
registerDialect(H2Dialect) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since we already have a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you look at
What is the problem to have built-in H2Dialect? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably, not related to this. If we don't want to support H2 officially as a dialect, why do we test it so broadly in Spark.?Maybe it makes sense to switch all internal Spark tests to Derby? |
||
|
||
/** | ||
* Fetch the JdbcDialect class corresponding to a given database url. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shall we be consistent and always put
classifyException
insidewithConnection
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that mixing two conceptually different things will make them consistent.