Merge lp:~wiml/libdrizzle/unit-tests into lp:libdrizzle

Proposed by Wim Lewis
Status: Merged
Approved by: Andrew Hutchings
Approved revision: no longer in the source branch.
Merged at revision: 110
Proposed branch: lp:~wiml/libdrizzle/unit-tests
Merge into: lp:libdrizzle
Diff against target: 1326 lines (+1094/-59)
11 files modified
Makefile.am (+1/-0)
libdrizzle/statement.cc (+1/-0)
tests/unit/binlog.cc (+5/-14)
tests/unit/column.c (+11/-31)
tests/unit/common.c (+93/-0)
tests/unit/common.h (+26/-8)
tests/unit/connect_uds.c (+2/-2)
tests/unit/datetypes.c (+330/-0)
tests/unit/include.am (+21/-4)
tests/unit/nulls.c (+278/-0)
tests/unit/numbers.c (+326/-0)
To merge this branch: bzr merge lp:~wiml/libdrizzle/unit-tests
Reviewer Review Type Date Requested Status
Andrew Hutchings Approve
Review via email: mp+154480@code.launchpad.net

Commit message

Additional unit tests and unit-test cleanup.

Description of the change

Wrote a few more unit tests to cover API I want to use. They currently fail, unfortunately, so I marked them XFAIL. I plan to fix some and file bugs for the rest.

I also rearranged common unit test code a little bit to put it in common.h/common.c, after the discussion in https://code.launchpad.net/~wiml/libdrizzle/unit-tests/+merge/151659 .

To post a comment you must log in.
Revision history for this message
Andrew Hutchings (linuxjedi) wrote :

Thanks for catching these. If there are any you want me to fix please let me know and I'll try and look over the weekend.

review: Approve
lp:~wiml/libdrizzle/unit-tests updated
110. By Drizzle Continuous Integration

Merge lp:~wiml/libdrizzle/unit-tests Build: jenkins-Libdrizzle-75

Revision history for this message
Wim Lewis (wiml-omni) wrote :

