~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/function/set_user_var.cc

Fix merge issues with 1.0 CC fix.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems
 
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#include <drizzled/server_includes.h>
21
 
#include CSTDINT_H
 
20
#include <config.h>
 
21
 
22
22
#include <drizzled/function/set_user_var.h>
23
 
#include <drizzled/function/get_variable.h>
24
 
#include <drizzled/function/update_hash.h>
25
23
#include <drizzled/field/num.h>
26
 
#include <drizzled/virtual_column_info.h>
27
24
#include <drizzled/session.h>
 
25
#include <drizzled/plugin/client.h>
 
26
#include <drizzled/user_var_entry.h>
 
27
#include <drizzled/table.h>
 
28
 
 
29
namespace drizzled {
28
30
 
29
31
/*
30
32
  When a user variable is updated (in a SET command or a query like
36
38
  assert(fixed == 0);
37
39
  /* fix_fields will call Item_func_set_user_var::fix_length_and_dec */
38
40
  if (Item_func::fix_fields(session, ref) ||
39
 
      !(entry= get_variable(&session->user_vars, name, 1)))
 
41
      !(entry= session->getVariable(name, true)))
40
42
    return true;
41
43
  /*
42
44
     Remember the last query which updated it, this way a query can later know
43
45
     if this variable is a constant item in the query (it is if update_query_id
44
46
     is different from query_id).
45
47
  */
46
 
  entry->update_query_id= session->query_id;
 
48
  entry->update_query_id= session->getQueryId();
47
49
  /*
48
50
    As it is wrong and confusing to associate any
49
51
    character set with NULL, @a should be latin2
89
91
  if (result_field)
90
92
  {
91
93
    Table *table= (Table *) arg;
92
 
    if (result_field->table == table || !table)
93
 
      bitmap_set_bit(result_field->table->read_set, result_field->field_index);
94
 
    if (result_field->vcol_info && result_field->vcol_info->expr_item)
95
 
      return result_field->vcol_info->
96
 
               expr_item->walk(&Item::register_field_in_read_map, 1, arg);
97
 
  }
98
 
  return 0;
99
 
}
100
 
 
101
 
/*
102
 
  Mark field in bitmap supplied as *arg
103
 
 
104
 
*/
105
 
 
106
 
bool Item_func_set_user_var::register_field_in_bitmap(unsigned char *arg)
107
 
{
108
 
  MY_BITMAP *bitmap = (MY_BITMAP *) arg;
109
 
  assert(bitmap);
110
 
  if (result_field)
111
 
  {
112
 
    bitmap_set_bit(bitmap, result_field->field_index);
113
 
  }
114
 
  return 0;
115
 
}
116
 
 
117
 
bool
118
 
Item_func_set_user_var::update_hash(void *ptr, uint32_t length,
 
94
    if (result_field->getTable() == table || !table)
 
95
      result_field->getTable()->setReadSet(result_field->position());
 
96
  }
 
97
  return 0;
 
98
}
 
99
 
 
100
 
 
101
void
 
102
Item_func_set_user_var::update_hash(data_ref data,
119
103
                                    Item_result res_type,
120
 
                                    const CHARSET_INFO * const cs, Derivation dv,
 
104
                                    const charset_info_st * const cs, Derivation dv,
121
105
                                    bool unsigned_arg)
122
106
{
123
107
  /*
126
110
  */
127
111
  if ((null_value= args[0]->null_value) && null_item)
128
112
    res_type= entry->type;                      // Don't change type of item
129
 
  if (::update_hash(entry, (null_value= args[0]->null_value),
130
 
                    ptr, length, res_type, cs, dv, unsigned_arg))
131
 
  {
132
 
    null_value= 1;
133
 
    return 1;
134
 
  }
135
 
  return 0;
 
113
  entry->update_hash((null_value= args[0]->null_value), data, res_type, cs, dv, unsigned_arg);
136
114
}
137
115
 
