Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
aeaf6d3c
Commit
aeaf6d3c
authored
Jan 31, 2007
by
gkodinov/kgeorge@rakia.gmz
Browse files
Options
Browse Files
Download
Plain Diff
Merge gkodinov@bk-internal.mysql.com:/home/bk/mysql-5.0-opt
into rakia.gmz:/home/kgeorge/mysql/autopush/B25575-5.0-opt
parents
066b2d81
16d2d682
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
140 additions
and
25 deletions
+140
-25
mysql-test/r/join_nested.result
mysql-test/r/join_nested.result
+28
-0
mysql-test/t/join_nested.test
mysql-test/t/join_nested.test
+39
-0
sql/mysql_priv.h
sql/mysql_priv.h
+2
-1
sql/sql_base.cc
sql/sql_base.cc
+40
-11
sql/sql_lex.h
sql/sql_lex.h
+14
-0
sql/sql_parse.cc
sql/sql_parse.cc
+6
-7
sql/sql_yacc.yy
sql/sql_yacc.yy
+10
-6
sql/table.cc
sql/table.cc
+1
-0
No files found.
mysql-test/r/join_nested.result
View file @
aeaf6d3c
...
...
@@ -1605,3 +1605,31 @@ WHERE t1.id='5';
id ct pc nm
5 NULL NULL NULL
DROP TABLE t1,t2,t3,t4;
CREATE TABLE t1 (a INT, b INT);
CREATE TABLE t2 (a INT);
CREATE TABLE t3 (a INT, c INT);
CREATE TABLE t4 (a INT, c INT);
CREATE TABLE t5 (a INT, c INT);
SELECT b FROM t1 JOIN (t2 LEFT JOIN t3 USING (a) LEFT JOIN t4 USING (a)
LEFT JOIN t5 USING (a)) USING (a);
b
SELECT c FROM t1 JOIN (t2 LEFT JOIN t3 USING (a) LEFT JOIN t4 USING (a)
LEFT JOIN t5 USING (a)) USING (a);
ERROR 23000: Column 'c' in field list is ambiguous
SELECT b FROM t1 JOIN (t2 JOIN t3 USING (a) JOIN t4 USING (a)
JOIN t5 USING (a)) USING (a);
b
SELECT c FROM t1 JOIN (t2 JOIN t3 USING (a) JOIN t4 USING (a)
JOIN t5 USING (a)) USING (a);
ERROR 23000: Column 'c' in field list is ambiguous
DROP TABLE t1,t2,t3,t4,t5;
CREATE TABLE t1 (a INT, b INT);
CREATE TABLE t2 (a INT, b INT);
CREATE TABLE t3 (a INT, b INT);
INSERT INTO t1 VALUES (1,1);
INSERT INTO t2 VALUES (1,1);
INSERT INTO t3 VALUES (1,1);
SELECT * FROM t1 JOIN (t2 JOIN t3 USING (b)) USING (a);
ERROR 23000: Column 'a' in from clause is ambiguous
DROP TABLE t1,t2,t3;
End of 5.0 tests
mysql-test/t/join_nested.test
View file @
aeaf6d3c
...
...
@@ -1045,3 +1045,42 @@ SELECT t1.*, t4.nm
WHERE
t1
.
id
=
'5'
;
DROP
TABLE
t1
,
t2
,
t3
,
t4
;
#
# BUG#25575: ERROR 1052 (Column in from clause is ambiguous) with sub-join
#
CREATE
TABLE
t1
(
a
INT
,
b
INT
);
CREATE
TABLE
t2
(
a
INT
);
CREATE
TABLE
t3
(
a
INT
,
c
INT
);
CREATE
TABLE
t4
(
a
INT
,
c
INT
);
CREATE
TABLE
t5
(
a
INT
,
c
INT
);
SELECT
b
FROM
t1
JOIN
(
t2
LEFT
JOIN
t3
USING
(
a
)
LEFT
JOIN
t4
USING
(
a
)
LEFT
JOIN
t5
USING
(
a
))
USING
(
a
);
--
error
ER_NON_UNIQ_ERROR
SELECT
c
FROM
t1
JOIN
(
t2
LEFT
JOIN
t3
USING
(
a
)
LEFT
JOIN
t4
USING
(
a
)
LEFT
JOIN
t5
USING
(
a
))
USING
(
a
);
SELECT
b
FROM
t1
JOIN
(
t2
JOIN
t3
USING
(
a
)
JOIN
t4
USING
(
a
)
JOIN
t5
USING
(
a
))
USING
(
a
);
--
error
ER_NON_UNIQ_ERROR
SELECT
c
FROM
t1
JOIN
(
t2
JOIN
t3
USING
(
a
)
JOIN
t4
USING
(
a
)
JOIN
t5
USING
(
a
))
USING
(
a
);
DROP
TABLE
t1
,
t2
,
t3
,
t4
,
t5
;
CREATE
TABLE
t1
(
a
INT
,
b
INT
);
CREATE
TABLE
t2
(
a
INT
,
b
INT
);
CREATE
TABLE
t3
(
a
INT
,
b
INT
);
INSERT
INTO
t1
VALUES
(
1
,
1
);
INSERT
INTO
t2
VALUES
(
1
,
1
);
INSERT
INTO
t3
VALUES
(
1
,
1
);
--
error
ER_NON_UNIQ_ERROR
SELECT
*
FROM
t1
JOIN
(
t2
JOIN
t3
USING
(
b
))
USING
(
a
);
DROP
TABLE
t1
,
t2
,
t3
;
--
echo
End
of
5.0
tests
sql/mysql_priv.h
View file @
aeaf6d3c
...
...
@@ -985,7 +985,8 @@ bool push_new_name_resolution_context(THD *thd,
TABLE_LIST
*
left_op
,
TABLE_LIST
*
right_op
);
void
add_join_on
(
TABLE_LIST
*
b
,
Item
*
expr
);
void
add_join_natural
(
TABLE_LIST
*
a
,
TABLE_LIST
*
b
,
List
<
String
>
*
using_fields
);
void
add_join_natural
(
TABLE_LIST
*
a
,
TABLE_LIST
*
b
,
List
<
String
>
*
using_fields
,
SELECT_LEX
*
lex
);
bool
add_proc_to_list
(
THD
*
thd
,
Item
*
item
);
TABLE
*
unlink_open_table
(
THD
*
thd
,
TABLE
*
list
,
TABLE
*
find
);
void
update_non_unique_table_error
(
TABLE_LIST
*
update
,
...
...
sql/sql_base.cc
View file @
aeaf6d3c
...
...
@@ -2945,7 +2945,7 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
{
List_iterator_fast
<
Natural_join_column
>
field_it
(
*
(
table_ref
->
join_columns
));
Natural_join_column
*
nj_col
;
Natural_join_column
*
nj_col
,
*
curr_nj_col
;
Field
*
found_field
;
Query_arena
*
arena
,
backup
;
DBUG_ENTER
(
"find_field_in_natural_join"
);
...
...
@@ -2956,14 +2956,21 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
LINT_INIT
(
found_field
);
for
(;;)
for
(
nj_col
=
NULL
,
curr_nj_col
=
field_it
++
;
curr_nj_col
;
curr_nj_col
=
field_it
++
)
{
if
(
!
(
nj_col
=
field_it
++
))
DBUG_RETURN
(
NULL
);
if
(
!
my_strcasecmp
(
system_charset_info
,
nj_col
->
name
(),
name
))
break
;
if
(
!
my_strcasecmp
(
system_charset_info
,
curr_nj_col
->
name
(),
name
))
{
if
(
nj_col
)
{
my_error
(
ER_NON_UNIQ_ERROR
,
MYF
(
0
),
name
,
thd
->
where
);
DBUG_RETURN
(
NULL
);
}
nj_col
=
curr_nj_col
;
}
}
if
(
!
nj_col
)
DBUG_RETURN
(
NULL
);
if
(
nj_col
->
view_field
)
{
...
...
@@ -3774,9 +3781,16 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
{
bool
found
=
FALSE
;
const
char
*
field_name_1
;
/* true if field_name_1 is a member of using_fields */
bool
is_using_column_1
;
if
(
!
(
nj_col_1
=
it_1
.
get_or_create_column_ref
(
leaf_1
)))
goto
err
;
field_name_1
=
nj_col_1
->
name
();
is_using_column_1
=
using_fields
&&
test_if_string_in_list
(
field_name_1
,
using_fields
);
DBUG_PRINT
(
"info"
,
(
"field_name_1=%s.%s"
,
nj_col_1
->
table_name
()
?
nj_col_1
->
table_name
()
:
""
,
field_name_1
));
/*
Find a field with the same name in table_ref_2.
...
...
@@ -3793,6 +3807,10 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
if
(
!
(
cur_nj_col_2
=
it_2
.
get_or_create_column_ref
(
leaf_2
)))
goto
err
;
cur_field_name_2
=
cur_nj_col_2
->
name
();
DBUG_PRINT
(
"info"
,
(
"cur_field_name_2=%s.%s"
,
cur_nj_col_2
->
table_name
()
?
cur_nj_col_2
->
table_name
()
:
""
,
cur_field_name_2
));
/*
Compare the two columns and check for duplicate common fields.
...
...
@@ -3800,10 +3818,16 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
table_ref_2 (then found == TRUE), or if a field in table_ref_2
was already matched by some previous field in table_ref_1
(then cur_nj_col_2->is_common == TRUE).
Note that it is too early to check the columns outside of the
USING list for ambiguity because they are not actually "referenced"
here. These columns must be checked only on unqualified reference
by name (e.g. in SELECT list).
*/
if
(
!
my_strcasecmp
(
system_charset_info
,
field_name_1
,
cur_field_name_2
))
{
if
(
found
||
cur_nj_col_2
->
is_common
)
DBUG_PRINT
(
"info"
,
(
"match c1.is_common=%d"
,
nj_col_1
->
is_common
));
if
(
cur_nj_col_2
->
is_common
||
(
found
&&
(
!
using_fields
||
is_using_column_1
)))
{
my_error
(
ER_NON_UNIQ_ERROR
,
MYF
(
0
),
field_name_1
,
thd
->
where
);
goto
err
;
...
...
@@ -3829,9 +3853,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
clause (if present), mark them as common fields, and add a new
equi-join condition to the ON clause.
*/
if
(
nj_col_2
&&
(
!
using_fields
||
test_if_string_in_list
(
field_name_1
,
using_fields
)))
if
(
nj_col_2
&&
(
!
using_fields
||
is_using_column_1
))
{
Item
*
item_1
=
nj_col_1
->
create_item
(
thd
);
Item
*
item_2
=
nj_col_2
->
create_item
(
thd
);
...
...
@@ -3886,6 +3908,13 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
eq_cond
);
nj_col_1
->
is_common
=
nj_col_2
->
is_common
=
TRUE
;
DBUG_PRINT
(
"info"
,
(
"%s.%s and %s.%s are common"
,
nj_col_1
->
table_name
()
?
nj_col_1
->
table_name
()
:
""
,
nj_col_1
->
name
(),
nj_col_2
->
table_name
()
?
nj_col_2
->
table_name
()
:
""
,
nj_col_2
->
name
()));
if
(
field_1
)
{
...
...
sql/sql_lex.h
View file @
aeaf6d3c
...
...
@@ -586,6 +586,20 @@ public:
int
cur_pos_in_select_list
;
List
<
udf_func
>
udf_list
;
/* udf function calls stack */
/*
This is a copy of the original JOIN USING list that comes from
the parser. The parser :
1. Sets the natural_join of the second TABLE_LIST in the join
and the st_select_lex::prev_join_using.
2. Makes a parent TABLE_LIST and sets its is_natural_join/
join_using_fields members.
3. Uses the wrapper TABLE_LIST as a table in the upper level.
We cannot assign directly to join_using_fields in the parser because
at stage (1.) the parent TABLE_LIST is not constructed yet and
the assignment will override the JOIN USING fields of the lower level
joins on the right.
*/
List
<
String
>
*
prev_join_using
;
void
init_query
();
void
init_select
();
...
...
sql/sql_parse.cc
View file @
aeaf6d3c
...
...
@@ -6432,11 +6432,8 @@ TABLE_LIST *st_select_lex::nest_last_join(THD *thd)
If this is a JOIN ... USING, move the list of joined fields to the
table reference that describes the join.
*/
if
(
table
->
join_using_fields
)
{
ptr
->
join_using_fields
=
table
->
join_using_fields
;
table
->
join_using_fields
=
NULL
;
}
if
(
prev_join_using
)
ptr
->
join_using_fields
=
prev_join_using
;
}
}
join_list
->
push_front
(
ptr
);
...
...
@@ -6692,6 +6689,7 @@ void add_join_on(TABLE_LIST *b, Item *expr)
a Left join argument
b Right join argument
using_fields Field names from USING clause
lex The current st_select_lex
IMPLEMENTATION
This function marks that table b should be joined with a either via
...
...
@@ -6720,10 +6718,11 @@ void add_join_on(TABLE_LIST *b, Item *expr)
None
*/
void
add_join_natural
(
TABLE_LIST
*
a
,
TABLE_LIST
*
b
,
List
<
String
>
*
using_fields
)
void
add_join_natural
(
TABLE_LIST
*
a
,
TABLE_LIST
*
b
,
List
<
String
>
*
using_fields
,
SELECT_LEX
*
lex
)
{
b
->
natural_join
=
a
;
b
->
join_using_fields
=
using_fields
;
lex
->
prev_join_using
=
using_fields
;
}
...
...
sql/sql_yacc.yy
View file @
aeaf6d3c
...
...
@@ -5466,11 +5466,11 @@ join_table:
YYERROR_UNLESS($1 && $3);
}
'(' using_list ')'
{ add_join_natural($1,$3,$7); $$=$3; }
{ add_join_natural($1,$3,$7
,Select
); $$=$3; }
| table_ref NATURAL JOIN_SYM table_factor
{
YYERROR_UNLESS($1 && ($$=$4));
add_join_natural($1,$4,NULL);
add_join_natural($1,$4,NULL
,Select
);
}
/* LEFT JOIN variants */
...
...
@@ -5497,11 +5497,15 @@ join_table:
YYERROR_UNLESS($1 && $5);
}
USING '(' using_list ')'
{ add_join_natural($1,$5,$9); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; }
{
add_join_natural($1,$5,$9,Select);
$5->outer_join|=JOIN_TYPE_LEFT;
$$=$5;
}
| table_ref NATURAL LEFT opt_outer JOIN_SYM table_factor
{
YYERROR_UNLESS($1 && $6);
add_join_natural($1,$6,NULL);
add_join_natural($1,$6,NULL
,Select
);
$6->outer_join|=JOIN_TYPE_LEFT;
$$=$6;
}
...
...
@@ -5535,12 +5539,12 @@ join_table:
LEX *lex= Lex;
if (!($$= lex->current_select->convert_right_join()))
YYABORT;
add_join_natural($$,$5,$9);
add_join_natural($$,$5,$9
,Select
);
}
| table_ref NATURAL RIGHT opt_outer JOIN_SYM table_factor
{
YYERROR_UNLESS($1 && $6);
add_join_natural($6,$1,NULL);
add_join_natural($6,$1,NULL
,Select
);
LEX *lex= Lex;
if (!($$= lex->current_select->convert_right_join()))
YYABORT;
...
...
sql/table.cc
View file @
aeaf6d3c
...
...
@@ -2630,6 +2630,7 @@ Field *Natural_join_column::field()
const
char
*
Natural_join_column
::
table_name
()
{
DBUG_ASSERT
(
table_ref
);
return
table_ref
->
alias
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment