~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Monty Taylor
  • Date: 2010-09-28 07:45:44 UTC
  • mto: (1799.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1800.
  • Revision ID: mordred@inaugust.com-20100928074544-s3ujnv6s8wro74l2
Added BSD copying file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (c) 1997, 2010, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 1997, 2009, Innobase Oy. All Rights Reserved.
4
4
Copyright (c) 2008, Google Inc.
5
5
 
6
6
Portions of this file contain modifications contributed and copyrighted by
18
18
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19
19
 
20
20
You should have received a copy of the GNU General Public License along with
21
 
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
22
 
St, Fifth Floor, Boston, MA 02110-1301 USA
 
21
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
22
Place, Suite 330, Boston, MA 02111-1307 USA
23
23
 
24
24
*****************************************************************************/
25
25
 
88
88
/*========================*/
89
89
        ulint           mtype,          /*!< in: main type */
90
90
        ulint           prtype,         /*!< in: precise type */
91
 
        ulint           mbminmaxlen,    /*!< in: minimum and maximum length of
92
 
                                        a multi-byte character */
 
91
        ulint           mbminlen,       /*!< in: minimum length of a
 
92
                                        multi-byte character */
 
93
        ulint           mbmaxlen,       /*!< in: maximum length of a
 
94
                                        multi-byte character */
93
95
        const byte*     clust_field,    /*!< in: the locally stored part of
94
96
                                        the clustered index column, including
95
97
                                        the BLOB pointer; the clustered
117
119
                return(FALSE);
118
120
        }
119
121
 
120
 
        len = dtype_get_at_most_n_mbchars(prtype, mbminmaxlen,
 
122
        len = dtype_get_at_most_n_mbchars(prtype, mbminlen, mbmaxlen,
121
123
                                          sec_len, len, (const char*) buf);
122
124
 
123
125
        return(!cmp_data_data(mtype, prtype, buf, len, sec_field, sec_len));
130
132
NOTE: the comparison is NOT done as a binary comparison, but character
131
133
fields are compared with collation!
132
134
@return TRUE if the secondary record is equal to the corresponding
133
 
fields in the clustered record, when compared with collation;
134
 
FALSE if not equal or if the clustered record has been marked for deletion */
 
135
fields in the clustered record, when compared with collation */
135
136
static
136
137
ibool
137
138
row_sel_sec_rec_is_for_clust_rec(
200
201
                        }
201
202
 
202
203
                        len = dtype_get_at_most_n_mbchars(
203
 
                                col->prtype, col->mbminmaxlen,
 
204
                                col->prtype, col->mbminlen, col->mbmaxlen,
204
205
                                ifield->prefix_len, len, (char*) clust_field);
205
206
 
206
207
                        if (rec_offs_nth_extern(clust_offs, clust_pos)
207
208
                            && len < sec_len) {
208
209
                                if (!row_sel_sec_rec_is_for_blob(
209
210
                                            col->mtype, col->prtype,
210
 
                                            col->mbminmaxlen,
 
211
                                            col->mbminlen, col->mbmaxlen,
211
212
                                            clust_field, clust_len,
212
213
                                            sec_field, sec_len,
213
214
                                            dict_table_zip_size(
414
415
                                                              field_no))) {
415
416
 
416
417
                                /* Copy an externally stored field to the
417
 
                                temporary heap, if possible. */
 
418
                                temporary heap */
418
419
 
419
420
                                heap = mem_heap_create(1);
420
421
 
423
424
                                        dict_table_zip_size(index->table),
424
425
                                        field_no, &len, heap);
425
426
 
426
 
                                /* data == NULL means that the
427
 
                                externally stored field was not
428
 
                                written yet. This record
429
 
                                should only be seen by
430
 
                                recv_recovery_rollback_active() or any
431
 
                                TRX_ISO_READ_UNCOMMITTED
432
 
                                transactions. The InnoDB SQL parser
433
 
                                (the sole caller of this function)
434
 
                                does not implement READ UNCOMMITTED,
435
 
                                and it is not involved during rollback. */
436
 
                                ut_a(data);
437
427
                                ut_a(len != UNIV_SQL_NULL);
438
428
 
439
429
                                needs_copy = TRUE;
441
431
                                data = rec_get_nth_field(rec, offsets,
442
432
                                                         field_no, &len);
443
433
 
 
434
                                if (len == UNIV_SQL_NULL) {
 
435
                                        len = UNIV_SQL_NULL;
 
436
                                }
 
437
 
444
438
                                needs_copy = column->copy_val;
445
439
                        }
446
440
 
861
855
                trx = thr_get_trx(thr);
862
856
 
863
857
                if (srv_locks_unsafe_for_binlog
864
 
                    || trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
 
858
                    || trx->isolation_level == TRX_ISO_READ_COMMITTED) {
865
859
                        lock_type = LOCK_REC_NOT_GAP;
866
860
                } else {
867
861
                        lock_type = LOCK_ORDINARY;
872
866
                        clust_rec, index, offsets,
873
867
                        node->row_lock_mode, lock_type, thr);
874
868
 
875
 
                switch (err) {
876
 
                case DB_SUCCESS:
877
 
                case DB_SUCCESS_LOCKED_REC:
878
 
                        /* Declare the variable uninitialized in Valgrind.
879
 
                        It should be set to DB_SUCCESS at func_exit. */
880
 
                        UNIV_MEM_INVALID(&err, sizeof err);
881
 
                        break;
882
 
                default:
 
869
                if (err != DB_SUCCESS) {
 
870
 
883
871
                        goto err_exit;
884
872
                }
885
873
        } else {
935
923
        when plan->clust_pcur was positioned.  The latch will not be
936
924
        released until mtr_commit(mtr). */
937
925
 
938
 
        ut_ad(!rec_get_deleted_flag(clust_rec, rec_offs_comp(offsets)));
939
926
        row_sel_fetch_columns(index, clust_rec, offsets,
940
927
                              UT_LIST_GET_FIRST(plan->columns));
941
928
        *out_rec = clust_rec;
950
937
 
951
938
/*********************************************************************//**
952
939
Sets a lock on a record.
953
 
@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */
 
940
@return DB_SUCCESS or error code */
954
941
UNIV_INLINE
955
 
enum db_err
 
942
ulint
956
943
sel_set_rec_lock(
957
944
/*=============*/
958
945
        const buf_block_t*      block,  /*!< in: buffer block of rec */
964
951
                                        LOC_REC_NOT_GAP */
965
952
        que_thr_t*              thr)    /*!< in: query thread */
966
953
{
967
 
        trx_t*          trx;
968
 
        enum db_err     err;
 
954
        trx_t*  trx;
 
955
        ulint   err;
969
956
 
970
957
        trx = thr_get_trx(thr);
971
958
 
1481
1468
 
1482
1469
                        if (srv_locks_unsafe_for_binlog
1483
1470
                            || trx->isolation_level
1484
 
                            <= TRX_ISO_READ_COMMITTED) {
 
1471
                            == TRX_ISO_READ_COMMITTED) {
1485
1472
 
1486
1473
                                if (page_rec_is_supremum(next_rec)) {
1487
1474
 
1498
1485
                                               node->row_lock_mode,
1499
1486
                                               lock_type, thr);
1500
1487
 
1501
 
                        switch (err) {
1502
 
                        case DB_SUCCESS_LOCKED_REC:
1503
 
                                err = DB_SUCCESS;
1504
 
                        case DB_SUCCESS:
1505
 
                                break;
1506
 
                        default:
 
1488
                        if (err != DB_SUCCESS) {
1507
1489
                                /* Note that in this case we will store in pcur
1508
1490
                                the PREDECESSOR of the record we are waiting
1509
1491
                                the lock for */
 
1492
 
1510
1493
                                goto lock_wait_or_error;
1511
1494
                        }
1512
1495
                }
1542
1525
                trx = thr_get_trx(thr);
1543
1526
 
1544
1527
                if (srv_locks_unsafe_for_binlog
1545
 
                    || trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
 
1528
                    || trx->isolation_level == TRX_ISO_READ_COMMITTED) {
1546
1529
 
1547
1530
                        if (page_rec_is_supremum(rec)) {
1548
1531
 
1558
1541
                                       rec, index, offsets,
1559
1542
                                       node->row_lock_mode, lock_type, thr);
1560
1543
 
1561
 
                switch (err) {
1562
 
                case DB_SUCCESS_LOCKED_REC:
1563
 
                        err = DB_SUCCESS;
1564
 
                case DB_SUCCESS:
1565
 
                        break;
1566
 
                default:
 
1544
                if (err != DB_SUCCESS) {
 
1545
 
1567
1546
                        goto lock_wait_or_error;
1568
1547
                }
1569
1548
        }
1638
1617
                                }
1639
1618
 
1640
1619
                                if (old_vers == NULL) {
1641
 
                                        /* The record does not exist
1642
 
                                        in our read view. Skip it, but
1643
 
                                        first attempt to determine
1644
 
                                        whether the index segment we
1645
 
                                        are searching through has been
1646
 
                                        exhausted. */
1647
 
 
1648
1620
                                        offsets = rec_get_offsets(
1649
1621
                                                rec, index, offsets,
1650
1622
                                                ULINT_UNDEFINED, &heap);
1729
1701
                                            &mtr);
1730
1702
                mtr_has_extra_clust_latch = TRUE;
1731
1703
 
1732
 
                switch (err) {
1733
 
                case DB_SUCCESS_LOCKED_REC:
1734
 
                        err = DB_SUCCESS;
1735
 
                case DB_SUCCESS:
1736
 
                        break;
1737
 
                default:
 
1704
                if (err != DB_SUCCESS) {
 
1705
 
1738
1706
                        goto lock_wait_or_error;
1739
1707
                }
1740
1708
 
1919
1887
                        thr->run_node = que_node_get_parent(node);
1920
1888
                }
1921
1889
 
1922
 
                err = DB_SUCCESS;
1923
1890
                goto func_exit;
1924
1891
        }
1925
1892
 
2077
2044
                        /* Reset the aggregate total values */
2078
2045
                        sel_reset_aggregate_vals(node);
2079
2046
                }
2080
 
 
2081
 
                err = DB_SUCCESS;
2082
2047
        }
2083
2048
 
2084
2049
        err = row_sel(node, thr);
2205
2170
        return((void*)42);
2206
2171
}
2207
2172
 
 
2173
/****************************************************************//**
 
2174
Callback function for fetch that stores an unsigned 4 byte integer to the
 
2175
location pointed. The column's type must be DATA_INT, DATA_UNSIGNED, length
 
2176
= 4.
 
2177
@return always returns NULL */
 
2178
UNIV_INTERN
 
2179
void*
 
2180
row_fetch_store_uint4(
 
2181
/*==================*/
 
2182
        void*   row,            /*!< in:  sel_node_t* */
 
2183
        void*   user_arg)       /*!< in:  data pointer */
 
2184
{
 
2185
        sel_node_t*     node = row;
 
2186
        ib_uint32_t*    val = user_arg;
 
2187
        ulint           tmp;
 
2188
 
 
2189
        dfield_t*       dfield = que_node_get_val(node->select_list);
 
2190
        const dtype_t*  type = dfield_get_type(dfield);
 
2191
        ulint           len = dfield_get_len(dfield);
 
2192
 
 
2193
        ut_a(dtype_get_mtype(type) == DATA_INT);
 
2194
        ut_a(dtype_get_prtype(type) & DATA_UNSIGNED);
 
2195
        ut_a(len == 4);
 
2196
 
 
2197
        tmp = mach_read_from_4(dfield_get_data(dfield));
 
2198
        *val = (ib_uint32_t) tmp;
 
2199
 
 
2200
        return(NULL);
 
2201
}
 
2202
 
2208
2203
/***********************************************************//**
2209
2204
Prints a row in a select result.
2210
2205
@return query thread to run next or NULL */
2532
2527
        ulint           len)    /*!< in: length of the data */
