From 821cfd875b3c64cd4739e1587df5ad939fad7f7f Mon Sep 17 00:00:00 2001 From: PHILO-HE Date: Sun, 23 Jun 2024 17:32:12 +0800 Subject: [PATCH] Move to separate file --- velox/functions/sparksql/CMakeLists.txt | 1 + velox/functions/sparksql/ConcatWs.cpp | 357 ++++++++++++++++++++++++ velox/functions/sparksql/ConcatWs.h | 28 ++ velox/functions/sparksql/Register.cpp | 1 + velox/functions/sparksql/String.cpp | 335 ---------------------- velox/functions/sparksql/String.h | 7 - 6 files changed, 387 insertions(+), 342 deletions(-) create mode 100644 velox/functions/sparksql/ConcatWs.cpp create mode 100644 velox/functions/sparksql/ConcatWs.h diff --git a/velox/functions/sparksql/CMakeLists.txt b/velox/functions/sparksql/CMakeLists.txt index 6ba9c03c6c79..536cd141f1e9 100644 --- a/velox/functions/sparksql/CMakeLists.txt +++ b/velox/functions/sparksql/CMakeLists.txt @@ -18,6 +18,7 @@ add_library( ArraySort.cpp Bitwise.cpp Comparisons.cpp + ConcatWs.cpp DecimalArithmetic.cpp DecimalCompare.cpp Hash.cpp diff --git a/velox/functions/sparksql/ConcatWs.cpp b/velox/functions/sparksql/ConcatWs.cpp new file mode 100644 index 000000000000..880cdf82432e --- /dev/null +++ b/velox/functions/sparksql/ConcatWs.cpp @@ -0,0 +1,357 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * Licensed 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. + */ +#include "velox/functions/sparksql/ConcatWs.h" +#include "velox/expression/VectorFunction.h" + +namespace facebook::velox::functions::sparksql { +class ConcatWs : public exec::VectorFunction { + public: + explicit ConcatWs(const std::optional& separator) + : separator_(separator) {} + + // Calculate the total number of bytes in the result. + size_t calculateTotalResultBytes( + const SelectivityVector& rows, + exec::EvalCtx& context, + std::vector& decodedArrays, + const std::vector& constantStrings, + const std::vector& decodedStringArgs, + const exec::LocalDecodedVector& decodedSeparator) const { + auto arrayArgNum = decodedArrays.size(); + std::vector arrayVectors; + std::vector elementsDecodedVectors; + for (auto i = 0; i < arrayArgNum; ++i) { + auto arrayVector = decodedArrays[i].get()->base()->as(); + arrayVectors.push_back(arrayVector); + auto elements = arrayVector->elements(); + exec::LocalSelectivityVector nestedRows(context, elements->size()); + nestedRows.get()->setAll(); + exec::LocalDecodedVector elementsHolder( + context, *elements, *nestedRows.get()); + elementsDecodedVectors.push_back(elementsHolder.get()); + } + + size_t totalResultBytes = 0; + rows.applyToSelected([&](auto row) { + int32_t allElements = 0; + // Calculate size for array columns data. + for (int i = 0; i < arrayArgNum; i++) { + auto arrayVector = arrayVectors[i]; + auto rawSizes = arrayVector->rawSizes(); + auto rawOffsets = arrayVector->rawOffsets(); + auto indices = decodedArrays[i].get()->indices(); + auto elementsDecoded = elementsDecodedVectors[i]; + + auto size = rawSizes[indices[row]]; + auto offset = rawOffsets[indices[row]]; + for (int j = 0; j < size; ++j) { + if (!elementsDecoded->isNullAt(offset + j)) { + auto element = elementsDecoded->valueAt(offset + j); + // No matter empty string or not. + allElements++; + totalResultBytes += element.size(); + } + } + } + + // Calculate size for string arg. + auto it = decodedStringArgs.begin(); + for (int i = 0; i < constantStrings.size(); i++) { + StringView value; + if (!constantStrings[i].empty()) { + value = StringView(constantStrings[i]); + } else { + // Skip NULL. + if ((*it)->isNullAt(row)) { + ++it; + continue; + } + value = (*it++)->valueAt(row); + } + // No matter empty string or not. + allElements++; + totalResultBytes += value.size(); + } + + int32_t separatorSize = separator_.has_value() + ? separator_.value().size() + : decodedSeparator->valueAt(row).size(); + + if (allElements > 1 && separatorSize > 0) { + totalResultBytes += (allElements - 1) * separatorSize; + } + }); + return totalResultBytes; + } + + void initVectors( + const SelectivityVector& rows, + const std::vector& args, + const exec::EvalCtx& context, + std::vector& decodedArrays, + std::vector& argMapping, + std::vector& constantStrings, + std::vector& decodedStringArgs) const { + for (auto i = 1; i < args.size(); ++i) { + if (args[i] && args[i]->typeKind() == TypeKind::ARRAY) { + decodedArrays.emplace_back(context, *args[i], rows); + continue; + } + // Handles string arg. + argMapping.push_back(i); + if (!separator_.has_value()) { + // Cannot concat consecutive constant string args in advance. + constantStrings.push_back(""); + continue; + } + if (args[i] && args[i]->as>() && + !args[i]->as>()->isNullAt(0)) { + std::ostringstream out; + out << args[i]->as>()->valueAt(0); + column_index_t j = i + 1; + // Concat constant string args in advance. + for (; j < args.size(); ++j) { + if (!args[j] || args[j]->typeKind() == TypeKind::ARRAY || + !args[j]->as>() || + args[j]->as>()->isNullAt(0)) { + break; + } + out << separator_.value() + << args[j]->as>()->valueAt(0); + } + constantStrings.emplace_back(out.str()); + i = j - 1; + } else { + constantStrings.push_back(""); + } + } + + // Number of string columns after combined consecutive constant ones. + auto numStringCols = constantStrings.size(); + for (auto i = 0; i < numStringCols; ++i) { + if (constantStrings[i].empty()) { + auto index = argMapping[i]; + decodedStringArgs.emplace_back(context, *args[index], rows); + } + } + } + + // ConcatWs implementation. It concatenates the arguments with the separator. + // Mixed using of VARCHAR & ARRAY is considered. If separator is + // constant, concatenate consecutive constant string args in advance. Then, + // concatenate the intemediate result with neighboring array args or + // non-constant string args. + void doApply( + const SelectivityVector& rows, + std::vector& args, + exec::EvalCtx& context, + FlatVector& flatResult) const { + std::vector argMapping; + std::vector constantStrings; + auto numArgs = args.size(); + argMapping.reserve(numArgs - 1); + // Save intermediate result for consecutive constant string args. + // They will be concatenated in advance. + constantStrings.reserve(numArgs - 1); + std::vector decodedArrays; + decodedArrays.reserve(numArgs - 1); + // For column string arg decoding. + std::vector decodedStringArgs; + decodedStringArgs.reserve(numArgs); + + initVectors( + rows, + args, + context, + decodedArrays, + argMapping, + constantStrings, + decodedStringArgs); + exec::LocalDecodedVector decodedSeparator(context); + if (!separator_.has_value()) { + decodedSeparator = exec::LocalDecodedVector(context, *args[0], rows); + } + + auto totalResultBytes = calculateTotalResultBytes( + rows, + context, + decodedArrays, + constantStrings, + decodedStringArgs, + decodedSeparator); + + std::vector arrayVectors; + std::vector elementsDecodedVectors; + for (auto i = 0; i < decodedArrays.size(); ++i) { + auto arrayVector = decodedArrays[i].get()->base()->as(); + arrayVectors.push_back(arrayVector); + auto elements = arrayVector->elements(); + exec::LocalSelectivityVector nestedRows(context, elements->size()); + nestedRows.get()->setAll(); + exec::LocalDecodedVector elementsHolder( + context, *elements, *nestedRows.get()); + elementsDecodedVectors.push_back(elementsHolder.get()); + } + // Allocate a string buffer. + auto rawBuffer = + flatResult.getRawStringBufferWithSpace(totalResultBytes, true); + rows.applyToSelected([&](auto row) { + const char* start = rawBuffer; + auto isFirst = true; + // For array arg. + int32_t i = 0; + // For string arg. + int32_t j = 0; + auto it = decodedStringArgs.begin(); + + auto copyToBuffer = [&](StringView value, StringView separator) { + if (isFirst) { + isFirst = false; + } else { + // Add separator before the current value. + if (!separator.empty()) { + memcpy(rawBuffer, separator.data(), separator.size()); + rawBuffer += separator.size(); + } + } + if (!value.empty()) { + memcpy(rawBuffer, value.data(), value.size()); + rawBuffer += value.size(); + } + }; + + for (auto itArgs = args.begin() + 1; itArgs != args.end(); ++itArgs) { + if ((*itArgs)->typeKind() == TypeKind::ARRAY) { + auto arrayVector = arrayVectors[i]; + auto rawSizes = arrayVector->rawSizes(); + auto rawOffsets = arrayVector->rawOffsets(); + auto indices = decodedArrays[i].get()->indices(); + auto elementsDecoded = elementsDecodedVectors[i]; + + auto size = rawSizes[indices[row]]; + auto offset = rawOffsets[indices[row]]; + for (int k = 0; k < size; ++k) { + if (!elementsDecoded->isNullAt(offset + k)) { + auto element = elementsDecoded->valueAt(offset + k); + copyToBuffer( + element, + separator_.has_value() + ? StringView(separator_.value()) + : decodedSeparator->valueAt(row)); + } + } + i++; + continue; + } + + if (j >= constantStrings.size()) { + continue; + } + + StringView value; + if (!constantStrings[j].empty()) { + value = StringView(constantStrings[j]); + } else { + // Skip NULL. + if ((*it)->isNullAt(row)) { + ++it; + continue; + } + value = (*it++)->valueAt(row); + } + copyToBuffer( + value, + separator_.has_value() + ? StringView(separator_.value()) + : decodedSeparator->valueAt(row)); + j++; + } + flatResult.setNoCopy(row, StringView(start, rawBuffer - start)); + }); + } + + void apply( + const SelectivityVector& rows, + std::vector& args, + const TypePtr& /* outputType */, + exec::EvalCtx& context, + VectorPtr& result) const override { + context.ensureWritable(rows, VARCHAR(), result); + auto flatResult = result->asFlatVector(); + auto numArgs = args.size(); + // If separator is NULL, result is NULL. + if (args[0]->isNullAt(0)) { + rows.applyToSelected([&](auto row) { result->setNull(row, true); }); + return; + } + // If only separator (not a NULL) is provided, result is an empty string. + if (numArgs == 1) { + rows.applyToSelected( + [&](auto row) { flatResult->setNoCopy(row, StringView("")); }); + return; + } + doApply(rows, args, context, *flatResult); + } + + private: + // For holding constant separator. + const std::optional separator_; +}; + +std::vector> concatWsSignatures() { + return {// The second and folowing arguments are varchar or array(varchar). + // Use "any" to allow the mixed using of these two types. The + // argument type will be checked in makeConcatWs. + // + // varchar, [varchar], [array(varchar)], ... -> varchar. + exec::FunctionSignatureBuilder() + .returnType("varchar") + .argumentType("varchar") + .argumentType("any") + .variableArity() + .build()}; +} + +std::shared_ptr makeConcatWs( + const std::string& name, + const std::vector& inputArgs, + const core::QueryConfig& /*config*/) { + auto numArgs = inputArgs.size(); + VELOX_USER_CHECK_GE( + numArgs, + 1, + "concat_ws requires one arguments at least, but got {}.", + numArgs); + for (const auto& arg : inputArgs) { + VELOX_USER_CHECK( + arg.type->isVarchar() || + (arg.type->isArray() && + arg.type->asArray().elementType()->isVarchar()), + "concat_ws requires varchar or array(varchar) arguments, but got {}.", + arg.type->toString()); + } + + BaseVector* constantSeparator = inputArgs[0].constantValue.get(); + std::optional separator = std::nullopt; + if (constantSeparator != nullptr) { + separator = + constantSeparator->as>()->valueAt(0).str(); + } + + return std::make_shared(separator); +} + +} \ No newline at end of file diff --git a/velox/functions/sparksql/ConcatWs.h b/velox/functions/sparksql/ConcatWs.h new file mode 100644 index 000000000000..1d5e8b6463f1 --- /dev/null +++ b/velox/functions/sparksql/ConcatWs.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * Licensed 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. + */ +#pragma once + +#include +#include "velox/expression/VectorFunction.h" + +namespace facebook::velox::functions::sparksql { +std::vector> concatWsSignatures(); + +std::shared_ptr makeConcatWs( + const std::string& name, + const std::vector& inputArgs, + const core::QueryConfig& config); +} // namespace facebook::velox::functions::sparksql diff --git a/velox/functions/sparksql/Register.cpp b/velox/functions/sparksql/Register.cpp index 1a39be13c30c..679b1a58a967 100644 --- a/velox/functions/sparksql/Register.cpp +++ b/velox/functions/sparksql/Register.cpp @@ -29,6 +29,7 @@ #include "velox/functions/sparksql/ArrayMinMaxFunction.h" #include "velox/functions/sparksql/ArraySort.h" #include "velox/functions/sparksql/Bitwise.h" +#include "velox/functions/sparksql/ConcatWs.h" #include "velox/functions/sparksql/DateTimeFunctions.h" #include "velox/functions/sparksql/Hash.h" #include "velox/functions/sparksql/In.h" diff --git a/velox/functions/sparksql/String.cpp b/velox/functions/sparksql/String.cpp index 7be0ac1d0f50..288e875166c9 100644 --- a/velox/functions/sparksql/String.cpp +++ b/velox/functions/sparksql/String.cpp @@ -103,299 +103,7 @@ class Length : public exec::VectorFunction { } }; -class ConcatWs : public exec::VectorFunction { - public: - explicit ConcatWs(const std::optional& separator) - : separator_(separator) {} - // Calculate the total number of bytes in the result. - size_t calculateTotalResultBytes( - const SelectivityVector& rows, - exec::EvalCtx& context, - std::vector& decodedArrays, - const std::vector& constantStrings, - const std::vector& decodedStringArgs, - const exec::LocalDecodedVector& decodedSeparator) const { - auto arrayArgNum = decodedArrays.size(); - std::vector arrayVectors; - std::vector elementsDecodedVectors; - for (auto i = 0; i < arrayArgNum; ++i) { - auto arrayVector = decodedArrays[i].get()->base()->as(); - arrayVectors.push_back(arrayVector); - auto elements = arrayVector->elements(); - exec::LocalSelectivityVector nestedRows(context, elements->size()); - nestedRows.get()->setAll(); - exec::LocalDecodedVector elementsHolder( - context, *elements, *nestedRows.get()); - elementsDecodedVectors.push_back(elementsHolder.get()); - } - - size_t totalResultBytes = 0; - rows.applyToSelected([&](auto row) { - int32_t allElements = 0; - // Calculate size for array columns data. - for (int i = 0; i < arrayArgNum; i++) { - auto arrayVector = arrayVectors[i]; - auto rawSizes = arrayVector->rawSizes(); - auto rawOffsets = arrayVector->rawOffsets(); - auto indices = decodedArrays[i].get()->indices(); - auto elementsDecoded = elementsDecodedVectors[i]; - - auto size = rawSizes[indices[row]]; - auto offset = rawOffsets[indices[row]]; - for (int j = 0; j < size; ++j) { - if (!elementsDecoded->isNullAt(offset + j)) { - auto element = elementsDecoded->valueAt(offset + j); - // No matter empty string or not. - allElements++; - totalResultBytes += element.size(); - } - } - } - - // Calculate size for string arg. - auto it = decodedStringArgs.begin(); - for (int i = 0; i < constantStrings.size(); i++) { - StringView value; - if (!constantStrings[i].empty()) { - value = StringView(constantStrings[i]); - } else { - // Skip NULL. - if ((*it)->isNullAt(row)) { - ++it; - continue; - } - value = (*it++)->valueAt(row); - } - // No matter empty string or not. - allElements++; - totalResultBytes += value.size(); - } - - int32_t separatorSize = separator_.has_value() - ? separator_.value().size() - : decodedSeparator->valueAt(row).size(); - - if (allElements > 1 && separatorSize > 0) { - totalResultBytes += (allElements - 1) * separatorSize; - } - }); - return totalResultBytes; - } - - void initVectors( - const SelectivityVector& rows, - const std::vector& args, - const exec::EvalCtx& context, - std::vector& decodedArrays, - std::vector& argMapping, - std::vector& constantStrings, - std::vector& decodedStringArgs) const { - for (auto i = 1; i < args.size(); ++i) { - if (args[i] && args[i]->typeKind() == TypeKind::ARRAY) { - decodedArrays.emplace_back(context, *args[i], rows); - continue; - } - // Handles string arg. - argMapping.push_back(i); - if (!separator_.has_value()) { - // Cannot concat consecutive constant string args in advance. - constantStrings.push_back(""); - continue; - } - if (args[i] && args[i]->as>() && - !args[i]->as>()->isNullAt(0)) { - std::ostringstream out; - out << args[i]->as>()->valueAt(0); - column_index_t j = i + 1; - // Concat constant string args in advance. - for (; j < args.size(); ++j) { - if (!args[j] || args[j]->typeKind() == TypeKind::ARRAY || - !args[j]->as>() || - args[j]->as>()->isNullAt(0)) { - break; - } - out << separator_.value() - << args[j]->as>()->valueAt(0); - } - constantStrings.emplace_back(out.str()); - i = j - 1; - } else { - constantStrings.push_back(""); - } - } - - // Number of string columns after combined consecutive constant ones. - auto numStringCols = constantStrings.size(); - for (auto i = 0; i < numStringCols; ++i) { - if (constantStrings[i].empty()) { - auto index = argMapping[i]; - decodedStringArgs.emplace_back(context, *args[index], rows); - } - } - } - - // ConcatWs implementation. It concatenates the arguments with the separator. - // Mixed using of VARCHAR & ARRAY is considered. If separator is - // constant, concatenate consecutive constant string args in advance. Then, - // concatenate the intemediate result with neighboring array args or - // non-constant string args. - void doApply( - const SelectivityVector& rows, - std::vector& args, - exec::EvalCtx& context, - FlatVector& flatResult) const { - std::vector argMapping; - std::vector constantStrings; - auto numArgs = args.size(); - argMapping.reserve(numArgs - 1); - // Save intermediate result for consecutive constant string args. - // They will be concatenated in advance. - constantStrings.reserve(numArgs - 1); - std::vector decodedArrays; - decodedArrays.reserve(numArgs - 1); - // For column string arg decoding. - std::vector decodedStringArgs; - decodedStringArgs.reserve(numArgs); - - initVectors( - rows, - args, - context, - decodedArrays, - argMapping, - constantStrings, - decodedStringArgs); - exec::LocalDecodedVector decodedSeparator(context); - if (!separator_.has_value()) { - decodedSeparator = exec::LocalDecodedVector(context, *args[0], rows); - } - - auto totalResultBytes = calculateTotalResultBytes( - rows, - context, - decodedArrays, - constantStrings, - decodedStringArgs, - decodedSeparator); - - std::vector arrayVectors; - std::vector elementsDecodedVectors; - for (auto i = 0; i < decodedArrays.size(); ++i) { - auto arrayVector = decodedArrays[i].get()->base()->as(); - arrayVectors.push_back(arrayVector); - auto elements = arrayVector->elements(); - exec::LocalSelectivityVector nestedRows(context, elements->size()); - nestedRows.get()->setAll(); - exec::LocalDecodedVector elementsHolder( - context, *elements, *nestedRows.get()); - elementsDecodedVectors.push_back(elementsHolder.get()); - } - // Allocate a string buffer. - auto rawBuffer = - flatResult.getRawStringBufferWithSpace(totalResultBytes, true); - rows.applyToSelected([&](auto row) { - const char* start = rawBuffer; - auto isFirst = true; - // For array arg. - int32_t i = 0; - // For string arg. - int32_t j = 0; - auto it = decodedStringArgs.begin(); - - auto copyToBuffer = [&](StringView value, StringView separator) { - if (isFirst) { - isFirst = false; - } else { - // Add separator before the current value. - if (!separator.empty()) { - memcpy(rawBuffer, separator.data(), separator.size()); - rawBuffer += separator.size(); - } - } - if (!value.empty()) { - memcpy(rawBuffer, value.data(), value.size()); - rawBuffer += value.size(); - } - }; - - for (auto itArgs = args.begin() + 1; itArgs != args.end(); ++itArgs) { - if ((*itArgs)->typeKind() == TypeKind::ARRAY) { - auto arrayVector = arrayVectors[i]; - auto rawSizes = arrayVector->rawSizes(); - auto rawOffsets = arrayVector->rawOffsets(); - auto indices = decodedArrays[i].get()->indices(); - auto elementsDecoded = elementsDecodedVectors[i]; - - auto size = rawSizes[indices[row]]; - auto offset = rawOffsets[indices[row]]; - for (int k = 0; k < size; ++k) { - if (!elementsDecoded->isNullAt(offset + k)) { - auto element = elementsDecoded->valueAt(offset + k); - copyToBuffer( - element, - separator_.has_value() - ? StringView(separator_.value()) - : decodedSeparator->valueAt(row)); - } - } - i++; - continue; - } - - if (j >= constantStrings.size()) { - continue; - } - - StringView value; - if (!constantStrings[j].empty()) { - value = StringView(constantStrings[j]); - } else { - // Skip NULL. - if ((*it)->isNullAt(row)) { - ++it; - continue; - } - value = (*it++)->valueAt(row); - } - copyToBuffer( - value, - separator_.has_value() - ? StringView(separator_.value()) - : decodedSeparator->valueAt(row)); - j++; - } - flatResult.setNoCopy(row, StringView(start, rawBuffer - start)); - }); - } - - void apply( - const SelectivityVector& rows, - std::vector& args, - const TypePtr& /* outputType */, - exec::EvalCtx& context, - VectorPtr& result) const override { - context.ensureWritable(rows, VARCHAR(), result); - auto flatResult = result->asFlatVector(); - auto numArgs = args.size(); - // If separator is NULL, result is NULL. - if (args[0]->isNullAt(0)) { - rows.applyToSelected([&](auto row) { result->setNull(row, true); }); - return; - } - // If only separator (not a NULL) is provided, result is an empty string. - if (numArgs == 1) { - rows.applyToSelected( - [&](auto row) { flatResult->setNoCopy(row, StringView("")); }); - return; - } - doApply(rows, args, context, *flatResult); - } - - private: - // For holding constant separator. - const std::optional separator_; -}; } // namespace @@ -438,49 +146,6 @@ std::shared_ptr makeLength( return kLengthFunction; } -std::vector> concatWsSignatures() { - return {// The second and folowing arguments are varchar or array(varchar). - // Use "any" to allow the mixed using of these two types. The - // argument type will be checked in makeConcatWs. - // - // varchar, [varchar], [array(varchar)], ... -> varchar. - exec::FunctionSignatureBuilder() - .returnType("varchar") - .argumentType("varchar") - .argumentType("any") - .variableArity() - .build()}; -} - -std::shared_ptr makeConcatWs( - const std::string& name, - const std::vector& inputArgs, - const core::QueryConfig& /*config*/) { - auto numArgs = inputArgs.size(); - VELOX_USER_CHECK_GE( - numArgs, - 1, - "concat_ws requires one arguments at least, but got {}.", - numArgs); - for (const auto& arg : inputArgs) { - VELOX_USER_CHECK( - arg.type->isVarchar() || - (arg.type->isArray() && - arg.type->asArray().elementType()->isVarchar()), - "concat_ws requires varchar or array(varchar) arguments, but got {}.", - arg.type->toString()); - } - - BaseVector* constantSeparator = inputArgs[0].constantValue.get(); - std::optional separator = std::nullopt; - if (constantSeparator != nullptr) { - separator = - constantSeparator->as>()->valueAt(0).str(); - } - - return std::make_shared(separator); -} - void encodeDigestToBase16(uint8_t* output, int digestSize) { static unsigned char const kHexCodes[] = "0123456789abcdef"; for (int i = digestSize - 1; i >= 0; --i) { diff --git a/velox/functions/sparksql/String.h b/velox/functions/sparksql/String.h index 265ecb8fda3e..75f9e90f3d3b 100644 --- a/velox/functions/sparksql/String.h +++ b/velox/functions/sparksql/String.h @@ -152,13 +152,6 @@ std::shared_ptr makeLength( const std::vector& inputArgs, const core::QueryConfig& config); -std::vector> concatWsSignatures(); - -std::shared_ptr makeConcatWs( - const std::string& name, - const std::vector& inputArgs, - const core::QueryConfig& config); - /// Expands each char of the digest data to two chars, /// representing the hex value of each digest char, in order. /// Note: digestSize must be one-half of outputSize.