~jlukas79/+junk/mysql-server

« back to all changes in this revision

Viewing changes to sql/item_sum.cc

manual merge 6.0-main --> 6.0-bka-review

Show diffs side-by-side

added added

removed removed

Lines of Context:
68
68
  aggr_sel= NULL;
69
69
  max_arg_level= -1;
70
70
  max_sum_func_level= -1;
 
71
  outer_fields.empty();
71
72
  return FALSE;
72
73
}
73
74
 
176
177
               MYF(0));
177
178
    return TRUE;
178
179
  }
 
180
 
179
181
  if (in_sum_func)
180
182
  {
181
183
    /*
196
198
      set_if_bigger(in_sum_func->max_sum_func_level, aggr_level);
197
199
    set_if_bigger(in_sum_func->max_sum_func_level, max_sum_func_level);
198
200
  }
 
201
 
 
202
  /*
 
203
    Check that non-aggregated fields and sum functions aren't mixed in the
 
204
    same select in the ONLY_FULL_GROUP_BY mode.
 
205
  */
 
206
  if (outer_fields.elements)
 
207
  {
 
208
    Item_field *field;
 
209
    /*
 
210
      Here we compare the nesting level of the select to which an outer field
 
211
      belongs to with the aggregation level of the sum function. All fields in
 
212
      the outer_fields list are checked.
 
213
 
 
214
      If the nesting level is equal to the aggregation level then the field is
 
215
        aggregated by this sum function.
 
216
      If the nesting level is less than the aggregation level then the field
 
217
        belongs to an outer select. In this case if there is an embedding sum
 
218
        function add current field to functions outer_fields list. If there is
 
219
        no embedding function then the current field treated as non aggregated
 
220
        and the select it belongs to is marked accordingly.
 
221
      If the nesting level is greater than the aggregation level then it means
 
222
        that this field was added by an inner sum function.
 
223
        Consider an example:
 
224
 
 
225
          select avg ( <-- we are here, checking outer.f1
 
226
            select (
 
227
              select sum(outer.f1 + inner.f1) from inner
 
228
            ) from outer)
 
229
          from most_outer;
 
230
 
 
231
        In this case we check that no aggregate functions are used in the
 
232
        select the field belongs to. If there are some then an error is
 
233
        raised.
 
234
    */
 
235
    List_iterator<Item_field> of(outer_fields);
 
236
    while ((field= of++))
 
237
    {
 
238
      SELECT_LEX *sel= field->cached_table->select_lex;
 
239
      if (sel->nest_level < aggr_level)
 
240
      {
 
241
        if (in_sum_func)
 
242
        {
 
243
          /*
 
244
            Let upper function decide whether this field is a non
 
245
            aggregated one.
 
246
          */
 
247
          in_sum_func->outer_fields.push_back(field);
 
248
        }
 
249
        else
 
250
          sel->full_group_by_flag|= NON_AGG_FIELD_USED;
 
251
      }
 
252
      if (sel->nest_level > aggr_level &&
 
253
          (sel->full_group_by_flag & SUM_FUNC_USED) &&
 
254
          !sel->group_list.elements)
 
255
      {
 
256
        my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
 
257
                   ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
 
258
        return TRUE;
 
259
      }
 
260
    }
 
261
  }
 
262
  aggr_sel->full_group_by_flag|= SUM_FUNC_USED;
199
263
  update_used_tables();
200
264
  thd->lex->in_sum_func= in_sum_func;
201
265
  return FALSE;
3011
3075
      result->append(*res);
3012
3076
  }
3013
3077
 
 
3078
  item->row_count++;
 
3079
 
3014
3080
  /* stop if length of result more than max_length */
3015
3081
  if (result->length() > item->max_length)
3016
3082
  {
3029
3095
                                          result->length(),
3030
3096
                                          &well_formed_error);
3031
3097
    result->length(old_length + add_length);
3032
 
    item->count_cut_values++;
3033
3098
    item->warning_for_row= TRUE;
 
3099
    push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
3100
                        ER_CUT_VALUE_GROUP_CONCAT, ER(ER_CUT_VALUE_GROUP_CONCAT),
 
3101
                        item->row_count);
