mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 11:01:52 +01:00
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:
commit
7b13e02039
65 changed files with 1498 additions and 784 deletions
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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= ¶m->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;
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'
|
||||
#
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
18
sql/field.cc
18
sql/field.cc
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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(<ime, 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, <ime, 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(<ime, 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(<ime,t_type);
|
||||
field->store_time(<ime, TIMESTAMP_DATE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
longlong Item_func_from_days::val_int()
|
||||
longlong Item_date::val_int()
|
||||
{
|
||||
TIME ltime;
|
||||
if (get_date(<ime, 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, <ime->year, <ime->month, <ime->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, <ime, 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(<ime, 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)),
|
||||
<ime, 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(<ime,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, <ime, 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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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'"
|
||||
|
|
388
sql/spatial.cc
388
sql/spatial.cc
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
271
sql/spatial.h
271
sql/spatial.h
|
@ -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
|
||||
|
|
|
@ -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))))
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ')'
|
||||
|
|
80
sql/time.cc
80
sql/time.cc
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue