~drizzle-trunk/drizzle/development

641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
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
15
/*************************************************************************
16
Gets pointer to the type struct of SQL data field. */
17
UNIV_INLINE
18
dtype_t*
19
dfield_get_type(
20
/*============*/
21
				/* out: pointer to the type struct */
22
	const dfield_t*	field)	/* in: SQL data field */
23
{
24
	ut_ad(field);
25
26
	return((dtype_t*) &(field->type));
27
}
28
#endif /* UNIV_DEBUG */
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
#ifdef UNIV_DEBUG
45
/*************************************************************************
46
Gets pointer to the data in a field. */
47
UNIV_INLINE
48
void*
49
dfield_get_data(
50
/*============*/
51
				/* out: pointer to data */
52
	const dfield_t* field)	/* in: field */
53
{
54
	ut_ad(field);
55
	ut_ad((field->len == UNIV_SQL_NULL)
56
	      || (field->data != &data_error));
57
58
	return((void*) field->data);
59
}
60
#endif /* UNIV_DEBUG */
61
62
/*************************************************************************
63
Gets length of field data. */
64
UNIV_INLINE
65
ulint
66
dfield_get_len(
67
/*===========*/
68
				/* out: length of data; UNIV_SQL_NULL if
69
				SQL null data */
70
	const dfield_t*	field)	/* in: field */
71
{
72
	ut_ad(field);
73
	ut_ad((field->len == UNIV_SQL_NULL)
74
	      || (field->data != &data_error));
75
76
	return(field->len);
77
}
78
79
/*************************************************************************
80
Sets length in a field. */
81
UNIV_INLINE
82
void
83
dfield_set_len(
84
/*===========*/
85
	dfield_t*	field,	/* in: field */
86
	ulint		len)	/* in: length or UNIV_SQL_NULL */
87
{
88
	ut_ad(field);
89
#ifdef UNIV_VALGRIND_DEBUG
90
	if (len != UNIV_SQL_NULL) UNIV_MEM_ASSERT_RW(field->data, len);
91
#endif /* UNIV_VALGRIND_DEBUG */
92
93
	field->ext = 0;
94
	field->len = len;
95
}
96
97
/*************************************************************************
98
Determines if a field is SQL NULL */
99
UNIV_INLINE
100
ulint
101
dfield_is_null(
102
/*===========*/
103
				/* out: nonzero if SQL null data */
104
	const dfield_t* field)	/* in: field */
105
{
106
	ut_ad(field);
107
108
	return(field->len == UNIV_SQL_NULL);
109
}
110
111
/*************************************************************************
112
Determines if a field is externally stored */
113
UNIV_INLINE
114
ulint
115
dfield_is_ext(
116
/*==========*/
117
				/* out: nonzero if externally stored */
118
	const dfield_t* field)	/* in: field */
119
{
120
	ut_ad(field);
121
122
	return(UNIV_UNLIKELY(field->ext));
123
}
124
125
/*************************************************************************
126
Sets the "external storage" flag */
127
UNIV_INLINE
128
void
129
dfield_set_ext(
130
/*===========*/
131
	dfield_t*	field)	/* in/out: field */
132
{
133
	ut_ad(field);
134
135
	field->ext = 1;
136
}
137
138
/*************************************************************************
139
Sets pointer to the data and length in a field. */
140
UNIV_INLINE
141
void
142
dfield_set_data(
143
/*============*/
144
	dfield_t*	field,	/* in: field */
145
	const void*	data,	/* in: data */
146
	ulint		len)	/* in: length or UNIV_SQL_NULL */
147
{
148
	ut_ad(field);
149
150
#ifdef UNIV_VALGRIND_DEBUG
151
	if (len != UNIV_SQL_NULL) UNIV_MEM_ASSERT_RW(data, len);
152
#endif /* UNIV_VALGRIND_DEBUG */
153
	field->data = (void*) data;
154
	field->ext = 0;
155
	field->len = len;
156
}
157
158
/*************************************************************************
159
Sets a data field to SQL NULL. */
160
UNIV_INLINE
161
void
162
dfield_set_null(
163
/*============*/
164
	dfield_t*	field)	/* in/out: field */
165
{
166
	dfield_set_data(field, NULL, UNIV_SQL_NULL);
167
}
168
169
/*************************************************************************
170
Copies the data and len fields. */
171
UNIV_INLINE
172
void
173
dfield_copy_data(
174
/*=============*/
175
	dfield_t*	field1,	/* out: field to copy to */
176
	const dfield_t*	field2)	/* in: field to copy from */
