This is an automated email from the ASF dual-hosted git repository. bchapuis pushed a commit to branch calcite-framework in repository https://gitbox.apache.org/repos/asf/incubator-baremaps.git
commit e9983dd21d1acad16405f0b4676acfd97f84341f Author: Bertil Chapuis <[email protected]> AuthorDate: Mon Jan 13 08:26:18 2025 +0100 Experiments with calcite --- .../org/apache/baremaps/calcite/CalciteTest.java | 2 +- baremaps-data/pom.xml | 4 + .../data/{store => calcite}/BaremapsDataTable.java | 2 +- .../data/calcite/CalciteMultipleDDLParser.java | 14 ++ .../apache/baremaps/data/calcite/CalciteTest.java | 170 +++++++++++++++++++++ pom.xml | 7 +- 6 files changed, 196 insertions(+), 3 deletions(-) diff --git a/baremaps-core/src/test/java/org/apache/baremaps/calcite/CalciteTest.java b/baremaps-core/src/test/java/org/apache/baremaps/calcite/CalciteTest.java index efc13eb4d..1b5e8b3b2 100644 --- a/baremaps-core/src/test/java/org/apache/baremaps/calcite/CalciteTest.java +++ b/baremaps-core/src/test/java/org/apache/baremaps/calcite/CalciteTest.java @@ -22,10 +22,10 @@ import com.google.common.collect.ImmutableList; import java.sql.*; import java.util.List; import java.util.Properties; +import org.apache.baremaps.data.calcite.BaremapsDataTable; import org.apache.baremaps.data.calcite.SqlDataTable; import org.apache.baremaps.data.collection.AppendOnlyLog; import org.apache.baremaps.data.collection.IndexedDataList; -import org.apache.baremaps.data.store.BaremapsDataTable; import org.apache.baremaps.data.type.RowDataType; import org.apache.baremaps.maplibre.vectortile.VectorTileFunctions; import org.apache.baremaps.store.*; diff --git a/baremaps-data/pom.xml b/baremaps-data/pom.xml index 406f2194b..2054a761e 100644 --- a/baremaps-data/pom.xml +++ b/baremaps-data/pom.xml @@ -37,6 +37,10 @@ limitations under the License. <groupId>org.apache.calcite</groupId> <artifactId>calcite-core</artifactId> </dependency> + <dependency> + <groupId>org.apache.calcite</groupId> + <artifactId>calcite-server</artifactId> + </dependency> <dependency> <groupId>org.roaringbitmap</groupId> <artifactId>RoaringBitmap</artifactId> diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/store/BaremapsDataTable.java b/baremaps-data/src/main/java/org/apache/baremaps/data/calcite/BaremapsDataTable.java similarity index 97% rename from baremaps-data/src/main/java/org/apache/baremaps/data/store/BaremapsDataTable.java rename to baremaps-data/src/main/java/org/apache/baremaps/data/calcite/BaremapsDataTable.java index 89123dab6..55ddee115 100644 --- a/baremaps-data/src/main/java/org/apache/baremaps/data/store/BaremapsDataTable.java +++ b/baremaps-data/src/main/java/org/apache/baremaps/data/calcite/BaremapsDataTable.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.baremaps.data.store; +package org.apache.baremaps.data.calcite; import java.util.Iterator; import org.apache.baremaps.data.collection.DataCollection; diff --git a/baremaps-data/src/main/java/org/apache/baremaps/data/calcite/CalciteMultipleDDLParser.java b/baremaps-data/src/main/java/org/apache/baremaps/data/calcite/CalciteMultipleDDLParser.java new file mode 100644 index 000000000..04984fd3e --- /dev/null +++ b/baremaps-data/src/main/java/org/apache/baremaps/data/calcite/CalciteMultipleDDLParser.java @@ -0,0 +1,14 @@ +package org.apache.baremaps.data.calcite; + +import org.apache.calcite.config.Lex; +import org.apache.calcite.sql.SqlNode; +import org.apache.calcite.sql.SqlNodeList; +import org.apache.calcite.sql.parser.SqlParser; +import org.apache.calcite.sql.parser.ddl.SqlDdlParserImpl; +import org.apache.calcite.sql.validate.SqlConformanceEnum; + +public class CalciteMultipleDDLParser { + public static void main(String[] args) throws Exception { + + } +} diff --git a/baremaps-data/src/test/java/org/apache/baremaps/data/calcite/CalciteTest.java b/baremaps-data/src/test/java/org/apache/baremaps/data/calcite/CalciteTest.java new file mode 100644 index 000000000..52768a70d --- /dev/null +++ b/baremaps-data/src/test/java/org/apache/baremaps/data/calcite/CalciteTest.java @@ -0,0 +1,170 @@ +/* + * 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.baremaps.data.calcite; + +import com.google.common.collect.ImmutableList; +import org.apache.baremaps.data.collection.AppendOnlyLog; +import org.apache.baremaps.data.collection.IndexedDataList; +import org.apache.baremaps.data.type.RowDataType; +import org.apache.baremaps.store.DataColumn.Cardinality; +import org.apache.baremaps.store.DataColumn.Type; +import org.apache.baremaps.store.*; +import org.apache.calcite.config.Lex; +import org.apache.calcite.jdbc.CalciteConnection; +import org.apache.calcite.model.ModelHandler; +import org.apache.calcite.runtime.SpatialTypeFunctions; +import org.apache.calcite.schema.SchemaPlus; +import org.apache.calcite.schema.impl.ViewTable; +import org.apache.calcite.schema.impl.ViewTableMacro; +import org.apache.calcite.sql.SqlNode; +import org.apache.calcite.sql.SqlNodeList; +import org.apache.calcite.sql.fun.SqlSpatialTypeFunctions; +import org.apache.calcite.sql.parser.SqlParseException; +import org.apache.calcite.sql.parser.SqlParser; +import org.apache.calcite.sql.parser.ddl.SqlDdlParserImpl; +import org.apache.calcite.sql.validate.SqlConformanceEnum; +import org.junit.jupiter.api.Test; +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.GeometryFactory; + +import java.sql.*; +import java.util.Collections; +import java.util.List; +import java.util.Properties; + +public class CalciteTest { + + @Test + void sql() throws SQLException { + GeometryFactory geometryFactory = new GeometryFactory(); + + // Configure Calcite connection properties + Properties info = new Properties(); + info.setProperty("lex", "MYSQL"); // Use MySQL dialect + info.setProperty("caseSensitive", "false"); // Disable case sensitivity + info.setProperty("unquotedCasing", "TO_LOWER"); // Convert unquoted identifiers to lowercase + info.setProperty("quotedCasing", "TO_LOWER"); + + try (Connection connection = DriverManager.getConnection("jdbc:calcite:", info)) { + CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class); + SchemaPlus rootSchema = calciteConnection.getRootSchema(); + + // Create and add 'city' table + DataSchema cityRowType = new DataSchemaImpl("city", List.of( + new DataColumnFixed("id", Cardinality.OPTIONAL, Type.INTEGER), + new DataColumnFixed("name", Cardinality.OPTIONAL, Type.STRING), + new DataColumnFixed("geometry", Cardinality.OPTIONAL, Type.GEOMETRY))); + + DataTable cityDataTable = new BaremapsDataTable( + cityRowType, + new IndexedDataList<>(new AppendOnlyLog<>(new RowDataType(cityRowType)))); + + cityDataTable.add(new DataRowImpl(cityDataTable.schema(), + List.of(1, "Paris", geometryFactory.createPoint(new Coordinate(2.3522, 48.8566))))); + cityDataTable.add(new DataRowImpl(cityDataTable.schema(), + List.of(2, "New York", geometryFactory.createPoint(new Coordinate(-74.0060, 40.7128))))); + + SqlDataTable citySqlDataTable = new SqlDataTable(cityDataTable); + rootSchema.add("city", citySqlDataTable); + + // Create and add 'population' table + DataSchema populationRowType = new DataSchemaImpl("population", List.of( + new DataColumnFixed("city_id", Cardinality.OPTIONAL, Type.INTEGER), + new DataColumnFixed("population", Cardinality.OPTIONAL, Type.INTEGER))); + + DataTable populationDataTable = new BaremapsDataTable( + populationRowType, + new IndexedDataList<>(new AppendOnlyLog<>(new RowDataType(populationRowType)))); + + populationDataTable.add(new DataRowImpl(populationDataTable.schema(), List.of(1, 2_161_000))); + populationDataTable.add(new DataRowImpl(populationDataTable.schema(), List.of(2, 8_336_000))); + + SqlDataTable populationSqlDataTable = new SqlDataTable(populationDataTable); + rootSchema.add("population", populationSqlDataTable); + + // Create view 'city_population' + String mvSql = "SELECT c.id, c.name, c.geometry, p.population " + + "FROM city c " + // lowercase and unquoted + "JOIN population p ON c.id = p.city_id"; + + ViewTableMacro materializedView = ViewTable.viewMacro( + rootSchema, + mvSql, + Collections.emptyList(), // Schema path + List.of("city_population"), // Name parts + false); // Not a materialized view + + rootSchema.add("city_population", materializedView); + + // Debug: List all tables in the root schema + System.out.println("Available tables in the root schema:"); + for (String tableName : rootSchema.getTableNames()) { + System.out.println(" - " + tableName); + } + + String sql = "SELECT * FROM city"; + try (Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(sql)) { + while (resultSet.next()) { + System.out.println(resultSet.getString("id") + " " + resultSet.getString("name")); + } + } + + // Query the view + sql = "SELECT * FROM city_population"; + try (Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(sql)) { + while (resultSet.next()) { + System.out.println( + resultSet.getString("id") + " " + resultSet.getString("name") + ); + } + } + } + + } + + @Test + void ddl() throws SqlParseException { + + // Example SQL script with multiple DDL statements + String sqlScript = """ + CREATE MATERIALIZED VIEW IF NOT EXISTS my_view AS + SELECT * FROM my_table; + """; + + // Build a parser config that supports DDL + SqlParser.Config config = SqlParser.configBuilder() + .setParserFactory(SqlDdlParserImpl.FACTORY) + .setConformance(SqlConformanceEnum.BABEL) + .setLex(Lex.MYSQL) + .build(); + + // Create the parser from the config + SqlParser parser = SqlParser.create(sqlScript, config); + + // Parse the script as a list of statements + SqlNodeList sqlNodeList = parser.parseStmtList(); + + // Iterate and print each parsed statement + for (SqlNode sqlNode : sqlNodeList) { + System.out.println("Parsed statement: " + sqlNode.toString()); + } + } + +} diff --git a/pom.xml b/pom.xml index e8da932e2..edb9af60a 100644 --- a/pom.xml +++ b/pom.xml @@ -88,7 +88,7 @@ limitations under the License. <version.lib.awssdk>2.27.17</version.lib.awssdk> <version.lib.brotli4j>1.16.0</version.lib.brotli4j> <version.lib.caffeine>3.1.8</version.lib.caffeine> - <version.lib.calcite>1.37.0</version.lib.calcite> + <version.lib.calcite>1.38.0</version.lib.calcite> <version.lib.commons-compress>1.27.1</version.lib.commons-compress> <version.lib.fastutil>8.5.14</version.lib.fastutil> <version.lib.flatgeobuf>3.26.2</version.lib.flatgeobuf> @@ -348,6 +348,11 @@ limitations under the License. <artifactId>calcite-core</artifactId> <version>${version.lib.calcite}</version> </dependency> + <dependency> + <groupId>org.apache.calcite</groupId> + <artifactId>calcite-server</artifactId> + <version>${version.lib.calcite}</version> + </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-compress</artifactId>
