mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
Merge bk-internal:/home/bk/mysql-5.0-maint
into pilot.blaudden:/home/msvensson/mysql/mysql-5.0-maint extra/comp_err.c: Auto merged sql/mysqld.cc: Auto merged
This commit is contained in:
commit
cc379fff6d
102 changed files with 3154 additions and 795 deletions
|
@ -17,7 +17,7 @@ noinst_SCRIPTS = Support/generate-text-files.pl
|
|||
|
||||
EXTRA_DIST = $(noinst_SCRIPTS) manual.chm mysql.info INSTALL-BINARY
|
||||
|
||||
TXT_FILES= ../INSTALL-SOURCE ../INSTALL-WIN-SOURCE ../EXCEPTIONS-CLIENT \
|
||||
TXT_FILES= ../INSTALL-SOURCE ../INSTALL-WIN-SOURCE \
|
||||
INSTALL-BINARY ../support-files/MacOSX/ReadMe.txt
|
||||
|
||||
all-local: $(TXT_FILES)
|
||||
|
@ -55,9 +55,6 @@ GT = $(srcdir)/Support/generate-text-files.pl
|
|||
INSTALL-BINARY: $(srcdir)/mysql.info $(GT)
|
||||
perl -w $(GT) $(srcdir)/mysql.info "installing-binary" "installing-source" > $@
|
||||
|
||||
../EXCEPTIONS-CLIENT: $(srcdir)/mysql.info $(GT)
|
||||
perl -w $(GT) $(srcdir)/mysql.info "mysql-floss-license-exception" "function-index" > $@
|
||||
|
||||
../support-files/MacOSX/ReadMe.txt: $(srcdir)/mysql.info $(GT)
|
||||
perl -w $(GT) $(srcdir)/mysql.info "mac-os-x-installation" "netware-installation" > $@
|
||||
|
||||
|
|
117
EXCEPTIONS-CLIENT
Normal file
117
EXCEPTIONS-CLIENT
Normal file
|
@ -0,0 +1,117 @@
|
|||
MySQL FLOSS License Exception
|
||||
|
||||
The MySQL AB Exception for Free/Libre and Open Source
|
||||
Software-only Applications Using MySQL Client Libraries (the
|
||||
"FLOSS Exception").
|
||||
|
||||
Version 0.5, 30 August 2006
|
||||
|
||||
Exception Intent
|
||||
|
||||
We want specified Free/Libre and Open Source Software (``FLOSS'')
|
||||
applications to be able to use specified GPL-licensed MySQL client
|
||||
libraries (the ``Program'') despite the fact that not all FLOSS
|
||||
licenses are compatible with version 2 of the GNU General Public
|
||||
License (the ``GPL'').
|
||||
|
||||
Legal Terms and Conditions
|
||||
|
||||
As a special exception to the terms and conditions of version 2.0
|
||||
of the GPL:
|
||||
|
||||
1. You are free to distribute a Derivative Work that is formed
|
||||
entirely from the Program and one or more works (each, a
|
||||
"FLOSS Work") licensed under one or more of the licenses
|
||||
listed below in section 1, as long as:
|
||||
a. You obey the GPL in all respects for the Program and the
|
||||
Derivative Work, except for identifiable sections of the
|
||||
Derivative Work which are not derived from the Program,
|
||||
and which can reasonably be considered independent and
|
||||
separate works in themselves,
|
||||
b. all identifiable sections of the Derivative Work which
|
||||
are not derived from the Program, and which can
|
||||
reasonably be considered independent and separate works
|
||||
in themselves,
|
||||
i. are distributed subject to one of the FLOSS licenses
|
||||
listed below, and
|
||||
ii. the object code or executable form of those sections
|
||||
are accompanied by the complete corresponding
|
||||
machine-readable source code for those sections on
|
||||
the same medium and under the same FLOSS license as
|
||||
the corresponding object code or executable forms of
|
||||
those sections, and
|
||||
c. any works which are aggregated with the Program or with a
|
||||
Derivative Work on a volume of a storage or distribution
|
||||
medium in accordance with the GPL, can reasonably be
|
||||
considered independent and separate works in themselves
|
||||
which are not derivatives of either the Program, a
|
||||
Derivative Work or a FLOSS Work.
|
||||
If the above conditions are not met, then the Program may only
|
||||
be copied, modified, distributed or used under the terms and
|
||||
conditions of the GPL or another valid licensing option from
|
||||
MySQL AB.
|
||||
|
||||
2. FLOSS License List
|
||||
|
||||
License name Version(s)/Copyright Date
|
||||
Academic Free License 2.0
|
||||
Apache Software License 1.0/1.1/2.0
|
||||
Apple Public Source License 2.0
|
||||
Artistic license From Perl 5.8.0
|
||||
BSD license "July 22 1999"
|
||||
Common Public License 1.0
|
||||
GNU Library or "Lesser" General Public License (LGPL) 2.0/2.1
|
||||
Jabber Open Source License 1.0
|
||||
MIT license ---
|
||||
Mozilla Public License (MPL) 1.0/1.1
|
||||
Open Software License 2.0
|
||||
OpenSSL license (with original SSLeay license) "2003" ("1998")
|
||||
PHP License 3.0
|
||||
Python license (CNRI Python License) ---
|
||||
Python Software Foundation License 2.1.1
|
||||
Sleepycat License "1999"
|
||||
University of Illinois/NCSA Open Source License ---
|
||||
W3C License "2001"
|
||||
X11 License "2001"
|
||||
Zlib/libpng License ---
|
||||
Zope Public License 2.0
|
||||
|
||||
Due to the many variants of some of the above licenses, we
|
||||
require that any version follow the 2003 version of the Free
|
||||
Software Foundation's Free Software Definition
|
||||
(http://www.gnu.org/philosophy/free-sw.html) or version 1.9 of
|
||||
the Open Source Definition by the Open Source Initiative
|
||||
(http://www.opensource.org/docs/definition.php).
|
||||
|
||||
3. Definitions
|
||||
|
||||
a. Terms used, but not defined, herein shall have the
|
||||
meaning provided in the GPL.
|
||||
b. Derivative Work means a derivative work under copyright
|
||||
law.
|
||||
|
||||
4. Applicability: This FLOSS Exception applies to all Programs
|
||||
that contain a notice placed by MySQL AB saying that the
|
||||
Program may be distributed under the terms of this FLOSS
|
||||
Exception. If you create or distribute a work which is a
|
||||
Derivative Work of both the Program and any other work
|
||||
licensed under the GPL, then this FLOSS Exception is not
|
||||
available for that work; thus, you must remove the FLOSS
|
||||
Exception notice from that work and comply with the GPL in all
|
||||
respects, including by retaining all GPL notices. You may
|
||||
choose to redistribute a copy of the Program exclusively under
|
||||
the terms of the GPL by removing the FLOSS Exception notice
|
||||
from that copy of the Program, provided that the copy has
|
||||
never been modified by you or any third party.
|
||||
|
||||
Appendix A. Qualified Libraries and Packages
|
||||
|
||||
The following is a non-exhaustive list of libraries and packages
|
||||
which are covered by the FLOSS License Exception. Please note that
|
||||
this appendix is provided merely as an additional service to
|
||||
specific FLOSS projects wishing to simplify licensing information
|
||||
for their users. Compliance with one of the licenses noted under
|
||||
the "FLOSS license list" section remains a prerequisite.
|
||||
|
||||
Package Name Qualifying License and Version
|
||||
Apache Portable Runtime (APR) Apache Software License 2.0
|
|
@ -903,32 +903,26 @@ Global
|
|||
{62E85884-3ACF-4F4C-873B-60B878147890}.Release.ActiveCfg = Release|Win32
|
||||
{62E85884-3ACF-4F4C-873B-60B878147890}.Release.Build.0 = Release|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.classic.ActiveCfg = classic|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.classic.Build.0 = classic|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.classic nt.ActiveCfg = classic|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.classic nt.Build.0 = classic|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Debug.ActiveCfg = Debug|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Debug.Build.0 = Debug|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Embedded_Classic.ActiveCfg = Release|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Embedded_Classic.Build.0 = Release|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Embedded_Debug.ActiveCfg = Debug|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Embedded_Debug.Build.0 = Debug|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Embedded_Pro.ActiveCfg = Release|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Embedded_Pro.Build.0 = Release|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Embedded_ProGPL.ActiveCfg = Release|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Embedded_ProGPL.Build.0 = Release|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Embedded_Release.ActiveCfg = Release|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Embedded_Release.Build.0 = Release|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Max.ActiveCfg = Release|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Max.Build.0 = Release|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Max nt.ActiveCfg = Release|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Max nt.Build.0 = Release|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.nt.ActiveCfg = Release|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.nt.Build.0 = Release|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.pro.ActiveCfg = pro|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.pro.Build.0 = pro|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.pro gpl.ActiveCfg = Release|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.pro gpl.Build.0 = Release|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.pro gpl nt.ActiveCfg = Release|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.pro gpl nt.Build.0 = Release|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.pro nt.ActiveCfg = pro|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.pro nt.Build.0 = pro|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Release.ActiveCfg = Release|Win32
|
||||
{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Release.Build.0 = Release|Win32
|
||||
{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.classic.ActiveCfg = classic|Win32
|
||||
{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.classic.Build.0 = classic|Win32
|
||||
{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.classic nt.ActiveCfg = classic|Win32
|
||||
|
@ -1011,32 +1005,26 @@ Global
|
|||
{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Release.ActiveCfg = Release|Win32
|
||||
{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Release.Build.0 = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.classic.ActiveCfg = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.classic.Build.0 = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.classic nt.ActiveCfg = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.classic nt.Build.0 = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.Debug.ActiveCfg = Debug|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.Debug.Build.0 = Debug|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.Embedded_Classic.ActiveCfg = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.Embedded_Classic.Build.0 = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.Embedded_Debug.ActiveCfg = Debug|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.Embedded_Debug.Build.0 = Debug|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.Embedded_Pro.ActiveCfg = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.Embedded_Pro.Build.0 = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.Embedded_ProGPL.ActiveCfg = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.Embedded_ProGPL.Build.0 = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.Embedded_Release.ActiveCfg = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.Embedded_Release.Build.0 = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.Max.ActiveCfg = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.Max.Build.0 = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.Max nt.ActiveCfg = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.Max nt.Build.0 = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.nt.ActiveCfg = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.nt.Build.0 = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.pro.ActiveCfg = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.pro.Build.0 = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.pro gpl.ActiveCfg = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.pro gpl.Build.0 = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.pro gpl nt.ActiveCfg = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.pro gpl nt.Build.0 = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.pro nt.ActiveCfg = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.pro nt.Build.0 = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.Release.ActiveCfg = Release|Win32
|
||||
{94B86159-C581-42CD-825D-C69CBC237E5C}.Release.Build.0 = Release|Win32
|
||||
{3737BFE2-EF25-464F-994D-BD28A9F84528}.classic.ActiveCfg = classic|Win32
|
||||
{3737BFE2-EF25-464F-994D-BD28A9F84528}.classic.Build.0 = classic|Win32
|
||||
{3737BFE2-EF25-464F-994D-BD28A9F84528}.classic nt.ActiveCfg = classic|Win32
|
||||
|
@ -1303,10 +1291,15 @@ Global
|
|||
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.classic nt.ActiveCfg = Release|Win32
|
||||
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Debug.ActiveCfg = Release|Win32
|
||||
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Embedded_Classic.ActiveCfg = Release|Win32
|
||||
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Embedded_Classic.Build.0 = Release|Win32
|
||||
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Embedded_Debug.ActiveCfg = Release|Win32
|
||||
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Embedded_Debug.Build.0 = Release|Win32
|
||||
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Embedded_Pro.ActiveCfg = Release|Win32
|
||||
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Embedded_Pro.Build.0 = Release|Win32
|
||||
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Embedded_ProGPL.ActiveCfg = Release|Win32
|
||||
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Embedded_ProGPL.Build.0 = Release|Win32
|
||||
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Embedded_Release.ActiveCfg = Release|Win32
|
||||
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Embedded_Release.Build.0 = Release|Win32
|
||||
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Max.ActiveCfg = Release|Win32
|
||||
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Max nt.ActiveCfg = Release|Win32
|
||||
{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.nt.ActiveCfg = Release|Win32
|
||||
|
|
|
@ -637,7 +637,7 @@ static struct message *find_message(struct errors *err, const char *lang,
|
|||
either.
|
||||
*/
|
||||
|
||||
static char checksum_format_specifier(const char* msg)
|
||||
static ha_checksum checksum_format_specifier(const char* msg)
|
||||
{
|
||||
ha_checksum chksum= 0;
|
||||
const char* p= msg;
|
||||
|
|
|
@ -1367,7 +1367,7 @@ mysql_stat(MYSQL *mysql)
|
|||
{
|
||||
DBUG_ENTER("mysql_stat");
|
||||
if (simple_command(mysql,COM_STATISTICS,0,0,0))
|
||||
return mysql->net.last_error;
|
||||
DBUG_RETURN(mysql->net.last_error);
|
||||
DBUG_RETURN((*mysql->methods->read_statistics)(mysql));
|
||||
}
|
||||
|
||||
|
|
|
@ -165,14 +165,14 @@ insert IGNORE into t1 values ('Garbage');
|
|||
|
||||
drop table t1;
|
||||
|
||||
create table t1 (fl geometry);
|
||||
create table t1 (fl geometry not null);
|
||||
--error 1416
|
||||
insert into t1 values (1);
|
||||
--error 1416
|
||||
insert into t1 values (1.11);
|
||||
--error 1416
|
||||
insert into t1 values ("qwerty");
|
||||
--error 1416
|
||||
--error 1048
|
||||
insert into t1 values (pointfromtext('point(1,1)'));
|
||||
|
||||
drop table t1;
|
||||
|
|
|
@ -1152,19 +1152,19 @@ select '-- select .. where date/time column = .. --' as test_sequence ;
|
|||
######## SELECT .. WHERE column(date/time/..)=value(CHAR(n)/LONGTEXT) ########
|
||||
set @arg00= '1991-01-01 01:01:01' ;
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= '1991-01-01 01:01:01' and c14= '1991-01-01 01:01:01' and
|
||||
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
|
||||
c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
|
||||
c17= '1991-01-01 01:01:01' ;
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= @arg00 and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
and c17= @arg00 ;
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= '1991-01-01 01:01:01' and c14= '1991-01-01 01:01:01' and
|
||||
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
|
||||
c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
|
||||
c17= '1991-01-01 01:01:01'" ;
|
||||
execute stmt1 ;
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= ? and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
|
||||
|
||||
|
||||
|
@ -1177,7 +1177,7 @@ where c1= 20 and c13= CAST('1991-01-01 01:01:01' as datetime) and
|
|||
c16= CAST('1991-01-01 01:01:01' as datetime) and
|
||||
c17= CAST('1991-01-01 01:01:01' as datetime) ;
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= @arg00 and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
and c17= @arg00 ;
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= CAST('1991-01-01 01:01:01' as datetime) and
|
||||
|
@ -1187,7 +1187,7 @@ where c1= 20 and c13= CAST('1991-01-01 01:01:01' as datetime) and
|
|||
c17= CAST('1991-01-01 01:01:01' as datetime)" ;
|
||||
execute stmt1 ;
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= ? and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
|
||||
|
||||
|
||||
|
|
|
@ -3043,6 +3043,7 @@ language = $path_language
|
|||
character-sets-dir = $path_charsetsdir
|
||||
basedir = $path_my_basedir
|
||||
server_id = $server_id
|
||||
shutdown-delay = 10
|
||||
skip-stack-trace
|
||||
skip-innodb
|
||||
skip-ndbcluster
|
||||
|
|
|
@ -446,7 +446,7 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
|||
insert IGNORE into t1 values ('Garbage');
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
drop table t1;
|
||||
create table t1 (fl geometry);
|
||||
create table t1 (fl geometry not null);
|
||||
insert into t1 values (1);
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
insert into t1 values (1.11);
|
||||
|
@ -454,5 +454,5 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
|||
insert into t1 values ("qwerty");
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
insert into t1 values (pointfromtext('point(1,1)'));
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
ERROR 23000: Column 'fl' cannot be null
|
||||
drop table t1;
|
||||
|
|
|
@ -446,7 +446,7 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
|||
insert IGNORE into t1 values ('Garbage');
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
drop table t1;
|
||||
create table t1 (fl geometry);
|
||||
create table t1 (fl geometry not null);
|
||||
insert into t1 values (1);
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
insert into t1 values (1.11);
|
||||
|
@ -454,5 +454,5 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
|||
insert into t1 values ("qwerty");
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
insert into t1 values (pointfromtext('point(1,1)'));
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
ERROR 23000: Column 'fl' cannot be null
|
||||
drop table t1;
|
||||
|
|
|
@ -128,3 +128,6 @@ f1 f2 if(f1, 40.0, 5.00)
|
|||
0 0 5.00
|
||||
1 1 40.00
|
||||
drop table t1;
|
||||
select if(0, 18446744073709551610, 18446744073709551610);
|
||||
if(0, 18446744073709551610, 18446744073709551610)
|
||||
18446744073709551610
|
||||
|
|
|
@ -141,4 +141,48 @@ t1 CREATE TABLE `t1` (
|
|||
`a` bigint(21) unsigned default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
drop table if exists table_26093;
|
||||
drop function if exists func_26093_a;
|
||||
drop function if exists func_26093_b;
|
||||
create table table_26093(a int);
|
||||
insert into table_26093 values
|
||||
(1), (2), (3), (4), (5),
|
||||
(6), (7), (8), (9), (10);
|
||||
create function func_26093_a(x int) returns int
|
||||
begin
|
||||
set @invoked := @invoked + 1;
|
||||
return x;
|
||||
end//
|
||||
create function func_26093_b(x int, y int) returns int
|
||||
begin
|
||||
set @invoked := @invoked + 1;
|
||||
return x;
|
||||
end//
|
||||
select avg(a) from table_26093;
|
||||
avg(a)
|
||||
5.5000
|
||||
select benchmark(100, (select avg(a) from table_26093));
|
||||
benchmark(100, (select avg(a) from table_26093))
|
||||
0
|
||||
set @invoked := 0;
|
||||
select benchmark(100, (select avg(func_26093_a(a)) from table_26093));
|
||||
benchmark(100, (select avg(func_26093_a(a)) from table_26093))
|
||||
0
|
||||
select @invoked;
|
||||
@invoked
|
||||
10
|
||||
set @invoked := 0;
|
||||
select benchmark(100, (select avg(func_26093_b(a, rand())) from table_26093));
|
||||
benchmark(100, (select avg(func_26093_b(a, rand())) from table_26093))
|
||||
0
|
||||
select @invoked;
|
||||
@invoked
|
||||
1000
|
||||
select benchmark(100, (select (a) from table_26093));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
select benchmark(100, (select 1, 1));
|
||||
ERROR 21000: Operand should contain 1 column(s)
|
||||
drop table table_26093;
|
||||
drop function func_26093_a;
|
||||
drop function func_26093_b;
|
||||
End of 5.0 tests
|
||||
|
|
|
@ -240,9 +240,7 @@ a
|
|||
10000
|
||||
select microsecond(19971231235959.01) as a;
|
||||
a
|
||||
0
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect time value: '19971231235959.01'
|
||||
10000
|
||||
select date_add("1997-12-31",INTERVAL "10.09" SECOND_MICROSECOND) as a;
|
||||
a
|
||||
1997-12-31 00:00:10.090000
|
||||
|
|
|
@ -1050,6 +1050,10 @@ H
|
|||
select last_day('0000-00-00');
|
||||
last_day('0000-00-00')
|
||||
NULL
|
||||
select isnull(week(now() + 0)), isnull(week(now() + 0.2)),
|
||||
week(20061108), week(20061108.01), week(20061108085411.000002);
|
||||
isnull(week(now() + 0)) isnull(week(now() + 0.2)) week(20061108) week(20061108.01) week(20061108085411.000002)
|
||||
0 0 45 45 45
|
||||
End of 4.1 tests
|
||||
explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1,
|
||||
timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a2;
|
||||
|
@ -1207,6 +1211,23 @@ SET NAMES DEFAULT;
|
|||
select str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE;
|
||||
str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE
|
||||
NULL
|
||||
create table t1 (field DATE);
|
||||
insert into t1 values ('2006-11-06');
|
||||
select * from t1 where field < '2006-11-06 04:08:36.0';
|
||||
field
|
||||
2006-11-06
|
||||
select * from t1 where field = '2006-11-06 04:08:36.0';
|
||||
field
|
||||
select * from t1 where field = '2006-11-06';
|
||||
field
|
||||
2006-11-06
|
||||
select * from t1 where CAST(field as DATETIME) < '2006-11-06 04:08:36.0';
|
||||
field
|
||||
2006-11-06
|
||||
select * from t1 where CAST(field as DATE) < '2006-11-06 04:08:36.0';
|
||||
field
|
||||
2006-11-06
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (a int, t1 time, t2 time, d date, PRIMARY KEY (a));
|
||||
INSERT INTO t1 VALUES (1, '10:00:00', NULL, NULL),
|
||||
(2, '11:00:00', '11:15:00', '1972-02-06');
|
||||
|
@ -1221,3 +1242,7 @@ t1 t2 SEC_TO_TIME( TIME_TO_SEC( t2 ) - TIME_TO_SEC( t1 ) ) QUARTER(d)
|
|||
11:00:00 11:15:00 00:15:00 1
|
||||
10:00:00 NULL NULL NULL
|
||||
DROP TABLE t1;
|
||||
SELECT TIME_FORMAT(SEC_TO_TIME(a),"%H:%i:%s") FROM (SELECT 3020399 AS a UNION SELECT 3020398 ) x GROUP BY 1;
|
||||
TIME_FORMAT(SEC_TO_TIME(a),"%H:%i:%s")
|
||||
838:59:58
|
||||
838:59:59
|
||||
|
|
|
@ -578,7 +578,7 @@ create table t1 select GeomFromWKB(POINT(1,3));
|
|||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`GeomFromWKB(POINT(1,3))` geometry NOT NULL default ''
|
||||
`GeomFromWKB(POINT(1,3))` geometry default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
CREATE TABLE `t1` (`object_id` bigint(20) unsigned NOT NULL default '0', `geo`
|
||||
|
@ -657,7 +657,7 @@ t1 where object_id=85984;
|
|||
object_id geometrytype(geo) ISSIMPLE(GEO) ASTEXT(centroid(geo))
|
||||
85984 MULTIPOLYGON 0 POINT(-114.87787186923 36.33101763469)
|
||||
drop table t1;
|
||||
create table t1 (fl geometry);
|
||||
create table t1 (fl geometry not null);
|
||||
insert into t1 values (1);
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
insert into t1 values (1.11);
|
||||
|
@ -665,7 +665,7 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
|||
insert into t1 values ("qwerty");
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
insert into t1 values (pointfromtext('point(1,1)'));
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
ERROR 23000: Column 'fl' cannot be null
|
||||
drop table t1;
|
||||
select (asWKT(geomfromwkb((0x000000000140240000000000004024000000000000))));
|
||||
(asWKT(geomfromwkb((0x000000000140240000000000004024000000000000))))
|
||||
|
@ -689,6 +689,48 @@ load data infile '../std_data_ln/bad_gis_data.dat' into table t1;
|
|||
ERROR 22004: Column was set to data type implicit default; NULL supplied for NOT NULL column 'b' at row 1
|
||||
alter table t1 enable keys;
|
||||
drop table t1;
|
||||
create table t1 (a int, b blob);
|
||||
insert into t1 values (1, ''), (2, NULL), (3, '1');
|
||||
select * from t1;
|
||||
a b
|
||||
1
|
||||
2 NULL
|
||||
3 1
|
||||
select
|
||||
geometryfromtext(b) IS NULL, geometryfromwkb(b) IS NULL, astext(b) IS NULL,
|
||||
aswkb(b) IS NULL, geometrytype(b) IS NULL, centroid(b) IS NULL,
|
||||
envelope(b) IS NULL, startpoint(b) IS NULL, endpoint(b) IS NULL,
|
||||
exteriorring(b) IS NULL, pointn(b, 1) IS NULL, geometryn(b, 1) IS NULL,
|
||||
interiorringn(b, 1) IS NULL, multipoint(b) IS NULL, isempty(b) IS NULL,
|
||||
issimple(b) IS NULL, isclosed(b) IS NULL, dimension(b) IS NULL,
|
||||
numgeometries(b) IS NULL, numinteriorrings(b) IS NULL, numpoints(b) IS NULL,
|
||||
area(b) IS NULL, glength(b) IS NULL, srid(b) IS NULL, x(b) IS NULL,
|
||||
y(b) IS NULL
|
||||
from t1;
|
||||
geometryfromtext(b) IS NULL geometryfromwkb(b) IS NULL astext(b) IS NULL aswkb(b) IS NULL geometrytype(b) IS NULL centroid(b) IS NULL envelope(b) IS NULL startpoint(b) IS NULL endpoint(b) IS NULL exteriorring(b) IS NULL pointn(b, 1) IS NULL geometryn(b, 1) IS NULL interiorringn(b, 1) IS NULL multipoint(b) IS NULL isempty(b) IS NULL issimple(b) IS NULL isclosed(b) IS NULL dimension(b) IS NULL numgeometries(b) IS NULL numinteriorrings(b) IS NULL numpoints(b) IS NULL area(b) IS NULL glength(b) IS NULL srid(b) IS NULL x(b) IS NULL y(b) IS NULL
|
||||
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
|
||||
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
|
||||
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
|
||||
select
|
||||
within(b, b) IS NULL, contains(b, b) IS NULL, overlaps(b, b) IS NULL,
|
||||
equals(b, b) IS NULL, disjoint(b, b) IS NULL, touches(b, b) IS NULL,
|
||||
intersects(b, b) IS NULL, crosses(b, b) IS NULL
|
||||
from t1;
|
||||
within(b, b) IS NULL contains(b, b) IS NULL overlaps(b, b) IS NULL equals(b, b) IS NULL disjoint(b, b) IS NULL touches(b, b) IS NULL intersects(b, b) IS NULL crosses(b, b) IS NULL
|
||||
1 1 1 1 1 1 1 1
|
||||
1 1 1 1 1 1 1 1
|
||||
1 1 1 1 1 1 1 1
|
||||
select
|
||||
point(b, b) IS NULL, linestring(b) IS NULL, polygon(b) IS NULL, multipoint(b) IS NULL,
|
||||
multilinestring(b) IS NULL, multipolygon(b) IS NULL,
|
||||
geometrycollection(b) IS NULL
|
||||
from t1;
|
||||
point(b, b) IS NULL linestring(b) IS NULL polygon(b) IS NULL multipoint(b) IS NULL multilinestring(b) IS NULL multipolygon(b) IS NULL geometrycollection(b) IS NULL
|
||||
0 1 1 1 1 1 1
|
||||
1 1 1 1 1 1 1
|
||||
0 1 1 1 1 1 1
|
||||
drop table t1;
|
||||
End of 4.1 tests
|
||||
create table t1 (s1 geometry not null,s2 char(100));
|
||||
create trigger t1_bu before update on t1 for each row set new.s1 = null;
|
||||
insert into t1 values (null,null);
|
||||
|
@ -715,7 +757,7 @@ drop table t1;
|
|||
create table t1 select GeomFromText('point(1 1)');
|
||||
desc t1;
|
||||
Field Type Null Key Default Extra
|
||||
GeomFromText('point(1 1)') geometry NO
|
||||
GeomFromText('point(1 1)') geometry YES NULL
|
||||
drop table t1;
|
||||
create table t1 (g geometry not null);
|
||||
insert into t1 values(default);
|
||||
|
|
|
@ -21,6 +21,6 @@ Success: the process was restarted.
|
|||
Success: server is ready to accept connection on socket.
|
||||
SHOW INSTANCE STATUS mysqld1;
|
||||
instance_name status version
|
||||
mysqld1 online VERSION
|
||||
mysqld1 STATE VERSION
|
||||
STOP INSTANCE mysqld2;
|
||||
Success: the process has been stopped.
|
||||
|
|
|
@ -87,13 +87,13 @@ where table_schema='test';
|
|||
table_name table_type table_comment
|
||||
t1 BASE TABLE
|
||||
v1 VIEW VIEW
|
||||
v2 VIEW View 'test.v2' references invalid table(s) or column(s) or function(s) or define
|
||||
v2 VIEW VIEW
|
||||
drop table t1;
|
||||
select table_name, table_type, table_comment from information_schema.tables
|
||||
where table_schema='test';
|
||||
table_name table_type table_comment
|
||||
v1 VIEW View 'test.v1' references invalid table(s) or column(s) or function(s) or define
|
||||
v2 VIEW View 'test.v2' references invalid table(s) or column(s) or function(s) or define
|
||||
v1 VIEW VIEW
|
||||
v2 VIEW VIEW
|
||||
drop function f1;
|
||||
drop function f2;
|
||||
drop view v1, v2;
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
INSERT INTO init_file.startup VALUES ( NOW() );
|
||||
SELECT * INTO @X FROM init_file.startup limit 0,1;
|
||||
SELECT * INTO @Y FROM init_file.startup limit 1,1;
|
||||
SELECT YEAR(@X)-YEAR(@Y);
|
||||
YEAR(@X)-YEAR(@Y)
|
||||
0
|
||||
DROP DATABASE init_file;
|
||||
ok
|
||||
end of 4.1 tests
|
||||
select * from t1;
|
||||
|
|
|
@ -446,7 +446,7 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
|||
insert IGNORE into t1 values ('Garbage');
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
drop table t1;
|
||||
create table t1 (fl geometry);
|
||||
create table t1 (fl geometry not null);
|
||||
insert into t1 values (1);
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
insert into t1 values (1.11);
|
||||
|
@ -454,5 +454,5 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
|||
insert into t1 values ("qwerty");
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
insert into t1 values (pointfromtext('point(1,1)'));
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
ERROR 23000: Column 'fl' cannot be null
|
||||
drop table t1;
|
||||
|
|
|
@ -446,7 +446,7 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
|||
insert IGNORE into t1 values ('Garbage');
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
drop table t1;
|
||||
create table t1 (fl geometry);
|
||||
create table t1 (fl geometry not null);
|
||||
insert into t1 values (1);
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
insert into t1 values (1.11);
|
||||
|
@ -454,7 +454,7 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
|||
insert into t1 values ("qwerty");
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
insert into t1 values (pointfromtext('point(1,1)'));
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
ERROR 23000: Column 'fl' cannot be null
|
||||
drop table t1;
|
||||
set engine_condition_pushdown = on;
|
||||
DROP TABLE IF EXISTS t1, gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry;
|
||||
|
@ -904,7 +904,7 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
|||
insert IGNORE into t1 values ('Garbage');
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
drop table t1;
|
||||
create table t1 (fl geometry);
|
||||
create table t1 (fl geometry not null);
|
||||
insert into t1 values (1);
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
insert into t1 values (1.11);
|
||||
|
@ -912,5 +912,5 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
|||
insert into t1 values ("qwerty");
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
insert into t1 values (pointfromtext('point(1,1)'));
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
ERROR 23000: Column 'fl' cannot be null
|
||||
drop table t1;
|
||||
|
|
|
@ -3046,25 +3046,25 @@ test_sequence
|
|||
-- select .. where date/time column = .. --
|
||||
set @arg00= '1991-01-01 01:01:01' ;
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= '1991-01-01 01:01:01' and c14= '1991-01-01 01:01:01' and
|
||||
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
|
||||
c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
|
||||
c17= '1991-01-01 01:01:01' ;
|
||||
found
|
||||
true
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= @arg00 and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
and c17= @arg00 ;
|
||||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= '1991-01-01 01:01:01' and c14= '1991-01-01 01:01:01' and
|
||||
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
|
||||
c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
|
||||
c17= '1991-01-01 01:01:01'" ;
|
||||
execute stmt1 ;
|
||||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= ? and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
|
||||
found
|
||||
true
|
||||
|
@ -3078,7 +3078,7 @@ c17= CAST('1991-01-01 01:01:01' as datetime) ;
|
|||
found
|
||||
true
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= @arg00 and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
and c17= @arg00 ;
|
||||
found
|
||||
true
|
||||
|
@ -3092,7 +3092,7 @@ execute stmt1 ;
|
|||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= ? and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
|
||||
found
|
||||
true
|
||||
|
|
|
@ -3029,25 +3029,25 @@ test_sequence
|
|||
-- select .. where date/time column = .. --
|
||||
set @arg00= '1991-01-01 01:01:01' ;
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= '1991-01-01 01:01:01' and c14= '1991-01-01 01:01:01' and
|
||||
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
|
||||
c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
|
||||
c17= '1991-01-01 01:01:01' ;
|
||||
found
|
||||
true
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= @arg00 and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
and c17= @arg00 ;
|
||||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= '1991-01-01 01:01:01' and c14= '1991-01-01 01:01:01' and
|
||||
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
|
||||
c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
|
||||
c17= '1991-01-01 01:01:01'" ;
|
||||
execute stmt1 ;
|
||||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= ? and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
|
||||
found
|
||||
true
|
||||
|
@ -3061,7 +3061,7 @@ c17= CAST('1991-01-01 01:01:01' as datetime) ;
|
|||
found
|
||||
true
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= @arg00 and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
and c17= @arg00 ;
|
||||
found
|
||||
true
|
||||
|
@ -3075,7 +3075,7 @@ execute stmt1 ;
|
|||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= ? and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
|
||||
found
|
||||
true
|
||||
|
|
|
@ -3030,25 +3030,25 @@ test_sequence
|
|||
-- select .. where date/time column = .. --
|
||||
set @arg00= '1991-01-01 01:01:01' ;
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= '1991-01-01 01:01:01' and c14= '1991-01-01 01:01:01' and
|
||||
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
|
||||
c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
|
||||
c17= '1991-01-01 01:01:01' ;
|
||||
found
|
||||
true
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= @arg00 and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
and c17= @arg00 ;
|
||||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= '1991-01-01 01:01:01' and c14= '1991-01-01 01:01:01' and
|
||||
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
|
||||
c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
|
||||
c17= '1991-01-01 01:01:01'" ;
|
||||
execute stmt1 ;
|
||||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= ? and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
|
||||
found
|
||||
true
|
||||
|
@ -3062,7 +3062,7 @@ c17= CAST('1991-01-01 01:01:01' as datetime) ;
|
|||
found
|
||||
true
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= @arg00 and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
and c17= @arg00 ;
|
||||
found
|
||||
true
|
||||
|
@ -3076,7 +3076,7 @@ execute stmt1 ;
|
|||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= ? and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
|
||||
found
|
||||
true
|
||||
|
|
|
@ -2966,25 +2966,25 @@ test_sequence
|
|||
-- select .. where date/time column = .. --
|
||||
set @arg00= '1991-01-01 01:01:01' ;
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= '1991-01-01 01:01:01' and c14= '1991-01-01 01:01:01' and
|
||||
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
|
||||
c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
|
||||
c17= '1991-01-01 01:01:01' ;
|
||||
found
|
||||
true
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= @arg00 and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
and c17= @arg00 ;
|
||||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= '1991-01-01 01:01:01' and c14= '1991-01-01 01:01:01' and
|
||||
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
|
||||
c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
|
||||
c17= '1991-01-01 01:01:01'" ;
|
||||
execute stmt1 ;
|
||||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= ? and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
|
||||
found
|
||||
true
|
||||
|
@ -2998,7 +2998,7 @@ c17= CAST('1991-01-01 01:01:01' as datetime) ;
|
|||
found
|
||||
true
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= @arg00 and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
and c17= @arg00 ;
|
||||
found
|
||||
true
|
||||
|
@ -3012,7 +3012,7 @@ execute stmt1 ;
|
|||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= ? and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
|
||||
found
|
||||
true
|
||||
|
@ -5980,25 +5980,25 @@ test_sequence
|
|||
-- select .. where date/time column = .. --
|
||||
set @arg00= '1991-01-01 01:01:01' ;
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= '1991-01-01 01:01:01' and c14= '1991-01-01 01:01:01' and
|
||||
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
|
||||
c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
|
||||
c17= '1991-01-01 01:01:01' ;
|
||||
found
|
||||
true
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= @arg00 and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
and c17= @arg00 ;
|
||||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= '1991-01-01 01:01:01' and c14= '1991-01-01 01:01:01' and
|
||||
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
|
||||
c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
|
||||
c17= '1991-01-01 01:01:01'" ;
|
||||
execute stmt1 ;
|
||||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= ? and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
|
||||
found
|
||||
true
|
||||
|
@ -6012,7 +6012,7 @@ c17= CAST('1991-01-01 01:01:01' as datetime) ;
|
|||
found
|
||||
true
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= @arg00 and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
and c17= @arg00 ;
|
||||
found
|
||||
true
|
||||
|
@ -6026,7 +6026,7 @@ execute stmt1 ;
|
|||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= ? and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
|
||||
found
|
||||
true
|
||||
|
|
|
@ -3029,25 +3029,25 @@ test_sequence
|
|||
-- select .. where date/time column = .. --
|
||||
set @arg00= '1991-01-01 01:01:01' ;
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= '1991-01-01 01:01:01' and c14= '1991-01-01 01:01:01' and
|
||||
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
|
||||
c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
|
||||
c17= '1991-01-01 01:01:01' ;
|
||||
found
|
||||
true
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= @arg00 and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
and c17= @arg00 ;
|
||||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= '1991-01-01 01:01:01' and c14= '1991-01-01 01:01:01' and
|
||||
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
|
||||
c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
|
||||
c17= '1991-01-01 01:01:01'" ;
|
||||
execute stmt1 ;
|
||||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= ? and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
|
||||
found
|
||||
true
|
||||
|
@ -3061,7 +3061,7 @@ c17= CAST('1991-01-01 01:01:01' as datetime) ;
|
|||
found
|
||||
true
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= @arg00 and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
and c17= @arg00 ;
|
||||
found
|
||||
true
|
||||
|
@ -3075,7 +3075,7 @@ execute stmt1 ;
|
|||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= ? and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
|
||||
found
|
||||
true
|
||||
|
|
|
@ -3029,25 +3029,25 @@ test_sequence
|
|||
-- select .. where date/time column = .. --
|
||||
set @arg00= '1991-01-01 01:01:01' ;
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= '1991-01-01 01:01:01' and c14= '1991-01-01 01:01:01' and
|
||||
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
|
||||
c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
|
||||
c17= '1991-01-01 01:01:01' ;
|
||||
found
|
||||
true
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= @arg00 and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
and c17= @arg00 ;
|
||||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= '1991-01-01 01:01:01' and c14= '1991-01-01 01:01:01' and
|
||||
where c1= 20 and c13= CAST('1991-01-01 01:01:01' AS DATE) and c14= '1991-01-01 01:01:01' and
|
||||
c15= '1991-01-01 01:01:01' and c16= '1991-01-01 01:01:01' and
|
||||
c17= '1991-01-01 01:01:01'" ;
|
||||
execute stmt1 ;
|
||||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= ? and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
|
||||
found
|
||||
true
|
||||
|
@ -3061,7 +3061,7 @@ c17= CAST('1991-01-01 01:01:01' as datetime) ;
|
|||
found
|
||||
true
|
||||
select 'true' as found from t9
|
||||
where c1= 20 and c13= @arg00 and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
where c1= 20 and c13= CAST(@arg00 AS DATE) and c14= @arg00 and c15= @arg00 and c16= @arg00
|
||||
and c17= @arg00 ;
|
||||
found
|
||||
true
|
||||
|
@ -3075,7 +3075,7 @@ execute stmt1 ;
|
|||
found
|
||||
true
|
||||
prepare stmt1 from "select 'true' as found from t9
|
||||
where c1= 20 and c13= ? and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
where c1= 20 and c13= CAST(? AS DATE) and c14= ? and c15= ? and c16= ? and c17= ?" ;
|
||||
execute stmt1 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
|
||||
found
|
||||
true
|
||||
|
|
|
@ -1128,9 +1128,9 @@ drop view if exists v1, v2, v3, v4;
|
|||
create function bug11555_1() returns int return (select max(i) from t1);
|
||||
create function bug11555_2() returns int return bug11555_1();
|
||||
create view v1 as select bug11555_1();
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
drop view v1;
|
||||
create view v2 as select bug11555_2();
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
drop view v2;
|
||||
create table t1 (i int);
|
||||
create view v1 as select bug11555_1();
|
||||
create view v2 as select bug11555_2();
|
||||
|
@ -1143,8 +1143,7 @@ ERROR HY000: View 'test.v2' references invalid table(s) or column(s) or function
|
|||
select * from v3;
|
||||
ERROR HY000: View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
create view v4 as select * from v1;
|
||||
ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
drop view v1, v2, v3;
|
||||
drop view v1, v2, v3, v4;
|
||||
drop function bug11555_1;
|
||||
drop function bug11555_2;
|
||||
create table t1 (i int);
|
||||
|
@ -1153,12 +1152,12 @@ create trigger t1_ai after insert on t1 for each row insert into t2 values (new.
|
|||
create view v1 as select * from t1;
|
||||
drop table t2;
|
||||
insert into v1 values (1);
|
||||
ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
ERROR HY000: Table 't2' was not locked with LOCK TABLES
|
||||
drop trigger t1_ai;
|
||||
create function bug11555_1() returns int return (select max(i) from t2);
|
||||
create trigger t1_ai after insert on t1 for each row set @a:=bug11555_1();
|
||||
insert into v1 values (2);
|
||||
ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
ERROR HY000: Table 't2' was not locked with LOCK TABLES
|
||||
drop function bug11555_1;
|
||||
drop table t1;
|
||||
drop view v1;
|
||||
|
@ -1269,3 +1268,135 @@ call bug24491();
|
|||
ERROR 42S22: Unknown column 'y.value' in 'field list'
|
||||
drop procedure bug24491;
|
||||
drop tables t1;
|
||||
DROP FUNCTION IF EXISTS bug18914_f1;
|
||||
DROP FUNCTION IF EXISTS bug18914_f2;
|
||||
DROP PROCEDURE IF EXISTS bug18914_p1;
|
||||
DROP PROCEDURE IF EXISTS bug18914_p2;
|
||||
DROP TABLE IF EXISTS t1, t2;
|
||||
CREATE TABLE t1 (i INT);
|
||||
CREATE PROCEDURE bug18914_p1() CREATE TABLE t2 (i INT);
|
||||
CREATE PROCEDURE bug18914_p2() DROP TABLE IF EXISTS no_such_table;
|
||||
CREATE FUNCTION bug18914_f1() RETURNS INT
|
||||
BEGIN
|
||||
CALL bug18914_p1();
|
||||
RETURN 1;
|
||||
END |
|
||||
CREATE FUNCTION bug18914_f2() RETURNS INT
|
||||
BEGIN
|
||||
CALL bug18914_p2();
|
||||
RETURN 1;
|
||||
END |
|
||||
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
|
||||
CALL bug18914_p1();
|
||||
INSERT INTO t1 VALUES (1);
|
||||
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
|
||||
SELECT bug18914_f1();
|
||||
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
|
||||
SELECT bug18914_f2();
|
||||
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
|
||||
SELECT * FROM t2;
|
||||
ERROR 42S02: Table 'test.t2' doesn't exist
|
||||
DROP FUNCTION bug18914_f1;
|
||||
DROP FUNCTION bug18914_f2;
|
||||
DROP PROCEDURE bug18914_p1;
|
||||
DROP PROCEDURE bug18914_p2;
|
||||
DROP TABLE t1;
|
||||
drop table if exists bogus_table_20713;
|
||||
drop function if exists func_20713_a;
|
||||
drop function if exists func_20713_b;
|
||||
create table bogus_table_20713( id int(10) not null primary key);
|
||||
insert into bogus_table_20713 values (1), (2), (3);
|
||||
create function func_20713_a() returns int(11)
|
||||
begin
|
||||
declare id int;
|
||||
declare continue handler for sqlexception set id=null;
|
||||
set @in_func := 1;
|
||||
set id = (select id from bogus_table_20713 where id = 3);
|
||||
set @in_func := 2;
|
||||
return id;
|
||||
end//
|
||||
create function func_20713_b() returns int(11)
|
||||
begin
|
||||
declare id int;
|
||||
declare continue handler for sqlstate value '42S02' set id=null;
|
||||
set @in_func := 1;
|
||||
set id = (select id from bogus_table_20713 where id = 3);
|
||||
set @in_func := 2;
|
||||
return id;
|
||||
end//
|
||||
set @in_func := 0;
|
||||
select func_20713_a();
|
||||
func_20713_a()
|
||||
NULL
|
||||
select @in_func;
|
||||
@in_func
|
||||
2
|
||||
set @in_func := 0;
|
||||
select func_20713_b();
|
||||
func_20713_b()
|
||||
NULL
|
||||
select @in_func;
|
||||
@in_func
|
||||
2
|
||||
drop table bogus_table_20713;
|
||||
set @in_func := 0;
|
||||
select func_20713_a();
|
||||
func_20713_a()
|
||||
NULL
|
||||
select @in_func;
|
||||
@in_func
|
||||
2
|
||||
set @in_func := 0;
|
||||
select func_20713_b();
|
||||
func_20713_b()
|
||||
NULL
|
||||
select @in_func;
|
||||
@in_func
|
||||
2
|
||||
drop function if exists func_20713_a;
|
||||
drop function if exists func_20713_b;
|
||||
drop table if exists table_25345_a;
|
||||
drop table if exists table_25345_b;
|
||||
drop procedure if exists proc_25345;
|
||||
drop function if exists func_25345;
|
||||
drop function if exists func_25345_b;
|
||||
create table table_25345_a (a int);
|
||||
create table table_25345_b (b int);
|
||||
create procedure proc_25345()
|
||||
begin
|
||||
declare c1 cursor for select a from table_25345_a;
|
||||
declare c2 cursor for select b from table_25345_b;
|
||||
select 1 as result;
|
||||
end ||
|
||||
create function func_25345() returns int(11)
|
||||
begin
|
||||
call proc_25345();
|
||||
return 1;
|
||||
end ||
|
||||
create function func_25345_b() returns int(11)
|
||||
begin
|
||||
declare c1 cursor for select a from table_25345_a;
|
||||
declare c2 cursor for select b from table_25345_b;
|
||||
return 1;
|
||||
end ||
|
||||
call proc_25345();
|
||||
result
|
||||
1
|
||||
select func_25345();
|
||||
ERROR 0A000: Not allowed to return a result set from a function
|
||||
select func_25345_b();
|
||||
func_25345_b()
|
||||
1
|
||||
drop table table_25345_a;
|
||||
call proc_25345();
|
||||
result
|
||||
1
|
||||
select func_25345();
|
||||
ERROR 0A000: Not allowed to return a result set from a function
|
||||
select func_25345_b();
|
||||
func_25345_b()
|
||||
1
|
||||
drop table table_25345_b;
|
||||
drop procedure proc_25345;
|
||||
drop function func_25345;
|
||||
drop function func_25345_b;
|
||||
|
|
|
@ -431,17 +431,17 @@ SELECT HEX(v10);
|
|||
END|
|
||||
CALL p1();
|
||||
HEX(v1)
|
||||
01
|
||||
1
|
||||
HEX(v2)
|
||||
00
|
||||
0
|
||||
HEX(v3)
|
||||
05
|
||||
5
|
||||
HEX(v4)
|
||||
5555555555555555
|
||||
HEX(v5)
|
||||
07
|
||||
7
|
||||
HEX(v6)
|
||||
0000000000000005
|
||||
5
|
||||
HEX(v7)
|
||||
80
|
||||
HEX(v8)
|
||||
|
@ -748,12 +748,60 @@ HEX(b) b = 0 b = FALSE b IS FALSE b = 1 b = TRUE b IS TRUE
|
|||
1 0 0 0 1 1 1
|
||||
call p2();
|
||||
HEX(vb) vb = 0 vb = FALSE vb IS FALSE vb = 1 vb = TRUE vb IS TRUE
|
||||
00 1 1 1 0 0 0
|
||||
0 1 1 1 0 0 0
|
||||
HEX(vb) vb = 0 vb = FALSE vb IS FALSE vb = 1 vb = TRUE vb IS TRUE
|
||||
01 0 0 1 1 1 0
|
||||
1 0 0 0 1 1 1
|
||||
DROP TABLE t1;
|
||||
DROP PROCEDURE p1;
|
||||
DROP PROCEDURE p2;
|
||||
DROP TABLE IF EXISTS table_12976_a;
|
||||
DROP TABLE IF EXISTS table_12976_b;
|
||||
DROP PROCEDURE IF EXISTS proc_12976_a;
|
||||
DROP PROCEDURE IF EXISTS proc_12976_b;
|
||||
CREATE TABLE table_12976_a (val bit(1));
|
||||
CREATE TABLE table_12976_b(
|
||||
appname varchar(15),
|
||||
emailperm bit not null default 1,
|
||||
phoneperm bit not null default 0);
|
||||
insert into table_12976_b values ('A', b'1', b'1'), ('B', b'0', b'0');
|
||||
CREATE PROCEDURE proc_12976_a()
|
||||
BEGIN
|
||||
declare localvar bit(1);
|
||||
SELECT val INTO localvar FROM table_12976_a;
|
||||
SELECT coalesce(localvar, 1)+1, coalesce(val, 1)+1 FROM table_12976_a;
|
||||
END||
|
||||
CREATE PROCEDURE proc_12976_b(
|
||||
name varchar(15),
|
||||
out ep bit,
|
||||
out msg varchar(10))
|
||||
BEGIN
|
||||
SELECT emailperm into ep FROM table_12976_b where (appname = name);
|
||||
IF ep is true THEN
|
||||
SET msg = 'True';
|
||||
ELSE
|
||||
SET msg = 'False';
|
||||
END IF;
|
||||
END||
|
||||
INSERT table_12976_a VALUES (0);
|
||||
call proc_12976_a();
|
||||
coalesce(localvar, 1)+1 coalesce(val, 1)+1
|
||||
1 1
|
||||
UPDATE table_12976_a set val=1;
|
||||
call proc_12976_a();
|
||||
coalesce(localvar, 1)+1 coalesce(val, 1)+1
|
||||
2 2
|
||||
call proc_12976_b('A', @ep, @msg);
|
||||
select @ep, @msg;
|
||||
@ep @msg
|
||||
1 True
|
||||
call proc_12976_b('B', @ep, @msg);
|
||||
select @ep, @msg;
|
||||
@ep @msg
|
||||
0 False
|
||||
DROP TABLE table_12976_a;
|
||||
DROP TABLE table_12976_b;
|
||||
DROP PROCEDURE proc_12976_a;
|
||||
DROP PROCEDURE proc_12976_b;
|
||||
|
||||
---------------------------------------------------------------
|
||||
BUG#9572
|
||||
|
|
|
@ -1155,9 +1155,13 @@ create function f12_2() returns int
|
|||
return (select count(*) from t3)|
|
||||
drop temporary table t3|
|
||||
select f12_1()|
|
||||
ERROR 42S02: Table 'test.t3' doesn't exist
|
||||
f12_1()
|
||||
3
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't3'
|
||||
select f12_1() from t1 limit 1|
|
||||
ERROR 42S02: Table 'test.t3' doesn't exist
|
||||
f12_1()
|
||||
3
|
||||
drop function f0|
|
||||
drop function f1|
|
||||
drop function f2|
|
||||
|
@ -5727,4 +5731,38 @@ END|
|
|||
CALL bug24117()|
|
||||
DROP PROCEDURE bug24117|
|
||||
DROP TABLE t3|
|
||||
drop function if exists func_8407_a|
|
||||
drop function if exists func_8407_b|
|
||||
create function func_8407_a() returns int
|
||||
begin
|
||||
declare x int;
|
||||
declare continue handler for sqlexception
|
||||
begin
|
||||
end;
|
||||
select 1 from no_such_view limit 1 into x;
|
||||
return x;
|
||||
end|
|
||||
create function func_8407_b() returns int
|
||||
begin
|
||||
declare x int default 0;
|
||||
declare continue handler for sqlstate '42S02'
|
||||
begin
|
||||
set x:= x+1000;
|
||||
end;
|
||||
case (select 1 from no_such_view limit 1)
|
||||
when 1 then set x:= x+1;
|
||||
when 2 then set x:= x+2;
|
||||
else set x:= x+100;
|
||||
end case;
|
||||
set x:=x + 500;
|
||||
return x;
|
||||
end|
|
||||
select func_8407_a()|
|
||||
func_8407_a()
|
||||
NULL
|
||||
select func_8407_b()|
|
||||
func_8407_b()
|
||||
1500
|
||||
drop function func_8407_a|
|
||||
drop function func_8407_b|
|
||||
drop table t1,t2;
|
||||
|
|
|
@ -3095,7 +3095,7 @@ SELECT a FROM t1 GROUP BY a
|
|||
HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)) > 3;
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
SELECT a FROM t1
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 2),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
|
||||
a
|
||||
|
@ -3103,11 +3103,11 @@ a
|
|||
4
|
||||
1
|
||||
3
|
||||
SELECT a FROM t1
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 1),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
SELECT a FROM t1
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
|
||||
a
|
||||
|
@ -3115,7 +3115,7 @@ a
|
|||
1
|
||||
3
|
||||
4
|
||||
SELECT a FROM t1
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
|
@ -3683,16 +3683,16 @@ CREATE TABLE t1 (id char(4) PRIMARY KEY, c int);
|
|||
CREATE TABLE t2 (c int);
|
||||
INSERT INTO t1 VALUES ('aa', 1);
|
||||
INSERT INTO t2 VALUES (1);
|
||||
SELECT * FROM t1
|
||||
SELECT * FROM t1
|
||||
WHERE EXISTS (SELECT c FROM t2 WHERE c=1
|
||||
UNION
|
||||
UNION
|
||||
SELECT c from t2 WHERE c=t1.c);
|
||||
id c
|
||||
aa 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
|
||||
UNION
|
||||
UNION
|
||||
SELECT c from t2 WHERE c=t1.c);
|
||||
id c
|
||||
aa 1
|
||||
|
@ -3702,9 +3702,9 @@ dd 1
|
|||
INSERT INTO t2 VALUES (2);
|
||||
CREATE TABLE t3 (c int);
|
||||
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
|
||||
UNION
|
||||
UNION
|
||||
SELECT c from t2 WHERE c=t1.c);
|
||||
id c
|
||||
aa 1
|
||||
|
@ -3754,3 +3754,116 @@ a MAX(b) test
|
|||
2 3 h
|
||||
3 4 i
|
||||
DROP TABLE t1;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP TABLE IF EXISTS t2;
|
||||
DROP TABLE IF EXISTS t1xt2;
|
||||
CREATE TABLE t1 (
|
||||
id_1 int(5) NOT NULL,
|
||||
t varchar(4) DEFAULT NULL
|
||||
);
|
||||
CREATE TABLE t2 (
|
||||
id_2 int(5) NOT NULL,
|
||||
t varchar(4) DEFAULT NULL
|
||||
);
|
||||
CREATE TABLE t1xt2 (
|
||||
id_1 int(5) NOT NULL,
|
||||
id_2 int(5) NOT NULL
|
||||
);
|
||||
INSERT INTO t1 VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd');
|
||||
INSERT INTO t2 VALUES (2, 'bb'), (3, 'cc'), (4, 'dd'), (12, 'aa');
|
||||
INSERT INTO t1xt2 VALUES (2, 2), (3, 3), (4, 4);
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
id_1
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
|
||||
id_1
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
|
||||
id_1
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
id_1
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1)));
|
||||
id_1
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1))));
|
||||
id_1
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
insert INTO t1xt2 VALUES (1, 12);
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
id_1
|
||||
1
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
|
||||
id_1
|
||||
1
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
|
||||
id_1
|
||||
1
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
id_1
|
||||
2
|
||||
3
|
||||
4
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
|
||||
id_1
|
||||
2
|
||||
3
|
||||
4
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
|
||||
id_1
|
||||
2
|
||||
3
|
||||
4
|
||||
insert INTO t1xt2 VALUES (2, 12);
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
id_1
|
||||
1
|
||||
2
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
|
||||
id_1
|
||||
1
|
||||
2
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
|
||||
id_1
|
||||
1
|
||||
2
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
id_1
|
||||
3
|
||||
4
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
|
||||
id_1
|
||||
3
|
||||
4
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
|
||||
id_1
|
||||
3
|
||||
4
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1xt2;
|
||||
|
|
|
@ -1335,4 +1335,41 @@ SELECT fubar_id FROM t2;
|
|||
fubar_id
|
||||
1
|
||||
DROP TABLE t1,t2;
|
||||
DROP TABLE IF EXISTS bug21825_A;
|
||||
DROP TABLE IF EXISTS bug21825_B;
|
||||
CREATE TABLE bug21825_A (id int(10));
|
||||
CREATE TABLE bug21825_B (id int(10));
|
||||
CREATE TRIGGER trgA AFTER INSERT ON bug21825_A
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
INSERT INTO bug21825_B (id) values (1);
|
||||
END//
|
||||
INSERT INTO bug21825_A (id) VALUES (10);
|
||||
INSERT INTO bug21825_A (id) VALUES (20);
|
||||
DROP TABLE bug21825_B;
|
||||
DELETE FROM bug21825_A WHERE id = 20;
|
||||
DROP TABLE bug21825_A;
|
||||
DROP TABLE IF EXISTS bug22580_t1;
|
||||
DROP PROCEDURE IF EXISTS bug22580_proc_1;
|
||||
DROP PROCEDURE IF EXISTS bug22580_proc_2;
|
||||
CREATE TABLE bug22580_t1 (a INT, b INT);
|
||||
CREATE PROCEDURE bug22580_proc_2()
|
||||
BEGIN
|
||||
DROP TABLE IF EXISTS bug22580_tmp;
|
||||
CREATE TEMPORARY TABLE bug22580_tmp (a INT);
|
||||
DROP TABLE bug22580_tmp;
|
||||
END||
|
||||
CREATE PROCEDURE bug22580_proc_1()
|
||||
BEGIN
|
||||
CALL bug22580_proc_2();
|
||||
END||
|
||||
CREATE TRIGGER t1bu BEFORE UPDATE ON bug22580_t1
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
CALL bug22580_proc_1();
|
||||
END||
|
||||
INSERT INTO bug22580_t1 VALUES (1,1);
|
||||
DROP TABLE bug22580_t1;
|
||||
DROP PROCEDURE bug22580_proc_1;
|
||||
DROP PROCEDURE bug22580_proc_2;
|
||||
End of 5.0 tests
|
||||
|
|
|
@ -834,14 +834,16 @@ show create view v1;
|
|||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 99999999999999999999999999999999999999999999999999999 AS `col1`
|
||||
drop view v1;
|
||||
create table tü (cü char);
|
||||
create view vü as select cü from tü;
|
||||
insert into vü values ('ü');
|
||||
select * from vü;
|
||||
cü
|
||||
ü
|
||||
drop view vü;
|
||||
drop table tü;
|
||||
set names utf8;
|
||||
create table tü (cü char);
|
||||
create view vü as select cü from tü;
|
||||
insert into vü values ('ü');
|
||||
select * from vü;
|
||||
cü
|
||||
ü
|
||||
drop view vü;
|
||||
drop table tü;
|
||||
set names latin1;
|
||||
create table t1 (a int, b int);
|
||||
insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10);
|
||||
create view v1(c) as select a+1 from t1 where b >= 4;
|
||||
|
@ -1933,11 +1935,11 @@ create function f1 () returns int return (select max(col1) from t1);
|
|||
DROP TABLE t1;
|
||||
CHECK TABLE v1, v2, v3, v4, v5, v6;
|
||||
Table Op Msg_type Msg_text
|
||||
test.v1 check error View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
test.v1 check status OK
|
||||
test.v2 check status OK
|
||||
test.v3 check error View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
test.v3 check status OK
|
||||
test.v4 check status OK
|
||||
test.v5 check error View 'test.v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
test.v5 check status OK
|
||||
test.v6 check status OK
|
||||
drop function f1;
|
||||
drop function f2;
|
||||
|
@ -3035,7 +3037,7 @@ View Create View
|
|||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _latin1'The\ZEnd' AS `TheEnd`
|
||||
DROP VIEW v1;
|
||||
CREATE TABLE t1 (mydate DATETIME);
|
||||
INSERT INTO t1 VALUES
|
||||
INSERT INTO t1 VALUES
|
||||
('2007-01-01'), ('2007-01-02'), ('2007-01-30'), ('2007-01-31');
|
||||
CREATE VIEW v1 AS SELECT mydate from t1;
|
||||
SELECT * FROM t1 WHERE mydate BETWEEN '2007-01-01' AND '2007-01-31';
|
||||
|
@ -3135,4 +3137,139 @@ code COUNT(DISTINCT country)
|
|||
100 2
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
DROP VIEW IF EXISTS v1;
|
||||
SELECT * FROM (SELECT 1) AS t;
|
||||
1
|
||||
1
|
||||
CREATE VIEW v1 AS SELECT * FROM (SELECT 1) AS t;
|
||||
ERROR HY000: View's SELECT contains a subquery in the FROM clause
|
||||
# Previously the following would fail.
|
||||
SELECT * FROM (SELECT 1) AS t;
|
||||
1
|
||||
1
|
||||
drop view if exists view_24532_a;
|
||||
drop view if exists view_24532_b;
|
||||
drop table if exists table_24532;
|
||||
create table table_24532 (
|
||||
a int,
|
||||
b bigint,
|
||||
c int(4),
|
||||
d bigint(48)
|
||||
);
|
||||
create view view_24532_a as
|
||||
select
|
||||
a IS TRUE,
|
||||
a IS NOT TRUE,
|
||||
a IS FALSE,
|
||||
a IS NOT FALSE,
|
||||
a IS UNKNOWN,
|
||||
a IS NOT UNKNOWN,
|
||||
a is NULL,
|
||||
a IS NOT NULL,
|
||||
ISNULL(a),
|
||||
b IS TRUE,
|
||||
b IS NOT TRUE,
|
||||
b IS FALSE,
|
||||
b IS NOT FALSE,
|
||||
b IS UNKNOWN,
|
||||
b IS NOT UNKNOWN,
|
||||
b is NULL,
|
||||
b IS NOT NULL,
|
||||
ISNULL(b),
|
||||
c IS TRUE,
|
||||
c IS NOT TRUE,
|
||||
c IS FALSE,
|
||||
c IS NOT FALSE,
|
||||
c IS UNKNOWN,
|
||||
c IS NOT UNKNOWN,
|
||||
c is NULL,
|
||||
c IS NOT NULL,
|
||||
ISNULL(c),
|
||||
d IS TRUE,
|
||||
d IS NOT TRUE,
|
||||
d IS FALSE,
|
||||
d IS NOT FALSE,
|
||||
d IS UNKNOWN,
|
||||
d IS NOT UNKNOWN,
|
||||
d is NULL,
|
||||
d IS NOT NULL,
|
||||
ISNULL(d)
|
||||
from table_24532;
|
||||
describe view_24532_a;
|
||||
Field Type Null Key Default Extra
|
||||
a IS TRUE int(1) NO 0
|
||||
a IS NOT TRUE int(1) NO 0
|
||||
a IS FALSE int(1) NO 0
|
||||
a IS NOT FALSE int(1) NO 0
|
||||
a IS UNKNOWN int(1) NO 0
|
||||
a IS NOT UNKNOWN int(1) NO 0
|
||||
a is NULL int(1) NO 0
|
||||
a IS NOT NULL int(1) NO 0
|
||||
ISNULL(a) int(1) NO 0
|
||||
b IS TRUE int(1) NO 0
|
||||
b IS NOT TRUE int(1) NO 0
|
||||
b IS FALSE int(1) NO 0
|
||||
b IS NOT FALSE int(1) NO 0
|
||||
b IS UNKNOWN int(1) NO 0
|
||||
b IS NOT UNKNOWN int(1) NO 0
|
||||
b is NULL int(1) NO 0
|
||||
b IS NOT NULL int(1) NO 0
|
||||
ISNULL(b) int(1) NO 0
|
||||
c IS TRUE int(1) NO 0
|
||||
c IS NOT TRUE int(1) NO 0
|
||||
c IS FALSE int(1) NO 0
|
||||
c IS NOT FALSE int(1) NO 0
|
||||
c IS UNKNOWN int(1) NO 0
|
||||
c IS NOT UNKNOWN int(1) NO 0
|
||||
c is NULL int(1) NO 0
|
||||
c IS NOT NULL int(1) NO 0
|
||||
ISNULL(c) int(1) NO 0
|
||||
d IS TRUE int(1) NO 0
|
||||
d IS NOT TRUE int(1) NO 0
|
||||
d IS FALSE int(1) NO 0
|
||||
d IS NOT FALSE int(1) NO 0
|
||||
d IS UNKNOWN int(1) NO 0
|
||||
d IS NOT UNKNOWN int(1) NO 0
|
||||
d is NULL int(1) NO 0
|
||||
d IS NOT NULL int(1) NO 0
|
||||
ISNULL(d) int(1) NO 0
|
||||
create view view_24532_b as
|
||||
select
|
||||
a IS TRUE,
|
||||
if(ifnull(a, 0), 1, 0) as old_istrue,
|
||||
a IS NOT TRUE,
|
||||
if(ifnull(a, 0), 0, 1) as old_isnottrue,
|
||||
a IS FALSE,
|
||||
if(ifnull(a, 1), 0, 1) as old_isfalse,
|
||||
a IS NOT FALSE,
|
||||
if(ifnull(a, 1), 1, 0) as old_isnotfalse
|
||||
from table_24532;
|
||||
describe view_24532_b;
|
||||
Field Type Null Key Default Extra
|
||||
a IS TRUE int(1) NO 0
|
||||
old_istrue int(1) NO 0
|
||||
a IS NOT TRUE int(1) NO 0
|
||||
old_isnottrue int(1) NO 0
|
||||
a IS FALSE int(1) NO 0
|
||||
old_isfalse int(1) NO 0
|
||||
a IS NOT FALSE int(1) NO 0
|
||||
old_isnotfalse int(1) NO 0
|
||||
show create view view_24532_b;
|
||||
View Create View
|
||||
view_24532_b CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `view_24532_b` AS select (`table_24532`.`a` is true) AS `a IS TRUE`,if(ifnull(`table_24532`.`a`,0),1,0) AS `old_istrue`,(`table_24532`.`a` is not true) AS `a IS NOT TRUE`,if(ifnull(`table_24532`.`a`,0),0,1) AS `old_isnottrue`,(`table_24532`.`a` is false) AS `a IS FALSE`,if(ifnull(`table_24532`.`a`,1),0,1) AS `old_isfalse`,(`table_24532`.`a` is not false) AS `a IS NOT FALSE`,if(ifnull(`table_24532`.`a`,1),1,0) AS `old_isnotfalse` from `table_24532`
|
||||
insert into table_24532 values (0, 0, 0, 0);
|
||||
select * from view_24532_b;
|
||||
a IS TRUE old_istrue a IS NOT TRUE old_isnottrue a IS FALSE old_isfalse a IS NOT FALSE old_isnotfalse
|
||||
0 0 1 1 1 1 0 0
|
||||
update table_24532 set a=1;
|
||||
select * from view_24532_b;
|
||||
a IS TRUE old_istrue a IS NOT TRUE old_isnottrue a IS FALSE old_isfalse a IS NOT FALSE old_isnotfalse
|
||||
1 1 0 0 0 0 1 1
|
||||
update table_24532 set a=NULL;
|
||||
select * from view_24532_b;
|
||||
a IS TRUE old_istrue a IS NOT TRUE old_isnottrue a IS FALSE old_isfalse a IS NOT FALSE old_isnotfalse
|
||||
0 0 1 1 0 0 1 1
|
||||
drop view view_24532_a;
|
||||
drop view view_24532_b;
|
||||
drop table table_24532;
|
||||
End of 5.0 tests.
|
||||
|
|
|
@ -27,3 +27,12 @@ insert into t2 values (11), (13);
|
|||
drop procedure p1;
|
||||
drop function f1;
|
||||
drop view v1;
|
||||
|
||||
#
|
||||
# Bug#23240 --init-file statements with NOW() reports '1970-01-01 11:00:00'as the date time
|
||||
#
|
||||
CREATE DATABASE IF NOT EXISTS init_file;
|
||||
CREATE TABLE IF NOT EXISTS init_file.startup ( startdate DATETIME );
|
||||
INSERT INTO init_file.startup VALUES ( NOW() );
|
||||
|
||||
|
||||
|
|
|
@ -10,6 +10,5 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
im_daemon_life_cycle : Bug#24415 see note: [19 Dec 23:17] Trudy Pelzer
|
||||
ndb_load : Bug#17233
|
||||
user_limits : Bug#23921 random failure of user_limits.test
|
||||
|
|
|
@ -97,3 +97,14 @@ create table t1 (f1 int, f2 int);
|
|||
insert into t1 values(1,1),(0,0);
|
||||
select f1, f2, if(f1, 40.0, 5.00) from t1 group by f1 order by f2;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#24532 (The return data type of IS TRUE is different from similar
|
||||
# operations)
|
||||
#
|
||||
# IF(x, unsigned, unsigned) should be unsigned.
|
||||
#
|
||||
|
||||
select if(0, 18446744073709551610, 18446744073709551610);
|
||||
|
||||
|
||||
|
|
|
@ -132,4 +132,61 @@ set global query_cache_size=default;
|
|||
create table t1 select INET_ATON('255.255.0.1') as `a`;
|
||||
show create table t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#26093 (SELECT BENCHMARK() for SELECT statements does not produce
|
||||
# valid results)
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists table_26093;
|
||||
drop function if exists func_26093_a;
|
||||
drop function if exists func_26093_b;
|
||||
--enable_warnings
|
||||
|
||||
create table table_26093(a int);
|
||||
insert into table_26093 values
|
||||
(1), (2), (3), (4), (5),
|
||||
(6), (7), (8), (9), (10);
|
||||
|
||||
delimiter //;
|
||||
|
||||
create function func_26093_a(x int) returns int
|
||||
begin
|
||||
set @invoked := @invoked + 1;
|
||||
return x;
|
||||
end//
|
||||
|
||||
create function func_26093_b(x int, y int) returns int
|
||||
begin
|
||||
set @invoked := @invoked + 1;
|
||||
return x;
|
||||
end//
|
||||
|
||||
delimiter ;//
|
||||
|
||||
select avg(a) from table_26093;
|
||||
|
||||
select benchmark(100, (select avg(a) from table_26093));
|
||||
|
||||
set @invoked := 0;
|
||||
select benchmark(100, (select avg(func_26093_a(a)) from table_26093));
|
||||
# Returns only 10, since intermediate results are cached.
|
||||
select @invoked;
|
||||
|
||||
set @invoked := 0;
|
||||
select benchmark(100, (select avg(func_26093_b(a, rand())) from table_26093));
|
||||
# Returns 1000, due to rand() preventing caching.
|
||||
select @invoked;
|
||||
|
||||
--error ER_SUBQUERY_NO_1_ROW
|
||||
select benchmark(100, (select (a) from table_26093));
|
||||
|
||||
--error ER_OPERAND_COLUMNS
|
||||
select benchmark(100, (select 1, 1));
|
||||
|
||||
drop table table_26093;
|
||||
drop function func_26093_a;
|
||||
drop function func_26093_b;
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
|
|
@ -570,6 +570,13 @@ union
|
|||
|
||||
select last_day('0000-00-00');
|
||||
|
||||
#
|
||||
# Bug 23616: datetime functions with double argumets
|
||||
#
|
||||
|
||||
select isnull(week(now() + 0)), isnull(week(now() + 0.2)),
|
||||
week(20061108), week(20061108.01), week(20061108085411.000002);
|
||||
|
||||
--echo End of 4.1 tests
|
||||
|
||||
explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1,
|
||||
|
@ -714,6 +721,19 @@ SET NAMES DEFAULT;
|
|||
|
||||
select str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE;
|
||||
|
||||
#
|
||||
# Bug #21103: DATE column not compared as DATE
|
||||
#
|
||||
|
||||
create table t1 (field DATE);
|
||||
insert into t1 values ('2006-11-06');
|
||||
select * from t1 where field < '2006-11-06 04:08:36.0';
|
||||
select * from t1 where field = '2006-11-06 04:08:36.0';
|
||||
select * from t1 where field = '2006-11-06';
|
||||
select * from t1 where CAST(field as DATETIME) < '2006-11-06 04:08:36.0';
|
||||
select * from t1 where CAST(field as DATE) < '2006-11-06 04:08:36.0';
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #25643: SEC_TO_TIME function problem
|
||||
#
|
||||
|
@ -725,3 +745,10 @@ SELECT t1, t2, SEC_TO_TIME( TIME_TO_SEC( t2 ) - TIME_TO_SEC( t1 ) ), QUARTER(d)
|
|||
SELECT t1, t2, SEC_TO_TIME( TIME_TO_SEC( t2 ) - TIME_TO_SEC( t1 ) ), QUARTER(d)
|
||||
FROM t1 ORDER BY a DESC;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug #20293: group by cuts off value from time_format
|
||||
#
|
||||
# Check if using GROUP BY with TIME_FORMAT() produces correct results
|
||||
|
||||
SELECT TIME_FORMAT(SEC_TO_TIME(a),"%H:%i:%s") FROM (SELECT 3020399 AS a UNION SELECT 3020398 ) x GROUP BY 1;
|
||||
|
|
|
@ -360,14 +360,14 @@ t1 where object_id=85984;
|
|||
|
||||
drop table t1;
|
||||
|
||||
create table t1 (fl geometry);
|
||||
create table t1 (fl geometry not null);
|
||||
--error 1416
|
||||
insert into t1 values (1);
|
||||
--error 1416
|
||||
insert into t1 values (1.11);
|
||||
--error 1416
|
||||
insert into t1 values ("qwerty");
|
||||
--error 1416
|
||||
--error 1048
|
||||
insert into t1 values (pointfromtext('point(1,1)'));
|
||||
|
||||
drop table t1;
|
||||
|
@ -389,7 +389,41 @@ load data infile '../std_data_ln/bad_gis_data.dat' into table t1;
|
|||
alter table t1 enable keys;
|
||||
drop table t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
#
|
||||
# Bug #26038: is null and bad data
|
||||
#
|
||||
|
||||
create table t1 (a int, b blob);
|
||||
insert into t1 values (1, ''), (2, NULL), (3, '1');
|
||||
select * from t1;
|
||||
|
||||
select
|
||||
geometryfromtext(b) IS NULL, geometryfromwkb(b) IS NULL, astext(b) IS NULL,
|
||||
aswkb(b) IS NULL, geometrytype(b) IS NULL, centroid(b) IS NULL,
|
||||
envelope(b) IS NULL, startpoint(b) IS NULL, endpoint(b) IS NULL,
|
||||
exteriorring(b) IS NULL, pointn(b, 1) IS NULL, geometryn(b, 1) IS NULL,
|
||||
interiorringn(b, 1) IS NULL, multipoint(b) IS NULL, isempty(b) IS NULL,
|
||||
issimple(b) IS NULL, isclosed(b) IS NULL, dimension(b) IS NULL,
|
||||
numgeometries(b) IS NULL, numinteriorrings(b) IS NULL, numpoints(b) IS NULL,
|
||||
area(b) IS NULL, glength(b) IS NULL, srid(b) IS NULL, x(b) IS NULL,
|
||||
y(b) IS NULL
|
||||
from t1;
|
||||
|
||||
select
|
||||
within(b, b) IS NULL, contains(b, b) IS NULL, overlaps(b, b) IS NULL,
|
||||
equals(b, b) IS NULL, disjoint(b, b) IS NULL, touches(b, b) IS NULL,
|
||||
intersects(b, b) IS NULL, crosses(b, b) IS NULL
|
||||
from t1;
|
||||
|
||||
select
|
||||
point(b, b) IS NULL, linestring(b) IS NULL, polygon(b) IS NULL, multipoint(b) IS NULL,
|
||||
multilinestring(b) IS NULL, multipolygon(b) IS NULL,
|
||||
geometrycollection(b) IS NULL
|
||||
from t1;
|
||||
|
||||
drop table t1;
|
||||
|
||||
--echo End of 4.1 tests
|
||||
|
||||
#
|
||||
# Bug #12281 (Geometry: crash in trigger)
|
||||
|
|
|
@ -23,15 +23,20 @@
|
|||
# - wait for IM-main to start accepting connections before continue test
|
||||
# case;
|
||||
#
|
||||
# NOTE: timeout is 55 seconds. Timeout should be more than shutdown-delay
|
||||
# specified for managed MySQL instance. Now shutdown-delay is 10 seconds
|
||||
# (set in mysql-test-run.pl). So, 55 seconds should be enough to make 5
|
||||
# attempts.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle Main-test: starting...
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle Killing IM-main...
|
||||
--exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_PATH_PID restarted 30 im_daemon_life_cycle
|
||||
--exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_PATH_PID restarted 55 im_daemon_life_cycle
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle Waiting for IM-main to start accepting connections...
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_socket.sh $EXE_MYSQL $IM_PATH_SOCK $IM_USERNAME $IM_PASSWORD '' 30 im_daemon_life_cycle
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_socket.sh $EXE_MYSQL $IM_PATH_SOCK $IM_USERNAME $IM_PASSWORD '' 55 im_daemon_life_cycle
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle Main-test: done.
|
||||
|
||||
|
@ -58,23 +63,23 @@
|
|||
START INSTANCE mysqld2;
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle mysqld2: waiting to start...
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 started im_daemon_life_cycle
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 55 started im_daemon_life_cycle
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle mysqld2: started.
|
||||
|
||||
# 2. Restart IM-main;
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle Killing IM-main...
|
||||
--exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_PATH_PID restarted 30 im_daemon_life_cycle
|
||||
--exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_PATH_PID restarted 55 im_daemon_life_cycle
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle Waiting for IM-main to start accepting connections...
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_socket.sh $EXE_MYSQL $IM_PATH_SOCK $IM_USERNAME $IM_PASSWORD '' 30 im_daemon_life_cycle
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_socket.sh $EXE_MYSQL $IM_PATH_SOCK $IM_USERNAME $IM_PASSWORD '' 55 im_daemon_life_cycle
|
||||
|
||||
# 3. Issue some statement -- connection should be re-established.
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle Checking that IM-main processing commands...
|
||||
|
||||
--replace_column 3 VERSION
|
||||
--replace_column 2 STATE 3 VERSION
|
||||
SHOW INSTANCE STATUS mysqld1;
|
||||
|
||||
# 4. Stop mysqld2, because it will not be stopped by IM, as it is nonguarded.
|
||||
|
@ -85,7 +90,7 @@ SHOW INSTANCE STATUS mysqld1;
|
|||
STOP INSTANCE mysqld2;
|
||||
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle mysqld2: waiting to stop...
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 stopped im_daemon_life_cycle
|
||||
--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 55 stopped im_daemon_life_cycle
|
||||
--exec $MYSQL_TEST_DIR/t/log.sh im_daemon_life_cycle mysqld2: stopped.
|
||||
|
||||
###########################################################################
|
||||
|
|
|
@ -6,6 +6,15 @@
|
|||
# mysql-test/t/init_file-master.opt for the actual test
|
||||
#
|
||||
|
||||
#
|
||||
# Bug#23240 --init-file statements with NOW() reports '1970-01-01 11:00:00'as the date time
|
||||
#
|
||||
INSERT INTO init_file.startup VALUES ( NOW() );
|
||||
SELECT * INTO @X FROM init_file.startup limit 0,1;
|
||||
SELECT * INTO @Y FROM init_file.startup limit 1,1;
|
||||
SELECT YEAR(@X)-YEAR(@Y);
|
||||
DROP DATABASE init_file;
|
||||
|
||||
--echo ok
|
||||
--echo end of 4.1 tests
|
||||
#
|
||||
|
|
|
@ -53,7 +53,7 @@ pid_path="$1"
|
|||
expected_result="$2"
|
||||
total_timeout="$3"
|
||||
test_id="$4"
|
||||
log_file="$MYSQLTEST_VARDIR/log/$test_id.log"
|
||||
log_file="$MYSQLTEST_VARDIR/log/$test_id.script.log"
|
||||
|
||||
log_debug "-- $basename: starting --"
|
||||
log_debug "pid_path: '$pid_path'"
|
||||
|
|
|
@ -17,7 +17,7 @@ if [ $# -lt 2 ]; then
|
|||
fi
|
||||
|
||||
test_id="$1"
|
||||
log_file="$MYSQLTEST_VARDIR/log/$test_id.log"
|
||||
log_file="$MYSQLTEST_VARDIR/log/$test_id.script.log"
|
||||
|
||||
shift
|
||||
|
||||
|
|
|
@ -1607,10 +1607,12 @@ create function bug11555_1() returns int return (select max(i) from t1);
|
|||
create function bug11555_2() returns int return bug11555_1();
|
||||
# It is OK to report name of implicitly used table which is missing
|
||||
# when we create view.
|
||||
--error ER_NO_SUCH_TABLE
|
||||
# For stored functions however, because of exceptions handlers, there is
|
||||
# no easy way to find out if a missing table makes the view invalid.
|
||||
create view v1 as select bug11555_1();
|
||||
--error ER_NO_SUCH_TABLE
|
||||
drop view v1;
|
||||
create view v2 as select bug11555_2();
|
||||
drop view v2;
|
||||
# But we should hide name of missing implicitly used table when we use view
|
||||
create table t1 (i int);
|
||||
create view v1 as select bug11555_1();
|
||||
|
@ -1625,9 +1627,8 @@ select * from v2;
|
|||
select * from v3;
|
||||
# Note that creation of view which depends on broken view is yet
|
||||
# another form of view usage.
|
||||
--error ER_VIEW_INVALID
|
||||
create view v4 as select * from v1;
|
||||
drop view v1, v2, v3;
|
||||
drop view v1, v2, v3, v4;
|
||||
# We also should hide details about broken triggers which are
|
||||
# invoked for view.
|
||||
drop function bug11555_1;
|
||||
|
@ -1637,12 +1638,14 @@ create table t2 (i int);
|
|||
create trigger t1_ai after insert on t1 for each row insert into t2 values (new.i);
|
||||
create view v1 as select * from t1;
|
||||
drop table t2;
|
||||
--error ER_VIEW_INVALID
|
||||
# Limitation, the desired error is ER_VIEW_INVALID
|
||||
--error ER_TABLE_NOT_LOCKED
|
||||
insert into v1 values (1);
|
||||
drop trigger t1_ai;
|
||||
create function bug11555_1() returns int return (select max(i) from t2);
|
||||
create trigger t1_ai after insert on t1 for each row set @a:=bug11555_1();
|
||||
--error ER_VIEW_INVALID
|
||||
# Limitation, the desired error is ER_VIEW_INVALID
|
||||
--error ER_TABLE_NOT_LOCKED
|
||||
insert into v1 values (2);
|
||||
drop function bug11555_1;
|
||||
drop table t1;
|
||||
|
@ -1839,6 +1842,184 @@ call bug24491();
|
|||
drop procedure bug24491;
|
||||
drop tables t1;
|
||||
|
||||
#
|
||||
# BUG#18914: Calling certain SPs from triggers fail
|
||||
#
|
||||
# Failing to call a procedure that does implicit commit from a trigger
|
||||
# is a correct behaviour, however the error message was misleading.
|
||||
#
|
||||
# DROP TABLE IF EXISTS is also fixed to give correct error instead of
|
||||
# "Table doesn't exist".
|
||||
#
|
||||
--disable_warnings
|
||||
DROP FUNCTION IF EXISTS bug18914_f1;
|
||||
DROP FUNCTION IF EXISTS bug18914_f2;
|
||||
DROP PROCEDURE IF EXISTS bug18914_p1;
|
||||
DROP PROCEDURE IF EXISTS bug18914_p2;
|
||||
DROP TABLE IF EXISTS t1, t2;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE t1 (i INT);
|
||||
|
||||
CREATE PROCEDURE bug18914_p1() CREATE TABLE t2 (i INT);
|
||||
CREATE PROCEDURE bug18914_p2() DROP TABLE IF EXISTS no_such_table;
|
||||
|
||||
delimiter |;
|
||||
CREATE FUNCTION bug18914_f1() RETURNS INT
|
||||
BEGIN
|
||||
CALL bug18914_p1();
|
||||
RETURN 1;
|
||||
END |
|
||||
|
||||
CREATE FUNCTION bug18914_f2() RETURNS INT
|
||||
BEGIN
|
||||
CALL bug18914_p2();
|
||||
RETURN 1;
|
||||
END |
|
||||
delimiter ;|
|
||||
|
||||
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
|
||||
CALL bug18914_p1();
|
||||
|
||||
--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
INSERT INTO t1 VALUES (1);
|
||||
|
||||
--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
SELECT bug18914_f1();
|
||||
|
||||
--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
SELECT bug18914_f2();
|
||||
|
||||
--error ER_NO_SUCH_TABLE
|
||||
SELECT * FROM t2;
|
||||
|
||||
DROP FUNCTION bug18914_f1;
|
||||
DROP FUNCTION bug18914_f2;
|
||||
DROP PROCEDURE bug18914_p1;
|
||||
DROP PROCEDURE bug18914_p2;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug#20713 (Functions will not not continue for SQLSTATE VALUE '42S02')
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists bogus_table_20713;
|
||||
drop function if exists func_20713_a;
|
||||
drop function if exists func_20713_b;
|
||||
--enable_warnings
|
||||
|
||||
create table bogus_table_20713( id int(10) not null primary key);
|
||||
insert into bogus_table_20713 values (1), (2), (3);
|
||||
|
||||
delimiter //;
|
||||
|
||||
create function func_20713_a() returns int(11)
|
||||
begin
|
||||
declare id int;
|
||||
|
||||
declare continue handler for sqlexception set id=null;
|
||||
|
||||
set @in_func := 1;
|
||||
set id = (select id from bogus_table_20713 where id = 3);
|
||||
set @in_func := 2;
|
||||
|
||||
return id;
|
||||
end//
|
||||
|
||||
create function func_20713_b() returns int(11)
|
||||
begin
|
||||
declare id int;
|
||||
|
||||
declare continue handler for sqlstate value '42S02' set id=null;
|
||||
|
||||
set @in_func := 1;
|
||||
set id = (select id from bogus_table_20713 where id = 3);
|
||||
set @in_func := 2;
|
||||
|
||||
return id;
|
||||
end//
|
||||
|
||||
delimiter ;//
|
||||
|
||||
set @in_func := 0;
|
||||
select func_20713_a();
|
||||
select @in_func;
|
||||
|
||||
set @in_func := 0;
|
||||
select func_20713_b();
|
||||
select @in_func;
|
||||
|
||||
drop table bogus_table_20713;
|
||||
|
||||
set @in_func := 0;
|
||||
select func_20713_a();
|
||||
select @in_func;
|
||||
|
||||
set @in_func := 0;
|
||||
select func_20713_b();
|
||||
select @in_func;
|
||||
|
||||
drop function if exists func_20713_a;
|
||||
drop function if exists func_20713_b;
|
||||
|
||||
#
|
||||
# Bug#25345 (Cursors from Functions)
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists table_25345_a;
|
||||
drop table if exists table_25345_b;
|
||||
drop procedure if exists proc_25345;
|
||||
drop function if exists func_25345;
|
||||
drop function if exists func_25345_b;
|
||||
--enable_warnings
|
||||
|
||||
create table table_25345_a (a int);
|
||||
create table table_25345_b (b int);
|
||||
|
||||
delimiter ||;
|
||||
|
||||
create procedure proc_25345()
|
||||
begin
|
||||
declare c1 cursor for select a from table_25345_a;
|
||||
declare c2 cursor for select b from table_25345_b;
|
||||
|
||||
select 1 as result;
|
||||
end ||
|
||||
|
||||
create function func_25345() returns int(11)
|
||||
begin
|
||||
call proc_25345();
|
||||
return 1;
|
||||
end ||
|
||||
|
||||
create function func_25345_b() returns int(11)
|
||||
begin
|
||||
declare c1 cursor for select a from table_25345_a;
|
||||
declare c2 cursor for select b from table_25345_b;
|
||||
|
||||
return 1;
|
||||
end ||
|
||||
|
||||
delimiter ;||
|
||||
|
||||
call proc_25345();
|
||||
--error ER_SP_NO_RETSET
|
||||
select func_25345();
|
||||
select func_25345_b();
|
||||
|
||||
drop table table_25345_a;
|
||||
|
||||
call proc_25345();
|
||||
--error ER_SP_NO_RETSET
|
||||
select func_25345();
|
||||
select func_25345_b();
|
||||
|
||||
drop table table_25345_b;
|
||||
drop procedure proc_25345;
|
||||
drop function func_25345;
|
||||
drop function func_25345_b;
|
||||
|
||||
#
|
||||
# BUG#NNNN: New bug synopsis
|
||||
|
|
|
@ -500,8 +500,6 @@ DROP PROCEDURE p1;
|
|||
#
|
||||
# Test case for BUG#12976: Boolean values reversed in stored procedures?
|
||||
#
|
||||
# TODO: test case failed.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
--echo
|
||||
|
@ -566,13 +564,8 @@ BEGIN
|
|||
END|
|
||||
delimiter ;|
|
||||
|
||||
# The expected and correct result.
|
||||
|
||||
call p1();
|
||||
|
||||
# The wrong result. Note that only hex(vb) works, but is printed with two
|
||||
# digits for some reason in this case.
|
||||
|
||||
call p2();
|
||||
|
||||
#
|
||||
|
@ -583,6 +576,64 @@ DROP TABLE t1;
|
|||
DROP PROCEDURE p1;
|
||||
DROP PROCEDURE p2;
|
||||
|
||||
# Additional tests for Bug#12976
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS table_12976_a;
|
||||
DROP TABLE IF EXISTS table_12976_b;
|
||||
DROP PROCEDURE IF EXISTS proc_12976_a;
|
||||
DROP PROCEDURE IF EXISTS proc_12976_b;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE table_12976_a (val bit(1));
|
||||
|
||||
CREATE TABLE table_12976_b(
|
||||
appname varchar(15),
|
||||
emailperm bit not null default 1,
|
||||
phoneperm bit not null default 0);
|
||||
|
||||
insert into table_12976_b values ('A', b'1', b'1'), ('B', b'0', b'0');
|
||||
|
||||
delimiter ||;
|
||||
CREATE PROCEDURE proc_12976_a()
|
||||
BEGIN
|
||||
declare localvar bit(1);
|
||||
SELECT val INTO localvar FROM table_12976_a;
|
||||
SELECT coalesce(localvar, 1)+1, coalesce(val, 1)+1 FROM table_12976_a;
|
||||
END||
|
||||
|
||||
CREATE PROCEDURE proc_12976_b(
|
||||
name varchar(15),
|
||||
out ep bit,
|
||||
out msg varchar(10))
|
||||
BEGIN
|
||||
SELECT emailperm into ep FROM table_12976_b where (appname = name);
|
||||
IF ep is true THEN
|
||||
SET msg = 'True';
|
||||
ELSE
|
||||
SET msg = 'False';
|
||||
END IF;
|
||||
END||
|
||||
|
||||
delimiter ;||
|
||||
|
||||
INSERT table_12976_a VALUES (0);
|
||||
call proc_12976_a();
|
||||
UPDATE table_12976_a set val=1;
|
||||
call proc_12976_a();
|
||||
|
||||
call proc_12976_b('A', @ep, @msg);
|
||||
select @ep, @msg;
|
||||
|
||||
call proc_12976_b('B', @ep, @msg);
|
||||
select @ep, @msg;
|
||||
|
||||
DROP TABLE table_12976_a;
|
||||
DROP TABLE table_12976_b;
|
||||
DROP PROCEDURE proc_12976_a;
|
||||
DROP PROCEDURE proc_12976_b;
|
||||
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Test case for BUG#9572: Stored procedures: variable type declarations
|
||||
|
|
|
@ -1370,7 +1370,7 @@ end|
|
|||
select f11()|
|
||||
--error ER_CANT_REOPEN_TABLE
|
||||
select f11() from t1|
|
||||
# We don't handle temporary tables used by nested functions well
|
||||
# Test that using a single table instance at a time works
|
||||
create function f12_1() returns int
|
||||
begin
|
||||
drop temporary table if exists t3;
|
||||
|
@ -1380,11 +1380,9 @@ begin
|
|||
end|
|
||||
create function f12_2() returns int
|
||||
return (select count(*) from t3)|
|
||||
# We need clean start to get error
|
||||
|
||||
drop temporary table t3|
|
||||
--error ER_NO_SUCH_TABLE
|
||||
select f12_1()|
|
||||
--error ER_NO_SUCH_TABLE
|
||||
select f12_1() from t1 limit 1|
|
||||
|
||||
# Cleanup
|
||||
|
@ -6693,6 +6691,53 @@ CALL bug24117()|
|
|||
DROP PROCEDURE bug24117|
|
||||
DROP TABLE t3|
|
||||
|
||||
#
|
||||
# Bug#8407(Stored functions/triggers ignore exception handler)
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
drop function if exists func_8407_a|
|
||||
drop function if exists func_8407_b|
|
||||
--enable_warnings
|
||||
|
||||
create function func_8407_a() returns int
|
||||
begin
|
||||
declare x int;
|
||||
|
||||
declare continue handler for sqlexception
|
||||
begin
|
||||
end;
|
||||
|
||||
select 1 from no_such_view limit 1 into x;
|
||||
|
||||
return x;
|
||||
end|
|
||||
|
||||
create function func_8407_b() returns int
|
||||
begin
|
||||
declare x int default 0;
|
||||
|
||||
declare continue handler for sqlstate '42S02'
|
||||
begin
|
||||
set x:= x+1000;
|
||||
end;
|
||||
|
||||
case (select 1 from no_such_view limit 1)
|
||||
when 1 then set x:= x+1;
|
||||
when 2 then set x:= x+2;
|
||||
else set x:= x+100;
|
||||
end case;
|
||||
set x:=x + 500;
|
||||
|
||||
return x;
|
||||
end|
|
||||
|
||||
select func_8407_a()|
|
||||
select func_8407_b()|
|
||||
|
||||
drop function func_8407_a|
|
||||
drop function func_8407_b|
|
||||
|
||||
#
|
||||
# NOTE: The delimiter is `|`, and not `;`. It is changed to `;`
|
||||
# at the end of the file!
|
||||
|
|
|
@ -2002,7 +2002,7 @@ EXPLAIN SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
|
|||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug 24653: sorting by expressions containing subselects
|
||||
# Bug 24653: sorting by expressions containing subselects
|
||||
# that return more than one row
|
||||
#
|
||||
|
||||
|
@ -2014,12 +2014,12 @@ INSERT INTO t2 VALUES
|
|||
(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 );
|
||||
--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 > 2), a;
|
||||
--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 > 2), a;
|
||||
--error 1242
|
||||
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);
|
||||
--error 1242
|
||||
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
|
|||
SELECT a FROM t1 GROUP BY a
|
||||
HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(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
|
||||
HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(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),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
|
||||
--error 1242
|
||||
SELECT a FROM t1
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 1),
|
||||
(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),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
|
||||
--error 1242
|
||||
SELECT a FROM t1
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(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
|
||||
|
||||
|
@ -2571,7 +2571,7 @@ DROP TABLE t1,t2;
|
|||
#
|
||||
# Bug #25219: EXIST subquery with UNION over a mix of
|
||||
# correlated and uncorrelated selects
|
||||
#
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (id char(4) PRIMARY KEY, c int);
|
||||
CREATE TABLE t2 (c int);
|
||||
|
@ -2579,28 +2579,29 @@ CREATE TABLE t2 (c int);
|
|||
INSERT INTO t1 VALUES ('aa', 1);
|
||||
INSERT INTO t2 VALUES (1);
|
||||
|
||||
SELECT * FROM t1
|
||||
SELECT * FROM t1
|
||||
WHERE EXISTS (SELECT c FROM t2 WHERE c=1
|
||||
UNION
|
||||
UNION
|
||||
SELECT c from t2 WHERE c=t1.c);
|
||||
|
||||
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
|
||||
UNION
|
||||
UNION
|
||||
SELECT c from t2 WHERE c=t1.c);
|
||||
|
||||
INSERT INTO t2 VALUES (2);
|
||||
CREATE TABLE t3 (c int);
|
||||
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
|
||||
UNION
|
||||
UNION
|
||||
SELECT c from t2 WHERE c=t1.c);
|
||||
|
||||
DROP TABLE t1,t2,t3;
|
||||
DROP TABLE t1,t2,t3;
|
||||
|
||||
#
|
||||
# Bug#23800: Outer fields in correlated subqueries is used in a temporary
|
||||
# table created for sorting.
|
||||
|
@ -2628,3 +2629,103 @@ 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 "(())")
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP TABLE IF EXISTS t2;
|
||||
DROP TABLE IF EXISTS t1xt2;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id_1 int(5) NOT NULL,
|
||||
t varchar(4) DEFAULT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE t2 (
|
||||
id_2 int(5) NOT NULL,
|
||||
t varchar(4) DEFAULT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE t1xt2 (
|
||||
id_1 int(5) NOT NULL,
|
||||
id_2 int(5) NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO t1 VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd');
|
||||
|
||||
INSERT INTO t2 VALUES (2, 'bb'), (3, 'cc'), (4, 'dd'), (12, 'aa');
|
||||
|
||||
INSERT INTO t1xt2 VALUES (2, 2), (3, 3), (4, 4);
|
||||
|
||||
# subselect returns 0 rows
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1)));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1))));
|
||||
|
||||
insert INTO t1xt2 VALUES (1, 12);
|
||||
|
||||
# subselect returns 1 row
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
|
||||
|
||||
insert INTO t1xt2 VALUES (2, 12);
|
||||
|
||||
# subselect returns more than 1 row
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
|
||||
|
||||
SELECT DISTINCT t1.id_1 FROM t1 WHERE
|
||||
(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1xt2;
|
||||
|
||||
|
|
|
@ -1625,4 +1625,78 @@ SELECT fubar_id FROM t2;
|
|||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
#
|
||||
# Bug#21285 (Incorrect message error deleting records in a table with a
|
||||
# trigger for inserting)
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS bug21825_A;
|
||||
DROP TABLE IF EXISTS bug21825_B;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE bug21825_A (id int(10));
|
||||
CREATE TABLE bug21825_B (id int(10));
|
||||
|
||||
delimiter //;
|
||||
|
||||
CREATE TRIGGER trgA AFTER INSERT ON bug21825_A
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
INSERT INTO bug21825_B (id) values (1);
|
||||
END//
|
||||
delimiter ;//
|
||||
|
||||
INSERT INTO bug21825_A (id) VALUES (10);
|
||||
INSERT INTO bug21825_A (id) VALUES (20);
|
||||
|
||||
DROP TABLE bug21825_B;
|
||||
|
||||
# Must pass, the missing table in the insert trigger should not matter.
|
||||
DELETE FROM bug21825_A WHERE id = 20;
|
||||
|
||||
DROP TABLE bug21825_A;
|
||||
|
||||
#
|
||||
# Bug#22580 (DROP TABLE in nested stored procedure causes strange dependancy
|
||||
# error)
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS bug22580_t1;
|
||||
DROP PROCEDURE IF EXISTS bug22580_proc_1;
|
||||
DROP PROCEDURE IF EXISTS bug22580_proc_2;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE bug22580_t1 (a INT, b INT);
|
||||
|
||||
DELIMITER ||;
|
||||
|
||||
CREATE PROCEDURE bug22580_proc_2()
|
||||
BEGIN
|
||||
DROP TABLE IF EXISTS bug22580_tmp;
|
||||
CREATE TEMPORARY TABLE bug22580_tmp (a INT);
|
||||
DROP TABLE bug22580_tmp;
|
||||
END||
|
||||
|
||||
CREATE PROCEDURE bug22580_proc_1()
|
||||
BEGIN
|
||||
CALL bug22580_proc_2();
|
||||
END||
|
||||
|
||||
CREATE TRIGGER t1bu BEFORE UPDATE ON bug22580_t1
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
CALL bug22580_proc_1();
|
||||
END||
|
||||
|
||||
DELIMITER ;||
|
||||
|
||||
# Must pass, the actions of the update trigger should not matter
|
||||
INSERT INTO bug22580_t1 VALUES (1,1);
|
||||
|
||||
DROP TABLE bug22580_t1;
|
||||
DROP PROCEDURE bug22580_proc_1;
|
||||
DROP PROCEDURE bug22580_proc_2;
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
|
|
@ -748,12 +748,14 @@ drop view v1;
|
|||
#
|
||||
# VIEWs with national characters
|
||||
#
|
||||
create table tü (cü char);
|
||||
create view vü as select cü from tü;
|
||||
insert into vü values ('ü');
|
||||
select * from vü;
|
||||
drop view vü;
|
||||
drop table tü;
|
||||
set names utf8;
|
||||
create table tü (cü char);
|
||||
create view vü as select cü from tü;
|
||||
insert into vü values ('ü');
|
||||
select * from vü;
|
||||
drop view vü;
|
||||
drop table tü;
|
||||
set names latin1;
|
||||
|
||||
#
|
||||
# problem with used_tables() of outer reference resolved in VIEW
|
||||
|
@ -2991,7 +2993,7 @@ DROP VIEW v1;
|
|||
#
|
||||
|
||||
CREATE TABLE t1 (mydate DATETIME);
|
||||
INSERT INTO t1 VALUES
|
||||
INSERT INTO t1 VALUES
|
||||
('2007-01-01'), ('2007-01-02'), ('2007-01-30'), ('2007-01-31');
|
||||
|
||||
CREATE VIEW v1 AS SELECT mydate from t1;
|
||||
|
@ -3039,7 +3041,7 @@ drop view v1;
|
|||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#26209: queries with GROUP BY and ORDER BY using views
|
||||
# Bug#26209: queries with GROUP BY and ORDER BY using views
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
|
@ -3058,4 +3060,107 @@ SELECT code, COUNT(DISTINCT country) FROM v1 GROUP BY code ORDER BY MAX(id);
|
|||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# BUG#25897: Some queries are no longer possible after a CREATE VIEW
|
||||
# fails
|
||||
#
|
||||
--disable_warnings
|
||||
DROP VIEW IF EXISTS v1;
|
||||
--enable_warnings
|
||||
|
||||
let $query = SELECT * FROM (SELECT 1) AS t;
|
||||
|
||||
eval $query;
|
||||
--error ER_VIEW_SELECT_DERIVED
|
||||
eval CREATE VIEW v1 AS $query;
|
||||
--echo # Previously the following would fail.
|
||||
eval $query;
|
||||
|
||||
#
|
||||
# Bug#24532: The return data type of IS TRUE is different from similar
|
||||
# operations
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
drop view if exists view_24532_a;
|
||||
drop view if exists view_24532_b;
|
||||
drop table if exists table_24532;
|
||||
--enable_warnings
|
||||
|
||||
create table table_24532 (
|
||||
a int,
|
||||
b bigint,
|
||||
c int(4),
|
||||
d bigint(48)
|
||||
);
|
||||
|
||||
create view view_24532_a as
|
||||
select
|
||||
a IS TRUE,
|
||||
a IS NOT TRUE,
|
||||
a IS FALSE,
|
||||
a IS NOT FALSE,
|
||||
a IS UNKNOWN,
|
||||
a IS NOT UNKNOWN,
|
||||
a is NULL,
|
||||
a IS NOT NULL,
|
||||
ISNULL(a),
|
||||
b IS TRUE,
|
||||
b IS NOT TRUE,
|
||||
b IS FALSE,
|
||||
b IS NOT FALSE,
|
||||
b IS UNKNOWN,
|
||||
b IS NOT UNKNOWN,
|
||||
b is NULL,
|
||||
b IS NOT NULL,
|
||||
ISNULL(b),
|
||||
c IS TRUE,
|
||||
c IS NOT TRUE,
|
||||
c IS FALSE,
|
||||
c IS NOT FALSE,
|
||||
c IS UNKNOWN,
|
||||
c IS NOT UNKNOWN,
|
||||
c is NULL,
|
||||
c IS NOT NULL,
|
||||
ISNULL(c),
|
||||
d IS TRUE,
|
||||
d IS NOT TRUE,
|
||||
d IS FALSE,
|
||||
d IS NOT FALSE,
|
||||
d IS UNKNOWN,
|
||||
d IS NOT UNKNOWN,
|
||||
d is NULL,
|
||||
d IS NOT NULL,
|
||||
ISNULL(d)
|
||||
from table_24532;
|
||||
|
||||
describe view_24532_a;
|
||||
|
||||
create view view_24532_b as
|
||||
select
|
||||
a IS TRUE,
|
||||
if(ifnull(a, 0), 1, 0) as old_istrue,
|
||||
a IS NOT TRUE,
|
||||
if(ifnull(a, 0), 0, 1) as old_isnottrue,
|
||||
a IS FALSE,
|
||||
if(ifnull(a, 1), 0, 1) as old_isfalse,
|
||||
a IS NOT FALSE,
|
||||
if(ifnull(a, 1), 1, 0) as old_isnotfalse
|
||||
from table_24532;
|
||||
|
||||
describe view_24532_b;
|
||||
|
||||
show create view view_24532_b;
|
||||
|
||||
insert into table_24532 values (0, 0, 0, 0);
|
||||
select * from view_24532_b;
|
||||
update table_24532 set a=1;
|
||||
select * from view_24532_b;
|
||||
update table_24532 set a=NULL;
|
||||
select * from view_24532_b;
|
||||
|
||||
drop view view_24532_a;
|
||||
drop view view_24532_b;
|
||||
drop table table_24532;
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
|
|
@ -63,7 +63,7 @@ pid_path="$1"
|
|||
total_attempts="$2"
|
||||
event="$3"
|
||||
test_id="$4"
|
||||
log_file="$MYSQLTEST_VARDIR/log/$test_id.log"
|
||||
log_file="$MYSQLTEST_VARDIR/log/$test_id.script.log"
|
||||
|
||||
log_debug "-- $basename: starting --"
|
||||
log_debug "pid_path: '$pid_path'"
|
||||
|
|
|
@ -30,7 +30,7 @@ password="$4"
|
|||
db="$5"
|
||||
total_timeout="$6"
|
||||
test_id="$7"
|
||||
log_file="$MYSQLTEST_VARDIR/log/$test_id.log"
|
||||
log_file="$MYSQLTEST_VARDIR/log/$test_id.script.log"
|
||||
|
||||
log_debug "-- $basename: starting --"
|
||||
log_debug "client_exe: '$client_exe'"
|
||||
|
|
|
@ -345,7 +345,12 @@ File my_sopen(const char *path, int oflag, int shflag, int pmode)
|
|||
return -1; /* return error to caller */
|
||||
}
|
||||
|
||||
fh= _open_osfhandle((intptr_t)osfh, oflag & (_O_APPEND | _O_RDONLY | _O_TEXT));
|
||||
if ((fh= _open_osfhandle((intptr_t)osfh,
|
||||
oflag & (_O_APPEND | _O_RDONLY | _O_TEXT))) == -1)
|
||||
{
|
||||
_dosmaperr(GetLastError()); /* map error */
|
||||
CloseHandle(osfh);
|
||||
}
|
||||
|
||||
return fh; /* return handle */
|
||||
}
|
||||
|
|
|
@ -130,7 +130,8 @@ public:
|
|||
NullablePrimaryKey = 740,
|
||||
UnsupportedChange = 741,
|
||||
BackupInProgress = 762,
|
||||
IncompatibleVersions = 763
|
||||
IncompatibleVersions = 763,
|
||||
SingleUser = 299
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
@ -206,7 +206,8 @@ public:
|
|||
NotUnique = 4251,
|
||||
AllocationError = 4252,
|
||||
CreateIndexTableFailed = 4253,
|
||||
DuplicateAttributes = 4258
|
||||
DuplicateAttributes = 4258,
|
||||
SingleUser = 299
|
||||
};
|
||||
|
||||
CreateIndxConf m_conf;
|
||||
|
|
|
@ -91,7 +91,8 @@ public:
|
|||
RecordTooBig = 738,
|
||||
InvalidPrimaryKeySize = 739,
|
||||
NullablePrimaryKey = 740,
|
||||
InvalidCharset = 743
|
||||
InvalidCharset = 743,
|
||||
SingleUser = 299
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
@ -172,7 +172,8 @@ public:
|
|||
IndexNotFound = 4243,
|
||||
BadRequestType = 4247,
|
||||
InvalidName = 4248,
|
||||
NotAnIndex = 4254
|
||||
NotAnIndex = 4254,
|
||||
SingleUser = 299
|
||||
};
|
||||
STATIC_CONST( SignalLength = DropIndxConf::SignalLength + 3 );
|
||||
|
||||
|
|
|
@ -58,7 +58,8 @@ public:
|
|||
InvalidTableVersion = 241,
|
||||
DropInProgress = 283,
|
||||
NoDropTableRecordAvailable = 1229,
|
||||
BackupInProgress = 761
|
||||
BackupInProgress = 761,
|
||||
SingleUser = 299
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -926,7 +926,7 @@ const EventLoggerBase::EventRepLogLevelMatrix EventLoggerBase::matrix[] = {
|
|||
ROW(NDBStopCompleted, LogLevel::llStartUp, 1, Logger::LL_INFO ),
|
||||
ROW(NDBStopForced, LogLevel::llStartUp, 1, Logger::LL_ALERT ),
|
||||
ROW(NDBStopAborted, LogLevel::llStartUp, 1, Logger::LL_INFO ),
|
||||
ROW(StartREDOLog, LogLevel::llStartUp, 10, Logger::LL_INFO ),
|
||||
ROW(StartREDOLog, LogLevel::llStartUp, 4, Logger::LL_INFO ),
|
||||
ROW(StartLog, LogLevel::llStartUp, 10, Logger::LL_INFO ),
|
||||
ROW(UNDORecordsExecuted, LogLevel::llStartUp, 15, Logger::LL_INFO ),
|
||||
ROW(StartReport, LogLevel::llStartUp, 4, Logger::LL_INFO ),
|
||||
|
|
|
@ -96,6 +96,8 @@ printPACKED_SIGNAL(FILE * output, const Uint32 * theData, Uint32 len, Uint16 rec
|
|||
}
|
||||
default:
|
||||
fprintf(output, "Unknown signal type\n");
|
||||
i = len; // terminate printing
|
||||
break;
|
||||
}
|
||||
}//for
|
||||
fprintf(output, "--------- End Packed Signals ----------\n");
|
||||
|
|
|
@ -2910,6 +2910,15 @@ Dbdict::execCREATE_TABLE_REQ(Signal* signal){
|
|||
break;
|
||||
}
|
||||
|
||||
if(getNodeState().getSingleUserMode() &&
|
||||
(refToNode(signal->getSendersBlockRef()) !=
|
||||
getNodeState().getSingleUserApi()))
|
||||
{
|
||||
jam();
|
||||
parseRecord.errorCode = CreateTableRef::SingleUser;
|
||||
break;
|
||||
}
|
||||
|
||||
CreateTableRecordPtr createTabPtr;
|
||||
c_opCreateTable.seize(createTabPtr);
|
||||
|
||||
|
@ -3072,6 +3081,15 @@ Dbdict::execALTER_TABLE_REQ(Signal* signal)
|
|||
return;
|
||||
}
|
||||
|
||||
if(getNodeState().getSingleUserMode() &&
|
||||
(refToNode(signal->getSendersBlockRef()) !=
|
||||
getNodeState().getSingleUserApi()))
|
||||
{
|
||||
jam();
|
||||
alterTableRef(signal, req, AlterTableRef::SingleUser);
|
||||
return;
|
||||
}
|
||||
|
||||
const TableRecord::TabState tabState = tablePtr.p->tabState;
|
||||
bool ok = false;
|
||||
switch(tabState){
|
||||
|
@ -5396,6 +5414,15 @@ Dbdict::execDROP_TABLE_REQ(Signal* signal){
|
|||
return;
|
||||
}
|
||||
|
||||
if(getNodeState().getSingleUserMode() &&
|
||||
(refToNode(signal->getSendersBlockRef()) !=
|
||||
getNodeState().getSingleUserApi()))
|
||||
{
|
||||
jam();
|
||||
dropTableRef(signal, req, DropTableRef::SingleUser);
|
||||
return;
|
||||
}
|
||||
|
||||
const TableRecord::TabState tabState = tablePtr.p->tabState;
|
||||
bool ok = false;
|
||||
switch(tabState){
|
||||
|
@ -6526,6 +6553,13 @@ Dbdict::execCREATE_INDX_REQ(Signal* signal)
|
|||
jam();
|
||||
tmperr = CreateIndxRef::Busy;
|
||||
}
|
||||
else if(getNodeState().getSingleUserMode() &&
|
||||
(refToNode(senderRef) !=
|
||||
getNodeState().getSingleUserApi()))
|
||||
{
|
||||
jam();
|
||||
tmperr = CreateIndxRef::SingleUser;
|
||||
}
|
||||
if (tmperr != CreateIndxRef::NoError) {
|
||||
releaseSections(signal);
|
||||
OpCreateIndex opBusy;
|
||||
|
@ -7096,6 +7130,13 @@ Dbdict::execDROP_INDX_REQ(Signal* signal)
|
|||
jam();
|
||||
tmperr = DropIndxRef::Busy;
|
||||
}
|
||||
else if(getNodeState().getSingleUserMode() &&
|
||||
(refToNode(senderRef) !=
|
||||
getNodeState().getSingleUserApi()))
|
||||
{
|
||||
jam();
|
||||
tmperr = DropIndxRef::SingleUser;
|
||||
}
|
||||
if (tmperr != DropIndxRef::NoError) {
|
||||
err = tmperr;
|
||||
goto error;
|
||||
|
|
|
@ -13686,7 +13686,7 @@ Dbdih::execDUMP_STATE_ORD(Signal* signal)
|
|||
}
|
||||
|
||||
if(arg == DumpStateOrd::EnableUndoDelayDataWrite){
|
||||
g_eventLogger.info("Dbdih:: delay write of datapages for table = %s",
|
||||
g_eventLogger.info("Dbdih:: delay write of datapages for table = %d",
|
||||
dumpState->args[1]);
|
||||
// Send this dump to ACC and TUP
|
||||
EXECUTE_DIRECT(DBACC, GSN_DUMP_STATE_ORD, signal, 2);
|
||||
|
|
|
@ -456,6 +456,7 @@ void Dblqh::execCONTINUEB(Signal* signal)
|
|||
else
|
||||
{
|
||||
jam();
|
||||
cstartRecReq = 2;
|
||||
StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend();
|
||||
conf->startingNodeId = getOwnNodeId();
|
||||
sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal,
|
||||
|
@ -11665,7 +11666,7 @@ void Dblqh::execGCP_SAVEREQ(Signal* signal)
|
|||
return;
|
||||
}
|
||||
|
||||
if(getNodeState().getNodeRestartInProgress() && cstartRecReq == ZFALSE)
|
||||
if(getNodeState().getNodeRestartInProgress() && cstartRecReq < 2)
|
||||
{
|
||||
GCPSaveRef * const saveRef = (GCPSaveRef*)&signal->theData[0];
|
||||
saveRef->dihPtr = dihPtr;
|
||||
|
@ -11942,6 +11943,10 @@ void Dblqh::execFSCLOSECONF(Signal* signal)
|
|||
// Set the prev file to check if we shall close it.
|
||||
logFilePtr.i = logFilePtr.p->prevLogFile;
|
||||
ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
|
||||
|
||||
logPartPtr.i = logFilePtr.p->logPartRec;
|
||||
ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
|
||||
|
||||
exitFromInvalidate(signal);
|
||||
return;
|
||||
case LogFileRecord::CLOSING_INIT:
|
||||
|
@ -13810,7 +13815,7 @@ void Dblqh::srCompletedLab(Signal* signal)
|
|||
* NO MORE FRAGMENTS ARE WAITING FOR SYSTEM RESTART.
|
||||
* -------------------------------------------------------------------- */
|
||||
lcpPtr.p->lcpState = LcpRecord::LCP_IDLE;
|
||||
if (cstartRecReq == ZTRUE) {
|
||||
if (cstartRecReq == 1) {
|
||||
jam();
|
||||
/* ----------------------------------------------------------------
|
||||
* WE HAVE ALSO RECEIVED AN INDICATION THAT NO MORE FRAGMENTS
|
||||
|
@ -13880,7 +13885,7 @@ void Dblqh::execSTART_RECREQ(Signal* signal)
|
|||
ndbrequire(req->receivingNodeId == cownNodeid);
|
||||
|
||||
cnewestCompletedGci = cnewestGci;
|
||||
cstartRecReq = ZTRUE;
|
||||
cstartRecReq = 1;
|
||||
for (logPartPtr.i = 0; logPartPtr.i < 4; logPartPtr.i++) {
|
||||
ptrAss(logPartPtr, logPartRecord);
|
||||
logPartPtr.p->logPartNewestCompletedGCI = cnewestCompletedGci;
|
||||
|
@ -13901,6 +13906,7 @@ void Dblqh::execSTART_RECREQ(Signal* signal)
|
|||
}//if
|
||||
if(cstartType == NodeState::ST_INITIAL_NODE_RESTART){
|
||||
jam();
|
||||
cstartRecReq = 2;
|
||||
StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend();
|
||||
conf->startingNodeId = getOwnNodeId();
|
||||
sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal,
|
||||
|
@ -15719,6 +15725,7 @@ void Dblqh::srFourthComp(Signal* signal)
|
|||
else
|
||||
{
|
||||
jam();
|
||||
cstartRecReq = 2;
|
||||
StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend();
|
||||
conf->startingNodeId = getOwnNodeId();
|
||||
sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal,
|
||||
|
@ -16685,7 +16692,7 @@ void Dblqh::initialiseRecordsLab(Signal* signal, Uint32 data,
|
|||
cCommitBlocked = false;
|
||||
ccurrentGcprec = RNIL;
|
||||
caddNodeState = ZFALSE;
|
||||
cstartRecReq = ZFALSE;
|
||||
cstartRecReq = 0;
|
||||
cnewestGci = (UintR)-1;
|
||||
cnewestCompletedGci = (UintR)-1;
|
||||
crestartOldestGci = 0;
|
||||
|
|
|
@ -346,27 +346,27 @@ NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r)
|
|||
}
|
||||
break;
|
||||
case NdbDictionary::Column::Blob:
|
||||
{
|
||||
const NdbBlob::Head* h = (const NdbBlob::Head*)r.aRef();
|
||||
out << h->length << ":";
|
||||
const unsigned char* p = (const unsigned char*)(h + 1);
|
||||
unsigned n = r.arraySize() - sizeof(*h);
|
||||
for (unsigned k = 0; k < n && k < h->length; k++)
|
||||
out.print("%02X", (int)p[k]);
|
||||
j = length;
|
||||
}
|
||||
break;
|
||||
case NdbDictionary::Column::Text:
|
||||
{
|
||||
const NdbBlob::Head* h = (const NdbBlob::Head*)r.aRef();
|
||||
out << h->length << ":";
|
||||
const unsigned char* p = (const unsigned char*)(h + 1);
|
||||
unsigned n = r.arraySize() - sizeof(*h);
|
||||
for (unsigned k = 0; k < n && k < h->length; k++)
|
||||
out.print("%c", (int)p[k]);
|
||||
j = length;
|
||||
{
|
||||
// user defined aRef() may not be aligned to Uint64
|
||||
NdbBlob::Head head;
|
||||
memcpy(&head, r.aRef(), sizeof(head));
|
||||
out << head.length << ":";
|
||||
const unsigned char* p = (const unsigned char*)r.aRef() + sizeof(head);
|
||||
if (r.arraySize() < sizeof(head))
|
||||
out << "***error***"; // really cannot happen
|
||||
else {
|
||||
unsigned n = r.arraySize() - sizeof(head);
|
||||
for (unsigned k = 0; k < n && k < head.length; k++) {
|
||||
if (r.getType() == NdbDictionary::Column::Blob)
|
||||
out.print("%02X", (int)p[k]);
|
||||
else
|
||||
out.print("%c", (int)p[k]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
j = length;
|
||||
}
|
||||
break;
|
||||
case NdbDictionary::Column::Longvarchar:
|
||||
{
|
||||
unsigned len = uint2korr(r.aRef());
|
||||
|
|
|
@ -264,6 +264,7 @@ ErrorBundle ErrorCodes[] = {
|
|||
/**
|
||||
* Application error
|
||||
*/
|
||||
{ 299, AE, "Operation not allowed or aborted due to single user mode" },
|
||||
{ 763, AE, "Alter table requires cluster nodes to have exact same version" },
|
||||
{ 823, AE, "Too much attrinfo from application in tuple manager" },
|
||||
{ 831, AE, "Too many nullable/bitfields in table definition" },
|
||||
|
|
|
@ -54,7 +54,12 @@ BackupFile::Twiddle(const AttributeDesc* attr_desc, AttributeData* attr_data, Ui
|
|||
return true;
|
||||
case 64:
|
||||
for(i = 0; i<arraySize; i++){
|
||||
attr_data->u_int64_value[i] = Twiddle64(attr_data->u_int64_value[i]);
|
||||
// allow unaligned
|
||||
char* p = (char*)&attr_data->u_int64_value[i];
|
||||
Uint64 x;
|
||||
memcpy(&x, p, sizeof(Uint64));
|
||||
x = Twiddle64(x);
|
||||
memcpy(p, &x, sizeof(Uint64));
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
|
|
|
@ -143,7 +143,8 @@ BIN_FILES="extra/comp_err$BS extra/replace$BS extra/perror$BS \
|
|||
extra/resolve_stack_dump$BS extra/mysql_waitpid$BS \
|
||||
myisam/myisamchk$BS myisam/myisampack$BS myisam/myisamlog$BS \
|
||||
myisam/myisam_ftdump$BS \
|
||||
sql/mysqld$BS sql/mysql_tzinfo_to_sql$BS \
|
||||
sql/mysqld$BS sql/mysqld-debug$BS \
|
||||
sql/mysql_tzinfo_to_sql$BS \
|
||||
server-tools/instance-manager/mysqlmanager$BS \
|
||||
client/mysql$BS client/mysqlshow$BS client/mysqladmin$BS \
|
||||
client/mysqldump$BS client/mysqlimport$BS \
|
||||
|
|
|
@ -508,7 +508,7 @@ int Instance_options::add_option(const char* option)
|
|||
{"--pid-file=", 11, &mysqld_pid_file, SAVE_WHOLE_AND_ADD},
|
||||
{"--mysqld-path=", 14, &mysqld_path, SAVE_VALUE},
|
||||
{"--nonguarded", 9, &nonguarded, SAVE_WHOLE},
|
||||
{"--shutdown_delay", 9, &shutdown_delay, SAVE_VALUE},
|
||||
{"--shutdown-delay", 9, &shutdown_delay, SAVE_VALUE},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
struct selected_options_st *selected_options;
|
||||
|
|
|
@ -210,10 +210,13 @@ void Listener_thread::run()
|
|||
return;
|
||||
|
||||
err:
|
||||
log_error("Listener: failed to initialize. Initiate shutdown...");
|
||||
|
||||
// we have to close the ip sockets in case of error
|
||||
for (i= 0; i < num_sockets; i++)
|
||||
closesocket(sockets[i]);
|
||||
|
||||
thread_registry.set_error_status();
|
||||
thread_registry.unregister_thread(&thread_info);
|
||||
thread_registry.request_shutdown();
|
||||
my_thread_end();
|
||||
|
|
|
@ -114,6 +114,9 @@ void stop_all(Guardian_thread *guardian, Thread_registry *registry)
|
|||
pthread_cond_signal(&guardian->COND_guardian);
|
||||
/* stop all threads */
|
||||
registry->deliver_shutdown();
|
||||
|
||||
/* Set error status in the thread registry. */
|
||||
registry->set_error_status();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -123,7 +126,7 @@ void stop_all(Guardian_thread *guardian, Thread_registry *registry)
|
|||
architecture.
|
||||
*/
|
||||
|
||||
void manager(const Options &options)
|
||||
int manager(const Options &options)
|
||||
{
|
||||
Thread_registry thread_registry;
|
||||
/*
|
||||
|
@ -145,10 +148,10 @@ void manager(const Options &options)
|
|||
instance_map.guardian= &guardian_thread;
|
||||
|
||||
if (instance_map.init() || user_map.init())
|
||||
return;
|
||||
return 1;
|
||||
|
||||
if (user_map.load(options.password_file_name))
|
||||
return;
|
||||
return 1;
|
||||
|
||||
/* write Instance Manager pid file */
|
||||
|
||||
|
@ -157,7 +160,7 @@ void manager(const Options &options)
|
|||
(int) manager_pid);
|
||||
|
||||
if (create_pid_file(options.pid_file_name, manager_pid))
|
||||
return;
|
||||
return 1;
|
||||
|
||||
/*
|
||||
Initialize signals and alarm-infrastructure.
|
||||
|
@ -301,5 +304,6 @@ err:
|
|||
end_thr_alarm(1);
|
||||
/* don't pthread_exit to kill all threads who did not shut down in time */
|
||||
#endif
|
||||
}
|
||||
|
||||
return thread_registry.get_error_status() ? 1 : 0;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
struct Options;
|
||||
|
||||
void manager(const Options &options);
|
||||
int manager(const Options &options);
|
||||
|
||||
int create_pid_file(const char *pid_file_name, int pid);
|
||||
|
||||
|
|
|
@ -110,8 +110,7 @@ int main(int argc, char *argv[])
|
|||
else
|
||||
#endif
|
||||
|
||||
manager(options);
|
||||
return_value= 0;
|
||||
return_value= manager(options);
|
||||
|
||||
err:
|
||||
options.cleanup();
|
||||
|
@ -254,26 +253,23 @@ static void daemonize(const char *log_file_name)
|
|||
enum { CHILD_OK= 0, CHILD_NEED_RESPAWN, CHILD_EXIT_ANGEL };
|
||||
|
||||
static volatile sig_atomic_t child_status= CHILD_OK;
|
||||
static volatile sig_atomic_t child_exit_code= 0;
|
||||
|
||||
/*
|
||||
Signal handler for SIGCHLD: reap child, analyze child exit status, and set
|
||||
Signal handler for SIGCHLD: reap child, analyze child exit code, and set
|
||||
child_status appropriately.
|
||||
*/
|
||||
|
||||
void reap_child(int __attribute__((unused)) signo)
|
||||
{
|
||||
int child_exit_status;
|
||||
/* As we have only one child, no need to cycle waitpid */
|
||||
if (waitpid(0, &child_exit_status, WNOHANG) > 0)
|
||||
/* NOTE: As we have only one child, no need to cycle waitpid(). */
|
||||
|
||||
int exit_code;
|
||||
|
||||
if (waitpid(0, &exit_code, WNOHANG) > 0)
|
||||
{
|
||||
if (WIFSIGNALED(child_exit_status))
|
||||
child_status= CHILD_NEED_RESPAWN;
|
||||
else
|
||||
/*
|
||||
As reap_child is not called for SIGSTOP, we should be here only
|
||||
if the child exited normally.
|
||||
*/
|
||||
child_status= CHILD_EXIT_ANGEL;
|
||||
child_exit_code= exit_code;
|
||||
child_status= exit_code ? CHILD_NEED_RESPAWN : CHILD_EXIT_ANGEL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -353,10 +349,16 @@ spawn:
|
|||
else if (child_status == CHILD_NEED_RESPAWN)
|
||||
{
|
||||
child_status= CHILD_OK;
|
||||
log_error("angel(): mysqlmanager exited abnormally: respawning...");
|
||||
log_error("angel(): mysqlmanager exited abnormally (exit code: %d):"
|
||||
"respawning...",
|
||||
(int) child_exit_code);
|
||||
sleep(1); /* don't respawn too fast */
|
||||
goto spawn;
|
||||
}
|
||||
|
||||
/* Delete IM-angel pid file. */
|
||||
my_delete(Options::angel_pid_file_name, MYF(0));
|
||||
|
||||
/*
|
||||
mysqlmanager successfully exited, let's silently evaporate
|
||||
If we return to main we fall into the manager() function, so let's
|
||||
|
|
|
@ -53,6 +53,7 @@ Thread_info::Thread_info(pthread_t thread_id_arg) :
|
|||
Thread_registry::Thread_registry() :
|
||||
shutdown_in_progress(false)
|
||||
,sigwait_thread_pid(pthread_self())
|
||||
,error_status(FALSE)
|
||||
{
|
||||
pthread_mutex_init(&LOCK_thread_registry, 0);
|
||||
pthread_cond_init(&COND_thread_registry_is_empty, 0);
|
||||
|
@ -243,3 +244,23 @@ void Thread_registry::request_shutdown()
|
|||
{
|
||||
pthread_kill(sigwait_thread_pid, SIGTERM);
|
||||
}
|
||||
|
||||
|
||||
int Thread_registry::get_error_status()
|
||||
{
|
||||
int ret_error_status;
|
||||
|
||||
pthread_mutex_lock(&LOCK_thread_registry);
|
||||
ret_error_status= error_status;
|
||||
pthread_mutex_unlock(&LOCK_thread_registry);
|
||||
|
||||
return ret_error_status;
|
||||
}
|
||||
|
||||
|
||||
void Thread_registry::set_error_status()
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_thread_registry);
|
||||
error_status= TRUE;
|
||||
pthread_mutex_unlock(&LOCK_thread_registry);
|
||||
}
|
||||
|
|
|
@ -97,12 +97,16 @@ public:
|
|||
pthread_mutex_t *mutex);
|
||||
int cond_timedwait(Thread_info *info, pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex, struct timespec *wait_time);
|
||||
int get_error_status();
|
||||
void set_error_status();
|
||||
|
||||
private:
|
||||
Thread_info head;
|
||||
bool shutdown_in_progress;
|
||||
pthread_mutex_t LOCK_thread_registry;
|
||||
pthread_cond_t COND_thread_registry_is_empty;
|
||||
pthread_t sigwait_thread_pid;
|
||||
bool error_status;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -206,7 +206,7 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
|
|||
digits= (uint) (pos-str);
|
||||
start_loop= 0; /* Start of scan loop */
|
||||
date_len[format_position[0]]= 0; /* Length of year field */
|
||||
if (pos == end)
|
||||
if (pos == end || *pos == '.')
|
||||
{
|
||||
/* Found date in internal format (only numbers like YYYYMMDD) */
|
||||
year_length= (digits == 4 || digits == 8 || digits >= 14) ? 4 : 2;
|
||||
|
|
23
sql/field.cc
23
sql/field.cc
|
@ -5319,27 +5319,30 @@ void Field_date::sql_type(String &res) const
|
|||
int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs)
|
||||
{
|
||||
TIME l_time;
|
||||
long tmp;
|
||||
int error;
|
||||
THD *thd= table ? table->in_use : current_thd;
|
||||
if (str_to_datetime(from, len, &l_time,
|
||||
(TIME_FUZZY_DATE |
|
||||
(thd->variables.sql_mode &
|
||||
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
|
||||
MODE_INVALID_DATES))),
|
||||
&error) <= MYSQL_TIMESTAMP_ERROR)
|
||||
enum enum_mysql_timestamp_type ret;
|
||||
if ((ret= str_to_datetime(from, len, &l_time,
|
||||
(TIME_FUZZY_DATE |
|
||||
(thd->variables.sql_mode &
|
||||
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
|
||||
MODE_INVALID_DATES))),
|
||||
&error)) <= MYSQL_TIMESTAMP_ERROR)
|
||||
{
|
||||
tmp= 0L;
|
||||
int3store(ptr,0L);
|
||||
error= 2;
|
||||
}
|
||||
else
|
||||
tmp= l_time.day + l_time.month*32 + l_time.year*16*32;
|
||||
{
|
||||
int3store(ptr, l_time.day + l_time.month*32 + l_time.year*16*32);
|
||||
if(!error && (ret != MYSQL_TIMESTAMP_DATE))
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (error)
|
||||
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
|
||||
from, len, MYSQL_TIMESTAMP_DATE, 1);
|
||||
|
||||
int3store(ptr,tmp);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -793,6 +793,59 @@ int Arg_comparator::compare_e_row()
|
|||
}
|
||||
|
||||
|
||||
void Item_func_truth::fix_length_and_dec()
|
||||
{
|
||||
maybe_null= 0;
|
||||
null_value= 0;
|
||||
decimals= 0;
|
||||
max_length= 1;
|
||||
}
|
||||
|
||||
|
||||
void Item_func_truth::print(String *str)
|
||||
{
|
||||
str->append('(');
|
||||
args[0]->print(str);
|
||||
str->append(STRING_WITH_LEN(" is "));
|
||||
if (! affirmative)
|
||||
str->append(STRING_WITH_LEN("not "));
|
||||
if (value)
|
||||
str->append(STRING_WITH_LEN("true"));
|
||||
else
|
||||
str->append(STRING_WITH_LEN("false"));
|
||||
str->append(')');
|
||||
}
|
||||
|
||||
|
||||
bool Item_func_truth::val_bool()
|
||||
{
|
||||
bool val= args[0]->val_bool();
|
||||
if (args[0]->null_value)
|
||||
{
|
||||
/*
|
||||
NULL val IS {TRUE, FALSE} --> FALSE
|
||||
NULL val IS NOT {TRUE, FALSE} --> TRUE
|
||||
*/
|
||||
return (! affirmative);
|
||||
}
|
||||
|
||||
if (affirmative)
|
||||
{
|
||||
/* {TRUE, FALSE} val IS {TRUE, FALSE} value */
|
||||
return (val == value);
|
||||
}
|
||||
|
||||
/* {TRUE, FALSE} val IS NOT {TRUE, FALSE} value */
|
||||
return (val != value);
|
||||
}
|
||||
|
||||
|
||||
longlong Item_func_truth::val_int()
|
||||
{
|
||||
return (val_bool() ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
|
||||
{
|
||||
if (!args[0]->fixed && args[0]->fix_fields(thd, args) ||
|
||||
|
@ -1529,6 +1582,7 @@ Item_func_if::fix_length_and_dec()
|
|||
{
|
||||
maybe_null=args[1]->maybe_null || args[2]->maybe_null;
|
||||
decimals= max(args[1]->decimals, args[2]->decimals);
|
||||
unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
|
||||
|
||||
enum Item_result arg1_type=args[1]->result_type();
|
||||
enum Item_result arg2_type=args[2]->result_type();
|
||||
|
@ -1558,12 +1612,20 @@ Item_func_if::fix_length_and_dec()
|
|||
collation.set(&my_charset_bin); // Number
|
||||
}
|
||||
}
|
||||
max_length=
|
||||
(cached_result_type == DECIMAL_RESULT || cached_result_type == INT_RESULT) ?
|
||||
(max(args[1]->max_length - args[1]->decimals,
|
||||
args[2]->max_length - args[2]->decimals) + decimals +
|
||||
(unsigned_flag ? 0 : 1) ) :
|
||||
max(args[1]->max_length, args[2]->max_length);
|
||||
|
||||
if ((cached_result_type == DECIMAL_RESULT )
|
||||
|| (cached_result_type == INT_RESULT))
|
||||
{
|
||||
int len1= args[1]->max_length - args[1]->decimals
|
||||
- (args[1]->unsigned_flag ? 0 : 1);
|
||||
|
||||
int len2= args[2]->max_length - args[2]->decimals
|
||||
- (args[2]->unsigned_flag ? 0 : 1);
|
||||
|
||||
max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
|
||||
}
|
||||
else
|
||||
max_length= max(args[1]->max_length, args[2]->max_length);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -101,6 +101,92 @@ public:
|
|||
uint decimal_precision() const { return 1; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Abstract Item class, to represent <code>X IS [NOT] (TRUE | FALSE)</code>
|
||||
boolean predicates.
|
||||
*/
|
||||
|
||||
class Item_func_truth : public Item_bool_func
|
||||
{
|
||||
public:
|
||||
virtual bool val_bool();
|
||||
virtual longlong val_int();
|
||||
virtual void fix_length_and_dec();
|
||||
virtual void print(String *str);
|
||||
|
||||
protected:
|
||||
Item_func_truth(Item *a, bool a_value, bool a_affirmative)
|
||||
: Item_bool_func(a), value(a_value), affirmative(a_affirmative)
|
||||
{}
|
||||
|
||||
~Item_func_truth()
|
||||
{}
|
||||
private:
|
||||
/**
|
||||
True for <code>X IS [NOT] TRUE</code>,
|
||||
false for <code>X IS [NOT] FALSE</code> predicates.
|
||||
*/
|
||||
const bool value;
|
||||
/**
|
||||
True for <code>X IS Y</code>, false for <code>X IS NOT Y</code> predicates.
|
||||
*/
|
||||
const bool affirmative;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
This Item represents a <code>X IS TRUE</code> boolean predicate.
|
||||
*/
|
||||
|
||||
class Item_func_istrue : public Item_func_truth
|
||||
{
|
||||
public:
|
||||
Item_func_istrue(Item *a) : Item_func_truth(a, true, true) {}
|
||||
~Item_func_istrue() {}
|
||||
virtual const char* func_name() const { return "istrue"; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
This Item represents a <code>X IS NOT TRUE</code> boolean predicate.
|
||||
*/
|
||||
|
||||
class Item_func_isnottrue : public Item_func_truth
|
||||
{
|
||||
public:
|
||||
Item_func_isnottrue(Item *a) : Item_func_truth(a, true, false) {}
|
||||
~Item_func_isnottrue() {}
|
||||
virtual const char* func_name() const { return "isnottrue"; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
This Item represents a <code>X IS FALSE</code> boolean predicate.
|
||||
*/
|
||||
|
||||
class Item_func_isfalse : public Item_func_truth
|
||||
{
|
||||
public:
|
||||
Item_func_isfalse(Item *a) : Item_func_truth(a, false, true) {}
|
||||
~Item_func_isfalse() {}
|
||||
virtual const char* func_name() const { return "isfalse"; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
This Item represents a <code>X IS NOT FALSE</code> boolean predicate.
|
||||
*/
|
||||
|
||||
class Item_func_isnotfalse : public Item_func_truth
|
||||
{
|
||||
public:
|
||||
Item_func_isnotfalse(Item *a) : Item_func_truth(a, false, false) {}
|
||||
~Item_func_isnotfalse() {}
|
||||
virtual const char* func_name() const { return "isnotfalse"; }
|
||||
};
|
||||
|
||||
|
||||
class Item_cache;
|
||||
#define UNKNOWN ((my_bool)-1)
|
||||
|
||||
|
|
|
@ -3459,6 +3459,7 @@ longlong Item_func_benchmark::val_int()
|
|||
DBUG_ASSERT(fixed == 1);
|
||||
char buff[MAX_FIELD_WIDTH];
|
||||
String tmp(buff,sizeof(buff), &my_charset_bin);
|
||||
my_decimal tmp_decimal;
|
||||
THD *thd=current_thd;
|
||||
|
||||
for (ulong loop=0 ; loop < loop_count && !thd->killed; loop++)
|
||||
|
@ -3473,6 +3474,9 @@ longlong Item_func_benchmark::val_int()
|
|||
case STRING_RESULT:
|
||||
(void) args[0]->val_str(&tmp);
|
||||
break;
|
||||
case DECIMAL_RESULT:
|
||||
(void) args[0]->val_decimal(&tmp_decimal);
|
||||
break;
|
||||
case ROW_RESULT:
|
||||
default:
|
||||
// This case should never be chosen
|
||||
|
|
|
@ -35,6 +35,7 @@ void Item_geometry_func::fix_length_and_dec()
|
|||
collation.set(&my_charset_bin);
|
||||
decimals=0;
|
||||
max_length=MAX_BLOB_WIDTH;
|
||||
maybe_null= 1;
|
||||
}
|
||||
|
||||
int Item_geometry_func::get_geometry_type() const
|
||||
|
@ -63,11 +64,8 @@ String *Item_func_geometry_from_text::val_str(String *str)
|
|||
return 0;
|
||||
str->length(0);
|
||||
str->q_append(srid);
|
||||
if (!Geometry::create_from_wkt(&buffer, &trs, str, 0))
|
||||
/* We shouldn't return NULL here as NULL is a legal spatial object */
|
||||
/* Geometry::bad_spatial_data will produce error message beeing stored*/
|
||||
/* in GEOMETRY field */
|
||||
return &Geometry::bad_geometry_data;
|
||||
if ((null_value= !Geometry::create_from_wkt(&buffer, &trs, str, 0)))
|
||||
return 0;
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -121,6 +119,7 @@ String *Item_func_as_wkt::val_str(String *str)
|
|||
void Item_func_as_wkt::fix_length_and_dec()
|
||||
{
|
||||
max_length=MAX_BLOB_WIDTH;
|
||||
maybe_null= 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -386,7 +385,8 @@ String *Item_func_spatial_collection::val_str(String *str)
|
|||
for (i= 0; i < arg_count; ++i)
|
||||
{
|
||||
String *res= args[i]->val_str(&arg_value);
|
||||
if (args[i]->null_value)
|
||||
uint32 len;
|
||||
if (args[i]->null_value || ((len= res->length()) < WKB_HEADER_SIZE))
|
||||
goto err;
|
||||
|
||||
if (coll_type == Geometry::wkb_geometrycollection)
|
||||
|
@ -395,13 +395,12 @@ String *Item_func_spatial_collection::val_str(String *str)
|
|||
In the case of GeometryCollection we don't need any checkings
|
||||
for item types, so just copy them into target collection
|
||||
*/
|
||||
if (str->append(res->ptr(), res->length(), (uint32) 512))
|
||||
if (str->append(res->ptr(), len, (uint32) 512))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
enum Geometry::wkbType wkb_type;
|
||||
uint32 len=res->length();
|
||||
const char *data= res->ptr() + 1;
|
||||
|
||||
/*
|
||||
|
@ -409,8 +408,6 @@ String *Item_func_spatial_collection::val_str(String *str)
|
|||
are of specific type, let's do this checking now
|
||||
*/
|
||||
|
||||
if (len < 5)
|
||||
goto err;
|
||||
wkb_type= (Geometry::wkbType) uint4korr(data);
|
||||
data+= 4;
|
||||
len-= 5;
|
||||
|
@ -532,9 +529,13 @@ longlong Item_func_spatial_rel::val_int()
|
|||
longlong Item_func_isempty::val_int()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
String tmp;
|
||||
null_value=0;
|
||||
return args[0]->null_value ? 1 : 0;
|
||||
String tmp;
|
||||
String *swkb= args[0]->val_str(&tmp);
|
||||
Geometry_buffer buffer;
|
||||
|
||||
null_value= args[0]->null_value ||
|
||||
!(Geometry::construct(&buffer, swkb->ptr(), swkb->length()));
|
||||
return null_value ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -542,10 +543,11 @@ longlong Item_func_issimple::val_int()
|
|||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
String tmp;
|
||||
String *wkb=args[0]->val_str(&tmp);
|
||||
|
||||
if ((null_value= (!wkb || args[0]->null_value)))
|
||||
return 0;
|
||||
String *swkb= args[0]->val_str(&tmp);
|
||||
Geometry_buffer buffer;
|
||||
|
||||
null_value= args[0]->null_value ||
|
||||
!(Geometry::construct(&buffer, swkb->ptr(), swkb->length()));
|
||||
/* TODO: Ramil or Holyfoot, add real IsSimple calculation */
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ public:
|
|||
enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; }
|
||||
Field *tmp_table_field(TABLE *t_arg);
|
||||
virtual int get_geometry_type() const;
|
||||
bool is_null() { (void) val_int(); return null_value; }
|
||||
};
|
||||
|
||||
class Item_func_geometry_from_text: public Item_geometry_func
|
||||
|
@ -81,6 +82,7 @@ public:
|
|||
void fix_length_and_dec()
|
||||
{
|
||||
max_length=20; // "GeometryCollection" is the most long
|
||||
maybe_null= 1;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -225,6 +227,8 @@ public:
|
|||
}
|
||||
}
|
||||
void print(String *str) { Item_func::print(str); }
|
||||
void fix_length_and_dec() { maybe_null= 1; }
|
||||
bool is_null() { (void) val_int(); return null_value; }
|
||||
};
|
||||
|
||||
class Item_func_isempty: public Item_bool_func
|
||||
|
@ -234,6 +238,7 @@ public:
|
|||
longlong val_int();
|
||||
optimize_type select_optimize() const { return OPTIMIZE_NONE; }
|
||||
const char *func_name() const { return "isempty"; }
|
||||
void fix_length_and_dec() { maybe_null= 1; }
|
||||
};
|
||||
|
||||
class Item_func_issimple: public Item_bool_func
|
||||
|
@ -243,6 +248,7 @@ public:
|
|||
longlong val_int();
|
||||
optimize_type select_optimize() const { return OPTIMIZE_NONE; }
|
||||
const char *func_name() const { return "issimple"; }
|
||||
void fix_length_and_dec() { maybe_null= 1; }
|
||||
};
|
||||
|
||||
class Item_func_isclosed: public Item_bool_func
|
||||
|
@ -252,6 +258,7 @@ public:
|
|||
longlong val_int();
|
||||
optimize_type select_optimize() const { return OPTIMIZE_NONE; }
|
||||
const char *func_name() const { return "isclosed"; }
|
||||
void fix_length_and_dec() { maybe_null= 1; }
|
||||
};
|
||||
|
||||
class Item_func_dimension: public Item_int_func
|
||||
|
@ -261,7 +268,7 @@ public:
|
|||
Item_func_dimension(Item *a): Item_int_func(a) {}
|
||||
longlong val_int();
|
||||
const char *func_name() const { return "dimension"; }
|
||||
void fix_length_and_dec() { max_length=10; }
|
||||
void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
|
||||
};
|
||||
|
||||
class Item_func_x: public Item_real_func
|
||||
|
@ -271,6 +278,11 @@ public:
|
|||
Item_func_x(Item *a): Item_real_func(a) {}
|
||||
double val_real();
|
||||
const char *func_name() const { return "x"; }
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
Item_real_func::fix_length_and_dec();
|
||||
maybe_null= 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -281,6 +293,11 @@ public:
|
|||
Item_func_y(Item *a): Item_real_func(a) {}
|
||||
double val_real();
|
||||
const char *func_name() const { return "y"; }
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
Item_real_func::fix_length_and_dec();
|
||||
maybe_null= 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -291,7 +308,7 @@ public:
|
|||
Item_func_numgeometries(Item *a): Item_int_func(a) {}
|
||||
longlong val_int();
|
||||
const char *func_name() const { return "numgeometries"; }
|
||||
void fix_length_and_dec() { max_length=10; }
|
||||
void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -302,7 +319,7 @@ public:
|
|||
Item_func_numinteriorring(Item *a): Item_int_func(a) {}
|
||||
longlong val_int();
|
||||
const char *func_name() const { return "numinteriorrings"; }
|
||||
void fix_length_and_dec() { max_length=10; }
|
||||
void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -313,7 +330,7 @@ public:
|
|||
Item_func_numpoints(Item *a): Item_int_func(a) {}
|
||||
longlong val_int();
|
||||
const char *func_name() const { return "numpoints"; }
|
||||
void fix_length_and_dec() { max_length=10; }
|
||||
void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -324,6 +341,11 @@ public:
|
|||
Item_func_area(Item *a): Item_real_func(a) {}
|
||||
double val_real();
|
||||
const char *func_name() const { return "area"; }
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
Item_real_func::fix_length_and_dec();
|
||||
maybe_null= 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -334,6 +356,11 @@ public:
|
|||
Item_func_glength(Item *a): Item_real_func(a) {}
|
||||
double val_real();
|
||||
const char *func_name() const { return "glength"; }
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
Item_real_func::fix_length_and_dec();
|
||||
maybe_null= 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -344,7 +371,7 @@ public:
|
|||
Item_func_srid(Item *a): Item_int_func(a) {}
|
||||
longlong val_int();
|
||||
const char *func_name() const { return "srid"; }
|
||||
void fix_length_and_dec() { max_length= 10; }
|
||||
void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
|
||||
};
|
||||
|
||||
#define GEOM_NEW(obj_constructor) new obj_constructor
|
||||
|
|
|
@ -51,6 +51,10 @@ Item_subselect::Item_subselect():
|
|||
void Item_subselect::init(st_select_lex *select_lex,
|
||||
select_subselect *result)
|
||||
{
|
||||
/*
|
||||
Please see Item_singlerow_subselect::invalidate_and_restore_select_lex(),
|
||||
which depends on alterations to the parse tree implemented here.
|
||||
*/
|
||||
|
||||
DBUG_ENTER("Item_subselect::init");
|
||||
DBUG_PRINT("enter", ("select_lex: 0x%lx", (long) select_lex));
|
||||
|
@ -91,6 +95,12 @@ void Item_subselect::init(st_select_lex *select_lex,
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
st_select_lex *
|
||||
Item_subselect::get_select_lex()
|
||||
{
|
||||
return unit->first_select();
|
||||
}
|
||||
|
||||
void Item_subselect::cleanup()
|
||||
{
|
||||
DBUG_ENTER("Item_subselect::cleanup");
|
||||
|
@ -268,6 +278,26 @@ Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex)
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
st_select_lex *
|
||||
Item_singlerow_subselect::invalidate_and_restore_select_lex()
|
||||
{
|
||||
DBUG_ENTER("Item_singlerow_subselect::invalidate_and_restore_select_lex");
|
||||
st_select_lex *result= get_select_lex();
|
||||
|
||||
DBUG_ASSERT(result);
|
||||
|
||||
/*
|
||||
This code restore the parse tree in it's state before the execution of
|
||||
Item_singlerow_subselect::Item_singlerow_subselect(),
|
||||
and in particular decouples this object from the SELECT_LEX,
|
||||
so that the SELECT_LEX can be used with a different flavor
|
||||
or Item_subselect instead, as part of query rewriting.
|
||||
*/
|
||||
unit->item= NULL;
|
||||
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
Item_maxmin_subselect::Item_maxmin_subselect(THD *thd_param,
|
||||
Item_subselect *parent,
|
||||
st_select_lex *select_lex,
|
||||
|
|
|
@ -126,6 +126,12 @@ public:
|
|||
virtual void reset_value_registration() {}
|
||||
enum_parsing_place place() { return parsing_place; }
|
||||
|
||||
/**
|
||||
Get the SELECT_LEX structure associated with this Item.
|
||||
@return the SELECT_LEX structure associated with this Item
|
||||
*/
|
||||
st_select_lex* get_select_lex();
|
||||
|
||||
friend class select_subselect;
|
||||
friend class Item_in_optimizer;
|
||||
friend bool Item_field::fix_fields(THD *, Item **);
|
||||
|
@ -169,6 +175,20 @@ public:
|
|||
bool null_inside();
|
||||
void bring_value();
|
||||
|
||||
/**
|
||||
This method is used to implement a special case of semantic tree
|
||||
rewriting, mandated by a SQL:2003 exception in the specification.
|
||||
The only caller of this method is handle_sql2003_note184_exception(),
|
||||
see the code there for more details.
|
||||
Note that this method breaks the object internal integrity, by
|
||||
removing it's association with the corresponding SELECT_LEX,
|
||||
making this object orphan from the parse tree.
|
||||
No other method, beside the destructor, should be called on this
|
||||
object, as it is now invalid.
|
||||
@return the SELECT_LEX structure that was given in the constructor.
|
||||
*/
|
||||
st_select_lex* invalidate_and_restore_select_lex();
|
||||
|
||||
friend class select_singlerow_subselect;
|
||||
};
|
||||
|
||||
|
|
|
@ -566,7 +566,7 @@ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
|
|||
|
||||
for (; haystack; haystack= haystack->next_global)
|
||||
{
|
||||
if (haystack->placeholder() || haystack->schema_table)
|
||||
if (haystack->placeholder())
|
||||
continue;
|
||||
table2= haystack->table;
|
||||
if (table2->s->tmp_table == TMP_TABLE)
|
||||
|
|
|
@ -3114,8 +3114,8 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
|
|||
|
||||
ex.skip_lines = skip_lines;
|
||||
List<Item> field_list;
|
||||
thd->main_lex.select_lex.context.resolve_in_table_list_only(&tables);
|
||||
set_fields(tables.db, field_list, &thd->main_lex.select_lex.context);
|
||||
thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
|
||||
set_fields(tables.db, field_list, &thd->lex->select_lex.context);
|
||||
thd->variables.pseudo_thread_id= thread_id;
|
||||
if (net)
|
||||
{
|
||||
|
|
|
@ -1600,18 +1600,6 @@ static void network_init(void)
|
|||
|
||||
#endif /*!EMBEDDED_LIBRARY*/
|
||||
|
||||
void MYSQLerror(const char *s)
|
||||
{
|
||||
THD *thd=current_thd;
|
||||
char *yytext= (char*) thd->lex->tok_start;
|
||||
/* "parse error" changed into "syntax error" between bison 1.75 and 1.875 */
|
||||
if (strcmp(s,"parse error") == 0 || strcmp(s,"syntax error") == 0)
|
||||
s=ER(ER_SYNTAX_ERROR);
|
||||
my_printf_error(ER_PARSE_ERROR, ER(ER_PARSE_ERROR), MYF(0), s,
|
||||
(yytext ? (char*) yytext : ""),
|
||||
thd->lex->yylineno);
|
||||
}
|
||||
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
/*
|
||||
|
@ -2448,6 +2436,14 @@ static int my_message_sql(uint error, const char *str, myf MyFlags)
|
|||
*/
|
||||
if ((thd= current_thd))
|
||||
{
|
||||
/*
|
||||
TODO: There are two exceptions mechanism (THD and sp_rcontext),
|
||||
this could be improved by having a common stack of handlers.
|
||||
*/
|
||||
if (thd->handle_error(error,
|
||||
MYSQL_ERROR::WARN_LEVEL_ERROR))
|
||||
DBUG_RETURN(0);
|
||||
|
||||
if (thd->spcont &&
|
||||
thd->spcont->handle_error(error, MYSQL_ERROR::WARN_LEVEL_ERROR, thd))
|
||||
{
|
||||
|
|
|
@ -36,6 +36,7 @@ Item_result
|
|||
sp_map_result_type(enum enum_field_types type)
|
||||
{
|
||||
switch (type) {
|
||||
case MYSQL_TYPE_BIT:
|
||||
case MYSQL_TYPE_TINY:
|
||||
case MYSQL_TYPE_SHORT:
|
||||
case MYSQL_TYPE_LONG:
|
||||
|
@ -58,6 +59,7 @@ Item::Type
|
|||
sp_map_item_type(enum enum_field_types type)
|
||||
{
|
||||
switch (type) {
|
||||
case MYSQL_TYPE_BIT:
|
||||
case MYSQL_TYPE_TINY:
|
||||
case MYSQL_TYPE_SHORT:
|
||||
case MYSQL_TYPE_LONG:
|
||||
|
@ -2388,16 +2390,11 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
|
|||
m_lex->mark_as_requiring_prelocking(lex_query_tables_own_last);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
reinit_stmt_before_use(thd, m_lex);
|
||||
/*
|
||||
If requested check whenever we have access to tables in LEX's table list
|
||||
and open and lock them before executing instructtions core function.
|
||||
*/
|
||||
if (open_tables &&
|
||||
(check_table_access(thd, SELECT_ACL, m_lex->query_tables, 0) ||
|
||||
open_and_lock_tables(thd, m_lex->query_tables)))
|
||||
res= -1;
|
||||
|
||||
if (open_tables)
|
||||
res= instr->exec_open_and_lock_tables(thd, m_lex->query_tables, nextp);
|
||||
|
||||
if (!res)
|
||||
res= instr->exec_core(thd, nextp);
|
||||
|
@ -2446,6 +2443,33 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
|
|||
sp_instr class functions
|
||||
*/
|
||||
|
||||
int sp_instr::exec_open_and_lock_tables(THD *thd, TABLE_LIST *tables,
|
||||
uint *nextp)
|
||||
{
|
||||
int result;
|
||||
|
||||
/*
|
||||
Check whenever we have access to tables for this statement
|
||||
and open and lock them before executing instructions core function.
|
||||
*/
|
||||
if (check_table_access(thd, SELECT_ACL, tables, 0)
|
||||
|| open_and_lock_tables(thd, tables))
|
||||
{
|
||||
get_cont_dest(nextp);
|
||||
result= -1;
|
||||
}
|
||||
else
|
||||
result= 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void sp_instr::get_cont_dest(uint *nextp)
|
||||
{
|
||||
*nextp= m_ip+1;
|
||||
}
|
||||
|
||||
|
||||
int sp_instr::exec_core(THD *thd, uint *nextp)
|
||||
{
|
||||
DBUG_ASSERT(0);
|
||||
|
@ -2626,6 +2650,15 @@ sp_instr_set_trigger_field::print(String *str)
|
|||
value->print(str);
|
||||
}
|
||||
|
||||
/*
|
||||
sp_instr_opt_meta
|
||||
*/
|
||||
|
||||
void sp_instr_opt_meta::get_cont_dest(uint *nextp)
|
||||
{
|
||||
*nextp= m_cont_dest;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
sp_instr_jump class functions
|
||||
|
|
|
@ -458,6 +458,28 @@ public:
|
|||
|
||||
virtual int execute(THD *thd, uint *nextp) = 0;
|
||||
|
||||
/**
|
||||
Execute <code>open_and_lock_tables()</code> for this statement.
|
||||
Open and lock the tables used by this statement, as a pre-requisite
|
||||
to execute the core logic of this instruction with
|
||||
<code>exec_core()</code>.
|
||||
If this statement fails, the next instruction to execute is also returned.
|
||||
This is useful when a user defined SQL continue handler needs to be
|
||||
executed.
|
||||
@param thd the current thread
|
||||
@param tables the list of tables to open and lock
|
||||
@param nextp the continuation instruction, returned to the caller if this
|
||||
method fails.
|
||||
@return zero on success, non zero on failure.
|
||||
*/
|
||||
int exec_open_and_lock_tables(THD *thd, TABLE_LIST *tables, uint *nextp);
|
||||
|
||||
/**
|
||||
Get the continuation destination of this instruction.
|
||||
@param nextp the continuation destination (output)
|
||||
*/
|
||||
virtual void get_cont_dest(uint *nextp);
|
||||
|
||||
/*
|
||||
Execute core function of instruction after all preparations (e.g.
|
||||
setting of proper LEX, saving part of the thread context have been
|
||||
|
@ -722,6 +744,8 @@ public:
|
|||
virtual void set_destination(uint old_dest, uint new_dest)
|
||||
= 0;
|
||||
|
||||
virtual void get_cont_dest(uint *nextp);
|
||||
|
||||
protected:
|
||||
|
||||
sp_instr *m_optdest; // Used during optimization
|
||||
|
|
|
@ -213,23 +213,24 @@ static uint32 wkb_get_uint(const char *ptr, Geometry::wkbByteOrder bo)
|
|||
}
|
||||
|
||||
|
||||
int Geometry::create_from_wkb(Geometry_buffer *buffer,
|
||||
const char *wkb, uint32 len, String *res)
|
||||
Geometry *Geometry::create_from_wkb(Geometry_buffer *buffer,
|
||||
const char *wkb, uint32 len, String *res)
|
||||
{
|
||||
uint32 geom_type;
|
||||
Geometry *geom;
|
||||
|
||||
if (len < WKB_HEADER_SIZE)
|
||||
return 1;
|
||||
return NULL;
|
||||
geom_type= wkb_get_uint(wkb+1, (wkbByteOrder)wkb[0]);
|
||||
if (!(geom= create_by_typeid(buffer, (int) geom_type)) ||
|
||||
res->reserve(WKB_HEADER_SIZE, 512))
|
||||
return 1;
|
||||
return NULL;
|
||||
|
||||
res->q_append((char) wkb_ndr);
|
||||
res->q_append(geom_type);
|
||||
return geom->init_from_wkb(wkb+WKB_HEADER_SIZE, len - WKB_HEADER_SIZE,
|
||||
(wkbByteOrder) wkb[0], res);
|
||||
|
||||
return geom->init_from_wkb(wkb + WKB_HEADER_SIZE, len - WKB_HEADER_SIZE,
|
||||
(wkbByteOrder) wkb[0], res) ? geom : NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -246,8 +246,8 @@ public:
|
|||
static Geometry *create_from_wkt(Geometry_buffer *buffer,
|
||||
Gis_read_stream *trs, String *wkt,
|
||||
bool init_stream=1);
|
||||
static int create_from_wkb(Geometry_buffer *buffer,
|
||||
const char *wkb, uint32 len, String *res);
|
||||
static Geometry *create_from_wkb(Geometry_buffer *buffer, const char *wkb,
|
||||
uint32 len, String *res);
|
||||
int as_wkt(String *wkt, const char **end)
|
||||
{
|
||||
uint32 len= get_class_info()->m_name.length;
|
||||
|
|
216
sql/sql_base.cc
216
sql/sql_base.cc
|
@ -28,6 +28,59 @@
|
|||
#include <io.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
This internal handler is used to trap internally
|
||||
errors that can occur when executing open table
|
||||
during the prelocking phase.
|
||||
*/
|
||||
class Prelock_error_handler : public Internal_error_handler
|
||||
{
|
||||
public:
|
||||
Prelock_error_handler()
|
||||
: m_handled_errors(0), m_unhandled_errors(0)
|
||||
{}
|
||||
|
||||
virtual ~Prelock_error_handler() {}
|
||||
|
||||
virtual bool handle_error(uint sql_errno,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
THD *thd);
|
||||
|
||||
bool safely_trapped_errors();
|
||||
|
||||
private:
|
||||
int m_handled_errors;
|
||||
int m_unhandled_errors;
|
||||
};
|
||||
|
||||
|
||||
bool
|
||||
Prelock_error_handler::handle_error(uint sql_errno,
|
||||
MYSQL_ERROR::enum_warning_level /* level */,
|
||||
THD * /* thd */)
|
||||
{
|
||||
if (sql_errno == ER_NO_SUCH_TABLE)
|
||||
{
|
||||
m_handled_errors++;
|
||||
return TRUE; // 'TRUE', as per coding style
|
||||
}
|
||||
|
||||
m_unhandled_errors++;
|
||||
return FALSE; // 'FALSE', as per coding style
|
||||
}
|
||||
|
||||
|
||||
bool Prelock_error_handler::safely_trapped_errors()
|
||||
{
|
||||
/*
|
||||
If m_unhandled_errors != 0, something else, unanticipated, happened,
|
||||
so the error is not trapped but returned to the caller.
|
||||
Multiple ER_NO_SUCH_TABLE can be raised in case of views.
|
||||
*/
|
||||
return ((m_handled_errors > 0) && (m_unhandled_errors == 0));
|
||||
}
|
||||
|
||||
|
||||
TABLE *unused_tables; /* Used by mysql_test */
|
||||
HASH open_cache; /* Used by mysql_test */
|
||||
|
||||
|
@ -1210,6 +1263,13 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
int4store(key + key_length, thd->server_id);
|
||||
int4store(key + key_length + 4, thd->variables.pseudo_thread_id);
|
||||
|
||||
/*
|
||||
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)
|
||||
{
|
||||
for (table= thd->temporary_tables; table ; table=table->next)
|
||||
|
@ -1218,6 +1278,12 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
!memcmp(table->s->table_cache_key, key,
|
||||
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 ||
|
||||
thd->prelocked_mode && table->query_id)
|
||||
{
|
||||
|
@ -1233,6 +1299,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) &&
|
||||
(thd->locked_tables || thd->prelocked_mode))
|
||||
{ // Using table locks
|
||||
|
@ -1304,7 +1377,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
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,
|
||||
real fix will be made after definition cache will be made)
|
||||
*/
|
||||
|
@ -1334,12 +1407,39 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||
}
|
||||
}
|
||||
my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias);
|
||||
if ((thd->locked_tables) && (thd->locked_tables->lock_count > 0))
|
||||
my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias);
|
||||
else
|
||||
my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias);
|
||||
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));
|
||||
|
||||
/*
|
||||
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)
|
||||
thd->version=refresh_version;
|
||||
else if ((thd->version != refresh_version) &&
|
||||
|
@ -1356,12 +1456,39 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
if (thd->handler_tables)
|
||||
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,
|
||||
&state);
|
||||
table && table->in_use ;
|
||||
table= (TABLE*) hash_next(&open_cache, (byte*) key, key_length,
|
||||
&state))
|
||||
{
|
||||
/*
|
||||
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)
|
||||
{
|
||||
DBUG_PRINT("note",
|
||||
|
@ -1375,16 +1502,35 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
}
|
||||
|
||||
/*
|
||||
There is a refresh in progress for this table
|
||||
Wait until the table is freed or the thread is killed.
|
||||
Back off, part 1: mark the table as "unused" for the
|
||||
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);
|
||||
/*
|
||||
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)
|
||||
{
|
||||
wait_for_refresh(thd);
|
||||
/* wait_for_refresh will unlock LOCK_open for us */
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
*refresh=1;
|
||||
DBUG_RETURN(0);
|
||||
|
@ -1392,6 +1538,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
}
|
||||
if (table)
|
||||
{
|
||||
/* Unlink the table from "unused_tables" list. */
|
||||
if (table == unused_tables)
|
||||
{ // First unused
|
||||
unused_tables=unused_tables->next; // Remove from link
|
||||
|
@ -1404,6 +1551,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Insert a new TABLE instance into the open cache */
|
||||
TABLE_SHARE *share;
|
||||
int error;
|
||||
/* Free cache if too big */
|
||||
|
@ -2092,6 +2240,8 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
|||
MEM_ROOT new_frm_mem;
|
||||
/* Also used for indicating that prelocking is need */
|
||||
TABLE_LIST **query_tables_last_own;
|
||||
bool safe_to_ignore_table;
|
||||
|
||||
DBUG_ENTER("open_tables");
|
||||
/*
|
||||
temporary mem_root for new .frm parsing.
|
||||
|
@ -2145,8 +2295,13 @@ 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)
|
||||
{
|
||||
safe_to_ignore_table= FALSE; // 'FALSE', as per coding style
|
||||
/*
|
||||
Ignore placeholders for derived tables. After derived tables
|
||||
processing, link to created temporary table will be put here.
|
||||
|
@ -2159,6 +2314,12 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
|||
goto process_view_routines;
|
||||
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 (!mysql_schema_table(thd, thd->lex, tables))
|
||||
|
@ -2166,9 +2327,32 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
|||
DBUG_RETURN(-1);
|
||||
}
|
||||
(*counter)++;
|
||||
|
||||
if (!tables->table &&
|
||||
!(tables->table= open_table(thd, tables, &new_frm_mem, &refresh, flags)))
|
||||
|
||||
/*
|
||||
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->prelocking_placeholder)
|
||||
{
|
||||
/*
|
||||
For the tables added by the pre-locking code, attempt to open
|
||||
the table but fail silently if the table does not exist.
|
||||
The real failure will occur when/if a statement attempts to use
|
||||
that table.
|
||||
*/
|
||||
Prelock_error_handler prelock_handler;
|
||||
thd->push_internal_handler(& prelock_handler);
|
||||
tables->table= open_table(thd, tables, &new_frm_mem, &refresh, flags);
|
||||
thd->pop_internal_handler();
|
||||
safe_to_ignore_table= prelock_handler.safely_trapped_errors();
|
||||
}
|
||||
else
|
||||
tables->table= open_table(thd, tables, &new_frm_mem, &refresh, flags);
|
||||
}
|
||||
|
||||
if (!tables->table)
|
||||
{
|
||||
free_root(&new_frm_mem, MYF(MY_KEEP_PREALLOC));
|
||||
|
||||
|
@ -2219,6 +2403,14 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
|||
close_tables_for_reopen(thd, start);
|
||||
goto restart;
|
||||
}
|
||||
|
||||
if (safe_to_ignore_table)
|
||||
{
|
||||
DBUG_PRINT("info", ("open_table: ignoring table '%s'.'%s'",
|
||||
tables->db, tables->alias));
|
||||
continue;
|
||||
}
|
||||
|
||||
result= -1; // Fatal error
|
||||
break;
|
||||
}
|
||||
|
@ -2273,7 +2465,7 @@ process_view_routines:
|
|||
{
|
||||
/*
|
||||
Serious error during reading stored routines from mysql.proc table.
|
||||
Something's wrong with the table or its contents, and an error has
|
||||
Something is wrong with the table or its contents, and an error has
|
||||
been emitted; we must abort.
|
||||
*/
|
||||
result= -1;
|
||||
|
@ -2522,7 +2714,7 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags)
|
|||
static void mark_real_tables_as_free_for_reuse(TABLE_LIST *table)
|
||||
{
|
||||
for (; table; table= table->next_global)
|
||||
if (!table->placeholder() && !table->schema_table)
|
||||
if (!table->placeholder())
|
||||
table->table->query_id= 0;
|
||||
}
|
||||
|
||||
|
@ -2594,7 +2786,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
|
|||
DBUG_RETURN(-1);
|
||||
for (table= tables; table; table= table->next_global)
|
||||
{
|
||||
if (!table->placeholder() && !table->schema_table)
|
||||
if (!table->placeholder())
|
||||
*(ptr++)= table->table;
|
||||
}
|
||||
|
||||
|
@ -2636,7 +2828,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
|
|||
|
||||
for (table= tables; table != first_not_own; table= table->next_global)
|
||||
{
|
||||
if (!table->placeholder() && !table->schema_table)
|
||||
if (!table->placeholder())
|
||||
{
|
||||
table->table->query_id= thd->query_id;
|
||||
if (check_lock_and_start_stmt(thd, table->table, table->lock_type))
|
||||
|
@ -2663,7 +2855,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
|
|||
TABLE_LIST *first_not_own= thd->lex->first_not_own_table();
|
||||
for (table= tables; table != first_not_own; table= table->next_global)
|
||||
{
|
||||
if (!table->placeholder() && !table->schema_table &&
|
||||
if (!table->placeholder() &&
|
||||
check_lock_and_start_stmt(thd, table->table, table->lock_type))
|
||||
{
|
||||
ha_rollback_stmt(thd);
|
||||
|
|
|
@ -1765,8 +1765,18 @@ void Query_cache::free_cache()
|
|||
{
|
||||
DBUG_ENTER("Query_cache::free_cache");
|
||||
if (query_cache_size > 0)
|
||||
{
|
||||
flush_cache();
|
||||
/*
|
||||
There may be two free_cache() calls in progress, because we
|
||||
release 'structure_guard_mutex' in flush_cache(). When the second
|
||||
flush_cache() wakes up from the wait on 'COND_flush_finished', the
|
||||
first call to free_cache() has done its job. So we have to test
|
||||
'query_cache_size > 0' the second time to see if the cache wasn't
|
||||
reset by other thread, or if it was reset and was re-enabled then.
|
||||
If the cache was reset, then we have nothing to do here.
|
||||
*/
|
||||
if (query_cache_size > 0)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
if (bins[0].free_blocks == 0)
|
||||
{
|
||||
|
@ -1808,6 +1818,12 @@ void Query_cache::free_cache()
|
|||
flush_in_progress flag and releases the lock, so other threads may
|
||||
proceed skipping the cache as if it is disabled. Concurrent
|
||||
flushes are performed in turn.
|
||||
|
||||
After flush_cache() call, the cache is flushed, all the freed
|
||||
memory is accumulated in bin[0], and the 'structure_guard_mutex'
|
||||
is locked. However, since we could release the mutex during
|
||||
execution, the rest of the cache state could have been changed,
|
||||
and should not be relied on.
|
||||
*/
|
||||
|
||||
void Query_cache::flush_cache()
|
||||
|
|
|
@ -166,14 +166,10 @@ Open_tables_state::Open_tables_state(ulong version_arg)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Pass nominal parameters to Statement constructor only to ensure that
|
||||
the destructor works OK in case of error. The main_mem_root will be
|
||||
re-initialized in init().
|
||||
*/
|
||||
|
||||
THD::THD()
|
||||
:Statement(CONVENTIONAL_EXECUTION, 0, ALLOC_ROOT_MIN_BLOCK_SIZE, 0),
|
||||
:Statement(&main_lex, &main_mem_root, CONVENTIONAL_EXECUTION,
|
||||
/* statement id */ 0),
|
||||
Open_tables_state(refresh_version),
|
||||
lock_id(&main_lock_id),
|
||||
user_time(0), in_sub_stmt(0), global_read_lock(0), is_fatal_error(0),
|
||||
|
@ -184,6 +180,12 @@ THD::THD()
|
|||
{
|
||||
ulong tmp;
|
||||
|
||||
/*
|
||||
Pass nominal parameters to init_alloc_root only to ensure that
|
||||
the destructor works OK in case of an error. The main_mem_root
|
||||
will be re-initialized in init_for_queries().
|
||||
*/
|
||||
init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
|
||||
stmt_arena= this;
|
||||
thread_stack= 0;
|
||||
db= 0;
|
||||
|
@ -226,7 +228,9 @@ THD::THD()
|
|||
#endif
|
||||
client_capabilities= 0; // minimalistic client
|
||||
net.last_error[0]=0; // If error on boot
|
||||
#ifdef HAVE_QUERY_CACHE
|
||||
query_cache_init_query(&net); // If error on boot
|
||||
#endif
|
||||
ull=0;
|
||||
system_thread= cleanup_done= abort_on_warning= no_warnings_for_error= 0;
|
||||
peer_port= 0; // For SHOW PROCESSLIST
|
||||
|
@ -275,6 +279,38 @@ THD::THD()
|
|||
substitute_null_with_insert_id = FALSE;
|
||||
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
|
||||
thr_lock_owner_init(&main_lock_id, &lock_info);
|
||||
|
||||
m_internal_handler= NULL;
|
||||
}
|
||||
|
||||
|
||||
void THD::push_internal_handler(Internal_error_handler *handler)
|
||||
{
|
||||
/*
|
||||
TODO: The current implementation is limited to 1 handler at a time only.
|
||||
THD and sp_rcontext need to be modified to use a common handler stack.
|
||||
*/
|
||||
DBUG_ASSERT(m_internal_handler == NULL);
|
||||
m_internal_handler= handler;
|
||||
}
|
||||
|
||||
|
||||
bool THD::handle_error(uint sql_errno,
|
||||
MYSQL_ERROR::enum_warning_level level)
|
||||
{
|
||||
if (m_internal_handler)
|
||||
{
|
||||
return m_internal_handler->handle_error(sql_errno, level, this);
|
||||
}
|
||||
|
||||
return FALSE; // 'FALSE', as per coding style
|
||||
}
|
||||
|
||||
|
||||
void THD::pop_internal_handler()
|
||||
{
|
||||
DBUG_ASSERT(m_internal_handler != NULL);
|
||||
m_internal_handler= NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -319,6 +355,7 @@ void THD::init(void)
|
|||
|
||||
void THD::init_for_queries()
|
||||
{
|
||||
set_time();
|
||||
ha_enable_transaction(this,TRUE);
|
||||
|
||||
reset_root_defaults(mem_root, variables.query_alloc_block_size,
|
||||
|
@ -442,6 +479,7 @@ THD::~THD()
|
|||
#ifndef DBUG_OFF
|
||||
dbug_sentry= THD_SENTRY_GONE;
|
||||
#endif
|
||||
free_root(&main_mem_root, MYF(0));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
@ -1588,18 +1626,17 @@ void Query_arena::cleanup_stmt()
|
|||
Statement functions
|
||||
*/
|
||||
|
||||
Statement::Statement(enum enum_state state_arg, ulong id_arg,
|
||||
ulong alloc_block_size, ulong prealloc_size)
|
||||
:Query_arena(&main_mem_root, state_arg),
|
||||
Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg,
|
||||
enum enum_state state_arg, ulong id_arg)
|
||||
:Query_arena(mem_root_arg, state_arg),
|
||||
id(id_arg),
|
||||
set_query_id(1),
|
||||
lex(&main_lex),
|
||||
lex(lex_arg),
|
||||
query(0),
|
||||
query_length(0),
|
||||
cursor(0)
|
||||
{
|
||||
name.str= NULL;
|
||||
init_sql_alloc(&main_mem_root, alloc_block_size, prealloc_size);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1641,7 +1678,7 @@ void Statement::restore_backup_statement(Statement *stmt, Statement *backup)
|
|||
|
||||
void THD::end_statement()
|
||||
{
|
||||
/* Cleanup SQL processing state to resuse this statement in next query. */
|
||||
/* Cleanup SQL processing state to reuse this statement in next query. */
|
||||
lex_end(lex);
|
||||
delete lex->result;
|
||||
lex->result= 0;
|
||||
|
@ -1682,12 +1719,6 @@ void THD::restore_active_arena(Query_arena *set, Query_arena *backup)
|
|||
|
||||
Statement::~Statement()
|
||||
{
|
||||
/*
|
||||
We must free `main_mem_root', not `mem_root' (pointer), to work
|
||||
correctly if this statement is used as a backup statement,
|
||||
for which `mem_root' may point to some other statement.
|
||||
*/
|
||||
free_root(&main_mem_root, MYF(0));
|
||||
}
|
||||
|
||||
C_MODE_START
|
||||
|
|
121
sql/sql_class.h
121
sql/sql_class.h
|
@ -753,8 +753,10 @@ public:
|
|||
|
||||
class Server_side_cursor;
|
||||
|
||||
/*
|
||||
State of a single command executed against this connection.
|
||||
/**
|
||||
@class Statement
|
||||
@brief State of a single command executed against this connection.
|
||||
|
||||
One connection can contain a lot of simultaneously running statements,
|
||||
some of which could be:
|
||||
- prepared, that is, contain placeholders,
|
||||
|
@ -772,10 +774,6 @@ class Statement: public ilink, public Query_arena
|
|||
Statement(const Statement &rhs); /* not implemented: */
|
||||
Statement &operator=(const Statement &rhs); /* non-copyable */
|
||||
public:
|
||||
/* FIXME: these must be protected */
|
||||
MEM_ROOT main_mem_root;
|
||||
LEX main_lex;
|
||||
|
||||
/*
|
||||
Uniquely identifies each statement object in thread scope; change during
|
||||
statement lifetime. FIXME: must be const
|
||||
|
@ -819,10 +817,10 @@ public:
|
|||
public:
|
||||
|
||||
/* This constructor is called for backup statements */
|
||||
Statement() { clear_alloc_root(&main_mem_root); }
|
||||
Statement() {}
|
||||
|
||||
Statement(enum enum_state state_arg, ulong id_arg,
|
||||
ulong alloc_block_size, ulong prealloc_size);
|
||||
Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg,
|
||||
enum enum_state state_arg, ulong id_arg);
|
||||
virtual ~Statement();
|
||||
|
||||
/* Assign execution context (note: not all members) of given stmt to self */
|
||||
|
@ -834,7 +832,7 @@ public:
|
|||
};
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Container for all statements created/used in a connection.
|
||||
Statements in Statement_map have unique Statement::id (guaranteed by id
|
||||
assignment in Statement::Statement)
|
||||
|
@ -914,6 +912,10 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state);
|
|||
bool xid_cache_insert(XID_STATE *xid_state);
|
||||
void xid_cache_delete(XID_STATE *xid_state);
|
||||
|
||||
/**
|
||||
@class Security_context
|
||||
@brief A set of THD members describing the current authenticated user.
|
||||
*/
|
||||
|
||||
class Security_context {
|
||||
public:
|
||||
|
@ -943,7 +945,7 @@ public:
|
|||
};
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
A registry for item tree transformations performed during
|
||||
query optimization. We register only those changes which require
|
||||
a rollback to re-execute a prepared statement or stored procedure
|
||||
|
@ -954,7 +956,7 @@ struct Item_change_record;
|
|||
typedef I_List<Item_change_record> Item_change_list;
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Type of prelocked mode.
|
||||
See comment for THD::prelocked_mode for complete description.
|
||||
*/
|
||||
|
@ -963,7 +965,7 @@ enum prelocked_mode_type {NON_PRELOCKED= 0, PRELOCKED= 1,
|
|||
PRELOCKED_UNDER_LOCK_TABLES= 2};
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Class that holds information about tables which were opened and locked
|
||||
by the thread. It is also used to save/restore this information in
|
||||
push_open_tables_state()/pop_open_tables_state().
|
||||
|
@ -1048,14 +1050,17 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
/* class to save context when executing a function or trigger */
|
||||
/**
|
||||
@class Sub_statement_state
|
||||
@brief Used to save context when executing a function or trigger
|
||||
*/
|
||||
|
||||
/* Defines used for Sub_statement_state::in_sub_stmt */
|
||||
|
||||
#define SUB_STMT_TRIGGER 1
|
||||
#define SUB_STMT_FUNCTION 2
|
||||
|
||||
|
||||
class Sub_statement_state
|
||||
{
|
||||
public:
|
||||
|
@ -1071,8 +1076,51 @@ public:
|
|||
SAVEPOINT *savepoints;
|
||||
};
|
||||
|
||||
/**
|
||||
This class represents the interface for internal error handlers.
|
||||
Internal error handlers are exception handlers used by the server
|
||||
implementation.
|
||||
*/
|
||||
class Internal_error_handler
|
||||
{
|
||||
protected:
|
||||
Internal_error_handler() {}
|
||||
virtual ~Internal_error_handler() {}
|
||||
|
||||
/*
|
||||
public:
|
||||
/**
|
||||
Handle an error condition.
|
||||
This method can be implemented by a subclass to achieve any of the
|
||||
following:
|
||||
- mask an error internally, prevent exposing it to the user,
|
||||
- mask an error and throw another one instead.
|
||||
When this method returns true, the error condition is considered
|
||||
'handled', and will not be propagated to upper layers.
|
||||
It is the responsability of the code installing an internal handler
|
||||
to then check for trapped conditions, and implement logic to recover
|
||||
from the anticipated conditions trapped during runtime.
|
||||
|
||||
This mechanism is similar to C++ try/throw/catch:
|
||||
- 'try' correspond to <code>THD::push_internal_handler()</code>,
|
||||
- 'throw' correspond to <code>my_error()</code>,
|
||||
which invokes <code>my_message_sql()</code>,
|
||||
- 'catch' correspond to checking how/if an internal handler was invoked,
|
||||
before removing it from the exception stack with
|
||||
<code>THD::pop_internal_handler()</code>.
|
||||
|
||||
@param sql_errno the error number
|
||||
@param level the error level
|
||||
@param thd the calling thread
|
||||
@return true if the error is handled
|
||||
*/
|
||||
virtual bool handle_error(uint sql_errno,
|
||||
MYSQL_ERROR::enum_warning_level level,
|
||||
THD *thd) = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@class THD
|
||||
For each client connection we create a separate thread with THD serving as
|
||||
a thread/connection descriptor
|
||||
*/
|
||||
|
@ -1659,6 +1707,47 @@ public:
|
|||
*p_db_length= db_length;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
Add an internal error handler to the thread execution context.
|
||||
@param handler the exception handler to add
|
||||
*/
|
||||
void push_internal_handler(Internal_error_handler *handler);
|
||||
|
||||
/**
|
||||
Handle an error condition.
|
||||
@param sql_errno the error number
|
||||
@param level the error level
|
||||
@return true if the error is handled
|
||||
*/
|
||||
virtual bool handle_error(uint sql_errno,
|
||||
MYSQL_ERROR::enum_warning_level level);
|
||||
|
||||
/**
|
||||
Remove the error handler last pushed.
|
||||
*/
|
||||
void pop_internal_handler();
|
||||
|
||||
private:
|
||||
/** The current internal error handler for this thread, or NULL. */
|
||||
Internal_error_handler *m_internal_handler;
|
||||
/**
|
||||
The lex to hold the parsed tree of conventional (non-prepared) queries.
|
||||
Whereas for prepared and stored procedure statements we use an own lex
|
||||
instance for each new query, for conventional statements we reuse
|
||||
the same lex. (@see mysql_parse for details).
|
||||
*/
|
||||
LEX main_lex;
|
||||
/**
|
||||
This memory root is used for two purposes:
|
||||
- for conventional queries, to allocate structures stored in main_lex
|
||||
during parsing, and allocate runtime data (execution plan, etc.)
|
||||
during execution.
|
||||
- for prepared queries, only to allocate runtime data. The parsed
|
||||
tree itself is reused between executions and thus is stored elsewhere.
|
||||
*/
|
||||
MEM_ROOT main_mem_root;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -99,6 +99,16 @@ void lex_free(void)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
st_parsing_options::reset()
|
||||
{
|
||||
allows_variable= TRUE;
|
||||
allows_select_into= TRUE;
|
||||
allows_select_procedure= TRUE;
|
||||
allows_derived= TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This is called before every query that is to be parsed.
|
||||
Because of this, it's critical to not do too much things here.
|
||||
|
@ -149,6 +159,7 @@ void lex_start(THD *thd, uchar *buf,uint length)
|
|||
lex->safe_to_cache_query= 1;
|
||||
lex->time_zone_tables_used= 0;
|
||||
lex->leaf_tables_insert= 0;
|
||||
lex->parsing_options.reset();
|
||||
lex->empty_field_list_on_rset= 0;
|
||||
lex->select_lex.select_number= 1;
|
||||
lex->next_state=MY_LEX_START;
|
||||
|
@ -1637,6 +1648,36 @@ void st_select_lex::print_limit(THD *thd, String *str)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Restore the LEX and THD in case of a parse error.
|
||||
|
||||
This is a clean up call that is invoked by the Bison generated
|
||||
parser before returning an error from MYSQLparse. If your
|
||||
semantic actions manipulate with the global thread state (which
|
||||
is a very bad practice and should not normally be employed) and
|
||||
need a clean-up in case of error, and you can not use %destructor
|
||||
rule in the grammar file itself, this function should be used
|
||||
to implement the clean up.
|
||||
*/
|
||||
|
||||
void st_lex::cleanup_lex_after_parse_error(THD *thd)
|
||||
{
|
||||
/*
|
||||
Delete sphead for the side effect of restoring of the original
|
||||
LEX state, thd->lex, thd->mem_root and thd->free_list if they
|
||||
were replaced when parsing stored procedure statements. We
|
||||
will never use sphead object after a parse error, so it's okay
|
||||
to delete it only for the sake of the side effect.
|
||||
TODO: make this functionality explicit in sp_head class.
|
||||
Sic: we must nullify the member of the main lex, not the
|
||||
current one that will be thrown away
|
||||
*/
|
||||
if (thd->lex->sphead)
|
||||
{
|
||||
delete thd->lex->sphead;
|
||||
thd->lex->sphead= NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Initialize (or reset) Query_tables_list object.
|
||||
|
|
|
@ -891,10 +891,8 @@ struct st_parsing_options
|
|||
bool allows_select_procedure;
|
||||
bool allows_derived;
|
||||
|
||||
st_parsing_options()
|
||||
: allows_variable(TRUE), allows_select_into(TRUE),
|
||||
allows_select_procedure(TRUE), allows_derived(TRUE)
|
||||
{}
|
||||
st_parsing_options() { reset(); }
|
||||
void reset();
|
||||
};
|
||||
|
||||
|
||||
|
@ -1184,6 +1182,10 @@ typedef struct st_lex : public Query_tables_list
|
|||
{
|
||||
return context_stack.head();
|
||||
}
|
||||
/*
|
||||
Restore the LEX and THD in case of a parse error.
|
||||
*/
|
||||
static void cleanup_lex_after_parse_error(THD *thd);
|
||||
|
||||
void reset_n_backup_query_tables_list(Query_tables_list *backup);
|
||||
void restore_backup_query_tables_list(Query_tables_list *backup);
|
||||
|
|
|
@ -1162,7 +1162,6 @@ pthread_handler_t handle_one_connection(void *arg)
|
|||
thd->version= refresh_version;
|
||||
thd->proc_info= 0;
|
||||
thd->command= COM_SLEEP;
|
||||
thd->set_time();
|
||||
thd->init_for_queries();
|
||||
|
||||
if (sys_init_connect.value_length && !(sctx->master_access & SUPER_ACL))
|
||||
|
@ -1178,7 +1177,6 @@ pthread_handler_t handle_one_connection(void *arg)
|
|||
sql_print_warning("%s", net->last_error);
|
||||
}
|
||||
thd->proc_info=0;
|
||||
thd->set_time();
|
||||
thd->init_for_queries();
|
||||
}
|
||||
|
||||
|
@ -1313,6 +1311,7 @@ pthread_handler_t handle_bootstrap(void *arg)
|
|||
mode we have only one thread.
|
||||
*/
|
||||
thd->query_id=next_query_id();
|
||||
thd->set_time();
|
||||
mysql_parse(thd,thd->query,length);
|
||||
close_thread_tables(thd); // Free tables
|
||||
|
||||
|
@ -4518,9 +4517,6 @@ end_with_restore_list:
|
|||
clean up the environment.
|
||||
*/
|
||||
create_sp_error:
|
||||
lex->unit.cleanup();
|
||||
delete lex->sphead;
|
||||
lex->sphead= 0;
|
||||
if (sp_result != SP_OK )
|
||||
goto error;
|
||||
send_ok(thd);
|
||||
|
@ -4891,9 +4887,6 @@ create_sp_error:
|
|||
/* Conditionally writes to binlog. */
|
||||
res= mysql_create_or_drop_trigger(thd, all_tables, 1);
|
||||
|
||||
/* We don't care about trigger body after this point */
|
||||
delete lex->sphead;
|
||||
lex->sphead= 0;
|
||||
break;
|
||||
}
|
||||
case SQLCOM_DROP_TRIGGER:
|
||||
|
@ -5916,15 +5909,7 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
|
|||
else
|
||||
#endif
|
||||
{
|
||||
if (thd->net.report_error)
|
||||
{
|
||||
if (thd->lex->sphead)
|
||||
{
|
||||
delete thd->lex->sphead;
|
||||
thd->lex->sphead= NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (! thd->net.report_error)
|
||||
{
|
||||
/*
|
||||
Binlog logs a string starting from thd->query and having length
|
||||
|
@ -5944,7 +5929,6 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
|
|||
query_cache_end_of_result(thd);
|
||||
}
|
||||
}
|
||||
lex->unit.cleanup();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5952,19 +5936,14 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
|
|||
DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
|
||||
thd->is_fatal_error));
|
||||
|
||||
/*
|
||||
The first thing we do after parse error is freeing sp_head to
|
||||
ensure that we have restored original memroot.
|
||||
*/
|
||||
if (thd->lex->sphead)
|
||||
{
|
||||
/* Clean up after failed stored procedure/function */
|
||||
delete thd->lex->sphead;
|
||||
thd->lex->sphead= NULL;
|
||||
}
|
||||
query_cache_abort(&thd->net);
|
||||
lex->unit.cleanup();
|
||||
}
|
||||
if (thd->lex->sphead)
|
||||
{
|
||||
delete thd->lex->sphead;
|
||||
thd->lex->sphead= 0;
|
||||
}
|
||||
lex->unit.cleanup();
|
||||
thd->proc_info="freeing items";
|
||||
thd->end_statement();
|
||||
thd->cleanup_after_query();
|
||||
|
|
|
@ -99,9 +99,12 @@ public:
|
|||
#endif
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
Prepared_statement: a statement that can contain placeholders
|
||||
******************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
/**
|
||||
@class Prepared_statement
|
||||
@brief Prepared_statement: a statement that can contain placeholders
|
||||
*/
|
||||
|
||||
class Prepared_statement: public Statement
|
||||
{
|
||||
|
@ -141,6 +144,16 @@ public:
|
|||
bool execute(String *expanded_query, bool open_cursor);
|
||||
/* Destroy this statement */
|
||||
bool deallocate();
|
||||
private:
|
||||
/**
|
||||
Store the parsed tree of a prepared statement here.
|
||||
*/
|
||||
LEX main_lex;
|
||||
/**
|
||||
The memory root to allocate parsed tree elements (instances of Item,
|
||||
SELECT_LEX and other classes).
|
||||
*/
|
||||
MEM_ROOT main_mem_root;
|
||||
};
|
||||
|
||||
|
||||
|
@ -2034,6 +2047,7 @@ void mysql_sql_stmt_prepare(THD *thd)
|
|||
delete stmt;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
if (thd->stmt_map.insert(thd, stmt))
|
||||
{
|
||||
/* The statement is deleted and an error is set if insert fails */
|
||||
|
@ -2629,17 +2643,18 @@ Select_fetch_protocol_prep::send_data(List<Item> &fields)
|
|||
****************************************************************************/
|
||||
|
||||
Prepared_statement::Prepared_statement(THD *thd_arg, Protocol *protocol_arg)
|
||||
:Statement(INITIALIZED, ++thd_arg->statement_id_counter,
|
||||
thd_arg->variables.query_alloc_block_size,
|
||||
thd_arg->variables.query_prealloc_size),
|
||||
:Statement(&main_lex, &main_mem_root,
|
||||
INITIALIZED, ++thd_arg->statement_id_counter),
|
||||
thd(thd_arg),
|
||||
result(thd_arg),
|
||||
protocol(protocol_arg),
|
||||
param_array(0),
|
||||
param_count(0),
|
||||
last_errno(0),
|
||||
flags((uint) IS_IN_USE)
|
||||
flags((uint) IS_IN_USE)
|
||||
{
|
||||
init_alloc_root(&main_mem_root, thd_arg->variables.query_alloc_block_size,
|
||||
thd_arg->variables.query_prealloc_size);
|
||||
*last_error= '\0';
|
||||
}
|
||||
|
||||
|
@ -2688,6 +2703,7 @@ Prepared_statement::~Prepared_statement()
|
|||
*/
|
||||
free_items();
|
||||
delete lex->result;
|
||||
free_root(&main_mem_root, MYF(0));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
@ -2703,6 +2719,7 @@ void Prepared_statement::cleanup_stmt()
|
|||
DBUG_ENTER("Prepared_statement::cleanup_stmt");
|
||||
DBUG_PRINT("enter",("stmt: %p", this));
|
||||
|
||||
DBUG_ASSERT(lex->sphead == 0);
|
||||
/* The order is important */
|
||||
lex->unit.cleanup();
|
||||
cleanup_items(free_list);
|
||||
|
@ -2789,15 +2806,6 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
|
|||
error= MYSQLparse((void *)thd) || thd->is_fatal_error ||
|
||||
thd->net.report_error || init_param_array(this);
|
||||
|
||||
/*
|
||||
The first thing we do after parse error is freeing sp_head to
|
||||
ensure that we have restored original memroot.
|
||||
*/
|
||||
if (error && lex->sphead)
|
||||
{
|
||||
delete lex->sphead;
|
||||
lex->sphead= NULL;
|
||||
}
|
||||
/*
|
||||
While doing context analysis of the query (in check_prepared_statement)
|
||||
we allocate a lot of additional memory: for open tables, JOINs, derived
|
||||
|
@ -2823,12 +2831,18 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
|
|||
if (error == 0)
|
||||
error= check_prepared_statement(this, name.str != 0);
|
||||
|
||||
/* Free sp_head if check_prepared_statement() failed. */
|
||||
if (error && lex->sphead)
|
||||
/*
|
||||
Currently CREATE PROCEDURE/TRIGGER/EVENT are prohibited in prepared
|
||||
statements: ensure we have no memory leak here if by someone tries
|
||||
to PREPARE stmt FROM "CREATE PROCEDURE ..."
|
||||
*/
|
||||
DBUG_ASSERT(lex->sphead == NULL || error != 0);
|
||||
if (lex->sphead)
|
||||
{
|
||||
delete lex->sphead;
|
||||
lex->sphead= NULL;
|
||||
}
|
||||
|
||||
lex_end(lex);
|
||||
cleanup_stmt();
|
||||
thd->restore_backup_statement(this, &stmt_backup);
|
||||
|
|
|
@ -983,11 +983,8 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
|
|||
thd->spcont= 0;
|
||||
if (MYSQLparse((void *)thd) || thd->is_fatal_error)
|
||||
{
|
||||
/*
|
||||
Free lex associated resources.
|
||||
QQ: Do we really need all this stuff here ?
|
||||
*/
|
||||
delete lex.sphead;
|
||||
/* Currently sphead is always deleted in case of a parse error */
|
||||
DBUG_ASSERT(lex.sphead == 0);
|
||||
goto err_with_lex_cleanup;
|
||||
}
|
||||
|
||||
|
|
|
@ -787,7 +787,7 @@ reopen_tables:
|
|||
tl->lock_type= using_update_log ? TL_READ_NO_INSERT : TL_READ;
|
||||
tl->updating= 0;
|
||||
/* Update TABLE::lock_type accordingly. */
|
||||
if (!tl->placeholder() && !tl->schema_table && !using_lock_tables)
|
||||
if (!tl->placeholder() && !using_lock_tables)
|
||||
tl->table->reginfo.lock_type= tl->lock_type;
|
||||
}
|
||||
}
|
||||
|
|
871
sql/sql_yacc.yy
871
sql/sql_yacc.yy
File diff suppressed because it is too large
Load diff
|
@ -2080,7 +2080,9 @@ void st_table_list::hide_view_error(THD *thd)
|
|||
thd->net.last_errno == ER_SP_DOES_NOT_EXIST ||
|
||||
thd->net.last_errno == ER_PROCACCESS_DENIED_ERROR ||
|
||||
thd->net.last_errno == ER_COLUMNACCESS_DENIED_ERROR ||
|
||||
thd->net.last_errno == ER_TABLEACCESS_DENIED_ERROR)
|
||||
thd->net.last_errno == ER_TABLEACCESS_DENIED_ERROR ||
|
||||
thd->net.last_errno == ER_TABLE_NOT_LOCKED ||
|
||||
thd->net.last_errno == ER_NO_SUCH_TABLE)
|
||||
{
|
||||
TABLE_LIST *top= top_table();
|
||||
thd->clear_error();
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue