Merge branch 'salsubaiee/asterix_lsm_stabilization_issue_384' into asterix_lsm_stabilization (Reviewed by Raman).
diff --git a/asterix-app/src/main/java/edu/uci/ics/asterix/aql/translator/AqlTranslator.java b/asterix-app/src/main/java/edu/uci/ics/asterix/aql/translator/AqlTranslator.java
index b9f81d6..41dde5d 100644
--- a/asterix-app/src/main/java/edu/uci/ics/asterix/aql/translator/AqlTranslator.java
+++ b/asterix-app/src/main/java/edu/uci/ics/asterix/aql/translator/AqlTranslator.java
@@ -547,6 +547,13 @@
             Index idx = MetadataManager.INSTANCE.getIndex(metadataProvider.getMetadataTxnContext(), dataverseName,
                     datasetName, indexName);
 
+            String itemTypeName = ds.getItemTypeName();
+            Datatype dt = MetadataManager.INSTANCE.getDatatype(metadataProvider.getMetadataTxnContext(), dataverseName,
+                    itemTypeName);
+            IAType itemType = dt.getDatatype();
+            ARecordType aRecordType = (ARecordType) itemType;
+            aRecordType.validateKeyFields(stmtCreateIndex.getFieldExprs(), stmtCreateIndex.getIndexType());
+
             if (idx != null) {
                 if (!stmtCreateIndex.getIfNotExists()) {
                     throw new AlgebricksException("An index with this name " + indexName + " already exists.");
diff --git a/asterix-app/src/test/resources/metadata/queries/exception/issue_384_create_index_error_1/issue_384_create_index_error_1.1.ddl.aql b/asterix-app/src/test/resources/metadata/queries/exception/issue_384_create_index_error_1/issue_384_create_index_error_1.1.ddl.aql
new file mode 100644
index 0000000..acc89db
--- /dev/null
+++ b/asterix-app/src/test/resources/metadata/queries/exception/issue_384_create_index_error_1/issue_384_create_index_error_1.1.ddl.aql
@@ -0,0 +1,20 @@
+/*
+ * Description  : create a btree index on unallowed key type.
+ * Expected Res : Failure
+ * Date         : 23 April 2013
+ * Issue        : 384
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use dataverse test;
+
+create type opentype as open {
+id:int32,
+loc:point
+}
+
+create dataset testds(opentype) primary key id;
+create index loc_index on testds(loc);
+
diff --git a/asterix-app/src/test/resources/metadata/queries/exception/issue_384_create_index_error_2/issue_384_create_index_error_2.1.ddl.aql b/asterix-app/src/test/resources/metadata/queries/exception/issue_384_create_index_error_2/issue_384_create_index_error_2.1.ddl.aql
new file mode 100644
index 0000000..f3ec8b2
--- /dev/null
+++ b/asterix-app/src/test/resources/metadata/queries/exception/issue_384_create_index_error_2/issue_384_create_index_error_2.1.ddl.aql
@@ -0,0 +1,20 @@
+/*
+ * Description  : create an rtree index on unallowed key type.
+ * Expected Res : Failure
+ * Date         : 23 April 2013
+ * Issue        : 384
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use dataverse test;
+
+create type opentype as open {
+id:int32,
+age:int32
+}
+
+create dataset testds(opentype) primary key id;
+create index loc_index on testds(age) type rtree;
+
diff --git a/asterix-app/src/test/resources/metadata/queries/exception/issue_384_create_index_error_3/issue_384_create_index_error_3.1.ddl.aql b/asterix-app/src/test/resources/metadata/queries/exception/issue_384_create_index_error_3/issue_384_create_index_error_3.1.ddl.aql
new file mode 100644
index 0000000..4d8c488
--- /dev/null
+++ b/asterix-app/src/test/resources/metadata/queries/exception/issue_384_create_index_error_3/issue_384_create_index_error_3.1.ddl.aql
@@ -0,0 +1,20 @@
+/*
+ * Description  : create a keyword index on unallowed key type.
+ * Expected Res : Failure
+ * Date         : 23 April 2013
+ * Issue        : 384
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use dataverse test;
+
+create type opentype as open {
+id:int32,
+loc:point
+}
+
+create dataset testds(opentype) primary key id;
+create index loc_index on testds(loc) type keyword;
+
diff --git a/asterix-app/src/test/resources/metadata/queries/exception/issue_384_create_index_error_4/issue_384_create_index_error_4.1.ddl.aql b/asterix-app/src/test/resources/metadata/queries/exception/issue_384_create_index_error_4/issue_384_create_index_error_4.1.ddl.aql
new file mode 100644
index 0000000..938f137
--- /dev/null
+++ b/asterix-app/src/test/resources/metadata/queries/exception/issue_384_create_index_error_4/issue_384_create_index_error_4.1.ddl.aql
@@ -0,0 +1,20 @@
+/*
+ * Description  : create a fuzzy keyword index on unallowed key type.
+ * Expected Res : Failure
+ * Date         : 23 April 2013
+ * Issue        : 384
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use dataverse test;
+
+create type opentype as open {
+id:int32,
+loc:point
+}
+
+create dataset testds(opentype) primary key id;
+create index loc_index on testds(loc) type fuzzy keyword;
+
diff --git a/asterix-app/src/test/resources/metadata/queries/exception/issue_384_create_index_error_5/issue_384_create_index_error_5.1.ddl.aql b/asterix-app/src/test/resources/metadata/queries/exception/issue_384_create_index_error_5/issue_384_create_index_error_5.1.ddl.aql
new file mode 100644
index 0000000..d9baf04
--- /dev/null
+++ b/asterix-app/src/test/resources/metadata/queries/exception/issue_384_create_index_error_5/issue_384_create_index_error_5.1.ddl.aql
@@ -0,0 +1,20 @@
+/*
+ * Description  : create an ngram index on unallowed key type.
+ * Expected Res : Failure
+ * Date         : 23 April 2013
+ * Issue        : 384
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use dataverse test;
+
+create type opentype as open {
+id:int32,
+loc:point
+}
+
+create dataset testds(opentype) primary key id;
+create index loc_index on testds(loc) type ngram(2);
+
diff --git a/asterix-app/src/test/resources/metadata/queries/exception/issue_384_create_index_error_6/issue_384_create_index_error_6.1.ddl.aql b/asterix-app/src/test/resources/metadata/queries/exception/issue_384_create_index_error_6/issue_384_create_index_error_6.1.ddl.aql
new file mode 100644
index 0000000..dee287d
--- /dev/null
+++ b/asterix-app/src/test/resources/metadata/queries/exception/issue_384_create_index_error_6/issue_384_create_index_error_6.1.ddl.aql
@@ -0,0 +1,20 @@
+/*
+ * Description  : create a fuzzy ngram index on unallowed key type.
+ * Expected Res : Failure
+ * Date         : 23 April 2013
+ * Issue        : 384
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use dataverse test;
+
+create type opentype as open {
+id:int32,
+loc:point
+}
+
+create dataset testds(opentype) primary key id;
+create index loc_index on testds(loc) type fuzzy ngram(2);
+
diff --git a/asterix-app/src/test/resources/metadata/testsuite.xml b/asterix-app/src/test/resources/metadata/testsuite.xml
index de671ba..47bcafa 100644
--- a/asterix-app/src/test/resources/metadata/testsuite.xml
+++ b/asterix-app/src/test/resources/metadata/testsuite.xml
@@ -254,6 +254,42 @@
         <expected-error>edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException</expected-error>
       </compilation-unit>
     </test-case>
+    <test-case FilePath="exception">
+      <compilation-unit name="issue_384_create_index_error_1">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
+      <compilation-unit name="issue_384_create_index_error_2">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
+      <compilation-unit name="issue_384_create_index_error_3">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
+      <compilation-unit name="issue_384_create_index_error_4">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
+      <compilation-unit name="issue_384_create_index_error_5">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
+      <compilation-unit name="issue_384_create_index_error_6">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException</expected-error>
+      </compilation-unit>
+    </test-case>
   </test-group>
   <test-group name="transaction">
     <test-case FilePath="transaction">
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/ARecordType.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/ARecordType.java
index e301cee..ec544ed 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/ARecordType.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/ARecordType.java
@@ -27,6 +27,7 @@
 import org.json.JSONObject;
 
 import edu.uci.ics.asterix.common.annotations.IRecordTypeAnnotation;
+import edu.uci.ics.asterix.common.config.DatasetConfig.IndexType;
 import edu.uci.ics.asterix.common.exceptions.AsterixException;
 import edu.uci.ics.asterix.om.base.IAObject;
 import edu.uci.ics.asterix.om.visitors.IOMVisitor;
@@ -268,6 +269,101 @@
         }
     }
 
+    /**
+     * Validates the key fields that will be used as keys of an index.
+     * 
+     * @param keyFieldNames
+     *            a list of key fields that will be validated
+     * @param indexType
+     *            the type of the index that its key fields is being validated
+     * @throws AlgebricksException
+     *             (if the validation failed), IOException
+     */
+    public void validateKeyFields(List<String> keyFieldNames, IndexType indexType) throws AlgebricksException,
+            IOException {
+        for (String fieldName : keyFieldNames) {
+            IAType fieldType = getFieldType(fieldName);
+            if (fieldType == null) {
+                throw new AlgebricksException("A field with this name  \"" + fieldName + "\" could not be found.");
+            }
+            switch (indexType) {
+                case BTREE:
+                    switch (fieldType.getTypeTag()) {
+                        case INT8:
+                        case INT16:
+                        case INT32:
+                        case INT64:
+                        case FLOAT:
+                        case DOUBLE:
+                        case STRING:
+                        case DATE:
+                        case TIME:
+                        case DATETIME:
+                            break;
+                        default:
+                            throw new AlgebricksException("The field \"" + fieldName + "\" which is of type "
+                                    + fieldType.getTypeTag() + " cannot be indexed using the BTree index.");
+                    }
+                    break;
+                case RTREE:
+                    switch (fieldType.getTypeTag()) {
+                        case POINT:
+                        case LINE:
+                        case RECTANGLE:
+                        case CIRCLE:
+                        case POLYGON:
+                            break;
+                        default:
+                            throw new AlgebricksException("The field \"" + fieldName + "\" which is of type "
+                                    + fieldType.getTypeTag() + " cannot be indexed using the RTree index.");
+                    }
+                    break;
+                case FUZZY_NGRAM_INVIX:
+                    switch (fieldType.getTypeTag()) {
+                        case STRING:
+                            break;
+                        default:
+                            throw new AlgebricksException("The field \"" + fieldName + "\" which is of type "
+                                    + fieldType.getTypeTag() + " cannot be indexed using the Fuzzy N-Gram index.");
+                    }
+                    break;
+                case FUZZY_WORD_INVIX:
+                    switch (fieldType.getTypeTag()) {
+                        case STRING:
+                        case UNORDEREDLIST:
+                        case ORDEREDLIST:
+                            break;
+                        default:
+                            throw new AlgebricksException("The field \"" + fieldName + "\" which is of type "
+                                    + fieldType.getTypeTag() + " cannot be indexed using the Fuzzy Keyword index.");
+                    }
+                    break;
+                case NGRAM_INVIX:
+                    switch (fieldType.getTypeTag()) {
+                        case STRING:
+                            break;
+                        default:
+                            throw new AlgebricksException("The field \"" + fieldName + "\" which is of type "
+                                    + fieldType.getTypeTag() + " cannot be indexed using the N-Gram index.");
+                    }
+                    break;
+                case WORD_INVIX:
+                    switch (fieldType.getTypeTag()) {
+                        case STRING:
+                        case UNORDEREDLIST:
+                        case ORDEREDLIST:
+                            break;
+                        default:
+                            throw new AlgebricksException("The field \"" + fieldName + "\" which is of type "
+                                    + fieldType.getTypeTag() + " cannot be indexed using the Keyword index.");
+                    }
+                    break;
+                default:
+                    throw new AlgebricksException("Invalid index type: " + indexType + ".");
+            }
+        }
+    }
+
     public boolean doesFieldExist(String fieldName) {
         for (String f : fieldNames) {
             if (f.compareTo(fieldName) == 0) {