~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to tests/kewpie/randgen/conf/optimizer/optimizer_subquery.yy

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2012-06-19 10:46:49 UTC
  • mfrom: (1.1.6)
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20120619104649-e2l0ggd4oz3um0f4
Tags: upstream-7.1.36-stable
ImportĀ upstreamĀ versionĀ 7.1.36-stable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (c) 2008, 2011 Oracle and/or its affiliates. All rights reserved.
 
2
# Use is subject to license terms.
 
3
#
 
4
# This program is free software; you can redistribute it and/or modify
 
5
# it under the terms of the GNU General Public License as published by
 
6
# the Free Software Foundation; version 2 of the License.
 
7
#
 
8
# This program is distributed in the hope that it will be useful, but
 
9
# WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
11
# General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 
16
# USA
 
17
 
 
18
# **NOTE** Joins for this grammar are currently not working as intended.
 
19
# For example, if we have tables 1, 2, and 3, we end up with ON conditions that 
 
20
# only involve tables 2 and 3.
 
21
# This will be fixed, but initial attempts at altering this had a negative 
 
22
# impact on the coverage the test was providing.  To be fixed when scheduling 
 
23
# permits.  We are still seeing significant coverage with the grammar as-is.
 
24
 
 
25
################################################################################
 
26
# optimizer_subquery.yy:  Random Query Generator grammar for testing subquery  #
 
27
#                    optimizations.  This grammar *should* hit the             # 
 
28
#                    optimizations listed here:                                #
 
29
#                    https://inside.mysql.com/wiki/Optimizer_grammar_worksheet #
 
30
# see:  WL#5006 Random Query Generator testing of Azalea Optimizer- subqueries #
 
31
#       https://intranet.mysql.com/worklog/QA-Sprint/?tid=5006                 #
 
32
#                                                                              #
 
33
# recommendations:                                                             #
 
34
#       queries: 10k+.  We can see a lot with lower values, but over 10k is    #
 
35
#                best.  The intersect optimization happens with low frequency  #
 
36
#                so larger values help us to hit it at least some of the time  #
 
37
#       engines: MyISAM *and* Innodb.  Certain optimizations are only hit with #
 
38
#                one engine or another and we should use both to ensure we     #
 
39
#                are getting maximum coverage                                  #
 
40
#       Validators:  ResultsetComparatorSimplify                               #
 
41
#                      - used on server-server comparisons                     #
 
42
#                    Transformer - used on a single server                     #
 
43
#                      - creates equivalent versions of a single query         # 
 
44
#                    SelectStability - used on a single server                 #
 
45
#                      - ensures the same query produces stable result sets    #
 
46
################################################################################
 
47
 
 
48
################################################################################
 
49
# The perl code in {} helps us with bookkeeping for writing more sensible      #
 
50
# queries.  We need to keep track of these items to ensure we get interesting  #
 
51
# and stable queries that find bugs rather than wondering if our query is      #
 
52
# dodgy.                                                                       #
 
53
################################################################################
 
54
query:
 
55
        { @nonaggregates = () ; $tables = 0 ; $fields = 0 ; $subquery_idx=0 ; $child_subquery_idx=0 ; "" } main_select ;
 
56
 
 
57
main_select:
 
58
        simple_select | simple_select | simple_select | simple_select |
 
59
        mixed_select |  mixed_select |  mixed_select |  mixed_select  | 
 
60
        aggregate_select ;
 
61
 
 
62
mixed_select:
 
63
        explain_extended SELECT distinct straight_join select_option select_list
 
64
        FROM join_list
 
65
        where_clause
 
66
        group_by_clause 
 
67
        having_clause
 
68
        order_by_clause ;
 
69
 
 
70
simple_select:
 
71
        explain_extended SELECT distinct straight_join select_option simple_select_list
 
72
        FROM join_list
 
73
        where_clause
 
74
        optional_group_by 
 
75
        having_clause
 
76
        order_by_clause ;
 
77
 
 
78
aggregate_select:
 
79
        explain_extended SELECT distinct straight_join select_option aggregate_select_list
 
80
        FROM join_list
 
81
        where_clause
 
82
        optional_group_by 
 
83
        having_clause
 
84
        order_by_clause ;
 
85
 
 
86
explain_extended:       
 
87
        | | | | | | | | | explain_extended2 ;
 
88
 
 
89
explain_extended2: | | | | EXPLAIN | EXPLAIN EXTENDED ; 
 
90
       
 
91
distinct: DISTINCT | | | | | | | | | ;
 
92
 
 
93
select_option:  | | | | | | | | | | | SQL_SMALL_RESULT ;
 
94
 
 
95
straight_join:  | | | | | | | | | | | | | | | | | | | | | STRAIGHT_JOIN ;
 
96
 
 
97
select_list:
 
98
        new_select_item |
 
99
        new_select_item , select_list |
 
100
        new_select_item , select_list ;
 
101
 
 
102
simple_select_list:
 
103
        nonaggregate_select_item |
 
104
        nonaggregate_select_item , simple_select_list |
 
105
        nonaggregate_select_item , simple_select_list ;
 
106
 
 
107
aggregate_select_list:
 
108
        aggregate_select_item | aggregate_select_item |
 
109
        aggregate_select_item, aggregate_select_list ;
 
110
 
 
111
join_list:
 
112
################################################################################
 
113
# this limits us to 2 and 3 table joins / can use it if we hit                 #
 
114
# too many mega-join conditions which take too long to run                     #
 
115
################################################################################
 
