summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2004-02-14 13:31:39 +0200
committerunknown <bell@sanja.is.com.ua>2004-02-14 13:31:39 +0200
commit6826a55b1da73770ce067972efafc00f9d2f6670 (patch)
tree5a43e43d6a139a343cb71c89c1209240d9287db0
parentfab7113f8398ba41d5e54e32dc0b3259a6297dfc (diff)
parent4ec12a5e55d5f2db27a5c0ce93c7e74254d652a4 (diff)
downloadmariadb-git-6826a55b1da73770ce067972efafc00f9d2f6670.tar.gz
merge
sql/item.h: Auto merged sql/item_sum.h: Auto merged sql/sql_class.h: Auto merged sql/sql_lex.cc: Auto merged sql/sql_prepare.cc: Auto merged
-rw-r--r--configure.in2
-rw-r--r--include/m_ctype.h4
-rw-r--r--include/m_string.h6
-rw-r--r--include/my_global.h14
-rw-r--r--include/mysql.h2
-rw-r--r--libmysql/Makefile.shared2
-rw-r--r--libmysql/libmysql.c4
-rw-r--r--libmysqld/lib_sql.cc10
-rw-r--r--mysql-test/r/ctype_utf8.result2
-rw-r--r--mysql-test/r/mysqldump.result2
-rw-r--r--mysql-test/r/show_check.result48
-rw-r--r--mysql-test/t/ctype_utf8.test7
-rw-r--r--mysql-test/t/show_check.test40
-rw-r--r--mysys/mf_keycache.c4
-rw-r--r--mysys/my_new.cc4
-rw-r--r--mytest-old.c169
-rw-r--r--sql-common/client.c3
-rw-r--r--sql/gstream.cc2
-rw-r--r--sql/init.cc3
-rw-r--r--sql/item.h2
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/item_sum.h4
-rw-r--r--sql/mysql_priv.h2
-rw-r--r--sql/sql_analyse.cc2
-rw-r--r--sql/sql_class.h3
-rw-r--r--sql/sql_lex.cc43
-rw-r--r--sql/sql_parse.cc32
-rw-r--r--sql/sql_prepare.cc10
-rw-r--r--sql/sql_show.cc76
-rw-r--r--sql/sql_string.cc2
-rw-r--r--sql/sql_table.cc7
-rw-r--r--sql/sql_yacc.yy26
-rw-r--r--strings/Makefile.am6
-rw-r--r--strings/atof.c207
-rw-r--r--strings/ctype-simple.c6
-rw-r--r--strings/ctype-ucs2.c6
-rw-r--r--strings/strtod.c140
-rw-r--r--tests/client_test.c85
38 files changed, 501 insertions, 488 deletions
diff --git a/configure.in b/configure.in
index 9cdb9d209c2..67a751f7e17 100644
--- a/configure.in
+++ b/configure.in
@@ -1828,7 +1828,7 @@ AC_CHECK_FUNCS(alarm bmove \
strtol strtoul strtoll strtoull snprintf tempnam thr_setconcurrency \
gethostbyaddr_r gethostbyname_r getpwnam \
bfill bzero bcmp strstr strpbrk strerror \
- tell atod memcpy memmove \
+ tell isinf memcpy memmove \
setupterm strcasecmp sighold vidattr lrand48 localtime_r gmtime_r \
sigset sigthreadmask pthread_sigmask pthread_setprio pthread_setprio_np \
pthread_setschedparam pthread_attr_setprio pthread_attr_setschedparam \
diff --git a/include/m_ctype.h b/include/m_ctype.h
index 88c3418fc0d..9c843382fc7 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -391,7 +391,11 @@ extern my_bool my_parse_charset_xml(const char *bug, uint len,
#define use_mb(s) ((s)->cset->ismbchar != NULL)
#define my_ismbchar(s, a, b) ((s)->cset->ismbchar((s), (a), (b)))
+#ifdef USE_MB
#define my_mbcharlen(s, a) ((s)->cset->mbcharlen((s),(a)))
+#else
+#define my_mbcharlen(s, a) 1
+#endif
#define my_caseup(s, a, l) ((s)->cset->caseup((s), (a), (l)))
#define my_casedn(s, a, l) ((s)->cset->casedn((s), (a), (l)))
diff --git a/include/m_string.h b/include/m_string.h
index d72342fb3c1..ac2aae37704 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -201,7 +201,7 @@ extern int strcmp(const char *, const char *);
extern size_t strlen(const char *);
#endif
#endif
-#ifndef HAVE_STRNLEN
+#ifndef HAVE_STRNLEN
extern uint strnlen(const char *s, uint n);
#endif
@@ -215,7 +215,9 @@ extern char *strstr(const char *, const char *);
#endif
extern int is_prefix(const char *, const char *);
-/* Conversion rutins */
+/* Conversion routines */
+double my_strtod(const char *str, char **end);
+double my_atof(const char *nptr);
#ifdef USE_MY_ITOA
extern char *my_itoa(int val,char *dst,int radix);
diff --git a/include/my_global.h b/include/my_global.h
index c9660d4d649..41e3636116a 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -522,7 +522,7 @@ typedef SOCKET_SIZE_TYPE size_socket;
#define FN_EXTCHAR '.'
#define FN_HOMELIB '~' /* ~/ is used as abbrev for home dir */
#define FN_CURLIB '.' /* ./ is used as abbrev for current dir */
-#define FN_PARENTDIR ".." /* Parentdirectory; Must be a string */
+#define FN_PARENTDIR ".." /* Parent directory; Must be a string */
#define FN_DEVCHAR ':'
#ifndef FN_LIBCHAR
@@ -581,14 +581,6 @@ typedef SOCKET_SIZE_TYPE size_socket;
/* Some defines of functions for portability */
-#ifndef HAVE_ATOD
-#define atod atof
-#endif
-#ifdef USE_MY_ATOF
-#define atof my_atof
-extern void init_my_atof(void);
-extern double my_atof(const char*);
-#endif
#undef remove /* Crashes MySQL on SCO 5.0.0 */
#ifndef __WIN__
#ifdef OS2
@@ -677,6 +669,10 @@ extern double my_atof(const char*);
#define FLT_MAX ((float)3.40282346638528860e+38)
#endif
+#ifndef HAVE_ISINF
+#define isinf(X) 0
+#endif
+
/*
Max size that must be added to a so that we know Size to make
adressable obj.
diff --git a/include/mysql.h b/include/mysql.h
index 0bb42c7f5eb..cd5d01d6f44 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -534,6 +534,8 @@ typedef struct st_mysql_stmt
char *query; /* query buffer */
MEM_ROOT mem_root; /* root allocations */
my_ulonglong last_fetched_column; /* last fetched column */
+ my_ulonglong affected_rows; /* copy of mysql->affected_rows
+ after statement execution */
unsigned long stmt_id; /* Id for prepared statement */
unsigned int last_errno; /* error code */
unsigned int param_count; /* parameters count */
diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared
index 1cffae4dc56..678abc91859 100644
--- a/libmysql/Makefile.shared
+++ b/libmysql/Makefile.shared
@@ -32,7 +32,7 @@ target_sources = libmysql.c password.c manager.c \
get_password.c errmsg.c
mystringsobjects = strmov.lo strxmov.lo strxnmov.lo strnmov.lo \
- strmake.lo strend.lo \
+ strmake.lo strend.lo strtod.lo \
strnlen.lo strfill.lo is_prefix.lo \
int2str.lo str2int.lo strinstr.lo strcont.lo \
strcend.lo bcmp.lo ctype-latin1.lo \
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 5c5898dfd7d..859ec92f793 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -2010,6 +2010,7 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length)
set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
DBUG_RETURN(1);
}
+ stmt->affected_rows= mysql->affected_rows;
DBUG_RETURN(0);
}
@@ -2106,7 +2107,7 @@ ulong STDCALL mysql_param_count(MYSQL_STMT * stmt)
my_ulonglong STDCALL mysql_stmt_affected_rows(MYSQL_STMT *stmt)
{
- return stmt->mysql->last_used_con->affected_rows;
+ return stmt->affected_rows;
}
@@ -3173,6 +3174,7 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
DBUG_RETURN(0);
}
mysql->affected_rows= result->row_count= result->data->rows;
+ stmt->affected_rows= result->row_count;
result->data_cursor= result->data->data;
result->fields= stmt->fields;
result->field_count= stmt->field_count;
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index 81235ce0c22..188227c21f9 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -251,7 +251,7 @@ int emb_next_result(MYSQL *mysql)
DBUG_ENTER("emb_next_result");
if (emb_advanced_command(mysql, COM_QUERY,0,0,
- thd->query_rest,thd->query_rest_length,1)
+ thd->query_rest.ptr(),thd->query_rest.length(),1)
|| emb_mysql_read_query_result(mysql))
DBUG_RETURN(1);
@@ -689,7 +689,10 @@ send_ok(THD *thd,ha_rows affected_rows,ulonglong id,const char *message)
mysql->affected_rows= affected_rows;
mysql->insert_id= id;
if (message)
+ {
strmake(thd->net.last_error, message, sizeof(thd->net.last_error)-1);
+ mysql->info= thd->net.last_error;
+ }
DBUG_VOID_RETURN;
}
@@ -762,11 +765,6 @@ bool Protocol::net_store_data(const char *from, uint length)
return false;
}
-char *memdup_mysql(struct st_mysql *mysql, const char*data, int length)
-{
- return memdup_root(&mysql->field_alloc, data, length);
-}
-
#if 0
/* The same as Protocol::net_store_data but does the converstion
*/
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 658a7b8f5f6..8b7178993a7 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -167,3 +167,5 @@ select hex(s1) from t1;
hex(s1)
41
drop table t1;
+create table t1 (a char(160) character set utf8, primary key(a));
+ERROR HY000: Incorrect sub part key. The used key part isn't a string, the used length is longer than the key part or the storage engine doesn't support unique sub keys
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index fd9e2a1f42b..0e642f48f3c 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -186,7 +186,7 @@ create table ```a` (i int);
/*!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 ```a`;
-CREATE TABLE ``a` (
+CREATE TABLE ```a` (
`i` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result
index 290f916ae72..235c6cd0ecf 100644
--- a/mysql-test/r/show_check.result
+++ b/mysql-test/r/show_check.result
@@ -265,3 +265,51 @@ c decimal(4,3) YES NULL
d double(4,3) YES NULL
f float(4,3) YES NULL
drop table t1;
+SET sql_mode='';
+SET sql_quote_show_create=OFF;
+CREATE TABLE ```ab``cd``` (i INT);
+SHOW CREATE TABLE ```ab``cd```;
+Table Create Table
+`ab`cd` CREATE TABLE ```ab``cd``` (
+ i int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE ```ab``cd```;
+CREATE TABLE ```ab````cd``` (i INT);
+SHOW CREATE TABLE ```ab````cd```;
+Table Create Table
+`ab``cd` CREATE TABLE ```ab````cd``` (
+ i int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE ```ab````cd```;
+CREATE TABLE ```a` (i INT);
+SHOW CREATE TABLE ```a`;
+Table Create Table
+`a CREATE TABLE ```a` (
+ i int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE ```a`;
+SET sql_mode='ANSI_QUOTES';
+CREATE TABLE """a" (i INT);
+SHOW CREATE TABLE """a";
+Table Create Table
+"a CREATE TABLE """a" (
+ i int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE """a";
+SET sql_mode='';
+SET sql_quote_show_create=OFF;
+CREATE TABLE t1 (i INT);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE t1 (
+ i int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE `table` (i INT);
+SHOW CREATE TABLE `table`;
+Table Create Table
+table CREATE TABLE `table` (
+ i int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE `table`;
+SET sql_quote_show_create=ON;
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index 0615de99b7a..49b1ed94757 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -98,3 +98,10 @@ create table t1 (s1 text character set utf8);
insert into t1 values (0x41FF);
select hex(s1) from t1;
drop table t1;
+
+#
+# Bug 2699
+# UTF8 breaks primary keys for cols > 85 characters
+#
+--error 1089
+create table t1 (a char(160) character set utf8, primary key(a));
diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test
index d262f02c978..1d64cfd2105 100644
--- a/mysql-test/t/show_check.test
+++ b/mysql-test/t/show_check.test
@@ -142,3 +142,43 @@ drop table t1;
create table t1 (c decimal(3,3), d double(3,3), f float(3,3));
show columns from t1;
drop table t1;
+
+#
+# Test for Bug #2593 "SHOW CREATE TABLE doesn't properly double quotes"
+#
+
+SET sql_mode='';
+SET sql_quote_show_create=OFF;
+
+CREATE TABLE ```ab``cd``` (i INT);
+SHOW CREATE TABLE ```ab``cd```;
+DROP TABLE ```ab``cd```;
+
+CREATE TABLE ```ab````cd``` (i INT);
+SHOW CREATE TABLE ```ab````cd```;
+DROP TABLE ```ab````cd```;
+
+CREATE TABLE ```a` (i INT);
+SHOW CREATE TABLE ```a`;
+DROP TABLE ```a`;
+
+SET sql_mode='ANSI_QUOTES';
+
+CREATE TABLE """a" (i INT);
+SHOW CREATE TABLE """a";
+DROP TABLE """a";
+
+# to test quotes around keywords.. :
+
+SET sql_mode='';
+SET sql_quote_show_create=OFF;
+
+CREATE TABLE t1 (i INT);
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE `table` (i INT);
+SHOW CREATE TABLE `table`;
+DROP TABLE `table`;
+
+SET sql_quote_show_create=ON;
diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c
index 08737221fb2..52b7f153e0d 100644
--- a/mysys/mf_keycache.c
+++ b/mysys/mf_keycache.c
@@ -627,7 +627,7 @@ writes: %ld r_requests: %ld reads: %ld",
a pointer to the last element.
*/
-static inline void link_into_queue(KEYCACHE_WQUEUE *wqueue,
+static void link_into_queue(KEYCACHE_WQUEUE *wqueue,
struct st_my_thread_var *thread)
{
struct st_my_thread_var *last;
@@ -662,7 +662,7 @@ static inline void link_into_queue(KEYCACHE_WQUEUE *wqueue,
See NOTES for link_into_queue
*/
-static inline void unlink_from_queue(KEYCACHE_WQUEUE *wqueue,
+static void unlink_from_queue(KEYCACHE_WQUEUE *wqueue,
struct st_my_thread_var *thread)
{
KEYCACHE_DBUG_PRINT("unlink_from_queue", ("thread %ld", thread->id));
diff --git a/mysys/my_new.cc b/mysys/my_new.cc
index ec27502d8aa..14423c3afd5 100644
--- a/mysys/my_new.cc
+++ b/mysys/my_new.cc
@@ -19,10 +19,10 @@
with gcc 3.0.x to avoid including libstdc++
*/
-#ifdef USE_MYSYS_NEW
-
#include "mysys_priv.h"
+#ifdef USE_MYSYS_NEW
+
void *operator new (size_t sz)
{
return (void *) malloc (sz ? sz : 1);
diff --git a/mytest-old.c b/mytest-old.c
deleted file mode 100644
index 8b4029f5e1e..00000000000
--- a/mytest-old.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*C4*/
-/****************************************************************/
-/* Author: Jethro Wright, III TS : 3/ 4/1998 9:15 */
-/* Date: 02/18/1998 */
-/* mytest.c : do some testing of the libmySQL.DLL.... */
-/* */
-/* History: */
-/* 02/18/1998 jw3 also sprach zarathustra.... */
-/****************************************************************/
-
-
-#include <windows.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <mysql.h>
-
-#define DEFALT_SQL_STMT "SELECT * FROM db"
-#ifndef offsetof
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-#endif
-
-
-/********************************************************
-**
-** main :-
-**
-********************************************************/
-
-int
-main( int argc, char * argv[] )
-{
-
- char szSQL[ 200 ], aszFlds[ 25 ][ 25 ], * pszT, szDB[ 50 ] ;
- int i, j, k, l, x ;
- MYSQL * myData ;
- MYSQL_RES * res ;
- MYSQL_FIELD * fd ;
- MYSQL_ROW row ;
-
- //....just curious....
- printf( "sizeof( MYSQL ) == %d\n", sizeof( MYSQL ) ) ;
- if ( argc == 2 )
- {
- strcpy( szDB, argv[ 1 ] ) ;
- strcpy( szSQL, DEFALT_SQL_STMT ) ;
- if (!strcmp(szDB,"--debug"))
- {
- strcpy( szDB, "mysql" ) ;
- printf("Some mysql struct information (size and offset):\n");
- printf("net:\t%3d %3d\n",sizeof(myData->net),offsetof(MYSQL,net));
- printf("host:\t%3d %3d\n",sizeof(myData->host),offsetof(MYSQL,host));
- printf("port:\t%3d %3d\n",sizeof(myData->port),offsetof(MYSQL,port));
- printf("protocol_version:\t%3d %3d\n",sizeof(myData->protocol_version),
- offsetof(MYSQL,protocol_version));
- printf("thread_id:\t%3d %3d\n",sizeof(myData->thread_id),
- offsetof(MYSQL,thread_id));
- printf("affected_rows:\t%3d %3d\n",sizeof(myData->affected_rows),
- offsetof(MYSQL,affected_rows));
- printf("packet_length:\t%3d %3d\n",sizeof(myData->packet_length),
- offsetof(MYSQL,packet_length));
- printf("status:\t%3d %3d\n",sizeof(myData->status),
- offsetof(MYSQL,status));
- printf("fields:\t%3d %3d\n",sizeof(myData->fields),
- offsetof(MYSQL,fields));
- printf("field_alloc:\t%3d %3d\n",sizeof(myData->field_alloc),
- offsetof(MYSQL,field_alloc));
- printf("free_me:\t%3d %3d\n",sizeof(myData->free_me),
- offsetof(MYSQL,free_me));
- printf("options:\t%3d %3d\n",sizeof(myData->options),
- offsetof(MYSQL,options));
- puts("");
- }
- }
- else if ( argc > 2 ) {
- strcpy( szDB, argv[ 1 ] ) ;
- strcpy( szSQL, argv[ 2 ] ) ;
- }
- else {
- strcpy( szDB, "mysql" ) ;
- strcpy( szSQL, DEFALT_SQL_STMT ) ;
- }
- //....
-
- if ( (myData = mysql_init((MYSQL*) 0)) &&
- mysql_real_connect( myData, NULL, NULL, NULL, NULL, MYSQL_PORT,
- NULL, 0 ) )
- {
- if ( mysql_select_db( myData, szDB ) < 0 ) {
- printf( "Can't select the %s database !\n", szDB ) ;
- mysql_close( myData ) ;
- return 2 ;
- }
- }
- else {
- printf( "Can't connect to the mysql server on port %d !\n",
- MYSQL_PORT ) ;
- mysql_close( myData ) ;
- return 1 ;
- }
- //....
- if ( ! mysql_query( myData, szSQL ) ) {
- res = mysql_store_result( myData ) ;
- i = (int) mysql_num_rows( res ) ; l = 1 ;
- printf( "Query: %s\nNumber of records found: %ld\n", szSQL, i ) ;
- //....we can get the field-specific characteristics here....
- for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
- strcpy( aszFlds[ x ], fd->name ) ;
- //....
- while ( row = mysql_fetch_row( res ) ) {
- j = mysql_num_fields( res ) ;
- printf( "Record #%ld:-\n", l++ ) ;
- for ( k = 0 ; k < j ; k++ )
- printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
- (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
- puts( "==============================\n" ) ;
- }
- mysql_free_result( res ) ;
- }
- else printf( "Couldn't execute %s on the server !\n", szSQL ) ;
- //....
- puts( "==== Diagnostic info ====" ) ;
- pszT = mysql_get_client_info() ;
- printf( "Client info: %s\n", pszT ) ;
- //....
- pszT = mysql_get_host_info( myData ) ;
- printf( "Host info: %s\n", pszT ) ;
- //....
- pszT = mysql_get_server_info( myData ) ;
- printf( "Server info: %s\n", pszT ) ;
- //....
- res = mysql_list_processes( myData ) ; l = 1 ;
- if (res)
- {
- for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
- strcpy( aszFlds[ x ], fd->name ) ;
- while ( row = mysql_fetch_row( res ) ) {
- j = mysql_num_fields( res ) ;
- printf( "Process #%ld:-\n", l++ ) ;
- for ( k = 0 ; k < j ; k++ )
- printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
- (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
- puts( "==============================\n" ) ;
- }
- }
- else
- {
- printf("Got error %s when retreiving processlist\n",mysql_error(myData));
- }
- //....
- res = mysql_list_tables( myData, "%" ) ; l = 1 ;
- for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
- strcpy( aszFlds[ x ], fd->name ) ;
- while ( row = mysql_fetch_row( res ) ) {
- j = mysql_num_fields( res ) ;
- printf( "Table #%ld:-\n", l++ ) ;
- for ( k = 0 ; k < j ; k++ )
- printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
- (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
- puts( "==============================\n" ) ;
- }
- //....
- pszT = mysql_stat( myData ) ;
- puts( pszT ) ;
- //....
- mysql_close( myData ) ;
- return 0 ;
-
-}
diff --git a/sql-common/client.c b/sql-common/client.c
index 1c58bd04d0e..10df4653601 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1420,7 +1420,8 @@ static MYSQL_METHODS client_methods=
cli_read_binary_rows,
cli_unbuffered_fetch,
NULL,
- cli_read_statistic
+ cli_read_statistic,
+ cli_read_query_result
#endif
};
diff --git a/sql/gstream.cc b/sql/gstream.cc
index a97ed9cae03..17b85af22bd 100644
--- a/sql/gstream.cc
+++ b/sql/gstream.cc
@@ -101,7 +101,7 @@ int GTextReadStream::get_next_number(double *d)
char *endptr;
- *d = strtod(cur, &endptr);
+ *d = my_strtod(cur, &endptr);
if (endptr)
{
diff --git a/sql/init.cc b/sql/init.cc
index 033dfd72843..084db57f8aa 100644
--- a/sql/init.cc
+++ b/sql/init.cc
@@ -34,9 +34,6 @@ void unireg_init(ulong options)
current_pid=(ulong) getpid(); /* Save for later ref */
init_time(); /* Init time-functions (read zone) */
-#ifdef USE_MY_ATOF
- init_my_atof(); /* use our atof */
-#endif
#ifndef EMBEDDED_LIBRARY
my_abort_hook=unireg_abort; /* Abort with close of databases */
#endif
diff --git a/sql/item.h b/sql/item.h
index 2ad85832747..9bdde1c9847 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -449,7 +449,7 @@ class Item_real :public Item
public:
const double value;
// Item_real() :value(0) {}
- Item_real(const char *str_arg,uint length) :value(atof(str_arg))
+ Item_real(const char *str_arg,uint length) :value(my_atof(str_arg))
{
name=(char*) str_arg;
decimals=(uint8) nr_of_decimals(str_arg);
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 34a61ba0353..82ff9de4a56 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2254,7 +2254,7 @@ double user_var_entry::val(my_bool *null_value)
case INT_RESULT:
return (double) *(longlong*) value;
case STRING_RESULT:
- return atof(value); // This is null terminated
+ return my_atof(value); // This is null terminated
case ROW_RESULT:
DBUG_ASSERT(1); // Impossible
break;
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 06989f30ae5..840ed1d1f7d 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -738,7 +738,7 @@ class Item_func_group_concat : public Item_sum
enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;}
const char *func_name() const { return "group_concat"; }
- enum Type type() const { return SUM_FUNC_ITEM; }
+ enum Type type() const { return SUM_FUNC_ITEM; }
virtual Item_result result_type () const { return STRING_RESULT; }
void clear();
bool add();
@@ -750,7 +750,7 @@ class Item_func_group_concat : public Item_sum
double val()
{
String *res; res=val_str(&str_value);
- return res ? atof(res->c_ptr()) : 0.0;
+ return res ? my_atof(res->c_ptr()) : 0.0;
}
longlong val_int()
{
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 73cc8b9ce03..ed56924775e 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -764,6 +764,8 @@ uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match);
uint check_word(TYPELIB *lib, const char *val, const char *end,
const char **end_of_word);
+bool is_keyword(const char *name, uint len);
+
#define MY_DB_OPT_FILE "db.opt"
bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create);
diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc
index 9e73e06d9c6..3c9563165fe 100644
--- a/sql/sql_analyse.cc
+++ b/sql/sql_analyse.cc
@@ -225,7 +225,7 @@ bool test_if_number(NUM_INFO *info, const char *str, uint str_len)
info->decimals++;
if (str == end)
{
- info->dval = atod(begin);
+ info->dval = my_atof(begin);
return 1;
}
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 93703acc97b..a3f3737e46f 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -591,8 +591,7 @@ public:
struct st_mysql_bind *client_params;
char *extra_data;
ulong extra_length;
- char *query_rest;
- uint32 query_rest_length;
+ String query_rest;
#endif
NET net; // client connection descriptor
MEM_ROOT warn_root; // For warnings and errors
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index f145a232809..7679bccebfd 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -181,6 +181,23 @@ static int find_keyword(LEX *lex, uint len, bool function)
return 0;
}
+/*
+ Check if name is a keyword
+
+ SYNOPSIS
+ is_keyword()
+ name checked name
+ len length of checked name
+
+ RETURN VALUES
+ 0 name is a keyword
+ 1 name isn't a keyword
+*/
+
+bool is_keyword(const char *name, uint len)
+{
+ return get_hash_symbol(name,len,0)!=0;
+}
/* make a copy of token before ptr and set yytoklen */
@@ -427,7 +444,6 @@ inline static uint int_token(const char *str,uint length)
return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger;
}
-
/*
yylex remember the following states from the following yylex()
@@ -678,10 +694,9 @@ int yylex(void *arg, void *yythd)
char quote_char= c; // Used char
lex->tok_start=lex->ptr; // Skip first `
while ((c=yyGet()))
- {
-#ifdef USE_MB
- if (my_mbcharlen(cs, c) == 1)
-#endif
+ {
+ int l;
+ if ((l= my_mbcharlen(cs, c)) == 1)
{
if (c == (uchar) NAMES_SEP_CHAR)
break; /* Old .frm format can't handle this char */
@@ -695,15 +710,12 @@ int yylex(void *arg, void *yythd)
}
}
#ifdef USE_MB
- else
+ else if (l > 1)
{
- int l;
- if ((l = my_ismbchar(cs,
- (const char *)lex->ptr-1,
- (const char *)lex->end_of_query)) == 0)
- break;
lex->ptr += l-1;
}
+ else
+ break;
#endif
}
if (double_quotes)
@@ -886,8 +898,13 @@ int yylex(void *arg, void *yythd)
}
/* fall true */
case MY_LEX_EOL:
- lex->next_state=MY_LEX_END; // Mark for next loop
- return(END_OF_INPUT);
+ if (lex->ptr >= lex->end_of_query)
+ {
+ lex->next_state=MY_LEX_END; // Mark for next loop
+ return(END_OF_INPUT);
+ }
+ state=MY_LEX_CHAR;
+ break;
case MY_LEX_END:
lex->next_state=MY_LEX_END;
return(0); // We found end of input last time
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 81d6b80678d..69ee43d53d1 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -48,7 +48,6 @@
extern "C" int gethostname(char *name, int namelen);
#endif
-char *memdup_mysql(struct st_mysql *mysql, const char*data, int length);
static int check_for_max_user_connections(THD *thd, USER_CONN *uc);
static void decrease_user_connections(USER_CONN *uc);
static bool check_db_used(THD *thd,TABLE_LIST *tables);
@@ -1420,8 +1419,17 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#ifndef EMBEDDED_LIBRARY
mysql_parse(thd, packet, length);
#else
- thd->query_rest= (char*)memdup_mysql(thd->mysql, packet, length);
- thd->query_rest_length= length;
+ /*
+ 'packet' can point inside the query_rest's buffer
+ so we have to do memmove here
+ */
+ if (thd->query_rest.length() > length)
+ {
+ memmove(thd->query_rest.c_ptr(), packet, length);
+ thd->query_rest.length(length);
+ }
+ else
+ thd->query_rest.copy(length);
break;
#endif /*EMBEDDED_LIBRARY*/
}
@@ -3854,23 +3862,7 @@ mysql_parse(THD *thd, char *inBuf, uint length)
if (query_cache_send_result_to_client(thd, inBuf, length) <= 0)
{
LEX *lex=lex_start(thd, (uchar*) inBuf, length);
- if (!yyparse((void *)thd) && ! thd->is_fatal_error &&
- /*
- If this is not a multiple query, ensure that it has been
- successfully parsed until the last character. This is to prevent
- against a wrong (too big) length passed to mysql_real_query(),
- mysql_prepare()... which can generate garbage characters at the
- end. If the query was initially multiple, found_colon will be false
- only when we are in the last query; this last query had already
- been end-spaces-stripped by alloc_query() in dispatch_command(); as
- end spaces are the only thing we accept at the end of a query, and
- they have been stripped already, here we can require that nothing
- remains after parsing.
- */
- (thd->lex->found_colon ||
- (char*)(thd->lex->ptr) == (thd->query+thd->query_length+1) ||
- /* yyerror() will show the garbage chars to the user */
- (yyerror("syntax error"), 0)))
+ if (!yyparse((void *)thd) && ! thd->is_fatal_error)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (mqh_used && thd->user_connect &&
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 9be11b6154c..a3c1b5a46eb 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -947,15 +947,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
lex->safe_to_cache_query= 0;
lex->param_count= 0;
- if (yyparse((void *)thd) || thd->is_fatal_error ||
- /*
- Check for wrong (too big) length passed to mysql_prepare() resulting in
- garbage at the end of the query. There is a similar check in mysql_parse().
- */
- (!thd->lex->found_colon &&
- (char*)(thd->lex->ptr) != (thd->query+thd->query_length+1) &&
- /* yyerror() will show the garbage chars to the user */
- (yyerror("syntax error"), 1)) || send_prepare_results(stmt))
+ if (yyparse((void *)thd) || thd->is_fatal_error || send_prepare_results(stmt))
goto yyparse_err;
lex_end(lex);
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 4da2522bd3f..f076e2fe802 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1085,8 +1085,7 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd)
DBUG_RETURN(0);
}
-/* possible TODO: call find_keyword() from sql_lex.cc here */
-static bool require_quotes(const char *name, uint length)
+static inline const char *require_quotes(const char *name, uint length)
{
uint i, d, c;
for (i=0; i<length; i+=d)
@@ -1094,7 +1093,37 @@ static bool require_quotes(const char *name, uint length)
c=((uchar *)name)[i];
d=my_mbcharlen(system_charset_info, c);
if (d==1 && !system_charset_info->ident_map[c])
- return 1;
+ return name+i;
+ }
+ return 0;
+}
+
+/*
+ Looking for char in multibyte string
+
+ SYNOPSIS
+ look_for_char()
+ name string for looking at
+ length length of name
+ q '\'' or '\"' for looking for
+
+ RETURN VALUES
+ # pointer to found char in string
+ 0 string doesn't contain required char
+*/
+
+static inline const char *look_for_char(const char *name,
+ uint length, char q)
+{
+ const char *cur= name;
+ const char *end= cur+length;
+ uint symbol_length;
+ for (; cur<end; cur+= symbol_length)
+ {
+ char c= *cur;
+ symbol_length= my_mbcharlen(system_charset_info, c);
+ if (symbol_length==1 && c==q)
+ return cur;
}
return 0;
}
@@ -1103,21 +1132,52 @@ void
append_identifier(THD *thd, String *packet, const char *name, uint length)
{
char qtype;
+ uint part_len;
+ const char *qplace;
if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
qtype= '\"';
else
qtype= '`';
- if ((thd->options & OPTION_QUOTE_SHOW_CREATE) ||
- require_quotes(name, length))
+ if (is_keyword(name,length))
{
- packet->append(&qtype, 1);
+ packet->append(&qtype, 1, system_charset_info);
packet->append(name, length, system_charset_info);
- packet->append(&qtype, 1);
+ packet->append(&qtype, 1, system_charset_info);
}
else
{
- packet->append(name, length, system_charset_info);
+ if (!(qplace= require_quotes(name, length)))
+ {
+ if (!(thd->options & OPTION_QUOTE_SHOW_CREATE))
+ packet->append(name, length, system_charset_info);
+ else
+ {
+ packet->append(&qtype, 1, system_charset_info);
+ packet->append(name, length, system_charset_info);
+ packet->append(&qtype, 1, system_charset_info);
+ }
+ }
+ else
+ {
+ packet->shrink(packet->length()+length+2);
+ packet->append(&qtype, 1, system_charset_info);
+ if (*qplace != qtype)
+ qplace= look_for_char(qplace+1,length-(qplace-name)-1,qtype);
+ while (qplace)
+ {
+ if ((part_len= qplace-name))
+ {
+ packet->append(name, part_len, system_charset_info);
+ length-= part_len;
+ }
+ packet->append(qplace, 1, system_charset_info);
+ name= qplace;
+ qplace= look_for_char(name+1,length-1,qtype);
+ }
+ packet->append(name, length, system_charset_info);
+ packet->append(&qtype, 1, system_charset_info);
+ }
}
}
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 093b85b46b7..e76c7902210 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -453,7 +453,7 @@ bool String::append(const char *s,uint32 arg_length, CHARSET_INFO *cs)
if (!arg_length) // Default argument
if (!(arg_length= (uint32) strlen(s)))
return FALSE;
- if (str_charset->mbmaxlen > 1)
+ if (cs != str_charset && str_charset->mbmaxlen > 1)
{
uint32 add_length=arg_length * str_charset->mbmaxlen;
if (realloc(str_length+ add_length))
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 4e66154e2a2..404d2b56e06 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -877,7 +877,12 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
column->field_name);
DBUG_RETURN(-1);
}
- key_part_info->length=(uint8) length;
+ if (length > file->max_key_part_length())
+ {
+ my_error(ER_WRONG_SUB_KEY,MYF(0));
+ DBUG_RETURN(-1);
+ }
+ key_part_info->length=(uint16) length;
/* Use packed keys for long strings on the first column */
if (!(db_options & HA_OPTION_NO_PACK_KEYS) &&
(length >= KEY_DEFAULT_PACK_LENGTH &&
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index bdeaf5a0b86..0e68fcc016d 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -2152,13 +2152,13 @@ select_init:
SELECT_LEX * sel= lex->current_select;
if (sel->set_braces(1))
{
- send_error(lex->thd, ER_SYNTAX_ERROR);
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
if (sel->linkage == UNION_TYPE &&
!sel->master_unit()->first_select()->braces)
{
- send_error(lex->thd, ER_SYNTAX_ERROR);
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
/* select in braces, can't contain global parameters */
@@ -2174,13 +2174,13 @@ select_init2:
SELECT_LEX * sel= lex->current_select;
if (lex->current_select->set_braces(0))
{
- send_error(lex->thd, ER_SYNTAX_ERROR);
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
if (sel->linkage == UNION_TYPE &&
sel->master_unit()->first_select()->braces)
{
- send_error(lex->thd, ER_SYNTAX_ERROR);
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
}
@@ -2734,7 +2734,7 @@ simple_expr:
{
if ($1->type() != Item::ROW_ITEM)
{
- send_error(Lex->thd, ER_SYNTAX_ERROR);
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
$$= new Item_func_interval((Item_row *)$1);
@@ -3070,7 +3070,7 @@ in_sum_expr:
LEX *lex= Lex;
if (lex->current_select->inc_in_sum_expr())
{
- send_error(lex->thd, ER_SYNTAX_ERROR);
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
}
@@ -3241,8 +3241,8 @@ select_derived:
if (((int)lex->sql_command >= (int)SQLCOM_HA_OPEN &&
lex->sql_command <= (int)SQLCOM_HA_READ) ||
lex->sql_command == (int)SQLCOM_KILL)
- {
- send_error(lex->thd, ER_SYNTAX_ERROR);
+ {
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE ||
@@ -3877,7 +3877,7 @@ opt_insert_update:
for a moment */
if (Lex->sql_command != SQLCOM_INSERT)
{
- send_error(Lex->thd, ER_SYNTAX_ERROR);
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
}
@@ -4484,7 +4484,7 @@ param_marker:
}
else
{
- yyerror("You have an error in your SQL syntax");
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
}
@@ -5527,7 +5527,7 @@ union_list:
}
if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)
{
- send_error(lex->thd, ER_SYNTAX_ERROR);
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
if (mysql_new_select(lex, 0))
@@ -5627,8 +5627,8 @@ subselect_start:
if (((int)lex->sql_command >= (int)SQLCOM_HA_OPEN &&
lex->sql_command <= (int)SQLCOM_HA_READ) ||
lex->sql_command == (int)SQLCOM_KILL)
- {
- send_error(lex->thd, ER_SYNTAX_ERROR);
+ {
+ yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
if (mysql_new_select(Lex, 1))
diff --git a/strings/Makefile.am b/strings/Makefile.am
index 61219c8abb9..89f32ac6b40 100644
--- a/strings/Makefile.am
+++ b/strings/Makefile.am
@@ -22,19 +22,19 @@ pkglib_LIBRARIES = libmystrings.a
# Exact one of ASSEMBLER_X
if ASSEMBLER_x86
ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s
-CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c ctype-extra.c
+CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c ctype-extra.c
else
if ASSEMBLER_sparc32
# These file MUST all be on the same line!! Otherwise automake
# generats a very broken makefile
ASRCS = bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s
-CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c ctype-extra.c my_strtoll10.c
+CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c ctype-extra.c my_strtoll10.c
else
#no assembler
ASRCS =
# These file MUST all be on the same line!! Otherwise automake
# generats a very broken makefile
-CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c ctype-extra.c my_strtoll10.c
+CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c ctype-extra.c my_strtoll10.c
endif
endif
diff --git a/strings/atof.c b/strings/atof.c
deleted file mode 100644
index 0e0aa598718..00000000000
--- a/strings/atof.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/* Copyright (C) 2000 MySQL AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/*
- A quicker atof. About 2-10 times faster than standard atof on sparc.
- This don't handle iee-options (NaN...) and the presission :s is a little
- less for some high exponential numbers (+-1 at 14th place).
- Returns 0.0 if overflow or wrong number.
- Must be inited with init_my_atof to handle possibly overflows.
-*/
-
-#include <my_global.h>
-#ifdef USE_MY_ATOF /* Skipp if we don't want it */
-#include <m_ctype.h>
-#include <floatingpoint.h>
-#include <signal.h>
-
-/* Read a double. If float is wrong return 0.
- float ::= [space]* [sign] {digit}+ decimal-point {digit}+ [exponent] |
- [sign] {digit}+ [decimal-point {digit}*] exponent |
- [sign] {digit}+ decimal-point [{digit}*] exponent |
- [sign] decimal-point {digit}* exponent |
- exponent :: = exponent-marker [sign] {digit}+
- exponent-marker ::= E e
- */
-
-
-#define is_exponent_marker(ch) (ch == 'E' || ch == 'e')
-
-static void my_atof_overflow _A((int sig,int code, struct sigcontext *scp,
- char *addr));
-static int parse_sign _A((char **str));
-static void parse_float_number_part _A((char **str,double *number, int *length));
-static void parse_decimal_number_part _A((char **str,double *number));
-static int parse_int_number_part _A((char **str,uint *number));
-
-static int volatile overflow,in_my_atof;
-static sigfpe_handler_type old_overflow_handler;
-
-void init_my_atof()
-{
- old_overflow_handler = (sigfpe_handler_type)
- ieee_handler("get", "overflow", old_overflow_handler);
- VOID(ieee_handler("set", "overflow", my_atof_overflow));
- return;
-}
-
-static void my_atof_overflow(sig, code, scp, addr)
-int sig;
-int code;
-struct sigcontext *scp;
-char *addr;
-{
- if (!in_my_atof)
- old_overflow_handler(sig,code,scp,addr);
- else
- overflow=1;
- return;
-}
-
-double my_atof(src)
-const char *src;
-{
- int sign, exp_sign; /* is number negative (+1) or positive (-1) */
- int length_before_point;
- double after_point; /* Number after decimal point and before exp */
- uint exponent; /* Exponent value */
- double exp_log,exp_val;
- char *tmp_src;
- double result_number;
-
- tmp_src = (char*) src;
- while (isspace(tmp_src[0]))
- tmp_src++; /* Skipp pre-space */
- sign = parse_sign(&tmp_src);
- overflow=0;
- in_my_atof=1;
- parse_float_number_part(&tmp_src, &result_number, &length_before_point);
- if (*tmp_src == '.')
- {
- tmp_src++;
- parse_decimal_number_part(&tmp_src, &after_point);
- result_number += after_point;
- }
- else if (length_before_point == 0)
- {
- in_my_atof=0;
- return 0.0;
- }
- if (is_exponent_marker(*tmp_src))
- {
- tmp_src++;
- exp_sign = parse_sign(&tmp_src);
- overflow|=parse_int_number_part(&tmp_src, &exponent);
-
- exp_log=10.0; exp_val=1.0;
- for (;;)
- {
- if (exponent & 1)
- {
- exp_val*= exp_log;
- exponent--;
- }
- if (!exponent)
- break;
- exp_log*=exp_log;
- exponent>>=1;
- }
- if (exp_sign < 0)
- result_number*=exp_val;
- else
- result_number/=exp_val;
- }
- if (sign > 0)
- result_number= -result_number;
-
- in_my_atof=0;
- if (overflow)
- return 0.0;
- return result_number;
-}
-
-
-static int parse_sign(str)
-char **str;
-{
- if (**str == '-')
- {
- (*str)++;
- return 1;
- }
- if (**str == '+')
- (*str)++;
- return -1;
-}
-
- /* Get number with may be separated with ',' */
-
-static void parse_float_number_part(str, number, length)
-char **str;
-double *number;
-int *length;
-{
- *number = 0;
- *length = 0;
-
- for (;;)
- {
- while (isdigit(**str))
- {
- (*length)++;
- *number = (*number * 10) + (**str - '0');
- (*str)++;
- }
- if (**str != ',')
- return; /* Skipp possibly ',' */
- (*str)++;
- }
-}
-
-static void parse_decimal_number_part(str, number)
-char **str;
-double *number;
-{
- double exp_log;
-
- *number = 0;
- exp_log=1/10.0;
- while (isdigit(**str))
- {
- *number+= (**str - '0')*exp_log;
- exp_log/=10;
- (*str)++;
- }
-}
-
- /* Parses int suitably for exponent */
-
-static int parse_int_number_part(str, number)
-char **str;
-uint *number;
-{
- *number = 0;
- while (isdigit(**str))
- {
- if (*number >= ((uint) ~0)/10)
- return 1; /* Don't overflow */
- *number = (*number * 10) + **str - '0';
- (*str)++;
- }
- return 0;
-}
-
-#endif
diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c
index 233251e16a8..e4435d1222d 100644
--- a/strings/ctype-simple.c
+++ b/strings/ctype-simple.c
@@ -684,7 +684,7 @@ noconv:
double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)),
- char *str, uint length,
+ char *str, uint length,
char **end, int *err)
{
char end_char;
@@ -702,12 +702,12 @@ double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)),
#else
if (length == INT_MAX32 || str[length] == 0)
#endif
- result= strtod(str, end);
+ result= my_strtod(str, end);
else
{
end_char= str[length];
str[length]= 0;
- result= strtod(str, end);
+ result= my_strtod(str, end);
str[length]= end_char; /* Restore end char */
}
*err= errno;
diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c
index bb74e0cf56b..ec306d9af35 100644
--- a/strings/ctype-ucs2.c
+++ b/strings/ctype-ucs2.c
@@ -856,7 +856,7 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
if (length >= sizeof(buf))
length= sizeof(buf)-1;
end= s+length;
-
+
while ((cnv=cs->cset->mb_wc(cs,&wc,s,end)) > 0)
{
s+=cnv;
@@ -865,9 +865,9 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
*b++= (char) wc;
}
*b= 0;
-
+
errno= 0;
- res=strtod(buf, endptr);
+ res=my_strtod(buf, endptr);
*err= errno;
if (endptr)
*endptr=(char*) (*endptr-buf+nptr);
diff --git a/strings/strtod.c b/strings/strtod.c
new file mode 100644
index 00000000000..ea6acbac6c4
--- /dev/null
+++ b/strings/strtod.c
@@ -0,0 +1,140 @@
+/*
+ An alternative implementation of "strtod()" that is both
+ simplier, and thread-safe.
+
+ From mit-threads as bundled with MySQL 3.22
+
+ SQL:2003 specifies a number as
+
+<signed numeric literal> ::= [ <sign> ] <unsigned numeric literal>
+
+<unsigned numeric literal> ::=
+ <exact numeric literal>
+ | <approximate numeric literal>
+
+<exact numeric literal> ::=
+ <unsigned integer> [ <period> [ <unsigned integer> ] ]
+ | <period> <unsigned integer>
+
+<approximate numeric literal> ::= <mantissa> E <exponent>
+
+<mantissa> ::= <exact numeric literal>
+
+<exponent> ::= <signed integer>
+
+ So do we.
+
+ */
+
+#include "my_base.h"
+#include "m_ctype.h"
+
+static double scaler10[] = {
+ 1.0, 1e10, 1e20, 1e30, 1e40, 1e50, 1e60, 1e70, 1e80, 1e90
+};
+static double scaler1[] = {
+ 1.0, 10.0, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9
+};
+
+// let's use a static array for not to accumulate the error
+static double pastpoint[] = {
+ 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, 1e-8, 1e-9,
+ 1e-10, 1e-11, 1e-12, 1e-13, 1e-14, 1e-15, 1e-16, 1e-17, 1e-18, 1e-19,
+ 1e-20, 1e-21, 1e-22, 1e-23, 1e-24, 1e-25, 1e-26, 1e-27, 1e-28, 1e-29,
+ 1e-30, 1e-31, 1e-32, 1e-33, 1e-34, 1e-35, 1e-36, 1e-37, 1e-38, 1e-39,
+ 1e-40, 1e-41, 1e-42, 1e-43, 1e-44, 1e-45, 1e-46, 1e-47, 1e-48, 1e-49,
+ 1e-50, 1e-51, 1e-52, 1e-53, 1e-54, 1e-55, 1e-56, 1e-57, 1e-58, 1e-59,
+};
+
+double my_strtod(const char *str, char **end)
+{
+ double result= 0.0;
+ int negative, ndigits;
+ const char *old_str;
+
+ while (my_isspace(&my_charset_latin1, *str))
+ str++;
+
+ if ((negative= (*str == '-')) || *str=='+')
+ str++;
+
+ old_str= str;
+ while (my_isdigit (&my_charset_latin1, *str))
+ {
+ result= result*10.0 + (*str - '0');
+ str++;
+ }
+ ndigits= str-old_str;
+
+ if (*str == '.')
+ {
+ int n= 0;
+ str++;
+ old_str= str;
+ while (my_isdigit (&my_charset_latin1, *str))
+ {
+ if (n < sizeof(pastpoint)/sizeof(pastpoint[0]))
+ {
+ result+= pastpoint[n] * (*str - '0');
+ n++;
+ }
+ str++;
+ }
+ ndigits+= str-old_str;
+ if (!ndigits) str--;
+ }
+ if (ndigits && (*str=='e' || *str=='E'))
+ {
+ int exp= 0;
+ int neg= 0;
+ const char *old_str= str++;
+
+ if ((neg= (*str == '-')) || *str == '+')
+ str++;
+
+ if (!my_isdigit (&my_charset_latin1, *str))
+ str= old_str;
+ else
+ {
+ double scaler= 1.0;
+ while (my_isdigit (&my_charset_latin1, *str))
+ {
+ exp= exp*10 + *str - '0';
+ str++;
+ }
+ if (exp >= 1000)
+ {
+ if (neg)
+ result= 0.0;
+ else
+ result= DBL_MAX;
+ goto done;
+ }
+ while (exp >= 100)
+ {
+ scaler*= 1.0e100;
+ exp-= 100;
+ }
+ scaler*= scaler10[exp/10]*scaler1[exp%10];
+ if (neg)
+ result/= scaler;
+ else
+ result*= scaler;
+ }
+ }
+
+done:
+ if (end)
+ *end = (char *)str;
+
+ if (isinf(result))
+ result=DBL_MAX;
+
+ return negative ? -result : result;
+}
+
+double my_atof(const char *nptr)
+{
+ return (strtod(nptr, 0));
+}
+
diff --git a/tests/client_test.c b/tests/client_test.c
index 0f3698b8a29..2275ef6d9f7 100644
--- a/tests/client_test.c
+++ b/tests/client_test.c
@@ -8113,6 +8113,84 @@ static void test_parse_error_and_bad_length()
}
+static void test_bug2247()
+{
+ MYSQL_STMT *stmt;
+ MYSQL_RES *res;
+ int rc;
+ int i;
+ const char *create= "CREATE TABLE bug2247(id INT UNIQUE AUTO_INCREMENT)";
+ const char *insert= "INSERT INTO bug2247 VALUES (NULL)";
+ const char *select= "SELECT id FROM bug2247";
+ const char *update= "UPDATE bug2247 SET id=id+10";
+ const char *drop= "DROP TABLE IF EXISTS bug2247";
+ ulonglong exp_count;
+ enum { NUM_ROWS= 5 };
+
+ myheader("test_bug2247");
+
+ fprintf(stdout, "\nChecking if stmt_affected_rows is not affected by\n"
+ "mysql_query ... ");
+ /* create table and insert few rows */
+ rc = mysql_query(mysql, drop);
+ myquery(rc);
+
+ rc= mysql_query(mysql, create);
+ myquery(rc);
+
+ stmt= mysql_prepare(mysql, insert, strlen(insert));
+ mystmt_init(stmt);
+ for (i= 0; i < NUM_ROWS; ++i)
+ {
+ rc= mysql_execute(stmt);
+ mystmt(stmt, rc);
+ }
+ exp_count= mysql_stmt_affected_rows(stmt);
+ assert(exp_count == 1);
+
+ rc= mysql_query(mysql, select);
+ myquery(rc);
+ /*
+ mysql_store_result overwrites mysql->affected_rows. Check that
+ mysql_stmt_affected_rows() returns the same value, whereas
+ mysql_affected_rows() value is correct.
+ */
+ res= mysql_store_result(mysql);
+ mytest(res);
+
+ assert(mysql_affected_rows(mysql) == NUM_ROWS);
+ assert(exp_count == mysql_stmt_affected_rows(stmt));
+
+ rc= mysql_query(mysql, update);
+ myquery(rc);
+ assert(mysql_affected_rows(mysql) == NUM_ROWS);
+ assert(exp_count == mysql_stmt_affected_rows(stmt));
+
+ mysql_free_result(res);
+ mysql_stmt_close(stmt);
+
+ /* check that mysql_stmt_store_result modifies mysql_stmt_affected_rows */
+ stmt= mysql_prepare(mysql, select, strlen(select));
+ mystmt_init(stmt);
+
+ rc= mysql_execute(stmt);
+ mystmt(stmt, rc);
+ rc= mysql_stmt_store_result(stmt);
+ mystmt(stmt, rc);
+ exp_count= mysql_stmt_affected_rows(stmt);
+ assert(exp_count == NUM_ROWS);
+
+ rc= mysql_query(mysql, insert);
+ myquery(rc);
+ assert(mysql_affected_rows(mysql) == 1);
+ assert(mysql_stmt_affected_rows(stmt) == exp_count);
+
+ mysql_stmt_close(stmt);
+ fprintf(stdout, "OK");
+}
+
+
+
static void test_subqueries()
{
MYSQL_STMT *stmt;
@@ -8195,7 +8273,9 @@ static void test_distinct()
myquery(rc);
}
-
+/*
+ Test for bug#2248 "mysql_fetch without prior mysql_execute hangs"
+*/
static void test_bug2248()
{
@@ -8502,6 +8582,9 @@ int main(int argc, char **argv)
test_bug2248(); /* BUG#2248 */
test_parse_error_and_bad_length(); /* test if bad length param in
mysql_prepare() triggers error */
+ test_bug2247(); /* test that mysql_stmt_affected_rows() returns
+ number of rows affected by last prepared
+ statement execution */
test_subqueries(); /* repeatable subqueries */
test_bad_union(); /* correct setup of UNION */
test_distinct(); /* distinct aggregate functions */