Repository: ignite Updated Branches: refs/heads/master 9e35993c0 -> 66755c1a2
IGNITE-8331: Add Decimal precision and scale constraint - Fixes #4689. Signed-off-by: Nikolay Izhikov <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/66755c1a Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/66755c1a Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/66755c1a Branch: refs/heads/master Commit: 66755c1a2f39f9da948e4033a8b64afd9ba242f5 Parents: 9e35993 Author: ololo3000 <[email protected]> Authored: Fri Nov 2 12:44:27 2018 +0300 Committer: Nikolay Izhikov <[email protected]> Committed: Fri Nov 2 13:13:57 2018 +0300 ---------------------------------------------------------------------- .../jdbc/thin/JdbcThinMetadataSelfTest.java | 11 +- .../cache/query/IgniteQueryErrorCode.java | 8 + .../query/QueryTypeDescriptorImpl.java | 25 +- .../internal/processors/query/QueryUtils.java | 21 +- .../cache/index/IgniteDecimalSelfTest.java | 7 +- ...ePartitionedAtomicColumnConstraintsTest.java | 405 ++++++++++++++++++- ...ansactionalSnapshotColumnConstraintTest.java | 120 ++++++ ...ansactionalSnapshotColumnConstraintTest.java | 120 ++++++ .../sql/IgniteSQLColumnConstraintsTest.java | 288 +++++++++++-- ...gniteTransactionSQLColumnConstraintTest.java | 71 ++++ .../IgniteBinaryCacheQueryTestSuite.java | 6 + 11 files changed, 1015 insertions(+), 67 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/66755c1a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java index 2bc569d..6e08862 100644 --- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMetadataSelfTest.java @@ -155,6 +155,7 @@ public class JdbcThinMetadataSelfTest extends JdbcThinAbstractSelfTest { stmt.execute("CREATE INDEX \"MyTestIndex quoted\" on \"Quoted\" (\"Id\" DESC)"); stmt.execute("CREATE INDEX IDX ON TEST (ID ASC)"); stmt.execute("CREATE TABLE TEST_DECIMAL_COLUMN (ID INT primary key, DEC_COL DECIMAL(8, 3))"); + stmt.execute("CREATE TABLE TEST_DECIMAL_COLUMN_PRECISION (ID INT primary key, DEC_COL DECIMAL(8))"); } } @@ -253,7 +254,8 @@ public class JdbcThinMetadataSelfTest extends JdbcThinAbstractSelfTest { "dep.DEPARTMENT", "PUBLIC.TEST", "PUBLIC.Quoted", - "PUBLIC.TEST_DECIMAL_COLUMN")); + "PUBLIC.TEST_DECIMAL_COLUMN", + "PUBLIC.TEST_DECIMAL_COLUMN_PRECISION")); Set<String> actualTbls = new HashSet<>(expectedTbls.size()); @@ -403,7 +405,9 @@ public class JdbcThinMetadataSelfTest extends JdbcThinAbstractSelfTest { "PUBLIC.Quoted.Id.null", "PUBLIC.Quoted.Name.null.50", "PUBLIC.TEST_DECIMAL_COLUMN.ID.null", - "PUBLIC.TEST_DECIMAL_COLUMN.DEC_COL.null.8.3" + "PUBLIC.TEST_DECIMAL_COLUMN.DEC_COL.null.8.3", + "PUBLIC.TEST_DECIMAL_COLUMN_PRECISION.ID.null", + "PUBLIC.TEST_DECIMAL_COLUMN_PRECISION.DEC_COL.null.8" )); Set<String> actualCols = new HashSet<>(expectedCols.size()); @@ -555,7 +559,8 @@ public class JdbcThinMetadataSelfTest extends JdbcThinAbstractSelfTest { "PUBLIC.TEST.PK_PUBLIC_TEST.ID", "PUBLIC.TEST.PK_PUBLIC_TEST.NAME", "PUBLIC.Quoted.PK_PUBLIC_Quoted.Id", - "PUBLIC.TEST_DECIMAL_COLUMN.ID.ID")); + "PUBLIC.TEST_DECIMAL_COLUMN.ID.ID", + "PUBLIC.TEST_DECIMAL_COLUMN_PRECISION.ID.ID")); Set<String> actualPks = new HashSet<>(expectedPks.size()); http://git-wip-us.apache.org/repos/asf/ignite/blob/66755c1a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/IgniteQueryErrorCode.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/IgniteQueryErrorCode.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/IgniteQueryErrorCode.java index fd017f2..39f1b60 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/IgniteQueryErrorCode.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/IgniteQueryErrorCode.java @@ -106,6 +106,12 @@ public final class IgniteQueryErrorCode { /** Attempt to INSERT, UPDATE or MERGE value that exceed maximum column length. */ public static final int TOO_LONG_VALUE = 4008; + /** Attempt to INSERT, UPDATE or MERGE value which scale exceed maximum DECIMAL column scale. */ + public static final int VALUE_SCALE_OUT_OF_RANGE = 4009; + + /** Attempt to INSERT, UPDATE or MERGE value which scale exceed maximum DECIMAL column scale. */ + public static final int KEY_SCALE_OUT_OF_RANGE = 4010; + /* 5xxx - transactions related runtime errors. */ /** Transaction is already open. */ @@ -151,6 +157,8 @@ public final class IgniteQueryErrorCode { case DUPLICATE_KEY: case TOO_LONG_KEY: case TOO_LONG_VALUE: + case KEY_SCALE_OUT_OF_RANGE: + case VALUE_SCALE_OUT_OF_RANGE: return SqlStateCode.CONSTRAINT_VIOLATION; case NULL_KEY: http://git-wip-us.apache.org/repos/asf/ignite/blob/66755c1a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java index 6d8085e..87394f6 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java @@ -17,6 +17,7 @@ package org.apache.ignite.internal.processors.query; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -36,10 +37,12 @@ import org.apache.ignite.internal.util.typedef.internal.A; import org.apache.ignite.internal.util.typedef.internal.S; import org.jetbrains.annotations.Nullable; +import static org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode.KEY_SCALE_OUT_OF_RANGE; import static org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode.NULL_KEY; import static org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode.NULL_VALUE; import static org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode.TOO_LONG_KEY; import static org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode.TOO_LONG_VALUE; +import static org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode.VALUE_SCALE_OUT_OF_RANGE; import static org.apache.ignite.internal.processors.query.QueryUtils.KEY_FIELD_NAME; import static org.apache.ignite.internal.processors.query.QueryUtils.VAL_FIELD_NAME; @@ -579,14 +582,30 @@ public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor { isKey ? NULL_KEY : NULL_VALUE); } - if (prop.precision() != -1 && - propVal != null && - String.class == propVal.getClass() && + if (propVal == null || prop.precision() == -1) + continue; + + if (String.class == propVal.getClass() && ((String)propVal).length() > prop.precision()) { throw new IgniteSQLException("Value for a column '" + prop.name() + "' is too long. " + "Maximum length: " + prop.precision() + ", actual length: " + ((CharSequence)propVal).length(), isKey ? TOO_LONG_KEY : TOO_LONG_VALUE); } + else if (BigDecimal.class == propVal.getClass()) { + BigDecimal dec = (BigDecimal)propVal; + + if (dec.precision() > prop.precision()) { + throw new IgniteSQLException("Value for a column '" + prop.name() + "' is out of range. " + + "Maximum precision: " + prop.precision() + ", actual precision: " + dec.precision(), + isKey ? TOO_LONG_KEY : TOO_LONG_VALUE); + } + else if (prop.scale() != -1 && + dec.scale() > prop.scale()) { + throw new IgniteSQLException("Value for a column '" + prop.name() + "' is out of range. " + + "Maximum scale : " + prop.scale() + ", actual scale: " + dec.scale(), + isKey ? KEY_SCALE_OUT_OF_RANGE : VALUE_SCALE_OUT_OF_RANGE); + } + } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/66755c1a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java index e9420f1..44e07a6 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java @@ -67,6 +67,8 @@ import org.jetbrains.annotations.Nullable; import static org.apache.ignite.IgniteSystemProperties.IGNITE_INDEXING_DISCOVERY_HISTORY_SIZE; import static org.apache.ignite.IgniteSystemProperties.getInteger; +import static org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode.TOO_LONG_VALUE; +import static org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode.VALUE_SCALE_OUT_OF_RANGE; /** * Utility methods for queries. @@ -1271,6 +1273,7 @@ public class QueryUtils { Map<String, Object> dfltVals = entity.getDefaultFieldValues(); Map<String, Integer> precision = entity.getFieldsPrecision(); + Map<String, Integer> scale = entity.getFieldsScale(); if (!F.isEmpty(precision)) { for (String fld : precision.keySet()) { @@ -1282,9 +1285,23 @@ public class QueryUtils { if (dfltVal == null) continue; - if (dfltVal.toString().length() > precision.get(fld)) { + if (dfltVal.getClass() == String.class && dfltVal.toString().length() > precision.get(fld)) { throw new IgniteSQLException("Default value '" + dfltVal + - "' is longer than maximum length " + precision.get(fld)); + "' is longer than maximum length " + precision.get(fld), TOO_LONG_VALUE); + } + else if (dfltVal.getClass() == BigDecimal.class) { + BigDecimal dec = (BigDecimal)dfltVal; + + if (dec.precision() > precision.get(fld)) { + throw new IgniteSQLException("Default value: '" + dfltVal + "' for a column " + fld + + " is out of range. Maximum precision: " + precision.get(fld) + + ", actual precision: " + dec.precision(), TOO_LONG_VALUE); + } + else if (!F.isEmpty(scale) && scale.containsKey(fld) && dec.scale() > scale.get(fld)) { + throw new IgniteSQLException("Default value:: '" + dfltVal + "' for a column " + fld + + " is out of range. Maximum scale: " + scale.get(fld) + + ", actual scale: " + dec.scale(), VALUE_SCALE_OUT_OF_RANGE); + } } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/66755c1a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/IgniteDecimalSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/IgniteDecimalSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/IgniteDecimalSelfTest.java index 96926ea..b3743de 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/IgniteDecimalSelfTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/IgniteDecimalSelfTest.java @@ -34,7 +34,6 @@ import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.internal.IgniteEx; import org.jetbrains.annotations.NotNull; -import static java.math.RoundingMode.HALF_UP; import static java.util.Arrays.asList; /** @@ -60,13 +59,13 @@ public class IgniteDecimalSelfTest extends AbstractSchemaSelfTest { private static final MathContext MATH_CTX = new MathContext(PRECISION); /** */ - private static final BigDecimal VAL_1 = new BigDecimal("123456789", MATH_CTX).setScale(SCALE, HALF_UP); + private static final BigDecimal VAL_1 = BigDecimal.valueOf(123456789); /** */ - private static final BigDecimal VAL_2 = new BigDecimal("12345678.12345678", MATH_CTX).setScale(SCALE, HALF_UP); + private static final BigDecimal VAL_2 = BigDecimal.valueOf(1.23456789); /** */ - private static final BigDecimal VAL_3 = new BigDecimal(".123456789", MATH_CTX).setScale(SCALE, HALF_UP); + private static final BigDecimal VAL_3 = BigDecimal.valueOf(.12345678); /** {@inheritDoc} */ @Override protected void beforeTestsStarted() throws Exception { http://git-wip-us.apache.org/repos/asf/ignite/blob/66755c1a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteCachePartitionedAtomicColumnConstraintsTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteCachePartitionedAtomicColumnConstraintsTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteCachePartitionedAtomicColumnConstraintsTest.java index 3715cf7..71bedaa 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteCachePartitionedAtomicColumnConstraintsTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteCachePartitionedAtomicColumnConstraintsTest.java @@ -18,6 +18,7 @@ package org.apache.ignite.internal.processors.sql; import java.io.Serializable; +import java.math.BigDecimal; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -39,6 +40,7 @@ import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import org.jetbrains.annotations.NotNull; import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC; +import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL_SNAPSHOT; import static org.apache.ignite.cache.CacheMode.PARTITIONED; import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC; import static org.apache.ignite.internal.processors.query.QueryUtils.KEY_FIELD_NAME; @@ -55,13 +57,32 @@ public class IgniteCachePartitionedAtomicColumnConstraintsTest extends GridCommo /** */ private static final String STR_ORG_CACHE_NAME = "STR_ORG"; - + + /** */ private static final String STR_ORG_WITH_FIELDS_CACHE_NAME = "STR_ORG_WITH_FIELDS"; /** */ private static final String OBJ_CACHE_NAME = "ORG_ADDRESS"; /** */ + private static final String DEC_CACHE_NAME_FOR_SCALE = "DEC_DEC_FOR_SCALE"; + + /** */ + private static final String OBJ_CACHE_NAME_FOR_SCALE = "ORG_EMPLOYEE_FOR_SCALE"; + + /** */ + private static final String DEC_EMPL_CACHE_NAME_FOR_SCALE = "DEC_EMPLOYEE_FOR_SCALE"; + + /** */ + private static final String DEC_CACHE_NAME_FOR_PREC = "DEC_DEC_FOR_PREC"; + + /** */ + private static final String OBJ_CACHE_NAME_FOR_PREC = "ORG_EMPLOYEE_FOR_PREC"; + + /** */ + private static final String DEC_EMPL_CACHE_NAME_FOR_PREC = "DEC_EMPLOYEE_FOR_PREC"; + + /** */ private Consumer<Runnable> shouldFail = (op) -> assertThrowsWithCause(op, IgniteException.class); /** */ @@ -71,6 +92,15 @@ public class IgniteCachePartitionedAtomicColumnConstraintsTest extends GridCommo @Override protected void beforeTestsStarted() throws Exception { startGrid(0); + createCachesForStringTests(); + + createCachesForDecimalPrecisionTests(); + + createCachesForDecimalScaleTests(); + } + + /** @throws Exception If failed.*/ + private void createCachesForStringTests() throws Exception { Map<String, Integer> strStrPrecision = new HashMap<>(); strStrPrecision.put(KEY_FIELD_NAME, 5); @@ -102,10 +132,88 @@ public class IgniteCachePartitionedAtomicColumnConstraintsTest extends GridCommo .setFieldsPrecision(strOrgPrecision)), STR_ORG_WITH_FIELDS_CACHE_NAME); } + /** @throws Exception If failed.*/ + private void createCachesForDecimalPrecisionTests() throws Exception { + Map<String, Integer> decDecPrecision = new HashMap<>(); + + decDecPrecision.put(KEY_FIELD_NAME, 4); + decDecPrecision.put(VAL_FIELD_NAME, 4); + + jcache(grid(0), cacheConfiguration(new QueryEntity(BigDecimal.class.getName(), BigDecimal.class.getName()) + .setFieldsPrecision(decDecPrecision)), DEC_CACHE_NAME_FOR_PREC); + + Map<String, Integer> orgEmployeePrecision = new HashMap<>(); + + orgEmployeePrecision.put("id", 4); + orgEmployeePrecision.put("salary", 4); + + jcache(grid(0), cacheConfiguration(new QueryEntity(DecOrganization.class.getName(), Employee.class.getName()) + .addQueryField("id", "java.math.BigDecimal", "id") + .addQueryField("salary", "java.math.BigDecimal", "salary") + .setFieldsPrecision(orgEmployeePrecision)), OBJ_CACHE_NAME_FOR_PREC); + + Map<String, Integer> decEmployeePrecision = new HashMap<>(); + + decEmployeePrecision.put(KEY_FIELD_NAME, 4); + decEmployeePrecision.put("salary", 4); + + jcache(grid(0), cacheConfiguration(new QueryEntity(BigDecimal.class.getName(), Employee.class.getName()) + .addQueryField("salary", "java.math.BigDecimal", "salary") + .setFieldsPrecision(decEmployeePrecision)), DEC_EMPL_CACHE_NAME_FOR_PREC); + } + + /** @throws Exception If failed.*/ + private void createCachesForDecimalScaleTests() throws Exception { + Map<String, Integer> decDecPrecision = new HashMap<>(); + + decDecPrecision.put(KEY_FIELD_NAME, 4); + decDecPrecision.put(VAL_FIELD_NAME, 4); + + Map<String, Integer> decDecScale = new HashMap<>(); + + decDecScale.put(KEY_FIELD_NAME, 2); + decDecScale.put(VAL_FIELD_NAME, 2); + + jcache(grid(0), cacheConfiguration(new QueryEntity(BigDecimal.class.getName(), BigDecimal.class.getName()) + .setFieldsScale(decDecScale) + .setFieldsPrecision(decDecPrecision)), DEC_CACHE_NAME_FOR_SCALE); + + Map<String, Integer> orgEmployeePrecision = new HashMap<>(); + + orgEmployeePrecision.put("id", 4); + orgEmployeePrecision.put("salary", 4); + + Map<String, Integer> orgEmployeeScale = new HashMap<>(); + + orgEmployeeScale.put("id", 2); + orgEmployeeScale.put("salary", 2); + + jcache(grid(0), cacheConfiguration(new QueryEntity(DecOrganization.class.getName(), Employee.class.getName()) + .addQueryField("id", "java.math.BigDecimal", "id") + .addQueryField("salary", "java.math.BigDecimal", "salary") + .setFieldsScale(orgEmployeeScale) + .setFieldsPrecision(orgEmployeePrecision)), OBJ_CACHE_NAME_FOR_SCALE); + + Map<String, Integer> decEmployeePrecision = new HashMap<>(); + + decEmployeePrecision.put(KEY_FIELD_NAME, 4); + decEmployeePrecision.put("salary", 4); + + Map<String, Integer> decEmployeeScale = new HashMap<>(); + + decEmployeeScale.put(KEY_FIELD_NAME, 2); + decEmployeeScale.put("salary", 2); + + jcache(grid(0), cacheConfiguration(new QueryEntity(BigDecimal.class.getName(), Employee.class.getName()) + .addQueryField("salary", "java.math.BigDecimal", "salary") + .setFieldsPrecision(decEmployeePrecision) + .setFieldsScale(decEmployeeScale)), DEC_EMPL_CACHE_NAME_FOR_SCALE); + } + /** * @throws Exception If failed. */ - public void testPutTooLongValueFail() throws Exception { + public void testPutTooLongStringValueFail() throws Exception { IgniteCache<String, String> cache = jcache(0, STR_CACHE_NAME); T2<String, String> val = new T2<>("3", "123456"); @@ -113,14 +221,14 @@ public class IgniteCachePartitionedAtomicColumnConstraintsTest extends GridCommo checkPutAll(shouldFail, cache, new T2<>("1", "1"), val); checkPutOps(shouldFail, cache, val); - + checkReplaceOps(shouldFail, cache, val, "1"); } /** * @throws Exception If failed. */ - public void testPutTooLongKeyFail() throws Exception { + public void testPutTooLongStringKeyFail() throws Exception { IgniteCache<String, String> cache = jcache(0, STR_CACHE_NAME); T2<String, String> val = new T2<>("123456", "2"); @@ -133,7 +241,7 @@ public class IgniteCachePartitionedAtomicColumnConstraintsTest extends GridCommo /** * @throws Exception If failed. */ - public void testPutTooLongValueFieldFail() throws Exception { + public void testPutTooLongStringValueFieldFail() throws Exception { IgniteCache<Organization, Address> cache = jcache(0, OBJ_CACHE_NAME); T2<Organization, Address> val = new T2<>(new Organization("3"), new Address("123456")); @@ -148,7 +256,7 @@ public class IgniteCachePartitionedAtomicColumnConstraintsTest extends GridCommo /** * @throws Exception If failed. */ - public void testPutTooLongKeyFieldFail() throws Exception { + public void testPutTooLongStringKeyFieldFail() throws Exception { IgniteCache<Organization, Address> cache = jcache(0, OBJ_CACHE_NAME); T2<Organization, Address> val = new T2<>(new Organization("123456"), new Address("2")); @@ -161,19 +269,21 @@ public class IgniteCachePartitionedAtomicColumnConstraintsTest extends GridCommo /** * @throws Exception If failed. */ - public void testPutTooLongKeyFail2() throws Exception { - doCheckPutTooLongKeyFail2(STR_ORG_CACHE_NAME); + public void testPutTooLongStringKeyFail2() throws Exception { + doCheckPutTooLongStringKeyFail2(STR_ORG_CACHE_NAME); } /** * @throws Exception If failed. */ - public void testPutTooLongKeyFail3() throws Exception { - doCheckPutTooLongKeyFail2(STR_ORG_WITH_FIELDS_CACHE_NAME); + public void testPutTooLongStringKeyFail3() throws Exception { + doCheckPutTooLongStringKeyFail2(STR_ORG_WITH_FIELDS_CACHE_NAME); } - - private void doCheckPutTooLongKeyFail2(String cacheName) { + /** + * @throws Exception If failed. + */ + private void doCheckPutTooLongStringKeyFail2(String cacheName) { IgniteCache<String, Organization> cache = jcache(0, cacheName); T2<String, Organization> val = new T2<>("123456", new Organization("1")); @@ -186,7 +296,7 @@ public class IgniteCachePartitionedAtomicColumnConstraintsTest extends GridCommo /** * @throws Exception If failed. */ - public void testPutLongValue() throws Exception { + public void testPutLongStringValue() throws Exception { IgniteCache<String, String> cache = jcache(0, STR_CACHE_NAME); T2<String, String> val = new T2<>("3", "12345"); @@ -201,7 +311,7 @@ public class IgniteCachePartitionedAtomicColumnConstraintsTest extends GridCommo /** * @throws Exception If failed. */ - public void testPutLongKey() throws Exception { + public void testPutLongStringKey() throws Exception { IgniteCache<String, String> cache = jcache(0, STR_CACHE_NAME); T2<String, String> val = new T2<>("12345", "2"); @@ -214,7 +324,7 @@ public class IgniteCachePartitionedAtomicColumnConstraintsTest extends GridCommo /** * @throws Exception If failed. */ - public void testPutLongValueField() throws Exception { + public void testPutLongStringValueField() throws Exception { IgniteCache<Organization, Address> cache = jcache(0, OBJ_CACHE_NAME); T2<Organization, Address> val = new T2<>(new Organization("3"), new Address("12345")); @@ -229,7 +339,7 @@ public class IgniteCachePartitionedAtomicColumnConstraintsTest extends GridCommo /** * @throws Exception If failed. */ - public void testPutLongKeyField() throws Exception { + public void testPutLongStringKeyField() throws Exception { IgniteCache<Organization, Address> cache = jcache(0, OBJ_CACHE_NAME); T2<Organization, Address> val = new T2<>(new Organization("12345"), new Address("2")); @@ -242,18 +352,21 @@ public class IgniteCachePartitionedAtomicColumnConstraintsTest extends GridCommo /** * @throws Exception If failed. */ - public void testPutLongKey2() throws Exception { - doCheckPutLongKey2(STR_ORG_CACHE_NAME); + public void testPutLongStringKey2() throws Exception { + doCheckPutLongStringKey2(STR_ORG_CACHE_NAME); } /** * @throws Exception If failed. */ - public void testPutLongKey3() throws Exception { - doCheckPutLongKey2(STR_ORG_WITH_FIELDS_CACHE_NAME); + public void testPutLongStringKey3() throws Exception { + doCheckPutLongStringKey2(STR_ORG_WITH_FIELDS_CACHE_NAME); } - private void doCheckPutLongKey2(String cacheName) { + /** + * @throws Exception If failed. + */ + private void doCheckPutLongStringKey2(String cacheName) { IgniteCache<String, Organization> cache = jcache(0, cacheName); T2<String, Organization> key2 = new T2<>("12345", new Organization("1")); @@ -263,6 +376,224 @@ public class IgniteCachePartitionedAtomicColumnConstraintsTest extends GridCommo checkPutOps(shouldSucceed, cache, key2); } + /** + * @throws Exception If failed. + */ + public void testPutTooLongDecimalValueFail() throws Exception { + IgniteCache<BigDecimal, BigDecimal> cache = jcache(0, DEC_CACHE_NAME_FOR_PREC); + + T2<BigDecimal, BigDecimal> val = new T2<>(d(12.36), d(123.45)); + + checkPutAll(shouldFail, cache, new T2<>(d(12.34), d(12.34)), val); + + checkPutOps(shouldFail, cache, val); + + checkReplaceOps(shouldFail, cache, val, d(12.34)); + } + + /** + * @throws Exception If failed. + */ + public void testPutTooLongDecimalKeyFail() throws Exception { + IgniteCache<BigDecimal, BigDecimal> cache = jcache(0, DEC_CACHE_NAME_FOR_PREC); + + T2<BigDecimal, BigDecimal> val = new T2<>(d(123.45), d(12.34)); + + checkPutAll(shouldFail, cache, new T2<>(d(12.35), d(12.34)), val); + + checkPutOps(shouldFail, cache, val); + } + + /** + * @throws Exception If failed. + */ + public void testPutTooLongDecimalKeyFail2() throws Exception { + IgniteCache<BigDecimal, Employee> cache = jcache(0, DEC_EMPL_CACHE_NAME_FOR_PREC); + + T2<BigDecimal, Employee> val = new T2<>(d(123.45), new Employee(d(12.34))); + + checkPutAll(shouldFail, cache, new T2<>(d(12.35), new Employee(d(12.34))), val); + + checkPutOps(shouldFail, cache, val); + } + + /** + * @throws Exception If failed. + */ + public void testPutTooLongDecimalValueFieldFail() throws Exception { + IgniteCache<DecOrganization, Employee> cache = jcache(0, OBJ_CACHE_NAME_FOR_PREC); + + T2<DecOrganization, Employee> val = new T2<>(new DecOrganization(d(12.36)), new Employee(d(123.45))); + + checkPutAll(shouldFail, cache, new T2<>(new DecOrganization(d(12.34)), new Employee(d(12.34))), val); + + checkPutOps(shouldFail, cache, val); + + checkReplaceOps(shouldFail, cache, val, new Employee(d(12.34))); + } + + /** + * @throws Exception If failed. + */ + public void testPutTooLongDecimalValueFieldFail2() throws Exception { + IgniteCache<BigDecimal, Employee> cache = jcache(0, DEC_EMPL_CACHE_NAME_FOR_PREC); + + T2<BigDecimal, Employee> val = new T2<>(d(12.36), new Employee(d(123.45))); + + checkPutAll(shouldFail, cache, new T2<>(d(12.34), new Employee(d(12.34))), val); + + checkPutOps(shouldFail, cache, val); + + checkReplaceOps(shouldFail, cache, val, new Employee(d(12.34))); + } + + /** + * @throws Exception If failed. + */ + public void testPutTooLongDecimalKeyFieldFail() throws Exception { + IgniteCache<DecOrganization, Employee> cache = jcache(0, OBJ_CACHE_NAME_FOR_PREC); + + T2<DecOrganization, Employee> val = new T2<>(new DecOrganization(d(123.45)), new Employee(d(12.34))); + + checkPutAll(shouldFail, cache, new T2<>(new DecOrganization(d(12.35)), new Employee(d(12.34))), val); + + checkPutOps(shouldFail, cache, val); + } + + /** + * @throws Exception If failed. + */ + public void testPutTooLongDecimalValueScaleFail() throws Exception { + IgniteCache<BigDecimal, BigDecimal> cache = jcache(0, DEC_CACHE_NAME_FOR_SCALE); + + T2<BigDecimal, BigDecimal> val = new T2<>(d(12.36), d(3.456)); + + checkPutAll(shouldFail, cache, new T2<>(d(12.34), d(12.34)), val); + + checkPutOps(shouldFail, cache, val); + + checkReplaceOps(shouldFail, cache, val, d(12.34)); + } + + /** + * @throws Exception If failed. + */ + public void testPutTooLongDecimalKeyScaleFail() throws Exception { + IgniteCache<BigDecimal, BigDecimal> cache = jcache(0, DEC_CACHE_NAME_FOR_SCALE); + + T2<BigDecimal, BigDecimal> val = new T2<>(d(3.456), d(12.34)); + + checkPutAll(shouldFail, cache, new T2<>(d(12.35), d(12.34)), val); + + checkPutOps(shouldFail, cache, val); + } + + /** + * @throws Exception If failed. + */ + public void testPutTooLongDecimalKeyScaleFail2() throws Exception { + IgniteCache<BigDecimal, Employee> cache = jcache(0, DEC_EMPL_CACHE_NAME_FOR_SCALE); + + T2<BigDecimal, Employee> val = new T2<>(d(3.456), new Employee(d(12.34))); + + checkPutAll(shouldFail, cache, new T2<>(d(12.35), new Employee(d(12.34))), val); + + checkPutOps(shouldFail, cache, val); + } + + /** + * @throws Exception If failed. + */ + public void testPutTooLongDecimalValueFieldScaleFail() throws Exception { + IgniteCache<DecOrganization, Employee> cache = jcache(0, OBJ_CACHE_NAME_FOR_SCALE); + + T2<DecOrganization, Employee> val = new T2<>(new DecOrganization(d(12.36)), new Employee(d(3.456))); + + checkPutAll(shouldFail, cache, new T2<>(new DecOrganization(d(12.34)), new Employee(d(12.34))), val); + + checkPutOps(shouldFail, cache, val); + + checkReplaceOps(shouldFail, cache, val, new Employee(d(12.34))); + } + + /** + * @throws Exception If failed. + */ + public void testPutTooLongDecimalValueFieldScaleFail2() throws Exception { + IgniteCache<BigDecimal, Employee> cache = jcache(0, DEC_EMPL_CACHE_NAME_FOR_SCALE); + + T2<BigDecimal, Employee> val = new T2<>(d(12.36), new Employee(d(3.456))); + + checkPutAll(shouldFail, cache, new T2<>(d(12.34), new Employee(d(12.34))), val); + + checkPutOps(shouldFail, cache, val); + + checkReplaceOps(shouldFail, cache, val, new Employee(d(12.34))); + } + + /** + * @throws Exception If failed. + */ + public void testPutTooLongDecimalKeyFieldScaleFail() throws Exception { + IgniteCache<DecOrganization, Employee> cache = jcache(0, OBJ_CACHE_NAME_FOR_SCALE); + + T2<DecOrganization, Employee> val = new T2<>(new DecOrganization(d(3.456)), new Employee(d(12.34))); + + checkPutAll(shouldFail, cache, new T2<>(new DecOrganization(d(12.35)), new Employee(d(12.34))), val); + + checkPutOps(shouldFail, cache, val); + } + + /** + * @throws Exception If failed. + */ + public void testPutValidDecimalKeyAndValue() throws Exception { + IgniteCache<BigDecimal, BigDecimal> cache = jcache(0, DEC_CACHE_NAME_FOR_SCALE); + + T2<BigDecimal, BigDecimal> val = new T2<>(d(12.37), d(12.34)); + + checkPutAll(shouldSucceed, cache, new T2<>(d(12.36), d(12.34)), val); + + checkPutOps(shouldSucceed, cache, val); + + checkReplaceOps(shouldSucceed, cache, val, d(12.34)); + } + + /** + * @throws Exception If failed. + */ + public void testPutValidDecimalKeyAndValueField() throws Exception { + IgniteCache<DecOrganization, Employee> cache = jcache(0, OBJ_CACHE_NAME_FOR_SCALE); + + T2<DecOrganization, Employee> val = new T2<>(new DecOrganization(d(12.37)), new Employee(d(12.34))); + + checkPutAll(shouldSucceed, cache, new T2<>(new DecOrganization(d(12.36)), new Employee(d(12.34))), val); + + checkPutOps(shouldSucceed, cache, val); + + checkReplaceOps(shouldSucceed, cache, val, new Employee(d(12.34))); + } + + /** + * @throws Exception If failed. + */ + public void testPutValidDecimalKeyAndValueField2() throws Exception { + IgniteCache<BigDecimal, Employee> cache = jcache(0, DEC_EMPL_CACHE_NAME_FOR_SCALE); + + T2<BigDecimal, Employee> val = new T2<>(d(12.37), new Employee(d(12.34))); + + checkPutAll(shouldSucceed, cache, new T2<>(d(12.36), new Employee(d(12.34))), val); + + checkPutOps(shouldSucceed, cache, val); + + checkReplaceOps(shouldSucceed, cache, val, new Employee(d(12.34))); + } + + /** */ + private BigDecimal d(double val) { + return BigDecimal.valueOf(val); + } + /** */ private <K, V> void checkReplaceOps(Consumer<Runnable> checker, IgniteCache<K, V> cache, T2<K, V> val, V okVal) { K k = val.get1(); @@ -352,9 +683,11 @@ public class IgniteCachePartitionedAtomicColumnConstraintsTest extends GridCommo cache.setAtomicityMode(atomicityMode()); cache.setBackups(1); cache.setWriteSynchronizationMode(FULL_SYNC); - cache.setQueryEntities(Collections.singletonList(qryEntity)); + if (TRANSACTIONAL_SNAPSHOT.equals(atomicityMode())) + cache.setNearConfiguration(null); + return cache; } @@ -393,4 +726,32 @@ public class IgniteCachePartitionedAtomicColumnConstraintsTest extends GridCommo this.address = address; } } + + /** */ + @SuppressWarnings("UnusedDeclaration") + private static class DecOrganization implements Serializable { + /** Id. */ + private final BigDecimal id; + + /** + * @param id Id. + */ + private DecOrganization(BigDecimal id) { + this.id = id; + } + } + + /** */ + @SuppressWarnings("UnusedDeclaration") + private static class Employee implements Serializable { + /** Salary. */ + private final BigDecimal salary; + + /** + * @param salary Salary. + */ + private Employee(BigDecimal salary) { + this.salary = salary; + } + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/66755c1a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteCachePartitionedTransactionalSnapshotColumnConstraintTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteCachePartitionedTransactionalSnapshotColumnConstraintTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteCachePartitionedTransactionalSnapshotColumnConstraintTest.java new file mode 100644 index 0000000..a636a3c --- /dev/null +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteCachePartitionedTransactionalSnapshotColumnConstraintTest.java @@ -0,0 +1,120 @@ +/* + * 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.sql; + +import org.apache.ignite.cache.CacheAtomicityMode; +import org.jetbrains.annotations.NotNull; + +/** */ +public class IgniteCachePartitionedTransactionalSnapshotColumnConstraintTest + extends IgniteCachePartitionedAtomicColumnConstraintsTest { + /** {@inheritDoc} */ + @NotNull @Override protected CacheAtomicityMode atomicityMode() { + return CacheAtomicityMode.TRANSACTIONAL_SNAPSHOT; + } + + /** */ + @Override public void testPutTooLongStringValueFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongStringKeyFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongStringValueFieldFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongStringKeyFieldFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongStringKeyFail2() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongStringKeyFail3() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalValueFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalKeyFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalKeyFail2() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalValueFieldFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalValueFieldFail2() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalKeyFieldFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalValueScaleFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalKeyScaleFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalKeyScaleFail2() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalValueFieldScaleFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalValueFieldScaleFail2() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalKeyFieldScaleFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/66755c1a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteCacheReplicatedTransactionalSnapshotColumnConstraintTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteCacheReplicatedTransactionalSnapshotColumnConstraintTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteCacheReplicatedTransactionalSnapshotColumnConstraintTest.java new file mode 100644 index 0000000..2a7f6b5 --- /dev/null +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteCacheReplicatedTransactionalSnapshotColumnConstraintTest.java @@ -0,0 +1,120 @@ +/* + * 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.sql; + +import org.apache.ignite.cache.CacheAtomicityMode; +import org.jetbrains.annotations.NotNull; + +/** */ +public class IgniteCacheReplicatedTransactionalSnapshotColumnConstraintTest + extends IgniteCacheReplicatedAtomicColumnConstraintsTest { + /** {@inheritDoc} */ + @NotNull @Override protected CacheAtomicityMode atomicityMode() { + return CacheAtomicityMode.TRANSACTIONAL_SNAPSHOT; + } + + /** */ + @Override public void testPutTooLongStringValueFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongStringKeyFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongStringValueFieldFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongStringKeyFieldFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongStringKeyFail2() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongStringKeyFail3() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalValueFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalKeyFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalKeyFail2() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalValueFieldFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalValueFieldFail2() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalKeyFieldFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalValueScaleFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalKeyScaleFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalKeyScaleFail2() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalValueFieldScaleFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalValueFieldScaleFail2() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } + + /** */ + @Override public void testPutTooLongDecimalKeyFieldScaleFail() { + fail("https://issues.apache.org/jira/browse/IGNITE-10066"); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/66755c1a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteSQLColumnConstraintsTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteSQLColumnConstraintsTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteSQLColumnConstraintsTest.java index af0b432..8e82063 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteSQLColumnConstraintsTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteSQLColumnConstraintsTest.java @@ -17,13 +17,16 @@ package org.apache.ignite.internal.processors.sql; +import java.math.BigDecimal; import java.util.List; +import java.util.Objects; import org.apache.ignite.cache.query.SqlFieldsQuery; import org.apache.ignite.internal.processors.query.IgniteSQLException; import org.apache.ignite.testframework.GridTestUtils; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import static org.apache.ignite.internal.processors.odbc.SqlStateCode.CONSTRAINT_VIOLATION; +import static org.apache.ignite.internal.processors.odbc.SqlStateCode.INTERNAL_ERROR; /** */ @@ -32,111 +35,330 @@ public class IgniteSQLColumnConstraintsTest extends GridCommonAbstractTest { @Override protected void beforeTestsStarted() throws Exception { startGrid(0); - execSQL("CREATE TABLE varchar_table(id INT PRIMARY KEY, str VARCHAR(5))"); + String mvccQry = mvccEnabled() ? " WITH \"atomicity=transactional_snapshot\"" : ""; + + runSQL("CREATE TABLE varchar_table(id INT PRIMARY KEY, str VARCHAR(5))" + mvccQry); execSQL("INSERT INTO varchar_table VALUES(?, ?)", 1, "12345"); - execSQL("CREATE TABLE char_table(id INT PRIMARY KEY, str CHAR(5))"); + checkSQLResults("SELECT * FROM varchar_table WHERE id = 1", 1, "12345"); + + runSQL("CREATE TABLE decimal_table(id INT PRIMARY KEY, val DECIMAL(4, 2))" + mvccQry); + + execSQL("INSERT INTO decimal_table VALUES(?, ?)", 1, 12.34); + + checkSQLResults("SELECT * FROM decimal_table WHERE id = 1", 1, BigDecimal.valueOf(12.34)); + + runSQL("CREATE TABLE char_table(id INT PRIMARY KEY, str CHAR(5))" + mvccQry); execSQL("INSERT INTO char_table VALUES(?, ?)", 1, "12345"); + + checkSQLResults("SELECT * FROM char_table WHERE id = 1", 1, "12345"); + + runSQL("CREATE TABLE decimal_table_4(id INT PRIMARY KEY, field DECIMAL(4, 2))" + mvccQry); + + runSQL("CREATE TABLE char_table_2(id INT PRIMARY KEY, field INTEGER)" + mvccQry); + + runSQL("CREATE TABLE decimal_table_2(id INT PRIMARY KEY, field INTEGER)" + mvccQry); + + runSQL("CREATE TABLE char_table_3(id INT PRIMARY KEY, field CHAR(5), field2 INTEGER)" + mvccQry); + + runSQL("CREATE TABLE decimal_table_3(id INT PRIMARY KEY, field DECIMAL(4, 2), field2 INTEGER)" + mvccQry); + + runSQL("CREATE TABLE char_table_4(id INT PRIMARY KEY, field CHAR(5))" + mvccQry); + } + + /** + * @throws Exception If failed. + */ + public void testCreateTableWithTooLongCharDefault() throws Exception { + checkSQLThrows("CREATE TABLE too_long_default(id INT PRIMARY KEY, str CHAR(5) DEFAULT '123456')", + INTERNAL_ERROR); + } + + /** + * @throws Exception If failed. + */ + public void testCreateTableWithTooLongScaleDecimalDefault() throws Exception { + checkSQLThrows("CREATE TABLE too_long_decimal_default_scale(id INT PRIMARY KEY, val DECIMAL(4, 2)" + + " DEFAULT 1.345)", INTERNAL_ERROR); + } + + public void testCreateTableWithTooLongDecimalDefault() throws Exception { + checkSQLThrows("CREATE TABLE too_long_decimal_default(id INT PRIMARY KEY, val DECIMAL(4, 2)" + + " DEFAULT 123.45)", INTERNAL_ERROR); + } + + /** + * @throws Exception If failed. + */ + public void testInsertTooLongDecimal() throws Exception { + checkSQLThrows("INSERT INTO decimal_table VALUES(?, ?)", CONSTRAINT_VIOLATION, 2, 123.45); + + assertTrue(execSQL("SELECT * FROM decimal_table WHERE id = ?", 2).isEmpty()); + + checkSQLThrows("UPDATE decimal_table SET val = ? WHERE id = ?", CONSTRAINT_VIOLATION, 123.45, 1); + + checkSQLResults("SELECT * FROM decimal_table WHERE id = 1", 1, BigDecimal.valueOf(12.34)); + + checkSQLThrows("MERGE INTO decimal_table(id, val) VALUES(?, ?)", CONSTRAINT_VIOLATION, 1, 123.45); + + checkSQLResults("SELECT * FROM decimal_table WHERE id = 1", 1, BigDecimal.valueOf(12.34)); } /** * @throws Exception If failed. */ - public void testCreateTableWithTooLongDefault() throws Exception { - checkSQLThrows("CREATE TABLE too_long_default(id INT PRIMARY KEY, str CHAR(5) DEFAULT '123456')"); + public void testInsertTooLongScaleDecimal() throws Exception { + checkSQLThrows("INSERT INTO decimal_table VALUES(?, ?)", CONSTRAINT_VIOLATION, 3, 1.234); + + assertTrue(execSQL("SELECT * FROM decimal_table WHERE id = ?", 3).isEmpty()); + + checkSQLThrows("UPDATE decimal_table SET val = ? WHERE id = ?", CONSTRAINT_VIOLATION, 1.234, 1); + + checkSQLResults("SELECT * FROM decimal_table WHERE id = 1", 1, BigDecimal.valueOf(12.34)); + + checkSQLThrows("MERGE INTO decimal_table(id, val) VALUES(?, ?)", CONSTRAINT_VIOLATION, 1, 1.234); + + checkSQLResults("SELECT * FROM decimal_table WHERE id = 1", 1, BigDecimal.valueOf(12.34)); } /** * @throws Exception If failed. */ public void testInsertTooLongVarchar() throws Exception { - checkSQLThrows("INSERT INTO varchar_table VALUES(?, ?)", 2, "123456"); + checkSQLThrows("INSERT INTO varchar_table VALUES(?, ?)", CONSTRAINT_VIOLATION, 2, "123456"); + + assertTrue(execSQL("SELECT * FROM varchar_table WHERE id = ?", 2).isEmpty()); + + checkSQLThrows("UPDATE varchar_table SET str = ? WHERE id = ?", CONSTRAINT_VIOLATION, "123456", 1); + + checkSQLResults("SELECT * FROM varchar_table WHERE id = 1", 1, "12345"); - checkSQLThrows("UPDATE varchar_table SET str = ? WHERE id = ?", "123456", 1); + checkSQLThrows("MERGE INTO varchar_table(id, str) VALUES(?, ?)", CONSTRAINT_VIOLATION, 1, "123456"); - checkSQLThrows("MERGE INTO varchar_table(id, str) VALUES(?, ?)", 1, "123456"); + checkSQLResults("SELECT * FROM varchar_table WHERE id = 1", 1, "12345"); } /** * @throws Exception If failed. */ public void testInsertTooLongChar() throws Exception { - checkSQLThrows("INSERT INTO char_table VALUES(?, ?)", 2, "123456"); + checkSQLThrows("INSERT INTO char_table VALUES(?, ?)", CONSTRAINT_VIOLATION, 2, "123456"); + + assertTrue(execSQL("SELECT * FROM char_table WHERE id = ?", 2).isEmpty()); + + checkSQLThrows("UPDATE char_table SET str = ? WHERE id = ?", CONSTRAINT_VIOLATION, "123456", 1); + + checkSQLResults("SELECT * FROM char_table WHERE id = 1", 1, "12345"); - checkSQLThrows("UPDATE char_table SET str = ? WHERE id = ?", "123456", 1); + checkSQLThrows("MERGE INTO char_table(id, str) VALUES(?, ?)", CONSTRAINT_VIOLATION, 1, "123456"); - checkSQLThrows("MERGE INTO char_table(id, str) VALUES(?, ?)", 1, "123456"); + checkSQLResults("SELECT * FROM char_table WHERE id = 1", 1, "12345"); } /** * @throws Exception If failed. */ - public void testConstraintsAfterAlterTable() throws Exception { - execSQL("CREATE TABLE char_table_2(id INT PRIMARY KEY, field INTEGER)"); - + public void testCharConstraintsAfterAlterTable() throws Exception { execSQL("ALTER TABLE char_table_2 ADD COLUMN str CHAR(5) NOT NULL"); execSQL("INSERT INTO char_table_2(id, str) VALUES(?, ?)", 1, "1"); - checkSQLThrows("INSERT INTO char_table_2(id, str) VALUES(?, ?)", 2, "123456"); + checkSQLResults("SELECT * FROM char_table_2 WHERE id = 1", 1, null, "1"); + + checkSQLThrows("INSERT INTO char_table_2(id, str) VALUES(?, ?)", CONSTRAINT_VIOLATION, 2, "123456"); + + assertTrue(execSQL("SELECT * FROM decimal_table_2 WHERE id = ?", 2).isEmpty()); + + checkSQLThrows("UPDATE char_table_2 SET str = ? WHERE id = ?", CONSTRAINT_VIOLATION, "123456", 1); - checkSQLThrows("UPDATE char_table_2 SET str = ? WHERE id = ?", "123456", 1); + checkSQLResults("SELECT * FROM char_table_2 WHERE id = 1", 1, null, "1"); - checkSQLThrows("MERGE INTO char_table_2(id, str) VALUES(?, ?)", 1, "123456"); + checkSQLThrows("MERGE INTO char_table_2(id, str) VALUES(?, ?)", CONSTRAINT_VIOLATION, 1, "123456"); + + checkSQLResults("SELECT * FROM char_table_2 WHERE id = 1", 1, null, "1"); } /** * @throws Exception If failed. */ - public void testDropColumnWithConstraint() throws Exception { - execSQL("CREATE TABLE char_table_3(id INT PRIMARY KEY, field CHAR(5), field2 INTEGER)"); + public void testDecimalConstraintsAfterAlterTable() throws Exception { + execSQL("ALTER TABLE decimal_table_2 ADD COLUMN val DECIMAL(4, 2) NOT NULL"); + + execSQL("INSERT INTO decimal_table_2(id, val) VALUES(?, ?)", 1, 12.34); + + checkSQLResults("SELECT * FROM decimal_table_2 WHERE id = 1", 1, null, BigDecimal.valueOf(12.34)); + + checkSQLThrows("INSERT INTO decimal_table_2(id, val) VALUES(?, ?)", CONSTRAINT_VIOLATION, 2, 1234.56); + + assertTrue(execSQL("SELECT * FROM decimal_table_2 WHERE id = ?", 2).isEmpty()); + + checkSQLThrows("UPDATE decimal_table_2 SET val = ? WHERE id = ?", CONSTRAINT_VIOLATION, 1234.56, 1); + + checkSQLResults("SELECT * FROM decimal_table_2 WHERE id = 1", 1, null, BigDecimal.valueOf(12.34)); + + checkSQLThrows("MERGE INTO decimal_table_2(id, val) VALUES(?, ?)", CONSTRAINT_VIOLATION, 1, 12345.6); + + checkSQLResults("SELECT * FROM decimal_table_2 WHERE id = 1", 1, null, BigDecimal.valueOf(12.34)); + + checkSQLThrows("INSERT INTO decimal_table_2(id, val) VALUES(?, ?)", CONSTRAINT_VIOLATION, 3, 1.234); + + checkSQLResults("SELECT * FROM decimal_table_2 WHERE id = 1", 1, null, BigDecimal.valueOf(12.34)); + checkSQLThrows("UPDATE decimal_table_2 SET val = ? WHERE id = ?", CONSTRAINT_VIOLATION, 1.234, 1); + + checkSQLResults("SELECT * FROM decimal_table_2 WHERE id = 1", 1, null, BigDecimal.valueOf(12.34)); + + checkSQLThrows("MERGE INTO decimal_table_2(id, val) VALUES(?, ?)", CONSTRAINT_VIOLATION, 1, 1.234); + + checkSQLResults("SELECT * FROM decimal_table_2 WHERE id = 1", 1, null, BigDecimal.valueOf(12.34)); + } + + /** + * @throws Exception If failed. + */ + public void testCharDropColumnWithConstraint() throws Exception { execSQL("INSERT INTO char_table_3(id, field, field2) VALUES(?, ?, ?)", 1, "12345", 1); - checkSQLThrows("INSERT INTO char_table_3(id, field, field2) VALUES(?, ?, ?)", 2, "123456", 1); + checkSQLResults("SELECT * FROM char_table_3 WHERE id = 1", 1, "12345", 1); + + checkSQLThrows("INSERT INTO char_table_3(id, field, field2) VALUES(?, ?, ?)", CONSTRAINT_VIOLATION, + 2, "123456", 1); + + assertTrue(execSQL("SELECT * FROM decimal_table_3 WHERE id = ?", 2).isEmpty()); execSQL("ALTER TABLE char_table_3 DROP COLUMN field"); execSQL("INSERT INTO char_table_3(id, field2) VALUES(?, ?)", 3, 3); + + checkSQLResults("SELECT * FROM char_table_3 WHERE id = 3", 3, 3); } - public void testSqlState() throws Exception { - execSQL("CREATE TABLE char_table_4(id INT PRIMARY KEY, field CHAR(5))"); + /** + * @throws Exception If failed. + */ + public void testDecimalDropColumnWithConstraint() throws Exception { + execSQL("INSERT INTO decimal_table_3(id, field, field2) VALUES(?, ?, ?)", 1, 12.34, 1); + + checkSQLResults("SELECT * FROM decimal_table_3 WHERE id = 1", 1, BigDecimal.valueOf(12.34), 1); - IgniteSQLException err = (IgniteSQLException) - checkSQLThrows("INSERT INTO char_table_4(id, field) VALUES(?, ?)", 1, "123456"); + checkSQLThrows("INSERT INTO decimal_table_3(id, field, field2) VALUES(?, ?, ?)", CONSTRAINT_VIOLATION, + 2, 12.3456, 1); - assertEquals(err.sqlState(), CONSTRAINT_VIOLATION); + assertTrue(execSQL("SELECT * FROM decimal_table_3 WHERE id = ?", 2).isEmpty()); + + execSQL("ALTER TABLE decimal_table_3 DROP COLUMN field"); + + execSQL("INSERT INTO decimal_table_3(id, field2) VALUES(?, ?)", 3, 3); + + checkSQLResults("SELECT * FROM decimal_table_3 WHERE id = 3", 3, 3); + } + + /** + * @throws Exception If failed. + */ + public void testCharSqlState() throws Exception { + checkSQLThrows("INSERT INTO char_table_4(id, field) VALUES(?, ?)", CONSTRAINT_VIOLATION, 1, "123456"); + + assertTrue(execSQL("SELECT * FROM decimal_table_4 WHERE id = ?", 1).isEmpty()); execSQL("INSERT INTO char_table_4(id, field) VALUES(?, ?)", 2, "12345"); - err = (IgniteSQLException) - checkSQLThrows("UPDATE char_table_4 SET field = ? WHERE id = ?", "123456", 2); + checkSQLResults("SELECT * FROM char_table_4 WHERE id = 2", 2, "12345"); + + checkSQLThrows("UPDATE char_table_4 SET field = ? WHERE id = ?", CONSTRAINT_VIOLATION, "123456", 2); - assertEquals(err.sqlState(), CONSTRAINT_VIOLATION); + checkSQLResults("SELECT * FROM char_table_4 WHERE id = 2", 2, "12345"); - err = (IgniteSQLException) - checkSQLThrows("MERGE INTO char_table_4(id, field) VALUES(?, ?)", 2, "123456"); + checkSQLThrows("MERGE INTO char_table_4(id, field) VALUES(?, ?)", CONSTRAINT_VIOLATION, 2, "123456"); - assertEquals(err.sqlState(), CONSTRAINT_VIOLATION); + checkSQLResults("SELECT * FROM char_table_4 WHERE id = 2", 2, "12345"); + } + + /** + * @throws Exception If failed. + */ + public void testDecimalSqlState() throws Exception { + checkSQLThrows("INSERT INTO decimal_table_4 VALUES(?, ?)", CONSTRAINT_VIOLATION, + 1, BigDecimal.valueOf(1234.56)); + + assertTrue(execSQL("SELECT * FROM decimal_table_4 WHERE id = ?", 1).isEmpty()); + + checkSQLThrows("INSERT INTO decimal_table_4 VALUES(?, ?)", CONSTRAINT_VIOLATION, + 1, BigDecimal.valueOf(1.345)); + + assertTrue(execSQL("SELECT * FROM decimal_table_4 WHERE id = ?", 1).isEmpty()); + + execSQL("INSERT INTO decimal_table_4 (id, field) VALUES(?, ?)", 2, 12.34); + + checkSQLResults("SELECT * FROM decimal_table_4 WHERE id = 2", 2, BigDecimal.valueOf(12.34)); + + checkSQLThrows("UPDATE decimal_table_4 SET field = ? WHERE id = ?", CONSTRAINT_VIOLATION, + BigDecimal.valueOf(1234.56), 2); + + checkSQLResults("SELECT * FROM decimal_table_4 WHERE id = 2", 2, BigDecimal.valueOf(12.34)); + + checkSQLThrows("MERGE INTO decimal_table_4(id, field) VALUES(?, ?)", CONSTRAINT_VIOLATION, + 2, BigDecimal.valueOf(1234.56)); + + checkSQLResults("SELECT * FROM decimal_table_4 WHERE id = 2", 2, BigDecimal.valueOf(12.34)); + + checkSQLThrows("UPDATE decimal_table_4 SET field = ? WHERE id = ?", CONSTRAINT_VIOLATION, + BigDecimal.valueOf(1.345), 2); + + checkSQLResults("SELECT * FROM decimal_table_4 WHERE id = 2", 2, BigDecimal.valueOf(12.34)); + + checkSQLThrows("MERGE INTO decimal_table_4(id, field) VALUES(?, ?)", CONSTRAINT_VIOLATION, + 2, BigDecimal.valueOf(1.345)); + + checkSQLResults("SELECT * FROM decimal_table_4 WHERE id = 2", 2, BigDecimal.valueOf(12.34)); } /** */ - private Throwable checkSQLThrows(String sql, Object... args) { - return GridTestUtils.assertThrowsWithCause(() -> { + protected void checkSQLThrows(String sql, String sqlStateCode, Object... args) { + IgniteSQLException err = (IgniteSQLException)GridTestUtils.assertThrowsWithCause(() -> { execSQL(sql, args); return 0; }, IgniteSQLException.class); + + assertEquals(err.sqlState(), sqlStateCode); } /** */ - private List<?> execSQL(String sql, Object... args) { + protected List<?> execSQL(String sql, Object... args) { + return runSQL(sql, args); + } + + /** */ + protected List<?> runSQL(String sql, Object... args) { SqlFieldsQuery qry = new SqlFieldsQuery(sql) .setArgs(args); return grid(0).context().query().querySqlFields(qry, true).getAll(); } + + /** */ + protected void checkSQLResults(String sql, Object... args) { + List<?> rows = execSQL(sql); + + assertNotNull(rows); + + assertTrue(!rows.isEmpty()); + + assertEquals(rows.size(), 1); + + List<?> row = (List<?>)rows.get(0); + + assertEquals(row.size(), args.length); + + for (int i = 0; i < args.length; i++) + assertTrue(args[i] + " != " + row.get(i), Objects.equals(args[i], row.get(i))); + } + + /** */ + protected boolean mvccEnabled() { + return false; + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/66755c1a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteTransactionSQLColumnConstraintTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteTransactionSQLColumnConstraintTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteTransactionSQLColumnConstraintTest.java new file mode 100644 index 0000000..5239e1f --- /dev/null +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/sql/IgniteTransactionSQLColumnConstraintTest.java @@ -0,0 +1,71 @@ +/* + * 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.sql; + +import java.util.List; +import org.apache.ignite.internal.processors.query.IgniteSQLException; +import org.apache.ignite.testframework.GridTestUtils; + +/** + */ +public class IgniteTransactionSQLColumnConstraintTest extends IgniteSQLColumnConstraintsTest { + /** {@inheritDoc} */ + @Override protected void checkSQLThrows(String sql, String sqlStateCode, Object... args) { + runSQL("BEGIN TRANSACTION"); + + IgniteSQLException err = (IgniteSQLException)GridTestUtils.assertThrowsWithCause(() -> { + runSQL(sql, args); + + return 0; + }, IgniteSQLException.class); + + runSQL("ROLLBACK TRANSACTION"); + + assertEquals(err.sqlState(), sqlStateCode); + } + + /** {@inheritDoc} */ + @Override protected List<?> execSQL(String sql, Object... args) { + runSQL("BEGIN TRANSACTION"); + + List<?> res = runSQL(sql, args); + + runSQL("COMMIT TRANSACTION"); + + return res; + } + + /** + * That test is ignored due to drop column(s) operation is unsupported for the MVCC tables. + */ + @Override public void testCharDropColumnWithConstraint() { + // No-op. + } + + /** + * That test is ignored due to drop column(s) operation is unsupported for the MVCC tables. + */ + @Override public void testDecimalDropColumnWithConstraint() { + // No-op. + } + + /** {@inheritDoc} */ + @Override protected boolean mvccEnabled() { + return true; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/66755c1a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite.java ---------------------------------------------------------------------- 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 ee82b7a..2fe9323 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 @@ -209,9 +209,12 @@ import org.apache.ignite.internal.processors.query.h2.sql.H2CompareBigQueryTest; import org.apache.ignite.internal.processors.query.h2.twostep.InOperationExtractPartitionSelfTest; import org.apache.ignite.internal.processors.sql.IgniteCachePartitionedAtomicColumnConstraintsTest; import org.apache.ignite.internal.processors.sql.IgniteCachePartitionedTransactionalColumnConstraintsTest; +import org.apache.ignite.internal.processors.sql.IgniteCachePartitionedTransactionalSnapshotColumnConstraintTest; import org.apache.ignite.internal.processors.sql.IgniteCacheReplicatedAtomicColumnConstraintsTest; import org.apache.ignite.internal.processors.sql.IgniteCacheReplicatedTransactionalColumnConstraintsTest; +import org.apache.ignite.internal.processors.sql.IgniteCacheReplicatedTransactionalSnapshotColumnConstraintTest; import org.apache.ignite.internal.processors.sql.IgniteSQLColumnConstraintsTest; +import org.apache.ignite.internal.processors.sql.IgniteTransactionSQLColumnConstraintTest; import org.apache.ignite.internal.processors.sql.SqlConnectorConfigurationValidationSelfTest; import org.apache.ignite.internal.sql.SqlParserBulkLoadSelfTest; import org.apache.ignite.internal.sql.SqlParserCreateIndexSelfTest; @@ -475,11 +478,14 @@ public class IgniteBinaryCacheQueryTestSuite extends TestSuite { suite.addTestSuite(IgniteSqlDefaultValueTest.class); suite.addTestSuite(IgniteDecimalSelfTest.class); suite.addTestSuite(IgniteSQLColumnConstraintsTest.class); + suite.addTestSuite(IgniteTransactionSQLColumnConstraintTest.class); suite.addTestSuite(IgniteCachePartitionedAtomicColumnConstraintsTest.class); suite.addTestSuite(IgniteCachePartitionedTransactionalColumnConstraintsTest.class); + suite.addTestSuite(IgniteCachePartitionedTransactionalSnapshotColumnConstraintTest.class); suite.addTestSuite(IgniteCacheReplicatedAtomicColumnConstraintsTest.class); suite.addTestSuite(IgniteCacheReplicatedTransactionalColumnConstraintsTest.class); + suite.addTestSuite(IgniteCacheReplicatedTransactionalSnapshotColumnConstraintTest.class); // H2 Rows on-heap cache suite.addTestSuite(H2RowCacheSelfTest.class);
