Skip to content

Commit 23af68b

Browse files
MDEV-36319: Wrong result json_table
Analysis: Json path comparison logic was incorrect.
1 parent 41725b4 commit 23af68b

File tree

3 files changed

+157
-15
lines changed

3 files changed

+157
-15
lines changed

mysql-test/main/func_json.result

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2692,4 +2692,75 @@ json_detailed('[[123],456]')
26922692
SELECT JSON_VALUE(JSON_OBJECT("a", ""), '$.a') = "" AS not_null;
26932693
not_null
26942694
1
2695+
#
2696+
# MDEV-36319: Wrong result json_table
2697+
#
2698+
SET @JSON='
2699+
{
2700+
"SZ": [
2701+
{
2702+
"NAME": "S0",
2703+
"OFFERS": [
2704+
{
2705+
"NAME": "S0A0"
2706+
}
2707+
]
2708+
},
2709+
{
2710+
"NAME": "S1",
2711+
"OFFERS": [
2712+
{
2713+
"NAME": "S1A0"
2714+
},
2715+
{
2716+
"NAME": "S1A1"
2717+
}
2718+
]
2719+
},
2720+
{
2721+
"NAME": "S2",
2722+
"OFFERS": [
2723+
{
2724+
"NAME": "S2A0"
2725+
}
2726+
]
2727+
},
2728+
{
2729+
"NAME": "S3",
2730+
"OFFERS": [
2731+
{
2732+
"NAME": "S3A0"
2733+
}
2734+
]
2735+
},
2736+
{
2737+
"NAME": "S4",
2738+
"OFFERS": [
2739+
{
2740+
"NAME": "S4A0"
2741+
}
2742+
]
2743+
},
2744+
{
2745+
"NAME": "S5",
2746+
"OFFERS": [
2747+
{
2748+
"NAME": "S5A0"
2749+
}
2750+
]
2751+
}
2752+
]
2753+
}
2754+
2755+
'
2756+
;
2757+
# Should return EMPTY result
2758+
SELECT * FROM json_table(@JSON, '$.SZ[0].OFFERS[1]'
2759+
COLUMNS(NAME VARCHAR(30) PATH '$.NAME')) AS t_sz;
2760+
NAME
2761+
# Should return S1A1
2762+
SELECT * FROM json_table(@JSON, '$.SZ[1].OFFERS[1]'
2763+
COLUMNS(NAME VARCHAR(30) PATH '$.NAME')) AS t_sz;
2764+
NAME
2765+
S1A1
26952766
# End of 10.11 Test

mysql-test/main/func_json.test

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1953,4 +1953,76 @@ select json_detailed('[[123],456]');
19531953

19541954
SELECT JSON_VALUE(JSON_OBJECT("a", ""), '$.a') = "" AS not_null;
19551955

1956+
--echo #
1957+
--echo # MDEV-36319: Wrong result json_table
1958+
--echo #
1959+
1960+
SET @JSON='
1961+
{
1962+
"SZ": [
1963+
{
1964+
"NAME": "S0",
1965+
"OFFERS": [
1966+
{
1967+
"NAME": "S0A0"
1968+
}
1969+
]
1970+
},
1971+
{
1972+
"NAME": "S1",
1973+
"OFFERS": [
1974+
{
1975+
"NAME": "S1A0"
1976+
},
1977+
{
1978+
"NAME": "S1A1"
1979+
}
1980+
]
1981+
},
1982+
{
1983+
"NAME": "S2",
1984+
"OFFERS": [
1985+
{
1986+
"NAME": "S2A0"
1987+
}
1988+
]
1989+
},
1990+
{
1991+
"NAME": "S3",
1992+
"OFFERS": [
1993+
{
1994+
"NAME": "S3A0"
1995+
}
1996+
]
1997+
},
1998+
{
1999+
"NAME": "S4",
2000+
"OFFERS": [
2001+
{
2002+
"NAME": "S4A0"
2003+
}
2004+
]
2005+
},
2006+
{
2007+
"NAME": "S5",
2008+
"OFFERS": [
2009+
{
2010+
"NAME": "S5A0"
2011+
}
2012+
]
2013+
}
2014+
]
2015+
}
2016+
2017+
'
2018+
;
2019+
2020+
--echo # Should return EMPTY result
2021+
SELECT * FROM json_table(@JSON, '$.SZ[0].OFFERS[1]'
2022+
COLUMNS(NAME VARCHAR(30) PATH '$.NAME')) AS t_sz;
2023+
2024+
--echo # Should return S1A1
2025+
SELECT * FROM json_table(@JSON, '$.SZ[1].OFFERS[1]'
2026+
COLUMNS(NAME VARCHAR(30) PATH '$.NAME')) AS t_sz;
2027+
19562028
--echo # End of 10.11 Test

sql/item_jsonfunc.cc

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -206,24 +206,23 @@ int json_path_parts_compare(
206206
{
207207
if (b->type & JSON_PATH_ARRAY)
208208
{
209-
int res= 0, corrected_n_item_a= 0;
210-
if (array_sizes)
211-
corrected_n_item_a= a->n_item < 0 ?
212-
array_sizes[b-temp_b] + a->n_item : a->n_item;
213-
if (a->type & JSON_PATH_ARRAY_RANGE)
209+
int res = 0;
210+
if (a->type & JSON_PATH_WILD)
211+
res = 1;
212+
else if (a->type & JSON_PATH_ARRAY_RANGE && array_sizes)
214213
{
215-
int corrected_n_item_end_a= 0;
216-
if (array_sizes)
217-
corrected_n_item_end_a= a->n_item_end < 0 ?
218-
array_sizes[b-temp_b] + a->n_item_end :
219-
a->n_item_end;
220-
res= b->n_item >= corrected_n_item_a &&
221-
b->n_item <= corrected_n_item_end_a;
214+
int start = (a->n_item >= 0) ? a->n_item
215+
: array_sizes[b - temp_b] + a->n_item;
216+
int end = (a->n_item_end >= 0) ? a->n_item_end
217+
: array_sizes[b - temp_b] + a->n_item_end;
218+
res = (b->n_item >= start && b->n_item <= end);
222219
}
223-
else
224-
res= corrected_n_item_a == b->n_item;
220+
else if (a->n_item >= 0)
221+
res = (a->n_item == b->n_item);
222+
else if (a->n_item < 0 && array_sizes)
223+
res = (a->n_item == b->n_item - array_sizes[b - temp_b]);
225224

226-
if ((a->type & JSON_PATH_WILD) || res)
225+
if (res)
227226
goto step_fits;
228227
goto step_failed;
229228
}

0 commit comments

Comments
 (0)