~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/row/row0sel.c

  • Committer: Monty Taylor
  • Date: 2008-09-15 17:24:04 UTC
  • Revision ID: monty@inaugust.com-20080915172404-ygh6hiyu0q7qpa9x
Removed strndup calls.

Show diffs side-by-side

added added

removed removed

Lines of Context:
51
51
#define SEL_RETRY       2
52
52
 
53
53
/************************************************************************
54
 
Returns TRUE if the user-defined column in a secondary index record
55
 
is alphabetically the same as the corresponding BLOB column in the clustered
56
 
index record.
57
 
NOTE: the comparison is NOT done as a binary comparison, but character
58
 
fields are compared with collation! */
59
 
static
60
 
ibool
61
 
row_sel_sec_rec_is_for_blob(
62
 
/*========================*/
63
 
                                        /* out: TRUE if the columns
64
 
                                        are equal */
65
 
        ulint           mtype,          /* in: main type */
66
 
        ulint           prtype,         /* in: precise type */
67
 
        ulint           mbminlen,       /* in: minimum length of a
68
 
                                        multi-byte character */
69
 
        ulint           mbmaxlen,       /* in: maximum length of a
70
 
                                        multi-byte character */
71
 
        const byte*     clust_field,    /* in: the locally stored part of
72
 
                                        the clustered index column, including
73
 
                                        the BLOB pointer; the clustered
74
 
                                        index record must be covered by
75
 
                                        a lock or a page latch to protect it
76
 
                                        against deletion (rollback or purge) */
77
 
        ulint           clust_len,      /* in: length of clust_field */
78
 
        const byte*     sec_field,      /* in: column in secondary index */
79
 
        ulint           sec_len,        /* in: length of sec_field */
80
 
        ulint           zip_size)       /* in: compressed page size, or 0 */
81
 
{
82
 
        ulint   len;
83
 
        byte    buf[DICT_MAX_INDEX_COL_LEN];
84
 
 
85
 
        len = btr_copy_externally_stored_field_prefix(buf, sizeof buf,
86
 
                                                      zip_size,
87
 
                                                      clust_field, clust_len);
88
 
        len = dtype_get_at_most_n_mbchars(prtype, mbminlen, mbmaxlen,
89
 
                                          sec_len, len, (const char*) buf);
90
 
 
91
 
        return(!cmp_data_data(mtype, prtype, buf, len, sec_field, sec_len));
92
 
}
93
 
 
94
 
/************************************************************************
95
54
Returns TRUE if the user-defined column values in a secondary index record
96
55
are alphabetically the same as the corresponding columns in the clustered
97
56
index record.
105
64
                                        record is equal to the corresponding
106
65
                                        fields in the clustered record,
107
66
                                        when compared with collation */
108
 
        const rec_t*    sec_rec,        /* in: secondary index record */
 
67
        rec_t*          sec_rec,        /* in: secondary index record */
109
68
        dict_index_t*   sec_index,      /* in: secondary index */
110
 
        const rec_t*    clust_rec,      /* in: clustered index record;
111
 
                                        must be protected by a lock or
112
 
                                        a page latch against deletion
113
 
                                        in rollback or purge */
 
69
        rec_t*          clust_rec,      /* in: clustered index record */
114
70
        dict_index_t*   clust_index)    /* in: clustered index */
115
71
{
116
 
        const byte*     sec_field;
 
72
        byte*           sec_field;
117
73
        ulint           sec_len;
118
 
        const byte*     clust_field;
 
74
        byte*           clust_field;
 
75
        ulint           clust_len;
119
76
        ulint           n;
120
77
        ulint           i;
121
78
        mem_heap_t*     heap            = NULL;
125
82
        ulint*          sec_offs        = sec_offsets_;
126
83
        ibool           is_equal        = TRUE;
127
84
 
128
 
        rec_offs_init(clust_offsets_);
129
 
        rec_offs_init(sec_offsets_);
130
 
 
131
 
        if (rec_get_deleted_flag(clust_rec,
132
 
                                 dict_table_is_comp(clust_index->table))) {
133
 
 
134
 
                /* The clustered index record is delete-marked;
135
 
                it is not visible in the read view.  Besides,
136
 
                if there are any externally stored columns,
137
 
                some of them may have already been purged. */
138
 
                return(FALSE);
139
 
        }
 
85
        *clust_offsets_ = (sizeof clust_offsets_) / sizeof *clust_offsets_;
 
86
        *sec_offsets_ = (sizeof sec_offsets_) / sizeof *sec_offsets_;
140
87
 
141
88
        clust_offs = rec_get_offsets(clust_rec, clust_index, clust_offs,
142
89
                                     ULINT_UNDEFINED, &heap);
148
95
        for (i = 0; i < n; i++) {
149
96
                const dict_field_t*     ifield;
150
97
                const dict_col_t*       col;
151
 
                ulint                   clust_pos;
152
 
                ulint                   clust_len;
153
 
                ulint                   len;
154
98
 
155
99
                ifield = dict_index_get_nth_field(sec_index, i);
156
100
                col = dict_field_get_col(ifield);
157
 
                clust_pos = dict_col_get_clust_pos(col, clust_index);
158
101
 
159
102
                clust_field = rec_get_nth_field(
160
 
                        clust_rec, clust_offs, clust_pos, &clust_len);
 
103
                        clust_rec, clust_offs,
 
104
                        dict_col_get_clust_pos(col, clust_index), &clust_len);
161
105
                sec_field = rec_get_nth_field(sec_rec, sec_offs, i, &sec_len);
162
106
 
163
 
                len = clust_len;
164
 
 
165
 
                if (ifield->prefix_len > 0 && len != UNIV_SQL_NULL) {
166
 
 
167
 
                        if (rec_offs_nth_extern(clust_offs, clust_pos)) {
168
 
                                len -= BTR_EXTERN_FIELD_REF_SIZE;
169
 
                        }
170
 
 
171
 
                        len = dtype_get_at_most_n_mbchars(
 
107
                if (ifield->prefix_len > 0 && clust_len != UNIV_SQL_NULL) {
 
108
 
 
109
                        clust_len = dtype_get_at_most_n_mbchars(
172
110
                                col->prtype, col->mbminlen, col->mbmaxlen,
173
 
                                ifield->prefix_len, len, (char*) clust_field);
174
 
 
175
 
                        if (rec_offs_nth_extern(clust_offs, clust_pos)
176
 
                            && len < sec_len) {
177
 
                                if (!row_sel_sec_rec_is_for_blob(
178
 
                                            col->mtype, col->prtype,
179
 
                                            col->mbminlen, col->mbmaxlen,
180
 
                                            clust_field, clust_len,
181
 
                                            sec_field, sec_len,
182
 
                                            dict_table_zip_size(
183
 
                                                    clust_index->table))) {
184
 
                                        goto inequal;
185
 
                                }
186
 
 
187
 
                                continue;
188
 
                        }
 
111
                                ifield->prefix_len,
 
112
                                clust_len, (char*) clust_field);
189
113
                }
190
114
 
191
115
                if (0 != cmp_data_data(col->mtype, col->prtype,
192
 
                                       clust_field, len,
 
116
                                       clust_field, clust_len,
193
117
                                       sec_field, sec_len)) {
194
 
inequal:
195
118
                        is_equal = FALSE;
196
119
                        goto func_exit;
197
120
                }
206
129
 
207
130
/*************************************************************************
208
131
Creates a select node struct. */
209
 
UNIV_INTERN
 
132
 
210
133
sel_node_t*
211
134
sel_node_create(
212
135
/*============*/
230
153
/*************************************************************************
231
154
Frees the memory private to a select node when a query graph is freed,
232
155
does not free the heap where the node was originally created. */
233
 
UNIV_INTERN
 
156
 
234
157
void
235
158
sel_node_free_private(
236
159
/*==================*/
354
277
row_sel_fetch_columns(
355
278
/*==================*/
356
279
        dict_index_t*   index,  /* in: record index */
357
 
        const rec_t*    rec,    /* in: record in a clustered or non-clustered
358
 
                                index; must be protected by a page latch */
 
280
        rec_t*          rec,    /* in: record in a clustered or non-clustered
 
281
                                index */
359
282
        const ulint*    offsets,/* in: rec_get_offsets(rec, index) */
360
283
        sym_node_t*     column) /* in: first column in a column list, or
361
284
                                NULL */
363
286
        dfield_t*       val;
364
287
        ulint           index_type;
365
288
        ulint           field_no;
366
 
        const byte*     data;
 
289
        byte*           data;
367
290
        ulint           len;
368
291
 
369
292
        ut_ad(rec_offs_validate(rec, index, offsets));
370
293
 
371
 
        if (dict_index_is_clust(index)) {
 
294
        if (index->type & DICT_CLUSTERED) {
372
295
                index_type = SYM_CLUST_FIELD_NO;
373
296
        } else {
374
297
                index_type = SYM_SEC_FIELD_NO;
391
314
                                heap = mem_heap_create(1);
392
315
 
393
316
                                data = btr_rec_copy_externally_stored_field(
394
 
                                        rec, offsets,
395
 
                                        dict_table_zip_size(index->table),
396
 
                                        field_no, &len, heap);
 
317
                                        rec, offsets, field_no, &len, heap);
397
318
 
398
319
                                ut_a(len != UNIV_SQL_NULL);
399
320
 
402
323
                                data = rec_get_nth_field(rec, offsets,
403
324
                                                         field_no, &len);
404
325
 
405
 
                                if (len == UNIV_SQL_NULL) {
406
 
                                        len = UNIV_SQL_NULL;
407
 
                                }
408
 
 
409
326
                                needs_copy = column->copy_val;
410
327
                        }
411
328
 
453
370
/*************************************************************************
454
371
Frees a prefetch buffer for a column, including the dynamically allocated
455
372
memory for data stored there. */
456
 
UNIV_INTERN
 
373
 
457
374
void
458
375
sel_col_prefetch_buf_free(
459
376
/*======================*/
501
418
 
502
419
                        ut_ad(!column->prefetch_buf);
503
420
                        ut_ad(que_node_get_val_buf_size(column) == 0);
504
 
                        ut_d(dfield_set_null(val));
505
 
 
 
421
#ifdef UNIV_DEBUG
 
422
                        dfield_set_data(val, NULL, 0);
 
423
#endif
506
424
                        goto next_col;
507
425
                }
508
426
 
509
427
                ut_ad(column->prefetch_buf);
510
 
                ut_ad(!dfield_is_ext(val));
511
428
 
512
429
                sel_buf = column->prefetch_buf + plan->first_prefetched;
513
430
 
651
568
                                        /* out: DB_SUCCESS or error code */
652
569
        dict_index_t*   clust_index,    /* in: clustered index */
653
570
        row_prebuilt_t* prebuilt,       /* in: prebuilt struct */
654
 
        const rec_t*    rec,            /* in: record in a clustered index */
 
571
        rec_t*          rec,            /* in: record in a clustered index */
655
572
        ulint**         offsets,        /* in/out: offsets returned by
656
573
                                        rec_get_offsets(rec, clust_index) */
657
574
        mem_heap_t**    offset_heap,    /* in/out: memory heap from which
658
575
                                        the offsets are allocated */
659
 
        const rec_t**   old_vers,       /* out: old version, or NULL if the
 
576
        rec_t**         old_vers,       /* out: old version, or NULL if the
660
577
                                        record does not exist in the view:
661
578
                                        i.e., it was freshly inserted
662
579
                                        afterwards */
769
686
        mem_heap_t*     heap            = NULL;
770
687
        ulint           offsets_[REC_OFFS_NORMAL_SIZE];
771
688
        ulint*          offsets         = offsets_;
772
 
        rec_offs_init(offsets_);
 
689
        *offsets_ = (sizeof offsets_) / sizeof *offsets_;
773
690
 
774
691
        *out_rec = NULL;
775
692
 
833
750
                }
834
751
 
835
752
                err = lock_clust_rec_read_check_and_lock(
836
 
                        0, btr_pcur_get_block(&plan->clust_pcur),
837
 
                        clust_rec, index, offsets,
 
753
                        0, clust_rec, index, offsets,
838
754
                        node->row_lock_mode, lock_type, thr);
839
755
 
840
756
                if (err != DB_SUCCESS) {
889
805
                }
890
806
        }
891
807
 
892
 
        /* Fetch the columns needed in test conditions.  The clustered
893
 
        index record is protected by a page latch that was acquired
894
 
        when plan->clust_pcur was positioned.  The latch will not be
895
 
        released until mtr_commit(mtr). */
 
808
        /* Fetch the columns needed in test conditions */
896
809
 
897
810
        row_sel_fetch_columns(index, clust_rec, offsets,
898
811
                              UT_LIST_GET_FIRST(plan->columns));
912
825
ulint
913
826
sel_set_rec_lock(
914
827
/*=============*/
915
 
                                        /* out: DB_SUCCESS or error code */
916
 
        const buf_block_t*      block,  /* in: buffer block of rec */
917
 
        const rec_t*            rec,    /* in: record */
918
 
        dict_index_t*           index,  /* in: index */
919
 
        const ulint*            offsets,/* in: rec_get_offsets(rec, index) */
920
 
        ulint                   mode,   /* in: lock mode */
921
 
        ulint                   type,   /* in: LOCK_ORDINARY, LOCK_GAP, or
922
 
                                        LOC_REC_NOT_GAP */
923
 
        que_thr_t*              thr)    /* in: query thread */
 
828
                                /* out: DB_SUCCESS or error code */
 
829
        rec_t*          rec,    /* in: record */
 
830
        dict_index_t*   index,  /* in: index */
 
831
        const ulint*    offsets,/* in: rec_get_offsets(rec, index) */
 
832
        ulint           mode,   /* in: lock mode */
 
833
        ulint           type,   /* in: LOCK_ORDINARY, LOCK_GAP, or
 
834
                                LOC_REC_NOT_GAP */
 
835
        que_thr_t*      thr)    /* in: query thread */
924
836
{
925
837
        trx_t*  trx;
926
838
        ulint   err;
934
846
                }
935
847
        }
936
848
 
937
 
        if (dict_index_is_clust(index)) {
 
849
        if (index->type & DICT_CLUSTERED) {
938
850
                err = lock_clust_rec_read_check_and_lock(
939
 
                        0, block, rec, index, offsets, mode, type, thr);
 
851
                        0, rec, index, offsets, mode, type, thr);
940
852
        } else {
941
853
                err = lock_sec_rec_read_check_and_lock(
942
 
                        0, block, rec, index, offsets, mode, type, thr);
 
854
                        0, rec, index, offsets, mode, type, thr);
943
855
        }
944
856
 
945
857
        return(err);
1151
1063
        ulint           offsets_[REC_OFFS_NORMAL_SIZE];
1152
1064
        ulint*          offsets         = offsets_;
1153
1065
        ulint           ret;
1154
 
        rec_offs_init(offsets_);
 
1066
        *offsets_ = (sizeof offsets_) / sizeof *offsets_;
1155
1067
 
1156
1068
        index = plan->index;
1157
1069
 
1187
1099
 
1188
1100
        offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
1189
1101
 
1190
 
        if (dict_index_is_clust(index)) {
 
1102
        if (index->type & DICT_CLUSTERED) {
1191
1103
                if (!lock_clust_rec_cons_read_sees(rec, index, offsets,
1192
1104
                                                   node->read_view)) {
1193
1105
                        ret = SEL_RETRY;
1194
1106
                        goto func_exit;
1195
1107
                }
1196
 
        } else if (!lock_sec_rec_cons_read_sees(rec, node->read_view)) {
 
1108
        } else if (!lock_sec_rec_cons_read_sees(rec, index, node->read_view)) {
1197
1109
 
1198
1110
                ret = SEL_RETRY;
1199
1111
                goto func_exit;
1200
1112
        }
1201
1113
 
1202
 
        /* Test the deleted flag. */
 
1114
        /* Test deleted flag. Fetch the columns needed in test conditions. */
 
1115
 
 
1116
        row_sel_fetch_columns(index, rec, offsets,
 
1117
                              UT_LIST_GET_FIRST(plan->columns));
1203
1118
 
1204
1119
        if (rec_get_deleted_flag(rec, dict_table_is_comp(plan->table))) {
1205
1120
 
1207
1122
                goto func_exit;
1208
1123
        }
1209
1124
 
1210
 
        /* Fetch the columns needed in test conditions.  The index
1211
 
        record is protected by a page latch that was acquired when
1212
 
        plan->pcur was positioned.  The latch will not be released
1213
 
        until mtr_commit(mtr). */
1214
 
 
1215
 
        row_sel_fetch_columns(index, rec, offsets,
1216
 
                              UT_LIST_GET_FIRST(plan->columns));
1217
 
 
1218
1125
        /* Test the rest of search conditions */
1219
1126
 
1220
1127
        if (!row_sel_test_other_conds(plan)) {
1282
1189
        mem_heap_t*     heap                            = NULL;
1283
1190
        ulint           offsets_[REC_OFFS_NORMAL_SIZE];
1284
1191
        ulint*          offsets                         = offsets_;
1285
 
        rec_offs_init(offsets_);
 
1192
        *offsets_ = (sizeof offsets_) / sizeof *offsets_;
1286
1193
 
1287
1194
        ut_ad(thr->run_node == node);
1288
1195
 
1462
1369
                                lock_type = LOCK_ORDINARY;
1463
1370
                        }
1464
1371
 
1465
 
                        err = sel_set_rec_lock(btr_pcur_get_block(&plan->pcur),
1466
 
                                               next_rec, index, offsets,
 
1372
                        err = sel_set_rec_lock(next_rec, index, offsets,
1467
1373
                                               node->row_lock_mode,
1468
1374
                                               lock_type, thr);
1469
1375
 
1519
1425
                        lock_type = LOCK_ORDINARY;
1520
1426
                }
1521
1427
 
1522
 
                err = sel_set_rec_lock(btr_pcur_get_block(&plan->pcur),
1523
 
                                       rec, index, offsets,
 
1428
                err = sel_set_rec_lock(rec, index, offsets,
1524
1429
                                       node->row_lock_mode, lock_type, thr);
1525
1430
 
1526
1431
                if (err != DB_SUCCESS) {
1583
1488
                /* This is a non-locking consistent read: if necessary, fetch
1584
1489
                a previous version of the record */
1585
1490
 
1586
 
                if (dict_index_is_clust(index)) {
 
1491
                if (index->type & DICT_CLUSTERED) {
1587
1492
 
1588
1493
                        if (!lock_clust_rec_cons_read_sees(rec, index, offsets,
1589
1494
                                                           node->read_view)) {
1602
1507
                                        offsets = rec_get_offsets(
1603
1508
                                                rec, index, offsets,
1604
1509
                                                ULINT_UNDEFINED, &heap);
1605
 
 
1606
 
                                        /* Fetch the columns needed in
1607
 
                                        test conditions. The clustered
1608
 
                                        index record is protected by a
1609
 
                                        page latch that was acquired
1610
 
                                        by row_sel_open_pcur() or
1611
 
                                        row_sel_restore_pcur_pos().
1612
 
                                        The latch will not be released
1613
 
                                        until mtr_commit(mtr). */
1614
 
 
1615
1510
                                        row_sel_fetch_columns(
1616
1511
                                                index, rec, offsets,
1617
1512
                                                UT_LIST_GET_FIRST(
1627
1522
 
1628
1523
                                rec = old_vers;
1629
1524
                        }
1630
 
                } else if (!lock_sec_rec_cons_read_sees(rec,
 
1525
                } else if (!lock_sec_rec_cons_read_sees(rec, index,
1631
1526
                                                        node->read_view)) {
1632
1527
                        cons_read_requires_clust_rec = TRUE;
1633
1528
                }
1635
1530
 
1636
1531
        /* PHASE 4: Test search end conditions and deleted flag */
1637
1532
 
1638
 
        /* Fetch the columns needed in test conditions.  The record is
1639
 
        protected by a page latch that was acquired by
1640
 
        row_sel_open_pcur() or row_sel_restore_pcur_pos().  The latch
1641
 
        will not be released until mtr_commit(mtr). */
 
1533
        /* Fetch the columns needed in test conditions */
1642
1534
 
1643
1535
        row_sel_fetch_columns(index, rec, offsets,
1644
1536
                              UT_LIST_GET_FIRST(plan->columns));
1671
1563
                goto next_rec;
1672
1564
        }
1673
1565
 
1674
 
 
1675
1566
        /* PHASE 5: Get the clustered index record, if needed and if we did
1676
1567
        not do the search using the clustered index */
1677
1568
 
1790
1681
        }
1791
1682
 
1792
1683
        if (leaf_contains_updates
1793
 
            && btr_pcur_is_after_last_on_page(&plan->pcur)) {
 
1684
            && btr_pcur_is_after_last_on_page(&(plan->pcur), &mtr)) {
1794
1685
 
1795
1686
                /* We must commit &mtr if we are moving to a different page,
1796
1687
                because we have done updates to the x-latched leaf page, and
1823
1714
        /* We found a record which satisfies the conditions: we can move to
1824
1715
        the next table or return a row in the result set */
1825
1716
 
1826
 
        ut_ad(btr_pcur_is_on_user_rec(&plan->pcur));
 
1717
        ut_ad(btr_pcur_is_on_user_rec(&(plan->pcur), &mtr));
1827
1718
 
1828
1719
        if (plan->unique_search && !node->can_get_updated) {
1829
1720
 
1858
1749
 
1859
1750
                thr->run_node = que_node_get_parent(node);
1860
1751
 
 
1752
                if (search_latch_locked) {
 
1753
                        rw_lock_s_unlock(&btr_search_latch);
 
1754
                }
 
1755
 
1861
1756
                err = DB_SUCCESS;
1862
1757
                goto func_exit;
1863
1758
        }
1901
1796
                        sel_assign_into_var_values(node->into_list, node);
1902
1797
 
1903
1798
                        thr->run_node = que_node_get_parent(node);
1904
 
                } else {
1905
 
                        node->state = SEL_NODE_NO_MORE_ROWS;
1906
 
 
1907
 
                        thr->run_node = que_node_get_parent(node);
 
1799
 
 
1800
                        if (search_latch_locked) {
 
1801
                                rw_lock_s_unlock(&btr_search_latch);
 
1802
                        }
 
1803
 
 
1804
                        goto func_exit;
 
1805
                }
 
1806
 
 
1807
                node->state = SEL_NODE_NO_MORE_ROWS;
 
1808
 
 
1809
                thr->run_node = que_node_get_parent(node);
 
1810
 
 
1811
                if (search_latch_locked) {
 
1812
                        rw_lock_s_unlock(&btr_search_latch);
1908
1813
                }
1909
1814
 
1910
1815
                goto func_exit;
1960
1865
lock_wait_or_error:
1961
1866
        /* See the note at stop_for_a_while: the same holds for this case */
1962
1867
 
1963
 
        ut_ad(!btr_pcur_is_before_first_on_page(&plan->pcur) || !node->asc);
 
1868
        ut_ad(!btr_pcur_is_before_first_on_page(&(plan->pcur), &mtr)
 
1869
              || !node->asc);
1964
1870
        ut_ad(!search_latch_locked);
1965
1871
 
1966
1872
        plan->stored_cursor_rec_processed = FALSE;
1973
1879
#endif /* UNIV_SYNC_DEBUG */
1974
1880
 
1975
1881
func_exit:
1976
 
        if (search_latch_locked) {
1977
 
                rw_lock_s_unlock(&btr_search_latch);
1978
 
        }
1979
1882
        if (UNIV_LIKELY_NULL(heap)) {
1980
1883
                mem_heap_free(heap);
1981
1884
        }
1985
1888
/**************************************************************************
1986
1889
Performs a select step. This is a high-level function used in SQL execution
1987
1890
graphs. */
1988
 
UNIV_INTERN
 
1891
 
1989
1892
que_thr_t*
1990
1893
row_sel_step(
1991
1894
/*=========*/
2086
1989
 
2087
1990
/**************************************************************************
2088
1991
Performs a fetch for a cursor. */
2089
 
UNIV_INTERN
 
1992
 
2090
1993
que_thr_t*
2091
1994
fetch_step(
2092
1995
/*=======*/
2149
2052
 
2150
2053
/********************************************************************
2151
2054
Sample callback function for fetch that prints each row.*/
2152
 
UNIV_INTERN
 
2055
 
2153
2056
void*
2154
2057
row_fetch_print(
2155
2058
/*============*/
2169
2072
 
2170
2073
        while (exp) {
2171
2074
                dfield_t*       dfield = que_node_get_val(exp);
2172
 
                const dtype_t*  type = dfield_get_type(dfield);
 
2075
                dtype_t*        type = dfield_get_type(dfield);
2173
2076
 
2174
2077
                fprintf(stderr, " column %lu:\n", (ulong)i);
2175
2078
 
2196
2099
Callback function for fetch that stores an unsigned 4 byte integer to the
2197
2100
location pointed. The column's type must be DATA_INT, DATA_UNSIGNED, length
2198
2101
= 4. */
2199
 
UNIV_INTERN
 
2102
 
2200
2103
void*
2201
2104
row_fetch_store_uint4(
2202
2105
/*==================*/
2209
2112
        ulint           tmp;
2210
2113
 
2211
2114
        dfield_t*       dfield = que_node_get_val(node->select_list);
2212
 
        const dtype_t*  type = dfield_get_type(dfield);
 
2115
        dtype_t*        type = dfield_get_type(dfield);
2213
2116
        ulint           len = dfield_get_len(dfield);
2214
2117
 
2215
2118
        ut_a(dtype_get_mtype(type) == DATA_INT);
2224
2127
 
2225
2128
/***************************************************************
2226
2129
Prints a row in a select result. */
2227
 
UNIV_INTERN
 
2130
 
2228
2131
que_thr_t*
2229
2132
row_printf_step(
2230
2133
/*============*/
2292
2195
last field is only a prefix of the full key field len and print a warning if
2293
2196
such appears. A counterpart of this function is
2294
2197
ha_innobase::store_key_val_for_row() in ha_innodb.cc. */
2295
 
UNIV_INTERN
 
2198
 
2296
2199
void
2297
2200
row_sel_convert_mysql_key_to_innobase(
2298
2201
/*==================================*/
2299
 
        dtuple_t*       tuple,          /* in/out: tuple where to build;
 
2202
        dtuple_t*       tuple,          /* in: tuple where to build;
2300
2203
                                        NOTE: we assume that the type info
2301
2204
                                        in the tuple is already according
2302
2205
                                        to index! */
2304
2207
                                        conversions */
2305
2208
        ulint           buf_len,        /* in: buffer length */
2306
2209
        dict_index_t*   index,          /* in: index of the key value */
2307
 
        const byte*     key_ptr,        /* in: MySQL key value */
 
2210
        byte*           key_ptr,        /* in: MySQL key value */
2308
2211
        ulint           key_len,        /* in: MySQL key value length */
2309
2212
        trx_t*          trx)            /* in: transaction */
2310
2213
{
2311
2214
        byte*           original_buf    = buf;
2312
 
        const byte*     original_key_ptr = key_ptr;
 
2215
        byte*           original_key_ptr = key_ptr;
2313
2216
        dict_field_t*   field;
2314
2217
        dfield_t*       dfield;
2315
2218
        ulint           data_offset;
2316
2219
        ulint           data_len;
2317
2220
        ulint           data_field_len;
2318
2221
        ibool           is_null;
2319
 
        const byte*     key_end;
 
2222
        byte*           key_end;
2320
2223
        ulint           n_fields = 0;
 
2224
        ulint           type;
2321
2225
 
2322
2226
        /* For documentation of the key value storage format in MySQL, see
2323
2227
        ha_innobase::store_key_val_for_row() in ha_innodb.cc. */
2331
2235
        dfield = dtuple_get_nth_field(tuple, 0);
2332
2236
        field = dict_index_get_nth_field(index, 0);
2333
2237
 
2334
 
        if (UNIV_UNLIKELY(dfield_get_type(dfield)->mtype == DATA_SYS)) {
 
2238
        if (dfield_get_type(dfield)->mtype == DATA_SYS) {
2335
2239
                /* A special case: we are looking for a position in the
2336
2240
                generated clustered index which InnoDB automatically added
2337
2241
                to a table with no primary key: the first and the only
2349
2253
 
2350
2254
        while (key_ptr < key_end) {
2351
2255
 
2352
 
                ulint   type = dfield_get_type(dfield)->mtype;
2353
 
                ut_a(field->col->mtype == type);
 
2256
                ut_a(field->col->mtype == dfield_get_type(dfield)->mtype);
2354
2257
 
2355
2258
                data_offset = 0;
2356
2259
                is_null = FALSE;
2362
2265
                        data_offset = 1;
2363
2266
 
2364
2267
                        if (*key_ptr != 0) {
2365
 
                                dfield_set_null(dfield);
 
2268
                                dfield_set_data(dfield, NULL, UNIV_SQL_NULL);
2366
2269
 
2367
2270
                                is_null = TRUE;
2368
2271
                        }
2369
2272
                }
2370
2273
 
 
2274
                type = dfield_get_type(dfield)->mtype;
 
2275
 
2371
2276
                /* Calculate data length and data field total length */
2372
2277
 
2373
2278
                if (type == DATA_BLOB) {
2413
2318
                        data_field_len = data_offset + data_len;
2414
2319
                }
2415
2320
 
2416
 
                if (UNIV_UNLIKELY
2417
 
                    (dtype_get_mysql_type(dfield_get_type(dfield))
2418
 
                     == DATA_MYSQL_TRUE_VARCHAR)
2419
 
                    && UNIV_LIKELY(type != DATA_INT)) {
 
2321
                if (dtype_get_mysql_type(dfield_get_type(dfield))
 
2322
                    == DATA_DRIZZLE_TRUE_VARCHAR
 
2323
                    && dfield_get_type(dfield)->mtype != DATA_INT) {
2420
2324
                        /* In a MySQL key value format, a true VARCHAR is
2421
2325
                        always preceded by 2 bytes of a length field.
2422
2326
                        dfield_get_type(dfield)->len returns the maximum
2432
2336
 
2433
2337
                /* Storing may use at most data_len bytes of buf */
2434
2338
 
2435
 
                if (UNIV_LIKELY(!is_null)) {
 
2339
                if (!is_null) {
2436
2340
                        row_mysql_store_col_in_innobase_format(
2437
2341
                                dfield, buf,
2438
2342
                                FALSE, /* MySQL key value format col */
2443
2347
 
2444
2348
                key_ptr += data_field_len;
2445
2349
 
2446
 
                if (UNIV_UNLIKELY(key_ptr > key_end)) {
 
2350
                if (key_ptr > key_end) {
2447
2351
                        /* The last field in key was not a complete key field
2448
2352
                        but a prefix of it.
2449
2353
 
2470
2374
                        fprintf(stderr, "\n");
2471
2375
 
2472
2376
                        if (!is_null) {
2473
 
                                ulint   len = dfield_get_len(dfield);
2474
 
                                dfield_set_len(dfield, len
2475
 
                                               - (ulint) (key_ptr - key_end));
 
2377
                                dfield->len -= (ulint)(key_ptr - key_end);
2476
2378
                        }
2477
2379
                }
2478
2380
 
2495
2397
void
2496
2398
row_sel_store_row_id_to_prebuilt(
2497
2399
/*=============================*/
2498
 
        row_prebuilt_t*         prebuilt,       /* in/out: prebuilt */
2499
 
        const rec_t*            index_rec,      /* in: record */
2500
 
        const dict_index_t*     index,          /* in: index of the record */
2501
 
        const ulint*            offsets)        /* in: rec_get_offsets
2502
 
                                                (index_rec, index) */
 
2400
        row_prebuilt_t* prebuilt,       /* in: prebuilt */
 
2401
        rec_t*          index_rec,      /* in: record */
 
2402
        dict_index_t*   index,          /* in: index of the record */
 
2403
        const ulint*    offsets)        /* in: rec_get_offsets
 
2404
                                        (index_rec, index) */
2503
2405
{
2504
 
        const byte*     data;
2505
 
        ulint           len;
 
2406
        byte*   data;
 
2407
        ulint   len;
2506
2408
 
2507
2409
        ut_ad(rec_offs_validate(index_rec, index, offsets));
2508
2410
 
2510
2412
                index_rec, offsets,
2511
2413
                dict_index_get_sys_col_pos(index, DATA_ROW_ID), &len);
2512
2414
 
2513
 
        if (UNIV_UNLIKELY(len != DATA_ROW_ID_LEN)) {
 
2415
        if (len != DATA_ROW_ID_LEN) {
2514
2416
                fprintf(stderr,
2515
2417
                        "InnoDB: Error: Row id field is"
2516
2418
                        " wrong length %lu in ", (ulong) len);
2534
2436
void
2535
2437
row_sel_field_store_in_mysql_format(
2536
2438
/*================================*/
2537
 
        byte*           dest,   /* in/out: buffer where to store; NOTE
2538
 
                                that BLOBs are not in themselves
2539
 
                                stored here: the caller must allocate
2540
 
                                and copy the BLOB into buffer before,
2541
 
                                and pass the pointer to the BLOB in
2542
 
                                'data' */
2543
 
        const mysql_row_templ_t* templ,
2544
 
                                /* in: MySQL column template.
2545
 
                                Its following fields are referenced:
2546
 
                                type, is_unsigned, mysql_col_len,
2547
 
                                mbminlen, mbmaxlen */
2548
 
        const byte*     data,   /* in: data to store */
2549
 
        ulint           len)    /* in: length of the data */
 
2439
        byte*   dest,   /* in/out: buffer where to store; NOTE that BLOBs
 
2440
                        are not in themselves stored here: the caller must
 
2441
                        allocate and copy the BLOB into buffer before, and pass
 
2442
                        the pointer to the BLOB in 'data' */
 
2443
        const mysql_row_templ_t* templ, /* in: MySQL column template.
 
2444
                        Its following fields are referenced:
 
2445
                        type, is_unsigned, mysql_col_len, mbminlen, mbmaxlen */
 
2446
        byte*   data,   /* in: data to store */
 
2447
        ulint   len)    /* in: length of the data */
2550
2448
{
2551
2449
        byte*   ptr;
2552
2450
        byte*   field_end;
2554
2452
 
2555
2453
        ut_ad(len != UNIV_SQL_NULL);
2556
2454
 
2557
 
        switch (templ->type) {
2558
 
        case DATA_INT:
 
2455
        if (templ->type == DATA_INT) {
2559
2456
                /* Convert integer data from Innobase to a little-endian
2560
2457
                format, sign bit restored to normal */
2561
2458
 
2575
2472
                }
2576
2473
 
2577
2474
                ut_ad(templ->mysql_col_len == len);
2578
 
                break;
 
2475
        } else if (templ->type == DATA_VARCHAR
 
2476
                   || templ->type == DATA_VARMYSQL
 
2477
                   || templ->type == DATA_BINARY) {
2579
2478
 
2580
 
        case DATA_VARCHAR:
2581
 
        case DATA_VARMYSQL:
2582
 
        case DATA_BINARY:
2583
2479
                field_end = dest + templ->mysql_col_len;
2584
2480
 
2585
 
                if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
 
2481
                if (templ->mysql_type == DATA_DRIZZLE_TRUE_VARCHAR) {
2586
2482
                        /* This is a >= 5.0.3 type true VARCHAR. Store the
2587
2483
                        length of the data to the first byte or the first
2588
2484
                        two bytes of dest. */
2630
2526
 
2631
2527
                        memset(pad_ptr, 0x20, field_end - pad_ptr);
2632
2528
                }
2633
 
                break;
2634
 
 
2635
 
        case DATA_BLOB:
 
2529
        } else if (templ->type == DATA_BLOB) {
2636
2530
                /* Store a pointer to the BLOB buffer to dest: the BLOB was
2637
2531
                already copied to the buffer in row_sel_store_mysql_rec */
2638
2532
 
2639
2533
                row_mysql_store_blob_ref(dest, templ->mysql_col_len, data,
2640
2534
                                         len);
2641
 
                break;
2642
 
 
2643
 
        case DATA_MYSQL:
 
2535
        } else if (templ->type == DATA_MYSQL) {
2644
2536
                memcpy(dest, data, len);
2645
2537
 
2646
2538
                ut_ad(templ->mysql_col_len >= len);
2661
2553
 
2662
2554
                        memset(dest + len, 0x20, templ->mysql_col_len - len);
2663
2555
                }
2664
 
                break;
2665
 
 
2666
 
        default:
2667
 
#ifdef UNIV_DEBUG
2668
 
        case DATA_SYS_CHILD:
2669
 
        case DATA_SYS:
2670
 
                /* These column types should never be shipped to MySQL. */
2671
 
                ut_ad(0);
2672
 
 
2673
 
        case DATA_CHAR:
2674
 
        case DATA_FIXBINARY:
2675
 
        case DATA_FLOAT:
2676
 
        case DATA_DOUBLE:
2677
 
        case DATA_DECIMAL:
2678
 
                /* Above are the valid column types for MySQL data. */
2679
 
#endif /* UNIV_DEBUG */
 
2556
        } else {
 
2557
                ut_ad(templ->type == DATA_CHAR
 
2558
                      || templ->type == DATA_FIXBINARY
 
2559
                      /*|| templ->type == DATA_SYS_CHILD
 
2560
                      || templ->type == DATA_SYS*/
 
2561
                      || templ->type == DATA_FLOAT
 
2562
                      || templ->type == DATA_DOUBLE
 
2563
                      || templ->type == DATA_DECIMAL);
2680
2564
                ut_ad(templ->mysql_col_len == len);
 
2565
 
2681
2566
                memcpy(dest, data, len);
2682
2567
        }
2683
2568
}
2697
2582
                                        case) */
2698
2583
        byte*           mysql_rec,      /* out: row in the MySQL format */
2699
2584
        row_prebuilt_t* prebuilt,       /* in: prebuilt struct */
2700
 
        const rec_t*    rec,            /* in: Innobase record in the index
 
2585
        rec_t*          rec,            /* in: Innobase record in the index
2701
2586
                                        which was described in prebuilt's
2702
 
                                        template; must be protected by
2703
 
                                        a page latch */
2704
 
        const ulint*    offsets,        /* in: array returned by
 
2587
                                        template */
 
2588
        const ulint*    offsets,        /* in: array returned by
2705
2589
                                        rec_get_offsets() */
2706
 
        ulint start_field_no,
2707
 
        ulint end_field_no)
 
2590
        ulint start_field_no,
 
2591
        ulint end_field_no)
2708
2592
{
2709
2593
        mysql_row_templ_t*      templ;
2710
2594
        mem_heap_t*             extern_field_heap       = NULL;
2711
2595
        mem_heap_t*             heap;
2712
 
        const byte*             data;
 
2596
        byte*                   data;
2713
2597
        ulint                   len;
2714
2598
        ulint                   i;
2715
2599
 
2721
2605
                prebuilt->blob_heap = NULL;
2722
2606
        }
2723
2607
 
2724
 
        for (i = start_field_no; i < end_field_no /* prebuilt->n_template */; i++) {
 
2608
        for (i = start_field_no; i < end_field_no /* prebuilt->n_template */ ; i++) {
2725
2609
 
2726
2610
                templ = prebuilt->mysql_template + i;
2727
2611
 
2752
2636
                        causes an assert */
2753
2637
 
2754
2638
                        data = btr_rec_copy_externally_stored_field(
2755
 
                                rec, offsets,
2756
 
                                dict_table_zip_size(prebuilt->table),
2757
 
                                templ->rec_field_no, &len, heap);
 
2639
                                rec, offsets, templ->rec_field_no,
 
2640
                                &len, heap);
2758
2641
 
2759
2642
                        ut_a(len != UNIV_SQL_NULL);
2760
2643
                } else {
2815
2698
                        case DATA_BINARY:
2816
2699
                        case DATA_VARMYSQL:
2817
2700
                                if (templ->mysql_type
2818
 
                                    == DATA_MYSQL_TRUE_VARCHAR) {
 
2701
                                    == DATA_DRIZZLE_TRUE_VARCHAR) {
2819
2702
                                        /* This is a >= 5.0.3 type
2820
2703
                                        true VARCHAR.  Zero the field. */
2821
2704
                                        pad_char = 0x00;
2829
2712
                                BLOB, TEXT and true VARCHAR) with space. */
2830
2713
                                if (UNIV_UNLIKELY(templ->mbminlen == 2)) {
2831
2714
                                        /* Treat UCS2 as a special case. */
2832
 
                                        byte* d = mysql_rec
 
2715
                                        data = mysql_rec
2833
2716
                                                + templ->mysql_col_offset;
2834
2717
                                        len = templ->mysql_col_len;
2835
2718
                                        /* There are two UCS2 bytes per char,
2837
2720
                                        ut_a(!(len & 1));
2838
2721
                                        /* Pad with 0x0020. */
2839
2722
                                        while (len) {
2840
 
                                                *d++ = 0x00;
2841
 
                                                *d++ = 0x20;
 
2723
                                                *data++ = 0x00;
 
2724
                                                *data++ = 0x20;
2842
2725
                                                len -= 2;
2843
2726
                                        }
2844
2727
                                        continue;
2869
2752
        read_view_t*    read_view,      /* in: read view */
2870
2753
        dict_index_t*   clust_index,    /* in: clustered index */
2871
2754
        row_prebuilt_t* prebuilt,       /* in: prebuilt struct */
2872
 
        const rec_t*    rec,            /* in: record in a clustered index */
 
2755
        rec_t*          rec,            /* in: record in a clustered index */
2873
2756
        ulint**         offsets,        /* in/out: offsets returned by
2874
2757
                                        rec_get_offsets(rec, clust_index) */
2875
2758
        mem_heap_t**    offset_heap,    /* in/out: memory heap from which
2905
2788
                                /* out: DB_SUCCESS or error code */
2906
2789
        row_prebuilt_t* prebuilt,/* in: prebuilt struct in the handle */
2907
2790
        dict_index_t*   sec_index,/* in: secondary index where rec resides */
2908
 
        const rec_t*    rec,    /* in: record in a non-clustered index; if
 
2791
        rec_t*          rec,    /* in: record in a non-clustered index; if
2909
2792
                                this is a locking read, then rec is not
2910
2793
                                allowed to be delete-marked, and that would
2911
2794
                                not make sense either */
2912
2795
        que_thr_t*      thr,    /* in: query thread */
2913
 
        const rec_t**   out_rec,/* out: clustered record or an old version of
 
2796
        rec_t**         out_rec,/* out: clustered record or an old version of
2914
2797
                                it, NULL if the old version did not exist
2915
2798
                                in the read view, i.e., it was a fresh
2916
2799
                                inserted version */
2917
 
        ulint**         offsets,/* in: offsets returned by
2918
 
                                rec_get_offsets(rec, sec_index);
2919
 
                                out: offsets returned by
 
2800
        ulint**         offsets,/* out: offsets returned by
2920
2801
                                rec_get_offsets(out_rec, clust_index) */
2921
2802
        mem_heap_t**    offset_heap,/* in/out: memory heap from which
2922
2803
                                the offsets are allocated */
2925
2806
                                access the clustered index */
2926
2807
{
2927
2808
        dict_index_t*   clust_index;
2928
 
        const rec_t*    clust_rec;
 
2809
        rec_t*          clust_rec;
2929
2810
        rec_t*          old_vers;
2930
2811
        ulint           err;
2931
2812
        trx_t*          trx;
2933
2814
        *out_rec = NULL;
2934
2815
        trx = thr_get_trx(thr);
2935
2816
 
2936
 
        row_build_row_ref_in_tuple(prebuilt->clust_ref, rec,
2937
 
                                   sec_index, *offsets, trx);
 
2817
        row_build_row_ref_in_tuple(prebuilt->clust_ref, sec_index, rec, trx);
2938
2818
 
2939
2819
        clust_index = dict_table_get_first_index(sec_index->table);
2940
2820
 
2998
2878
                we set a LOCK_REC_NOT_GAP type lock */
2999
2879
 
3000
2880
                err = lock_clust_rec_read_check_and_lock(
3001
 
                        0, btr_pcur_get_block(prebuilt->clust_pcur),
3002
 
                        clust_rec, clust_index, *offsets,
 
2881
                        0, clust_rec, clust_index, *offsets,
3003
2882
                        prebuilt->select_lock_type, LOCK_REC_NOT_GAP, thr);
3004
2883
                if (err != DB_SUCCESS) {
3005
2884
 
3026
2905
                                clust_rec, offsets, offset_heap, &old_vers,
3027
2906
                                mtr);
3028
2907
 
3029
 
                        if (err != DB_SUCCESS || old_vers == NULL) {
 
2908
                        if (err != DB_SUCCESS) {
3030
2909
 
3031
2910
                                goto err_exit;
3032
2911
                        }
3047
2926
                visit through secondary index records that would not really
3048
2927
                exist in our snapshot. */
3049
2928
 
3050
 
                if (clust_rec
3051
 
                    && (old_vers
3052
 
                        || rec_get_deleted_flag(rec, dict_table_is_comp(
3053
 
                                                        sec_index->table)))
 
2929
                if (clust_rec && (old_vers || rec_get_deleted_flag(
 
2930
                                          rec,
 
2931
                                          dict_table_is_comp(
 
2932
                                                  sec_index->table)))
3054
2933
                    && !row_sel_sec_rec_is_for_clust_rec(
3055
2934
                            rec, sec_index, clust_rec, clust_index)) {
3056
2935
                        clust_rec = NULL;
 
2936
                } else {
3057
2937
#ifdef UNIV_SEARCH_DEBUG
3058
 
                } else {
3059
2938
                        ut_a(clust_rec == NULL
3060
2939
                             || row_sel_sec_rec_is_for_clust_rec(
3061
2940
                                     rec, sec_index, clust_rec, clust_index));
3130
3009
                        return(TRUE);
3131
3010
                }
3132
3011
 
3133
 
                if (btr_pcur_is_on_user_rec(pcur)) {
 
3012
                if (btr_pcur_is_on_user_rec(pcur, mtr)) {
3134
3013
                        btr_pcur_move_to_prev(pcur, mtr);
3135
3014
                }
3136
3015
 
3140
3019
        ut_ad(relative_position == BTR_PCUR_BEFORE
3141
3020
              || relative_position == BTR_PCUR_BEFORE_FIRST_IN_TREE);
3142
3021
 
3143
 
        if (moves_up && btr_pcur_is_on_user_rec(pcur)) {
 
3022
        if (moves_up && btr_pcur_is_on_user_rec(pcur, mtr)) {
3144
3023
                btr_pcur_move_to_next(pcur, mtr);
3145
3024
        }
3146
3025
 
3204
3083
row_sel_push_cache_row_for_mysql(
3205
3084
/*=============================*/
3206
3085
        row_prebuilt_t* prebuilt,       /* in: prebuilt struct */
3207
 
        const rec_t*    rec,            /* in: record to push; must
3208
 
                                        be protected by a page latch */
 
3086
        rec_t*          rec,            /* in: record to push */
3209
3087
        const ulint*    offsets,        /* in: rec_get_offsets() */
3210
 
        ulint           start_field_no, /* psergy: start from this field */
3211
 
        byte*           remainder_buf)  /* if above !=0 -> where to take
3212
 
                                           prev fields */
 
3088
        ulint           start_field_no, /* psergey: start from this field */
 
3089
        byte*           remainder_buf)  /* if above !=0 -> where to take prev fields */
3213
3090
{
3214
3091
        byte*   buf;
3215
3092
        ulint   i;
3216
3093
 
3217
 
        ut_ad(prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE);
 
3094
        ut_ad(prebuilt->n_fetch_cached < DRIZZLE_FETCH_CACHE_SIZE);
3218
3095
        ut_ad(rec_offs_validate(rec, NULL, offsets));
3219
3096
        ut_a(!prebuilt->templ_contains_blob);
3220
3097
 
3221
3098
        if (prebuilt->fetch_cache[0] == NULL) {
3222
3099
                /* Allocate memory for the fetch cache */
3223
3100
 
3224
 
                for (i = 0; i < MYSQL_FETCH_CACHE_SIZE; i++) {
 
3101
                for (i = 0; i < DRIZZLE_FETCH_CACHE_SIZE; i++) {
3225
3102
 
3226
3103
                        /* A user has reported memory corruption in these
3227
3104
                        buffers in Linux. Put magic numbers there to help
3243
3120
                                  prebuilt->fetch_cache[
3244
3121
                                          prebuilt->n_fetch_cached],
3245
3122
                                  prebuilt, rec, offsets, start_field_no,
3246
 
                                  prebuilt->n_template))) {
 
3123
                                  prebuilt->n_template))) {
3247
3124
                ut_error;
3248
3125
        }
3249
 
 
3250
3126
        if (start_field_no) {
3251
3127
          for (i=0; i < start_field_no; i++) {
3252
3128
            register ulint offs;
3253
 
            mysql_row_templ_t* templ;
 
3129
            mysql_row_templ_t* templ;
3254
3130
            templ = prebuilt->mysql_template + i;
3255
3131
 
3256
3132
            if (templ->mysql_null_bit_mask) {
3257
3133
              offs= templ->mysql_null_byte_offset;
3258
 
              if (*(remainder_buf + offs) & templ->mysql_null_bit_mask)
3259
 
                 *(prebuilt->fetch_cache[prebuilt->n_fetch_cached] + offs) |= 
3260
 
                /*  (*(remainder_buf + offs) &*/( templ->mysql_null_bit_mask);
3261
 
              else
3262
 
                *(prebuilt->fetch_cache[prebuilt->n_fetch_cached] + offs) &= 
3263
 
                  ~templ->mysql_null_bit_mask;
3264
 
 
 
3134
              *(prebuilt->fetch_cache[prebuilt->n_fetch_cached] + offs) ^= 
 
3135
                (*(remainder_buf + offs) & templ->mysql_null_bit_mask);
3265
3136
            }
3266
3137
            offs= templ->mysql_col_offset;
3267
3138
            memcpy(prebuilt->fetch_cache[prebuilt->n_fetch_cached] + offs,
3270
3141
          }
3271
3142
        }
3272
3143
 
3273
 
 
3274
3144
        prebuilt->n_fetch_cached++;
3275
3145
}
3276
3146
 
3284
3154
row_sel_try_search_shortcut_for_mysql(
3285
3155
/*==================================*/
3286
3156
                                /* out: SEL_FOUND, SEL_EXHAUSTED, SEL_RETRY */
3287
 
        const rec_t**   out_rec,/* out: record if found */
 
3157
        rec_t**         out_rec,/* out: record if found */
3288
3158
        row_prebuilt_t* prebuilt,/* in: prebuilt struct */
3289
3159
        ulint**         offsets,/* in/out: for rec_get_offsets(*out_rec) */
3290
3160
        mem_heap_t**    heap,   /* in/out: heap for rec_get_offsets() */
3291
3161
        mtr_t*          mtr)    /* in: started mtr */
3292
3162
{
3293
3163
        dict_index_t*   index           = prebuilt->index;
3294
 
        const dtuple_t* search_tuple    = prebuilt->search_tuple;
 
3164
        dtuple_t*       search_tuple    = prebuilt->search_tuple;
3295
3165
        btr_pcur_t*     pcur            = prebuilt->pcur;
3296
3166
        trx_t*          trx             = prebuilt->trx;
3297
 
        const rec_t*    rec;
 
3167
        rec_t*          rec;
3298
3168
 
3299
 
        ut_ad(dict_index_is_clust(index));
 
3169
        ut_ad(index->type & DICT_CLUSTERED);
3300
3170
        ut_ad(!prebuilt->templ_contains_blob);
3301
3171
 
3302
3172
        btr_pcur_open_with_no_init(index, search_tuple, PAGE_CUR_GE,
3351
3221
and fetch prev. NOTE that if we do a search with a full key value
3352
3222
from a unique index (ROW_SEL_EXACT), then we will not store the cursor
3353
3223
position and fetch next or fetch prev must not be tried to the cursor! */
3354
 
UNIV_INTERN
 
3224
 
3355
3225
ulint
3356
3226
row_search_for_mysql(
3357
3227
/*=================*/
3380
3250
{
3381
3251
        dict_index_t*   index           = prebuilt->index;
3382
3252
        ibool           comp            = dict_table_is_comp(index->table);
3383
 
        const dtuple_t* search_tuple    = prebuilt->search_tuple;
 
3253
        dtuple_t*       search_tuple    = prebuilt->search_tuple;
3384
3254
        btr_pcur_t*     pcur            = prebuilt->pcur;
3385
3255
        trx_t*          trx             = prebuilt->trx;
3386
3256
        dict_index_t*   clust_index;
3387
3257
        que_thr_t*      thr;
3388
 
        const rec_t*    rec;
3389
 
        const rec_t*    result_rec;
3390
 
        const rec_t*    clust_rec;
 
3258
        rec_t*          rec;
 
3259
        rec_t*          result_rec;
 
3260
        rec_t*          clust_rec;
3391
3261
        ulint           err                             = DB_SUCCESS;
3392
3262
        ibool           unique_search                   = FALSE;
3393
3263
        ibool           unique_search_from_clust_index  = FALSE;
3409
3279
        mem_heap_t*     heap                            = NULL;
3410
3280
        ulint           offsets_[REC_OFFS_NORMAL_SIZE];
3411
3281
        ulint*          offsets                         = offsets_;
3412
 
        ibool           some_fields_in_buffer;
3413
 
        ibool           get_clust_rec= 0;
 
3282
        ibool           some_fields_in_buffer;
 
3283
        ibool           get_clust_rec= 0;
3414
3284
 
3415
 
        rec_offs_init(offsets_);
 
3285
        *offsets_ = (sizeof offsets_) / sizeof *offsets_;
3416
3286
 
3417
3287
        ut_ad(index && pcur && search_tuple);
3418
3288
        ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
3552
3422
                }
3553
3423
 
3554
3424
                if (prebuilt->fetch_cache_first > 0
3555
 
                    && prebuilt->fetch_cache_first < MYSQL_FETCH_CACHE_SIZE) {
 
3425
                    && prebuilt->fetch_cache_first < DRIZZLE_FETCH_CACHE_SIZE) {
3556
3426
 
3557
3427
                        /* The previous returned row was popped from the fetch
3558
3428
                        cache, but the cache was not full at the time of the
3582
3452
        locks when locking delete-marked records. */
3583
3453
 
3584
3454
        if (match_mode == ROW_SEL_EXACT
3585
 
            && dict_index_is_unique(index)
 
3455
            && index->type & DICT_UNIQUE
3586
3456
            && dtuple_get_n_fields(search_tuple)
3587
3457
            == dict_index_get_n_unique(index)
3588
 
            && (dict_index_is_clust(index)
 
3458
            && (index->type & DICT_CLUSTERED
3589
3459
                || !dtuple_contains_null(search_tuple))) {
3590
3460
 
3591
3461
                /* Note above that a UNIQUE secondary index can contain many
3622
3492
 
3623
3493
        if (UNIV_UNLIKELY(direction == 0)
3624
3494
            && unique_search
3625
 
            && dict_index_is_clust(index)
 
3495
            && index->type & DICT_CLUSTERED
3626
3496
            && !prebuilt->templ_contains_blob
3627
3497
            && !prebuilt->used_in_HANDLER
3628
3498
            && (prebuilt->mysql_row_len < UNIV_PAGE_SIZE / 8)) {
3662
3532
                                ut_a(0 == cmp_dtuple_rec(search_tuple,
3663
3533
                                                         rec, offsets));
3664
3534
#endif
3665
 
                                /* At this point, rec is protected by
3666
 
                                a page latch that was acquired by
3667
 
                                row_sel_try_search_shortcut_for_mysql().
3668
 
                                The latch will not be released until
3669
 
                                mtr_commit(&mtr). */
3670
 
 
3671
3535
                                if (!row_sel_store_mysql_rec(buf, prebuilt,
3672
 
                                                             rec, offsets, 0,
3673
 
                                                             prebuilt->n_template)) {
 
3536
                                                             rec, offsets, 0, 
 
3537
                                                             prebuilt->n_template)) {
3674
3538
                                        err = DB_TOO_BIG_RECORD;
3675
3539
 
3676
3540
                                        /* We let the main loop to do the
3685
3549
 
3686
3550
                                srv_n_rows_read++;
3687
3551
 
 
3552
                                if (trx->search_latch_timeout > 0
 
3553
                                    && trx->has_search_latch) {
 
3554
 
 
3555
                                        trx->search_latch_timeout--;
 
3556
 
 
3557
                                        rw_lock_s_unlock(&btr_search_latch);
 
3558
                                        trx->has_search_latch = FALSE;
 
3559
                                }
 
3560
 
 
3561
                                /* NOTE that we do NOT store the cursor
 
3562
                                position */
3688
3563
                                err = DB_SUCCESS;
3689
 
                                goto release_search_latch_if_needed;
 
3564
                                goto func_exit;
3690
3565
 
3691
3566
                        case SEL_EXHAUSTED:
3692
3567
                                mtr_commit(&mtr);
3694
3569
                                /* ut_print_name(stderr, index->name);
3695
3570
                                fputs(" record not found 2\n", stderr); */
3696
3571
 
3697
 
                                err = DB_RECORD_NOT_FOUND;
3698
 
release_search_latch_if_needed:
3699
3572
                                if (trx->search_latch_timeout > 0
3700
3573
                                    && trx->has_search_latch) {
3701
3574
 
3707
3580
 
3708
3581
                                /* NOTE that we do NOT store the cursor
3709
3582
                                position */
 
3583
 
 
3584
                                err = DB_RECORD_NOT_FOUND;
3710
3585
                                goto func_exit;
3711
 
 
3712
 
                        case SEL_RETRY:
3713
 
                                break;
3714
 
 
3715
 
                        default:
3716
 
                                ut_ad(0);
3717
3586
                        }
3718
3587
shortcut_fails_too_big_rec:
3719
3588
                        mtr_commit(&mtr);
3733
3602
 
3734
3603
        if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
3735
3604
            && prebuilt->select_lock_type != LOCK_NONE
3736
 
            && trx->mysql_thd != NULL
3737
3605
            && trx->mysql_query_str != NULL
3738
 
            && *trx->mysql_query_str != NULL) {
 
3606
            && *trx->mysql_query_str != NULL
 
3607
            && trx->mysql_thd != NULL) {
3739
3608
 
3740
3609
                /* Scan the MySQL query string; check if SELECT is the first
3741
3610
                word there */
3812
3681
 
3813
3682
                        /* Try to place a gap lock on the next index record
3814
3683
                        to prevent phantoms in ORDER BY ... DESC queries */
3815
 
                        const rec_t*    next = page_rec_get_next_const(rec);
3816
3684
 
3817
 
                        offsets = rec_get_offsets(next, index, offsets,
 
3685
                        offsets = rec_get_offsets(page_rec_get_next(rec),
 
3686
                                                  index, offsets,
3818
3687
                                                  ULINT_UNDEFINED, &heap);
3819
 
                        err = sel_set_rec_lock(btr_pcur_get_block(pcur),
3820
 
                                               next, index, offsets,
 
3688
                        err = sel_set_rec_lock(page_rec_get_next(rec),
 
3689
                                               index, offsets,
3821
3690
                                               prebuilt->select_lock_type,
3822
3691
                                               LOCK_GAP, thr);
3823
3692
 
3885
3754
        fputs("Using ", stderr);
3886
3755
        dict_index_name_print(stderr, index);
3887
3756
        fprintf(stderr, " cnt %lu ; Page no %lu\n", cnt,
3888
 
        page_get_page_no(page_align(rec)));
 
3757
        buf_frame_get_page_no(buf_frame_align(rec)));
3889
3758
        rec_print(rec);
3890
3759
        */
3891
3760
#endif /* UNIV_SEARCH_DEBUG */
3915
3784
 
3916
3785
                        offsets = rec_get_offsets(rec, index, offsets,
3917
3786
                                                  ULINT_UNDEFINED, &heap);
3918
 
                        err = sel_set_rec_lock(btr_pcur_get_block(pcur),
3919
 
                                               rec, index, offsets,
 
3787
                        err = sel_set_rec_lock(rec, index, offsets,
3920
3788
                                               prebuilt->select_lock_type,
3921
3789
                                               LOCK_ORDINARY, thr);
3922
3790
 
3954
3822
wrong_offs:
3955
3823
                if (srv_force_recovery == 0 || moves_up == FALSE) {
3956
3824
                        ut_print_timestamp(stderr);
3957
 
                        buf_page_print(page_align(rec), 0);
 
3825
                        buf_page_print(buf_frame_align(rec));
3958
3826
                        fprintf(stderr,
3959
 
                                "\nInnoDB: rec address %p,"
 
3827
                                "\nInnoDB: rec address %p, first"
 
3828
                                " buffer frame %p\n"
 
3829
                                "InnoDB: buffer pool high end %p,"
3960
3830
                                " buf block fix count %lu\n",
3961
 
                                (void*) rec, (ulong)
3962
 
                                btr_cur_get_block(btr_pcur_get_btr_cur(pcur))
3963
 
                                ->page.buf_fix_count);
 
3831
                                (void*) rec, (void*) buf_pool->frame_zero,
 
3832
                                (void*) buf_pool->high_end,
 
3833
                                (ulong)buf_block_align(rec)->buf_fix_count);
3964
3834
                        fprintf(stderr,
3965
3835
                                "InnoDB: Index corruption: rec offs %lu"
3966
3836
                                " next offs %lu, page no %lu,\n"
3967
3837
                                "InnoDB: ",
3968
3838
                                (ulong) page_offset(rec),
3969
3839
                                (ulong) next_offs,
3970
 
                                (ulong) page_get_page_no(page_align(rec)));
 
3840
                                (ulong) buf_frame_get_page_no(rec));
3971
3841
                        dict_index_name_print(stderr, trx, index);
3972
3842
                        fputs(". Run CHECK TABLE. You may need to\n"
3973
3843
                              "InnoDB: restore from a backup, or"
3987
3857
                                "InnoDB: ",
3988
3858
                                (ulong) page_offset(rec),
3989
3859
                                (ulong) next_offs,
3990
 
                                (ulong) page_get_page_no(page_align(rec)));
 
3860
                                (ulong) buf_frame_get_page_no(rec));
3991
3861
                        dict_index_name_print(stderr, trx, index);
3992
3862
                        fputs(". We try to skip the rest of the page.\n",
3993
3863
                              stderr);
4012
3882
                                "InnoDB: ",
4013
3883
                                (ulong) page_offset(rec),
4014
3884
                                (ulong) next_offs,
4015
 
                                (ulong) page_get_page_no(page_align(rec)));
 
3885
                                (ulong) buf_frame_get_page_no(rec));
4016
3886
                        dict_index_name_print(stderr, trx, index);
4017
3887
                        fputs(". We try to skip the record.\n",
4018
3888
                              stderr);
4046
3916
                                using a READ COMMITTED isolation level. */
4047
3917
 
4048
3918
                                err = sel_set_rec_lock(
4049
 
                                        btr_pcur_get_block(pcur),
4050
3919
                                        rec, index, offsets,
4051
3920
                                        prebuilt->select_lock_type, LOCK_GAP,
4052
3921
                                        thr);
4082
3951
                                using a READ COMMITTED isolation level. */
4083
3952
 
4084
3953
                                err = sel_set_rec_lock(
4085
 
                                        btr_pcur_get_block(pcur),
4086
3954
                                        rec, index, offsets,
4087
3955
                                        prebuilt->select_lock_type, LOCK_GAP,
4088
3956
                                        thr);
4151
4019
                        lock_type = LOCK_REC_NOT_GAP;
4152
4020
                }
4153
4021
 
4154
 
                err = sel_set_rec_lock(btr_pcur_get_block(pcur),
4155
 
                                       rec, index, offsets,
 
4022
                err = sel_set_rec_lock(rec, index, offsets,
4156
4023
                                       prebuilt->select_lock_type,
4157
4024
                                       lock_type, thr);
4158
4025
 
4159
4026
                switch (err) {
4160
 
                        const rec_t*    old_vers;
 
4027
                        rec_t*  old_vers;
4161
4028
                case DB_SUCCESS:
4162
4029
                        break;
4163
4030
                case DB_LOCK_WAIT:
4260
4127
 
4261
4128
                                rec = old_vers;
4262
4129
                        }
4263
 
                } else if (!lock_sec_rec_cons_read_sees(rec, trx->read_view)) {
 
4130
                } else if (!lock_sec_rec_cons_read_sees(rec, index,
 
4131
                                                        trx->read_view)) {
4264
4132
                        /* We are looking into a non-clustered index,
4265
4133
                        and to get the right version of the record we
4266
4134
                        have to look also into the clustered index: this
4268
4136
                        information via the clustered index record. */
4269
4137
 
4270
4138
                        ut_ad(index != clust_index);
4271
 
                        get_clust_rec= TRUE;
 
4139
                        get_clust_rec= TRUE;
4272
4140
                        goto idx_cond_check;
4273
4141
                }
4274
4142
        }
4313
4181
                goto next_rec;
4314
4182
        }
4315
4183
 
 
4184
 
4316
4185
idx_cond_check:
4317
4186
        if (prebuilt->idx_cond_func)
4318
4187
        {
4333
4202
 
4334
4203
        /* Get the clustered index record if needed, if we did not do the
4335
4204
        search using the clustered index. */
4336
 
 
4337
4205
        if (get_clust_rec || (index != clust_index &&
4338
 
            prebuilt->need_to_access_clustered)) {
 
4206
            prebuilt->need_to_access_clustered)) {
4339
4207
 
4340
4208
                /* We use a 'goto' to the preceding label if a consistent
4341
4209
                read of a secondary index record requires us to look up old
4342
4210
                versions of the associated clustered index record. */
4343
4211
 
4344
4212
                ut_ad(rec_offs_validate(rec, index, offsets));
4345
 
 
 
4213
                
4346
4214
                /* It was a non-clustered index and we must fetch also the
4347
4215
                clustered index record */
4348
4216
 
4409
4277
                                result_rec != rec ? clust_index : index,
4410
4278
                                offsets));
4411
4279
 
4412
 
        /* At this point, the clustered index record is protected
4413
 
        by a page latch that was acquired when pcur was positioned.
4414
 
        The latch will not be released until mtr_commit(&mtr). */
4415
 
 
4416
4280
        if ((match_mode == ROW_SEL_EXACT
4417
 
             || prebuilt->n_rows_fetched >= MYSQL_FETCH_CACHE_THRESHOLD)
 
4281
             || prebuilt->n_rows_fetched >= DRIZZLE_FETCH_CACHE_THRESHOLD)
4418
4282
            && prebuilt->select_lock_type == LOCK_NONE
4419
4283
            && !prebuilt->templ_contains_blob
4420
4284
            && !prebuilt->clust_index_was_generated
4421
4285
            && !prebuilt->used_in_HANDLER
4422
4286
            && prebuilt->template_type
4423
 
            != ROW_MYSQL_DUMMY_TEMPLATE) {
 
4287
            != ROW_DRIZZLE_DUMMY_TEMPLATE) {
4424
4288
 
4425
4289
                /* Inside an update, for example, we do not cache rows,
4426
4290
                since we may use the cursor position to do the actual
4430
4294
                are BLOBs in the fields to be fetched. In HANDLER we do
4431
4295
                not cache rows because there the cursor is a scrollable
4432
4296
                cursor. */
4433
 
                some_fields_in_buffer= (index != clust_index &&
 
4297
                some_fields_in_buffer= (index != clust_index &&
4434
4298
                                        prebuilt->idx_cond_func);
4435
4299
 
4436
4300
                row_sel_push_cache_row_for_mysql(prebuilt, result_rec,
4437
 
                                                 offsets,
4438
 
                                                 some_fields_in_buffer?
4439
 
                                                 prebuilt->n_index_fields: 0,
4440
 
                                                 buf);
4441
 
                if (prebuilt->n_fetch_cached == MYSQL_FETCH_CACHE_SIZE) {
 
4301
                                                 offsets, 
 
4302
                                                 some_fields_in_buffer? 
 
4303
                                                 prebuilt->n_index_fields: 0,
 
4304
                                                 buf);
 
4305
                if (prebuilt->n_fetch_cached == DRIZZLE_FETCH_CACHE_SIZE) {
4442
4306
 
4443
4307
                        goto got_row;
4444
4308
                }
4445
4309
 
4446
4310
                goto next_rec;
4447
4311
        } else {
4448
 
                if (prebuilt->template_type == ROW_MYSQL_DUMMY_TEMPLATE) {
 
4312
                if (prebuilt->template_type == ROW_DRIZZLE_DUMMY_TEMPLATE) {
4449
4313
                        memcpy(buf + 4, result_rec
4450
4314
                               - rec_offs_extra_size(offsets),
4451
4315
                               rec_offs_size(offsets));
4454
4318
                } else {
4455
4319
                        if (!row_sel_store_mysql_rec(buf, prebuilt,
4456
4320
                                                     result_rec, offsets,
4457
 
                                                     prebuilt->idx_cond_func?
 
4321
                                                     prebuilt->idx_cond_func? 
4458
4322
                                                     prebuilt->n_index_fields: 0,
4459
4323
                                                     prebuilt->n_template)) {
4460
4324
                                err = DB_TOO_BIG_RECORD;
4484
4348
        HANDLER command where the user can move the cursor with PREV or NEXT
4485
4349
        even after a unique search. */
4486
4350
 
 
4351
        err = DB_SUCCESS;
 
4352
 
4487
4353
idx_cond_failed:
4488
4354
        if (!unique_search_from_clust_index
4489
4355
            || prebuilt->select_lock_type != LOCK_NONE
4494
4360
                btr_pcur_store_position(pcur, &mtr);
4495
4361
        }
4496
4362
 
4497
 
        err = DB_SUCCESS;
4498
 
 
4499
4363
        goto normal_return;
4500
4364
 
4501
4365
next_rec:
4502
4366
        /* Reset the old and new "did semi-consistent read" flags. */
 
4367
        get_clust_rec= FALSE;
4503
4368
        if (UNIV_UNLIKELY(prebuilt->row_read_type
4504
4369
                          == ROW_READ_DID_SEMI_CONSISTENT)) {
4505
4370
                prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
4680
4545
/***********************************************************************
4681
4546
Checks if MySQL at the moment is allowed for this table to retrieve a
4682
4547
consistent read result, or store it to the query cache. */
4683
 
UNIV_INTERN
 
4548
 
4684
4549
ibool
4685
4550
row_search_check_if_query_cache_permitted(
4686
4551
/*======================================*/
4738
4603
Read the AUTOINC column from the current row. If the value is less than
4739
4604
0 and the type is not unsigned then we reset the value to 0. */
4740
4605
static
4741
 
ib_uint64_t
 
4606
ib_longlong
4742
4607
row_search_autoinc_read_column(
4743
4608
/*===========================*/
4744
4609
                                        /* out: value read from the column */
4745
4610
        dict_index_t*   index,          /* in: index to read from */
4746
 
        const rec_t*    rec,            /* in: current rec */
 
4611
        rec_t*  rec,            /* in: current rec */
4747
4612
        ulint           col_no,         /* in: column number */
4748
4613
        ibool           unsigned_type)  /* in: signed or unsigned flag */
4749
4614
{
4750
4615
        ulint           len;
4751
4616
        const byte*     data;
4752
 
        ib_uint64_t     value;
 
4617
        ib_longlong     value;
4753
4618
        mem_heap_t*     heap = NULL;
 
4619
        /* Our requirement is that dest should be word aligned. */
 
4620
        byte            dest[sizeof(value)];
4754
4621
        ulint           offsets_[REC_OFFS_NORMAL_SIZE];
4755
4622
        ulint*          offsets = offsets_;
4756
4623
 
4757
 
        rec_offs_init(offsets_);
 
4624
        *offsets_ = sizeof offsets_ / sizeof *offsets_;
4758
4625
 
4759
4626
        offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
4760
4627
 
4763
4630
        ut_a(len != UNIV_SQL_NULL);
4764
4631
        ut_a(len <= sizeof value);
4765
4632
 
4766
 
        /* we assume AUTOINC value cannot be negative */
4767
 
        value = mach_read_int_type(data, len, unsigned_type);
 
4633
        mach_read_int_type(dest, data, len, unsigned_type);
 
4634
 
 
4635
        /* The assumption here is that the AUTOINC value can't be negative
 
4636
        and that dest is word aligned. */
 
4637
        switch (len) {
 
4638
        case 8:
 
4639
                value = *(ib_longlong*) dest;
 
4640
                break;
 
4641
 
 
4642
        case 4:
 
4643
                value = *(ib_uint32_t*) dest;
 
4644
                break;
 
4645
 
 
4646
        case 3:
 
4647
                value = *(ib_uint32_t*) dest;
 
4648
                value &= 0xFFFFFF;
 
4649
                break;
 
4650
 
 
4651
        case 2:
 
4652
                value = *(uint16_t *) dest;
 
4653
                break;
 
4654
 
 
4655
        case 1:
 
4656
                value = *dest;
 
4657
                break;
 
4658
 
 
4659
        default:
 
4660
                ut_error;
 
4661
        }
4768
4662
 
4769
4663
        if (UNIV_LIKELY_NULL(heap)) {
4770
4664
                mem_heap_free(heap);
4771
4665
        }
4772
4666
 
4773
 
        if (!unsigned_type && (ib_int64_t) value < 0) {
 
4667
        if (!unsigned_type && value < 0) {
4774
4668
                value = 0;
4775
4669
        }
4776
4670
 
4780
4674
/***********************************************************************
4781
4675
Get the last row. */
4782
4676
static
4783
 
const rec_t*
 
4677
rec_t*
4784
4678
row_search_autoinc_get_rec(
4785
4679
/*=======================*/
4786
4680
                                        /* out: current rec or NULL */
4788
4682
        mtr_t*          mtr)            /* in: mini transaction */
4789
4683
{
4790
4684
        do {
4791
 
                const rec_t* rec = btr_pcur_get_rec(pcur);
 
4685
                rec_t* rec = btr_pcur_get_rec(pcur);
4792
4686
 
4793
4687
                if (page_rec_is_user_rec(rec)) {
4794
4688
                        return(rec);
4800
4694
 
4801
4695
/***********************************************************************
4802
4696
Read the max AUTOINC value from an index. */
4803
 
UNIV_INTERN
 
4697
 
4804
4698
ulint
4805
4699
row_search_max_autoinc(
4806
4700
/*===================*/
4809
4703
                                        column name can't be found in index */
4810
4704
        dict_index_t*   index,          /* in: index to search */
4811
4705
        const char*     col_name,       /* in: name of autoinc column */
4812
 
        ib_uint64_t*    value)          /* out: AUTOINC value read */
 
4706
        ib_longlong*    value)          /* out: AUTOINC value read */
4813
4707
{
4814
4708
        ulint           i;
4815
4709
        ulint           n_cols;
4842
4736
                        FALSE, index, BTR_SEARCH_LEAF, &pcur, TRUE, &mtr);
4843
4737
 
4844
4738
                if (page_get_n_recs(btr_pcur_get_page(&pcur)) > 0) {
4845
 
                        const rec_t*    rec;
 
4739
                        rec_t*  rec;
4846
4740
 
4847
4741
                        rec = row_search_autoinc_get_rec(&pcur, &mtr);
4848
4742