138
116
/**
157
135
 
158
136
  switch (cached_result_type) {
159
137
  case REAL_RESULT:
160
 
  {
161
 
    save_result.vreal= use_result_field ? result_field->val_real() :
162
 
                        args[0]->val_real();
163
 
    break;
164
 
  }
 
138
    {
 
139
      save_result.vreal= use_result_field ? result_field->val_real() :
 
140
        args[0]->val_real();
 
141
      break;
 
142
    }
165
143
  case INT_RESULT:
166
 
  {
167
 
    save_result.vint= use_result_field ? result_field->val_int() :
168
 
                       args[0]->val_int();
169
 
    unsigned_flag= use_result_field ? ((Field_num*)result_field)->unsigned_flag:
170
 
                    args[0]->unsigned_flag;
171
 
    break;
172
 
  }
 
144
    {
 
145
      save_result.vint= use_result_field ? result_field->val_int() :
 
146
        args[0]->val_int();
 
147
 
 
148
      unsigned_flag= use_result_field ? ((Field_num*)result_field)->unsigned_flag:
 
149
        args[0]->unsigned_flag;
 
150
 
 
151
      break;
 
152
    }
173
153
  case STRING_RESULT:
174
 
  {
175
 
    save_result.vstr= use_result_field ? result_field->val_str(&value) :
176
 
                       args[0]->val_str(&value);
177
 
    break;
178
 
  }
 
154
    {
 
155
      save_result.vstr= use_result_field ? result_field->val_str_internal(&value) :
 
156
        args[0]->val_str(&value);
 
157
      break;
 
158
    }
179
159
  case DECIMAL_RESULT:
180
 
  {
181
 
    save_result.vdec= use_result_field ?
182
 
                       result_field->val_decimal(&decimal_buff) :
183
 
                       args[0]->val_decimal(&decimal_buff);
184
 
    break;
185
 
  }
 
160
    {
 
161
      save_result.vdec= use_result_field ?
 
162
        result_field->val_decimal(&decimal_buff) :
 
163
        args[0]->val_decimal(&decimal_buff);
 
164
      break;
 
165
    }
186
166
  case ROW_RESULT:
187
 
  default:
188
167
    // This case should never be chosen
189
168
    assert(0);
190
169
    break;
191
170
  }
192
 
  return(false);
 
171
 
 
172
  return false;
193
173
}
194
174
 
195
175
/**
207
187
 
208
188
*/
209
189
 
210
 
bool
 
