From 3f65b92e7a64fac28d59ee8fb4289976ed8f8178 Mon Sep 17 00:00:00 2001
From: Alex Behm <alex.behm@cloudera.com>
Date: Thu, 9 Nov 2017 10:52:49 -0800
Subject: [PATCH] Add ConstTest() agg fn.

Change-Id: I4b3d2ab9eb1fa8663ca1cd2c31d8a70dbd13e8f1
---
 be/src/exprs/aggregate-functions-ir.cc             | 39 ++++++++++++++++++++++
 be/src/exprs/aggregate-functions.h                 |  7 ++++
 .../java/org/apache/impala/catalog/BuiltinsDb.java | 10 ++++++
 3 files changed, 56 insertions(+)

diff --git a/be/src/exprs/aggregate-functions-ir.cc b/be/src/exprs/aggregate-functions-ir.cc
index 049344e..d5020e8 100644
--- a/be/src/exprs/aggregate-functions-ir.cc
+++ b/be/src/exprs/aggregate-functions-ir.cc
@@ -1437,6 +1437,45 @@ BigIntVal AggregateFunctions::HllFinalize(FunctionContext* ctx, const StringVal&
   return estimate;
 }
 
+void AggregateFunctions::ConstTestInit(FunctionContext* ctx, BigIntVal* dst) {
+  DoubleVal* second_arg = reinterpret_cast<DoubleVal*>(ctx->GetConstantArg(1));
+  if (second_arg != nullptr) {
+    LOG(ERROR) << "ConstTestInit() got const 2nd arg: " << second_arg->val;
+  } else {
+    LOG(ERROR) << "ConstTestInit() const 2nd arg not set";
+  }
+}
+
+void AggregateFunctions::ConstTestUpdate(FunctionContext* ctx, const BigIntVal& src,
+    const DoubleVal& const_arg, BigIntVal* dst) {
+  DoubleVal* second_arg = reinterpret_cast<DoubleVal*>(ctx->GetConstantArg(1));
+  if (second_arg != nullptr) {
+    LOG(ERROR) << "ConstTestUpdate() got const 2nd arg: " << second_arg->val;
+  } else {
+    LOG(ERROR) << "ConstTestUpdate() const 2nd arg not set";
+  }
+}
+
+void AggregateFunctions::ConstTestMerge(FunctionContext* ctx, const BigIntVal& src,
+    const DoubleVal& const_arg, BigIntVal* dst) {
+  DoubleVal* second_arg = reinterpret_cast<DoubleVal*>(ctx->GetConstantArg(1));
+  if (second_arg != nullptr) {
+    LOG(ERROR) << "ConstTestMerge() got const 2nd arg: " << second_arg->val;
+  } else {
+    LOG(ERROR) << "ConstTestMerge() const 2nd arg not set";
+  }
+}
+
+BigIntVal AggregateFunctions::ConstTestFinalize(FunctionContext* ctx, const BigIntVal& src) {
+  DoubleVal* second_arg = reinterpret_cast<DoubleVal*>(ctx->GetConstantArg(1));
+  if (second_arg != nullptr) {
+    LOG(ERROR) << "ConstTestFinalize() got const 2nd arg: " << second_arg->val;
+  } else {
+    LOG(ERROR) << "ConstTestFinalize() const 2nd arg not set";
+  }
+  return BigIntVal(0);
+}
+
 // An implementation of a simple single pass variance algorithm. A standard UDA must
 // be single pass (i.e. does not scan the table more than once), so the most canonical
 // two pass approach is not practical.
diff --git a/be/src/exprs/aggregate-functions.h b/be/src/exprs/aggregate-functions.h
index 5ebcb97..184c2e0 100644
--- a/be/src/exprs/aggregate-functions.h
+++ b/be/src/exprs/aggregate-functions.h
@@ -204,6 +204,13 @@ class AggregateFunctions {
   /// estimates.
   static uint64_t HllFinalEstimate(const uint8_t* buckets, int32_t num_buckets);
 
+  static void ConstTestInit(FunctionContext* ctx, BigIntVal* dst);
+  static void ConstTestUpdate(FunctionContext* ctx, const BigIntVal& src,
+      const DoubleVal& const_arg, BigIntVal* dst);
+  static void ConstTestMerge(FunctionContext* ctx, const BigIntVal& src,
+      const DoubleVal& const_arg, BigIntVal* dst);
+  static BigIntVal ConstTestFinalize(FunctionContext* ctx, const BigIntVal& src);
+
   /// Knuth's variance algorithm, more numerically stable than canonical stddev
   /// algorithms; reference implementation:
   /// http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Online_algorithm
diff --git a/fe/src/main/java/org/apache/impala/catalog/BuiltinsDb.java b/fe/src/main/java/org/apache/impala/catalog/BuiltinsDb.java
index 07699d3..1777879 100644
--- a/fe/src/main/java/org/apache/impala/catalog/BuiltinsDb.java
+++ b/fe/src/main/java/org/apache/impala/catalog/BuiltinsDb.java
@@ -705,6 +705,16 @@ public class BuiltinsDb extends Db {
         prefix + "15CountStarRemoveEPN10impala_udf15FunctionContextEPNS1_9BigIntValE",
         null, false, true, true));
 
+    // ConstTest()
+    db.addBuiltin(AggregateFunction.createBuiltin(db, "const_test",
+        Lists.<Type>newArrayList(Type.BIGINT, Type.DOUBLE), Type.BIGINT, Type.BIGINT,
+        prefix + "13ConstTestInitEPN10impala_udf15FunctionContextEPNS1_9BigIntValE",
+        prefix + "15ConstTestUpdateEPN10impala_udf15FunctionContextERKNS1_9BigIntValERKNS1_9DoubleValEPS4_",
+        prefix + "14ConstTestMergeEPN10impala_udf15FunctionContextERKNS1_9BigIntValERKNS1_9DoubleValEPS4_",
+        null,
+        prefix + "17ConstTestFinalizeEPN10impala_udf15FunctionContextERKNS1_9BigIntValE",
+        true, false, true));
+
     for (Type t: Type.getSupportedTypes()) {
       if (t.isNull()) continue; // NULL is handled through type promotion.
       if (t.isScalarType(PrimitiveType.CHAR)) continue; // promoted to STRING
-- 
2.7.4

