Skip to content

Commit 65e7283

Browse files
committed
Add GraalVM Reachability Metadata and corresponding nativeTest for Presto
1 parent 485153d commit 65e7283

File tree

20 files changed

+809
-44
lines changed

20 files changed

+809
-44
lines changed

docs/document/content/user-manual/shardingsphere-jdbc/graalvm-native-image/_index.cn.md

-3
Original file line numberDiff line numberDiff line change
@@ -330,9 +330,6 @@ ShardingSphere 的单元测试仅使用 Maven 模块 `io.github.linghengqian:hiv
330330
9. 由于 https://github.com/apache/doris/issues/9426 的影响,当通过 Shardinghere JDBC 连接至 Apache Doris FE,
331331
用户需自行提供 `apache/doris` 集成模块相关的 GraalVM Reachability Metadata。
332332

333-
10. 由于 https://github.com/prestodb/presto/issues/23226 的影响,当通过 Shardinghere JDBC 连接至 Presto Server,
334-
用户需自行提供 `com.facebook.presto:presto-jdbc` 和 `prestodb/presto` 集成模块相关的 GraalVM Reachability Metadata。
335-
336333
## 贡献 GraalVM Reachability Metadata
337334

338335
ShardingSphere 对在 GraalVM Native Image 下的可用性的验证,是通过 GraalVM Native Build Tools 的 Maven Plugin 子项目来完成的。

docs/document/content/user-manual/shardingsphere-jdbc/graalvm-native-image/_index.en.md

-3
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,6 @@ the Oracle JDBC Driver corresponding to the `com.oracle.database.jdbc:ojdbc8` Ma
344344
9. Due to https://github.com/apache/doris/issues/9426, when connecting to Apache Doris FE via Shardinghere JDBC,
345345
users need to provide GraalVM Reachability Metadata related to the `apache/doris` integration module.
346346

347-
10. Due to https://github.com/prestodb/presto/issues/23226, when connecting to Presto Server via Shardinghere JDBC,
348-
users need to provide GraalVM Reachability Metadata related to the `com.facebook.presto:presto-jdbc` and `prestodb/presto` integration module.
349-
350347
## Contribute GraalVM Reachability Metadata
351348

352349
The verification of ShardingSphere's availability under GraalVM Native Image is completed through the Maven Plugin subproject
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.shardingsphere.infra.database.presto.metadata.data.loader;
19+
20+
import org.apache.shardingsphere.infra.database.core.metadata.data.loader.DialectMetaDataLoader;
21+
import org.apache.shardingsphere.infra.database.core.metadata.data.loader.MetaDataLoaderMaterial;
22+
import org.apache.shardingsphere.infra.database.core.metadata.data.model.ColumnMetaData;
23+
import org.apache.shardingsphere.infra.database.core.metadata.data.model.SchemaMetaData;
24+
import org.apache.shardingsphere.infra.database.core.metadata.data.model.TableMetaData;
25+
import org.apache.shardingsphere.infra.database.core.metadata.database.datatype.DataTypeRegistry;
26+
27+
import java.sql.Connection;
28+
import java.sql.PreparedStatement;
29+
import java.sql.ResultSet;
30+
import java.sql.SQLException;
31+
import java.sql.Types;
32+
import java.util.Collection;
33+
import java.util.Collections;
34+
import java.util.HashMap;
35+
import java.util.LinkedList;
36+
import java.util.Map;
37+
import java.util.stream.Collectors;
38+
39+
/**
40+
* Meta data loader for Presto.
41+
* As of prestodb/presto 0.290 of the Memory Connector, the table `INFORMATION_SCHEMA.INDEXES` does not exist,
42+
* and `INFORMATION_SCHEMA.COLUMNS` does not have a column `IS_VISIBLE`.
43+
* This may change in the future.
44+
*/
45+
public final class PrestoMetaDataLoader implements DialectMetaDataLoader {
46+
47+
@Override
48+
public Collection<SchemaMetaData> load(final MetaDataLoaderMaterial material) throws SQLException {
49+
Collection<TableMetaData> tableMetaDataList = new LinkedList<>();
50+
try (Connection connection = material.getDataSource().getConnection()) {
51+
Map<String, Collection<ColumnMetaData>> columnMetaDataMap = loadColumnMetaDataMap(connection, material.getActualTableNames());
52+
for (Map.Entry<String, Collection<ColumnMetaData>> entry : columnMetaDataMap.entrySet()) {
53+
tableMetaDataList.add(new TableMetaData(entry.getKey(), entry.getValue(), Collections.emptyList(), Collections.emptyList()));
54+
}
55+
}
56+
return Collections.singleton(new SchemaMetaData(material.getDefaultSchemaName(), tableMetaDataList));
57+
}
58+
59+
@SuppressWarnings("SqlSourceToSinkFlow")
60+
private Map<String, Collection<ColumnMetaData>> loadColumnMetaDataMap(final Connection connection, final Collection<String> tables) throws SQLException {
61+
Map<String, Collection<ColumnMetaData>> result = new HashMap<>();
62+
try (PreparedStatement preparedStatement = connection.prepareStatement(getTableMetaDataSQL(tables))) {
63+
preparedStatement.setString(1, connection.getCatalog());
64+
try (ResultSet resultSet = preparedStatement.executeQuery()) {
65+
while (resultSet.next()) {
66+
String tableName = resultSet.getString("TABLE_NAME");
67+
ColumnMetaData columnMetaData = loadColumnMetaData(resultSet);
68+
if (!result.containsKey(tableName)) {
69+
result.put(tableName, new LinkedList<>());
70+
}
71+
result.get(tableName).add(columnMetaData);
72+
}
73+
}
74+
}
75+
return result;
76+
}
77+
78+
private String getTableMetaDataSQL(final Collection<String> tables) {
79+
if (tables.isEmpty()) {
80+
return "SELECT TABLE_CATALOG,\n"
81+
+ " TABLE_NAME,\n"
82+
+ " COLUMN_NAME,\n"
83+
+ " DATA_TYPE,\n"
84+
+ " ORDINAL_POSITION,\n"
85+
+ " IS_NULLABLE\n"
86+
+ "FROM INFORMATION_SCHEMA.COLUMNS\n"
87+
+ "WHERE TABLE_CATALOG = ?\n"
88+
+ "ORDER BY ORDINAL_POSITION";
89+
}
90+
String collect = tables.stream().map(each -> String.format("'%s'", each).toUpperCase()).collect(Collectors.joining(","));
91+
return String.format("SELECT TABLE_CATALOG,\n"
92+
+ " TABLE_NAME,\n"
93+
+ " COLUMN_NAME,\n"
94+
+ " DATA_TYPE,\n"
95+
+ " ORDINAL_POSITION,\n"
96+
+ " IS_NULLABLE\n"
97+
+ "FROM INFORMATION_SCHEMA.COLUMNS\n"
98+
+ "WHERE TABLE_CATALOG = ?\n"
99+
+ " AND UPPER(TABLE_NAME) IN (%s)\n"
100+
+ "ORDER BY ORDINAL_POSITION", collect);
101+
}
102+
103+
private ColumnMetaData loadColumnMetaData(final ResultSet resultSet) throws SQLException {
104+
String columnName = resultSet.getString("COLUMN_NAME");
105+
String dataType = resultSet.getString("DATA_TYPE");
106+
boolean isNullable = "YES".equals(resultSet.getString("IS_NULLABLE"));
107+
return new ColumnMetaData(columnName, DataTypeRegistry.getDataType(getDatabaseType(), dataType).orElse(Types.OTHER), Boolean.FALSE, Boolean.FALSE, false, Boolean.TRUE, false, isNullable);
108+
}
109+
110+
@Override
111+
public String getDatabaseType() {
112+
return "Presto";
113+
}
114+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one or more
3+
# contributor license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright ownership.
5+
# The ASF licenses this file to You under the Apache License, Version 2.0
6+
# (the "License"); you may not use this file except in compliance with
7+
# the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
org.apache.shardingsphere.infra.database.presto.metadata.data.loader.PrestoMetaDataLoader
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.shardingsphere.infra.database.presto.database;
19+
20+
import org.apache.shardingsphere.infra.database.core.metadata.database.DialectDatabaseMetaData;
21+
import org.apache.shardingsphere.infra.database.core.metadata.database.enums.NullsOrderType;
22+
import org.apache.shardingsphere.infra.database.core.metadata.database.enums.QuoteCharacter;
23+
import org.apache.shardingsphere.infra.database.core.spi.DatabaseTypedSPILoader;
24+
import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
25+
import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
26+
import org.junit.jupiter.api.Test;
27+
28+
import static org.hamcrest.CoreMatchers.is;
29+
import static org.hamcrest.MatcherAssert.assertThat;
30+
31+
class PrestoDatabaseMetaDataTest {
32+
33+
private final DialectDatabaseMetaData dialectDatabaseMetaData = DatabaseTypedSPILoader.getService(DialectDatabaseMetaData.class, TypedSPILoader.getService(DatabaseType.class, "Presto"));
34+
35+
@Test
36+
void assertGetQuoteCharacter() {
37+
assertThat(dialectDatabaseMetaData.getQuoteCharacter(), is(QuoteCharacter.QUOTE));
38+
}
39+
40+
@Test
41+
void assertGetDefaultNullsOrderType() {
42+
assertThat(dialectDatabaseMetaData.getDefaultNullsOrderType(), is(NullsOrderType.LOW));
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[
2+
{
3+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.guava.reflect.Reflection"},
4+
"interfaces":["java.lang.reflect.TypeVariable"]
5+
}
6+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
[
2+
{
3+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.client.StatementClientV1"},
4+
"name":"com.facebook.presto.jdbc.internal.client.ClientTypeSignature",
5+
"methods":[{"name":"<init>","parameterTypes":["java.lang.String","java.util.List","java.util.List","java.util.List"] }]
6+
},
7+
{
8+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.ObjectReader"},
9+
"name":"com.facebook.presto.jdbc.internal.client.ClientTypeSignature",
10+
"allDeclaredFields":true,
11+
"queryAllDeclaredMethods":true,
12+
"queryAllDeclaredConstructors":true
13+
},
14+
{
15+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.deser.DefaultDeserializationContext"},
16+
"name":"com.facebook.presto.jdbc.internal.client.ClientTypeSignatureParameter$ClientTypeSignatureParameterDeserializer",
17+
"methods":[{"name":"<init>","parameterTypes":[] }]
18+
},
19+
{
20+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.client.StatementClientV1"},
21+
"name":"com.facebook.presto.jdbc.internal.client.Column",
22+
"methods":[{"name":"<init>","parameterTypes":["java.lang.String","java.lang.String","com.facebook.presto.jdbc.internal.client.ClientTypeSignature"] }]
23+
},
24+
{
25+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.ObjectReader"},
26+
"name":"com.facebook.presto.jdbc.internal.client.Column",
27+
"allDeclaredFields":true,
28+
"queryAllDeclaredMethods":true,
29+
"queryAllDeclaredConstructors":true
30+
},
31+
{
32+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.ObjectReader"},
33+
"name":"com.facebook.presto.jdbc.internal.client.ErrorLocation",
34+
"allDeclaredFields":true,
35+
"queryAllDeclaredMethods":true,
36+
"queryAllDeclaredConstructors":true
37+
},
38+
{
39+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.ObjectReader"},
40+
"name":"com.facebook.presto.jdbc.internal.client.FailureInfo",
41+
"allDeclaredFields":true,
42+
"queryAllDeclaredMethods":true,
43+
"queryAllDeclaredConstructors":true,
44+
"allPublicConstructors": true
45+
},
46+
{
47+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.ObjectReader"},
48+
"name":"com.facebook.presto.jdbc.internal.client.QueryData",
49+
"queryAllDeclaredMethods":true
50+
},
51+
{
52+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.ObjectReader"},
53+
"name":"com.facebook.presto.jdbc.internal.client.QueryError",
54+
"allDeclaredFields":true,
55+
"queryAllDeclaredMethods":true,
56+
"queryAllDeclaredConstructors":true,
57+
"allPublicConstructors": true
58+
},
59+
{
60+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.ObjectReader"},
61+
"name":"com.facebook.presto.jdbc.internal.client.QueryResults",
62+
"allDeclaredFields":true,
63+
"queryAllDeclaredMethods":true,
64+
"queryAllDeclaredConstructors":true,
65+
"methods":[{"name":"<init>","parameterTypes":["java.lang.String","java.net.URI","java.net.URI","java.net.URI","java.util.List","java.util.List","java.util.List","com.facebook.presto.jdbc.internal.client.StatementStats","com.facebook.presto.jdbc.internal.client.QueryError","java.util.List","java.lang.String","java.lang.Long"] }]
66+
},
67+
{
68+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.ObjectReader"},
69+
"name":"com.facebook.presto.jdbc.internal.client.QueryStatusInfo",
70+
"queryAllDeclaredMethods":true
71+
},
72+
{
73+
"condition":{"typeReachable":"com.facebook.presto.jdbc.PrestoPreparedStatement"},
74+
"name":"com.facebook.presto.jdbc.internal.client.StageStats",
75+
"methods":[{"name":"<init>","parameterTypes":["java.lang.String","java.lang.String","boolean","int","int","int","int","int","long","long","long","long","java.util.List"] }]
76+
},
77+
{
78+
"condition":{"typeReachable":"com.facebook.presto.jdbc.PrestoResultSet$ResultsPageIterator"},
79+
"name":"com.facebook.presto.jdbc.internal.client.StageStats",
80+
"methods":[{"name":"<init>","parameterTypes":["java.lang.String","java.lang.String","boolean","int","int","int","int","int","long","long","long","long","java.util.List"] }]
81+
},
82+
{
83+
"condition":{"typeReachable":"com.facebook.presto.jdbc.PrestoStatement"},
84+
"name":"com.facebook.presto.jdbc.internal.client.StageStats",
85+
"methods":[{"name":"<init>","parameterTypes":["java.lang.String","java.lang.String","boolean","int","int","int","int","int","long","long","long","long","java.util.List"] }]
86+
},
87+
{
88+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.ObjectReader"},
89+
"name":"com.facebook.presto.jdbc.internal.client.StageStats",
90+
"allDeclaredFields":true,
91+
"queryAllDeclaredMethods":true,
92+
"queryAllDeclaredConstructors":true
93+
},
94+
{
95+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.ObjectReader"},
96+
"name":"com.facebook.presto.jdbc.internal.client.StatementStats",
97+
"allDeclaredFields":true,
98+
"queryAllDeclaredMethods":true,
99+
"queryAllDeclaredConstructors":true,
100+
"methods":[{"name":"<init>","parameterTypes":["java.lang.String","boolean","boolean","boolean","int","int","int","int","int","long","long","long","long","long","long","long","long","long","long","long","com.facebook.presto.jdbc.internal.client.StageStats","com.facebook.presto.jdbc.internal.common.RuntimeStats"] }]
101+
},
102+
{
103+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.deser.std.MapDeserializer"},
104+
"name":"com.facebook.presto.jdbc.internal.common.RuntimeMetric",
105+
"allDeclaredFields":true,
106+
"queryAllDeclaredMethods":true,
107+
"queryAllDeclaredConstructors":true,
108+
"methods":[{"name":"<init>","parameterTypes":["java.lang.String","com.facebook.presto.jdbc.internal.common.RuntimeUnit","long","long","long","long"] }]
109+
},
110+
{
111+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.ObjectReader"},
112+
"name":"com.facebook.presto.jdbc.internal.common.RuntimeStats",
113+
"allDeclaredFields":true,
114+
"queryAllDeclaredMethods":true,
115+
"queryAllDeclaredConstructors":true
116+
},
117+
{
118+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.introspect.AnnotatedConstructor"},
119+
"name":"com.facebook.presto.jdbc.internal.common.RuntimeStats",
120+
"methods":[{"name":"<init>","parameterTypes":["java.util.Map"] }]
121+
},
122+
{
123+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.deser.std.MapDeserializer"},
124+
"name":"com.facebook.presto.jdbc.internal.common.RuntimeUnit",
125+
"allDeclaredFields":true,
126+
"queryAllDeclaredMethods":true
127+
},
128+
{
129+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.introspect.JacksonAnnotationIntrospector"},
130+
"name":"com.facebook.presto.jdbc.internal.common.RuntimeUnit",
131+
"allDeclaredFields":true
132+
},
133+
{
134+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.util.ClassUtil"},
135+
"name":"com.facebook.presto.jdbc.internal.common.RuntimeUnit",
136+
"allDeclaredFields":true
137+
},
138+
{
139+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.ObjectMapper"},
140+
"name":"com.facebook.presto.jdbc.internal.common.type.ParameterKind",
141+
"allDeclaredFields":true,
142+
"queryAllDeclaredMethods":true
143+
},
144+
{
145+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.introspect.AnnotatedMethod"},
146+
"name":"com.facebook.presto.jdbc.internal.common.type.ParameterKind",
147+
"methods":[{"name":"fromJsonValue","parameterTypes":["java.lang.String"] }]
148+
},
149+
{
150+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.guava.reflect.Types$TypeVariableInvocationHandler"},
151+
"name":"com.facebook.presto.jdbc.internal.guava.reflect.Types$TypeVariableImpl",
152+
"queryAllPublicMethods":true
153+
},
154+
{
155+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.ext.Java7Handlers"},
156+
"name":"com.facebook.presto.jdbc.internal.jackson.databind.ext.Java7HandlersImpl",
157+
"methods":[{"name":"<init>","parameterTypes":[] }]
158+
},
159+
{
160+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.ext.Java7Support"},
161+
"name":"com.facebook.presto.jdbc.internal.jackson.databind.ext.Java7SupportImpl",
162+
"methods":[{"name":"<init>","parameterTypes":[] }]
163+
},
164+
{
165+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.com.facebook.airlift.json.ObjectMapperProvider"},
166+
"name":"com.facebook.presto.jdbc.internal.joda.time.DateTime"
167+
},
168+
{
169+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.ObjectReader"},
170+
"name":"com.facebook.presto.jdbc.internal.spi.PrestoWarning",
171+
"allDeclaredFields":true,
172+
"queryAllDeclaredMethods":true,
173+
"queryAllDeclaredConstructors":true
174+
},
175+
{
176+
"condition":{"typeReachable":"com.facebook.presto.jdbc.internal.jackson.databind.ObjectReader"},
177+
"name":"com.facebook.presto.jdbc.internal.spi.WarningCode",
178+
"allDeclaredFields":true,
179+
"queryAllDeclaredMethods":true,
180+
"queryAllDeclaredConstructors":true
181+
}
182+
]

0 commit comments

Comments
 (0)