IGNITE-5287: Simplified CacheConfiguration.sqlEscapeAll handling. This closes #2004.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/427ca690 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/427ca690 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/427ca690 Branch: refs/heads/ignite-5075 Commit: 427ca6900209421db7693df1dbf7e15fc872c0cd Parents: e09b5a2 Author: devozerov <[email protected]> Authored: Sat May 27 12:48:08 2017 +0300 Committer: devozerov <[email protected]> Committed: Sat May 27 12:48:08 2017 +0300 ---------------------------------------------------------------------- .../internal/jdbc2/JdbcNoDefaultCacheTest.java | 2 - .../configuration/CacheConfiguration.java | 11 + .../processors/cache/GridCacheProcessor.java | 16 +- .../processors/query/GridQueryIndexing.java | 9 +- .../processors/query/GridQueryProcessor.java | 21 +- .../query/GridQueryTypeDescriptor.java | 15 + .../internal/processors/query/QuerySchema.java | 2 +- .../query/QueryTypeDescriptorImpl.java | 9 + .../internal/processors/query/QueryUtils.java | 272 ++++++++++++++----- .../query/property/QueryBinaryProperty.java | 2 +- .../query/h2/H2IndexingAbstractGeoSelfTest.java | 26 +- .../query/h2/H2IndexingBinaryGeoSelfTest.java | 30 -- .../H2IndexingBinarySegmentedGeoSelfTest.java | 30 -- .../query/h2/H2IndexingGeoSelfTest.java | 2 +- .../h2/H2IndexingSegmentedGeoSelfTest.java | 2 +- .../testsuites/GeoSpatialIndexingTestSuite.java | 5 - .../processors/query/h2/H2RowDescriptor.java | 8 +- .../internal/processors/query/h2/H2Schema.java | 46 +++- .../processors/query/h2/H2TableDescriptor.java | 30 +- .../internal/processors/query/h2/H2Utils.java | 79 +----- .../processors/query/h2/IgniteH2Indexing.java | 74 ++--- .../processors/query/h2/opt/GridH2Table.java | 6 +- .../IgniteCacheInsertSqlQuerySelfTest.java | 27 +- .../cache/index/AbstractSchemaSelfTest.java | 123 +++++++-- .../DynamicIndexAbstractBasicSelfTest.java | 77 ++---- .../DynamicIndexAbstractConcurrentSelfTest.java | 28 +- .../index/DynamicIndexAbstractSelfTest.java | 30 +- .../index/H2DynamicIndexAbstractSelfTest.java | 48 ++-- .../cache/index/SchemaExchangeSelfTest.java | 13 +- .../query/IgniteSqlSchemaIndexingTest.java | 4 +- .../query/IgniteSqlSplitterSelfTest.java | 10 +- .../h2/GridIndexingSpiAbstractSelfTest.java | 10 + .../query/h2/sql/BaseH2CompareQueryTest.java | 12 +- .../query/h2/sql/H2CompareBigQueryTest.java | 2 +- .../processors/query/h2/sql/bigQuery.sql | 8 +- 35 files changed, 602 insertions(+), 487 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcNoDefaultCacheTest.java ---------------------------------------------------------------------- diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcNoDefaultCacheTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcNoDefaultCacheTest.java index b28f9dd..545286c 100644 --- a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcNoDefaultCacheTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcNoDefaultCacheTest.java @@ -19,7 +19,6 @@ package org.apache.ignite.internal.jdbc2; import java.sql.Connection; import java.sql.DriverManager; -import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.concurrent.Callable; @@ -33,7 +32,6 @@ import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; import org.apache.ignite.testframework.GridTestUtils; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import static org.apache.ignite.IgniteJdbcDriver.CFG_URL_PREFIX; http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java index 1136c71..7269086 100644 --- a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java +++ b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java @@ -1819,6 +1819,17 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> { } /** + * Clear query entities. + * + * @return {@code this} for chaining. + */ + public CacheConfiguration<K, V> clearQueryEntities() { + this.qryEntities = null; + + return this; + } + + /** * Defines a hint to query execution engine on desired degree of parallelism within a single node. * Query executor may or may not use this hint depending on estimated query costs. Query executor may define * certain restrictions on parallelism depending on query type and/or cache type. http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java index d94c41f..9a25672 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java @@ -45,6 +45,7 @@ import org.apache.ignite.IgniteSystemProperties; import org.apache.ignite.cache.CacheExistsException; import org.apache.ignite.cache.CacheMode; import org.apache.ignite.cache.CacheRebalanceMode; +import org.apache.ignite.cache.QueryEntity; import org.apache.ignite.cache.affinity.AffinityFunction; import org.apache.ignite.cache.affinity.AffinityFunctionContext; import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction; @@ -297,6 +298,17 @@ public class GridCacheProcessor extends GridProcessorAdapter { throw new IgniteCheckedException("Cannot set both cache writer factory and cache store factory " + "for cache: " + U.maskName(cfg.getName())); } + + Collection<QueryEntity> entities = cfg.getQueryEntities(); + + if (!F.isEmpty(entities)) { + Collection<QueryEntity> normalEntities = new ArrayList<>(entities.size()); + + for (QueryEntity entity : entities) + normalEntities.add(QueryUtils.normalizeQueryEntity(entity, cfg.isSqlEscapeAll())); + + cfg.clearQueryEntities().setQueryEntities(normalEntities); + } } /** @@ -503,8 +515,6 @@ public class GridCacheProcessor extends GridProcessorAdapter { if (cc.getEvictionPolicy() != null && !cc.isOnheapCacheEnabled()) throw new IgniteCheckedException("Onheap cache must be enabled if eviction policy is configured [cacheName=" + U.maskName(cc.getName()) + "]"); - - QueryUtils.validateCacheConfiguration(cc); } /** @@ -1361,8 +1371,6 @@ public class GridCacheProcessor extends GridProcessorAdapter { CacheStore cfgStore = cfg.getCacheStoreFactory() != null ? cfg.getCacheStoreFactory().create() : null; - QueryUtils.prepareCacheConfiguration(cfg); - validate(ctx.config(), cfg, desc.cacheType(), cfgStore); if (pluginMgr == null) http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java index 4b9c0e2..77c581c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryIndexing.java @@ -168,12 +168,13 @@ public interface GridQueryIndexing { * Registers cache. * * @param cacheName Cache name. + * @param schemaName Schema name. * @param cctx Cache context. * @param ccfg Cache configuration. * @throws IgniteCheckedException If failed. */ - public void registerCache(String cacheName, GridCacheContext<?,?> cctx, CacheConfiguration<?,?> ccfg) - throws IgniteCheckedException; + public void registerCache(String cacheName, String schemaName, GridCacheContext<?,?> cctx, + CacheConfiguration<?,?> ccfg) throws IgniteCheckedException; /** * Unregisters cache. @@ -207,14 +208,14 @@ public interface GridQueryIndexing { * the key should be removed from indexes other than one being updated. * * @param cacheName Cache name. - * @param typeName Type name. + * @param type Type descriptor. * @param key Key. * @param val Value. * @param ver Version. * @param expirationTime Expiration time or 0 if never expires. * @throws IgniteCheckedException If failed. */ - public void store(String cacheName, String typeName, KeyCacheObject key, int partId, CacheObject val, + public void store(String cacheName, GridQueryTypeDescriptor type, KeyCacheObject key, int partId, CacheObject val, GridCacheVersion ver, long expirationTime, long link) throws IgniteCheckedException; /** http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java index 09dbe42..3233fd2 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java @@ -668,8 +668,12 @@ public class GridQueryProcessor extends GridProcessorAdapter { try { synchronized (stateMux) { + boolean escape = cctx.config().isSqlEscapeAll(); + String cacheName = cctx.name(); + String schemaName = QueryUtils.normalizeSchemaName(cacheName, cctx.config().getSqlSchema(), escape); + // Prepare candidates. List<Class<?>> mustDeserializeClss = new ArrayList<>(); @@ -680,7 +684,7 @@ public class GridQueryProcessor extends GridProcessorAdapter { if (!F.isEmpty(qryEntities)) { for (QueryEntity qryEntity : qryEntities) { QueryTypeCandidate cand = QueryUtils.typeForQueryEntity(cacheName, cctx, qryEntity, - mustDeserializeClss); + mustDeserializeClss, escape); cands.add(cand); } @@ -755,7 +759,7 @@ public class GridQueryProcessor extends GridProcessorAdapter { } // Ready to register at this point. - registerCache0(cacheName, cctx, cands); + registerCache0(cacheName, schemaName, cctx, cands); // Warn about possible implicit deserialization. if (!mustDeserializeClss.isEmpty()) { @@ -978,7 +982,7 @@ public class GridQueryProcessor extends GridProcessorAdapter { Map<String, T2<QueryEntity, QueryIndex>> idxMap = new HashMap<>(); for (QueryEntity entity : schema.entities()) { - String tblName = QueryUtils.tableName(entity); + String tblName = entity.getTableName(); QueryEntity oldEntity = tblMap.put(tblName, entity); @@ -989,7 +993,7 @@ public class GridQueryProcessor extends GridProcessorAdapter { } for (QueryIndex entityIdx : entity.getIndexes()) { - String idxName = QueryUtils.indexName(entity, entityIdx); + String idxName = entityIdx.getName(); T2<QueryEntity, QueryIndex> oldIdxEntity = idxMap.put(idxName, new T2<>(entity, entityIdx)); @@ -1321,15 +1325,16 @@ public class GridQueryProcessor extends GridProcessorAdapter { * Register cache in indexing SPI. * * @param cacheName Cache name. + * @param schemaName Schema name. * @param cctx Cache context. * @param cands Candidates. * @throws IgniteCheckedException If failed. */ - private void registerCache0(String cacheName, GridCacheContext<?, ?> cctx, Collection<QueryTypeCandidate> cands) - throws IgniteCheckedException { + private void registerCache0(String cacheName, String schemaName, GridCacheContext<?, ?> cctx, + Collection<QueryTypeCandidate> cands) throws IgniteCheckedException { synchronized (stateMux) { if (idx != null) - idx.registerCache(cacheName, cctx, cctx.config()); + idx.registerCache(cacheName, schemaName, cctx, cctx.config()); try { for (QueryTypeCandidate cand : cands) { @@ -1596,7 +1601,7 @@ public class GridQueryProcessor extends GridProcessorAdapter { if (desc == null) return; - idx.store(cacheName, desc.name(), key, partId, val, ver, expirationTime, link); + idx.store(cacheName, desc, key, partId, val, ver, expirationTime, link); } finally { busyLock.leaveBusy(); http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java index 3c75ac4..c1a9e1e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java @@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.query; import java.util.Map; import org.apache.ignite.IgniteCheckedException; +import org.jetbrains.annotations.Nullable; /** * Value descriptor which allows to extract fields from value object of given type. @@ -145,4 +146,18 @@ public interface GridQueryTypeDescriptor { * @return value field name. */ public String valueFieldName(); + + /** + * Gets key field alias. + * + * @return Key field alias. + */ + @Nullable public String keyFieldAlias(); + + /** + * Gets value field alias. + * + * @return value field alias. + */ + @Nullable public String valueFieldAlias(); } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QuerySchema.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QuerySchema.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QuerySchema.java index b380131..34a4502 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QuerySchema.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QuerySchema.java @@ -93,7 +93,7 @@ public class QuerySchema implements Serializable { SchemaIndexCreateOperation op0 = (SchemaIndexCreateOperation)op; for (QueryEntity entity : entities) { - String tblName = QueryUtils.tableName(entity); + String tblName = entity.getTableName(); if (F.eq(tblName, op0.tableName())) { boolean exists = false; http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/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 4848b0a..c0da83f 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 @@ -447,4 +447,13 @@ public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor { @Override public String valueFieldName() { return valFieldName; } + + /** {@inheritDoc} */ + @Nullable @Override public String keyFieldAlias() { + return keyFieldName != null ? aliases.get(keyFieldName) : null; + } + + @Nullable @Override public String valueFieldAlias() { + return valFieldName != null ? aliases.get(valFieldName) : null; + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/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 245965c..c327820 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 @@ -18,6 +18,7 @@ package org.apache.ignite.internal.processors.query; import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteException; import org.apache.ignite.cache.QueryEntity; import org.apache.ignite.cache.QueryIndex; import org.apache.ignite.cache.QueryIndexType; @@ -45,10 +46,10 @@ import java.lang.reflect.Method; import java.math.BigDecimal; import java.sql.Time; import java.sql.Timestamp; -import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -64,13 +65,13 @@ import static org.apache.ignite.IgniteSystemProperties.getInteger; public class QueryUtils { /** Field name for key. */ - public static final String KEY_FIELD_NAME = "_key"; + public static final String KEY_FIELD_NAME = "_KEY"; /** Field name for value. */ - public static final String VAL_FIELD_NAME = "_val"; + public static final String VAL_FIELD_NAME = "_VAL"; /** Version field name. */ - public static final String VER_FIELD_NAME = "_ver"; + public static final String VER_FIELD_NAME = "_VER"; /** Discovery history size. */ private static final int DISCO_HIST_SIZE = getInteger(IGNITE_INDEXING_DISCOVERY_HISTORY_SIZE, 1000); @@ -106,8 +107,14 @@ public class QueryUtils { public static String tableName(QueryEntity entity) { String res = entity.getTableName(); - if (res == null) + if (res == null) { + String valTyp = entity.findValueType(); + + if (valTyp == null) + throw new IgniteException("Value type cannot be null or empty [queryEntity=" + entity + ']'); + res = typeName(entity.findValueType()); + } return res; } @@ -161,17 +168,172 @@ public class QueryUtils { } /** + * Normalize query entity. If "escape" flag is set, nothing changes. Otherwise we convert all object names to + * upper case and replace inner class separator characters ('$' for Java and '.' for .NET) with underscore. + * + * @param entity Query entity. + * @param escape Escape flag taken form configuration. + * @return Normalized query entity. + */ + public static QueryEntity normalizeQueryEntity(QueryEntity entity, boolean escape) { + if (escape) { + String tblName = tableName(entity); + + entity.setTableName(tblName); + + Map<String, String> aliases = new HashMap<>(entity.getAliases()); + + for (String fieldName : entity.getFields().keySet()) { + String fieldAlias = entity.getAliases().get(fieldName); + + if (fieldAlias == null) { + fieldAlias = aliasForFieldName(fieldName); + + aliases.put(fieldName, fieldAlias); + } + } + + entity.setAliases(aliases); + + for (QueryIndex idx : entity.getIndexes()) + idx.setName(indexName(tblName, idx)); + + validateQueryEntity(entity); + + return entity; + } + + QueryEntity normalEntity = new QueryEntity(); + + // Propagate plain properties. + normalEntity.setKeyType(entity.getKeyType()); + normalEntity.setValueType(entity.getValueType()); + normalEntity.setFields(entity.getFields()); + normalEntity.setKeyFields(entity.getKeyFields()); + normalEntity.setKeyFieldName(entity.getKeyFieldName()); + normalEntity.setValueFieldName(entity.getValueFieldName()); + + // Normalize table name. + String normalTblName = entity.getTableName(); + + if (normalTblName == null) + // Replace special characters for auto-generated table name. + normalTblName = normalizeObjectName(tableName(entity), true); + else + // No replaces for manually defined table. + normalTblName = normalizeObjectName(normalTblName, false); + + normalEntity.setTableName(normalTblName); + + // Normalize field names through aliases. + Map<String, String> normalAliases = new HashMap<>(normalEntity.getAliases()); + + for (String fieldName : normalEntity.getFields().keySet()) { + String fieldAlias = entity.getAliases().get(fieldName); + + if (fieldAlias == null) + fieldAlias = aliasForFieldName(fieldName); + + assert fieldAlias != null; + + normalAliases.put(fieldName, normalizeObjectName(fieldAlias, false)); + } + + normalEntity.setAliases(normalAliases); + + // Normalize indexes. + Collection<QueryIndex> normalIdxs = new LinkedList<>(); + + for (QueryIndex idx : entity.getIndexes()) { + QueryIndex normalIdx = new QueryIndex(); + + normalIdx.setFields(idx.getFields()); + normalIdx.setIndexType(idx.getIndexType()); + normalIdx.setInlineSize(idx.getInlineSize()); + + normalIdx.setName(normalizeObjectName(indexName(normalTblName, idx), false)); + + normalIdxs.add(normalIdx); + } + + normalEntity.setIndexes(normalIdxs); + + validateQueryEntity(normalEntity); + + return normalEntity; + } + + /** + * Stores rule for constructing schemaName according to cache configuration. + * + * @param cacheName Cache name. + * @param schemaName Schema name. + * @param escape Whether to perform escape. + * @return Proper schema name according to ANSI-99 standard. + */ + public static String normalizeSchemaName(String cacheName, @Nullable String schemaName, boolean escape) { + String res = schemaName; + + if (res == null) { + res = cacheName; + + // If schema name is not set explicitly, we will use escaped cache name. The reason is that cache name + // could contain weird characters, such as underscores, dots or non-Latin stuff, which are invalid from + // SQL synthax perspective. We do not want node to fail on startup due to this. + escape = true; + } + + if (!escape) + res = normalizeObjectName(res, false); + + return res; + } + + /** + * Get alias for the field name (i.e. last part of the property). + * + * @param fieldName Field name. + * @return Alias. + */ + private static String aliasForFieldName(String fieldName) { + int idx = fieldName.lastIndexOf('.'); + + if (idx >= 0) + fieldName = fieldName.substring(idx + 1); + + return fieldName; + } + + /** + * Normalize object name. + * + * @param str String. + * @param replace Whether to perform replace. + * @return Escaped string. + */ + public static @Nullable String normalizeObjectName(@Nullable String str, boolean replace) { + if (str == null) + return null; + + if (replace) + str = str.replace('.', '_').replace('$', '_'); + + return str.toUpperCase(); + } + + /** * Create type candidate for query entity. * * @param cacheName Cache name. * @param cctx Cache context. * @param qryEntity Query entity. * @param mustDeserializeClss Classes which must be deserialized. + * @param escape Escape flag. * @return Type candidate. * @throws IgniteCheckedException If failed. */ public static QueryTypeCandidate typeForQueryEntity(String cacheName, GridCacheContext cctx, QueryEntity qryEntity, - List<Class<?>> mustDeserializeClss) throws IgniteCheckedException { + List<Class<?>> mustDeserializeClss, boolean escape) throws IgniteCheckedException { GridKernalContext ctx = cctx.kernalContext(); CacheConfiguration<?,?> ccfg = cctx.config(); @@ -253,8 +415,12 @@ public class QueryUtils { // Need to setup affinity key for distributed joins. String affField = ctx.cacheObjects().affinityField(qryEntity.findKeyType()); - if (affField != null) + if (affField != null) { + if (!escape) + affField = normalizeObjectName(affField, false); + desc.affinityKey(affField); + } } } else { @@ -266,8 +432,12 @@ public class QueryUtils { String affField = ((GridCacheDefaultAffinityKeyMapper)keyMapper).affinityKeyPropertyName(desc.keyClass()); - if (affField != null) + if (affField != null) { + if (!escape) + affField = normalizeObjectName(affField, false); + desc.affinityKey(affField); + } } typeId = new QueryTypeIdKey(cacheName, valCls); @@ -836,76 +1006,48 @@ public class QueryUtils { } /** - * Prepare cache configuration. + * Validate query entity. * - * @param ccfg Cache configuration. + * @param entity Entity. */ - @SuppressWarnings("unchecked") - public static void prepareCacheConfiguration(CacheConfiguration ccfg) { - assert ccfg != null; - - Collection<QueryEntity> entities = ccfg.getQueryEntities(); - - if (!F.isEmpty(entities)) { - for (QueryEntity entity : entities) { - if (F.isEmpty(entity.findValueType())) - continue; - - Collection<QueryIndex> idxs = entity.getIndexes(); + private static void validateQueryEntity(QueryEntity entity) { + if (F.isEmpty(entity.findValueType())) + throw new IgniteException("Value type cannot be null or empty [queryEntity=" + entity + ']'); - if (!F.isEmpty(idxs)) { - for (QueryIndex idx : idxs) { - if (idx.getName() == null) { - String idxName = indexName(entity, idx); + String keyFieldName = entity.getKeyFieldName(); - idx.setName(idxName); - } - } - } - } + if (keyFieldName != null && !entity.getFields().containsKey(keyFieldName)) { + throw new IgniteException("Key field is not in the field list [queryEntity=" + entity + + ", keyFieldName=" + keyFieldName + "]"); } - } - /** - * Prepare cache configuration. - * - * @param ccfg Cache configuration. - * @throws IgniteCheckedException If failed. - */ - @SuppressWarnings("unchecked") - public static void validateCacheConfiguration(CacheConfiguration ccfg) throws IgniteCheckedException { - assert ccfg != null; - - Collection<QueryEntity> entities = ccfg.getQueryEntities(); + String valFieldName = entity.getValueFieldName(); - if (!F.isEmpty(entities)) { - for (QueryEntity entity : entities) { - if (F.isEmpty(entity.findValueType())) - throw new IgniteCheckedException("Value type cannot be null or empty [cacheName=" + - ccfg.getName() + ", queryEntity=" + entity + ']'); + if (valFieldName != null && !entity.getFields().containsKey(valFieldName)) { + throw new IgniteException("Value field is not in the field list [queryEntity=" + entity + + ", valFieldName=" + valFieldName + "]"); + } - Collection<QueryIndex> idxs = entity.getIndexes(); + Collection<QueryIndex> idxs = entity.getIndexes(); - if (!F.isEmpty(idxs)) { - Set<String> idxNames = new HashSet<>(); + if (!F.isEmpty(idxs)) { + Set<String> idxNames = new HashSet<>(); - for (QueryIndex idx : idxs) { - String idxName = idx.getName(); + for (QueryIndex idx : idxs) { + String idxName = idx.getName(); - if (idxName == null) - idxName = indexName(entity, idx); + if (idxName == null) + idxName = indexName(entity, idx); - assert !F.isEmpty(idxName); + assert !F.isEmpty(idxName); - if (!idxNames.add(idxName)) - throw new IgniteCheckedException("Duplicate index name [cacheName=" + ccfg.getName() + - ", queryEntity=" + entity + ", queryIdx=" + idx + ']'); + if (!idxNames.add(idxName)) + throw new IgniteException("Duplicate index name [queryEntity=" + entity + + ", queryIdx=" + idx + ']'); - if (idx.getIndexType() == null) - throw new IgniteCheckedException("Index type is not set [cacheName=" + ccfg.getName() + - ", queryEntity=" + entity + ", queryIdx=" + idx + ']'); - } - } + if (idx.getIndexType() == null) + throw new IgniteException("Index type is not set [queryEntity=" + entity + + ", queryIdx=" + idx + ']'); } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryBinaryProperty.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryBinaryProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryBinaryProperty.java index 3b42a78..d8b907e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryBinaryProperty.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/property/QueryBinaryProperty.java @@ -137,7 +137,7 @@ public class QueryBinaryProperty implements GridQueryProperty { else if (obj instanceof BinaryObjectBuilder) { BinaryObjectBuilder obj0 = (BinaryObjectBuilder)obj; - return obj0.getField(name()); + return obj0.getField(propName); } else throw new IgniteCheckedException("Unexpected binary object class [type=" + obj.getClass() + ']'); http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingAbstractGeoSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingAbstractGeoSelfTest.java b/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingAbstractGeoSelfTest.java index ddba4cc..7f135fd 100644 --- a/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingAbstractGeoSelfTest.java +++ b/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingAbstractGeoSelfTest.java @@ -30,9 +30,7 @@ import org.apache.ignite.cache.query.SqlFieldsQuery; import org.apache.ignite.cache.query.SqlQuery; import org.apache.ignite.cache.query.annotations.QuerySqlField; import org.apache.ignite.configuration.CacheConfiguration; -import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.internal.IgniteInternalFuture; -import org.apache.ignite.internal.binary.BinaryMarshaller; import org.apache.ignite.internal.processors.cache.GridCacheAbstractSelfTest; import org.apache.ignite.internal.processors.query.QueryUtils; import org.apache.ignite.internal.util.GridStringBuilder; @@ -74,20 +72,15 @@ public abstract class H2IndexingAbstractGeoSelfTest extends GridCacheAbstractSel /** */ private static final int QRY_PARALLELISM_LVL = 7; - /** Binary marshaller flag. */ - private final boolean binary; - /** Segmented index flag. */ private final boolean segmented; /** * Constructor. * - * @param binary Binary marshaller flag. * @param segmented Segmented index flag. */ - protected H2IndexingAbstractGeoSelfTest(boolean binary, boolean segmented) { - this.binary = binary; + protected H2IndexingAbstractGeoSelfTest(boolean segmented) { this.segmented = segmented; } @@ -101,16 +94,6 @@ public abstract class H2IndexingAbstractGeoSelfTest extends GridCacheAbstractSel return DUR * 3; } - /** {@inheritDoc} */ - @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { - IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); - - if (binary) - cfg.setMarshaller(new BinaryMarshaller()); - - return cfg; - } - /** * Create cache. * @@ -157,8 +140,11 @@ public abstract class H2IndexingAbstractGeoSelfTest extends GridCacheAbstractSel IgniteCache<K, V> cache = grid(0).getOrCreateCache(ccfg); // Process indexes dynamically. - for (QueryIndex idx : idxs) - createDynamicIndex(cache, entity, idx); + for (QueryIndex idx : idxs) { + QueryEntity normalEntity = QueryUtils.normalizeQueryEntity(entity, ccfg.isSqlEscapeAll()); + + createDynamicIndex(cache, normalEntity, idx); + } return cache; } http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingBinaryGeoSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingBinaryGeoSelfTest.java b/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingBinaryGeoSelfTest.java deleted file mode 100644 index eb3ec6e..0000000 --- a/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingBinaryGeoSelfTest.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ignite.internal.processors.query.h2; - -/** - * Geo-indexing test for binary mode. - */ -public class H2IndexingBinaryGeoSelfTest extends H2IndexingAbstractGeoSelfTest { - /** - * Constructor. - */ - public H2IndexingBinaryGeoSelfTest() { - super(true, false); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingBinarySegmentedGeoSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingBinarySegmentedGeoSelfTest.java b/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingBinarySegmentedGeoSelfTest.java deleted file mode 100644 index fe94a3d..0000000 --- a/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingBinarySegmentedGeoSelfTest.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ignite.internal.processors.query.h2; - -/** - * Geo-indexing test for binary mode and segmented cache. - */ -public class H2IndexingBinarySegmentedGeoSelfTest extends H2IndexingAbstractGeoSelfTest { - /** - * Constructor. - */ - public H2IndexingBinarySegmentedGeoSelfTest() { - super(true, true); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingGeoSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingGeoSelfTest.java b/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingGeoSelfTest.java index 280c946..be3f5cd 100644 --- a/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingGeoSelfTest.java +++ b/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingGeoSelfTest.java @@ -25,6 +25,6 @@ public class H2IndexingGeoSelfTest extends H2IndexingAbstractGeoSelfTest { * Constructor. */ public H2IndexingGeoSelfTest() { - super(false, false); + super(false); } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingSegmentedGeoSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingSegmentedGeoSelfTest.java b/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingSegmentedGeoSelfTest.java index b2cf781..97bfb88 100644 --- a/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingSegmentedGeoSelfTest.java +++ b/modules/geospatial/src/test/java/org/apache/ignite/internal/processors/query/h2/H2IndexingSegmentedGeoSelfTest.java @@ -25,6 +25,6 @@ public class H2IndexingSegmentedGeoSelfTest extends H2IndexingAbstractGeoSelfTes * Constructor. */ public H2IndexingSegmentedGeoSelfTest() { - super(false, true); + super(true); } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/geospatial/src/test/java/org/apache/ignite/testsuites/GeoSpatialIndexingTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/geospatial/src/test/java/org/apache/ignite/testsuites/GeoSpatialIndexingTestSuite.java b/modules/geospatial/src/test/java/org/apache/ignite/testsuites/GeoSpatialIndexingTestSuite.java index 2395b93..22109de 100644 --- a/modules/geospatial/src/test/java/org/apache/ignite/testsuites/GeoSpatialIndexingTestSuite.java +++ b/modules/geospatial/src/test/java/org/apache/ignite/testsuites/GeoSpatialIndexingTestSuite.java @@ -18,8 +18,6 @@ package org.apache.ignite.testsuites; import junit.framework.TestSuite; -import org.apache.ignite.internal.processors.query.h2.H2IndexingBinaryGeoSelfTest; -import org.apache.ignite.internal.processors.query.h2.H2IndexingBinarySegmentedGeoSelfTest; import org.apache.ignite.internal.processors.query.h2.H2IndexingGeoSelfTest; import org.apache.ignite.internal.processors.query.h2.H2IndexingSegmentedGeoSelfTest; @@ -37,9 +35,6 @@ public class GeoSpatialIndexingTestSuite extends TestSuite { suite.addTestSuite(H2IndexingGeoSelfTest.class); suite.addTestSuite(H2IndexingSegmentedGeoSelfTest.class); - suite.addTestSuite(H2IndexingBinaryGeoSelfTest.class); - suite.addTestSuite(H2IndexingBinarySegmentedGeoSelfTest.class); - return suite; } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowDescriptor.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowDescriptor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowDescriptor.java index 6f5ce3e..fbc9d6c 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowDescriptor.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowDescriptor.java @@ -154,8 +154,12 @@ public class H2RowDescriptor implements GridH2RowDescriptor { } final List<String> fieldsList = Arrays.asList(fields); - keyAliasColumnId = (type.keyFieldName() != null) ? DEFAULT_COLUMNS_COUNT + fieldsList.indexOf(type.keyFieldName()) : -1; - valueAliasColumnId = (type.valueFieldName() != null) ? DEFAULT_COLUMNS_COUNT + fieldsList.indexOf(type.valueFieldName()) : -1; + + keyAliasColumnId = + (type.keyFieldName() != null) ? DEFAULT_COLUMNS_COUNT + fieldsList.indexOf(type.keyFieldAlias()) : -1; + + valueAliasColumnId = + (type.valueFieldName() != null) ? DEFAULT_COLUMNS_COUNT + fieldsList.indexOf(type.valueFieldAlias()) : -1; // Index is not snapshotable in db-x. snapshotableIdx = false; http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Schema.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Schema.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Schema.java index 603a0c1..8dd87c0 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Schema.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Schema.java @@ -17,14 +17,13 @@ package org.apache.ignite.internal.processors.query.h2; -import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; import org.apache.ignite.internal.util.offheap.unsafe.GridUnsafeMemory; import org.h2.mvstore.cache.CacheLongKeyLIRS; import org.jsr166.ConcurrentHashMap8; -import java.util.Map; +import java.util.Collection; import java.util.concurrent.ConcurrentMap; /** @@ -43,27 +42,24 @@ public class H2Schema { /** */ private final ConcurrentMap<String, H2TableDescriptor> tbls = new ConcurrentHashMap8<>(); + /** */ + private final ConcurrentMap<String, H2TableDescriptor> typeToTbl = new ConcurrentHashMap8<>(); + /** Cache for deserialized offheap rows. */ private final CacheLongKeyLIRS<GridH2Row> rowCache; /** */ private final GridCacheContext<?, ?> cctx; - /** */ - private final CacheConfiguration<?, ?> ccfg; - /** * @param cacheName Cache name. * @param schemaName Schema name. * @param cctx Cache context. - * @param ccfg Cache configuration. */ - H2Schema(String cacheName, String schemaName, GridCacheContext<?, ?> cctx, - CacheConfiguration<?, ?> ccfg) { + public H2Schema(String cacheName, String schemaName, GridCacheContext<?, ?> cctx) { this.cacheName = cacheName; this.cctx = cctx; this.schemaName = schemaName; - this.ccfg = ccfg; rowCache = null; } @@ -106,23 +102,43 @@ public class H2Schema { /** * @return Tables. */ - public Map<String, H2TableDescriptor> tables() { - return tbls; + public Collection<H2TableDescriptor> tables() { + return tbls.values(); + } + + /** + * @param tblName Table name. + * @return Table. + */ + public H2TableDescriptor tableByName(String tblName) { + return tbls.get(tblName); + } + + /** + * @param typeName Type name. + * @return Table. + */ + public H2TableDescriptor tableByTypeName(String typeName) { + return typeToTbl.get(typeName); } /** * @param tbl Table descriptor. */ public void add(H2TableDescriptor tbl) { - if (tbls.putIfAbsent(tbl.typeName(), tbl) != null) + if (tbls.putIfAbsent(tbl.tableName(), tbl) != null) + throw new IllegalStateException("Table already registered: " + tbl.fullTableName()); + + if (typeToTbl.putIfAbsent(tbl.typeName(), tbl) != null) throw new IllegalStateException("Table already registered: " + tbl.fullTableName()); } /** - * @return Escape all. + * @param tbl Table descriptor. */ - public boolean escapeAll() { - return ccfg.isSqlEscapeAll(); + public void remove(H2TableDescriptor tbl) { + tbls.remove(tbl.tableName()); + typeToTbl.remove(tbl.typeName()); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java index a9548aa..2440788 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableDescriptor.java @@ -80,9 +80,7 @@ public class H2TableDescriptor implements GridH2SystemIndexFactory { this.type = type; this.schema = schema; - String tblName = H2Utils.escapeName(type.tableName(), schema.escapeAll()); - - fullTblName = schema.schemaName() + "." + tblName; + fullTblName = H2Utils.withQuotes(schema.schemaName()) + "." + H2Utils.withQuotes(type.tableName()); } /** @@ -121,6 +119,13 @@ public class H2TableDescriptor implements GridH2SystemIndexFactory { } /** + * @return Table name. + */ + String tableName() { + return type.tableName(); + } + + /** * @return Database full table name. */ String fullTableName() { @@ -232,10 +237,7 @@ public class H2TableDescriptor implements GridH2SystemIndexFactory { String firstField = idxDesc.fields().iterator().next(); - String firstFieldName = - schema.escapeAll() ? firstField : H2Utils.escapeName(firstField, false).toUpperCase(); - - Column col = tbl.getColumn(firstFieldName); + Column col = tbl.getColumn(firstField); IndexColumn idxCol = tbl.indexColumn(col.getColumnId(), idxDesc.descending(firstField) ? SortOrder.DESCENDING : SortOrder.ASCENDING); @@ -279,31 +281,27 @@ public class H2TableDescriptor implements GridH2SystemIndexFactory { * @return Index. */ public GridH2IndexBase createUserIndex(GridQueryIndexDescriptor idxDesc) { - String name = schema.escapeAll() ? idxDesc.name() : H2Utils.escapeName(idxDesc.name(), false).toUpperCase(); - IndexColumn keyCol = tbl.indexColumn(KEY_COL, SortOrder.ASCENDING); IndexColumn affCol = tbl.getAffinityKeyColumn(); List<IndexColumn> cols = new ArrayList<>(idxDesc.fields().size() + 2); - boolean escapeAll = schema.escapeAll(); - for (String field : idxDesc.fields()) { - String fieldName = escapeAll ? field : H2Utils.escapeName(field, false).toUpperCase(); - - Column col = tbl.getColumn(fieldName); + Column col = tbl.getColumn(field); cols.add(tbl.indexColumn(col.getColumnId(), idxDesc.descending(field) ? SortOrder.DESCENDING : SortOrder.ASCENDING)); } GridH2RowDescriptor desc = tbl.rowDescriptor(); + if (idxDesc.type() == QueryIndexType.SORTED) { cols = H2Utils.treeIndexColumns(desc, cols, keyCol, affCol); - return idx.createSortedIndex(schema, name, tbl, false, cols, idxDesc.inlineSize()); + + return idx.createSortedIndex(schema, idxDesc.name(), tbl, false, cols, idxDesc.inlineSize()); } else if (idxDesc.type() == QueryIndexType.GEOSPATIAL) { - return H2Utils.createSpatialIndex(tbl, name, cols.toArray(new IndexColumn[cols.size()])); + return H2Utils.createSpatialIndex(tbl, idxDesc.name(), cols.toArray(new IndexColumn[cols.size()])); } throw new IllegalStateException("Index type: " + idxDesc.type()); http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java index 75d739d..a4fdb53 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java @@ -18,7 +18,6 @@ package org.apache.ignite.internal.processors.query.h2; import org.apache.ignite.IgniteException; -import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata; import org.apache.ignite.internal.processors.query.h2.opt.GridH2IndexBase; import org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor; @@ -46,11 +45,8 @@ public class H2Utils { private static final String SPATIAL_IDX_CLS = "org.apache.ignite.internal.processors.query.h2.opt.GridH2SpatialIndex"; - /** */ - public static final char ESC_CH = '\"'; - - /** */ - private static final String ESC_STR = ESC_CH + "" + ESC_CH; + /** Quotation character. */ + private static final char ESC_CH = '\"'; /** * @param c1 First column. @@ -98,15 +94,14 @@ public class H2Utils { * @param ifNotExists Quietly skip index creation if it exists. * @return Statement string. */ - public static String indexCreateSql(String fullTblName, GridH2IndexBase h2Idx, boolean ifNotExists, - boolean escapeAll) { + public static String indexCreateSql(String fullTblName, GridH2IndexBase h2Idx, boolean ifNotExists) { boolean spatial = F.eq(SPATIAL_IDX_CLS, h2Idx.getClass().getName()); GridStringBuilder sb = new SB("CREATE ") .a(spatial ? "SPATIAL " : "") .a("INDEX ") .a(ifNotExists ? "IF NOT EXISTS " : "") - .a(escapeName(h2Idx.getName(), escapeAll)) + .a(withQuotes(h2Idx.getName())) .a(" ON ") .a(fullTblName) .a(" ("); @@ -119,7 +114,7 @@ public class H2Utils { else sb.a(", "); - sb.a("\"" + col.columnName + "\"").a(" ").a(col.sortType == SortOrder.ASCENDING ? "ASC" : "DESC"); + sb.a(withQuotes(col.columnName)).a(" ").a(col.sortType == SortOrder.ASCENDING ? "ASC" : "DESC"); } sb.a(')'); @@ -132,53 +127,10 @@ public class H2Utils { * @param schemaName <b>Quoted</b> schema name. * @param idxName Index name. * @param ifExists Quietly skip index drop if it exists. - * @param escapeAll Escape flag. * @return Statement string. */ - public static String indexDropSql(String schemaName, String idxName, boolean ifExists, boolean escapeAll) { - return "DROP INDEX " + (ifExists ? "IF EXISTS " : "") + schemaName + '.' + escapeName(idxName, escapeAll); - } - - /** - * Escapes name to be valid SQL identifier. Currently just replaces '.' and '$' sign with '_'. - * - * @param name Name. - * @param escapeAll Escape flag. - * @return Escaped name. - */ - public static String escapeName(String name, boolean escapeAll) { - if (name == null) // It is possible only for a cache name. - return ESC_STR; - - if (escapeAll) - return ESC_CH + name + ESC_CH; - - SB sb = null; - - for (int i = 0; i < name.length(); i++) { - char ch = name.charAt(i); - - if (!Character.isLetter(ch) && !Character.isDigit(ch) && ch != '_' && - !(ch == '"' && (i == 0 || i == name.length() - 1)) && ch != '-') { - // Class name can also contain '$' or '.' - these should be escaped. - assert ch == '$' || ch == '.'; - - if (sb == null) - sb = new SB(); - - sb.a(name.substring(sb.length(), i)); - - // Replace illegal chars with '_'. - sb.a('_'); - } - } - - if (sb == null) - return name; - - sb.a(name.substring(sb.length(), name.length())); - - return sb.toString(); + public static String indexDropSql(String schemaName, String idxName, boolean ifExists) { + return "DROP INDEX " + (ifExists ? "IF EXISTS " : "") + withQuotes(schemaName) + '.' + withQuotes(idxName); } /** @@ -231,20 +183,13 @@ public class H2Utils { } /** - * Stores rule for constructing schemaName according to cache configuration. + * Add quotes around the name. * - * @param ccfg Cache configuration. - * @return Proper schema name according to ANSI-99 standard. + * @param str String. + * @return String with quotes. */ - public static String schemaNameFromCacheConfiguration(CacheConfiguration<?, ?> ccfg) { - if (ccfg.getSqlSchema() == null) - return escapeName(ccfg.getName(), true); - - if (ccfg.getSqlSchema().charAt(0) == ESC_CH) - return ccfg.getSqlSchema(); - - return ccfg.isSqlEscapeAll() ? - escapeName(ccfg.getSqlSchema(), true) : ccfg.getSqlSchema().toUpperCase(); + public static String withQuotes(String str) { + return ESC_CH + str + ESC_CH; } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java index 8e6eeba..71d3ad5 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java @@ -450,7 +450,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { try { stmt = c.connection().createStatement(); - stmt.executeUpdate("SET SCHEMA " + schema); + stmt.executeUpdate("SET SCHEMA " + H2Utils.withQuotes(schema)); if (log.isDebugEnabled()) log.debug("Set schema: " + schema); @@ -476,7 +476,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { * @throws IgniteCheckedException If failed to create db schema. */ private void createSchema(String schema) throws IgniteCheckedException { - executeStatement("INFORMATION_SCHEMA", "CREATE SCHEMA IF NOT EXISTS " + schema); + executeStatement("INFORMATION_SCHEMA", "CREATE SCHEMA IF NOT EXISTS " + H2Utils.withQuotes(schema)); if (log.isDebugEnabled()) log.debug("Created H2 schema for index database: " + schema); @@ -489,7 +489,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { * @throws IgniteCheckedException If failed to create db schema. */ private void dropSchema(String schema) throws IgniteCheckedException { - executeStatement("INFORMATION_SCHEMA", "DROP SCHEMA IF EXISTS " + schema); + executeStatement("INFORMATION_SCHEMA", "DROP SCHEMA IF EXISTS " + H2Utils.withQuotes(schema)); if (log.isDebugEnabled()) log.debug("Dropped H2 schema for index database: " + schema); @@ -559,14 +559,14 @@ public class IgniteH2Indexing implements GridQueryIndexing { /** {@inheritDoc} */ @Override public void store(String cacheName, - String typeName, + GridQueryTypeDescriptor type, KeyCacheObject k, int partId, CacheObject v, GridCacheVersion ver, long expirationTime, long link) throws IgniteCheckedException { - H2TableDescriptor tbl = tableDescriptor(typeName, cacheName); + H2TableDescriptor tbl = tableDescriptor(type.name(), cacheName); if (tbl == null) return; // Type was rejected. @@ -664,7 +664,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { tbl.onDrop(); - tbl.schema().tables().remove(tbl.typeName()); + tbl.schema().remove(tbl); } /** @@ -682,7 +682,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { h2Tbl.proposeUserIndex(h2Idx); try { - String sql = H2Utils.indexCreateSql(desc.fullTableName(), h2Idx, false, desc.schema().escapeAll()); + String sql = H2Utils.indexCreateSql(desc.fullTableName(), h2Idx, false); executeSql(cacheName, sql); } @@ -703,7 +703,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { H2Schema schema = schemas.get(schemaName); - H2TableDescriptor desc = (schema != null ? schema.tables().get(tblName) : null); + H2TableDescriptor desc = (schema != null ? schema.tableByName(tblName) : null); if (desc == null) throw new IgniteCheckedException("Table not found in internal H2 database [schemaName=" + schemaName + @@ -738,7 +738,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { // At this point index is in consistent state, promote it through H2 SQL statement, so that cached // prepared statements are re-built. - String sql = H2Utils.indexCreateSql(desc.fullTableName(), h2Idx, ifNotExists, schema.escapeAll()); + String sql = H2Utils.indexCreateSql(desc.fullTableName(), h2Idx, ifNotExists); executeSql(cacheName, sql); } @@ -756,9 +756,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { throws IgniteCheckedException{ String schemaName = schema(cacheName); - H2Schema schema = schemas.get(schemaName); - - String sql = H2Utils.indexDropSql(schemaName, idxName, ifExists, schema.escapeAll()); + String sql = H2Utils.indexDropSql(schemaName, idxName, ifExists); executeSql(cacheName, sql); } @@ -1450,7 +1448,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { caches0.add(cctx.cacheId()); for (QueryTable table : twoStepQry.tables()) { - String tblCacheName = cacheNameForSchemaAndTable(table.schema(), table.table()); + String tblCacheName = cacheName(table.schema()); int cacheId = CU.cacheId(tblCacheName); @@ -1505,17 +1503,6 @@ public class IgniteH2Indexing implements GridQueryIndexing { } /** - * Get cache for schema and table. - * - * @param schemaName Schema name. - * @param tblName Table name. - * @return Cache name. - */ - private String cacheNameForSchemaAndTable(String schemaName, String tblName) { - return cacheName(schemaName); - } - - /** * @throws IllegalStateException if segmented indices used with non-segmented indices. */ private void checkCacheIndexSegmentation(List<Integer> cacheIds) { @@ -1661,16 +1648,6 @@ public class IgniteH2Indexing implements GridQueryIndexing { name.equalsIgnoreCase(VER_FIELD_NAME)) throw new IgniteCheckedException(MessageFormat.format(ptrn, name)); } - - if (type.keyFieldName() != null && !type.fields().containsKey(type.keyFieldName())) { - throw new IgniteCheckedException(MessageFormat.format("Name ''{0}'' must be amongst fields since it " + - "is configured as ''keyFieldName'' [type=" + type.name() + "]", type.keyFieldName())); - } - - if (type.valueFieldName() != null && !type.fields().containsKey(type.valueFieldName())) { - throw new IgniteCheckedException(MessageFormat.format("Name ''{0}'' must be amongst fields since it " + - "is configured as ''valueFieldName'' [type=" + type.name() + "]", type.valueFieldName())); - } } /** @@ -1688,8 +1665,6 @@ public class IgniteH2Indexing implements GridQueryIndexing { assert schema != null; assert tbl != null; - boolean escapeAll = schema.escapeAll(); - String keyType = dbTypeFromClass(tbl.type().keyClass()); String valTypeStr = dbTypeFromClass(tbl.type().valueClass()); @@ -1704,7 +1679,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { sql.a(',').a(VER_FIELD_NAME).a(" OTHER INVISIBLE"); for (Map.Entry<String, Class<?>> e : tbl.type().fields().entrySet()) - sql.a(',').a(H2Utils.escapeName(e.getKey(), escapeAll)).a(' ').a(dbTypeFromClass(e.getValue())); + sql.a(',').a(H2Utils.withQuotes(e.getKey())).a(' ').a(dbTypeFromClass(e.getValue())); sql.a(')'); @@ -1797,7 +1772,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { if (schema == null) return null; - return schema.tables().get(type); + return schema.tableByTypeName(type); } /** @@ -1838,12 +1813,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { H2Schema schema = schemas.get(schemaName); - // For the compatibility with conversion from """" to "" inside h2 lib - if (schema == null) { - assert schemaName.isEmpty() || schemaName.charAt(0) != H2Utils.ESC_CH; - - schema = schemas.get(H2Utils.escapeName(schemaName, true)); - } + assert schema != null; return schema.cacheName(); } @@ -2248,18 +2218,16 @@ public class IgniteH2Indexing implements GridQueryIndexing { } /** {@inheritDoc} */ - @Override public void registerCache(String cacheName, GridCacheContext<?, ?> cctx, CacheConfiguration<?, ?> ccfg) - throws IgniteCheckedException { - String schema = H2Utils.schemaNameFromCacheConfiguration(ccfg); - - if (schemas.putIfAbsent(schema, new H2Schema(cacheName, schema, cctx, ccfg)) != null) + @Override public void registerCache(String cacheName, String schemaName, GridCacheContext<?, ?> cctx, + CacheConfiguration<?, ?> ccfg) throws IgniteCheckedException { + if (schemas.putIfAbsent(schemaName, new H2Schema(cacheName, schemaName, cctx)) != null) throw new IgniteCheckedException("Cache already registered: " + U.maskName(cacheName)); - cacheName2schema.put(cacheName, schema); + cacheName2schema.put(cacheName, schemaName); - createSchema(schema); + createSchema(schemaName); - createSqlFunctions(schema, ccfg.getSqlFunctionClasses()); + createSqlFunctions(schemaName, ccfg.getSqlFunctionClasses()); } /** {@inheritDoc} */ @@ -2281,7 +2249,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { U.error(log, "Failed to drop schema on cache stop (will ignore): " + cacheName, e); } - for (H2TableDescriptor tblDesc : rmv.tables().values()) + for (H2TableDescriptor tblDesc : rmv.tables()) for (Index idx : tblDesc.table().getIndexes()) idx.close(null); http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java index cb9042e..a85cd93 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java @@ -138,10 +138,8 @@ public class GridH2Table extends TableBase { int affKeyColId = -1; if (affKey != null) { - String colName = desc.context().config().isSqlEscapeAll() ? affKey : affKey.toUpperCase(); - - if (doesColumnExist(colName)) - affKeyColId = getColumn(colName).getColumnId(); + if (doesColumnExist(affKey)) + affKeyColId = getColumn(affKey).getColumnId(); else affinityColExists = false; } http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java index 6bbd7e1..579432f 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java @@ -30,6 +30,8 @@ import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder; import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; import org.apache.ignite.testframework.GridTestUtils; +import static org.apache.ignite.internal.processors.cache.IgniteCacheUpdateSqlQuerySelfTest.*; + /** * */ @@ -187,15 +189,20 @@ public class IgniteCacheInsertSqlQuerySelfTest extends IgniteCacheAbstractInsert * */ public void testNestedFieldsHandling() { - IgniteCache<Integer, IgniteCacheUpdateSqlQuerySelfTest.AllTypes> p = ignite(0).cache("I2AT"); + IgniteCache<Integer, AllTypes> p = ignite(0).cache("I2AT"); - p.query(new SqlFieldsQuery("insert into AllTypes(_key, innerTypeCol, arrListCol, _val, innerStrCol) " + - "values (1, ?, ?, ?, 'sss')") .setArgs(new IgniteCacheUpdateSqlQuerySelfTest.AllTypes.InnerType(50L), - new ArrayList<>(Arrays.asList(3L, 2L, 1L)), new IgniteCacheUpdateSqlQuerySelfTest.AllTypes(1L))); + p.query(new SqlFieldsQuery( + "insert into AllTypes(_key, innerTypeCol, arrListCol, _val, innerStrCol) values (1, ?, ?, ?, 'sss')"). + setArgs( + new AllTypes.InnerType(50L), + new ArrayList<>(Arrays.asList(3L, 2L, 1L)), + new AllTypes(1L) + ) + ); - IgniteCacheUpdateSqlQuerySelfTest.AllTypes res = p.get(1); + AllTypes res = p.get(1); - IgniteCacheUpdateSqlQuerySelfTest.AllTypes.InnerType resInner = new IgniteCacheUpdateSqlQuerySelfTest.AllTypes.InnerType(50L); + AllTypes.InnerType resInner = new AllTypes.InnerType(50L); resInner.innerStrCol = "sss"; resInner.arrListCol = new ArrayList<>(Arrays.asList(3L, 2L, 1L)); @@ -208,17 +215,17 @@ public class IgniteCacheInsertSqlQuerySelfTest extends IgniteCacheAbstractInsert IgniteCache<Integer, IgniteCacheUpdateSqlQuerySelfTest.AllTypes> p = ignite(0).cache("I2AT"); p.query(new SqlFieldsQuery("insert into AllTypes(_key, _val) values (1, ?)") - .setArgs(new IgniteCacheUpdateSqlQuerySelfTest.AllTypes(1L))); + .setArgs(new AllTypes(1L))); p.destroy(); p = ignite(0).getOrCreateCache(cacheConfig("I2AT", true, false, Integer.class, - IgniteCacheUpdateSqlQuerySelfTest.AllTypes.class)); + AllTypes.class)); p.query(new SqlFieldsQuery("insert into AllTypes(_key, _val, dateCol) values (1, ?, null)") - .setArgs(new IgniteCacheUpdateSqlQuerySelfTest.AllTypes(1L))); + .setArgs(new AllTypes(1L))); - IgniteCacheUpdateSqlQuerySelfTest.AllTypes exp = new IgniteCacheUpdateSqlQuerySelfTest.AllTypes(1L); + AllTypes exp = new AllTypes(1L); exp.dateCol = null; http://git-wip-us.apache.org/repos/asf/ignite/blob/427ca690/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/AbstractSchemaSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/AbstractSchemaSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/AbstractSchemaSelfTest.java index 1f50244..91ae2f7 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/AbstractSchemaSelfTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/AbstractSchemaSelfTest.java @@ -22,6 +22,7 @@ import org.apache.ignite.Ignition; import org.apache.ignite.cache.QueryEntity; import org.apache.ignite.cache.QueryIndex; import org.apache.ignite.cache.QueryIndexType; +import org.apache.ignite.cache.query.SqlFieldsQuery; import org.apache.ignite.cache.query.annotations.QuerySqlField; import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.internal.IgniteEx; @@ -33,7 +34,9 @@ import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor; import org.apache.ignite.internal.processors.query.QueryIndexDescriptorImpl; import org.apache.ignite.internal.processors.query.QueryTypeDescriptorImpl; import org.apache.ignite.internal.processors.query.QueryUtils; +import org.apache.ignite.internal.util.GridStringBuilder; import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.internal.util.typedef.internal.SB; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteBiTuple; import org.apache.ignite.lang.IgnitePredicate; @@ -58,32 +61,38 @@ public class AbstractSchemaSelfTest extends GridCommonAbstractTest { /** Table name. */ protected static final String TBL_NAME = tableName(ValueClass.class); - /** Table name 2. */ - protected static final String TBL_NAME_2 = tableName(ValueClass2.class); + /** Escaped table name. */ + protected static final String TBL_NAME_ESCAPED = typeName(ValueClass.class); /** Index name 1. */ - protected static final String IDX_NAME_1 = "idx_1"; + protected static final String IDX_NAME_1 = "IDX_1"; + + /** Index name 1 escaped. */ + protected static final String IDX_NAME_1_ESCAPED = "idx_1"; /** Index name 2. */ - protected static final String IDX_NAME_2 = "idx_2"; + protected static final String IDX_NAME_2 = "IDX_2"; - /** Index name 3. */ - protected static final String IDX_NAME_3 = "idx_3"; + /** Index name 2 escaped. */ + protected static final String IDX_NAME_2_ESCAPED = "idx_2"; /** Key ID field. */ protected static final String FIELD_KEY = "id"; - /** Field 1. */ - protected static final String FIELD_NAME_1 = "field1"; + /** Key alias */ + protected static final String FIELD_KEY_ALIAS = "key"; /** Field 1. */ - protected static final String FIELD_NAME_2 = "field2"; + protected static final String FIELD_NAME_1 = "FIELD1"; - /** Field 3. */ - protected static final String FIELD_NAME_3 = "field3"; + /** Field 1 escaped. */ + protected static final String FIELD_NAME_1_ESCAPED = "field1"; - /** Key alias */ - protected static final String FIELD_KEY_ALIAS = "key"; + /** Field 2. */ + protected static final String FIELD_NAME_2 = "FIELD2"; + + /** Field 2 escaped. */ + protected static final String FIELD_NAME_2_ESCAPED = "field2"; /** * Get type on the given node for the given cache and table name. Type must exist. @@ -205,7 +214,7 @@ public class AbstractSchemaSelfTest extends GridCommonAbstractTest { assert desc != null; for (QueryEntity entity : desc.schema().entities()) { - if (F.eq(tblName, QueryUtils.tableName(entity))) { + if (F.eq(tblName, entity.getTableName())) { for (QueryIndex idx : entity.getIndexes()) { if (F.eq(QueryUtils.indexName(entity, idx), idxName)) { LinkedHashMap<String, Boolean> idxFields = idx.getFields(); @@ -215,7 +224,7 @@ public class AbstractSchemaSelfTest extends GridCommonAbstractTest { int i = 0; for (String idxField : idxFields.keySet()) { - assertEquals(idxField, fields[i].get1()); + assertEquals(idxField.toLowerCase(), fields[i].get1().toLowerCase()); assertEquals(idxFields.get(idxField), fields[i].get2()); i++; @@ -256,8 +265,8 @@ public class AbstractSchemaSelfTest extends GridCommonAbstractTest { String expFieldName = fields[i].get1(); boolean expFieldAsc = fields[i].get2(); - assertEquals("Index field mismatch [pos=" + i + ", expField=" + expFieldName + - ", actualField=" + fieldNames.get(i) + ']', expFieldName, fieldNames.get(i)); + assertEquals("Index field mismatch [pos=" + i + ", expField=" + expFieldName + ", actualField=" + + fieldNames.get(i) + ']', expFieldName.toLowerCase(), fieldNames.get(i).toLowerCase()); boolean fieldAsc = !idxDesc.descending(expFieldName); @@ -275,7 +284,7 @@ public class AbstractSchemaSelfTest extends GridCommonAbstractTest { */ protected static void assertNoIndex(String cacheName, String tblName, String idxName) { for (Ignite node : Ignition.allGrids()) - assertNoIndex((IgniteEx)node, cacheName, tblName, idxName); + assertNoIndex(node, cacheName, tblName, idxName); } /** @@ -367,11 +376,21 @@ public class AbstractSchemaSelfTest extends GridCommonAbstractTest { * @param cls Class. * @return Table name. */ - protected static String tableName(Class cls) { + protected static String typeName(Class cls) { return cls.getSimpleName(); } /** + * Get table name for class. + * + * @param cls Class. + * @return Table name. + */ + protected static String tableName(Class cls) { + return QueryUtils.normalizeObjectName(typeName(cls), true); + } + + /** * Convenient method for index creation. * * @param name Name. @@ -433,6 +452,72 @@ public class AbstractSchemaSelfTest extends GridCommonAbstractTest { } /** + * Synchronously create index. + * + * @param node Ignite node. + * @param cacheName Cache name. + * @param tblName Table name. + * @param idx Index. + * @param ifNotExists When set to true operation will fail if index already exists. + * @throws Exception If failed. + */ + protected void dynamicIndexCreate(Ignite node, String cacheName, String tblName, QueryIndex idx, boolean ifNotExists) + throws Exception { + GridStringBuilder sql = new SB("CREATE INDEX ") + .a(ifNotExists ? "IF NOT EXISTS " : "") + .a(idx.getName()) + .a(" ON ") + .a(tblName) + .a(" ("); + + boolean first = true; + + for (Map.Entry<String, Boolean> fieldEntry : idx.getFields().entrySet()) { + if (first) + first = false; + else + sql.a(", "); + + String name = fieldEntry.getKey(); + boolean asc = fieldEntry.getValue(); + + sql.a(name).a(" ").a(asc ? "ASC" : "DESC"); + } + + sql.a(')'); + + executeSql(node, cacheName, sql.toString()); + } + + /** + * Synchronously drop index. + * + * @param node Ignite node. + * @param cacheName Cache name. + * @param idxName Index name. + * @param ifExists When set to true operation fill fail if index doesn't exists. + * @throws Exception if failed. + */ + protected void dynamicIndexDrop(Ignite node, String cacheName, String idxName, boolean ifExists) throws Exception { + String sql = "DROP INDEX " + (ifExists ? "IF EXISTS " : "") + idxName; + + executeSql(node, cacheName, sql); + } + + /** + * Execute SQL. + * + * @param node Ignite node. + * @param cacheName Cache name. + * @param sql SQL. + */ + private void executeSql(Ignite node, String cacheName, String sql) { + log.info("Executing DDL: " + sql); + + node.cache(cacheName).query(new SqlFieldsQuery(sql)).getAll(); + } + + /** * Key class. */ public static class KeyClass {
