~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/**********************************************************************
2
Data dictionary memory object creation
3
4
(c) 1996 Innobase Oy
5
6
Created 1/8/1996 Heikki Tuuri
7
***********************************************************************/
8
9
#include "dict0mem.h"
10
11
#ifdef UNIV_NONINL
12
#include "dict0mem.ic"
13
#endif
14
15
#include "rem0rec.h"
16
#include "data0type.h"
17
#include "mach0data.h"
18
#include "dict0dict.h"
19
#include "que0que.h"
20
#include "pars0pars.h"
21
#include "lock0lock.h"
22
23
#define	DICT_HEAP_SIZE		100	/* initial memory heap size when
24
					creating a table or index object */
25
26
/**************************************************************************
27
Creates a table memory object. */
28
29
dict_table_t*
30
dict_mem_table_create(
31
/*==================*/
32
				/* out, own: table object */
33
	const char*	name,	/* in: table name */
34
	ulint		space,	/* in: space where the clustered index of
35
				the table is placed; this parameter is
36
				ignored if the table is made a member of
37
				a cluster */
38
	ulint		n_cols,	/* in: number of columns */
39
	ulint		flags)	/* in: table flags */
40
{
41
	dict_table_t*	table;
42
	mem_heap_t*	heap;
43
44
	ut_ad(name);
45
	ut_ad(!(flags & ~DICT_TF_COMPACT));
46
47
	heap = mem_heap_create(DICT_HEAP_SIZE);
48
49
	table = mem_heap_alloc(heap, sizeof(dict_table_t));
50
51
	table->heap = heap;
52
53
	table->flags = (unsigned int) flags;
54
	table->name = mem_heap_strdup(heap, name);
55
	table->dir_path_of_temp_table = NULL;
56
	table->space = (unsigned int) space;
57
	table->ibd_file_missing = FALSE;
58
	table->tablespace_discarded = FALSE;
59
	table->n_def = 0;
60
	table->n_cols = (unsigned int) (n_cols + DATA_N_SYS_COLS);
61
62
	table->n_mysql_handles_opened = 0;
63
	table->n_foreign_key_checks_running = 0;
64
65
	table->cached = FALSE;
66
67
	table->cols = mem_heap_alloc(heap, (n_cols + DATA_N_SYS_COLS)
68
				     * sizeof(dict_col_t));
69
	table->col_names = NULL;
70
	UT_LIST_INIT(table->indexes);
71
72
	table->auto_inc_lock = mem_heap_alloc(heap, lock_get_size());
73
74
	table->query_cache_inv_trx_id = ut_dulint_zero;
75
76
	UT_LIST_INIT(table->locks);
77
	UT_LIST_INIT(table->foreign_list);
78
	UT_LIST_INIT(table->referenced_list);
79
80
#ifdef UNIV_DEBUG
81
	table->does_not_fit_in_memory = FALSE;
82
#endif /* UNIV_DEBUG */
83
84
	table->stat_initialized = FALSE;
85
86
	table->stat_modified_counter = 0;
87
88
	table->big_rows = 0;
89
90
	mutex_create(&table->autoinc_mutex, SYNC_DICT_AUTOINC_MUTEX);
91
92
	table->autoinc_inited = FALSE;
93
94
	/* The actual increment value will be set by MySQL, we simply
95
	default to 1 here.*/
96
	table->autoinc_increment = 1;
97
98
	/* The number of transactions that are either waiting on the
99
	AUTOINC lock or have been granted the lock. */
100
	table->n_waiting_or_granted_auto_inc_locks = 0;
101
102
#ifdef UNIV_DEBUG
103
	table->magic_n = DICT_TABLE_MAGIC_N;
104
#endif /* UNIV_DEBUG */
105
	return(table);
106
}
107
108
/********************************************************************
109
Free a table memory object. */
110
111
void
112
dict_mem_table_free(
113
/*================*/
114
	dict_table_t*	table)		/* in: table */
115
{
116
	ut_ad(table);
117
	ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
118
119
	mutex_free(&(table->autoinc_mutex));
120
	mem_heap_free(table->heap);
121
}
122
123
/********************************************************************
124
Append 'name' to 'col_names' (@see dict_table_t::col_names). */
125
static
126
const char*
127
dict_add_col_name(
128
/*==============*/
129
					/* out: new column names array */
130
	const char*	col_names,	/* in: existing column names, or
131
					NULL */
132
	ulint		cols,		/* in: number of existing columns */
133
	const char*	name,		/* in: new column name */
134
	mem_heap_t*	heap)		/* in: heap */
135
{
136
	ulint	old_len;
137
	ulint	new_len;
138
	ulint	total_len;
139
	char*	res;
140
141
	ut_ad(!cols == !col_names);
142
143
	/* Find out length of existing array. */
144
	if (col_names) {
145
		const char*	s = col_names;
146
		ulint		i;
147
148
		for (i = 0; i < cols; i++) {
149
			s += strlen(s) + 1;
150
		}
151
152
		old_len = s - col_names;
153
	} else {
154
		old_len = 0;
155
	}
156
157
	new_len = strlen(name) + 1;
158
	total_len = old_len + new_len;
159
160
	res = mem_heap_alloc(heap, total_len);
161
162
	if (old_len > 0) {
163
		memcpy(res, col_names, old_len);
164
	}
165
166
	memcpy(res + old_len, name, new_len);
167
168
	return(res);
169
}
170
171
/**************************************************************************
172
Adds a column definition to a table. */
173
174
void
175
dict_mem_table_add_col(
176
/*===================*/
177
	dict_table_t*	table,	/* in: table */
178
	mem_heap_t*	heap,	/* in: temporary memory heap, or NULL */
179
	const char*	name,	/* in: column name, or NULL */
180
	ulint		mtype,	/* in: main datatype */
181
	ulint		prtype,	/* in: precise type */
182
	ulint		len)	/* in: precision */
