~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/************************************************************************
2
SQL data field and tuple
3
4
(c) 1994-1996 Innobase Oy
5
6
Created 5/30/1994 Heikki Tuuri
7
*************************************************************************/
8
9
#include "mem0mem.h"
10
#include "ut0rnd.h"
11
12
#ifdef UNIV_DEBUG
13
extern byte data_error;
14
#endif /* UNIV_DEBUG */
15
16
/*************************************************************************
17
Gets pointer to the type struct of SQL data field. */
18
UNIV_INLINE
19
dtype_t*
20
dfield_get_type(
21
/*============*/
22
				/* out: pointer to the type struct */
23
	dfield_t*	field)	/* in: SQL data field */
24
{
25
	ut_ad(field);
26
27
	return(&(field->type));
28
}
29
30
/*************************************************************************
31
Sets the type struct of SQL data field. */
32
UNIV_INLINE
33
void
34
dfield_set_type(
35
/*============*/
36
	dfield_t*	field,	/* in: SQL data field */
37
	dtype_t*	type)	/* in: pointer to data type struct */
38
{
39
	ut_ad(field && type);
40
41
	field->type = *type;
42
}
43
44
/*************************************************************************
45
Gets pointer to the data in a field. */
46
UNIV_INLINE
47
void*
48
dfield_get_data(
49
/*============*/
50
				/* out: pointer to data */
51
	dfield_t* field)	/* in: field */
52
{
53
	ut_ad(field);
54
	ut_ad((field->len == UNIV_SQL_NULL)
55
	      || (field->data != &data_error));
56
57
	return(field->data);
58
}
59
60
/*************************************************************************
61
Gets length of field data. */
62
UNIV_INLINE
63
ulint
64
dfield_get_len(
65
/*===========*/
66
				/* out: length of data; UNIV_SQL_NULL if
67
				SQL null data */
68
	dfield_t* field)	/* in: field */
69
{
70
	ut_ad(field);
71
	ut_ad((field->len == UNIV_SQL_NULL)
72
	      || (field->data != &data_error));
73
74
	return(field->len);
75
}
76
77
/*************************************************************************
78
Sets length in a field. */
79
UNIV_INLINE
80
void
81
dfield_set_len(
82
/*===========*/
83
	dfield_t*	field,	/* in: field */
84
	ulint		len)	/* in: length or UNIV_SQL_NULL */
85
{
86
	ut_ad(field);
87
88
	field->len = len;
89
}
90
91
/*************************************************************************
92
Sets pointer to the data and length in a field. */
93
UNIV_INLINE
94
void
95
dfield_set_data(
96
/*============*/
97
	dfield_t*	field,	/* in: field */
98
	const void*	data,	/* in: data */
99
	ulint		len)	/* in: length or UNIV_SQL_NULL */
100
{
101
	ut_ad(field);
102
103
	field->data = (void*) data;
104
	field->len = len;
105
}
106
107
/*************************************************************************
108
Copies the data and len fields. */
109
UNIV_INLINE
110
void
111
dfield_copy_data(
112
/*=============*/
113
	dfield_t*	field1,	/* in: field to copy to */
114
	dfield_t*	field2)	/* in: field to copy from */
115
{
116
	ut_ad(field1 && field2);
117
118
	field1->data = field2->data;
119
	field1->len = field2->len;
120
}
121
122
/*************************************************************************
123
Copies a data field to another. */
124
UNIV_INLINE
125
void
126
dfield_copy(
127
/*========*/
128
	dfield_t*	field1,	/* in: field to copy to */
129
	dfield_t*	field2)	/* in: field to copy from */
130
{
131
	*field1 = *field2;
132
}
133
134
/*************************************************************************
135
Tests if data length and content is equal for two dfields. */
136
UNIV_INLINE
137
ibool
138
dfield_datas_are_binary_equal(
139
/*==========================*/
140
				/* out: TRUE if equal */
141
	dfield_t*	field1,	/* in: field */
142
	dfield_t*	field2)	/* in: field */
143
{
144
	ulint	len;
145
146
	len = field1->len;
147
148
	if ((len != field2->len)
149
	    || ((len != UNIV_SQL_NULL)
150
		&& (0 != ut_memcmp(field1->data, field2->data,
151
				   len)))) {
152
153
		return(FALSE);
154
	}
155
156
	return(TRUE);
157
}
158
159
/*************************************************************************
160
Gets info bits in a data tuple. */
161
UNIV_INLINE
162
ulint
163
dtuple_get_info_bits(
164
/*=================*/
165
				/* out: info bits */
166
	dtuple_t*	tuple)	/* in: tuple */
