@@ -2859,6 +2859,104 @@ impl<'a> IntoIterator for &'a Operations {
28592859 }
28602860}
28612861
2862+ /// Prune a randomly generated set of query operations to avoid combinations we don't support (or
2863+ /// that are too expensive) in fuzz-generated queries.
2864+ fn prune_query_operations ( ops : & mut Vec < QueryOperation > ) {
2865+ // Don't generate an aggregate with distinct keyword or a plain distinct in the same query as a
2866+ // WHERE IN clause, since we don't support those queries (ENG-2942)
2867+ let mut distinct_found = false ;
2868+ let mut in_parameter_found = false ;
2869+
2870+ // Don't generate an OR filter in the same query as a parameter of any kind, since
2871+ // we don't support those queries (ENG-2976)
2872+ let mut parameter_found = false ;
2873+ let mut or_filter_found = false ;
2874+
2875+ // Only allow one window function per query
2876+ // Window functions can't be used with: ranges, aggregates, or group by
2877+ let mut window_function_found = false ;
2878+ let mut range_parameter_found = false ;
2879+ let mut aggregate_found = false ;
2880+
2881+ ops. retain ( |op| match op {
2882+ QueryOperation :: ColumnAggregate ( agg) if agg. is_distinct ( ) => {
2883+ if in_parameter_found || window_function_found {
2884+ false
2885+ } else {
2886+ distinct_found = true ;
2887+ aggregate_found = true ;
2888+ true
2889+ }
2890+ }
2891+ QueryOperation :: Distinct => {
2892+ if in_parameter_found {
2893+ false
2894+ } else {
2895+ distinct_found = true ;
2896+ true
2897+ }
2898+ }
2899+ QueryOperation :: InParameter { .. } => {
2900+ if distinct_found || or_filter_found || window_function_found || in_parameter_found {
2901+ false
2902+ } else {
2903+ in_parameter_found = true ;
2904+ parameter_found = true ;
2905+ true
2906+ }
2907+ }
2908+ QueryOperation :: SingleParameter | QueryOperation :: MultipleParameters => {
2909+ if or_filter_found {
2910+ false
2911+ } else {
2912+ parameter_found = true ;
2913+ true
2914+ }
2915+ }
2916+ QueryOperation :: RangeParameter | QueryOperation :: MultipleRangeParameters => {
2917+ if window_function_found || or_filter_found {
2918+ false
2919+ } else {
2920+ range_parameter_found = true ;
2921+ parameter_found = true ;
2922+ true
2923+ }
2924+ }
2925+ QueryOperation :: Filter ( Filter {
2926+ extend_where_with : LogicalOp :: Or ,
2927+ ..
2928+ } ) => {
2929+ if parameter_found {
2930+ false
2931+ } else {
2932+ or_filter_found = true ;
2933+ true
2934+ }
2935+ }
2936+ QueryOperation :: ColumnAggregate ( _) => {
2937+ if window_function_found {
2938+ false
2939+ } else {
2940+ aggregate_found = true ;
2941+ true
2942+ }
2943+ }
2944+ QueryOperation :: WindowFunction ( _) => {
2945+ if window_function_found
2946+ || range_parameter_found
2947+ || aggregate_found
2948+ || in_parameter_found
2949+ {
2950+ false
2951+ } else {
2952+ window_function_found = true ;
2953+ true
2954+ }
2955+ }
2956+ _ => true ,
2957+ } ) ;
2958+ }
2959+
28622960impl Arbitrary for Operations {
28632961 type Parameters = <Vec < QueryOperation > as Arbitrary >:: Parameters ;
28642962
@@ -2867,101 +2965,7 @@ impl Arbitrary for Operations {
28672965 fn arbitrary_with ( args : Self :: Parameters ) -> Self :: Strategy {
28682966 any_with :: < Vec < QueryOperation > > ( args)
28692967 . prop_map ( |mut ops| {
2870- // Don't generate an aggregate with distinct keyword or a plain distinct
2871- // in the same query as a WHERE IN clause,
2872- // since we don't support those queries (ENG-2942)
2873- let mut distinct_found = false ;
2874- let mut in_parameter_found = false ;
2875-
2876- // Don't generate an OR filter in the same query as a parameter of any kind, since
2877- // we don't support those queries (ENG-2976)
2878- let mut parameter_found = false ;
2879- let mut or_filter_found = false ;
2880-
2881- // Only allow one window function per query
2882- // Window functions can't be used with: ranges, aggregates, or group by
2883- let mut window_function_found = false ;
2884- let mut range_parameter_found = false ;
2885- let mut aggregate_found = false ;
2886-
2887- ops. retain ( |op| match op {
2888- QueryOperation :: ColumnAggregate ( agg) if agg. is_distinct ( ) => {
2889- if in_parameter_found || window_function_found {
2890- false
2891- } else {
2892- distinct_found = true ;
2893- aggregate_found = true ;
2894- true
2895- }
2896- }
2897- QueryOperation :: Distinct => {
2898- if in_parameter_found {
2899- false
2900- } else {
2901- distinct_found = true ;
2902- true
2903- }
2904- }
2905- QueryOperation :: InParameter { .. } => {
2906- if distinct_found || or_filter_found || window_function_found {
2907- false
2908- } else {
2909- in_parameter_found = true ;
2910- parameter_found = true ;
2911- true
2912- }
2913- }
2914- QueryOperation :: SingleParameter | QueryOperation :: MultipleParameters => {
2915- if or_filter_found {
2916- false
2917- } else {
2918- parameter_found = true ;
2919- true
2920- }
2921- }
2922- QueryOperation :: RangeParameter | QueryOperation :: MultipleRangeParameters => {
2923- if window_function_found || or_filter_found {
2924- false
2925- } else {
2926- range_parameter_found = true ;
2927- parameter_found = true ;
2928- true
2929- }
2930- }
2931- QueryOperation :: Filter ( Filter {
2932- extend_where_with : LogicalOp :: Or ,
2933- ..
2934- } ) => {
2935- if parameter_found {
2936- false
2937- } else {
2938- or_filter_found = true ;
2939- true
2940- }
2941- }
2942- QueryOperation :: ColumnAggregate ( _) => {
2943- if window_function_found {
2944- false
2945- } else {
2946- aggregate_found = true ;
2947- true
2948- }
2949- }
2950- QueryOperation :: WindowFunction ( _) => {
2951- if window_function_found
2952- || range_parameter_found
2953- || aggregate_found
2954- || in_parameter_found
2955- {
2956- false
2957- } else {
2958- window_function_found = true ;
2959- true
2960- }
2961- }
2962- _ => true ,
2963- } ) ;
2964-
2968+ prune_query_operations ( & mut ops) ;
29652969 Operations ( ops)
29662970 } )
29672971 . boxed ( )
@@ -3573,6 +3577,24 @@ mod tests {
35733577 }
35743578 }
35753579
3580+ #[ test]
3581+ fn prunes_extra_in_parameters ( ) {
3582+ let mut ops = vec ! [
3583+ QueryOperation :: InParameter { num_values: 2 } ,
3584+ QueryOperation :: InParameter { num_values: 3 } ,
3585+ QueryOperation :: SingleParameter ,
3586+ ] ;
3587+
3588+ prune_query_operations ( & mut ops) ;
3589+
3590+ assert_eq ! (
3591+ ops. into_iter( )
3592+ . filter( |op| matches!( op, QueryOperation :: InParameter { .. } ) )
3593+ . count( ) ,
3594+ 1
3595+ ) ;
3596+ }
3597+
35763598 mod parse_num_operations {
35773599 use super :: * ;
35783600
0 commit comments