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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
dd0b8188
Commit
dd0b8188
authored
Nov 17, 2006
by
holyfoot/hf@deer.(none)
Browse files
Options
Browse Files
Download
Plain Diff
Merge mysql.com:/home/hf/work/mysql-5.0-mrg
into mysql.com:/home/hf/work/mysql-5.1-mrg
parents
fd810905
497ccd6b
Changes
20
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
324 additions
and
66 deletions
+324
-66
client/mysqltest.c
client/mysqltest.c
+79
-10
libmysqld/lib_sql.cc
libmysqld/lib_sql.cc
+1
-0
mysql-test/r/order_by.result
mysql-test/r/order_by.result
+27
-0
mysql-test/r/subselect.result
mysql-test/r/subselect.result
+32
-0
mysql-test/t/flush.test
mysql-test/t/flush.test
+0
-8
mysql-test/t/flush_block_commit.test
mysql-test/t/flush_block_commit.test
+0
-3
mysql-test/t/innodb-lock.test
mysql-test/t/innodb-lock.test
+0
-2
mysql-test/t/lock_multi.test
mysql-test/t/lock_multi.test
+0
-8
mysql-test/t/order_by.test
mysql-test/t/order_by.test
+75
-0
mysql-test/t/rename.test
mysql-test/t/rename.test
+0
-4
mysql-test/t/show_check.test
mysql-test/t/show_check.test
+1
-2
mysql-test/t/status.test
mysql-test/t/status.test
+0
-7
mysql-test/t/subselect.test
mysql-test/t/subselect.test
+33
-0
sql-common/client.c
sql-common/client.c
+2
-0
sql/item.cc
sql/item.cc
+30
-4
sql/item_subselect.cc
sql/item_subselect.cc
+26
-9
sql/item_subselect.h
sql/item_subselect.h
+4
-0
sql/protocol.cc
sql/protocol.cc
+8
-8
sql/protocol.h
sql/protocol.h
+0
-1
sql/sql_class.h
sql/sql_class.h
+6
-0
No files found.
client/mysqltest.c
View file @
dd0b8188
...
...
@@ -29,6 +29,7 @@
Matt Wagner <matt@mysql.com>
Monty
Jani
Holyfoot
*/
#define MTEST_VERSION "3.0"
...
...
@@ -220,6 +221,12 @@ struct st_connection
MYSQL
*
util_mysql
;
char
*
name
;
MYSQL_STMT
*
stmt
;
const
char
*
cur_query
;
int
cur_query_len
;
pthread_mutex_t
mutex
;
pthread_cond_t
cond
;
int
query_done
;
};
struct
st_connection
connections
[
128
];
struct
st_connection
*
cur_con
,
*
next_con
,
*
connections_end
;
...
...
@@ -458,7 +465,6 @@ void mysql_disable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
int
mysql_rpl_parse_enabled
(
MYSQL
*
mysql
__attribute__
((
unused
)))
{
return
1
;
}
my_bool
mysql_rpl_probe
(
MYSQL
*
mysql
__attribute__
((
unused
)))
{
return
1
;
}
#endif
void
replace_dynstr_append_mem
(
DYNAMIC_STRING
*
ds
,
const
char
*
val
,
int
len
);
void
replace_dynstr_append
(
DYNAMIC_STRING
*
ds
,
const
char
*
val
);
...
...
@@ -470,6 +476,56 @@ void handle_error(struct st_command*,
void
handle_no_error
(
struct
st_command
*
);
#ifdef EMBEDDED_LIBRARY
/*
send_one_query executes query in separate thread what is
necessary in embedded library to run 'send' in proper way.
This implementation doesn't handle errors returned
by mysql_send_query. It's technically possible, though
i don't see where it is needed.
*/
pthread_handler_decl
(
send_one_query
,
arg
)
{
struct
st_connection
*
cn
=
(
struct
st_connection
*
)
arg
;
mysql_thread_init
();
VOID
(
mysql_send_query
(
&
cn
->
mysql
,
cn
->
cur_query
,
cn
->
cur_query_len
));
mysql_thread_end
();
pthread_mutex_lock
(
&
cn
->
mutex
);
cn
->
query_done
=
1
;
VOID
(
pthread_cond_signal
(
&
cn
->
cond
));
pthread_mutex_unlock
(
&
cn
->
mutex
);
pthread_exit
(
0
);
return
0
;
}
static
int
do_send_query
(
struct
st_connection
*
cn
,
const
char
*
q
,
int
q_len
,
int
flags
)
{
pthread_t
tid
;
if
(
flags
&
QUERY_REAP_FLAG
)
return
mysql_send_query
(
&
cn
->
mysql
,
q
,
q_len
);
if
(
pthread_mutex_init
(
&
cn
->
mutex
,
NULL
)
||
pthread_cond_init
(
&
cn
->
cond
,
NULL
))
die
(
"Error in the thread library"
);
cn
->
cur_query
=
q
;
cn
->
cur_query_len
=
q_len
;
cn
->
query_done
=
0
;
if
(
pthread_create
(
&
tid
,
NULL
,
send_one_query
,
(
void
*
)
cn
))
die
(
"Cannot start new thread for query"
);
return
0
;
}
#else
/*EMBEDDED_LIBRARY*/
#define do_send_query(cn,q,q_len,flags) mysql_send_query(&cn->mysql, q, q_len)
#endif
/*EMBEDDED_LIBRARY*/
void
do_eval
(
DYNAMIC_STRING
*
query_eval
,
const
char
*
query
,
const
char
*
query_end
,
my_bool
pass_through_escape_chars
)
...
...
@@ -4498,7 +4554,6 @@ int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql)
}
/*
Run query using MySQL C API
...
...
@@ -4515,10 +4570,11 @@ int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql)
error - function will not return
*/
void
run_query_normal
(
MYSQL
*
mysql
,
struct
st_command
*
command
,
void
run_query_normal
(
struct
st_connection
*
cn
,
struct
st_command
*
command
,
int
flags
,
char
*
query
,
int
query_len
,
DYNAMIC_STRING
*
ds
,
DYNAMIC_STRING
*
ds_warnings
)
{
MYSQL
*
mysql
=
&
cn
->
mysql
;
MYSQL_RES
*
res
=
0
;
int
err
=
0
,
counter
=
0
;
DBUG_ENTER
(
"run_query_normal"
);
...
...
@@ -4530,14 +4586,26 @@ void run_query_normal(MYSQL *mysql, struct st_command *command,
/*
Send the query
*/
if
(
mysql_send_query
(
mysql
,
query
,
query_len
))
if
(
do_send_query
(
cn
,
query
,
query_len
,
flags
))
{
handle_error
(
command
,
mysql_errno
(
mysql
),
mysql_error
(
mysql
),
mysql_sqlstate
(
mysql
),
ds
);
goto
end
;
}
}
#ifdef EMBEDDED_LIBRARY
/*
Here we handle 'reap' command, so we need to check if the
query's thread was finished and probably wait
*/
else
if
(
flags
&
QUERY_REAP_FLAG
)
{
pthread_mutex_lock
(
&
cn
->
mutex
);
while
(
!
cn
->
query_done
)
pthread_cond_wait
(
&
cn
->
cond
,
&
cn
->
mutex
);
pthread_mutex_unlock
(
&
cn
->
mutex
);
}
#endif
/*EMBEDDED_LIBRARY*/
if
(
!
(
flags
&
QUERY_REAP_FLAG
))
DBUG_VOID_RETURN
;
...
...
@@ -5028,8 +5096,9 @@ int util_query(MYSQL* org_mysql, const char* query){
*/
void
run_query
(
MYSQL
*
mysql
,
struct
st_command
*
command
,
int
flags
)
void
run_query
(
struct
st_connection
*
cn
,
struct
st_command
*
command
,
int
flags
)
{
MYSQL
*
mysql
=
&
cn
->
mysql
;
DYNAMIC_STRING
*
ds
;
DYNAMIC_STRING
ds_result
;
DYNAMIC_STRING
ds_warnings
;
...
...
@@ -5186,7 +5255,7 @@ void run_query(MYSQL *mysql, struct st_command *command, int flags)
match_re
(
&
ps_re
,
query
))
run_query_stmt
(
mysql
,
command
,
query
,
query_len
,
ds
,
&
ds_warnings
);
else
run_query_normal
(
mysql
,
command
,
flags
,
query
,
query_len
,
run_query_normal
(
cn
,
command
,
flags
,
query
,
query_len
,
ds
,
&
ds_warnings
);
if
(
sp_created
)
...
...
@@ -5651,7 +5720,7 @@ int main(int argc, char **argv)
strmake
(
command
->
require_file
,
save_file
,
sizeof
(
save_file
));
save_file
[
0
]
=
0
;
}
run_query
(
&
cur_con
->
mysql
,
command
,
QUERY_REAP_FLAG
|
QUERY_SEND_FLAG
);
run_query
(
cur_con
,
command
,
QUERY_REAP_FLAG
|
QUERY_SEND_FLAG
);
display_result_vertically
=
old_display_result_vertically
;
command
->
last_argument
=
command
->
end
;
command_executed
++
;
...
...
@@ -5682,7 +5751,7 @@ int main(int argc, char **argv)
strmake
(
command
->
require_file
,
save_file
,
sizeof
(
save_file
));
save_file
[
0
]
=
0
;
}
run_query
(
&
cur_con
->
mysql
,
command
,
flags
);
run_query
(
cur_con
,
command
,
flags
);
command_executed
++
;
command
->
last_argument
=
command
->
end
;
break
;
...
...
@@ -5708,7 +5777,7 @@ int main(int argc, char **argv)
the query and read the result some time later when reap instruction
is given on this connection.
*/
run_query
(
&
cur_con
->
mysql
,
command
,
QUERY_SEND_FLAG
);
run_query
(
cur_con
,
command
,
QUERY_SEND_FLAG
);
command_executed
++
;
command
->
last_argument
=
command
->
end
;
break
;
...
...
libmysqld/lib_sql.cc
View file @
dd0b8188
...
...
@@ -100,6 +100,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
mysql
->
affected_rows
=
~
(
my_ulonglong
)
0
;
mysql
->
field_count
=
0
;
net
->
last_errno
=
0
;
thd
->
current_stmt
=
stmt
;
thd
->
store_globals
();
// Fix if more than one connect
/*
...
...
mysql-test/r/order_by.result
View file @
dd0b8188
...
...
@@ -854,6 +854,33 @@ b a
20 1
10 2
DROP TABLE t1;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2);
SELECT a + 1 AS num FROM t1 ORDER BY 30 - num;
num
3
2
SELECT CONCAT('test', a) AS str FROM t1 ORDER BY UPPER(str);
str
test1
test2
SELECT a + 1 AS num FROM t1 GROUP BY 30 - num;
num
3
2
SELECT a + 1 AS num FROM t1 HAVING 30 - num;
num
2
3
SELECT a + 1 AS num, num + 1 FROM t1;
ERROR 42S22: Unknown column 'num' in 'field list'
SELECT a + 1 AS num, (select num + 2 FROM t1 LIMIT 1) FROM t1;
num (select num + 2 FROM t1 LIMIT 1)
2 4
3 5
SELECT a.a + 1 AS num FROM t1 a JOIN t1 b ON num = b.a;
ERROR 42S22: Unknown column 'num' in 'on clause'
DROP TABLE t1;
CREATE TABLE t1 (a int, b int, PRIMARY KEY (a));
INSERT INTO t1 VALUES (1,1), (2,2), (3,3);
explain SELECT t1.b as a, t2.b as c FROM
...
...
mysql-test/r/subselect.result
View file @
dd0b8188
...
...
@@ -3001,6 +3001,38 @@ field1 field2
1 1
1 3
DROP TABLE t1, t2;
CREATE TABLE t1(a int, INDEX (a));
INSERT INTO t1 VALUES (1), (3), (5), (7);
INSERT INTO t1 VALUES (NULL);
CREATE TABLE t2(a int);
INSERT INTO t2 VALUES (1),(2),(3);
EXPLAIN SELECT a, a IN (SELECT a FROM t1) FROM t2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 3
2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 2 Using index
SELECT a, a IN (SELECT a FROM t1) FROM t2;
a a IN (SELECT a FROM t1)
1 1
2 NULL
3 1
DROP TABLE t1,t2;
CREATE TABLE t1 (a DATETIME);
INSERT INTO t1 VALUES ('1998-09-23'), ('2003-03-25');
CREATE TABLE t2 AS SELECT
(SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a
FROM t1 WHERE a > '2000-01-01';
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`sub_a` datetime default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
CREATE TABLE t3 AS (SELECT a FROM t1 WHERE a < '2000-01-01') UNION (SELECT a FROM t1 WHERE a > '2000-01-01');
SHOW CREATE TABLE t3;
Table Create Table
t3 CREATE TABLE `t3` (
`a` datetime default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1,t2,t3;
create table t1 (df decimal(5,1));
insert into t1 values(1.1);
insert into t1 values(2.2);
...
...
mysql-test/t/flush.test
View file @
dd0b8188
# This test doesn't work with the embedded version as this code
# assumes that one query is running while we are doing queries on
# a second connection.
# This would work if mysqltest run would be threaded and handle each
# connection in a separate thread.
#
--
source
include
/
not_embedded
.
inc
connect
(
con1
,
localhost
,
root
,,);
connect
(
con2
,
localhost
,
root
,,);
connection
con1
;
...
...
mysql-test/t/flush_block_commit.test
View file @
dd0b8188
...
...
@@ -3,9 +3,6 @@
# We verify that we did not introduce a deadlock.
# This is intended to mimick how mysqldump and innobackup work.
# This test doesn't work with the embedded server
--
source
include
/
not_embedded
.
inc
# And it requires InnoDB
--
source
include
/
have_innodb
.
inc
...
...
mysql-test/t/innodb-lock.test
View file @
dd0b8188
--
source
include
/
have_innodb
.
inc
# Can't test this with embedded server
--
source
include
/
not_embedded
.
inc
#
# Check and select innodb lock type
...
...
mysql-test/t/lock_multi.test
View file @
dd0b8188
# This test doesn't work with the embedded version as this code
# assumes that one query is running while we are doing queries on
# a second connection.
# This would work if mysqltest run would be threaded and handle each
# connection in a separate thread.
#
--
source
include
/
not_embedded
.
inc
--
disable_warnings
drop
table
if
exists
t1
,
t2
;
--
enable_warnings
...
...
mysql-test/t/order_by.test
View file @
dd0b8188
...
...
@@ -514,6 +514,81 @@ set max_sort_length=20;
select
a
from
t1
order
by
a
;
drop
table
t1
;
#
# Bug #7331
#
create
table
t1
(
`sid`
decimal
(
8
,
0
)
default
null
,
`wnid`
varchar
(
11
)
not
null
default
''
,
key
`wnid14`
(
`wnid`
(
4
)),
key
`wnid`
(
`wnid`
)
)
engine
=
myisam
default
charset
=
latin1
;
insert
into
t1
(
`sid`
,
`wnid`
)
values
(
'10100'
,
'01019000000'
),(
'37986'
,
'01019000000'
),(
'37987'
,
'01019010000'
),
(
'39560'
,
'01019090000'
),(
'37989'
,
'01019000000'
),(
'37990'
,
'01019011000'
),
(
'37991'
,
'01019011000'
),(
'37992'
,
'01019019000'
),(
'37993'
,
'01019030000'
),
(
'37994'
,
'01019090000'
),(
'475'
,
'02070000000'
),(
'25253'
,
'02071100000'
),
(
'25255'
,
'02071100000'
),(
'25256'
,
'02071110000'
),(
'25258'
,
'02071130000'
),
(
'25259'
,
'02071190000'
),(
'25260'
,
'02071200000'
),(
'25261'
,
'02071210000'
),
(
'25262'
,
'02071290000'
),(
'25263'
,
'02071300000'
),(
'25264'
,
'02071310000'
),
(
'25265'
,
'02071310000'
),(
'25266'
,
'02071320000'
),(
'25267'
,
'02071320000'
),
(
'25269'
,
'02071330000'
),(
'25270'
,
'02071340000'
),(
'25271'
,
'02071350000'
),
(
'25272'
,
'02071360000'
),(
'25273'
,
'02071370000'
),(
'25281'
,
'02071391000'
),
(
'25282'
,
'02071391000'
),(
'25283'
,
'02071399000'
),(
'25284'
,
'02071400000'
),
(
'25285'
,
'02071410000'
),(
'25286'
,
'02071410000'
),(
'25287'
,
'02071420000'
),
(
'25288'
,
'02071420000'
),(
'25291'
,
'02071430000'
),(
'25290'
,
'02071440000'
),
(
'25292'
,
'02071450000'
),(
'25293'
,
'02071460000'
),(
'25294'
,
'02071470000'
),
(
'25295'
,
'02071491000'
),(
'25296'
,
'02071491000'
),(
'25297'
,
'02071499000'
);
explain
select
*
from
t1
where
wnid
like
'0101%'
order
by
wnid
;
select
*
from
t1
where
wnid
like
'0101%'
order
by
wnid
;
drop
table
t1
;
#
# Bug #7672 - a wrong result for a select query in braces followed by order by
#
CREATE
TABLE
t1
(
a
int
);
INSERT
INTO
t1
VALUES
(
2
),
(
1
),
(
1
),
(
2
),
(
1
);
SELECT
a
FROM
t1
ORDER
BY
a
;
(
SELECT
a
FROM
t1
)
ORDER
BY
a
;
DROP
TABLE
t1
;
#
# Bug #18767: global ORDER BY applied to a SELECT with ORDER BY either was
# ignored or 'concatened' to the latter.
CREATE
TABLE
t1
(
a
int
,
b
int
);
INSERT
INTO
t1
VALUES
(
1
,
30
),
(
2
,
20
),
(
1
,
10
),
(
2
,
30
),
(
1
,
20
),
(
2
,
10
);
(
SELECT
b
,
a
FROM
t1
ORDER
BY
a
,
b
)
ORDER
BY
b
,
a
;
(
SELECT
b
FROM
t1
ORDER
BY
b
DESC
)
ORDER
BY
b
ASC
;
(
SELECT
b
,
a
FROM
t1
ORDER
BY
b
,
a
)
ORDER
BY
a
,
b
;
(
SELECT
b
,
a
FROM
t1
ORDER
by
b
,
a
LIMIT
3
)
ORDER
by
a
,
b
;
DROP
TABLE
t1
;
#
# Bug #22457: Column alias in ORDER BY works, but not if in an expression
#
CREATE
TABLE
t1
(
a
INT
);
INSERT
INTO
t1
VALUES
(
1
),(
2
);
SELECT
a
+
1
AS
num
FROM
t1
ORDER
BY
30
-
num
;
SELECT
CONCAT
(
'test'
,
a
)
AS
str
FROM
t1
ORDER
BY
UPPER
(
str
);
SELECT
a
+
1
AS
num
FROM
t1
GROUP
BY
30
-
num
;
SELECT
a
+
1
AS
num
FROM
t1
HAVING
30
-
num
;
--
error
1054
SELECT
a
+
1
AS
num
,
num
+
1
FROM
t1
;
SELECT
a
+
1
AS
num
,
(
select
num
+
2
FROM
t1
LIMIT
1
)
FROM
t1
;
--
error
1054
SELECT
a
.
a
+
1
AS
num
FROM
t1
a
JOIN
t1
b
ON
num
=
b
.
a
;
DROP
TABLE
t1
;
# End of 4.1 tests
create
table
t1
(
a
int
not
null
,
b
int
not
null
,
c
int
not
null
);
insert
t1
values
(
1
,
1
,
1
),(
1
,
1
,
2
),(
1
,
2
,
1
);
select
a
,
b
from
t1
group
by
a
,
b
order
by
sum
(
c
);
...
...
mysql-test/t/rename.test
View file @
dd0b8188
...
...
@@ -2,10 +2,6 @@
# Test of rename table
#
# Test requires concurrent connections, which can't be tested on embedded
# server
--
source
include
/
not_embedded
.
inc
--
disable_warnings
drop
table
if
exists
t0
,
t1
,
t2
,
t3
,
t4
;
# Clear up from other tests (to ensure that SHOW TABLES below is right)
...
...
mysql-test/t/show_check.test
View file @
dd0b8188
# Requires use of multiple simultaneous connections, not supported with
# embedded server testing
# Uses GRANT commands that usually disabled in embedded server
--
source
include
/
not_embedded
.
inc
# check that CSV engine was compiled in, as the result of the test
...
...
mysql-test/t/status.test
View file @
dd0b8188
# This test doesn't work with the embedded version as this code
# assumes that one query is running while we are doing queries on
# a second connection.
# This would work if mysqltest run would be threaded and handle each
# connection in a separate thread.
#
--
source
include
/
not_embedded
.
inc
# PS causes different statistics
--
disable_ps_protocol
...
...
mysql-test/t/subselect.test
View file @
dd0b8188
...
...
@@ -1955,6 +1955,39 @@ SELECT field1, field2
DROP
TABLE
t1
,
t2
;
#
# Bug #23478: not top-level IN subquery returning a non-empty result set
# with possible NULL values by index access from the outer query
#
CREATE
TABLE
t1
(
a
int
,
INDEX
(
a
));
INSERT
INTO
t1
VALUES
(
1
),
(
3
),
(
5
),
(
7
);
INSERT
INTO
t1
VALUES
(
NULL
);
CREATE
TABLE
t2
(
a
int
);
INSERT
INTO
t2
VALUES
(
1
),(
2
),(
3
);
EXPLAIN
SELECT
a
,
a
IN
(
SELECT
a
FROM
t1
)
FROM
t2
;
SELECT
a
,
a
IN
(
SELECT
a
FROM
t1
)
FROM
t2
;
DROP
TABLE
t1
,
t2
;
#
# Bug #11302: getObject() returns a String for a sub-query of type datetime
#
CREATE
TABLE
t1
(
a
DATETIME
);
INSERT
INTO
t1
VALUES
(
'1998-09-23'
),
(
'2003-03-25'
);
CREATE
TABLE
t2
AS
SELECT
(
SELECT
a
FROM
t1
WHERE
a
<
'2000-01-01'
)
AS
sub_a
FROM
t1
WHERE
a
>
'2000-01-01'
;
SHOW
CREATE
TABLE
t2
;
CREATE
TABLE
t3
AS
(
SELECT
a
FROM
t1
WHERE
a
<
'2000-01-01'
)
UNION
(
SELECT
a
FROM
t1
WHERE
a
>
'2000-01-01'
);
SHOW
CREATE
TABLE
t3
;
DROP
TABLE
t1
,
t2
,
t3
;
# End of 4.1 tests
#
...
...
sql-common/client.c
View file @
dd0b8188
...
...
@@ -1186,6 +1186,8 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
for
(
row
=
data
->
data
;
row
;
row
=
row
->
next
,
field
++
)
{
uchar
*
pos
;
/* fields count may be wrong */
DBUG_ASSERT
((
field
-
result
)
<
fields
);
cli_fetch_lengths
(
&
lengths
[
0
],
row
->
data
,
default_value
?
8
:
7
);
field
->
catalog
=
strdup_root
(
alloc
,(
char
*
)
row
->
data
[
0
]);
field
->
db
=
strdup_root
(
alloc
,(
char
*
)
row
->
data
[
1
]);
...
...
sql/item.cc
View file @
dd0b8188
...
...
@@ -3672,12 +3672,38 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
Item
**
res
=
find_item_in_list
(
this
,
thd
->
lex
->
current_select
->
item_list
,
&
counter
,
REPORT_EXCEPT_NOT_FOUND
,
&
not_used
);
if
(
res
!=
(
Item
**
)
not_found_item
&&
(
*
res
)
->
type
()
==
Item
::
FIELD_ITEM
)
if
(
res
!=
(
Item
**
)
not_found_item
)
{
if
((
*
res
)
->
type
()
==
Item
::
FIELD_ITEM
)
{
/*
It's an Item_field referencing another Item_field in the select
list.
use the field from the Item_field in the select list and leave
the Item_field instance in place.
*/
set_field
((
*
((
Item_field
**
)
res
))
->
field
);
return
0
;
}
else
{
/*
It's not an Item_field in the select list so we must make a new
Item_ref to point to the Item in the select list and replace the
Item_field created by the parser with the new Item_ref.
*/
Item_ref
*
rf
=
new
Item_ref
(
db_name
,
table_name
,
field_name
);
if
(
!
rf
)
return
1
;
thd
->
change_item_tree
(
ref
,
rf
);
/*
Because Item_ref never substitutes itself with other items
in Item_ref::fix_fields(), we can safely use the original
pointer to it even after fix_fields()
*/
return
rf
->
fix_fields
(
thd
,
tables
,
ref
)
||
rf
->
check_cols
(
1
);
}
}
}
if
((
ret
=
fix_outer_field
(
thd
,
&
from_field
,
reference
))
<
0
)
goto
error
;
...
...
sql/item_subselect.cc
View file @
dd0b8188
...
...
@@ -434,6 +434,15 @@ enum Item_result Item_singlerow_subselect::result_type() const
return
engine
->
type
();
}
/*
Don't rely on the result type to calculate field type.
Ask the engine instead.
*/
enum_field_types
Item_singlerow_subselect
::
field_type
()
const
{
return
engine
->
field_type
();
}
void
Item_singlerow_subselect
::
fix_length_and_dec
()
{
if
((
max_columns
=
engine
->
cols
())
==
1
)
...
...
@@ -710,6 +719,7 @@ double Item_in_subselect::val_real()
*/
DBUG_ASSERT
(
0
);
DBUG_ASSERT
(
fixed
==
1
);
null_value
=
0
;
if
(
exec
())
{
reset
();
...
...
@@ -730,6 +740,7 @@ longlong Item_in_subselect::val_int()
*/
DBUG_ASSERT
(
0
);
DBUG_ASSERT
(
fixed
==
1
);
null_value
=
0
;
if
(
exec
())
{
reset
();
...
...
@@ -750,6 +761,7 @@ String *Item_in_subselect::val_str(String *str)
*/
DBUG_ASSERT
(
0
);
DBUG_ASSERT
(
fixed
==
1
);
null_value
=
0
;
if
(
exec
())
{
reset
();
...
...
@@ -1542,32 +1554,36 @@ int subselect_uniquesubquery_engine::prepare()
return
1
;
}
static
Item_result
set_row
(
List
<
Item
>
&
item_list
,
Item
*
item
,
Item_cache
**
row
,
bool
*
maybe_null
)
/*
makes storage for the output values for the subquery and calcuates
their data and column types and their nullability.
*/
void
subselect_engine
::
set_row
(
List
<
Item
>
&
item_list
,
Item_cache
**
row
)
{
Item_result
res_type
=
STRING_RESULT
;
Item
*
sel_item
;
List_iterator_fast
<
Item
>
li
(
item_list
);
res_type
=
STRING_RESULT
;
res_field_type
=
FIELD_TYPE_VAR_STRING
;
for
(
uint
i
=
0
;
(
sel_item
=
li
++
);
i
++
)
{
item
->
max_length
=
sel_item
->
max_length
;
res_type
=
sel_item
->
result_type
();
res_field_type
=
sel_item
->
field_type
();
item
->
decimals
=
sel_item
->
decimals
;
item
->
unsigned_flag
=
sel_item
->
unsigned_flag
;
*
maybe_null
=
sel_item
->
maybe_null
;
if
(
!
(
row
[
i
]
=
Item_cache
::
get_cache
(
res_type
)))
return
STRING_RESULT
;
// we should return something
return
;
row
[
i
]
->
setup
(
sel_item
);
}
if
(
item_list
.
elements
>
1
)
res_type
=
ROW_RESULT
;
return
res_type
;
}
void
subselect_single_select_engine
::
fix_length_and_dec
(
Item_cache
**
row
)
{
DBUG_ASSERT
(
row
||
select_lex
->
item_list
.
elements
==
1
);
res_type
=
set_row
(
select_lex
->
item_list
,
item
,
row
,
&
maybe_null
);
set_row
(
select_lex
->
item_list
,
row
);
item
->
collation
.
set
(
row
[
0
]
->
collation
);
if
(
cols
()
!=
1
)
maybe_null
=
0
;
...
...
@@ -1579,13 +1595,14 @@ void subselect_union_engine::fix_length_and_dec(Item_cache **row)
if
(
unit
->
first_select
()
->
item_list
.
elements
==
1
)
{
res_type
=
set_row
(
unit
->
types
,
item
,
row
,
&
maybe_null
);
set_row
(
unit
->
types
,
row
);
item
->
collation
.
set
(
row
[
0
]
->
collation
);
}
else
{
bool
fake
=
0
;
res_type
=
set_row
(
unit
->
types
,
item
,
row
,
&
fake
);
bool
maybe_null_saved
=
maybe_null
;
set_row
(
unit
->
types
,
row
);
maybe_null
=
maybe_null_saved
;
}
}
...
...
sql/item_subselect.h
View file @
dd0b8188
...
...
@@ -156,6 +156,7 @@ class Item_singlerow_subselect :public Item_subselect
my_decimal
*
val_decimal
(
my_decimal
*
);
bool
val_bool
();
enum
Item_result
result_type
()
const
;
enum_field_types
field_type
()
const
;
void
fix_length_and_dec
();
uint
cols
();
...
...
@@ -292,6 +293,7 @@ class subselect_engine: public Sql_alloc
THD
*
thd
;
/* pointer to current THD */
Item_subselect
*
item
;
/* item, that use this engine */
enum
Item_result
res_type
;
/* type of results */
enum_field_types
res_field_type
;
/* column type of the results */
bool
maybe_null
;
/* may be null (first item in select) */
public:
...
...
@@ -301,6 +303,7 @@ class subselect_engine: public Sql_alloc
result
=
res
;
item
=
si
;
res_type
=
STRING_RESULT
;
res_field_type
=
FIELD_TYPE_VAR_STRING
;
maybe_null
=
0
;
}
virtual
~
subselect_engine
()
{};
// to satisfy compiler
...
...
@@ -318,6 +321,7 @@ class subselect_engine: public Sql_alloc
virtual
uint
cols
()
=
0
;
/* return number of columns in select */
virtual
uint8
uncacheable
()
=
0
;
/* query is uncacheable */
enum
Item_result
type
()
{
return
res_type
;
}
enum_field_types
field_type
()
{
return
res_field_type
;
}
virtual
void
exclude
()
=
0
;
bool
may_be_null
()
{
return
maybe_null
;
};
virtual
table_map
upper_select_const_tables
()
=
0
;
...
...
sql/protocol.cc
View file @
dd0b8188
...
...
@@ -46,7 +46,7 @@ bool Protocol_prep::net_store_data(const char *from, uint length)
packet
->
realloc
(
packet_length
+
9
+
length
))
return
1
;
char
*
to
=
(
char
*
)
net_store_length
((
char
*
)
packet
->
ptr
()
+
packet_length
,
(
ulonglong
)
length
);
length
);
memcpy
(
to
,
from
,
length
);
packet
->
length
((
uint
)
(
to
+
length
-
packet
->
ptr
()));
return
0
;
...
...
@@ -282,8 +282,8 @@ send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message)
}
buff
[
0
]
=
0
;
// No fields
pos
=
net_store_length
(
buff
+
1
,
(
ulonglong
)
affected_rows
);
pos
=
net_store_length
(
pos
,
(
ulonglong
)
id
);
pos
=
net_store_length
(
buff
+
1
,
affected_rows
);
pos
=
net_store_length
(
pos
,
id
);
if
(
thd
->
client_capabilities
&
CLIENT_PROTOCOL_41
)
{
DBUG_PRINT
(
"info"
,
...
...
@@ -458,7 +458,7 @@ void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
ulonglong for bigger numbers.
*/
char
*
net_store_length
(
char
*
pkg
,
uint
length
)
static
char
*
net_store_length_fast
(
char
*
pkg
,
uint
length
)
{
uchar
*
packet
=
(
uchar
*
)
pkg
;
if
(
length
<
251
)
...
...
@@ -481,7 +481,7 @@ char *net_store_length(char *pkg, uint length)
char
*
net_store_data
(
char
*
to
,
const
char
*
from
,
uint
length
)
{
to
=
net_store_length
(
to
,
length
);
to
=
net_store_length
_fast
(
to
,
length
);
memcpy
(
to
,
from
,
length
);
return
to
+
length
;
}
...
...
@@ -490,7 +490,7 @@ char *net_store_data(char *to,int32 from)
{
char
buff
[
20
];
uint
length
=
(
uint
)
(
int10_to_str
(
from
,
buff
,
10
)
-
buff
);
to
=
net_store_length
(
to
,
length
);
to
=
net_store_length
_fast
(
to
,
length
);
memcpy
(
to
,
buff
,
length
);
return
to
+
length
;
}
...
...
@@ -499,7 +499,7 @@ char *net_store_data(char *to,longlong from)
{
char
buff
[
22
];
uint
length
=
(
uint
)
(
longlong10_to_str
(
from
,
buff
,
10
)
-
buff
);
to
=
net_store_length
(
to
,
length
);
to
=
net_store_length
_fast
(
to
,
length
);
memcpy
(
to
,
buff
,
length
);
return
to
+
length
;
}
...
...
@@ -563,7 +563,7 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
if
(
flags
&
SEND_NUM_ROWS
)
{
// Packet with number of elements
char
*
pos
=
net_store_length
(
buff
,
(
uint
)
list
->
elements
);
char
*
pos
=
net_store_length
(
buff
,
list
->
elements
);
(
void
)
my_net_write
(
&
thd
->
net
,
buff
,(
uint
)
(
pos
-
buff
));
}
...
...
sql/protocol.h
View file @
dd0b8188
...
...
@@ -166,7 +166,6 @@ void send_ok(THD *thd, ha_rows affected_rows=0L, ulonglong id=0L,
const
char
*
info
=
0
);
void
send_eof
(
THD
*
thd
);
bool
send_old_password_request
(
THD
*
thd
);
char
*
net_store_length
(
char
*
packet
,
uint
length
);
char
*
net_store_data
(
char
*
to
,
const
char
*
from
,
uint
length
);
char
*
net_store_data
(
char
*
to
,
int32
from
);
char
*
net_store_data
(
char
*
to
,
longlong
from
);
...
...
sql/sql_class.h
View file @
dd0b8188
...
...
@@ -838,6 +838,12 @@ class THD :public Statement,
struct
st_mysql_data
**
data_tail
;
void
clear_data_list
();
struct
st_mysql_data
*
alloc_new_dataset
();
/*
In embedded server it points to the statement that is processed
in the current query. We store some results directly in statement
fields then.
*/
struct
st_mysql_stmt
*
current_stmt
;
#endif
NET
net
;
// client connection descriptor
MEM_ROOT
warn_root
;
// For warnings and errors
...
...
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