~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/field.cc

  • Committer: Stewart Smith
  • Date: 2009-06-16 00:44:35 UTC
  • mto: (1119.2.6 merge)
  • mto: This revision was merged to the branch mainline in revision 1124.
  • Revision ID: stewart@flamingspork.com-20090616004435-t1vust6erhco7edc
make comment_index test not leave tables behind after running

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, Inc.
 
4
 *  Copyright (C) 2008 Sun Microsystems
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 "config.h"
21
 
 
 
20
#include <drizzled/server_includes.h>
 
21
#include CSTDINT_H
22
22
#include <drizzled/session.h>
23
23
#include <drizzled/table.h>
24
24
#include <drizzled/error.h>
25
 
#include <drizzled/join.h>
26
25
#include <drizzled/sql_base.h>
27
26
#include <drizzled/sql_select.h>
28
27
#include <drizzled/item/cmpfunc.h>
29
28
#include <drizzled/item/field.h>
30
29
#include <drizzled/item/outer_ref.h>
31
 
#include <drizzled/plugin/client.h>
32
 
 
33
 
#include <boost/dynamic_bitset.hpp>
34
 
 
35
 
namespace drizzled
36
 
{
 
30
 
 
31
using namespace drizzled;
37
32
 
38
33
/**
39
34
  Store the pointer to this item field into a list if not already there.
86
81
 
87
82
bool Item_field::find_item_in_field_list_processor(unsigned char *arg)
88
83
{
89
 
  KeyPartInfo *first_non_group_part= *((KeyPartInfo **) arg);
90
 
  KeyPartInfo *last_part= *(((KeyPartInfo **) arg) + 1);
91
 
  KeyPartInfo *cur_part;
 
84
  KEY_PART_INFO *first_non_group_part= *((KEY_PART_INFO **) arg);
 
85
  KEY_PART_INFO *last_part= *(((KEY_PART_INFO **) arg) + 1);
 
86
  KEY_PART_INFO *cur_part;
92
87
 
93
88
  for (cur_part= first_non_group_part; cur_part != last_part; cur_part++)
94
89
  {
110
105
bool Item_field::register_field_in_read_map(unsigned char *arg)
111
106
{
112
107
  Table *table= (Table *) arg;
113
 
  if (field->getTable() == table || !table)
114
 
    field->getTable()->setReadSet(field->position());
115
 
 
116
 
  return 0;
117
 
}
118
 
 
 
108
  if (field->table == table || !table)
 
109
    field->table->setReadSet(field->field_index);
 
110
 
 
111
  return 0;
 
112
}
 
113
 
 
114
 
 
115
Item_field *Item::filed_for_view_update()
 
116
{
 
117
  return 0;
 
118
}
119
119
 
120
120
Item_field::Item_field(Field *f)
121
 
  :Item_ident(0, NULL, f->getTable()->getAlias(), f->field_name),
 
121
  :Item_ident(0, NULL, *f->table_name, f->field_name),
122
122
   item_equal(0), no_const_subst(0),
123
123
   have_privileges(0), any_privileges(0)
124
124
{
138
138
  Item_field (this is important in prepared statements).
139
139
*/
140
140
 
141
 
Item_field::Item_field(Session *,
142
 
                       Name_resolution_context *context_arg,
143
 
                       Field *f) :
144
 
  Item_ident(context_arg,
145
 
             f->getTable()->getShare()->getSchemaName(),
146
 
             f->getTable()->getAlias(),
147
 
             f->field_name),
148
 
   item_equal(0),
149
 
   no_const_subst(0),
150
 
   have_privileges(0),
151
 
   any_privileges(0)
 
141
Item_field::Item_field(Session *, Name_resolution_context *context_arg,
 
142
                       Field *f)
 
143
  :Item_ident(context_arg, f->table->s->db.str, *f->table_name, f->field_name),
 
144
   item_equal(0), no_const_subst(0),
 
145
   have_privileges(0), any_privileges(0)
152
146
{
153
147
  set_field(f);
154
148
}
156
150
 
157
151
Item_field::Item_field(Name_resolution_context *context_arg,
158
152
                       const char *db_arg,const char *table_name_arg,
159
 
                       const char *field_name_arg) :
160
 
  Item_ident(context_arg, db_arg,table_name_arg,field_name_arg),
161
 
   field(0),
162
 
   result_field(0),
163
 
   item_equal(0),
164
 
   no_const_subst(0),
165
 
   have_privileges(0),
166
 
   any_privileges(0)
 
153
                       const char *field_name_arg)
 
