Skip to content

Commit 98a84af

Browse files
natashasehgalfacebook-github-bot
authored andcommitted
Fix cast to capped varchar for JSON (prestodb#24396)
Summary: https://www.internalfb.com/tasks/?t=211442303 There was an error in running query on Prestissimo not Presto - "Scalar function presto.default.substr not registered with arguments: (JSON, BIGINT, BIGINT)". This is not due to missing function, as the function signature does not exist in Presto. It occurs when attempting to cast JSON as varchar of capped length. Related Diff: https://www.internalfb.com/diff/D59531026 Note: Exception is still raised for try_cast() behavior. Alignment is out of scope for this PR Differential Revision: D68353517
1 parent 84955a8 commit 98a84af

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

presto-native-execution/presto_cpp/main/types/PrestoToVeloxExpr.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,15 @@ std::optional<TypedExprPtr> convertCastToVarcharWithMaxLength(
181181
VELOX_DCHECK(end == returnType.data() + returnType.size() - 1);
182182

183183
VELOX_DCHECK_EQ(args.size(), 1);
184-
const auto arg = args[0];
185184

185+
auto arg = args[0];
186+
// If the argument is of JSON type, convert it to VARCHAR before applying substr.
187+
if (velox::isJsonType(arg->type())) {
188+
arg = std::make_shared<CallTypedExpr>(
189+
velox::VARCHAR(),
190+
std::vector<TypedExprPtr>{arg},
191+
"presto.default.json_format");
192+
}
186193
return std::make_shared<CallTypedExpr>(
187194
arg->type(),
188195
std::vector<TypedExprPtr>{

presto-native-execution/presto_cpp/main/types/tests/RowExpressionTest.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,17 @@
1818
#include "presto_cpp/presto_protocol/core/presto_protocol_core.h"
1919
#include "velox/core/Expressions.h"
2020
#include "velox/type/Type.h"
21+
#include "velox/functions/prestosql/types/JsonType.h"
2122

2223
using namespace facebook::presto;
2324
using namespace facebook::velox;
2425
using namespace facebook::velox::core;
2526

2627
class RowExpressionTest : public ::testing::Test {
2728
public:
29+
RowExpressionTest(){
30+
registerJsonType();
31+
}
2832
static void SetUpTestCase() {
2933
memory::MemoryManager::testingSetInstance({});
3034
}
@@ -626,6 +630,20 @@ TEST_F(RowExpressionTest, castToVarchar) {
626630
ASSERT_TRUE(returnExpr->nullOnFailure());
627631
ASSERT_EQ(returnExpr->type()->toString(), "VARCHAR");
628632
}
633+
// CAST(json AS varchar(3))
634+
{
635+
std::shared_ptr<protocol::CallExpression> p =
636+
json::parse(makeCastToVarchar(false, "json", "varchar(3)"));
637+
auto expr = converter_->toVeloxExpr(p);
638+
auto returnExpr = std::dynamic_pointer_cast<const CallTypedExpr>(expr);
639+
ASSERT_NE(returnExpr, nullptr);
640+
ASSERT_EQ(returnExpr->name(), "presto.default.substr");
641+
642+
auto returnArg = std::dynamic_pointer_cast<const ConstantTypedExpr>(
643+
returnExpr->inputs()[2]);
644+
ASSERT_EQ(returnArg->type()->toString(), "BIGINT");
645+
ASSERT_EQ(returnArg->value().toJson(returnArg->type()), "3");
646+
}
629647
}
630648

631649
TEST_F(RowExpressionTest, special) {

0 commit comments

Comments
 (0)