Merge lp:~wiml/libdrizzle/unit-tests into lp:libdrizzle
- unit-tests
- Merge into libdrizzle-redux
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 |
Related bugs: |
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:/
To post a comment you must log in.
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, <h, &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, <h, &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, <h, &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, <h, &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 | +} |
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.