1
/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
* Drizzle Client & Protocol Library
5
* Copyright (C) 2013 Drizzle Developer Group
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions are
12
* * Redistributions of source code must retain the above copyright
13
* notice, this list of conditions and the following disclaimer.
15
* * Redistributions in binary form must reproduce the above
16
* copyright notice, this list of conditions and the following disclaimer
17
* in the documentation and/or other materials provided with the
20
* * The names of its contributors may not be used to endorse or
21
* promote products derived from this software without specific prior
24
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39
* This test inserts a set of rows with NULLs in various columns, and verifies
40
* that returned rows have NULLs in the proper columns (and non-NULL values in
41
* the other columns). A binary count is used to generate 64 combinations of
42
* NULL and non-NULL across 6 columns.
44
* Both the insert and the query are performed twice, once using the text-based
45
* query interface and once using the prepared-statement binary-based query interface.
48
#include <yatl/lite.h>
50
#include <libdrizzle-5.1/libdrizzle.h>
55
#define CHECKED_QUERY(cmd) result = drizzle_query(con, cmd, 0, &driz_ret); ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, from \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), cmd);
57
#define TEST_PREPARED_STATEMENTS
59
int main(int argc, char *argv[])
65
drizzle_result_st *result;
67
#ifdef TEST_PREPARED_STATEMENTS
71
drizzle_st *con= drizzle_create(getenv("MYSQL_SERVER"),
72
getenv("MYSQL_PORT") ? atoi("MYSQL_PORT") : DRIZZLE_DEFAULT_TCP_PORT,
74
getenv("MYSQL_PASSWORD"),
75
getenv("MYSQL_SCHEMA"), 0);
76
ASSERT_NOT_NULL_(con, "Drizzle connection object creation error");
78
drizzle_return_t driz_ret= drizzle_connect(con);
79
if (driz_ret == DRIZZLE_RETURN_COULD_NOT_CONNECT)
81
char error[DRIZZLE_MAX_ERROR_SIZE];
82
strncpy(error, drizzle_error(con), DRIZZLE_MAX_ERROR_SIZE);
84
SKIP_IF_(driz_ret == DRIZZLE_RETURN_COULD_NOT_CONNECT, "%s(%s)", error, drizzle_strerror(driz_ret));
86
ASSERT_EQ_(DRIZZLE_RETURN_OK, driz_ret, "drizzle_connect(): %s(%s)", drizzle_error(con), drizzle_strerror(driz_ret));
88
CHECKED_QUERY("DROP SCHEMA IF EXISTS libdrizzle");
90
CHECKED_QUERY("CREATE SCHEMA libdrizzle");
92
driz_ret= drizzle_select_db(con, "libdrizzle");
93
ASSERT_EQ_(DRIZZLE_RETURN_OK, driz_ret, "USE libdrizzle");
95
CHECKED_QUERY("create table libdrizzle.t1 (a int, b int, c int, d int, e int, f int, g int, h int, i int, j int, k int)");
99
char *querybuf = malloc(256 + 60*64);
100
strcpy(querybuf, "insert into libdrizzle.t1 values ");
101
char *p = querybuf + strlen(querybuf);
103
for(int sym = 0; sym < 64; sym++) {
106
#define APPENDMAYBE(b) if (sym & b) { strcpy(p, "NULL"); p += 4; } else { p += sprintf(p, "%d", sym*NCOLS + cn); }
107
APPENDMAYBE(0x01); *p++ = ','; cn++;
108
APPENDMAYBE(0x02); *p++ = ','; cn++;
109
APPENDMAYBE(0x04); cn++;
110
p += sprintf(p, ",%d,%d,%d,%d,", sym*NCOLS + 3, sym*NCOLS + 4, sym*NCOLS + 5, sym*NCOLS + 6);
112
APPENDMAYBE(0x08); cn++;
113
p += sprintf(p, ",%d,", sym*NCOLS + 8); cn++;
114
APPENDMAYBE(0x10); *p++ = ','; cn++;
115
APPENDMAYBE(0x20); cn++;
121
CHECKED_QUERY(querybuf);
123
#ifdef TEST_PREPARED_STATEMENTS
124
strcpy(querybuf, "insert into libdrizzle.t1 values (?,?,?,?,?,?,?,?,?,?,?)");
125
sth = drizzle_stmt_prepare(con, querybuf, strlen(querybuf), &driz_ret);
126
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, preparing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), querybuf);
128
for(int sym = 0; sym < 64; sym++) {
129
// driz_ret= drizzle_stmt_reset(sth);
130
// ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, resetting statement", drizzle_strerror(driz_ret), drizzle_error(con));
132
#define SETMAYBE(cn,b) if (sym & b) driz_ret = drizzle_stmt_set_null(sth, cn); else SETALWAYS(cn);
133
#define SETALWAYS(cn) driz_ret = drizzle_stmt_set_short(sth, cn, sym*NCOLS + cn + 1000, 0)
134
ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
148
driz_ret = drizzle_stmt_execute(sth);
149
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, executing insert, sym=%d", drizzle_strerror(driz_ret), drizzle_error(con), sym);
151
driz_ret = drizzle_stmt_buffer(sth);
152
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, buffering result, sym=%d", drizzle_strerror(driz_ret), drizzle_error(con), sym);
154
// ASSERT_EQ(drizzle_stmt_affected_rows, 1);
157
ASSERT_EQ(drizzle_stmt_close(sth), DRIZZLE_RETURN_OK);
164
CHECKED_QUERY("select a,b,c,d,e,f,g,h,i,j,k from libdrizzle.t1 order by e");
165
drizzle_result_buffer(result);
166
num_fields= drizzle_result_column_count(result);
167
ASSERT_EQ_(num_fields, NCOLS, "Bad number of fields, expected %d, got %d", 11, num_fields);
171
while ((row = drizzle_row_next(result))) {
175
/* 'sym' is the value used to decide which fields have NULLs or not.
176
* 'rowbase' is the number that would be stored in the first field of this
177
* row (assuming it's non-NULL).
185
rowbase = 1000 + sym*NCOLS;
188
#define NULLMAYBE(cn, b) if (sym & b) { ASSERT_NULL_(row[cn], "Column %d, row %d should be NULL", cn+1, cur_row); } else { ASSERT_NOT_NULL_(row[cn], "Column %d, row %d should not be NULL", cn+1, cur_row); sprintf(nbuf, "%d", rowbase+cn); ASSERT_STREQ(row[cn], nbuf); }
189
#define NULLNEVER(cn) NULLMAYBE(cn, 0)
206
ASSERT_EQ(cur_row, table_size);
208
drizzle_result_free(result);
210
#ifdef TEST_PREPARED_STATEMENTS
211
strcpy(querybuf, "select a,b,c,d,e,f,g,h,i,j,k from libdrizzle.t1 order by e");
212
sth = drizzle_stmt_prepare(con, querybuf, strlen(querybuf), &driz_ret);
213
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, preparing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), querybuf);
214
driz_ret = drizzle_stmt_execute(sth);
215
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, executing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), querybuf);
219
driz_ret = drizzle_stmt_fetch(sth);
220
if (driz_ret == DRIZZLE_RETURN_ROW_END)
223
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, fetching row #%d", drizzle_strerror(driz_ret), drizzle_error(con), cur_row);
225
/* 'sym' is the value used to decide which fields have NULLs or not.
226
* 'rowbase' is the number that would be stored in the first field of this
227
* row (assuming it's non-NULL).
237
rowbase = 1000 + sym*NCOLS;
243
#define GETNULLNESS(cn) isNull = drizzle_stmt_get_is_null(sth, cn, &driz_ret); ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
244
#define NULLNOTNOW(cn) ASSERT_FALSE_(isNull, "Column %d, row %d should not be NULL", cn+1, cur_row); rowvalue = drizzle_stmt_get_int(sth, cn, &driz_ret); ASSERT_EQ(driz_ret,DRIZZLE_RETURN_OK); ASSERT_EQ(rowvalue, (unsigned)(rowbase + cn));
245
#define NULLMAYBE(cn, b) GETNULLNESS(cn); if (sym & b) { ASSERT_TRUE_(isNull, "Column %d, row %d should be NULL", cn+1, cur_row); } else { NULLNOTNOW(cn); }
246
#define NULLNEVER(cn) GETNULLNESS(cn); NULLNOTNOW(cn);
265
ASSERT_EQ(cur_row, table_size);
266
ASSERT_EQ(drizzle_stmt_close(sth), DRIZZLE_RETURN_OK);
269
CHECKED_QUERY("DROP TABLE libdrizzle.t1");
270
ASSERT_EQ_(DRIZZLE_RETURN_OK, driz_ret, "DROP TABLE libdrizzle.t1");
272
CHECKED_QUERY("DROP SCHEMA IF EXISTS libdrizzle");
274
driz_ret= drizzle_quit(con);
275
ASSERT_EQ_(DRIZZLE_RETURN_OK, driz_ret, "%s", drizzle_strerror(driz_ret));