Merge commit '8db70084f0593983af6ed877ccf50553dec4649c' from release-0.9.4-pre-rc

Change-Id: I3514c30a78bdf1a05bffb8858e7b0634e8b89595
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java
index fd66821..29a8e77 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java
@@ -67,6 +67,7 @@
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
 import org.apache.hyracks.algebricks.core.algebra.visitors.ILogicalExpressionReferenceTransform;
 import org.apache.hyracks.algebricks.core.algebra.visitors.ILogicalExpressionVisitor;
+import org.apache.hyracks.algebricks.core.config.AlgebricksConfig;
 import org.apache.hyracks.algebricks.core.jobgen.impl.JobGenContext;
 import org.apache.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
@@ -91,13 +92,16 @@
             BuiltinFunctions.GET_RECORD_FIELDS, BuiltinFunctions.GET_RECORD_FIELD_VALUE,
             BuiltinFunctions.FIELD_ACCESS_NESTED, BuiltinFunctions.GET_ITEM, BuiltinFunctions.OPEN_RECORD_CONSTRUCTOR,
             BuiltinFunctions.FIELD_ACCESS_BY_INDEX, BuiltinFunctions.CAST_TYPE, BuiltinFunctions.META,
-            BuiltinFunctions.META_KEY, BuiltinFunctions.RECORD_CONCAT, BuiltinFunctions.RECORD_CONCAT_STRICT);
+            BuiltinFunctions.META_KEY, BuiltinFunctions.RECORD_CONCAT, BuiltinFunctions.RECORD_CONCAT_STRICT,
+            BuiltinFunctions.TO_ATOMIC, BuiltinFunctions.TO_ARRAY);
 
-    /** Throws exceptions in substituiteProducedVariable, setVarType, and one getVarType method. */
+    /**
+     * Throws exceptions in substituiteProducedVariable, setVarType, and one getVarType method.
+     */
     private static final IVariableTypeEnvironment _emptyTypeEnv = new IVariableTypeEnvironment() {
 
         @Override
-        public boolean substituteProducedVariable(LogicalVariable v1, LogicalVariable v2) throws AlgebricksException {
+        public boolean substituteProducedVariable(LogicalVariable v1, LogicalVariable v2) {
             throw new IllegalStateException();
         }
 
@@ -108,12 +112,12 @@
 
         @Override
         public Object getVarType(LogicalVariable var, List<LogicalVariable> nonNullVariables,
-                List<List<LogicalVariable>> correlatedNullableVariableLists) throws AlgebricksException {
+                List<List<LogicalVariable>> correlatedNullableVariableLists) {
             throw new IllegalStateException();
         }
 
         @Override
-        public Object getVarType(LogicalVariable var) throws AlgebricksException {
+        public Object getVarType(LogicalVariable var) {
             throw new IllegalStateException();
         }
 
@@ -170,14 +174,13 @@
         }
 
         @Override
-        public Pair<Boolean, ILogicalExpression> visitConstantExpression(ConstantExpression expr, Void arg)
-                throws AlgebricksException {
+        public Pair<Boolean, ILogicalExpression> visitConstantExpression(ConstantExpression expr, Void arg) {
             return new Pair<>(false, expr);
         }
 
         @Override
         public Pair<Boolean, ILogicalExpression> visitVariableReferenceExpression(VariableReferenceExpression expr,
-                Void arg) throws AlgebricksException {
+                Void arg) {
             return new Pair<>(false, expr);
         }
 
@@ -194,31 +197,33 @@
                 return new Pair<>(false, null);
             }
 
-            //Current List SerDe assumes a strongly typed list, so we do not constant fold the list constructors if they are not strongly typed
-            if (expr.getFunctionIdentifier().equals(BuiltinFunctions.UNORDERED_LIST_CONSTRUCTOR)
-                    || expr.getFunctionIdentifier().equals(BuiltinFunctions.ORDERED_LIST_CONSTRUCTOR)) {
-                AbstractCollectionType listType = (AbstractCollectionType) TypeCastUtils.getRequiredType(expr);
-                if (listType != null && (listType.getItemType().getTypeTag() == ATypeTag.ANY
-                        || listType.getItemType() instanceof AbstractCollectionType)) {
-                    //case1: listType == null,  could be a nested list inside a list<ANY>
-                    //case2: itemType = ANY
-                    //case3: itemType = a nested list
-                    return new Pair<>(false, null);
-                }
-            }
-            if (expr.getFunctionIdentifier().equals(BuiltinFunctions.FIELD_ACCESS_BY_NAME)) {
-                ARecordType rt = (ARecordType) _emptyTypeEnv.getType(expr.getArguments().get(0).getValue());
-                String str = ConstantExpressionUtil.getStringConstant(expr.getArguments().get(1).getValue());
-                int k = rt.getFieldIndex(str);
-                if (k >= 0) {
-                    // wait for the ByNameToByIndex rule to apply
-                    return new Pair<>(changed, expr);
-                }
-            }
-
-            IScalarEvaluatorFactory fact = jobGenCtx.getExpressionRuntimeProvider().createEvaluatorFactory(expr,
-                    _emptyTypeEnv, _emptySchemas, jobGenCtx);
             try {
+                // Current List SerDe assumes a strongly typed list, so we do not constant fold the list constructors
+                // if they are not strongly typed
+                if (expr.getFunctionIdentifier().equals(BuiltinFunctions.UNORDERED_LIST_CONSTRUCTOR)
+                        || expr.getFunctionIdentifier().equals(BuiltinFunctions.ORDERED_LIST_CONSTRUCTOR)) {
+                    AbstractCollectionType listType = (AbstractCollectionType) TypeCastUtils.getRequiredType(expr);
+                    if (listType != null && (listType.getItemType().getTypeTag() == ATypeTag.ANY
+                            || listType.getItemType() instanceof AbstractCollectionType)) {
+                        //case1: listType == null,  could be a nested list inside a list<ANY>
+                        //case2: itemType = ANY
+                        //case3: itemType = a nested list
+                        return new Pair<>(false, null);
+                    }
+                }
+                if (expr.getFunctionIdentifier().equals(BuiltinFunctions.FIELD_ACCESS_BY_NAME)) {
+                    ARecordType rt = (ARecordType) _emptyTypeEnv.getType(expr.getArguments().get(0).getValue());
+                    String str = ConstantExpressionUtil.getStringConstant(expr.getArguments().get(1).getValue());
+                    int k = rt.getFieldIndex(str);
+                    if (k >= 0) {
+                        // wait for the ByNameToByIndex rule to apply
+                        return new Pair<>(changed, expr);
+                    }
+                }
+
+                IScalarEvaluatorFactory fact = jobGenCtx.getExpressionRuntimeProvider().createEvaluatorFactory(expr,
+                        _emptyTypeEnv, _emptySchemas, jobGenCtx);
+
                 IScalarEvaluator eval = fact.createScalarEvaluator(null);
                 eval.evaluate(null, p);
                 Object t = _emptyTypeEnv.getType(expr);
@@ -229,8 +234,11 @@
                 bbis.setByteBuffer(ByteBuffer.wrap(p.getByteArray(), p.getStartOffset(), p.getLength()), 0);
                 IAObject o = (IAObject) serde.deserialize(dis);
                 return new Pair<>(true, new ConstantExpression(new AsterixConstantValue(o)));
-            } catch (HyracksDataException e) {
-                throw new AlgebricksException(e);
+            } catch (HyracksDataException | AlgebricksException e) {
+                if (AlgebricksConfig.ALGEBRICKS_LOGGER.isDebugEnabled()) {
+                    AlgebricksConfig.ALGEBRICKS_LOGGER.debug("Exception caught at constant folding: " + e, e);
+                }
+                return new Pair<>(false, null);
             }
         }
 
@@ -267,7 +275,7 @@
             return changed;
         }
 
-        private boolean checkArgs(AbstractFunctionCallExpression expr) throws AlgebricksException {
+        private boolean checkArgs(AbstractFunctionCallExpression expr) {
             for (Mutable<ILogicalExpression> r : expr.getArguments()) {
                 if (r.getValue().getExpressionTag() != LogicalExpressionTag.CONSTANT) {
                     return false;
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/FlushMetadataOnlyTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/FlushMetadataOnlyTest.java
index f9421a1..1251d91 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/FlushMetadataOnlyTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/FlushMetadataOnlyTest.java
@@ -28,7 +28,7 @@
 import org.apache.asterix.test.common.TestHelper;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.job.JobId;
-import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
 import org.apache.hyracks.data.std.util.DataUtils;
 import org.apache.hyracks.storage.am.common.api.IIndexDataflowHelper;
 import org.apache.hyracks.storage.am.common.dataflow.IndexDataflowHelperFactory;
@@ -106,7 +106,7 @@
         StorageTestUtils.flush(dsLifecycleMgr, lsmBtree, false);
         // assert one disk component
         Assert.assertEquals(1, lsmBtree.getDiskComponents().size());
-        VoidPointable pointable = VoidPointable.FACTORY.createPointable();
+        ArrayBackedValueStorage pointable = new ArrayBackedValueStorage();
         ComponentUtils.get(lsmBtree, key, pointable);
         Assert.assertTrue(DataUtils.equals(pointable, value));
         // ensure that we can search this component
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/LogMarkerTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/LogMarkerTest.java
index 0a968c8..2121327 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/LogMarkerTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/LogMarkerTest.java
@@ -56,6 +56,7 @@
 import org.apache.hyracks.api.test.FrameWriterTestUtils.FrameWriterOperation;
 import org.apache.hyracks.api.util.HyracksConstants;
 import org.apache.hyracks.data.std.primitive.LongPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
 import org.apache.hyracks.dataflow.common.comm.io.FrameTupleAppender;
 import org.apache.hyracks.dataflow.common.data.accessors.ITupleReference;
 import org.apache.hyracks.dataflow.common.io.MessagingFrameTupleAppender;
@@ -156,9 +157,10 @@
                         iHelperFactory.create(ctx.getJobletContext().getServiceContext(), 0);
                 dataflowHelper.open();
                 LSMBTree btree = (LSMBTree) dataflowHelper.getIndexInstance();
-                LongPointable longPointable = LongPointable.FACTORY.createPointable();
-                ComponentUtils.get(btree, ComponentUtils.MARKER_LSN_KEY, longPointable);
-                long lsn = longPointable.getLong();
+                ArrayBackedValueStorage buffer = new ArrayBackedValueStorage();
+
+                ComponentUtils.get(btree, ComponentUtils.MARKER_LSN_KEY, buffer);
+                long lsn = LongPointable.getLong(buffer.getByteArray(), buffer.getStartOffset());
                 int numOfMarkers = 0;
                 LogReader logReader = (LogReader) nc.getTransactionSubsystem().getLogManager().getLogReader(false);
                 long expectedMarkerId = markerId - 1;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/numeric/scientific/scientific.1.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/numeric/scientific/scientific.1.query.aql
index d668b0b..2ae391b 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries/numeric/scientific/scientific.1.query.aql
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/numeric/scientific/scientific.1.query.aql
@@ -17,5 +17,7 @@
  * under the License.
  */
 
-[2e5, 2e-5, .2e2, .2e-2, 0.5e3, 0.5e-3, 3.2e5, 3.2e-5]
+let $v1 := [2e5, 2e+5, 2e-5, .2e2, .2e+2, .2e-2, 0.5e3, 0.5e+3, 0.5e-3, 3.2e5, 3.2e+5, 3.2e-5 ]
+let $v2 := [2E5, 2E+5, 2E-5, .2E2, .2E+2, .2E-2, 0.5E3, 0.5E+3, 0.5E-3, 3.2E5, 3.2E+5, 3.2E-5 ]
+return { "t1": $v1, "t2": $v2 }
 
diff --git a/asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/issue2348/issue2348.1.ddl.sqlpp
similarity index 63%
copy from asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/issue2348/issue2348.1.ddl.sqlpp
index a4a5ad6..a50d20b 100644
--- a/asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/issue2348/issue2348.1.ddl.sqlpp
@@ -16,15 +16,15 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.asterix.transaction.management.service.locking;
 
-import org.apache.asterix.common.exceptions.ACIDException;
-import org.apache.asterix.common.transactions.ITransactionContext;
+drop  dataverse test if exists;
+create  dataverse test;
 
-public class WaitInterruptedException extends ACIDException {
-    private static final long serialVersionUID = 1L;
+use test;
 
-    public WaitInterruptedException(ITransactionContext txnContext, String message, Throwable cause) {
-        super(txnContext, message, cause);
-    }
-}
+create type test.TestType as
+{
+  c_id: string
+};
+
+create  dataset t1(TestType) primary key c_id;
diff --git a/asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/issue2348/issue2348.2.update.sqlpp
similarity index 63%
rename from asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java
rename to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/issue2348/issue2348.2.update.sqlpp
index a4a5ad6..ec72ef5 100644
--- a/asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/issue2348/issue2348.2.update.sqlpp
@@ -16,15 +16,12 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.asterix.transaction.management.service.locking;
 
-import org.apache.asterix.common.exceptions.ACIDException;
-import org.apache.asterix.common.transactions.ITransactionContext;
+use test;
 
-public class WaitInterruptedException extends ACIDException {
-    private static final long serialVersionUID = 1L;
-
-    public WaitInterruptedException(ITransactionContext txnContext, String message, Throwable cause) {
-        super(txnContext, message, cause);
-    }
-}
+insert into t1 select value t from [
+  {"c_id":"01","c_b":true, "c_d":900,"c_i":999999},
+  {"c_id":"02","c_b":true, "c_d":800,"c_i":888888},
+  {"c_id":"03","c_b":true, "c_d":700,"c_i":777777},
+  {"c_id":"05","c_b":false,"c_d":111,"c_i":111111}
+] t
diff --git a/asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/issue2348/issue2348.3.query.sqlpp
similarity index 63%
copy from asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/issue2348/issue2348.3.query.sqlpp
index a4a5ad6..4fc8b4b 100644
--- a/asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/issue2348/issue2348.3.query.sqlpp
@@ -16,15 +16,11 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.asterix.transaction.management.service.locking;
 
-import org.apache.asterix.common.exceptions.ACIDException;
-import org.apache.asterix.common.transactions.ITransactionContext;
+use test;
 
-public class WaitInterruptedException extends ACIDException {
-    private static final long serialVersionUID = 1L;
-
-    public WaitInterruptedException(ITransactionContext txnContext, String message, Throwable cause) {
-        super(txnContext, message, cause);
-    }
-}
+select min(distinct c_i) v
+from t1
+where c_b
+group by c_i, c_d, c_b
+order by v
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/ifinf/ifinf.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/ifinf/ifinf.1.query.sqlpp
index 3b12ead..3b395bc 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/ifinf/ifinf.1.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/ifinf/ifinf.1.query.sqlpp
@@ -39,6 +39,7 @@
     [ 17, ifinf(float("INF"), double("-INF"), 2) ],
     [ 18, isnull(ifinf(double("INF"), double("-INF"), [], 2)) ],
     [ 19, ismissing(if_inf(double("INF"), double("-INF"), missing, 2)) ],
-    [ 20, tostring(ifinf(float("INF"), float("NaN"), 2)) ]
+    [ 20, tostring(ifinf(float("INF"), float("NaN"), 2)) ],
+    [ 21, if_inf(2, 1/0) ]
 ] t
 order by t[0]
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/scientific/scientific.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/scientific/scientific.1.query.sqlpp
index d668b0b..2bfe15f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/scientific/scientific.1.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/scientific/scientific.1.query.sqlpp
@@ -17,5 +17,9 @@
  * under the License.
  */
 
-[2e5, 2e-5, .2e2, .2e-2, 0.5e3, 0.5e-3, 3.2e5, 3.2e-5]
+{
+  "t1": [2e5, 2e+5, 2e-5, .2e2, .2e+2, .2e-2, 0.5e3, 0.5e+3, 0.5e-3, 3.2e5, 3.2e+5, 3.2e-5 ],
+  "t2": [2E5, 2E+5, 2E-5, .2E2, .2E+2, .2E-2, 0.5E3, 0.5E+3, 0.5E-3, 3.2E5, 3.2E+5, 3.2E-5 ]
+}
+
 
diff --git a/asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_array/to_array.1.query.sqlpp
similarity index 63%
copy from asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_array/to_array.1.query.sqlpp
index a4a5ad6..c0814b5 100644
--- a/asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_array/to_array.1.query.sqlpp
@@ -16,15 +16,18 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.asterix.transaction.management.service.locking;
 
-import org.apache.asterix.common.exceptions.ACIDException;
-import org.apache.asterix.common.transactions.ITransactionContext;
-
-public class WaitInterruptedException extends ACIDException {
-    private static final long serialVersionUID = 1L;
-
-    public WaitInterruptedException(ITransactionContext txnContext, String message, Throwable cause) {
-        super(txnContext, message, cause);
-    }
-}
+{
+  "t1": [ toarray(missing) is missing, toarray(null) is null, is_array(to_array([])) ],
+  "t2": to_array([]),
+  "t3": to_array([1]),
+  "t4": to_array([1,2]),
+  "t5": to_array("hello"),
+  "t6": to_array({"a":1}),
+  "t7": to_array({{ 2 }}),
+  "t8": (
+    from range(1,4) t
+    select value to_array(t)
+    order by t
+  )
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.1.ddl.sqlpp
similarity index 63%
copy from asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.1.ddl.sqlpp
index a4a5ad6..c156646 100644
--- a/asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.1.ddl.sqlpp
@@ -16,15 +16,15 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.asterix.transaction.management.service.locking;
 
-import org.apache.asterix.common.exceptions.ACIDException;
-import org.apache.asterix.common.transactions.ITransactionContext;
+drop  dataverse test if exists;
+create  dataverse test;
 
-public class WaitInterruptedException extends ACIDException {
-    private static final long serialVersionUID = 1L;
+use test;
 
-    public WaitInterruptedException(ITransactionContext txnContext, String message, Throwable cause) {
-        super(txnContext, message, cause);
-    }
-}
+create type test.T1 as
+{
+  id : bigint
+};
+
+create dataset t1(T1) primary key id;
diff --git a/asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.2.update.sqlpp
similarity index 63%
copy from asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.2.update.sqlpp
index a4a5ad6..2397ffb 100644
--- a/asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.2.update.sqlpp
@@ -16,15 +16,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.asterix.transaction.management.service.locking;
 
-import org.apache.asterix.common.exceptions.ACIDException;
-import org.apache.asterix.common.transactions.ITransactionContext;
+use test;
 
-public class WaitInterruptedException extends ACIDException {
-    private static final long serialVersionUID = 1L;
-
-    public WaitInterruptedException(ITransactionContext txnContext, String message, Throwable cause) {
-        super(txnContext, message, cause);
-    }
-}
+insert into t1 select value t
+from [
+  { "id": 1, "v": 2 },
+  { "id": 2, "v": "hello" },
+  { "id": 3, "v": [[[2]]] },
+  { "id": 4, "v": [[[2, 3]]] },
+  { "id": 5, "v": {"a": 2} },
+  { "id": 6, "v": {"a": 2, "b": 3} },
+  { "id": 7, "v": {"a":{"b":{"c":{"d":2}}}} },
+  { "id": 8, "v": {"a":[{"b":[{"c":[2]}]}]} }
+] t
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.3.query.sqlpp
new file mode 100644
index 0000000..07303d9
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.3.query.sqlpp
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+{
+    "t1": [ toatomic(missing) is missing, toatom(null) is null ],
+    "t2": [ to_atomic(1), to_atomic(true), to_atomic("hello") ],
+    "t3": [ to_atomic([]), to_atomic([2]), to_atomic([2,3]), to_atomic([[[[4]]]]) ],
+    "t4": [ to_atomic({{}}), to_atomic({{2}}), to_atomic({{2,3}}), to_atomic({{{{{{{{4}}}}}}}}) ],
+    "t5": [ to_atomic({}), to_atomic({"a":2}), to_atomic({"a":2, "b":3}), to_atomic({"a":{"b":{"c":{"d":4}}}}) ],
+    "t6": [ to_atomic([{"a":1}]), to_atomic([{"a":1, "b":2}]), to_atomic({"a":[{"b":[{"c":[2]}]}]}) ],
+    "t7": (
+      from range(1,4) t
+      select to_atomic(t) v1, to_atomic([t]) v2, to_atomic({"a": t}) v3, to_atomic([[{"a":[t]}]]) v4
+      order by t
+    )
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.4.query.sqlpp
similarity index 63%
copy from asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.4.query.sqlpp
index a4a5ad6..95fb2cb 100644
--- a/asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.4.query.sqlpp
@@ -16,15 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.asterix.transaction.management.service.locking;
 
-import org.apache.asterix.common.exceptions.ACIDException;
-import org.apache.asterix.common.transactions.ITransactionContext;
+use test;
 
-public class WaitInterruptedException extends ACIDException {
-    private static final long serialVersionUID = 1L;
-
-    public WaitInterruptedException(ITransactionContext txnContext, String message, Throwable cause) {
-        super(txnContext, message, cause);
-    }
-}
+select value [t.id, to_atomic(t.v) ]
+from t1 t
+order by t.id
\ No newline at end of file
diff --git a/asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_object/to_object.1.query.sqlpp
similarity index 63%
copy from asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_object/to_object.1.query.sqlpp
index a4a5ad6..e7c04f7 100644
--- a/asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/WaitInterruptedException.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_object/to_object.1.query.sqlpp
@@ -16,15 +16,18 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.asterix.transaction.management.service.locking;
 
-import org.apache.asterix.common.exceptions.ACIDException;
-import org.apache.asterix.common.transactions.ITransactionContext;
-
-public class WaitInterruptedException extends ACIDException {
-    private static final long serialVersionUID = 1L;
-
-    public WaitInterruptedException(ITransactionContext txnContext, String message, Throwable cause) {
-        super(txnContext, message, cause);
-    }
-}
+{
+  "t1": [ toobject(missing) is missing, toobj(null) is null ],
+  "t2": is_object(to_object({})),
+  "t3": to_object({}),
+  "t4": to_object({"a":1}),
+  "t5": to_object({"a":1, "b":2}),
+  "t6": (
+    from [
+      int8("1"), int16("2"), int32("3"), int64("4"), float("5"), double("6"),
+      "hello", [7], [ { "a": 1 } ]
+    ] t
+    select value to_object(t)
+  )
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_string_01/to_string_01.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_string_01/to_string_01.1.query.sqlpp
index f759e16..52a39fc 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_string_01/to_string_01.1.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_string_01/to_string_01.1.query.sqlpp
@@ -18,7 +18,7 @@
  */
  {
   "t1": tostring(false),
-  "t2": to_string(true),
+  "t2": tostr(true),
   "t3": to_string(int8("8")),
   "t4": to_string(int16("16")),
   "t5": to_string(int32("32")),
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/issue2348/issue2348.3.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/issue2348/issue2348.3.adm
new file mode 100644
index 0000000..cf2ede9
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/issue2348/issue2348.3.adm
@@ -0,0 +1,3 @@
+{ "v": 777777 }
+{ "v": 888888 }
+{ "v": 999999 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/ifinf/ifinf.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/ifinf/ifinf.1.adm
index c45efa6..9f56be4 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/ifinf/ifinf.1.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/ifinf/ifinf.1.adm
@@ -18,4 +18,5 @@
 [ 17, 2 ]
 [ 18, true ]
 [ 19, true ]
-[ 20, "NaN" ]
\ No newline at end of file
+[ 20, "NaN" ]
+[ 21, 2 ]
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/scientific/scientific.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/scientific/scientific.1.adm
index f65c2fe..1a2e70f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/scientific/scientific.1.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/scientific/scientific.1.adm
@@ -1 +1 @@
-[ 200000.0, 2.0E-5, 20.0, 0.002, 500.0, 5.0E-4, 320000.0, 3.2E-5 ]
\ No newline at end of file
+{ "t1": [ 200000.0, 200000.0, 2.0E-5, 20.0, 20.0, 0.002, 500.0, 500.0, 5.0E-4, 320000.0, 320000.0, 3.2E-5 ], "t2": [ 200000.0, 200000.0, 2.0E-5, 20.0, 20.0, 0.002, 500.0, 500.0, 5.0E-4, 320000.0, 320000.0, 3.2E-5 ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_array/to_array.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_array/to_array.1.adm
new file mode 100644
index 0000000..5aeb739
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_array/to_array.1.adm
@@ -0,0 +1 @@
+{ "t1": [ true, true, true ], "t2": [  ], "t3": [ 1 ], "t4": [ 1, 2 ], "t5": [ "hello" ], "t6": [ { "a": 1 } ], "t7": [ 2 ], "t8": [ [ 1 ], [ 2 ], [ 3 ], [ 4 ] ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_atomic/to_atomic.3.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_atomic/to_atomic.3.adm
new file mode 100644
index 0000000..aec2ce7
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_atomic/to_atomic.3.adm
@@ -0,0 +1 @@
+{ "t1": [ true, true ], "t2": [ 1, true, "hello" ], "t3": [ null, 2, null, 4 ], "t4": [ null, 2, null, 4 ], "t5": [ null, 2, null, 4 ], "t6": [ 1, null, 2 ], "t7": [ { "v1": 1, "v2": 1, "v3": 1, "v4": 1 }, { "v1": 2, "v2": 2, "v3": 2, "v4": 2 }, { "v1": 3, "v2": 3, "v3": 3, "v4": 3 }, { "v1": 4, "v2": 4, "v3": 4, "v4": 4 } ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_atomic/to_atomic.4.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_atomic/to_atomic.4.adm
new file mode 100644
index 0000000..3f4c517
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_atomic/to_atomic.4.adm
@@ -0,0 +1,8 @@
+[ 1, 2 ]
+[ 2, "hello" ]
+[ 3, 2 ]
+[ 4, null ]
+[ 5, 2 ]
+[ 6, null ]
+[ 7, 2 ]
+[ 8, 2 ]
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_object/to_object.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_object/to_object.1.adm
new file mode 100644
index 0000000..ceb84c2
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_object/to_object.1.adm
@@ -0,0 +1 @@
+{ "t1": [ true, true ], "t2": true, "t3": {  }, "t4": { "a": 1 }, "t5": { "a": 1, "b": 2 }, "t6": [ {  }, {  }, {  }, {  }, {  }, {  }, {  }, {  }, {  } ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
index ca95282..05382bc 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -687,6 +687,11 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="aggregate-sql">
+      <compilation-unit name="issue2348">
+        <output-dir compare="Text">issue2348</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="aggregate-sql">
       <compilation-unit name="avg_double">
         <output-dir compare="Text">avg_double</output-dir>
       </compilation-unit>
@@ -9236,6 +9241,16 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="types">
+      <compilation-unit name="to_array">
+        <output-dir compare="Text">to_array</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="types">
+      <compilation-unit name="to_atomic">
+        <output-dir compare="Text">to_atomic</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="types">
       <compilation-unit name="to_boolean_01">
         <output-dir compare="Text">to_boolean_01</output-dir>
       </compilation-unit>
@@ -9247,28 +9262,6 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="types">
-      <compilation-unit name="to_string_01">
-        <output-dir compare="Text">to_string_01</output-dir>
-      </compilation-unit>
-    </test-case>
-    <test-case FilePath="types">
-      <compilation-unit name="to_string_02">
-        <output-dir compare="Text">to_string_02</output-dir>
-        <expected-error>ASX0004: Unsupported type</expected-error>
-      </compilation-unit>
-    </test-case>
-    <test-case FilePath="types">
-      <compilation-unit name="to_double_01">
-        <output-dir compare="Text">to_double_01</output-dir>
-      </compilation-unit>
-    </test-case>
-    <test-case FilePath="types">
-      <compilation-unit name="to_double_02">
-        <output-dir compare="Text">to_double_02</output-dir>
-        <expected-error>ASX0002: Type mismatch</expected-error>
-      </compilation-unit>
-    </test-case>
-    <test-case FilePath="types">
       <compilation-unit name="to_bigint_01">
         <output-dir compare="Text">to_bigint_01</output-dir>
       </compilation-unit>
@@ -9280,6 +9273,17 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="types">
+      <compilation-unit name="to_double_01">
+        <output-dir compare="Text">to_double_01</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="types">
+      <compilation-unit name="to_double_02">
+        <output-dir compare="Text">to_double_02</output-dir>
+        <expected-error>ASX0002: Type mismatch</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="types">
       <compilation-unit name="to_number_01">
         <output-dir compare="Text">to_number_01</output-dir>
       </compilation-unit>
@@ -9290,6 +9294,22 @@
         <expected-error>ASX0002: Type mismatch</expected-error>
       </compilation-unit>
     </test-case>
+    <test-case FilePath="types">
+      <compilation-unit name="to_object">
+        <output-dir compare="Text">to_object</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="types">
+      <compilation-unit name="to_string_01">
+        <output-dir compare="Text">to_string_01</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="types">
+      <compilation-unit name="to_string_02">
+        <output-dir compare="Text">to_string_02</output-dir>
+        <expected-error>ASX0004: Unsupported type</expected-error>
+      </compilation-unit>
+    </test-case>
   </test-group>
   <test-group name="materialization">
     <test-case FilePath="materialization">
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/BaseOperationTracker.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/BaseOperationTracker.java
index 9ec13ef..b7af0b6 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/BaseOperationTracker.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/context/BaseOperationTracker.java
@@ -74,4 +74,8 @@
         dsInfo.untouch();
         dsInfo.getIndexes().get(resourceId).untouch();
     }
+
+    public DatasetInfo getDatasetInfo() {
+        return dsInfo;
+    }
 }
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/dataflow/NoOpFrameOperationCallbackFactory.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/dataflow/NoOpFrameOperationCallbackFactory.java
index 5e3879f..8f28752 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/dataflow/NoOpFrameOperationCallbackFactory.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/dataflow/NoOpFrameOperationCallbackFactory.java
@@ -18,6 +18,8 @@
  */
 package org.apache.asterix.common.dataflow;
 
+import java.io.IOException;
+
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.storage.am.lsm.common.api.IFrameOperationCallback;
@@ -43,5 +45,10 @@
         public void frameCompleted() throws HyracksDataException {
             // No Op
         }
+
+        @Override
+        public void close() throws IOException {
+            // No Op
+        }
     }
 }
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ACIDException.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ACIDException.java
index 77634eb..9775b45 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ACIDException.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ACIDException.java
@@ -18,8 +18,6 @@
  */
 package org.apache.asterix.common.exceptions;
 
-import org.apache.asterix.common.transactions.ITransactionContext;
-
 /**
  * Represents an exception related to an unexpected behavior that prevents the
  * system from supporting ACID guarantees. The exception contains the
@@ -30,25 +28,6 @@
 public class ACIDException extends RuntimeException {
 
     private static final long serialVersionUID = -8855848112541877323L;
-    private ITransactionContext txnContext;
-
-    public ITransactionContext getTxnContext() {
-        return txnContext;
-    }
-
-    public void setTxnContext(ITransactionContext txnContext) {
-        this.txnContext = txnContext;
-    }
-
-    public ACIDException(ITransactionContext txnContext, String message) {
-        super(message);
-        this.txnContext = txnContext;
-    }
-
-    public ACIDException(ITransactionContext txnContext, String message, Throwable cause) {
-        super(message, cause);
-        this.txnContext = txnContext;
-    }
 
     public ACIDException(String message, Throwable cause) {
         super(message, cause);
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
index 8146797..b9a5b29 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
@@ -74,6 +74,7 @@
     public static final int INVALID_TYPE_CASTING_MATH_FUNCTION = 31;
     public static final int REJECT_BAD_CLUSTER_STATE = 32;
     public static final int REJECT_NODE_UNREGISTERED = 33;
+    public static final int DIVISION_BY_ZERO = 34;
 
     public static final int INSTANTIATION_ERROR = 100;
 
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/AbstractLSMIOOperationCallback.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/AbstractLSMIOOperationCallback.java
index b9f0cc7..f027979 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/AbstractLSMIOOperationCallback.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/ioopcallbacks/AbstractLSMIOOperationCallback.java
@@ -28,6 +28,7 @@
 import org.apache.asterix.common.storage.ResourceReference;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.primitive.LongPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
 import org.apache.hyracks.storage.am.common.api.IMetadataPageManager;
 import org.apache.hyracks.storage.am.common.freepage.MutableArrayValueReference;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMComponent;
@@ -68,6 +69,7 @@
     protected ILSMComponentId[] nextComponentIds;
 
     protected final ILSMComponentIdGenerator idGenerator;
+    protected final ArrayBackedValueStorage buffer = new ArrayBackedValueStorage(Long.BYTES);
     private final IIndexCheckpointManagerProvider indexCheckpointManagerProvider;
     private final Map<ILSMComponentId, Long> componentLsnMap = new HashMap<>();
 
@@ -128,7 +130,7 @@
             }
             LongPointable markerLsn = LongPointable.FACTORY
                     .createPointable(ComponentUtils.getLong(opCtx.getComponentsToBeMerged().get(0).getMetadata(),
-                            ComponentUtils.MARKER_LSN_KEY, ComponentUtils.NOT_FOUND));
+                            ComponentUtils.MARKER_LSN_KEY, ComponentUtils.NOT_FOUND, buffer));
             opCtx.getNewComponent().getMetadata().put(ComponentUtils.MARKER_LSN_KEY, markerLsn);
         } else if (opCtx.getIoOperationType() == LSMIOOperationType.FLUSH) {
             // advance memory component indexes
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/transactions/PrimaryIndexLogMarkerCallback.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/transactions/PrimaryIndexLogMarkerCallback.java
index abe474b..a2ab15f 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/transactions/PrimaryIndexLogMarkerCallback.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/transactions/PrimaryIndexLogMarkerCallback.java
@@ -23,6 +23,7 @@
 
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.primitive.LongPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMDiskComponent;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMIndex;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMMemoryComponent;
@@ -34,6 +35,7 @@
 public class PrimaryIndexLogMarkerCallback implements ILogMarkerCallback {
     private final LongPointable pointable = LongPointable.FACTORY.createPointable();
     private final ILSMIndex index;
+    private final ArrayBackedValueStorage buffer = new ArrayBackedValueStorage(Long.BYTES);
 
     /**
      * @param index:
@@ -53,7 +55,7 @@
         long lsn;
         try {
             lsn = ComponentUtils.getLong(index.getCurrentMemoryComponent().getMetadata(), ComponentUtils.MARKER_LSN_KEY,
-                    ComponentUtils.NOT_FOUND);
+                    ComponentUtils.NOT_FOUND, buffer);
         } catch (HyracksDataException e) {
             // Should never happen since this is a memory component
             throw new IllegalStateException(e);
@@ -76,7 +78,7 @@
         for (ILSMDiskComponent c : diskComponents) {
             try {
                 long lsn = ComponentUtils.getLong(c.getMetadata(), ComponentUtils.MARKER_LSN_KEY,
-                        ComponentUtils.NOT_FOUND);
+                        ComponentUtils.NOT_FOUND, buffer);
                 if (lsn != ComponentUtils.NOT_FOUND) {
                     return lsn;
                 }
@@ -101,7 +103,7 @@
             if (c.isReadable()) {
                 try {
                     lsn = ComponentUtils.getLong(c.getMetadata(), ComponentUtils.MARKER_LSN_KEY,
-                            ComponentUtils.NOT_FOUND);
+                            ComponentUtils.NOT_FOUND, buffer);
                 } catch (HyracksDataException e) {
                     // Should never happen since this is a memory component
                     throw new IllegalStateException(e);
@@ -117,7 +119,11 @@
     @Override
     public void after(long lsn) {
         pointable.setLong(lsn);
-        index.getCurrentMemoryComponent().getMetadata().put(ComponentUtils.MARKER_LSN_KEY, pointable);
+        try {
+            index.getCurrentMemoryComponent().getMetadata().put(ComponentUtils.MARKER_LSN_KEY, pointable);
+        } catch (HyracksDataException e) {
+            throw new IllegalStateException(e);
+        }
     }
 
     public ILSMIndex getIndex() {
diff --git a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
index f9188b8..92aac98 100644
--- a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
+++ b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
@@ -67,6 +67,7 @@
 31 = Invalid type-casting math function: %1$s for converting %2$s to %3$s
 32 = Cannot execute request, cluster is %1$s
 33 = Node is not registered with the CC
+34 = Division by Zero.
 
 100 = Unable to instantiate class %1$s
 
diff --git a/asterixdb/asterix-doc/src/main/markdown/builtins/11_type.md b/asterixdb/asterix-doc/src/main/markdown/builtins/11_type.md
index f972735..578508f 100644
--- a/asterixdb/asterix-doc/src/main/markdown/builtins/11_type.md
+++ b/asterixdb/asterix-doc/src/main/markdown/builtins/11_type.md
@@ -293,6 +293,67 @@
 
  The function has an alias `isunknown`.
 
+### to_array ###
+  * Syntax:
+
+        to_array(expr)
+
+  * Converts input value to an `array` value
+  * Arguments:
+     * `expr` : an expression
+  * Return Value:
+     * if the argument is `missing` then `missing` is returned
+     * if the argument is `null` then `null` is returned
+     * if the argument is of `array` type then it is returned as is
+     * if the argument is of `multiset` type then it is returned as an `array` with elements in an undefined order
+     * otherwise an `array` containing the input expression as its single item is returned
+
+ * Example:
+
+        {
+          "v1": to_array("asterix"),
+          "v2": to_array(["asterix"]),
+        };
+
+ * The expected result is:
+
+        { "v1": ["asterix"], "v2": ["asterix"] }
+
+ The function has an alias `toarray`.
+
+### to_atomic ###
+  * Syntax:
+
+        to_atomic(expr)
+
+  * Converts input value to a [primitive](../datamodel.html#PrimitiveTypes) value
+  * Arguments:
+     * `expr` : an expression
+  * Return Value:
+     * if the argument is `missing` then `missing` is returned
+     * if the argument is `null` then `null` is returned
+     * if the argument is of primitive type then it is returned as is
+     * if the argument is of `array` or `multiset` type and has only one element then the result of invoking
+       to_atomic() on that element is returned
+     * if the argument is of `object` type and has only one field then the result of invoking to_atomic() on the
+       value of that field is returned
+     * otherwise `null` is returned
+
+ * Example:
+
+        {
+          "v1": to_atomic("asterix"),
+          "v2": to_atomic(["asterix"]),
+          "v3": to_atomic([0, 1]),
+          "v4": to_atomic({"value": "asterix"}),
+          "v5": to_number({"x": 1, "y": 2})
+        };
+
+ * The expected result is:
+
+        { "v1": "asterix", "v2": "asterix", "v3": null, "v4": "asterix", "v5": null }
+
+ The function has two aliases, `toatomic` or `toatom`.
 
 ### to_boolean ###
   * Syntax:
@@ -325,8 +386,7 @@
 
         { "v1": false, "v2": true, "v3": false, "v4": true }
 
- The function has an alias `toboolean`.
-
+ The function has two aliases, `toboolean` or `tobool`.
 
 ### to_bigint ###
   * Syntax:
@@ -364,7 +424,6 @@
 
  The function has an alias `tobigint`.
 
-
 ### to_double ###
   * Syntax:
 
@@ -432,7 +491,34 @@
 
         { "v1": 0, "v2": 1, "v3": 10, "v4": 11.5, "v5": 12.5 }
 
- The function has an alias `tonumber`.
+ The function has two aliases, `tonumber` or `tonum`.
+
+### to_object ###
+  * Syntax:
+
+        to_object(expr)
+
+  * Converts input value to an `object` value
+  * Arguments:
+     * `expr` : an expression
+  * Return Value:
+     * if the argument is `missing` then `missing` is returned
+     * if the argument is `null` then `null` is returned
+     * if the argument is of `object` type then it is returned as is
+     * otherwise an empty `object` is returned
+
+ * Example:
+
+        {
+          "v1": to_object({"value": "asterix"}),
+          "v2": to_object("asterix")
+        };
+
+ * The expected result is:
+
+        { "v1": {"value": "asterix"}, "v2": {} }
+
+ The function has two aliases, `toobject` or `toobj`.
 
 ### to_string ###
   * Syntax:
@@ -465,4 +551,4 @@
 
         { "v1": "false", "v2": "true", "v3": "10", "v4": "11.5", "v5": "asterix" }
 
- The function has an alias `tostring`.
+ The function has two aliases, `tostring` or `tostr`.
diff --git a/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj b/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj
index 74fe907..2d87556 100644
--- a/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj
+++ b/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj
@@ -2805,9 +2805,9 @@
 <DEFAULT,IN_DBL_BRACE>
 TOKEN:
 {
-    < DOUBLE_LITERAL: <DIGITS> ( "." <DIGITS> ) (("e"|"E") ("-")? <DIGITS>)?
-                          | <DIGITS> (("e"|"E") ("-")? <DIGITS>)
-                          | "." <DIGITS> (("e"|"E") ("-")? <DIGITS>)?
+    < DOUBLE_LITERAL: <DIGITS> ( "." <DIGITS> ) (("e"|"E") ("+"|"-")? <DIGITS>)?
+                          | <DIGITS> (("e"|"E") ("+"|"-")? <DIGITS>)
+                          | "." <DIGITS> (("e"|"E") ("+"|"-")? <DIGITS>)?
     >
   | < FLOAT_LITERAL: <DIGITS> ( "f" | "F" )
         | <DIGITS> ( "." <DIGITS> ( "f" | "F" ) )?
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java
index 3116521..3dffc00 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java
@@ -69,12 +69,19 @@
         addFunctionMapping("ifinf", "if-inf"); // ifinf, internal: if-inf
         addFunctionMapping("ifnan", "if-nan"); // ifnan, internal: if-nan
         addFunctionMapping("ifnanorinf", "if-nan-or-inf"); // ifnanorinf, internal: if-nan-or-inf
+        addFunctionMapping("toarray", "to-array"); // toarray, internal: to-array
+        addFunctionMapping("toatomic", "to-atomic"); // toatomic, internal: to-atomic
+        addFunctionMapping("toatom", "to-atomic"); // toatom, internal: to-atomic
         addFunctionMapping("toboolean", "to-boolean"); // toboolean, internal: to-boolean
-        addFunctionMapping("tostring", "to-string"); // tostring, internal: to-string
-        addFunctionMapping("todouble", "to-double"); // todouble, internal: to-double
+        addFunctionMapping("tobool", "to-boolean"); // tobool, internal: to-boolean
         addFunctionMapping("tobigint", "to-bigint"); // tobigint, internal: to-bigint
+        addFunctionMapping("todouble", "to-double"); // todouble, internal: to-double
+        addFunctionMapping("tostring", "to-string"); // tostring, internal: to-string
+        addFunctionMapping("tostr", "to-string"); // tostr, internal: to-string
         addFunctionMapping("tonumber", "to-number"); // tonumber, internal: to-number
         addFunctionMapping("tonum", "to-number"); // tonum, internal: to-number
+        addFunctionMapping("toobject", "to-object"); // toobject, internal: to-object
+        addFunctionMapping("toobj", "to-object"); // toobj, internal: to-object
 
         // Object functions
         // record-merge, internal: object-merge
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index 246c251..9af114b 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -3387,9 +3387,9 @@
 <DEFAULT,IN_DBL_BRACE>
 TOKEN:
 {
-    < DOUBLE_LITERAL: <DIGITS> ( "." <DIGITS> ) (("e"|"E") ("-")? <DIGITS>)?
-                      | <DIGITS> (("e"|"E") ("-")? <DIGITS>)
-                      | "." <DIGITS> (("e"|"E") ("-")? <DIGITS>)?
+    < DOUBLE_LITERAL: <DIGITS> ( "." <DIGITS> ) (("e"|"E") ("+"|"-")? <DIGITS>)?
+                      | <DIGITS> (("e"|"E") ("+"|"-")? <DIGITS>)
+                      | "." <DIGITS> (("e"|"E") ("+"|"-")? <DIGITS>)?
     >
   | < FLOAT_LITERAL:  <DIGITS> ( "f" | "F" )
                       | <DIGITS> ( "." <DIGITS> ( "f" | "F" ) )?
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DurationArithmeticOperations.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DurationArithmeticOperations.java
index a50adc6..26c3fb3 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DurationArithmeticOperations.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DurationArithmeticOperations.java
@@ -85,13 +85,13 @@
         boolean isLeapYear = GREG_CAL.isLeapYear(year);
 
         if (isLeapYear) {
-            if (day > GregorianCalendarSystem.DAYS_OF_MONTH_ORDI[month - 1]) {
-                day = GregorianCalendarSystem.DAYS_OF_MONTH_ORDI[month - 1];
-            }
-        } else {
             if (day > GregorianCalendarSystem.DAYS_OF_MONTH_LEAP[month - 1]) {
                 day = GregorianCalendarSystem.DAYS_OF_MONTH_LEAP[month - 1];
             }
+        } else {
+            if (day > GregorianCalendarSystem.DAYS_OF_MONTH_ORDI[month - 1]) {
+                day = GregorianCalendarSystem.DAYS_OF_MONTH_ORDI[month - 1];
+            }
         }
 
         return GREG_CAL.getChronon(year, month, day, hour, min, sec, ms, 0) + dayTimeDuration;
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
index a15eefe..6eeb6ab 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
@@ -107,9 +107,11 @@
 import org.apache.asterix.om.typecomputer.impl.SubsetCollectionTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.SubstringTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.SwitchCaseComputer;
+import org.apache.asterix.om.typecomputer.impl.ToArrayTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.ToBigIntTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.ToDoubleTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.ToNumberTypeComputer;
+import org.apache.asterix.om.typecomputer.impl.ToObjectTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.UnaryBinaryInt64TypeComputer;
 import org.apache.asterix.om.typecomputer.impl.UnaryMinusTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.UnaryStringInt64TypeComputer;
@@ -997,16 +999,22 @@
     public static final FunctionIdentifier IF_NAN_OR_INF =
             new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "if-nan-or-inf", FunctionIdentifier.VARARGS);
 
-    public static final FunctionIdentifier TO_BOOLEAN =
-            new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-boolean", 1);
-    public static final FunctionIdentifier TO_STRING =
-            new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-string", 1);
-    public static final FunctionIdentifier TO_DOUBLE =
-            new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-double", 1);
+    public static final FunctionIdentifier TO_ATOMIC =
+            new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-atomic", 1);
+    public static final FunctionIdentifier TO_ARRAY =
+            new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-array", 1);
     public static final FunctionIdentifier TO_BIGINT =
             new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-bigint", 1);
+    public static final FunctionIdentifier TO_BOOLEAN =
+            new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-boolean", 1);
+    public static final FunctionIdentifier TO_DOUBLE =
+            new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-double", 1);
     public static final FunctionIdentifier TO_NUMBER =
             new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-number", 1);
+    public static final FunctionIdentifier TO_OBJECT =
+            new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-object", 1);
+    public static final FunctionIdentifier TO_STRING =
+            new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-string", 1);
 
     public static final FunctionIdentifier EXTERNAL_LOOKUP =
             new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "external-lookup", FunctionIdentifier.VARARGS);
@@ -1193,11 +1201,14 @@
         addFunction(RANGE, AInt64TypeComputer.INSTANCE, true);
         addFunction(RECTANGLE_CONSTRUCTOR, ARectangleTypeComputer.INSTANCE, true);
 
-        addFunction(TO_BOOLEAN, ABooleanTypeComputer.INSTANCE, true);
-        addFunction(TO_STRING, AStringTypeComputer.INSTANCE, true);
-        addFunction(TO_DOUBLE, ToDoubleTypeComputer.INSTANCE, true);
+        addFunction(TO_ATOMIC, AnyTypeComputer.INSTANCE, true);
+        addFunction(TO_ARRAY, ToArrayTypeComputer.INSTANCE, true);
         addFunction(TO_BIGINT, ToBigIntTypeComputer.INSTANCE, true);
+        addFunction(TO_BOOLEAN, ABooleanTypeComputer.INSTANCE, true);
+        addFunction(TO_DOUBLE, ToDoubleTypeComputer.INSTANCE, true);
         addFunction(TO_NUMBER, ToNumberTypeComputer.INSTANCE, true);
+        addFunction(TO_OBJECT, ToObjectTypeComputer.INSTANCE, true);
+        addFunction(TO_STRING, AStringTypeComputer.INSTANCE, true);
 
         // Aggregate Functions
         addFunction(MAX, MinMaxAggTypeComputer.INSTANCE, true);
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ToArrayTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ToArrayTypeComputer.java
new file mode 100644
index 0000000..e33284f
--- /dev/null
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ToArrayTypeComputer.java
@@ -0,0 +1,47 @@
+/*
+ * 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.asterix.om.typecomputer.impl;
+
+import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
+import org.apache.asterix.om.types.AOrderedListType;
+import org.apache.asterix.om.types.AUnorderedListType;
+import org.apache.asterix.om.types.IAType;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+
+public class ToArrayTypeComputer extends AbstractResultTypeComputer {
+    public static final ToArrayTypeComputer INSTANCE = new ToArrayTypeComputer();
+
+    private ToArrayTypeComputer() {
+    }
+
+    @Override
+    protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
+        IAType argType = strippedInputTypes[0];
+        switch (argType.getTypeTag()) {
+            case ARRAY:
+                return argType;
+            case MULTISET:
+                return new AOrderedListType(((AUnorderedListType) argType).getItemType(), null);
+            default:
+                return new AOrderedListType(argType, null);
+        }
+    }
+}
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ToObjectTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ToObjectTypeComputer.java
new file mode 100644
index 0000000..116f7ac
--- /dev/null
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ToObjectTypeComputer.java
@@ -0,0 +1,41 @@
+/*
+ * 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.asterix.om.typecomputer.impl;
+
+import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.IAType;
+import org.apache.asterix.om.utils.RecordUtil;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+
+public class ToObjectTypeComputer extends AbstractResultTypeComputer {
+    public static final ToObjectTypeComputer INSTANCE = new ToObjectTypeComputer();
+
+    private ToObjectTypeComputer() {
+    }
+
+    @Override
+    protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
+        IAType strippedInputType = strippedInputTypes[0];
+        return strippedInputType.getTypeTag() == ATypeTag.OBJECT ? strippedInputType
+                : RecordUtil.FULLY_OPEN_RECORD_TYPE;
+    }
+}
diff --git a/asterixdb/asterix-replication/src/main/java/org/apache/asterix/replication/sync/ReplicaFilesSynchronizer.java b/asterixdb/asterix-replication/src/main/java/org/apache/asterix/replication/sync/ReplicaFilesSynchronizer.java
index 0d97a7a..583f33d 100644
--- a/asterixdb/asterix-replication/src/main/java/org/apache/asterix/replication/sync/ReplicaFilesSynchronizer.java
+++ b/asterixdb/asterix-replication/src/main/java/org/apache/asterix/replication/sync/ReplicaFilesSynchronizer.java
@@ -18,12 +18,9 @@
  */
 package org.apache.asterix.replication.sync;
 
-import static org.apache.asterix.common.utils.StorageConstants.METADATA_FILE_NAME;
-
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.SocketChannel;
-import java.util.Comparator;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -43,13 +40,6 @@
  */
 public class ReplicaFilesSynchronizer {
 
-    private static final Comparator<String> REPLICATED_FILES_COMPARATOR = (file, anotherFile) -> {
-        if (file.endsWith(METADATA_FILE_NAME) && !anotherFile.endsWith(METADATA_FILE_NAME)) {
-            return -1;
-        }
-        return file.compareTo(anotherFile);
-    };
-
     private final PartitionReplica replica;
     private final INcApplicationContext appCtx;
 
@@ -89,8 +79,8 @@
 
     private void replicateMissingFiles(List<String> files) {
         final FileSynchronizer sync = new FileSynchronizer(appCtx, replica);
-        // sort files to ensure index metadata files are replicated first
-        files.sort(REPLICATED_FILES_COMPARATOR);
+        // sort files to ensure index metadata files starting with "." are replicated first
+        files.sort(String::compareTo);
         files.forEach(sync::replicate);
     }
 
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericCaretDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericCaretDescriptor.java
index 3b72072..0079a8a 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericCaretDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericCaretDescriptor.java
@@ -22,6 +22,7 @@
 import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.runtime.exceptions.OverflowException;
 import org.apache.asterix.runtime.exceptions.UnsupportedTypeException;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
@@ -44,7 +45,7 @@
     @Override
     protected long evaluateInteger(long lhs, long rhs) throws HyracksDataException {
         if (rhs > Integer.MAX_VALUE) {
-            throw new ArithmeticException("Exponent cannot be larger than 2^31-1");
+            throw new OverflowException(getIdentifier());
         }
         return LongMath.checkedPow(lhs, (int) rhs);
     }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivideDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivideDescriptor.java
index 7cda149..77c94bf 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivideDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivideDescriptor.java
@@ -18,10 +18,13 @@
  */
 package org.apache.asterix.runtime.evaluators.functions;
 
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.RuntimeDataException;
 import org.apache.asterix.om.functions.BuiltinFunctions;
 import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.runtime.exceptions.OverflowException;
 import org.apache.asterix.runtime.exceptions.UnsupportedTypeException;
 import org.apache.hyracks.algebricks.common.exceptions.NotImplementedException;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -44,10 +47,10 @@
     @Override
     protected long evaluateInteger(long lhs, long rhs) throws HyracksDataException {
         if (rhs == 0) {
-            throw new ArithmeticException("Division by Zero.");
+            throw new RuntimeDataException(ErrorCode.DIVISION_BY_ZERO);
         }
         if ((lhs == Long.MIN_VALUE) && (rhs == -1L)) {
-            throw new ArithmeticException(("Overflow in integer division"));
+            throw new OverflowException(getIdentifier());
         }
         return lhs / rhs;
     }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToArrayDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToArrayDescriptor.java
new file mode 100644
index 0000000..9764aed
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToArrayDescriptor.java
@@ -0,0 +1,117 @@
+/*
+ * 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.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.asterix.builders.OrderedListBuilder;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.functions.IFunctionTypeInferer;
+import org.apache.asterix.om.typecomputer.impl.TypeComputeUtils;
+import org.apache.asterix.om.types.AOrderedListType;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.IAType;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.functions.FunctionTypeInferers;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ToArrayDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new ToArrayDescriptor();
+        }
+
+        @Override
+        public IFunctionTypeInferer createFunctionTypeInferer() {
+            return FunctionTypeInferers.SET_EXPRESSION_TYPE;
+        }
+    };
+
+    private static final long serialVersionUID = 1L;
+    private AOrderedListType oltype;
+
+    @Override
+    public void setImmutableStates(Object... states) {
+        oltype = TypeComputeUtils.extractOrderedListType((IAType) states[0]);
+    }
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
+
+                return new IScalarEvaluator() {
+
+                    private final IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx);
+                    private final IPointable arg0 = new VoidPointable();
+                    private final OrderedListBuilder listBuilder = new OrderedListBuilder();
+                    private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+                    private final DataOutput out = resultStorage.getDataOutput();
+
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple, IPointable resultPointable)
+                            throws HyracksDataException {
+                        eval0.evaluate(tuple, arg0);
+                        byte[] data = arg0.getByteArray();
+                        int offset = arg0.getStartOffset();
+                        if (data[offset] == ATypeTag.SERIALIZED_ORDEREDLIST_TYPE_TAG) {
+                            resultPointable.set(arg0);
+                        } else if (data[offset] == ATypeTag.SERIALIZED_UNORDEREDLIST_TYPE_TAG) {
+                            try {
+                                resultStorage.reset();
+                                out.writeByte(ATypeTag.SERIALIZED_ORDEREDLIST_TYPE_TAG);
+                                out.write(data, offset + 1, arg0.getLength() - 1);
+                                resultPointable.set(resultStorage);
+                            } catch (IOException e) {
+                                throw HyracksDataException.create(e);
+                            }
+                        } else {
+                            resultStorage.reset();
+                            listBuilder.reset(oltype);
+                            listBuilder.addItem(arg0);
+                            listBuilder.write(out, true);
+                            resultPointable.set(resultStorage);
+                        }
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return BuiltinFunctions.TO_ARRAY;
+    }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToAtomicDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToAtomicDescriptor.java
new file mode 100644
index 0000000..16554b5
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToAtomicDescriptor.java
@@ -0,0 +1,194 @@
+/*
+ * 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.asterix.runtime.evaluators.functions;
+
+import java.util.List;
+
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.functions.IFunctionTypeInferer;
+import org.apache.asterix.om.pointables.AListVisitablePointable;
+import org.apache.asterix.om.pointables.ARecordVisitablePointable;
+import org.apache.asterix.om.pointables.PointableAllocator;
+import org.apache.asterix.om.pointables.base.DefaultOpenFieldType;
+import org.apache.asterix.om.pointables.base.IVisitablePointable;
+import org.apache.asterix.om.types.AOrderedListType;
+import org.apache.asterix.om.types.ARecordType;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.AUnionType;
+import org.apache.asterix.om.types.AUnorderedListType;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.om.types.IAType;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.functions.FunctionTypeInferers;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.api.IValueReference;
+import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ToAtomicDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new ToAtomicDescriptor();
+        }
+
+        @Override
+        public IFunctionTypeInferer createFunctionTypeInferer() {
+            return FunctionTypeInferers.SET_ARGUMENT_TYPE;
+        }
+    };
+
+    private static final long serialVersionUID = 1L;
+    private IAType argType;
+
+    @Override
+    public void setImmutableStates(Object... states) {
+        argType = (IAType) states[0];
+    }
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
+
+                return new IScalarEvaluator() {
+
+                    private final IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx);
+                    private final IPointable arg = new VoidPointable();
+
+                    private final PointableAllocator pAlloc = new PointableAllocator();
+
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple, IPointable resultPointable)
+                            throws HyracksDataException {
+                        eval0.evaluate(tuple, arg);
+
+                        IValueReference itemPtr = arg;
+                        IAType itemTypeInferred = argType;
+
+                        for (;;) {
+                            byte[] itemData = itemPtr.getByteArray();
+                            int itemOffset = itemPtr.getStartOffset();
+                            ATypeTag typeTag = ATypeTag.VALUE_TYPE_MAPPING[itemData[itemOffset]];
+                            switch (typeTag) {
+                                case ARRAY:
+                                case MULTISET:
+                                    AListVisitablePointable listPointable =
+                                            (AListVisitablePointable) allocatePointable(itemTypeInferred, typeTag);
+                                    listPointable.set(itemPtr);
+                                    List<IVisitablePointable> listItems = listPointable.getItems();
+                                    if (listItems.size() != 1) {
+                                        PointableHelper.setNull(resultPointable);
+                                        return;
+                                    }
+                                    itemPtr = listItems.get(0);
+                                    itemTypeInferred = getListItemType(itemTypeInferred);
+                                    break;
+                                case OBJECT:
+                                    ARecordType recType = asRecordType(itemTypeInferred);
+                                    ARecordVisitablePointable recPointable =
+                                            (ARecordVisitablePointable) allocatePointable(itemTypeInferred, typeTag);
+                                    recPointable.set(itemPtr);
+                                    List<IVisitablePointable> recValues = recPointable.getFieldValues();
+                                    if (recValues.size() != 1) {
+                                        PointableHelper.setNull(resultPointable);
+                                        return;
+                                    }
+                                    itemPtr = recValues.get(0);
+                                    itemTypeInferred = recType.getFieldTypes().length == 1 ? recType.getFieldTypes()[0]
+                                            : BuiltinType.ANY;
+                                    break;
+                                default:
+                                    resultPointable.set(itemPtr);
+                                    return;
+                            }
+                        }
+                    }
+
+                    private IVisitablePointable allocatePointable(IAType inferredType, ATypeTag actualTypeTag) {
+                        if (inferredType.equals(BuiltinType.ANY)) {
+                            return allocatePointableForAny(actualTypeTag);
+                        }
+                        return pAlloc.allocateFieldValue(inferredType);
+                    }
+
+                    private IVisitablePointable allocatePointableForAny(ATypeTag typeTag) {
+                        switch (typeTag) {
+                            case OBJECT:
+                                return pAlloc.allocateFieldValue(DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE);
+                            case ARRAY:
+                                return pAlloc.allocateFieldValue(DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE);
+                            case MULTISET:
+                                return pAlloc.allocateFieldValue(DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE);
+                            default:
+                                return pAlloc.allocateFieldValue(null);
+                        }
+                    }
+
+                    private ARecordType asRecordType(IAType inferredType) {
+                        switch (inferredType.getTypeTag()) {
+                            case OBJECT:
+                                return (ARecordType) inferredType;
+                            case UNION:
+                                IAType innerType = ((AUnionType) inferredType).getActualType();
+                                if (innerType.getTypeTag() == ATypeTag.OBJECT) {
+                                    return (ARecordType) innerType;
+                                }
+                        }
+                        return DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE;
+                    }
+
+                    private IAType getListItemType(IAType inferredType) {
+                        switch (inferredType.getTypeTag()) {
+                            case ARRAY:
+                                return ((AOrderedListType) inferredType).getItemType();
+                            case MULTISET:
+                                return ((AUnorderedListType) inferredType).getItemType();
+                            case UNION:
+                                IAType innerType = ((AUnionType) inferredType).getActualType();
+                                switch (innerType.getTypeTag()) {
+                                    case ARRAY:
+                                        return ((AOrderedListType) innerType).getItemType();
+                                    case MULTISET:
+                                        return ((AUnorderedListType) innerType).getItemType();
+                                }
+                        }
+                        return BuiltinType.ANY;
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return BuiltinFunctions.TO_ATOMIC;
+    }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToObjectDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToObjectDescriptor.java
new file mode 100644
index 0000000..82dbd95
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToObjectDescriptor.java
@@ -0,0 +1,97 @@
+/*
+ * 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.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+
+import org.apache.asterix.builders.RecordBuilder;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ToObjectDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new ToObjectDescriptor();
+        }
+    };
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
+
+                return new IScalarEvaluator() {
+
+                    private final IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx);
+                    private final IPointable arg0 = new VoidPointable();
+                    private final RecordBuilder recordBuilder = new RecordBuilder();
+                    private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+                    private final DataOutput out = resultStorage.getDataOutput();
+                    private boolean wroteEmpty;
+
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple, IPointable resultPointable)
+                            throws HyracksDataException {
+                        eval0.evaluate(tuple, arg0);
+                        byte[] data = arg0.getByteArray();
+                        int offset = arg0.getStartOffset();
+                        if (data[offset] == ATypeTag.SERIALIZED_RECORD_TYPE_TAG) {
+                            resultPointable.set(arg0);
+                        } else {
+                            writeEmpty();
+                            resultPointable.set(resultStorage);
+                        }
+                    }
+
+                    private void writeEmpty() throws HyracksDataException {
+                        if (!wroteEmpty) {
+                            resultStorage.reset();
+                            recordBuilder.reset(null);
+                            recordBuilder.init();
+                            recordBuilder.write(out, true);
+                            wroteEmpty = true;
+                        }
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return BuiltinFunctions.TO_OBJECT;
+    }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordNamesDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordNamesDescriptor.java
index bb8e3e7..1719980 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordNamesDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordNamesDescriptor.java
@@ -31,6 +31,7 @@
 import org.apache.asterix.om.types.AOrderedListType;
 import org.apache.asterix.om.types.ARecordType;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.PointableHelper;
 import org.apache.asterix.runtime.functions.FunctionTypeInferers;
@@ -78,6 +79,7 @@
                     private final IPointable argPtr = new VoidPointable();
                     private final ARecordPointable recordPointable =
                             (ARecordPointable) ARecordPointable.FACTORY.createPointable();
+                    private final AOrderedListType listType = new AOrderedListType(BuiltinType.ASTRING, null);
                     private final OrderedListBuilder listBuilder = new OrderedListBuilder();
                     private final ArrayBackedValueStorage itemStorage = new ArrayBackedValueStorage();
                     private final DataOutput itemOut = itemStorage.getDataOutput();
@@ -100,7 +102,7 @@
 
                         recordPointable.set(data, offset, argPtr.getLength());
 
-                        listBuilder.reset(AOrderedListType.FULL_OPEN_ORDEREDLIST_TYPE);
+                        listBuilder.reset(listType);
 
                         try {
                             for (int i = 0, n = recordPointable.getSchemeFieldCount(recType); i < n; i++) {
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java
index 6648ff2..b05dbed 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java
@@ -241,10 +241,13 @@
 import org.apache.asterix.runtime.evaluators.functions.SubstringBeforeDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.SubstringDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.SwitchCaseDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.ToArrayDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.ToAtomicDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.ToBigIntDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.ToBooleanDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.ToDoubleDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.ToNumberDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.ToObjectDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.ToStringDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.UUIDDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.binary.BinaryConcatDescriptor;
@@ -689,17 +692,20 @@
         fc.addGenerated(DurationFromIntervalDescriptor.FACTORY);
 
         // Type functions.
+        fc.addGenerated(IsArrayDescriptor.FACTORY);
         fc.addGenerated(IsAtomicDescriptor.FACTORY);
         fc.addGenerated(IsBooleanDescriptor.FACTORY);
         fc.addGenerated(IsNumberDescriptor.FACTORY);
-        fc.addGenerated(IsStringDescriptor.FACTORY);
-        fc.addGenerated(IsArrayDescriptor.FACTORY);
         fc.addGenerated(IsObjectDescriptor.FACTORY);
-        fc.addGenerated(ToBooleanDescriptor.FACTORY);
-        fc.addGenerated(ToStringDescriptor.FACTORY);
-        fc.addGenerated(ToDoubleDescriptor.FACTORY);
+        fc.addGenerated(IsStringDescriptor.FACTORY);
+        fc.addGenerated(ToArrayDescriptor.FACTORY);
+        fc.addGenerated(ToAtomicDescriptor.FACTORY);
         fc.addGenerated(ToBigIntDescriptor.FACTORY);
+        fc.addGenerated(ToBooleanDescriptor.FACTORY);
+        fc.addGenerated(ToDoubleDescriptor.FACTORY);
         fc.addGenerated(ToNumberDescriptor.FACTORY);
+        fc.addGenerated(ToObjectDescriptor.FACTORY);
+        fc.addGenerated(ToStringDescriptor.FACTORY);
 
         // Cast function
         fc.addGenerated(CastTypeDescriptor.FACTORY);
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionTypeInferers.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionTypeInferers.java
index be041e5..e5a4301 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionTypeInferers.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionTypeInferers.java
@@ -69,6 +69,16 @@
         }
     };
 
+    public static final IFunctionTypeInferer SET_ARGUMENT_TYPE = new IFunctionTypeInferer() {
+        @Override
+        public void infer(ILogicalExpression expr, IFunctionDescriptor fd, IVariableTypeEnvironment context,
+                CompilerProperties compilerProps) throws AlgebricksException {
+            AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expr;
+            IAType t = (IAType) context.getType(fce.getArguments().get(0).getValue());
+            fd.setImmutableStates(TypeComputeUtils.getActualType(t));
+        }
+    };
+
     public static final class CastTypeInferer implements IFunctionTypeInferer {
         @Override
         public void infer(ILogicalExpression expr, IFunctionDescriptor fd, IVariableTypeEnvironment context,
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/operators/LSMPrimaryUpsertOperatorNodePushable.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/operators/LSMPrimaryUpsertOperatorNodePushable.java
index e58a7db..68053d3 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/operators/LSMPrimaryUpsertOperatorNodePushable.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/operators/LSMPrimaryUpsertOperatorNodePushable.java
@@ -40,6 +40,7 @@
 import org.apache.hyracks.api.dataflow.value.IMissingWriterFactory;
 import org.apache.hyracks.api.dataflow.value.RecordDescriptor;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.api.util.CleanupUtils;
 import org.apache.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
 import org.apache.hyracks.dataflow.common.comm.io.ArrayTupleReference;
 import org.apache.hyracks.dataflow.common.comm.io.FrameTupleAccessor;
@@ -243,6 +244,11 @@
                     callback.frameCompleted();
                     appender.write(writer, true);
                 }
+
+                @Override
+                public void close() throws IOException {
+                    callback.close();
+                }
             };
         } catch (Throwable e) { // NOSONAR: Re-thrown
             throw HyracksDataException.create(e);
@@ -360,16 +366,12 @@
 
     @Override
     public void close() throws HyracksDataException {
-        try {
-            try {
-                if (cursor != null) {
-                    cursor.destroy();
-                }
-            } finally {
-                writer.close();
-            }
-        } finally {
-            indexHelper.close();
+        Throwable failure = CleanupUtils.close(frameOpCallback, null);
+        failure = CleanupUtils.destroy(failure, cursor);
+        failure = CleanupUtils.close(writer, failure);
+        failure = CleanupUtils.close(indexHelper, failure);
+        if (failure != null) {
+            throw HyracksDataException.create(failure);
         }
     }
 
diff --git a/asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/ConcurrentLockManager.java b/asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/ConcurrentLockManager.java
index 726f95c..c91d233 100644
--- a/asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/ConcurrentLockManager.java
+++ b/asterixdb/asterix-transactions/src/main/java/org/apache/asterix/transaction/management/service/locking/ConcurrentLockManager.java
@@ -146,7 +146,8 @@
                 }
             }
         } catch (InterruptedException e) {
-            throw new WaitInterruptedException(txnContext, "interrupted", e);
+            Thread.currentThread().interrupt();
+            throw new ACIDException(e);
         } finally {
             group.releaseLatch();
         }
@@ -371,7 +372,8 @@
                 }
             }
         } catch (InterruptedException e) {
-            throw new WaitInterruptedException(txnContext, "interrupted", e);
+            Thread.currentThread().interrupt();
+            throw new ACIDException(e);
         } finally {
             if (reqSlot != NILL) {
                 // deallocate request, if we allocated one earlier
diff --git a/asterixdb/asterix-transactions/src/test/java/org/apache/asterix/transaction/management/service/locking/LockManagerUnitTest.java b/asterixdb/asterix-transactions/src/test/java/org/apache/asterix/transaction/management/service/locking/LockManagerUnitTest.java
index 817e0f0..0489319 100644
--- a/asterixdb/asterix-transactions/src/test/java/org/apache/asterix/transaction/management/service/locking/LockManagerUnitTest.java
+++ b/asterixdb/asterix-transactions/src/test/java/org/apache/asterix/transaction/management/service/locking/LockManagerUnitTest.java
@@ -31,6 +31,7 @@
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import org.apache.asterix.common.exceptions.ACIDException;
 import org.apache.asterix.common.transactions.DatasetId;
 import org.apache.asterix.common.transactions.ILockManager;
 import org.apache.asterix.common.transactions.ITransactionContext;
@@ -106,7 +107,7 @@
         reqs.add(req(Kind.LOCK, j(2), d(1), e(1), LockMode.X));
         reqs.add(req(Kind.PRINT));
         reqs.add(req(Kind.INSTANT_LOCK, j(3), d(1), e(1), LockMode.S));
-        expectError(execute(reqs), j(3), WaitInterruptedException.class);
+        expectError(execute(reqs), j(3), ACIDException.class);
     }
 
     @Test
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/IntersectOperator.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/IntersectOperator.java
index 8a06ec4..c2e4541 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/IntersectOperator.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/IntersectOperator.java
@@ -155,9 +155,11 @@
             Object expectedType = expected.getVarType(expectedVariables.get(i));
             Object actualType = actual.getVarType(actualVariables.get(i));
             if (!expectedType.equals(actualType)) {
-                AlgebricksConfig.ALGEBRICKS_LOGGER
-                        .warn("Type of two variables are not equal." + expectedVariables.get(i) + " is of type: "
-                                + expectedType + actualVariables.get(i) + " is of type: " + actualType);
+                if (AlgebricksConfig.ALGEBRICKS_LOGGER.isWarnEnabled()) {
+                    AlgebricksConfig.ALGEBRICKS_LOGGER
+                            .warn("Type of two variables are not equal." + expectedVariables.get(i) + " is of type: "
+                                    + expectedType + actualVariables.get(i) + " is of type: " + actualType);
+                }
             }
         }
     }
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/FDsAndEquivClassesVisitor.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/FDsAndEquivClassesVisitor.java
index 39d522f..2d5780d 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/FDsAndEquivClassesVisitor.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/FDsAndEquivClassesVisitor.java
@@ -314,9 +314,11 @@
             }
         }
         if (changed) {
-            AlgebricksConfig.ALGEBRICKS_LOGGER
-                    .debug(">>>> Group-by list changed from " + GroupByOperator.veListToString(gByList) + " to "
-                            + GroupByOperator.veListToString(newGbyList) + ".\n");
+            if (AlgebricksConfig.ALGEBRICKS_LOGGER.isDebugEnabled()) {
+                AlgebricksConfig.ALGEBRICKS_LOGGER
+                        .debug(">>>> Group-by list changed from " + GroupByOperator.veListToString(gByList) + " to "
+                                + GroupByOperator.veListToString(newGbyList) + ".\n");
+            }
         }
         gByList.clear();
         gByList.addAll(newGbyList);
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalPropertiesVisitor.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalPropertiesVisitor.java
index 5d9e2dc..ae93386 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalPropertiesVisitor.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalPropertiesVisitor.java
@@ -80,7 +80,7 @@
             computeLogicalPropertiesRec(ref.getValue(), visitor, context);
         }
         op.accept(visitor, context);
-        if (AlgebricksConfig.DEBUG) {
+        if (AlgebricksConfig.DEBUG && AlgebricksConfig.ALGEBRICKS_LOGGER.isTraceEnabled()) {
             AlgebricksConfig.ALGEBRICKS_LOGGER.trace(
                     "Logical properties visitor for " + op + ": " + context.getLogicalPropertiesVector(op) + "\n");
         }
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/HeuristicOptimizer.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/HeuristicOptimizer.java
index 4388032..9119d6c 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/HeuristicOptimizer.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/HeuristicOptimizer.java
@@ -90,7 +90,7 @@
             final LogicalOperatorPrettyPrintVisitor pvisitor = context.getPrettyPrintVisitor();
             pvisitor.reset(new AlgebricksAppendable());
             PlanPrettyPrinter.printPlan(plan, pvisitor, 0);
-            AlgebricksConfig.ALGEBRICKS_LOGGER.info(name + ":\n" + pvisitor.get().toString());
+            AlgebricksConfig.ALGEBRICKS_LOGGER.log(lvl, name + ":\n" + pvisitor.get().toString());
         }
     }
 
diff --git a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/EnforceStructuralPropertiesRule.java b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/EnforceStructuralPropertiesRule.java
index da0466e..f06933a 100644
--- a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/EnforceStructuralPropertiesRule.java
+++ b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/EnforceStructuralPropertiesRule.java
@@ -50,14 +50,14 @@
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder.OrderKind;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.FDsAndEquivClassesVisitor;
+import org.apache.hyracks.algebricks.core.algebra.operators.physical.AbstractPreSortedDistinctByPOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.physical.AbstractPreclusteredGroupByPOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.physical.AbstractStableSortPOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.physical.BroadcastExchangePOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.physical.ExternalGroupByPOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.physical.HashPartitionExchangePOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.physical.HashPartitionMergeExchangePOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.physical.InMemoryStableSortPOperator;
-import org.apache.hyracks.algebricks.core.algebra.operators.physical.PreSortedDistinctByPOperator;
-import org.apache.hyracks.algebricks.core.algebra.operators.physical.PreclusteredGroupByPOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.physical.RandomMergeExchangePOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.physical.RandomPartitionExchangePOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.physical.RangePartitionExchangePOperator;
@@ -123,7 +123,9 @@
         // somewhere else, too.
 
         physicalOptimizationConfig = context.getPhysicalOptimizationConfig();
-        AlgebricksConfig.ALGEBRICKS_LOGGER.debug(">>>> Optimizing operator " + op.getPhysicalOperator() + ".\n");
+        if (AlgebricksConfig.ALGEBRICKS_LOGGER.isDebugEnabled()) {
+            AlgebricksConfig.ALGEBRICKS_LOGGER.debug(">>>> Optimizing operator " + op.getPhysicalOperator() + ".\n");
+        }
 
         PhysicalOptimizationsUtil.computeFDsAndEquivalenceClasses(op, context);
 
@@ -132,8 +134,10 @@
                         new LinkedList<ILocalStructuralProperty>());
         boolean changed = physOptimizeOp(opRef, pvector, false, context);
         op.computeDeliveredPhysicalProperties(context);
-        AlgebricksConfig.ALGEBRICKS_LOGGER.trace(">>>> Structural properties for " + op.getPhysicalOperator() + ": "
-                + op.getDeliveredPhysicalProperties() + "\n");
+        if (AlgebricksConfig.ALGEBRICKS_LOGGER.isTraceEnabled()) {
+            AlgebricksConfig.ALGEBRICKS_LOGGER.trace(">>>> Structural properties for " + op.getPhysicalOperator() + ": "
+                    + op.getDeliveredPhysicalProperties() + "\n");
+        }
 
         context.addToDontApplySet(this, opRef.getValue());
 
@@ -142,6 +146,7 @@
 
     private boolean physOptimizePlan(ILogicalPlan plan, IPhysicalPropertiesVector pvector, boolean nestedPlan,
             IOptimizationContext context) throws AlgebricksException {
+        boolean loggerTraceEnabled = AlgebricksConfig.ALGEBRICKS_LOGGER.isTraceEnabled();
         boolean changed = false;
         for (Mutable<ILogicalOperator> root : plan.getRoots()) {
             if (physOptimizeOp(root, pvector, nestedPlan, context)) {
@@ -149,8 +154,10 @@
             }
             AbstractLogicalOperator op = (AbstractLogicalOperator) root.getValue();
             op.computeDeliveredPhysicalProperties(context);
-            AlgebricksConfig.ALGEBRICKS_LOGGER.trace(">>>> Structural properties for " + op.getPhysicalOperator() + ": "
-                    + op.getDeliveredPhysicalProperties() + "\n");
+            if (loggerTraceEnabled) {
+                AlgebricksConfig.ALGEBRICKS_LOGGER.trace(">>>> Structural properties for " + op.getPhysicalOperator()
+                        + ": " + op.getDeliveredPhysicalProperties() + "\n");
+            }
         }
         return changed;
     }
@@ -238,6 +245,8 @@
             }
         }
 
+        boolean loggerTraceEnabled = AlgebricksConfig.ALGEBRICKS_LOGGER.isTraceEnabled();
+
         // The child index of the child operator to optimize first.
         int startChildIndex = getStartChildIndex(op, pr, nestedPlan, context);
         IPartitioningProperty firstDeliveredPartitioning = null;
@@ -249,8 +258,10 @@
             AbstractLogicalOperator child = (AbstractLogicalOperator) op.getInputs().get(childIndex).getValue();
             IPhysicalPropertiesVector delivered = child.getDeliveredPhysicalProperties();
 
-            AlgebricksConfig.ALGEBRICKS_LOGGER
-                    .trace(">>>> Properties delivered by " + child.getPhysicalOperator() + ": " + delivered + "\n");
+            if (loggerTraceEnabled) {
+                AlgebricksConfig.ALGEBRICKS_LOGGER
+                        .trace(">>>> Properties delivered by " + child.getPhysicalOperator() + ": " + delivered + "\n");
+            }
             IPartitioningRequirementsCoordinator prc = pr.getPartitioningCoordinator();
             // Coordinates requirements by looking at the firstDeliveredPartitioning.
             Pair<Boolean, IPartitioningProperty> pbpp = prc.coordinateRequirements(
@@ -259,8 +270,10 @@
             IPhysicalPropertiesVector rqd =
                     new StructuralPropertiesVector(pbpp.second, requiredProperty.getLocalProperties());
 
-            AlgebricksConfig.ALGEBRICKS_LOGGER
-                    .trace(">>>> Required properties for " + child.getPhysicalOperator() + ": " + rqd + "\n");
+            if (loggerTraceEnabled) {
+                AlgebricksConfig.ALGEBRICKS_LOGGER
+                        .trace(">>>> Required properties for " + child.getPhysicalOperator() + ": " + rqd + "\n");
+            }
             // The partitioning property of reqdProperties[childIndex] could be updated here because
             // rqd.getPartitioningProperty() is the same object instance as requiredProperty.getPartitioningProperty().
             IPhysicalPropertiesVector diff = delivered.getUnsatisfiedPropertiesFrom(rqd,
@@ -280,7 +293,9 @@
                     delivered = newChild.getDeliveredPhysicalProperties();
                     IPhysicalPropertiesVector newDiff =
                             newPropertiesDiff(newChild, rqd, mayExpandPartitioningProperties, context);
-                    AlgebricksConfig.ALGEBRICKS_LOGGER.trace(">>>> New properties diff: " + newDiff + "\n");
+                    if (loggerTraceEnabled) {
+                        AlgebricksConfig.ALGEBRICKS_LOGGER.trace(">>>> New properties diff: " + newDiff + "\n");
+                    }
 
                     if (isRedundantSort(opRef, delivered, newDiff, context)) {
                         opIsRedundantSort = true;
@@ -304,7 +319,7 @@
         }
 
         if (opIsRedundantSort) {
-            if (AlgebricksConfig.DEBUG) {
+            if (AlgebricksConfig.DEBUG && loggerTraceEnabled) {
                 AlgebricksConfig.ALGEBRICKS_LOGGER
                         .trace(">>>> Removing redundant SORT operator " + op.getPhysicalOperator() + "\n");
                 printOp(op);
@@ -340,8 +355,10 @@
             newChildEqClasses = context.getEquivalenceClassMap(newChild);
             newChildFDs = context.getFDList(newChild);
         }
-        AlgebricksConfig.ALGEBRICKS_LOGGER.trace(
-                ">>>> Required properties for new op. " + newChild.getPhysicalOperator() + ": " + required + "\n");
+        if (AlgebricksConfig.ALGEBRICKS_LOGGER.isTraceEnabled()) {
+            AlgebricksConfig.ALGEBRICKS_LOGGER.trace(
+                    ">>>> Required properties for new op. " + newChild.getPhysicalOperator() + ": " + required + "\n");
+        }
 
         return newDelivered.getUnsatisfiedPropertiesFrom(required, mayExpandPartitioningProperties, newChildEqClasses,
                 newChildFDs);
@@ -357,15 +374,17 @@
                 hgbyOp.computeColumnSet(gby.getGroupByList());
                 break;
             }
-            case PRE_CLUSTERED_GROUP_BY: {
+            case PRE_CLUSTERED_GROUP_BY:
+            case MICRO_PRE_CLUSTERED_GROUP_BY: {
                 GroupByOperator gby = (GroupByOperator) op;
-                PreclusteredGroupByPOperator preSortedGby = (PreclusteredGroupByPOperator) pOp;
+                AbstractPreclusteredGroupByPOperator preSortedGby = (AbstractPreclusteredGroupByPOperator) pOp;
                 preSortedGby.setGbyColumns(gby.getGbyVarList());
                 break;
             }
-            case PRE_SORTED_DISTINCT_BY: {
+            case PRE_SORTED_DISTINCT_BY:
+            case MICRO_PRE_SORTED_DISTINCT_BY: {
                 DistinctOperator d = (DistinctOperator) op;
-                PreSortedDistinctByPOperator preSortedDistinct = (PreSortedDistinctByPOperator) pOp;
+                AbstractPreSortedDistinctByPOperator preSortedDistinct = (AbstractPreSortedDistinctByPOperator) pOp;
                 preSortedDistinct.setDistinctByColumns(d.getDistinctByVarList());
                 break;
             }
@@ -446,7 +465,9 @@
             }
             AbstractLogicalOperator newChild = (AbstractLogicalOperator) op.getInputs().get(childIndex).getValue();
             IPhysicalPropertiesVector newDiff = newPropertiesDiff(newChild, required, true, context);
-            AlgebricksConfig.ALGEBRICKS_LOGGER.trace(">>>> New properties diff: " + newDiff + "\n");
+            if (AlgebricksConfig.ALGEBRICKS_LOGGER.isTraceEnabled()) {
+                AlgebricksConfig.ALGEBRICKS_LOGGER.trace(">>>> New properties diff: " + newDiff + "\n");
+            }
             if (newDiff != null) {
                 addLocalEnforcers(op, childIndex, newDiff.getLocalProperties(), nestedPlan, context);
             }
@@ -455,7 +476,7 @@
 
     private void addLocalEnforcers(AbstractLogicalOperator op, int i, List<ILocalStructuralProperty> localProperties,
             boolean nestedPlan, IOptimizationContext context) throws AlgebricksException {
-        if (AlgebricksConfig.DEBUG) {
+        if (AlgebricksConfig.DEBUG && AlgebricksConfig.ALGEBRICKS_LOGGER.isTraceEnabled()) {
             AlgebricksConfig.ALGEBRICKS_LOGGER
                     .trace(">>>> Adding local enforcers for local props = " + localProperties + "\n");
         }
@@ -523,7 +544,7 @@
         }
         oo.getInputs().add(topOp);
         context.computeAndSetTypeEnvironmentForOperator(oo);
-        if (AlgebricksConfig.DEBUG) {
+        if (AlgebricksConfig.DEBUG && AlgebricksConfig.ALGEBRICKS_LOGGER.isTraceEnabled()) {
             AlgebricksConfig.ALGEBRICKS_LOGGER.trace(">>>> Added sort enforcer " + oo.getPhysicalOperator() + ".\n");
         }
         return new MutableObject<ILogicalOperator>(oo);
@@ -606,7 +627,7 @@
             exchg.setExecutionMode(AbstractLogicalOperator.ExecutionMode.PARTITIONED);
             OperatorPropertiesUtil.computeSchemaAndPropertiesRecIfNull(exchg, context);
             context.computeAndSetTypeEnvironmentForOperator(exchg);
-            if (AlgebricksConfig.DEBUG) {
+            if (AlgebricksConfig.DEBUG && AlgebricksConfig.ALGEBRICKS_LOGGER.isDebugEnabled()) {
                 AlgebricksConfig.ALGEBRICKS_LOGGER
                         .debug(">>>> Added partitioning enforcer " + exchg.getPhysicalOperator() + ".\n");
                 printOp((AbstractLogicalOperator) op);
@@ -626,7 +647,9 @@
     private void printOp(AbstractLogicalOperator op) throws AlgebricksException {
         LogicalOperatorPrettyPrintVisitor pvisitor = new LogicalOperatorPrettyPrintVisitor();
         PlanPrettyPrinter.printOperator(op, pvisitor, 0);
-        AlgebricksConfig.ALGEBRICKS_LOGGER.debug(pvisitor.get().toString());
+        if (AlgebricksConfig.ALGEBRICKS_LOGGER.isDebugEnabled()) {
+            AlgebricksConfig.ALGEBRICKS_LOGGER.debug(pvisitor.get().toString());
+        }
     }
 
     private List<OrderColumn> computeOrderColumns(IPhysicalPropertiesVector pv) {
@@ -655,8 +678,10 @@
         newOp.recomputeSchema();
         newOp.computeDeliveredPhysicalProperties(context);
         context.computeAndSetTypeEnvironmentForOperator(newOp);
-        AlgebricksConfig.ALGEBRICKS_LOGGER.trace(">>>> Structural properties for " + newOp.getPhysicalOperator() + ": "
-                + newOp.getDeliveredPhysicalProperties() + "\n");
+        if (AlgebricksConfig.ALGEBRICKS_LOGGER.isTraceEnabled()) {
+            AlgebricksConfig.ALGEBRICKS_LOGGER.trace(">>>> Structural properties for " + newOp.getPhysicalOperator()
+                    + ": " + newOp.getDeliveredPhysicalProperties() + "\n");
+        }
 
         PhysicalOptimizationsUtil.computeFDsAndEquivalenceClasses(newOp, context);
     }
diff --git a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/IntroduceGroupByForSubplanRule.java b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/IntroduceGroupByForSubplanRule.java
index c4ea604..5118bf3 100644
--- a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/IntroduceGroupByForSubplanRule.java
+++ b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/IntroduceGroupByForSubplanRule.java
@@ -201,7 +201,9 @@
             //retain the intersection
             pkVars.retainAll(producedVars);
         }
-        AlgebricksConfig.ALGEBRICKS_LOGGER.debug("Found FD for introducing group-by: " + pkVars);
+        if (AlgebricksConfig.ALGEBRICKS_LOGGER.isDebugEnabled()) {
+            AlgebricksConfig.ALGEBRICKS_LOGGER.debug("Found FD for introducing group-by: " + pkVars);
+        }
 
         Mutable<ILogicalOperator> rightRef = join.getInputs().get(1);
         LogicalVariable testForNull = null;
diff --git a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/util/JoinUtils.java b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/util/JoinUtils.java
index 0bc2a5e..555d468 100644
--- a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/util/JoinUtils.java
+++ b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/util/JoinUtils.java
@@ -109,14 +109,19 @@
         ILogicalOperator opBuild = op.getInputs().get(1).getValue();
         LogicalPropertiesVisitor.computeLogicalPropertiesDFS(opBuild, context);
         ILogicalPropertiesVector v = context.getLogicalPropertiesVector(opBuild);
-        AlgebricksConfig.ALGEBRICKS_LOGGER
-                .debug("// HybridHashJoin inner branch -- Logical properties for " + opBuild + ": " + v + "\n");
+        boolean loggerDebugEnabled = AlgebricksConfig.ALGEBRICKS_LOGGER.isDebugEnabled();
+        if (loggerDebugEnabled) {
+            AlgebricksConfig.ALGEBRICKS_LOGGER
+                    .debug("// HybridHashJoin inner branch -- Logical properties for " + opBuild + ": " + v + "\n");
+        }
         if (v != null) {
             int size2 = v.getMaxOutputFrames();
             HybridHashJoinPOperator hhj = (HybridHashJoinPOperator) op.getPhysicalOperator();
             if (size2 > 0 && size2 * hhj.getFudgeFactor() <= hhj.getMemSizeInFrames()) {
-                AlgebricksConfig.ALGEBRICKS_LOGGER
-                        .debug("// HybridHashJoin inner branch " + opBuild + " fits in memory\n");
+                if (loggerDebugEnabled) {
+                    AlgebricksConfig.ALGEBRICKS_LOGGER
+                            .debug("// HybridHashJoin inner branch " + opBuild + " fits in memory\n");
+                }
                 // maintains the local properties on the probe side
                 op.setPhysicalOperator(
                         new InMemoryHashJoinPOperator(hhj.getKind(), hhj.getPartitioningType(), hhj.getKeysLeftBranch(),
diff --git a/hyracks-fullstack/algebricks/algebricks-tests/src/test/java/org/apache/hyracks/algebricks/tests/util/AlgebricksHyracksIntegrationUtil.java b/hyracks-fullstack/algebricks/algebricks-tests/src/test/java/org/apache/hyracks/algebricks/tests/util/AlgebricksHyracksIntegrationUtil.java
index 1df9824..9b3817e 100644
--- a/hyracks-fullstack/algebricks/algebricks-tests/src/test/java/org/apache/hyracks/algebricks/tests/util/AlgebricksHyracksIntegrationUtil.java
+++ b/hyracks-fullstack/algebricks/algebricks-tests/src/test/java/org/apache/hyracks/algebricks/tests/util/AlgebricksHyracksIntegrationUtil.java
@@ -91,10 +91,14 @@
     }
 
     public static void runJob(JobSpecification spec) throws Exception {
-        AlgebricksConfig.ALGEBRICKS_LOGGER.info(spec.toJSON().toString());
+        boolean loggerInfoEnabled = AlgebricksConfig.ALGEBRICKS_LOGGER.isInfoEnabled();
+        if (loggerInfoEnabled) {
+            AlgebricksConfig.ALGEBRICKS_LOGGER.info(spec.toJSON().toString());
+        }
         JobId jobId = hcc.startJob(spec, EnumSet.of(JobFlag.PROFILE_RUNTIME));
-        AlgebricksConfig.ALGEBRICKS_LOGGER.info(jobId.toString());
+        if (loggerInfoEnabled) {
+            AlgebricksConfig.ALGEBRICKS_LOGGER.info(jobId.toString());
+        }
         hcc.waitForCompletion(jobId);
     }
-
 }
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties b/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties
index 8635efd..1846062 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties
@@ -115,7 +115,7 @@
 96 = Illegal attempt to enter empty component
 97 = Illegal attempt to exit empty component
 98 = A flush operation has failed
-99 = A merge operation has failed
+99 = A merge operation has failed. The component %1$s was found in the list of index components
 100 = Failed to shutdown event processor for %1$s
 101 = Page %1$s does not exist in file %2$s
 102 = Failed to open virtual buffer cache since it is already open
diff --git a/hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/main/java/org/apache/hyracks/data/std/util/ArrayBackedValueStorage.java b/hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/main/java/org/apache/hyracks/data/std/util/ArrayBackedValueStorage.java
index e075f4e..d5a4481 100644
--- a/hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/main/java/org/apache/hyracks/data/std/util/ArrayBackedValueStorage.java
+++ b/hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/main/java/org/apache/hyracks/data/std/util/ArrayBackedValueStorage.java
@@ -22,12 +22,22 @@
 import java.io.IOException;
 import java.util.Objects;
 
+import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IMutableValueStorage;
+import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.api.IValueReference;
 
-public class ArrayBackedValueStorage implements IMutableValueStorage {
+public class ArrayBackedValueStorage implements IMutableValueStorage, IPointable {
 
-    private final GrowableArray data = new GrowableArray();
+    private final GrowableArray data;
+
+    public ArrayBackedValueStorage(int size) {
+        data = new GrowableArray(size);
+    }
+
+    public ArrayBackedValueStorage() {
+        data = new GrowableArray();
+    }
 
     @Override
     public void reset() {
@@ -54,16 +64,15 @@
         return data.getLength();
     }
 
-    //TODO: don't swallow, but throw the exception
-    public void append(IValueReference value) {
+    public void append(IValueReference value) throws HyracksDataException {
         try {
             data.append(value);
         } catch (IOException e) {
-            e.printStackTrace();
+            throw HyracksDataException.create(e);
         }
     }
 
-    public void assign(IValueReference value) {
+    public void assign(IValueReference value) throws HyracksDataException {
         reset();
         append(value);
     }
@@ -89,4 +98,31 @@
         return Objects.equals(data, other.data);
     }
 
+    @Override
+    public void set(byte[] bytes, int start, int length) {
+        reset();
+        if (bytes != null) {
+            try {
+                data.append(bytes, start, length);
+            } catch (IOException e) {
+                throw new IllegalStateException(e);
+            }
+        }
+    }
+
+    @Override
+    public void set(IValueReference pointer) {
+        try {
+            assign(pointer);
+        } catch (HyracksDataException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    public byte[] toByteArray() {
+        byte[] byteArray = new byte[getLength()];
+        System.arraycopy(getByteArray(), getStartOffset(), byteArray, 0, getLength());
+        return byteArray;
+    }
+
 }
diff --git a/hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/main/java/org/apache/hyracks/data/std/util/GrowableArray.java b/hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/main/java/org/apache/hyracks/data/std/util/GrowableArray.java
index 994d286..12486d9 100644
--- a/hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/main/java/org/apache/hyracks/data/std/util/GrowableArray.java
+++ b/hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/main/java/org/apache/hyracks/data/std/util/GrowableArray.java
@@ -26,8 +26,18 @@
 import org.apache.hyracks.data.std.api.IValueReference;
 
 public class GrowableArray implements IDataOutputProvider {
-    private final ByteArrayAccessibleOutputStream baaos = new ByteArrayAccessibleOutputStream();
-    private final RewindableDataOutputStream dos = new RewindableDataOutputStream(baaos);
+    private final ByteArrayAccessibleOutputStream baaos;
+    private final RewindableDataOutputStream dos;
+
+    public GrowableArray() {
+        baaos = new ByteArrayAccessibleOutputStream();
+        dos = new RewindableDataOutputStream(baaos);
+    }
+
+    public GrowableArray(int size) {
+        baaos = new ByteArrayAccessibleOutputStream(size);
+        dos = new RewindableDataOutputStream(baaos);
+    }
 
     @Override
     public DataOutput getDataOutput() {
@@ -65,7 +75,11 @@
     }
 
     public void append(IValueReference value) throws IOException {
-        dos.write(value.getByteArray(), value.getStartOffset(), value.getLength());
+        append(value.getByteArray(), value.getStartOffset(), value.getLength());
+    }
+
+    public void append(byte[] data, int offset, int length) throws IOException {
+        dos.write(data, offset, length);
     }
 
     public void setSize(int bytesRequired) {
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/IIndexDataflowHelper.java b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/IIndexDataflowHelper.java
index be10b27..9e65eb2 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/IIndexDataflowHelper.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/api/IIndexDataflowHelper.java
@@ -18,11 +18,13 @@
  */
 package org.apache.hyracks.storage.am.common.api;
 
+import java.io.Closeable;
+
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.storage.common.IIndex;
 import org.apache.hyracks.storage.common.LocalResource;
 
-public interface IIndexDataflowHelper {
+public interface IIndexDataflowHelper extends Closeable {
 
     /**
      * If open throws an exception, it means that the index was not opened successfully.
@@ -36,6 +38,7 @@
      *
      * @throws HyracksDataException
      */
+    @Override
     void close() throws HyracksDataException;
 
     /**
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/api/IComponentMetadata.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/api/IComponentMetadata.java
index 5dee557..fa69d7a 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/api/IComponentMetadata.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/api/IComponentMetadata.java
@@ -19,8 +19,8 @@
 package org.apache.hyracks.storage.am.lsm.common.api;
 
 import org.apache.hyracks.api.exceptions.HyracksDataException;
-import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.api.IValueReference;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
 
 public interface IComponentMetadata {
 
@@ -41,14 +41,5 @@
      * @param value
      * @throws HyracksDataException
      */
-    void get(IValueReference key, IPointable value) throws HyracksDataException;
-
-    /**
-     * Get the value
-     *
-     * @param key
-     * @return
-     * @throws HyracksDataException
-     */
-    IValueReference get(IValueReference key) throws HyracksDataException;
+    void get(IValueReference key, ArrayBackedValueStorage value) throws HyracksDataException;
 }
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/api/IFrameOperationCallback.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/api/IFrameOperationCallback.java
index 96eb559..df78c53 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/api/IFrameOperationCallback.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/api/IFrameOperationCallback.java
@@ -18,13 +18,14 @@
  */
 package org.apache.hyracks.storage.am.lsm.common.api;
 
+import java.io.Closeable;
+
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
 /**
  * An interface that is used to enable frame level operation on indexes
  */
-@FunctionalInterface
-public interface IFrameOperationCallback {
+public interface IFrameOperationCallback extends Closeable {
     /**
      * Called once processing the frame is done before calling nextFrame on the next IFrameWriter in
      * the pipeline
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/AbstractLSMDiskComponent.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/AbstractLSMDiskComponent.java
index 633de6b..5e28b30 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/AbstractLSMDiskComponent.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/AbstractLSMDiskComponent.java
@@ -19,6 +19,7 @@
 package org.apache.hyracks.storage.am.lsm.common.impls;
 
 import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
 import org.apache.hyracks.storage.am.common.api.IMetadataPageManager;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMComponentFilter;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMComponentId;
@@ -37,6 +38,7 @@
     private static final Logger LOGGER = LogManager.getLogger();
 
     private final DiskComponentMetadata metadata;
+    private final ArrayBackedValueStorage buffer = new ArrayBackedValueStorage(Long.BYTES);
 
     // a variable cache of componentId stored in metadata.
     // since componentId is immutable, we do not want to read from metadata every time the componentId
@@ -122,7 +124,7 @@
         }
         synchronized (this) {
             if (componentId == null) {
-                componentId = LSMComponentIdUtils.readFrom(metadata);
+                componentId = LSMComponentIdUtils.readFrom(metadata, buffer);
             }
         }
         if (componentId.missing()) {
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/BlockingIOOperationCallbackWrapper.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/BlockingIOOperationCallbackWrapper.java
index 042720c..a8ee286 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/BlockingIOOperationCallbackWrapper.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/BlockingIOOperationCallbackWrapper.java
@@ -34,7 +34,7 @@
     }
 
     public synchronized void waitForIO() throws InterruptedException {
-        if (!notified) {
+        while (!notified) {
             wait();
         }
         notified = false;
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/DiskComponentMetadata.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/DiskComponentMetadata.java
index d1244ce..649989c 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/DiskComponentMetadata.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/DiskComponentMetadata.java
@@ -19,9 +19,8 @@
 package org.apache.hyracks.storage.am.lsm.common.impls;
 
 import org.apache.hyracks.api.exceptions.HyracksDataException;
-import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.api.IValueReference;
-import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
 import org.apache.hyracks.storage.am.common.api.IMetadataPageManager;
 import org.apache.hyracks.storage.am.lsm.common.api.IComponentMetadata;
 
@@ -39,17 +38,10 @@
     }
 
     @Override
-    public void get(IValueReference key, IPointable value) throws HyracksDataException {
+    public void get(IValueReference key, ArrayBackedValueStorage value) throws HyracksDataException {
         mdpManager.get(mdpManager.createMetadataFrame(), key, value);
     }
 
-    @Override
-    public IValueReference get(IValueReference key) throws HyracksDataException {
-        VoidPointable value = VoidPointable.FACTORY.createPointable();
-        get(key, value);
-        return value;
-    }
-
     public void put(MemoryComponentMetadata metadata) throws HyracksDataException {
         metadata.copy(mdpManager);
     }
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/EmptyDiskComponentMetadata.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/EmptyDiskComponentMetadata.java
index 7d1925b..d0fe8a9 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/EmptyDiskComponentMetadata.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/EmptyDiskComponentMetadata.java
@@ -19,8 +19,8 @@
 package org.apache.hyracks.storage.am.lsm.common.impls;
 
 import org.apache.hyracks.api.exceptions.HyracksDataException;
-import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.api.IValueReference;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
 
 public class EmptyDiskComponentMetadata extends DiskComponentMetadata {
     public static final EmptyDiskComponentMetadata INSTANCE = new EmptyDiskComponentMetadata();
@@ -35,12 +35,7 @@
     }
 
     @Override
-    public void get(IValueReference key, IPointable value) throws HyracksDataException {
-        throw new IllegalStateException("Attempt to read metadata of empty component");
-    }
-
-    @Override
-    public IValueReference get(IValueReference key) throws HyracksDataException {
+    public void get(IValueReference key, ArrayBackedValueStorage value) throws HyracksDataException {
         throw new IllegalStateException("Attempt to read metadata of empty component");
     }
 
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMHarness.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMHarness.java
index eed8f6e..59f48d4 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMHarness.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/LSMHarness.java
@@ -601,6 +601,7 @@
     public void scheduleMerge(ILSMIndexOperationContext ctx, ILSMIOOperationCallback callback)
             throws HyracksDataException {
         if (!getAndEnterComponents(ctx, LSMOperationType.MERGE, true)) {
+            LOGGER.info("Failed to enter components for merge operation. Calling finalize");
             ctx.setIoOperationType(LSMIOOperationType.MERGE);
             callback.afterFinalize(ctx);
             return;
@@ -871,10 +872,12 @@
             scheduleMerge(ctx, ioCallback);
         }
         IOOperationUtils.waitForIoOperation(ioCallback);
-        // ensure that merge has succeeded
-        for (ILSMDiskComponent component : toBeDeleted) {
-            if (lsmIndex.getDiskComponents().contains(component)) {
-                throw HyracksDataException.create(ErrorCode.A_MERGE_OPERATION_HAS_FAILED);
+        synchronized (opTracker) {
+            // ensure that merge has succeeded
+            for (ILSMDiskComponent component : toBeDeleted) {
+                if (lsmIndex.getDiskComponents().contains(component)) {
+                    throw HyracksDataException.create(ErrorCode.A_MERGE_OPERATION_HAS_FAILED, component.toString());
+                }
             }
         }
     }
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/MemoryComponentMetadata.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/MemoryComponentMetadata.java
index 3179790..e73fa0a 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/MemoryComponentMetadata.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/MemoryComponentMetadata.java
@@ -20,10 +20,10 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
-import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.api.IValueReference;
 import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
 import org.apache.hyracks.storage.am.common.api.IMetadataPageManager;
@@ -35,61 +35,94 @@
 
 public class MemoryComponentMetadata implements IComponentMetadata {
     private static final Logger LOGGER = LogManager.getLogger();
-    private static final byte[] empty = new byte[0];
+    private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
     private final List<org.apache.commons.lang3.tuple.Pair<IValueReference, ArrayBackedValueStorage>> store =
             new ArrayList<>();
 
     /**
      * Note: for memory metadata, it is expected that the key will be constant
+     *
+     * @throws HyracksDataException
      */
     @Override
-    public void put(IValueReference key, IValueReference value) {
-        ArrayBackedValueStorage stored = get(key);
-        if (stored == null) {
-            stored = new ArrayBackedValueStorage();
-            store.add(Pair.of(key, stored));
+    public void put(IValueReference key, IValueReference value) throws HyracksDataException {
+        lock.writeLock().lock();
+        try {
+            ArrayBackedValueStorage stored = get(key);
+            if (stored == null) {
+                stored = new ArrayBackedValueStorage();
+                store.add(Pair.of(key, stored));
+            }
+            stored.assign(value);
+        } finally {
+            lock.writeLock().unlock();
         }
-        stored.assign(value);
     }
 
     /**
      * Note: for memory metadata, it is expected that the key will be constant
+     *
+     * @throws HyracksDataException
      */
     @Override
-    public void get(IValueReference key, IPointable value) {
-        value.set(empty, 0, 0);
-        ArrayBackedValueStorage stored = get(key);
-        if (stored != null) {
-            value.set(stored);
+    public void get(IValueReference key, ArrayBackedValueStorage value) throws HyracksDataException {
+        lock.readLock().lock();
+        try {
+            value.reset();
+            ArrayBackedValueStorage stored = get(key);
+            if (stored != null) {
+                value.append(stored);
+            }
+        } finally {
+            lock.readLock().unlock();
         }
     }
 
-    @Override
-    public ArrayBackedValueStorage get(IValueReference key) {
-        for (Pair<IValueReference, ArrayBackedValueStorage> pair : store) {
-            if (pair.getKey().equals(key)) {
-                return pair.getValue();
+    private ArrayBackedValueStorage get(IValueReference key) {
+        lock.readLock().lock();
+        try {
+            for (Pair<IValueReference, ArrayBackedValueStorage> pair : store) {
+                if (pair.getKey().equals(key)) {
+                    return pair.getValue();
+                }
             }
+            return null;
+        } finally {
+            lock.readLock().unlock();
         }
-        return null;
     }
 
     public void copy(IMetadataPageManager mdpManager) throws HyracksDataException {
-        LOGGER.log(Level.INFO, "Copying Metadata into a different component");
-        ITreeIndexMetadataFrame frame = mdpManager.createMetadataFrame();
-        for (Pair<IValueReference, ArrayBackedValueStorage> pair : store) {
-            if (LOGGER.isInfoEnabled()) {
-                LOGGER.log(Level.INFO, "Copying " + pair.getKey() + " : " + pair.getValue().getLength() + " bytes");
+        lock.readLock().lock();
+        try {
+            LOGGER.log(Level.INFO, "Copying Metadata into a different component");
+            ITreeIndexMetadataFrame frame = mdpManager.createMetadataFrame();
+            for (Pair<IValueReference, ArrayBackedValueStorage> pair : store) {
+                if (LOGGER.isInfoEnabled()) {
+                    LOGGER.log(Level.INFO, "Copying " + pair.getKey() + " : " + pair.getValue().getLength() + " bytes");
+                }
+                mdpManager.put(frame, pair.getKey(), pair.getValue());
             }
-            mdpManager.put(frame, pair.getKey(), pair.getValue());
+        } finally {
+            lock.readLock().unlock();
         }
     }
 
     public void copy(DiskComponentMetadata metadata) throws HyracksDataException {
-        metadata.put(this);
+        lock.readLock().lock();
+        try {
+            metadata.put(this);
+        } finally {
+            lock.readLock().unlock();
+        }
     }
 
     public void reset() {
-        store.clear();
+        lock.writeLock().lock();
+        try {
+            store.clear();
+        } finally {
+            lock.writeLock().unlock();
+        }
     }
 }
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/util/ComponentUtils.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/util/ComponentUtils.java
index 94a3702..4b7f338 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/util/ComponentUtils.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/util/ComponentUtils.java
@@ -24,6 +24,7 @@
 import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.api.IValueReference;
 import org.apache.hyracks.data.std.primitive.LongPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
 import org.apache.hyracks.storage.am.bloomfilter.impls.BloomFilter;
 import org.apache.hyracks.storage.am.common.api.ITreeIndex;
 import org.apache.hyracks.storage.am.common.freepage.MutableArrayValueReference;
@@ -59,10 +60,10 @@
      * @throws HyracksDataException
      *             If the comopnent was a disk component and an IO error was encountered
      */
-    public static long getLong(IComponentMetadata metadata, IValueReference key, long defaultValue)
-            throws HyracksDataException {
-        IValueReference value = metadata.get(key);
-        return value == null || value.getLength() == 0 ? defaultValue
+    public static long getLong(IComponentMetadata metadata, IValueReference key, long defaultValue,
+            ArrayBackedValueStorage value) throws HyracksDataException {
+        metadata.get(key, value);
+        return value.getLength() == 0 ? defaultValue
                 : LongPointable.getLong(value.getByteArray(), value.getStartOffset());
     }
 
@@ -73,31 +74,36 @@
      *
      * @param index
      * @param key
-     * @param pointable
+     * @param value
      * @throws HyracksDataException
      */
-    public static void get(ILSMIndex index, IValueReference key, IPointable pointable) throws HyracksDataException {
+    public static void get(ILSMIndex index, IValueReference key, ArrayBackedValueStorage value)
+            throws HyracksDataException {
         boolean loggable = LOGGER.isDebugEnabled();
+        value.reset();
         if (loggable) {
             LOGGER.log(Level.DEBUG, "Getting " + key + " from index " + index);
         }
         // Lock the opTracker to ensure index components don't change
         synchronized (index.getOperationTracker()) {
-            index.getCurrentMemoryComponent().getMetadata().get(key, pointable);
-            if (pointable.getLength() == 0) {
+            ILSMMemoryComponent cmc = index.getCurrentMemoryComponent();
+            if (cmc.isReadable()) {
+                index.getCurrentMemoryComponent().getMetadata().get(key, value);
+            }
+            if (value.getLength() == 0) {
                 if (loggable) {
                     LOGGER.log(Level.DEBUG, key + " was not found in mutable memory component of " + index);
                 }
                 // was not found in the in current mutable component, search in the other in memory components
-                fromImmutableMemoryComponents(index, key, pointable);
-                if (pointable.getLength() == 0) {
+                fromImmutableMemoryComponents(index, key, value);
+                if (value.getLength() == 0) {
                     if (loggable) {
                         LOGGER.log(Level.DEBUG, key + " was not found in all immmutable memory components of " + index);
                     }
                     // was not found in the in all in memory components, search in the disk components
-                    fromDiskComponents(index, key, pointable);
+                    fromDiskComponents(index, key, value);
                     if (loggable) {
-                        if (pointable.getLength() == 0) {
+                        if (value.getLength() == 0) {
                             LOGGER.log(Level.DEBUG, key + " was not found in all disk components of " + index);
                         } else {
                             LOGGER.log(Level.DEBUG, key + " was found in disk components of " + index);
@@ -134,7 +140,7 @@
         }
     }
 
-    private static void fromDiskComponents(ILSMIndex index, IValueReference key, IPointable pointable)
+    private static void fromDiskComponents(ILSMIndex index, IValueReference key, ArrayBackedValueStorage value)
             throws HyracksDataException {
         boolean loggable = LOGGER.isDebugEnabled();
         if (loggable) {
@@ -144,15 +150,16 @@
             if (loggable) {
                 LOGGER.log(Level.DEBUG, "Getting " + key + " from disk components " + c);
             }
-            c.getMetadata().get(key, pointable);
-            if (pointable.getLength() != 0) {
+            c.getMetadata().get(key, value);
+            if (value.getLength() != 0) {
                 // Found
                 return;
             }
         }
     }
 
-    private static void fromImmutableMemoryComponents(ILSMIndex index, IValueReference key, IPointable pointable) {
+    private static void fromImmutableMemoryComponents(ILSMIndex index, IValueReference key,
+            ArrayBackedValueStorage value) throws HyracksDataException {
         boolean loggable = LOGGER.isDebugEnabled();
         if (loggable) {
             LOGGER.log(Level.DEBUG, "Getting " + key + " from immutable memory components of " + index);
@@ -174,8 +181,8 @@
             }
             ILSMMemoryComponent c = index.getMemoryComponents().get(next);
             if (c.isReadable()) {
-                c.getMetadata().get(key, pointable);
-                if (pointable.getLength() != 0) {
+                c.getMetadata().get(key, value);
+                if (value.getLength() != 0) {
                     // Found
                     return;
                 }
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/util/LSMComponentIdUtils.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/util/LSMComponentIdUtils.java
index 3c88543..6d4b0a7 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/util/LSMComponentIdUtils.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/util/LSMComponentIdUtils.java
@@ -20,6 +20,7 @@
 
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.primitive.LongPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
 import org.apache.hyracks.storage.am.common.freepage.MutableArrayValueReference;
 import org.apache.hyracks.storage.am.lsm.common.api.IComponentMetadata;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMComponentId;
@@ -37,9 +38,10 @@
 
     }
 
-    public static ILSMComponentId readFrom(IComponentMetadata metadata) throws HyracksDataException {
-        long minId = ComponentUtils.getLong(metadata, COMPONENT_ID_MIN_KEY, LSMComponentId.NOT_FOUND);
-        long maxId = ComponentUtils.getLong(metadata, COMPONENT_ID_MAX_KEY, LSMComponentId.NOT_FOUND);
+    public static ILSMComponentId readFrom(IComponentMetadata metadata, ArrayBackedValueStorage buffer)
+            throws HyracksDataException {
+        long minId = ComponentUtils.getLong(metadata, COMPONENT_ID_MIN_KEY, LSMComponentId.NOT_FOUND, buffer);
+        long maxId = ComponentUtils.getLong(metadata, COMPONENT_ID_MAX_KEY, LSMComponentId.NOT_FOUND, buffer);
         if (minId == LSMComponentId.NOT_FOUND || maxId == LSMComponentId.NOT_FOUND) {
             return LSMComponentId.MISSING_COMPONENT_ID;
         } else {