~ubuntu-branches/ubuntu/lucid/mysql-dfsg-5.1/lucid-security

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