177
{
178
	ut_ad(field1 && field2);
179
180
	field1->data = field2->data;
181
	field1->len = field2->len;
182
	field1->ext = field2->ext;
183
}
184
185
/*************************************************************************
186
Copies a data field to another. */
187
UNIV_INLINE
188
void
189
dfield_copy(
190
/*========*/
191
	dfield_t*	field1,	/* out: field to copy to */
192
	const dfield_t*	field2)	/* in: field to copy from */
193
{
194
	*field1 = *field2;
195
}
196
197
/*************************************************************************
198
Copies the data pointed to by a data field. */
199
UNIV_INLINE
200
void
201
dfield_dup(
202
/*=======*/
203
	dfield_t*	field,	/* in/out: data field */
204
	mem_heap_t*	heap)	/* in: memory heap where allocated */
205
{
206
	if (!dfield_is_null(field)) {
207
		UNIV_MEM_ASSERT_RW(field->data, field->len);
208
		field->data = mem_heap_dup(heap, field->data, field->len);
209
	}
210
}
211
212
/*************************************************************************
213
Tests if data length and content is equal for two dfields. */
214
UNIV_INLINE
215
ibool
216
dfield_datas_are_binary_equal(
217
/*==========================*/
218
				/* out: TRUE if equal */
219
	const dfield_t*	field1,	/* in: field */
220
	const dfield_t*	field2)	/* in: field */
221
{
222
	ulint	len;
223
224
	len = field1->len;
225
226
	return(len == field2->len
227
	       && (len == UNIV_SQL_NULL
228
		   || !memcmp(field1->data, field2->data, len)));
229
}
230
231
/*************************************************************************
232
Gets info bits in a data tuple. */
233
UNIV_INLINE
234
ulint
235
dtuple_get_info_bits(
236
/*=================*/
237
				/* out: info bits */
238
	const dtuple_t*	tuple)	/* in: tuple */
239
{
240
	ut_ad(tuple);
241
242
	return(tuple->info_bits);
243
}
244
245
/*************************************************************************
246
Sets info bits in a data tuple. */
247
UNIV_INLINE
248
void
249
dtuple_set_info_bits(
250
/*=================*/
251
	dtuple_t*	tuple,		/* in: tuple */
252
	ulint		info_bits)	/* in: info bits */
253
{
254
	ut_ad(tuple);
255
256
	tuple->info_bits = info_bits;
257
}
258
259
/*************************************************************************
260
Gets number of fields used in record comparisons. */
261
UNIV_INLINE
262
ulint
263
dtuple_get_n_fields_cmp(
264
/*====================*/
265
				/* out: number of fields used in comparisons
266
				in rem0cmp.* */
267
	const dtuple_t*	tuple)	/* in: tuple */
268
{
269
	ut_ad(tuple);
270
271
	return(tuple->n_fields_cmp);
272
}
273
274
/*************************************************************************
275
Sets number of fields used in record comparisons. */
276
UNIV_INLINE
277
void
278
dtuple_set_n_fields_cmp(
279
/*====================*/
280
	dtuple_t*	tuple,		/* in: tuple */
281
	ulint		n_fields_cmp)	/* in: number of fields used in
282
					comparisons in rem0cmp.* */
283
{
284
	ut_ad(tuple);
285
	ut_ad(n_fields_cmp <= tuple->n_fields);
286
287
	tuple->n_fields_cmp = n_fields_cmp;
288
}
289
290
/*************************************************************************
291
Gets number of fields in a data tuple. */
292
UNIV_INLINE
293
ulint
294
dtuple_get_n_fields(
295
/*================*/
296
				/* out: number of fields */
297
	const dtuple_t*	tuple)	/* in: tuple */
298
{
299
	ut_ad(tuple);
300
301
	return(tuple->n_fields);
302
}
303
304
#ifdef UNIV_DEBUG
305
/*************************************************************************
306
Gets nth field of a tuple. */
307
UNIV_INLINE
308
dfield_t*
309
dtuple_get_nth_field(
310
/*=================*/
311
				/* out: nth field */
312
	const dtuple_t*	tuple,	/* in: tuple */
313
	ulint		n)	/* in: index of field */
