aod sketch to kll function
diff --git a/sql/datasketches_aod_sketch.sql b/sql/datasketches_aod_sketch.sql
index 8f26cd0..49da709 100644
--- a/sql/datasketches_aod_sketch.sql
+++ b/sql/datasketches_aod_sketch.sql
@@ -169,3 +169,11 @@
 CREATE OR REPLACE FUNCTION aod_sketch_a_not_b(aod_sketch, aod_sketch, int) RETURNS aod_sketch
     AS '$libdir/datasketches', 'pg_aod_sketch_a_not_b'
     LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OR REPLACE FUNCTION aod_sketch_to_kll_float_sketch(aod_sketch, int) RETURNS kll_float_sketch
+    AS '$libdir/datasketches', 'pg_aod_sketch_to_kll_float_sketch'
+    LANGUAGE C STRICT IMMUTABLE;
+
+CREATE OR REPLACE FUNCTION aod_sketch_to_kll_float_sketch(aod_sketch, int, int) RETURNS kll_float_sketch
+    AS '$libdir/datasketches', 'pg_aod_sketch_to_kll_float_sketch'
+    LANGUAGE C STRICT IMMUTABLE;
diff --git a/src/aod_sketch_c_adapter.cpp b/src/aod_sketch_c_adapter.cpp
index ef8e9f6..fbd28b7 100644
--- a/src/aod_sketch_c_adapter.cpp
+++ b/src/aod_sketch_c_adapter.cpp
@@ -20,6 +20,7 @@
 #include "aod_sketch_c_adapter.h"
 #include "allocator.h"
 #include "postgres_h_substitute.h"
+#include "kll_float_sketch_c_adapter.h"
 
 #include <array_of_doubles_sketch.hpp>
 #include <array_of_doubles_union.hpp>
@@ -269,3 +270,16 @@
   }
   pg_unreachable();
 }
