~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/function/str/make_set.cc

  • Committer: Monty Taylor
  • Date: 2009-03-24 17:44:41 UTC
  • mto: (960.5.2 mordred)
  • mto: This revision was merged to the branch mainline in revision 964.
  • Revision ID: mordred@inaugust.com-20090324174441-nmsq0gwjlgf7f0mt
Changed handlerton to StorageEngine.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2008 Sun Microsystems
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; version 2 of the License.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 */
 
19
 
 
20
#include <drizzled/server_includes.h>
 
21
#include CSTDINT_H
 
22
#include <drizzled/function/str/make_set.h>
 
23
#include <drizzled/session.h>
 
24
 
 
25
void Item_func_make_set::update_used_tables()
 
26
{
 
27
  Item_func::update_used_tables();
 
28
  item->update_used_tables();
 
29
  used_tables_cache|=item->used_tables();
 
30
  const_item_cache&=item->const_item();
 
31
}
 
32
 
 
33
 
 
34
void Item_func_make_set::split_sum_func(Session *session, Item **ref_pointer_array,
 
35
                                        List<Item> &fields)
 
36
{
 
37
  item->split_sum_func(session, ref_pointer_array, fields, &item, true);
 
38
  Item_str_func::split_sum_func(session, ref_pointer_array, fields);
 
39
}
 
40
 
 
41
 
 
42
void Item_func_make_set::fix_length_and_dec()
 
43
{
 
44
  max_length=arg_count-1;
 
45
 
 
46
  if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1))
 
47
    return;
 
48
 
 
49
  for (uint32_t i=0 ; i < arg_count ; i++)
 
50
    max_length+=args[i]->max_length;
 
51
 
 
52
  used_tables_cache|=     item->used_tables();
 
53
  not_null_tables_cache&= item->not_null_tables();
 
54
  const_item_cache&=      item->const_item();
 
55
  with_sum_func= with_sum_func || item->with_sum_func;
 
56
}
 
57
 
 
58
String *Item_func_make_set::val_str(String *str)
 
59
{
 
60
  assert(fixed == 1);
 
61
  uint64_t bits;
 
62
  bool first_found=0;
 
63
  Item **ptr=args;
 
64
  String *result=&my_empty_string;
 
65
 
 
66
  bits=item->val_int();
 
67
  if ((null_value=item->null_value))
 
68
    return NULL;
 
69
 
 
70
  if (arg_count < 64)
 
71
    bits &= ((uint64_t) 1 << arg_count)-1;
 
72
 
 
73
  for (; bits; bits >>= 1, ptr++)
 
74
  {
 
75
    if (bits & 1)
 
76
    {
 
77
      String *res= (*ptr)->val_str(str);
 
78
      if (res)                                  // Skip nulls
 
79
      {
 
80
        if (!first_found)
 
81
        {                                       // First argument
 
82
          first_found=1;
 
83
          if (res != str)
 
84
            result=res;                         // Use original string
 
85
          else
 
86
          {
 
87
            if (tmp_str.copy(*res))             // Don't use 'str'
 
88
              return &my_empty_string;
 
89
            result= &tmp_str;
 
90
          }
 
91
        }
 
92
        else
 
93
        {
 
94
          if (result != &tmp_str)
 
95
          {                                     // Copy data to tmp_str
 
96
            if (tmp_str.alloc(result->length()+res->length()+1) ||
 
97
                tmp_str.copy(*result))
 
98
              return &my_empty_string;
 
99
            result= &tmp_str;
 
100
          }
 
101
          if (tmp_str.append(STRING_WITH_LEN(","), &my_charset_bin) || tmp_str.append(*res))
 
102
            return &my_empty_string;
 
103
        }
 
104
      }
 
105
    }
 
106
  }
 
107
  return result;
 
108
}
 
109
 
 
110
 
 
111
Item *Item_func_make_set::transform(Item_transformer transformer, unsigned char *arg)
 
112
{
 
113
  Item *new_item= item->transform(transformer, arg);
 
114
  if (!new_item)
 
115
    return 0;
 
116
 
 
117
  /*
 
118
    Session::change_item_tree() should be called only if the tree was
 
119
    really transformed, i.e. when a new item has been created.
 
120
    Otherwise we'll be allocating a lot of unnecessary memory for
 
121
    change records at each execution.
 
122
  */
 
123
  if (item != new_item)
 
124
    current_session->change_item_tree(&item, new_item);
 
125
  return Item_str_func::transform(transformer, arg);
 
126
}
 
127
 
 
128
 
 
129
void Item_func_make_set::print(String *str, enum_query_type query_type)
 
130
{
 
131
  str->append(STRING_WITH_LEN("make_set("));
 
132
  item->print(str, query_type);
 
133
  if (arg_count)
 
134
  {
 
135
    str->append(',');
 
136
    print_args(str, 0, query_type);
 
137
  }
 
138
  str->append(')');
 
139
}
 
140