167
{
168
	ut_ad(tuple);
169
170
	return(tuple->info_bits);
171
}
172
173
/*************************************************************************
174
Sets info bits in a data tuple. */
175
UNIV_INLINE
176
void
177
dtuple_set_info_bits(
178
/*=================*/
179
	dtuple_t*	tuple,		/* in: tuple */
180
	ulint		info_bits)	/* in: info bits */
181
{
182
	ut_ad(tuple);
183
184
	tuple->info_bits = info_bits;
185
}
186
187
/*************************************************************************
188
Gets number of fields used in record comparisons. */
189
UNIV_INLINE
190
ulint
191
dtuple_get_n_fields_cmp(
192
/*====================*/
193
				/* out: number of fields used in comparisons
194
				in rem0cmp.* */
195
	dtuple_t*	tuple)	/* in: tuple */
196
{
197
	ut_ad(tuple);
198
199
	return(tuple->n_fields_cmp);
200
}
201
202
/*************************************************************************
203
Sets number of fields used in record comparisons. */
204
UNIV_INLINE
205
void
206
dtuple_set_n_fields_cmp(
207
/*====================*/
208
	dtuple_t*	tuple,		/* in: tuple */
209
	ulint		n_fields_cmp)	/* in: number of fields used in
210
					comparisons in rem0cmp.* */
211
{
212
	ut_ad(tuple);
213
	ut_ad(n_fields_cmp <= tuple->n_fields);
214
215
	tuple->n_fields_cmp = n_fields_cmp;
216
}
217
218
/*************************************************************************
219
Gets number of fields in a data tuple. */
220
UNIV_INLINE
221
ulint
222
dtuple_get_n_fields(
223
/*================*/
224
				/* out: number of fields */
225
	dtuple_t*	tuple)	/* in: tuple */
226
{
227
	ut_ad(tuple);
228
229
	return(tuple->n_fields);
230
}
231
232
/*************************************************************************
233
Gets nth field of a tuple. */
234
UNIV_INLINE
235
dfield_t*
236
dtuple_get_nth_field(
237
/*=================*/
238
				/* out: nth field */
239
	dtuple_t*	tuple,	/* in: tuple */
240
	ulint		n)	/* in: index of field */
241
{
242
	ut_ad(tuple);
243
	ut_ad(n < tuple->n_fields);
244
245
	return(tuple->fields + n);
246
}
247
248
/**************************************************************
249
Creates a data tuple to a memory heap. The default value for number
250
of fields used in record comparisons for this tuple is n_fields. */
251
UNIV_INLINE
252
dtuple_t*
253
dtuple_create(
254
/*==========*/
255
				/* out, own: created tuple */
256
	mem_heap_t*	heap,	/* in: memory heap where the tuple
257
				is created */
258
	ulint		n_fields) /* in: number of fields */
259
{
260
	dtuple_t*	tuple;
261
262
	ut_ad(heap);
263
264
	tuple = (dtuple_t*) mem_heap_alloc(heap, sizeof(dtuple_t)
265
					   + n_fields * sizeof(dfield_t));
266
	tuple->info_bits = 0;
267
	tuple->n_fields = n_fields;
268
	tuple->n_fields_cmp = n_fields;
269
	tuple->fields = (dfield_t*)(((byte*)tuple) + sizeof(dtuple_t));
270
271
#ifdef UNIV_DEBUG
272
	tuple->magic_n = DATA_TUPLE_MAGIC_N;
273
274
	{	/* In the debug version, initialize fields to an error value */
275
		ulint	i;
276
277
		for (i = 0; i < n_fields; i++) {
278
			(tuple->fields + i)->data = &data_error;
279
			dfield_get_type(tuple->fields + i)->mtype = DATA_ERROR;
280
		}
281
	}
282
#endif
283
	return(tuple);
284
}
285
286
/**************************************************************
287
The following function returns the sum of data lengths of a tuple. The space
288
occupied by the field structs or the tuple struct is not counted. Neither
289
is possible space in externally stored parts of the field. */
290
UNIV_INLINE
291
ulint
292
dtuple_get_data_size(
293
/*=================*/
294
				/* out: sum of data lengths */
295
	dtuple_t*	tuple)	/* in: typed data tuple */