154
  :Item_ident(context_arg, db_arg,table_name_arg,field_name_arg),
 
155
   field(0), result_field(0), item_equal(0), no_const_subst(0),
 
156
   have_privileges(0), any_privileges(0)
167
157
{
168
 
  Select_Lex *select= getSession().getLex()->current_select;
 
158
  Select_Lex *select= current_session->lex->current_select;
169
159
  collation.set(DERIVATION_IMPLICIT);
170
 
 
171
160
  if (select && select->parsing_place != IN_HAVING)
172
161
      select->select_n_where_fields++;
173
162
}
176
165
  Constructor need to process subselect with temporary tables (see Item)
177
166
*/
178
167
 
179
 
Item_field::Item_field(Session *session, Item_field *item) :
180
 
  Item_ident(session, item),
181
 
  field(item->field),
182
 
  result_field(item->result_field),
183
 
  item_equal(item->item_equal),
184
 
  no_const_subst(item->no_const_subst),
185
 
  have_privileges(item->have_privileges),
186
 
  any_privileges(item->any_privileges)
 
168
Item_field::Item_field(Session *session, Item_field *item)
 
169
  :Item_ident(session, item),
 
170
   field(item->field),
 
171
   result_field(item->result_field),
 
172
   item_equal(item->item_equal),
 
173
   no_const_subst(item->no_const_subst),
 
174
   have_privileges(item->have_privileges),
 
175
   any_privileges(item->any_privileges)
187
176
{
188
177
  collation.set(DERIVATION_IMPLICIT);
189
178
}
194
183
  maybe_null=field->maybe_null();
195
184
  decimals= field->decimals();
196
185
  max_length= field_par->max_display_length();
197
 
  table_name= field_par->getTable()->getAlias();
 
186
  table_name= *field_par->table_name;
198
187
  field_name= field_par->field_name;
199
 
  db_name= field_par->getTable()->getShare()->getSchemaName();
200
 
  alias_name_used= field_par->getTable()->alias_name_used;
 
188
  db_name= field_par->table->s->db.str;
 
189
  alias_name_used= field_par->table->alias_name_used;
201
190
  unsigned_flag=test(field_par->flags & UNSIGNED_FLAG);
202
191
  collation.set(field_par->charset(), field_par->derivation());
203
192
  fixed= 1;
 
193
  if (field->table->s->tmp_table == SYSTEM_TMP_TABLE)
 
194
    any_privileges= 0;
204
195
}
205
196
 
206
197
 
246
237
}
247
238
 
248
239
 
249
 
type::Decimal *Item_field::val_decimal(type::Decimal *decimal_value)
 
240
my_decimal *Item_field::val_decimal(my_decimal *decimal_value)
250
241
{
251
242
  if ((null_value= field->is_null()))
252
243
    return 0;
262
253
  return result_field->val_str(str,&str_value);
263
254
}
264
255
 
265
 
bool Item_field::get_date(type::Time &ltime,uint32_t fuzzydate)
 
256
bool Item_field::get_date(DRIZZLE_TIME *ltime,uint32_t fuzzydate)
266
257
{
267
258
  if ((null_value=field->is_null()) || field->get_date(ltime,fuzzydate))
268
259
  {
269
 
    ltime.reset();
 
260
    memset(ltime, 0, sizeof(*ltime));
270
261
    return 1;
271
262
  }
272
263
  return 0;
273
264
}
274
265
 
275
 
bool Item_field::get_date_result(type::Time &ltime,uint32_t fuzzydate)
 
266
bool Item_field::get_date_result(DRIZZLE_TIME *ltime,uint32_t fuzzydate)
276
267
{
277
268
  if ((null_value=result_field->is_null()) ||
278
269
      result_field->get_date(ltime,fuzzydate))
279
270
  {
280
 
    ltime.reset();
 
271
    memset(ltime, 0, sizeof(*ltime));
281
272
    return 1;
282
273
  }
283
274
  return 0;
284
275
}
285
276
 
286
 
bool Item_field::get_time(type::Time &ltime)
 
277
bool Item_field::get_time(DRIZZLE_TIME *ltime)
287
278
{
288
279
  if ((null_value=field->is_null()) || field->get_time(ltime))
289
280
  {
290
 
    ltime.reset();
 
281
    memset(ltime, 0, sizeof(*ltime));
291
282
    return 1;
292
283
  }
293
284
  return 0;
308
299
}
309
300
 
310
301
 
311
 
type::Decimal *Item_field::val_decimal_result(type::Decimal *decimal_value)
 
302
my_decimal *Item_field::val_decimal_result(my_decimal *decimal_value)
312
303
{
313
304
  if ((null_value= result_field->is_null()))
314
305
    return 0;
319
310
bool Item_field::val_bool_result()
320
311
{
321
312
  if ((null_value= result_field->is_null()))
322
 
  {
323
313
    return false;
324
 
  }
325
 
 
326
314
  switch (result_field->result_type()) {
327
315
  case INT_RESULT:
328
316
    return result_field->val_int() != 0;
329
 
 
330
317
  case DECIMAL_RESULT:
331
 
    {
332
 
      type::Decimal decimal_value;
333
 
      type::Decimal *val= result_field->val_decimal(&decimal_value);
334
 
      if (val)
335
 
        return not val->isZero();
336
 
      return 0;
337
 
    }
338
 
 
 
318
  {
 
319
    my_decimal decimal_value;
 
320
    my_decimal *val= result_field->val_decimal(&decimal_value);
 
321
    if (val)
 
322
      return !my_decimal_is_zero(val);
 
323
    return 0;
 
324
  }
339
325
  case REAL_RESULT:
340
326
  case STRING_RESULT:
341
327
    return result_field->val_real() != 0.0;
342
 
 
343
328
  case ROW_RESULT:
 
329
  default:
344
330
    assert(0);
345
331
    return 0;                                   // Shut up compiler
346
332
  }
347
 
 
348
 
  assert(0);
349
 
  return 0;                                   // Shut up compiler
350
333
}
351
334
 
352
335
 
369
352
    (In cases where we would choose wrong we would have to generate a
370
353
    ER_NON_UNIQ_ERROR).
371
354
  */
372
 
  return (not my_strcasecmp(system_charset_info, item_field->name, field_name) &&
373
 
          (not item_field->table_name || not table_name ||
374
 
           (not my_strcasecmp(table_alias_charset, item_field->table_name, table_name) &&
375
 
            (not item_field->db_name || not db_name ||
376
 
             (item_field->db_name && not my_strcasecmp(system_charset_info, item_field->db_name, db_name))))));
 
355
  return (!my_strcasecmp(system_charset_info, item_field->name,
 
356
                         field_name) &&
 
357
          (!item_field->table_name || !table_name ||
 
358
           (!my_strcasecmp(table_alias_charset, item_field->table_name,
 
359
                           table_name) &&
 
360
            (!item_field->db_name || !db_name ||
 
361
             (item_field->db_name && !strcmp(item_field->db_name,
 
362
                                             db_name))))));
377
363
}
378
364
 
379
365
 
380
366
table_map Item_field::used_tables() const
381
367
{
382
 
  if (field->getTable()->const_table)
383
 
  {
 
368
  if (field->table->const_table)
384
369
    return 0;                                   // const item
385
 
  }
386
 
 
387
 
  return (depended_from ? OUTER_REF_TABLE_BIT : field->getTable()->map);
 
370
  return (depended_from ? OUTER_REF_TABLE_BIT : field->table->map);
388
371
}
389
372
 
390
373
enum Item_result Item_field::result_type () const
540
523
      {
541
524
        if (*from_field != view_ref_found)
542
525
        {
543
 
          prev_subselect_item->used_tables_cache|= (*from_field)->getTable()->map;
544
 
          prev_subselect_item->const_item_cache= false;
 
526
          prev_subselect_item->used_tables_cache|= (*from_field)->table->map;
 
527
          prev_subselect_item->const_item_cache= 0;
545
528
          set_field(*from_field);
546
529
          if (!last_checked_context->select_lex->having_fix_field &&
547
530
              select->group_list.elements &&
629
612
      case it does not matter which used tables bits we set)
630
613
    */
631
614
    prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
632
 
    prev_subselect_item->const_item_cache= false;
 
615
    prev_subselect_item->const_item_cache= 0;
633
616
  }
634
617
 
635
618
  assert(ref != 0);
640
623
    if (upward_lookup)
641
624
    {
642
625
      // We can't say exactly what absent table or field
643
 
      my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), session->where());
 
626
      my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), session->where);
644
627
    }
645
628
    else
