This is an automated email from the ASF dual-hosted git repository.

alsuliman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 32fa9412b7 [ASTERIXDB-3446][RT] Do not use pools in CastTypeEvaluator
32fa9412b7 is described below

commit 32fa9412b7298c5b39097a1b1c5f444b4e27357c
Author: Ali Alsuliman <[email protected]>
AuthorDate: Thu Jul 11 23:40:37 2024 +0300

    [ASTERIXDB-3446][RT] Do not use pools in CastTypeEvaluator
    
    - user model changes: no
    - storage format changes: no
    - interface changes: no
    
    Details:
    Do not use pools in CastTypeEvaluator since that is not
    needed.
    - Use separate caster that uses pool for array functions.
    
    Ext-ref: MB-62691
    Change-Id: I0df95d19e652b97a86144ee5d56ca92596ab5c95
    Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/18466
    Integration-Tests: Jenkins <[email protected]>
    Tested-by: Ali Alsuliman <[email protected]>
    Reviewed-by: Ali Alsuliman <[email protected]>
    Reviewed-by: Murtadha Hubail <[email protected]>
---
 .../array_append/array_append.1.ddl.sqlpp          |  7 +-
 .../array_append/array_append.2.update.sqlpp       |  5 ++
 ...pend.4.ddl.sqlpp => array_append.4.query.sqlpp} |  6 +-
 ...append.4.ddl.sqlpp => array_append.9.ddl.sqlpp} |  0
 .../array_fun/array_append/array_append.4.adm      |  2 +
 .../functions/AbstractArrayAddRemoveEval.java      | 16 ++--
 .../functions/AbstractArrayProcessArraysEval.java  |  8 +-
 .../functions/ArrayFlattenDescriptor.java          |  9 +--
 .../functions/ArrayIntersectDescriptor.java        |  7 +-
 .../functions/ArrayReplaceEvaluator.java           | 10 +--
 .../evaluators/functions/ArrayStarDescriptor.java  |  8 +-
 .../evaluators/functions/CastTypeEvaluator.java    | 88 +++++++++-------------
 .../{CastTypeEvaluator.java => TypeCaster.java}    | 75 +++++-------------
 13 files changed, 97 insertions(+), 144 deletions(-)

diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.1.ddl.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.1.ddl.sqlpp
index 1c55a9a5d0..e2ea074340 100755
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.1.ddl.sqlpp
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.1.ddl.sqlpp
@@ -52,5 +52,10 @@ id: int,
 compType: t1
 };
 
+create type t3 AS {
+id: int
+};
+
 create  dataset TweetMessages(TweetMessageType) primary key tweetid hints 
(`CARDINALITY`=`100`);
-create dataset d1(t2) primary key id;
\ No newline at end of file
+create dataset d1(t2) primary key id;
+create dataset d3(t3) primary key id;
\ No newline at end of file
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.2.update.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.2.update.sqlpp
index 1c4bad0031..e320513d7f 100755
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.2.update.sqlpp
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.2.update.sqlpp
@@ -24,4 +24,9 @@ load  dataset TweetMessages using localfs 
((`path`=`asterix_nc1://data/tinysocia
 insert into d1([
 {"id":1, "compType":{"sth":33}},
 {"id":2, "compType":{"sth":44}, "followers":["John Green", "Emily Jones"]}
+]);
+
+insert into d3([
+{"id":1, "list_f": [99],           "compType":{"sth":33}, "s": 1},
+{"id":2, "list_f": [88, {"a": 8}], "compType":[{"sth":44}, {"sth2": [1,2]}], 
"s": 2}
 ]);
\ No newline at end of file
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.4.ddl.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.4.query.sqlpp
similarity index 88%
copy from 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.4.ddl.sqlpp
copy to 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.4.query.sqlpp
index 3f8c8ec49a..061dd7fc92 100755
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.4.ddl.sqlpp
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.4.query.sqlpp
@@ -17,4 +17,8 @@
  * under the License.
  */
 
-drop  dataverse TinySocial;
\ No newline at end of file
+USE TinySocial;
+
+FROM d3 AS d
+SELECT array_append(d.list_f, d.compType, d.s) AS append_result
+ORDER BY d.id;
\ No newline at end of file
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.4.ddl.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.9.ddl.sqlpp
similarity index 100%
rename from 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.4.ddl.sqlpp
rename to 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.9.ddl.sqlpp
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_append/array_append.4.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_append/array_append.4.adm
new file mode 100644
index 0000000000..b7e6002b0a
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_append/array_append.4.adm
@@ -0,0 +1,2 @@
+{ "append_result": [ 99, { "sth": 33 }, 1 ] }
+{ "append_result": [ 88, { "a": 8 }, [ { "sth": 44 }, { "sth2": [ 1, 2 ] } ], 
2 ] }
\ No newline at end of file
diff --git 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractArrayAddRemoveEval.java
 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractArrayAddRemoveEval.java
index f65bf30238..95c062cbbf 100755
--- 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractArrayAddRemoveEval.java
+++ 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractArrayAddRemoveEval.java
@@ -52,7 +52,7 @@ public abstract class AbstractArrayAddRemoveEval implements 
IScalarEvaluator {
     private final IPointable[] valuesArgs;
     private final IScalarEvaluator listArgEval;
     private final IScalarEvaluator[] valuesEval;
-    private final CastTypeEvaluator caster;
+    private final TypeCaster caster;
     private final ListAccessor listAccessor;
     private final int listOffset;
     private final int valuesOffset;
@@ -71,7 +71,7 @@ public abstract class AbstractArrayAddRemoveEval implements 
IScalarEvaluator {
         orderedListBuilder = null;
         unorderedListBuilder = null;
         listAccessor = new ListAccessor();
-        caster = new CastTypeEvaluator(null);
+        caster = new TypeCaster(null);
         storage = new ArrayBackedValueStorage();
         listArg = new VoidPointable();
         tempList = new VoidPointable();
@@ -130,8 +130,10 @@ public abstract class AbstractArrayAddRemoveEval 
implements IScalarEvaluator {
                 // cast val to open if needed. don't cast if function will 
return null anyway, e.g. list arg not list
                 defaultOpenType = 
DefaultOpenFieldType.getDefaultOpenFieldType(argTypes[i + 
valuesOffset].getTypeTag());
                 if (defaultOpenType != null && !returnNull && makeOpen) {
-                    caster.resetAndAllocate(defaultOpenType, argTypes[i + 
valuesOffset], valuesEval[i]);
-                    caster.evaluate(tuple, valuesArgs[i]);
+                    valuesEval[i].evaluate(tuple, tempItem);
+                    if 
(!PointableHelper.checkAndSetMissingOrNull(valuesArgs[i], tempItem)) {
+                        caster.allocateAndCast(tempItem, argTypes[i + 
valuesOffset], valuesArgs[i], defaultOpenType);
+                    }
                 } else {
                     valuesEval[i].evaluate(tuple, valuesArgs[i]);
                 }
@@ -162,8 +164,7 @@ public abstract class AbstractArrayAddRemoveEval implements 
IScalarEvaluator {
                 if (makeOpen || argTypes[listOffset].getTypeTag() != 
ATypeTag.ARRAY) {
                     listType = 
DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE;
                     // TODO(ali): maybe casting isn't needed if compile-time 
type=ANY if guaranteed input list is open
-                    caster.resetAndAllocate(listType, argTypes[listOffset], 
listArgEval);
-                    caster.cast(tempList, listArg);
+                    caster.allocateAndCast(tempList, argTypes[listOffset], 
listArg, listType);
                 } else {
                     listType = (AbstractCollectionType) argTypes[listOffset];
                     listArg.set(tempList);
@@ -175,8 +176,7 @@ public abstract class AbstractArrayAddRemoveEval implements 
IScalarEvaluator {
                 listBuilder = unorderedListBuilder;
                 if (makeOpen || argTypes[listOffset].getTypeTag() != 
ATypeTag.MULTISET) {
                     listType = 
DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE;
-                    caster.resetAndAllocate(listType, argTypes[listOffset], 
listArgEval);
-                    caster.cast(tempList, listArg);
+                    caster.allocateAndCast(tempList, argTypes[listOffset], 
listArg, listType);
                 } else {
                     listType = (AbstractCollectionType) argTypes[listOffset];
                     listArg.set(tempList);
diff --git 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractArrayProcessArraysEval.java
 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractArrayProcessArraysEval.java
index 052b79dec7..401f9fc480 100755
--- 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractArrayProcessArraysEval.java
+++ 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractArrayProcessArraysEval.java
@@ -56,7 +56,7 @@ public abstract class AbstractArrayProcessArraysEval 
implements IScalarEvaluator
     private final IObjectPool<IPointable, Void> pointablePool;
     private final IObjectPool<IMutableValueStorage, Void> storageAllocator;
     private final IAType[] argTypes;
-    private final CastTypeEvaluator caster;
+    private final TypeCaster caster;
     private OrderedListBuilder orderedListBuilder;
     private UnorderedListBuilder unorderedListBuilder;
 
@@ -68,7 +68,7 @@ public abstract class AbstractArrayProcessArraysEval 
implements IScalarEvaluator
         storageAllocator = new 
ListObjectPool<>(ObjectFactories.STORAGE_FACTORY);
         finalResult = new ArrayBackedValueStorage();
         listAccessor = new ListAccessor();
-        caster = new CastTypeEvaluator(null);
+        caster = new TypeCaster(sourceLoc);
         tempList = new VoidPointable();
         listsArgs = new IPointable[args.length];
         listsEval = new IScalarEvaluator[args.length];
@@ -111,9 +111,7 @@ public abstract class AbstractArrayProcessArraysEval 
implements IScalarEvaluator
                         if (outList == null) {
                             outList = (AbstractCollectionType) 
DefaultOpenFieldType.getDefaultOpenFieldType(listTag);
                         }
-
-                        caster.resetAndAllocate(outList, argTypes[i], 
listsEval[i]);
-                        caster.cast(tempList, listsArgs[i]);
+                        caster.allocateAndCast(tempList, argTypes[i], 
listsArgs[i], outList);
                     }
                 }
             }
diff --git 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayFlattenDescriptor.java
 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayFlattenDescriptor.java
index 72d6c3d58b..67c0da9d40 100644
--- 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayFlattenDescriptor.java
+++ 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayFlattenDescriptor.java
@@ -127,7 +127,7 @@ public class ArrayFlattenDescriptor extends 
AbstractScalarFunctionDynamicDescrip
         private final TaggedValuePointable depthArg;
         private final IObjectPool<IMutableValueStorage, ATypeTag> 
storageAllocator;
         private final IObjectPool<ListAccessor, ATypeTag> 
listAccessorAllocator;
-        private final CastTypeEvaluator caster;
+        private final TypeCaster caster;
         private final ArrayBackedValueStorage finalStorage;
         private ArrayBackedValueStorage storage;
         private IAsterixListBuilder orderedListBuilder;
@@ -141,7 +141,7 @@ public class ArrayFlattenDescriptor extends 
AbstractScalarFunctionDynamicDescrip
             depthEval = args[1].createScalarEvaluator(ctx);
             list = new VoidPointable();
             pointable = new VoidPointable();
-            caster = new CastTypeEvaluator(null);
+            caster = new TypeCaster(sourceLoc);
             depthArg = new TaggedValuePointable();
             orderedListBuilder = null;
             unorderedListBuilder = null;
@@ -172,9 +172,8 @@ public class ArrayFlattenDescriptor extends 
AbstractScalarFunctionDynamicDescrip
             }
 
             try {
-                
caster.resetAndAllocate(DefaultOpenFieldType.getDefaultOpenFieldType(listType), 
inputListType,
-                        listEval);
-                caster.cast(pointable, list);
+                caster.allocateAndCast(pointable, inputListType, list,
+                        
DefaultOpenFieldType.getDefaultOpenFieldType(listType));
 
                 int depthInt = (int) depth;
                 // create list
diff --git 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayIntersectDescriptor.java
 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayIntersectDescriptor.java
index c33222d7c8..25a01caffb 100755
--- 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayIntersectDescriptor.java
+++ 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayIntersectDescriptor.java
@@ -179,7 +179,7 @@ public class ArrayIntersectDescriptor extends 
AbstractScalarFunctionDynamicDescr
         private final IObjectPool<List<ValueListIndex>, ATypeTag> 
arrayListAllocator;
         private final IObjectPool<ValueListIndex, ATypeTag> 
valueListIndexAllocator;
         private final ArrayBackedValueStorage finalResult;
-        private final CastTypeEvaluator caster;
+        private final TypeCaster caster;
         private final IBinaryComparator comp;
         private IAsterixListBuilder orderedListBuilder;
         private IAsterixListBuilder unorderedListBuilder;
@@ -194,7 +194,7 @@ public class ArrayIntersectDescriptor extends 
AbstractScalarFunctionDynamicDescr
             hashes = new Int2ObjectOpenHashMap<>();
             finalResult = new ArrayBackedValueStorage();
             listAccessor = new ListAccessor();
-            caster = new CastTypeEvaluator(null);
+            caster = new TypeCaster(sourceLoc);
             // for functions that accept multiple lists arguments, they will 
be casted to open, hence item is ANY
             comp = BinaryComparatorFactoryProvider.INSTANCE
                     .getBinaryComparatorFactory(BuiltinType.ANY, 
BuiltinType.ANY, true).createBinaryComparator();
@@ -247,8 +247,7 @@ public class ArrayIntersectDescriptor extends 
AbstractScalarFunctionDynamicDescr
                                         (AbstractCollectionType) 
DefaultOpenFieldType.getDefaultOpenFieldType(listTag);
                             }
 
-                            caster.resetAndAllocate(outList, argTypes[i], 
listsEval[i]);
-                            caster.cast(pointable, listsArgs[i]);
+                            caster.allocateAndCast(pointable, argTypes[i], 
listsArgs[i], outList);
                             nextSize = getNumItems(outList, 
listsArgs[i].getByteArray(), listsArgs[i].getStartOffset());
                             if (nextSize < minSize || minSize == -1) {
                                 minSize = nextSize;
diff --git 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayReplaceEvaluator.java
 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayReplaceEvaluator.java
index aeda168a17..74eb3e10f2 100644
--- 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayReplaceEvaluator.java
+++ 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayReplaceEvaluator.java
@@ -86,7 +86,7 @@ public class ArrayReplaceEvaluator extends AbstractScalarEval 
{
     private final ListAccessor listAccessor;
     private final IBinaryComparator comp;
     private final ArrayBackedValueStorage storage;
-    private final CastTypeEvaluator caster;
+    private final TypeCaster caster;
     private IAsterixListBuilder orderedListBuilder;
     private IAsterixListBuilder unorderedListBuilder;
 
@@ -108,7 +108,7 @@ public class ArrayReplaceEvaluator extends 
AbstractScalarEval {
         tempVal = new VoidPointable();
         item = new VoidPointable();
         listAccessor = new ListAccessor();
-        caster = new CastTypeEvaluator(null);
+        caster = new TypeCaster(sourceLocation);
         orderedListBuilder = null;
         unorderedListBuilder = null;
 
@@ -157,12 +157,10 @@ public class ArrayReplaceEvaluator extends 
AbstractScalarEval {
         }
         try {
             IAType defaultOpenType = 
DefaultOpenFieldType.getDefaultOpenFieldType(listType);
-            caster.resetAndAllocate(defaultOpenType, inputListType, listEval);
-            caster.cast(tempList, list);
+            caster.allocateAndCast(tempList, inputListType, list, 
defaultOpenType);
             defaultOpenType = 
DefaultOpenFieldType.getDefaultOpenFieldType(newValTag);
             if (defaultOpenType != null) {
-                caster.resetAndAllocate(defaultOpenType, newValueType, 
newValEval);
-                caster.cast(tempVal, newVal);
+                caster.allocateAndCast(tempVal, newValueType, newVal, 
defaultOpenType);
             } else {
                 newVal.set(tempVal);
             }
diff --git 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayStarDescriptor.java
 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayStarDescriptor.java
index 78d8d3664e..ae11178b45 100755
--- 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayStarDescriptor.java
+++ 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayStarDescriptor.java
@@ -182,7 +182,7 @@ public class ArrayStarDescriptor extends 
AbstractScalarFunctionDynamicDescriptor
         private final IPointable list;
         private final IPointable tempList;
         private final IPointable object;
-        private final CastTypeEvaluator caster;
+        private final TypeCaster caster;
         private final ListAccessor listAccessor;
         private final RecordBuilder recordBuilder;
         private final IAsterixListBuilder listBuilder;
@@ -198,7 +198,7 @@ public class ArrayStarDescriptor extends 
AbstractScalarFunctionDynamicDescriptor
             list = new VoidPointable();
             tempList = new VoidPointable();
             listEval = args[0].createScalarEvaluator(ctx);
-            caster = new CastTypeEvaluator(null);
+            caster = new TypeCaster(sourceLoc);
             listAccessor = new ListAccessor();
             recordBuilder = new RecordBuilder();
             listBuilder = new OrderedListBuilder();
@@ -225,8 +225,8 @@ public class ArrayStarDescriptor extends 
AbstractScalarFunctionDynamicDescriptor
             }
 
             try {
-                
caster.resetAndAllocate(DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE, 
inputListType, listEval);
-                caster.cast(tempList, list);
+                caster.allocateAndCast(tempList, inputListType, list,
+                        DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE);
 
                 tempMinHeap.clear();
                 fieldNameToValuesList.clear();
diff --git 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastTypeEvaluator.java
 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastTypeEvaluator.java
index 50f6417e56..6be4483c3b 100644
--- 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastTypeEvaluator.java
+++ 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastTypeEvaluator.java
@@ -30,8 +30,6 @@ import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.om.types.EnumDeserializer;
 import org.apache.asterix.om.types.IAType;
 import org.apache.asterix.om.types.TypeTagUtil;
-import org.apache.asterix.om.util.container.IObjectPool;
-import org.apache.asterix.om.util.container.ListObjectPool;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.api.exceptions.SourceLocation;
@@ -42,34 +40,27 @@ import 
org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 public class CastTypeEvaluator implements IScalarEvaluator {
 
     private final IPointable argPointable = new VoidPointable();
-    private final IObjectPool<AFlatValueCastingPointable, IAType> 
flatValuePool =
-            new ListObjectPool<>(AFlatValueCastingPointable.FACTORY);
-    private final IObjectPool<ARecordCastingPointable, IAType> recordValuePool 
=
-            new ListObjectPool<>(ARecordCastingPointable.FACTORY);
-    private final IObjectPool<AListCastingPointable, IAType> listValuePool =
-            new ListObjectPool<>(AListCastingPointable.FACTORY);
-    private IScalarEvaluator argEvaluator;
+    private final IScalarEvaluator argEvaluator;
     protected final SourceLocation sourceLoc;
     private ICastingPointable inputPointable;
+    private ICastingPointable record;
+    private ICastingPointable list;
+    private ICastingPointable flat;
     private final ACastingPointableVisitor castVisitor = createCastVisitor();
     private final CastResult castResult = new CastResult(new VoidPointable(), 
null);
-    private boolean inputTypeIsAny;
-
-    public CastTypeEvaluator(SourceLocation sourceLoc) {
-        this.sourceLoc = sourceLoc;
-        // reset() should be called after using this constructor before 
calling any method
-    }
+    private final boolean inputTypeIsAny;
 
     public CastTypeEvaluator(IAType reqType, IAType inputType, 
IScalarEvaluator argEvaluator,
             SourceLocation sourceLoc) {
         this.sourceLoc = sourceLoc;
-        resetAndAllocate(reqType, inputType, argEvaluator);
-    }
-
-    public void resetAndAllocate(IAType reqType, IAType inputType, 
IScalarEvaluator argEvaluator) {
         this.argEvaluator = argEvaluator;
-        this.inputPointable = allocatePointable(inputType);
         this.castResult.setOutType(reqType);
+        if (!inputType.equals(BuiltinType.ANY)) {
+            this.inputPointable = createPointable(inputType);
+            this.inputTypeIsAny = false;
+        } else {
+            this.inputTypeIsAny = true;
+        }
     }
 
     protected ACastingPointableVisitor createCastVisitor() {
@@ -79,20 +70,11 @@ public class CastTypeEvaluator implements IScalarEvaluator {
     @Override
     public void evaluate(IFrameTupleReference tuple, IPointable result) throws 
HyracksDataException {
         argEvaluator.evaluate(tuple, argPointable);
-
         if (PointableHelper.checkAndSetMissingOrNull(result, argPointable)) {
             return;
         }
-
-        cast(argPointable, result);
-    }
-
-    // TODO(ali): refactor in a better way
-    protected void cast(IPointable argPointable, IPointable result) throws 
HyracksDataException {
         if (inputTypeIsAny) {
-            ATypeTag inTag = EnumDeserializer.ATYPETAGDESERIALIZER
-                    
.deserialize(argPointable.getByteArray()[argPointable.getStartOffset()]);
-            inputPointable = 
allocateForInput(TypeTagUtil.getBuiltinTypeByTag(inTag));
+            inputPointable = getPointable(argPointable);
         }
         inputPointable.set(argPointable);
         castInto(result);
@@ -103,35 +85,37 @@ public class CastTypeEvaluator implements IScalarEvaluator 
{
         result.set(castResult.getOutPointable());
     }
 
-    private ICastingPointable allocatePointable(IAType inputType) {
-        if (!inputType.equals(BuiltinType.ANY)) {
-            inputTypeIsAny = false;
-            return allocateForInput(inputType);
-        } else {
-            inputTypeIsAny = true;
-            return null;
+    private static ICastingPointable createPointable(IAType type) {
+        switch (type.getTypeTag()) {
+            case OBJECT:
+                return ARecordCastingPointable.FACTORY.create(type);
+            case ARRAY:
+            case MULTISET:
+                return AListCastingPointable.FACTORY.create(type);
+            default:
+                return AFlatValueCastingPointable.FACTORY.create(type);
         }
     }
 
-    private ICastingPointable allocateForInput(IAType inputType) {
-        ICastingPointable pointable;
-        switch (inputType.getTypeTag()) {
+    private ICastingPointable getPointable(IPointable arg) throws 
HyracksDataException {
+        ATypeTag tag = 
EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(arg.getByteArray()[arg.getStartOffset()]);
+        switch (tag) {
             case OBJECT:
-                pointable = recordValuePool.allocate(inputType);
-                break;
+                if (record == null) {
+                    record = 
ARecordCastingPointable.FACTORY.create(TypeTagUtil.getBuiltinTypeByTag(tag));
+                }
+                return record;
             case ARRAY:
             case MULTISET:
-                pointable = listValuePool.allocate(inputType);
-                break;
+                if (list == null) {
+                    list = 
AListCastingPointable.FACTORY.create(TypeTagUtil.getBuiltinTypeByTag(tag));
+                }
+                return list;
             default:
-                pointable = flatValuePool.allocate(null);
+                if (flat == null) {
+                    flat = AFlatValueCastingPointable.FACTORY.create(null);
+                }
+                return flat;
         }
-        return pointable;
-    }
-
-    public void deallocatePointables() {
-        flatValuePool.reset();
-        listValuePool.reset();
-        recordValuePool.reset();
     }
 }
diff --git 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastTypeEvaluator.java
 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/TypeCaster.java
similarity index 54%
copy from 
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastTypeEvaluator.java
copy to 
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/TypeCaster.java
index 50f6417e56..670b44d0ca 100644
--- 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastTypeEvaluator.java
+++ 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/TypeCaster.java
@@ -32,88 +32,47 @@ import org.apache.asterix.om.types.IAType;
 import org.apache.asterix.om.types.TypeTagUtil;
 import org.apache.asterix.om.util.container.IObjectPool;
 import org.apache.asterix.om.util.container.ListObjectPool;
-import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.api.exceptions.SourceLocation;
 import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.primitive.VoidPointable;
-import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 
-public class CastTypeEvaluator implements IScalarEvaluator {
+public class TypeCaster {
 
-    private final IPointable argPointable = new VoidPointable();
     private final IObjectPool<AFlatValueCastingPointable, IAType> 
flatValuePool =
             new ListObjectPool<>(AFlatValueCastingPointable.FACTORY);
     private final IObjectPool<ARecordCastingPointable, IAType> recordValuePool 
=
             new ListObjectPool<>(ARecordCastingPointable.FACTORY);
     private final IObjectPool<AListCastingPointable, IAType> listValuePool =
             new ListObjectPool<>(AListCastingPointable.FACTORY);
-    private IScalarEvaluator argEvaluator;
-    protected final SourceLocation sourceLoc;
-    private ICastingPointable inputPointable;
-    private final ACastingPointableVisitor castVisitor = createCastVisitor();
     private final CastResult castResult = new CastResult(new VoidPointable(), 
null);
-    private boolean inputTypeIsAny;
+    private final ACastingPointableVisitor castVisitor;
 
-    public CastTypeEvaluator(SourceLocation sourceLoc) {
-        this.sourceLoc = sourceLoc;
-        // reset() should be called after using this constructor before 
calling any method
+    public TypeCaster(SourceLocation sourceLoc) {
+        this.castVisitor = new ACastingPointableVisitor(true, sourceLoc);
     }
 
-    public CastTypeEvaluator(IAType reqType, IAType inputType, 
IScalarEvaluator argEvaluator,
-            SourceLocation sourceLoc) {
-        this.sourceLoc = sourceLoc;
-        resetAndAllocate(reqType, inputType, argEvaluator);
-    }
-
-    public void resetAndAllocate(IAType reqType, IAType inputType, 
IScalarEvaluator argEvaluator) {
-        this.argEvaluator = argEvaluator;
-        this.inputPointable = allocatePointable(inputType);
-        this.castResult.setOutType(reqType);
-    }
-
-    protected ACastingPointableVisitor createCastVisitor() {
-        return ACastingPointableVisitor.strictCasting(sourceLoc);
-    }
-
-    @Override
-    public void evaluate(IFrameTupleReference tuple, IPointable result) throws 
HyracksDataException {
-        argEvaluator.evaluate(tuple, argPointable);
-
-        if (PointableHelper.checkAndSetMissingOrNull(result, argPointable)) {
-            return;
-        }
-
-        cast(argPointable, result);
-    }
-
-    // TODO(ali): refactor in a better way
-    protected void cast(IPointable argPointable, IPointable result) throws 
HyracksDataException {
-        if (inputTypeIsAny) {
-            ATypeTag inTag = EnumDeserializer.ATYPETAGDESERIALIZER
-                    
.deserialize(argPointable.getByteArray()[argPointable.getStartOffset()]);
-            inputPointable = 
allocateForInput(TypeTagUtil.getBuiltinTypeByTag(inTag));
-        }
-        inputPointable.set(argPointable);
-        castInto(result);
-    }
-
-    protected void castInto(IPointable result) throws HyracksDataException {
+    protected void allocateAndCast(IPointable argPointable, IAType argType, 
IPointable result, IAType reqType)
+            throws HyracksDataException {
+        castResult.setOutType(reqType);
+        ICastingPointable inputPointable = allocate(argPointable, argType);
         inputPointable.accept(castVisitor, castResult);
         result.set(castResult.getOutPointable());
     }
 
-    private ICastingPointable allocatePointable(IAType inputType) {
-        if (!inputType.equals(BuiltinType.ANY)) {
-            inputTypeIsAny = false;
-            return allocateForInput(inputType);
+    private ICastingPointable allocate(IPointable arg, IAType argType) throws 
HyracksDataException {
+        ICastingPointable p;
+        if (!argType.equals(BuiltinType.ANY)) {
+            p = allocate(argType);
         } else {
-            inputTypeIsAny = true;
-            return null;
+            ATypeTag tag = 
EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(arg.getByteArray()[arg.getStartOffset()]);
+            p = allocate(TypeTagUtil.getBuiltinTypeByTag(tag));
         }
+        p.set(arg);
+        return p;
     }
 
-    private ICastingPointable allocateForInput(IAType inputType) {
+    private ICastingPointable allocate(IAType inputType) {
         ICastingPointable pointable;
         switch (inputType.getTypeTag()) {
             case OBJECT:

Reply via email to