Skip to content

Commit 40f8802

Browse files
kahatlenlukin-oleksiy
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 831fdd7 commit 40f8802

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
@@ -2219,3 +2219,29 @@ EXPLAIN
22192219
-> Table scan on t (rows=2)
22202220

22212221
DROP TABLE t;
2222+
#
2223+
# Bug#36606073: json_table and exists make a bug
2224+
#
2225+
CREATE TABLE t(x VARCHAR(10));
2226+
INSERT INTO t VALUES ('[1]'), ('[2]'), ('[3]');
2227+
SELECT * FROM t WHERE EXISTS (
2228+
SELECT * FROM JSON_TABLE(x, '$[*]' COLUMNS (i INT PATH '$')) AS jt WHERE i = 2
2229+
);
2230+
x
2231+
[2]
2232+
DROP TABLE t;
2233+
#
2234+
# PS-9390: JSON_TABLE and EXISTS() does not work
2235+
# https://perconadev.atlassian.net/browse/PS-9390
2236+
#
2237+
CREATE TABLE t (id INT PRIMARY KEY, b JSON);
2238+
INSERT INTO t SET id = 1, b = '{"a": [{"b": "1"}]}';
2239+
SELECT * FROM t WHERE EXISTS(SELECT 1 FROM JSON_TABLE(t.b, '$."a"[*]' COLUMNS (col1 VARCHAR(100) PATH '$.b' )) a);
2240+
id b
2241+
1 {"a": [{"b": "1"}]}
2242+
INSERT INTO t SET id = 2, b = '{"a": [{"b": "2"}]}';
2243+
SELECT * FROM t WHERE EXISTS(SELECT 1 FROM JSON_TABLE(t.b, '$."a"[*]' COLUMNS (col1 VARCHAR(100) PATH '$.b' )) a);
2244+
id b
2245+
1 {"a": [{"b": "1"}]}
2246+
2 {"a": [{"b": "2"}]}
2247+
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
@@ -1557,3 +1557,26 @@ EXPLAIN FORMAT=TREE DELETE FROM t WHERE EXISTS
15571557
);
15581558

15591559
DROP TABLE t;
1560+
1561+
--echo #
1562+
--echo # Bug#36606073: json_table and exists make a bug
1563+
--echo #
1564+
1565+
CREATE TABLE t(x VARCHAR(10));
1566+
INSERT INTO t VALUES ('[1]'), ('[2]'), ('[3]');
1567+
SELECT * FROM t WHERE EXISTS (
1568+
SELECT * FROM JSON_TABLE(x, '$[*]' COLUMNS (i INT PATH '$')) AS jt WHERE i = 2
1569+
);
1570+
DROP TABLE t;
1571+
1572+
--echo #
1573+
--echo # PS-9390: JSON_TABLE and EXISTS() does not work
1574+
--echo # https://perconadev.atlassian.net/browse/PS-9390
1575+
--echo #
1576+
1577+
CREATE TABLE t (id INT PRIMARY KEY, b JSON);
1578+
INSERT INTO t SET id = 1, b = '{"a": [{"b": "1"}]}';
1579+
SELECT * FROM t WHERE EXISTS(SELECT 1 FROM JSON_TABLE(t.b, '$."a"[*]' COLUMNS (col1 VARCHAR(100) PATH '$.b' )) a);
1580+
INSERT INTO t SET id = 2, b = '{"a": [{"b": "2"}]}';
1581+
SELECT * FROM t WHERE EXISTS(SELECT 1 FROM JSON_TABLE(t.b, '$."a"[*]' COLUMNS (col1 VARCHAR(100) PATH '$.b' )) a);
1582+
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"
@@ -2164,6 +2165,11 @@ static void fix_tables_after_pullout(Query_block *parent_query_block,
21642165
"lateral CTE".
21652166
*/
21662167
}
2168+
2169+
if (tr->is_table_function()) {
2170+
tr->table_function->fix_after_pullout(parent_query_block,
2171+
removed_query_block);
2172+
}
21672173
}
21682174

21692175
/**

sql/table_function.cc

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

98+
void Table_function::fix_after_pullout(Query_block *parent_query_block,
99+
Query_block *removed_query_block) {
100+
do_fix_after_pullout(parent_query_block, removed_query_block);
101+
table->pos_in_table_list->dep_tables = used_tables();
102+
}
103+
98104
/******************************************************************************
99105
Implementation of JSON_TABLE function
100106
******************************************************************************/
@@ -770,6 +776,11 @@ void Table_function_json::do_cleanup() {
770776
for (uint i = 0; i < m_all_columns.size(); i++) m_all_columns[i]->cleanup();
771777
}
772778

779+
void Table_function_json::do_fix_after_pullout(
780+
Query_block *parent_query_block, Query_block *removed_query_block) {
781+
source->fix_after_pullout(parent_query_block, removed_query_block);
782+
}
783+
773784
void JT_data_source::cleanup() {
774785
v.clear();
775786
producing_records = false;
@@ -874,6 +885,11 @@ void Table_function_sequence::do_cleanup() {
874885
m_precalculated_upper_bound = 0;
875886
}
876887

888+
void Table_function_sequence::do_fix_after_pullout(
889+
Query_block *parent_query_block, Query_block *removed_query_block) {
890+
m_source->fix_after_pullout(parent_query_block, removed_query_block);
891+
}
892+
877893
ulonglong Table_function_sequence::calculate_upper_bound() const {
878894
ulonglong res = 0;
879895
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)