190
void
211
191
Item_func_set_user_var::update()
212
192
{
213
 
  bool res= false;
214
 
 
215
193
  switch (cached_result_type) {
216
194
  case REAL_RESULT:
217
 
  {
218
 
    res= update_hash((void*) &save_result.vreal,sizeof(save_result.vreal),
219
 
                     REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
220
 
    break;
221
 
  }
 
195
    {
 
196
      update_hash(data_ref(&save_result.vreal, sizeof(save_result.vreal)), REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
 
197
      break;
 
198
    }
 
199
 
222
200
  case INT_RESULT:
223
 
  {
224
 
    res= update_hash((void*) &save_result.vint, sizeof(save_result.vint),
225
 
                     INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT,
226
 
                     unsigned_flag);
227
 
    break;
228
 
  }
 
201
    {
 
202
      update_hash(data_ref(&save_result.vint, sizeof(save_result.vint)), INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, unsigned_flag);
 
203
      break;
 
204
    }
 
205
 
229
206
  case STRING_RESULT:
230
 
  {
231
 
    if (!save_result.vstr)                                      // Null value
232
 
      res= update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin,
233
 
                       DERIVATION_IMPLICIT, 0);
234
 
    else
235
 
      res= update_hash((void*) save_result.vstr->ptr(),
236
 
                       save_result.vstr->length(), STRING_RESULT,
237
 
                       save_result.vstr->charset(),
238
 
                       DERIVATION_IMPLICIT, 0);
239
 
    break;
240
 
  }
 
207
    {
 
208
      if (!save_result.vstr)                                      // Null value
 
209
        update_hash(data_ref(), STRING_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
 
210
      else
 
211
        update_hash(*save_result.vstr, STRING_RESULT, save_result.vstr->charset(), DERIVATION_IMPLICIT, 0);
 
212
      break;
 
213
    }
 
214
 
241
215
  case DECIMAL_RESULT:
242
 
  {
243
 
    if (!save_result.vdec)                                      // Null value
244
 
      res= update_hash((void*) 0, 0, DECIMAL_RESULT, &my_charset_bin,
245
 
                       DERIVATION_IMPLICIT, 0);
246
 
    else
247
 
      res= update_hash((void*) save_result.vdec,
248
 
                       sizeof(my_decimal), DECIMAL_RESULT,
249
 
                       &my_charset_bin, DERIVATION_IMPLICIT, 0);
250
 
    break;
251
 
  }
 
216
    {
 
217
      if (!save_result.vdec)                                      // Null value
 
218
        update_hash(data_ref(), DECIMAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
 
219
      else
 
220
        update_hash(data_ref(save_result.vdec, sizeof(type::Decimal)), DECIMAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
 
221
      break;
 
222
    }
 
223
 
252
224
  case ROW_RESULT:
253
 
  default:
254
225
    // This case should never be chosen
255
 
    assert(0);
 
226
    assert(false);
256
227
    break;
257
228
  }
258
 
  return(res);
259
229
}
260
230
 
261
231
double Item_func_set_user_var::val_real()
283
253
}
284
254
 
285
255
 
286
 
my_decimal *Item_func_set_user_var::val_decimal(my_decimal *val)
 
256
type::Decimal *Item_func_set_user_var::val_decimal(type::Decimal *val)
287
257
{
288
258
  assert(fixed == 1);
289
259
  check(0);
316
286
}
317
287
 
318
288
 
319
 
my_decimal *Item_func_set_user_var::val_decimal_result(my_decimal *val)
 
289
type::Decimal *Item_func_set_user_var::val_decimal_result(type::Decimal *val)
320
290
{
321
291
  assert(fixed == 1);
322
292
  check(true);
324
294
  return entry->val_decimal(&null_value, val);
325
295
}
326
296
 
327
 
void Item_func_set_user_var::print(String *str, enum_query_type query_type)
 
297
void Item_func_set_user_var::print(String *str)
328
298
{
329
299
  str->append(STRING_WITH_LEN("(@"));
330
 
  str->append(name.str, name.length);
331
 
  str->append(STRING_WITH_LEN(":="));
332
 
  args[0]->print(str, query_type);
333
 
  str->append(')');
334
 
}
335
 
 
336
 
 
337
 
void Item_func_set_user_var::print_as_stmt(String *str,
338
 
                                           enum_query_type query_type)
339
 
{
340
 
  str->append(STRING_WITH_LEN("set @"));
341
 
  str->append(name.str, name.length);
342
 
  str->append(STRING_WITH_LEN(":="));
343
 
  args[0]->print(str, query_type);
344
 
  str->append(')');
345
 
}
346
 
 
347
 
bool Item_func_set_user_var::send(Protocol *protocol, String *str_arg)
 
300
  str->append(name);
 
301
  str->append(STRING_WITH_LEN(":="));
 
302
  args[0]->print(str);
 
303
  str->append(')');
 
304
}
 
305
 
 
306
void Item_func_set_user_var::send(plugin::Client *client, String *str_arg)
348
307
{
349
308
  if (result_field)
350
309
  {
351
310
    check(1);
352
311
    update();
353
 
    return protocol->store(result_field);
 
312
    client->store(result_field);
 
313
    return;
354
314
  }
355
 
  return Item::send(protocol, str_arg);
 
315
  Item::send(client, str_arg);
356
316
}
357
317
 
358
 
void Item_func_set_user_var::make_field(Send_field *tmp_field)
 
318
void Item_func_set_user_var::make_field(SendField *tmp_field)
359
319
{
360
320
  if (result_field)
361
321
  {
365
325
      tmp_field->col_name=Item::name;               // Use user supplied name
366
326
  }
367
327
  else
 
328
  {
368
329
    Item::make_field(tmp_field);
 
330
  }
369
331
}
370
332
 
371
333
/*
421
383
      (result_type() == REAL_RESULT && field->result_type() == STRING_RESULT))
422
384
  {
423
385
    String *result;
424
 
    const CHARSET_INFO * const cs= collation.collation;
 
386
    const charset_info_st * const cs= collation.collation;
425
387
    char buff[MAX_FIELD_WIDTH];         // Alloc buffer for small columns
426
388
    str_value.set_quick(buff, sizeof(buff), cs);
427
389
    result= entry->val_str(&null_value, &str_value, decimals);
448
410
  }
449
411
  else if (result_type() == DECIMAL_RESULT)
450
412
  {
451
 
    my_decimal decimal_value;
452
 
    my_decimal *val= entry->val_decimal(&null_value, &decimal_value);
 
413
    type::Decimal decimal_value;
 
414
    type::Decimal *val= entry->val_decimal(&null_value, &decimal_value);
453
415
    if (null_value)
454
416
      return set_field_to_null(field);
455
417
    field->set_notnull();
467
429
}
468
430
 
469
431
 
 
432
} /* namespace drizzled */