183
{
184
	dict_col_t*	col;
185
	ulint		mbminlen;
186
	ulint		mbmaxlen;
187
	ulint		i;
188
189
	ut_ad(table);
190
	ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
191
	ut_ad(!heap == !name);
192
193
	i = table->n_def++;
194
195
	if (name) {
196
		if (UNIV_UNLIKELY(table->n_def == table->n_cols)) {
197
			heap = table->heap;
198
		}
199
		if (UNIV_LIKELY(i) && UNIV_UNLIKELY(!table->col_names)) {
200
			/* All preceding column names are empty. */
201
			char* s = mem_heap_alloc(heap, table->n_def);
202
			memset(s, 0, table->n_def);
203
			table->col_names = s;
204
		}
205
206
		table->col_names = dict_add_col_name(table->col_names,
207
						     i, name, heap);
208
	}
209
210
	col = (dict_col_t*) dict_table_get_nth_col(table, i);
211
212
	col->ind = (unsigned int) i;
213
	col->ord_part = 0;
214
215
	col->mtype = (unsigned int) mtype;
216
	col->prtype = (unsigned int) prtype;
217
	col->len = (unsigned int) len;
218
219
	dtype_get_mblen(mtype, prtype, &mbminlen, &mbmaxlen);
220
221
	col->mbminlen = (unsigned int) mbminlen;
222
	col->mbmaxlen = (unsigned int) mbmaxlen;
223
}
224
225
/**************************************************************************
226
Creates an index memory object. */
227
228
dict_index_t*
229
dict_mem_index_create(
230
/*==================*/
231
					/* out, own: index object */
232
	const char*	table_name,	/* in: table name */
233
	const char*	index_name,	/* in: index name */
234
	ulint		space,		/* in: space where the index tree is
235
					placed, ignored if the index is of
236
					the clustered type */
237
	ulint		type,		/* in: DICT_UNIQUE,
238
					DICT_CLUSTERED, ... ORed */
239
	ulint		n_fields)	/* in: number of fields */
240
{
241
	dict_index_t*	index;
242
	mem_heap_t*	heap;
243
244
	ut_ad(table_name && index_name);
245
246
	heap = mem_heap_create(DICT_HEAP_SIZE);
247
	index = mem_heap_alloc(heap, sizeof(dict_index_t));
248
249
	index->heap = heap;
250
251
	index->type = type;
252
	index->space = (unsigned int) space;
253
	index->page = 0;
254
	index->name = mem_heap_strdup(heap, index_name);
255
	index->table_name = table_name;
256
	index->table = NULL;
257
	index->n_def = index->n_nullable = 0;
258
	index->n_fields = (unsigned int) n_fields;
259
	index->fields = mem_heap_alloc(heap, 1 + n_fields
260
				       * sizeof(dict_field_t));
261
	/* The '1 +' above prevents allocation
262
	of an empty mem block */
263
	index->stat_n_diff_key_vals = NULL;
264
265
	index->cached = FALSE;
266
	memset(&index->lock, 0, sizeof index->lock);
267
#ifdef UNIV_DEBUG
268
	index->magic_n = DICT_INDEX_MAGIC_N;
269
#endif /* UNIV_DEBUG */
270
	return(index);
271
}
272
273
/**************************************************************************
274
Creates and initializes a foreign constraint memory object. */
275
276
dict_foreign_t*
277
dict_mem_foreign_create(void)
278
/*=========================*/
279
				/* out, own: foreign constraint struct */
280
{
281
	dict_foreign_t*	foreign;
282
	mem_heap_t*	heap;
283
284
	heap = mem_heap_create(100);
285
286
	foreign = mem_heap_alloc(heap, sizeof(dict_foreign_t));
287
288
	foreign->heap = heap;
289
290
	foreign->id = NULL;
291
292
	foreign->type = 0;
293
	foreign->foreign_table_name = NULL;
294
	foreign->foreign_table = NULL;
295
	foreign->foreign_col_names = NULL;
296
297
	foreign->referenced_table_name = NULL;
298
	foreign->referenced_table = NULL;
299
	foreign->referenced_col_names = NULL;
300
301
	foreign->n_fields = 0;
302
303
	foreign->foreign_index = NULL;
304
	foreign->referenced_index = NULL;
305
306
	return(foreign);
307
}
308
309
/**************************************************************************
310
Adds a field definition to an index. NOTE: does not take a copy
311
of the column name if the field is a column. The memory occupied
312
by the column name may be released only after publishing the index. */
313
314
void
315
dict_mem_index_add_field(
316
/*=====================*/
317
	dict_index_t*	index,		/* in: index */
318
	const char*	name,		/* in: column name */
319
	ulint		prefix_len)	/* in: 0 or the column prefix length
320
					in a MySQL index like
321
					INDEX (textcol(25)) */
322
{
323
	dict_field_t*	field;
324
325
	ut_ad(index);
326
	ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
327
328
	index->n_def++;
329
330
	field = dict_index_get_nth_field(index, index->n_def - 1);
331
332
	field->name = name;
333
	field->prefix_len = (unsigned int) prefix_len;
334
}
335
336
/**************************************************************************
337
Frees an index memory object. */
338
339
void
340
dict_mem_index_free(
341
/*================*/
342
	dict_index_t*	index)	/* in: index */
343
{
344
	ut_ad(index);
345
	ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
346
347
	mem_heap_free(index->heap);
348
}