You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

838 lines
20 KiB

12 years ago
12 years ago
  1. /*****************************************************************************
  2. Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
  3. This program is free software; you can redistribute it and/or modify it under
  4. the terms of the GNU General Public License as published by the Free Software
  5. Foundation; version 2 of the License.
  6. This program is distributed in the hope that it will be useful, but WITHOUT
  7. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License along with
  10. this program; if not, write to the Free Software Foundation, Inc.,
  11. 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
  12. *****************************************************************************/
  13. /***************************************************************//**
  14. @file ut/ut0ut.cc
  15. Various utilities for Innobase.
  16. Created 5/11/1994 Heikki Tuuri
  17. ********************************************************************/
  18. #include "ut0ut.h"
  19. #ifndef UNIV_INNOCHECKSUM
  20. #include "ut0sort.h"
  21. #include "os0thread.h" /* thread-ID */
  22. #ifdef UNIV_NONINL
  23. #include "ut0ut.ic"
  24. #endif
  25. #include <stdarg.h>
  26. #include <string.h>
  27. #include <ctype.h>
  28. #ifndef UNIV_HOTBACKUP
  29. # include "trx0trx.h"
  30. # include "ha_prototypes.h"
  31. # include "mysql_com.h" /* NAME_LEN */
  32. #endif /* UNIV_HOTBACKUP */
  33. /** A constant to prevent the compiler from optimizing ut_delay() away. */
  34. UNIV_INTERN ibool ut_always_false = FALSE;
  35. #ifdef __WIN__
  36. /*****************************************************************//**
  37. NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix
  38. epoch starts from 1970/1/1. For selection of constant see:
  39. http://support.microsoft.com/kb/167296/ */
  40. #define WIN_TO_UNIX_DELTA_USEC ((ib_int64_t) 11644473600000000ULL)
  41. /*****************************************************************//**
  42. This is the Windows version of gettimeofday(2).
  43. @return 0 if all OK else -1 */
  44. static
  45. int
  46. ut_gettimeofday(
  47. /*============*/
  48. struct timeval* tv, /*!< out: Values are relative to Unix epoch */
  49. void* tz) /*!< in: not used */
  50. {
  51. FILETIME ft;
  52. ib_int64_t tm;
  53. if (!tv) {
  54. errno = EINVAL;
  55. return(-1);
  56. }
  57. GetSystemTimeAsFileTime(&ft);
  58. tm = (ib_int64_t) ft.dwHighDateTime << 32;
  59. tm |= ft.dwLowDateTime;
  60. ut_a(tm >= 0); /* If tm wraps over to negative, the quotient / 10
  61. does not work */
  62. tm /= 10; /* Convert from 100 nsec periods to usec */
  63. /* If we don't convert to the Unix epoch the value for
  64. struct timeval::tv_sec will overflow.*/
  65. tm -= WIN_TO_UNIX_DELTA_USEC;
  66. tv->tv_sec = (long) (tm / 1000000L);
  67. tv->tv_usec = (long) (tm % 1000000L);
  68. return(0);
  69. }
  70. #else
  71. /** An alias for gettimeofday(2). On Microsoft Windows, we have to
  72. reimplement this function. */
  73. #define ut_gettimeofday gettimeofday
  74. #endif
  75. /**********************************************************//**
  76. Returns system time. We do not specify the format of the time returned:
  77. the only way to manipulate it is to use the function ut_difftime.
  78. @return system time */
  79. UNIV_INTERN
  80. ib_time_t
  81. ut_time(void)
  82. /*=========*/
  83. {
  84. return(time(NULL));
  85. }
  86. #ifndef UNIV_HOTBACKUP
  87. /**********************************************************//**
  88. Returns system time.
  89. Upon successful completion, the value 0 is returned; otherwise the
  90. value -1 is returned and the global variable errno is set to indicate the
  91. error.
  92. @return 0 on success, -1 otherwise */
  93. UNIV_INTERN
  94. int
  95. ut_usectime(
  96. /*========*/
  97. ulint* sec, /*!< out: seconds since the Epoch */
  98. ulint* ms) /*!< out: microseconds since the Epoch+*sec */
  99. {
  100. struct timeval tv;
  101. int ret;
  102. int errno_gettimeofday;
  103. int i;
  104. for (i = 0; i < 10; i++) {
  105. ret = ut_gettimeofday(&tv, NULL);
  106. if (ret == -1) {
  107. errno_gettimeofday = errno;
  108. ut_print_timestamp(stderr);
  109. fprintf(stderr, " InnoDB: gettimeofday(): %s\n",
  110. strerror(errno_gettimeofday));
  111. os_thread_sleep(100000); /* 0.1 sec */
  112. errno = errno_gettimeofday;
  113. } else {
  114. break;
  115. }
  116. }
  117. if (ret != -1) {
  118. *sec = (ulint) tv.tv_sec;
  119. *ms = (ulint) tv.tv_usec;
  120. }
  121. return(ret);
  122. }
  123. /**********************************************************//**
  124. Returns the number of microseconds since epoch. Similar to
  125. time(3), the return value is also stored in *tloc, provided
  126. that tloc is non-NULL.
  127. @return us since epoch */
  128. UNIV_INTERN
  129. ullint
  130. ut_time_us(
  131. /*=======*/
  132. ullint* tloc) /*!< out: us since epoch, if non-NULL */
  133. {
  134. struct timeval tv;
  135. ullint us;
  136. ut_gettimeofday(&tv, NULL);
  137. us = (ullint) tv.tv_sec * 1000000 + tv.tv_usec;
  138. if (tloc != NULL) {
  139. *tloc = us;
  140. }
  141. return(us);
  142. }
  143. /**********************************************************//**
  144. Returns the number of milliseconds since some epoch. The
  145. value may wrap around. It should only be used for heuristic
  146. purposes.
  147. @return ms since epoch */
  148. UNIV_INTERN
  149. ulint
  150. ut_time_ms(void)
  151. /*============*/
  152. {
  153. struct timeval tv;
  154. ut_gettimeofday(&tv, NULL);
  155. return((ulint) tv.tv_sec * 1000 + tv.tv_usec / 1000);
  156. }
  157. #endif /* !UNIV_HOTBACKUP */
  158. /**********************************************************//**
  159. Returns the difference of two times in seconds.
  160. @return time2 - time1 expressed in seconds */
  161. UNIV_INTERN
  162. double
  163. ut_difftime(
  164. /*========*/
  165. ib_time_t time2, /*!< in: time */
  166. ib_time_t time1) /*!< in: time */
  167. {
  168. return(difftime(time2, time1));
  169. }
  170. #endif /* !UNIV_INNOCHECKSUM */
  171. /**********************************************************//**
  172. Prints a timestamp to a file. */
  173. UNIV_INTERN
  174. void
  175. ut_print_timestamp(
  176. /*===============*/
  177. FILE* file) /*!< in: file where to print */
  178. {
  179. ulint thread_id = 0;
  180. #ifndef UNIV_INNOCHECKSUM
  181. thread_id = os_thread_pf(os_thread_get_curr_id());
  182. #endif
  183. #ifdef __WIN__
  184. SYSTEMTIME cal_tm;
  185. GetLocalTime(&cal_tm);
  186. fprintf(file, "%d-%02d-%02d %02d:%02d:%02d %lx",
  187. (int) cal_tm.wYear,
  188. (int) cal_tm.wMonth,
  189. (int) cal_tm.wDay,
  190. (int) cal_tm.wHour,
  191. (int) cal_tm.wMinute,
  192. (int) cal_tm.wSecond,
  193. thread_id);
  194. #else
  195. struct tm* cal_tm_ptr;
  196. time_t tm;
  197. #ifdef HAVE_LOCALTIME_R
  198. struct tm cal_tm;
  199. time(&tm);
  200. localtime_r(&tm, &cal_tm);
  201. cal_tm_ptr = &cal_tm;
  202. #else
  203. time(&tm);
  204. cal_tm_ptr = localtime(&tm);
  205. #endif
  206. fprintf(file, "%d-%02d-%02d %02d:%02d:%02d %lx",
  207. cal_tm_ptr->tm_year + 1900,
  208. cal_tm_ptr->tm_mon + 1,
  209. cal_tm_ptr->tm_mday,
  210. cal_tm_ptr->tm_hour,
  211. cal_tm_ptr->tm_min,
  212. cal_tm_ptr->tm_sec,
  213. thread_id);
  214. #endif
  215. }
  216. #ifndef UNIV_INNOCHECKSUM
  217. /**********************************************************//**
  218. Sprintfs a timestamp to a buffer, 13..14 chars plus terminating NUL. */
  219. UNIV_INTERN
  220. void
  221. ut_sprintf_timestamp(
  222. /*=================*/
  223. char* buf) /*!< in: buffer where to sprintf */
  224. {
  225. #ifdef __WIN__
  226. SYSTEMTIME cal_tm;
  227. GetLocalTime(&cal_tm);
  228. sprintf(buf, "%02d%02d%02d %2d:%02d:%02d",
  229. (int) cal_tm.wYear % 100,
  230. (int) cal_tm.wMonth,
  231. (int) cal_tm.wDay,
  232. (int) cal_tm.wHour,
  233. (int) cal_tm.wMinute,
  234. (int) cal_tm.wSecond);
  235. #else
  236. struct tm* cal_tm_ptr;
  237. time_t tm;
  238. #ifdef HAVE_LOCALTIME_R
  239. struct tm cal_tm;
  240. time(&tm);
  241. localtime_r(&tm, &cal_tm);
  242. cal_tm_ptr = &cal_tm;
  243. #else
  244. time(&tm);
  245. cal_tm_ptr = localtime(&tm);
  246. #endif
  247. sprintf(buf, "%02d%02d%02d %2d:%02d:%02d",
  248. cal_tm_ptr->tm_year % 100,
  249. cal_tm_ptr->tm_mon + 1,
  250. cal_tm_ptr->tm_mday,
  251. cal_tm_ptr->tm_hour,
  252. cal_tm_ptr->tm_min,
  253. cal_tm_ptr->tm_sec);
  254. #endif
  255. }
  256. #ifdef UNIV_HOTBACKUP
  257. /**********************************************************//**
  258. Sprintfs a timestamp to a buffer with no spaces and with ':' characters
  259. replaced by '_'. */
  260. UNIV_INTERN
  261. void
  262. ut_sprintf_timestamp_without_extra_chars(
  263. /*=====================================*/
  264. char* buf) /*!< in: buffer where to sprintf */
  265. {
  266. #ifdef __WIN__
  267. SYSTEMTIME cal_tm;
  268. GetLocalTime(&cal_tm);
  269. sprintf(buf, "%02d%02d%02d_%2d_%02d_%02d",
  270. (int) cal_tm.wYear % 100,
  271. (int) cal_tm.wMonth,
  272. (int) cal_tm.wDay,
  273. (int) cal_tm.wHour,
  274. (int) cal_tm.wMinute,
  275. (int) cal_tm.wSecond);
  276. #else
  277. struct tm* cal_tm_ptr;
  278. time_t tm;
  279. #ifdef HAVE_LOCALTIME_R
  280. struct tm cal_tm;
  281. time(&tm);
  282. localtime_r(&tm, &cal_tm);
  283. cal_tm_ptr = &cal_tm;
  284. #else
  285. time(&tm);
  286. cal_tm_ptr = localtime(&tm);
  287. #endif
  288. sprintf(buf, "%02d%02d%02d_%2d_%02d_%02d",
  289. cal_tm_ptr->tm_year % 100,
  290. cal_tm_ptr->tm_mon + 1,
  291. cal_tm_ptr->tm_mday,
  292. cal_tm_ptr->tm_hour,
  293. cal_tm_ptr->tm_min,
  294. cal_tm_ptr->tm_sec);
  295. #endif
  296. }
  297. /**********************************************************//**
  298. Returns current year, month, day. */
  299. UNIV_INTERN
  300. void
  301. ut_get_year_month_day(
  302. /*==================*/
  303. ulint* year, /*!< out: current year */
  304. ulint* month, /*!< out: month */
  305. ulint* day) /*!< out: day */
  306. {
  307. #ifdef __WIN__
  308. SYSTEMTIME cal_tm;
  309. GetLocalTime(&cal_tm);
  310. *year = (ulint) cal_tm.wYear;
  311. *month = (ulint) cal_tm.wMonth;
  312. *day = (ulint) cal_tm.wDay;
  313. #else
  314. struct tm* cal_tm_ptr;
  315. time_t tm;
  316. #ifdef HAVE_LOCALTIME_R
  317. struct tm cal_tm;
  318. time(&tm);
  319. localtime_r(&tm, &cal_tm);
  320. cal_tm_ptr = &cal_tm;
  321. #else
  322. time(&tm);
  323. cal_tm_ptr = localtime(&tm);
  324. #endif
  325. *year = (ulint) cal_tm_ptr->tm_year + 1900;
  326. *month = (ulint) cal_tm_ptr->tm_mon + 1;
  327. *day = (ulint) cal_tm_ptr->tm_mday;
  328. #endif
  329. }
  330. #endif /* UNIV_HOTBACKUP */
  331. #ifndef UNIV_HOTBACKUP
  332. /*************************************************************//**
  333. Runs an idle loop on CPU. The argument gives the desired delay
  334. in microseconds on 100 MHz Pentium + Visual C++.
  335. @return dummy value */
  336. UNIV_INTERN
  337. ulint
  338. ut_delay(
  339. /*=====*/
  340. ulint delay) /*!< in: delay in microseconds on 100 MHz Pentium */
  341. {
  342. ulint i, j;
  343. j = 0;
  344. for (i = 0; i < delay * 50; i++) {
  345. j += i;
  346. UT_RELAX_CPU();
  347. }
  348. if (ut_always_false) {
  349. ut_always_false = (ibool) j;
  350. }
  351. return(j);
  352. }
  353. #endif /* !UNIV_HOTBACKUP */
  354. /*************************************************************//**
  355. Prints the contents of a memory buffer in hex and ascii. */
  356. UNIV_INTERN
  357. void
  358. ut_print_buf(
  359. /*=========*/
  360. FILE* file, /*!< in: file where to print */
  361. const void* buf, /*!< in: memory buffer */
  362. ulint len) /*!< in: length of the buffer */
  363. {
  364. const byte* data;
  365. ulint i;
  366. UNIV_MEM_ASSERT_RW(buf, len);
  367. fprintf(file, " len %lu; hex ", len);
  368. for (data = (const byte*) buf, i = 0; i < len; i++) {
  369. fprintf(file, "%02lx", (ulong)*data++);
  370. }
  371. fputs("; asc ", file);
  372. data = (const byte*) buf;
  373. for (i = 0; i < len; i++) {
  374. int c = (int) *data++;
  375. putc(isprint(c) ? c : ' ', file);
  376. }
  377. putc(';', file);
  378. }
  379. /**********************************************************************//**
  380. Sort function for ulint arrays. */
  381. UNIV_INTERN
  382. void
  383. ut_ulint_sort(
  384. /*==========*/
  385. ulint* arr, /*!< in/out: array to sort */
  386. ulint* aux_arr, /*!< in/out: aux array to use in sort */
  387. ulint low, /*!< in: lower bound */
  388. ulint high) /*!< in: upper bound */
  389. {
  390. UT_SORT_FUNCTION_BODY(ut_ulint_sort, arr, aux_arr, low, high,
  391. ut_ulint_cmp);
  392. }
  393. /*************************************************************//**
  394. Calculates fast the number rounded up to the nearest power of 2.
  395. @return first power of 2 which is >= n */
  396. UNIV_INTERN
  397. ulint
  398. ut_2_power_up(
  399. /*==========*/
  400. ulint n) /*!< in: number != 0 */
  401. {
  402. ulint res;
  403. res = 1;
  404. ut_ad(n > 0);
  405. while (res < n) {
  406. res = res * 2;
  407. }
  408. return(res);
  409. }
  410. /**********************************************************************//**
  411. Outputs a NUL-terminated file name, quoted with apostrophes. */
  412. UNIV_INTERN
  413. void
  414. ut_print_filename(
  415. /*==============*/
  416. FILE* f, /*!< in: output stream */
  417. const char* name) /*!< in: name to print */
  418. {
  419. putc('\'', f);
  420. for (;;) {
  421. int c = *name++;
  422. switch (c) {
  423. case 0:
  424. goto done;
  425. case '\'':
  426. putc(c, f);
  427. /* fall through */
  428. default:
  429. putc(c, f);
  430. }
  431. }
  432. done:
  433. putc('\'', f);
  434. }
  435. #ifndef UNIV_HOTBACKUP
  436. /**********************************************************************//**
  437. Outputs a fixed-length string, quoted as an SQL identifier.
  438. If the string contains a slash '/', the string will be
  439. output as two identifiers separated by a period (.),
  440. as in SQL database_name.identifier. */
  441. UNIV_INTERN
  442. void
  443. ut_print_name(
  444. /*==========*/
  445. FILE* f, /*!< in: output stream */
  446. const trx_t* trx, /*!< in: transaction */
  447. ibool table_id,/*!< in: TRUE=print a table name,
  448. FALSE=print other identifier */
  449. const char* name) /*!< in: name to print */
  450. {
  451. ut_print_namel(f, trx, table_id, name, strlen(name));
  452. }
  453. /**********************************************************************//**
  454. Outputs a fixed-length string, quoted as an SQL identifier.
  455. If the string contains a slash '/', the string will be
  456. output as two identifiers separated by a period (.),
  457. as in SQL database_name.identifier. */
  458. UNIV_INTERN
  459. void
  460. ut_print_namel(
  461. /*===========*/
  462. FILE* f, /*!< in: output stream */
  463. const trx_t* trx, /*!< in: transaction (NULL=no quotes) */
  464. ibool table_id,/*!< in: TRUE=print a table name,
  465. FALSE=print other identifier */
  466. const char* name, /*!< in: name to print */
  467. ulint namelen)/*!< in: length of name */
  468. {
  469. /* 2 * NAME_LEN for database and table name,
  470. and some slack for the #mysql50# prefix and quotes */
  471. char buf[3 * NAME_LEN];
  472. const char* bufend;
  473. bufend = innobase_convert_name(buf, sizeof buf,
  474. name, namelen,
  475. trx ? trx->mysql_thd : NULL,
  476. table_id);
  477. fwrite(buf, 1, bufend - buf, f);
  478. }
  479. /**********************************************************************//**
  480. Formats a table or index name, quoted as an SQL identifier. If the name
  481. contains a slash '/', the result will contain two identifiers separated by
  482. a period (.), as in SQL database_name.identifier.
  483. @return pointer to 'formatted' */
  484. UNIV_INTERN
  485. char*
  486. ut_format_name(
  487. /*===========*/
  488. const char* name, /*!< in: table or index name, must be
  489. '\0'-terminated */
  490. ibool is_table, /*!< in: if TRUE then 'name' is a table
  491. name */
  492. char* formatted, /*!< out: formatted result, will be
  493. '\0'-terminated */
  494. ulint formatted_size) /*!< out: no more than this number of
  495. bytes will be written to 'formatted' */
  496. {
  497. switch (formatted_size) {
  498. case 1:
  499. formatted[0] = '\0';
  500. /* FALL-THROUGH */
  501. case 0:
  502. return(formatted);
  503. }
  504. char* end;
  505. end = innobase_convert_name(formatted, formatted_size,
  506. name, strlen(name), NULL, is_table);
  507. /* If the space in 'formatted' was completely used, then sacrifice
  508. the last character in order to write '\0' at the end. */
  509. if ((ulint) (end - formatted) == formatted_size) {
  510. end--;
  511. }
  512. ut_a((ulint) (end - formatted) < formatted_size);
  513. *end = '\0';
  514. return(formatted);
  515. }
  516. /**********************************************************************//**
  517. Catenate files. */
  518. UNIV_INTERN
  519. void
  520. ut_copy_file(
  521. /*=========*/
  522. FILE* dest, /*!< in: output file */
  523. FILE* src) /*!< in: input file to be appended to output */
  524. {
  525. long len = ftell(src);
  526. char buf[4096];
  527. rewind(src);
  528. do {
  529. size_t maxs = len < (long) sizeof buf
  530. ? (size_t) len
  531. : sizeof buf;
  532. size_t size = fread(buf, 1, maxs, src);
  533. fwrite(buf, 1, size, dest);
  534. len -= (long) size;
  535. if (size < maxs) {
  536. break;
  537. }
  538. } while (len > 0);
  539. }
  540. #endif /* !UNIV_HOTBACKUP */
  541. #ifdef __WIN__
  542. # include <stdarg.h>
  543. /**********************************************************************//**
  544. A substitute for vsnprintf(3), formatted output conversion into
  545. a limited buffer. Note: this function DOES NOT return the number of
  546. characters that would have been printed if the buffer was unlimited because
  547. VC's _vsnprintf() returns -1 in this case and we would need to call
  548. _vscprintf() in addition to estimate that but we would need another copy
  549. of "ap" for that and VC does not provide va_copy(). */
  550. UNIV_INTERN
  551. void
  552. ut_vsnprintf(
  553. /*=========*/
  554. char* str, /*!< out: string */
  555. size_t size, /*!< in: str size */
  556. const char* fmt, /*!< in: format */
  557. va_list ap) /*!< in: format values */
  558. {
  559. _vsnprintf(str, size, fmt, ap);
  560. str[size - 1] = '\0';
  561. }
  562. /**********************************************************************//**
  563. A substitute for snprintf(3), formatted output conversion into
  564. a limited buffer.
  565. @return number of characters that would have been printed if the size
  566. were unlimited, not including the terminating '\0'. */
  567. UNIV_INTERN
  568. int
  569. ut_snprintf(
  570. /*========*/
  571. char* str, /*!< out: string */
  572. size_t size, /*!< in: str size */
  573. const char* fmt, /*!< in: format */
  574. ...) /*!< in: format values */
  575. {
  576. int res;
  577. va_list ap1;
  578. va_list ap2;
  579. va_start(ap1, fmt);
  580. va_start(ap2, fmt);
  581. res = _vscprintf(fmt, ap1);
  582. ut_a(res != -1);
  583. if (size > 0) {
  584. _vsnprintf(str, size, fmt, ap2);
  585. if ((size_t) res >= size) {
  586. str[size - 1] = '\0';
  587. }
  588. }
  589. va_end(ap1);
  590. va_end(ap2);
  591. return(res);
  592. }
  593. #endif /* __WIN__ */
  594. /*************************************************************//**
  595. Convert an error number to a human readable text message. The
  596. returned string is static and should not be freed or modified.
  597. @return string, describing the error */
  598. UNIV_INTERN
  599. const char*
  600. ut_strerr(
  601. /*======*/
  602. dberr_t num) /*!< in: error number */
  603. {
  604. switch (num) {
  605. case DB_SUCCESS:
  606. return("Success");
  607. case DB_SUCCESS_LOCKED_REC:
  608. return("Success, record lock created");
  609. case DB_ERROR:
  610. return("Generic error");
  611. case DB_READ_ONLY:
  612. return("Read only transaction");
  613. case DB_INTERRUPTED:
  614. return("Operation interrupted");
  615. case DB_OUT_OF_MEMORY:
  616. return("Cannot allocate memory");
  617. case DB_OUT_OF_FILE_SPACE:
  618. return("Out of disk space");
  619. case DB_LOCK_WAIT:
  620. return("Lock wait");
  621. case DB_DEADLOCK:
  622. return("Deadlock");
  623. case DB_ROLLBACK:
  624. return("Rollback");
  625. case DB_DUPLICATE_KEY:
  626. return("Duplicate key");
  627. case DB_QUE_THR_SUSPENDED:
  628. return("The queue thread has been suspended");
  629. case DB_MISSING_HISTORY:
  630. return("Required history data has been deleted");
  631. case DB_CLUSTER_NOT_FOUND:
  632. return("Cluster not found");
  633. case DB_TABLE_NOT_FOUND:
  634. return("Table not found");
  635. case DB_MUST_GET_MORE_FILE_SPACE:
  636. return("More file space needed");
  637. case DB_TABLE_IS_BEING_USED:
  638. return("Table is being used");
  639. case DB_TOO_BIG_RECORD:
  640. return("Record too big");
  641. case DB_TOO_BIG_INDEX_COL:
  642. return("Index columns size too big");
  643. case DB_LOCK_WAIT_TIMEOUT:
  644. return("Lock wait timeout");
  645. case DB_NO_REFERENCED_ROW:
  646. return("Referenced key value not found");
  647. case DB_ROW_IS_REFERENCED:
  648. return("Row is referenced");
  649. case DB_CANNOT_ADD_CONSTRAINT:
  650. return("Cannot add constraint");
  651. case DB_CORRUPTION:
  652. return("Data structure corruption");
  653. case DB_CANNOT_DROP_CONSTRAINT:
  654. return("Cannot drop constraint");
  655. case DB_NO_SAVEPOINT:
  656. return("No such savepoint");
  657. case DB_TABLESPACE_EXISTS:
  658. return("Tablespace already exists");
  659. case DB_TABLESPACE_DELETED:
  660. return("Tablespace deleted or being deleted");
  661. case DB_TABLESPACE_NOT_FOUND:
  662. return("Tablespace not found");
  663. case DB_LOCK_TABLE_FULL:
  664. return("Lock structs have exhausted the buffer pool");
  665. case DB_FOREIGN_DUPLICATE_KEY:
  666. return("Foreign key activated with duplicate keys");
  667. case DB_FOREIGN_EXCEED_MAX_CASCADE:
  668. return("Foreign key cascade delete/update exceeds max depth");
  669. case DB_TOO_MANY_CONCURRENT_TRXS:
  670. return("Too many concurrent transactions");
  671. case DB_UNSUPPORTED:
  672. return("Unsupported");
  673. case DB_INVALID_NULL:
  674. return("NULL value encountered in NOT NULL column");
  675. case DB_STATS_DO_NOT_EXIST:
  676. return("Persistent statistics do not exist");
  677. case DB_FAIL:
  678. return("Failed, retry may succeed");
  679. case DB_OVERFLOW:
  680. return("Overflow");
  681. case DB_UNDERFLOW:
  682. return("Underflow");
  683. case DB_STRONG_FAIL:
  684. return("Failed, retry will not succeed");
  685. case DB_ZIP_OVERFLOW:
  686. return("Zip overflow");
  687. case DB_RECORD_NOT_FOUND:
  688. return("Record not found");
  689. case DB_CHILD_NO_INDEX:
  690. return("No index on referencing keys in referencing table");
  691. case DB_PARENT_NO_INDEX:
  692. return("No index on referenced keys in referenced table");
  693. case DB_FTS_INVALID_DOCID:
  694. return("FTS Doc ID cannot be zero");
  695. case DB_INDEX_CORRUPT:
  696. return("Index corrupted");
  697. case DB_UNDO_RECORD_TOO_BIG:
  698. return("Undo record too big");
  699. case DB_END_OF_INDEX:
  700. return("End of index");
  701. case DB_IO_ERROR:
  702. return("I/O error");
  703. case DB_TABLE_IN_FK_CHECK:
  704. return("Table is being used in foreign key check");
  705. case DB_DATA_MISMATCH:
  706. return("data mismatch");
  707. case DB_SCHEMA_NOT_LOCKED:
  708. return("schema not locked");
  709. case DB_NOT_FOUND:
  710. return("not found");
  711. case DB_ONLINE_LOG_TOO_BIG:
  712. return("Log size exceeded during online index creation");
  713. case DB_DICT_CHANGED:
  714. return("Table dictionary has changed");
  715. case DB_IDENTIFIER_TOO_LONG:
  716. return("Identifier name is too long");
  717. case DB_FTS_EXCEED_RESULT_CACHE_LIMIT:
  718. return("FTS query exceeds result cache limit");
  719. case DB_TEMP_FILE_WRITE_FAILURE:
  720. return("Temp file write failure");
  721. case DB_FTS_TOO_MANY_WORDS_IN_PHRASE:
  722. return("Too many words in a FTS phrase or proximity search");
  723. /* do not add default: in order to produce a warning if new code
  724. is added to the enum but not added here */
  725. }
  726. /* we abort here because if unknown error code is given, this could
  727. mean that memory corruption has happened and someone's error-code
  728. variable has been overwritten with bogus data */
  729. ut_error;
  730. /* NOT REACHED */
  731. return("Unknown error");
  732. }
  733. #endif /* !UNIV_INNOCHECKSUM */