2533
2528
{
2534
2529
        byte*   ptr;
 
2530
        byte*   field_end;
 
2531
        byte*   pad_ptr;
2535
2532
 
2536
2533
        ut_ad(len != UNIV_SQL_NULL);
2537
 
        UNIV_MEM_ASSERT_RW(data, len);
2538
2534
 
2539
2535
        switch (templ->type) {
2540
 
                const byte*     field_end;
2541
 
                byte*           pad;
2542
2536
        case DATA_INT:
2543
2537
                /* Convert integer data from Innobase to a little-endian
2544
2538
                format, sign bit restored to normal */
2582
2576
                unused end of a >= 5.0.3 true VARCHAR column, just in case
2583
2577
                MySQL expects its contents to be deterministic. */
2584
2578
 
2585
 
                pad = dest + len;
 
2579
                pad_ptr = dest + len;
2586
2580
 
2587
2581
                ut_ad(templ->mbminlen <= templ->mbmaxlen);
2588
2582
 
2589
 
                /* We treat some Unicode charset strings specially. */
2590
 
                switch (templ->mbminlen) {
2591
 
                case 4:
2592
 
                        /* InnoDB should never have stripped partial
2593
 
                        UTF-32 characters. */
2594
 
                        ut_a(!(len & 3));
2595
 
                        break;
2596
 
                case 2:
2597
 
                        /* A space char is two bytes,
2598
 
                        0x0020 in UCS2 and UTF-16 */
 
2583
                /* We handle UCS2 charset strings differently. */
 
2584
                if (templ->mbminlen == 2) {
 
2585
                        /* A space char is two bytes, 0x0020 in UCS2 */
2599
2586
 
2600
 
                        if (UNIV_UNLIKELY(len & 1)) {
 
2587
                        if (len & 1) {
2601
2588
                                /* A 0x20 has been stripped from the column.
2602
2589
                                Pad it back. */
2603
2590
 
2604
 
                                if (pad < field_end) {
2605
 
                                        *pad++ = 0x20;
 
2591
                                if (pad_ptr < field_end) {
 
2592
                                        *pad_ptr = 0x20;
 
2593
                                        pad_ptr++;
2606
2594
                                }
2607
2595
                        }
 
2596
 
 
2597
                        /* Pad the rest of the string with 0x0020 */
 
2598
 
 
2599
                        while (pad_ptr < field_end) {
 
2600
                                *pad_ptr = 0x00;
 
2601
                                pad_ptr++;
 
2602
                                *pad_ptr = 0x20;
 
2603
                                pad_ptr++;
 
2604
                        }
 
2605
                } else {
 
2606
                        ut_ad(templ->mbminlen == 1);
 
2607
                        /* space=0x20 */
 
2608
 
 
2609
                        memset(pad_ptr, 0x20, field_end - pad_ptr);
2608
2610
                }
2609
 
 
2610
 
                row_mysql_pad_col(templ->mbminlen, pad, field_end - pad);
2611
2611
                break;
2612
2612
 
2613
2613
        case DATA_BLOB:
2632
2632
                      || !(templ->mysql_col_len % templ->mbmaxlen));
2633
2633
                ut_ad(len * templ->mbmaxlen >= templ->mysql_col_len);
2634
2634
 
2635
 
                if (templ->mbminlen == 1 && templ->mbmaxlen != 1) {
 
2635
                if (templ->mbminlen != templ->mbmaxlen) {
2636
2636
                        /* Pad with spaces. This undoes the stripping
2637
 
                        done in row0mysql.c, function
 
2637
                        done in row0mysql.ic, function
2638
2638
                        row_mysql_store_col_in_innobase_format(). */
2639
2639
 
2640
2640
                        memset(dest + len, 0x20, templ->mysql_col_len - len);
2665
2665
Note that the template in prebuilt may advise us to copy only a few
2666
2666
columns to mysql_rec, other columns are left blank. All columns may not
2667
2667
be needed in the query.
2668
 
@return TRUE on success, FALSE if not all columns could be retrieved */
 
2668
@return TRUE if success, FALSE if could not allocate memory for a BLOB
 
2669
(though we may also assert in that case) */
2669
2670
static
2670
 
#ifdef __GNUC__
2671
 
 __attribute__((warn_unused_result))
2672
 
#endif
2673
2671
ibool
2674
2672
row_sel_store_mysql_rec(
2675
2673
/*====================*/
2733
2731
                                dict_table_zip_size(prebuilt->table),
2734
2732
                                templ->rec_field_no, &len, heap);
2735
2733
 
2736
 
                        if (UNIV_UNLIKELY(!data)) {
2737
 
                                /* The externally stored field
2738
 
                                was not written yet. This
2739
 
                                record should only be seen by
2740
 
                                recv_recovery_rollback_active()
2741
 
                                or any TRX_ISO_READ_UNCOMMITTED
2742
 
                                transactions. */
2743
 
 
2744
 
                                if (extern_field_heap) {
2745
 
                                        mem_heap_free(extern_field_heap);
2746
 
                                }
2747
 
 
2748
 
                                return(FALSE);
2749
 
                        }
2750
 
 
2751
 
                        if (UNIV_UNLIKELY(!data)) {
2752
 
                                /* The externally stored field
2753
 
                                was not written yet. This
2754
 
                                record should only be seen by
2755
 
                                recv_recovery_rollback_active()
2756
 
                                or any TRX_ISO_READ_UNCOMMITTED
2757
 
                                transactions. */
2758
 
 
2759
 
                                if (extern_field_heap) {
2760
 
                                        mem_heap_free(extern_field_heap);
2761
 
                                }
2762
 
 
2763
 
                                return(FALSE);
2764
 
                        }
2765
 
 
2766
2734
                        ut_a(len != UNIV_SQL_NULL);
2767
2735
                } else {
2768
2736
                        /* Field is stored in the row. */
2811
2779
                        /* MySQL assumes that the field for an SQL
2812
2780
                        NULL value is set to the default value. */
2813
2781
 
2814
 
                        UNIV_MEM_ASSERT_RW(prebuilt->default_rec
2815
 
                                           + templ->mysql_col_offset,
2816
 
                                           templ->mysql_col_len);
2817
2782
                        mysql_rec[templ->mysql_null_byte_offset]
2818
2783
                                |= (byte) templ->mysql_null_bit_mask;
2819
2784
                        memcpy(mysql_rec + templ->mysql_col_offset,
2865
2830
Retrieves the clustered index record corresponding to a record in a
2866
2831
non-clustered index. Does the necessary locking. Used in the MySQL
2867
2832
interface.
2868
 
@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */
 
2833
@return DB_SUCCESS or error code */
2869
2834
static
2870
 
enum db_err
 
2835
ulint
2871
2836
row_sel_get_clust_rec_for_mysql(
2872
2837
/*============================*/
2873
2838
        row_prebuilt_t* prebuilt,/*!< in: prebuilt struct in the handle */
2894
2859
        dict_index_t*   clust_index;
2895
2860
        const rec_t*    clust_rec;
2896
2861
        rec_t*          old_vers;
2897
 
        enum db_err     err;
 
2862
        ulint           err;
2898
2863
        trx_t*          trx;
2899
2864
 
2900
2865
        *out_rec = NULL;
2953
2918
 
2954
2919
                clust_rec = NULL;
2955
2920
 
2956
 
                err = DB_SUCCESS;
2957
2921
                goto func_exit;
2958
2922
        }
2959
2923
 
2969
2933
                        0, btr_pcur_get_block(prebuilt->clust_pcur),
2970
2934
                        clust_rec, clust_index, *offsets,
2971
2935
                        prebuilt->select_lock_type, LOCK_REC_NOT_GAP, thr);
2972
 
                switch (err) {
2973
 
                case DB_SUCCESS:
2974
 
                case DB_SUCCESS_LOCKED_REC:
2975
 
                        break;
2976
 
                default:
 
2936
                if (err != DB_SUCCESS) {
 
2937
 
2977
2938
                        goto err_exit;
2978
2939
                }
2979
2940
        } else {
3020
2981
 
3021
2982
                if (clust_rec
3022
2983
                    && (old_vers
3023
 
                        || trx->isolation_level <= TRX_ISO_READ_UNCOMMITTED
3024
2984
                        || rec_get_deleted_flag(rec, dict_table_is_comp(
3025
2985
                                                        sec_index->table)))
3026
2986
                    && !row_sel_sec_rec_is_for_clust_rec(
3033
2993
                                     rec, sec_index, clust_rec, clust_index));
3034
2994
#endif
3035
2995
                }
3036
 
 
3037
 
                err = DB_SUCCESS;
3038
2996
        }
3039
2997
 
3040
2998
func_exit:
3047
3005
                btr_pcur_store_position(prebuilt->clust_pcur, mtr);
3048
3006
        }
3049
3007
 
 
3008
        err = DB_SUCCESS;
3050
3009
err_exit:
3051
3010
        return(err);
3052
3011
}
3143
3102
 
3144
3103
                for (i = 0; i < prebuilt->n_template; i++) {
3145
3104
                        templ = prebuilt->mysql_template + i;
3146
 
#if 0 /* Some of the cached_rec may legitimately be uninitialized. */
3147
 
                        UNIV_MEM_ASSERT_RW(cached_rec
3148
 
                                           + templ->mysql_col_offset,
3149
 
                                           templ->mysql_col_len);
3150
 
#endif
3151
3105
                        ut_memcpy(buf + templ->mysql_col_offset,
3152
3106
                                  cached_rec + templ->mysql_col_offset,
3153
3107
                                  templ->mysql_col_len);
3162
3116
                }
3163
3117
        }
3164
3118
        else {
3165
 
#if 0 /* Some of the cached_rec may legitimately be uninitialized. */
3166
 
                UNIV_MEM_ASSERT_RW(prebuilt->fetch_cache
3167
 
                                   [prebuilt->fetch_cache_first],
3168
 
                                   prebuilt->mysql_prefix_len);
3169
 
#endif
3170
3119
                ut_memcpy(buf,
3171
3120
                          prebuilt->fetch_cache[prebuilt->fetch_cache_first],
3172
3121
                          prebuilt->mysql_prefix_len);
3180
3129
}
3181
3130
 
3182
3131
/********************************************************************//**
3183
 
Pushes a row for MySQL to the fetch cache.
3184
 
@return TRUE on success, FALSE if the record contains incomplete BLOBs */
 
3132
Pushes a row for MySQL to the fetch cache. */
3185
3133
UNIV_INLINE
3186
 
#ifdef __GNUC__
3187
 
__attribute__((warn_unused_result))
3188
 
#endif
3189
 
ibool
 
3134
void
3190
3135
row_sel_push_cache_row_for_mysql(
3191
3136
/*=============================*/
3192
3137
        row_prebuilt_t* prebuilt,       /*!< in: prebuilt struct */
3221
3166
        }
3222
3167
 
3223
3168
        ut_ad(prebuilt->fetch_cache_first == 0);
3224
 
        UNIV_MEM_INVALID(prebuilt->fetch_cache[prebuilt->n_fetch_cached],
3225
 
                         prebuilt->mysql_row_len);
3226
3169
 
3227
3170
        if (UNIV_UNLIKELY(!row_sel_store_mysql_rec(
3228
3171
                                  prebuilt->fetch_cache[
3229
3172
                                          prebuilt->n_fetch_cached],
3230
3173
                                  prebuilt, rec, offsets))) {
3231
 
                return(FALSE);
 
3174
                ut_error;
3232
3175
        }
3233
3176
 
3234
3177
        prebuilt->n_fetch_cached++;
3235
 
        return(TRUE);
3236
3178
}
3237
3179
 
3238
3180
/*********************************************************************//**
3260
3202
        ut_ad(dict_index_is_clust(index));
3261
3203
        ut_ad(!prebuilt->templ_contains_blob);
3262
3204
 
3263
 
#ifndef UNIV_SEARCH_DEBUG
3264
3205
        btr_pcur_open_with_no_init(index, search_tuple, PAGE_CUR_GE,
3265
3206
                                   BTR_SEARCH_LEAF, pcur,
 
3207
#ifndef UNIV_SEARCH_DEBUG
3266
3208
                                   RW_S_LATCH,
3267
 
                                   mtr);
3268
 
#else /* UNIV_SEARCH_DEBUG */
3269
 
        btr_pcur_open_with_no_init(index, search_tuple, PAGE_CUR_GE,
3270
 
                                   BTR_SEARCH_LEAF, pcur,
 
3209
#else
3271
3210
                                   0,
 
3211
#endif
3272
3212
                                   mtr);
3273
 
#endif /* UNIV_SEARCH_DEBUG */
3274
3213
        rec = btr_pcur_get_rec(pcur);
3275
3214
 
3276
3215
        if (!page_rec_is_user_rec(rec)) {
3370
3309
        mem_heap_t*     heap                            = NULL;
3371
3310
        ulint           offsets_[REC_OFFS_NORMAL_SIZE];
3372
3311
        ulint*          offsets                         = offsets_;
3373
 
        ibool           table_lock_waited               = FALSE;
3374
3312
 
3375
3313
        rec_offs_init(offsets_);
3376
3314
 
3601
3539
                                row_sel_try_search_shortcut_for_mysql().
3602
3540
                                The latch will not be released until
3603
3541
                                mtr_commit(&mtr). */
3604
 
                                ut_ad(!rec_get_deleted_flag(rec, comp));
3605
3542
 
3606
3543
                                if (!row_sel_store_mysql_rec(buf, prebuilt,
3607
3544
                                                             rec, offsets)) {
3608
 
                                        /* Only fresh inserts may contain
3609
 
                                        incomplete externally stored
3610
 
                                        columns. Pretend that such
3611
 
                                        records do not exist. Such
3612
 
                                        records may only be accessed
3613
 
                                        at the READ UNCOMMITTED
3614
 
                                        isolation level or when
3615
 
                                        rolling back a recovered
3616
 
                                        transaction. Rollback happens
3617
 
                                        at a lower level, not here. */
3618
 
                                        ut_a(trx->isolation_level
3619
 
                                             == TRX_ISO_READ_UNCOMMITTED);
 
3545
                                        err = DB_TOO_BIG_RECORD;
3620
3546
 
3621
 
                                        /* Proceed as in case SEL_RETRY. */
3622
 
                                        break;
 
3547
                                        /* We let the main loop to do the
 
3548
                                        error handling */
 
3549
                                        goto shortcut_fails_too_big_rec;
3623
3550
                                }
3624
3551
 
3625
3552
                                mtr_commit(&mtr);
3659
3586
                        default:
3660
3587
                                ut_ad(0);
3661
3588
                        }
3662
 
 
 
3589
shortcut_fails_too_big_rec:
3663
3590
                        mtr_commit(&mtr);
3664
3591
                        mtr_start(&mtr);
3665
3592
                }
