~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.cc

  • Committer: Jay Pipes
  • Date: 2009-03-19 23:04:21 UTC
  • mto: This revision was merged to the branch mainline in revision 957.
  • Revision ID: jpipes@serialcoder-20090319230421-x7yfjzfy34aon7uj
Move Foreign_key implementation into its own implementation file and out of session.cc

Show diffs side-by-side

added added

removed removed

Lines of Context:
46
46
extern pthread_key_t THR_Session;
47
47
extern pthread_key_t THR_Mem_root;
48
48
 
49
 
 
50
49
/*****************************************************************************
51
50
** Instansiate templates
52
51
*****************************************************************************/
63
62
template class List_iterator<Alter_column>;
64
63
#endif
65
64
 
66
 
 
67
65
/****************************************************************************
68
66
** User variables
69
67
****************************************************************************/
70
 
 
71
68
extern "C" unsigned char *get_var_key(user_var_entry *entry, size_t *length,
72
69
                              bool )
73
70
{
96
93
  If out of memory, a partial copy is returned and an error is set
97
94
  in Session.
98
95
*/
99
 
 
100
96
Key::Key(const Key &rhs, MEM_ROOT *mem_root)
101
97
  :type(rhs.type),
102
98
  key_create_info(rhs.key_create_info),
107
103
  list_copy_and_replace_each_value(columns, mem_root);
108
104
}
109
105
 
110
 
/**
111
 
  Construct an (almost) deep copy of this foreign key. Only those
112
 
  elements that are known to never change are not copied.
113
 
  If out of memory, a partial copy is returned and an error is set
114
 
  in Session.
115
 
*/
116
 
 
117
 
Foreign_key::Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root)
118
 
  :Key(rhs),
119
 
  ref_table(rhs.ref_table),
120
 
  ref_columns(rhs.ref_columns),
121
 
  delete_opt(rhs.delete_opt),
122
 
  update_opt(rhs.update_opt),
123
 
  match_opt(rhs.match_opt)
124
 
{
125
 
  list_copy_and_replace_each_value(ref_columns, mem_root);
126
 
}
127
 
 
128
 
/*
129
 
  Test if a foreign key (= generated key) is a prefix of the given key
130
 
  (ignoring key name, key type and order of columns)
131
 
 
132
 
  NOTES:
133
 
    This is only used to test if an index for a FOREIGN KEY exists
134
 
 
135
 
  IMPLEMENTATION
136
 
    We only compare field names
137
 
 
138
 
  RETURN
139
 
    0   Generated key is a prefix of other key
140
 
    1   Not equal
141
 
*/
142
 
 
143
 
bool foreign_key_prefix(Key *a, Key *b)
144
 
{
145
 
  /* Ensure that 'a' is the generated key */
146
 
  if (a->generated)
147
 
  {
148
 
    if (b->generated && a->columns.elements > b->columns.elements)
149
 
      std::swap(a, b);                       // Put shorter key in 'a'
150
 
  }
151
 
  else
152
 
  {
153
 
    if (!b->generated)
154
 
      return true;                              // No foreign key
155
 
    std::swap(a, b);                       // Put generated key in 'a'
156
 
  }
157
 
 
158
 
  /* Test if 'a' is a prefix of 'b' */
159
 
  if (a->columns.elements > b->columns.elements)
160
 
    return true;                                // Can't be prefix
161
 
 
162
 
  List_iterator<Key_part_spec> col_it1(a->columns);
163
 
  List_iterator<Key_part_spec> col_it2(b->columns);
164
 
  const Key_part_spec *col1, *col2;
165
 
 
166
 
#ifdef ENABLE_WHEN_INNODB_CAN_HANDLE_SWAPED_FOREIGN_KEY_COLUMNS
167
 
  while ((col1= col_it1++))
168
 
  {
169
 
    bool found= 0;
170
 
    col_it2.rewind();
171
 
    while ((col2= col_it2++))
172
 
    {
173
 
      if (*col1 == *col2)
174
 
      {
175
 
        found= true;
176
 
        break;
177
 
      }
178
 
    }
179
 
    if (!found)
180
 
      return true;                              // Error
181
 
  }
182
 
  return false;                                 // Is prefix
183
 
#else
184
 
  while ((col1= col_it1++))
185
 
  {
186
 
    col2= col_it2++;
187
 
    if (!(*col1 == *col2))
188
 
      return true;
189
 
  }
190
 
  return false;                                 // Is prefix
191
 
#endif
192
 
}
193
 
 
194
 
 
195
 
/*
196
 
  Check if the foreign key options are compatible with columns
197
 
  on which the FK is created.
198
 
 
199
 
  RETURN
200
 
    0   Key valid
201
 
    1   Key invalid
202
 
*/
203
 
bool Foreign_key::validate(List<Create_field> &table_fields)
204
 
{
205
 
  Create_field  *sql_field;
206
 
  Key_part_spec *column;
207
 
  List_iterator<Key_part_spec> cols(columns);
208
 
  List_iterator<Create_field> it(table_fields);
209
 
  while ((column= cols++))
210
 
  {
211
 
    it.rewind();
212
 
    while ((sql_field= it++) &&
213
 
           my_strcasecmp(system_charset_info,
214
 
                         column->field_name.str,
215
 
                         sql_field->field_name)) {}
216
 
    if (!sql_field)
217
 
    {
218
 
      my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
219
 
      return true;
220
 
    }
221
 
    if (type == Key::FOREIGN_KEY && sql_field->vcol_info)
222
 
    {
223
 
      if (delete_opt == FK_OPTION_SET_NULL)
224
 
      {
225
 
        my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0),
226
 
                 "ON DELETE SET NULL");
227
 
        return true;
228
 
      }
229
 
      if (update_opt == FK_OPTION_SET_NULL)
230
 
      {
231
 
        my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0),
232
 
                 "ON UPDATE SET NULL");
233
 
        return true;
234
 
      }
235
 
      if (update_opt == FK_OPTION_CASCADE)
236
 
      {
237
 
        my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0),
238
 
                 "ON UPDATE CASCADE");
239
 
        return true;
240
 
      }
241
 
    }
242
 
  }
243
 
  return false;
244
 
}
245
 
 
246
 
 
247
106
/****************************************************************************
248
107
** Thread specific functions
249
108
****************************************************************************/