Drizzled Public API Documentation

ut0ut.cc
1 /*****************************************************************************
2 
3 Copyright (C) 1994, 2010, Innobase Oy. All Rights Reserved.
4 Copyright (C) 2009 Sun Microsystems, Inc.
5 
6 Portions of this file contain modifications contributed and copyrighted by
7 Sun Microsystems, Inc. Those modifications are gratefully acknowledged and
8 are described briefly in the InnoDB documentation. The contributions by
9 Sun Microsystems are incorporated with their permission, and subject to the
10 conditions contained in the file COPYING.Sun_Microsystems.
11 
12 This program is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License as published by the Free Software
14 Foundation; version 2 of the License.
15 
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License along with
21 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
22 St, Fifth Floor, Boston, MA 02110-1301 USA
23 
24 *****************************************************************************/
25 
26 /***************************************************************/
33 #include "ut0ut.h"
34 
35 #ifdef UNIV_NONINL
36 #include "ut0ut.ic"
37 #endif
38 
39 #include <stdarg.h>
40 #include <string.h>
41 #include <ctype.h>
42 
43 #ifndef UNIV_HOTBACKUP
44 # include "trx0trx.h"
45 # if defined(BUILD_DRIZZLE)
46 # include "drizzled/common.h"
47 # if TIME_WITH_SYS_TIME
48 # include <sys/time.h>
49 # include <time.h>
50 # else
51 # if HAVE_SYS_TIME_H
52 # include <sys/time.h>
53 # else
54 # include <time.h>
55 # endif
56 # endif
57 # else
58 # include "ha_prototypes.h"
59 # include "mysql_com.h" /* NAME_LEN */
60 # endif /* DRIZZLE */
61 #endif /* UNIV_HOTBACKUP */
62 #include <errno.h>
63 #include <assert.h>
64 
66 UNIV_INTERN ibool ut_always_false = FALSE;
67 
68 #ifdef __WIN__
69 /*****************************************************************/
73 #define WIN_TO_UNIX_DELTA_USEC ((ib_int64_t) 11644473600000000ULL)
74 
75 
76 /*****************************************************************/
79 static
80 int
81 ut_gettimeofday(
82 /*============*/
83  struct timeval* tv,
84  void* tz)
85 {
86  FILETIME ft;
87  ib_int64_t tm;
88 
89  if (!tv) {
90  errno = EINVAL;
91  return(-1);
92  }
93 
94  GetSystemTimeAsFileTime(&ft);
95 
96  tm = (ib_int64_t) ft.dwHighDateTime << 32;
97  tm |= ft.dwLowDateTime;
98 
99  ut_a(tm >= 0); /* If tm wraps over to negative, the quotient / 10
100  does not work */
101 
102  tm /= 10; /* Convert from 100 nsec periods to usec */
103 
104  /* If we don't convert to the Unix epoch the value for
105  struct timeval::tv_sec will overflow.*/
106  tm -= WIN_TO_UNIX_DELTA_USEC;
107 
108  tv->tv_sec = (long) (tm / 1000000L);
109  tv->tv_usec = (long) (tm % 1000000L);
110 
111  return(0);
112 }
113 #else
114 
116 #define ut_gettimeofday gettimeofday
117 #endif
118 
119 /********************************************************/
124 UNIV_INTERN
125 ulint
127 /*==========*/
128  ulint a)
129 {
130  ib_int64_t i;
131 
132  i = (ib_int64_t)a;
133 
134  i = i >> 32;
135 
136  return((ulint)i);
137 }
138 
139 /**********************************************************/
143 UNIV_INTERN
144 ib_time_t
145 ut_time(void)
146 /*=========*/
147 {
148  return(time(NULL));
149 }
150 
151 #ifndef UNIV_HOTBACKUP
152 /**********************************************************/
158 UNIV_INTERN
159 int
161 /*========*/
162  ulint* sec,
163  ulint* ms)
164 {
165  struct timeval tv;
166  int ret;
167  int errno_gettimeofday;
168  int i;
169 
170  for (i = 0; i < 10; i++) {
171 
172  ret = ut_gettimeofday(&tv, NULL);
173 
174  if (ret == -1) {
175  errno_gettimeofday = errno;
176  ut_print_timestamp(stderr);
177  fprintf(stderr, " InnoDB: gettimeofday(): %s\n",
178  strerror(errno_gettimeofday));
179  os_thread_sleep(100000); /* 0.1 sec */
180  errno = errno_gettimeofday;
181  } else {
182  break;
183  }
184  }
185 
186  if (ret != -1) {
187  *sec = (ulint) tv.tv_sec;
188  *ms = (ulint) tv.tv_usec;
189  }
190 
191  return(ret);
192 }
193 
194 /**********************************************************/
199 UNIV_INTERN
200 ullint
202 /*=======*/
203  ullint* tloc)
204 {
205  struct timeval tv;
206  ullint us;
207 
208  ut_gettimeofday(&tv, NULL);
209 
210  us = (ullint) tv.tv_sec * 1000000 + tv.tv_usec;
211 
212  if (tloc != NULL) {
213  *tloc = us;
214  }
215 
216  return(us);
217 }
218 
219 /**********************************************************/
224 UNIV_INTERN
225 ulint
227 /*============*/
228 {
229  struct timeval tv;
230 
231  ut_gettimeofday(&tv, NULL);
232 
233  return((ulint) tv.tv_sec * 1000 + tv.tv_usec / 1000);
234 }
235 #endif /* !UNIV_HOTBACKUP */
236 
237 /**********************************************************/
240 UNIV_INTERN
241 double
243 /*========*/
244  ib_time_t time2,
245  ib_time_t time1)
246 {
247  return(difftime(time2, time1));
248 }
249 
250 /**********************************************************/
252 UNIV_INTERN
253 void
255 /*===============*/
256  FILE* file)
257 {
258 #ifdef __WIN__
259  SYSTEMTIME cal_tm;
260 
261  GetLocalTime(&cal_tm);
262 
263  fprintf(file,"%02d%02d%02d %2d:%02d:%02d",
264  (int)cal_tm.wYear % 100,
265  (int)cal_tm.wMonth,
266  (int)cal_tm.wDay,
267  (int)cal_tm.wHour,
268  (int)cal_tm.wMinute,
269  (int)cal_tm.wSecond);
270 #else
271  struct tm cal_tm;
272  struct tm* cal_tm_ptr;
273  time_t tm;
274 
275  time(&tm);
276 
277 #ifdef HAVE_LOCALTIME_R
278  localtime_r(&tm, &cal_tm);
279  cal_tm_ptr = &cal_tm;
280 #else
281  cal_tm_ptr = localtime(&tm);
282 #endif
283  fprintf(file,"%02d%02d%02d %2d:%02d:%02d",
284  cal_tm_ptr->tm_year % 100,
285  cal_tm_ptr->tm_mon + 1,
286  cal_tm_ptr->tm_mday,
287  cal_tm_ptr->tm_hour,
288  cal_tm_ptr->tm_min,
289  cal_tm_ptr->tm_sec);
290 #endif
291 }
292 
293 /**********************************************************/
295 UNIV_INTERN
296 void
298 /*=================*/
299  char* buf)
300 {
301 #ifdef __WIN__
302  SYSTEMTIME cal_tm;
303 
304  GetLocalTime(&cal_tm);
305 
306  sprintf(buf, "%02d%02d%02d %2d:%02d:%02d",
307  (int)cal_tm.wYear % 100,
308  (int)cal_tm.wMonth,
309  (int)cal_tm.wDay,
310  (int)cal_tm.wHour,
311  (int)cal_tm.wMinute,
312  (int)cal_tm.wSecond);
313 #else
314  struct tm cal_tm;
315  struct tm* cal_tm_ptr;
316  time_t tm;
317 
318  time(&tm);
319 
320 #ifdef HAVE_LOCALTIME_R
321  localtime_r(&tm, &cal_tm);
322  cal_tm_ptr = &cal_tm;
323 #else
324  cal_tm_ptr = localtime(&tm);
325 #endif
326  sprintf(buf, "%02d%02d%02d %2d:%02d:%02d",
327  cal_tm_ptr->tm_year % 100,
328  cal_tm_ptr->tm_mon + 1,
329  cal_tm_ptr->tm_mday,
330  cal_tm_ptr->tm_hour,
331  cal_tm_ptr->tm_min,
332  cal_tm_ptr->tm_sec);
333 #endif
334 }
335 
336 #ifdef UNIV_HOTBACKUP
337 /**********************************************************/
340 UNIV_INTERN
341 void
342 ut_sprintf_timestamp_without_extra_chars(
343 /*=====================================*/
344  char* buf)
345 {
346 #ifdef __WIN__
347  SYSTEMTIME cal_tm;
348 
349  GetLocalTime(&cal_tm);
350 
351  sprintf(buf, "%02d%02d%02d_%2d_%02d_%02d",
352  (int)cal_tm.wYear % 100,
353  (int)cal_tm.wMonth,
354  (int)cal_tm.wDay,
355  (int)cal_tm.wHour,
356  (int)cal_tm.wMinute,
357  (int)cal_tm.wSecond);
358 #else
359  struct tm cal_tm;
360  struct tm* cal_tm_ptr;
361  time_t tm;
362 
363  time(&tm);
364 
365 #ifdef HAVE_LOCALTIME_R
366  localtime_r(&tm, &cal_tm);
367  cal_tm_ptr = &cal_tm;
368 #else
369  cal_tm_ptr = localtime(&tm);
370 #endif
371  sprintf(buf, "%02d%02d%02d_%2d_%02d_%02d",
372  cal_tm_ptr->tm_year % 100,
373  cal_tm_ptr->tm_mon + 1,
374  cal_tm_ptr->tm_mday,
375  cal_tm_ptr->tm_hour,
376  cal_tm_ptr->tm_min,
377  cal_tm_ptr->tm_sec);
378 #endif
379 }
380 
381 /**********************************************************/
383 UNIV_INTERN
384 void
385 ut_get_year_month_day(
386 /*==================*/
387  ulint* year,
388  ulint* month,
389  ulint* day)
390 {
391 #ifdef __WIN__
392  SYSTEMTIME cal_tm;
393 
394  GetLocalTime(&cal_tm);
395 
396  *year = (ulint)cal_tm.wYear;
397  *month = (ulint)cal_tm.wMonth;
398  *day = (ulint)cal_tm.wDay;
399 #else
400  struct tm cal_tm;
401  struct tm* cal_tm_ptr;
402  time_t tm;
403 
404  time(&tm);
405 
406 #ifdef HAVE_LOCALTIME_R
407  localtime_r(&tm, &cal_tm);
408  cal_tm_ptr = &cal_tm;
409 #else
410  cal_tm_ptr = localtime(&tm);
411 #endif
412  *year = (ulint)cal_tm_ptr->tm_year + 1900;
413  *month = (ulint)cal_tm_ptr->tm_mon + 1;
414  *day = (ulint)cal_tm_ptr->tm_mday;
415 #endif
416 }
417 #endif /* UNIV_HOTBACKUP */
418 
419 #ifndef UNIV_HOTBACKUP
420 /*************************************************************/
424 UNIV_INTERN
425 ulint
427 /*=====*/
428  ulint delay)
429 {
430  ulint i, j;
431 
432  j = 0;
433 
434  for (i = 0; i < delay * 50; i++) {
435  j += i;
436  UT_RELAX_CPU();
437  }
438 
439  if (ut_always_false) {
440  ut_always_false = (ibool) j;
441  }
442 
443  return(j);
444 }
445 #endif /* !UNIV_HOTBACKUP */
446 
447 /*************************************************************/
449 UNIV_INTERN
450 void
452 /*=========*/
453  FILE* file,
454  const void* buf,
455  ulint len)
456 {
457  const byte* data;
458  ulint i;
459 
460  UNIV_MEM_ASSERT_RW(buf, len);
461 
462  fprintf(file, " len %lu; hex ", len);
463 
464  for (data = (const byte*)buf, i = 0; i < len; i++) {
465  fprintf(file, "%02lx", (ulong)*data++);
466  }
467 
468  fputs("; asc ", file);
469 
470  data = (const byte*)buf;
471 
472  for (i = 0; i < len; i++) {
473  int c = (int) *data++;
474  putc(isprint(c) ? c : ' ', file);
475  }
476 
477  putc(';', file);
478 }
479 
480 /*************************************************************/
483 UNIV_INTERN
484 ulint
486 /*==========*/
487  ulint n)
488 {
489  ulint res;
490 
491  res = 1;
492 
493  ut_ad(n > 0);
494 
495  while (res < n) {
496  res = res * 2;
497  }
498 
499  return(res);
500 }
501 
502 /**********************************************************************/
504 UNIV_INTERN
505 void
507 /*==============*/
508  FILE* f,
509  const char* name)
510 {
511  putc('\'', f);
512  for (;;) {
513  int c = *name++;
514  switch (c) {
515  case 0:
516  goto done;
517  case '\'':
518  putc(c, f);
519  /* fall through */
520  default:
521  putc(c, f);
522  }
523  }
524 done:
525  putc('\'', f);
526 }
527 #ifndef UNIV_HOTBACKUP
528 /**********************************************************************/
533 UNIV_INTERN
534 void
536 /*==========*/
537  FILE* f,
538  trx_t* trx,
539  ibool table_id,
541  const char* name)
542 {
543  ut_print_namel(f, trx, table_id, name, strlen(name));
544 }
545 
546 /**********************************************************************/
551 UNIV_INTERN
552 void
554 /*===========*/
555  FILE* f,
556  trx_t* trx,
557  ibool table_id,
559  const char* name,
560  ulint namelen)
561 {
562  /* 2 * NAME_LEN for database and table name,
563  and some slack for the #mysql50# prefix and quotes */
564  char buf[3 * NAME_LEN];
565  const char* bufend;
566 
567  bufend = innobase_convert_name(buf, sizeof buf,
568  name, namelen,
569  trx ? trx->mysql_thd : NULL,
570  table_id);
571 
572  ssize_t ret= fwrite(buf, 1, bufend - buf, f);
573  assert(ret==bufend-buf);
574 }
575 
576 /**********************************************************************/
578 UNIV_INTERN
579 void
581 /*=========*/
582  FILE* dest,
583  FILE* src)
584 {
585  long len = ftell(src);
586  char buf[4096];
587 
588  rewind(src);
589  do {
590  size_t maxs = len < (long) sizeof buf
591  ? (size_t) len
592  : sizeof buf;
593  size_t size = fread(buf, 1, maxs, src);
594  size_t ret= fwrite(buf, 1, size, dest);
595  assert(ret==size);
596  len -= (long) size;
597  if (size < maxs) {
598  break;
599  }
600  } while (len > 0);
601 }
602 #endif /* !UNIV_HOTBACKUP */
603 
604 #ifdef __WIN__
605 # include <stdarg.h>
606 /**********************************************************************/
611 UNIV_INTERN
612 int
614 /*========*/
615  char* str,
616  size_t size,
617  const char* fmt,
618  ...)
619 {
620  int res;
621  va_list ap1;
622  va_list ap2;
623 
624  va_start(ap1, fmt);
625  va_start(ap2, fmt);
626 
627  res = _vscprintf(fmt, ap1);
628  ut_a(res != -1);
629 
630  if (size > 0) {
631  _vsnprintf(str, size, fmt, ap2);
632 
633  if ((size_t) res >= size) {
634  str[size - 1] = '\0';
635  }
636  }
637 
638  va_end(ap1);
639  va_end(ap2);
640 
641  return(res);
642 }
643 #endif /* __WIN__ */
644 
645 /*************************************************************/
649 UNIV_INTERN
650 const char*
652 /*======*/
653  enum db_err num)
654 {
655  switch (num) {
656  case DB_SUCCESS:
657  return("Success");
659  return("Success, record lock created");
660  case DB_ERROR:
661  return("Generic error");
662  case DB_INTERRUPTED:
663  return("Operation interrupted");
664  case DB_OUT_OF_MEMORY:
665  return("Cannot allocate memory");
666  case DB_OUT_OF_FILE_SPACE:
667  return("Out of disk space");
668  case DB_LOCK_WAIT:
669  return("Lock wait");
670  case DB_DEADLOCK:
671  return("Deadlock");
672  case DB_ROLLBACK:
673  return("Rollback");
674  case DB_DUPLICATE_KEY:
675  return("Duplicate key");
676  case DB_QUE_THR_SUSPENDED:
677  return("The queue thread has been suspended");
678  case DB_MISSING_HISTORY:
679  return("Required history data has been deleted");
680  case DB_CLUSTER_NOT_FOUND:
681  return("Cluster not found");
682  case DB_TABLE_NOT_FOUND:
683  return("Table not found");
684  case DB_MUST_GET_MORE_FILE_SPACE:
685  return("More file space needed");
686  case DB_TABLE_IS_BEING_USED:
687  return("Table is being used");
688  case DB_TOO_BIG_RECORD:
689  return("Record too big");
690  case DB_LOCK_WAIT_TIMEOUT:
691  return("Lock wait timeout");
692  case DB_NO_REFERENCED_ROW:
693  return("Referenced key value not found");
694  case DB_ROW_IS_REFERENCED:
695  return("Row is referenced");
696  case DB_CANNOT_ADD_CONSTRAINT:
697  return("Cannot add constraint");
698  case DB_CORRUPTION:
699  return("Data structure corruption");
700  case DB_COL_APPEARS_TWICE_IN_INDEX:
701  return("Column appears twice in index");
702  case DB_CANNOT_DROP_CONSTRAINT:
703  return("Cannot drop constraint");
704  case DB_NO_SAVEPOINT:
705  return("No such savepoint");
706  case DB_TABLESPACE_ALREADY_EXISTS:
707  return("Tablespace already exists");
708  case DB_TABLESPACE_DELETED:
709  return("No such tablespace");
710  case DB_LOCK_TABLE_FULL:
711  return("Lock structs have exhausted the buffer pool");
712  case DB_FOREIGN_DUPLICATE_KEY:
713  return("Foreign key activated with duplicate keys");
714  case DB_FOREIGN_EXCEED_MAX_CASCADE:
715  return("Foreign key cascade delete/update exceeds max depth");
716  case DB_TOO_MANY_CONCURRENT_TRXS:
717  return("Too many concurrent transactions");
718  case DB_UNSUPPORTED:
719  return("Unsupported");
720  case DB_PRIMARY_KEY_IS_NULL:
721  return("Primary key is NULL");
722  case DB_STATS_DO_NOT_EXIST:
723  return("Persistent statistics do not exist");
724  case DB_FAIL:
725  return("Failed, retry may succeed");
726  case DB_OVERFLOW:
727  return("Overflow");
728  case DB_UNDERFLOW:
729  return("Underflow");
730  case DB_STRONG_FAIL:
731  return("Failed, retry will not succeed");
732  case DB_ZIP_OVERFLOW:
733  return("Zip overflow");
734  case DB_RECORD_NOT_FOUND:
735  return("Record not found");
736  case DB_CHILD_NO_INDEX:
737  return("No index on referencing keys in referencing table");
738  case DB_PARENT_NO_INDEX:
739  return("No index on referenced keys in referenced table");
740  case DB_END_OF_INDEX:
741  return("End of index");
742  /* do not add default: in order to produce a warning if new code
743  is added to the enum but not added here */
744  }
745 
746  /* we abort here because if unknown error code is given, this could
747  mean that memory corruption has happened and someone's error-code
748  variable has been overwritten with bogus data */
749  ut_error;
750 
751  /* NOT REACHED */
752  return("Unknown error");
753 }