296
{
297
	dfield_t*	field;
298
	ulint		n_fields;
299
	ulint		len;
300
	ulint		i;
301
	ulint		sum	= 0;
302
303
	ut_ad(tuple);
304
	ut_ad(dtuple_check_typed(tuple));
305
	ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
306
307
	n_fields = tuple->n_fields;
308
309
	for (i = 0; i < n_fields; i++) {
310
		field = dtuple_get_nth_field(tuple,  i);
311
		len = dfield_get_len(field);
312
313
		if (len == UNIV_SQL_NULL) {
314
			len = dtype_get_sql_null_size(dfield_get_type(field));
315
		}
316
317
		sum += len;
318
	}
319
320
	return(sum);
321
}
322
323
/***********************************************************************
324
Sets types of fields binary in a tuple. */
325
UNIV_INLINE
326
void
327
dtuple_set_types_binary(
328
/*====================*/
329
	dtuple_t*	tuple,	/* in: data tuple */
330
	ulint		n)	/* in: number of fields to set */
331
{
332
	dtype_t*	dfield_type;
333
	ulint		i;
334
335
	for (i = 0; i < n; i++) {
336
		dfield_type = dfield_get_type(dtuple_get_nth_field(tuple, i));
337
		dtype_set(dfield_type, DATA_BINARY, 0, 0);
338
	}
339
}
340
341
/****************************************************************
342
Folds a prefix given as the number of fields of a tuple. */
343
UNIV_INLINE
344
ulint
345
dtuple_fold(
346
/*========*/
347
				/* out: the folded value */
348
	dtuple_t*	tuple,	/* in: the tuple */
349
	ulint		n_fields,/* in: number of complete fields to fold */
350
	ulint		n_bytes,/* in: number of bytes to fold in an
351
				incomplete last field */
352
	dulint		tree_id)/* in: index tree id */
353
{
354
	dfield_t*	field;
355
	ulint		i;
356
	byte*		data;
357
	ulint		len;
358
	ulint		fold;
359
360
	ut_ad(tuple);
361
	ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
362
	ut_ad(dtuple_check_typed(tuple));
363
364
	fold = ut_fold_dulint(tree_id);
365
366
	for (i = 0; i < n_fields; i++) {
367
		field = dtuple_get_nth_field(tuple, i);
368
369
		data = (byte*) dfield_get_data(field);
370
		len = dfield_get_len(field);
371
372
		if (len != UNIV_SQL_NULL) {
373
			fold = ut_fold_ulint_pair(fold,
374
						  ut_fold_binary(data, len));
375
		}
376
	}
377
378
	if (n_bytes > 0) {
379
		field = dtuple_get_nth_field(tuple, i);
380
381
		data = (byte*) dfield_get_data(field);
382
		len = dfield_get_len(field);
383
384
		if (len != UNIV_SQL_NULL) {
385
			if (len > n_bytes) {
386
				len = n_bytes;
387
			}
388
389
			fold = ut_fold_ulint_pair(fold,
390
						  ut_fold_binary(data, len));
391
		}
392
	}
393
394
	return(fold);
395
}
396
397
/**************************************************************************
398
Writes an SQL null field full of zeros. */
399
UNIV_INLINE
400
void
401
data_write_sql_null(
402
/*================*/
403
	byte*	data,	/* in: pointer to a buffer of size len */
404
	ulint	len)	/* in: SQL null size in bytes */
405
{
406
	ulint	j;
407
408
	for (j = 0; j < len; j++) {
409
		data[j] = '\0';
410
	}
411
}
412
413
/**************************************************************************
414
Checks if a dtuple contains an SQL null value. */
415
UNIV_INLINE
416
ibool
417
dtuple_contains_null(
418
/*=================*/
419
				/* out: TRUE if some field is SQL null */
420
	dtuple_t*	tuple)	/* in: dtuple */
421
{
422
	ulint	n;
423
	ulint	i;
424
425
	n = dtuple_get_n_fields(tuple);
426
427
	for (i = 0; i < n; i++) {
428
		if (dfield_get_len(dtuple_get_nth_field(tuple, i))
429
		    == UNIV_SQL_NULL) {
430
431
			return(TRUE);
432
		}
433
	}
434
435
	return(FALSE);
436
}