3034
3102
    return 1;
3035
3103
  }
3036
3104
  return 0;
3050
3118
Item_func_group_concat(Name_resolution_context *context_arg,
3051
3119
                       bool distinct_arg, List<Item> *select_list,
3052
3120
                       SQL_LIST *order_list, String *separator_arg)
3053
 
  :tmp_table_param(0), warning(0),
3054
 
   separator(separator_arg), tree(0), unique_filter(NULL), table(0),
 
3121
  :tmp_table_param(0), separator(separator_arg), tree(0),
 
3122
   unique_filter(NULL), table(0),
3055
3123
   order(0), context(context_arg),
3056
3124
   arg_count_order(order_list ? order_list->elements : 0),
3057
3125
   arg_count_field(select_list->elements),
3058
 
   count_cut_values(0),
 
3126
   row_count(0),
3059
3127
   distinct(distinct_arg),
3060
3128
   warning_for_row(FALSE),
3061
3129
   force_copy_fields(0), original(0)
3103
3171
                                               Item_func_group_concat *item)
3104
3172
  :Item_sum(thd, item),
3105
3173
  tmp_table_param(item->tmp_table_param),
3106
 
  warning(item->warning),
3107
3174
  separator(item->separator),
3108
3175
  tree(item->tree),
3109
3176
  unique_filter(item->unique_filter),
3112
3179
  context(item->context),
3113
3180
  arg_count_order(item->arg_count_order),
3114
3181
  arg_count_field(item->arg_count_field),
3115
 
  count_cut_values(item->count_cut_values),
 
3182
  row_count(item->row_count),
3116
3183
  distinct(item->distinct),
3117
3184
  warning_for_row(item->warning_for_row),
3118
3185
  always_null(item->always_null),
3130
3197
  DBUG_ENTER("Item_func_group_concat::cleanup");
3131
3198
  Item_sum::cleanup();
3132
3199
 
3133
 
  /* Adjust warning message to include total number of cut values */
3134
 
  if (warning)
3135
 
  {
3136
 
    char warn_buff[MYSQL_ERRMSG_SIZE];
3137
 
    sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3138
 
    warning->set_msg(current_thd, warn_buff);
3139
 
    warning= 0;
3140
 
  }
3141
 
 
3142
3200
  /*
3143
3201
    Free table and tree if they belong to this item (if item have not pointer
3144
3202
    to original item from which was made copy => it own its objects )
3162
3220
        delete unique_filter;
3163
3221
        unique_filter= NULL;
3164
3222
      }
3165
 
      if (warning)
3166
 
      {
3167
 
        char warn_buff[MYSQL_ERRMSG_SIZE];
3168
 
        sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
3169
 
        warning->set_msg(thd, warn_buff);
3170
 
        warning= 0;
3171
 
      }
3172
3223
    }
3173
 
    DBUG_ASSERT(tree == 0 && warning == 0);
 
3224
    DBUG_ASSERT(tree == 0);
3174
3225
  }
3175
3226
  DBUG_VOID_RETURN;
3176
3227
}
3191
3242
  no_appended= TRUE;
3192
3243
  if (tree)
3193
3244
    reset_tree(tree);
3194
 
  if (distinct)
 
3245
  if (unique_filter)
3195
3246
    unique_filter->reset();
3196
3247
  /* No need to reset the table as we never call write_row */
3197
3248
}
3453
3504
    /* Tree is used for sorting as in ORDER BY */
3454
3505
    tree_walk(tree, (tree_walk_action)&dump_leaf_key, (void*)this,
3455
3506
              left_root_right);
3456
 
  if (count_cut_values && !warning)
3457
 
  {
3458
 
    /*
3459
 
      ER_CUT_VALUE_GROUP_CONCAT needs an argument, but this gets set in
3460
 
      Item_func_group_concat::cleanup().
3461
 
    */
3462
 
    DBUG_ASSERT(table);
3463
 
    warning= push_warning(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN,
3464
 
                          ER_CUT_VALUE_GROUP_CONCAT,
3465
 
                          ER(ER_CUT_VALUE_GROUP_CONCAT));
3466
 
  }
3467
3507
  return &result;
3468
3508
}
3469
3509