314
{
315
	ut_ad(tuple);
316
	ut_ad(n < tuple->n_fields);
317
318
	return((dfield_t*) tuple->fields + n);
319
}
320
#endif /* UNIV_DEBUG */
321
322
/**************************************************************
323
Creates a data tuple to a memory heap. The default value for number
324
of fields used in record comparisons for this tuple is n_fields. */
325
UNIV_INLINE
326
dtuple_t*
327
dtuple_create(
328
/*==========*/
329
				/* out, own: created tuple */
330
	mem_heap_t*	heap,	/* in: memory heap where the tuple
331
				is created */
332
	ulint		n_fields) /* in: number of fields */
333
{
334
	dtuple_t*	tuple;
335
336
	ut_ad(heap);
337
338
	tuple = (dtuple_t*) mem_heap_alloc(heap, sizeof(dtuple_t)
339
					   + n_fields * sizeof(dfield_t));
340
	tuple->info_bits = 0;
341
	tuple->n_fields = n_fields;
342
	tuple->n_fields_cmp = n_fields;
343
	tuple->fields = (dfield_t*) &tuple[1];
344
345
#ifdef UNIV_DEBUG
346
	tuple->magic_n = DATA_TUPLE_MAGIC_N;
347
348
	{	/* In the debug version, initialize fields to an error value */
349
		ulint	i;
350
351
		for (i = 0; i < n_fields; i++) {
352
			dfield_t*       field;
353
354
			field = dtuple_get_nth_field(tuple, i);
355
356
			dfield_set_len(field, UNIV_SQL_NULL);
357
			field->data = &data_error;
358
			dfield_get_type(field)->mtype = DATA_ERROR;
359
		}
360
	}
361
362
	UNIV_MEM_INVALID(tuple->fields, n_fields * sizeof *tuple->fields);
363
#endif
364
	return(tuple);
365
}
366
367
/**************************************************************
368
Wrap data fields in a tuple. The default value for number
369
of fields used in record comparisons for this tuple is n_fields. */
370
UNIV_INLINE
371
const dtuple_t*
372
dtuple_from_fields(
373
/*===============*/
374
					/* out: data tuple */
375
	dtuple_t*	tuple,		/* in: storage for data tuple */
376
	const dfield_t*	fields,		/* in: fields */
377
	ulint		n_fields)	/* in: number of fields */
378
{
379
	tuple->info_bits = 0;
380
	tuple->n_fields = tuple->n_fields_cmp = n_fields;
381
	tuple->fields = (dfield_t*) fields;
382
	ut_d(tuple->magic_n = DATA_TUPLE_MAGIC_N);
383
384
	return(tuple);
385
}
386
387
/*************************************************************************
388
Copies a data tuple to another.  This is a shallow copy; if a deep copy
389
is desired, dfield_dup() will have to be invoked on each field. */
390
UNIV_INLINE
391
dtuple_t*
392
dtuple_copy(
393
/*========*/
394
				/* out, own: copy of tuple */
395
	const dtuple_t*	tuple,	/* in: tuple to copy from */
396
	mem_heap_t*	heap)	/* in: memory heap
397
				where the tuple is created */
398
{
399
	ulint		n_fields	= dtuple_get_n_fields(tuple);
400
	dtuple_t*	new_tuple	= dtuple_create(heap, n_fields);
401
	ulint		i;
402
403
	for (i = 0; i < n_fields; i++) {
404
		dfield_copy(dtuple_get_nth_field(new_tuple, i),
405
			    dtuple_get_nth_field(tuple, i));
406
	}
407
408
	return(new_tuple);
409
}
410
411
/**************************************************************
412
The following function returns the sum of data lengths of a tuple. The space
413
occupied by the field structs or the tuple struct is not counted. Neither
414
is possible space in externally stored parts of the field. */
415
UNIV_INLINE
416
ulint
417
dtuple_get_data_size(
418
/*=================*/
419
				/* out: sum of data lengths */
420
	const dtuple_t*	tuple)	/* in: typed data tuple */
421
{
422
	const dfield_t*	field;
423
	ulint		n_fields;
424
	ulint		len;
425
	ulint		i;
426
	ulint		sum	= 0;
427
428
	ut_ad(tuple);
429
	ut_ad(dtuple_check_typed(tuple));
430
	ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
431
432
	n_fields = tuple->n_fields;
433
434
	for (i = 0; i < n_fields; i++) {
435
		field = dtuple_get_nth_field(tuple,  i);
436
		len = dfield_get_len(field);
437
438
		if (len == UNIV_SQL_NULL) {
439
			len = dtype_get_sql_null_size(dfield_get_type(field));
440
		}
441
442
		sum += len;
443
	}
444
445
	return(sum);
446
}
447
448
/*************************************************************************
449
Computes the number of externally stored fields in a data tuple. */
450
UNIV_INLINE
451
ulint
452
dtuple_get_n_ext(
453
/*=============*/
454
				/* out: number of externally stored fields */
455
	const dtuple_t*	tuple)	/* in: tuple */
