1 /*****************************************************************************
2 
3 Copyright (c) 2006, 2016, Oracle and/or its affiliates. All Rights Reserved.
4 Copyright (c) 2017, 2020, 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/ha_prototypes.h
22 Prototypes for global functions in ha_innodb.cc that are called by
23 InnoDB C code.
24 
25 NOTE: This header is intended to insulate InnoDB from SQL names and functions.
26 Do not include any headers other than univ.i into this unless they are very
27 simple headers.
28 ************************************************************************/
29 
30 #ifndef HA_INNODB_PROTOTYPES_H
31 #define HA_INNODB_PROTOTYPES_H
32 
33 #include "univ.i"
34 
35 #ifndef UNIV_INNOCHECKSUM
36 
37 /* Forward declarations */
38 class THD;
39 
40 // JAN: TODO missing features:
41 #undef MYSQL_FT_INIT_EXT
42 #undef MYSQL_PFS
43 #undef MYSQL_STORE_FTS_DOC_ID
44 
45 /*******************************************************************//**
46 Formats the raw data in "data" (in InnoDB on-disk format) that is of
47 type DATA_(CHAR|VARCHAR|MYSQL|VARMYSQL) using "charset_coll" and writes
48 the result to "buf". The result is converted to "system_charset_info".
49 Not more than "buf_size" bytes are written to "buf".
50 The result is always NUL-terminated (provided buf_size > 0) and the
51 number of bytes that were written to "buf" is returned (including the
52 terminating NUL).
53 @return number of bytes that were written */
54 ulint
55 innobase_raw_format(
56 /*================*/
57 	const char*	data,		/*!< in: raw data */
58 	ulint		data_len,	/*!< in: raw data length
59 					in bytes */
60 	ulint		charset_coll,	/*!< in: charset collation */
61 	char*		buf,		/*!< out: output buffer */
62 	ulint		buf_size);	/*!< in: output buffer size
63 					in bytes */
64 
65 /*****************************************************************//**
66 Invalidates the MySQL query cache for the table. */
67 void
68 innobase_invalidate_query_cache(
69 /*============================*/
70 	trx_t*		trx,		/*!< in: transaction which
71 					modifies the table */
72 	const char*	full_name);	/*!< in: concatenation of
73 					database name, path separator,
74 					table name, null char NUL;
75 					NOTE that in Windows this is
76 					always in LOWER CASE! */
77 
78 /** Quote a standard SQL identifier like tablespace, index or column name.
79 @param[in]	file	output stream
80 @param[in]	trx	InnoDB transaction, or NULL
81 @param[in]	id	identifier to quote */
82 void
83 innobase_quote_identifier(
84 	FILE*		file,
85 	trx_t*		trx,
86 	const char*	id);
87 
88 /** Quote an standard SQL identifier like tablespace, index or column name.
89 Return the string as an std:string object.
90 @param[in]	trx	InnoDB transaction, or NULL
91 @param[in]	id	identifier to quote
92 @return a std::string with id properly quoted. */
93 std::string
94 innobase_quote_identifier(
95 	trx_t*		trx,
96 	const char*	id);
97 
98 /*****************************************************************//**
99 Convert a table name to the MySQL system_charset_info (UTF-8).
100 @return pointer to the end of buf */
101 char*
102 innobase_convert_name(
103 /*==================*/
104 	char*		buf,	/*!< out: buffer for converted identifier */
105 	ulint		buflen,	/*!< in: length of buf, in bytes */
106 	const char*	id,	/*!< in: table name to convert */
107 	ulint		idlen,	/*!< in: length of id, in bytes */
108 	THD*		thd);	/*!< in: MySQL connection thread, or NULL */
109 
110 /******************************************************************//**
111 Returns true if the thread is the replication thread on the slave
112 server. Used in srv_conc_enter_innodb() to determine if the thread
113 should be allowed to enter InnoDB - the replication thread is treated
114 differently than other threads. Also used in
115 srv_conc_force_exit_innodb().
116 @return true if thd is the replication thread */
117 ibool
118 thd_is_replication_slave_thread(
119 /*============================*/
120 	THD*	thd);	/*!< in: thread handle */
121 
122 /******************************************************************//**
123 Returns true if the transaction this thread is processing has edited
124 non-transactional tables. Used by the deadlock detector when deciding
125 which transaction to rollback in case of a deadlock - we try to avoid
126 rolling back transactions that have edited non-transactional tables.
127 @return true if non-transactional tables have been edited */
128 ibool
129 thd_has_edited_nontrans_tables(
130 /*===========================*/
131 	THD*	thd);	/*!< in: thread handle */
132 
133 /**
134 Get high resolution timestamp for the current query start time.
135 
136 @retval timestamp in microseconds precision
137 */
138 unsigned long long thd_query_start_micro(const MYSQL_THD thd);
139 
140 /*************************************************************//**
141 Prints info of a THD object (== user session thread) to the given file. */
142 void
143 innobase_mysql_print_thd(
144 /*=====================*/
145 	FILE*	f,		/*!< in: output stream */
146 	THD*	thd,		/*!< in: pointer to a MySQL THD object */
147 	uint	max_query_len);	/*!< in: max query length to print, or 0 to
148 				   use the default max length */
149 
150 /*****************************************************************//**
151 Log code calls this whenever log has been written and/or flushed up
152 to a new position. We use this to notify upper layer of a new commit
153 checkpoint when necessary.*/
154 UNIV_INTERN
155 void
156 innobase_mysql_log_notify(
157 /*======================*/
158 	ib_uint64_t	flush_lsn);	/*!< in: LSN flushed to disk */
159 
160 /** Converts a MySQL type to an InnoDB type. Note that this function returns
161 the 'mtype' of InnoDB. InnoDB differentiates between MySQL's old <= 4.1
162 VARCHAR and the new true VARCHAR in >= 5.0.3 by the 'prtype'.
163 @param[out]	unsigned_flag		DATA_UNSIGNED if an 'unsigned type';
164 at least ENUM and SET, and unsigned integer types are 'unsigned types'
165 @param[in]	f			MySQL Field
166 @return DATA_BINARY, DATA_VARCHAR, ... */
167 ulint
168 get_innobase_type_from_mysql_type(
169 	ulint*			unsigned_flag,
170 	const void*		field);
171 
172 /******************************************************************//**
173 Get the variable length bounds of the given character set. */
174 void
175 innobase_get_cset_width(
176 /*====================*/
177 	ulint	cset,		/*!< in: MySQL charset-collation code */
178 	ulint*	mbminlen,	/*!< out: minimum length of a char (in bytes) */
179 	ulint*	mbmaxlen);	/*!< out: maximum length of a char (in bytes) */
180 
181 /******************************************************************//**
182 Compares NUL-terminated UTF-8 strings case insensitively.
183 @return 0 if a=b, <0 if a<b, >1 if a>b */
184 int
185 innobase_strcasecmp(
186 /*================*/
187 	const char*	a,	/*!< in: first string to compare */
188 	const char*	b);	/*!< in: second string to compare */
189 
190 /** Strip dir name from a full path name and return only the file name
191 @param[in]	path_name	full path name
192 @return file name or "null" if no file name */
193 const char*
194 innobase_basename(
195 	const char*	path_name);
196 
197 /******************************************************************//**
198 Returns true if the thread is executing a SELECT statement.
199 @return true if thd is executing SELECT */
200 ibool
201 thd_is_select(
202 /*==========*/
203 	const THD*	thd);	/*!< in: thread handle */
204 
205 /******************************************************************//**
206 Converts an identifier to a table name. */
207 void
208 innobase_convert_from_table_id(
209 /*===========================*/
210 	CHARSET_INFO*	cs,	/*!< in: the 'from' character set */
211 	char*		to,	/*!< out: converted identifier */
212 	const char*	from,	/*!< in: identifier to convert */
213 	ulint		len);	/*!< in: length of 'to', in bytes; should
214 				be at least 5 * strlen(to) + 1 */
215 /******************************************************************//**
216 Converts an identifier to UTF-8. */
217 void
218 innobase_convert_from_id(
219 /*=====================*/
220 	CHARSET_INFO*	cs,	/*!< in: the 'from' character set */
221 	char*		to,	/*!< out: converted identifier */
222 	const char*	from,	/*!< in: identifier to convert */
223 	ulint		len);	/*!< in: length of 'to', in bytes;
224 				should be at least 3 * strlen(to) + 1 */
225 /******************************************************************//**
226 Makes all characters in a NUL-terminated UTF-8 string lower case. */
227 void
228 innobase_casedn_str(
229 /*================*/
230 	char*	a);	/*!< in/out: string to put in lower case */
231 
232 #ifdef WITH_WSREP
233 void
234 wsrep_innobase_kill_one_trx(MYSQL_THD const thd_ptr,
235                             const trx_t * const bf_trx,
236                             trx_t *victim_trx,
237                             my_bool signal);
238 ulint wsrep_innobase_mysql_sort(int mysql_type, uint charset_number,
239                              unsigned char* str, unsigned int str_length,
240                              unsigned int buf_length);
241 #endif /* WITH_WSREP */
242 
243 extern "C" struct charset_info_st *thd_charset(THD *thd);
244 
245 /** Determines the current SQL statement.
246 Thread unsafe, can only be called from the thread owning the THD.
247 @param[in]	thd	MySQL thread handle
248 @param[out]	length	Length of the SQL statement
249 @return			SQL statement string */
250 const char*
251 innobase_get_stmt_unsafe(
252 	THD*	thd,
253 	size_t*	length);
254 
255 /******************************************************************//**
256 This function is used to find the storage length in bytes of the first n
257 characters for prefix indexes using a multibyte character set. The function
258 finds charset information and returns length of prefix_len characters in the
259 index field in bytes.
260 @return number of bytes occupied by the first n characters */
261 ulint
262 innobase_get_at_most_n_mbchars(
263 /*===========================*/
264 	ulint charset_id,	/*!< in: character set id */
265 	ulint prefix_len,	/*!< in: prefix length in bytes of the index
266 				(this has to be divided by mbmaxlen to get the
267 				number of CHARACTERS n in the prefix) */
268 	ulint data_len,		/*!< in: length of the string in bytes */
269 	const char* str);	/*!< in: character string */
270 
271 /** Get status of innodb_tmpdir.
272 @param[in]	thd	thread handle, or NULL to query
273 			the global innodb_tmpdir.
274 @retval NULL if innodb_tmpdir="" */
275 UNIV_INTERN
276 const char*
277 thd_innodb_tmpdir(
278 	THD*	thd);
279 
280 /******************************************************************//**
281 Returns the lock wait timeout for the current connection.
282 @return the lock wait timeout, in seconds */
283 ulong
284 thd_lock_wait_timeout(
285 /*==================*/
286 	THD*	thd);	/*!< in: thread handle, or NULL to query
287 			the global innodb_lock_wait_timeout */
288 /** Get status of innodb_tmpdir.
289 @param[in]	thd	thread handle, or NULL to query
290 			the global innodb_tmpdir.
291 @retval NULL if innodb_tmpdir="" */
292 const char*
293 thd_innodb_tmpdir(
294 	THD*	thd);
295 
296 /**********************************************************************//**
297 Get the current setting of the table_cache_size global parameter. We do
298 a dirty read because for one there is no synchronization object and
299 secondly there is little harm in doing so even if we get a torn read.
300 @return SQL statement string */
301 ulint
302 innobase_get_table_cache_size(void);
303 /*===============================*/
304 
305 /**********************************************************************//**
306 Get the current setting of the lower_case_table_names global parameter from
307 mysqld.cc. We do a dirty read because for one there is no synchronization
308 object and secondly there is little harm in doing so even if we get a torn
309 read.
310 @return value of lower_case_table_names */
311 ulint
312 innobase_get_lower_case_table_names(void);
313 /*=====================================*/
314 
315 /******************************************************************//**
316 compare two character string case insensitively according to their charset. */
317 int
318 innobase_fts_text_case_cmp(
319 /*=======================*/
320 	const void*	cs,		/*!< in: Character set */
321 	const void*	p1,		/*!< in: key */
322 	const void*	p2);		/*!< in: node */
323 
324 /******************************************************************//**
325 Returns true if transaction should be flagged as read-only.
326 @return true if the thd is marked as read-only */
327 bool
328 thd_trx_is_read_only(
329 /*=================*/
330 	THD*	thd);	/*!< in/out: thread handle */
331 
332 /******************************************************************//**
333 Check if the transaction is an auto-commit transaction. TRUE also
334 implies that it is a SELECT (read-only) transaction.
335 @return true if the transaction is an auto commit read-only transaction. */
336 ibool
337 thd_trx_is_auto_commit(
338 /*===================*/
339 	THD*	thd);	/*!< in: thread handle, or NULL */
340 
341 /*****************************************************************//**
342 A wrapper function of innobase_convert_name(), convert a table name
343 to the MySQL system_charset_info (UTF-8) and quote it if needed.
344 @return pointer to the end of buf */
345 void
346 innobase_format_name(
347 /*==================*/
348 	char*		buf,	/*!< out: buffer for converted identifier */
349 	ulint		buflen,	/*!< in: length of buf, in bytes */
350 	const char*	name);	/*!< in: table name to format */
351 
352 /** Corresponds to Sql_condition:enum_warning_level. */
353 enum ib_log_level_t {
354 	IB_LOG_LEVEL_INFO,
355 	IB_LOG_LEVEL_WARN,
356 	IB_LOG_LEVEL_ERROR,
357 	IB_LOG_LEVEL_FATAL
358 };
359 
360 /******************************************************************//**
361 Use this when the args are first converted to a formatted string and then
362 passed to the format string from errmsg-utf8.txt. The error message format
363 must be: "Some string ... %s".
364 
365 Push a warning message to the client, it is a wrapper around:
366 
367 void push_warning_printf(
368 	THD *thd, Sql_condition::enum_warning_level level,
369 	uint code, const char *format, ...);
370 */
371 void
372 ib_errf(
373 /*====*/
374 	THD*		thd,		/*!< in/out: session */
375 	ib_log_level_t	level,		/*!< in: warning level */
376 	ib_uint32_t	code,		/*!< MySQL error code */
377 	const char*	format,		/*!< printf format */
378 	...)				/*!< Args */
379 	MY_ATTRIBUTE((format(printf, 4, 5)));
380 
381 /******************************************************************//**
382 Use this when the args are passed to the format string from
383 errmsg-utf8.txt directly as is.
384 
385 Push a warning message to the client, it is a wrapper around:
386 
387 void push_warning_printf(
388 	THD *thd, Sql_condition::enum_warning_level level,
389 	uint code, const char *format, ...);
390 */
391 void
392 ib_senderrf(
393 /*========*/
394 	THD*		thd,		/*!< in/out: session */
395 	ib_log_level_t	level,		/*!< in: warning level */
396 	ib_uint32_t	code,		/*!< MySQL error code */
397 	...);				/*!< Args */
398 
399 extern const char* 	TROUBLESHOOTING_MSG;
400 extern const char* 	TROUBLESHOOT_DATADICT_MSG;
401 extern const char* 	BUG_REPORT_MSG;
402 extern const char* 	FORCE_RECOVERY_MSG;
403 extern const char*      OPERATING_SYSTEM_ERROR_MSG;
404 extern const char*      FOREIGN_KEY_CONSTRAINTS_MSG;
405 extern const char*      SET_TRANSACTION_MSG;
406 extern const char*      INNODB_PARAMETERS_MSG;
407 
408 /******************************************************************//**
409 Returns the NUL terminated value of glob_hostname.
410 @return pointer to glob_hostname. */
411 const char*
412 server_get_hostname();
413 /*=================*/
414 
415 /*********************************************************************//**
416 Compute the next autoinc value.
417 
418 For MySQL replication the autoincrement values can be partitioned among
419 the nodes. The offset is the start or origin of the autoincrement value
420 for a particular node. For n nodes the increment will be n and the offset
421 will be in the interval [1, n]. The formula tries to allocate the next
422 value for a particular node.
423 
424 Note: This function is also called with increment set to the number of
425 values we want to reserve for multi-value inserts e.g.,
426 
427 	INSERT INTO T VALUES(), (), ();
428 
429 innobase_next_autoinc() will be called with increment set to 3 where
430 autoinc_lock_mode != TRADITIONAL because we want to reserve 3 values for
431 the multi-value INSERT above.
432 @return the next value */
433 ulonglong
434 innobase_next_autoinc(
435 /*==================*/
436 	ulonglong	current,	/*!< in: Current value */
437 	ulonglong	need,		/*!< in: count of values needed */
438 	ulonglong	step,		/*!< in: AUTOINC increment step */
439 	ulonglong	offset,		/*!< in: AUTOINC offset */
440 	ulonglong	max_value)	/*!< in: max value for type */
441 	MY_ATTRIBUTE((pure, warn_unused_result));
442 
443 /**********************************************************************
444 Converts an identifier from my_charset_filename to UTF-8 charset. */
445 uint
446 innobase_convert_to_system_charset(
447 /*===============================*/
448 	char*           to,		/* out: converted identifier */
449 	const char*     from,		/* in: identifier to convert */
450 	ulint           len,		/* in: length of 'to', in bytes */
451 	uint*		errors);	/* out: error return */
452 /**********************************************************************
453 Check if the length of the identifier exceeds the maximum allowed.
454 The input to this function is an identifier in charset my_charset_filename.
455 return true when length of identifier is too long. */
456 my_bool
457 innobase_check_identifier_length(
458 /*=============================*/
459 	const char*	id);	/* in: identifier to check.  it must belong
460 				to charset my_charset_filename */
461 
462 /**********************************************************************
463 Converts an identifier from my_charset_filename to UTF-8 charset. */
464 uint
465 innobase_convert_to_system_charset(
466 /*===============================*/
467 	char*		to,		/* out: converted identifier */
468 	const char*	from,		/* in: identifier to convert */
469 	ulint		len,		/* in: length of 'to', in bytes */
470 	uint*		errors);	/* out: error return */
471 
472 /**********************************************************************
473 Converts an identifier from my_charset_filename to UTF-8 charset. */
474 uint
475 innobase_convert_to_filename_charset(
476 /*=================================*/
477 	char*		to,	/* out: converted identifier */
478 	const char*	from,	/* in: identifier to convert */
479 	ulint		len);	/* in: length of 'to', in bytes */
480 
481 /********************************************************************//**
482 Helper function to push warnings from InnoDB internals to SQL-layer. */
483 UNIV_INTERN
484 void
485 ib_push_warning(
486 	trx_t*		trx,	/*!< in: trx */
487 	dberr_t		error,	/*!< in: error code to push as warning */
488 	const char	*format,/*!< in: warning message */
489 	...);
490 
491 /********************************************************************//**
492 Helper function to push warnings from InnoDB internals to SQL-layer. */
493 UNIV_INTERN
494 void
495 ib_push_warning(
496 	void*		ithd,	/*!< in: thd */
497 	dberr_t		error,	/*!< in: error code to push as warning */
498 	const char	*format,/*!< in: warning message */
499 	...);
500 
501 /*****************************************************************//**
502 Normalizes a table name string. A normalized name consists of the
503 database name catenated to '/' and table name. An example:
504 test/mytable. On Windows normalization puts both the database name and the
505 table name always to lower case if "set_lower_case" is set to TRUE. */
506 void
507 normalize_table_name_c_low(
508 /*=======================*/
509 	char*		norm_name,	/*!< out: normalized name as a
510 					null-terminated string */
511 	const char*	name,		/*!< in: table name string */
512 	ibool		set_lower_case); /*!< in: TRUE if we want to set
513 					name to lower case */
514 /*************************************************************//**
515 InnoDB index push-down condition check defined in ha_innodb.cc
516 @return ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */
517 
518 #include <my_compare.h>
519 
520 ICP_RESULT
521 innobase_index_cond(
522 /*================*/
523 	void*	file)	/*!< in/out: pointer to ha_innobase */
524 	MY_ATTRIBUTE((warn_unused_result));
525 
526 /** Update the system variable with the given value of the InnoDB
527 buffer pool size.
528 @param[in]	buf_pool_size	given value of buffer pool size.*/
529 void
530 innodb_set_buf_pool_size(ulonglong buf_pool_size);
531 
532 /** Create a MYSQL_THD for a background thread and mark it as such.
533 @param name thread info for SHOW PROCESSLIST
534 @return new MYSQL_THD */
535 MYSQL_THD
536 innobase_create_background_thd(const char* name);
537 
538 /** Destroy a background purge thread THD.
539 @param[in]	thd	MYSQL_THD to destroy */
540 void
541 innobase_destroy_background_thd(MYSQL_THD);
542 
543 /** Close opened tables, free memory, delete items for a MYSQL_THD.
544 @param[in]	thd	MYSQL_THD to reset */
545 void
546 innobase_reset_background_thd(MYSQL_THD);
547 
548 #endif /* !UNIV_INNOCHECKSUM */
549 #endif /* HA_INNODB_PROTOTYPES_H */
550