MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
api0api.cc
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (c) 2008, 2013, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free Software
7 Foundation; version 2 of the License.
8 
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
16 
17 *****************************************************************************/
18 
19 /**************************************************/
27 #include "univ.i"
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <stdarg.h>
33 #ifdef HAVE_UNISTD_H
34 #include <unistd.h>
35 #endif
36 
37 #include "api0api.h"
38 #include "api0misc.h"
39 #include "srv0start.h"
40 #include "dict0dict.h"
41 #include "btr0pcur.h"
42 #include "row0ins.h"
43 #include "row0upd.h"
44 #include "row0vers.h"
45 #include "trx0roll.h"
46 #include "dict0crea.h"
47 #include "row0merge.h"
48 #include "pars0pars.h"
49 #include "lock0types.h"
50 #include "row0sel.h"
51 #include "lock0lock.h"
52 #include "rem0cmp.h"
53 #include "ut0dbg.h"
54 #include "dict0priv.h"
55 #include "ut0ut.h"
56 #include "ha_prototypes.h"
57 #include "trx0roll.h"
58 
60 my_bool ib_binlog_enabled = FALSE;
61 
63 my_bool ib_mdl_enabled = FALSE;
64 
66 my_bool ib_disable_row_lock = FALSE;
67 
70 
73 
78 };
79 
86 };
87 
89 struct ib_qry_grph_t {
96 };
97 
99 struct ib_qry_node_t {
106 };
107 
110 
114 };
115 
118 struct ib_cursor_t {
129  bool valid_trx;
130 };
131 
133 struct ib_col_t {
134  const char* name;
138  ulint len;
142 };
143 
145 struct ib_key_col_t {
146  const char* name;
148  ulint prefix_len;
149 };
150 
151 struct ib_table_def_t;
152 
158  const char* name;
165  ibool clustered;
167  ibool unique;
173 };
174 
179  const char* name;
183  ulint page_size;
189  dict_table_t* table; /* Table read from or NULL */
190 };
191 
193 struct ib_tuple_t {
205 };
206 
212 #define INNOBASE_WAKE_INTERVAL 32
213 
214 /*****************************************************************/
217 UNIV_INLINE
218 ib_bool_t
220 /*========================*/
221  btr_pcur_t* pcur)
222 {
223  return(pcur->old_stored == BTR_PCUR_OLD_STORED
224  && (pcur->pos_state == BTR_PCUR_IS_POSITIONED
225  || pcur->pos_state == BTR_PCUR_WAS_POSITIONED));
226 }
227 
228 
229 /********************************************************************/
232 static
234 ib_open_table_by_id(
235 /*================*/
236  ib_id_u64_t tid,
237  ib_bool_t locked)
238 {
240  table_id_t table_id;
241 
242  table_id = tid;
243 
244  if (!locked) {
246  }
247 
248  table = dict_table_open_on_id(table_id, FALSE, DICT_TABLE_OP_NORMAL);
249 
250  if (table != NULL && table->ibd_file_missing) {
251  table = NULL;
252  }
253 
254  if (!locked) {
256  }
257 
258  return(table);
259 }
260 
261 /********************************************************************/
264 UNIV_INTERN
265 void*
267 /*==================*/
268  const char* name)
269 {
271 
272  table = dict_table_open_on_name(name, FALSE, FALSE,
274 
275  if (table != NULL && table->ibd_file_missing) {
276  table = NULL;
277  }
278 
279  return(table);
280 }
281 
282 /********************************************************************/
285 static
287 ib_lookup_table_by_name(
288 /*====================*/
289  const char* name)
290 {
292 
293  table = dict_table_get_low(name);
294 
295  if (table != NULL && table->ibd_file_missing) {
296  table = NULL;
297  }
298 
299  return(table);
300 }
301 
302 /********************************************************************/
307 UNIV_INLINE
308 void
310 /*=======================*/
311 {
312  static ulint ib_signal_counter = 0;
313 
314  ++ib_signal_counter;
315 
316  if ((ib_signal_counter % INNOBASE_WAKE_INTERVAL) == 0) {
318  }
319 }
320 
321 /*********************************************************************/
324 UNIV_INLINE
325 ulint
327 /*===============*/
328  dict_index_t* cluster)
329 {
330  ulint i;
331  ulint max_len = 0;
332  ulint n_fields = cluster->n_fields;
333 
334  /* Add the size of the ordering columns in the
335  clustered index. */
336  for (i = 0; i < n_fields; ++i) {
337  const dict_col_t* col;
338 
339  col = dict_index_get_nth_col(cluster, i);
340 
341  /* Use the maximum output size of
342  mach_write_compressed(), although the encoded
343  length should always fit in 2 bytes. */
344  max_len += dict_col_get_max_size(col);
345  }
346 
347  return(max_len);
348 }
349 
350 /*****************************************************************/
352 static
353 void
354 ib_read_tuple(
355 /*==========*/
356  const rec_t* rec,
357  ib_bool_t page_format,
358  ib_tuple_t* tuple)
359 {
360  ulint i;
361  void* ptr;
362  rec_t* copy;
363  ulint rec_meta_data;
364  ulint n_index_fields;
365  ulint offsets_[REC_OFFS_NORMAL_SIZE];
366  ulint* offsets = offsets_;
367  dtuple_t* dtuple = tuple->ptr;
368  const dict_index_t* index = tuple->index;
369 
370  rec_offs_init(offsets_);
371 
372  offsets = rec_get_offsets(
373  rec, index, offsets, ULINT_UNDEFINED, &tuple->heap);
374 
375  rec_meta_data = rec_get_info_bits(rec, page_format);
376  dtuple_set_info_bits(dtuple, rec_meta_data);
377 
378  /* Make a copy of the rec. */
379  ptr = mem_heap_alloc(tuple->heap, rec_offs_size(offsets));
380  copy = rec_copy(ptr, rec, offsets);
381 
382  n_index_fields = ut_min(
383  rec_offs_n_fields(offsets), dtuple_get_n_fields(dtuple));
384 
385  for (i = 0; i < n_index_fields; ++i) {
386  ulint len;
387  const byte* data;
388  dfield_t* dfield;
389 
390  if (tuple->type == TPL_TYPE_ROW) {
391  const dict_col_t* col;
392  ulint col_no;
393  const dict_field_t* index_field;
394 
395  index_field = dict_index_get_nth_field(index, i);
396  col = dict_field_get_col(index_field);
397  col_no = dict_col_get_no(col);
398 
399  dfield = dtuple_get_nth_field(dtuple, col_no);
400  } else {
401  dfield = dtuple_get_nth_field(dtuple, i);
402  }
403 
404  data = rec_get_nth_field(copy, offsets, i, &len);
405 
406  /* Fetch and copy any externally stored column. */
407  if (rec_offs_nth_extern(offsets, i)) {
408 
409  ulint zip_size;
410 
411  zip_size = dict_table_zip_size(index->table);
412 
414  copy, offsets, zip_size, i, &len,
415  tuple->heap);
416 
417  ut_a(len != UNIV_SQL_NULL);
418  }
419 
420  dfield_set_data(dfield, data, len);
421  }
422 }
423 
424 /*****************************************************************/
427 static
428 ib_tpl_t
429 ib_key_tuple_new_low(
430 /*=================*/
431  const dict_index_t* index,
433  ulint n_cols,
434  mem_heap_t* heap)
435 {
436  ib_tuple_t* tuple;
437  ulint i;
438  ulint n_cmp_cols;
439 
440  tuple = static_cast<ib_tuple_t*>(
441  mem_heap_alloc(heap, sizeof(*tuple)));
442 
443  if (tuple == NULL) {
444  mem_heap_free(heap);
445  return(NULL);
446  }
447 
448  tuple->heap = heap;
449  tuple->index = index;
450  tuple->type = TPL_TYPE_KEY;
451 
452  /* Is it a generated clustered index ? */
453  if (n_cols == 0) {
454  ++n_cols;
455  }
456 
457  tuple->ptr = dtuple_create(heap, n_cols);
458 
459  /* Copy types and set to SQL_NULL. */
460  dict_index_copy_types(tuple->ptr, index, n_cols);
461 
462  for (i = 0; i < n_cols; i++) {
463 
464  dfield_t* dfield;
465 
466  dfield = dtuple_get_nth_field(tuple->ptr, i);
467  dfield_set_null(dfield);
468  }
469 
470  n_cmp_cols = dict_index_get_n_ordering_defined_by_user(index);
471 
472  dtuple_set_n_fields_cmp(tuple->ptr, n_cmp_cols);
473 
474  return((ib_tpl_t) tuple);
475 }
476 
477 /*****************************************************************/
480 static
481 ib_tpl_t
482 ib_key_tuple_new(
483 /*=============*/
484  const dict_index_t* index,
485  ulint n_cols)
486 {
487  mem_heap_t* heap;
488 
489  heap = mem_heap_create(64);
490 
491  if (heap == NULL) {
492  return(NULL);
493  }
494 
495  return(ib_key_tuple_new_low(index, n_cols, heap));
496 }
497 
498 /*****************************************************************/
501 static
502 ib_tpl_t
503 ib_row_tuple_new_low(
504 /*=================*/
505  const dict_index_t* index,
506  ulint n_cols,
507  mem_heap_t* heap)
508 {
509  ib_tuple_t* tuple;
510 
511  tuple = static_cast<ib_tuple_t*>(mem_heap_alloc(heap, sizeof(*tuple)));
512 
513  if (tuple == NULL) {
514  mem_heap_free(heap);
515  return(NULL);
516  }
517 
518  tuple->heap = heap;
519  tuple->index = index;
520  tuple->type = TPL_TYPE_ROW;
521 
522  tuple->ptr = dtuple_create(heap, n_cols);
523 
524  /* Copy types and set to SQL_NULL. */
525  dict_table_copy_types(tuple->ptr, index->table);
526 
527  return((ib_tpl_t) tuple);
528 }
529 
530 /*****************************************************************/
533 static
534 ib_tpl_t
535 ib_row_tuple_new(
536 /*=============*/
537  const dict_index_t* index,
538  ulint n_cols)
539 {
540  mem_heap_t* heap;
541 
542  heap = mem_heap_create(64);
543 
544  if (heap == NULL) {
545  return(NULL);
546  }
547 
548  return(ib_row_tuple_new_low(index, n_cols, heap));
549 }
550 
551 /*****************************************************************/
554 UNIV_INTERN
555 ib_err_t
557 /*=========*/
558  ib_trx_t ib_trx,
559  ib_trx_level_t ib_trx_level,
560  void* thd)
561 {
562  ib_err_t err = DB_SUCCESS;
563  trx_t* trx = (trx_t*) ib_trx;
564 
565  ut_a(ib_trx_level <= IB_TRX_SERIALIZABLE);
566 
567  trx_start_if_not_started(trx);
568 
569  trx->isolation_level = ib_trx_level;
570 
571  /* FIXME: This is a place holder, we should add an arg that comes
572  from the client. */
573  trx->mysql_thd = static_cast<THD*>(thd);
574 
575  return(err);
576 }
577 
578 /*****************************************************************/
582 UNIV_INTERN
583 ib_trx_t
585 /*=========*/
586  ib_trx_level_t ib_trx_level)
587 {
588  trx_t* trx;
589  ib_bool_t started;
590 
591  trx = trx_allocate_for_mysql();
592  started = ib_trx_start((ib_trx_t) trx, ib_trx_level, NULL);
593  ut_a(started);
594 
595  return((ib_trx_t) trx);
596 }
597 
598 /*****************************************************************/
601 UNIV_INTERN
604 /*=========*/
605  ib_trx_t ib_trx)
606 {
607  trx_t* trx = (trx_t*) ib_trx;
608 
609  return((ib_trx_state_t) trx->state);
610 }
611 
612 /*****************************************************************/
615 UNIV_INTERN
616 ib_u64_t
618 /*==================*/
619  ib_trx_t ib_trx)
620 {
621  trx_t* trx = (trx_t*) ib_trx;
622  return(static_cast<ib_u64_t>(trx->start_time));
623 }
624 /*****************************************************************/
627 UNIV_INTERN
628 ib_err_t
630 /*===========*/
631  ib_trx_t ib_trx)
632 {
633  trx_t* trx = (trx_t*) ib_trx;
634 
635  ut_ad(trx != NULL);
636  trx_free_for_mysql(trx);
637 
638  return(DB_SUCCESS);
639 }
640 
641 /*****************************************************************/
646 ib_err_t
648 /*==========*/
649  ib_trx_t ib_trx)
650 {
651  ib_err_t err = DB_SUCCESS;
652  trx_t* trx = (trx_t*) ib_trx;
653 
654  if (trx->state == TRX_STATE_NOT_STARTED) {
655  err = ib_trx_release(ib_trx);
656  return(err);
657  }
658 
659  trx_commit(trx);
660 
661  err = ib_trx_release(ib_trx);
662  ut_a(err == DB_SUCCESS);
663 
664  return(DB_SUCCESS);
665 }
666 
667 /*****************************************************************/
671 UNIV_INTERN
672 ib_err_t
674 /*============*/
675  ib_trx_t ib_trx)
676 {
677  ib_err_t err;
678  trx_t* trx = (trx_t*) ib_trx;
679 
680  err = static_cast<ib_err_t>(trx_rollback_for_mysql(trx));
681 
682  /* It should always succeed */
683  ut_a(err == DB_SUCCESS);
684 
685  err = ib_trx_release(ib_trx);
686  ut_a(err == DB_SUCCESS);
687 
689 
690  return(err);
691 }
692 
693 /*****************************************************************/
696 UNIV_INLINE
697 const ib_index_def_t*
699 /*================*/
700  ib_vector_t* indexes,
701  const char* name)
702 {
703  ulint i;
704 
705  for (i = 0; i < ib_vector_size(indexes); ++i) {
706  const ib_index_def_t* index_def;
707 
708  index_def = (ib_index_def_t*) ib_vector_get(indexes, i);
709 
710  if (innobase_strcasecmp(name, index_def->name) == 0) {
711  return(index_def);
712  }
713  }
714 
715  return(NULL);
716 }
717 
718 /*****************************************************************/
721 UNIV_INLINE
722 ulint
724 /*==============*/
725  const ib_col_t* ib_col)
726 {
727  ulint prtype = 0;
728 
729  if (ib_col->ib_col_attr & IB_COL_UNSIGNED) {
730  prtype |= DATA_UNSIGNED;
731 
732  ut_a(ib_col->ib_col_type == IB_INT);
733  }
734 
735  if (ib_col->ib_col_attr & IB_COL_NOT_NULL) {
736  prtype |= DATA_NOT_NULL;
737  }
738 
739  return(prtype);
740 }
741 
742 /*****************************************************************/
745 UNIV_INLINE
746 ulint
748 /*==============*/
749  const ib_col_t* ib_col)
750 {
751  /* Note: The api0api.h types should map directly to
752  the internal numeric codes. */
753  return(ib_col->ib_col_type);
754 }
755 
756 /*****************************************************************/
759 UNIV_INLINE
760 const ib_col_t*
762 /*==============*/
763  const ib_vector_t* cols,
764  const char* name)
765 {
766  ulint i;
767 
768  for (i = 0; i < ib_vector_size(cols); ++i) {
769  const ib_col_t* ib_col;
770 
771  ib_col = static_cast<const ib_col_t*>(
772  ib_vector_get((ib_vector_t*) cols, i));
773 
774  if (innobase_strcasecmp(ib_col->name, name) == 0) {
775  return(ib_col);
776  }
777  }
778 
779  return(NULL);
780 }
781 
782 /*****************************************************************/
785 UNIV_INLINE
786 const ib_key_col_t*
788 /*==============*/
789  ib_vector_t* cols,
790  const char* name)
791 {
792  ulint i;
793 
794  for (i = 0; i < ib_vector_size(cols); ++i) {
795  const ib_key_col_t* ib_col;
796 
797  ib_col = static_cast<ib_key_col_t*>(ib_vector_get(cols, i));
798 
799  if (innobase_strcasecmp(ib_col->name, name) == 0) {
800  return(ib_col);
801  }
802  }
803 
804  return(NULL);
805 }
806 
807 #ifdef __WIN__
808 /*****************************************************************/
810 static
811 void
812 ib_to_lower_case(
813 /*=============*/
814  char* ptr)
815 {
816  while (*ptr) {
817  *ptr = tolower(*ptr);
818  ++ptr;
819  }
820 }
821 #endif /* __WIN__ */
822 
823 /*****************************************************************/
832 static
833 void
834 ib_normalize_table_name(
835 /*====================*/
836  char* norm_name,
838  const char* name)
839 {
840  const char* ptr = name;
841 
842  /* Scan name from the end */
843 
844  ptr += ut_strlen(name) - 1;
845 
846  /* Find the start of the table name. */
847  while (ptr >= name && *ptr != '\\' && *ptr != '/' && ptr > name) {
848  --ptr;
849  }
850 
851 
852  /* For system tables there is no '/' or dbname. */
853  ut_a(ptr >= name);
854 
855  if (ptr > name) {
856  const char* db_name;
857  const char* table_name;
858 
859  table_name = ptr + 1;
860 
861  --ptr;
862 
863  while (ptr >= name && *ptr != '\\' && *ptr != '/') {
864  ptr--;
865  }
866 
867  db_name = ptr + 1;
868 
869  memcpy(norm_name, db_name,
870  ut_strlen(name) + 1 - (db_name - name));
871 
872  norm_name[table_name - db_name - 1] = '/';
873 #ifdef __WIN__
874  ib_to_lower_case(norm_name);
875 #endif
876  } else {
877  ut_strcpy(norm_name, name);
878  }
879 }
880 
881 /*****************************************************************/
885 UNIV_INTERN
886 ib_err_t
888 /*================*/
889  const char* name)
890 {
891  const char* slash = NULL;
892  ulint len = ut_strlen(name);
893 
894  if (len < 2
895  || *name == '/'
896  || name[len - 1] == '/'
897  || (name[0] == '.' && name[1] == '/')
898  || (name[0] == '.' && name[1] == '.' && name[2] == '/')) {
899 
900  return(DB_DATA_MISMATCH);
901  }
902 
903  for ( ; *name; ++name) {
904 #ifdef __WIN__
905  /* Check for reserved characters in DOS filenames. */
906  switch (*name) {
907  case ':':
908  case '|':
909  case '"':
910  case '*':
911  case '<':
912  case '>':
913  return(DB_DATA_MISMATCH);
914  }
915 #endif /* __WIN__ */
916  if (*name == '/') {
917  if (slash) {
918  return(DB_DATA_MISMATCH);
919  }
920  slash = name;
921  }
922  }
923 
924  return(slash ? DB_SUCCESS : DB_DATA_MISMATCH);
925 }
926 
927 
928 
929 /*****************************************************************/
932 UNIV_INLINE
935 /*====================*/
936  ib_vector_t* indexes)
937 {
938  ulint i;
939  ulint n_indexes;
940 
941  n_indexes = ib_vector_size(indexes);
942 
943  for (i = 0; i < n_indexes; ++i) {
944  ib_index_def_t* ib_index_def;
945 
946  ib_index_def = static_cast<ib_index_def_t*>(
947  ib_vector_get(indexes, i));
948 
949  if (ib_index_def->clustered) {
950  return(ib_index_def);
951  }
952  }
953 
954  return(NULL);
955 }
956 
957 /*****************************************************************/
960 static
961 ib_err_t
962 ib_table_get_id_low(
963 /*================*/
964  const char* table_name,
965  ib_id_u64_t* table_id)
966 {
968  ib_err_t err = DB_TABLE_NOT_FOUND;
969 
970  *table_id = 0;
971 
972  table = ib_lookup_table_by_name(table_name);
973 
974  if (table != NULL) {
975  *table_id = (table->id);
976 
977  err = DB_SUCCESS;
978  }
979 
980  return(err);
981 }
982 
983 /*****************************************************************/
986 static
987 ib_err_t
988 ib_create_cursor(
989 /*=============*/
990  ib_crsr_t* ib_crsr,
991  dict_table_t* table,
992  dict_index_t* index,
993  trx_t* trx)
994 {
995  mem_heap_t* heap;
997  ib_err_t err = DB_SUCCESS;
998 
999  heap = mem_heap_create(sizeof(*cursor) * 2);
1000 
1001  if (heap != NULL) {
1002  row_prebuilt_t* prebuilt;
1003 
1004  cursor = static_cast<ib_cursor_t*>(
1005  mem_heap_zalloc(heap, sizeof(*cursor)));
1006 
1007  cursor->heap = heap;
1008 
1009  cursor->query_heap = mem_heap_create(64);
1010 
1011  if (cursor->query_heap == NULL) {
1012  mem_heap_free(heap);
1013 
1014  return(DB_OUT_OF_MEMORY);
1015  }
1016 
1017  cursor->prebuilt = row_create_prebuilt(table, 0);
1018 
1019  prebuilt = cursor->prebuilt;
1020 
1021  prebuilt->trx = trx;
1022 
1023  cursor->valid_trx = TRUE;
1024 
1025  prebuilt->table = table;
1026  prebuilt->select_lock_type = LOCK_NONE;
1027  prebuilt->innodb_api = TRUE;
1028 
1029  prebuilt->index = index;
1030 
1031  ut_a(prebuilt->index != NULL);
1032 
1033  if (prebuilt->trx != NULL) {
1034  ++prebuilt->trx->n_mysql_tables_in_use;
1035 
1036  prebuilt->index_usable =
1038  prebuilt->trx, prebuilt->index);
1039 
1040  /* Assign a read view if the transaction does
1041  not have it yet */
1042 
1043  trx_assign_read_view(prebuilt->trx);
1044  }
1045 
1046  *ib_crsr = (ib_crsr_t) cursor;
1047  } else {
1048  err = DB_OUT_OF_MEMORY;
1049  }
1050 
1051  return(err);
1052 }
1053 
1054 /*****************************************************************/
1058 static
1059 ib_err_t
1060 ib_create_cursor_with_index_id(
1061 /*===========================*/
1062  ib_crsr_t* ib_crsr,
1063  dict_table_t* table,
1064  ib_id_u64_t index_id,
1065  trx_t* trx)
1066 {
1068 
1069  if (index_id != 0) {
1070  mutex_enter(&dict_sys->mutex);
1071  index = dict_index_find_on_id_low(index_id);
1072  mutex_exit(&dict_sys->mutex);
1073  } else {
1074  index = dict_table_get_first_index(table);
1075  }
1076 
1077  return(ib_create_cursor(ib_crsr, table, index, trx));
1078 }
1079 
1080 /*****************************************************************/
1083 UNIV_INTERN
1084 ib_err_t
1086 /*==========================*/
1087  ib_id_u64_t table_id,
1088  ib_trx_t ib_trx,
1090  ib_crsr_t* ib_crsr)
1091 {
1092  ib_err_t err;
1094 
1095  if (ib_trx == NULL || !ib_schema_lock_is_exclusive(ib_trx)) {
1096  table = ib_open_table_by_id(table_id, FALSE);
1097  } else {
1098  table = ib_open_table_by_id(table_id, TRUE);
1099  }
1100 
1101  if (table == NULL) {
1102 
1103  return(DB_TABLE_NOT_FOUND);
1104  }
1105 
1106  err = ib_create_cursor_with_index_id(ib_crsr, table, 0,
1107  (trx_t*) ib_trx);
1108 
1109  return(err);
1110 }
1111 
1112 /*****************************************************************/
1115 UNIV_INTERN
1116 ib_err_t
1118 /*==========================*/
1119  ib_id_u64_t index_id,
1120  ib_trx_t ib_trx,
1122  ib_crsr_t* ib_crsr)
1123 {
1124  ib_err_t err;
1126  ulint table_id = (ulint)( index_id >> 32);
1127 
1128  if (ib_trx == NULL || !ib_schema_lock_is_exclusive(ib_trx)) {
1129  table = ib_open_table_by_id(table_id, FALSE);
1130  } else {
1131  table = ib_open_table_by_id(table_id, TRUE);
1132  }
1133 
1134  if (table == NULL) {
1135 
1136  return(DB_TABLE_NOT_FOUND);
1137  }
1138 
1139  /* We only return the lower 32 bits of the dulint. */
1140  err = ib_create_cursor_with_index_id(
1141  ib_crsr, table, index_id, (trx_t*) ib_trx);
1142 
1143  if (ib_crsr != NULL) {
1144  const ib_cursor_t* cursor;
1145 
1146  cursor = *(ib_cursor_t**) ib_crsr;
1147 
1148  if (cursor->prebuilt->index == NULL) {
1149  ib_err_t crsr_err;
1150 
1151  crsr_err = ib_cursor_close(*ib_crsr);
1152  ut_a(crsr_err == DB_SUCCESS);
1153 
1154  *ib_crsr = NULL;
1155  }
1156  }
1157 
1158  return(err);
1159 }
1160 
1161 /*****************************************************************/
1164 UNIV_INTERN
1165 ib_err_t
1167 /*============================*/
1168  ib_crsr_t ib_open_crsr,
1169  const char* index_name,
1170  ib_crsr_t* ib_crsr,
1171  int* idx_type,
1172  ib_id_u64_t* idx_id)
1173 {
1176  index_id_t index_id = 0;
1177  ib_err_t err = DB_TABLE_NOT_FOUND;
1178  ib_cursor_t* cursor = (ib_cursor_t*) ib_open_crsr;
1179 
1180  *idx_type = 0;
1181  *idx_id = 0;
1182  *ib_crsr = NULL;
1183 
1184  /* We want to increment the ref count, so we do a redundant search. */
1185  table = dict_table_open_on_id(cursor->prebuilt->table->id,
1186  FALSE, DICT_TABLE_OP_NORMAL);
1187  ut_a(table != NULL);
1188 
1189  /* The first index is always the cluster index. */
1190  index = dict_table_get_first_index(table);
1191 
1192  /* Traverse the user defined indexes. */
1193  while (index != NULL) {
1194  if (innobase_strcasecmp(index->name, index_name) == 0) {
1195  index_id = index->id;
1196  *idx_type = index->type;
1197  *idx_id = index_id;
1198  break;
1199  }
1200  index = UT_LIST_GET_NEXT(indexes, index);
1201  }
1202 
1203  if (!index_id) {
1204  dict_table_close(table, FALSE, FALSE);
1205  return(DB_ERROR);
1206  }
1207 
1208  if (index_id > 0) {
1209  ut_ad(index->id == index_id);
1210  err = ib_create_cursor(
1211  ib_crsr, table, index, cursor->prebuilt->trx);
1212  }
1213 
1214  if (*ib_crsr != NULL) {
1215  const ib_cursor_t* cursor;
1216 
1217  cursor = *(ib_cursor_t**) ib_crsr;
1218 
1219  if (cursor->prebuilt->index == NULL) {
1220  err = ib_cursor_close(*ib_crsr);
1221  ut_a(err == DB_SUCCESS);
1222  *ib_crsr = NULL;
1223  }
1224  }
1225 
1226  return(err);
1227 }
1228 
1229 /*****************************************************************/
1232 UNIV_INTERN
1233 ib_err_t
1235 /*=================*/
1236  const char* name,
1237  ib_trx_t ib_trx,
1239  ib_crsr_t* ib_crsr)
1240 {
1241  ib_err_t err;
1243  char* normalized_name;
1244 
1245  normalized_name = static_cast<char*>(mem_alloc(ut_strlen(name) + 1));
1246  ib_normalize_table_name(normalized_name, name);
1247 
1248  if (ib_trx != NULL) {
1249  if (!ib_schema_lock_is_exclusive(ib_trx)) {
1251  normalized_name);
1252  } else {
1253  /* NOTE: We do not acquire MySQL metadata lock */
1254  table = ib_lookup_table_by_name(normalized_name);
1255  }
1256  } else {
1257  table = (dict_table_t*)ib_open_table_by_name(normalized_name);
1258  }
1259 
1260  mem_free(normalized_name);
1261  normalized_name = NULL;
1262 
1263  /* It can happen that another thread has created the table but
1264  not the cluster index or it's a broken table definition. Refuse to
1265  open if that's the case. */
1266  if (table != NULL && dict_table_get_first_index(table) == NULL) {
1267  table = NULL;
1268  }
1269 
1270  if (table != NULL) {
1271  err = ib_create_cursor_with_index_id(ib_crsr, table, 0,
1272  (trx_t*) ib_trx);
1273  } else {
1274  err = DB_TABLE_NOT_FOUND;
1275  }
1276 
1277  return(err);
1278 }
1279 
1280 /********************************************************************/
1282 static
1283 void
1284 ib_qry_proc_free(
1285 /*=============*/
1286  ib_qry_proc_t* q_proc)
1287 {
1291 
1292  memset(q_proc, 0x0, sizeof(*q_proc));
1293 }
1294 
1295 /*****************************************************************/
1297 UNIV_INTERN
1298 void
1300 /*================*/
1301  ib_crsr_t ib_crsr)
1302 {
1303  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
1304 
1305  cursor->prebuilt->trx = NULL;
1306 }
1307 
1308 /*****************************************************************/
1311 UNIV_INTERN
1312 ib_err_t
1314 /*============*/
1315  ib_crsr_t ib_crsr)
1316 {
1317  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
1318  row_prebuilt_t* prebuilt = cursor->prebuilt;
1319 
1320  if (cursor->valid_trx && prebuilt->trx != NULL
1321  && prebuilt->trx->n_mysql_tables_in_use > 0) {
1322 
1323  --prebuilt->trx->n_mysql_tables_in_use;
1324  }
1325 
1326  /* The fields in this data structure are allocated from
1327  the query heap and so need to be reset too. */
1328  ib_qry_proc_free(&cursor->q_proc);
1329 
1330  mem_heap_empty(cursor->query_heap);
1331 
1332  return(DB_SUCCESS);
1333 }
1334 
1335 /*****************************************************************/
1338 ib_err_t
1340 /*==============*/
1341  ib_crsr_t ib_crsr,
1342  ib_trx_t ib_trx)
1343 {
1344  ib_err_t err = DB_SUCCESS;
1345  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
1346  trx_t* trx = (trx_t*) ib_trx;
1347 
1348  row_prebuilt_t* prebuilt = cursor->prebuilt;
1349 
1350  row_update_prebuilt_trx(prebuilt, trx);
1351 
1352  cursor->valid_trx = TRUE;
1353 
1354  trx_assign_read_view(prebuilt->trx);
1355 
1356  ib_qry_proc_free(&cursor->q_proc);
1357 
1358  mem_heap_empty(cursor->query_heap);
1359 
1360  return(err);
1361 }
1362 
1363 /*****************************************************************/
1366 ib_err_t
1368 /*=================*/
1369  ib_crsr_t ib_crsr,
1370  ib_trx_t ib_trx)
1371 {
1372  ib_err_t err = DB_SUCCESS;
1373  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
1374  row_prebuilt_t* prebuilt = cursor->prebuilt;
1375 
1376  ut_ad(prebuilt->trx == (trx_t*) ib_trx);
1377  err = ib_trx_commit(ib_trx);
1378  prebuilt->trx = NULL;
1379  cursor->valid_trx = FALSE;
1380  return(err);
1381 }
1382 
1383 /*****************************************************************/
1386 UNIV_INTERN
1387 ib_err_t
1389 /*============*/
1390  ib_crsr_t ib_crsr)
1391 {
1392  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
1393  row_prebuilt_t* prebuilt;
1394  trx_t* trx;
1395 
1396  if (!cursor) {
1397  return(DB_SUCCESS);
1398  }
1399 
1400  prebuilt = cursor->prebuilt;
1401  trx = prebuilt->trx;
1402 
1403  ib_qry_proc_free(&cursor->q_proc);
1404 
1405  /* The transaction could have been detached from the cursor. */
1406  if (cursor->valid_trx && trx != NULL
1407  && trx->n_mysql_tables_in_use > 0) {
1408  --trx->n_mysql_tables_in_use;
1409  }
1410 
1411  row_prebuilt_free(prebuilt, FALSE);
1412  cursor->prebuilt = NULL;
1413 
1414  mem_heap_free(cursor->query_heap);
1415  mem_heap_free(cursor->heap);
1416  cursor = NULL;
1417 
1418  return(DB_SUCCESS);
1419 }
1420 
1421 /*****************************************************************/
1424 UNIV_INTERN
1425 ib_err_t
1427 /*==================*/
1428  ib_crsr_t ib_crsr)
1429 {
1430  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
1431  row_prebuilt_t* prebuilt = cursor->prebuilt;
1432 
1433  if (prebuilt && prebuilt->table) {
1434  dict_table_close(prebuilt->table, FALSE, FALSE);
1435  }
1436 
1437  return(DB_SUCCESS);
1438 }
1439 /**********************************************************************/
1442 UNIV_INLINE
1443 ib_err_t
1445 /*==========================*/
1446  que_thr_t* thr,
1447  ins_node_t* node,
1448  trx_savept_t* savept)
1450 {
1451  trx_t* trx;
1452  ib_err_t err;
1453  ib_bool_t lock_wait;
1454 
1455  trx = thr_get_trx(thr);
1456 
1457  do {
1458  thr->run_node = node;
1459  thr->prev_node = node;
1460 
1461  row_ins_step(thr);
1462 
1463  err = trx->error_state;
1464 
1465  if (err != DB_SUCCESS) {
1467 
1468  thr->lock_state = QUE_THR_LOCK_ROW;
1469  lock_wait = ib_handle_errors(&err, trx, thr, savept);
1470  thr->lock_state = QUE_THR_LOCK_NOLOCK;
1471  } else {
1472  lock_wait = FALSE;
1473  }
1474  } while (lock_wait);
1475 
1476  return(err);
1477 }
1478 
1479 /*****************************************************************/
1482 static
1483 ib_err_t
1484 ib_execute_insert_query_graph(
1485 /*==========================*/
1486  dict_table_t* table,
1488  ins_node_t* node)
1489 {
1490  trx_t* trx;
1491  que_thr_t* thr;
1492  trx_savept_t savept;
1493  ib_err_t err = DB_SUCCESS;
1494 
1495  trx = ins_graph->trx;
1496 
1497  savept = trx_savept_take(trx);
1498 
1499  thr = que_fork_get_first_thr(ins_graph);
1500 
1502 
1503  err = ib_insert_row_with_lock_retry(thr, node, &savept);
1504 
1505  if (err == DB_SUCCESS) {
1507 
1508  dict_table_n_rows_inc(table);
1509 
1511  }
1512 
1513  trx->op_info = "";
1514 
1515  return(err);
1516 }
1517 
1518 /*****************************************************************/
1520 static
1521 void
1522 ib_insert_query_graph_create(
1523 /*==========================*/
1524  ib_cursor_t* cursor)
1525 {
1526  ib_qry_proc_t* q_proc = &cursor->q_proc;
1527  ib_qry_node_t* node = &q_proc->node;
1528  trx_t* trx = cursor->prebuilt->trx;
1529 
1530  ut_a(trx->state != TRX_STATE_NOT_STARTED);
1531 
1532  if (node->ins == NULL) {
1533  dtuple_t* row;
1534  ib_qry_grph_t* grph = &q_proc->grph;
1535  mem_heap_t* heap = cursor->query_heap;
1536  dict_table_t* table = cursor->prebuilt->table;
1537 
1538  node->ins = ins_node_create(INS_DIRECT, table, heap);
1539 
1540  node->ins->select = NULL;
1541  node->ins->values_list = NULL;
1542 
1543  row = dtuple_create(heap, dict_table_get_n_cols(table));
1544  dict_table_copy_types(row, table);
1545 
1546  ins_node_set_new_row(node->ins, row);
1547 
1548  grph->ins = static_cast<que_fork_t*>(
1550  pars_complete_graph_for_exec(node->ins, trx,
1551  heap)));
1552 
1553  grph->ins->state = QUE_FORK_ACTIVE;
1554  }
1555 }
1556 
1557 /*****************************************************************/
1560 UNIV_INTERN
1561 ib_err_t
1563 /*=================*/
1564  ib_crsr_t ib_crsr,
1565  const ib_tpl_t ib_tpl)
1566 {
1567  ib_ulint_t i;
1568  ib_qry_node_t* node;
1569  ib_qry_proc_t* q_proc;
1570  ulint n_fields;
1571  dtuple_t* dst_dtuple;
1572  ib_err_t err = DB_SUCCESS;
1573  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
1574  const ib_tuple_t* src_tuple = (const ib_tuple_t*) ib_tpl;
1575 
1576  ib_insert_query_graph_create(cursor);
1577 
1578  ut_ad(src_tuple->type == TPL_TYPE_ROW);
1579 
1580  q_proc = &cursor->q_proc;
1581  node = &q_proc->node;
1582 
1583  node->ins->state = INS_NODE_ALLOC_ROW_ID;
1584  dst_dtuple = node->ins->row;
1585 
1586  n_fields = dtuple_get_n_fields(src_tuple->ptr);
1587  ut_ad(n_fields == dtuple_get_n_fields(dst_dtuple));
1588 
1589  /* Do a shallow copy of the data fields and check for NULL
1590  constraints on columns. */
1591  for (i = 0; i < n_fields; i++) {
1592  ulint mtype;
1593  dfield_t* src_field;
1594  dfield_t* dst_field;
1595 
1596  src_field = dtuple_get_nth_field(src_tuple->ptr, i);
1597 
1598  mtype = dtype_get_mtype(dfield_get_type(src_field));
1599 
1600  /* Don't touch the system columns. */
1601  if (mtype != DATA_SYS) {
1602  ulint prtype;
1603 
1604  prtype = dtype_get_prtype(dfield_get_type(src_field));
1605 
1606  if ((prtype & DATA_NOT_NULL)
1607  && dfield_is_null(src_field)) {
1608 
1609  err = DB_DATA_MISMATCH;
1610  break;
1611  }
1612 
1613  dst_field = dtuple_get_nth_field(dst_dtuple, i);
1614  ut_ad(mtype
1615  == dtype_get_mtype(dfield_get_type(dst_field)));
1616 
1617  /* Do a shallow copy. */
1619  dst_field, src_field->data, src_field->len);
1620 
1621  if (dst_field->len != IB_SQL_NULL) {
1622  UNIV_MEM_ASSERT_RW(dst_field->data,
1623  dst_field->len);
1624  }
1625  }
1626  }
1627 
1628  if (err == DB_SUCCESS) {
1629  err = ib_execute_insert_query_graph(
1630  src_tuple->index->table, q_proc->grph.ins, node->ins);
1631  }
1632 
1634 
1635  return(err);
1636 }
1637 
1638 /*********************************************************************/
1641 UNIV_INLINE
1642 upd_t*
1644 /*====================*/
1645  ib_cursor_t* cursor)
1646 {
1647  trx_t* trx = cursor->prebuilt->trx;
1648  mem_heap_t* heap = cursor->query_heap;
1649  dict_table_t* table = cursor->prebuilt->table;
1650  ib_qry_proc_t* q_proc = &cursor->q_proc;
1651  ib_qry_grph_t* grph = &q_proc->grph;
1652  ib_qry_node_t* node = &q_proc->node;
1653 
1654  ut_a(trx->state != TRX_STATE_NOT_STARTED);
1655 
1656  if (node->upd == NULL) {
1657  node->upd = static_cast<upd_node_t*>(
1658  row_create_update_node_for_mysql(table, heap));
1659  }
1660 
1661  grph->upd = static_cast<que_fork_t*>(
1663  pars_complete_graph_for_exec(node->upd, trx, heap)));
1664 
1665  grph->upd->state = QUE_FORK_ACTIVE;
1666 
1667  return(node->upd->update);
1668 }
1669 
1670 /**********************************************************************/
1672 static
1673 void
1674 ib_update_col(
1675 /*==========*/
1676 
1677  ib_cursor_t* cursor,
1678  upd_field_t* upd_field,
1679  ulint col_no,
1680  dfield_t* dfield)
1681 {
1682  ulint data_len;
1683  dict_table_t* table = cursor->prebuilt->table;
1684  dict_index_t* index = dict_table_get_first_index(table);
1685 
1686  data_len = dfield_get_len(dfield);
1687 
1688  if (data_len == UNIV_SQL_NULL) {
1689  dfield_set_null(&upd_field->new_val);
1690  } else {
1691  dfield_copy_data(&upd_field->new_val, dfield);
1692  }
1693 
1694  upd_field->exp = NULL;
1695 
1696  upd_field->orig_len = 0;
1697 
1698  upd_field->field_no = dict_col_get_clust_pos(
1699  &table->cols[col_no], index);
1700 }
1701 
1702 /**********************************************************************/
1706 static
1707 ib_err_t
1708 ib_calc_diff(
1709 /*=========*/
1710  ib_cursor_t* cursor,
1711  upd_t* upd,
1712  const ib_tuple_t*old_tuple,
1713  const ib_tuple_t*new_tuple)
1714 {
1715  ulint i;
1716  ulint n_changed = 0;
1717  ib_err_t err = DB_SUCCESS;
1718  ulint n_fields = dtuple_get_n_fields(new_tuple->ptr);
1719 
1720  ut_a(old_tuple->type == TPL_TYPE_ROW);
1721  ut_a(new_tuple->type == TPL_TYPE_ROW);
1722  ut_a(old_tuple->index->table == new_tuple->index->table);
1723 
1724  for (i = 0; i < n_fields; ++i) {
1725  ulint mtype;
1726  ulint prtype;
1727  upd_field_t* upd_field;
1728  dfield_t* new_dfield;
1729  dfield_t* old_dfield;
1730 
1731  new_dfield = dtuple_get_nth_field(new_tuple->ptr, i);
1732  old_dfield = dtuple_get_nth_field(old_tuple->ptr, i);
1733 
1734  mtype = dtype_get_mtype(dfield_get_type(old_dfield));
1735  prtype = dtype_get_prtype(dfield_get_type(old_dfield));
1736 
1737  /* Skip the system columns */
1738  if (mtype == DATA_SYS) {
1739  continue;
1740 
1741  } else if ((prtype & DATA_NOT_NULL)
1742  && dfield_is_null(new_dfield)) {
1743 
1744  err = DB_DATA_MISMATCH;
1745  break;
1746  }
1747 
1748  if (dfield_get_len(new_dfield) != dfield_get_len(old_dfield)
1749  || (!dfield_is_null(old_dfield)
1750  && memcmp(dfield_get_data(new_dfield),
1751  dfield_get_data(old_dfield),
1752  dfield_get_len(old_dfield)) != 0)) {
1753 
1754  upd_field = &upd->fields[n_changed];
1755 
1756  ib_update_col(cursor, upd_field, i, new_dfield);
1757 
1758  ++n_changed;
1759  }
1760  }
1761 
1762  if (err == DB_SUCCESS) {
1763  upd->info_bits = 0;
1764  upd->n_fields = n_changed;
1765  }
1766 
1767  return(err);
1768 }
1769 
1770 /**********************************************************************/
1773 UNIV_INLINE
1774 ib_err_t
1776 /*==========================*/
1777  que_thr_t* thr,
1778  upd_node_t* node,
1779  trx_savept_t* savept)
1782 {
1783  trx_t* trx;
1784  ib_err_t err;
1785  ib_bool_t lock_wait;
1786 
1787  trx = thr_get_trx(thr);
1788 
1789  do {
1790  thr->run_node = node;
1791  thr->prev_node = node;
1792 
1793  row_upd_step(thr);
1794 
1795  err = trx->error_state;
1796 
1797  if (err != DB_SUCCESS) {
1799 
1800  if (err != DB_RECORD_NOT_FOUND) {
1801  thr->lock_state = QUE_THR_LOCK_ROW;
1802 
1803  lock_wait = ib_handle_errors(
1804  &err, trx, thr, savept);
1805 
1806  thr->lock_state = QUE_THR_LOCK_NOLOCK;
1807  } else {
1808  lock_wait = FALSE;
1809  }
1810  } else {
1811  lock_wait = FALSE;
1812  }
1813  } while (lock_wait);
1814 
1815  return(err);
1816 }
1817 
1818 /*********************************************************************/
1821 UNIV_INLINE
1822 ib_err_t
1824 /*==========================*/
1825  ib_cursor_t* cursor,
1826  btr_pcur_t* pcur)
1827 {
1828  ib_err_t err;
1829  que_thr_t* thr;
1830  upd_node_t* node;
1831  trx_savept_t savept;
1832  trx_t* trx = cursor->prebuilt->trx;
1833  dict_table_t* table = cursor->prebuilt->table;
1834  ib_qry_proc_t* q_proc = &cursor->q_proc;
1835 
1836  /* The transaction must be running. */
1837  ut_a(trx->state != TRX_STATE_NOT_STARTED);
1838 
1839  node = q_proc->node.upd;
1840 
1842  btr_pcur_copy_stored_position(node->pcur, pcur);
1843 
1844  ut_a(node->pcur->rel_pos == BTR_PCUR_ON);
1845 
1846  savept = trx_savept_take(trx);
1847 
1848  thr = que_fork_get_first_thr(q_proc->grph.upd);
1849 
1850  node->state = UPD_NODE_UPDATE_CLUSTERED;
1851 
1853 
1854  err = ib_update_row_with_lock_retry(thr, node, &savept);
1855 
1856  if (err == DB_SUCCESS) {
1857 
1859 
1860  if (node->is_delete) {
1861 
1862  dict_table_n_rows_dec(table);
1863 
1865  } else {
1867  }
1868 
1869  } else if (err == DB_RECORD_NOT_FOUND) {
1870  trx->error_state = DB_SUCCESS;
1871  }
1872 
1873  trx->op_info = "";
1874 
1875  return(err);
1876 }
1877 
1878 /*****************************************************************/
1881 UNIV_INTERN
1882 ib_err_t
1884 /*=================*/
1885  ib_crsr_t ib_crsr,
1886  const ib_tpl_t ib_old_tpl,
1887  const ib_tpl_t ib_new_tpl)
1888 {
1889  upd_t* upd;
1890  ib_err_t err;
1891  btr_pcur_t* pcur;
1892  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
1893  row_prebuilt_t* prebuilt = cursor->prebuilt;
1894  const ib_tuple_t*old_tuple = (const ib_tuple_t*) ib_old_tpl;
1895  const ib_tuple_t*new_tuple = (const ib_tuple_t*) ib_new_tpl;
1896 
1897  if (dict_index_is_clust(prebuilt->index)) {
1898  pcur = &cursor->prebuilt->pcur;
1899  } else if (prebuilt->need_to_access_clustered) {
1900  pcur = &cursor->prebuilt->clust_pcur;
1901  } else {
1902  return(DB_ERROR);
1903  }
1904 
1905  ut_a(old_tuple->type == TPL_TYPE_ROW);
1906  ut_a(new_tuple->type == TPL_TYPE_ROW);
1907 
1908  upd = ib_update_vector_create(cursor);
1909 
1910  err = ib_calc_diff(cursor, upd, old_tuple, new_tuple);
1911 
1912  if (err == DB_SUCCESS) {
1913  /* Note that this is not a delete. */
1914  cursor->q_proc.node.upd->is_delete = FALSE;
1915 
1916  err = ib_execute_update_query_graph(cursor, pcur);
1917  }
1918 
1920 
1921  return(err);
1922 }
1923 
1924 /**********************************************************************/
1927 static
1928 ib_err_t
1929 ib_delete_row(
1930 /*==========*/
1931  ib_cursor_t* cursor,
1932  btr_pcur_t* pcur,
1933  const rec_t* rec)
1934 {
1935  ulint i;
1936  upd_t* upd;
1937  ib_err_t err;
1938  ib_tuple_t* tuple;
1939  ib_tpl_t ib_tpl;
1940  ulint n_cols;
1941  upd_field_t* upd_field;
1942  ib_bool_t page_format;
1943  dict_table_t* table = cursor->prebuilt->table;
1944  dict_index_t* index = dict_table_get_first_index(table);
1945 
1947  ib_tpl = ib_key_tuple_new(index, n_cols);
1948 
1949  if (!ib_tpl) {
1950  return(DB_OUT_OF_MEMORY);
1951  }
1952 
1953  tuple = (ib_tuple_t*) ib_tpl;
1954 
1955  upd = ib_update_vector_create(cursor);
1956 
1957  page_format = dict_table_is_comp(index->table);
1958  ib_read_tuple(rec, page_format, tuple);
1959 
1960  upd->n_fields = ib_tuple_get_n_cols(ib_tpl);
1961 
1962  for (i = 0; i < upd->n_fields; ++i) {
1963  dfield_t* dfield;
1964 
1965  upd_field = &upd->fields[i];
1966  dfield = dtuple_get_nth_field(tuple->ptr, i);
1967 
1968  dfield_copy_data(&upd_field->new_val, dfield);
1969 
1970  upd_field->exp = NULL;
1971 
1972  upd_field->orig_len = 0;
1973 
1974  upd->info_bits = 0;
1975 
1976  upd_field->field_no = dict_col_get_clust_pos(
1977  &table->cols[i], index);
1978  }
1979 
1980  /* Note that this is a delete. */
1981  cursor->q_proc.node.upd->is_delete = TRUE;
1982 
1983  err = ib_execute_update_query_graph(cursor, pcur);
1984 
1985  ib_tuple_delete(ib_tpl);
1986 
1987  return(err);
1988 }
1989 
1990 /*****************************************************************/
1993 UNIV_INTERN
1994 ib_err_t
1996 /*=================*/
1997  ib_crsr_t ib_crsr)
1998 {
1999  ib_err_t err;
2000  btr_pcur_t* pcur;
2002  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
2003  row_prebuilt_t* prebuilt = cursor->prebuilt;
2004 
2005  index = dict_table_get_first_index(prebuilt->index->table);
2006 
2007  /* Check whether this is a secondary index cursor */
2008  if (index != prebuilt->index) {
2009  if (prebuilt->need_to_access_clustered) {
2010  pcur = &prebuilt->clust_pcur;
2011  } else {
2012  return(DB_ERROR);
2013  }
2014  } else {
2015  pcur = &prebuilt->pcur;
2016  }
2017 
2018  if (ib_btr_cursor_is_positioned(pcur)) {
2019  const rec_t* rec;
2020  ib_bool_t page_format;
2021  mtr_t mtr;
2022 
2023  page_format = dict_table_is_comp(index->table);
2024 
2025  mtr_start(&mtr);
2026 
2027  if (btr_pcur_restore_position(
2028  BTR_SEARCH_LEAF, pcur, &mtr)) {
2029 
2030  rec = btr_pcur_get_rec(pcur);
2031  } else {
2032  rec = NULL;
2033  }
2034 
2035  mtr_commit(&mtr);
2036 
2037  if (rec && !rec_get_deleted_flag(rec, page_format)) {
2038  err = ib_delete_row(cursor, pcur, rec);
2039  } else {
2040  err = DB_RECORD_NOT_FOUND;
2041  }
2042  } else {
2043  err = DB_RECORD_NOT_FOUND;
2044  }
2045 
2047 
2048  return(err);
2049 }
2050 
2051 /*****************************************************************/
2054 UNIV_INTERN
2055 ib_err_t
2057 /*===============*/
2058  ib_crsr_t ib_crsr,
2059  ib_tpl_t ib_tpl)
2060 {
2061  ib_err_t err;
2062  ib_tuple_t* tuple = (ib_tuple_t*) ib_tpl;
2063  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
2064 
2065  ut_a(cursor->prebuilt->trx->state != TRX_STATE_NOT_STARTED);
2066 
2067  /* When searching with IB_EXACT_MATCH set, row_search_for_mysql()
2068  will not position the persistent cursor but will copy the record
2069  found into the row cache. It should be the only entry. */
2070  if (!ib_cursor_is_positioned(ib_crsr) ) {
2071  err = DB_RECORD_NOT_FOUND;
2072  } else {
2073  mtr_t mtr;
2074  btr_pcur_t* pcur;
2075  row_prebuilt_t* prebuilt = cursor->prebuilt;
2076 
2077  if (prebuilt->need_to_access_clustered
2078  && tuple->type == TPL_TYPE_ROW) {
2079  pcur = &prebuilt->clust_pcur;
2080  } else {
2081  pcur = &prebuilt->pcur;
2082  }
2083 
2084  if (pcur == NULL) {
2085  return(DB_ERROR);
2086  }
2087 
2088  mtr_start(&mtr);
2089 
2090  if (btr_pcur_restore_position(BTR_SEARCH_LEAF, pcur, &mtr)) {
2091  const rec_t* rec;
2092  ib_bool_t page_format;
2093 
2094  page_format = dict_table_is_comp(tuple->index->table);
2095  rec = btr_pcur_get_rec(pcur);
2096 
2097  if (prebuilt->innodb_api_rec &&
2098  prebuilt->innodb_api_rec != rec) {
2099  rec = prebuilt->innodb_api_rec;
2100  }
2101 
2102  if (!rec_get_deleted_flag(rec, page_format)) {
2103  ib_read_tuple(rec, page_format, tuple);
2104  err = DB_SUCCESS;
2105  } else{
2106  err = DB_RECORD_NOT_FOUND;
2107  }
2108 
2109  } else {
2110  err = DB_RECORD_NOT_FOUND;
2111  }
2112 
2113  mtr_commit(&mtr);
2114  }
2115 
2116  return(err);
2117 }
2118 
2119 /*****************************************************************/
2122 UNIV_INLINE
2123 ib_err_t
2125 /*===============*/
2126  ib_cursor_t* cursor,
2128 {
2129  ib_err_t err;
2130  row_prebuilt_t* prebuilt = cursor->prebuilt;
2131  unsigned char* buf;
2132 
2133  buf = static_cast<unsigned char*>(mem_alloc(UNIV_PAGE_SIZE));
2134 
2135  /* We want to position at one of the ends, row_search_for_mysql()
2136  uses the search_tuple fields to work out what to do. */
2137  dtuple_set_n_fields(prebuilt->search_tuple, 0);
2138 
2139  err = static_cast<ib_err_t>(row_search_for_mysql(
2140  buf, mode, prebuilt, 0, 0));
2141 
2142  mem_free(buf);
2143 
2144  return(err);
2145 }
2146 
2147 /*****************************************************************/
2150 UNIV_INTERN
2151 ib_err_t
2153 /*============*/
2154  ib_crsr_t ib_crsr)
2155 {
2156  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
2157 
2158  return(ib_cursor_position(cursor, IB_CUR_G));
2159 }
2160 
2161 /*****************************************************************/
2164 UNIV_INTERN
2165 ib_err_t
2167 /*===========*/
2168  ib_crsr_t ib_crsr)
2169 {
2170  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
2171 
2172  return(ib_cursor_position(cursor, IB_CUR_L));
2173 }
2174 
2175 /*****************************************************************/
2178 UNIV_INTERN
2179 ib_err_t
2181 /*===========*/
2182  ib_crsr_t ib_crsr)
2183 {
2184  ib_err_t err;
2185  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
2186  row_prebuilt_t* prebuilt = cursor->prebuilt;
2187  byte buf[UNIV_PAGE_SIZE_MAX];
2188 
2189  /* We want to move to the next record */
2190  dtuple_set_n_fields(prebuilt->search_tuple, 0);
2191 
2192  err = static_cast<ib_err_t>(row_search_for_mysql(
2193  buf, PAGE_CUR_G, prebuilt, 0, ROW_SEL_NEXT));
2194 
2195  return(err);
2196 }
2197 
2198 /*****************************************************************/
2201 UNIV_INTERN
2202 ib_err_t
2204 /*=============*/
2205  ib_crsr_t ib_crsr,
2206  ib_tpl_t ib_tpl,
2207  ib_srch_mode_t ib_srch_mode)
2208 {
2209  ulint i;
2210  ulint n_fields;
2211  ib_err_t err = DB_SUCCESS;
2212  ib_tuple_t* tuple = (ib_tuple_t*) ib_tpl;
2213  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
2214  row_prebuilt_t* prebuilt = cursor->prebuilt;
2215  dtuple_t* search_tuple = prebuilt->search_tuple;
2216  unsigned char* buf;
2217 
2218  ut_a(tuple->type == TPL_TYPE_KEY);
2219 
2220  n_fields = dict_index_get_n_ordering_defined_by_user(prebuilt->index);
2221 
2222  dtuple_set_n_fields(search_tuple, n_fields);
2223  dtuple_set_n_fields_cmp(search_tuple, n_fields);
2224 
2225  /* Do a shallow copy */
2226  for (i = 0; i < n_fields; ++i) {
2227  dfield_copy(dtuple_get_nth_field(search_tuple, i),
2228  dtuple_get_nth_field(tuple->ptr, i));
2229  }
2230 
2231  ut_a(prebuilt->select_lock_type <= LOCK_NUM);
2232 
2233  prebuilt->innodb_api_rec = NULL;
2234 
2235  buf = static_cast<unsigned char*>(mem_alloc(UNIV_PAGE_SIZE));
2236 
2237  err = static_cast<ib_err_t>(row_search_for_mysql(
2238  buf, ib_srch_mode, prebuilt, cursor->match_mode, 0));
2239 
2240  mem_free(buf);
2241 
2242  return(err);
2243 }
2244 
2245 /*****************************************************************/
2247 UNIV_INTERN
2248 void
2250 /*=====================*/
2251  ib_crsr_t ib_crsr,
2252  ib_match_mode_t match_mode)
2253 {
2254  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
2255 
2256  cursor->match_mode = match_mode;
2257 }
2258 
2259 /*****************************************************************/
2262 UNIV_INLINE
2263 dfield_t*
2265 /*==============*/
2266  ib_tuple_t* tuple,
2267  ulint col_no)
2268 {
2269  dfield_t* dfield;
2270 
2271  dfield = dtuple_get_nth_field(tuple->ptr, col_no);
2272 
2273  return(dfield);
2274 }
2275 
2276 /*****************************************************************/
2279 UNIV_INLINE
2280 ib_err_t
2282 /*==============*/
2283  const dtype_t* dtype)
2284 {
2285  return(static_cast<ib_err_t>(
2286  (dtype_get_mtype(dtype) == DATA_VARCHAR
2287  || dtype_get_mtype(dtype) == DATA_CHAR
2288  || dtype_get_mtype(dtype) == DATA_MYSQL
2289  || dtype_get_mtype(dtype) == DATA_VARMYSQL
2290  || dtype_get_mtype(dtype) == DATA_FIXBINARY
2291  || dtype_get_mtype(dtype) == DATA_BINARY)
2292  && dtype_get_len(dtype) > 0));
2293 }
2294 
2295 /*****************************************************************/
2298 UNIV_INTERN
2299 ib_err_t
2301 /*=============*/
2302  ib_tpl_t ib_tpl,
2303  ib_ulint_t col_no,
2304  const void* src,
2305  ib_ulint_t len,
2306  ib_bool_t need_cpy)
2307 {
2308  const dtype_t* dtype;
2309  dfield_t* dfield;
2310  void* dst = NULL;
2311  ib_tuple_t* tuple = (ib_tuple_t*) ib_tpl;
2312  ulint col_len;
2313 
2314  dfield = ib_col_get_dfield(tuple, col_no);
2315 
2316  /* User wants to set the column to NULL. */
2317  if (len == IB_SQL_NULL) {
2318  dfield_set_null(dfield);
2319  return(DB_SUCCESS);
2320  }
2321 
2322  dtype = dfield_get_type(dfield);
2323  col_len = dtype_get_len(dtype);
2324 
2325  /* Not allowed to update system columns. */
2326  if (dtype_get_mtype(dtype) == DATA_SYS) {
2327  return(DB_DATA_MISMATCH);
2328  }
2329 
2330  dst = dfield_get_data(dfield);
2331 
2332  /* Since TEXT/CLOB also map to DATA_VARCHAR we need to make an
2333  exception. Perhaps we need to set the precise type and check
2334  for that. */
2335  if (ib_col_is_capped(dtype)) {
2336 
2337  len = ut_min(len, col_len);
2338 
2339  if (dst == NULL || len > dfield_get_len(dfield)) {
2340  dst = mem_heap_alloc(tuple->heap, col_len);
2341  ut_a(dst != NULL);
2342  }
2343  } else if (dst == NULL || len > dfield_get_len(dfield)) {
2344  dst = mem_heap_alloc(tuple->heap, len);
2345  }
2346 
2347  if (dst == NULL) {
2348  return(DB_OUT_OF_MEMORY);
2349  }
2350 
2351  switch (dtype_get_mtype(dtype)) {
2352  case DATA_INT: {
2353 
2354  if (col_len == len) {
2355  ibool usign;
2356 
2357  usign = dtype_get_prtype(dtype) & DATA_UNSIGNED;
2358  mach_write_int_type(static_cast<byte*>(dst),
2359  static_cast<const byte*>(src),
2360  len, usign);
2361 
2362  } else {
2363  return(DB_DATA_MISMATCH);
2364  }
2365  break;
2366  }
2367 
2368  case DATA_FLOAT:
2369  if (len == sizeof(float)) {
2370  mach_float_write(static_cast<byte*>(dst), *(float*)src);
2371  } else {
2372  return(DB_DATA_MISMATCH);
2373  }
2374  break;
2375 
2376  case DATA_DOUBLE:
2377  if (len == sizeof(double)) {
2378  mach_double_write(static_cast<byte*>(dst),
2379  *(double*)src);
2380  } else {
2381  return(DB_DATA_MISMATCH);
2382  }
2383  break;
2384 
2385  case DATA_SYS:
2386  ut_error;
2387  break;
2388 
2389  case DATA_CHAR: {
2390  ulint pad_char = ULINT_UNDEFINED;
2391 
2392  pad_char = dtype_get_pad_char(
2393  dtype_get_mtype(dtype), dtype_get_prtype(dtype));
2394 
2395  ut_a(pad_char != ULINT_UNDEFINED);
2396 
2397  memset((byte*) dst + len,
2398  pad_char,
2399  col_len - len);
2400 
2401  memcpy(dst, src, len);
2402 
2403  len = col_len;
2404  break;
2405  }
2406  case DATA_BLOB:
2407  case DATA_BINARY:
2408  case DATA_DECIMAL:
2409  case DATA_VARCHAR:
2410  case DATA_FIXBINARY:
2411  if (need_cpy) {
2412  memcpy(dst, src, len);
2413  } else {
2414  dfield_set_data(dfield, src, len);
2415  dst = dfield_get_data(dfield);
2416  }
2417  break;
2418 
2419  case DATA_MYSQL:
2420  case DATA_VARMYSQL: {
2421  ulint cset;
2422  CHARSET_INFO* cs;
2423  int error = 0;
2424  ulint true_len = len;
2425 
2426  /* For multi byte character sets we need to
2427  calculate the true length of the data. */
2428  cset = dtype_get_charset_coll(
2429  dtype_get_prtype(dtype));
2430  cs = all_charsets[cset];
2431  if (cs) {
2432  uint pos = (uint)(col_len / cs->mbmaxlen);
2433 
2434  if (len > 0 && cs->mbmaxlen > 1) {
2435  true_len = (ulint)
2436  cs->cset->well_formed_len(
2437  cs,
2438  (const char*)src,
2439  (const char*)src + len,
2440  pos,
2441  &error);
2442 
2443  if (true_len < len) {
2444  len = true_len;
2445  }
2446  }
2447  }
2448 
2449  /* All invalid bytes in data need be truncated.
2450  If len == 0, means all bytes of the data is invalid.
2451  In this case, the data will be truncated to empty.*/
2452  memcpy(dst, src, len);
2453 
2454  /* For DATA_MYSQL, need to pad the unused
2455  space with spaces. */
2456  if (dtype_get_mtype(dtype) == DATA_MYSQL) {
2457  ulint n_chars;
2458 
2459  if (len < col_len) {
2460  ulint pad_len = col_len - len;
2461 
2462  ut_a(cs != NULL);
2463  ut_a(!(pad_len % cs->mbminlen));
2464 
2465  cs->cset->fill(cs, (char*)dst + len,
2466  pad_len,
2467  0x20 /* space */);
2468  }
2469 
2470  /* Why we should do below? See function
2471  row_mysql_store_col_in_innobase_format */
2472 
2473  ut_a(!(dtype_get_len(dtype)
2474  % dtype_get_mbmaxlen(dtype)));
2475 
2476  n_chars = dtype_get_len(dtype)
2477  / dtype_get_mbmaxlen(dtype);
2478 
2479  /* Strip space padding. */
2480  while (col_len > n_chars
2481  && ((char*)dst)[col_len - 1] == 0x20) {
2482  col_len--;
2483  }
2484 
2485  len = col_len;
2486  }
2487  break;
2488  }
2489 
2490  default:
2491  ut_error;
2492  }
2493 
2494  if (dst != dfield_get_data(dfield)) {
2495  dfield_set_data(dfield, dst, len);
2496  } else {
2497  dfield_set_len(dfield, len);
2498  }
2499 
2500  return(DB_SUCCESS);
2501 }
2502 
2503 /*****************************************************************/
2506 UNIV_INTERN
2507 ib_ulint_t
2509 /*===========*/
2510  ib_tpl_t ib_tpl,
2511  ib_ulint_t i)
2512 {
2513  const dfield_t* dfield;
2514  ulint data_len;
2515  ib_tuple_t* tuple = (ib_tuple_t*) ib_tpl;
2516 
2517  dfield = ib_col_get_dfield(tuple, i);
2518 
2519  data_len = dfield_get_len(dfield);
2520 
2521  return(data_len == UNIV_SQL_NULL ? IB_SQL_NULL : data_len);
2522 }
2523 
2524 /*****************************************************************/
2527 UNIV_INLINE
2528 ib_ulint_t
2530 /*==================*/
2531  ib_tpl_t ib_tpl,
2532  ib_ulint_t i,
2533  void* dst,
2534  ib_ulint_t len)
2535 {
2536  const void* data;
2537  const dfield_t* dfield;
2538  ulint data_len;
2539  ib_tuple_t* tuple = (ib_tuple_t*) ib_tpl;
2540 
2541  dfield = ib_col_get_dfield(tuple, i);
2542 
2543  data = dfield_get_data(dfield);
2544  data_len = dfield_get_len(dfield);
2545 
2546  if (data_len != UNIV_SQL_NULL) {
2547 
2548  const dtype_t* dtype = dfield_get_type(dfield);
2549 
2550  switch (dtype_get_mtype(dfield_get_type(dfield))) {
2551  case DATA_INT: {
2552  ibool usign;
2553  ullint ret;
2554 
2555  ut_a(data_len == len);
2556 
2557  usign = dtype_get_prtype(dtype) & DATA_UNSIGNED;
2558  ret = mach_read_int_type(static_cast<const byte*>(data),
2559  data_len, usign);
2560 
2561  if (usign) {
2562  if (len == 1) {
2563  *(ib_i8_t*)dst = (ib_i8_t)ret;
2564  } else if (len == 2) {
2565  *(ib_i16_t*)dst = (ib_i16_t)ret;
2566  } else if (len == 4) {
2567  *(ib_i32_t*)dst = (ib_i32_t)ret;
2568  } else {
2569  *(ib_i64_t*)dst = (ib_i64_t)ret;
2570  }
2571  } else {
2572  if (len == 1) {
2573  *(ib_u8_t*)dst = (ib_i8_t)ret;
2574  } else if (len == 2) {
2575  *(ib_u16_t*)dst = (ib_i16_t)ret;
2576  } else if (len == 4) {
2577  *(ib_u32_t*)dst = (ib_i32_t)ret;
2578  } else {
2579  *(ib_u64_t*)dst = (ib_i64_t)ret;
2580  }
2581  }
2582 
2583  break;
2584  }
2585  case DATA_FLOAT:
2586  if (len == data_len) {
2587  float f;
2588 
2589  ut_a(data_len == sizeof(f));
2590  f = mach_float_read(static_cast<const byte*>(
2591  data));
2592  memcpy(dst, &f, sizeof(f));
2593  } else {
2594  data_len = 0;
2595  }
2596  break;
2597  case DATA_DOUBLE:
2598  if (len == data_len) {
2599  double d;
2600 
2601  ut_a(data_len == sizeof(d));
2602  d = mach_double_read(static_cast<const byte*>(
2603  data));
2604  memcpy(dst, &d, sizeof(d));
2605  } else {
2606  data_len = 0;
2607  }
2608  break;
2609  default:
2610  data_len = ut_min(data_len, len);
2611  memcpy(dst, data, data_len);
2612  }
2613  } else {
2614  data_len = IB_SQL_NULL;
2615  }
2616 
2617  return(data_len);
2618 }
2619 
2620 /*****************************************************************/
2623 UNIV_INTERN
2624 ib_ulint_t
2626 /*==============*/
2627  ib_tpl_t ib_tpl,
2628  ib_ulint_t i,
2629  void* dst,
2630  ib_ulint_t len)
2631 {
2632  return(ib_col_copy_value_low(ib_tpl, i, dst, len));
2633 }
2634 
2635 /*****************************************************************/
2638 UNIV_INLINE
2641 /*============*/
2642  ulint prtype)
2643 {
2644  ib_col_attr_t attr = IB_COL_NONE;
2645 
2646  if (prtype & DATA_UNSIGNED) {
2647  attr = static_cast<ib_col_attr_t>(attr | IB_COL_UNSIGNED);
2648  }
2649 
2650  if (prtype & DATA_NOT_NULL) {
2651  attr = static_cast<ib_col_attr_t>(attr | IB_COL_NOT_NULL);
2652  }
2653 
2654  return(attr);
2655 }
2656 
2657 /*****************************************************************/
2660 UNIV_INTERN
2661 const char*
2663 /*============*/
2664  ib_crsr_t ib_crsr,
2665  ib_ulint_t i)
2666 {
2667  const char* name;
2668  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
2669  dict_table_t* table = cursor->prebuilt->table;
2670  dict_col_t* col = dict_table_get_nth_col(table, i);
2671  ulint col_no = dict_col_get_no(col);
2672 
2673  name = dict_table_get_col_name(table, col_no);
2674 
2675  return(name);
2676 }
2677 
2678 /*****************************************************************/
2681 UNIV_INTERN
2682 const char*
2684 /*==================*/
2685  ib_crsr_t ib_crsr,
2686  ib_ulint_t i)
2687 {
2688  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
2689  dict_index_t* index = cursor->prebuilt->index;
2690  dict_field_t* field;
2691 
2692  if (index) {
2693  field = dict_index_get_nth_field(cursor->prebuilt->index, i);
2694 
2695  if (field) {
2696  return(field->name);
2697  }
2698  }
2699 
2700  return(NULL);
2701 }
2702 
2703 /*****************************************************************/
2706 UNIV_INLINE
2707 ib_ulint_t
2709 /*================*/
2710  ib_tpl_t ib_tpl,
2711  ib_ulint_t i,
2712  ib_col_meta_t* ib_col_meta)
2713 {
2714  ib_u16_t prtype;
2715  const dfield_t* dfield;
2716  ulint data_len;
2717  ib_tuple_t* tuple = (ib_tuple_t*) ib_tpl;
2718 
2719  dfield = ib_col_get_dfield(tuple, i);
2720 
2721  data_len = dfield_get_len(dfield);
2722 
2723  /* We assume 1-1 mapping between the ENUM and internal type codes. */
2724  ib_col_meta->type = static_cast<ib_col_type_t>(
2725  dtype_get_mtype(dfield_get_type(dfield)));
2726 
2727  ib_col_meta->type_len = dtype_get_len(dfield_get_type(dfield));
2728 
2729  prtype = (ib_u16_t) dtype_get_prtype(dfield_get_type(dfield));
2730 
2731  ib_col_meta->attr = ib_col_get_attr(prtype);
2732  ib_col_meta->client_type = prtype & DATA_MYSQL_TYPE_MASK;
2733 
2734  return(data_len);
2735 }
2736 
2737 /*************************************************************/
2739 UNIV_INLINE
2740 ib_err_t
2742 /*===============*/
2743  ib_tpl_t ib_tpl,
2744  ib_ulint_t i,
2745  ib_bool_t usign,
2746  ulint size)
2747 {
2748  ib_col_meta_t ib_col_meta;
2749 
2750  ib_col_get_meta_low(ib_tpl, i, &ib_col_meta);
2751 
2752  if (ib_col_meta.type != IB_INT) {
2753  return(DB_DATA_MISMATCH);
2754  } else if (ib_col_meta.type_len == IB_SQL_NULL) {
2755  return(DB_UNDERFLOW);
2756  } else if (ib_col_meta.type_len != size) {
2757  return(DB_DATA_MISMATCH);
2758  } else if ((ib_col_meta.attr & IB_COL_UNSIGNED) && !usign) {
2759  return(DB_DATA_MISMATCH);
2760  }
2761 
2762  return(DB_SUCCESS);
2763 }
2764 
2765 /*************************************************************/
2768 UNIV_INTERN
2769 ib_err_t
2771 /*=============*/
2772  ib_tpl_t ib_tpl,
2773  ib_ulint_t i,
2774  ib_i8_t* ival)
2775 {
2776  ib_err_t err;
2777 
2778  err = ib_tuple_check_int(ib_tpl, i, IB_FALSE, sizeof(*ival));
2779 
2780  if (err == DB_SUCCESS) {
2781  ib_col_copy_value_low(ib_tpl, i, ival, sizeof(*ival));
2782  }
2783 
2784  return(err);
2785 }
2786 
2787 /*************************************************************/
2790 UNIV_INTERN
2791 ib_err_t
2793 /*=============*/
2794  ib_tpl_t ib_tpl,
2795  ib_ulint_t i,
2796  ib_u8_t* ival)
2797 {
2798  ib_err_t err;
2799 
2800  err = ib_tuple_check_int(ib_tpl, i, IB_TRUE, sizeof(*ival));
2801 
2802  if (err == DB_SUCCESS) {
2803  ib_col_copy_value_low(ib_tpl, i, ival, sizeof(*ival));
2804  }
2805 
2806  return(err);
2807 }
2808 
2809 /*************************************************************/
2812 UNIV_INTERN
2813 ib_err_t
2815 /*==============*/
2816  ib_tpl_t ib_tpl,
2817  ib_ulint_t i,
2818  ib_i16_t* ival)
2819 {
2820  ib_err_t err;
2821 
2822  err = ib_tuple_check_int(ib_tpl, i, FALSE, sizeof(*ival));
2823 
2824  if (err == DB_SUCCESS) {
2825  ib_col_copy_value_low(ib_tpl, i, ival, sizeof(*ival));
2826  }
2827 
2828  return(err);
2829 }
2830 
2831 /*************************************************************/
2834 UNIV_INTERN
2835 ib_err_t
2837 /*==============*/
2838  ib_tpl_t ib_tpl,
2839  ib_ulint_t i,
2840  ib_u16_t* ival)
2841 {
2842  ib_err_t err;
2843 
2844  err = ib_tuple_check_int(ib_tpl, i, IB_TRUE, sizeof(*ival));
2845 
2846  if (err == DB_SUCCESS) {
2847  ib_col_copy_value_low(ib_tpl, i, ival, sizeof(*ival));
2848  }
2849 
2850  return(err);
2851 }
2852 
2853 /*************************************************************/
2856 UNIV_INTERN
2857 ib_err_t
2859 /*==============*/
2860  ib_tpl_t ib_tpl,
2861  ib_ulint_t i,
2862  ib_i32_t* ival)
2863 {
2864  ib_err_t err;
2865 
2866  err = ib_tuple_check_int(ib_tpl, i, FALSE, sizeof(*ival));
2867 
2868  if (err == DB_SUCCESS) {
2869  ib_col_copy_value_low(ib_tpl, i, ival, sizeof(*ival));
2870  }
2871 
2872  return(err);
2873 }
2874 
2875 /*************************************************************/
2878 UNIV_INTERN
2879 ib_err_t
2881 /*==============*/
2882  ib_tpl_t ib_tpl,
2883  ib_ulint_t i,
2884  ib_u32_t* ival)
2885 {
2886  ib_err_t err;
2887 
2888  err = ib_tuple_check_int(ib_tpl, i, IB_TRUE, sizeof(*ival));
2889 
2890  if (err == DB_SUCCESS) {
2891  ib_col_copy_value_low(ib_tpl, i, ival, sizeof(*ival));
2892  }
2893 
2894  return(err);
2895 }
2896 
2897 /*************************************************************/
2900 UNIV_INTERN
2901 ib_err_t
2903 /*==============*/
2904  ib_tpl_t ib_tpl,
2905  ib_ulint_t i,
2906  ib_i64_t* ival)
2907 {
2908  ib_err_t err;
2909 
2910  err = ib_tuple_check_int(ib_tpl, i, FALSE, sizeof(*ival));
2911 
2912  if (err == DB_SUCCESS) {
2913  ib_col_copy_value_low(ib_tpl, i, ival, sizeof(*ival));
2914  }
2915 
2916  return(err);
2917 }
2918 
2919 /*************************************************************/
2922 UNIV_INTERN
2923 ib_err_t
2925 /*==============*/
2926  ib_tpl_t ib_tpl,
2927  ib_ulint_t i,
2928  ib_u64_t* ival)
2929 {
2930  ib_err_t err;
2931 
2932  err = ib_tuple_check_int(ib_tpl, i, IB_TRUE, sizeof(*ival));
2933 
2934  if (err == DB_SUCCESS) {
2935  ib_col_copy_value_low(ib_tpl, i, ival, sizeof(*ival));
2936  }
2937 
2938  return(err);
2939 }
2940 
2941 /*****************************************************************/
2944 UNIV_INTERN
2945 const void*
2947 /*=============*/
2948  ib_tpl_t ib_tpl,
2949  ib_ulint_t i)
2950 {
2951  const void* data;
2952  const dfield_t* dfield;
2953  ulint data_len;
2954  ib_tuple_t* tuple = (ib_tuple_t*) ib_tpl;
2955 
2956  dfield = ib_col_get_dfield(tuple, i);
2957 
2958  data = dfield_get_data(dfield);
2959  data_len = dfield_get_len(dfield);
2960 
2961  return(data_len != UNIV_SQL_NULL ? data : NULL);
2962 }
2963 
2964 /*****************************************************************/
2967 UNIV_INTERN
2968 ib_ulint_t
2970 /*============*/
2971  ib_tpl_t ib_tpl,
2972  ib_ulint_t i,
2973  ib_col_meta_t* ib_col_meta)
2974 {
2975  return(ib_col_get_meta_low(ib_tpl, i, ib_col_meta));
2976 }
2977 
2978 /*****************************************************************/
2981 UNIV_INTERN
2982 ib_tpl_t
2984 /*============*/
2985  ib_tpl_t ib_tpl)
2986 {
2987  const dict_index_t* index;
2988  ulint n_cols;
2989  ib_tuple_t* tuple = (ib_tuple_t*) ib_tpl;
2990  ib_tuple_type_t type = tuple->type;
2991  mem_heap_t* heap = tuple->heap;
2992 
2993  index = tuple->index;
2994  n_cols = dtuple_get_n_fields(tuple->ptr);
2995 
2996  mem_heap_empty(heap);
2997 
2998  if (type == TPL_TYPE_ROW) {
2999  return(ib_row_tuple_new_low(index, n_cols, heap));
3000  } else {
3001  return(ib_key_tuple_new_low(index, n_cols, heap));
3002  }
3003 }
3004 
3005 /*****************************************************************/
3010 UNIV_INTERN
3011 ib_err_t
3013 /*=====================*/
3014  ib_crsr_t ib_crsr,
3015  ib_tpl_t* ib_dst_tpl,
3016  const ib_tpl_t ib_src_tpl)
3017 {
3018  ulint i;
3019  ulint n_fields;
3020  ib_err_t err = DB_SUCCESS;
3021  ib_tuple_t* dst_tuple = NULL;
3022  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
3023  ib_tuple_t* src_tuple = (ib_tuple_t*) ib_src_tpl;
3024  dict_index_t* clust_index;
3025 
3026  clust_index = dict_table_get_first_index(cursor->prebuilt->table);
3027 
3028  /* We need to ensure that the src tuple belongs to the same table
3029  as the open cursor and that it's not a tuple for a cluster index. */
3030  if (src_tuple->type != TPL_TYPE_KEY) {
3031  return(DB_ERROR);
3032  } else if (src_tuple->index->table != cursor->prebuilt->table) {
3033  return(DB_DATA_MISMATCH);
3034  } else if (src_tuple->index == clust_index) {
3035  return(DB_ERROR);
3036  }
3037 
3038  /* Create the cluster index key search tuple. */
3039  *ib_dst_tpl = ib_clust_search_tuple_create(ib_crsr);
3040 
3041  if (!*ib_dst_tpl) {
3042  return(DB_OUT_OF_MEMORY);
3043  }
3044 
3045  dst_tuple = (ib_tuple_t*) *ib_dst_tpl;
3046  ut_a(dst_tuple->index == clust_index);
3047 
3048  n_fields = dict_index_get_n_unique(dst_tuple->index);
3049 
3050  /* Do a deep copy of the data fields. */
3051  for (i = 0; i < n_fields; i++) {
3052  ulint pos;
3053  dfield_t* src_field;
3054  dfield_t* dst_field;
3055 
3057  src_tuple->index, dst_tuple->index, i);
3058 
3059  ut_a(pos != ULINT_UNDEFINED);
3060 
3061  src_field = dtuple_get_nth_field(src_tuple->ptr, pos);
3062  dst_field = dtuple_get_nth_field(dst_tuple->ptr, i);
3063 
3064  if (!dfield_is_null(src_field)) {
3065  UNIV_MEM_ASSERT_RW(src_field->data, src_field->len);
3066 
3067  dst_field->data = mem_heap_dup(
3068  dst_tuple->heap,
3069  src_field->data,
3070  src_field->len);
3071 
3072  dst_field->len = src_field->len;
3073  } else {
3074  dfield_set_null(dst_field);
3075  }
3076  }
3077 
3078  return(err);
3079 }
3080 
3081 /*****************************************************************/
3085 UNIV_INTERN
3086 ib_err_t
3088 /*==========*/
3089  ib_tpl_t ib_dst_tpl,
3090  const ib_tpl_t ib_src_tpl)
3091 {
3092  ulint i;
3093  ulint n_fields;
3094  ib_err_t err = DB_SUCCESS;
3095  const ib_tuple_t*src_tuple = (const ib_tuple_t*) ib_src_tpl;
3096  ib_tuple_t* dst_tuple = (ib_tuple_t*) ib_dst_tpl;
3097 
3098  /* Make sure src and dst are not the same. */
3099  ut_a(src_tuple != dst_tuple);
3100 
3101  /* Make sure they are the same type and refer to the same index. */
3102  if (src_tuple->type != dst_tuple->type
3103  || src_tuple->index != dst_tuple->index) {
3104 
3105  return(DB_DATA_MISMATCH);
3106  }
3107 
3108  n_fields = dtuple_get_n_fields(src_tuple->ptr);
3109  ut_ad(n_fields == dtuple_get_n_fields(dst_tuple->ptr));
3110 
3111  /* Do a deep copy of the data fields. */
3112  for (i = 0; i < n_fields; ++i) {
3113  dfield_t* src_field;
3114  dfield_t* dst_field;
3115 
3116  src_field = dtuple_get_nth_field(src_tuple->ptr, i);
3117  dst_field = dtuple_get_nth_field(dst_tuple->ptr, i);
3118 
3119  if (!dfield_is_null(src_field)) {
3120  UNIV_MEM_ASSERT_RW(src_field->data, src_field->len);
3121 
3122  dst_field->data = mem_heap_dup(
3123  dst_tuple->heap,
3124  src_field->data,
3125  src_field->len);
3126 
3127  dst_field->len = src_field->len;
3128  } else {
3129  dfield_set_null(dst_field);
3130  }
3131  }
3132 
3133  return(err);
3134 }
3135 
3136 /*****************************************************************/
3139 UNIV_INTERN
3140 ib_tpl_t
3142 /*=======================*/
3143  ib_crsr_t ib_crsr)
3144 {
3145  ulint n_cols;
3146  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
3147  dict_index_t* index = cursor->prebuilt->index;
3148 
3149  n_cols = dict_index_get_n_unique_in_tree(index);
3150  return(ib_key_tuple_new(index, n_cols));
3151 }
3152 
3153 /*****************************************************************/
3156 UNIV_INTERN
3157 ib_tpl_t
3159 /*=====================*/
3160  ib_crsr_t ib_crsr)
3161 {
3162  ulint n_cols;
3163  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
3164  dict_index_t* index = cursor->prebuilt->index;
3165 
3166  n_cols = dict_index_get_n_fields(index);
3167  return(ib_row_tuple_new(index, n_cols));
3168 }
3169 
3170 /*****************************************************************/
3173 UNIV_INTERN
3174 ib_tpl_t
3176 /*=========================*/
3177  ib_crsr_t ib_crsr)
3178 {
3179  ulint n_cols;
3180  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
3182 
3183  index = dict_table_get_first_index(cursor->prebuilt->table);
3184 
3186  return(ib_key_tuple_new(index, n_cols));
3187 }
3188 
3189 /*****************************************************************/
3192 UNIV_INTERN
3193 ib_tpl_t
3195 /*=======================*/
3196  ib_crsr_t ib_crsr)
3197 {
3198  ulint n_cols;
3199  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
3201 
3202  index = dict_table_get_first_index(cursor->prebuilt->table);
3203 
3204  n_cols = dict_table_get_n_cols(cursor->prebuilt->table);
3205  return(ib_row_tuple_new(index, n_cols));
3206 }
3207 
3208 /*****************************************************************/
3211 UNIV_INTERN
3212 ib_ulint_t
3214 /*=====================*/
3215  const ib_tpl_t ib_tpl)
3216 {
3217  const ib_tuple_t* tuple = (const ib_tuple_t*) ib_tpl;
3218 
3219  if (tuple->type == TPL_TYPE_ROW) {
3220  return(dict_table_get_n_user_cols(tuple->index->table));
3221  }
3222 
3224 }
3225 
3226 /*****************************************************************/
3229 UNIV_INTERN
3230 ib_ulint_t
3232 /*================*/
3233  const ib_tpl_t ib_tpl)
3234 {
3235  const ib_tuple_t* tuple = (const ib_tuple_t*) ib_tpl;
3236 
3237  return(dtuple_get_n_fields(tuple->ptr));
3238 }
3239 
3240 /*****************************************************************/
3242 UNIV_INTERN
3243 void
3245 /*============*/
3246  ib_tpl_t ib_tpl)
3247 {
3248  ib_tuple_t* tuple = (ib_tuple_t*) ib_tpl;
3249 
3250  if (!ib_tpl) {
3251  return;
3252  }
3253 
3254  mem_heap_free(tuple->heap);
3255 }
3256 
3257 /*****************************************************************/
3260 UNIV_INTERN
3261 ib_err_t
3263 /*============*/
3264  const char* table_name,
3265  ib_id_u64_t* table_id)
3266 {
3267  ib_err_t err;
3268 
3270 
3271  err = ib_table_get_id_low(table_name, table_id);
3272 
3274 
3275  return(err);
3276 }
3277 
3278 /*****************************************************************/
3281 UNIV_INTERN
3282 ib_err_t
3284 /*============*/
3285  const char* table_name,
3286  const char* index_name,
3287  ib_id_u64_t* index_id)
3288 {
3290  char* normalized_name;
3291  ib_err_t err = DB_TABLE_NOT_FOUND;
3292 
3293  *index_id = 0;
3294 
3295  normalized_name = static_cast<char*>(
3296  mem_alloc(ut_strlen(table_name) + 1));
3297  ib_normalize_table_name(normalized_name, table_name);
3298 
3299  table = ib_lookup_table_by_name(normalized_name);
3300 
3301  mem_free(normalized_name);
3302  normalized_name = NULL;
3303 
3304  if (table != NULL) {
3306 
3307  index = dict_table_get_index_on_name(table, index_name);
3308 
3309  if (index != NULL) {
3310  /* We only support 32 bit table and index ids. Because
3311  we need to pack the table id into the index id. */
3312 
3313  *index_id = (table->id);
3314  *index_id <<= 32;
3315  *index_id |= (index->id);
3316 
3317  err = DB_SUCCESS;
3318  }
3319  }
3320 
3321  return(err);
3322 }
3323 
3324 #ifdef __WIN__
3325 #define SRV_PATH_SEPARATOR '\\'
3326 #else
3327 #define SRV_PATH_SEPARATOR '/'
3328 #endif
3329 
3330 
3331 /*****************************************************************/
3334 UNIV_INTERN
3335 ib_bool_t
3337 /*====================*/
3338  const ib_crsr_t ib_crsr)
3339 {
3340  const ib_cursor_t* cursor = (const ib_cursor_t*) ib_crsr;
3341  row_prebuilt_t* prebuilt = cursor->prebuilt;
3342 
3343  return(ib_btr_cursor_is_positioned(&prebuilt->pcur));
3344 }
3345 
3346 
3347 /*****************************************************************/
3350 UNIV_INTERN
3351 ib_bool_t
3353 /*========================*/
3354  const ib_trx_t ib_trx)
3355 {
3356  const trx_t* trx = (const trx_t*) ib_trx;
3357 
3358  return(trx->dict_operation_lock_mode == RW_X_LATCH);
3359 }
3360 
3361 /*****************************************************************/
3364 UNIV_INTERN
3365 ib_bool_t
3367 /*=====================*/
3368  const ib_trx_t ib_trx)
3369 {
3370  const trx_t* trx = (const trx_t*) ib_trx;
3371 
3372  return(trx->dict_operation_lock_mode == RW_S_LATCH);
3373 }
3374 
3375 /*****************************************************************/
3378 UNIV_INTERN
3379 ib_err_t
3381 /*===========*/
3382  ib_crsr_t ib_crsr,
3383  ib_lck_mode_t ib_lck_mode)
3384 {
3385  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
3386  row_prebuilt_t* prebuilt = cursor->prebuilt;
3387  trx_t* trx = prebuilt->trx;
3388  dict_table_t* table = prebuilt->table;
3389 
3391  trx, table, (enum lock_mode) ib_lck_mode));
3392 }
3393 
3394 /*****************************************************************/
3397 UNIV_INTERN
3398 ib_err_t
3400 /*==========*/
3401  ib_trx_t ib_trx,
3402  ib_id_u64_t table_id,
3403  ib_lck_mode_t ib_lck_mode)
3404 {
3405  ib_err_t err;
3406  que_thr_t* thr;
3407  mem_heap_t* heap;
3409  ib_qry_proc_t q_proc;
3410  trx_t* trx = (trx_t*) ib_trx;
3411 
3412  ut_a(trx->state != TRX_STATE_NOT_STARTED);
3413 
3414  table = ib_open_table_by_id(table_id, FALSE);
3415 
3416  if (table == NULL) {
3417  return(DB_TABLE_NOT_FOUND);
3418  }
3419 
3420  ut_a(ib_lck_mode <= static_cast<ib_lck_mode_t>(LOCK_NUM));
3421 
3422  heap = mem_heap_create(128);
3423 
3424  q_proc.node.sel = sel_node_create(heap);
3425 
3426  thr = pars_complete_graph_for_exec(q_proc.node.sel, trx, heap);
3427 
3428  q_proc.grph.sel = static_cast<que_fork_t*>(que_node_get_parent(thr));
3429  q_proc.grph.sel->state = QUE_FORK_ACTIVE;
3430 
3431  trx->op_info = "setting table lock";
3432 
3433  ut_a(ib_lck_mode == IB_LOCK_IS || ib_lck_mode == IB_LOCK_IX);
3434  err = static_cast<ib_err_t>(
3435  lock_table(0, table, (enum lock_mode) ib_lck_mode, thr));
3436 
3437  trx->error_state = err;
3438 
3439  mem_heap_free(heap);
3440 
3441  return(err);
3442 }
3443 
3444 /*****************************************************************/
3447 UNIV_INTERN
3448 ib_err_t
3450 /*=============*/
3451  ib_crsr_t ib_crsr)
3452 {
3453  ib_err_t err = DB_SUCCESS;
3454  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
3455  row_prebuilt_t* prebuilt = cursor->prebuilt;
3456 
3457  if (prebuilt->trx->mysql_n_tables_locked > 0) {
3458  --prebuilt->trx->mysql_n_tables_locked;
3459  } else {
3460  err = DB_ERROR;
3461  }
3462 
3463  return(err);
3464 }
3465 
3466 /*****************************************************************/
3469 UNIV_INTERN
3470 ib_err_t
3472 /*====================*/
3473  ib_crsr_t ib_crsr,
3474  ib_lck_mode_t ib_lck_mode)
3475 {
3476  ib_err_t err = DB_SUCCESS;
3477  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
3478  row_prebuilt_t* prebuilt = cursor->prebuilt;
3479 
3480  ut_a(ib_lck_mode <= static_cast<ib_lck_mode_t>(LOCK_NUM));
3481 
3482  if (ib_lck_mode == IB_LOCK_X) {
3483  err = ib_cursor_lock(ib_crsr, IB_LOCK_IX);
3484  } else if (ib_lck_mode == IB_LOCK_S) {
3485  err = ib_cursor_lock(ib_crsr, IB_LOCK_IS);
3486  }
3487 
3488  if (err == DB_SUCCESS) {
3489  prebuilt->select_lock_type = (enum lock_mode) ib_lck_mode;
3490  ut_a(prebuilt->trx->state != TRX_STATE_NOT_STARTED);
3491  }
3492 
3493  return(err);
3494 }
3495 
3496 /*****************************************************************/
3498 UNIV_INTERN
3499 void
3501 /*=========================*/
3502  ib_crsr_t ib_crsr)
3503 {
3504  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
3505  row_prebuilt_t* prebuilt = cursor->prebuilt;
3506 
3507  prebuilt->need_to_access_clustered = TRUE;
3508 }
3509 
3510 /*************************************************************/
3513 UNIV_INLINE
3514 ib_err_t
3516 /*===============*/
3517  ib_tpl_t ib_tpl,
3518  ulint col_no,
3519  const void* value,
3520  ulint value_len)
3521 {
3522  const dfield_t* dfield;
3523  ulint data_len;
3524  ulint type_len;
3525  ib_tuple_t* tuple = (ib_tuple_t*) ib_tpl;
3526 
3527  ut_a(col_no < ib_tuple_get_n_cols(ib_tpl));
3528 
3529  dfield = ib_col_get_dfield(tuple, col_no);
3530 
3531  data_len = dfield_get_len(dfield);
3532  type_len = dtype_get_len(dfield_get_type(dfield));
3533 
3534  if (dtype_get_mtype(dfield_get_type(dfield)) != DATA_INT
3535  || value_len != data_len) {
3536 
3537  return(DB_DATA_MISMATCH);
3538  }
3539 
3540  return(ib_col_set_value(ib_tpl, col_no, value, type_len, true));
3541 }
3542 
3543 /*****************************************************************/
3547 UNIV_INTERN
3548 ib_err_t
3550 /*==============*/
3551  ib_tpl_t ib_tpl,
3552  int col_no,
3553  ib_i8_t val)
3554 {
3555  return(ib_col_set_value(ib_tpl, col_no, &val, sizeof(val), true));
3556 }
3557 
3558 /*****************************************************************/
3562 UNIV_INTERN
3563 ib_err_t
3565 /*===============*/
3566  ib_tpl_t ib_tpl,
3567  int col_no,
3568  ib_i16_t val)
3569 {
3570  return(ib_col_set_value(ib_tpl, col_no, &val, sizeof(val), true));
3571 }
3572 
3573 /*****************************************************************/
3577 UNIV_INTERN
3578 ib_err_t
3580 /*===============*/
3581  ib_tpl_t ib_tpl,
3582  int col_no,
3583  ib_i32_t val)
3584 {
3585  return(ib_col_set_value(ib_tpl, col_no, &val, sizeof(val), true));
3586 }
3587 
3588 /*****************************************************************/
3592 UNIV_INTERN
3593 ib_err_t
3595 /*===============*/
3596  ib_tpl_t ib_tpl,
3597  int col_no,
3598  ib_i64_t val)
3599 {
3600  return(ib_col_set_value(ib_tpl, col_no, &val, sizeof(val), true));
3601 }
3602 
3603 /*****************************************************************/
3607 UNIV_INTERN
3608 ib_err_t
3610 /*==============*/
3611  ib_tpl_t ib_tpl,
3612  int col_no,
3613  ib_u8_t val)
3614 {
3615  return(ib_col_set_value(ib_tpl, col_no, &val, sizeof(val), true));
3616 }
3617 
3618 /*****************************************************************/
3622 UNIV_INTERN
3623 ib_err_t
3625 /*===============*/
3626  ib_tpl_t ib_tpl,
3627  int col_no,
3628  ib_u16_t val)
3629 {
3630  return(ib_col_set_value(ib_tpl, col_no, &val, sizeof(val), true));
3631 }
3632 
3633 /*****************************************************************/
3637 UNIV_INTERN
3638 ib_err_t
3640 /*===============*/
3641  ib_tpl_t ib_tpl,
3642  int col_no,
3643  ib_u32_t val)
3644 {
3645  return(ib_col_set_value(ib_tpl, col_no, &val, sizeof(val), true));
3646 }
3647 
3648 /*****************************************************************/
3652 UNIV_INTERN
3653 ib_err_t
3655 /*===============*/
3656  ib_tpl_t ib_tpl,
3657  int col_no,
3658  ib_u64_t val)
3659 {
3660  return(ib_col_set_value(ib_tpl, col_no, &val, sizeof(val), true));
3661 }
3662 
3663 /*****************************************************************/
3665 UNIV_INTERN
3666 void
3668 /*=================*/
3669  ib_crsr_t ib_crsr)
3670 {
3671  ib_cursor_t* cursor = (ib_cursor_t*) ib_crsr;
3672 
3673  cursor->prebuilt->sql_stat_start = TRUE;
3674 }
3675 
3676 /*****************************************************************/
3679 UNIV_INTERN
3680 ib_err_t
3682 /*==================*/
3683  ib_tpl_t ib_tpl,
3684  int col_no,
3685  double val)
3686 {
3687  const dfield_t* dfield;
3688  ib_tuple_t* tuple = (ib_tuple_t*) ib_tpl;
3689 
3690  dfield = ib_col_get_dfield(tuple, col_no);
3691 
3692  if (dtype_get_mtype(dfield_get_type(dfield)) == DATA_DOUBLE) {
3693  return(ib_col_set_value(ib_tpl, col_no,
3694  &val, sizeof(val), true));
3695  } else {
3696  return(DB_DATA_MISMATCH);
3697  }
3698 }
3699 
3700 /*************************************************************/
3703 UNIV_INTERN
3704 ib_err_t
3706 /*=================*/
3707  ib_tpl_t ib_tpl,
3708  ib_ulint_t col_no,
3709  double* dval)
3710 {
3711  ib_err_t err;
3712  const dfield_t* dfield;
3713  ib_tuple_t* tuple = (ib_tuple_t*) ib_tpl;
3714 
3715  dfield = ib_col_get_dfield(tuple, col_no);
3716 
3717  if (dtype_get_mtype(dfield_get_type(dfield)) == DATA_DOUBLE) {
3718  ib_col_copy_value_low(ib_tpl, col_no, dval, sizeof(*dval));
3719  err = DB_SUCCESS;
3720  } else {
3721  err = DB_DATA_MISMATCH;
3722  }
3723 
3724  return(err);
3725 }
3726 
3727 /*****************************************************************/
3730 UNIV_INTERN
3731 ib_err_t
3733 /*=================*/
3734  ib_tpl_t ib_tpl,
3735  int col_no,
3736  float val)
3737 {
3738  const dfield_t* dfield;
3739  ib_tuple_t* tuple = (ib_tuple_t*) ib_tpl;
3740 
3741  dfield = ib_col_get_dfield(tuple, col_no);
3742 
3743  if (dtype_get_mtype(dfield_get_type(dfield)) == DATA_FLOAT) {
3744  return(ib_col_set_value(ib_tpl, col_no,
3745  &val, sizeof(val), true));
3746  } else {
3747  return(DB_DATA_MISMATCH);
3748  }
3749 }
3750 
3751 /*************************************************************/
3754 UNIV_INTERN
3755 ib_err_t
3757 /*================*/
3758  ib_tpl_t ib_tpl,
3759  ib_ulint_t col_no,
3760  float* fval)
3761 {
3762  ib_err_t err;
3763  const dfield_t* dfield;
3764  ib_tuple_t* tuple = (ib_tuple_t*) ib_tpl;
3765 
3766  dfield = ib_col_get_dfield(tuple, col_no);
3767 
3768  if (dtype_get_mtype(dfield_get_type(dfield)) == DATA_FLOAT) {
3769  ib_col_copy_value_low(ib_tpl, col_no, fval, sizeof(*fval));
3770  err = DB_SUCCESS;
3771  } else {
3772  err = DB_DATA_MISMATCH;
3773  }
3774 
3775  return(err);
3776 }
3777 
3778 /*****************************************************************/
3782 UNIV_INTERN
3783 ib_err_t
3785 /*===============*/
3786  ib_crsr_t* ib_crsr,
3788  ib_id_u64_t* table_id)
3789 {
3790  ib_err_t err;
3791  ib_cursor_t* cursor = *(ib_cursor_t**) ib_crsr;
3792  row_prebuilt_t* prebuilt = cursor->prebuilt;
3793 
3794  *table_id = 0;
3795 
3796  err = ib_cursor_lock(*ib_crsr, IB_LOCK_X);
3797 
3798  if (err == DB_SUCCESS) {
3799  trx_t* trx;
3800  dict_table_t* table = prebuilt->table;
3801 
3802  /* We are going to free the cursor and the prebuilt. Store
3803  the transaction handle locally. */
3804  trx = prebuilt->trx;
3805  err = ib_cursor_close(*ib_crsr);
3806  ut_a(err == DB_SUCCESS);
3807 
3808  *ib_crsr = NULL;
3809 
3810  /* A temp go around for assertion in trx_start_for_ddl_low
3811  we already start the trx */
3812  if (trx->state == TRX_STATE_ACTIVE) {
3813 #ifdef UNIV_DEBUG
3814  trx->start_file = 0;
3815 #endif /* UNIV_DEBUG */
3817  }
3818 
3819  /* This function currently commits the transaction
3820  on success. */
3821  err = static_cast<ib_err_t>(
3822  row_truncate_table_for_mysql(table, trx));
3823 
3824  if (err == DB_SUCCESS) {
3825  *table_id = (table->id);
3826  }
3827  }
3828 
3829  return(err);
3830 }
3831 
3832 /*****************************************************************/
3835 UNIV_INTERN
3836 ib_err_t
3838 /*==============*/
3839  const char* table_name,
3840  ib_id_u64_t* table_id)
3841 {
3842  ib_err_t err;
3844  ib_err_t trunc_err;
3845  ib_trx_t ib_trx = NULL;
3846  ib_crsr_t ib_crsr = NULL;
3847 
3849 
3851 
3852  table = dict_table_open_on_name(table_name, TRUE, FALSE,
3854 
3855  if (table != NULL && dict_table_get_first_index(table)) {
3856  err = ib_create_cursor_with_index_id(&ib_crsr, table, 0,
3857  (trx_t*) ib_trx);
3858  } else {
3859  err = DB_TABLE_NOT_FOUND;
3860  }
3861 
3863 
3864  if (err == DB_SUCCESS) {
3865  trunc_err = ib_cursor_truncate(&ib_crsr, table_id);
3866  ut_a(err == DB_SUCCESS);
3867  } else {
3868  trunc_err = err;
3869  }
3870 
3871  if (ib_crsr != NULL) {
3872  err = ib_cursor_close(ib_crsr);
3873  ut_a(err == DB_SUCCESS);
3874  }
3875 
3876  if (trunc_err == DB_SUCCESS) {
3877  ut_a(ib_trx_state(ib_trx) == static_cast<ib_trx_state_t>(
3878  TRX_STATE_NOT_STARTED));
3879 
3880  err = ib_trx_release(ib_trx);
3881  ut_a(err == DB_SUCCESS);
3882  } else {
3883  err = ib_trx_rollback(ib_trx);
3884  ut_a(err == DB_SUCCESS);
3885  }
3886 
3887  return(trunc_err);
3888 }
3889 
3890 /*****************************************************************/
3893 UNIV_INTERN
3894 ib_err_t
3896 /*=========*/
3897  void* thd)
3899 {
3900  innobase_close_thd(static_cast<THD*>(thd));
3901 
3902  return(DB_SUCCESS);
3903 }
3904 
3905 /*****************************************************************/
3908 UNIV_INTERN
3911 /*==============*/
3912 {
3913  return(static_cast<ib_trx_state_t>(ib_trx_level_setting));
3914 }
3915 
3916 /*****************************************************************/
3919 UNIV_INTERN
3920 ib_ulint_t
3922 /*=======================*/
3923 {
3924  return(static_cast<ib_ulint_t>(ib_bk_commit_interval));
3925 }
3926 
3927 /*****************************************************************/
3930 UNIV_INTERN
3931 int
3933 /*============*/
3934 {
3935  int cfg_status;
3936 
3937  cfg_status = (ib_binlog_enabled) ? IB_CFG_BINLOG_ENABLED : 0;
3938 
3939  if (ib_mdl_enabled) {
3940  cfg_status |= IB_CFG_MDL_ENABLED;
3941  }
3942 
3943  if (ib_disable_row_lock) {
3944  cfg_status |= IB_CFG_DISABLE_ROWLOCK;
3945  }
3946 
3947  return(cfg_status);
3948 }