456
{
457
	ulint	n_ext		= 0;
458
	ulint	n_fields	= tuple->n_fields;
459
	ulint	i;
460
461
	ut_ad(tuple);
462
	ut_ad(dtuple_check_typed(tuple));
463
	ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
464
465
	for (i = 0; i < n_fields; i++) {
466
		n_ext += dtuple_get_nth_field(tuple, i)->ext;
467
	}
468
469
	return(n_ext);
470
}
471
472
/***********************************************************************
473
Sets types of fields binary in a tuple. */
474
UNIV_INLINE
475
void
476
dtuple_set_types_binary(
477
/*====================*/
478
	dtuple_t*	tuple,	/* in: data tuple */
479
	ulint		n)	/* in: number of fields to set */
480
{
481
	dtype_t*	dfield_type;
482
	ulint		i;
483
484
	for (i = 0; i < n; i++) {
485
		dfield_type = dfield_get_type(dtuple_get_nth_field(tuple, i));
486
		dtype_set(dfield_type, DATA_BINARY, 0, 0);
487
	}
488
}
489
490
/****************************************************************
491
Folds a prefix given as the number of fields of a tuple. */
492
UNIV_INLINE
493
ulint
494
dtuple_fold(
495
/*========*/
496
				/* out: the folded value */
497
	const dtuple_t*	tuple,	/* in: the tuple */
498
	ulint		n_fields,/* in: number of complete fields to fold */
499
	ulint		n_bytes,/* in: number of bytes to fold in an
500
				incomplete last field */
501
	dulint		tree_id)/* in: index tree id */
502
{
503
	const dfield_t*	field;
504
	ulint		i;
505
	const byte*	data;
506
	ulint		len;
507
	ulint		fold;
508
509
	ut_ad(tuple);
510
	ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N);
511
	ut_ad(dtuple_check_typed(tuple));
512
513
	fold = ut_fold_dulint(tree_id);
514
515
	for (i = 0; i < n_fields; i++) {
516
		field = dtuple_get_nth_field(tuple, i);
517
518
		data = (const byte*) dfield_get_data(field);
519
		len = dfield_get_len(field);
520
521
		if (len != UNIV_SQL_NULL) {
522
			fold = ut_fold_ulint_pair(fold,
523
						  ut_fold_binary(data, len));
524
		}
525
	}
526
527
	if (n_bytes > 0) {
528
		field = dtuple_get_nth_field(tuple, i);
529
530
		data = (const byte*) dfield_get_data(field);
531
		len = dfield_get_len(field);
532
533
		if (len != UNIV_SQL_NULL) {
534
			if (len > n_bytes) {
535
				len = n_bytes;
536
			}
537
538
			fold = ut_fold_ulint_pair(fold,
539
						  ut_fold_binary(data, len));
540
		}
541
	}
542
543
	return(fold);
544
}
545
546
/**************************************************************************
547
Writes an SQL null field full of zeros. */
548
UNIV_INLINE
549
void
550
data_write_sql_null(
551
/*================*/
552
	byte*	data,	/* in: pointer to a buffer of size len */
553
	ulint	len)	/* in: SQL null size in bytes */
554
{
555
	memset(data, 0, len);
556
}
557
558
/**************************************************************************
559
Checks if a dtuple contains an SQL null value. */
560
UNIV_INLINE
561
ibool
562
dtuple_contains_null(
563
/*=================*/
564
				/* out: TRUE if some field is SQL null */
565
	const dtuple_t*	tuple)	/* in: dtuple */
566
{
567
	ulint	n;
568
	ulint	i;
569
570
	n = dtuple_get_n_fields(tuple);
571
572
	for (i = 0; i < n; i++) {
573
		if (dfield_is_null(dtuple_get_nth_field(tuple, i))) {
574
575
			return(TRUE);
576
		}
577
	}
578
579
	return(FALSE);
580
}
581
582
/******************************************************************
583
Frees the memory in a big rec vector. */
584
UNIV_INLINE
585
void
586
dtuple_big_rec_free(
587
/*================*/
588
	big_rec_t*	vector)	/* in, own: big rec vector; it is
589
				freed in this function */
590
{
591
	mem_heap_free(vector->heap);
592
}