This is an automated email from the ASF dual-hosted git repository. jackietien pushed a commit to branch ty/TableModelGrammar in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 5bbcd7b1ee4b58b1b7880abb0553c6fb32844e19 Author: JackieTien97 <[email protected]> AuthorDate: Thu Feb 29 15:28:26 2024 +0800 first UT --- .../relational/metadata/QualifiedObjectName.java | 4 - .../plan/relational/analyzer/AnalyzerTest.java | 70 +++++++++++++++++- .../db/relational/grammar/sql/RelationalSql.g4 | 2 +- .../sql/parser/CaseInsensitiveStream.java | 85 ++++++++++++++++++++++ .../iotdb/db/relational/sql/parser/SqlParser.java | 3 +- 5 files changed, 156 insertions(+), 8 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/QualifiedObjectName.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/QualifiedObjectName.java index a6dd9b55fb4..834170b27d6 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/QualifiedObjectName.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/QualifiedObjectName.java @@ -19,8 +19,6 @@ package org.apache.iotdb.db.queryengine.plan.relational.metadata; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; import com.google.errorprone.annotations.Immutable; import java.util.Objects; @@ -38,7 +36,6 @@ public class QualifiedObjectName { private static final Pattern PATTERN = Pattern.compile("(?<database>" + COMPONENT + ")\\.(?<table>" + COMPONENT + ")"); - @JsonCreator public static QualifiedObjectName valueOf(String name) { requireNonNull(name, "name is null"); Matcher matcher = PATTERN.matcher(name); @@ -85,7 +82,6 @@ public class QualifiedObjectName { return Objects.hash(dbName, objectName); } - @JsonValue @Override public String toString() { return quoteIfNeeded(dbName) + '.' + quoteIfNeeded(objectName); diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java index 3feb40ada8d..d12e478efa9 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java @@ -20,7 +20,18 @@ package org.apache.iotdb.db.queryengine.plan.relational.analyzer; import org.apache.iotdb.db.queryengine.common.SessionInfo; +import org.apache.iotdb.db.queryengine.plan.relational.function.BoundSignature; +import org.apache.iotdb.db.queryengine.plan.relational.function.FunctionId; +import org.apache.iotdb.db.queryengine.plan.relational.function.FunctionKind; +import org.apache.iotdb.db.queryengine.plan.relational.function.OperatorType; +import org.apache.iotdb.db.queryengine.plan.relational.metadata.ColumnHandle; +import org.apache.iotdb.db.queryengine.plan.relational.metadata.ColumnSchema; import org.apache.iotdb.db.queryengine.plan.relational.metadata.Metadata; +import org.apache.iotdb.db.queryengine.plan.relational.metadata.OperatorNotFoundException; +import org.apache.iotdb.db.queryengine.plan.relational.metadata.QualifiedObjectName; +import org.apache.iotdb.db.queryengine.plan.relational.metadata.ResolvedFunction; +import org.apache.iotdb.db.queryengine.plan.relational.metadata.TableHandle; +import org.apache.iotdb.db.queryengine.plan.relational.metadata.TableSchema; import org.apache.iotdb.db.queryengine.plan.relational.security.AccessControl; import org.apache.iotdb.db.relational.sql.parser.SqlParser; import org.apache.iotdb.db.relational.sql.tree.Statement; @@ -29,11 +40,20 @@ import org.junit.Test; import org.mockito.Mockito; import java.time.ZoneId; +import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; import static org.apache.iotdb.db.queryengine.execution.warnings.WarningCollector.NOOP; +import static org.apache.iotdb.tsfile.read.common.type.BooleanType.BOOLEAN; +import static org.apache.iotdb.tsfile.read.common.type.IntType.INT32; +import static org.apache.iotdb.tsfile.read.common.type.LongType.INT64; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.eq; public class AnalyzerTest { @@ -42,11 +62,57 @@ public class AnalyzerTest { private final NopAccessControl nopAccessControl = new NopAccessControl(); @Test - public void testRawDataQuery() { - String sql = "select s1, status, s1 + 1 as t from table1 where time > 100 and s2 > 10;"; + public void testRawDataQuery() throws OperatorNotFoundException { + String sql = "SELECT s1, (s1 + 1) as t from table1 where time > 100 and s2 > 10"; Metadata metadata = Mockito.mock(Metadata.class); Mockito.when(metadata.tableExists(Mockito.any())).thenReturn(true); + TableHandle tableHandle = Mockito.mock(TableHandle.class); + Mockito.when( + metadata.getTableHandle(Mockito.any(), eq(new QualifiedObjectName("testdb", "table1")))) + .thenReturn(Optional.of(tableHandle)); + + Map<String, ColumnHandle> map = new HashMap<>(); + TableSchema tableSchema = Mockito.mock(TableSchema.class); + Mockito.when(tableSchema.getTableName()).thenReturn("table1"); + ColumnSchema column1 = + ColumnSchema.builder().setName("time").setType(INT64).setHidden(false).build(); + ColumnHandle column1Handle = Mockito.mock(ColumnHandle.class); + map.put("time", column1Handle); + ColumnSchema column2 = + ColumnSchema.builder().setName("s1").setType(INT32).setHidden(false).build(); + ColumnHandle column2Handle = Mockito.mock(ColumnHandle.class); + map.put("s1", column2Handle); + ColumnSchema column3 = + ColumnSchema.builder().setName("s2").setType(INT64).setHidden(false).build(); + ColumnHandle column3Handle = Mockito.mock(ColumnHandle.class); + map.put("s2", column3Handle); + List<ColumnSchema> columnSchemaList = Arrays.asList(column1, column2, column3); + Mockito.when(tableSchema.getColumns()).thenReturn(columnSchemaList); + + Mockito.when(metadata.getTableSchema(Mockito.any(), eq(tableHandle))).thenReturn(tableSchema); + Mockito.when(metadata.getColumnHandles(Mockito.any(), eq(tableHandle))).thenReturn(map); + + ResolvedFunction lLessThanI = + new ResolvedFunction( + new BoundSignature("l<i", BOOLEAN, Arrays.asList(INT64, INT32)), + new FunctionId("l<i"), + FunctionKind.SCALAR, + true); + + ResolvedFunction iAddi = + new ResolvedFunction( + new BoundSignature("l+i", INT64, Arrays.asList(INT32, INT32)), + new FunctionId("l+i"), + FunctionKind.SCALAR, + true); + + Mockito.when( + metadata.resolveOperator(eq(OperatorType.LESS_THAN), eq(Arrays.asList(INT64, INT32)))) + .thenReturn(lLessThanI); + Mockito.when(metadata.resolveOperator(eq(OperatorType.ADD), eq(Arrays.asList(INT32, INT32)))) + .thenReturn(iAddi); + Analysis actualAnalysis = analyzeSQL(sql, metadata); assertNotNull(actualAnalysis); System.out.println(actualAnalysis.getTypes()); diff --git a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4 b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4 index 880ab455df7..26cd32456e6 100644 --- a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4 +++ b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4 @@ -729,7 +729,7 @@ nonReserved | RANGE | READ | READONLY | REFRESH | REGION | REGIONID | REGIONS | RENAME | REPAIR | REPEAT | REPEATABLE | REPLACE | RESET | RESPECT | RESTRICT | RETURN | RETURNING | RETURNS | REVOKE | ROLE | ROLES | ROLLBACK | ROW | ROWS | RUNNING | SERIESSLOTID | SCALAR | SCHEMA | SCHEMAS | SECOND | SECURITY | SEEK | SERIALIZABLE | SESSION | SET | SETS | SHOW | SOME | START | STATS | SUBSET | SUBSTRING | SYSTEM - | TABLES | TABLESAMPLE | TEXT | TEXT_STRING | TIES | TIMEPARTITION | TIMESERIES | TIMESLOTID | TIMESTAMP | TO | TRAILING | TRANSACTION | TRUNCATE | TRY_CAST | TYPE + | TABLES | TABLESAMPLE | TEXT | TEXT_STRING | TIES | TIME | TIMEPARTITION | TIMESERIES | TIMESLOTID | TIMESTAMP | TO | TRAILING | TRANSACTION | TRUNCATE | TRY_CAST | TYPE | UNBOUNDED | UNCOMMITTED | UNCONDITIONAL | UNIQUE | UNKNOWN | UNMATCHED | UNTIL | UPDATE | URI | USE | USER | UTF16 | UTF32 | UTF8 | VALIDATE | VALUE | VARIABLES | VARIATION | VERBOSE | VERSION | VIEW | WEEK | WHILE | WINDOW | WITHIN | WITHOUT | WORK | WRAPPER | WRITE diff --git a/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/parser/CaseInsensitiveStream.java b/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/parser/CaseInsensitiveStream.java new file mode 100644 index 00000000000..f6883a7308e --- /dev/null +++ b/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/parser/CaseInsensitiveStream.java @@ -0,0 +1,85 @@ +/* + * 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.iotdb.db.relational.sql.parser; + +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.IntStream; +import org.antlr.v4.runtime.misc.Interval; + +public class CaseInsensitiveStream implements CharStream { + private final CharStream stream; + + public CaseInsensitiveStream(CharStream stream) { + this.stream = stream; + } + + @Override + public String getText(Interval interval) { + return stream.getText(interval); + } + + @Override + public void consume() { + stream.consume(); + } + + @Override + public int LA(int i) { + int result = stream.LA(i); + + switch (result) { + case 0: + case IntStream.EOF: + return result; + default: + return Character.toUpperCase(result); + } + } + + @Override + public int mark() { + return stream.mark(); + } + + @Override + public void release(int marker) { + stream.release(marker); + } + + @Override + public int index() { + return stream.index(); + } + + @Override + public void seek(int index) { + stream.seek(index); + } + + @Override + public int size() { + return stream.size(); + } + + @Override + public String getSourceName() { + return stream.getSourceName(); + } +} diff --git a/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/parser/SqlParser.java b/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/parser/SqlParser.java index 6a8e652fe63..2df8fecc3bb 100644 --- a/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/parser/SqlParser.java +++ b/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/parser/SqlParser.java @@ -123,7 +123,8 @@ public class SqlParser { Optional<NodeLocation> location, Function<RelationalSqlParser, ParserRuleContext> parseFunction) { try { - RelationalSqlLexer lexer = new RelationalSqlLexer(CharStreams.fromString(sql)); + RelationalSqlLexer lexer = + new RelationalSqlLexer(new CaseInsensitiveStream(CharStreams.fromString(sql))); CommonTokenStream tokenStream = new CommonTokenStream(lexer); RelationalSqlParser parser = new RelationalSqlParser(tokenStream); initializer.accept(lexer, parser);
