~ubuntu-branches/ubuntu/vivid/drizzle/vivid-proposed

« back to all changes in this revision

Viewing changes to tests/test_tools/randgen/conf/optimizer/optimizer_subquery_semijoin.yy

  • Committer: Package Import Robot
  • Author(s): Tobias Frost
  • Date: 2013-08-22 20:18:31 UTC
  • mto: (20.1.1 sid)
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: package-import@ubuntu.com-20130822201831-gn3ozsh7o7wmc5tk
Tags: upstream-7.2.3
ImportĀ upstreamĀ versionĀ 7.2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2008-2010 Sun Microsystems, Inc. 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 /* _thread_id */ ;
 
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 | INNER JOIN | INNER JOIN | INNER JOIN | STRAIGHT_JOIN |
 
135
        left_right outer JOIN | STRAIGHT_JOIN ;  
 
136
 
 
137
join_condition_item:
 
138
    current_table_item . int_indexed = previous_table_item . int_field_name on_subquery |
 
139
    current_table_item . int_field_name = previous_table_item . int_indexed on_subquery |
 
140
    current_table_item . `col_varchar_key` = previous_table_item . char_field_name on_subquery |
 
141
    current_table_item . char_field_name = previous_table_item . `col_varchar_key` on_subquery ;
 
142
 
 
143
on_subquery:
 
144
    |||||||||||||||||||| { $subquery_idx += 1 ; $subquery_tables=0 ; ""} and_or general_subquery ;
 
145
 
 
146
 
 
147
left_right:
 
148
        LEFT | RIGHT ;
 
149
 
 
150
outer:
 
151
        | OUTER ;
 
152
 
 
153
where_clause:
 
154
        WHERE where_subquery |
 
155
        WHERE ( where_subquery ) and_or where_list |
 
156
        WHERE ( where_subquery ) and_or where_list ;
 
157
 
 
158
 
 
159
where_list:
 
160
        generic_where_list |
 
161
        range_predicate1_list | range_predicate2_list |
 
162
        range_predicate1_list and_or generic_where_list |
 
163
        range_predicate2_list and_or generic_where_list ; 
 
164
 
 
165
 
 
166
generic_where_list:
 
167
        where_item |
 
168
        ( where_item and_or where_item ) ;
 
169
 
 
170
not:
 
171
        | | | | NOT;
 
172
 
 
173
where_item:
 
174
        where_subquery  |  
 
175
        alias1 . int_field_name arithmetic_operator existing_table_item . int_field_name  |
 
176
        existing_table_item . char_field_name arithmetic_operator _char  |
 
177
        existing_table_item . char_field_name arithmetic_operator existing_table_item . char_field_name |
 
178
        alias1 . _field IS not NULL |
 
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
 
 
184
################################################################################
 
185
# subquery rules
 
186
################################################################################
 
187
 
 
188
where_subquery:
 
189
    { $subquery_idx += 1 ; $subquery_tables=0 ; ""} subquery_type ;
 
190
 
 
191
subquery_type:
 
192
    general_subquery | special_subquery ;
 
193
 
 
194
general_subquery:
 
195
    existing_table_item . int_field_name arithmetic_operator  int_single_value_subquery  |
 
196
    existing_table_item . char_field_name arithmetic_operator char_single_value_subquery |
 
197
    existing_table_item . int_field_name membership_operator  int_single_member_subquery  |
 
198
    ( existing_table_item . int_field_name , existing_table_item . int_field_name ) not IN int_double_member_subquery |
 
199
    ( existing_table_item . int_field_name , existing_table_item . int_field_name ) not IN int_double_member_subquery |
 
200
    ( existing_table_item . int_field_name , existing_table_item . int_field_name ) not IN int_double_member_subquery |
 
201
    ( existing_table_item . int_field_name , existing_table_item . int_field_name ) not IN int_double_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
    ( existing_table_item . char_field_name , existing_table_item . char_field_name ) not IN char_double_member_subquery |
 
206
    ( existing_table_item . char_field_name , existing_table_item . char_field_name ) not IN char_double_member_subquery |
 
207
    ( existing_table_item . char_field_name , existing_table_item . char_field_name ) not IN char_double_member_subquery |
 
208
    ( _digit, _digit ) not IN int_double_member_subquery |
 
209
    ( _char, _char ) not IN char_double_member_subquery |
 
210
    ( _digit, _digit ) not IN int_double_member_subquery |
 
211
    ( _char, _char ) not IN char_double_member_subquery |
 
212
    ( _digit, _digit ) not IN int_double_member_subquery |
 
213
    ( _char, _char ) not IN char_double_member_subquery |
 
214
    ( _digit, _digit ) not IN int_double_member_subquery |
 
215
    ( _char, _char ) not IN char_double_member_subquery |
 
216
    ( _digit, _digit ) not IN int_double_member_subquery |
 
217
    ( _char, _char ) not IN char_double_member_subquery |
 
218
    existing_table_item . int_field_name membership_operator int_single_union_subquery |
 
219
    existing_table_item . char_field_name membership_operator char_single_union_subquery ;
 
220
 
 
221
general_subquery_union_test_disabled:
 
222
    existing_table_item . char_field_name arithmetic_operator all_any char_single_union_subquery_disabled |
 
223
    existing_table_item . int_field_name arithmetic_operator all_any int_single_union_subquery_disabled ;
 
224
 
 
225
special_subquery:
 
226
    not EXISTS ( int_single_member_subquery ) |
 
227
    not EXISTS ( char_single_member_subquery ) |
 
228
    not EXISTS int_correlated_subquery |
 
229
    not EXISTS char_correlated_subquery  | 
 
230
    existing_table_item . int_field_name membership_operator  int_correlated_subquery  |
 
231
    existing_table_item . char_field_name membership_operator char_correlated_subquery  |
 
232
    int_single_value_subquery IS not NULL |
 
233
    char_single_value_subquery IS not NULL ;
 
234
 
 
235
int_single_value_subquery:
 
236
    ( SELECT distinct select_option aggregate subquery_table_one_two . int_field_name ) AS { "SQ".$subquery_idx."_field1" } 
 
237
      subquery_body ) |
 
238
    ( SELECT distinct select_option aggregate subquery_table_one_two . int_field_name ) AS { "SQ".$subquery_idx."_field1" } 
 
239
      subquery_body ) |
 
240
    ( SELECT _digit FROM DUAL ) ;
 
241
 
 
242
char_single_value_subquery:
 
243
    ( SELECT distinct select_option aggregate subquery_table_one_two . char_field_name ) AS { "SQ".$subquery_idx."_field1" } 
 
244
      subquery_body ) |
 
245
    ( SELECT distinct select_option aggregate subquery_table_one_two . char_field_name ) AS { "SQ".$subquery_idx."_field1" } 
 
246
      subquery_body ) |
 
247
    ( SELECT _char FROM DUAL ) ;
 
248
   
 
249
int_single_member_subquery:
 
250
    ( SELECT distinct select_option subquery_table_one_two . int_field_name AS { "SQ".$subquery_idx."_field1" }
 
251
      subquery_body 
 
252
      single_subquery_group_by
 
253
      subquery_having ) |
 
254
    ( SELECT _digit FROM DUAL ) ;
 
255
 
 
256
int_single_union_subquery:
 
257
    (  SELECT _digit  UNION all_distinct  SELECT _digit  )  ;
 
258
 
 
259
int_single_union_subquery_disabled:
 
260
    int_single_member_subquery   UNION all_distinct  int_single_member_subquery ;
 
261
 
 
262
int_double_member_subquery:
 
263
    ( SELECT distinct select_option subquery_table_one_two . int_field_name AS { "SQ".$subquery_idx."_field1" } , 
 
264
      subquery_table_one_two . int_field_name AS { "SQ".$subquery_idx."_field2" }
 
265
      subquery_body 
 
266
      double_subquery_group_by
 
267
      subquery_having ) |
 
268
    ( SELECT distinct select_option subquery_table_one_two . int_field_name AS { "SQ".$subquery_idx."_field1" } , 
 
269
      subquery_table_one_two . int_field_name AS { "SQ".$subquery_idx."_field2" }
 
270
      subquery_body 
 
271
      double_subquery_group_by
 
272
      subquery_having ) |
 
273
    ( SELECT distinct select_option subquery_table_one_two . int_field_name AS { "SQ".$subquery_idx."_field1" } , 
 
274
      subquery_table_one_two . int_field_name AS { "SQ".$subquery_idx."_field2" }
 
275
      subquery_body 
 
276
      double_subquery_group_by
 
277
      subquery_having ) |
 
278
    ( SELECT distinct select_option subquery_table_one_two . int_field_name AS { "SQ".$subquery_idx."_field1" } , 
 
279
      aggregate subquery_table_one_two . int_field_name ) AS { "SQ".$subquery_idx."_field2" }
 
280
      subquery_body 
 
281
      single_subquery_group_by
 
282
      subquery_having ) |
 
283
    (  SELECT _digit , _digit  UNION all_distinct  SELECT _digit, _digit  ) ;
 
284
 
 
285
char_single_member_subquery:
 
286
    ( SELECT distinct select_option subquery_table_one_two . char_field_name AS { "SQ".$subquery_idx."_field1" }
 
287
     subquery_body
 
288
     single_subquery_group_by
 
289
     subquery_having) ;
 
290
 
 
291
char_single_union_subquery:
 
292
    (  SELECT _char  UNION all_distinct  SELECT _char  )  ;
 
293
 
 
294
char_single_union_subquery_disabled:
 
295
    char_single_member_subquery   UNION all_distinct char_single_member_subquery  ;
 
296
 
 
297
char_double_member_subquery:
 
298
   ( SELECT distinct select_option subquery_table_one_two . char_field_name AS { "SQ".$subquery_idx."_field1" } ,
 
299
     subquery_table_one_two . char_field_name AS { "SQ".$subquery_idx."_field2" }
 
300
     subquery_body
 
301
     double_subquery_group_by
 
302
     subquery_having ) |
 
303
   ( SELECT distinct select_option subquery_table_one_two . char_field_name AS { "SQ".$subquery_idx."_field1" } ,
 
304
     subquery_table_one_two . char_field_name AS { "SQ".$subquery_idx."_field2" }
 
305
     subquery_body
 
306
     double_subquery_group_by
 
307
     subquery_having ) |
 
308
   ( SELECT distinct select_option subquery_table_one_two . char_field_name AS { "SQ".$subquery_idx."_field1" } ,
 
309
     subquery_table_one_two . char_field_name AS { "SQ".$subquery_idx."_field2" }
 
310
     subquery_body
 
311
     double_subquery_group_by
 
312
     subquery_having ) |
 
313
   ( SELECT distinct select_option subquery_table_one_two . char_field_name AS { "SQ".$subquery_idx."_field1" } ,
 
314
     subquery_table_one_two . char_field_name AS { "SQ".$subquery_idx."_field2" }
 
315
     subquery_body
 
316
     double_subquery_group_by
 
317
     subquery_having ) |
 
318
   ( SELECT distinct select_option subquery_table_one_two . char_field_name AS { "SQ".$subquery_idx."_field1" } ,
 
319
     aggregate subquery_table_one_two . char_field_name ) AS { "SQ".$subquery_idx."_field2" }
 
320
     subquery_body
 
321
     single_subquery_group_by
 
322
     subquery_having ) |
 
323
   (  SELECT _char , _char  UNION all_distinct  SELECT _char , _char  ) ;
 
324
 
 
325
int_correlated_subquery:
 
326
    ( SELECT distinct select_option subquery_table_one_two . int_field_name AS { "SQ".$subquery_idx."_field1" }
 
327
      FROM subquery_join_list 
 
328
      correlated_subquery_where_clause ) ;
 
329
 
 
330
char_correlated_subquery:
 
331
    ( SELECT distinct select_option subquery_table_one_two . char_field_name AS { "SQ".$subquery_idx."_field1" }
 
332
      FROM subquery_join_list 
 
333
      correlated_subquery_where_clause ) ;
 
334
 
 
335
int_scalar_correlated_subquery:
 
336
     ( SELECT distinct select_option aggregate subquery_table_one_two . int_field_name ) AS { "SQ".$subquery_idx."_field1" }
 
337
      FROM subquery_join_list 
 
338
      correlated_subquery_where_clause ) ;
 
339
 
 
340
subquery_body:
 
341
      FROM subquery_join_list
 
342
      subquery_where_clause ;
 
343
 
 
344
subquery_where_clause:
 
345
    | | WHERE subquery_where_list ;
 
346
 
 
347
correlated_subquery_where_clause:
 
348
    WHERE correlated_subquery_where_list ;
 
349
 
 
350
correlated_subquery_where_list:
 
351
    correlated_subquery_where_item |
 
352
    correlated_subquery_where_item and_or correlated_subquery_where_item |
 
353
    correlated_subquery_where_item and_or subquery_where_item ;
 
354
 
 
355
correlated_subquery_where_item:
 
356
    existing_subquery_table_item . int_field_name arithmetic_operator existing_table_item . int_field_name |
 
357
    existing_subquery_table_item . char_field_name arithmetic_operator existing_table_item . char_field_name ;
 
358
 
 
359
subquery_where_list:
 
360
    subquery_where_item | subquery_where_item | subquery_where_item |
 
361
    ( subquery_where_item and_or subquery_where_item ) ;
 
362
 
 
363
subquery_where_item:
 
364
   existing_subquery_table_item . int_field_name arithmetic_operator _digit |
 
365
   existing_subquery_table_item . char_field_name arithmetic_operator _char |
 
366
   existing_subquery_table_item . int_field_name arithmetic_operator existing_subquery_table_item . int_field_name |
 
367
   existing_subquery_table_item . char_field_name arithmetic_operator existing_subquery_table_item . char_field_name |
 
368
   child_subquery ;
 
369
 
 
370
subquery_join_list:
 
371
   subquery_new_table_item  |  subquery_new_table_item  |
 
372
   ( subquery_new_table_item , subquery_new_table_item ) |
 
373
   ( subquery_new_table_item join_type subquery_new_table_item ON (subquery_join_condition_item ) ) |
 
374
   ( subquery_new_table_item join_type subquery_new_table_item ON (subquery_join_condition_item ) ) |
 
375
   ( 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 ) ) ;
 
376
 
 
377
subquery_join_condition_item:
 
378
    subquery_current_table_item . int_field_name = subquery_previous_table_item . int_indexed subquery_on_subquery |
 
379
    subquery_current_table_item . int_indexed = subquery_previous_table_item . int_field_name subquery_on_subquery |
 
380
    subquery_current_table_item . `col_varchar_key` = subquery_previous_table_item . char_field_name subquery_on_subquery |
 
381
    subquery_current_table_item . char_field_name = subquery_previous_table_item . `col_varchar_key` subquery_on_subquery ;
 
382
 
 
383
subquery_on_subquery:
 
384
    |||||||||||||||||||| { $child_subquery_idx += 1 ; $child_subquery_tables=0 ; ""} and_or general_child_subquery ;
 
385
 
 
386
single_subquery_group_by:
 
387
    | | | | | | | | | GROUP BY { "SQ".$subquery_idx."_field1" } ;
 
388
 
 
389
 
 
390
double_subquery_group_by:
 
391
    | | | | | | | | | GROUP BY { "SQ".$subquery_idx."_field1" } ,  { "SQ".$subquery_idx."_field2" } ;
 
392
 
 
393
subquery_having:
 
394
    | | | | | | | | | | HAVING subquery_having_list ;
 
395
 
 
396
subquery_having_list:
 
397
        subquery_having_item |
 
398
        subquery_having_item |
 
399
        (subquery_having_list and_or subquery_having_item)  ;
 
400
 
 
401
subquery_having_item:
 
402
        existing_subquery_table_item . int_field_name arithmetic_operator _digit |
 
403
        existing_subquery_table_item . int_field_name arithmetic_operator _char ;
 
404
 
 
405
 
 
406
################################################################################
 
407
# Child subquery rules
 
408
################################################################################
 
409
 
 
410
child_subquery:
 
411
    { $child_subquery_idx += 1 ; $child_subquery_tables=0 ; ""} child_subquery_type ;
 
412
 
 
413
child_subquery_type:
 
414
    general_child_subquery | special_child_subquery ;
 
415
 
 
416
general_child_subquery:
 
417
    existing_subquery_table_item . int_field_name arithmetic_operator  int_single_value_child_subquery  |
 
418
    existing_subquery_table_item . char_field_name arithmetic_operator char_single_value_child_subquery |
 
419
    existing_subquery_table_item . int_field_name membership_operator  int_single_member_child_subquery  |
 
420
    ( existing_subquery_table_item . int_field_name , existing_subquery_table_item . int_field_name ) not IN int_double_member_child_subquery |
 
421
    existing_subquery_table_item . char_field_name membership_operator  char_single_member_child_subquery  |
 
422
    ( existing_subquery_table_item . char_field_name , existing_subquery_table_item . char_field_name ) not IN char_double_member_child_subquery |
 
423
    ( _digit, _digit ) not IN int_double_member_child_subquery |
 
424
    ( _char, _char ) not IN char_double_member_child_subquery |
 
425
    existing_subquery_table_item . int_field_name membership_operator int_single_union_child_subquery |
 
426
    existing_subquery_table_item . char_field_name membership_operator char_single_union_child_subquery ;
 
427
 
 
428
special_child_subquery:
 
429
    not EXISTS ( int_single_member_child_subquery ) |
 
430
    not EXISTS ( char_single_member_child_subquery ) |
 
431
    not EXISTS int_correlated_child_subquery |
 
432
    not EXISTS char_correlated_child_subquery |
 
433
    existing_subquery_table_item . int_field_name membership_operator  int_correlated_child_subquery  |
 
434
    existing_subquery_table_item . char_field_name membership_operator char_correlated_child_subquery ;
 
435
 
 
436
 
 
437
int_single_value_child_subquery:
 
438
    ( SELECT distinct select_option aggregate child_subquery_table_one_two . int_field_name ) AS { "C_SQ".$child_subquery_idx."_field1" } 
 
439
      child_subquery_body ) ;
 
440
 
 
441
char_single_value_child_subquery:
 
442
    ( SELECT distinct select_option aggregate child_subquery_table_one_two . char_field_name ) AS { "C_SQ".$child_subquery_idx."_field1" } 
 
443
      child_subquery_body ) ;
 
444
   
 
445
int_single_member_child_subquery:
 
446
    ( SELECT distinct select_option child_subquery_table_one_two . int_field_name AS { "C_SQ".$child_subquery_idx."_field1" }
 
447
      child_subquery_body 
 
448
      single_child_subquery_group_by
 
449
      child_subquery_having ) ;
 
450
 
 
451
int_single_union_child_subquery:
 
452
    (  SELECT _digit  UNION all_distinct  SELECT _digit  )  ;
 
453
 
 
454
int_double_member_child_subquery:
 
455
    ( SELECT distinct select_option child_subquery_table_one_two . int_field_name AS { "C_SQ".$child_subquery_idx."_field1" } , 
 
456
      child_subquery_table_one_two . int_field_name AS { "C_SQ".$child_subquery_idx."_field2" }
 
457
      child_subquery_body 
 
458
      double_child_subquery_group_by
 
459
      child_subquery_having ) |
 
460
    ( SELECT distinct select_option child_subquery_table_one_two . int_field_name AS { "C_SQ".$child_subquery_idx."_field1" } , 
 
461
      aggregate child_subquery_table_one_two . int_field_name ) AS { "C_SQ".$child_subquery_idx."_field2" }
 
462
      child_subquery_body 
 
463
      single_child_subquery_group_by
 
464
      child_subquery_having );
 
465
 
 
466
char_single_member_child_subquery:
 
467
    ( SELECT distinct select_option child_subquery_table_one_two . char_field_name AS { "C_SQ".$child_subquery_idx."_field1" }
 
468
     child_subquery_body
 
469
     single_child_subquery_group_by
 
470
     child_subquery_having) ;
 
471
 
 
472
char_single_union_child_subquery:
 
473
    (  SELECT _digit  UNION all_distinct  SELECT _digit  )  ;
 
474
 
 
475
char_double_member_child_subquery:
 
476
   ( SELECT distinct select_option child_subquery_table_one_two . char_field_name AS { "C_SQ".$child_subquery_idx."_field1" } ,
 
477
     child_subquery_table_one_two . char_field_name AS { "C_SQ".$child_subquery_idx."_field2" }
 
478
     child_subquery_body
 
479
     double_child_subquery_group_by
 
480
     child_subquery_having ) |
 
481
   ( SELECT distinct select_option child_subquery_table_one_two . char_field_name AS { "C_SQ".$child_subquery_idx."_field1" } ,
 
482
     aggregate child_subquery_table_one_two . char_field_name ) AS { "C_SQ".$child_subquery_idx."_field2" }
 
483
     child_subquery_body
 
484
     single_child_subquery_group_by
 
485
     child_subquery_having );
 
486
 
 
487
int_correlated_child_subquery:
 
488
    ( SELECT distinct select_option child_subquery_table_one_two . int_field_name AS { "C_SQ".$subquery_idx."_field1" }
 
489
      FROM child_subquery_join_list 
 
490
      correlated_child_subquery_where_clause ) ;
 
491
 
 
492
char_correlated_child_subquery:
 
493
    ( SELECT distinct select_option child_subquery_table_one_two . char_field_name AS { "C_SQ".$subquery_idx."_field1" }
 
494
      FROM child_subquery_join_list 
 
495
      correlated_child_subquery_where_clause ) ;
 
496
 
 
497
child_subquery_body:
 
498
      FROM child_subquery_join_list
 
499
      child_subquery_where_clause ;
 
500
 
 
501
child_subquery_where_clause:
 
502
    | WHERE child_subquery_where_list ;
 
503
 
 
504
correlated_child_subquery_where_clause:
 
505
    WHERE correlated_child_subquery_where_list ;
 
506
 
 
507
correlated_child_subquery_where_list:
 
508
    correlated_child_subquery_where_item | correlated_child_subquery_where_item | correlated_child_subquery_where_item |
 
509
    correlated_child_subquery_where_item and_or correlated_child_subquery_where_item |
 
510
    correlated_child_subquery_where_item and_or child_subquery_where_item ;
 
511
 
 
512
correlated_child_subquery_where_item:
 
513
    existing_child_subquery_table_item . int_field_name arithmetic_operator existing_subquery_table_item . int_field_name |
 
514
    existing_child_subquery_table_item . char_field_name arithmetic_operator existing_subquery_table_item . char_field_name ;
 
515
 
 
516
child_subquery_where_list:
 
517
    child_subquery_where_item | child_subquery_where_item | child_subquery_where_item |
 
518
    ( child_subquery_where_item and_or child_subquery_where_item ) ;
 
519
 
 
520
child_subquery_where_item:
 
521
   existing_child_subquery_table_item . int_field_name arithmetic_operator _digit |
 
522
   existing_child_subquery_table_item . char_field_name arithmetic_operator _char |
 
523
   existing_child_subquery_table_item . int_field_name arithmetic_operator existing_child_subquery_table_item . int_field_name |
 
524
   existing_child_subquery_table_item . char_field_name arithmetic_operator existing_child_subquery_table_item . char_field_name ;
 
525
# |
 
526
#   child_child_subquery ;
 
527
 
 
528
child_subquery_join_list:
 
529
    child_subquery_new_table_item  |  child_subquery_new_table_item  |
 
530
   ( child_subquery_new_table_item join_type child_subquery_new_table_item ON (child_subquery_join_condition_item ) ) |
 
531
   ( child_subquery_new_table_item join_type child_subquery_new_table_item ON (child_subquery_join_condition_item ) ) |
 
532
   ( 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 ) ) ;
 
533
 
 
534
child_subquery_join_condition_item:
 
535
    child_subquery_current_table_item . int_field_name = child_subquery_previous_table_item . int_indexed |
 
536
    child_subquery_current_table_item . int_indexed = child_subquery_previous_table_item . int_field_name |
 
537
    child_subquery_current_table_item . `col_varchar_key` = child_subquery_previous_table_item . char_field_name |
 
538
    child_subquery_current_table_item . char_field_name = child_subquery_previous_table_item . `col_varchar_key` ;
 
539
 
 
540
single_child_subquery_group_by:
 
541
    | | | | | | | | | GROUP BY { "C_SQ".$child_subquery_idx."_field1" } ;
 
542
 
 
543
 
 
544
double_child_subquery_group_by:
 
545
    | | | | | | | | | GROUP BY { "C_SQ".$child_subquery_idx."_field1" } ,  { "C_SQ".$child_subquery_idx."_field2" } ;
 