3673
3600
                trx->has_search_latch = FALSE;
3674
3601
        }
3675
3602
 
3676
 
        ut_ad(prebuilt->sql_stat_start || trx->conc_state == TRX_ACTIVE);
3677
 
        ut_ad(trx->conc_state == TRX_NOT_STARTED
3678
 
              || trx->conc_state == TRX_ACTIVE);
3679
 
        ut_ad(prebuilt->sql_stat_start
3680
 
              || prebuilt->select_lock_type != LOCK_NONE
3681
 
              || trx->read_view);
3682
 
 
3683
 
        ut_ad(prebuilt->sql_stat_start || trx->conc_state == TRX_ACTIVE);
3684
 
        ut_ad(trx->conc_state == TRX_NOT_STARTED
3685
 
              || trx->conc_state == TRX_ACTIVE);
3686
 
        ut_ad(prebuilt->sql_stat_start
3687
 
              || prebuilt->select_lock_type != LOCK_NONE
3688
 
              || trx->read_view);
3689
 
 
3690
3603
        trx_start_if_not_started(trx);
3691
3604
 
3692
3605
        if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
3717
3630
 
3718
3631
        clust_index = dict_table_get_first_index(index->table);
3719
3632
 
3720
 
        /* Do some start-of-statement preparations */
