1/*****************************************************************************
2
3Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved.
4Copyright (c) 2017, 2018, 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/row0mysql.h
22Interface between Innobase row operations and MySQL.
23Contains also create table and other data dictionary operations.
24
25Created 9/17/2000 Heikki Tuuri
26*******************************************************/
27
28#ifndef row0mysql_h
29#define row0mysql_h
30
31#include "ha_prototypes.h"
32
33#include "data0data.h"
34#include "que0types.h"
35#include "dict0types.h"
36#include "trx0types.h"
37#include "row0types.h"
38#include "btr0pcur.h"
39#include "trx0types.h"
40#include "fil0crypt.h"
41
42// Forward declaration
43struct SysIndexCallback;
44
45extern ibool row_rollback_on_timeout;
46
47struct row_prebuilt_t;
48
49/*******************************************************************//**
50Frees the blob heap in prebuilt when no longer needed. */
51void
52row_mysql_prebuilt_free_blob_heap(
53/*==============================*/
54 row_prebuilt_t* prebuilt); /*!< in: prebuilt struct of a
55 ha_innobase:: table handle */
56/*******************************************************************//**
57Stores a >= 5.0.3 format true VARCHAR length to dest, in the MySQL row
58format.
59@return pointer to the data, we skip the 1 or 2 bytes at the start
60that are used to store the len */
61byte*
62row_mysql_store_true_var_len(
63/*=========================*/
64 byte* dest, /*!< in: where to store */
65 ulint len, /*!< in: length, must fit in two bytes */
66 ulint lenlen);/*!< in: storage length of len: either 1 or 2 bytes */
67/*******************************************************************//**
68Reads a >= 5.0.3 format true VARCHAR length, in the MySQL row format, and
69returns a pointer to the data.
70@return pointer to the data, we skip the 1 or 2 bytes at the start
71that are used to store the len */
72const byte*
73row_mysql_read_true_varchar(
74/*========================*/
75 ulint* len, /*!< out: variable-length field length */
76 const byte* field, /*!< in: field in the MySQL format */
77 ulint lenlen);/*!< in: storage length of len: either 1
78 or 2 bytes */
79/*******************************************************************//**
80Stores a reference to a BLOB in the MySQL format. */
81void
82row_mysql_store_blob_ref(
83/*=====================*/
84 byte* dest, /*!< in: where to store */
85 ulint col_len,/*!< in: dest buffer size: determines into
86 how many bytes the BLOB length is stored,
87 the space for the length may vary from 1
88 to 4 bytes */
89 const void* data, /*!< in: BLOB data; if the value to store
90 is SQL NULL this should be NULL pointer */
91 ulint len); /*!< in: BLOB length; if the value to store
92 is SQL NULL this should be 0; remember
93 also to set the NULL bit in the MySQL record
94 header! */
95/*******************************************************************//**
96Reads a reference to a BLOB in the MySQL format.
97@return pointer to BLOB data */
98const byte*
99row_mysql_read_blob_ref(
100/*====================*/
101 ulint* len, /*!< out: BLOB length */
102 const byte* ref, /*!< in: BLOB reference in the
103 MySQL format */
104 ulint col_len); /*!< in: BLOB reference length
105 (not BLOB length) */
106/*******************************************************************//**
107Converts InnoDB geometry data format to MySQL data format. */
108void
109row_mysql_store_geometry(
110/*=====================*/
111 byte* dest, /*!< in/out: where to store */
112 ulint dest_len, /*!< in: dest buffer size: determines into
113 how many bytes the geometry length is stored,
114 the space for the length may vary from 1
115 to 4 bytes */
116 const byte* src, /*!< in: geometry data; if the value to store
117 is SQL NULL this should be NULL pointer */
118 ulint src_len); /*!< in: geometry length; if the value to store
119 is SQL NULL this should be 0; remember
120 also to set the NULL bit in the MySQL record
121 header! */
122/**************************************************************//**
123Pad a column with spaces. */
124void
125row_mysql_pad_col(
126/*==============*/
127 ulint mbminlen, /*!< in: minimum size of a character,
128 in bytes */
129 byte* pad, /*!< out: padded buffer */
130 ulint len); /*!< in: number of bytes to pad */
131
132/**************************************************************//**
133Stores a non-SQL-NULL field given in the MySQL format in the InnoDB format.
134The counterpart of this function is row_sel_field_store_in_mysql_format() in
135row0sel.cc.
136@return up to which byte we used buf in the conversion */
137byte*
138row_mysql_store_col_in_innobase_format(
139/*===================================*/
140 dfield_t* dfield, /*!< in/out: dfield where dtype
141 information must be already set when
142 this function is called! */
143 byte* buf, /*!< in/out: buffer for a converted
144 integer value; this must be at least
145 col_len long then! NOTE that dfield
146 may also get a pointer to 'buf',
147 therefore do not discard this as long
148 as dfield is used! */
149 ibool row_format_col, /*!< TRUE if the mysql_data is from
150 a MySQL row, FALSE if from a MySQL
151 key value;
152 in MySQL, a true VARCHAR storage
153 format differs in a row and in a
154 key value: in a key value the length
155 is always stored in 2 bytes! */
156 const byte* mysql_data, /*!< in: MySQL column value, not
157 SQL NULL; NOTE that dfield may also
158 get a pointer to mysql_data,
159 therefore do not discard this as long
160 as dfield is used! */
161 ulint col_len, /*!< in: MySQL column length; NOTE that
162 this is the storage length of the
163 column in the MySQL format row, not
164 necessarily the length of the actual
165 payload data; if the column is a true
166 VARCHAR then this is irrelevant */
167 ulint comp); /*!< in: nonzero=compact format */
168/****************************************************************//**
169Handles user errors and lock waits detected by the database engine.
170@return true if it was a lock wait and we should continue running the
171query thread */
172bool
173row_mysql_handle_errors(
174/*====================*/
175 dberr_t* new_err,/*!< out: possible new error encountered in
176 rollback, or the old error which was
177 during the function entry */
178 trx_t* trx, /*!< in: transaction */
179 que_thr_t* thr, /*!< in: query thread, or NULL */
180 trx_savept_t* savept) /*!< in: savepoint, or NULL */
181 MY_ATTRIBUTE((nonnull(1,2)));
182/********************************************************************//**
183Create a prebuilt struct for a MySQL table handle.
184@return own: a prebuilt struct */
185row_prebuilt_t*
186row_create_prebuilt(
187/*================*/
188 dict_table_t* table, /*!< in: Innobase table handle */
189 ulint mysql_row_len); /*!< in: length in bytes of a row in
190 the MySQL format */
191/********************************************************************//**
192Free a prebuilt struct for a MySQL table handle. */
193void
194row_prebuilt_free(
195/*==============*/
196 row_prebuilt_t* prebuilt, /*!< in, own: prebuilt struct */
197 ibool dict_locked); /*!< in: TRUE=data dictionary locked */
198/*********************************************************************//**
199Updates the transaction pointers in query graphs stored in the prebuilt
200struct. */
201void
202row_update_prebuilt_trx(
203/*====================*/
204 row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct
205 in MySQL handle */
206 trx_t* trx); /*!< in: transaction handle */
207
208/*********************************************************************//**
209Sets an AUTO_INC type lock on the table mentioned in prebuilt. The
210AUTO_INC lock gives exclusive access to the auto-inc counter of the
211table. The lock is reserved only for the duration of an SQL statement.
212It is not compatible with another AUTO_INC or exclusive lock on the
213table.
214@return error code or DB_SUCCESS */
215dberr_t
216row_lock_table_autoinc_for_mysql(
217/*=============================*/
218 row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in the MySQL
219 table handle */
220 MY_ATTRIBUTE((nonnull, warn_unused_result));
221
222/** Lock a table.
223@param[in,out] prebuilt table handle
224@return error code or DB_SUCCESS */
225dberr_t
226row_lock_table(row_prebuilt_t* prebuilt);
227
228/** System Versioning: row_insert_for_mysql() modes */
229enum ins_mode_t {
230 /* plain row (without versioning) */
231 ROW_INS_NORMAL = 0,
232 /* row_start = TRX_ID, row_end = MAX */
233 ROW_INS_VERSIONED,
234 /* row_end = TRX_ID */
235 ROW_INS_HISTORICAL
236};
237
238/** Does an insert for MySQL.
239@param[in] mysql_rec row in the MySQL format
240@param[in,out] prebuilt prebuilt struct in MySQL handle
241@param[in] ins_mode what row type we're inserting
242@return error code or DB_SUCCESS*/
243dberr_t
244row_insert_for_mysql(
245 const byte* mysql_rec,
246 row_prebuilt_t* prebuilt,
247 ins_mode_t ins_mode)
248 MY_ATTRIBUTE((warn_unused_result));
249
250/*********************************************************************//**
251Builds a dummy query graph used in selects. */
252void
253row_prebuild_sel_graph(
254/*===================*/
255 row_prebuilt_t* prebuilt); /*!< in: prebuilt struct in MySQL
256 handle */
257/*********************************************************************//**
258Gets pointer to a prebuilt update vector used in updates. If the update
259graph has not yet been built in the prebuilt struct, then this function
260first builds it.
261@return prebuilt update vector */
262upd_t*
263row_get_prebuilt_update_vector(
264/*===========================*/
265 row_prebuilt_t* prebuilt); /*!< in: prebuilt struct in MySQL
266 handle */
267/** Does an update or delete of a row for MySQL.
268@param[in,out] prebuilt prebuilt struct in MySQL handle
269@return error code or DB_SUCCESS */
270dberr_t
271row_update_for_mysql(
272 row_prebuilt_t* prebuilt)
273 MY_ATTRIBUTE((warn_unused_result));
274
275/** This can only be used when srv_locks_unsafe_for_binlog is TRUE or this
276session is using a READ COMMITTED or READ UNCOMMITTED isolation level.
277Before calling this function row_search_for_mysql() must have
278initialized prebuilt->new_rec_locks to store the information which new
279record locks really were set. This function removes a newly set
280clustered index record lock under prebuilt->pcur or
281prebuilt->clust_pcur. Thus, this implements a 'mini-rollback' that
282releases the latest clustered index record lock we set.
283@param[in,out] prebuilt prebuilt struct in MySQL handle
284@param[in] has_latches_on_recs TRUE if called so that we have the
285 latches on the records under pcur
286 and clust_pcur, and we do not need
287 to reposition the cursors. */
288void
289row_unlock_for_mysql(
290 row_prebuilt_t* prebuilt,
291 ibool has_latches_on_recs);
292
293/*********************************************************************//**
294Checks if a table name contains the string "/#sql" which denotes temporary
295tables in MySQL.
296@return true if temporary table */
297bool
298row_is_mysql_tmp_table_name(
299/*========================*/
300 const char* name) MY_ATTRIBUTE((warn_unused_result));
301 /*!< in: table name in the form
302 'database/tablename' */
303
304/*********************************************************************//**
305Creates an query graph node of 'update' type to be used in the MySQL
306interface.
307@return own: update node */
308upd_node_t*
309row_create_update_node_for_mysql(
310/*=============================*/
311 dict_table_t* table, /*!< in: table to update */
312 mem_heap_t* heap); /*!< in: mem heap from which allocated */
313
314/**********************************************************************//**
315Does a cascaded delete or set null in a foreign key operation.
316@return error code or DB_SUCCESS */
317dberr_t
318row_update_cascade_for_mysql(
319/*=========================*/
320 que_thr_t* thr, /*!< in: query thread */
321 upd_node_t* node, /*!< in: update node used in the cascade
322 or set null operation */
323 dict_table_t* table) /*!< in: table where we do the operation */
324 MY_ATTRIBUTE((nonnull, warn_unused_result));
325/*********************************************************************//**
326Locks the data dictionary exclusively for performing a table create or other
327data dictionary modification operation. */
328void
329row_mysql_lock_data_dictionary_func(
330/*================================*/
331 trx_t* trx, /*!< in/out: transaction */
332 const char* file, /*!< in: file name */
333 unsigned line); /*!< in: line number */
334#define row_mysql_lock_data_dictionary(trx) \
335 row_mysql_lock_data_dictionary_func(trx, __FILE__, __LINE__)
336/*********************************************************************//**
337Unlocks the data dictionary exclusive lock. */
338void
339row_mysql_unlock_data_dictionary(
340/*=============================*/
341 trx_t* trx); /*!< in/out: transaction */
342/*********************************************************************//**
343Locks the data dictionary in shared mode from modifications, for performing
344foreign key check, rollback, or other operation invisible to MySQL. */
345void
346row_mysql_freeze_data_dictionary_func(
347/*==================================*/
348 trx_t* trx, /*!< in/out: transaction */
349 const char* file, /*!< in: file name */
350 unsigned line); /*!< in: line number */
351#define row_mysql_freeze_data_dictionary(trx) \
352 row_mysql_freeze_data_dictionary_func(trx, __FILE__, __LINE__)
353/*********************************************************************//**
354Unlocks the data dictionary shared lock. */
355void
356row_mysql_unfreeze_data_dictionary(
357/*===============================*/
358 trx_t* trx); /*!< in/out: transaction */
359/*********************************************************************//**
360Creates a table for MySQL. On failure the transaction will be rolled back
361and the 'table' object will be freed.
362@return error code or DB_SUCCESS */
363dberr_t
364row_create_table_for_mysql(
365/*=======================*/
366 dict_table_t* table, /*!< in, own: table definition
367 (will be freed, or on DB_SUCCESS
368 added to the data dictionary cache) */
369 trx_t* trx, /*!< in/out: transaction */
370 fil_encryption_t mode, /*!< in: encryption mode */
371 uint32_t key_id) /*!< in: encryption key_id */
372 MY_ATTRIBUTE((warn_unused_result));
373
374/*********************************************************************//**
375Does an index creation operation for MySQL. TODO: currently failure
376to create an index results in dropping the whole table! This is no problem
377currently as all indexes must be created at the same time as the table.
378@return error number or DB_SUCCESS */
379dberr_t
380row_create_index_for_mysql(
381/*=======================*/
382 dict_index_t* index, /*!< in, own: index definition
383 (will be freed) */
384 trx_t* trx, /*!< in: transaction handle */
385 const ulint* field_lengths) /*!< in: if not NULL, must contain
386 dict_index_get_n_fields(index)
387 actual field lengths for the
388 index columns, which are
389 then checked for not being too
390 large. */
391 MY_ATTRIBUTE((warn_unused_result));
392/*********************************************************************//**
393Scans a table create SQL string and adds to the data dictionary
394the foreign key constraints declared in the string. This function
395should be called after the indexes for a table have been created.
396Each foreign key constraint must be accompanied with indexes in
397bot participating tables. The indexes are allowed to contain more
398fields than mentioned in the constraint.
399
400@param[in] trx transaction
401@param[in] sql_string table create statement where
402 foreign keys are declared like:
403 FOREIGN KEY (a, b) REFERENCES table2(c, d),
404 table2 can be written also with the database
405 name before it: test.table2; the default
406 database id the database of parameter name
407@param[in] sql_length length of sql_string
408@param[in] name table full name in normalized form
409@param[in] reject_fks if TRUE, fail with error code
410 DB_CANNOT_ADD_CONSTRAINT if any
411 foreign keys are found.
412@return error code or DB_SUCCESS */
413dberr_t
414row_table_add_foreign_constraints(
415 trx_t* trx,
416 const char* sql_string,
417 size_t sql_length,
418 const char* name,
419 ibool reject_fks)
420 MY_ATTRIBUTE((warn_unused_result));
421
422/*********************************************************************//**
423The master thread in srv0srv.cc calls this regularly to drop tables which
424we must drop in background after queries to them have ended. Such lazy
425dropping of tables is needed in ALTER TABLE on Unix.
426@return how many tables dropped + remaining tables in list */
427ulint
428row_drop_tables_for_mysql_in_background(void);
429/*=========================================*/
430/*********************************************************************//**
431Get the background drop list length. NOTE: the caller must own the kernel
432mutex!
433@return how many tables in list */
434ulint
435row_get_background_drop_list_len_low(void);
436/*======================================*/
437
438/** Drop garbage tables during recovery. */
439void
440row_mysql_drop_garbage_tables();
441
442/*********************************************************************//**
443Sets an exclusive lock on a table.
444@return error code or DB_SUCCESS */
445dberr_t
446row_mysql_lock_table(
447/*=================*/
448 trx_t* trx, /*!< in/out: transaction */
449 dict_table_t* table, /*!< in: table to lock */
450 enum lock_mode mode, /*!< in: LOCK_X or LOCK_S */
451 const char* op_info) /*!< in: string for trx->op_info */
452 MY_ATTRIBUTE((nonnull, warn_unused_result));
453
454/*********************************************************************//**
455Truncates a table for MySQL.
456@return error code or DB_SUCCESS */
457dberr_t
458row_truncate_table_for_mysql(
459/*=========================*/
460 dict_table_t* table, /*!< in: table handle */
461 trx_t* trx) /*!< in: transaction handle */
462 MY_ATTRIBUTE((nonnull, warn_unused_result));
463/*********************************************************************//**
464Drops a table for MySQL. If the data dictionary was not already locked
465by the transaction, the transaction will be committed. Otherwise, the
466data dictionary will remain locked.
467@return error code or DB_SUCCESS */
468dberr_t
469row_drop_table_for_mysql(
470/*=====================*/
471 const char* name, /*!< in: table name */
472 trx_t* trx, /*!< in: dictionary transaction handle */
473 bool drop_db,/*!< in: true=dropping whole database */
474 ibool create_failed,/*!<in: TRUE=create table failed
475 because e.g. foreign key column
476 type mismatch. */
477 bool nonatomic = true);
478 /*!< in: whether it is permitted
479 to release and reacquire dict_operation_lock */
480
481/*********************************************************************//**
482Discards the tablespace of a table which stored in an .ibd file. Discarding
483means that this function deletes the .ibd file and assigns a new table id for
484the table. Also the file_unreadable flag is set.
485@return error code or DB_SUCCESS */
486dberr_t
487row_discard_tablespace_for_mysql(
488/*=============================*/
489 const char* name, /*!< in: table name */
490 trx_t* trx) /*!< in: transaction handle */
491 MY_ATTRIBUTE((nonnull, warn_unused_result));
492/*****************************************************************//**
493Imports a tablespace. The space id in the .ibd file must match the space id
494of the table in the data dictionary.
495@return error code or DB_SUCCESS */
496dberr_t
497row_import_tablespace_for_mysql(
498/*============================*/
499 dict_table_t* table, /*!< in/out: table */
500 row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL */
501 MY_ATTRIBUTE((nonnull, warn_unused_result));
502
503/** Drop a database for MySQL.
504@param[in] name database name which ends at '/'
505@param[in] trx transaction handle
506@param[out] found number of dropped tables/partitions
507@return error code or DB_SUCCESS */
508dberr_t
509row_drop_database_for_mysql(
510 const char* name,
511 trx_t* trx,
512 ulint* found);
513
514/*********************************************************************//**
515Renames a table for MySQL.
516@return error code or DB_SUCCESS */
517dberr_t
518row_rename_table_for_mysql(
519/*=======================*/
520 const char* old_name, /*!< in: old table name */
521 const char* new_name, /*!< in: new table name */
522 trx_t* trx, /*!< in/out: transaction */
523 bool commit) /*!< in: whether to commit trx */
524 MY_ATTRIBUTE((nonnull, warn_unused_result));
525
526/*********************************************************************//**
527Scans an index for either COOUNT(*) or CHECK TABLE.
528If CHECK TABLE; Checks that the index contains entries in an ascending order,
529unique constraint is not broken, and calculates the number of index entries
530in the read view of the current transaction.
531@return DB_SUCCESS or other error */
532dberr_t
533row_scan_index_for_mysql(
534/*=====================*/
535 row_prebuilt_t* prebuilt, /*!< in: prebuilt struct
536 in MySQL handle */
537 const dict_index_t* index, /*!< in: index */
538 ulint* n_rows) /*!< out: number of entries
539 seen in the consistent read */
540 MY_ATTRIBUTE((warn_unused_result));
541/*********************************************************************//**
542Initialize this module */
543void
544row_mysql_init(void);
545/*================*/
546
547/*********************************************************************//**
548Close this module */
549void
550row_mysql_close(void);
551/*=================*/
552
553/* A struct describing a place for an individual column in the MySQL
554row format which is presented to the table handler in ha_innobase.
555This template struct is used to speed up row transformations between
556Innobase and MySQL. */
557
558struct mysql_row_templ_t {
559 ulint col_no; /*!< column number of the column */
560 ulint rec_field_no; /*!< field number of the column in an
561 Innobase record in the current index;
562 not defined if template_type is
563 ROW_MYSQL_WHOLE_ROW */
564 ibool rec_field_is_prefix; /* is this field in a prefix index? */
565 ulint rec_prefix_field_no; /* record field, even if just a
566 prefix; same as rec_field_no when not a
567 prefix, otherwise rec_field_no is
568 ULINT_UNDEFINED but this is the true
569 field number*/
570 ulint clust_rec_field_no; /*!< field number of the column in an
571 Innobase record in the clustered index;
572 not defined if template_type is
573 ROW_MYSQL_WHOLE_ROW */
574 ulint icp_rec_field_no; /*!< field number of the column in an
575 Innobase record in the current index;
576 not defined unless
577 index condition pushdown is used */
578 ulint mysql_col_offset; /*!< offset of the column in the MySQL
579 row format */
580 ulint mysql_col_len; /*!< length of the column in the MySQL
581 row format */
582 ulint mysql_null_byte_offset; /*!< MySQL NULL bit byte offset in a
583 MySQL record */
584 ulint mysql_null_bit_mask; /*!< bit mask to get the NULL bit,
585 zero if column cannot be NULL */
586 ulint type; /*!< column type in Innobase mtype
587 numbers DATA_CHAR... */
588 ulint mysql_type; /*!< MySQL type code; this is always
589 < 256 */
590 ulint mysql_length_bytes; /*!< if mysql_type
591 == DATA_MYSQL_TRUE_VARCHAR, this tells
592 whether we should use 1 or 2 bytes to
593 store the MySQL true VARCHAR data
594 length at the start of row in the MySQL
595 format (NOTE that the MySQL key value
596 format always uses 2 bytes for the data
597 len) */
598 ulint charset; /*!< MySQL charset-collation code
599 of the column, or zero */
600 ulint mbminlen; /*!< minimum length of a char, in bytes,
601 or zero if not a char type */
602 ulint mbmaxlen; /*!< maximum length of a char, in bytes,
603 or zero if not a char type */
604 ulint is_unsigned; /*!< if a column type is an integer
605 type and this field is != 0, then
606 it is an unsigned integer type */
607 ulint is_virtual; /*!< if a column is a virtual column */
608};
609
610#define MYSQL_FETCH_CACHE_SIZE 8
611/* After fetching this many rows, we start caching them in fetch_cache */
612#define MYSQL_FETCH_CACHE_THRESHOLD 4
613
614#define ROW_PREBUILT_ALLOCATED 78540783
615#define ROW_PREBUILT_FREED 26423527
616
617/** A struct for (sometimes lazily) prebuilt structures in an Innobase table
618handle used within MySQL; these are used to save CPU time. */
619
620struct row_prebuilt_t {
621 ulint magic_n; /*!< this magic number is set to
622 ROW_PREBUILT_ALLOCATED when created,
623 or ROW_PREBUILT_FREED when the
624 struct has been freed */
625 dict_table_t* table; /*!< Innobase table handle */
626 dict_index_t* index; /*!< current index for a search, if
627 any */
628 trx_t* trx; /*!< current transaction handle */
629 unsigned sql_stat_start:1;/*!< TRUE when we start processing of
630 an SQL statement: we may have to set
631 an intention lock on the table,
632 create a consistent read view etc. */
633 unsigned clust_index_was_generated:1;
634 /*!< if the user did not define a
635 primary key in MySQL, then Innobase
636 automatically generated a clustered
637 index where the ordering column is
638 the row id: in this case this flag
639 is set to TRUE */
640 unsigned index_usable:1; /*!< caches the value of
641 row_merge_is_index_usable(trx,index) */
642 unsigned read_just_key:1;/*!< set to 1 when MySQL calls
643 ha_innobase::extra with the
644 argument HA_EXTRA_KEYREAD; it is enough
645 to read just columns defined in
646 the index (i.e., no read of the
647 clustered index record necessary) */
648 unsigned used_in_HANDLER:1;/*!< TRUE if we have been using this
649 handle in a MySQL HANDLER low level
650 index cursor command: then we must
651 store the pcur position even in a
652 unique search from a clustered index,
653 because HANDLER allows NEXT and PREV
654 in such a situation */
655 unsigned template_type:2;/*!< ROW_MYSQL_WHOLE_ROW,
656 ROW_MYSQL_REC_FIELDS,
657 ROW_MYSQL_DUMMY_TEMPLATE, or
658 ROW_MYSQL_NO_TEMPLATE */
659 unsigned n_template:10; /*!< number of elements in the
660 template */
661 unsigned null_bitmap_len:10;/*!< number of bytes in the SQL NULL
662 bitmap at the start of a row in the
663 MySQL format */
664 unsigned need_to_access_clustered:1; /*!< if we are fetching
665 columns through a secondary index
666 and at least one column is not in
667 the secondary index, then this is
668 set to TRUE; note that sometimes this
669 is set but we later optimize out the
670 clustered index lookup */
671 unsigned templ_contains_blob:1;/*!< TRUE if the template contains
672 a column with DATA_LARGE_MTYPE(
673 get_innobase_type_from_mysql_type())
674 is TRUE;
675 not to be confused with InnoDB
676 externally stored columns
677 (VARCHAR can be off-page too) */
678 unsigned versioned_write:1;/*!< whether this is
679 a versioned write */
680 mysql_row_templ_t* mysql_template;/*!< template used to transform
681 rows fast between MySQL and Innobase
682 formats; memory for this template
683 is not allocated from 'heap' */
684 mem_heap_t* heap; /*!< memory heap from which
685 these auxiliary structures are
686 allocated when needed */
687 ins_node_t* ins_node; /*!< Innobase SQL insert node
688 used to perform inserts
689 to the table */
690 byte* ins_upd_rec_buff;/*!< buffer for storing data converted
691 to the Innobase format from the MySQL
692 format */
693 const byte* default_rec; /*!< the default values of all columns
694 (a "default row") in MySQL format */
695 ulint hint_need_to_fetch_extra_cols;
696 /*!< normally this is set to 0; if this
697 is set to ROW_RETRIEVE_PRIMARY_KEY,
698 then we should at least retrieve all
699 columns in the primary key; if this
700 is set to ROW_RETRIEVE_ALL_COLS, then
701 we must retrieve all columns in the
702 key (if read_just_key == 1), or all
703 columns in the table */
704 upd_node_t* upd_node; /*!< Innobase SQL update node used
705 to perform updates and deletes */
706 trx_id_t trx_id; /*!< The table->def_trx_id when
707 ins_graph was built */
708 que_fork_t* ins_graph; /*!< Innobase SQL query graph used
709 in inserts. Will be rebuilt on
710 trx_id or n_indexes mismatch. */
711 que_fork_t* upd_graph; /*!< Innobase SQL query graph used
712 in updates or deletes */
713 btr_pcur_t* pcur; /*!< persistent cursor used in selects
714 and updates */
715 btr_pcur_t* clust_pcur; /*!< persistent cursor used in
716 some selects and updates */
717 que_fork_t* sel_graph; /*!< dummy query graph used in
718 selects */
719 dtuple_t* search_tuple; /*!< prebuilt dtuple used in selects */
720 byte row_id[DATA_ROW_ID_LEN];
721 /*!< if the clustered index was
722 generated, the row id of the
723 last row fetched is stored
724 here */
725 doc_id_t fts_doc_id; /* if the table has an FTS index on
726 it then we fetch the doc_id.
727 FTS-FIXME: Currently we fetch it always
728 but in the future we must only fetch
729 it when FTS columns are being
730 updated */
731 dtuple_t* clust_ref; /*!< prebuilt dtuple used in
732 sel/upd/del */
733 ulint select_lock_type;/*!< LOCK_NONE, LOCK_S, or LOCK_X */
734 ulint stored_select_lock_type;/*!< this field is used to
735 remember the original select_lock_type
736 that was decided in ha_innodb.cc,
737 ::store_lock(), ::external_lock(),
738 etc. */
739 ulint row_read_type; /*!< ROW_READ_WITH_LOCKS if row locks
740 should be the obtained for records
741 under an UPDATE or DELETE cursor.
742 If innodb_locks_unsafe_for_binlog
743 is TRUE, this can be set to
744 ROW_READ_TRY_SEMI_CONSISTENT, so that
745 if the row under an UPDATE or DELETE
746 cursor was locked by another
747 transaction, InnoDB will resort
748 to reading the last committed value
749 ('semi-consistent read'). Then,
750 this field will be set to
751 ROW_READ_DID_SEMI_CONSISTENT to
752 indicate that. If the row does not
753 match the WHERE condition, MySQL will
754 invoke handler::unlock_row() to
755 clear the flag back to
756 ROW_READ_TRY_SEMI_CONSISTENT and
757 to simply skip the row. If
758 the row matches, the next call to
759 row_search_for_mysql() will lock
760 the row.
761 This eliminates lock waits in some
762 cases; note that this breaks
763 serializability. */
764 ulint new_rec_locks; /*!< normally 0; if
765 srv_locks_unsafe_for_binlog is
766 TRUE or session is using READ
767 COMMITTED or READ UNCOMMITTED
768 isolation level, set in
769 row_search_for_mysql() if we set a new
770 record lock on the secondary
771 or clustered index; this is
772 used in row_unlock_for_mysql()
773 when releasing the lock under
774 the cursor if we determine
775 after retrieving the row that
776 it does not need to be locked
777 ('mini-rollback') */
778 ulint mysql_prefix_len;/*!< byte offset of the end of
779 the last requested column */
780 ulint mysql_row_len; /*!< length in bytes of a row in the
781 MySQL format */
782 ulint n_rows_fetched; /*!< number of rows fetched after
783 positioning the current cursor */
784 ulint fetch_direction;/*!< ROW_SEL_NEXT or ROW_SEL_PREV */
785 byte* fetch_cache[MYSQL_FETCH_CACHE_SIZE];
786 /*!< a cache for fetched rows if we
787 fetch many rows from the same cursor:
788 it saves CPU time to fetch them in a
789 batch; we reserve mysql_row_len
790 bytes for each such row; these
791 pointers point 4 bytes past the
792 allocated mem buf start, because
793 there is a 4 byte magic number at the
794 start and at the end */
795 bool keep_other_fields_on_keyread; /*!< when using fetch
796 cache with HA_EXTRA_KEYREAD, don't
797 overwrite other fields in mysql row
798 row buffer.*/
799 ulint fetch_cache_first;/*!< position of the first not yet
800 fetched row in fetch_cache */
801 ulint n_fetch_cached; /*!< number of not yet fetched rows
802 in fetch_cache */
803 mem_heap_t* blob_heap; /*!< in SELECTS BLOB fields are copied
804 to this heap */
805 mem_heap_t* old_vers_heap; /*!< memory heap where a previous
806 version is built in consistent read */
807 bool in_fts_query; /*!< Whether we are in a FTS query */
808 bool fts_doc_id_in_read_set; /*!< true if table has externally
809 defined FTS_DOC_ID coulmn. */
810 /*----------------------*/
811 ulonglong autoinc_last_value;
812 /*!< last value of AUTO-INC interval */
813 ulonglong autoinc_increment;/*!< The increment step of the auto
814 increment column. Value must be
815 greater than or equal to 1. Required to
816 calculate the next value */
817 ulonglong autoinc_offset; /*!< The offset passed to
818 get_auto_increment() by MySQL. Required
819 to calculate the next value */
820 dberr_t autoinc_error; /*!< The actual error code encountered
821 while trying to init or read the
822 autoinc value from the table. We
823 store it here so that we can return
824 it to MySQL */
825 /*----------------------*/
826 void* idx_cond; /*!< In ICP, pointer to a ha_innobase,
827 passed to innobase_index_cond().
828 NULL if index condition pushdown is
829 not used. */
830 ulint idx_cond_n_cols;/*!< Number of fields in idx_cond_cols.
831 0 if and only if idx_cond == NULL. */
832 /*----------------------*/
833
834 /*----------------------*/
835 rtr_info_t* rtr_info; /*!< R-tree Search Info */
836 /*----------------------*/
837
838 ulint magic_n2; /*!< this should be the same as
839 magic_n */
840
841 byte* srch_key_val1; /*!< buffer used in converting
842 search key values from MySQL format
843 to InnoDB format.*/
844 byte* srch_key_val2; /*!< buffer used in converting
845 search key values from MySQL format
846 to InnoDB format.*/
847 uint srch_key_val_len; /*!< Size of search key */
848 /** Disable prefetch. */
849 bool m_no_prefetch;
850
851 /** Return materialized key for secondary index scan */
852 bool m_read_virtual_key;
853
854 /** The MySQL table object */
855 TABLE* m_mysql_table;
856
857 /** Get template by dict_table_t::cols[] number */
858 const mysql_row_templ_t* get_template_by_col(ulint col) const
859 {
860 ut_ad(col < n_template);
861 ut_ad(mysql_template);
862 for (ulint i = col; i < n_template; ++i) {
863 const mysql_row_templ_t* templ = &mysql_template[i];
864 if (!templ->is_virtual && templ->col_no == col) {
865 return templ;
866 }
867 }
868 return NULL;
869 }
870};
871
872/** Callback for row_mysql_sys_index_iterate() */
873struct SysIndexCallback {
874 virtual ~SysIndexCallback() { }
875
876 /** Callback method
877 @param mtr current mini transaction
878 @param pcur persistent cursor. */
879 virtual void operator()(mtr_t* mtr, btr_pcur_t* pcur) throw() = 0;
880};
881
882/** Get the computed value by supplying the base column values.
883@param[in,out] row the data row
884@param[in] col virtual column
885@param[in] index index on the virtual column
886@param[in,out] local_heap heap memory for processing large data etc.
887@param[in,out] heap memory heap that copies the actual index row
888@param[in] ifield index field
889@param[in] thd MySQL thread handle
890@param[in,out] mysql_table mysql table object
891@param[in] old_table during ALTER TABLE, this is the old table
892 or NULL.
893@param[in] parent_update update vector for the parent row
894@param[in] foreign foreign key information
895@return the field filled with computed value */
896dfield_t*
897innobase_get_computed_value(
898 const dtuple_t* row,
899 const dict_v_col_t* col,
900 const dict_index_t* index,
901 mem_heap_t** local_heap,
902 mem_heap_t* heap,
903 const dict_field_t* ifield,
904 THD* thd,
905 TABLE* mysql_table,
906 const dict_table_t* old_table,
907 upd_t* parent_update,
908 dict_foreign_t* foreign);
909
910/** Get the computed value by supplying the base column values.
911@param[in,out] table the table whose virtual column template to be built */
912void
913innobase_init_vc_templ(
914 dict_table_t* table);
915
916/** Change dbname and table name in table->vc_templ.
917@param[in,out] table the table whose virtual column template
918dbname and tbname to be renamed. */
919void
920innobase_rename_vc_templ(
921 dict_table_t* table);
922
923#define ROW_PREBUILT_FETCH_MAGIC_N 465765687
924
925#define ROW_MYSQL_WHOLE_ROW 0
926#define ROW_MYSQL_REC_FIELDS 1
927#define ROW_MYSQL_NO_TEMPLATE 2
928#define ROW_MYSQL_DUMMY_TEMPLATE 3 /* dummy template used in
929 row_scan_and_check_index */
930
931/* Values for hint_need_to_fetch_extra_cols */
932#define ROW_RETRIEVE_PRIMARY_KEY 1
933#define ROW_RETRIEVE_ALL_COLS 2
934
935/* Values for row_read_type */
936#define ROW_READ_WITH_LOCKS 0
937#define ROW_READ_TRY_SEMI_CONSISTENT 1
938#define ROW_READ_DID_SEMI_CONSISTENT 2
939
940#ifdef UNIV_DEBUG
941/** Wait for the background drop list to become empty. */
942void
943row_wait_for_background_drop_list_empty();
944#endif /* UNIV_DEBUG */
945
946#endif /* row0mysql.h */
947