116
        ( new_table_item join_type new_table_item ON (join_condition_item ) ) |
 
117
        ( new_table_item join_type ( ( new_table_item join_type new_table_item ON (join_condition_item ) ) ) ON (join_condition_item ) ) |
 
118
        ( new_table_item , new_table_item ) |
 
119
        ( new_table_item , new_table_item , new_table_item ) ;
 
120
 
 
121
 
 
122
join_list_disabled:
 
123
################################################################################
 
124
# preventing deep join nesting for run time / table access methods are more    #
 
125
# important here - join.yy can provide deeper join coverage                    #
 
126
# Enabling this / swapping out with join_list above can produce some           #
 
127
# time-consuming queries.                                                      #
 
128
################################################################################
 
129
 
 
130
        new_table_item |
 
131
        ( new_table_item join_type join_list ON (join_condition_item ) ) ;
 
132
 
 
133
join_type:
 
134
        INNER JOIN | left_right outer JOIN |
 
135
        INNER JOIN | left_right outer JOIN |
 
136
        INNER JOIN | left_right outer JOIN |
 
137
        INNER JOIN | left_right outer JOIN |
 
138
        INNER JOIN | left_right outer JOIN |
 
139
        STRAIGHT_JOIN ;  
 
140
 
 
141
join_condition_item:
 
142
    current_table_item . int_indexed = previous_table_item . int_field_name on_subquery |
 
143
    current_table_item . int_field_name = previous_table_item . int_indexed on_subquery |
 
144
    current_table_item . `col_varchar_key` = previous_table_item . char_field_name on_subquery |
 
145
    current_table_item . char_field_name = previous_table_item . `col_varchar_key` on_subquery ;
 
146
 
 
147
on_subquery:
 
148
    |||||||||||||||||||| { $subquery_idx += 1 ; $subquery_tables=0 ; ""} and_or general_subquery ;
 
149
 
 
150
 
 
151
left_right:
 
152
        LEFT | RIGHT ;
 
153
 
 
154
outer:
 
155
        | OUTER ;
 
156
 
 
157
where_clause:
 
158
        WHERE where_subquery |
 
159
        WHERE ( where_subquery ) and_or where_list |
 
160
        WHERE ( where_subquery ) and_or where_list ;
 
161
 
 
162
 
 
163
where_list:
 
164
        generic_where_list |
 
165
        range_predicate1_list | range_predicate2_list |
 
166
        range_predicate1_list and_or generic_where_list |
 
167
        range_predicate2_list and_or generic_where_list ; 
 
168
 
 
169
 
 
170
generic_where_list:
 
171
        where_item |
 
172
        ( where_item and_or where_item ) ;
 
173
 
 
174
not:
 
175
        | | | NOT;
 
176
 
 
177
where_item:
 
178
        where_subquery  |  
 
179
        alias1 . int_field_name arithmetic_operator existing_table_item . int_field_name  |
 
180
        existing_table_item . char_field_name arithmetic_operator _char  |
 
181
        existing_table_item . char_field_name arithmetic_operator existing_table_item . char_field_name |
 
182
        alias1 . _field IS not NULL |
 
183
        alias1 . int_field_name arithmetic_operator existing_table_item . int_field_name  |
 
184
        existing_table_item . char_field_name arithmetic_operator _char  |
 
185
        existing_table_item . char_field_name arithmetic_operator existing_table_item . char_field_name |
 
186
        alias1 . _field IS not NULL ;
 
187
 
 
188
################################################################################
 
189
# subquery rules
 
190
################################################################################
 
191
 
 
192
where_subquery:
 
193
    { $subquery_idx += 1 ; $subquery_tables=0 ; ""} subquery_type ;
 
194
 
 
195
subquery_type:
 
196
    general_subquery | special_subquery ;
 
197
 
 
198
general_subquery:
 
199
    existing_table_item . int_field_name arithmetic_operator  int_single_value_subquery  |
 
200
    existing_table_item . char_field_name arithmetic_operator char_single_value_subquery |
 
201
    existing_table_item . int_field_name membership_operator  int_single_member_subquery  |
 
202
    ( existing_table_item . int_field_name , existing_table_item . int_field_name ) not IN int_double_member_subquery |
 
203
    existing_table_item . char_field_name membership_operator  char_single_member_subquery  |
 
204
    ( existing_table_item . char_field_name , existing_table_item . char_field_name ) not IN char_double_member_subquery |
 
205
    ( _digit, _digit ) not IN int_double_member_subquery |
 
206
    ( _char, _char ) not IN char_double_member_subquery |
 
207
    existing_table_item . int_field_name membership_operator int_single_union_subquery |
 
208
    existing_table_item . char_field_name membership_operator char_single_union_subquery ;
 
209
 
 
210
general_subquery_union_test_disabled:
 
211
    existing_table_item . char_field_name arithmetic_operator all_any char_single_union_subquery_disabled |
 
212
    existing_table_item . int_field_name arithmetic_operator all_any int_single_union_subquery_disabled ;
 
213
 
 
214
special_subquery:
 
215
    not EXISTS ( int_single_member_subquery ) |
 
216
    not EXISTS ( char_single_member_subquery ) |
 
217
    not EXISTS int_correlated_subquery |
 
218
    not EXISTS char_correlated_subquery  | 
 
219
    existing_table_item . int_field_name membership_operator  int_correlated_subquery  |
 
220
    existing_table_item . char_field_name membership_operator char_correlated_subquery  |
 
221
    int_single_value_subquery IS not NULL |
 
