From c3b3eeb6260a44753dd917ec129ff52a248effe6 Mon Sep 17 00:00:00 2001 From: Christian Zentgraf <82243552+czentgr@users.noreply.github.com> Date: Wed, 4 Feb 2026 19:37:52 -0500 Subject: [PATCH 1/3] feat(ci): Expand CVE reporting to med and low (#27081) --- .github/workflows/owasp-dependency-check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/owasp-dependency-check.yml b/.github/workflows/owasp-dependency-check.yml index 426187e40b678..2c0c731a77c40 100644 --- a/.github/workflows/owasp-dependency-check.yml +++ b/.github/workflows/owasp-dependency-check.yml @@ -18,7 +18,7 @@ jobs: group: ${{ github.workflow }}-owasp-dependency-check-${{ github.event.pull_request.number }} cancel-in-progress: true env: - CVSS_THRESHOLD: ${{ github.event.inputs.cvss-threshold || '7.0' }} + CVSS_THRESHOLD: ${{ github.event.inputs.cvss-threshold || '0.1' }} OWASP_VERSION: 12.1.3 steps: # Checkout PR branch first to get access to the composite action From 6c7dd6441d2553bf5336dedcec7b6c14b0a20550 Mon Sep 17 00:00:00 2001 From: Pramod Satya Date: Wed, 4 Feb 2026 19:04:17 -0800 Subject: [PATCH 2/3] fix(native): Fix Velox to Presto IN expression conversion (#26951) ## Description Fixes Velox to Presto `IN` expression conversion. When the `IN-list` is constant, the Velox expression representation uses a constant expression with an array vector to store the list (see conversion [here](https://github.com/prestodb/presto/blob/4e91f155d0f4704325552fac3807da0efdba6a35/presto-native-execution/presto_cpp/main/types/PrestoToVeloxExpr.cpp#L780)). The Presto `IN` expression expects the values from constant `IN-list` to be distinct arguments to the `SpecialFormExpression`. The `VeloxToPrestoExpr` is modified accordingly. ## Motivation and Context Resolves https://github.com/prestodb/presto/issues/26921. ## Impact Fixes bug with `IN` expression in native expression optimizer. ## Test Plan Added e2e test. ``` == NO RELEASE NOTE == ``` ## Summary by Sourcery Fix Velox-to-Presto conversion of IN expressions to correctly construct Presto special form arguments and add coverage for the native expression optimizer. Bug Fixes: - Correct Velox IN expression conversion when the IN-list is represented as a constant array so Presto receives individual arguments instead of a single array-typed constant. Tests: - Add an end-to-end test ensuring IN expressions are handled correctly by the native expression optimizer in the sidecar plugin test suite. --- .../main/types/VeloxToPrestoExpr.cpp | 80 ++++++++++++++++++- .../presto_cpp/main/types/VeloxToPrestoExpr.h | 11 +++ .../sidecar/TestNativeSidecarPlugin.java | 10 ++- 3 files changed, 98 insertions(+), 3 deletions(-) diff --git a/presto-native-execution/presto_cpp/main/types/VeloxToPrestoExpr.cpp b/presto-native-execution/presto_cpp/main/types/VeloxToPrestoExpr.cpp index aa8a228360c98..91e1c309d8a7e 100644 --- a/presto-native-execution/presto_cpp/main/types/VeloxToPrestoExpr.cpp +++ b/presto-native-execution/presto_cpp/main/types/VeloxToPrestoExpr.cpp @@ -17,6 +17,7 @@ #include "presto_cpp/main/types/PrestoToVeloxExpr.h" #include "velox/core/ITypedExpr.h" #include "velox/expression/ExprConstants.h" +#include "velox/vector/BaseVector.h" #include "velox/vector/ConstantVector.h" using namespace facebook::presto; @@ -161,6 +162,78 @@ VeloxToPrestoExprConverter::getSwitchSpecialFormExpressionArgs( return result; } +void VeloxToPrestoExprConverter::getArgsFromConstantInList( + const velox::core::ConstantTypedExpr* inList, + std::vector& result) const { + const auto inListVector = inList->toConstantVector(pool_); + auto* constantVector = + inListVector->as>(); + VELOX_CHECK_NOT_NULL( + constantVector, "Expected ConstantVector of Array type for IN-list."); + const auto* arrayVector = + constantVector->wrappedVector()->as(); + VELOX_CHECK_NOT_NULL( + arrayVector, + "Expected constant IN-list to be of Array type, but got {}.", + constantVector->wrappedVector()->type()->toString()); + + auto wrappedIdx = constantVector->wrappedIndex(0); + auto size = arrayVector->sizeAt(wrappedIdx); + auto offset = arrayVector->offsetAt(wrappedIdx); + auto elementsVector = arrayVector->elements(); + + for (velox::vector_size_t i = 0; i < size; i++) { + auto elementIndex = offset + i; + auto elementConstant = + velox::BaseVector::wrapInConstant(1, elementIndex, elementsVector); + // Construct a core::ConstantTypedExpr from the constant value at this + // index in array vector, then convert it to a protocol::RowExpression. + const auto constantExpr = + std::make_shared(elementConstant); + result.push_back(getConstantExpression(constantExpr.get())); + } +} + +// IN expression in Presto is of form `expr0 IN [expr1, expr2, ..., exprN]`. +// The Velox representation of IN expression has the same form as Presto when +// any of the expressions in the IN list is non-constant; when the IN list only +// has constant expressions, it is of form `expr0 IN constantExpr(ARRAY[ +// expr1.constantValue(), expr2.constantValue(), ..., exprN.constantValue()])`. +// This function retrieves the arguments to Presto IN expression from Velox IN +// expression in both of these forms. +std::vector +VeloxToPrestoExprConverter::getInSpecialFormExpressionArgs( + const velox::core::CallTypedExpr* inExpr) const { + std::vector result; + const auto& inputs = inExpr->inputs(); + const auto numInputs = inputs.size(); + VELOX_CHECK_GE(numInputs, 2, "IN expression should have at least 2 inputs"); + + // Value being searched for with this `IN` expression is always the first + // input, convert it to a Presto expression. + result.push_back(getRowExpression(inputs.at(0))); + const auto& inList = inputs.at(1); + if (numInputs == 2 && inList->isConstantKind()) { + // Converts inputs from constant Velox IN-list to arguments in the Presto + // `IN` expression. Eg: For expression `col0 IN ['apple', 'foo', `bar`]`, + // `apple`, `foo`, and `bar` from the IN-list are converted to equivalent + // Presto constant expressions. + const auto* constantInList = + inList->asUnchecked(); + getArgsFromConstantInList(constantInList, result); + } else { + // Converts inputs from the Velox IN-list to arguments in the Presto `IN` + // expression when the Velox IN-list has at least one non-constant + // expression. Eg: For expression `col0 IN ['apple', col1, 'foo']`, `apple`, + // col1, and `foo` from the IN-list are converted to equivalent + // Presto expressions. + for (auto i = 1; i < numInputs; i++) { + result.push_back(getRowExpression(inputs[i])); + } + } + return result; +} + SpecialFormExpressionPtr VeloxToPrestoExprConverter::getSpecialFormExpression( const velox::core::CallTypedExpr* expr) const { VELOX_CHECK( @@ -181,11 +254,14 @@ SpecialFormExpressionPtr VeloxToPrestoExprConverter::getSpecialFormExpression( // Arguments for switch expression include 'WHEN' special form expression(s) // so they are constructed separately. static constexpr char const* kSwitch = "SWITCH"; + static constexpr char const* kIn = "IN"; if (name == kSwitch) { result.arguments = getSwitchSpecialFormExpressionArgs(expr); + } else if (name == kIn) { + result.arguments = getInSpecialFormExpressionArgs(expr); } else { - // Presto special form expressions that are not of type `SWITCH`, such as - // `IN`, `AND`, `OR` etc,. are handled in this clause. The list of Presto + // Presto special form expressions that are not of type `SWITCH` and `IN`, + // such as `AND`, `OR`, are handled in this clause. The list of Presto // special form expressions can be found in `kPrestoSpecialForms` in the // helper function `isPrestoSpecialForm`. auto exprInputs = expr->inputs(); diff --git a/presto-native-execution/presto_cpp/main/types/VeloxToPrestoExpr.h b/presto-native-execution/presto_cpp/main/types/VeloxToPrestoExpr.h index 08e3de660e0ae..26369c7ec382e 100644 --- a/presto-native-execution/presto_cpp/main/types/VeloxToPrestoExpr.h +++ b/presto-native-execution/presto_cpp/main/types/VeloxToPrestoExpr.h @@ -81,6 +81,17 @@ class VeloxToPrestoExprConverter { std::vector getSwitchSpecialFormExpressionArgs( const velox::core::CallTypedExpr* switchExpr) const; + /// Helper function to convert values from a constant `IN` list in Velox + /// expression to equivalent Presto expressions. + void getArgsFromConstantInList( + const velox::core::ConstantTypedExpr* inList, + std::vector& result) const; + + /// Helper function to get the arguments for Presto `IN` expression from + /// Velox `IN` expression. + std::vector getInSpecialFormExpressionArgs( + const velox::core::CallTypedExpr* inExpr) const; + /// Helper function to construct a Presto `protocol::SpecialFormExpression` /// from a Velox call expression. This function should be called only on call /// expressions that map to a Presto `SpecialFormExpression`. This can be diff --git a/presto-native-sidecar-plugin/src/test/java/com/facebook/presto/sidecar/TestNativeSidecarPlugin.java b/presto-native-sidecar-plugin/src/test/java/com/facebook/presto/sidecar/TestNativeSidecarPlugin.java index 49cb71e9ffaea..f325a315fd8e1 100644 --- a/presto-native-sidecar-plugin/src/test/java/com/facebook/presto/sidecar/TestNativeSidecarPlugin.java +++ b/presto-native-sidecar-plugin/src/test/java/com/facebook/presto/sidecar/TestNativeSidecarPlugin.java @@ -653,7 +653,7 @@ public void testP4HyperLogLogWithApproxSet() // are addressed using the native expression optimizer, and it is enabled everywhere. @Test - public void testQueriesUsingNativeOptimizer() + public void testNativeExpressionOptimizer() { Session session = Session.builder(getSession()) .setSystemProperty(EXPRESSION_OPTIMIZER_NAME, "native") @@ -681,6 +681,14 @@ public void testQueriesUsingNativeOptimizer() assertQuerySucceeds(session, "SELECT * FROM (SELECT row_number() over(partition by orderstatus order by orderkey, orderstatus) rn, * from orders) WHERE rn = 1"); assertQuerySucceeds(session, "WITH t AS (SELECT linenumber, row_number() over (partition by linenumber order by linenumber) as rn FROM lineitem) SELECT * FROM t WHERE rn = 1"); assertQuerySucceeds(session, "SELECT row_number() OVER (PARTITION BY orderdate ORDER BY orderdate) FROM orders"); + + // IN expressions + assertQuerySucceeds(session, "SELECT table_name FROM information_schema.columns WHERE table_name IN ('nation', 'region')"); + assertQuerySucceeds(session, "SELECT name FROM nation WHERE nationkey NOT IN (1, 2, 3, 4, 5, 10, 11, 12, 13)"); + assertQuerySucceeds(session, "SELECT orderkey FROM lineitem WHERE shipmode IN ('TRUCK', 'FOB', 'RAIL')"); + assertQuerySucceeds(session, "SELECT table_name, COALESCE(abs(ordinal_position), 0) as abs_pos FROM information_schema.columns WHERE table_catalog = 'hive' AND table_name IN ('nation', 'region') ORDER BY table_name, ordinal_position"); + assertQuerySucceeds(session, "SELECT table_name, ordinal_position FROM information_schema.columns WHERE abs(ordinal_position) IN (1, 2, 3) AND table_catalog = 'hive' AND table_name != 'roles' ORDER BY table_name, ordinal_position"); + assertQuerySucceeds(session, "select lower(table_name) from information_schema.tables where table_name = 'lineitem' or table_name = 'LINEITEM'"); } private String generateRandomTableName() From 6fb40f02af65d48a808697efa7bb1e404418ccec Mon Sep 17 00:00:00 2001 From: Pramod Satya Date: Wed, 4 Feb 2026 20:18:20 -0800 Subject: [PATCH 3/3] fix(native): Add support for kHyperLogLog type in NativeTypeManager (#26978) ## Description Velox now supports `KHyperLogLog` type (ref: https://github.com/facebookincubator/velox/pull/15199/commits/11657034d96517d672739450c36cb4dababd8851). Adds support for this type to the `NativeTypeManager`. Also adds `KHyperLogLog` to `StandardTypes` in `presto-common` to avoid a dependency on `presto-main-base` in `presto-native-sidecar-plugin`. ## Motivation and Context Fix test failure uncovered in `presto-native-tests`. Required for https://github.com/prestodb/presto/pull/23671. ## Impact Queries with `KHyperLogLog` won't fail on sidecar enabled Presto C++ deployments. ## Test Plan Added e2e test. ``` == NO RELEASE NOTE == ``` --- .../presto/common/type/StandardTypes.java | 1 + .../com/facebook/presto/type/TypeCoercer.java | 3 +- .../KHyperLogLogAggregationFunction.java | 17 ++++++----- .../khyperloglog/KHyperLogLogFunctions.java | 17 ++++++----- .../khyperloglog/KHyperLogLogOperators.java | 11 +++---- .../MergeKHyperLogLogAggregationFunction.java | 5 ++-- .../typemanager/NativeTypeManager.java | 2 ++ .../sidecar/TestNativeSidecarPlugin.java | 29 +++++++++++++++++++ 8 files changed, 61 insertions(+), 24 deletions(-) diff --git a/presto-common/src/main/java/com/facebook/presto/common/type/StandardTypes.java b/presto-common/src/main/java/com/facebook/presto/common/type/StandardTypes.java index 2291fd8dc80e4..f2c1f408969d8 100644 --- a/presto-common/src/main/java/com/facebook/presto/common/type/StandardTypes.java +++ b/presto-common/src/main/java/com/facebook/presto/common/type/StandardTypes.java @@ -34,6 +34,7 @@ public final class StandardTypes public static final String QDIGEST = "qdigest"; public static final String TDIGEST = "tdigest"; public static final String KLL_SKETCH = "kllsketch"; + public static final String K_HYPER_LOG_LOG = "KHyperLogLog"; public static final String P4_HYPER_LOG_LOG = "P4HyperLogLog"; public static final String INTERVAL_DAY_TO_SECOND = "interval day to second"; public static final String INTERVAL_YEAR_TO_MONTH = "interval year to month"; diff --git a/presto-main-base/src/main/java/com/facebook/presto/type/TypeCoercer.java b/presto-main-base/src/main/java/com/facebook/presto/type/TypeCoercer.java index b78211b3a1290..2991eb6255a9f 100644 --- a/presto-main-base/src/main/java/com/facebook/presto/type/TypeCoercer.java +++ b/presto-main-base/src/main/java/com/facebook/presto/type/TypeCoercer.java @@ -28,7 +28,6 @@ import com.facebook.presto.common.type.VarcharType; import com.facebook.presto.metadata.FunctionAndTypeManager; import com.facebook.presto.sql.analyzer.FunctionsConfig; -import com.facebook.presto.type.khyperloglog.KHyperLogLogType; import com.facebook.presto.type.setdigest.SetDigestType; import com.google.common.collect.ImmutableList; @@ -156,7 +155,7 @@ public Optional coerceTypeBase(Type sourceType, String resultTypeBase) case StandardTypes.JSON: case StandardTypes.INTERVAL_YEAR_TO_MONTH: case StandardTypes.INTERVAL_DAY_TO_SECOND: - case KHyperLogLogType.NAME: + case StandardTypes.K_HYPER_LOG_LOG: case JoniRegexpType.NAME: case LikePatternType.NAME: case JsonPathType.NAME: diff --git a/presto-main-base/src/main/java/com/facebook/presto/type/khyperloglog/KHyperLogLogAggregationFunction.java b/presto-main-base/src/main/java/com/facebook/presto/type/khyperloglog/KHyperLogLogAggregationFunction.java index 666e1d738d7be..378586a9ee5a6 100644 --- a/presto-main-base/src/main/java/com/facebook/presto/type/khyperloglog/KHyperLogLogAggregationFunction.java +++ b/presto-main-base/src/main/java/com/facebook/presto/type/khyperloglog/KHyperLogLogAggregationFunction.java @@ -15,7 +15,6 @@ package com.facebook.presto.type.khyperloglog; import com.facebook.presto.common.block.BlockBuilder; -import com.facebook.presto.common.type.StandardTypes; import com.facebook.presto.spi.function.AggregationFunction; import com.facebook.presto.spi.function.AggregationState; import com.facebook.presto.spi.function.CombineFunction; @@ -26,6 +25,10 @@ import io.airlift.slice.Slice; import io.airlift.slice.XxHash64; +import static com.facebook.presto.common.type.StandardTypes.BIGINT; +import static com.facebook.presto.common.type.StandardTypes.DOUBLE; +import static com.facebook.presto.common.type.StandardTypes.K_HYPER_LOG_LOG; + @AggregationFunction("khyperloglog_agg") public final class KHyperLogLogAggregationFunction { @@ -34,7 +37,7 @@ public final class KHyperLogLogAggregationFunction private KHyperLogLogAggregationFunction() {} @InputFunction - public static void input(@AggregationState KHyperLogLogState state, @SqlType(StandardTypes.BIGINT) long value, @SqlType(StandardTypes.BIGINT) long uii) + public static void input(@AggregationState KHyperLogLogState state, @SqlType(BIGINT) long value, @SqlType(BIGINT) long uii) { if (state.getKHLL() == null) { state.setKHLL(new KHyperLogLog()); @@ -44,7 +47,7 @@ public static void input(@AggregationState KHyperLogLogState state, @SqlType(Sta @InputFunction @LiteralParameters("x") - public static void input(@AggregationState KHyperLogLogState state, @SqlType("varchar(x)") Slice value, @SqlType(StandardTypes.BIGINT) long uii) + public static void input(@AggregationState KHyperLogLogState state, @SqlType("varchar(x)") Slice value, @SqlType(BIGINT) long uii) { if (state.getKHLL() == null) { state.setKHLL(new KHyperLogLog()); @@ -53,14 +56,14 @@ public static void input(@AggregationState KHyperLogLogState state, @SqlType("va } @InputFunction - public static void input(@AggregationState KHyperLogLogState state, @SqlType(StandardTypes.DOUBLE) double value, @SqlType(StandardTypes.BIGINT) long uii) + public static void input(@AggregationState KHyperLogLogState state, @SqlType(DOUBLE) double value, @SqlType(BIGINT) long uii) { input(state, Double.doubleToLongBits(value), uii); } @InputFunction @LiteralParameters("x") - public static void input(@AggregationState KHyperLogLogState state, @SqlType(StandardTypes.BIGINT) long value, @SqlType("varchar(x)") Slice uii) + public static void input(@AggregationState KHyperLogLogState state, @SqlType(BIGINT) long value, @SqlType("varchar(x)") Slice uii) { input(state, value, XxHash64.hash(uii)); } @@ -74,7 +77,7 @@ public static void input(@AggregationState KHyperLogLogState state, @SqlType("va @InputFunction @LiteralParameters("x") - public static void input(@AggregationState KHyperLogLogState state, @SqlType(StandardTypes.DOUBLE) double value, @SqlType("varchar(x)") Slice uii) + public static void input(@AggregationState KHyperLogLogState state, @SqlType(DOUBLE) double value, @SqlType("varchar(x)") Slice uii) { input(state, Double.doubleToLongBits(value), XxHash64.hash(uii)); } @@ -92,7 +95,7 @@ public static void combine(@AggregationState KHyperLogLogState state, @Aggregati } } - @OutputFunction(KHyperLogLogType.NAME) + @OutputFunction(K_HYPER_LOG_LOG) public static void output(@AggregationState KHyperLogLogState state, BlockBuilder out) { SERIALIZER.serialize(state, out); diff --git a/presto-main-base/src/main/java/com/facebook/presto/type/khyperloglog/KHyperLogLogFunctions.java b/presto-main-base/src/main/java/com/facebook/presto/type/khyperloglog/KHyperLogLogFunctions.java index 5d907a6a74ca5..4e3d0dbdc7b17 100644 --- a/presto-main-base/src/main/java/com/facebook/presto/type/khyperloglog/KHyperLogLogFunctions.java +++ b/presto-main-base/src/main/java/com/facebook/presto/type/khyperloglog/KHyperLogLogFunctions.java @@ -28,6 +28,7 @@ import static com.facebook.presto.common.type.BigintType.BIGINT; import static com.facebook.presto.common.type.DoubleType.DOUBLE; +import static com.facebook.presto.common.type.StandardTypes.K_HYPER_LOG_LOG; public final class KHyperLogLogFunctions { @@ -37,14 +38,14 @@ private KHyperLogLogFunctions() @ScalarFunction @SqlType(StandardTypes.BIGINT) - public static long cardinality(@SqlType(KHyperLogLogType.NAME) Slice khll) + public static long cardinality(@SqlType(K_HYPER_LOG_LOG) Slice khll) { return KHyperLogLog.newInstance(khll).cardinality(); } @ScalarFunction @SqlType(StandardTypes.BIGINT) - public static long intersectionCardinality(@SqlType(KHyperLogLogType.NAME) Slice slice1, @SqlType(KHyperLogLogType.NAME) Slice slice2) + public static long intersectionCardinality(@SqlType(K_HYPER_LOG_LOG) Slice slice1, @SqlType(K_HYPER_LOG_LOG) Slice slice2) { KHyperLogLog khll1 = KHyperLogLog.newInstance(slice1); KHyperLogLog khll2 = KHyperLogLog.newInstance(slice2); @@ -67,7 +68,7 @@ public static long intersectionCardinality(@SqlType(KHyperLogLogType.NAME) Slice @ScalarFunction @SqlType(StandardTypes.DOUBLE) - public static double jaccardIndex(@SqlType(KHyperLogLogType.NAME) Slice slice1, @SqlType(KHyperLogLogType.NAME) Slice slice2) + public static double jaccardIndex(@SqlType(K_HYPER_LOG_LOG) Slice slice1, @SqlType(K_HYPER_LOG_LOG) Slice slice2) { KHyperLogLog khll1 = KHyperLogLog.newInstance(slice1); KHyperLogLog khll2 = KHyperLogLog.newInstance(slice2); @@ -77,7 +78,7 @@ public static double jaccardIndex(@SqlType(KHyperLogLogType.NAME) Slice slice1, @ScalarFunction @SqlType("map(bigint,double)") - public static Block uniquenessDistribution(@TypeParameter("map") Type mapType, @SqlType(KHyperLogLogType.NAME) Slice slice) + public static Block uniquenessDistribution(@TypeParameter("map") Type mapType, @SqlType(K_HYPER_LOG_LOG) Slice slice) { KHyperLogLog khll = KHyperLogLog.newInstance(slice); return uniquenessDistribution(mapType, slice, khll.getMinhashSize()); @@ -85,7 +86,7 @@ public static Block uniquenessDistribution(@TypeParameter("map") @ScalarFunction @SqlType("map(bigint,double)") - public static Block uniquenessDistribution(@TypeParameter("map") Type mapType, @SqlType(KHyperLogLogType.NAME) Slice slice, @SqlType(StandardTypes.BIGINT) long histogramSize) + public static Block uniquenessDistribution(@TypeParameter("map") Type mapType, @SqlType(K_HYPER_LOG_LOG) Slice slice, @SqlType(StandardTypes.BIGINT) long histogramSize) { KHyperLogLog khll = KHyperLogLog.newInstance(slice); @@ -102,15 +103,15 @@ public static Block uniquenessDistribution(@TypeParameter("map") @ScalarFunction @SqlType(StandardTypes.DOUBLE) - public static double reidentificationPotential(@SqlType(KHyperLogLogType.NAME) Slice khll, @SqlType(StandardTypes.BIGINT) long threshold) + public static double reidentificationPotential(@SqlType(K_HYPER_LOG_LOG) Slice khll, @SqlType(StandardTypes.BIGINT) long threshold) { return KHyperLogLog.newInstance(khll).reidentificationPotential(threshold); } @ScalarFunction - @SqlType(KHyperLogLogType.NAME) + @SqlType(K_HYPER_LOG_LOG) @SqlNullable - public static Slice mergeKhll(@SqlType("array(KHyperLogLog)") Block block) + public static Slice mergeKhll(@SqlType("array(" + K_HYPER_LOG_LOG + ")") Block block) { if (block.getPositionCount() == 0) { return null; diff --git a/presto-main-base/src/main/java/com/facebook/presto/type/khyperloglog/KHyperLogLogOperators.java b/presto-main-base/src/main/java/com/facebook/presto/type/khyperloglog/KHyperLogLogOperators.java index fd647d5f61f56..335da17837c2d 100644 --- a/presto-main-base/src/main/java/com/facebook/presto/type/khyperloglog/KHyperLogLogOperators.java +++ b/presto-main-base/src/main/java/com/facebook/presto/type/khyperloglog/KHyperLogLogOperators.java @@ -14,12 +14,13 @@ package com.facebook.presto.type.khyperloglog; -import com.facebook.presto.common.type.StandardTypes; import com.facebook.presto.spi.function.ScalarOperator; import com.facebook.presto.spi.function.SqlType; import io.airlift.slice.Slice; import static com.facebook.presto.common.function.OperatorType.CAST; +import static com.facebook.presto.common.type.StandardTypes.K_HYPER_LOG_LOG; +import static com.facebook.presto.common.type.StandardTypes.VARBINARY; public final class KHyperLogLogOperators { @@ -28,15 +29,15 @@ private KHyperLogLogOperators() } @ScalarOperator(CAST) - @SqlType(StandardTypes.VARBINARY) - public static Slice castToBinary(@SqlType(KHyperLogLogType.NAME) Slice slice) + @SqlType(VARBINARY) + public static Slice castToBinary(@SqlType(K_HYPER_LOG_LOG) Slice slice) { return slice; } @ScalarOperator(CAST) - @SqlType(KHyperLogLogType.NAME) - public static Slice castFromBinary(@SqlType(StandardTypes.VARBINARY) Slice slice) + @SqlType(K_HYPER_LOG_LOG) + public static Slice castFromBinary(@SqlType(VARBINARY) Slice slice) { return slice; } diff --git a/presto-main-base/src/main/java/com/facebook/presto/type/khyperloglog/MergeKHyperLogLogAggregationFunction.java b/presto-main-base/src/main/java/com/facebook/presto/type/khyperloglog/MergeKHyperLogLogAggregationFunction.java index c45e0bb0918b1..9c1211c73191a 100644 --- a/presto-main-base/src/main/java/com/facebook/presto/type/khyperloglog/MergeKHyperLogLogAggregationFunction.java +++ b/presto-main-base/src/main/java/com/facebook/presto/type/khyperloglog/MergeKHyperLogLogAggregationFunction.java @@ -15,6 +15,7 @@ package com.facebook.presto.type.khyperloglog; import com.facebook.presto.common.block.BlockBuilder; +import com.facebook.presto.common.type.StandardTypes; import com.facebook.presto.spi.function.AggregationFunction; import com.facebook.presto.spi.function.AggregationState; import com.facebook.presto.spi.function.CombineFunction; @@ -31,7 +32,7 @@ public final class MergeKHyperLogLogAggregationFunction private MergeKHyperLogLogAggregationFunction() {} @InputFunction - public static void input(@AggregationState KHyperLogLogState state, @SqlType(KHyperLogLogType.NAME) Slice value) + public static void input(@AggregationState KHyperLogLogState state, @SqlType(StandardTypes.K_HYPER_LOG_LOG) Slice value) { KHyperLogLog instance = KHyperLogLog.newInstance(value); merge(state, instance); @@ -53,7 +54,7 @@ private static void merge(@AggregationState KHyperLogLogState state, KHyperLogLo } } - @OutputFunction(KHyperLogLogType.NAME) + @OutputFunction(StandardTypes.K_HYPER_LOG_LOG) public static void output(@AggregationState KHyperLogLogState state, BlockBuilder out) { if (state.getKHLL() == null) { diff --git a/presto-native-sidecar-plugin/src/main/java/com/facebook/presto/sidecar/typemanager/NativeTypeManager.java b/presto-native-sidecar-plugin/src/main/java/com/facebook/presto/sidecar/typemanager/NativeTypeManager.java index 54d39931acff3..7f6098b223ea4 100644 --- a/presto-native-sidecar-plugin/src/main/java/com/facebook/presto/sidecar/typemanager/NativeTypeManager.java +++ b/presto-native-sidecar-plugin/src/main/java/com/facebook/presto/sidecar/typemanager/NativeTypeManager.java @@ -53,6 +53,7 @@ import static com.facebook.presto.common.type.StandardTypes.IPADDRESS; import static com.facebook.presto.common.type.StandardTypes.IPPREFIX; import static com.facebook.presto.common.type.StandardTypes.JSON; +import static com.facebook.presto.common.type.StandardTypes.K_HYPER_LOG_LOG; import static com.facebook.presto.common.type.StandardTypes.MAP; import static com.facebook.presto.common.type.StandardTypes.P4_HYPER_LOG_LOG; import static com.facebook.presto.common.type.StandardTypes.QDIGEST; @@ -92,6 +93,7 @@ public class NativeTypeManager DOUBLE, SMALLINT, HYPER_LOG_LOG, + K_HYPER_LOG_LOG, P4_HYPER_LOG_LOG, JSON, TIME_WITH_TIME_ZONE, diff --git a/presto-native-sidecar-plugin/src/test/java/com/facebook/presto/sidecar/TestNativeSidecarPlugin.java b/presto-native-sidecar-plugin/src/test/java/com/facebook/presto/sidecar/TestNativeSidecarPlugin.java index f325a315fd8e1..20fedd32722de 100644 --- a/presto-native-sidecar-plugin/src/test/java/com/facebook/presto/sidecar/TestNativeSidecarPlugin.java +++ b/presto-native-sidecar-plugin/src/test/java/com/facebook/presto/sidecar/TestNativeSidecarPlugin.java @@ -691,6 +691,35 @@ public void testNativeExpressionOptimizer() assertQuerySucceeds(session, "select lower(table_name) from information_schema.tables where table_name = 'lineitem' or table_name = 'LINEITEM'"); } + @Test + public void testMergeKHyperLogLog() + { + assertQuery( + "select cardinality(merge(khll)), uniqueness_distribution(merge(khll)) " + + "from (" + + " select k1, k2, khyperloglog_agg(v1, v2) khll " + + " from (values (1, 1, 2, 3), (1, 1, 4, 0), (1, 2, 90, 20), (1, 2, 87, 1), " + + " (2, 1, 11, 30), (2, 1, 11, 11), (2, 2, 9, 1), (2, 2, 87, 2)) t(k1, k2, v1, v2) " + + " group by k1, k2" + + ")"); + + // Test merge(KHyperLogLog) when there are no rows. + assertQuery( + "select cardinality(merge(khll)), uniqueness_distribution(merge(khll)) " + + "from (" + + " select khyperloglog_agg(v1, v2) khll " + + " from (values (1, 1, 2, 3)) t(k1, k2, v1, v2) " + + " where 1 = 0" + + ")"); + + // Verify merge(KHyperLogLog) handles null states correctly. + assertQuery( + "select cardinality(merge(khll)), uniqueness_distribution(merge(khll)) " + + "from (" + + " select CAST(null AS KHYPERLOGLOG) khll" + + ")"); + } + private String generateRandomTableName() { String tableName = "tmp_presto_" + UUID.randomUUID().toString().replace("-", "");