Merge sanja.is.com.ua:/home/bell/mysql/bk/mysql-4.1

into sanja.is.com.ua:/home/bell/mysql/bk/work-fix_fields-4.1
This commit is contained in:
unknown 2004-03-15 16:31:41 +02:00
commit 7b13e02039
65 changed files with 1498 additions and 784 deletions

View file

@ -59,6 +59,7 @@ jani@rhols221.arenanet.fi
jani@ua126d19.elisa.omakaista.fi
jani@ua141d10.elisa.omakaista.fi
jani@ua167d18.elisa.omakaista.fi
jani@ua72d24.elisa.omakaista.fi
jcole@abel.spaceapes.com
jcole@main.burghcom.com
jcole@mugatu.spaceapes.com

View file

@ -43,6 +43,7 @@
#include <my_sys.h>
#include <m_string.h>
#include <m_ctype.h>
#include <assert.h>
#include "client_priv.h"
#include "mysql.h"
@ -63,7 +64,6 @@
#define SHOW_NULL 2
#define SHOW_DEFAULT 4
#define SHOW_EXTRA 5
#define QUOTE_CHAR '`'
/* Size of buffer for dump's select query */
#define QUERY_LENGTH 1536
@ -89,6 +89,7 @@ static char insert_pat[12 * 1024],*opt_password=0,*current_user=0,
*where=0,
*opt_compatible_mode_str= 0,
*err_ptr= 0;
static char compatible_mode_normal_str[255];
static char *default_charset= (char*) MYSQL_UNIVERSAL_CLIENT_CHARSET;
static ulong opt_compatible_mode= 0;
static uint opt_mysql_port= 0, err_len= 0;
@ -111,6 +112,15 @@ const char *compatible_mode_names[]=
"ANSI",
NullS
};
#define MASK_ANSI_QUOTES \
(\
(1<<2) | /* POSTGRESQL */\
(1<<3) | /* ORACLE */\
(1<<4) | /* MSSQL */\
(1<<5) | /* DB2 */\
(1<<6) | /* MAXDB */\
(1<<10) /* ANSI */\
)
TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1,
"", compatible_mode_names};
@ -377,10 +387,10 @@ static void write_header(FILE *sql_file, char *db_name)
");
}
fprintf(sql_file,
"/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=\"%s\" */;\n",
path?"":"NO_AUTO_VALUE_ON_ZERO");
"/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=\"%s%s%s\" */;\n",
path?"":"NO_AUTO_VALUE_ON_ZERO",compatible_mode_normal_str[0]==0?"":",",
compatible_mode_normal_str);
}
return;
} /* write_header */
@ -480,6 +490,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case (int) OPT_COMPATIBLE:
{
char buff[255];
char *end= compatible_mode_normal_str;
int i;
ulong mode;
opt_quoted= 1;
opt_set_names= 1;
@ -493,6 +506,27 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
fprintf(stderr, "Invalid mode to --compatible: %s\n", buff);
exit(1);
}
#if !defined(DBUG_OFF)
{
int size_for_sql_mode= 0;
const char **ptr;
for (ptr= compatible_mode_names; *ptr; ptr++)
size_for_sql_mode+= strlen(*ptr);
size_for_sql_mode+= sizeof(compatible_mode_names)-1;
DBUG_ASSERT(sizeof(compatible_mode_normal_str)>=size_for_sql_mode);
}
#endif
mode= opt_compatible_mode;
for (i= 0, mode= opt_compatible_mode; mode; mode>>= 1, i++)
{
if (mode & 1)
{
end= strmov(end, compatible_mode_names[i]);
end= strmov(end, ",");
}
}
if (end!=compatible_mode_normal_str)
end[-1]= 0;
break;
}
case (int) OPT_MYSQL_PROTOCOL:
@ -594,6 +628,7 @@ static void safe_exit(int error)
*/
static int dbConnect(char *host, char *user,char *passwd)
{
char buff[20+FN_REFLEN];
DBUG_ENTER("dbConnect");
if (verbose)
{
@ -622,6 +657,16 @@ static int dbConnect(char *host, char *user,char *passwd)
DBerror(&mysql_connection, "when trying to connect");
return 1;
}
sprintf(buff, "/*!40100 SET @@SQL_MODE=\"%s\" */",
compatible_mode_normal_str);
if (mysql_query(sock, buff))
{
fprintf(stderr, "%s: Can't set the compatible mode %s (error %s)\n",
my_progname, compatible_mode_normal_str, mysql_error(sock));
mysql_close(sock);
safe_exit(EX_MYSQLERR);
return 1;
}
return 0;
} /* dbConnect */
@ -670,17 +715,19 @@ static my_bool test_if_special_chars(const char *str)
static char *quote_name(const char *name, char *buff, my_bool force)
{
char *to= buff;
char qtype= (opt_compatible_mode & MASK_ANSI_QUOTES) ? '\"' : '`';
if (!force && !opt_quoted && !test_if_special_chars(name))
return (char*) name;
*to++= QUOTE_CHAR;
*to++= qtype;
while (*name)
{
if (*name == QUOTE_CHAR)
*to++= QUOTE_CHAR;
if (*name == qtype)
*to++= qtype;
*to++= *name++;
}
to[0]=QUOTE_CHAR;
to[1]=0;
to[0]= qtype;
to[1]= 0;
return buff;
} /* quote_name */
@ -853,31 +900,6 @@ static uint getTableStructure(char *table, char* db)
/* Make an sql-file, if path was given iow. option -T was given */
char buff[20+FN_REFLEN];
if (opt_compatible_mode)
{
char *end;
uint i;
sprintf(buff, "/*!40100 SET @@sql_mode=\"");
end= strend(buff);
for (i= 0; opt_compatible_mode; opt_compatible_mode>>= 1, i++)
{
if (opt_compatible_mode & 1)
{
end= strmov(end, compatible_mode_names[i]);
end= strmov(end, ",");
}
}
end= strmov(end-1, "\" */");
if (mysql_query(sock, buff))
{
fprintf(stderr, "%s: Can't set the compatible mode '%s' (%s)\n",
my_progname, table, mysql_error(sock));
safe_exit(EX_MYSQLERR);
DBUG_RETURN(0);
}
}
sprintf(buff,"show create table %s", result_table);
if (mysql_query(sock, buff))
{
@ -1858,6 +1880,7 @@ int main(int argc, char **argv)
{
MYSQL_ROW row;
MYSQL_RES *master;
compatible_mode_normal_str[0]= 0;
MY_INIT(argv[0]);
if (get_options(&argc, &argv))

View file

@ -218,6 +218,9 @@ extern int is_prefix(const char *, const char *);
/* Conversion routines */
double my_strtod(const char *str, char **end);
double my_atof(const char *nptr);
#ifndef EOVERFLOW
#define EOVERFLOW 84
#endif
#ifdef USE_MY_ITOA
extern char *my_itoa(int val,char *dst,int radix);

View file

@ -575,7 +575,7 @@ typedef struct st_mysql_methods
MYSQL_DATA *(*read_binary_rows)(MYSQL_STMT *stmt);
int (*unbuffered_fetch)(MYSQL *mysql, char **row);
void (*free_embedded_thd)(MYSQL *mysql);
const char *(*read_statistic)(MYSQL *mysql);
const char *(*read_statistics)(MYSQL *mysql);
int (*next_result)(MYSQL *mysql);
int (*read_change_user_result)(MYSQL *mysql, char *buff, const char *passwd);
#endif

View file

@ -307,4 +307,6 @@
#define ER_NON_UPDATABLE_TABLE 1288
#define ER_FEATURE_DISABLED 1289
#define ER_OPTION_PREVENTS_STATEMENT 1290
#define ER_ERROR_MESSAGES 291
#define ER_DUPLICATED_VALUE_IN_TYPE 1291
#define ER_TRUNCATED_WRONG_VALUE 1292
#define ER_ERROR_MESSAGES 293

View file

@ -38,6 +38,7 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode,
const char *sqlstate);
void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate);
#ifdef __cplusplus
}
#endif

View file

@ -34,6 +34,7 @@ CXXFLAGS="$CXXFLAGS "
AC_PROG_CC
AC_PROG_RANLIB
AC_PROG_INSTALL
AC_PROG_LIBTOOL
AC_CHECK_HEADERS(aio.h sched.h)
AC_CHECK_SIZEOF(int, 4)
AC_CHECK_SIZEOF(long, 4)

View file

@ -57,7 +57,7 @@ MYSQL_DATA * cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
int cli_stmt_execute(MYSQL_STMT *stmt);
MYSQL_DATA * cli_read_binary_rows(MYSQL_STMT *stmt);
int cli_unbuffered_fetch(MYSQL *mysql, char **row);
const char * cli_read_statistic(MYSQL *mysql);
const char * cli_read_statistics(MYSQL *mysql);
int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd);
#ifdef EMBEDDED_LIBRARY

View file

@ -1126,7 +1126,7 @@ mysql_dump_debug_info(MYSQL *mysql)
DBUG_RETURN(simple_command(mysql,COM_DEBUG,0,0,0));
}
const char *cli_read_statistic(MYSQL *mysql)
const char *cli_read_statistics(MYSQL *mysql)
{
mysql->net.read_pos[mysql->packet_length]=0; /* End of stat string */
if (!mysql->net.read_pos[0])
@ -1145,7 +1145,7 @@ mysql_stat(MYSQL *mysql)
DBUG_ENTER("mysql_stat");
if (simple_command(mysql,COM_STATISTICS,0,0,0))
return mysql->net.last_error;
DBUG_RETURN((*mysql->methods->read_statistic)(mysql));
DBUG_RETURN((*mysql->methods->read_statistics)(mysql));
}
@ -1544,21 +1544,6 @@ void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode,
}
/*
Set the internal error message to mysql handler
*/
static void set_mysql_error(MYSQL * mysql, int errcode, const char *sqlstate)
{
DBUG_ENTER("set_mysql_error");
DBUG_PRINT("enter", ("error :%d '%s'", errcode, ER(errcode)));
DBUG_ASSERT(mysql != 0);
mysql->net.last_errno= errcode;
strmov(mysql->net.last_error, ER(errcode));
strmov(mysql->net.sqlstate, sqlstate);
}
/*
Reallocate the NET package to be at least of 'length' bytes
@ -2872,7 +2857,7 @@ my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
{
/*
Set param->is_null to point to a dummy variable if it's not set.
This is to make the excute code easier
This is to make the execute code easier
*/
if (!param->is_null)
param->is_null= &param->internal_is_null;
@ -3142,8 +3127,7 @@ MYSQL_DATA *cli_read_binary_rows(MYSQL_STMT *stmt)
if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
MYF(MY_WME | MY_ZEROFILL))))
{
set_stmt_errmsg(stmt, ER(CR_OUT_OF_MEMORY), CR_OUT_OF_MEMORY,
unknown_sqlstate);
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
DBUG_RETURN(0);
}
init_alloc_root(&result->alloc,8192,0); /* Assume rowlength < 8192 */
@ -3159,8 +3143,7 @@ MYSQL_DATA *cli_read_binary_rows(MYSQL_STMT *stmt)
!(cur->data= ((MYSQL_ROW) alloc_root(&result->alloc, pkt_len))))
{
free_rows(result);
set_stmt_errmsg(stmt, ER(CR_OUT_OF_MEMORY), CR_OUT_OF_MEMORY,
unknown_sqlstate);
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate);
DBUG_RETURN(0);
}
*prev_ptr= cur;

View file