3721
 
 
3722
 
        if (!prebuilt->sql_stat_start) {
3723
 
                /* No need to set an intention lock or assign a read view */
3724
 
 
3725
 
                if (trx->read_view == NULL
3726
 
                    && prebuilt->select_lock_type == LOCK_NONE) {
3727
 
 
3728
 
                        fputs("InnoDB: Error: MySQL is trying to"
3729
 
                              " perform a consistent read\n"
3730
 
                              "InnoDB: but the read view is not assigned!\n",
3731
 
                              stderr);
3732
 
                        trx_print(stderr, trx, 600);
3733
 
                        fputc('\n', stderr);
3734
 
                        ut_error;
3735
 
                }
3736
 
        } else if (prebuilt->select_lock_type == LOCK_NONE) {
3737
 
                /* This is a consistent read */
3738
 
                /* Assign a read view for the query */
3739
 
 
3740
 
                trx_assign_read_view(trx);
3741
 
                prebuilt->sql_stat_start = FALSE;
3742
 
        } else {
3743
 
wait_table_again:
3744
 
                err = lock_table(0, index->table,
3745
 
                                 prebuilt->select_lock_type == LOCK_S
3746
 
                                 ? LOCK_IS : LOCK_IX, thr);
3747
 
 
3748
 
                if (err != DB_SUCCESS) {
3749
 
 
3750
 
                        table_lock_waited = TRUE;
3751
 
                        goto lock_table_wait;
3752
 
                }
3753
 
                prebuilt->sql_stat_start = FALSE;
3754
 
        }
3755
 
 
3756
 
        /* Open or restore index cursor position */
