~drizzle-trunk/libdrizzle/jenkins-Libdrizzle-83

« back to all changes in this revision

Viewing changes to tests/unit/nulls.c

  • Committer: Continuous Integration
  • Date: 2013-03-21 10:44:02 UTC
  • mfrom: (108.1.7 libdrizzle)
  • Revision ID: ci@drizzle.org-20130321104402-9alevcsgdw6fo2k0
Merge lp:~wiml/libdrizzle/unit-tests Build: jenkins-Libdrizzle-75

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
2
 *
 
3
 *  Drizzle Client & Protocol Library
 
4
 *
 
5
 * Copyright (C) 2013 Drizzle Developer Group
 
6
 * All rights reserved.
 
7
 *
 
8
 * Redistribution and use in source and binary forms, with or without
 
9
 * modification, are permitted provided that the following conditions are
 
10
 * met:
 
11
 *
 
12
 *     * Redistributions of source code must retain the above copyright
 
13
 * notice, this list of conditions and the following disclaimer.
 
14
 *
 
15
 *     * Redistributions in binary form must reproduce the above
 
16
 * copyright notice, this list of conditions and the following disclaimer
 
17
 * in the documentation and/or other materials provided with the
 
18
 * distribution.
 
19
 *
 
20
 *     * The names of its contributors may not be used to endorse or
 
21
 * promote products derived from this software without specific prior
 
22
 * written permission.
 
23
 *
 
24
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
25
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
26
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
27
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
28
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
29
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
30
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
31
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
32
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
33
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
34
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
35
 *
 
36
 */
 
37
 
 
38
/*
 
39
 * This test inserts a set of rows with NULLs in various columns, and verifies
 
40
 * that returned rows have NULLs in the proper columns (and non-NULL values in
 
41
 * the other columns). A binary count is used to generate 64 combinations of
 
42
 * NULL and non-NULL across 6 columns.
 
43
 *
 
44
 * Both the insert and the query are performed twice, once using the text-based
 
45
 * query interface and once using the prepared-statement binary-based query interface.
 
46
 */
 
47
 
 
48
#include <yatl/lite.h>
 
49
 
 
50
#include <libdrizzle-5.1/libdrizzle.h>
 
51
#include <stdio.h>
 
52
#include <string.h>
 
53
#include <stdlib.h>
 
54
 
 
55
#define CHECKED_QUERY(cmd) result = drizzle_query(con, cmd, 0, &driz_ret); ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, from \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), cmd);
 
56
 
 
57
#define TEST_PREPARED_STATEMENTS
 
58
 
 
59
int main(int argc, char *argv[])
 
60
{
 
61
  (void) argc;
 
62
  (void) argv;
 
63
  drizzle_row_t row;
 
64
  int num_fields;
 
65
  drizzle_result_st *result;
 
66
  int table_size;
 
67
#ifdef TEST_PREPARED_STATEMENTS
 
68
  drizzle_stmt_st *sth;
 
69
#endif
 
70
  
 
71
  drizzle_st *con= drizzle_create(getenv("MYSQL_SERVER"),
 
72
                                  getenv("MYSQL_PORT") ? atoi("MYSQL_PORT") : DRIZZLE_DEFAULT_TCP_PORT,
 
73
                                  getenv("MYSQL_USER"),
 
74
                                  getenv("MYSQL_PASSWORD"),
 
75
                                  getenv("MYSQL_SCHEMA"), 0);
 
76
  ASSERT_NOT_NULL_(con, "Drizzle connection object creation error");
 
77
  
 
78
  drizzle_return_t driz_ret= drizzle_connect(con);
 
79
  if (driz_ret == DRIZZLE_RETURN_COULD_NOT_CONNECT)
 
80
  {
 
81
    char error[DRIZZLE_MAX_ERROR_SIZE];
 
82
    strncpy(error, drizzle_error(con), DRIZZLE_MAX_ERROR_SIZE);
 
83
    drizzle_quit(con);
 
84
    SKIP_IF_(driz_ret == DRIZZLE_RETURN_COULD_NOT_CONNECT, "%s(%s)", error, drizzle_strerror(driz_ret));
 
85
  }
 
86
  ASSERT_EQ_(DRIZZLE_RETURN_OK, driz_ret, "drizzle_connect(): %s(%s)", drizzle_error(con), drizzle_strerror(driz_ret));
 
87
  
 
88
  CHECKED_QUERY("DROP SCHEMA IF EXISTS libdrizzle");
 
89
  
 
90
  CHECKED_QUERY("CREATE SCHEMA libdrizzle");
 
91
  
 
92
  driz_ret= drizzle_select_db(con, "libdrizzle");
 
93
  ASSERT_EQ_(DRIZZLE_RETURN_OK, driz_ret, "USE libdrizzle");
 
94
  
 
95
  CHECKED_QUERY("create table libdrizzle.t1 (a int, b int, c int, d int, e int, f int, g int, h int, i int, j int, k int)");
 
96
  
 
97
#define NCOLS 11
 
98
  
 
99
  char *querybuf = malloc(256 + 60*64);
 
100
  strcpy(querybuf, "insert into libdrizzle.t1 values ");
 
101
  char *p = querybuf + strlen(querybuf);
 
102
  
 
103
  for(int sym = 0; sym < 64; sym++) {
 
104
    int cn = 0;
 
105
    *p++ = '(';
 
106
#define APPENDMAYBE(b)  if (sym & b) { strcpy(p, "NULL"); p += 4; } else { p += sprintf(p, "%d", sym*NCOLS + cn); }
 
107
    APPENDMAYBE(0x01); *p++ = ','; cn++;
 
108
    APPENDMAYBE(0x02); *p++ = ','; cn++;
 
109
    APPENDMAYBE(0x04);             cn++;
 
110
    p += sprintf(p, ",%d,%d,%d,%d,", sym*NCOLS + 3, sym*NCOLS + 4, sym*NCOLS + 5, sym*NCOLS + 6);
 
111
    cn += 4;
 
112
    APPENDMAYBE(0x08);             cn++;
 
113
    p += sprintf(p, ",%d,", sym*NCOLS + 8); cn++;
 
114
    APPENDMAYBE(0x10); *p++ = ','; cn++;
 
115
    APPENDMAYBE(0x20);             cn++;
 
116
    *p++ = ')';
 
117
    if (sym < 63)
 
118
      *p++ = ',';
 
119
#undef APPENDMAYBE
 
120
  }
 
121
  CHECKED_QUERY(querybuf);
 
122
  
 
123
#ifdef TEST_PREPARED_STATEMENTS
 
124
  strcpy(querybuf, "insert into libdrizzle.t1 values (?,?,?,?,?,?,?,?,?,?,?)");
 
125
  sth = drizzle_stmt_prepare(con, querybuf, strlen(querybuf), &driz_ret);
 
126
  ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, preparing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), querybuf);
 
127
  
 
128
  for(int sym = 0; sym < 64; sym++) {
 
129
    // driz_ret= drizzle_stmt_reset(sth);
 
130
    // ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, resetting statement", drizzle_strerror(driz_ret), drizzle_error(con));
 
131
    
 
132
#define SETMAYBE(cn,b) if (sym & b) driz_ret = drizzle_stmt_set_null(sth, cn); else SETALWAYS(cn);
 
133
#define SETALWAYS(cn) driz_ret = drizzle_stmt_set_short(sth, cn, sym*NCOLS + cn + 1000, 0)
 
134
    ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
 
135
    SETMAYBE(0,0x01);
 
136
    SETMAYBE(1,0x02);
 
137
    SETMAYBE(2,0x04);
 
138
    SETALWAYS(3);
 
139
    SETALWAYS(4);
 
140
    SETALWAYS(5);
 
141
    SETALWAYS(6);
 
142
    SETMAYBE(7,0x08);
 
143
    SETALWAYS(8);
 
144
    SETMAYBE(9,0x10);
 
145
    SETMAYBE(10,0x20);
 
146
#undef SETMAYBE
 
147
    
 
148
    driz_ret = drizzle_stmt_execute(sth);
 
149
    ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, executing insert, sym=%d", drizzle_strerror(driz_ret), drizzle_error(con), sym);
 
150
    
 
151
    driz_ret = drizzle_stmt_buffer(sth);
 
152
    ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, buffering result, sym=%d", drizzle_strerror(driz_ret), drizzle_error(con), sym);
 
153
    
 
154
    // ASSERT_EQ(drizzle_stmt_affected_rows, 1);
 
155
  }
 
156
  
 
157
  ASSERT_EQ(drizzle_stmt_close(sth), DRIZZLE_RETURN_OK);
 
158
  
 
159
  table_size = 128;
 
160
#else
 
161
  table_size = 64;
 
162
#endif
 
163
  
 
164
  CHECKED_QUERY("select a,b,c,d,e,f,g,h,i,j,k from libdrizzle.t1 order by e");
 
165
  drizzle_result_buffer(result);
 
166
  num_fields= drizzle_result_column_count(result);
 
167
  ASSERT_EQ_(num_fields, NCOLS, "Bad number of fields, expected %d, got %d", 11, num_fields);
 
168
  
 
169
  int cur_row = 0;
 
170
  char nbuf[16];
 
171
  while ((row = drizzle_row_next(result))) {
 
172
    cur_row ++;
 
173
    int sym, rowbase;
 
174
    
 
175
    /* 'sym' is the value used to decide which fields have NULLs or not.
 
176
     * 'rowbase' is the number that would be stored in the first field of this
 
177
     * row (assuming it's non-NULL).
 
178
     */
 
179
    
 
180
    if (cur_row <= 64) {
 
181
      sym = cur_row - 1;
 
182
      rowbase = sym*NCOLS;
 
183
    } else {
 
184
      sym = cur_row - 65;
 
185
      rowbase = 1000 + sym*NCOLS;
 
186
    }
 
187
    
 
188
#define NULLMAYBE(cn, b)  if (sym & b) { ASSERT_NULL_(row[cn], "Column %d, row %d should be NULL", cn+1, cur_row); } else { ASSERT_NOT_NULL_(row[cn], "Column %d, row %d should not be NULL", cn+1, cur_row); sprintf(nbuf, "%d", rowbase+cn); ASSERT_STREQ(row[cn], nbuf); }
 
189
#define NULLNEVER(cn) NULLMAYBE(cn, 0)
 
190
    
 
191
    NULLMAYBE(0, 0x01);
 
192
    NULLMAYBE(1, 0x02);
 
193
    NULLMAYBE(2, 0x04);
 
194
    NULLNEVER(3);
 
195
    NULLNEVER(4);
 
196
    NULLNEVER(5);
 
197
    NULLNEVER(6);
 
198
    NULLMAYBE(7, 0x08);
 
199
    NULLNEVER(8);
 
200
    NULLMAYBE(9, 0x10);
 
201
    NULLMAYBE(10, 0x20);
 
202
    
 
203
#undef NULLMAYBE
 
204
#undef NULLNEVER
 
205
  }
 
206
  ASSERT_EQ(cur_row, table_size);
 
207
  
 
208
  drizzle_result_free(result);
 
209
  
 
210
#ifdef TEST_PREPARED_STATEMENTS
 
211
  strcpy(querybuf, "select a,b,c,d,e,f,g,h,i,j,k from libdrizzle.t1 order by e");
 
212
  sth = drizzle_stmt_prepare(con, querybuf, strlen(querybuf), &driz_ret);
 
213
  ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, preparing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), querybuf);
 
214
  driz_ret = drizzle_stmt_execute(sth);
 
215
  ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, executing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), querybuf);
 
216
  
 
217
  cur_row = 0;
 
218
  for (;;) {
 
219
    driz_ret = drizzle_stmt_fetch(sth);
 
220
    if (driz_ret == DRIZZLE_RETURN_ROW_END)
 
221
      break;
 
222
    cur_row ++;
 
223
    ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, fetching row #%d", drizzle_strerror(driz_ret), drizzle_error(con), cur_row);
 
224
    
 
225
    /* 'sym' is the value used to decide which fields have NULLs or not.
 
226
     * 'rowbase' is the number that would be stored in the first field of this
 
227
     * row (assuming it's non-NULL).
 
228
     */
 
229
    
 
230
    int sym, rowbase;
 
231
    
 
232
    if (cur_row <= 64) {
 
233
      sym = cur_row - 1;
 
234
      rowbase = sym*NCOLS;
 
235
    } else {
 
236
      sym = cur_row - 65;
 
237
      rowbase = 1000 + sym*NCOLS;
 
238
    }
 
239
    
 
240
    bool isNull;
 
241
    uint32_t rowvalue;
 
242
    
 
243
#define GETNULLNESS(cn) isNull = drizzle_stmt_get_is_null(sth, cn, &driz_ret); ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
 
244
#define NULLNOTNOW(cn) ASSERT_FALSE_(isNull, "Column %d, row %d should not be NULL", cn+1, cur_row); rowvalue = drizzle_stmt_get_int(sth, cn, &driz_ret); ASSERT_EQ(driz_ret,DRIZZLE_RETURN_OK); ASSERT_EQ(rowvalue, (unsigned)(rowbase + cn));
 
245
#define NULLMAYBE(cn, b) GETNULLNESS(cn); if (sym & b) { ASSERT_TRUE_(isNull, "Column %d, row %d should be NULL", cn+1, cur_row); } else { NULLNOTNOW(cn); }
 
246
#define NULLNEVER(cn) GETNULLNESS(cn); NULLNOTNOW(cn);
 
247
    
 
248
    NULLMAYBE(0, 0x01);
 
249
    NULLMAYBE(1, 0x02);
 
250
    NULLMAYBE(2, 0x04);
 
251
    NULLNEVER(3);
 
252
    NULLNEVER(4);
 
253
    NULLNEVER(5);
 
254
    NULLNEVER(6);
 
255
    NULLMAYBE(7, 0x08);
 
256
    NULLNEVER(8);
 
257
    NULLMAYBE(9, 0x10);
 
258
    NULLMAYBE(10, 0x20);
 
259
    
 
260
#undef NULLMAYBE
 
261
#undef NULLNEVER
 
262
#undef GETNULLNESS
 
263
#undef NULLNOTNOW
 
264
  }
 
265
  ASSERT_EQ(cur_row, table_size);
 
266
  ASSERT_EQ(drizzle_stmt_close(sth), DRIZZLE_RETURN_OK);
 
267
#endif
 
268
  
 
269
  CHECKED_QUERY("DROP TABLE libdrizzle.t1");
 
270
  ASSERT_EQ_(DRIZZLE_RETURN_OK, driz_ret, "DROP TABLE libdrizzle.t1");
 
271
   
 
272
  CHECKED_QUERY("DROP SCHEMA IF EXISTS libdrizzle");
 
273
 
 
274
  driz_ret= drizzle_quit(con);
 
275
  ASSERT_EQ_(DRIZZLE_RETURN_OK, driz_ret, "%s", drizzle_strerror(driz_ret));
 
276
  
 
277
  return EXIT_SUCCESS;
 
278
}