This is an automated email from the ASF dual-hosted git repository. ipavlukhin 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 6a87307 IGNITE-12565 Extend test coverage [IGNITE-9279] Support custom default SQL schema name - Fixes #7289. 6a87307 is described below commit 6a8730754b5f1bf064ec044e7342b85c5b50627f Author: ipavlukhin <vololo...@gmail.com> AuthorDate: Thu Jan 23 15:43:30 2020 +0300 IGNITE-12565 Extend test coverage [IGNITE-9279] Support custom default SQL schema name - Fixes #7289. Signed-off-by: ipavlukhin <vololo...@gmail.com> --- .../apache/ignite/testframework/GridTestUtils.java | 19 +- .../processors/query/AbstractCustomSchemaTest.java | 197 +++++++++++++++++++++ .../query/AbstractDefaultSchemaTest.java | 133 ++++++++++++++ .../query/IgniteSqlCustomSchemaTest.java | 51 ++++++ .../query/IgniteSqlCustomSchemaWithPdsEnabled.java | 148 ++++++++++++++++ .../query/IgniteSqlDefaultSchemaTest.java | 31 ++++ .../IgniteSqlSchemasDiffConfigurationsTest.java | 90 ++++++++++ .../processors/query/JdbcSqlCustomSchemaTest.java | 85 +++++++++ .../processors/query/JdbcSqlDefaultSchemaTest.java | 85 +++++++++ .../IgniteBinaryCacheQueryTestSuite.java | 13 ++ 10 files changed, 850 insertions(+), 2 deletions(-) diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java b/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java index 23a64f0..7a26606 100644 --- a/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java +++ b/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java @@ -2125,11 +2125,26 @@ public final class GridTestUtils { * Generate random alphabetical string. * * @param rnd Random object. - * @param maxLen Maximal length of string + * @param maxLen Maximal length of string. * @return Random string object. */ public static String randomString(Random rnd, int maxLen) { - int len = rnd.nextInt(maxLen); + return randomString(rnd, 0, maxLen); + } + + /** + * Generate random alphabetical string. + * + * @param rnd Random object. + * @param minLen Minimum length of string. + * @param maxLen Maximal length of string. + * @return Random string object. + */ + public static String randomString(Random rnd, int minLen, int maxLen) { + assert minLen >= 0 : "minLen >= 0"; + assert maxLen >= minLen : "maxLen >= minLen"; + + int len = maxLen == minLen ? minLen : minLen + rnd.nextInt(maxLen - minLen); StringBuilder b = new StringBuilder(len); diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/AbstractCustomSchemaTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/AbstractCustomSchemaTest.java new file mode 100644 index 0000000..c32dbb48 --- /dev/null +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/AbstractCustomSchemaTest.java @@ -0,0 +1,197 @@ +/* + * 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; + +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.processors.cache.index.AbstractIndexingCommonTest; +import org.apache.ignite.testframework.GridTestUtils; +import org.junit.After; +import org.junit.Assert; +import org.junit.Test; + +/** Abstract test to verify custom sql schema. */ +public abstract class AbstractCustomSchemaTest extends AbstractIndexingCommonTest { + /** */ + protected static final String TBL_NAME = "T1"; + + /** */ + protected static final String SCHEMA_NAME_1 = "SCHEMA_1"; + + /** */ + protected static final String SCHEMA_NAME_2 = "SCHEMA_2"; + + /** */ + private static final String SCHEMA_NAME_3 = "ScHeMa3"; + + /** */ + private static final String SCHEMA_NAME_4 = "SCHEMA_4"; + + /** */ + private static final String UNKNOWN_SCHEMA_NAME = "UNKNOWN_SCHEMA"; + + /** */ + private static final String CACHE_NAME = "cache_4"; + + /** */ + protected static String t(String schema, String tbl) { + return schema + "." + tbl; + } + + /** */ + private static String q(String str) { + return "\"" + str + "\""; + } + + /** */ + protected abstract List<List<?>> execSql(String qry); + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + return super.getConfiguration(igniteInstanceName) + .setSqlSchemas(SCHEMA_NAME_1, SCHEMA_NAME_2, q(SCHEMA_NAME_3)) + .setCacheConfiguration(new CacheConfiguration(CACHE_NAME).setSqlSchema(SCHEMA_NAME_4)); + } + + /** {@inheritDoc} */ + @Override protected void beforeTestsStarted() throws Exception { + startGrid(0); + } + + /** */ + @After + public void clear() { + execSql("DROP TABLE IF EXISTS " + t(SCHEMA_NAME_1, TBL_NAME)); + execSql("DROP TABLE IF EXISTS " + t(SCHEMA_NAME_2, TBL_NAME)); + execSql("DROP TABLE IF EXISTS " + t(q(SCHEMA_NAME_3), TBL_NAME)); + execSql("DROP TABLE IF EXISTS " + t(SCHEMA_NAME_4, TBL_NAME)); + } + + /** */ + @Test + public void testBasicOpsDiffSchemas() { + execSql("CREATE TABLE " + t(SCHEMA_NAME_1, TBL_NAME) + " (s1_key INT PRIMARY KEY, s1_val INT)"); + execSql("CREATE TABLE " + t(SCHEMA_NAME_2, TBL_NAME) + " (s2_key INT PRIMARY KEY, s2_val INT)"); + execSql("CREATE TABLE " + t(q(SCHEMA_NAME_3), TBL_NAME) + " (s3_key INT PRIMARY KEY, s3_val INT)"); + execSql("CREATE TABLE " + t(SCHEMA_NAME_4, TBL_NAME) + " (s4_key INT PRIMARY KEY, s4_val INT)"); + + execSql("INSERT INTO " + t(SCHEMA_NAME_1, TBL_NAME) + " (s1_key, s1_val) VALUES (1, 2)"); + execSql("INSERT INTO " + t(SCHEMA_NAME_2, TBL_NAME) + " (s2_key, s2_val) VALUES (1, 2)"); + execSql("INSERT INTO " + t(q(SCHEMA_NAME_3), TBL_NAME) + " (s3_key, s3_val) VALUES (1, 2)"); + execSql("INSERT INTO " + t(SCHEMA_NAME_4, TBL_NAME) + " (s4_key, s4_val) VALUES (1, 2)"); + + execSql("UPDATE " + t(SCHEMA_NAME_1, TBL_NAME) + " SET s1_val = 5"); + execSql("UPDATE " + t(SCHEMA_NAME_2, TBL_NAME) + " SET s2_val = 5"); + execSql("UPDATE " + t(q(SCHEMA_NAME_3), TBL_NAME) + " SET s3_val = 5"); + execSql("UPDATE " + t(SCHEMA_NAME_4, TBL_NAME) + " SET s4_val = 5"); + + execSql("DELETE FROM " + t(SCHEMA_NAME_1, TBL_NAME)); + execSql("DELETE FROM " + t(SCHEMA_NAME_2, TBL_NAME)); + execSql("DELETE FROM " + t(q(SCHEMA_NAME_3), TBL_NAME)); + execSql("DELETE FROM " + t(SCHEMA_NAME_4, TBL_NAME)); + + execSql("CREATE INDEX t1_idx_1 ON " + t(SCHEMA_NAME_1, TBL_NAME) + "(s1_val)"); + execSql("CREATE INDEX t1_idx_1 ON " + t(SCHEMA_NAME_2, TBL_NAME) + "(s2_val)"); + execSql("CREATE INDEX t1_idx_1 ON " + t(q(SCHEMA_NAME_3), TBL_NAME) + "(s3_val)"); + execSql("CREATE INDEX t1_idx_1 ON " + t(SCHEMA_NAME_4, TBL_NAME) + "(s4_val)"); + + execSql("SELECT * FROM " + t(SCHEMA_NAME_1, TBL_NAME)); + execSql("SELECT * FROM " + t(SCHEMA_NAME_2, TBL_NAME)); + execSql("SELECT * FROM " + t(q(SCHEMA_NAME_3), TBL_NAME)); + execSql("SELECT * FROM " + t(SCHEMA_NAME_4, TBL_NAME)); + + execSql("SELECT * FROM " + t(SCHEMA_NAME_1, TBL_NAME) + + " JOIN " + t(SCHEMA_NAME_2, TBL_NAME) + + " JOIN " + t(q(SCHEMA_NAME_3), TBL_NAME) + + " JOIN " + t(SCHEMA_NAME_4, TBL_NAME)); + + verifyTbls(); + + execSql("DROP TABLE " + t(SCHEMA_NAME_1, TBL_NAME)); + execSql("DROP TABLE " + t(SCHEMA_NAME_2, TBL_NAME)); + execSql("DROP TABLE " + t(q(SCHEMA_NAME_3), TBL_NAME)); + execSql("DROP TABLE " + t(SCHEMA_NAME_4, TBL_NAME)); + } + + /** */ + @Test + public void testRecreateTableWithinSchema() { + grid(0).cache(CACHE_NAME).destroy(); + + grid(0).createCache(new CacheConfiguration<>(CACHE_NAME + "_new").setSqlSchema(SCHEMA_NAME_4)); + + List<List<?>> res = execSql("SELECT SQL_SCHEMA FROM " + t(QueryUtils.SCHEMA_SYS, "CACHES") + + " WHERE CACHE_NAME = '" + CACHE_NAME + "_new'"); + + Assert.assertEquals( + Collections.singletonList(Collections.singletonList(SCHEMA_NAME_4)), + res + ); + } + + /** */ + @Test + @SuppressWarnings("ThrowableNotThrown") + public void testCreateTblsInDiffSchemasForSameCache() { + final String testCache = "cache1"; + + execSql("CREATE TABLE " + t(SCHEMA_NAME_1, TBL_NAME) + + " (s1_key INT PRIMARY KEY, s1_val INT) WITH \"cache_name=" + testCache + "\""); + + GridTestUtils.assertThrowsWithCause( + () -> execSql("CREATE TABLE " + t(SCHEMA_NAME_2, TBL_NAME) + + " (s1_key INT PRIMARY KEY, s2_val INT) WITH \"cache_name=" + testCache + "\""), + SQLException.class + ); + + execSql("DROP TABLE " + t(SCHEMA_NAME_1, TBL_NAME)); + } + + /** */ + @Test + @SuppressWarnings("ThrowableNotThrown") + public void testCreateDropNonExistingSchema() { + GridTestUtils.assertThrowsWithCause( + () -> execSql("CREATE TABLE " + t(UNKNOWN_SCHEMA_NAME, TBL_NAME) + "(id INT PRIMARY KEY, val INT)"), + SQLException.class + ); + + GridTestUtils.assertThrowsWithCause( + () -> execSql("DROP TABLE " + t(UNKNOWN_SCHEMA_NAME, TBL_NAME)), + SQLException.class + ); + } + + /** */ + private void verifyTbls() { + List<List<?>> res = execSql("SELECT SCHEMA_NAME, KEY_ALIAS FROM " + t(QueryUtils.SCHEMA_SYS, "TABLES") + " ORDER BY SCHEMA_NAME"); + + List<List<?>> exp = Arrays.asList( + Arrays.asList(SCHEMA_NAME_1, "S1_KEY"), + Arrays.asList(SCHEMA_NAME_2, "S2_KEY"), + Arrays.asList(SCHEMA_NAME_4, "S4_KEY"), + Arrays.asList(SCHEMA_NAME_3, "S3_KEY") + ); + + Assert.assertEquals(exp, res); + } +} diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/AbstractDefaultSchemaTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/AbstractDefaultSchemaTest.java new file mode 100644 index 0000000..20a4854 --- /dev/null +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/AbstractDefaultSchemaTest.java @@ -0,0 +1,133 @@ +/* + * 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; + +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Predicate; +import java.util.function.Supplier; +import org.apache.ignite.internal.processors.cache.index.AbstractIndexingCommonTest; +import org.apache.ignite.testframework.GridTestUtils; +import org.jetbrains.annotations.Nullable; +import org.junit.Assert; +import org.junit.Test; + +/** Abstract test to verify default sql schema. */ +public abstract class AbstractDefaultSchemaTest extends AbstractIndexingCommonTest { + /** Table name. */ + private static final String TBL_NAME = "T1"; + + /** + * @param qry Query. + */ + protected abstract List<List<?>> execSql(String qry); + + /** + * @param withSchema Whether to specify schema or not. + */ + public String tableName(boolean withSchema) { + String prefix = ""; + + if (withSchema) + prefix += "PUBLIC."; + + return prefix + TBL_NAME; + } + + /** {@inheritDoc} */ + @Override protected void beforeTestsStarted() throws Exception { + startGrid(0); + } + + /** */ + @Test + public void testBasicOpsExplicitPublicSchema() { + executeStmtsAndVerify(() -> true); + } + + /** */ + @Test + public void testBasicOpsImplicitPublicSchema() { + executeStmtsAndVerify(() -> false); + } + + /** */ + @Test + public void testBasicOpsMixedPublicSchema() { + AtomicInteger i = new AtomicInteger(); + + executeStmtsAndVerify(() -> (i.incrementAndGet() & 1) == 0); + } + + /** */ + @Test + @SuppressWarnings("ThrowableNotThrown") + public void testCreateDropNonExistingSchema() { + GridTestUtils.assertThrowsWithCause( + () -> sql("CREATE TABLE UNKNOWN_SCHEMA." + TBL_NAME + "(id INT PRIMARY KEY, val INT)"), + SQLException.class + ); + + GridTestUtils.assertThrowsWithCause( + () -> sql("DROP TABLE UNKNOWN_SCHEMA." + TBL_NAME), + SQLException.class + ); + } + + /** */ + private void executeStmtsAndVerify(Supplier<Boolean> withSchemaDecisionSup) { + sql("CREATE TABLE " + tableName(withSchemaDecisionSup.get()) + " (id INT PRIMARY KEY, val INT)"); + + sql("CREATE INDEX t1_idx_1 ON " + tableName(withSchemaDecisionSup.get()) + "(val)"); + + sql("INSERT INTO " + tableName(withSchemaDecisionSup.get()) + " (id, val) VALUES(1, 2)"); + sql("SELECT * FROM " + tableName(withSchemaDecisionSup.get()), res -> oneRowList(1, 2).equals(res)); + + sql("UPDATE " + tableName(withSchemaDecisionSup.get()) + " SET val = 5"); + sql("SELECT * FROM " + tableName(withSchemaDecisionSup.get()), res -> oneRowList(1, 5).equals(res)); + + sql("DELETE FROM " + tableName(withSchemaDecisionSup.get()) + " WHERE id = 1"); + sql("SELECT COUNT(*) FROM " + tableName(withSchemaDecisionSup.get()), res -> oneRowList(0L).equals(res)); + + sql("SELECT COUNT(*) FROM " + QueryUtils.SCHEMA_SYS + ".TABLES WHERE schema_name = 'PUBLIC' " + + "AND table_name = \'" + TBL_NAME + "\'", res -> oneRowList(1L).equals(res)); + + sql("DROP TABLE " + tableName(withSchemaDecisionSup.get())); + } + + /** */ + private List<List<?>> oneRowList(Object... args) { + return Collections.singletonList(Arrays.asList(args)); + } + + /** */ + protected void sql(String qry) { + sql(qry, null); + } + + /** */ + protected void sql(String qry, @Nullable Predicate<List<List<?>>> validator) { + List<List<?>> res = execSql(qry); + + if (validator != null) + Assert.assertTrue(validator.test(res)); + } +} diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlCustomSchemaTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlCustomSchemaTest.java new file mode 100644 index 0000000..2e4ae1b --- /dev/null +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlCustomSchemaTest.java @@ -0,0 +1,51 @@ +/* + * 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; + +import java.util.List; +import org.apache.ignite.cache.query.SqlFieldsQuery; +import org.apache.ignite.testframework.GridTestUtils; +import org.junit.Test; + +/** Verifies custom sql schema through SqlFieldsQuery API. */ +public class IgniteSqlCustomSchemaTest extends AbstractCustomSchemaTest { + /** {@inheritDoc} */ + @Override protected List<List<?>> execSql(String qry) { + return grid(0).context().query() + .querySqlFields(new SqlFieldsQuery(qry).setLazy(true), false) + .getAll(); + } + + /** {@inheritDoc} */ + @Test + @SuppressWarnings("ThrowableNotThrown") + @Override public void testCreateTblsInDiffSchemasForSameCache() { + final String testCache = "cache1"; + + execSql("CREATE TABLE " + t(SCHEMA_NAME_1, TBL_NAME) + + " (s1_key INT PRIMARY KEY, s1_val INT) WITH \"cache_name=" + testCache + "\""); + + GridTestUtils.assertThrowsWithCause( + () -> execSql("CREATE TABLE " + t(SCHEMA_NAME_2, TBL_NAME) + + " (s1_key INT PRIMARY KEY, s2_val INT) WITH \"cache_name=" + testCache + "\""), + IgniteSQLException.class + ); + + execSql("DROP TABLE " + t(SCHEMA_NAME_1, TBL_NAME)); + } +} diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlCustomSchemaWithPdsEnabled.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlCustomSchemaWithPdsEnabled.java new file mode 100644 index 0000000..d04bdd2 --- /dev/null +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlCustomSchemaWithPdsEnabled.java @@ -0,0 +1,148 @@ +/* + * 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; + +import java.util.List; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.cache.query.SqlFieldsQuery; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.DataRegionConfiguration; +import org.apache.ignite.configuration.DataStorageConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.processors.cache.index.AbstractIndexingCommonTest; +import org.junit.After; +import org.junit.Assert; +import org.junit.Test; + +/** Test verifies custom sql schema behavior when PDS is enabled. */ +public class IgniteSqlCustomSchemaWithPdsEnabled extends AbstractIndexingCommonTest { + /** */ + private static final String CACHE_NAME = "cache_4"; + + /** */ + private static final String SCHEMA_NAME_1 = "SCHEMA_1"; + + /** */ + private static final String SCHEMA_NAME_2 = "SCHEMA_2"; + + /** */ + private static final String SCHEMA_NAME_3 = "ScHeMa3"; + + /** */ + private static final String SCHEMA_NAME_4 = "SCHEMA_4"; + + /** */ + private static final String TABLE_NAME = "T1"; + + /** */ + private static final String[] ALL_SCHEMAS = + new String[]{SCHEMA_NAME_1, SCHEMA_NAME_2, SCHEMA_NAME_3, SCHEMA_NAME_4}; + + /** */ + private static String t(String schema, String tbl) { + return schema + "." + tbl; + } + + /** */ + private static String q(String str) { + return "\"" + str + "\""; + } + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + return super.getConfiguration(igniteInstanceName) + .setSqlSchemas(SCHEMA_NAME_1, SCHEMA_NAME_2, q(SCHEMA_NAME_3)) + .setDataStorageConfiguration( + new DataStorageConfiguration().setDefaultDataRegionConfiguration( + new DataRegionConfiguration().setPersistenceEnabled(true))); + } + + /** */ + @After + public void tearDown() throws Exception { + stopAllGrids(); + + cleanPersistenceDir(); + } + + /** */ + @Test + public void testSimpleRestart() throws Exception { + startAndActivate().createCache(new CacheConfiguration<>(CACHE_NAME).setSqlSchema(SCHEMA_NAME_4)); + + for (String schemaName : ALL_SCHEMAS) { + execSql("CREATE TABLE " + t(q(schemaName), TABLE_NAME) + "(id INT PRIMARY KEY, val VARCHAR)"); + + for (int i = 0; i < 10; i++) + execSql("INSERT INTO " + t(q(schemaName), TABLE_NAME) + "(id, val) VALUES (" + i + ", '" + schemaName + "')"); + } + + stopGrid(0); + + startGrid(0).cluster().active(true); + + for (String schemaName : ALL_SCHEMAS) { + List<List<?>> act = execSql("SELECT COUNT(*) FROM " + t(q(schemaName), TABLE_NAME) + + " WHERE val = '" + schemaName + "'"); + + Assert.assertEquals(10L, act.get(0).get(0)); + } + } + + /** */ + @Test + public void testRecreateAfterRestart() throws Exception { + IgniteCache<?, ?> cache = startAndActivate().createCache( + new CacheConfiguration<>(CACHE_NAME).setSqlSchema(SCHEMA_NAME_4)); + + verifyCacheInSchema(CACHE_NAME, SCHEMA_NAME_4); + + cache.destroy(); + + stopGrid(0); + + startAndActivate().createCache(new CacheConfiguration<>(CACHE_NAME).setSqlSchema(SCHEMA_NAME_4)); + + verifyCacheInSchema(CACHE_NAME, SCHEMA_NAME_4); + } + + /** */ + private void verifyCacheInSchema(String cacheName, String expSchema) { + Object actSchema = execSql("SELECT SQL_SCHEMA FROM " + t(QueryUtils.SCHEMA_SYS, "CACHES") + + " WHERE CACHE_NAME = '" + cacheName + "'").get(0).get(0); + + Assert.assertEquals(expSchema, actSchema); + } + + /** */ + private IgniteEx startAndActivate() throws Exception { + IgniteEx ignite = startGrid(0); + + ignite.cluster().active(true); + + return ignite; + } + + /** */ + private List<List<?>> execSql(String qry) { + return grid(0).context().query() + .querySqlFields(new SqlFieldsQuery(qry).setLazy(true), false) + .getAll(); + } +} diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlDefaultSchemaTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlDefaultSchemaTest.java new file mode 100644 index 0000000..7334e4b --- /dev/null +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlDefaultSchemaTest.java @@ -0,0 +1,31 @@ +/* + * 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; + +import java.util.List; +import org.apache.ignite.cache.query.SqlFieldsQuery; + +/** Verifies default sql schema through SqlFieldsQuery API. */ +public class IgniteSqlDefaultSchemaTest extends AbstractDefaultSchemaTest { + /** {@inheritDoc} */ + @Override protected List<List<?>> execSql(String qry) { + return grid(0).context().query() + .querySqlFields(new SqlFieldsQuery(qry).setLazy(true), false) + .getAll(); + } +} diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlSchemasDiffConfigurationsTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlSchemasDiffConfigurationsTest.java new file mode 100644 index 0000000..1fce5a9 --- /dev/null +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlSchemasDiffConfigurationsTest.java @@ -0,0 +1,90 @@ +/* + * 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; + +import java.util.Arrays; +import java.util.List; +import org.apache.ignite.cache.query.SqlFieldsQuery; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.processors.cache.index.AbstractIndexingCommonTest; +import org.junit.After; +import org.junit.Assert; +import org.junit.Test; + +/** Verifies custom sql schema within different configurations. */ +public class IgniteSqlSchemasDiffConfigurationsTest extends AbstractIndexingCommonTest { + /** */ + private static final String SCHEMA_NAME_1 = "SCHEMA_1"; + + /** */ + private static final String SCHEMA_NAME_2 = "SCHEMA_2"; + + /** */ + private static final String SCHEMA_NAME_3 = "SCHEMA_3"; + + /** */ + private static final String SCHEMA_NAME_4 = "SCHEMA_4"; + + /** */ + private static String t(String schema, String tbl) { + return schema + "." + tbl; + } + + /** */ + @After + public void tearDown() { + stopAllGrids(); + } + + /** */ + @Test + public void testDiffSqlSchemasCfgProp() throws Exception { + startGrid(getConfiguration("ign1").setSqlSchemas(SCHEMA_NAME_1, SCHEMA_NAME_2)); + + startGrid(getConfiguration("ign2").setSqlSchemas(SCHEMA_NAME_3, SCHEMA_NAME_4)); + + List<List<String>> exp = Arrays.asList( + Arrays.asList(SCHEMA_NAME_1, "cache_1"), + Arrays.asList(SCHEMA_NAME_2, "cache_2"), + Arrays.asList(SCHEMA_NAME_3, "cache_3"), + Arrays.asList(SCHEMA_NAME_4, "cache_4") + ); + + for (List<String> row : exp) + grid("ign1").createCache(new CacheConfiguration<>(row.get(1)).setSqlSchema(row.get(0))); + + List<List<?>> res = execSql("ign1", "SELECT SQL_SCHEMA, CACHE_NAME FROM " + + t(QueryUtils.SCHEMA_SYS, "CACHES") + " WHERE CACHE_NAME LIKE 'cache%' ORDER BY SQL_SCHEMA"); + + Assert.assertEquals(exp, res); + } + + /** */ + private IgniteConfiguration createTestConf(String nodeName, String schemaName, String cacheName) throws Exception { + return getConfiguration(nodeName) + .setCacheConfiguration(new CacheConfiguration(cacheName).setSqlSchema(schemaName)); + } + + /** */ + protected List<List<?>> execSql(String ignName, String qry) { + return grid(ignName).context().query() + .querySqlFields(new SqlFieldsQuery(qry).setLazy(true), false) + .getAll(); + } +} diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/JdbcSqlCustomSchemaTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/JdbcSqlCustomSchemaTest.java new file mode 100644 index 0000000..c48a0ac --- /dev/null +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/JdbcSqlCustomSchemaTest.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.ignite.internal.processors.query; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.regex.Pattern; + +/** Verifies custom sql schema through JDBC API. */ +public class JdbcSqlCustomSchemaTest extends AbstractCustomSchemaTest { + /** SELECT query pattern. */ + private static final Pattern SELECT_QRY_PATTERN = Pattern.compile("^SELECT .*"); + + /** Connection. */ + private Connection conn; + + /** {@inheritDoc} */ + @Override protected void afterTestsStopped() throws Exception { + if (conn != null && !conn.isClosed()) + conn.close(); + + super.afterTestsStopped(); + } + + /** */ + private Connection getOrCreateConnection() throws SQLException { + if (conn == null) + conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1"); + + return conn; + } + + /** {@inheritDoc} */ + @Override protected List<List<?>> execSql(String qry) { + try (Statement stmt = getOrCreateConnection().createStatement()) { + if (SELECT_QRY_PATTERN.matcher(qry).matches()) + return resultSetToList(stmt.executeQuery(qry)); + else { + stmt.execute(qry); + + return Collections.emptyList(); + } + } + catch (SQLException e) { + throw new RuntimeException(e); + } + } + + /** Converts {@link ResultSet} to list of lists. */ + private List<List<?>> resultSetToList(ResultSet rs) throws SQLException { + List<List<?>> res = new ArrayList<>(); + + while (rs.next()) { + List<Object> row = new ArrayList<>(); + + res.add(row); + + for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) + row.add(rs.getObject(i)); + } + + return res; + } +} diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/JdbcSqlDefaultSchemaTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/JdbcSqlDefaultSchemaTest.java new file mode 100644 index 0000000..fb2d358 --- /dev/null +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/JdbcSqlDefaultSchemaTest.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.ignite.internal.processors.query; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.regex.Pattern; + +/** Verifies default sql schema through JDBC API. */ +public class JdbcSqlDefaultSchemaTest extends AbstractDefaultSchemaTest { + /** SELECT query pattern. */ + private static final Pattern SELECT_QRY_PATTERN = Pattern.compile("^SELECT .*"); + + /** Connection. */ + private Connection conn; + + /** {@inheritDoc} */ + @Override protected void afterTestsStopped() throws Exception { + if (conn != null && !conn.isClosed()) + conn.close(); + + super.afterTestsStopped(); + } + + /** */ + private Connection getOrCreateConnection() throws SQLException { + if (conn == null) + conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1"); + + return conn; + } + + /** {@inheritDoc} */ + @Override protected List<List<?>> execSql(String qry) { + try (Statement stmt = getOrCreateConnection().createStatement()) { + if (SELECT_QRY_PATTERN.matcher(qry).matches()) + return resultSetToList(stmt.executeQuery(qry)); + else { + stmt.execute(qry); + + return Collections.emptyList(); + } + } + catch (SQLException e) { + throw new RuntimeException(e); + } + } + + /** Converts {@link ResultSet} to list of lists. */ + private List<List<?>> resultSetToList(ResultSet rs) throws SQLException { + List<List<?>> res = new ArrayList<>(); + + while (rs.next()) { + List<Object> row = new ArrayList<>(); + + res.add(row); + + for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) + row.add(rs.getObject(i)); + } + + return res; + } +} diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite.java index 53166e1..4234735 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite.java +++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite.java @@ -185,6 +185,9 @@ import org.apache.ignite.internal.processors.query.IgniteCachelessQueriesSelfTes import org.apache.ignite.internal.processors.query.IgniteQueryDedicatedPoolTest; import org.apache.ignite.internal.processors.query.IgniteQueryTableLockAndConnectionPoolLazyModeOffTest; import org.apache.ignite.internal.processors.query.IgniteQueryTableLockAndConnectionPoolLazyModeOnTest; +import org.apache.ignite.internal.processors.query.IgniteSqlCustomSchemaTest; +import org.apache.ignite.internal.processors.query.IgniteSqlCustomSchemaWithPdsEnabled; +import org.apache.ignite.internal.processors.query.IgniteSqlDefaultSchemaTest; import org.apache.ignite.internal.processors.query.IgniteSqlDefaultValueTest; import org.apache.ignite.internal.processors.query.IgniteSqlDistributedJoinSelfTest; import org.apache.ignite.internal.processors.query.IgniteSqlEntryCacheModeAgnosticTest; @@ -196,11 +199,14 @@ import org.apache.ignite.internal.processors.query.IgniteSqlParameterizedQueryTe import org.apache.ignite.internal.processors.query.IgniteSqlQueryParallelismTest; import org.apache.ignite.internal.processors.query.IgniteSqlRoutingTest; import org.apache.ignite.internal.processors.query.IgniteSqlSchemaIndexingTest; +import org.apache.ignite.internal.processors.query.IgniteSqlSchemasDiffConfigurationsTest; import org.apache.ignite.internal.processors.query.IgniteSqlSegmentedIndexMultiNodeSelfTest; import org.apache.ignite.internal.processors.query.IgniteSqlSegmentedIndexSelfTest; import org.apache.ignite.internal.processors.query.IgniteSqlSkipReducerOnUpdateDmlFlagSelfTest; import org.apache.ignite.internal.processors.query.IgniteSqlSkipReducerOnUpdateDmlSelfTest; import org.apache.ignite.internal.processors.query.IgniteSqlSplitterSelfTest; +import org.apache.ignite.internal.processors.query.JdbcSqlCustomSchemaTest; +import org.apache.ignite.internal.processors.query.JdbcSqlDefaultSchemaTest; import org.apache.ignite.internal.processors.query.KillQueryFromClientTest; import org.apache.ignite.internal.processors.query.KillQueryFromNeighbourTest; import org.apache.ignite.internal.processors.query.KillQueryOnClientDisconnectTest; @@ -520,6 +526,13 @@ import org.junit.runners.Suite; IgniteSQLColumnConstraintsTest.class, IgniteTransactionSQLColumnConstraintTest.class, + IgniteSqlDefaultSchemaTest.class, + IgniteSqlCustomSchemaTest.class, + JdbcSqlDefaultSchemaTest.class, + JdbcSqlCustomSchemaTest.class, + IgniteSqlCustomSchemaWithPdsEnabled.class, + IgniteSqlSchemasDiffConfigurationsTest.class, + IgniteCachePartitionedAtomicColumnConstraintsTest.class, IgniteCachePartitionedTransactionalColumnConstraintsTest.class, IgniteCachePartitionedTransactionalSnapshotColumnConstraintTest.class,