You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by is...@apache.org on 2022/02/08 08:41:28 UTC
[ignite] branch master updated: IGNITE-16492 Add schema-related tests
This is an automated email from the ASF dual-hosted git repository.
isapego 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 f1d90ac IGNITE-16492 Add schema-related tests
f1d90ac is described below
commit f1d90ac30f02e99e26ebaeb38a77150f5af81a22
Author: Igor Sapego <is...@apache.org>
AuthorDate: Tue Feb 8 11:40:43 2022 +0300
IGNITE-16492 Add schema-related tests
This closes #9806
---
modules/platforms/cpp/core-test/CMakeLists.txt | 1 +
.../cpp/core-test/config/cache-query-schema-32.xml | 52 ++++
.../config/cache-query-schema-default.xml | 60 ++++
.../cpp/core-test/config/cache-query-schema.xml | 34 +++
.../cpp/core-test/src/cache_query_schema_test.cpp | 312 +++++++++++++++++++
modules/platforms/cpp/odbc-test/CMakeLists.txt | 3 +-
.../cpp/odbc-test/config/queries-schema-32.xml | 52 ++++
.../odbc-test/config/queries-schema-default.xml | 68 +++++
.../cpp/odbc-test/config/queries-schema.xml | 34 +++
.../cpp/odbc-test/src/sql_schema_test.cpp | 337 +++++++++++++++++++++
.../Cache/Query/CacheDmlQueriesTestSchema.cs | 255 ++++++++++++++++
11 files changed, 1207 insertions(+), 1 deletion(-)
diff --git a/modules/platforms/cpp/core-test/CMakeLists.txt b/modules/platforms/cpp/core-test/CMakeLists.txt
index 04791b1..188716e 100644
--- a/modules/platforms/cpp/core-test/CMakeLists.txt
+++ b/modules/platforms/cpp/core-test/CMakeLists.txt
@@ -62,6 +62,7 @@ set(SOURCES
src/test_utils.cpp
src/cluster_node_test.cpp
src/affinity_test.cpp
+ src/cache_query_schema_test.cpp
src/cluster_group_test.cpp)
add_executable(${TARGET} ${SOURCES})
diff --git a/modules/platforms/cpp/core-test/config/cache-query-schema-32.xml b/modules/platforms/cpp/core-test/config/cache-query-schema-32.xml
new file mode 100644
index 0000000..5c639121
--- /dev/null
+++ b/modules/platforms/cpp/core-test/config/cache-query-schema-32.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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.
+-->
+
+<!--
+ Ignite Spring configuration file to startup grid cache.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/util
+ http://www.springframework.org/schema/util/spring-util.xsd">
+ <import resource="cache-query-schema-default.xml"/>
+
+ <bean parent="grid.cfg">
+ <property name="memoryConfiguration">
+ <bean class="org.apache.ignite.configuration.MemoryConfiguration">
+ <property name="systemCacheInitialSize" value="#{10 * 1024 * 1024}"/>
+ <property name="systemCacheMaxSize" value="#{40 * 1024 * 1024}"/>
+ <property name="defaultMemoryPolicyName" value="dfltPlc"/>
+
+ <property name="memoryPolicies">
+ <list>
+ <bean class="org.apache.ignite.configuration.MemoryPolicyConfiguration">
+ <property name="name" value="dfltPlc"/>
+ <property name="maxSize" value="#{100 * 1024 * 1024}"/>
+ <property name="initialSize" value="#{10 * 1024 * 1024}"/>
+ </bean>
+ </list>
+ </property>
+ </bean>
+ </property>
+ </bean>
+</beans>
diff --git a/modules/platforms/cpp/core-test/config/cache-query-schema-default.xml b/modules/platforms/cpp/core-test/config/cache-query-schema-default.xml
new file mode 100644
index 0000000..84c12e1
--- /dev/null
+++ b/modules/platforms/cpp/core-test/config/cache-query-schema-default.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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.
+-->
+
+<!--
+ Ignite Spring configuration file to startup grid cache.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/util
+ http://www.springframework.org/schema/util/spring-util.xsd">
+ <bean abstract="true" id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
+ <property name="localHost" value="127.0.0.1"/>
+ <property name="connectorConfiguration"><null/></property>
+
+ <property name="sqlSchemas">
+ <list>
+ <value>SCHEMA_1</value>
+ <value>SCHEMA_2</value>
+ <value>"ScHeMa3"</value>
+ <value>SCHEMA_4</value>
+ </list>
+ </property>
+
+ <property name="discoverySpi">
+ <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
+ <property name="ipFinder">
+ <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+ <property name="addresses">
+ <list>
+ <!-- In distributed environment, replace with actual host IP address. -->
+ <value>127.0.0.1:47500</value>
+ </list>
+ </property>
+ </bean>
+ </property>
+ <property name="socketTimeout" value="300" />
+ </bean>
+ </property>
+ </bean>
+</beans>
diff --git a/modules/platforms/cpp/core-test/config/cache-query-schema.xml b/modules/platforms/cpp/core-test/config/cache-query-schema.xml
new file mode 100644
index 0000000..5e13ac4
--- /dev/null
+++ b/modules/platforms/cpp/core-test/config/cache-query-schema.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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.
+-->
+
+<!--
+ Ignite Spring configuration file to startup grid cache.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/util
+ http://www.springframework.org/schema/util/spring-util.xsd">
+ <import resource="cache-query-schema-default.xml"/>
+
+ <bean parent="grid.cfg"/>
+</beans>
diff --git a/modules/platforms/cpp/core-test/src/cache_query_schema_test.cpp b/modules/platforms/cpp/core-test/src/cache_query_schema_test.cpp
new file mode 100644
index 0000000..b796464
--- /dev/null
+++ b/modules/platforms/cpp/core-test/src/cache_query_schema_test.cpp
@@ -0,0 +1,312 @@
+/*
+ * 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.
+ */
+
+#include <stdint.h>
+
+#include <iterator>
+
+#include <boost/test/unit_test.hpp>
+
+#include <ignite/common/utils.h>
+
+#include "ignite/cache/cache.h"
+#include "ignite/cache/query/query_cursor.h"
+#include "ignite/cache/query/query_sql_fields.h"
+#include "ignite/ignite.h"
+#include "ignite/ignition.h"
+#include "ignite/test_utils.h"
+
+using namespace boost::unit_test;
+
+using namespace ignite;
+using namespace ignite::cache;
+using namespace ignite::cache::query;
+using namespace ignite::common;
+
+using ignite::impl::binary::BinaryUtils;
+
+/**
+ * Ensure that cursor is empy fails.
+ *
+ * @param cur Cursor.
+ */
+template<typename Cursor>
+void ChechEmptyCursorGetNextThrowsException(Cursor& cur)
+{
+ BOOST_REQUIRE(!cur.HasNext());
+ BOOST_CHECK_EXCEPTION(cur.GetNext(), IgniteError, ignite_test::IsGenericError);
+}
+
+/**
+ * Check single row through iteration.
+ *
+ * @param cur Cursor.
+ * @param c1 First column.
+ */
+template<typename T1>
+void CheckSingleRow(QueryFieldsCursor& cur, const T1& c1)
+{
+ BOOST_REQUIRE(cur.HasNext());
+
+ QueryFieldsRow row = cur.GetNext();
+
+ BOOST_REQUIRE_EQUAL(row.GetNext<T1>(), c1);
+
+ BOOST_REQUIRE(!row.HasNext());
+
+ ChechEmptyCursorGetNextThrowsException(cur);
+}
+
+/**
+ * Check row through iteration.
+ *
+ * @param cur Cursor.
+ * @param c1 First column.
+ */
+template<typename T1, typename T2>
+void CheckRow(QueryFieldsCursor& cur, const T1& c1, const T2& c2)
+{
+ BOOST_REQUIRE(cur.HasNext());
+
+ QueryFieldsRow row = cur.GetNext();
+
+ BOOST_REQUIRE_EQUAL(row.GetNext<T1>(), c1);
+ BOOST_REQUIRE_EQUAL(row.GetNext<T2>(), c2);
+
+ BOOST_REQUIRE(!row.HasNext());
+}
+
+/**
+ * Check single row through iteration.
+ *
+ * @param cur Cursor.
+ * @param c1 First column.
+ */
+template<typename T1, typename T2>
+void CheckSingleRow(QueryFieldsCursor& cur, const T1& c1, const T2& c2)
+{
+ CheckRow<T1, T2>(cur, c1, c2);
+
+ ChechEmptyCursorGetNextThrowsException(cur);
+}
+
+static const std::string TABLE_NAME = "T1";
+static const std::string SCHEMA_NAME_1 = "SCHEMA_1";
+static const std::string SCHEMA_NAME_2 = "SCHEMA_2";
+static const std::string SCHEMA_NAME_3 = "ScHeMa3";
+static const std::string Q_SCHEMA_NAME_3 = '"' + SCHEMA_NAME_3 + '"';
+static const std::string SCHEMA_NAME_4 = "SCHEMA_4";
+
+/**
+ * Test setup fixture.
+ */
+struct CacheQuerySchemaTestSuiteFixture
+{
+ Ignite StartNode(const char* name)
+ {
+#ifdef IGNITE_TESTS_32
+ return ignite_test::StartNode("cache-query-schema-32.xml", name);
+#else
+ return ignite_test::StartNode("cache-query-schema.xml", name);
+#endif
+ }
+
+ /**
+ * Constructor.
+ */
+ CacheQuerySchemaTestSuiteFixture() :
+ grid(StartNode("Node1"))
+ {
+ // No-op.
+ }
+
+ /**
+ * Destructor.
+ */
+ ~CacheQuerySchemaTestSuiteFixture()
+ {
+ Ignition::StopAll(true);
+ }
+
+ /** Perform SQL in cluster. */
+ QueryFieldsCursor Sql(const std::string& sql)
+ {
+ return grid
+ .GetOrCreateCache<int, int>("SchemaTestCache")
+ .Query(SqlFieldsQuery(sql));
+ }
+
+ std::string TableName(bool withSchema)
+ {
+ return withSchema ? "PUBLIC." + TABLE_NAME : TABLE_NAME;
+ }
+
+ template<typename Predicate>
+ void ExecuteStatementsAndVerify(Predicate& pred)
+ {
+ Sql("CREATE TABLE " + TableName(pred()) + " (id INT PRIMARY KEY, val INT)");
+
+ Sql("CREATE INDEX t1_idx_1 ON " + TableName(pred()) + "(val)");
+
+ Sql("INSERT INTO " + TableName(pred()) + " (id, val) VALUES(1, 2)");
+
+ QueryFieldsCursor cursor = Sql("SELECT * FROM " + TableName(pred()));
+ CheckSingleRow<int32_t, int32_t>(cursor, 1, 2);
+
+ Sql("UPDATE " + TableName(pred()) + " SET val = 5");
+ cursor = Sql("SELECT * FROM " + TableName(pred()));
+ CheckSingleRow<int32_t, int32_t>(cursor, 1, 5);
+
+ Sql("DELETE FROM " + TableName(pred()) + " WHERE id = 1");
+ cursor = Sql("SELECT COUNT(*) FROM " + TableName(pred()));
+ CheckSingleRow<int64_t>(cursor, 0);
+
+ cursor = Sql("SELECT COUNT(*) FROM SYS.TABLES WHERE schema_name = 'PUBLIC' "
+ "AND table_name = \'" + TABLE_NAME + "\'");
+ CheckSingleRow<int64_t>(cursor, 1);
+
+ Sql("DROP TABLE " + TableName(pred()));
+ }
+
+ /** Node started during the test. */
+ Ignite grid;
+};
+
+BOOST_FIXTURE_TEST_SUITE(CacheQuerySchemaTestSuite, CacheQuerySchemaTestSuiteFixture)
+
+bool TruePred()
+{
+ return true;
+}
+
+BOOST_AUTO_TEST_CASE(TestBasicOpsExplicitPublicSchema)
+{
+ ExecuteStatementsAndVerify(TruePred);
+}
+
+bool FalsePred()
+{
+ return false;
+}
+
+BOOST_AUTO_TEST_CASE(TestBasicOpsImplicitPublicSchema)
+{
+ ExecuteStatementsAndVerify(FalsePred);
+}
+
+struct MixedPred
+{
+ int i;
+
+ MixedPred() : i(0)
+ {
+ // No-op.
+ }
+
+ bool operator()()
+ {
+ return (++i & 1) == 0;
+ }
+};
+
+BOOST_AUTO_TEST_CASE(TestBasicOpsMixedPublicSchema)
+{
+ MixedPred pred;
+
+ ExecuteStatementsAndVerify(pred);
+}
+
+BOOST_AUTO_TEST_CASE(TestCreateDropNonExistingSchema)
+{
+ BOOST_CHECK_THROW(
+ Sql("CREATE TABLE UNKNOWN_SCHEMA." + TABLE_NAME + "(id INT PRIMARY KEY, val INT)"),
+ IgniteError
+ );
+
+ BOOST_CHECK_THROW(
+ Sql("DROP TABLE UNKNOWN_SCHEMA." + TABLE_NAME),
+ IgniteError
+ );
+}
+
+BOOST_AUTO_TEST_CASE(TestBasicOpsDiffSchemas)
+{
+ Sql("CREATE TABLE " + SCHEMA_NAME_1 + '.' + TABLE_NAME + " (s1_key INT PRIMARY KEY, s1_val INT)");
+ Sql("CREATE TABLE " + SCHEMA_NAME_2 + '.' + TABLE_NAME + " (s2_key INT PRIMARY KEY, s2_val INT)");
+ Sql("CREATE TABLE " + Q_SCHEMA_NAME_3 + '.' + TABLE_NAME + " (s3_key INT PRIMARY KEY, s3_val INT)");
+ Sql("CREATE TABLE " + SCHEMA_NAME_4 + '.' + TABLE_NAME + " (s4_key INT PRIMARY KEY, s4_val INT)");
+
+ Sql("INSERT INTO " + SCHEMA_NAME_1 + '.' + TABLE_NAME + " (s1_key, s1_val) VALUES (1, 2)");
+ Sql("INSERT INTO " + SCHEMA_NAME_2 + '.' + TABLE_NAME + " (s2_key, s2_val) VALUES (1, 2)");
+ Sql("INSERT INTO " + Q_SCHEMA_NAME_3 + '.' + TABLE_NAME + " (s3_key, s3_val) VALUES (1, 2)");
+ Sql("INSERT INTO " + SCHEMA_NAME_4 + '.' + TABLE_NAME + " (s4_key, s4_val) VALUES (1, 2)");
+
+ Sql("UPDATE " + SCHEMA_NAME_1 + '.' + TABLE_NAME + " SET s1_val = 5");
+ Sql("UPDATE " + SCHEMA_NAME_2 + '.' + TABLE_NAME + " SET s2_val = 5");
+ Sql("UPDATE " + Q_SCHEMA_NAME_3 + '.' + TABLE_NAME + " SET s3_val = 5");
+ Sql("UPDATE " + SCHEMA_NAME_4 + '.' + TABLE_NAME + " SET s4_val = 5");
+
+ Sql("DELETE FROM " + SCHEMA_NAME_1 + '.' + TABLE_NAME);
+ Sql("DELETE FROM " + SCHEMA_NAME_2 + '.' + TABLE_NAME);
+ Sql("DELETE FROM " + Q_SCHEMA_NAME_3 + '.' + TABLE_NAME);
+ Sql("DELETE FROM " + SCHEMA_NAME_4 + '.' + TABLE_NAME);
+
+ Sql("CREATE INDEX t1_idx_1 ON " + SCHEMA_NAME_1 + '.' + TABLE_NAME + "(s1_val)");
+ Sql("CREATE INDEX t1_idx_1 ON " + SCHEMA_NAME_2 + '.' + TABLE_NAME + "(s2_val)");
+ Sql("CREATE INDEX t1_idx_1 ON " + Q_SCHEMA_NAME_3 + '.' + TABLE_NAME + "(s3_val)");
+ Sql("CREATE INDEX t1_idx_1 ON " + SCHEMA_NAME_4 + '.' + TABLE_NAME + "(s4_val)");
+
+ Sql("SELECT * FROM " + SCHEMA_NAME_1 + '.' + TABLE_NAME);
+ Sql("SELECT * FROM " + SCHEMA_NAME_2 + '.' + TABLE_NAME);
+ Sql("SELECT * FROM " + Q_SCHEMA_NAME_3 + '.' + TABLE_NAME);
+ Sql("SELECT * FROM " + SCHEMA_NAME_4 + '.' + TABLE_NAME);
+
+ Sql("SELECT * FROM " + SCHEMA_NAME_1 + '.' + TABLE_NAME
+ + " JOIN " + SCHEMA_NAME_2 + '.' + TABLE_NAME
+ + " JOIN " + Q_SCHEMA_NAME_3 + '.' + TABLE_NAME
+ + " JOIN " + SCHEMA_NAME_4 + '.' + TABLE_NAME);
+
+ QueryFieldsCursor cursor = Sql("SELECT SCHEMA_NAME, KEY_ALIAS FROM SYS.TABLES ORDER BY SCHEMA_NAME");
+
+ CheckRow<std::string, std::string>(cursor, SCHEMA_NAME_1, "S1_KEY");
+ CheckRow<std::string, std::string>(cursor, SCHEMA_NAME_2, "S2_KEY");
+ CheckRow<std::string, std::string>(cursor, SCHEMA_NAME_4, "S4_KEY");
+ CheckRow<std::string, std::string>(cursor, SCHEMA_NAME_3, "S3_KEY");
+
+ ChechEmptyCursorGetNextThrowsException(cursor);
+
+ Sql("DROP TABLE " + SCHEMA_NAME_1 + '.' + TABLE_NAME);
+ Sql("DROP TABLE " + SCHEMA_NAME_2 + '.' + TABLE_NAME);
+ Sql("DROP TABLE " + Q_SCHEMA_NAME_3 + '.' + TABLE_NAME);
+ Sql("DROP TABLE " + SCHEMA_NAME_4 + '.' + TABLE_NAME);
+}
+
+BOOST_AUTO_TEST_CASE(TestCreateTblsInDiffSchemasForSameCache)
+{
+ std::string testCache = "cache1";
+
+ Sql("CREATE TABLE " + SCHEMA_NAME_1 + '.' + TABLE_NAME +
+ " (s1_key INT PRIMARY KEY, s1_val INT) WITH \"cache_name=" + testCache + '"');
+
+ BOOST_CHECK_THROW(
+ Sql("CREATE TABLE " + SCHEMA_NAME_2 + '.' + TABLE_NAME +
+ " (s1_key INT PRIMARY KEY, s2_val INT) WITH \"cache_name=" + testCache + '"'),
+ IgniteError
+ );
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/modules/platforms/cpp/odbc-test/CMakeLists.txt b/modules/platforms/cpp/odbc-test/CMakeLists.txt
index dd4273a..b3a8af9 100644
--- a/modules/platforms/cpp/odbc-test/CMakeLists.txt
+++ b/modules/platforms/cpp/odbc-test/CMakeLists.txt
@@ -28,7 +28,7 @@ find_package(Boost 1.53 REQUIRED COMPONENTS unit_test_framework chrono thread sy
find_package(ODBC REQUIRED)
include_directories(SYSTEM ${ODBC_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${JNI_INCLUDE_DIRS})
-include_directories(include ../odbc/include ../network/include)
+include_directories(include ../odbc/include ../network/include ../network/src)
set(SOURCES
src/teamcity/teamcity_boost.cpp
@@ -68,6 +68,7 @@ set(SOURCES
src/sql_parsing_test.cpp
src/streaming_test.cpp
src/cursor_binding_test.cpp
+ src/sql_schema_test.cpp
src/test_server.cpp
../odbc/src/log.cpp
../odbc/src/cursor.cpp
diff --git a/modules/platforms/cpp/odbc-test/config/queries-schema-32.xml b/modules/platforms/cpp/odbc-test/config/queries-schema-32.xml
new file mode 100644
index 0000000..c564301
--- /dev/null
+++ b/modules/platforms/cpp/odbc-test/config/queries-schema-32.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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.
+-->
+
+<!--
+ Ignite Spring configuration file to startup grid cache.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/util
+ http://www.springframework.org/schema/util/spring-util.xsd">
+ <import resource="queries-schema-default.xml"/>
+
+ <bean parent="grid.cfg">
+ <property name="memoryConfiguration">
+ <bean class="org.apache.ignite.configuration.MemoryConfiguration">
+ <property name="systemCacheInitialSize" value="#{10 * 1024 * 1024}"/>
+ <property name="systemCacheMaxSize" value="#{40 * 1024 * 1024}"/>
+ <property name="defaultMemoryPolicyName" value="dfltPlc"/>
+
+ <property name="memoryPolicies">
+ <list>
+ <bean class="org.apache.ignite.configuration.MemoryPolicyConfiguration">
+ <property name="name" value="dfltPlc"/>
+ <property name="maxSize" value="#{100 * 1024 * 1024}"/>
+ <property name="initialSize" value="#{10 * 1024 * 1024}"/>
+ </bean>
+ </list>
+ </property>
+ </bean>
+ </property>
+ </bean>
+</beans>
diff --git a/modules/platforms/cpp/odbc-test/config/queries-schema-default.xml b/modules/platforms/cpp/odbc-test/config/queries-schema-default.xml
new file mode 100644
index 0000000..bcdaec5
--- /dev/null
+++ b/modules/platforms/cpp/odbc-test/config/queries-schema-default.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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.
+-->
+
+<!--
+ Ignite Spring configuration file to startup grid cache.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/util
+ http://www.springframework.org/schema/util/spring-util.xsd">
+ <bean abstract="true" id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
+ <property name="localHost" value="127.0.0.1"/>
+ <property name="connectorConfiguration"><null/></property>
+
+ <property name="clientConnectorConfiguration">
+ <bean class="org.apache.ignite.configuration.ClientConnectorConfiguration">
+ <property name="host" value="127.0.0.1"/>
+ <property name="port" value="11110"/>
+ <property name="portRange" value="10"/>
+ </bean>
+ </property>
+
+ <property name="sqlSchemas">
+ <list>
+ <value>SCHEMA_1</value>
+ <value>SCHEMA_2</value>
+ <value>"ScHeMa3"</value>
+ <value>SCHEMA_4</value>
+ </list>
+ </property>
+
+ <property name="discoverySpi">
+ <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
+ <property name="ipFinder">
+ <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+ <property name="addresses">
+ <list>
+ <!-- In distributed environment, replace with actual host IP address. -->
+ <value>127.0.0.1:47500</value>
+ </list>
+ </property>
+ </bean>
+ </property>
+ <property name="socketTimeout" value="300" />
+ </bean>
+ </property>
+ </bean>
+</beans>
diff --git a/modules/platforms/cpp/odbc-test/config/queries-schema.xml b/modules/platforms/cpp/odbc-test/config/queries-schema.xml
new file mode 100644
index 0000000..1a9513f
--- /dev/null
+++ b/modules/platforms/cpp/odbc-test/config/queries-schema.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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.
+-->
+
+<!--
+ Ignite Spring configuration file to startup grid cache.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/util
+ http://www.springframework.org/schema/util/spring-util.xsd">
+ <import resource="queries-schema-default.xml"/>
+
+ <bean parent="grid.cfg"/>
+</beans>
diff --git a/modules/platforms/cpp/odbc-test/src/sql_schema_test.cpp b/modules/platforms/cpp/odbc-test/src/sql_schema_test.cpp
new file mode 100644
index 0000000..adf7e2c
--- /dev/null
+++ b/modules/platforms/cpp/odbc-test/src/sql_schema_test.cpp
@@ -0,0 +1,337 @@
+/*
+ * 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.
+ */
+
+#include <stdint.h>
+
+#include <iterator>
+
+#include <boost/test/unit_test.hpp>
+
+#include <ignite/common/utils.h>
+
+#include "ignite/cache/cache.h"
+#include "ignite/cache/query/query_cursor.h"
+#include "ignite/cache/query/query_sql_fields.h"
+#include "ignite/ignite.h"
+#include "ignite/ignition.h"
+
+#include "odbc_test_suite.h"
+#include "test_utils.h"
+#include "ignite/odbc/odbc_error.h"
+
+using namespace boost::unit_test;
+
+using namespace ignite;
+using namespace ignite::cache;
+using namespace ignite::cache::query;
+
+using namespace ignite_test;
+
+/**
+ * Ensure that cursor is empy fails.
+ *
+ * @param stmt Statement.
+ */
+void ChechEmptyCursorGetNextThrowsException(SQLHSTMT stmt)
+{
+ SQLRETURN ret = SQLFetch(stmt);
+
+ BOOST_REQUIRE_EQUAL(ret, SQL_NO_DATA);
+}
+
+/**
+ * Check single row through iteration.
+ *
+ * @param stmt Statement.
+ * @param c1 First column.
+ */
+void CheckSingleLongRow1(SQLHSTMT stmt, const int64_t c1)
+{
+ int64_t val1 = 0;
+
+ SQLRETURN ret = SQLFetch(stmt);
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ret = SQLGetData(stmt, 1, SQL_C_SBIGINT, &val1, 0, 0);
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ BOOST_REQUIRE_EQUAL(val1, c1);
+
+ ChechEmptyCursorGetNextThrowsException(stmt);
+}
+
+/**
+ * Check row through iteration.
+ *
+ * @param stmt Statement.
+ * @param c1 First column.
+ * @param c2 Second column.
+ */
+void CheckStringRow2(SQLHSTMT stmt, const std::string& c1, const std::string& c2)
+{
+ char val1[1024] = { 0 };
+ char val2[1024] = { 0 };
+ SQLLEN val1Len = 0;
+ SQLLEN val2Len = 0;
+
+ SQLRETURN ret = SQLFetch(stmt);
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ret = SQLGetData(stmt, 1, SQL_C_CHAR, val1, sizeof(val1), &val1Len);
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ret = SQLGetData(stmt, 2, SQL_C_CHAR, val2, sizeof(val2), &val2Len);
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ BOOST_REQUIRE_EQUAL(std::string(val1, static_cast<size_t>(val1Len)), c1);
+ BOOST_REQUIRE_EQUAL(std::string(val2, static_cast<size_t>(val2Len)), c2);
+}
+
+/**
+ * Check single row through iteration.
+ *
+ * @param stmt Statement.
+ * @param c1 First column.
+ * @param c2 Second column.
+ */
+void CheckSingleIntRow2(SQLHSTMT stmt, int32_t c1, int32_t c2)
+{
+ int32_t val1 = 0;
+ int32_t val2 = 0;
+
+ SQLRETURN ret = SQLFetch(stmt);
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ret = SQLGetData(stmt, 1, SQL_C_SLONG, &val1, 0, 0);
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ret = SQLGetData(stmt, 2, SQL_C_SLONG, &val2, 0, 0);
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ BOOST_REQUIRE_EQUAL(val1, c1);
+ BOOST_REQUIRE_EQUAL(val2, c2);
+
+ ChechEmptyCursorGetNextThrowsException(stmt);
+}
+
+static const std::string TABLE_NAME = "T1";
+static const std::string SCHEMA_NAME_1 = "SCHEMA_1";
+static const std::string SCHEMA_NAME_2 = "SCHEMA_2";
+static const std::string SCHEMA_NAME_3 = "ScHeMa3";
+static const std::string Q_SCHEMA_NAME_3 = '"' + SCHEMA_NAME_3 + '"';
+static const std::string SCHEMA_NAME_4 = "SCHEMA_4";
+
+/**
+ * Test setup fixture.
+ */
+struct SchemaTestSuiteFixture : odbc::OdbcTestSuite
+{
+ /**
+ * Constructor.
+ */
+ SchemaTestSuiteFixture() :
+ grid(StartNode("queries-schema.xml", "Node1"))
+ {
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=PUBLIC");
+ }
+
+ /**
+ * Destructor.
+ */
+ ~SchemaTestSuiteFixture()
+ {
+ Ignition::StopAll(true);
+ }
+
+ /** Perform SQL in cluster. */
+ void Sql(const std::string& sql)
+ {
+ SQLFreeStmt(stmt, SQL_CLOSE);
+
+ SQLRETURN ret = ExecQuery(sql);
+
+ ODBC_THROW_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
+ }
+
+ std::string TableName(bool withSchema)
+ {
+ return withSchema ? "PUBLIC." + TABLE_NAME : TABLE_NAME;
+ }
+
+ template<typename Predicate>
+ void ExecuteStatementsAndVerify(Predicate& pred)
+ {
+ Sql("CREATE TABLE " + TableName(pred()) + " (id INT PRIMARY KEY, val INT)");
+
+ Sql("CREATE INDEX t1_idx_1 ON " + TableName(pred()) + "(val)");
+
+ Sql("INSERT INTO " + TableName(pred()) + " (id, val) VALUES(1, 2)");
+
+ Sql("SELECT * FROM " + TableName(pred()));
+ CheckSingleIntRow2(stmt, 1, 2);
+
+ Sql("UPDATE " + TableName(pred()) + " SET val = 5");
+ Sql("SELECT * FROM " + TableName(pred()));
+ CheckSingleIntRow2(stmt, 1, 5);
+
+ Sql("DELETE FROM " + TableName(pred()) + " WHERE id = 1");
+ Sql("SELECT COUNT(*) FROM " + TableName(pred()));
+ CheckSingleLongRow1(stmt, 0);
+
+ Sql("SELECT COUNT(*) FROM SYS.TABLES WHERE schema_name = 'PUBLIC' "
+ "AND table_name = \'" + TABLE_NAME + "\'");
+ CheckSingleLongRow1(stmt, 1);
+
+ Sql("DROP TABLE " + TableName(pred()));
+ }
+
+ /** Node started during the test. */
+ Ignite grid;
+};
+
+BOOST_FIXTURE_TEST_SUITE(SchemaTestSuite, SchemaTestSuiteFixture)
+
+bool TruePred()
+{
+ return true;
+}
+
+BOOST_AUTO_TEST_CASE(TestBasicOpsExplicitPublicSchema)
+{
+ ExecuteStatementsAndVerify(TruePred);
+}
+
+bool FalsePred()
+{
+ return false;
+}
+
+BOOST_AUTO_TEST_CASE(TestBasicOpsImplicitPublicSchema)
+{
+ ExecuteStatementsAndVerify(FalsePred);
+}
+
+struct MixedPred
+{
+ int i;
+
+ MixedPred() : i(0)
+ {
+ // No-op.
+ }
+
+ bool operator()()
+ {
+ return (++i & 1) == 0;
+ }
+};
+
+BOOST_AUTO_TEST_CASE(TestBasicOpsMixedPublicSchema)
+{
+ MixedPred pred;
+
+ ExecuteStatementsAndVerify(pred);
+}
+
+BOOST_AUTO_TEST_CASE(TestCreateDropNonExistingSchema)
+{
+ BOOST_CHECK_THROW(
+ Sql("CREATE TABLE UNKNOWN_SCHEMA." + TABLE_NAME + "(id INT PRIMARY KEY, val INT)"),
+ OdbcClientError
+ );
+
+ BOOST_CHECK_THROW(
+ Sql("DROP TABLE UNKNOWN_SCHEMA." + TABLE_NAME),
+ OdbcClientError
+ );
+}
+
+BOOST_AUTO_TEST_CASE(TestBasicOpsDiffSchemas)
+{
+ Sql("CREATE TABLE " + SCHEMA_NAME_1 + '.' + TABLE_NAME + " (s1_key INT PRIMARY KEY, s1_val INT)");
+ Sql("CREATE TABLE " + SCHEMA_NAME_2 + '.' + TABLE_NAME + " (s2_key INT PRIMARY KEY, s2_val INT)");
+ Sql("CREATE TABLE " + Q_SCHEMA_NAME_3 + '.' + TABLE_NAME + " (s3_key INT PRIMARY KEY, s3_val INT)");
+ Sql("CREATE TABLE " + SCHEMA_NAME_4 + '.' + TABLE_NAME + " (s4_key INT PRIMARY KEY, s4_val INT)");
+
+ Sql("INSERT INTO " + SCHEMA_NAME_1 + '.' + TABLE_NAME + " (s1_key, s1_val) VALUES (1, 2)");
+ Sql("INSERT INTO " + SCHEMA_NAME_2 + '.' + TABLE_NAME + " (s2_key, s2_val) VALUES (1, 2)");
+ Sql("INSERT INTO " + Q_SCHEMA_NAME_3 + '.' + TABLE_NAME + " (s3_key, s3_val) VALUES (1, 2)");
+ Sql("INSERT INTO " + SCHEMA_NAME_4 + '.' + TABLE_NAME + " (s4_key, s4_val) VALUES (1, 2)");
+
+ Sql("UPDATE " + SCHEMA_NAME_1 + '.' + TABLE_NAME + " SET s1_val = 5");
+ Sql("UPDATE " + SCHEMA_NAME_2 + '.' + TABLE_NAME + " SET s2_val = 5");
+ Sql("UPDATE " + Q_SCHEMA_NAME_3 + '.' + TABLE_NAME + " SET s3_val = 5");
+ Sql("UPDATE " + SCHEMA_NAME_4 + '.' + TABLE_NAME + " SET s4_val = 5");
+
+ Sql("DELETE FROM " + SCHEMA_NAME_1 + '.' + TABLE_NAME);
+ Sql("DELETE FROM " + SCHEMA_NAME_2 + '.' + TABLE_NAME);
+ Sql("DELETE FROM " + Q_SCHEMA_NAME_3 + '.' + TABLE_NAME);
+ Sql("DELETE FROM " + SCHEMA_NAME_4 + '.' + TABLE_NAME);
+
+ Sql("CREATE INDEX t1_idx_1 ON " + SCHEMA_NAME_1 + '.' + TABLE_NAME + "(s1_val)");
+ Sql("CREATE INDEX t1_idx_1 ON " + SCHEMA_NAME_2 + '.' + TABLE_NAME + "(s2_val)");
+ Sql("CREATE INDEX t1_idx_1 ON " + Q_SCHEMA_NAME_3 + '.' + TABLE_NAME + "(s3_val)");
+ Sql("CREATE INDEX t1_idx_1 ON " + SCHEMA_NAME_4 + '.' + TABLE_NAME + "(s4_val)");
+
+ Sql("SELECT * FROM " + SCHEMA_NAME_1 + '.' + TABLE_NAME);
+ Sql("SELECT * FROM " + SCHEMA_NAME_2 + '.' + TABLE_NAME);
+ Sql("SELECT * FROM " + Q_SCHEMA_NAME_3 + '.' + TABLE_NAME);
+ Sql("SELECT * FROM " + SCHEMA_NAME_4 + '.' + TABLE_NAME);
+
+ Sql("SELECT * FROM " + SCHEMA_NAME_1 + '.' + TABLE_NAME
+ + " JOIN " + SCHEMA_NAME_2 + '.' + TABLE_NAME
+ + " JOIN " + Q_SCHEMA_NAME_3 + '.' + TABLE_NAME
+ + " JOIN " + SCHEMA_NAME_4 + '.' + TABLE_NAME);
+
+ Sql("SELECT SCHEMA_NAME, KEY_ALIAS FROM SYS.TABLES ORDER BY SCHEMA_NAME");
+
+ CheckStringRow2(stmt, SCHEMA_NAME_1, "S1_KEY");
+ CheckStringRow2(stmt, SCHEMA_NAME_2, "S2_KEY");
+ CheckStringRow2(stmt, SCHEMA_NAME_4, "S4_KEY");
+ CheckStringRow2(stmt, SCHEMA_NAME_3, "S3_KEY");
+
+ ChechEmptyCursorGetNextThrowsException(stmt);
+
+ Sql("DROP TABLE " + SCHEMA_NAME_1 + '.' + TABLE_NAME);
+ Sql("DROP TABLE " + SCHEMA_NAME_2 + '.' + TABLE_NAME);
+ Sql("DROP TABLE " + Q_SCHEMA_NAME_3 + '.' + TABLE_NAME);
+ Sql("DROP TABLE " + SCHEMA_NAME_4 + '.' + TABLE_NAME);
+}
+
+BOOST_AUTO_TEST_CASE(TestCreateTblsInDiffSchemasForSameCache)
+{
+ std::string testCache = "cache1";
+
+ Sql("CREATE TABLE " + SCHEMA_NAME_1 + '.' + TABLE_NAME +
+ " (s1_key INT PRIMARY KEY, s1_val INT) WITH \"cache_name=" + testCache + '"');
+
+ BOOST_CHECK_THROW(
+ Sql("CREATE TABLE " + SCHEMA_NAME_2 + '.' + TABLE_NAME +
+ " (s1_key INT PRIMARY KEY, s2_val INT) WITH \"cache_name=" + testCache + '"'),
+ OdbcClientError
+ );
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTestSchema.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTestSchema.cs
new file mode 100644
index 0000000..f0f5611
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTestSchema.cs
@@ -0,0 +1,255 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Cache.Query
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using Apache.Ignite.Core.Cache.Query;
+ using Apache.Ignite.Core.Common;
+ using NUnit.Framework;
+
+ /// <summary>
+ /// Tests Data Manipulation Language queries related to schema.
+ /// </summary>
+ public class CacheDmlQueriesTestSchema
+ {
+ /// Table name
+ private const string TableName = "T1";
+
+ private const string SchemaName1 = "SCHEMA_1";
+ private const string SchemaName2 = "SCHEMA_2";
+ private const string SchemaName3 = "ScHeMa3";
+ private const string SchemaName4 = "SCHEMA_4";
+
+ private const string QSchemaName4 = "\"" + SchemaName3 + "\"";
+
+ /// <summary>
+ /// Sets up test fixture.
+ /// </summary>
+ [TestFixtureSetUp]
+ public void FixtureSetUp()
+ {
+ var cfg = new IgniteConfiguration(TestUtils.GetTestConfiguration())
+ {
+ SqlSchemas = new List<string>
+ {
+ SchemaName1,
+ SchemaName2,
+ QSchemaName4,
+ SchemaName4
+ }
+ };
+
+ Ignition.Start(cfg);
+ }
+
+ /// <summary>
+ /// Tears down test fixture.
+ /// </summary>
+ [TestFixtureTearDown]
+ public void FixtureTearDown()
+ {
+ Ignition.StopAll(true);
+ }
+
+ /// <summary>
+ /// Schema explicitly defined.
+ /// </summary>
+ [Test]
+ public void TestBasicOpsExplicitPublicSchema()
+ {
+ ExecuteStmtsAndVerify(() => true);
+ }
+
+ /// <summary>
+ /// Schema is imlicit.
+ /// </summary>
+ [Test]
+ public void TestBasicOpsImplicitPublicSchema()
+ {
+ ExecuteStmtsAndVerify(() => false);
+ }
+
+ /// <summary>
+ /// Schema is mixed.
+ /// </summary>
+ [Test]
+ public void TestBasicOpsMixedPublicSchema()
+ {
+ int i = 0;
+
+ ExecuteStmtsAndVerify(() => ((++i & 1) == 0));
+ }
+
+ /// <summary>
+ /// Create and drop non-existing schema.
+ /// </summary>
+ [Test]
+ public void TestCreateDropNonExistingSchema()
+ {
+ Assert.Throws<IgniteException>(() =>
+ Sql("CREATE TABLE UNKNOWN_SCHEMA." + TableName + "(id INT PRIMARY KEY, val INT)"));
+
+ Assert.Throws<IgniteException>(() => Sql("DROP TABLE UNKNOWN_SCHEMA." + TableName));
+ }
+
+ /// <summary>
+ /// Create tables in different schemas for same cache.
+ /// </summary>
+ [Test]
+ public void TestCreateTblsInDiffSchemasForSameCache()
+ {
+ const string testCache = "cache1";
+
+ Sql("CREATE TABLE " + SchemaName1 + '.' + TableName
+ + " (s1_key INT PRIMARY KEY, s1_val INT) WITH \"cache_name=" + testCache + "\"");
+
+ Assert.Throws<IgniteException>(
+ () => Sql("CREATE TABLE " + SchemaName2 + '.' + TableName
+ + " (s1_key INT PRIMARY KEY, s2_val INT) WITH \"cache_name=" + testCache + "\"")
+ );
+
+ Sql("DROP TABLE " + SchemaName1 + '.' + TableName);
+ }
+
+ /// <summary>
+ /// Basic test with different schemas.
+ /// </summary>
+ [Test]
+ public void TestBasicOpsDiffSchemas()
+ {
+ Sql("CREATE TABLE " + SchemaName1 + '.' + TableName + " (s1_key INT PRIMARY KEY, s1_val INT)");
+ Sql("CREATE TABLE " + SchemaName2 + '.' + TableName + " (s2_key INT PRIMARY KEY, s2_val INT)");
+ Sql("CREATE TABLE " + QSchemaName4 + '.' + TableName + " (s3_key INT PRIMARY KEY, s3_val INT)");
+ Sql("CREATE TABLE " + SchemaName4 + '.' + TableName + " (s4_key INT PRIMARY KEY, s4_val INT)");
+
+ Sql("INSERT INTO " + SchemaName1 + '.' + TableName + " (s1_key, s1_val) VALUES (1, 2)");
+ Sql("INSERT INTO " + SchemaName2 + '.' + TableName + " (s2_key, s2_val) VALUES (1, 2)");
+ Sql("INSERT INTO " + QSchemaName4 + '.' + TableName + " (s3_key, s3_val) VALUES (1, 2)");
+ Sql("INSERT INTO " + SchemaName4 + '.' + TableName + " (s4_key, s4_val) VALUES (1, 2)");
+
+ Sql("UPDATE " + SchemaName1 + '.' + TableName + " SET s1_val = 5");
+ Sql("UPDATE " + SchemaName2 + '.' + TableName + " SET s2_val = 5");
+ Sql("UPDATE " + QSchemaName4 + '.' + TableName + " SET s3_val = 5");
+ Sql("UPDATE " + SchemaName4 + '.' + TableName + " SET s4_val = 5");
+
+ Sql("DELETE FROM " + SchemaName1 + '.' + TableName);
+ Sql("DELETE FROM " + SchemaName2 + '.' + TableName);
+ Sql("DELETE FROM " + QSchemaName4 + '.' + TableName);
+ Sql("DELETE FROM " + SchemaName4 + '.' + TableName);
+
+ Sql("CREATE INDEX t1_idx_1 ON " + SchemaName1 + '.' + TableName + "(s1_val)");
+ Sql("CREATE INDEX t1_idx_1 ON " + SchemaName2 + '.' + TableName + "(s2_val)");
+ Sql("CREATE INDEX t1_idx_1 ON " + QSchemaName4 + '.' + TableName + "(s3_val)");
+ Sql("CREATE INDEX t1_idx_1 ON " + SchemaName4 + '.' + TableName + "(s4_val)");
+
+ Sql("SELECT * FROM " + SchemaName1 + '.' + TableName);
+ Sql("SELECT * FROM " + SchemaName2 + '.' + TableName);
+ Sql("SELECT * FROM " + QSchemaName4 + '.' + TableName);
+ Sql("SELECT * FROM " + SchemaName4 + '.' + TableName);
+
+ Sql("SELECT * FROM " + SchemaName1 + '.' + TableName
+ + " JOIN " + SchemaName2 + '.' + TableName
+ + " JOIN " + QSchemaName4 + '.' + TableName
+ + " JOIN " + SchemaName4 + '.' + TableName);
+
+ VerifyTables();
+
+ Sql("DROP TABLE " + SchemaName1 + '.' + TableName);
+ Sql("DROP TABLE " + SchemaName2 + '.' + TableName);
+ Sql("DROP TABLE " + QSchemaName4 + '.' + TableName);
+ Sql("DROP TABLE " + SchemaName4 + '.' + TableName);
+ }
+
+ /// <summary>
+ /// Verify tables.
+ /// </summary>
+ private static void VerifyTables()
+ {
+ Sql("SELECT SCHEMA_NAME, KEY_ALIAS FROM SYS.TABLES ORDER BY SCHEMA_NAME", res =>
+ {
+ Assert.AreEqual(new List<List<object>>
+ {
+ new List<object> {SchemaName1, "S1_KEY"},
+ new List<object> {SchemaName2, "S2_KEY"},
+ new List<object> {SchemaName4, "S4_KEY"},
+ new List<object> {SchemaName3, "S3_KEY"}
+ }, res);
+ });
+ }
+
+ /// <summary>
+ /// Get test table name.
+ /// </summary>
+ private static string GetTableName(bool withSchema)
+ {
+ return withSchema ? "PUBLIC." + TableName : TableName;
+ }
+
+ /// <summary>
+ /// Perform SQL query.
+ /// </summary>
+ private static void Sql(string qry, Action<IList<IList<object>>> validator = null)
+ {
+ var res = Ignition
+ .GetIgnite()
+ .GetOrCreateCache<int, int>("TestCache")
+ .Query(new SqlFieldsQuery(qry))
+ .GetAll();
+
+ if (validator != null)
+ validator.Invoke(res);
+ }
+
+ /// <summary>
+ /// Generate one-row result set.
+ /// </summary>
+ private static List<List<object>> OneRowList(params object[] vals)
+ {
+ return new List<List<object>> {vals.ToList()};
+ }
+
+ /// <summary>
+ /// Create/insert/update/delete/drop table in PUBLIC schema.
+ /// </summary>
+ private static void ExecuteStmtsAndVerify(Func<bool> withSchemaDecisionSup)
+ {
+ Sql("CREATE TABLE " + GetTableName(withSchemaDecisionSup()) + " (id INT PRIMARY KEY, val INT)");
+
+ Sql("CREATE INDEX t1_idx_1 ON " + GetTableName(withSchemaDecisionSup()) + "(val)");
+
+ Sql("INSERT INTO " + GetTableName(withSchemaDecisionSup()) + " (id, val) VALUES(1, 2)");
+ Sql("SELECT * FROM " + GetTableName(withSchemaDecisionSup()),
+ res => Assert.AreEqual(OneRowList(1, 2), res));
+
+ Sql("UPDATE " + GetTableName(withSchemaDecisionSup()) + " SET val = 5");
+ Sql("SELECT * FROM " + GetTableName(withSchemaDecisionSup()),
+ res => Assert.AreEqual(OneRowList(1, 5), res));
+
+ Sql("DELETE FROM " + GetTableName(withSchemaDecisionSup()) + " WHERE id = 1");
+ Sql("SELECT COUNT(*) FROM " + GetTableName(withSchemaDecisionSup()),
+ res => Assert.AreEqual(OneRowList(0), res));
+
+ Sql("SELECT COUNT(*) FROM SYS.TABLES WHERE schema_name = 'PUBLIC' " +
+ "AND table_name = \'" + TableName + "\'", res => Assert.AreEqual(OneRowList(1), res));
+
+ Sql("DROP TABLE " + GetTableName(withSchemaDecisionSup()));
+ }
+ }
+}
\ No newline at end of file