3757
 
 
3758
3633
        if (UNIV_LIKELY(direction != 0)) {
3759
3634
                ibool   need_to_process = sel_restore_position_for_mysql(
3760
3635
                        &same_user_rec, BTR_SEARCH_LEAF,
3795
3670
                    && !page_rec_is_supremum(rec)
3796
3671
                    && set_also_gap_locks
3797
3672
                    && !(srv_locks_unsafe_for_binlog
3798
 
                         || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
 
3673
                         || trx->isolation_level == TRX_ISO_READ_COMMITTED)
3799
3674
                    && prebuilt->select_lock_type != LOCK_NONE) {
3800
3675
 
3801
3676
                        /* Try to place a gap lock on the next index record
3809
3684
                                               prebuilt->select_lock_type,
3810
3685
                                               LOCK_GAP, thr);
3811
3686
 
3812
 
                        switch (err) {
3813
 
                        case DB_SUCCESS_LOCKED_REC:
3814
 
                                err = DB_SUCCESS;
3815
 
                        case DB_SUCCESS:
3816
 
                                break;
3817
 
                        default:
 
3687
                        if (err != DB_SUCCESS) {
 
3688
 
3818
3689
                                goto lock_wait_or_error;
3819
3690
                        }
3820
3691
                }
3830
3701
                }
3831
3702
        }
3832
3703
 
 
3704
        if (!prebuilt->sql_stat_start) {
 
3705
                /* No need to set an intention lock or assign a read view */
 
3706
 
 
3707
                if (trx->read_view == NULL
 
3708
                    && prebuilt->select_lock_type == LOCK_NONE) {
 
3709
 
 
3710
                        fputs("InnoDB: Error: MySQL is trying to"
 
3711
                              " perform a consistent read\n"
 
3712
                              "InnoDB: but the read view is not assigned!\n",
 
3713
                              stderr);
 
3714
                        trx_print(stderr, trx, 600);
 
3715
                        fputc('\n', stderr);
 
3716
                        ut_a(0);
 
3717
                }
 
3718
        } else if (prebuilt->select_lock_type == LOCK_NONE) {
 
3719
                /* This is a consistent read */
 
3720
                /* Assign a read view for the query */
 
3721
 
 
3722
                trx_assign_read_view(trx);
 
3723
                prebuilt->sql_stat_start = FALSE;
 
3724
        } else {
 
3725
                ulint   lock_mode;
 
3726
                if (prebuilt->select_lock_type == LOCK_S) {
 
3727
                        lock_mode = LOCK_IS;
 
3728
                } else {
 
3729
                        lock_mode = LOCK_IX;
 
3730
                }
 
3731
                err = lock_table(0, index->table, lock_mode, thr);
 
3732
 
 
3733
                if (err != DB_SUCCESS) {
 
3734
 
 
3735
                        goto lock_wait_or_error;
 
3736
                }
 
3737
                prebuilt->sql_stat_start = FALSE;
 
3738
        }
 
3739
 
3833
3740
rec_loop:
3834
3741
        /*-------------------------------------------------------------*/
3835
3742
        /* PHASE 4: Look for matching records in a loop */
3859
3766
 
3860
3767
                if (set_also_gap_locks
3861
3768
                    && !(srv_locks_unsafe_for_binlog
3862
 
                         || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
 
3769
                         || trx->isolation_level == TRX_ISO_READ_COMMITTED)
3863
3770
                    && prebuilt->select_lock_type != LOCK_NONE) {
3864
3771
 
3865
3772
                        /* Try to place a lock on the index record */
3876
3783
                                               prebuilt->select_lock_type,
3877
3784
                                               LOCK_ORDINARY, thr);
3878
3785
 
3879
 
                        switch (err) {
3880
 
                        case DB_SUCCESS_LOCKED_REC:
3881
 
                                err = DB_SUCCESS;
3882
 
                        case DB_SUCCESS:
3883
 
                                break;
3884
 
                        default:
 
3786
                        if (err != DB_SUCCESS) {
 
3787
 
3885
3788
                                goto lock_wait_or_error;
3886
3789
                        }
3887
3790
                }
3997
3900
                        if (set_also_gap_locks
3998
3901
                            && !(srv_locks_unsafe_for_binlog
3999
3902
                                 || trx->isolation_level
4000
 
                                 <= TRX_ISO_READ_COMMITTED)
 
3903
                                 == TRX_ISO_READ_COMMITTED)
4001
3904
                            && prebuilt->select_lock_type != LOCK_NONE) {
4002
3905
 
4003
3906
                                /* Try to place a gap lock on the index
4011
3914
                                        prebuilt->select_lock_type, LOCK_GAP,
4012
3915
                                        thr);
4013
3916
 
4014
 
                                switch (err) {
4015
 
                                case DB_SUCCESS_LOCKED_REC:
4016
 
                                case DB_SUCCESS:
4017
 
                                        break;
4018
 
                                default:
 
3917
                                if (err != DB_SUCCESS) {
 
3918
 
4019
3919
                                        goto lock_wait_or_error;
4020
3920
                                }
4021
3921
                        }
4036
3936
                        if (set_also_gap_locks
4037
3937
                            && !(srv_locks_unsafe_for_binlog
4038
3938
                                 || trx->isolation_level
4039
 
                                 <= TRX_ISO_READ_COMMITTED)
 
3939
                                 == TRX_ISO_READ_COMMITTED)
4040
3940
                            && prebuilt->select_lock_type != LOCK_NONE) {
4041
3941
 
4042
3942
                                /* Try to place a gap lock on the index
4050
3950
                                        prebuilt->select_lock_type, LOCK_GAP,
4051
3951
                                        thr);
4052
3952
 
4053
 
                                switch (err) {
4054
 
                                case DB_SUCCESS_LOCKED_REC:
4055
 
                                case DB_SUCCESS:
4056
 
                                        break;
4057
 
                                default:
 
3953
                                if (err != DB_SUCCESS) {
 
3954
 
4058
3955
                                        goto lock_wait_or_error;
4059
3956
                                }
4060
3957
                        }
4087
3984
 
4088
3985
                if (!set_also_gap_locks
4089
3986
                    || srv_locks_unsafe_for_binlog
4090
 
                    || trx->isolation_level <= TRX_ISO_READ_COMMITTED
 
3987
                    || trx->isolation_level == TRX_ISO_READ_COMMITTED
4091
3988
                    || (unique_search
4092
3989
                        && !UNIV_UNLIKELY(rec_get_deleted_flag(rec, comp)))) {
4093
3990
 
4124
4021
 
4125
4022
                switch (err) {
4126
4023
                        const rec_t*    old_vers;
4127
 
                case DB_SUCCESS_LOCKED_REC:
 
4024
                case DB_SUCCESS:
4128
4025
                        if (srv_locks_unsafe_for_binlog
4129
 
                            || trx->isolation_level
4130
 
                            <= TRX_ISO_READ_COMMITTED) {
 
4026
                            || trx->isolation_level == TRX_ISO_READ_COMMITTED) {
4131
4027
                                /* Note that a record of
4132
4028
                                prebuilt->index was locked. */
4133
4029
                                prebuilt->new_rec_locks = 1;
4134
4030
                        }
4135
 
                        err = DB_SUCCESS;
4136
 
                case DB_SUCCESS:
4137
4031
                        break;
4138
4032
                case DB_LOCK_WAIT:
4139
 
                        /* Never unlock rows that were part of a conflict. */
4140
 
                        prebuilt->new_rec_locks = 0;
