Commit fed7a8d6 authored by hf@deer.(none)'s avatar hf@deer.(none)

Merge abotchkov@bk-internal.mysql.com:/home/bk/mysql-4.1

into deer.(none):/home/hf/work/mysql-4.1.2way
parents 1374a58c acdc9c59
......@@ -34,6 +34,7 @@ hf@deer.(none)
hf@deer.mysql.r18.ru
hf@genie.(none)
igor@hundin.mysql.fi
igor@rurik.mysql.com
jani@dsl-jkl1657.dial.inet.fi
jani@dsl-kpogw4gb5.dial.inet.fi
jani@hynda.(none)
......@@ -97,6 +98,7 @@ sasha@mysql.sashanet.com
serg@build.mysql2.com
serg@serg.mylan
serg@serg.mysql.com
serg@sergbook.mylan
serg@sergbook.mysql.com
sinisa@rhols221.adsl.netsonic.fi
tfr@beta.frontier86.ee
......
#! /bin/sh
echo "Test: post-incoming works"
#! /bin/sh
echo "Test: post-outgoing works"
#!/bin/sh
if [ "$REAL_EMAIL" = "" ]
then
echo "Error: you must set REAL_EMAIL in your profile"
echo "e.g.: export REAL_EMAIL='Joe Dow <joe@foo.bar>'"
echo ""
echo "Commit FAILED!"
echo "Set REAL_EMAIL and retry."
exit 1
fi
......@@ -10,7 +10,7 @@ This is a simple 'HOWTO' document describing how to
build MySQL binaries for versions 4.1 and above on
Windows. Instructions are provided for building binaries
from a standard source distribution or from the BitKeeper
tree that contains the latest developer source.
tree that contains the latest development source.
---------------------------------------------------------
NOTE
......@@ -51,29 +51,15 @@ system:
- ~45 MB disk space
- 64 MB RAM
You'll also need a MySQL source distribution. You can
get the source for released versions of MySQL from:
http://www.mysql.com/downloads/
Alternatively, you can package a source distribution
yourself from the latest BitKeeper developer source
tree. If you plan to do this, you must create the
package on a Unix system and then transfer it to your
Windows system. (The reason for this is that the initial
configuration scripts and some of the build steps work
only on Unix.) The BitKeeper approach thus requires:
- A system running Unix, or a Unix-like system such as Linux
- BitKeeper 3.0 installed on that system (you can obtain
BitKeeper from http://www.bitkeeper.com)
You'll also need a MySQL source distribution, which you
can obtain as described in section 2.
-------------------------------------------------------
2. OBTAINING A WINDOWS SOURCE DISTRIBUTION
-------------------------------------------------------
There are two ways you can get a Windows source distribution for
MySQL version 4.1 and above:
There are two ways you can get a Windows source distribution
for MySQL version 4.1 and above:
I. Obtain a MySQL AB-distributed source distribution for the
particular version of MySQL in which you are interested.
......@@ -82,41 +68,54 @@ MySQL version 4.1 and above:
http://www.mysql.com/downloads/
II. Create a source package yourself from the latest development
'BitKeeper' source tree.
II. Alternatively, you can package a source distribution
yourself from the latest BitKeeper developer source
tree. If you plan to do this, you must create the
package on a Unix system and then transfer it to your
Windows system. (The reason for this is that some of the
configuration and build steps require tools that work only
on Unix.) The BitKeeper approach thus requires:
- A system running Unix, or a Unix-like system such as Linux
- BitKeeper 3.0 installed on that system (you can obtain
BitKeeper from http://www.bitkeeper.com)
If you are using the first option, you can skip the next
section and go directly to 'BUILDING FROM VC++ WORKSPACE'.
section and go directly to "BUILDING 'mysql server & clients'
FROM VC++ WORKSPACE"
-------------------------------------------------------
3. CREATING A SOURCE PACKAGE FROM THE 'BitKeeper' TREE
-------------------------------------------------------
To build the latest Windows source package, Please follow the
following instructions from any of your '*UNIX*' operating
systems (preferably Linux):
To build the latest Windows source package from the current
BitKeeper source tree, use the following instructions. Please
note that this procedure must be performed on a system
running a Unix or Unix-like operating system. (The procedure
is know to work well on Linux, for example.
- Clone the BitKeeper source tree for MySQL (version 4.1
or above, as desired). For more information how to clone
the BitKeeper source tree, follow the instructions at:
the source tree, see the instructions at:
http://www.mysql.com/doc/en/Installing_source_tree.html
- Build the distribution so that you have a server binary to
work with. One way to do this is to run the following
command in the top-level directory of your source tree:
- Configure and build the distribution so that you have a
server binary to work with. One way to do this is to run
the following command in the top-level directory of your
source tree:
./BUILD/compile-pentium-max
- After making sure that build process completed successfully,
- After making sure that the build process completed successfully,
run the following utility script from top-level directory
of your source tree:
./scripts/make_win_src_distribution
This script creates the Windows source package. You can
supply different options to the script based on your needs.
It accepts: the following options:
This script creates a Windows source package, to be used on
your Windows system. You can supply different options to the
script based on your needs. It accepts the following options:
--debug Debug, without creating the package
--tmp Specify the temporary location
......@@ -128,15 +127,14 @@ systems (preferably Linux):
By default, make_win_src_distribution creates a zipped
archive with the name mysql-$version-win-src.zip, where
$version is the version of the MySQL source tree you
cloned.
$version represents the version of your MySQL source tree.
- Copy or upload to your Windows machine the Windows source
package that you have just created, and compile it using
package that you have just created. To compile it, use
the instructions in the next section.
---------------------------------------------------------
4. BUILDING 'mysql server & clients' FROM VC++ WORKSPACE
4. BUILDING 'mysql server & clients' FROM VC++ WORKSPACE
---------------------------------------------------------
NOTE: MySQL 4.1 and above VC++ workspace files are compatible
......@@ -148,20 +146,20 @@ Unpack the Windows source zipped archive to a folder and open
mysql.dsw from your top-level directory.
If you want to build both release and debug versions, then
select 'build' -> 'buildall' option. To build only 'release'
or 'debug' versions, then select all appropriate workspaces
from the 'build' -> 'batch build' option.
select 'build' -> 'buildall' option. To build only release
or debug versions, select all appropriate workspaces from
the 'build' -> 'batch build' option.
The simplest solution to build basic clients and core
The simplest solution to building the basic clients and core
server is to set your current active workspace as 'mysqld'
release or debug version, and just hit 'build' or 'F7', which
creates necessary client binaries in the 'client_release' or
'client_debug' directories. The libraries are placed in the
creates the necessary client binaries in the 'client_release'
or 'client_debug' directories. The libraries are placed in the
'lib_release' and 'lib_debug' directories for release and
debug versions, respectively.
Now you have built the distribution. If you get any compiler
errors, please cross check and send the compiler output to
errors, please cross check and email the compiler output to
win32@lists.mysql.com for further assistance.
---------------------------------------------------------
......@@ -173,16 +171,28 @@ TODO from MySQL PIEFU team.
6. STARTING THE MYSQL SERVER FOR THE FIRST TIME
---------------------------------------------------------
First ensure to set or copy my.ini or my.cnf file to your
'data' directory that exists in the top-level directory or
point to existing 'data' directory.
Now, start your server from the 'client_release' or
'client_debug' directory (depending on which server you
want to use), by following the instructions from:
The server built using the preceding instructions will
expect that the MySQL base directory and data directory
are C:\mysql and C:\mysql\data by default. If you want to
test your server using the source root directory and its
data directory as the base directory and data directory,
you will need to tell the server their pathnames. You can
either do this on the command line with the --basedir
and --data-dir options, or place appropriate options in
an option file (C:\my.cnf or the my.ini file in your
Windows directory). If you have an existing data directory
elsewhere that you want to use, you can specify its pathname
instead.
Start your server from the 'client_release' or 'client_debug'
directory (depending on which server you want to use). The
general instructions are given here:
http://www.mysql.com/doc/en/Windows_installation.html
You'll have to adapt the instructions appropriately if you
want to use a different base directory and/or data directory.
That's all!!! See, it's as simple to build MySQL on Windows
as on any other platform!!!
......@@ -200,12 +210,12 @@ exists in your 'client_release' or 'client_debug' directory.
---------------------------------------------------------
- For production use, MySQL AB does not advise using a MySQL
server built by yourself from source. Instead, stick to
binaries shipped by MySQL AB.
server built by yourself from source. It is preferable to
stick to using binaries shipped by MySQL AB.
- If you find something not working as expected, or you have
suggestions about ways to improve the current build process
on Windows, please email to 'win32@lists.mysql.com'.
on Windows, please email to win32@lists.mysql.com.
Thanks
MySQL Team
......@@ -22,7 +22,7 @@ AUTOMAKE_OPTIONS = foreign
EXTRA_DIST = INSTALL-SOURCE README \
COPYING COPYING.LIB
SUBDIRS = . include @docs_dirs@ \
@readline_topdir@ \
@readline_topdir@ sql-common \
@thread_dirs@ pstack @sql_client_dirs@ \
@sql_server_dirs@ scripts man tests \
BUILD @netware_dir@ os2 @libmysqld_dirs@ \
......
......@@ -2176,8 +2176,8 @@ AC_ARG_WITH(libedit,
[ with_libedit=undefined ]
)
compile_readline= no
compile_libedit= no
compile_readline="no"
compile_libedit="no"
if [test "$with_libedit" = "yes"] && [test "$with_readline" = "yes"]
then
......@@ -2820,6 +2820,7 @@ AC_OUTPUT(Makefile extra/Makefile mysys/Makefile isam/Makefile dnl
libmysql_r/Makefile libmysqld/Makefile libmysqld/examples/Makefile dnl
libmysql/Makefile client/Makefile dnl
pstack/Makefile pstack/aout/Makefile sql/Makefile sql/share/Makefile dnl
sql-common/Makefile dnl
merge/Makefile dbug/Makefile scripts/Makefile dnl
include/Makefile sql-bench/Makefile tools/Makefile dnl
tests/Makefile Docs/Makefile support-files/Makefile dnl
......@@ -2840,6 +2841,7 @@ echo "Remember to check the platform specific part of the reference manual for"
echo "hints about installing MySQL on your platform. Also have a look at the"
echo "files in the Docs directory."
echo
# The following text is checked in ./Do-compile to se that the configure ends.
# The following text is checked in ./Do-compile to verify that configure
# ended sucessfully - don't remove it.
echo "Thank you for choosing MySQL!"
echo
......@@ -21,7 +21,7 @@ pkginclude_HEADERS = my_dbug.h m_string.h my_sys.h my_list.h my_xml.h \
my_semaphore.h my_pthread.h my_no_pthread.h raid.h \
errmsg.h my_global.h my_net.h my_alloc.h \
my_getopt.h sslopt-longopts.h my_dir.h typelib.h \
sslopt-vars.h sslopt-case.h $(BUILT_SOURCES)
sslopt-vars.h sslopt-case.h sql_common.h $(BUILT_SOURCES)
noinst_HEADERS = config-win.h config-os2.h config-netware.h \
nisam.h heap.h merge.h my_bitmap.h\
myisam.h myisampack.h myisammrg.h ft_global.h\
......
......@@ -123,7 +123,8 @@ enum ha_extra_function {
HA_EXTRA_NO_IGNORE_DUP_KEY,
HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE, /* Cursor will not be used for update */
HA_EXTRA_PREPARE_FOR_DELETE,
HA_EXTRA_PREPARE_FOR_UPDATE /* Remove read cache if problems */
HA_EXTRA_PREPARE_FOR_UPDATE, /* Remove read cache if problems */
HA_EXTRA_PRELOAD_BUFFER_SIZE /* Set buffer size for preloading */
};
/* The following is parameter to ha_panic() */
......@@ -256,6 +257,7 @@ enum ha_base_keytype {
#define HA_ERR_CANNOT_ADD_FOREIGN 150 /* Cannot add a foreign key constr. */
#define HA_ERR_NO_REFERENCED_ROW 151 /* Cannot add a child row */
#define HA_ERR_ROW_IS_REFERENCED 152 /* Cannot delete a parent row */
#define HA_ERR_NON_UNIQUE_BLOCK_SIZE 153 /* Non unique key block size */
/* Other constants */
......
......@@ -643,6 +643,8 @@ extern int init_key_cache(ulong use_mem);
extern int resize_key_cache(ulong use_mem);
extern byte *key_cache_read(File file,my_off_t filepos,byte* buff,uint length,
uint block_length,int return_buffer);
extern int key_cache_insert(File file, my_off_t filepos,
byte *buff, uint length);
extern int key_cache_write(File file,my_off_t filepos,byte* buff,uint length,
uint block_length,int force_write);
extern int flush_key_blocks(int file, enum flush_type type);
......
......@@ -410,6 +410,7 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, ulonglong key_map,
int mi_init_bulk_insert(MI_INFO *info, ulong cache_size, ha_rows rows);
void mi_flush_bulk_insert(MI_INFO *info, uint inx);
void mi_end_bulk_insert(MI_INFO *info);
int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves);
#ifdef __cplusplus
}
......
......@@ -28,6 +28,7 @@ libmysqlclient_la_SOURCES = $(target_sources)
libmysqlclient_la_LIBADD = $(target_libadd)
libmysqlclient_la_LDFLAGS = $(target_ldflags)
EXTRA_DIST = Makefile.shared
noinst_HEADERS = client_settings.h
# This is called from the toplevel makefile
link_sources:
......
......@@ -47,6 +47,7 @@ libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
mi_range.c mi_dbug.c mi_checksum.c mi_log.c \
mi_changed.c mi_static.c mi_delete_all.c \
mi_delete_table.c mi_rename.c mi_check.c \
mi_preload.c \
ft_parser.c ft_stopwords.c ft_static.c \
ft_update.c ft_boolean_search.c ft_nlq_search.c sort.c \
rt_index.c rt_key.c rt_mbr.c rt_split.c sp_key.c
......
......@@ -367,6 +367,9 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
if (!share->state.header.uniques)
info->opt_flag|= OPT_NO_ROWS;
break;
case HA_EXTRA_PRELOAD_BUFFER_SIZE:
info->preload_buff_size= *((ulong *) extra_arg);
break;
case HA_EXTRA_KEY_CACHE:
case HA_EXTRA_NO_KEY_CACHE:
default:
......
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Preload indexes into key cache
*/
#include "myisamdef.h"
/*
Preload pages of the index file for a table into the key cache
SYNOPSIS
mi_preload()
info open table
map map of indexes to preload into key cache
ignore_leaves only non-leaves pages are to be preloaded
RETURN VALUE
0 if a success. error code - otherwise.
NOTES.
At present pages for all indexes are preloaded.
In future only pages for indexes specified in the key_map parameter
of the table will be preloaded.
*/
int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
{
uint i;
uint length;
uint block_length= 0;
uchar *buff= NULL;
MYISAM_SHARE* share= info->s;
uint keys= share->state.header.keys;
MI_KEYDEF *keyinfo= share->keyinfo;
my_off_t key_file_length= share->state.state.key_file_length;
my_off_t pos= share->base.keystart;
if (!keys || !key_map || key_file_length == pos)
return 0;
block_length= keyinfo[0].block_length;
if (!key_map)
return 0;
/* Check whether all indexes use the same block size */
for (i= 1 ; i < keys ; i++)
{
if (keyinfo[i].block_length != block_length)
return (my_errno= HA_ERR_NON_UNIQUE_BLOCK_SIZE);
}
length= info->preload_buff_size/block_length * block_length;
set_if_bigger(length, block_length);
if (!(buff= (uchar *) my_malloc(length, MYF(MY_WME))))
return (my_errno= HA_ERR_OUT_OF_MEM);
if (flush_key_blocks(share->kfile, FLUSH_RELEASE))
goto err;
do
{
/* Read the next block of index file into the preload buffer */
set_if_smaller(length, key_file_length-pos);
if (my_pread(share->kfile, (byte*) buff, length, pos, MYF(MY_FAE)))
goto err;
if (ignore_leaves)
{
uchar *end= buff+length;
do
{
if (mi_test_if_nod(buff))
{
if (key_cache_insert(share->kfile, pos, (byte*) buff, block_length))
goto err;
}
pos+= block_length;
}
while ((buff+= block_length) != end);
buff= end-length;
}
else
{
if (key_cache_insert(share->kfile, pos, (byte*) buff, length))
goto err;
pos+= length;
}
}
while (pos != key_file_length);
my_free(buff, MYF(0));
return 0;
err:
my_free(buff, MYF(MY_ALLOW_ZERO_PTR));
return (my_errno= errno);
}
......@@ -262,6 +262,7 @@ struct st_myisam_info {
int save_lastinx;
LIST open_list;
IO_CACHE rec_cache; /* When cacheing records */
uint preload_buff_size; /* When preloading indexes */
myf lock_wait; /* is 0 or MY_DONT_WAIT */
my_bool was_locked; /* Was locked in panic */
my_bool quick_mode;
......
......@@ -249,6 +249,24 @@ INSERT INTO t1 VALUES (1, 'a545f661efdd1fb66fdee3aab79945bf');
SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password");
1
DROP TABLE t1;
select collation(bin(130)), coercibility(bin(130));
collation(bin(130)) coercibility(bin(130))
latin1_swedish_ci 3
select collation(oct(130)), coercibility(oct(130));
collation(oct(130)) coercibility(oct(130))
latin1_swedish_ci 3
select collation(conv(130,16,10)), coercibility(conv(130,16,10));
collation(conv(130,16,10)) coercibility(conv(130,16,10))
latin1_swedish_ci 3
select collation(hex(130)), coercibility(hex(130));
collation(hex(130)) coercibility(hex(130))
latin1_swedish_ci 3
select collation(char(130)), coercibility(hex(130));
collation(char(130)) coercibility(hex(130))
binary 3
select collation(format(130,10)), coercibility(format(130,10));
collation(format(130,10)) coercibility(format(130,10))
latin1_swedish_ci 3
select collation(lcase(_latin2'a')), coercibility(lcase(_latin2'a'));
collation(lcase(_latin2'a')) coercibility(lcase(_latin2'a'))
latin2_general_ci 3
......@@ -267,9 +285,21 @@ latin2_general_ci 3
select collation(concat(_latin2'a',_latin2'b')), coercibility(concat(_latin2'a',_latin2'b'));
collation(concat(_latin2'a',_latin2'b')) coercibility(concat(_latin2'a',_latin2'b'))
latin2_general_ci 3
select collation(lpad(_latin2'a',4,_latin2'b')), coercibility(lpad(_latin2'a',4,_latin2'b'));
collation(lpad(_latin2'a',4,_latin2'b')) coercibility(lpad(_latin2'a',4,_latin2'b'))
binary 3
select collation(rpad(_latin2'a',4,_latin2'b')), coercibility(rpad(_latin2'a',4,_latin2'b'));
collation(rpad(_latin2'a',4,_latin2'b')) coercibility(rpad(_latin2'a',4,_latin2'b'))
latin2_general_ci 3
select collation(concat_ws(_latin2'a',_latin2'b')), coercibility(concat_ws(_latin2'a',_latin2'b'));
collation(concat_ws(_latin2'a',_latin2'b')) coercibility(concat_ws(_latin2'a',_latin2'b'))
latin2_general_ci 3
select collation(make_set(255,_latin2'a',_latin2'b',_latin2'c')), coercibility(make_set(255,_latin2'a',_latin2'b',_latin2'c'));
collation(make_set(255,_latin2'a',_latin2'b',_latin2'c')) coercibility(make_set(255,_latin2'a',_latin2'b',_latin2'c'))
latin2_general_ci 3
select collation(export_set(255,_latin2'y',_latin2'n',_latin2' ')), coercibility(export_set(255,_latin2'y',_latin2'n',_latin2' '));
collation(export_set(255,_latin2'y',_latin2'n',_latin2' ')) coercibility(export_set(255,_latin2'y',_latin2'n',_latin2' '))
binary 3
select collation(trim(_latin2' a ')), coercibility(trim(_latin2' a '));
collation(trim(_latin2' a ')) coercibility(trim(_latin2' a '))
latin2_general_ci 3
......@@ -306,15 +336,28 @@ latin2_general_ci 3
select collation(insert(_latin2'abcd',2,3,_latin2'ef')), coercibility(insert(_latin2'abcd',2,3,_latin2'ef'));
collation(insert(_latin2'abcd',2,3,_latin2'ef')) coercibility(insert(_latin2'abcd',2,3,_latin2'ef'))
latin2_general_ci 3
select collation(replace(_latin2'abcd',_latin2'b',_latin2'B')), coercibility(replace(_latin2'abcd',_latin2'b',_latin2'B'));
collation(replace(_latin2'abcd',_latin2'b',_latin2'B')) coercibility(replace(_latin2'abcd',_latin2'b',_latin2'B'))
latin2_general_ci 3
create table t1
select
bin(130),
oct(130),
conv(130,16,10),
hex(130),
char(130),
format(130,10),
left(_latin2'a',1),
right(_latin2'a',1),
lcase(_latin2'a'),
ucase(_latin2'a'),
substring(_latin2'a',1,1),
concat(_latin2'a',_latin2'b'),
lpad(_latin2'a',4,_latin2'b'),
rpad(_latin2'a',4,_latin2'b'),
concat_ws(_latin2'a',_latin2'b'),
make_set(255,_latin2'a',_latin2'b',_latin2'c'),
export_set(255,_latin2'y',_latin2'n',_latin2' '),
trim(_latin2' a '),
ltrim(_latin2' a '),
rtrim(_latin2' a '),
......@@ -326,18 +369,31 @@ reverse(_latin2'ab'),
quote(_latin2'ab'),
soundex(_latin2'ab'),
substring(_latin2'ab',1),
insert(_latin2'abcd',2,3,_latin2'ef')
insert(_latin2'abcd',2,3,_latin2'ef'),
replace(_latin2'abcd',_latin2'b',_latin2'B')
;
Warnings:
Warning 1263 Data truncated for column 'format(130,10)' at row 1
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`bin(130)` char(64) NOT NULL default '',
`oct(130)` char(64) NOT NULL default '',
`conv(130,16,10)` char(64) NOT NULL default '',
`hex(130)` char(6) NOT NULL default '',
`char(130)` char(1) NOT NULL default '',
`format(130,10)` char(4) NOT NULL default '',
`left(_latin2'a',1)` char(1) character set latin2 NOT NULL default '',
`right(_latin2'a',1)` char(1) character set latin2 NOT NULL default '',
`lcase(_latin2'a')` char(1) character set latin2 NOT NULL default '',
`ucase(_latin2'a')` char(1) character set latin2 NOT NULL default '',
`substring(_latin2'a',1,1)` char(1) character set latin2 NOT NULL default '',
`concat(_latin2'a',_latin2'b')` char(2) character set latin2 NOT NULL default '',
`lpad(_latin2'a',4,_latin2'b')` char(4) character set latin2 NOT NULL default '',
`rpad(_latin2'a',4,_latin2'b')` char(4) character set latin2 NOT NULL default '',
`concat_ws(_latin2'a',_latin2'b')` char(1) character set latin2 NOT NULL default '',
`make_set(255,_latin2'a',_latin2'b',_latin2'c')` char(5) character set latin2 NOT NULL default '',
`export_set(255,_latin2'y',_latin2'n',_latin2' ')` char(127) character set latin2 NOT NULL default '',
`trim(_latin2' a ')` char(3) character set latin2 NOT NULL default '',
`ltrim(_latin2' a ')` char(3) character set latin2 NOT NULL default '',
`rtrim(_latin2' a ')` char(3) character set latin2 NOT NULL default '',
......@@ -349,6 +405,7 @@ t1 CREATE TABLE `t1` (
`quote(_latin2'ab')` char(6) character set latin2 NOT NULL default '',
`soundex(_latin2'ab')` char(4) character set latin2 NOT NULL default '',
`substring(_latin2'ab',1)` char(2) character set latin2 NOT NULL default '',
`insert(_latin2'abcd',2,3,_latin2'ef')` char(6) character set latin2 NOT NULL default ''
`insert(_latin2'abcd',2,3,_latin2'ef')` char(6) character set latin2 NOT NULL default '',
`replace(_latin2'abcd',_latin2'b',_latin2'B')` char(4) character set latin2 NOT NULL default ''
) TYPE=MyISAM CHARSET=latin1
drop table t1;
drop table if exists t1, t2;
create table t1 (
a int not null auto_increment,
b char(16) not null,
primary key (a),
key (b)
);
create table t2(
a int not null auto_increment,
b char(16) not null,
primary key (a),
key (b)
);
insert into t1(b) values
('test0'),
('test1'),
('test2'),
('test3'),
('test4'),
('test5'),
('test6'),
('test7');
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
select count(*) from t1;
count(*)
33448
select count(*) from t2;
count(*)
20672
flush tables;
flush status;
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
select count(*) from t1 where b = 'test1';
count(*)
4181
show status like "key_read%";
Variable_name Value
Key_read_requests 217
Key_reads 45
select count(*) from t1 where b = 'test1';
count(*)
4181
show status like "key_read%";
Variable_name Value
Key_read_requests 434
Key_reads 45
flush tables;
flush status;
select @@preload_buffer_size;
@@preload_buffer_size
32768
load index into cache t1 keys;
Table Op Msg_type Msg_text
test.t1 preload_keys status OK
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
select count(*) from t1 where b = 'test1';
count(*)
4181
show status like "key_read%";
Variable_name Value
Key_read_requests 217
Key_reads 45
flush tables;
flush status;
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
set session preload_buffer_size=256*1024;
select @@preload_buffer_size;
@@preload_buffer_size
262144
load index into cache t1 keys ignore leaves;
Table Op Msg_type Msg_text
test.t1 preload_keys status OK
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
select count(*) from t1 where b = 'test1';
count(*)
4181
show status like "key_read%";
Variable_name Value
Key_read_requests 217
Key_reads 45
flush tables;
flush status;
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
set session preload_buffer_size=1*1024;
select @@preload_buffer_size;
@@preload_buffer_size
1024
load index into cache t1 keys, t2 keys (primary,b) ignore leaves;
Table Op Msg_type Msg_text
test.t1 preload_keys status OK
test.t2 preload_keys status OK
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
select count(*) from t1 where b = 'test1';
count(*)
4181
select count(*) from t2 where b = 'test1';
count(*)
2584
show status like "key_read%";
Variable_name Value
Key_read_requests 351
Key_reads 73
flush tables;
flush status;
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
load index into cache t3 keys, t2 keys (primary,b) ;
Table Op Msg_type Msg_text
test.t3 preload_keys error Table 'test.t3' doesn't exist
test.t2 preload_keys status OK
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
flush tables;
flush status;
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
load index into cache t3 keys (b), t2 keys (c) ;
Table Op Msg_type Msg_text
test.t3 preload_keys error Table 'test.t3' doesn't exist
test.t2 preload_keys error Key column 'c' doesn't exist in table
test.t2 preload_keys status Operation failed
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
drop table t1, t2;
......@@ -136,13 +136,23 @@ DROP TABLE t1;
#
# Test collation and coercibility
#
select collation(bin(130)), coercibility(bin(130));
select collation(oct(130)), coercibility(oct(130));
select collation(conv(130,16,10)), coercibility(conv(130,16,10));
select collation(hex(130)), coercibility(hex(130));
select collation(char(130)), coercibility(hex(130));
select collation(format(130,10)), coercibility(format(130,10));
select collation(lcase(_latin2'a')), coercibility(lcase(_latin2'a'));
select collation(ucase(_latin2'a')), coercibility(ucase(_latin2'a'));
select collation(left(_latin2'a',1)), coercibility(left(_latin2'a',1));
select collation(right(_latin2'a',1)), coercibility(right(_latin2'a',1));
select collation(substring(_latin2'a',1,1)), coercibility(substring(_latin2'a',1,1));
select collation(concat(_latin2'a',_latin2'b')), coercibility(concat(_latin2'a',_latin2'b'));
select collation(lpad(_latin2'a',4,_latin2'b')), coercibility(lpad(_latin2'a',4,_latin2'b'));
select collation(rpad(_latin2'a',4,_latin2'b')), coercibility(rpad(_latin2'a',4,_latin2'b'));
select collation(concat_ws(_latin2'a',_latin2'b')), coercibility(concat_ws(_latin2'a',_latin2'b'));
select collation(make_set(255,_latin2'a',_latin2'b',_latin2'c')), coercibility(make_set(255,_latin2'a',_latin2'b',_latin2'c'));
select collation(export_set(255,_latin2'y',_latin2'n',_latin2' ')), coercibility(export_set(255,_latin2'y',_latin2'n',_latin2' '));
select collation(trim(_latin2' a ')), coercibility(trim(_latin2' a '));
select collation(ltrim(_latin2' a ')), coercibility(ltrim(_latin2' a '));
select collation(rtrim(_latin2' a ')), coercibility(rtrim(_latin2' a '));
......@@ -155,16 +165,27 @@ select collation(quote(_latin2'ab')), coercibility(quote(_latin2'ab'));
select collation(soundex(_latin2'ab')), coercibility(soundex(_latin2'ab'));
select collation(substring(_latin2'ab',1)), coercibility(substring(_latin2'ab',1));
select collation(insert(_latin2'abcd',2,3,_latin2'ef')), coercibility(insert(_latin2'abcd',2,3,_latin2'ef'));
select collation(replace(_latin2'abcd',_latin2'b',_latin2'B')), coercibility(replace(_latin2'abcd',_latin2'b',_latin2'B'));
create table t1
select
bin(130),
oct(130),
conv(130,16,10),
hex(130),
char(130),
format(130,10),
left(_latin2'a',1),
right(_latin2'a',1),
lcase(_latin2'a'),
ucase(_latin2'a'),
substring(_latin2'a',1,1),
concat(_latin2'a',_latin2'b'),
lpad(_latin2'a',4,_latin2'b'),
rpad(_latin2'a',4,_latin2'b'),
concat_ws(_latin2'a',_latin2'b'),
make_set(255,_latin2'a',_latin2'b',_latin2'c'),
export_set(255,_latin2'y',_latin2'n',_latin2' '),
trim(_latin2' a '),
ltrim(_latin2' a '),
rtrim(_latin2' a '),
......@@ -176,8 +197,8 @@ select
quote(_latin2'ab'),
soundex(_latin2'ab'),
substring(_latin2'ab',1),
insert(_latin2'abcd',2,3,_latin2'ef')
insert(_latin2'abcd',2,3,_latin2'ef'),
replace(_latin2'abcd',_latin2'b',_latin2'B')
;
show create table t1;
drop table t1;
#
# Testing of PRELOAD
#
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
create table t1 (
a int not null auto_increment,
b char(16) not null,
primary key (a),
key (b)
);
create table t2(
a int not null auto_increment,
b char(16) not null,
primary key (a),
key (b)
);
insert into t1(b) values
('test0'),
('test1'),
('test2'),
('test3'),
('test4'),
('test5'),
('test6'),
('test7');
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
select count(*) from t1;
select count(*) from t2;
flush tables; flush status;
show status like "key_read%";
select count(*) from t1 where b = 'test1';
show status like "key_read%";
select count(*) from t1 where b = 'test1';
show status like "key_read%";
flush tables; flush status;
select @@preload_buffer_size;
load index into cache t1 keys;
show status like "key_read%";
select count(*) from t1 where b = 'test1';
show status like "key_read%";
flush tables; flush status;
show status like "key_read%";
set session preload_buffer_size=256*1024;
select @@preload_buffer_size;
load index into cache t1 keys ignore leaves;
show status like "key_read%";
select count(*) from t1 where b = 'test1';
show status like "key_read%";
flush tables; flush status;
show status like "key_read%";
set session preload_buffer_size=1*1024;
select @@preload_buffer_size;
load index into cache t1 keys, t2 keys (primary,b) ignore leaves;
show status like "key_read%";
select count(*) from t1 where b = 'test1';
select count(*) from t2 where b = 'test1';
show status like "key_read%";
flush tables; flush status;
show status like "key_read%";
load index into cache t3 keys, t2 keys (primary,b) ;
show status like "key_read%";
flush tables; flush status;
show status like "key_read%";
load index into cache t3 keys (b), t2 keys (c) ;
show status like "key_read%";
drop table t1, t2;
......@@ -826,7 +826,7 @@ static HASH_LINK *get_hash_link(int file, my_off_t filepos)
(uint) hash_link->file,(ulong) hash_link->diskpos));
}
}
KEYCACHE_DBUG_ASSERT(n <= my_hash_links_used);
KEYCACHE_DBUG_ASSERT(cnt <= my_hash_links_used);
#endif
}
if (! hash_link)
......@@ -1063,6 +1063,9 @@ static BLOCK_LINK *find_key_block(int file, my_off_t filepos,
KEYCACHE_DBUG_ASSERT(page_status != -1);
*page_st=page_status;
KEYCACHE_DBUG_PRINT("find_key_block",
("file %u, filepos %lu, page_status %lu",
(uint) file,(ulong) filepos,(uint) page_status));
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE("check_keycache2",test_key_cache("end of find_key_block",0););
......@@ -1181,7 +1184,7 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
keycache_pthread_mutex_lock(&THR_LOCK_keycache);
my_cache_r_requests++;
block=find_key_block(file,filepos,0,&page_st);
if (page_st != PAGE_READ)
if (block->status != BLOCK_ERROR && page_st != PAGE_READ)
{
/* The requested page is to be read into the block buffer */
read_block(block,key_cache_block_size,read_length+offset,
......@@ -1255,6 +1258,86 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
}
/*
Insert a block of file data from a buffer into key cache
SYNOPSIS
key_cache_insert()
file file descriptor
filepos file offset of the data from the buffer
buff buffer with data to insert into key cache
length length of the data in the buffer
RETURN VALUE
0 if a success, 1 -otherwise.
*/
int key_cache_insert(File file, my_off_t filepos, byte *buff, uint length)
{
DBUG_ENTER("key_cache_insert");
DBUG_PRINT("enter", ("file %u, filepos %lu, length %u",
(uint) file,(ulong) filepos, length));
if (my_disk_blocks > 0)
{
/* Key cache is used */
reg1 BLOCK_LINK *block;
uint offset= (uint) (filepos & (key_cache_block_size-1));
uint read_length;
int page_st;
/* Read data into key cache from buff in key_cache_block_size increments */
filepos-= offset;
do
{
read_length= length > key_cache_block_size ?
key_cache_block_size : length;
KEYCACHE_DBUG_ASSERT(read_length > 0);
keycache_pthread_mutex_lock(&THR_LOCK_keycache);
my_cache_r_requests++;
block=find_key_block(file, filepos, 0, &page_st);
if (block->status != BLOCK_ERROR && page_st != PAGE_READ)
{
/* The requested page is to be read into the block buffer */
#if !defined(SERIALIZED_READ_FROM_CACHE)
keycache_pthread_mutex_unlock(&THR_LOCK_keycache);
#endif
/* Copy data from buff */
if (!(read_length & 511))
bmove512(block->buffer+offset, buff, read_length);
else
memcpy(block->buffer+offset, buff, (size_t) read_length);
#if !defined(SERIALIZED_READ_FROM_CACHE)
keycache_pthread_mutex_lock(&THR_LOCK_keycache);
#endif
block->status= BLOCK_READ;
block->length= read_length+offset;
}
remove_reader(block);
/*
Link the block into the LRU chain
if it's the last submitted request for the block
*/
unreg_request(block,1);
keycache_pthread_mutex_unlock(&THR_LOCK_keycache);
if (block->status & BLOCK_ERROR)
DBUG_RETURN(1);
buff+=read_length;
filepos+=read_length;
offset=0;
} while ((length-= read_length));
}
DBUG_RETURN(0);
}
/*
Write a buffer into disk;
filepos must be a multiple of 'block_length', but it doesn't
......@@ -1303,7 +1386,7 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
keycache_pthread_mutex_lock(&THR_LOCK_keycache);
my_cache_w_requests++;
block=find_key_block(file, filepos, 1, &page_st);
if (page_st != PAGE_READ &&
if (block->status != BLOCK_ERROR && page_st != PAGE_READ &&
(offset || read_length < key_cache_block_size))
read_block(block,
offset + read_length >= key_cache_block_size?
......
......@@ -4,7 +4,7 @@ ALTER TABLE host type=MyISAM;
ALTER TABLE func type=MyISAM;
ALTER TABLE columns_priv type=MyISAM;
ALTER TABLE tables_priv type=MyISAM;
ALTER TABLE user change password password char(45) not null;
ALTER TABLE user change Password Password char(45) not null;
ALTER TABLE user add File_priv enum('N','Y') NOT NULL;
CREATE TABLE IF NOT EXISTS func (
name char(64) DEFAULT '' NOT NULL,
......
# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## Process this file with automake to create Makefile.in
EXTRA_DIST = client.c pack.c
# Don't update the files from bitkeeper
%::SCCS/s.%
......@@ -688,6 +688,72 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
}
/*
Preload pages of the index file for a table into the key cache.
*/
int ha_myisam::preload_keys(THD* thd, HA_CHECK_OPT *check_opt)
{
int error;
const char *errmsg;
ulonglong map= ~(ulonglong) 0;
TABLE_LIST *table_list= table->pos_in_table_list;
my_bool ignore_leaves= table_list->ignore_leaves;
DBUG_ENTER("ha_myisam::preload_keys");
/* Check validity of the index references */
if (table_list->use_index)
{
key_map kmap= get_key_map_from_key_list(table, table_list->use_index);
if (kmap == ~(key_map) 0)
{
errmsg= thd->net.last_error;
error= HA_ADMIN_FAILED;
goto err;
}
if (kmap)
map= kmap;
}
mi_extra(file, HA_EXTRA_PRELOAD_BUFFER_SIZE,
(void *) &thd->variables.preload_buff_size);
if ((error= mi_preload(file, map, ignore_leaves)))
{
switch (error) {
case HA_ERR_NON_UNIQUE_BLOCK_SIZE:
errmsg= "Indexes use different block sizes";
break;
case HA_ERR_OUT_OF_MEM:
errmsg= "Failed to allocate buffer";
break;
default:
char buf[ERRMSGSIZE+20];
my_snprintf(buf, ERRMSGSIZE,
"Failed to read from index file (errno: %d)", my_errno);
errmsg= buf;
}
error= HA_ADMIN_FAILED;
goto err;
}
DBUG_RETURN(HA_ADMIN_OK);
err:
{
MI_CHECK param;
myisamchk_init(&param);
param.thd= thd;
param.op_name= (char*)"preload_keys";
param.db_name= table->table_cache_key;
param.table_name= table->table_name;
param.testflag= 0;
mi_check_print_error(&param, errmsg);
DBUG_RETURN(error);
}
}
/*
Deactive all not unique index that can be recreated fast
......
......@@ -127,6 +127,7 @@ class ha_myisam: public handler
int optimize(THD* thd, HA_CHECK_OPT* check_opt);
int restore(THD* thd, HA_CHECK_OPT* check_opt);
int backup(THD* thd, HA_CHECK_OPT* check_opt);
int preload_keys(THD* thd, HA_CHECK_OPT* check_opt);
#ifdef HAVE_REPLICATION
int dump(THD* thd, int fd);
int net_read_dump(NET* net);
......
......@@ -620,6 +620,11 @@ int handler::analyze(THD* thd, HA_CHECK_OPT* check_opt)
return HA_ADMIN_NOT_IMPLEMENTED;
}
int handler::preload_keys(THD* thd, HA_CHECK_OPT* check_opt)
{
return HA_ADMIN_NOT_IMPLEMENTED;
}
/*
Read first row (only) from a table
This is never called for InnoDB or BDB tables, as these table types
......
......@@ -305,6 +305,7 @@ class handler :public Sql_alloc
virtual int optimize(THD* thd,HA_CHECK_OPT* check_opt);
virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt);
virtual int backup(THD* thd, HA_CHECK_OPT* check_opt);
virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt);
/*
restore assumes .frm file must exist, and that generate_table() has been
called; It will just copy the data file and run repair.
......
......@@ -39,7 +39,7 @@ Item::Item():
{
marker= 0;
maybe_null=null_value=with_sum_func=unsigned_flag=0;
coercibility=COER_IMPLICIT;
coercibility=COER_COERCIBLE;
name= 0;
decimals= 0; max_length= 0;
THD *thd= current_thd;
......
......@@ -813,6 +813,7 @@ String *Item_func_replace::val_str(String *str)
void Item_func_replace::fix_length_and_dec()
{
uint i;
max_length=args[0]->max_length;
int diff=(int) (args[2]->max_length - args[1]->max_length);
if (diff > 0 && args[1]->max_length)
......@@ -825,6 +826,20 @@ void Item_func_replace::fix_length_and_dec()
max_length=MAX_BLOB_WIDTH;
maybe_null=1;
}
set_charset(args[0]->charset(), args[0]->coercibility);
for (i=1; i<3; i++)
{
if (set_charset(charset(), coercibility,
args[i]->charset(), args[i]->coercibility))
{
my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0),
charset()->name,coercion_name(coercibility),
args[i]->charset()->name,coercion_name(args[i]->coercibility),
func_name());
break;
}
}
}
......@@ -1765,8 +1780,20 @@ void Item_func_make_set::split_sum_func(Item **ref_pointer_array,
void Item_func_make_set::fix_length_and_dec()
{
max_length=arg_count-1;
for (uint i=1 ; i < arg_count ; i++)
set_charset(args[0]->charset(), args[0]->coercibility);
for (uint i=0 ; i < arg_count ; i++)
{
max_length+=args[i]->max_length;
if (set_charset(charset(), coercibility,
args[i]->charset(), args[i]->coercibility))
{
my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0),
charset()->name,coercion_name(coercibility),
args[i]->charset()->name,coercion_name(args[i]->coercibility),
func_name());
break;
}
}
used_tables_cache|=item->used_tables();
const_item_cache&=item->const_item();
with_sum_func= with_sum_func || item->with_sum_func;
......@@ -1949,6 +1976,15 @@ String *Item_func_repeat::val_str(String *str)
void Item_func_rpad::fix_length_and_dec()
{
if (set_charset(args[0]->charset(), args[0]->coercibility,
args[2]->charset(), args[2]->coercibility))
{
my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0),
args[0]->charset()->name,coercion_name(args[0]->coercibility),
args[2]->charset()->name,coercion_name(args[2]->coercibility),
func_name());
}
if (args[1]->const_item())
{
uint32 length= (uint32) args[1]->val_int();
......@@ -2009,6 +2045,15 @@ String *Item_func_rpad::val_str(String *str)
void Item_func_lpad::fix_length_and_dec()
{
if (set_charset(args[0]->charset(), args[0]->coercibility,
args[2]->charset(), args[2]->coercibility))
{
my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0),
args[0]->charset()->name,coercion_name(args[0]->coercibility),
args[2]->charset()->name,coercion_name(args[2]->coercibility),
func_name());
}
if (args[1]->const_item())
{
uint32 length= (uint32) args[1]->val_int();
......@@ -2418,9 +2463,24 @@ String* Item_func_export_set::val_str(String* str)
void Item_func_export_set::fix_length_and_dec()
{
uint i;
uint length=max(args[1]->max_length,args[2]->max_length);
uint sep_length=(arg_count > 3 ? args[3]->max_length : 1);
max_length=length*64+sep_length*63;
set_charset(args[1]->charset(), args[1]->coercibility);
for (i=2 ; i < 4 && i < arg_count ; i++)
{
if (set_charset(charset(), coercibility,
args[i]->charset(), args[i]->coercibility))
{
my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0),
charset()->name,coercion_name(coercibility),
args[i]->charset()->name,coercion_name(args[i]->coercibility),
func_name());
break;
}
}
}
String* Item_func_inet_ntoa::val_str(String* str)
......@@ -2557,7 +2617,7 @@ String *Item_func_quote::val_str(String *str)
}
#ifdef HAVE_COMPRESS
#include "../zlib/zlib.h"
#include "zlib.h"
String *Item_func_compress::val_str(String *str)
{
......
......@@ -433,6 +433,7 @@ class Item_func_format :public Item_str_func
String *val_str(String *);
void fix_length_and_dec()
{
set_charset(default_charset());
max_length=args[0]->max_length+(args[0]->max_length-args[0]->decimals)/3;
}
const char *func_name() const { return "format"; }
......@@ -444,7 +445,11 @@ class Item_func_char :public Item_str_func
public:
Item_func_char(List<Item> &list) :Item_str_func(list) {}
String *val_str(String *);
void fix_length_and_dec() { maybe_null=0; max_length=arg_count; }
void fix_length_and_dec()
{
set_charset(default_charset());
maybe_null=0; max_length=arg_count;
}
const char *func_name() const { return "char"; }
};
......@@ -490,7 +495,11 @@ class Item_func_conv :public Item_str_func
Item_func_conv(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
const char *func_name() const { return "conv"; }
String *val_str(String *);
void fix_length_and_dec() { decimals=0; max_length=64; }
void fix_length_and_dec()
{
set_charset(default_charset());
decimals=0; max_length=64;
}
};
......@@ -501,7 +510,11 @@ class Item_func_hex :public Item_str_func
Item_func_hex(Item *a) :Item_str_func(a) {}
const char *func_name() const { return "hex"; }
String *val_str(String *);
void fix_length_and_dec() { decimals=0; max_length=args[0]->max_length*2; }
void fix_length_and_dec()
{
set_charset(default_charset());
decimals=0; max_length=args[0]->max_length*2;
}
};
......
......@@ -221,6 +221,7 @@ static SYMBOL symbols[] = {
{ "KILL", SYM(KILL_SYM),0,0},
{ "LAST", SYM(LAST_SYM),0,0},
{ "LEADING", SYM(LEADING),0,0},
{ "LEAVES", SYM(LEAVES),0,0},
{ "LEFT", SYM(LEFT),0,0},
{ "LEVEL", SYM(LEVEL_SYM),0,0},
{ "LIKE", SYM(LIKE),0,0},
......
......@@ -250,6 +250,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout);
/* Options to add_table_to_list() */
#define TL_OPTION_UPDATING 1
#define TL_OPTION_FORCE_INDEX 2
#define TL_OPTION_IGNORE_LEAVES 4
/* Some portable defines */
......@@ -402,6 +403,8 @@ int mysql_analyze_table(THD* thd, TABLE_LIST* table_list,
HA_CHECK_OPT* check_opt);
int mysql_optimize_table(THD* thd, TABLE_LIST* table_list,
HA_CHECK_OPT* check_opt);
int mysql_preload_keys(THD* thd, TABLE_LIST* table_list);
bool check_simple_select();
SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length);
......@@ -593,6 +596,8 @@ enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND,
extern const Item **not_found_item;
Item ** find_item_in_list(Item *item, List<Item> &items, uint *counter,
find_item_error_report_type report_error);
key_map get_key_map_from_key_list(TABLE *table,
List<String> *index_list);
bool insert_fields(THD *thd,TABLE_LIST *tables,
const char *db_name, const char *table_name,
List_iterator<Item> *it);
......
......@@ -3426,6 +3426,7 @@ enum options
OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT,
OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT,
OPT_OPEN_FILES_LIMIT,
OPT_PRELOAD_BUFFER_SIZE,
OPT_QUERY_CACHE_LIMIT, OPT_QUERY_CACHE_MIN_RES_UNIT, OPT_QUERY_CACHE_SIZE,
OPT_QUERY_CACHE_TYPE, OPT_RECORD_BUFFER,
OPT_RECORD_RND_BUFFER, OPT_RELAY_LOG_SPACE_LIMIT, OPT_RELAY_LOG_PURGE,
......@@ -4234,6 +4235,11 @@ replicating a LOAD DATA INFILE command.",
"If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of files.",
(gptr*) &open_files_limit, (gptr*) &open_files_limit, 0, GET_ULONG,
REQUIRED_ARG, 0, 0, 65535, 0, 1, 0},
{"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
"The size of the buffer that is allocated when preloading indexes",
(gptr*) &global_system_variables.preload_buff_size,
(gptr*) &max_system_variables.preload_buff_size, 0, GET_ULONG,
REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0},
#ifdef HAVE_QUERY_CACHE
{"query_cache_limit", OPT_QUERY_CACHE_LIMIT,
"Don't cache results that are bigger than this.",
......
......@@ -210,6 +210,8 @@ sys_var_thd_ulong sys_net_retry_count("net_retry_count",
&SV::net_retry_count,
fix_net_retry_count);
sys_var_thd_bool sys_new_mode("new", &SV::new_mode);
sys_var_thd_ulong sys_preload_buff_size("preload_buffer_size",
&SV::preload_buff_size);
sys_var_thd_ulong sys_read_buff_size("read_buffer_size",
&SV::read_buff_size);
sys_var_bool_ptr sys_readonly("read_only", &opt_readonly);
......@@ -423,6 +425,7 @@ sys_var *sys_variables[]=
&sys_net_wait_timeout,
&sys_net_write_timeout,
&sys_new_mode,
&sys_preload_buff_size,
&sys_pseudo_thread_id,
&sys_query_cache_size,
#ifdef HAVE_QUERY_CACHE
......@@ -602,6 +605,7 @@ struct show_var_st init_vars[]= {
{"log_error", (char*) log_error_file, SHOW_CHAR},
{"port", (char*) &mysqld_port, SHOW_INT},
{"protocol_version", (char*) &protocol_version, SHOW_INT},
{sys_preload_buff_size.name, (char*) &sys_preload_buff_size, SHOW_SYS},
{sys_pseudo_thread_id.name, (char*) &sys_pseudo_thread_id, SHOW_SYS},
{sys_read_buff_size.name, (char*) &sys_read_buff_size, SHOW_SYS},
{sys_readonly.name, (char*) &sys_readonly, SHOW_SYS},
......
......@@ -35,8 +35,6 @@ static int open_unireg_entry(THD *thd,TABLE *entry,const char *db,
const char *name, const char *alias);
static void free_cache_entry(TABLE *entry);
static void mysql_rm_tmp_tables(void);
static key_map get_key_map_from_key_list(TABLE *table,
List<String> *index_list);
extern "C" byte *table_cache_key(const byte *record,uint *length,
......@@ -2066,8 +2064,8 @@ bool setup_tables(TABLE_LIST *tables)
}
static key_map get_key_map_from_key_list(TABLE *table,
List<String> *index_list)
key_map get_key_map_from_key_list(TABLE *table,
List<String> *index_list)
{
key_map map=0;
List_iterator_fast<String> it(*index_list);
......
......@@ -366,6 +366,7 @@ struct system_variables
ulong net_retry_count;
ulong net_wait_timeout;
ulong net_write_timeout;
ulong preload_buff_size;
ulong query_cache_type;
ulong read_buff_size;
ulong read_rnd_buff_size;
......
......@@ -59,7 +59,7 @@ enum enum_sql_command {
SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_ALTER_DB,
SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT,
SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION,
SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK,
SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK, SQLCOM_PRELOAD_KEYS,
SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE,
SQLCOM_ROLLBACK, SQLCOM_COMMIT, SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP,
SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_CHANGE_MASTER,
......
......@@ -1881,6 +1881,15 @@ mysql_execute_command(THD *thd)
res = mysql_restore_table(thd, tables);
break;
}
case SQLCOM_PRELOAD_KEYS:
{
if (check_db_used(thd, tables) ||
check_access(thd, INDEX_ACL, tables->db, &tables->grant.privilege))
goto error;
res = mysql_preload_keys(thd, tables);
break;
}
#ifndef EMBEDDED_LIBRARY
case SQLCOM_CHANGE_MASTER:
......@@ -4107,6 +4116,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
ptr->lock_type= lock_type;
ptr->updating= test(table_options & TL_OPTION_UPDATING);
ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
ptr->derived= table->sel;
if (use_index)
ptr->use_index=(List<String> *) thd->memdup((gptr) use_index,
......
......@@ -1404,6 +1404,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
goto err;
continue;
}
table->table->pos_in_table_list= table;
if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify)
{
char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE];
......@@ -1559,6 +1560,28 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
}
/*
Preload specified indexes for a table into key cache
SYNOPSIS
mysql_preload_keys()
thd Thread object
tables Table list (one table only)
RETURN VALUES
0 ok
-1 error
*/
int mysql_preload_keys(THD* thd, TABLE_LIST* tables)
{
DBUG_ENTER("mysql_preload_keys");
DBUG_RETURN(mysql_admin_table(thd, tables, 0,
"preload_keys", TL_READ, 0, 0, 0,
&handler::preload_keys));
}
/*
Create a table identical to the specified table
......
......@@ -256,6 +256,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token KEY_SYM
%token LEADING
%token LEAST_SYM
%token LEAVES
%token LEVEL_SYM
%token LEX_HOSTNAME
%token LIKE
......@@ -579,7 +580,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
type int_type real_type order_dir opt_field_spec lock_option
udf_type if_exists opt_local opt_table_options table_options
table_option opt_if_not_exists opt_no_write_to_binlog opt_var_type opt_var_ident_type
delete_option opt_temporary all_or_any opt_distinct
delete_option opt_temporary all_or_any opt_distinct opt_ignore_leaves
%type <ulong_num>
ULONG_NUM raid_types merge_insert_types
......@@ -608,7 +609,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
key_alg opt_btree_or_rtree
%type <string_list>
key_usage_list
key_usage_list
%type <key_part>
key_part
......@@ -656,10 +657,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%type <NONE>
query verb_clause create change select do drop insert replace insert2
insert_values update delete truncate rename
show describe load alter optimize flush
show describe load alter optimize preload flush
reset purge begin commit rollback slave master_def master_defs
repair restore backup analyze check start
field_list field_list_item field_spec kill column_def key_def
preload_list preload_keys
select_item_list select_item values_list no_braces
opt_limit_clause delete_limit_clause fields opt_values values
procedure_list procedure_list2 procedure_item
......@@ -728,6 +730,7 @@ verb_clause:
| lock
| kill
| optimize
| preload
| purge
| rename
| repair
......@@ -1835,6 +1838,55 @@ table_to_table:
YYABORT;
};
preload:
LOAD INDEX INTO CACHE_SYM
{
LEX *lex=Lex;
lex->sql_command=SQLCOM_PRELOAD_KEYS;
}
preload_list
{}
;
preload_list:
preload_keys
| preload_list ',' preload_keys;
preload_keys:
table_ident preload_keys_spec opt_ignore_leaves
{
LEX *lex=Lex;
SELECT_LEX *sel= &lex->select_lex;
if (!sel->add_table_to_list(lex->thd, $1, NULL, $3,
TL_READ,
sel->get_use_index(),
(List<String> *)0))
YYABORT;
}
;
preload_keys_spec:
keys_or_index { Select->select_lex()->interval_list.empty(); }
preload_key_list_or_empty
{
LEX *lex=Lex;
SELECT_LEX *sel= &lex->select_lex;
sel->use_index= sel->interval_list;
sel->use_index_ptr= &sel->use_index;
}
;
preload_key_list_or_empty:
/* empty */
| '(' key_usage_list2 ')' {}
;
opt_ignore_leaves:
/* empty */
{ $$= 0; }
| IGNORE_SYM LEAVES { $$= TL_OPTION_IGNORE_LEAVES; }
;
/*
Select : retrieve data from table
*/
......@@ -4279,6 +4331,7 @@ keyword:
| INSERT_METHOD {}
| RELAY_THREAD {}
| LAST_SYM {}
| LEAVES {}
| LEVEL_SYM {}
| LINESTRING {}
| LOCAL_SYM {}
......
......@@ -181,6 +181,7 @@ typedef struct st_table_list
bool straight; /* optimize with prev table */
bool updating; /* for replicate-do/ignore table */
bool force_index; /* Prefer index over table scan */
bool ignore_leaves; /* Preload only non-leaf nodes */
} TABLE_LIST;
typedef struct st_changed_table_list
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment