Added scalar version of all aggregate functions via a GenericScalarAggregateFunction. Added tests for them on all types, nulls, and empty streams.
git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_fix_agg@582 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_avg.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_avg.aql
new file mode 100644
index 0000000..8c8ed73
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_avg.aql
@@ -0,0 +1,19 @@
+/*
+ * Description : Tests the scalar version of avg without nulls.
+ * Success : Yes
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/aggregate_scalar_avg.adm";
+
+let $i8 := avg([int8("1"), int8("2"), int8("3")])
+let $i16 := avg([int16("1"), int16("2"), int16("3")])
+let $i32 := avg([int32("1"), int32("2"), int32("3")])
+let $i64 := avg([int64("1"), int64("2"), int64("3")])
+let $f := avg([float("1"), float("2"), float("3")])
+let $d := avg([double("1"), double("2"), double("3")])
+for $i in [$i8, $i16, $i32, $i64, $f, $d]
+return $i
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_avg_empty.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_avg_empty.aql
new file mode 100644
index 0000000..351f5f8
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_avg_empty.aql
@@ -0,0 +1,12 @@
+/*
+ * Description : Tests the scalar version of avg with an empty list.
+ * Success : Yes
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/aggregate_scalar_avg_empty.adm";
+
+avg([ ])
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_avg_null.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_avg_null.aql
new file mode 100644
index 0000000..5108573
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_avg_null.aql
@@ -0,0 +1,19 @@
+/*
+ * Description : Tests the scalar version of avg with nulls.
+ * Success : Yes
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/aggregate_scalar_avg_null.adm";
+
+let $i8 := avg([int8("1"), int8("2"), int8("3"), null])
+let $i16 := avg([int16("1"), int16("2"), int16("3"), null])
+let $i32 := avg([int32("1"), int32("2"), int32("3"), null])
+let $i64 := avg([int64("1"), int64("2"), int64("3"), null])
+let $f := avg([float("1"), float("2"), float("3"), null])
+let $d := avg([double("1"), double("2"), double("3"), null])
+for $i in [$i8, $i16, $i32, $i64, $f, $d]
+return $i
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_count.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_count.aql
new file mode 100644
index 0000000..3508fc6
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_count.aql
@@ -0,0 +1,20 @@
+/*
+ * Description : Tests the scalar version of count without nulls.
+ * Success : Yes
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/aggregate_scalar_count.adm";
+
+let $i8 := count([int8("1"), int8("2"), int8("3")])
+let $i16 := count([int16("1"), int16("2"), int16("3")])
+let $i32 := count([int32("1"), int32("2"), int32("3")])
+let $i64 := count([int64("1"), int64("2"), int64("3")])
+let $f := count([float("1"), float("2"), float("3")])
+let $d := count([double("1"), double("2"), double("3")])
+let $s := count(["a", "b", "c"])
+for $i in [$i8, $i16, $i32, $i64, $f, $d, $s]
+return $i
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_count_empty.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_count_empty.aql
new file mode 100644
index 0000000..afd3dab
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_count_empty.aql
@@ -0,0 +1,12 @@
+/*
+ * Description : Tests the scalar version of count with an empty list.
+ * Success : Yes
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/aggregate_scalar_count_empty.adm";
+
+count([ ])
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_count_null.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_count_null.aql
new file mode 100644
index 0000000..60dd19f
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_count_null.aql
@@ -0,0 +1,20 @@
+/*
+ * Description : Tests the scalar version of count with nulls.
+ * Success : Yes
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/aggregate_scalar_count_null.adm";
+
+let $i8 := count([int8("1"), int8("2"), int8("3"), null])
+let $i16 := count([int16("1"), int16("2"), int16("3"), null])
+let $i32 := count([int32("1"), int32("2"), int32("3"), null])
+let $i64 := count([int64("1"), int64("2"), int64("3"), null])
+let $f := count([float("1"), float("2"), float("3"), null])
+let $d := count([double("1"), double("2"), double("3"), null])
+let $s := count(["a", "b", "c", null])
+for $i in [$i8, $i16, $i32, $i64, $f, $d, $s]
+return $i
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_max.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_max.aql
new file mode 100644
index 0000000..1d044f8
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_max.aql
@@ -0,0 +1,19 @@
+/*
+ * Description : Tests the scalar version of max without nulls.
+ * Success : Yes
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/aggregate_scalar_max.adm";
+
+let $i8 := max([int8("1"), int8("2"), int8("3")])
+let $i16 := max([int16("1"), int16("2"), int16("3")])
+let $i32 := max([int32("1"), int32("2"), int32("3")])
+let $i64 := max([int64("1"), int64("2"), int64("3")])
+let $f := max([float("1"), float("2"), float("3")])
+let $d := max([double("1"), double("2"), double("3")])
+for $i in [$i8, $i16, $i32, $i64, $f, $d]
+return $i
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_max_empty.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_max_empty.aql
new file mode 100644
index 0000000..3a4396e
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_max_empty.aql
@@ -0,0 +1,12 @@
+/*
+ * Description : Tests the scalar version of max with an empty list.
+ * Success : Yes
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/aggregate_scalar_max_empty.adm";
+
+max([ ])
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_max_null.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_max_null.aql
new file mode 100644
index 0000000..7dcd368
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_max_null.aql
@@ -0,0 +1,19 @@
+/*
+ * Description : Tests the scalar version of max with nulls.
+ * Success : Yes
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/aggregate_scalar_max_null.adm";
+
+let $i8 := max([int8("1"), int8("2"), int8("3"), null])
+let $i16 := max([int16("1"), int16("2"), int16("3"), null])
+let $i32 := max([int32("1"), int32("2"), int32("3"), null])
+let $i64 := max([int64("1"), int64("2"), int64("3"), null])
+let $f := max([float("1"), float("2"), float("3"), null])
+let $d := max([double("1"), double("2"), double("3"), null])
+for $i in [$i8, $i16, $i32, $i64, $f, $d]
+return $i
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_min.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_min.aql
new file mode 100644
index 0000000..3089758
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_min.aql
@@ -0,0 +1,19 @@
+/*
+ * Description : Tests the scalar version of min without nulls.
+ * Success : Yes
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/aggregate_scalar_min.adm";
+
+let $i8 := min([int8("1"), int8("2"), int8("3")])
+let $i16 := min([int16("1"), int16("2"), int16("3")])
+let $i32 := min([int32("1"), int32("2"), int32("3")])
+let $i64 := min([int64("1"), int64("2"), int64("3")])
+let $f := min([float("1"), float("2"), float("3")])
+let $d := min([double("1"), double("2"), double("3")])
+for $i in [$i8, $i16, $i32, $i64, $f, $d]
+return $i
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_min_empty.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_min_empty.aql
new file mode 100644
index 0000000..e242a35
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_min_empty.aql
@@ -0,0 +1,12 @@
+/*
+ * Description : Tests the scalar version of min with an empty list.
+ * Success : Yes
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/aggregate_scalar_min_empty.adm";
+
+min([ ])
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_min_null.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_min_null.aql
new file mode 100644
index 0000000..8601228
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_min_null.aql
@@ -0,0 +1,19 @@
+/*
+ * Description : Tests the scalar version of min with nulls.
+ * Success : Yes
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/aggregate_scalar_min_null.adm";
+
+let $i8 := min([int8("1"), int8("2"), int8("3"), null])
+let $i16 := min([int16("1"), int16("2"), int16("3"), null])
+let $i32 := min([int32("1"), int32("2"), int32("3"), null])
+let $i64 := min([int64("1"), int64("2"), int64("3"), null])
+let $f := min([float("1"), float("2"), float("3"), null])
+let $d := min([double("1"), double("2"), double("3"), null])
+for $i in [$i8, $i16, $i32, $i64, $f, $d]
+return $i
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_sum.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_sum.aql
new file mode 100644
index 0000000..843360f
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_sum.aql
@@ -0,0 +1,19 @@
+/*
+ * Description : Tests the scalar version of sum without nulls.
+ * Success : Yes
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/aggregate_scalar_sum.adm";
+
+let $i8 := sum([int8("1"), int8("2"), int8("3")])
+let $i16 := sum([int16("1"), int16("2"), int16("3")])
+let $i32 := sum([int32("1"), int32("2"), int32("3")])
+let $i64 := sum([int64("1"), int64("2"), int64("3")])
+let $f := sum([float("1"), float("2"), float("3")])
+let $d := sum([double("1"), double("2"), double("3")])
+for $i in [$i8, $i16, $i32, $i64, $f, $d]
+return $i
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_sum_empty.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_sum_empty.aql
new file mode 100644
index 0000000..35bf676
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_sum_empty.aql
@@ -0,0 +1,12 @@
+/*
+ * Description : Tests the scalar version of sum with an empty list.
+ * Success : Yes
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/aggregate_scalar_sum_empty.adm";
+
+sum([ ])
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_sum_null.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_sum_null.aql
new file mode 100644
index 0000000..a4c2e61
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/scalar_sum_null.aql
@@ -0,0 +1,19 @@
+/*
+ * Description : Tests the scalar version of sum with nulls.
+ * Success : Yes
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/aggregate_scalar_sum_null.adm";
+
+let $i8 := sum([int8("1"), int8("2"), int8("3"), null])
+let $i16 := sum([int16("1"), int16("2"), int16("3"), null])
+let $i32 := sum([int32("1"), int32("2"), int32("3"), null])
+let $i64 := sum([int64("1"), int64("2"), int64("3"), null])
+let $f := sum([float("1"), float("2"), float("3"), null])
+let $d := sum([double("1"), double("2"), double("3"), null])
+for $i in [$i8, $i16, $i32, $i64, $f, $d]
+return $i
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_avg.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_avg.adm
new file mode 100644
index 0000000..483cb2f
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_avg.adm
@@ -0,0 +1,6 @@
+2.0
+2.0
+2.0
+2.0
+2.0
+2.0
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_avg_empty.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_avg_empty.adm
new file mode 100644
index 0000000..19765bd
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_avg_empty.adm
@@ -0,0 +1 @@
+null
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_avg_null.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_avg_null.adm
new file mode 100644
index 0000000..0800a91
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_avg_null.adm
@@ -0,0 +1,6 @@
+null
+null
+null
+null
+null
+null
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_count.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_count.adm
new file mode 100644
index 0000000..80f0b99
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_count.adm
@@ -0,0 +1,7 @@
+3
+3
+3
+3
+3
+3
+3
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_count_empty.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_count_empty.adm
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_count_empty.adm
@@ -0,0 +1 @@
+0
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_count_null.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_count_null.adm
new file mode 100644
index 0000000..4ff1111
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_count_null.adm
@@ -0,0 +1,7 @@
+4
+4
+4
+4
+4
+4
+4
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_max.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_max.adm
new file mode 100644
index 0000000..a2a1efe
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_max.adm
@@ -0,0 +1,6 @@
+3i8
+3i16
+3
+3i64
+3.0f
+3.0d
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_max_empty.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_max_empty.adm
new file mode 100644
index 0000000..19765bd
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_max_empty.adm
@@ -0,0 +1 @@
+null
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_max_null.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_max_null.adm
new file mode 100644
index 0000000..0800a91
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_max_null.adm
@@ -0,0 +1,6 @@
+null
+null
+null
+null
+null
+null
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_min.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_min.adm
new file mode 100644
index 0000000..ebfec4e
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_min.adm
@@ -0,0 +1,6 @@
+1i8
+1i16
+1
+1i64
+1.0f
+1.0d
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_min_empty.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_min_empty.adm
new file mode 100644
index 0000000..19765bd
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_min_empty.adm
@@ -0,0 +1 @@
+null
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_min_null.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_min_null.adm
new file mode 100644
index 0000000..0800a91
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_min_null.adm
@@ -0,0 +1,6 @@
+null
+null
+null
+null
+null
+null
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_sum.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_sum.adm
new file mode 100644
index 0000000..6e7617e
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_sum.adm
@@ -0,0 +1,6 @@
+6i8
+6i16
+6
+6i64
+6.0f
+6.0d
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_sum_empty.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_sum_empty.adm
new file mode 100644
index 0000000..19765bd
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_sum_empty.adm
@@ -0,0 +1 @@
+null
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_sum_null.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_sum_null.adm
new file mode 100644
index 0000000..0800a91
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/scalar_sum_null.adm
@@ -0,0 +1,6 @@
+null
+null
+null
+null
+null
+null
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/AOrderedlistPrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/AOrderedlistPrinterFactory.java
index 9edb640..563b14c 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/AOrderedlistPrinterFactory.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/AOrderedlistPrinterFactory.java
@@ -34,10 +34,6 @@
private ATypeTag itemTag;
private boolean typedItemList = false;
- // private int itemLength;
- // private int numberOfitems;
- // private int itemOffset;
-
@Override
public void init() throws AlgebricksException {
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/base/SingleFieldFrameTupleReference.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/base/SingleFieldFrameTupleReference.java
index a42a3e9..c0c08fd 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/base/SingleFieldFrameTupleReference.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/base/SingleFieldFrameTupleReference.java
@@ -5,12 +5,12 @@
public class SingleFieldFrameTupleReference implements IFrameTupleReference {
- private byte[] fildData;
+ private byte[] fieldData;
private int start;
private int length;
- public void reset(byte[] fildData, int start, int length) {
- this.fildData = fildData;
+ public void reset(byte[] fieldData, int start, int length) {
+ this.fieldData = fieldData;
this.start = start;
this.length = length;
}
@@ -22,7 +22,7 @@
@Override
public byte[] getFieldData(int fIdx) {
- return fildData;
+ return fieldData;
}
@Override
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/scalar/AbstractScalarAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/scalar/AbstractScalarAggregateDescriptor.java
index 17f01b9..fdf9325 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/scalar/AbstractScalarAggregateDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/scalar/AbstractScalarAggregateDescriptor.java
@@ -6,6 +6,7 @@
import edu.uci.ics.asterix.om.functions.IFunctionManager;
import edu.uci.ics.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.unnestingfunctions.std.ScanCollectionDescriptor.ScanCollectionUnnestingFunctionFactory;
import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyAggregateFunctionFactory;
@@ -24,7 +25,8 @@
@Override
public ICopyEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
- // Always access column 0.
+ // The aggregate function will get a SingleFieldFrameTupleReference that points to the result of the ScanCollection.
+ // The list-item will always reside in the first filed (column) of the SingleFieldFrameTupleReference.
ICopyEvaluatorFactory[] aggFuncArgs = new ICopyEvaluatorFactory[1];
aggFuncArgs[0] = new ColumnAccessEvalFactory(0);
// Create aggregate function from this scalar version.
@@ -33,7 +35,11 @@
IFunctionDescriptor fd = mgr.lookupFunction(fid);
AbstractAggregateFunctionDynamicDescriptor aggFuncDesc = (AbstractAggregateFunctionDynamicDescriptor) fd;
ICopyAggregateFunctionFactory aggFuncFactory = aggFuncDesc.createAggregateFunctionFactory(aggFuncArgs);
- return new GenericScalarAggregateFunction(args, aggFuncFactory.createAggregateFunction(output));
+ // Use ScanCollection to iterate over list items.
+ ScanCollectionUnnestingFunctionFactory scanCollectionFactory = new ScanCollectionUnnestingFunctionFactory(
+ args[0]);
+ return new GenericScalarAggregateFunction(aggFuncFactory.createAggregateFunction(output),
+ scanCollectionFactory);
}
};
}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/scalar/GenericScalarAggregateFunction.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/scalar/GenericScalarAggregateFunction.java
index 90e62cf..0811968 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/scalar/GenericScalarAggregateFunction.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/scalar/GenericScalarAggregateFunction.java
@@ -1,65 +1,41 @@
package edu.uci.ics.asterix.runtime.aggregates.scalar;
-import edu.uci.ics.asterix.common.exceptions.AsterixException;
-import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AOrderedListSerializerDeserializer;
-import edu.uci.ics.asterix.om.types.ATypeTag;
-import edu.uci.ics.asterix.om.types.EnumDeserializer;
-import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
import edu.uci.ics.asterix.runtime.aggregates.base.SingleFieldFrameTupleReference;
import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyAggregateFunction;
import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
-import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyUnnestingFunction;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyUnnestingFunctionFactory;
import edu.uci.ics.hyracks.data.std.util.ArrayBackedValueStorage;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
/**
- * Implements scalar aggregates via the corresponding
- * ICopyAggregateFunction which should be passed inside this function.
+ * Implements scalar aggregates by iterating over a collection with the ScanCollection unnesting function,
+ * and applying the corresponding ICopyAggregateFunction to each collection-item.
*/
public class GenericScalarAggregateFunction implements ICopyEvaluator {
- private final ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
- private final ICopyEvaluator argEval;
+ private final ArrayBackedValueStorage listItemOut = new ArrayBackedValueStorage();
private final ICopyAggregateFunction aggFunc;
+ private final ICopyUnnestingFunction scanCollection;
private final SingleFieldFrameTupleReference itemTuple = new SingleFieldFrameTupleReference();
-
- public GenericScalarAggregateFunction(ICopyEvaluatorFactory[] args, ICopyAggregateFunction aggFunc) throws AlgebricksException {
- this.argEval = args[0].createEvaluator(argOut);
+
+ public GenericScalarAggregateFunction(ICopyAggregateFunction aggFunc,
+ ICopyUnnestingFunctionFactory scanCollectionFactory) throws AlgebricksException {
this.aggFunc = aggFunc;
+ this.scanCollection = scanCollectionFactory.createUnnestingFunction(listItemOut);
+ listItemOut.reset();
}
@Override
public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
- argOut.reset();
- argEval.evaluate(tuple);
- byte[] listBytes = argOut.getByteArray();
- ATypeTag argType = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(listBytes[0]);
- switch (argType) {
- case UNORDEREDLIST: {
- break;
- }
- case ORDEREDLIST: {
- try {
- aggFunc.init();
- ATypeTag itemTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(listBytes[1]);
- int numItems = AOrderedListSerializerDeserializer.getNumberOfItems(listBytes, 0);
- for (int i = 0; i < numItems; i++) {
- int itemOffset = AOrderedListSerializerDeserializer.getItemOffset(listBytes, i);
- int itemLength = NonTaggedFormatUtil.getFieldValueLength(listBytes, itemOffset, itemTag, false);
- itemTuple.reset(listBytes, itemOffset, itemLength);
- aggFunc.step(itemTuple);
- }
- aggFunc.finish();
- } catch (AsterixException e) {
- throw new AlgebricksException(e);
- }
- break;
- }
- default: {
- throw new AlgebricksException("Unsupported type '" + argType + "' as input to scalar aggregate function.");
- }
- }
+ scanCollection.init(tuple);
+ while (scanCollection.step()) {
+ itemTuple.reset(listItemOut.getByteArray(), 0, listItemOut.getLength());
+ aggFunc.step(itemTuple);
+ listItemOut.reset();
+ }
+ aggFunc.finish();
}
}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/scalar/ScalarAvgAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/scalar/ScalarAvgAggregateDescriptor.java
new file mode 100644
index 0000000..ae2a485
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/scalar/ScalarAvgAggregateDescriptor.java
@@ -0,0 +1,22 @@
+package edu.uci.ics.asterix.runtime.aggregates.scalar;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+
+public class ScalarAvgAggregateDescriptor extends AbstractScalarAggregateDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "avg", 1);
+ public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new ScalarAvgAggregateDescriptor();
+ }
+ };
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/scalar/ScalarMaxAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/scalar/ScalarMaxAggregateDescriptor.java
new file mode 100644
index 0000000..a71eb3c
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/scalar/ScalarMaxAggregateDescriptor.java
@@ -0,0 +1,22 @@
+package edu.uci.ics.asterix.runtime.aggregates.scalar;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+
+public class ScalarMaxAggregateDescriptor extends AbstractScalarAggregateDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "max", 1);
+ public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new ScalarMaxAggregateDescriptor();
+ }
+ };
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/scalar/ScalarMinAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/scalar/ScalarMinAggregateDescriptor.java
new file mode 100644
index 0000000..4beae60
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/scalar/ScalarMinAggregateDescriptor.java
@@ -0,0 +1,22 @@
+package edu.uci.ics.asterix.runtime.aggregates.scalar;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+
+public class ScalarMinAggregateDescriptor extends AbstractScalarAggregateDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "min", 1);
+ public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new ScalarMinAggregateDescriptor();
+ }
+ };
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/scalar/ScalarSumAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/scalar/ScalarSumAggregateDescriptor.java
new file mode 100644
index 0000000..f3d9d1a
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/scalar/ScalarSumAggregateDescriptor.java
@@ -0,0 +1,22 @@
+package edu.uci.ics.asterix.runtime.aggregates.scalar;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+
+public class ScalarSumAggregateDescriptor extends AbstractScalarAggregateDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "sum", 1);
+ public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new ScalarSumAggregateDescriptor();
+ }
+ };
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/OrderedListConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/OrderedListConstructorDescriptor.java
index 496c524..af02cdd 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/OrderedListConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/OrderedListConstructorDescriptor.java
@@ -96,7 +96,7 @@
try {
for (int i = 0; i < argEvals.length; i++) {
inputVal.reset();
- argEvals[i].evaluate(tuple);
+ argEvals[i].evaluate(tuple);
builder.addItem(inputVal);
}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
index 60e29f9..268d563 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
@@ -41,7 +41,11 @@
import edu.uci.ics.asterix.om.types.AUnorderedListType;
import edu.uci.ics.asterix.om.types.IAType;
import edu.uci.ics.asterix.runtime.aggregates.collections.ListifyAggregateDescriptor;
+import edu.uci.ics.asterix.runtime.aggregates.scalar.ScalarAvgAggregateDescriptor;
import edu.uci.ics.asterix.runtime.aggregates.scalar.ScalarCountAggregateDescriptor;
+import edu.uci.ics.asterix.runtime.aggregates.scalar.ScalarMaxAggregateDescriptor;
+import edu.uci.ics.asterix.runtime.aggregates.scalar.ScalarMinAggregateDescriptor;
+import edu.uci.ics.asterix.runtime.aggregates.scalar.ScalarSumAggregateDescriptor;
import edu.uci.ics.asterix.runtime.aggregates.serializable.std.SerializableAvgAggregateDescriptor;
import edu.uci.ics.asterix.runtime.aggregates.serializable.std.SerializableCountAggregateDescriptor;
import edu.uci.ics.asterix.runtime.aggregates.serializable.std.SerializableGlobalAvgAggregateDescriptor;
@@ -323,6 +327,10 @@
// scalar aggregates
temp.add(ScalarCountAggregateDescriptor.FACTORY);
+ temp.add(ScalarAvgAggregateDescriptor.FACTORY);
+ temp.add(ScalarSumAggregateDescriptor.FACTORY);
+ temp.add(ScalarMaxAggregateDescriptor.FACTORY);
+ temp.add(ScalarMinAggregateDescriptor.FACTORY);
// new functions - constructors
temp.add(ABooleanConstructorDescriptor.FACTORY);
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/unnestingfunctions/std/ScanCollectionDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/unnestingfunctions/std/ScanCollectionDescriptor.java
index 7963b00..cf39008 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/unnestingfunctions/std/ScanCollectionDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/unnestingfunctions/std/ScanCollectionDescriptor.java
@@ -48,7 +48,7 @@
return new ScanCollectionUnnestingFunctionFactory(args[0]);
}
- private static class ScanCollectionUnnestingFunctionFactory implements ICopyUnnestingFunctionFactory {
+ public static class ScanCollectionUnnestingFunctionFactory implements ICopyUnnestingFunctionFactory {
private static final long serialVersionUID = 1L;