646
629
    {
707
690
    {
708
691
      Item_ref *rf;
709
692
      rf= new Item_ref(context,
710
 
                       (cached_table->getSchemaName()[0] ? cached_table->getSchemaName() : 0),
 
693
                       (cached_table->db[0] ? cached_table->db : 0),
711
694
                       (char*) cached_table->alias, (char*) field_name);
712
695
      if (!rf)
713
696
        return -1;
799
782
      {
800
783
        uint32_t counter;
801
784
        enum_resolution_type resolution;
802
 
        Item** res= find_item_in_list(session,
803
 
                                      this, session->lex->current_select->item_list,
 
785
        Item** res= find_item_in_list(this, session->lex->current_select->item_list,
804
786
                                      &counter, REPORT_EXCEPT_NOT_FOUND,
805
787
                                      &resolution);
806
788
        if (!res)
824
806
            {
825
807
              /* The column to which we link isn't valid. */
826
808
              my_error(ER_BAD_FIELD_ERROR, MYF(0), (*res)->name,
827
 
                       session->where());
 
809
                       current_session->where);
828
810
              return(1);
829
811
            }
830
812
 
898
880
  }
899
881
  else if (session->mark_used_columns != MARK_COLUMNS_NONE)
900
882
  {
901
 
    Table *table= field->getTable();
902
 
    boost::dynamic_bitset<> *current_bitmap, *other_bitmap;
 
883
    Table *table= field->table;
 
884
    MY_BITMAP *current_bitmap, *other_bitmap;
903
885
    if (session->mark_used_columns == MARK_COLUMNS_READ)
904
886
    {
905
887
      current_bitmap= table->read_set;
910
892
      current_bitmap= table->write_set;
911
893
      other_bitmap=   table->read_set;
912
894
    }
913
 
    //if (! current_bitmap->testAndSet(field->position()))
914
 
    if (! current_bitmap->test(field->position()))
 
895
    if (!bitmap_test_and_set(current_bitmap, field->field_index))
915
896
    {
916
 
      if (! other_bitmap->test(field->position()))
 
897
      if (!bitmap_is_set(other_bitmap, field->field_index))
917
898
      {
918
899
        /* First usage of column */
919
900
        table->used_fields++;                     // Used to optimize loops
 
901
        /* purecov: begin inspected */
920
902
        table->covering_keys&= field->part_of_key;
 
903
        /* purecov: end */
921
904
      }
922
905
    }
923
906
  }
1199
1182
}
1200
1183
 
1201
1184
 
1202
 
bool Item_field::send(plugin::Client *client, String *)
 
1185
bool Item_field::send(plugin::Protocol *protocol, String *)
1203
1186
{
1204
 
  return client->store(result_field);
 
1187
  return protocol->store(result_field);
1205
1188
}
1206
1189
 
1207
1190
 
1211
1194
    need to set no_errors to prevent warnings about type conversion
1212
1195
    popping up.
1213
1196
  */
1214
 
  Session *session= field->getTable()->in_use;
 
1197
  Session *session= field->table->in_use;
1215
1198
  int no_errors;
1216
1199
 
1217
1200
  no_errors= session->no_errors;
1248
1231
  Select_Lex *select= (Select_Lex*)select_arg;
1249
1232
  assert(fixed);
1250
1233
 
1251
 
  if (field->getTable() != select->context.table_list->table)
 
1234
  if (field->table != select->context.table_list->table)
1252
1235
  {
1253
1236
    List<Item> *all_fields= &select->join->all_fields;
1254
1237
    Item **ref_pointer_array= select->ref_pointer_array;
1267
1250
 
1268
1251
void Item_field::print(String *str, enum_query_type query_type)
1269
1252
{
1270
 
  if (field && field->getTable()->const_table)
 
1253
  if (field && field->table->const_table)
1271
1254
  {
1272
1255
    char buff[MAX_FIELD_WIDTH];
1273
1256
    String tmp(buff,sizeof(buff),str->charset());
1274
 
    field->val_str_internal(&tmp);
1275
 
    if (field->is_null())  {
1276
 
      str->append("NULL");
1277
 
    }
1278
 
    else {
1279
 
      str->append('\'');
1280
 
      str->append(tmp);
1281
 
      str->append('\'');
1282
 
    }
 
1257
    field->val_str(&tmp);
 
1258
    str->append('\'');
 
1259
    str->append(tmp);
 
1260
    str->append('\'');
1283
1261
    return;
1284
1262
  }
1285
1263
  Item_ident::print(str, query_type);
1286
1264
}
1287
 
 
1288
 
 
1289
 
} /* namespace drizzled */