546
 
 
547
child_subquery_having:
 
548
    | | | | | | | | | | HAVING child_subquery_having_list ;
 
549
 
 
550
child_subquery_having_list:
 
551
        child_subquery_having_item |
 
552
        child_subquery_having_item |
 
553
        (child_subquery_having_list and_or child_subquery_having_item)  ;
 
554
 
 
555
child_subquery_having_item:
 
556
        existing_child_subquery_table_item . int_field_name arithmetic_operator _digit |
 
557
        existing_child_subquery_table_item . int_field_name arithmetic_operator _char ;
 
558
 
 
559
 
 
560
################################################################################
 
561
# The range_predicate_1* rules below are in place to ensure we hit the         #
 
562
# index_merge/sort_union optimization.                                         #
 
563
# NOTE: combinations of the predicate_1 and predicate_2 rules tend to hit the  #
 
564
# index_merge/intersect optimization                                           #
 
565
################################################################################
 
566
 
 
567
range_predicate1_list:
 
568
      range_predicate1_item | 
 
569
      ( range_predicate1_item OR range_predicate1_item ) ;
 
570
 
 
571
range_predicate1_item:
 
572
         alias1 . int_indexed not BETWEEN _tinyint_unsigned[invariant] AND ( _tinyint_unsigned[invariant] + _tinyint_unsigned ) |
 
573
         alias1 . `col_varchar_key` arithmetic_operator _char[invariant]  |
 
574
         alias1 . int_indexed not IN (number_list) |
 
575
         alias1 . `col_varchar_key` not IN (char_list) |
 
576
         alias1 . `pk` > _tinyint_unsigned[invariant] AND alias1 . `pk` < ( _tinyint_unsigned[invariant] + _tinyint_unsigned ) |
 
577
         alias1 . `col_int_key` > _tinyint_unsigned[invariant] AND alias1 . `col_int_key` < ( _tinyint_unsigned[invariant] + _tinyint_unsigned ) ;
 
578
 
 
579
################################################################################
 
580
# The range_predicate_2* rules below are in place to ensure we hit the         #
 
581
# index_merge/union optimization.                                              #
 
582
# NOTE: combinations of the predicate_1 and predicate_2 rules tend to hit the  #
 
583
# index_merge/intersect optimization                                           #
 
584
################################################################################
 
585
 
 
586
range_predicate2_list:
 
587
      range_predicate2_item | 
 
588
      ( range_predicate2_item and_or range_predicate2_item ) ;
 
589
 
 
590
range_predicate2_item:
 
591
        alias1 . `pk` = _tinyint_unsigned |
 
592
        alias1 . `col_int_key` = _tinyint_unsigned |
 
593
        alias1 . `col_varchar_key` = _char |
 
594
        alias1 . int_indexed = _tinyint_unsigned |
 
595
        alias1 . `col_varchar_key` LIKE CONCAT( _char , '%') |
 
596
        alias1 . int_indexed = existing_table_item . int_indexed |
 
597
        alias1 . `col_varchar_key` = existing_table_item . `col_varchar_key` ;
 
598
 
 
599
################################################################################
 
600
# The number and char_list rules are for creating WHERE conditions that test   #
 
601
# 'field' IN (list_of_items)                                                   #
 
602
################################################################################
 
603
number_list:
 
604
        _tinyint_unsigned | number_list, _tinyint_unsigned ;
 
605
 
 
606
char_list:
 
607
        _char | 'USA' | char_list , _char | char_list , 'USA' ;
 
608
 
 
609
################################################################################
 
610
# We ensure that a GROUP BY statement includes all nonaggregates.              #
 
611
# This helps to ensure the query is more useful in detecting real errors /     #
 
612
# that the query doesn't lend itself to variable result sets                   #
 
613
################################################################################
 
614
group_by_clause:
 
615
        { scalar(@nonaggregates) > 0 ? " GROUP BY ".join (', ' , @nonaggregates ) : "" }  ;
 
616
 
 
617
optional_group_by:
 
618
        | | group_by_clause ;
 
619
 
 
620
having_clause:
 
621
        | HAVING having_list;
 
622
 
 
623
having_list:
 
624
        having_item |
 
625
        having_item |
 
626
        (having_list and_or having_item)  ;
 
627
 
 
628
having_item:
 
629
        existing_select_item arithmetic_operator value |
 
630
        existing_select_item arithmetic_operator value |
 
631
        existing_select_item arithmetic_operator value |
 
632
        existing_select_item arithmetic_operator value |
 
633
        existing_select_item arithmetic_operator value |
 
634
        existing_select_item arithmetic_operator value |
 
635
        { $subquery_idx += 1 ; $subquery_tables=0 ; ""} general_subquery;
 
636
 
 
637
################################################################################
 
638
# We use the total_order_by rule when using the LIMIT operator to ensure that  #
 
639
# we have a consistent result set - server1 and server2 should not differ      #
 
640
################################################################################
 
641
 
 
642
order_by_clause:
 
643
        |
 
