MDEV-25202: JSON_TABLE: Early table reference leads to unexpected result set
(Also fixes MDEV-25254). Re-work Name Resolution for the argument of JSON_TABLE(json_doc, ....) function. The json_doc argument can refer to other tables, but it can only refer to the tables that precede[*] the JSON_TABLE(...) call. [*] - For queries with RIGHT JOINs, the "preceding" is determined after the query is normalized by converting RIGHT JOIN into left one. The implementation is as follows: - Table function arguments use their own Name_resolution_context. - The Name_resolution_context now has a bitmap of tables that should be ignored when searching for a field. - get_disallowed_table_deps() walks the TABLE_LIST::nested_join tree and computes a bitmap of tables that do not "precede" the given JSON_TABLE(...) invocation (according the above definition of "preceding").
This commit is contained in:
parent
13390a70e2
commit
84cf9c2e11
@ -55,7 +55,7 @@ item_name item_props color
|
|||||||
Laptop {"color": "black", "price": 1000} black
|
Laptop {"color": "black", "price": 1000} black
|
||||||
Jeans {"color": "blue", "price": 50} blue
|
Jeans {"color": "blue", "price": 50} blue
|
||||||
select * from t1 right join json_table(t1.item_props,'$' columns( color varchar(100) path '$.color')) as T on 1;
|
select * from t1 right join json_table(t1.item_props,'$' columns( color varchar(100) path '$.color')) as T on 1;
|
||||||
ERROR 42000: Cross dependency found in OUTER JOIN; examine your ON conditions
|
ERROR 42S22: Unknown column 't1.item_props' in 'JSON_TABLE argument'
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
select * from JSON_TABLE( '[ {"xa": 1, "b": [11,111]}, {"a": 2, "b": [22,222]}, {"a":3}]', '$[*]' COLUMNS( a INT PATH '$.a' default '101' on empty, NESTED PATH '$.b[*]' COLUMNS (b INT PATH '$'))) as jt;
|
select * from JSON_TABLE( '[ {"xa": 1, "b": [11,111]}, {"a": 2, "b": [22,222]}, {"a":3}]', '$[*]' COLUMNS( a INT PATH '$.a' default '101' on empty, NESTED PATH '$.b[*]' COLUMNS (b INT PATH '$'))) as jt;
|
||||||
a b
|
a b
|
||||||
@ -251,8 +251,12 @@ SELECT t1.x*2 m, jt.* FROM t1,
|
|||||||
JSON_TABLE(m, '$[*]' COLUMNS (i INT PATH '$')) jt;
|
JSON_TABLE(m, '$[*]' COLUMNS (i INT PATH '$')) jt;
|
||||||
ERROR 42S22: Unknown column 'm' in 'JSON_TABLE argument'
|
ERROR 42S22: Unknown column 'm' in 'JSON_TABLE argument'
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
select * from json_table(JS3.size, '$' columns (size INT PATH '$.size')) as JS1, json_table(JS1.size, '$' columns (size INT PATH '$.size')) as JS2, json_table(JS1.size, '$' columns (size INT PATH '$.size')) as JS3 where 1;
|
select *
|
||||||
ERROR 42S02: Unknown table 'JS3' in JSON_TABLE argument
|
from
|
||||||
|
json_table(JS3.size, '$' columns (size INT PATH '$.size')) as JS1,
|
||||||
|
json_table(JS1.size, '$' columns (size INT PATH '$.size')) as JS2,
|
||||||
|
json_table(JS1.size, '$' columns (size INT PATH '$.size')) as JS3 where 1;
|
||||||
|
ERROR 42S22: Unknown column 'JS3.size' in 'JSON_TABLE argument'
|
||||||
create table t1 (json varchar(100) character set utf8);
|
create table t1 (json varchar(100) character set utf8);
|
||||||
insert into t1 values ('{"value":"АБВ"}');
|
insert into t1 values ('{"value":"АБВ"}');
|
||||||
create table tj1 as
|
create table tj1 as
|
||||||
@ -279,7 +283,7 @@ test.t1 analyze status Engine-independent statistics collected
|
|||||||
test.t1 analyze Warning Engine-independent statistics are not collected for column 'f1'
|
test.t1 analyze Warning Engine-independent statistics are not collected for column 'f1'
|
||||||
test.t1 analyze status OK
|
test.t1 analyze status OK
|
||||||
SELECT * FROM JSON_TABLE(tt3.f1, "$" COLUMNS (id FOR ORDINALITY)) AS tbl STRAIGHT_JOIN t1 AS tt3;
|
SELECT * FROM JSON_TABLE(tt3.f1, "$" COLUMNS (id FOR ORDINALITY)) AS tbl STRAIGHT_JOIN t1 AS tt3;
|
||||||
ERROR 42S02: Unknown table 'tt3' in JSON_TABLE argument
|
ERROR 42S22: Unknown column 'tt3.f1' in 'JSON_TABLE argument'
|
||||||
SELECT * FROM t1 as jj1,
|
SELECT * FROM t1 as jj1,
|
||||||
(SELECT tt2.*
|
(SELECT tt2.*
|
||||||
FROM
|
FROM
|
||||||
@ -589,5 +593,81 @@ f
|
|||||||
NULL
|
NULL
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-25254: JSON_TABLE: Inconsistent name resolution with right joins
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
SELECT * FROM t1 RIGHT JOIN JSON_TABLE(t1.a,'$' COLUMNS(o FOR ORDINALITY)) jt ON TRUE;
|
||||||
|
ERROR 42S22: Unknown column 't1.a' in 'JSON_TABLE argument'
|
||||||
|
CREATE VIEW v AS
|
||||||
|
SELECT * FROM t1 RIGHT JOIN JSON_TABLE(t1.a,'$' COLUMNS(o FOR ORDINALITY)) jt ON TRUE;
|
||||||
|
ERROR 42S22: Unknown column 't1.a' in 'JSON_TABLE argument'
|
||||||
|
insert into t1 values (1),(2),(3);
|
||||||
|
SELECT * FROM t1 RIGHT JOIN JSON_TABLE(t1.a,'$' COLUMNS(o FOR ORDINALITY)) jt ON TRUE;
|
||||||
|
ERROR 42S22: Unknown column 't1.a' in 'JSON_TABLE argument'
|
||||||
|
drop table t1;
|
||||||
|
#
|
||||||
|
# MDEV-25202: JSON_TABLE: Early table reference leads to unexpected result set, server crash
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (o INT);
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
CREATE TABLE t2 (a INT);
|
||||||
|
INSERT INTO t2 VALUES (3),(4);
|
||||||
|
SELECT * FROM JSON_TABLE(a, '$' COLUMNS(o FOR ORDINALITY)) AS jt1 NATURAL JOIN t1 JOIN t2;
|
||||||
|
ERROR 42S22: Unknown column 'a' in 'JSON_TABLE argument'
|
||||||
|
SELECT * FROM JSON_TABLE(a, '$' COLUMNS(o FOR ORDINALITY)) AS jt1 NATURAL JOIN t1 STRAIGHT_JOIN t2;
|
||||||
|
ERROR 42S22: Unknown column 'a' in 'JSON_TABLE argument'
|
||||||
|
drop table t1,t2;
|
||||||
|
# Now, try a JSON_TABLE that has a subquery that has an outside reference:
|
||||||
|
create table t1(a int, js varchar(32));
|
||||||
|
create table t2(a varchar(100));
|
||||||
|
insert into t2 values('');
|
||||||
|
explain
|
||||||
|
select *
|
||||||
|
from
|
||||||
|
t1 left join
|
||||||
|
json_table(concat('',js),
|
||||||
|
'$' columns ( color varchar(32) path '$.color')
|
||||||
|
) as JT on 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
explain
|
||||||
|
select *
|
||||||
|
from
|
||||||
|
t1 right join
|
||||||
|
json_table(concat('',js),
|
||||||
|
'$' columns ( color varchar(32) path '$.color')
|
||||||
|
) as JT on 1;
|
||||||
|
ERROR 42S22: Unknown column 'js' in 'JSON_TABLE argument'
|
||||||
|
explain
|
||||||
|
select *
|
||||||
|
from
|
||||||
|
t1 left join
|
||||||
|
json_table((select concat(a,js) from t2),
|
||||||
|
'$' columns ( color varchar(32) path '$.color')
|
||||||
|
) as JT on 1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
2 SUBQUERY t2 system NULL NULL NULL NULL 1
|
||||||
|
explain
|
||||||
|
select *
|
||||||
|
from
|
||||||
|
t1 right join
|
||||||
|
json_table((select concat(a,js) from t2),
|
||||||
|
'$' columns ( color varchar(32) path '$.color')
|
||||||
|
) as JT on 1;
|
||||||
|
ERROR 42S22: Unknown column 'js' in 'field list'
|
||||||
|
drop table t1,t2;
|
||||||
|
#
|
||||||
|
# MDEV-25256: JSON_TABLE: Error ER_VIEW_INVALID upon running query via view
|
||||||
|
#
|
||||||
|
SELECT * FROM
|
||||||
|
JSON_TABLE('[]', '$' COLUMNS(a TEXT PATH '$[*]')) AS jt1
|
||||||
|
RIGHT JOIN JSON_TABLE(jt1.a, '$' COLUMNS(o2 FOR ORDINALITY)) AS jt2
|
||||||
|
ON(1)
|
||||||
|
RIGHT JOIN JSON_TABLE('[]', '$' COLUMNS(o3 FOR ORDINALITY)) AS jt3
|
||||||
|
ON(1)
|
||||||
|
WHERE 0;
|
||||||
|
ERROR 42S22: Unknown column 'jt1.a' in 'JSON_TABLE argument'
|
||||||
|
#
|
||||||
# End of 10.6 tests
|
# End of 10.6 tests
|
||||||
#
|
#
|
||||||
|
@ -640,13 +640,13 @@ DEALLOCATE PREPARE stmt;
|
|||||||
CREATE TABLE t1 (id INT, jc JSON);
|
CREATE TABLE t1 (id INT, jc JSON);
|
||||||
SELECT * FROM t1 RIGHT JOIN JSON_TABLE(t1.jc, '$' COLUMNS
|
SELECT * FROM t1 RIGHT JOIN JSON_TABLE(t1.jc, '$' COLUMNS
|
||||||
(id FOR ORDINALITY)) as jt ON t1.jc=jt.id;
|
(id FOR ORDINALITY)) as jt ON t1.jc=jt.id;
|
||||||
id jc id
|
ERROR 42S22: Unknown column 't1.jc' in 'JSON_TABLE argument'
|
||||||
SELECT * FROM JSON_TABLE(t1.jc, '$' COLUMNS
|
SELECT * FROM JSON_TABLE(t1.jc, '$' COLUMNS
|
||||||
(id FOR ORDINALITY)) as jt LEFT JOIN t1 ON t1.jc=jt.id;
|
(id FOR ORDINALITY)) as jt LEFT JOIN t1 ON t1.jc=jt.id;
|
||||||
ERROR 42S02: Unknown table 't1' in JSON_TABLE argument
|
ERROR 42S22: Unknown column 't1.jc' in 'JSON_TABLE argument'
|
||||||
SELECT * FROM JSON_TABLE(t1.jc, '$' COLUMNS
|
SELECT * FROM JSON_TABLE(t1.jc, '$' COLUMNS
|
||||||
(id FOR ORDINALITY)) as jt RIGHT JOIN t1 ON t1.jc=jt.id;
|
(id FOR ORDINALITY)) as jt RIGHT JOIN t1 ON t1.jc=jt.id;
|
||||||
ERROR 42S02: Unknown table 't1' in JSON_TABLE argument
|
id id jc
|
||||||
SELECT * FROM t1 LEFT JOIN JSON_TABLE(t1.jc, '$' COLUMNS
|
SELECT * FROM t1 LEFT JOIN JSON_TABLE(t1.jc, '$' COLUMNS
|
||||||
(id FOR ORDINALITY)) as jt ON t1.jc=jt.id;
|
(id FOR ORDINALITY)) as jt ON t1.jc=jt.id;
|
||||||
id jc id
|
id jc id
|
||||||
@ -667,34 +667,33 @@ SELECT * FROM t1 AS t1o RIGHT JOIN
|
|||||||
(t1 AS t1i JOIN JSON_TABLE(t1o.jc, '$' COLUMNS
|
(t1 AS t1i JOIN JSON_TABLE(t1o.jc, '$' COLUMNS
|
||||||
(id FOR ORDINALITY)) as jt ON t1i.jc=jt.id)
|
(id FOR ORDINALITY)) as jt ON t1i.jc=jt.id)
|
||||||
ON t1o.id=t1i.id;
|
ON t1o.id=t1i.id;
|
||||||
id jc id jc id
|
ERROR 42S22: Unknown column 't1o.jc' in 'JSON_TABLE argument'
|
||||||
SELECT * FROM t1 AS t1o RIGHT JOIN
|
SELECT * FROM t1 AS t1o RIGHT JOIN
|
||||||
(t1 AS t1i RIGHT JOIN JSON_TABLE(t1o.jc, '$' COLUMNS
|
(t1 AS t1i RIGHT JOIN JSON_TABLE(t1o.jc, '$' COLUMNS
|
||||||
(id FOR ORDINALITY)) as jt ON t1i.jc=jt.id)
|
(id FOR ORDINALITY)) as jt ON t1i.jc=jt.id)
|
||||||
ON t1o.id=t1i.id;
|
ON t1o.id=t1i.id;
|
||||||
id jc id jc id
|
ERROR 42S22: Unknown column 't1o.jc' in 'JSON_TABLE argument'
|
||||||
WITH qn AS
|
WITH qn AS
|
||||||
(SELECT jt.* FROM t1 RIGHT JOIN JSON_TABLE(t1.jc, '$' COLUMNS
|
(SELECT jt.* FROM t1 RIGHT JOIN JSON_TABLE(t1.jc, '$' COLUMNS
|
||||||
(id FOR ORDINALITY)) as jt ON t1.jc=jt.id)
|
(id FOR ORDINALITY)) as jt ON t1.jc=jt.id)
|
||||||
SELECT * from qn;
|
SELECT * from qn;
|
||||||
id
|
ERROR 42S22: Unknown column 't1.jc' in 'JSON_TABLE argument'
|
||||||
WITH qn AS
|
WITH qn AS
|
||||||
(SELECT 1 UNION
|
(SELECT 1 UNION
|
||||||
SELECT jt.id FROM t1 RIGHT JOIN JSON_TABLE(t1.jc, '$' COLUMNS
|
SELECT jt.id FROM t1 RIGHT JOIN JSON_TABLE(t1.jc, '$' COLUMNS
|
||||||
(id FOR ORDINALITY)) as jt ON t1.jc=jt.id)
|
(id FOR ORDINALITY)) as jt ON t1.jc=jt.id)
|
||||||
SELECT * from qn;
|
SELECT * from qn;
|
||||||
1
|
ERROR 42S22: Unknown column 't1.jc' in 'JSON_TABLE argument'
|
||||||
1
|
|
||||||
SELECT * FROM t1 AS t1o RIGHT JOIN
|
SELECT * FROM t1 AS t1o RIGHT JOIN
|
||||||
(t1 AS t1i JOIN JSON_TABLE(t1o.jc, '$' COLUMNS
|
(t1 AS t1i JOIN JSON_TABLE(t1o.jc, '$' COLUMNS
|
||||||
(id FOR ORDINALITY)) as jt ON t1i.jc=jt.id)
|
(id FOR ORDINALITY)) as jt ON t1i.jc=jt.id)
|
||||||
ON t1o.id=t1i.id;
|
ON t1o.id=t1i.id;
|
||||||
id jc id jc id
|
ERROR 42S22: Unknown column 't1o.jc' in 'JSON_TABLE argument'
|
||||||
SELECT * FROM t1 AS t1o RIGHT JOIN
|
SELECT * FROM t1 AS t1o RIGHT JOIN
|
||||||
(t1 AS t1i RIGHT JOIN JSON_TABLE(t1o.jc, '$' COLUMNS
|
(t1 AS t1i RIGHT JOIN JSON_TABLE(t1o.jc, '$' COLUMNS
|
||||||
(id FOR ORDINALITY)) as jt ON t1i.jc=jt.id)
|
(id FOR ORDINALITY)) as jt ON t1i.jc=jt.id)
|
||||||
ON t1o.id=t1i.id;
|
ON t1o.id=t1i.id;
|
||||||
id jc id jc id
|
ERROR 42S22: Unknown column 't1o.jc' in 'JSON_TABLE argument'
|
||||||
INSERT INTO t1 VALUES(1,"1"),(2,"4"),(3,"3");
|
INSERT INTO t1 VALUES(1,"1"),(2,"4"),(3,"3");
|
||||||
ANALYZE TABLE t1;
|
ANALYZE TABLE t1;
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
@ -717,7 +716,7 @@ LEFT JOIN
|
|||||||
JSON_TABLE(t1.jc, '$' COLUMNS (id FOR ORDINALITY)) as jt ON t1.jc=jt.id
|
JSON_TABLE(t1.jc, '$' COLUMNS (id FOR ORDINALITY)) as jt ON t1.jc=jt.id
|
||||||
RIGHT JOIN
|
RIGHT JOIN
|
||||||
JSON_TABLE(jt.id, '$' COLUMNS (id FOR ORDINALITY)) as jt1 ON jt.id=jt1.id;
|
JSON_TABLE(jt.id, '$' COLUMNS (id FOR ORDINALITY)) as jt1 ON jt.id=jt1.id;
|
||||||
ERROR 42000: Cross dependency found in OUTER JOIN; examine your ON conditions
|
ERROR 42S22: Unknown column 'jt.id' in 'JSON_TABLE argument'
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
# Bug#25525409: ASSERTION `TABLE_LIST->TABLE' FAILED IN SQL/SQL_BASE.CC
|
# Bug#25525409: ASSERTION `TABLE_LIST->TABLE' FAILED IN SQL/SQL_BASE.CC
|
||||||
|
@ -25,7 +25,7 @@ insert into t1 values ('Jeans', '{"color": "blue", "price": 50}');
|
|||||||
|
|
||||||
select * from t1 left join json_table(t1.item_props,'$' columns( color varchar(100) path '$.color')) as T on 1;
|
select * from t1 left join json_table(t1.item_props,'$' columns( color varchar(100) path '$.color')) as T on 1;
|
||||||
|
|
||||||
--error ER_WRONG_OUTER_JOIN
|
--error ER_BAD_FIELD_ERROR
|
||||||
select * from t1 right join json_table(t1.item_props,'$' columns( color varchar(100) path '$.color')) as T on 1;
|
select * from t1 right join json_table(t1.item_props,'$' columns( color varchar(100) path '$.color')) as T on 1;
|
||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
@ -173,8 +173,12 @@ SELECT t1.x*2 m, jt.* FROM t1,
|
|||||||
JSON_TABLE(m, '$[*]' COLUMNS (i INT PATH '$')) jt;
|
JSON_TABLE(m, '$[*]' COLUMNS (i INT PATH '$')) jt;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
--error ER_UNKNOWN_TABLE
|
--error ER_BAD_FIELD_ERROR
|
||||||
select * from json_table(JS3.size, '$' columns (size INT PATH '$.size')) as JS1, json_table(JS1.size, '$' columns (size INT PATH '$.size')) as JS2, json_table(JS1.size, '$' columns (size INT PATH '$.size')) as JS3 where 1;
|
select *
|
||||||
|
from
|
||||||
|
json_table(JS3.size, '$' columns (size INT PATH '$.size')) as JS1,
|
||||||
|
json_table(JS1.size, '$' columns (size INT PATH '$.size')) as JS2,
|
||||||
|
json_table(JS1.size, '$' columns (size INT PATH '$.size')) as JS3 where 1;
|
||||||
|
|
||||||
create table t1 (json varchar(100) character set utf8);
|
create table t1 (json varchar(100) character set utf8);
|
||||||
insert into t1 values ('{"value":"АБВ"}');
|
insert into t1 values ('{"value":"АБВ"}');
|
||||||
@ -195,7 +199,7 @@ INSERT INTO t1 VALUES
|
|||||||
(6, '{\"1\": 6}');
|
(6, '{\"1\": 6}');
|
||||||
ANALYZE TABLE t1;
|
ANALYZE TABLE t1;
|
||||||
|
|
||||||
--error ER_UNKNOWN_TABLE
|
--error ER_BAD_FIELD_ERROR
|
||||||
SELECT * FROM JSON_TABLE(tt3.f1, "$" COLUMNS (id FOR ORDINALITY)) AS tbl STRAIGHT_JOIN t1 AS tt3;
|
SELECT * FROM JSON_TABLE(tt3.f1, "$" COLUMNS (id FOR ORDINALITY)) AS tbl STRAIGHT_JOIN t1 AS tt3;
|
||||||
--error ER_BAD_FIELD_ERROR
|
--error ER_BAD_FIELD_ERROR
|
||||||
SELECT * FROM t1 as jj1,
|
SELECT * FROM t1 as jj1,
|
||||||
@ -460,6 +464,97 @@ CREATE TABLE t1 AS SELECT * FROM JSON_TABLE('{"x":1}', '$' COLUMNS(f DATE PATH '
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-25254: JSON_TABLE: Inconsistent name resolution with right joins
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
|
SELECT * FROM t1 RIGHT JOIN JSON_TABLE(t1.a,'$' COLUMNS(o FOR ORDINALITY)) jt ON TRUE;
|
||||||
|
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
|
CREATE VIEW v AS
|
||||||
|
SELECT * FROM t1 RIGHT JOIN JSON_TABLE(t1.a,'$' COLUMNS(o FOR ORDINALITY)) jt ON TRUE;
|
||||||
|
|
||||||
|
insert into t1 values (1),(2),(3);
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
|
SELECT * FROM t1 RIGHT JOIN JSON_TABLE(t1.a,'$' COLUMNS(o FOR ORDINALITY)) jt ON TRUE;
|
||||||
|
|
||||||
|
drop table t1;
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-25202: JSON_TABLE: Early table reference leads to unexpected result set, server crash
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1 (o INT);
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
|
||||||
|
CREATE TABLE t2 (a INT);
|
||||||
|
INSERT INTO t2 VALUES (3),(4);
|
||||||
|
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
|
SELECT * FROM JSON_TABLE(a, '$' COLUMNS(o FOR ORDINALITY)) AS jt1 NATURAL JOIN t1 JOIN t2;
|
||||||
|
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
|
SELECT * FROM JSON_TABLE(a, '$' COLUMNS(o FOR ORDINALITY)) AS jt1 NATURAL JOIN t1 STRAIGHT_JOIN t2;
|
||||||
|
|
||||||
|
drop table t1,t2;
|
||||||
|
|
||||||
|
--echo # Now, try a JSON_TABLE that has a subquery that has an outside reference:
|
||||||
|
|
||||||
|
create table t1(a int, js varchar(32));
|
||||||
|
|
||||||
|
create table t2(a varchar(100));
|
||||||
|
insert into t2 values('');
|
||||||
|
|
||||||
|
# First, without subquery:
|
||||||
|
explain
|
||||||
|
select *
|
||||||
|
from
|
||||||
|
t1 left join
|
||||||
|
json_table(concat('',js),
|
||||||
|
'$' columns ( color varchar(32) path '$.color')
|
||||||
|
) as JT on 1;
|
||||||
|
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
|
explain
|
||||||
|
select *
|
||||||
|
from
|
||||||
|
t1 right join
|
||||||
|
json_table(concat('',js),
|
||||||
|
'$' columns ( color varchar(32) path '$.color')
|
||||||
|
) as JT on 1;
|
||||||
|
|
||||||
|
# Now, with subquery:
|
||||||
|
explain
|
||||||
|
select *
|
||||||
|
from
|
||||||
|
t1 left join
|
||||||
|
json_table((select concat(a,js) from t2),
|
||||||
|
'$' columns ( color varchar(32) path '$.color')
|
||||||
|
) as JT on 1;
|
||||||
|
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
|
explain
|
||||||
|
select *
|
||||||
|
from
|
||||||
|
t1 right join
|
||||||
|
json_table((select concat(a,js) from t2),
|
||||||
|
'$' columns ( color varchar(32) path '$.color')
|
||||||
|
) as JT on 1;
|
||||||
|
|
||||||
|
drop table t1,t2;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-25256: JSON_TABLE: Error ER_VIEW_INVALID upon running query via view
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
|
SELECT * FROM
|
||||||
|
JSON_TABLE('[]', '$' COLUMNS(a TEXT PATH '$[*]')) AS jt1
|
||||||
|
RIGHT JOIN JSON_TABLE(jt1.a, '$' COLUMNS(o2 FOR ORDINALITY)) AS jt2
|
||||||
|
ON(1)
|
||||||
|
RIGHT JOIN JSON_TABLE('[]', '$' COLUMNS(o3 FOR ORDINALITY)) AS jt3
|
||||||
|
ON(1)
|
||||||
|
WHERE 0;
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.6 tests
|
--echo # End of 10.6 tests
|
||||||
|
@ -549,15 +549,17 @@ CREATE TABLE t1 (id INT, jc JSON);
|
|||||||
|
|
||||||
# psergey!
|
# psergey!
|
||||||
#--error ER_UNKNOWN_TABLE
|
#--error ER_UNKNOWN_TABLE
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
SELECT * FROM t1 RIGHT JOIN JSON_TABLE(t1.jc, '$' COLUMNS
|
SELECT * FROM t1 RIGHT JOIN JSON_TABLE(t1.jc, '$' COLUMNS
|
||||||
(id FOR ORDINALITY)) as jt ON t1.jc=jt.id;
|
(id FOR ORDINALITY)) as jt ON t1.jc=jt.id;
|
||||||
|
|
||||||
# psergey!
|
# psergey!
|
||||||
--error ER_UNKNOWN_TABLE
|
#--error ER_UNKNOWN_TABLE
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
SELECT * FROM JSON_TABLE(t1.jc, '$' COLUMNS
|
SELECT * FROM JSON_TABLE(t1.jc, '$' COLUMNS
|
||||||
(id FOR ORDINALITY)) as jt LEFT JOIN t1 ON t1.jc=jt.id;
|
(id FOR ORDINALITY)) as jt LEFT JOIN t1 ON t1.jc=jt.id;
|
||||||
|
|
||||||
--error ER_UNKNOWN_TABLE
|
#--error ER_UNKNOWN_TABLE
|
||||||
SELECT * FROM JSON_TABLE(t1.jc, '$' COLUMNS
|
SELECT * FROM JSON_TABLE(t1.jc, '$' COLUMNS
|
||||||
(id FOR ORDINALITY)) as jt RIGHT JOIN t1 ON t1.jc=jt.id;
|
(id FOR ORDINALITY)) as jt RIGHT JOIN t1 ON t1.jc=jt.id;
|
||||||
|
|
||||||
@ -580,6 +582,7 @@ EXPLAIN SELECT * FROM t1 t1o RIGHT JOIN t1 ON t1o.id=t1.id
|
|||||||
|
|
||||||
# psergey:
|
# psergey:
|
||||||
#--error ER_BAD_FIELD_ERROR
|
#--error ER_BAD_FIELD_ERROR
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
SELECT * FROM t1 AS t1o RIGHT JOIN
|
SELECT * FROM t1 AS t1o RIGHT JOIN
|
||||||
(t1 AS t1i JOIN JSON_TABLE(t1o.jc, '$' COLUMNS
|
(t1 AS t1i JOIN JSON_TABLE(t1o.jc, '$' COLUMNS
|
||||||
(id FOR ORDINALITY)) as jt ON t1i.jc=jt.id)
|
(id FOR ORDINALITY)) as jt ON t1i.jc=jt.id)
|
||||||
@ -587,6 +590,7 @@ SELECT * FROM t1 AS t1o RIGHT JOIN
|
|||||||
|
|
||||||
# psergey:
|
# psergey:
|
||||||
#--error ER_UNKNOWN_TABLE
|
#--error ER_UNKNOWN_TABLE
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
SELECT * FROM t1 AS t1o RIGHT JOIN
|
SELECT * FROM t1 AS t1o RIGHT JOIN
|
||||||
(t1 AS t1i RIGHT JOIN JSON_TABLE(t1o.jc, '$' COLUMNS
|
(t1 AS t1i RIGHT JOIN JSON_TABLE(t1o.jc, '$' COLUMNS
|
||||||
(id FOR ORDINALITY)) as jt ON t1i.jc=jt.id)
|
(id FOR ORDINALITY)) as jt ON t1i.jc=jt.id)
|
||||||
@ -594,12 +598,14 @@ SELECT * FROM t1 AS t1o RIGHT JOIN
|
|||||||
|
|
||||||
# psergey:
|
# psergey:
|
||||||
#--error ER_UNKNOWN_TABLE
|
#--error ER_UNKNOWN_TABLE
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
WITH qn AS
|
WITH qn AS
|
||||||
(SELECT jt.* FROM t1 RIGHT JOIN JSON_TABLE(t1.jc, '$' COLUMNS
|
(SELECT jt.* FROM t1 RIGHT JOIN JSON_TABLE(t1.jc, '$' COLUMNS
|
||||||
(id FOR ORDINALITY)) as jt ON t1.jc=jt.id)
|
(id FOR ORDINALITY)) as jt ON t1.jc=jt.id)
|
||||||
SELECT * from qn;
|
SELECT * from qn;
|
||||||
|
|
||||||
#--error ER_UNKNOWN_TABLE
|
#--error ER_UNKNOWN_TABLE
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
WITH qn AS
|
WITH qn AS
|
||||||
(SELECT 1 UNION
|
(SELECT 1 UNION
|
||||||
SELECT jt.id FROM t1 RIGHT JOIN JSON_TABLE(t1.jc, '$' COLUMNS
|
SELECT jt.id FROM t1 RIGHT JOIN JSON_TABLE(t1.jc, '$' COLUMNS
|
||||||
@ -607,12 +613,14 @@ WITH qn AS
|
|||||||
SELECT * from qn;
|
SELECT * from qn;
|
||||||
|
|
||||||
#--error ER_BAD_FIELD_ERROR
|
#--error ER_BAD_FIELD_ERROR
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
SELECT * FROM t1 AS t1o RIGHT JOIN
|
SELECT * FROM t1 AS t1o RIGHT JOIN
|
||||||
(t1 AS t1i JOIN JSON_TABLE(t1o.jc, '$' COLUMNS
|
(t1 AS t1i JOIN JSON_TABLE(t1o.jc, '$' COLUMNS
|
||||||
(id FOR ORDINALITY)) as jt ON t1i.jc=jt.id)
|
(id FOR ORDINALITY)) as jt ON t1i.jc=jt.id)
|
||||||
ON t1o.id=t1i.id;
|
ON t1o.id=t1i.id;
|
||||||
|
|
||||||
#--error ER_UNKNOWN_TABLE
|
#--error ER_UNKNOWN_TABLE
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
SELECT * FROM t1 AS t1o RIGHT JOIN
|
SELECT * FROM t1 AS t1o RIGHT JOIN
|
||||||
(t1 AS t1i RIGHT JOIN JSON_TABLE(t1o.jc, '$' COLUMNS
|
(t1 AS t1i RIGHT JOIN JSON_TABLE(t1o.jc, '$' COLUMNS
|
||||||
(id FOR ORDINALITY)) as jt ON t1i.jc=jt.id)
|
(id FOR ORDINALITY)) as jt ON t1i.jc=jt.id)
|
||||||
@ -628,7 +636,7 @@ SELECT * FROM t1 LEFT JOIN JSON_TABLE(t1.jc, '$' COLUMNS
|
|||||||
EXPLAIN SELECT * FROM t1 LEFT JOIN JSON_TABLE(t1.jc, '$' COLUMNS
|
EXPLAIN SELECT * FROM t1 LEFT JOIN JSON_TABLE(t1.jc, '$' COLUMNS
|
||||||
(id INT PATH '$')) as jt ON t1.id=jt.id;
|
(id INT PATH '$')) as jt ON t1.id=jt.id;
|
||||||
|
|
||||||
--error ER_WRONG_OUTER_JOIN
|
--error ER_BAD_FIELD_ERROR
|
||||||
SELECT * FROM t1
|
SELECT * FROM t1
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
JSON_TABLE(t1.jc, '$' COLUMNS (id FOR ORDINALITY)) as jt ON t1.jc=jt.id
|
JSON_TABLE(t1.jc, '$' COLUMNS (id FOR ORDINALITY)) as jt ON t1.jc=jt.id
|
||||||
|
@ -5543,6 +5543,8 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
|
|||||||
first_name_resolution_table,
|
first_name_resolution_table,
|
||||||
outer_context->
|
outer_context->
|
||||||
last_name_resolution_table,
|
last_name_resolution_table,
|
||||||
|
outer_context->
|
||||||
|
ignored_tables,
|
||||||
reference,
|
reference,
|
||||||
IGNORE_EXCEPT_NON_UNIQUE,
|
IGNORE_EXCEPT_NON_UNIQUE,
|
||||||
TRUE, TRUE)) !=
|
TRUE, TRUE)) !=
|
||||||
@ -5688,6 +5690,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
|
|||||||
find_field_in_tables(thd, this,
|
find_field_in_tables(thd, this,
|
||||||
context->first_name_resolution_table,
|
context->first_name_resolution_table,
|
||||||
context->last_name_resolution_table,
|
context->last_name_resolution_table,
|
||||||
|
context->ignored_tables,
|
||||||
reference, REPORT_ALL_ERRORS,
|
reference, REPORT_ALL_ERRORS,
|
||||||
!any_privileges, TRUE);
|
!any_privileges, TRUE);
|
||||||
}
|
}
|
||||||
@ -5854,6 +5857,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
|
|||||||
if ((from_field= find_field_in_tables(thd, this,
|
if ((from_field= find_field_in_tables(thd, this,
|
||||||
context->first_name_resolution_table,
|
context->first_name_resolution_table,
|
||||||
context->last_name_resolution_table,
|
context->last_name_resolution_table,
|
||||||
|
context->ignored_tables,
|
||||||
reference,
|
reference,
|
||||||
thd->lex->use_only_table_context ?
|
thd->lex->use_only_table_context ?
|
||||||
REPORT_ALL_ERRORS :
|
REPORT_ALL_ERRORS :
|
||||||
@ -7913,6 +7917,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
|
|||||||
first_name_resolution_table,
|
first_name_resolution_table,
|
||||||
outer_context->
|
outer_context->
|
||||||
last_name_resolution_table,
|
last_name_resolution_table,
|
||||||
|
outer_context->ignored_tables,
|
||||||
reference,
|
reference,
|
||||||
IGNORE_EXCEPT_NON_UNIQUE,
|
IGNORE_EXCEPT_NON_UNIQUE,
|
||||||
TRUE, TRUE);
|
TRUE, TRUE);
|
||||||
|
@ -232,6 +232,12 @@ struct Name_resolution_context: Sql_alloc
|
|||||||
*/
|
*/
|
||||||
bool resolve_in_select_list;
|
bool resolve_in_select_list;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Bitmap of tables that should be ignored when doing name resolution.
|
||||||
|
Normally it is {0}. Non-zero values are used by table functions.
|
||||||
|
*/
|
||||||
|
table_map ignored_tables;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Security context of this name resolution context. It's used for views
|
Security context of this name resolution context. It's used for views
|
||||||
and is non-zero only if the view is defined with SQL SECURITY DEFINER.
|
and is non-zero only if the view is defined with SQL SECURITY DEFINER.
|
||||||
@ -241,6 +247,7 @@ struct Name_resolution_context: Sql_alloc
|
|||||||
Name_resolution_context()
|
Name_resolution_context()
|
||||||
:outer_context(0), table_list(0), select_lex(0),
|
:outer_context(0), table_list(0), select_lex(0),
|
||||||
error_processor_data(0),
|
error_processor_data(0),
|
||||||
|
ignored_tables(0),
|
||||||
security_ctx(0)
|
security_ctx(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "item_jsonfunc.h"
|
#include "item_jsonfunc.h"
|
||||||
#include "json_table.h"
|
#include "json_table.h"
|
||||||
#include "sql_show.h"
|
#include "sql_show.h"
|
||||||
|
#include "sql_select.h"
|
||||||
|
|
||||||
#define HA_ERR_JSON_TABLE (HA_ERR_LAST+1)
|
#define HA_ERR_JSON_TABLE (HA_ERR_LAST+1)
|
||||||
|
|
||||||
@ -40,6 +41,111 @@ public:
|
|||||||
|
|
||||||
static table_function_handlerton table_function_hton;
|
static table_function_handlerton table_function_hton;
|
||||||
|
|
||||||
|
/*
|
||||||
|
@brief
|
||||||
|
Collect a bitmap of tables that a given table function cannot have
|
||||||
|
references to.
|
||||||
|
|
||||||
|
@detail
|
||||||
|
According to the SQL standard, a table function can refer to any table
|
||||||
|
that's "preceding" it in the FROM clause.
|
||||||
|
|
||||||
|
The other limitation we would like to enforce is that the inner side of
|
||||||
|
an outer join cannot refer to the outer side. An example:
|
||||||
|
|
||||||
|
SELECT * from JSON_TABLE(t1.col, ...) left join t1 on ...
|
||||||
|
|
||||||
|
This function implements both of the above restrictions.
|
||||||
|
|
||||||
|
Basic idea: the "join_list" contains the tables in the order that's a
|
||||||
|
reverse of the order they were specified in the query.
|
||||||
|
If we walk the join_list, we will encounter:
|
||||||
|
1. First, the tables that table function cannot refer to (collect them in a
|
||||||
|
bitmap)
|
||||||
|
2. Then, the table function itself (put it in the bitmap, too, as self-
|
||||||
|
references are not allowed, and stop the walk)
|
||||||
|
3. Tables that the table function CAN refer to (we don't walk these as
|
||||||
|
we've stopped on step #2).
|
||||||
|
|
||||||
|
The above can be applied recursively for nested joins (this covers NATURAL
|
||||||
|
JOIN, and JOIN ... USING constructs).
|
||||||
|
|
||||||
|
Enforcing the "refer to only preceding tables" rule means that outer side
|
||||||
|
of LEFT JOIN cannot refer to the inner side.
|
||||||
|
|
||||||
|
Handing RIGHT JOINs: There are no RIGHT JOINs in the join_list data
|
||||||
|
structures. They were converted to LEFT JOINs (see calls to st_select_lex::
|
||||||
|
convert_right_join). This conversion changes the order of tables, but
|
||||||
|
we are ok with operating on the tables "in the left join order".
|
||||||
|
|
||||||
|
@return
|
||||||
|
TRUE - enumeration has found the Table Function instance. The bitmap is
|
||||||
|
ready.
|
||||||
|
FALSE - Otherwise
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
static
|
||||||
|
bool get_disallowed_table_deps_for_list(table_map table_func_bit,
|
||||||
|
List<TABLE_LIST> *join_list,
|
||||||
|
table_map *disallowed_tables)
|
||||||
|
{
|
||||||
|
TABLE_LIST *table;
|
||||||
|
NESTED_JOIN *nested_join;
|
||||||
|
List_iterator<TABLE_LIST> li(*join_list);
|
||||||
|
|
||||||
|
while ((table= li++))
|
||||||
|
{
|
||||||
|
if ((nested_join= table->nested_join))
|
||||||
|
{
|
||||||
|
if (get_disallowed_table_deps_for_list(table_func_bit,
|
||||||
|
&nested_join->join_list,
|
||||||
|
disallowed_tables))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*disallowed_tables |= table->table->map;
|
||||||
|
if (table_func_bit == table->table->map)
|
||||||
|
{
|
||||||
|
// This is the JSON_TABLE(...) that are we're computing dependencies
|
||||||
|
// for.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@brief
|
||||||
|
Given a join and a table function in it (specified by its table_func_bit),
|
||||||
|
produce a bitmap of tables that the table function can NOT have references
|
||||||
|
to.
|
||||||
|
|
||||||
|
@detail
|
||||||
|
See get_disallowed_table_deps_for_list
|
||||||
|
|
||||||
|
@return
|
||||||
|
Bitmap of tables that table function can NOT have references to.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static
|
||||||
|
table_map get_disallowed_table_deps(JOIN *join, table_map table_func_bit)
|
||||||
|
{
|
||||||
|
table_map disallowed_tables= 0;
|
||||||
|
if (get_disallowed_table_deps_for_list(table_func_bit, join->join_list,
|
||||||
|
&disallowed_tables))
|
||||||
|
return disallowed_tables;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return disallowed_tables;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A table that produces output rows for JSON_TABLE().
|
A table that produces output rows for JSON_TABLE().
|
||||||
@ -1113,6 +1219,34 @@ void Table_function_json_table::end_nested_path()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@brief Create a name resolution context for doing name resolution in table
|
||||||
|
function argument.
|
||||||
|
|
||||||
|
@seealso
|
||||||
|
push_new_name_resolution_context
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool push_table_function_arg_context(LEX *lex, MEM_ROOT *alloc)
|
||||||
|
{
|
||||||
|
// Walk the context stack until we find a context that is select-level
|
||||||
|
// context.
|
||||||
|
List_iterator<Name_resolution_context> it(lex->context_stack);
|
||||||
|
Name_resolution_context *ctx= NULL;
|
||||||
|
while ((ctx= it++))
|
||||||
|
{
|
||||||
|
if (ctx->select_lex && ctx == &ctx->select_lex->context)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DBUG_ASSERT(ctx);
|
||||||
|
|
||||||
|
// Then, create a copy of it and return it.
|
||||||
|
Name_resolution_context *new_ctx= new (alloc) Name_resolution_context;
|
||||||
|
*new_ctx= *ctx;
|
||||||
|
return lex->push_context(new_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@brief
|
@brief
|
||||||
Perform name-resolution phase tasks
|
Perform name-resolution phase tasks
|
||||||
@ -1139,9 +1273,17 @@ int Table_function_json_table::setup(THD *thd, TABLE_LIST *sql_table,
|
|||||||
bool res;
|
bool res;
|
||||||
save_is_item_list_lookup= thd->lex->current_select->is_item_list_lookup;
|
save_is_item_list_lookup= thd->lex->current_select->is_item_list_lookup;
|
||||||
thd->lex->current_select->is_item_list_lookup= 0;
|
thd->lex->current_select->is_item_list_lookup= 0;
|
||||||
s_lex->end_lateral_table= sql_table;
|
|
||||||
|
// Prepare the name resolution context. First, copy the context that
|
||||||
|
// is using for name resolution of the WHERE clause
|
||||||
|
*m_context= thd->lex->current_select->context;
|
||||||
|
|
||||||
|
// Then, restrict it to only allow to refer to tables that come before the
|
||||||
|
// table function reference
|
||||||
|
m_context->ignored_tables= get_disallowed_table_deps(s_lex->join, t->map);
|
||||||
|
|
||||||
res= m_json->fix_fields_if_needed(thd, &m_json);
|
res= m_json->fix_fields_if_needed(thd, &m_json);
|
||||||
s_lex->end_lateral_table= NULL;
|
|
||||||
thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
|
thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
|
||||||
if (res)
|
if (res)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -224,6 +224,10 @@ public:
|
|||||||
void start_nested_path(Json_table_nested_path *np);
|
void start_nested_path(Json_table_nested_path *np);
|
||||||
void end_nested_path();
|
void end_nested_path();
|
||||||
Json_table_nested_path *get_cur_nested_path() { return cur_parent; }
|
Json_table_nested_path *get_cur_nested_path() { return cur_parent; }
|
||||||
|
void set_name_resolution_context(Name_resolution_context *arg)
|
||||||
|
{
|
||||||
|
m_context= arg;
|
||||||
|
}
|
||||||
|
|
||||||
/* SQL Parser: current column in JSON_TABLE (...) syntax */
|
/* SQL Parser: current column in JSON_TABLE (...) syntax */
|
||||||
Json_table_column *m_cur_json_table_column;
|
Json_table_column *m_cur_json_table_column;
|
||||||
@ -232,6 +236,8 @@ public:
|
|||||||
CHARSET_INFO *m_text_literal_cs;
|
CHARSET_INFO *m_text_literal_cs;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/* Context to be used for resolving the first argument. */
|
||||||
|
Name_resolution_context *m_context;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
the JSON argument can be taken from other tables.
|
the JSON argument can be taken from other tables.
|
||||||
@ -251,6 +257,7 @@ private:
|
|||||||
Json_table_nested_path **last_sibling_hook;
|
Json_table_nested_path **last_sibling_hook;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool push_table_function_arg_context(LEX *lex, MEM_ROOT *alloc);
|
||||||
|
|
||||||
TABLE *create_table_for_function(THD *thd, TABLE_LIST *sql_table);
|
TABLE *create_table_for_function(THD *thd, TABLE_LIST *sql_table);
|
||||||
|
|
||||||
|
@ -6319,6 +6319,8 @@ Field *find_field_in_table_sef(TABLE *table, const char *name)
|
|||||||
first_table list of tables to be searched for item
|
first_table list of tables to be searched for item
|
||||||
last_table end of the list of tables to search for item. If NULL
|
last_table end of the list of tables to search for item. If NULL
|
||||||
then search to the end of the list 'first_table'.
|
then search to the end of the list 'first_table'.
|
||||||
|
ignored_tables Bitmap of tables that should be ignored. Do not try
|
||||||
|
to find the field in those.
|
||||||
ref if 'item' is resolved to a view field, ref is set to
|
ref if 'item' is resolved to a view field, ref is set to
|
||||||
point to the found view field
|
point to the found view field
|
||||||
report_error Degree of error reporting:
|
report_error Degree of error reporting:
|
||||||
@ -6346,6 +6348,7 @@ Field *find_field_in_table_sef(TABLE *table, const char *name)
|
|||||||
Field *
|
Field *
|
||||||
find_field_in_tables(THD *thd, Item_ident *item,
|
find_field_in_tables(THD *thd, Item_ident *item,
|
||||||
TABLE_LIST *first_table, TABLE_LIST *last_table,
|
TABLE_LIST *first_table, TABLE_LIST *last_table,
|
||||||
|
table_map ignored_tables,
|
||||||
Item **ref, find_item_error_report_type report_error,
|
Item **ref, find_item_error_report_type report_error,
|
||||||
bool check_privileges, bool register_tree_change)
|
bool check_privileges, bool register_tree_change)
|
||||||
{
|
{
|
||||||
@ -6462,15 +6465,15 @@ find_field_in_tables(THD *thd, Item_ident *item,
|
|||||||
db= name_buff;
|
db= name_buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first_table && first_table->select_lex &&
|
if (last_table)
|
||||||
first_table->select_lex->end_lateral_table)
|
|
||||||
last_table= first_table->select_lex->end_lateral_table;
|
|
||||||
else if (last_table)
|
|
||||||
last_table= last_table->next_name_resolution_table;
|
last_table= last_table->next_name_resolution_table;
|
||||||
|
|
||||||
for (; cur_table != last_table ;
|
for (; cur_table != last_table ;
|
||||||
cur_table= cur_table->next_name_resolution_table)
|
cur_table= cur_table->next_name_resolution_table)
|
||||||
{
|
{
|
||||||
|
if (cur_table->table && (cur_table->table->map & ignored_tables))
|
||||||
|
continue;
|
||||||
|
|
||||||
Field *cur_field= find_field_in_table_ref(thd, cur_table, name, length,
|
Field *cur_field= find_field_in_table_ref(thd, cur_table, name, length,
|
||||||
item->name.str, db, table_name, ref,
|
item->name.str, db, table_name, ref,
|
||||||
(thd->lex->sql_command ==
|
(thd->lex->sql_command ==
|
||||||
|
@ -195,6 +195,7 @@ bool fill_record(THD *thd, TABLE *table, Field **field, List<Item> &values,
|
|||||||
Field *
|
Field *
|
||||||
find_field_in_tables(THD *thd, Item_ident *item,
|
find_field_in_tables(THD *thd, Item_ident *item,
|
||||||
TABLE_LIST *first_table, TABLE_LIST *last_table,
|
TABLE_LIST *first_table, TABLE_LIST *last_table,
|
||||||
|
table_map ignored_tables,
|
||||||
Item **ref, find_item_error_report_type report_error,
|
Item **ref, find_item_error_report_type report_error,
|
||||||
bool check_privileges, bool register_tree_change);
|
bool check_privileges, bool register_tree_change);
|
||||||
Field *
|
Field *
|
||||||
|
@ -99,6 +99,7 @@ static bool init_fields(THD *thd, TABLE_LIST *tables,
|
|||||||
Lex_cstring_strlen(find_fields->table_name),
|
Lex_cstring_strlen(find_fields->table_name),
|
||||||
Lex_cstring_strlen(find_fields->field_name)));
|
Lex_cstring_strlen(find_fields->field_name)));
|
||||||
if (!(find_fields->field= find_field_in_tables(thd, field, tables, NULL,
|
if (!(find_fields->field= find_field_in_tables(thd, field, tables, NULL,
|
||||||
|
table_map(0),
|
||||||
0, REPORT_ALL_ERRORS, 1,
|
0, REPORT_ALL_ERRORS, 1,
|
||||||
TRUE)))
|
TRUE)))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
@ -10115,7 +10115,7 @@ SELECT_LEX *LEX::parsed_subselect(SELECT_LEX_UNIT *unit)
|
|||||||
(curr_sel == NULL && current_select == &builtin_select));
|
(curr_sel == NULL && current_select == &builtin_select));
|
||||||
if (curr_sel)
|
if (curr_sel)
|
||||||
{
|
{
|
||||||
curr_sel->register_unit(unit, &curr_sel->context);
|
curr_sel->register_unit(unit, context_stack.head());
|
||||||
curr_sel->add_statistics(unit);
|
curr_sel->add_statistics(unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1184,8 +1184,6 @@ public:
|
|||||||
enum leaf_list_state {UNINIT, READY, SAVED};
|
enum leaf_list_state {UNINIT, READY, SAVED};
|
||||||
enum leaf_list_state prep_leaf_list_state;
|
enum leaf_list_state prep_leaf_list_state;
|
||||||
uint insert_tables;
|
uint insert_tables;
|
||||||
// Last table for LATERAL join, used by table functions
|
|
||||||
TABLE_LIST *end_lateral_table;
|
|
||||||
st_select_lex *merged_into; /* select which this select is merged into */
|
st_select_lex *merged_into; /* select which this select is merged into */
|
||||||
/* (not 0 only for views/derived tables) */
|
/* (not 0 only for views/derived tables) */
|
||||||
|
|
||||||
@ -1449,7 +1447,7 @@ public:
|
|||||||
ha_rows get_limit();
|
ha_rows get_limit();
|
||||||
|
|
||||||
friend struct LEX;
|
friend struct LEX;
|
||||||
st_select_lex() : group_list_ptrs(NULL), end_lateral_table(NULL), braces(0),
|
st_select_lex() : group_list_ptrs(NULL), braces(0),
|
||||||
automatic_brackets(0), n_sum_items(0), n_child_sum_items(0)
|
automatic_brackets(0), n_sum_items(0), n_child_sum_items(0)
|
||||||
{}
|
{}
|
||||||
void make_empty_select()
|
void make_empty_select()
|
||||||
|
@ -9007,6 +9007,10 @@ bool st_select_lex_unit::add_fake_select_lex(THD *thd_arg)
|
|||||||
@param left_op left operand of the JOIN
|
@param left_op left operand of the JOIN
|
||||||
@param right_op rigth operand of the JOIN
|
@param right_op rigth operand of the JOIN
|
||||||
|
|
||||||
|
@seealso
|
||||||
|
push_table_function_arg_context() serves similar purpose for table
|
||||||
|
functions
|
||||||
|
|
||||||
@retval
|
@retval
|
||||||
FALSE if all is OK
|
FALSE if all is OK
|
||||||
@retval
|
@retval
|
||||||
|
@ -24564,8 +24564,8 @@ find_order_in_list(THD *thd, Ref_ptr_array ref_pointer_array,
|
|||||||
order_item_type == Item::REF_ITEM)
|
order_item_type == Item::REF_ITEM)
|
||||||
{
|
{
|
||||||
from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables,
|
from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables,
|
||||||
NULL, &view_ref, IGNORE_ERRORS, FALSE,
|
NULL, table_map(0), &view_ref,
|
||||||
FALSE);
|
IGNORE_ERRORS, FALSE, FALSE);
|
||||||
if (!from_field)
|
if (!from_field)
|
||||||
from_field= (Field*) not_found_field;
|
from_field= (Field*) not_found_field;
|
||||||
}
|
}
|
||||||
|
@ -11683,29 +11683,38 @@ json_on_empty_response:
|
|||||||
;
|
;
|
||||||
|
|
||||||
table_function:
|
table_function:
|
||||||
JSON_TABLE_SYM '(' expr ','
|
JSON_TABLE_SYM '('
|
||||||
|
{
|
||||||
|
push_table_function_arg_context(Lex, thd->mem_root);
|
||||||
|
//TODO: introduce IN_TABLE_FUNC_ARGUMENT?
|
||||||
|
Select->parsing_place= IN_ON;
|
||||||
|
}
|
||||||
|
expr ','
|
||||||
{
|
{
|
||||||
Table_function_json_table *jt=
|
Table_function_json_table *jt=
|
||||||
new (thd->mem_root) Table_function_json_table($3);
|
new (thd->mem_root) Table_function_json_table($4);
|
||||||
if (unlikely(!jt))
|
if (unlikely(!jt))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
Lex->json_table= jt;
|
Lex->json_table= jt;
|
||||||
|
|
||||||
|
Select->parsing_place= NO_MATTER;
|
||||||
|
jt->set_name_resolution_context(Lex->pop_context());
|
||||||
}
|
}
|
||||||
json_text_literal json_table_columns_clause ')' opt_table_alias_clause
|
json_text_literal json_table_columns_clause ')' opt_table_alias_clause
|
||||||
{
|
{
|
||||||
SELECT_LEX *sel= Select;
|
SELECT_LEX *sel= Select;
|
||||||
if (unlikely($9 == NULL))
|
if (unlikely($10 == NULL))
|
||||||
{
|
{
|
||||||
/* Alias is not optional. */
|
/* Alias is not optional. */
|
||||||
my_error(ER_JSON_TABLE_ALIAS_REQUIRED, MYF(0));
|
my_error(ER_JSON_TABLE_ALIAS_REQUIRED, MYF(0));
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
if (unlikely(Lex->json_table->m_nested_path.set_path(thd, $6)))
|
if (unlikely(Lex->json_table->m_nested_path.set_path(thd, $7)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
sel->table_join_options= 0;
|
sel->table_join_options= 0;
|
||||||
if (!($$= Select->add_table_to_list(thd,
|
if (!($$= Select->add_table_to_list(thd,
|
||||||
new (thd->mem_root) Table_ident(thd, &empty_clex_str,
|
new (thd->mem_root) Table_ident(thd, &empty_clex_str,
|
||||||
$9, TRUE),
|
$10, TRUE),
|
||||||
NULL,
|
NULL,
|
||||||
Select->get_table_join_options() |
|
Select->get_table_join_options() |
|
||||||
TL_OPTION_TABLE_FUNCTION,
|
TL_OPTION_TABLE_FUNCTION,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user