summaryrefslogtreecommitdiff
path: root/sql/table.h
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2019-06-30 13:16:12 -0700
committerIgor Babaev <igor@askmonty.org>2019-07-11 13:39:21 -0700
commit8540fa83bb34df6a3d489a4e85c77692f36e3e26 (patch)
tree7a56a3d6652d25e7af8a3dafc15cbc7aaee09fab /sql/table.h
parent8997f20f12309d2660988f254415a343d6328835 (diff)
downloadmariadb-git-8540fa83bb34df6a3d489a4e85c77692f36e3e26.tar.gz
MDEV-19421 Basic 3-way join queries are not parsed.
The parser returned a syntax error message for the queries with join expressions like this t1 JOIN t2 [LEFT | RIGHT] JOIN t3 ON ... ON ... when the second operand of the outer JOIN operation with ON clause was another join expression with ON clause. In this expression the JOIN operator is right-associative, i.e. expression has to be parsed as the expression t1 JOIN (t2 [LEFT | RIGHT] JOIN t3 ON ... ) ON ... Such join expressions are hard to parse because the outer JOIN is left-associative if there is no ON clause for the first outer JOIN operator. The patch implements the solution when the JOIN operator is always parsed as right-associative and builds first the right-associative tree. If it happens that there is no corresponding ON clause for this operator the tree is converted to left-associative. The idea of the solution was taken from the patch by Martin Hansson "WL#8083: Fixed the join_table rule" from MySQL-8.0 code line. As the grammar rules related to join expressions in MySQL-8.0 and MariaDB-5.5+ are quite different MariaDB solution could not borrow any code from the MySQL-8.0 solution.
Diffstat (limited to 'sql/table.h')
-rw-r--r--sql/table.h24
1 files changed, 24 insertions, 0 deletions
diff --git a/sql/table.h b/sql/table.h
index c81ee68b0a6..66a51b9d4f5 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -46,6 +46,7 @@ struct TABLE_LIST;
class ACL_internal_schema_access;
class ACL_internal_table_access;
class Field;
+struct Name_resolution_context;
/*
Used to identify NESTED_JOIN structures within a join (applicable only to
@@ -1618,6 +1619,7 @@ struct TABLE_LIST
char *db, *alias, *table_name, *schema_table_name;
char *option; /* Used by cache index */
Item *on_expr; /* Used with outer join */
+ Name_resolution_context *on_context; /* For ON expressions */
Item *sj_on_expr;
/*
@@ -2332,9 +2334,31 @@ public:
};
+#define JOIN_OP_NEST 1
+#define REBALANCED_NEST 2
+
typedef struct st_nested_join
{
List<TABLE_LIST> join_list; /* list of elements in the nested join */
+ /*
+ Currently the valid values for nest type are:
+ JOIN_OP_NEST - for nest created for JOIN operation used as an operand in
+ a join expression, contains 2 elements;
+ JOIN_OP_NEST | REBALANCED_NEST - nest created after tree re-balancing
+ in st_select_lex::add_cross_joined_table(), contains 1 element;
+ 0 - for all other nests.
+ Examples:
+ 1. SELECT * FROM t1 JOIN t2 LEFT JOIN t3 ON t2.a=t3.a;
+ Here the nest created for LEFT JOIN at first has nest_type==JOIN_OP_NEST.
+ After re-balancing in st_select_lex::add_cross_joined_table() this nest
+ has nest_type==JOIN_OP_NEST | REBALANCED_NEST. The nest for JOIN created
+ in st_select_lex::add_cross_joined_table() has nest_type== JOIN_OP_NEST.
+ 2. SELECT * FROM t1 JOIN (t2 LEFT JOIN t3 ON t2.a=t3.a)
+ Here the nest created for LEFT JOIN has nest_type==0, because it's not
+ an operand in a join expression. The nest created for JOIN has nest_type
+ set to JOIN_OP_NEST.
+ */
+ uint nest_type;
/*
Bitmap of tables within this nested join (including those embedded within
its children), including tables removed by table elimination.