MDEV-25381: JSON_TABLE: ER_WRONG_OUTER_JOIN upon query with LEFT and RIGHT joins and view
Table_function_json_table::m_dep_tables attempts to cache the value of m_json->used_tables(), poorly. Remove the cache and use the value directly.
This commit is contained in:
parent
4a10dd0253
commit
6bac48d0cf
@ -750,5 +750,48 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY jt ALL NULL NULL NULL NULL 40 Table function: json_table; Using where; FirstMatch(t1)
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-25381: JSON_TABLE: ER_WRONG_OUTER_JOIN upon query with LEFT and RIGHT joins and view
|
||||
#
|
||||
CREATE TABLE t1 (a INT);
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
CREATE TABLE t2 (b INT, c TEXT);
|
||||
INSERT INTO t2 VALUES (1,'{}'),(2,'[]');
|
||||
CREATE VIEW v2 AS SELECT * FROM t2;
|
||||
SELECT *
|
||||
FROM
|
||||
t1 RIGHT JOIN
|
||||
t2 AS tt
|
||||
LEFT JOIN
|
||||
JSON_TABLE(tt.c, '$' COLUMNS(o FOR ORDINALITY)) AS jt
|
||||
ON tt.b = jt.o
|
||||
ON t1.a = tt.b;
|
||||
a b c o
|
||||
1 1 {} 1
|
||||
2 2 [] NULL
|
||||
SELECT *
|
||||
FROM
|
||||
t1 RIGHT JOIN
|
||||
v2 AS tt
|
||||
LEFT JOIN
|
||||
JSON_TABLE(tt.c, '$' COLUMNS(o FOR ORDINALITY)) AS jt
|
||||
ON tt.b = jt.o
|
||||
ON t1.a = tt.b;
|
||||
a b c o
|
||||
1 1 {} 1
|
||||
2 2 [] NULL
|
||||
SELECT *
|
||||
FROM
|
||||
t1 RIGHT JOIN
|
||||
v2 AS tt
|
||||
LEFT JOIN
|
||||
JSON_TABLE(CONCAT(tt.c,''), '$' COLUMNS(o FOR ORDINALITY)) AS jt
|
||||
ON tt.b = jt.o
|
||||
ON t1.a = tt.b;
|
||||
a b c o
|
||||
1 1 {} 1
|
||||
2 2 [] NULL
|
||||
DROP VIEW v2;
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# End of 10.6 tests
|
||||
#
|
||||
|
@ -644,6 +644,47 @@ WHERE
|
||||
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-25381: JSON_TABLE: ER_WRONG_OUTER_JOIN upon query with LEFT and RIGHT joins and view
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a INT);
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
|
||||
CREATE TABLE t2 (b INT, c TEXT);
|
||||
INSERT INTO t2 VALUES (1,'{}'),(2,'[]');
|
||||
CREATE VIEW v2 AS SELECT * FROM t2;
|
||||
|
||||
SELECT *
|
||||
FROM
|
||||
t1 RIGHT JOIN
|
||||
t2 AS tt
|
||||
LEFT JOIN
|
||||
JSON_TABLE(tt.c, '$' COLUMNS(o FOR ORDINALITY)) AS jt
|
||||
ON tt.b = jt.o
|
||||
ON t1.a = tt.b;
|
||||
|
||||
SELECT *
|
||||
FROM
|
||||
t1 RIGHT JOIN
|
||||
v2 AS tt
|
||||
LEFT JOIN
|
||||
JSON_TABLE(tt.c, '$' COLUMNS(o FOR ORDINALITY)) AS jt
|
||||
ON tt.b = jt.o
|
||||
ON t1.a = tt.b;
|
||||
|
||||
SELECT *
|
||||
FROM
|
||||
t1 RIGHT JOIN
|
||||
v2 AS tt
|
||||
LEFT JOIN
|
||||
JSON_TABLE(CONCAT(tt.c,''), '$' COLUMNS(o FOR ORDINALITY)) AS jt
|
||||
ON tt.b = jt.o
|
||||
ON t1.a = tt.b;
|
||||
|
||||
DROP VIEW v2;
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.6 tests
|
||||
--echo #
|
||||
|
@ -1324,20 +1324,6 @@ int Table_function_json_table::setup(THD *thd, TABLE_LIST *sql_table,
|
||||
jc->m_field->charset= jc->m_explicit_cs;
|
||||
}
|
||||
}
|
||||
|
||||
m_dep_tables= m_json->used_tables();
|
||||
|
||||
if (m_dep_tables)
|
||||
{
|
||||
t->no_cache= TRUE;
|
||||
if (unlikely(m_dep_tables & sql_table->get_map()))
|
||||
{
|
||||
/* Table itself is used in the argument. */
|
||||
my_error(ER_WRONG_USAGE, MYF(0), "JSON_TABLE", "argument");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -1475,12 +1461,8 @@ int Table_function_json_table::print(THD *thd, TABLE_LIST *sql_table,
|
||||
void Table_function_json_table::fix_after_pullout(TABLE_LIST *sql_table,
|
||||
st_select_lex *new_parent, bool merge)
|
||||
{
|
||||
sql_table->dep_tables&= ~m_dep_tables;
|
||||
|
||||
m_json->fix_after_pullout(new_parent, &m_json, merge);
|
||||
m_dep_tables= m_json->used_tables();
|
||||
|
||||
sql_table->dep_tables|= m_dep_tables;
|
||||
sql_table->dep_tables= used_tables();
|
||||
}
|
||||
|
||||
|
||||
|
@ -208,8 +208,16 @@ public:
|
||||
st_select_lex *new_parent, bool merge);
|
||||
void update_used_tables() { m_json->update_used_tables(); }
|
||||
|
||||
table_map used_tables() const { return m_dep_tables; }
|
||||
bool join_cache_allowed() const { return !m_dep_tables; }
|
||||
table_map used_tables() const { return m_json->used_tables(); }
|
||||
bool join_cache_allowed() const
|
||||
{
|
||||
/*
|
||||
Can use join cache when we have an outside reference.
|
||||
If there's dependency on any other table or randomness,
|
||||
cannot use it.
|
||||
*/
|
||||
return !(used_tables() & ~OUTER_REF_TABLE_BIT);
|
||||
}
|
||||
void get_estimates(ha_rows *out_rows,
|
||||
double *scan_time, double *startup_cost);
|
||||
|
||||
@ -242,13 +250,6 @@ private:
|
||||
/* Context to be used for resolving the first argument. */
|
||||
Name_resolution_context *m_context;
|
||||
|
||||
/*
|
||||
the JSON argument can be taken from other tables.
|
||||
We have to mark these tables as dependent so the
|
||||
mask of these dependent tables is calculated in ::setup().
|
||||
*/
|
||||
table_map m_dep_tables;
|
||||
|
||||
/* Current NESTED PATH level being parsed */
|
||||
Json_table_nested_path *cur_parent;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user