mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Merge bk-internal.mysql.com:/home/bk/mysql-4.1
into mishka.local:/home/my/mysql-4.1 sql/ha_ndbcluster.cc: Auto merged sql/sql_base.cc: Auto merged sql/sql_parse.cc: Auto merged
This commit is contained in:
@@ -78,7 +78,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
|||||||
int lock_error,kfile,open_mode,save_errno,have_rtree=0;
|
int lock_error,kfile,open_mode,save_errno,have_rtree=0;
|
||||||
uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
|
uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
|
||||||
key_parts,unique_key_parts,fulltext_keys,uniques;
|
key_parts,unique_key_parts,fulltext_keys,uniques;
|
||||||
char name_buff[FN_REFLEN], org_name [FN_REFLEN], index_name[FN_REFLEN],
|
char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
|
||||||
data_name[FN_REFLEN];
|
data_name[FN_REFLEN];
|
||||||
char *disk_cache, *disk_pos, *end_pos;
|
char *disk_cache, *disk_pos, *end_pos;
|
||||||
MI_INFO info,*m_info,*old_info;
|
MI_INFO info,*m_info,*old_info;
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
drop table if exists t1,t2;
|
drop table if exists t1,t2,t3;
|
||||||
create table t1 (bandID MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY, payoutID SMALLINT UNSIGNED NOT NULL);
|
create table t1 (bandID MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY, payoutID SMALLINT UNSIGNED NOT NULL);
|
||||||
insert into t1 (bandID,payoutID) VALUES (1,6),(2,6),(3,4),(4,9),(5,10),(6,1),(7,12),(8,12);
|
insert into t1 (bandID,payoutID) VALUES (1,6),(2,6),(3,4),(4,9),(5,10),(6,1),(7,12),(8,12);
|
||||||
create table t2 (payoutID SMALLINT UNSIGNED NOT NULL PRIMARY KEY);
|
create table t2 (payoutID SMALLINT UNSIGNED NOT NULL PRIMARY KEY);
|
||||||
@@ -636,16 +636,35 @@ ff1 ff2
|
|||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
create table t1 (a int unique);
|
create table t1 (a int unique);
|
||||||
create table t2 (a int, b int);
|
create table t2 (a int, b int);
|
||||||
|
create table t3 (c int, d int);
|
||||||
insert into t1 values (1),(2);
|
insert into t1 values (1),(2);
|
||||||
insert into t2 values (1,2);
|
insert into t2 values (1,2);
|
||||||
|
insert into t3 values (1,6),(3,7);
|
||||||
select * from t1;
|
select * from t1;
|
||||||
a
|
a
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
insert into t1 select t2.a from t2 on duplicate key update a= a + t2.b;
|
insert into t1 select a from t2 on duplicate key update a= t1.a + t2.b;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
a
|
a
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
drop table t1;
|
insert into t1 select a+1 from t2 on duplicate key update t1.a= t1.a + t2.b+1;
|
||||||
drop table t2;
|
select * from t1;
|
||||||
|
a
|
||||||
|
3
|
||||||
|
5
|
||||||
|
insert into t1 select t3.c from t3 on duplicate key update a= a + t3.d;
|
||||||
|
select * from t1;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
5
|
||||||
|
10
|
||||||
|
insert into t1 select t2.a from t2 group by t2.a on duplicate key update a= a + 10;
|
||||||
|
insert into t1 select t2.a from t2 on duplicate key update a= a + t2.b;
|
||||||
|
ERROR 23000: Column 'a' in field list is ambiguous
|
||||||
|
insert into t1 select t2.a from t2 on duplicate key update t2.a= a + t2.b;
|
||||||
|
ERROR 42S02: Unknown table 't2' in field list
|
||||||
|
insert into t1 select t2.a from t2 group by t2.a on duplicate key update a= t1.a + t2.b;
|
||||||
|
ERROR 42S02: Unknown table 't2' in field list
|
||||||
|
drop table t1,t2,t3;
|
||||||
|
@@ -143,7 +143,7 @@ INSERT t1 VALUES (1,2,10), (3,4,20);
|
|||||||
CREATE TABLE t2 (a INT, b INT, c INT, d INT);
|
CREATE TABLE t2 (a INT, b INT, c INT, d INT);
|
||||||
INSERT t2 VALUES (5,6,30,1), (7,4,40,1), (8,9,60,1);
|
INSERT t2 VALUES (5,6,30,1), (7,4,40,1), (8,9,60,1);
|
||||||
INSERT t2 VALUES (2,1,11,2), (7,4,40,2);
|
INSERT t2 VALUES (2,1,11,2), (7,4,40,2);
|
||||||
INSERT t1 SELECT a,b,c FROM t2 WHERE d=1 ON DUPLICATE KEY UPDATE c=c+100;
|
INSERT t1 SELECT a,b,c FROM t2 WHERE d=1 ON DUPLICATE KEY UPDATE c=t1.c+100;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
a b c
|
a b c
|
||||||
1 2 10
|
1 2 10
|
||||||
@@ -158,6 +158,8 @@ a b c
|
|||||||
5 0 30
|
5 0 30
|
||||||
8 9 60
|
8 9 60
|
||||||
INSERT t1 SELECT a,b,c FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=c+VALUES(a);
|
INSERT t1 SELECT a,b,c FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=c+VALUES(a);
|
||||||
|
ERROR 23000: Column 'c' in field list is ambiguous
|
||||||
|
INSERT t1 SELECT a,b,c FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=t1.c+VALUES(t1.a);
|
||||||
SELECT *, VALUES(a) FROM t1;
|
SELECT *, VALUES(a) FROM t1;
|
||||||
a b c VALUES(a)
|
a b c VALUES(a)
|
||||||
1 2 10 NULL
|
1 2 10 NULL
|
||||||
@@ -174,7 +176,7 @@ select * from t1;
|
|||||||
a
|
a
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
insert ignore into t1 select a from t1 on duplicate key update a=a+1 ;
|
insert ignore into t1 select a from t1 as t2 on duplicate key update a=t1.a+1 ;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
a
|
a
|
||||||
1
|
1
|
||||||
@@ -185,5 +187,7 @@ a
|
|||||||
2
|
2
|
||||||
3
|
3
|
||||||
insert into t1 select a from t1 on duplicate key update a=a+1 ;
|
insert into t1 select a from t1 on duplicate key update a=a+1 ;
|
||||||
ERROR 23000: Duplicate entry '3' for key 1
|
ERROR 23000: Column 'a' in field list is ambiguous
|
||||||
|
insert ignore into t1 select a from t1 on duplicate key update a=t1.a+1 ;
|
||||||
|
ERROR 23000: Column 't1.a' in field list is ambiguous
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
DROP TABLE IF EXISTS t1,t2,t3;
|
DROP TABLE IF EXISTS t1,t2,t3,t2aA,t1Aa;
|
||||||
DROP DATABASE IF EXISTS `TEST_$1`;
|
DROP DATABASE IF EXISTS `TEST_$1`;
|
||||||
DROP DATABASE IF EXISTS `test_$1`;
|
DROP DATABASE IF EXISTS `test_$1`;
|
||||||
|
DROP DATABASE mysqltest_LC2;
|
||||||
CREATE TABLE T1 (a int);
|
CREATE TABLE T1 (a int);
|
||||||
INSERT INTO T1 VALUES (1);
|
INSERT INTO T1 VALUES (1);
|
||||||
SHOW TABLES LIKE "T1";
|
SHOW TABLES LIKE "T1";
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
drop table if exists t1,t2;
|
drop table if exists t1,t2,t3;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
|
||||||
create table t1 (bandID MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY, payoutID SMALLINT UNSIGNED NOT NULL);
|
create table t1 (bandID MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY, payoutID SMALLINT UNSIGNED NOT NULL);
|
||||||
@@ -182,10 +182,24 @@ drop table t1, t2;
|
|||||||
#
|
#
|
||||||
create table t1 (a int unique);
|
create table t1 (a int unique);
|
||||||
create table t2 (a int, b int);
|
create table t2 (a int, b int);
|
||||||
|
create table t3 (c int, d int);
|
||||||
insert into t1 values (1),(2);
|
insert into t1 values (1),(2);
|
||||||
insert into t2 values (1,2);
|
insert into t2 values (1,2);
|
||||||
|
insert into t3 values (1,6),(3,7);
|
||||||
select * from t1;
|
select * from t1;
|
||||||
|
insert into t1 select a from t2 on duplicate key update a= t1.a + t2.b;
|
||||||
|
select * from t1;
|
||||||
|
insert into t1 select a+1 from t2 on duplicate key update t1.a= t1.a + t2.b+1;
|
||||||
|
select * from t1;
|
||||||
|
insert into t1 select t3.c from t3 on duplicate key update a= a + t3.d;
|
||||||
|
select * from t1;
|
||||||
|
insert into t1 select t2.a from t2 group by t2.a on duplicate key update a= a + 10;
|
||||||
|
|
||||||
|
#Some error cases
|
||||||
|
--error 1052
|
||||||
insert into t1 select t2.a from t2 on duplicate key update a= a + t2.b;
|
insert into t1 select t2.a from t2 on duplicate key update a= a + t2.b;
|
||||||
select * from t1;
|
--error 1109
|
||||||
drop table t1;
|
insert into t1 select t2.a from t2 on duplicate key update t2.a= a + t2.b;
|
||||||
drop table t2;
|
--error 1109
|
||||||
|
insert into t1 select t2.a from t2 group by t2.a on duplicate key update a= t1.a + t2.b;
|
||||||
|
drop table t1,t2,t3;
|
||||||
|
@@ -72,11 +72,13 @@ CREATE TABLE t2 (a INT, b INT, c INT, d INT);
|
|||||||
# column names deliberately clash with columns in t1 (Bug#8147)
|
# column names deliberately clash with columns in t1 (Bug#8147)
|
||||||
INSERT t2 VALUES (5,6,30,1), (7,4,40,1), (8,9,60,1);
|
INSERT t2 VALUES (5,6,30,1), (7,4,40,1), (8,9,60,1);
|
||||||
INSERT t2 VALUES (2,1,11,2), (7,4,40,2);
|
INSERT t2 VALUES (2,1,11,2), (7,4,40,2);
|
||||||
INSERT t1 SELECT a,b,c FROM t2 WHERE d=1 ON DUPLICATE KEY UPDATE c=c+100;
|
INSERT t1 SELECT a,b,c FROM t2 WHERE d=1 ON DUPLICATE KEY UPDATE c=t1.c+100;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
INSERT t1 SET a=5 ON DUPLICATE KEY UPDATE b=0;
|
INSERT t1 SET a=5 ON DUPLICATE KEY UPDATE b=0;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
|
--error 1052
|
||||||
INSERT t1 SELECT a,b,c FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=c+VALUES(a);
|
INSERT t1 SELECT a,b,c FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=c+VALUES(a);
|
||||||
|
INSERT t1 SELECT a,b,c FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=t1.c+VALUES(t1.a);
|
||||||
SELECT *, VALUES(a) FROM t1;
|
SELECT *, VALUES(a) FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
@@ -89,10 +91,12 @@ create table t1 (a int not null unique) engine=myisam;
|
|||||||
insert into t1 values (1),(2);
|
insert into t1 values (1),(2);
|
||||||
insert ignore into t1 select 1 on duplicate key update a=2;
|
insert ignore into t1 select 1 on duplicate key update a=2;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
insert ignore into t1 select a from t1 on duplicate key update a=a+1 ;
|
insert ignore into t1 select a from t1 as t2 on duplicate key update a=t1.a+1 ;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
insert into t1 select 1 on duplicate key update a=2;
|
insert into t1 select 1 on duplicate key update a=2;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
--error 1062
|
--error 1052
|
||||||
insert into t1 select a from t1 on duplicate key update a=a+1 ;
|
insert into t1 select a from t1 on duplicate key update a=a+1 ;
|
||||||
|
--error 1052
|
||||||
|
insert ignore into t1 select a from t1 on duplicate key update a=t1.a+1 ;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
@@ -10,9 +10,10 @@ show variables like "lower_case_table_names";
|
|||||||
enable_query_log;
|
enable_query_log;
|
||||||
|
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
DROP TABLE IF EXISTS t1,t2,t3;
|
DROP TABLE IF EXISTS t1,t2,t3,t2aA,t1Aa;
|
||||||
DROP DATABASE IF EXISTS `TEST_$1`;
|
DROP DATABASE IF EXISTS `TEST_$1`;
|
||||||
DROP DATABASE IF EXISTS `test_$1`;
|
DROP DATABASE IF EXISTS `test_$1`;
|
||||||
|
DROP DATABASE mysqltest_LC2;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
|
||||||
CREATE TABLE T1 (a int);
|
CREATE TABLE T1 (a int);
|
||||||
|
@@ -98,17 +98,16 @@ int check_if_legal_filename(const char *path)
|
|||||||
|
|
||||||
for (reserved_name= reserved_names; *reserved_name; reserved_name++)
|
for (reserved_name= reserved_names; *reserved_name; reserved_name++)
|
||||||
{
|
{
|
||||||
|
const char *reserved= *reserved_name; /* never empty */
|
||||||
const char *name= path;
|
const char *name= path;
|
||||||
const char *current_reserved_name= *reserved_name;
|
|
||||||
|
|
||||||
while (name != end && *current_reserved_name)
|
do
|
||||||
{
|
{
|
||||||
if (*current_reserved_name != my_toupper(&my_charset_latin1, *name))
|
if (*reserved != my_toupper(&my_charset_latin1, *name))
|
||||||
break;
|
break;
|
||||||
current_reserved_name++;
|
|
||||||
if (++name == end)
|
if (++name == end)
|
||||||
DBUG_RETURN(1); /* Found wrong path */
|
DBUG_RETURN(1); /* Found wrong path */
|
||||||
}
|
} while (*++reserved);
|
||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
@@ -21,25 +21,34 @@
|
|||||||
|
|
||||||
static void make_ftype(my_string to,int flag);
|
static void make_ftype(my_string to,int flag);
|
||||||
|
|
||||||
/* Open a file as stream */
|
/*
|
||||||
|
Open a file as stream
|
||||||
|
|
||||||
FILE *my_fopen(const char *FileName, int Flags, myf MyFlags)
|
SYNOPSIS
|
||||||
/* Path-name of file */
|
my_fopen()
|
||||||
/* Read | write .. */
|
FileName Path-name of file
|
||||||
/* Special flags */
|
Flags Read | write | append | trunc (like for open())
|
||||||
|
MyFlags Flags for handling errors
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 Error
|
||||||
|
# File handler
|
||||||
|
*/
|
||||||
|
|
||||||
|
FILE *my_fopen(const char *filename, int flags, myf MyFlags)
|
||||||
{
|
{
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
char type[5];
|
char type[5];
|
||||||
DBUG_ENTER("my_fopen");
|
DBUG_ENTER("my_fopen");
|
||||||
DBUG_PRINT("my",("Name: '%s' Flags: %d MyFlags: %d",
|
DBUG_PRINT("my",("Name: '%s' flags: %d MyFlags: %d",
|
||||||
FileName, Flags, MyFlags));
|
filename, flags, MyFlags));
|
||||||
/*
|
/*
|
||||||
if we are not creating, then we need to use my_access to make sure
|
if we are not creating, then we need to use my_access to make sure
|
||||||
the file exists since Windows doesn't handle files like "com1.sym"
|
the file exists since Windows doesn't handle files like "com1.sym"
|
||||||
very well
|
very well
|
||||||
*/
|
*/
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
if (check_if_legal_filename(FileName))
|
if (check_if_legal_filename(filename))
|
||||||
{
|
{
|
||||||
errno= EACCES;
|
errno= EACCES;
|
||||||
fd= 0;
|
fd= 0;
|
||||||
@@ -47,8 +56,8 @@ FILE *my_fopen(const char *FileName, int Flags, myf MyFlags)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
make_ftype(type,Flags);
|
make_ftype(type,flags);
|
||||||
fd = fopen(FileName, type);
|
fd = fopen(filename, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd != 0)
|
if (fd != 0)
|
||||||
@@ -65,7 +74,7 @@ FILE *my_fopen(const char *FileName, int Flags, myf MyFlags)
|
|||||||
}
|
}
|
||||||
pthread_mutex_lock(&THR_LOCK_open);
|
pthread_mutex_lock(&THR_LOCK_open);
|
||||||
if ((my_file_info[fileno(fd)].name = (char*)
|
if ((my_file_info[fileno(fd)].name = (char*)
|
||||||
my_strdup(FileName,MyFlags)))
|
my_strdup(filename,MyFlags)))
|
||||||
{
|
{
|
||||||
my_stream_opened++;
|
my_stream_opened++;
|
||||||
my_file_info[fileno(fd)].type = STREAM_BY_FOPEN;
|
my_file_info[fileno(fd)].type = STREAM_BY_FOPEN;
|
||||||
@@ -81,9 +90,9 @@ FILE *my_fopen(const char *FileName, int Flags, myf MyFlags)
|
|||||||
my_errno=errno;
|
my_errno=errno;
|
||||||
DBUG_PRINT("error",("Got error %d on open",my_errno));
|
DBUG_PRINT("error",("Got error %d on open",my_errno));
|
||||||
if (MyFlags & (MY_FFNF | MY_FAE | MY_WME))
|
if (MyFlags & (MY_FFNF | MY_FAE | MY_WME))
|
||||||
my_error((Flags & O_RDONLY) || (Flags == O_RDONLY ) ? EE_FILENOTFOUND :
|
my_error((flags & O_RDONLY) || (flags == O_RDONLY ) ? EE_FILENOTFOUND :
|
||||||
EE_CANTCREATEFILE,
|
EE_CANTCREATEFILE,
|
||||||
MYF(ME_BELL+ME_WAITTANG), FileName,my_errno);
|
MYF(ME_BELL+ME_WAITTANG), filename, my_errno);
|
||||||
DBUG_RETURN((FILE*) 0);
|
DBUG_RETURN((FILE*) 0);
|
||||||
} /* my_fopen */
|
} /* my_fopen */
|
||||||
|
|
||||||
@@ -158,14 +167,24 @@ FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags)
|
|||||||
DBUG_RETURN(fd);
|
DBUG_RETURN(fd);
|
||||||
} /* my_fdopen */
|
} /* my_fdopen */
|
||||||
|
|
||||||
/*
|
|
||||||
make_ftype
|
|
||||||
Make a filehandler-open-typestring from ordinary inputflags
|
|
||||||
|
|
||||||
Note: This routine attempts to find the best possible match
|
/*
|
||||||
|
Make a fopen() typestring from a open() type bitmap
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
make_ftype()
|
||||||
|
to String for fopen() is stored here
|
||||||
|
flag Flag used by open()
|
||||||
|
|
||||||
|
IMPLEMENTATION
|
||||||
|
This routine attempts to find the best possible match
|
||||||
between a numeric option and a string option that could be
|
between a numeric option and a string option that could be
|
||||||
fed to fopen. There is not a 1 to 1 mapping between the two.
|
fed to fopen. There is not a 1 to 1 mapping between the two.
|
||||||
|
|
||||||
|
NOTE
|
||||||
|
On Unix, O_RDONLY is usually 0
|
||||||
|
|
||||||
|
MAPPING
|
||||||
r == O_RDONLY
|
r == O_RDONLY
|
||||||
w == O_WRONLY|O_TRUNC|O_CREAT
|
w == O_WRONLY|O_TRUNC|O_CREAT
|
||||||
a == O_WRONLY|O_APPEND|O_CREAT
|
a == O_WRONLY|O_APPEND|O_CREAT
|
||||||
@@ -173,18 +192,14 @@ FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags)
|
|||||||
w+ == O_RDWR|O_TRUNC|O_CREAT
|
w+ == O_RDWR|O_TRUNC|O_CREAT
|
||||||
a+ == O_RDWR|O_APPEND|O_CREAT
|
a+ == O_RDWR|O_APPEND|O_CREAT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void make_ftype(register my_string to, register int flag)
|
static void make_ftype(register my_string to, register int flag)
|
||||||
{
|
{
|
||||||
#if FILE_BINARY
|
|
||||||
/* If we have binary-files */
|
|
||||||
reg3 int org_flag=flag;
|
|
||||||
#endif
|
|
||||||
flag&= ~FILE_BINARY; /* remove binary bit */
|
|
||||||
|
|
||||||
/* check some possible invalid combinations */
|
/* check some possible invalid combinations */
|
||||||
DBUG_ASSERT(flag & (O_TRUNC|O_APPEND) != O_TRUNC|O_APPEND);
|
DBUG_ASSERT((flag & (O_TRUNC | O_APPEND)) != (O_TRUNC | O_APPEND));
|
||||||
|
DBUG_ASSERT((flag & (O_WRONLY | O_RDWR)) != (O_WRONLY | O_RDWR));
|
||||||
|
|
||||||
if (flag & (O_RDONLY|O_WRONLY) == O_WRONLY)
|
if ((flag & (O_RDONLY|O_WRONLY)) == O_WRONLY)
|
||||||
*to++= (flag & O_APPEND) ? 'a' : 'w';
|
*to++= (flag & O_APPEND) ? 'a' : 'w';
|
||||||
else if (flag & O_RDWR)
|
else if (flag & O_RDWR)
|
||||||
{
|
{
|
||||||
@@ -201,9 +216,8 @@ static void make_ftype(register my_string to, register int flag)
|
|||||||
*to++= 'r';
|
*to++= 'r';
|
||||||
|
|
||||||
#if FILE_BINARY /* If we have binary-files */
|
#if FILE_BINARY /* If we have binary-files */
|
||||||
if (org_flag & FILE_BINARY)
|
if (flag & FILE_BINARY)
|
||||||
*to++='b';
|
*to++='b';
|
||||||
#endif
|
#endif
|
||||||
*to='\0';
|
*to='\0';
|
||||||
} /* make_ftype */
|
} /* make_ftype */
|
||||||
|
|
||||||
|
@@ -1053,6 +1053,7 @@ void Field_str::make_field(Send_field *field)
|
|||||||
|
|
||||||
uint Field::fill_cache_field(CACHE_FIELD *copy)
|
uint Field::fill_cache_field(CACHE_FIELD *copy)
|
||||||
{
|
{
|
||||||
|
uint store_length;
|
||||||
copy->str=ptr;
|
copy->str=ptr;
|
||||||
copy->length=pack_length();
|
copy->length=pack_length();
|
||||||
copy->blob_field=0;
|
copy->blob_field=0;
|
||||||
@@ -1065,10 +1066,16 @@ uint Field::fill_cache_field(CACHE_FIELD *copy)
|
|||||||
}
|
}
|
||||||
else if (!zero_pack() && (type() == FIELD_TYPE_STRING && copy->length > 4 ||
|
else if (!zero_pack() && (type() == FIELD_TYPE_STRING && copy->length > 4 ||
|
||||||
type() == FIELD_TYPE_VAR_STRING))
|
type() == FIELD_TYPE_VAR_STRING))
|
||||||
|
{
|
||||||
copy->strip=1; /* Remove end space */
|
copy->strip=1; /* Remove end space */
|
||||||
|
store_length= 2;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
copy->strip=0;
|
copy->strip=0;
|
||||||
return copy->length+(int) copy->strip;
|
store_length= 0;
|
||||||
|
}
|
||||||
|
return copy->length+ store_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -439,9 +439,11 @@ int ha_ndbcluster::ndb_err(NdbConnection *trans)
|
|||||||
if (m_rows_to_insert == 1)
|
if (m_rows_to_insert == 1)
|
||||||
m_dupkey= table->primary_key;
|
m_dupkey= table->primary_key;
|
||||||
else
|
else
|
||||||
// We are batching inserts, offending key is not available
|
{
|
||||||
|
/* We are batching inserts, offending key is not available */
|
||||||
m_dupkey= (uint) -1;
|
m_dupkey= (uint) -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -65,7 +65,6 @@ Item::Item():
|
|||||||
place == IN_HAVING)
|
place == IN_HAVING)
|
||||||
thd->lex->current_select->select_n_having_items++;
|
thd->lex->current_select->select_n_having_items++;
|
||||||
}
|
}
|
||||||
item_flags= 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -84,8 +83,7 @@ Item::Item(THD *thd, Item *item):
|
|||||||
unsigned_flag(item->unsigned_flag),
|
unsigned_flag(item->unsigned_flag),
|
||||||
with_sum_func(item->with_sum_func),
|
with_sum_func(item->with_sum_func),
|
||||||
fixed(item->fixed),
|
fixed(item->fixed),
|
||||||
collation(item->collation),
|
collation(item->collation)
|
||||||
item_flags(item->item_flags)
|
|
||||||
{
|
{
|
||||||
next= thd->free_list; // Put in free list
|
next= thd->free_list; // Put in free list
|
||||||
thd->free_list= this;
|
thd->free_list= this;
|
||||||
|
11
sql/item.h
11
sql/item.h
@@ -107,11 +107,6 @@ public:
|
|||||||
|
|
||||||
typedef bool (Item::*Item_processor)(byte *arg);
|
typedef bool (Item::*Item_processor)(byte *arg);
|
||||||
|
|
||||||
/*
|
|
||||||
See comments for sql_yacc.yy: insert_update_elem rule
|
|
||||||
*/
|
|
||||||
#define MY_ITEM_PREFER_1ST_TABLE 1
|
|
||||||
|
|
||||||
class Item {
|
class Item {
|
||||||
Item(const Item &); /* Prevent use of these */
|
Item(const Item &); /* Prevent use of these */
|
||||||
void operator=(Item &);
|
void operator=(Item &);
|
||||||
@@ -147,7 +142,6 @@ public:
|
|||||||
my_bool with_sum_func;
|
my_bool with_sum_func;
|
||||||
my_bool fixed; /* If item fixed with fix_fields */
|
my_bool fixed; /* If item fixed with fix_fields */
|
||||||
DTCollation collation;
|
DTCollation collation;
|
||||||
uint8 item_flags; /* Flags on how item should be processed */
|
|
||||||
|
|
||||||
// alloc & destruct is done as start of select using sql_alloc
|
// alloc & destruct is done as start of select using sql_alloc
|
||||||
Item();
|
Item();
|
||||||
@@ -333,11 +327,6 @@ public:
|
|||||||
cleanup();
|
cleanup();
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
virtual bool set_flags_processor(byte *args)
|
|
||||||
{
|
|
||||||
this->item_flags|= *((uint8*)args);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -576,7 +576,8 @@ int mysql_multi_update_lock(THD *thd,
|
|||||||
List<Item> *fields,
|
List<Item> *fields,
|
||||||
SELECT_LEX *select_lex);
|
SELECT_LEX *select_lex);
|
||||||
int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
|
int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
|
||||||
TABLE_LIST *insert_table_list, TABLE *table,
|
TABLE_LIST *insert_table_list,
|
||||||
|
TABLE_LIST *dup_table_list, TABLE *table,
|
||||||
List<Item> &fields, List_item *values,
|
List<Item> &fields, List_item *values,
|
||||||
List<Item> &update_fields,
|
List<Item> &update_fields,
|
||||||
List<Item> &update_values, enum_duplicates duplic);
|
List<Item> &update_values, enum_duplicates duplic);
|
||||||
|
@@ -6098,9 +6098,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
|||||||
case (int) OPT_SLOW_QUERY_LOG:
|
case (int) OPT_SLOW_QUERY_LOG:
|
||||||
opt_slow_log=1;
|
opt_slow_log=1;
|
||||||
break;
|
break;
|
||||||
case (int) OPT_LOG_SLOW_ADMIN_STATEMENTS:
|
|
||||||
opt_log_slow_admin_statements= 1;
|
|
||||||
break;
|
|
||||||
case (int) OPT_SKIP_NEW:
|
case (int) OPT_SKIP_NEW:
|
||||||
opt_specialflag|= SPECIAL_NO_NEW_FUNC;
|
opt_specialflag|= SPECIAL_NO_NEW_FUNC;
|
||||||
delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
|
delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
|
||||||
|
@@ -1516,7 +1516,7 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
|
|||||||
{
|
{
|
||||||
if (!(res= var->value->val_str(&str)))
|
if (!(res= var->value->val_str(&str)))
|
||||||
{
|
{
|
||||||
strmake(buff, "NULL", 4);
|
strmov(buff, "NULL");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
var->save_result.ulong_value= ((ulong)
|
var->save_result.ulong_value= ((ulong)
|
||||||
|
@@ -2003,7 +2003,7 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
|||||||
const char *name=item->field_name;
|
const char *name=item->field_name;
|
||||||
uint length=(uint) strlen(name);
|
uint length=(uint) strlen(name);
|
||||||
char name_buff[NAME_LEN+1];
|
char name_buff[NAME_LEN+1];
|
||||||
|
bool allow_rowid;
|
||||||
|
|
||||||
if (item->cached_table)
|
if (item->cached_table)
|
||||||
{
|
{
|
||||||
@@ -2095,9 +2095,8 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
|||||||
return (Field*) not_found_field;
|
return (Field*) not_found_field;
|
||||||
return (Field*) 0;
|
return (Field*) 0;
|
||||||
}
|
}
|
||||||
bool allow_rowid= tables && !tables->next; // Only one table
|
allow_rowid= tables && !tables->next; // Only one table
|
||||||
uint table_idx= 0;
|
for (; tables ; tables=tables->next)
|
||||||
for (; tables ; tables=tables->next, table_idx++)
|
|
||||||
{
|
{
|
||||||
if (!tables->table)
|
if (!tables->table)
|
||||||
{
|
{
|
||||||
@@ -2126,8 +2125,6 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
|||||||
return (Field*) 0;
|
return (Field*) 0;
|
||||||
}
|
}
|
||||||
found= field;
|
found= field;
|
||||||
if (table_idx == 0 && item->item_flags & MY_ITEM_PREFER_1ST_TABLE)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (found)
|
if (found)
|
||||||
|
@@ -271,7 +271,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
thd->used_tables=0;
|
thd->used_tables=0;
|
||||||
values= its++;
|
values= its++;
|
||||||
|
|
||||||
if (mysql_prepare_insert(thd, table_list, insert_table_list, table,
|
if (mysql_prepare_insert(thd, table_list, insert_table_list,
|
||||||
|
insert_table_list, table,
|
||||||
fields, values, update_fields,
|
fields, values, update_fields,
|
||||||
update_values, duplic))
|
update_values, duplic))
|
||||||
goto abort;
|
goto abort;
|
||||||
@@ -499,22 +500,37 @@ abort:
|
|||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
mysql_prepare_insert()
|
mysql_prepare_insert()
|
||||||
thd - thread handler
|
thd thread handler
|
||||||
table_list - global table list
|
table_list global table list (not including first table for
|
||||||
insert_table_list - local table list of INSERT SELECT_LEX
|
INSERT ... SELECT)
|
||||||
values - values to insert. NULL for INSERT ... SELECT
|
insert_table_list Table we are inserting into (for INSERT ... SELECT)
|
||||||
|
dup_table_list Tables to be used in ON DUPLICATE KEY
|
||||||
|
It's either all global tables or only the table we
|
||||||
|
insert into, depending on if we are using GROUP BY
|
||||||
|
in the SELECT clause).
|
||||||
|
values Values to insert. NULL for INSERT ... SELECT
|
||||||
|
|
||||||
|
TODO (in far future)
|
||||||
|
In cases of:
|
||||||
|
INSERT INTO t1 SELECT a, sum(a) as sum1 from t2 GROUP BY a
|
||||||
|
ON DUPLICATE KEY ...
|
||||||
|
we should be able to refer to sum1 in the ON DUPLICATE KEY part
|
||||||
|
|
||||||
RETURN VALUE
|
RETURN VALUE
|
||||||
0 - OK
|
0 OK
|
||||||
-1 - error (message is not sent to user)
|
-1 error (message is not sent to user)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
|
int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
|
||||||
TABLE_LIST *insert_table_list, TABLE *table,
|
TABLE_LIST *insert_table_list,
|
||||||
|
TABLE_LIST *dup_table_list,
|
||||||
|
TABLE *table,
|
||||||
List<Item> &fields, List_item *values,
|
List<Item> &fields, List_item *values,
|
||||||
List<Item> &update_fields, List<Item> &update_values,
|
List<Item> &update_fields, List<Item> &update_values,
|
||||||
enum_duplicates duplic)
|
enum_duplicates duplic)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("mysql_prepare_insert");
|
DBUG_ENTER("mysql_prepare_insert");
|
||||||
|
|
||||||
if (duplic == DUP_UPDATE && !table->insert_values)
|
if (duplic == DUP_UPDATE && !table->insert_values)
|
||||||
{
|
{
|
||||||
/* it should be allocated before Item::fix_fields() */
|
/* it should be allocated before Item::fix_fields() */
|
||||||
@@ -528,7 +544,7 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
|
|||||||
(values && setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0)) ||
|
(values && setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0)) ||
|
||||||
(duplic == DUP_UPDATE &&
|
(duplic == DUP_UPDATE &&
|
||||||
(check_update_fields(thd, table, insert_table_list, update_fields) ||
|
(check_update_fields(thd, table, insert_table_list, update_fields) ||
|
||||||
setup_fields(thd, 0, insert_table_list, update_values, 1, 0, 0))))
|
setup_fields(thd, 0, dup_table_list, update_values, 1, 0, 0))))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
if (values && find_real_table_in_list(table_list->next, table_list->db,
|
if (values && find_real_table_in_list(table_list->next, table_list->db,
|
||||||
table_list->real_name))
|
table_list->real_name))
|
||||||
|
@@ -2831,6 +2831,8 @@ unsent_create_error:
|
|||||||
case SQLCOM_INSERT_SELECT:
|
case SQLCOM_INSERT_SELECT:
|
||||||
{
|
{
|
||||||
TABLE_LIST *first_local_table= (TABLE_LIST *) select_lex->table_list.first;
|
TABLE_LIST *first_local_table= (TABLE_LIST *) select_lex->table_list.first;
|
||||||
|
TABLE_LIST dup_tables;
|
||||||
|
TABLE *insert_table;
|
||||||
if ((res= insert_precheck(thd, tables)))
|
if ((res= insert_precheck(thd, tables)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -2856,14 +2858,27 @@ unsent_create_error:
|
|||||||
if ((res= open_and_lock_tables(thd, tables)))
|
if ((res= open_and_lock_tables(thd, tables)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
insert_table= tables->table;
|
||||||
/* Skip first table, which is the table we are inserting in */
|
/* Skip first table, which is the table we are inserting in */
|
||||||
select_lex->table_list.first= (byte*) first_local_table->next;
|
select_lex->table_list.first= (byte*) first_local_table->next;
|
||||||
|
tables= (TABLE_LIST *) select_lex->table_list.first;
|
||||||
|
dup_tables= *first_local_table;
|
||||||
|
first_local_table->next= 0;
|
||||||
|
if (select_lex->group_list.elements != 0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
When we are using GROUP BY we can't refere to other tables in the
|
||||||
|
ON DUPLICATE KEY part
|
||||||
|
*/
|
||||||
|
dup_tables.next= 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(res= mysql_prepare_insert(thd, tables, first_local_table,
|
if (!(res= mysql_prepare_insert(thd, tables, first_local_table,
|
||||||
tables->table, lex->field_list, 0,
|
&dup_tables, insert_table,
|
||||||
|
lex->field_list, 0,
|
||||||
lex->update_list, lex->value_list,
|
lex->update_list, lex->value_list,
|
||||||
lex->duplicates)) &&
|
lex->duplicates)) &&
|
||||||
(result= new select_insert(tables->table, &lex->field_list,
|
(result= new select_insert(insert_table, &lex->field_list,
|
||||||
&lex->update_list, &lex->value_list,
|
&lex->update_list, &lex->value_list,
|
||||||
lex->duplicates, lex->ignore)))
|
lex->duplicates, lex->ignore)))
|
||||||
{
|
{
|
||||||
@@ -2876,7 +2891,7 @@ unsent_create_error:
|
|||||||
/* revert changes for SP */
|
/* revert changes for SP */
|
||||||
lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE;
|
lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE;
|
||||||
delete result;
|
delete result;
|
||||||
tables->table->insert_values= 0;
|
insert_table->insert_values= 0;
|
||||||
if (thd->net.report_error)
|
if (thd->net.report_error)
|
||||||
res= -1;
|
res= -1;
|
||||||
}
|
}
|
||||||
@@ -4950,9 +4965,10 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Writing this command to the binlog may result in infinite loops when doing
|
Writing this command to the binlog may result in infinite loops when
|
||||||
mysqlbinlog|mysql, and anyway it does not really make sense to log it
|
doing mysqlbinlog|mysql, and anyway it does not really make sense to
|
||||||
automatically (would cause more trouble to users than it would help them)
|
log it automatically (would cause more trouble to users than it would
|
||||||
|
help them)
|
||||||
*/
|
*/
|
||||||
tmp_write_to_binlog= 0;
|
tmp_write_to_binlog= 0;
|
||||||
mysql_log.new_file(1);
|
mysql_log.new_file(1);
|
||||||
|
@@ -918,6 +918,7 @@ static int mysql_test_insert(Prepared_statement *stmt,
|
|||||||
|
|
||||||
table_list->table->insert_values=(byte *)1; // don't allocate insert_values
|
table_list->table->insert_values=(byte *)1; // don't allocate insert_values
|
||||||
if ((res= mysql_prepare_insert(thd, table_list, insert_table_list,
|
if ((res= mysql_prepare_insert(thd, table_list, insert_table_list,
|
||||||
|
insert_table_list,
|
||||||
table_list->table, fields, values,
|
table_list->table, fields, values,
|
||||||
update_fields, update_values, duplic)))
|
update_fields, update_values, duplic)))
|
||||||
goto error;
|
goto error;
|
||||||
|
@@ -28,8 +28,6 @@
|
|||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
#include <ft_global.h>
|
#include <ft_global.h>
|
||||||
|
|
||||||
typedef uint32 cache_rec_length_type;
|
|
||||||
|
|
||||||
const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
|
const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
|
||||||
"MAYBE_REF","ALL","range","index","fulltext",
|
"MAYBE_REF","ALL","range","index","fulltext",
|
||||||
"ref_or_null","unique_subquery","index_subquery"
|
"ref_or_null","unique_subquery","index_subquery"
|
||||||
@@ -8074,7 +8072,7 @@ used_blob_length(CACHE_FIELD **ptr)
|
|||||||
static bool
|
static bool
|
||||||
store_record_in_cache(JOIN_CACHE *cache)
|
store_record_in_cache(JOIN_CACHE *cache)
|
||||||
{
|
{
|
||||||
cache_rec_length_type length;
|
uint length;
|
||||||
uchar *pos;
|
uchar *pos;
|
||||||
CACHE_FIELD *copy,*end_field;
|
CACHE_FIELD *copy,*end_field;
|
||||||
bool last_record;
|
bool last_record;
|
||||||
@@ -8119,9 +8117,9 @@ store_record_in_cache(JOIN_CACHE *cache)
|
|||||||
end > str && end[-1] == ' ' ;
|
end > str && end[-1] == ' ' ;
|
||||||
end--) ;
|
end--) ;
|
||||||
length=(uint) (end-str);
|
length=(uint) (end-str);
|
||||||
memcpy(pos+sizeof(length), str, length);
|
memcpy(pos+2, str, length);
|
||||||
memcpy_fixed(pos, &length, sizeof(length));
|
int2store(pos, length);
|
||||||
pos+= length+sizeof(length);
|
pos+= length+2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -8155,7 +8153,7 @@ static void
|
|||||||
read_cached_record(JOIN_TAB *tab)
|
read_cached_record(JOIN_TAB *tab)
|
||||||
{
|
{
|
||||||
uchar *pos;
|
uchar *pos;
|
||||||
cache_rec_length_type length;
|
uint length;
|
||||||
bool last_record;
|
bool last_record;
|
||||||
CACHE_FIELD *copy,*end_field;
|
CACHE_FIELD *copy,*end_field;
|
||||||
|
|
||||||
@@ -8184,10 +8182,10 @@ read_cached_record(JOIN_TAB *tab)
|
|||||||
{
|
{
|
||||||
if (copy->strip)
|
if (copy->strip)
|
||||||
{
|
{
|
||||||
memcpy_fixed(&length, pos, sizeof(length));
|
length= uint2korr(pos);
|
||||||
memcpy(copy->str, pos+sizeof(length), length);
|
memcpy(copy->str, pos+2, length);
|
||||||
memset(copy->str+length, ' ', copy->length-length);
|
memset(copy->str+length, ' ', copy->length-length);
|
||||||
pos+= sizeof(length)+length;
|
pos+= 2 + length;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -4239,24 +4239,9 @@ insert_update_elem:
|
|||||||
simple_ident equal expr_or_default
|
simple_ident equal expr_or_default
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
uint8 tmp= MY_ITEM_PREFER_1ST_TABLE;
|
|
||||||
if (lex->update_list.push_back($1) ||
|
if (lex->update_list.push_back($1) ||
|
||||||
lex->value_list.push_back($3))
|
lex->value_list.push_back($3))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
/*
|
|
||||||
INSERT INTO a1(a) SELECT b1.a FROM b1 ON DUPLICATE KEY
|
|
||||||
UPDATE a= a + b1.b
|
|
||||||
|
|
||||||
Set MY_ITEM_PREFER_1ST_TABLE flag to $1 and $3 items
|
|
||||||
to prevent find_field_in_tables() doing further item searching
|
|
||||||
if it finds item occurence in first table in insert_table_list.
|
|
||||||
This allows to avoid ambiguity in resolving 'a' field in
|
|
||||||
example above.
|
|
||||||
*/
|
|
||||||
$1->walk(&Item::set_flags_processor,
|
|
||||||
(byte *) &tmp);
|
|
||||||
$3->walk(&Item::set_flags_processor,
|
|
||||||
(byte *) &tmp);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
opt_low_priority:
|
opt_low_priority:
|
||||||
|
Reference in New Issue
Block a user