1/*****************************************************************************
2
3Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
4Copyright (c) 2017, MariaDB Corporation.
5
6This program is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free Software
8Foundation; version 2 of the License.
9
10This program is distributed in the hope that it will be useful, but WITHOUT
11ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License along with
15this program; if not, write to the Free Software Foundation, Inc.,
1651 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
17
18*****************************************************************************/
19
20/********************************************************************//**
21@file include/data0data.h
22SQL data field and tuple
23
24Created 5/30/1994 Heikki Tuuri
25*************************************************************************/
26
27#ifndef data0data_h
28#define data0data_h
29
30#include "univ.i"
31
32#include "data0types.h"
33#include "data0type.h"
34#include "mem0mem.h"
35#include "dict0types.h"
36
37#include <ostream>
38
39/** Storage for overflow data in a big record, that is, a clustered
40index record which needs external storage of data fields */
41struct big_rec_t;
42struct upd_t;
43
44#ifdef UNIV_DEBUG
45/*********************************************************************//**
46Gets pointer to the type struct of SQL data field.
47@return pointer to the type struct */
48UNIV_INLINE
49dtype_t*
50dfield_get_type(
51/*============*/
52 const dfield_t* field) /*!< in: SQL data field */
53 MY_ATTRIBUTE((nonnull, warn_unused_result));
54/*********************************************************************//**
55Gets pointer to the data in a field.
56@return pointer to data */
57UNIV_INLINE
58void*
59dfield_get_data(
60/*============*/
61 const dfield_t* field) /*!< in: field */
62 MY_ATTRIBUTE((nonnull, warn_unused_result));
63#else /* UNIV_DEBUG */
64# define dfield_get_type(field) (&(field)->type)
65# define dfield_get_data(field) ((field)->data)
66#endif /* UNIV_DEBUG */
67/*********************************************************************//**
68Sets the type struct of SQL data field. */
69UNIV_INLINE
70void
71dfield_set_type(
72/*============*/
73 dfield_t* field, /*!< in: SQL data field */
74 const dtype_t* type); /*!< in: pointer to data type struct */
75
76/*********************************************************************//**
77Gets length of field data.
78@return length of data; UNIV_SQL_NULL if SQL null data */
79UNIV_INLINE
80ulint
81dfield_get_len(
82/*===========*/
83 const dfield_t* field) /*!< in: field */
84 MY_ATTRIBUTE((nonnull, warn_unused_result));
85/*********************************************************************//**
86Sets length in a field. */
87UNIV_INLINE
88void
89dfield_set_len(
90/*===========*/
91 dfield_t* field, /*!< in: field */
92 ulint len) /*!< in: length or UNIV_SQL_NULL */
93 MY_ATTRIBUTE((nonnull));
94/*********************************************************************//**
95Determines if a field is SQL NULL
96@return nonzero if SQL null data */
97UNIV_INLINE
98ulint
99dfield_is_null(
100/*===========*/
101 const dfield_t* field) /*!< in: field */
102 MY_ATTRIBUTE((nonnull, warn_unused_result));
103/*********************************************************************//**
104Determines if a field is externally stored
105@return nonzero if externally stored */
106UNIV_INLINE
107ulint
108dfield_is_ext(
109/*==========*/
110 const dfield_t* field) /*!< in: field */
111 MY_ATTRIBUTE((nonnull, warn_unused_result));
112/*********************************************************************//**
113Sets the "external storage" flag */
114UNIV_INLINE
115void
116dfield_set_ext(
117/*===========*/
118 dfield_t* field) /*!< in/out: field */
119 MY_ATTRIBUTE((nonnull));
120
121/** Gets spatial status for "external storage"
122@param[in,out] field field */
123UNIV_INLINE
124spatial_status_t
125dfield_get_spatial_status(
126 const dfield_t* field);
127
128/** Sets spatial status for "external storage"
129@param[in,out] field field
130@param[in] spatial_status spatial status */
131UNIV_INLINE
132void
133dfield_set_spatial_status(
134 dfield_t* field,
135 spatial_status_t spatial_status);
136
137/*********************************************************************//**
138Sets pointer to the data and length in a field. */
139UNIV_INLINE
140void
141dfield_set_data(
142/*============*/
143 dfield_t* field, /*!< in: field */
144 const void* data, /*!< in: data */
145 ulint len) /*!< in: length or UNIV_SQL_NULL */
146 MY_ATTRIBUTE((nonnull(1)));
147/*********************************************************************//**
148Sets pointer to the data and length in a field. */
149UNIV_INLINE
150void
151dfield_write_mbr(
152/*=============*/
153 dfield_t* field, /*!< in: field */
154 const double* mbr) /*!< in: data */
155 MY_ATTRIBUTE((nonnull(1)));
156/*********************************************************************//**
157Sets a data field to SQL NULL. */
158UNIV_INLINE
159void
160dfield_set_null(
161/*============*/
162 dfield_t* field) /*!< in/out: field */
163 MY_ATTRIBUTE((nonnull));
164/**********************************************************************//**
165Writes an SQL null field full of zeros. */
166UNIV_INLINE
167void
168data_write_sql_null(
169/*================*/
170 byte* data, /*!< in: pointer to a buffer of size len */
171 ulint len) /*!< in: SQL null size in bytes */
172 MY_ATTRIBUTE((nonnull));
173/*********************************************************************//**
174Copies the data and len fields. */
175UNIV_INLINE
176void
177dfield_copy_data(
178/*=============*/
179 dfield_t* field1, /*!< out: field to copy to */
180 const dfield_t* field2); /*!< in: field to copy from */
181
182/*********************************************************************//**
183Copies a data field to another. */
184UNIV_INLINE
185void
186dfield_copy(
187/*========*/
188 dfield_t* field1, /*!< out: field to copy to */
189 const dfield_t* field2) /*!< in: field to copy from */
190 MY_ATTRIBUTE((nonnull));
191/*********************************************************************//**
192Copies the data pointed to by a data field. */
193UNIV_INLINE
194void
195dfield_dup(
196/*=======*/
197 dfield_t* field, /*!< in/out: data field */
198 mem_heap_t* heap) /*!< in: memory heap where allocated */
199 MY_ATTRIBUTE((nonnull));
200
201/*********************************************************************//**
202Tests if two data fields are equal.
203If len==0, tests the data length and content for equality.
204If len>0, tests the first len bytes of the content for equality.
205@return TRUE if both fields are NULL or if they are equal */
206UNIV_INLINE
207ibool
208dfield_datas_are_binary_equal(
209/*==========================*/
210 const dfield_t* field1, /*!< in: field */
211 const dfield_t* field2, /*!< in: field */
212 ulint len) /*!< in: maximum prefix to compare,
213 or 0 to compare the whole field length */
214 MY_ATTRIBUTE((nonnull, warn_unused_result));
215/*********************************************************************//**
216Tests if dfield data length and content is equal to the given.
217@return TRUE if equal */
218UNIV_INLINE
219ibool
220dfield_data_is_binary_equal(
221/*========================*/
222 const dfield_t* field, /*!< in: field */
223 ulint len, /*!< in: data length or UNIV_SQL_NULL */
224 const byte* data) /*!< in: data */
225 MY_ATTRIBUTE((nonnull, warn_unused_result));
226/*********************************************************************//**
227Gets number of fields in a data tuple.
228@return number of fields */
229UNIV_INLINE
230ulint
231dtuple_get_n_fields(
232/*================*/
233 const dtuple_t* tuple) /*!< in: tuple */
234 MY_ATTRIBUTE((nonnull, warn_unused_result));
235/** Gets number of virtual fields in a data tuple.
236@param[in] tuple dtuple to check
237@return number of fields */
238UNIV_INLINE
239ulint
240dtuple_get_n_v_fields(
241 const dtuple_t* tuple);
242
243#ifdef UNIV_DEBUG
244/** Gets nth field of a tuple.
245@param[in] tuple tuple
246@param[in] n index of field
247@return nth field */
248UNIV_INLINE
249dfield_t*
250dtuple_get_nth_field(
251 const dtuple_t* tuple,
252 ulint n);
253/** Gets nth virtual field of a tuple.
254@param[in] tuple tuple
255@oaran[in] n the nth field to get
256@return nth field */
257UNIV_INLINE
258dfield_t*
259dtuple_get_nth_v_field(
260 const dtuple_t* tuple,
261 ulint n);
262#else /* UNIV_DEBUG */
263# define dtuple_get_nth_field(tuple, n) ((tuple)->fields + (n))
264# define dtuple_get_nth_v_field(tuple, n) ((tuple)->fields + (tuple)->n_fields + (n))
265#endif /* UNIV_DEBUG */
266/*********************************************************************//**
267Gets info bits in a data tuple.
268@return info bits */
269UNIV_INLINE
270ulint
271dtuple_get_info_bits(
272/*=================*/
273 const dtuple_t* tuple) /*!< in: tuple */
274 MY_ATTRIBUTE((nonnull, warn_unused_result));
275/*********************************************************************//**
276Sets info bits in a data tuple. */
277UNIV_INLINE
278void
279dtuple_set_info_bits(
280/*=================*/
281 dtuple_t* tuple, /*!< in: tuple */
282 ulint info_bits) /*!< in: info bits */
283 MY_ATTRIBUTE((nonnull));
284/*********************************************************************//**
285Gets number of fields used in record comparisons.
286@return number of fields used in comparisons in rem0cmp.* */
287UNIV_INLINE
288ulint
289dtuple_get_n_fields_cmp(
290/*====================*/
291 const dtuple_t* tuple) /*!< in: tuple */
292 MY_ATTRIBUTE((nonnull, warn_unused_result));
293/*********************************************************************//**
294Gets number of fields used in record comparisons. */
295UNIV_INLINE
296void
297dtuple_set_n_fields_cmp(
298/*====================*/
299 dtuple_t* tuple, /*!< in: tuple */
300 ulint n_fields_cmp) /*!< in: number of fields used in
301 comparisons in rem0cmp.* */
302 MY_ATTRIBUTE((nonnull));
303
304/* Estimate the number of bytes that are going to be allocated when
305creating a new dtuple_t object */
306#define DTUPLE_EST_ALLOC(n_fields) \
307 (sizeof(dtuple_t) + (n_fields) * sizeof(dfield_t))
308
309/** Creates a data tuple from an already allocated chunk of memory.
310The size of the chunk must be at least DTUPLE_EST_ALLOC(n_fields).
311The default value for number of fields used in record comparisons
312for this tuple is n_fields.
313@param[in,out] buf buffer to use
314@param[in] buf_size buffer size
315@param[in] n_fields number of field
316@param[in] n_v_fields number of fields on virtual columns
317@return created tuple (inside buf) */
318UNIV_INLINE
319dtuple_t*
320dtuple_create_from_mem(
321 void* buf,
322 ulint buf_size,
323 ulint n_fields,
324 ulint n_v_fields)
325 MY_ATTRIBUTE((nonnull, warn_unused_result));
326
327/**********************************************************//**
328Creates a data tuple to a memory heap. The default value for number
329of fields used in record comparisons for this tuple is n_fields.
330@return own: created tuple */
331UNIV_INLINE
332dtuple_t*
333dtuple_create(
334/*==========*/
335 mem_heap_t* heap, /*!< in: memory heap where the tuple
336 is created, DTUPLE_EST_ALLOC(n_fields)
337 bytes will be allocated from this heap */
338 ulint n_fields)/*!< in: number of fields */
339 MY_ATTRIBUTE((nonnull, malloc));
340
341/** Initialize the virtual field data in a dtuple_t
342@param[in,out] vrow dtuple contains the virtual fields */
343UNIV_INLINE
344void
345dtuple_init_v_fld(
346 const dtuple_t* vrow);
347
348/** Duplicate the virtual field data in a dtuple_t
349@param[in,out] vrow dtuple contains the virtual fields
350@param[in] heap heap memory to use */
351UNIV_INLINE
352void
353dtuple_dup_v_fld(
354 const dtuple_t* vrow,
355 mem_heap_t* heap);
356
357/** Creates a data tuple with possible virtual columns to a memory heap.
358@param[in] heap memory heap where the tuple is created
359@param[in] n_fields number of fields
360@param[in] n_v_fields number of fields on virtual col
361@return own: created tuple */
362UNIV_INLINE
363dtuple_t*
364dtuple_create_with_vcol(
365 mem_heap_t* heap,
366 ulint n_fields,
367 ulint n_v_fields);
368
369/*********************************************************************//**
370Sets number of fields used in a tuple. Normally this is set in
371dtuple_create, but if you want later to set it smaller, you can use this. */
372void
373dtuple_set_n_fields(
374/*================*/
375 dtuple_t* tuple, /*!< in: tuple */
376 ulint n_fields) /*!< in: number of fields */
377 MY_ATTRIBUTE((nonnull));
378/** Copies a data tuple's virtaul fields to another. This is a shallow copy;
379@param[in,out] d_tuple destination tuple
380@param[in] s_tuple source tuple */
381UNIV_INLINE
382void
383dtuple_copy_v_fields(
384 dtuple_t* d_tuple,
385 const dtuple_t* s_tuple);
386/*********************************************************************//**
387Copies a data tuple to another. This is a shallow copy; if a deep copy
388is desired, dfield_dup() will have to be invoked on each field.
389@return own: copy of tuple */
390UNIV_INLINE
391dtuple_t*
392dtuple_copy(
393/*========*/
394 const dtuple_t* tuple, /*!< in: tuple to copy from */
395 mem_heap_t* heap) /*!< in: memory heap
396 where the tuple is created */
397 MY_ATTRIBUTE((nonnull, malloc));
398/**********************************************************//**
399The following function returns the sum of data lengths of a tuple. The space
400occupied by the field structs or the tuple struct is not counted.
401@return sum of data lens */
402UNIV_INLINE
403ulint
404dtuple_get_data_size(
405/*=================*/
406 const dtuple_t* tuple, /*!< in: typed data tuple */
407 ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
408 MY_ATTRIBUTE((nonnull));
409/*********************************************************************//**
410Computes the number of externally stored fields in a data tuple.
411@return number of fields */
412UNIV_INLINE
413ulint
414dtuple_get_n_ext(
415/*=============*/
416 const dtuple_t* tuple) /*!< in: tuple */
417 MY_ATTRIBUTE((nonnull));
418/** Compare two data tuples.
419@param[in] tuple1 first data tuple
420@param[in] tuple2 second data tuple
421@return positive, 0, negative if tuple1 is greater, equal, less, than tuple2,
422respectively */
423int
424dtuple_coll_cmp(
425 const dtuple_t* tuple1,
426 const dtuple_t* tuple2)
427 MY_ATTRIBUTE((warn_unused_result));
428/** Fold a prefix given as the number of fields of a tuple.
429@param[in] tuple index record
430@param[in] n_fields number of complete fields to fold
431@param[in] n_bytes number of bytes to fold in the last field
432@param[in] index_id index tree ID
433@return the folded value */
434UNIV_INLINE
435ulint
436dtuple_fold(
437 const dtuple_t* tuple,
438 ulint n_fields,
439 ulint n_bytes,
440 index_id_t tree_id)
441 MY_ATTRIBUTE((warn_unused_result));
442/*******************************************************************//**
443Sets types of fields binary in a tuple. */
444UNIV_INLINE
445void
446dtuple_set_types_binary(
447/*====================*/
448 dtuple_t* tuple, /*!< in: data tuple */
449 ulint n) /*!< in: number of fields to set */
450 MY_ATTRIBUTE((nonnull));
451/**********************************************************************//**
452Checks if a dtuple contains an SQL null value.
453@return TRUE if some field is SQL null */
454UNIV_INLINE
455ibool
456dtuple_contains_null(
457/*=================*/
458 const dtuple_t* tuple) /*!< in: dtuple */
459 MY_ATTRIBUTE((nonnull, warn_unused_result));
460/**********************************************************//**
461Checks that a data field is typed. Asserts an error if not.
462@return TRUE if ok */
463ibool
464dfield_check_typed(
465/*===============*/
466 const dfield_t* field) /*!< in: data field */
467 MY_ATTRIBUTE((nonnull, warn_unused_result));
468/**********************************************************//**
469Checks that a data tuple is typed. Asserts an error if not.
470@return TRUE if ok */
471ibool
472dtuple_check_typed(
473/*===============*/
474 const dtuple_t* tuple) /*!< in: tuple */
475 MY_ATTRIBUTE((nonnull, warn_unused_result));
476#ifdef UNIV_DEBUG
477/**********************************************************//**
478Validates the consistency of a tuple which must be complete, i.e,
479all fields must have been set.
480@return TRUE if ok */
481ibool
482dtuple_validate(
483/*============*/
484 const dtuple_t* tuple) /*!< in: tuple */
485 MY_ATTRIBUTE((nonnull, warn_unused_result));
486#endif /* UNIV_DEBUG */
487/*************************************************************//**
488Pretty prints a dfield value according to its data type. */
489void
490dfield_print(
491/*=========*/
492 const dfield_t* dfield) /*!< in: dfield */
493 MY_ATTRIBUTE((nonnull));
494/*************************************************************//**
495Pretty prints a dfield value according to its data type. Also the hex string
496is printed if a string contains non-printable characters. */
497void
498dfield_print_also_hex(
499/*==================*/
500 const dfield_t* dfield) /*!< in: dfield */
501 MY_ATTRIBUTE((nonnull));
502/**********************************************************//**
503The following function prints the contents of a tuple. */
504void
505dtuple_print(
506/*=========*/
507 FILE* f, /*!< in: output stream */
508 const dtuple_t* tuple) /*!< in: tuple */
509 MY_ATTRIBUTE((nonnull));
510
511/** Print the contents of a tuple.
512@param[out] o output stream
513@param[in] field array of data fields
514@param[in] n number of data fields */
515void
516dfield_print(
517 std::ostream& o,
518 const dfield_t* field,
519 ulint n);
520/** Print the contents of a tuple.
521@param[out] o output stream
522@param[in] tuple data tuple */
523void
524dtuple_print(
525 std::ostream& o,
526 const dtuple_t* tuple);
527
528/** Print the contents of a tuple.
529@param[out] o output stream
530@param[in] tuple data tuple */
531inline
532std::ostream&
533operator<<(std::ostream& o, const dtuple_t& tuple)
534{
535 dtuple_print(o, &tuple);
536 return(o);
537}
538
539/**************************************************************//**
540Moves parts of long fields in entry to the big record vector so that
541the size of tuple drops below the maximum record size allowed in the
542database. Moves data only from those fields which are not necessary
543to determine uniquely the insertion place of the tuple in the index.
544@return own: created big record vector, NULL if we are not able to
545shorten the entry enough, i.e., if there are too many fixed-length or
546short fields in entry or the index is clustered */
547big_rec_t*
548dtuple_convert_big_rec(
549/*===================*/
550 dict_index_t* index, /*!< in: index */
551 upd_t* upd, /*!< in/out: update vector */
552 dtuple_t* entry, /*!< in/out: index entry */
553 ulint* n_ext) /*!< in/out: number of
554 externally stored columns */
555 MY_ATTRIBUTE((malloc, warn_unused_result));
556/**************************************************************//**
557Puts back to entry the data stored in vector. Note that to ensure the
558fields in entry can accommodate the data, vector must have been created
559from entry with dtuple_convert_big_rec. */
560void
561dtuple_convert_back_big_rec(
562/*========================*/
563 dict_index_t* index, /*!< in: index */
564 dtuple_t* entry, /*!< in: entry whose data was put to vector */
565 big_rec_t* vector) /*!< in, own: big rec vector; it is
566 freed in this function */
567 MY_ATTRIBUTE((nonnull));
568/**************************************************************//**
569Frees the memory in a big rec vector. */
570UNIV_INLINE
571void
572dtuple_big_rec_free(
573/*================*/
574 big_rec_t* vector) /*!< in, own: big rec vector; it is
575 freed in this function */
576 MY_ATTRIBUTE((nonnull));
577
578/*######################################################################*/
579
580/** Structure for an SQL data field */
581struct dfield_t{
582 void* data; /*!< pointer to data */
583 unsigned ext:1; /*!< TRUE=externally stored, FALSE=local */
584 unsigned spatial_status:2;
585 /*!< spatial status of externally stored field
586 in undo log for purge */
587 unsigned len; /*!< data length; UNIV_SQL_NULL if SQL null */
588 dtype_t type; /*!< type of data */
589
590 /** Create a deep copy of this object.
591 @param[in,out] heap memory heap in which the clone will be created
592 @return the cloned object */
593 dfield_t* clone(mem_heap_t* heap) const;
594
595 /** @return system field indicates history row */
596 bool vers_history_row() const
597 {
598 ut_ad(type.vers_sys_end());
599 if (type.mtype == DATA_FIXBINARY) {
600 ut_ad(len == sizeof timestamp_max_bytes);
601 return 0 != memcmp(data, timestamp_max_bytes, len);
602 } else {
603 ut_ad(type.mtype == DATA_INT);
604 ut_ad(len == sizeof trx_id_max_bytes);
605 return 0 != memcmp(data, trx_id_max_bytes, len);
606 }
607 ut_ad(0);
608 return false;
609 }
610};
611
612/** Structure for an SQL data tuple of fields (logical record) */
613struct dtuple_t {
614 ulint info_bits; /*!< info bits of an index record:
615 the default is 0; this field is used
616 if an index record is built from
617 a data tuple */
618 ulint n_fields; /*!< number of fields in dtuple */
619 ulint n_fields_cmp; /*!< number of fields which should
620 be used in comparison services
621 of rem0cmp.*; the index search
622 is performed by comparing only these
623 fields, others are ignored; the
624 default value in dtuple creation is
625 the same value as n_fields */
626 dfield_t* fields; /*!< fields */
627 ulint n_v_fields; /*!< number of virtual fields */
628 dfield_t* v_fields; /*!< fields on virtual column */
629 UT_LIST_NODE_T(dtuple_t) tuple_list;
630 /*!< data tuples can be linked into a
631 list using this field */
632#ifdef UNIV_DEBUG
633 ulint magic_n; /*!< magic number, used in
634 debug assertions */
635/** Value of dtuple_t::magic_n */
636# define DATA_TUPLE_MAGIC_N 65478679
637#endif /* UNIV_DEBUG */
638
639 /** Trim the tail of an index tuple before insert or update.
640 After instant ADD COLUMN, if the last fields of a clustered index tuple
641 match the 'default row', there will be no need to store them.
642 NOTE: A page latch in the index must be held, so that the index
643 may not lose 'instantness' before the trimmed tuple has been
644 inserted or updated.
645 @param[in] index index possibly with instantly added columns */
646 void trim(const dict_index_t& index);
647};
648
649/** A slot for a field in a big rec vector */
650struct big_rec_field_t {
651
652 /** Constructor.
653 @param[in] field_no_ the field number
654 @param[in] len_ the data length
655 @param[in] data_ the data */
656 big_rec_field_t(ulint field_no_, ulint len_, const void* data_)
657 : field_no(field_no_),
658 len(len_),
659 data(data_)
660 {}
661
662 ulint field_no; /*!< field number in record */
663 ulint len; /*!< stored data length, in bytes */
664 const void* data; /*!< stored data */
665};
666
667/** Storage format for overflow data in a big record, that is, a
668clustered index record which needs external storage of data fields */
669struct big_rec_t {
670 mem_heap_t* heap; /*!< memory heap from which
671 allocated */
672 const ulint capacity; /*!< fields array size */
673 ulint n_fields; /*!< number of stored fields */
674 big_rec_field_t*fields; /*!< stored fields */
675
676 /** Constructor.
677 @param[in] max the capacity of the array of fields. */
678 explicit big_rec_t(const ulint max)
679 : heap(0),
680 capacity(max),
681 n_fields(0),
682 fields(0)
683 {}
684
685 /** Append one big_rec_field_t object to the end of array of fields */
686 void append(const big_rec_field_t& field)
687 {
688 ut_ad(n_fields < capacity);
689 fields[n_fields] = field;
690 n_fields++;
691 }
692
693 /** Allocate a big_rec_t object in the given memory heap, and for
694 storing n_fld number of fields.
695 @param[in] heap memory heap in which this object is allocated
696 @param[in] n_fld maximum number of fields that can be stored in
697 this object
698 @return the allocated object */
699 static big_rec_t* alloc(
700 mem_heap_t* heap,
701 ulint n_fld);
702};
703
704#include "data0data.ic"
705
706#endif
707