~drizzle-trunk/drizzle/development

1008.3.1 by Stewart Smith
move Item_default_value out into its own files under drizzled/item/ to make it easier to find and follow current convention
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 <drizzled/error.h>
22
#include <drizzled/name_resolution_context.h>
23
#include <drizzled/table.h>
24
#include <drizzled/session.h>
25
#include <drizzled/current_session.h>
26
#include <drizzled/item/default_value.h>
27
28
bool Item_default_value::eq(const Item *item, bool binary_cmp) const
29
{
30
  return item->type() == DEFAULT_VALUE_ITEM &&
31
    ((Item_default_value *)item)->arg->eq(arg, binary_cmp);
32
}
33
34
35
bool Item_default_value::fix_fields(Session *session, Item **)
36
{
37
  Item *real_arg;
38
  Item_field *field_arg;
39
  Field *def_field;
40
  assert(fixed == 0);
41
42
  if (!arg)
43
  {
44
    fixed= 1;
45
    return false;
46
  }
47
  if (!arg->fixed && arg->fix_fields(session, &arg))
48
    goto error;
49
50
51
  real_arg= arg->real_item();
52
  if (real_arg->type() != FIELD_ITEM)
53
  {
54
    my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), arg->name);
55
    goto error;
56
  }
57
58
  field_arg= (Item_field *)real_arg;
59
  if (field_arg->field->flags & NO_DEFAULT_VALUE_FLAG)
60
  {
61
    my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), field_arg->field->field_name);
62
    goto error;
63
  }
64
  if (!(def_field= (Field*) sql_alloc(field_arg->field->size_of())))
65
    goto error;
66
  memcpy(def_field, field_arg->field, field_arg->field->size_of());
67
  def_field->move_field_offset((my_ptrdiff_t)
68
                               (def_field->table->s->default_values -
69
                                def_field->table->record[0]));
70
  set_field(def_field);
71
  return false;
72
73
error:
74
  context->process_error(session);
75
  return true;
76
}
77
78
79
void Item_default_value::print(String *str, enum_query_type query_type)
80
{
81
  if (!arg)
82
  {
83
    str->append(STRING_WITH_LEN("default"));
84
    return;
85
  }
86
  str->append(STRING_WITH_LEN("default("));
87
  arg->print(str, query_type);
88
  str->append(')');
89
}
90
91
92
int Item_default_value::save_in_field(Field *field_arg, bool no_conversions)
93
{
94
  if (!arg)
95
  {
96
    if (field_arg->flags & NO_DEFAULT_VALUE_FLAG)
97
    {
98
      if (field_arg->reset())
99
      {
100
        my_message(ER_CANT_CREATE_GEOMETRY_OBJECT,
101
                   ER(ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0));
102
        return -1;
103
      }
104
105
      {
106
        push_warning_printf(field_arg->table->in_use,
107
                            DRIZZLE_ERROR::WARN_LEVEL_WARN,
108
                            ER_NO_DEFAULT_FOR_FIELD,
109
                            ER(ER_NO_DEFAULT_FOR_FIELD),
110
                            field_arg->field_name);
111
      }
112
      return 1;
113
    }
114
    field_arg->set_default();
115
    return 0;
116
  }
117
  return Item_field::save_in_field(field_arg, no_conversions);
118
}
119
120
121
/**
122
  This method like the walk method traverses the item tree, but at the
123
  same time it can replace some nodes in the tree.
124
*/
125
126
Item *Item_default_value::transform(Item_transformer transformer, unsigned char *args)
127
{
128
  Item *new_item= arg->transform(transformer, args);
129
  if (!new_item)
130
    return NULL;
131
132
  /*
133
    Session::change_item_tree() should be called only if the tree was
134
    really transformed, i.e. when a new item has been created.
135
    Otherwise we'll be allocating a lot of unnecessary memory for
136
    change records at each execution.
137
  */
138
  if (arg != new_item)
139
    current_session->change_item_tree(&arg, new_item);
140
  return (this->*transformer)(args);
141
}