Skip to content

Commit 9dc4999

Browse files
kahatlenpercona-ysorokin
authored andcommitted
PS-9390 fix: JSON_TABLE and EXISTS() does not work
https://perconadev.atlassian.net/browse/PS-9390 Backported the fix for Bug #114897 / #36606073 (https://bugs.mysql.com/bug.php?id=114897) "json_table and exists make a bug" (commit 15e6812@mysql/mysql-server) which was added by Oracle in 9.3.0 but not in 8.4.5 / 8.0.42. In addition, 'json.json_table' MTR test case extended with the original query reported in PS-9390.
1 parent 2d48335 commit 9dc4999

File tree

5 files changed

+88
-0
lines changed

5 files changed

+88
-0
lines changed

mysql-test/suite/json/r/json_table.result

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2196,3 +2196,29 @@ SELECT * FROM JSON_TABLE('[1, 2]', '$' COLUMNS (
21962196
#
21972197
SELECT 1 FROM JSON_TABLE(ROW(1, 2), '$' COLUMNS (o FOR ORDINALITY)) AS jt;
21982198
ERROR 21000: Operand should contain 1 column(s)
2199+
#
2200+
# Bug#36606073: json_table and exists make a bug
2201+
#
2202+
CREATE TABLE t(x VARCHAR(10));
2203+
INSERT INTO t VALUES ('[1]'), ('[2]'), ('[3]');
2204+
SELECT * FROM t WHERE EXISTS (
2205+
SELECT * FROM JSON_TABLE(x, '$[*]' COLUMNS (i INT PATH '$')) AS jt WHERE i = 2
2206+
);
2207+
x
2208+
[2]
2209+
DROP TABLE t;
2210+
#
2211+
# PS-9390: JSON_TABLE and EXISTS() does not work
2212+
# https://perconadev.atlassian.net/browse/PS-9390
2213+
#
2214+
CREATE TABLE t (id INT PRIMARY KEY, b JSON);
2215+
INSERT INTO t SET id = 1, b = '{"a": [{"b": "1"}]}';
2216+
SELECT * FROM t WHERE EXISTS(SELECT 1 FROM JSON_TABLE(t.b, '$."a"[*]' COLUMNS (col1 VARCHAR(100) PATH '$.b' )) a);
2217+
id b
2218+
1 {"a": [{"b": "1"}]}
2219+
INSERT INTO t SET id = 2, b = '{"a": [{"b": "2"}]}';
2220+
SELECT * FROM t WHERE EXISTS(SELECT 1 FROM JSON_TABLE(t.b, '$."a"[*]' COLUMNS (col1 VARCHAR(100) PATH '$.b' )) a);
2221+
id b
2222+
1 {"a": [{"b": "1"}]}
2223+
2 {"a": [{"b": "2"}]}
2224+
DROP TABLE t;

mysql-test/suite/json/t/json_table.test

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,3 +1533,26 @@ SELECT * FROM JSON_TABLE('[1, 2]', '$' COLUMNS (
15331533
--echo #
15341534
--error ER_OPERAND_COLUMNS
15351535
SELECT 1 FROM JSON_TABLE(ROW(1, 2), '$' COLUMNS (o FOR ORDINALITY)) AS jt;
1536+
1537+
--echo #
1538+
--echo # Bug#36606073: json_table and exists make a bug
1539+
--echo #
1540+
1541+
CREATE TABLE t(x VARCHAR(10));
1542+
INSERT INTO t VALUES ('[1]'), ('[2]'), ('[3]');
1543+
SELECT * FROM t WHERE EXISTS (
1544+
SELECT * FROM JSON_TABLE(x, '$[*]' COLUMNS (i INT PATH '$')) AS jt WHERE i = 2
1545+
);
1546+
DROP TABLE t;
1547+
1548+
--echo #
1549+
--echo # PS-9390: JSON_TABLE and EXISTS() does not work
1550+
--echo # https://perconadev.atlassian.net/browse/PS-9390
1551+
--echo #
1552+
1553+
CREATE TABLE t (id INT PRIMARY KEY, b JSON);
1554+
INSERT INTO t SET id = 1, b = '{"a": [{"b": "1"}]}';
1555+
SELECT * FROM t WHERE EXISTS(SELECT 1 FROM JSON_TABLE(t.b, '$."a"[*]' COLUMNS (col1 VARCHAR(100) PATH '$.b' )) a);
1556+
INSERT INTO t SET id = 2, b = '{"a": [{"b": "2"}]}';
1557+
SELECT * FROM t WHERE EXISTS(SELECT 1 FROM JSON_TABLE(t.b, '$."a"[*]' COLUMNS (col1 VARCHAR(100) PATH '$.b' )) a);
1558+
DROP TABLE t;

sql/sql_resolver.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
#include "sql/sql_union.h" // Query_result_union
108108
#include "sql/system_variables.h"
109109
#include "sql/table.h"
110+
#include "sql/table_function.h"
110111
#include "sql/thd_raii.h"
111112
#include "sql/thr_malloc.h"
112113
#include "sql/visible_fields.h"
@@ -2354,6 +2355,11 @@ static void fix_tables_after_pullout(Query_block *parent_query_block,
23542355
"lateral CTE".
23552356
*/
23562357
}
2358+
2359+
if (tr->is_table_function()) {
2360+
tr->table_function->fix_after_pullout(parent_query_block,
2361+
removed_query_block);
2362+
}
23572363
}
23582364

23592365
/**

sql/table_function.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ bool Table_function::init_args() {
9393
return false;
9494
}
9595

96+
void Table_function::fix_after_pullout(Query_block *parent_query_block,
97+
Query_block *removed_query_block) {
98+
do_fix_after_pullout(parent_query_block, removed_query_block);
99+
table->pos_in_table_list->dep_tables = used_tables();
100+
}
101+
96102
/******************************************************************************
97103
Implementation of JSON_TABLE function
98104
******************************************************************************/
@@ -766,6 +772,11 @@ void Table_function_json::do_cleanup() {
766772
for (uint i = 0; i < m_all_columns.size(); i++) m_all_columns[i]->cleanup();
767773
}
768774

775+
void Table_function_json::do_fix_after_pullout(
776+
Query_block *parent_query_block, Query_block *removed_query_block) {
777+
source->fix_after_pullout(parent_query_block, removed_query_block);
778+
}
779+
769780
void JT_data_source::cleanup() {
770781
v.clear();
771782
producing_records = false;
@@ -870,6 +881,11 @@ void Table_function_sequence::do_cleanup() {
870881
m_precalculated_upper_bound = 0;
871882
}
872883

884+
void Table_function_sequence::do_fix_after_pullout(
885+
Query_block *parent_query_block, Query_block *removed_query_block) {
886+
m_source->fix_after_pullout(parent_query_block, removed_query_block);
887+
}
888+
873889
ulonglong Table_function_sequence::calculate_upper_bound() const {
874890
ulonglong res = 0;
875891
if (!m_source->is_null()) {

sql/table_function.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,17 @@ class Table_function {
158158

159159
virtual bool walk(Item_processor processor, enum_walk walk, uchar *arg) = 0;
160160

161+
/**
162+
Fix after tables have been moved from one query_block level to the parent
163+
level, e.g by semijoin conversion.
164+
165+
@param parent_query_block query_block that tables are moved to.
166+
@param removed_query_block query_block that tables are moved away from,
167+
child of parent_query_block.
168+
*/
169+
void fix_after_pullout(Query_block *parent_query_block,
170+
Query_block *removed_query_block);
171+
161172
private:
162173
/**
163174
Get the list of fields to create the result table
@@ -173,6 +184,8 @@ class Table_function {
173184
virtual bool do_init_args() = 0;
174185
friend bool Table_ref::setup_table_function(THD *thd);
175186
virtual void do_cleanup() {}
187+
virtual void do_fix_after_pullout(Query_block *parent_query_block,
188+
Query_block *removed_query_block) = 0;
176189
};
177190

178191
/****************************************************************************
@@ -431,6 +444,8 @@ class Table_function_json final : public Table_function {
431444
List<Create_field> *get_field_list() override;
432445
bool do_init_args() override;
433446
void do_cleanup() override;
447+
void do_fix_after_pullout(Query_block *parent_query_block,
448+
Query_block *removed_query_block) override;
434449
};
435450

436451
class Table_function_sequence final : public Table_function {
@@ -501,6 +516,8 @@ class Table_function_sequence final : public Table_function {
501516
virtual List<Create_field> *get_field_list() override;
502517
virtual bool do_init_args() override;
503518
virtual void do_cleanup() override;
519+
void do_fix_after_pullout(Query_block *parent_query_block,
520+
Query_block *removed_query_block) override;
504521

505522
ulonglong calculate_upper_bound() const;
506523
};

0 commit comments

Comments
 (0)