@ -234,7 +234,7 @@ static void emb_free_embedded_thd(MYSQL *mysql)
delete thd;
}
static const char * emb_read_statistic(MYSQL *mysql)
static const char * emb_read_statistics(MYSQL *mysql)
{
THD *thd= (THD*)mysql->thd;
return thd->net.last_error;
@ -279,7 +279,7 @@ MYSQL_METHODS embedded_methods=
emb_read_binary_rows,
emb_unbuffered_fetch,
emb_free_embedded_thd,
emb_read_statistic,
emb_read_statistics,
emb_next_result,
emb_read_change_user_result
};
@ -398,23 +398,6 @@ int init_embedded_server(int argc, char **argv, char **groups)
udf_init();
#endif
if (opt_bin_log)
{
if (!opt_bin_logname)
{
char tmp[FN_REFLEN];
/* TODO: The following should be using fn_format(); We just need to
first change fn_format() to cut the file name if it's too long.
*/
strmake(tmp,glob_hostname,FN_REFLEN-5);
strmov(strcend(tmp,'.'),"-bin");
opt_bin_logname=my_strdup(tmp,MYF(MY_WME));
}
open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
opt_binlog_index_name, LOG_BIN, 0, 0, max_binlog_size);
using_update_log=1;
}
(void) thr_setconcurrency(concurrency); // 10 by default
if (

View file

@ -104,9 +104,9 @@ drop table t2;
create table t2 select CAST("2001-12-29" AS DATE) as d, CAST("20:45:11" AS TIME) as t, CAST("2001-12-29 20:45:11" AS DATETIME) as dt;
describe t2;
Field Type Null Key Default Extra
d date 0000-00-00
t time 00:00:00
dt datetime 0000-00-00 00:00:00
d date YES NULL
t time YES NULL
dt datetime YES NULL
drop table t1,t2;
create table t1 (a tinyint);
create table t2 (a int) select * from t1;
@ -396,12 +396,12 @@ Field Type Null Key Default Extra
a int(11) YES NULL
b bigint(11) 0
c bigint(10) 0
d date 0000-00-00
d date YES NULL
e char(1)
f datetime 0000-00-00 00:00:00
g time 00:00:00
f datetime YES NULL
g time YES NULL
h longblob
dd time 00:00:00
dd time YES NULL
select * from t2;
a b c d e f g h dd
1 -7 7 2000-01-01 b 2000-01-01 00:00:00 05:04:03 yet another binary data 02:00:00
@ -456,6 +456,20 @@ Field Type Null Key Default Extra
name varchar(10) YES NULL
age smallint(6) YES -1
drop table t1, t2;
create table t1(cenum enum('a'), cset set('b'));
create table t2(cenum enum('a','a'), cset set('b','b'));
Warnings:
Error 1291 Column 'cenum' has duplicated value 'a' in ENUM
Error 1291 Column 'cset' has duplicated value 'b' in SET
create table t3(cenum enum('a','A','a','c','c'), cset set('b','B','b','d','d'));
Warnings:
Error 1291 Column 'cenum' has duplicated value 'a' in ENUM
Error 1291 Column 'cenum' has duplicated value 'A' in ENUM
Error 1291 Column 'cenum' has duplicated value 'c' in ENUM
Error 1291 Column 'cset' has duplicated value 'b' in SET
Error 1291 Column 'cset' has duplicated value 'B' in SET
Error 1291 Column 'cset' has duplicated value 'd' in SET
drop table t1, t2, t3;
create database test_$1;
use test_$1;
select database();
@ -468,3 +482,44 @@ NULL
select database();
database()
NULL
use test;
create table t1 (a int, index `primary` (a));
ERROR 42000: Incorrect index name 'primary'
create table t1 (a int, index `PRIMARY` (a));
ERROR 42000: Incorrect index name 'PRIMARY'
create table t1 (`primary` int, index(`primary`));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`primary` int(11) default NULL,
KEY `primary_2` (`primary`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
create table t2 (`PRIMARY` int, index(`PRIMARY`));
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`PRIMARY` int(11) default NULL,
KEY `PRIMARY_2` (`PRIMARY`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
create table t3 (a int);
alter table t3 add index `primary` (a);
ERROR 42000: Incorrect index name 'primary'
alter table t3 add index `PRIMARY` (a);
ERROR 42000: Incorrect index name 'PRIMARY'
create table t4 (`primary` int);
alter table t4 add index(`primary`);
show create table t4;
Table Create Table
t4 CREATE TABLE `t4` (
`primary` int(11) default NULL,
KEY `primary_2` (`primary`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
create table t5 (`PRIMARY` int);
alter table t5 add index(`PRIMARY`);
show create table t5;
Table Create Table
t5 CREATE TABLE `t5` (
`PRIMARY` int(11) default NULL,
KEY `PRIMARY_2` (`PRIMARY`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1, t2, t3, t4, t5;

View file

@ -78,11 +78,11 @@ select str_to_date(concat('15-01-2001',' 2:59:58.999'),
concat('%d-%m-%Y',' ','%H:%i:%s.%f'));
str_to_date(concat('15-01-2001',' 2:59:58.999'),
concat('%d-%m-%Y',' ','%H:%i:%s.%f'))
2001-01-15 02:59:58.000999
2001-01-15 02:59:58.999000
create table t1 (date char(30), format char(30) not null);
insert into t1 values
('2003-01-02 10:11:12', '%Y-%m-%d %H:%i:%S'),
('03-01-02 8:11:2.123456', '%y-%m-%d %H:%i:%S'),
('03-01-02 8:11:2.123456', '%y-%m-%d %H:%i:%S.%#'),
('2003-01-02 10:11:12 PM', '%Y-%m-%d %h:%i:%S %p'),
('2003-01-02 01:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f%p'),
('2003-01-02 02:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f %p'),
@ -106,16 +106,16 @@ insert into t1 values
select date,format,str_to_date(date, format) as str_to_date from t1;
date format str_to_date
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 10:11:12
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 2003-01-02 08:11:02
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 2003-01-02 08:11:02
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.012345
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.012345
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.012345
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.123450
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.123450
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.123450
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12
10:20:10 %H:%i:%s 0000-00-00 10:20:10
10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10
10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10
10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.000044
10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.440000
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58
15 September 2001 %d %M %Y 2001-09-15 00:00:00
15 SEPTEMB 2001 %d %M %Y 2001-09-15 00:00:00
@ -130,16 +130,16 @@ Thursday 53 1998 %W %u %Y 1998-12-31 00:00:00
select date,format,concat('',str_to_date(date, format)) as con from t1;
date format con
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 10:11:12
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 2003-01-02 08:11:02
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 2003-01-02 08:11:02
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.012345
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.012345
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.012345
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.123450
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.123450
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.123450
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12
10:20:10 %H:%i:%s 0000-00-00 10:20:10
10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10
10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10
10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.000044
10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.440000
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58
15 September 2001 %d %M %Y 2001-09-15 00:00:00
15 SEPTEMB 2001 %d %M %Y 2001-09-15 00:00:00
@ -154,16 +154,16 @@ Thursday 53 1998 %W %u %Y 1998-12-31 00:00:00
select date,format,cast(str_to_date(date, format) as datetime) as datetime from t1;
date format datetime
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 10:11:12
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 2003-01-02 08:11:02
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 2003-01-02 08:11:02
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.012345
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.012345
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.012345
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.123450
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.123450
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.123450
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12
10:20:10 %H:%i:%s 0000-00-00 10:20:10
10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10
10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10
10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.000044
10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.440000
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58
15 September 2001 %d %M %Y 2001-09-15 00:00:00
15 SEPTEMB 2001 %d %M %Y 2001-09-15 00:00:00
@ -178,7 +178,7 @@ Thursday 53 1998 %W %u %Y 1998-12-31 00:00:00
select date,format,DATE(str_to_date(date, format)) as date2 from t1;
date format date2
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 2003-01-02
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 2003-01-02
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02
@ -202,16 +202,16 @@ Thursday 53 1998 %W %u %Y 1998-12-31
select date,format,TIME(str_to_date(date, format)) as time from t1;
date format time
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 10:11:12
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 08:11:02
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 08:11:02
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 22:11:12
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 01:11:12.012345
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 02:11:12.012345
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 00:11:12.012345
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 01:11:12.123450
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 02:11:12.123450
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 00:11:12.123450
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 23:11:12
10:20:10 %H:%i:%s 10:20:10
10:20:10 %h:%i:%s.%f 10:20:10
10:20:10AM %h:%i:%s%p 10:20:10
10:20:10.44AM %h:%i:%s.%f%p 10:20:10.000044
10:20:10.44AM %h:%i:%s.%f%p 10:20:10.440000
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 12:59:58
15 September 2001 %d %M %Y 00:00:00
15 SEPTEMB 2001 %d %M %Y 00:00:00
@ -226,16 +226,16 @@ Thursday 53 1998 %W %u %Y 00:00:00
select date,format,concat(TIME(str_to_date(date, format))) as time2 from t1;
date format time2
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 10:11:12
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 08:11:02
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 08:11:02
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 22:11:12
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 01:11:12.012345
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 02:11:12.012345
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 00:11:12.012345
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 01:11:12.123450
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 02:11:12.123450
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 00:11:12.123450
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 23:11:12
10:20:10 %H:%i:%s 10:20:10
10:20:10 %h:%i:%s.%f 10:20:10
10:20:10AM %h:%i:%s%p 10:20:10
10:20:10.44AM %h:%i:%s.%f%p 10:20:10.000044
10:20:10.44AM %h:%i:%s.%f%p 10:20:10.440000
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 12:59:58
15 September 2001 %d %M %Y 00:00:00
15 SEPTEMB 2001 %d %M %Y 00:00:00
@ -302,11 +302,15 @@ date format str_to_date
10:20:10AM %h:%i:%s 0000-00-00 10:20:10
2003-01-02 10:11:12 %Y-%m-%d %h:%i:%S 2003-01-02 10:11:12
03-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 0003-01-02 22:11:12
Warnings:
Note 1292 Truncated wrong string value: '10:20:10AM'
select date,format,concat(str_to_date(date, format),'') as con from t1;
date format con
10:20:10AM %h:%i:%s 0000-00-00 10:20:10
2003-01-02 10:11:12 %Y-%m-%d %h:%i:%S 2003-01-02 10:11:12
03-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 0003-01-02 22:11:12
Warnings:
Note 1292 Truncated wrong string value: '10:20:10AM'
drop table t1;
select get_format(DATE, 'USA') as a;
a
@ -335,3 +339,56 @@ date_format(d,"%d")
14
14
drop table t1;
select str_to_date("2003-....01ABCD-02 10:11:12.0012", "%Y-%.%m%@-%d %H:%i:%S.%f") as a;
a
2003-01-02 10:11:12.001200
create table t1 select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f") as f1,
str_to_date("10:11:12.0012", "%H:%i:%S.%f") as f2,
str_to_date("2003-01-02", "%Y-%m-%d") as f3,
str_to_date("02", "%d") as f4, str_to_date("02 10", "%d %H") as f5;
describe t1;
Field Type Null Key Default Extra
f1 datetime YES NULL
f2 time YES NULL
f3 date YES NULL
f4 date YES NULL
f5 time YES NULL
select * from t1;
f1 f2 f3 f4 f5
2003-01-02 10:11:12 10:11:12 2003-01-02 0000-00-02 58:00:00
drop table t1;
create table t1 select "02 10" as a, "%d %H" as b;
select str_to_date(a,b) from t1;
str_to_date(a,b)
0000-00-02 10:00:00
create table t2 select str_to_date(a,b) from t1;
describe t2;
Field Type Null Key Default Extra
str_to_date(a,b) char(29) YES NULL
select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f") as f1,
str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S") as f2,
str_to_date("2003-01-02", "%Y-%m-%d") as f3,
str_to_date("02 10:11:12", "%d %H:%i:%S.%f") as f4,
str_to_date("02 10:11:12", "%d %H:%i:%S") as f5,
str_to_date("02 10", "%d %f") as f6;
f1 f2 f3 f4 f5 f6
2003-01-02 10:11:12.001200 2003-01-02 10:11:12 2003-01-02 58:11:12 58:11:12 48:00:00.100000
Warnings:
Note 1292 Truncated wrong datetime value: '2003-01-02 10:11:12.0012'
drop table t1, t2;
select str_to_date("2003-01-02 10:11:12.0012ABCD", "%Y-%m-%d %H:%i:%S.%f") as f1,
addtime("-01:01:01.01 GGG", "-23:59:59.1") as f2,
microsecond("1997-12-31 23:59:59.01XXXX") as f3;
f1 f2 f3
2003-01-02 10:11:12.001200 -25:01:00.110000 10000
Warnings:
Note 1292 Truncated wrong datetime value: '2003-01-02 10:11:12.0012ABCD'
Note 1292 Truncated wrong time value: '-01:01:01.01 GG'
Note 1292 Truncated wrong datetime value: '1997-12-31 23:59:59.01XXXX'
select str_to_date("2003-04-05 g", "%Y-%m-%d") as f1,
str_to_date("2003-04-05 10:11:12.101010234567", "%Y-%m-%d %H:%i:%S.%f") as f2;
f1 f2
2003-04-05 2003-04-05 10:11:12.101010
Warnings:
Note 1292 Truncated wrong date value: '2003-04-05 g'
Note 1292 Truncated wrong datetime value: '2003-04-05 10:11:12.101010234567'

View file

@ -159,14 +159,14 @@ time("1997-12-31 23:59:59.000001") as f9;
describe t1;
Field Type Null Key Default Extra
f1 date 0000-00-00
f2 datetime 0000-00-00 00:00:00
f3 time 00:00:00
f2 datetime YES NULL
f3 time YES NULL
f4 time 00:00:00
f5 time 00:00:00
f6 time 00:00:00
f7 datetime 0000-00-00 00:00:00
f8 date 0000-00-00
f9 time 00:00:00
f7 datetime YES NULL
f8 date YES NULL
f9 time YES NULL
select * from t1;
f1 f2 f3 f4 f5 f6 f7 f8 f9
1997-01-01 1998-01-02 01:01:00 49:01:01 46:58:57 -23:59:59 10:11:12 2001-12-01 01:01:01 1997-12-31 23:59:59
@ -198,3 +198,18 @@ NULL NULL
NULL NULL
00:00:00 -24:00:00
drop table t1, test;
select addtime("-01:01:01.01", "-23:59:59.1") as a;
a
-25:01:00.110000
select microsecond("1997-12-31 23:59:59.01") as a;
a
10000
select microsecond(19971231235959.01) as a;
a
10000
select date_add("1997-12-31",INTERVAL "10.09" SECOND_MICROSECOND) as a;
a
1997-12-31 00:00:10.090000
select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f");
str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f")
2003-01-02 10:11:12.001200

View file

@ -624,3 +624,13 @@ Note 1003 select high_priority md5(_latin1'hello') AS `md5('hello')`,sha(_latin1
SELECT lpad(12345, 5, "#");
lpad(12345, 5, "#")
12345
create table t1 (id int(1), str varchar(10)) DEFAULT CHARSET=utf8;
insert into t1 values (1,'aaaaaaaaaa'), (2,'bbbbbbbbbb');
create table t2 (id int(1), str varchar(10)) DEFAULT CHARSET=utf8;
insert into t2 values (1,'cccccccccc'), (2,'dddddddddd');
select substring(concat(t1.str, t2.str), 1, 15) "name" from t1, t2
where t2.id=t1.id order by name;
name
aaaaaaaaaaccccc
bbbbbbbbbbddddd
drop table t1, t2;

View file

@ -506,17 +506,32 @@ last_day('2001-01-01 01:01:01') as f5, last_day(NULL),
last_day('2001-02-12');
f1 f2 f3 f4 f5 last_day(NULL) last_day('2001-02-12')
2000-02-29 2002-12-31 NULL 2003-04-30 2001-01-31 NULL 2001-02-28
create table t1 select last_day('2000-02-05') as a;
create table t1 select last_day('2000-02-05') as a,
from_days(to_days("960101")) as b;
describe t1;
Field Type Null Key Default Extra
a date 0000-00-00
b date YES NULL
select * from t1;
a
2000-02-29
a b
2000-02-29 1996-01-01
drop table t1;
select last_day('2000-02-05');
last_day('2000-02-05')
2000-02-29
select last_day('2000-02-05') as a,
from_days(to_days("960101")) as b;
a b
2000-02-29 1996-01-01
select date_add(last_day("1997-12-1"), INTERVAL 1 DAY);
date_add(last_day("1997-12-1"), INTERVAL 1 DAY)
1998-01-01
select length(last_day("1997-12-1"));
length(last_day("1997-12-1"))
10
select last_day("1997-12-1")+0;
last_day("1997-12-1")+0
19971231
select last_day("1997-12-1")+0.0;
last_day("1997-12-1")+0.0
19971231.0
select strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0;
strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0
1

View file

@ -169,7 +169,6 @@ set @value= "1e+1111111111a";
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
Warnings:
Warning 1265 Data truncated for column 'f_double ' at row 1
Warning 1264 Data truncated, out of range for column 'f_double ' at row 1
Warning 1265 Data truncated for column 'f_float ' at row 1
Warning 1264 Data truncated, out of range for column 'f_float ' at row 1
Warning 1265 Data truncated for column 'f_double_7_2 ' at row 1
@ -177,7 +176,6 @@ Warning 1264 Data truncated, out of range for column 'f_double_7_2 ' at row 1
Warning 1265 Data truncated for column 'f_float_4_3 ' at row 1
Warning 1264 Data truncated, out of range for column 'f_float_4_3 ' at row 1
Warning 1265 Data truncated for column 'f_double_u ' at row 1
Warning 1264 Data truncated, out of range for column 'f_double_u ' at row 1
Warning 1265 Data truncated for column 'f_float_u ' at row 1
Warning 1264 Data truncated, out of range for column 'f_float_u ' at row 1
Warning 1265 Data truncated for column 'f_double_15_1_u ' at row 1
@ -199,7 +197,6 @@ set @value= "-1e+1111111111a";
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
Warnings:
Warning 1265 Data truncated for column 'f_double ' at row 1
Warning 1264 Data truncated, out of range for column 'f_double ' at row 1
Warning 1265 Data truncated for column 'f_float ' at row 1
Warning 1264 Data truncated, out of range for column 'f_float ' at row 1
Warning 1265 Data truncated for column 'f_double_7_2 ' at row 1
@ -228,17 +225,15 @@ f_float_3_1_u 0.0
set @value= 1e+1111111111;
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
Warnings:
Warning 1264 Data truncated, out of range for column 'f_double ' at row 1
Warning 1264 Data truncated, out of range for column 'f_float ' at row 1
Warning 1264 Data truncated, out of range for column 'f_double_7_2 ' at row 1
Warning 1264 Data truncated, out of range for column 'f_float_4_3 ' at row 1
Warning 1264 Data truncated, out of range for column 'f_double_u ' at row 1
Warning 1264 Data truncated, out of range for column 'f_float_u ' at row 1
Warning 1264 Data truncated, out of range for column 'f_double_15_1_u ' at row 1
Warning 1264 Data truncated, out of range for column 'f_float_3_1_u ' at row 1
select * from t1 where `number `=last_insert_id();
number 6
original_value inf
original_value 1.7976931348623e+308
f_double 1.79769313486232e+308
f_float 3.40282e+38
f_double_7_2 99999.99
@ -250,7 +245,6 @@ f_float_3_1_u 99.9
set @value= -1e+1111111111;
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
Warnings:
Warning 1264 Data truncated, out of range for column 'f_double ' at row 1
Warning 1264 Data truncated, out of range for column 'f_float ' at row 1
Warning 1264 Data truncated, out of range for column 'f_double_7_2 ' at row 1
Warning 1264 Data truncated, out of range for column 'f_float_4_3 ' at row 1
@ -260,7 +254,7 @@ Warning 1264 Data truncated, out of range for column 'f_double_15_1_u ' at row 1
Warning 1264 Data truncated, out of range for column 'f_float_3_1_u ' at row 1
select * from t1 where `number `=last_insert_id();
number 7
original_value -inf
original_value -1.7976931348623e+308
f_double -1.79769313486232e+308
f_float -3.40282e+38
f_double_7_2 -99999.99

View file

@ -46,8 +46,6 @@ UNLOCK TABLES;
DROP TABLE t1;
CREATE TABLE t1 (a double);
INSERT INTO t1 VALUES (-9e999999);
Warnings:
Warning 1264 Data truncated, out of range for column 'a' at row 1
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT, CHARACTER_SET_CLIENT=utf8 */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
@ -144,7 +142,7 @@ CREATE TABLE t1 (a int) ENGINE=MYISAM;
INSERT INTO t1 VALUES (1), (2);
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_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,MYSQL40" */;
DROP TABLE IF EXISTS `t1`;
CREATE TABLE `t1` (
`a` int(11) default NULL
@ -163,7 +161,7 @@ UNLOCK TABLES;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_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,MYSQL323" */;
DROP TABLE IF EXISTS `t1`;
CREATE TABLE `t1` (
`a` int(11) default NULL
@ -205,6 +203,88 @@ UNLOCK TABLES;
drop table ```a`;
create table t1(a int);
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT, CHARACTER_SET_CLIENT=utf8 */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_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" */;
DROP TABLE IF EXISTS `t1`;
CREATE TABLE `t1` (
`a` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
LOCK TABLES `t1` WRITE;
UNLOCK TABLES;
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_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,ANSI" */;
DROP TABLE IF EXISTS "t1";
CREATE TABLE "t1" (
"a" int(11) default NULL
);
/*!40000 ALTER TABLE "t1" DISABLE KEYS */;
LOCK TABLES "t1" WRITE;
UNLOCK TABLES;
/*!40000 ALTER TABLE "t1" ENABLE KEYS */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
set global sql_mode='ANSI_QUOTES';
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT, CHARACTER_SET_CLIENT=utf8 */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_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" */;
DROP TABLE IF EXISTS `t1`;
CREATE TABLE `t1` (
`a` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
LOCK TABLES `t1` WRITE;
UNLOCK TABLES;
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_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,ANSI" */;
DROP TABLE IF EXISTS "t1";
CREATE TABLE "t1" (
"a" int(11) default NULL
);
/*!40000 ALTER TABLE "t1" DISABLE KEYS */;
LOCK TABLES "t1" WRITE;
UNLOCK TABLES;
/*!40000 ALTER TABLE "t1" ENABLE KEYS */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
set global sql_mode='';
drop table t1;
create table t1(a int);
insert into t1 values (1),(2),(3);
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT, CHARACTER_SET_CLIENT=utf8 */;

View file

@ -25,9 +25,11 @@ t
36:30:31
insert into t1 values("10.22.22"),(1234567),(123456789),(123456789.10),("10 22:22"),("12.45a");
Warnings:
Note 1292 Truncated wrong time value: '10.22.22'
Warning 1264 Data truncated, out of range for column 't' at row 2
Warning 1264 Data truncated, out of range for column 't' at row 3
Warning 1264 Data truncated, out of range for column 't' at row 4
Note 1292 Truncated wrong time value: '12.45a'
select * from t1;
t
10:22:33

View file

@ -346,6 +346,15 @@ create table t2(name varchar(10), age smallint default - 1);
describe t2;
drop table t1, t2;
#
# test for bug #1427 "enum allows duplicate values in the list"
#
create table t1(cenum enum('a'), cset set('b'));
create table t2(cenum enum('a','a'), cset set('b','b'));
create table t3(cenum enum('a','A','a','c','c'), cset set('b','B','b','d','d'));
drop table t1, t2, t3;
#
# Bug #1209
#
@ -359,3 +368,33 @@ select database();
# Connect without a database
connect (user4,localhost,mysqltest_1,,*NO-ONE*);
select database();
#
# Test for Bug 856 'Naming a key "Primary" causes trouble'
#
use test;
--error 1280
create table t1 (a int, index `primary` (a));
--error 1280
create table t1 (a int, index `PRIMARY` (a));
create table t1 (`primary` int, index(`primary`));
show create table t1;
create table t2 (`PRIMARY` int, index(`PRIMARY`));
show create table t2;
create table t3 (a int);
--error 1280
alter table t3 add index `primary` (a);
--error 1280
alter table t3 add index `PRIMARY` (a);
create table t4 (`primary` int);
alter table t4 add index(`primary`);
show create table t4;
create table t5 (`PRIMARY` int);
alter table t5 add index(`PRIMARY`);
show create table t5;
drop table t1, t2, t3, t4, t5;

View file

@ -124,7 +124,7 @@ select str_to_date(concat('15-01-2001',' 2:59:58.999'),
create table t1 (date char(30), format char(30) not null);
insert into t1 values
('2003-01-02 10:11:12', '%Y-%m-%d %H:%i:%S'),
('03-01-02 8:11:2.123456', '%y-%m-%d %H:%i:%S'),
('03-01-02 8:11:2.123456', '%y-%m-%d %H:%i:%S.%#'),
('2003-01-02 10:11:12 PM', '%Y-%m-%d %h:%i:%S %p'),
('2003-01-02 01:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f%p'),
('2003-01-02 02:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f %p'),
@ -209,3 +209,32 @@ create table t1 (d date);
insert into t1 values ('2004-07-14'),('2005-07-14');
select date_format(d,"%d") from t1 order by 1;
drop table t1;
select str_to_date("2003-....01ABCD-02 10:11:12.0012", "%Y-%.%m%@-%d %H:%i:%S.%f") as a;
create table t1 select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f") as f1,
str_to_date("10:11:12.0012", "%H:%i:%S.%f") as f2,
str_to_date("2003-01-02", "%Y-%m-%d") as f3,
str_to_date("02", "%d") as f4, str_to_date("02 10", "%d %H") as f5;
describe t1;
select * from t1;
drop table t1;
create table t1 select "02 10" as a, "%d %H" as b;
select str_to_date(a,b) from t1;
create table t2 select str_to_date(a,b) from t1;
describe t2;
select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f") as f1,
str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S") as f2,
str_to_date("2003-01-02", "%Y-%m-%d") as f3,
str_to_date("02 10:11:12", "%d %H:%i:%S.%f") as f4,
str_to_date("02 10:11:12", "%d %H:%i:%S") as f5,
str_to_date("02 10", "%d %f") as f6;
drop table t1, t2;
select str_to_date("2003-01-02 10:11:12.0012ABCD", "%Y-%m-%d %H:%i:%S.%f") as f1,
addtime("-01:01:01.01 GGG", "-23:59:59.1") as f2,
microsecond("1997-12-31 23:59:59.01XXXX") as f3;
select str_to_date("2003-04-05 g", "%Y-%m-%d") as f1,
str_to_date("2003-04-05 10:11:12.101010234567", "%Y-%m-%d %H:%i:%S.%f") as f2;

View file

@ -97,3 +97,9 @@ SELECT ADDTIME(t1,t2) As ttt, ADDTIME(t2, t3) As qqq from test;
SELECT TIMEDIFF(t1,t4) As ttt, TIMEDIFF(t2, t3) As qqq from test;
drop table t1, test;
select addtime("-01:01:01.01", "-23:59:59.1") as a;
select microsecond("1997-12-31 23:59:59.01") as a;
select microsecond(19971231235959.01) as a;
select date_add("1997-12-31",INTERVAL "10.09" SECOND_MICROSECOND) as a;
select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f");

View file

@ -360,3 +360,16 @@ explain extended select md5('hello'), sha('abc'), sha1('abc'), soundex(''), 'moo
#
SELECT lpad(12345, 5, "#");
#
# Bug #3089
#
create table t1 (id int(1), str varchar(10)) DEFAULT CHARSET=utf8;
insert into t1 values (1,'aaaaaaaaaa'), (2,'bbbbbbbbbb');
create table t2 (id int(1), str varchar(10)) DEFAULT CHARSET=utf8;
insert into t2 values (1,'cccccccccc'), (2,'dddddddddd');
select substring(concat(t1.str, t2.str), 1, 15) "name" from t1, t2
where t2.id=t1.id order by name;
drop table t1, t2;

View file

@ -249,12 +249,18 @@ select last_day('2000-02-05') as f1, last_day('2002-12-31') as f2,
last_day('2001-01-01 01:01:01') as f5, last_day(NULL),
last_day('2001-02-12');
create table t1 select last_day('2000-02-05') as a;
create table t1 select last_day('2000-02-05') as a,
from_days(to_days("960101")) as b;
describe t1;
select * from t1;
drop table t1;
select last_day('2000-02-05');
select last_day('2000-02-05') as a,
from_days(to_days("960101")) as b;
select date_add(last_day("1997-12-1"), INTERVAL 1 DAY);
select length(last_day("1997-12-1"));
select last_day("1997-12-1")+0;
select last_day("1997-12-1")+0.0;
# Test SAPDB UTC_% functions. This part is TZ dependant (It is supposed that
# TZ variable set to GMT-3

View file

@ -72,6 +72,19 @@ create table ```a` (i int);
--exec $MYSQL_DUMP --skip-comments test
drop table ```a`;
#
# Bug #2591 "mysqldump quotes names inconsistently"
#
create table t1(a int);
--exec $MYSQL_DUMP --comments=0 test
--exec $MYSQL_DUMP --comments=0 --compatible=ansi test
set global sql_mode='ANSI_QUOTES';
--exec $MYSQL_DUMP --comments=0 test
--exec $MYSQL_DUMP --comments=0 --compatible=ansi test
set global sql_mode='';
drop table t1;
#
# Bug #2705 'mysqldump --tab extra output'
#

View file

@ -585,11 +585,8 @@ net_safe_read(MYSQL *mysql)
return (packet_error);
#endif /*MYSQL_SERVER*/
end_server(mysql);
net->last_errno=(net->last_errno == ER_NET_PACKET_TOO_LARGE ?
CR_NET_PACKET_TOO_LARGE:
CR_SERVER_LOST);
strmov(net->last_error,ER(net->last_errno));
strmov(net->sqlstate, unknown_sqlstate);
set_mysql_error(mysql, net->last_errno == ER_NET_PACKET_TOO_LARGE ?
CR_NET_PACKET_TOO_LARGE: CR_SERVER_LOST, unknown_sqlstate);
return (packet_error);
}
if (net->read_pos[0] == 255)
@ -609,11 +606,8 @@ net_safe_read(MYSQL *mysql)
min((uint) len,(uint) sizeof(net->last_error)-1));
}
else
{
net->last_errno=CR_UNKNOWN_ERROR;
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error,ER(net->last_errno));
}
set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
DBUG_PRINT("error",("Got error: %d/%s (%s)",
net->last_errno, net->sqlstate, net->last_error));
return(packet_error);
@ -649,8 +643,7 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
}
if (mysql->status != MYSQL_STATUS_READY)
{
strmov(net->last_error,ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
strmov(net->sqlstate, unknown_sqlstate);
set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
return 1;
}
@ -704,6 +697,24 @@ void free_old_query(MYSQL *mysql)
DBUG_VOID_RETURN;
}
/*
Set the internal error message to mysql handler
*/
void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate)
{
NET *net;
DBUG_ENTER("set_mysql_error");
DBUG_PRINT("enter", ("error :%d '%s'", errcode, ER(errcode)));
DBUG_ASSERT(mysql != 0);
net= &mysql->net;
net->last_errno= errcode;
strmov(net->last_error, ER(errcode));
strmov(net->sqlstate, sqlstate);
}
#ifdef __WIN__
static my_bool is_NT(void)
{
@ -1164,9 +1175,7 @@ MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
MYF(MY_WME | MY_ZEROFILL))))
{
net->last_errno=CR_OUT_OF_MEMORY;
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error,ER(net->last_errno));
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
DBUG_RETURN(0);
}
init_alloc_root(&result->alloc,8192,0); /* Assume rowlength < 8192 */
@ -1193,9 +1202,7 @@ MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
(fields+1)*sizeof(char *)+pkt_len))))
{
free_rows(result);
net->last_errno=CR_OUT_OF_MEMORY;
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error,ER(net->last_errno));
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
DBUG_RETURN(0);
}
*prev_ptr=cur;
@ -1214,9 +1221,7 @@ MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
if (len > (ulong) (end_to - to))
{
free_rows(result);
net->last_errno=CR_MALFORMED_PACKET;
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error,ER(net->last_errno));
set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
DBUG_RETURN(0);
}
memcpy(to,(char*) cp,len); to[len]=0;
@ -1287,9 +1292,7 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
{
if (len > (ulong) (end_pos - pos))
{
net->last_errno=CR_UNKNOWN_ERROR;
strmov(net->last_error,ER(net->last_errno));
strmov(net->sqlstate, unknown_sqlstate);
set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
return -1;
}
row[field] = (char*) pos;
@ -1422,7 +1425,7 @@ static MYSQL_METHODS client_methods=
cli_read_binary_rows,
cli_unbuffered_fetch,
NULL,
cli_read_statistic,
cli_read_statistics,
cli_read_query_result,
cli_read_change_user_result
#endif
@ -1675,9 +1678,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
if (!net->vio)
{
DBUG_PRINT("error",("Unknow protocol %d ",mysql->options.protocol));
strmov(net->sqlstate, unknown_sqlstate);
net->last_errno= CR_CONN_UNKNOW_PROTOCOL;
strmov(net->last_error, ER(CR_CONN_UNKNOW_PROTOCOL));
set_mysql_error(mysql, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
goto error;
}
@ -1685,9 +1686,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
{
vio_delete(net->vio);
net->vio = 0;
net->last_errno=CR_OUT_OF_MEMORY;
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error,ER(net->last_errno));
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
goto error;
}
vio_keepalive(net->vio,TRUE);
@ -1704,9 +1703,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
if (mysql->options.connect_timeout &&
vio_poll_read(net->vio, mysql->options.connect_timeout))
{
net->last_errno= CR_SERVER_LOST;
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error,ER(net->last_errno));
set_mysql_error(mysql, CR_SERVER_LOST, unknown_sqlstate);
goto error;
}
@ -1760,8 +1757,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
if (mysql->options.secure_auth && passwd[0] &&
!(mysql->server_capabilities & CLIENT_SECURE_CONNECTION))
{
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error, ER(net->last_errno=CR_SECURE_AUTH));
set_mysql_error(mysql, CR_SECURE_AUTH, unknown_sqlstate);
goto error;
}
@ -1815,8 +1811,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
!(mysql->user=my_strdup(user,MYF(0))) ||
!(mysql->passwd=my_strdup(passwd,MYF(0))))
{
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error, ER(net->last_errno=CR_OUT_OF_MEMORY));
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
goto error;
}
strmov(mysql->host_info,host_info);
@ -1883,9 +1878,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
struct st_mysql_options *options= &mysql->options;
if (my_net_write(net,buff,(uint) (end-buff)) || net_flush(net))
{
strmov(net->sqlstate, unknown_sqlstate);
net->last_errno= CR_SERVER_LOST;
strmov(net->last_error,ER(net->last_errno));
set_mysql_error(mysql, CR_SERVER_LOST, unknown_sqlstate);
goto error;
}
/* Do the SSL layering. */
@ -1896,18 +1889,14 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
options->ssl_capath,
options->ssl_cipher)))
{
strmov(net->sqlstate, unknown_sqlstate);
net->last_errno= CR_SSL_CONNECTION_ERROR;
strmov(net->last_error,ER(net->last_errno));
set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
goto error;
}
DBUG_PRINT("info", ("IO layer change in progress..."));
if (sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd),
mysql->net.vio, (long) (mysql->options.connect_timeout)))
{
strmov(net->sqlstate, unknown_sqlstate);
net->last_errno= CR_SSL_CONNECTION_ERROR;
strmov(net->last_error,ER(net->last_errno));
set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
goto error;
}
DBUG_PRINT("info", ("IO layer change done!"));
@ -1956,9 +1945,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
/* Write authentication package */
if (my_net_write(net,buff,(ulong) (end-buff)) || net_flush(net))
{
strmov(net->sqlstate, unknown_sqlstate);
net->last_errno= CR_SERVER_LOST;
strmov(net->last_error,ER(net->last_errno));
set_mysql_error(mysql, CR_SERVER_LOST, unknown_sqlstate);
goto error;
}
@ -1980,9 +1967,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
scramble_323(buff, mysql->scramble, passwd);
if (my_net_write(net, buff, SCRAMBLE_LENGTH_323 + 1) || net_flush(net))
{
net->last_errno= CR_SERVER_LOST;
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error,ER(net->last_errno));
set_mysql_error(mysql, CR_SERVER_LOST, unknown_sqlstate);
goto error;
}
/* Read what server thinks about out new auth message report */
@ -2077,9 +2062,7 @@ my_bool mysql_reconnect(MYSQL *mysql)
{
/* Allow reconnect next time */
mysql->server_status&= ~SERVER_STATUS_IN_TRANS;
strmov(mysql->net.sqlstate, unknown_sqlstate);
mysql->net.last_errno=CR_SERVER_GONE_ERROR;
strmov(mysql->net.last_error,ER(mysql->net.last_errno));
set_mysql_error(mysql, CR_SERVER_GONE_ERROR, unknown_sqlstate);
DBUG_RETURN(1);
}
mysql_init(&tmp_mysql);
@ -2363,9 +2346,7 @@ MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql)
DBUG_RETURN(0);
if (mysql->status != MYSQL_STATUS_GET_RESULT)
{
strmov(mysql->net.sqlstate, unknown_sqlstate);
strmov(mysql->net.last_error,
ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
DBUG_RETURN(0);
}
mysql->status=MYSQL_STATUS_READY; /* server is ready */
@ -2374,9 +2355,7 @@ MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql)
mysql->field_count),
MYF(MY_WME | MY_ZEROFILL))))
{
strmov(mysql->net.sqlstate, unknown_sqlstate);
mysql->net.last_errno=CR_OUT_OF_MEMORY;
strmov(mysql->net.last_error, ER(mysql->net.last_errno));
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
DBUG_RETURN(0);
}
result->methods= mysql->methods;
@ -2421,9 +2400,7 @@ static MYSQL_RES * cli_use_result(MYSQL *mysql)
DBUG_RETURN(0);
if (mysql->status != MYSQL_STATUS_GET_RESULT)
{
strmov(mysql->net.sqlstate, unknown_sqlstate);
strmov(mysql->net.last_error,
ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
DBUG_RETURN(0);
}
if (!(result=(MYSQL_RES*) my_malloc(sizeof(*result)+
@ -2592,3 +2569,4 @@ const char * STDCALL mysql_error(MYSQL *mysql)
{
return mysql->net.last_error;
}

View file

@ -4765,7 +4765,8 @@ void Field_blob::get_key_image(char *buff,uint length,
{
const char *dummy;
MBR mbr;
Geometry gobj;
Geometry_buffer buffer;
Geometry *gobj;
if (blob_length < SRID_SIZE)
{
@ -4773,8 +4774,9 @@ void Field_blob::get_key_image(char *buff,uint length,
return;
}
get_ptr(&blob);
gobj.create_from_wkb(blob + SRID_SIZE, blob_length - SRID_SIZE);
if (gobj.get_mbr(&mbr, &dummy))
gobj= Geometry::create_from_wkb(&buffer,
blob + SRID_SIZE, blob_length - SRID_SIZE);
if (gobj->get_mbr(&mbr, &dummy))
bzero(buff, SIZEOF_STORED_DOUBLE*4);
else
{
@ -5013,9 +5015,11 @@ void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
return;
}
get_ptr(&blob);
Geometry gobj;
gobj.create_from_wkb(blob + SRID_SIZE, blob_length - SRID_SIZE);
if (gobj.get_mbr(&mbr, &dummy))
Geometry_buffer buffer;
Geometry *gobj;
gobj= Geometry::create_from_wkb(&buffer,
blob + SRID_SIZE, blob_length - SRID_SIZE);
if (gobj->get_mbr(&mbr, &dummy))
bzero(buff, SIZEOF_STORED_DOUBLE*4);
else
{
@ -5075,7 +5079,7 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs)
if (length < SRID_SIZE + WKB_HEADER_SIZE + SIZEOF_STORED_DOUBLE*2)
goto err;
wkb_type= uint4korr(from + WKB_HEADER_SIZE);
if (wkb_type < (uint32) Geometry::wkbPoint ||
if (wkb_type < (uint32) Geometry::wkb_point ||
wkb_type > (uint32) Geometry::wkb_end)
return 1;
Field_blob::store_length(length);

View file

@ -24,7 +24,7 @@
enum Gis_read_stream::enum_tok_types Gis_read_stream::get_next_toc_type()
{
skip_space();
if (!*m_cur)
if (m_cur >= m_limit)
return eostream;
if (my_isvar_start(&my_charset_bin, *m_cur))
return word;
@ -53,7 +53,7 @@ bool Gis_read_stream::get_next_word(LEX_STRING *res)
my_isvar() is a macro that would cause side effects
*/
m_cur++;
while (my_isvar(&my_charset_bin, *m_cur))
while ((m_cur < m_limit) && my_isvar(&my_charset_bin, *m_cur))
m_cur++;
res->length= (uint32) (m_cur - res->str);
@ -71,16 +71,21 @@ bool Gis_read_stream::get_next_word(LEX_STRING *res)
bool Gis_read_stream::get_next_number(double *d)
{
char *endptr;
int err;
skip_space();
/* The following will also test for end \0 */
if ((*m_cur < '0' || *m_cur > '9') && *m_cur != '-' && *m_cur != '+')
if ((m_cur >= m_limit) ||
(*m_cur < '0' || *m_cur > '9') && *m_cur != '-' && *m_cur != '+')
{
set_error_msg("Numeric constant expected");
return 1;
}
*d = my_strtod(m_cur, &endptr);
*d = my_strntod(m_charset, (char *)m_cur,
m_limit-m_cur, &endptr, &err);
if (err)
return 1;
if (endptr)
m_cur = endptr;
return 0;
@ -90,7 +95,7 @@ bool Gis_read_stream::get_next_number(double *d)
bool Gis_read_stream::check_next_symbol(char symbol)
{
skip_space();
if (*m_cur != symbol)
if ((m_cur >= m_limit) || (*m_cur != symbol))
{
char buff[32];
strmov(buff, "'?' expected");

View file

@ -29,8 +29,8 @@ public:
comma
};
Gis_read_stream(const char *buffer, int size)
:m_cur(buffer), m_limit(buffer + size), m_err_msg(NULL)
Gis_read_stream(CHARSET_INFO *charset, const char *buffer, int size)
:m_cur(buffer), m_limit(buffer + size), m_err_msg(NULL), m_charset(charset)
{}
Gis_read_stream(): m_cur(NullS), m_limit(NullS), m_err_msg(NullS)
{}
@ -46,14 +46,14 @@ public:
inline void skip_space()
{
while (my_isspace(&my_charset_latin1, *m_cur))
while ((m_cur < m_limit) && my_isspace(&my_charset_latin1, *m_cur))
m_cur++;
}
/* Skip next character, if match. Return 1 if no match */
inline bool skip_char(char skip)
{
skip_space();
if (*m_cur != skip)
if ((m_cur >= m_limit) || *m_cur != skip)
return 1; /* Didn't find char */
m_cur++;
return 0;
@ -72,4 +72,5 @@ protected:
const char *m_cur;
const char *m_limit;
char *m_err_msg;
CHARSET_INFO *m_charset;
};

View file

@ -30,10 +30,14 @@
String *Item_func_geometry_from_text::val_str(String *str)
{
Geometry geom;
Geometry_buffer buffer;
String arg_val;
String *wkt= args[0]->val_str(&arg_val);
Gis_read_stream trs(wkt->c_ptr(), wkt->length());
if ((null_value= args[0]->null_value))
return 0;
Gis_read_stream trs(wkt->charset(), wkt->ptr(), wkt->length());
uint32 srid= 0;
if ((arg_count == 2) && !args[1]->null_value)
@ -43,7 +47,7 @@ String *Item_func_geometry_from_text::val_str(String *str)
return 0;
str->length(0);
str->q_append(srid);
if ((null_value=(args[0]->null_value || geom.create_from_wkt(&trs, str, 0))))
if ((null_value= !Geometry::create_from_wkt(&buffer, &trs, str, 0)))
return 0;
return str;
}
@ -59,7 +63,8 @@ String *Item_func_geometry_from_wkb::val_str(String *str)
{
String arg_val;
String *wkb= args[0]->val_str(&arg_val);
Geometry geom;
Geometry_buffer buffer;
Geometry *geom;
uint32 srid= 0;
if ((arg_count == 2) && !args[1]->null_value)
@ -69,9 +74,10 @@ String *Item_func_geometry_from_wkb::val_str(String *str)
return 0;
str->length(0);
str->q_append(srid);
if ((null_value= (args[0]->null_value ||
geom.create_from_wkb(wkb->ptr(), wkb->length()))) ||
str->append(*wkb))
if ((null_value=
(args[0]->null_value ||
!(geom= Geometry::create_from_wkb(&buffer, wkb->ptr(), wkb->length())) ||
str->append(*wkb))))
return 0;
return str;
}
@ -87,16 +93,18 @@ String *Item_func_as_wkt::val_str(String *str)
{
String arg_val;
String *swkb= args[0]->val_str(&arg_val);
Geometry geom;
Geometry_buffer buffer;
Geometry *geom= NULL;
const char *dummy;
if ((null_value= (args[0]->null_value ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE))))
if ((null_value=
(args[0]->null_value ||
!(geom= Geometry::create_from_wkb(&buffer, swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE)))))
return 0;
str->length(0);
if ((null_value= geom.as_wkt(str, &dummy)))
if ((null_value= geom->as_wkt(str, &dummy)))
return 0;
return str;
@ -113,11 +121,13 @@ String *Item_func_as_wkb::val_str(String *str)
{
String arg_val;
String *swkb= args[0]->val_str(&arg_val);
Geometry geom;
Geometry_buffer buffer;
Geometry *geom;
if ((null_value= (args[0]->null_value ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE))))
if ((null_value=
(args[0]->null_value ||
!(geom= Geometry::create_from_wkb(&buffer, swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE)))))
return 0;
str->copy(swkb->ptr() + SRID_SIZE, swkb->length() - SRID_SIZE,
@ -135,15 +145,17 @@ void Item_func_as_wkb::fix_length_and_dec()
String *Item_func_geometry_type::val_str(String *str)
{
String *swkb= args[0]->val_str(str);
Geometry geom;
Geometry_buffer buffer;
Geometry *geom= NULL;
if ((null_value= (args[0]->null_value ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE))))
if ((null_value=
(args[0]->null_value ||
!(geom= Geometry::create_from_wkb(&buffer, swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE)))))
return 0;
/* String will not move */
str->set(geom.get_class_info()->m_name.str,
geom.get_class_info()->m_name.length,
str->set(geom->get_class_info()->m_name.str,
geom->get_class_info()->m_name.length,
default_charset());
return str;
}
@ -153,12 +165,14 @@ String *Item_func_envelope::val_str(String *str)
{
String arg_val;
String *swkb= args[0]->val_str(&arg_val);
Geometry geom;
Geometry_buffer buffer;
Geometry *geom= NULL;
uint32 srid;
if ((null_value= args[0]->null_value ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE)))
if ((null_value=
args[0]->null_value ||
!(geom= Geometry::create_from_wkb(&buffer, swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE))))
return 0;
srid= uint4korr(swkb->ptr());
@ -166,7 +180,7 @@ String *Item_func_envelope::val_str(String *str)
if (str->reserve(SRID_SIZE, 512))
return 0;
str->q_append(srid);
return (null_value= geom.envelope(str)) ? 0 : str;
return (null_value= geom->envelope(str)) ? 0 : str;
}
@ -174,13 +188,13 @@ String *Item_func_centroid::val_str(String *str)
{
String arg_val;
String *swkb= args[0]->val_str(&arg_val);
Geometry geom;
Geometry_buffer buffer;
Geometry *geom= NULL;
uint32 srid;
if ((null_value= args[0]->null_value ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE) ||
!GEOM_METHOD_PRESENT(geom, centroid)))
!(geom= Geometry::create_from_wkb(&buffer, swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE))))
return 0;
if (str->reserve(SRID_SIZE, 512))
@ -189,7 +203,7 @@ String *Item_func_centroid::val_str(String *str)
srid= uint4korr(swkb->ptr());
str->q_append(srid);
return (null_value= test(geom.centroid(str))) ? 0 : str;
return (null_value= test(geom->centroid(str))) ? 0 : str;
}
@ -201,12 +215,14 @@ String *Item_func_spatial_decomp::val_str(String *str)
{
String arg_val;
String *swkb= args[0]->val_str(&arg_val);
Geometry geom;
Geometry_buffer buffer;
Geometry *geom= NULL;
uint32 srid;
if ((null_value= (args[0]->null_value ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE))))
if ((null_value=
(args[0]->null_value ||
!(geom= Geometry::create_from_wkb(&buffer, swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE)))))
return 0;
srid= uint4korr(swkb->ptr());
@ -216,17 +232,17 @@ String *Item_func_spatial_decomp::val_str(String *str)
str->q_append(srid);
switch (decomp_func) {
case SP_STARTPOINT:
if (!GEOM_METHOD_PRESENT(geom,start_point) || geom.start_point(str))
if (geom->start_point(str))
goto err;
break;
case SP_ENDPOINT:
if (!GEOM_METHOD_PRESENT(geom,end_point) || geom.end_point(str))
if (geom->end_point(str))
goto err;
break;
case SP_EXTERIORRING:
if (!GEOM_METHOD_PRESENT(geom,exterior_ring) || geom.exterior_ring(str))
if (geom->exterior_ring(str))
goto err;
break;
@ -246,12 +262,14 @@ String *Item_func_spatial_decomp_n::val_str(String *str)
String arg_val;
String *swkb= args[0]->val_str(&arg_val);
long n= (long) args[1]->val_int();
Geometry geom;
Geometry_buffer buffer;
Geometry *geom= NULL;
uint32 srid;
if ((null_value= (args[0]->null_value || args[1]->null_value ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE))))
if ((null_value=
(args[0]->null_value || args[1]->null_value ||
!(geom= Geometry::create_from_wkb(&buffer, swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE)))))
return 0;
if (str->reserve(SRID_SIZE, 512))
@ -262,18 +280,17 @@ String *Item_func_spatial_decomp_n::val_str(String *str)
switch (decomp_func_n)
{
case SP_POINTN:
if (!GEOM_METHOD_PRESENT(geom,point_n) || geom.point_n(n,str))
if (geom->point_n(n,str))
goto err;
break;
case SP_GEOMETRYN:
if (!GEOM_METHOD_PRESENT(geom,geometry_n) || geom.geometry_n(n,str))
if (geom->geometry_n(n,str))
goto err;
break;
case SP_INTERIORRINGN:
if (!GEOM_METHOD_PRESENT(geom,interior_ring_n) ||
geom.interior_ring_n(n,str))
if (geom->interior_ring_n(n,str))
goto err;
break;
@ -309,8 +326,8 @@ String *Item_func_point::val_str(String *str)
return 0;
str->length(0);
str->q_append((char)Geometry::wkbNDR);
str->q_append((uint32)Geometry::wkbPoint);
str->q_append((char)Geometry::wkb_ndr);
str->q_append((uint32)Geometry::wkb_point);
str->q_append(x);
str->q_append(y);
return str;
@ -336,7 +353,7 @@ String *Item_func_spatial_collection::val_str(String *str)
if (str->reserve(1 + 4 + 4, 512))
goto err;
str->q_append((char) Geometry::wkbNDR);
str->q_append((char) Geometry::wkb_ndr);
str->q_append((uint32) coll_type);
str->q_append((uint32) arg_count);
@ -346,7 +363,7 @@ String *Item_func_spatial_collection::val_str(String *str)
if (args[i]->null_value)
goto err;
if (coll_type == Geometry::wkbGeometryCollection)
if (coll_type == Geometry::wkb_geometrycollection)
{
/*
In the case of GeometryCollection we don't need any checkings
@ -375,19 +392,19 @@ String *Item_func_spatial_collection::val_str(String *str)
goto err;
switch (coll_type) {
case Geometry::wkbMultiPoint:
case Geometry::wkbMultiLineString:
case Geometry::wkbMultiPolygon:
case Geometry::wkb_multipoint:
case Geometry::wkb_multilinestring:
case Geometry::wkb_multipolygon:
if (len < WKB_HEADER_SIZE ||
str->append(data-WKB_HEADER_SIZE, len+WKB_HEADER_SIZE, 512))
goto err;
break;
case Geometry::wkbLineString:
case Geometry::wkb_linestring:
if (str->append(data, POINT_DATA_SIZE, 512))
goto err;
break;
case Geometry::wkbPolygon:
case Geometry::wkb_polygon:
{
uint32 n_points;
double x1, y1, x2, y2;
@ -439,18 +456,20 @@ longlong Item_func_spatial_rel::val_int()
{
String *res1= args[0]->val_str(&tmp_value1);
String *res2= args[1]->val_str(&tmp_value2);
Geometry g1, g2;
Geometry_buffer buffer1, buffer2;
Geometry *g1, *g2;
MBR mbr1, mbr2;
const char *dummy;
if ((null_value= (args[0]->null_value ||
args[1]->null_value ||
g1.create_from_wkb(res1->ptr() + SRID_SIZE,
res1->length() - SRID_SIZE) ||
g2.create_from_wkb(res2->ptr() + SRID_SIZE,
res2->length() - SRID_SIZE) ||
g1.get_mbr(&mbr1, &dummy) ||
g2.get_mbr(&mbr2, &dummy))))
if ((null_value=
(args[0]->null_value ||
args[1]->null_value ||
!(g1= Geometry::create_from_wkb(&buffer1, res1->ptr() + SRID_SIZE,
res1->length() - SRID_SIZE)) ||
!(g2= Geometry::create_from_wkb(&buffer2, res2->ptr() + SRID_SIZE,
res2->length() - SRID_SIZE)) ||
g1->get_mbr(&mbr1, &dummy) ||
g2->get_mbr(&mbr2, &dummy))))
return 0;
switch (spatial_rel) {
@ -503,15 +522,16 @@ longlong Item_func_isclosed::val_int()
{
String tmp;
String *swkb= args[0]->val_str(&tmp);
Geometry geom;
Geometry_buffer buffer;
Geometry *geom;
int isclosed= 0; // In case of error
null_value= (!swkb ||
args[0]->null_value ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE) ||
!GEOM_METHOD_PRESENT(geom,is_closed) ||
geom.is_closed(&isclosed));
!(geom=
Geometry::create_from_wkb(&buffer, swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE)) ||
geom->is_closed(&isclosed));
return (longlong) isclosed;
}
@ -525,14 +545,16 @@ longlong Item_func_dimension::val_int()
{
uint32 dim= 0; // In case of error
String *swkb= args[0]->val_str(&value);
Geometry geom;
Geometry_buffer buffer;
Geometry *geom;
const char *dummy;
null_value= (!swkb ||
args[0]->null_value ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE) ||
geom.dimension(&dim, &dummy));
!(geom= Geometry::create_from_wkb(&buffer,
swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE)) ||
geom->dimension(&dim, &dummy));
return (longlong) dim;
}
@ -541,13 +563,14 @@ longlong Item_func_numinteriorring::val_int()
{
uint32 num= 0; // In case of error
String *swkb= args[0]->val_str(&value);
Geometry geom;
Geometry_buffer buffer;
Geometry *geom;
null_value= (!swkb ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE) ||
!GEOM_METHOD_PRESENT(geom, num_interior_ring) ||
geom.num_interior_ring(&num));
!(geom= Geometry::create_from_wkb(&buffer,
swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE)) ||
geom->num_interior_ring(&num));
return (longlong) num;
}
@ -556,13 +579,14 @@ longlong Item_func_numgeometries::val_int()
{
uint32 num= 0; // In case of errors
String *swkb= args[0]->val_str(&value);
Geometry geom;
Geometry_buffer buffer;
Geometry *geom;
null_value= (!swkb ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE) ||
!GEOM_METHOD_PRESENT(geom, num_geometries) ||
geom.num_geometries(&num));
!(geom= Geometry::create_from_wkb(&buffer,
swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE)) ||
geom->num_geometries(&num));
return (longlong) num;
}
@ -571,14 +595,15 @@ longlong Item_func_numpoints::val_int()
{
uint32 num= 0; // In case of errors
String *swkb= args[0]->val_str(&value);
Geometry geom;
Geometry_buffer buffer;
Geometry *geom;
null_value= (!swkb ||
args[0]->null_value ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE) ||
!GEOM_METHOD_PRESENT(geom, num_points) ||
geom.num_points(&num));
!(geom= Geometry::create_from_wkb(&buffer,
swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE)) ||
geom->num_points(&num));
return (longlong) num;
}
@ -587,13 +612,14 @@ double Item_func_x::val()
{
double res= 0.0; // In case of errors
String *swkb= args[0]->val_str(&value);
Geometry geom;
Geometry_buffer buffer;
Geometry *geom;
null_value= (!swkb ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE) ||
!GEOM_METHOD_PRESENT(geom, get_x) ||
geom.get_x(&res));
!(geom= Geometry::create_from_wkb(&buffer,
swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE)) ||
geom->get_x(&res));
return res;
}
@ -602,13 +628,14 @@ double Item_func_y::val()
{
double res= 0; // In case of errors
String *swkb= args[0]->val_str(&value);
Geometry geom;
Geometry_buffer buffer;
Geometry *geom;
null_value= (!swkb ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE) ||
!GEOM_METHOD_PRESENT(geom, get_y) ||
geom.get_y(&res));
!(geom= Geometry::create_from_wkb(&buffer,
swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE)) ||
geom->get_y(&res));
return res;
}
@ -617,14 +644,15 @@ double Item_func_area::val()
{
double res= 0; // In case of errors
String *swkb= args[0]->val_str(&value);
Geometry geom;
Geometry_buffer buffer;
Geometry *geom;
const char *dummy;
null_value= (!swkb ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE) ||
!GEOM_METHOD_PRESENT(geom, area) ||
geom.area(&res, &dummy));
!(geom= Geometry::create_from_wkb(&buffer,
swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE)) ||
geom->area(&res, &dummy));
return res;
}
@ -632,24 +660,27 @@ double Item_func_glength::val()
{
double res= 0; // In case of errors
String *swkb= args[0]->val_str(&value);
Geometry geom;
Geometry_buffer buffer;
Geometry *geom;
null_value= (!swkb ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE) ||
!GEOM_METHOD_PRESENT(geom, length) ||
geom.length(&res));
!(geom= Geometry::create_from_wkb(&buffer,
swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE)) ||
geom->length(&res));
return res;
}
longlong Item_func_srid::val_int()
{
String *swkb= args[0]->val_str(&value);
Geometry geom;
Geometry_buffer buffer;
Geometry *geom;
null_value= (!swkb ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE));
null_value= !swkb ||
!(geom= Geometry::create_from_wkb(&buffer,
swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE));
if (null_value)
return 0;

View file

@ -1033,7 +1033,7 @@ void Item_func_substr::fix_length_and_dec()
}
if (arg_count == 3 && args[2]->const_item())
{
int32 length= (int32) args[2]->val_int() * default_charset_info->mbmaxlen;
int32 length= (int32) args[2]->val_int() * collation.collation->mbmaxlen;
if (length <= 0)
max_length=0; /* purecov: inspected */
else
@ -2241,7 +2241,7 @@ String *Item_func_hex::val_str(String *str)
return &tmp_value;
}
int inline hexchar_to_int(char c)
inline int hexchar_to_int(char c)
{
if (c <= '9' && c >= '0')
return c-'0';
@ -2721,7 +2721,7 @@ String *Item_func_uuid::val_str(String *str)
{
ulong tmp=sql_rnd_with_mutex();
uchar mac[6];
int i;
unsigned int i;
if (my_gethwaddr(mac))
{
/*
@ -2754,7 +2754,14 @@ String *Item_func_uuid::val_str(String *str)
tv++;
}
else
nanoseq=0;
{
if (nanoseq)
{
tv-=nanoseq;
nanoseq=0;
}
DBUG_ASSERT(tv > uuid_time);
}
uuid_time=tv;
pthread_mutex_unlock(&LOCK_uuid_generator);

View file

@ -48,11 +48,6 @@ TYPELIB day_names_typelib=
{ array_elements(day_names)-1,"", day_names};
enum date_time_format_types
{
TIME_ONLY= 0, TIME_MICROSECOND, DATE_ONLY, DATE_TIME, DATE_TIME_MICROSECOND
};
/*
OPTIMIZATION TODO:
- Replace the switch with a function that should be called for each
@ -128,6 +123,9 @@ static bool make_datetime(date_time_format_types format, TIME *ltime,
val String to decode
length Length of string
l_time Store result here
cached_timestamp_type
It uses to get an appropriate warning
in the case when the value is truncated.
RETURN
0 ok
@ -135,7 +133,8 @@ static bool make_datetime(date_time_format_types format, TIME *ltime,
*/
static bool extract_date_time(DATE_TIME_FORMAT *format,
const char *val, uint length, TIME *l_time)
const char *val, uint length, TIME *l_time,
timestamp_type cached_timestamp_type)
{
int weekday= 0, yearday= 0, daypart= 0;
int week_number= -1;
@ -143,9 +142,11 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
int error= 0;
bool usa_time= 0;
bool sunday_first= 0;
int frac_part;
const char *val_begin= val;
const char *val_end= val + length;
const char *ptr= format->format.str;
const char *end= ptr+ format->format.length;
const char *end= ptr + format->format.length;
DBUG_ENTER("extract_date_time");
bzero((char*) l_time, sizeof(*l_time));
@ -235,7 +236,12 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
/* Second part */
case 'f':
tmp= (char*) val_end;
if (tmp - val > 6)
tmp= (char*) val + 6;
l_time->second_part= (int) my_strtoll10(val, &tmp, &error);
frac_part= 6 - (tmp - val);
if (frac_part > 0)
l_time->second_part*= (ulong) log_10_int[frac_part];
val= tmp;
break;
@ -251,6 +257,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
(const uchar *) val, 2,
(const uchar *) "AM", 2))
goto err;
val+= 2;
break;
/* Exotic things */
@ -281,6 +288,18 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
val= tmp;
break;
case '.':
while (my_ispunct(cs, *val) && val != val_end)
val++;
break;
case '@':
while (my_isalpha(cs, *val) && val != val_end)
val++;
break;
case '#':
while (my_isdigit(cs, *val) && val != val_end)
val++;
break;
default:
goto err;
}
@ -348,6 +367,18 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
l_time->minute > 59 || l_time->second > 59)
goto err;
if (val != val_end)
{
do
{
if (!my_isspace(&my_charset_latin1,*val))
{
make_truncated_value_warning(current_thd, val_begin, length,
cached_timestamp_type);
break;
}
} while (++val != val_end);
}
DBUG_RETURN(0);
err:
@ -584,16 +615,27 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
/*
** Get a array of positive numbers from a string object.
** Each number is separated by 1 non digit character
** Return error if there is too many numbers.
** If there is too few numbers, assume that the numbers are left out
** from the high end. This allows one to give:
** DAY_TO_SECOND as "D MM:HH:SS", "MM:HH:SS" "HH:SS" or as seconds.
Get a array of positive numbers from a string object.
Each number is separated by 1 non digit character
Return error if there is too many numbers.
If there is too few numbers, assume that the numbers are left out
from the high end. This allows one to give:
DAY_TO_SECOND as "D MM:HH:SS", "MM:HH:SS" "HH:SS" or as seconds.
SYNOPSIS
str: string value
length: length of str
cs: charset of str
values: array of results
count: count of elements in result array
transform_msec: if value is true we suppose
that the last part of string value is microseconds
and we should transform value to six digit value.
For example, '1.1' -> '1.100000'
*/
bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
uint count, long *values)
uint count, long *values, bool transform_msec)
{
const char *end=str+length;
uint i;
@ -603,8 +645,15 @@ bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
for (i=0 ; i < count ; i++)
{
long value;
const char *start= str;
for (value=0; str != end && my_isdigit(cs,*str) ; str++)
value=value*10L + (long) (*str - '0');
if (transform_msec && i == count - 1) // microseconds always last
{
long msec_length= 6 - (str - start);
if (msec_length > 0)
value*= (long) log_10_int[msec_length];
}
values[i]= value;
while (str != end && !my_isdigit(cs,*str))
str++;
@ -925,19 +974,19 @@ static bool get_interval_value(Item *args,interval_type int_type,
interval->second=value;
break;
case INTERVAL_YEAR_MONTH: // Allow YEAR-MONTH YYYYYMM
if (get_interval_info(str,length,cs,2,array))
if (get_interval_info(str,length,cs,2,array,0))
return (1);
interval->year=array[0];
interval->month=array[1];
break;
case INTERVAL_DAY_HOUR:
if (get_interval_info(str,length,cs,2,array))
if (get_interval_info(str,length,cs,2,array,0))
return (1);
interval->day=array[0];
interval->hour=array[1];
break;
case INTERVAL_DAY_MICROSECOND:
if (get_interval_info(str,length,cs,5,array))
if (get_interval_info(str,length,cs,5,array,1))
return (1);
interval->day=array[0];
interval->hour=array[1];
@ -946,14 +995,14 @@ static bool get_interval_value(Item *args,interval_type int_type,
interval->second_part=array[4];
break;
case INTERVAL_DAY_MINUTE:
if (get_interval_info(str,length,cs,3,array))
if (get_interval_info(str,length,cs,3,array,0))
return (1);
interval->day=array[0];
interval->hour=array[1];
interval->minute=array[2];
break;
case INTERVAL_DAY_SECOND:
if (get_interval_info(str,length,cs,4,array))
if (get_interval_info(str,length,cs,4,array,0))
return (1);
interval->day=array[0];
interval->hour=array[1];
@ -961,7 +1010,7 @@ static bool get_interval_value(Item *args,interval_type int_type,
interval->second=array[3];
break;
case INTERVAL_HOUR_MICROSECOND:
if (get_interval_info(str,length,cs,4,array))
if (get_interval_info(str,length,cs,4,array,1))
return (1);
interval->hour=array[0];
interval->minute=array[1];
@ -969,33 +1018,33 @@ static bool get_interval_value(Item *args,interval_type int_type,
interval->second_part=array[3];
break;
case INTERVAL_HOUR_MINUTE:
if (get_interval_info(str,length,cs,2,array))
if (get_interval_info(str,length,cs,2,array,0))
return (1);
interval->hour=array[0];
interval->minute=array[1];
break;
case INTERVAL_HOUR_SECOND:
if (get_interval_info(str,length,cs,3,array))
if (get_interval_info(str,length,cs,3,array,0))
return (1);
interval->hour=array[0];
interval->minute=array[1];
interval->second=array[2];
break;
case INTERVAL_MINUTE_MICROSECOND:
if (get_interval_info(str,length,cs,3,array))
if (get_interval_info(str,length,cs,3,array,1))
return (1);
interval->minute=array[0];
interval->second=array[1];
interval->second_part=array[2];
break;
case INTERVAL_MINUTE_SECOND:
if (get_interval_info(str,length,cs,2,array))
if (get_interval_info(str,length,cs,2,array,0))
return (1);
interval->minute=array[0];
interval->second=array[1];
break;
case INTERVAL_SECOND_MICROSECOND:
if (get_interval_info(str,length,cs,2,array))
if (get_interval_info(str,length,cs,2,array,1))
return (1);
interval->second=array[0];
interval->second_part=array[1];
@ -1008,22 +1057,13 @@ static bool get_interval_value(Item *args,interval_type int_type,
String *Item_date::val_str(String *str)
{
TIME ltime;
ulong value=(ulong) val_int();
if (null_value)
return (String*) 0;
if (get_date(&ltime, TIME_FUZZY_DATE))
return (String *) 0;
if (str->alloc(11))
{
null_value= 1;
return (String *) 0;
}
ltime.year= (value/10000L) % 10000;
ltime.month= (value/100)%100;
ltime.day= (value%100);
ltime.neg= 0;
ltime.time_type=TIMESTAMP_DATE;
make_date((DATE_TIME_FORMAT *) 0, &ltime, str);
return str;
}
@ -1032,28 +1072,31 @@ String *Item_date::val_str(String *str)
int Item_date::save_in_field(Field *field, bool no_conversions)
{
TIME ltime;
timestamp_type t_type=TIMESTAMP_DATETIME;
if (get_date(&ltime, TIME_FUZZY_DATE))
{
if (null_value)
return set_field_to_null(field);
t_type=TIMESTAMP_NONE; // Error
}
return set_field_to_null(field);
field->set_notnull();
field->store_time(&ltime,t_type);
field->store_time(&ltime, TIMESTAMP_DATE);
return 0;
}
longlong Item_func_from_days::val_int()
longlong Item_date::val_int()
{
TIME ltime;
if (get_date(&ltime, TIME_FUZZY_DATE))
return 0;
return (longlong) (ltime.year*10000L+ltime.month*100+ltime.day);
}
bool Item_func_from_days::get_date(TIME *ltime, uint fuzzy_date)
{
longlong value=args[0]->val_int();
if ((null_value=args[0]->null_value))
return 0; /* purecov: inspected */
uint year,month,day;
get_date_from_daynr((long) value,&year,&month,&day);
return (longlong) (year*10000L+month*100+day);
return 1;
get_date_from_daynr((long) value, &ltime->year, &ltime->month, &ltime->day);
ltime->time_type= TIMESTAMP_DATE;
return 0;
}
@ -1082,6 +1125,16 @@ void Item_func_curdate::fix_length_and_dec()
ltime.time_type=TIMESTAMP_DATE;
}
String *Item_func_curdate::val_str(String *str)
{
if (str->alloc(11))
{
null_value= 1;
return (String *) 0;
}
make_date((DATE_TIME_FORMAT *) 0, &ltime, str);
return str;
}
bool Item_func_curdate::get_date(TIME *res,
uint fuzzy_date __attribute__((unused)))
@ -2311,6 +2364,103 @@ void Item_func_get_format::print(String *str)
}
/*
check_result_type(s, l) returns DATE/TIME type
according to format string
s: DATE/TIME format string
l: length of s
Result: date_time_format_types value:
DATE_TIME_MICROSECOND, DATE_TIME,
TIME_MICROSECOND, TIME_ONLY
We don't process day format's characters('D', 'd', 'e')
because day may be a member of all date/time types.
If only day format's character and no time part present
the result type is MYSQL_TYPE_DATE
*/
date_time_format_types check_result_type(const char *format, uint length)
{
const char *time_part_frms= "HISThiklrs";
const char *date_part_frms= "MUYWabcjmuyw";
bool date_part_used= 0, time_part_used= 0, frac_second_used= 0;
const char *val= format;
const char *end= format + length;
for (; val != end && val != end; val++)
{
if (*val == '%' && val+1 != end)
{
val++;
if ((frac_second_used= (*val == 'f')) ||
(!time_part_used && strchr(time_part_frms, *val)))
time_part_used= 1;
else if (!date_part_used && strchr(date_part_frms, *val))
date_part_used= 1;
if (time_part_used && date_part_used && frac_second_used)
return DATE_TIME_MICROSECOND;
}
}
if (time_part_used)
{
if (date_part_used)
return DATE_TIME;
if (frac_second_used)
return TIME_MICROSECOND;
return TIME_ONLY;
}
return DATE_ONLY;
}
Field *Item_func_str_to_date::tmp_table_field(TABLE *t_arg)
{
if (cached_field_type == MYSQL_TYPE_TIME)
return (new Field_time(maybe_null, name, t_arg, &my_charset_bin));
if (cached_field_type == MYSQL_TYPE_DATE)
return (new Field_date(maybe_null, name, t_arg, &my_charset_bin));
if (cached_field_type == MYSQL_TYPE_DATETIME)
return (new Field_datetime(maybe_null, name, t_arg, &my_charset_bin));
return (new Field_string(max_length, maybe_null, name, t_arg, &my_charset_bin));
}
void Item_func_str_to_date::fix_length_and_dec()
{
char format_buff[64];
String format_str(format_buff, sizeof(format_buff), &my_charset_bin), *format;
maybe_null= 1;
decimals=0;
cached_field_type= MYSQL_TYPE_STRING;
max_length= MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
cached_timestamp_type= TIMESTAMP_NONE;
if ((const_item= args[1]->const_item()))
{
format= args[1]->val_str(&format_str);
cached_format_type= check_result_type(format->ptr(), format->length());
switch (cached_format_type) {
case DATE_ONLY:
cached_timestamp_type= TIMESTAMP_DATE;
cached_field_type= MYSQL_TYPE_DATE;
max_length= MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
break;
case TIME_ONLY:
case TIME_MICROSECOND:
cached_timestamp_type= TIMESTAMP_TIME;
cached_field_type= MYSQL_TYPE_TIME;
max_length= MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
break;
default:
cached_timestamp_type= TIMESTAMP_DATETIME;
cached_field_type= MYSQL_TYPE_DATETIME;
break;
}
}
}
bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date)
{
DATE_TIME_FORMAT date_time_format;
@ -2328,8 +2478,18 @@ bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date)
date_time_format.format.str= (char*) format->ptr();
date_time_format.format.length= format->length();
if (extract_date_time(&date_time_format, val->ptr(), val->length(),
ltime))
ltime, cached_timestamp_type))
goto null_date;
if (cached_timestamp_type == TIMESTAMP_TIME && ltime->day)
{
/*
Day part for time type can be nonzero value and so
we should add hours from day part to hour part to
keep valid time value.
*/
ltime->hour+= ltime->day*24;
ltime->day= 0;
}
return 0;
null_date:
@ -2344,29 +2504,22 @@ String *Item_func_str_to_date::val_str(String *str)
if (Item_func_str_to_date::get_date(&ltime, TIME_FUZZY_DATE))
return 0;
/*
The following DATE_TIME should be done dynamicly based on the
format string (wen it's a constant). For example, we should only return
microseconds if there was an %f in the format
*/
if (!make_datetime(ltime.second_part ? DATE_TIME_MICROSECOND : DATE_TIME,
if (!make_datetime((const_item ? cached_format_type :
(ltime.second_part ? DATE_TIME_MICROSECOND : DATE_TIME)),
&ltime, str))
return str;
return 0;
}
String *Item_func_last_day::val_str(String *str)
bool Item_func_last_day::get_date(TIME *ltime, uint fuzzy_date)
{
TIME ltime;
if (!get_arg0_date(&ltime,0))
{
uint month_idx= ltime.month-1;
ltime.day= days_in_month[month_idx];
if ( month_idx == 1 && calc_days_in_year(ltime.year) == 366)
ltime.day+= 1;
if (!make_datetime(DATE_ONLY, &ltime, str))
return str;
}
if (get_arg0_date(ltime,fuzzy_date))
return 1;
uint month_idx= ltime->month-1;
ltime->day= days_in_month[month_idx];
if ( month_idx == 1 && calc_days_in_year(ltime->year) == 366)
ltime->day= 29;
ltime->time_type= TIMESTAMP_DATE;
return 0;
}

View file

@ -21,6 +21,11 @@
#pragma interface /* gcc class implementation */
#endif
enum date_time_format_types
{
TIME_ONLY= 0, TIME_MICROSECOND, DATE_ONLY, DATE_TIME, DATE_TIME_MICROSECOND
};
class Item_func_period_add :public Item_int_func
{
public:
@ -318,6 +323,7 @@ public:
enum Item_result result_type () const { return STRING_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
String *val_str(String *str);
longlong val_int();
double val() { return (double) val_int(); }
const char *func_name() const { return "date"; }
void fix_length_and_dec()
@ -407,6 +413,7 @@ public:
Item_func_curdate() :Item_date() {}
void set_result_from_tm(struct tm *now);
longlong val_int() { return (value) ; }
String *val_str(String *str);
void fix_length_and_dec();
bool get_date(TIME *res, uint fuzzy_date);
virtual void store_now_in_tm(time_t now, struct tm *now_tm)=0;
@ -477,8 +484,8 @@ class Item_func_from_days :public Item_date
{
public:
Item_func_from_days(Item *a) :Item_date(a) {}
longlong val_int();
const char *func_name() const { return "from_days"; }
bool get_date(TIME *res, uint fuzzy_date);
};
@ -610,6 +617,19 @@ public:
};
class Item_typecast_maybe_null :public Item_typecast
{
public:
Item_typecast_maybe_null(Item *a) :Item_typecast(a) {}
void fix_length_and_dec()
{
collation.set(&my_charset_bin);
max_length=args[0]->max_length;
maybe_null= 1;
}
};
class Item_char_typecast :public Item_typecast
{
int cast_length;
@ -626,10 +646,10 @@ public:
};
class Item_date_typecast :public Item_typecast
class Item_date_typecast :public Item_typecast_maybe_null
{
public:
Item_date_typecast(Item *a) :Item_typecast(a) {}
Item_date_typecast(Item *a) :Item_typecast_maybe_null(a) {}
String *val_str(String *str);
bool get_date(TIME *ltime, uint fuzzy_date);
const char *cast_type() const { return "date"; }
@ -641,10 +661,10 @@ public:
};
class Item_time_typecast :public Item_typecast
class Item_time_typecast :public Item_typecast_maybe_null
{
public:
Item_time_typecast(Item *a) :Item_typecast(a) {}
Item_time_typecast(Item *a) :Item_typecast_maybe_null(a) {}
String *val_str(String *str);
bool get_time(TIME *ltime);
const char *cast_type() const { return "time"; }
@ -656,10 +676,10 @@ public:
};
class Item_datetime_typecast :public Item_typecast
class Item_datetime_typecast :public Item_typecast_maybe_null
{
public:
Item_datetime_typecast(Item *a) :Item_typecast(a) {}
Item_datetime_typecast(Item *a) :Item_typecast_maybe_null(a) {}
String *val_str(String *str);
const char *cast_type() const { return "datetime"; }
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
@ -793,37 +813,29 @@ public:
};
class Item_func_str_to_date :public Item_date_func
class Item_func_str_to_date :public Item_str_func
{
enum_field_types cached_field_type;
date_time_format_types cached_format_type;
timestamp_type cached_timestamp_type;
bool const_item;
public:
Item_func_str_to_date(Item *a, Item *b)
:Item_date_func(a, b)
:Item_str_func(a, b)
{}
String *val_str(String *str);
bool get_date(TIME *ltime, uint fuzzy_date);
const char *func_name() const { return "str_to_date"; }
void fix_length_and_dec()
{
maybe_null= 1;
decimals=0;
max_length=MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
}
enum_field_types field_type() const { return cached_field_type; }
void fix_length_and_dec();
Field *tmp_table_field(TABLE *t_arg);
};
class Item_func_last_day :public Item_str_func
class Item_func_last_day :public Item_date
{
public:
Item_func_last_day(Item *a) :Item_str_func(a) {}
String *val_str(String *str);
Item_func_last_day(Item *a) :Item_date(a) {}
const char *func_name() const { return "last_day"; }
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
void fix_length_and_dec()
{
decimals=0;
max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
}
Field *tmp_table_field(TABLE *t_arg)
{
return (new Field_date(maybe_null, name, t_arg, &my_charset_bin));
}
bool get_date(TIME *res, uint fuzzy_date);
};

View file

@ -799,6 +799,7 @@ extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN];
extern char pidfile_name[FN_REFLEN], time_zone[30], *opt_init_file;
extern char log_error_file[FN_REFLEN];
extern double log_10[32];
extern ulonglong log_10_int[20];
extern ulonglong keybuff_size;
extern ulong refresh_version,flush_version, thread_id,query_id,opened_tables;
extern ulong created_tmp_tables, created_tmp_disk_tables, bytes_sent;
@ -958,6 +959,8 @@ timestamp_type str_to_TIME(const char *str, uint length, TIME *l_time,
void localtime_to_TIME(TIME *to, struct tm *from);
void calc_time_from_sec(TIME *to, long seconds, long microseconds);
void make_truncated_value_warning(THD *thd, const char *str_val,
uint str_length, timestamp_type time_type);
extern DATE_TIME_FORMAT *date_time_format_make(timestamp_type format_type,
const char *format_str,
uint format_length);

View file

@ -305,6 +305,14 @@ ulong my_bind_addr; /* the address we bind to */
volatile ulong cached_thread_count= 0;
double log_10[32]; /* 10 potences */
ulonglong log_10_int[20]=
{
1, 10, 100, 1000, 10000UL, 100000UL, 1000000UL, 10000000UL,
100000000UL, 1000000000UL, 10000000000UL, 100000000000UL,
1000000000000UL, 10000000000000UL, 100000000000000UL,
1000000000000000UL, 10000000000000000UL, 100000000000000000UL,
1000000000000000000UL, 10000000000000000000UL
};
time_t start_time;

View file

@ -303,3 +303,5 @@ character-set=latin2
"The target table %-.100s of the %s is not updatable",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -297,3 +297,5 @@ character-set=latin1
"The target table %-.100s of the %s is not updateable",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -305,3 +305,5 @@ character-set=latin1
"The target table %-.100s of the %s is not updateable",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -294,3 +294,5 @@ character-set=latin1
"The target table %-.100s of the %s is not updatable",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -299,3 +299,5 @@ character-set=latin7
"The target table %-.100s of the %s is not updateable",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -294,3 +294,5 @@ character-set=latin1
"The target table %-.100s of the %s is not updateable",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -306,3 +306,5 @@ character-set=latin1
"The target table %-.100s of the %s is not updateable",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -294,3 +294,5 @@ character-set=greek
"The target table %-.100s of the %s is not updateable",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -296,3 +296,5 @@ character-set=latin2
"The target table %-.100s of the %s is not updateable",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -294,3 +294,5 @@ character-set=latin1
"The target table %-.100s of the %s is not updateable",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -296,3 +296,5 @@ character-set=ujis
"The target table %-.100s of the %s is not updateable",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -294,3 +294,5 @@ character-set=euckr
"The target table %-.100s of the %s is not updateable",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -296,3 +296,5 @@ character-set=latin1
"The target table %-.100s of the %s is not updateable",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -296,3 +296,5 @@ character-set=latin1
"The target table %-.100s of the %s is not updateable",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -298,3 +298,5 @@ character-set=latin2
"The target table %-.100s of the %s is not updateable",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -295,3 +295,5 @@ character-set=latin1
"The target table %-.100s of the %s is not updateable",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -298,3 +298,5 @@ character-set=latin2
"The target table %-.100s of the %s is not updateable",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -296,3 +296,5 @@ character-set=koi8r
"ôÁÂÌÉÃÁ %-.100s × %s ÎÅ ÍÏÖÅÔ ÉÚÍÅÎÑÔÓÑ",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -288,3 +288,5 @@ character-set=cp1250
"The target table %-.100s of the %s is not updatable",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working"
"The MySQL server is running with the %s option so it cannot execute this statement"
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -302,3 +302,5 @@ character-set=latin2
"The target table %-.100s of the %s is not updateable",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -296,3 +296,5 @@ character-set=latin1
"The target table %-.100s of the %s is not updateable",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -294,3 +294,5 @@ character-set=latin1
"'%s' är inte aktiverad; För att aktivera detta måste du bygga om MySQL med '%s' definerad",
"MySQL är started i --skip-grant-tables mod. Pga av detta kan du inte använda detta program",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -299,3 +299,5 @@ character-set=koi8u
"ôÁÂÌÉÃÑ %-.100s Õ %s ÎÅ ÍÏÖÅ ÏÎÏ×ÌÀ×ÁÔÉÓØ",
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
"The MySQL server is running with the %s option so it cannot execute this statement",
"Column '%-.100s' has duplicated value '%-.64s' in %s"
"Truncated wrong %-.32s value: '%-.128s'"

View file

@ -19,91 +19,105 @@
/***************************** Gis_class_info *******************************/
#define IMPLEMENT_GEOM(class_name, type_id, name) \
{ \
(GF_InitFromText) &class_name::init_from_wkt, \
(GF_GetDataAsText) &class_name::get_data_as_wkt, \
(GF_GetDataSize) &class_name::get_data_size, \
(GF_GetMBR) &class_name::get_mbr, \
(GF_GetD) &class_name::get_x, \
(GF_GetD) &class_name::get_y, \
(GF_GetD) &class_name::length, \
(GF_GetD_AND_END) &class_name::area, \
(GF_GetI) &class_name::is_closed, \
(GF_GetUI) &class_name::num_interior_ring, \
(GF_GetUI) &class_name::num_points, \
(GF_GetUI) &class_name::num_geometries, \
(GF_GetUI_AND_END) &class_name::dimension, \
(GF_GetWS) &class_name::start_point, \
(GF_GetWS) &class_name::end_point, \
(GF_GetWS) &class_name::exterior_ring, \
(GF_GetWS) &class_name::centroid, \
(GF_GetUIWS) &class_name::point_n, \
(GF_GetUIWS) &class_name::interior_ring_n, \
(GF_GetUIWS) &class_name::geometry_n, \
name, \
class_name::type_id, \
NULL \
}
static LEX_STRING_WITH_INIT point_name("POINT", 5);
static LEX_STRING_WITH_INIT linestring_name("LINESTRING", 10);
static LEX_STRING_WITH_INIT polygon_name("POLYGON",7);
static LEX_STRING_WITH_INIT multipoint_name("MULTIPOINT",10);
static LEX_STRING_WITH_INIT multilinestring_name("MULTILINESTRING",15);
static LEX_STRING_WITH_INIT multipolygon_name("MULTIPOLYGON",12);
static LEX_STRING_WITH_INIT geometrycollection_name("GEOMETRYCOLLECTION",18);
static Geometry::Gis_class_info ci_collection[]=
Geometry::Class_info *Geometry::ci_collection[Geometry::wkb_end]=
{
IMPLEMENT_GEOM(Gis_point, wkbPoint, point_name),
IMPLEMENT_GEOM(Gis_line_string, wkbLineString, linestring_name),
IMPLEMENT_GEOM(Gis_polygon, wkbPolygon, polygon_name),
IMPLEMENT_GEOM(Gis_multi_point, wkbMultiPoint, multipoint_name),
IMPLEMENT_GEOM(Gis_multi_line_stringg, wkbMultiLineString, multilinestring_name),
IMPLEMENT_GEOM(Gis_multi_polygon, wkbMultiPolygon, multipolygon_name),
IMPLEMENT_GEOM(Gis_geometry_collection, wkbGeometryCollection,
geometrycollection_name)
NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
static Geometry::Gis_class_info *ci_collection_end=
(ci_collection + array_elements(ci_collection));
static Geometry::Class_info **ci_collection_end=
Geometry::ci_collection+Geometry::wkb_end;
Geometry::Class_info::Class_info(const char *name, int type_id,
void(*create_func)(void *)):
m_name(name, strlen(name)), m_type_id(type_id), m_create_func(create_func)
{
ci_collection[type_id]= this;
}
static void create_point(void *buffer)
{
new(buffer) Gis_point;
}
static void create_linestring(void *buffer)
{
new(buffer) Gis_line_string;
}
static void create_polygon(void *buffer)
{
new(buffer) Gis_polygon;
}
static void create_multipoint(void *buffer)
{
new(buffer) Gis_multi_point;
}
static void create_multipolygon(void *buffer)
{
new(buffer) Gis_multi_polygon;
}
static void create_multilinestring(void *buffer)
{
new(buffer) Gis_multi_line_string;
}
static void create_geometrycollection(void *buffer)
{
new(buffer) Gis_geometry_collection;
}
static Geometry::Class_info point_class("POINT",
Geometry::wkb_point, create_point);
static Geometry::Class_info linestring_class("LINESTRING",
Geometry::wkb_linestring,
create_linestring);
static Geometry::Class_info polygon_class("POLYGON",
Geometry::wkb_polygon,
create_polygon);
static Geometry::Class_info multipoint_class("MULTIPOINT",
Geometry::wkb_multipoint,
create_multipoint);
static Geometry::Class_info
multilinestring_class("MULTILINESTRING",
Geometry::wkb_multilinestring, create_multilinestring);
static Geometry::Class_info multipolygon_class("MULTIPOLYGON",
Geometry::wkb_multipolygon,
create_multipolygon);
static Geometry::Class_info
geometrycollection_class("GEOMETRYCOLLECTION",Geometry::wkb_geometrycollection,
create_geometrycollection);
/***************************** Geometry *******************************/
Geometry::Gis_class_info *Geometry::find_class(int type_id)
Geometry::Class_info *Geometry::find_class(const char *name, uint32 len)
{
for (Gis_class_info *cur_rt= ci_collection; cur_rt < ci_collection_end; cur_rt++)
for (Class_info **cur_rt= ci_collection;
cur_rt < ci_collection_end; cur_rt++)
{
if (cur_rt->m_type_id == type_id)
return cur_rt;
}
return 0;
}
Geometry::Gis_class_info *Geometry::find_class(const char *name, uint32 len)
{
for (Gis_class_info *cur_rt= ci_collection; cur_rt < ci_collection_end; cur_rt++)
{
if ((cur_rt->m_name.length == len) &&
if (*cur_rt &&
((*cur_rt)->m_name.length == len) &&
(my_strnncoll(&my_charset_latin1,
(const uchar*) cur_rt->m_name.str, len,
(const uchar*) (*cur_rt)->m_name.str, len,
(const uchar*) name, len) == 0))
return cur_rt;
return *cur_rt;
}
return 0;
}
int Geometry::create_from_wkb(const char *data, uint32 data_len)
Geometry *Geometry::create_from_wkb(Geometry_buffer *buffer,
const char *data, uint32 data_len)
{
uint32 geom_type;
Geometry *result;
if (data_len < 1 + 4)
return 1;
return NULL;
data++;
/*
FIXME: check byte ordering
@ -111,39 +125,44 @@ int Geometry::create_from_wkb(const char *data, uint32 data_len)
*/
geom_type= uint4korr(data);
data+= 4;
if (!(m_vmt= find_class((int) geom_type)))
return 1;
m_data= data;
m_data_end= data + data_len;
return 0;
if (!(result= create_by_typeid(buffer, (int) geom_type)))
return NULL;
result->m_data= data;
result->m_data_end= data + data_len;
return result;
}
int Geometry::create_from_wkt(Gis_read_stream *trs, String *wkt,
bool init_stream)
Geometry *Geometry::create_from_wkt(Geometry_buffer *buffer,
Gis_read_stream *trs, String *wkt,
bool init_stream)
{
LEX_STRING name;
Class_info *ci;
if (trs->get_next_word(&name))
{
trs->set_error_msg("Geometry name expected");
return 1;
return NULL;
}
if (!(m_vmt= find_class(name.str, name.length)) ||
if (!(ci= find_class(name.str, name.length)) ||
wkt->reserve(1 + 4, 512))
return 1;
wkt->q_append((char) wkbNDR);
wkt->q_append((uint32) get_class_info()->m_type_id);
return NULL;
(*ci->m_create_func)((void *)buffer);
Geometry *result= (Geometry *)buffer;
wkt->q_append((char) wkb_ndr);
wkt->q_append((uint32) result->get_class_info()->m_type_id);
if (trs->check_next_symbol('(') ||
init_from_wkt(trs, wkt) ||
result->init_from_wkt(trs, wkt) ||
trs->check_next_symbol(')'))
return 1;
return NULL;
if (init_stream)
{
init_from_wkb(wkt->ptr(), wkt->length());
shift_wkb_header();
result->init_from_wkb(wkt->ptr(), wkt->length());
result->shift_wkb_header();
}
return 0;
return result;
}
@ -155,8 +174,8 @@ bool Geometry::envelope(String *result) const
if (get_mbr(&mbr, &end) || result->reserve(1+4*3+SIZEOF_STORED_DOUBLE*10))
return 1;
result->q_append((char) wkbNDR);
result->q_append((uint32) wkbPolygon);
result->q_append((char) wkb_ndr);
result->q_append((uint32) wkb_polygon);
result->q_append((uint32) 1);
result->q_append((uint32) 5);
result->q_append(mbr.xmin);
@ -187,13 +206,13 @@ bool Geometry::envelope(String *result) const
1 Can't reallocate 'result'
*/
bool Geometry::create_point(String *result, const char *data)
bool Geometry::create_point(String *result, const char *data) const
{
if (no_data(data, SIZEOF_STORED_DOUBLE * 2) ||
result->reserve(1 + 4 + SIZEOF_STORED_DOUBLE * 2))
return 1;
result->q_append((char) wkbNDR);
result->q_append((uint32) wkbPoint);
result->q_append((char) wkb_ndr);
result->q_append((uint32) wkb_point);
/* Copy two double in same format */
result->q_append(data, SIZEOF_STORED_DOUBLE*2);
return 0;
@ -213,13 +232,13 @@ bool Geometry::create_point(String *result, const char *data)
1 Can't reallocate 'result'
*/
bool Geometry::create_point(String *result, double x, double y)
bool Geometry::create_point(String *result, double x, double y) const
{
if (result->reserve(1 + 4 + SIZEOF_STORED_DOUBLE * 2))
return 1;
result->q_append((char) wkbNDR);
result->q_append((uint32) wkbPoint);
result->q_append((char) wkb_ndr);
result->q_append((uint32) wkb_point);
result->q_append(x);
result->q_append(y);
return 0;
@ -240,7 +259,7 @@ bool Geometry::create_point(String *result, double x, double y)
*/
const char *Geometry::append_points(String *txt, uint32 n_points,
const char *data, uint32 offset)
const char *data, uint32 offset) const
{
while (n_points--)
{
@ -317,7 +336,7 @@ bool Gis_point::init_from_wkt(Gis_read_stream *trs, String *wkb)
}
bool Gis_point::get_data_as_wkt(String *txt, const char **end)
bool Gis_point::get_data_as_wkt(String *txt, const char **end) const
{
double x, y;
if (get_xy(&x, &y))
@ -332,7 +351,7 @@ bool Gis_point::get_data_as_wkt(String *txt, const char **end)
}
int Gis_point::get_mbr(MBR *mbr, const char **end) const
bool Gis_point::get_mbr(MBR *mbr, const char **end) const
{
double x, y;
if (get_xy(&x, &y))
@ -342,6 +361,11 @@ int Gis_point::get_mbr(MBR *mbr, const char **end) const
return 0;
}
const Geometry::Class_info *Gis_point::get_class_info() const
{
return &point_class;
}
/***************************** LineString *******************************/
@ -381,7 +405,7 @@ bool Gis_line_string::init_from_wkt(Gis_read_stream *trs, String *wkb)
}
bool Gis_line_string::get_data_as_wkt(String *txt, const char **end)
bool Gis_line_string::get_data_as_wkt(String *txt, const char **end) const
{
uint32 n_points;
const char *data= m_data;
@ -419,7 +443,7 @@ bool Gis_line_string::get_mbr(MBR *mbr, const char **end) const
}
bool Gis_line_string::length(double *len) const
int Gis_line_string::length(double *len) const
{
uint32 n_points;
double prev_x, prev_y;
@ -451,7 +475,7 @@ bool Gis_line_string::length(double *len) const
}
bool Gis_line_string::is_closed(int *closed) const
int Gis_line_string::is_closed(int *closed) const
{
uint32 n_points;
double x1, y1, x2, y2;
@ -478,21 +502,21 @@ bool Gis_line_string::is_closed(int *closed) const
}
bool Gis_line_string::num_points(uint32 *n_points) const
int Gis_line_string::num_points(uint32 *n_points) const
{
*n_points= uint4korr(m_data);
return 0;
}
bool Gis_line_string::start_point(String *result)
int Gis_line_string::start_point(String *result) const
{
/* +4 is for skipping over number of points */
return create_point(result, m_data + 4);
}
bool Gis_line_string::end_point(String *result)
int Gis_line_string::end_point(String *result) const
{
uint32 n_points;
if (no_data(m_data, 4))
@ -502,7 +526,7 @@ bool Gis_line_string::end_point(String *result)
}
bool Gis_line_string::point_n(uint32 num, String *result)
int Gis_line_string::point_n(uint32 num, String *result) const
{
uint32 n_points;
if (no_data(m_data, 4))
@ -514,6 +538,11 @@ bool Gis_line_string::point_n(uint32 num, String *result)
return create_point(result, m_data + 4 + (num - 1) * POINT_DATA_SIZE);
}
const Geometry::Class_info *Gis_line_string::get_class_info() const
{
return &linestring_class;
}
/***************************** Polygon *******************************/
@ -570,7 +599,7 @@ bool Gis_polygon::init_from_wkt(Gis_read_stream *trs, String *wkb)
}
bool Gis_polygon::get_data_as_wkt(String *txt, const char **end)
bool Gis_polygon::get_data_as_wkt(String *txt, const char **end) const
{
uint32 n_linear_rings;
const char *data= m_data;
@ -622,7 +651,7 @@ bool Gis_polygon::get_mbr(MBR *mbr, const char **end) const
}
bool Gis_polygon::area(double *ar, const char **end_of_data) const
int Gis_polygon::area(double *ar, const char **end_of_data) const
{
uint32 n_linear_rings;
double result= -1.0;
@ -671,7 +700,7 @@ bool Gis_polygon::area(double *ar, const char **end_of_data) const
}
bool Gis_polygon::exterior_ring(String *result)
int Gis_polygon::exterior_ring(String *result) const
{
uint32 n_points, length;
const char *data= m_data + 4; // skip n_linerings
@ -684,15 +713,15 @@ bool Gis_polygon::exterior_ring(String *result)
if (no_data(data, length) || result->reserve(1+4+4+ length))
return 1;
result->q_append((char) wkbNDR);
result->q_append((uint32) wkbLineString);
result->q_append((char) wkb_ndr);
result->q_append((uint32) wkb_linestring);
result->q_append(n_points);
result->q_append(data, n_points * POINT_DATA_SIZE);
return 0;
}
bool Gis_polygon::num_interior_ring(uint32 *n_int_rings) const
int Gis_polygon::num_interior_ring(uint32 *n_int_rings) const
{
if (no_data(m_data, 4))
return 1;
@ -701,7 +730,7 @@ bool Gis_polygon::num_interior_ring(uint32 *n_int_rings) const
}
bool Gis_polygon::interior_ring_n(uint32 num, String *result) const
int Gis_polygon::interior_ring_n(uint32 num, String *result) const
{
const char *data= m_data;
uint32 n_linear_rings;
@ -730,8 +759,8 @@ bool Gis_polygon::interior_ring_n(uint32 num, String *result) const
if (no_data(data, points_size) || result->reserve(1+4+4+ points_size))
return 1;
result->q_append((char) wkbNDR);
result->q_append((uint32) wkbLineString);
result->q_append((char) wkb_ndr);
result->q_append((uint32) wkb_linestring);
result->q_append(n_points);
result->q_append(data, points_size);
@ -739,7 +768,7 @@ bool Gis_polygon::interior_ring_n(uint32 num, String *result) const
}
bool Gis_polygon::centroid_xy(double *x, double *y) const
int Gis_polygon::centroid_xy(double *x, double *y) const
{
uint32 n_linear_rings;
double res_area, res_cx, res_cy;
@ -812,7 +841,7 @@ bool Gis_polygon::centroid_xy(double *x, double *y) const
}
bool Gis_polygon::centroid(String *result)
int Gis_polygon::centroid(String *result) const
{
double x, y;
if (centroid_xy(&x, &y))
@ -820,6 +849,11 @@ bool Gis_polygon::centroid(String *result)
return create_point(result, x, y);
}
const Geometry::Class_info *Gis_polygon::get_class_info() const
{
return &polygon_class;
}
/***************************** MultiPoint *******************************/
@ -845,8 +879,8 @@ bool Gis_multi_point::init_from_wkt(Gis_read_stream *trs, String *wkb)
{
if (wkb->reserve(1+4, 512))
return 1;
wkb->q_append((char) wkbNDR);
wkb->q_append((uint32) wkbPoint);
wkb->q_append((char) wkb_ndr);
wkb->q_append((uint32) wkb_point);
if (p.init_from_wkt(trs, wkb))
return 1;
n_points++;
@ -858,7 +892,7 @@ bool Gis_multi_point::init_from_wkt(Gis_read_stream *trs, String *wkb)
}
bool Gis_multi_point::get_data_as_wkt(String *txt, const char **end)
bool Gis_multi_point::get_data_as_wkt(String *txt, const char **end) const
{
uint32 n_points;
if (no_data(m_data, 4))
@ -881,14 +915,14 @@ bool Gis_multi_point::get_mbr(MBR *mbr, const char **end) const
}
bool Gis_multi_point::num_geometries(uint32 *num) const
int Gis_multi_point::num_geometries(uint32 *num) const
{
*num= uint4korr(m_data);
return 0;
}
bool Gis_multi_point::geometry_n(uint32 num, String *result) const
int Gis_multi_point::geometry_n(uint32 num, String *result) const
{
const char *data= m_data;
uint32 n_points;
@ -907,10 +941,15 @@ bool Gis_multi_point::geometry_n(uint32 num, String *result) const
return 0;
}
const Geometry::Class_info *Gis_multi_point::get_class_info() const
{
return &multipoint_class;
}
/***************************** MultiLineString *******************************/
uint32 Gis_multi_line_stringg::get_data_size() const
uint32 Gis_multi_line_string::get_data_size() const
{
uint32 n_line_strings;
const char *data= m_data;
@ -931,7 +970,7 @@ uint32 Gis_multi_line_stringg::get_data_size() const
}
bool Gis_multi_line_stringg::init_from_wkt(Gis_read_stream *trs, String *wkb)
bool Gis_multi_line_string::init_from_wkt(Gis_read_stream *trs, String *wkb)
{
uint32 n_line_strings= 0;
uint32 ls_pos= wkb->length();
@ -946,8 +985,8 @@ bool Gis_multi_line_stringg::init_from_wkt(Gis_read_stream *trs, String *wkb)
if (wkb->reserve(1+4, 512))
return 1;
wkb->q_append((char) wkbNDR);
wkb->q_append((uint32) wkbLineString);
wkb->q_append((char) wkb_ndr);
wkb->q_append((uint32) wkb_linestring);
if (trs->check_next_symbol('(') ||
ls.init_from_wkt(trs, wkb) ||
@ -962,7 +1001,8 @@ bool Gis_multi_line_stringg::init_from_wkt(Gis_read_stream *trs, String *wkb)
}
bool Gis_multi_line_stringg::get_data_as_wkt(String *txt, const char **end)
bool Gis_multi_line_string::get_data_as_wkt(String *txt,
const char **end) const
{
uint32 n_line_strings;
const char *data= m_data;
@ -993,7 +1033,7 @@ bool Gis_multi_line_stringg::get_data_as_wkt(String *txt, const char **end)
}
bool Gis_multi_line_stringg::get_mbr(MBR *mbr, const char **end) const
bool Gis_multi_line_string::get_mbr(MBR *mbr, const char **end) const
{
uint32 n_line_strings;
const char *data= m_data;
@ -1014,14 +1054,14 @@ bool Gis_multi_line_stringg::get_mbr(MBR *mbr, const char **end) const
}
bool Gis_multi_line_stringg::num_geometries(uint32 *num) const
int Gis_multi_line_string::num_geometries(uint32 *num) const
{
*num= uint4korr(m_data);
return 0;
}
bool Gis_multi_line_stringg::geometry_n(uint32 num, String *result) const
int Gis_multi_line_string::geometry_n(uint32 num, String *result) const
{
uint32 n_line_strings, n_points, length;
const char *data= m_data;
@ -1050,7 +1090,7 @@ bool Gis_multi_line_stringg::geometry_n(uint32 num, String *result) const
}
bool Gis_multi_line_stringg::length(double *len) const
int Gis_multi_line_string::length(double *len) const
{
uint32 n_line_strings;
const char *data= m_data;
@ -1080,7 +1120,7 @@ bool Gis_multi_line_stringg::length(double *len) const
}
bool Gis_multi_line_stringg::is_closed(int *closed) const
int Gis_multi_line_string::is_closed(int *closed) const
{
uint32 n_line_strings;
const char *data= m_data;
@ -1109,6 +1149,11 @@ bool Gis_multi_line_stringg::is_closed(int *closed) const
return 0;
}
const Geometry::Class_info *Gis_multi_line_string::get_class_info() const
{
return &multilinestring_class;
}
/***************************** MultiPolygon *******************************/
@ -1156,8 +1201,8 @@ bool Gis_multi_polygon::init_from_wkt(Gis_read_stream *trs, String *wkb)
{
if (wkb->reserve(1+4, 512))
return 1;
wkb->q_append((char) wkbNDR);
wkb->q_append((uint32) wkbPolygon);
wkb->q_append((char) wkb_ndr);
wkb->q_append((uint32) wkb_polygon);
if (trs->check_next_symbol('(') ||
p.init_from_wkt(trs, wkb) ||
@ -1172,7 +1217,7 @@ bool Gis_multi_polygon::init_from_wkt(Gis_read_stream *trs, String *wkb)
}
bool Gis_multi_polygon::get_data_as_wkt(String *txt, const char **end)
bool Gis_multi_polygon::get_data_as_wkt(String *txt, const char **end) const
{
uint32 n_polygons;
const char *data= m_data;
@ -1245,14 +1290,14 @@ bool Gis_multi_polygon::get_mbr(MBR *mbr, const char **end) const
}
bool Gis_multi_polygon::num_geometries(uint32 *num) const
int Gis_multi_polygon::num_geometries(uint32 *num) const
{
*num= uint4korr(m_data);
return 0;
}
bool Gis_multi_polygon::geometry_n(uint32 num, String *result) const
int Gis_multi_polygon::geometry_n(uint32 num, String *result) const
{
uint32 n_polygons;
const char *data= m_data, *start_of_polygon;
@ -1291,7 +1336,7 @@ bool Gis_multi_polygon::geometry_n(uint32 num, String *result) const
}
bool Gis_multi_polygon::area(double *ar, const char **end_of_data) const
int Gis_multi_polygon::area(double *ar, const char **end_of_data) const
{
uint32 n_polygons;
const char *data= m_data;
@ -1319,7 +1364,7 @@ bool Gis_multi_polygon::area(double *ar, const char **end_of_data) const
}
bool Gis_multi_polygon::centroid(String *result)
int Gis_multi_polygon::centroid(String *result) const
{
uint32 n_polygons;
bool first_loop= 1;
@ -1363,6 +1408,11 @@ bool Gis_multi_polygon::centroid(String *result)
return create_point(result, res_cx, res_cy);
}
const Geometry::Class_info *Gis_multi_polygon::get_class_info() const
{
return &multipolygon_class;
}
/************************* GeometryCollection ****************************/
@ -1370,6 +1420,8 @@ uint32 Gis_geometry_collection::get_data_size() const
{
uint32 n_objects;
const char *data= m_data;
Geometry_buffer buffer;
Geometry *geom;
if (no_data(data, 4))
return GET_SIZE_ERROR;
@ -1379,17 +1431,16 @@ uint32 Gis_geometry_collection::get_data_size() const
while (n_objects--)
{
uint32 wkb_type,object_size;
Geometry geom;
if (no_data(data, WKB_HEADER_SIZE))
return GET_SIZE_ERROR;
wkb_type= uint4korr(data + 1);
data+= WKB_HEADER_SIZE;
if (geom.init(wkb_type))
if (!(geom= create_by_typeid(&buffer, wkb_type)))
return GET_SIZE_ERROR;
geom.init_from_wkb(data, (uint) (m_data_end - data));
if ((object_size= geom.get_data_size()) == GET_SIZE_ERROR)
geom->init_from_wkb(data, (uint) (m_data_end - data));
if ((object_size= geom->get_data_size()) == GET_SIZE_ERROR)
return GET_SIZE_ERROR;
data+= object_size;
}
@ -1401,7 +1452,8 @@ bool Gis_geometry_collection::init_from_wkt(Gis_read_stream *trs, String *wkb)
{
uint32 n_objects= 0;
uint32 no_pos= wkb->length();
Geometry g;
Geometry_buffer buffer;
Geometry *g;
if (wkb->reserve(4, 512))
return 1;
@ -1409,10 +1461,10 @@ bool Gis_geometry_collection::init_from_wkt(Gis_read_stream *trs, String *wkb)
for (;;)
{
if (g.create_from_wkt(trs, wkb))
if (!(g= create_from_wkt(&buffer, trs, wkb)))
return 1;
if (g.get_class_info()->m_type_id == wkbGeometryCollection)
if (g->get_class_info()->m_type_id == wkb_geometrycollection)
{
trs->set_error_msg("Unexpected GEOMETRYCOLLECTION");
return 1;
@ -1427,10 +1479,12 @@ bool Gis_geometry_collection::init_from_wkt(Gis_read_stream *trs, String *wkb)
}
bool Gis_geometry_collection::get_data_as_wkt(String *txt, const char **end)
bool Gis_geometry_collection::get_data_as_wkt(String *txt,
const char **end) const
{
uint32 n_objects;
Geometry geom;
Geometry_buffer buffer;
Geometry *geom;
const char *data= m_data;
if (no_data(data, 4))
@ -1447,10 +1501,10 @@ bool Gis_geometry_collection::get_data_as_wkt(String *txt, const char **end)
wkb_type= uint4korr(data + 1);
data+= WKB_HEADER_SIZE;
if (geom.init(wkb_type))
if (!(geom= create_by_typeid(&buffer, wkb_type)))
return 1;
geom.init_from_wkb(data, (uint) (m_data_end - data));
if (geom.as_wkt(txt, &data))
geom->init_from_wkb(data, (uint) (m_data_end - data));
if (geom->as_wkt(txt, &data))
return 1;
if (txt->append(",", 1, 512))
return 1;
@ -1465,6 +1519,8 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const
{
uint32 n_objects;
const char *data= m_data;
Geometry_buffer buffer;
Geometry *geom;
if (no_data(data, 4))
return 1;
@ -1474,17 +1530,16 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const
while (n_objects--)
{
uint32 wkb_type;
Geometry geom;
if (no_data(data, WKB_HEADER_SIZE))
return 1;
wkb_type= uint4korr(data + 1);
data+= WKB_HEADER_SIZE;
if (geom.init(wkb_type))
if (!(geom= create_by_typeid(&buffer, wkb_type)))
return 1;
geom.init_from_wkb(data, (uint32) (m_data_end - data));
if (geom.get_mbr(mbr, &data))
geom->init_from_wkb(data, (uint32) (m_data_end - data));
if (geom->get_mbr(mbr, &data))
return 1;
}
*end= data;
@ -1492,7 +1547,7 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const
}
bool Gis_geometry_collection::num_geometries(uint32 *num) const
int Gis_geometry_collection::num_geometries(uint32 *num) const
{
if (no_data(m_data, 4))
return 1;
@ -1501,10 +1556,12 @@ bool Gis_geometry_collection::num_geometries(uint32 *num) const
}
bool Gis_geometry_collection::geometry_n(uint32 num, String *result) const
int Gis_geometry_collection::geometry_n(uint32 num, String *result) const
{
uint32 n_objects, wkb_type, length;
const char *data= m_data;
Geometry_buffer buffer;
Geometry *geom;
if (no_data(data, 4))
return 1;
@ -1515,17 +1572,15 @@ bool Gis_geometry_collection::geometry_n(uint32 num, String *result) const
do
{
Geometry geom;
if (no_data(data, WKB_HEADER_SIZE))
return 1;
wkb_type= uint4korr(data + 1);
data+= WKB_HEADER_SIZE;
if (geom.init(wkb_type))
if (!(geom= create_by_typeid(&buffer, wkb_type)))
return 1;
geom.init_from_wkb(data, (uint) (m_data_end - data));
if ((length= geom.get_data_size()) == GET_SIZE_ERROR)
geom->init_from_wkb(data, (uint) (m_data_end - data));
if ((length= geom->get_data_size()) == GET_SIZE_ERROR)
return 1;
data+= length;
} while (--num);
@ -1533,7 +1588,7 @@ bool Gis_geometry_collection::geometry_n(uint32 num, String *result) const
/* Copy found object to result */
if (result->reserve(1+4+length))
return 1;
result->q_append((char) wkbNDR);
result->q_append((char) wkb_ndr);
result->q_append((uint32) wkb_type);
result->q_append(data-length, length); // data-length = start_of_data
return 0;
@ -1557,6 +1612,8 @@ bool Gis_geometry_collection::dimension(uint32 *res_dim, const char **end) const
{
uint32 n_objects;
const char *data= m_data;
Geometry_buffer buffer;
Geometry *geom;
if (no_data(data, 4))
return 1;
@ -1568,21 +1625,20 @@ bool Gis_geometry_collection::dimension(uint32 *res_dim, const char **end) const
{
uint32 wkb_type, length, dim;
const char *end_data;
Geometry geom;
if (no_data(data, WKB_HEADER_SIZE))
return 1;
wkb_type= uint4korr(data + 1);
data+= WKB_HEADER_SIZE;
if (geom.init(wkb_type))
if (!(geom= create_by_typeid(&buffer, wkb_type)))
return 1;
geom.init_from_wkb(data, (uint32) (m_data_end - data));
if (geom.dimension(&dim, &end_data))
geom->init_from_wkb(data, (uint32) (m_data_end - data));
if (geom->dimension(&dim, &end_data))
return 1;
set_if_bigger(*res_dim, dim);
if (end_data) // Complex object
data= end_data;
else if ((length= geom.get_data_size()) == GET_SIZE_ERROR)
else if ((length= geom->get_data_size()) == GET_SIZE_ERROR)
return 1;
else
data+= length;
@ -1590,3 +1646,9 @@ bool Gis_geometry_collection::dimension(uint32 *res_dim, const char **end) const
*end= data;
return 0;
}
const Geometry::Class_info *Gis_geometry_collection::get_class_info() const
{
return &geometrycollection_class;
}

View file

@ -152,142 +152,80 @@ struct MBR
/***************************** Geometry *******************************/
class Geometry;
typedef bool (Geometry::*GF_InitFromText)(Gis_read_stream *, String *);
typedef bool (Geometry::*GF_GetDataAsText)(String *, const char **);
typedef uint32 (Geometry::*GF_GetDataSize)() const;
typedef bool (Geometry::*GF_GetMBR)(MBR *, const char **end) const;
typedef bool (Geometry::*GF_GetD)(double *) const;
typedef bool (Geometry::*GF_GetD_AND_END)(double *, const char **) const;
typedef bool (Geometry::*GF_GetI)(int *) const;
typedef bool (Geometry::*GF_GetUI)(uint32 *) const;
typedef bool (Geometry::*GF_GetUI_AND_END)(uint32 *, const char **) const;
typedef bool (Geometry::*GF_GetWS)(String *);
typedef bool (Geometry::*GF_GetUIWS)(uint32, String *) const;
#define GEOM_METHOD_PRESENT(geom_obj, method)\
(geom_obj.m_vmt->method != &Geometry::method)
struct Geometry_buffer;
class Geometry
{
public:
static void *operator new(size_t size, void *buffer)
{
return buffer;
}
enum wkbType
{
wkbPoint= 1,
wkbLineString= 2,
wkbPolygon= 3,
wkbMultiPoint= 4,
wkbMultiLineString= 5,
wkbMultiPolygon= 6,
wkbGeometryCollection= 7,
wkb_end=8
wkb_point= 1,
wkb_linestring= 2,
wkb_polygon= 3,
wkb_multipoint= 4,
wkb_multilinestring= 5,
wkb_multipolygon= 6,
wkb_geometrycollection= 7,
wkb_end=7
};
enum wkbByteOrder
{
wkbXDR= 0, /* Big Endian */
wkbNDR= 1 /* Little Endian */
wkb_xdr= 0, /* Big Endian */
wkb_ndr= 1 /* Little Endian */
};
class Gis_class_info
class Class_info
{
public:
GF_InitFromText init_from_wkt;
GF_GetDataAsText get_data_as_wkt;
GF_GetDataSize get_data_size;
GF_GetMBR get_mbr;
GF_GetD get_x;
GF_GetD get_y;
GF_GetD length;
GF_GetD_AND_END area;
GF_GetI is_closed;
GF_GetUI num_interior_ring;
GF_GetUI num_points;
GF_GetUI num_geometries;
GF_GetUI_AND_END dimension;
GF_GetWS start_point;
GF_GetWS end_point;
GF_GetWS exterior_ring;
GF_GetWS centroid;
GF_GetUIWS point_n;
GF_GetUIWS interior_ring_n;
GF_GetUIWS geometry_n;
LEX_STRING m_name;
LEX_STRING_WITH_INIT m_name;
int m_type_id;
Gis_class_info *m_next_rt;
void (*m_create_func)(void *);
Class_info(const char *name, int type_id, void(*create_func)(void *));
};
Gis_class_info *m_vmt;
const Gis_class_info *get_class_info() const { return m_vmt; }
uint32 get_data_size() const { return (this->*m_vmt->get_data_size)(); }
bool init_from_wkt(Gis_read_stream *trs, String *wkb)
{ return (this->*m_vmt->init_from_wkt)(trs, wkb); }
bool get_data_as_wkt(String *txt, const char **end)
{ return (this->*m_vmt->get_data_as_wkt)(txt, end); }
int get_mbr(MBR *mbr, const char **end) const
{ return (this->*m_vmt->get_mbr)(mbr, end); }
bool dimension(uint32 *dim, const char **end) const
{
return (this->*m_vmt->dimension)(dim, end);
}
bool get_x(double *x) const { return (this->*m_vmt->get_x)(x); }
bool get_y(double *y) const { return (this->*m_vmt->get_y)(y); }
bool length(double *len) const { return (this->*m_vmt->length)(len); }
bool area(double *ar, const char **end) const
{
return (this->*m_vmt->area)(ar, end);
}
bool is_closed(int *closed) const
{ return (this->*m_vmt->is_closed)(closed); }
bool num_interior_ring(uint32 *n_int_rings) const
{ return (this->*m_vmt->num_interior_ring)(n_int_rings); }
bool num_points(uint32 *n_points) const
{ return (this->*m_vmt->num_points)(n_points); }
bool num_geometries(uint32 *num) const
{ return (this->*m_vmt->num_geometries)(num); }
bool start_point(String *point)
{ return (this->*m_vmt->start_point)(point); }
bool end_point(String *point)
{ return (this->*m_vmt->end_point)(point); }
bool exterior_ring(String *ring)
{ return (this->*m_vmt->exterior_ring)(ring); }
bool centroid(String *point)
{ return (this->*m_vmt->centroid)(point); }
bool point_n(uint32 num, String *result) const
{ return (this->*m_vmt->point_n)(num, result); }
bool interior_ring_n(uint32 num, String *result) const
{ return (this->*m_vmt->interior_ring_n)(num, result); }
bool geometry_n(uint32 num, String *result) const
{ return (this->*m_vmt->geometry_n)(num, result); }
virtual const Class_info *get_class_info() const=0;
virtual uint32 get_data_size() const=0;
virtual bool init_from_wkt(Gis_read_stream *trs, String *wkb)=0;
virtual bool get_data_as_wkt(String *txt, const char **end) const=0;
virtual bool get_mbr(MBR *mbr, const char **end) const=0;
virtual bool dimension(uint32 *dim, const char **end) const=0;
virtual int get_x(double *x) const { return -1; }
virtual int get_y(double *y) const { return -1; }
virtual int length(double *len) const { return -1; }
virtual int area(double *ar, const char **end) const { return -1;}
virtual int is_closed(int *closed) const { return -1; }
virtual int num_interior_ring(uint32 *n_int_rings) const { return -1; }
virtual int num_points(uint32 *n_points) const { return -1; }
virtual int num_geometries(uint32 *num) const { return -1; }
virtual int start_point(String *point) const { return -1; }
virtual int end_point(String *point) const { return -1; }
virtual int exterior_ring(String *ring) const { return -1; }
virtual int centroid(String *point) const { return -1; }
virtual int point_n(uint32 num, String *result) const { return -1; }
virtual int interior_ring_n(uint32 num, String *result) const { return -1; }
virtual int geometry_n(uint32 num, String *result) const { return -1; }
public:
int create_from_wkb(const char *data, uint32 data_len);
int create_from_wkt(Gis_read_stream *trs, String *wkt, bool init_stream=1);
int init(int type_id)
static Geometry *Geometry::create_by_typeid(Geometry_buffer *buffer,
int type_id)
{
m_vmt= find_class(type_id);
return !m_vmt;
}
int new_geometry(const char *name, uint32 len)
{
m_vmt= find_class(name, len);
return !m_vmt;
Class_info *ci;
if (!(ci= find_class((int) type_id)))
return NULL;
(*ci->m_create_func)((void *)buffer);
return (Geometry *)buffer;
}
static Geometry *create_from_wkb(Geometry_buffer *buffer,
const char *data, uint32 data_len);
static Geometry *create_from_wkt(Geometry_buffer *buffer,
Gis_read_stream *trs, String *wkt,
bool init_stream=1);
int as_wkt(String *wkt, const char **end)
{
uint32 len= get_class_info()->m_name.length;
@ -313,14 +251,19 @@ public:
}
bool envelope(String *result) const;
static Geometry::Class_info *ci_collection[Geometry::wkb_end];
protected:
static Gis_class_info *find_class(int type_id);
static Gis_class_info *find_class(const char *name, uint32 len);
static Class_info *find_class(int type_id)
{
return ((type_id < wkb_point) || (type_id > wkb_end)) ?
NULL : ci_collection[type_id];
}
static Class_info *find_class(const char *name, uint32 len);
const char *append_points(String *txt, uint32 n_points,
const char *data, uint32 offset);
bool create_point(String *result, const char *data);
bool create_point(String *result, double x, double y);
const char *data, uint32 offset) const;
bool create_point(String *result, const char *data) const;
bool create_point(String *result, double x, double y) const;
const char *get_mbr_for_points(MBR *mbr, const char *data, uint offset)
const;
@ -340,10 +283,10 @@ class Gis_point: public Geometry
public:
uint32 get_data_size() const;
bool init_from_wkt(Gis_read_stream *trs, String *wkb);
bool get_data_as_wkt(String *txt, const char **end);
int get_mbr(MBR *mbr, const char **end) const;
bool get_data_as_wkt(String *txt, const char **end) const;
bool get_mbr(MBR *mbr, const char **end) const;
bool get_xy(double *x, double *y) const
int get_xy(double *x, double *y) const
{
const char *data= m_data;
if (no_data(data, SIZEOF_STORED_DOUBLE * 2))
@ -353,7 +296,7 @@ public:
return 0;
}
bool get_x(double *x) const
int get_x(double *x) const
{
if (no_data(m_data, SIZEOF_STORED_DOUBLE))
return 1;
@ -361,7 +304,7 @@ public:
return 0;
}
bool get_y(double *y) const
int get_y(double *y) const
{
const char *data= m_data;
if (no_data(data, SIZEOF_STORED_DOUBLE * 2)) return 1;
@ -375,6 +318,7 @@ public:
*end= 0; /* No default end */
return 0;
}
const Class_info *get_class_info() const;
};
@ -385,20 +329,21 @@ class Gis_line_string: public Geometry
public:
uint32 get_data_size() const;
bool init_from_wkt(Gis_read_stream *trs, String *wkb);
bool get_data_as_wkt(String *txt, const char **end);
bool get_data_as_wkt(String *txt, const char **end) const;
bool get_mbr(MBR *mbr, const char **end) const;
bool length(double *len) const;
bool is_closed(int *closed) const;
bool num_points(uint32 *n_points) const;
bool start_point(String *point);
bool end_point(String *point);
bool point_n(uint32 n, String *result);
int length(double *len) const;
int is_closed(int *closed) const;
int num_points(uint32 *n_points) const;
int start_point(String *point) const;
int end_point(String *point) const;
int point_n(uint32 n, String *result) const;
bool dimension(uint32 *dim, const char **end) const
{
*dim= 1;
*end= 0; /* No default end */
return 0;
}
const Class_info *get_class_info() const;
};
@ -409,20 +354,21 @@ class Gis_polygon: public Geometry
public:
uint32 get_data_size() const;
bool init_from_wkt(Gis_read_stream *trs, String *wkb);
bool get_data_as_wkt(String *txt, const char **end);
bool get_data_as_wkt(String *txt, const char **end) const;
bool get_mbr(MBR *mbr, const char **end) const;
bool area(double *ar, const char **end) const;
bool exterior_ring(String *result);
bool num_interior_ring(uint32 *n_int_rings) const;
bool interior_ring_n(uint32 num, String *result) const;
bool centroid_xy(double *x, double *y) const;
bool centroid(String *result);
int area(double *ar, const char **end) const;
int exterior_ring(String *result) const;
int num_interior_ring(uint32 *n_int_rings) const;
int interior_ring_n(uint32 num, String *result) const;
int centroid_xy(double *x, double *y) const;
int centroid(String *result) const;
bool dimension(uint32 *dim, const char **end) const
{
*dim= 2;
*end= 0; /* No default end */
return 0;
}
const Class_info *get_class_info() const;
};
@ -433,38 +379,40 @@ class Gis_multi_point: public Geometry
public:
uint32 get_data_size() const;
bool init_from_wkt(Gis_read_stream *trs, String *wkb);
bool get_data_as_wkt(String *txt, const char **end);
bool get_data_as_wkt(String *txt, const char **end) const;
bool get_mbr(MBR *mbr, const char **end) const;
bool num_geometries(uint32 *num) const;
bool geometry_n(uint32 num, String *result) const;
int num_geometries(uint32 *num) const;
int geometry_n(uint32 num, String *result) const;
bool dimension(uint32 *dim, const char **end) const
{
*dim= 0;
*end= 0; /* No default end */
return 0;
}
const Class_info *get_class_info() const;
};
/***************************** MultiLineString *******************************/
class Gis_multi_line_stringg: public Geometry
class Gis_multi_line_string: public Geometry
{
public:
uint32 get_data_size() const;
bool init_from_wkt(Gis_read_stream *trs, String *wkb);
bool get_data_as_wkt(String *txt, const char **end);
bool get_data_as_wkt(String *txt, const char **end) const;
bool get_mbr(MBR *mbr, const char **end) const;
bool num_geometries(uint32 *num) const;
bool geometry_n(uint32 num, String *result) const;
bool length(double *len) const;
bool is_closed(int *closed) const;
int num_geometries(uint32 *num) const;
int geometry_n(uint32 num, String *result) const;
int length(double *len) const;
int is_closed(int *closed) const;
bool dimension(uint32 *dim, const char **end) const
{
*dim= 1;
*end= 0; /* No default end */
return 0;
}
const Class_info *get_class_info() const;
};
@ -475,19 +423,19 @@ class Gis_multi_polygon: public Geometry
public:
uint32 get_data_size() const;
bool init_from_wkt(Gis_read_stream *trs, String *wkb);
bool get_data_as_wkt(String *txt, const char **end);
bool get_data_as_wkt(String *txt, const char **end) const;
bool get_mbr(MBR *mbr, const char **end) const;
bool num_geometries(uint32 *num) const;
bool geometry_n(uint32 num, String *result) const;
bool area(double *ar, const char **end) const;
bool centroid(String *result);
int num_geometries(uint32 *num) const;
int geometry_n(uint32 num, String *result) const;
int area(double *ar, const char **end) const;
int centroid(String *result) const;
bool dimension(uint32 *dim, const char **end) const
{
*dim= 2;
*end= 0; /* No default end */
return 0;
}
const Class_info *get_class_info() const;
};
@ -498,11 +446,18 @@ class Gis_geometry_collection: public Geometry
public:
uint32 get_data_size() const;
bool init_from_wkt(Gis_read_stream *trs, String *wkb);
bool get_data_as_wkt(String *txt, const char **end);
bool get_data_as_wkt(String *txt, const char **end) const;
bool get_mbr(MBR *mbr, const char **end) const;
bool num_geometries(uint32 *num) const;
bool geometry_n(uint32 num, String *result) const;
int num_geometries(uint32 *num) const;
int geometry_n(uint32 num, String *result) const;
bool dimension(uint32 *dim, const char **end) const;
const Class_info *get_class_info() const;
};
const int geometry_buffer_size= sizeof(Gis_point);
struct Geometry_buffer
{
void *arr[(geometry_buffer_size - 1)/sizeof(void *) + 1];
};
#endif

View file

@ -1321,8 +1321,8 @@ bool st_select_lex_unit::create_total_list(THD *thd_arg, st_lex *lex,
DESCRIPTION
This is used for UNION & subselect to create a new table list of all used
tables.
The table_list->table entry in all used tables are set to point
to the entries in this list.
The table_list->table_list in all tables of global list are set to point
to the local SELECT_LEX entries.
RETURN
0 - OK
@ -1373,7 +1373,7 @@ create_total_list_n_last_return(THD *thd_arg,
{
TABLE_LIST *cursor;
next_table= aux->next;
/* Add not used table to the total table list */
/* Add to the total table list */
if (!(cursor= (TABLE_LIST *) thd->memdup((char*) aux,
sizeof(*aux))))
{

View file

@ -342,6 +342,50 @@ static int sort_keys(KEY *a, KEY *b)
0);
}
/*
Check TYPELIB (set or enum) for duplicates
SYNOPSIS
check_duplicates_in_interval()
set_or_name "SET" or "ENUM" string for warning message
name name of the checked column
typelib list of values for the column
DESCRIPTION
This function prints an warning for each value in list
which has some duplicates on its right
RETURN VALUES
void
*/
void check_duplicates_in_interval(const char *set_or_name,
const char *name, TYPELIB *typelib)
{
unsigned int old_count= typelib->count;
const char **old_type_names= typelib->type_names;
if (typelib->count <= 1)
return;
old_count= typelib->count;
old_type_names= typelib->type_names;
const char **cur_value= typelib->type_names;
for ( ; typelib->count > 1; cur_value++)
{
typelib->type_names++;
typelib->count--;
if (find_type((char*)*cur_value,typelib,1))
{
push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_DUPLICATED_VALUE_IN_TYPE,
ER(ER_DUPLICATED_VALUE_IN_TYPE),
name,*cur_value,set_or_name);
}
}
typelib->count= old_count;
typelib->type_names= old_type_names;
}
/*
Create a table
@ -546,6 +590,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
if (sql_field->charset->state & MY_CS_BINSORT)
sql_field->pack_flag|=FIELDFLAG_BINARY;
sql_field->unireg_check=Field::INTERVAL_FIELD;
check_duplicates_in_interval("ENUM",sql_field->field_name,
sql_field->interval);
break;
case FIELD_TYPE_SET:
sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
@ -553,6 +599,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
if (sql_field->charset->state & MY_CS_BINSORT)
sql_field->pack_flag|=FIELDFLAG_BINARY;
sql_field->unireg_check=Field::BIT_FIELD;
check_duplicates_in_interval("SET",sql_field->field_name,
sql_field->interval);
break;
case FIELD_TYPE_DATE: // Rest of string types
case FIELD_TYPE_NEWDATE:
@ -639,6 +687,12 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
DBUG_RETURN(-1);
}
key_parts+=key->columns.elements;
if (key->name && !tmp_table &&
!my_strcasecmp(system_charset_info,key->name,primary_key_name))
{
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name);
DBUG_RETURN(-1);
}
}
tmp=min(file->max_keys(), MAX_KEY);
if (key_count > tmp)
@ -1079,7 +1133,8 @@ make_unique_key_name(const char *field_name,KEY *start,KEY *end)
{
char buff[MAX_FIELD_NAME],*buff_end;
if (!check_if_keyname_exists(field_name,start,end))
if (!check_if_keyname_exists(field_name,start,end) &&
my_strcasecmp(system_charset_info,field_name,primary_key_name))
return (char*) field_name; // Use fieldname
buff_end=strmake(buff,field_name,MAX_FIELD_NAME-4);
for (uint i=2 ; ; i++)
@ -2403,6 +2458,12 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
{
if (key->type != Key::FOREIGN_KEY)
key_list.push_back(key);
if (key->name &&
!my_strcasecmp(system_charset_info,key->name,primary_key_name))
{
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name);
DBUG_RETURN(-1);
}
}
}

View file

@ -2941,14 +2941,14 @@ geometry_function:
{ $$= GEOM_NEW(Item_func_geometry_from_wkb($3, $5)); }
| GEOMETRYCOLLECTION '(' expr_list ')'
{ $$= GEOM_NEW(Item_func_spatial_collection(* $3,
Geometry::wkbGeometryCollection,
Geometry::wkbPoint)); }
Geometry::wkb_geometrycollection,
Geometry::wkb_point)); }
| LINESTRING '(' expr_list ')'
{ $$= GEOM_NEW(Item_func_spatial_collection(* $3,
Geometry::wkbLineString, Geometry::wkbPoint)); }
Geometry::wkb_linestring, Geometry::wkb_point)); }
| MULTILINESTRING '(' expr_list ')'
{ $$= GEOM_NEW( Item_func_spatial_collection(* $3,
Geometry::wkbMultiLineString, Geometry::wkbLineString)); }
Geometry::wkb_multilinestring, Geometry::wkb_linestring)); }
| MLINEFROMTEXT '(' expr ')'
{ $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
| MLINEFROMTEXT '(' expr ',' expr ')'
@ -2963,10 +2963,10 @@ geometry_function:
{ $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
| MULTIPOINT '(' expr_list ')'
{ $$= GEOM_NEW(Item_func_spatial_collection(* $3,
Geometry::wkbMultiPoint, Geometry::wkbPoint)); }
Geometry::wkb_multipoint, Geometry::wkb_point)); }
| MULTIPOLYGON '(' expr_list ')'
{ $$= GEOM_NEW(Item_func_spatial_collection(* $3,
Geometry::wkbMultiPolygon, Geometry::wkbPolygon)); }
Geometry::wkb_multipolygon, Geometry::wkb_polygon)); }
| POINT_SYM '(' expr ',' expr ')'
{ $$= GEOM_NEW(Item_func_point($3,$5)); }
| POINTFROMTEXT '(' expr ')'
@ -2979,7 +2979,7 @@ geometry_function:
{ $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
| POLYGON '(' expr_list ')'
{ $$= GEOM_NEW(Item_func_spatial_collection(* $3,
Geometry::wkbPolygon, Geometry::wkbLineString)); }
Geometry::wkb_polygon, Geometry::wkb_linestring)); }
| GEOMCOLLFROMTEXT '(' expr ')'
{ $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
| GEOMCOLLFROMTEXT '(' expr ',' expr ')'

View file

@ -391,9 +391,11 @@ str_to_TIME(const char *str, uint length, TIME *l_time, uint flags)
ulong not_zero_date, allow_space;
bool is_internal_format;
const char *pos, *last_field_pos;
const char *str_begin= str;
const char *end=str+length;
const uchar *format_position;
bool found_delimitier= 0, found_space= 0;
uint frac_pos, frac_len;
DBUG_ENTER("str_to_TIME");
DBUG_PRINT("ENTER",("str: %.*s",length,str));
@ -482,7 +484,7 @@ str_to_TIME(const char *str, uint length, TIME *l_time, uint flags)
tmp_value=tmp_value*10 + (ulong) (uchar) (*str - '0');
str++;
}
date_len[i]+= (uint) (str - start);
date_len[i]= (uint) (str - start);
if (tmp_value > 999999) // Impossible date part
DBUG_RETURN(TIMESTAMP_NONE);
date[i]=tmp_value;
@ -535,9 +537,9 @@ str_to_TIME(const char *str, uint length, TIME *l_time, uint flags)
{
if (str+2 <= end && (str[1] == 'M' || str[1] == 'm'))
{
if (str[1] == 'p' || str[1] == 'P')
if (str[0] == 'p' || str[0] == 'P')
add_hours= 12;
else if (str[1] != 'a' || str[1] != 'A')
else if (str[0] != 'a' || str[0] != 'A')
continue; // Not AM/PM
str+= 2; // Skip AM/PM
/* Skip space after AM/PM */
@ -569,7 +571,13 @@ str_to_TIME(const char *str, uint length, TIME *l_time, uint flags)
l_time->hour= date[(uint) format_position[3]];
l_time->minute= date[(uint) format_position[4]];
l_time->second= date[(uint) format_position[5]];
l_time->second_part= date[(uint) format_position[6]];
frac_pos= (uint) format_position[6];
frac_len= date_len[frac_pos];
if (frac_len < 6)
date[frac_pos]*= (uint) log_10_int[6 - frac_len];
l_time->second_part= date[frac_pos];
if (format_position[7] != (uchar) 255)
{
if (l_time->hour > 12)
@ -585,6 +593,8 @@ str_to_TIME(const char *str, uint length, TIME *l_time, uint flags)
l_time->hour= date[3];
l_time->minute= date[4];
l_time->second= date[5];
if (date_len[6] < 6)
date[6]*= (uint) log_10_int[6 - date_len[6]];
l_time->second_part=date[6];
}
l_time->neg= 0;
@ -614,15 +624,17 @@ str_to_TIME(const char *str, uint length, TIME *l_time, uint flags)
current_thd->cuted_fields++;
goto err;
}
if (str != end && current_thd->count_cuted_fields)
l_time->time_type= (number_of_fields <= 3 ?
TIMESTAMP_DATE : TIMESTAMP_DATETIME);
for (; str != end ; str++)
{
for (; str != end ; str++)
if (!my_isspace(&my_charset_latin1,*str))
{
if (!my_isspace(&my_charset_latin1,*str))
{
current_thd->cuted_fields++;
break;
}
make_truncated_value_warning(current_thd, str_begin, length,
l_time->time_type);
break;
}
}
@ -686,6 +698,7 @@ bool str_to_time(const char *str,uint length,TIME *l_time)
{
long date[5],value;
const char *end=str+length, *end_of_days;
const char *str_begin= str;
bool found_days,found_hours;
uint state;
@ -706,7 +719,7 @@ bool str_to_time(const char *str,uint length,TIME *l_time)
{ // Probably full timestamp
enum timestamp_type res= str_to_TIME(str,length,l_time,
(TIME_FUZZY_DATE |
TIME_DATETIME_ONLY));
TIME_DATETIME_ONLY));
if ((int) res >= (int) TIMESTAMP_DATETIME_ERROR)
return res == TIMESTAMP_DATETIME_ERROR;
}
@ -784,6 +797,8 @@ fractional:
my_isdigit(&my_charset_latin1,str[0]) &&
field_length--)
value=value*10 + (uint) (uchar) (*str - '0');
if (field_length)
value*= (long) log_10_int[field_length];
date[4]=value;
}
else
@ -796,12 +811,12 @@ fractional:
str++;
if (str+2 <= end && (str[1] == 'M' || str[1] == 'm'))
{
if (str[1] == 'p' || str[1] == 'P')
if (str[0] == 'p' || str[0] == 'P')
{
str+= 2;
date[1]= date[1]%12 + 12;
}
else if (str[1] == 'a' || str[1] == 'A')
else if (str[0] == 'a' || str[0] == 'A')
str+=2;
}
}
@ -822,13 +837,14 @@ fractional:
l_time->time_type= TIMESTAMP_TIME;
/* Check if there is garbage at end of the TIME specification */
if (str != end && current_thd->count_cuted_fields)
if (str != end)
{
do
{
if (!my_isspace(&my_charset_latin1,*str))
{
current_thd->cuted_fields++;
make_truncated_value_warning(current_thd, str_begin, length,
TIMESTAMP_TIME);
break;
}
} while (++str != end);
@ -1265,3 +1281,35 @@ void make_datetime(DATE_TIME_FORMAT *format, TIME *l_time, String *str)
str->length(length);
str->set_charset(&my_charset_bin);
}
void make_truncated_value_warning(THD *thd, const char *str_val,
uint str_length, timestamp_type time_type)
{
char warn_buff[MYSQL_ERRMSG_SIZE];
const char *type_str;
char buff[128];
String str(buff,(uint32) sizeof(buff), system_charset_info);
str.length(0);
str.append(str_val, str_length);
str.append('\0');
switch (time_type) {
case TIMESTAMP_DATE:
type_str= "date";
break;
case TIMESTAMP_DATETIME:
type_str= "datetime";
break;
case TIMESTAMP_TIME:
type_str= "time";
break;
default:
type_str= "string";
break;
}
sprintf(warn_buff, ER(ER_TRUNCATED_WRONG_VALUE),
type_str, str.ptr());
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_TRUNCATED_WRONG_VALUE, warn_buff);
}

View file

@ -2,7 +2,7 @@
An alternative implementation of "strtod()" that is both
simplier, and thread-safe.
From mit-threads as bundled with MySQL 3.22
From mit-threads as bundled with MySQL 3.23
SQL:2003 specifies a number as
@ -41,6 +41,7 @@ double my_strtod(const char *str, char **end)
double result= 0.0;
int negative, ndigits;
const char *old_str;
my_bool overflow=0;
while (my_isspace(&my_charset_latin1, *str))
str++;
@ -85,7 +86,8 @@ double my_strtod(const char *str, char **end)
double scaler= 1.0;
while (my_isdigit (&my_charset_latin1, *str))
{
exp= exp*10 + *str - '0';
if (exp < 9999) /* protection against exp overflow */
exp= exp*10 + *str - '0';
str++;
}
if (exp >= 1000)
@ -93,7 +95,7 @@ double my_strtod(const char *str, char **end)
if (neg)
result= 0.0;
else
result= DBL_MAX*10;
overflow=1;
goto done;
}
while (exp >= 100)
@ -113,6 +115,12 @@ done:
if (end)
*end = (char *)str;
if (overflow || ((overflow=isinf(result))))
{
result=DBL_MAX;
errno=EOVERFLOW;
}
return negative ? -result : result;
}

View file

@ -35,6 +35,7 @@ pkgdata_DATA = my-small.cnf \
my-large.cnf \
my-huge.cnf \
mysql-log-rotate \
mysql-@VERSION@.spec \
MySQL-shared-compat.spec
pkgdata_SCRIPTS = mysql.server