mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
Merge willster.(none):/home/stewart/Documents/MySQL/5.1/ndb
into willster.(none):/home/stewart/Documents/MySQL/5.1/pending include/my_sys.h: Auto merged
This commit is contained in:
commit
d712fa8893
100 changed files with 3369 additions and 882 deletions
|
@ -66,7 +66,7 @@ INSTALL-BINARY: mysql.info $(GT)
|
|||
# It is not in BitKeeper, but is downloaded from intranet by Bootstrap.
|
||||
dist-hook:
|
||||
if [ -e $(srcdir)/manual.chm ] ; then \
|
||||
cp $(srcdir)/manual.chm $(distdir); \
|
||||
cp -f $(srcdir)/manual.chm $(distdir); \
|
||||
fi
|
||||
|
||||
# Don't update the files from bitkeeper
|
||||
|
|
|
@ -65,6 +65,9 @@ TARGET_LINK_LIBRARIES(mysqldump mysqlclient mysys dbug yassl taocrypt zlib wsock
|
|||
ADD_EXECUTABLE(mysqlimport mysqlimport.c)
|
||||
TARGET_LINK_LIBRARIES(mysqlimport mysqlclient mysys dbug yassl taocrypt zlib wsock32)
|
||||
|
||||
ADD_EXECUTABLE(mysql_upgrade mysql_upgrade.c)
|
||||
TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient mysys dbug yassl taocrypt zlib wsock32)
|
||||
|
||||
ADD_EXECUTABLE(mysqlshow mysqlshow.c)
|
||||
TARGET_LINK_LIBRARIES(mysqlshow mysqlclient mysys dbug yassl taocrypt zlib wsock32)
|
||||
|
||||
|
|
|
@ -253,6 +253,29 @@ AC_DEFUN([MYSQL_PLUGIN_ACTIONS],[
|
|||
])
|
||||
])
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl Macro: MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS
|
||||
dnl
|
||||
dnl SYNOPSIS
|
||||
dnl MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS([name],[file name])
|
||||
dnl
|
||||
dnl DESCRIPTION
|
||||
dnl Some modules in plugins keep dependance on structures
|
||||
dnl declared in sql/ (THD class usually)
|
||||
dnl That has to be fixed in the future, but until then
|
||||
dnl we have to recompile these modules when we want to
|
||||
dnl to compile server parts with the different #defines
|
||||
dnl Normally it happens when we compile the embedded server
|
||||
dnl Thus one should mark such files in his handler using this macro
|
||||
dnl (currently only one such a file per plugin is supported)
|
||||
dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
|
||||
AC_DEFUN([MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS],[
|
||||
MYSQL_REQUIRE_PLUGIN([$1])
|
||||
m4_define([MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS_]AS_TR_CPP([$1]), [$2])
|
||||
])
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl Macro: MYSQL_CONFIGURE_PLUGINS
|
||||
dnl
|
||||
|
@ -282,6 +305,9 @@ AC_DEFUN([MYSQL_CONFIGURE_PLUGINS],[
|
|||
AC_SUBST([mysql_pg_dirs])
|
||||
AC_SUBST([mysql_se_unittest_dirs])
|
||||
AC_SUBST([mysql_pg_unittest_dirs])
|
||||
AC_SUBST([condition_dependent_plugin_modules])
|
||||
AC_SUBST([condition_dependent_plugin_links])
|
||||
AC_SUBST([condition_dependent_plugin_includes])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
@ -307,6 +333,7 @@ AC_DEFUN([_MYSQL_EMIT_CHECK_PLUGIN],[
|
|||
[MYSQL_PLUGIN_DYNAMIC_]AS_TR_CPP([$1]),
|
||||
[MYSQL_PLUGIN_MANDATORY_]AS_TR_CPP([$1]),
|
||||
[MYSQL_PLUGIN_DISABLED_]AS_TR_CPP([$1]),
|
||||
[MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS_]AS_TR_CPP([$1]),
|
||||
[MYSQL_PLUGIN_ACTIONS_]AS_TR_CPP([$1])
|
||||
)
|
||||
])
|
||||
|
@ -402,6 +429,11 @@ dnl Although this is "pretty", it breaks libmysqld build
|
|||
mysql_plugin_defs="$mysql_plugin_defs, [builtin_]$2[_plugin]"
|
||||
[with_plugin_]$2=yes
|
||||
AC_MSG_RESULT([yes])
|
||||
m4_ifdef([$11],[
|
||||
condition_dependent_plugin_modules="$condition_dependent_plugin_modules m4_bregexp($11, [[^/]+$], [\&])"
|
||||
condition_dependent_plugin_links="$condition_dependent_plugin_links $6/$11"
|
||||
condition_dependent_plugin_includes="$condition_dependent_plugin_includes -I[\$(top_srcdir)]/$6/m4_bregexp($11, [^.+[/$]], [\&])"
|
||||
])
|
||||
fi
|
||||
m4_ifdef([$6],[
|
||||
if test -n "$mysql_use_plugin_dir" ; then
|
||||
|
|
|
@ -1441,9 +1441,9 @@ fi
|
|||
# dlopen, dlerror
|
||||
case "$with_mysqld_ldflags " in
|
||||
|
||||
*"-static "*)
|
||||
*"-all-static "*)
|
||||
# No need to check for dlopen when mysqld is linked with
|
||||
# -all-static or -static as it won't be able to load any functions.
|
||||
# -all-static as it won't be able to load any functions.
|
||||
# NOTE! It would be better if it was possible to test if dlopen
|
||||
# can be used, but a good way to test it couldn't be found
|
||||
|
||||
|
|
|
@ -120,6 +120,8 @@ enum my_lex_states
|
|||
|
||||
struct charset_info_st;
|
||||
|
||||
|
||||
/* See strings/CHARSET_INFO.txt for information about this structure */
|
||||
typedef struct my_collation_handler_st
|
||||
{
|
||||
my_bool (*init)(struct charset_info_st *, void *(*alloc)(uint));
|
||||
|
@ -162,6 +164,7 @@ extern MY_COLLATION_HANDLER my_collation_8bit_simple_ci_handler;
|
|||
extern MY_COLLATION_HANDLER my_collation_ucs2_uca_handler;
|
||||
|
||||
|
||||
/* See strings/CHARSET_INFO.txt about information on this structure */
|
||||
typedef struct my_charset_handler_st
|
||||
{
|
||||
my_bool (*init)(struct charset_info_st *, void *(*alloc)(uint));
|
||||
|
@ -228,6 +231,7 @@ extern MY_CHARSET_HANDLER my_charset_8bit_handler;
|
|||
extern MY_CHARSET_HANDLER my_charset_ucs2_handler;
|
||||
|
||||
|
||||
/* See strings/CHARSET_INFO.txt about information on this structure */
|
||||
typedef struct charset_info_st
|
||||
{
|
||||
uint number;
|
||||
|
|
|
@ -229,12 +229,17 @@ enum ha_base_keytype {
|
|||
#define HA_USES_PARSER 16384 /* Fulltext index uses [pre]parser */
|
||||
#define HA_USES_BLOCK_SIZE ((uint) 32768)
|
||||
#define HA_SORT_ALLOWS_SAME 512 /* Intern bit when sorting records */
|
||||
#if MYSQL_VERSION_ID < 0x50200
|
||||
/*
|
||||
Key has a part that can have end space. If this is an unique key
|
||||
we have to handle it differently from other unique keys as we can find
|
||||
many matching rows for one key (because end space are not compared)
|
||||
*/
|
||||
#define HA_END_SPACE_KEY 4096
|
||||
#define HA_END_SPACE_KEY 0 /* was: 4096 */
|
||||
#else
|
||||
#error HA_END_SPACE_KEY is obsolete, please remove it
|
||||
#endif
|
||||
|
||||
|
||||
/* These flags can be added to key-seg-flag */
|
||||
|
||||
|
|
|
@ -614,12 +614,17 @@ C_MODE_END
|
|||
#define _STATIC_VARARGS(X) X
|
||||
#define _PC(X) X
|
||||
|
||||
/* The DBUG_ON flag always takes precedence over default DBUG_OFF */
|
||||
#if defined(DBUG_ON) && defined(DBUG_OFF)
|
||||
#undef DBUG_OFF
|
||||
#endif
|
||||
|
||||
#if defined(_lint) && !defined(DBUG_OFF)
|
||||
#define DBUG_OFF
|
||||
/* We might be forced to turn debug off, if not turned off already */
|
||||
#if (defined(FORCE_DBUG_OFF) || defined(_lint)) && !defined(DBUG_OFF)
|
||||
# define DBUG_OFF
|
||||
# ifdef DBUG_ON
|
||||
# undef DBUG_ON
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <my_dbug.h>
|
||||
|
|
|
@ -341,12 +341,18 @@ typedef int (*IO_CACHE_CALLBACK)(struct st_io_cache*);
|
|||
#ifdef THREAD
|
||||
typedef struct st_io_cache_share
|
||||
{
|
||||
/* to sync on reads into buffer */
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
int count, total;
|
||||
/* actual IO_CACHE that filled the buffer */
|
||||
struct st_io_cache *active;
|
||||
pthread_mutex_t mutex; /* To sync on reads into buffer. */
|
||||
pthread_cond_t cond; /* To wait for signals. */
|
||||
pthread_cond_t cond_writer; /* For a synchronized writer. */
|
||||
/* Offset in file corresponding to the first byte of buffer. */
|
||||
my_off_t pos_in_file;
|
||||
/* If a synchronized write cache is the source of the data. */
|
||||
struct st_io_cache *source_cache;
|
||||
byte *buffer; /* The read buffer. */
|
||||
byte *read_end; /* Behind last valid byte of buffer. */
|
||||
int running_threads; /* threads not in lock. */
|
||||
int total_threads; /* threads sharing the cache. */
|
||||
int error; /* Last error. */
|
||||
#ifdef NOT_YET_IMPLEMENTED
|
||||
/* whether the structure should be free'd */
|
||||
my_bool alloced;
|
||||
|
@ -720,8 +726,8 @@ extern void setup_io_cache(IO_CACHE* info);
|
|||
extern int _my_b_read(IO_CACHE *info,byte *Buffer,uint Count);
|
||||
#ifdef THREAD
|
||||
extern int _my_b_read_r(IO_CACHE *info,byte *Buffer,uint Count);
|
||||
extern void init_io_cache_share(IO_CACHE *info,
|
||||
IO_CACHE_SHARE *s, uint num_threads);
|
||||
extern void init_io_cache_share(IO_CACHE *read_cache, IO_CACHE_SHARE *cshare,
|
||||
IO_CACHE *write_cache, uint num_threads);
|
||||
extern void remove_io_thread(IO_CACHE *info);
|
||||
#endif
|
||||
extern int _my_b_seq_read(IO_CACHE *info,byte *Buffer,uint Count);
|
||||
|
|
|
@ -419,7 +419,7 @@ typedef struct st_mi_check_param
|
|||
uint testflag, key_cache_block_size;
|
||||
uint8 language;
|
||||
my_bool using_global_keycache, opt_lock_memory, opt_follow_links;
|
||||
my_bool retry_repair, force_sort, calc_checksum;
|
||||
my_bool retry_repair, force_sort;
|
||||
char temp_filename[FN_REFLEN],*isam_file_name;
|
||||
MY_TMPDIR *tmpdir;
|
||||
int tmpfile_createflag;
|
||||
|
|
|
@ -293,12 +293,6 @@ typedef struct st_mysql
|
|||
/* needed for embedded server - no net buffer to store the 'info' */
|
||||
char *info_buffer;
|
||||
#endif
|
||||
/*
|
||||
In embedded server it points to the statement that is processed
|
||||
in the current query. We store some results directly in statement
|
||||
fields then.
|
||||
*/
|
||||
struct st_mysql_stmt *current_stmt;
|
||||
} MYSQL;
|
||||
|
||||
typedef struct st_mysql_res {
|
||||
|
|
|
@ -32,7 +32,8 @@ INCLUDES= -I$(top_builddir)/include -I$(top_srcdir)/include \
|
|||
-I$(top_builddir)/include -I$(top_srcdir)/include \
|
||||
-I$(top_srcdir)/sql -I$(top_srcdir)/sql/examples \
|
||||
-I$(top_srcdir)/regex \
|
||||
$(openssl_includes) @ZLIB_INCLUDES@
|
||||
$(openssl_includes) @ZLIB_INCLUDES@ \
|
||||
@condition_dependent_plugin_includes@
|
||||
|
||||
noinst_LIBRARIES = libmysqld_int.a
|
||||
pkglib_LIBRARIES = libmysqld.a
|
||||
|
@ -77,6 +78,8 @@ libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources)
|
|||
libmysqld_a_SOURCES=
|
||||
|
||||
sqlstoragesources = $(EXTRA_libmysqld_a_SOURCES)
|
||||
storagesources = @condition_dependent_plugin_modules@
|
||||
storagesourceslinks = @condition_dependent_plugin_links@
|
||||
|
||||
# automake misses these
|
||||
sql_yacc.cc sql_yacc.h: $(top_srcdir)/sql/sql_yacc.yy
|
||||
|
@ -170,12 +173,19 @@ link_sources:
|
|||
@LN_CP_F@ `find $(srcdir)/../sql -name "$$f"` "$$f"; \
|
||||
done; \
|
||||
fi; \
|
||||
if test -n "$(storagesources)" ; \
|
||||
then \
|
||||
rm -f $(storagesources); \
|
||||
for f in $(storagesourceslinks); do \
|
||||
@LN_CP_F@ $(top_srcdir)/$$f . ; \
|
||||
done; \
|
||||
fi; \
|
||||
rm -f client_settings.h; \
|
||||
@LN_CP_F@ $(top_srcdir)/libmysql/client_settings.h client_settings.h
|
||||
|
||||
|
||||
clean-local:
|
||||
rm -f `echo $(sqlsources) $(libmysqlsources) $(sqlstoragesources) | sed "s;\.lo;.c;g"` \
|
||||
rm -f `echo $(sqlsources) $(libmysqlsources) $(sqlstoragesources) $(storagesources) | sed "s;\.lo;.c;g"` \
|
||||
$(top_srcdir)/linked_libmysqld_sources; \
|
||||
rm -f client_settings.h
|
||||
|
||||
|
|
|
@ -100,7 +100,6 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
|
|||
mysql->affected_rows= ~(my_ulonglong) 0;
|
||||
mysql->field_count= 0;
|
||||
net->last_errno= 0;
|
||||
mysql->current_stmt= stmt;
|
||||
|
||||
thd->store_globals(); // Fix if more than one connect
|
||||
/*
|
||||
|
|
|
@ -321,6 +321,24 @@ SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id
|
|||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
#
|
||||
# Bug#22781: SQL_BIG_RESULT fails to influence sort plan
|
||||
#
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c FLOAT, KEY b(b)) ENGINE = INNODB;
|
||||
|
||||
INSERT INTO t1 VALUES ( 1 , 1 , 1);
|
||||
INSERT INTO t1 SELECT a + 1 , MOD(a + 1 , 20), 1 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 2 , MOD(a + 2 , 20), 1 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 4 , MOD(a + 4 , 20), 1 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 8 , MOD(a + 8 , 20), 1 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 16, MOD(a + 16, 20), 1 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 32, MOD(a + 32, 20), 1 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 64, MOD(a + 64, 20), 1 FROM t1;
|
||||
|
||||
EXPLAIN SELECT b, SUM(c) FROM t1 GROUP BY b;
|
||||
EXPLAIN SELECT SQL_BIG_RESULT b, SUM(c) FROM t1 GROUP BY b;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Test of behaviour with CREATE ... SELECT
|
||||
#
|
||||
|
|
|
@ -1155,6 +1155,81 @@ check table t1;
|
|||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
drop table t1;
|
||||
set names utf8;
|
||||
create table t1 (s1 char(5) character set utf8);
|
||||
insert into t1 values
|
||||
('a'),('b'),(null),('ペテルグル'),('ü'),('Y');
|
||||
create index it1 on t1 (s1);
|
||||
select s1 as before_delete_general_ci from t1 where s1 like 'ペテ%';
|
||||
before_delete_general_ci
|
||||
ペテルグル
|
||||
delete from t1 where s1 = 'Y';
|
||||
select s1 as after_delete_general_ci from t1 where s1 like 'ペテ%';
|
||||
after_delete_general_ci
|
||||
ペテルグル
|
||||
drop table t1;
|
||||
set names utf8;
|
||||
create table t1 (s1 char(5) character set utf8 collate utf8_unicode_ci);
|
||||
insert into t1 values
|
||||
('a'),('b'),(null),('ペテルグル'),('ü'),('Y');
|
||||
create index it1 on t1 (s1);
|
||||
select s1 as before_delete_unicode_ci from t1 where s1 like 'ペテ%';
|
||||
before_delete_unicode_ci
|
||||
ペテルグル
|
||||
delete from t1 where s1 = 'Y';
|
||||
select s1 as after_delete_unicode_ci from t1 where s1 like 'ペテ%';
|
||||
after_delete_unicode_ci
|
||||
ペテルグル
|
||||
drop table t1;
|
||||
set names utf8;
|
||||
create table t1 (s1 char(5) character set utf8 collate utf8_bin);
|
||||
insert into t1 values
|
||||
('a'),('b'),(null),('ペテルグル'),('ü'),('Y');
|
||||
create index it1 on t1 (s1);
|
||||
select s1 as before_delete_bin from t1 where s1 like 'ペテ%';
|
||||
before_delete_bin
|
||||
ペテルグル
|
||||
delete from t1 where s1 = 'Y';
|
||||
select s1 as after_delete_bin from t1 where s1 like 'ペテ%';
|
||||
after_delete_bin
|
||||
ペテルグル
|
||||
drop table t1;
|
||||
set names utf8;
|
||||
create table t1 (a varchar(30) not null primary key)
|
||||
engine=innodb default character set utf8 collate utf8_general_ci;
|
||||
insert into t1 values ('あいうえおかきくけこさしすせそ');
|
||||
insert into t1 values ('さしすせそかきくけこあいうえお');
|
||||
select a as gci1 from t1 where a like 'さしすせそかきくけこあいうえお%';
|
||||
gci1
|
||||
さしすせそかきくけこあいうえお
|
||||
select a as gci2 from t1 where a like 'あいうえおかきくけこさしすせそ';
|
||||
gci2
|
||||
あいうえおかきくけこさしすせそ
|
||||
drop table t1;
|
||||
set names utf8;
|
||||
create table t1 (a varchar(30) not null primary key)
|
||||
engine=innodb default character set utf8 collate utf8_unicode_ci;
|
||||
insert into t1 values ('あいうえおかきくけこさしすせそ');
|
||||
insert into t1 values ('さしすせそかきくけこあいうえお');
|
||||
select a as uci1 from t1 where a like 'さしすせそかきくけこあいうえお%';
|
||||
uci1
|
||||
さしすせそかきくけこあいうえお
|
||||
select a as uci2 from t1 where a like 'あいうえおかきくけこさしすせそ';
|
||||
uci2
|
||||
あいうえおかきくけこさしすせそ
|
||||
drop table t1;
|
||||
set names utf8;
|
||||
create table t1 (a varchar(30) not null primary key)
|
||||
engine=innodb default character set utf8 collate utf8_bin;
|
||||
insert into t1 values ('あいうえおかきくけこさしすせそ');
|
||||
insert into t1 values ('さしすせそかきくけこあいうえお');
|
||||
select a as bin1 from t1 where a like 'さしすせそかきくけこあいうえお%';
|
||||
bin1
|
||||
さしすせそかきくけこあいうえお
|
||||
select a as bin2 from t1 where a like 'あいうえおかきくけこさしすせそ';
|
||||
bin2
|
||||
あいうえおかきくけこさしすせそ
|
||||
drop table t1;
|
||||
SET NAMES utf8;
|
||||
CREATE TABLE t1 (id int PRIMARY KEY,
|
||||
a varchar(16) collate utf8_unicode_ci NOT NULL default '',
|
||||
|
|
|
@ -74,11 +74,6 @@ grp group_concat(c order by 1)
|
|||
1 a
|
||||
2 b,c
|
||||
3 C,D,d,d,D,E
|
||||
select grp,group_concat(c order by "c") from t1 group by grp;
|
||||
grp group_concat(c order by "c")
|
||||
1 a
|
||||
2 b,c
|
||||
3 C,D,d,d,D,E
|
||||
select grp,group_concat(distinct c order by c) from t1 group by grp;
|
||||
grp group_concat(distinct c order by c)
|
||||
1 a
|
||||
|
|
|
@ -1143,9 +1143,9 @@ EXPLAIN EXTENDED
|
|||
SELECT * FROM t1 INNER JOIN t2 ON code=id
|
||||
WHERE id='a12' AND (LENGTH(code)=5 OR code < 'a00');
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t2 const PRIMARY PRIMARY 12 const 1 100.00 Using index
|
||||
1 SIMPLE t1 ref code code 13 const 3 100.00 Using where; Using index
|
||||
1 SIMPLE t2 ref PRIMARY PRIMARY 12 const 1 100.00 Using where; Using index
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`code` AS `code`,`test`.`t2`.`id` AS `id` from `test`.`t1` join `test`.`t2` where ((`test`.`t1`.`code` = _latin1'a12') and (`test`.`t2`.`id` = _latin1'a12') and (length(`test`.`t1`.`code`) = 5))
|
||||
Note 1003 select `test`.`t1`.`code` AS `code`,`test`.`t2`.`id` AS `id` from `test`.`t1` join `test`.`t2` where ((`test`.`t1`.`code` = _latin1'a12') and (length(`test`.`t1`.`code`) = 5))
|
||||
DROP TABLE t1,t2;
|
||||
End of 5.0 tests
|
||||
|
|
|
@ -862,3 +862,14 @@ CHECK TABLE t1 EXTENDED;
|
|||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (foo GEOMETRY NOT NULL, SPATIAL INDEX(foo) );
|
||||
INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(1,1)));
|
||||
INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(1,0)));
|
||||
INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(0,1)));
|
||||
INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(0,0)));
|
||||
SELECT 1 FROM t1 WHERE foo != PointFromWKB(POINT(0,0));
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -303,10 +303,10 @@ spid sum(userid)
|
|||
1 1
|
||||
explain select sql_big_result score,count(*) from t1 group by score desc;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL score 3 NULL 8 Using index
|
||||
1 SIMPLE t1 index NULL score 3 NULL 8 Using index; Using filesort
|
||||
explain select sql_big_result score,count(*) from t1 group by score desc order by null;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL score 3 NULL 8 Using index
|
||||
1 SIMPLE t1 index NULL score 3 NULL 8 Using index; Using filesort
|
||||
select sql_big_result score,count(*) from t1 group by score desc;
|
||||
score count(*)
|
||||
3 5
|
||||
|
@ -775,6 +775,55 @@ select sql_buffer_result max(f1)+1 from t1;
|
|||
max(f1)+1
|
||||
3
|
||||
drop table t1;
|
||||
CREATE TABLE t1(a INT);
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
SELECT a FROM t1 GROUP BY 'a';
|
||||
a
|
||||
1
|
||||
SELECT a FROM t1 GROUP BY "a";
|
||||
a
|
||||
1
|
||||
SELECT a FROM t1 GROUP BY `a`;
|
||||
a
|
||||
1
|
||||
2
|
||||
set sql_mode=ANSI_QUOTES;
|
||||
SELECT a FROM t1 GROUP BY "a";
|
||||
a
|
||||
1
|
||||
2
|
||||
SELECT a FROM t1 GROUP BY 'a';
|
||||
a
|
||||
1
|
||||
SELECT a FROM t1 GROUP BY `a`;
|
||||
a
|
||||
1
|
||||
2
|
||||
set sql_mode='';
|
||||
SELECT a FROM t1 HAVING 'a' > 1;
|
||||
a
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
SELECT a FROM t1 HAVING "a" > 1;
|
||||
a
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
SELECT a FROM t1 HAVING `a` > 1;
|
||||
a
|
||||
2
|
||||
SELECT a FROM t1 ORDER BY 'a' DESC;
|
||||
a
|
||||
1
|
||||
2
|
||||
SELECT a FROM t1 ORDER BY "a" DESC;
|
||||
a
|
||||
1
|
||||
2
|
||||
SELECT a FROM t1 ORDER BY `a` DESC;
|
||||
a
|
||||
2
|
||||
1
|
||||
DROP TABLE t1;
|
||||
create table t1 (c1 char(3), c2 char(3));
|
||||
create table t2 (c3 char(3), c4 char(3));
|
||||
insert into t1 values ('aaa', 'bb1'), ('aaa', 'bb2');
|
||||
|
@ -821,6 +870,69 @@ a b real_b
|
|||
68 France France
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1,t2;
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY, b INT, key (b));
|
||||
INSERT INTO t1 VALUES (1, 1);
|
||||
INSERT INTO t1 SELECT a + 1 , MOD(a + 1 , 20) FROM t1;
|
||||
INSERT INTO t1 SELECT a + 2 , MOD(a + 2 , 20) FROM t1;
|
||||
INSERT INTO t1 SELECT a + 4 , MOD(a + 4 , 20) FROM t1;
|
||||
INSERT INTO t1 SELECT a + 8 , MOD(a + 8 , 20) FROM t1;
|
||||
INSERT INTO t1 SELECT a + 16, MOD(a + 16, 20) FROM t1;
|
||||
INSERT INTO t1 SELECT a + 32, MOD(a + 32, 20) FROM t1;
|
||||
INSERT INTO t1 SELECT a + 64, MOD(a + 64, 20) FROM t1;
|
||||
SELECT MIN(b), MAX(b) from t1;
|
||||
MIN(b) MAX(b)
|
||||
0 19
|
||||
EXPLAIN SELECT b, sum(1) FROM t1 GROUP BY b;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL b 5 NULL 128 Using index
|
||||
EXPLAIN SELECT SQL_BIG_RESULT b, sum(1) FROM t1 GROUP BY b;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL b 5 NULL 128 Using index; Using filesort
|
||||
SELECT b, sum(1) FROM t1 GROUP BY b;
|
||||
b sum(1)
|
||||
0 6
|
||||
1 7
|
||||
2 7
|
||||
3 7
|
||||
4 7
|
||||
5 7
|
||||
6 7
|
||||
7 7
|
||||
8 7
|
||||
9 6
|
||||
10 6
|
||||
11 6
|
||||
12 6
|
||||
13 6
|
||||
14 6
|
||||
15 6
|
||||
16 6
|
||||
17 6
|
||||
18 6
|
||||
19 6
|
||||
SELECT SQL_BIG_RESULT b, sum(1) FROM t1 GROUP BY b;
|
||||
b sum(1)
|
||||
0 6
|
||||
1 7
|
||||
2 7
|
||||
3 7
|
||||
4 7
|
||||
5 7
|
||||
6 7
|
||||
7 7
|
||||
8 7
|
||||
9 6
|
||||
10 6
|
||||
11 6
|
||||
12 6
|
||||
13 6
|
||||
14 6
|
||||
15 6
|
||||
16 6
|
||||
17 6
|
||||
18 6
|
||||
19 6
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a INT, b INT, KEY(a));
|
||||
INSERT INTO t1 VALUES (1, 1), (2, 2), (3,3), (4,4);
|
||||
EXPLAIN SELECT a, SUM(b) FROM t1 GROUP BY a LIMIT 2;
|
||||
|
|
|
@ -2162,3 +2162,23 @@ t1;
|
|||
id2 id3 id5 id4 id3 id6 id5 id1
|
||||
1 1 1 1 1 1 1 1
|
||||
DROP TABLE t1,t2,t3,t4,t5,t6;
|
||||
CREATE TABLE t1 (a int, b int, PRIMARY KEY (a,b), KEY b (b));
|
||||
INSERT INTO t1 VALUES (1,1),(1,2),(1,0),(1,3);
|
||||
explain SELECT MAX(b), a FROM t1 WHERE b < 2 AND a = 1 GROUP BY a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range PRIMARY,b PRIMARY 8 NULL 1 Using where; Using index for group-by
|
||||
SELECT MAX(b), a FROM t1 WHERE b < 2 AND a = 1 GROUP BY a;
|
||||
MAX(b) a
|
||||
1 1
|
||||
SELECT MIN(b), a FROM t1 WHERE b > 1 AND a = 1 GROUP BY a;
|
||||
MIN(b) a
|
||||
2 1
|
||||
CREATE TABLE t2 (a int, b int, c int, PRIMARY KEY (a,b,c));
|
||||
INSERT INTO t2 SELECT a,b,b FROM t1;
|
||||
explain SELECT MIN(c) FROM t2 WHERE b = 2 and a = 1 and c > 1 GROUP BY a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 range PRIMARY PRIMARY 12 NULL 1 Using where; Using index for group-by
|
||||
SELECT MIN(c) FROM t2 WHERE b = 2 and a = 1 and c > 1 GROUP BY a;
|
||||
MIN(c)
|
||||
2
|
||||
DROP TABLE t1,t2;
|
||||
|
|
|
@ -2063,15 +2063,15 @@ i 10
|
|||
select sql_big_result v,count(c) from t1 group by v limit 10;
|
||||
v count(c)
|
||||
a 1
|
||||
a 10
|
||||
b 10
|
||||
c 10
|
||||
d 10
|
||||
e 10
|
||||
f 10
|
||||
g 10
|
||||
a 10
|
||||
b 10
|
||||
c 10
|
||||
d 10
|
||||
e 10
|
||||
f 10
|
||||
g 10
|
||||
h 10
|
||||
i 10
|
||||
i 10
|
||||
select c,count(*) from t1 group by c limit 10;
|
||||
c count(*)
|
||||
a 1
|
||||
|
|
|
@ -290,6 +290,22 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
1 SIMPLE t2 index NULL fkey 5 NULL 5 Using index
|
||||
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.fkey 1 Using where
|
||||
DROP TABLE t1,t2;
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c FLOAT, KEY b(b)) ENGINE = INNODB;
|
||||
INSERT INTO t1 VALUES ( 1 , 1 , 1);
|
||||
INSERT INTO t1 SELECT a + 1 , MOD(a + 1 , 20), 1 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 2 , MOD(a + 2 , 20), 1 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 4 , MOD(a + 4 , 20), 1 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 8 , MOD(a + 8 , 20), 1 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 16, MOD(a + 16, 20), 1 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 32, MOD(a + 32, 20), 1 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 64, MOD(a + 64, 20), 1 FROM t1;
|
||||
EXPLAIN SELECT b, SUM(c) FROM t1 GROUP BY b;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL b 5 NULL 128
|
||||
EXPLAIN SELECT SQL_BIG_RESULT b, SUM(c) FROM t1 GROUP BY b;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 128 Using filesort
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a int, b int);
|
||||
insert into t1 values (1,1),(1,2);
|
||||
CREATE TABLE t2 (primary key (a)) select * from t1;
|
||||
|
|
|
@ -629,7 +629,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
EXPLAIN SELECT * FROM t2 WHERE fileset_id = 2
|
||||
AND file_code = '0000000115' LIMIT 1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ref PRIMARY,files PRIMARY 35 const,const 1 Using where
|
||||
1 SIMPLE t2 const PRIMARY,files PRIMARY 35 const,const 1
|
||||
DROP TABLE t2, t1;
|
||||
create table t1 (x int, y int, index xy(x, y));
|
||||
create table t2 (x int, y int, index xy(x, y));
|
||||
|
|
|
@ -1611,15 +1611,15 @@ i 10
|
|||
select sql_big_result v,count(c) from t1 group by v limit 10;
|
||||
v count(c)
|
||||
a 1
|
||||
a 10
|
||||
b 10
|
||||
c 10
|
||||
d 10
|
||||
e 10
|
||||
f 10
|
||||
g 10
|
||||
a 10
|
||||
b 10
|
||||
c 10
|
||||
d 10
|
||||
e 10
|
||||
f 10
|
||||
g 10
|
||||
h 10
|
||||
i 10
|
||||
i 10
|
||||
select c,count(*) from t1 group by c limit 10;
|
||||
c count(*)
|
||||
a 1
|
||||
|
|
|
@ -796,6 +796,132 @@ a b
|
|||
xxxxxxxxx bbbbbb
|
||||
xxxxxxxxx bbbbbb
|
||||
DROP TABLE t1;
|
||||
SET @@myisam_repair_threads=2;
|
||||
SHOW VARIABLES LIKE 'myisam_repair%';
|
||||
Variable_name Value
|
||||
myisam_repair_threads 2
|
||||
CREATE TABLE t1 (
|
||||
`_id` int(11) NOT NULL default '0',
|
||||
`url` text,
|
||||
`email` text,
|
||||
`description` text,
|
||||
`loverlap` int(11) default NULL,
|
||||
`roverlap` int(11) default NULL,
|
||||
`lneighbor_id` int(11) default NULL,
|
||||
`rneighbor_id` int(11) default NULL,
|
||||
`length_` int(11) default NULL,
|
||||
`sequence` mediumtext,
|
||||
`name` text,
|
||||
`_obj_class` text NOT NULL,
|
||||
PRIMARY KEY (`_id`),
|
||||
UNIQUE KEY `sequence_name_index` (`name`(50)),
|
||||
KEY (`length_`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
INSERT INTO t1 VALUES
|
||||
(1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample1',''),
|
||||
(2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample2',''),
|
||||
(3,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample3',''),
|
||||
(4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample4',''),
|
||||
(5,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample5',''),
|
||||
(6,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample6',''),
|
||||
(7,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample7',''),
|
||||
(8,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample8',''),
|
||||
(9,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample9','');
|
||||
SELECT _id FROM t1;
|
||||
_id
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
DELETE FROM t1 WHERE _id < 8;
|
||||
SHOW TABLE STATUS LIKE 't1';
|
||||
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||
t1 MyISAM 10 Dynamic 2 # # # # 140 # # # # # #
|
||||
CHECK TABLE t1 EXTENDED;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
OPTIMIZE TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 optimize status OK
|
||||
CHECK TABLE t1 EXTENDED;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
SHOW TABLE STATUS LIKE 't1';
|
||||
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||
t1 MyISAM 10 Dynamic 2 # # # # 0 # # # # # #
|
||||
SELECT _id FROM t1;
|
||||
_id
|
||||
8
|
||||
9
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (
|
||||
`_id` int(11) NOT NULL default '0',
|
||||
`url` text,
|
||||
`email` text,
|
||||
`description` text,
|
||||
`loverlap` int(11) default NULL,
|
||||
`roverlap` int(11) default NULL,
|
||||
`lneighbor_id` int(11) default NULL,
|
||||
`rneighbor_id` int(11) default NULL,
|
||||
`length_` int(11) default NULL,
|
||||
`sequence` mediumtext,
|
||||
`name` text,
|
||||
`_obj_class` text NOT NULL,
|
||||
PRIMARY KEY (`_id`),
|
||||
UNIQUE KEY `sequence_name_index` (`name`(50)),
|
||||
KEY (`length_`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
INSERT INTO t1 VALUES
|
||||
(1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample1',''),
|
||||
(2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample2',''),
|
||||
(3,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample3',''),
|
||||
(4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample4',''),
|
||||
(5,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample5',''),
|
||||
(6,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample6',''),
|
||||
(7,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample7',''),
|
||||
(8,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample8',''),
|
||||
(9,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample9','');
|
||||
SELECT _id FROM t1;
|
||||
_id
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
DELETE FROM t1 WHERE _id < 8;
|
||||
SHOW TABLE STATUS LIKE 't1';
|
||||
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||
t1 MyISAM 10 Dynamic 2 # # # # 140 # # # # # #
|
||||
CHECK TABLE t1 EXTENDED;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
REPAIR TABLE t1 QUICK;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 repair status OK
|
||||
CHECK TABLE t1 EXTENDED;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
SHOW TABLE STATUS LIKE 't1';
|
||||
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||
t1 MyISAM 10 Dynamic 2 # # # # 140 # # # # # #
|
||||
SELECT _id FROM t1;
|
||||
_id
|
||||
8
|
||||
9
|
||||
DROP TABLE t1;
|
||||
SET @@myisam_repair_threads=1;
|
||||
SHOW VARIABLES LIKE 'myisam_repair%';
|
||||
Variable_name Value
|
||||
myisam_repair_threads 1
|
||||
set storage_engine=MyISAM;
|
||||
drop table if exists t1,t2,t3;
|
||||
--- Testing varchar ---
|
||||
|
@ -1002,15 +1128,15 @@ i 10
|
|||
select sql_big_result v,count(c) from t1 group by v limit 10;
|
||||
v count(c)
|
||||
a 1
|
||||
a 10
|
||||
b 10
|
||||
c 10
|
||||
d 10
|
||||
e 10
|
||||
f 10
|
||||
g 10
|
||||
a 10
|
||||
b 10
|
||||
c 10
|
||||
d 10
|
||||
e 10
|
||||
f 10
|
||||
g 10
|
||||
h 10
|
||||
i 10
|
||||
i 10
|
||||
select c,count(*) from t1 group by c limit 10;
|
||||
c count(*)
|
||||
a 1
|
||||
|
|
|
@ -592,6 +592,21 @@ a max(b)
|
|||
NULL 2
|
||||
a 1
|
||||
drop table t1;
|
||||
create table t1 (a varchar(22) not null , b int);
|
||||
insert into t1 values ("2006-07-01 21:30", 1), ("2006-07-01 23:30", 10);
|
||||
select left(a,10), a, sum(b) from t1 group by 1,2 with rollup;
|
||||
left(a,10) a sum(b)
|
||||
2006-07-01 2006-07-01 21:30 1
|
||||
2006-07-01 2006-07-01 23:30 10
|
||||
2006-07-01 NULL 11
|
||||
NULL NULL 11
|
||||
select left(a,10) x, a, sum(b) from t1 group by x,a with rollup;
|
||||
x a sum(b)
|
||||
2006-07-01 2006-07-01 21:30 1
|
||||
2006-07-01 2006-07-01 23:30 10
|
||||
2006-07-01 NULL 11
|
||||
NULL NULL 11
|
||||
drop table t1;
|
||||
CREATE TABLE t1(id int, type char(1));
|
||||
INSERT INTO t1 VALUES
|
||||
(1,"A"),(2,"C"),(3,"A"),(4,"A"),(5,"B"),
|
||||
|
|
|
@ -499,54 +499,6 @@ create temporary table if not exists t1 (a1 int);
|
|||
execute stmt;
|
||||
drop temporary table t1;
|
||||
deallocate prepare stmt;
|
||||
CREATE TABLE t1(
|
||||
ID int(10) unsigned NOT NULL auto_increment,
|
||||
Member_ID varchar(15) NOT NULL default '',
|
||||
Action varchar(12) NOT NULL,
|
||||
Action_Date datetime NOT NULL,
|
||||
Track varchar(15) default NULL,
|
||||
User varchar(12) default NULL,
|
||||
Date_Updated timestamp NOT NULL default CURRENT_TIMESTAMP on update
|
||||
CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (ID),
|
||||
KEY Action (Action),
|
||||
KEY Action_Date (Action_Date)
|
||||
);
|
||||
INSERT INTO t1(Member_ID, Action, Action_Date, Track) VALUES
|
||||
('111111', 'Disenrolled', '2006-03-01', 'CAD' ),
|
||||
('111111', 'Enrolled', '2006-03-01', 'CAD' ),
|
||||
('111111', 'Disenrolled', '2006-07-03', 'CAD' ),
|
||||
('222222', 'Enrolled', '2006-03-07', 'CAD' ),
|
||||
('222222', 'Enrolled', '2006-03-07', 'CHF' ),
|
||||
('222222', 'Disenrolled', '2006-08-02', 'CHF' ),
|
||||
('333333', 'Enrolled', '2006-03-01', 'CAD' ),
|
||||
('333333', 'Disenrolled', '2006-03-01', 'CAD' ),
|
||||
('444444', 'Enrolled', '2006-03-01', 'CAD' ),
|
||||
('555555', 'Disenrolled', '2006-03-01', 'CAD' ),
|
||||
('555555', 'Enrolled', '2006-07-21', 'CAD' ),
|
||||
('555555', 'Disenrolled', '2006-03-01', 'CHF' ),
|
||||
('666666', 'Enrolled', '2006-02-09', 'CAD' ),
|
||||
('666666', 'Enrolled', '2006-05-12', 'CHF' ),
|
||||
('666666', 'Disenrolled', '2006-06-01', 'CAD' );
|
||||
PREPARE STMT FROM
|
||||
"SELECT GROUP_CONCAT(Track SEPARATOR ', ') FROM t1
|
||||
WHERE Member_ID=? AND Action='Enrolled' AND
|
||||
(Track,Action_Date) IN (SELECT Track, MAX(Action_Date) FROM t1
|
||||
WHERE Member_ID=?
|
||||
GROUP BY Track
|
||||
HAVING Track>='CAD' AND
|
||||
MAX(Action_Date)>'2006-03-01')";
|
||||
SET @id='111111';
|
||||
EXECUTE STMT USING @id,@id;
|
||||
GROUP_CONCAT(Track SEPARATOR ', ')
|
||||
NULL
|
||||
SET @id='222222';
|
||||
EXECUTE STMT USING @id,@id;
|
||||
GROUP_CONCAT(Track SEPARATOR ', ')
|
||||
CAD
|
||||
DEALLOCATE PREPARE STMT;
|
||||
DROP TABLE t1;
|
||||
End of 4.1 tests
|
||||
create table t1 (a varchar(20));
|
||||
insert into t1 values ('foo');
|
||||
prepare stmt FROM 'SELECT char_length (a) FROM t1';
|
||||
|
@ -564,77 +516,6 @@ SELECT FOUND_ROWS();
|
|||
FOUND_ROWS()
|
||||
2
|
||||
deallocate prepare stmt;
|
||||
create table t1 (a char(3) not null, b char(3) not null,
|
||||
c char(3) not null, primary key (a, b, c));
|
||||
create table t2 like t1;
|
||||
prepare stmt from
|
||||
"select t1.a from (t1 left outer join t2 on t2.a=1 and t1.b=t2.b)
|
||||
where t1.a=1";
|
||||
execute stmt;
|
||||
a
|
||||
execute stmt;
|
||||
a
|
||||
execute stmt;
|
||||
a
|
||||
prepare stmt from
|
||||
"select t1.a, t1.b, t1.c, t2.a, t2.b, t2.c from
|
||||
(t1 left outer join t2 on t2.a=? and t1.b=t2.b)
|
||||
left outer join t2 t3 on t3.a=? where t1.a=?";
|
||||
set @a:=1, @b:=1, @c:=1;
|
||||
execute stmt using @a, @b, @c;
|
||||
a b c a b c
|
||||
execute stmt using @a, @b, @c;
|
||||
a b c a b c
|
||||
execute stmt using @a, @b, @c;
|
||||
a b c a b c
|
||||
deallocate prepare stmt;
|
||||
drop table t1,t2;
|
||||
SET @aux= "SELECT COUNT(*)
|
||||
FROM INFORMATION_SCHEMA.COLUMNS A,
|
||||
INFORMATION_SCHEMA.COLUMNS B
|
||||
WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA
|
||||
AND A.TABLE_NAME = B.TABLE_NAME
|
||||
AND A.COLUMN_NAME = B.COLUMN_NAME AND
|
||||
A.TABLE_NAME = 'user'";
|
||||
prepare my_stmt from @aux;
|
||||
execute my_stmt;
|
||||
COUNT(*)
|
||||
39
|
||||
execute my_stmt;
|
||||
COUNT(*)
|
||||
39
|
||||
execute my_stmt;
|
||||
COUNT(*)
|
||||
39
|
||||
deallocate prepare my_stmt;
|
||||
drop procedure if exists p1|
|
||||
drop table if exists t1|
|
||||
create table t1 (id int)|
|
||||
insert into t1 values(1)|
|
||||
create procedure p1(a int, b int)
|
||||
begin
|
||||
declare c int;
|
||||
select max(id)+1 into c from t1;
|
||||
insert into t1 select a+b;
|
||||
insert into t1 select a-b;
|
||||
insert into t1 select a-c;
|
||||
end|
|
||||
set @a= 3, @b= 4|
|
||||
prepare stmt from "call p1(?, ?)"|
|
||||
execute stmt using @a, @b|
|
||||
execute stmt using @a, @b|
|
||||
select * from t1|
|
||||
id
|
||||
1
|
||||
7
|
||||
-1
|
||||
1
|
||||
7
|
||||
-1
|
||||
-5
|
||||
deallocate prepare stmt|
|
||||
drop procedure p1|
|
||||
drop table t1|
|
||||
drop table if exists t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
|
@ -698,47 +579,6 @@ id
|
|||
3
|
||||
deallocate prepare stmt;
|
||||
drop table t1, t2;
|
||||
create table t1 (a int);
|
||||
insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
||||
prepare stmt from "select * from t1 limit ?, ?";
|
||||
set @offset=0, @limit=1;
|
||||
execute stmt using @offset, @limit;
|
||||
a
|
||||
1
|
||||
select * from t1 limit 0, 1;
|
||||
a
|
||||
1
|
||||
set @offset=3, @limit=2;
|
||||
execute stmt using @offset, @limit;
|
||||
a
|
||||
4
|
||||
5
|
||||
select * from t1 limit 3, 2;
|
||||
a
|
||||
4
|
||||
5
|
||||
prepare stmt from "select * from t1 limit ?";
|
||||
execute stmt using @limit;
|
||||
a
|
||||
1
|
||||
2
|
||||
prepare stmt from "select * from t1 where a in (select a from t1 limit ?)";
|
||||
ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
|
||||
prepare stmt from "select * from t1 union all select * from t1 limit ?, ?";
|
||||
set @offset=9;
|
||||
set @limit=2;
|
||||
execute stmt using @offset, @limit;
|
||||
a
|
||||
10
|
||||
1
|
||||
prepare stmt from "(select * from t1 limit ?, ?) union all
|
||||
(select * from t1 limit ?, ?) order by a limit ?";
|
||||
execute stmt using @offset, @limit, @offset, @limit, @limit;
|
||||
a
|
||||
10
|
||||
10
|
||||
drop table t1;
|
||||
deallocate prepare stmt;
|
||||
create table t1 (id int);
|
||||
prepare stmt from "insert into t1 (id) select id from t1 union select id from t1";
|
||||
execute stmt;
|
||||
|
@ -839,15 +679,6 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
|
|||
select ? from t1;
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? from t1' at line 1
|
||||
drop table t1;
|
||||
CREATE TABLE b12651_T1(a int) ENGINE=MYISAM;
|
||||
CREATE TABLE b12651_T2(b int) ENGINE=MYISAM;
|
||||
CREATE VIEW b12651_V1 as SELECT b FROM b12651_T2;
|
||||
PREPARE b12651 FROM 'SELECT 1 FROM b12651_T1 WHERE a IN (SELECT b FROM b12651_V1)';
|
||||
EXECUTE b12651;
|
||||
1
|
||||
DROP VIEW b12651_V1;
|
||||
DROP TABLE b12651_T1, b12651_T2;
|
||||
DEALLOCATE PREPARE b12651;
|
||||
prepare stmt from "select @@time_zone";
|
||||
execute stmt;
|
||||
@@time_zone
|
||||
|
@ -1064,6 +895,194 @@ select @@max_prepared_stmt_count, @@prepared_stmt_count;
|
|||
@@max_prepared_stmt_count @@prepared_stmt_count
|
||||
3 0
|
||||
set global max_prepared_stmt_count= @old_max_prepared_stmt_count;
|
||||
drop table if exists t1;
|
||||
create temporary table if not exists t1 (a1 int);
|
||||
prepare stmt from "delete t1 from t1 where (cast(a1/3 as unsigned) * 3) = a1";
|
||||
drop temporary table t1;
|
||||
create temporary table if not exists t1 (a1 int);
|
||||
execute stmt;
|
||||
drop temporary table t1;
|
||||
create temporary table if not exists t1 (a1 int);
|
||||
execute stmt;
|
||||
drop temporary table t1;
|
||||
create temporary table if not exists t1 (a1 int);
|
||||
execute stmt;
|
||||
drop temporary table t1;
|
||||
deallocate prepare stmt;
|
||||
CREATE TABLE t1(
|
||||
ID int(10) unsigned NOT NULL auto_increment,
|
||||
Member_ID varchar(15) NOT NULL default '',
|
||||
Action varchar(12) NOT NULL,
|
||||
Action_Date datetime NOT NULL,
|
||||
Track varchar(15) default NULL,
|
||||
User varchar(12) default NULL,
|
||||
Date_Updated timestamp NOT NULL default CURRENT_TIMESTAMP on update
|
||||
CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (ID),
|
||||
KEY Action (Action),
|
||||
KEY Action_Date (Action_Date)
|
||||
);
|
||||
INSERT INTO t1(Member_ID, Action, Action_Date, Track) VALUES
|
||||
('111111', 'Disenrolled', '2006-03-01', 'CAD' ),
|
||||
('111111', 'Enrolled', '2006-03-01', 'CAD' ),
|
||||
('111111', 'Disenrolled', '2006-07-03', 'CAD' ),
|
||||
('222222', 'Enrolled', '2006-03-07', 'CAD' ),
|
||||
('222222', 'Enrolled', '2006-03-07', 'CHF' ),
|
||||
('222222', 'Disenrolled', '2006-08-02', 'CHF' ),
|
||||
('333333', 'Enrolled', '2006-03-01', 'CAD' ),
|
||||
('333333', 'Disenrolled', '2006-03-01', 'CAD' ),
|
||||
('444444', 'Enrolled', '2006-03-01', 'CAD' ),
|
||||
('555555', 'Disenrolled', '2006-03-01', 'CAD' ),
|
||||
('555555', 'Enrolled', '2006-07-21', 'CAD' ),
|
||||
('555555', 'Disenrolled', '2006-03-01', 'CHF' ),
|
||||
('666666', 'Enrolled', '2006-02-09', 'CAD' ),
|
||||
('666666', 'Enrolled', '2006-05-12', 'CHF' ),
|
||||
('666666', 'Disenrolled', '2006-06-01', 'CAD' );
|
||||
PREPARE STMT FROM
|
||||
"SELECT GROUP_CONCAT(Track SEPARATOR ', ') FROM t1
|
||||
WHERE Member_ID=? AND Action='Enrolled' AND
|
||||
(Track,Action_Date) IN (SELECT Track, MAX(Action_Date) FROM t1
|
||||
WHERE Member_ID=?
|
||||
GROUP BY Track
|
||||
HAVING Track>='CAD' AND
|
||||
MAX(Action_Date)>'2006-03-01')";
|
||||
SET @id='111111';
|
||||
EXECUTE STMT USING @id,@id;
|
||||
GROUP_CONCAT(Track SEPARATOR ', ')
|
||||
NULL
|
||||
SET @id='222222';
|
||||
EXECUTE STMT USING @id,@id;
|
||||
GROUP_CONCAT(Track SEPARATOR ', ')
|
||||
CAD
|
||||
DEALLOCATE PREPARE STMT;
|
||||
DROP TABLE t1;
|
||||
End of 4.1 tests
|
||||
create table t1 (a varchar(20));
|
||||
insert into t1 values ('foo');
|
||||
prepare stmt FROM 'SELECT char_length (a) FROM t1';
|
||||
ERROR 42000: FUNCTION test.char_length does not exist
|
||||
drop table t1;
|
||||
create table t1 (a char(3) not null, b char(3) not null,
|
||||
c char(3) not null, primary key (a, b, c));
|
||||
create table t2 like t1;
|
||||
prepare stmt from
|
||||
"select t1.a from (t1 left outer join t2 on t2.a=1 and t1.b=t2.b)
|
||||
where t1.a=1";
|
||||
execute stmt;
|
||||
a
|
||||
execute stmt;
|
||||
a
|
||||
execute stmt;
|
||||
a
|
||||
prepare stmt from
|
||||
"select t1.a, t1.b, t1.c, t2.a, t2.b, t2.c from
|
||||
(t1 left outer join t2 on t2.a=? and t1.b=t2.b)
|
||||
left outer join t2 t3 on t3.a=? where t1.a=?";
|
||||
set @a:=1, @b:=1, @c:=1;
|
||||
execute stmt using @a, @b, @c;
|
||||
a b c a b c
|
||||
execute stmt using @a, @b, @c;
|
||||
a b c a b c
|
||||
execute stmt using @a, @b, @c;
|
||||
a b c a b c
|
||||
deallocate prepare stmt;
|
||||
drop table t1,t2;
|
||||
SET @aux= "SELECT COUNT(*)
|
||||
FROM INFORMATION_SCHEMA.COLUMNS A,
|
||||
INFORMATION_SCHEMA.COLUMNS B
|
||||
WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA
|
||||
AND A.TABLE_NAME = B.TABLE_NAME
|
||||
AND A.COLUMN_NAME = B.COLUMN_NAME AND
|
||||
A.TABLE_NAME = 'user'";
|
||||
prepare my_stmt from @aux;
|
||||
execute my_stmt;
|
||||
COUNT(*)
|
||||
39
|
||||
execute my_stmt;
|
||||
COUNT(*)
|
||||
39
|
||||
execute my_stmt;
|
||||
COUNT(*)
|
||||
39
|
||||
deallocate prepare my_stmt;
|
||||
drop procedure if exists p1|
|
||||
drop table if exists t1|
|
||||
create table t1 (id int)|
|
||||
insert into t1 values(1)|
|
||||
create procedure p1(a int, b int)
|
||||
begin
|
||||
declare c int;
|
||||
select max(id)+1 into c from t1;
|
||||
insert into t1 select a+b;
|
||||
insert into t1 select a-b;
|
||||
insert into t1 select a-c;
|
||||
end|
|
||||
set @a= 3, @b= 4|
|
||||
prepare stmt from "call p1(?, ?)"|
|
||||
execute stmt using @a, @b|
|
||||
execute stmt using @a, @b|
|
||||
select * from t1|
|
||||
id
|
||||
1
|
||||
7
|
||||
-1
|
||||
1
|
||||
7
|
||||
-1
|
||||
-5
|
||||
deallocate prepare stmt|
|
||||
drop procedure p1|
|
||||
drop table t1|
|
||||
create table t1 (a int);
|
||||
insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
||||
prepare stmt from "select * from t1 limit ?, ?";
|
||||
set @offset=0, @limit=1;
|
||||
execute stmt using @offset, @limit;
|
||||
a
|
||||
1
|
||||
select * from t1 limit 0, 1;
|
||||
a
|
||||
1
|
||||
set @offset=3, @limit=2;
|
||||
execute stmt using @offset, @limit;
|
||||
a
|
||||
4
|
||||
5
|
||||
select * from t1 limit 3, 2;
|
||||
a
|
||||
4
|
||||
5
|
||||
prepare stmt from "select * from t1 limit ?";
|
||||
execute stmt using @limit;
|
||||
a
|
||||
1
|
||||
2
|
||||
prepare stmt from "select * from t1 where a in (select a from t1 limit ?)";
|
||||
ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
|
||||
prepare stmt from "select * from t1 union all select * from t1 limit ?, ?";
|
||||
set @offset=9;
|
||||
set @limit=2;
|
||||
execute stmt using @offset, @limit;
|
||||
a
|
||||
10
|
||||
1
|
||||
prepare stmt from "(select * from t1 limit ?, ?) union all
|
||||
(select * from t1 limit ?, ?) order by a limit ?";
|
||||
execute stmt using @offset, @limit, @offset, @limit, @limit;
|
||||
a
|
||||
10
|
||||
10
|
||||
drop table t1;
|
||||
deallocate prepare stmt;
|
||||
CREATE TABLE b12651_T1(a int) ENGINE=MYISAM;
|
||||
CREATE TABLE b12651_T2(b int) ENGINE=MYISAM;
|
||||
CREATE VIEW b12651_V1 as SELECT b FROM b12651_T2;
|
||||
PREPARE b12651 FROM 'SELECT 1 FROM b12651_T1 WHERE a IN (SELECT b FROM b12651_V1)';
|
||||
EXECUTE b12651;
|
||||
1
|
||||
DROP VIEW b12651_V1;
|
||||
DROP TABLE b12651_T1, b12651_T2;
|
||||
DEALLOCATE PREPARE b12651;
|
||||
create table t1 (id int);
|
||||
prepare ins_call from "insert into t1 (id) values (1)";
|
||||
execute ins_call;
|
||||
|
@ -1365,22 +1384,26 @@ create procedure proc_1() reset query cache;
|
|||
call proc_1();
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
create function func_1() returns int begin reset query cache; return 1; end|
|
||||
ERROR 0A000: RESET is not allowed in stored function or trigger
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
ERROR 0A000: RESET is not allowed in stored function or trigger
|
||||
drop function func_1;
|
||||
drop procedure proc_1;
|
||||
prepare abc from "reset query cache";
|
||||
execute abc;
|
||||
execute abc;
|
||||
execute abc;
|
||||
deallocate prepare abc;
|
||||
create procedure proc_1() reset master;
|
||||
drop procedure proc_1;
|
||||
create function func_1() returns int begin reset master; return 1; end|
|
||||
ERROR 0A000: RESET is not allowed in stored function or trigger
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
ERROR 0A000: RESET is not allowed in stored function or trigger
|
||||
drop function func_1;
|
||||
drop procedure proc_1;
|
||||
prepare abc from "reset master";
|
||||
execute abc;
|
||||
execute abc;
|
||||
|
@ -1390,11 +1413,13 @@ create procedure proc_1() reset slave;
|
|||
call proc_1();
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
create function func_1() returns int begin reset slave; return 1; end|
|
||||
ERROR 0A000: RESET is not allowed in stored function or trigger
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
ERROR 0A000: RESET is not allowed in stored function or trigger
|
||||
drop function func_1;
|
||||
drop procedure proc_1;
|
||||
prepare abc from "reset slave";
|
||||
execute abc;
|
||||
execute abc;
|
||||
|
@ -1429,13 +1454,13 @@ call proc_1();
|
|||
call proc_1();
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
create function func_1() returns int begin flush hosts; return 1; end|
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
drop function func_1;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
drop procedure proc_1;
|
||||
prepare abc from "flush hosts";
|
||||
execute abc;
|
||||
execute abc;
|
||||
|
@ -1445,13 +1470,13 @@ create procedure proc_1() flush privileges;
|
|||
call proc_1();
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
create function func_1() returns int begin flush privileges; return 1; end|
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
drop function func_1;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
drop procedure proc_1;
|
||||
prepare abc from "flush privileges";
|
||||
deallocate prepare abc;
|
||||
create procedure proc_1() flush tables with read lock;
|
||||
|
@ -1461,9 +1486,13 @@ call proc_1();
|
|||
unlock tables;
|
||||
call proc_1();
|
||||
unlock tables;
|
||||
drop procedure proc_1;
|
||||
create function func_1() returns int begin flush tables with read lock; return 1; end|
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
drop function func_1;
|
||||
drop procedure proc_1;
|
||||
prepare abc from "flush tables with read lock";
|
||||
execute abc;
|
||||
execute abc;
|
||||
|
@ -1474,13 +1503,13 @@ create procedure proc_1() flush tables;
|
|||
call proc_1();
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
create function func_1() returns int begin flush tables; return 1; end|
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
drop function func_1;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
drop procedure proc_1;
|
||||
prepare abc from "flush tables";
|
||||
execute abc;
|
||||
execute abc;
|
||||
|
@ -1540,13 +1569,13 @@ mysql user 0 0
|
|||
mysql general_log 1 0
|
||||
mysql host 0 0
|
||||
flush tables;
|
||||
drop procedure proc_1;
|
||||
create function func_1() returns int begin flush tables; return 1; end|
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
drop function func_1;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
drop procedure proc_1;
|
||||
flush tables;
|
||||
select Host, User from mysql.user limit 0;
|
||||
Host User
|
||||
|
@ -1603,13 +1632,13 @@ create procedure proc_1() flush logs;
|
|||
call proc_1();
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
create function func_1() returns int begin flush logs; return 1; end|
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
drop function func_1;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
drop procedure proc_1;
|
||||
prepare abc from "flush logs";
|
||||
execute abc;
|
||||
execute abc;
|
||||
|
@ -1619,13 +1648,13 @@ create procedure proc_1() flush status;
|
|||
call proc_1();
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
create function func_1() returns int begin flush status; return 1; end|
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
drop function func_1;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
drop procedure proc_1;
|
||||
prepare abc from "flush status";
|
||||
execute abc;
|
||||
execute abc;
|
||||
|
@ -1635,39 +1664,39 @@ create procedure proc_1() flush slave;
|
|||
call proc_1();
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
create function func_1() returns int begin flush slave; return 1; end|
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
drop function func_1;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
drop procedure proc_1;
|
||||
prepare abc from "flush slave";
|
||||
execute abc;
|
||||
execute abc;
|
||||
execute abc;
|
||||
deallocate prepare abc;
|
||||
create procedure proc_1() flush master;
|
||||
drop procedure proc_1;
|
||||
create function func_1() returns int begin flush master; return 1; end|
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
drop function func_1;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
drop procedure proc_1;
|
||||
prepare abc from "flush master";
|
||||
deallocate prepare abc;
|
||||
create procedure proc_1() flush des_key_file;
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
create function func_1() returns int begin flush des_key_file; return 1; end|
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
drop function func_1;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
drop procedure proc_1;
|
||||
prepare abc from "flush des_key_file";
|
||||
execute abc;
|
||||
execute abc;
|
||||
|
@ -1677,13 +1706,13 @@ create procedure proc_1() flush user_resources;
|
|||
call proc_1();
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
create function func_1() returns int begin flush user_resources; return 1; end|
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
ERROR 0A000: FLUSH is not allowed in stored function or trigger
|
||||
drop function func_1;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
drop procedure proc_1;
|
||||
prepare abc from "flush user_resources";
|
||||
execute abc;
|
||||
execute abc;
|
||||
|
@ -1763,18 +1792,6 @@ Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
|
|||
execute abc;
|
||||
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
|
||||
deallocate prepare abc;
|
||||
create procedure proc_1() show scheduler status;
|
||||
drop procedure proc_1;
|
||||
create function func_1() returns int begin show scheduler status; return 1; end|
|
||||
ERROR 0A000: Not allowed to return a result set from a function
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
drop function func_1;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
prepare abc from "show scheduler status";
|
||||
ERROR HY000: This command is not supported in the prepared statement protocol yet
|
||||
deallocate prepare abc;
|
||||
ERROR HY000: Unknown prepared statement handler (abc) given to DEALLOCATE PREPARE
|
||||
drop procedure if exists a;
|
||||
create procedure a() select 42;
|
||||
create procedure proc_1(a char(2)) show create procedure a;
|
||||
|
@ -1952,11 +1969,11 @@ ERROR HY000: No paths allowed for shared library
|
|||
drop procedure proc_1;
|
||||
create procedure proc_1() install plugin my_plug soname 'some_plugin.so';
|
||||
call proc_1();
|
||||
ERROR HY000: Can't open shared library '/work/mysql-5.1-runtime/mysql-test/lib/mysql/some_plugin.so' (errno: 0 cannot open shared object file: No such file or directory)
|
||||
ERROR HY000: Can't open shared library
|
||||
call proc_1();
|
||||
ERROR HY000: Can't open shared library '/work/mysql-5.1-runtime/mysql-test/lib/mysql/some_plugin.so' (errno: 22 cannot open shared object file: No such file or directory)
|
||||
ERROR HY000: Can't open shared library
|
||||
call proc_1();
|
||||
ERROR HY000: Can't open shared library '/work/mysql-5.1-runtime/mysql-test/lib/mysql/some_plugin.so' (errno: 22 cannot open shared object file: No such file or directory)
|
||||
ERROR HY000: Can't open shared library
|
||||
drop procedure proc_1;
|
||||
create function func_1() returns int begin install plugin my_plug soname '/tmp/plugin'; return 1; end|
|
||||
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
|
||||
|
@ -2086,7 +2103,7 @@ drop user pstest_xyz@localhost;
|
|||
deallocate prepare abc;
|
||||
drop event if exists xyz;
|
||||
create function func_1() returns int begin create event xyz on schedule at now() do select 123; return 1; end|
|
||||
ERROR 0A000: Not allowed to return a result set from a function
|
||||
ERROR HY000: Recursivity of EVENT DDL statements is forbidden when body is present
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
ERROR 42000: FUNCTION test.func_1 does not exist
|
||||
drop function func_1;
|
||||
|
|
|
@ -54,3 +54,13 @@ Tables_in_test
|
|||
t2
|
||||
t4
|
||||
drop table t2, t4;
|
||||
create table t1(f1 int);
|
||||
create view v1 as select * from t1;
|
||||
alter table v1 rename to v2;
|
||||
alter table v1 rename to v2;
|
||||
ERROR 42S02: Table 'test.v1' doesn't exist
|
||||
rename table v2 to v1;
|
||||
rename table v2 to v1;
|
||||
ERROR 42S01: Table 'v1' already exists
|
||||
drop view v1;
|
||||
drop table t1;
|
||||
|
|
|
@ -52,6 +52,44 @@ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_par
|
|||
t1 1 a 1 a A 5 NULL NULL YES BTREE
|
||||
SET myisam_repair_threads=@@global.myisam_repair_threads;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(a INT);
|
||||
USE mysql;
|
||||
REPAIR TABLE test.t1 USE_FRM;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 repair status OK
|
||||
USE test;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(a CHAR(255), KEY(a));
|
||||
SET myisam_sort_buffer_size=4096;
|
||||
INSERT INTO t1 VALUES
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0');
|
||||
Warnings:
|
||||
Error 1034 sort_buffer_size is to small
|
||||
Error 1034 Number of rows changed from 0 to 157
|
||||
SET myisam_repair_threads=2;
|
||||
REPAIR TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 repair error sort_buffer_size is to small
|
||||
test.t1 repair warning Number of rows changed from 0 to 157
|
||||
test.t1 repair status OK
|
||||
SET myisam_repair_threads=@@global.myisam_repair_threads;
|
||||
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
|
||||
DROP TABLE t1;
|
||||
DROP TABLE IF EXISTS tt1;
|
||||
CREATE TEMPORARY TABLE tt1 (c1 INT);
|
||||
REPAIR TABLE tt1 USE_FRM;
|
||||
|
|
|
@ -3517,3 +3517,97 @@ id a b c d e
|
|||
2 NULL NULL NULL 2 40
|
||||
2 NULL NULL NULL 2 50
|
||||
DROP TABLE t1,t2,t3;
|
||||
create table t1 (c1 varchar(1), c2 int, c3 int, c4 int, c5 int, c6 int,
|
||||
c7 int, c8 int, c9 int, fulltext key (`c1`));
|
||||
select distinct match (`c1`) against ('z') , c2, c3, c4,c5, c6,c7, c8
|
||||
from t1 where c9=1 order by c2, c2;
|
||||
match (`c1`) against ('z') c2 c3 c4 c5 c6 c7 c8
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (pk varchar(10) PRIMARY KEY, fk varchar(16));
|
||||
CREATE TABLE t2 (pk varchar(16) PRIMARY KEY, fk varchar(10));
|
||||
INSERT INTO t1 VALUES
|
||||
('d','dddd'), ('i','iii'), ('a','aa'), ('b','bb'), ('g','gg'),
|
||||
('e','eee'), ('c','cccc'), ('h','hhh'), ('j','jjj'), ('f','fff');
|
||||
INSERT INTO t2 VALUES
|
||||
('jjj', 'j'), ('cc','c'), ('ccc','c'), ('aaa', 'a'), ('jjjj','j'),
|
||||
('hhh','h'), ('gg','g'), ('fff','f'), ('ee','e'), ('ffff','f'),
|
||||
('bbb','b'), ('ff','f'), ('cccc','c'), ('dddd','d'), ('jj','j'),
|
||||
('aaaa','a'), ('bb','b'), ('eeee','e'), ('aa','a'), ('hh','h');
|
||||
EXPLAIN SELECT t2.*
|
||||
FROM t1 JOIN t2 ON t2.fk=t1.pk
|
||||
WHERE t2.fk < 'c' AND t2.pk=t1.fk;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 3 Using where
|
||||
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where
|
||||
EXPLAIN SELECT t2.*
|
||||
FROM t1 JOIN t2 ON t2.fk=t1.pk
|
||||
WHERE t2.fk BETWEEN 'a' AND 'b' AND t2.pk=t1.fk;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using where
|
||||
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where
|
||||
EXPLAIN SELECT t2.*
|
||||
FROM t1 JOIN t2 ON t2.fk=t1.pk
|
||||
WHERE t2.fk IN ('a','b') AND t2.pk=t1.fk;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using where
|
||||
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where
|
||||
DROP TABLE t1,t2;
|
||||
CREATE TABLE t1 (a int, b varchar(20) NOT NULL, PRIMARY KEY(a));
|
||||
CREATE TABLE t2 (a int, b varchar(20) NOT NULL,
|
||||
PRIMARY KEY (a), UNIQUE KEY (b));
|
||||
INSERT INTO t1 VALUES (1,'a'),(2,'b'),(3,'c');
|
||||
INSERT INTO t2 VALUES (1,'a'),(2,'b'),(3,'c');
|
||||
EXPLAIN SELECT t1.a FROM t1 LEFT JOIN t2 ON t2.b=t1.b WHERE t1.a=3;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
|
||||
1 SIMPLE t2 const b b 22 const 1 Using index
|
||||
DROP TABLE t1,t2;
|
||||
CREATE TABLE t1(id int PRIMARY KEY, b int, e int);
|
||||
CREATE TABLE t2(i int, a int, INDEX si(i), INDEX ai(a));
|
||||
CREATE TABLE t3(a int PRIMARY KEY, c char(4), INDEX ci(c));
|
||||
INSERT INTO t1 VALUES
|
||||
(1,10,19), (2,20,22), (4,41,42), (9,93,95), (7, 77,79),
|
||||
(6,63,67), (5,55,58), (3,38,39), (8,81,89);
|
||||
INSERT INTO t2 VALUES
|
||||
(21,210), (41,410), (82,820), (83,830), (84,840),
|
||||
(65,650), (51,510), (37,370), (94,940), (76,760),
|
||||
(22,220), (33,330), (40,400), (95,950), (38,380),
|
||||
(67,670), (88,880), (57,570), (96,960), (97,970);
|
||||
INSERT INTO t3 VALUES
|
||||
(210,'bb'), (950,'ii'), (400,'ab'), (500,'ee'), (220,'gg'),
|
||||
(440,'gg'), (310,'eg'), (380,'ee'), (840,'bb'), (830,'ff'),
|
||||
(230,'aa'), (960,'ii'), (410,'aa'), (510,'ee'), (290,'bb'),
|
||||
(450,'gg'), (320,'dd'), (390,'hh'), (850,'jj'), (860,'ff');
|
||||
EXPLAIN
|
||||
SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3
|
||||
WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND
|
||||
t3.a=t2.a AND t3.c IN ('bb','ee');
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
|
||||
1 SIMPLE t2 range si si 5 NULL 4 Using where
|
||||
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
|
||||
EXPLAIN
|
||||
SELECT t3.a FROM t1,t2,t3
|
||||
WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND
|
||||
t3.a=t2.a AND t3.c IN ('bb','ee') ;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
|
||||
1 SIMPLE t2 range si,ai si 5 NULL 4 Using where
|
||||
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
|
||||
EXPLAIN
|
||||
SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3
|
||||
WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
|
||||
t3.c IN ('bb','ee');
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
|
||||
1 SIMPLE t2 range si si 5 NULL 2 Using where
|
||||
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
|
||||
EXPLAIN
|
||||
SELECT t3.a FROM t1,t2,t3
|
||||
WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
|
||||
t3.c IN ('bb','ee');
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
|
||||
1 SIMPLE t2 range si,ai si 5 NULL 2 Using where
|
||||
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
|
||||
DROP TABLE t1,t2,t3;
|
||||
|
|
|
@ -363,12 +363,12 @@ INSERT INTO t8 (pseudo,email) VALUES ('joce1','test1');
|
|||
INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
|
||||
EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t8 ref PRIMARY PRIMARY 37 const 1 100.00 Using where; Using index
|
||||
4 SUBQUERY t8 ref PRIMARY PRIMARY 37 1 100.00 Using where; Using index
|
||||
2 SUBQUERY t8 ref PRIMARY PRIMARY 37 const 1 100.00 Using where
|
||||
3 SUBQUERY t8 ref PRIMARY PRIMARY 37 1 100.00 Using where; Using index
|
||||
1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
||||
4 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index
|
||||
2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
|
||||
3 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t8`.`pseudo` AS `pseudo`,(select `test`.`t8`.`email` AS `email` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select `test`.`t8`.`pseudo` AS `pseudo` from `test`.`t8` where (`test`.`t8`.`pseudo` = _latin1'joce')))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select `test`.`t8`.`pseudo` AS `pseudo` from `test`.`t8` where (`test`.`t8`.`pseudo` = _latin1'joce')))
|
||||
Note 1003 select `test`.`t8`.`pseudo` AS `pseudo`,(select `test`.`t8`.`email` AS `email` from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1
|
||||
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
|
||||
t8 WHERE pseudo='joce');
|
||||
ERROR 21000: Operand should contain 1 column(s)
|
||||
|
@ -3458,6 +3458,32 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
4 UNION t12 system NULL NULL NULL NULL 0 const row not found
|
||||
NULL UNION RESULT <union2,4> ALL NULL NULL NULL NULL NULL
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a VARCHAR(250), b INT auto_increment, PRIMARY KEY (b));
|
||||
insert into t1 (a) values (FLOOR(rand() * 100));
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
SELECT a,
|
||||
(SELECT REPEAT(' ',250) FROM t1 i1
|
||||
WHERE i1.b=t1.a ORDER BY RAND() LIMIT 1) AS a
|
||||
FROM t1 ORDER BY a LIMIT 5;
|
||||
a a
|
||||
0 NULL
|
||||
0 NULL
|
||||
0 NULL
|
||||
0 NULL
|
||||
0 NULL
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a INT, b INT);
|
||||
CREATE TABLE t2 (a INT);
|
||||
INSERT INTO t2 values (1);
|
||||
|
|
|
@ -779,3 +779,14 @@ select f1 from t1 where f1 in (select f1 from t1);
|
|||
f1
|
||||
40
|
||||
drop table t1;
|
||||
create table t1 as
|
||||
select from_days(s) as date,t
|
||||
from (select 1 as s,'t' as t union select null, null ) as sub1;
|
||||
select group_concat(t) from t1 group by week(date)/10;
|
||||
group_concat(t)
|
||||
t
|
||||
Warnings:
|
||||
Warning 1292 Incorrect datetime value: '0000-00-00'
|
||||
Warning 1292 Incorrect datetime value: '0000-00-00'
|
||||
Warning 1292 Incorrect datetime value: '0000-00-00'
|
||||
drop table t1;
|
||||
|
|
|
@ -1745,3 +1745,12 @@ create table t1 (a set('x','y') default 'x');
|
|||
alter table t1 alter a set default 'z';
|
||||
ERROR 42000: Invalid default value for 'a'
|
||||
drop table t1;
|
||||
create table t1 (f1 int);
|
||||
alter table t1 add f2 enum(0xFFFF);
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`f1` int(11) DEFAULT NULL,
|
||||
`f2` enum('ÿÿ') DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
|
|
|
@ -2956,4 +2956,14 @@ View Create View
|
|||
v1 CREATE ALGORITHM=MERGE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`pk` AS `pk` from (`t1` join `t2` on(((`t2`.`fk` = `t1`.`pk`) and (`t2`.`ver` = (select max(`t`.`ver`) AS `MAX(t.ver)` from `t2` `t` where (`t`.`org` = `t2`.`org`))))))
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1, t2;
|
||||
CREATE TABLE t1(id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, val INT UNSIGNED NOT NULL);
|
||||
CREATE VIEW v1 AS SELECT id, val FROM t1 WHERE val >= 1 AND val <= 5 WITH CHECK OPTION;
|
||||
INSERT INTO v1 (val) VALUES (2);
|
||||
INSERT INTO v1 (val) VALUES (4);
|
||||
INSERT INTO v1 (val) VALUES (6);
|
||||
ERROR HY000: CHECK OPTION failed 'test.v1'
|
||||
UPDATE v1 SET val=6 WHERE id=2;
|
||||
ERROR HY000: CHECK OPTION failed 'test.v1'
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
End of 5.0 tests.
|
||||
|
|
|
@ -941,6 +941,76 @@ INSERT INTO t1 VALUES('uUABCDEFGHIGKLMNOPRSTUVWXYZ̈bbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
|||
check table t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#20471 LIKE search fails with indexed utf8 char column
|
||||
#
|
||||
set names utf8;
|
||||
create table t1 (s1 char(5) character set utf8);
|
||||
insert into t1 values
|
||||
('a'),('b'),(null),('ペテルグル'),('ü'),('Y');
|
||||
create index it1 on t1 (s1);
|
||||
select s1 as before_delete_general_ci from t1 where s1 like 'ペテ%';
|
||||
delete from t1 where s1 = 'Y';
|
||||
select s1 as after_delete_general_ci from t1 where s1 like 'ペテ%';
|
||||
drop table t1;
|
||||
|
||||
set names utf8;
|
||||
create table t1 (s1 char(5) character set utf8 collate utf8_unicode_ci);
|
||||
insert into t1 values
|
||||
('a'),('b'),(null),('ペテルグル'),('ü'),('Y');
|
||||
create index it1 on t1 (s1);
|
||||
select s1 as before_delete_unicode_ci from t1 where s1 like 'ペテ%';
|
||||
delete from t1 where s1 = 'Y';
|
||||
select s1 as after_delete_unicode_ci from t1 where s1 like 'ペテ%';
|
||||
drop table t1;
|
||||
|
||||
set names utf8;
|
||||
create table t1 (s1 char(5) character set utf8 collate utf8_bin);
|
||||
insert into t1 values
|
||||
('a'),('b'),(null),('ペテルグル'),('ü'),('Y');
|
||||
create index it1 on t1 (s1);
|
||||
select s1 as before_delete_bin from t1 where s1 like 'ペテ%';
|
||||
delete from t1 where s1 = 'Y';
|
||||
select s1 as after_delete_bin from t1 where s1 like 'ペテ%';
|
||||
drop table t1;
|
||||
|
||||
# additional tests from duplicate bug#20744 MySQL return no result
|
||||
|
||||
set names utf8;
|
||||
--disable_warnings
|
||||
create table t1 (a varchar(30) not null primary key)
|
||||
engine=innodb default character set utf8 collate utf8_general_ci;
|
||||
--enable_warnings
|
||||
insert into t1 values ('あいうえおかきくけこさしすせそ');
|
||||
insert into t1 values ('さしすせそかきくけこあいうえお');
|
||||
select a as gci1 from t1 where a like 'さしすせそかきくけこあいうえお%';
|
||||
select a as gci2 from t1 where a like 'あいうえおかきくけこさしすせそ';
|
||||
drop table t1;
|
||||
|
||||
set names utf8;
|
||||
--disable_warnings
|
||||
create table t1 (a varchar(30) not null primary key)
|
||||
engine=innodb default character set utf8 collate utf8_unicode_ci;
|
||||
--enable_warnings
|
||||
insert into t1 values ('あいうえおかきくけこさしすせそ');
|
||||
insert into t1 values ('さしすせそかきくけこあいうえお');
|
||||
select a as uci1 from t1 where a like 'さしすせそかきくけこあいうえお%';
|
||||
select a as uci2 from t1 where a like 'あいうえおかきくけこさしすせそ';
|
||||
drop table t1;
|
||||
|
||||
set names utf8;
|
||||
--disable_warnings
|
||||
create table t1 (a varchar(30) not null primary key)
|
||||
engine=innodb default character set utf8 collate utf8_bin;
|
||||
--enable_warnings
|
||||
insert into t1 values ('あいうえおかきくけこさしすせそ');
|
||||
insert into t1 values ('さしすせそかきくけこあいうえお');
|
||||
select a as bin1 from t1 where a like 'さしすせそかきくけこあいうえお%';
|
||||
select a as bin2 from t1 where a like 'あいうえおかきくけこさしすせそ';
|
||||
drop table t1;
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Bug#14896: Comparison with a key in a partial index over mb chararacter field
|
||||
#
|
||||
|
|
|
@ -23,7 +23,6 @@ ndb_autodiscover2 : BUG#18952 2006-02-16 jmiller Needs to be fixed w.r.t
|
|||
#ndb_binlog_ignore_db : BUG#21279 2006-07-25 ingo Randomly throws a warning
|
||||
ndb_load : BUG#17233 2006-05-04 tomas failed load data from infile causes mysqld dbug_assert, binlog not flushed
|
||||
partition_03ndb : BUG#16385 2006-03-24 mikael Partitions: crash when updating a range partitioned NDB table
|
||||
ps : BUG#21524 2006-08-08 pgalbraith 'ps' test fails in --ps-protocol test AMD64 bit
|
||||
ps_7ndb : BUG#18950 2006-02-16 jmiller create table like does not obtain LOCK_open
|
||||
rpl_ndb_2innodb : BUG#19227 2006-04-20 pekka pk delete apparently not replicated
|
||||
rpl_ndb_2myisam : BUG#19227 Seems to pass currently
|
||||
|
|
|
@ -32,7 +32,6 @@ select grp,group_concat(d order by a desc) from t1 group by grp;
|
|||
select grp,group_concat(a order by a,d+c-ascii(c)-a) from t1 group by grp;
|
||||
select grp,group_concat(a order by d+c-ascii(c),a) from t1 group by grp;
|
||||
select grp,group_concat(c order by 1) from t1 group by grp;
|
||||
select grp,group_concat(c order by "c") from t1 group by grp;
|
||||
select grp,group_concat(distinct c order by c) from t1 group by grp;
|
||||
select grp,group_concat(distinct c order by c desc) from t1 group by grp;
|
||||
explain extended select grp,group_concat(distinct c order by c desc) from t1 group by grp;
|
||||
|
|
|
@ -231,4 +231,14 @@ INSERT INTO t1 (c1) VALUES (
|
|||
CHECK TABLE t1 EXTENDED;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug #21888: Query on GEOMETRY field using PointFromWKB() results in lost connection
|
||||
#
|
||||
CREATE TABLE t1 (foo GEOMETRY NOT NULL, SPATIAL INDEX(foo) );
|
||||
INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(1,1)));
|
||||
INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(1,0)));
|
||||
INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(0,1)));
|
||||
INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(0,0)));
|
||||
SELECT 1 FROM t1 WHERE foo != PointFromWKB(POINT(0,0));
|
||||
DROP TABLE t1;
|
||||
# End of 4.1 tests
|
||||
|
|
|
@ -609,6 +609,30 @@ select sql_buffer_result max(f1) is null from t1;
|
|||
select sql_buffer_result max(f1)+1 from t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# BUG#14019-4.1-opt
|
||||
#
|
||||
CREATE TABLE t1(a INT); INSERT INTO t1 VALUES (1),(2);
|
||||
|
||||
SELECT a FROM t1 GROUP BY 'a';
|
||||
SELECT a FROM t1 GROUP BY "a";
|
||||
SELECT a FROM t1 GROUP BY `a`;
|
||||
|
||||
set sql_mode=ANSI_QUOTES;
|
||||
SELECT a FROM t1 GROUP BY "a";
|
||||
SELECT a FROM t1 GROUP BY 'a';
|
||||
SELECT a FROM t1 GROUP BY `a`;
|
||||
set sql_mode='';
|
||||
|
||||
SELECT a FROM t1 HAVING 'a' > 1;
|
||||
SELECT a FROM t1 HAVING "a" > 1;
|
||||
SELECT a FROM t1 HAVING `a` > 1;
|
||||
|
||||
SELECT a FROM t1 ORDER BY 'a' DESC;
|
||||
SELECT a FROM t1 ORDER BY "a" DESC;
|
||||
SELECT a FROM t1 ORDER BY `a` DESC;
|
||||
DROP TABLE t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
#
|
||||
|
@ -656,6 +680,28 @@ where t2.b=v1.a GROUP BY t2.b;
|
|||
DROP VIEW v1;
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
#
|
||||
# Bug#22781: SQL_BIG_RESULT fails to influence sort plan
|
||||
#
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY, b INT, key (b));
|
||||
|
||||
INSERT INTO t1 VALUES (1, 1);
|
||||
INSERT INTO t1 SELECT a + 1 , MOD(a + 1 , 20) FROM t1;
|
||||
INSERT INTO t1 SELECT a + 2 , MOD(a + 2 , 20) FROM t1;
|
||||
INSERT INTO t1 SELECT a + 4 , MOD(a + 4 , 20) FROM t1;
|
||||
INSERT INTO t1 SELECT a + 8 , MOD(a + 8 , 20) FROM t1;
|
||||
INSERT INTO t1 SELECT a + 16, MOD(a + 16, 20) FROM t1;
|
||||
INSERT INTO t1 SELECT a + 32, MOD(a + 32, 20) FROM t1;
|
||||
INSERT INTO t1 SELECT a + 64, MOD(a + 64, 20) FROM t1;
|
||||
|
||||
SELECT MIN(b), MAX(b) from t1;
|
||||
|
||||
EXPLAIN SELECT b, sum(1) FROM t1 GROUP BY b;
|
||||
EXPLAIN SELECT SQL_BIG_RESULT b, sum(1) FROM t1 GROUP BY b;
|
||||
SELECT b, sum(1) FROM t1 GROUP BY b;
|
||||
SELECT SQL_BIG_RESULT b, sum(1) FROM t1 GROUP BY b;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug #21174: Index degrades sort performance and
|
||||
# optimizer does not honor IGNORE INDEX
|
||||
|
|
|
@ -819,3 +819,19 @@ SELECT * FROM
|
|||
t1;
|
||||
|
||||
DROP TABLE t1,t2,t3,t4,t5,t6;
|
||||
|
||||
#
|
||||
# Bug#22342: No results returned for query using max and group by
|
||||
#
|
||||
CREATE TABLE t1 (a int, b int, PRIMARY KEY (a,b), KEY b (b));
|
||||
INSERT INTO t1 VALUES (1,1),(1,2),(1,0),(1,3);
|
||||
|
||||
explain SELECT MAX(b), a FROM t1 WHERE b < 2 AND a = 1 GROUP BY a;
|
||||
SELECT MAX(b), a FROM t1 WHERE b < 2 AND a = 1 GROUP BY a;
|
||||
SELECT MIN(b), a FROM t1 WHERE b > 1 AND a = 1 GROUP BY a;
|
||||
CREATE TABLE t2 (a int, b int, c int, PRIMARY KEY (a,b,c));
|
||||
INSERT INTO t2 SELECT a,b,b FROM t1;
|
||||
explain SELECT MIN(c) FROM t2 WHERE b = 2 and a = 1 and c > 1 GROUP BY a;
|
||||
SELECT MIN(c) FROM t2 WHERE b = 2 and a = 1 and c > 1 GROUP BY a;
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
|
|
@ -755,6 +755,97 @@ SELECT * FROM t1;
|
|||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug#8283 - OPTIMIZE TABLE causes data loss
|
||||
#
|
||||
SET @@myisam_repair_threads=2;
|
||||
SHOW VARIABLES LIKE 'myisam_repair%';
|
||||
#
|
||||
# Test OPTIMIZE. This creates a new data file.
|
||||
CREATE TABLE t1 (
|
||||
`_id` int(11) NOT NULL default '0',
|
||||
`url` text,
|
||||
`email` text,
|
||||
`description` text,
|
||||
`loverlap` int(11) default NULL,
|
||||
`roverlap` int(11) default NULL,
|
||||
`lneighbor_id` int(11) default NULL,
|
||||
`rneighbor_id` int(11) default NULL,
|
||||
`length_` int(11) default NULL,
|
||||
`sequence` mediumtext,
|
||||
`name` text,
|
||||
`_obj_class` text NOT NULL,
|
||||
PRIMARY KEY (`_id`),
|
||||
UNIQUE KEY `sequence_name_index` (`name`(50)),
|
||||
KEY (`length_`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
#
|
||||
INSERT INTO t1 VALUES
|
||||
(1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample1',''),
|
||||
(2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample2',''),
|
||||
(3,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample3',''),
|
||||
(4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample4',''),
|
||||
(5,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample5',''),
|
||||
(6,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample6',''),
|
||||
(7,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample7',''),
|
||||
(8,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample8',''),
|
||||
(9,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample9','');
|
||||
#
|
||||
SELECT _id FROM t1;
|
||||
DELETE FROM t1 WHERE _id < 8;
|
||||
--replace_column 6 # 7 # 8 # 9 # 11 # 12 # 13 # 14 # 15 # 16 #
|
||||
SHOW TABLE STATUS LIKE 't1';
|
||||
CHECK TABLE t1 EXTENDED;
|
||||
OPTIMIZE TABLE t1;
|
||||
CHECK TABLE t1 EXTENDED;
|
||||
--replace_column 6 # 7 # 8 # 9 # 11 # 12 # 13 # 14 # 15 # 16 #
|
||||
SHOW TABLE STATUS LIKE 't1';
|
||||
SELECT _id FROM t1;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Test REPAIR QUICK. This retains the old data file.
|
||||
CREATE TABLE t1 (
|
||||
`_id` int(11) NOT NULL default '0',
|
||||
`url` text,
|
||||
`email` text,
|
||||
`description` text,
|
||||
`loverlap` int(11) default NULL,
|
||||
`roverlap` int(11) default NULL,
|
||||
`lneighbor_id` int(11) default NULL,
|
||||
`rneighbor_id` int(11) default NULL,
|
||||
`length_` int(11) default NULL,
|
||||
`sequence` mediumtext,
|
||||
`name` text,
|
||||
`_obj_class` text NOT NULL,
|
||||
PRIMARY KEY (`_id`),
|
||||
UNIQUE KEY `sequence_name_index` (`name`(50)),
|
||||
KEY (`length_`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
#
|
||||
INSERT INTO t1 VALUES
|
||||
(1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample1',''),
|
||||
(2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample2',''),
|
||||
(3,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample3',''),
|
||||
(4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample4',''),
|
||||
(5,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample5',''),
|
||||
(6,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample6',''),
|
||||
(7,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample7',''),
|
||||
(8,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample8',''),
|
||||
(9,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample9','');
|
||||
#
|
||||
SELECT _id FROM t1;
|
||||
DELETE FROM t1 WHERE _id < 8;
|
||||
--replace_column 6 # 7 # 8 # 9 # 11 # 12 # 13 # 14 # 15 # 16 #
|
||||
SHOW TABLE STATUS LIKE 't1';
|
||||
CHECK TABLE t1 EXTENDED;
|
||||
REPAIR TABLE t1 QUICK;
|
||||
CHECK TABLE t1 EXTENDED;
|
||||
--replace_column 6 # 7 # 8 # 9 # 11 # 12 # 13 # 14 # 15 # 16 #
|
||||
SHOW TABLE STATUS LIKE 't1';
|
||||
SELECT _id FROM t1;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
SET @@myisam_repair_threads=1;
|
||||
SHOW VARIABLES LIKE 'myisam_repair%';
|
||||
# Test varchar
|
||||
#
|
||||
|
||||
|
|
|
@ -283,6 +283,15 @@ select a, max(b) from t1 group by a with rollup;
|
|||
select distinct a, max(b) from t1 group by a with rollup;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #20825: rollup puts non-equal values together
|
||||
#
|
||||
create table t1 (a varchar(22) not null , b int);
|
||||
insert into t1 values ("2006-07-01 21:30", 1), ("2006-07-01 23:30", 10);
|
||||
select left(a,10), a, sum(b) from t1 group by 1,2 with rollup;
|
||||
select left(a,10) x, a, sum(b) from t1 group by x,a with rollup;
|
||||
drop table t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
#
|
||||
|
@ -318,4 +327,3 @@ SELECT * FROM v1;
|
|||
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
# End of 4.1 tests
|
||||
|
|
|
@ -354,14 +354,14 @@ create table t1 (a int, b int);
|
|||
insert into t1 (a, b) values (1,1), (1,2), (2,1), (2,2);
|
||||
prepare stmt from
|
||||
"explain select * from t1 where t1.a=2 and t1.a=t1.b and t1.b > 1 + ?";
|
||||
--replace_column 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 -
|
||||
set @v=5;
|
||||
execute stmt using @v;
|
||||
--replace_column 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 -
|
||||
execute stmt using @v;
|
||||
set @v=0;
|
||||
execute stmt using @v;
|
||||
--replace_column 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 -
|
||||
execute stmt using @v;
|
||||
set @v=5;
|
||||
--replace_column 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 -
|
||||
execute stmt using @v;
|
||||
drop table t1;
|
||||
deallocate prepare stmt;
|
||||
|
@ -1447,13 +1447,15 @@ create procedure proc_1() reset query cache;
|
|||
call proc_1();
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
delimiter |;
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
create function func_1() returns int begin reset query cache; return 1; end|
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
delimiter ;|
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
drop function func_1;
|
||||
drop procedure proc_1;
|
||||
prepare abc from "reset query cache";
|
||||
execute abc;
|
||||
execute abc;
|
||||
|
@ -1462,13 +1464,15 @@ deallocate prepare abc;
|
|||
|
||||
|
||||
create procedure proc_1() reset master;
|
||||
drop procedure proc_1;
|
||||
delimiter |;
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
create function func_1() returns int begin reset master; return 1; end|
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
delimiter ;|
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
drop function func_1;
|
||||
drop procedure proc_1;
|
||||
prepare abc from "reset master";
|
||||
execute abc;
|
||||
execute abc;
|
||||
|
@ -1480,13 +1484,15 @@ create procedure proc_1() reset slave;
|
|||
call proc_1();
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
delimiter |;
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
create function func_1() returns int begin reset slave; return 1; end|
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
delimiter ;|
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
drop function func_1;
|
||||
drop procedure proc_1;
|
||||
prepare abc from "reset slave";
|
||||
execute abc;
|
||||
execute abc;
|
||||
|
@ -1527,15 +1533,15 @@ call proc_1();
|
|||
call proc_1();
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
delimiter |;
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
create function func_1() returns int begin flush hosts; return 1; end|
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
delimiter ;|
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
drop function func_1;
|
||||
drop procedure proc_1;
|
||||
prepare abc from "flush hosts";
|
||||
execute abc;
|
||||
execute abc;
|
||||
|
@ -1547,15 +1553,15 @@ create procedure proc_1() flush privileges;
|
|||
call proc_1();
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
delimiter |;
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
create function func_1() returns int begin flush privileges; return 1; end|
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
delimiter ;|
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
drop function func_1;
|
||||
drop procedure proc_1;
|
||||
prepare abc from "flush privileges";
|
||||
deallocate prepare abc;
|
||||
|
||||
|
@ -1567,11 +1573,15 @@ call proc_1();
|
|||
unlock tables;
|
||||
call proc_1();
|
||||
unlock tables;
|
||||
drop procedure proc_1;
|
||||
delimiter |;
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
create function func_1() returns int begin flush tables with read lock; return 1; end|
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
delimiter ;|
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
drop function func_1;
|
||||
drop procedure proc_1;
|
||||
prepare abc from "flush tables with read lock";
|
||||
execute abc;
|
||||
execute abc;
|
||||
|
@ -1584,15 +1594,15 @@ create procedure proc_1() flush tables;
|
|||
call proc_1();
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
delimiter |;
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
create function func_1() returns int begin flush tables; return 1; end|
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
delimiter ;|
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
drop function func_1;
|
||||
drop procedure proc_1;
|
||||
prepare abc from "flush tables";
|
||||
execute abc;
|
||||
execute abc;
|
||||
|
@ -1622,15 +1632,15 @@ select Host, User from mysql.user limit 0;
|
|||
select Host, Db from mysql.host limit 0;
|
||||
show open tables from mysql;
|
||||
flush tables;
|
||||
drop procedure proc_1;
|
||||
delimiter |;
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
create function func_1() returns int begin flush tables; return 1; end|
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
delimiter ;|
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
drop function func_1;
|
||||
drop procedure proc_1;
|
||||
flush tables;
|
||||
select Host, User from mysql.user limit 0;
|
||||
select Host, Db from mysql.host limit 0;
|
||||
|
@ -1659,15 +1669,15 @@ create procedure proc_1() flush logs;
|
|||
call proc_1();
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
delimiter |;
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
create function func_1() returns int begin flush logs; return 1; end|
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
delimiter ;|
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
drop function func_1;
|
||||
drop procedure proc_1;
|
||||
prepare abc from "flush logs";
|
||||
execute abc;
|
||||
execute abc;
|
||||
|
@ -1679,15 +1689,15 @@ create procedure proc_1() flush status;
|
|||
call proc_1();
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
delimiter |;
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
create function func_1() returns int begin flush status; return 1; end|
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
delimiter ;|
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
drop function func_1;
|
||||
drop procedure proc_1;
|
||||
prepare abc from "flush status";
|
||||
execute abc;
|
||||
execute abc;
|
||||
|
@ -1699,15 +1709,15 @@ create procedure proc_1() flush slave;
|
|||
call proc_1();
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
delimiter |;
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
create function func_1() returns int begin flush slave; return 1; end|
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
delimiter ;|
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
drop function func_1;
|
||||
drop procedure proc_1;
|
||||
prepare abc from "flush slave";
|
||||
execute abc;
|
||||
execute abc;
|
||||
|
@ -1716,15 +1726,15 @@ deallocate prepare abc;
|
|||
|
||||
|
||||
create procedure proc_1() flush master;
|
||||
drop procedure proc_1;
|
||||
delimiter |;
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
create function func_1() returns int begin flush master; return 1; end|
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
delimiter ;|
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
drop function func_1;
|
||||
drop procedure proc_1;
|
||||
prepare abc from "flush master";
|
||||
deallocate prepare abc;
|
||||
|
||||
|
@ -1733,15 +1743,15 @@ create procedure proc_1() flush des_key_file;
|
|||
call proc_1();
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
delimiter |;
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
create function func_1() returns int begin flush des_key_file; return 1; end|
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
delimiter ;|
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
drop function func_1;
|
||||
drop procedure proc_1;
|
||||
prepare abc from "flush des_key_file";
|
||||
execute abc;
|
||||
execute abc;
|
||||
|
@ -1753,15 +1763,15 @@ create procedure proc_1() flush user_resources;
|
|||
call proc_1();
|
||||
call proc_1();
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
delimiter |;
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
create function func_1() returns int begin flush user_resources; return 1; end|
|
||||
create function func_1() returns int begin call proc_1(); return 1; end|
|
||||
delimiter ;|
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
drop function func_1;
|
||||
drop procedure proc_1;
|
||||
prepare abc from "flush user_resources";
|
||||
execute abc;
|
||||
execute abc;
|
||||
|
@ -1865,22 +1875,6 @@ execute abc;
|
|||
deallocate prepare abc;
|
||||
|
||||
|
||||
create procedure proc_1() show scheduler status;
|
||||
drop procedure proc_1;
|
||||
delimiter |;
|
||||
--error ER_SP_NO_RETSET
|
||||
create function func_1() returns int begin show scheduler status; return 1; end|
|
||||
delimiter ;|
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
select func_1(), func_1(), func_1() from dual;
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
drop function func_1;
|
||||
--error ER_UNSUPPORTED_PS
|
||||
prepare abc from "show scheduler status";
|
||||
--error ER_UNKNOWN_STMT_HANDLER
|
||||
deallocate prepare abc;
|
||||
|
||||
|
||||
--disable_warnings
|
||||
drop procedure if exists a;
|
||||
--enable_warnings
|
||||
|
@ -1997,10 +1991,13 @@ call proc_1();
|
|||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
create procedure proc_1() install plugin my_plug soname 'some_plugin.so';
|
||||
--replace_regex /(Can\'t open shared library).*$/\1/
|
||||
--error ER_CANT_OPEN_LIBRARY
|
||||
call proc_1();
|
||||
--replace_regex /(Can\'t open shared library).*$/\1/
|
||||
--error ER_CANT_OPEN_LIBRARY
|
||||
call proc_1();
|
||||
--replace_regex /(Can\'t open shared library).*$/\1/
|
||||
--error ER_CANT_OPEN_LIBRARY
|
||||
call proc_1();
|
||||
drop procedure proc_1;
|
||||
|
@ -2150,7 +2147,7 @@ drop event if exists xyz;
|
|||
#drop event xyz;
|
||||
#drop procedure proc_1;
|
||||
delimiter |;
|
||||
--error ER_SP_NO_RETSET
|
||||
--error ER_EVENT_RECURSIVITY_FORBIDDEN
|
||||
create function func_1() returns int begin create event xyz on schedule at now() do select 123; return 1; end|
|
||||
delimiter ;|
|
||||
--error ER_SP_DOES_NOT_EXIST
|
||||
|
|
|
@ -72,4 +72,17 @@ disconnect con2;
|
|||
disconnect con1;
|
||||
connection default;
|
||||
|
||||
#
|
||||
# Bug#14959: ALTER TABLE isn't able to rename a view
|
||||
#
|
||||
create table t1(f1 int);
|
||||
create view v1 as select * from t1;
|
||||
alter table v1 rename to v2;
|
||||
--error 1146
|
||||
alter table v1 rename to v2;
|
||||
rename table v2 to v1;
|
||||
--error 1050
|
||||
rename table v2 to v1;
|
||||
drop view v1;
|
||||
drop table t1;
|
||||
# End of 4.1 tests
|
||||
|
|
|
@ -45,6 +45,44 @@ SHOW INDEX FROM t1;
|
|||
SET myisam_repair_threads=@@global.myisam_repair_threads;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# BUG#22562 - REPAIR TABLE .. USE_FRM causes server crash on Windows and
|
||||
# server hangs on Linux
|
||||
#
|
||||
CREATE TABLE t1(a INT);
|
||||
USE mysql;
|
||||
REPAIR TABLE test.t1 USE_FRM;
|
||||
USE test;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# BUG#23175 - MYISAM crash/repair failed during repair
|
||||
#
|
||||
CREATE TABLE t1(a CHAR(255), KEY(a));
|
||||
SET myisam_sort_buffer_size=4096;
|
||||
INSERT INTO t1 VALUES
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
|
||||
('0'),('0'),('0'),('0'),('0'),('0'),('0');
|
||||
SET myisam_repair_threads=2;
|
||||
REPAIR TABLE t1;
|
||||
SET myisam_repair_threads=@@global.myisam_repair_threads;
|
||||
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
|
||||
DROP TABLE t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
# End of 5.0 tests
|
||||
|
||||
|
|
|
@ -2997,5 +2997,99 @@ SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id
|
|||
SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id
|
||||
WHERE t1.id=2;
|
||||
|
||||
DROP TABLE t1,t2,t3;
|
||||
|
||||
#
|
||||
# Bug#20503: Server crash due to the ORDER clause isn't taken into account
|
||||
# while space allocation
|
||||
#
|
||||
create table t1 (c1 varchar(1), c2 int, c3 int, c4 int, c5 int, c6 int,
|
||||
c7 int, c8 int, c9 int, fulltext key (`c1`));
|
||||
select distinct match (`c1`) against ('z') , c2, c3, c4,c5, c6,c7, c8
|
||||
from t1 where c9=1 order by c2, c2;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #22735: no equality propagation for BETWEEN and IN with STRING arguments
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (pk varchar(10) PRIMARY KEY, fk varchar(16));
|
||||
CREATE TABLE t2 (pk varchar(16) PRIMARY KEY, fk varchar(10));
|
||||
|
||||
INSERT INTO t1 VALUES
|
||||
('d','dddd'), ('i','iii'), ('a','aa'), ('b','bb'), ('g','gg'),
|
||||
('e','eee'), ('c','cccc'), ('h','hhh'), ('j','jjj'), ('f','fff');
|
||||
INSERT INTO t2 VALUES
|
||||
('jjj', 'j'), ('cc','c'), ('ccc','c'), ('aaa', 'a'), ('jjjj','j'),
|
||||
('hhh','h'), ('gg','g'), ('fff','f'), ('ee','e'), ('ffff','f'),
|
||||
('bbb','b'), ('ff','f'), ('cccc','c'), ('dddd','d'), ('jj','j'),
|
||||
('aaaa','a'), ('bb','b'), ('eeee','e'), ('aa','a'), ('hh','h');
|
||||
|
||||
EXPLAIN SELECT t2.*
|
||||
FROM t1 JOIN t2 ON t2.fk=t1.pk
|
||||
WHERE t2.fk < 'c' AND t2.pk=t1.fk;
|
||||
EXPLAIN SELECT t2.*
|
||||
FROM t1 JOIN t2 ON t2.fk=t1.pk
|
||||
WHERE t2.fk BETWEEN 'a' AND 'b' AND t2.pk=t1.fk;
|
||||
EXPLAIN SELECT t2.*
|
||||
FROM t1 JOIN t2 ON t2.fk=t1.pk
|
||||
WHERE t2.fk IN ('a','b') AND t2.pk=t1.fk;
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
#
|
||||
# Bug #22367: Optimizer uses ref join type instead of eq_ref for simple
|
||||
# join on strings
|
||||
#
|
||||
CREATE TABLE t1 (a int, b varchar(20) NOT NULL, PRIMARY KEY(a));
|
||||
CREATE TABLE t2 (a int, b varchar(20) NOT NULL,
|
||||
PRIMARY KEY (a), UNIQUE KEY (b));
|
||||
INSERT INTO t1 VALUES (1,'a'),(2,'b'),(3,'c');
|
||||
INSERT INTO t2 VALUES (1,'a'),(2,'b'),(3,'c');
|
||||
|
||||
EXPLAIN SELECT t1.a FROM t1 LEFT JOIN t2 ON t2.b=t1.b WHERE t1.a=3;
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
#
|
||||
# Bug #19579: predicates that become sargable after reading const tables
|
||||
# are not taken into account by optimizer
|
||||
#
|
||||
|
||||
CREATE TABLE t1(id int PRIMARY KEY, b int, e int);
|
||||
CREATE TABLE t2(i int, a int, INDEX si(i), INDEX ai(a));
|
||||
CREATE TABLE t3(a int PRIMARY KEY, c char(4), INDEX ci(c));
|
||||
|
||||
INSERT INTO t1 VALUES
|
||||
(1,10,19), (2,20,22), (4,41,42), (9,93,95), (7, 77,79),
|
||||
(6,63,67), (5,55,58), (3,38,39), (8,81,89);
|
||||
INSERT INTO t2 VALUES
|
||||
(21,210), (41,410), (82,820), (83,830), (84,840),
|
||||
(65,650), (51,510), (37,370), (94,940), (76,760),
|
||||
(22,220), (33,330), (40,400), (95,950), (38,380),
|
||||
(67,670), (88,880), (57,570), (96,960), (97,970);
|
||||
INSERT INTO t3 VALUES
|
||||
(210,'bb'), (950,'ii'), (400,'ab'), (500,'ee'), (220,'gg'),
|
||||
(440,'gg'), (310,'eg'), (380,'ee'), (840,'bb'), (830,'ff'),
|
||||
(230,'aa'), (960,'ii'), (410,'aa'), (510,'ee'), (290,'bb'),
|
||||
(450,'gg'), (320,'dd'), (390,'hh'), (850,'jj'), (860,'ff');
|
||||
|
||||
EXPLAIN
|
||||
SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3
|
||||
WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND
|
||||
t3.a=t2.a AND t3.c IN ('bb','ee');
|
||||
EXPLAIN
|
||||
SELECT t3.a FROM t1,t2,t3
|
||||
WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND
|
||||
t3.a=t2.a AND t3.c IN ('bb','ee') ;
|
||||
|
||||
EXPLAIN
|
||||
SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3
|
||||
WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
|
||||
t3.c IN ('bb','ee');
|
||||
EXPLAIN
|
||||
SELECT t3.a FROM t1,t2,t3
|
||||
WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
|
||||
t3.c IN ('bb','ee');
|
||||
|
||||
DROP TABLE t1,t2,t3;
|
||||
|
|
|
@ -2370,6 +2370,32 @@ explain select * from t1 where not exists
|
|||
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug#21798: memory leak during query execution with subquery in column
|
||||
# list using a function
|
||||
#
|
||||
CREATE TABLE t1 (a VARCHAR(250), b INT auto_increment, PRIMARY KEY (b));
|
||||
insert into t1 (a) values (FLOOR(rand() * 100));
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
insert into t1 (a) select FLOOR(rand() * 100) from t1;
|
||||
|
||||
SELECT a,
|
||||
(SELECT REPEAT(' ',250) FROM t1 i1
|
||||
WHERE i1.b=t1.a ORDER BY RAND() LIMIT 1) AS a
|
||||
FROM t1 ORDER BY a LIMIT 5;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug #21540: Subqueries with no from and aggregate functions return
|
||||
# wrong results
|
||||
|
|
|
@ -385,3 +385,12 @@ insert into t1 values (40);
|
|||
flush tables;
|
||||
select f1 from t1 where f1 in (select f1 from t1);
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#22183: Unhandled NULL caused server crash
|
||||
#
|
||||
create table t1 as
|
||||
select from_days(s) as date,t
|
||||
from (select 1 as s,'t' as t union select null, null ) as sub1;
|
||||
select group_concat(t) from t1 group by week(date)/10;
|
||||
drop table t1;
|
||||
|
|
|
@ -127,4 +127,13 @@ create table t1 (a set('x','y') default 'x');
|
|||
alter table t1 alter a set default 'z';
|
||||
drop table t1;
|
||||
|
||||
|
||||
#
|
||||
# Bug#20922 mysql removes a name of first column in a table
|
||||
#
|
||||
create table t1 (f1 int);
|
||||
alter table t1 add f2 enum(0xFFFF);
|
||||
show create table t1;
|
||||
drop table t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
|
|
@ -2884,4 +2884,19 @@ SHOW CREATE VIEW v1;
|
|||
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
#
|
||||
# Bug #16813 (WITH CHECK OPTION doesn't work with UPDATE)
|
||||
#
|
||||
CREATE TABLE t1(id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, val INT UNSIGNED NOT NULL);
|
||||
CREATE VIEW v1 AS SELECT id, val FROM t1 WHERE val >= 1 AND val <= 5 WITH CHECK OPTION;
|
||||
INSERT INTO v1 (val) VALUES (2);
|
||||
INSERT INTO v1 (val) VALUES (4);
|
||||
-- error 1369
|
||||
INSERT INTO v1 (val) VALUES (6);
|
||||
-- error 1369
|
||||
UPDATE v1 SET val=6 WHERE id=2;
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
|
|
@ -70,7 +70,6 @@ static void my_aiowait(my_aio_result *result);
|
|||
#define IO_ROUND_UP(X) (((X)+IO_SIZE-1) & ~(IO_SIZE-1))
|
||||
#define IO_ROUND_DN(X) ( (X) & ~(IO_SIZE-1))
|
||||
|
||||
|
||||
/*
|
||||
Setup internal pointers inside IO_CACHE
|
||||
|
||||
|
@ -502,65 +501,366 @@ int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
|
|||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
#ifdef THREAD
|
||||
/* Prepare IO_CACHE for shared use */
|
||||
void init_io_cache_share(IO_CACHE *info, IO_CACHE_SHARE *s, uint num_threads)
|
||||
/*
|
||||
Prepare IO_CACHE for shared use.
|
||||
|
||||
SYNOPSIS
|
||||
init_io_cache_share()
|
||||
read_cache A read cache. This will be copied for
|
||||
every thread after setup.
|
||||
cshare The share.
|
||||
write_cache If non-NULL a write cache that is to be
|
||||
synchronized with the read caches.
|
||||
num_threads Number of threads sharing the cache
|
||||
including the write thread if any.
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
The shared cache is used so: One IO_CACHE is initialized with
|
||||
init_io_cache(). This includes the allocation of a buffer. Then a
|
||||
share is allocated and init_io_cache_share() is called with the io
|
||||
cache and the share. Then the io cache is copied for each thread. So
|
||||
every thread has its own copy of IO_CACHE. But the allocated buffer
|
||||
is shared because cache->buffer is the same for all caches.
|
||||
|
||||
One thread reads data from the file into the buffer. All threads
|
||||
read from the buffer, but every thread maintains its own set of
|
||||
pointers into the buffer. When all threads have used up the buffer
|
||||
contents, one of the threads reads the next block of data into the
|
||||
buffer. To accomplish this, each thread enters the cache lock before
|
||||
accessing the buffer. They wait in lock_io_cache() until all threads
|
||||
joined the lock. The last thread entering the lock is in charge of
|
||||
reading from file to buffer. It wakes all threads when done.
|
||||
|
||||
Synchronizing a write cache to the read caches works so: Whenever
|
||||
the write buffer needs a flush, the write thread enters the lock and
|
||||
waits for all other threads to enter the lock too. They do this when
|
||||
they have used up the read buffer. When all threads are in the lock,
|
||||
the write thread copies the write buffer to the read buffer and
|
||||
wakes all threads.
|
||||
|
||||
share->running_threads is the number of threads not being in the
|
||||
cache lock. When entering lock_io_cache() the number is decreased.
|
||||
When the thread that fills the buffer enters unlock_io_cache() the
|
||||
number is reset to the number of threads. The condition
|
||||
running_threads == 0 means that all threads are in the lock. Bumping
|
||||
up the number to the full count is non-intuitive. But increasing the
|
||||
number by one for each thread that leaves the lock could lead to a
|
||||
solo run of one thread. The last thread to join a lock reads from
|
||||
file to buffer, wakes the other threads, processes the data in the
|
||||
cache and enters the lock again. If no other thread left the lock
|
||||
meanwhile, it would think it's the last one again and read the next
|
||||
block...
|
||||
|
||||
The share has copies of 'error', 'buffer', 'read_end', and
|
||||
'pos_in_file' from the thread that filled the buffer. We may not be
|
||||
able to access this information directly from its cache because the
|
||||
thread may be removed from the share before the variables could be
|
||||
copied by all other threads. Or, if a write buffer is synchronized,
|
||||
it would change its 'pos_in_file' after waking the other threads,
|
||||
possibly before they could copy its value.
|
||||
|
||||
However, the 'buffer' variable in the share is for a synchronized
|
||||
write cache. It needs to know where to put the data. Otherwise it
|
||||
would need access to the read cache of one of the threads that is
|
||||
not yet removed from the share.
|
||||
|
||||
RETURN
|
||||
void
|
||||
*/
|
||||
|
||||
void init_io_cache_share(IO_CACHE *read_cache, IO_CACHE_SHARE *cshare,
|
||||
IO_CACHE *write_cache, uint num_threads)
|
||||
{
|
||||
DBUG_ASSERT(info->type == READ_CACHE);
|
||||
pthread_mutex_init(&s->mutex, MY_MUTEX_INIT_FAST);
|
||||
pthread_cond_init (&s->cond, 0);
|
||||
s->total=s->count=num_threads-1;
|
||||
s->active=0;
|
||||
info->share=s;
|
||||
info->read_function=_my_b_read_r;
|
||||
info->current_pos= info->current_end= 0;
|
||||
DBUG_ENTER("init_io_cache_share");
|
||||
DBUG_PRINT("io_cache_share", ("read_cache: 0x%lx share: 0x%lx "
|
||||
"write_cache: 0x%lx threads: %u",
|
||||
read_cache, cshare, write_cache, num_threads));
|
||||
|
||||
DBUG_ASSERT(num_threads > 1);
|
||||
DBUG_ASSERT(read_cache->type == READ_CACHE);
|
||||
DBUG_ASSERT(!write_cache || (write_cache->type == WRITE_CACHE));
|
||||
|
||||
pthread_mutex_init(&cshare->mutex, MY_MUTEX_INIT_FAST);
|
||||
pthread_cond_init(&cshare->cond, 0);
|
||||
pthread_cond_init(&cshare->cond_writer, 0);
|
||||
|
||||
cshare->running_threads= num_threads;
|
||||
cshare->total_threads= num_threads;
|
||||
cshare->error= 0; /* Initialize. */
|
||||
cshare->buffer= read_cache->buffer;
|
||||
cshare->read_end= NULL; /* See function comment of lock_io_cache(). */
|
||||
cshare->pos_in_file= 0; /* See function comment of lock_io_cache(). */
|
||||
cshare->source_cache= write_cache; /* Can be NULL. */
|
||||
|
||||
read_cache->share= cshare;
|
||||
read_cache->read_function= _my_b_read_r;
|
||||
read_cache->current_pos= NULL;
|
||||
read_cache->current_end= NULL;
|
||||
|
||||
if (write_cache)
|
||||
write_cache->share= cshare;
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Remove a thread from shared access to IO_CACHE
|
||||
Every thread should do that on exit for not
|
||||
to deadlock other threads
|
||||
Remove a thread from shared access to IO_CACHE.
|
||||
|
||||
SYNOPSIS
|
||||
remove_io_thread()
|
||||
cache The IO_CACHE to be removed from the share.
|
||||
|
||||
NOTE
|
||||
|
||||
Every thread must do that on exit for not to deadlock other threads.
|
||||
|
||||
The last thread destroys the pthread resources.
|
||||
|
||||
A writer flushes its cache first.
|
||||
|
||||
RETURN
|
||||
void
|
||||
*/
|
||||
void remove_io_thread(IO_CACHE *info)
|
||||
|
||||
void remove_io_thread(IO_CACHE *cache)
|
||||
{
|
||||
IO_CACHE_SHARE *s=info->share;
|
||||
IO_CACHE_SHARE *cshare= cache->share;
|
||||
uint total;
|
||||
DBUG_ENTER("remove_io_thread");
|
||||
|
||||
pthread_mutex_lock(&s->mutex);
|
||||
s->total--;
|
||||
if (! s->count--)
|
||||
pthread_cond_signal(&s->cond);
|
||||
pthread_mutex_unlock(&s->mutex);
|
||||
}
|
||||
/* If the writer goes, it needs to flush the write cache. */
|
||||
if (cache == cshare->source_cache)
|
||||
flush_io_cache(cache);
|
||||
|
||||
static int lock_io_cache(IO_CACHE *info, my_off_t pos)
|
||||
{
|
||||
int total;
|
||||
IO_CACHE_SHARE *s=info->share;
|
||||
pthread_mutex_lock(&cshare->mutex);
|
||||
DBUG_PRINT("io_cache_share", ("%s: 0x%lx",
|
||||
(cache == cshare->source_cache) ?
|
||||
"writer" : "reader", cache));
|
||||
|
||||
pthread_mutex_lock(&s->mutex);
|
||||
if (!s->count)
|
||||
/* Remove from share. */
|
||||
total= --cshare->total_threads;
|
||||
DBUG_PRINT("io_cache_share", ("remaining threads: %u", total));
|
||||
|
||||
/* Detach from share. */
|
||||
cache->share= NULL;
|
||||
|
||||
/* If the writer goes, let the readers know. */
|
||||
if (cache == cshare->source_cache)
|
||||
{
|
||||
s->count=s->total;
|
||||
return 1;
|
||||
DBUG_PRINT("io_cache_share", ("writer leaves"));
|
||||
cshare->source_cache= NULL;
|
||||
}
|
||||
|
||||
total=s->total;
|
||||
s->count--;
|
||||
while (!s->active || s->active->pos_in_file < pos)
|
||||
pthread_cond_wait(&s->cond, &s->mutex);
|
||||
/* If all threads are waiting for me to join the lock, wake them. */
|
||||
if (!--cshare->running_threads)
|
||||
{
|
||||
DBUG_PRINT("io_cache_share", ("the last running thread leaves, wake all"));
|
||||
pthread_cond_signal(&cshare->cond_writer);
|
||||
pthread_cond_broadcast(&cshare->cond);
|
||||
}
|
||||
|
||||
if (s->total < total &&
|
||||
(!s->active || s->active->pos_in_file < pos))
|
||||
return 1;
|
||||
pthread_mutex_unlock(&cshare->mutex);
|
||||
|
||||
pthread_mutex_unlock(&s->mutex);
|
||||
return 0;
|
||||
if (!total)
|
||||
{
|
||||
DBUG_PRINT("io_cache_share", ("last thread removed, destroy share"));
|
||||
pthread_cond_destroy (&cshare->cond_writer);
|
||||
pthread_cond_destroy (&cshare->cond);
|
||||
pthread_mutex_destroy(&cshare->mutex);
|
||||
}
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
static void unlock_io_cache(IO_CACHE *info)
|
||||
|
||||
/*
|
||||
Lock IO cache and wait for all other threads to join.
|
||||
|
||||
SYNOPSIS
|
||||
lock_io_cache()
|
||||
cache The cache of the thread entering the lock.
|
||||
pos File position of the block to read.
|
||||
Unused for the write thread.
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
Wait for all threads to finish with the current buffer. We want
|
||||
all threads to proceed in concert. The last thread to join
|
||||
lock_io_cache() will read the block from file and all threads start
|
||||
to use it. Then they will join again for reading the next block.
|
||||
|
||||
The waiting threads detect a fresh buffer by comparing
|
||||
cshare->pos_in_file with the position they want to process next.
|
||||
Since the first block may start at position 0, we take
|
||||
cshare->read_end as an additional condition. This variable is
|
||||
initialized to NULL and will be set after a block of data is written
|
||||
to the buffer.
|
||||
|
||||
RETURN
|
||||
1 OK, lock in place, go ahead and read.
|
||||
0 OK, unlocked, another thread did the read.
|
||||
*/
|
||||
|
||||
static int lock_io_cache(IO_CACHE *cache, my_off_t pos)
|
||||
{
|
||||
pthread_cond_broadcast(&info->share->cond);
|
||||
pthread_mutex_unlock(&info->share->mutex);
|
||||
IO_CACHE_SHARE *cshare= cache->share;
|
||||
DBUG_ENTER("lock_io_cache");
|
||||
|
||||
/* Enter the lock. */
|
||||
pthread_mutex_lock(&cshare->mutex);
|
||||
cshare->running_threads--;
|
||||
DBUG_PRINT("io_cache_share", ("%s: 0x%lx pos: %lu running: %u",
|
||||
(cache == cshare->source_cache) ?
|
||||
"writer" : "reader", cache, (ulong) pos,
|
||||
cshare->running_threads));
|
||||
|
||||
if (cshare->source_cache)
|
||||
{
|
||||
/* A write cache is synchronized to the read caches. */
|
||||
|
||||
if (cache == cshare->source_cache)
|
||||
{
|
||||
/* The writer waits until all readers are here. */
|
||||
while (cshare->running_threads)
|
||||
{
|
||||
DBUG_PRINT("io_cache_share", ("writer waits in lock"));
|
||||
pthread_cond_wait(&cshare->cond_writer, &cshare->mutex);
|
||||
}
|
||||
DBUG_PRINT("io_cache_share", ("writer awoke, going to copy"));
|
||||
|
||||
/* Stay locked. Leave the lock later by unlock_io_cache(). */
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
/* The last thread wakes the writer. */
|
||||
if (!cshare->running_threads)
|
||||
{
|
||||
DBUG_PRINT("io_cache_share", ("waking writer"));
|
||||
pthread_cond_signal(&cshare->cond_writer);
|
||||
}
|
||||
|
||||
/*
|
||||
Readers wait until the data is copied from the writer. Another
|
||||
reason to stop waiting is the removal of the write thread. If this
|
||||
happens, we leave the lock with old data in the buffer.
|
||||
*/
|
||||
while ((!cshare->read_end || (cshare->pos_in_file < pos)) &&
|
||||
cshare->source_cache)
|
||||
{
|
||||
DBUG_PRINT("io_cache_share", ("reader waits in lock"));
|
||||
pthread_cond_wait(&cshare->cond, &cshare->mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
If the writer was removed from the share while this thread was
|
||||
asleep, we need to simulate an EOF condition. The writer cannot
|
||||
reset the share variables as they might still be in use by readers
|
||||
of the last block. When we awake here then because the last
|
||||
joining thread signalled us. If the writer is not the last, it
|
||||
will not signal. So it is safe to clear the buffer here.
|
||||
*/
|
||||
if (!cshare->read_end || (cshare->pos_in_file < pos))
|
||||
{
|
||||
DBUG_PRINT("io_cache_share", ("reader found writer removed. EOF"));
|
||||
cshare->read_end= cshare->buffer; /* Empty buffer. */
|
||||
cshare->error= 0; /* EOF is not an error. */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
There are read caches only. The last thread arriving in
|
||||
lock_io_cache() continues with a locked cache and reads the block.
|
||||
*/
|
||||
if (!cshare->running_threads)
|
||||
{
|
||||
DBUG_PRINT("io_cache_share", ("last thread joined, going to read"));
|
||||
/* Stay locked. Leave the lock later by unlock_io_cache(). */
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
/*
|
||||
All other threads wait until the requested block is read by the
|
||||
last thread arriving. Another reason to stop waiting is the
|
||||
removal of a thread. If this leads to all threads being in the
|
||||
lock, we have to continue also. The first of the awaken threads
|
||||
will then do the read.
|
||||
*/
|
||||
while ((!cshare->read_end || (cshare->pos_in_file < pos)) &&
|
||||
cshare->running_threads)
|
||||
{
|
||||
DBUG_PRINT("io_cache_share", ("reader waits in lock"));
|
||||
pthread_cond_wait(&cshare->cond, &cshare->mutex);
|
||||
}
|
||||
|
||||
/* If the block is not yet read, continue with a locked cache and read. */
|
||||
if (!cshare->read_end || (cshare->pos_in_file < pos))
|
||||
{
|
||||
DBUG_PRINT("io_cache_share", ("reader awoke, going to read"));
|
||||
/* Stay locked. Leave the lock later by unlock_io_cache(). */
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
/* Another thread did read the block already. */
|
||||
}
|
||||
DBUG_PRINT("io_cache_share", ("reader awoke, going to process %u bytes",
|
||||
cshare->read_end ? (uint)
|
||||
(cshare->read_end - cshare->buffer) : 0));
|
||||
|
||||
/*
|
||||
Leave the lock. Do not call unlock_io_cache() later. The thread that
|
||||
filled the buffer did this and marked all threads as running.
|
||||
*/
|
||||
pthread_mutex_unlock(&cshare->mutex);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Unlock IO cache.
|
||||
|
||||
SYNOPSIS
|
||||
unlock_io_cache()
|
||||
cache The cache of the thread leaving the lock.
|
||||
|
||||
NOTE
|
||||
This is called by the thread that filled the buffer. It marks all
|
||||
threads as running and awakes them. This must not be done by any
|
||||
other thread.
|
||||
|
||||
Do not signal cond_writer. Either there is no writer or the writer
|
||||
is the only one who can call this function.
|
||||
|
||||
The reason for resetting running_threads to total_threads before
|
||||
waking all other threads is that it could be possible that this
|
||||
thread is so fast with processing the buffer that it enters the lock
|
||||
before even one other thread has left it. If every awoken thread
|
||||
would increase running_threads by one, this thread could think that
|
||||
he is again the last to join and would not wait for the other
|
||||
threads to process the data.
|
||||
|
||||
RETURN
|
||||
void
|
||||
*/
|
||||
|
||||
static void unlock_io_cache(IO_CACHE *cache)
|
||||
{
|
||||
IO_CACHE_SHARE *cshare= cache->share;
|
||||
DBUG_ENTER("unlock_io_cache");
|
||||
DBUG_PRINT("io_cache_share", ("%s: 0x%lx pos: %lu running: %u",
|
||||
(cache == cshare->source_cache) ?
|
||||
"writer" : "reader",
|
||||
cache, (ulong) cshare->pos_in_file,
|
||||
cshare->total_threads));
|
||||
|
||||
cshare->running_threads= cshare->total_threads;
|
||||
pthread_cond_broadcast(&cshare->cond);
|
||||
pthread_mutex_unlock(&cshare->mutex);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
|
@ -569,7 +869,7 @@ static void unlock_io_cache(IO_CACHE *info)
|
|||
|
||||
SYNOPSIS
|
||||
_my_b_read_r()
|
||||
info IO_CACHE pointer
|
||||
cache IO_CACHE pointer
|
||||
Buffer Buffer to retrieve count bytes from file
|
||||
Count Number of bytes to read into Buffer
|
||||
|
||||
|
@ -581,7 +881,7 @@ static void unlock_io_cache(IO_CACHE *info)
|
|||
|
||||
It works as follows: when a thread tries to read from a file (that
|
||||
is, after using all the data from the (shared) buffer), it just
|
||||
hangs on lock_io_cache(), wating for other threads. When the very
|
||||
hangs on lock_io_cache(), waiting for other threads. When the very
|
||||
last thread attempts a read, lock_io_cache() returns 1, the thread
|
||||
does actual IO and unlock_io_cache(), which signals all the waiting
|
||||
threads that data is in the buffer.
|
||||
|
@ -601,16 +901,17 @@ static void unlock_io_cache(IO_CACHE *info)
|
|||
1 Error: can't read requested characters
|
||||
*/
|
||||
|
||||
int _my_b_read_r(register IO_CACHE *info, byte *Buffer, uint Count)
|
||||
int _my_b_read_r(register IO_CACHE *cache, byte *Buffer, uint Count)
|
||||
{
|
||||
my_off_t pos_in_file;
|
||||
uint length, diff_length, left_length;
|
||||
IO_CACHE_SHARE *cshare= cache->share;
|
||||
DBUG_ENTER("_my_b_read_r");
|
||||
|
||||
if ((left_length= (uint) (info->read_end - info->read_pos)))
|
||||
if ((left_length= (uint) (cache->read_end - cache->read_pos)))
|
||||
{
|
||||
DBUG_ASSERT(Count >= left_length); /* User is not using my_b_read() */
|
||||
memcpy(Buffer, info->read_pos, (size_t) (left_length));
|
||||
memcpy(Buffer, cache->read_pos, (size_t) (left_length));
|
||||
Buffer+= left_length;
|
||||
Count-= left_length;
|
||||
}
|
||||
|
@ -618,55 +919,133 @@ int _my_b_read_r(register IO_CACHE *info, byte *Buffer, uint Count)
|
|||
{
|
||||
int cnt, len;
|
||||
|
||||
pos_in_file= info->pos_in_file + (info->read_end - info->buffer);
|
||||
pos_in_file= cache->pos_in_file + (cache->read_end - cache->buffer);
|
||||
diff_length= (uint) (pos_in_file & (IO_SIZE-1));
|
||||
length=IO_ROUND_UP(Count+diff_length)-diff_length;
|
||||
length=(length <= info->read_length) ?
|
||||
length + IO_ROUND_DN(info->read_length - length) :
|
||||
length - IO_ROUND_UP(length - info->read_length) ;
|
||||
if (info->type != READ_FIFO &&
|
||||
(length > (info->end_of_file - pos_in_file)))
|
||||
length= (uint) (info->end_of_file - pos_in_file);
|
||||
length= ((length <= cache->read_length) ?
|
||||
length + IO_ROUND_DN(cache->read_length - length) :
|
||||
length - IO_ROUND_UP(length - cache->read_length));
|
||||
if (cache->type != READ_FIFO &&
|
||||
(length > (cache->end_of_file - pos_in_file)))
|
||||
length= (uint) (cache->end_of_file - pos_in_file);
|
||||
if (length == 0)
|
||||
{
|
||||
info->error= (int) left_length;
|
||||
cache->error= (int) left_length;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (lock_io_cache(info, pos_in_file))
|
||||
if (lock_io_cache(cache, pos_in_file))
|
||||
{
|
||||
info->share->active=info;
|
||||
if (info->seek_not_done) /* File touched, do seek */
|
||||
VOID(my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)));
|
||||
len=(int)my_read(info->file,info->buffer, length, info->myflags);
|
||||
info->read_end=info->buffer + (len == -1 ? 0 : len);
|
||||
info->error=(len == (int)length ? 0 : len);
|
||||
info->pos_in_file=pos_in_file;
|
||||
unlock_io_cache(info);
|
||||
/* With a synchronized write/read cache we won't come here... */
|
||||
DBUG_ASSERT(!cshare->source_cache);
|
||||
/*
|
||||
... unless the writer has gone before this thread entered the
|
||||
lock. Simulate EOF in this case. It can be distinguished by
|
||||
cache->file.
|
||||
*/
|
||||
if (cache->file < 0)
|
||||
len= 0;
|
||||
else
|
||||
{
|
||||
if (cache->seek_not_done) /* File touched, do seek */
|
||||
VOID(my_seek(cache->file, pos_in_file, MY_SEEK_SET, MYF(0)));
|
||||
len= (int) my_read(cache->file, cache->buffer, length, cache->myflags);
|
||||
}
|
||||
DBUG_PRINT("io_cache_share", ("read %d bytes", len));
|
||||
|
||||
cache->read_end= cache->buffer + (len == -1 ? 0 : len);
|
||||
cache->error= (len == (int)length ? 0 : len);
|
||||
cache->pos_in_file= pos_in_file;
|
||||
|
||||
/* Copy important values to the share. */
|
||||
cshare->error= cache->error;
|
||||
cshare->read_end= cache->read_end;
|
||||
cshare->pos_in_file= pos_in_file;
|
||||
|
||||
/* Mark all threads as running and wake them. */
|
||||
unlock_io_cache(cache);
|
||||
}
|
||||
else
|
||||
{
|
||||
info->error= info->share->active->error;
|
||||
info->read_end= info->share->active->read_end;
|
||||
info->pos_in_file= info->share->active->pos_in_file;
|
||||
len= (int) (info->error == -1 ? -1 : info->read_end-info->buffer);
|
||||
/*
|
||||
With a synchronized write/read cache readers always come here.
|
||||
Copy important values from the share.
|
||||
*/
|
||||
cache->error= cshare->error;
|
||||
cache->read_end= cshare->read_end;
|
||||
cache->pos_in_file= cshare->pos_in_file;
|
||||
|
||||
len= (int) ((cache->error == -1) ? -1 : cache->read_end - cache->buffer);
|
||||
}
|
||||
info->read_pos=info->buffer;
|
||||
info->seek_not_done=0;
|
||||
cache->read_pos= cache->buffer;
|
||||
cache->seek_not_done= 0;
|
||||
if (len <= 0)
|
||||
{
|
||||
info->error= (int) left_length;
|
||||
DBUG_PRINT("io_cache_share", ("reader error. len %d left %u",
|
||||
len, left_length));
|
||||
cache->error= (int) left_length;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
cnt= ((uint) len > Count) ? (int) Count : len;
|
||||
memcpy(Buffer, info->read_pos, (size_t) cnt);
|
||||
memcpy(Buffer, cache->read_pos, (size_t) cnt);
|
||||
Count -= cnt;
|
||||
Buffer+= cnt;
|
||||
left_length+= cnt;
|
||||
info->read_pos+= cnt;
|
||||
cache->read_pos+= cnt;
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Copy data from write cache to read cache.
|
||||
|
||||
SYNOPSIS
|
||||
copy_to_read_buffer()
|
||||
write_cache The write cache.
|
||||
write_buffer The source of data, mostly the cache buffer.
|
||||
write_length The number of bytes to copy.
|
||||
|
||||
NOTE
|
||||
The write thread will wait for all read threads to join the cache
|
||||
lock. Then it copies the data over and wakes the read threads.
|
||||
|
||||
RETURN
|
||||
void
|
||||
*/
|
||||
|
||||
static void copy_to_read_buffer(IO_CACHE *write_cache,
|
||||
const byte *write_buffer, uint write_length)
|
||||
{
|
||||
IO_CACHE_SHARE *cshare= write_cache->share;
|
||||
|
||||
DBUG_ASSERT(cshare->source_cache == write_cache);
|
||||
/*
|
||||
write_length is usually less or equal to buffer_length.
|
||||
It can be bigger if _my_b_write() is called with a big length.
|
||||
*/
|
||||
while (write_length)
|
||||
{
|
||||
uint copy_length= min(write_length, write_cache->buffer_length);
|
||||
int __attribute__((unused)) rc;
|
||||
|
||||
rc= lock_io_cache(write_cache, write_cache->pos_in_file);
|
||||
/* The writing thread does always have the lock when it awakes. */
|
||||
DBUG_ASSERT(rc);
|
||||
|
||||
memcpy(cshare->buffer, write_buffer, copy_length);
|
||||
|
||||
cshare->error= 0;
|
||||
cshare->read_end= cshare->buffer + copy_length;
|
||||
cshare->pos_in_file= write_cache->pos_in_file;
|
||||
|
||||
/* Mark all threads as running and wake them. */
|
||||
unlock_io_cache(write_cache);
|
||||
|
||||
write_buffer+= copy_length;
|
||||
write_length-= copy_length;
|
||||
}
|
||||
}
|
||||
#endif /*THREAD*/
|
||||
|
||||
|
||||
/*
|
||||
|
@ -1018,6 +1397,7 @@ int _my_b_write(register IO_CACHE *info, const byte *Buffer, uint Count)
|
|||
Buffer+=rest_length;
|
||||
Count-=rest_length;
|
||||
info->write_pos+=rest_length;
|
||||
|
||||
if (my_b_flush_io_cache(info,1))
|
||||
return 1;
|
||||
if (Count >= IO_SIZE)
|
||||
|
@ -1030,6 +1410,23 @@ int _my_b_write(register IO_CACHE *info, const byte *Buffer, uint Count)
|
|||
}
|
||||
if (my_write(info->file,Buffer,(uint) length,info->myflags | MY_NABP))
|
||||
return info->error= -1;
|
||||
|
||||
#ifdef THREAD
|
||||
/*
|
||||
In case of a shared I/O cache with a writer we normally do direct
|
||||
write cache to read cache copy. Simulate this here by direct
|
||||
caller buffer to read cache copy. Do it after the write so that
|
||||
the cache readers actions on the flushed part can go in parallel
|
||||
with the write of the extra stuff. copy_to_read_buffer()
|
||||
synchronizes writer and readers so that after this call the
|
||||
readers can act on the extra stuff while the writer can go ahead
|
||||
and prepare the next output. copy_to_read_buffer() relies on
|
||||
info->pos_in_file.
|
||||
*/
|
||||
if (info->share)
|
||||
copy_to_read_buffer(info, Buffer, length);
|
||||
#endif
|
||||
|
||||
Count-=length;
|
||||
Buffer+=length;
|
||||
info->pos_in_file+=length;
|
||||
|
@ -1050,6 +1447,14 @@ int my_b_append(register IO_CACHE *info, const byte *Buffer, uint Count)
|
|||
{
|
||||
uint rest_length,length;
|
||||
|
||||
#ifdef THREAD
|
||||
/*
|
||||
Assert that we cannot come here with a shared cache. If we do one
|
||||
day, we might need to add a call to copy_to_read_buffer().
|
||||
*/
|
||||
DBUG_ASSERT(!info->share);
|
||||
#endif
|
||||
|
||||
lock_append_buffer(info);
|
||||
rest_length=(uint) (info->write_end - info->write_pos);
|
||||
if (Count <= rest_length)
|
||||
|
@ -1110,6 +1515,14 @@ int my_block_write(register IO_CACHE *info, const byte *Buffer, uint Count,
|
|||
uint length;
|
||||
int error=0;
|
||||
|
||||
#ifdef THREAD
|
||||
/*
|
||||
Assert that we cannot come here with a shared cache. If we do one
|
||||
day, we might need to add a call to copy_to_read_buffer().
|
||||
*/
|
||||
DBUG_ASSERT(!info->share);
|
||||
#endif
|
||||
|
||||
if (pos < info->pos_in_file)
|
||||
{
|
||||
/* Of no overlap, write everything without buffering */
|
||||
|
@ -1186,6 +1599,17 @@ int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock)
|
|||
|
||||
if ((length=(uint) (info->write_pos - info->write_buffer)))
|
||||
{
|
||||
#ifdef THREAD
|
||||
/*
|
||||
In case of a shared I/O cache with a writer we do direct write
|
||||
cache to read cache copy. Do it before the write here so that
|
||||
the readers can work in parallel with the write.
|
||||
copy_to_read_buffer() relies on info->pos_in_file.
|
||||
*/
|
||||
if (info->share)
|
||||
copy_to_read_buffer(info, info->write_buffer, length);
|
||||
#endif
|
||||
|
||||
pos_in_file=info->pos_in_file;
|
||||
/*
|
||||
If we have append cache, we always open the file with
|
||||
|
@ -1265,16 +1689,10 @@ int end_io_cache(IO_CACHE *info)
|
|||
|
||||
#ifdef THREAD
|
||||
/*
|
||||
if IO_CACHE is shared between several threads, only one
|
||||
thread needs to call end_io_cache() - just as init_io_cache()
|
||||
should be called only once and then memcopy'ed
|
||||
Every thread must call remove_io_thread(). The last one destroys
|
||||
the share elements.
|
||||
*/
|
||||
if (info->share)
|
||||
{
|
||||
pthread_cond_destroy(&info->share->cond);
|
||||
pthread_mutex_destroy(&info->share->mutex);
|
||||
info->share=0;
|
||||
}
|
||||
DBUG_ASSERT(!info->share || !info->share->total_threads);
|
||||
#endif
|
||||
|
||||
if ((pre_close=info->pre_close))
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/* To avoid problems with alarms in debug code, we disable DBUG here */
|
||||
#undef DBUG_OFF
|
||||
#define DBUG_OFF
|
||||
#define FORCE_DBUG_OFF
|
||||
#include <my_global.h>
|
||||
|
||||
#if defined(THREAD) && !defined(DONT_USE_THR_ALARM)
|
||||
|
|
|
@ -72,7 +72,7 @@ multiple read locks.
|
|||
*/
|
||||
|
||||
#if !defined(MAIN) && !defined(DBUG_OFF) && !defined(EXTRA_DEBUG)
|
||||
#define DBUG_OFF
|
||||
#define FORCE_DBUG_OFF
|
||||
#endif
|
||||
|
||||
#include "mysys_priv.h"
|
||||
|
|
|
@ -5,8 +5,11 @@
|
|||
|
||||
# stop on errors
|
||||
set -e
|
||||
sed -e "s/^DIST_COMMON/#DIST_COMMON/g" storage/ndb/Makefile.am > storage/ndb/Makefile.am.$$
|
||||
mv storage/ndb/Makefile.am.$$ storage/ndb/Makefile.am
|
||||
|
||||
for package in . ./storage/innobase
|
||||
# for package in . ./storage/innobase
|
||||
for package in .
|
||||
do
|
||||
(cd $package
|
||||
rm -rf config.cache autom4te.cache
|
||||
|
@ -14,6 +17,7 @@ do
|
|||
autoheader
|
||||
libtoolize --force
|
||||
aclocal
|
||||
# automake --verbose --add-missing --force-missing
|
||||
automake --add-missing --force-missing
|
||||
autoconf)
|
||||
done
|
||||
|
|
|
@ -24,5 +24,4 @@ base_configs=" \
|
|||
--prefix=N:/mysql \
|
||||
--without-mysqlmanager \
|
||||
--without-man \
|
||||
--without-csv-storage-engine \
|
||||
"
|
||||
|
|
|
@ -8,7 +8,7 @@ fi
|
|||
|
||||
# The base path(in wineformat) where compilers, includes and
|
||||
# libraries are installed
|
||||
if test -z $MYDEV
|
||||
if test -z "$MYDEV"
|
||||
then
|
||||
# the default is "F:/mydev"
|
||||
export MYDEV="F:/mydev"
|
||||
|
|
|
@ -151,17 +151,18 @@ echo "making files writable..."
|
|||
cd $target_dir
|
||||
chmod -R u+rw,g+rw .
|
||||
|
||||
# edit the mvenv file
|
||||
echo "updating the mwenv environment file..."
|
||||
## # edit the mvenv file
|
||||
## echo "updating the mwenv environment file..."
|
||||
mwenv="./netware/BUILD/mwenv"
|
||||
mv -f $mwenv $mwenv.org
|
||||
sed -e "s;WINE_BUILD_DIR;$wine_build_dir;g" \
|
||||
-e "s;BUILD_DIR;$build_dir;g" \
|
||||
-e "s;VERSION;$version;g" $mwenv.org > $mwenv
|
||||
chmod +rwx $mwenv
|
||||
## mv -f $mwenv $mwenv.org
|
||||
## sed -e "s;WINE_BUILD_DIR;$wine_build_dir;g" \
|
||||
## -e "s;BUILD_DIR;$build_dir;g" \
|
||||
## -e "s;VERSION;$version;g" $mwenv.org > $mwenv
|
||||
## chmod +rwx $mwenv
|
||||
|
||||
PWD=`pwd`
|
||||
SRC_DIR=`grep "^export MYDEV=" $mwenv | cut -d'=' -f2 | \
|
||||
# This line will catch the default value only, let's hope it is correct
|
||||
SRC_DIR=`grep "^ *export MYDEV=" $mwenv | cut -d'=' -f2 | \
|
||||
sed -e 's;";;g' -e "s;^;echo ;g" -e "s;$;/\`basename $PWD\`;g" | /bin/sh`
|
||||
|
||||
|
||||
|
|
|
@ -253,8 +253,8 @@ $CP mysql-test/t/*.test $BASE/mysql-test/t
|
|||
$CP mysql-test/t/*.imtest mysql-test/t/*.disabled $BASE/mysql-test/t
|
||||
$CP mysql-test/t/*.opt mysql-test/t/*.slave-mi $BASE/mysql-test/t
|
||||
$CP mysql-test/t/*.sh mysql-test/t/*.sql $BASE/mysql-test/t
|
||||
$CP mysql-test/r/*.result mysql-test/r/*.require \
|
||||
$BASE/mysql-test/r
|
||||
$CP mysql-test/r/*.result $BASE/mysql-test/r
|
||||
$CP mysql-test/r/*.require $BASE/mysql-test/r
|
||||
$CP mysql-test/extra/binlog_tests/*.test $BASE/mysql-test/extra/binlog_tests
|
||||
$CP mysql-test/extra/rpl_tests/*.test $BASE/mysql-test/extra/rpl_tests
|
||||
|
||||
|
@ -326,14 +326,16 @@ fi
|
|||
|
||||
# NDB Cluster
|
||||
if [ x$NDBCLUSTER = x1 ]; then
|
||||
( cd storage/ndb ; @MAKE@ DESTDIR=$BASE/ndb-stage install )
|
||||
( cd mysql-test/ndb ; @MAKE@ DESTDIR=$BASE/ndb-stage install )
|
||||
( cd storage/ndb ; @MAKE@ DESTDIR=$BASE/ndb-stage install )
|
||||
( cd mysql-test ; @MAKE@ DESTDIR=$BASE/ndb-stage install )
|
||||
$CP $BASE/ndb-stage@bindir@/* $BASE/bin/.
|
||||
$CP $BASE/ndb-stage@libexecdir@/* $BASE/bin/.
|
||||
$CP $BASE/ndb-stage@pkglibdir@/* $BASE/lib/.
|
||||
test -d $BASE/include/storage || mkdir $BASE/include/storage
|
||||
$CP -r $BASE/ndb-stage@pkgincludedir@/storage/ndb $BASE/include/storage/
|
||||
$CP -r $BASE/ndb-stage@prefix@/mysql-test/ndb $BASE/mysql-test/. || exit 1
|
||||
$CP -r $BASE/ndb-stage@prefix@/mysql-test/std_data/ndb_backup50 $BASE/mysql-test/std_data/. || exit 1
|
||||
$CP -r $BASE/ndb-stage@prefix@/mysql-test/std_data/ndb_backup51 $BASE/mysql-test/std_data/. || exit 1
|
||||
rm -rf $BASE/ndb-stage
|
||||
fi
|
||||
|
||||
|
|
|
@ -1,41 +1,227 @@
|
|||
#! /bin/sh
|
||||
#!/bin/sh
|
||||
|
||||
NOINST_NAME=$1
|
||||
# Exit if failing to copy, we want exact specifications, not
|
||||
# just "what happen to be built".
|
||||
set -e
|
||||
|
||||
mkdir $NOINST_NAME
|
||||
mkdir $NOINST_NAME/bin
|
||||
cp client/release/*.exe $NOINST_NAME/bin/
|
||||
cp extra/release/*.exe $NOINST_NAME/bin/
|
||||
mv $NOINST_NAME/bin/comp_err.exe $NOINST_NAME/bin/comp-err.exe
|
||||
cp storage/myisam/release/*.exe $NOINST_NAME/bin/
|
||||
cp server-tools/instance-manager/release/*.exe $NOINST_NAME/bin/
|
||||
cp tests/release/*.exe $NOINST_NAME/bin/
|
||||
cp libmysql/release/*.exe $NOINST_NAME/bin/
|
||||
cp libmysql/release/libmysql.dll $NOINST_NAME/bin/
|
||||
# ----------------------------------------------------------------------
|
||||
# Read first argument that is the base name of the resulting TAR file.
|
||||
# See usage() function below for a description on the arguments.
|
||||
#
|
||||
# NOTE: We will read the rest of the command line later on.
|
||||
# NOTE: Pattern matching with "{..,..}" can't be used, not portable.
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
cp sql/release/mysqld.exe $NOINST_NAME/bin/mysqld.exe
|
||||
cp sql/debug/mysqld.exe $NOINST_NAME/bin/mysqld-debug.exe
|
||||
# For Pro/Classic builds, do this instead:
|
||||
# cp sql/release/mysqld.exe $NOINST_NAME/bin/mysqld-nt.exe
|
||||
# cp sql/debug/mysqld.exe $NOINST_NAME/bin/mysqld-debug.exe
|
||||
# FIXME FIXME "debug", own build or handled here?
|
||||
# FIXME FIXME add way to copy from other builds executables
|
||||
|
||||
cp COPYING EXCEPTIONS-CLIENT $NOINST_NAME/
|
||||
cp -dpR win/data $NOINST_NAME/data
|
||||
mkdir $NOINST_NAME/Docs
|
||||
cp Docs/INSTALL-BINARY Docs/manual.chm ChangeLog COPYING $NOINST_NAME/Docs/
|
||||
usage()
|
||||
{
|
||||
echo <<EOF
|
||||
Usage: make_win_bin_dist [ options ] package-base-name [ copy-defs... ]
|
||||
|
||||
# These will be filled in when we enable embedded.
|
||||
mkdir -p $NOINST_NAME/Embedded/DLL/debug $NOINST_NAME/Embedded/DLL/release $NOINST_NAME/Embedded/static/release
|
||||
This is a script to run from the top of a source tree built on Windows.
|
||||
The "package-base-name" argument should be something like
|
||||
|
||||
mkdir -p $NOINST_NAME/examples/libmysqltest/debug $NOINST_NAME/examples/libmysqltest/release
|
||||
cp libmysql/mytest.c libmysql/myTest.vcproj libmysql/release/myTest.exe $NOINST_NAME/examples/libmysqltest/
|
||||
cp libmysql/debug/myTest.exe $NOINST_NAME/examples/libmysqltest/debug/
|
||||
cp libmysql/release/myTest.exe $NOINST_NAME/examples/libmysqltest/release/
|
||||
mysql-noinstall-5.0.25-win32 (or winx64)
|
||||
|
||||
mkdir -p $NOINST_NAME/examples/tests
|
||||
cp tests/*.res tests/*.tst tests/*.pl tests/*.c $NOINST_NAME/examples/tests/
|
||||
and will be the name of the directory of the unpacked ZIP (stripping
|
||||
away the "noinstall" part of the ZIP file name if any) and the base
|
||||
for the resulting package name.
|
||||
|
||||
mkdir -p $NOINST_NAME/include
|
||||
Options are
|
||||
|
||||
--embedded Pack the embedded server and give error if not built.
|
||||
The default is to pack it if it is built.
|
||||
|
||||
--no-embedded Don't pack the embedded server even if built
|
||||
|
||||
--debug Pack the debug binaries and give error if not built.
|
||||
|
||||
--no-debug Don't pack the debug binaries even if built
|
||||
|
||||
--only-debug The target for this build was "Debug", and we just
|
||||
want to replace the normal binaries with debug
|
||||
versions, i.e. no separate "debug" directories.
|
||||
|
||||
--exe-suffix=SUF Add a suffix to the "mysqld" binary.
|
||||
|
||||
As you might want to include files of directories from other builds
|
||||
(like a "mysqld-max.exe" server), you can instruct this script do copy
|
||||
them in for you. This is the "copy-def" arguments, and they are of the
|
||||
form
|
||||
|
||||
relative-dest-name=source-name .....
|
||||
|
||||
i.e. can be something like
|
||||
|
||||
bin/mysqld-max.exe=../my-max-build/sql/release/mysqld.exe
|
||||
|
||||
If you specify a directory the whole directory will be copied.
|
||||
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# We need to be at the top of a source tree, check that we are
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
if [ ! -d "sql" ] ; then
|
||||
echo "You need to run this script from inside the source tree"
|
||||
usage
|
||||
fi
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Actual argument processing, first part
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
NOINST_NAME=""
|
||||
TARGET="release"
|
||||
PACK_EMBEDDED="" # Could be "no", "yes" or empty
|
||||
PACK_DEBUG="" # Could be "no", "yes" or empty
|
||||
EXE_SUFFIX=""
|
||||
|
||||
for arg do
|
||||
shift
|
||||
case "$arg" in
|
||||
--embedded) PACK_EMBEDDED="yes" ;;
|
||||
--no-embedded) PACK_EMBEDDED="no" ;;
|
||||
--debug) PACK_DEBUG="yes" ;;
|
||||
--no-debug) PACK_DEBUG="no" ;;
|
||||
--only-debug) TARGET="debug" ; PACK_DEBUG="no" ;;
|
||||
--exe-suffix=*) EXE_SUFFIX=`echo "$arg" | sed -e "s,--exe-suffix=,,"` ;;
|
||||
-*)
|
||||
echo "Unknown argument '$arg'"
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
NOINST_NAME="$arg"
|
||||
break
|
||||
esac
|
||||
done
|
||||
|
||||
if [ x"$NOINST_NAME" = x"" ] ; then
|
||||
echo "No base package name given"
|
||||
usage
|
||||
fi
|
||||
DESTDIR=`echo $NOINST_NAME | sed 's/-noinstall-/-/'`
|
||||
|
||||
if [ -e $DESTDIR ] ; then
|
||||
echo "Please remove the old $DESTDIR before running this script"
|
||||
usage
|
||||
fi
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Copy executables, and client DLL (FIXME why?)
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
trap 'echo "Clearning up and exiting..." ; rm -fr $DESTDIR; exit 1' ERR
|
||||
|
||||
mkdir $DESTDIR
|
||||
mkdir $DESTDIR/bin
|
||||
cp client/$TARGET/*.exe $DESTDIR/bin/
|
||||
cp extra/$TARGET/*.exe $DESTDIR/bin/
|
||||
cp storage/myisam/$TARGET/*.exe $DESTDIR/bin/
|
||||
cp server-tools/instance-manager/$TARGET/*.exe $DESTDIR/bin/
|
||||
cp tests/$TARGET/*.exe $DESTDIR/bin/
|
||||
cp libmysql/$TARGET/*.exe $DESTDIR/bin/
|
||||
cp libmysql/$TARGET/libmysql.dll $DESTDIR/bin/
|
||||
|
||||
# FIXME really needed?!
|
||||
mv $DESTDIR/bin/comp_err.exe $DESTDIR/bin/comp-err.exe
|
||||
|
||||
cp sql/$TARGET/mysqld.exe $DESTDIR/bin/mysqld$EXE_SUFFIX.exe
|
||||
|
||||
if [ x"$PACK_DEBUG" = "" -a -f "sql/debug/mysqld.exe" -o \
|
||||
x"$PACK_DEBUG" = "yes" ] ; then
|
||||
cp sql/debug/mysqld.exe $DESTDIR/bin/mysqld-debug.exe
|
||||
cp sql/debug/mysqld.pdb $DESTDIR/bin/mysqld-debug.pdb
|
||||
cp sql/debug/mysqld.map $DESTDIR/bin/mysqld-debug.map
|
||||
fi
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Copy data directory, readme files etc
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# FIXME is there ever a data directory to copy?
|
||||
if [ -d win/data ] ; then
|
||||
cp -pR win/data $DESTDIR/data
|
||||
fi
|
||||
|
||||
# FIXME maybe a flag to define "release build", or do the
|
||||
# check from the calling script that all these are there,
|
||||
# and with the correct content.
|
||||
|
||||
mkdir $DESTDIR/Docs
|
||||
cp Docs/INSTALL-BINARY $DESTDIR/Docs/
|
||||
cp Docs/manual.chm $DESTDIR/Docs/ || /bin/true
|
||||
cp ChangeLog $DESTDIR/Docs/ || /bin/true
|
||||
cp support-files/my-*.ini $DESTDIR/
|
||||
|
||||
if [ -f COPYING ] ; then
|
||||
cp COPYING EXCEPTIONS-CLIENT $DESTDIR/
|
||||
cp COPYING $DESTDIR/Docs/
|
||||
fi
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# These will be filled in when we enable embedded. Note that if no
|
||||
# argument is given, it is copied if exists, else a check is done.
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
copy_embedded()
|
||||
{
|
||||
mkdir -p $DESTDIR/Embedded/DLL/release \
|
||||
$DESTDIR/Embedded/static/release \
|
||||
$DESTDIR/include
|
||||
cp libmysqld/libmysqld.def $DESTDIR/include/
|
||||
cp libmysqld/$TARGET/mysqlserver.lib $DESTDIR/Embedded/static/release/
|
||||
cp libmysqld/$TARGET/libmysqld.dll $DESTDIR/Embedded/DLL/release/
|
||||
cp libmysqld/$TARGET/libmysqld.exp $DESTDIR/Embedded/DLL/release/
|
||||
cp libmysqld/$TARGET/libmysqld.lib $DESTDIR/Embedded/DLL/release/
|
||||
|
||||
if [ x"$PACK_DEBUG" = "" -a -f "libmysqld/debug/libmysqld.lib" -o \
|
||||
x"$PACK_DEBUG" = "yes" ] ; then
|
||||
mkdir -p $DESTDIR/Embedded/DLL/debug
|
||||
cp libmysqld/debug/libmysqld.dll $DESTDIR/Embedded/DLL/debug/
|
||||
cp libmysqld/debug/libmysqld.exp $DESTDIR/Embedded/DLL/debug/
|
||||
cp libmysqld/debug/libmysqld.lib $DESTDIR/Embedded/DLL/debug/
|
||||
fi
|
||||
}
|
||||
|
||||
if [ x"$PACK_EMBEDDED" = "" -a \
|
||||
-f "libmysqld/$TARGET/mysqlserver.lib" -a \
|
||||
-f "libmysqld/$TARGET/libmysqld.lib" -o \
|
||||
x"$PACK_EMBEDDED" = "yes" ] ; then
|
||||
copy_embedded
|
||||
fi
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# FIXME test stuff that is useless garbage?
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
mkdir -p $DESTDIR/examples/libmysqltest/release
|
||||
cp libmysql/mytest.c libmysql/myTest.vcproj libmysql/$TARGET/myTest.exe \
|
||||
$DESTDIR/examples/libmysqltest/
|
||||
cp libmysql/$TARGET/myTest.exe $DESTDIR/examples/libmysqltest/release/
|
||||
|
||||
if [ x"$PACK_DEBUG" = "" -a -f "libmysql/debug/myTest.exe" -o \
|
||||
x"$PACK_DEBUG" = "yes" ] ; then
|
||||
mkdir -p $DESTDIR/examples/libmysqltest/debug
|
||||
cp libmysql/debug/myTest.exe $DESTDIR/examples/libmysqltest/debug/
|
||||
fi
|
||||
|
||||
mkdir -p $DESTDIR/examples/tests
|
||||
cp tests/*.res tests/*.tst tests/*.pl tests/*.c $DESTDIR/examples/tests/
|
||||
|
||||
mkdir -p $DESTDIR/examples/udf_example
|
||||
cp sql/udf_example.def sql/udf_example.vcproj sql/udf_example.c $DESTDIR/examples/udf_example/
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# FIXME why not copy it all in "include"?!
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
mkdir -p $DESTDIR/include
|
||||
cp include/conf*.h \
|
||||
include/mysql*.h \
|
||||
include/errmsg.h \
|
||||
|
@ -48,69 +234,122 @@ cp include/conf*.h \
|
|||
include/m_string.h \
|
||||
include/m_ctype.h \
|
||||
include/my_global.h \
|
||||
include/typelib.h $NOINST_NAME/include/
|
||||
cp libmysql/libmysql.def $NOINST_NAME/include/
|
||||
cp libmysqld/libmysqld.def $NOINST_NAME/include/
|
||||
include/typelib.h $DESTDIR/include/
|
||||
cp libmysql/libmysql.def $DESTDIR/include/
|
||||
|
||||
mkdir -p $NOINST_NAME/lib/debug $NOINST_NAME/lib/opt
|
||||
cp libmysql/debug/libmysql.dll \
|
||||
libmysql/debug/libmysql.lib \
|
||||
client/debug/mysqlclient.lib \
|
||||
mysys/debug/mysys.lib \
|
||||
regex/debug/regex.lib \
|
||||
strings/debug/strings.lib \
|
||||
zlib/debug/zlib.lib $NOINST_NAME/lib/debug/
|
||||
cp libmysql/release/libmysql.dll \
|
||||
libmysql/release/libmysql.lib \
|
||||
client/release/mysqlclient.lib \
|
||||
regex/release/regex.lib \
|
||||
strings/release/strings.lib \
|
||||
zlib/release/zlib.lib $NOINST_NAME/lib/opt/
|
||||
cp mysys/release/mysys.lib $NOINST_NAME/lib/opt/mysys_tls.lib
|
||||
# ----------------------------------------------------------------------
|
||||
# Client libraries, and other libraries
|
||||
# FIXME why "libmysql.dll" installed both in "bin" and "lib/opt"?
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
cp support-files/my-*.ini $NOINST_NAME/
|
||||
mkdir -p $DESTDIR/lib/opt
|
||||
cp libmysql/$TARGET/libmysql.dll \
|
||||
libmysql/$TARGET/libmysql.lib \
|
||||
client/$TARGET/mysqlclient.lib \
|
||||
regex/$TARGET/regex.lib \
|
||||
strings/$TARGET/strings.lib \
|
||||
zlib/$TARGET/zlib.lib $DESTDIR/lib/opt/
|
||||
|
||||
mkdir -p $NOINST_NAME/mysql-test/include $NOINST_NAME/mysql-test/lib \
|
||||
$NOINST_NAME/mysql-test/r $NOINST_NAME/mysql-test/std_data \
|
||||
$NOINST_NAME/mysql-test/t $NOINST_NAME/mysql-test/extra
|
||||
cp mysql-test/mysql-test-run.pl $NOINST_NAME/mysql-test/
|
||||
cp mysql-test/README $NOINST_NAME/mysql-test/
|
||||
cp mysql-test/install_test_db.sh $NOINST_NAME/mysql-test/install_test_db
|
||||
cp mysql-test/include/*.inc $NOINST_NAME/mysql-test/include/
|
||||
cp mysql-test/lib/*.pl $NOINST_NAME/mysql-test/lib/
|
||||
cp mysql-test/lib/*.sql $NOINST_NAME/mysql-test/lib/
|
||||
cp mysql-test/r/*.require $NOINST_NAME/mysql-test/r/
|
||||
if [ x"$PACK_DEBUG" = "" -a -f "libmysql/debug/libmysql.lib" -o \
|
||||
x"$PACK_DEBUG" = "yes" ] ; then
|
||||
mkdir -p $DESTDIR/lib/debug
|
||||
cp libmysql/debug/libmysql.dll \
|
||||
libmysql/debug/libmysql.lib \
|
||||
client/debug/mysqlclient.lib \
|
||||
mysys/debug/mysys.lib \
|
||||
regex/debug/regex.lib \
|
||||
strings/debug/strings.lib \
|
||||
zlib/debug/zlib.lib $DESTDIR/lib/debug/
|
||||
fi
|
||||
|
||||
# FIXME sort this out...
|
||||
cp mysys/$TARGET/mysys.lib $DESTDIR/lib/opt/mysys_tls.lib
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Copy the test directory
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
mkdir -p $DESTDIR/mysql-test/include $DESTDIR/mysql-test/lib \
|
||||
$DESTDIR/mysql-test/r $DESTDIR/mysql-test/std_data \
|
||||
$DESTDIR/mysql-test/t
|
||||
cp mysql-test/mysql-test-run.pl $DESTDIR/mysql-test/
|
||||
cp mysql-test/README $DESTDIR/mysql-test/
|
||||
cp mysql-test/install_test_db.sh $DESTDIR/mysql-test/install_test_db
|
||||
cp mysql-test/include/*.inc $DESTDIR/mysql-test/include/
|
||||
cp mysql-test/lib/*.pl $DESTDIR/mysql-test/lib/
|
||||
cp mysql-test/lib/*.sql $DESTDIR/mysql-test/lib/
|
||||
cp mysql-test/r/*.require $DESTDIR/mysql-test/r/
|
||||
# Need this trick, or we get "argument list too long".
|
||||
ABS_DST=`pwd`/$NOINST_NAME
|
||||
ABS_DST=`pwd`/$DESTDIR
|
||||
(cd mysql-test/r/ && cp *.result $ABS_DST/mysql-test/r/)
|
||||
cp mysql-test/std_data/* $NOINST_NAME/mysql-test/std_data/
|
||||
cp mysql-test/t/*.disabled $NOINST_NAME/mysql-test/t/
|
||||
cp mysql-test/t/*.opt $NOINST_NAME/mysql-test/t/
|
||||
cp mysql-test/t/*.sh $NOINST_NAME/mysql-test/t/
|
||||
cp mysql-test/t/*.slave-mi $NOINST_NAME/mysql-test/t/
|
||||
cp mysql-test/t/*.sql $NOINST_NAME/mysql-test/t/
|
||||
cp mysql-test/t/*.def $NOINST_NAME/mysql-test/t/
|
||||
cp mysql-test/std_data/Moscow_leap $DESTDIR/mysql-test/std_data/
|
||||
cp mysql-test/std_data/des_key_file $DESTDIR/mysql-test/std_data/
|
||||
cp mysql-test/std_data/*.000001 $DESTDIR/mysql-test/std_data/
|
||||
cp mysql-test/std_data/*.cnf $DESTDIR/mysql-test/std_data/
|
||||
cp mysql-test/std_data/*.dat $DESTDIR/mysql-test/std_data/
|
||||
cp mysql-test/std_data/*.frm $DESTDIR/mysql-test/std_data/
|
||||
cp mysql-test/std_data/*.pem $DESTDIR/mysql-test/std_data/
|
||||
cp mysql-test/t/*.opt $DESTDIR/mysql-test/t/
|
||||
cp mysql-test/t/*.sh $DESTDIR/mysql-test/t/
|
||||
cp mysql-test/t/*.slave-mi $DESTDIR/mysql-test/t/
|
||||
cp mysql-test/t/*.sql $DESTDIR/mysql-test/t/
|
||||
cp mysql-test/t/*.def $DESTDIR/mysql-test/t/
|
||||
(cd mysql-test/t/ && cp *.test $ABS_DST/mysql-test/t/)
|
||||
cp -dpR mysql-test/extra/* $NOINST_NAME/mysql-test/extra/
|
||||
|
||||
# This copies in the unsubstituted scripts (containing @VAR@), but that seems
|
||||
# rather better than substituting random Unix paths and architecture names
|
||||
# from the Unix bootstrap host. Not sure what the point is of including these
|
||||
# shell scripts in the Windows packaging in any case.
|
||||
mkdir -p $NOINST_NAME/scripts
|
||||
# Note that this will not copy "extra" if a soft link
|
||||
if [ -d mysql-test/extra ] ; then
|
||||
mkdir -p $DESTDIR/mysql-test/extra
|
||||
cp -pR mysql-test/extra/* $DESTDIR/mysql-test/extra/
|
||||
fi
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Copy what could be usable in the "scripts" directory. Currently
|
||||
# only SQL files, others are bourne shell scripts or Perl scripts
|
||||
# not really usable on Windows.
|
||||
#
|
||||
# But to be nice to the few Cygwin users we might have in 5.0 we
|
||||
# continue to copy the stuff, but don't include it include it in
|
||||
# the WiX install.
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
mkdir -p $DESTDIR/scripts
|
||||
|
||||
# Uncomment and remove the for loop in 5.1
|
||||
#cp scripts/*.sql $DESTDIR/scripts/
|
||||
|
||||
for i in `cd scripts && ls`; do \
|
||||
if echo $i | grep -q '\.sh'; then \
|
||||
cp scripts/$i $NOINST_NAME/scripts/`echo $i | sed -e 's/\.sh$//'`; \
|
||||
else if [ $i = Makefile.am -o $i = Makefile.in -o -e scripts/$i.sh ] ; then \
|
||||
cp scripts/$i $DESTDIR/scripts/`echo $i | sed -e 's/\.sh$//'`; \
|
||||
elif [ $i = Makefile.am -o $i = Makefile.in -o -e scripts/$i.sh ] ; then \
|
||||
: ; \
|
||||
else \
|
||||
cp scripts/$i $NOINST_NAME/scripts/$i; \
|
||||
fi; fi; \
|
||||
cp scripts/$i $DESTDIR/scripts/$i; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
cp -dpR sql/share $NOINST_NAME/
|
||||
cp -dpR sql-bench $NOINST_NAME/
|
||||
rm -f $NOINST_NAME/sql-bench/*.sh $NOINST_NAME/sql-bench/Makefile*
|
||||
cp -pR sql/share $DESTDIR/
|
||||
|
||||
zip -r $NOINST_NAME.zip $NOINST_NAME
|
||||
rm -Rf $NOINST_NAME
|
||||
# ----------------------------------------------------------------------
|
||||
# Copy other files specified on command line DEST=SOURCE
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
for arg do
|
||||
dst=`echo $arg | sed 's/=.*$//'`
|
||||
src=`echo $arg | sed 's/^.*=//'`
|
||||
|
||||
if [ x"$dst" = x"" -o x"$src" = x"" ] ; then
|
||||
echo "Invalid specification of what to copy"
|
||||
usage
|
||||
fi
|
||||
|
||||
mkdir -p `dirname $DESTDIR/$dst`
|
||||
cp -pR "$src" $DESTDIR/$dst
|
||||
done
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Finally creat the ZIP archive
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
rm -f $NOINST_NAME.zip
|
||||
zip -r $NOINST_NAME.zip $DESTDIR
|
||||
rm -Rf $DESTDIR
|
||||
|
|
|
@ -27,7 +27,7 @@ INCLUDES = @ZLIB_INCLUDES@ \
|
|||
WRAPLIBS= @WRAPLIBS@
|
||||
SUBDIRS = share
|
||||
libexec_PROGRAMS = mysqld
|
||||
EXTRA_PROGRAMS = gen_lex_hash
|
||||
noinst_PROGRAMS = gen_lex_hash
|
||||
bin_PROGRAMS = mysql_tzinfo_to_sql
|
||||
gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@
|
||||
LDADD = $(top_builddir)/vio/libvio.a \
|
||||
|
@ -120,8 +120,9 @@ DEFS = -DMYSQL_SERVER \
|
|||
-DLIBDIR="\"$(MYSQLLIBdir)\"" \
|
||||
@DEFS@
|
||||
|
||||
BUILT_SOURCES = sql_yacc.cc sql_yacc.h lex_hash.h
|
||||
EXTRA_DIST = udf_example.c udf_example.def $(BUILT_SOURCES) \
|
||||
BUILT_DIST_SRC = sql_yacc.cc sql_yacc.h
|
||||
BUILT_SOURCES = $(BUILT_DIST_SRC) lex_hash.h
|
||||
EXTRA_DIST = udf_example.c udf_example.def $(BUILT_DIST_SRC) \
|
||||
nt_servc.cc nt_servc.h message.mc CMakeLists.txt \
|
||||
udf_example.c udf_example.def
|
||||
CLEANFILES = lex_hash.h sql_yacc.cc sql_yacc.h sql_yacc.output
|
||||
|
@ -157,11 +158,10 @@ sql_yacc.o: sql_yacc.cc sql_yacc.h $(HEADERS)
|
|||
@echo "If it fails, re-run configure with --with-low-memory"
|
||||
$(CXXCOMPILE) $(LM_CFLAGS) -c $<
|
||||
|
||||
# This generates lex_hash.h
|
||||
# NOTE Built sources should depend on their sources not the tool
|
||||
# this avoid the rebuild of the built files in a source dist
|
||||
lex_hash.h: gen_lex_hash.cc lex.h
|
||||
$(MAKE) $(AM_MAKEFLAGS) gen_lex_hash$(EXEEXT)
|
||||
# FIXME seems like now "lex_hash.h" differs depending on configure
|
||||
# flags, so can't pregenerate and include in source TAR. Revert to
|
||||
# dist pregenerated if this changes, so the file doesn't differ.
|
||||
lex_hash.h: gen_lex_hash$(EXEEXT)
|
||||
./gen_lex_hash$(EXEEXT) > $@
|
||||
|
||||
# the following three should eventually be moved out of this directory
|
||||
|
|
|
@ -132,11 +132,17 @@ bool Cached_item_decimal::cmp()
|
|||
{
|
||||
my_decimal tmp;
|
||||
my_decimal *ptmp= item->val_decimal(&tmp);
|
||||
if (null_value != item->null_value || my_decimal_cmp(&value, ptmp))
|
||||
if (null_value != item->null_value ||
|
||||
(!item->null_value && my_decimal_cmp(&value, ptmp)))
|
||||
{
|
||||
null_value= item->null_value;
|
||||
my_decimal2decimal(ptmp, &value);
|
||||
return TRUE;
|
||||
/* Save only not null values */
|
||||
if (!null_value)
|
||||
{
|
||||
my_decimal2decimal(ptmp, &value);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -1122,6 +1122,8 @@ bool Item_func_between::fix_fields(THD *thd, Item **ref)
|
|||
if (Item_func_opt_neg::fix_fields(thd, ref))
|
||||
return 1;
|
||||
|
||||
thd->lex->current_select->between_count++;
|
||||
|
||||
/* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
|
||||
if (pred_level && !negated)
|
||||
return 0;
|
||||
|
|
|
@ -448,6 +448,7 @@ public:
|
|||
negated= !negated;
|
||||
return this;
|
||||
}
|
||||
bool subst_argument_checker(byte **arg) { return TRUE; }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -7129,8 +7129,8 @@ int Update_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli,
|
|||
row_start, &m_cols, row_end, &m_master_reclength,
|
||||
table->write_set, UPDATE_ROWS_EVENT);
|
||||
|
||||
DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
|
||||
DBUG_DUMP("m_after_image", m_after_image, table->s->reclength);
|
||||
DBUG_DUMP("record[0]", (const char *)table->record[0], table->s->reclength);
|
||||
DBUG_DUMP("m_after_image", (const char *)m_after_image, table->s->reclength);
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -150,7 +150,7 @@ MY_LOCALE *my_locale_by_name(const char *name);
|
|||
Feel free to raise this by the smallest amount you can to get the
|
||||
"execution_constants" test to pass.
|
||||
*/
|
||||
#define STACK_MIN_SIZE 9336 // Abort if less stack during eval.
|
||||
#define STACK_MIN_SIZE 10788 // Abort if less stack during eval.
|
||||
|
||||
#define STACK_MIN_SIZE_FOR_OPEN 1024*80
|
||||
#define STACK_BUFF_ALLOC 256 // For stack overrun checks
|
||||
|
@ -784,6 +784,9 @@ bool quick_rm_table(handlerton *base,const char *db,
|
|||
const char *table_name, uint flags);
|
||||
void close_cached_table(THD *thd, TABLE *table);
|
||||
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent);
|
||||
bool do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db,
|
||||
char *new_table_name, char *new_table_alias,
|
||||
bool skip_error);
|
||||
bool mysql_change_db(THD *thd,const char *name,bool no_access_check);
|
||||
void mysql_parse(THD *thd,char *inBuf,uint length);
|
||||
bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length);
|
||||
|
@ -870,7 +873,8 @@ bool mysql_xa_recover(THD *thd);
|
|||
bool check_simple_select();
|
||||
int mysql_alter_tablespace(THD* thd, st_alter_tablespace *ts_info);
|
||||
|
||||
SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length);
|
||||
SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length,
|
||||
SORT_FIELD *sortorder);
|
||||
int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
||||
List<Item> &fields, List <Item> &all_fields, ORDER *order);
|
||||
int setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
||||
|
|
|
@ -9787,6 +9787,7 @@ TRP_GROUP_MIN_MAX::make_quick(PARAM *param, bool retrieve_full_rows,
|
|||
quick->quick_prefix_select= NULL;
|
||||
|
||||
quick->update_key_stat();
|
||||
quick->adjust_prefix_ranges();
|
||||
|
||||
DBUG_RETURN(quick);
|
||||
}
|
||||
|
@ -10016,6 +10017,42 @@ bool QUICK_GROUP_MIN_MAX_SELECT::add_range(SEL_ARG *sel_range)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Opens the ranges if there are more conditions in quick_prefix_select than
|
||||
the ones used for jumping through the prefixes.
|
||||
|
||||
SYNOPSIS
|
||||
QUICK_GROUP_MIN_MAX_SELECT::adjust_prefix_ranges()
|
||||
|
||||
NOTES
|
||||
quick_prefix_select is made over the conditions on the whole key.
|
||||
It defines a number of ranges of length x.
|
||||
However when jumping through the prefixes we use only the the first
|
||||
few most significant keyparts in the range key. However if there
|
||||
are more keyparts to follow the ones we are using we must make the
|
||||
condition on the key inclusive (because x < "ab" means
|
||||
x[0] < 'a' OR (x[0] == 'a' AND x[1] < 'b').
|
||||
To achive the above we must turn off the NEAR_MIN/NEAR_MAX
|
||||
*/
|
||||
void QUICK_GROUP_MIN_MAX_SELECT::adjust_prefix_ranges ()
|
||||
{
|
||||
if (quick_prefix_select &&
|
||||
group_prefix_len < quick_prefix_select->max_used_key_length)
|
||||
{
|
||||
DYNAMIC_ARRAY *arr;
|
||||
uint inx;
|
||||
|
||||
for (inx= 0, arr= &quick_prefix_select->ranges; inx < arr->elements; inx++)
|
||||
{
|
||||
QUICK_RANGE *range;
|
||||
|
||||
get_dynamic(arr, (gptr)&range, inx);
|
||||
range->flag &= ~(NEAR_MIN | NEAR_MAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Determine the total number and length of the keys that will be used for
|
||||
index lookup.
|
||||
|
|
|
@ -295,6 +295,7 @@ protected:
|
|||
friend class QUICK_SELECT_DESC;
|
||||
friend class QUICK_INDEX_MERGE_SELECT;
|
||||
friend class QUICK_ROR_INTERSECT_SELECT;
|
||||
friend class QUICK_GROUP_MIN_MAX_SELECT;
|
||||
|
||||
DYNAMIC_ARRAY ranges; /* ordered array of range ptrs */
|
||||
QUICK_RANGE **cur_range; /* current element in ranges */
|
||||
|
@ -643,6 +644,7 @@ public:
|
|||
~QUICK_GROUP_MIN_MAX_SELECT();
|
||||
bool add_range(SEL_ARG *sel_range);
|
||||
void update_key_stat();
|
||||
void adjust_prefix_ranges();
|
||||
bool alloc_buffers();
|
||||
int init();
|
||||
int reset();
|
||||
|
|
|
@ -4362,13 +4362,20 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter,
|
|||
const char *field_name=0;
|
||||
const char *table_name=0;
|
||||
bool found_unaliased_non_uniq= 0;
|
||||
/*
|
||||
true if the item that we search for is a valid name reference
|
||||
(and not an item that happens to have a name).
|
||||
*/
|
||||
bool is_ref_by_name= 0;
|
||||
uint unaliased_counter;
|
||||
|
||||
LINT_INIT(unaliased_counter); // Dependent on found_unaliased
|
||||
|
||||
*unaliased= FALSE;
|
||||
|
||||
if (find->type() == Item::FIELD_ITEM || find->type() == Item::REF_ITEM)
|
||||
is_ref_by_name= (find->type() == Item::FIELD_ITEM ||
|
||||
find->type() == Item::REF_ITEM);
|
||||
if (is_ref_by_name)
|
||||
{
|
||||
field_name= ((Item_ident*) find)->field_name;
|
||||
table_name= ((Item_ident*) find)->table_name;
|
||||
|
@ -4480,7 +4487,7 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter,
|
|||
}
|
||||
}
|
||||
else if (!table_name && (find->eq(item,0) ||
|
||||
find->name && item->name &&
|
||||
is_ref_by_name && find->name && item->name &&
|
||||
!my_strcasecmp(system_charset_info,
|
||||
item->name,find->name)))
|
||||
{
|
||||
|
@ -5810,6 +5817,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
|
|||
thd->mark_used_columns= MARK_COLUMNS_READ;
|
||||
DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
|
||||
select_lex->cond_count= 0;
|
||||
select_lex->between_count= 0;
|
||||
|
||||
for (table= tables; table; table= table->next_local)
|
||||
{
|
||||
|
|
|
@ -2632,10 +2632,10 @@ int THD::binlog_update_row(TABLE* table, bool is_trans,
|
|||
my_size_t const after_size= pack_row(table, cols, after_row,
|
||||
after_record);
|
||||
|
||||
DBUG_DUMP("before_record", before_record, table->s->reclength);
|
||||
DBUG_DUMP("after_record", after_record, table->s->reclength);
|
||||
DBUG_DUMP("before_row", before_row, before_size);
|
||||
DBUG_DUMP("after_row", after_row, after_size);
|
||||
DBUG_DUMP("before_record", (const char *)before_record, table->s->reclength);
|
||||
DBUG_DUMP("after_record", (const char *)after_record, table->s->reclength);
|
||||
DBUG_DUMP("before_row", (const char *)before_row, before_size);
|
||||
DBUG_DUMP("after_row", (const char *)after_row, after_size);
|
||||
|
||||
Rows_log_event* const ev=
|
||||
binlog_prepare_pending_rows_event(table, server_id, cols, colcnt,
|
||||
|
|
|
@ -183,7 +183,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||
MYF(MY_FAE | MY_ZEROFILL));
|
||||
|
||||
if (!(sortorder= make_unireg_sortorder((ORDER*) order->first,
|
||||
&length)) ||
|
||||
&length, NULL)) ||
|
||||
(table->sort.found_records = filesort(thd, table, sortorder, length,
|
||||
select, HA_POS_ERROR, 1,
|
||||
&examined_rows))
|
||||
|
|
|
@ -1147,7 +1147,7 @@ void st_select_lex::init_query()
|
|||
initialization is checked for failure.
|
||||
*/
|
||||
parent_lex->push_context(&context);
|
||||
cond_count= with_wild= 0;
|
||||
cond_count= between_count= with_wild= 0;
|
||||
conds_processed_with_permanent_arena= 0;
|
||||
ref_pointer_array= 0;
|
||||
select_n_having_items= 0;
|
||||
|
|
|
@ -556,7 +556,8 @@ public:
|
|||
list during split_sum_func
|
||||
*/
|
||||
uint select_n_having_items;
|
||||
uint cond_count; /* number of arguments of and/or/xor in where/having */
|
||||
uint cond_count; /* number of arguments of and/or/xor in where/having/on */
|
||||
uint between_count; /* number of between predicates in where/having/on */
|
||||
enum_parsing_place parsing_place; /* where we are parsing expression */
|
||||
bool with_sum_func; /* sum function indicator */
|
||||
/*
|
||||
|
|
|
@ -125,96 +125,143 @@ static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Rename a single table or a view
|
||||
|
||||
SYNPOSIS
|
||||
do_rename()
|
||||
thd Thread handle
|
||||
ren_table A table/view to be renamed
|
||||
new_db The database to which the table to be moved to
|
||||
new_table_name The new table/view name
|
||||
new_table_alias The new table/view alias
|
||||
skip_error Whether to skip error
|
||||
|
||||
DESCRIPTION
|
||||
Rename a single table or a view.
|
||||
|
||||
RETURN
|
||||
false Ok
|
||||
true rename failed
|
||||
*/
|
||||
|
||||
bool
|
||||
do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name,
|
||||
char *new_table_alias, bool skip_error)
|
||||
{
|
||||
int rc= 1;
|
||||
char name[FN_REFLEN];
|
||||
const char *new_alias, *old_alias;
|
||||
frm_type_enum frm_type;
|
||||
enum legacy_db_type table_type;
|
||||
|
||||
DBUG_ENTER("do_rename");
|
||||
|
||||
if (lower_case_table_names == 2)
|
||||
{
|
||||
old_alias= ren_table->alias;
|
||||
new_alias= new_table_alias;
|
||||
}
|
||||
else
|
||||
{
|
||||
old_alias= ren_table->table_name;
|
||||
new_alias= new_table_name;
|
||||
}
|
||||
build_table_filename(name, sizeof(name),
|
||||
new_db, new_alias, reg_ext, 0);
|
||||
if (!access(name,F_OK))
|
||||
{
|
||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
|
||||
DBUG_RETURN(1); // This can't be skipped
|
||||
}
|
||||
build_table_filename(name, sizeof(name),
|
||||
ren_table->db, old_alias, reg_ext, 0);
|
||||
|
||||
frm_type= mysql_frm_type(thd, name, &table_type);
|
||||
switch (frm_type)
|
||||
{
|
||||
case FRMTYPE_TABLE:
|
||||
{
|
||||
if (!(rc= mysql_rename_table(ha_resolve_by_legacy_type(thd,
|
||||
table_type),
|
||||
ren_table->db, old_alias,
|
||||
new_db, new_alias, 0)))
|
||||
{
|
||||
if ((rc= Table_triggers_list::change_table_name(thd, ren_table->db,
|
||||
old_alias,
|
||||
new_db,
|
||||
new_alias)))
|
||||
{
|
||||
/*
|
||||
We've succeeded in renaming table's .frm and in updating
|
||||
corresponding handler data, but have failed to update table's
|
||||
triggers appropriately. So let us revert operations on .frm
|
||||
and handler's data and report about failure to rename table.
|
||||
*/
|
||||
(void) mysql_rename_table(ha_resolve_by_legacy_type(thd,
|
||||
table_type),
|
||||
new_db, new_alias,
|
||||
ren_table->db, old_alias, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FRMTYPE_VIEW:
|
||||
/* change of schema is not allowed */
|
||||
if (strcmp(ren_table->db, new_db))
|
||||
my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db,
|
||||
new_db);
|
||||
else
|
||||
rc= mysql_rename_view(thd, new_alias, ren_table);
|
||||
break;
|
||||
default:
|
||||
DBUG_ASSERT(0); // should never happen
|
||||
case FRMTYPE_ERROR:
|
||||
my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
|
||||
break;
|
||||
}
|
||||
if (rc && !skip_error)
|
||||
DBUG_RETURN(1);
|
||||
|
||||
DBUG_RETURN(0);
|
||||
|
||||
}
|
||||
/*
|
||||
Rename all tables in list; Return pointer to wrong entry if something goes
|
||||
wrong. Note that the table_list may be empty!
|
||||
*/
|
||||
|
||||
/*
|
||||
Rename tables/views in the list
|
||||
|
||||
SYNPOSIS
|
||||
rename_tables()
|
||||
thd Thread handle
|
||||
table_list List of tables to rename
|
||||
skip_error Whether to skip errors
|
||||
|
||||
DESCRIPTION
|
||||
Take a table/view name from and odd list element and rename it to a
|
||||
the name taken from list element+1. Note that the table_list may be
|
||||
empty.
|
||||
|
||||
RETURN
|
||||
false Ok
|
||||
true rename failed
|
||||
*/
|
||||
|
||||
static TABLE_LIST *
|
||||
rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
|
||||
{
|
||||
TABLE_LIST *ren_table,*new_table;
|
||||
frm_type_enum frm_type;
|
||||
enum legacy_db_type table_type;
|
||||
TABLE_LIST *ren_table,*new_table, *tmp_table;
|
||||
|
||||
DBUG_ENTER("rename_tables");
|
||||
|
||||
for (ren_table= table_list; ren_table; ren_table= new_table->next_local)
|
||||
{
|
||||
int rc= 1;
|
||||
char name[FN_REFLEN];
|
||||
const char *new_alias, *old_alias;
|
||||
|
||||
new_table= ren_table->next_local;
|
||||
if (lower_case_table_names == 2)
|
||||
{
|
||||
old_alias= ren_table->alias;
|
||||
new_alias= new_table->alias;
|
||||
}
|
||||
else
|
||||
{
|
||||
old_alias= ren_table->table_name;
|
||||
new_alias= new_table->table_name;
|
||||
}
|
||||
build_table_filename(name, sizeof(name),
|
||||
new_table->db, new_alias, reg_ext, 0);
|
||||
if (!access(name,F_OK))
|
||||
{
|
||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
|
||||
DBUG_RETURN(ren_table); // This can't be skipped
|
||||
}
|
||||
build_table_filename(name, sizeof(name),
|
||||
ren_table->db, old_alias, reg_ext, 0);
|
||||
|
||||
frm_type= mysql_frm_type(thd, name, &table_type);
|
||||
switch (frm_type)
|
||||
{
|
||||
case FRMTYPE_TABLE:
|
||||
{
|
||||
if (table_type == DB_TYPE_UNKNOWN)
|
||||
my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
|
||||
else
|
||||
{
|
||||
if (!(rc= mysql_rename_table(ha_resolve_by_legacy_type(thd,
|
||||
table_type),
|
||||
ren_table->db, old_alias,
|
||||
new_table->db, new_alias, 0)))
|
||||
{
|
||||
if ((rc= Table_triggers_list::change_table_name(thd, ren_table->db,
|
||||
old_alias,
|
||||
new_table->db,
|
||||
new_alias)))
|
||||
{
|
||||
/*
|
||||
We've succeeded in renaming table's .frm and in updating
|
||||
corresponding handler data, but have failed to update table's
|
||||
triggers appropriately. So let us revert operations on .frm
|
||||
and handler's data and report about failure to rename table.
|
||||
*/
|
||||
(void) mysql_rename_table(ha_resolve_by_legacy_type(thd,
|
||||
table_type),
|
||||
new_table->db, new_alias,
|
||||
ren_table->db, old_alias, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FRMTYPE_VIEW:
|
||||
/* change of schema is not allowed */
|
||||
if (strcmp(ren_table->db, new_table->db))
|
||||
my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db,
|
||||
new_table->db);
|
||||
else
|
||||
rc= mysql_rename_view(thd, new_alias, ren_table);
|
||||
break;
|
||||
default:
|
||||
DBUG_ASSERT(0); // should never happen
|
||||
case FRMTYPE_ERROR:
|
||||
my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
|
||||
break;
|
||||
}
|
||||
if (rc && !skip_error)
|
||||
if (do_rename(thd, ren_table, new_table->db, new_table->table_name,
|
||||
new_table->alias, skip_error))
|
||||
DBUG_RETURN(ren_table);
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
|
|
|
@ -35,14 +35,17 @@ const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
|
|||
"index_merge"
|
||||
};
|
||||
|
||||
struct st_sargable_param;
|
||||
|
||||
static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array);
|
||||
static bool make_join_statistics(JOIN *join, TABLE_LIST *leaves, COND *conds,
|
||||
DYNAMIC_ARRAY *keyuse);
|
||||
static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
|
||||
JOIN_TAB *join_tab,
|
||||
JOIN_TAB *join_tab,
|
||||
uint tables, COND *conds,
|
||||
COND_EQUAL *cond_equal,
|
||||
table_map table_map, SELECT_LEX *select_lex);
|
||||
table_map table_map, SELECT_LEX *select_lex,
|
||||
st_sargable_param **sargables);
|
||||
static int sort_keyuse(KEYUSE *a,KEYUSE *b);
|
||||
static void set_position(JOIN *join,uint index,JOIN_TAB *table,KEYUSE *key);
|
||||
static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
|
||||
|
@ -1380,12 +1383,13 @@ JOIN::exec()
|
|||
thd->examined_row_count= 0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
/*
|
||||
don't reset the found rows count if there're no tables
|
||||
as FOUND_ROWS() may be called.
|
||||
*/
|
||||
/*
|
||||
Don't reset the found rows count if there're no tables as
|
||||
FOUND_ROWS() may be called. Never reset the examined row count here.
|
||||
It must be accumulated from all join iterations of all join parts.
|
||||
*/
|
||||
if (tables)
|
||||
thd->limit_found_rows= thd->examined_row_count= 0;
|
||||
thd->limit_found_rows= 0;
|
||||
|
||||
if (zero_result_cause)
|
||||
{
|
||||
|
@ -1415,7 +1419,8 @@ JOIN::exec()
|
|||
simple_order= simple_group;
|
||||
skip_sort_order= 0;
|
||||
}
|
||||
if (order &&
|
||||
if (order &&
|
||||
(order != group_list || !(select_options & SELECT_BIG_RESULT)) &&
|
||||
(const_tables == tables ||
|
||||
((simple_order || skip_sort_order) &&
|
||||
test_if_skip_sort_order(&join_tab[const_tables], order,
|
||||
|
@ -1433,6 +1438,12 @@ JOIN::exec()
|
|||
List<Item> *curr_all_fields= &all_fields;
|
||||
List<Item> *curr_fields_list= &fields_list;
|
||||
TABLE *curr_tmp_table= 0;
|
||||
/*
|
||||
Initialize examined rows here because the values from all join parts
|
||||
must be accumulated in examined_row_count. Hence every join
|
||||
iteration must count from zero.
|
||||
*/
|
||||
curr_join->examined_rows= 0;
|
||||
|
||||
if ((curr_join->select_lex->options & OPTION_SCHEMA_TABLE) &&
|
||||
get_schema_tables_result(curr_join))
|
||||
|
@ -1593,6 +1604,7 @@ JOIN::exec()
|
|||
{
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
sortorder= curr_join->sortorder;
|
||||
}
|
||||
|
||||
thd->proc_info="Copying to group table";
|
||||
|
@ -1805,6 +1817,7 @@ JOIN::exec()
|
|||
(select_options & OPTION_FOUND_ROWS ?
|
||||
HA_POS_ERROR : unit->select_limit_cnt)))
|
||||
DBUG_VOID_RETURN;
|
||||
sortorder= curr_join->sortorder;
|
||||
if (curr_join->const_tables != curr_join->tables &&
|
||||
!curr_join->join_tab[curr_join->const_tables].table->sort.io_cache)
|
||||
{
|
||||
|
@ -1855,9 +1868,12 @@ JOIN::exec()
|
|||
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
|
||||
error= do_select(curr_join, curr_fields_list, NULL, procedure);
|
||||
thd->limit_found_rows= curr_join->send_records;
|
||||
thd->examined_row_count= curr_join->examined_rows;
|
||||
}
|
||||
|
||||
/* Accumulate the counts from all join iterations of all join parts. */
|
||||
thd->examined_row_count+= curr_join->examined_rows;
|
||||
DBUG_PRINT("counts", ("thd->examined_row_count: %lu",
|
||||
(ulong) thd->examined_row_count));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
@ -2071,6 +2087,19 @@ static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
|
|||
DBUG_RETURN(HA_POS_ERROR); /* This shouldn't happend */
|
||||
}
|
||||
|
||||
/*
|
||||
This structure is used to collect info on potentially sargable
|
||||
predicates in order to check whether they become sargable after
|
||||
reading const tables.
|
||||
We form a bitmap of indexes that can be used for sargable predicates.
|
||||
Only such indexes are involved in range analysis.
|
||||
*/
|
||||
typedef struct st_sargable_param
|
||||
{
|
||||
Field *field; /* field against which to check sargability */
|
||||
Item **arg_value; /* values of potential keys for lookups */
|
||||
uint num_values; /* number of values in the above array */
|
||||
} SARGABLE_PARAM;
|
||||
|
||||
/*
|
||||
Calculate the best possible join and initialize the join structure
|
||||
|
@ -2093,6 +2122,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
|||
JOIN_TAB *stat,*stat_end,*s,**stat_ref;
|
||||
KEYUSE *keyuse,*start_keyuse;
|
||||
table_map outer_join=0;
|
||||
SARGABLE_PARAM *sargables= 0;
|
||||
JOIN_TAB *stat_vector[MAX_TABLES+1];
|
||||
DBUG_ENTER("make_join_statistics");
|
||||
|
||||
|
@ -2230,7 +2260,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
|||
if (conds || outer_join)
|
||||
if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables,
|
||||
conds, join->cond_equal,
|
||||
~outer_join, join->select_lex))
|
||||
~outer_join, join->select_lex, &sargables))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
/* Read tables with 0 or 1 rows (system tables) */
|
||||
|
@ -2380,6 +2410,26 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
|||
}
|
||||
} while (join->const_table_map & found_ref && ref_changed);
|
||||
|
||||
/*
|
||||
Update info on indexes that can be used for search lookups as
|
||||
reading const tables may has added new sargable predicates.
|
||||
*/
|
||||
if (const_count && sargables)
|
||||
{
|
||||
for( ; sargables->field ; sargables++)
|
||||
{
|
||||
Field *field= sargables->field;
|
||||
JOIN_TAB *stat= field->table->reginfo.join_tab;
|
||||
key_map possible_keys= field->key_start;
|
||||
possible_keys.intersect(field->table->keys_in_use_for_query);
|
||||
bool is_const= 1;
|
||||
for (uint i=0; i< sargables->num_values; i++)
|
||||
is_const&= sargables->arg_value[i]->const_item();
|
||||
if (is_const)
|
||||
stat[0].const_keys.merge(possible_keys);
|
||||
}
|
||||
}
|
||||
|
||||
/* Calc how many (possible) matched records in each table */
|
||||
|
||||
for (s=stat ; s < stat_end ; s++)
|
||||
|
@ -2639,6 +2689,7 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
|
|||
eq_func True if we used =, <=> or IS NULL
|
||||
value Value used for comparison with field
|
||||
usable_tables Tables which can be used for key optimization
|
||||
sargables IN/OUT Array of found sargable candidates
|
||||
|
||||
NOTES
|
||||
If we are doing a NOT NULL comparison on a NOT NULL field in a outer join
|
||||
|
@ -2650,8 +2701,8 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
|
|||
|
||||
static void
|
||||
add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
|
||||
Field *field, bool eq_func, Item **value, uint num_values,
|
||||
table_map usable_tables)
|
||||
Field *field, bool eq_func, Item **value, uint num_values,
|
||||
table_map usable_tables, SARGABLE_PARAM **sargables)
|
||||
{
|
||||
uint exists_optimize= 0;
|
||||
if (!(field->flags & PART_KEY_FLAG))
|
||||
|
@ -2710,6 +2761,19 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
|
|||
}
|
||||
if (is_const)
|
||||
stat[0].const_keys.merge(possible_keys);
|
||||
else if (!eq_func)
|
||||
{
|
||||
/*
|
||||
Save info to be able check whether this predicate can be
|
||||
considered as sargable for range analisis after reading const tables.
|
||||
We do not save info about equalities as update_const_equal_items
|
||||
will take care of updating info on keys from sargable equalities.
|
||||
*/
|
||||
(*sargables)--;
|
||||
(*sargables)->field= field;
|
||||
(*sargables)->arg_value= value;
|
||||
(*sargables)->num_values= num_values;
|
||||
}
|
||||
/*
|
||||
We can't always use indexes when comparing a string index to a
|
||||
number. cmp_type() is checked to allow compare of dates to numbers.
|
||||
|
@ -2800,6 +2864,7 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
|
|||
value Value used for comparison with field
|
||||
Is NULL for BETWEEN and IN
|
||||
usable_tables Tables which can be used for key optimization
|
||||
sargables IN/OUT Array of found sargable candidates
|
||||
|
||||
NOTES
|
||||
If field items f1 and f2 belong to the same multiple equality and
|
||||
|
@ -2813,11 +2878,12 @@ static void
|
|||
add_key_equal_fields(KEY_FIELD **key_fields, uint and_level,
|
||||
Item_func *cond, Item_field *field_item,
|
||||
bool eq_func, Item **val,
|
||||
uint num_values, table_map usable_tables)
|
||||
uint num_values, table_map usable_tables,
|
||||
SARGABLE_PARAM **sargables)
|
||||
{
|
||||
Field *field= field_item->field;
|
||||
add_key_field(key_fields, and_level, cond, field,
|
||||
eq_func, val, num_values, usable_tables);
|
||||
eq_func, val, num_values, usable_tables, sargables);
|
||||
Item_equal *item_equal= field_item->item_equal;
|
||||
if (item_equal)
|
||||
{
|
||||
|
@ -2832,7 +2898,8 @@ add_key_equal_fields(KEY_FIELD **key_fields, uint and_level,
|
|||
if (!field->eq(item->field))
|
||||
{
|
||||
add_key_field(key_fields, and_level, cond, item->field,
|
||||
eq_func, val, num_values, usable_tables);
|
||||
eq_func, val, num_values, usable_tables,
|
||||
sargables);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2840,7 +2907,8 @@ add_key_equal_fields(KEY_FIELD **key_fields, uint and_level,
|
|||
|
||||
static void
|
||||
add_key_fields(KEY_FIELD **key_fields,uint *and_level,
|
||||
COND *cond, table_map usable_tables)
|
||||
COND *cond, table_map usable_tables,
|
||||
SARGABLE_PARAM **sargables)
|
||||
{
|
||||
if (cond->type() == Item_func::COND_ITEM)
|
||||
{
|
||||
|
@ -2851,20 +2919,20 @@ add_key_fields(KEY_FIELD **key_fields,uint *and_level,
|
|||
{
|
||||
Item *item;
|
||||
while ((item=li++))
|
||||
add_key_fields(key_fields,and_level,item,usable_tables);
|
||||
add_key_fields(key_fields,and_level,item,usable_tables,sargables);
|
||||
for (; org_key_fields != *key_fields ; org_key_fields++)
|
||||
org_key_fields->level= *and_level;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*and_level)++;
|
||||
add_key_fields(key_fields,and_level,li++,usable_tables);
|
||||
add_key_fields(key_fields,and_level,li++,usable_tables,sargables);
|
||||
Item *item;
|
||||
while ((item=li++))
|
||||
{
|
||||
KEY_FIELD *start_key_fields= *key_fields;
|
||||
(*and_level)++;
|
||||
add_key_fields(key_fields,and_level,item,usable_tables);
|
||||
add_key_fields(key_fields,and_level,item,usable_tables,sargables);
|
||||
*key_fields=merge_key_fields(org_key_fields,start_key_fields,
|
||||
*key_fields,++(*and_level));
|
||||
}
|
||||
|
@ -2895,9 +2963,9 @@ add_key_fields(KEY_FIELD **key_fields,uint *and_level,
|
|||
cond_func->argument_count() != 2);
|
||||
add_key_equal_fields(key_fields, *and_level, cond_func,
|
||||
(Item_field*) (cond_func->key_item()->real_item()),
|
||||
0, values,
|
||||
0, values,
|
||||
cond_func->argument_count()-1,
|
||||
usable_tables);
|
||||
usable_tables, sargables);
|
||||
}
|
||||
if (cond_func->functype() == Item_func::BETWEEN)
|
||||
{
|
||||
|
@ -2911,7 +2979,8 @@ add_key_fields(KEY_FIELD **key_fields,uint *and_level,
|
|||
{
|
||||
field_item= (Item_field *) (cond_func->arguments()[i]->real_item());
|
||||
add_key_equal_fields(key_fields, *and_level, cond_func,
|
||||
field_item, 0, values, 1, usable_tables);
|
||||
field_item, 0, values, 1, usable_tables,
|
||||
sargables);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2928,7 +2997,8 @@ add_key_fields(KEY_FIELD **key_fields,uint *and_level,
|
|||
add_key_equal_fields(key_fields, *and_level, cond_func,
|
||||
(Item_field*) (cond_func->arguments()[0])->real_item(),
|
||||
equal_func,
|
||||
cond_func->arguments()+1, 1, usable_tables);
|
||||
cond_func->arguments()+1, 1, usable_tables,
|
||||
sargables);
|
||||
}
|
||||
if (cond_func->arguments()[1]->real_item()->type() == Item::FIELD_ITEM &&
|
||||
cond_func->functype() != Item_func::LIKE_FUNC &&
|
||||
|
@ -2937,7 +3007,8 @@ add_key_fields(KEY_FIELD **key_fields,uint *and_level,
|
|||
add_key_equal_fields(key_fields, *and_level, cond_func,
|
||||
(Item_field*) (cond_func->arguments()[1])->real_item(),
|
||||
equal_func,
|
||||
cond_func->arguments(),1,usable_tables);
|
||||
cond_func->arguments(),1,usable_tables,
|
||||
sargables);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2952,7 +3023,7 @@ add_key_fields(KEY_FIELD **key_fields,uint *and_level,
|
|||
add_key_equal_fields(key_fields, *and_level, cond_func,
|
||||
(Item_field*) (cond_func->arguments()[0])->real_item(),
|
||||
cond_func->functype() == Item_func::ISNULL_FUNC,
|
||||
&tmp, 1, usable_tables);
|
||||
&tmp, 1, usable_tables, sargables);
|
||||
}
|
||||
break;
|
||||
case Item_func::OPTIMIZE_EQUAL:
|
||||
|
@ -2970,7 +3041,7 @@ add_key_fields(KEY_FIELD **key_fields,uint *and_level,
|
|||
while ((item= it++))
|
||||
{
|
||||
add_key_field(key_fields, *and_level, cond_func, item->field,
|
||||
TRUE, &const_item, 1, usable_tables);
|
||||
TRUE, &const_item, 1, usable_tables, sargables);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -2990,7 +3061,8 @@ add_key_fields(KEY_FIELD **key_fields,uint *and_level,
|
|||
if (!field->eq(item->field))
|
||||
{
|
||||
add_key_field(key_fields, *and_level, cond_func, field,
|
||||
TRUE, (Item **) &item, 1, usable_tables);
|
||||
TRUE, (Item **) &item, 1, usable_tables,
|
||||
sargables);
|
||||
}
|
||||
}
|
||||
it.rewind();
|
||||
|
@ -3141,6 +3213,7 @@ sort_keyuse(KEYUSE *a,KEYUSE *b)
|
|||
nested_join_table IN Nested join pseudo-table to process
|
||||
end INOUT End of the key field array
|
||||
and_level INOUT And-level
|
||||
sargables IN/OUT Array of found sargable candidates
|
||||
|
||||
DESCRIPTION
|
||||
This function populates KEY_FIELD array with entries generated from the
|
||||
|
@ -3164,7 +3237,8 @@ sort_keyuse(KEYUSE *a,KEYUSE *b)
|
|||
*/
|
||||
|
||||
static void add_key_fields_for_nj(TABLE_LIST *nested_join_table,
|
||||
KEY_FIELD **end, uint *and_level)
|
||||
KEY_FIELD **end, uint *and_level,
|
||||
SARGABLE_PARAM **sargables)
|
||||
{
|
||||
List_iterator<TABLE_LIST> li(nested_join_table->nested_join->join_list);
|
||||
table_map tables= 0;
|
||||
|
@ -3174,12 +3248,12 @@ static void add_key_fields_for_nj(TABLE_LIST *nested_join_table,
|
|||
while ((table= li++))
|
||||
{
|
||||
if (table->nested_join)
|
||||
add_key_fields_for_nj(table, end, and_level);
|
||||
add_key_fields_for_nj(table, end, and_level, sargables);
|
||||
else
|
||||
if (!table->on_expr)
|
||||
tables |= table->table->map;
|
||||
}
|
||||
add_key_fields(end, and_level, nested_join_table->on_expr, tables);
|
||||
add_key_fields(end, and_level, nested_join_table->on_expr, tables, sargables);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3194,9 +3268,10 @@ static void add_key_fields_for_nj(TABLE_LIST *nested_join_table,
|
|||
tables Number of tables in join
|
||||
cond WHERE condition (note that the function analyzes
|
||||
join_tab[i]->on_expr too)
|
||||
normal_tables tables not inner w.r.t some outer join (ones for which
|
||||
normal_tables Tables not inner w.r.t some outer join (ones for which
|
||||
we can make ref access based the WHERE clause)
|
||||
select_lex current SELECT
|
||||
sargables OUT Array of found sargable candidates
|
||||
|
||||
RETURN
|
||||
0 - OK
|
||||
|
@ -3205,27 +3280,55 @@ static void add_key_fields_for_nj(TABLE_LIST *nested_join_table,
|
|||
|
||||
static bool
|
||||
update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
|
||||
uint tables, COND *cond, COND_EQUAL *cond_equal,
|
||||
table_map normal_tables, SELECT_LEX *select_lex)
|
||||
uint tables, COND *cond, COND_EQUAL *cond_equal,
|
||||
table_map normal_tables, SELECT_LEX *select_lex,
|
||||
SARGABLE_PARAM **sargables)
|
||||
{
|
||||
uint and_level,i,found_eq_constant;
|
||||
KEY_FIELD *key_fields, *end, *field;
|
||||
uint sz;
|
||||
uint m= 1;
|
||||
|
||||
if (cond_equal && cond_equal->max_members)
|
||||
m= cond_equal->max_members;
|
||||
|
||||
if (!(key_fields=(KEY_FIELD*)
|
||||
thd->alloc(sizeof(key_fields[0])*
|
||||
(thd->lex->current_select->cond_count+1)*2*m)))
|
||||
|
||||
/*
|
||||
We use the same piece of memory to store both KEY_FIELD
|
||||
and SARGABLE_PARAM structure.
|
||||
KEY_FIELD values are placed at the beginning this memory
|
||||
while SARGABLE_PARAM values are put at the end.
|
||||
All predicates that are used to fill arrays of KEY_FIELD
|
||||
and SARGABLE_PARAM structures have at most 2 arguments
|
||||
except BETWEEN predicates that have 3 arguments and
|
||||
IN predicates.
|
||||
This any predicate if it's not BETWEEN/IN can be used
|
||||
directly to fill at most 2 array elements, either of KEY_FIELD
|
||||
or SARGABLE_PARAM type. For a BETWEEN predicate 3 elements
|
||||
can be filled as this predicate is considered as
|
||||
saragable with respect to each of its argument.
|
||||
An IN predicate can require at most 1 element as currently
|
||||
it is considered as sargable only for its first argument.
|
||||
Multiple equality can add elements that are filled after
|
||||
substitution of field arguments by equal fields. There
|
||||
can be not more than cond_equal->max_members such substitutions.
|
||||
*/
|
||||
sz= max(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
|
||||
(((thd->lex->current_select->cond_count+1)*2 +
|
||||
thd->lex->current_select->between_count)*m+1);
|
||||
if (!(key_fields=(KEY_FIELD*) thd->alloc(sz)))
|
||||
return TRUE; /* purecov: inspected */
|
||||
and_level= 0;
|
||||
field= end= key_fields;
|
||||
*sargables= (SARGABLE_PARAM *) key_fields +
|
||||
(sz - sizeof((*sargables)[0].field))/sizeof(SARGABLE_PARAM);
|
||||
/* set a barrier for the array of SARGABLE_PARAM */
|
||||
(*sargables)[0].field= 0;
|
||||
|
||||
if (my_init_dynamic_array(keyuse,sizeof(KEYUSE),20,64))
|
||||
return TRUE;
|
||||
if (cond)
|
||||
{
|
||||
add_key_fields(&end,&and_level,cond,normal_tables);
|
||||
add_key_fields(&end,&and_level,cond,normal_tables,sargables);
|
||||
for (; field != end ; field++)
|
||||
{
|
||||
add_key_part(keyuse,field);
|
||||
|
@ -3248,7 +3351,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
|
|||
*/
|
||||
if (*join_tab[i].on_expr_ref)
|
||||
add_key_fields(&end,&and_level,*join_tab[i].on_expr_ref,
|
||||
join_tab[i].table->map);
|
||||
join_tab[i].table->map,sargables);
|
||||
}
|
||||
|
||||
/* Process ON conditions for the nested joins */
|
||||
|
@ -3258,7 +3361,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
|
|||
while ((table= li++))
|
||||
{
|
||||
if (table->nested_join)
|
||||
add_key_fields_for_nj(table, &end, &and_level);
|
||||
add_key_fields_for_nj(table, &end, &and_level, sargables);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5124,9 +5227,28 @@ make_simple_join(JOIN *join,TABLE *tmp_table)
|
|||
JOIN_TAB *join_tab;
|
||||
DBUG_ENTER("make_simple_join");
|
||||
|
||||
if (!(tableptr=(TABLE**) join->thd->alloc(sizeof(TABLE*))) ||
|
||||
!(join_tab=(JOIN_TAB*) join->thd->alloc(sizeof(JOIN_TAB))))
|
||||
DBUG_RETURN(TRUE);
|
||||
/*
|
||||
Reuse TABLE * and JOIN_TAB if already allocated by a previous call
|
||||
to this function through JOIN::exec (may happen for sub-queries).
|
||||
*/
|
||||
if (!join->table_reexec)
|
||||
{
|
||||
if (!(join->table_reexec= (TABLE**) join->thd->alloc(sizeof(TABLE*))))
|
||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||
if (join->tmp_join)
|
||||
join->tmp_join->table_reexec= join->table_reexec;
|
||||
}
|
||||
if (!join->join_tab_reexec)
|
||||
{
|
||||
if (!(join->join_tab_reexec=
|
||||
(JOIN_TAB*) join->thd->alloc(sizeof(JOIN_TAB))))
|
||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||
if (join->tmp_join)
|
||||
join->tmp_join->join_tab_reexec= join->join_tab_reexec;
|
||||
}
|
||||
tableptr= join->table_reexec;
|
||||
join_tab= join->join_tab_reexec;
|
||||
|
||||
join->join_tab=join_tab;
|
||||
join->table=tableptr; tableptr[0]=tmp_table;
|
||||
join->tables=1;
|
||||
|
@ -7514,7 +7636,22 @@ static void update_const_equal_items(COND *cond, JOIN_TAB *tab)
|
|||
((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
|
||||
{
|
||||
Item_equal *item_equal= (Item_equal *) cond;
|
||||
bool contained_const= item_equal->get_const() != NULL;
|
||||
item_equal->update_const();
|
||||
if (!contained_const && item_equal->get_const())
|
||||
{
|
||||
/* Update keys for range analysis */
|
||||
Item_equal_iterator it(*item_equal);
|
||||
Item_field *item_field;
|
||||
while ((item_field= it++))
|
||||
{
|
||||
Field *field= item_field->field;
|
||||
JOIN_TAB *stat= field->table->reginfo.join_tab;
|
||||
key_map possible_keys= field->key_start;
|
||||
possible_keys.intersect(field->table->keys_in_use_for_query);
|
||||
stat[0].const_keys.merge(possible_keys);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10359,6 +10496,8 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
|
|||
*/
|
||||
join->examined_rows++;
|
||||
join->thd->row_count++;
|
||||
DBUG_PRINT("counts", ("join->examined_rows++: %lu",
|
||||
(ulong) join->examined_rows));
|
||||
|
||||
if (found)
|
||||
{
|
||||
|
@ -12220,7 +12359,6 @@ static int
|
|||
create_sort_index(THD *thd, JOIN *join, ORDER *order,
|
||||
ha_rows filesort_limit, ha_rows select_limit)
|
||||
{
|
||||
SORT_FIELD *sortorder;
|
||||
uint length;
|
||||
ha_rows examined_rows;
|
||||
TABLE *table;
|
||||
|
@ -12234,11 +12372,18 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
|
|||
table= tab->table;
|
||||
select= tab->select;
|
||||
|
||||
if (test_if_skip_sort_order(tab,order,select_limit,0))
|
||||
/*
|
||||
When there is SQL_BIG_RESULT do not sort using index for GROUP BY,
|
||||
and thus force sorting on disk.
|
||||
*/
|
||||
if ((order != join->group_list ||
|
||||
!(join->select_options & SELECT_BIG_RESULT)) &&
|
||||
test_if_skip_sort_order(tab,order,select_limit,0))
|
||||
DBUG_RETURN(0);
|
||||
if (!(sortorder=make_unireg_sortorder(order,&length)))
|
||||
if (!(join->sortorder=
|
||||
make_unireg_sortorder(order,&length,join->sortorder)))
|
||||
goto err; /* purecov: inspected */
|
||||
/* It's not fatal if the following alloc fails */
|
||||
|
||||
table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
|
||||
MYF(MY_WME | MY_ZEROFILL));
|
||||
table->status=0; // May be wrong if quick_select
|
||||
|
@ -12283,7 +12428,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
|
|||
|
||||
if (table->s->tmp_table)
|
||||
table->file->info(HA_STATUS_VARIABLE); // Get record count
|
||||
table->sort.found_records=filesort(thd, table,sortorder, length,
|
||||
table->sort.found_records=filesort(thd, table,join->sortorder, length,
|
||||
select, filesort_limit, 0,
|
||||
&examined_rows);
|
||||
tab->records= table->sort.found_records; // For SQL_CALC_ROWS
|
||||
|
@ -12631,7 +12776,8 @@ err:
|
|||
}
|
||||
|
||||
|
||||
SORT_FIELD *make_unireg_sortorder(ORDER *order, uint *length)
|
||||
SORT_FIELD *make_unireg_sortorder(ORDER *order, uint *length,
|
||||
SORT_FIELD *sortorder)
|
||||
{
|
||||
uint count;
|
||||
SORT_FIELD *sort,*pos;
|
||||
|
@ -12640,7 +12786,9 @@ SORT_FIELD *make_unireg_sortorder(ORDER *order, uint *length)
|
|||
count=0;
|
||||
for (ORDER *tmp = order; tmp; tmp=tmp->next)
|
||||
count++;
|
||||
pos=sort=(SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD)*(count+1));
|
||||
if (!sortorder)
|
||||
sortorder= (SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD)*(count+1));
|
||||
pos=sort=sortorder;
|
||||
if (!pos)
|
||||
return 0;
|
||||
|
||||
|
@ -13758,7 +13906,19 @@ bool JOIN::alloc_func_list()
|
|||
disctinct->group_by optimization
|
||||
*/
|
||||
if (select_distinct)
|
||||
{
|
||||
group_parts+= fields_list.elements;
|
||||
/*
|
||||
If the ORDER clause is specified then it's possible that
|
||||
it also will be optimized, so reserve space for it too
|
||||
*/
|
||||
if (order)
|
||||
{
|
||||
ORDER *ord;
|
||||
for (ord= order; ord; ord= ord->next)
|
||||
group_parts++;
|
||||
}
|
||||
}
|
||||
|
||||
/* This must use calloc() as rollup_make_fields depends on this */
|
||||
sum_funcs= (Item_sum**) thd->calloc(sizeof(Item_sum**) * (func_count+1) +
|
||||
|
@ -14241,12 +14401,17 @@ bool JOIN::rollup_init()
|
|||
while ((item= it++))
|
||||
{
|
||||
ORDER *group_tmp;
|
||||
bool found_in_group= 0;
|
||||
|
||||
for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
|
||||
{
|
||||
if (*group_tmp->item == item)
|
||||
{
|
||||
item->maybe_null= 1;
|
||||
found_in_group= 1;
|
||||
}
|
||||
}
|
||||
if (item->type() == Item::FUNC_ITEM)
|
||||
if (item->type() == Item::FUNC_ITEM && !found_in_group)
|
||||
{
|
||||
bool changed= FALSE;
|
||||
if (change_group_ref(thd, (Item_func *) item, group_list, &changed))
|
||||
|
|
|
@ -321,6 +321,18 @@ public:
|
|||
bool union_part; // this subselect is part of union
|
||||
bool optimized; // flag to avoid double optimization in EXPLAIN
|
||||
|
||||
/*
|
||||
storage for caching buffers allocated during query execution.
|
||||
These buffers allocations need to be cached as the thread memory pool is
|
||||
cleared only at the end of the execution of the whole query and not caching
|
||||
allocations that occur in repetition at execution time will result in
|
||||
excessive memory usage.
|
||||
*/
|
||||
SORT_FIELD *sortorder; // make_unireg_sortorder()
|
||||
TABLE **table_reexec; // make_simple_join()
|
||||
JOIN_TAB *join_tab_reexec; // make_simple_join()
|
||||
/* end of allocation caching storage */
|
||||
|
||||
JOIN(THD *thd_arg, List<Item> &fields_arg, ulonglong select_options_arg,
|
||||
select_result *result_arg)
|
||||
:fields_list(fields_arg)
|
||||
|
@ -346,6 +358,9 @@ public:
|
|||
examined_rows= 0;
|
||||
exec_tmp_table1= 0;
|
||||
exec_tmp_table2= 0;
|
||||
sortorder= 0;
|
||||
table_reexec= 0;
|
||||
join_tab_reexec= 0;
|
||||
thd= thd_arg;
|
||||
sum_funcs= sum_funcs2= 0;
|
||||
procedure= 0;
|
||||
|
|
|
@ -5152,7 +5152,9 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||
ha_rows copied,deleted;
|
||||
uint db_create_options, used_fields;
|
||||
handlerton *old_db_type, *new_db_type;
|
||||
legacy_db_type table_type;
|
||||
HA_CREATE_INFO *create_info;
|
||||
frm_type_enum frm_type;
|
||||
uint need_copy_table= 0;
|
||||
bool no_table_reopen= FALSE, varchar= FALSE;
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
|
@ -5234,6 +5236,52 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||
if (alter_info->tablespace_op != NO_TABLESPACE_OP)
|
||||
DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list,
|
||||
alter_info->tablespace_op));
|
||||
strxnmov(new_name_buff, sizeof (new_name_buff) - 1, mysql_data_home, "/", db,
|
||||
"/", table_name, reg_ext, NullS);
|
||||
(void) unpack_filename(new_name_buff, new_name_buff);
|
||||
if (lower_case_table_names != 2)
|
||||
my_casedn_str(files_charset_info, new_name_buff);
|
||||
frm_type= mysql_frm_type(thd, new_name_buff, &table_type);
|
||||
/* Rename a view */
|
||||
if (frm_type == FRMTYPE_VIEW && !(alter_info->flags & ~ALTER_RENAME))
|
||||
{
|
||||
/*
|
||||
Avoid problems with a rename on a table that we have locked or
|
||||
if the user is trying to to do this in a transcation context
|
||||
*/
|
||||
|
||||
if (thd->locked_tables || thd->active_transaction())
|
||||
{
|
||||
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
|
||||
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
if (wait_if_global_read_lock(thd,0,1))
|
||||
DBUG_RETURN(1);
|
||||
VOID(pthread_mutex_lock(&LOCK_open));
|
||||
if (lock_table_names(thd, table_list))
|
||||
goto view_err;
|
||||
|
||||
error=0;
|
||||
if (!do_rename(thd, table_list, new_db, new_name, new_name, 1))
|
||||
{
|
||||
if (mysql_bin_log.is_open())
|
||||
{
|
||||
thd->clear_error();
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
|
||||
mysql_bin_log.write(&qinfo);
|
||||
}
|
||||
send_ok(thd);
|
||||
}
|
||||
|
||||
unlock_table_names(thd, table_list, (TABLE_LIST*) 0);
|
||||
|
||||
view_err:
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
start_waiting_global_read_lock(thd);
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
|
||||
DBUG_RETURN(TRUE);
|
||||
table->use_all_columns();
|
||||
|
@ -6515,7 +6563,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
|
|||
if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
|
||||
setup_order(thd, thd->lex->select_lex.ref_pointer_array,
|
||||
&tables, fields, all_fields, order) ||
|
||||
!(sortorder=make_unireg_sortorder(order, &length)) ||
|
||||
!(sortorder=make_unireg_sortorder(order, &length, NULL)) ||
|
||||
(from->sort.found_records = filesort(thd, from, sortorder, length,
|
||||
(SQL_SELECT *) 0, HA_POS_ERROR, 1,
|
||||
&examined_rows)) ==
|
||||
|
|
|
@ -327,7 +327,7 @@ int mysql_update(THD *thd,
|
|||
|
||||
table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
|
||||
MYF(MY_FAE | MY_ZEROFILL));
|
||||
if (!(sortorder=make_unireg_sortorder(order, &length)) ||
|
||||
if (!(sortorder=make_unireg_sortorder(order, &length, NULL)) ||
|
||||
(table->sort.found_records= filesort(thd, table, sortorder, length,
|
||||
select, limit, 1,
|
||||
&examined_rows))
|
||||
|
|
|
@ -1421,6 +1421,7 @@ opt_ev_comment: /* empty */ { $$= 0; }
|
|||
| COMMENT_SYM TEXT_STRING_sys
|
||||
{
|
||||
Lex->comment= Lex->event_parse_data->comment= $2;
|
||||
$$= 1;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
21
sql/table.cc
21
sql/table.cc
|
@ -802,7 +802,21 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
|||
count)))
|
||||
goto err;
|
||||
for (count= 0; count < interval->count; count++)
|
||||
interval->type_lengths[count]= strlen(interval->type_names[count]);
|
||||
{
|
||||
char *val= (char*) interval->type_names[count];
|
||||
interval->type_lengths[count]= strlen(val);
|
||||
/*
|
||||
Replace all ',' symbols with NAMES_SEP_CHAR.
|
||||
See the comment in unireg.cc, pack_fields() function
|
||||
for details.
|
||||
*/
|
||||
for (uint cnt= 0 ; cnt < interval->type_lengths[count] ; cnt++)
|
||||
{
|
||||
char c= val[cnt];
|
||||
if (c == ',')
|
||||
val[cnt]= NAMES_SEP_CHAR;
|
||||
}
|
||||
}
|
||||
interval->type_lengths[count]= 0;
|
||||
}
|
||||
}
|
||||
|
@ -2773,12 +2787,13 @@ bool st_table_list::prep_where(THD *thd, Item **conds,
|
|||
this expression will not be moved to WHERE condition (i.e. will
|
||||
be clean correctly for PS/SP)
|
||||
*/
|
||||
tbl->on_expr= and_conds(tbl->on_expr, where);
|
||||
tbl->on_expr= and_conds(tbl->on_expr,
|
||||
where->copy_andor_structure(thd));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tbl == 0)
|
||||
*conds= and_conds(*conds, where);
|
||||
*conds= and_conds(*conds, where->copy_andor_structure(thd));
|
||||
if (arena)
|
||||
thd->restore_active_arena(arena, &backup);
|
||||
where_processed= TRUE;
|
||||
|
|
|
@ -793,6 +793,21 @@ static bool pack_fields(File file, List<create_field> &create_fields,
|
|||
tmp.append(NAMES_SEP_CHAR);
|
||||
for (const char **pos=field->interval->type_names ; *pos ; pos++)
|
||||
{
|
||||
char *val= (char*) *pos;
|
||||
uint str_len= strlen(val);
|
||||
/*
|
||||
Note, hack: in old frm NAMES_SEP_CHAR is used to separate
|
||||
names in the interval (ENUM/SET). To allow names to contain
|
||||
NAMES_SEP_CHAR, we replace it with a comma before writing frm.
|
||||
Backward conversion is done during frm file opening,
|
||||
See table.cc, openfrm() function
|
||||
*/
|
||||
for (uint cnt= 0 ; cnt < str_len ; cnt++)
|
||||
{
|
||||
char c= val[cnt];
|
||||
if (c == NAMES_SEP_CHAR)
|
||||
val[cnt]= ',';
|
||||
}
|
||||
tmp.append(*pos);
|
||||
tmp.append(NAMES_SEP_CHAR);
|
||||
}
|
||||
|
|
|
@ -2,3 +2,4 @@ MYSQL_STORAGE_ENGINE(federated,,[Federated Storage Engine],
|
|||
[Connects to tables on remote MySQL servers], [max,max-no-ndb])
|
||||
MYSQL_PLUGIN_STATIC(federated, [libfederated.a])
|
||||
MYSQL_PLUGIN_DYNAMIC(federated, [ha_federated.la])
|
||||
MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(federated, [ha_federated.cc])
|
||||
|
|
|
@ -3,4 +3,5 @@ MYSQL_STORAGE_ENGINE(heap,no, [Memory Storage Engine],
|
|||
MYSQL_PLUGIN_DIRECTORY(heap, [storage/heap])
|
||||
MYSQL_PLUGIN_STATIC(heap, [libheap.a])
|
||||
MYSQL_PLUGIN_MANDATORY(heap) dnl Memory tables
|
||||
MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(heap, [ha_heap.cc])
|
||||
|
||||
|
|
|
@ -68,4 +68,5 @@ MYSQL_PLUGIN_ACTIONS(innobase, [
|
|||
storage/innobase/handler/Makefile
|
||||
storage/innobase/usr/Makefile)
|
||||
])
|
||||
MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(innobase, [handler/ha_innodb.cc])
|
||||
|
||||
|
|
|
@ -16,6 +16,31 @@
|
|||
|
||||
/* Describe, check and repair of MyISAM tables */
|
||||
|
||||
/*
|
||||
About checksum calculation.
|
||||
|
||||
There are two types of checksums. Table checksum and row checksum.
|
||||
|
||||
Row checksum is an additional byte at the end of dynamic length
|
||||
records. It must be calculated if the table is configured for them.
|
||||
Otherwise they must not be used. The variable
|
||||
MYISAM_SHARE::calc_checksum determines if row checksums are used.
|
||||
MI_INFO::checksum is used as temporary storage during row handling.
|
||||
For parallel repair we must assure that only one thread can use this
|
||||
variable. There is no problem on the write side as this is done by one
|
||||
thread only. But when checking a record after read this could go
|
||||
wrong. But since all threads read through a common read buffer, it is
|
||||
sufficient if only one thread checks it.
|
||||
|
||||
Table checksum is an eight byte value in the header of the index file.
|
||||
It can be calculated even if row checksums are not used. The variable
|
||||
MI_CHECK::glob_crc is calculated over all records.
|
||||
MI_SORT_PARAM::calc_checksum determines if this should be done. This
|
||||
variable is not part of MI_CHECK because it must be set per thread for
|
||||
parallel repair. The global glob_crc must be changed by one thread
|
||||
only. And it is sufficient to calculate the checksum once only.
|
||||
*/
|
||||
|
||||
#include "ftdefs.h"
|
||||
#include <m_ctype.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -41,8 +66,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info,MI_KEYDEF *keyinfo,
|
|||
ha_checksum *key_checksum, uint level);
|
||||
static uint isam_key_length(MI_INFO *info,MI_KEYDEF *keyinfo);
|
||||
static ha_checksum calc_checksum(ha_rows count);
|
||||
static int writekeys(MI_CHECK *param, MI_INFO *info,byte *buff,
|
||||
my_off_t filepos);
|
||||
static int writekeys(MI_SORT_PARAM *sort_param);
|
||||
static int sort_one_index(MI_CHECK *param, MI_INFO *info,MI_KEYDEF *keyinfo,
|
||||
my_off_t pagepos, File new_file);
|
||||
static int sort_key_read(MI_SORT_PARAM *sort_param,void *key);
|
||||
|
@ -1102,7 +1126,8 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
|
|||
goto err;
|
||||
start_recpos=pos;
|
||||
splits++;
|
||||
VOID(_mi_pack_get_block_info(info,&block_info, -1, start_recpos));
|
||||
VOID(_mi_pack_get_block_info(info, &info->bit_buff, &block_info,
|
||||
&info->rec_buff, -1, start_recpos));
|
||||
pos=block_info.filepos+block_info.rec_len;
|
||||
if (block_info.rec_len < (uint) info->s->min_pack_length ||
|
||||
block_info.rec_len > (uint) info->s->max_pack_length)
|
||||
|
@ -1116,7 +1141,8 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
|
|||
if (_mi_read_cache(¶m->read_cache,(byte*) info->rec_buff,
|
||||
block_info.filepos, block_info.rec_len, READING_NEXT))
|
||||
goto err;
|
||||
if (_mi_pack_rec_unpack(info,record,info->rec_buff,block_info.rec_len))
|
||||
if (_mi_pack_rec_unpack(info, &info->bit_buff, record,
|
||||
info->rec_buff, block_info.rec_len))
|
||||
{
|
||||
mi_check_print_error(param,"Found wrong record at %s",
|
||||
llstr(start_recpos,llbuff));
|
||||
|
@ -1400,7 +1426,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
|
|||
info->state->empty=0;
|
||||
param->glob_crc=0;
|
||||
if (param->testflag & T_CALC_CHECKSUM)
|
||||
param->calc_checksum=1;
|
||||
sort_param.calc_checksum= 1;
|
||||
|
||||
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
|
||||
|
||||
|
@ -1429,7 +1455,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
|
|||
/* Re-create all keys, which are set in key_map. */
|
||||
while (!(error=sort_get_next_record(&sort_param)))
|
||||
{
|
||||
if (writekeys(param,info,(byte*)sort_param.record,sort_param.filepos))
|
||||
if (writekeys(&sort_param))
|
||||
{
|
||||
if (my_errno != HA_ERR_FOUND_DUPP_KEY)
|
||||
goto err;
|
||||
|
@ -1574,11 +1600,13 @@ err:
|
|||
|
||||
/* Uppate keyfile when doing repair */
|
||||
|
||||
static int writekeys(MI_CHECK *param, register MI_INFO *info, byte *buff,
|
||||
my_off_t filepos)
|
||||
static int writekeys(MI_SORT_PARAM *sort_param)
|
||||
{
|
||||
register uint i;
|
||||
uchar *key;
|
||||
uchar *key;
|
||||
MI_INFO *info= sort_param->sort_info->info;
|
||||
byte *buff= sort_param->record;
|
||||
my_off_t filepos= sort_param->filepos;
|
||||
DBUG_ENTER("writekeys");
|
||||
|
||||
key=info->lastkey+info->s->base.max_key_length;
|
||||
|
@ -1632,8 +1660,8 @@ static int writekeys(MI_CHECK *param, register MI_INFO *info, byte *buff,
|
|||
}
|
||||
}
|
||||
/* Remove checksum that was added to glob_crc in sort_get_next_record */
|
||||
if (param->calc_checksum)
|
||||
param->glob_crc-= info->checksum;
|
||||
if (sort_param->calc_checksum)
|
||||
sort_param->sort_info->param->glob_crc-= info->checksum;
|
||||
DBUG_PRINT("error",("errno: %d",my_errno));
|
||||
DBUG_RETURN(-1);
|
||||
} /* writekeys */
|
||||
|
@ -2140,7 +2168,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
|
|||
del=info->state->del;
|
||||
param->glob_crc=0;
|
||||
if (param->testflag & T_CALC_CHECKSUM)
|
||||
param->calc_checksum=1;
|
||||
sort_param.calc_checksum= 1;
|
||||
|
||||
rec_per_key_part= param->rec_per_key_part;
|
||||
for (sort_param.key=0 ; sort_param.key < share->base.keys ;
|
||||
|
@ -2226,7 +2254,8 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
|
|||
param->retry_repair=1;
|
||||
goto err;
|
||||
}
|
||||
param->calc_checksum=0; /* No need to calc glob_crc */
|
||||
/* No need to calculate checksum again. */
|
||||
sort_param.calc_checksum= 0;
|
||||
free_root(&sort_param.wordroot, MYF(0));
|
||||
|
||||
/* Set for next loop */
|
||||
|
@ -2390,6 +2419,28 @@ err:
|
|||
Each key is handled by a separate thread.
|
||||
TODO: make a number of threads a parameter
|
||||
|
||||
In parallel repair we use one thread per index. There are two modes:
|
||||
|
||||
Quick
|
||||
|
||||
Only the indexes are rebuilt. All threads share a read buffer.
|
||||
Every thread that needs fresh data in the buffer enters the shared
|
||||
cache lock. The last thread joining the lock reads the buffer from
|
||||
the data file and wakes all other threads.
|
||||
|
||||
Non-quick
|
||||
|
||||
The data file is rebuilt and all indexes are rebuilt to point to
|
||||
the new record positions. One thread is the master thread. It
|
||||
reads from the old data file and writes to the new data file. It
|
||||
also creates one of the indexes. The other threads read from a
|
||||
buffer which is filled by the master. If they need fresh data,
|
||||
they enter the shared cache lock. If the masters write buffer is
|
||||
full, it flushes it to the new data file and enters the shared
|
||||
cache lock too. When all threads joined in the lock, the master
|
||||
copies its write buffer to the read buffer for the other threads
|
||||
and wakes them.
|
||||
|
||||
RESULT
|
||||
0 ok
|
||||
<>0 Error
|
||||
|
@ -2412,6 +2463,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
|
|||
ulong *rec_per_key_part;
|
||||
HA_KEYSEG *keyseg;
|
||||
char llbuff[22];
|
||||
IO_CACHE new_data_cache; /* For non-quick repair. */
|
||||
IO_CACHE_SHARE io_share;
|
||||
SORT_INFO sort_info;
|
||||
ulonglong key_map=share->state.key_map;
|
||||
|
@ -2433,19 +2485,55 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
|
|||
if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
|
||||
param->testflag|=T_CALC_CHECKSUM;
|
||||
|
||||
/*
|
||||
Quick repair (not touching data file, rebuilding indexes):
|
||||
{
|
||||
Read cache is (MI_CHECK *param)->read_cache using info->dfile.
|
||||
}
|
||||
|
||||
Non-quick repair (rebuilding data file and indexes):
|
||||
{
|
||||
Master thread:
|
||||
|
||||
Read cache is (MI_CHECK *param)->read_cache using info->dfile.
|
||||
Write cache is (MI_INFO *info)->rec_cache using new_file.
|
||||
|
||||
Slave threads:
|
||||
|
||||
Read cache is new_data_cache synced to master rec_cache.
|
||||
|
||||
The final assignment of the filedescriptor for rec_cache is done
|
||||
after the cache creation.
|
||||
|
||||
Don't check file size on new_data_cache, as the resulting file size
|
||||
is not known yet.
|
||||
|
||||
As rec_cache and new_data_cache are synced, write_buffer_length is
|
||||
used for the read cache 'new_data_cache'. Both start at the same
|
||||
position 'new_header_length'.
|
||||
}
|
||||
*/
|
||||
DBUG_PRINT("info", ("is quick repair: %d", rep_quick));
|
||||
bzero((char*)&sort_info,sizeof(sort_info));
|
||||
/* Initialize pthread structures before goto err. */
|
||||
pthread_mutex_init(&sort_info.mutex, MY_MUTEX_INIT_FAST);
|
||||
pthread_cond_init(&sort_info.cond, 0);
|
||||
|
||||
if (!(sort_info.key_block=
|
||||
alloc_key_blocks(param,
|
||||
(uint) param->sort_key_blocks,
|
||||
share->base.max_key_block_length))
|
||||
|| init_io_cache(¶m->read_cache,info->dfile,
|
||||
(uint) param->read_buffer_length,
|
||||
READ_CACHE,share->pack.header_length,1,MYF(MY_WME)) ||
|
||||
(! rep_quick &&
|
||||
init_io_cache(&info->rec_cache,info->dfile,
|
||||
(uint) param->write_buffer_length,
|
||||
WRITE_CACHE,new_header_length,1,
|
||||
MYF(MY_WME | MY_WAIT_IF_FULL) & param->myf_rw)))
|
||||
alloc_key_blocks(param, (uint) param->sort_key_blocks,
|
||||
share->base.max_key_block_length)) ||
|
||||
init_io_cache(¶m->read_cache, info->dfile,
|
||||
(uint) param->read_buffer_length,
|
||||
READ_CACHE, share->pack.header_length, 1, MYF(MY_WME)) ||
|
||||
(!rep_quick &&
|
||||
(init_io_cache(&info->rec_cache, info->dfile,
|
||||
(uint) param->write_buffer_length,
|
||||
WRITE_CACHE, new_header_length, 1,
|
||||
MYF(MY_WME | MY_WAIT_IF_FULL) & param->myf_rw) ||
|
||||
init_io_cache(&new_data_cache, -1,
|
||||
(uint) param->write_buffer_length,
|
||||
READ_CACHE, new_header_length, 1,
|
||||
MYF(MY_WME | MY_DONT_CHECK_FILESIZE)))))
|
||||
goto err;
|
||||
sort_info.key_block_end=sort_info.key_block+param->sort_key_blocks;
|
||||
info->opt_flag|=WRITE_CACHE_USED;
|
||||
|
@ -2536,8 +2624,6 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
|
|||
|
||||
del=info->state->del;
|
||||
param->glob_crc=0;
|
||||
if (param->testflag & T_CALC_CHECKSUM)
|
||||
param->calc_checksum=1;
|
||||
|
||||
if (!(sort_param=(MI_SORT_PARAM *)
|
||||
my_malloc((uint) share->base.keys *
|
||||
|
@ -2587,6 +2673,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
|
|||
sort_param[i].sort_info=&sort_info;
|
||||
sort_param[i].master=0;
|
||||
sort_param[i].fix_datafile=0;
|
||||
sort_param[i].calc_checksum= 0;
|
||||
|
||||
sort_param[i].filepos=new_header_length;
|
||||
sort_param[i].max_pos=sort_param[i].pos=share->pack.header_length;
|
||||
|
@ -2624,19 +2711,45 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
|
|||
sort_info.total_keys=i;
|
||||
sort_param[0].master= 1;
|
||||
sort_param[0].fix_datafile= (my_bool)(! rep_quick);
|
||||
sort_param[0].calc_checksum= test(param->testflag & T_CALC_CHECKSUM);
|
||||
|
||||
sort_info.got_error=0;
|
||||
pthread_mutex_init(&sort_info.mutex, MY_MUTEX_INIT_FAST);
|
||||
pthread_cond_init(&sort_info.cond, 0);
|
||||
pthread_mutex_lock(&sort_info.mutex);
|
||||
|
||||
init_io_cache_share(¶m->read_cache, &io_share, i);
|
||||
/*
|
||||
Initialize the I/O cache share for use with the read caches and, in
|
||||
case of non-quick repair, the write cache. When all threads join on
|
||||
the cache lock, the writer copies the write cache contents to the
|
||||
read caches.
|
||||
*/
|
||||
if (i > 1)
|
||||
{
|
||||
if (rep_quick)
|
||||
init_io_cache_share(¶m->read_cache, &io_share, NULL, i);
|
||||
else
|
||||
init_io_cache_share(&new_data_cache, &io_share, &info->rec_cache, i);
|
||||
}
|
||||
else
|
||||
io_share.total_threads= 0; /* share not used */
|
||||
|
||||
(void) pthread_attr_init(&thr_attr);
|
||||
(void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
|
||||
|
||||
for (i=0 ; i < sort_info.total_keys ; i++)
|
||||
{
|
||||
sort_param[i].read_cache=param->read_cache;
|
||||
/*
|
||||
Copy the properly initialized IO_CACHE structure so that every
|
||||
thread has its own copy. In quick mode param->read_cache is shared
|
||||
for use by all threads. In non-quick mode all threads but the
|
||||
first copy the shared new_data_cache, which is synchronized to the
|
||||
write cache of the first thread. The first thread copies
|
||||
param->read_cache, which is not shared.
|
||||
*/
|
||||
sort_param[i].read_cache= ((rep_quick || !i) ? param->read_cache :
|
||||
new_data_cache);
|
||||
DBUG_PRINT("io_cache_share", ("thread: %u read_cache: 0x%lx",
|
||||
i, (long) &sort_param[i].read_cache));
|
||||
|
||||
/*
|
||||
two approaches: the same amount of memory for each thread
|
||||
or the memory for the same number of keys for each thread...
|
||||
|
@ -2654,7 +2767,10 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
|
|||
(void *) (sort_param+i)))
|
||||
{
|
||||
mi_check_print_error(param,"Cannot start a repair thread");
|
||||
remove_io_thread(¶m->read_cache);
|
||||
/* Cleanup: Detach from the share. Avoid others to be blocked. */
|
||||
if (io_share.total_threads)
|
||||
remove_io_thread(&sort_param[i].read_cache);
|
||||
DBUG_PRINT("error", ("Cannot start a repair thread"));
|
||||
sort_info.got_error=1;
|
||||
}
|
||||
else
|
||||
|
@ -2676,6 +2792,11 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
|
|||
|
||||
if (sort_param[0].fix_datafile)
|
||||
{
|
||||
/*
|
||||
Append some nuls to the end of a memory mapped file. Destroy the
|
||||
write cache. The master thread did already detach from the share
|
||||
by remove_io_thread() in sort.c:thr_find_all_keys().
|
||||
*/
|
||||
if (write_data_suffix(&sort_info,1) || end_io_cache(&info->rec_cache))
|
||||
goto err;
|
||||
if (param->testflag & T_SAFE_REPAIR)
|
||||
|
@ -2691,8 +2812,14 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
|
|||
sort_param->filepos;
|
||||
/* Only whole records */
|
||||
share->state.version=(ulong) time((time_t*) 0);
|
||||
|
||||
/*
|
||||
Exchange the data file descriptor of the table, so that we use the
|
||||
new file from now on.
|
||||
*/
|
||||
my_close(info->dfile,MYF(0));
|
||||
info->dfile=new_file;
|
||||
|
||||
share->data_file_type=sort_info.new_data_file_type;
|
||||
share->pack.header_length=(ulong) new_header_length;
|
||||
}
|
||||
|
@ -2747,7 +2874,20 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
|
|||
|
||||
err:
|
||||
got_error|= flush_blocks(param, share->key_cache, share->kfile);
|
||||
/*
|
||||
Destroy the write cache. The master thread did already detach from
|
||||
the share by remove_io_thread() or it was not yet started (if the
|
||||
error happend before creating the thread).
|
||||
*/
|
||||
VOID(end_io_cache(&info->rec_cache));
|
||||
/*
|
||||
Destroy the new data cache in case of non-quick repair. All slave
|
||||
threads did either detach from the share by remove_io_thread()
|
||||
already or they were not yet started (if the error happend before
|
||||
creating the threads).
|
||||
*/
|
||||
if (!rep_quick)
|
||||
VOID(end_io_cache(&new_data_cache));
|
||||
if (!got_error)
|
||||
{
|
||||
/* Replace the actual file with the temporary file */
|
||||
|
@ -2879,12 +3019,41 @@ static int sort_ft_key_read(MI_SORT_PARAM *sort_param, void *key)
|
|||
} /* sort_ft_key_read */
|
||||
|
||||
|
||||
/* Read next record from file using parameters in sort_info */
|
||||
/* Return -1 if end of file, 0 if ok and > 0 if error */
|
||||
/*
|
||||
Read next record from file using parameters in sort_info.
|
||||
|
||||
SYNOPSIS
|
||||
sort_get_next_record()
|
||||
sort_param Information about and for the sort process
|
||||
|
||||
NOTE
|
||||
|
||||
Dynamic Records With Non-Quick Parallel Repair
|
||||
|
||||
For non-quick parallel repair we use a synchronized read/write
|
||||
cache. This means that one thread is the master who fixes the data
|
||||
file by reading each record from the old data file and writing it
|
||||
to the new data file. By doing this the records in the new data
|
||||
file are written contiguously. Whenever the write buffer is full,
|
||||
it is copied to the read buffer. The slaves read from the read
|
||||
buffer, which is not associated with a file. Thus read_cache.file
|
||||
is -1. When using _mi_read_cache(), the slaves must always set
|
||||
flag to READING_NEXT so that the function never tries to read from
|
||||
file. This is safe because the records are contiguous. There is no
|
||||
need to read outside the cache. This condition is evaluated in the
|
||||
variable 'parallel_flag' for quick reference. read_cache.file must
|
||||
be >= 0 in every other case.
|
||||
|
||||
RETURN
|
||||
-1 end of file
|
||||
0 ok
|
||||
> 0 error
|
||||
*/
|
||||
|
||||
static int sort_get_next_record(MI_SORT_PARAM *sort_param)
|
||||
{
|
||||
int searching;
|
||||
int parallel_flag;
|
||||
uint found_record,b_type,left_length;
|
||||
my_off_t pos;
|
||||
byte *to;
|
||||
|
@ -2922,7 +3091,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
|
|||
sort_param->max_pos=(sort_param->pos+=share->base.pack_reclength);
|
||||
if (*sort_param->record)
|
||||
{
|
||||
if (param->calc_checksum)
|
||||
if (sort_param->calc_checksum)
|
||||
param->glob_crc+= (info->checksum=
|
||||
mi_static_checksum(info,sort_param->record));
|
||||
DBUG_RETURN(0);
|
||||
|
@ -2937,6 +3106,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
|
|||
LINT_INIT(to);
|
||||
pos=sort_param->pos;
|
||||
searching=(sort_param->fix_datafile && (param->testflag & T_EXTEND));
|
||||
parallel_flag= (sort_param->read_cache.file < 0) ? READING_NEXT : 0;
|
||||
for (;;)
|
||||
{
|
||||
found_record=block_info.second_read= 0;
|
||||
|
@ -2967,7 +3137,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
|
|||
(byte*) block_info.header,pos,
|
||||
MI_BLOCK_INFO_HEADER_LENGTH,
|
||||
(! found_record ? READING_NEXT : 0) |
|
||||
READING_HEADER))
|
||||
parallel_flag | READING_HEADER))
|
||||
{
|
||||
if (found_record)
|
||||
{
|
||||
|
@ -3144,9 +3314,31 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
|
|||
llstr(sort_param->start_recpos,llbuff));
|
||||
goto try_next;
|
||||
}
|
||||
if (_mi_read_cache(&sort_param->read_cache,to,block_info.filepos,
|
||||
block_info.data_len,
|
||||
(found_record == 1 ? READING_NEXT : 0)))
|
||||
/*
|
||||
Copy information that is already read. Avoid accessing data
|
||||
below the cache start. This could happen if the header
|
||||
streched over the end of the previous buffer contents.
|
||||
*/
|
||||
{
|
||||
uint header_len= (uint) (block_info.filepos - pos);
|
||||
uint prefetch_len= (MI_BLOCK_INFO_HEADER_LENGTH - header_len);
|
||||
|
||||
if (prefetch_len > block_info.data_len)
|
||||
prefetch_len= block_info.data_len;
|
||||
if (prefetch_len)
|
||||
{
|
||||
memcpy(to, block_info.header + header_len, prefetch_len);
|
||||
block_info.filepos+= prefetch_len;
|
||||
block_info.data_len-= prefetch_len;
|
||||
left_length-= prefetch_len;
|
||||
to+= prefetch_len;
|
||||
}
|
||||
}
|
||||
if (block_info.data_len &&
|
||||
_mi_read_cache(&sort_param->read_cache,to,block_info.filepos,
|
||||
block_info.data_len,
|
||||
(found_record == 1 ? READING_NEXT : 0) |
|
||||
parallel_flag))
|
||||
{
|
||||
mi_check_print_info(param,
|
||||
"Read error for block at: %s (error: %d); Skipped",
|
||||
|
@ -3176,13 +3368,14 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
|
|||
{
|
||||
if (sort_param->read_cache.error < 0)
|
||||
DBUG_RETURN(1);
|
||||
if (info->s->calc_checksum)
|
||||
info->checksum=mi_checksum(info,sort_param->record);
|
||||
if (sort_param->calc_checksum)
|
||||
info->checksum= mi_checksum(info, sort_param->record);
|
||||
if ((param->testflag & (T_EXTEND | T_REP)) || searching)
|
||||
{
|
||||
if (_mi_rec_check(info, sort_param->record, sort_param->rec_buff,
|
||||
sort_param->find_length,
|
||||
(param->testflag & T_QUICK) &&
|
||||
sort_param->calc_checksum &&
|
||||
test(info->s->calc_checksum)))
|
||||
{
|
||||
mi_check_print_info(param,"Found wrong packed record at %s",
|
||||
|
@ -3190,7 +3383,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
|
|||
goto try_next;
|
||||
}
|
||||
}
|
||||
if (param->calc_checksum)
|
||||
if (sort_param->calc_checksum)
|
||||
param->glob_crc+= info->checksum;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
@ -3217,7 +3410,8 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
|
|||
DBUG_RETURN(1); /* Something wrong with data */
|
||||
}
|
||||
sort_param->start_recpos=sort_param->pos;
|
||||
if (_mi_pack_get_block_info(info,&block_info,-1,sort_param->pos))
|
||||
if (_mi_pack_get_block_info(info, &sort_param->bit_buff, &block_info,
|
||||
&sort_param->rec_buff, -1, sort_param->pos))
|
||||
DBUG_RETURN(-1);
|
||||
if (!block_info.rec_len &&
|
||||
sort_param->pos + MEMMAP_EXTRA_MARGIN ==
|
||||
|
@ -3241,15 +3435,14 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
|
|||
llstr(sort_param->pos,llbuff));
|
||||
continue;
|
||||
}
|
||||
if (_mi_pack_rec_unpack(info,sort_param->record,sort_param->rec_buff,
|
||||
block_info.rec_len))
|
||||
if (_mi_pack_rec_unpack(info, &sort_param->bit_buff, sort_param->record,
|
||||
sort_param->rec_buff, block_info.rec_len))
|
||||
{
|
||||
if (! searching)
|
||||
mi_check_print_info(param,"Found wrong record at %s",
|
||||
llstr(sort_param->pos,llbuff));
|
||||
continue;
|
||||
}
|
||||
info->checksum=mi_checksum(info,sort_param->record);
|
||||
if (!sort_param->fix_datafile)
|
||||
{
|
||||
sort_param->filepos=sort_param->pos;
|
||||
|
@ -3259,8 +3452,9 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
|
|||
sort_param->max_pos=(sort_param->pos=block_info.filepos+
|
||||
block_info.rec_len);
|
||||
info->packed_length=block_info.rec_len;
|
||||
if (param->calc_checksum)
|
||||
param->glob_crc+= info->checksum;
|
||||
if (sort_param->calc_checksum)
|
||||
param->glob_crc+= (info->checksum=
|
||||
mi_checksum(info, sort_param->record));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
}
|
||||
|
@ -3268,7 +3462,20 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
|
|||
}
|
||||
|
||||
|
||||
/* Write record to new file */
|
||||
/*
|
||||
Write record to new file.
|
||||
|
||||
SYNOPSIS
|
||||
sort_write_record()
|
||||
sort_param Sort parameters.
|
||||
|
||||
NOTE
|
||||
This is only called by a master thread if parallel repair is used.
|
||||
|
||||
RETURN
|
||||
0 OK
|
||||
1 Error
|
||||
*/
|
||||
|
||||
int sort_write_record(MI_SORT_PARAM *sort_param)
|
||||
{
|
||||
|
@ -3317,6 +3524,7 @@ int sort_write_record(MI_SORT_PARAM *sort_param)
|
|||
}
|
||||
from=sort_info->buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER);
|
||||
}
|
||||
/* We can use info->checksum here as only one thread calls this. */
|
||||
info->checksum=mi_checksum(info,sort_param->record);
|
||||
reclength=_mi_rec_pack(info,from,sort_param->record);
|
||||
flag=0;
|
||||
|
@ -3726,7 +3934,7 @@ static int sort_delete_record(MI_SORT_PARAM *sort_param)
|
|||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
if (param->calc_checksum)
|
||||
if (sort_param->calc_checksum)
|
||||
param->glob_crc-=(*info->s->calc_checksum)(info, sort_param->record);
|
||||
}
|
||||
error=flush_io_cache(&info->rec_cache) || (*info->s->delete_record)(info);
|
||||
|
|
|
@ -219,7 +219,10 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
|||
((open_flags & HA_OPEN_ABORT_IF_CRASHED) &&
|
||||
(my_disable_locking && share->state.open_count))))
|
||||
{
|
||||
DBUG_PRINT("error",("Table is marked as crashed"));
|
||||
DBUG_PRINT("error",("Table is marked as crashed. open_flags: %u "
|
||||
"changed: %u open_count: %u !locking: %d",
|
||||
open_flags, share->state.changed,
|
||||
share->state.open_count, my_disable_locking));
|
||||
my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
|
||||
HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
|
||||
goto err;
|
||||
|
|
|
@ -103,7 +103,8 @@ static uint fill_and_get_bits(MI_BIT_BUFF *bit_buff,uint count);
|
|||
static void fill_buffer(MI_BIT_BUFF *bit_buff);
|
||||
static uint max_bit(uint value);
|
||||
#ifdef HAVE_MMAP
|
||||
static uchar *_mi_mempack_get_block_info(MI_INFO *myisam,MI_BLOCK_INFO *info,
|
||||
static uchar *_mi_mempack_get_block_info(MI_INFO *myisam, MI_BIT_BUFF *bit_buff,
|
||||
MI_BLOCK_INFO *info, byte **rec_buff_p,
|
||||
uchar *header);
|
||||
#endif
|
||||
|
||||
|
@ -449,13 +450,15 @@ int _mi_read_pack_record(MI_INFO *info, my_off_t filepos, byte *buf)
|
|||
DBUG_RETURN(-1); /* _search() didn't find record */
|
||||
|
||||
file=info->dfile;
|
||||
if (_mi_pack_get_block_info(info, &block_info, file, filepos))
|
||||
if (_mi_pack_get_block_info(info, &info->bit_buff, &block_info,
|
||||
&info->rec_buff, file, filepos))
|
||||
goto err;
|
||||
if (my_read(file,(byte*) info->rec_buff + block_info.offset ,
|
||||
block_info.rec_len - block_info.offset, MYF(MY_NABP)))
|
||||
goto panic;
|
||||
info->update|= HA_STATE_AKTIV;
|
||||
DBUG_RETURN(_mi_pack_rec_unpack(info,buf,info->rec_buff,block_info.rec_len));
|
||||
DBUG_RETURN(_mi_pack_rec_unpack(info, &info->bit_buff, buf,
|
||||
info->rec_buff, block_info.rec_len));
|
||||
panic:
|
||||
my_errno=HA_ERR_WRONG_IN_RECORD;
|
||||
err:
|
||||
|
@ -464,8 +467,8 @@ err:
|
|||
|
||||
|
||||
|
||||
int _mi_pack_rec_unpack(register MI_INFO *info, register byte *to, byte *from,
|
||||
ulong reclength)
|
||||
int _mi_pack_rec_unpack(register MI_INFO *info, MI_BIT_BUFF *bit_buff,
|
||||
register byte *to, byte *from, ulong reclength)
|
||||
{
|
||||
byte *end_field;
|
||||
reg3 MI_COLUMNDEF *end;
|
||||
|
@ -473,18 +476,18 @@ int _mi_pack_rec_unpack(register MI_INFO *info, register byte *to, byte *from,
|
|||
MYISAM_SHARE *share=info->s;
|
||||
DBUG_ENTER("_mi_pack_rec_unpack");
|
||||
|
||||
init_bit_buffer(&info->bit_buff, (uchar*) from,reclength);
|
||||
init_bit_buffer(bit_buff, (uchar*) from, reclength);
|
||||
|
||||
for (current_field=share->rec, end=current_field+share->base.fields ;
|
||||
current_field < end ;
|
||||
current_field++,to=end_field)
|
||||
{
|
||||
end_field=to+current_field->length;
|
||||
(*current_field->unpack)(current_field,&info->bit_buff,(uchar*) to,
|
||||
(*current_field->unpack)(current_field, bit_buff, (uchar*) to,
|
||||
(uchar*) end_field);
|
||||
}
|
||||
if (! info->bit_buff.error &&
|
||||
info->bit_buff.pos - info->bit_buff.bits/8 == info->bit_buff.end)
|
||||
if (!bit_buff->error &&
|
||||
bit_buff->pos - bit_buff->bits / 8 == bit_buff->end)
|
||||
DBUG_RETURN(0);
|
||||
info->update&= ~HA_STATE_AKTIV;
|
||||
DBUG_RETURN(my_errno=HA_ERR_WRONG_IN_RECORD);
|
||||
|
@ -1015,13 +1018,16 @@ int _mi_read_rnd_pack_record(MI_INFO *info, byte *buf,
|
|||
|
||||
if (info->opt_flag & READ_CACHE_USED)
|
||||
{
|
||||
if (_mi_read_cache(&info->rec_cache,(byte*) block_info.header,filepos,
|
||||
share->pack.ref_length, skip_deleted_blocks))
|
||||
if (_mi_read_cache(&info->rec_cache, (byte*) block_info.header,
|
||||
filepos, share->pack.ref_length,
|
||||
skip_deleted_blocks ? READING_NEXT : 0))
|
||||
goto err;
|
||||
b_type=_mi_pack_get_block_info(info,&block_info,-1, filepos);
|
||||
b_type=_mi_pack_get_block_info(info, &info->bit_buff, &block_info,
|
||||
&info->rec_buff, -1, filepos);
|
||||
}
|
||||
else
|
||||
b_type=_mi_pack_get_block_info(info,&block_info,info->dfile,filepos);
|
||||
b_type=_mi_pack_get_block_info(info, &info->bit_buff, &block_info,
|
||||
&info->rec_buff, info->dfile, filepos);
|
||||
if (b_type)
|
||||
goto err; /* Error code is already set */
|
||||
#ifndef DBUG_OFF
|
||||
|
@ -1034,9 +1040,9 @@ int _mi_read_rnd_pack_record(MI_INFO *info, byte *buf,
|
|||
|
||||
if (info->opt_flag & READ_CACHE_USED)
|
||||
{
|
||||
if (_mi_read_cache(&info->rec_cache,(byte*) info->rec_buff,
|
||||
block_info.filepos, block_info.rec_len,
|
||||
skip_deleted_blocks))
|
||||
if (_mi_read_cache(&info->rec_cache, (byte*) info->rec_buff,
|
||||
block_info.filepos, block_info.rec_len,
|
||||
skip_deleted_blocks ? READING_NEXT : 0))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
|
@ -1051,8 +1057,8 @@ int _mi_read_rnd_pack_record(MI_INFO *info, byte *buf,
|
|||
info->nextpos=block_info.filepos+block_info.rec_len;
|
||||
info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
|
||||
|
||||
DBUG_RETURN (_mi_pack_rec_unpack(info,buf,info->rec_buff,
|
||||
block_info.rec_len));
|
||||
DBUG_RETURN (_mi_pack_rec_unpack(info, &info->bit_buff, buf,
|
||||
info->rec_buff, block_info.rec_len));
|
||||
err:
|
||||
DBUG_RETURN(my_errno);
|
||||
}
|
||||
|
@ -1060,8 +1066,9 @@ int _mi_read_rnd_pack_record(MI_INFO *info, byte *buf,
|
|||
|
||||
/* Read and process header from a huff-record-file */
|
||||
|
||||
uint _mi_pack_get_block_info(MI_INFO *myisam, MI_BLOCK_INFO *info, File file,
|
||||
my_off_t filepos)
|
||||
uint _mi_pack_get_block_info(MI_INFO *myisam, MI_BIT_BUFF *bit_buff,
|
||||
MI_BLOCK_INFO *info, byte **rec_buff_p,
|
||||
File file, my_off_t filepos)
|
||||
{
|
||||
uchar *header=info->header;
|
||||
uint head_length,ref_length;
|
||||
|
@ -1086,17 +1093,17 @@ uint _mi_pack_get_block_info(MI_INFO *myisam, MI_BLOCK_INFO *info, File file,
|
|||
head_length+= read_pack_length((uint) myisam->s->pack.version,
|
||||
header + head_length, &info->blob_len);
|
||||
if (!(mi_alloc_rec_buff(myisam,info->rec_len + info->blob_len,
|
||||
&myisam->rec_buff)))
|
||||
rec_buff_p)))
|
||||
return BLOCK_FATAL_ERROR; /* not enough memory */
|
||||
myisam->bit_buff.blob_pos=(uchar*) myisam->rec_buff+info->rec_len;
|
||||
myisam->bit_buff.blob_end= myisam->bit_buff.blob_pos+info->blob_len;
|
||||
bit_buff->blob_pos= (uchar*) *rec_buff_p + info->rec_len;
|
||||
bit_buff->blob_end= bit_buff->blob_pos + info->blob_len;
|
||||
myisam->blob_length=info->blob_len;
|
||||
}
|
||||
info->filepos=filepos+head_length;
|
||||
if (file > 0)
|
||||
{
|
||||
info->offset=min(info->rec_len, ref_length - head_length);
|
||||
memcpy(myisam->rec_buff, header+head_length, info->offset);
|
||||
memcpy(*rec_buff_p, header + head_length, info->offset);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1214,7 +1221,8 @@ void _mi_unmap_file(MI_INFO *info)
|
|||
}
|
||||
|
||||
|
||||
static uchar *_mi_mempack_get_block_info(MI_INFO *myisam,MI_BLOCK_INFO *info,
|
||||
static uchar *_mi_mempack_get_block_info(MI_INFO *myisam, MI_BIT_BUFF *bit_buff,
|
||||
MI_BLOCK_INFO *info, byte **rec_buff_p,
|
||||
uchar *header)
|
||||
{
|
||||
header+= read_pack_length((uint) myisam->s->pack.version, header,
|
||||
|
@ -1225,10 +1233,10 @@ static uchar *_mi_mempack_get_block_info(MI_INFO *myisam,MI_BLOCK_INFO *info,
|
|||
&info->blob_len);
|
||||
/* mi_alloc_rec_buff sets my_errno on error */
|
||||
if (!(mi_alloc_rec_buff(myisam, info->blob_len,
|
||||
&myisam->rec_buff)))
|
||||
rec_buff_p)))
|
||||
return 0; /* not enough memory */
|
||||
myisam->bit_buff.blob_pos=(uchar*) myisam->rec_buff;
|
||||
myisam->bit_buff.blob_end= (uchar*) myisam->rec_buff + info->blob_len;
|
||||
bit_buff->blob_pos= (uchar*) *rec_buff_p;
|
||||
bit_buff->blob_end= (uchar*) *rec_buff_p + info->blob_len;
|
||||
}
|
||||
return header;
|
||||
}
|
||||
|
@ -1244,11 +1252,13 @@ static int _mi_read_mempack_record(MI_INFO *info, my_off_t filepos, byte *buf)
|
|||
if (filepos == HA_OFFSET_ERROR)
|
||||
DBUG_RETURN(-1); /* _search() didn't find record */
|
||||
|
||||
if (!(pos= (byte*) _mi_mempack_get_block_info(info,&block_info,
|
||||
if (!(pos= (byte*) _mi_mempack_get_block_info(info, &info->bit_buff,
|
||||
&block_info, &info->rec_buff,
|
||||
(uchar*) share->file_map+
|
||||
filepos)))
|
||||
DBUG_RETURN(-1);
|
||||
DBUG_RETURN(_mi_pack_rec_unpack(info, buf, pos, block_info.rec_len));
|
||||
DBUG_RETURN(_mi_pack_rec_unpack(info, &info->bit_buff, buf,
|
||||
pos, block_info.rec_len));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1268,7 +1278,8 @@ static int _mi_read_rnd_mempack_record(MI_INFO *info, byte *buf,
|
|||
my_errno=HA_ERR_END_OF_FILE;
|
||||
goto err;
|
||||
}
|
||||
if (!(pos= (byte*) _mi_mempack_get_block_info(info,&block_info,
|
||||
if (!(pos= (byte*) _mi_mempack_get_block_info(info, &info->bit_buff,
|
||||
&block_info, &info->rec_buff,
|
||||
(uchar*)
|
||||
(start=share->file_map+
|
||||
filepos))))
|
||||
|
@ -1285,7 +1296,8 @@ static int _mi_read_rnd_mempack_record(MI_INFO *info, byte *buf,
|
|||
info->nextpos=filepos+(uint) (pos-start)+block_info.rec_len;
|
||||
info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
|
||||
|
||||
DBUG_RETURN (_mi_pack_rec_unpack(info,buf,pos, block_info.rec_len));
|
||||
DBUG_RETURN (_mi_pack_rec_unpack(info, &info->bit_buff, buf,
|
||||
pos, block_info.rec_len));
|
||||
err:
|
||||
DBUG_RETURN(my_errno);
|
||||
}
|
||||
|
|
|
@ -71,6 +71,21 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx, key_range *min_key,
|
|||
uchar * key_buff;
|
||||
uint start_key_len;
|
||||
|
||||
/*
|
||||
The problem is that the optimizer doesn't support
|
||||
RTree keys properly at the moment.
|
||||
Hope this will be fixed some day.
|
||||
But now NULL in the min_key means that we
|
||||
didn't make the task for the RTree key
|
||||
and expect BTree functionality from it.
|
||||
As it's not able to handle such request
|
||||
we return the error.
|
||||
*/
|
||||
if (!min_key)
|
||||
{
|
||||
res= HA_POS_ERROR;
|
||||
break;
|
||||
}
|
||||
key_buff= info->lastkey+info->s->base.max_key_length;
|
||||
start_key_len= _mi_pack_key(info,inx, key_buff,
|
||||
(uchar*) min_key->key, min_key->length,
|
||||
|
|
|
@ -76,6 +76,7 @@ typedef struct st_mi_state_info
|
|||
ulong sec_index_changed; /* Updated when new sec_index */
|
||||
ulong sec_index_used; /* which extra index are in use */
|
||||
ulonglong key_map; /* Which keys are in use */
|
||||
ha_checksum checksum; /* Table checksum */
|
||||
ulong version; /* timestamp of create */
|
||||
time_t create_time; /* Time when created database */
|
||||
time_t recover_time; /* Time for last recover */
|
||||
|
@ -177,6 +178,7 @@ typedef struct st_mi_isam_share { /* Shared between opens */
|
|||
int (*delete_record)(struct st_myisam_info*);
|
||||
int (*read_rnd)(struct st_myisam_info*, byte*, my_off_t, my_bool);
|
||||
int (*compare_record)(struct st_myisam_info*, const byte *);
|
||||
/* Function to use for a row checksum. */
|
||||
ha_checksum (*calc_checksum)(struct st_myisam_info*, const byte *);
|
||||
int (*compare_unique)(struct st_myisam_info*, MI_UNIQUEDEF *,
|
||||
const byte *record, my_off_t pos);
|
||||
|
@ -262,7 +264,7 @@ struct st_myisam_info {
|
|||
my_off_t last_keypage; /* Last key page read */
|
||||
my_off_t last_search_keypage; /* Last keypage when searching */
|
||||
my_off_t dupp_key_pos;
|
||||
ha_checksum checksum;
|
||||
ha_checksum checksum; /* Temp storage for row checksum */
|
||||
/* QQ: the folloing two xxx_length fields should be removed,
|
||||
as they are not compatible with parallel repair */
|
||||
ulong packed_length,blob_length; /* Length of found, packed record */
|
||||
|
@ -314,8 +316,9 @@ typedef struct st_mi_sort_param
|
|||
pthread_t thr;
|
||||
IO_CACHE read_cache, tempfile, tempfile_for_exceptions;
|
||||
DYNAMIC_ARRAY buffpek;
|
||||
|
||||
/*
|
||||
MI_BIT_BUFF bit_buff; /* For parallel repair of packrec. */
|
||||
|
||||
/*
|
||||
The next two are used to collect statistics, see update_key_parts for
|
||||
description.
|
||||
*/
|
||||
|
@ -326,6 +329,7 @@ typedef struct st_mi_sort_param
|
|||
uint key, key_length,real_key_length,sortbuff_size;
|
||||
uint maxbuffers, keys, find_length, sort_keys_length;
|
||||
my_bool fix_datafile, master;
|
||||
my_bool calc_checksum; /* calculate table checksum */
|
||||
MI_KEYDEF *keyinfo;
|
||||
HA_KEYSEG *seg;
|
||||
SORT_INFO *sort_info;
|
||||
|
@ -379,8 +383,15 @@ typedef struct st_mi_sort_param
|
|||
#define mi_putint(x,y,nod) { uint16 boh=(nod ? (uint16) 32768 : 0) + (uint16) (y);\
|
||||
mi_int2store(x,boh); }
|
||||
#define mi_test_if_nod(x) (x[0] & 128 ? info->s->base.key_reflength : 0)
|
||||
#define mi_mark_crashed(x) (x)->s->state.changed|=STATE_CRASHED
|
||||
#define mi_mark_crashed_on_repair(x) { (x)->s->state.changed|=STATE_CRASHED|STATE_CRASHED_ON_REPAIR ; (x)->update|= HA_STATE_CHANGED; }
|
||||
#define mi_mark_crashed(x) do{(x)->s->state.changed|= STATE_CRASHED; \
|
||||
DBUG_PRINT("error", ("Marked table crashed")); \
|
||||
}while(0)
|
||||
#define mi_mark_crashed_on_repair(x) do{(x)->s->state.changed|= \
|
||||
STATE_CRASHED|STATE_CRASHED_ON_REPAIR; \
|
||||
(x)->update|= HA_STATE_CHANGED; \
|
||||
DBUG_PRINT("error", \
|
||||
("Marked table crashed")); \
|
||||
}while(0)
|
||||
#define mi_is_crashed(x) ((x)->s->state.changed & STATE_CRASHED)
|
||||
#define mi_is_crashed_on_repair(x) ((x)->s->state.changed & STATE_CRASHED_ON_REPAIR)
|
||||
#define mi_print_error(SHARE, ERRNO) \
|
||||
|
@ -620,8 +631,8 @@ extern void _mi_print_key(FILE *stream,HA_KEYSEG *keyseg,const uchar *key,
|
|||
extern my_bool _mi_read_pack_info(MI_INFO *info,pbool fix_keys);
|
||||
extern int _mi_read_pack_record(MI_INFO *info,my_off_t filepos,byte *buf);
|
||||
extern int _mi_read_rnd_pack_record(MI_INFO*, byte *,my_off_t, my_bool);
|
||||
extern int _mi_pack_rec_unpack(MI_INFO *info,byte *to,byte *from,
|
||||
ulong reclength);
|
||||
extern int _mi_pack_rec_unpack(MI_INFO *info, MI_BIT_BUFF *bit_buff,
|
||||
byte *to, byte *from, ulong reclength);
|
||||
extern ulonglong mi_safe_mul(ulonglong a,ulonglong b);
|
||||
extern int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf,
|
||||
const byte *oldrec, const byte *newrec, my_off_t pos);
|
||||
|
@ -686,7 +697,9 @@ extern "C" {
|
|||
|
||||
extern uint _mi_get_block_info(MI_BLOCK_INFO *,File, my_off_t);
|
||||
extern uint _mi_rec_pack(MI_INFO *info,byte *to,const byte *from);
|
||||
extern uint _mi_pack_get_block_info(MI_INFO *, MI_BLOCK_INFO *, File, my_off_t);
|
||||
extern uint _mi_pack_get_block_info(MI_INFO *myisam, MI_BIT_BUFF *bit_buff,
|
||||
MI_BLOCK_INFO *info, byte **rec_buff_p,
|
||||
File file, my_off_t filepos);
|
||||
extern void _my_store_blob_length(byte *pos,uint pack_length,uint length);
|
||||
extern void _myisam_log(enum myisam_log_commands command,MI_INFO *info,
|
||||
const byte *buffert,uint length);
|
||||
|
|
|
@ -1965,7 +1965,7 @@ static char *bindigits(ulonglong value, uint bits)
|
|||
|
||||
DBUG_ASSERT(idx < sizeof(digits));
|
||||
while (idx)
|
||||
*(ptr++)= '0' + ((value >> (--idx)) & 1);
|
||||
*(ptr++)= '0' + ((char) (value >> (--idx)) & (char) 1);
|
||||
*ptr= '\0';
|
||||
return digits;
|
||||
}
|
||||
|
@ -1995,7 +1995,7 @@ static char *hexdigits(ulonglong value)
|
|||
DBUG_ASSERT(idx < sizeof(digits));
|
||||
while (idx)
|
||||
{
|
||||
if ((*(ptr++)= '0' + ((value >> (4 * (--idx))) & 0xf)) > '9')
|
||||
if ((*(ptr++)= '0' + ((char) (value >> (4 * (--idx))) & (char) 0xf)) > '9')
|
||||
*(ptr - 1)+= 'a' - '9' - 1;
|
||||
}
|
||||
*ptr= '\0';
|
||||
|
@ -2284,7 +2284,7 @@ static my_off_t write_huff_tree(HUFF_TREE *huff_tree, uint trees)
|
|||
errors++;
|
||||
break;
|
||||
}
|
||||
idx+= code & 1;
|
||||
idx+= (uint) code & 1;
|
||||
if (idx >= length)
|
||||
{
|
||||
VOID(fflush(stdout));
|
||||
|
|
|
@ -3,4 +3,5 @@ MYSQL_STORAGE_ENGINE(myisam,no, [MyISAM Storage Engine],
|
|||
MYSQL_PLUGIN_DIRECTORY(myisam, [storage/myisam])
|
||||
MYSQL_PLUGIN_STATIC(myisam, [libmyisam.a])
|
||||
MYSQL_PLUGIN_MANDATORY(myisam) dnl Default
|
||||
MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(myisam, [ha_myisam.cc])
|
||||
|
||||
|
|
|
@ -148,7 +148,8 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
|
|||
skr=maxbuffer;
|
||||
if (memavl < sizeof(BUFFPEK)*(uint) maxbuffer ||
|
||||
(keys=(memavl-sizeof(BUFFPEK)*(uint) maxbuffer)/
|
||||
(sort_length+sizeof(char*))) <= 1)
|
||||
(sort_length+sizeof(char*))) <= 1 ||
|
||||
keys < (uint) maxbuffer)
|
||||
{
|
||||
mi_check_print_error(info->sort_info->param,
|
||||
"sort_buffer_size is to small");
|
||||
|
@ -309,7 +310,7 @@ static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info, uint keys,
|
|||
|
||||
pthread_handler_t thr_find_all_keys(void *arg)
|
||||
{
|
||||
MI_SORT_PARAM *info= (MI_SORT_PARAM*) arg;
|
||||
MI_SORT_PARAM *sort_param= (MI_SORT_PARAM*) arg;
|
||||
int error;
|
||||
uint memavl,old_memavl,keys,sort_length;
|
||||
uint idx, maxbuffer;
|
||||
|
@ -321,32 +322,34 @@ pthread_handler_t thr_find_all_keys(void *arg)
|
|||
|
||||
if (my_thread_init())
|
||||
goto err;
|
||||
if (info->sort_info->got_error)
|
||||
DBUG_ENTER("thr_find_all_keys");
|
||||
DBUG_PRINT("enter", ("master: %d", sort_param->master));
|
||||
if (sort_param->sort_info->got_error)
|
||||
goto err;
|
||||
|
||||
if (info->keyinfo->flag && HA_VAR_LENGTH_KEY)
|
||||
if (sort_param->keyinfo->flag && HA_VAR_LENGTH_KEY)
|
||||
{
|
||||
info->write_keys=write_keys_varlen;
|
||||
info->read_to_buffer=read_to_buffer_varlen;
|
||||
info->write_key=write_merge_key_varlen;
|
||||
sort_param->write_keys= write_keys_varlen;
|
||||
sort_param->read_to_buffer= read_to_buffer_varlen;
|
||||
sort_param->write_key= write_merge_key_varlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->write_keys=write_keys;
|
||||
info->read_to_buffer=read_to_buffer;
|
||||
info->write_key=write_merge_key;
|
||||
sort_param->write_keys= write_keys;
|
||||
sort_param->read_to_buffer= read_to_buffer;
|
||||
sort_param->write_key= write_merge_key;
|
||||
}
|
||||
|
||||
my_b_clear(&info->tempfile);
|
||||
my_b_clear(&info->tempfile_for_exceptions);
|
||||
bzero((char*) &info->buffpek,sizeof(info->buffpek));
|
||||
bzero((char*) &info->unique, sizeof(info->unique));
|
||||
my_b_clear(&sort_param->tempfile);
|
||||
my_b_clear(&sort_param->tempfile_for_exceptions);
|
||||
bzero((char*) &sort_param->buffpek, sizeof(sort_param->buffpek));
|
||||
bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
|
||||
sort_keys= (uchar **) NULL;
|
||||
|
||||
memavl=max(info->sortbuff_size, MIN_SORT_MEMORY);
|
||||
idx= info->sort_info->max_records;
|
||||
sort_length= info->key_length;
|
||||
maxbuffer= 1;
|
||||
memavl= max(sort_param->sortbuff_size, MIN_SORT_MEMORY);
|
||||
idx= sort_param->sort_info->max_records;
|
||||
sort_length= sort_param->key_length;
|
||||
maxbuffer= 1;
|
||||
|
||||
while (memavl >= MIN_SORT_MEMORY)
|
||||
{
|
||||
|
@ -361,20 +364,22 @@ pthread_handler_t thr_find_all_keys(void *arg)
|
|||
skr=maxbuffer;
|
||||
if (memavl < sizeof(BUFFPEK)*maxbuffer ||
|
||||
(keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
|
||||
(sort_length+sizeof(char*))) <= 1)
|
||||
(sort_length+sizeof(char*))) <= 1 ||
|
||||
keys < (uint) maxbuffer)
|
||||
{
|
||||
mi_check_print_error(info->sort_info->param,
|
||||
mi_check_print_error(sort_param->sort_info->param,
|
||||
"sort_buffer_size is to small");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr);
|
||||
}
|
||||
if ((sort_keys=(uchar **)my_malloc(keys*(sort_length+sizeof(char*))+
|
||||
((info->keyinfo->flag & HA_FULLTEXT) ?
|
||||
HA_FT_MAXBYTELEN : 0), MYF(0))))
|
||||
if ((sort_keys= (uchar**)
|
||||
my_malloc(keys*(sort_length+sizeof(char*))+
|
||||
((sort_param->keyinfo->flag & HA_FULLTEXT) ?
|
||||
HA_FT_MAXBYTELEN : 0), MYF(0))))
|
||||
{
|
||||
if (my_init_dynamic_array(&info->buffpek, sizeof(BUFFPEK),
|
||||
if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK),
|
||||
maxbuffer, maxbuffer/2))
|
||||
{
|
||||
my_free((gptr) sort_keys,MYF(0));
|
||||
|
@ -389,70 +394,88 @@ pthread_handler_t thr_find_all_keys(void *arg)
|
|||
}
|
||||
if (memavl < MIN_SORT_MEMORY)
|
||||
{
|
||||
mi_check_print_error(info->sort_info->param,"Sort buffer to small"); /* purecov: tested */
|
||||
mi_check_print_error(sort_param->sort_info->param, "Sort buffer too small");
|
||||
goto err; /* purecov: tested */
|
||||
}
|
||||
|
||||
if (info->sort_info->param->testflag & T_VERBOSE)
|
||||
printf("Key %d - Allocating buffer for %d keys\n",info->key+1,keys);
|
||||
info->sort_keys=sort_keys;
|
||||
if (sort_param->sort_info->param->testflag & T_VERBOSE)
|
||||
printf("Key %d - Allocating buffer for %d keys\n",
|
||||
sort_param->key + 1, keys);
|
||||
sort_param->sort_keys= sort_keys;
|
||||
|
||||
idx=error=0;
|
||||
sort_keys[0]=(uchar*) (sort_keys+keys);
|
||||
|
||||
while (!(error=info->sort_info->got_error) &&
|
||||
!(error=(*info->key_read)(info,sort_keys[idx])))
|
||||
DBUG_PRINT("info", ("reading keys"));
|
||||
while (!(error= sort_param->sort_info->got_error) &&
|
||||
!(error= (*sort_param->key_read)(sort_param, sort_keys[idx])))
|
||||
{
|
||||
if (info->real_key_length > info->key_length)
|
||||
if (sort_param->real_key_length > sort_param->key_length)
|
||||
{
|
||||
if (write_key(info,sort_keys[idx], &info->tempfile_for_exceptions))
|
||||
if (write_key(sort_param, sort_keys[idx],
|
||||
&sort_param->tempfile_for_exceptions))
|
||||
goto err;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (++idx == keys)
|
||||
{
|
||||
if (info->write_keys(info,sort_keys,idx-1,
|
||||
(BUFFPEK *)alloc_dynamic(&info->buffpek),
|
||||
&info->tempfile))
|
||||
if (sort_param->write_keys(sort_param, sort_keys, idx - 1,
|
||||
(BUFFPEK*) alloc_dynamic(&sort_param->buffpek),
|
||||
&sort_param->tempfile))
|
||||
goto err;
|
||||
sort_keys[0]=(uchar*) (sort_keys+keys);
|
||||
memcpy(sort_keys[0],sort_keys[idx-1],(size_t) info->key_length);
|
||||
memcpy(sort_keys[0], sort_keys[idx - 1], (size_t) sort_param->key_length);
|
||||
idx=1;
|
||||
}
|
||||
sort_keys[idx]=sort_keys[idx-1]+info->key_length;
|
||||
sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length;
|
||||
}
|
||||
if (error > 0)
|
||||
goto err;
|
||||
if (info->buffpek.elements)
|
||||
if (sort_param->buffpek.elements)
|
||||
{
|
||||
if (info->write_keys(info,sort_keys, idx,
|
||||
(BUFFPEK *) alloc_dynamic(&info->buffpek), &info->tempfile))
|
||||
if (sort_param->write_keys(sort_param, sort_keys, idx,
|
||||
(BUFFPEK*) alloc_dynamic(&sort_param->buffpek),
|
||||
&sort_param->tempfile))
|
||||
goto err;
|
||||
info->keys=(info->buffpek.elements-1)*(keys-1)+idx;
|
||||
sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx;
|
||||
}
|
||||
else
|
||||
info->keys=idx;
|
||||
sort_param->keys= idx;
|
||||
|
||||
info->sort_keys_length=keys;
|
||||
sort_param->sort_keys_length= keys;
|
||||
goto ok;
|
||||
|
||||
err:
|
||||
info->sort_info->got_error=1; /* no need to protect this with a mutex */
|
||||
DBUG_PRINT("error", ("got some error"));
|
||||
sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */
|
||||
if (sort_keys)
|
||||
my_free((gptr) sort_keys,MYF(0));
|
||||
info->sort_keys=0;
|
||||
delete_dynamic(& info->buffpek);
|
||||
close_cached_file(&info->tempfile);
|
||||
close_cached_file(&info->tempfile_for_exceptions);
|
||||
sort_param->sort_keys= 0;
|
||||
delete_dynamic(& sort_param->buffpek);
|
||||
close_cached_file(&sort_param->tempfile);
|
||||
close_cached_file(&sort_param->tempfile_for_exceptions);
|
||||
|
||||
ok:
|
||||
free_root(&info->wordroot, MYF(0));
|
||||
remove_io_thread(&info->read_cache);
|
||||
pthread_mutex_lock(&info->sort_info->mutex);
|
||||
info->sort_info->threads_running--;
|
||||
pthread_cond_signal(&info->sort_info->cond);
|
||||
pthread_mutex_unlock(&info->sort_info->mutex);
|
||||
free_root(&sort_param->wordroot, MYF(0));
|
||||
/*
|
||||
Detach from the share if the writer is involved. Avoid others to
|
||||
be blocked. This includes a flush of the write buffer. This will
|
||||
also indicate EOF to the readers.
|
||||
*/
|
||||
if (sort_param->sort_info->info->rec_cache.share)
|
||||
remove_io_thread(&sort_param->sort_info->info->rec_cache);
|
||||
|
||||
/* Readers detach from the share if any. Avoid others to be blocked. */
|
||||
if (sort_param->read_cache.share)
|
||||
remove_io_thread(&sort_param->read_cache);
|
||||
|
||||
pthread_mutex_lock(&sort_param->sort_info->mutex);
|
||||
if (!--sort_param->sort_info->threads_running)
|
||||
pthread_cond_signal(&sort_param->sort_info->cond);
|
||||
pthread_mutex_unlock(&sort_param->sort_info->mutex);
|
||||
|
||||
DBUG_PRINT("exit", ("======== ending thread ========"));
|
||||
my_thread_end();
|
||||
return NULL;
|
||||
}
|
||||
|
@ -470,6 +493,7 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
|
|||
MYISAM_SHARE *share=info->s;
|
||||
MI_SORT_PARAM *sinfo;
|
||||
byte *mergebuf=0;
|
||||
DBUG_ENTER("thr_write_keys");
|
||||
LINT_INIT(length);
|
||||
|
||||
for (i= 0, sinfo= sort_param ;
|
||||
|
@ -479,6 +503,8 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
|
|||
if (!sinfo->sort_keys)
|
||||
{
|
||||
got_error=1;
|
||||
my_free(mi_get_rec_buff_ptr(info, sinfo->rec_buff),
|
||||
MYF(MY_ALLOW_ZERO_PTR));
|
||||
continue;
|
||||
}
|
||||
if (!got_error)
|
||||
|
@ -606,7 +632,7 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
|
|||
}
|
||||
}
|
||||
my_free((gptr) mergebuf,MYF(MY_ALLOW_ZERO_PTR));
|
||||
return got_error;
|
||||
DBUG_RETURN(got_error);
|
||||
}
|
||||
#endif /* THREAD */
|
||||
|
||||
|
|
|
@ -3,3 +3,4 @@ MYSQL_STORAGE_ENGINE(myisammrg,no,[MyISAM MERGE Engine],
|
|||
MYSQL_PLUGIN_DIRECTORY(myisammrg,[storage/myisammrg])
|
||||
MYSQL_PLUGIN_STATIC(myisammrg, [libmyisammrg.a])
|
||||
MYSQL_PLUGIN_MANDATORY(myisammrg)
|
||||
MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(myisammrg, [ha_myisammrg.cc])
|
||||
|
|
|
@ -75,7 +75,7 @@ Dbtup::dump_disk_alloc(Dbtup::Disk_alloc_info & alloc)
|
|||
for(Uint32 i = 0; i<MAX_FREE_LIST; i++)
|
||||
{
|
||||
printf(" %d : ", i);
|
||||
Ptr<Page> ptr;
|
||||
PagePtr ptr;
|
||||
ArrayPool<Page> *pool= (ArrayPool<Page>*)&m_global_page_pool;
|
||||
LocalDLList<Page> list(*pool, alloc.m_dirty_pages[i]);
|
||||
for(list.first(ptr); !ptr.isNull(); list.next(ptr))
|
||||
|
@ -262,7 +262,7 @@ Dbtup::update_extent_pos(Disk_alloc_info& alloc,
|
|||
}
|
||||
|
||||
void
|
||||
Dbtup::restart_setup_page(Disk_alloc_info& alloc, Ptr<Page> pagePtr)
|
||||
Dbtup::restart_setup_page(Disk_alloc_info& alloc, PagePtr pagePtr)
|
||||
{
|
||||
/**
|
||||
* Link to extent, clear uncommitted_used_space
|
||||
|
@ -344,12 +344,15 @@ Dbtup::disk_page_prealloc(Signal* signal,
|
|||
if (!alloc.m_dirty_pages[i].isEmpty())
|
||||
{
|
||||
ptrI= alloc.m_dirty_pages[i].firstItem;
|
||||
Ptr<GlobalPage> page;
|
||||
m_global_page_pool.getPtr(page, ptrI);
|
||||
Ptr<GlobalPage> gpage;
|
||||
m_global_page_pool.getPtr(gpage, ptrI);
|
||||
|
||||
disk_page_prealloc_dirty_page(alloc, *(PagePtr*)&page, i, sz);
|
||||
key->m_page_no= ((Page*)page.p)->m_page_no;
|
||||
key->m_file_no= ((Page*)page.p)->m_file_no;
|
||||
PagePtr tmp;
|
||||
tmp.i = gpage.i;
|
||||
tmp.p = reinterpret_cast<Page*>(gpage.p);
|
||||
disk_page_prealloc_dirty_page(alloc, tmp, i, sz);
|
||||
key->m_page_no= tmp.p->m_page_no;
|
||||
key->m_file_no= tmp.p->m_file_no;
|
||||
if (DBG_DISK)
|
||||
ndbout << " found dirty page " << *key << endl;
|
||||
return 0; // Page in memory
|
||||
|
@ -547,7 +550,7 @@ Dbtup::disk_page_prealloc(Signal* signal,
|
|||
|
||||
void
|
||||
Dbtup::disk_page_prealloc_dirty_page(Disk_alloc_info & alloc,
|
||||
Ptr<Page> pagePtr,
|
||||
PagePtr pagePtr,
|
||||
Uint32 old_idx, Uint32 sz)
|
||||
{
|
||||
ddassert(pagePtr.p->list_index == old_idx);
|
||||
|
@ -638,7 +641,9 @@ Dbtup::disk_page_prealloc_callback(Signal* signal,
|
|||
fragPtr.i= req.p->m_frag_ptr_i;
|
||||
ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
|
||||
|
||||
Ptr<Page> pagePtr = *(Ptr<Page>*)&gpage;
|
||||
PagePtr pagePtr;
|
||||
pagePtr.i = gpage.i;
|
||||
pagePtr.p = reinterpret_cast<Page*>(gpage.p);
|
||||
|
||||
if (unlikely(pagePtr.p->m_restart_seq != globalData.m_restart_seq))
|
||||
{
|
||||
|
@ -666,7 +671,9 @@ Dbtup::disk_page_prealloc_initial_callback(Signal*signal,
|
|||
|
||||
Ptr<GlobalPage> gpage;
|
||||
m_global_page_pool.getPtr(gpage, page_id);
|
||||
Ptr<Page> pagePtr = *(Ptr<Page>*)&gpage;
|
||||
PagePtr pagePtr;
|
||||
pagePtr.i = gpage.i;
|
||||
pagePtr.p = reinterpret_cast<Page*>(gpage.p);
|
||||
|
||||
Ptr<Fragrecord> fragPtr;
|
||||
fragPtr.i= req.p->m_frag_ptr_i;
|
||||
|
@ -705,7 +712,7 @@ void
|
|||
Dbtup::disk_page_prealloc_callback_common(Signal* signal,
|
||||
Ptr<Page_request> req,
|
||||
Ptr<Fragrecord> fragPtr,
|
||||
Ptr<Page> pagePtr)
|
||||
PagePtr pagePtr)
|
||||
{
|
||||
/**
|
||||
* 1) remove page request from Disk_alloc_info.m_page_requests
|
||||
|
@ -736,7 +743,7 @@ Dbtup::disk_page_prealloc_callback_common(Signal* signal,
|
|||
*/
|
||||
ArrayPool<Page> *cheat_pool= (ArrayPool<Page>*)&m_global_page_pool;
|
||||
LocalDLList<Page> list(* cheat_pool, alloc.m_dirty_pages[new_idx]);
|
||||
list.add(*(Ptr<Page>*)&pagePtr);
|
||||
list.add(pagePtr);
|
||||
pagePtr.p->uncommitted_used_space = real_used;
|
||||
pagePtr.p->list_index = new_idx;
|
||||
|
||||
|
@ -765,7 +772,7 @@ Dbtup::disk_page_prealloc_callback_common(Signal* signal,
|
|||
}
|
||||
|
||||
void
|
||||
Dbtup::disk_page_set_dirty(Ptr<Page> pagePtr)
|
||||
Dbtup::disk_page_set_dirty(PagePtr pagePtr)
|
||||
{
|
||||
Uint32 idx = pagePtr.p->list_index;
|
||||
if ((idx & 0x8000) == 0)
|
||||
|
@ -833,7 +840,9 @@ Dbtup::disk_page_unmap_callback(Uint32 page_id, Uint32 dirty_count)
|
|||
{
|
||||
Ptr<GlobalPage> gpage;
|
||||
m_global_page_pool.getPtr(gpage, page_id);
|
||||
PagePtr pagePtr= *(PagePtr*)&gpage;
|
||||
PagePtr pagePtr;
|
||||
pagePtr.i = gpage.i;
|
||||
pagePtr.p = reinterpret_cast<Page*>(gpage.p);
|
||||
|
||||
Uint32 type = pagePtr.p->m_page_header.m_page_type;
|
||||
if (unlikely((type != File_formats::PT_Tup_fixsize_page &&
|
||||
|
@ -1028,10 +1037,13 @@ Dbtup::disk_page_abort_prealloc(Signal *signal, Fragrecord* fragPtrP,
|
|||
case -1:
|
||||
break;
|
||||
default:
|
||||
Ptr<GlobalPage> page;
|
||||
m_global_page_pool.getPtr(page, (Uint32)res);
|
||||
disk_page_abort_prealloc_callback_1(signal, fragPtrP, *(PagePtr*)&page,
|
||||
sz);
|
||||
Ptr<GlobalPage> gpage;
|
||||
m_global_page_pool.getPtr(gpage, (Uint32)res);
|
||||
PagePtr pagePtr;
|
||||
pagePtr.i = gpage.i;
|
||||
pagePtr.p = reinterpret_cast<Page*>(gpage.p);
|
||||
|
||||
disk_page_abort_prealloc_callback_1(signal, fragPtrP, pagePtr, sz);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1044,8 +1056,10 @@ Dbtup::disk_page_abort_prealloc_callback(Signal* signal,
|
|||
Ptr<GlobalPage> gpage;
|
||||
m_global_page_pool.getPtr(gpage, page_id);
|
||||
|
||||
PagePtr pagePtr= *(PagePtr*)&gpage;
|
||||
|
||||
PagePtr pagePtr;
|
||||
pagePtr.i = gpage.i;
|
||||
pagePtr.p = reinterpret_cast<Page*>(gpage.p);
|
||||
|
||||
Ptr<Tablerec> tabPtr;
|
||||
tabPtr.i= pagePtr.p->m_table_id;
|
||||
ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
|
||||
|
@ -1308,7 +1322,9 @@ Dbtup::disk_restart_undo_callback(Signal* signal,
|
|||
jamEntry();
|
||||
Ptr<GlobalPage> gpage;
|
||||
m_global_page_pool.getPtr(gpage, page_id);
|
||||
Ptr<Page> pagePtr = *(Ptr<Page>*)&gpage;
|
||||
PagePtr pagePtr;
|
||||
pagePtr.i = gpage.i;
|
||||
pagePtr.p = reinterpret_cast<Page*>(gpage.p);
|
||||
|
||||
Apply_undo* undo = &f_undo;
|
||||
|
||||
|
|
|
@ -1039,22 +1039,19 @@ int Dbtup::handleUpdateReq(Signal* signal,
|
|||
tup_version= (tup_version + 1) & ZTUP_VERSION_MASK;
|
||||
operPtrP->tupVersion= tup_version;
|
||||
|
||||
int retValue;
|
||||
if (!req_struct->interpreted_exec) {
|
||||
jam();
|
||||
retValue= updateAttributes(req_struct,
|
||||
&cinBuffer[0],
|
||||
req_struct->attrinfo_len);
|
||||
int retValue = updateAttributes(req_struct,
|
||||
&cinBuffer[0],
|
||||
req_struct->attrinfo_len);
|
||||
if (unlikely(retValue == -1))
|
||||
goto error;
|
||||
} else {
|
||||
jam();
|
||||
if (unlikely(interpreterStartLab(signal, req_struct) == -1))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (retValue == -1) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (regTabPtr->need_shrink())
|
||||
{
|
||||
shrink_tuple(req_struct, sizes+2, regTabPtr, disk);
|
||||
|
@ -1073,7 +1070,7 @@ int Dbtup::handleUpdateReq(Signal* signal,
|
|||
jam();
|
||||
setChecksum(req_struct->m_tuple_ptr, regTabPtr);
|
||||
}
|
||||
return retValue;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
tupkeyErrorLab(signal);
|
||||
|
|
|
@ -305,7 +305,11 @@ inline
|
|||
bool
|
||||
RecordPool<T, P>::seize(Ptr<T> & ptr)
|
||||
{
|
||||
return m_pool.seize(*(Ptr<void>*)&ptr);
|
||||
Ptr<void> tmp;
|
||||
bool ret = m_pool.seize(tmp);
|
||||
ptr.i = tmp.i;
|
||||
ptr.p = static_cast<T*>(tmp.p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T, typename P>
|
||||
|
|
|
@ -366,7 +366,29 @@ NdbTransaction::execute(ExecType aTypeOfExec,
|
|||
* operations, making postExecute impossible
|
||||
*/
|
||||
if (abortOption == AO_IgnoreError)
|
||||
{
|
||||
if (theCompletedFirstOp != NULL)
|
||||
{
|
||||
if (tCompletedFirstOp != NULL)
|
||||
{
|
||||
tCompletedLastOp->next(theCompletedFirstOp);
|
||||
theCompletedFirstOp = tCompletedFirstOp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
theCompletedFirstOp = tCompletedFirstOp;
|
||||
theCompletedLastOp = tCompletedLastOp;
|
||||
}
|
||||
if (tPrepOp != NULL && tRestOp != NULL) {
|
||||
if (theFirstOpInList == NULL)
|
||||
theFirstOpInList = tRestOp;
|
||||
else
|
||||
theLastOpInList->next(tRestOp);
|
||||
theLastOpInList = tLastOp;
|
||||
}
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ndb_api_crash_on_complex_blob_abort
|
||||
|
|
|
@ -33,7 +33,7 @@ typedef struct charset_info_st
|
|||
uint strxfrm_multiply;
|
||||
uint mbminlen;
|
||||
uint mbmaxlen;
|
||||
char max_sort_char; /* For LIKE optimization */
|
||||
uint16 max_sort_char; /* For LIKE optimization */
|
||||
|
||||
MY_CHARSET_HANDLER *cset;
|
||||
MY_COLLATION_HANDLER *coll;
|
||||
|
@ -134,7 +134,15 @@ Misc fields
|
|||
mbmaxlen - maximum multibyte sequence length.
|
||||
1 for 8bit charsets. Can be also 2 or 3.
|
||||
|
||||
|
||||
max_sort_char - for LIKE range
|
||||
in case of 8bit character sets - native code
|
||||
of maximum character (max_str pad byte);
|
||||
in case of UTF8 and UCS2 - Unicode code of the maximum
|
||||
possible character (usually U+FFFF). This code is
|
||||
converted to multibyte representation (usually 0xEFBFBF)
|
||||
and then used as a pad sequence for max_str.
|
||||
in case of other multibyte character sets -
|
||||
max_str pad byte (usually 0xFF).
|
||||
|
||||
MY_CHARSET_HANDLER
|
||||
==================
|
||||
|
|
|
@ -474,15 +474,35 @@ static void my_hash_sort_mb_bin(CHARSET_INFO *cs __attribute__((unused)),
|
|||
|
||||
|
||||
/*
|
||||
Write max key: create a buffer with multibyte
|
||||
representation of the max_sort_char character,
|
||||
and copy it into max_str in a loop.
|
||||
Fill the given buffer with 'maximum character' for given charset
|
||||
SYNOPSIS
|
||||
pad_max_char()
|
||||
cs Character set
|
||||
str Start of buffer to fill
|
||||
end End of buffer to fill
|
||||
|
||||
DESCRIPTION
|
||||
Write max key:
|
||||
- for non-Unicode character sets:
|
||||
just set to 255.
|
||||
- for Unicode character set (utf-8):
|
||||
create a buffer with multibyte representation of the max_sort_char
|
||||
character, and copy it into max_str in a loop.
|
||||
*/
|
||||
static void pad_max_char(CHARSET_INFO *cs, char *str, char *end)
|
||||
{
|
||||
char buf[10];
|
||||
char buflen= cs->cset->wc_mb(cs, cs->max_sort_char, (uchar*) buf,
|
||||
(uchar*) buf + sizeof(buf));
|
||||
char buflen;
|
||||
|
||||
if (!(cs->state & MY_CS_UNICODE))
|
||||
{
|
||||
bfill(str, end - str, 255);
|
||||
return;
|
||||
}
|
||||
|
||||
buflen= cs->cset->wc_mb(cs, cs->max_sort_char, (uchar*) buf,
|
||||
(uchar*) buf + sizeof(buf));
|
||||
|
||||
DBUG_ASSERT(buflen > 0);
|
||||
do
|
||||
{
|
||||
|
@ -943,7 +963,7 @@ MY_COLLATION_HANDLER my_collation_mb_bin_handler =
|
|||
my_strnncollsp_mb_bin,
|
||||
my_strnxfrm_mb_bin,
|
||||
my_strnxfrmlen_simple,
|
||||
my_like_range_simple,
|
||||
my_like_range_mb,
|
||||
my_wildcmp_mb_bin,
|
||||
my_strcasecmp_mb_bin,
|
||||
my_instr_mb,
|
||||
|
|
|
@ -2615,7 +2615,7 @@ CHARSET_INFO my_charset_utf8_bin=
|
|||
1, /* mbminlen */
|
||||
3, /* mbmaxlen */
|
||||
0, /* min_sort_char */
|
||||
255, /* max_sort_char */
|
||||
0xFFFF, /* max_sort_char */
|
||||
' ', /* pad char */
|
||||
0, /* escape_with_backslash_is_dangerous */
|
||||
&my_charset_utf8_handler,
|
||||
|
|
|
@ -327,7 +327,7 @@ then
|
|||
cp -fp mysql-debug-%{mysql_version}/config.log "$MYSQL_DEBUGCONFLOG_DEST"
|
||||
fi
|
||||
|
||||
(cd mysql-debug-%{mysql_version} ; \
|
||||
(cd mysql-debug-%{mysql_version}/mysql-test ; \
|
||||
./mysql-test-run.pl --comment=debug --skip-rpl --skip-ndbcluster --force ; \
|
||||
true)
|
||||
|
||||
|
@ -357,12 +357,13 @@ then
|
|||
cp -fp mysql-release-%{mysql_version}/config.log "$MYSQL_CONFLOG_DEST"
|
||||
fi
|
||||
|
||||
(cd mysql-release-%{mysql_version} ; \
|
||||
./mysql-test-run.pl --comment=normal --force ; \
|
||||
./mysql-test-run.pl --comment=ps --ps-protocol --force ; \
|
||||
./mysql-test-run.pl --comment=normal+rowrepl --mysqld=--binlog-format=row --force ; \
|
||||
./mysql-test-run.pl --comment=ps+rowrepl --ps-protocol --mysqld=--binlog-format=row --force ; \
|
||||
true)
|
||||
cd mysql-release-%{mysql_version}/mysql-test
|
||||
./mysql-test-run.pl --comment=normal --force --skip-ndbcluster --timer || true
|
||||
./mysql-test-run.pl --comment=ps --ps-protocol --force --skip-ndbcluster --timer || true
|
||||
./mysql-test-run.pl --comment=normal+rowrepl --mysqld=--binlog-format=row --force --skip-ndbcluster --timer || true
|
||||
./mysql-test-run.pl --comment=ps+rowrepl+NDB --ps-protocol --mysqld=--binlog-format=row --force --timer || true
|
||||
./mysql-test-run.pl --comment=NDB --with-ndbcluster-only --force --timer || true
|
||||
cd ../..
|
||||
|
||||
##############################################################################
|
||||
|
||||
|
@ -522,7 +523,6 @@ fi
|
|||
%doc %attr(644, root, man) %{_mandir}/man1/myisamchk.1*
|
||||
%doc %attr(644, root, man) %{_mandir}/man1/myisamlog.1*
|
||||
%doc %attr(644, root, man) %{_mandir}/man1/myisampack.1*
|
||||
%doc %attr(644, root, man) %{_mandir}/man1/mysql_explain_log.1*
|
||||
%doc %attr(644, root, man) %{_mandir}/man8/mysqld.8*
|
||||
%doc %attr(644, root, man) %{_mandir}/man1/mysqld_multi.1*
|
||||
%doc %attr(644, root, man) %{_mandir}/man1/mysqld_safe.1*
|
||||
|
|
|
@ -140,11 +140,19 @@ static signal_entry install_signal[]= {
|
|||
{ SIGABRT, handle_core_signal },
|
||||
{ SIGFPE, handle_core_signal },
|
||||
{ SIGSEGV, handle_core_signal },
|
||||
{ SIGBUS, handle_core_signal },
|
||||
{ SIGXCPU, handle_core_signal },
|
||||
{ SIGXFSZ, handle_core_signal },
|
||||
{ SIGSYS, handle_core_signal },
|
||||
{ SIGTRAP, handle_core_signal }
|
||||
{ SIGBUS, handle_core_signal }
|
||||
#ifdef SIGXCPU
|
||||
, { SIGXCPU, handle_core_signal }
|
||||
#endif
|
||||
#ifdef SIGXCPU
|
||||
, { SIGXFSZ, handle_core_signal }
|
||||
#endif
|
||||
#ifdef SIGXCPU
|
||||
, { SIGSYS, handle_core_signal }
|
||||
#endif
|
||||
#ifdef SIGXCPU
|
||||
, { SIGTRAP, handle_core_signal }
|
||||
#endif
|
||||
};
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue