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.
38
#include <yatl/lite.h>
39
#include "tests/unit/common.h"
41
#include <libdrizzle-5.1/libdrizzle.h>
49
/* We've chosen the floats so that the are exactly representable in a normal binary floating-point format, so we should get exact results out. However, some compilers (pretty reasonably) warn when doing exact equality tests of floats. This gets around that. */
50
#define FLOAT_EQ_EXACT(a, b) ( isfinite(a) && isfinite(b) && !(a < b) && !(a > b) )
52
#define ASSERT_FLOATEQEXACT(a, b) ASSERT_TRUE_(FLOAT_EQ_EXACT(a, b), "Floating-point values %f != %f (difference is %g)", (a), (b), (a)-(b))
54
static const drizzle_column_type_t expected_column_types[9] = {
55
DRIZZLE_COLUMN_TYPE_NONE, /* Columns are 1-indexed */
56
DRIZZLE_COLUMN_TYPE_LONG,
57
DRIZZLE_COLUMN_TYPE_TINY,
58
DRIZZLE_COLUMN_TYPE_SHORT,
59
DRIZZLE_COLUMN_TYPE_INT24,
60
DRIZZLE_COLUMN_TYPE_LONG,
61
DRIZZLE_COLUMN_TYPE_LONGLONG,
62
DRIZZLE_COLUMN_TYPE_FLOAT,
63
DRIZZLE_COLUMN_TYPE_DOUBLE
66
/* These are close to the maximum value for each integer type. A few bits are cleared in the middle of each value to detect other kinds of scrambling (e.g. inappropriate sign-extension of intermediate results). */
67
static const intmax_t column_maxes[5] = {
70
0x7FFEFF, /* 8388351 */
71
0x7FFDFFFF, /* 2147352575 */
72
0x7FFBFFFFFFFFCFFF /* 9222246136947920895 */
75
static const char *column_names[9] = {
77
"a", "b", "c", "d", "e", "f", "g", "h"
80
int main(int argc, char *argv[])
84
drizzle_result_st *result;
85
drizzle_return_t driz_ret;
94
CHECKED_QUERY("create table libdrizzle.t1 (a int primary key auto_increment, b tinyint, c smallint, d mediumint, e int, f bigint, g float, h double)");
96
/* Insert rows with pk 1 and 2 */
97
CHECKED_QUERY("insert into libdrizzle.t1 (b,c,d,e,f,g,h) values (1,1,1,1,1,1,1), (127,32687,8388351,2147352575,9222246136947920895,443664,291.2711110711098);");
98
ASSERT_EQ(drizzle_result_affected_rows(result), 2);
100
/* Insert row with pk 3 */
101
CHECKED_QUERY("insert into libdrizzle.t1 (b,c,d,e,f,g,h) ( select 0-b, 0-c, 0-d, 0-e, 0-f, g+1.015625, h+1 from t1 where a = 2 );");
102
ASSERT_EQ(drizzle_result_affected_rows(result), 1);
104
/* Insert row with pk 4 - test marshaling values we transmit */
105
query = "insert into libdrizzle.t1 (b,c,d,e,f,g,h) values (?,?,?,?,?,?,?)";
106
sth = drizzle_stmt_prepare(con, query, strlen(query), &driz_ret);
107
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, preparing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
108
CHECK(drizzle_stmt_set_tiny(sth, 0, 127, 0));
109
CHECK(drizzle_stmt_set_short(sth, 1, 32687, 0));
110
CHECK(drizzle_stmt_set_int(sth, 2, 8388351, 0));
111
CHECK(drizzle_stmt_set_int(sth, 3, 2147352575, 0));
112
CHECK(drizzle_stmt_set_bigint(sth, 4, 9222246136947920895, 0));
113
CHECK(drizzle_stmt_set_float(sth, 5, 443664.0));
114
CHECK(drizzle_stmt_set_double(sth, 6, 291.2711110711098));
115
driz_ret = drizzle_stmt_execute(sth);
116
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, executing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
117
driz_ret = drizzle_stmt_buffer(sth);
118
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, buffering \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
119
CHECK(drizzle_stmt_close(sth));
121
/* TODO: Also send some negative values of each type */
123
/* Read the table back, with values sent over the wire in text form */
124
CHECKED_QUERY("select * from libdrizzle.t1 order by b, a");
126
drizzle_result_buffer(result);
127
num_fields= drizzle_result_column_count(result);
129
ASSERT_EQ_(num_fields, 8, "Retrieved bad number of fields");
131
int readback_order[4] = { 3, 1, 2, 4 };
133
unsigned int cur_row= 0;
134
drizzle_column_st *column;
135
while ((row = drizzle_row_next(result)))
137
drizzle_column_seek(result, 0);
140
ASSERT_EQ(drizzle_row_current(result), cur_row);
141
ASSERT_TRUE(cur_row <= 4);
143
char expected_colA[10];
144
sprintf(expected_colA, "%d", readback_order[cur_row-1]);
145
ASSERT_EQ_(strcmp(row[0], expected_colA), 0, "Retrieved bad row value; row=%d got=%s expected=%s", cur_row, row[0], expected_colA);
147
while ((column= drizzle_column_next(result)))
150
ASSERT_EQ_(strcmp(drizzle_column_db(column), "libdrizzle"), 0, "Column has bad DB name");
151
ASSERT_EQ_(strcmp(drizzle_column_table(column), "t1"), 0, "Column had bad table name");
152
ASSERT_EQ(drizzle_column_current(result), cur_column);
153
ASSERT_STREQ(drizzle_column_name(column), column_names[cur_column]);
154
ASSERT_EQ_(drizzle_column_type(column), expected_column_types[cur_column], "Column %d has type=%d expected=%d", cur_column, drizzle_column_type(column), expected_column_types[cur_column]);
156
ASSERT_EQ_(cur_column, 8, "Wrong column count");
158
for (cur_column = 2; cur_column <= 6; cur_column ++) {
160
ASSERT_STREQ("1", row[cur_column-1]);
161
} else if (cur_row == 3 || cur_row == 4) {
163
snprintf(buf, 25, "%"PRIdMAX, column_maxes[cur_column-2]);
164
ASSERT_STREQ(buf, row[cur_column-1]);
165
} else if (cur_row == 1) {
167
snprintf(buf, 25, "-%"PRIdMAX, column_maxes[cur_column-2]);
168
ASSERT_STREQ(buf, row[cur_column-1]);
173
ASSERT_STREQ("443665", row[6]);
174
ASSERT_STREQ("292.2711110711098", row[7]);
177
if (cur_row == 3 || cur_row == 4) {
178
ASSERT_STREQ("443664", row[6]);
179
ASSERT_STREQ("291.2711110711098", row[7]);
184
/* Should have had 4 rows */
185
ASSERT_EQ_(cur_row, 4, "Retrieved bad number of rows");
187
drizzle_result_free(result);
189
/* Read the table back, with values sent over the wire in binary form */
190
query = "select a,b,c,d,e,f,g,h from libdrizzle.t1";
191
sth = drizzle_stmt_prepare(con, query, strlen(query), &driz_ret);
192
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, preparing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
193
driz_ret = drizzle_stmt_execute(sth);
194
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, executing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
195
driz_ret = drizzle_stmt_buffer(sth);
196
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, buffering \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
198
ASSERT_EQ(4, drizzle_stmt_row_count(sth));
200
while (drizzle_stmt_fetch(sth) != DRIZZLE_RETURN_ROW_END)
203
printf("Row %d\n", cur_row);
205
int columnA = drizzle_stmt_get_int(sth, 0, &driz_ret);
206
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), 1, cur_row);
209
intmax_t col_val, expect_val;
210
char expect_strval[64];
211
const char *col_strval;
215
for (cur_column = 2; cur_column <= 6; cur_column ++) {
218
expect_val = ( 0 - column_maxes[cur_column-2] );
225
expect_val = column_maxes[cur_column-2];
228
ASSERT_FALSE_(1, "Row %d has column.a = %u", cur_row, columnA);
231
/* These columns are 0-based */
233
col_val = drizzle_stmt_get_bigint(sth, cur_column-1, &driz_ret);
234
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), cur_column, cur_row);
235
col_strval = drizzle_stmt_get_string(sth, cur_column-1, <h, &driz_ret);
236
ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
237
ASSERT_EQ(lth, strlen(col_strval));
238
col_dblval = drizzle_stmt_get_double(sth, cur_column-1, &driz_ret);
239
ASSERT_TRUE_(driz_ret == DRIZZLE_RETURN_OK || driz_ret == DRIZZLE_RETURN_TRUNCATED, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), cur_column, cur_row);
241
printf(" Column %d: %"PRIdMAX" \"%s\" %f\n", cur_column, col_val, col_strval, col_dblval);
246
ASSERT_EQ_(expect_val, col_val, "Column %d of row %d: expected %"PRIdMAX", got %"PRIdMAX,
247
cur_column, cur_row, expect_val, col_val);
248
if (cur_column <= 5) {
249
uint32_t col_narrowval = drizzle_stmt_get_int(sth, cur_column-1, &driz_ret);
250
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), cur_column, cur_row);
251
ASSERT_EQ_(col_val, col_narrowval, "column %d of row %d: get_bigint returns %"PRIdMAX", get_int returns %"PRId32,
252
cur_column, cur_row, col_val, col_narrowval);
254
ASSERT_FLOATEQEXACT((double)expect_val, col_dblval);
256
snprintf(expect_strval, 64, "%"PRIdMAX, expect_val);
257
ASSERT_STREQ(expect_strval, col_strval);
260
float expect_floatval;
261
double expect_dblval;
264
expect_floatval = 1.0;
269
expect_floatval = 443664.0;
270
expect_dblval = 291.2711110711098;
273
expect_floatval = 443665.0;
274
expect_dblval = 292.2711110711098;
278
col_val = drizzle_stmt_get_int(sth, 6, &driz_ret);
279
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_TRUNCATED, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), cur_column, cur_row);
280
ASSERT_FLOATEQEXACT((float)col_val, trunc(expect_floatval));
282
col_val = drizzle_stmt_get_bigint(sth, 6, &driz_ret);
283
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_TRUNCATED, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), cur_column, cur_row);
284
ASSERT_FLOATEQEXACT((float)col_val, trunc(expect_floatval));
286
col_dblval = drizzle_stmt_get_double(sth, 6, &driz_ret);
287
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), cur_column, cur_row);
288
ASSERT_FLOATEQEXACT(col_dblval, expect_floatval);
290
col_strval = drizzle_stmt_get_string(sth, 6, <h, &driz_ret);
291
ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
293
printf(" Column %d: %"PRIdMAX" \"%s\" %f\n", 7, col_val, col_strval, col_dblval);
297
col_val = drizzle_stmt_get_int(sth, 7, &driz_ret);
298
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_TRUNCATED, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), cur_column, cur_row);
299
ASSERT_FLOATEQEXACT((double)col_val, trunc(expect_dblval));
301
col_val = drizzle_stmt_get_bigint(sth, 7, &driz_ret);
302
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_TRUNCATED, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), cur_column, cur_row);
303
ASSERT_FLOATEQEXACT((double)col_val, trunc(expect_dblval));
305
col_dblval = drizzle_stmt_get_double(sth, 7, &driz_ret);
306
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), cur_column, cur_row);
307
ASSERT_FLOATEQEXACT(col_dblval, expect_dblval);
309
col_strval = drizzle_stmt_get_string(sth, 7, <h, &driz_ret);
310
ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
312
printf(" Column %d: %"PRIdMAX" \"%s\" %f\n", 8, col_val, col_strval, col_dblval);
315
ASSERT_EQ(cur_row, 4);
317
driz_ret = drizzle_stmt_close(sth);
318
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s", drizzle_strerror(driz_ret), drizzle_error(con));
320
drizzle_query(con, "DROP TABLE libdrizzle.t1", 0, &driz_ret);
321
ASSERT_EQ_(DRIZZLE_RETURN_OK, driz_ret, "DROP TABLE libdrizzle.t1");