You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by am...@apache.org on 2023/09/02 09:46:46 UTC
[ignite-3] 01/01: Minor refactoring.
This is an automated email from the ASF dual-hosted git repository.
amashenkov pushed a commit to branch ignite-20337
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
commit a16d9a3f5907e15bd9d53c1507eb78477c3dae09
Author: amashenkov <an...@gmail.com>
AuthorDate: Sat Sep 2 12:46:36 2023 +0300
Minor refactoring.
---
.../ignite/internal/sql/engine/ItMetadataTest.java | 15 ++--
.../internal/sql/engine/util/ColumnMatcher.java | 29 +++++++
.../internal/sql/engine/util/MetadataMatcher.java | 5 +-
.../internal/sql/engine/util/QueryChecker.java | 97 ++++++++++++----------
4 files changed, 94 insertions(+), 52 deletions(-)
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItMetadataTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItMetadataTest.java
index ef6bfcf166..c036dfa244 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItMetadataTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItMetadataTest.java
@@ -21,8 +21,6 @@ import static java.util.stream.Collectors.joining;
import static java.util.stream.Stream.generate;
import static org.apache.ignite.sql.ColumnMetadata.UNDEFINED_SCALE;
-import java.time.Duration;
-import java.time.Period;
import org.apache.ignite.internal.sql.engine.util.MetadataMatcher;
import org.apache.ignite.sql.ColumnType;
import org.junit.jupiter.api.BeforeAll;
@@ -92,9 +90,14 @@ public class ItMetadataTest extends ClusterPerClassIntegrationTest {
public void infixTypeCast() {
assertQuery("select id, id::tinyint as tid, id::smallint as sid, id::varchar as vid, id::interval hour, "
+ "id::interval year from person")
- .columnNames("ID", "TID", "SID", "VID", "ID :: INTERVAL INTERVAL_HOUR", "ID :: INTERVAL INTERVAL_YEAR")
- .columnTypes(Integer.class, Byte.class, Short.class, String.class, Duration.class, Period.class)
- .check();
+ .columnMetadata(
+ new MetadataMatcher().name("ID").type(ColumnType.INT32),
+ new MetadataMatcher().name("TID").type(ColumnType.INT8),
+ new MetadataMatcher().name("SID").type(ColumnType.INT16),
+ new MetadataMatcher().name("VID").type(ColumnType.STRING),
+ new MetadataMatcher().name("ID :: INTERVAL INTERVAL_HOUR").type(ColumnType.DURATION),
+ new MetadataMatcher().name("ID :: INTERVAL INTERVAL_YEAR").type(ColumnType.PERIOD)
+ ).check();
}
@Test
@@ -109,7 +112,7 @@ public class ItMetadataTest extends ClusterPerClassIntegrationTest {
@Test
public void metadata() {
sql("CREATE TABLE METADATA_TABLE (" + "ID INT PRIMARY KEY, "
- + "BOOLEAN_C BOOLEAN, "
+ + "BOOLEAN_C BOOLEAN, "
// Exact numeric types
+ "TINY_C TINYINT, " // TINYINT is not a part of any SQL standard.
diff --git a/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/ColumnMatcher.java b/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/ColumnMatcher.java
new file mode 100644
index 0000000000..02eb537870
--- /dev/null
+++ b/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/ColumnMatcher.java
@@ -0,0 +1,29 @@
+/*
+ * 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.ignite.internal.sql.engine.util;
+
+import org.apache.ignite.sql.ColumnMetadata;
+
+/**
+ * Column metadata matcher interface.
+ */
+@FunctionalInterface
+public interface ColumnMatcher {
+ /** Validates column metadata. */
+ void check(ColumnMetadata columnMetadata);
+}
diff --git a/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/MetadataMatcher.java b/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/MetadataMatcher.java
index f65d2d0fea..bc78b1ff0f 100644
--- a/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/MetadataMatcher.java
+++ b/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/MetadataMatcher.java
@@ -34,7 +34,7 @@ import org.junit.jupiter.api.function.Executable;
/**
* Column metadata checker.
*/
-public class MetadataMatcher {
+public class MetadataMatcher implements ColumnMatcher {
/** Marker object. */
private static final Object NO_CHECK = new Object() {
@Override
@@ -132,7 +132,8 @@ public class MetadataMatcher {
*
* @param actualMeta Metadata to check.
*/
- void check(ColumnMetadata actualMeta) {
+ @Override
+ public void check(ColumnMetadata actualMeta) {
List<Executable> matchers = new ArrayList<>();
if (name != NO_CHECK) {
diff --git a/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/QueryChecker.java b/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/QueryChecker.java
index a676e3cdc2..6b925b8e25 100644
--- a/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/QueryChecker.java
+++ b/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/QueryChecker.java
@@ -273,6 +273,34 @@ public abstract class QueryChecker {
String createQuery();
}
+ /** Validates method {@link #check()} method was called on {@link QueryChecker}. */
+ private static class QueryCheckerValidator {
+ QueryChecker currentChecker;
+ Throwable stacktrace;
+
+ void set(QueryChecker newChecker) {
+ if (currentChecker != null) {
+ throw new IllegalStateException("Found previous QueryChecker.", stacktrace);
+ }
+
+ currentChecker = newChecker;
+ stacktrace = new AssertionError("Method `check()` wasn't called.");
+ }
+
+ void remove(QueryChecker queryChecker) {
+ if (queryChecker == currentChecker) {
+ currentChecker = null;
+ }
+
+ IllegalStateException ex = new IllegalStateException("Unexpected QueryChecker.");
+ ex.addSuppressed(stacktrace);
+
+ throw ex;
+ }
+ }
+
+ private static final QueryCheckerValidator CURRENT_CHECKER_HOLDER = new QueryCheckerValidator();
+
private final QueryTemplate queryTemplate;
private final ArrayList<Matcher<String>> planMatchers = new ArrayList<>();
@@ -281,18 +309,12 @@ public abstract class QueryChecker {
private List<List<?>> expectedResult;
- private List<String> expectedColumnNames;
-
- private List<Type> expectedColumnTypes;
-
- private List<MetadataMatcher> metadataMatchers;
+ private List<ColumnMatcher> metadataMatchers;
private boolean ordered;
private Object[] params = OBJECT_EMPTY_ARRAY;
- private String exactPlan;
-
private Transaction tx;
/**
@@ -314,6 +336,9 @@ public abstract class QueryChecker {
public QueryChecker(Transaction tx, QueryTemplate queryTemplate) {
this.tx = tx;
this.queryTemplate = new AddDisabledRulesTemplate(queryTemplate, disabledRules);
+
+ //noinspection ThisEscapedInObjectConstruction
+ CURRENT_CHECKER_HOLDER.set(this);
}
/**
@@ -419,7 +444,11 @@ public abstract class QueryChecker {
* @return This.
*/
public QueryChecker columnNames(String... columns) {
- expectedColumnNames = Arrays.asList(columns);
+ assert metadataMatchers == null;
+
+ metadataMatchers = Arrays.stream(columns)
+ .map(name -> new MetadataMatcher().name(name))
+ .collect(Collectors.toList());
return this;
}
@@ -430,7 +459,15 @@ public abstract class QueryChecker {
* @return This.
*/
public QueryChecker columnTypes(Type... columns) {
- expectedColumnTypes = Arrays.asList(columns);
+ assert metadataMatchers == null;
+
+ metadataMatchers = Arrays.stream(columns)
+ .map(t -> (ColumnMatcher) columnMetadata -> {
+ Class<?> type = ColumnType.columnTypeToClass(columnMetadata.type());
+
+ assertThat("Column type don't match", type, equalTo(t));
+ })
+ .collect(Collectors.toList());
return this;
}
@@ -441,18 +478,9 @@ public abstract class QueryChecker {
* @return This.
*/
public QueryChecker columnMetadata(MetadataMatcher... matchers) {
- metadataMatchers = Arrays.asList(matchers);
+ assert metadataMatchers == null;
- return this;
- }
-
- /**
- * Sets plan.
- *
- * @return This.
- */
- public QueryChecker planEquals(String plan) {
- exactPlan = plan;
+ metadataMatchers = Arrays.asList(matchers);
return this;
}
@@ -461,6 +489,8 @@ public abstract class QueryChecker {
* Run checks.
*/
public void check() {
+ CURRENT_CHECKER_HOLDER.remove(this);
+
// Check plan.
QueryProcessor qryProc = getEngine();
@@ -472,7 +502,7 @@ public abstract class QueryChecker {
try {
- if (!CollectionUtils.nullOrEmpty(planMatchers) || exactPlan != null) {
+ if (!CollectionUtils.nullOrEmpty(planMatchers)) {
CompletableFuture<AsyncSqlCursor<List<Object>>> explainCursors = qryProc.querySingleAsync(sessionId,
context, transactions(), "EXPLAIN PLAN FOR " + qry, params);
@@ -486,10 +516,6 @@ public abstract class QueryChecker {
assertThat("Invalid plan:\n" + actualPlan, actualPlan, matcher);
}
}
-
- if (exactPlan != null) {
- assertEquals(exactPlan, actualPlan);
- }
}
// Check result.
CompletableFuture<AsyncSqlCursor<List<Object>>> cursors =
@@ -499,31 +525,14 @@ public abstract class QueryChecker {
checkMetadata(cur);
- if (expectedColumnNames != null) {
- List<String> colNames = cur.metadata().columns().stream()
- .map(ColumnMetadata::name)
- .collect(Collectors.toList());
-
- assertThat("Column names don't match", colNames, equalTo(expectedColumnNames));
- }
-
- if (expectedColumnTypes != null) {
- List<Type> colTypes = cur.metadata().columns().stream()
- .map(ColumnMetadata::type)
- .map(ColumnType::columnTypeToClass)
- .collect(Collectors.toList());
-
- assertThat("Column types don't match", colTypes, equalTo(expectedColumnTypes));
- }
-
if (metadataMatchers != null) {
List<ColumnMetadata> columnMetadata = cur.metadata().columns();
Iterator<ColumnMetadata> valueIterator = columnMetadata.iterator();
- Iterator<MetadataMatcher> matcherIterator = metadataMatchers.iterator();
+ Iterator<ColumnMatcher> matcherIterator = metadataMatchers.iterator();
while (matcherIterator.hasNext() && valueIterator.hasNext()) {
- MetadataMatcher matcher = matcherIterator.next();
+ ColumnMatcher matcher = matcherIterator.next();
ColumnMetadata actualElement = valueIterator.next();
matcher.check(actualElement);