There are fixes for some of them in my date-time branch, lp:~wiml-omni/libdrizzle/date-time . I can't justify spending a whole lot more of my employer's time on this, though, so I'm winding down --- I'll be filing a few more bugs w/o fixes probably for someone else to deal with.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile.am'
2--- Makefile.am 2013-01-18 13:33:00 +0000
3+++ Makefile.am 2013-03-20 18:43:44 +0000
4@@ -6,6 +6,7 @@
5 SUFFIXES =
6 .PHONY =
7 TESTS =
8+XFAIL_TESTS =
9 CLEANFILES =
10 DISTCLEANFILES =
11 bin_PROGRAMS =
12
13=== modified file 'libdrizzle/statement.cc'
14--- libdrizzle/statement.cc 2013-03-11 17:27:16 +0000
15+++ libdrizzle/statement.cc 2013-03-20 18:43:44 +0000
16@@ -441,6 +441,7 @@
17 param->length= 0;
18 break;
19 case DRIZZLE_COLUMN_TYPE_TINY:
20+ param->data= param->data_buffer;
21 *(uint8_t*)param->data= *row[column_counter];
22 break;
23 case DRIZZLE_COLUMN_TYPE_SHORT:
24
25=== modified file 'tests/unit/binlog.cc'
26--- tests/unit/binlog.cc 2013-01-28 01:04:53 +0000
27+++ tests/unit/binlog.cc 2013-03-20 18:43:44 +0000
28@@ -40,7 +40,7 @@
29
30 #include <libdrizzle-5.1/libdrizzle.h>
31
32-#include "tests/unit/cleanup.h"
33+#include "tests/unit/common.h"
34
35 #include <cstdio>
36 #include <cstdlib>
37@@ -72,19 +72,10 @@
38 (void) argc;
39 (void) argv;
40 drizzle_binlog_st *binlog;
41-
42- con= drizzle_create(getenv("MYSQL_SERVER"),
43- getenv("MYSQL_PORT") ? atoi("MYSQL_PORT") : DRIZZLE_DEFAULT_TCP_PORT,
44- getenv("MYSQL_USER"),
45- getenv("MYSQL_PASSWORD"),
46- getenv("MYSQL_SCHEMA"), NULL);
47-
48- CLOSE_ON_EXIT(con);
49- ASSERT_NOT_NULL_(con, "Drizzle connection object creation error");
50-
51- drizzle_return_t ret= drizzle_connect(con);
52- SKIP_IF_(ret == DRIZZLE_RETURN_COULD_NOT_CONNECT, "%s(%s)", drizzle_error(con), drizzle_strerror(ret));
53- ASSERT_EQ_(DRIZZLE_RETURN_OK, ret, "%s(%s)", drizzle_error(con), drizzle_strerror(ret));
54+ drizzle_return_t ret;
55+
56+ set_up_connection();
57+
58 binlog= drizzle_binlog_init(con, binlog_event, binlog_error, NULL, true);
59 ret= drizzle_binlog_start(binlog, 0, "", 0);
60 SKIP_IF_(ret == DRIZZLE_RETURN_ERROR_CODE, "Binlog is not open?: %s(%s)", drizzle_error(con), drizzle_strerror(ret));
61
62=== modified file 'tests/unit/column.c'
63--- tests/unit/column.c 2013-03-04 22:18:50 +0000
64+++ tests/unit/column.c 2013-03-20 18:43:44 +0000
65@@ -36,7 +36,7 @@
66 */
67
68 #include <yatl/lite.h>
69-#include "tests/unit/cleanup.h"
70+#include "tests/unit/common.h"
71
72 #include <libdrizzle-5.1/libdrizzle.h>
73
74@@ -45,42 +45,24 @@
75 #include <stdlib.h>
76 #include <inttypes.h>
77
78-#define CHECKED_QUERY(cmd) drizzle_query(con, cmd, 0, &ret); ASSERT_EQ_(ret, DRIZZLE_RETURN_OK, "Error (%s): %s, from \"%s\"", drizzle_strerror(ret), drizzle_error(con), cmd);
79-
80 int main(int argc, char *argv[])
81 {
82 (void) argc;
83 (void) argv;
84 drizzle_row_t row;
85 int num_fields;
86-
87- con= drizzle_create(getenv("MYSQL_SERVER"),
88- getenv("MYSQL_PORT") ? atoi("MYSQL_PORT") : DRIZZLE_DEFAULT_TCP_PORT,
89- getenv("MYSQL_USER"),
90- getenv("MYSQL_PASSWORD"),
91- getenv("MYSQL_SCHEMA"), 0);
92- ASSERT_NOT_NULL_(con, "Drizzle connection object creation error");
93- CLOSE_ON_EXIT(con);
94-
95- drizzle_return_t ret= drizzle_connect(con);
96- SKIP_IF_(ret == DRIZZLE_RETURN_COULD_NOT_CONNECT, "%s", drizzle_strerror(ret));
97- ASSERT_EQ_(DRIZZLE_RETURN_OK, ret, "%s(%s)", drizzle_error(con), drizzle_strerror(ret));
98-
99- CHECKED_QUERY("DROP SCHEMA IF EXISTS libdrizzle");
100-
101+ drizzle_result_st *result;
102+ drizzle_return_t driz_ret;
103+
104+ set_up_connection();
105 CHECKED_QUERY("SET CHARACTER SET latin1"); /* Or any other one-byte-per-character character set */
106-
107- CHECKED_QUERY("CREATE SCHEMA libdrizzle");
108-
109- ret= drizzle_select_db(con, "libdrizzle");
110- ASSERT_EQ_(DRIZZLE_RETURN_OK, ret, "USE libdrizzle");
111+ set_up_schema();
112
113 CHECKED_QUERY("create table libdrizzle.t1 (a int primary key auto_increment, b varchar(255), c timestamp default current_timestamp)");
114
115 CHECKED_QUERY("insert into libdrizzle.t1 (b) values ('this'),('is'),('war')");
116
117- drizzle_result_st *result= drizzle_query(con, "select * from libdrizzle.t1", 0, &ret);
118- ASSERT_TRUE_(ret == DRIZZLE_RETURN_OK, "select * from libdrizzle.t1");
119+ CHECKED_QUERY("select * from libdrizzle.t1");
120
121 drizzle_result_buffer(result);
122 num_fields= drizzle_result_column_count(result);
123@@ -107,9 +89,9 @@
124 ASSERT_EQ_(drizzle_column_type(column), DRIZZLE_COLUMN_TYPE_LONG, "Column type wrong");
125 break;
126 case 2:
127- ASSERT_EQ_(drizzle_column_max_size(column), 255, "Column max size wrong %zu != 255", drizzle_column_max_size(column));
128+ ASSERT_EQ_(drizzle_column_max_size(column), 255, "Column max size wrong %zu != 255", (size_t)drizzle_column_max_size(column));
129
130- ASSERT_EQ_(drizzle_column_charset(column), DRIZZLE_CHARSET_LATIN1_SWEDISH_CI, "Column charset wrong, %d != %d", drizzle_column_charset(column), DRIZZLE_CHARSET_UTF8_BIN);
131+ ASSERT_EQ_(drizzle_column_charset(column), DRIZZLE_CHARSET_LATIN1_SWEDISH_CI, "Column charset wrong, %d != %d", drizzle_column_charset(column), DRIZZLE_CHARSET_LATIN1_SWEDISH_CI);
132 break;
133 case 3:
134 ASSERT_EQ_(drizzle_column_type(column), DRIZZLE_COLUMN_TYPE_TIMESTAMP, "Column type wrong");
135@@ -123,11 +105,9 @@
136
137 drizzle_result_free(result);
138
139- drizzle_query(con, "DROP TABLE libdrizzle.t1", 0, &ret);
140- ASSERT_EQ_(DRIZZLE_RETURN_OK, ret, "DROP TABLE libdrizzle.t1");
141+ CHECKED_QUERY("DROP TABLE libdrizzle.t1");
142
143- drizzle_query(con, "DROP SCHEMA IF EXISTS libdrizzle", 0, &ret);
144- ASSERT_EQ_(DRIZZLE_RETURN_OK, ret, "DROP SCHEMA libdrizzle (%s)", drizzle_error(con));
145+ tear_down_schema();
146
147 return EXIT_SUCCESS;
148 }
149
150=== added file 'tests/unit/common.c'
151--- tests/unit/common.c 1970-01-01 00:00:00 +0000
152+++ tests/unit/common.c 2013-03-20 18:43:44 +0000
153@@ -0,0 +1,93 @@
154+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
155+ *
156+ * Drizzle Client & Protocol Library
157+ *
158+ * Copyright (C) 2013 Drizzle Developer Group
159+ * All rights reserved.
160+ *
161+ * Redistribution and use in source and binary forms, with or without
162+ * modification, are permitted provided that the following conditions are
163+ * met:
164+ *
165+ * * Redistributions of source code must retain the above copyright
166+ * notice, this list of conditions and the following disclaimer.
167+ *
168+ * * Redistributions in binary form must reproduce the above
169+ * copyright notice, this list of conditions and the following disclaimer
170+ * in the documentation and/or other materials provided with the
171+ * distribution.
172+ *
173+ * * The names of its contributors may not be used to endorse or
174+ * promote products derived from this software without specific prior
175+ * written permission.
176+ *
177+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
178+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
179+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
180+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
181+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
182+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
183+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
184+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
185+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
186+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
187+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
188+ *
189+ */
190+
191+#include "common.h"
192+#include <yatl/lite.h>
193+
194+drizzle_st *con= NULL;
195+
196+void close_connection_on_exit(void)
197+{
198+ if (con == NULL) {
199+ return;
200+ }
201+
202+ drizzle_return_t ret= drizzle_quit(con);
203+ ASSERT_EQ_(DRIZZLE_RETURN_OK, ret, "drizzle_quit() : %s", drizzle_strerror(ret));
204+ con= NULL;
205+}
206+
207+/* Common connection setup used by the unit tests.
208+ * Connects to the server, deletes and recreates the libdrizzle schema.
209+ */
210+void set_up_connection(void)
211+{
212+ drizzle_return_t driz_ret;
213+
214+ ASSERT_NULL_(con, "con opened twice?");
215+
216+ con= drizzle_create(getenv("MYSQL_SERVER"),
217+ getenv("MYSQL_PORT") ? atoi("MYSQL_PORT") : DRIZZLE_DEFAULT_TCP_PORT,
218+ getenv("MYSQL_USER"),
219+ getenv("MYSQL_PASSWORD"),
220+ getenv("MYSQL_SCHEMA"), 0);
221+ ASSERT_NOT_NULL_(con, "Drizzle connection object creation error");
222+ atexit(close_connection_on_exit);
223+
224+ driz_ret= drizzle_connect(con);
225+ SKIP_IF_(driz_ret == DRIZZLE_RETURN_COULD_NOT_CONNECT, "%s", drizzle_strerror(driz_ret));
226+ ASSERT_EQ_(DRIZZLE_RETURN_OK, driz_ret, "%s(%s)", drizzle_error(con), drizzle_strerror(driz_ret));
227+}
228+
229+void set_up_schema(void)
230+{
231+ drizzle_result_st *result;
232+ drizzle_return_t driz_ret;
233+
234+ CHECKED_QUERY("DROP SCHEMA IF EXISTS libdrizzle");
235+ CHECKED_QUERY("CREATE SCHEMA libdrizzle");
236+ CHECK(drizzle_select_db(con, "libdrizzle"));
237+}
238+
239+void tear_down_schema(void)
240+{
241+ drizzle_result_st *result;
242+ drizzle_return_t driz_ret;
243+
244+ CHECKED_QUERY("DROP SCHEMA IF EXISTS libdrizzle");
245+}
246+
247
248=== renamed file 'tests/unit/cleanup.h' => 'tests/unit/common.h'
249--- tests/unit/cleanup.h 2013-03-04 22:03:56 +0000
250+++ tests/unit/common.h 2013-03-20 18:43:44 +0000
251@@ -40,6 +40,7 @@
252 #ifdef __cplusplus
253 # include <cstdlib>
254 # include <cstdio>
255+extern "C" {
256 #else
257 # include <stdlib.h>
258 # include <stdio.h>
259@@ -47,12 +48,29 @@
260
261 #include <libdrizzle-5.1/libdrizzle.h>
262
263-static drizzle_st *con= NULL;
264-static void close_connection_on_exit(void)
265-{
266- drizzle_return_t ret= drizzle_quit(con);
267- ASSERT_EQ_(DRIZZLE_RETURN_OK, ret, "drizzle_quit() : %s", drizzle_strerror(ret));
268-}
269-
270-#define CLOSE_ON_EXIT(__connection) atexit(close_connection_on_exit);
271+
272+extern drizzle_st *con;
273+
274+/* Common connection setup used by the unit tests.
275+ */
276+extern void set_up_connection(void);
277+
278+extern void close_connection_on_exit(void);
279+
280+/* For unit tests that make tables, etc.: delete-and-recreate the schema on setup, and delete the schema on teardown. */
281+extern void set_up_schema(void);
282+extern void tear_down_schema(void);
283+
284+#ifdef __cplusplus
285+} /* extern "C" */
286+#endif
287+
288+/* Perform a query; assign the result to 'result' and the returncode to 'driz_ret'; assert that the returncode is DRIZZLE_RETURN_OK. */
289+#define CHECKED_QUERY(cmd) result = drizzle_query(con, cmd, 0, &driz_ret); \
290+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, from \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), cmd);
291+
292+/* Call a libdrizzle function that just returns a drizzle_return_t. Assign the return to 'driz_ret' and assert that it is DRIZZLE_RETURN_OK. */
293+#define CHECK(s) driz_ret = (s); \
294+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, in \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), #s);
295+
296
297
298=== modified file 'tests/unit/connect_uds.c'
299--- tests/unit/connect_uds.c 2013-01-27 13:01:06 +0000
300+++ tests/unit/connect_uds.c 2013-03-20 18:43:44 +0000
301@@ -37,7 +37,7 @@
302
303 #include <yatl/lite.h>
304
305-#include "tests/unit/cleanup.h"
306+#include "tests/unit/common.h"
307
308 #include <libdrizzle-5.1/libdrizzle.h>
309 #include <stdio.h>
310@@ -54,8 +54,8 @@
311 getenv("MYSQL_USER"),
312 getenv("MYSQL_PASSWORD"),
313 getenv("MYSQL_SCHEMA"), 0);
314- CLOSE_ON_EXIT(con);
315 ASSERT_NOT_NULL_(con, "Drizzle connection object creation error");
316+ atexit(close_connection_on_exit);
317
318 drizzle_return_t ret= drizzle_connect(con);
319 SKIP_IF_(ret == DRIZZLE_RETURN_COULD_NOT_CONNECT, "%s(%s)", drizzle_error(con), drizzle_strerror(ret));
320
321=== added file 'tests/unit/datetypes.c'
322--- tests/unit/datetypes.c 1970-01-01 00:00:00 +0000
323+++ tests/unit/datetypes.c 2013-03-20 18:43:44 +0000
324@@ -0,0 +1,330 @@
325+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
326+ *
327+ * Drizzle Client & Protocol Library
328+ *
329+ * Copyright (C) 2013 Drizzle Developer Group
330+ * All rights reserved.
331+ *
332+ * Redistribution and use in source and binary forms, with or without
333+ * modification, are permitted provided that the following conditions are
334+ * met:
335+ *
336+ * * Redistributions of source code must retain the above copyright
337+ * notice, this list of conditions and the following disclaimer.
338+ *
339+ * * Redistributions in binary form must reproduce the above
340+ * copyright notice, this list of conditions and the following disclaimer
341+ * in the documentation and/or other materials provided with the
342+ * distribution.
343+ *
344+ * * The names of its contributors may not be used to endorse or
345+ * promote products derived from this software without specific prior
346+ * written permission.
347+ *
348+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
349+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
350+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
351+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
352+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
353+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
354+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
355+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
356+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
357+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
358+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
359+ *
360+ */
361+
362+#include <yatl/lite.h>
363+#include "tests/unit/common.h"
364+
365+#include <libdrizzle-5.1/libdrizzle.h>
366+
367+#include <stdio.h>
368+#include <string.h>
369+#include <stdlib.h>
370+#include <inttypes.h>
371+
372+#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);
373+
374+#define CHECK(s) driz_ret = (s); ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, in \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), #s);
375+
376+static const drizzle_column_type_t expected_column_types[10] = {
377+ DRIZZLE_COLUMN_TYPE_NONE, /* Columns are 1-indexed */
378+
379+ DRIZZLE_COLUMN_TYPE_LONG,
380+
381+ DRIZZLE_COLUMN_TYPE_DATE,
382+ DRIZZLE_COLUMN_TYPE_YEAR,
383+ DRIZZLE_COLUMN_TYPE_TIMESTAMP,
384+ DRIZZLE_COLUMN_TYPE_TIMESTAMP,
385+ DRIZZLE_COLUMN_TYPE_TIME,
386+ DRIZZLE_COLUMN_TYPE_TIME,
387+ DRIZZLE_COLUMN_TYPE_DATETIME,
388+// DRIZZLE_COLUMN_TYPE_NEWDATE,
389+ DRIZZLE_COLUMN_TYPE_DATETIME,
390+};
391+
392+static const char *column_names[10] = {
393+ NULL,
394+ "a", "b", "c", "d", "e", "f", "g", "h", "i"
395+};
396+
397+int main(int argc, char *argv[])
398+{
399+ (void) argc;
400+ (void) argv;
401+ drizzle_result_st *result;
402+ drizzle_return_t driz_ret;
403+ drizzle_row_t row;
404+ int num_fields;
405+ const char *query;
406+ drizzle_stmt_st *sth;
407+ unsigned rows_in_table;
408+
409+ set_up_connection();
410+ set_up_schema();
411+
412+ CHECKED_QUERY("create table libdrizzle.dt1 (a int primary key not null, b date, c year(4), d timestamp(0), e timestamp(6), f time(0), g time(6), h datetime(0), i datetime(6))");
413+ rows_in_table = 0;
414+
415+ /* Insert rows with pk 1 and 2 */
416+ CHECKED_QUERY("insert into libdrizzle.dt1 (a,b,c,d,e,f,g,h,i) values "
417+ "(1, '1970-01-01', '2112', '2013-03-13 09:22:00.001', '2013-03-13 09:22:00.001', '6:15:03', '23:59:59.75', '1642-12-25 12:15:01', '1642-12-25 12:12:00.125'),"
418+ "(2, '84-02-29', '12', NOW(), NOW(), '3 6:15:03', '23:59:59.0625', '1642-12-25 12:15:01', '1642-12-25 12:12:00.000000');");
419+ ASSERT_EQ(drizzle_result_affected_rows(result), 2);
420+ rows_in_table += 2;
421+
422+ /* Insert row with pk 3 and 4 - test marshaling values we transmit */
423+ query = "insert into libdrizzle.dt1 (a,b,c,d,e,f,g,h,i) values (?,?,?,?,?,?,?,?,?)";
424+ sth = drizzle_stmt_prepare(con, query, strlen(query), &driz_ret);
425+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, preparing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
426+
427+ /* Row 3 should be the same as row 1, above */
428+ CHECK(drizzle_stmt_set_short(sth, 0, 3, 0));
429+ CHECK(drizzle_stmt_set_timestamp(sth, 1, 1970, 1, 1, 0, 0, 0, 0));
430+ CHECK(drizzle_stmt_set_int(sth, 2, 2112, 0));
431+ CHECK(drizzle_stmt_set_timestamp(sth, 3, 2013, 3, 13, 9, 22, 0, 1000));
432+ CHECK(drizzle_stmt_set_timestamp(sth, 4, 2013, 3, 13, 9, 22, 0, 1000));
433+ CHECK(drizzle_stmt_set_time(sth, 5, 0, 6, 15, 3, 0, 0));
434+ CHECK(drizzle_stmt_set_time(sth, 6, 0, 23, 59, 59, 750000, 0));
435+ CHECK(drizzle_stmt_set_timestamp(sth, 7, 1642, 12, 25, 12, 15, 1, 0));
436+ CHECK(drizzle_stmt_set_timestamp(sth, 8, 1642, 12, 25, 12, 12, 0, 125000));
437+
438+ driz_ret = drizzle_stmt_execute(sth);
439+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, executing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
440+ driz_ret = drizzle_stmt_buffer(sth);
441+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, buffering \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
442+ rows_in_table ++;
443+
444+ /* Row 4 is similar to row 2, above. But 2-digit years aren't automatically y2k-promoted if we send them raw. */
445+ CHECK(drizzle_stmt_set_short(sth, 0, 4, 0));
446+ CHECK(drizzle_stmt_set_timestamp(sth, 1, 84, 2, 9, 0, 0, 0, 0));
447+ CHECK(drizzle_stmt_set_int(sth, 2, 12, 0)); /* 12 will become 2012 because we're sending an int, not a YEAR */
448+ CHECK(drizzle_stmt_set_timestamp(sth, 3, 2013, 3, 13, 9, 22, 0, 1000));
449+ CHECK(drizzle_stmt_set_timestamp(sth, 4, 2013, 3, 13, 9, 22, 0, 1000));
450+ CHECK(drizzle_stmt_set_time(sth, 5, 3, 6, 15, 3, 0, 0));
451+ CHECK(drizzle_stmt_set_time(sth, 6, 0, 23, 59, 59, 62500, 0));
452+ CHECK(drizzle_stmt_set_timestamp(sth, 7, 1642, 12, 25, 12, 15, 1, 0));
453+ CHECK(drizzle_stmt_set_timestamp(sth, 8, 1642, 12, 25, 12, 12, 0, 0));
454+
455+ driz_ret = drizzle_stmt_execute(sth);
456+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, executing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
457+ driz_ret = drizzle_stmt_buffer(sth);
458+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, buffering \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
459+ rows_in_table ++;
460+
461+ CHECK(drizzle_stmt_close(sth));
462+
463+ /* Read the table back, with values sent over the wire in text form */
464+ CHECKED_QUERY("select * from libdrizzle.dt1 order by a");
465+
466+ drizzle_result_buffer(result);
467+ num_fields= drizzle_result_column_count(result);
468+
469+ ASSERT_EQ_(num_fields, 9, "Retrieved bad number of fields");
470+
471+ unsigned int cur_row= 0;
472+ drizzle_column_st *column;
473+ while ((row = drizzle_row_next(result)))
474+ {
475+ drizzle_column_seek(result, 0);
476+ int cur_column= 0;
477+ cur_row++;
478+ ASSERT_EQ(drizzle_row_current(result), cur_row);
479+ ASSERT_TRUE(cur_row <= 4);
480+
481+ char expected_colA[10];
482+ sprintf(expected_colA, "%d", cur_row);
483+ ASSERT_EQ_(strcmp(row[0], expected_colA), 0, "Retrieved bad row value; row=%d got=%s expected=%s", cur_row, row[0], expected_colA);
484+
485+ while ((column= drizzle_column_next(result)))
486+ {
487+ cur_column++;
488+ ASSERT_EQ_(strcmp(drizzle_column_db(column), "libdrizzle"), 0, "Column has bad DB name");
489+ ASSERT_EQ_(strcmp(drizzle_column_table(column), "dt1"), 0, "Column %d had bad table name", cur_column);
490+ ASSERT_EQ(drizzle_column_current(result), cur_column);
491+ ASSERT_STREQ_(drizzle_column_name(column), column_names[cur_column], "Column %d name", cur_column);
492+ 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]);
493+ }
494+ ASSERT_EQ_(cur_column, 9, "Wrong column count");
495+
496+ if (cur_row == 1 || cur_row == 3) {
497+ ASSERT_STREQ("1970-01-01", row[1]);
498+ ASSERT_STREQ("2112", row[2]);
499+ ASSERT_STREQ("06:15:03", row[5]);
500+ ASSERT_STREQ("23:59:59.750000", row[6]);
501+ ASSERT_STREQ("1642-12-25 12:15:01", row[7]);
502+ ASSERT_STREQ("1642-12-25 12:12:00.125000", row[8]);
503+ }
504+
505+ if (cur_row == 2) {
506+ ASSERT_STREQ("1984-02-29", row[1]);
507+ ASSERT_STREQ("2012", row[2]);
508+ } else if (cur_row == 4) {
509+ ASSERT_STREQ("0084-02-09", row[1]);
510+ ASSERT_STREQ("2012", row[2]);
511+ }
512+
513+ if (cur_row == 2 || cur_row == 4) {
514+ ASSERT_STREQ("78:15:03", row[5]);
515+ ASSERT_STREQ("23:59:59.062500", row[6]);
516+ ASSERT_STREQ("1642-12-25 12:15:01", row[7]);
517+ ASSERT_STREQ("1642-12-25 12:12:00.000000", row[8]);
518+ }
519+ }
520+ ASSERT_EQ_(cur_row, rows_in_table, "Retrieved bad number of rows");
521+
522+ drizzle_result_free(result);
523+
524+ /* Read the table back, with values sent over the wire in binary form */
525+ query = "select a,b,c,d,e,f,g,h,i from libdrizzle.dt1 order by a";
526+ sth = drizzle_stmt_prepare(con, query, strlen(query), &driz_ret);
527+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, preparing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
528+ driz_ret = drizzle_stmt_execute(sth);
529+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, executing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
530+ driz_ret = drizzle_stmt_buffer(sth);
531+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, buffering \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
532+
533+ ASSERT_EQ(rows_in_table, drizzle_stmt_row_count(sth));
534+ cur_row = 0;
535+ while (drizzle_stmt_fetch(sth) != DRIZZLE_RETURN_ROW_END)
536+ {
537+ size_t lth;
538+ const char *col_strval;
539+ int col_intval;
540+
541+ cur_row ++;
542+ printf("Row %d\n", cur_row);
543+
544+ int columnA = drizzle_stmt_get_int(sth, 0, &driz_ret);
545+ 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);
546+ ASSERT_EQ(cur_row, (unsigned)columnA);
547+
548+#define ASSERT_COL_STREQ_(coln, expected, ...) \
549+ col_strval = drizzle_stmt_get_string(sth, coln-1, &lth, &driz_ret); \
550+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Fetching column %u of row %u", coln, cur_row); \
551+ ASSERT_STREQ_(expected, col_strval, "Stringified value of column %u of row %u", coln, cur_row); \
552+ ASSERT_EQ_(lth, strlen(col_strval), "Length of stringified value of column %u of row %u", coln, cur_row);
553+
554+ switch (cur_row) {
555+ case 1:
556+ case 3:
557+ ASSERT_COL_STREQ_(2, "1970-01-01");
558+ ASSERT_COL_STREQ_(3, "2112");
559+ ASSERT_COL_STREQ_(6, "06:15:03");
560+ ASSERT_COL_STREQ_(7, "23:59:59.750000");
561+ ASSERT_COL_STREQ_(8, "1642-12-25 12:15:01");
562+ ASSERT_COL_STREQ_(9, "1642-12-25 12:12:00.125000");
563+ break;
564+ case 2:
565+ case 4:
566+ ASSERT_COL_STREQ_(3, "2012");
567+ ASSERT_COL_STREQ_(6, "78:15:03");
568+ ASSERT_COL_STREQ_(7, "23:59:59.062500");
569+ ASSERT_COL_STREQ_(8, "1642-12-25 12:15:01");
570+ ASSERT_COL_STREQ_(9, "1642-12-25 12:12:00.000000");
571+ break;
572+ }
573+
574+ if (cur_row == 2) {
575+ ASSERT_COL_STREQ_(2, "1984-02-29");
576+ } else if (cur_row == 4) {
577+ ASSERT_COL_STREQ_(2, "0084-02-29"); /* Yes, year 84, during the reign of Domitian */
578+ }
579+
580+ /* TODO: libdrizzle currently has no way to give us access to the actual returned values for time/date fields. If that changes, test the values here. */
581+
582+ col_intval = drizzle_stmt_get_int(sth, 3-1, &driz_ret);
583+ ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
584+ switch (cur_row) {
585+ case 1:
586+ case 3:
587+ ASSERT_EQ(2112, col_intval);
588+ break;
589+ case 2:
590+ case 4:
591+ ASSERT_EQ(2012, col_intval);
592+ break;
593+ }
594+ }
595+ ASSERT_EQ(cur_row, rows_in_table);
596+ driz_ret = drizzle_stmt_close(sth);
597+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s", drizzle_strerror(driz_ret), drizzle_error(con));
598+
599+ /* Check that libdrizzle stringifies values the same way the server does */
600+ for (unsigned checking_column = 2; checking_column < 10; checking_column ++) {
601+ const char *col_name = column_names[checking_column];
602+ char *query_buf = NULL;
603+ asprintf(&query_buf, "select a, %s, cast(%s as char) from libdrizzle.dt1",
604+ col_name, col_name);
605+ query = query_buf;
606+
607+ sth = drizzle_stmt_prepare(con, query, strlen(query), &driz_ret);
608+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, preparing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
609+ driz_ret = drizzle_stmt_execute(sth);
610+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, executing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
611+ driz_ret = drizzle_stmt_buffer(sth);
612+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, buffering \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
613+
614+ free(query_buf);
615+ query_buf = NULL;
616+ query = NULL;
617+
618+ ASSERT_EQ(rows_in_table, drizzle_stmt_row_count(sth));
619+ cur_row = 0;
620+ while (drizzle_stmt_fetch(sth) != DRIZZLE_RETURN_ROW_END)
621+ {
622+ size_t server_strval_lth, drizzle_strval_lth;
623+ const char *server_strval, *drizzle_strval;
624+
625+ cur_row ++;
626+
627+ unsigned columnA = drizzle_stmt_get_int(sth, 0, &driz_ret);
628+ ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
629+
630+ drizzle_strval = drizzle_stmt_get_string(sth, 1, &drizzle_strval_lth, &driz_ret);
631+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Raw column '%s' of row %u", col_name, columnA);
632+ ASSERT_EQ(strlen(drizzle_strval), drizzle_strval_lth);
633+
634+ server_strval = drizzle_stmt_get_string(sth, 2, &server_strval_lth, &driz_ret);
635+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Cast column '%s' of row %u", col_name, columnA);
636+ ASSERT_EQ(strlen(server_strval), server_strval_lth);
637+
638+ printf("row=%u col=%s: '%s' / '%s'\n",
639+ columnA, col_name, drizzle_strval, server_strval);
640+
641+ ASSERT_STREQ_(server_strval, drizzle_strval, "Row %u, column '%s': server strval does not match libdrizzle strval", columnA, col_name);
642+ }
643+ ASSERT_EQ(rows_in_table, cur_row);
644+
645+ driz_ret = drizzle_stmt_close(sth);
646+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s", drizzle_strerror(driz_ret), drizzle_error(con));
647+ }
648+
649+ CHECKED_QUERY("DROP TABLE libdrizzle.dt1");
650+
651+ tear_down_schema();
652+
653+ return EXIT_SUCCESS;
654+}
655
656=== modified file 'tests/unit/include.am'
657--- tests/unit/include.am 2013-01-27 01:57:09 +0000
658+++ tests/unit/include.am 2013-03-20 18:43:44 +0000
659@@ -2,9 +2,9 @@
660 # included from Top Level Makefile.am
661 # All paths should be given relative to the root
662
663-noinst_HEADERS+= tests/unit/cleanup.h
664+noinst_HEADERS+= tests/unit/common.h
665
666-tests_unit_binlog_SOURCES= tests/unit/binlog.cc
667+tests_unit_binlog_SOURCES= tests/unit/binlog.cc tests/unit/common.c
668 tests_unit_binlog_LDADD= libdrizzle/libdrizzle.la
669 check_PROGRAMS+= tests/unit/binlog
670 noinst_PROGRAMS+= tests/unit/binlog
671@@ -33,7 +33,7 @@
672 check_PROGRAMS+= tests/unit/query
673 noinst_PROGRAMS+= tests/unit/query
674
675-tests_unit_column_SOURCES= tests/unit/column.c
676+tests_unit_column_SOURCES= tests/unit/column.c tests/unit/common.c
677 tests_unit_column_LDADD= libdrizzle/libdrizzle.la
678 check_PROGRAMS+= tests/unit/column
679 noinst_PROGRAMS+= tests/unit/column
680@@ -47,6 +47,23 @@
681 check-column: tests/unit/column
682 tests/unit/column
683
684+tests_unit_numbers_SOURCES= tests/unit/numbers.c tests/unit/common.c
685+tests_unit_numbers_LDADD= libdrizzle/libdrizzle.la
686+check_PROGRAMS+= tests/unit/numbers
687+noinst_PROGRAMS+= tests/unit/numbers
688+
689+tests_unit_datetypes_SOURCES= tests/unit/datetypes.c tests/unit/common.c
690+tests_unit_datetypes_LDADD= libdrizzle/libdrizzle.la
691+check_PROGRAMS+= tests/unit/datetypes
692+noinst_PROGRAMS+= tests/unit/datetypes
693+XFAIL_TESTS+= tests/unit/datetypes
694+
695+tests_unit_nulls_SOURCES= tests/unit/nulls.c tests/unit/common.c
696+tests_unit_nulls_LDADD= libdrizzle/libdrizzle.la
697+check_PROGRAMS+= tests/unit/nulls
698+noinst_PROGRAMS+= tests/unit/nulls
699+# Currently fails due to https://bugs.launchpad.net/libdrizzle/+bug/1150195
700+XFAIL_TESTS+= tests/unit/nulls
701
702 tests_unit_row_SOURCES= tests/unit/row.c
703 tests_unit_row_LDADD= libdrizzle/libdrizzle.la
704@@ -77,7 +94,7 @@
705 check-connect: tests/unit/connect
706 tests/unit/connect
707
708-tests_unit_connect_uds_SOURCES= tests/unit/connect_uds.c
709+tests_unit_connect_uds_SOURCES= tests/unit/connect_uds.c tests/unit/common.c
710 tests_unit_connect_uds_LDADD= libdrizzle/libdrizzle.la
711 check_PROGRAMS+= tests/unit/connect_uds
712 noinst_PROGRAMS+= tests/unit/connect_uds
713
714=== added file 'tests/unit/nulls.c'
715--- tests/unit/nulls.c 1970-01-01 00:00:00 +0000
716+++ tests/unit/nulls.c 2013-03-20 18:43:44 +0000
717@@ -0,0 +1,278 @@
718+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
719+ *
720+ * Drizzle Client & Protocol Library
721+ *
722+ * Copyright (C) 2013 Drizzle Developer Group
723+ * All rights reserved.
724+ *
725+ * Redistribution and use in source and binary forms, with or without
726+ * modification, are permitted provided that the following conditions are
727+ * met:
728+ *
729+ * * Redistributions of source code must retain the above copyright
730+ * notice, this list of conditions and the following disclaimer.
731+ *
732+ * * Redistributions in binary form must reproduce the above
733+ * copyright notice, this list of conditions and the following disclaimer
734+ * in the documentation and/or other materials provided with the
735+ * distribution.
736+ *
737+ * * The names of its contributors may not be used to endorse or
738+ * promote products derived from this software without specific prior
739+ * written permission.
740+ *
741+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
742+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
743+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
744+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
745+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
746+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
747+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
748+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
749+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
750+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
751+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
752+ *
753+ */
754+
755+/*
756+ * This test inserts a set of rows with NULLs in various columns, and verifies
757+ * that returned rows have NULLs in the proper columns (and non-NULL values in
758+ * the other columns). A binary count is used to generate 64 combinations of
759+ * NULL and non-NULL across 6 columns.
760+ *
761+ * Both the insert and the query are performed twice, once using the text-based
762+ * query interface and once using the prepared-statement binary-based query interface.
763+ */
764+
765+#include <yatl/lite.h>
766+
767+#include <libdrizzle-5.1/libdrizzle.h>
768+#include <stdio.h>
769+#include <string.h>
770+#include <stdlib.h>
771+
772+#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);
773+
774+#define TEST_PREPARED_STATEMENTS
775+
776+int main(int argc, char *argv[])
777+{
778+ (void) argc;
779+ (void) argv;
780+ drizzle_row_t row;
781+ int num_fields;
782+ drizzle_result_st *result;
783+ int table_size;
784+#ifdef TEST_PREPARED_STATEMENTS
785+ drizzle_stmt_st *sth;
786+#endif
787+
788+ drizzle_st *con= drizzle_create(getenv("MYSQL_SERVER"),
789+ getenv("MYSQL_PORT") ? atoi("MYSQL_PORT") : DRIZZLE_DEFAULT_TCP_PORT,
790+ getenv("MYSQL_USER"),
791+ getenv("MYSQL_PASSWORD"),
792+ getenv("MYSQL_SCHEMA"), 0);
793+ ASSERT_NOT_NULL_(con, "Drizzle connection object creation error");
794+
795+ drizzle_return_t driz_ret= drizzle_connect(con);
796+ if (driz_ret == DRIZZLE_RETURN_COULD_NOT_CONNECT)
797+ {
798+ char error[DRIZZLE_MAX_ERROR_SIZE];
799+ strncpy(error, drizzle_error(con), DRIZZLE_MAX_ERROR_SIZE);
800+ drizzle_quit(con);
801+ SKIP_IF_(driz_ret == DRIZZLE_RETURN_COULD_NOT_CONNECT, "%s(%s)", error, drizzle_strerror(driz_ret));
802+ }
803+ ASSERT_EQ_(DRIZZLE_RETURN_OK, driz_ret, "drizzle_connect(): %s(%s)", drizzle_error(con), drizzle_strerror(driz_ret));
804+
805+ CHECKED_QUERY("DROP SCHEMA IF EXISTS libdrizzle");
806+
807+ CHECKED_QUERY("CREATE SCHEMA libdrizzle");
808+
809+ driz_ret= drizzle_select_db(con, "libdrizzle");
810+ ASSERT_EQ_(DRIZZLE_RETURN_OK, driz_ret, "USE libdrizzle");
811+
812+ 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)");
813+
814+#define NCOLS 11
815+
816+ char *querybuf = malloc(256 + 60*64);
817+ strcpy(querybuf, "insert into libdrizzle.t1 values ");
818+ char *p = querybuf + strlen(querybuf);
819+
820+ for(int sym = 0; sym < 64; sym++) {
821+ int cn = 0;
822+ *p++ = '(';
823+#define APPENDMAYBE(b) if (sym & b) { strcpy(p, "NULL"); p += 4; } else { p += sprintf(p, "%d", sym*NCOLS + cn); }
824+ APPENDMAYBE(0x01); *p++ = ','; cn++;
825+ APPENDMAYBE(0x02); *p++ = ','; cn++;
826+ APPENDMAYBE(0x04); cn++;
827+ p += sprintf(p, ",%d,%d,%d,%d,", sym*NCOLS + 3, sym*NCOLS + 4, sym*NCOLS + 5, sym*NCOLS + 6);
828+ cn += 4;
829+ APPENDMAYBE(0x08); cn++;
830+ p += sprintf(p, ",%d,", sym*NCOLS + 8); cn++;
831+ APPENDMAYBE(0x10); *p++ = ','; cn++;
832+ APPENDMAYBE(0x20); cn++;
833+ *p++ = ')';
834+ if (sym < 63)
835+ *p++ = ',';
836+#undef APPENDMAYBE
837+ }
838+ CHECKED_QUERY(querybuf);
839+
840+#ifdef TEST_PREPARED_STATEMENTS
841+ strcpy(querybuf, "insert into libdrizzle.t1 values (?,?,?,?,?,?,?,?,?,?,?)");
842+ sth = drizzle_stmt_prepare(con, querybuf, strlen(querybuf), &driz_ret);
843+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, preparing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), querybuf);
844+
845+ for(int sym = 0; sym < 64; sym++) {
846+ // driz_ret= drizzle_stmt_reset(sth);
847+ // ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, resetting statement", drizzle_strerror(driz_ret), drizzle_error(con));
848+
849+#define SETMAYBE(cn,b) if (sym & b) driz_ret = drizzle_stmt_set_null(sth, cn); else SETALWAYS(cn);
850+#define SETALWAYS(cn) driz_ret = drizzle_stmt_set_short(sth, cn, sym*NCOLS + cn + 1000, 0)
851+ ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
852+ SETMAYBE(0,0x01);
853+ SETMAYBE(1,0x02);
854+ SETMAYBE(2,0x04);
855+ SETALWAYS(3);
856+ SETALWAYS(4);
857+ SETALWAYS(5);
858+ SETALWAYS(6);
859+ SETMAYBE(7,0x08);
860+ SETALWAYS(8);
861+ SETMAYBE(9,0x10);
862+ SETMAYBE(10,0x20);
863+#undef SETMAYBE
864+
865+ driz_ret = drizzle_stmt_execute(sth);
866+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, executing insert, sym=%d", drizzle_strerror(driz_ret), drizzle_error(con), sym);
867+
868+ driz_ret = drizzle_stmt_buffer(sth);
869+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, buffering result, sym=%d", drizzle_strerror(driz_ret), drizzle_error(con), sym);
870+
871+ // ASSERT_EQ(drizzle_stmt_affected_rows, 1);
872+ }
873+
874+ ASSERT_EQ(drizzle_stmt_close(sth), DRIZZLE_RETURN_OK);
875+
876+ table_size = 128;
877+#else
878+ table_size = 64;
879+#endif
880+
881+ CHECKED_QUERY("select a,b,c,d,e,f,g,h,i,j,k from libdrizzle.t1 order by e");
882+ drizzle_result_buffer(result);
883+ num_fields= drizzle_result_column_count(result);
884+ ASSERT_EQ_(num_fields, NCOLS, "Bad number of fields, expected %d, got %d", 11, num_fields);
885+
886+ int cur_row = 0;
887+ char nbuf[16];
888+ while ((row = drizzle_row_next(result))) {
889+ cur_row ++;
890+ int sym, rowbase;
891+
892+ /* 'sym' is the value used to decide which fields have NULLs or not.
893+ * 'rowbase' is the number that would be stored in the first field of this
894+ * row (assuming it's non-NULL).
895+ */
896+
897+ if (cur_row <= 64) {
898+ sym = cur_row - 1;
899+ rowbase = sym*NCOLS;
900+ } else {
901+ sym = cur_row - 65;
902+ rowbase = 1000 + sym*NCOLS;
903+ }
904+
905+#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); }
906+#define NULLNEVER(cn) NULLMAYBE(cn, 0)
907+
908+ NULLMAYBE(0, 0x01);
909+ NULLMAYBE(1, 0x02);
910+ NULLMAYBE(2, 0x04);
911+ NULLNEVER(3);
912+ NULLNEVER(4);
913+ NULLNEVER(5);
914+ NULLNEVER(6);
915+ NULLMAYBE(7, 0x08);
916+ NULLNEVER(8);
917+ NULLMAYBE(9, 0x10);
918+ NULLMAYBE(10, 0x20);
919+
920+#undef NULLMAYBE
921+#undef NULLNEVER
922+ }
923+ ASSERT_EQ(cur_row, table_size);
924+
925+ drizzle_result_free(result);
926+
927+#ifdef TEST_PREPARED_STATEMENTS
928+ strcpy(querybuf, "select a,b,c,d,e,f,g,h,i,j,k from libdrizzle.t1 order by e");
929+ sth = drizzle_stmt_prepare(con, querybuf, strlen(querybuf), &driz_ret);
930+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, preparing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), querybuf);
931+ driz_ret = drizzle_stmt_execute(sth);
932+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, executing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), querybuf);
933+
934+ cur_row = 0;
935+ for (;;) {
936+ driz_ret = drizzle_stmt_fetch(sth);
937+ if (driz_ret == DRIZZLE_RETURN_ROW_END)
938+ break;
939+ cur_row ++;
940+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, fetching row #%d", drizzle_strerror(driz_ret), drizzle_error(con), cur_row);
941+
942+ /* 'sym' is the value used to decide which fields have NULLs or not.
943+ * 'rowbase' is the number that would be stored in the first field of this
944+ * row (assuming it's non-NULL).
945+ */
946+
947+ int sym, rowbase;
948+
949+ if (cur_row <= 64) {
950+ sym = cur_row - 1;
951+ rowbase = sym*NCOLS;
952+ } else {
953+ sym = cur_row - 65;
954+ rowbase = 1000 + sym*NCOLS;
955+ }
956+
957+ bool isNull;
958+ uint32_t rowvalue;
959+
960+#define GETNULLNESS(cn) isNull = drizzle_stmt_get_is_null(sth, cn, &driz_ret); ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
961+#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));
962+#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); }
963+#define NULLNEVER(cn) GETNULLNESS(cn); NULLNOTNOW(cn);
964+
965+ NULLMAYBE(0, 0x01);
966+ NULLMAYBE(1, 0x02);
967+ NULLMAYBE(2, 0x04);
968+ NULLNEVER(3);
969+ NULLNEVER(4);
970+ NULLNEVER(5);
971+ NULLNEVER(6);
972+ NULLMAYBE(7, 0x08);
973+ NULLNEVER(8);
974+ NULLMAYBE(9, 0x10);
975+ NULLMAYBE(10, 0x20);
976+
977+#undef NULLMAYBE
978+#undef NULLNEVER
979+#undef GETNULLNESS
980+#undef NULLNOTNOW
981+ }
982+ ASSERT_EQ(cur_row, table_size);
983+ ASSERT_EQ(drizzle_stmt_close(sth), DRIZZLE_RETURN_OK);
984+#endif
985+
986+ CHECKED_QUERY("DROP TABLE libdrizzle.t1");
987+ ASSERT_EQ_(DRIZZLE_RETURN_OK, driz_ret, "DROP TABLE libdrizzle.t1");
988+
989+ CHECKED_QUERY("DROP SCHEMA IF EXISTS libdrizzle");
990+
991+ driz_ret= drizzle_quit(con);
992+ ASSERT_EQ_(DRIZZLE_RETURN_OK, driz_ret, "%s", drizzle_strerror(driz_ret));
993+
994+ return EXIT_SUCCESS;
995+}
996
997=== added file 'tests/unit/numbers.c'
998--- tests/unit/numbers.c 1970-01-01 00:00:00 +0000
999+++ tests/unit/numbers.c 2013-03-20 18:43:44 +0000
1000@@ -0,0 +1,326 @@
1001+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
1002+ *
1003+ * Drizzle Client & Protocol Library
1004+ *
1005+ * Copyright (C) 2013 Drizzle Developer Group
1006+ * All rights reserved.
1007+ *
1008+ * Redistribution and use in source and binary forms, with or without
1009+ * modification, are permitted provided that the following conditions are
1010+ * met:
1011+ *
1012+ * * Redistributions of source code must retain the above copyright
1013+ * notice, this list of conditions and the following disclaimer.
1014+ *
1015+ * * Redistributions in binary form must reproduce the above
1016+ * copyright notice, this list of conditions and the following disclaimer
1017+ * in the documentation and/or other materials provided with the
1018+ * distribution.
1019+ *
1020+ * * The names of its contributors may not be used to endorse or
1021+ * promote products derived from this software without specific prior
1022+ * written permission.
1023+ *
1024+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1025+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1026+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1027+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1028+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1029+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1030+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1031+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1032+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1033+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1034+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1035+ *
1036+ */
1037+
1038+#include <yatl/lite.h>
1039+#include "tests/unit/common.h"
1040+
1041+#include <libdrizzle-5.1/libdrizzle.h>
1042+
1043+#include <stdio.h>
1044+#include <string.h>
1045+#include <stdlib.h>
1046+#include <inttypes.h>
1047+#include <math.h>
1048+
1049+/* 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. */
1050+#define FLOAT_EQ_EXACT(a, b) ( isfinite(a) && isfinite(b) && !(a < b) && !(a > b) )
1051+
1052+#define ASSERT_FLOATEQEXACT(a, b) ASSERT_TRUE_(FLOAT_EQ_EXACT(a, b), "Floating-point values %f != %f (difference is %g)", (a), (b), (a)-(b))
1053+
1054+static const drizzle_column_type_t expected_column_types[9] = {
1055+ DRIZZLE_COLUMN_TYPE_NONE, /* Columns are 1-indexed */
1056+ DRIZZLE_COLUMN_TYPE_LONG,
1057+ DRIZZLE_COLUMN_TYPE_TINY,
1058+ DRIZZLE_COLUMN_TYPE_SHORT,
1059+ DRIZZLE_COLUMN_TYPE_INT24,
1060+ DRIZZLE_COLUMN_TYPE_LONG,
1061+ DRIZZLE_COLUMN_TYPE_LONGLONG,
1062+ DRIZZLE_COLUMN_TYPE_FLOAT,
1063+ DRIZZLE_COLUMN_TYPE_DOUBLE
1064+};
1065+
1066+/* 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). */
1067+static const intmax_t column_maxes[5] = {
1068+ 0x7F, /* 127 */
1069+ 0x7FAF, /* 32687 */
1070+ 0x7FFEFF, /* 8388351 */
1071+ 0x7FFDFFFF, /* 2147352575 */
1072+ 0x7FFBFFFFFFFFCFFF /* 9222246136947920895 */
1073+};
1074+
1075+static const char *column_names[9] = {
1076+ NULL,
1077+ "a", "b", "c", "d", "e", "f", "g", "h"
1078+};
1079+
1080+int main(int argc, char *argv[])
1081+{
1082+ (void) argc;
1083+ (void) argv;
1084+ drizzle_result_st *result;
1085+ drizzle_return_t driz_ret;
1086+ drizzle_row_t row;
1087+ const char *query;
1088+ drizzle_stmt_st *sth;
1089+ int num_fields;
1090+
1091+ set_up_connection();
1092+ set_up_schema();
1093+
1094+ 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)");
1095+
1096+ /* Insert rows with pk 1 and 2 */
1097+ 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);");
1098+ ASSERT_EQ(drizzle_result_affected_rows(result), 2);
1099+
1100+ /* Insert row with pk 3 */
1101+ 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 );");
1102+ ASSERT_EQ(drizzle_result_affected_rows(result), 1);
1103+
1104+ /* Insert row with pk 4 - test marshaling values we transmit */
1105+ query = "insert into libdrizzle.t1 (b,c,d,e,f,g,h) values (?,?,?,?,?,?,?)";
1106+ sth = drizzle_stmt_prepare(con, query, strlen(query), &driz_ret);
1107+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, preparing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
1108+ CHECK(drizzle_stmt_set_tiny(sth, 0, 127, 0));
1109+ CHECK(drizzle_stmt_set_short(sth, 1, 32687, 0));
1110+ CHECK(drizzle_stmt_set_int(sth, 2, 8388351, 0));
1111+ CHECK(drizzle_stmt_set_int(sth, 3, 2147352575, 0));
1112+ CHECK(drizzle_stmt_set_bigint(sth, 4, 9222246136947920895, 0));
1113+ CHECK(drizzle_stmt_set_float(sth, 5, 443664.0));
1114+ CHECK(drizzle_stmt_set_double(sth, 6, 291.2711110711098));
1115+ driz_ret = drizzle_stmt_execute(sth);
1116+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, executing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
1117+ driz_ret = drizzle_stmt_buffer(sth);
1118+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, buffering \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
1119+ CHECK(drizzle_stmt_close(sth));
1120+
1121+ /* TODO: Also send some negative values of each type */
1122+
1123+ /* Read the table back, with values sent over the wire in text form */
1124+ CHECKED_QUERY("select * from libdrizzle.t1 order by b, a");
1125+
1126+ drizzle_result_buffer(result);
1127+ num_fields= drizzle_result_column_count(result);
1128+
1129+ ASSERT_EQ_(num_fields, 8, "Retrieved bad number of fields");
1130+
1131+ int readback_order[4] = { 3, 1, 2, 4 };
1132+
1133+ unsigned int cur_row= 0;
1134+ drizzle_column_st *column;
1135+ while ((row = drizzle_row_next(result)))
1136+ {
1137+ drizzle_column_seek(result, 0);
1138+ int cur_column= 0;
1139+ cur_row++;
1140+ ASSERT_EQ(drizzle_row_current(result), cur_row);
1141+ ASSERT_TRUE(cur_row <= 4);
1142+
1143+ char expected_colA[10];
1144+ sprintf(expected_colA, "%d", readback_order[cur_row-1]);
1145+ ASSERT_EQ_(strcmp(row[0], expected_colA), 0, "Retrieved bad row value; row=%d got=%s expected=%s", cur_row, row[0], expected_colA);
1146+
1147+ while ((column= drizzle_column_next(result)))
1148+ {
1149+ cur_column++;
1150+ ASSERT_EQ_(strcmp(drizzle_column_db(column), "libdrizzle"), 0, "Column has bad DB name");
1151+ ASSERT_EQ_(strcmp(drizzle_column_table(column), "t1"), 0, "Column had bad table name");
1152+ ASSERT_EQ(drizzle_column_current(result), cur_column);
1153+ ASSERT_STREQ(drizzle_column_name(column), column_names[cur_column]);
1154+ 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]);
1155+ }
1156+ ASSERT_EQ_(cur_column, 8, "Wrong column count");
1157+
1158+ for (cur_column = 2; cur_column <= 6; cur_column ++) {
1159+ if (cur_row == 2) {
1160+ ASSERT_STREQ("1", row[cur_column-1]);
1161+ } else if (cur_row == 3 || cur_row == 4) {
1162+ char buf[25];
1163+ snprintf(buf, 25, "%"PRIdMAX, column_maxes[cur_column-2]);
1164+ ASSERT_STREQ(buf, row[cur_column-1]);
1165+ } else if (cur_row == 1) {
1166+ char buf[25];
1167+ snprintf(buf, 25, "-%"PRIdMAX, column_maxes[cur_column-2]);
1168+ ASSERT_STREQ(buf, row[cur_column-1]);
1169+ }
1170+ }
1171+
1172+ if (cur_row == 1) {
1173+ ASSERT_STREQ("443665", row[6]);
1174+ ASSERT_STREQ("292.2711110711098", row[7]);
1175+ }
1176+
1177+ if (cur_row == 3 || cur_row == 4) {
1178+ ASSERT_STREQ("443664", row[6]);
1179+ ASSERT_STREQ("291.2711110711098", row[7]);
1180+ }
1181+
1182+
1183+ }
1184+ /* Should have had 4 rows */
1185+ ASSERT_EQ_(cur_row, 4, "Retrieved bad number of rows");
1186+
1187+ drizzle_result_free(result);
1188+
1189+ /* Read the table back, with values sent over the wire in binary form */
1190+ query = "select a,b,c,d,e,f,g,h from libdrizzle.t1";
1191+ sth = drizzle_stmt_prepare(con, query, strlen(query), &driz_ret);
1192+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, preparing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
1193+ driz_ret = drizzle_stmt_execute(sth);
1194+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, executing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
1195+ driz_ret = drizzle_stmt_buffer(sth);
1196+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, buffering \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
1197+
1198+ ASSERT_EQ(4, drizzle_stmt_row_count(sth));
1199+ cur_row = 0;
1200+ while (drizzle_stmt_fetch(sth) != DRIZZLE_RETURN_ROW_END)
1201+ {
1202+ cur_row ++;
1203+ printf("Row %d\n", cur_row);
1204+
1205+ int columnA = drizzle_stmt_get_int(sth, 0, &driz_ret);
1206+ 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);
1207+
1208+ int cur_column;
1209+ intmax_t col_val, expect_val;
1210+ char expect_strval[64];
1211+ const char *col_strval;
1212+ double col_dblval;
1213+ size_t lth;
1214+
1215+ for (cur_column = 2; cur_column <= 6; cur_column ++) {
1216+ switch (columnA) {
1217+ case 3:
1218+ expect_val = ( 0 - column_maxes[cur_column-2] );
1219+ break;
1220+ case 1:
1221+ expect_val = 1;
1222+ break;
1223+ case 2:
1224+ case 4:
1225+ expect_val = column_maxes[cur_column-2];
1226+ break;
1227+ default:
1228+ ASSERT_FALSE_(1, "Row %d has column.a = %u", cur_row, columnA);
1229+ }
1230+
1231+ /* These columns are 0-based */
1232+
1233+ col_val = drizzle_stmt_get_bigint(sth, cur_column-1, &driz_ret);
1234+ 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);
1235+ col_strval = drizzle_stmt_get_string(sth, cur_column-1, &lth, &driz_ret);
1236+ ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
1237+ ASSERT_EQ(lth, strlen(col_strval));
1238+ col_dblval = drizzle_stmt_get_double(sth, cur_column-1, &driz_ret);
1239+ 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);
1240+
1241+ printf(" Column %d: %"PRIdMAX" \"%s\" %f\n", cur_column, col_val, col_strval, col_dblval);
1242+
1243+ if (columnA == 3)
1244+ continue;
1245+
1246+ ASSERT_EQ_(expect_val, col_val, "Column %d of row %d: expected %"PRIdMAX", got %"PRIdMAX,
1247+ cur_column, cur_row, expect_val, col_val);
1248+ if (cur_column <= 5) {
1249+ uint32_t col_narrowval = drizzle_stmt_get_int(sth, cur_column-1, &driz_ret);
1250+ 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);
1251+ ASSERT_EQ_(col_val, col_narrowval, "column %d of row %d: get_bigint returns %"PRIdMAX", get_int returns %"PRId32,
1252+ cur_column, cur_row, col_val, col_narrowval);
1253+ }
1254+ ASSERT_FLOATEQEXACT((double)expect_val, col_dblval);
1255+
1256+ snprintf(expect_strval, 64, "%"PRIdMAX, expect_val);
1257+ ASSERT_STREQ(expect_strval, col_strval);
1258+ }
1259+
1260+ float expect_floatval;
1261+ double expect_dblval;
1262+ switch (columnA) {
1263+ case 1:
1264+ expect_floatval = 1.0;
1265+ expect_dblval = 1.0;
1266+ break;
1267+ case 2:
1268+ case 4:
1269+ expect_floatval = 443664.0;
1270+ expect_dblval = 291.2711110711098;
1271+ break;
1272+ case 3:
1273+ expect_floatval = 443665.0;
1274+ expect_dblval = 292.2711110711098;
1275+ break;
1276+ }
1277+
1278+ col_val = drizzle_stmt_get_int(sth, 6, &driz_ret);
1279+ 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);
1280+ ASSERT_FLOATEQEXACT((float)col_val, trunc(expect_floatval));
1281+
1282+ col_val = drizzle_stmt_get_bigint(sth, 6, &driz_ret);
1283+ 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);
1284+ ASSERT_FLOATEQEXACT((float)col_val, trunc(expect_floatval));
1285+
1286+ col_dblval = drizzle_stmt_get_double(sth, 6, &driz_ret);
1287+ 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);
1288+ ASSERT_FLOATEQEXACT(col_dblval, expect_floatval);
1289+
1290+ col_strval = drizzle_stmt_get_string(sth, 6, &lth, &driz_ret);
1291+ ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
1292+
1293+ printf(" Column %d: %"PRIdMAX" \"%s\" %f\n", 7, col_val, col_strval, col_dblval);
1294+
1295+
1296+
1297+ col_val = drizzle_stmt_get_int(sth, 7, &driz_ret);
1298+ 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);
1299+ ASSERT_FLOATEQEXACT((double)col_val, trunc(expect_dblval));
1300+
1301+ col_val = drizzle_stmt_get_bigint(sth, 7, &driz_ret);
1302+ 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);
1303+ ASSERT_FLOATEQEXACT((double)col_val, trunc(expect_dblval));
1304+
1305+ col_dblval = drizzle_stmt_get_double(sth, 7, &driz_ret);
1306+ 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);
1307+ ASSERT_FLOATEQEXACT(col_dblval, expect_dblval);
1308+
1309+ col_strval = drizzle_stmt_get_string(sth, 7, &lth, &driz_ret);
1310+ ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
1311+
1312+ printf(" Column %d: %"PRIdMAX" \"%s\" %f\n", 8, col_val, col_strval, col_dblval);
1313+ }
1314+
1315+ ASSERT_EQ(cur_row, 4);
1316+
1317+ driz_ret = drizzle_stmt_close(sth);
1318+ ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s", drizzle_strerror(driz_ret), drizzle_error(con));
1319+
1320+ drizzle_query(con, "DROP TABLE libdrizzle.t1", 0, &driz_ret);
1321+ ASSERT_EQ_(DRIZZLE_RETURN_OK, driz_ret, "DROP TABLE libdrizzle.t1");
1322+
1323+ tear_down_schema();
1324+
1325+ return EXIT_SUCCESS;
1326+}

Subscribers

People subscribed via source and target branches

to all changes:
to status/vote changes: