Skip to content

Commit 7930184

Browse files
committed
[CALCITE-7022] Decouple ModelHandler from CalciteConnection
ModelHandler is mainly a parser that can transform YAML/JSON files into SchemaPlus objects. Currently, the class requires a CalciteConnection in order to be instantiated and the latter is a pretty heavyweight object. The usage of the CalciteConnection makes it rather cumbersome to instantiate and use the parsing capabilities of the ModelHander independently. In reality though, the handler does not need much from the CalciteConnection and we could easily refactor the handler to not depend on the connection at all. The motivation for this change is to facilitate the creation of schema objects from YAML/JSON files.
1 parent 988caac commit 7930184

File tree

4 files changed

+114
-14
lines changed

4 files changed

+114
-14
lines changed

core/src/main/java/org/apache/calcite/jdbc/Driver.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,11 @@ protected Function0<CalcitePrepare> createPrepareFactory() {
144144
final String model = model(connection);
145145
if (model != null) {
146146
try {
147-
new ModelHandler(connection, model);
147+
ModelHandler h = new ModelHandler(connection.getRootSchema(), model);
148+
String defaultName = h.defaultSchemaName();
149+
if (defaultName != null) {
150+
connection.setSchema(defaultName);
151+
}
148152
} catch (IOException e) {
149153
throw new SQLException(e);
150154
}

core/src/main/java/org/apache/calcite/model/ModelHandler.java

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -77,20 +77,19 @@ public class ModelHandler {
7777
.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
7878
private static final ObjectMapper YAML_MAPPER = new YAMLMapper();
7979

80-
private final CalciteConnection connection;
80+
private final SchemaPlus rootSchema;
81+
private final @Nullable String defaultSchemaName;
8182
private final Deque<Pair<? extends @Nullable String, SchemaPlus>> schemaStack =
8283
new ArrayDeque<>();
8384
private final String modelUri;
8485
Lattice.@Nullable Builder latticeBuilder;
8586
Lattice.@Nullable TileBuilder tileBuilder;
8687

8788
@SuppressWarnings("method.invocation.invalid")
88-
public ModelHandler(CalciteConnection connection, String uri)
89-
throws IOException {
89+
public ModelHandler(SchemaPlus rootSchema, String uri) throws IOException {
9090
super();
91-
this.connection = connection;
9291
this.modelUri = uri;
93-
92+
this.rootSchema = rootSchema;
9493
JsonRoot root;
9594
ObjectMapper mapper;
9695
if (uri.startsWith("inline:")) {
@@ -105,6 +104,19 @@ public ModelHandler(CalciteConnection connection, String uri)
105104
root = mapper.readValue(new File(uri), JsonRoot.class);
106105
}
107106
visit(root);
107+
this.defaultSchemaName = root.defaultSchema;
108+
}
109+
110+
@Deprecated // to be removed before 2.0
111+
public ModelHandler(CalciteConnection connection, String uri) throws IOException {
112+
this(connection.getRootSchema(), uri);
113+
if (defaultSchemaName != null) {
114+
try {
115+
connection.setSchema(defaultSchemaName);
116+
} catch (SQLException e) {
117+
throw new RuntimeException(e);
118+
}
119+
}
108120
}
109121

110122
// CHECKSTYLE: IGNORE 1
@@ -196,7 +208,7 @@ public static void addFunctions(SchemaPlus schema,
196208

197209
public void visit(JsonRoot jsonRoot) {
198210
final Pair<@Nullable String, SchemaPlus> pair =
199-
Pair.of(null, connection.getRootSchema());
211+
Pair.of(null, rootSchema);
200212
schemaStack.push(pair);
201213
for (JsonType rootType : jsonRoot.types) {
202214
rootType.accept(this);
@@ -206,13 +218,6 @@ public void visit(JsonRoot jsonRoot) {
206218
}
207219
final Pair<? extends @Nullable String, SchemaPlus> p = schemaStack.pop();
208220
assert p == pair;
209-
if (jsonRoot.defaultSchema != null) {
210-
try {
211-
connection.setSchema(jsonRoot.defaultSchema);
212-
} catch (SQLException e) {
213-
throw new RuntimeException(e);
214-
}
215-
}
216221
}
217222

218223
public void visit(JsonMapSchema jsonSchema) {
@@ -473,6 +478,10 @@ private SchemaPlus currentMutableSchema(String elementType) {
473478
return schema;
474479
}
475480

481+
public @Nullable String defaultSchemaName() {
482+
return this.defaultSchemaName;
483+
}
484+
476485
public void visit(final JsonType jsonType) {
477486
try {
478487
final SchemaPlus schema = currentMutableSchema("type");
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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+
package org.apache.calcite.model;
18+
19+
import org.apache.calcite.jdbc.CalciteSchema;
20+
import org.apache.calcite.schema.SchemaPlus;
21+
import org.apache.calcite.schema.lookup.LikePattern;
22+
import org.apache.calcite.util.Sources;
23+
24+
import com.google.common.collect.ImmutableSet;
25+
26+
import org.junit.jupiter.api.Test;
27+
28+
import java.io.IOException;
29+
import java.util.Set;
30+
31+
import static org.hamcrest.CoreMatchers.is;
32+
import static org.hamcrest.MatcherAssert.assertThat;
33+
34+
import static java.util.Objects.requireNonNull;
35+
36+
/**
37+
* Unit test for {@link ModelHandler}.
38+
*/
39+
public class ModelHandlerTest {
40+
41+
/** Test case for
42+
* <a href="https://issues.apache.org/jira/browse/CALCITE-7022">[CALCITE-7022]
43+
* Decouple ModelHandler from CalciteConnection</a>.
44+
* The test ensures/demonstrates that a Schema can be easily parsed/created from a model
45+
* file (JSON/YAML) without necessitating the creation of complex/heavy objects
46+
* (e.g., CalciteConnection). */
47+
@Test void testPopulateRootSchemaFromURL() throws IOException {
48+
SchemaPlus root = CalciteSchema.createRootSchema(false, false).plus();
49+
String mURI =
50+
Sources.of(requireNonNull(ModelHandlerTest.class.getResource("/hsqldb-scott.json")))
51+
.path();
52+
ModelHandler h = new ModelHandler(root, mURI);
53+
SchemaPlus scott = root.subSchemas().get("SCOTT");
54+
Set<String> tables = scott.tables().getNames(new LikePattern("%"));
55+
assertThat(tables, is(ImmutableSet.of("EMP", "DEPT", "BONUS", "SALGRADE")));
56+
assertThat(h.defaultSchemaName(), is("SCOTT"));
57+
}
58+
59+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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+
"version": "1.0",
19+
"defaultSchema": "SCOTT",
20+
"schemas": [ {
21+
"type": "jdbc",
22+
"name": "SCOTT",
23+
"jdbcUser": "SA",
24+
"jdbcPassword": "",
25+
"jdbcUrl": "jdbc:hsqldb:res:scott",
26+
"jdbcSchema": "SCOTT"
27+
} ]
28+
}

0 commit comments

Comments
 (0)