You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by pp...@apache.org on 2024/01/16 10:30:40 UTC
(ignite-3) branch main updated: IGNITE-21166 Sql. Provide internal API to get a columns metadata for non-executed query (#3037)
This is an automated email from the ASF dual-hosted git repository.
ppa pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new a9d4ae29e6 IGNITE-21166 Sql. Provide internal API to get a columns metadata for non-executed query (#3037)
a9d4ae29e6 is described below
commit a9d4ae29e64c1282a5af7afc04c1f3d3325d4989
Author: Pavel Pereslegin <xx...@gmail.com>
AuthorDate: Tue Jan 16 13:30:35 2024 +0300
IGNITE-21166 Sql. Provide internal API to get a columns metadata for non-executed query (#3037)
---
.../sql/ClientSqlParameterMetadataRequest.java | 4 +-
.../client/fakes/FakeIgniteQueryProcessor.java | 4 +-
.../sql/engine/ItDynamicParameterTest.java | 23 +++++----
.../ignite/internal/sql/engine/QueryProcessor.java | 9 ++--
.../internal/sql/engine/SqlQueryProcessor.java | 12 ++---
.../internal/sql/engine/prepare/QueryMetadata.java | 53 ++++++++++++++++++++
.../internal/sql/engine/util/QueryCheckerTest.java | 56 ++++++++++++++++++----
.../internal/sql/engine/util/QueryCheckerImpl.java | 42 +++++++++++-----
8 files changed, 156 insertions(+), 47 deletions(-)
diff --git a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/sql/ClientSqlParameterMetadataRequest.java b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/sql/ClientSqlParameterMetadataRequest.java
index d4eef1a73f..4eb61cfeca 100644
--- a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/sql/ClientSqlParameterMetadataRequest.java
+++ b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/sql/ClientSqlParameterMetadataRequest.java
@@ -25,7 +25,7 @@ import org.apache.ignite.internal.client.proto.ClientMessagePacker;
import org.apache.ignite.internal.client.proto.ClientMessageUnpacker;
import org.apache.ignite.internal.sql.engine.QueryProcessor;
import org.apache.ignite.internal.sql.engine.QueryProperty;
-import org.apache.ignite.internal.sql.engine.prepare.ParameterMetadata;
+import org.apache.ignite.internal.sql.engine.prepare.QueryMetadata;
import org.apache.ignite.internal.sql.engine.property.SqlProperties;
import org.apache.ignite.internal.sql.engine.property.SqlPropertiesHelper;
@@ -57,7 +57,7 @@ public class ClientSqlParameterMetadataRequest {
return processor.prepareSingleAsync(properties, tx, query).thenAccept(meta -> writeMeta(out, meta));
}
- private static void writeMeta(ClientMessagePacker out, ParameterMetadata meta) {
+ private static void writeMeta(ClientMessagePacker out, QueryMetadata meta) {
var types = meta.parameterTypes();
out.packInt(types.size());
diff --git a/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeIgniteQueryProcessor.java b/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeIgniteQueryProcessor.java
index 528ddabd3e..fbdfc5ffb2 100644
--- a/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeIgniteQueryProcessor.java
+++ b/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeIgniteQueryProcessor.java
@@ -23,7 +23,7 @@ import java.util.concurrent.CompletableFuture;
import org.apache.ignite.internal.sql.engine.AsyncSqlCursor;
import org.apache.ignite.internal.sql.engine.InternalSqlRow;
import org.apache.ignite.internal.sql.engine.QueryProcessor;
-import org.apache.ignite.internal.sql.engine.prepare.ParameterMetadata;
+import org.apache.ignite.internal.sql.engine.prepare.QueryMetadata;
import org.apache.ignite.internal.sql.engine.property.SqlProperties;
import org.apache.ignite.internal.tx.InternalTransaction;
import org.apache.ignite.tx.IgniteTransactions;
@@ -34,7 +34,7 @@ import org.jetbrains.annotations.Nullable;
*/
public class FakeIgniteQueryProcessor implements QueryProcessor {
@Override
- public CompletableFuture<ParameterMetadata> prepareSingleAsync(SqlProperties properties,
+ public CompletableFuture<QueryMetadata> prepareSingleAsync(SqlProperties properties,
@Nullable InternalTransaction transaction, String qry, Object... params) {
throw new UnsupportedOperationException();
}
diff --git a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDynamicParameterTest.java b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDynamicParameterTest.java
index 22ebd676f5..ffc6803f57 100644
--- a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDynamicParameterTest.java
+++ b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDynamicParameterTest.java
@@ -33,7 +33,6 @@ import java.util.stream.Stream;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.ignite.internal.sql.BaseSqlIntegrationTest;
-import org.apache.ignite.internal.sql.engine.prepare.ParameterMetadata;
import org.apache.ignite.internal.sql.engine.prepare.ParameterType;
import org.apache.ignite.internal.sql.engine.property.SqlProperties;
import org.apache.ignite.internal.sql.engine.property.SqlPropertiesHelper;
@@ -294,9 +293,9 @@ public class ItDynamicParameterTest extends BaseSqlIntegrationTest {
@ParameterizedTest
@MethodSource("statementsWithParameters")
public void testGetParameterTypesSimple(String stmt, List<ColumnType> expectedTypes, Object[] params) {
- ParameterMetadata parameterTypes = getParameterMetadata(stmt, params);
+ List<ParameterType> parameterTypes = getParameterTypes(stmt, params);
- List<ColumnType> columnTypes = parameterTypes.parameterTypes()
+ List<ColumnType> columnTypes = parameterTypes
.stream()
.map(ParameterType::columnType)
.collect(Collectors.toList());
@@ -321,7 +320,7 @@ public class ItDynamicParameterTest extends BaseSqlIntegrationTest {
assertThrowsSqlException(
Sql.STMT_VALIDATION_ERR,
"Unexpected number of query parameters",
- () -> getParameterMetadata("SELECT ? + ?", 1, 2, 3));
+ () -> getParameterTypes("SELECT ? + ?", 1, 2, 3));
}
@Test
@@ -341,9 +340,9 @@ public class ItDynamicParameterTest extends BaseSqlIntegrationTest {
log.info("SELECT from column names: {}", stmt);
- ParameterMetadata parameterTypes = getParameterMetadata(stmt.toString());
+ List<ParameterType> parameterTypes = getParameterTypes(stmt.toString());
- List<NativeType> actualTypes = parameterTypes.parameterTypes().stream()
+ List<NativeType> actualTypes = parameterTypes.stream()
.map(p -> TypeUtils.columnType2NativeType(p.columnType(), p.precision(), p.scale(), p.precision()))
.collect(Collectors.toList());
@@ -362,9 +361,9 @@ public class ItDynamicParameterTest extends BaseSqlIntegrationTest {
log.info("INSERT from column names: {}", stmt);
- ParameterMetadata parameterTypes = getParameterMetadata(stmt.toString());
+ List<ParameterType> parameterTypes = getParameterTypes(stmt.toString());
- List<NativeType> actualTypes = parameterTypes.parameterTypes().stream()
+ List<NativeType> actualTypes = parameterTypes.stream()
.map(p -> TypeUtils.columnType2NativeType(p.columnType(), p.precision(), p.scale(), p.precision()))
.collect(Collectors.toList());
@@ -389,9 +388,9 @@ public class ItDynamicParameterTest extends BaseSqlIntegrationTest {
log.info("UPDATE from column names: {}", stmt);
- ParameterMetadata parameterTypes = getParameterMetadata(stmt.toString());
+ List<ParameterType> parameterTypes = getParameterTypes(stmt.toString());
- List<NativeType> actualTypes = parameterTypes.parameterTypes().stream()
+ List<NativeType> actualTypes = parameterTypes.stream()
.map(p -> TypeUtils.columnType2NativeType(p.columnType(), p.precision(), p.scale(), p.precision()))
.collect(Collectors.toList());
@@ -452,9 +451,9 @@ public class ItDynamicParameterTest extends BaseSqlIntegrationTest {
() -> assertQuery(query).withParams(params).check());
}
- private ParameterMetadata getParameterMetadata(String query, Object... params) {
+ private List<ParameterType> getParameterTypes(String query, Object... params) {
QueryProcessor qryProc = queryProcessor();
SqlProperties properties = SqlPropertiesHelper.emptyProperties();
- return await(qryProc.prepareSingleAsync(properties, null, query, params));
+ return await(qryProc.prepareSingleAsync(properties, null, query, params)).parameterTypes();
}
}
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/QueryProcessor.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/QueryProcessor.java
index 258651d37e..190b3a6a58 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/QueryProcessor.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/QueryProcessor.java
@@ -19,7 +19,7 @@ package org.apache.ignite.internal.sql.engine;
import java.util.concurrent.CompletableFuture;
import org.apache.ignite.internal.manager.IgniteComponent;
-import org.apache.ignite.internal.sql.engine.prepare.ParameterMetadata;
+import org.apache.ignite.internal.sql.engine.prepare.QueryMetadata;
import org.apache.ignite.internal.sql.engine.property.SqlProperties;
import org.apache.ignite.internal.tx.InternalTransaction;
import org.apache.ignite.lang.IgniteException;
@@ -32,18 +32,19 @@ import org.jetbrains.annotations.Nullable;
public interface QueryProcessor extends IgniteComponent {
/**
- * Returns parameter metadata for the given statement. This method uses optional array of parameters to assist with type inference.
+ * Returns columns and parameters metadata for the given statement.
+ * This method uses optional array of parameters to assist with type inference.
*
* @param properties User query properties. See {@link QueryProperty} for available properties.
* @param transaction A transaction to use to resolve a schema.
* @param qry Single statement SQL query.
* @param params Query parameters.
- * @return Parameter metadata.
+ * @return Query metadata.
*
* @throws IgniteException in case of an error.
* @see QueryProperty
*/
- CompletableFuture<ParameterMetadata> prepareSingleAsync(SqlProperties properties,
+ CompletableFuture<QueryMetadata> prepareSingleAsync(SqlProperties properties,
@Nullable InternalTransaction transaction,
String qry, Object... params);
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/SqlQueryProcessor.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/SqlQueryProcessor.java
index c660152014..cfc62f603c 100644
--- a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/SqlQueryProcessor.java
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/SqlQueryProcessor.java
@@ -91,9 +91,9 @@ import org.apache.ignite.internal.sql.engine.exec.mapping.ExecutionTargetFactory
import org.apache.ignite.internal.sql.engine.exec.mapping.ExecutionTargetProvider;
import org.apache.ignite.internal.sql.engine.exec.mapping.MappingServiceImpl;
import org.apache.ignite.internal.sql.engine.message.MessageServiceImpl;
-import org.apache.ignite.internal.sql.engine.prepare.ParameterMetadata;
import org.apache.ignite.internal.sql.engine.prepare.PrepareService;
import org.apache.ignite.internal.sql.engine.prepare.PrepareServiceImpl;
+import org.apache.ignite.internal.sql.engine.prepare.QueryMetadata;
import org.apache.ignite.internal.sql.engine.prepare.QueryPlan;
import org.apache.ignite.internal.sql.engine.property.SqlProperties;
import org.apache.ignite.internal.sql.engine.property.SqlPropertiesHelper;
@@ -428,7 +428,7 @@ public class SqlQueryProcessor implements QueryProcessor {
/** {@inheritDoc} */
@Override
- public CompletableFuture<ParameterMetadata> prepareSingleAsync(SqlProperties properties,
+ public CompletableFuture<QueryMetadata> prepareSingleAsync(SqlProperties properties,
@Nullable InternalTransaction transaction,
String qry, Object... params) {
@@ -489,7 +489,7 @@ public class SqlQueryProcessor implements QueryProcessor {
return service;
}
- private CompletableFuture<ParameterMetadata> prepareSingleAsync0(
+ private CompletableFuture<QueryMetadata> prepareSingleAsync0(
SqlProperties properties,
@Nullable InternalTransaction explicitTransaction,
String sql,
@@ -500,9 +500,9 @@ public class SqlQueryProcessor implements QueryProcessor {
QueryCancel queryCancel = new QueryCancel();
- CompletableFuture<ParameterMetadata> start = new CompletableFuture<>();
+ CompletableFuture<QueryMetadata> start = new CompletableFuture<>();
- CompletableFuture<ParameterMetadata> stage = start.thenCompose(ignored -> {
+ CompletableFuture<QueryMetadata> stage = start.thenCompose(ignored -> {
ParsedResult result = parserService.parse(sql);
validateParsedStatement(properties0, result);
@@ -511,7 +511,7 @@ public class SqlQueryProcessor implements QueryProcessor {
HybridTimestamp timestamp = explicitTransaction != null ? explicitTransaction.startTimestamp() : clock.now();
return prepareParsedStatement(schemaName, result, timestamp, queryCancel, params)
- .thenApply(QueryPlan::parameterMetadata);
+ .thenApply(plan -> new QueryMetadata(plan.metadata(), plan.parameterMetadata()));
});
// TODO IGNITE-20078 Improve (or remove) CancellationException handling.
diff --git a/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/QueryMetadata.java b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/QueryMetadata.java
new file mode 100644
index 0000000000..dedf6fb423
--- /dev/null
+++ b/modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/QueryMetadata.java
@@ -0,0 +1,53 @@
+/*
+ * 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.prepare;
+
+import java.util.List;
+import org.apache.ignite.internal.tostring.IgniteToStringInclude;
+import org.apache.ignite.internal.tostring.S;
+import org.apache.ignite.sql.ColumnMetadata;
+import org.apache.ignite.sql.ResultSetMetadata;
+
+/**
+ * Query metadata combines {@link ParameterMetadata dynamic parameters metadata} and {@link ColumnMetadata columns metadata}.
+ */
+public class QueryMetadata {
+ @IgniteToStringInclude
+ private final List<ColumnMetadata> columns;
+
+ @IgniteToStringInclude
+ private final List<ParameterType> parameterTypes;
+
+ public QueryMetadata(ResultSetMetadata resultSetMetadata, ParameterMetadata parameterMetadata) {
+ this.columns = resultSetMetadata.columns();
+ this.parameterTypes = parameterMetadata.parameterTypes();
+ }
+
+ public List<ColumnMetadata> columns() {
+ return columns;
+ }
+
+ public List<ParameterType> parameterTypes() {
+ return parameterTypes;
+ }
+
+ @Override
+ public String toString() {
+ return S.toString(QueryMetadata.class, this);
+ }
+}
diff --git a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/util/QueryCheckerTest.java b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/util/QueryCheckerTest.java
index caed3ae0bd..a513697824 100644
--- a/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/util/QueryCheckerTest.java
+++ b/modules/sql-engine/src/test/java/org/apache/ignite/internal/sql/engine/util/QueryCheckerTest.java
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.sql.engine.util;
+import static org.apache.ignite.internal.testframework.IgniteTestUtils.assertThrows;
import static org.apache.ignite.internal.testframework.IgniteTestUtils.assertThrowsWithCause;
import static org.apache.ignite.internal.util.CompletableFutures.nullCompletedFuture;
import static org.hamcrest.Matchers.containsString;
@@ -33,7 +34,7 @@ import org.apache.ignite.internal.sql.engine.framework.NoOpTransaction;
import org.apache.ignite.internal.sql.engine.framework.TestBuilders;
import org.apache.ignite.internal.sql.engine.framework.TestCluster;
import org.apache.ignite.internal.sql.engine.framework.TestNode;
-import org.apache.ignite.internal.sql.engine.prepare.ParameterMetadata;
+import org.apache.ignite.internal.sql.engine.prepare.QueryMetadata;
import org.apache.ignite.internal.sql.engine.prepare.QueryPlan;
import org.apache.ignite.internal.sql.engine.property.SqlProperties;
import org.apache.ignite.internal.sql.engine.tx.QueryTransactionWrapperImpl;
@@ -216,15 +217,15 @@ public class QueryCheckerTest extends BaseIgniteAbstractTest {
@Test
void testMetadata() {
- assertQuery("SELECT * FROM t1")
+ assertQueryMeta("SELECT * FROM t1")
.columnNames("ID", "VAL")
.check();
- assertQuery("SELECT * FROM t1")
+ assertQueryMeta("SELECT * FROM t1")
.columnTypes(Integer.class, Integer.class)
.check();
- assertQuery("SELECT id, val::DECIMAL(19, 2) as val_dec, id::VARCHAR(64) as id_str FROM t1")
+ assertQueryMeta("SELECT id, val::DECIMAL(19, 2) as val_dec, id::VARCHAR(64) as id_str FROM t1")
.columnMetadata(
new MetadataMatcher()
.name("ID")
@@ -248,13 +249,44 @@ public class QueryCheckerTest extends BaseIgniteAbstractTest {
.nullable(false)
)
.check();
+
+ // Test that validates the results cannot be executed correctly without actually executing the query.
+ assertThrows(
+ AssertionError.class,
+ () -> assertQueryMeta("SELECT * FROM t1")
+ .columnTypes(Integer.class, Integer.class)
+ .returns(1, 1)
+ .returns(2, 2)
+ .check(),
+ "Expected that the query will only be prepared, but not executed"
+ );
+
+ // Test that only checks metadata should not execute the query.
+ assertThrows(
+ AssertionError.class,
+ () -> assertQuery("SELECT * FROM t1")
+ .columnTypes(Integer.class, Integer.class)
+ .check(),
+ "Expected that the query will be executed"
+ );
}
private static QueryChecker assertQuery(String qry) {
TestNode testNode = CLUSTER.node(NODE_NAME);
return queryCheckerFactory.create(
- new TestQueryProcessor(testNode),
+ new TestQueryProcessor(testNode, false),
+ new TestIgniteTransactions(),
+ null,
+ qry
+ );
+ }
+
+ private static QueryChecker assertQueryMeta(String qry) {
+ TestNode testNode = CLUSTER.node(NODE_NAME);
+
+ return queryCheckerFactory.create(
+ new TestQueryProcessor(testNode, true),
new TestIgniteTransactions(),
null,
qry
@@ -263,15 +295,22 @@ public class QueryCheckerTest extends BaseIgniteAbstractTest {
private static class TestQueryProcessor implements QueryProcessor {
private final TestNode node;
+ private final boolean prepareOnly;
- TestQueryProcessor(TestNode node) {
+ TestQueryProcessor(TestNode node, boolean prepareOnly) {
this.node = node;
+ this.prepareOnly = prepareOnly;
}
@Override
- public CompletableFuture<ParameterMetadata> prepareSingleAsync(SqlProperties properties,
+ public CompletableFuture<QueryMetadata> prepareSingleAsync(SqlProperties properties,
@Nullable InternalTransaction transaction, String qry, Object... params) {
- throw new UnsupportedOperationException();
+ assert params == null || params.length == 0 : "params are not supported";
+ assert prepareOnly : "Expected that the query will be executed";
+
+ QueryPlan plan = node.prepare(qry);
+
+ return CompletableFuture.completedFuture(new QueryMetadata(plan.metadata(), plan.parameterMetadata()));
}
@Override
@@ -283,6 +322,7 @@ public class QueryCheckerTest extends BaseIgniteAbstractTest {
Object... params
) {
assert params == null || params.length == 0 : "params are not supported";
+ assert !prepareOnly : "Expected that the query will only be prepared, but not executed";
QueryPlan plan = node.prepare(qry);
AsyncCursor<InternalSqlRow> dataCursor = node.executePlan(plan);
diff --git a/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/QueryCheckerImpl.java b/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/QueryCheckerImpl.java
index 1a154cca07..5afdfae3ce 100644
--- a/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/QueryCheckerImpl.java
+++ b/modules/sql-engine/src/testFixtures/java/org/apache/ignite/internal/sql/engine/util/QueryCheckerImpl.java
@@ -27,6 +27,7 @@ import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.not;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
import java.lang.reflect.Type;
@@ -48,6 +49,7 @@ import org.apache.ignite.internal.sql.engine.QueryProcessor;
import org.apache.ignite.internal.sql.engine.QueryProperty;
import org.apache.ignite.internal.sql.engine.SqlQueryType;
import org.apache.ignite.internal.sql.engine.hint.IgniteHint;
+import org.apache.ignite.internal.sql.engine.prepare.QueryMetadata;
import org.apache.ignite.internal.sql.engine.property.SqlProperties;
import org.apache.ignite.internal.sql.engine.property.SqlPropertiesHelper;
import org.apache.ignite.internal.tx.InternalTransaction;
@@ -300,6 +302,18 @@ abstract class QueryCheckerImpl implements QueryChecker {
}
}
}
+
+ // Check column metadata only.
+ if (resultChecker == null && metadataMatchers != null) {
+ QueryMetadata queryMetadata = await(qryProc.prepareSingleAsync(PROPERTIES, tx, qry, params));
+
+ assertNotNull(queryMetadata);
+
+ checkColumnsMetadata(queryMetadata.columns());
+
+ return;
+ }
+
// Check result.
CompletableFuture<AsyncSqlCursor<InternalSqlRow>> cursors =
qryProc.querySingleAsync(PROPERTIES, transactions(), tx, qry, params);
@@ -309,19 +323,7 @@ abstract class QueryCheckerImpl implements QueryChecker {
checkMetadata(cur.metadata());
if (metadataMatchers != null) {
- List<ColumnMetadata> columnMetadata = cur.metadata().columns();
-
- Iterator<ColumnMetadata> valueIterator = columnMetadata.iterator();
- Iterator<ColumnMatcher> matcherIterator = metadataMatchers.iterator();
-
- while (matcherIterator.hasNext() && valueIterator.hasNext()) {
- ColumnMatcher matcher = matcherIterator.next();
- ColumnMetadata actualElement = valueIterator.next();
-
- matcher.check(actualElement);
- }
-
- assertEquals(metadataMatchers.size(), columnMetadata.size(), "Column metadata doesn't match");
+ checkColumnsMetadata(cur.metadata().columns());
}
List<InternalSqlRow> rows = Commons.cast(getAllFromCursor(cur));
@@ -332,6 +334,20 @@ abstract class QueryCheckerImpl implements QueryChecker {
}
}
+ private void checkColumnsMetadata(List<ColumnMetadata> columnsMetadata) {
+ Iterator<ColumnMetadata> valueIterator = columnsMetadata.iterator();
+ Iterator<ColumnMatcher> matcherIterator = metadataMatchers.iterator();
+
+ while (matcherIterator.hasNext() && valueIterator.hasNext()) {
+ ColumnMatcher matcher = matcherIterator.next();
+ ColumnMetadata actualElement = valueIterator.next();
+
+ matcher.check(actualElement);
+ }
+
+ assertEquals(metadataMatchers.size(), columnsMetadata.size(), "Column metadata doesn't match");
+ }
+
@Override
public String toString() {
return QueryCheckerImpl.class.getSimpleName() + "[sql=" + queryTemplate.originalQueryString() + "]";