ha_innodb.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:165k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & Innobase Oy
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. /* This file defines the InnoDB handler: the interface between MySQL and
  14. InnoDB
  15. NOTE: You can only use noninlined InnoDB functions in this file, because we
  16. have disables the InnoDB inlining in this file. */
  17. /* TODO list for the InnoDB handler in 4.1:
  18.   - Remove the flag innodb_active_trans from thd and replace it with a
  19.     function call innodb_active_trans(thd), which looks at the InnoDB
  20.     trx struct state field
  21.   - Find out what kind of problems the OS X case-insensitivity causes to
  22.     table and database names; should we 'normalize' the names like we do
  23.     in Windows?
  24. */
  25. #ifdef USE_PRAGMA_IMPLEMENTATION
  26. #pragma implementation // gcc: Class implementation
  27. #endif
  28. #include "mysql_priv.h"
  29. #include "slave.h"
  30. #ifdef HAVE_INNOBASE_DB
  31. #include <m_ctype.h>
  32. #include <hash.h>
  33. #include <myisampack.h>
  34. #include <mysys_err.h>
  35. #include <my_sys.h>
  36. #define MAX_ULONG_BIT ((ulong) 1 << (sizeof(ulong)*8-1))
  37. #include "ha_innodb.h"
  38. pthread_mutex_t innobase_mutex;
  39. bool innodb_inited= 0;
  40. /* Store MySQL definition of 'byte': in Linux it is char while InnoDB
  41. uses unsigned char; the header univ.i which we include next defines
  42. 'byte' as a macro which expands to 'unsigned char' */
  43. typedef byte mysql_byte;
  44. #define INSIDE_HA_INNOBASE_CC
  45. /* Include necessary InnoDB headers */
  46. extern "C" {
  47. #include "../innobase/include/univ.i"
  48. #include "../innobase/include/os0file.h"
  49. #include "../innobase/include/os0thread.h"
  50. #include "../innobase/include/srv0start.h"
  51. #include "../innobase/include/srv0srv.h"
  52. #include "../innobase/include/trx0roll.h"
  53. #include "../innobase/include/trx0trx.h"
  54. #include "../innobase/include/trx0sys.h"
  55. #include "../innobase/include/mtr0mtr.h"
  56. #include "../innobase/include/row0ins.h"
  57. #include "../innobase/include/row0mysql.h"
  58. #include "../innobase/include/row0sel.h"
  59. #include "../innobase/include/row0upd.h"
  60. #include "../innobase/include/log0log.h"
  61. #include "../innobase/include/lock0lock.h"
  62. #include "../innobase/include/dict0crea.h"
  63. #include "../innobase/include/btr0cur.h"
  64. #include "../innobase/include/btr0btr.h"
  65. #include "../innobase/include/fsp0fsp.h"
  66. #include "../innobase/include/sync0sync.h"
  67. #include "../innobase/include/fil0fil.h"
  68. }
  69. #define HA_INNOBASE_ROWS_IN_TABLE 10000 /* to get optimization right */
  70. #define HA_INNOBASE_RANGE_COUNT   100
  71. uint  innobase_init_flags  = 0;
  72. ulong  innobase_cache_size  = 0;
  73. /* The default values for the following, type long, start-up parameters
  74. are declared in mysqld.cc: */
  75. long innobase_mirrored_log_groups, innobase_log_files_in_group,
  76.      innobase_log_file_size, innobase_log_buffer_size,
  77.      innobase_buffer_pool_awe_mem_mb,
  78.      innobase_buffer_pool_size, innobase_additional_mem_pool_size,
  79.      innobase_file_io_threads, innobase_lock_wait_timeout,
  80.      innobase_thread_concurrency, innobase_force_recovery,
  81.      innobase_open_files;
  82. /* The default values for the following char* start-up parameters
  83. are determined in innobase_init below: */
  84.   
  85. char* innobase_data_home_dir = NULL;
  86. char* innobase_data_file_path  = NULL;
  87. char* innobase_log_group_home_dir = NULL;
  88. char* innobase_log_arch_dir = NULL;/* unused */
  89. /* The following has a misleading name: starting from 4.0.5, this also
  90. affects Windows: */
  91. char* innobase_unix_file_flush_method = NULL;
  92. /* Below we have boolean-valued start-up parameters, and their default
  93. values */
  94. uint innobase_flush_log_at_trx_commit = 1;
  95. my_bool innobase_log_archive = FALSE;/* unused */
  96. my_bool innobase_use_native_aio = FALSE;
  97. my_bool innobase_fast_shutdown = TRUE;
  98. my_bool innobase_very_fast_shutdown = FALSE; /* this can be set to
  99.  1 just prior calling
  100.  innobase_end() */
  101. my_bool innobase_file_per_table = FALSE;
  102. my_bool innobase_locks_unsafe_for_binlog        = FALSE;
  103. my_bool innobase_create_status_file = FALSE;
  104. static char *internal_innobase_data_file_path = NULL;
  105. /* The following counter is used to convey information to InnoDB
  106. about server activity: in selects it is not sensible to call
  107. srv_active_wake_master_thread after each fetch or search, we only do
  108. it every INNOBASE_WAKE_INTERVAL'th step. */
  109. #define INNOBASE_WAKE_INTERVAL 32
  110. ulong innobase_active_counter = 0;
  111. char* innobase_home  = NULL;
  112. char    innodb_dummy_stmt_trx_handle = 'D';
  113. static HASH  innobase_open_tables;
  114. #ifdef __NETWARE__   /* some special cleanup for NetWare */
  115. bool nw_panic = FALSE;
  116. #endif
  117. static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
  118.       my_bool not_used __attribute__((unused)));
  119. static INNOBASE_SHARE *get_share(const char *table_name);
  120. static void free_share(INNOBASE_SHARE *share);
  121. /* General functions */
  122. /**********************************************************************
  123. Save some CPU by testing the value of srv_thread_concurrency in inline
  124. functions. */
  125. inline
  126. void
  127. innodb_srv_conc_enter_innodb(
  128. /*=========================*/
  129. trx_t* trx) /* in: transaction handle */
  130. {
  131. if (srv_thread_concurrency >= 500) {
  132. return;
  133. }
  134. srv_conc_enter_innodb(trx);
  135. }
  136. /**********************************************************************
  137. Save some CPU by testing the value of srv_thread_concurrency in inline
  138. functions. */
  139. inline
  140. void
  141. innodb_srv_conc_exit_innodb(
  142. /*========================*/
  143. trx_t* trx) /* in: transaction handle */
  144. {
  145. if (srv_thread_concurrency >= 500) {
  146. return;
  147. }
  148. srv_conc_exit_innodb(trx);
  149. }
  150. /**********************************************************************
  151. Releases possible search latch and InnoDB thread FIFO ticket. These should
  152. be released at each SQL statement end, and also when mysqld passes the
  153. control to the client. It does no harm to release these also in the middle
  154. of an SQL statement. */
  155. inline
  156. void
  157. innobase_release_stat_resources(
  158. /*============================*/
  159. trx_t* trx) /* in: transaction object */
  160. {
  161. if (trx->has_search_latch) {
  162. trx_search_latch_release_if_reserved(trx);
  163. }
  164. if (trx->declared_to_be_inside_innodb) {
  165. /* Release our possible ticket in the FIFO */
  166. srv_conc_force_exit_innodb(trx);
  167. }
  168. }
  169. /************************************************************************
  170. Call this function when mysqld passes control to the client. That is to
  171. avoid deadlocks on the adaptive hash S-latch possibly held by thd. For more
  172. documentation, see handler.cc. */
  173. void
  174. innobase_release_temporary_latches(
  175. /*===============================*/
  176.         void*   innobase_tid)
  177. {
  178.         innobase_release_stat_resources((trx_t*)innobase_tid);
  179. }
  180. /************************************************************************
  181. Increments innobase_active_counter and every INNOBASE_WAKE_INTERVALth
  182. time calls srv_active_wake_master_thread. This function should be used
  183. when a single database operation may introduce a small need for
  184. server utility activity, like checkpointing. */
  185. inline
  186. void
  187. innobase_active_small(void)
  188. /*=======================*/
  189. {
  190. innobase_active_counter++;
  191. if ((innobase_active_counter % INNOBASE_WAKE_INTERVAL) == 0) {
  192. srv_active_wake_master_thread();
  193. }
  194. }
  195. /************************************************************************
  196. Converts an InnoDB error code to a MySQL error code and also tells to MySQL
  197. about a possible transaction rollback inside InnoDB caused by a lock wait
  198. timeout or a deadlock. */
  199. static
  200. int
  201. convert_error_code_to_mysql(
  202. /*========================*/
  203. /* out: MySQL error code */
  204. int error, /* in: InnoDB error code */
  205. THD* thd) /* in: user thread handle or NULL */
  206. {
  207. if (error == DB_SUCCESS) {
  208. return(0);
  209.    } else if (error == (int) DB_DUPLICATE_KEY) {
  210.      return(HA_ERR_FOUND_DUPP_KEY);
  211.   } else if (error == (int) DB_RECORD_NOT_FOUND) {
  212.      return(HA_ERR_NO_ACTIVE_RECORD);
  213.   } else if (error == (int) DB_ERROR) {
  214.      return(-1); /* unspecified error */
  215.   } else if (error == (int) DB_DEADLOCK) {
  216.   /* Since we rolled back the whole transaction, we must
  217.   tell it also to MySQL so that MySQL knows to empty the
  218.   cached binlog for this transaction */
  219.   if (thd) {
  220.   ha_rollback(thd);
  221.   }
  222.      return(HA_ERR_LOCK_DEADLOCK);
  223.   } else if (error == (int) DB_LOCK_WAIT_TIMEOUT) {
  224. /* Since we rolled back the whole transaction, we must
  225. tell it also to MySQL so that MySQL knows to empty the
  226. cached binlog for this transaction */
  227. if (thd) {
  228. ha_rollback(thd);
  229. }
  230.     return(HA_ERR_LOCK_WAIT_TIMEOUT);
  231.   } else if (error == (int) DB_NO_REFERENCED_ROW) {
  232.      return(HA_ERR_NO_REFERENCED_ROW);
  233.   } else if (error == (int) DB_ROW_IS_REFERENCED) {
  234.      return(HA_ERR_ROW_IS_REFERENCED);
  235.         } else if (error == (int) DB_CANNOT_ADD_CONSTRAINT) {
  236.      return(HA_ERR_CANNOT_ADD_FOREIGN);
  237.         } else if (error == (int) DB_CANNOT_DROP_CONSTRAINT) {
  238.      return(HA_ERR_ROW_IS_REFERENCED); /* TODO: This is a bit
  239. misleading, a new MySQL error
  240. code should be introduced */
  241.         } else if (error == (int) DB_COL_APPEARS_TWICE_IN_INDEX) {
  242.      return(HA_ERR_CRASHED);
  243.   } else if (error == (int) DB_OUT_OF_FILE_SPACE) {
  244.      return(HA_ERR_RECORD_FILE_FULL);
  245.   } else if (error == (int) DB_TABLE_IS_BEING_USED) {
  246.      return(HA_ERR_WRONG_COMMAND);
  247.   } else if (error == (int) DB_TABLE_NOT_FOUND) {
  248.      return(HA_ERR_KEY_NOT_FOUND);
  249.    } else if (error == (int) DB_TOO_BIG_RECORD) {
  250.      return(HA_ERR_TO_BIG_ROW);
  251.    } else if (error == (int) DB_CORRUPTION) {
  252.      return(HA_ERR_CRASHED);
  253.    } else if (error == (int) DB_NO_SAVEPOINT) {
  254.      return(HA_ERR_NO_SAVEPOINT);
  255.    } else if (error == (int) DB_LOCK_TABLE_FULL) {
  256.      return(HA_ERR_LOCK_TABLE_FULL);
  257.      } else {
  258.      return(-1); // Unknown error
  259.      }
  260. }
  261. /*****************************************************************
  262. If you want to print a thd that is not associated with the current thread,
  263. you must call this function before reserving the InnoDB kernel_mutex, to
  264. protect MySQL from setting thd->query NULL. If you print a thd of the current
  265. thread, we know that MySQL cannot modify thd->query, and it is not necessary
  266. to call this. Call innobase_mysql_end_print_arbitrary_thd() after you release
  267. the kernel_mutex.
  268. NOTE that /mysql/innobase/lock/lock0lock.c must contain the prototype for this
  269. function! */
  270. extern "C"
  271. void
  272. innobase_mysql_prepare_print_arbitrary_thd(void)
  273. /*============================================*/
  274. {
  275. VOID(pthread_mutex_lock(&LOCK_thread_count));
  276. }
  277. /*****************************************************************
  278. Relases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
  279. NOTE that /mysql/innobase/lock/lock0lock.c must contain the prototype for this
  280. function! */
  281. extern "C"
  282. void
  283. innobase_mysql_end_print_arbitrary_thd(void)
  284. /*========================================*/
  285. {
  286. VOID(pthread_mutex_unlock(&LOCK_thread_count));
  287. }
  288. /*****************************************************************
  289. Prints info of a THD object (== user session thread) to the
  290. standard output. NOTE that /mysql/innobase/trx/trx0trx.c must contain
  291. the prototype for this function! */
  292. extern "C"
  293. void
  294. innobase_mysql_print_thd(
  295. /*=====================*/
  296. FILE*   f, /* in: output stream */
  297.         void*   input_thd)/* in: pointer to a MySQL THD object */
  298. {
  299. const THD* thd;
  300. const char* s;
  301. char buf[301];
  302.         thd = (const THD*) input_thd;
  303.    fprintf(f, "MySQL thread id %lu, query id %lu",
  304. thd->thread_id, thd->query_id);
  305. if (thd->host) {
  306. putc(' ', f);
  307. fputs(thd->host, f);
  308. }
  309. if (thd->ip) {
  310. putc(' ', f);
  311. fputs(thd->ip, f);
  312. }
  313.    if (thd->user) {
  314. putc(' ', f);
  315. fputs(thd->user, f);
  316.    }
  317. if ((s = thd->proc_info)) {
  318. putc(' ', f);
  319. fputs(s, f);
  320. }
  321. if ((s = thd->query)) {
  322. /* determine the length of the query string */
  323. uint32 i, len;
  324. len = thd->query_length;
  325. if (len > 300) {
  326. len = 300; /* ADDITIONAL SAFETY: print at most
  327. 300 chars to reduce the probability of
  328. a seg fault if there is a race in
  329. thd->query_length in MySQL; after
  330. May 14, 2004 probably no race any more,
  331. but better be safe */
  332. }
  333.                 /* Use strmake to reduce the timeframe
  334.                    for a race, compared to fwrite() */
  335. i= (uint) (strmake(buf, s, len) - buf);
  336. putc('n', f);
  337. fwrite(buf, 1, i, f);
  338. }
  339. putc('n', f);
  340. }
  341. /**********************************************************************
  342. Compares NUL-terminated UTF-8 strings case insensitively.
  343. NOTE that the exact prototype of this function has to be in
  344. /innobase/dict/dict0dict.c! */
  345. extern "C"
  346. int
  347. innobase_strcasecmp(
  348. /*================*/
  349. /* out: 0 if a=b, <0 if a<b, >1 if a>b */
  350. const char* a, /* in: first string to compare */
  351. const char* b) /* in: second string to compare */
  352. {
  353. return(my_strcasecmp(system_charset_info, a, b));
  354. }
  355. /**********************************************************************
  356. Makes all characters in a NUL-terminated UTF-8 string lower case.
  357. NOTE that the exact prototype of this function has to be in
  358. /innobase/dict/dict0dict.c! */
  359. extern "C"
  360. void
  361. innobase_casedn_str(
  362. /*================*/
  363. char* a) /* in/out: string to put in lower case */
  364. {
  365. my_casedn_str(system_charset_info, a);
  366. }
  367. /*************************************************************************
  368. Creates a temporary file. */
  369. extern "C"
  370. int
  371. innobase_mysql_tmpfile(void)
  372. /*========================*/
  373. /* out: temporary file descriptor, or < 0 on error */
  374. {
  375. char filename[FN_REFLEN];
  376. int fd2 = -1;
  377. File fd = create_temp_file(filename, mysql_tmpdir, "ib",
  378. #ifdef __WIN__
  379. O_BINARY | O_TRUNC | O_SEQUENTIAL |
  380. O_TEMPORARY | O_SHORT_LIVED |
  381. #endif /* __WIN__ */
  382. O_CREAT | O_EXCL | O_RDWR,
  383. MYF(MY_WME));
  384. if (fd >= 0) {
  385. #ifndef __WIN__
  386. /* On Windows, open files cannot be removed, but files can be
  387. created with the O_TEMPORARY flag to the same effect
  388. ("delete on close"). */
  389. unlink(filename);
  390. #endif /* !__WIN__ */
  391. /* Copy the file descriptor, so that the additional resources
  392. allocated by create_temp_file() can be freed by invoking
  393. my_close().
  394. Because the file descriptor returned by this function
  395. will be passed to fdopen(), it will be closed by invoking
  396. fclose(), which in turn will invoke close() instead of
  397. my_close(). */
  398. fd2 = dup(fd);
  399. if (fd2 < 0) {
  400. DBUG_PRINT("error",("Got error %d on dup",fd2));
  401. my_errno=errno;
  402. my_error(EE_OUT_OF_FILERESOURCES,
  403. MYF(ME_BELL+ME_WAITTANG), filename, my_errno);
  404. }
  405. my_close(fd, MYF(MY_WME));
  406. }
  407. return(fd2);
  408. }
  409. /*************************************************************************
  410. Gets the InnoDB transaction handle for a MySQL handler object, creates
  411. an InnoDB transaction struct if the corresponding MySQL thread struct still
  412. lacks one. */
  413. static
  414. trx_t*
  415. check_trx_exists(
  416. /*=============*/
  417. /* out: InnoDB transaction handle */
  418. THD* thd) /* in: user thread handle */
  419. {
  420. trx_t* trx;
  421. ut_ad(thd == current_thd);
  422. trx = (trx_t*) thd->transaction.all.innobase_tid;
  423. if (trx == NULL) {
  424.         DBUG_ASSERT(thd != NULL);
  425. trx = trx_allocate_for_mysql();
  426. trx->mysql_thd = thd;
  427. trx->mysql_query_str = &((*thd).query);
  428. thd->transaction.all.innobase_tid = trx;
  429. /* The execution of a single SQL statement is denoted by
  430. a 'transaction' handle which is a dummy pointer: InnoDB
  431. remembers internally where the latest SQL statement
  432. started, and if error handling requires rolling back the
  433. latest statement, InnoDB does a rollback to a savepoint. */
  434. thd->transaction.stmt.innobase_tid =
  435.                   (void*)&innodb_dummy_stmt_trx_handle;
  436. } else {
  437. if (trx->magic_n != TRX_MAGIC_N) {
  438. mem_analyze_corruption((byte*)trx);
  439. ut_a(0);
  440. }
  441. }
  442. if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) {
  443. trx->check_foreigns = FALSE;
  444. } else {
  445. trx->check_foreigns = TRUE;
  446. }
  447. if (thd->options & OPTION_RELAXED_UNIQUE_CHECKS) {
  448. trx->check_unique_secondary = FALSE;
  449. } else {
  450. trx->check_unique_secondary = TRUE;
  451. }
  452. return(trx);
  453. }
  454. /*************************************************************************
  455. Updates the user_thd field in a handle and also allocates a new InnoDB
  456. transaction handle if needed, and updates the transaction fields in the
  457. prebuilt struct. */
  458. inline
  459. int
  460. ha_innobase::update_thd(
  461. /*====================*/
  462. /* out: 0 or error code */
  463. THD* thd) /* in: thd to use the handle */
  464. {
  465. row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
  466. trx_t* trx;
  467. trx = check_trx_exists(thd);
  468. if (prebuilt->trx != trx) {
  469. row_update_prebuilt_trx(prebuilt, trx);
  470. }
  471. user_thd = thd;
  472. return(0);
  473. }
  474. /*   BACKGROUND INFO: HOW THE MYSQL QUERY CACHE WORKS WITH INNODB
  475.      ------------------------------------------------------------
  476. 1) The use of the query cache for TBL is disabled when there is an
  477. uncommitted change to TBL.
  478. 2) When a change to TBL commits, InnoDB stores the current value of
  479. its global trx id counter, let us denote it by INV_TRX_ID, to the table object
  480. in the InnoDB data dictionary, and does only allow such transactions whose
  481. id <= INV_TRX_ID to use the query cache.
  482. 3) When InnoDB does an INSERT/DELETE/UPDATE to a table TBL, or an implicit
  483. modification because an ON DELETE CASCADE, we invalidate the MySQL query cache
  484. of TBL immediately.
  485. How this is implemented inside InnoDB:
  486. 1) Since every modification always sets an IX type table lock on the InnoDB
  487. table, it is easy to check if there can be uncommitted modifications for a
  488. table: just check if there are locks in the lock list of the table.
  489. 2) When a transaction inside InnoDB commits, it reads the global trx id
  490. counter and stores the value INV_TRX_ID to the tables on which it had a lock.
  491. 3) If there is an implicit table change from ON DELETE CASCADE or SET NULL,
  492. InnoDB calls an invalidate method for the MySQL query cache for that table.
  493. How this is implemented inside sql_cache.cc:
  494. 1) The query cache for an InnoDB table TBL is invalidated immediately at an
  495. INSERT/UPDATE/DELETE, just like in the case of MyISAM. No need to delay
  496. invalidation to the transaction commit.
  497. 2) To store or retrieve a value from the query cache of an InnoDB table TBL,
  498. any query must first ask InnoDB's permission. We must pass the thd as a
  499. parameter because InnoDB will look at the trx id, if any, associated with
  500. that thd.
  501. 3) Use of the query cache for InnoDB tables is now allowed also when
  502. AUTOCOMMIT==0 or we are inside BEGIN ... COMMIT. Thus transactions no longer
  503. put restrictions on the use of the query cache.
  504. */
  505. /**********************************************************************
  506. The MySQL query cache uses this to check from InnoDB if the query cache at
  507. the moment is allowed to operate on an InnoDB table. The SQL query must
  508. be a non-locking SELECT.
  509. The query cache is allowed to operate on certain query only if this function
  510. returns TRUE for all tables in the query.
  511. If thd is not in the autocommit state, this function also starts a new
  512. transaction for thd if there is no active trx yet, and assigns a consistent
  513. read view to it if there is no read view yet. */
  514. my_bool
  515. innobase_query_caching_of_table_permitted(
  516. /*======================================*/
  517. /* out: TRUE if permitted, FALSE if not;
  518. note that the value FALSE does not mean
  519. we should invalidate the query cache:
  520. invalidation is called explicitly */
  521. THD* thd, /* in: thd of the user who is trying to
  522. store a result to the query cache or
  523. retrieve it */
  524. char* full_name, /* in: concatenation of database name,
  525. the null character '', and the table
  526. name */
  527. uint full_name_len) /* in: length of the full name, i.e.
  528. len(dbname) + len(tablename) + 1 */
  529. {
  530. ibool is_autocommit;
  531. trx_t* trx;
  532. char norm_name[1000];
  533. ut_a(full_name_len < 999);
  534. if (thd->variables.tx_isolation == ISO_SERIALIZABLE) {
  535. /* In the SERIALIZABLE mode we add LOCK IN SHARE MODE to every
  536. plain SELECT if AUTOCOMMIT is not on. */
  537. return((my_bool)FALSE);
  538. }
  539. trx = (trx_t*) thd->transaction.all.innobase_tid;
  540. if (trx == NULL) {
  541. trx = check_trx_exists(thd);
  542. }
  543. innobase_release_stat_resources(trx);
  544. if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
  545. is_autocommit = TRUE;
  546. } else {
  547. is_autocommit = FALSE;
  548. }
  549. if (is_autocommit && trx->n_mysql_tables_in_use == 0) {
  550. /* We are going to retrieve the query result from the query
  551. cache. This cannot be a store operation to the query cache
  552. because then MySQL would have locks on tables already.
  553. TODO: if the user has used LOCK TABLES to lock the table,
  554. then we open a transaction in the call of row_.. below.
  555. That trx can stay open until UNLOCK TABLES. The same problem
  556. exists even if we do not use the query cache. MySQL should be
  557. modified so that it ALWAYS calls some cleanup function when
  558. the processing of a query ends!
  559. We can imagine we instantaneously serialize this consistent
  560. read trx to the current trx id counter. If trx2 would have
  561. changed the tables of a query result stored in the cache, and
  562. trx2 would have already committed, making the result obsolete,
  563. then trx2 would have already invalidated the cache. Thus we
  564. can trust the result in the cache is ok for this query. */
  565. return((my_bool)TRUE);
  566. }
  567. /* Normalize the table name to InnoDB format */
  568. memcpy(norm_name, full_name, full_name_len);
  569. norm_name[strlen(norm_name)] = '/'; /* InnoDB uses '/' as the
  570.     separator between db and table */
  571. norm_name[full_name_len] = '';
  572. #ifdef __WIN__
  573. innobase_casedn_str(norm_name);
  574. #endif
  575. /* The call of row_search_.. will start a new transaction if it is
  576. not yet started */
  577. thd->transaction.all.innodb_active_trans = 1;
  578. if (row_search_check_if_query_cache_permitted(trx, norm_name)) {
  579. /* printf("Query cache for %s permittedn", norm_name); */
  580. return((my_bool)TRUE);
  581. }
  582. /* printf("Query cache for %s NOT permittedn", norm_name); */
  583. return((my_bool)FALSE);
  584. }
  585. /*********************************************************************
  586. Invalidates the MySQL query cache for the table.
  587. NOTE that the exact prototype of this function has to be in
  588. /innobase/row/row0ins.c! */
  589. extern "C"
  590. void
  591. innobase_invalidate_query_cache(
  592. /*============================*/
  593. trx_t* trx, /* in: transaction which modifies the table */
  594. char* full_name, /* in: concatenation of database name, null
  595. char '', table name, null char'';
  596. NOTE that in Windows this is always
  597. in LOWER CASE! */
  598. ulint full_name_len) /* in: full name length where also the null
  599. chars count */
  600. {
  601. /* Argument TRUE below means we are using transactions */
  602. #ifdef HAVE_QUERY_CACHE
  603. query_cache.invalidate((THD*)(trx->mysql_thd),
  604. (const char*)full_name,
  605. (uint32)full_name_len,
  606. TRUE);
  607. #endif
  608. }
  609. /*********************************************************************
  610. Get the quote character to be used in SQL identifiers.
  611. This definition must match the one in innobase/ut/ut0ut.c! */
  612. extern "C"
  613. int
  614. mysql_get_identifier_quote_char(
  615. /*============================*/
  616. /* out: quote character to be
  617. used in SQL identifiers; EOF if none */
  618. trx_t* trx, /* in: transaction */
  619. const char* name, /* in: name to print */
  620. ulint namelen)/* in: length of name */
  621. {
  622. if (!trx || !trx->mysql_thd) {
  623. return(EOF);
  624. }
  625. return(get_quote_char_for_identifier((THD*) trx->mysql_thd,
  626. name, namelen));
  627. }
  628. /**************************************************************************
  629. Obtain a pointer to the MySQL THD object, as in current_thd().  This
  630. definition must match the one in sql/ha_innodb.cc! */
  631. extern "C"
  632. void*
  633. innobase_current_thd(void)
  634. /*======================*/
  635. /* out: MySQL THD object */
  636. {
  637. return(current_thd);
  638. }
  639. /*********************************************************************
  640. Call this when you have opened a new table handle in HANDLER, before you
  641. call index_read_idx() etc. Actually, we can let the cursor stay open even
  642. over a transaction commit! Then you should call this before every operation,
  643. fetch next etc. This function inits the necessary things even after a
  644. transaction commit. */
  645. void
  646. ha_innobase::init_table_handle_for_HANDLER(void)
  647. /*============================================*/
  648. {
  649.         row_prebuilt_t* prebuilt;
  650.         /* If current thd does not yet have a trx struct, create one.
  651.         If the current handle does not yet have a prebuilt struct, create
  652.         one. Update the trx pointers in the prebuilt struct. Normally
  653.         this operation is done in external_lock. */
  654.         update_thd(current_thd);
  655.         /* Initialize the prebuilt struct much like it would be inited in
  656.         external_lock */
  657.         prebuilt = (row_prebuilt_t*)innobase_prebuilt;
  658. innobase_release_stat_resources(prebuilt->trx);
  659.         /* If the transaction is not started yet, start it */
  660.         trx_start_if_not_started_noninline(prebuilt->trx);
  661.         /* Assign a read view if the transaction does not have it yet */
  662.         trx_assign_read_view(prebuilt->trx);
  663. /* Set the MySQL flag to mark that there is an active transaction */
  664. current_thd->transaction.all.innodb_active_trans = 1;
  665.         /* We did the necessary inits in this function, no need to repeat them
  666.         in row_search_for_mysql */
  667.         prebuilt->sql_stat_start = FALSE;
  668.         /* We let HANDLER always to do the reads as consistent reads, even
  669.         if the trx isolation level would have been specified as SERIALIZABLE */
  670.         prebuilt->select_lock_type = LOCK_NONE;
  671.         prebuilt->stored_select_lock_type = LOCK_NONE;
  672.         /* Always fetch all columns in the index record */
  673.         prebuilt->hint_need_to_fetch_extra_cols = ROW_RETRIEVE_ALL_COLS;
  674.         /* We want always to fetch all columns in the whole row? Or do
  675. we???? */
  676.         prebuilt->read_just_key = FALSE;
  677. prebuilt->used_in_HANDLER = TRUE;
  678. }
  679. /*************************************************************************
  680. Opens an InnoDB database. */
  681. bool
  682. innobase_init(void)
  683. /*===============*/
  684. /* out: TRUE if error */
  685. {
  686. static char current_dir[3]; /* Set if using current lib */
  687. int err;
  688. bool ret;
  689. char          *default_path;
  690.    DBUG_ENTER("innobase_init");
  691.    os_innodb_umask = (ulint)my_umask;
  692. /* First calculate the default path for innodb_data_home_dir etc.,
  693. in case the user has not given any value.
  694. Note that when using the embedded server, the datadirectory is not
  695. necessarily the current directory of this program. */
  696. if (mysqld_embedded) {
  697. default_path = mysql_real_data_home;
  698. fil_path_to_mysql_datadir = mysql_real_data_home;
  699. } else {
  700.    /* It's better to use current lib, to keep paths short */
  701.    current_dir[0] = FN_CURLIB;
  702.    current_dir[1] = FN_LIBCHAR;
  703.    current_dir[2] = 0;
  704.    default_path = current_dir;
  705. }
  706. ut_a(default_path);
  707. if (specialflag & SPECIAL_NO_PRIOR) {
  708.         srv_set_thread_priorities = FALSE;
  709. } else {
  710.         srv_set_thread_priorities = TRUE;
  711.         srv_query_thread_priority = QUERY_PRIOR;
  712. }
  713. /* Set InnoDB initialization parameters according to the values
  714. read from MySQL .cnf file */
  715. /*--------------- Data files -------------------------*/
  716. /* The default dir for data files is the datadir of MySQL */
  717. srv_data_home = (innobase_data_home_dir ? innobase_data_home_dir :
  718.  default_path);
  719. /* Set default InnoDB data file size to 10 MB and let it be
  720.    auto-extending. Thus users can use InnoDB in >= 4.0 without having
  721. to specify any startup options. */
  722. if (!innobase_data_file_path) {
  723.    innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
  724. }
  725. /* Since InnoDB edits the argument in the next call, we make another
  726. copy of it: */
  727. internal_innobase_data_file_path = my_strdup(innobase_data_file_path,
  728.    MYF(MY_WME));
  729. ret = (bool) srv_parse_data_file_paths_and_sizes(
  730. internal_innobase_data_file_path,
  731. &srv_data_file_names,
  732. &srv_data_file_sizes,
  733. &srv_data_file_is_raw_partition,
  734. &srv_n_data_files,
  735. &srv_auto_extend_last_data_file,
  736. &srv_last_file_size_max);
  737. if (ret == FALSE) {
  738.    sql_print_error(
  739. "InnoDB: syntax error in innodb_data_file_path");
  740.    DBUG_RETURN(TRUE);
  741. }
  742. /* -------------- Log files ---------------------------*/
  743. /* The default dir for log files is the datadir of MySQL */
  744. if (!innobase_log_group_home_dir) {
  745.    innobase_log_group_home_dir = default_path;
  746. }
  747. #ifdef UNIV_LOG_ARCHIVE   
  748. /* Since innodb_log_arch_dir has no relevance under MySQL,
  749. starting from 4.0.6 we always set it the same as
  750. innodb_log_group_home_dir: */
  751. innobase_log_arch_dir = innobase_log_group_home_dir;
  752. srv_arch_dir = innobase_log_arch_dir;
  753. #endif /* UNIG_LOG_ARCHIVE */
  754. ret = (bool)
  755. srv_parse_log_group_home_dirs(innobase_log_group_home_dir,
  756. &srv_log_group_home_dirs);
  757. if (ret == FALSE || innobase_mirrored_log_groups != 1) {
  758. fprintf(stderr,
  759. "InnoDB: syntax error in innodb_log_group_home_dirn"
  760. "InnoDB: or a wrong number of mirrored log groupsn");
  761. DBUG_RETURN(TRUE);
  762. }
  763. /* --------------------------------------------------*/
  764. srv_file_flush_method_str = innobase_unix_file_flush_method;
  765. srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
  766. srv_n_log_files = (ulint) innobase_log_files_in_group;
  767. srv_log_file_size = (ulint) innobase_log_file_size;
  768. #ifdef UNIV_LOG_ARCHIVE
  769. srv_log_archive_on = (ulint) innobase_log_archive;
  770. #endif /* UNIV_LOG_ARCHIVE */
  771. srv_log_buffer_size = (ulint) innobase_log_buffer_size;
  772. srv_flush_log_at_trx_commit = (ulint) innobase_flush_log_at_trx_commit;
  773.         /* We set srv_pool_size here in units of 1 kB. InnoDB internally
  774.         changes the value so that it becomes the number of database pages. */
  775.         if (innobase_buffer_pool_awe_mem_mb == 0) {
  776.                 /* Careful here: we first convert the signed long int to ulint
  777.                 and only after that divide */
  778.  
  779.                 srv_pool_size = ((ulint) innobase_buffer_pool_size) / 1024;
  780.         } else {
  781.                 srv_use_awe = TRUE;
  782.                 srv_pool_size = (ulint)
  783.                                 (1024 * innobase_buffer_pool_awe_mem_mb);
  784.                 srv_awe_window_size = (ulint) innobase_buffer_pool_size;
  785.  
  786.                 /* Note that what the user specified as
  787.                 innodb_buffer_pool_size is actually the AWE memory window
  788.                 size in this case, and the real buffer pool size is
  789.                 determined by .._awe_mem_mb. */
  790.         }
  791. srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
  792. srv_n_file_io_threads = (ulint) innobase_file_io_threads;
  793. srv_lock_wait_timeout = (ulint) innobase_lock_wait_timeout;
  794. srv_thread_concurrency = (ulint) innobase_thread_concurrency;
  795. srv_force_recovery = (ulint) innobase_force_recovery;
  796. srv_fast_shutdown = (ibool) innobase_fast_shutdown;
  797. srv_file_per_table = (ibool) innobase_file_per_table;
  798.         srv_locks_unsafe_for_binlog = (ibool) innobase_locks_unsafe_for_binlog;
  799. srv_max_n_open_files = (ulint) innobase_open_files;
  800. srv_innodb_status = (ibool) innobase_create_status_file;
  801. srv_print_verbose_log = mysqld_embedded ? 0 : 1;
  802. /* Store the default charset-collation number of this MySQL
  803. installation */
  804. data_mysql_default_charset_coll = (ulint)default_charset_info->number;
  805. data_mysql_latin1_swedish_charset_coll =
  806. (ulint)my_charset_latin1.number;
  807. /* Store the latin1_swedish_ci character ordering table to InnoDB. For
  808. non-latin1_swedish_ci charsets we use the MySQL comparison functions,
  809. and consequently we do not need to know the ordering internally in
  810. InnoDB. */
  811. ut_a(0 == strcmp((char*)my_charset_latin1.name,
  812. (char*)"latin1_swedish_ci"));
  813. memcpy(srv_latin1_ordering, my_charset_latin1.sort_order, 256);
  814. /* Since we in this module access directly the fields of a trx
  815.         struct, and due to different headers and flags it might happen that
  816. mutex_t has a different size in this module and in InnoDB
  817. modules, we check at run time that the size is the same in
  818. these compilation modules. */
  819. srv_sizeof_trx_t_in_ha_innodb_cc = sizeof(trx_t);
  820. err = innobase_start_or_create_for_mysql();
  821. if (err != DB_SUCCESS) {
  822. DBUG_RETURN(1);
  823. }
  824. (void) hash_init(&innobase_open_tables,system_charset_info, 32, 0, 0,
  825.   (hash_get_key) innobase_get_key, 0, 0);
  826. pthread_mutex_init(&innobase_mutex, MY_MUTEX_INIT_FAST);
  827. innodb_inited= 1;
  828. /* If this is a replication slave and we needed to do a crash recovery,
  829. set the master binlog position to what InnoDB internally knew about
  830. how far we got transactions durable inside InnoDB. There is a
  831. problem here: if the user used also MyISAM tables, InnoDB might not
  832. know the right position for them.
  833. THIS DOES NOT WORK CURRENTLY because replication seems to initialize
  834. glob_mi also after innobase_init. */
  835. /* if (trx_sys_mysql_master_log_pos != -1) {
  836. ut_memcpy(glob_mi.log_file_name, trx_sys_mysql_master_log_name,
  837. 1 + ut_strlen(trx_sys_mysql_master_log_name));
  838. glob_mi.pos = trx_sys_mysql_master_log_pos;
  839. }
  840. */
  841.    DBUG_RETURN(0);
  842. }
  843. /***********************************************************************
  844. Closes an InnoDB database. */
  845. bool
  846. innobase_end(void)
  847. /*==============*/
  848. /* out: TRUE if error */
  849. {
  850. int err= 0;
  851. DBUG_ENTER("innobase_end");
  852. #ifdef __NETWARE__  /* some special cleanup for NetWare */
  853. if (nw_panic) {
  854. set_panic_flag_for_netware();
  855. }
  856. #endif
  857. if (innodb_inited)
  858. {
  859.   if (innobase_very_fast_shutdown) {
  860.     srv_very_fast_shutdown = TRUE;
  861.     fprintf(stderr,
  862. "InnoDB: MySQL has requested a very fast shutdown without flushingn"
  863. "InnoDB: the InnoDB buffer pool to data files. At the next mysqld startupn"
  864. "InnoDB: InnoDB will do a crash recovery!n");
  865.   }
  866.   innodb_inited= 0;
  867.   if (innobase_shutdown_for_mysql() != DB_SUCCESS)
  868.     err= 1;
  869.   hash_free(&innobase_open_tables);
  870.   my_free(internal_innobase_data_file_path,MYF(MY_ALLOW_ZERO_PTR));
  871.   pthread_mutex_destroy(&innobase_mutex);
  872. }
  873.    DBUG_RETURN(err);
  874. }
  875. /********************************************************************
  876. Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
  877. the logs, and the name of this function should be innobase_checkpoint. */
  878. bool
  879. innobase_flush_logs(void)
  880. /*=====================*/
  881. /* out: TRUE if error */
  882. {
  883.    bool  result = 0;
  884.    DBUG_ENTER("innobase_flush_logs");
  885. log_buffer_flush_to_disk();
  886.    DBUG_RETURN(result);
  887. }
  888. /*********************************************************************
  889. Commits a transaction in an InnoDB database. */
  890. void
  891. innobase_commit_low(
  892. /*================*/
  893. trx_t* trx) /* in: transaction handle */
  894. {
  895.         if (trx->conc_state == TRX_NOT_STARTED) {
  896.                 return;
  897.         }
  898. #ifdef HAVE_REPLICATION
  899.         if (current_thd->slave_thread) {
  900.                 /* Update the replication position info inside InnoDB */
  901.                 trx->mysql_master_log_file_name
  902.                                         = active_mi->rli.group_master_log_name;
  903.                 trx->mysql_master_log_pos= ((ib_longlong)
  904.                         active_mi->rli.future_group_master_log_pos);
  905.         }
  906. #endif /* HAVE_REPLICATION */
  907. trx_commit_for_mysql(trx);
  908. }
  909. /*********************************************************************
  910. Creates an InnoDB transaction struct for the thd if it does not yet have one.
  911. Starts a new InnoDB transaction if a transaction is not yet started. And
  912. assigns a new snapshot for a consistent read if the transaction does not yet
  913. have one. */
  914. int
  915. innobase_start_trx_and_assign_read_view(
  916. /*====================================*/
  917. /* out: 0 */
  918. THD* thd) /* in: MySQL thread handle of the user for whom
  919. the transaction should be committed */
  920. {
  921. trx_t* trx;
  922.    DBUG_ENTER("innobase_start_trx_and_assign_read_view");
  923. /* Create a new trx struct for thd, if it does not yet have one */
  924. trx = check_trx_exists(thd);
  925. /* This is just to play safe: release a possible FIFO ticket and
  926. search latch. Since we will reserve the kernel mutex, we have to
  927. release the search system latch first to obey the latching order. */
  928. innobase_release_stat_resources(trx);
  929. /* If the transaction is not started yet, start it */
  930. trx_start_if_not_started_noninline(trx);
  931. /* Assign a read view if the transaction does not have it yet */
  932. trx_assign_read_view(trx);
  933. /* Set the MySQL flag to mark that there is an active transaction */
  934. current_thd->transaction.all.innodb_active_trans = 1;
  935. DBUG_RETURN(0);
  936. }
  937. /*********************************************************************
  938. Commits a transaction in an InnoDB database or marks an SQL statement
  939. ended. */
  940. int
  941. innobase_commit(
  942. /*============*/
  943. /* out: 0 */
  944. THD* thd, /* in: MySQL thread handle of the user for whom
  945. the transaction should be committed */
  946. void* trx_handle)/* in: InnoDB trx handle or
  947. &innodb_dummy_stmt_trx_handle: the latter means
  948. that the current SQL statement ended */
  949. {
  950. trx_t* trx;
  951.    DBUG_ENTER("innobase_commit");
  952.    DBUG_PRINT("trans", ("ending transaction"));
  953. trx = check_trx_exists(thd);
  954. /* Release a possible FIFO ticket and search latch. Since we will
  955. reserve the kernel mutex, we have to release the search system latch
  956. first to obey the latching order. */
  957. innobase_release_stat_resources(trx);
  958. /* The flag thd->transaction.all.innodb_active_trans is set to 1 in
  959. 1. ::external_lock(),
  960. 2. ::start_stmt(),
  961. 3. innobase_query_caching_of_table_permitted(),
  962. 4. innobase_savepoint(),
  963. 5. ::init_table_handle_for_HANDLER(),
  964. 6. innobase_start_trx_and_assign_read_view()
  965. and it is only set to 0 in a commit or a rollback. If it is 0 we know
  966. there cannot be resources to be freed and we could return immediately.
  967. For the time being, we play safe and do the cleanup though there should
  968. be nothing to clean up. */
  969. if (thd->transaction.all.innodb_active_trans == 0
  970.     && trx->conc_state != TRX_NOT_STARTED) {
  971.     
  972.         fprintf(stderr,
  973. "InnoDB: Error: thd->transaction.all.innodb_active_trans == 0n"
  974. "InnoDB: but trx->conc_state != TRX_NOT_STARTEDn");
  975. }
  976. if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle
  977.     || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
  978.         
  979. /* We were instructed to commit the whole transaction, or
  980. this is an SQL statement end and autocommit is on */
  981. innobase_commit_low(trx);
  982. thd->transaction.all.innodb_active_trans = 0;
  983. } else {
  984.         /* We just mark the SQL statement ended and do not do a
  985. transaction commit */
  986. if (trx->auto_inc_lock) {
  987. /* If we had reserved the auto-inc lock for some
  988. table in this SQL statement we release it now */
  989.   
  990. row_unlock_table_autoinc_for_mysql(trx);
  991. }
  992. /* Store the current undo_no of the transaction so that we
  993. know where to roll back if we have to roll back the next
  994. SQL statement */
  995. trx_mark_sql_stat_end(trx);
  996. }
  997. /* Tell the InnoDB server that there might be work for utility
  998. threads: */
  999. srv_active_wake_master_thread();
  1000. DBUG_RETURN(0);
  1001. }
  1002. /*********************************************************************
  1003. This is called when MySQL writes the binlog entry for the current
  1004. transaction. Writes to the InnoDB tablespace info which tells where the
  1005. MySQL binlog entry for the current transaction ended. Also commits the
  1006. transaction inside InnoDB but does NOT flush InnoDB log files to disk.
  1007. To flush you have to call innobase_commit_complete(). We have separated
  1008. flushing to eliminate the bottleneck of LOCK_log in log.cc which disabled
  1009. InnoDB's group commit capability. */
  1010. int
  1011. innobase_report_binlog_offset_and_commit(
  1012. /*=====================================*/
  1013.                                 /* out: 0 */
  1014.         THD*    thd,            /* in: user thread */
  1015.         void*   trx_handle,     /* in: InnoDB trx handle */
  1016.         char*   log_file_name,  /* in: latest binlog file name */
  1017.         my_off_t end_offset)    /* in: the offset in the binlog file
  1018.                                    up to which we wrote */
  1019. {
  1020. trx_t* trx;
  1021. trx = (trx_t*)trx_handle;
  1022. ut_a(trx != NULL);
  1023. trx->mysql_log_file_name = log_file_name;  
  1024. trx->mysql_log_offset = (ib_longlong)end_offset;
  1025. trx->flush_log_later = TRUE;
  1026.    innobase_commit(thd, trx_handle);
  1027. trx->flush_log_later = FALSE;
  1028. return(0);
  1029. }
  1030. /*********************************************************************
  1031. This is called after MySQL has written the binlog entry for the current
  1032. transaction. Flushes the InnoDB log files to disk if required. */
  1033. int
  1034. innobase_commit_complete(
  1035. /*=====================*/
  1036.                                 /* out: 0 */
  1037.         void*   trx_handle)     /* in: InnoDB trx handle */
  1038. {
  1039. trx_t* trx;
  1040. if (srv_flush_log_at_trx_commit == 0) {
  1041.         return(0);
  1042. }
  1043. trx = (trx_t*)trx_handle;
  1044. ut_a(trx != NULL);
  1045.    trx_commit_complete_for_mysql(trx);
  1046. return(0);
  1047. }
  1048. /*********************************************************************
  1049. Rolls back a transaction or the latest SQL statement. */
  1050. int
  1051. innobase_rollback(
  1052. /*==============*/
  1053. /* out: 0 or error number */
  1054. THD* thd, /* in: handle to the MySQL thread of the user
  1055. whose transaction should be rolled back */
  1056. void* trx_handle)/* in: InnoDB trx handle or a dummy stmt handle;
  1057. the latter means we roll back the latest SQL
  1058. statement */
  1059. {
  1060. int error = 0;
  1061. trx_t* trx;
  1062. DBUG_ENTER("innobase_rollback");
  1063. DBUG_PRINT("trans", ("aborting transaction"));
  1064. trx = check_trx_exists(thd);
  1065. /* Release a possible FIFO ticket and search latch. Since we will
  1066. reserve the kernel mutex, we have to release the search system latch
  1067. first to obey the latching order. */
  1068. innobase_release_stat_resources(trx);
  1069.         if (trx->auto_inc_lock) {
  1070. /* If we had reserved the auto-inc lock for some table (if
  1071. we come here to roll back the latest SQL statement) we
  1072. release it now before a possibly lengthy rollback */
  1073. row_unlock_table_autoinc_for_mysql(trx);
  1074. }
  1075. if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle
  1076.     || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
  1077. error = trx_rollback_for_mysql(trx);
  1078. thd->transaction.all.innodb_active_trans = 0;
  1079. } else {
  1080. error = trx_rollback_last_sql_stat_for_mysql(trx);
  1081. }
  1082. DBUG_RETURN(convert_error_code_to_mysql(error, NULL));
  1083. }
  1084. /*********************************************************************
  1085. Rolls back a transaction to a savepoint. */
  1086. int
  1087. innobase_rollback_to_savepoint(
  1088. /*===========================*/
  1089. /* out: 0 if success, HA_ERR_NO_SAVEPOINT if
  1090. no savepoint with the given name */
  1091. THD* thd, /* in: handle to the MySQL thread of the user
  1092. whose transaction should be rolled back */
  1093. char* savepoint_name, /* in: savepoint name */
  1094. my_off_t* binlog_cache_pos)/* out: position which corresponds to the
  1095. savepoint in the binlog cache of this
  1096. transaction, not defined if error */
  1097. {
  1098. ib_longlong mysql_binlog_cache_pos;
  1099. int     error = 0;
  1100. trx_t*     trx;
  1101. DBUG_ENTER("innobase_rollback_to_savepoint");
  1102. trx = check_trx_exists(thd);
  1103. /* Release a possible FIFO ticket and search latch. Since we will
  1104. reserve the kernel mutex, we have to release the search system latch
  1105. first to obey the latching order. */
  1106. innobase_release_stat_resources(trx);
  1107. error = trx_rollback_to_savepoint_for_mysql(trx, savepoint_name,
  1108. &mysql_binlog_cache_pos);
  1109. *binlog_cache_pos = (my_off_t)mysql_binlog_cache_pos;
  1110. DBUG_RETURN(convert_error_code_to_mysql(error, NULL));
  1111. }
  1112. /*********************************************************************
  1113. Sets a transaction savepoint. */
  1114. int
  1115. innobase_savepoint(
  1116. /*===============*/
  1117. /* out: always 0, that is, always succeeds */
  1118. THD* thd, /* in: handle to the MySQL thread */
  1119. char* savepoint_name, /* in: savepoint name */
  1120. my_off_t binlog_cache_pos)/* in: offset up to which the current
  1121. transaction has cached log entries to its
  1122. binlog cache, not defined if no transaction
  1123. active, or we are in the autocommit state, or
  1124. binlogging is not switched on */
  1125. {
  1126. int error = 0;
  1127. trx_t* trx;
  1128. DBUG_ENTER("innobase_savepoint");
  1129. if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
  1130. /* In the autocommit state there is no sense to set a
  1131. savepoint: we return immediate success */
  1132.         DBUG_RETURN(0);
  1133. }
  1134. trx = check_trx_exists(thd);
  1135. /* Release a possible FIFO ticket and search latch. Since we will
  1136. reserve the kernel mutex, we have to release the search system latch
  1137. first to obey the latching order. */
  1138. innobase_release_stat_resources(trx);
  1139. /* Setting a savepoint starts a transaction inside InnoDB since
  1140. it allocates resources for it (memory to store the savepoint name,
  1141. for example) */
  1142. thd->transaction.all.innodb_active_trans = 1;
  1143. error = trx_savepoint_for_mysql(trx, savepoint_name,
  1144.      (ib_longlong)binlog_cache_pos);
  1145. DBUG_RETURN(convert_error_code_to_mysql(error, NULL));
  1146. }
  1147. /*********************************************************************
  1148. Frees a possible InnoDB trx object associated with the current THD. */
  1149. int
  1150. innobase_close_connection(
  1151. /*======================*/
  1152. /* out: 0 or error number */
  1153. THD* thd) /* in: handle to the MySQL thread of the user
  1154. whose transaction should be rolled back */
  1155. {
  1156. trx_t* trx;
  1157. trx = (trx_t*)thd->transaction.all.innobase_tid;
  1158. if (NULL != trx) {
  1159.         innobase_rollback(thd, (void*)trx);
  1160. trx_free_for_mysql(trx);
  1161. thd->transaction.all.innobase_tid = NULL;
  1162. }
  1163. return(0);
  1164. }
  1165. /*****************************************************************************
  1166. ** InnoDB database tables
  1167. *****************************************************************************/
  1168. /********************************************************************
  1169. Gives the file extension of an InnoDB single-table tablespace. */
  1170. const char**
  1171. ha_innobase::bas_ext() const
  1172. /*========================*/
  1173. /* out: file extension string */
  1174. {
  1175. static const char* ext[] = {".ibd", NullS};
  1176. return(ext);
  1177. }
  1178. /*********************************************************************
  1179. Normalizes a table name string. A normalized name consists of the
  1180. database name catenated to '/' and table name. An example:
  1181. test/mytable. On Windows normalization puts both the database name and the
  1182. table name always to lower case. */
  1183. static
  1184. void
  1185. normalize_table_name(
  1186. /*=================*/
  1187. char* norm_name, /* out: normalized name as a
  1188. null-terminated string */
  1189. const char* name) /* in: table name string */
  1190. {
  1191. char* name_ptr;
  1192. char* db_ptr;
  1193. char* ptr;
  1194. /* Scan name from the end */
  1195. ptr = strend(name)-1;
  1196. while (ptr >= name && *ptr != '\' && *ptr != '/') {
  1197. ptr--;
  1198. }
  1199. name_ptr = ptr + 1;
  1200. DBUG_ASSERT(ptr > name);
  1201. ptr--;
  1202. while (ptr >= name && *ptr != '\' && *ptr != '/') {
  1203. ptr--;
  1204. }
  1205. db_ptr = ptr + 1;
  1206. memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name));
  1207. norm_name[name_ptr - db_ptr - 1] = '/';
  1208. #ifdef __WIN__
  1209. innobase_casedn_str(norm_name);
  1210. #endif
  1211. }
  1212. /*********************************************************************
  1213. Creates and opens a handle to a table which already exists in an InnoDB
  1214. database. */
  1215. int
  1216. ha_innobase::open(
  1217. /*==============*/
  1218. /* out: 1 if error, 0 if success */
  1219. const char* name, /* in: table name */
  1220. int  mode, /* in: not used */
  1221. uint  test_if_locked) /* in: not used */
  1222. {
  1223. dict_table_t* ib_table;
  1224.    char norm_name[1000];
  1225. THD* thd;
  1226. DBUG_ENTER("ha_innobase::open");
  1227. UT_NOT_USED(mode);
  1228. UT_NOT_USED(test_if_locked);
  1229. thd = current_thd;
  1230. normalize_table_name(norm_name, name);
  1231. user_thd = NULL;
  1232. last_query_id = (ulong)-1;
  1233. if (!(share=get_share(name))) {
  1234. DBUG_RETURN(1);
  1235. }
  1236. /* Create buffers for packing the fields of a record. Why
  1237. table->reclength did not work here? Obviously, because char
  1238. fields when packed actually became 1 byte longer, when we also
  1239. stored the string length as the first byte. */
  1240. upd_and_key_val_buff_len = table->reclength + table->max_key_length
  1241. + MAX_REF_PARTS * 3;
  1242. if (!(mysql_byte*) my_multi_malloc(MYF(MY_WME),
  1243.      &upd_buff, upd_and_key_val_buff_len,
  1244.      &key_val_buff, upd_and_key_val_buff_len,
  1245.      NullS)) {
  1246.    free_share(share);
  1247.    DBUG_RETURN(1);
  1248.    }
  1249. /* Get pointer to a table object in InnoDB dictionary cache */
  1250. ib_table = dict_table_get_and_increment_handle_count(
  1251.             norm_name, NULL);
  1252.   if (NULL == ib_table) {
  1253.         ut_print_timestamp(stderr);
  1254.         fprintf(stderr, "  InnoDB error:n"
  1255. "Cannot find table %s from the internal data dictionaryn"
  1256. "of InnoDB though the .frm file for the table exists. Maybe youn"
  1257. "have deleted and recreated InnoDB data files but have forgottenn"
  1258. "to delete the corresponding .frm files of InnoDB tables, or youn"
  1259. "have moved .frm files to another database?n"
  1260. "Look from section 15.1 of http://www.innodb.com/ibman.htmln"
  1261. "how you can resolve the problem.n",
  1262.   norm_name);
  1263.         free_share(share);
  1264.      my_free((char*) upd_buff, MYF(0));
  1265.      my_errno = ENOENT;
  1266.      DBUG_RETURN(1);
  1267.    }
  1268.   if (ib_table->ibd_file_missing && !thd->tablespace_op) {
  1269.         ut_print_timestamp(stderr);
  1270.         fprintf(stderr, "  InnoDB error:n"
  1271. "MySQL is trying to open a table handle but the .ibd file forn"
  1272. "table %s does not exist.n"
  1273. "Have you deleted the .ibd file from the database directory undern"
  1274. "the MySQL datadir, or have you used DISCARD TABLESPACE?n"
  1275. "Look from section 15.1 of http://www.innodb.com/ibman.htmln"
  1276. "how you can resolve the problem.n",
  1277.   norm_name);
  1278.         free_share(share);
  1279.      my_free((char*) upd_buff, MYF(0));
  1280.      my_errno = ENOENT;
  1281. dict_table_decrement_handle_count(ib_table);
  1282.      DBUG_RETURN(1);
  1283.    }
  1284. innobase_prebuilt = row_create_prebuilt(ib_table);
  1285. ((row_prebuilt_t*)innobase_prebuilt)->mysql_row_len = table->reclength;
  1286. /* Looks like MySQL-3.23 sometimes has primary key number != 0 */
  1287.   primary_key = table->primary_key;
  1288. key_used_on_scan = primary_key;
  1289. /* Allocate a buffer for a 'row reference'. A row reference is
  1290. a string of bytes of length ref_length which uniquely specifies
  1291.         a row in our table. Note that MySQL may also compare two row
  1292.         references for equality by doing a simple memcmp on the strings
  1293.         of length ref_length! */
  1294.    if (!row_table_got_default_clust_index(ib_table)) {
  1295.         if (primary_key >= MAX_KEY) {
  1296.                 fprintf(stderr,
  1297.     "InnoDB: Error: table %s has a primary key in InnoDBn"
  1298.     "InnoDB: data dictionary, but not in MySQL!n", name);
  1299. }
  1300. ((row_prebuilt_t*)innobase_prebuilt)
  1301. ->clust_index_was_generated = FALSE;
  1302.   /*
  1303.   MySQL allocates the buffer for ref. key_info->key_length
  1304.   includes space for all key columns + one byte for each column
  1305.   that may be NULL. ref_length must be as exact as possible to
  1306.   save space, because all row reference buffers are allocated
  1307.   based on ref_length.
  1308. */
  1309.  
  1310.    ref_length = table->key_info[primary_key].key_length;
  1311. } else {
  1312.         if (primary_key != MAX_KEY) {
  1313.                 fprintf(stderr,
  1314.     "InnoDB: Error: table %s has no primary key in InnoDBn"
  1315.     "InnoDB: data dictionary, but has one in MySQL!n"
  1316.     "InnoDB: If you created the table with a MySQLn"
  1317.                     "InnoDB: version < 3.23.54 and did not define a primaryn"
  1318.                     "InnoDB: key, but defined a unique key with all non-NULLn"
  1319.                     "InnoDB: columns, then MySQL internally treats that keyn"
  1320.                     "InnoDB: as the primary key. You can fix this error byn"
  1321.     "InnoDB: dump + DROP + CREATE + reimport of the table.n",
  1322. name);
  1323. }
  1324. ((row_prebuilt_t*)innobase_prebuilt)
  1325. ->clust_index_was_generated = TRUE;
  1326.    ref_length = DATA_ROW_ID_LEN;
  1327. /*
  1328.   If we automatically created the clustered index, then
  1329.   MySQL does not know about it, and MySQL must NOT be aware
  1330.   of the index used on scan, to make it avoid checking if we
  1331.   update the column of the index. That is why we assert below
  1332.   that key_used_on_scan is the undefined value MAX_KEY.
  1333.   The column is the row id in the automatical generation case,
  1334.   and it will never be updated anyway.
  1335. */
  1336.        
  1337. if (key_used_on_scan != MAX_KEY) {
  1338.                 fprintf(stderr,
  1339. "InnoDB: Warning: table %s key_used_on_scan is %lu even though there is non"
  1340. "InnoDB: primary key inside InnoDB.n",
  1341. name, (ulong)key_used_on_scan);
  1342. }
  1343. }
  1344. auto_inc_counter_for_this_stat = 0;
  1345. block_size = 16 * 1024; /* Index block size in InnoDB: used by MySQL
  1346. in query optimization */
  1347. /* Init table lock structure */
  1348. thr_lock_data_init(&share->lock,&lock,(void*) 0);
  1349.    info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
  1350.    DBUG_RETURN(0);
  1351. }
  1352. /**********************************************************************
  1353. Closes a handle to an InnoDB table. */
  1354. int
  1355. ha_innobase::close(void)
  1356. /*====================*/
  1357. /* out: error number */
  1358. {
  1359.    DBUG_ENTER("ha_innobase::close");
  1360. row_prebuilt_free((row_prebuilt_t*) innobase_prebuilt);
  1361.      my_free((char*) upd_buff, MYF(0));
  1362.         free_share(share);
  1363. /* Tell InnoDB server that there might be work for
  1364. utility threads: */
  1365. srv_active_wake_master_thread();
  1366.    DBUG_RETURN(0);
  1367. }
  1368. /* The following accessor functions should really be inside MySQL code! */
  1369. /******************************************************************
  1370. Gets field offset for a field in a table. */
  1371. inline
  1372. uint
  1373. get_field_offset(
  1374. /*=============*/
  1375. /* out: offset */
  1376. TABLE* table, /* in: MySQL table object */
  1377. Field* field) /* in: MySQL field object */
  1378. {
  1379. return((uint) (field->ptr - (char*) table->record[0]));
  1380. }
  1381. /******************************************************************
  1382. Checks if a field in a record is SQL NULL. Uses the record format
  1383. information in table to track the null bit in record. */
  1384. inline
  1385. uint
  1386. field_in_record_is_null(
  1387. /*====================*/
  1388. /* out: 1 if NULL, 0 otherwise */
  1389. TABLE* table, /* in: MySQL table object */
  1390. Field* field, /* in: MySQL field object */
  1391. char* record) /* in: a row in MySQL format */
  1392. {
  1393. int null_offset;
  1394. if (!field->null_ptr) {
  1395. return(0);
  1396. }
  1397. null_offset = (uint) ((char*) field->null_ptr
  1398. - (char*) table->record[0]);
  1399. if (record[null_offset] & field->null_bit) {
  1400. return(1);
  1401. }
  1402. return(0);
  1403. }
  1404. /******************************************************************
  1405. Sets a field in a record to SQL NULL. Uses the record format
  1406. information in table to track the null bit in record. */
  1407. inline
  1408. void
  1409. set_field_in_record_to_null(
  1410. /*========================*/
  1411. TABLE* table, /* in: MySQL table object */
  1412. Field* field, /* in: MySQL field object */
  1413. char* record) /* in: a row in MySQL format */
  1414. {
  1415. int null_offset;
  1416. null_offset = (uint) ((char*) field->null_ptr
  1417. - (char*) table->record[0]);
  1418. record[null_offset] = record[null_offset] | field->null_bit;
  1419. }
  1420. /******************************************************************
  1421. Resets SQL NULL bits in a record to zero. */
  1422. inline
  1423. void
  1424. reset_null_bits(
  1425. /*============*/
  1426. TABLE* table, /* in: MySQL table object */
  1427. char* record) /* in: a row in MySQL format */
  1428. {
  1429. bzero(record, table->null_bytes);
  1430. }
  1431. extern "C" {
  1432. /*****************************************************************
  1433. InnoDB uses this function to compare two data fields for which the data type
  1434. is such that we must use MySQL code to compare them. NOTE that the prototype
  1435. of this function is in rem0cmp.c in InnoDB source code! If you change this
  1436. function, remember to update the prototype there! */
  1437. int
  1438. innobase_mysql_cmp(
  1439. /*===============*/
  1440. /* out: 1, 0, -1, if a is greater,
  1441. equal, less than b, respectively */
  1442. int mysql_type, /* in: MySQL type */
  1443. uint charset_number, /* in: number of the charset */
  1444. unsigned char* a, /* in: data field */
  1445. unsigned int a_length, /* in: data field length,
  1446. not UNIV_SQL_NULL */
  1447. unsigned char* b, /* in: data field */
  1448. unsigned int b_length) /* in: data field length,
  1449. not UNIV_SQL_NULL */
  1450. {
  1451. CHARSET_INFO* charset;
  1452. enum_field_types mysql_tp;
  1453. int                     ret;
  1454. DBUG_ASSERT(a_length != UNIV_SQL_NULL);
  1455. DBUG_ASSERT(b_length != UNIV_SQL_NULL);
  1456. mysql_tp = (enum_field_types) mysql_type;
  1457. switch (mysql_tp) {
  1458. case FIELD_TYPE_STRING:
  1459. case FIELD_TYPE_VAR_STRING:
  1460. case FIELD_TYPE_TINY_BLOB:
  1461. case FIELD_TYPE_MEDIUM_BLOB:
  1462. case FIELD_TYPE_BLOB:
  1463. case FIELD_TYPE_LONG_BLOB:
  1464. /* Use the charset number to pick the right charset struct for
  1465. the comparison. Since the MySQL function get_charset may be
  1466. slow before Bar removes the mutex operation there, we first
  1467. look at 2 common charsets directly. */
  1468. if (charset_number == default_charset_info->number) {
  1469. charset = default_charset_info;
  1470. } else if (charset_number == my_charset_latin1.number) {
  1471. charset = &my_charset_latin1;
  1472. } else {
  1473. charset = get_charset(charset_number, MYF(MY_WME));
  1474. if (charset == NULL) {
  1475. fprintf(stderr,
  1476. "InnoDB: fatal error: InnoDB needs charset %lu for doing a comparison,n"
  1477. "InnoDB: but MySQL cannot find that charset.n", (ulong)charset_number);
  1478. ut_a(0);
  1479. }
  1480. }
  1481.                 /* Starting from 4.1.3, we use strnncollsp() in comparisons of
  1482.                 non-latin1_swedish_ci strings. NOTE that the collation order
  1483.                 changes then: 'b...' is ordered BEFORE 'b  ...'. Users
  1484.                 having indexes on such data need to rebuild their tables! */
  1485.                 ret = charset->coll->strnncollsp(charset,
  1486.                                   a, a_length,
  1487.                                   b, b_length);
  1488. if (ret < 0) {
  1489.         return(-1);
  1490. } else if (ret > 0) {
  1491.         return(1);
  1492. } else {
  1493.         return(0);
  1494.         }
  1495. default:
  1496. assert(0);
  1497. }
  1498. return(0);
  1499. }
  1500. }
  1501. /******************************************************************
  1502. Converts a MySQL type to an InnoDB type. */
  1503. inline
  1504. ulint
  1505. get_innobase_type_from_mysql_type(
  1506. /*==============================*/
  1507. /* out: DATA_BINARY, DATA_VARCHAR, ... */
  1508. ulint* unsigned_flag, /* out: DATA_UNSIGNED if an 'unsigned type';
  1509. at least ENUM and SET, and unsigned integer
  1510. types are 'unsigned types' */
  1511. Field* field) /* in: MySQL field */
  1512. {
  1513. /* The following asserts try to check that the MySQL type code fits in
  1514. 8 bits: this is used in ibuf and also when DATA_NOT_NULL is ORed to
  1515. the type */
  1516. DBUG_ASSERT((ulint)FIELD_TYPE_STRING < 256);
  1517. DBUG_ASSERT((ulint)FIELD_TYPE_VAR_STRING < 256);
  1518. DBUG_ASSERT((ulint)FIELD_TYPE_DOUBLE < 256);
  1519. DBUG_ASSERT((ulint)FIELD_TYPE_FLOAT < 256);
  1520. DBUG_ASSERT((ulint)FIELD_TYPE_DECIMAL < 256);
  1521. if (field->flags & UNSIGNED_FLAG) {
  1522. *unsigned_flag = DATA_UNSIGNED;
  1523. } else {
  1524. *unsigned_flag = 0;
  1525. }
  1526. if (field->real_type() == FIELD_TYPE_ENUM
  1527.     || field->real_type() == FIELD_TYPE_SET) {
  1528. /* MySQL has field->type() a string type for these, but the
  1529. data is actually internally stored as an unsigned integer
  1530. code! */
  1531. *unsigned_flag = DATA_UNSIGNED; /* MySQL has its own unsigned
  1532. flag set to zero, even though
  1533. internally this is an unsigned
  1534. integer type */
  1535. return(DATA_INT);
  1536. }
  1537. switch (field->type()) {
  1538.         /* NOTE that we only allow string types in DATA_MYSQL
  1539. and DATA_VARMYSQL */
  1540. case FIELD_TYPE_VAR_STRING: if (field->binary()) {
  1541. return(DATA_BINARY);
  1542. } else if (strcmp(
  1543.   field->charset()->name,
  1544.  "latin1_swedish_ci") == 0) {
  1545. return(DATA_VARCHAR);
  1546. } else {
  1547. return(DATA_VARMYSQL);
  1548. }
  1549. case FIELD_TYPE_STRING: if (field->binary()) {
  1550. return(DATA_FIXBINARY);
  1551. } else if (strcmp(
  1552.    field->charset()->name,
  1553.    "latin1_swedish_ci") == 0) {
  1554. return(DATA_CHAR);
  1555. } else {
  1556. return(DATA_MYSQL);
  1557. }
  1558. case FIELD_TYPE_LONG:
  1559. case FIELD_TYPE_LONGLONG:
  1560. case FIELD_TYPE_TINY:
  1561. case FIELD_TYPE_SHORT:
  1562. case FIELD_TYPE_INT24:
  1563. case FIELD_TYPE_DATE:
  1564. case FIELD_TYPE_DATETIME:
  1565. case FIELD_TYPE_YEAR:
  1566. case FIELD_TYPE_NEWDATE:
  1567. case FIELD_TYPE_TIME:
  1568. case FIELD_TYPE_TIMESTAMP:
  1569. return(DATA_INT);
  1570. case FIELD_TYPE_FLOAT:
  1571. return(DATA_FLOAT);
  1572. case FIELD_TYPE_DOUBLE:
  1573. return(DATA_DOUBLE);
  1574. case FIELD_TYPE_DECIMAL:
  1575. return(DATA_DECIMAL);
  1576. case FIELD_TYPE_TINY_BLOB:
  1577. case FIELD_TYPE_MEDIUM_BLOB:
  1578. case FIELD_TYPE_BLOB:
  1579. case FIELD_TYPE_LONG_BLOB:
  1580. return(DATA_BLOB);
  1581. default:
  1582. assert(0);
  1583. }
  1584. return(0);
  1585. }
  1586. /***********************************************************************
  1587. Stores a key value for a row to a buffer. */
  1588. uint
  1589. ha_innobase::store_key_val_for_row(
  1590. /*===============================*/
  1591. /* out: key value length as stored in buff */
  1592. uint  keynr, /* in: key number */
  1593. char* buff, /* in/out: buffer for the key value (in MySQL
  1594. format) */
  1595. uint buff_len,/* in: buffer length */
  1596. const mysql_byte* record)/* in: row in MySQL format */
  1597. {
  1598. KEY* key_info  = table->key_info + keynr;
  1599.    KEY_PART_INFO* key_part = key_info->key_part;
  1600.    KEY_PART_INFO* end = key_part + key_info->key_parts;
  1601. char* buff_start = buff;
  1602. enum_field_types mysql_type;
  1603. Field* field;
  1604. ulint blob_len;
  1605. byte* blob_data;
  1606. ibool is_null;
  1607.    DBUG_ENTER("store_key_val_for_row");
  1608. /* The format for storing a key field in MySQL is the following:
  1609. 1. If the column can be NULL, then in the first byte we put 1 if the
  1610. field value is NULL, 0 otherwise.
  1611. 2. If the column is of a BLOB type (it must be a column prefix field
  1612. in this case), then we put the length of the data in the field to the
  1613. next 2 bytes, in the little-endian format. If the field is SQL NULL,
  1614. then these 2 bytes are set to 0. Note that the length of data in the
  1615. field is <= column prefix length.
  1616. 3. In a column prefix field, prefix_len next bytes are reserved for
  1617. data. In a normal field the max field length next bytes are reserved
  1618. for data. For a VARCHAR(n) the max field length is n. If the stored
  1619. value is the SQL NULL then these data bytes are set to 0. */
  1620. /* We have to zero-fill the buffer so that MySQL is able to use a
  1621. simple memcmp to compare two key values to determine if they are
  1622. equal. MySQL does this to compare contents of two 'ref' values. */
  1623. bzero(buff, buff_len);
  1624.    for (; key_part != end; key_part++) {
  1625.         is_null = FALSE;
  1626.      if (key_part->null_bit) {
  1627.        if (record[key_part->null_offset]
  1628. & key_part->null_bit) {
  1629. *buff = 1;
  1630. is_null = TRUE;
  1631.        } else {
  1632. *buff = 0;
  1633. }
  1634. buff++;
  1635.      }
  1636. field = key_part->field;
  1637. mysql_type = field->type();
  1638. if (mysql_type == FIELD_TYPE_TINY_BLOB
  1639.     || mysql_type == FIELD_TYPE_MEDIUM_BLOB
  1640.     || mysql_type == FIELD_TYPE_BLOB
  1641.     || mysql_type == FIELD_TYPE_LONG_BLOB) {
  1642. ut_a(key_part->key_part_flag & HA_PART_KEY_SEG);
  1643.         if (is_null) {
  1644.  buff += key_part->length + 2;
  1645.  
  1646.  continue;
  1647. }
  1648.     
  1649.         blob_data = row_mysql_read_blob_ref(&blob_len,
  1650. (byte*) (record
  1651. + (ulint)get_field_offset(table, field)),
  1652. (ulint) field->pack_length());
  1653. ut_a(get_field_offset(table, field)
  1654.      == key_part->offset);
  1655. if (blob_len > key_part->length) {
  1656.         blob_len = key_part->length;
  1657. }
  1658. /* MySQL reserves 2 bytes for the length and the
  1659. storage of the number is little-endian */
  1660. ut_a(blob_len < 256);
  1661. *((byte*)buff) = (byte)blob_len;
  1662. buff += 2;
  1663. memcpy(buff, blob_data, blob_len);
  1664. buff += key_part->length;
  1665. } else {
  1666.         if (is_null) {
  1667.  buff += key_part->length;
  1668.  
  1669.  continue;
  1670. }
  1671. memcpy(buff, record + key_part->offset,
  1672. key_part->length);
  1673. buff += key_part->length;
  1674. }
  1675.    }
  1676. ut_a(buff <= buff_start + buff_len);
  1677. DBUG_RETURN((uint)(buff - buff_start));
  1678. }
  1679. /******************************************************************
  1680. Builds a 'template' to the prebuilt struct. The template is used in fast
  1681. retrieval of just those column values MySQL needs in its processing. */
  1682. static
  1683. void
  1684. build_template(
  1685. /*===========*/
  1686. row_prebuilt_t* prebuilt, /* in: prebuilt struct */
  1687. THD* thd, /* in: current user thread, used
  1688. only if templ_type is
  1689. ROW_MYSQL_REC_FIELDS */
  1690. TABLE* table, /* in: MySQL table */
  1691. ulint templ_type) /* in: ROW_MYSQL_WHOLE_ROW or
  1692. ROW_MYSQL_REC_FIELDS */
  1693. {
  1694. dict_index_t* index;
  1695. dict_index_t* clust_index;
  1696. mysql_row_templ_t* templ;
  1697. Field* field;
  1698. ulint n_fields;
  1699. ulint n_requested_fields = 0;
  1700. ibool fetch_all_in_key = FALSE;
  1701. ibool fetch_primary_key_cols = FALSE;
  1702. ulint i;
  1703. if (prebuilt->select_lock_type == LOCK_X) {
  1704. /* We always retrieve the whole clustered index record if we
  1705. use exclusive row level locks, for example, if the read is
  1706. done in an UPDATE statement. */
  1707.         templ_type = ROW_MYSQL_WHOLE_ROW;
  1708. }
  1709. if (templ_type == ROW_MYSQL_REC_FIELDS) {
  1710.      if (prebuilt->hint_need_to_fetch_extra_cols
  1711. == ROW_RETRIEVE_ALL_COLS) {
  1712. /* We know we must at least fetch all columns in the key, or
  1713. all columns in the table */
  1714. if (prebuilt->read_just_key) {
  1715. /* MySQL has instructed us that it is enough to
  1716. fetch the columns in the key; looks like MySQL
  1717. can set this flag also when there is only a
  1718. prefix of the column in the key: in that case we
  1719. retrieve the whole column from the clustered
  1720. index */
  1721. fetch_all_in_key = TRUE;
  1722. } else {
  1723. templ_type = ROW_MYSQL_WHOLE_ROW;
  1724. }
  1725.     } else if (prebuilt->hint_need_to_fetch_extra_cols
  1726. == ROW_RETRIEVE_PRIMARY_KEY) {
  1727. /* We must at least fetch all primary key cols. Note that if
  1728. the clustered index was internally generated by InnoDB on the
  1729. row id (no primary key was defined), then
  1730. row_search_for_mysql() will always retrieve the row id to a
  1731. special buffer in the prebuilt struct. */
  1732. fetch_primary_key_cols = TRUE;
  1733.     }
  1734. }
  1735. clust_index = dict_table_get_first_index_noninline(prebuilt->table);
  1736. if (templ_type == ROW_MYSQL_REC_FIELDS) {
  1737. index = prebuilt->index;
  1738. } else {
  1739. index = clust_index;
  1740. }
  1741. if (index == clust_index) {
  1742. prebuilt->need_to_access_clustered = TRUE;
  1743. } else {
  1744. prebuilt->need_to_access_clustered = FALSE;
  1745. /* Below we check column by column if we need to access
  1746. the clustered index */
  1747. }
  1748. n_fields = (ulint)table->fields; /* number of columns */
  1749. if (!prebuilt->mysql_template) {
  1750. prebuilt->mysql_template = (mysql_row_templ_t*)
  1751. mem_alloc_noninline(
  1752. n_fields * sizeof(mysql_row_templ_t));
  1753. }
  1754. prebuilt->template_type = templ_type;
  1755. prebuilt->null_bitmap_len = table->null_bytes;
  1756. prebuilt->templ_contains_blob = FALSE;
  1757. /* Note that in InnoDB, i is the column number. MySQL calls columns
  1758. 'fields'. */
  1759. for (i = 0; i < n_fields; i++) {
  1760. templ = prebuilt->mysql_template + n_requested_fields;
  1761. field = table->field[i];
  1762. if (templ_type == ROW_MYSQL_REC_FIELDS
  1763.     && !(fetch_all_in_key
  1764.  && dict_index_contains_col_or_prefix(index, i))
  1765.     && !(fetch_primary_key_cols
  1766.  && dict_table_col_in_clustered_key(index->table, i))
  1767.     && thd->query_id != field->query_id) {
  1768. /* This field is not needed in the query, skip it */
  1769. goto skip_field;
  1770. }
  1771. n_requested_fields++;
  1772. templ->col_no = i;
  1773. if (index == clust_index) {
  1774. templ->rec_field_no = (index->table->cols + i)
  1775. ->clust_pos;
  1776. } else {
  1777. templ->rec_field_no = dict_index_get_nth_col_pos(
  1778. index, i);
  1779. }
  1780. if (templ->rec_field_no == ULINT_UNDEFINED) {
  1781. prebuilt->need_to_access_clustered = TRUE;
  1782. }
  1783. if (field->null_ptr) {
  1784. templ->mysql_null_byte_offset =
  1785. (ulint) ((char*) field->null_ptr
  1786. - (char*) table->record[0]);
  1787. templ->mysql_null_bit_mask = (ulint) field->null_bit;
  1788. } else {
  1789. templ->mysql_null_bit_mask = 0;
  1790. }
  1791. templ->mysql_col_offset = (ulint)
  1792. get_field_offset(table, field);
  1793. templ->mysql_col_len = (ulint) field->pack_length();
  1794. templ->type = index->table->cols[i].type.mtype;
  1795. templ->is_unsigned = index->table->cols[i].type.prtype
  1796. & DATA_UNSIGNED;
  1797. templ->charset = dtype_get_charset_coll_noninline(
  1798. index->table->cols[i].type.prtype);
  1799. if (templ->type == DATA_BLOB) {
  1800. prebuilt->templ_contains_blob = TRUE;
  1801. }
  1802. skip_field:
  1803. ;
  1804. }
  1805. prebuilt->n_template = n_requested_fields;
  1806. if (index != clust_index && prebuilt->need_to_access_clustered) {
  1807. /* Change rec_field_no's to correspond to the clustered index
  1808. record */
  1809. for (i = 0; i < n_requested_fields; i++) {
  1810. templ = prebuilt->mysql_template + i;
  1811. templ->rec_field_no =
  1812.     (index->table->cols + templ->col_no)->clust_pos;
  1813. }
  1814. }
  1815. }
  1816. /************************************************************************
  1817. Stores a row in an InnoDB database, to the table specified in this
  1818. handle. */
  1819. int
  1820. ha_innobase::write_row(
  1821. /*===================*/
  1822. /* out: error code */
  1823. mysql_byte*  record) /* in: a row in MySQL format */
  1824. {
  1825. row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
  1826.    int  error;
  1827. longlong auto_inc;
  1828. longlong dummy;
  1829. ibool           incremented_auto_inc_for_stat = FALSE;
  1830. ibool           incremented_auto_inc_counter = FALSE;
  1831. ibool           skip_auto_inc_decr;
  1832.    DBUG_ENTER("ha_innobase::write_row");
  1833. if (prebuilt->trx !=
  1834. (trx_t*) current_thd->transaction.all.innobase_tid) {
  1835. fprintf(stderr,
  1836. "InnoDB: Error: the transaction object for the table handle is atn"
  1837. "InnoDB: %p, but for the current thread it is at %pn",
  1838. prebuilt->trx,
  1839. current_thd->transaction.all.innobase_tid);
  1840. fputs("InnoDB: Dump of 200 bytes around prebuilt: ", stderr);
  1841. ut_print_buf(stderr, ((const byte*)prebuilt) - 100, 200);
  1842. fputs("n"
  1843. "InnoDB: Dump of 200 bytes around transaction.all: ",
  1844. stderr);
  1845. ut_print_buf(stderr,
  1846. ((byte*)(&(current_thd->transaction.all))) - 100, 200);
  1847. putc('n', stderr);
  1848. ut_error;
  1849. }
  1850.    statistic_increment(ha_write_count, &LOCK_status);
  1851.         if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
  1852.                 table->timestamp_field->set_time();
  1853. if ((user_thd->lex->sql_command == SQLCOM_ALTER_TABLE
  1854.     || user_thd->lex->sql_command == SQLCOM_OPTIMIZE
  1855.     || user_thd->lex->sql_command == SQLCOM_CREATE_INDEX
  1856.     || user_thd->lex->sql_command == SQLCOM_DROP_INDEX)
  1857.     && num_write_row >= 10000) {
  1858. /* ALTER TABLE is COMMITted at every 10000 copied rows.
  1859. The IX table lock for the original table has to be re-issued.
  1860. As this method will be called on a temporary table where the
  1861. contents of the original table is being copied to, it is
  1862. a bit tricky to determine the source table.  The cursor
  1863. position in the source table need not be adjusted after the
  1864. intermediate COMMIT, since writes by other transactions are
  1865. being blocked by a MySQL table lock TL_WRITE_ALLOW_READ. */
  1866. dict_table_t* src_table;
  1867. ibool mode;
  1868. num_write_row = 0;
  1869. /* Commit the transaction.  This will release the table
  1870. locks, so they have to be acquired again. */
  1871. /* Altering an InnoDB table */
  1872. /* Get the source table. */
  1873. src_table = lock_get_src_table(
  1874. prebuilt->trx, prebuilt->table, &mode);
  1875. if (!src_table) {
  1876. no_commit:
  1877. /* Unknown situation: do not commit */
  1878. /*
  1879. ut_print_timestamp(stderr);
  1880. fprintf(stderr,
  1881. "  InnoDB error: ALTER TABLE is holding lock"
  1882. " on %lu tables!n",
  1883. prebuilt->trx->mysql_n_tables_locked);
  1884. */
  1885. ;
  1886. } else if (src_table == prebuilt->table) {
  1887. /* Source table is not in InnoDB format:
  1888. no need to re-acquire locks on it. */
  1889. /* Altering to InnoDB format */
  1890. innobase_commit(user_thd, prebuilt->trx);
  1891. /* Note that this transaction is still active. */
  1892. user_thd->transaction.all.innodb_active_trans = 1;
  1893. /* We will need an IX lock on the destination table. */
  1894.         prebuilt->sql_stat_start = TRUE;
  1895. } else {
  1896. /* Ensure that there are no other table locks than
  1897. LOCK_IX and LOCK_AUTO_INC on the destination table. */
  1898. if (!lock_is_table_exclusive(prebuilt->table,
  1899. prebuilt->trx)) {
  1900. goto no_commit;
  1901. }
  1902. /* Commit the transaction.  This will release the table
  1903. locks, so they have to be acquired again. */
  1904. innobase_commit(user_thd, prebuilt->trx);
  1905. /* Note that this transaction is still active. */
  1906. user_thd->transaction.all.innodb_active_trans = 1;
  1907. /* Re-acquire the table lock on the source table. */
  1908. row_lock_table_for_mysql(prebuilt, src_table, mode);
  1909. /* We will need an IX lock on the destination table. */
  1910.         prebuilt->sql_stat_start = TRUE;
  1911. }
  1912. }
  1913. num_write_row++;
  1914. if (last_query_id != user_thd->query_id) {
  1915.         prebuilt->sql_stat_start = TRUE;
  1916.                 last_query_id = user_thd->query_id;
  1917. innobase_release_stat_resources(prebuilt->trx);
  1918. }
  1919.    if (table->next_number_field && record == table->record[0]) {
  1920. /* This is the case where the table has an
  1921. auto-increment column */
  1922. /* Initialize the auto-inc counter if it has not been
  1923. initialized yet */
  1924. if (0 == dict_table_autoinc_peek(prebuilt->table)) {
  1925. /* This call initializes the counter */
  1926.         error = innobase_read_and_init_auto_inc(&dummy);
  1927. if (error) {
  1928. /* Deadlock or lock wait timeout */
  1929. goto func_exit;
  1930. }
  1931. /* We have to set sql_stat_start to TRUE because
  1932. the above call probably has called a select, and
  1933. has reset that flag; row_insert_for_mysql has to
  1934. know to set the IX intention lock on the table,
  1935. something it only does at the start of each
  1936. statement */
  1937. prebuilt->sql_stat_start = TRUE;
  1938. }
  1939.         /* Fetch the value the user possibly has set in the
  1940.         autoincrement field */
  1941.         auto_inc = table->next_number_field->val_int();
  1942. /* In replication and also otherwise the auto-inc column 
  1943. can be set with SET INSERT_ID. Then we must look at
  1944. user_thd->next_insert_id. If it is nonzero and the user
  1945. has not supplied a value, we must use it, and use values
  1946. incremented by 1 in all subsequent inserts within the
  1947. same SQL statement! */
  1948. if (auto_inc == 0 && user_thd->next_insert_id != 0) {
  1949.         auto_inc_counter_for_this_stat
  1950. = user_thd->next_insert_id;
  1951. }
  1952. if (auto_inc == 0 && auto_inc_counter_for_this_stat) {
  1953. /* The user set the auto-inc counter for
  1954. this SQL statement with SET INSERT_ID. We must
  1955. assign sequential values from the counter. */
  1956. auto_inc = auto_inc_counter_for_this_stat;
  1957. /* We give MySQL a new value to place in the
  1958. auto-inc column */
  1959. user_thd->next_insert_id = auto_inc;
  1960. auto_inc_counter_for_this_stat++;
  1961. incremented_auto_inc_for_stat = TRUE;
  1962. }
  1963. if (auto_inc != 0) {
  1964. /* This call will calculate the max of the current
  1965. value and the value supplied by the user and
  1966. update the counter accordingly */
  1967. /* We have to use the transactional lock mechanism
  1968. on the auto-inc counter of the table to ensure
  1969. that replication and roll-forward of the binlog
  1970. exactly imitates also the given auto-inc values.
  1971. The lock is released at each SQL statement's
  1972. end. */
  1973. innodb_srv_conc_enter_innodb(prebuilt->trx);
  1974. error = row_lock_table_autoinc_for_mysql(prebuilt);
  1975. innodb_srv_conc_exit_innodb(prebuilt->trx);
  1976. if (error != DB_SUCCESS) {
  1977. error = convert_error_code_to_mysql(error,
  1978.     user_thd);
  1979. goto func_exit;
  1980. }
  1981. dict_table_autoinc_update(prebuilt->table, auto_inc);
  1982. } else {
  1983. innodb_srv_conc_enter_innodb(prebuilt->trx);
  1984. if (!prebuilt->trx->auto_inc_lock) {
  1985. error = row_lock_table_autoinc_for_mysql(
  1986. prebuilt);
  1987. if (error != DB_SUCCESS) {
  1988.   innodb_srv_conc_exit_innodb(
  1989. prebuilt->trx);
  1990. error = convert_error_code_to_mysql(
  1991. error, user_thd);
  1992. goto func_exit;
  1993. }
  1994. }
  1995. /* The following call gets the value of the auto-inc
  1996. counter of the table and increments it by 1 */
  1997. auto_inc = dict_table_autoinc_get(prebuilt->table);
  1998. incremented_auto_inc_counter = TRUE;
  1999. innodb_srv_conc_exit_innodb(prebuilt->trx);
  2000. /* We can give the new value for MySQL to place in
  2001. the field */
  2002. user_thd->next_insert_id = auto_inc;
  2003. }
  2004. /* This call of a handler.cc function places
  2005. user_thd->next_insert_id to the column value, if the column
  2006. value was not set by the user */
  2007.      update_auto_increment();
  2008. }
  2009. if (prebuilt->mysql_template == NULL
  2010. || prebuilt->template_type != ROW_MYSQL_WHOLE_ROW) {
  2011. /* Build the template used in converting quickly between
  2012. the two database formats */
  2013. build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
  2014. }
  2015. innodb_srv_conc_enter_innodb(prebuilt->trx);
  2016. error = row_insert_for_mysql((byte*) record, prebuilt);
  2017. innodb_srv_conc_exit_innodb(prebuilt->trx);
  2018. if (error != DB_SUCCESS) {
  2019.         /* If the insert did not succeed we restore the value of
  2020. the auto-inc counter we used; note that this behavior was
  2021. introduced only in version 4.0.4.
  2022. NOTE that a REPLACE command and LOAD DATA INFILE REPLACE
  2023. handles a duplicate key error
  2024. itself, and we must not decrement the autoinc counter
  2025. if we are performing those statements.
  2026. NOTE 2: if there was an error, for example a deadlock,
  2027. which caused InnoDB to roll back the whole transaction
  2028. already in the call of row_insert_for_mysql(), we may no
  2029. longer have the AUTO-INC lock, and cannot decrement
  2030. the counter here. */
  2031.         skip_auto_inc_decr = FALSE;
  2032.         if (error == DB_DUPLICATE_KEY
  2033.     && (user_thd->lex->sql_command == SQLCOM_REPLACE
  2034. || user_thd->lex->sql_command
  2035.                  == SQLCOM_REPLACE_SELECT
  2036.      || (user_thd->lex->sql_command == SQLCOM_LOAD
  2037.     && user_thd->lex->duplicates == DUP_REPLACE))) {
  2038.         skip_auto_inc_decr= TRUE;
  2039. }
  2040.         if (!skip_auto_inc_decr && incremented_auto_inc_counter
  2041.     && prebuilt->trx->auto_inc_lock) {
  2042.                 dict_table_autoinc_decrement(prebuilt->table);
  2043.         }
  2044. if (!skip_auto_inc_decr && incremented_auto_inc_for_stat
  2045.     && prebuilt->trx->auto_inc_lock) {
  2046.         auto_inc_counter_for_this_stat--;
  2047. }
  2048. }
  2049. error = convert_error_code_to_mysql(error, user_thd);
  2050. /* Tell InnoDB server that there might be work for
  2051. utility threads: */
  2052. func_exit:
  2053. innobase_active_small();
  2054.    DBUG_RETURN(error);
  2055. }
  2056. /******************************************************************
  2057. Converts field data for storage in an InnoDB update vector. */
  2058. inline
  2059. mysql_byte*
  2060. innobase_convert_and_store_changed_col(
  2061. /*===================================*/
  2062. /* out: pointer to the end of the converted
  2063. data in the buffer */
  2064. upd_field_t* ufield, /* in/out: field in the update vector */
  2065. mysql_byte* buf, /* in: buffer we can use in conversion */
  2066. mysql_byte* data, /* in: column data to store */
  2067. ulint len, /* in: data len */
  2068. ulint col_type,/* in: data type in InnoDB type numbers */
  2069. ulint prtype) /* InnoDB precise data type and flags */
  2070. {
  2071. uint i;
  2072. if (len == UNIV_SQL_NULL) {
  2073. data = NULL;
  2074. } else if (col_type == DATA_VARCHAR || col_type == DATA_BINARY
  2075.    || col_type == DATA_VARMYSQL) {
  2076. /* Remove trailing spaces. */
  2077. /* Handle UCS2 strings differently.  As no new
  2078. collations will be introduced in 4.1, we hardcode the
  2079. charset-collation codes here.  In 5.0, the logic will
  2080. be based on mbminlen. */
  2081. ulint cset = dtype_get_charset_coll_noninline(prtype);
  2082. if (cset == 35/*ucs2_general_ci*/
  2083. || cset == 90/*ucs2_bin*/
  2084. || (cset >= 128/*ucs2_unicode_ci*/
  2085. && cset <= 144/*ucs2_persian_ci*/)) {
  2086. /* space=0x0020 */
  2087. /* Trim "half-chars", just in case. */
  2088. len = len - (len % 2); /* len &= ~1; */
  2089. while (len && data[len - 2] == 0x00
  2090. && data[len - 1] == 0x20) {
  2091. len -= 2;
  2092. }
  2093. } else {
  2094. /* space=0x20 */
  2095. while (len && data[len - 1] == 0x20) {
  2096. len--;
  2097. }
  2098. }
  2099. } else if (col_type == DATA_INT) {
  2100. /* Store integer data in InnoDB in a big-endian
  2101. format, sign bit negated, if signed */
  2102. for (i = 0; i < len; i++) {
  2103. buf[len - 1 - i] = data[i];
  2104. }
  2105. if (!(prtype & DATA_UNSIGNED)) {
  2106. buf[0] = buf[0] ^ 128;
  2107. }
  2108. data = buf;
  2109. buf += len;
  2110. }
  2111. ufield->new_val.data = data;
  2112. ufield->new_val.len = len;
  2113. return(buf);
  2114. }
  2115. /**************************************************************************
  2116. Checks which fields have changed in a row and stores information
  2117. of them to an update vector. */
  2118. static
  2119. int
  2120. calc_row_difference(
  2121. /*================*/
  2122. /* out: error number or 0 */
  2123. upd_t* uvect, /* in/out: update vector */
  2124. mysql_byte*  old_row, /* in: old row in MySQL format */
  2125. mysql_byte*  new_row, /* in: new row in MySQL format */
  2126. struct st_table* table, /* in: table in MySQL data
  2127. dictionary */
  2128. mysql_byte* upd_buff, /* in: buffer to use */
  2129. ulint buff_len, /* in: buffer length */
  2130. row_prebuilt_t* prebuilt, /* in: InnoDB prebuilt struct */
  2131. THD* thd) /* in: user thread */
  2132. {
  2133. mysql_byte* original_upd_buff = upd_buff;
  2134. Field* field;
  2135. uint n_fields;
  2136. ulint o_len;
  2137. ulint n_len;
  2138. byte*         o_ptr;
  2139.         byte*         n_ptr;
  2140.         byte*         buf;
  2141. upd_field_t* ufield;
  2142. ulint col_type;
  2143. ulint prtype;
  2144. ulint n_changed = 0;
  2145. uint i;
  2146. n_fields = table->fields;
  2147. /* We use upd_buff to convert changed fields */
  2148. buf = (byte*) upd_buff;
  2149. for (i = 0; i < n_fields; i++) {
  2150. field = table->field[i];
  2151. /* if (thd->query_id != field->query_id) { */
  2152. /* TODO: check that these fields cannot have
  2153. changed! */
  2154. /* goto skip_field;
  2155. }*/
  2156. o_ptr = (byte*) old_row + get_field_offset(table, field);
  2157. n_ptr = (byte*) new_row + get_field_offset(table, field);
  2158. o_len = field->pack_length();
  2159. n_len = field->pack_length();
  2160. col_type = prebuilt->table->cols[i].type.mtype;
  2161. prtype = prebuilt->table->cols[i].type.prtype;
  2162. switch (col_type) {
  2163. case DATA_BLOB:
  2164. o_ptr = row_mysql_read_blob_ref(&o_len, o_ptr, o_len);
  2165. n_ptr = row_mysql_read_blob_ref(&n_len, n_ptr, n_len);
  2166. break;
  2167. case DATA_VARCHAR:
  2168. case DATA_BINARY:
  2169. case DATA_VARMYSQL:
  2170. o_ptr = row_mysql_read_var_ref_noninline(&o_len,
  2171. o_ptr);
  2172. n_ptr = row_mysql_read_var_ref_noninline(&n_len,
  2173. n_ptr);
  2174. default:
  2175. ;
  2176. }
  2177. if (field->null_ptr) {
  2178. if (field_in_record_is_null(table, field,
  2179. (char*) old_row)) {
  2180. o_len = UNIV_SQL_NULL;
  2181. }
  2182. if (field_in_record_is_null(table, field,
  2183. (char*) new_row)) {
  2184. n_len = UNIV_SQL_NULL;
  2185. }
  2186. }
  2187. if (o_len != n_len || (o_len != UNIV_SQL_NULL &&
  2188. 0 != memcmp(o_ptr, n_ptr, o_len))) {
  2189. /* The field has changed */
  2190. ufield = uvect->fields + n_changed;
  2191. buf = (byte*)
  2192.                           innobase_convert_and_store_changed_col(ufield,
  2193.   (mysql_byte*)buf,
  2194.   (mysql_byte*)n_ptr, n_len, col_type,
  2195. prtype);
  2196. ufield->exp = NULL;
  2197. ufield->field_no = prebuilt->table->cols[i].clust_pos;
  2198. n_changed++;
  2199. }
  2200. }
  2201. uvect->n_fields = n_changed;
  2202. uvect->info_bits = 0;
  2203. ut_a(buf <= (byte*)original_upd_buff + buff_len);
  2204. return(0);
  2205. }
  2206. /**************************************************************************
  2207. Updates a row given as a parameter to a new value. Note that we are given
  2208. whole rows, not just the fields which are updated: this incurs some
  2209. overhead for CPU when we check which fields are actually updated.
  2210. TODO: currently InnoDB does not prevent the 'Halloween problem':
  2211. in a searched update a single row can get updated several times
  2212. if its index columns are updated! */
  2213. int
  2214. ha_innobase::update_row(
  2215. /*====================*/
  2216. /* out: error number or 0 */
  2217. const mysql_byte*  old_row,/* in: old row in MySQL format */
  2218. mysql_byte*  new_row)/* in: new row in MySQL format */
  2219. {
  2220. row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
  2221. upd_t* uvect;
  2222. int error = 0;
  2223. DBUG_ENTER("ha_innobase::update_row");
  2224. ut_ad(prebuilt->trx ==
  2225. (trx_t*) current_thd->transaction.all.innobase_tid);
  2226.         if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
  2227.                 table->timestamp_field->set_time();
  2228. if (last_query_id != user_thd->query_id) {
  2229.         prebuilt->sql_stat_start = TRUE;
  2230.                 last_query_id = user_thd->query_id;
  2231. innobase_release_stat_resources(prebuilt->trx);
  2232. }
  2233. if (prebuilt->upd_node) {
  2234. uvect = prebuilt->upd_node->update;
  2235. } else {
  2236. uvect = row_get_prebuilt_update_vector(prebuilt);
  2237. }
  2238. /* Build an update vector from the modified fields in the rows
  2239. (uses upd_buff of the handle) */
  2240. calc_row_difference(uvect, (mysql_byte*) old_row, new_row, table,
  2241. upd_buff, (ulint)upd_and_key_val_buff_len,
  2242. prebuilt, user_thd);
  2243. /* This is not a delete */
  2244. prebuilt->upd_node->is_delete = FALSE;
  2245. assert(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
  2246. innodb_srv_conc_enter_innodb(prebuilt->trx);
  2247. error = row_update_for_mysql((byte*) old_row, prebuilt);
  2248. innodb_srv_conc_exit_innodb(prebuilt->trx);
  2249. error = convert_error_code_to_mysql(error, user_thd);
  2250. /* Tell InnoDB server that there might be work for
  2251. utility threads: */
  2252. innobase_active_small();
  2253. DBUG_RETURN(error);
  2254. }
  2255. /**************************************************************************
  2256. Deletes a row given as the parameter. */
  2257. int
  2258. ha_innobase::delete_row(
  2259. /*====================*/
  2260. /* out: error number or 0 */
  2261. const mysql_byte* record) /* in: a row in MySQL format */
  2262. {
  2263. row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
  2264. int error = 0;
  2265. DBUG_ENTER("ha_innobase::delete_row");
  2266. ut_ad(prebuilt->trx ==
  2267. (trx_t*) current_thd->transaction.all.innobase_tid);
  2268. if (last_query_id != user_thd->query_id) {
  2269.         prebuilt->sql_stat_start = TRUE;
  2270.                 last_query_id = user_thd->query_id;
  2271. innobase_release_stat_resources(prebuilt->trx);
  2272. }
  2273. if (!prebuilt->upd_node) {
  2274. row_get_prebuilt_update_vector(prebuilt);
  2275. }
  2276. /* This is a delete */
  2277. prebuilt->upd_node->is_delete = TRUE;
  2278. innodb_srv_conc_enter_innodb(prebuilt->trx);
  2279. error = row_update_for_mysql((byte*) record, prebuilt);
  2280. innodb_srv_conc_exit_innodb(prebuilt->trx);
  2281. error = convert_error_code_to_mysql(error, user_thd);
  2282. /* Tell the InnoDB server that there might be work for
  2283. utility threads: */
  2284. innobase_active_small();
  2285. DBUG_RETURN(error);
  2286. }
  2287. /**********************************************************************
  2288. Initializes a handle to use an index. */
  2289. int
  2290. ha_innobase::index_init(
  2291. /*====================*/
  2292. /* out: 0 or error number */