74
75
#define SEL_EXHAUSTED 1
75
76
#define SEL_RETRY 2
77
/************************************************************************
78
/********************************************************************//**
78
79
Returns TRUE if the user-defined column in a secondary index record
79
80
is alphabetically the same as the corresponding BLOB column in the clustered
81
82
NOTE: the comparison is NOT done as a binary comparison, but character
82
fields are compared with collation! */
83
fields are compared with collation!
84
@return TRUE if the columns are equal */
85
87
row_sel_sec_rec_is_for_blob(
86
88
/*========================*/
87
/* out: TRUE if the columns
89
ulint mtype, /* in: main type */
90
ulint prtype, /* in: precise type */
91
ulint mbminlen, /* in: minimum length of a
92
multi-byte character */
93
ulint mbmaxlen, /* in: maximum length of a
94
multi-byte character */
95
const byte* clust_field, /* in: the locally stored part of
89
ulint mtype, /*!< in: main type */
90
ulint prtype, /*!< in: precise type */
91
ulint mbminlen, /*!< in: minimum length of a
92
multi-byte character */
93
ulint mbmaxlen, /*!< in: maximum length of a
94
multi-byte character */
95
const byte* clust_field, /*!< in: the locally stored part of
96
96
the clustered index column, including
97
97
the BLOB pointer; the clustered
98
98
index record must be covered by
99
99
a lock or a page latch to protect it
100
100
against deletion (rollback or purge) */
101
ulint clust_len, /* in: length of clust_field */
102
const byte* sec_field, /* in: column in secondary index */
103
ulint sec_len, /* in: length of sec_field */
104
ulint zip_size) /* in: compressed page size, or 0 */
101
ulint clust_len, /*!< in: length of clust_field */
102
const byte* sec_field, /*!< in: column in secondary index */
103
ulint sec_len, /*!< in: length of sec_field */
104
ulint zip_size) /*!< in: compressed page size, or 0 */
107
107
byte buf[DICT_MAX_INDEX_COL_LEN];
125
125
return(!cmp_data_data(mtype, prtype, buf, len, sec_field, sec_len));
128
/************************************************************************
128
/********************************************************************//**
129
129
Returns TRUE if the user-defined column values in a secondary index record
130
130
are alphabetically the same as the corresponding columns in the clustered
132
132
NOTE: the comparison is NOT done as a binary comparison, but character
133
fields are compared with collation! */
133
fields are compared with collation!
134
@return TRUE if the secondary record is equal to the corresponding
135
fields in the clustered record, when compared with collation */
136
138
row_sel_sec_rec_is_for_clust_rec(
137
139
/*=============================*/
138
/* out: TRUE if the secondary
139
record is equal to the corresponding
140
fields in the clustered record,
141
when compared with collation */
142
const rec_t* sec_rec, /* in: secondary index record */
143
dict_index_t* sec_index, /* in: secondary index */
144
const rec_t* clust_rec, /* in: clustered index record;
140
const rec_t* sec_rec, /*!< in: secondary index record */
141
dict_index_t* sec_index, /*!< in: secondary index */
142
const rec_t* clust_rec, /*!< in: clustered index record;
145
143
must be protected by a lock or
146
144
a page latch against deletion
147
145
in rollback or purge */
148
dict_index_t* clust_index) /* in: clustered index */
146
dict_index_t* clust_index) /*!< in: clustered index */
150
148
const byte* sec_field;
238
236
return(is_equal);
241
/*************************************************************************
242
Creates a select node struct. */
239
/*********************************************************************//**
240
Creates a select node struct.
241
@return own: select node struct */
247
/* out, own: select node struct */
248
mem_heap_t* heap) /* in: memory heap where created */
246
mem_heap_t* heap) /*!< in: memory heap where created */
250
248
sel_node_t* node;
307
/*************************************************************************
305
/*********************************************************************//**
308
306
Assigns the values in the select list to the possible into-variables in
309
307
SELECT ... INTO ... */
312
310
sel_assign_into_var_values(
313
311
/*=======================*/
314
sym_node_t* var, /* in: first variable in a list of variables */
315
sel_node_t* node) /* in: select node */
312
sym_node_t* var, /*!< in: first variable in a list of variables */
313
sel_node_t* node) /*!< in: select node */
336
/*************************************************************************
334
/*********************************************************************//**
337
335
Resets the aggregate value totals in the select list of an aggregate type
341
339
sel_reset_aggregate_vals(
342
340
/*=====================*/
343
sel_node_t* node) /* in: select node */
341
sel_node_t* node) /*!< in: select node */
345
343
func_node_t* func_node;
357
355
node->aggregate_already_fetched = FALSE;
360
/*************************************************************************
358
/*********************************************************************//**
361
359
Copies the input variable values when an explicit cursor is opened. */
364
362
row_sel_copy_input_variable_vals(
365
363
/*=============================*/
366
sel_node_t* node) /* in: select node */
364
sel_node_t* node) /*!< in: select node */
381
/*************************************************************************
379
/*********************************************************************//**
382
380
Fetches the column values from a record. */
385
383
row_sel_fetch_columns(
386
384
/*==================*/
387
dict_index_t* index, /* in: record index */
388
const rec_t* rec, /* in: record in a clustered or non-clustered
385
dict_index_t* index, /*!< in: record index */
386
const rec_t* rec, /*!< in: record in a clustered or non-clustered
389
387
index; must be protected by a page latch */
390
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
391
sym_node_t* column) /* in: first column in a column list, or
388
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
389
sym_node_t* column) /*!< in: first column in a column list, or
460
/*************************************************************************
458
/*********************************************************************//**
461
459
Allocates a prefetch buffer for a column when prefetch is first time done. */
464
462
sel_col_prefetch_buf_alloc(
465
463
/*=======================*/
466
sym_node_t* column) /* in: symbol table node for a column */
464
sym_node_t* column) /*!< in: symbol table node for a column */
468
466
sel_buf_t* sel_buf;
484
/*************************************************************************
482
/*********************************************************************//**
485
483
Frees a prefetch buffer for a column, including the dynamically allocated
486
484
memory for data stored there. */
489
487
sel_col_prefetch_buf_free(
490
488
/*======================*/
491
sel_buf_t* prefetch_buf) /* in, own: prefetch buffer */
489
sel_buf_t* prefetch_buf) /*!< in, own: prefetch buffer */
493
491
sel_buf_t* sel_buf;
565
563
plan->first_prefetched++;
568
/*************************************************************************
566
/*********************************************************************//**
569
567
Pushes the column values for a prefetched, cached row to the column prefetch
570
568
buffers from the val fields in the column nodes. */
573
571
sel_push_prefetched_row(
574
572
/*====================*/
575
plan_t* plan) /* in: plan node for a table */
573
plan_t* plan) /*!< in: plan node for a table */
577
575
sym_node_t* column;
578
576
sel_buf_t* sel_buf;
640
/*************************************************************************
641
Builds a previous version of a clustered index record for a consistent read */
638
/*********************************************************************//**
639
Builds a previous version of a clustered index record for a consistent read
640
@return DB_SUCCESS or error code */
644
643
row_sel_build_prev_vers(
645
644
/*====================*/
646
/* out: DB_SUCCESS or error code */
647
read_view_t* read_view, /* in: read view */
648
dict_index_t* index, /* in: plan node for table */
649
rec_t* rec, /* in: record in a clustered index */
650
ulint** offsets, /* in/out: offsets returned by
645
read_view_t* read_view, /*!< in: read view */
646
dict_index_t* index, /*!< in: plan node for table */
647
rec_t* rec, /*!< in: record in a clustered index */
648
ulint** offsets, /*!< in/out: offsets returned by
651
649
rec_get_offsets(rec, plan->index) */
652
mem_heap_t** offset_heap, /* in/out: memory heap from which
650
mem_heap_t** offset_heap, /*!< in/out: memory heap from which
653
651
the offsets are allocated */
654
mem_heap_t** old_vers_heap, /* out: old version heap to use */
655
rec_t** old_vers, /* out: old version, or NULL if the
652
mem_heap_t** old_vers_heap, /*!< out: old version heap to use */
653
rec_t** old_vers, /*!< out: old version, or NULL if the
656
654
record does not exist in the view:
657
655
i.e., it was freshly inserted
659
mtr_t* mtr) /* in: mtr */
657
mtr_t* mtr) /*!< in: mtr */
675
/*************************************************************************
673
/*********************************************************************//**
676
674
Builds the last committed version of a clustered index record for a
677
semi-consistent read. */
675
semi-consistent read.
676
@return DB_SUCCESS or error code */
680
679
row_sel_build_committed_vers_for_mysql(
681
680
/*===================================*/
682
/* out: DB_SUCCESS or error code */
683
dict_index_t* clust_index, /* in: clustered index */
684
row_prebuilt_t* prebuilt, /* in: prebuilt struct */
685
const rec_t* rec, /* in: record in a clustered index */
686
ulint** offsets, /* in/out: offsets returned by
681
dict_index_t* clust_index, /*!< in: clustered index */
682
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
683
const rec_t* rec, /*!< in: record in a clustered index */
684
ulint** offsets, /*!< in/out: offsets returned by
687
685
rec_get_offsets(rec, clust_index) */
688
mem_heap_t** offset_heap, /* in/out: memory heap from which
686
mem_heap_t** offset_heap, /*!< in/out: memory heap from which
689
687
the offsets are allocated */
690
const rec_t** old_vers, /* out: old version, or NULL if the
688
const rec_t** old_vers, /*!< out: old version, or NULL if the
691
689
record does not exist in the view:
692
690
i.e., it was freshly inserted
694
mtr_t* mtr) /* in: mtr */
692
mtr_t* mtr) /*!< in: mtr */
710
/*************************************************************************
708
/*********************************************************************//**
711
709
Tests the conditions which determine when the index segment we are searching
712
through has been exhausted. */
710
through has been exhausted.
711
@return TRUE if row passed the tests */
715
714
row_sel_test_end_conds(
716
715
/*===================*/
717
/* out: TRUE if row passed the tests */
718
plan_t* plan) /* in: plan for the table; the column values must
716
plan_t* plan) /*!< in: plan for the table; the column values must
719
717
already have been retrieved and the right sides of
720
718
comparisons evaluated */
748
/*************************************************************************
749
Tests the other conditions. */
746
/*********************************************************************//**
747
Tests the other conditions.
748
@return TRUE if row passed the tests */
752
751
row_sel_test_other_conds(
753
752
/*=====================*/
754
/* out: TRUE if row passed the tests */
755
plan_t* plan) /* in: plan for the table; the column values must
753
plan_t* plan) /*!< in: plan for the table; the column values must
756
754
already have been retrieved */
758
756
func_node_t* cond;
776
/*************************************************************************
774
/*********************************************************************//**
777
775
Retrieves the clustered index record corresponding to a record in a
778
non-clustered index. Does the necessary locking. */
776
non-clustered index. Does the necessary locking.
777
@return DB_SUCCESS or error code */
781
780
row_sel_get_clust_rec(
782
781
/*==================*/
783
/* out: DB_SUCCESS or error code */
784
sel_node_t* node, /* in: select_node */
785
plan_t* plan, /* in: plan node for table */
786
rec_t* rec, /* in: record in a non-clustered index */
787
que_thr_t* thr, /* in: query thread */
788
rec_t** out_rec,/* out: clustered record or an old version of
782
sel_node_t* node, /*!< in: select_node */
783
plan_t* plan, /*!< in: plan node for table */
784
rec_t* rec, /*!< in: record in a non-clustered index */
785
que_thr_t* thr, /*!< in: query thread */
786
rec_t** out_rec,/*!< out: clustered record or an old version of
789
787
it, NULL if the old version did not exist
790
788
in the read view, i.e., it was a fresh
791
789
inserted version */
792
mtr_t* mtr) /* in: mtr used to get access to the
790
mtr_t* mtr) /*!< in: mtr used to get access to the
793
791
non-clustered record; the same mtr is used to
794
792
access the clustered index */
940
/*************************************************************************
941
Sets a lock on a record. */
938
/*********************************************************************//**
939
Sets a lock on a record.
940
@return DB_SUCCESS or error code */
944
943
sel_set_rec_lock(
945
944
/*=============*/
946
/* out: DB_SUCCESS or error code */
947
const buf_block_t* block, /* in: buffer block of rec */
948
const rec_t* rec, /* in: record */
949
dict_index_t* index, /* in: index */
950
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
951
ulint mode, /* in: lock mode */
952
ulint type, /* in: LOCK_ORDINARY, LOCK_GAP, or
945
const buf_block_t* block, /*!< in: buffer block of rec */
946
const rec_t* rec, /*!< in: record */
947
dict_index_t* index, /*!< in: index */
948
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
949
ulint mode, /*!< in: lock mode */
950
ulint type, /*!< in: LOCK_ORDINARY, LOCK_GAP, or
953
951
LOC_REC_NOT_GAP */
954
que_thr_t* thr) /* in: query thread */
952
que_thr_t* thr) /*!< in: query thread */
979
/*************************************************************************
977
/*********************************************************************//**
980
978
Opens a pcur to a table index. */
983
981
row_sel_open_pcur(
984
982
/*==============*/
985
plan_t* plan, /* in: table plan */
983
plan_t* plan, /*!< in: table plan */
986
984
ibool search_latch_locked,
987
/* in: TRUE if the thread currently
985
/*!< in: TRUE if the thread currently
988
986
has the search latch locked in
990
mtr_t* mtr) /* in: mtr */
988
mtr_t* mtr) /*!< in: mtr */
992
990
dict_index_t* index;
993
991
func_node_t* cond;
1051
1049
plan->pcur_is_open = TRUE;
1054
/*************************************************************************
1055
Restores a stored pcur position to a table index. */
1052
/*********************************************************************//**
1053
Restores a stored pcur position to a table index.
1054
@return TRUE if the cursor should be moved to the next record after we
1055
return from this function (moved to the previous, in the case of a
1056
descending cursor) without processing again the current cursor
1058
1060
row_sel_restore_pcur_pos(
1059
1061
/*=====================*/
1060
/* out: TRUE if the cursor should be moved to
1061
the next record after we return from this
1062
function (moved to the previous, in the case
1063
of a descending cursor) without processing
1064
again the current cursor record */
1065
plan_t* plan, /* in: table plan */
1066
mtr_t* mtr) /* in: mtr */
1062
plan_t* plan, /*!< in: table plan */
1063
mtr_t* mtr) /*!< in: mtr */
1068
1065
ibool equal_position;
1069
1066
ulint relative_position;
1161
1158
plan->n_rows_prefetched = 0;
1164
/*************************************************************************
1161
/*********************************************************************//**
1165
1162
Tries to do a shortcut to fetch a clustered index record with a unique key,
1166
using the hash index if possible (not always). */
1163
using the hash index if possible (not always).
1164
@return SEL_FOUND, SEL_EXHAUSTED, SEL_RETRY */
1169
1167
row_sel_try_search_shortcut(
1170
1168
/*========================*/
1171
/* out: SEL_FOUND, SEL_EXHAUSTED, SEL_RETRY */
1172
sel_node_t* node, /* in: select node for a consistent read */
1173
plan_t* plan, /* in: plan for a unique search in clustered
1169
sel_node_t* node, /*!< in: select node for a consistent read */
1170
plan_t* plan, /*!< in: plan for a unique search in clustered
1175
mtr_t* mtr) /* in: mtr */
1172
mtr_t* mtr) /*!< in: mtr */
1177
1174
dict_index_t* index;
1266
/*************************************************************************
1267
Performs a select step. */
1263
/*********************************************************************//**
1264
Performs a select step.
1265
@return DB_SUCCESS or error code */
1272
/* out: DB_SUCCESS or error code */
1273
sel_node_t* node, /* in: select node */
1274
que_thr_t* thr) /* in: query thread */
1270
sel_node_t* node, /*!< in: select node */
1271
que_thr_t* thr) /*!< in: query thread */
1276
1273
dict_index_t* index;
1968
/**************************************************************************
1964
/**********************************************************************//**
1969
1965
Performs a select step. This is a high-level function used in SQL execution
1967
@return query thread to run next or NULL */
1975
/* out: query thread to run next or NULL */
1976
que_thr_t* thr) /* in: query thread */
1972
que_thr_t* thr) /*!< in: query thread */
1978
1974
ulint i_lock_mode;
1979
1975
sym_node_t* table_node;
2070
/**************************************************************************
2071
Performs a fetch for a cursor. */
2066
/**********************************************************************//**
2067
Performs a fetch for a cursor.
2068
@return query thread to run next or NULL */
2076
/* out: query thread to run next or NULL */
2077
que_thr_t* thr) /* in: query thread */
2073
que_thr_t* thr) /*!< in: query thread */
2079
2075
sel_node_t* sel_node;
2080
2076
fetch_node_t* node;
2133
/********************************************************************
2134
Sample callback function for fetch that prints each row.*/
2129
/****************************************************************//**
2130
Sample callback function for fetch that prints each row.
2131
@return always returns non-NULL */
2137
2134
row_fetch_print(
2138
2135
/*============*/
2139
/* out: always returns non-NULL */
2140
void* row, /* in: sel_node_t* */
2141
void* user_arg) /* in: not used */
2136
void* row, /*!< in: sel_node_t* */
2137
void* user_arg) /*!< in: not used */
2143
2139
sel_node_t* node = row;
2144
2140
que_node_t* exp;
2174
2170
return((void*)42);
2177
/********************************************************************
2173
/****************************************************************//**
2178
2174
Callback function for fetch that stores an unsigned 4 byte integer to the
2179
2175
location pointed. The column's type must be DATA_INT, DATA_UNSIGNED, length
2177
@return always returns NULL */
2183
2180
row_fetch_store_uint4(
2184
2181
/*==================*/
2185
/* out: always returns NULL */
2186
void* row, /* in: sel_node_t* */
2187
void* user_arg) /* in: data pointer */
2182
void* row, /*!< in: sel_node_t* */
2183
void* user_arg) /*!< in: data pointer */
2189
2185
sel_node_t* node = row;
2190
2186
ib_uint32_t* val = user_arg;
2207
/***************************************************************
2208
Prints a row in a select result. */
2203
/***********************************************************//**
2204
Prints a row in a select result.
2205
@return query thread to run next or NULL */
2211
2208
row_printf_step(
2212
2209
/*============*/
2213
/* out: query thread to run next or NULL */
2214
que_thr_t* thr) /* in: query thread */
2210
que_thr_t* thr) /*!< in: query thread */
2216
2212
row_printf_node_t* node;
2217
2213
sel_node_t* sel_node;
2279
2275
row_sel_convert_mysql_key_to_innobase(
2280
2276
/*==================================*/
2281
dtuple_t* tuple, /* in/out: tuple where to build;
2277
dtuple_t* tuple, /*!< in/out: tuple where to build;
2282
2278
NOTE: we assume that the type info
2283
2279
in the tuple is already according
2285
byte* buf, /* in: buffer to use in field
2281
byte* buf, /*!< in: buffer to use in field
2287
ulint buf_len, /* in: buffer length */
2288
dict_index_t* index, /* in: index of the key value */
2289
const byte* key_ptr, /* in: MySQL key value */
2290
ulint key_len, /* in: MySQL key value length */
2291
trx_t* trx) /* in: transaction */
2283
ulint buf_len, /*!< in: buffer length */
2284
dict_index_t* index, /*!< in: index of the key value */
2285
const byte* key_ptr, /*!< in: MySQL key value */
2286
ulint key_len, /*!< in: MySQL key value length */
2287
trx_t* trx) /*!< in: transaction */
2293
2289
byte* original_buf = buf;
2294
2290
const byte* original_key_ptr = key_ptr;
2471
2467
dtuple_set_n_fields(tuple, n_fields);
2474
/******************************************************************
2470
/**************************************************************//**
2475
2471
Stores the row id to the prebuilt struct. */
2478
2474
row_sel_store_row_id_to_prebuilt(
2479
2475
/*=============================*/
2480
row_prebuilt_t* prebuilt, /* in/out: prebuilt */
2481
const rec_t* index_rec, /* in: record */
2482
const dict_index_t* index, /* in: index of the record */
2483
const ulint* offsets) /* in: rec_get_offsets
2476
row_prebuilt_t* prebuilt, /*!< in/out: prebuilt */
2477
const rec_t* index_rec, /*!< in: record */
2478
const dict_index_t* index, /*!< in: index of the record */
2479
const ulint* offsets) /*!< in: rec_get_offsets
2484
2480
(index_rec, index) */
2486
2482
const byte* data;
2509
2505
ut_memcpy(prebuilt->row_id, data, len);
2512
/******************************************************************
2508
/**************************************************************//**
2513
2509
Stores a non-SQL-NULL field in the MySQL format. The counterpart of this
2514
2510
function is row_mysql_store_col_in_innobase_format() in row0mysql.c. */
2517
2513
row_sel_field_store_in_mysql_format(
2518
2514
/*================================*/
2519
byte* dest, /* in/out: buffer where to store; NOTE
2515
byte* dest, /*!< in/out: buffer where to store; NOTE
2520
2516
that BLOBs are not in themselves
2521
2517
stored here: the caller must allocate
2522
2518
and copy the BLOB into buffer before,
2523
2519
and pass the pointer to the BLOB in
2525
2521
const mysql_row_templ_t* templ,
2526
/* in: MySQL column template.
2522
/*!< in: MySQL column template.
2527
2523
Its following fields are referenced:
2528
2524
type, is_unsigned, mysql_col_len,
2529
2525
mbminlen, mbmaxlen */
2530
const byte* data, /* in: data to store */
2531
ulint len) /* in: length of the data */
2526
const byte* data, /*!< in: data to store */
2527
ulint len) /*!< in: length of the data */
2534
2530
byte* field_end;
2667
/******************************************************************
2663
/**************************************************************//**
2668
2664
Convert a row in the Innobase format to a row in the MySQL format.
2669
2665
Note that the template in prebuilt may advise us to copy only a few
2670
2666
columns to mysql_rec, other columns are left blank. All columns may not
2671
be needed in the query. */
2667
be needed in the query.
2668
@return TRUE if success, FALSE if could not allocate memory for a BLOB
2669
(though we may also assert in that case) */
2674
2672
row_sel_store_mysql_rec(
2675
2673
/*====================*/
2676
/* out: TRUE if success, FALSE if
2677
could not allocate memory for a BLOB
2678
(though we may also assert in that
2680
byte* mysql_rec, /* out: row in the MySQL format */
2681
row_prebuilt_t* prebuilt, /* in: prebuilt struct */
2682
const rec_t* rec, /* in: Innobase record in the index
2674
byte* mysql_rec, /*!< out: row in the MySQL format */
2675
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
2676
const rec_t* rec, /*!< in: Innobase record in the index
2683
2677
which was described in prebuilt's
2684
2678
template; must be protected by
2685
2679
a page latch */
2686
const ulint* offsets, /* in: array returned by
2680
const ulint* offsets) /*!< in: array returned by
2687
2681
rec_get_offsets() */
2688
ulint start_field_no,
2691
2683
mysql_row_templ_t* templ;
2692
2684
mem_heap_t* extern_field_heap = NULL;
2791
2782
mysql_rec[templ->mysql_null_byte_offset]
2792
2783
|= (byte) templ->mysql_null_bit_mask;
2793
2784
memcpy(mysql_rec + templ->mysql_col_offset,
2794
prebuilt->default_rec + templ->mysql_col_offset,
2785
(const byte*) prebuilt->default_rec
2786
+ templ->mysql_col_offset,
2795
2787
templ->mysql_col_len);
2802
/*************************************************************************
2803
Builds a previous version of a clustered index record for a consistent read */
2794
/*********************************************************************//**
2795
Builds a previous version of a clustered index record for a consistent read
2796
@return DB_SUCCESS or error code */
2806
2799
row_sel_build_prev_vers_for_mysql(
2807
2800
/*==============================*/
2808
/* out: DB_SUCCESS or error code */
2809
read_view_t* read_view, /* in: read view */
2810
dict_index_t* clust_index, /* in: clustered index */
2811
row_prebuilt_t* prebuilt, /* in: prebuilt struct */
2812
const rec_t* rec, /* in: record in a clustered index */
2813
ulint** offsets, /* in/out: offsets returned by
2801
read_view_t* read_view, /*!< in: read view */
2802
dict_index_t* clust_index, /*!< in: clustered index */
2803
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
2804
const rec_t* rec, /*!< in: record in a clustered index */
2805
ulint** offsets, /*!< in/out: offsets returned by
2814
2806
rec_get_offsets(rec, clust_index) */
2815
mem_heap_t** offset_heap, /* in/out: memory heap from which
2807
mem_heap_t** offset_heap, /*!< in/out: memory heap from which
2816
2808
the offsets are allocated */
2817
rec_t** old_vers, /* out: old version, or NULL if the
2809
rec_t** old_vers, /*!< out: old version, or NULL if the
2818
2810
record does not exist in the view:
2819
2811
i.e., it was freshly inserted
2821
mtr_t* mtr) /* in: mtr */
2813
mtr_t* mtr) /*!< in: mtr */
2837
/*************************************************************************
2829
/*********************************************************************//**
2838
2830
Retrieves the clustered index record corresponding to a record in a
2839
2831
non-clustered index. Does the necessary locking. Used in the MySQL
2833
@return DB_SUCCESS or error code */
2843
2836
row_sel_get_clust_rec_for_mysql(
2844
2837
/*============================*/
2845
/* out: DB_SUCCESS or error code */
2846
row_prebuilt_t* prebuilt,/* in: prebuilt struct in the handle */
2847
dict_index_t* sec_index,/* in: secondary index where rec resides */
2848
const rec_t* rec, /* in: record in a non-clustered index; if
2838
row_prebuilt_t* prebuilt,/*!< in: prebuilt struct in the handle */
2839
dict_index_t* sec_index,/*!< in: secondary index where rec resides */
2840
const rec_t* rec, /*!< in: record in a non-clustered index; if
2849
2841
this is a locking read, then rec is not
2850
2842
allowed to be delete-marked, and that would
2851
2843
not make sense either */
2852
que_thr_t* thr, /* in: query thread */
2853
const rec_t** out_rec,/* out: clustered record or an old version of
2844
que_thr_t* thr, /*!< in: query thread */
2845
const rec_t** out_rec,/*!< out: clustered record or an old version of
2854
2846
it, NULL if the old version did not exist
2855
2847
in the read view, i.e., it was a fresh
2856
2848
inserted version */
2857
ulint** offsets,/* in: offsets returned by
2849
ulint** offsets,/*!< in: offsets returned by
2858
2850
rec_get_offsets(rec, sec_index);
2859
2851
out: offsets returned by
2860
2852
rec_get_offsets(out_rec, clust_index) */
2861
mem_heap_t** offset_heap,/* in/out: memory heap from which
2853
mem_heap_t** offset_heap,/*!< in/out: memory heap from which
2862
2854
the offsets are allocated */
2863
mtr_t* mtr) /* in: mtr used to get access to the
2855
mtr_t* mtr) /*!< in: mtr used to get access to the
2864
2856
non-clustered record; the same mtr is used to
2865
2857
access the clustered index */
3020
/************************************************************************
3013
/********************************************************************//**
3021
3014
Restores cursor position after it has been stored. We have to take into
3022
3015
account that the record cursor was positioned on may have been deleted.
3023
Then we may have to move the cursor one step up or down. */
3016
Then we may have to move the cursor one step up or down.
3017
@return TRUE if we may need to process the record the cursor is now
3018
positioned on (i.e. we should not go to the next record yet) */
3026
3021
sel_restore_position_for_mysql(
3027
3022
/*===========================*/
3028
/* out: TRUE if we may need to
3029
process the record the cursor is
3030
now positioned on (i.e. we should
3031
not go to the next record yet) */
3032
ibool* same_user_rec, /* out: TRUE if we were able to restore
3023
ibool* same_user_rec, /*!< out: TRUE if we were able to restore
3033
3024
the cursor on a user record with the
3034
3025
same ordering prefix in in the
3035
3026
B-tree index */
3036
ulint latch_mode, /* in: latch mode wished in
3027
ulint latch_mode, /*!< in: latch mode wished in
3038
btr_pcur_t* pcur, /* in: cursor whose position
3029
btr_pcur_t* pcur, /*!< in: cursor whose position
3039
3030
has been stored */
3040
ibool moves_up, /* in: TRUE if the cursor moves up
3031
ibool moves_up, /*!< in: TRUE if the cursor moves up
3041
3032
in the index */
3042
mtr_t* mtr) /* in: mtr; CAUTION: may commit
3033
mtr_t* mtr) /*!< in: mtr; CAUTION: may commit
3043
3034
mtr temporarily! */
3090
/************************************************************************
3081
/********************************************************************//**
3091
3082
Pops a cached row for MySQL from the fetch cache. */
3094
3085
row_sel_pop_cached_row_for_mysql(
3095
3086
/*=============================*/
3096
byte* buf, /* in/out: buffer where to copy the
3087
byte* buf, /*!< in/out: buffer where to copy the
3098
row_prebuilt_t* prebuilt) /* in: prebuilt struct */
3089
row_prebuilt_t* prebuilt) /*!< in: prebuilt struct */
3101
3092
mysql_row_templ_t* templ;
3140
/************************************************************************
3131
/********************************************************************//**
3141
3132
Pushes a row for MySQL to the fetch cache. */
3144
3135
row_sel_push_cache_row_for_mysql(
3145
3136
/*=============================*/
3146
row_prebuilt_t* prebuilt, /* in: prebuilt struct */
3147
const rec_t* rec, /* in: record to push; must
3137
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
3138
const rec_t* rec, /*!< in: record to push; must
3148
3139
be protected by a page latch */
3149
const ulint* offsets, /* in: rec_get_offsets() */
3150
ulint start_field_no, /* psergy: start from this field */
3151
byte* remainder_buf) /* if above !=0 -> where to take
3140
const ulint* offsets) /*!<in: rec_get_offsets() */
3182
3170
if (UNIV_UNLIKELY(!row_sel_store_mysql_rec(
3183
3171
prebuilt->fetch_cache[
3184
3172
prebuilt->n_fetch_cached],
3185
prebuilt, rec, offsets, start_field_no,
3186
prebuilt->n_template))) {
3173
prebuilt, rec, offsets))) {
3190
if (start_field_no) {
3191
for (i=0; i < start_field_no; i++) {
3192
register ulint offs;
3193
mysql_row_templ_t* templ;
3194
templ = prebuilt->mysql_template + i;
3196
if (templ->mysql_null_bit_mask) {
3197
offs= templ->mysql_null_byte_offset;
3198
if (*(remainder_buf + offs) & templ->mysql_null_bit_mask)
3199
*(prebuilt->fetch_cache[prebuilt->n_fetch_cached] + offs) |=
3200
/* (*(remainder_buf + offs) &*/( templ->mysql_null_bit_mask);
3202
*(prebuilt->fetch_cache[prebuilt->n_fetch_cached] + offs) &=
3203
~templ->mysql_null_bit_mask;
3206
offs= templ->mysql_col_offset;
3207
memcpy(prebuilt->fetch_cache[prebuilt->n_fetch_cached] + offs,
3208
remainder_buf + offs,
3209
templ->mysql_col_len);
3214
3177
prebuilt->n_fetch_cached++;
3217
/*************************************************************************
3180
/*********************************************************************//**
3218
3181
Tries to do a shortcut to fetch a clustered index record with a unique key,
3219
3182
using the hash index if possible (not always). We assume that the search
3220
3183
mode is PAGE_CUR_GE, it is a consistent read, there is a read view in trx,
3221
btr search latch has been locked in S-mode. */
3184
btr search latch has been locked in S-mode.
3185
@return SEL_FOUND, SEL_EXHAUSTED, SEL_RETRY */
3224
3188
row_sel_try_search_shortcut_for_mysql(
3225
3189
/*==================================*/
3226
/* out: SEL_FOUND, SEL_EXHAUSTED, SEL_RETRY */
3227
const rec_t** out_rec,/* out: record if found */
3228
row_prebuilt_t* prebuilt,/* in: prebuilt struct */
3229
ulint** offsets,/* in/out: for rec_get_offsets(*out_rec) */
3230
mem_heap_t** heap, /* in/out: heap for rec_get_offsets() */
3231
mtr_t* mtr) /* in: started mtr */
3190
const rec_t** out_rec,/*!< out: record if found */
3191
row_prebuilt_t* prebuilt,/*!< in: prebuilt struct */
3192
ulint** offsets,/*!< in/out: for rec_get_offsets(*out_rec) */
3193
mem_heap_t** heap, /*!< in/out: heap for rec_get_offsets() */
3194
mtr_t* mtr) /*!< in: started mtr */
3233
3196
dict_index_t* index = prebuilt->index;
3234
3197
const dtuple_t* search_tuple = prebuilt->search_tuple;
3285
3248
return(SEL_FOUND);
3288
/************************************************************************
3251
/********************************************************************//**
3289
3252
Searches for rows in the database. This is used in the interface to
3290
3253
MySQL. This function opens a cursor, and also implements fetch next
3291
3254
and fetch prev. NOTE that if we do a search with a full key value
3292
3255
from a unique index (ROW_SEL_EXACT), then we will not store the cursor
3293
position and fetch next or fetch prev must not be tried to the cursor! */
3256
position and fetch next or fetch prev must not be tried to the cursor!
3257
@return DB_SUCCESS, DB_RECORD_NOT_FOUND, DB_END_OF_INDEX, DB_DEADLOCK,
3258
DB_LOCK_TABLE_FULL, DB_CORRUPTION, or DB_TOO_BIG_RECORD */
3296
3261
row_search_for_mysql(
3297
3262
/*=================*/
3299
DB_RECORD_NOT_FOUND,
3300
DB_END_OF_INDEX, DB_DEADLOCK,
3301
DB_LOCK_TABLE_FULL, DB_CORRUPTION,
3302
or DB_TOO_BIG_RECORD */
3303
byte* buf, /* in/out: buffer for the fetched
3263
byte* buf, /*!< in/out: buffer for the fetched
3304
3264
row in the MySQL format */
3305
ulint mode, /* in: search mode PAGE_CUR_L, ... */
3306
row_prebuilt_t* prebuilt, /* in: prebuilt struct for the
3265
ulint mode, /*!< in: search mode PAGE_CUR_L, ... */
3266
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct for the
3307
3267
table handle; this contains the info
3308
3268
of search_tuple, index; if search
3309
3269
tuple contains 0 fields then we
3310
3270
position the cursor at the start or
3311
3271
the end of the index, depending on
3313
ulint match_mode, /* in: 0 or ROW_SEL_EXACT or
3273
ulint match_mode, /*!< in: 0 or ROW_SEL_EXACT or
3314
3274
ROW_SEL_EXACT_PREFIX */
3315
ulint direction) /* in: 0 or ROW_SEL_NEXT or
3275
ulint direction) /*!< in: 0 or ROW_SEL_NEXT or
3316
3276
ROW_SEL_PREV; NOTE: if this is != 0,
3317
3277
then prebuilt must have a pcur
3318
3278
with stored position! In opening of a
3368
3326
"InnoDB: the MySQL datadir, or have you used"
3369
3327
" DISCARD TABLESPACE?\n"
3370
3328
"InnoDB: Look from\n"
3371
"InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
3372
"innodb-troubleshooting.html\n"
3329
"InnoDB: " REFMAN "innodb-troubleshooting.html\n"
3373
3330
"InnoDB: how you can resolve the problem.\n",
3374
3331
prebuilt->table->name);
3376
3333
return(DB_ERROR);
3336
if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
3338
return(DB_MISSING_HISTORY);
3379
3341
if (UNIV_UNLIKELY(prebuilt->magic_n != ROW_PREBUILT_ALLOCATED)) {
3380
3342
fprintf(stderr,
3381
3343
"InnoDB: Error: trying to free a corrupt\n"
3439
3401
is set or session is using a READ COMMITED isolation level. Then
3440
3402
we are able to remove the record locks set here on an individual
3443
if ((srv_locks_unsafe_for_binlog
3444
|| trx->isolation_level == TRX_ISO_READ_COMMITTED)
3445
&& prebuilt->select_lock_type != LOCK_NONE) {
3447
trx_reset_new_rec_lock_info(trx);
3404
prebuilt->new_rec_locks = 0;
3450
3406
/*-------------------------------------------------------------*/
3451
3407
/* PHASE 1: Try to pop the row from the prefetch cache */
4249
if (prebuilt->idx_cond_func)
4252
ut_ad(prebuilt->template_type != ROW_DRIZZLE_DUMMY_TEMPLATE);
4253
offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
4254
row_sel_store_mysql_rec(buf, prebuilt, rec,
4255
offsets, 0, prebuilt->n_index_fields);
4256
res= prebuilt->idx_cond_func(prebuilt->idx_cond_func_arg);
4261
err = DB_RECORD_NOT_FOUND;
4262
goto idx_cond_failed;
4266
4211
/* Get the clustered index record if needed, if we did not do the
4267
4212
search using the clustered index. */
4269
if (get_clust_rec || (index != clust_index &&
4270
prebuilt->need_to_access_clustered)) {
4214
if (index != clust_index && prebuilt->need_to_access_clustered) {
4272
4217
/* We use a 'goto' to the preceding label if a consistent
4273
4218
read of a secondary index record requires us to look up old
4274
4219
versions of the associated clustered index record. */
4247
if ((srv_locks_unsafe_for_binlog
4248
|| trx->isolation_level == TRX_ISO_READ_COMMITTED)
4249
&& prebuilt->select_lock_type != LOCK_NONE) {
4250
/* Note that both the secondary index record
4251
and the clustered index record were locked. */
4252
ut_ad(prebuilt->new_rec_locks == 1);
4253
prebuilt->new_rec_locks = 2;
4302
4256
if (UNIV_UNLIKELY(rec_get_deleted_flag(clust_rec, comp))) {
4304
4258
/* The record is delete marked: we can skip it */
4362
4316
are BLOBs in the fields to be fetched. In HANDLER we do
4363
4317
not cache rows because there the cursor is a scrollable
4365
some_fields_in_buffer= (index != clust_index &&
4366
prebuilt->idx_cond_func);
4368
4320
row_sel_push_cache_row_for_mysql(prebuilt, result_rec,
4370
some_fields_in_buffer?
4371
prebuilt->n_index_fields: 0,
4373
4322
if (prebuilt->n_fetch_cached == MYSQL_FETCH_CACHE_SIZE) {
4437
4382
prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
4439
4384
did_semi_consistent_read = FALSE;
4441
if (UNIV_UNLIKELY(srv_locks_unsafe_for_binlog
4442
|| trx->isolation_level == TRX_ISO_READ_COMMITTED)
4443
&& prebuilt->select_lock_type != LOCK_NONE) {
4445
trx_reset_new_rec_lock_info(trx);
4385
prebuilt->new_rec_locks = 0;
4448
4387
/*-------------------------------------------------------------*/
4449
4388
/* PHASE 5: Move the cursor to the next index record */
4612
/***********************************************************************
4551
/*******************************************************************//**
4613
4552
Checks if MySQL at the moment is allowed for this table to retrieve a
4614
consistent read result, or store it to the query cache. */
4553
consistent read result, or store it to the query cache.
4554
@return TRUE if storing or retrieving from the query cache is permitted */
4617
4557
row_search_check_if_query_cache_permitted(
4618
4558
/*======================================*/
4619
/* out: TRUE if storing or retrieving
4620
from the query cache is permitted */
4621
trx_t* trx, /* in: transaction object */
4622
const char* norm_name) /* in: concatenation of database name,
4559
trx_t* trx, /*!< in: transaction object */
4560
const char* norm_name) /*!< in: concatenation of database name,
4623
4561
'/' char, table name */
4625
4563
dict_table_t* table;
4669
/***********************************************************************
4607
/*******************************************************************//**
4670
4608
Read the AUTOINC column from the current row. If the value is less than
4671
0 and the type is not unsigned then we reset the value to 0. */
4609
0 and the type is not unsigned then we reset the value to 0.
4610
@return value read from the column */
4674
4613
row_search_autoinc_read_column(
4675
4614
/*===========================*/
4676
/* out: value read from the column */
4677
dict_index_t* index, /* in: index to read from */
4678
const rec_t* rec, /* in: current rec */
4679
ulint col_no, /* in: column number */
4680
ibool unsigned_type) /* in: signed or unsigned flag */
4615
dict_index_t* index, /*!< in: index to read from */
4616
const rec_t* rec, /*!< in: current rec */
4617
ulint col_no, /*!< in: column number */
4618
ibool unsigned_type) /*!< in: signed or unsigned flag */
4683
4621
const byte* data;
4712
/***********************************************************************
4713
Get the last row. */
4650
/*******************************************************************//**
4652
@return current rec or NULL */
4716
4655
row_search_autoinc_get_rec(
4717
4656
/*=======================*/
4718
/* out: current rec or NULL */
4719
btr_pcur_t* pcur, /* in: the current cursor */
4720
mtr_t* mtr) /* in: mini transaction */
4657
btr_pcur_t* pcur, /*!< in: the current cursor */
4658
mtr_t* mtr) /*!< in: mini transaction */
4723
4661
const rec_t* rec = btr_pcur_get_rec(pcur);
4733
/***********************************************************************
4734
Read the max AUTOINC value from an index. */
4671
/*******************************************************************//**
4672
Read the max AUTOINC value from an index.
4673
@return DB_SUCCESS if all OK else error code, DB_RECORD_NOT_FOUND if
4674
column name can't be found in index */
4737
4677
row_search_max_autoinc(
4738
4678
/*===================*/
4739
/* out: DB_SUCCESS if all OK else
4740
error code, DB_RECORD_NOT_FOUND if
4741
column name can't be found in index */
4742
dict_index_t* index, /* in: index to search */
4743
const char* col_name, /* in: name of autoinc column */
4744
ib_uint64_t* value) /* out: AUTOINC value read */
4679
dict_index_t* index, /*!< in: index to search */
4680
const char* col_name, /*!< in: name of autoinc column */
4681
ib_uint64_t* value) /*!< out: AUTOINC value read */