~ubuntu-branches/ubuntu/trusty/mysql-5.6/trusty

« back to all changes in this revision

Viewing changes to unittest/gunit/opt_range-t.cc

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-02-12 11:54:27 UTC
  • Revision ID: package-import@ubuntu.com-20140212115427-oq6tfsqxl1wuwehi
Tags: upstream-5.6.15
ImportĀ upstreamĀ versionĀ 5.6.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
 
15
 
 
16
// First include (the generated) my_config.h, to get correct platform defines.
 
17
#include "my_config.h"
 
18
#include <gtest/gtest.h>
 
19
 
 
20
#include "test_utils.h"
 
21
 
 
22
#include "opt_range.cc"
 
23
 
 
24
namespace opt_range_unittest {
 
25
 
 
26
using my_testing::Server_initializer;
 
27
 
 
28
class SelArgTest : public ::testing::Test
 
29
{
 
30
protected:
 
31
  SelArgTest()
 
32
  {
 
33
    memset(&m_opt_param, 0, sizeof(m_opt_param));
 
34
  }
 
35
 
 
36
  virtual void SetUp()
 
37
  {
 
38
    initializer.SetUp();
 
39
    m_opt_param.thd= thd();
 
40
    m_opt_param.mem_root= &m_alloc;
 
41
    m_opt_param.current_table= 1<<0;
 
42
    init_sql_alloc(&m_alloc, thd()->variables.range_alloc_block_size, 0);
 
43
  }
 
44
 
 
45
  virtual void TearDown()
 
46
  {
 
47
    initializer.TearDown();
 
48
    free_root(&m_alloc, MYF(0));
 
49
  }
 
50
 
 
51
  THD *thd() { return initializer.thd(); }
 
52
 
 
53
  Server_initializer initializer;
 
54
  MEM_ROOT           m_alloc;
 
55
  RANGE_OPT_PARAM    m_opt_param;
 
56
};
 
57
 
 
58
/*
 
59
 Experiment with these to measure performance of
 
60
   'new (thd->mem_root)' Foo vs. 'new Foo'.
 
61
 With gcc 4.4.2 I see ~4% difference (in optimized mode).
 
62
*/
 
63
const int num_iterations= 10;
 
64
const int num_allocs= 10;
 
65
 
 
66
TEST_F(SelArgTest, AllocateExplicit)
 
67
{
 
68
  for (int ix= 0; ix < num_iterations; ++ix)
 
69
  {
 
70
    free_root(thd()->mem_root, MYF(MY_KEEP_PREALLOC));
 
71
    for (int ii= 0; ii < num_allocs; ++ii)
 
72
      new (thd()->mem_root) SEL_ARG;
 
73
  }
 
74
}
 
75
 
 
76
TEST_F(SelArgTest, AllocateImplicit)
 
77
{
 
78
  for (int ix= 0; ix < num_iterations; ++ix)
 
79
  {
 
80
    free_root(thd()->mem_root, MYF(MY_KEEP_PREALLOC));
 
81
    for (int ii= 0; ii < num_allocs; ++ii)
 
82
      new SEL_ARG;
 
83
  }
 
84
}
 
85
 
 
86
/*
 
87
  We cannot do EXPECT_NE(NULL, get_mm_tree(...))
 
88
  because of limits in google test.
 
89
 */
 
90
const SEL_TREE *null_tree= NULL;
 
91
const SEL_ARG  *null_arg= NULL;
 
92
 
 
93
 
 
94
class Mock_field_long : public Field_long
 
95
{
 
96
public:
 
97
  Mock_field_long(THD *thd, Item *item)
 
98
    : Field_long(0,                             // ptr_arg
 
99
                 8,                             // len_arg
 
100
                 NULL,                          // null_ptr_arg
 
101
                 0,                             // null_bit_arg
 
102
                 Field::NONE,                   // unireg_check_arg
 
103
                 "field_name",                  // field_name_arg
 
104
                 false,                         // zero_arg
 
105
                 false)                         // unsigned_arg
 
106
  {
 
107
    m_table_name= "mock_table";
 
108
    memset(&m_share, 0, sizeof(m_share));
 
109
    const char *foo= "mock_db";
 
110
    m_share.db.str= const_cast<char*>(foo);
 
111
    m_share.db.length= strlen(m_share.db.str);
 
112
 
 
113
    bitmap_init(&share_allset, 0, sizeof(my_bitmap_map), 0);
 
114
    bitmap_set_above(&share_allset, 0, 1); //all bits 1
 
115
    m_share.all_set= share_allset;
 
116
 
 
117
    memset(&m_table, 0, sizeof(m_table));
 
118
    m_table.s= &m_share;
 
119
 
 
120
    bitmap_init(&tbl_readset, 0, sizeof(my_bitmap_map), 0);
 
121
    m_table.read_set= &tbl_readset;
 
122
 
 
123
    bitmap_init(&tbl_writeset, 0, sizeof(my_bitmap_map), 0);
 
124
    m_table.write_set= &tbl_writeset;
 
125
 
 
126
    m_table.map= 1<<0;
 
127
    m_table.in_use= thd;
 
128
    this->table_name= &m_table_name;
 
129
    this->table= &m_table;
 
130
    this->ptr= (uchar*) alloc_root((thd->mem_root), KEY_LENGTH);
 
131
    if (item)
 
132
      item->save_in_field_no_warnings(this, true);      
 
133
  }
 
134
  ~Mock_field_long()
 
135
  {
 
136
    bitmap_free(&share_allset);
 
137
    bitmap_free(&tbl_readset);
 
138
    bitmap_free(&tbl_writeset);
 
139
  }
 
140
 
 
141
  // #bytes to store the value - see Field_long::key_lenght()
 
142
  static const int KEY_LENGTH= 4;
 
143
  const char *m_table_name;
 
144
  TABLE_SHARE m_share;
 
145
  TABLE       m_table;
 
146
  MY_BITMAP   share_allset;
 
147
  MY_BITMAP   tbl_readset;
 
148
  MY_BITMAP   tbl_writeset;
 
149
};
 
150
 
 
151
 
 
152
static void print_selarg_ranges(String *s, SEL_ARG *sel_arg, 
 
153
                                const KEY_PART_INFO *kpi)
 
154
{
 
155
  for (SEL_ARG *cur= sel_arg->first(); 
 
156
       cur != &null_element; 
 
157
       cur= cur->right)
 
158
  {
 
159
    String current_range;
 
160
    append_range(&current_range, kpi, cur->min_value, cur->max_value, 
 
161
                 cur->min_flag | cur->max_flag);
 
162
 
 
163
    if (s->length() > 0)
 
164
      s->append(STRING_WITH_LEN("\n"));
 
165
 
 
166
    s->append(current_range);
 
167
  }
 
168
}
 
169
 
 
170
 
 
171
TEST_F(SelArgTest, SimpleCond)
 
172
{
 
173
  EXPECT_NE(null_tree, get_mm_tree(&m_opt_param, new Item_int(42)));
 
174
}
 
175
 
 
176
 
 
177
/*
 
178
  TODO: Here we try to build a range, but a lot of mocking remains
 
179
  before it works as intended. Currently get_mm_tree() returns NULL
 
180
  because m_opt_param.key_parts and m_opt_param.key_parts_end have not
 
181
  been setup. 
 
182
*/
 
183
TEST_F(SelArgTest, EqualCond)
 
184
{
 
185
  Mock_field_long field_long(thd(), NULL);
 
186
  m_opt_param.table= &field_long.m_table;
 
187
  SEL_TREE *tree= get_mm_tree(&m_opt_param,
 
188
                              new Item_equal(new Item_int(42),
 
189
                                             new Item_field(&field_long)));
 
190
  EXPECT_EQ(null_tree, tree);
 
191
}
 
192
 
 
193
 
 
194
TEST_F(SelArgTest, SelArgOnevalue)
 
195
{
 
196
  Mock_field_long field_long7(thd(), new Item_int(7));
 
197
 
 
198
  KEY_PART_INFO kpi;
 
199
  kpi.init_from_field(&field_long7);
 
200
 
 
201
  uchar range_val7[field_long7.KEY_LENGTH];
 
202
  field_long7.get_key_image(range_val7, kpi.length, Field::itRAW);
 
203
 
 
204
  SEL_ARG sel_arg7(&field_long7, range_val7, range_val7);
 
205
  String range_string;
 
206
  print_selarg_ranges(&range_string, &sel_arg7, &kpi);
 
207
  const char expected[]= "7 <= field_name <= 7";
 
208
  EXPECT_STREQ(expected, range_string.c_ptr());
 
209
 
 
210
  sel_arg7.min_flag|= NO_MIN_RANGE;
 
211
  range_string.length(0);
 
212
  print_selarg_ranges(&range_string, &sel_arg7, &kpi);
 
213
  const char expected2[]= "field_name <= 7";
 
214
  EXPECT_STREQ(expected2, range_string.c_ptr());
 
215
 
 
216
  sel_arg7.max_flag= NEAR_MAX;
 
217
  range_string.length(0);
 
218
  print_selarg_ranges(&range_string, &sel_arg7, &kpi);
 
219
  const char expected3[]= "field_name < 7";
 
220
  EXPECT_STREQ(expected3, range_string.c_ptr());
 
221
 
 
222
  sel_arg7.min_flag= NEAR_MIN;
 
223
  sel_arg7.max_flag= NO_MAX_RANGE;
 
224
  range_string.length(0);
 
225
  print_selarg_ranges(&range_string, &sel_arg7, &kpi);
 
226
  const char expected4[]= "7 < field_name";
 
227
  EXPECT_STREQ(expected4, range_string.c_ptr());
 
228
 
 
229
  sel_arg7.min_flag= 0;
 
230
  range_string.length(0);
 
231
  print_selarg_ranges(&range_string, &sel_arg7, &kpi);
 
232
  const char expected5[]= "7 <= field_name";
 
233
  EXPECT_STREQ(expected5, range_string.c_ptr());
 
234
}
 
235
 
 
236
 
 
237
TEST_F(SelArgTest, SelArgBetween)
 
238
{
 
239
  Mock_field_long field_long3(thd(), new Item_int(3));
 
240
  Mock_field_long field_long5(thd(), new Item_int(5));
 
241
 
 
242
  KEY_PART_INFO kpi;
 
243
  kpi.init_from_field(&field_long3);
 
244
 
 
245
  uchar range_val3[field_long3.KEY_LENGTH];
 
246
  field_long3.get_key_image(range_val3, kpi.length, Field::itRAW);
 
247
 
 
248
  uchar range_val5[field_long5.KEY_LENGTH];
 
249
  field_long5.get_key_image(range_val5, kpi.length, Field::itRAW);
 
250
 
 
251
  SEL_ARG sel_arg35(&field_long3, range_val3, range_val5);
 
252
 
 
253
  String range_string;
 
254
  print_selarg_ranges(&range_string, &sel_arg35, &kpi);
 
255
  const char expected[]= "3 <= field_name <= 5";
 
256
  EXPECT_STREQ(expected, range_string.c_ptr());
 
257
 
 
258
  range_string.length(0);
 
259
  sel_arg35.min_flag= NEAR_MIN;
 
260
  print_selarg_ranges(&range_string, &sel_arg35, &kpi);
 
261
  const char expected2[]= "3 < field_name <= 5";
 
262
  EXPECT_STREQ(expected2, range_string.c_ptr());
 
263
 
 
264
  range_string.length(0);
 
265
  sel_arg35.max_flag= NEAR_MAX;
 
266
  print_selarg_ranges(&range_string, &sel_arg35, &kpi);
 
267
  const char expected3[]= "3 < field_name < 5";
 
268
  EXPECT_STREQ(expected3, range_string.c_ptr());
 
269
 
 
270
  range_string.length(0);
 
271
  sel_arg35.min_flag= 0;
 
272
  print_selarg_ranges(&range_string, &sel_arg35, &kpi);
 
273
  const char expected4[]= "3 <= field_name < 5";
 
274
  EXPECT_STREQ(expected4, range_string.c_ptr());
 
275
 
 
276
  range_string.length(0);
 
277
  sel_arg35.min_flag= NO_MIN_RANGE;
 
278
  sel_arg35.max_flag= 0;
 
279
  print_selarg_ranges(&range_string, &sel_arg35, &kpi);
 
280
  const char expected5[]= "field_name <= 5";
 
281
  EXPECT_STREQ(expected5, range_string.c_ptr());
 
282
 
 
283
  range_string.length(0);
 
284
  sel_arg35.min_flag= 0;
 
285
  sel_arg35.max_flag= NO_MAX_RANGE;
 
286
  print_selarg_ranges(&range_string, &sel_arg35, &kpi);
 
287
  const char expected6[]= "3 <= field_name";
 
288
  EXPECT_STREQ(expected6, range_string.c_ptr());
 
289
}
 
290
 
 
291
TEST_F(SelArgTest, CopyMax)
 
292
{
 
293
  Mock_field_long field_long3(thd(), new Item_int(3));
 
294
  Mock_field_long field_long5(thd(), new Item_int(5));
 
295
 
 
296
  KEY_PART_INFO kpi;
 
297
  kpi.init_from_field(&field_long3);
 
298
 
 
299
  uchar range_val3[field_long3.KEY_LENGTH];
 
300
  field_long3.get_key_image(range_val3, kpi.length, Field::itRAW);
 
301
 
 
302
  uchar range_val5[field_long5.KEY_LENGTH];
 
303
  field_long5.get_key_image(range_val5, kpi.length, Field::itRAW);
 
304
 
 
305
  SEL_ARG sel_arg3(&field_long3, range_val3, range_val3);
 
306
  sel_arg3.min_flag= NO_MIN_RANGE;
 
307
  SEL_ARG sel_arg5(&field_long5, range_val5, range_val5);
 
308
  sel_arg5.min_flag= NO_MIN_RANGE;
 
309
 
 
310
  String range_string;
 
311
  print_selarg_ranges(&range_string, &sel_arg3, &kpi);
 
312
  const char expected[]= "field_name <= 3";
 
313
  EXPECT_STREQ(expected, range_string.c_ptr());
 
314
 
 
315
  range_string.length(0);
 
316
  print_selarg_ranges(&range_string, &sel_arg5, &kpi);
 
317
  const char expected2[]= "field_name <= 5";
 
318
  EXPECT_STREQ(expected2, range_string.c_ptr());
 
319
 
 
320
  /*
 
321
    Ranges now:
 
322
                       -inf ----------------3-5----------- +inf
 
323
    sel_arg3:          [-------------------->
 
324
    sel_arg5:          [---------------------->
 
325
    Below: merge these two ranges into sel_arg3 using copy_max()
 
326
  */
 
327
  bool full_range= sel_arg3.copy_max(&sel_arg5);
 
328
  // The merged range does not cover all possible values
 
329
  EXPECT_FALSE(full_range);
 
330
 
 
331
  range_string.length(0);
 
332
  print_selarg_ranges(&range_string, &sel_arg3, &kpi);
 
333
  const char expected3[]= "field_name <= 5";
 
334
  EXPECT_STREQ(expected3, range_string.c_ptr());
 
335
 
 
336
  range_string.length(0);
 
337
  sel_arg5.min_flag= 0;
 
338
  sel_arg5.max_flag= NO_MAX_RANGE;
 
339
  print_selarg_ranges(&range_string, &sel_arg5, &kpi);
 
340
  const char expected4[]= "5 <= field_name";
 
341
  EXPECT_STREQ(expected4, range_string.c_ptr());
 
342
 
 
343
  /*
 
344
    Ranges now:
 
345
                       -inf ----------------3-5----------- +inf
 
346
    sel_arg3:          [---------------------->
 
347
    sel_arg5:                                 <---------------]
 
348
    Below: merge these two ranges into sel_arg3 using copy_max()
 
349
  */
 
350
 
 
351
  full_range= sel_arg3.copy_max(&sel_arg5);
 
352
  // The new range covers all possible values
 
353
  EXPECT_TRUE(full_range);
 
354
 
 
355
  range_string.length(0);
 
356
  print_selarg_ranges(&range_string, &sel_arg3, &kpi);
 
357
  const char expected5[]= "field_name";
 
358
  EXPECT_STREQ(expected5, range_string.c_ptr());
 
359
}
 
360
 
 
361
TEST_F(SelArgTest, CopyMin)
 
362
{
 
363
  Mock_field_long field_long3(thd(), new Item_int(3));
 
364
  Mock_field_long field_long5(thd(), new Item_int(5));
 
365
 
 
366
  KEY_PART_INFO kpi;
 
367
  kpi.init_from_field(&field_long3);
 
368
 
 
369
  uchar range_val3[field_long3.KEY_LENGTH];
 
370
  field_long3.get_key_image(range_val3, kpi.length, Field::itRAW);
 
371
 
 
372
  uchar range_val5[field_long5.KEY_LENGTH];
 
373
  field_long5.get_key_image(range_val5, kpi.length, Field::itRAW);
 
374
 
 
375
  SEL_ARG sel_arg3(&field_long3, range_val3, range_val3);
 
376
  sel_arg3.max_flag= NO_MAX_RANGE;
 
377
  SEL_ARG sel_arg5(&field_long5, range_val5, range_val5);
 
378
  sel_arg5.max_flag= NO_MAX_RANGE;
 
379
 
 
380
  String range_string;
 
381
  print_selarg_ranges(&range_string, &sel_arg3, &kpi);
 
382
  const char expected[]= "3 <= field_name";
 
383
  EXPECT_STREQ(expected, range_string.c_ptr());
 
384
 
 
385
  range_string.length(0);
 
386
  print_selarg_ranges(&range_string, &sel_arg5, &kpi);
 
387
  const char expected2[]= "5 <= field_name";
 
388
  EXPECT_STREQ(expected2, range_string.c_ptr());
 
389
 
 
390
  /*
 
391
    Ranges now:
 
392
                       -inf ----------------3-5----------- +inf
 
393
    sel_arg3:                               <-----------------]
 
394
    sel_arg5:                                 <---------------]
 
395
    Below: merge these two ranges into sel_arg3 using copy_max()
 
396
  */
 
397
  bool full_range= sel_arg5.copy_min(&sel_arg3);
 
398
  // The merged range does not cover all possible values
 
399
  EXPECT_FALSE(full_range);
 
400
 
 
401
  range_string.length(0);
 
402
  print_selarg_ranges(&range_string, &sel_arg5, &kpi);
 
403
  const char expected3[]= "3 <= field_name";
 
404
  EXPECT_STREQ(expected3, range_string.c_ptr());
 
405
 
 
406
  range_string.length(0);
 
407
  sel_arg3.max_flag= 0;
 
408
  sel_arg3.min_flag= NO_MIN_RANGE;
 
409
  print_selarg_ranges(&range_string, &sel_arg3, &kpi);
 
410
  const char expected4[]= "field_name <= 3";
 
411
  EXPECT_STREQ(expected4, range_string.c_ptr());
 
412
 
 
413
  /*
 
414
    Ranges now:
 
415
                       -inf ----------------3-5----------- +inf
 
416
    sel_arg3:          [-------------------->                
 
417
    sel_arg5:                               <-----------------]
 
418
    Below: merge these two ranges into sel_arg5 using copy_min()
 
419
  */
 
420
 
 
421
  full_range= sel_arg5.copy_min(&sel_arg3);
 
422
  // The new range covers all possible values
 
423
  EXPECT_TRUE(full_range);
 
424
 
 
425
  range_string.length(0);
 
426
  print_selarg_ranges(&range_string, &sel_arg5, &kpi);
 
427
  const char expected5[]= "field_name";
 
428
  EXPECT_STREQ(expected5, range_string.c_ptr());
 
429
}
 
430
 
 
431
 
 
432
TEST_F(SelArgTest, KeyOr1)
 
433
{
 
434
  Mock_field_long field_long3(thd(), new Item_int(3));
 
435
  Mock_field_long field_long4(thd(), new Item_int(4));
 
436
 
 
437
  KEY_PART_INFO kpi;
 
438
  kpi.init_from_field(&field_long3);
 
439
 
 
440
  uchar range_val3[field_long3.KEY_LENGTH];
 
441
  field_long3.get_key_image(range_val3, kpi.length, Field::itRAW);
 
442
 
 
443
  uchar range_val4[field_long4.KEY_LENGTH];
 
444
  field_long4.get_key_image(range_val4, kpi.length, Field::itRAW);
 
445
 
 
446
  SEL_ARG sel_arg_lt3(&field_long3, range_val3, range_val3);
 
447
  sel_arg_lt3.part= 0;
 
448
  sel_arg_lt3.min_flag= NO_MIN_RANGE;
 
449
  sel_arg_lt3.max_flag= NEAR_MAX;
 
450
 
 
451
  SEL_ARG sel_arg_gt3(&field_long3, range_val3, range_val3);
 
452
  sel_arg_gt3.part= 0;
 
453
  sel_arg_gt3.min_flag= NEAR_MIN;
 
454
  sel_arg_gt3.max_flag= NO_MAX_RANGE;
 
455
 
 
456
  SEL_ARG sel_arg_lt4(&field_long4, range_val4, range_val4);
 
457
  sel_arg_lt4.part= 0;
 
458
  sel_arg_lt4.min_flag= NO_MIN_RANGE;
 
459
  sel_arg_lt4.max_flag= NEAR_MAX;
 
460
 
 
461
  String range_string;
 
462
  print_selarg_ranges(&range_string, &sel_arg_lt3, &kpi);
 
463
  const char expected_lt3[]= "field_name < 3";
 
464
  EXPECT_STREQ(expected_lt3, range_string.c_ptr());
 
465
 
 
466
  range_string.length(0);
 
467
  print_selarg_ranges(&range_string, &sel_arg_gt3, &kpi);
 
468
  const char expected_gt3[]= "3 < field_name";
 
469
  EXPECT_STREQ(expected_gt3, range_string.c_ptr());
 
470
 
 
471
  range_string.length(0);
 
472
  print_selarg_ranges(&range_string, &sel_arg_lt4, &kpi);
 
473
  const char expected_lt4[]= "field_name < 4";
 
474
  EXPECT_STREQ(expected_lt4, range_string.c_ptr());
 
475
 
 
476
 
 
477
  /*
 
478
    Ranges now:
 
479
                       -inf ----------------34----------- +inf
 
480
    sel_arg_lt3:       [-------------------->
 
481
    sel_arg_gt3:                             <---------------]
 
482
    sel_arg_lt4:       [--------------------->
 
483
  */
 
484
 
 
485
  SEL_ARG *tmp= key_or(NULL, &sel_arg_lt3, &sel_arg_gt3);
 
486
 
 
487
  /*
 
488
    Ranges now:
 
489
                       -inf ----------------34----------- +inf
 
490
    tmp:               [--------------------><---------------]
 
491
    sel_arg_lt4:       [--------------------->
 
492
  */
 
493
  range_string.length(0);
 
494
  print_selarg_ranges(&range_string, tmp, &kpi);
 
495
  const char expected_merged[]= 
 
496
    "field_name < 3\n"
 
497
    "3 < field_name";
 
498
  EXPECT_STREQ(expected_merged, range_string.c_ptr());
 
499
 
 
500
  SEL_ARG *tmp2= key_or(NULL, tmp, &sel_arg_lt4);
 
501
  EXPECT_EQ(null_arg, tmp2);
 
502
}
 
503
 
 
504
}
 
505
 
 
506