Skip to content

Commit

Permalink
[opt](jdbc catalog) Change jdbc Driver loading to Java code
Browse files Browse the repository at this point in the history
  • Loading branch information
zy-kkk committed Jan 13, 2025
1 parent 87858e5 commit 47f3f0d
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 19 deletions.
22 changes: 6 additions & 16 deletions be/src/vec/exec/vjdbc_connector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,23 +119,13 @@ Status JdbcConnector::open(RuntimeState* state, bool read) {
// Add a scoped cleanup jni reference object. This cleans up local refs made below.
JniLocalFrame jni_frame;
{
std::string local_location;
std::hash<std::string> hash_str;
auto* function_cache = UserFunctionCache::instance();
if (_conn_param.resource_name.empty()) {
// for jdbcExternalTable, _conn_param.resource_name == ""
// so, we use _conn_param.driver_path as key of jarpath
SCOPED_RAW_TIMER(&_jdbc_statistic._load_jar_timer);
RETURN_IF_ERROR(function_cache->get_jarpath(
std::abs((int64_t)hash_str(_conn_param.driver_path)), _conn_param.driver_path,
_conn_param.driver_checksum, &local_location));
std::string driver_path;

if (_conn_param.driver_path.find(":/") == std::string::npos) {
driver_path = "file://" + config::jdbc_drivers_dir + "/" + _conn_param.driver_path;
} else {
SCOPED_RAW_TIMER(&_jdbc_statistic._load_jar_timer);
RETURN_IF_ERROR(function_cache->get_jarpath(
std::abs((int64_t)hash_str(_conn_param.resource_name)), _conn_param.driver_path,
_conn_param.driver_checksum, &local_location));
driver_path = _conn_param.driver_path;
}
VLOG_QUERY << "driver local path = " << local_location;

TJdbcExecutorCtorParams ctor_params;
ctor_params.__set_statement(_sql_str);
Expand All @@ -144,7 +134,7 @@ Status JdbcConnector::open(RuntimeState* state, bool read) {
ctor_params.__set_jdbc_user(_conn_param.user);
ctor_params.__set_jdbc_password(_conn_param.passwd);
ctor_params.__set_jdbc_driver_class(_conn_param.driver_class);
ctor_params.__set_driver_path(local_location);
ctor_params.__set_driver_path(driver_path);
if (state == nullptr) {
ctor_params.__set_batch_size(read ? 1 : 0);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

import org.apache.doris.cloud.security.SecurityChecker;
import org.apache.doris.common.exception.InternalException;
import org.apache.doris.common.jni.utils.UdfUtils;
import org.apache.doris.common.jni.vec.ColumnType;
import org.apache.doris.common.jni.vec.ColumnValueConverter;
import org.apache.doris.common.jni.vec.VectorColumn;
Expand All @@ -28,6 +27,7 @@
import org.apache.doris.thrift.TJdbcOperation;

import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.log4j.Logger;
import org.apache.thrift.TDeserializer;
Expand All @@ -38,6 +38,8 @@
import java.io.FileNotFoundException;
import java.lang.reflect.Array;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.Date;
Expand All @@ -58,6 +60,7 @@ public abstract class BaseJdbcExecutor implements JdbcExecutor {
private static final TBinaryProtocol.Factory PROTOCOL_FACTORY = new TBinaryProtocol.Factory();
private HikariDataSource hikariDataSource = null;
private final byte[] hikariDataSourceLock = new byte[0];
private ClassLoader classLoader = null;
private Connection conn = null;
protected JdbcDataSourceConfig config;
protected PreparedStatement preparedStatement = null;
Expand All @@ -69,6 +72,7 @@ public abstract class BaseJdbcExecutor implements JdbcExecutor {
protected int batchSizeNum = 0;
protected int curBlockRows = 0;
protected String jdbcDriverVersion;
private static final Map<URL, ClassLoader> classLoaderMap = Maps.newConcurrentMap();

public BaseJdbcExecutor(byte[] thriftParams) throws Exception {
setJdbcDriverSystemProperties();
Expand Down Expand Up @@ -299,8 +303,7 @@ private void init(JdbcDataSourceConfig config, String sql) throws JdbcExecutorEx
ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
String hikariDataSourceKey = config.createCacheKey();
try {
ClassLoader parent = getClass().getClassLoader();
ClassLoader classLoader = UdfUtils.getClassLoader(config.getJdbcDriverUrl(), parent);
initializeClassLoader(config);
Thread.currentThread().setContextClassLoader(classLoader);
hikariDataSource = JdbcDataSource.getDataSource().getSource(hikariDataSourceKey);
if (hikariDataSource == null) {
Expand Down Expand Up @@ -358,6 +361,22 @@ private void init(JdbcDataSourceConfig config, String sql) throws JdbcExecutorEx
}
}

private synchronized void initializeClassLoader(JdbcDataSourceConfig config)
throws MalformedURLException, FileNotFoundException {
try {
URL[] urls = {new URL(config.getJdbcDriverUrl())};
if (classLoaderMap.containsKey(urls[0])) {
this.classLoader = classLoaderMap.get(urls[0]);
} else {
ClassLoader parent = getClass().getClassLoader();
this.classLoader = URLClassLoader.newInstance(urls, parent);
classLoaderMap.put(urls[0], this.classLoader);
}
} catch (MalformedURLException e) {
throw new RuntimeException("Error loading JDBC driver.", e);
}
}

protected void setValidationQuery(HikariDataSource ds) {
ds.setConnectionTestQuery("SELECT 1");
}
Expand Down

0 comments on commit 47f3f0d

Please sign in to comment.