Commit 86ec3c8f authored by unknown's avatar unknown

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
parents 0a10f78f c5040ddd
......@@ -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
......
......@@ -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:
return the the length of the data that is returned.
@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
@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
@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.
@item MYSQL_TIME
This structure is used to send and receive DATE, TIME and
TIMESTAMP data directly to/from server.
@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
@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
......@@ -612,6 +661,14 @@ 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
MYSQL_TYPE_VAR_STRING
......@@ -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
......@@ -678,11 +739,9 @@ how to fetch the statement binary data, refer to @ref{mysql_fetch}.
@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 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_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
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
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,7 +882,7 @@ 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.
......@@ -938,6 +1012,14 @@ 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
MYSQL_TYPE_VAR_STRING
......@@ -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))
......@@ -1112,8 +1264,16 @@ char str_data[50];
exit(0);
@}
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[0])
fprintf(stdout, "\n Col1 data is NULL");
else
fprintf(stdout, "\n Col1: %d, length: %ld", int_data, int_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));
......@@ -1260,6 +1410,9 @@ long length;
Closes the prepared statement. @code{mysql_stmt_close()} also
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
Zero if the statement was freed successfully. Non-zero if an error occured.
......@@ -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()}
......@@ -1419,4 +1572,165 @@ Zero if successful. Non-zero if an error occured
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
......@@ -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);
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))
{
......
......@@ -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 */
......
......@@ -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
......
......@@ -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)
......
......@@ -50,7 +50,7 @@ class Item_sum_unique_users :public Item_sum_num
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);
}
......
......@@ -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)},
......
......@@ -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");
......
......@@ -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 {}
......
......@@ -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);
......@@ -147,29 +150,30 @@ 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)))
......@@ -179,16 +183,20 @@ static void client_connect()
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,6 +359,7 @@ int my_process_result_set(MYSQL_RES *result)
fputc('\n',stdout);
row_count++;
}
if (row_count)
my_print_dashes(result);
if (mysql_errno(mysql) != 0)
......@@ -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++;
}
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 *
......@@ -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,12 +4873,25 @@ 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,
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;
}
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment