This is an automated email from the ASF dual-hosted git repository.
CalvinKirs pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 994630bb2ef [refactor](plugin) Remove FE cloud auto-download for JDBC
drivers and Java UDF (#66596)
994630bb2ef is described below
commit 994630bb2ef85aa70487e4004c807991e85b4ce2
Author: Calvin Kirs <[email protected]>
AuthorDate: Tue Aug 11 10:21:00 2026 +0800
[refactor](plugin) Remove FE cloud auto-download for JDBC drivers and Java
UDF (#66596)
### What problem does this PR solve?
Related PR: #54304
Problem Summary:
Removes the FE cloud plugin auto-download feature.
In cloud mode, when a JDBC driver or a Java UDF was referenced by bare
jar name, FE tried to fetch it from the cluster's object storage
(`plugins/jdbc_drivers/...`, `plugins/java_udf/...`) instead of
resolving it locally.
Two reasons to drop it:
1. It has had no real users for a long time.
2. The kernel should not be responsible for distributing peripheral
plugins. Staging third-party jars (JDBC drivers, UDF jars) onto the
nodes is a deployment / ops concern, and non-cloud deployments have
always done it that way.
It was also broken in practice: the downloader built S3 properties
without a scheme hint, so the filesystem SPI routed them to
`HdfsProperties` and the download failed with a `ClassCastException`
surfaced as `Cannot download JDBC driver from cloud: ...`.
What is removed:
- `CloudPluginDownloader` + its unit test
- `JdbcResource` — the JDBC driver cloud-download branch
- `CreateFunctionCommand` — the Java UDF cloud-download branch
-
`regression-test/suites/plugin_p1/test_cloud_plugin_auto_download.groovy`
FE-side plugin resolution is now purely local and identical in cloud and
non-cloud mode.
The BE side is deliberately left untouched in this PR.
### Release note
FE no longer auto-downloads JDBC drivers or Java UDF jars from object
storage in cloud mode. Place the jar under
`$DORIS_HOME/plugins/jdbc_drivers/` or `$DORIS_HOME/plugins/java_udf/`
(or use a full URL such as `file://` / `http://`), the same way
non-cloud deployments already do. A missing JDBC driver is now reported
as `JDBC driver file does not exist: <name>`.
### Check List (For Author)
- Test <!-- At least one of them must be included. -->
- [ ] Regression test
- [ ] Unit Test
- [ ] Manual test (add detailed scripts or steps below)
- [x] No need to test or manual test. Explain why:
- [ ] This is a refactor/code format and no logic has been changed.
- [ ] Previous test can cover this change.
- [ ] No code files have been changed.
- [x] Other reason: this removes a feature and its tests; the remaining
local-resolution path is already covered by existing JDBC catalog and
UDF tests.
- Behavior changed:
- [ ] No.
- [x] Yes. In cloud mode, a bare jar name is no longer fetched from
object storage by FE; it must exist locally under the plugins directory.
- Does this need documentation?
- [ ] No.
- [x] Yes. <!-- Add document PR link here. eg:
https://github.com/apache/doris-website/pull/1214 -->
---
.../org/apache/doris/catalog/JdbcResource.java | 14 --
.../doris/common/plugin/CloudPluginDownloader.java | 157 -------------------
.../plans/commands/CreateFunctionCommand.java | 16 --
.../common/plugin/CloudPluginDownloaderTest.java | 173 ---------------------
.../test_cloud_plugin_auto_download.groovy | 121 --------------
5 files changed, 481 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/catalog/JdbcResource.java
b/fe/fe-core/src/main/java/org/apache/doris/catalog/JdbcResource.java
index 0141d33d276..43ecf7d5cd8 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/JdbcResource.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/JdbcResource.java
@@ -23,8 +23,6 @@ import org.apache.doris.common.Config;
import org.apache.doris.common.DdlException;
import org.apache.doris.common.EnvUtils;
import org.apache.doris.common.FeConstants;
-import org.apache.doris.common.plugin.CloudPluginDownloader;
-import org.apache.doris.common.plugin.CloudPluginDownloader.PluginType;
import org.apache.doris.common.proc.BaseProcResult;
import org.apache.doris.common.util.TimeUtils;
import org.apache.doris.common.util.Util;
@@ -449,18 +447,6 @@ public class JdbcResource extends Resource {
} else if (oldTargetFile.exists()) {
// File exists in old default directory
return "file://" + oldTargetPath;
- } else if (Config.isCloudMode()) {
- // Cloud mode: download from cloud to default directory
- try {
- String downloadedPath =
CloudPluginDownloader.downloadFromCloud(
- PluginType.JDBC_DRIVERS, driverUrl, targetPath);
- return "file://" + downloadedPath;
- } catch (Exception e) {
- LOG.warn("failed to download jdbc driver url: " +
driverUrl, e);
- throw new RuntimeException("Cannot download JDBC driver
from cloud: " + driverUrl
- + ". Please retry later or check your driver has
been uploaded to cloud. Error: "
- + Util.getRootCauseMessage(e));
- }
} else {
// File does not exist in both new and old default directory
throw new RuntimeException("JDBC driver file does not exist: "
+ driverUrl);
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/common/plugin/CloudPluginDownloader.java
b/fe/fe-core/src/main/java/org/apache/doris/common/plugin/CloudPluginDownloader.java
deleted file mode 100644
index 20e6c0342d3..00000000000
---
a/fe/fe-core/src/main/java/org/apache/doris/common/plugin/CloudPluginDownloader.java
+++ /dev/null
@@ -1,157 +0,0 @@
-// 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.doris.common.plugin;
-
-import org.apache.doris.cloud.proto.Cloud;
-import org.apache.doris.cloud.rpc.MetaServiceProxy;
-import org.apache.doris.filesystem.DorisInputFile;
-import org.apache.doris.filesystem.Location;
-import org.apache.doris.fs.FileSystemFactory;
-import org.apache.doris.service.FrontendOptions;
-
-import com.google.common.base.Strings;
-
-import java.io.File;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardCopyOption;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Simple cloud plugin downloader for UDF and JDBC drivers.
- */
-public class CloudPluginDownloader {
-
- public enum PluginType {
- JDBC_DRIVERS,
- JAVA_UDF,
- CONNECTORS, // Reserved, not supported yet
- HADOOP_CONF // Reserved, not supported yet
- }
-
- /**
- * Download plugin from cloud storage to local path
- */
- public static synchronized String downloadFromCloud(PluginType type,
String name, String localPath) {
- validateInput(type, name);
- try {
- Cloud.ObjectStoreInfoPB objInfo = getCloudStorageInfo();
- String remotePath = buildS3Path(objInfo, type, name);
- return doDownload(objInfo, remotePath, localPath);
- } catch (Exception e) {
- throw new RuntimeException("Failed to download plugin: " +
e.getMessage(), e);
- }
- }
-
- /**
- * Validate input parameters
- */
- static void validateInput(PluginType type, String name) {
- if (Strings.isNullOrEmpty(name)) {
- throw new IllegalArgumentException("Plugin name cannot be empty");
- }
-
- if (type != PluginType.JDBC_DRIVERS && type != PluginType.JAVA_UDF) {
- throw new UnsupportedOperationException("Plugin type " + type + "
is not supported yet");
- }
- }
-
- /**
- * Get cloud storage info from MetaService
- * Package-private for testing
- */
- static Cloud.ObjectStoreInfoPB getCloudStorageInfo() throws Exception {
- Cloud.GetObjStoreInfoResponse response = MetaServiceProxy.getInstance()
- .getObjStoreInfo(Cloud.GetObjStoreInfoRequest.newBuilder()
-
.setRequestIp(FrontendOptions.getLocalHostAddressCached())
- .build());
-
- if (response.getStatus().getCode() != Cloud.MetaServiceCode.OK) {
- throw new RuntimeException("Failed to get storage info: " +
response.getStatus().getMsg());
- }
-
- if (response.getObjInfoList().isEmpty()) {
- throw new RuntimeException("Only SaaS cloud storage is supported
currently");
- }
-
- return response.getObjInfo(0);
- }
-
- /**
- * Build complete S3 path from objInfo
- * Package-private for testing
- */
- static String buildS3Path(Cloud.ObjectStoreInfoPB objInfo, PluginType
type, String name) {
- String bucket = objInfo.getBucket();
- String prefix = objInfo.hasPrefix() ? objInfo.getPrefix() : "";
- String relativePath = String.format("plugins/%s/%s",
type.name().toLowerCase(), name);
-
- String fullPath;
- if (Strings.isNullOrEmpty(prefix)) {
- fullPath = bucket + "/" + relativePath;
- } else {
- fullPath = bucket + "/" + prefix + "/" + relativePath;
- }
-
- return "s3://" + fullPath;
- }
-
- /**
- * Execute download using SPI FileSystem
- */
- private static String doDownload(Cloud.ObjectStoreInfoPB objInfo, String
remotePath, String localPath)
- throws Exception {
- // Create parent directory
- Path parentDir = Paths.get(localPath).getParent();
- if (parentDir != null && !Files.exists(parentDir)) {
- Files.createDirectories(parentDir);
- }
-
- // Delete existing file if present
- File localFile = new File(localPath);
- if (localFile.exists() && !localFile.delete()) {
- throw new RuntimeException("Failed to delete existing file: " +
localPath);
- }
-
- // Download via SPI FileSystem
- Map<String, String> properties = buildProperties(objInfo);
- org.apache.doris.filesystem.FileSystem fileSystem =
- FileSystemFactory.getFileSystem(properties);
- DorisInputFile inputFile =
fileSystem.newInputFile(Location.of(remotePath));
- try (InputStream in = inputFile.newStream()) {
- Files.copy(in, localFile.toPath(),
StandardCopyOption.REPLACE_EXISTING);
- }
- return localPath;
- }
-
- /**
- * Build storage properties map from objInfo
- */
- private static Map<String, String> buildProperties(Cloud.ObjectStoreInfoPB
objInfo) {
- Map<String, String> props = new HashMap<>();
- props.put("s3.endpoint", objInfo.getEndpoint());
- props.put("s3.region", objInfo.getRegion());
- props.put("s3.access_key", objInfo.getAk());
- props.put("s3.secret_key", objInfo.getSk());
- props.put("s3.bucket", objInfo.getBucket());
- return props;
- }
-}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateFunctionCommand.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateFunctionCommand.java
index 66a4c1f428c..0cdb1be3c5d 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateFunctionCommand.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateFunctionCommand.java
@@ -46,7 +46,6 @@ import org.apache.doris.common.EnvUtils;
import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.ErrorReport;
import org.apache.doris.common.FeConstants;
-import org.apache.doris.common.plugin.CloudPluginDownloader;
import org.apache.doris.common.util.URI;
import org.apache.doris.common.util.Util;
import org.apache.doris.mysql.privilege.PrivPredicate;
@@ -485,21 +484,6 @@ public class CreateFunctionCommand extends Command
implements ForwardWithSync {
private String checkAndReturnDefaultJavaUdfUrl(String url) {
String defaultUrl = EnvUtils.getDorisHome() + "/plugins/java_udf";
- // In cloud mode, try cloud download first
- if (Config.isCloudMode()) {
- String targetPath = defaultUrl + "/" + url;
- try {
- String downloadedPath =
CloudPluginDownloader.downloadFromCloud(
- CloudPluginDownloader.PluginType.JAVA_UDF, url,
targetPath);
- if (!downloadedPath.isEmpty()) {
- return "file://" + downloadedPath;
- }
- } catch (Exception e) {
- throw new RuntimeException("Cannot download UDF from cloud: "
+ url
- + ". Please retry later or check your UDF has been
uploaded to cloud.");
- }
- }
- // Return the file path (original UDF behavior)
return "file://" + defaultUrl + "/" + url;
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/common/plugin/CloudPluginDownloaderTest.java
b/fe/fe-core/src/test/java/org/apache/doris/common/plugin/CloudPluginDownloaderTest.java
deleted file mode 100644
index 50b91fc786b..00000000000
---
a/fe/fe-core/src/test/java/org/apache/doris/common/plugin/CloudPluginDownloaderTest.java
+++ /dev/null
@@ -1,173 +0,0 @@
-// 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.doris.common.plugin;
-
-import org.apache.doris.cloud.proto.Cloud;
-import org.apache.doris.cloud.rpc.MetaServiceProxy;
-import org.apache.doris.common.plugin.CloudPluginDownloader.PluginType;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.MockedStatic;
-import org.mockito.Mockito;
-
-import java.util.Collections;
-
-/**
- * Unit tests for CloudPluginDownloader using package-private methods for
direct white-box testing.
- */
-public class CloudPluginDownloaderTest {
-
- private Cloud.GetObjStoreInfoResponse mockResponse;
- private Cloud.ObjectStoreInfoPB mockObjInfo;
- private MetaServiceProxy mockMetaServiceProxy;
-
- @BeforeEach
- void setUp() {
- mockResponse = Mockito.mock(Cloud.GetObjStoreInfoResponse.class);
- mockObjInfo = Mockito.mock(Cloud.ObjectStoreInfoPB.class);
- mockMetaServiceProxy = Mockito.mock(MetaServiceProxy.class);
- }
-
- // ============== validateInput Tests ==============
-
- @Test
- void testValidateInput() {
- // Positive cases
- Assertions.assertDoesNotThrow(() -> {
- CloudPluginDownloader.validateInput(PluginType.JDBC_DRIVERS,
"mysql.jar");
- CloudPluginDownloader.validateInput(PluginType.JAVA_UDF,
"my_udf.jar");
- });
-
- // Empty/null name
- IllegalArgumentException ex1 =
Assertions.assertThrows(IllegalArgumentException.class,
- () ->
CloudPluginDownloader.validateInput(PluginType.JDBC_DRIVERS, ""));
- Assertions.assertEquals("Plugin name cannot be empty",
ex1.getMessage());
-
- IllegalArgumentException ex2 =
Assertions.assertThrows(IllegalArgumentException.class,
- () ->
CloudPluginDownloader.validateInput(PluginType.JDBC_DRIVERS, null));
- Assertions.assertEquals("Plugin name cannot be empty",
ex2.getMessage());
-
- // Unsupported types
- UnsupportedOperationException ex3 =
Assertions.assertThrows(UnsupportedOperationException.class,
- () ->
CloudPluginDownloader.validateInput(PluginType.CONNECTORS, "test.jar"));
- Assertions.assertTrue(ex3.getMessage().contains("is not supported
yet"));
- }
-
- // ============== getCloudStorageInfo Tests ==============
-
- @Test
- void testGetCloudStorageInfo() throws Exception {
- try (MockedStatic<MetaServiceProxy> mockedStatic =
Mockito.mockStatic(MetaServiceProxy.class)) {
-
mockedStatic.when(MetaServiceProxy::getInstance).thenReturn(mockMetaServiceProxy);
-
- // Success case
- Cloud.MetaServiceResponseStatus okStatus =
Cloud.MetaServiceResponseStatus.newBuilder()
- .setCode(Cloud.MetaServiceCode.OK).build();
- Mockito.when(mockResponse.getStatus()).thenReturn(okStatus);
-
Mockito.when(mockResponse.getObjInfoList()).thenReturn(Collections.singletonList(mockObjInfo));
- Mockito.when(mockResponse.getObjInfo(0)).thenReturn(mockObjInfo);
-
Mockito.when(mockMetaServiceProxy.getObjStoreInfo(Mockito.any())).thenReturn(mockResponse);
-
- Cloud.ObjectStoreInfoPB result =
CloudPluginDownloader.getCloudStorageInfo();
- Assertions.assertEquals(mockObjInfo, result);
-
- // Error response
- Cloud.MetaServiceResponseStatus failedStatus =
Cloud.MetaServiceResponseStatus.newBuilder()
-
.setCode(Cloud.MetaServiceCode.INVALID_ARGUMENT).setMsg("Test error").build();
- Mockito.when(mockResponse.getStatus()).thenReturn(failedStatus);
-
- RuntimeException ex1 =
Assertions.assertThrows(RuntimeException.class,
- CloudPluginDownloader::getCloudStorageInfo);
- Assertions.assertTrue(ex1.getMessage().contains("Failed to get
storage info"));
-
- // Empty storage list
- Mockito.when(mockResponse.getStatus()).thenReturn(okStatus);
-
Mockito.when(mockResponse.getObjInfoList()).thenReturn(Collections.emptyList());
-
- RuntimeException ex2 =
Assertions.assertThrows(RuntimeException.class,
- CloudPluginDownloader::getCloudStorageInfo);
- Assertions.assertTrue(ex2.getMessage().contains("Only SaaS cloud
storage is supported"));
- }
- }
-
- // ============== buildS3Path Tests ==============
-
- @Test
- void testBuildS3Path() {
- Mockito.when(mockObjInfo.getBucket()).thenReturn("test-bucket");
-
- // With prefix
- Mockito.when(mockObjInfo.hasPrefix()).thenReturn(true);
- Mockito.when(mockObjInfo.getPrefix()).thenReturn("test-prefix");
-
Assertions.assertEquals("s3://test-bucket/test-prefix/plugins/jdbc_drivers/mysql.jar",
- CloudPluginDownloader.buildS3Path(mockObjInfo,
PluginType.JDBC_DRIVERS, "mysql.jar"));
-
- // Without prefix
- Mockito.when(mockObjInfo.hasPrefix()).thenReturn(false);
- Assertions.assertEquals("s3://test-bucket/plugins/java_udf/my_udf.jar",
- CloudPluginDownloader.buildS3Path(mockObjInfo,
PluginType.JAVA_UDF, "my_udf.jar"));
-
- // All plugin types
- Assertions.assertEquals("s3://test-bucket/plugins/connectors/test.jar",
- CloudPluginDownloader.buildS3Path(mockObjInfo,
PluginType.CONNECTORS, "test.jar"));
-
Assertions.assertEquals("s3://test-bucket/plugins/hadoop_conf/test.xml",
- CloudPluginDownloader.buildS3Path(mockObjInfo,
PluginType.HADOOP_CONF, "test.xml"));
- }
-
- // ============== Integration Test ==============
-
- @Test
- void testDownloadFromCloudIntegration() {
- // Basic integration test - should fail early due to validation
- IllegalArgumentException ex =
Assertions.assertThrows(IllegalArgumentException.class,
- () ->
CloudPluginDownloader.downloadFromCloud(PluginType.JDBC_DRIVERS, "",
"/tmp/test.jar"));
- Assertions.assertEquals("Plugin name cannot be empty",
ex.getMessage());
-
- // Should fail at MetaService level (no real cloud environment)
- RuntimeException ex2 = Assertions.assertThrows(RuntimeException.class,
- () ->
CloudPluginDownloader.downloadFromCloud(PluginType.JDBC_DRIVERS, "mysql.jar",
"/tmp/test.jar"));
- Assertions.assertTrue(ex2.getMessage().contains("Failed to download
plugin"));
- }
-
- @Test
- void testBuildS3PathEdgeCases() {
- // Test empty bucket (edge case)
- Mockito.when(mockObjInfo.getBucket()).thenReturn("");
- Mockito.when(mockObjInfo.hasPrefix()).thenReturn(false);
- String result = CloudPluginDownloader.buildS3Path(mockObjInfo,
PluginType.JDBC_DRIVERS, "test.jar");
- Assertions.assertEquals("s3:///plugins/jdbc_drivers/test.jar", result);
-
- // Test special characters in name
- Mockito.when(mockObjInfo.getBucket()).thenReturn("test-bucket");
- String specialResult = CloudPluginDownloader.buildS3Path(mockObjInfo,
PluginType.JAVA_UDF, "[email protected]");
-
Assertions.assertEquals("s3://test-bucket/plugins/java_udf/[email protected]",
specialResult);
- }
-
- // ============== Enum Tests ==============
-
- @Test
- void testPluginTypeEnum() {
- Assertions.assertEquals("JDBC_DRIVERS",
PluginType.JDBC_DRIVERS.name());
- Assertions.assertEquals("JAVA_UDF", PluginType.JAVA_UDF.name());
- Assertions.assertEquals("CONNECTORS", PluginType.CONNECTORS.name());
- Assertions.assertEquals("HADOOP_CONF", PluginType.HADOOP_CONF.name());
- Assertions.assertEquals(4, PluginType.values().length);
- }
-}
diff --git
a/regression-test/suites/plugin_p1/test_cloud_plugin_auto_download.groovy
b/regression-test/suites/plugin_p1/test_cloud_plugin_auto_download.groovy
deleted file mode 100644
index 2b697db07ba..00000000000
--- a/regression-test/suites/plugin_p1/test_cloud_plugin_auto_download.groovy
+++ /dev/null
@@ -1,121 +0,0 @@
-// 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.
-
-suite("test_cloud_plugin_auto_download", "p1,external") {
-
- //sass cloud-mode only
- if (!isCloudMode() || enableStoragevault()) {
- logger.info("Skip test_plugin_auto_download because not in sass cloud
mode")
- return
- }
-
- String jdbcUrl = context.config.jdbcUrl
- String jdbcUser = context.config.jdbcUser
- String jdbcPassword = context.config.jdbcPassword
-
- sql """drop database if exists internal.test_auto_download_db; """
- sql """create database if not exists internal.test_auto_download_db;"""
- sql """create table if not exists internal.test_auto_download_db.test_tbl
- (id int, name varchar(20))
- distributed by hash(id) buckets 1
- properties('replication_num' = '1');
- """
- sql """insert into internal.test_auto_download_db.test_tbl values(1,
'auto_download_test')"""
-
- sql """drop catalog if exists test_auto_download_catalog """
- sql """ CREATE CATALOG `test_auto_download_catalog` PROPERTIES (
- "user" = "${jdbcUser}",
- "type" = "jdbc",
- "password" = "${jdbcPassword}",
- "jdbc_url" = "${jdbcUrl}",
- "driver_url" = "mysql-connector-j-8.3.0.jar",
- "driver_class" = "com.mysql.cj.jdbc.Driver"
- )"""
-
- def result = sql """
- select * from test_auto_download_catalog.test_auto_download_db.test_tbl
- """
- logger.info("result: ${result}")
- assertTrue(result.size() > 0)
- assertEquals(result[0][0], 1)
- assertEquals(result[0][1], "auto_download_test")
-
- sql """drop catalog if exists test_auto_download_catalog """
-
- sql """ use internal.test_auto_download_db; """
-
- sql """DROP FUNCTION IF EXISTS java_udf_add_one(int)"""
-
- sql """ CREATE FUNCTION java_udf_add_one(int) RETURNS int PROPERTIES (
- "file"="java-udf-demo-jar-with-dependencies.jar",
- "symbol"="org.apache.doris.udf.AddOne",
- "type"="JAVA_UDF"
- ); """
-
- def result2 = sql """
- select java_udf_add_one(100) as result
- """
- assertTrue(result2.size() > 0)
- assertEquals(result2[0][0], 101)
-
- sql """DROP FUNCTION IF EXISTS java_udf_add_one(int)"""
-
- // negative test case 1: non-existent JDBC driver jar
- sql """drop catalog if exists test_non_existent_driver_catalog """
- try {
- sql """ CREATE CATALOG `test_non_existent_driver_catalog` PROPERTIES (
- "user" = "${jdbcUser}",
- "type" = "jdbc",
- "password" = "${jdbcPassword}",
- "jdbc_url" = "${jdbcUrl}",
- "driver_url" = "non-existent-mysql-driver.jar",
- "driver_class" = "com.mysql.cj.jdbc.Driver"
- )"""
-
- sql """
- select * from
test_non_existent_driver_catalog.test_auto_download_db.test_tbl
- """
- assertTrue(false, "Should have thrown exception for non-existent
driver jar")
- } catch (Exception e) {
- logger.info("Expected exception for non-existent driver jar: " +
e.getMessage())
- assertTrue(e.getMessage().contains("has been uploaded to cloud"))
- } finally {
- sql """drop catalog if exists test_non_existent_driver_catalog """
- }
-
- // negative test case 2: non-existent UDF jar
- sql """DROP FUNCTION IF EXISTS java_udf_non_existent(int)"""
- try {
- sql """ CREATE FUNCTION java_udf_non_existent(int) RETURNS int
PROPERTIES (
- "file"="non-existent-udf.jar",
- "symbol"="org.apache.doris.udf.NonExistent",
- "type"="JAVA_UDF"
- ); """
-
- sql """
- select java_udf_non_existent(100) as result
- """
- assertTrue(false, "Should have thrown exception for non-existent UDF
jar")
- } catch (Exception e) {
- logger.info("Expected exception for non-existent UDF jar: " +
e.getMessage())
- assertTrue(e.getMessage().contains("has been uploaded to cloud"))
- } finally {
- sql """DROP FUNCTION IF EXISTS java_udf_non_existent(int)"""
- }
-
- sql """ drop database if exists internal.test_auto_download_db; """
-}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]