~ubuntu-branches/ubuntu/saucy/drizzle/saucy-proposed

« back to all changes in this revision

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