4141
 
 
4142
4033
                        if (UNIV_LIKELY(prebuilt->row_read_type
4143
4034
                                        != ROW_READ_TRY_SEMI_CONSISTENT)
4144
 
                            || unique_search
4145
4035
                            || index != clust_index) {
4146
4036
 
4147
4037
                                goto lock_wait_or_error;
4153
4043
                                clust_index, prebuilt, rec,
4154
4044
                                &offsets, &heap, &old_vers, &mtr);
4155
4045
 
4156
 
                        switch (err) {
4157
 
                        case DB_SUCCESS_LOCKED_REC:
4158
 
                                err = DB_SUCCESS;
4159
 
                        case DB_SUCCESS:
4160
 
                                break;
4161
 
                        default:
 
4046
                        if (err != DB_SUCCESS) {
 
4047
 
4162
4048
                                goto lock_wait_or_error;
4163
4049
                        }
4164
4050
 
4172
4058
                        if (UNIV_LIKELY(trx->wait_lock != NULL)) {
4173
4059
                                lock_cancel_waiting_and_release(
4174
4060
                                        trx->wait_lock);
 
4061
                                prebuilt->new_rec_locks = 0;
4175
4062
                        } else {
4176
4063
                                mutex_exit(&kernel_mutex);
4177
4064
 
4183
4070
                                                          ULINT_UNDEFINED,
4184
4071
                                                          &heap);
4185
4072
                                err = DB_SUCCESS;
 
4073
                                /* Note that a record of
 
4074
                                prebuilt->index was locked. */
 
4075
                                prebuilt->new_rec_locks = 1;
4186
4076
                                break;
4187
4077
                        }
4188
4078
                        mutex_exit(&kernel_mutex);
4228
4118
                                        prebuilt, rec, &offsets, &heap,
4229
4119
                                        &old_vers, &mtr);
4230
4120
 
4231
 
                                switch (err) {
4232
 
                                case DB_SUCCESS_LOCKED_REC:
4233
 
                                case DB_SUCCESS:
4234
 
                                        break;
4235
 
                                default:
 
4121
                                if (err != DB_SUCCESS) {
 
4122
 
4236
4123
                                        goto lock_wait_or_error;
4237
4124
                                }
4238
4125
 
4245
4132
 
4246
4133
                                rec = old_vers;
4247
4134
                        }
4248
 
                } else {
 
4135
                } else if (!lock_sec_rec_cons_read_sees(rec, trx->read_view)) {
4249
4136
                        /* We are looking into a non-clustered index,
4250
4137
                        and to get the right version of the record we
4251
4138
                        have to look also into the clustered index: this
4253
4140
                        information via the clustered index record. */
4254
4141
 
4255
4142
                        ut_ad(index != clust_index);
4256
 
                        ut_ad(!dict_index_is_clust(index));
4257
 
                        if (!lock_sec_rec_cons_read_sees(
4258
 
                                    rec, trx->read_view)) {
4259
 
                                goto requires_clust_rec;
4260
 
                        }
 
4143
                        goto requires_clust_rec;
4261
4144
                }
4262
4145
        }
4263
4146
 
4271
4154
                /* The record is delete-marked: we can skip it */
4272
4155
 