644
        ORDER BY alias1 . _field_indexed desc , total_order_by  limit |
 
645
        ORDER BY order_by_list |
 
646
        ORDER BY  order_by_list, total_order_by limit ;
 
647
 
 
648
total_order_by:
 
649
        { join(', ', map { "field".$_ } (1..$fields) ) };
 
650
 
 
651
order_by_list:
 
652
        order_by_item  |
 
653
        order_by_item  , order_by_list ;
 
654
 
 
655
order_by_item:
 
656
        alias1 . _field_indexed , existing_table_item .`pk` desc  |
 
657
        alias1 . _field_indexed desc |
 
658
        existing_select_item desc |
 
659
        CONCAT ( existing_table_item . char_field_name, existing_table_item . char_field_name );
 
660
desc:
 
661
        ASC | | DESC ; 
 
662
 
 
663
 
 
664
limit:
 
665
        | | LIMIT limit_size | LIMIT limit_size OFFSET _digit;
 
666
 
 
667
new_select_item:
 
668
        nonaggregate_select_item |
 
669
        nonaggregate_select_item |
 
670
        aggregate_select_item |
 
671
        combo_select_item |
 
672
        nonaggregate_select_item |
 
673
        nonaggregate_select_item |
 
674
        aggregate_select_item |
 
675
        select_subquery;
 
676
 
 
677
################################################################################
 
678
# We have the perl code here to help us write more sensible queries            #
 
679
# It allows us to use field1...fieldn in the WHERE, ORDER BY, and GROUP BY     #
 
680
# clauses so that the queries will produce more stable and interesting results #
 
681
################################################################################
 
682
 
 
683
nonaggregate_select_item:
 
684
        table_one_two . _field_indexed AS { my $f = "field".++$fields ; push @nonaggregates , $f ; $f } |
 
685
        table_one_two . _field_indexed AS { my $f = "field".++$fields ; push @nonaggregates , $f ; $f } |
 
686
        table_one_two . _field AS { my $f = "field".++$fields ; push @nonaggregates , $f ; $f } ;
 
687
 
 
688
aggregate_select_item:
 
689
        aggregate table_one_two . _field ) AS { "field".++$fields };
 
690
 
 
691
select_subquery:
 
692
         { $subquery_idx += 1 ; $subquery_tables=0 ; ""} select_subquery_body;
 
693
 
 
694
select_subquery_body:
 
695
         int_single_value_subquery AS { my $f = "field".++$fields ; push @nonaggregates , $f ; $f } |
 
696
         char_single_value_subquery AS { my $f = "field".++$fields ; push @nonaggregates , $f ; $f } |
 
697
         int_scalar_correlated_subquery AS  { my $f = "field".++$fields ; push @nonaggregates , $f ; $f } ;
 
698
 
 
699
select_subquery_body_disabled:
 
700
         (  SELECT _digit  UNION all_distinct  ( SELECT _digit ) LIMIT 1 )  AS  { my $f = "field".++$fields ; push @nonaggregates , $f ; $f } |
 
701
         (  SELECT _char  UNION all_distinct ( SELECT _char ) LIMIT 1 )  AS  { my $f = "field".++$fields ; push @nonaggregates , $f ; $f } ;
 
702
 
 
703
################################################################################
 
704
# The combo_select_items are for 'spice' 
 
705
################################################################################
 
706
 
 
707
combo_select_item:
 
708
    ( ( table_one_two . int_field_name ) math_operator ( table_one_two . int_field_name ) ) AS { my $f = "field".++$fields ; push @nonaggregates , $f ; $f } |
 
709
    CONCAT ( table_one_two . char_field_name , table_one_two . char_field_name ) AS { my $f = "field".++$fields ; push @nonaggregates , $f ; $f } ;
 
710
 
 
711
table_one_two:
 
712
        alias1 | alias1 | alias2 ;
 
713
 
 
714
subquery_table_one_two:
 
715
        { "SQ".$subquery_idx."_alias1" ;  } | { "SQ".$subquery_idx."_alias1" ;  } |
 
716
        { "SQ".$subquery_idx."_alias1" ;  } | { "SQ".$subquery_idx."_alias2" ;  } ;      
 
717
 
 
718
child_subquery_table_one_two:
 
719
        { "C_SQ".$child_subquery_idx."_alias1" ;  } | { "C_SQ".$child_subquery_idx."_alias1" ;  } |
 
720
        { "C_SQ".$child_subquery_idx."_alias1" ;  } | { "C_SQ".$child_subquery_idx."_alias2" ;  } ;
 
721
 
 
722
aggregate:
 
