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