This is an automated email from the ASF dual-hosted git repository. ivandasch pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push: new 8dd17748482 IGNITE-21491 SQL Calcite: Fix assertion error for multiline statements in thin client (#11394) 8dd17748482 is described below commit 8dd17748482189db05aad6f1b107fb36c2bc883e Author: Ivan Daschinskiy <ivanda...@apache.org> AuthorDate: Tue Jun 18 13:34:26 2024 +0300 IGNITE-21491 SQL Calcite: Fix assertion error for multiline statements in thin client (#11394) --- .../query/calcite/CalciteQueryProcessor.java | 8 ++ .../query/calcite/thin/MultiLineQueryTest.java | 108 +++++++++++++++++++++ .../ignite/testsuites/IntegrationTestSuite.java | 2 + .../processors/query/GridQueryProcessor.java | 6 +- .../internal/processors/query/QueryProperties.java | 11 ++- 5 files changed, 133 insertions(+), 2 deletions(-) diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessor.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessor.java index c1f4f90aeeb..fd00f2dfa3b 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessor.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessor.java @@ -65,6 +65,7 @@ import org.apache.ignite.internal.processors.query.IgniteSQLException; import org.apache.ignite.internal.processors.query.QueryContext; import org.apache.ignite.internal.processors.query.QueryEngine; import org.apache.ignite.internal.processors.query.QueryParserMetricsHolder; +import org.apache.ignite.internal.processors.query.QueryProperties; import org.apache.ignite.internal.processors.query.QueryUtils; import org.apache.ignite.internal.processors.query.calcite.exec.ArrayRowHandler; import org.apache.ignite.internal.processors.query.calcite.exec.ExchangeService; @@ -500,8 +501,15 @@ public class CalciteQueryProcessor extends GridProcessorAdapter implements Query parserMetrics.countCacheMiss(); + QueryProperties qryProps = qryCtx != null ? qryCtx.unwrap(QueryProperties.class) : null; + SqlNodeList qryList = Commons.parse(sql, FRAMEWORK_CONFIG.getParserConfig()); + if (qryList.size() > 1 && qryProps != null && qryProps.isFailOnMultipleStmts()) { + throw new IgniteSQLException("Multiple statements queries are not supported.", + IgniteQueryErrorCode.UNSUPPORTED_OPERATION); + } + List<T> res = new ArrayList<>(qryList.size()); List<RootQuery<Object[]>> qrys = new ArrayList<>(qryList.size()); diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/thin/MultiLineQueryTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/thin/MultiLineQueryTest.java new file mode 100644 index 00000000000..5af3d58e7fc --- /dev/null +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/thin/MultiLineQueryTest.java @@ -0,0 +1,108 @@ +/* + * 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.processors.query.calcite.thin; + +import java.util.List; +import org.apache.ignite.IgniteException; +import org.apache.ignite.Ignition; +import org.apache.ignite.cache.query.SqlFieldsQuery; +import org.apache.ignite.calcite.CalciteQueryEngineConfiguration; +import org.apache.ignite.client.IgniteClient; +import org.apache.ignite.configuration.ClientConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.configuration.SqlConfiguration; +import org.apache.ignite.indexing.IndexingQueryEngineConfiguration; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import static org.apache.ignite.testframework.GridTestUtils.assertThrows; + +/** + * Tests proper exception is thrown when multiline expressions are executed on thin client on both engines. + */ +@RunWith(Parameterized.class) +public class MultiLineQueryTest extends GridCommonAbstractTest { + /** */ + private static final String H2_ENGINE = IndexingQueryEngineConfiguration.ENGINE_NAME; + + /** */ + private static final String CALCITE_ENGINE = CalciteQueryEngineConfiguration.ENGINE_NAME; + + /** */ + private IgniteClient cli; + + /** */ + @Parameterized.Parameter + public String queryEngine; + + /** */ + @Parameterized.Parameters(name = "engine={0}") + public static List<Object> parameters() { + return F.asList(H2_ENGINE, CALCITE_ENGINE); + } + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + return super.getConfiguration(igniteInstanceName).setSqlConfiguration( + new SqlConfiguration().setQueryEnginesConfiguration( + new IndexingQueryEngineConfiguration(), + new CalciteQueryEngineConfiguration() + ) + ); + } + + /** {@inheritDoc} */ + @Override protected void beforeTest() throws Exception { + super.beforeTest(); + + startGrids(1); + + cli = Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1")); + + execute("create table if not exists test(id int primary key, val varchar)"); + } + + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + if (cli != null) { + cli.close(); + + cli = null; + } + + stopAllGrids(); + + super.afterTest(); + } + + /** */ + @Test + public void testMultilineThrowsProperException() { + assertThrows(log(), () -> { + execute("insert /* QUERY_ENGINE('" + queryEngine + "') */ into test (id, val) values (1, 'hello');" + + "select /* QUERY_ENGINE('" + queryEngine + "') */ val from test where id = 1"); + }, IgniteException.class, "Multiple statements queries are not supported"); + } + + /** */ + private List<List<?>> execute(String sql) { + return cli.query(new SqlFieldsQuery(sql)).getAll(); + } +} diff --git a/modules/calcite/src/test/java/org/apache/ignite/testsuites/IntegrationTestSuite.java b/modules/calcite/src/test/java/org/apache/ignite/testsuites/IntegrationTestSuite.java index fa1ca919b98..dd23c284ac1 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/testsuites/IntegrationTestSuite.java +++ b/modules/calcite/src/test/java/org/apache/ignite/testsuites/IntegrationTestSuite.java @@ -72,6 +72,7 @@ import org.apache.ignite.internal.processors.query.calcite.jdbc.JdbcQueryTest; import org.apache.ignite.internal.processors.query.calcite.rules.JoinCommuteRulesTest; import org.apache.ignite.internal.processors.query.calcite.rules.OrToUnionRuleTest; import org.apache.ignite.internal.processors.query.calcite.rules.ProjectScanMergeRuleTest; +import org.apache.ignite.internal.processors.query.calcite.thin.MultiLineQueryTest; import org.junit.runner.RunWith; import org.junit.runners.Suite; @@ -135,6 +136,7 @@ import org.junit.runners.Suite; IndexWithSameNameCalciteTest.class, AuthorizationIntegrationTest.class, DdlTransactionCalciteSelfTest.class, + MultiLineQueryTest.class, }) public class IntegrationTestSuite { } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java index 3db44e0239c..208ee4f9c67 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java @@ -3042,7 +3042,11 @@ public class GridQueryProcessor extends GridProcessorAdapter { QueryEngine qryEngine = engineForQuery(cliCtx, qry); if (qryEngine != null) { - QueryProperties qryProps = new QueryProperties(cctx == null ? null : cctx.name(), keepBinary); + QueryProperties qryProps = new QueryProperties( + cctx == null ? null : cctx.name(), + keepBinary, + failOnMultipleStmts + ); if (qry instanceof SqlFieldsQueryEx && ((SqlFieldsQueryEx)qry).isBatched()) { res = qryEngine.queryBatched( diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryProperties.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryProperties.java index 9e2bad26704..eb081eb6917 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryProperties.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryProperties.java @@ -30,9 +30,13 @@ public final class QueryProperties { private final boolean keepBinary; /** */ - public QueryProperties(@Nullable String cacheName, boolean keepBinary) { + private final boolean failOnMultipleStmts; + + /** */ + public QueryProperties(@Nullable String cacheName, boolean keepBinary, boolean failOnMultipleStmts) { this.cacheName = cacheName; this.keepBinary = keepBinary; + this.failOnMultipleStmts = failOnMultipleStmts; } /** */ @@ -40,6 +44,11 @@ public final class QueryProperties { return keepBinary; } + /** */ + public boolean isFailOnMultipleStmts() { + return failOnMultipleStmts; + } + /** */ public @Nullable String cacheName() { return cacheName;