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
92b44016
Commit
92b44016
authored
Mar 06, 2007
by
kostja@bodhi.local
Browse files
Options
Browse Files
Download
Plain Diff
Merge bodhi.local:/opt/local/work/mysql-5.0-runtime
into bodhi.local:/opt/local/work/mysql-5.1-runtime-merge
parents
3d488d49
f49f21dc
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
199 additions
and
52 deletions
+199
-52
client/mysql_upgrade.c
client/mysql_upgrade.c
+20
-9
mysql-test/t/subselect.test
mysql-test/t/subselect.test
+46
-19
sql/sql_base.cc
sql/sql_base.cc
+109
-5
sql/sql_yacc.yy
sql/sql_yacc.yy
+24
-19
No files found.
client/mysql_upgrade.c
View file @
92b44016
...
@@ -171,7 +171,7 @@ void set_extra_default(int id, const struct my_option *opt)
...
@@ -171,7 +171,7 @@ void set_extra_default(int id, const struct my_option *opt)
}
}
d
=
(
extra_default_t
*
)
my_malloc
(
sizeof
(
extra_default_t
),
d
=
(
extra_default_t
*
)
my_malloc
(
sizeof
(
extra_default_t
),
MYF
(
MY_FAE
|
MY_ZEROFILL
));
MYF
(
MY_FAE
|
MY_ZEROFILL
));
d
->
id
=
id
;
d
->
id
=
id
;
d
->
name
=
opt
->
name
;
d
->
name
=
opt
->
name
;
d
->
n_len
=
strlen
(
opt
->
name
);
d
->
n_len
=
strlen
(
opt
->
name
);
...
@@ -345,15 +345,17 @@ static int create_defaults_file(const char *path, const char *forced_path)
...
@@ -345,15 +345,17 @@ static int create_defaults_file(const char *path, const char *forced_path)
}
}
dynstr_set
(
&
buf
,
NULL
);
dynstr_set
(
&
buf
,
NULL
);
}
}
if
(
dynstr_append_mem
(
&
buf
,
"
\n
"
,
1
)
if
(
dynstr_append_mem
(
&
buf
,
"
\n
"
,
1
)
||
||
dynstr_append_mem
(
&
buf
,
d
->
name
,
d
->
n_len
)
dynstr_append_mem
(
&
buf
,
d
->
name
,
d
->
n_len
)
||
||
(
d
->
v_len
&&
(
dynstr_append_mem
(
&
buf
,
"="
,
1
)
(
d
->
v_len
&&
(
dynstr_append_mem
(
&
buf
,
"="
,
1
)
||
||
dynstr_append_mem
(
&
buf
,
d
->
value
,
d
->
v_len
))))
dynstr_append_mem
(
&
buf
,
d
->
value
,
d
->
v_len
))))
{
{
ret
=
1
;
ret
=
1
;
goto
error
;
goto
error
;
}
}
my_delete
((
gptr
)
d
,
MYF
(
0
));
my_delete
((
gptr
)
d
,
MYF
(
0
));
my_free
((
gptr
)
d
,
MYF
(
0
));
list_pop
(
extra_defaults
);
/* pop off the head */
list_pop
(
extra_defaults
);
/* pop off the head */
}
}
if
(
my_write
(
defaults_file
,
buf
.
str
,
buf
.
length
,
MYF
(
MY_FNABP
|
MY_WME
)))
if
(
my_write
(
defaults_file
,
buf
.
str
,
buf
.
length
,
MYF
(
MY_FNABP
|
MY_WME
)))
...
@@ -451,10 +453,10 @@ int main(int argc, char **argv)
...
@@ -451,10 +453,10 @@ int main(int argc, char **argv)
char
*
forced_extra_defaults
;
char
*
forced_extra_defaults
;
char
*
local_defaults_group_suffix
;
char
*
local_defaults_group_suffix
;
const
char
*
script_line
;
const
char
*
script_line
;
char
*
upgrade_defaults_path
=
0
;
char
*
upgrade_defaults_path
=
NULL
;
char
*
defaults_to_use
=
NULL
;
char
*
defaults_to_use
=
NULL
;
int
upgrade_defaults_created
=
0
;
int
upgrade_defaults_created
=
0
;
int
no_defaults
;
char
path
[
FN_REFLEN
];
char
path
[
FN_REFLEN
];
DYNAMIC_STRING
cmdline
;
DYNAMIC_STRING
cmdline
;
...
@@ -464,6 +466,10 @@ int main(int argc, char **argv)
...
@@ -464,6 +466,10 @@ int main(int argc, char **argv)
#endif
#endif
/* Check if we are forced to use specific defaults */
/* Check if we are forced to use specific defaults */
no_defaults
=
0
;
if
(
argc
>=
2
&&
!
strcmp
(
argv
[
1
],
"--no-defaults"
))
no_defaults
=
1
;
get_defaults_options
(
argc
,
argv
,
get_defaults_options
(
argc
,
argv
,
&
forced_defaults_file
,
&
forced_extra_defaults
,
&
forced_defaults_file
,
&
forced_extra_defaults
,
&
local_defaults_group_suffix
);
&
local_defaults_group_suffix
);
...
@@ -578,7 +584,9 @@ int main(int argc, char **argv)
...
@@ -578,7 +584,9 @@ int main(int argc, char **argv)
if
(
defaults_to_use
)
if
(
defaults_to_use
)
{
{
dynstr_append
(
&
cmdline
,
" "
);
dynstr_append
(
&
cmdline
,
" "
);
dynstr_append_os_quoted
(
&
cmdline
,
"--defaults-extra-file="
,
dynstr_append_os_quoted
(
&
cmdline
,
(
no_defaults
?
"--defaults-file="
:
"--defaults-extra-file="
),
defaults_to_use
,
NullS
);
defaults_to_use
,
NullS
);
}
}
...
@@ -652,7 +660,9 @@ fix_priv_tables:
...
@@ -652,7 +660,9 @@ fix_priv_tables:
if
(
defaults_to_use
)
if
(
defaults_to_use
)
{
{
dynstr_append
(
&
cmdline
,
" "
);
dynstr_append
(
&
cmdline
,
" "
);
dynstr_append_os_quoted
(
&
cmdline
,
"--defaults-extra-file="
,
dynstr_append_os_quoted
(
&
cmdline
,
(
no_defaults
?
"--defaults-file="
:
"--defaults-extra-file="
),
defaults_to_use
,
NullS
);
defaults_to_use
,
NullS
);
}
}
dynstr_append
(
&
cmdline
,
" "
);
dynstr_append
(
&
cmdline
,
" "
);
...
@@ -684,6 +694,7 @@ error:
...
@@ -684,6 +694,7 @@ error:
if
(
upgrade_defaults_created
)
if
(
upgrade_defaults_created
)
my_delete
(
upgrade_defaults_path
,
MYF
(
0
));
my_delete
(
upgrade_defaults_path
,
MYF
(
0
));
my_free
(
upgrade_defaults_path
,
MYF
(
MY_ALLOW_ZERO_PTR
));
my_end
(
info_flag
?
MY_CHECK_ERROR
:
0
);
my_end
(
info_flag
?
MY_CHECK_ERROR
:
0
);
return
ret
;
return
ret
;
}
}
...
...
mysql-test/t/subselect.test
View file @
92b44016
...
@@ -2002,7 +2002,7 @@ EXPLAIN SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
...
@@ -2002,7 +2002,7 @@ EXPLAIN SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
DROP
TABLE
t1
;
DROP
TABLE
t1
;
#
#
# Bug 24653: sorting by expressions containing subselects
# Bug 24653: sorting by expressions containing subselects
# that return more than one row
# that return more than one row
#
#
...
@@ -2014,12 +2014,12 @@ INSERT INTO t2 VALUES
...
@@ -2014,12 +2014,12 @@ INSERT INTO t2 VALUES
(
2
,
1
),
(
1
,
3
),
(
2
,
1
),
(
4
,
4
),
(
2
,
2
),
(
1
,
4
);
(
2
,
1
),
(
1
,
3
),
(
2
,
1
),
(
4
,
4
),
(
2
,
2
),
(
1
,
4
);
SELECT
a
FROM
t1
ORDER
BY
(
SELECT
c
FROM
t2
WHERE
b
>
2
);
SELECT
a
FROM
t1
ORDER
BY
(
SELECT
c
FROM
t2
WHERE
b
>
2
);
--
error
1242
--
error
1242
SELECT
a
FROM
t1
ORDER
BY
(
SELECT
c
FROM
t2
WHERE
b
>
1
);
SELECT
a
FROM
t1
ORDER
BY
(
SELECT
c
FROM
t2
WHERE
b
>
1
);
SELECT
a
FROM
t1
ORDER
BY
(
SELECT
c
FROM
t2
WHERE
b
>
2
),
a
;
SELECT
a
FROM
t1
ORDER
BY
(
SELECT
c
FROM
t2
WHERE
b
>
2
),
a
;
--
error
1242
--
error
1242
SELECT
a
FROM
t1
ORDER
BY
(
SELECT
c
FROM
t2
WHERE
b
>
1
),
a
;
SELECT
a
FROM
t1
ORDER
BY
(
SELECT
c
FROM
t2
WHERE
b
>
1
),
a
;
SELECT
b
,
MAX
(
c
)
FROM
t2
GROUP
BY
b
,
(
SELECT
c
FROM
t2
WHERE
b
>
2
);
SELECT
b
,
MAX
(
c
)
FROM
t2
GROUP
BY
b
,
(
SELECT
c
FROM
t2
WHERE
b
>
2
);
--
error
1242
--
error
1242
SELECT
b
,
MAX
(
c
)
FROM
t2
GROUP
BY
b
,
(
SELECT
c
FROM
t2
WHERE
b
>
1
);
SELECT
b
,
MAX
(
c
)
FROM
t2
GROUP
BY
b
,
(
SELECT
c
FROM
t2
WHERE
b
>
1
);
...
@@ -2036,28 +2036,28 @@ SELECT a FROM t1 GROUP BY a
...
@@ -2036,28 +2036,28 @@ SELECT a FROM t1 GROUP BY a
SELECT
a
FROM
t1
GROUP
BY
a
SELECT
a
FROM
t1
GROUP
BY
a
HAVING
IFNULL
((
SELECT
b
FROM
t2
WHERE
b
>
4
),
HAVING
IFNULL
((
SELECT
b
FROM
t2
WHERE
b
>
4
),
(
SELECT
c
FROM
t2
WHERE
c
=
a
AND
b
>
2
ORDER
BY
b
))
>
3
;
(
SELECT
c
FROM
t2
WHERE
c
=
a
AND
b
>
2
ORDER
BY
b
))
>
3
;
--
error
1242
--
error
1242
SELECT
a
FROM
t1
GROUP
BY
a
SELECT
a
FROM
t1
GROUP
BY
a
HAVING
IFNULL
((
SELECT
b
FROM
t2
WHERE
b
>
4
),
HAVING
IFNULL
((
SELECT
b
FROM
t2
WHERE
b
>
4
),
(
SELECT
c
FROM
t2
WHERE
c
=
a
AND
b
>
1
ORDER
BY
b
))
>
3
;
(
SELECT
c
FROM
t2
WHERE
c
=
a
AND
b
>
1
ORDER
BY
b
))
>
3
;
SELECT
a
FROM
t1
SELECT
a
FROM
t1
ORDER
BY
IFNULL
((
SELECT
b
FROM
t2
WHERE
b
>
2
),
ORDER
BY
IFNULL
((
SELECT
b
FROM
t2
WHERE
b
>
2
),
(
SELECT
c
FROM
t2
WHERE
c
=
a
AND
b
>
2
ORDER
BY
b
));
(
SELECT
c
FROM
t2
WHERE
c
=
a
AND
b
>
2
ORDER
BY
b
));
--
error
1242
--
error
1242
SELECT
a
FROM
t1
SELECT
a
FROM
t1
ORDER
BY
IFNULL
((
SELECT
b
FROM
t2
WHERE
b
>
1
),
ORDER
BY
IFNULL
((
SELECT
b
FROM
t2
WHERE
b
>
1
),
(
SELECT
c
FROM
t2
WHERE
c
=
a
AND
b
>
1
ORDER
BY
b
));
(
SELECT
c
FROM
t2
WHERE
c
=
a
AND
b
>
1
ORDER
BY
b
));
SELECT
a
FROM
t1
SELECT
a
FROM
t1
ORDER
BY
IFNULL
((
SELECT
b
FROM
t2
WHERE
b
>
4
),
ORDER
BY
IFNULL
((
SELECT
b
FROM
t2
WHERE
b
>
4
),
(
SELECT
c
FROM
t2
WHERE
c
=
a
AND
b
>
2
ORDER
BY
b
));
(
SELECT
c
FROM
t2
WHERE
c
=
a
AND
b
>
2
ORDER
BY
b
));
--
error
1242
--
error
1242
SELECT
a
FROM
t1
SELECT
a
FROM
t1
ORDER
BY
IFNULL
((
SELECT
b
FROM
t2
WHERE
b
>
4
),
ORDER
BY
IFNULL
((
SELECT
b
FROM
t2
WHERE
b
>
4
),
(
SELECT
c
FROM
t2
WHERE
c
=
a
AND
b
>
1
ORDER
BY
b
));
(
SELECT
c
FROM
t2
WHERE
c
=
a
AND
b
>
1
ORDER
BY
b
));
DROP
TABLE
t1
,
t2
;
DROP
TABLE
t1
,
t2
;
# End of 4.1 tests
# End of 4.1 tests
...
@@ -2571,7 +2571,7 @@ DROP TABLE t1,t2;
...
@@ -2571,7 +2571,7 @@ DROP TABLE t1,t2;
#
#
# Bug #25219: EXIST subquery with UNION over a mix of
# Bug #25219: EXIST subquery with UNION over a mix of
# correlated and uncorrelated selects
# correlated and uncorrelated selects
#
#
CREATE
TABLE
t1
(
id
char
(
4
)
PRIMARY
KEY
,
c
int
);
CREATE
TABLE
t1
(
id
char
(
4
)
PRIMARY
KEY
,
c
int
);
CREATE
TABLE
t2
(
c
int
);
CREATE
TABLE
t2
(
c
int
);
...
@@ -2579,25 +2579,25 @@ CREATE TABLE t2 (c int);
...
@@ -2579,25 +2579,25 @@ CREATE TABLE t2 (c int);
INSERT
INTO
t1
VALUES
(
'aa'
,
1
);
INSERT
INTO
t1
VALUES
(
'aa'
,
1
);
INSERT
INTO
t2
VALUES
(
1
);
INSERT
INTO
t2
VALUES
(
1
);
SELECT
*
FROM
t1
SELECT
*
FROM
t1
WHERE
EXISTS
(
SELECT
c
FROM
t2
WHERE
c
=
1
WHERE
EXISTS
(
SELECT
c
FROM
t2
WHERE
c
=
1
UNION
UNION
SELECT
c
from
t2
WHERE
c
=
t1
.
c
);
SELECT
c
from
t2
WHERE
c
=
t1
.
c
);
INSERT
INTO
t1
VALUES
(
'bb'
,
2
),
(
'cc'
,
3
),
(
'dd'
,
1
);
INSERT
INTO
t1
VALUES
(
'bb'
,
2
),
(
'cc'
,
3
),
(
'dd'
,
1
);
SELECT
*
FROM
t1
SELECT
*
FROM
t1
WHERE
EXISTS
(
SELECT
c
FROM
t2
WHERE
c
=
1
WHERE
EXISTS
(
SELECT
c
FROM
t2
WHERE
c
=
1
UNION
UNION
SELECT
c
from
t2
WHERE
c
=
t1
.
c
);
SELECT
c
from
t2
WHERE
c
=
t1
.
c
);
INSERT
INTO
t2
VALUES
(
2
);
INSERT
INTO
t2
VALUES
(
2
);
CREATE
TABLE
t3
(
c
int
);
CREATE
TABLE
t3
(
c
int
);
INSERT
INTO
t3
VALUES
(
1
);
INSERT
INTO
t3
VALUES
(
1
);
SELECT
*
FROM
t1
SELECT
*
FROM
t1
WHERE
EXISTS
(
SELECT
t2
.
c
FROM
t2
JOIN
t3
ON
t2
.
c
=
t3
.
c
WHERE
t2
.
c
=
1
WHERE
EXISTS
(
SELECT
t2
.
c
FROM
t2
JOIN
t3
ON
t2
.
c
=
t3
.
c
WHERE
t2
.
c
=
1
UNION
UNION
SELECT
c
from
t2
WHERE
c
=
t1
.
c
);
SELECT
c
from
t2
WHERE
c
=
t1
.
c
);
DROP
TABLE
t1
,
t2
,
t3
;
DROP
TABLE
t1
,
t2
,
t3
;
...
@@ -2609,6 +2609,33 @@ CREATE TABLE t1 (s1 char(1));
...
@@ -2609,6 +2609,33 @@ CREATE TABLE t1 (s1 char(1));
INSERT
INTO
t1
VALUES
(
'a'
);
INSERT
INTO
t1
VALUES
(
'a'
);
SELECT
*
FROM
t1
WHERE
_utf8
'a'
=
ANY
(
SELECT
s1
FROM
t1
);
SELECT
*
FROM
t1
WHERE
_utf8
'a'
=
ANY
(
SELECT
s1
FROM
t1
);
DROP
TABLE
t1
;
DROP
TABLE
t1
;
#
# Bug#23800: Outer fields in correlated subqueries is used in a temporary
# table created for sorting.
#
CREATE
TABLE
t1
(
f1
int
);
CREATE
TABLE
t2
(
f2
int
,
f21
int
,
f3
timestamp
);
INSERT
INTO
t1
VALUES
(
1
),(
1
),(
2
),(
2
);
INSERT
INTO
t2
VALUES
(
1
,
1
,
"2004-02-29 11:11:11"
),
(
2
,
2
,
"2004-02-29 11:11:11"
);
SELECT
((
SELECT
f2
FROM
t2
WHERE
f21
=
f1
LIMIT
1
)
*
COUNT
(
f1
))
AS
sq
FROM
t1
GROUP
BY
f1
;
SELECT
(
SELECT
SUM
(
1
)
FROM
t2
ttt
GROUP
BY
t2
.
f3
LIMIT
1
)
AS
tt
FROM
t2
;
PREPARE
stmt1
FROM
'SELECT ((SELECT f2 FROM t2 WHERE f21=f1 LIMIT 1) * COUNT(f1)) AS sq FROM t1 GROUP BY f1'
;
EXECUTE
stmt1
;
EXECUTE
stmt1
;
DEALLOCATE
PREPARE
stmt1
;
SELECT
f2
,
AVG
(
f21
),
(
SELECT
t
.
f3
FROM
t2
AS
t
WHERE
t2
.
f2
=
t
.
f2
AND
t
.
f3
=
MAX
(
t2
.
f3
))
AS
test
FROM
t2
GROUP
BY
f2
;
DROP
TABLE
t1
,
t2
;
CREATE
TABLE
t1
(
a
int
,
b
INT
,
c
CHAR
(
10
)
NOT
NULL
);
INSERT
INTO
t1
VALUES
(
1
,
1
,
'a'
),
(
1
,
2
,
'b'
),
(
1
,
3
,
'c'
),
(
1
,
4
,
'd'
),
(
1
,
5
,
'e'
),
(
2
,
1
,
'f'
),
(
2
,
2
,
'g'
),
(
2
,
3
,
'h'
),
(
3
,
4
,
'i'
),
(
3
,
3
,
'j'
),
(
3
,
2
,
'k'
),
(
3
,
1
,
'l'
),
(
1
,
9
,
'm'
);
SELECT
a
,
MAX
(
b
),
(
SELECT
t
.
c
FROM
t1
AS
t
WHERE
t1
.
a
=
t
.
a
AND
t
.
b
=
MAX
(
t1
.
b
))
AS
test
FROM
t1
GROUP
BY
a
;
DROP
TABLE
t1
;
#
#
# Bug#21904 (parser problem when using IN with a double "(())")
# Bug#21904 (parser problem when using IN with a double "(())")
...
...
sql/sql_base.cc
View file @
92b44016
...
@@ -1850,6 +1850,13 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
...
@@ -1850,6 +1850,13 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
key_length
=
(
create_table_def_key
(
thd
,
key
,
table_list
,
1
)
-
key_length
=
(
create_table_def_key
(
thd
,
key
,
table_list
,
1
)
-
TMP_TABLE_KEY_EXTRA
);
TMP_TABLE_KEY_EXTRA
);
/*
Unless requested otherwise, try to resolve this table in the list
of temporary tables of this thread. In MySQL temporary tables
are always thread-local and "shadow" possible base tables with the
same name. This block implements the behaviour.
TODO: move this block into a separate function.
*/
if
(
!
table_list
->
skip_temporary
)
if
(
!
table_list
->
skip_temporary
)
{
{
for
(
table
=
thd
->
temporary_tables
;
table
;
table
=
table
->
next
)
for
(
table
=
thd
->
temporary_tables
;
table
;
table
=
table
->
next
)
...
@@ -1859,6 +1866,12 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
...
@@ -1859,6 +1866,12 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
!
memcmp
(
table
->
s
->
table_cache_key
.
str
,
key
,
!
memcmp
(
table
->
s
->
table_cache_key
.
str
,
key
,
key_length
+
TMP_TABLE_KEY_EXTRA
))
key_length
+
TMP_TABLE_KEY_EXTRA
))
{
{
/*
We're trying to use the same temporary table twice in a query.
Right now we don't support this because a temporary table
is always represented by only one TABLE object in THD, and
it can not be cloned. Emit an error for an unsupported behaviour.
*/
if
(
table
->
query_id
==
thd
->
query_id
||
if
(
table
->
query_id
==
thd
->
query_id
||
thd
->
prelocked_mode
&&
table
->
query_id
)
thd
->
prelocked_mode
&&
table
->
query_id
)
{
{
...
@@ -1878,6 +1891,13 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
...
@@ -1878,6 +1891,13 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
}
}
}
}
/*
The table is not temporary - if we're in pre-locked or LOCK TABLES
mode, let's try to find the requested table in the list of pre-opened
and locked tables. If the table is not there, return an error - we can't
open not pre-opened tables in pre-locked/LOCK TABLES mode.
TODO: move this block into a separate function.
*/
if
(
!
(
flags
&
MYSQL_OPEN_IGNORE_LOCKED_TABLES
)
&&
if
(
!
(
flags
&
MYSQL_OPEN_IGNORE_LOCKED_TABLES
)
&&
(
thd
->
locked_tables
||
thd
->
prelocked_mode
))
(
thd
->
locked_tables
||
thd
->
prelocked_mode
))
{
// Using table locks
{
// Using table locks
...
@@ -1949,7 +1969,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
...
@@ -1949,7 +1969,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
goto
reset
;
goto
reset
;
}
}
/*
/*
is it view
?
Is this table a view and not a base table
?
(it is work around to allow to open view with locked tables,
(it is work around to allow to open view with locked tables,
real fix will be made after definition cache will be made)
real fix will be made after definition cache will be made)
*/
*/
...
@@ -1981,8 +2001,32 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
...
@@ -1981,8 +2001,32 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
/*
Non pre-locked/LOCK TABLES mode, and the table is not temporary:
this is the normal use case.
Now we should:
- try to find the table in the table cache.
- if one of the discovered TABLE instances is name-locked
(table->s->version == 0) or some thread has started FLUSH TABLES
(refresh_version > table->s->version), back off -- we have to wait
until no one holds a name lock on the table.
- if there is no such TABLE in the name cache, read the table definition
and insert it into the cache.
We perform all of the above under LOCK_open which currently protects
the open cache (also known as table cache) and table definitions stored
on disk.
*/
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
/*
If it's the first table from a list of tables used in a query,
remember refresh_version (the version of open_cache state).
If the version changes while we're opening the remaining tables,
we will have to back off, close all the tables opened-so-far,
and try to reopen them.
Note: refresh_version is currently changed only during FLUSH TABLES.
*/
if
(
!
thd
->
open_tables
)
if
(
!
thd
->
open_tables
)
thd
->
version
=
refresh_version
;
thd
->
version
=
refresh_version
;
else
if
((
thd
->
version
!=
refresh_version
)
&&
else
if
((
thd
->
version
!=
refresh_version
)
&&
...
@@ -1999,6 +2043,16 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
...
@@ -1999,6 +2043,16 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
if
(
thd
->
handler_tables
)
if
(
thd
->
handler_tables
)
mysql_ha_flush
(
thd
,
(
TABLE_LIST
*
)
NULL
,
MYSQL_HA_REOPEN_ON_USAGE
,
TRUE
);
mysql_ha_flush
(
thd
,
(
TABLE_LIST
*
)
NULL
,
MYSQL_HA_REOPEN_ON_USAGE
,
TRUE
);
/*
Actually try to find the table in the open_cache.
The cache may contain several "TABLE" instances for the same
physical table. The instances that are currently "in use" by
some thread have their "in_use" member != NULL.
There is no good reason for having more than one entry in the
hash for the same physical table, except that we use this as
an implicit "pending locks queue" - see
wait_for_locked_table_names for details.
*/
for
(
table
=
(
TABLE
*
)
hash_first
(
&
open_cache
,
(
byte
*
)
key
,
key_length
,
for
(
table
=
(
TABLE
*
)
hash_first
(
&
open_cache
,
(
byte
*
)
key
,
key_length
,
&
state
);
&
state
);
table
&&
table
->
in_use
;
table
&&
table
->
in_use
;
...
@@ -2008,6 +2062,21 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
...
@@ -2008,6 +2062,21 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
/*
/*
Here we flush tables marked for flush. However we never flush log
Here we flush tables marked for flush. However we never flush log
tables here. They are flushed only on FLUSH LOGS.
tables here. They are flushed only on FLUSH LOGS.
Normally, table->s->version contains the value of
refresh_version from the moment when this table was
(re-)opened and added to the cache.
If since then we did (or just started) FLUSH TABLES
statement, refresh_version has been increased.
For "name-locked" TABLE instances, table->s->version is set
to 0 (see lock_table_name for details).
In case there is a pending FLUSH TABLES or a name lock, we
need to back off and re-start opening tables.
If we do not back off now, we may dead lock in case of lock
order mismatch with some other thread:
c1: name lock t1; -- sort of exclusive lock
c2: open t2; -- sort of shared lock
c1: name lock t2; -- blocks
c2: open t1; -- blocks
*/
*/
if
(
table
->
s
->
version
!=
refresh_version
&&
!
table
->
s
->
log_table
)
if
(
table
->
s
->
version
!=
refresh_version
&&
!
table
->
s
->
log_table
)
{
{
...
@@ -2023,16 +2092,35 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
...
@@ -2023,16 +2092,35 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
}
}
/*
/*
There is a refresh in progress for this table
Back off, part 1: mark the table as "unused" for the
Wait until the table is freed or the thread is killed.
purpose of name-locking by setting table->db_stat to 0. Do
that only for the tables in this thread that have an old
table->s->version (this is an optimization (?)).
table->db_stat == 0 signals wait_for_locked_table_names
that the tables in question are not used any more. See
table_is_used call for details.
*/
*/
close_old_data_files
(
thd
,
thd
->
open_tables
,
0
,
0
);
close_old_data_files
(
thd
,
thd
->
open_tables
,
0
,
0
);
/*
Back-off part 2: try to avoid "busy waiting" on the table:
if the table is in use by some other thread, we suspend
and wait till the operation is complete: when any
operation that juggles with table->s->version completes,
it broadcasts COND_refresh condition variable.
*/
if
(
table
->
in_use
!=
thd
)
if
(
table
->
in_use
!=
thd
)
{
/* wait_for_conditionwill unlock LOCK_open for us */
wait_for_condition
(
thd
,
&
LOCK_open
,
&
COND_refresh
);
wait_for_condition
(
thd
,
&
LOCK_open
,
&
COND_refresh
);
}
else
else
{
{
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
}
}
/*
There is a refresh in progress for this table.
Signal the caller that it has to try again.
*/
if
(
refresh
)
if
(
refresh
)
*
refresh
=
1
;
*
refresh
=
1
;
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
...
@@ -2040,6 +2128,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
...
@@ -2040,6 +2128,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
}
}
if
(
table
)
if
(
table
)
{
{
/* Unlink the table from "unused_tables" list. */
if
(
table
==
unused_tables
)
if
(
table
==
unused_tables
)
{
// First unused
{
// First unused
unused_tables
=
unused_tables
->
next
;
// Remove from link
unused_tables
=
unused_tables
->
next
;
// Remove from link
...
@@ -2052,6 +2141,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
...
@@ -2052,6 +2141,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
}
}
else
else
{
{
/* Insert a new TABLE instance into the open cache */
int
error
;
int
error
;
/* Free cache if too big */
/* Free cache if too big */
while
(
open_cache
.
records
>
table_cache_size
&&
unused_tables
)
while
(
open_cache
.
records
>
table_cache_size
&&
unused_tables
)
...
@@ -2906,6 +2996,10 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
...
@@ -2906,6 +2996,10 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
}
}
}
}
/*
For every table in the list of tables to open, try to find or open
a table.
*/
for
(
tables
=
*
start
;
tables
;
tables
=
tables
->
next_global
)
for
(
tables
=
*
start
;
tables
;
tables
=
tables
->
next_global
)
{
{
/*
/*
...
@@ -2920,6 +3014,12 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
...
@@ -2920,6 +3014,12 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
goto
process_view_routines
;
goto
process_view_routines
;
continue
;
continue
;
}
}
/*
If this TABLE_LIST object is a placeholder for an information_schema
table, create a temporary table to represent the information_schema
table in the query. Do not fill it yet - will be filled during
execution.
*/
if
(
tables
->
schema_table
)
if
(
tables
->
schema_table
)
{
{
if
(
!
mysql_schema_table
(
thd
,
thd
->
lex
,
tables
))
if
(
!
mysql_schema_table
(
thd
,
thd
->
lex
,
tables
))
...
@@ -2927,7 +3027,11 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
...
@@ -2927,7 +3027,11 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
(
*
counter
)
++
;
(
*
counter
)
++
;
/*
Not a placeholder: must be a base table or a view, and the table is
not opened yet. Try to open the table.
*/
if
(
!
tables
->
table
&&
if
(
!
tables
->
table
&&
!
(
tables
->
table
=
open_table
(
thd
,
tables
,
&
new_frm_mem
,
&
refresh
,
flags
)))
!
(
tables
->
table
=
open_table
(
thd
,
tables
,
&
new_frm_mem
,
&
refresh
,
flags
)))
{
{
...
@@ -3034,7 +3138,7 @@ process_view_routines:
...
@@ -3034,7 +3138,7 @@ process_view_routines:
{
{
/*
/*
Serious error during reading stored routines from mysql.proc table.
Serious error during reading stored routines from mysql.proc table.
Something
'
s wrong with the table or its contents, and an error has
Something
i
s wrong with the table or its contents, and an error has
been emitted; we must abort.
been emitted; we must abort.
*/
*/
result
=
-
1
;
result
=
-
1
;
...
...
sql/sql_yacc.yy
View file @
92b44016
...
@@ -47,7 +47,7 @@ const LEX_STRING null_lex_str={0,0};
...
@@ -47,7 +47,7 @@ const LEX_STRING null_lex_str={0,0};
#define yyoverflow(A,B,C,D,E,F) {ulong val= *(F); if (my_yyoverflow((B), (D), &val)) { yyerror((char*) (A)); return 2; } else { *(F)= (YYSIZE_T)val; }}
#define yyoverflow(A,B,C,D,E,F) {ulong val= *(F); if (my_yyoverflow((B), (D), &val)) { yyerror((char*) (A)); return 2; } else { *(F)= (YYSIZE_T)val; }}
#define YY
ERROR
_UNLESS(A) \
#define YY
ABORT
_UNLESS(A) \
if (!(A)) \
if (!(A)) \
{ \
{ \
yyerror(ER(ER_SYNTAX_ERROR)); \
yyerror(ER(ER_SYNTAX_ERROR)); \
...
@@ -421,6 +421,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
...
@@ -421,6 +421,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%}
%}
%pure_parser /* We have threads */
%pure_parser /* We have threads */
/*
Currently there is 251 shift/reduce conflict. We should not introduce
new conflicts any more.
*/
%expect 251
/*
/*
Comments for TOKENS.
Comments for TOKENS.
...
@@ -7140,7 +7145,7 @@ table_ref:
...
@@ -7140,7 +7145,7 @@ table_ref:
;
;
join_table_list:
join_table_list:
derived_table_list { YY
ERROR
_UNLESS($$=$1); }
derived_table_list { YY
ABORT
_UNLESS($$=$1); }
;
;
/* Warning - may return NULL in case of incomplete SELECT */
/* Warning - may return NULL in case of incomplete SELECT */
...
@@ -7148,7 +7153,7 @@ derived_table_list:
...
@@ -7148,7 +7153,7 @@ derived_table_list:
table_ref { $$=$1; }
table_ref { $$=$1; }
| derived_table_list ',' table_ref
| derived_table_list ',' table_ref
{
{
YY
ERROR
_UNLESS($1 && ($$=$3));
YY
ABORT
_UNLESS($1 && ($$=$3));
}
}
;
;
...
@@ -7167,13 +7172,13 @@ join_table:
...
@@ -7167,13 +7172,13 @@ join_table:
left-associative joins.
left-associative joins.
*/
*/
table_ref %prec TABLE_REF_PRIORITY normal_join table_ref
table_ref %prec TABLE_REF_PRIORITY normal_join table_ref
{ YY
ERROR
_UNLESS($1 && ($$=$3)); }
{ YY
ABORT
_UNLESS($1 && ($$=$3)); }
| table_ref STRAIGHT_JOIN table_factor
| table_ref STRAIGHT_JOIN table_factor
{ YY
ERROR
_UNLESS($1 && ($$=$3)); $3->straight=1; }
{ YY
ABORT
_UNLESS($1 && ($$=$3)); $3->straight=1; }
| table_ref normal_join table_ref
| table_ref normal_join table_ref
ON
ON
{
{
YY
ERROR
_UNLESS($1 && $3);
YY
ABORT
_UNLESS($1 && $3);
/* Change the current name resolution context to a local context. */
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(YYTHD, $1, $3))
if (push_new_name_resolution_context(YYTHD, $1, $3))
YYABORT;
YYABORT;
...
@@ -7188,7 +7193,7 @@ join_table:
...
@@ -7188,7 +7193,7 @@ join_table:
| table_ref STRAIGHT_JOIN table_factor
| table_ref STRAIGHT_JOIN table_factor
ON
ON
{
{
YY
ERROR
_UNLESS($1 && $3);
YY
ABORT
_UNLESS($1 && $3);
/* Change the current name resolution context to a local context. */
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(YYTHD, $1, $3))
if (push_new_name_resolution_context(YYTHD, $1, $3))
YYABORT;
YYABORT;
...
@@ -7204,13 +7209,13 @@ join_table:
...
@@ -7204,13 +7209,13 @@ join_table:
| table_ref normal_join table_ref
| table_ref normal_join table_ref
USING
USING
{
{
YY
ERROR
_UNLESS($1 && $3);
YY
ABORT
_UNLESS($1 && $3);
}
}
'(' using_list ')'
'(' using_list ')'
{ add_join_natural($1,$3,$7,Select); $$=$3; }
{ add_join_natural($1,$3,$7,Select); $$=$3; }
| table_ref NATURAL JOIN_SYM table_factor
| table_ref NATURAL JOIN_SYM table_factor
{
{
YY
ERROR
_UNLESS($1 && ($$=$4));
YY
ABORT
_UNLESS($1 && ($$=$4));
add_join_natural($1,$4,NULL,Select);
add_join_natural($1,$4,NULL,Select);
}
}
...
@@ -7218,7 +7223,7 @@ join_table:
...
@@ -7218,7 +7223,7 @@ join_table:
| table_ref LEFT opt_outer JOIN_SYM table_ref
| table_ref LEFT opt_outer JOIN_SYM table_ref
ON
ON
{
{
YY
ERROR
_UNLESS($1 && $5);
YY
ABORT
_UNLESS($1 && $5);
/* Change the current name resolution context to a local context. */
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(YYTHD, $1, $5))
if (push_new_name_resolution_context(YYTHD, $1, $5))
YYABORT;
YYABORT;
...
@@ -7234,7 +7239,7 @@ join_table:
...
@@ -7234,7 +7239,7 @@ join_table:
}
}
| table_ref LEFT opt_outer JOIN_SYM table_factor
| table_ref LEFT opt_outer JOIN_SYM table_factor
{
{
YY
ERROR
_UNLESS($1 && $5);
YY
ABORT
_UNLESS($1 && $5);
}
}
USING '(' using_list ')'
USING '(' using_list ')'
{
{
...
@@ -7244,7 +7249,7 @@ join_table:
...
@@ -7244,7 +7249,7 @@ join_table:
}
}
| table_ref NATURAL LEFT opt_outer JOIN_SYM table_factor
| table_ref NATURAL LEFT opt_outer JOIN_SYM table_factor
{
{
YY
ERROR
_UNLESS($1 && $6);
YY
ABORT
_UNLESS($1 && $6);
add_join_natural($1,$6,NULL,Select);
add_join_natural($1,$6,NULL,Select);
$6->outer_join|=JOIN_TYPE_LEFT;
$6->outer_join|=JOIN_TYPE_LEFT;
$$=$6;
$$=$6;
...
@@ -7254,7 +7259,7 @@ join_table:
...
@@ -7254,7 +7259,7 @@ join_table:
| table_ref RIGHT opt_outer JOIN_SYM table_ref
| table_ref RIGHT opt_outer JOIN_SYM table_ref
ON
ON
{
{
YY
ERROR
_UNLESS($1 && $5);
YY
ABORT
_UNLESS($1 && $5);
/* Change the current name resolution context to a local context. */
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(YYTHD, $1, $5))
if (push_new_name_resolution_context(YYTHD, $1, $5))
YYABORT;
YYABORT;
...
@@ -7271,7 +7276,7 @@ join_table:
...
@@ -7271,7 +7276,7 @@ join_table:
}
}
| table_ref RIGHT opt_outer JOIN_SYM table_factor
| table_ref RIGHT opt_outer JOIN_SYM table_factor
{
{
YY
ERROR
_UNLESS($1 && $5);
YY
ABORT
_UNLESS($1 && $5);
}
}
USING '(' using_list ')'
USING '(' using_list ')'
{
{
...
@@ -7282,7 +7287,7 @@ join_table:
...
@@ -7282,7 +7287,7 @@ join_table:
}
}
| table_ref NATURAL RIGHT opt_outer JOIN_SYM table_factor
| table_ref NATURAL RIGHT opt_outer JOIN_SYM table_factor
{
{
YY
ERROR
_UNLESS($1 && $6);
YY
ABORT
_UNLESS($1 && $6);
add_join_natural($6,$1,NULL,Select);
add_join_natural($6,$1,NULL,Select);
LEX *lex= Lex;
LEX *lex= Lex;
if (!($$= lex->current_select->convert_right_join()))
if (!($$= lex->current_select->convert_right_join()))
...
@@ -7325,7 +7330,7 @@ table_factor:
...
@@ -7325,7 +7330,7 @@ table_factor:
expr '}'
expr '}'
{
{
LEX *lex= Lex;
LEX *lex= Lex;
YY
ERROR
_UNLESS($3 && $7);
YY
ABORT
_UNLESS($3 && $7);
add_join_on($7,$10);
add_join_on($7,$10);
Lex->pop_context();
Lex->pop_context();
$7->outer_join|=JOIN_TYPE_LEFT;
$7->outer_join|=JOIN_TYPE_LEFT;
...
@@ -11511,21 +11516,21 @@ xa: XA_SYM begin_or_start xid opt_join_or_resume
...
@@ -11511,21 +11516,21 @@ xa: XA_SYM begin_or_start xid opt_join_or_resume
xid: text_string
xid: text_string
{
{
YY
ERROR
_UNLESS($1->length() <= MAXGTRIDSIZE);
YY
ABORT
_UNLESS($1->length() <= MAXGTRIDSIZE);
if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
YYABORT;
YYABORT;
Lex->xid->set(1L, $1->ptr(), $1->length(), 0, 0);
Lex->xid->set(1L, $1->ptr(), $1->length(), 0, 0);
}
}
| text_string ',' text_string
| text_string ',' text_string
{
{
YY
ERROR
_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
YY
ABORT
_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
YYABORT;
YYABORT;
Lex->xid->set(1L, $1->ptr(), $1->length(), $3->ptr(), $3->length());
Lex->xid->set(1L, $1->ptr(), $1->length(), $3->ptr(), $3->length());
}
}
| text_string ',' text_string ',' ulong_num
| text_string ',' text_string ',' ulong_num
{
{
YY
ERROR
_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
YY
ABORT
_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
YYABORT;
YYABORT;
Lex->xid->set($5, $1->ptr(), $1->length(), $3->ptr(), $3->length());
Lex->xid->set($5, $1->ptr(), $1->length(), $3->ptr(), $3->length());
...
...
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