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

« back to all changes in this revision

Viewing changes to tests/unit/numbers.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
#include <yatl/lite.h>
 
39
#include "tests/unit/common.h"
 
40
 
 
41
#include <libdrizzle-5.1/libdrizzle.h>
 
42
 
 
43
#include <stdio.h>
 
44
#include <string.h>
 
45
#include <stdlib.h>
 
46
#include <inttypes.h>
 
47
#include <math.h>
 
48
 
 
49
/* We've chosen the floats so that the are exactly representable in a normal binary floating-point format, so we should get exact results out. However, some compilers (pretty reasonably) warn when doing exact equality tests of floats. This gets around that. */
 
50
#define FLOAT_EQ_EXACT(a, b) ( isfinite(a) && isfinite(b) && !(a < b) && !(a > b) )
 
51
 
 
52
#define ASSERT_FLOATEQEXACT(a, b) ASSERT_TRUE_(FLOAT_EQ_EXACT(a, b), "Floating-point values %f != %f (difference is %g)", (a), (b), (a)-(b))
 
53
 
 
54
static const drizzle_column_type_t expected_column_types[9] = {
 
55
    DRIZZLE_COLUMN_TYPE_NONE, /* Columns are 1-indexed */
 
56
    DRIZZLE_COLUMN_TYPE_LONG,
 
57
    DRIZZLE_COLUMN_TYPE_TINY,
 
58
    DRIZZLE_COLUMN_TYPE_SHORT,
 
59
    DRIZZLE_COLUMN_TYPE_INT24,
 
60
    DRIZZLE_COLUMN_TYPE_LONG,
 
61
    DRIZZLE_COLUMN_TYPE_LONGLONG,
 
62
    DRIZZLE_COLUMN_TYPE_FLOAT,
 
63
    DRIZZLE_COLUMN_TYPE_DOUBLE
 
64
};
 
65
 
 
66
/* These are close to the maximum value for each integer type. A few bits are cleared in the middle of each value to detect other kinds of scrambling (e.g. inappropriate sign-extension of intermediate results). */
 
67
static const intmax_t column_maxes[5] = {
 
68
    0x7F,                /*                 127 */
 
69
    0x7FAF,              /*               32687 */
 
70
    0x7FFEFF,            /*             8388351 */
 
71
    0x7FFDFFFF,          /*          2147352575 */
 
72
    0x7FFBFFFFFFFFCFFF   /* 9222246136947920895 */
 
73
};
 
74
 
 
75
static const char *column_names[9] = {
 
76
    NULL,
 
77
    "a", "b", "c", "d", "e", "f", "g", "h"
 
78
};
 
79
 
 
80
int main(int argc, char *argv[])
 
81
{
 
82
  (void) argc;
 
83
  (void) argv;
 
84
  drizzle_result_st *result;
 
85
  drizzle_return_t driz_ret;
 
86
  drizzle_row_t row;
 
87
  const char *query;
 
88
  drizzle_stmt_st *sth;
 
89
  int num_fields;
 
90
  
 
91
  set_up_connection();
 
92
  set_up_schema();
 
93
  
 
94
  CHECKED_QUERY("create table libdrizzle.t1 (a int primary key auto_increment, b tinyint, c smallint, d mediumint, e int, f bigint, g float, h double)");
 
95
  
 
96
  /* Insert rows with pk 1 and 2 */
 
97
  CHECKED_QUERY("insert into libdrizzle.t1 (b,c,d,e,f,g,h) values (1,1,1,1,1,1,1), (127,32687,8388351,2147352575,9222246136947920895,443664,291.2711110711098);");
 
98
  ASSERT_EQ(drizzle_result_affected_rows(result), 2);
 
99
  
 
100
  /* Insert row with pk 3 */
 
101
  CHECKED_QUERY("insert into libdrizzle.t1 (b,c,d,e,f,g,h) ( select 0-b, 0-c, 0-d, 0-e, 0-f, g+1.015625, h+1 from t1 where a = 2 );");
 
102
  ASSERT_EQ(drizzle_result_affected_rows(result), 1);
 
103
  
 
104
  /* Insert row with pk 4 - test marshaling values we transmit */
 
105
  query = "insert into libdrizzle.t1 (b,c,d,e,f,g,h) values (?,?,?,?,?,?,?)";
 
106
  sth = drizzle_stmt_prepare(con, query, strlen(query), &driz_ret);
 
107
  ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, preparing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
 
108
  CHECK(drizzle_stmt_set_tiny(sth,   0, 127, 0));
 
109
  CHECK(drizzle_stmt_set_short(sth,  1, 32687, 0));
 
110
  CHECK(drizzle_stmt_set_int(sth,    2, 8388351, 0));
 
111
  CHECK(drizzle_stmt_set_int(sth,    3, 2147352575, 0));
 
112
  CHECK(drizzle_stmt_set_bigint(sth, 4, 9222246136947920895, 0));
 
113
  CHECK(drizzle_stmt_set_float(sth,  5, 443664.0));
 
114
  CHECK(drizzle_stmt_set_double(sth, 6, 291.2711110711098));
 
115
  driz_ret = drizzle_stmt_execute(sth);
 
116
  ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, executing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
 
117
  driz_ret = drizzle_stmt_buffer(sth);
 
118
  ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, buffering \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
 
119
  CHECK(drizzle_stmt_close(sth));
 
120
  
 
121
  /* TODO: Also send some negative values of each type */
 
122
  
 
123
  /* Read the table back, with values sent over the wire in text form */
 
124
  CHECKED_QUERY("select * from libdrizzle.t1 order by b, a");
 
125
  
 
126
  drizzle_result_buffer(result);
 
127
  num_fields= drizzle_result_column_count(result);
 
128
  
 
129
  ASSERT_EQ_(num_fields, 8, "Retrieved bad number of fields");
 
130
  
 
131
  int readback_order[4] = { 3, 1, 2, 4 };
 
132
  
 
133
  unsigned int cur_row= 0;
 
134
  drizzle_column_st *column;
 
135
  while ((row = drizzle_row_next(result)))
 
136
  {
 
137
    drizzle_column_seek(result, 0);
 
138
    int cur_column= 0;
 
139
    cur_row++;
 
140
    ASSERT_EQ(drizzle_row_current(result), cur_row);
 
141
    ASSERT_TRUE(cur_row <= 4);
 
142
    
 
143
    char expected_colA[10];
 
144
    sprintf(expected_colA, "%d", readback_order[cur_row-1]);
 
145
    ASSERT_EQ_(strcmp(row[0], expected_colA), 0, "Retrieved bad row value; row=%d got=%s expected=%s", cur_row, row[0], expected_colA);
 
146
    
 
147
    while ((column= drizzle_column_next(result)))
 
148
    {
 
149
      cur_column++;
 
150
      ASSERT_EQ_(strcmp(drizzle_column_db(column), "libdrizzle"), 0, "Column has bad DB name");
 
151
      ASSERT_EQ_(strcmp(drizzle_column_table(column), "t1"), 0, "Column had bad table name");
 
152
      ASSERT_EQ(drizzle_column_current(result), cur_column);
 
153
      ASSERT_STREQ(drizzle_column_name(column), column_names[cur_column]);
 
154
      ASSERT_EQ_(drizzle_column_type(column), expected_column_types[cur_column], "Column %d has type=%d expected=%d", cur_column, drizzle_column_type(column), expected_column_types[cur_column]);
 
155
    }
 
156
    ASSERT_EQ_(cur_column, 8, "Wrong column count");
 
157
    
 
158
    for (cur_column = 2; cur_column <= 6; cur_column ++) {
 
159
      if (cur_row == 2) {
 
160
        ASSERT_STREQ("1", row[cur_column-1]);
 
161
      } else if (cur_row == 3 || cur_row == 4) {
 
162
        char buf[25];
 
163
        snprintf(buf, 25, "%"PRIdMAX, column_maxes[cur_column-2]);
 
164
        ASSERT_STREQ(buf, row[cur_column-1]);
 
165
      } else if (cur_row == 1) {
 
166
        char buf[25];
 
167
        snprintf(buf, 25, "-%"PRIdMAX, column_maxes[cur_column-2]);
 
168
        ASSERT_STREQ(buf, row[cur_column-1]);
 
169
      }
 
170
    }
 
171
    
 
172
    if (cur_row == 1) {
 
173
      ASSERT_STREQ("443665", row[6]);
 
174
      ASSERT_STREQ("292.2711110711098", row[7]);
 
175
    }
 
176
    
 
177
    if (cur_row == 3 || cur_row == 4) {
 
178
      ASSERT_STREQ("443664", row[6]);
 
179
      ASSERT_STREQ("291.2711110711098", row[7]);
 
180
    }
 
181
    
 
182
    
 
183
  }
 
184
  /* Should have had 4 rows */
 
185
  ASSERT_EQ_(cur_row, 4, "Retrieved bad number of rows");
 
186
  
 
187
  drizzle_result_free(result);
 
188
  
 
189
  /* Read the table back, with values sent over the wire in binary form */
 
190
  query = "select a,b,c,d,e,f,g,h from libdrizzle.t1";
 
191
  sth = drizzle_stmt_prepare(con, query, strlen(query), &driz_ret);
 
192
  ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, preparing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
 
193
  driz_ret = drizzle_stmt_execute(sth);
 
194
  ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, executing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
 
195
  driz_ret = drizzle_stmt_buffer(sth);
 
196
  ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, buffering \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
 
197
  
 
198
  ASSERT_EQ(4, drizzle_stmt_row_count(sth));
 
199
  cur_row = 0;
 
200
  while (drizzle_stmt_fetch(sth) != DRIZZLE_RETURN_ROW_END)
 
201
  {
 
202
    cur_row ++;
 
203
    printf("Row %d\n", cur_row);
 
204
    
 
205
    int columnA = drizzle_stmt_get_int(sth, 0, &driz_ret);
 
206
    ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), 1, cur_row);
 
207
    
 
208
    int cur_column;
 
209
    intmax_t col_val, expect_val;
 
210
    char expect_strval[64];
 
211
    const char *col_strval;
 
212
    double col_dblval;
 
213
    size_t lth;
 
214
    
 
215
    for (cur_column = 2; cur_column <= 6; cur_column ++) {
 
216
      switch (columnA) {
 
217
        case 3:
 
218
          expect_val = ( 0 - column_maxes[cur_column-2] );
 
219
          break;
 
220
        case 1:
 
221
          expect_val = 1;
 
222
          break;
 
223
        case 2:
 
224
        case 4:
 
225
          expect_val = column_maxes[cur_column-2];
 
226
          break;
 
227
        default:
 
228
          ASSERT_FALSE_(1, "Row %d has column.a = %u", cur_row, columnA);
 
229
      }
 
230
      
 
231
      /* These columns are 0-based */
 
232
      
 
233
      col_val = drizzle_stmt_get_bigint(sth, cur_column-1, &driz_ret);
 
234
      ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), cur_column, cur_row);
 
235
      col_strval = drizzle_stmt_get_string(sth, cur_column-1, &lth, &driz_ret);
 
236
      ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
 
237
      ASSERT_EQ(lth, strlen(col_strval));
 
238
      col_dblval = drizzle_stmt_get_double(sth, cur_column-1, &driz_ret);
 
239
      ASSERT_TRUE_(driz_ret == DRIZZLE_RETURN_OK || driz_ret == DRIZZLE_RETURN_TRUNCATED, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), cur_column, cur_row);
 
240
      
 
241
      printf("  Column %d: %"PRIdMAX"  \"%s\"   %f\n", cur_column, col_val, col_strval, col_dblval);
 
242
      
 
243
      if (columnA == 3)
 
244
        continue;
 
245
      
 
246
      ASSERT_EQ_(expect_val, col_val, "Column %d of row %d: expected %"PRIdMAX", got %"PRIdMAX,
 
247
                 cur_column, cur_row, expect_val, col_val);
 
248
      if (cur_column <= 5) {
 
249
        uint32_t col_narrowval = drizzle_stmt_get_int(sth, cur_column-1, &driz_ret);
 
250
        ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), cur_column, cur_row);
 
251
        ASSERT_EQ_(col_val, col_narrowval, "column %d of row %d: get_bigint returns %"PRIdMAX", get_int returns %"PRId32,
 
252
                   cur_column, cur_row, col_val, col_narrowval);
 
253
      }
 
254
      ASSERT_FLOATEQEXACT((double)expect_val, col_dblval);
 
255
      
 
256
      snprintf(expect_strval, 64, "%"PRIdMAX, expect_val);
 
257
      ASSERT_STREQ(expect_strval, col_strval);
 
258
    }
 
259
    
 
260
    float expect_floatval;
 
261
    double expect_dblval;
 
262
    switch (columnA) {
 
263
      case 1:
 
264
        expect_floatval = 1.0;
 
265
        expect_dblval = 1.0;
 
266
        break;
 
267
      case 2:
 
268
      case 4:
 
269
        expect_floatval = 443664.0;
 
270
        expect_dblval = 291.2711110711098;
 
271
        break;
 
272
      case 3:
 
273
        expect_floatval = 443665.0;
 
274
        expect_dblval = 292.2711110711098;
 
275
        break;
 
276
    }
 
277
    
 
278
    col_val = drizzle_stmt_get_int(sth, 6, &driz_ret);
 
279
    ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_TRUNCATED, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), cur_column, cur_row);
 
280
    ASSERT_FLOATEQEXACT((float)col_val, trunc(expect_floatval));
 
281
    
 
282
    col_val = drizzle_stmt_get_bigint(sth, 6, &driz_ret);
 
283
    ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_TRUNCATED, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), cur_column, cur_row);
 
284
    ASSERT_FLOATEQEXACT((float)col_val, trunc(expect_floatval));
 
285
    
 
286
    col_dblval = drizzle_stmt_get_double(sth, 6, &driz_ret);
 
287
    ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), cur_column, cur_row);
 
288
    ASSERT_FLOATEQEXACT(col_dblval, expect_floatval);
 
289
    
 
290
    col_strval = drizzle_stmt_get_string(sth, 6, &lth, &driz_ret);
 
291
    ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
 
292
    
 
293
    printf("  Column %d: %"PRIdMAX"  \"%s\"   %f\n", 7, col_val, col_strval, col_dblval);
 
294
    
 
295
    
 
296
    
 
297
    col_val = drizzle_stmt_get_int(sth, 7, &driz_ret);
 
298
    ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_TRUNCATED, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), cur_column, cur_row);
 
299
    ASSERT_FLOATEQEXACT((double)col_val, trunc(expect_dblval));
 
300
    
 
301
    col_val = drizzle_stmt_get_bigint(sth, 7, &driz_ret);
 
302
    ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_TRUNCATED, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), cur_column, cur_row);
 
303
    ASSERT_FLOATEQEXACT((double)col_val, trunc(expect_dblval));
 
304
    
 
305
    col_dblval = drizzle_stmt_get_double(sth, 7, &driz_ret);
 
306
    ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), cur_column, cur_row);
 
307
    ASSERT_FLOATEQEXACT(col_dblval, expect_dblval);
 
308
    
 
309
    col_strval = drizzle_stmt_get_string(sth, 7, &lth, &driz_ret);
 
310
    ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
 
311
    
 
312
    printf("  Column %d: %"PRIdMAX"  \"%s\"   %f\n", 8, col_val, col_strval, col_dblval);
 
313
  }
 
314
  
 
315
  ASSERT_EQ(cur_row, 4);
 
316
  
 
317
  driz_ret = drizzle_stmt_close(sth);
 
318
  ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s", drizzle_strerror(driz_ret), drizzle_error(con));
 
319
  
 
320
  drizzle_query(con, "DROP TABLE libdrizzle.t1", 0, &driz_ret);
 
321
  ASSERT_EQ_(DRIZZLE_RETURN_OK, driz_ret, "DROP TABLE libdrizzle.t1");
 
322
  
 
323
  tear_down_schema();
 
324
  
 
325
  return EXIT_SUCCESS;
 
326
}