+
+void* aod_sketch_to_kll_float_sketch(const void* sketchptr, unsigned column_index, unsigned k) {
+  try {
+    auto kllptr = kll_float_sketch_new(k);
+    for (const auto& entry: *static_cast<const compact_aod_sketch_pg*>(sketchptr)) {
+      kll_float_sketch_update(kllptr, entry.second[column_index]);
+    }
+    return kllptr;
+  } catch (std::exception& e) {
+    pg_error(e.what());
+  }
+  pg_unreachable();
+}
diff --git a/src/aod_sketch_c_adapter.h b/src/aod_sketch_c_adapter.h
index d3ed775..ebf92c7 100644
--- a/src/aod_sketch_c_adapter.h
+++ b/src/aod_sketch_c_adapter.h
@@ -24,6 +24,8 @@
 extern "C" {
 #endif
 
+#include "ptr_with_size.h"
+
 void* aod_sketch_new(unsigned num_values);
 void* aod_sketch_new_lgk(unsigned num_values, unsigned lg_k);
 void* aod_sketch_new_lgk_p(unsigned num_values, unsigned lg_k, float p);
@@ -38,11 +40,6 @@
 void** aod_sketch_get_estimate_and_bounds(const void* sketchptr, unsigned num_std_devs);
 char* aod_sketch_to_string(const void* sketchptr, bool print_entries);
 
-struct ptr_with_size {
-  void* ptr;
-  unsigned long long size;
-};
-
 struct ptr_with_size aod_sketch_serialize(const void* sketchptr, unsigned header_size);
 void* aod_sketch_deserialize(const char* buffer, unsigned length);
 
@@ -59,6 +56,8 @@
 
 void* aod_a_not_b(const void* sketchptr1, const void* sketchptr2);
 
+void* aod_sketch_to_kll_float_sketch(const void* sketchptr, unsigned column_index, unsigned k);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/aod_sketch_pg_functions.c b/src/aod_sketch_pg_functions.c
index 04feec7..825b1b2 100644
--- a/src/aod_sketch_pg_functions.c
+++ b/src/aod_sketch_pg_functions.c
@@ -26,6 +26,7 @@
 
 #include "aod_sketch_c_adapter.h"
 #include "base64.h"
+#include "kll_float_sketch_c_adapter.h"
 
 /* PG_FUNCTION_INFO_V1 macro to pass functions to postgres */
 PG_FUNCTION_INFO_V1(pg_aod_sketch_add_item);
@@ -41,6 +42,7 @@
 PG_FUNCTION_INFO_V1(pg_aod_sketch_union);
 PG_FUNCTION_INFO_V1(pg_aod_sketch_intersection);
 PG_FUNCTION_INFO_V1(pg_aod_sketch_a_not_b);
+PG_FUNCTION_INFO_V1(pg_aod_sketch_to_kll_float_sketch);
 
 /* function declarations */
 Datum pg_aod_sketch_recv(PG_FUNCTION_ARGS);
@@ -58,6 +60,7 @@
 Datum pg_aod_sketch_union(PG_FUNCTION_ARGS);
 Datum pg_aod_sketch_intersection(PG_FUNCTION_ARGS);
 Datum pg_aod_sketch_a_not_b(PG_FUNCTION_ARGS);
+Datum pg_aod_sketch_to_kll_float_sketch(PG_FUNCTION_ARGS);
 
 Datum pg_aod_sketch_add_item(PG_FUNCTION_ARGS) {
   void* sketchptr;
@@ -464,3 +467,24 @@
   SET_VARSIZE(bytes_out.ptr, bytes_out.size);
   PG_RETURN_BYTEA_P(bytes_out.ptr);
 }
+
+Datum pg_aod_sketch_to_kll_float_sketch(PG_FUNCTION_ARGS) {
+  const bytea* bytes_in;
+  void* aodptr;
+  int column_index;
+  int k;
+  void* kllptr;
+  struct ptr_with_size bytes_out;
+
+  bytes_in = PG_GETARG_BYTEA_P(0);
+  aodptr = aod_sketch_deserialize(VARDATA(bytes_in), VARSIZE(bytes_in) - VARHDRSZ);
+  column_index = PG_GETARG_INT32(1);
+  k = PG_GETARG_INT32(2);
+  if (k == 0) k = DEFAULT_K;
+  kllptr = aod_sketch_to_kll_float_sketch(aodptr, column_index, k);
+  bytes_out = kll_float_sketch_serialize(kllptr, VARHDRSZ);
+  kll_float_sketch_delete(kllptr);
+  compact_aod_sketch_delete(aodptr);
+  SET_VARSIZE(bytes_out.ptr, bytes_out.size);
+  PG_RETURN_BYTEA_P(bytes_out.ptr);
+}
diff --git a/src/cpc_sketch_c_adapter.h b/src/cpc_sketch_c_adapter.h
index 550f8e3..8df971d 100644
--- a/src/cpc_sketch_c_adapter.h
+++ b/src/cpc_sketch_c_adapter.h
@@ -24,6 +24,8 @@
 extern "C" {
 #endif
 
+#include "ptr_with_size.h"
+
 void cpc_init();
 void cpc_cleanup();
 
@@ -36,11 +38,6 @@
 void** cpc_sketch_get_estimate_and_bounds(const void* sketchptr, unsigned num_std_devs);
 char* cpc_sketch_to_string(const void* sketchptr);
 
-struct ptr_with_size {
-  void* ptr;
-  unsigned long long size;
-};
-
 struct ptr_with_size cpc_sketch_serialize(const void* sketchptr, unsigned header_size);
 void* cpc_sketch_deserialize(const char* buffer, unsigned length);
 
diff --git a/src/frequent_strings_sketch_c_adapter.h b/src/frequent_strings_sketch_c_adapter.h
index ab0fd3b..c6a8f7d 100644
--- a/src/frequent_strings_sketch_c_adapter.h
+++ b/src/frequent_strings_sketch_c_adapter.h
@@ -24,6 +24,8 @@
 extern "C" {
 #endif
 
+#include "ptr_with_size.h"
+
 void* frequent_strings_sketch_new(unsigned lg_k);
 void frequent_strings_sketch_delete(void* sketchptr);
 
@@ -31,11 +33,6 @@
 void frequent_strings_sketch_merge(void* sketchptr1, const void* sketchptr2);
 char* frequent_strings_sketch_to_string(const void* sketchptr, bool print_items);
 
-struct ptr_with_size {
-  void* ptr;
-  unsigned long long size;
-};
-
 struct ptr_with_size frequent_strings_sketch_serialize(const void* sketchptr, unsigned header_size);
 void* frequent_strings_sketch_deserialize(const char* buffer, unsigned length);
 unsigned frequent_strings_sketch_get_serialized_size_bytes(const void* sketchptr);
diff --git a/src/hll_sketch_c_adapter.h b/src/hll_sketch_c_adapter.h
index 08c2317..21ef1bd 100644
--- a/src/hll_sketch_c_adapter.h
+++ b/src/hll_sketch_c_adapter.h
@@ -24,6 +24,8 @@
 extern "C" {
 #endif
 
+#include "ptr_with_size.h"
+
 void* hll_sketch_new(unsigned lg_k);
 void* hll_sketch_new_tgt_type(unsigned lg_k, unsigned tgt_type);
 void hll_sketch_delete(void* sketchptr);
@@ -34,11 +36,6 @@
 void** hll_sketch_get_estimate_and_bounds(const void* sketchptr, unsigned num_std_devs);
 char* hll_sketch_to_string(const void* sketchptr);
 
-struct ptr_with_size {
-  void* ptr;
-  unsigned long long size;
-};
-
 struct ptr_with_size hll_sketch_serialize(const void* sketchptr, unsigned header_size);
 void* hll_sketch_deserialize(const char* buffer, unsigned length);
 
diff --git a/src/kll_float_sketch_c_adapter.h b/src/kll_float_sketch_c_adapter.h
index df98366..f175906 100644
--- a/src/kll_float_sketch_c_adapter.h
+++ b/src/kll_float_sketch_c_adapter.h
@@ -24,6 +24,10 @@
 extern "C" {
 #endif
 
+#include "ptr_with_size.h"
+
+static const unsigned DEFAULT_K = 200;
+
 void* kll_float_sketch_new(unsigned k);
 void kll_float_sketch_delete(void* sketchptr);
 
@@ -34,11 +38,6 @@
 unsigned long long kll_float_sketch_get_n(const void* sketchptr);
 char* kll_float_sketch_to_string(const void* sketchptr);
 
-struct ptr_with_size {
-  void* ptr;
-  unsigned long long size;
-};
-
 struct ptr_with_size kll_float_sketch_serialize(const void* sketchptr, unsigned header_size);
 void* kll_float_sketch_deserialize(const char* buffer, unsigned length);
 unsigned kll_float_sketch_get_serialized_size_bytes(const void* sketchptr);
diff --git a/src/kll_float_sketch_pg_functions.c b/src/kll_float_sketch_pg_functions.c
index 64df873..87426c8 100644
--- a/src/kll_float_sketch_pg_functions.c
+++ b/src/kll_float_sketch_pg_functions.c
@@ -55,7 +55,6 @@
 Datum pg_kll_float_sketch_get_quantiles(PG_FUNCTION_ARGS);
 Datum pg_kll_float_sketch_get_histogram(PG_FUNCTION_ARGS);
 
-static const unsigned DEFAULT_K = 200;
 static const unsigned DEFAULT_NUM_BINS = 10;
 
 Datum pg_kll_float_sketch_add_item(PG_FUNCTION_ARGS) {
diff --git a/src/ptr_with_size.h b/src/ptr_with_size.h
new file mode 100644
index 0000000..f130444
--- /dev/null
+++ b/src/ptr_with_size.h
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+#ifndef PTR_WITH_SIZE_H
+#define PTR_WITH_SIZE_H
+
+struct ptr_with_size {
+  void* ptr;
+  unsigned long long size;
+};
+
+#endif
diff --git a/src/theta_sketch_c_adapter.h b/src/theta_sketch_c_adapter.h
index 36e2b3a..2a14f98 100644
--- a/src/theta_sketch_c_adapter.h
+++ b/src/theta_sketch_c_adapter.h
@@ -24,6 +24,8 @@
 extern "C" {
 #endif
 
+#include "ptr_with_size.h"
+
 void* theta_sketch_new_default();
 void* theta_sketch_new_lgk(unsigned lg_k);
 void* theta_sketch_new_lgk_p(unsigned lg_k, float p);
@@ -36,11 +38,6 @@
 void** theta_sketch_get_estimate_and_bounds(const void* sketchptr, unsigned num_std_devs);
 char* theta_sketch_to_string(const void* sketchptr);
 
-struct ptr_with_size {
-  void* ptr;
-  unsigned long long size;
-};
-
 struct ptr_with_size theta_sketch_serialize(const void* sketchptr, unsigned header_size);
 void* theta_sketch_deserialize(const char* buffer, unsigned length);