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