4273
4156
                if ((srv_locks_unsafe_for_binlog
4274
 
                     || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
 
4157
                     || trx->isolation_level == TRX_ISO_READ_COMMITTED)
4275
4158
                    && prebuilt->select_lock_type != LOCK_NONE
4276
4159
                    && !did_semi_consistent_read) {
4277
4160
 
4325
4208
                err = row_sel_get_clust_rec_for_mysql(prebuilt, index, rec,
4326
4209
                                                      thr, &clust_rec,
4327
4210
                                                      &offsets, &heap, &mtr);
4328
 
                switch (err) {
4329
 
                case DB_SUCCESS:
4330
 
                        if (clust_rec == NULL) {
4331
 
                                /* The record did not exist in the read view */
4332
 
                                ut_ad(prebuilt->select_lock_type == LOCK_NONE);
 
4211
                if (err != DB_SUCCESS) {
4333
4212
 
4334
 
                                goto next_rec;
4335
 
                        }
4336
 
                        break;
4337
 
                case DB_SUCCESS_LOCKED_REC:
4338
 
                        ut_a(clust_rec != NULL);
4339
 
                        if (srv_locks_unsafe_for_binlog
4340
 
                             || trx->isolation_level
4341
 
                            <= TRX_ISO_READ_COMMITTED) {
4342
 
                                /* Note that the clustered index record
4343
 
                                was locked. */
4344
 
                                prebuilt->new_rec_locks = 2;
4345
 
                        }
4346
 
                        err = DB_SUCCESS;
4347
 
                        break;
4348
 
                default:
4349
4213
                        goto lock_wait_or_error;
4350
4214
                }
4351
4215
 
 
4216
                if (clust_rec == NULL) {
 
4217
                        /* The record did not exist in the read view */
 
4218
                        ut_ad(prebuilt->select_lock_type == LOCK_NONE);
 
4219
 
 
4220
                        goto next_rec;
 
4221
                }
 
4222
 
 
4223
                if ((srv_locks_unsafe_for_binlog
 
4224
                     || trx->isolation_level == TRX_ISO_READ_COMMITTED)
 
4225
                    && prebuilt->select_lock_type != LOCK_NONE) {
 
4226
                        /* Note that both the secondary index record
 
4227
                        and the clustered index record were locked. */
 
4228
                        ut_ad(prebuilt->new_rec_locks == 1);
 
4229
                        prebuilt->new_rec_locks = 2;
 
4230
                }
 
4231
 
4352
4232
                if (UNIV_UNLIKELY(rec_get_deleted_flag(clust_rec, comp))) {
4353
4233
 
4354
4234
                        /* The record is delete marked: we can skip it */
4355
4235
 
4356
4236
                        if ((srv_locks_unsafe_for_binlog
4357
 
                             || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
 
4237
                             || trx->isolation_level == TRX_ISO_READ_COMMITTED)
4358
4238
                            && prebuilt->select_lock_type != LOCK_NONE) {
4359
4239
 
4360
4240
                                /* No need to keep a lock on a delete-marked
4380
4260
                                                  ULINT_UNDEFINED, &heap);
4381
4261
                        result_rec = rec;
4382
4262
                }
4383
 
 
4384
 
                /* result_rec can legitimately be delete-marked
4385
 
                now that it has been established that it points to a
4386
 
                clustered index record that exists in the read view. */
4387
4263
        } else {
4388
4264
                result_rec = rec;
4389
 
                ut_ad(!rec_get_deleted_flag(rec, comp));
4390
4265
        }
4391
4266
 
4392
4267
        /* We found a qualifying record 'result_rec'. At this point,
4417
4292
                not cache rows because there the cursor is a scrollable
4418
4293
                cursor. */
4419
4294
 
4420
 
                if (!row_sel_push_cache_row_for_mysql(prebuilt, result_rec,
4421
 
                                                      offsets)) {
4422
 
                        /* Only fresh inserts may contain incomplete
4423
 
                        externally stored columns. Pretend that such
4424
 
                        records do not exist. Such records may only be
4425
 
                        accessed at the READ UNCOMMITTED isolation
4426
 
                        level or when rolling back a recovered
4427
 
                        transaction. Rollback happens at a lower
4428
 
                        level, not here. */
4429
 
                        ut_a(trx->isolation_level == TRX_ISO_READ_UNCOMMITTED);
4430
 
                } else if (prebuilt->n_fetch_cached
4431
 
                           == MYSQL_FETCH_CACHE_SIZE) {
 
4295
                row_sel_push_cache_row_for_mysql(prebuilt, result_rec,
 
4296
                                                 offsets);
 
4297
                if (prebuilt->n_fetch_cached == MYSQL_FETCH_CACHE_SIZE) {
4432
4298
 
4433
4299
                        goto got_row;
4434
4300
                }
4444
4310
                } else {
4445
4311
                        if (!row_sel_store_mysql_rec(buf, prebuilt,
4446
4312
                                                     result_rec, offsets)) {
4447
 
                                /* Only fresh inserts may contain
4448
 
                                incomplete externally stored
4449
 
                                columns. Pretend that such records do
4450
 
                                not exist. Such records may only be
4451
 
                                accessed at the READ UNCOMMITTED
4452
 
                                isolation level or when rolling back a
4453
 
                                recovered transaction. Rollback
4454
 
                                happens at a lower level, not here. */
4455
 
                                ut_a(trx->isolation_level
4456
 
                                     == TRX_ISO_READ_UNCOMMITTED);
4457
 
                                goto next_rec;
 
4313
                                err = DB_TOO_BIG_RECORD;
 
4314
 
 
4315
                                goto lock_wait_or_error;
4458
4316
                        }
4459
4317
                }
4460
4318
 
4563
4421
 
4564
4422
        btr_pcur_store_position(pcur, &mtr);
4565
4423
 
4566
 
lock_table_wait:
4567
4424
        mtr_commit(&mtr);
4568
4425
        mtr_has_extra_clust_latch = FALSE;
4569
4426
 
4581
4438
                thr->lock_state = QUE_THR_LOCK_NOLOCK;
4582
4439
                mtr_start(&mtr);
4583
4440
 
4584
 
                /* Table lock waited, go try to obtain table lock
4585
 
                again */
4586
 
                if (table_lock_waited) {
4587
 
                        table_lock_waited = FALSE;
4588
 
 
4589
 
                        goto wait_table_again;
4590
 
                }
4591
 
 
4592
4441
                sel_restore_position_for_mysql(&same_user_rec,
4593
4442
                                               BTR_SEARCH_LEAF, pcur,
4594
4443
                                               moves_up, &mtr);
4595
4444
 
4596
4445
                if ((srv_locks_unsafe_for_binlog
4597
 
                     || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
 
4446
                     || trx->isolation_level == TRX_ISO_READ_COMMITTED)
4598
4447
                    && !same_user_rec) {
4599
4448
 
4600
4449
                        /* Since we were not able to restore the cursor
4707
4556
        IX type locks actually would require ret = FALSE. */
4708
4557
 
4709
4558
        if (UT_LIST_GET_LEN(table->locks) == 0
4710
 
            && trx->id >= table->query_cache_inv_trx_id) {
 
4559
            && ut_dulint_cmp(trx->id,
 
4560
                             table->query_cache_inv_trx_id) >= 0) {
4711
4561
 
4712
4562
                ret = TRUE;
4713
4563
 
4739
4589
        dict_index_t*   index,          /*!< in: index to read from */
4740
4590
        const rec_t*    rec,            /*!< in: current rec */
4741
4591
        ulint           col_no,         /*!< in: column number */
4742
 
        ulint           mtype,          /*!< in: column main type */
4743
4592
        ibool           unsigned_type)  /*!< in: signed or unsigned flag */
4744
4593
{
4745
4594
        ulint           len;
4756
4605
        data = rec_get_nth_field(rec, offsets, col_no, &len);
4757
4606
 
4758
4607
        ut_a(len != UNIV_SQL_NULL);
4759
 
 
4760
 
        switch (mtype) {
4761
 
        case DATA_INT:
4762
 
                ut_a(len <= sizeof value);
4763
 
                value = mach_read_int_type(data, len, unsigned_type);
4764
 
                break;
4765
 
 
4766
 
        case DATA_FLOAT:
4767
 
                ut_a(len == sizeof(float));
4768
 
                value = (ib_uint64_t) mach_float_read(data);
4769
 
                break;
4770
 
 
4771
 
        case DATA_DOUBLE:
4772
 
                ut_a(len == sizeof(double));
4773
 
                value = (ib_uint64_t) mach_double_read(data);
4774
 
                break;
4775
 
 
4776
 
        default:
4777
 
                ut_error;
4778
 
        }
 
4608
        ut_a(len <= sizeof value);
 
4609
 
 
4610
        /* we assume AUTOINC value cannot be negative */
 
4611
        value = mach_read_int_type(data, len, unsigned_type);
4779
4612
 
4780
4613
        if (UNIV_LIKELY_NULL(heap)) {
4781
4614
                mem_heap_free(heap);
4861
4694
                                        dfield->col->prtype & DATA_UNSIGNED);
4862
4695
 
4863
4696
                                *value = row_search_autoinc_read_column(
4864
 
                                        index, rec, i,
4865
 
                                        dfield->col->mtype, unsigned_type);
 
4697
                                        index, rec, i, unsigned_type);
4866
4698
                        }
4867
4699
                }
4868
4700