723
        COUNT( distinct | SUM( distinct | MIN( distinct | MAX( distinct ;
 
724
 
 
725
################################################################################
 
726
# The following rules are for writing more sensible queries - that we don't    #
 
727
# reference tables / fields that aren't present in the query and that we keep  #
 
728
# track of what we have added.  You shouldn't need to touch these ever         #
 
729
################################################################################
 
730
new_table_item:
 
731
        _table AS { "alias".++$tables } | _table AS { "alias".++$tables } | _table AS { "alias".++$tables } ;
 
732
#|
 
733
 #       ( from_subquery ) AS { "alias".++$tables } ;
 
734
 
 
735
from_subquery:
 
736
       { $subquery_idx += 1 ; $subquery_tables=0 ; ""}  SELECT distinct select_option subquery_table_one_two . * subquery_body  ;
 
737
 
 
738
subquery_new_table_item:
 
739
        _table AS { "SQ".$subquery_idx."_alias".++$subquery_tables } ;
 
740
 
 
741
child_subquery_new_table_item:
 
742
        _table AS { "C_SQ".$child_subquery_idx."_alias".++$child_subquery_tables } ;      
 
743
 
 
744
current_table_item:
 
745
        { "alias".$tables };
 
746
 
 
747
subquery_current_table_item:
 
748
        { "SQ".$subquery_idx."_alias".$subquery_tables } ;
 
749
 
 
750
child_subquery_current_table_item:
 
751
        { "C_SQ".$child_subquery_idx."_alias".$child_subquery_tables } ;
 
752
 
 
753
previous_table_item:
 
754
        { "alias".($tables - 1) };
 
755
 
 
756
subquery_previous_table_item:
 
757
        { "SQ".$subquery_idx."_alias".($subquery_tables-1) } ;
 
758
 
 
759
child_subquery_previous_table_item:
 
760
        { "C_SQ".$child_subquery_idx."_alias".($child_subquery_tables-1) } ;
 
761
 
 
762
existing_table_item:
 
763
        { "alias".$prng->int(1,$tables) };
 
764
 
 
765
existing_subquery_table_item:
 
766
        { "SQ".$subquery_idx."_alias".$prng->int(1,$subquery_tables) } ;
 
767
 
 
768
existing_child_subquery_table_item:
 
769
        { "C_SQ".$child_subquery_idx."_alias".$prng->int(1,$child_subquery_tables) } ;
 
770
 
 
771
existing_select_item:
 
772
        { "field".$prng->int(1,$fields) };
 
773
 
 
774
################################################################################
 
775
# end of utility rules                                                         #
 
776
################################################################################
 
777
 
 
778
arithmetic_operator:
 
779
        = | > | < | != | <> | <= | >= ;
 
780
 
 
781
 
 
782
membership_operator:
 
783
    arithmetic_operator all_any |
 
784
    not IN |
 
785
    not IN |
 
786
    not IN |
 
787
    not IN ;
 
788
 
 
789
all_any:
 
790
    ALL | ANY | SOME ;
 
791
 
 
792
################################################################################
 
793
# Used for creating combo_items - ie (field1 + field2) AS fieldX               #
 
794
# We ignore division to prevent division by zero errors                        #
 
795
################################################################################
 
796
math_operator:
 
797
    + | - | * ;
 
798
 
 
799
################################################################################
 
800
# We stack AND to provide more interesting options for the optimizer           #
 
801
# Alter these percentages at your own risk / look for coverage regressions     #
 
802
# with --debug if you play with these.  Those optimizations that require an    #
 
803
# OR-only list in the WHERE clause are specifically stacked in another rule    #
 
804
################################################################################
 
805
and_or:
 
806
        AND | AND | AND | AND | AND | OR ;
 
807
 
 
808
all_distinct:
 
809
   | | | | |
 
810
   | | | ALL | DISTINCT ;
 
811
 
 
812
        
 
813
value:
 
814
        _digit | _digit | _digit | _digit | _tinyint_unsigned|
 
815
        _char(1) | _char(1) | _char(1) | _char(2) | _char(2) | 'USA' ;
 
816
 
 
817
_table:
 
818
     A | B | C | BB | CC | B | C | BB | CC | 
 
819
     CC | CC | CC | CC | CC |
 
820
     C | C | C | C | C | D |  view ;
 
821
 
 
822
################################################################################
 
823
# Add a possibility for 'view' to occur at the end of the previous '_table' rule
 
824
# to allow a chance to use views (when running the RQG with --views)
 
825
################################################################################
 
826
 
 
827
view:
 
828
    view_A | view_AA | view_B | view_BB | view_C | view_CC | view_C | view_CC | view_D ;
 
829
 
 
830
_field:
 
831
    int_field_name | char_field_name ;
 
832
 
 
833
_digit:
 
834
    1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | _tinyint_unsigned ;
 
835
 
 
836
int_field_name:
 
837
    `pk` | `col_int_key` | `col_int_nokey` ;
 
838
 
 
839
int_indexed:
 
840
    `pk` | `col_int_key` ;
 
841
 
 
842
 
 
843
char_field_name:
 
844
    `col_varchar_key` | `col_varchar_nokey` ;
 
845
 
 
846
################################################################################
 
847
# We define LIMIT_rows in this fashion as LIMIT values can differ depending on      #
 
848
# how large the LIMIT is - LIMIT 2 = LIMIT 9 != LIMIT 19                       #
 
849
################################################################################
 
850
 
 
851
limit_size:
 
852
    1 | 2 | 10 | 100 | 1000;