mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Merge acurtis@bk-internal:/home/bk/mysql-5.1-new
into xiphis.org:/home/antony/work2/wl3201-final sql/ha_innodb.cc: Auto merged sql/sql_show.cc: Auto merged
This commit is contained in:
@ -257,6 +257,7 @@ EndProject
|
|||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysql_client_test", "tests\mysql_client_test.vcproj", "{DA224DAB-5006-42BE-BB77-16E8BE5326D5}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysql_client_test", "tests\mysql_client_test.vcproj", "{DA224DAB-5006-42BE-BB77-16E8BE5326D5}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
{26383276-4843-494B-8BE0-8936ED3EBAAB} = {26383276-4843-494B-8BE0-8936ED3EBAAB}
|
{26383276-4843-494B-8BE0-8936ED3EBAAB} = {26383276-4843-494B-8BE0-8936ED3EBAAB}
|
||||||
|
{44D9C7DC-6636-4B82-BD01-6876C64017DF} = {44D9C7DC-6636-4B82-BD01-6876C64017DF}
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysqlmanager", "server-tools\instance-manager\mysqlmanager.vcproj", "{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysqlmanager", "server-tools\instance-manager\mysqlmanager.vcproj", "{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}"
|
||||||
|
@ -3232,6 +3232,49 @@
|
|||||||
PreprocessorDefinitions=""/>
|
PreprocessorDefinitions=""/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="my_memmem.c">
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Max|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="TLS_DEBUG|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="TLS|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="my_messnc.c">
|
RelativePath="my_messnc.c">
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
|
@ -307,7 +307,7 @@ int main(int argc, char **argv)
|
|||||||
b_read= my_read(check_file, chf_buffer, sizeof(chf_buffer)-1, MYF(0));
|
b_read= my_read(check_file, chf_buffer, sizeof(chf_buffer)-1, MYF(0));
|
||||||
chf_buffer[b_read]= 0;
|
chf_buffer[b_read]= 0;
|
||||||
my_close(check_file, MYF(0));
|
my_close(check_file, MYF(0));
|
||||||
if (!strcmp(chf_buffer, VERSION))
|
if (!strcmp(chf_buffer, MYSQL_SERVER_VERSION))
|
||||||
{
|
{
|
||||||
if (opt_verbose)
|
if (opt_verbose)
|
||||||
puts("mysql_upgrade already done for this version");
|
puts("mysql_upgrade already done for this version");
|
||||||
|
@ -176,7 +176,7 @@ typedef struct my_charset_handler_st
|
|||||||
uint (*lengthsp)(struct charset_info_st *, const char *ptr, uint length);
|
uint (*lengthsp)(struct charset_info_st *, const char *ptr, uint length);
|
||||||
uint (*numcells)(struct charset_info_st *, const char *b, const char *e);
|
uint (*numcells)(struct charset_info_st *, const char *b, const char *e);
|
||||||
|
|
||||||
/* Unicode convertion */
|
/* Unicode conversion */
|
||||||
int (*mb_wc)(struct charset_info_st *cs,my_wc_t *wc,
|
int (*mb_wc)(struct charset_info_st *cs,my_wc_t *wc,
|
||||||
const unsigned char *s,const unsigned char *e);
|
const unsigned char *s,const unsigned char *e);
|
||||||
int (*wc_mb)(struct charset_info_st *cs,my_wc_t wc,
|
int (*wc_mb)(struct charset_info_st *cs,my_wc_t wc,
|
||||||
@ -186,7 +186,7 @@ typedef struct my_charset_handler_st
|
|||||||
int (*ctype)(struct charset_info_st *cs, int *ctype,
|
int (*ctype)(struct charset_info_st *cs, int *ctype,
|
||||||
const unsigned char *s, const unsigned char *e);
|
const unsigned char *s, const unsigned char *e);
|
||||||
|
|
||||||
/* Functions for case and sort convertion */
|
/* Functions for case and sort conversion */
|
||||||
void (*caseup_str)(struct charset_info_st *, char *);
|
void (*caseup_str)(struct charset_info_st *, char *);
|
||||||
void (*casedn_str)(struct charset_info_st *, char *);
|
void (*casedn_str)(struct charset_info_st *, char *);
|
||||||
uint (*caseup)(struct charset_info_st *, char *src, uint srclen,
|
uint (*caseup)(struct charset_info_st *, char *src, uint srclen,
|
||||||
@ -204,7 +204,7 @@ typedef struct my_charset_handler_st
|
|||||||
|
|
||||||
void (*fill)(struct charset_info_st *, char *to, uint len, int fill);
|
void (*fill)(struct charset_info_st *, char *to, uint len, int fill);
|
||||||
|
|
||||||
/* String-to-number convertion routines */
|
/* String-to-number conversion routines */
|
||||||
long (*strntol)(struct charset_info_st *, const char *s, uint l,
|
long (*strntol)(struct charset_info_st *, const char *s, uint l,
|
||||||
int base, char **e, int *err);
|
int base, char **e, int *err);
|
||||||
ulong (*strntoul)(struct charset_info_st *, const char *s, uint l,
|
ulong (*strntoul)(struct charset_info_st *, const char *s, uint l,
|
||||||
|
@ -601,6 +601,11 @@ extern char *_my_strndup(const byte *from, uint length,
|
|||||||
const char *sFile, uint uLine,
|
const char *sFile, uint uLine,
|
||||||
myf MyFlag);
|
myf MyFlag);
|
||||||
|
|
||||||
|
/* implemented in my_memmem.c */
|
||||||
|
extern void *my_memmem(const void *haystack, size_t haystacklen,
|
||||||
|
const void *needle, size_t needlelen);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
extern int my_access(const char *path, int amode);
|
extern int my_access(const char *path, int amode);
|
||||||
extern File my_sopen(const char *path, int oflag, int shflag, int pmode);
|
extern File my_sopen(const char *path, int oflag, int shflag, int pmode);
|
||||||
|
@ -50,6 +50,7 @@ KEY_COLUMN_USAGE
|
|||||||
PARTITIONS
|
PARTITIONS
|
||||||
PLUGINS
|
PLUGINS
|
||||||
PROCESSLIST
|
PROCESSLIST
|
||||||
|
REFERENTIAL_CONSTRAINTS
|
||||||
ROUTINES
|
ROUTINES
|
||||||
SCHEMATA
|
SCHEMATA
|
||||||
SCHEMA_PRIVILEGES
|
SCHEMA_PRIVILEGES
|
||||||
@ -745,7 +746,7 @@ CREATE TABLE t_crashme ( f1 BIGINT);
|
|||||||
CREATE VIEW a1 (t_CRASHME) AS SELECT f1 FROM t_crashme GROUP BY f1;
|
CREATE VIEW a1 (t_CRASHME) AS SELECT f1 FROM t_crashme GROUP BY f1;
|
||||||
CREATE VIEW a2 AS SELECT t_CRASHME FROM a1;
|
CREATE VIEW a2 AS SELECT t_CRASHME FROM a1;
|
||||||
count(*)
|
count(*)
|
||||||
112
|
113
|
||||||
drop view a2, a1;
|
drop view a2, a1;
|
||||||
drop table t_crashme;
|
drop table t_crashme;
|
||||||
select table_schema,table_name, column_name from
|
select table_schema,table_name, column_name from
|
||||||
@ -759,6 +760,7 @@ information_schema PARTITIONS PARTITION_EXPRESSION
|
|||||||
information_schema PARTITIONS SUBPARTITION_EXPRESSION
|
information_schema PARTITIONS SUBPARTITION_EXPRESSION
|
||||||
information_schema PARTITIONS PARTITION_DESCRIPTION
|
information_schema PARTITIONS PARTITION_DESCRIPTION
|
||||||
information_schema PLUGINS PLUGIN_DESCRIPTION
|
information_schema PLUGINS PLUGIN_DESCRIPTION
|
||||||
|
information_schema PROCESSLIST INFO
|
||||||
information_schema ROUTINES ROUTINE_DEFINITION
|
information_schema ROUTINES ROUTINE_DEFINITION
|
||||||
information_schema ROUTINES SQL_MODE
|
information_schema ROUTINES SQL_MODE
|
||||||
information_schema TRIGGERS ACTION_CONDITION
|
information_schema TRIGGERS ACTION_CONDITION
|
||||||
@ -832,6 +834,7 @@ COLUMN_PRIVILEGES TABLE_NAME select
|
|||||||
FILES TABLE_NAME select
|
FILES TABLE_NAME select
|
||||||
KEY_COLUMN_USAGE TABLE_NAME select
|
KEY_COLUMN_USAGE TABLE_NAME select
|
||||||
PARTITIONS TABLE_NAME select
|
PARTITIONS TABLE_NAME select
|
||||||
|
REFERENTIAL_CONSTRAINTS TABLE_NAME select
|
||||||
STATISTICS TABLE_NAME select
|
STATISTICS TABLE_NAME select
|
||||||
TABLES TABLE_NAME select
|
TABLES TABLE_NAME select
|
||||||
TABLE_CONSTRAINTS TABLE_NAME select
|
TABLE_CONSTRAINTS TABLE_NAME select
|
||||||
@ -843,7 +846,7 @@ flush privileges;
|
|||||||
SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA;
|
SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA;
|
||||||
table_schema count(*)
|
table_schema count(*)
|
||||||
cluster 1
|
cluster 1
|
||||||
information_schema 22
|
information_schema 23
|
||||||
mysql 21
|
mysql 21
|
||||||
create table t1 (i int, j int);
|
create table t1 (i int, j int);
|
||||||
create trigger trg1 before insert on t1 for each row
|
create trigger trg1 before insert on t1 for each row
|
||||||
|
@ -13,6 +13,7 @@ KEY_COLUMN_USAGE
|
|||||||
PARTITIONS
|
PARTITIONS
|
||||||
PLUGINS
|
PLUGINS
|
||||||
PROCESSLIST
|
PROCESSLIST
|
||||||
|
REFERENTIAL_CONSTRAINTS
|
||||||
ROUTINES
|
ROUTINES
|
||||||
SCHEMATA
|
SCHEMATA
|
||||||
SCHEMA_PRIVILEGES
|
SCHEMA_PRIVILEGES
|
||||||
|
@ -25,3 +25,34 @@ NULL test PRIMARY NULL test t3 id 1 NULL NULL NULL NULL
|
|||||||
NULL test t3_ibfk_1 NULL test t3 id 1 1 test t2 t1_id
|
NULL test t3_ibfk_1 NULL test t3 id 1 1 test t2 t1_id
|
||||||
NULL test t3_ibfk_1 NULL test t3 t2_id 2 2 test t2 id
|
NULL test t3_ibfk_1 NULL test t3 t2_id 2 2 test t2 id
|
||||||
drop table t3, t2, t1;
|
drop table t3, t2, t1;
|
||||||
|
CREATE TABLE t1(a1 INT NOT NULL, a2 INT NOT NULL,
|
||||||
|
PRIMARY KEY(a1, a2)) ENGINE=INNODB;
|
||||||
|
CREATE TABLE t2(b1 INT, b2 INT, INDEX (b1, b2),
|
||||||
|
CONSTRAINT A1
|
||||||
|
FOREIGN KEY (b1, b2) REFERENCES t1(a1, a2)
|
||||||
|
ON UPDATE CASCADE ON DELETE NO ACTION) ENGINE=INNODB;
|
||||||
|
CREATE TABLE t3(b1 INT, b2 INT, INDEX (b1, b2),
|
||||||
|
CONSTRAINT A2
|
||||||
|
FOREIGN KEY (b1, b2) REFERENCES t2(b1, b2)
|
||||||
|
ON UPDATE SET NULL ON DELETE RESTRICT) ENGINE=INNODB;
|
||||||
|
CREATE TABLE t4(b1 INT, b2 INT, INDEX (b1, b2),
|
||||||
|
CONSTRAINT A3
|
||||||
|
FOREIGN KEY (b1, b2) REFERENCES t3(b1, b2)
|
||||||
|
ON UPDATE NO ACTION ON DELETE SET NULL) ENGINE=INNODB;
|
||||||
|
CREATE TABLE t5(b1 INT, b2 INT, INDEX (b1, b2),
|
||||||
|
CONSTRAINT A4
|
||||||
|
FOREIGN KEY (b1, b2) REFERENCES t4(b1, b2)
|
||||||
|
ON UPDATE RESTRICT ON DELETE CASCADE) ENGINE=INNODB;
|
||||||
|
select a.CONSTRAINT_SCHEMA, b.TABLE_NAME, CONSTRAINT_TYPE,
|
||||||
|
b.CONSTRAINT_NAME, UNIQUE_CONSTRAINT_SCHEMA, UNIQUE_CONSTRAINT_NAME,
|
||||||
|
MATCH_OPTION, UPDATE_RULE, DELETE_RULE
|
||||||
|
from information_schema.TABLE_CONSTRAINTS a,
|
||||||
|
information_schema.REFERENTIAL_CONSTRAINTS b
|
||||||
|
where a.CONSTRAINT_SCHEMA = 'test' and a.CONSTRAINT_SCHEMA = b.CONSTRAINT_SCHEMA and
|
||||||
|
a.CONSTRAINT_NAME = b.CONSTRAINT_NAME;
|
||||||
|
CONSTRAINT_SCHEMA TABLE_NAME CONSTRAINT_TYPE CONSTRAINT_NAME UNIQUE_CONSTRAINT_SCHEMA UNIQUE_CONSTRAINT_NAME MATCH_OPTION UPDATE_RULE DELETE_RULE
|
||||||
|
test t2 FOREIGN KEY A1 test t1 NONE CASCADE NO ACTION
|
||||||
|
test t3 FOREIGN KEY A2 test t2 NONE SET NULL RESTRICT
|
||||||
|
test t4 FOREIGN KEY A3 test t3 NONE NO ACTION SET NULL
|
||||||
|
test t5 FOREIGN KEY A4 test t4 NONE RESTRICT CASCADE
|
||||||
|
drop tables t5, t4, t3, t2, t1;
|
||||||
|
@ -1056,3 +1056,104 @@ a b
|
|||||||
1 9
|
1 9
|
||||||
3 7
|
3 7
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (a int);
|
||||||
|
create table t2 like t1;
|
||||||
|
create table t3 like t2;
|
||||||
|
prepare stmt from "repair table t1";
|
||||||
|
execute stmt;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 repair status OK
|
||||||
|
execute stmt;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 repair status OK
|
||||||
|
prepare stmt from "optimize table t1";
|
||||||
|
execute stmt;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 optimize status OK
|
||||||
|
execute stmt;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 optimize status Table is already up to date
|
||||||
|
prepare stmt from "analyze table t1";
|
||||||
|
execute stmt;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze status Table is already up to date
|
||||||
|
execute stmt;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze status Table is already up to date
|
||||||
|
prepare stmt from "repair table t1, t2, t3";
|
||||||
|
execute stmt;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 repair status OK
|
||||||
|
test.t2 repair status OK
|
||||||
|
test.t3 repair status OK
|
||||||
|
execute stmt;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 repair status OK
|
||||||
|
test.t2 repair status OK
|
||||||
|
test.t3 repair status OK
|
||||||
|
prepare stmt from "optimize table t1, t2, t3";
|
||||||
|
execute stmt;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 optimize status OK
|
||||||
|
test.t2 optimize status OK
|
||||||
|
test.t3 optimize status OK
|
||||||
|
execute stmt;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 optimize status Table is already up to date
|
||||||
|
test.t2 optimize status Table is already up to date
|
||||||
|
test.t3 optimize status Table is already up to date
|
||||||
|
prepare stmt from "analyze table t1, t2, t3";
|
||||||
|
execute stmt;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze status Table is already up to date
|
||||||
|
test.t2 analyze status Table is already up to date
|
||||||
|
test.t3 analyze status Table is already up to date
|
||||||
|
execute stmt;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze status Table is already up to date
|
||||||
|
test.t2 analyze status Table is already up to date
|
||||||
|
test.t3 analyze status Table is already up to date
|
||||||
|
prepare stmt from "repair table t1, t4, t3";
|
||||||
|
execute stmt;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 repair status OK
|
||||||
|
test.t4 repair error Table 'test.t4' doesn't exist
|
||||||
|
test.t3 repair status OK
|
||||||
|
Warnings:
|
||||||
|
Error 1146 Table 'test.t4' doesn't exist
|
||||||
|
execute stmt;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 repair status OK
|
||||||
|
test.t4 repair error Table 'test.t4' doesn't exist
|
||||||
|
test.t3 repair status OK
|
||||||
|
Warnings:
|
||||||
|
Error 1146 Table 'test.t4' doesn't exist
|
||||||
|
prepare stmt from "optimize table t1, t3, t4";
|
||||||
|
execute stmt;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 optimize status OK
|
||||||
|
test.t3 optimize status OK
|
||||||
|
test.t4 optimize error Table 'test.t4' doesn't exist
|
||||||
|
Warnings:
|
||||||
|
Error 1146 Table 'test.t4' doesn't exist
|
||||||
|
execute stmt;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 optimize status Table is already up to date
|
||||||
|
test.t3 optimize status Table is already up to date
|
||||||
|
test.t4 optimize error Table 'test.t4' doesn't exist
|
||||||
|
Warnings:
|
||||||
|
Error 1146 Table 'test.t4' doesn't exist
|
||||||
|
prepare stmt from "analyze table t4, t1";
|
||||||
|
execute stmt;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t4 analyze error Table 'test.t4' doesn't exist
|
||||||
|
test.t1 analyze status Table is already up to date
|
||||||
|
Warnings:
|
||||||
|
Error 1146 Table 'test.t4' doesn't exist
|
||||||
|
execute stmt;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t4 analyze error Table 'test.t4' doesn't exist
|
||||||
|
test.t1 analyze status Table is already up to date
|
||||||
|
Warnings:
|
||||||
|
Error 1146 Table 'test.t4' doesn't exist
|
||||||
|
deallocate prepare stmt;
|
||||||
|
@ -410,13 +410,10 @@ ERROR HY000: This command is not supported in the prepared statement protocol ye
|
|||||||
prepare stmt1 from ' select * into outfile ''data.txt'' from t1 ';
|
prepare stmt1 from ' select * into outfile ''data.txt'' from t1 ';
|
||||||
execute stmt1 ;
|
execute stmt1 ;
|
||||||
prepare stmt1 from ' optimize table t1 ' ;
|
prepare stmt1 from ' optimize table t1 ' ;
|
||||||
ERROR HY000: This command is not supported in the prepared statement protocol yet
|
|
||||||
prepare stmt1 from ' analyze table t1 ' ;
|
prepare stmt1 from ' analyze table t1 ' ;
|
||||||
ERROR HY000: This command is not supported in the prepared statement protocol yet
|
|
||||||
prepare stmt1 from ' checksum table t1 ' ;
|
prepare stmt1 from ' checksum table t1 ' ;
|
||||||
ERROR HY000: This command is not supported in the prepared statement protocol yet
|
ERROR HY000: This command is not supported in the prepared statement protocol yet
|
||||||
prepare stmt1 from ' repair table t1 ' ;
|
prepare stmt1 from ' repair table t1 ' ;
|
||||||
ERROR HY000: This command is not supported in the prepared statement protocol yet
|
|
||||||
prepare stmt1 from ' restore table t1 from ''data.txt'' ' ;
|
prepare stmt1 from ' restore table t1 from ''data.txt'' ' ;
|
||||||
ERROR HY000: This command is not supported in the prepared statement protocol yet
|
ERROR HY000: This command is not supported in the prepared statement protocol yet
|
||||||
prepare stmt1 from ' handler t1 open ';
|
prepare stmt1 from ' handler t1 open ';
|
||||||
|
@ -286,12 +286,12 @@ id stmt_text status
|
|||||||
1 select 1 supported
|
1 select 1 supported
|
||||||
2 flush tables not supported
|
2 flush tables not supported
|
||||||
3 handler t1 open as ha not supported
|
3 handler t1 open as ha not supported
|
||||||
4 analyze table t1 not supported
|
4 analyze table t1 supported
|
||||||
5 check table t1 not supported
|
5 check table t1 not supported
|
||||||
6 checksum table t1 not supported
|
6 checksum table t1 not supported
|
||||||
7 check table t1 not supported
|
7 check table t1 not supported
|
||||||
8 optimize table t1 not supported
|
8 optimize table t1 supported
|
||||||
9 repair table t1 not supported
|
9 repair table t1 supported
|
||||||
10 describe extended select * from t1 supported
|
10 describe extended select * from t1 supported
|
||||||
11 help help not supported
|
11 help help not supported
|
||||||
12 show databases supported
|
12 show databases supported
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
drop table if exists t1, t2;
|
drop table if exists t1, t2;
|
||||||
|
drop function if exists f1;
|
||||||
create table t1 (ts timestamp);
|
create table t1 (ts timestamp);
|
||||||
set time_zone='+00:00';
|
set time_zone='+00:00';
|
||||||
select unix_timestamp(utc_timestamp())-unix_timestamp(current_timestamp());
|
select unix_timestamp(utc_timestamp())-unix_timestamp(current_timestamp());
|
||||||
@ -268,3 +269,17 @@ select * from t1;
|
|||||||
convert_tz(NULL, NULL, NULL)
|
convert_tz(NULL, NULL, NULL)
|
||||||
NULL
|
NULL
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (ldt datetime, udt datetime);
|
||||||
|
create function f1(i datetime) returns datetime
|
||||||
|
return convert_tz(i, 'UTC', 'Europe/Moscow');
|
||||||
|
create trigger t1_bi before insert on t1 for each row
|
||||||
|
set new.udt:= convert_tz(new.ldt, 'Europe/Moscow', 'UTC');
|
||||||
|
insert into t1 (ldt) values ('2006-04-19 16:30:00');
|
||||||
|
select * from t1;
|
||||||
|
ldt udt
|
||||||
|
2006-04-19 16:30:00 2006-04-19 12:30:00
|
||||||
|
select ldt, f1(udt) as ldt2 from t1;
|
||||||
|
ldt ldt2
|
||||||
|
2006-04-19 16:30:00 2006-04-19 16:30:00
|
||||||
|
drop table t1;
|
||||||
|
drop function f1;
|
||||||
|
@ -665,3 +665,12 @@ CALL p2();
|
|||||||
EXTRACTVALUE(p,'/Ñ/r')
|
EXTRACTVALUE(p,'/Ñ/r')
|
||||||
A
|
A
|
||||||
DROP PROCEDURE p2;
|
DROP PROCEDURE p2;
|
||||||
|
select extractValue('<ns:element xmlns:ns="myns"/>','count(ns:element)');
|
||||||
|
extractValue('<ns:element xmlns:ns="myns"/>','count(ns:element)')
|
||||||
|
1
|
||||||
|
select extractValue('<ns:element xmlns:ns="myns">a</ns:element>','/ns:element');
|
||||||
|
extractValue('<ns:element xmlns:ns="myns">a</ns:element>','/ns:element')
|
||||||
|
a
|
||||||
|
select extractValue('<ns:element xmlns:ns="myns">a</ns:element>','/ns:element/@xmlns:ns');
|
||||||
|
extractValue('<ns:element xmlns:ns="myns">a</ns:element>','/ns:element/@xmlns:ns')
|
||||||
|
myns
|
||||||
|
@ -47,7 +47,7 @@ select cast('1a' as signed);
|
|||||||
select cast('' as signed);
|
select cast('' as signed);
|
||||||
|
|
||||||
#
|
#
|
||||||
# Character set convertion
|
# Character set conversion
|
||||||
#
|
#
|
||||||
set names binary;
|
set names binary;
|
||||||
select cast(_latin1'test' as char character set latin2);
|
select cast(_latin1'test' as char character set latin2);
|
||||||
|
@ -21,3 +21,35 @@ select * from information_schema.KEY_COLUMN_USAGE where
|
|||||||
TABLE_SCHEMA= "test";
|
TABLE_SCHEMA= "test";
|
||||||
|
|
||||||
drop table t3, t2, t1;
|
drop table t3, t2, t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test for REFERENTIAL_CONSTRAINTS table
|
||||||
|
#
|
||||||
|
CREATE TABLE t1(a1 INT NOT NULL, a2 INT NOT NULL,
|
||||||
|
PRIMARY KEY(a1, a2)) ENGINE=INNODB;
|
||||||
|
CREATE TABLE t2(b1 INT, b2 INT, INDEX (b1, b2),
|
||||||
|
CONSTRAINT A1
|
||||||
|
FOREIGN KEY (b1, b2) REFERENCES t1(a1, a2)
|
||||||
|
ON UPDATE CASCADE ON DELETE NO ACTION) ENGINE=INNODB;
|
||||||
|
CREATE TABLE t3(b1 INT, b2 INT, INDEX (b1, b2),
|
||||||
|
CONSTRAINT A2
|
||||||
|
FOREIGN KEY (b1, b2) REFERENCES t2(b1, b2)
|
||||||
|
ON UPDATE SET NULL ON DELETE RESTRICT) ENGINE=INNODB;
|
||||||
|
CREATE TABLE t4(b1 INT, b2 INT, INDEX (b1, b2),
|
||||||
|
CONSTRAINT A3
|
||||||
|
FOREIGN KEY (b1, b2) REFERENCES t3(b1, b2)
|
||||||
|
ON UPDATE NO ACTION ON DELETE SET NULL) ENGINE=INNODB;
|
||||||
|
CREATE TABLE t5(b1 INT, b2 INT, INDEX (b1, b2),
|
||||||
|
CONSTRAINT A4
|
||||||
|
FOREIGN KEY (b1, b2) REFERENCES t4(b1, b2)
|
||||||
|
ON UPDATE RESTRICT ON DELETE CASCADE) ENGINE=INNODB;
|
||||||
|
|
||||||
|
|
||||||
|
select a.CONSTRAINT_SCHEMA, b.TABLE_NAME, CONSTRAINT_TYPE,
|
||||||
|
b.CONSTRAINT_NAME, UNIQUE_CONSTRAINT_SCHEMA, UNIQUE_CONSTRAINT_NAME,
|
||||||
|
MATCH_OPTION, UPDATE_RULE, DELETE_RULE
|
||||||
|
from information_schema.TABLE_CONSTRAINTS a,
|
||||||
|
information_schema.REFERENTIAL_CONSTRAINTS b
|
||||||
|
where a.CONSTRAINT_SCHEMA = 'test' and a.CONSTRAINT_SCHEMA = b.CONSTRAINT_SCHEMA and
|
||||||
|
a.CONSTRAINT_NAME = b.CONSTRAINT_NAME;
|
||||||
|
drop tables t5, t4, t3, t2, t1;
|
||||||
|
1
mysql-test/t/mysql_client_test-master.opt
Normal file
1
mysql-test/t/mysql_client_test-master.opt
Normal file
@ -0,0 +1 @@
|
|||||||
|
--log --log-output=FILE
|
@ -1110,4 +1110,40 @@ select * from t1 order by 1+1;
|
|||||||
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#19308 "REPAIR/OPTIMIZE/ANALYZE supported in SP but not in PS".
|
||||||
|
# Add test coverage for the added commands.
|
||||||
|
#
|
||||||
|
create table t1 (a int);
|
||||||
|
create table t2 like t1;
|
||||||
|
create table t3 like t2;
|
||||||
|
prepare stmt from "repair table t1";
|
||||||
|
execute stmt;
|
||||||
|
execute stmt;
|
||||||
|
prepare stmt from "optimize table t1";
|
||||||
|
execute stmt;
|
||||||
|
execute stmt;
|
||||||
|
prepare stmt from "analyze table t1";
|
||||||
|
execute stmt;
|
||||||
|
execute stmt;
|
||||||
|
prepare stmt from "repair table t1, t2, t3";
|
||||||
|
execute stmt;
|
||||||
|
execute stmt;
|
||||||
|
prepare stmt from "optimize table t1, t2, t3";
|
||||||
|
execute stmt;
|
||||||
|
execute stmt;
|
||||||
|
prepare stmt from "analyze table t1, t2, t3";
|
||||||
|
execute stmt;
|
||||||
|
execute stmt;
|
||||||
|
prepare stmt from "repair table t1, t4, t3";
|
||||||
|
execute stmt;
|
||||||
|
execute stmt;
|
||||||
|
prepare stmt from "optimize table t1, t3, t4";
|
||||||
|
execute stmt;
|
||||||
|
execute stmt;
|
||||||
|
prepare stmt from "analyze table t4, t1";
|
||||||
|
execute stmt;
|
||||||
|
execute stmt;
|
||||||
|
deallocate prepare stmt;
|
||||||
|
|
||||||
# End of 5.0 tests
|
# End of 5.0 tests
|
||||||
|
@ -456,13 +456,10 @@ into table t1 fields terminated by ''\t'' ';
|
|||||||
prepare stmt1 from ' select * into outfile ''data.txt'' from t1 ';
|
prepare stmt1 from ' select * into outfile ''data.txt'' from t1 ';
|
||||||
execute stmt1 ;
|
execute stmt1 ;
|
||||||
##
|
##
|
||||||
--error 1295
|
|
||||||
prepare stmt1 from ' optimize table t1 ' ;
|
prepare stmt1 from ' optimize table t1 ' ;
|
||||||
--error 1295
|
|
||||||
prepare stmt1 from ' analyze table t1 ' ;
|
prepare stmt1 from ' analyze table t1 ' ;
|
||||||
--error 1295
|
--error 1295
|
||||||
prepare stmt1 from ' checksum table t1 ' ;
|
prepare stmt1 from ' checksum table t1 ' ;
|
||||||
--error 1295
|
|
||||||
prepare stmt1 from ' repair table t1 ' ;
|
prepare stmt1 from ' repair table t1 ' ;
|
||||||
--error 1295
|
--error 1295
|
||||||
prepare stmt1 from ' restore table t1 from ''data.txt'' ' ;
|
prepare stmt1 from ' restore table t1 from ''data.txt'' ' ;
|
||||||
|
@ -207,7 +207,7 @@ show status like "Qcache_queries_in_cache";
|
|||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Charset convertion (cp1251_koi8 always present)
|
# Charset conversion (cp1251_koi8 always present)
|
||||||
#
|
#
|
||||||
create table t1 (a char(1) not null collate koi8r_general_ci);
|
create table t1 (a char(1) not null collate koi8r_general_ci);
|
||||||
insert into t1 values(_koi8r"<22>");
|
insert into t1 values(_koi8r"<22>");
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
# Preparing playground
|
# Preparing playground
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
drop table if exists t1, t2;
|
drop table if exists t1, t2;
|
||||||
|
drop function if exists f1;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
|
||||||
|
|
||||||
@ -222,3 +223,22 @@ select * from t1;
|
|||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test for bug #11081 "Using a CONVERT_TZ function in a stored function
|
||||||
|
# or trigger fails".
|
||||||
|
#
|
||||||
|
create table t1 (ldt datetime, udt datetime);
|
||||||
|
create function f1(i datetime) returns datetime
|
||||||
|
return convert_tz(i, 'UTC', 'Europe/Moscow');
|
||||||
|
create trigger t1_bi before insert on t1 for each row
|
||||||
|
set new.udt:= convert_tz(new.ldt, 'Europe/Moscow', 'UTC');
|
||||||
|
# This should work without errors
|
||||||
|
insert into t1 (ldt) values ('2006-04-19 16:30:00');
|
||||||
|
select * from t1;
|
||||||
|
# This should work without errors as well
|
||||||
|
select ldt, f1(udt) as ldt2 from t1;
|
||||||
|
drop table t1;
|
||||||
|
drop function f1;
|
||||||
|
|
||||||
|
# End of 5.0 tests
|
||||||
|
@ -335,3 +335,11 @@ END//
|
|||||||
DELIMITER ;//
|
DELIMITER ;//
|
||||||
CALL p2();
|
CALL p2();
|
||||||
DROP PROCEDURE p2;
|
DROP PROCEDURE p2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#18170: XML: ExtractValue():
|
||||||
|
# XPath expression can't use QNames (colon in names)
|
||||||
|
#
|
||||||
|
select extractValue('<ns:element xmlns:ns="myns"/>','count(ns:element)');
|
||||||
|
select extractValue('<ns:element xmlns:ns="myns">a</ns:element>','/ns:element');
|
||||||
|
select extractValue('<ns:element xmlns:ns="myns">a</ns:element>','/ns:element/@xmlns:ns');
|
||||||
|
@ -53,6 +53,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
|
|||||||
charset.c charset-def.c my_bitmap.c my_bit.c md5.c \
|
charset.c charset-def.c my_bitmap.c my_bit.c md5.c \
|
||||||
my_gethostbyname.c rijndael.c my_aes.c sha1.c \
|
my_gethostbyname.c rijndael.c my_aes.c sha1.c \
|
||||||
my_handler.c my_netware.c my_largepage.c \
|
my_handler.c my_netware.c my_largepage.c \
|
||||||
|
my_memmem.c \
|
||||||
my_windac.c my_access.c base64.c
|
my_windac.c my_access.c base64.c
|
||||||
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
|
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
|
||||||
thr_mutex.c thr_rwlock.c \
|
thr_mutex.c thr_rwlock.c \
|
||||||
|
@ -26,4 +26,4 @@ ADD_LIBRARY(mysys array.c charset-def.c charset.c checksum.c default.c default_m
|
|||||||
my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c
|
my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c
|
||||||
my_windac.c my_winsem.c my_winthread.c my_write.c ptr_cmp.c queues.c
|
my_windac.c my_winsem.c my_winthread.c my_write.c ptr_cmp.c queues.c
|
||||||
rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c
|
rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c
|
||||||
thr_rwlock.c tree.c typelib.c my_vle.c base64.c)
|
thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c)
|
||||||
|
@ -252,37 +252,89 @@ uint my_b_printf(IO_CACHE *info, const char* fmt, ...)
|
|||||||
uint my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args)
|
uint my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args)
|
||||||
{
|
{
|
||||||
uint out_length=0;
|
uint out_length=0;
|
||||||
|
uint minimum_width; /* as yet unimplemented */
|
||||||
|
uint minimum_width_sign;
|
||||||
|
uint precision; /* as yet unimplemented for anything but %b */
|
||||||
|
|
||||||
for (; *fmt ; fmt++)
|
/*
|
||||||
|
Store the location of the beginning of a format directive, for the
|
||||||
|
case where we learn we shouldn't have been parsing a format string
|
||||||
|
at all, and we don't want to lose the flag/precision/width/size
|
||||||
|
information.
|
||||||
|
*/
|
||||||
|
const char* backtrack;
|
||||||
|
|
||||||
|
for (; *fmt != '\0'; fmt++)
|
||||||
{
|
{
|
||||||
if (*fmt++ != '%')
|
/* Copy everything until '%' or end of string */
|
||||||
|
const char *start=fmt;
|
||||||
|
uint length;
|
||||||
|
|
||||||
|
for (; (*fmt != '\0') && (*fmt != '%'); fmt++) ;
|
||||||
|
|
||||||
|
length= (uint) (fmt - start);
|
||||||
|
out_length+=length;
|
||||||
|
if (my_b_write(info, start, length))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (*fmt == '\0') /* End of format */
|
||||||
{
|
{
|
||||||
/* Copy everything until '%' or end of string */
|
return out_length;
|
||||||
const char *start=fmt-1;
|
|
||||||
uint length;
|
|
||||||
for (; *fmt && *fmt != '%' ; fmt++ ) ;
|
|
||||||
length= (uint) (fmt - start);
|
|
||||||
out_length+=length;
|
|
||||||
if (my_b_write(info, start, length))
|
|
||||||
goto err;
|
|
||||||
if (!*fmt) /* End of format */
|
|
||||||
{
|
|
||||||
return out_length;
|
|
||||||
}
|
|
||||||
fmt++;
|
|
||||||
/* Found one '%' */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
By this point, *fmt must be a percent; Keep track of this location and
|
||||||
|
skip over the percent character.
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(*fmt == '%');
|
||||||
|
backtrack= fmt;
|
||||||
|
fmt++;
|
||||||
|
|
||||||
|
minimum_width= 0;
|
||||||
|
precision= 0;
|
||||||
|
minimum_width_sign= 1;
|
||||||
/* Skip if max size is used (to be compatible with printf) */
|
/* Skip if max size is used (to be compatible with printf) */
|
||||||
while (my_isdigit(&my_charset_latin1, *fmt) || *fmt == '.' || *fmt == '-')
|
while (*fmt == '-') { fmt++; minimum_width_sign= -1; }
|
||||||
|
if (*fmt == '*') {
|
||||||
|
precision= (int) va_arg(args, int);
|
||||||
fmt++;
|
fmt++;
|
||||||
|
} else {
|
||||||
|
while (my_isdigit(&my_charset_latin1, *fmt)) {
|
||||||
|
minimum_width=(minimum_width * 10) + (*fmt - '0');
|
||||||
|
fmt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
minimum_width*= minimum_width_sign;
|
||||||
|
|
||||||
|
if (*fmt == '.') {
|
||||||
|
fmt++;
|
||||||
|
if (*fmt == '*') {
|
||||||
|
precision= (int) va_arg(args, int);
|
||||||
|
fmt++;
|
||||||
|
} else {
|
||||||
|
while (my_isdigit(&my_charset_latin1, *fmt)) {
|
||||||
|
precision=(precision * 10) + (*fmt - '0');
|
||||||
|
fmt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (*fmt == 's') /* String parameter */
|
if (*fmt == 's') /* String parameter */
|
||||||
{
|
{
|
||||||
reg2 char *par = va_arg(args, char *);
|
reg2 char *par = va_arg(args, char *);
|
||||||
uint length = (uint) strlen(par);
|
uint length = (uint) strlen(par);
|
||||||
|
/* TODO: implement minimum width and precision */
|
||||||
out_length+=length;
|
out_length+=length;
|
||||||
if (my_b_write(info, par, length))
|
if (my_b_write(info, par, length))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
else if (*fmt == 'b') /* Sized buffer parameter, only precision makes sense */
|
||||||
|
{
|
||||||
|
char *par = va_arg(args, char *);
|
||||||
|
out_length+= precision;
|
||||||
|
if (my_b_write(info, par, precision))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
|
else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
|
||||||
{
|
{
|
||||||
register int iarg;
|
register int iarg;
|
||||||
@ -317,9 +369,9 @@ uint my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* %% or unknown code */
|
/* %% or unknown code */
|
||||||
if (my_b_write(info, "%", 1))
|
if (my_b_write(info, backtrack, fmt-backtrack))
|
||||||
goto err;
|
goto err;
|
||||||
out_length++;
|
out_length+= fmt-backtrack;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return out_length;
|
return out_length;
|
||||||
|
66
mysys/my_memmem.c
Normal file
66
mysys/my_memmem.c
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#include "my_base.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
my_memmem, port of a GNU extension.
|
||||||
|
|
||||||
|
Returns a pointer to the beginning of the substring, needle, or NULL if the
|
||||||
|
substring is not found in haystack.
|
||||||
|
*/
|
||||||
|
void *my_memmem(const void *haystack, size_t haystacklen,
|
||||||
|
const void *needle, size_t needlelen)
|
||||||
|
{
|
||||||
|
const unsigned char *cursor;
|
||||||
|
const unsigned char *last_possible_needle_location =
|
||||||
|
(unsigned char *)haystack + haystacklen - needlelen;
|
||||||
|
|
||||||
|
/* Easy answers */
|
||||||
|
if (needlelen > haystacklen) return(NULL);
|
||||||
|
if (needle == NULL) return(NULL);
|
||||||
|
if (haystack == NULL) return(NULL);
|
||||||
|
if (needlelen == 0) return(NULL);
|
||||||
|
if (haystacklen == 0) return(NULL);
|
||||||
|
|
||||||
|
for (cursor = haystack; cursor <= last_possible_needle_location; cursor++) {
|
||||||
|
if (memcmp(needle, cursor, needlelen) == 0) {
|
||||||
|
return((void *) cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MAIN
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
char haystack[10], needle[3];
|
||||||
|
|
||||||
|
memmove(haystack, "0123456789", 10);
|
||||||
|
|
||||||
|
memmove(needle, "no", 2);
|
||||||
|
assert(my_memmem(haystack, 10, needle, 2) == NULL);
|
||||||
|
|
||||||
|
memmove(needle, "345", 3);
|
||||||
|
assert(my_memmem(haystack, 10, needle, 3) != NULL);
|
||||||
|
|
||||||
|
memmove(needle, "789", 3);
|
||||||
|
assert(my_memmem(haystack, 10, needle, 3) != NULL);
|
||||||
|
assert(my_memmem(haystack, 9, needle, 3) == NULL);
|
||||||
|
|
||||||
|
memmove(needle, "012", 3);
|
||||||
|
assert(my_memmem(haystack, 10, needle, 3) != NULL);
|
||||||
|
assert(my_memmem(NULL, 10, needle, 3) == NULL);
|
||||||
|
|
||||||
|
assert(my_memmem(NULL, 10, needle, 3) == NULL);
|
||||||
|
assert(my_memmem(haystack, 0, needle, 3) == NULL);
|
||||||
|
assert(my_memmem(haystack, 10, NULL, 3) == NULL);
|
||||||
|
assert(my_memmem(haystack, 10, needle, 0) == NULL);
|
||||||
|
|
||||||
|
assert(my_memmem(haystack, 1, needle, 3) == NULL);
|
||||||
|
|
||||||
|
printf("success\n");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -5832,34 +5832,55 @@ ha_innobase::get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong length= 0;
|
ulong length;
|
||||||
if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE) {
|
if (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE)
|
||||||
length=17;
|
{
|
||||||
tmp_buff= "ON DELETE CASCADE";
|
length=7;
|
||||||
}
|
tmp_buff= "CASCADE";
|
||||||
else if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) {
|
}
|
||||||
length=18;
|
else if (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL)
|
||||||
tmp_buff= "ON DELETE SET NULL";
|
{
|
||||||
}
|
length=8;
|
||||||
else if (foreign->type == DICT_FOREIGN_ON_DELETE_NO_ACTION) {
|
tmp_buff= "SET NULL";
|
||||||
length=19;
|
}
|
||||||
tmp_buff= "ON DELETE NO ACTION";
|
else if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION)
|
||||||
}
|
{
|
||||||
else if (foreign->type == DICT_FOREIGN_ON_UPDATE_CASCADE) {
|
length=9;
|
||||||
length=17;
|
tmp_buff= "NO ACTION";
|
||||||
tmp_buff= "ON UPDATE CASCADE";
|
}
|
||||||
}
|
else
|
||||||
else if (foreign->type == DICT_FOREIGN_ON_UPDATE_SET_NULL) {
|
{
|
||||||
length=18;
|
length=8;
|
||||||
tmp_buff= "ON UPDATE SET NULL";
|
tmp_buff= "RESTRICT";
|
||||||
}
|
}
|
||||||
else if (foreign->type == DICT_FOREIGN_ON_UPDATE_NO_ACTION) {
|
f_key_info.delete_method= make_lex_string(thd, f_key_info.delete_method,
|
||||||
length=19;
|
tmp_buff, length, 1);
|
||||||
tmp_buff= "ON UPDATE NO ACTION";
|
|
||||||
}
|
|
||||||
f_key_info.constraint_method= make_lex_string(thd,
|
if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE)
|
||||||
f_key_info.constraint_method,
|
{
|
||||||
tmp_buff, length, 1);
|
length=7;
|
||||||
|
tmp_buff= "CASCADE";
|
||||||
|
}
|
||||||
|
else if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL)
|
||||||
|
{
|
||||||
|
length=8;
|
||||||
|
tmp_buff= "SET NULL";
|
||||||
|
}
|
||||||
|
else if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION)
|
||||||
|
{
|
||||||
|
length=9;
|
||||||
|
tmp_buff= "NO ACTION";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
length=8;
|
||||||
|
tmp_buff= "RESTRICT";
|
||||||
|
}
|
||||||
|
f_key_info.update_method= make_lex_string(thd, f_key_info.update_method,
|
||||||
|
tmp_buff, length, 1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FOREIGN_KEY_INFO *pf_key_info= ((FOREIGN_KEY_INFO *)
|
FOREIGN_KEY_INFO *pf_key_info= ((FOREIGN_KEY_INFO *)
|
||||||
thd->memdup((gptr) &f_key_info,
|
thd->memdup((gptr) &f_key_info,
|
||||||
|
@ -2280,6 +2280,30 @@ static int my_xpath_parse_Number(MY_XPATH *xpath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
QName grammar can be found in a separate document
|
||||||
|
http://www.w3.org/TR/REC-xml-names/#NT-QName
|
||||||
|
|
||||||
|
[6] QName ::= (Prefix ':')? LocalPart
|
||||||
|
[7] Prefix ::= NCName
|
||||||
|
[8] LocalPart ::= NCName
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
my_xpath_parse_QName(MY_XPATH *xpath)
|
||||||
|
{
|
||||||
|
const char *beg;
|
||||||
|
if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT))
|
||||||
|
return 0;
|
||||||
|
beg= xpath->prevtok.beg;
|
||||||
|
if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_COLON))
|
||||||
|
return 1; /* Non qualified name */
|
||||||
|
if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT))
|
||||||
|
return 0;
|
||||||
|
xpath->prevtok.beg= beg;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Scan Variable reference
|
Scan Variable reference
|
||||||
|
|
||||||
@ -2313,7 +2337,7 @@ my_xpath_parse_VariableReference(MY_XPATH *xpath)
|
|||||||
static int
|
static int
|
||||||
my_xpath_parse_NodeTest_QName(MY_XPATH *xpath)
|
my_xpath_parse_NodeTest_QName(MY_XPATH *xpath)
|
||||||
{
|
{
|
||||||
if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT))
|
if (!my_xpath_parse_QName(xpath))
|
||||||
return 0;
|
return 0;
|
||||||
DBUG_ASSERT(xpath->context);
|
DBUG_ASSERT(xpath->context);
|
||||||
uint len= xpath->prevtok.end - xpath->prevtok.beg;
|
uint len= xpath->prevtok.end - xpath->prevtok.beg;
|
||||||
|
@ -177,6 +177,8 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset;
|
|||||||
|
|
||||||
/* Characters shown for the command in 'show processlist' */
|
/* Characters shown for the command in 'show processlist' */
|
||||||
#define PROCESS_LIST_WIDTH 100
|
#define PROCESS_LIST_WIDTH 100
|
||||||
|
/* Characters shown for the command in 'information_schema.processlist' */
|
||||||
|
#define PROCESS_LIST_INFO_WIDTH 65535
|
||||||
|
|
||||||
/* Time handling defaults */
|
/* Time handling defaults */
|
||||||
#define TIMESTAMP_MAX_YEAR 2038
|
#define TIMESTAMP_MAX_YEAR 2038
|
||||||
|
@ -1753,7 +1753,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
if (alloc_query(thd, packet, packet_length))
|
if (alloc_query(thd, packet, packet_length))
|
||||||
break; // fatal error is set
|
break; // fatal error is set
|
||||||
char *packet_end= thd->query + thd->query_length;
|
char *packet_end= thd->query + thd->query_length;
|
||||||
general_log_print(thd, command, "%s", thd->query);
|
general_log_print(thd, command, "%.*b", thd->query_length, thd->query);
|
||||||
DBUG_PRINT("query",("%-.4096s",thd->query));
|
DBUG_PRINT("query",("%-.4096s",thd->query));
|
||||||
|
|
||||||
if (!(specialflag & SPECIAL_NO_PRIOR))
|
if (!(specialflag & SPECIAL_NO_PRIOR))
|
||||||
|
@ -1755,6 +1755,9 @@ static bool check_prepared_statement(Prepared_statement *stmt,
|
|||||||
case SQLCOM_CALL:
|
case SQLCOM_CALL:
|
||||||
case SQLCOM_CREATE_VIEW:
|
case SQLCOM_CREATE_VIEW:
|
||||||
case SQLCOM_DROP_VIEW:
|
case SQLCOM_DROP_VIEW:
|
||||||
|
case SQLCOM_REPAIR:
|
||||||
|
case SQLCOM_ANALYZE:
|
||||||
|
case SQLCOM_OPTIMIZE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1553,15 +1553,11 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
|
|||||||
TABLE *table= tables->table;
|
TABLE *table= tables->table;
|
||||||
CHARSET_INFO *cs= system_charset_info;
|
CHARSET_INFO *cs= system_charset_info;
|
||||||
char *user;
|
char *user;
|
||||||
bool verbose;
|
|
||||||
ulong max_query_length;
|
|
||||||
time_t now= time(0);
|
time_t now= time(0);
|
||||||
DBUG_ENTER("fill_process_list");
|
DBUG_ENTER("fill_process_list");
|
||||||
|
|
||||||
user= thd->security_ctx->master_access & PROCESS_ACL ?
|
user= thd->security_ctx->master_access & PROCESS_ACL ?
|
||||||
NullS : thd->security_ctx->priv_user;
|
NullS : thd->security_ctx->priv_user;
|
||||||
verbose= thd->lex->verbose;
|
|
||||||
max_query_length= PROCESS_LIST_WIDTH;
|
|
||||||
|
|
||||||
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
||||||
|
|
||||||
@ -1645,7 +1641,8 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
|
|||||||
if (tmp->query)
|
if (tmp->query)
|
||||||
{
|
{
|
||||||
table->field[7]->store(tmp->query,
|
table->field[7]->store(tmp->query,
|
||||||
min(max_query_length, tmp->query_length), cs);
|
min(PROCESS_LIST_INFO_WIDTH,
|
||||||
|
tmp->query_length), cs);
|
||||||
table->field[7]->set_notnull();
|
table->field[7]->set_notnull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4234,6 +4231,75 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fill and store records into I_S.referential_constraints table
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
get_referential_constraints_record()
|
||||||
|
thd thread handle
|
||||||
|
tables table list struct(processed table)
|
||||||
|
table I_S table
|
||||||
|
res 1 means the error during opening of the processed table
|
||||||
|
0 means processed table is opened without error
|
||||||
|
base_name db name
|
||||||
|
file_name table name
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok
|
||||||
|
# error
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_referential_constraints_record(THD *thd, struct st_table_list *tables,
|
||||||
|
TABLE *table, bool res,
|
||||||
|
const char *base_name, const char *file_name)
|
||||||
|
{
|
||||||
|
CHARSET_INFO *cs= system_charset_info;
|
||||||
|
DBUG_ENTER("get_referential_constraints_record");
|
||||||
|
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
if (!tables->view)
|
||||||
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
|
thd->net.last_errno, thd->net.last_error);
|
||||||
|
thd->clear_error();
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
if (!tables->view)
|
||||||
|
{
|
||||||
|
List<FOREIGN_KEY_INFO> f_key_list;
|
||||||
|
TABLE *show_table= tables->table;
|
||||||
|
show_table->file->info(HA_STATUS_VARIABLE |
|
||||||
|
HA_STATUS_NO_LOCK |
|
||||||
|
HA_STATUS_TIME);
|
||||||
|
|
||||||
|
show_table->file->get_foreign_key_list(thd, &f_key_list);
|
||||||
|
FOREIGN_KEY_INFO *f_key_info;
|
||||||
|
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
|
||||||
|
while ((f_key_info= it++))
|
||||||
|
{
|
||||||
|
restore_record(table, s->default_values);
|
||||||
|
table->field[1]->store(base_name, strlen(base_name), cs);
|
||||||
|
table->field[9]->store(file_name, strlen(file_name), cs);
|
||||||
|
table->field[2]->store(f_key_info->forein_id->str,
|
||||||
|
f_key_info->forein_id->length, cs);
|
||||||
|
table->field[4]->store(f_key_info->referenced_db->str,
|
||||||
|
f_key_info->referenced_db->length, cs);
|
||||||
|
table->field[5]->store(f_key_info->referenced_table->str,
|
||||||
|
f_key_info->referenced_table->length, cs);
|
||||||
|
table->field[6]->store(STRING_WITH_LEN("NONE"), cs);
|
||||||
|
table->field[7]->store(f_key_info->update_method->str,
|
||||||
|
f_key_info->update_method->length, cs);
|
||||||
|
table->field[8]->store(f_key_info->delete_method->str,
|
||||||
|
f_key_info->delete_method->length, cs);
|
||||||
|
if (schema_table_store_record(thd, table))
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Find schema_tables elment by name
|
Find schema_tables elment by name
|
||||||
|
|
||||||
@ -5099,9 +5165,9 @@ ST_FIELD_INFO processlist_fields_info[]=
|
|||||||
{"HOST", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Host"},
|
{"HOST", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Host"},
|
||||||
{"DB", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Db"},
|
{"DB", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Db"},
|
||||||
{"COMMAND", 16, MYSQL_TYPE_STRING, 0, 0, "Command"},
|
{"COMMAND", 16, MYSQL_TYPE_STRING, 0, 0, "Command"},
|
||||||
{"TIME", 4, MYSQL_TYPE_LONG, 0, 0, "Time"},
|
{"TIME", 7, MYSQL_TYPE_LONG, 0, 0, "Time"},
|
||||||
{"STATE", 30, MYSQL_TYPE_STRING, 0, 1, "State"},
|
{"STATE", 30, MYSQL_TYPE_STRING, 0, 1, "State"},
|
||||||
{"INFO", PROCESS_LIST_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info"},
|
{"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info"},
|
||||||
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
|
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -5163,6 +5229,22 @@ ST_FIELD_INFO files_fields_info[]=
|
|||||||
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
|
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ST_FIELD_INFO referential_constraints_fields_info[]=
|
||||||
|
{
|
||||||
|
{"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
|
||||||
|
{"CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
|
||||||
|
{"CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
|
||||||
|
{"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
|
||||||
|
{"UNIQUE_CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
|
||||||
|
{"UNIQUE_CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
|
||||||
|
{"MATCH_OPTION", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
|
||||||
|
{"UPDATE_RULE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
|
||||||
|
{"DELETE_RULE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
|
||||||
|
{"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
|
||||||
|
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Description of ST_FIELD_INFO in table.h
|
Description of ST_FIELD_INFO in table.h
|
||||||
|
|
||||||
@ -5198,6 +5280,9 @@ ST_SCHEMA_TABLE schema_tables[]=
|
|||||||
fill_plugins, make_old_format, 0, -1, -1, 0},
|
fill_plugins, make_old_format, 0, -1, -1, 0},
|
||||||
{"PROCESSLIST", processlist_fields_info, create_schema_table,
|
{"PROCESSLIST", processlist_fields_info, create_schema_table,
|
||||||
fill_schema_processlist, make_old_format, 0, -1, -1, 0},
|
fill_schema_processlist, make_old_format, 0, -1, -1, 0},
|
||||||
|
{"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info,
|
||||||
|
create_schema_table, get_all_tables, 0, get_referential_constraints_record,
|
||||||
|
1, 9, 0},
|
||||||
{"ROUTINES", proc_fields_info, create_schema_table,
|
{"ROUTINES", proc_fields_info, create_schema_table,
|
||||||
fill_schema_proc, make_proc_old_format, 0, -1, -1, 0},
|
fill_schema_proc, make_proc_old_format, 0, -1, -1, 0},
|
||||||
{"SCHEMATA", schema_fields_info, create_schema_table,
|
{"SCHEMATA", schema_fields_info, create_schema_table,
|
||||||
|
@ -331,7 +331,7 @@ bool String::set_or_copy_aligned(const char *str,uint32 arg_length,
|
|||||||
return copy_aligned(str, arg_length, offset, cs);
|
return copy_aligned(str, arg_length, offset, cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy with charset convertion */
|
/* Copy with charset conversion */
|
||||||
|
|
||||||
bool String::copy(const char *str, uint32 arg_length,
|
bool String::copy(const char *str, uint32 arg_length,
|
||||||
CHARSET_INFO *from_cs, CHARSET_INFO *to_cs, uint *errors)
|
CHARSET_INFO *from_cs, CHARSET_INFO *to_cs, uint *errors)
|
||||||
|
@ -335,7 +335,8 @@ typedef struct st_foreign_key_info
|
|||||||
LEX_STRING *forein_id;
|
LEX_STRING *forein_id;
|
||||||
LEX_STRING *referenced_db;
|
LEX_STRING *referenced_db;
|
||||||
LEX_STRING *referenced_table;
|
LEX_STRING *referenced_table;
|
||||||
LEX_STRING *constraint_method;
|
LEX_STRING *update_method;
|
||||||
|
LEX_STRING *delete_method;
|
||||||
List<LEX_STRING> foreign_fields;
|
List<LEX_STRING> foreign_fields;
|
||||||
List<LEX_STRING> referenced_fields;
|
List<LEX_STRING> referenced_fields;
|
||||||
} FOREIGN_KEY_INFO;
|
} FOREIGN_KEY_INFO;
|
||||||
@ -359,6 +360,7 @@ enum enum_schema_tables
|
|||||||
SCH_PARTITIONS,
|
SCH_PARTITIONS,
|
||||||
SCH_PLUGINS,
|
SCH_PLUGINS,
|
||||||
SCH_PROCESSLIST,
|
SCH_PROCESSLIST,
|
||||||
|
SCH_REFERENTIAL_CONSTRAINTS,
|
||||||
SCH_PROCEDURES,
|
SCH_PROCEDURES,
|
||||||
SCH_SCHEMATA,
|
SCH_SCHEMATA,
|
||||||
SCH_SCHEMA_PRIVILEGES,
|
SCH_SCHEMA_PRIVILEGES,
|
||||||
|
@ -1382,11 +1382,30 @@ static LS_INFO *tz_lsis= 0;
|
|||||||
static bool time_zone_tables_exist= 1;
|
static bool time_zone_tables_exist= 1;
|
||||||
|
|
||||||
|
|
||||||
typedef struct st_tz_names_entry: public Sql_alloc
|
/*
|
||||||
|
Names of tables (with their lengths) that are needed
|
||||||
|
for dynamical loading of time zone descriptions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const LEX_STRING tz_tables_names[MY_TZ_TABLES_COUNT]=
|
||||||
{
|
{
|
||||||
|
{(char *) STRING_WITH_LEN("time_zone_name")},
|
||||||
|
{(char *) STRING_WITH_LEN("time_zone")},
|
||||||
|
{(char *) STRING_WITH_LEN("time_zone_transition_type")},
|
||||||
|
{(char *) STRING_WITH_LEN("time_zone_transition")}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Name of database to which those tables belong. */
|
||||||
|
|
||||||
|
static const LEX_STRING tz_tables_db_name= {(char *) STRING_WITH_LEN("mysql")};
|
||||||
|
|
||||||
|
|
||||||
|
class Tz_names_entry: public Sql_alloc
|
||||||
|
{
|
||||||
|
public:
|
||||||
String name;
|
String name;
|
||||||
Time_zone *tz;
|
Time_zone *tz;
|
||||||
} TZ_NAMES_ENTRY;
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1394,7 +1413,7 @@ typedef struct st_tz_names_entry: public Sql_alloc
|
|||||||
they should obey C calling conventions.
|
they should obey C calling conventions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern "C" byte* my_tz_names_get_key(TZ_NAMES_ENTRY *entry, uint *length,
|
extern "C" byte* my_tz_names_get_key(Tz_names_entry *entry, uint *length,
|
||||||
my_bool not_used __attribute__((unused)))
|
my_bool not_used __attribute__((unused)))
|
||||||
{
|
{
|
||||||
*length= entry->name.length();
|
*length= entry->name.length();
|
||||||
@ -1415,7 +1434,8 @@ extern "C" byte* my_offset_tzs_get_key(Time_zone_offset *entry, uint *length,
|
|||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
tz_init_table_list()
|
tz_init_table_list()
|
||||||
tz_tabs - pointer to preallocated array of 4 TABLE_LIST objects
|
tz_tabs - pointer to preallocated array of MY_TZ_TABLES_COUNT
|
||||||
|
TABLE_LIST objects
|
||||||
global_next_ptr - pointer to variable which points to global_next member
|
global_next_ptr - pointer to variable which points to global_next member
|
||||||
of last element of global table list (or list root
|
of last element of global table list (or list root
|
||||||
then list is empty) (in/out).
|
then list is empty) (in/out).
|
||||||
@ -1430,27 +1450,27 @@ extern "C" byte* my_offset_tzs_get_key(Time_zone_offset *entry, uint *length,
|
|||||||
static void
|
static void
|
||||||
tz_init_table_list(TABLE_LIST *tz_tabs, TABLE_LIST ***global_next_ptr)
|
tz_init_table_list(TABLE_LIST *tz_tabs, TABLE_LIST ***global_next_ptr)
|
||||||
{
|
{
|
||||||
bzero(tz_tabs, sizeof(TABLE_LIST) * 4);
|
bzero(tz_tabs, sizeof(TABLE_LIST) * MY_TZ_TABLES_COUNT);
|
||||||
tz_tabs[0].alias= tz_tabs[0].table_name= (char*)"time_zone_name";
|
|
||||||
tz_tabs[1].alias= tz_tabs[1].table_name= (char*)"time_zone";
|
for (int i= 0; i < MY_TZ_TABLES_COUNT; i++)
|
||||||
tz_tabs[2].alias= tz_tabs[2].table_name= (char*)"time_zone_transition_type";
|
{
|
||||||
tz_tabs[3].alias= tz_tabs[3].table_name= (char*)"time_zone_transition";
|
tz_tabs[i].alias= tz_tabs[i].table_name= tz_tables_names[i].str;
|
||||||
tz_tabs[0].next_global= tz_tabs[0].next_local= tz_tabs+1;
|
tz_tabs[i].table_name_length= tz_tables_names[i].length;
|
||||||
tz_tabs[1].next_global= tz_tabs[1].next_local= tz_tabs+2;
|
tz_tabs[i].db= tz_tables_db_name.str;
|
||||||
tz_tabs[2].next_global= tz_tabs[2].next_local= tz_tabs+3;
|
tz_tabs[i].db_length= tz_tables_db_name.length;
|
||||||
tz_tabs[0].lock_type= tz_tabs[1].lock_type= tz_tabs[2].lock_type=
|
tz_tabs[i].lock_type= TL_READ;
|
||||||
tz_tabs[3].lock_type= TL_READ;
|
|
||||||
tz_tabs[0].db= tz_tabs[1].db= tz_tabs[2].db= tz_tabs[3].db= (char *)"mysql";
|
if (i != MY_TZ_TABLES_COUNT - 1)
|
||||||
|
tz_tabs[i].next_global= tz_tabs[i].next_local= &tz_tabs[i+1];
|
||||||
|
if (i != 0)
|
||||||
|
tz_tabs[i].prev_global= &tz_tabs[i-1].next_global;
|
||||||
|
}
|
||||||
|
|
||||||
/* Link into global list */
|
/* Link into global list */
|
||||||
tz_tabs[0].prev_global= *global_next_ptr;
|
tz_tabs[0].prev_global= *global_next_ptr;
|
||||||
tz_tabs[1].prev_global= &tz_tabs[0].next_global;
|
|
||||||
tz_tabs[2].prev_global= &tz_tabs[1].next_global;
|
|
||||||
tz_tabs[3].prev_global= &tz_tabs[2].next_global;
|
|
||||||
|
|
||||||
**global_next_ptr= tz_tabs;
|
**global_next_ptr= tz_tabs;
|
||||||
/* Update last-global-pointer to point to pointer in last table */
|
/* Update last-global-pointer to point to pointer in last table */
|
||||||
*global_next_ptr= &tz_tabs[3].next_global;
|
*global_next_ptr= &tz_tabs[MY_TZ_TABLES_COUNT-1].next_global;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1479,7 +1499,8 @@ TABLE_LIST fake_time_zone_tables_list;
|
|||||||
|
|
||||||
NOTE
|
NOTE
|
||||||
my_tz_check_n_skip_implicit_tables() function depends on fact that
|
my_tz_check_n_skip_implicit_tables() function depends on fact that
|
||||||
elements of list created are allocated as TABLE_LIST[4] array.
|
elements of list created are allocated as TABLE_LIST[MY_TZ_TABLES_COUNT]
|
||||||
|
array.
|
||||||
|
|
||||||
RETURN VALUES
|
RETURN VALUES
|
||||||
Returns pointer to first TABLE_LIST object, (could be 0 if time zone
|
Returns pointer to first TABLE_LIST object, (could be 0 if time zone
|
||||||
@ -1495,7 +1516,8 @@ my_tz_get_table_list(THD *thd, TABLE_LIST ***global_next_ptr)
|
|||||||
if (!time_zone_tables_exist)
|
if (!time_zone_tables_exist)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
if (!(tz_tabs= (TABLE_LIST *)thd->alloc(sizeof(TABLE_LIST) * 4)))
|
if (!(tz_tabs= (TABLE_LIST *)thd->alloc(sizeof(TABLE_LIST) *
|
||||||
|
MY_TZ_TABLES_COUNT)))
|
||||||
DBUG_RETURN(&fake_time_zone_tables_list);
|
DBUG_RETURN(&fake_time_zone_tables_list);
|
||||||
|
|
||||||
tz_init_table_list(tz_tabs, global_next_ptr);
|
tz_init_table_list(tz_tabs, global_next_ptr);
|
||||||
@ -1534,9 +1556,9 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
|
|||||||
{
|
{
|
||||||
THD *thd;
|
THD *thd;
|
||||||
TABLE_LIST *tables= 0;
|
TABLE_LIST *tables= 0;
|
||||||
TABLE_LIST tables_buff[5], **last_global_next_ptr;
|
TABLE_LIST tables_buff[1+MY_TZ_TABLES_COUNT], **last_global_next_ptr;
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
TZ_NAMES_ENTRY *tmp_tzname;
|
Tz_names_entry *tmp_tzname;
|
||||||
my_bool return_val= 1;
|
my_bool return_val= 1;
|
||||||
int res;
|
int res;
|
||||||
DBUG_ENTER("my_tz_init");
|
DBUG_ENTER("my_tz_init");
|
||||||
@ -1568,7 +1590,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
|
|||||||
tz_inited= 1;
|
tz_inited= 1;
|
||||||
|
|
||||||
/* Add 'SYSTEM' time zone to tz_names hash */
|
/* Add 'SYSTEM' time zone to tz_names hash */
|
||||||
if (!(tmp_tzname= new (&tz_storage) TZ_NAMES_ENTRY()))
|
if (!(tmp_tzname= new (&tz_storage) Tz_names_entry()))
|
||||||
{
|
{
|
||||||
sql_print_error("Fatal error: OOM while initializing time zones");
|
sql_print_error("Fatal error: OOM while initializing time zones");
|
||||||
goto end_with_cleanup;
|
goto end_with_cleanup;
|
||||||
@ -1764,7 +1786,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
|
|||||||
{
|
{
|
||||||
TABLE *table= 0;
|
TABLE *table= 0;
|
||||||
TIME_ZONE_INFO *tz_info;
|
TIME_ZONE_INFO *tz_info;
|
||||||
TZ_NAMES_ENTRY *tmp_tzname;
|
Tz_names_entry *tmp_tzname;
|
||||||
Time_zone *return_val= 0;
|
Time_zone *return_val= 0;
|
||||||
int res;
|
int res;
|
||||||
uint tzid, ttid;
|
uint tzid, ttid;
|
||||||
@ -2039,7 +2061,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!(tmp_tzname= new (&tz_storage) TZ_NAMES_ENTRY()) ||
|
if (!(tmp_tzname= new (&tz_storage) Tz_names_entry()) ||
|
||||||
!(tmp_tzname->tz= new (&tz_storage) Time_zone_db(tz_info,
|
!(tmp_tzname->tz= new (&tz_storage) Time_zone_db(tz_info,
|
||||||
&(tmp_tzname->name))) ||
|
&(tmp_tzname->name))) ||
|
||||||
(tmp_tzname->name.set(tz_name_buff, tz_name->length(),
|
(tmp_tzname->name.set(tz_name_buff, tz_name->length(),
|
||||||
@ -2186,7 +2208,7 @@ str_to_offset(const char *str, uint length, long *offset)
|
|||||||
Time_zone *
|
Time_zone *
|
||||||
my_tz_find(const String * name, TABLE_LIST *tz_tables)
|
my_tz_find(const String * name, TABLE_LIST *tz_tables)
|
||||||
{
|
{
|
||||||
TZ_NAMES_ENTRY *tmp_tzname;
|
Tz_names_entry *tmp_tzname;
|
||||||
Time_zone *result_tz= 0;
|
Time_zone *result_tz= 0;
|
||||||
long offset;
|
long offset;
|
||||||
DBUG_ENTER("my_tz_find");
|
DBUG_ENTER("my_tz_find");
|
||||||
@ -2221,7 +2243,7 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
result_tz= 0;
|
result_tz= 0;
|
||||||
if ((tmp_tzname= (TZ_NAMES_ENTRY *)hash_search(&tz_names,
|
if ((tmp_tzname= (Tz_names_entry *)hash_search(&tz_names,
|
||||||
(const byte *)name->ptr(),
|
(const byte *)name->ptr(),
|
||||||
name->length())))
|
name->length())))
|
||||||
result_tz= tmp_tzname->tz;
|
result_tz= tmp_tzname->tz;
|
||||||
@ -2273,7 +2295,7 @@ Time_zone *my_tz_find_with_opening_tz_tables(THD *thd, const String *name)
|
|||||||
our time zone tables. Note that if we don't have tz tables on this
|
our time zone tables. Note that if we don't have tz tables on this
|
||||||
slave, we don't even try.
|
slave, we don't even try.
|
||||||
*/
|
*/
|
||||||
TABLE_LIST tables[4];
|
TABLE_LIST tables[MY_TZ_TABLES_COUNT];
|
||||||
TABLE_LIST *dummy;
|
TABLE_LIST *dummy;
|
||||||
TABLE_LIST **dummyp= &dummy;
|
TABLE_LIST **dummyp= &dummy;
|
||||||
tz_init_table_list(tables, &dummyp);
|
tz_init_table_list(tables, &dummyp);
|
||||||
|
13
sql/tztime.h
13
sql/tztime.h
@ -69,6 +69,15 @@ extern my_time_t sec_since_epoch_TIME(TIME *t);
|
|||||||
|
|
||||||
extern TABLE_LIST fake_time_zone_tables_list;
|
extern TABLE_LIST fake_time_zone_tables_list;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Number of elements in table list produced by my_tz_get_table_list()
|
||||||
|
(this table list contains tables which are needed for dynamical loading
|
||||||
|
of time zone descriptions). Actually it is imlementation detail that
|
||||||
|
should not be used anywhere outside of tztime.h and tztime.cc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const int MY_TZ_TABLES_COUNT= 4;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check if we have pointer to the begining of list of implicitly used time
|
Check if we have pointer to the begining of list of implicitly used time
|
||||||
zone tables, set SELECT_ACL for them and fast-forward to its end.
|
zone tables, set SELECT_ACL for them and fast-forward to its end.
|
||||||
@ -91,9 +100,9 @@ inline bool my_tz_check_n_skip_implicit_tables(TABLE_LIST **table,
|
|||||||
{
|
{
|
||||||
if (*table == tz_tables)
|
if (*table == tz_tables)
|
||||||
{
|
{
|
||||||
for (int i= 0; i < 4; i++)
|
for (int i= 0; i < MY_TZ_TABLES_COUNT; i++)
|
||||||
(*table)[i].grant.privilege= SELECT_ACL;
|
(*table)[i].grant.privilege= SELECT_ACL;
|
||||||
(*table)+= 3;
|
(*table)+= MY_TZ_TABLES_COUNT - 1;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -172,7 +172,7 @@ mb_wc - converts the left multibyte sequence into it Unicode code.
|
|||||||
mc_mb - converts the given Unicode code into multibyte sequence.
|
mc_mb - converts the given Unicode code into multibyte sequence.
|
||||||
|
|
||||||
|
|
||||||
Case and sort convertion
|
Case and sort conversion
|
||||||
------------------------
|
------------------------
|
||||||
caseup_str - converts the given 0-terminated string into the upper case
|
caseup_str - converts the given 0-terminated string into the upper case
|
||||||
casedn_str - converts the given 0-terminated string into the lower case
|
casedn_str - converts the given 0-terminated string into the lower case
|
||||||
@ -227,4 +227,4 @@ hash_sort() - calculates hash value taking in account
|
|||||||
the collation rules, e.g. case-insensitivity,
|
the collation rules, e.g. case-insensitivity,
|
||||||
accent sensitivity, etc.
|
accent sensitivity, etc.
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
%#[l]d
|
%#[l]d
|
||||||
%#[l]u
|
%#[l]u
|
||||||
%#[l]x
|
%#[l]x
|
||||||
|
%#.#b Local format; note first # is ignored and second is REQUIRED
|
||||||
%#.#s Note first # is ignored
|
%#.#s Note first # is ignored
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
@ -40,7 +41,7 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
|
|||||||
|
|
||||||
for (; *fmt ; fmt++)
|
for (; *fmt ; fmt++)
|
||||||
{
|
{
|
||||||
if (fmt[0] != '%')
|
if (*fmt != '%')
|
||||||
{
|
{
|
||||||
if (to == end) /* End of buffer */
|
if (to == end) /* End of buffer */
|
||||||
break;
|
break;
|
||||||
@ -95,6 +96,16 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
|
|||||||
to=strnmov(to,par,plen);
|
to=strnmov(to,par,plen);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else if (*fmt == 'b') /* Buffer parameter */
|
||||||
|
{
|
||||||
|
char *par = va_arg(ap, char *);
|
||||||
|
DBUG_ASSERT(to <= end);
|
||||||
|
if (to + abs(width) + 1 > end)
|
||||||
|
width= end - to - 1; /* sign doesn't matter */
|
||||||
|
memmove(to, par, abs(width));
|
||||||
|
to+= width;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
else if (*fmt == 'd' || *fmt == 'u'|| *fmt== 'x') /* Integer parameter */
|
else if (*fmt == 'd' || *fmt == 'u'|| *fmt== 'x') /* Integer parameter */
|
||||||
{
|
{
|
||||||
register long larg;
|
register long larg;
|
||||||
|
@ -43,7 +43,7 @@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
|
|||||||
LIBS = @CLIENT_LIBS@
|
LIBS = @CLIENT_LIBS@
|
||||||
LDADD = @CLIENT_EXTRA_LDFLAGS@ \
|
LDADD = @CLIENT_EXTRA_LDFLAGS@ \
|
||||||
$(top_builddir)/libmysql/libmysqlclient.la
|
$(top_builddir)/libmysql/libmysqlclient.la
|
||||||
mysql_client_test_LDADD= $(LDADD) $(CXXLDFLAGS)
|
mysql_client_test_LDADD= $(LDADD) $(CXXLDFLAGS) -L../mysys -lmysys
|
||||||
mysql_client_test_SOURCES= mysql_client_test.c $(yassl_dummy_link_fix)
|
mysql_client_test_SOURCES= mysql_client_test.c $(yassl_dummy_link_fix)
|
||||||
insert_test_SOURCES= insert_test.c $(yassl_dummy_link_fix)
|
insert_test_SOURCES= insert_test.c $(yassl_dummy_link_fix)
|
||||||
select_test_SOURCES= select_test.c $(yassl_dummy_link_fix)
|
select_test_SOURCES= select_test.c $(yassl_dummy_link_fix)
|
||||||
|
@ -6,4 +6,4 @@ ADD_DEFINITIONS("-DMYSQL_CLIENT")
|
|||||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
|
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
|
||||||
|
|
||||||
ADD_EXECUTABLE(mysql_client_test mysql_client_test.c)
|
ADD_EXECUTABLE(mysql_client_test mysql_client_test.c)
|
||||||
TARGET_LINK_LIBRARIES(mysql_client_test dbug mysqlclient yassl taocrypt zlib wsock32)
|
TARGET_LINK_LIBRARIES(mysql_client_test dbug mysys mysqlclient yassl taocrypt zlib wsock32)
|
||||||
|
@ -14839,6 +14839,73 @@ static void test_bug15613()
|
|||||||
myquery(rc);
|
myquery(rc);
|
||||||
mysql_stmt_close(stmt);
|
mysql_stmt_close(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Bug#17667: An attacker has the opportunity to bypass query logging.
|
||||||
|
*/
|
||||||
|
static void test_bug17667()
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
struct buffer_and_length {
|
||||||
|
const char *buffer;
|
||||||
|
const uint length;
|
||||||
|
} statements[]= {
|
||||||
|
{ "drop table if exists bug17667", 29 },
|
||||||
|
{ "create table bug17667 (c varchar(20))", 37 },
|
||||||
|
{ "insert into bug17667 (c) values ('regular') /* NUL=\0 with comment */", 68 },
|
||||||
|
{ "insert into bug17667 (c) values ('NUL=\0 in value')", 50 },
|
||||||
|
{ "insert into bug17667 (c) values ('5 NULs=\0\0\0\0\0')", 48 },
|
||||||
|
{ "/* NUL=\0 with comment */ insert into bug17667 (c) values ('encore')", 67 },
|
||||||
|
{ "drop table bug17667", 19 },
|
||||||
|
{ NULL, 0 } };
|
||||||
|
|
||||||
|
struct buffer_and_length *statement_cursor;
|
||||||
|
FILE *log_file;
|
||||||
|
|
||||||
|
myheader("test_bug17667");
|
||||||
|
|
||||||
|
for (statement_cursor= statements; statement_cursor->buffer != NULL;
|
||||||
|
statement_cursor++) {
|
||||||
|
rc= mysql_real_query(mysql, statement_cursor->buffer,
|
||||||
|
statement_cursor->length);
|
||||||
|
myquery(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(1); /* The server may need time to flush the data to the log. */
|
||||||
|
log_file= fopen("var/log/master.log", "r");
|
||||||
|
if (log_file != NULL) {
|
||||||
|
|
||||||
|
for (statement_cursor= statements; statement_cursor->buffer != NULL;
|
||||||
|
statement_cursor++) {
|
||||||
|
char line_buffer[MAX_TEST_QUERY_LENGTH*2];
|
||||||
|
/* more than enough room for the query and some marginalia. */
|
||||||
|
|
||||||
|
do {
|
||||||
|
memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2);
|
||||||
|
|
||||||
|
DIE_UNLESS(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) !=
|
||||||
|
NULL);
|
||||||
|
/* If we reach EOF before finishing the statement list, then we failed. */
|
||||||
|
|
||||||
|
} while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2,
|
||||||
|
statement_cursor->buffer, statement_cursor->length) == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("success. All queries found intact in the log.\n");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Could not find the log file, var/log/master.log, so "
|
||||||
|
"test_bug17667 is \ninconclusive. Run test from the "
|
||||||
|
"mysql-test/mysql-test-run* program \nto set up the correct "
|
||||||
|
"environment for this test.\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (log_file != NULL)
|
||||||
|
fclose(log_file);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Bug#14169: type of group_concat() result changed to blob if tmp_table was used
|
Bug#14169: type of group_concat() result changed to blob if tmp_table was used
|
||||||
*/
|
*/
|
||||||
@ -15139,6 +15206,7 @@ static struct my_tests_st my_tests[]= {
|
|||||||
{ "test_bug16144", test_bug16144 },
|
{ "test_bug16144", test_bug16144 },
|
||||||
{ "test_bug15613", test_bug15613 },
|
{ "test_bug15613", test_bug15613 },
|
||||||
{ "test_bug14169", test_bug14169 },
|
{ "test_bug14169", test_bug14169 },
|
||||||
|
{ "test_bug17667", test_bug17667 },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user