222
    char_single_value_subquery IS not NULL ;
 
223
 
 
224
int_single_value_subquery:
 
225
    ( SELECT distinct select_option aggregate subquery_table_one_two . int_field_name ) AS { "SQ".$subquery_idx."_field1" } 
 
226
      subquery_body ) |
 
227
    ( SELECT distinct select_option aggregate subquery_table_one_two . int_field_name ) AS { "SQ".$subquery_idx."_field1" } 
 
228
      subquery_body ) |
 
229
    ( SELECT _digit FROM DUAL ) ;
 
230
 
 
231
char_single_value_subquery:
 
232
    ( SELECT distinct select_option aggregate subquery_table_one_two . char_field_name ) AS { "SQ".$subquery_idx."_field1" } 
 
233
      subquery_body ) |
 
234
    ( SELECT distinct select_option aggregate subquery_table_one_two . char_field_name ) AS { "SQ".$subquery_idx."_field1" } 
 
235
      subquery_body ) |
 
236
    ( SELECT _char FROM DUAL ) ;
 
237
   
 
238
int_single_member_subquery:
 
239
    ( SELECT distinct select_option subquery_table_one_two . int_field_name AS { "SQ".$subquery_idx."_field1" }
 
240
      subquery_body 
 
241
      single_subquery_group_by
 
242
      subquery_having ) |
 
243
    ( SELECT _digit FROM DUAL ) ;
 
244
 
 
245
int_single_union_subquery:
 
246
    (  SELECT _digit  UNION all_distinct  SELECT _digit  )  ;
 
247
 
 
248
int_single_union_subquery_disabled:
 
249
    int_single_member_subquery   UNION all_distinct  int_single_member_subquery ;
 
250
 
 
251
int_double_member_subquery:
 
252
    ( SELECT distinct select_option subquery_table_one_two . int_field_name AS { "SQ".$subquery_idx."_field1" } , 
 
253
      subquery_table_one_two . int_field_name AS { "SQ".$subquery_idx."_field2" }
 
254
      subquery_body 
 
255
      double_subquery_group_by
 
256
      subquery_having ) |
 
257
    ( SELECT distinct select_option subquery_table_one_two . int_field_name AS { "SQ".$subquery_idx."_field1" } , 
 
258
      aggregate subquery_table_one_two . int_field_name ) AS { "SQ".$subquery_idx."_field2" }
 
259
      subquery_body 
 
260
      single_subquery_group_by
 
261
      subquery_having ) |
 
262
    (  SELECT _digit , _digit  UNION all_distinct  SELECT _digit, _digit  ) ;
 
263
 
 
264
char_single_member_subquery:
 
265
    ( SELECT distinct select_option subquery_table_one_two . char_field_name AS { "SQ".$subquery_idx."_field1" }
 
266
     subquery_body
 
267
     single_subquery_group_by
 
268
     subquery_having) ;
 
269
 
 
270
char_single_union_subquery:
 
271
    (  SELECT _char  UNION all_distinct  SELECT _char  )  ;
 
272
 
 
273
char_single_union_subquery_disabled:
 
274
    char_single_member_subquery   UNION all_distinct char_single_member_subquery  ;
 
275
 
 
276
char_double_member_subquery:
 
277
   ( SELECT distinct select_option subquery_table_one_two . char_field_name AS { "SQ".$subquery_idx."_field1" } ,
 
278
     subquery_table_one_two . char_field_name AS { "SQ".$subquery_idx."_field2" }
 
279
     subquery_body
 
280
     double_subquery_group_by
 
281
     subquery_having ) |
 
282
   ( SELECT distinct select_option subquery_table_one_two . char_field_name AS { "SQ".$subquery_idx."_field1" } ,
 
283
     aggregate subquery_table_one_two . char_field_name ) AS { "SQ".$subquery_idx."_field2" }
 
284
     subquery_body
 
285
     single_subquery_group_by
 
286
     subquery_having ) |
 
287
   (  SELECT _char , _char  UNION all_distinct  SELECT _char , _char  ) ;
 
288
 
 
289
int_correlated_subquery:
 
290
    ( SELECT distinct select_option subquery_table_one_two . int_field_name AS { "SQ".$subquery_idx."_field1" }
 
291
      FROM subquery_join_list 
 
292
      correlated_subquery_where_clause ) ;
 
293
 
 
294
char_correlated_subquery:
 
295
    ( SELECT distinct select_option subquery_table_one_two . char_field_name AS { "SQ".$subquery_idx."_field1" }
 
296
      FROM subquery_join_list 
 
297
      correlated_subquery_where_clause ) ;
 
298
 
 
299
int_scalar_correlated_subquery:
 
300
     ( SELECT distinct select_option aggregate subquery_table_one_two . int_field_name ) AS { "SQ".$subquery_idx."_field1" }
 
301
      FROM subquery_join_list 
 
302
      correlated_subquery_where_clause ) ;
 
303
 
 
304
subquery_body:
 
305
      FROM subquery_join_list
 
306
      subquery_where_clause ;
 
307
 
 
308
subquery_where_clause:
 
309
    | | WHERE subquery_where_list ;
 
310
 
 
311
correlated_subquery_where_clause:
 
312
    WHERE correlated_subquery_where_list ;
 
313
 
 
314
correlated_subquery_where_list:
 
315
    correlated_subquery_where_item |
 
316
    correlated_subquery_where_item and_or correlated_subquery_where_item |
 
317
    correlated_subquery_where_item and_or subquery_where_item ;
 
318
 
 
319
correlated_subquery_where_item:
 
320
    existing_subquery_table_item . int_field_name arithmetic_operator existing_table_item . int_field_name |
 
321
    existing_subquery_table_item . char_field_name arithmetic_operator existing_table_item . char_field_name ;
 
322
 
 
323
subquery_where_list:
 
324
    subquery_where_item | subquery_where_item | subquery_where_item |
 
325
    ( subquery_where_item and_or subquery_where_item ) ;
 
326
 
 
327
subquery_where_item:
 
328
   existing_subquery_table_item . int_field_name arithmetic_operator _digit |
 
329
   existing_subquery_table_item . char_field_name arithmetic_operator _char |
 
330
   existing_subquery_table_item . int_field_name arithmetic_operator existing_subquery_table_item . int_field_name |
 
331
   existing_subquery_table_item . char_field_name arithmetic_operator existing_subquery_table_item . char_field_name |
 
332
   child_subquery ;
 
333
 
 
334
subquery_join_list:
 
335
   subquery_new_table_item  |  subquery_new_table_item  |
 
336
   ( subquery_new_table_item , subquery_new_table_item ) |
 
337
   ( subquery_new_table_item join_type subquery_new_table_item ON (subquery_join_condition_item ) ) |
 
338
   ( subquery_new_table_item join_type subquery_new_table_item ON (subquery_join_condition_item ) ) |
 
339
   ( subquery_new_table_item join_type ( subquery_new_table_item join_type subquery_new_table_item ON (subquery_join_condition_item )  ) ON (subquery_join_condition_item ) ) ;
 
340
 
 
341
subquery_join_condition_item:
 
342
    subquery_current_table_item . int_field_name = subquery_previous_table_item . int_indexed subquery_on_subquery |
 
343
    subquery_current_table_item . int_indexed = subquery_previous_table_item . int_field_name subquery_on_subquery |
 
344
    subquery_current_table_item . `col_varchar_key` = subquery_previous_table_item . char_field_name subquery_on_subquery |
 
345
    subquery_current_table_item . char_field_name = subquery_previous_table_item . `col_varchar_key` subquery_on_subquery ;
 
346
 
 
347
subquery_on_subquery:
 
348
    |||||||||||||||||||| { $child_subquery_idx += 1 ; $child_subquery_tables=0 ; ""} and_or general_child_subquery ;
 
349
 
 
350
single_subquery_group_by:
 
351
    | | | | | | | | | GROUP BY { "SQ".$subquery_idx."_field1" } ;
 
352
 
 
353
 
 
354
double_subquery_group_by:
 
355
    | | | | | | | | | GROUP BY { "SQ".$subquery_idx."_field1" } ,  { "SQ".$subquery_idx."_field2" } ;
 
356
 
 
357
subquery_having:
 
358
    | | | | | | | | | | HAVING subquery_having_list ;
 
359
 
 
360
subquery_having_list:
 
361
        subquery_having_item |
 
362
        subquery_having_item |
 
363
        (subquery_having_list and_or subquery_having_item)  ;
 
364
 
 
365
subquery_having_item:
 
366
        existing_subquery_table_item . int_field_name arithmetic_operator _digit |
 
367
        existing_subquery_table_item . int_field_name arithmetic_operator _char ;
 
368
 
 
369
 
 
370
################################################################################
 
371
# Child subquery rules
 
372
################################################################################
 
373
 
 
374
child_subquery:
 
375
    { $child_subquery_idx += 1 ; $child_subquery_tables=0 ; ""} child_subquery_type ;
 
376
 
 
377
child_subquery_type:
 
378
    general_child_subquery | special_child_subquery ;
 
379
 
 
380
general_child_subquery:
 
381
    existing_subquery_table_item . int_field_name arithmetic_operator  int_single_value_child_subquery  |
 
382
    existing_subquery_table_item . char_field_name arithmetic_operator char_single_value_child_subquery |
 
383
    existing_subquery_table_item . int_field_name membership_operator  int_single_member_child_subquery  |
 
384
    ( existing_subquery_table_item . int_field_name , existing_subquery_table_item . int_field_name ) not IN int_double_member_child_subquery |
 
385
    existing_subquery_table_item . char_field_name membership_operator  char_single_member_child_subquery  |
 
386
    ( existing_subquery_table_item . char_field_name , existing_subquery_table_item . char_field_name ) not IN char_double_member_child_subquery |
 
387
    ( _digit, _digit ) not IN int_double_member_child_subquery |
 
388
    ( _char, _char ) not IN char_double_member_child_subquery |
 
389
    existing_subquery_table_item . int_field_name membership_operator int_single_union_child_subquery |
 
390
    existing_subquery_table_item . char_field_name membership_operator char_single_union_child_subquery ;
 
391
 
 
392
special_child_subquery:
 
393
    not EXISTS ( int_single_member_child_subquery ) |
 
394
    not EXISTS ( char_single_member_child_subquery ) |
 
395
    not EXISTS int_correlated_child_subquery |
 
396
    not EXISTS char_correlated_child_subquery |
 
397
    existing_subquery_table_item . int_field_name membership_operator  int_correlated_child_subquery  |
 
398
    existing_subquery_table_item . char_field_name membership_operator char_correlated_child_subquery ;
 
399
 
 
400
 
 
401
int_single_value_child_subquery:
 
402
    ( SELECT distinct select_option aggregate child_subquery_table_one_two . int_field_name ) AS { "C_SQ".$child_subquery_idx."_field1" } 
 
403
      child_subquery_body ) ;
 
404
 
 
405
char_single_value_child_subquery:
 
406
    ( SELECT distinct select_option aggregate child_subquery_table_one_two . char_field_name ) AS { "C_SQ".$child_subquery_idx."_field1" } 
 
407
      child_subquery_body ) ;
 
408
   
 
409
int_single_member_child_subquery:
 
410
    ( SELECT distinct select_option child_subquery_table_one_two . int_field_name AS { "C_SQ".$child_subquery_idx."_field1" }
 
411
      child_subquery_body 
 
412
      single_child_subquery_group_by
 
413
      child_subquery_having ) ;
 
414
 
 
415
int_single_union_child_subquery:
 
416
    (  SELECT _digit  UNION all_distinct  SELECT _digit  )  ;
 
417
 
 
418
int_double_member_child_subquery:
 
419
    ( SELECT distinct select_option child_subquery_table_one_two . int_field_name AS { "C_SQ".$child_subquery_idx."_field1" } , 
 
420
      child_subquery_table_one_two . int_field_name AS { "C_SQ".$child_subquery_idx."_field2" }
 
421
      child_subquery_body 
 
422
      double_child_subquery_group_by
 
423
      child_subquery_having ) |
 
424
    ( SELECT distinct select_option child_subquery_table_one_two . int_field_name AS { "C_SQ".$child_subquery_idx."_field1" } , 
 
425
      aggregate child_subquery_table_one_two . int_field_name ) AS { "C_SQ".$child_subquery_idx."_field2" }
 
426
      child_subquery_body 
 
427
      single_child_subquery_group_by
 
428
      child_subquery_having );
 
429
 
 
430
char_single_member_child_subquery:
 
431
    ( SELECT distinct select_option child_subquery_table_one_two . char_field_name AS { "C_SQ".$child_subquery_idx."_field1" }
 
432
     child_subquery_body
 
433
     single_child_subquery_group_by
 
434
     child_subquery_having) ;
 
435
 
 
436
char_single_union_child_subquery:
 
437
    (  SELECT _digit  UNION all_distinct  SELECT _digit  )  ;
 
438
 
 
439
char_double_member_child_subquery:
 
440
   ( SELECT distinct select_option child_subquery_table_one_two . char_field_name AS { "C_SQ".$child_subquery_idx."_field1" } ,
 
441
     child_subquery_table_one_two . char_field_name AS { "C_SQ".$child_subquery_idx."_field2" }
 
442
     child_subquery_body
 
443
     double_child_subquery_group_by
 
444
     child_subquery_having ) |
 
445
   ( SELECT distinct select_option child_subquery_table_one_two . char_field_name AS { "C_SQ".$child_subquery_idx."_field1" } ,
 
446
     aggregate child_subquery_table_one_two . char_field_name ) AS { "C_SQ".$child_subquery_idx."_field2" }
 
447
     child_subquery_body
 
448
     single_child_subquery_group_by
 
449
     child_subquery_having );
 
450
 
 
451
int_correlated_child_subquery:
 
452
    ( SELECT distinct select_option child_subquery_table_one_two . int_field_name AS { "C_SQ".$subquery_idx."_field1" }
 
453
      FROM child_subquery_join_list 
 
454
      correlated_child_subquery_where_clause ) ;
 
455
 
 
456
char_correlated_child_subquery:
 
457
    ( SELECT distinct select_option child_subquery_table_one_two . char_field_name AS { "C_SQ".$subquery_idx."_field1" }
 
458
      FROM child_subquery_join_list 
 
459
      correlated_child_subquery_where_clause ) ;
 
460
 
 
461
child_subquery_body:
 
462
      FROM child_subquery_join_list
 
463
      child_subquery_where_clause ;
 
464
 
 
465
child_subquery_where_clause:
 
466
    | WHERE child_subquery_where_list ;
 
467
 
 
468
correlated_child_subquery_where_clause:
 
469
    WHERE correlated_child_subquery_where_list ;
 
470
 
 
471
correlated_child_subquery_where_list:
 
472
    correlated_child_subquery_where_item | correlated_child_subquery_where_item | correlated_child_subquery_where_item |
 
473
    correlated_child_subquery_where_item and_or correlated_child_subquery_where_item |
 
474
    correlated_child_subquery_where_item and_or child_subquery_where_item ;
 
475
 
 
476
correlated_child_subquery_where_item:
 
477
    existing_child_subquery_table_item . int_field_name arithmetic_operator existing_subquery_table_item . int_field_name |
 
478
    existing_child_subquery_table_item . char_field_name arithmetic_operator existing_subquery_table_item . char_field_name ;
 
479
 
 
480
child_subquery_where_list:
 
481
    child_subquery_where_item | child_subquery_where_item | child_subquery_where_item |
 
482
    ( child_subquery_where_item and_or child_subquery_where_item ) ;
 
483
 
 
484
child_subquery_where_item:
 
485
   existing_child_subquery_table_item . int_field_name arithmetic_operator _digit |
 
486
   existing_child_subquery_table_item . char_field_name arithmetic_operator _char |
 
487
   existing_child_subquery_table_item . int_field_name arithmetic_operator existing_child_subquery_table_item . int_field_name |
 
488
   existing_child_subquery_table_item . char_field_name arithmetic_operator existing_child_subquery_table_item . char_field_name ;
 
489
# |
 
490
#   child_child_subquery ;
 
491
 
 
492
child_subquery_join_list:
 
493
    child_subquery_new_table_item  |  child_subquery_new_table_item  |
 
494
   ( child_subquery_new_table_item join_type child_subquery_new_table_item ON (child_subquery_join_condition_item ) ) |
 
495
   ( child_subquery_new_table_item join_type child_subquery_new_table_item ON (child_subquery_join_condition_item ) ) |
 
496
   ( child_subquery_new_table_item join_type ( ( child_subquery_new_table_item join_type child_subquery_new_table_item ON (child_subquery_join_condition_item ) ) ) ON (child_subquery_join_condition_item ) ) ;
 
497
 
 
498
child_subquery_join_condition_item:
 
499
    child_subquery_current_table_item . int_field_name = child_subquery_previous_table_item . int_indexed |
 
500
    child_subquery_current_table_item . int_indexed = child_subquery_previous_table_item . int_field_name |
 
501
    child_subquery_current_table_item . `col_varchar_key` = child_subquery_previous_table_item . char_field_name |
 
502
    child_subquery_current_table_item . char_field_name = child_subquery_previous_table_item . `col_varchar_key` ;
 
503
 
 
504
single_child_subquery_group_by:
 
505
    | | | | | | | | | GROUP BY { "C_SQ".$child_subquery_idx."_field1" } ;
 
506
 
 
507
 
 
508
double_child_subquery_group_by:
 
509
    | | | | | | | | | GROUP BY { "C_SQ".$child_subquery_idx."_field1" } ,  { "C_SQ".$child_subquery_idx."_field2" } ;
 
510
 
 
511
child_subquery_having:
 
512
    | | | | | | | | | | HAVING child_subquery_having_list ;
 
513
 
 
514
child_subquery_having_list:
 
515
        child_subquery_having_item |
 
516
        child_subquery_having_item |
 
517
        (child_subquery_having_list and_or child_subquery_having_item)  ;
 
518
 
 
519
child_subquery_having_item:
 
520
        existing_child_subquery_table_item . int_field_name arithmetic_operator _digit |
 
521
        existing_child_subquery_table_item . int_field_name arithmetic_operator _char ;
 
522
 
 
523
 
 
524
################################################################################
 
525
# The range_predicate_1* rules below are in place to ensure we hit the         #
 
526
# index_merge/sort_union optimization.                                         #
 
527
# NOTE: combinations of the predicate_1 and predicate_2 rules tend to hit the  #
 
528
# index_merge/intersect optimization                                           #
 
529
################################################################################
 
530
 
 
531
range_predicate1_list:
 
532
      range_predicate1_item | 
 
533
      ( range_predicate1_item OR range_predicate1_item ) ;
 
534
 
 
535
range_predicate1_item:
 
536
         alias1 . int_indexed not BETWEEN _tinyint_unsigned[invariant] AND ( _tinyint_unsigned[invariant] + _tinyint_unsigned ) |
 
537
         alias1 . `col_varchar_key` arithmetic_operator _char[invariant]  |
 
538
         alias1 . int_indexed not IN (number_list) |
 
539
         alias1 . `col_varchar_key` not IN (char_list) |
 
540
         alias1 . `pk` > _tinyint_unsigned[invariant] AND alias1 . `pk` < ( _tinyint_unsigned[invariant] + _tinyint_unsigned ) |
 
541
         alias1 . `col_int_key` > _tinyint_unsigned[invariant] AND alias1 . `col_int_key` < ( _tinyint_unsigned[invariant] + _tinyint_unsigned ) ;
 
542
 
 
543
################################################################################
 
544
# The range_predicate_2* rules below are in place to ensure we hit the         #
 
545
# index_merge/union optimization.                                              #
 
546
# NOTE: combinations of the predicate_1 and predicate_2 rules tend to hit the  #
 
547
# index_merge/intersect optimization                                           #
 
548
################################################################################
 
549
 
 
550
range_predicate2_list:
 
551
      range_predicate2_item | 
 
552
      ( range_predicate2_item and_or range_predicate2_item ) ;
 
553
 
 
554
range_predicate2_item:
 
555
        alias1 . `pk` = _tinyint_unsigned |
 
556
        alias1 . `col_int_key` = _tinyint_unsigned |
 
557
        alias1 . `col_varchar_key` = _char |
 
558
        alias1 . int_indexed = _tinyint_unsigned |
 
559
        alias1 . `col_varchar_key` LIKE CONCAT( _char , '%') |
 
560
        alias1 . int_indexed = existing_table_item . int_indexed |
 
561
        alias1 . `col_varchar_key` = existing_table_item . `col_varchar_key` ;
 
562
 
 
563
################################################################################
 
564
# The number and char_list rules are for creating WHERE conditions that test   #
 
565
# 'field' IN (list_of_items)                                                   #
 
566
################################################################################
 
567
number_list:
 
568
        _tinyint_unsigned | number_list, _tinyint_unsigned ;
 
569
 
 
570
char_list:
 
571
        _char | 'USA' | char_list , _char | char_list , 'USA' ;
 
572
 
 
573
################################################################################
 
574
# We ensure that a GROUP BY statement includes all nonaggregates.              #
 
575
# This helps to ensure the query is more useful in detecting real errors /     #
 
576
# that the query doesn't lend itself to variable result sets                   #
 
577
################################################################################
 
578
group_by_clause:
 
579
        { scalar(@nonaggregates) > 0 ? " GROUP BY ".join (', ' , @nonaggregates ) : "" }  ;
 
580
 
 
581
optional_group_by:
 
582
        | | group_by_clause ;
 
583
 
 
584
having_clause:
 
585
        | HAVING having_list;
 
586
 
 
587
having_list:
 
588
        having_item |
 
589
        having_item |
 
590
        (having_list and_or having_item)  ;
 
591
 
 
592
having_item:
 
593
        existing_select_item arithmetic_operator value |
 
594
        existing_select_item arithmetic_operator value |
 
595
        existing_select_item arithmetic_operator value |
 
596
        existing_select_item arithmetic_operator value |
 
597
        existing_select_item arithmetic_operator value |
 
598
        existing_select_item arithmetic_operator value |
 
599
        { $subquery_idx += 1 ; $subquery_tables=0 ; ""} general_subquery;
 
600
 
 
601
################################################################################
 
602
# We use the total_order_by rule when using the LIMIT operator to ensure that  #
 
603
# we have a consistent result set - server1 and server2 should not differ      #
 
604
################################################################################
 
605
 
 
606
order_by_clause:
 
607
        |
 
608
        ORDER BY alias1 . _field_indexed desc , total_order_by  limit |
 
609
        ORDER BY order_by_list |
 
610
        ORDER BY  order_by_list, total_order_by limit ;
 
611
 
 
612
total_order_by:
 
613
        { join(', ', map { "field".$_ } (1..$fields) ) };
 
614
 
 
615
order_by_list:
 
616
        order_by_item  |
 
617
        order_by_item  , order_by_list ;
 
618
 
 
619
order_by_item:
 
620
        alias1 . _field_indexed , existing_table_item .`pk` desc  |
 
621
        alias1 . _field_indexed desc |
 
622
        existing_select_item desc |
 
623
        CONCAT( existing_table_item . char_field_name, existing_table_item . char_field_name );
 
624
desc:
 
625
        ASC | | DESC ; 
 
626
 
 
627
 
 
628
limit:
 
629
        | | LIMIT limit_size | LIMIT limit_size OFFSET _digit;
 
630
 
 
631
new_select_item:
 
632
        nonaggregate_select_item |
 
633
        nonaggregate_select_item |
 
634
        aggregate_select_item |
 
635
        combo_select_item |
 
636
        nonaggregate_select_item |
 
637
        nonaggregate_select_item |
 
638
        aggregate_select_item |
 
639
        select_subquery;
 
640
 
 
641
################################################################################
 
642
# We have the perl code here to help us write more sensible queries            #
 
643
# It allows us to use field1...fieldn in the WHERE, ORDER BY, and GROUP BY     #
 
644
# clauses so that the queries will produce more stable and interesting results #
 
645
################################################################################
 
646
 
 
647
nonaggregate_select_item:
 
648
        table_one_two . _field_indexed AS { my $f = "field".++$fields ; push @nonaggregates , $f ; $f } |
 
649
        table_one_two . _field_indexed AS { my $f = "field".++$fields ; push @nonaggregates , $f ; $f } |
 
650
        table_one_two . _field AS { my $f = "field".++$fields ; push @nonaggregates , $f ; $f } ;
 
651
 
 
652
aggregate_select_item:
 
653
        aggregate table_one_two . _field ) AS { "field".++$fields };
 
654
 
 
655
select_subquery:
 
656
         { $subquery_idx += 1 ; $subquery_tables=0 ; ""} select_subquery_body;
 
657
 
 
658
select_subquery_body:
 
659
         int_single_value_subquery AS { my $f = "field".++$fields ; push @nonaggregates , $f ; $f } |
 
660
         char_single_value_subquery AS { my $f = "field".++$fields ; push @nonaggregates , $f ; $f } |
 
661
         int_scalar_correlated_subquery AS  { my $f = "field".++$fields ; push @nonaggregates , $f ; $f } ;
 
662
 
 
663
select_subquery_body_disabled:
 
664
         (  SELECT _digit  UNION all_distinct  ( SELECT _digit ) LIMIT 1 )  AS  { my $f = "field".++$fields ; push @nonaggregates , $f ; $f } |
 
665
         (  SELECT _char  UNION all_distinct ( SELECT _char ) LIMIT 1 )  AS  { my $f = "field".++$fields ; push @nonaggregates , $f ; $f } ;
 
666
 
 
667
################################################################################
 
668
# The combo_select_items are for 'spice' 
 
669
################################################################################
 
670
 
 
671
combo_select_item:
 
672
    ( ( table_one_two . int_field_name ) math_operator ( table_one_two . int_field_name ) ) AS { my $f = "field".++$fields ; push @nonaggregates , $f ; $f } |
 
673
    CONCAT( table_one_two . char_field_name , table_one_two . char_field_name ) AS { my $f = "field".++$fields ; push @nonaggregates , $f ; $f } ;
 
674
 
 
675
table_one_two:
 
676
        alias1 | alias1 | alias2 ;
 
677
 
 
678
subquery_table_one_two:
 
679
        { "SQ".$subquery_idx."_alias1" ;  } | { "SQ".$subquery_idx."_alias1" ;  } |
 
680
        { "SQ".$subquery_idx."_alias1" ;  } | { "SQ".$subquery_idx."_alias2" ;  } ;      
 
681
 
 
682
child_subquery_table_one_two:
 
683
        { "C_SQ".$child_subquery_idx."_alias1" ;  } | { "C_SQ".$child_subquery_idx."_alias1" ;  } |
 
684
        { "C_SQ".$child_subquery_idx."_alias1" ;  } | { "C_SQ".$child_subquery_idx."_alias2" ;  } ;
 
685
 
 
686
aggregate:
 
687
        COUNT( distinct | SUM( distinct | MIN( distinct | MAX( distinct ;
 
688
 
 
689
################################################################################
 
690
# The following rules are for writing more sensible queries - that we don't    #
 
691
# reference tables / fields that aren't present in the query and that we keep  #
 
692
# track of what we have added.  You shouldn't need to touch these ever         #
 
693
################################################################################
 
694
new_table_item:
 
695
        _table AS { "alias".++$tables } | _table AS { "alias".++$tables } | _table AS { "alias".++$tables } |
 
696
        ( from_subquery ) AS { "alias".++$tables } ;
 
697
 
 
698
from_subquery:
 
699
       { $subquery_idx += 1 ; $subquery_tables=0 ; ""}  SELECT distinct select_option subquery_table_one_two . * subquery_body  ;
 
700
 
 
701
subquery_new_table_item:
 
702
        _table AS { "SQ".$subquery_idx."_alias".++$subquery_tables } ;
 
703
 
 
704
child_subquery_new_table_item:
 
705
        _table AS { "C_SQ".$child_subquery_idx."_alias".++$child_subquery_tables } ;      
 
706
 
 
707
current_table_item:
 
708
        { "alias".$tables };
 
709
 
 
710
subquery_current_table_item:
 
711
        { "SQ".$subquery_idx."_alias".$subquery_tables } ;
 
712
 
 
713
child_subquery_current_table_item:
 
714
        { "C_SQ".$child_subquery_idx."_alias".$child_subquery_tables } ;
 
715
 
 
716
previous_table_item:
 
717
        { "alias".($tables - 1) };
 
718
 
 
719
subquery_previous_table_item:
 
720
        { "SQ".$subquery_idx."_alias".($subquery_tables-1) } ;
 
721
 
 
722
child_subquery_previous_table_item:
 
723
        { "C_SQ".$child_subquery_idx."_alias".($child_subquery_tables-1) } ;
 
724
 
 
725
existing_table_item:
 
726
        { "alias".$prng->int(1,$tables) };
 
727
 
 
728
existing_subquery_table_item:
 
729
        { "SQ".$subquery_idx."_alias".$prng->int(1,$subquery_tables) } ;
 
730
 
 
731
existing_child_subquery_table_item:
 
732
        { "C_SQ".$child_subquery_idx."_alias".$prng->int(1,$child_subquery_tables) } ;
 
733
 
 
734
existing_select_item:
 
735
        { "field".$prng->int(1,$fields) };
 
736
 
 
737
################################################################################
 
738
# end of utility rules                                                         #
 
739
################################################################################
 
740
 
 
741
arithmetic_operator:
 
742
        = | > | < | != | <> | <= | >= ;
 
743
 
 
744
 
 
745
membership_operator:
 
746
    arithmetic_operator all_any |
 
747
    not IN ;
 
748
 
 
749
all_any:
 
750
    ALL | ANY | SOME ;
 
751
 
 
752
################################################################################
 
753
# Used for creating combo_items - ie (field1 + field2) AS fieldX               #
 
754
# We ignore division to prevent division by zero errors                        #
 
755
################################################################################
 
756
math_operator:
 
757
    + | - | * ;
 
758
 
 
759
################################################################################
 
760
# We stack AND to provide more interesting options for the optimizer           #
 
761
# Alter these percentages at your own risk / look for coverage regressions     #
 
762
# with --debug if you play with these.  Those optimizations that require an    #
 
763
# OR-only list in the WHERE clause are specifically stacked in another rule    #
 
764
################################################################################
 
765
and_or:
 
766
   AND | AND | OR ;
 
767
 
 
768
all_distinct:
 
769
   | | | | |
 
770
   | | | ALL | DISTINCT ;
 
771
 
 
772
        
 
773
value:
 
774
        _digit | _digit | _digit | _digit | _tinyint_unsigned|
 
775
        _char(1) | _char(1) | _char(1) | _char(2) | _char(2) | 'USA' ;
 
776
 
 
777
_table:
 
778
     A | B | C | BB | CC | B | C | BB | CC | 
 
779
     CC | CC | CC | CC | CC |
 
780
     C | C | C | C | C | D |  view ;
 
781
 
 
782
################################################################################
 
783
# Add a possibility for 'view' to occur at the end of the previous '_table' rule
 
784
# to allow a chance to use views (when running the RQG with --views)
 
785
################################################################################
 
786
 
 
787
view:
 
788
    view_A | view_AA | view_B | view_BB | view_C | view_CC | view_C | view_CC | view_D ;
 
789
 
 
790
_field:
 
791
    int_field_name | char_field_name ;
 
792
 
 
793
_digit:
 
794
    1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | _tinyint_unsigned ;
 
795
 
 
796
int_field_name:
 
797
    `pk` | `col_int_key` | `col_int_nokey` ;
 
798
 
 
799
int_indexed:
 
800
    `pk` | `col_int_key` ;
 
801
 
 
802
 
 
803
char_field_name:
 
804
    `col_varchar_key` | `col_varchar_nokey` ;
 
805
 
 
806
################################################################################
 
807
# We define LIMIT_rows in this fashion as LIMIT values can differ depending on      #
 
808
# how large the LIMIT is - LIMIT 2 = LIMIT 9 != LIMIT 19                       #
 
809
################################################################################
 
810
 
 
811
limit_size:
 
812
    1 | 2 | 10 | 100 | 1000;