Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
d36bd697
Commit
d36bd697
authored
Jul 29, 2017
by
Vicențiu Ciorbaru
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
5.6.37
parent
0af98182
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
176 additions
and
52 deletions
+176
-52
storage/innobase/api/api0api.cc
storage/innobase/api/api0api.cc
+17
-4
storage/innobase/handler/ha_innodb.cc
storage/innobase/handler/ha_innodb.cc
+21
-0
storage/innobase/handler/ha_innodb.h
storage/innobase/handler/ha_innodb.h
+5
-1
storage/innobase/include/row0mysql.h
storage/innobase/include/row0mysql.h
+6
-1
storage/innobase/include/row0sel.h
storage/innobase/include/row0sel.h
+13
-1
storage/innobase/row/row0merge.cc
storage/innobase/row/row0merge.cc
+3
-3
storage/innobase/row/row0sel.cc
storage/innobase/row/row0sel.cc
+111
-42
No files found.
storage/innobase/api/api0api.cc
View file @
d36bd697
/*****************************************************************************
Copyright (c) 2008, 201
5
, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 201
7
, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
...
...
@@ -1976,11 +1976,14 @@ ib_cursor_read_row(
page_format
=
static_cast
<
ib_bool_t
>
(
dict_table_is_comp
(
tuple
->
index
->
table
));
rec
=
btr_pcur_get_rec
(
pcur
);
if
(
prebuilt
->
innodb_api_rec
&&
prebuilt
->
innodb_api_rec
!=
rec
)
{
rec
=
prebuilt
->
innodb_api_rec
;
if
(
!
rec_get_deleted_flag
(
rec
,
page_format
))
{
if
(
prebuilt
->
innodb_api
&&
prebuilt
->
innodb_api_rec
!=
NULL
)
{
rec
=
prebuilt
->
innodb_api_rec
;
}
}
if
(
!
rec_get_deleted_flag
(
rec
,
page_format
))
{
...
...
@@ -2017,6 +2020,10 @@ ib_cursor_position(
buf
=
static_cast
<
unsigned
char
*>
(
mem_alloc
(
UNIV_PAGE_SIZE
));
if
(
prebuilt
->
innodb_api
)
{
prebuilt
->
cursor_heap
=
cursor
->
heap
;
}
/* We want to position at one of the ends, row_search_for_mysql()
uses the search_tuple fields to work out what to do. */
dtuple_set_n_fields
(
prebuilt
->
search_tuple
,
0
);
...
...
@@ -2071,6 +2078,9 @@ ib_cursor_next(
row_prebuilt_t
*
prebuilt
=
cursor
->
prebuilt
;
byte
buf
[
UNIV_PAGE_SIZE_MAX
];
if
(
prebuilt
->
innodb_api
)
{
prebuilt
->
cursor_heap
=
cursor
->
heap
;
}
/* We want to move to the next record */
dtuple_set_n_fields
(
prebuilt
->
search_tuple
,
0
);
...
...
@@ -2123,6 +2133,9 @@ ib_cursor_moveto(
buf
=
static_cast
<
unsigned
char
*>
(
mem_alloc
(
UNIV_PAGE_SIZE
));
if
(
prebuilt
->
innodb_api
)
{
prebuilt
->
cursor_heap
=
cursor
->
heap
;
}
err
=
static_cast
<
ib_err_t
>
(
row_search_for_mysql
(
buf
,
ib_srch_mode
,
prebuilt
,
cursor
->
match_mode
,
0
));
...
...
storage/innobase/handler/ha_innodb.cc
View file @
d36bd697
...
...
@@ -8321,6 +8321,27 @@ ha_innobase::ft_init_ext(
return
((
FT_INFO
*
)
fts_hdl
);
}
/*****************************************************************//**
Copy a cached MySQL row.
If requested, also avoids overwriting non-read columns.
@param[out] buf Row in MySQL format.
@param[in] cached_row Which row to copy.
@param[in] rec_len Record length. */
void
ha_innobase
::
copy_cached_row
(
uchar
*
buf
,
const
uchar
*
cached_row
,
uint
rec_len
)
{
if
(
prebuilt
->
keep_other_fields_on_keyread
)
{
row_sel_copy_cached_fields_for_mysql
(
buf
,
cached_row
,
prebuilt
);
}
else
{
memcpy
(
buf
,
cached_row
,
rec_len
);
}
}
/*****************************************************************//**
Set up search tuple for a query through FTS_DOC_ID_INDEX on
supplied Doc ID. This is used by MySQL to retrieve the documents
...
...
storage/innobase/handler/ha_innodb.h
View file @
d36bd697
/*****************************************************************************
Copyright (c) 2000, 201
6
, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2000, 201
7
, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
...
...
@@ -142,6 +142,10 @@ class ha_innobase: public handler
int
index_first
(
uchar
*
buf
);
int
index_last
(
uchar
*
buf
);
/* Copy a cached MySQL row. If requested, also avoids
overwriting non-read columns. */
void
copy_cached_row
(
uchar
*
to_rec
,
const
uchar
*
from_rec
,
uint
rec_length
);
int
rnd_init
(
bool
scan
);
int
rnd_end
();
int
rnd_next
(
uchar
*
buf
);
...
...
storage/innobase/include/row0mysql.h
View file @
d36bd697
/*****************************************************************************
Copyright (c) 2000, 201
6
, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2000, 201
7
, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
...
...
@@ -723,6 +723,8 @@ struct row_prebuilt_t {
mem_heap_t
*
heap
;
/*!< memory heap from which
these auxiliary structures are
allocated when needed */
mem_heap_t
*
cursor_heap
;
/*!< memory heap from which
innodb_api_buf is allocated per session*/
ins_node_t
*
ins_node
;
/*!< Innobase SQL insert node
used to perform inserts
to the table */
...
...
@@ -873,6 +875,9 @@ struct row_prebuilt_t {
unsigned
innodb_api
:
1
;
/*!< whether this is a InnoDB API
query */
const
rec_t
*
innodb_api_rec
;
/*!< InnoDB API search result */
void
*
innodb_api_buf
;
/*!< Buffer holding copy of the physical
Innodb API search record */
ulint
innodb_api_rec_size
;
/*!< Size of the Innodb API record */
byte
*
srch_key_val1
;
/*!< buffer used in converting
search key values from MySQL format
to InnoDB format.*/
...
...
storage/innobase/include/row0sel.h
View file @
d36bd697
/*****************************************************************************
Copyright (c) 1997, 201
6
, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1997, 201
7
, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
...
...
@@ -205,6 +205,18 @@ struct sel_buf_t{
when data != NULL */
};
/** Copy used fields from cached row.
Copy cache record field by field, don't touch fields that
are not covered by current key.
@param[out] buf Where to copy the MySQL row.
@param[in] cached_rec What to copy (in MySQL row format).
@param[in] prebuilt prebuilt struct. */
void
row_sel_copy_cached_fields_for_mysql
(
byte
*
buf
,
const
byte
*
cached_rec
,
row_prebuilt_t
*
prebuilt
);
/** Query plan */
struct
plan_t
{
dict_table_t
*
table
;
/*!< table struct in the dictionary
...
...
storage/innobase/row/row0merge.cc
View file @
d36bd697
/*****************************************************************************
Copyright (c) 2005, 201
6
, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2005, 201
7
, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
...
...
@@ -1462,6 +1462,8 @@ row_merge_read_clustered_index(
row_ext_t
*
ext
;
page_cur_t
*
cur
=
btr_pcur_get_page_cur
(
&
pcur
);
mem_heap_empty
(
row_heap
);
page_cur_move_to_next
(
cur
);
if
(
page_cur_is_after_last
(
cur
))
{
...
...
@@ -1885,8 +1887,6 @@ row_merge_read_clustered_index(
if
(
err
!=
DB_SUCCESS
)
{
goto
func_exit
;
}
mem_heap_empty
(
row_heap
);
}
func_exit:
...
...
storage/innobase/row/row0sel.cc
View file @
d36bd697
/*****************************************************************************
Copyright (c) 1997, 201
6
, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1997, 201
7
, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
...
...
@@ -2555,47 +2555,51 @@ row_sel_store_row_id_to_prebuilt(
#ifdef UNIV_DEBUG
/** Convert a non-SQL-NULL field from Innobase format to MySQL format. */
# define row_sel_field_store_in_mysql_format(dest,templ,idx,field,src,len) \
row_sel_field_store_in_mysql_format_func(dest,templ,idx,field,src,len)
# define row_sel_field_store_in_mysql_format(dest,templ,idx,field,src,len
,sec
) \
row_sel_field_store_in_mysql_format_func(dest,templ,idx,field,src,len
,sec
)
#else
/* UNIV_DEBUG */
/** Convert a non-SQL-NULL field from Innobase format to MySQL format. */
# define row_sel_field_store_in_mysql_format(dest,templ,idx,field,src,len) \
row_sel_field_store_in_mysql_format_func(dest,templ,src,len)
# define row_sel_field_store_in_mysql_format(dest,templ,idx,field,src,len
,sec
) \
row_sel_field_store_in_mysql_format_func(dest,templ,src,len
,sec
)
#endif
/* UNIV_DEBUG */
/**************************************************************//**
Stores a non-SQL-NULL field in the MySQL format. The counterpart of this
function is row_mysql_store_col_in_innobase_format() in row0mysql.cc. */
/** Stores a non-SQL-NULL field in the MySQL format. The counterpart of this
function is row_mysql_store_col_in_innobase_format() in row0mysql.cc.
@param[in,out] dest buffer where to store; NOTE
that BLOBs are not in themselves stored
here: the caller must allocate and copy
the BLOB into buffer before, and pass
the pointer to the BLOB in 'data'
@param[in] templ MySQL column template. Its following fields
are referenced: type, is_unsigned, mysql_col_len,
mbminlen, mbmaxlen
@param[in] index InnoDB index
@param[in] field_no templ->rec_field_no or templ->clust_rec_field_no
or templ->icp_rec_field_no
@param[in] data data to store
@param[in] len length of the data
@param[in] sec_field secondary index field no if the secondary index
record but the prebuilt template is in
clustered index format and used only for end
range comparison. */
static
MY_ATTRIBUTE
((
nonnull
))
void
row_sel_field_store_in_mysql_format_func
(
/*=====================================*/
byte
*
dest
,
/*!< in/out: buffer where to store; NOTE
that BLOBs are not in themselves
stored here: the caller must allocate
and copy the BLOB into buffer before,
and pass the pointer to the BLOB in
'data' */
byte
*
dest
,
const
mysql_row_templ_t
*
templ
,
/*!< in: MySQL column template.
Its following fields are referenced:
type, is_unsigned, mysql_col_len,
mbminlen, mbmaxlen */
#ifdef UNIV_DEBUG
const
dict_index_t
*
index
,
/*!< in: InnoDB index */
ulint
field_no
,
/*!< in: templ->rec_field_no or
templ->clust_rec_field_no or
templ->icp_rec_field_no */
#endif
/* UNIV_DEBUG */
const
byte
*
data
,
/*!< in: data to store */
ulint
len
)
/*!< in: length of the data */
const
byte
*
data
,
ulint
len
,
ulint
sec_field
)
{
byte
*
ptr
;
#ifdef UNIV_DEBUG
const
dict_field_t
*
field
=
dict_index_get_nth_field
(
index
,
field_no
);
bool
clust_templ_for_sec
=
(
sec_field
!=
ULINT_UNDEFINED
);
#endif
/* UNIV_DEBUG */
ut_ad
(
len
!=
UNIV_SQL_NULL
);
...
...
@@ -2709,7 +2713,8 @@ row_sel_field_store_in_mysql_format_func(
containing UTF-8 ENUM columns due to Bug #9526. */
ut_ad
(
!
templ
->
mbmaxlen
||
!
(
templ
->
mysql_col_len
%
templ
->
mbmaxlen
));
ut_ad
(
len
*
templ
->
mbmaxlen
>=
templ
->
mysql_col_len
ut_ad
(
clust_templ_for_sec
||
len
*
templ
->
mbmaxlen
>=
templ
->
mysql_col_len
||
(
field_no
==
templ
->
icp_rec_field_no
&&
field
->
prefix_len
>
0
));
ut_ad
(
!
(
field
->
prefix_len
%
templ
->
mbmaxlen
));
...
...
@@ -2737,21 +2742,26 @@ row_sel_field_store_in_mysql_format_func(
case
DATA_DECIMAL
:
/* Above are the valid column types for MySQL data. */
#endif
/* UNIV_DEBUG */
/* If sec_field value is present then mapping of
secondary index records to clustered index template
happens for end range comparison. So length can
vary according to secondary index record length. */
ut_ad
(
field
->
prefix_len
?
field
->
prefix_len
==
len
:
templ
->
mysql_col_len
==
len
);
:
(
clust_templ_for_sec
?
1
:
(
templ
->
mysql_col_len
==
len
)));
memcpy
(
dest
,
data
,
len
);
}
}
#ifdef UNIV_DEBUG
/** Convert a field from Innobase format to MySQL format. */
# define row_sel_store_mysql_field(m,p,r,i,o,f,t,
c
) \
row_sel_store_mysql_field_func(m,p,r,i,o,f,t,
c
)
# define row_sel_store_mysql_field(m,p,r,i,o,f,t,
s
) \
row_sel_store_mysql_field_func(m,p,r,i,o,f,t,
s
)
#else
/* UNIV_DEBUG */
/** Convert a field from Innobase format to MySQL format. */
# define row_sel_store_mysql_field(m,p,r,i,o,f,t,
c
) \
row_sel_store_mysql_field_func(m,p,r,o,f,t,
c
)
# define row_sel_store_mysql_field(m,p,r,i,o,f,t,
s
) \
row_sel_store_mysql_field_func(m,p,r,o,f,t,
s
)
#endif
/* UNIV_DEBUG */
/** Convert a field in the Innobase format to a field in the MySQL format.
@param[out] mysql_rec record in the MySQL format
...
...
@@ -2766,7 +2776,7 @@ row_sel_field_store_in_mysql_format_func(
or sec field no if clust_templ_for_sec
is TRUE
@param[in] templ row template
@param[in]
clust_templ_for_sec TRUE
if rec belongs to secondary index
@param[in]
sec_field_no field_no
if rec belongs to secondary index
but prebuilt template is in clustered
index format and used only for end
range comparison. */
...
...
@@ -2782,10 +2792,12 @@ row_sel_store_mysql_field_func(
const
ulint
*
offsets
,
ulint
field_no
,
const
mysql_row_templ_t
*
templ
,
bool
clust_templ_for_sec
)
ulint
sec_field_no
)
{
const
byte
*
data
;
ulint
len
;
ulint
clust_field_no
;
bool
clust_templ_for_sec
=
(
sec_field_no
!=
ULINT_UNDEFINED
);
ut_ad
(
prebuilt
->
default_rec
);
ut_ad
(
templ
);
...
...
@@ -2796,7 +2808,14 @@ row_sel_store_mysql_field_func(
||
field_no
==
templ
->
rec_field_no
||
field_no
==
templ
->
icp_rec_field_no
);
ut_ad
(
rec_offs_validate
(
rec
,
clust_templ_for_sec
==
true
?
prebuilt
->
index
:
index
,
offsets
));
clust_templ_for_sec
?
prebuilt
->
index
:
index
,
offsets
));
/* If sec_field_no is present then extract the data from record
using secondary field no. */
if
(
clust_templ_for_sec
)
{
clust_field_no
=
field_no
;
field_no
=
sec_field_no
;
}
if
(
UNIV_UNLIKELY
(
rec_offs_nth_extern
(
offsets
,
field_no
)))
{
...
...
@@ -2845,7 +2864,8 @@ row_sel_store_mysql_field_func(
row_sel_field_store_in_mysql_format
(
mysql_rec
+
templ
->
mysql_col_offset
,
templ
,
index
,
field_no
,
data
,
len
);
templ
,
index
,
field_no
,
data
,
len
,
ULINT_UNDEFINED
);
if
(
heap
!=
prebuilt
->
blob_heap
)
{
mem_heap_free
(
heap
);
...
...
@@ -2893,9 +2913,14 @@ row_sel_store_mysql_field_func(
mem_heap_dup
(
prebuilt
->
blob_heap
,
data
,
len
));
}
/* Reassign the clustered index field no. */
if
(
clust_templ_for_sec
)
{
field_no
=
clust_field_no
;
}
row_sel_field_store_in_mysql_format
(
mysql_rec
+
templ
->
mysql_col_offset
,
templ
,
index
,
field_no
,
data
,
len
);
templ
,
index
,
field_no
,
data
,
len
,
sec_field_no
);
}
ut_ad
(
len
!=
UNIV_SQL_NULL
);
...
...
@@ -2967,6 +2992,8 @@ row_sel_store_mysql_rec(
=
rec_clust
?
templ
->
clust_rec_field_no
:
templ
->
rec_field_no
;
ulint
sec_field_no
=
ULINT_UNDEFINED
;
/* We should never deliver column prefixes to MySQL,
except for evaluating innobase_index_cond(). */
ut_ad
(
dict_index_get_nth_field
(
index
,
field_no
)
->
prefix_len
...
...
@@ -2983,13 +3010,13 @@ row_sel_store_mysql_rec(
ut_ad
(
templ
->
rec_field_no
==
templ
->
clust_rec_field_no
);
field_no
=
it
-
template_col
.
begin
();
sec_
field_no
=
it
-
template_col
.
begin
();
}
if
(
!
row_sel_store_mysql_field
(
mysql_rec
,
prebuilt
,
rec
,
index
,
offsets
,
field_no
,
templ
,
clust_templ_for_sec
))
{
sec_field_no
))
{
return
(
FALSE
);
}
}
...
...
@@ -2999,7 +3026,8 @@ row_sel_store_mysql_rec(
NOTE, the record must be cluster index record. Secondary index
might not have the Doc ID */
if
(
dict_table_has_fts_index
(
prebuilt
->
table
)
&&
dict_index_is_clust
(
index
))
{
&&
dict_index_is_clust
(
index
)
&&
!
clust_templ_for_sec
)
{
prebuilt
->
fts_doc_id
=
fts_get_doc_id_from_rec
(
prebuilt
->
table
,
rec
,
NULL
);
...
...
@@ -3370,6 +3398,36 @@ row_sel_copy_cached_field_for_mysql(
ut_memcpy
(
buf
,
cache
,
len
);
}
/** Copy used fields from cached row.
Copy cache record field by field, don't touch fields that
are not covered by current key.
@param[out] buf Where to copy the MySQL row.
@param[in] cached_rec What to copy (in MySQL row format).
@param[in] prebuilt prebuilt struct. */
void
row_sel_copy_cached_fields_for_mysql
(
byte
*
buf
,
const
byte
*
cached_rec
,
row_prebuilt_t
*
prebuilt
)
{
const
mysql_row_templ_t
*
templ
;
ulint
i
;
for
(
i
=
0
;
i
<
prebuilt
->
n_template
;
i
++
)
{
templ
=
prebuilt
->
mysql_template
+
i
;
row_sel_copy_cached_field_for_mysql
(
buf
,
cached_rec
,
templ
);
/* Copy NULL bit of the current field from cached_rec
to buf */
if
(
templ
->
mysql_null_bit_mask
)
{
buf
[
templ
->
mysql_null_byte_offset
]
^=
(
buf
[
templ
->
mysql_null_byte_offset
]
^
cached_rec
[
templ
->
mysql_null_byte_offset
])
&
(
byte
)
templ
->
mysql_null_bit_mask
;
}
}
}
/********************************************************************//**
Pops a cached row for MySQL from the fetch cache. */
UNIV_INLINE
...
...
@@ -3629,7 +3687,7 @@ row_search_idx_cond_check(
if
(
!
row_sel_store_mysql_field
(
mysql_rec
,
prebuilt
,
rec
,
prebuilt
->
index
,
offsets
,
templ
->
icp_rec_field_no
,
templ
,
false
))
{
templ
,
ULINT_UNDEFINED
))
{
return
(
ICP_NO_MATCH
);
}
}
...
...
@@ -5086,8 +5144,19 @@ row_search_for_mysql(
btr_pcur_store_position
(
pcur
,
&
mtr
);
if
(
prebuilt
->
innodb_api
)
{
prebuilt
->
innodb_api_rec
=
result_rec
;
if
(
prebuilt
->
innodb_api
&&
(
btr_pcur_get_rec
(
pcur
)
!=
result_rec
))
{
ulint
rec_size
=
rec_offs_size
(
offsets
);
if
(
!
prebuilt
->
innodb_api_rec_size
||
(
prebuilt
->
innodb_api_rec_size
<
rec_size
))
{
prebuilt
->
innodb_api_buf
=
static_cast
<
byte
*>
(
mem_heap_alloc
(
prebuilt
->
cursor_heap
,
rec_size
));
prebuilt
->
innodb_api_rec_size
=
rec_size
;
}
prebuilt
->
innodb_api_rec
=
rec_copy
(
prebuilt
->
innodb_api_buf
,
result_rec
,
offsets
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment