Commit 078919ad authored by unknown's avatar unknown

Merge mysql.com:/home/pem/work/mysql-4.1

into mysql.com:/home/pem/work/mysql-5.0-merge


client/mysql.cc:
  Auto merged
libmysql/libmysql.c:
  Auto merged
libmysqld/lib_sql.cc:
  Auto merged
mysql-test/r/mysqldump.result:
  Auto merged
mysql-test/r/show_check.result:
  Auto merged
sql/item.cc:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/sql_class.h:
  Auto merged
sql/sql_lex.cc:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql-common/client.c:
  Auto merged
sql/sql_prepare.cc:
  Auto merged
sql/sql_show.cc:
  Auto merged
sql/sql_table.cc:
  Auto merged
sql/sql_yacc.yy:
  Auto merged
tests/client_test.c:
  Auto merged
parents b5c8de4c 9a3a0d7d
...@@ -839,7 +839,9 @@ static int get_options(int argc, char **argv) ...@@ -839,7 +839,9 @@ static int get_options(int argc, char **argv)
opt_reconnect= 0; opt_reconnect= 0;
connect_flag= 0; /* Not in interactive mode */ connect_flag= 0; /* Not in interactive mode */
} }
if (!(charset_info= get_charset_by_csname(default_charset,
if (strcmp(default_charset, charset_info->csname) &&
!(charset_info= get_charset_by_csname(default_charset,
MY_CS_PRIMARY, MYF(MY_WME)))) MY_CS_PRIMARY, MYF(MY_WME))))
exit(1); exit(1);
if (argc > 1) if (argc > 1)
......
...@@ -311,7 +311,8 @@ static int get_options(int *argc, char ***argv) ...@@ -311,7 +311,8 @@ static int get_options(int *argc, char ***argv)
} }
/* TODO: This variable is not yet used */ /* TODO: This variable is not yet used */
if (!(charset_info= get_charset_by_csname(default_charset, if (strcmp(default_charset, charset_info->csname) &&
!(charset_info= get_charset_by_csname(default_charset,
MY_CS_PRIMARY, MYF(MY_WME)))) MY_CS_PRIMARY, MYF(MY_WME))))
exit(1); exit(1);
if (*argc > 0 && opt_alldbs) if (*argc > 0 && opt_alldbs)
......
...@@ -536,7 +536,8 @@ static int get_options(int *argc, char ***argv) ...@@ -536,7 +536,8 @@ static int get_options(int *argc, char ***argv)
my_progname); my_progname);
return(1); return(1);
} }
if (!(charset_info= get_charset_by_csname(default_charset, if (strcmp(default_charset, charset_info->csname) &&
!(charset_info= get_charset_by_csname(default_charset,
MY_CS_PRIMARY, MYF(MY_WME)))) MY_CS_PRIMARY, MYF(MY_WME))))
exit(1); exit(1);
if ((*argc < 1 && !opt_alldbs) || (*argc > 0 && opt_alldbs)) if ((*argc < 1 && !opt_alldbs) || (*argc > 0 && opt_alldbs))
......
...@@ -238,7 +238,8 @@ static int get_options(int *argc, char ***argv) ...@@ -238,7 +238,8 @@ static int get_options(int *argc, char ***argv)
fprintf(stderr, "You can't use --ignore (-i) and --replace (-r) at the same time.\n"); fprintf(stderr, "You can't use --ignore (-i) and --replace (-r) at the same time.\n");
return(1); return(1);
} }
if (!(charset_info= get_charset_by_csname(default_charset, if (strcmp(default_charset, charset_info->csname) &&
!(charset_info= get_charset_by_csname(default_charset,
MY_CS_PRIMARY, MYF(MY_WME)))) MY_CS_PRIMARY, MYF(MY_WME))))
exit(1); exit(1);
if (*argc < 2) if (*argc < 2)
......
...@@ -57,9 +57,6 @@ typedef int my_socket; ...@@ -57,9 +57,6 @@ typedef int my_socket;
#include "mysql_com.h" #include "mysql_com.h"
#include "mysql_version.h" #include "mysql_version.h"
#include "typelib.h" #include "typelib.h"
#ifndef DBUG_OFF
#define CHECK_EXTRA_ARGUMENTS
#endif
#include "my_list.h" /* for LISTs used in 'MYSQL' and 'MYSQL_STMT' */ #include "my_list.h" /* for LISTs used in 'MYSQL' and 'MYSQL_STMT' */
...@@ -537,6 +534,8 @@ typedef struct st_mysql_stmt ...@@ -537,6 +534,8 @@ typedef struct st_mysql_stmt
char *query; /* query buffer */ char *query; /* query buffer */
MEM_ROOT mem_root; /* root allocations */ MEM_ROOT mem_root; /* root allocations */
my_ulonglong last_fetched_column; /* last fetched column */ my_ulonglong last_fetched_column; /* last fetched column */
my_ulonglong affected_rows; /* copy of mysql->affected_rows
after statement execution */
unsigned long stmt_id; /* Id for prepared statement */ unsigned long stmt_id; /* Id for prepared statement */
unsigned int last_errno; /* error code */ unsigned int last_errno; /* error code */
unsigned int param_count; /* parameters count */ unsigned int param_count; /* parameters count */
...@@ -575,6 +574,7 @@ typedef struct st_mysql_methods ...@@ -575,6 +574,7 @@ typedef struct st_mysql_methods
int (*unbuffered_fetch)(MYSQL *mysql, char **row); int (*unbuffered_fetch)(MYSQL *mysql, char **row);
void (*free_embedded_thd)(MYSQL *mysql); void (*free_embedded_thd)(MYSQL *mysql);
const char *(*read_statistic)(MYSQL *mysql); const char *(*read_statistic)(MYSQL *mysql);
int (*next_result)(MYSQL *mysql);
#endif #endif
} MYSQL_METHODS; } MYSQL_METHODS;
......
...@@ -1653,14 +1653,6 @@ mysql_prepare(MYSQL *mysql, const char *query, ulong length) ...@@ -1653,14 +1653,6 @@ mysql_prepare(MYSQL *mysql, const char *query, ulong length)
DBUG_ENTER("mysql_prepare"); DBUG_ENTER("mysql_prepare");
DBUG_ASSERT(mysql != 0); DBUG_ASSERT(mysql != 0);
#ifdef CHECK_EXTRA_ARGUMENTS
if (!query)
{
set_mysql_error(mysql, CR_NULL_POINTER, unknown_sqlstate);
DBUG_RETURN(0);
}
#endif
if (!(stmt= (MYSQL_STMT *) my_malloc(sizeof(MYSQL_STMT), if (!(stmt= (MYSQL_STMT *) my_malloc(sizeof(MYSQL_STMT),
MYF(MY_WME | MY_ZEROFILL))) || MYF(MY_WME | MY_ZEROFILL))) ||
!(stmt->query= my_strdup_with_length((byte *) query, length, MYF(0)))) !(stmt->query= my_strdup_with_length((byte *) query, length, MYF(0))))
...@@ -2018,6 +2010,7 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length) ...@@ -2018,6 +2010,7 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length)
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
stmt->affected_rows= mysql->affected_rows;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -2086,19 +2079,6 @@ int STDCALL mysql_execute(MYSQL_STMT *stmt) ...@@ -2086,19 +2079,6 @@ int STDCALL mysql_execute(MYSQL_STMT *stmt)
{ {
DBUG_ENTER("mysql_execute"); DBUG_ENTER("mysql_execute");
if (stmt->state == MY_ST_UNKNOWN)
{
set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate);
DBUG_RETURN(1);
}
#ifdef CHECK_EXTRA_ARGUMENTS
if (stmt->param_count && !stmt->param_buffers)
{
/* Parameters exists, but no bound buffers */
set_stmt_error(stmt, CR_NOT_ALL_PARAMS_BOUND, unknown_sqlstate);
DBUG_RETURN(1);
}
#endif
if ((*stmt->mysql->methods->stmt_execute)(stmt)) if ((*stmt->mysql->methods->stmt_execute)(stmt))
DBUG_RETURN(1); DBUG_RETURN(1);
...@@ -2127,7 +2107,7 @@ ulong STDCALL mysql_param_count(MYSQL_STMT * stmt) ...@@ -2127,7 +2107,7 @@ ulong STDCALL mysql_param_count(MYSQL_STMT * stmt)
my_ulonglong STDCALL mysql_stmt_affected_rows(MYSQL_STMT *stmt) my_ulonglong STDCALL mysql_stmt_affected_rows(MYSQL_STMT *stmt)
{ {
return stmt->mysql->last_used_con->affected_rows; return stmt->affected_rows;
} }
...@@ -2144,19 +2124,6 @@ my_bool STDCALL mysql_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind) ...@@ -2144,19 +2124,6 @@ my_bool STDCALL mysql_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind)
MYSQL_BIND *param, *end; MYSQL_BIND *param, *end;
DBUG_ENTER("mysql_bind_param"); DBUG_ENTER("mysql_bind_param");
#ifdef CHECK_EXTRA_ARGUMENTS
if (stmt->state == MY_ST_UNKNOWN)
{
set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate);
DBUG_RETURN(1);
}
if (!stmt->param_count)
{
set_stmt_error(stmt, CR_NO_PARAMETERS_EXISTS, unknown_sqlstate);
DBUG_RETURN(1);
}
#endif
/* Allocated on prepare */ /* Allocated on prepare */
memcpy((char*) stmt->params, (char*) bind, memcpy((char*) stmt->params, (char*) bind,
sizeof(MYSQL_BIND) * stmt->param_count); sizeof(MYSQL_BIND) * stmt->param_count);
...@@ -2279,11 +2246,6 @@ mysql_send_long_data(MYSQL_STMT *stmt, uint param_number, ...@@ -2279,11 +2246,6 @@ mysql_send_long_data(MYSQL_STMT *stmt, uint param_number,
DBUG_PRINT("enter",("param no : %d, data : %lx, length : %ld", DBUG_PRINT("enter",("param no : %d, data : %lx, length : %ld",
param_number, data, length)); param_number, data, length));
if (param_number >= stmt->param_count)
{
set_stmt_error(stmt, CR_INVALID_PARAMETER_NO, unknown_sqlstate);
DBUG_RETURN(1);
}
param= stmt->params+param_number; param= stmt->params+param_number;
if (param->buffer_type < MYSQL_TYPE_TINY_BLOB || if (param->buffer_type < MYSQL_TYPE_TINY_BLOB ||
param->buffer_type > MYSQL_TYPE_STRING) param->buffer_type > MYSQL_TYPE_STRING)
...@@ -2853,18 +2815,6 @@ my_bool STDCALL mysql_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind) ...@@ -2853,18 +2815,6 @@ my_bool STDCALL mysql_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
DBUG_ENTER("mysql_bind_result"); DBUG_ENTER("mysql_bind_result");
DBUG_ASSERT(stmt != 0); DBUG_ASSERT(stmt != 0);
#ifdef CHECK_EXTRA_ARGUMENTS
if (stmt->state == MY_ST_UNKNOWN)
{
set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate);
DBUG_RETURN(1);
}
if (!bind)
{
set_stmt_error(stmt, CR_NULL_POINTER, unknown_sqlstate);
DBUG_RETURN(1);
}
#endif
if (!(bind_count= stmt->field_count) && if (!(bind_count= stmt->field_count) &&
!(bind_count= alloc_stmt_fields(stmt))) !(bind_count= alloc_stmt_fields(stmt)))
DBUG_RETURN(0); DBUG_RETURN(0);
...@@ -3035,6 +2985,15 @@ int STDCALL mysql_fetch(MYSQL_STMT *stmt) ...@@ -3035,6 +2985,15 @@ int STDCALL mysql_fetch(MYSQL_STMT *stmt)
} }
else /* un-buffered */ else /* un-buffered */
{ {
if (mysql->status != MYSQL_STATUS_GET_RESULT)
{
if (!stmt->field_count)
goto no_data;
set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
DBUG_RETURN(1);
}
if((*mysql->methods->unbuffered_fetch)(mysql, ( char **)&row)) if((*mysql->methods->unbuffered_fetch)(mysql, ( char **)&row))
{ {
set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno, set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
...@@ -3065,7 +3024,7 @@ int STDCALL mysql_fetch(MYSQL_STMT *stmt) ...@@ -3065,7 +3024,7 @@ int STDCALL mysql_fetch(MYSQL_STMT *stmt)
mysql_fetch_column() mysql_fetch_column()
stmt Prepared statement handler stmt Prepared statement handler
bind Where data should be placed. Should be filled in as bind Where data should be placed. Should be filled in as
when calling mysql_bind_param() when calling mysql_bind_result()
column Column to fetch (first column is 0) column Column to fetch (first column is 0)
ulong offset Offset in result data (to fetch blob in pieces) ulong offset Offset in result data (to fetch blob in pieces)
This is normally 0 This is normally 0
...@@ -3083,14 +3042,6 @@ int STDCALL mysql_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind, ...@@ -3083,14 +3042,6 @@ int STDCALL mysql_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind,
if (!stmt->current_row) if (!stmt->current_row)
goto no_data; goto no_data;
#ifdef CHECK_EXTRA_ARGUMENTS
if (column >= stmt->field_count)
{
set_stmt_errmsg(stmt, "Invalid column descriptor",1, unknown_sqlstate);
DBUG_RETURN(1);
}
#endif
if (param->null_field) if (param->null_field)
{ {
if (bind->is_null) if (bind->is_null)
...@@ -3224,6 +3175,7 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt) ...@@ -3224,6 +3175,7 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
mysql->affected_rows= result->row_count= result->data->rows; mysql->affected_rows= result->row_count= result->data->rows;
stmt->affected_rows= result->row_count;
result->data_cursor= result->data->data; result->data_cursor= result->data->data;
result->fields= stmt->fields; result->fields= stmt->fields;
result->field_count= stmt->field_count; result->field_count= stmt->field_count;
...@@ -3511,7 +3463,6 @@ my_bool STDCALL mysql_more_results(MYSQL *mysql) ...@@ -3511,7 +3463,6 @@ my_bool STDCALL mysql_more_results(MYSQL *mysql)
/* /*
Reads and returns the next query results Reads and returns the next query results
*/ */
int STDCALL mysql_next_result(MYSQL *mysql) int STDCALL mysql_next_result(MYSQL *mysql)
{ {
DBUG_ENTER("mysql_next_result"); DBUG_ENTER("mysql_next_result");
...@@ -3530,7 +3481,7 @@ int STDCALL mysql_next_result(MYSQL *mysql) ...@@ -3530,7 +3481,7 @@ int STDCALL mysql_next_result(MYSQL *mysql)
mysql->affected_rows= ~(my_ulonglong) 0; mysql->affected_rows= ~(my_ulonglong) 0;
if (mysql->last_used_con->server_status & SERVER_MORE_RESULTS_EXISTS) if (mysql->last_used_con->server_status & SERVER_MORE_RESULTS_EXISTS)
DBUG_RETURN((*mysql->methods->read_query_result)(mysql)); DBUG_RETURN((*mysql->methods->next_result)(mysql));
DBUG_RETURN(-1); /* No more results */ DBUG_RETURN(-1); /* No more results */
} }
......
...@@ -245,6 +245,18 @@ static MYSQL_RES * emb_mysql_store_result(MYSQL *mysql) ...@@ -245,6 +245,18 @@ static MYSQL_RES * emb_mysql_store_result(MYSQL *mysql)
return mysql_store_result(mysql); return mysql_store_result(mysql);
} }
int emb_next_result(MYSQL *mysql)
{
THD *thd= (THD*)mysql->thd;
DBUG_ENTER("emb_next_result");
if (emb_advanced_command(mysql, COM_QUERY,0,0,
thd->query_rest.ptr(),thd->query_rest.length(),1)
|| emb_mysql_read_query_result(mysql))
DBUG_RETURN(1);
DBUG_RETURN(0); /* No more results */
}
MYSQL_METHODS embedded_methods= MYSQL_METHODS embedded_methods=
{ {
...@@ -259,7 +271,8 @@ MYSQL_METHODS embedded_methods= ...@@ -259,7 +271,8 @@ MYSQL_METHODS embedded_methods=
emb_read_binary_rows, emb_read_binary_rows,
emb_unbuffered_fetch, emb_unbuffered_fetch,
emb_free_embedded_thd, emb_free_embedded_thd,
emb_read_statistic emb_read_statistic,
emb_next_result
}; };
C_MODE_END C_MODE_END
...@@ -676,7 +689,10 @@ send_ok(THD *thd,ha_rows affected_rows,ulonglong id,const char *message) ...@@ -676,7 +689,10 @@ send_ok(THD *thd,ha_rows affected_rows,ulonglong id,const char *message)
mysql->affected_rows= affected_rows; mysql->affected_rows= affected_rows;
mysql->insert_id= id; mysql->insert_id= id;
if (message) if (message)
{
strmake(thd->net.last_error, message, sizeof(thd->net.last_error)-1); strmake(thd->net.last_error, message, sizeof(thd->net.last_error)-1);
mysql->info= thd->net.last_error;
}
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -64,12 +64,6 @@ test ...@@ -64,12 +64,6 @@ test
select cast(_koi8r'' as char character set cp1251); select cast(_koi8r'' as char character set cp1251);
cast(_koi8r'' as char character set cp1251) cast(_koi8r'' as char character set cp1251)
select convert(_latin1'test', "latin1_german1_ci", "latin1_swedish_ci");
convert(_latin1'test', "latin1_german1_ci", "latin1_swedish_ci")
test
select convert(_koi8r'', "koi8r_general_ci", "cp1251_general_ci");
convert(_koi8r'', "koi8r_general_ci", "cp1251_general_ci")
create table t1 select cast(_koi8r'' as char character set cp1251) as t; create table t1 select cast(_koi8r'' as char character set cp1251) as t;
show create table t1; show create table t1;
Table Create Table Table Create Table
......
...@@ -167,3 +167,5 @@ select hex(s1) from t1; ...@@ -167,3 +167,5 @@ select hex(s1) from t1;
hex(s1) hex(s1)
41 41
drop table t1; drop table t1;
create table t1 (a char(160) character set utf8, primary key(a));
ERROR HY000: Incorrect sub part key. The used key part isn't a string, the used length is longer than the key part or the storage engine doesn't support unique sub keys
...@@ -51,6 +51,20 @@ t1 CREATE TABLE `t1` ( ...@@ -51,6 +51,20 @@ t1 CREATE TABLE `t1` (
`version` char(40) default NULL `version` char(40) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1; drop table t1;
select charset(charset(_utf8'a')), charset(collation(_utf8'a'));
charset(charset(_utf8'a')) charset(collation(_utf8'a'))
utf8 utf8
select collation(charset(_utf8'a')), collation(collation(_utf8'a'));
collation(charset(_utf8'a')) collation(collation(_utf8'a'))
utf8_general_ci utf8_general_ci
create table t1 select charset(_utf8'a'), collation(_utf8'a');
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`charset(_utf8'a')` char(64) character set utf8 NOT NULL default '',
`collation(_utf8'a')` char(64) character set utf8 NOT NULL default ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
select TRUE,FALSE,NULL; select TRUE,FALSE,NULL;
TRUE FALSE NULL TRUE FALSE NULL
1 0 NULL 1 0 NULL
...@@ -186,7 +186,7 @@ create table ```a` (i int); ...@@ -186,7 +186,7 @@ create table ```a` (i int);
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=NO_AUTO_VALUE_ON_ZERO */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=NO_AUTO_VALUE_ON_ZERO */;
DROP TABLE IF EXISTS ```a`; DROP TABLE IF EXISTS ```a`;
CREATE TABLE ``a` ( CREATE TABLE ```a` (
`i` int(11) default NULL `i` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1; ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
......
...@@ -266,3 +266,51 @@ c decimal(4,3) YES NULL ...@@ -266,3 +266,51 @@ c decimal(4,3) YES NULL
d double(4,3) YES NULL d double(4,3) YES NULL
f float(4,3) YES NULL f float(4,3) YES NULL
drop table t1; drop table t1;
SET sql_mode='';
SET sql_quote_show_create=OFF;
CREATE TABLE ```ab``cd``` (i INT);
SHOW CREATE TABLE ```ab``cd```;
Table Create Table
`ab`cd` CREATE TABLE ```ab``cd``` (
i int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE ```ab``cd```;
CREATE TABLE ```ab````cd``` (i INT);
SHOW CREATE TABLE ```ab````cd```;
Table Create Table
`ab``cd` CREATE TABLE ```ab````cd``` (
i int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE ```ab````cd```;
CREATE TABLE ```a` (i INT);
SHOW CREATE TABLE ```a`;
Table Create Table
`a CREATE TABLE ```a` (
i int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE ```a`;
SET sql_mode='ANSI_QUOTES';
CREATE TABLE """a" (i INT);
SHOW CREATE TABLE """a";
Table Create Table
"a CREATE TABLE """a" (
i int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE """a";
SET sql_mode='';
SET sql_quote_show_create=OFF;
CREATE TABLE t1 (i INT);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE t1 (
i int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE `table` (i INT);
SHOW CREATE TABLE `table`;
Table Create Table
table CREATE TABLE `table` (
i int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE `table`;
SET sql_quote_show_create=ON;
...@@ -28,8 +28,6 @@ select CAST(DATE "2004-01-22 21:45:33" AS CHAR(4) BINARY); ...@@ -28,8 +28,6 @@ select CAST(DATE "2004-01-22 21:45:33" AS CHAR(4) BINARY);
set names binary; set names binary;
select cast(_latin1'test' as char character set latin2); select cast(_latin1'test' as char character set latin2);
select cast(_koi8r'' as char character set cp1251); select cast(_koi8r'' as char character set cp1251);
select convert(_latin1'test', "latin1_german1_ci", "latin1_swedish_ci");
select convert(_koi8r'', "koi8r_general_ci", "cp1251_general_ci");
create table t1 select cast(_koi8r'' as char character set cp1251) as t; create table t1 select cast(_koi8r'' as char character set cp1251) as t;
show create table t1; show create table t1;
drop table t1; drop table t1;
......
...@@ -147,11 +147,6 @@ UPDATE t1 SET utf8_f=CONVERT(koi8_ru_f USING utf8); ...@@ -147,11 +147,6 @@ UPDATE t1 SET utf8_f=CONVERT(koi8_ru_f USING utf8);
SET CHARACTER SET koi8r; SET CHARACTER SET koi8r;
SELECT * FROM t1; SELECT * FROM t1;
#
# codecovarage for Item_func_conv_charset3
#
select CONVERT(koi8_ru_f, 'cp1251_general_ci', 'utf8_general_ci'), comment from t1;
explain extended select CONVERT(koi8_ru_f, 'cp1251_general_ci', 'utf8_general_ci'), comment from t1;
ALTER TABLE t1 ADD bin_f CHAR(32) BYTE NOT NULL; ALTER TABLE t1 ADD bin_f CHAR(32) BYTE NOT NULL;
UPDATE t1 SET bin_f=koi8_ru_f; UPDATE t1 SET bin_f=koi8_ru_f;
......
...@@ -98,3 +98,10 @@ create table t1 (s1 text character set utf8); ...@@ -98,3 +98,10 @@ create table t1 (s1 text character set utf8);
insert into t1 values (0x41FF); insert into t1 values (0x41FF);
select hex(s1) from t1; select hex(s1) from t1;
drop table t1; drop table t1;
#
# Bug 2699
# UTF8 breaks primary keys for cols > 85 characters
#
--error 1089
create table t1 (a char(160) character set utf8, primary key(a));
...@@ -23,4 +23,10 @@ create table t1 (version char(40)) select database(), user(), version() as 'vers ...@@ -23,4 +23,10 @@ create table t1 (version char(40)) select database(), user(), version() as 'vers
show create table t1; show create table t1;
drop table t1; drop table t1;
select charset(charset(_utf8'a')), charset(collation(_utf8'a'));
select collation(charset(_utf8'a')), collation(collation(_utf8'a'));
create table t1 select charset(_utf8'a'), collation(_utf8'a');
show create table t1;
drop table t1;
select TRUE,FALSE,NULL; select TRUE,FALSE,NULL;
...@@ -142,3 +142,43 @@ drop table t1; ...@@ -142,3 +142,43 @@ drop table t1;
create table t1 (c decimal(3,3), d double(3,3), f float(3,3)); create table t1 (c decimal(3,3), d double(3,3), f float(3,3));
show columns from t1; show columns from t1;
drop table t1; drop table t1;
#
# Test for Bug #2593 "SHOW CREATE TABLE doesn't properly double quotes"
#
SET sql_mode='';
SET sql_quote_show_create=OFF;
CREATE TABLE ```ab``cd``` (i INT);
SHOW CREATE TABLE ```ab``cd```;
DROP TABLE ```ab``cd```;
CREATE TABLE ```ab````cd``` (i INT);
SHOW CREATE TABLE ```ab````cd```;
DROP TABLE ```ab````cd```;
CREATE TABLE ```a` (i INT);
SHOW CREATE TABLE ```a`;
DROP TABLE ```a`;
SET sql_mode='ANSI_QUOTES';
CREATE TABLE """a" (i INT);
SHOW CREATE TABLE """a";
DROP TABLE """a";
# to test quotes around keywords.. :
SET sql_mode='';
SET sql_quote_show_create=OFF;
CREATE TABLE t1 (i INT);
SHOW CREATE TABLE t1;
DROP TABLE t1;
CREATE TABLE `table` (i INT);
SHOW CREATE TABLE `table`;
DROP TABLE `table`;
SET sql_quote_show_create=ON;
...@@ -1420,7 +1420,8 @@ static MYSQL_METHODS client_methods= ...@@ -1420,7 +1420,8 @@ static MYSQL_METHODS client_methods=
cli_read_binary_rows, cli_read_binary_rows,
cli_unbuffered_fetch, cli_unbuffered_fetch,
NULL, NULL,
cli_read_statistic cli_read_statistic,
cli_read_query_result
#endif #endif
}; };
......
...@@ -598,6 +598,8 @@ void Item_param::set_time(TIME *tm, timestamp_type type) ...@@ -598,6 +598,8 @@ void Item_param::set_time(TIME *tm, timestamp_type type)
ltime.second_part= tm->second_part; ltime.second_part= tm->second_part;
ltime.neg= tm->neg;
ltime.time_type= type; ltime.time_type= type;
item_is_time= true; item_is_time= true;
......
...@@ -2124,42 +2124,6 @@ void Item_func_conv_charset::print(String *str) ...@@ -2124,42 +2124,6 @@ void Item_func_conv_charset::print(String *str)
str->append(')'); str->append(')');
} }
String *Item_func_conv_charset3::val_str(String *str)
{
char cs1[30], cs2[30];
String to_cs_buff(cs1, sizeof(cs1), default_charset_info);
String from_cs_buff(cs2, sizeof(cs2), default_charset_info);
String *arg= args[0]->val_str(str);
String *to_cs= args[1]->val_str(&to_cs_buff);
String *from_cs= args[2]->val_str(&from_cs_buff);
CHARSET_INFO *from_charset;
CHARSET_INFO *to_charset;
if (!arg || args[0]->null_value ||
!to_cs || args[1]->null_value ||
!from_cs || args[2]->null_value ||
!(from_charset=get_charset_by_name(from_cs->ptr(), MYF(MY_WME))) ||
!(to_charset=get_charset_by_name(to_cs->ptr(), MYF(MY_WME))))
{
null_value= 1;
return 0;
}
if (str_value.copy(arg->ptr(), arg->length(), from_charset, to_charset))
{
null_value= 1;
return 0;
}
null_value= 0;
return &str_value;
}
void Item_func_conv_charset3::fix_length_and_dec()
{
max_length = args[0]->max_length;
}
String *Item_func_set_collation::val_str(String *str) String *Item_func_set_collation::val_str(String *str)
{ {
str=args[0]->val_str(str); str=args[0]->val_str(str);
...@@ -2226,7 +2190,7 @@ String *Item_func_charset::val_str(String *str) ...@@ -2226,7 +2190,7 @@ String *Item_func_charset::val_str(String *str)
if ((null_value=(args[0]->null_value || !res->charset()))) if ((null_value=(args[0]->null_value || !res->charset())))
return 0; return 0;
str->copy(res->charset()->csname,strlen(res->charset()->csname), str->copy(res->charset()->csname,strlen(res->charset()->csname),
&my_charset_latin1, default_charset()); &my_charset_latin1, collation.collation);
return str; return str;
} }
...@@ -2237,7 +2201,7 @@ String *Item_func_collation::val_str(String *str) ...@@ -2237,7 +2201,7 @@ String *Item_func_collation::val_str(String *str)
if ((null_value=(args[0]->null_value || !res->charset()))) if ((null_value=(args[0]->null_value || !res->charset())))
return 0; return 0;
str->copy(res->charset()->name,strlen(res->charset()->name), str->copy(res->charset()->name,strlen(res->charset()->name),
&my_charset_latin1, default_charset()); &my_charset_latin1, collation.collation);
return str; return str;
} }
......
...@@ -619,16 +619,6 @@ class Item_func_set_collation :public Item_str_func ...@@ -619,16 +619,6 @@ class Item_func_set_collation :public Item_str_func
void print(String *str) { print_op(str); } void print(String *str) { print_op(str); }
}; };
class Item_func_conv_charset3 :public Item_str_func
{
public:
Item_func_conv_charset3(Item *arg1,Item *arg2,Item *arg3)
:Item_str_func(arg1,arg2,arg3) {}
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "convert"; }
};
class Item_func_charset :public Item_str_func class Item_func_charset :public Item_str_func
{ {
public: public:
...@@ -637,8 +627,8 @@ class Item_func_charset :public Item_str_func ...@@ -637,8 +627,8 @@ class Item_func_charset :public Item_str_func
const char *func_name() const { return "charset"; } const char *func_name() const { return "charset"; }
void fix_length_and_dec() void fix_length_and_dec()
{ {
max_length=40; // should be enough
collation.set(system_charset_info); collation.set(system_charset_info);
max_length= 64 * collation.collation->mbmaxlen; // should be enough
}; };
}; };
...@@ -650,8 +640,8 @@ class Item_func_collation :public Item_str_func ...@@ -650,8 +640,8 @@ class Item_func_collation :public Item_str_func
const char *func_name() const { return "collation"; } const char *func_name() const { return "collation"; }
void fix_length_and_dec() void fix_length_and_dec()
{ {
max_length=40; // should be enough
collation.set(system_charset_info); collation.set(system_charset_info);
max_length= 64 * collation.collation->mbmaxlen; // should be enough
}; };
}; };
......
...@@ -801,6 +801,8 @@ uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match); ...@@ -801,6 +801,8 @@ uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match);
uint check_word(TYPELIB *lib, const char *val, const char *end, uint check_word(TYPELIB *lib, const char *val, const char *end,
const char **end_of_word); const char **end_of_word);
bool is_keyword(const char *name, uint len);
/* sql_parse.cc */ /* sql_parse.cc */
void free_items(Item *item); void free_items(Item *item);
void cleanup_items(Item *item); void cleanup_items(Item *item);
......
...@@ -588,6 +588,7 @@ class THD :public ilink, ...@@ -588,6 +588,7 @@ class THD :public ilink,
struct st_mysql_bind *client_params; struct st_mysql_bind *client_params;
char *extra_data; char *extra_data;
ulong extra_length; ulong extra_length;
String query_rest;
#endif #endif
NET net; // client connection descriptor NET net; // client connection descriptor
MEM_ROOT warn_root; // For warnings and errors MEM_ROOT warn_root; // For warnings and errors
......
...@@ -203,6 +203,23 @@ static int find_keyword(LEX *lex, uint len, bool function) ...@@ -203,6 +203,23 @@ static int find_keyword(LEX *lex, uint len, bool function)
return 0; return 0;
} }
/*
Check if name is a keyword
SYNOPSIS
is_keyword()
name checked name
len length of checked name
RETURN VALUES
0 name is a keyword
1 name isn't a keyword
*/
bool is_keyword(const char *name, uint len)
{
return get_hash_symbol(name,len,0)!=0;
}
/* make a copy of token before ptr and set yytoklen */ /* make a copy of token before ptr and set yytoklen */
...@@ -215,6 +232,13 @@ static LEX_STRING get_token(LEX *lex,uint length) ...@@ -215,6 +232,13 @@ static LEX_STRING get_token(LEX *lex,uint length)
return tmp; return tmp;
} }
/*
todo:
There are no dangerous charsets in mysql for function
get_quoted_token yet. But it should be fixed in the
future to operate multichar strings (like ucs2)
*/
static LEX_STRING get_quoted_token(LEX *lex,uint length, char quote) static LEX_STRING get_quoted_token(LEX *lex,uint length, char quote)
{ {
LEX_STRING tmp; LEX_STRING tmp;
...@@ -442,7 +466,6 @@ inline static uint int_token(const char *str,uint length) ...@@ -442,7 +466,6 @@ inline static uint int_token(const char *str,uint length)
return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger; return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger;
} }
/* /*
yylex remember the following states from the following yylex() yylex remember the following states from the following yylex()
...@@ -692,22 +715,25 @@ int yylex(void *arg, void *yythd) ...@@ -692,22 +715,25 @@ int yylex(void *arg, void *yythd)
uint double_quotes= 0; uint double_quotes= 0;
char quote_char= c; // Used char char quote_char= c; // Used char
lex->tok_start=lex->ptr; // Skip first ` lex->tok_start=lex->ptr; // Skip first `
#ifdef USE_MB while ((c=yyGet()))
if (use_mb(cs))
{ {
while ((c= yyGet())) #ifdef USE_MB
if (my_mbcharlen(cs, c) == 1)
#endif
{ {
if (c == (uchar) NAMES_SEP_CHAR)
break; /* Old .frm format can't handle this char */
if (c == quote_char) if (c == quote_char)
{ {
if (yyPeek() != quote_char) if (yyPeek() != quote_char)
break; break;
c= yyGet(); c=yyGet();
double_quotes++; double_quotes++;
continue; continue;
} }
if (c == (uchar) NAMES_SEP_CHAR) }
break; #ifdef USE_MB
if (my_mbcharlen(cs, c) > 1) else
{ {
int l; int l;
if ((l = my_ismbchar(cs, if ((l = my_ismbchar(cs,
...@@ -716,24 +742,7 @@ int yylex(void *arg, void *yythd) ...@@ -716,24 +742,7 @@ int yylex(void *arg, void *yythd)
break; break;
lex->ptr += l-1; lex->ptr += l-1;
} }
}
}
else
#endif #endif
{
while ((c=yyGet()))
{
if (c == quote_char)
{
if (yyPeek() != quote_char)
break;
c=yyGet();
double_quotes++;
continue;
}
if (c == (uchar) NAMES_SEP_CHAR)
break;
}
} }
if (double_quotes) if (double_quotes)
yylval->lex_str=get_quoted_token(lex,yyLength() - double_quotes, yylval->lex_str=get_quoted_token(lex,yyLength() - double_quotes,
...@@ -915,8 +924,13 @@ int yylex(void *arg, void *yythd) ...@@ -915,8 +924,13 @@ int yylex(void *arg, void *yythd)
} }
/* fall true */ /* fall true */
case MY_LEX_EOL: case MY_LEX_EOL:
if (lex->ptr >= lex->end_of_query)
{
lex->next_state=MY_LEX_END; // Mark for next loop lex->next_state=MY_LEX_END; // Mark for next loop
return(END_OF_INPUT); return(END_OF_INPUT);
}
state=MY_LEX_CHAR;
break;
case MY_LEX_END: case MY_LEX_END:
lex->next_state=MY_LEX_END; lex->next_state=MY_LEX_END;
return(0); // We found end of input last time return(0); // We found end of input last time
......
...@@ -1411,11 +1411,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1411,11 +1411,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
char *packet= thd->lex->found_colon; char *packet= thd->lex->found_colon;
/* /*
Multiple queries exits, execute them individually Multiple queries exits, execute them individually
in embedded server - just store them to be executed later
*/ */
#ifndef EMBEDDED_LIBRARY
if (thd->lock || thd->open_tables || thd->derived_tables) if (thd->lock || thd->open_tables || thd->derived_tables)
close_thread_tables(thd); close_thread_tables(thd);
#endif
ulong length= thd->query_length-(ulong)(thd->lex->found_colon-thd->query); ulong length= thd->query_length-(ulong)(packet-thd->query);
/* Remove garbage at start of query */ /* Remove garbage at start of query */
while (my_isspace(thd->charset(), *packet) && length > 0) while (my_isspace(thd->charset(), *packet) && length > 0)
...@@ -1428,7 +1430,22 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1428,7 +1430,22 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
VOID(pthread_mutex_lock(&LOCK_thread_count)); VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id= query_id++; thd->query_id= query_id++;
VOID(pthread_mutex_unlock(&LOCK_thread_count)); VOID(pthread_mutex_unlock(&LOCK_thread_count));
#ifndef EMBEDDED_LIBRARY
mysql_parse(thd, packet, length); mysql_parse(thd, packet, length);
#else
/*
'packet' can point inside the query_rest's buffer
so we have to do memmove here
*/
if (thd->query_rest.length() > length)
{
memmove(thd->query_rest.c_ptr(), packet, length);
thd->query_rest.length(length);
}
else
thd->query_rest.copy(length);
break;
#endif /*EMBEDDED_LIBRARY*/
} }
if (!(specialflag & SPECIAL_NO_PRIOR)) if (!(specialflag & SPECIAL_NO_PRIOR))
......
...@@ -1085,8 +1085,7 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd) ...@@ -1085,8 +1085,7 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/* possible TODO: call find_keyword() from sql_lex.cc here */ static inline const char *require_quotes(const char *name, uint length)
static bool require_quotes(const char *name, uint length)
{ {
uint i, d, c; uint i, d, c;
for (i=0; i<length; i+=d) for (i=0; i<length; i+=d)
...@@ -1094,7 +1093,37 @@ static bool require_quotes(const char *name, uint length) ...@@ -1094,7 +1093,37 @@ static bool require_quotes(const char *name, uint length)
c=((uchar *)name)[i]; c=((uchar *)name)[i];
d=my_mbcharlen(system_charset_info, c); d=my_mbcharlen(system_charset_info, c);
if (d==1 && !system_charset_info->ident_map[c]) if (d==1 && !system_charset_info->ident_map[c])
return 1; return name+i;
}
return 0;
}
/*
Looking for char in multibyte string
SYNOPSIS
look_for_char()
name string for looking at
length length of name
q '\'' or '\"' for looking for
RETURN VALUES
# pointer to found char in string
0 string doesn't contain required char
*/
static inline const char *look_for_char(const char *name,
uint length, char q)
{
const char *cur= name;
const char *end= cur+length;
uint symbol_length;
for (; cur<end; cur+= symbol_length)
{
char c= *cur;
symbol_length= my_mbcharlen(system_charset_info, c);
if (symbol_length==1 && c==q)
return cur;
} }
return 0; return 0;
} }
...@@ -1103,21 +1132,52 @@ void ...@@ -1103,21 +1132,52 @@ void
append_identifier(THD *thd, String *packet, const char *name, uint length) append_identifier(THD *thd, String *packet, const char *name, uint length)
{ {
char qtype; char qtype;
uint part_len;
const char *qplace;
if (thd->variables.sql_mode & MODE_ANSI_QUOTES) if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
qtype= '\"'; qtype= '\"';
else else
qtype= '`'; qtype= '`';
if ((thd->options & OPTION_QUOTE_SHOW_CREATE) || if (is_keyword(name,length))
require_quotes(name, length))
{ {
packet->append(&qtype, 1); packet->append(&qtype, 1, system_charset_info);
packet->append(name, length, system_charset_info); packet->append(name, length, system_charset_info);
packet->append(&qtype, 1); packet->append(&qtype, 1, system_charset_info);
} }
else else
{ {
if (!(qplace= require_quotes(name, length)))
{
if (!(thd->options & OPTION_QUOTE_SHOW_CREATE))
packet->append(name, length, system_charset_info); packet->append(name, length, system_charset_info);
else
{
packet->append(&qtype, 1, system_charset_info);
packet->append(name, length, system_charset_info);
packet->append(&qtype, 1, system_charset_info);
}
}
else
{
packet->shrink(packet->length()+length+2);
packet->append(&qtype, 1, system_charset_info);
if (*qplace != qtype)
qplace= look_for_char(qplace+1,length-(qplace-name)-1,qtype);
while (qplace)
{
if ((part_len= qplace-name))
{
packet->append(name, part_len, system_charset_info);
length-= part_len;
}
packet->append(qplace, 1, system_charset_info);
name= qplace;
qplace= look_for_char(name+1,length-1,qtype);
}
packet->append(name, length, system_charset_info);
packet->append(&qtype, 1, system_charset_info);
}
} }
} }
......
...@@ -873,7 +873,12 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, ...@@ -873,7 +873,12 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
column->field_name); column->field_name);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
key_part_info->length=(uint8) length; if (length > file->max_key_part_length())
{
my_error(ER_WRONG_SUB_KEY,MYF(0));
DBUG_RETURN(-1);
}
key_part_info->length=(uint16) length;
/* Use packed keys for long strings on the first column */ /* Use packed keys for long strings on the first column */
if (!(db_options & HA_OPTION_NO_PACK_KEYS) && if (!(db_options & HA_OPTION_NO_PACK_KEYS) &&
(length >= KEY_DEFAULT_PACK_LENGTH && (length >= KEY_DEFAULT_PACK_LENGTH &&
......
...@@ -3636,8 +3636,6 @@ simple_expr: ...@@ -3636,8 +3636,6 @@ simple_expr:
} }
| CONVERT_SYM '(' expr USING charset_name ')' | CONVERT_SYM '(' expr USING charset_name ')'
{ $$= new Item_func_conv_charset($3,$5); } { $$= new Item_func_conv_charset($3,$5); }
| CONVERT_SYM '(' expr ',' expr ',' expr ')'
{ $$= new Item_func_conv_charset3($3,$7,$5); }
| DEFAULT '(' simple_ident ')' | DEFAULT '(' simple_ident ')'
{ $$= new Item_default_value($3); } { $$= new Item_default_value($3); }
| VALUES '(' simple_ident ')' | VALUES '(' simple_ident ')'
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment