You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/03/10 08:59:55 UTC

[3/4] ignite git commit: IGNITE-4807: Moved type descriptor and index descriptor to top-level.

IGNITE-4807: Moved type descriptor and index descriptor to top-level.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/5899cc3e
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/5899cc3e
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/5899cc3e

Branch: refs/heads/ignite-4705-2
Commit: 5899cc3e61e56fb34a8e8dba51295c55e5385da2
Parents: 9e4c2cf
Author: devozerov <vo...@gridgain.com>
Authored: Thu Mar 9 16:58:44 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Thu Mar 9 16:58:44 2017 +0300

----------------------------------------------------------------------
 .../processors/query/GridQueryProcessor.java    | 443 ++-----------------
 .../query/QueryIndexDescriptorImpl.java         | 102 +++++
 .../query/QueryTypeDescriptorImpl.java          | 337 ++++++++++++++
 3 files changed, 470 insertions(+), 412 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/5899cc3e/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 b35a506..1c5b822 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
@@ -27,15 +27,12 @@ import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.TreeSet;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ExecutorService;
@@ -83,12 +80,8 @@ import org.apache.ignite.internal.util.future.GridFinishedFuture;
 import org.apache.ignite.internal.util.lang.GridCloseableIterator;
 import org.apache.ignite.internal.util.lang.GridClosureException;
 import org.apache.ignite.internal.util.lang.IgniteOutClosureX;
-import org.apache.ignite.internal.util.tostring.GridToStringExclude;
-import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.internal.A;
-import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.internal.util.worker.GridWorker;
 import org.apache.ignite.internal.util.worker.GridWorkerFuture;
@@ -140,10 +133,10 @@ public class GridQueryProcessor extends GridProcessorAdapter {
     private final GridSpinBusyLock busyLock = new GridSpinBusyLock();
 
     /** Type descriptors. */
-    private final Map<QueryTypeIdKey, TypeDescriptor> types = new ConcurrentHashMap8<>();
+    private final Map<QueryTypeIdKey, QueryTypeDescriptorImpl> types = new ConcurrentHashMap8<>();
 
     /** Type descriptors. */
-    private final ConcurrentMap<QueryTypeNameKey, TypeDescriptor> typesByName = new ConcurrentHashMap8<>();
+    private final ConcurrentMap<QueryTypeNameKey, QueryTypeDescriptorImpl> typesByName = new ConcurrentHashMap8<>();
 
     /** */
     private ExecutorService execSvc;
@@ -231,7 +224,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
                     if (F.isEmpty(qryEntity.getValueType()))
                         throw new IgniteCheckedException("Value type is not set: " + qryEntity);
 
-                    TypeDescriptor desc = new TypeDescriptor();
+                    QueryTypeDescriptorImpl desc = new QueryTypeDescriptorImpl();
 
                     // Key and value classes still can be available if they are primitive or JDK part.
                     // We need that to set correct types for _key and _val columns.
@@ -318,7 +311,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
 
                         if (keyMapper instanceof GridCacheDefaultAffinityKeyMapper) {
                             String affField =
-                                ((GridCacheDefaultAffinityKeyMapper)keyMapper).affinityKeyPropertyName(desc.keyCls);
+                                ((GridCacheDefaultAffinityKeyMapper)keyMapper).affinityKeyPropertyName(desc.keyClass());
 
                             if (affField != null)
                                 desc.affinityKey(affField);
@@ -347,7 +340,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
                         meta.getDescendingFields().isEmpty() && meta.getGroups().isEmpty())
                         continue;
 
-                    TypeDescriptor desc = new TypeDescriptor();
+                    QueryTypeDescriptorImpl desc = new QueryTypeDescriptorImpl();
 
                     // Key and value classes still can be available if they are primitive or JDK part.
                     // We need that to set correct types for _key and _val columns.
@@ -468,7 +461,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
      * @param desc Type descriptor.
      * @throws IgniteCheckedException If failed.
      */
-    private void addTypeByName(CacheConfiguration<?, ?> ccfg, TypeDescriptor desc) throws IgniteCheckedException {
+    private void addTypeByName(CacheConfiguration<?, ?> ccfg, QueryTypeDescriptorImpl desc) throws IgniteCheckedException {
         if (typesByName.putIfAbsent(new QueryTypeNameKey(ccfg.getName(), desc.name()), desc) != null)
             throw new IgniteCheckedException("Type with name '" + desc.name() + "' already indexed " +
                 "in cache '" + ccfg.getName() + "'.");
@@ -542,10 +535,10 @@ public class GridQueryProcessor extends GridProcessorAdapter {
         try {
             idx.unregisterCache(cctx.config());
 
-            Iterator<Map.Entry<QueryTypeIdKey, TypeDescriptor>> it = types.entrySet().iterator();
+            Iterator<Map.Entry<QueryTypeIdKey, QueryTypeDescriptorImpl>> it = types.entrySet().iterator();
 
             while (it.hasNext()) {
-                Map.Entry<QueryTypeIdKey, TypeDescriptor> entry = it.next();
+                Map.Entry<QueryTypeIdKey, QueryTypeDescriptorImpl> entry = it.next();
 
                 if (F.eq(cctx.name(), entry.getKey().space())) {
                     it.remove();
@@ -591,7 +584,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
      * @param desc Type descriptor.
      * @return Future that will be completed when rebuilding of all indexes is finished.
      */
-    private IgniteInternalFuture<?> rebuildIndexes(@Nullable final String space, @Nullable final TypeDescriptor desc) {
+    private IgniteInternalFuture<?> rebuildIndexes(@Nullable final String space, @Nullable final QueryTypeDescriptorImpl desc) {
         if (idx == null)
             return new GridFinishedFuture<>(new IgniteCheckedException("Indexing is disabled."));
 
@@ -641,7 +634,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
         try {
             GridCompoundFuture<?, ?> fut = new GridCompoundFuture<Object, Object>();
 
-            for (Map.Entry<QueryTypeIdKey, TypeDescriptor> e : types.entrySet())
+            for (Map.Entry<QueryTypeIdKey, QueryTypeDescriptorImpl> e : types.entrySet())
                 fut.add((IgniteInternalFuture)rebuildIndexes(e.getKey().space(), e.getValue()));
 
             fut.markInitialized();
@@ -709,7 +702,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
                 id = new QueryTypeIdKey(space, valCls);
             }
 
-            TypeDescriptor desc = types.get(id);
+            QueryTypeDescriptorImpl desc = types.get(id);
 
             if (desc == null || !desc.registered())
                 return;
@@ -774,7 +767,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
 
             return executeQuery(GridCacheQueryType.SQL_FIELDS, clause, cctx, new IgniteOutClosureX<GridCloseableIterator<IgniteBiTuple<K, V>>>() {
                 @Override public GridCloseableIterator<IgniteBiTuple<K, V>> applyx() throws IgniteCheckedException {
-                    TypeDescriptor type = typesByName.get(new QueryTypeNameKey(space, resType));
+                    QueryTypeDescriptorImpl type = typesByName.get(new QueryTypeNameKey(space, resType));
 
                     if (type == null || !type.registered())
                         throw new CacheException("Failed to find SQL table for type: " + resType);
@@ -863,7 +856,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
                         String sqlQry = qry.getSql();
                         Object[] params = qry.getArgs();
 
-                        TypeDescriptor typeDesc = typesByName.get(
+                        QueryTypeDescriptorImpl typeDesc = typesByName.get(
                             new QueryTypeNameKey(
                                 space,
                                 type));
@@ -1165,7 +1158,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
             return executeQuery(GridCacheQueryType.TEXT, clause, cctx,
                 new IgniteOutClosureX<GridCloseableIterator<IgniteBiTuple<K, V>>>() {
                     @Override public GridCloseableIterator<IgniteBiTuple<K, V>> applyx() throws IgniteCheckedException {
-                        TypeDescriptor type = typesByName.get(new QueryTypeNameKey(space, resType));
+                        QueryTypeDescriptorImpl type = typesByName.get(new QueryTypeNameKey(space, resType));
 
                         if (type == null || !type.registered())
                             throw new CacheException("Failed to find SQL table for type: " + resType);
@@ -1255,17 +1248,18 @@ public class GridQueryProcessor extends GridProcessorAdapter {
             throw new IllegalStateException("Failed to process undeploy event (grid is stopping).");
 
         try {
-            Iterator<Map.Entry<QueryTypeIdKey, TypeDescriptor>> it = types.entrySet().iterator();
+            Iterator<Map.Entry<QueryTypeIdKey, QueryTypeDescriptorImpl>> it = types.entrySet().iterator();
 
             while (it.hasNext()) {
-                Map.Entry<QueryTypeIdKey, TypeDescriptor> e = it.next();
+                Map.Entry<QueryTypeIdKey, QueryTypeDescriptorImpl> e = it.next();
 
                 if (!F.eq(e.getKey().space(), space))
                     continue;
 
-                TypeDescriptor desc = e.getValue();
+                QueryTypeDescriptorImpl desc = e.getValue();
 
-                if (ldr.equals(U.detectClassLoader(desc.valCls)) || ldr.equals(U.detectClassLoader(desc.keyCls))) {
+                if (ldr.equals(U.detectClassLoader(desc.valueClass())) ||
+                    ldr.equals(U.detectClassLoader(desc.keyClass()))) {
                     idx.unregisterType(e.getKey().space(), desc);
 
                     it.remove();
@@ -1285,7 +1279,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
      * @param coCtx Cache object context.
      * @throws IgniteCheckedException If failed.
      */
-    private void processClassMeta(CacheTypeMetadata meta, TypeDescriptor d, CacheObjectContext coCtx)
+    private void processClassMeta(CacheTypeMetadata meta, QueryTypeDescriptorImpl d, CacheObjectContext coCtx)
         throws IgniteCheckedException {
         Map<String,String> aliases = meta.getAliases();
 
@@ -1357,7 +1351,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
      * @throws IgniteCheckedException If failed.
      */
     private void addToIndex(
-        TypeDescriptor d,
+        QueryTypeDescriptorImpl d,
         Class<?> keyCls,
         Class<?> valCls,
         String pathStr,
@@ -1411,7 +1405,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
      * @param d Type descriptor.
      * @throws IgniteCheckedException If failed.
      */
-    private void processBinaryMeta(CacheTypeMetadata meta, TypeDescriptor d)
+    private void processBinaryMeta(CacheTypeMetadata meta, QueryTypeDescriptorImpl d)
         throws IgniteCheckedException {
         Map<String,String> aliases = meta.getAliases();
 
@@ -1478,7 +1472,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
         for (Map.Entry<String, Class<?>> entry : meta.getQueryFields().entrySet()) {
             QueryBinaryProperty prop = buildBinaryProperty(entry.getKey(), entry.getValue(), aliases, null);
 
-            if (!d.props.containsKey(prop.name()))
+            if (!d.properties().containsKey(prop.name()))
                 d.addProperty(prop, false);
         }
     }
@@ -1490,7 +1484,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
      * @param d Type descriptor.
      * @throws IgniteCheckedException If failed.
      */
-    private void processBinaryMeta(QueryEntity qryEntity, TypeDescriptor d) throws IgniteCheckedException {
+    private void processBinaryMeta(QueryEntity qryEntity, QueryTypeDescriptorImpl d) throws IgniteCheckedException {
         Map<String,String> aliases = qryEntity.getAliases();
 
         if (aliases == null)
@@ -1523,8 +1517,8 @@ public class GridQueryProcessor extends GridProcessorAdapter {
             else
                 isKeyField = (hasKeyFields ? keyFields.contains(entry.getKey()) : null);
 
-            QueryBinaryProperty prop = buildBinaryProperty(entry.getKey(), U.classForName(entry.getValue(), Object.class, true),
-                aliases, isKeyField);
+            QueryBinaryProperty prop = buildBinaryProperty(entry.getKey(),
+                U.classForName(entry.getValue(), Object.class, true), aliases, isKeyField);
 
             d.addProperty(prop, false);
         }
@@ -1541,7 +1535,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
      */
     private void processClassMeta(
         QueryEntity qryEntity,
-        TypeDescriptor d,
+        QueryTypeDescriptorImpl d,
         CacheObjectContext coCtx
     ) throws IgniteCheckedException {
         Map<String,String> aliases = qryEntity.getAliases();
@@ -1571,7 +1565,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
      * @param d Type descriptor to populate.
      * @throws IgniteCheckedException If failed to build index information.
      */
-    private void processIndexes(QueryEntity qryEntity, TypeDescriptor d) throws IgniteCheckedException {
+    private void processIndexes(QueryEntity qryEntity, QueryTypeDescriptorImpl d) throws IgniteCheckedException {
         if (!F.isEmpty(qryEntity.getIndexes())) {
             Map<String, String> aliases = qryEntity.getAliases();
 
@@ -1740,8 +1734,8 @@ public class GridQueryProcessor extends GridProcessorAdapter {
         Collection<GridQueryTypeDescriptor> spaceTypes = new ArrayList<>(
             Math.min(10, types.size()));
 
-        for (Map.Entry<QueryTypeIdKey, TypeDescriptor> e : types.entrySet()) {
-            TypeDescriptor desc = e.getValue();
+        for (Map.Entry<QueryTypeIdKey, QueryTypeDescriptorImpl> e : types.entrySet()) {
+            QueryTypeDescriptorImpl desc = e.getValue();
 
             if (desc.registered() && F.eq(e.getKey().space(), space))
                 spaceTypes.add(desc);
@@ -1759,7 +1753,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
      * @throws IgniteCheckedException If failed.
      */
     public GridQueryTypeDescriptor type(@Nullable String space, String typeName) throws IgniteCheckedException {
-        TypeDescriptor type = typesByName.get(new QueryTypeNameKey(space, typeName));
+        QueryTypeDescriptorImpl type = typesByName.get(new QueryTypeNameKey(space, typeName));
 
         if (type == null || !type.registered())
             throw new IgniteCheckedException("Failed to find type descriptor for type name: " + typeName);
@@ -1936,380 +1930,6 @@ public class GridQueryProcessor extends GridProcessorAdapter {
     }
 
     /**
-     * Descriptor of type.
-     */
-    private static class TypeDescriptor implements GridQueryTypeDescriptor {
-        /** */
-        private String name;
-
-        /** */
-        private String tblName;
-
-        /** Value field names and types with preserved order. */
-        @GridToStringInclude
-        private final Map<String, Class<?>> fields = new LinkedHashMap<>();
-
-        /** */
-        @GridToStringExclude
-        private final Map<String, GridQueryProperty> props = new HashMap<>();
-
-        /** Map with upper cased property names to help find properties based on SQL INSERT and MERGE queries. */
-        private final Map<String, GridQueryProperty> uppercaseProps = new HashMap<>();
-
-        /** */
-        @GridToStringInclude
-        private final Map<String, IndexDescriptor> indexes = new HashMap<>();
-
-        /** */
-        private IndexDescriptor fullTextIdx;
-
-        /** */
-        private Class<?> keyCls;
-
-        /** */
-        private Class<?> valCls;
-
-        /** */
-        private String keyTypeName;
-
-        /** */
-        private String valTypeName;
-
-        /** */
-        private boolean valTextIdx;
-
-        /** */
-        private String affKey;
-
-        /** SPI can decide not to register this type. */
-        private boolean registered;
-
-        /**
-         * @return {@code True} if type registration in SPI was finished and type was not rejected.
-         */
-        boolean registered() {
-            return registered;
-        }
-
-        /**
-         * @param registered Sets registered flag.
-         */
-        void registered(boolean registered) {
-            this.registered = registered;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String name() {
-            return name;
-        }
-
-        /**
-         * Sets type name.
-         *
-         * @param name Name.
-         */
-        void name(String name) {
-            this.name = name;
-        }
-
-        /**
-         * Gets table name for type.
-         * @return Table name.
-         */
-        public String tableName() {
-            return tblName;
-        }
-
-        /**
-         * Sets table name for type.
-         *
-         * @param tblName Table name.
-         */
-        public void tableName(String tblName) {
-            this.tblName = tblName;
-        }
-
-        /** {@inheritDoc} */
-        @Override public Map<String, Class<?>> fields() {
-            return fields;
-        }
-
-        /** {@inheritDoc} */
-        @Override public GridQueryProperty property(String name) {
-            GridQueryProperty res = props.get(name);
-
-            if (res == null)
-                res = uppercaseProps.get(name.toUpperCase());
-
-            return res;
-        }
-
-        /** {@inheritDoc} */
-        @SuppressWarnings("unchecked")
-        @Override public <T> T value(String field, Object key, Object val) throws IgniteCheckedException {
-            assert field != null;
-
-            GridQueryProperty prop = property(field);
-
-            if (prop == null)
-                throw new IgniteCheckedException("Failed to find field '" + field + "' in type '" + name + "'.");
-
-            return (T)prop.value(key, val);
-        }
-
-        /** {@inheritDoc} */
-        @SuppressWarnings("unchecked")
-        @Override public void setValue(String field, Object key, Object val, Object propVal)
-            throws IgniteCheckedException {
-            assert field != null;
-
-            GridQueryProperty prop = property(field);
-
-            if (prop == null)
-                throw new IgniteCheckedException("Failed to find field '" + field + "' in type '" + name + "'.");
-
-            prop.setValue(key, val, propVal);
-        }
-
-        /** {@inheritDoc} */
-        @Override public Map<String, GridQueryIndexDescriptor> indexes() {
-            return Collections.<String, GridQueryIndexDescriptor>unmodifiableMap(indexes);
-        }
-
-        /**
-         * Adds index.
-         *
-         * @param idxName Index name.
-         * @param type Index type.
-         * @return Index descriptor.
-         * @throws IgniteCheckedException In case of error.
-         */
-        public IndexDescriptor addIndex(String idxName, QueryIndexType type) throws IgniteCheckedException {
-            IndexDescriptor idx = new IndexDescriptor(type);
-
-            if (indexes.put(idxName, idx) != null)
-                throw new IgniteCheckedException("Index with name '" + idxName + "' already exists.");
-
-            return idx;
-        }
-
-        /**
-         * Adds field to index.
-         *
-         * @param idxName Index name.
-         * @param field Field name.
-         * @param orderNum Fields order number in index.
-         * @param descending Sorting order.
-         * @throws IgniteCheckedException If failed.
-         */
-        public void addFieldToIndex(String idxName, String field, int orderNum,
-            boolean descending) throws IgniteCheckedException {
-            IndexDescriptor desc = indexes.get(idxName);
-
-            if (desc == null)
-                desc = addIndex(idxName, QueryIndexType.SORTED);
-
-            desc.addField(field, orderNum, descending);
-        }
-
-        /**
-         * Adds field to text index.
-         *
-         * @param field Field name.
-         */
-        public void addFieldToTextIndex(String field) {
-            if (fullTextIdx == null) {
-                fullTextIdx = new IndexDescriptor(QueryIndexType.FULLTEXT);
-
-                indexes.put(null, fullTextIdx);
-            }
-
-            fullTextIdx.addField(field, 0, false);
-        }
-
-        /** {@inheritDoc} */
-        @Override public Class<?> valueClass() {
-            return valCls;
-        }
-
-        /**
-         * Sets value class.
-         *
-         * @param valCls Value class.
-         */
-        void valueClass(Class<?> valCls) {
-            A.notNull(valCls, "Value class must not be null");
-            this.valCls = valCls;
-        }
-
-        /** {@inheritDoc} */
-        @Override public Class<?> keyClass() {
-            return keyCls;
-        }
-
-        /**
-         * Set key class.
-         *
-         * @param keyCls Key class.
-         */
-        void keyClass(Class<?> keyCls) {
-            this.keyCls = keyCls;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String keyTypeName() {
-            return keyTypeName;
-        }
-
-        /**
-         * Set key type name.
-         *
-         * @param keyTypeName Key type name.
-         */
-        public void keyTypeName(String keyTypeName) {
-            this.keyTypeName = keyTypeName;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String valueTypeName() {
-            return valTypeName;
-        }
-
-        /**
-         * Set value type name.
-         *
-         * @param valTypeName Value type name.
-         */
-        public void valueTypeName(String valTypeName) {
-            this.valTypeName = valTypeName;
-        }
-
-        /**
-         * Adds property to the type descriptor.
-         *
-         * @param prop Property.
-         * @param failOnDuplicate Fail on duplicate flag.
-         * @throws IgniteCheckedException In case of error.
-         */
-        public void addProperty(GridQueryProperty prop, boolean failOnDuplicate) throws IgniteCheckedException {
-            String name = prop.name();
-
-            if (props.put(name, prop) != null && failOnDuplicate)
-                throw new IgniteCheckedException("Property with name '" + name + "' already exists.");
-
-            if (uppercaseProps.put(name.toUpperCase(), prop) != null && failOnDuplicate)
-                throw new IgniteCheckedException("Property with upper cased name '" + name + "' already exists.");
-
-            fields.put(name, prop.type());
-        }
-
-        /** {@inheritDoc} */
-        @Override public boolean valueTextIndex() {
-            return valTextIdx;
-        }
-
-        /**
-         * Sets if this value should be text indexed.
-         *
-         * @param valTextIdx Flag value.
-         */
-        public void valueTextIndex(boolean valTextIdx) {
-            this.valTextIdx = valTextIdx;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String affinityKey() {
-            return affKey;
-        }
-
-        /**
-         * @param affKey Affinity key field.
-         */
-        void affinityKey(String affKey) {
-            this.affKey = affKey;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String toString() {
-            return S.toString(TypeDescriptor.class, this);
-        }
-    }
-
-    /**
-     * Index descriptor.
-     */
-    private static class IndexDescriptor implements GridQueryIndexDescriptor {
-        /** Fields sorted by order number. */
-        private final Collection<T2<String, Integer>> fields = new TreeSet<>(
-            new Comparator<T2<String, Integer>>() {
-                @Override public int compare(T2<String, Integer> o1, T2<String, Integer> o2) {
-                    if (o1.get2().equals(o2.get2())) // Order is equal, compare field names to avoid replace in Set.
-                        return o1.get1().compareTo(o2.get1());
-
-                    return o1.get2() < o2.get2() ? -1 : 1;
-                }
-            });
-
-        /** Fields which should be indexed in descending order. */
-        private Collection<String> descendings;
-
-        /** */
-        private final QueryIndexType type;
-
-        /**
-         * @param type Type.
-         */
-        private IndexDescriptor(QueryIndexType type) {
-            assert type != null;
-
-            this.type = type;
-        }
-
-        /** {@inheritDoc} */
-        @Override public Collection<String> fields() {
-            Collection<String> res = new ArrayList<>(fields.size());
-
-            for (T2<String, Integer> t : fields)
-                res.add(t.get1());
-
-            return res;
-        }
-
-        /** {@inheritDoc} */
-        @Override public boolean descending(String field) {
-            return descendings != null && descendings.contains(field);
-        }
-
-        /**
-         * Adds field to this index.
-         *
-         * @param field Field name.
-         * @param orderNum Field order number in this index.
-         * @param descending Sort order.
-         */
-        public void addField(String field, int orderNum, boolean descending) {
-            fields.add(new T2<>(field, orderNum));
-
-            if (descending) {
-                if (descendings == null)
-                    descendings  = new HashSet<>();
-
-                descendings.add(field);
-            }
-        }
-
-        /** {@inheritDoc} */
-        @Override public QueryIndexType type() {
-            return type;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String toString() {
-            return S.toString(IndexDescriptor.class, this);
-        }
-    }
-
-    /**
      * The way to index.
      */
     private enum IndexType {
@@ -2322,5 +1942,4 @@ public class GridQueryProcessor extends GridProcessorAdapter {
         /** Text index. */
         TEXT
     }
-
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5899cc3e/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryIndexDescriptorImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryIndexDescriptorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryIndexDescriptorImpl.java
new file mode 100644
index 0000000..53a0dfe
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryIndexDescriptorImpl.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.query;
+
+import org.apache.ignite.cache.QueryIndexType;
+import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.TreeSet;
+
+/**
+ * Index descriptor.
+ */
+public class QueryIndexDescriptorImpl implements GridQueryIndexDescriptor {
+    /** Fields sorted by order number. */
+    private final Collection<T2<String, Integer>> fields = new TreeSet<>(
+        new Comparator<T2<String, Integer>>() {
+            @Override public int compare(T2<String, Integer> o1, T2<String, Integer> o2) {
+                if (o1.get2().equals(o2.get2())) // Order is equal, compare field names to avoid replace in Set.
+                    return o1.get1().compareTo(o2.get1());
+
+                return o1.get2() < o2.get2() ? -1 : 1;
+            }
+        });
+
+    /** Fields which should be indexed in descending order. */
+    private Collection<String> descendings;
+
+    /** */
+    private final QueryIndexType type;
+
+    /**
+     * @param type Type.
+     */
+    public QueryIndexDescriptorImpl(QueryIndexType type) {
+        assert type != null;
+
+        this.type = type;
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<String> fields() {
+        Collection<String> res = new ArrayList<>(fields.size());
+
+        for (T2<String, Integer> t : fields)
+            res.add(t.get1());
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean descending(String field) {
+        return descendings != null && descendings.contains(field);
+    }
+
+    /**
+     * Adds field to this index.
+     *
+     * @param field Field name.
+     * @param orderNum Field order number in this index.
+     * @param descending Sort order.
+     */
+    public void addField(String field, int orderNum, boolean descending) {
+        fields.add(new T2<>(field, orderNum));
+
+        if (descending) {
+            if (descendings == null)
+                descendings  = new HashSet<>();
+
+            descendings.add(field);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public QueryIndexType type() {
+        return type;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(QueryIndexDescriptorImpl.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5899cc3e/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
new file mode 100644
index 0000000..f22cc11
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java
@@ -0,0 +1,337 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.query;
+
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.cache.QueryIndexType;
+import org.apache.ignite.internal.util.tostring.GridToStringExclude;
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.internal.A;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Descriptor of type.
+ */
+public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor {
+    /** */
+    private String name;
+
+    /** */
+    private String tblName;
+
+    /** Value field names and types with preserved order. */
+    @GridToStringInclude
+    private final Map<String, Class<?>> fields = new LinkedHashMap<>();
+
+    /** */
+    @GridToStringExclude
+    private final Map<String, GridQueryProperty> props = new HashMap<>();
+
+    /** Map with upper cased property names to help find properties based on SQL INSERT and MERGE queries. */
+    private final Map<String, GridQueryProperty> uppercaseProps = new HashMap<>();
+
+    /** */
+    @GridToStringInclude
+    private final Map<String, QueryIndexDescriptorImpl> indexes = new HashMap<>();
+
+    /** */
+    private QueryIndexDescriptorImpl fullTextIdx;
+
+    /** */
+    private Class<?> keyCls;
+
+    /** */
+    private Class<?> valCls;
+
+    /** */
+    private String keyTypeName;
+
+    /** */
+    private String valTypeName;
+
+    /** */
+    private boolean valTextIdx;
+
+    /** */
+    private String affKey;
+
+    /** SPI can decide not to register this type. */
+    private boolean registered;
+
+    /**
+     * @return {@code True} if type registration in SPI was finished and type was not rejected.
+     */
+    public boolean registered() {
+        return registered;
+    }
+
+    /**
+     * @param registered Sets registered flag.
+     */
+    public void registered(boolean registered) {
+        this.registered = registered;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String name() {
+        return name;
+    }
+
+    /**
+     * Sets type name.
+     *
+     * @param name Name.
+     */
+    public void name(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Gets table name for type.
+     * @return Table name.
+     */
+    public String tableName() {
+        return tblName;
+    }
+
+    /**
+     * Sets table name for type.
+     *
+     * @param tblName Table name.
+     */
+    public void tableName(String tblName) {
+        this.tblName = tblName;
+    }
+
+    /** {@inheritDoc} */
+    @Override public Map<String, Class<?>> fields() {
+        return fields;
+    }
+
+    /** {@inheritDoc} */
+    @Override public GridQueryProperty property(String name) {
+        GridQueryProperty res = props.get(name);
+
+        if (res == null)
+            res = uppercaseProps.get(name.toUpperCase());
+
+        return res;
+    }
+
+    /**
+     * @return Properties.
+     */
+    public Map<String, GridQueryProperty> properties() {
+        return props;
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override public <T> T value(String field, Object key, Object val) throws IgniteCheckedException {
+        assert field != null;
+
+        GridQueryProperty prop = property(field);
+
+        if (prop == null)
+            throw new IgniteCheckedException("Failed to find field '" + field + "' in type '" + name + "'.");
+
+        return (T)prop.value(key, val);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override public void setValue(String field, Object key, Object val, Object propVal)
+        throws IgniteCheckedException {
+        assert field != null;
+
+        GridQueryProperty prop = property(field);
+
+        if (prop == null)
+            throw new IgniteCheckedException("Failed to find field '" + field + "' in type '" + name + "'.");
+
+        prop.setValue(key, val, propVal);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Map<String, GridQueryIndexDescriptor> indexes() {
+        return Collections.<String, GridQueryIndexDescriptor>unmodifiableMap(indexes);
+    }
+
+    /**
+     * Adds index.
+     *
+     * @param idxName Index name.
+     * @param type Index type.
+     * @return Index descriptor.
+     * @throws IgniteCheckedException In case of error.
+     */
+    public QueryIndexDescriptorImpl addIndex(String idxName, QueryIndexType type) throws IgniteCheckedException {
+        QueryIndexDescriptorImpl idx = new QueryIndexDescriptorImpl(type);
+
+        if (indexes.put(idxName, idx) != null)
+            throw new IgniteCheckedException("Index with name '" + idxName + "' already exists.");
+
+        return idx;
+    }
+
+    /**
+     * Adds field to index.
+     *
+     * @param idxName Index name.
+     * @param field Field name.
+     * @param orderNum Fields order number in index.
+     * @param descending Sorting order.
+     * @throws IgniteCheckedException If failed.
+     */
+    public void addFieldToIndex(String idxName, String field, int orderNum,
+        boolean descending) throws IgniteCheckedException {
+        QueryIndexDescriptorImpl desc = indexes.get(idxName);
+
+        if (desc == null)
+            desc = addIndex(idxName, QueryIndexType.SORTED);
+
+        desc.addField(field, orderNum, descending);
+    }
+
+    /**
+     * Adds field to text index.
+     *
+     * @param field Field name.
+     */
+    public void addFieldToTextIndex(String field) {
+        if (fullTextIdx == null) {
+            fullTextIdx = new QueryIndexDescriptorImpl(QueryIndexType.FULLTEXT);
+
+            indexes.put(null, fullTextIdx);
+        }
+
+        fullTextIdx.addField(field, 0, false);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Class<?> valueClass() {
+        return valCls;
+    }
+
+    /**
+     * Sets value class.
+     *
+     * @param valCls Value class.
+     */
+    public void valueClass(Class<?> valCls) {
+        A.notNull(valCls, "Value class must not be null");
+        this.valCls = valCls;
+    }
+
+    /** {@inheritDoc} */
+    @Override public Class<?> keyClass() {
+        return keyCls;
+    }
+
+    /**
+     * Set key class.
+     *
+     * @param keyCls Key class.
+     */
+    public void keyClass(Class<?> keyCls) {
+        this.keyCls = keyCls;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String keyTypeName() {
+        return keyTypeName;
+    }
+
+    /**
+     * Set key type name.
+     *
+     * @param keyTypeName Key type name.
+     */
+    public void keyTypeName(String keyTypeName) {
+        this.keyTypeName = keyTypeName;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String valueTypeName() {
+        return valTypeName;
+    }
+
+    /**
+     * Set value type name.
+     *
+     * @param valTypeName Value type name.
+     */
+    public void valueTypeName(String valTypeName) {
+        this.valTypeName = valTypeName;
+    }
+
+    /**
+     * Adds property to the type descriptor.
+     *
+     * @param prop Property.
+     * @param failOnDuplicate Fail on duplicate flag.
+     * @throws IgniteCheckedException In case of error.
+     */
+    public void addProperty(GridQueryProperty prop, boolean failOnDuplicate) throws IgniteCheckedException {
+        String name = prop.name();
+
+        if (props.put(name, prop) != null && failOnDuplicate)
+            throw new IgniteCheckedException("Property with name '" + name + "' already exists.");
+
+        if (uppercaseProps.put(name.toUpperCase(), prop) != null && failOnDuplicate)
+            throw new IgniteCheckedException("Property with upper cased name '" + name + "' already exists.");
+
+        fields.put(name, prop.type());
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean valueTextIndex() {
+        return valTextIdx;
+    }
+
+    /**
+     * Sets if this value should be text indexed.
+     *
+     * @param valTextIdx Flag value.
+     */
+    public void valueTextIndex(boolean valTextIdx) {
+        this.valTextIdx = valTextIdx;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String affinityKey() {
+        return affKey;
+    }
+
+    /**
+     * @param affKey Affinity key field.
+     */
+    public void affinityKey(String affKey) {
+        this.affKey = affKey;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(QueryTypeDescriptorImpl.class, this);
+    }
+}