summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <monty@mashka.mysql.fi>2003-02-12 23:18:00 +0200
committerunknown <monty@mashka.mysql.fi>2003-02-12 23:18:00 +0200
commit86ec3c8f085c65b9ac2ef8776cad956465abddd7 (patch)
tree924512c54bd3a6090a69986d62adfd8be7ce1fdd
parent0a10f78f1245fef3b2a3f5ca9a413ab830ea088e (diff)
parentc5040dddee0e84076ec7860a9e8ce5df0ced581d (diff)
downloadmariadb-git-86ec3c8f085c65b9ac2ef8776cad956465abddd7.tar.gz
Merge work:/home/bk/mysql-4.1 into mashka.mysql.fi:/home/my/mysql-4.1
libmysql/libmysql.c: Auto merged scripts/mysqld_safe.sh: Auto merged sql/field.cc: Auto merged sql/lex.h: Auto merged sql/sql_derived.cc: Auto merged sql/sql_yacc.yy: Auto merged
-rw-r--r--Docs/gis.txt15
-rwxr-xr-xDocs/prepare.texi566
-rw-r--r--libmysql/libmysql.c43
-rw-r--r--myisam/rt_index.c2
-rw-r--r--scripts/mysqld_safe.sh3
-rw-r--r--sql/field.cc2
-rw-r--r--sql/item_uniq.h2
-rw-r--r--sql/lex.h18
-rw-r--r--sql/sql_derived.cc2
-rw-r--r--sql/sql_yacc.yy22
-rw-r--r--tests/client_test.c685
11 files changed, 1011 insertions, 349 deletions
diff --git a/Docs/gis.txt b/Docs/gis.txt
index d80a200d5a6..3556949d516 100644
--- a/Docs/gis.txt
+++ b/Docs/gis.txt
@@ -496,18 +496,28 @@ built GEOMETRY value.
* |*LineFromText(lineStringTaggedText String [,SRID
Integer]):LineString *| - constructs a LineString
+ . |*LineStringFromText()*| - synonym for LineFromText().
+
* |*PolyFromText(polygonTaggedText String [,SRID Integer]):Polygon
*|- constructs a Polygon
+ |*PolygonFromText()*| - synonym for PolyFromText().
+
* |*MPointFromText(multiPointTaggedText String [,SRID
Integer]):MultiPoint *| - constructs a MultiPoint
+ |*MultiPointFromText()*| - synonym for MPointFromText().
+
* |*MLineFromText(multiLineStringTaggedText String [,SRID
Integer]):MultiLineString *| - constructs a MultiLineString
+ |*MultiLineStringFromText()*| - synonym for MLineFromText().
+
* |*MPolyFromText(multiPolygonTaggedText String [,SRID
Integer]):MultiPolygon *| - constructs a MultiPolygon
+ |*MultiPolygonFromText()*| - synonym for MPolyFromText().
+
* |*GeomCollFromText(geometryCollectionTaggedText String [,SRID
Integer]):GeomCollection *| - constructs a GeometryCollection
@@ -844,7 +854,10 @@ implementation of several spatial field types correspondent to every
instansiable object subclass. For example a *Point* type is proposed to
restrict data stored in a field of this type to only Point OpenGIS
subclass. MySQL provides an implementation of single GEOMETRY type which
-doesn't restrict objects to certain OpenGIS subclass.
+doesn't restrict objects to certain OpenGIS subclass. Other proposed
+spatial field types are mapped into GEOMETRY type, so all these types
+can be used as a symonym for GEOMETRY: POINT, MULTIPOINT, LINESTRING,
+MULTILINESTRING, POLYGON, MULTIPOLYGON.
9.2 No additional Metadata Views
diff --git a/Docs/prepare.texi b/Docs/prepare.texi
index 7a526800213..0b515012980 100755
--- a/Docs/prepare.texi
+++ b/Docs/prepare.texi
@@ -117,6 +117,8 @@
* C Prepared statement datatypes::
* C Prepared statements function overview::
* C Prepared statement functions::
+* multiple queries::
+* date handling::
@end menu
@node C Prepared statements, C Prepared statement datatypes, MySQL prepared statements, MySQL prepared statements
@@ -160,8 +162,10 @@ Prepared statements mainly uses the following two @code{MYSQL_STMT} and
@sp 1
@table @code
-@tindex MYSQL C type
+@tindex MYSQL_STMT C type
+
@item MYSQL_STMT
+
This structure represents a statement handle to prepared statements.It
is used for all statement related functions.
@@ -178,11 +182,14 @@ the system resources.
@sp 1
@tindex MYSQL_BIND C type
+
@item MYSQL_BIND
-This structure is used in order to bind parameter buffers inorder to
-send the parameters data to @code{mysql_execute()} call; as well as to
-bind row buffers to fetch the result set data using @code{mysql_fetch()}.
-@end table
+
+This structure is used in order to bind parameter
+buffers(@code{mysql_bind_param()}) inorder to the parameters data to
+@code{mysql_execute()} call; as well as to bind row
+buffers(@code{mysql_bind_result()}) to fetch the result set data using
+@code{mysql_fetch()}.
@sp 1
@@ -191,6 +198,7 @@ The @code{MYSQL_BIND} structure contains the members listed here:
@table @code
+
@item enum enum_field_types buffer_type [input]
The type of the buffer. The @code{type} value must be one of the following:
@@ -202,6 +210,10 @@ The type of the buffer. The @code{type} value must be one of the following:
@item @code{MYSQL_TYPE_LONGLONG}
@item @code{MYSQL_TYPE_FLOAT}
@item @code{MYSQL_TYPE_DOUBLE}
+@item @code{MYSQL_TYPE_TIME}
+@item @code{MYSQL_TYPE_DATE}
+@item @code{MYSQL_TYPE_DATETIME}
+@item @code{MYSQL_TYPE_TIMESTAMP}
@item @code{MYSQL_TYPE_STRING}
@item @code{MYSQL_TYPE_VAR_STRING}
@item @code{MYSQL_TYPE_TINY_BLOB}
@@ -218,49 +230,62 @@ data when the structure is used for result set bind.
@sp 1
+@item unsigned long buffer_length [input]
+Length of the @code{*buffer} in bytes. For character and binary C data,
+the buffer_length specifies the length of the @code{*buffer} to be used
+as a parameter data in case if it is used with @code{mysql_bind_param()}
+or to return that many bytes when fetching results when this is used
+with @code{mysql_bind_result()}.
+
+
@item long *length [input/output]
Pointer to the buffer for the parameter's length. When the structure is
used as a input parameter data binding, then this argument points to a
-buffer that, when @code{mysql_execute()} is called, contains one of the
-following:
-
-@itemize @bullet
-@item
-The length of the parameter value stored in *buffer. This is ignored
-except for character or binary C data.
-@item
-MYSQL_NULL_DATA. The parameter value is NULL.
-@item
-MYSQL_LONG_DATA. The parameter value is a long data and is supplied in
-chunks through @code{mysql_send_long_data()}.
-@end itemize
+buffer that, when @code{mysql_execute()} is called, contains the length
+of the parameter value stored in *buffer. This is ignored except for
+character or binary C data.
If the length is a null pointer, then the protocol assumes that all
-input parameter values are non-NULL and that character and binary data
-are null terminated.
-
+character and binary data are null terminated.
When this structure is used in output binding, then @code{mysql_fetch()}
-return the following values in the length buffer:
-
-@itemize @bullet
-@item
-The length of the data that is returned
-@item
-MYSQL_NULL_DATA, indicating the data returned is a NULL data.
-@end itemize
-
-
-@c @item bool is_null [input]
-@c To indicate the parameter data is NULL. This is same as supplying
-@c MYSQL_NULL_DATA, -1 as the length in length pointer.
-
-
-@c @item bool is_long_data [input]
-@c To indicate the parameter data is a long data, and the data will be
-@c supplied in chunks through @code{mysql_send_long_data()}.This is also
-@c same as supplying MYSQL_LONG_DATA, -2 as the length in length pointer.
-@c @end table
+return the the length of the data that is returned.
+
+@sp 1
+
+@item bool *is_null [input/output]
+Indicates if the parameter data is NULL or fetched data is NULL.
+@end table
+
+@sp 1
+
+@tindex MySQL C type
+
+@item MYSQL_TIME
+
+This structure is used to send and receive DATE, TIME and
+TIMESTAMP data directly to/from server.
+
+@sp 1
+
+@noindent
+The @code{MYSQL_TIME} structure contains the members listed here:
+
+@multitable @columnfractions .20 .20 .68
+
+@item @strong{Member} @tab @strong{Type} @tab @strong{Description}
+
+@item @code{year} @tab unsigned int @tab Year.
+@item @code{month} @tab unsigned int @tab Month of the year.
+@item @code{day} @tab unsigned int @tab Day of the month.
+@item @code{hour} @tab unsigned int @tab Hour of the day(TIME).
+@item @code{minute} @tab unsigned int @tab Minute of the hour.
+@item @code{second} @tab unsigned int @tab Second of the minute.
+@item @code{neg} @tab my_bool @tab A boolean flag to
+indicate if the time is negative.
+@item @code{second_part} @tab unsigned long @tab Fraction part of the
+second(not yet used)
+@end multitable
@end table
@@ -289,7 +314,10 @@ are described in greater detail in the later section.
@item @strong{mysql_stmt_affected_rows()} @tab Returns the number of rows changes/deleted/inserted by the last UPDATE,DELETE,or INSERT query
-@item @strong{mysql_bind_result()} @tab Binds application data buffers to columns in the resultset.
+@item @strong{mysql_bind_result()} @tab Binds application data buffers
+to columns in the resultset.
+
+@item @strong{mysql_stmt_store_result()} @tab Retrieves the complete result set to the client
@item @strong{mysql_fetch()} @tab Fetches the next rowset of data from the result set and returns data for all bound columns.
@@ -315,6 +343,7 @@ are described in greater detail in the later section.
@end multitable
@sp 1
+
Call @code{mysql_prepare()} to prepare and initialize the statement
handle, then call @code{mysql_bind_param()} to supply the parameters
data, and then call @code{mysql_execute()} to execute the query. You can
@@ -421,7 +450,7 @@ You can get the statement error code and message using
@code{mysql_stmt_errno()} and @code{mysql_stmt_error()} respectively.
-@node C Prepared statement functions, , C Prepared statements function overview, MySQL prepared statements
+@node C Prepared statement functions, multiple queries, C Prepared statements function overview, MySQL prepared statements
@subsection C Prepared Statement Function Descriptions
You need to use the following functions when you want to prepare and
@@ -429,21 +458,24 @@ execute the queries.
@menu
-* mysql_prepare::
-* mysql_param_count::
-* mysql_prepare_result::
-* mysql_bind_param::
-* mysql_execute::
-* mysql_stmt_affected_rows::
-* mysql_bind_result::
-* mysql_fetch::
-* mysql_send_long_data::
-* mysql_stmt_close::
-* mysql_stmt_errno::
-* mysql_stmt_error::
-* mysql_commit::
-* mysql_rollback::
-* mysql_autocommit::
+* mysql_prepare:: @code{mysql_prepare()}
+* mysql_param_count:: @code{mysql_param_count()}
+* mysql_prepare_result:: @code{mysql_prepare_result()}
+* mysql_bind_param:: @code{mysql_bind_param()}
+* mysql_execute:: @code{mysql_execute()}
+* mysql_stmt_affected_rows:: @code{mysql_stmt_affected_rows()}
+* mysql_bind_result:: @code{mysql_bind_result()}
+* mysql_stmt_store_result:: @code{mysql_stmt_store_result()}
+* mysql_fetch:: @code{mysql_fetch()}
+* mysql_send_long_data:: @code{mysql_send_long_data()}
+* mysql_stmt_close:: @code{mysql_stmt_close()}
+* mysql_stmt_errno:: @code{mysql_stmt_errno()}
+* mysql_stmt_error:: @code{mysql_stmt_error()}
+* mysql_commit:: @code{mysql_commit()}
+* mysql_rollback:: @code{mysql_rollback()}
+* mysql_autocommit:: @code{mysql_autocommit()}
+* mysql_more_results:: @code{mysql_more_results()}
+* mysql_next_result:: @code{mysql_next_result()}
@end menu
@node mysql_prepare, mysql_param_count, C Prepared statement functions, C Prepared statement functions
@@ -488,6 +520,18 @@ occured.
@subsubheading Errors
+@item CR_COMMANDS_OUT_OF_SYNC
+Commands were executed in an improper order
+@item CR_OUT_OF_MEMORY
+Out of memory
+@item CR_SERVER_GONE_ERROR
+The MySQL server has gone away
+@item CR_SERVER_LOST
+The connection to the server was lost during the query
+@item CR_UNKNOWN_ERROR
+An unkown error occured
+@end table
+
If the prepare is not successful, i.e. when @code{mysql_prepare()} returned a
NULL statement, errors can be obtained by calling @code{mysql_error()}.
@@ -573,6 +617,11 @@ the prepared query.
@subsubheading Errors
+@item CR_OUT_OF_MEMOR
+Out of memory
+@item CR_UNKNOWN_ERROR
+An unknown error occured
+
None
@@ -611,6 +660,14 @@ MYSQL_TYPE_LONGLONG
MYSQL_TYPE_FLOAT
@item
MYSQL_TYPE_DOUBLE
+@item
+MYSQL_TYPE_TIME
+@item
+MYSQL_TYPE_DATE
+@item
+MYSQL_TYPE_DATETIME
+@item
+MYSQL_TYPE_TIMESTAMP
@item
MYSQL_TYPE_STRING
@item
@@ -639,6 +696,10 @@ buffer type is non string or binary
@item CR_UNSUPPORTED_PARAM_TYPE
The conversion is not supported, possibly the buffer_type is illegal or
its not from the above list of supported types.
+@item CR_OUT_OF_MEMOR
+Out of memory
+@item CR_UNKNOWN_ERROR
+An unknown error occured
@end table
@subsubheading Example
@@ -677,12 +738,10 @@ how to fetch the statement binary data, refer to @ref{mysql_fetch}.
@code{mysql_execute()} returns the following return values:
@multitable @columnfractions .30 .65
-@item @strong{Return Value} @tab @strong{Description}
-@item MYSQL_SUCCESS, 0 @tab Successful
-@item MYSQL_STATUS_ERROR, 1 @tab Error occured. Error code and
+@item @strong{Return Value} @tab @strong{Description}
+@item 0 @tab Successful
+@item 1 @tab Error occured. Error code and
message can be obtained by calling @code{mysql_stmt_errno()} and @code{mysql_stmt_error()}.
-@item MYSQL_NEED_DATA, 99 @tab One of the parameter buffer is
-indicating the data suppy in chunks, and the supply is not yet complete.
@end multitable
@@ -693,10 +752,16 @@ indicating the data suppy in chunks, and the supply is not yet complete.
No query prepared prior to execution
@item CR_ALL_PARAMS_NOT_BOUND
Not all parameters data is supplied
-@item CR_SERVER_GONE_ERROR
-The MySQL server has gone away
-@item CR_UNKNOWN_ERROR
-An unkown error occured
+@item CR_COMMANDS_OUT_OF_SYNC
+Commands were executed in an improper order.
+@item CR_OUT_OF_MEMORY
+Out of memory.
+@item CR_SERVER_GONE_ERROR
+The MySQL server has gone away.
+@item CR_SERVER_LOST
+The connection to the server was lost during the query.
+@item CR_UNKNOWN_ERROR
+An unknown error occurred.
@end table
@@ -714,7 +779,9 @@ ulonglong affected_rows;
long length;
unsigned int param_count;
int int_data;
+short small_data;
char str_data[50], query[255];
+my_bool is_null;
/* Set autocommit mode to true */
mysql_autocommit(mysql, 1);
@@ -735,8 +802,8 @@ char str_data[50], query[255];
@}
/* Prepare a insert query with 3 parameters */
- strcpy(query, "INSERT INTO test_table(col1,col2,col3) values(?,?,?)");
- if(!(stmt = mysql_prepare(mysql,query,strlen(query))))
+ strmov(query, "INSERT INTO test_table(col1,col2,col3) values(?,?,?)");
+ if(!(stmt = mysql_prepare(mysql, query, strlen(query))))
@{
fprintf(stderr, "\n prepare, insert failed");
fprintf(stderr, "\n %s", mysql_error(mysql));
@@ -757,19 +824,25 @@ char str_data[50], query[255];
/* Bind the data for the parameters */
/* INTEGER PART */
- memset(bind,0,sizeof(bind));
bind[0].buffer_type= MYSQL_TYPE_LONG;
- bind[0].buffer= (void *)&int_data;
-
+ bind[0].buffer= (char *)&int_data;
+ bind[0].is_null= 0;
+ bind[0].length= 0;
+
/* STRING PART */
bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
- bind[1].buffer= (void *)str_data;
+ bind[1].buffer= (char *)str_data;
bind[1].buffer_length= sizeof(str_data);
-
+ bind[1].is_null= 0;
+ bind[1].length= 0;
+
/* SMALLINT PART */
bind[2].buffer_type= MYSQL_TYPE_SHORT;
- bind[2].buffer= (void *)&small_data;
- bind[2].length= (long *)&length;
+ bind[2].buffer= (char *)&small_data;
+ bind[2].is_null= &is_null;
+ bind[2].length= 0;
+ is_null= 0;
+
/* Bind the buffers */
if (mysql_bind_param(stmt, bind))
@@ -782,8 +855,9 @@ char str_data[50], query[255];
/* Specify the data */
int_data= 10; /* integer */
strcpy(str_data,"MySQL"); /* string */
+
/* INSERT SMALLINT data as NULL */
- length= MYSQL_NULL_DATA;
+ is_null= 1;
/* Execute the insert statement - 1*/
if (mysql_execute(stmt))
@@ -808,8 +882,8 @@ char str_data[50], query[255];
int_data= 1000;
strcpy(str_data,"The most popular open source database");
small_data= 1000; /* smallint */
- length= 0;
-
+ is_null= 0; /* reset NULL */
+
/* Execute the insert statement - 2*/
if (mysql_execute(stmt))
@{
@@ -843,7 +917,7 @@ char str_data[50], query[255];
fprintf(stderr, "\n %s", mysql_error(mysql));
exit(0);
@}
- fprintf(stdout, "Success, MySQL prepared statements are working great !!!");
+ fprintf(stdout, "Success, MySQL prepared statements are working!!!");
@end example
@@ -885,7 +959,7 @@ from @ref{mysql_execute,mysql_execute()}.
-@node mysql_bind_result, mysql_fetch, mysql_stmt_affected_rows, C Prepared statement functions
+@node mysql_bind_result, mysql_stmt_store_result, mysql_stmt_affected_rows, C Prepared statement functions
@subsubsection @code{mysql_bind_result()}
@findex @code{mysql_bind_result()}
@@ -894,7 +968,7 @@ from @ref{mysql_execute,mysql_execute()}.
@subsubheading Description
-@code{mysql_bind_result()} is ised to associate, or bind, columns in the
+@code{mysql_bind_result()} is used to associate, or bind, columns in the
resultset to data buffers and length buffers. When @code{mysql_fetch()} is
called to fetch data, the MySQL client protocol returns the data for the
bound columns in the specified buffers.
@@ -937,6 +1011,14 @@ MYSQL_TYPE_LONGLONG
MYSQL_TYPE_FLOAT
@item
MYSQL_TYPE_DOUBLE
+@item
+MYSQL_TYPE_TIME
+@item
+MYSQL_TYPE_DATE
+@item
+MYSQL_TYPE_DATETIME
+@item
+MYSQL_TYPE_TIMESTAMP
@item
MYSQL_TYPE_STRING
@item
@@ -956,12 +1038,17 @@ MYSQL_TYPE_LONG_BLOB
Zero if the bind was successful. Non-zero if an error occured.
@subsubheading Errors
+
@table @code
@item CR_NO_PREPARE_STMT
No prepared statement exists
@item CR_UNSUPPORTED_PARAM_TYPE
The conversion is not supported, possibly the buffer_type is illegal or
its not from the list of supported types.
+@item CR_OUT_OF_MEMOR
+Out of memory
+@item CR_UNKNOWN_ERROR
+An unknown error occured
@end table
@subsubheading Example
@@ -971,7 +1058,53 @@ For the usage of @code{mysql_bind_result()} refer to the Example from
-@node mysql_fetch, mysql_send_long_data, mysql_bind_result, C Prepared statement functions
+
+@node mysql_stmt_store_result, mysql_fetch, mysql_bind_result, C Prepared statement functions
+@subsubsection @code{mysql_stmt_store_result()}
+
+@findex code{mysql_stmt_store_result()}
+
+@code{int mysql_stmt_store_result(MYSQL_STMT *stmt)}
+
+@subsubheading Description
+
+You must call @code{mysql_stmt_store_result()} for every query that
+successfully retrieves
+data(@code{SELECT},@code{SHOW},@code{DESCRIBE},@code{EXPLAIN}), and only
+if you want to buffer the complete result set by the client, so that the
+subsequent @code{mysql_fetch()} call returns buffered data.
+
+@sp 1
+
+You don't have to call @code{mysql_stmt_store_result()} for other
+queries, but it will not harm or cause any notable performance in all
+cases.You can detect if the query didn't have a result set by checking
+if @code{mysql_prepare_result()} returns 0. For more information refer
+to @ref{mysql_prepare_result}.
+
+@subsubheading Return Values
+
+@code{Zero} if the results are buffered successfully or @code{Non Zero} in case of an error.
+
+
+@subsubheading Errors
+
+@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Commands were executed in an improper order.
+@item CR_OUT_OF_MEMORY
+Out of memory.
+@item CR_SERVER_GONE_ERROR
+The MySQL server has gone away.
+@item CR_SERVER_LOST
+The connection to the server was lost during the query.
+@item CR_UNKNOWN_ERROR
+An unknown error occurred.
+@end table
+
+
+
+@node mysql_fetch, mysql_send_long_data, mysql_stmt_store_result, C Prepared statement functions
@subsubsection @code{mysql_fetch()}
@findex code{mysql_fetch()}
@@ -982,7 +1115,9 @@ For the usage of @code{mysql_bind_result()} refer to the Example from
@code{mysql_fetch()} returns the next rowset in the result set. It can
be called only while the result set exists i.e. after a call to
-@code{mysql_execute()} that creates a result set.
+@code{mysql_execute()} that creates a result set or after
+@code{mysql_stmt_store_result()}, which is called after
+@code{mysql_execute()} to buffer the entire resultset.
@sp 1
@@ -994,11 +1129,12 @@ set and the lengths are returned to the length pointer.
Note that, all columns must be bound by the application.
@sp 1
-If the data fetched is a NULL data, then the length buffer will have a
-value of @strong{MYSQL_NULL_DATA}, -1, else it will have the length of
-the data being fetched based on the buffer type specified by the
-application. All numeric, float and double types have the
-fixed length(in bytes) as listed below:
+If the data fetched is a NULL data, then the @code{is_null} value from
+@code{MYSQL_BIND} contains TRUE, 1, else the data and its length is
+returned to @code{*buffer} and @code{*length} variables based on the
+buffer type specified by the application. All numeric, float and double
+types have the fixed length(in bytes) as listed below:
+
@multitable @columnfractions .10 .30
@item @strong{Type} @tab @strong{Length}
@@ -1008,6 +1144,10 @@ fixed length(in bytes) as listed below:
@item MYSQL_TYPE_FLOAT @tab 4
@item MYSQL_TYPE_LONGLONG @tab 8
@item MYSQL_TYPE_DOUBLE @tab 8
+@item MYSQL_TYPE_TIME @tab sizeof(MYSQL_TIME)
+@item MYSQL_TYPE_DATE @tab sizeof(MYSQL_TIME)
+@item MYSQL_TYPE_DATETIME @tab sizeof(MYSQL_TIME)
+@item MYSQL_TYPE_TIMESTAMP @tab sizeof(MYSQL_TIME)
@item MYSQL_TYPE_STRING @tab data length
@item MYSQL_TYPE_VAR_STRING @tab data_length
@item MYSQL_TYPE_BLOB @tab data_length
@@ -1023,21 +1163,31 @@ where @code{*data_length} is nothing but the 'Actual length of the data'.
@multitable @columnfractions .30 .65
@item @strong{Return Value} @tab @strong{Description}
-@item MYSQL_SUCCESS, 0 @tab Successful, the data has been
+@item 0 @tab Successful, the data has been
fetched to application data buffers.
-@item MYSQL_STATUS_ERROR, 1 @tab Error occured. Error code and
+@item 1 @tab Error occured. Error code and
message can be obtained by calling @code{mysql_stmt_errno()} and @code{mysql_stmt_error()}.
-@item MYSQL_NO_DATA, 100 @tab No more rows/data exists
+@item 100, MYSQL_NO_DATA @tab No more rows/data exists
@end multitable
@subsubheading Errors
@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Commands were executed in an improper order.
+@item CR_OUT_OF_MEMORY
+Out of memory.
+@item CR_SERVER_GONE_ERROR
+The MySQL server has gone away.
+@item CR_SERVER_LOST
+The connection to the server was lost during the query.
+@item CR_UNKNOWN_ERROR
+An unknown error occurred.
@item CR_UNSUPPORTED_PARAM_TYPE
-If the field type is DATE,DATETIME,TIME,or TIMESTAMP; and the
-application buffer type is non string based.
+If the buffer type is MYSQL_TYPE_DATE,DATETIME,TIME,or TIMESTAMP; and if
+the field type is not DATE, TIME, DATETIME or TIMESTAMP.
@item
-All other un-supported conversions are returned from
+All other unsupported conversion errors are returned from
@code{mysql_bind_result()}.
@end table
@@ -1054,6 +1204,7 @@ MYSQL_RES *result;
int int_data;
long int_length, str_length;
char str_data[50];
+my_bool is_null[2];
query= "SELECT col1, col2 FROM test_table WHERE col1= 10)");
if (!(stmt= mysql_prepare(&mysql, query, strlen(query)))
@@ -1082,19 +1233,20 @@ char str_data[50];
/* Execute the SELECT query */
if (mysql_execute(stmt))
@{
- fprintf(stderr, "\n execute didn't retuned expected return code, MYSQL_NEED_DATA");
+ fprintf(stderr, "\n execute failed");
+ fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
exit(0);
@}
/* Bind the result data buffers */
- bzero(bind, 0, sizeof(bind));
-
bind[0].buffer_type= MYSQL_TYPE_LONG;
- bind[0].buffer= (void *)&int_data;
+ bind[0].buffer= (char *)&int_data;
+ bind[0].is_null= &is_null[0];
bind[0].length= &int_length;
bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
bind[1].buffer= (void *)str_data;
+ bind[1].is_null= &is_null[1];
bind[1].length= &str_length;
if (mysql_bind_result(stmt, bind))
@@ -1111,9 +1263,17 @@ char str_data[50];
fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
exit(0);
@}
+
+ if (is_null[0])
+ fprintf(stdout, "\n Col1 data is NULL");
+ else
+ fprintf(stdout, "\n Col1: %d, length: %ld", int_data, int_length);
- fprintf(stdout, "\n int_data: %d, length: %ld", int_data, int_length);
- fprintf(stdout, "\n str_data: %s, length: %ld", str_data, str_length);
+ if (is_null[1])
+ fprintf(stdout, "\n Col2 data is NULL");
+ else
+ fprintf(stdout, "\n Col2: %s, length: %ld", str_data, str_length);
+
/* call mysql_fetch again */
if (mysql_fetch(stmt) |= MYSQL_NO_DATA)
@@ -1122,7 +1282,7 @@ char str_data[50];
exit(0);
@}
- /* Free the prepare result */
+ /* Free the prepare result meta information */
mysql_free_result(result);
/* Free the statement handle */
@@ -1144,7 +1304,7 @@ char str_data[50];
@findex @code{mysql_send_long_data()}.
@code{int mysql_send_long_data(MYSQL_STMT *stmt, unsigned int
-parameter_number, const char *data, ulong length, my_bool is_last_data)}
+parameter_number, const char *data, ulong length)}
@subsubheading Description
@@ -1156,13 +1316,7 @@ binary data type.
@sp 1
The @code{data} is a pointer to buffer containing the actual data for
the parameter represendted by @code{parameter_number}. The @code{length}
-indicates the amount of data to be sent in bytes, and @code{is_last_data} is a
-boolean flag to indicate the end of the data. If it is != 0, then the
-current call will be the end of the data, else it waits for the
-application to send all data. If the application doesn't ended the data
-supply from @code{mysql_send_long_data()}, then the
-@code{mysql_execute()} will return @strong{MYSQL_NEED_DATA}.
-
+indicates the amount of data to be sent in bytes.
@subsubheading Return Values
@@ -1176,10 +1330,14 @@ occured.
@table @code
@item CR_INVALID_PARAMETER_NO
Invalid parameter number
+@item CR_COMMANDS_OUT_OF_SYNC
+Commands were executed in an improper order.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away
+@item CR_OUT_OF_MEMOR
+Out of memory
@item CR_UNKNOWN_ERROR
-An unkown error occured
+An unknown error occured
@end table
@subsubheading Example
@@ -1200,9 +1358,7 @@ long length;
memset(bind, 0, sizeof(bind));
bind[0].buffer_type= MYSQL_TYPE_STRING;
bind[0].length= &length;
-
- /* Indicate that the data supply is in CHUNKS */
- length= MYSQL_LONG_DATA;
+ bind[0].is_null= 0;
/* Bind the buffers */
if (mysql_bind_param(stmt, bind))
@@ -1212,22 +1368,16 @@ long length;
exit(0);
@}
- /* Execute the insert statement - It should return MYSQL_NEED_DATA */
- if (mysql_execute(stmt) != MYSQL_NEED_DATA)
- @{
- fprintf(stderr, "\n execute didn't retuned expected return code, MYSQL_NEED_DATA");
- exit(0);
- @}
-
/* Supply data in chunks to server */
- if (!mysql_send_long_data(stmt,1,"MySQL",5,0))
+ if (!mysql_send_long_data(stmt,1,"MySQL",5))
@{
fprintf(stderr, "\n send_long_data failed");
fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
exit(0);
@}
- /* Supply the last piece of data */
- if (mysql_send_long_data(stmt,1," - The most popular open source database",40,1))
+
+ /* Supply the next piece of data */
+ if (mysql_send_long_data(stmt,1," - The most popular open source database",40))
@{
fprintf(stderr, "\n send_long_data failed");
fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
@@ -1258,7 +1408,10 @@ long length;
@subsubheading Description
Closes the prepared statement. @code{mysql_stmt_close()} also
-deallocates the statement handle pointed to by @code{stmt}.
+deallocates the statement handle pointed to by @code{stmt}.
+
+If the current query results are pending or un-read; this cancels the
+query results; so that next call can be executed.
@subsubheading Return Values
@@ -1398,7 +1551,7 @@ None.
-@node mysql_autocommit, , mysql_rollback, C Prepared statement functions
+@node mysql_autocommit, mysql_more_results, mysql_rollback, C Prepared statement functions
@subsubsection @code{mysql_autocommit()}
@@ -1418,5 +1571,166 @@ Zero if successful. Non-zero if an error occured
@subsubheading Errors
None.
+
+
+@node mysql_more_results, mysql_next_result, mysql_autocommit, C Prepared statement functions
+@subsubsection @code{mysql_more_results()}
+
+
+@findex @code{mysql_more_results()}.
+
+@code{my_bool mysql_more_results(MYSQL *mysql)}
+
+@subsubheading Description
+
+Returns true if more results exists from the currently executed query,
+and the application must call @code{mysql_next_result()} to fetch the
+results.
+
+
+@subsubheading Return Values
+
+@code{TRUE} if more results exists. @code{FALSE} if no more results exists.
+
+@subsubheading Errors
+
+None.
+
+
+@node mysql_next_result, , mysql_more_results, C Prepared statement functions
+@subsubsection @code{mysql_next_result()}
+
+
+@findex @code{mysql_next_result()}.
+
+@code{int mysql_next_result(MYSQL *mysql)}
+
+@subsubheading Description
+
+If more query results exists, then @code{mysql_next_result()} reads the
+next query results and returns the status back to application.
+
+@subsubheading Return Values
+
+Zero if successful. Non-zero if an error occured
+
+@subsubheading Errors
+
+None.
+
+
+
+@node multiple queries, date handling, C Prepared statement functions, MySQL prepared statements
+@subsection Handling multiple query executions
+
+
+From version 4.1 and above, MySQL supports the multi query execution
+using the single command. In order to do this, you must set the client flag
+@code{CLIENT_MULTI_QUERIES} option during the connection.
+
+@sp 1
+
+By default @code{mysql_query()} or @code{mysql_real_query()} returns
+only the first query status and the subsequent queries status can
+be processed using @code{mysql_more_results()} and
+@code{mysql_next_result()}.
+
+
+@example
+
+ /* Connect to server with option CLIENT_MULTI_QUERIES */
+ mysql_real_query(..., CLIENT_MULTI_QUERIES);
+
+ /* Now execute multiple queries */
+ mysql_query(mysql,"DROP TABLE IF EXISTS test_table;\
+ CREATE TABLE test_table(id int);\
+ INSERT INTO test_table VALUES(10);\
+ UPDATE test_table SET id=20 WHERE id=10;\
+ SELECT * FROM test_table;\
+ DROP TABLE test_table";
+ while (mysql_more_results(mysql))
+ {
+ /* Process all results */
+ mysql_next_result(mysql);
+ ...
+ printf("total affected rows: %lld", mysql_affected_rows(mysql));
+ ...
+ if ((result= mysql_store_result(mysql))
+ {
+ /* Returned a result set, process it */
+ }
+ }
+
+@end example
+
+
+
+@node date handling, , multiple queries, MySQL prepared statements
+@subsection Handling DATE, TIME and TIMESTAMP
+
+Using the new binary protocol from MySQL 4.1 and above, one can send and
+receive the DATE, TIME and TIMESTAMP data using the @code{MYSQL_TIME}
+structure.
+
+@code{MYSQL_TIME} structure consites of the following members:
+
+@itemize @bullet
+@item year
+@item month
+@item day
+@item hour
+@item minute
+@item second
+@item second_part
+@end itemize
+
+
+In order to send the data, one must use the prepared statements through
+@code{mysql_prepare()} and @code{mysql_execute()}; and must bind the
+parameter using type as @code{MYSQL_TYPE_DATE} inorder to process date
+value, @code{MYSQL_TYPE_TIME} for time and @code{MYSQL_TYPE_DATETIME} or
+@code{MYSQL_TYPE_TIMESTAMP} for datetime/timestamp using
+@code{mysql_bind_param()} when sending and @code{mysql_bind_results()}
+while receiving the data.
+
+@sp 1
+Here is a simple example; which inserts the DATE, TIME and TIMESTAMP data.
+
+@example
+
+MYSQL_TIME ts;
+MYSQL_BIND bind[3];
+MYSQL_STMT *stmt;
+
+ strmov(query, "INSERT INTO test_table(date_field, time_field,
+ timestamp_field) VALUES(?,?,?");
+
+ stmt= mysql_prepare(mysql, query, strlen(query)));
+
+ /* setup input buffers for all 3 parameters */
+ bind[0].buffer_type= MYSQL_TYPE_DATE;
+ bind[0].buffer= (char *)&ts;
+ bind[0].is_null= 0;
+ bind[0].length= 0;
+ ..
+ bind[1]= bind[2]= bind[0];
+ ..
+
+ mysql_bind_param(stmt, bind);
+
+ /* supply the data to be sent is the ts structure */
+ ts.year= 2002;
+ ts.month= 02;
+ ts.day= 03;
+
+ ts.hour= 10;
+ ts.minute= 45;
+ ts.second= 20;
+
+ mysql_execute(stmt);
+ ..
+
+@end example
+
@bye
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 53c97aff27b..fe435616532 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -2084,7 +2084,7 @@ Try also with PIPE or TCP/IP
}
sock_addr.sin_port = (ushort) htons((ushort) port);
if (my_connect(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr),
- mysql->options.connect_timeout) <0)
+ mysql->options.connect_timeout))
{
DBUG_PRINT("error",("Got error %d on connect to '%s'",socket_errno,host));
net->last_errno= CR_CONN_HOST_ERROR;
@@ -4043,6 +4043,7 @@ unsigned int alloc_stmt_fields(MYSQL_STMT *stmt)
field->org_table= strdup_root(alloc,fields->org_table);
field->name = strdup_root(alloc,fields->name);
field->org_name = strdup_root(alloc,fields->org_name);
+ field->charsetnr= fields->charsetnr;
field->length = fields->length;
field->type = fields->type;
field->flags = fields->flags;
@@ -4767,13 +4768,13 @@ static void send_data_long(MYSQL_BIND *param, longlong value)
*param->buffer= (uchar) value;
break;
case MYSQL_TYPE_SHORT:
- int2store(buffer, (short)value);
+ int2store(buffer, value);
break;
case MYSQL_TYPE_LONG:
- int4store(buffer, (int32)value);
+ int4store(buffer, value);
break;
case MYSQL_TYPE_LONGLONG:
- int8store(buffer, (longlong)value);
+ int8store(buffer, value);
break;
case MYSQL_TYPE_FLOAT:
{
@@ -4810,7 +4811,7 @@ static void send_data_double(MYSQL_BIND *param, double value)
int2store(buffer, (short)value);
break;
case MYSQL_TYPE_LONG:
- int4store(buffer, (int32)value);
+ int4store(buffer, (long)value);
break;
case MYSQL_TYPE_LONGLONG:
int8store(buffer, (longlong)value);
@@ -4947,30 +4948,37 @@ static void send_data_time(MYSQL_BIND *param, MYSQL_TIME ltime,
/* Fetch data to buffers */
-static void fetch_results(MYSQL_BIND *param, uint field_type, uchar **row)
+static void fetch_results(MYSQL_BIND *param, uint field_type, uchar **row,
+ my_bool field_is_unsigned)
{
ulong length;
switch (field_type) {
case MYSQL_TYPE_TINY:
{
- uchar value= (uchar) **row;
- send_data_long(param,(longlong)value);
+ char value= (char) **row;
+ longlong data= (field_is_unsigned) ? (longlong) (unsigned char) value:
+ (longlong) value;
+ send_data_long(param,data);
length= 1;
break;
}
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_YEAR:
{
- short value= (short)sint2korr(*row);
- send_data_long(param,(longlong)value);
- length= 2;
+ short value= sint2korr(*row);
+ longlong data= (field_is_unsigned) ? (longlong) (unsigned short) value:
+ (longlong) value;
+ send_data_long(param,data);
+ length= 2;
break;
}
case MYSQL_TYPE_LONG:
{
- int32 value= (int32)sint4korr(*row);
- send_data_long(param,(int32)value);
+ long value= sint4korr(*row);
+ longlong data= (field_is_unsigned) ? (longlong) (unsigned long) value:
+ (longlong) value;
+ send_data_long(param,data);
length= 4;
break;
}
@@ -4985,7 +4993,7 @@ static void fetch_results(MYSQL_BIND *param, uint field_type, uchar **row)
{
float value;
float4get(value,*row);
- send_data_double(param,(double)value);
+ send_data_double(param,value);
length= 4;
break;
}
@@ -4993,7 +5001,7 @@ static void fetch_results(MYSQL_BIND *param, uint field_type, uchar **row)
{
double value;
float8get(value,*row);
- send_data_double(param,(double)value);
+ send_data_double(param,value);
length= 8;
break;
}
@@ -5241,7 +5249,10 @@ static int stmt_fetch_row(MYSQL_STMT *stmt, uchar *row)
if (field->type == bind->buffer_type)
(*bind->fetch_result)(bind, &row);
else
- fetch_results(bind, field->type, &row);
+ {
+ my_bool field_is_unsigned= (field->flags & UNSIGNED_FLAG) ? 1: 0;
+ fetch_results(bind, field->type, &row, field_is_unsigned);
+ }
}
if (! ((bit<<=1) & 255))
{
diff --git a/myisam/rt_index.c b/myisam/rt_index.c
index d55d01fa4a3..ad0d593ee0a 100644
--- a/myisam/rt_index.c
+++ b/myisam/rt_index.c
@@ -503,7 +503,7 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key,
return res;
}
- switch ((res = rtree_insert_req(info, &keyinfo[keynr], key, key_length,
+ switch ((res = rtree_insert_req(info, keyinfo, key, key_length,
old_root, &new_page, ins_level, 0)))
{
case 0: /* root was not split */
diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
index 0e9f4de09fe..49c5b0f51b7 100644
--- a/scripts/mysqld_safe.sh
+++ b/scripts/mysqld_safe.sh
@@ -272,7 +272,6 @@ echo "Starting $MYSQLD daemon with databases from $DATADIR"
echo "`date +'%y%m%d %H:%M:%S mysqld started'`" >> $err_log
while true
do
- rm -f $MYSQL_UNIX_PORT $pid_file # Some extra safety
if test -z "$args"
then
$NOHUP_NICENESS $ledir/$MYSQLD $defaults --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR $USER_OPTION --pid-file=$pid_file @MYSQLD_DEFAULT_SWITCHES@ >> $err_log 2>&1
@@ -311,7 +310,7 @@ do
I=`expr $I + 1`
done
fi
-
+ rm -f $MYSQL_UNIX_PORT $pid_file # Some extra safety
echo "`date +'%y%m%d %H:%M:%S'` mysqld restarted" | tee -a $err_log
done
diff --git a/sql/field.cc b/sql/field.cc
index 3b3320bb2f4..697de878c03 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1913,7 +1913,7 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
char *end;
tmp= cs->scan(cs, from, from+len, MY_SEQ_SPACES);
- len-= tmp;
+ len-= (uint)tmp;
from+= tmp;
my_errno=0;
if (unsigned_flag)
diff --git a/sql/item_uniq.h b/sql/item_uniq.h
index ac004e747f8..5ffd10be7a5 100644
--- a/sql/item_uniq.h
+++ b/sql/item_uniq.h
@@ -50,7 +50,7 @@ public:
fixed= 1;
return 0;
}
- Item_sum *copy_or_same(THD* thd)
+ Item *copy_or_same(THD* thd)
{
return new Item_sum_unique_users(thd, *this);
}
diff --git a/sql/lex.h b/sql/lex.h
index 3fa7dd97250..d4ae8c32828 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -222,6 +222,7 @@ static SYMBOL symbols[] = {
{ "LEVEL", SYM(LEVEL_SYM),0,0},
{ "LIKE", SYM(LIKE),0,0},
{ "LINES", SYM(LINES),0,0},
+ { "LINESTRING", SYM(LINESTRING),0,0},
{ "LIMIT", SYM(LIMIT),0,0},
{ "LOAD", SYM(LOAD),0,0},
{ "LOCAL", SYM(LOCAL_SYM),0,0},
@@ -261,6 +262,9 @@ static SYMBOL symbols[] = {
{ "MODE", SYM(MODE_SYM),0,0},
{ "MODIFY", SYM(MODIFY_SYM),0,0},
{ "MONTH", SYM(MONTH_SYM),0,0},
+ { "MULTILINESTRING", SYM(MULTILINESTRING),0,0},
+ { "MULTIPOINT", SYM(MULTIPOINT),0,0},
+ { "MULTIPOLYGON", SYM(MULTIPOLYGON),0,0},
{ "MRG_MYISAM", SYM(MERGE_SYM),0,0},
{ "MYISAM", SYM(MYISAM_SYM),0,0},
{ "NATURAL", SYM(NATURAL),0,0},
@@ -286,6 +290,8 @@ static SYMBOL symbols[] = {
{ "PACK_KEYS", SYM(PACK_KEYS_SYM),0,0},
{ "PARTIAL", SYM(PARTIAL),0,0},
{ "PASSWORD", SYM(PASSWORD),0,0},
+ { "POINT", SYM(POINT),0,0},
+ { "POLYGON", SYM(POLYGON),0,0},
{ "PURGE", SYM(PURGE),0,0},
{ "PRECISION", SYM(PRECISION),0,0},
{ "PREV", SYM(PREV_SYM),0,0},
@@ -503,7 +509,7 @@ static SYMBOL sql_functions[] = {
{ "LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)},
{ "LN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ln)},
{ "LINEFROMTEXT", SYM(LINEFROMTEXT),0,0},
- { "LINESTRING", SYM(LINESTRING),0,0},
+ { "LINESTRINGFROMTEXT",SYM(LINEFROMTEXT),0,0},
{ "LOAD_FILE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_load_file)},
{ "LOCATE", SYM(LOCATE),0,0},
{ "LOG", SYM(LOG_SYM),0,0},
@@ -521,14 +527,13 @@ static SYMBOL sql_functions[] = {
{ "MLINEFROMTEXT", SYM(MLINEFROMTEXT),0,0},
{ "MPOINTFROMTEXT", SYM(MPOINTFROMTEXT),0,0},
{ "MPOLYFROMTEXT", SYM(MPOLYFROMTEXT),0,0},
- { "MULTILINESTRING", SYM(MULTILINESTRING),0,0},
- { "MULTIPOINT", SYM(MULTIPOINT),0,0},
- { "MULTIPOLYGON", SYM(MULTIPOLYGON),0,0},
{ "MONTHNAME", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_monthname)},
+ { "MULTILINESTRINGFROMTEXT",SYM(MLINEFROMTEXT),0,0},
+ { "MULTIPOLYGONFROMTEXT",SYM(MPOLYFROMTEXT),0,0},
{ "NOW", SYM(NOW_SYM),0,0},
{ "NULLIF", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_nullif)},
{ "NUMGEOMETRIES", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_numgeometries)},
- { "NUMINTERIORRING", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_numinteriorring)},
+ { "NUMINTERIORRINGS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_numinteriorring)},
{ "NUMPOINTS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_numpoints)},
{ "OCTET_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)},
{ "OCT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_oct)},
@@ -538,11 +543,10 @@ static SYMBOL sql_functions[] = {
{ "PERIOD_ADD", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_period_add)},
{ "PERIOD_DIFF", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_period_diff)},
{ "PI", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_pi)},
- { "POINT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_point)},
{ "POINTFROMTEXT", SYM(POINTFROMTEXT),0,0},
{ "POINTN", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pointn)},
{ "POLYFROMTEXT", SYM(POLYFROMTEXT),0,0},
- { "POLYGON", SYM(POLYGON),0,0},
+ { "POLYGONFROMTEXT", SYM(POLYFROMTEXT),0,0},
{ "POSITION", SYM(POSITION_SYM),0,0},
{ "POW", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)},
{ "POWER", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)},
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 1db2f5b9fb8..528bdb7b6f5 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -72,7 +72,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
TABLE_LIST *tables= (TABLE_LIST *)sl->table_list.first;
TMP_TABLE_PARAM tmp_table_param;
bool is_union= sl->next_select() && sl->next_select()->linkage == UNION_TYPE;
- bool is_subsel= sl->first_inner_unit();
+ bool is_subsel= sl->first_inner_unit() ? 1: 0;
SELECT_LEX_NODE *save_current_select= lex->current_select;
DBUG_ENTER("mysql_derived");
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index fdf8014f876..9b089fab107 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -486,6 +486,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token NOW_SYM
%token PASSWORD
%token POINTFROMTEXT
+%token POINT
%token POLYFROMTEXT
%token POLYGON
%token POSITION_SYM
@@ -1145,6 +1146,18 @@ type:
$$=FIELD_TYPE_BLOB; }
| GEOMETRY_SYM { Lex->charset=&my_charset_bin;
$$=FIELD_TYPE_GEOMETRY; }
+ | POINT { Lex->charset=&my_charset_bin;
+ $$=FIELD_TYPE_GEOMETRY; }
+ | MULTIPOINT { Lex->charset=&my_charset_bin;
+ $$=FIELD_TYPE_GEOMETRY; }
+ | LINESTRING { Lex->charset=&my_charset_bin;
+ $$=FIELD_TYPE_GEOMETRY; }
+ | MULTILINESTRING { Lex->charset=&my_charset_bin;
+ $$=FIELD_TYPE_GEOMETRY; }
+ | POLYGON { Lex->charset=&my_charset_bin;
+ $$=FIELD_TYPE_GEOMETRY; }
+ | MULTIPOLYGON { Lex->charset=&my_charset_bin;
+ $$=FIELD_TYPE_GEOMETRY; }
| MEDIUMBLOB { Lex->charset=&my_charset_bin;
$$=FIELD_TYPE_MEDIUM_BLOB; }
| LONGBLOB { Lex->charset=&my_charset_bin;
@@ -2299,6 +2312,8 @@ simple_expr:
{ $$= new Item_func_password($3); }
| PASSWORD '(' expr ',' expr ')'
{ $$= new Item_func_password($3,$5); }
+ | POINT '(' expr ',' expr ')'
+ { $$= new Item_func_point($3,$5); }
| POINTFROMTEXT '(' expr ')'
{ $$= new Item_func_geometry_from_text($3); }
| POINTFROMTEXT '(' expr ',' expr ')'
@@ -3966,6 +3981,7 @@ keyword:
| FIRST_SYM {}
| FIXED_SYM {}
| FLUSH_SYM {}
+ | GEOMETRY_SYM {}
| GRANTS {}
| GLOBAL_SYM {}
| HANDLER_SYM {}
@@ -3983,6 +3999,7 @@ keyword:
| IO_THREAD {}
| LAST_SYM {}
| LEVEL_SYM {}
+ | LINESTRING {}
| LOCAL_SYM {}
| LOCKS_SYM {}
| LOGS_SYM {}
@@ -4005,6 +4022,9 @@ keyword:
| MODIFY_SYM {}
| MODE_SYM {}
| MONTH_SYM {}
+ | MULTILINESTRING {}
+ | MULTIPOINT {}
+ | MULTIPOLYGON {}
| MYISAM_SYM {}
| NATIONAL_SYM {}
| NCHAR_SYM {}
@@ -4017,6 +4037,8 @@ keyword:
| PACK_KEYS_SYM {}
| PARTIAL {}
| PASSWORD {}
+ | POINT {}
+ | POLYGON {}
| PREV_SYM {}
| PROCESS {}
| PROCESSLIST_SYM {}
diff --git a/tests/client_test.c b/tests/client_test.c
index dc91bf2cbf1..0ba4b4e564c 100644
--- a/tests/client_test.c
+++ b/tests/client_test.c
@@ -34,6 +34,9 @@
#include <m_string.h>
#include <assert.h>
+
+#define MAX_TEST_QUERY_LENGTH 300 /* MAX QUERY BUFFER LENGTH */
+
/* set default options */
static char *opt_db=0;
static char *opt_user=0;
@@ -44,7 +47,7 @@ static unsigned int opt_port;
static my_bool tty_password=0;
static MYSQL *mysql=0;
-static char query[255];
+static char query[MAX_TEST_QUERY_LENGTH];
static char current_db[]= "client_test_db";
static unsigned int test_count= 0;
static unsigned int opt_count= 0;
@@ -77,7 +80,7 @@ static double total_time;
static void print_error(const char *msg)
{
- if (mysql)
+ if (mysql && mysql_errno(mysql))
{
if (mysql->server_version)
fprintf(stdout,"\n [MySQL-%s]",mysql->server_version);
@@ -90,7 +93,7 @@ static void print_error(const char *msg)
static void print_st_error(MYSQL_STMT *stmt, const char *msg)
{
- if (stmt)
+ if (stmt && mysql_stmt_errno(stmt))
{
if (stmt->mysql && stmt->mysql->server_version)
fprintf(stdout,"\n [MySQL-%s]",stmt->mysql->server_version);
@@ -98,7 +101,7 @@ static void print_st_error(MYSQL_STMT *stmt, const char *msg)
fprintf(stdout,"\n [MySQL]");
fprintf(stdout,"[%d] %s\n",mysql_stmt_errno(stmt),
- mysql_stmt_error(stmt));
+ mysql_stmt_error(stmt));
}
else if (msg) fprintf(stderr, " [MySQL] %s\n", msg);
}
@@ -147,48 +150,53 @@ myassert(stmt != 0); \
#define mystmt_init_r(stmt) \
{ \
+if (stmt == 0) \
+ myerror(NULL);\
myassert(stmt == 0);\
}
#define mytest(x) if (!x) {myerror(NULL);myassert(TRUE);}
#define mytest_r(x) if (x) {myerror(NULL);myassert(TRUE);}
-#define PREPARE(A,B) mysql_prepare(A,B,strlen(B))
-
/********************************************************
* connect to the server *
*********************************************************/
static void client_connect()
{
int rc;
- char buff[255];
myheader_r("client_connect");
- fprintf(stdout, "\n Establishig a connection ...");
+ fprintf(stdout, "\n Establishing a connection ...");
+
if (!(mysql = mysql_init(NULL)))
{
myerror("mysql_init() failed");
exit(0);
}
+
if (!(mysql_real_connect(mysql,opt_host,opt_user,
- opt_password, opt_db ? opt_db:"test", opt_port,
- opt_unix_socket, 0)))
+ opt_password, opt_db ? opt_db:"test", opt_port,
+ opt_unix_socket, 0)))
{
myerror("connection failed");
mysql_close(mysql);
fprintf(stdout,"\n Check the connection options using --help or -?\n");
exit(0);
}
+
fprintf(stdout," OK");
/* set AUTOCOMMIT to ON*/
mysql_autocommit(mysql, TRUE);
+
fprintf(stdout, "\n Creating a test database '%s' ...", current_db);
- strxmov(buff,"CREATE DATABASE IF NOT EXISTS ", current_db, NullS);
- rc = mysql_query(mysql, buff);
+ strxmov(query,"CREATE DATABASE IF NOT EXISTS ", current_db, NullS);
+
+ rc = mysql_query(mysql, query);
myquery(rc);
- strxmov(buff,"USE ", current_db, NullS);
- rc = mysql_query(mysql, buff);
+
+ strxmov(query,"USE ", current_db, NullS);
+ rc = mysql_query(mysql, query);
myquery(rc);
fprintf(stdout," OK");
@@ -203,11 +211,12 @@ static void client_disconnect()
if (mysql)
{
- char buff[255];
fprintf(stdout, "\n droping the test database '%s' ...", current_db);
- strxmov(buff,"DROP DATABASE IF EXISTS ", current_db, NullS);
- mysql_query(mysql, buff);
+ strxmov(query,"DROP DATABASE IF EXISTS ", current_db, NullS);
+
+ mysql_query(mysql, query);
fprintf(stdout, " OK");
+
fprintf(stdout, "\n closing the connection ...");
mysql_close(mysql);
fprintf(stdout, " OK\n");
@@ -350,7 +359,8 @@ int my_process_result_set(MYSQL_RES *result)
fputc('\n',stdout);
row_count++;
}
- my_print_dashes(result);
+ if (row_count)
+ my_print_dashes(result);
if (mysql_errno(mysql) != 0)
fprintf(stderr, "\n\tmysql_fetch_row() failed\n");
@@ -363,35 +373,37 @@ int my_process_result_set(MYSQL_RES *result)
/********************************************************
* process the stmt result set *
*********************************************************/
+#define MAX_RES_FIELDS 50
+#define MAX_FIELD_DATA_SIZE 255
+
uint my_process_stmt_result(MYSQL_STMT *stmt)
{
int field_count;
uint row_count= 0;
- MYSQL_BIND buffer[50];
+ MYSQL_BIND buffer[MAX_RES_FIELDS];
MYSQL_FIELD *field;
MYSQL_RES *result;
- char data[50][255];
- ulong length[50];
- my_bool is_null[50];
+ char data[MAX_RES_FIELDS][MAX_FIELD_DATA_SIZE];
+ ulong length[MAX_RES_FIELDS];
+ my_bool is_null[MAX_RES_FIELDS];
int rc, i;
- if (!(result= mysql_prepare_result(stmt)))
+ if (!(result= mysql_prepare_result(stmt))) /* No meta info */
{
while (!mysql_fetch(stmt))
row_count++;
return row_count;
}
- field_count= mysql_num_fields(result);
+ field_count= min(mysql_num_fields(result), MAX_RES_FIELDS);
for(i=0; i < field_count; i++)
{
buffer[i].buffer_type= MYSQL_TYPE_STRING;
- buffer[i].buffer_length=50;
- buffer[i].length=&length[i];
- buffer[i].buffer=(char*) data[i];
+ buffer[i].buffer_length= MAX_FIELD_DATA_SIZE;
+ buffer[i].length= &length[i];
+ buffer[i].buffer= (char*) data[i];
buffer[i].is_null= &is_null[i];
}
-
my_print_result_metadata(result);
rc= mysql_bind_result(stmt,buffer);
@@ -426,7 +438,9 @@ uint my_process_stmt_result(MYSQL_STMT *stmt)
fputc('\n',stdout);
row_count++;
}
- my_print_dashes(result);
+ if (row_count)
+ my_print_dashes(result);
+
fprintf(stdout,"\n\t%d %s returned\n", row_count,
row_count == 1 ? "row" : "rows");
mysql_free_result(result);
@@ -436,14 +450,14 @@ uint my_process_stmt_result(MYSQL_STMT *stmt)
/********************************************************
* process the stmt result set *
*********************************************************/
-uint my_stmt_result(const char *query, unsigned long length)
+uint my_stmt_result(const char *buff, unsigned long length)
{
MYSQL_STMT *stmt;
uint row_count;
int rc;
- fprintf(stdout,"\n\n %s", query);
- stmt= mysql_prepare(mysql,query,length);
+ fprintf(stdout,"\n\n %s", buff);
+ stmt= mysql_prepare(mysql,buff,length);
mystmt_init(stmt);
rc = mysql_execute(stmt);
@@ -463,7 +477,6 @@ static void verify_col_data(const char *table, const char *col,
{
MYSQL_RES *result;
MYSQL_ROW row;
- char query[255];
int rc, field= 1;
if (table && col)
@@ -528,11 +541,44 @@ static void verify_prepare_field(MYSQL_RES *result,
static void verify_param_count(MYSQL_STMT *stmt, long exp_count)
{
long param_count= mysql_param_count(stmt);
- fprintf(stdout,"\n total parameters in stmt: %ld (expected: %ld)",
+ fprintf(stdout,"\n total parameters in stmt: `%ld` (expected: `%ld`)",
param_count, exp_count);
myassert(param_count == exp_count);
}
+/*
+ Utility function to verify the total affected rows
+*/
+static void verify_st_affected_rows(MYSQL_STMT *stmt, ulonglong exp_count)
+{
+ ulonglong affected_rows= mysql_stmt_affected_rows(stmt);
+ fprintf(stdout,"\n total affected rows: `%lld` (expected: `%lld`)",
+ affected_rows, exp_count);
+ myassert(affected_rows == exp_count);
+}
+
+/*
+ Utility function to verify the total affected rows
+*/
+static void verify_affected_rows(ulonglong exp_count)
+{
+ ulonglong affected_rows= mysql_affected_rows(mysql);
+ fprintf(stdout,"\n total affected rows: `%lld` (expected: `%lld`)",
+ affected_rows, exp_count);
+ myassert(affected_rows == exp_count);
+}
+
+/*
+ Utility function to verify the total fields count
+*/
+static void verify_field_count(MYSQL_RES *result, uint exp_count)
+{
+ uint field_count= mysql_num_fields(result);
+ fprintf(stdout,"\n total fields in the result set: `%d` (expected: `%d`)",
+ field_count, exp_count);
+ myassert(field_count == exp_count);
+}
+
/********************************************************
* store result processing *
@@ -683,7 +729,7 @@ static void test_tran_bdb()
rc = mysql_commit(mysql);
myquery(rc);
- /* now insert the second row, and rollback the transaction */
+ /* now insert the second row, and rollback the transaction */
rc = mysql_query(mysql,"INSERT INTO my_demo_transaction VALUES(20,'mysql')");
myquery(rc);
@@ -761,7 +807,7 @@ static void test_tran_innodb()
rc = mysql_commit(mysql);
myquery(rc);
- /* now insert the second row, and rollback the transaction */
+ /* now insert the second row, and rollback the transaction */
rc = mysql_query(mysql,"INSERT INTO my_demo_transaction VALUES(20,'mysql')");
myquery(rc);
@@ -826,32 +872,32 @@ static void test_prepare_simple()
myquery(rc);
/* alter table */
- strcpy(query,"ALTER TABLE test_prepare_simple ADD new char(20)");
- stmt = mysql_prepare(mysql, query, strlen(query));
+ strmov(query,"ALTER TABLE test_prepare_simple ADD new char(20)");
+ stmt = mysql_prepare(mysql, query, 70);
mystmt_init(stmt);
verify_param_count(stmt,0);
mysql_stmt_close(stmt);
/* insert */
- strcpy(query,"INSERT INTO test_prepare_simple VALUES(?,?)");
- stmt = mysql_prepare(mysql, query, strlen(query));
+ strmov(query,"INSERT INTO test_prepare_simple VALUES(?,?)");
+ stmt = mysql_prepare(mysql, query, 70);
mystmt_init(stmt);
verify_param_count(stmt,2);
mysql_stmt_close(stmt);
/* update */
- strcpy(query,"UPDATE test_prepare_simple SET id=? WHERE id=? AND name= ?");
- stmt = mysql_prepare(mysql, query, strlen(query));
+ strmov(query,"UPDATE test_prepare_simple SET id=? WHERE id=? AND name= ?");
+ stmt = mysql_prepare(mysql, query, 100);
mystmt_init(stmt);
verify_param_count(stmt,3);
mysql_stmt_close(stmt);
/* delete */
- strcpy(query,"DELETE FROM test_prepare_simple WHERE id=10");
- stmt = mysql_prepare(mysql, query, strlen(query));
+ strmov(query,"DELETE FROM test_prepare_simple WHERE id=10");
+ stmt = mysql_prepare(mysql, query, 60);
mystmt_init(stmt);
verify_param_count(stmt,0);
@@ -861,8 +907,8 @@ static void test_prepare_simple()
mysql_stmt_close(stmt);
/* delete */
- strcpy(query,"DELETE FROM test_prepare_simple WHERE id=?");
- stmt = mysql_prepare(mysql, query, strlen(query));
+ strmov(query,"DELETE FROM test_prepare_simple WHERE id=?");
+ stmt = mysql_prepare(mysql, query, 50);
mystmt_init(stmt);
verify_param_count(stmt,1);
@@ -872,8 +918,8 @@ static void test_prepare_simple()
mysql_stmt_close(stmt);
/* select */
- strcpy(query,"SELECT * FROM test_prepare_simple WHERE id=? AND name= ?");
- stmt = mysql_prepare(mysql, query, strlen(query));
+ strmov(query,"SELECT * FROM test_prepare_simple WHERE id=? AND name= ?");
+ stmt = mysql_prepare(mysql, query, 100);
mystmt_init(stmt);
verify_param_count(stmt,2);
@@ -893,7 +939,7 @@ static void test_prepare_field_result()
{
MYSQL_STMT *stmt;
MYSQL_RES *result;
- int rc,param_count;
+ int rc;
myheader("test_prepare_field_result");
@@ -909,7 +955,7 @@ static void test_prepare_field_result()
myquery(rc);
/* insert */
- strcpy(query,"SELECT int_c,var_c,date_c as date,ts_c,char_c FROM \
+ strmov(query,"SELECT int_c,var_c,date_c as date,ts_c,char_c FROM \
test_prepare_field_result as t1 WHERE int_c=?");
stmt = mysql_prepare(mysql, query, strlen(query));
mystmt_init(stmt);
@@ -933,9 +979,7 @@ static void test_prepare_field_result()
verify_prepare_field(result,4,"char_c","char_c",MYSQL_TYPE_STRING,
"t1","test_prepare_field_result",current_db);
- param_count= mysql_num_fields(result);
- fprintf(stdout,"\n\n total fields: `%d` (expected: `5`)", param_count);
- myassert(param_count == 5);
+ verify_field_count(result, 5);
mysql_free_result(result);
mysql_stmt_close(stmt);
}
@@ -960,11 +1004,11 @@ static void test_prepare_syntax()
rc = mysql_query(mysql,"CREATE TABLE test_prepare_syntax(id int, name varchar(50), extra int)");
myquery(rc);
- strcpy(query,"INSERT INTO test_prepare_syntax VALUES(?");
+ strmov(query,"INSERT INTO test_prepare_syntax VALUES(?");
stmt = mysql_prepare(mysql, query, strlen(query));
mystmt_init_r(stmt);
- strcpy(query,"SELECT id,name FROM test_prepare_syntax WHERE id=? AND WHERE");
+ strmov(query,"SELECT id,name FROM test_prepare_syntax WHERE id=? AND WHERE");
stmt = mysql_prepare(mysql, query, strlen(query));
mystmt_init_r(stmt);
@@ -981,7 +1025,6 @@ static void test_prepare()
{
MYSQL_STMT *stmt;
int rc, i;
- char query[200];
int int_data, o_int_data;
char str_data[50], data[50];
char tiny_data, o_tiny_data;
@@ -1011,7 +1054,7 @@ static void test_prepare()
myquery(rc);
/* insert by prepare */
- strcpy(query,"INSERT INTO my_prepare VALUES(?,?,?,?,?,?,?)");
+ strxmov(query,"INSERT INTO my_prepare VALUES(?,?,?,?,?,?,?)",NullS);
stmt = mysql_prepare(mysql, query, strlen(query));
mystmt_init(stmt);
@@ -1102,15 +1145,17 @@ static void test_prepare()
rc = mysql_fetch(stmt);
mystmt(stmt, rc);
- fprintf(stdout, "\n tiny : %d (%lu)", tiny_data,length[0]);
- fprintf(stdout, "\n short : %d (%lu)", small_data,length[3]);
- fprintf(stdout, "\n int : %d (%lu)", int_data,length[2]);
- fprintf(stdout, "\n big : %lld (%lu)", big_data,length[4]);
+ fprintf(stdout, "\n");
+
+ fprintf(stdout, "\n\t tiny : %d (%lu)", tiny_data,length[0]);
+ fprintf(stdout, "\n\t short : %d (%lu)", small_data,length[3]);
+ fprintf(stdout, "\n\t int : %d (%lu)", int_data,length[2]);
+ fprintf(stdout, "\n\t big : %lld (%lu)", big_data,length[4]);
- fprintf(stdout, "\n float : %f (%lu)", real_data,length[5]);
- fprintf(stdout, "\n double : %f (%lu)", double_data,length[6]);
+ fprintf(stdout, "\n\t float : %f (%lu)", real_data,length[5]);
+ fprintf(stdout, "\n\t double : %f (%lu)", double_data,length[6]);
- fprintf(stdout, "\n str : %s (%lu)", str_data, length[1]);
+ fprintf(stdout, "\n\t str : %s (%lu)", str_data, length[1]);
myassert(tiny_data == o_tiny_data);
myassert(is_null[0] == 0);
@@ -1156,7 +1201,7 @@ static void test_double_compare()
{
MYSQL_STMT *stmt;
int rc;
- char query[200],real_data[10], tiny_data;
+ char real_data[10], tiny_data;
double double_data;
MYSQL_RES *result;
MYSQL_BIND bind[3];
@@ -1180,7 +1225,7 @@ static void test_double_compare()
rc = mysql_query(mysql,"INSERT INTO test_double_compare VALUES(1,10.2,34.5)");
myquery(rc);
- strcpy(query, "UPDATE test_double_compare SET col1=100 WHERE col1 = ? AND col2 = ? AND COL3 = ?");
+ strmov(query, "UPDATE test_double_compare SET col1=100 WHERE col1 = ? AND col2 = ? AND COL3 = ?");
stmt = mysql_prepare(mysql,query, strlen(query));
mystmt_init(stmt);
@@ -1213,8 +1258,7 @@ static void test_double_compare()
rc = mysql_execute(stmt);
mystmt(stmt, rc);
- rc = (int)mysql_affected_rows(mysql);
- fprintf(stdout,"\n total affected rows:%d",rc);
+ verify_affected_rows(0);
mysql_stmt_close(stmt);
@@ -1344,7 +1388,6 @@ static void test_fetch_null()
{
MYSQL_STMT *stmt;
int rc;
- const char query[100];
int i, nData;
MYSQL_BIND bind[11];
ulong length[11];
@@ -1425,12 +1468,10 @@ static void test_select_version()
{
MYSQL_STMT *stmt;
int rc;
- const char query[100];
myheader("test_select_version");
- strmov((char *)query , "SELECT @@version");
- stmt = PREPARE(mysql, query);
+ stmt = mysql_prepare(mysql, "SELECT @@version", 30);
mystmt_init(stmt);
verify_param_count(stmt,0);
@@ -1449,13 +1490,10 @@ static void test_select_simple()
{
MYSQL_STMT *stmt;
int rc;
- const char query[100];
myheader("test_select_simple");
- /* insert by prepare */
- strmov((char *)query, "SHOW TABLES FROM mysql");
- stmt = mysql_prepare(mysql, query, strlen(query));
+ stmt = mysql_prepare(mysql, "SHOW TABLES FROM mysql", 50);
mystmt_init(stmt);
verify_param_count(stmt,0);
@@ -1639,7 +1677,7 @@ static void test_select()
/* string data */
nData=10;
- strcpy(szData,(char *)"venu");
+ strmov(szData,(char *)"venu");
bind[1].buffer_type=FIELD_TYPE_STRING;
bind[1].buffer=(char *)szData;
bind[1].buffer_length= 4;
@@ -1750,7 +1788,7 @@ static void test_simple_update()
rc = mysql_query(mysql,"INSERT INTO test_update VALUES(1,'MySQL',100)");
myquery(rc);
- myassert(1 == mysql_affected_rows(mysql));
+ verify_affected_rows(1);
rc = mysql_commit(mysql);
myquery(rc);
@@ -1779,7 +1817,7 @@ static void test_simple_update()
rc = mysql_execute(stmt);
mystmt(stmt, rc);
- myassert(1 == mysql_affected_rows(mysql));
+ verify_affected_rows(1);
mysql_stmt_close(stmt);
@@ -2184,7 +2222,7 @@ static void test_simple_delete()
rc = mysql_query(mysql,"INSERT INTO test_simple_delete VALUES(1,'MySQL',100)");
myquery(rc);
- myassert(1 == mysql_affected_rows(mysql));
+ verify_affected_rows(1);
rc = mysql_commit(mysql);
myquery(rc);
@@ -2214,7 +2252,8 @@ static void test_simple_delete()
rc = mysql_execute(stmt);
mystmt(stmt, rc);
- myassert(1 == mysql_affected_rows(mysql));
+
+ verify_affected_rows(1);
mysql_stmt_close(stmt);
@@ -2292,7 +2331,7 @@ static void test_update()
rc = mysql_execute(stmt);
mystmt(stmt, rc);
- myassert(1 == mysql_affected_rows(mysql));
+ verify_affected_rows(1);
mysql_stmt_close(stmt);
strmov(query,"UPDATE test_update SET col2=? WHERE col3=?");
@@ -2316,7 +2355,7 @@ static void test_update()
rc = mysql_execute(stmt);
mystmt(stmt, rc);
- myassert(1 == mysql_affected_rows(mysql));
+ verify_affected_rows(1);
mysql_stmt_close(stmt);
@@ -2394,7 +2433,6 @@ static void test_bind_result()
{
MYSQL_STMT *stmt;
int rc;
- char query[100];
int nData;
ulong length, length1;
char szData[100];
@@ -2440,8 +2478,7 @@ static void test_bind_result()
bind[1].length= &length1;
bind[1].is_null= &is_null[1];
- strmov(query , "SELECT * FROM test_bind_result");
- stmt = mysql_prepare(mysql, query, strlen(query));
+ stmt = mysql_prepare(mysql, "SELECT * FROM test_bind_result", 50);
mystmt_init(stmt);
rc = mysql_bind_result(stmt,bind);
@@ -2490,7 +2527,6 @@ static void test_bind_result_ext()
{
MYSQL_STMT *stmt;
int rc, i;
- const char query[100];
uchar t_data;
short s_data;
int i_data;
@@ -2563,8 +2599,7 @@ static void test_bind_result_ext()
bind[7].length= &bLength;
bind[7].buffer_length= sizeof(bData);
- strmov((char *)query , "SELECT * FROM test_bind_result");
- stmt = mysql_prepare(mysql, query, strlen(query));
+ stmt = mysql_prepare(mysql, "select * from test_bind_result", 50);
mystmt_init(stmt);
rc = mysql_bind_result(stmt,bind);
@@ -2614,11 +2649,10 @@ static void test_bind_result_ext1()
MYSQL_STMT *stmt;
uint i;
int rc;
- const char query[100];
char t_data[20];
float s_data;
short i_data;
- short b_data;
+ uchar b_data;
int f_data;
long bData;
char d_data[20];
@@ -2655,7 +2689,6 @@ static void test_bind_result_ext1()
bind[0].buffer_type=MYSQL_TYPE_STRING;
bind[0].buffer=(char *) t_data;
bind[0].buffer_length= sizeof(t_data);
- bind[0].length= &length[0];
bind[1].buffer_type=MYSQL_TYPE_FLOAT;
bind[1].buffer=(char *)&s_data;
@@ -2684,8 +2717,7 @@ static void test_bind_result_ext1()
bind[i].length= &length[i];
}
- strmov((char *)query , "SELECT * FROM test_bind_result");
- stmt = mysql_prepare(mysql, query, strlen(query));
+ stmt = mysql_prepare(mysql, "select * from test_bind_result", 50);
mystmt_init(stmt);
rc = mysql_bind_result(stmt,bind);
@@ -2712,6 +2744,7 @@ static void test_bind_result_ext1()
myassert(i_data == 3999);
myassert(f_data == 2);
myassert(strcmp(d_data,"58.89")==0);
+ myassert(b_data == 54);
myassert(length[0] == 3);
myassert(length[1] == 4);
@@ -3399,13 +3432,19 @@ static void test_warnings()
myheader("test_warnings");
+ mysql_query(mysql, "DROP TABLE if exists test_non_exists");
+
+ rc = mysql_query(mysql, "DROP TABLE if exists test_non_exists");
+ myquery(rc);
+
+ fprintf(stdout, "\n total warnings: %d", mysql_warning_count(mysql));
rc = mysql_query(mysql,"SHOW WARNINGS");
myquery(rc);
- result = mysql_use_result(mysql);
+ result = mysql_store_result(mysql);
mytest(result);
- my_process_result_set(result);
+ myassert(1 == my_process_result_set(result));
mysql_free_result(result);
}
@@ -3419,10 +3458,15 @@ static void test_errors()
myheader("test_errors");
+ mysql_query(mysql, "DROP TABLE if exists test_non_exists");
+
+ rc = mysql_query(mysql, "DROP TABLE test_non_exists");
+ myquery_r(rc);
+
rc = mysql_query(mysql,"SHOW ERRORS");
myquery(rc);
- result = mysql_use_result(mysql);
+ result = mysql_store_result(mysql);
mytest(result);
my_process_result_set(result);
@@ -3438,12 +3482,11 @@ static void test_insert()
{
MYSQL_STMT *stmt;
int rc;
- char query[200];
char str_data[50];
char tiny_data;
MYSQL_RES *result;
MYSQL_BIND bind[2];
- ulong length[2];
+ ulong length;
myheader("test_insert");
@@ -3461,9 +3504,7 @@ static void test_insert()
myquery(rc);
/* insert by prepare */
- bzero(bind, sizeof(bind));
- strmov(query,"INSERT INTO test_prep_insert VALUES(?,?)");
- stmt = mysql_prepare(mysql, query, strlen(query));
+ stmt = mysql_prepare(mysql, "INSERT INTO test_prep_insert VALUES(?,?)", 70);
mystmt_init(stmt);
verify_param_count(stmt,2);
@@ -3472,12 +3513,14 @@ static void test_insert()
bind[0].buffer_type=FIELD_TYPE_TINY;
bind[0].buffer=(char *)&tiny_data;
bind[0].is_null= 0;
+ bind[0].length= 0;
/* string */
bind[1].buffer_type=FIELD_TYPE_STRING;
bind[1].buffer=str_data;
bind[1].buffer_length=sizeof(str_data);;
bind[1].is_null= 0;
+ bind[1].length= &length;
rc = mysql_bind_param(stmt,bind);
mystmt(stmt, rc);
@@ -3485,7 +3528,7 @@ static void test_insert()
/* now, execute the prepared statement to insert 10 records.. */
for (tiny_data=0; tiny_data < 3; tiny_data++)
{
- length[1] = my_sprintf(str_data, (str_data, "MySQL%d",tiny_data));
+ length = my_sprintf(str_data, (str_data, "MySQL%d",tiny_data));
rc = mysql_execute(stmt);
mystmt(stmt, rc);
}
@@ -3516,7 +3559,6 @@ static void test_prepare_resultset()
{
MYSQL_STMT *stmt;
int rc;
- char query[200];
MYSQL_RES *result;
myheader("test_prepare_resultset");
@@ -3534,8 +3576,7 @@ static void test_prepare_resultset()
name varchar(50),extra double)");
myquery(rc);
- strmov(query,"SELECT * FROM test_prepare_resultset");
- stmt = PREPARE(mysql, query);
+ stmt = mysql_prepare(mysql, "SELECT * FROM test_prepare_resultset", 60);
mystmt_init(stmt);
verify_param_count(stmt,0);
@@ -3616,7 +3657,6 @@ static void test_stmt_close()
MYSQL_STMT *stmt1, *stmt2, *stmt3, *stmt_x;
MYSQL_BIND bind[1];
MYSQL_RES *result;
- char query[100];
unsigned int count;
int rc;
@@ -3648,25 +3688,25 @@ static void test_stmt_close()
myquery(rc);
strmov(query,"ALTER TABLE test_stmt_close ADD name varchar(20)");
- stmt1= PREPARE(lmysql, query);
+ stmt1= mysql_prepare(lmysql, query, 70);
mystmt_init(stmt1);
verify_param_count(stmt1, 0);
strmov(query,"INSERT INTO test_stmt_close(id) VALUES(?)");
- stmt_x= PREPARE(mysql, query);
+ stmt_x= mysql_prepare(mysql, query, 70);
mystmt_init(stmt_x);
verify_param_count(stmt_x, 1);
strmov(query,"UPDATE test_stmt_close SET id=? WHERE id=?");
- stmt3= PREPARE(lmysql, query);
+ stmt3= mysql_prepare(lmysql, query, 70);
mystmt_init(stmt3);
verify_param_count(stmt3, 2);
strmov(query,"SELECT * FROM test_stmt_close WHERE id=?");
- stmt2= PREPARE(lmysql, query);
+ stmt2= mysql_prepare(lmysql, query, 70);
mystmt_init(stmt2);
verify_param_count(stmt2, 1);
@@ -3698,9 +3738,7 @@ static void test_stmt_close()
rc = mysql_execute(stmt_x);
mystmt(stmt_x, rc);
- rc= (ulong)mysql_stmt_affected_rows(stmt_x);
- fprintf(stdout,"\n total rows affected: %d", rc);
- myassert (rc == 1);
+ verify_st_affected_rows(stmt_x, 1);
rc= mysql_stmt_close(stmt_x);
fprintf(stdout,"\n mysql_close_stmt(x) returned: %d", rc);
@@ -3820,7 +3858,6 @@ static void test_insert_meta()
{
MYSQL_STMT *stmt;
int rc;
- char query[200];
MYSQL_RES *result;
MYSQL_FIELD *field;
@@ -3840,7 +3877,7 @@ static void test_insert_meta()
myquery(rc);
strmov(query,"INSERT INTO test_prep_insert VALUES(10,'venu1','test')");
- stmt = mysql_prepare(mysql, query, strlen(query));
+ stmt = mysql_prepare(mysql, query, 70);
mystmt_init(stmt);
verify_param_count(stmt,0);
@@ -3851,7 +3888,7 @@ static void test_insert_meta()
mysql_stmt_close(stmt);
strmov(query,"INSERT INTO test_prep_insert VALUES(?,'venu',?)");
- stmt = mysql_prepare(mysql, query, strlen(query));
+ stmt = mysql_prepare(mysql, query, 70);
mystmt_init(stmt);
verify_param_count(stmt,2);
@@ -3884,7 +3921,6 @@ static void test_update_meta()
{
MYSQL_STMT *stmt;
int rc;
- char query[200];
MYSQL_RES *result;
MYSQL_FIELD *field;
@@ -3904,7 +3940,7 @@ static void test_update_meta()
myquery(rc);
strmov(query,"UPDATE test_prep_update SET col1=10, col2='venu1' WHERE col3='test'");
- stmt = mysql_prepare(mysql, query, strlen(query));
+ stmt = mysql_prepare(mysql, query, 100);
mystmt_init(stmt);
verify_param_count(stmt,0);
@@ -3915,7 +3951,7 @@ static void test_update_meta()
mysql_stmt_close(stmt);
strmov(query,"UPDATE test_prep_update SET col1=?, col2='venu' WHERE col3=?");
- stmt = mysql_prepare(mysql, query, strlen(query));
+ stmt = mysql_prepare(mysql, query, 100);
mystmt_init(stmt);
verify_param_count(stmt,2);
@@ -3952,7 +3988,6 @@ static void test_select_meta()
{
MYSQL_STMT *stmt;
int rc;
- char query[200];
MYSQL_RES *result;
MYSQL_FIELD *field;
@@ -3972,7 +4007,7 @@ static void test_select_meta()
myquery(rc);
strmov(query,"SELECT * FROM test_prep_select WHERE col1=10");
- stmt = mysql_prepare(mysql, query, strlen(query));
+ stmt = mysql_prepare(mysql, query, 70);
mystmt_init(stmt);
verify_param_count(stmt,0);
@@ -3981,7 +4016,7 @@ static void test_select_meta()
mytest_r(result);
strmov(query,"SELECT col1, col3 from test_prep_select WHERE col1=? AND col3='test' AND col2= ?");
- stmt = mysql_prepare(mysql, query, strlen(query));
+ stmt = mysql_prepare(mysql, query, 120);
mystmt_init(stmt);
verify_param_count(stmt,2);
@@ -4170,9 +4205,7 @@ static void test_multi_stmt()
rc = mysql_execute(stmt2);
mystmt(stmt2, rc);
- rc = (int)mysql_stmt_affected_rows(stmt2);
- fprintf(stdout,"\n total rows affected(update): %d", rc);
- myassert(rc == 1);
+ verify_st_affected_rows(stmt2, 1);
rc = mysql_execute(stmt);
mystmt(stmt, rc);
@@ -4191,9 +4224,7 @@ static void test_multi_stmt()
rc = mysql_execute(stmt1);
mystmt(stmt1, rc);
- rc = (int)mysql_stmt_affected_rows(stmt1);
- fprintf(stdout,"\n total rows affected(delete): %d", rc);
- myassert(rc == 1);
+ verify_st_affected_rows(stmt1, 1);
mysql_stmt_close(stmt1);
@@ -4219,11 +4250,11 @@ static void test_manual_sample()
unsigned int param_count;
MYSQL_STMT *stmt;
short small_data;
- int int_data, i;
- char str_data[50], query[255];
+ int int_data;
+ char str_data[50];
ulonglong affected_rows;
MYSQL_BIND bind[3];
- my_bool is_null[3];
+ my_bool is_null;
myheader("test_manual_sample");
@@ -4271,24 +4302,24 @@ static void test_manual_sample()
/* Bind the data for the parameters */
/* INTEGER PART */
- memset(bind,0,sizeof(bind));
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer= (char *)&int_data;
+ bind[0].is_null= 0;
+ bind[0].length= 0;
/* STRING PART */
bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
bind[1].buffer= (char *)str_data;
bind[1].buffer_length= sizeof(str_data);
+ bind[1].is_null= 0;
+ bind[1].length= 0;
/* SMALLINT PART */
bind[2].buffer_type= MYSQL_TYPE_SHORT;
bind[2].buffer= (char *)&small_data;
-
- for (i= 0; i < (int) array_elements(bind); i++)
- {
- bind[i].is_null= &is_null[i];
- is_null[i]=0;
- }
+ bind[2].is_null= &is_null;
+ bind[2].length= 0;
+ is_null= 0;
/* Bind the buffers */
if (mysql_bind_param(stmt, bind))
@@ -4301,8 +4332,9 @@ static void test_manual_sample()
/* Specify the data */
int_data= 10; /* integer */
strmov(str_data,"MySQL"); /* string */
+
/* INSERT SMALLINT data as NULL */
- is_null[2]= 1;
+ is_null= 1;
/* Execute the insert statement - 1*/
if (mysql_execute(stmt))
@@ -4326,7 +4358,7 @@ static void test_manual_sample()
int_data= 1000;
strmov(str_data,"The most popular open source database");
small_data= 1000; /* smallint */
- is_null[2]= 0;
+ is_null= 0; /* reset */
/* Execute the insert statement - 2*/
if (mysql_execute(stmt))
@@ -4484,7 +4516,8 @@ static void test_multi_query()
if ((result= mysql_store_result(mysql)))
my_process_result_set(result);
else
- fprintf(stdout,"OK, %d row(s) affected, %d warning(s)", exp_value,
+ fprintf(stdout,"OK, %lld row(s) affected, %d warning(s)",
+ mysql_affected_rows(mysql),
mysql_warning_count(mysql));
exp_value= (uint) mysql_affected_rows(mysql);
}
@@ -4501,7 +4534,6 @@ static void test_store_result()
{
MYSQL_STMT *stmt;
int rc;
- const char query[100];
long nData;
char szData[100];
MYSQL_BIND bind[2];
@@ -4545,8 +4577,7 @@ static void test_store_result()
bind[1].is_null= &is_null[1];
length1= 0;
- strmov((char *)query , "SELECT * FROM test_store_result");
- stmt = mysql_prepare(mysql, query, strlen(query));
+ stmt = mysql_prepare(mysql, "SELECT * FROM test_store_result", 50);
mystmt_init(stmt);
rc = mysql_bind_result(stmt,bind);
@@ -4726,7 +4757,6 @@ static void test_store_result2()
bind[0].buffer= (char *) &nData; /* integer data */
bind[0].length= &length;
bind[0].is_null= 0;
- length= 0;
strmov((char *)query , "SELECT col1 FROM test_store_result where col1= ?");
stmt = mysql_prepare(mysql, query, strlen(query));
@@ -4817,17 +4847,17 @@ static void test_subselect()
myquery(rc);
/* fetch */
-
- bind[0].buffer_type=FIELD_TYPE_LONG;
+ bind[0].buffer_type= FIELD_TYPE_LONG;
bind[0].buffer= (char *) &id;
bind[0].length= &length;
- bind[0],is_null= 0;
- length=0;
+ bind[0].is_null= 0;
+ length= 0;
strmov((char *)query , "SELECT ROW(1,7) IN (select id, id1 from test_sub2 WHERE id1=?)");
myassert(1 == my_stmt_result("SELECT ROW(1,7) IN (select id, id1 from test_sub2 WHERE id1=8)",100));
myassert(1 == my_stmt_result("SELECT ROW(1,7) IN (select id, id1 from test_sub2 WHERE id1=7)",100));
- stmt = mysql_prepare(mysql, query, strlen(query));
+
+ stmt = mysql_prepare(mysql, query, 150);
mystmt_init(stmt);
rc = mysql_bind_param(stmt,bind);
@@ -4843,11 +4873,24 @@ static void test_subselect()
rc = mysql_fetch(stmt);
mystmt(stmt,rc);
- fprintf(stdout,"\n row 1: %d(%lu)",id, length);
+ fprintf(stdout,"\n row 1: %d (%lu)",id, length);
myassert(id == 1);
rc = mysql_fetch(stmt);
myassert(rc == MYSQL_NO_DATA);
+
+ id= 8;
+ rc = mysql_execute(stmt);
+ mystmt(stmt, rc);
+
+ rc = mysql_fetch(stmt);
+ mystmt(stmt,rc);
+
+ fprintf(stdout,"\n row 1: %d (%lu)",id, length);
+ myassert(id == 0);
+
+ rc = mysql_fetch(stmt);
+ myassert(rc == MYSQL_NO_DATA);
mysql_stmt_close(stmt);
#endif
@@ -4859,7 +4902,7 @@ static void test_subselect()
*/
static void test_bind_date_conv(uint row_count)
{
- MYSQL_STMT *stmt;
+ MYSQL_STMT *stmt= 0;
uint rc, i, count= row_count;
ulong length[4];
MYSQL_BIND bind[4];
@@ -5129,8 +5172,6 @@ static void test_pure_coverage()
stmt = mysql_prepare(mysql,"insert into test_pure(c2) values(10)",100);
mystmt_init(stmt);
- verify_param_count(stmt, 0);
-
rc = mysql_bind_param(stmt, bind);
mystmt_r(stmt, rc);
@@ -5307,8 +5348,7 @@ static void test_open_direct()
rc = mysql_execute(stmt);
mystmt(stmt, rc);
- fprintf(stdout, "\n total affected rows: %lld", mysql_stmt_affected_rows(stmt));
- myassert(1 == mysql_stmt_affected_rows(stmt));
+ verify_st_affected_rows(stmt, 1);
rc = mysql_query(mysql, "SELECT * FROM test_open_direct");
myquery(rc);
@@ -5321,8 +5361,7 @@ static void test_open_direct()
rc = mysql_execute(stmt);
mystmt(stmt, rc);
- fprintf(stdout, "\n total affected rows: %lld", mysql_stmt_affected_rows(stmt));
- myassert(1 == mysql_stmt_affected_rows(stmt));
+ verify_st_affected_rows(stmt, 1);
rc = mysql_query(mysql, "SELECT * FROM test_open_direct");
myquery(rc);
@@ -5384,7 +5423,8 @@ static void test_fetch_nobuffs()
myheader("test_fetch_nobuffs");
- stmt = mysql_prepare(mysql,"SELECT DATABASE(), CURRENT_USER(), CURRENT_DATE(), CURRENT_TIME()",100);
+ stmt = mysql_prepare(mysql,"SELECT DATABASE(), CURRENT_USER(), \
+ CURRENT_DATE(), CURRENT_TIME()",100);
mystmt_init(stmt);
rc = mysql_execute(stmt);
@@ -5393,7 +5433,8 @@ static void test_fetch_nobuffs()
rc = 0;
while (mysql_fetch(stmt) != MYSQL_NO_DATA)
rc++;
- fprintf(stdout, "\n total rows: %d", rc);
+
+ fprintf(stdout, "\n total rows : %d", rc);
myassert(rc == 1);
bind[0].buffer_type= MYSQL_TYPE_STRING;
@@ -5421,13 +5462,272 @@ static void test_fetch_nobuffs()
fprintf(stdout, "\n CURRENT_DATE() : %s", str[2]);
fprintf(stdout, "\n CURRENT_TIME() : %s", str[3]);
}
- fprintf(stdout, "\n total rows: %d", rc);
+ fprintf(stdout, "\n total rows : %d", rc);
myassert(rc == 1);
mysql_stmt_close(stmt);
}
-static struct my_option myctest_long_options[] =
+/*
+ To test a misc bug
+*/
+static void test_ushort_bug()
+{
+ MYSQL_STMT *stmt;
+ MYSQL_BIND bind[4];
+ ushort short_value;
+ ulong long_value;
+ ulong s_length, l_length, ll_length, t_length;
+ ulonglong longlong_value;
+ int rc;
+ uchar tiny_value;
+
+ myheader("test_ushort_bug");
+
+ rc= mysql_query(mysql,"DROP TABLE IF EXISTS test_ushort");
+ myquery(rc);
+
+ rc= mysql_query(mysql,"CREATE TABLE test_ushort(a smallint unsigned, \
+ b smallint unsigned, \
+ c smallint unsigned, \
+ d smallint unsigned)");
+ myquery(rc);
+
+ rc= mysql_query(mysql,"INSERT INTO test_ushort VALUES(35999, 35999, 35999, 200)");
+ myquery(rc);
+
+
+ stmt = mysql_prepare(mysql,"SELECT * FROM test_ushort",50);
+ mystmt_init(stmt);
+
+ rc = mysql_execute(stmt);
+ mystmt(stmt, rc);
+
+ bind[0].buffer_type= MYSQL_TYPE_SHORT;
+ bind[0].buffer= (char *)&short_value;
+ bind[0].is_null= 0;
+ bind[0].length= &s_length;
+
+ bind[1].buffer_type= MYSQL_TYPE_LONG;
+ bind[1].buffer= (char *)&long_value;
+ bind[1].is_null= 0;
+ bind[1].length= &l_length;
+
+ bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
+ bind[2].buffer= (char *)&longlong_value;
+ bind[2].is_null= 0;
+ bind[2].length= &ll_length;
+
+ bind[3].buffer_type= MYSQL_TYPE_TINY;
+ bind[3].buffer= (char *)&tiny_value;
+ bind[3].is_null= 0;
+ bind[3].length= &t_length;
+
+ rc = mysql_bind_result(stmt, bind);
+ mystmt(stmt, rc);
+
+ rc = mysql_fetch(stmt);
+ mystmt(stmt, rc);
+
+ fprintf(stdout,"\n ushort : %d (%ld)", short_value, s_length);
+ fprintf(stdout,"\n ulong : %ld (%ld)", long_value, l_length);
+ fprintf(stdout,"\n longlong : %lld (%ld)", longlong_value, ll_length);
+ fprintf(stdout,"\n tinyint : %d (%ld)", tiny_value, t_length);
+
+ myassert(short_value == 35999);
+ myassert(s_length == 2);
+
+ myassert(long_value == 35999);
+ myassert(l_length == 4);
+
+ myassert(longlong_value == 35999);
+ myassert(ll_length == 8);
+
+ myassert(tiny_value == 200);
+ myassert(t_length == 1);
+
+ rc = mysql_fetch(stmt);
+ myassert(rc == MYSQL_NO_DATA);
+
+ mysql_stmt_close(stmt);
+}
+
+/*
+ To test a misc smallint-signed conversion bug
+*/
+static void test_sshort_bug()
+{
+ MYSQL_STMT *stmt;
+ MYSQL_BIND bind[4];
+ short short_value;
+ long long_value;
+ ulong s_length, l_length, ll_length, t_length;
+ ulonglong longlong_value;
+ int rc;
+ uchar tiny_value;
+
+ myheader("test_sshort_bug");
+
+ rc= mysql_query(mysql,"DROP TABLE IF EXISTS test_sshort");
+ myquery(rc);
+
+ rc= mysql_query(mysql,"CREATE TABLE test_sshort(a smallint signed, \
+ b smallint signed, \
+ c smallint unsigned, \
+ d smallint unsigned)");
+ myquery(rc);
+
+ rc= mysql_query(mysql,"INSERT INTO test_sshort VALUES(-5999, -5999, 35999, 200)");
+ myquery(rc);
+
+
+ stmt = mysql_prepare(mysql,"SELECT * FROM test_sshort",50);
+ mystmt_init(stmt);
+
+ rc = mysql_execute(stmt);
+ mystmt(stmt, rc);
+
+ bind[0].buffer_type= MYSQL_TYPE_SHORT;
+ bind[0].buffer= (char *)&short_value;
+ bind[0].is_null= 0;
+ bind[0].length= &s_length;
+
+ bind[1].buffer_type= MYSQL_TYPE_LONG;
+ bind[1].buffer= (char *)&long_value;
+ bind[1].is_null= 0;
+ bind[1].length= &l_length;
+
+ bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
+ bind[2].buffer= (char *)&longlong_value;
+ bind[2].is_null= 0;
+ bind[2].length= &ll_length;
+
+ bind[3].buffer_type= MYSQL_TYPE_TINY;
+ bind[3].buffer= (char *)&tiny_value;
+ bind[3].is_null= 0;
+ bind[3].length= &t_length;
+
+ rc = mysql_bind_result(stmt, bind);
+ mystmt(stmt, rc);
+
+ rc = mysql_fetch(stmt);
+ mystmt(stmt, rc);
+
+ fprintf(stdout,"\n sshort : %d (%ld)", short_value, s_length);
+ fprintf(stdout,"\n slong : %ld (%ld)", long_value, l_length);
+ fprintf(stdout,"\n longlong : %lld (%ld)", longlong_value, ll_length);
+ fprintf(stdout,"\n tinyint : %d (%ld)", tiny_value, t_length);
+
+ myassert(short_value == -5999);
+ myassert(s_length == 2);
+
+ myassert(long_value == -5999);
+ myassert(l_length == 4);
+
+ myassert(longlong_value == 35999);
+ myassert(ll_length == 8);
+
+ myassert(tiny_value == 200);
+ myassert(t_length == 1);
+
+ rc = mysql_fetch(stmt);
+ myassert(rc == MYSQL_NO_DATA);
+
+ mysql_stmt_close(stmt);
+}
+
+/*
+ To test a misc tinyint-signed conversion bug
+*/
+static void test_stiny_bug()
+{
+ MYSQL_STMT *stmt;
+ MYSQL_BIND bind[4];
+ short short_value;
+ long long_value;
+ ulong s_length, l_length, ll_length, t_length;
+ ulonglong longlong_value;
+ int rc;
+ uchar tiny_value;
+
+ myheader("test_stiny_bug");
+
+ rc= mysql_query(mysql,"DROP TABLE IF EXISTS test_stiny");
+ myquery(rc);
+
+ rc= mysql_query(mysql,"CREATE TABLE test_stiny(a tinyint signed, \
+ b tinyint signed, \
+ c tinyint unsigned, \
+ d tinyint unsigned)");
+ myquery(rc);
+
+ rc= mysql_query(mysql,"INSERT INTO test_stiny VALUES(-128, -127, 255, 0)");
+ myquery(rc);
+
+
+ stmt = mysql_prepare(mysql,"SELECT * FROM test_stiny",50);
+ mystmt_init(stmt);
+
+ rc = mysql_execute(stmt);
+ mystmt(stmt, rc);
+
+ bind[0].buffer_type= MYSQL_TYPE_SHORT;
+ bind[0].buffer= (char *)&short_value;
+ bind[0].is_null= 0;
+ bind[0].length= &s_length;
+
+ bind[1].buffer_type= MYSQL_TYPE_LONG;
+ bind[1].buffer= (char *)&long_value;
+ bind[1].is_null= 0;
+ bind[1].length= &l_length;
+
+ bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
+ bind[2].buffer= (char *)&longlong_value;
+ bind[2].is_null= 0;
+ bind[2].length= &ll_length;
+
+ bind[3].buffer_type= MYSQL_TYPE_TINY;
+ bind[3].buffer= (char *)&tiny_value;
+ bind[3].is_null= 0;
+ bind[3].length= &t_length;
+
+ rc = mysql_bind_result(stmt, bind);
+ mystmt(stmt, rc);
+
+ rc = mysql_fetch(stmt);
+ mystmt(stmt, rc);
+
+ fprintf(stdout,"\n sshort : %d (%ld)", short_value, s_length);
+ fprintf(stdout,"\n slong : %ld (%ld)", long_value, l_length);
+ fprintf(stdout,"\n longlong : %lld (%ld)", longlong_value, ll_length);
+ fprintf(stdout,"\n tinyint : %d (%ld)", tiny_value, t_length);
+
+ myassert(short_value == -128);
+ myassert(s_length == 2);
+
+ myassert(long_value == -127);
+ myassert(l_length == 4);
+
+ myassert(longlong_value == 255);
+ myassert(ll_length == 8);
+
+ myassert(tiny_value == 0);
+ myassert(t_length == 1);
+
+ rc = mysql_fetch(stmt);
+ myassert(rc == MYSQL_NO_DATA);
+
+ mysql_stmt_close(stmt);
+}
+
+/*
+ Read and parse arguments and MySQL options from my.cnf
+*/
+
+static const char *client_test_load_default_groups[]= { "client", 0 };
+static char **defaults_argv;
+
+static struct my_option client_test_long_options[] =
{
{"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
0, 0, 0, 0, 0},
@@ -5447,10 +5747,18 @@ static struct my_option myctest_long_options[] =
{"socket", 'S', "Socket file to use for connection", (char **) &opt_unix_socket,
(char **) &opt_unix_socket, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"count", 't', "Number of times test to be executed", (char **) &opt_count,
- (char **) &opt_count, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ (char **) &opt_count, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
+
+static void client_test_print_version(void)
+{
+ fprintf(stdout, "%s Distrib %s, for %s (%s)\n\n",
+ my_progname,MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
+}
+
+
static void usage(void)
{
/*
@@ -5464,25 +5772,13 @@ static void usage(void)
puts("and you are welcome to modify and redistribute it under the GPL license\n");
puts(" Copyright (C) 1995-2003 MySQL AB ");
puts("-----------------------------------------------------------------------\n");
- fprintf(stdout,"usage: %s [OPTIONS]\n\n", my_progname);
- fprintf(stdout,"\
- -?, --help Display this help message and exit.\n\
- -D --database=... Database name to be used for test.\n\
- -h, --host=... Connect to host.\n\
- -p, --password[=...] Password to use when connecting to server.\n");
-#ifdef __WIN__
- fprintf(stdout,"\
- -W, --pipe Use named pipes to connect to server.\n");
-#endif
- fprintf(stdout,"\
- -P, --port=... Port number to use for connection.\n\
- -S, --socket=... Socket file to use for connection.\n");
-#ifndef DONT_ALLOW_USER_CHANGE
- fprintf(stdout,"\
- -u, --user=# User for login if not current user.\n");
-#endif
- fprintf(stdout,"\
- -t, --count=... Execute the test count times.\n");
+ client_test_print_version();
+ fprintf(stdout,"Usage: %s [OPTIONS]\n\n", my_progname);
+
+ my_print_help(client_test_long_options);
+ print_defaults("my", client_test_load_default_groups);
+ my_print_variables(client_test_long_options);
+
puts("***********************************************************************\n");
}
@@ -5513,22 +5809,17 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
return 0;
}
-static const char *load_default_groups[]= { "client",0 };
-
static void get_options(int argc, char **argv)
{
int ho_error;
- load_defaults("my",load_default_groups,&argc,&argv);
+ load_defaults("my",client_test_load_default_groups,&argc,&argv);
- if ((ho_error=handle_options(&argc,&argv, myctest_long_options,
- get_one_option)))
+ if ((ho_error= handle_options(&argc,&argv, client_test_long_options,
+ get_one_option)))
exit(ho_error);
- /*free_defaults(argv);*/
if (tty_password)
opt_password=get_tty_password(NullS);
- if (!opt_count)
- opt_count= 1;
return;
}
@@ -5540,7 +5831,7 @@ static void print_test_output()
{
fprintf(stdout,"\n\n");
fprintf(stdout,"All '%d' tests were successful (in '%d' iterations)",
- test_count-1, opt_count);
+ test_count-1, opt_count);
fprintf(stdout,"\n Total execution time: %g SECS", total_time);
if (opt_count > 1)
fprintf(stdout," (Avg: %g SECS)", total_time/opt_count);
@@ -5554,6 +5845,9 @@ static void print_test_output()
int main(int argc, char **argv)
{
MY_INIT(argv[0]);
+
+ load_defaults("my",client_test_load_default_groups,&argc,&argv);
+ defaults_argv= argv;
get_options(argc,argv);
client_connect(); /* connect to server */
@@ -5625,7 +5919,7 @@ int main(int argc, char **argv)
test_prepare_resultset();/* prepare meta info test */
test_stmt_close(); /* mysql_stmt_close() test -- hangs */
test_prepare_field_result(); /* prepare meta info */
- test_multi_stmt(); /* multi stmt test -TODO*/
+ test_multi_stmt(); /* multi stmt test */
test_multi_query(); /* test multi query execution */
test_store_result(); /* test the store_result */
test_store_result1(); /* test store result without buffers */
@@ -5640,13 +5934,18 @@ int main(int argc, char **argv)
test_manual_sample(); /* sample in the manual */
test_pure_coverage(); /* keep pure coverage happy */
test_buffers(); /* misc buffer handling */
+ test_ushort_bug(); /* test a simple conv bug from php */
+ test_sshort_bug(); /* test a simple conv bug from php */
+ test_stiny_bug(); /* test a simple conv bug from php */
end_time= time((time_t *)0);
total_time+= difftime(end_time, start_time);
+
/* End of tests */
}
client_disconnect(); /* disconnect from server */
+ free_defaults(defaults_argv);
print_test_output();
return(0);