summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzverevgeny <[email protected]>2025-06-09 19:51:18 +0300
committerGitHub <[email protected]>2025-06-09 16:51:18 +0000
commitbb8cc77d02904c9f12f5bac205036935c1eddd64 (patch)
treed5d61d1bf3de6335772d8a2489274bada30ec625
parentfb1d531b5de4a3f5223a60e408e6f7a083a4a214 (diff)
Remove unnecessary quotes from json path (#19501)
-rw-r--r--ydb/core/kqp/opt/physical/kqp_opt_phy_olap_filter.cpp20
-rw-r--r--ydb/core/kqp/ut/olap/json_ut.cpp5
2 files changed, 24 insertions, 1 deletions
diff --git a/ydb/core/kqp/opt/physical/kqp_opt_phy_olap_filter.cpp b/ydb/core/kqp/opt/physical/kqp_opt_phy_olap_filter.cpp
index aabb9e7e914..d34bd914891 100644
--- a/ydb/core/kqp/opt/physical/kqp_opt_phy_olap_filter.cpp
+++ b/ydb/core/kqp/opt/physical/kqp_opt_phy_olap_filter.cpp
@@ -312,6 +312,24 @@ TMaybeNode<TExprBase> SafeCastPredicatePushdown(const TCoFlatMap& inputFlatmap,
return ComparisonPushdown(parameters, predicate, ctx, pos);
}
+namespace {
+
+//Workarownd for #19125
+NYql::NNodes::TCoUtf8 RemoveJsonPathUnnecessaryQuote(const NYql::NNodes::TCoUtf8& node, TExprContext& ctx) {
+ const std::string_view& path = node.Literal().StringValue();
+ if (UTF8Detect(path) == ASCII && path.starts_with("$.\"") && path.substr(3).ends_with("\"")) {
+ const auto& nakedPath = path.substr(3, path.length()-4);
+ for (auto c: nakedPath) {
+ if (!isalpha(c) && !isdigit(c) && c != '_') {
+ return node;
+ }
+ }
+ return Build<TCoUtf8>(ctx, node.Pos()).Literal().Build(TString("$.") + nakedPath).Done();
+ }
+ return node;
+}
+
+} //namespace
std::vector<TExprBase> ConvertComparisonNode(const TExprBase& nodeIn, const TExprNode& argument, TExprContext& ctx, TPositionHandle pos, bool allowApply)
{
@@ -346,7 +364,7 @@ std::vector<TExprBase> ConvertComparisonNode(const TExprBase& nodeIn, const TExp
auto builder = Build<TKqpOlapJsonValue>(ctx, pos)
.Column(maybeColMember.Cast().Name())
- .Path(maybePathUtf8.Cast());
+ .Path(RemoveJsonPathUnnecessaryQuote(maybePathUtf8.Cast(), ctx));
if (maybeReturningType) {
builder.ReturningType(maybeReturningType.Cast());
} else {
diff --git a/ydb/core/kqp/ut/olap/json_ut.cpp b/ydb/core/kqp/ut/olap/json_ut.cpp
index 6eb72682788..5a0dc662ebd 100644
--- a/ydb/core/kqp/ut/olap/json_ut.cpp
+++ b/ydb/core/kqp/ut/olap/json_ut.cpp
@@ -654,6 +654,11 @@ Y_UNIT_TEST_SUITE(KqpOlapJson) {
EXPECTED: [[4u;["{\"a\":\"a4\",\"b.c.d\":\"b4\"}"]];[14u;["{\"a\":\"a4\",\"b.c.d\":\"1b4\"}"]]]
IDX_ND_SKIP_APPROVE: 0, 3, 2
------
+ READ: SELECT * FROM `/Root/ColumnTable` WHERE JSON_VALUE(Col2, "$.\"a\"") = "a4" ORDER BY Col1;
+ EXPECTED: [[4u;["{\"a\":\"a4\",\"b.c.d\":\"b4\"}"]];[14u;["{\"a\":\"a4\",\"b.c.d\":\"1b4\"}"]]]
+ IDX_ND_SKIP_APPROVE: 0, 3, 2
+ ------
+
READ: SELECT * FROM `/Root/ColumnTable` WHERE JSON_VALUE(Col2, "$.\"b.c.d111\"") = "1b5" ORDER BY Col1;
EXPECTED: []
IDX_ND_SKIP_APPROVE: 0, 5, 0