summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
Diffstat (limited to 'storage')
-rw-r--r--storage/connect/CMakeLists.txt82
-rw-r--r--storage/connect/ha_connect.cc56
-rw-r--r--storage/connect/ha_connect.h7
-rw-r--r--storage/connect/jsonudf.cpp2
-rw-r--r--storage/connect/mycat.cc11
-rw-r--r--storage/connect/myconn.cpp5
-rw-r--r--storage/connect/mysql-test/connect/r/json_java_2.result17
-rw-r--r--storage/connect/mysql-test/connect/r/json_java_3.result17
-rw-r--r--storage/connect/mysql-test/connect/r/json_mongo_c.result17
-rw-r--r--storage/connect/mysql-test/connect/r/mongo_c.result2
-rw-r--r--storage/connect/mysql-test/connect/r/mongo_java_2.result2
-rw-r--r--storage/connect/mysql-test/connect/r/mongo_java_3.result2
-rw-r--r--storage/connect/mysql-test/connect/r/odbc_oracle.result32
-rw-r--r--storage/connect/mysql-test/connect/r/tbl_thread.result54
-rw-r--r--storage/connect/mysql-test/connect/std_data/Mongo2.jarbin3461358 -> 623907 bytes
-rw-r--r--storage/connect/mysql-test/connect/std_data/Mongo3.jarbin1705776 -> 1705776 bytes
-rw-r--r--storage/connect/mysql-test/connect/t/mongo_test.inc4
-rw-r--r--storage/connect/mysql-test/connect/t/tbl_thread.test34
-rw-r--r--storage/connect/myutil.cpp4
-rw-r--r--storage/connect/reldef.cpp2
-rw-r--r--storage/connect/reldef.h1
-rw-r--r--storage/connect/tabext.cpp95
-rw-r--r--storage/connect/tabext.h1
-rw-r--r--storage/connect/tabjson.cpp7
-rw-r--r--storage/connect/tabmysql.cpp17
-rw-r--r--storage/connect/tabmysql.h1
-rw-r--r--storage/connect/tabtbl.cpp58
-rw-r--r--storage/connect/tabtbl.h1
-rw-r--r--storage/connect/tabutil.cpp3
-rw-r--r--storage/connect/valblk.cpp13
-rw-r--r--storage/connect/valblk.h6
-rw-r--r--storage/connect/value.cpp101
-rw-r--r--storage/federated/ha_federated.cc69
-rw-r--r--storage/innobase/btr/btr0btr.cc57
-rw-r--r--storage/innobase/btr/btr0bulk.cc28
-rw-r--r--storage/innobase/btr/btr0cur.cc89
-rw-r--r--storage/innobase/btr/btr0defragment.cc1
-rw-r--r--storage/innobase/btr/btr0pcur.cc9
-rw-r--r--storage/innobase/btr/btr0sea.cc34
-rw-r--r--storage/innobase/data/data0data.cc11
-rw-r--r--storage/innobase/dict/dict0defrag_bg.cc4
-rw-r--r--storage/innobase/dict/dict0dict.cc28
-rw-r--r--storage/innobase/dict/dict0stats.cc12
-rw-r--r--storage/innobase/fts/fts0fts.cc10
-rw-r--r--storage/innobase/gis/gis0rtree.cc53
-rw-r--r--storage/innobase/gis/gis0sea.cc56
-rw-r--r--storage/innobase/handler/handler0alter.cc58
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.cc9
-rw-r--r--storage/innobase/include/data0data.h10
-rw-r--r--storage/innobase/include/dict0dict.h30
-rw-r--r--storage/innobase/include/dict0dict.ic14
-rw-r--r--storage/innobase/include/dict0mem.h4
-rw-r--r--storage/innobase/include/gis0rtree.ic3
-rw-r--r--storage/innobase/include/ha_prototypes.h1
-rw-r--r--storage/innobase/include/page0cur.ic4
-rw-r--r--storage/innobase/include/page0page.h318
-rw-r--r--storage/innobase/include/page0page.ic240
-rw-r--r--storage/innobase/include/rem0rec.h71
-rw-r--r--storage/innobase/lock/lock0lock.cc14
-rw-r--r--storage/innobase/mtr/mtr0log.cc9
-rw-r--r--storage/innobase/page/page0cur.cc56
-rw-r--r--storage/innobase/page/page0page.cc20
-rw-r--r--storage/innobase/page/page0zip.cc24
-rw-r--r--storage/innobase/rem/rem0cmp.cc1
-rw-r--r--storage/innobase/rem/rem0rec.cc126
-rw-r--r--storage/innobase/row/row0import.cc4
-rw-r--r--storage/innobase/row/row0ins.cc20
-rw-r--r--storage/innobase/row/row0log.cc14
-rw-r--r--storage/innobase/row/row0merge.cc4
-rw-r--r--storage/innobase/row/row0mysql.cc5
-rw-r--r--storage/innobase/row/row0purge.cc7
-rw-r--r--storage/innobase/row/row0row.cc6
-rw-r--r--storage/innobase/row/row0sel.cc70
-rw-r--r--storage/innobase/row/row0uins.cc2
-rw-r--r--storage/innobase/row/row0umod.cc4
-rw-r--r--storage/innobase/row/row0undo.cc2
-rw-r--r--storage/innobase/row/row0upd.cc17
-rw-r--r--storage/innobase/row/row0vers.cc27
-rw-r--r--storage/innobase/srv/srv0start.cc2
-rw-r--r--storage/innobase/trx/trx0i_s.cc3
-rw-r--r--storage/innobase/trx/trx0rec.cc4
-rw-r--r--storage/innobase/trx/trx0sys.cc10
-rw-r--r--storage/myisam/ha_myisam.cc15
-rw-r--r--storage/test_sql_discovery/mysql-test/sql_discovery/simple.result2
-rw-r--r--storage/tokudb/CMakeLists.txt9
-rw-r--r--storage/tokudb/PerconaFT/buildheader/make_tdb.cc2
-rw-r--r--storage/tokudb/PerconaFT/src/ydb-internal.h9
-rw-r--r--storage/tokudb/PerconaFT/src/ydb_cursor.cc108
-rw-r--r--storage/tokudb/ha_tokudb.cc8
-rw-r--r--storage/tokudb/mysql-test/rpl/r/rpl_row_log_tokudb.result315
-rw-r--r--storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb-master.opt2
-rw-r--r--storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb.test14
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/dir_per_db.result10
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/dir_per_db.test17
94 files changed, 1330 insertions, 1509 deletions
diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt
index 2fabd12dcd0..a1594f8797c 100644
--- a/storage/connect/CMakeLists.txt
+++ b/storage/connect/CMakeLists.txt
@@ -245,7 +245,7 @@ int main() {
ENDIF(CONNECT_WITH_ODBC)
#
-# JDBC and MongoDB Java Driver
+# JDBC with MongoDB Java Driver included but disabled
#
OPTION(CONNECT_WITH_MONGO "Compile CONNECT storage engine with MONGO support" ON)
OPTION(CONNECT_WITH_JDBC "Compile CONNECT storage engine with JDBC support" ON)
@@ -265,13 +265,13 @@ IF(CONNECT_WITH_JDBC)
MysqlInterface.java OracleInterface.java PostgresqlInterface.java
JavaWrappers.jar)
add_definitions(-DJDBC_SUPPORT)
- IF(CONNECT_WITH_MONGO)
+ IF(CONNECT_WITH_MONGO)
SET(CONNECT_SOURCES ${CONNECT_SOURCES}
jmgfam.cpp jmgoconn.cpp mongo.cpp tabjmg.cpp
jmgfam.h jmgoconn.h mongo.h tabjmg.h
Mongo2Interface.java Mongo3Interface.java)
- add_definitions(-DMONGO_SUPPORT)
- ENDIF()
+ add_definitions(-DMONGO_SUPPORT -DMONGO_ENABLED=0)
+ ENDIF()
ELSE()
SET(JDBC_LIBRARY "")
ENDIF()
@@ -290,33 +290,36 @@ IF(CONNECT_WITH_ZIP)
ENDIF(CONNECT_WITH_ZIP)
#
-# MONGO C Driver (CMAKE NOT YET WORKING)
+# MONGO C Driver
#
-#IF(CONNECT_WITH_MONGO)
-# IF(WIN32)
-# # Adding some typical places to search in
-# SET(PC_MONGO_INCLUDE_DIRS
-# C:/mongo-c-driver/include
-# D:/mongo-c-driver/include)
-# SET(PC_MONGO_LIBRARY_DIRS
-# C:/mongo-c-driver/lib
-# D:/mongo-c-driver/lib)
-# ENDIF(WIN32)
-# FIND_PACKAGE(libmongoc 1.7)
-# IF (MONGO_FOUND)
-# INCLUDE_DIRECTORIES(${MONGO_INCLUDE_DIR})
-# SET(MONGO_LIBRARY ${MONGO_LIBRARIES})
-# SET(CONNECT_SOURCES ${CONNECT_SOURCES}
-# cmgoconn.cpp cmgfam.cpp tabcmg.cpp
-# cmgoconn.h cmgfam.h tabcmg.h)
-# add_definitions(-DCMGO_SUPPORT)
-# IF (NOT JAVA_FOUND AND JNI_FOUND)
-# SET(CONNECT_SOURCES ${CONNECT_SOURCES} mongo.cpp mongo.h)
-# add_definitions(-DMONGO_SUPPORT)
-# ENDIF (NOT JAVA_FOUND AND JNI_FOUND)
-# ENDIF(MONGO_FOUND)
-#ENDIF(CONNECT_WITH_MONGO)
+IF(CONNECT_WITH_MONGO)
+ IF(WIN32)
+ # Adding some typical places to search in
+ SET(PC_MONGO_INCLUDE_DIRS
+ C:/mongo-c-driver/include
+ D:/mongo-c-driver/include)
+ SET(PC_MONGO_LIBRARY_DIRS
+ C:/mongo-c-driver/lib
+ D:/mongo-c-driver/lib)
+ ENDIF(WIN32)
+ FIND_PACKAGE(libmongoc-1.0 1.7)
+ IF (libmongoc-1.0_FOUND)
+ INCLUDE_DIRECTORIES(${MONGOC_INCLUDE_DIRS})
+ SET(MONGOC_LIBRARY ${MONGOC_LIBRARIES})
+ SET(CONNECT_SOURCES ${CONNECT_SOURCES}
+ cmgoconn.cpp cmgfam.cpp tabcmg.cpp
+ cmgoconn.h cmgfam.h tabcmg.h)
+ add_definitions(-DCMGO_SUPPORT)
+ IF (NOT JAVA_FOUND AND JNI_FOUND)
+ SET(CONNECT_SOURCES ${CONNECT_SOURCES} mongo.cpp mongo.h)
+ add_definitions(-DMONGO_SUPPORT -DMONGO_ENABLED=1)
+ ELSE ()
+ remove_definitions(-DMONGO_ENABLED=0)
+ add_definitions(-DMONGO_ENABLED=1)
+ ENDIF (NOT JAVA_FOUND AND JNI_FOUND)
+ ENDIF(libmongoc-1.0_FOUND)
+ENDIF(CONNECT_WITH_MONGO)
#
@@ -337,9 +340,25 @@ MYSQL_ADD_PLUGIN(connect ${CONNECT_SOURCES}
STORAGE_ENGINE
COMPONENT connect-engine
RECOMPILE_FOR_EMBEDDED
-# LINK_LIBRARIES ${ZLIB_LIBRARY} ${XML_LIBRARY} ${ICONV_LIBRARY} $(MONGO_LIBRARY)
LINK_LIBRARIES ${ZLIB_LIBRARY} ${XML_LIBRARY} ${ICONV_LIBRARY}
- ${ODBC_LIBRARY} ${JDBC_LIBRARY} ${IPHLPAPI_LIBRARY})
+ ${ODBC_LIBRARY} ${JDBC_LIBRARY} ${MONGOC_LIBRARY} ${IPHLPAPI_LIBRARY})
+
+IF(NOT TARGET connect)
+ RETURN()
+ENDIF()
+
+# Install some extra files that belong to connect engine
+IF(WIN32)
+ # install ha_connect.lib
+ GET_TARGET_PROPERTY(CONNECT_LOCATION connect LOCATION)
+ STRING(REPLACE "dll" "lib" CONNECT_LIB ${CONNECT_LOCATION})
+ IF(CMAKE_CONFIGURATION_TYPES)
+ STRING(REPLACE "${CMAKE_CFG_INTDIR}" "\${CMAKE_INSTALL_CONFIG_NAME}"
+ CONNECT_LIB ${CONNECT_LIB})
+ ENDIF()
+ INSTALL(FILES ${CONNECT_LIB}
+ DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine)
+ENDIF(WIN32)
IF(NOT TARGET connect)
RETURN()
@@ -368,4 +387,3 @@ IF(CONNECT_WITH_JDBC AND JAVA_FOUND AND JNI_FOUND)
${CMAKE_CURRENT_BINARY_DIR}/JdbcInterface.jar
DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine)
ENDIF()
-
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 4877f147e66..39506eae533 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -172,9 +172,9 @@
#define JSONMAX 10 // JSON Default max grp size
extern "C" {
- char version[]= "Version 1.06.0001 April 17, 2017";
+ char version[]= "Version 1.06.0004 September 03, 2017";
#if defined(__WIN__)
- char compver[]= "Version 1.06.0001 " __DATE__ " " __TIME__;
+ char compver[]= "Version 1.06.0004 " __DATE__ " " __TIME__;
char slash= '\\';
#else // !__WIN__
char slash= '/';
@@ -360,6 +360,13 @@ static MYSQL_THDVAR_STR(java_wrapper,
NULL, NULL, "wrappers/JdbcInterface");
#endif // JDBC_SUPPORT
+#if defined(MONGO_SUPPORT)
+// Enabling MONGO table type
+static MYSQL_THDVAR_BOOL(enable_mongo, PLUGIN_VAR_RQCMDARG,
+ "Enabling the MongoDB access",
+ NULL, NULL, MONGO_ENABLED);
+#endif // MONGO_SUPPORT
+
#if defined(XMSG) || defined(NEWMSG)
const char *language_names[]=
{
@@ -420,6 +427,10 @@ char *GetJavaWrapper(void)
{return connect_hton ? THDVAR(current_thd, java_wrapper) : (char*)"wrappers/JdbcInterface";}
#endif // JDBC_SUPPORT
+#if defined(MONGO_SUPPORT)
+bool MongoEnabled(void) { return THDVAR(current_thd, enable_mongo); }
+#endif // MONGO_SUPPORT
+
extern "C" const char *msglang(void)
{
#if defined(FRENCH)
@@ -1286,9 +1297,14 @@ PCSZ ha_connect::GetStringOption(PCSZ opname, PCSZ sdef)
else
opval= GetListOption(xp->g, opname, options->oplist);
- } else if (!stricmp(opname, "Query_String"))
- opval= thd_query_string(table->in_use)->str;
- else if (!stricmp(opname, "Partname"))
+ } else if (!stricmp(opname, "Query_String")) {
+// This escapes everything and returns a wrong query
+// opval = thd_query_string(table->in_use)->str;
+ opval = (PCSZ)PlugSubAlloc(xp->g, NULL,
+ thd_query_string(table->in_use)->length + 1);
+ strcpy((char*)opval, thd_query_string(table->in_use)->str);
+// sprintf((char*)opval, "%s", thd_query_string(table->in_use)->str);
+ } else if (!stricmp(opname, "Partname"))
opval= partname;
else if (!stricmp(opname, "Table_charset")) {
const CHARSET_INFO *chif= (tshp) ? tshp->table_charset
@@ -1434,7 +1450,7 @@ PFOS ha_connect::GetFieldOptionStruct(Field *fdp)
void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
{
const char *cp;
- char *chset, v;
+ char *chset, v = 0;
ha_field_option_struct *fop;
Field* fp;
Field* *fldp;
@@ -1487,7 +1503,6 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
} // endif fop
chset = (char *)fp->charset()->name;
- v = (!strcmp(chset, "binary")) ? 'B' : 0;
switch (fp->type()) {
case MYSQL_TYPE_BLOB:
@@ -1502,8 +1517,9 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
switch (pcf->Type) {
case TYPE_STRING:
- // Do something for case
- cp= fp->charset()->name;
+ case TYPE_BIN:
+ // Do something for case
+ cp= chset;
// Find if collation name ends by _ci
if (!strcmp(cp + strlen(cp) - 3, "_ci")) {
@@ -2115,6 +2131,11 @@ int ha_connect::MakeRecord(char *buf)
charset= tdbp->data_charset();
rc= fp->store(p, strlen(p), charset, CHECK_FIELD_WARN);
break;
+ case TYPE_BIN:
+ p = value->GetCharValue();
+ charset = &my_charset_bin;
+ rc = fp->store(p, strlen(p), charset, CHECK_FIELD_WARN);
+ break;
case TYPE_DOUBLE:
rc= fp->store(value->GetFloatValue());
break;
@@ -5164,7 +5185,8 @@ static bool add_field(String *sql, const char *field_name, int typ, int len,
error|= sql->append("` ");
error|= sql->append(type);
- if (len && typ != TYPE_DATE && (typ != TYPE_DOUBLE || dec >= 0)) {
+ if (typ == TYPE_STRING ||
+ (len && typ != TYPE_DATE && (typ != TYPE_DOUBLE || dec >= 0))) {
error|= sql->append('(');
error|= sql->append_ulonglong(len);
@@ -6390,6 +6412,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
+#if 0
if (!fp->field_length) {
sprintf(g->Message, "Unsupported 0 length for column %s",
fp->field_name.str);
@@ -6399,7 +6422,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
MYF(0), fp->field_name.str);
DBUG_RETURN(rc);
} // endif fp
-
+#endif // 0
break; // To be checked
case MYSQL_TYPE_BIT:
case MYSQL_TYPE_NULL:
@@ -7167,7 +7190,10 @@ static struct st_mysql_sys_var* connect_system_variables[]= {
MYSQL_SYSVAR(class_path),
MYSQL_SYSVAR(java_wrapper),
#endif // JDBC_SUPPORT
- NULL
+#if defined(MONGO_SUPPORT)
+ MYSQL_SYSVAR(enable_mongo),
+#endif // MONGO_SUPPORT
+NULL
};
maria_declare_plugin(connect)
@@ -7176,14 +7202,14 @@ maria_declare_plugin(connect)
&connect_storage_engine,
"CONNECT",
"Olivier Bertrand",
- "Management of External Data (SQL/MED), including many file formats",
+ "Management of External Data (SQL/NOSQL/MED), including many file formats",
PLUGIN_LICENSE_GPL,
connect_init_func, /* Plugin Init */
connect_done_func, /* Plugin Deinit */
0x0106, /* version number (1.05) */
NULL, /* status variables */
connect_system_variables, /* system variables */
- "1.06.0001", /* string version */
- MariaDB_PLUGIN_MATURITY_BETA /* maturity */
+ "1.06.0004", /* string version */
+ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
}
maria_declare_plugin_end;
diff --git a/storage/connect/ha_connect.h b/storage/connect/ha_connect.h
index 8a54f8f16d1..c3d458094a2 100644
--- a/storage/connect/ha_connect.h
+++ b/storage/connect/ha_connect.h
@@ -348,6 +348,13 @@ const char *GetValStr(OPVAL vop, bool neg);
PFIL CondFilter(PGLOBAL g, Item *cond);
//PFIL CheckFilter(PGLOBAL g);
+/** admin commands - called from mysql_admin_table */
+virtual int check(THD* thd, HA_CHECK_OPT* check_opt)
+{
+ // TODO: implement it
+ return HA_ADMIN_OK; // Just to avoid error message with checktables
+} // end of check
+
/**
Number of rows in table. It will only be called if
(table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0
diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp
index 34a43c72016..29bccc4afeb 100644
--- a/storage/connect/jsonudf.cpp
+++ b/storage/connect/jsonudf.cpp
@@ -539,7 +539,7 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
SetJsonValue(g, MulVal, jvp, n);
if (!MulVal->IsNull()) {
- switch (op) {
+ switch (op) {
case OP_CNC:
if (Nodes[n].CncVal) {
val[0] = Nodes[n].CncVal;
diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc
index 3a09b3003da..20082dcc43e 100644
--- a/storage/connect/mycat.cc
+++ b/storage/connect/mycat.cc
@@ -107,6 +107,9 @@
extern "C" HINSTANCE s_hModule; // Saved module handle
#endif // !__WIN__
+#if defined(MONGO_SUPPORT)
+bool MongoEnabled(void);
+#endif // MONGO_SUPPORT
PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
/***********************************************************************/
@@ -554,7 +557,13 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
case TAB_VIR: tdp= new(g) VIRDEF; break;
case TAB_JSON: tdp= new(g) JSONDEF; break;
#if defined(MONGO_SUPPORT)
- case TAB_MONGO: tdp = new(g) MGODEF; break;
+ case TAB_MONGO:
+ if (MongoEnabled())
+ tdp = new(g) MGODEF;
+ else
+ strcpy(g->Message, "MONGO type not enabled");
+
+ break;
#endif // MONGO_SUPPORT
#if defined(ZIP_SUPPORT)
case TAB_ZIP: tdp= new(g) ZIPDEF; break;
diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp
index d2d55f33611..08bb24e14df 100644
--- a/storage/connect/myconn.cpp
+++ b/storage/connect/myconn.cpp
@@ -472,7 +472,7 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
int pt, const char *csname)
{
const char *pipe = NULL;
- uint cto = 6000, nrt = 12000;
+ uint cto = 10, nrt = 20;
my_bool my_true= 1;
m_DB = mysql_init(NULL);
@@ -525,7 +525,8 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
mysql_options(m_DB, MYSQL_OPT_USE_THREAD_SPECIFIC_MEMORY,
(char*)&my_true);
- if (!mysql_real_connect(m_DB, host, user, pwd, db, pt, pipe, CLIENT_MULTI_RESULTS)) {
+ if (!mysql_real_connect(m_DB, host, user, pwd, db, pt, pipe,
+ CLIENT_MULTI_RESULTS | CLIENT_REMEMBER_OPTIONS)) {
#if defined(_DEBUG)
sprintf(g->Message, "mysql_real_connect failed: (%d) %s",
mysql_errno(m_DB), mysql_error(m_DB));
diff --git a/storage/connect/mysql-test/connect/r/json_java_2.result b/storage/connect/mysql-test/connect/r/json_java_2.result
index 83272ec00ce..96c58221b24 100644
--- a/storage/connect/mysql-test/connect/r/json_java_2.result
+++ b/storage/connect/mysql-test/connect/r/json_java_2.result
@@ -1,4 +1,5 @@
SET GLOBAL connect_class_path='C:/MariaDB-10.2/MariaDB/storage/connect/mysql-test/connect/std_data/Mongo2.jar';
+set connect_enable_mongo=1;
#
# Test the MONGO table type
#
@@ -25,7 +26,6 @@ address_street 1 CHAR 38 38 0 0 address.street
address_zipcode 1 CHAR 5 5 0 0 address.zipcode
borough 1 CHAR 13 13 0 0
cuisine 1 CHAR 64 64 0 0
-grades 1 CHAR 0 0 0 1
grades_date 1 CHAR 256 256 0 1 grades.0.date
grades_grade 1 CHAR 14 14 0 1 grades.0.grade
grades_score 5 BIGINT 2 2 0 1 grades.0.score
@@ -72,7 +72,6 @@ t1 CREATE TABLE `t1` (
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
`borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL,
- `grades` char(1) DEFAULT NULL,
`grades_date` varchar(256) DEFAULT NULL `FIELD_FORMAT`='grades.0.date',
`grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade',
`grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score',
@@ -80,12 +79,12 @@ t1 CREATE TABLE `t1` (
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `OPTION_LIST`='Level=1,Driver=Java,Version=2' `DATA_CHARSET`='utf8' `LRECL`=4096
SELECT * FROM t1 LIMIT 5;
-_id address_building address_coord address_street address_zipcode borough cuisine grades grades_date grades_grade grades_score name restaurant_id
-58ada47de5a51ddfcd5ed51c 1007 -73.856077 Morris Park Ave 10462 Bronx Bakery 2 2014-03-03T00:00:00.000Z A 2 Morris Park Bake Shop 30075445
-58ada47de5a51ddfcd5ed51d 469 -73.961704 Flatbush Avenue 11225 Brooklyn Hamburgers 2 2014-12-30T00:00:00.000Z A 8 Wendy'S 30112340
-58ada47de5a51ddfcd5ed51e 351 -73.98513559999999 West 57 Street 10019 Manhattan Irish 2 2014-09-06T00:00:00.000Z A 2 Dj Reynolds Pub And Restaurant 30191841
-58ada47de5a51ddfcd5ed51f 2780 -73.98241999999999 Stillwell Avenue 11224 Brooklyn American 2 2014-06-10T00:00:00.000Z A 5 Riviera Caterer 40356018
-58ada47de5a51ddfcd5ed520 97-22 -73.8601152 63 Road 11374 Queens Jewish/Kosher 2 2014-11-24T00:00:00.000Z Z 20 Tov Kosher Kitchen 40356068
+_id address_building address_coord address_street address_zipcode borough cuisine grades_date grades_grade grades_score name restaurant_id
+58ada47de5a51ddfcd5ed51c 1007 -73.856077 Morris Park Ave 10462 Bronx Bakery 2014-03-03T00:00:00.000Z A 2 Morris Park Bake Shop 30075445
+58ada47de5a51ddfcd5ed51d 469 -73.961704 Flatbush Avenue 11225 Brooklyn Hamburgers 2014-12-30T00:00:00.000Z A 8 Wendy'S 30112340
+58ada47de5a51ddfcd5ed51e 351 -73.98513559999999 West 57 Street 10019 Manhattan Irish 2014-09-06T00:00:00.000Z A 2 Dj Reynolds Pub And Restaurant 30191841
+58ada47de5a51ddfcd5ed51f 2780 -73.98241999999999 Stillwell Avenue 11224 Brooklyn American 2014-06-10T00:00:00.000Z A 5 Riviera Caterer 40356018
+58ada47de5a51ddfcd5ed520 97-22 -73.8601152 63 Road 11374 Queens Jewish/Kosher 2014-11-24T00:00:00.000Z Z 20 Tov Kosher Kitchen 40356068
DROP TABLE t1;
#
# Dropping a column
@@ -259,7 +258,6 @@ t1 CREATE TABLE `t1` (
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
`borough` char(13) NOT NULL,
- `grades` char(1) DEFAULT NULL,
`grades_date` char(24) DEFAULT NULL `FIELD_FORMAT`='grades.0.date',
`grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade',
`grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score',
@@ -384,3 +382,4 @@ planner 167 41.75
postcard 23 5.75
DROP TABLE t1;
true
+set connect_enable_mongo=0;
diff --git a/storage/connect/mysql-test/connect/r/json_java_3.result b/storage/connect/mysql-test/connect/r/json_java_3.result
index 563bcef7321..09901452975 100644
--- a/storage/connect/mysql-test/connect/r/json_java_3.result
+++ b/storage/connect/mysql-test/connect/r/json_java_3.result
@@ -1,4 +1,5 @@
SET GLOBAL connect_class_path='C:/MariaDB-10.2/MariaDB/storage/connect/mysql-test/connect/std_data/Mongo3.jar';
+set connect_enable_mongo=1;
#
# Test the MONGO table type
#
@@ -25,7 +26,6 @@ address_street 1 CHAR 38 38 0 0 address.street
address_zipcode 1 CHAR 5 5 0 0 address.zipcode
borough 1 CHAR 13 13 0 0
cuisine 1 CHAR 64 64 0 0
-grades 1 CHAR 0 0 0 1
grades_date 1 CHAR 256 256 0 1 grades.0.date
grades_grade 1 CHAR 14 14 0 1 grades.0.grade
grades_score 5 BIGINT 2 2 0 1 grades.0.score
@@ -72,7 +72,6 @@ t1 CREATE TABLE `t1` (
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
`borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL,
- `grades` char(1) DEFAULT NULL,
`grades_date` varchar(256) DEFAULT NULL `FIELD_FORMAT`='grades.0.date',
`grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade',
`grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score',
@@ -80,12 +79,12 @@ t1 CREATE TABLE `t1` (
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `OPTION_LIST`='Level=1,Driver=Java,Version=3' `DATA_CHARSET`='utf8' `LRECL`=4096
SELECT * FROM t1 LIMIT 5;
-_id address_building address_coord address_street address_zipcode borough cuisine grades grades_date grades_grade grades_score name restaurant_id
-58ada47de5a51ddfcd5ed51c 1007 -73.856077 Morris Park Ave 10462 Bronx Bakery 1 1393804800 A 2 Morris Park Bake Shop 30075445
-58ada47de5a51ddfcd5ed51d 469 -73.961704 Flatbush Avenue 11225 Brooklyn Hamburgers 1 1419897600 A 8 Wendy'S 30112340
-58ada47de5a51ddfcd5ed51e 351 -73.98513559999999 West 57 Street 10019 Manhattan Irish 1 1409961600 A 2 Dj Reynolds Pub And Restaurant 30191841
-58ada47de5a51ddfcd5ed51f 2780 -73.98241999999999 Stillwell Avenue 11224 Brooklyn American 1 1402358400 A 5 Riviera Caterer 40356018
-58ada47de5a51ddfcd5ed520 97-22 -73.8601152 63 Road 11374 Queens Jewish/Kosher 1 1416787200 Z 20 Tov Kosher Kitchen 40356068
+_id address_building address_coord address_street address_zipcode borough cuisine grades_date grades_grade grades_score name restaurant_id
+58ada47de5a51ddfcd5ed51c 1007 -73.856077 Morris Park Ave 10462 Bronx Bakery 1393804800 A 2 Morris Park Bake Shop 30075445
+58ada47de5a51ddfcd5ed51d 469 -73.961704 Flatbush Avenue 11225 Brooklyn Hamburgers 1419897600 A 8 Wendy'S 30112340
+58ada47de5a51ddfcd5ed51e 351 -73.98513559999999 West 57 Street 10019 Manhattan Irish 1409961600 A 2 Dj Reynolds Pub And Restaurant 30191841
+58ada47de5a51ddfcd5ed51f 2780 -73.98241999999999 Stillwell Avenue 11224 Brooklyn American 1402358400 A 5 Riviera Caterer 40356018
+58ada47de5a51ddfcd5ed520 97-22 -73.8601152 63 Road 11374 Queens Jewish/Kosher 1416787200 Z 20 Tov Kosher Kitchen 40356068
DROP TABLE t1;
#
# Dropping a column
@@ -259,7 +258,6 @@ t1 CREATE TABLE `t1` (
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
`borough` char(13) NOT NULL,
- `grades` char(1) DEFAULT NULL,
`grades_date` bigint(13) DEFAULT NULL `FIELD_FORMAT`='grades.0.date',
`grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade',
`grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score',
@@ -384,3 +382,4 @@ planner 167 41.75
postcard 23 5.75
DROP TABLE t1;
true
+set connect_enable_mongo=0;
diff --git a/storage/connect/mysql-test/connect/r/json_mongo_c.result b/storage/connect/mysql-test/connect/r/json_mongo_c.result
index d3363f39eab..afcad8d2ea2 100644
--- a/storage/connect/mysql-test/connect/r/json_mongo_c.result
+++ b/storage/connect/mysql-test/connect/r/json_mongo_c.result
@@ -1,3 +1,4 @@
+set connect_enable_mongo=1;
#
# Test the MONGO table type
#
@@ -24,7 +25,6 @@ address_street 1 CHAR 38 38 0 0 address.street
address_zipcode 1 CHAR 5 5 0 0 address.zipcode
borough 1 CHAR 13 13 0 0
cuisine 1 CHAR 64 64 0 0
-grades 1 CHAR 0 0 0 1
grades_date 1 CHAR 256 256 0 1 grades.0.date
grades_grade 1 CHAR 14 14 0 1 grades.0.grade
grades_score 5 BIGINT 2 2 0 1 grades.0.score
@@ -71,7 +71,6 @@ t1 CREATE TABLE `t1` (
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
`borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL,
- `grades` char(1) DEFAULT NULL,
`grades_date` varchar(256) DEFAULT NULL `FIELD_FORMAT`='grades.0.date',
`grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade',
`grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score',
@@ -79,12 +78,12 @@ t1 CREATE TABLE `t1` (
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `OPTION_LIST`='Level=1,Driver=C,Version=0' `DATA_CHARSET`='utf8' `LRECL`=1024
SELECT * FROM t1 LIMIT 5;
-_id address_building address_coord address_street address_zipcode borough cuisine grades grades_date grades_grade grades_score name restaurant_id
-58ada47de5a51ddfcd5ed51c 1007 -73.856076999999999089 Morris Park Ave 10462 Bronx Bakery 1 1393804800 A 2 Morris Park Bake Shop 30075445
-58ada47de5a51ddfcd5ed51d 469 -73.96170399999999745 Flatbush Avenue 11225 Brooklyn Hamburgers 1 1419897600 A 8 Wendy'S 30112340
-58ada47de5a51ddfcd5ed51e 351 -73.985135599999992451 West 57 Street 10019 Manhattan Irish 1 1409961600 A 2 Dj Reynolds Pub And Restaurant 30191841
-58ada47de5a51ddfcd5ed51f 2780 -73.982419999999990523 Stillwell Avenue 11224 Brooklyn American 1 1402358400 A 5 Riviera Caterer 40356018
-58ada47de5a51ddfcd5ed520 97-22 -73.860115199999995639 63 Road 11374 Queens Jewish/Kosher 1 1416787200 Z 20 Tov Kosher Kitchen 40356068
+_id address_building address_coord address_street address_zipcode borough cuisine grades_date grades_grade grades_score name restaurant_id
+58ada47de5a51ddfcd5ed51c 1007 -73.856076999999999089 Morris Park Ave 10462 Bronx Bakery 1393804800 A 2 Morris Park Bake Shop 30075445
+58ada47de5a51ddfcd5ed51d 469 -73.96170399999999745 Flatbush Avenue 11225 Brooklyn Hamburgers 1419897600 A 8 Wendy'S 30112340
+58ada47de5a51ddfcd5ed51e 351 -73.985135599999992451 West 57 Street 10019 Manhattan Irish 1409961600 A 2 Dj Reynolds Pub And Restaurant 30191841
+58ada47de5a51ddfcd5ed51f 2780 -73.982419999999990523 Stillwell Avenue 11224 Brooklyn American 1402358400 A 5 Riviera Caterer 40356018
+58ada47de5a51ddfcd5ed520 97-22 -73.860115199999995639 63 Road 11374 Queens Jewish/Kosher 1416787200 Z 20 Tov Kosher Kitchen 40356068
DROP TABLE t1;
#
# Dropping a column
@@ -258,7 +257,6 @@ t1 CREATE TABLE `t1` (
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
`borough` char(13) NOT NULL,
- `grades` char(1) DEFAULT NULL,
`grades_date` bigint(13) DEFAULT NULL `FIELD_FORMAT`='grades.0.date',
`grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade',
`grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score',
@@ -383,3 +381,4 @@ planner 167 41.75
postcard 23 5.75
DROP TABLE t1;
true
+set connect_enable_mongo=0;
diff --git a/storage/connect/mysql-test/connect/r/mongo_c.result b/storage/connect/mysql-test/connect/r/mongo_c.result
index da0832994c2..f90f3a94b44 100644
--- a/storage/connect/mysql-test/connect/r/mongo_c.result
+++ b/storage/connect/mysql-test/connect/r/mongo_c.result
@@ -1,3 +1,4 @@
+set connect_enable_mongo=1;
#
# Test the MONGO table type
#
@@ -376,3 +377,4 @@ planner 167 41.750000
postcard 23 5.750000
DROP TABLE t1;
true
+set connect_enable_mongo=0;
diff --git a/storage/connect/mysql-test/connect/r/mongo_java_2.result b/storage/connect/mysql-test/connect/r/mongo_java_2.result
index b1e9ea74f72..02b8ae09d34 100644
--- a/storage/connect/mysql-test/connect/r/mongo_java_2.result
+++ b/storage/connect/mysql-test/connect/r/mongo_java_2.result
@@ -1,4 +1,5 @@
SET GLOBAL connect_class_path='C:/MariaDB-10.2/MariaDB/storage/connect/mysql-test/connect/std_data/Mongo2.jar';
+set connect_enable_mongo=1;
#
# Test the MONGO table type
#
@@ -377,3 +378,4 @@ planner 167 41.75
postcard 23 5.75
DROP TABLE t1;
true
+set connect_enable_mongo=0;
diff --git a/storage/connect/mysql-test/connect/r/mongo_java_3.result b/storage/connect/mysql-test/connect/r/mongo_java_3.result
index e2fe584620f..c4387bfa5b1 100644
--- a/storage/connect/mysql-test/connect/r/mongo_java_3.result
+++ b/storage/connect/mysql-test/connect/r/mongo_java_3.result
@@ -1,4 +1,5 @@
SET GLOBAL connect_class_path='C:/MariaDB-10.2/MariaDB/storage/connect/mysql-test/connect/std_data/Mongo3.jar';
+set connect_enable_mongo=1;
#
# Test the MONGO table type
#
@@ -377,3 +378,4 @@ planner 167 41.75
postcard 23 5.75
DROP TABLE t1;
true
+set connect_enable_mongo=0;
diff --git a/storage/connect/mysql-test/connect/r/odbc_oracle.result b/storage/connect/mysql-test/connect/r/odbc_oracle.result
index db7f78f67cd..8dc7dc07bb1 100644
--- a/storage/connect/mysql-test/connect/r/odbc_oracle.result
+++ b/storage/connect/mysql-test/connect/r/odbc_oracle.result
@@ -72,11 +72,11 @@ TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr'
CATFUNC=Columns;
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks
-NULL MTR T1 A 3 DECIMAL 38 40 0 10 1 NULL
-NULL MTR T1 B 6 NUMBER 38 40 NULL NULL 1 NULL
-NULL MTR T2 A 12 VARCHAR2 64 64 NULL NULL 1 NULL
-NULL MTR V1 A 3 DECIMAL 38 40 0 10 1 NULL
-NULL MTR V1 B 6 NUMBER 38 40 NULL NULL 1 NULL
+ MTR T1 A 3 DECIMAL 38 40 0 10 1
+ MTR T1 B 6 NUMBER 38 40 NULL NULL 1
+ MTR T2 A 12 VARCHAR2 64 64 NULL NULL 1
+ MTR V1 A 3 DECIMAL 38 40 0 10 1
+ MTR V1 B 6 NUMBER 38 40 NULL NULL 1
DROP TABLE t1;
# All columns in all schemas (limited with WHERE)
CREATE TABLE t1 ENGINE=CONNECT
@@ -84,18 +84,18 @@ TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr'
CATFUNC=Columns TABNAME='%.%';
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks
-NULL MTR T1 A 3 DECIMAL 38 40 0 10 1 NULL
-NULL MTR T1 B 6 NUMBER 38 40 NULL NULL 1 NULL
-NULL MTR T2 A 12 VARCHAR2 64 64 NULL NULL 1 NULL
-NULL MTR V1 A 3 DECIMAL 38 40 0 10 1 NULL
-NULL MTR V1 B 6 NUMBER 38 40 NULL NULL 1 NULL
+ MTR T1 A 3 DECIMAL 38 40 0 10 1
+ MTR T1 B 6 NUMBER 38 40 NULL NULL 1
+ MTR T2 A 12 VARCHAR2 64 64 NULL NULL 1
+ MTR V1 A 3 DECIMAL 38 40 0 10 1
+ MTR V1 B 6 NUMBER 38 40 NULL NULL 1
DROP TABLE t1;
# All tables "T1" in all schemas (limited with WHERE)
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr' CATFUNC=Columns TABNAME='%.T1';
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks
-NULL MTR T1 A 3 DECIMAL 38 40 0 10 1 NULL
-NULL MTR T1 B 6 NUMBER 38 40 NULL NULL 1 NULL
+ MTR T1 A 3 DECIMAL 38 40 0 10 1
+ MTR T1 B 6 NUMBER 38 40 NULL NULL 1
DROP TABLE t1;
# Table "T1" in the schema "MTR"
CREATE TABLE t1 ENGINE=CONNECT
@@ -103,8 +103,8 @@ TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr'
CATFUNC=Columns TABNAME='MTR.T1';
SELECT * FROM t1 ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks
-NULL MTR T1 A 3 DECIMAL 38 40 0 10 1 NULL
-NULL MTR T1 B 6 NUMBER 38 40 NULL NULL 1 NULL
+ MTR T1 A 3 DECIMAL 38 40 0 10 1
+ MTR T1 B 6 NUMBER 38 40 NULL NULL 1
DROP TABLE t1;
# All tables "T1" in all schemas (filtered with WHERE)
CREATE TABLE t1 ENGINE=CONNECT
@@ -112,8 +112,8 @@ TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr'
CATFUNC=Columns TABNAME='%.T1';
SELECT * FROM t1 WHERE Table_Schema='MTR' ORDER BY Table_Schema, Table_Name;
Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks
-NULL MTR T1 A 3 DECIMAL 38 40 0 10 1 NULL
-NULL MTR T1 B 6 NUMBER 38 40 NULL NULL 1 NULL
+ MTR T1 A 3 DECIMAL 38 40 0 10 1
+ MTR T1 B 6 NUMBER 38 40 NULL NULL 1
DROP TABLE t1;
#
# Checking tables
diff --git a/storage/connect/mysql-test/connect/r/tbl_thread.result b/storage/connect/mysql-test/connect/r/tbl_thread.result
index ef6439462bb..f53ccd25b97 100644
--- a/storage/connect/mysql-test/connect/r/tbl_thread.result
+++ b/storage/connect/mysql-test/connect/r/tbl_thread.result
@@ -35,6 +35,22 @@ a b
9 test09
10 test10
11 test11
+CREATE TABLE rt4 (a int, b char(10));
+INSERT INTO rt4 VALUES (12,'test12'),(13,'test13'),(14,'test14'),(15,'test15');
+SELECT * FROM rt4;
+a b
+12 test12
+13 test13
+14 test14
+15 test15
+CREATE TABLE rt5 (a int, b char(10));
+INSERT INTO rt5 VALUES (16,'test16'),(17,'test17'),(18,'test18'),(19,'test19');
+SELECT * FROM rt5;
+a b
+16 test16
+17 test17
+18 test18
+19 test19
connection default;
CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:MASTER_PORT/test/rt2';
@@ -52,11 +68,36 @@ a b
9 test09
10 test10
11 test11
+CREATE TABLE t4 ENGINE=CONNECT TABLE_TYPE=MYSQL
+CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/rt4';
+SELECT * FROM t4;
+a b
+12 test12
+13 test13
+14 test14
+15 test15
+CREATE TABLE t5 ENGINE=CONNECT TABLE_TYPE=MYSQL
+CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/rt5';
+SELECT * FROM t5;
+a b
+16 test16
+17 test17
+18 test18
+19 test19
CREATE TABLE total (a int, b char(10))
-ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2,t3'
+ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2,t3,t4,t5'
OPTION_LIST='thread=yes,port=PORT';
+set connect_xtrace=1;
SELECT * FROM total order by a desc;
a b
+19 test19
+18 test18
+17 test17
+16 test16
+15 test15
+14 test14
+13 test13
+12 test12
11 test11
10 test10
9 test09
@@ -69,12 +110,13 @@ a b
2 test02
1 test01
0 test00
+set connect_xtrace=0;
connection master;
DROP TABLE rt2;
connection slave;
-DROP TABLE rt3;
+DROP TABLE rt3,rt4,rt5;
connection default;
-DROP TABLE t1,t2,t3,total;
+DROP TABLE t1,t2,t3,t4,t5,total;
#
# Old thread TBL tables test modified
#
@@ -87,13 +129,15 @@ SELECT * FROM t2;
v
22
CREATE TABLE total (v BIGINT(20) UNSIGNED NOT NULL) ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2' OPTION_LIST='thread=yes,port=PORT';;
+set connect_xtrace=1;
SELECT * FROM total order by v desc;
v
22
11
+set connect_xtrace=0;
DROP TABLE t1,t2,total;
#
-# Old thread TBL tables test not modified
+# Old thread TBL tables test not modified (suppressed until MDEV-10179 is fixed)
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL SRCDEF='select 11 as v';
SELECT * FROM t1;
@@ -104,10 +148,12 @@ SELECT * FROM t2;
v
22
CREATE TABLE total (v BIGINT(20) UNSIGNED NOT NULL) ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2' OPTION_LIST='thread=yes,port=PORT';;
+set connect_xtrace=1;
SELECT * FROM total order by v desc;
v
22
11
+set connect_xtrace=0;
DROP TABLE total;
DROP TABLE t1;
DROP TABLE t2;
diff --git a/storage/connect/mysql-test/connect/std_data/Mongo2.jar b/storage/connect/mysql-test/connect/std_data/Mongo2.jar
index d019bf6906b..9be654bd4c8 100644
--- a/storage/connect/mysql-test/connect/std_data/Mongo2.jar
+++ b/storage/connect/mysql-test/connect/std_data/Mongo2.jar
Binary files differ
diff --git a/storage/connect/mysql-test/connect/std_data/Mongo3.jar b/storage/connect/mysql-test/connect/std_data/Mongo3.jar
index 73eb3571290..2850177a668 100644
--- a/storage/connect/mysql-test/connect/std_data/Mongo3.jar
+++ b/storage/connect/mysql-test/connect/std_data/Mongo3.jar
Binary files differ
diff --git a/storage/connect/mysql-test/connect/t/mongo_test.inc b/storage/connect/mysql-test/connect/t/mongo_test.inc
index c223e70f719..c728b85fd2f 100644
--- a/storage/connect/mysql-test/connect/t/mongo_test.inc
+++ b/storage/connect/mysql-test/connect/t/mongo_test.inc
@@ -1,3 +1,5 @@
+set connect_enable_mongo=1;
+
--echo #
--echo # Test the MONGO table type
--echo #
@@ -201,3 +203,5 @@ OPTION_LIST='Driver=$DRV,Version=$VERS,Pipeline=YES' $CONN;
SELECT * FROM t1;
DROP TABLE t1;
--exec $MONGO --eval "db.testcoll.drop()" --quiet
+
+set connect_enable_mongo=0;
diff --git a/storage/connect/mysql-test/connect/t/tbl_thread.test b/storage/connect/mysql-test/connect/t/tbl_thread.test
index abc1ef34729..68a0ebcd44d 100644
--- a/storage/connect/mysql-test/connect/t/tbl_thread.test
+++ b/storage/connect/mysql-test/connect/t/tbl_thread.test
@@ -2,8 +2,6 @@
connection default;
-let $PORT= `select @@port`;
-
--echo #
--echo # Checking thread TBL tables
--echo #
@@ -24,6 +22,14 @@ CREATE TABLE rt3 (a int, b char(10));
INSERT INTO rt3 VALUES (8,'test08'),(9,'test09'),(10,'test10'),(11,'test11');
SELECT * FROM rt3;
+CREATE TABLE rt4 (a int, b char(10));
+INSERT INTO rt4 VALUES (12,'test12'),(13,'test13'),(14,'test14'),(15,'test15');
+SELECT * FROM rt4;
+
+CREATE TABLE rt5 (a int, b char(10));
+INSERT INTO rt5 VALUES (16,'test16'),(17,'test17'),(18,'test18'),(19,'test19');
+SELECT * FROM rt5;
+
connection default;
--replace_result $MASTER_MYPORT MASTER_PORT
@@ -36,11 +42,23 @@ eval CREATE TABLE t3 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/rt3';
SELECT * FROM t3;
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval CREATE TABLE t4 ENGINE=CONNECT TABLE_TYPE=MYSQL
+CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/rt4';
+SELECT * FROM t4;
+
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval CREATE TABLE t5 ENGINE=CONNECT TABLE_TYPE=MYSQL
+CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/rt5';
+SELECT * FROM t5;
+
--replace_result $PORT PORT
eval CREATE TABLE total (a int, b char(10))
-ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2,t3'
+ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2,t3,t4,t5'
OPTION_LIST='thread=yes,port=$PORT';
+set connect_xtrace=1;
SELECT * FROM total order by a desc;
+set connect_xtrace=0;
connection master;
@@ -48,11 +66,11 @@ DROP TABLE rt2;
connection slave;
-DROP TABLE rt3;
+DROP TABLE rt3,rt4,rt5;
connection default;
-DROP TABLE t1,t2,t3,total;
+DROP TABLE t1,t2,t3,t4,t5,total;
--echo #
--echo # Old thread TBL tables test modified
@@ -67,11 +85,13 @@ SELECT * FROM t2;
--replace_result $PORT PORT
--eval CREATE TABLE total (v BIGINT(20) UNSIGNED NOT NULL) ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2' OPTION_LIST='thread=yes,port=$PORT';
+set connect_xtrace=1;
SELECT * FROM total order by v desc;
+set connect_xtrace=0;
DROP TABLE t1,t2,total;
--echo #
---echo # Old thread TBL tables test not modified
+--echo # Old thread TBL tables test not modified (suppressed until MDEV-10179 is fixed)
--echo #
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL SRCDEF='select 11 as v';
SELECT * FROM t1;
@@ -81,7 +101,9 @@ SELECT * FROM t2;
--replace_result $PORT PORT
--eval CREATE TABLE total (v BIGINT(20) UNSIGNED NOT NULL) ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2' OPTION_LIST='thread=yes,port=$PORT';
+set connect_xtrace=1;
SELECT * FROM total order by v desc;
+set connect_xtrace=0;
DROP TABLE total;
DROP TABLE t1;
diff --git a/storage/connect/myutil.cpp b/storage/connect/myutil.cpp
index c2053f1c832..338a79d9455 100644
--- a/storage/connect/myutil.cpp
+++ b/storage/connect/myutil.cpp
@@ -218,7 +218,7 @@ int MYSQLtoPLG(int mytype, char *var)
case MYSQL_TYPE_VARCHAR:
#endif // !ALPHA)
case MYSQL_TYPE_STRING:
- type = TYPE_STRING;
+ type = (*var == 'B') ? TYPE_BIN : TYPE_STRING;
break;
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_TINY_BLOB:
@@ -232,7 +232,7 @@ int MYSQLtoPLG(int mytype, char *var)
type = TYPE_STRING;
*var = 'X';
} else
- type = TYPE_ERROR;
+ type = TYPE_BIN;
break;
case TPC_SKIP:
diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp
index 95069baf76e..031fdebe650 100644
--- a/storage/connect/reldef.cpp
+++ b/storage/connect/reldef.cpp
@@ -789,7 +789,7 @@ int COLDEF::Define(PGLOBAL g, void *, PCOLINFO cfp, int poff)
Poff = poff;
Buf_Type = cfp->Type;
- if ((Clen = GetTypeSize(Buf_Type, cfp->Length)) <= 0) {
+ if ((Clen = GetTypeSize(Buf_Type, cfp->Length)) < 0) {
sprintf(g->Message, MSG(BAD_COL_TYPE), GetTypeName(Buf_Type), Name);
return -1;
} // endswitch
diff --git a/storage/connect/reldef.h b/storage/connect/reldef.h
index 8b19a413ade..84ae2a491f0 100644
--- a/storage/connect/reldef.h
+++ b/storage/connect/reldef.h
@@ -94,6 +94,7 @@ public:
virtual void SetIndx(PIXDEF) {}
virtual bool IsHuge(void) {return false;}
const CHARSET_INFO *data_charset() {return m_data_charset;}
+ const char *GetCsName(void) {return csname;}
// Methods
int GetColCatInfo(PGLOBAL g);
diff --git a/storage/connect/tabext.cpp b/storage/connect/tabext.cpp
index 1d76e0417fa..207c8401c7b 100644
--- a/storage/connect/tabext.cpp
+++ b/storage/connect/tabext.cpp
@@ -279,10 +279,57 @@ int TDBEXT::Decode(PCSZ txt, char *buf, size_t n)
} // end of Decode
/***********************************************************************/
-/* MakeSQL: make the SQL statement use with remote connection. */
-/* TODO: when implementing remote filtering, column only used in */
-/* local filter should be removed from column list. */
+/* MakeSrcdef: make the SQL statement from SRDEF option. */
/***********************************************************************/
+bool TDBEXT::MakeSrcdef(PGLOBAL g)
+{
+ char *catp = strstr(Srcdef, "%s");
+
+ if (catp) {
+ char *fil1= 0, *fil2;
+ PCSZ ph = ((EXTDEF*)To_Def)->Phpos;
+
+ if (!ph)
+ ph = (strstr(catp + 2, "%s")) ? "WH" : "W";
+
+ if (stricmp(ph, "H")) {
+ fil1 = (To_CondFil && *To_CondFil->Body)
+ ? To_CondFil->Body : PlugDup(g, "1=1");
+ } // endif ph
+
+ if (stricmp(ph, "W")) {
+ fil2 = (To_CondFil && To_CondFil->Having && *To_CondFil->Having)
+ ? To_CondFil->Having : PlugDup(g, "1=1");
+ } // endif ph
+
+ if (!stricmp(ph, "W")) {
+ Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1));
+ Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil1));
+ } else if (!stricmp(ph, "WH")) {
+ Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1) + strlen(fil2));
+ Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil1, fil2));
+ } else if (!stricmp(ph, "H")) {
+ Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil2));
+ Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil2));
+ } else if (!stricmp(ph, "HW")) {
+ Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1) + strlen(fil2));
+ Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil2, fil1));
+ } else {
+ strcpy(g->Message, "MakeSQL: Wrong place holders specification");
+ return true;
+ } // endif's ph
+
+ } else
+ Query = new(g)STRING(g, 0, Srcdef);
+
+ return false;
+} // end of MakeSrcdef
+
+ /***********************************************************************/
+ /* MakeSQL: make the SQL statement use with remote connection. */
+ /* TODO: when implementing remote filtering, column only used in */
+ /* local filter should be removed from column list. */
+ /***********************************************************************/
bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
{
PCSZ schmp = NULL;
@@ -292,46 +339,8 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
PTABLE tablep = To_Table;
PCOL colp;
- if (Srcdef) {
- if ((catp = strstr(Srcdef, "%s"))) {
- char *fil1= 0, *fil2;
- PCSZ ph = ((EXTDEF*)To_Def)->Phpos;
-
- if (!ph)
- ph = (strstr(catp + 2, "%s")) ? "WH" : "W";
-
- if (stricmp(ph, "H")) {
- fil1 = (To_CondFil && *To_CondFil->Body)
- ? To_CondFil->Body : PlugDup(g, "1=1");
- } // endif ph
-
- if (stricmp(ph, "W")) {
- fil2 = (To_CondFil && To_CondFil->Having && *To_CondFil->Having)
- ? To_CondFil->Having : PlugDup(g, "1=1");
- } // endif ph
-
- if (!stricmp(ph, "W")) {
- Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1));
- Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil1));
- } else if (!stricmp(ph, "WH")) {
- Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1) + strlen(fil2));
- Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil1, fil2));
- } else if (!stricmp(ph, "H")) {
- Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil2));
- Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil2));
- } else if (!stricmp(ph, "HW")) {
- Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1) + strlen(fil2));
- Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil2, fil1));
- } else {
- strcpy(g->Message, "MakeSQL: Wrong place holders specification");
- return true;
- } // endif's ph
-
- } else
- Query = new(g)STRING(g, 0, Srcdef);
-
- return false;
- } // endif Srcdef
+ if (Srcdef)
+ return MakeSrcdef(g);
// Allocate the string used to contain the Query
Query = new(g)STRING(g, 1023, "SELECT ");
diff --git a/storage/connect/tabext.h b/storage/connect/tabext.h
index 7ddf2a68117..6b67c2ab5ed 100644
--- a/storage/connect/tabext.h
+++ b/storage/connect/tabext.h
@@ -126,6 +126,7 @@ public:
protected:
// Internal functions
+ virtual bool MakeSrcdef(PGLOBAL g);
virtual bool MakeSQL(PGLOBAL g, bool cnt);
//virtual bool MakeInsert(PGLOBAL g);
virtual bool MakeCommand(PGLOBAL g);
diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp
index 76a3d5e9988..401441520da 100644
--- a/storage/connect/tabjson.cpp
+++ b/storage/connect/tabjson.cpp
@@ -136,6 +136,7 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0;
tdp->Pretty = GetIntegerTableOption(g, topt, "Pretty", 2);
tdp->Xcol = GetStringTableOption(g, topt, "Expand", NULL);
+ tdp->Accept = GetBooleanTableOption(g, topt, "Accept", false);
tdp->Uri = (dsn && *dsn ? dsn : NULL);
if (!tdp->Fn && !tdp->Uri) {
@@ -365,7 +366,7 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
jcp->Scale = MY_MAX(jcp->Scale, jcol.Scale);
jcp->Cbn |= jcol.Cbn;
jcp->Found = true;
- } else {
+ } else if (jcol.Type != TYPE_UNKNOWN || tdp->Accept) {
// New column
jcp = (PJCL)PlugSubAlloc(g, NULL, sizeof(JCOL));
*jcp = jcol;
@@ -448,8 +449,8 @@ PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info)
/* Now get the results into blocks. */
/*********************************************************************/
for (i = 0, jcp = fjcp; jcp; i++, jcp = jcp->Next) {
- if (jcp->Type == TYPE_UNKNOWN) // Void column
- jcp->Type = TYPE_STRING;
+ if (jcp->Type == TYPE_UNKNOWN)
+ jcp->Type = TYPE_STRING; // Void column
crp = qrp->Colresp; // Column Name
crp->Kdata->SetValue(jcp->Name, i);
diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp
index bdddcf64ca8..d1e2ae69608 100644
--- a/storage/connect/tabmysql.cpp
+++ b/storage/connect/tabmysql.cpp
@@ -513,18 +513,8 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx)
if (Query)
return false; // already done
- if (Srcdef) {
- if (strstr(Srcdef, "%s")) {
- char *fil;
-
- fil = (To_CondFil) ? To_CondFil->Body : PlugDup(g, "1=1");
- Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil));
- Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil));
- } else
- Query = new(g)STRING(g, 0, Srcdef);
-
- return false;
- } // endif Srcdef
+ if (Srcdef)
+ return MakeSrcdef(g);
// Allocate the string used to contain Query
Query = new(g) STRING(g, 1023, "SELECT ");
@@ -1270,7 +1260,8 @@ MYSQLCOL::MYSQLCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PCSZ am)
: COLBLK(NULL, tdbp, i)
{
const char *chset = get_charset_name(fld->charsetnr);
- char v = (!strcmp(chset, "binary")) ? 'B' : 0;
+//char v = (!strcmp(chset, "binary")) ? 'B' : 0;
+ char v = 0;
Name = fld->name;
Opt = 0;
diff --git a/storage/connect/tabmysql.h b/storage/connect/tabmysql.h
index 3c37ae5bf3b..39fba87bcc9 100644
--- a/storage/connect/tabmysql.h
+++ b/storage/connect/tabmysql.h
@@ -69,6 +69,7 @@ class MYSQLDEF : public EXTDEF {/* Logical table description */
/***********************************************************************/
class TDBMYSQL : public TDBEXT {
friend class MYSQLCOL;
+ friend class TDBTBM;
public:
// Constructor
TDBMYSQL(PMYDEF tdp);
diff --git a/storage/connect/tabtbl.cpp b/storage/connect/tabtbl.cpp
index afd6b47c5a2..6e4a038ec92 100644
--- a/storage/connect/tabtbl.cpp
+++ b/storage/connect/tabtbl.cpp
@@ -578,10 +578,19 @@ pthread_handler_t ThreadOpen(void *p)
// Try to open the connection
if (!cmp->Tap->GetTo_Tdb()->OpenDB(cmp->G)) {
pthread_mutex_lock(&tblmut);
+ if (trace)
+ htrc("Table %s ready\n", cmp->Tap->GetName());
+
cmp->Ready = true;
pthread_mutex_unlock(&tblmut);
- } else
- cmp->Rc = RC_FX;
+ } else {
+ pthread_mutex_lock(&tblmut);
+ if (trace)
+ htrc("Opening %s failed\n", cmp->Tap->GetName());
+
+ cmp->Rc = RC_FX;
+ pthread_mutex_unlock(&tblmut);
+ } // endif OpenDB
my_thread_end();
} else
@@ -633,6 +642,18 @@ int TDBTBM::RowNumber(PGLOBAL g, bool b)
} // end of RowNumber
/***********************************************************************/
+/* Returns true if this MYSQL table refers to a local table. */
+/***********************************************************************/
+bool TDBTBM::IsLocal(PTABLE tbp)
+{
+ TDBMYSQL *tdbp = (TDBMYSQL*)tbp->GetTo_Tdb();
+
+ return ((!stricmp(tdbp->Host, "localhost") ||
+ !strcmp(tdbp->Host, "127.0.0.1")) &&
+ tdbp->Port == GetDefaultPort());
+} // end of IsLocal
+
+/***********************************************************************/
/* Initialyze table parallel processing. */
/***********************************************************************/
bool TDBTBM::OpenTables(PGLOBAL g)
@@ -644,10 +665,13 @@ bool TDBTBM::OpenTables(PGLOBAL g)
// Allocates the TBMT blocks for the tables
for (tabp = Tablist; tabp; tabp = tabp->Next)
- if (tabp->GetTo_Tdb()->GetAmType() == TYPE_AM_MYSQL) {
+ if (tabp->GetTo_Tdb()->GetAmType() == TYPE_AM_MYSQL && !IsLocal(tabp)) {
// Remove remote table from the local list
*ptabp = tabp->Next;
+ if (trace)
+ htrc("=====> New remote table %s\n", tabp->GetName());
+
// Make the remote table block
tp = (PTBMT)PlugSubAlloc(g, NULL, sizeof(TBMT));
memset(tp, 0, sizeof(TBMT));
@@ -671,7 +695,10 @@ bool TDBTBM::OpenTables(PGLOBAL g)
ptp = &tp->Next;
Nrc++; // Number of remote connections
} else {
- ptabp = &tabp->Next;
+ if (trace)
+ htrc("=====> Local table %s\n", tabp->GetName());
+
+ ptabp = &tabp->Next;
Nlc++; // Number of local connections
} // endif Type
@@ -788,7 +815,7 @@ int TDBTBM::ReadDB(PGLOBAL g)
/***********************************************************************/
int TDBTBM::ReadNextRemote(PGLOBAL g)
{
- bool b = false;
+ bool b;
if (Tdbp)
Tdbp->CloseDB(g);
@@ -796,17 +823,22 @@ int TDBTBM::ReadNextRemote(PGLOBAL g)
Cmp = NULL;
retry:
- // Search for a remote table having its result set
+ b = false;
+
+ // Search for a remote table having its result set
pthread_mutex_lock(&tblmut);
for (PTBMT tp = Tmp; tp; tp = tp->Next)
- if (tp->Ready) {
- if (!tp->Complete) {
- Cmp = tp;
- break;
- } // endif Complete
+ if (tp->Rc != RC_FX) {
+ if (tp->Ready) {
+ if (!tp->Complete) {
+ Cmp = tp;
+ break;
+ } // endif Complete
- } else
- b = true;
+ } else
+ b = true;
+
+ } // endif Rc
pthread_mutex_unlock(&tblmut);
diff --git a/storage/connect/tabtbl.h b/storage/connect/tabtbl.h
index 3a5ec45d025..f02bf620aae 100644
--- a/storage/connect/tabtbl.h
+++ b/storage/connect/tabtbl.h
@@ -146,6 +146,7 @@ class DllExport TDBTBM : public TDBTBL {
protected:
// Internal functions
+ bool IsLocal(PTABLE tbp);
bool OpenTables(PGLOBAL g);
int ReadNextRemote(PGLOBAL g);
diff --git a/storage/connect/tabutil.cpp b/storage/connect/tabutil.cpp
index 158cf744a4a..9ab3d5e8806 100644
--- a/storage/connect/tabutil.cpp
+++ b/storage/connect/tabutil.cpp
@@ -186,7 +186,8 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
crp->Kdata->SetValue(colname, i);
chset = (char *)fp->charset()->name;
- v = (!strcmp(chset, "binary")) ? 'B' : 0;
+// v = (!strcmp(chset, "binary")) ? 'B' : 0;
+ v = 0;
if ((type = MYSQLtoPLG(fp->type(), &v)) == TYPE_ERROR) {
if (v == 'K') {
diff --git a/storage/connect/valblk.cpp b/storage/connect/valblk.cpp
index 5b98f3eb425..018c7ee3fe1 100644
--- a/storage/connect/valblk.cpp
+++ b/storage/connect/valblk.cpp
@@ -59,11 +59,12 @@ PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len,
switch (type) {
case TYPE_STRING:
+ case TYPE_BIN:
case TYPE_DECIM:
if (len)
- blkp = new(g) CHRBLK(mp, nval, len, prec, blank);
+ blkp = new(g) CHRBLK(mp, nval, type, len, prec, blank);
else
- blkp = new(g) STRBLK(g, mp, nval);
+ blkp = new(g) STRBLK(g, mp, nval, type);
break;
case TYPE_SHORT:
@@ -615,8 +616,8 @@ int TYPBLK<TYPE>::GetMaxLength(void)
/***********************************************************************/
/* Constructor. */
/***********************************************************************/
-CHRBLK::CHRBLK(void *mp, int nval, int len, int prec, bool blank)
- : VALBLK(mp, TYPE_STRING, nval), Chrp((char*&)Blkp)
+CHRBLK::CHRBLK(void *mp, int nval, int type, int len, int prec, bool blank)
+ : VALBLK(mp, type, nval), Chrp((char*&)Blkp)
{
Valp = NULL;
Blanks = blank;
@@ -1008,8 +1009,8 @@ int CHRBLK::GetMaxLength(void)
/***********************************************************************/
/* Constructor. */
/***********************************************************************/
-STRBLK::STRBLK(PGLOBAL g, void *mp, int nval)
- : VALBLK(mp, TYPE_STRING, nval), Strp((PSZ*&)Blkp)
+STRBLK::STRBLK(PGLOBAL g, void *mp, int nval, int type)
+ : VALBLK(mp, type, nval), Strp((PSZ*&)Blkp)
{
Global = g;
Nullable = true;
diff --git a/storage/connect/valblk.h b/storage/connect/valblk.h
index 38a73424985..a3d7bf30fcf 100644
--- a/storage/connect/valblk.h
+++ b/storage/connect/valblk.h
@@ -214,7 +214,7 @@ class TYPBLK : public VALBLK {
class CHRBLK : public VALBLK {
public:
// Constructors
- CHRBLK(void *mp, int size, int len, int prec, bool b);
+ CHRBLK(void *mp, int size, int type, int len, int prec, bool b);
// Implementation
virtual bool Init(PGLOBAL g, bool check);
@@ -267,7 +267,7 @@ class CHRBLK : public VALBLK {
class STRBLK : public VALBLK {
public:
// Constructors
- STRBLK(PGLOBAL g, void *mp, int size);
+ STRBLK(PGLOBAL g, void *mp, int size, int type);
// Implementation
virtual void SetNull(int n, bool b) {if (b) {Strp[n] = NULL;}}
@@ -345,7 +345,7 @@ class PTRBLK : public STRBLK {
bool, bool, bool);
protected:
// Constructors
- PTRBLK(PGLOBAL g, void *mp, int size) : STRBLK(g, mp, size) {}
+ PTRBLK(PGLOBAL g, void *mp, int size) : STRBLK(g, mp, size, TYPE_PCHAR) {}
// Implementation
diff --git a/storage/connect/value.cpp b/storage/connect/value.cpp
index 60d1c2f459c..a80da808548 100644
--- a/storage/connect/value.cpp
+++ b/storage/connect/value.cpp
@@ -176,7 +176,7 @@ int GetTypeSize(int type, int len)
case TYPE_DOUBLE: len = sizeof(double); break;
case TYPE_TINY: len = sizeof(char); break;
case TYPE_PCHAR: len = sizeof(char*); break;
- default: len = 0;
+ default: len = -1;
} // endswitch type
return len;
@@ -236,6 +236,7 @@ bool IsTypeChar(int type)
switch (type) {
case TYPE_STRING:
case TYPE_DECIM:
+ case TYPE_BIN:
return true;
} // endswitch type
@@ -1369,7 +1370,7 @@ bool TYPVAL<PSZ>::SetValue_char(const char *cp, int n)
if (!cp || n == 0) {
Reset();
- Null = Nullable;
+ Null = (cp) ? false : Nullable;
} else if (cp != Strp) {
const char *p = cp + n - 1;
@@ -1858,8 +1859,9 @@ int DECVAL::CompareValue(PVAL vp)
BINVAL::BINVAL(PGLOBAL g, void *p, int cl, int n) : VALUE(TYPE_BIN)
{
assert(g);
- Len = n;
- Clen = cl;
+//Len = n;
+ Len = (g) ? n : (p) ? strlen((char*)p) : 0;
+ Clen = cl;
Binp = PlugSubAlloc(g, NULL, Clen + 1);
memset(Binp, 0, Clen + 1);
@@ -1992,10 +1994,15 @@ bool BINVAL::SetValue_pval(PVAL valp, bool chktype)
return true;
if (!(Null = valp->IsNull() && Nullable)) {
- if ((rc = (Len = valp->GetSize()) > Clen))
+ int len = Len;
+
+ if ((rc = (Len = valp->GetSize()) > Clen))
Len = Clen;
+ else if (len > Len)
+ memset(Binp, 0, len);
memcpy(Binp, valp->GetTo_Val(), Len);
+ ((char*)Binp)[Len] = 0;
} else
Reset();
@@ -2012,10 +2019,15 @@ bool BINVAL::SetValue_char(const char *p, int n)
bool rc;
if (p && n > 0) {
- rc = n > Clen;
- Len = MY_MIN(n, Clen);
- memcpy(Binp, p, Len);
- Null = false;
+ int len = Len;
+
+ if (len > (Len = MY_MIN(n, Clen)))
+ memset(Binp, 0, len);
+
+ memcpy(Binp, p, Len);
+ ((char*)Binp)[Len] = 0;
+ rc = n > Clen;
+ Null = false;
} else {
rc = false;
Reset();
@@ -2031,9 +2043,14 @@ bool BINVAL::SetValue_char(const char *p, int n)
void BINVAL::SetValue_psz(PCSZ s)
{
if (s) {
- Len = MY_MIN(Clen, (signed)strlen(s));
- memcpy(Binp, s, Len);
- Null = false;
+ int len = Len;
+
+ if (len > (Len = MY_MIN(Clen, (signed)strlen(s))))
+ memset(Binp, 0, len);
+
+ memcpy(Binp, s, Len);
+ ((char*)Binp)[Len] = 0;
+ Null = false;
} else {
Reset();
Null = Nullable;
@@ -2053,14 +2070,19 @@ void BINVAL::SetValue_pvblk(PVBLK blk, int n)
Reset();
Null = Nullable;
} else if (vp != Binp) {
+ int len = Len;
+
if (blk->GetType() == TYPE_STRING)
Len = strlen((char*)vp);
else
Len = blk->GetVlen();
- Len = MY_MIN(Clen, Len);
+ if (len > (Len = MY_MIN(Clen, Len)))
+ memset(Binp, 0, len);
+
memcpy(Binp, vp, Len);
- Null = false;
+ ((char*)Binp)[Len] = 0;
+ Null = false;
} // endif vp
} // end of SetValue_pvblk
@@ -2071,7 +2093,10 @@ void BINVAL::SetValue_pvblk(PVBLK blk, int n)
void BINVAL::SetValue(int n)
{
if (Clen >= 4) {
- *((int*)Binp) = n;
+ if (Len > 4)
+ memset(Binp, 0, Len);
+
+ *((int*)Binp) = n;
Len = 4;
} else
SetValue((short)n);
@@ -2084,7 +2109,10 @@ void BINVAL::SetValue(int n)
void BINVAL::SetValue(uint n)
{
if (Clen >= 4) {
- *((uint*)Binp) = n;
+ if (Len > 4)
+ memset(Binp, 0, Len);
+
+ *((uint*)Binp) = n;
Len = 4;
} else
SetValue((ushort)n);
@@ -2097,7 +2125,10 @@ void BINVAL::SetValue(uint n)
void BINVAL::SetValue(short i)
{
if (Clen >= 2) {
- *((int*)Binp) = i;
+ if (Len > 2)
+ memset(Binp, 0, Len);
+
+ *((int*)Binp) = i;
Len = 2;
} else
SetValue((char)i);
@@ -2110,7 +2141,10 @@ void BINVAL::SetValue(short i)
void BINVAL::SetValue(ushort i)
{
if (Clen >= 2) {
- *((uint*)Binp) = i;
+ if (Len > 2)
+ memset(Binp, 0, Len);
+
+ *((uint*)Binp) = i;
Len = 2;
} else
SetValue((uchar)i);
@@ -2123,7 +2157,10 @@ void BINVAL::SetValue(ushort i)
void BINVAL::SetValue(longlong n)
{
if (Clen >= 8) {
- *((longlong*)Binp) = n;
+ if (Len > 8)
+ memset(Binp, 0, Len);
+
+ *((longlong*)Binp) = n;
Len = 8;
} else
SetValue((int)n);
@@ -2136,7 +2173,10 @@ void BINVAL::SetValue(longlong n)
void BINVAL::SetValue(ulonglong n)
{
if (Clen >= 8) {
- *((ulonglong*)Binp) = n;
+ if (Len > 8)
+ memset(Binp, 0, Len);
+
+ *((ulonglong*)Binp) = n;
Len = 8;
} else
SetValue((uint)n);
@@ -2147,6 +2187,9 @@ void BINVAL::SetValue(ulonglong n)
/***********************************************************************/
void BINVAL::SetValue(double n)
{
+ if (Len > 8)
+ memset(Binp, 0, Len);
+
if (Clen >= 8) {
*((double*)Binp) = n;
Len = 8;
@@ -2163,7 +2206,10 @@ void BINVAL::SetValue(double n)
/***********************************************************************/
void BINVAL::SetValue(char c)
{
- *((char*)Binp) = c;
+ if (Len > 1)
+ memset(Binp, 0, Len);
+
+ *((char*)Binp) = c;
Len = 1;
} // end of SetValue
@@ -2172,7 +2218,10 @@ void BINVAL::SetValue(char c)
/***********************************************************************/
void BINVAL::SetValue(uchar c)
{
- *((uchar*)Binp) = c;
+ if (Len > 1)
+ memset(Binp, 0, Len);
+
+ *((uchar*)Binp) = c;
Len = 1;
} // end of SetValue
@@ -2182,6 +2231,7 @@ void BINVAL::SetValue(uchar c)
void BINVAL::SetBinValue(void *p)
{
memcpy(Binp, p, Clen);
+ Len = Clen;
} // end of SetBinValue
/***********************************************************************/
@@ -2207,10 +2257,11 @@ bool BINVAL::GetBinValue(void *buf, int buflen, bool go)
/***********************************************************************/
char *BINVAL::ShowValue(char *buf, int len)
{
- int n = MY_MIN(Len, len / 2);
+ //int n = MY_MIN(Len, len / 2);
- sprintf(buf, GetXfmt(), n, Binp);
- return buf;
+ //sprintf(buf, GetXfmt(), n, Binp);
+ //return buf;
+ return (char*)Binp;
} // end of ShowValue
/***********************************************************************/
diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc
index e35da50ba96..059113e2fa5 100644
--- a/storage/federated/ha_federated.cc
+++ b/storage/federated/ha_federated.cc
@@ -2980,6 +2980,9 @@ int ha_federated::reset(void)
}
reset_dynamic(&results);
+ if (mysql)
+ mysql->net.thd= NULL;
+
return 0;
}
@@ -3200,12 +3203,14 @@ int ha_federated::real_query(const char *query, size_t length)
int rc= 0;
DBUG_ENTER("ha_federated::real_query");
- if (!mysql && (rc= real_connect()))
+ if (!query || !length)
goto end;
- if (!query || !length)
+ if (!mysql && (rc= real_connect()))
goto end;
+ mysql->net.thd= table->in_use;
+
rc= mysql_real_query(mysql, query, (uint) length);
end:
@@ -3289,66 +3294,6 @@ int ha_federated::external_lock(THD *thd, int lock_type)
int error= 0;
DBUG_ENTER("ha_federated::external_lock");
- /*
- Support for transactions disabled until WL#2952 fixes it.
- */
-#ifdef XXX_SUPERCEDED_BY_WL2952
- if (lock_type != F_UNLCK)
- {
- ha_federated *trx= (ha_federated *)thd_get_ha_data(thd, ht);
-
- DBUG_PRINT("info",("federated not lock F_UNLCK"));
- if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
- {
- DBUG_PRINT("info",("federated autocommit"));
- /*
- This means we are doing an autocommit
- */
- error= connection_autocommit(TRUE);
- if (error)
- {
- DBUG_PRINT("info", ("error setting autocommit TRUE: %d", error));
- DBUG_RETURN(error);
- }
- trans_register_ha(thd, FALSE, ht);
- }
- else
- {
- DBUG_PRINT("info",("not autocommit"));
- if (!trx)
- {
- /*
- This is where a transaction gets its start
- */
- error= connection_autocommit(FALSE);
- if (error)
- {
- DBUG_PRINT("info", ("error setting autocommit FALSE: %d", error));
- DBUG_RETURN(error);
- }
- thd_set_ha_data(thd, ht, this);
- trans_register_ha(thd, TRUE, ht);
- /*
- Send a lock table to the remote end.
- We do not support this at the moment
- */
- if (thd->options & (OPTION_TABLE_LOCK))
- {
- DBUG_PRINT("info", ("We do not support lock table yet"));
- }
- }
- else
- {
- ha_federated *ptr;
- for (ptr= trx; ptr; ptr= ptr->trx_next)
- if (ptr == this)
- break;
- else if (!ptr->trx_next)
- ptr->trx_next= this;
- }
- }
- }
-#endif /* XXX_SUPERCEDED_BY_WL2952 */
table_will_be_deleted = FALSE;
DBUG_RETURN(error);
}
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc
index 815324825bd..3e9f26ad125 100644
--- a/storage/innobase/btr/btr0btr.cc
+++ b/storage/innobase/btr/btr0btr.cc
@@ -720,8 +720,9 @@ btr_page_free_low(
ulint* offsets = NULL;
rec_t* rec = page_rec_get_next(page_get_infimum_rec(page));
while (!page_rec_is_supremum(rec)) {
- offsets = rec_get_offsets(rec, index,
- offsets, ULINT_UNDEFINED,
+ offsets = rec_get_offsets(rec, index, offsets,
+ page_is_leaf(page),
+ ULINT_UNDEFINED,
&heap);
ulint size = rec_offs_data_size(offsets);
memset(rec, 0, size);
@@ -832,7 +833,7 @@ btr_node_ptr_set_child_page_no(
ulint len;
ut_ad(rec_offs_validate(rec, NULL, offsets));
- ut_ad(!page_is_leaf(page_align(rec)));
+ ut_ad(!page_rec_is_leaf(rec));
ut_ad(!rec_offs_comp(offsets) || rec_get_node_ptr_flag(rec));
/* The child address is in the last field */
@@ -937,7 +938,7 @@ btr_page_get_father_node_ptr_func(
node_ptr = btr_cur_get_rec(cursor);
- offsets = rec_get_offsets(node_ptr, index, offsets,
+ offsets = rec_get_offsets(node_ptr, index, offsets, false,
ULINT_UNDEFINED, &heap);
if (btr_node_ptr_get_child_page_no(node_ptr, offsets) != page_no) {
@@ -953,10 +954,11 @@ btr_page_get_father_node_ptr_func(
print_rec = page_rec_get_next(
page_get_infimum_rec(page_align(user_rec)));
- offsets = rec_get_offsets(print_rec, index,
- offsets, ULINT_UNDEFINED, &heap);
+ offsets = rec_get_offsets(print_rec, index, offsets,
+ page_rec_is_leaf(user_rec),
+ ULINT_UNDEFINED, &heap);
page_rec_print(print_rec, offsets);
- offsets = rec_get_offsets(node_ptr, index, offsets,
+ offsets = rec_get_offsets(node_ptr, index, offsets, false,
ULINT_UNDEFINED, &heap);
page_rec_print(node_ptr, offsets);
@@ -2275,9 +2277,9 @@ btr_page_get_split_rec(
/* Include tuple */
incl_data += insert_size;
} else {
- offsets = rec_get_offsets(rec, cursor->index,
- offsets, ULINT_UNDEFINED,
- &heap);
+ offsets = rec_get_offsets(rec, cursor->index, offsets,
+ page_is_leaf(page),
+ ULINT_UNDEFINED, &heap);
incl_data += rec_offs_size(offsets);
}
@@ -2385,6 +2387,7 @@ btr_page_insert_fits(
space after rec is removed from page. */
*offsets = rec_get_offsets(rec, cursor->index, *offsets,
+ page_is_leaf(page),
ULINT_UNDEFINED, heap);
total_data -= rec_offs_size(*offsets);
@@ -2673,7 +2676,7 @@ btr_page_tuple_smaller(
first_rec = page_cur_get_rec(&pcur);
*offsets = rec_get_offsets(
- first_rec, cursor->index, *offsets,
+ first_rec, cursor->index, *offsets, page_is_leaf(block->frame),
n_uniq, heap);
return(cmp_dtuple_rec(tuple, first_rec, *offsets) < 0);
@@ -2980,7 +2983,7 @@ func_start:
first_rec = move_limit = split_rec;
*offsets = rec_get_offsets(split_rec, cursor->index, *offsets,
- n_uniq, heap);
+ page_is_leaf(page), n_uniq, heap);
if (tuple != NULL) {
insert_left = cmp_dtuple_rec(
@@ -3808,8 +3811,9 @@ retry:
cursor2.tree_height = cursor->tree_height;
offsets2 = rec_get_offsets(
- btr_cur_get_rec(&cursor2), index,
- NULL, ULINT_UNDEFINED, &heap);
+ btr_cur_get_rec(&cursor2), index, NULL,
+ page_is_leaf(cursor2.page_cur.block->frame),
+ ULINT_UNDEFINED, &heap);
/* Check if parent entry needs to be updated */
mbr_changed = rtr_merge_mbr_changed(
@@ -3989,8 +3993,9 @@ retry:
ulint rec_info;
offsets2 = rec_get_offsets(
- btr_cur_get_rec(&cursor2),
- index, NULL, ULINT_UNDEFINED, &heap);
+ btr_cur_get_rec(&cursor2), index, NULL,
+ page_is_leaf(cursor2.page_cur.block->frame),
+ ULINT_UNDEFINED, &heap);
ut_ad(btr_node_ptr_get_child_page_no(
btr_cur_get_rec(&cursor2), offsets2)
@@ -4468,8 +4473,9 @@ btr_print_recursive(
node_ptr = page_cur_get_rec(&cursor);
- *offsets = rec_get_offsets(node_ptr, index, *offsets,
- ULINT_UNDEFINED, heap);
+ *offsets = rec_get_offsets(
+ node_ptr, index, *offsets, false,
+ ULINT_UNDEFINED, heap);
btr_print_recursive(index,
btr_node_ptr_get_child(node_ptr,
index,
@@ -4662,7 +4668,8 @@ btr_index_rec_validate(
return(FALSE);
}
- offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
+ offsets = rec_get_offsets(rec, index, offsets, page_is_leaf(page),
+ ULINT_UNDEFINED, &heap);
for (i = 0; i < n; i++) {
dict_field_t* field = dict_index_get_nth_field(index, i);
@@ -4916,7 +4923,7 @@ btr_validate_level(
page_cur_move_to_next(&cursor);
node_ptr = page_cur_get_rec(&cursor);
- offsets = rec_get_offsets(node_ptr, index, offsets,
+ offsets = rec_get_offsets(node_ptr, index, offsets, false,
ULINT_UNDEFINED, &heap);
savepoint2 = mtr_set_savepoint(&mtr);
@@ -5042,10 +5049,12 @@ loop:
rec = page_rec_get_prev(page_get_supremum_rec(page));
right_rec = page_rec_get_next(page_get_infimum_rec(
right_page));
- offsets = rec_get_offsets(rec, index,
- offsets, ULINT_UNDEFINED, &heap);
- offsets2 = rec_get_offsets(right_rec, index,
- offsets2, ULINT_UNDEFINED, &heap);
+ offsets = rec_get_offsets(rec, index, offsets,
+ page_is_leaf(page),
+ ULINT_UNDEFINED, &heap);
+ offsets2 = rec_get_offsets(right_rec, index, offsets2,
+ page_is_leaf(right_page),
+ ULINT_UNDEFINED, &heap);
/* For spatial index, we cannot guarantee the key ordering
across pages, so skip the record compare verification for
diff --git a/storage/innobase/btr/btr0bulk.cc b/storage/innobase/btr/btr0bulk.cc
index 8a954f9d3c3..139e3116d06 100644
--- a/storage/innobase/btr/btr0bulk.cc
+++ b/storage/innobase/btr/btr0bulk.cc
@@ -176,7 +176,8 @@ PageBulk::insert(
if (!page_rec_is_infimum(m_cur_rec)) {
rec_t* old_rec = m_cur_rec;
ulint* old_offsets = rec_get_offsets(
- old_rec, m_index, NULL, ULINT_UNDEFINED, &m_heap);
+ old_rec, m_index, NULL, page_rec_is_leaf(old_rec),
+ ULINT_UNDEFINED, &m_heap);
ut_ad(cmp_rec_rec(rec, old_rec, offsets, old_offsets, m_index)
> 0);
@@ -377,9 +378,9 @@ PageBulk::getSplitRec()
rec = page_rec_get_next(rec);
ut_ad(page_rec_is_user_rec(rec));
- offsets = rec_get_offsets(rec, m_index,
- offsets, ULINT_UNDEFINED,
- &(m_heap));
+ offsets = rec_get_offsets(rec, m_index, offsets,
+ page_is_leaf(m_page),
+ ULINT_UNDEFINED, &m_heap);
total_recs_size += rec_offs_size(offsets);
n_recs++;
} while (total_recs_size + page_dir_calc_reserved_space(n_recs)
@@ -409,7 +410,8 @@ PageBulk::copyIn(
do {
offsets = rec_get_offsets(rec, m_index, offsets,
- ULINT_UNDEFINED, &(m_heap));
+ page_rec_is_leaf(split_rec),
+ ULINT_UNDEFINED, &m_heap);
insert(rec, offsets);
@@ -449,18 +451,18 @@ PageBulk::copyOut(
/* Set last record's next in page */
ulint* offsets = NULL;
rec = page_rec_get_prev(split_rec);
- offsets = rec_get_offsets(rec, m_index,
- offsets, ULINT_UNDEFINED,
- &(m_heap));
+ offsets = rec_get_offsets(rec, m_index, offsets,
+ page_rec_is_leaf(split_rec),
+ ULINT_UNDEFINED, &m_heap);
page_rec_set_next(rec, page_get_supremum_rec(m_page));
/* Set related members */
m_cur_rec = rec;
m_heap_top = rec_get_end(rec, offsets);
- offsets = rec_get_offsets(last_rec, m_index,
- offsets, ULINT_UNDEFINED,
- &(m_heap));
+ offsets = rec_get_offsets(last_rec, m_index, offsets,
+ page_rec_is_leaf(split_rec),
+ ULINT_UNDEFINED, &m_heap);
m_free_space += rec_get_end(last_rec, offsets)
- m_heap_top
@@ -876,8 +878,8 @@ BtrBulk::insert(
/* Convert tuple to rec. */
rec = rec_convert_dtuple_to_rec(static_cast<byte*>(mem_heap_alloc(
page_bulk->m_heap, rec_size)), m_index, tuple, n_ext);
- offsets = rec_get_offsets(rec, m_index, offsets, ULINT_UNDEFINED,
- &(page_bulk->m_heap));
+ offsets = rec_get_offsets(rec, m_index, offsets, !level,
+ ULINT_UNDEFINED, &page_bulk->m_heap);
page_bulk->insert(rec, offsets);
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index 40317c54334..63eac83337f 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -1545,8 +1545,8 @@ retry_page_get:
node_ptr = page_cur_get_rec(page_cursor);
- offsets = rec_get_offsets(
- node_ptr, index, offsets, ULINT_UNDEFINED, &heap);
+ offsets = rec_get_offsets(node_ptr, index, offsets, false,
+ ULINT_UNDEFINED, &heap);
/* If the rec is the first or last in the page for
pessimistic delete intention, it might cause node_ptr insert
@@ -1662,10 +1662,8 @@ need_opposite_intention:
&& latch_mode == BTR_MODIFY_TREE
&& (up_match >= rec_offs_n_fields(offsets) - 1
|| low_match >= rec_offs_n_fields(offsets) - 1)) {
- const rec_t* first_rec
- = page_rec_get_next_const(
- page_get_infimum_rec(
- page));
+ const rec_t* first_rec = page_rec_get_next_const(
+ page_get_infimum_rec(page));
ulint matched_fields;
ut_ad(upper_rw_latch == RW_X_LATCH);
@@ -1678,7 +1676,7 @@ need_opposite_intention:
offsets2 = rec_get_offsets(
first_rec, index, offsets2,
- ULINT_UNDEFINED, &heap);
+ false, ULINT_UNDEFINED, &heap);
cmp_rec_rec_with_match(node_ptr, first_rec,
offsets, offsets2, index, FALSE,
&matched_fields);
@@ -1690,14 +1688,13 @@ need_opposite_intention:
const rec_t* last_rec;
last_rec = page_rec_get_prev_const(
- page_get_supremum_rec(
- page));
+ page_get_supremum_rec(page));
matched_fields = 0;
offsets2 = rec_get_offsets(
last_rec, index, offsets2,
- ULINT_UNDEFINED, &heap);
+ false, ULINT_UNDEFINED, &heap);
cmp_rec_rec_with_match(
node_ptr, last_rec,
offsets, offsets2, index,
@@ -1854,14 +1851,9 @@ need_opposite_intention:
cursor->rtr_info->path;
if (!path->empty() && found) {
-#ifdef UNIV_DEBUG
- node_visit_t last_visit = path->back();
-
- ut_ad(last_visit.page_no == page_id.page_no());
-#endif /* UNIV_DEBUG */
-
+ ut_ad(path->back().page_no
+ == page_id.page_no());
path->pop_back();
-
#ifdef UNIV_DEBUG
if (page_mode == PAGE_CUR_RTREE_LOCATE
&& (latch_mode != BTR_MODIFY_LEAF)) {
@@ -1873,14 +1865,13 @@ need_opposite_intention:
offsets = rec_get_offsets(
my_node_ptr, index, offsets,
- ULINT_UNDEFINED, &heap);
+ false, ULINT_UNDEFINED, &heap);
ulint my_page_no
= btr_node_ptr_get_child_page_no(
my_node_ptr, offsets);
ut_ad(page_id.page_no() == my_page_no);
-
}
#endif
}
@@ -2316,7 +2307,7 @@ btr_cur_open_at_index_side_func(
node_ptr = page_cur_get_rec(page_cursor);
offsets = rec_get_offsets(node_ptr, cursor->index, offsets,
- ULINT_UNDEFINED, &heap);
+ false, ULINT_UNDEFINED, &heap);
/* If the rec is the first or last in the page for
pessimistic delete intention, it might cause node_ptr insert
@@ -2612,7 +2603,7 @@ btr_cur_open_at_rnd_pos_func(
node_ptr = page_cur_get_rec(page_cursor);
offsets = rec_get_offsets(node_ptr, cursor->index, offsets,
- ULINT_UNDEFINED, &heap);
+ false, ULINT_UNDEFINED, &heap);
/* If the rec is the first or last in the page for
pessimistic delete intention, it might cause node_ptr insert
@@ -3086,10 +3077,11 @@ fail_err:
}
#ifdef BTR_CUR_HASH_ADAPT
+ if (!leaf) {
# ifdef MYSQL_INDEX_DISABLE_AHI
- if (index->disable_ahi); else
+ } else if (index->disable_ahi) {
# endif
- if (!reorg && leaf && (cursor->flag == BTR_CUR_HASH)) {
+ } else if (!reorg && cursor->flag == BTR_CUR_HASH) {
btr_search_update_hash_node_on_insert(cursor);
} else {
btr_search_update_hash_on_insert(cursor);
@@ -3285,15 +3277,19 @@ btr_cur_pessimistic_insert(
}
}
+ if (!page_is_leaf(btr_cur_get_page(cursor))) {
+ ut_ad(!big_rec_vec);
+ } else {
#ifdef BTR_CUR_HASH_ADAPT
# ifdef MYSQL_INDEX_DISABLE_AHI
- if (index->disable_ahi); else
+ if (index->disable_ahi); else
# endif
- btr_search_update_hash_on_insert(cursor);
+ btr_search_update_hash_on_insert(cursor);
#endif /* BTR_CUR_HASH_ADAPT */
- if (inherit && !(flags & BTR_NO_LOCKING_FLAG)) {
+ if (inherit && !(flags & BTR_NO_LOCKING_FLAG)) {
- lock_update_insert(btr_cur_get_block(cursor), *rec);
+ lock_update_insert(btr_cur_get_block(cursor), *rec);
+ }
}
if (n_reserved > 0) {
@@ -3489,7 +3485,8 @@ btr_cur_parse_update_in_place(
/* We do not need to reserve search latch, as the page is only
being recovered, and there cannot be a hash index to it. */
- offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
+ offsets = rec_get_offsets(rec, index, NULL, true,
+ ULINT_UNDEFINED, &heap);
if (!(flags & BTR_KEEP_SYS_FLAG)) {
row_upd_rec_sys_fields_in_recovery(rec, page_zip, offsets,
@@ -3813,7 +3810,7 @@ btr_cur_optimistic_update(
ut_ad(fil_page_index_page_check(page));
ut_ad(btr_page_get_index_id(page) == index->id);
- *offsets = rec_get_offsets(rec, index, *offsets,
+ *offsets = rec_get_offsets(rec, index, *offsets, true,
ULINT_UNDEFINED, heap);
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ut_a(!rec_offs_any_null_extern(rec, *offsets)
@@ -4180,7 +4177,8 @@ btr_cur_pessimistic_update(
rec = btr_cur_get_rec(cursor);
*offsets = rec_get_offsets(
- rec, index, *offsets, ULINT_UNDEFINED, offsets_heap);
+ rec, index, *offsets, page_is_leaf(page),
+ ULINT_UNDEFINED, offsets_heap);
dtuple_t* new_entry = row_rec_to_index_entry(
rec, index, *offsets, &n_ext, entry_heap);
@@ -4614,7 +4612,7 @@ btr_cur_parse_del_mark_set_clust_rec(
if (!(flags & BTR_KEEP_SYS_FLAG)) {
row_upd_rec_sys_fields_in_recovery(
rec, page_zip,
- rec_get_offsets(rec, index, offsets,
+ rec_get_offsets(rec, index, offsets, true,
pos + 2, &heap),
pos, trx_id, roll_ptr);
} else {
@@ -4623,8 +4621,8 @@ btr_cur_parse_del_mark_set_clust_rec(
ut_ad(memcmp(rec_get_nth_field(
rec,
rec_get_offsets(rec, index,
- offsets, pos,
- &heap),
+ offsets, true,
+ pos, &heap),
pos, &offset),
field_ref_zero, DATA_TRX_ID_LEN));
ut_ad(offset == DATA_TRX_ID_LEN);
@@ -4665,7 +4663,7 @@ btr_cur_del_mark_set_clust_rec(
ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table));
ut_ad(buf_block_get_frame(block) == page_align(rec));
- ut_ad(page_is_leaf(page_align(rec)));
+ ut_ad(page_rec_is_leaf(rec));
ut_ad(mtr->is_named_space(index->space));
if (rec_get_deleted_flag(rec, rec_offs_comp(offsets))) {
@@ -4959,7 +4957,7 @@ btr_cur_optimistic_delete_func(
|| (flags & BTR_CREATE_FLAG));
rec = btr_cur_get_rec(cursor);
- offsets = rec_get_offsets(rec, cursor->index, offsets,
+ offsets = rec_get_offsets(rec, cursor->index, offsets, true,
ULINT_UNDEFINED, &heap);
no_compress_needed = !rec_offs_any_extern(offsets)
@@ -5103,7 +5101,8 @@ btr_cur_pessimistic_delete(
ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
- offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
+ offsets = rec_get_offsets(rec, index, NULL, page_is_leaf(page),
+ ULINT_UNDEFINED, &heap);
if (rec_offs_any_extern(offsets)) {
btr_rec_free_externally_stored_fields(index,
@@ -5134,10 +5133,9 @@ btr_cur_pessimistic_delete(
level = btr_page_get_level(page, mtr);
- if (level > 0
- && UNIV_UNLIKELY(rec == page_rec_get_next(
- page_get_infimum_rec(page)))) {
-
+ if (level == 0) {
+ btr_search_update_hash_on_delete(cursor);
+ } else if (UNIV_UNLIKELY(page_rec_is_first(rec, page))) {
rec_t* next_rec = page_rec_get_next(rec);
if (btr_page_get_prev(page, mtr) == FIL_NULL) {
@@ -5166,8 +5164,8 @@ btr_cur_pessimistic_delete(
block, mtr, NULL,
&father_cursor);
offsets = rec_get_offsets(
- btr_cur_get_rec(&father_cursor), index,
- NULL, ULINT_UNDEFINED, &heap);
+ btr_cur_get_rec(&father_cursor), index, NULL,
+ false, ULINT_UNDEFINED, &heap);
father_rec = btr_cur_get_rec(&father_cursor);
rtr_read_mbr(rec_get_nth_field(
@@ -5204,8 +5202,6 @@ btr_cur_pessimistic_delete(
}
}
- btr_search_update_hash_on_delete(cursor);
-
page_cur_delete_rec(btr_cur_get_page_cur(cursor), index, offsets, mtr);
#ifdef UNIV_ZIP_DEBUG
ut_a(!page_zip || page_zip_validate(page_zip, page, index));
@@ -6061,10 +6057,12 @@ btr_estimate_number_of_different_key_vals(
page = btr_cur_get_page(&cursor);
rec = page_rec_get_next(page_get_infimum_rec(page));
+ ut_d(const bool is_leaf = page_is_leaf(page));
if (!page_rec_is_supremum(rec)) {
not_empty_flag = 1;
offsets_rec = rec_get_offsets(rec, index, offsets_rec,
+ is_leaf,
ULINT_UNDEFINED, &heap);
if (n_not_null != NULL) {
@@ -6085,6 +6083,7 @@ btr_estimate_number_of_different_key_vals(
offsets_next_rec = rec_get_offsets(next_rec, index,
offsets_next_rec,
+ is_leaf,
ULINT_UNDEFINED,
&heap);
@@ -7353,6 +7352,8 @@ btr_rec_free_externally_stored_fields(
ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(mtr_is_page_fix(mtr, rec, MTR_MEMO_PAGE_X_FIX, index->table));
+ ut_ad(dict_index_is_clust(index));
+ ut_ad(page_rec_is_leaf(rec));
/* Free possible externally stored fields in the record */
ut_ad(dict_table_is_comp(index->table) == !!rec_offs_comp(offsets));
diff --git a/storage/innobase/btr/btr0defragment.cc b/storage/innobase/btr/btr0defragment.cc
index d4b83930191..335b4fc220d 100644
--- a/storage/innobase/btr/btr0defragment.cc
+++ b/storage/innobase/btr/btr0defragment.cc
@@ -402,6 +402,7 @@ btr_defragment_calc_n_recs_for_size(
while (page_cur_get_rec(&cur) != page_get_supremum_rec(page)) {
rec_t* cur_rec = page_cur_get_rec(&cur);
offsets = rec_get_offsets(cur_rec, index, offsets,
+ page_is_leaf(page),
ULINT_UNDEFINED, &heap);
ulint rec_size = rec_offs_size(offsets);
size += rec_size;
diff --git a/storage/innobase/btr/btr0pcur.cc b/storage/innobase/btr/btr0pcur.cc
index fdde6f5d3e7..2b85c764a3b 100644
--- a/storage/innobase/btr/btr0pcur.cc
+++ b/storage/innobase/btr/btr0pcur.cc
@@ -303,10 +303,10 @@ btr_pcur_restore_position_func(
heap = mem_heap_create(256);
offsets1 = rec_get_offsets(
- cursor->old_rec, index, NULL,
+ cursor->old_rec, index, NULL, true,
cursor->old_n_fields, &heap);
offsets2 = rec_get_offsets(
- rec, index, NULL,
+ rec, index, NULL, true,
cursor->old_n_fields, &heap);
ut_ad(!cmp_rec_rec(cursor->old_rec,
@@ -331,7 +331,7 @@ btr_pcur_restore_position_func(
heap = mem_heap_create(256);
- tuple = dict_index_build_data_tuple(index, cursor->old_rec,
+ tuple = dict_index_build_data_tuple(cursor->old_rec, index, true,
cursor->old_n_fields, heap);
/* Save the old search mode of the cursor */
@@ -365,7 +365,8 @@ btr_pcur_restore_position_func(
&& btr_pcur_is_on_user_rec(cursor)
&& !cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor),
rec_get_offsets(btr_pcur_get_rec(cursor),
- index, NULL, ULINT_UNDEFINED, &heap))) {
+ index, NULL, true,
+ ULINT_UNDEFINED, &heap))) {
/* We have to store the NEW value for the modify clock,
since the cursor can now be on a different page!
diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc
index 3ae9e95819a..750c2506ff5 100644
--- a/storage/innobase/btr/btr0sea.cc
+++ b/storage/innobase/btr/btr0sea.cc
@@ -609,8 +609,8 @@ btr_search_update_hash_ref(
ut_ad(rw_lock_own(btr_get_search_latch(cursor->index), RW_LOCK_X));
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_S)
|| rw_lock_own(&(block->lock), RW_LOCK_X));
- ut_ad(page_align(btr_cur_get_rec(cursor))
- == buf_block_get_frame(block));
+ ut_ad(page_align(btr_cur_get_rec(cursor)) == block->frame);
+ ut_ad(page_is_leaf(block->frame));
assert_block_ahi_valid(block);
index = block->index;
@@ -640,7 +640,7 @@ btr_search_update_hash_ref(
}
fold = rec_fold(rec,
- rec_get_offsets(rec, index, offsets_,
+ rec_get_offsets(rec, index, offsets_, true,
ULINT_UNDEFINED, &heap),
block->curr_n_fields,
block->curr_n_bytes, index->id);
@@ -750,10 +750,11 @@ btr_search_check_guess(
rec = btr_cur_get_rec(cursor);
ut_ad(page_rec_is_user_rec(rec));
+ ut_ad(page_rec_is_leaf(rec));
match = 0;
- offsets = rec_get_offsets(rec, cursor->index, offsets,
+ offsets = rec_get_offsets(rec, cursor->index, offsets, true,
n_unique, &heap);
cmp = cmp_dtuple_rec_with_match(tuple, rec, offsets, &match);
@@ -808,7 +809,7 @@ btr_search_check_guess(
}
offsets = rec_get_offsets(prev_rec, cursor->index, offsets,
- n_unique, &heap);
+ true, n_unique, &heap);
cmp = cmp_dtuple_rec_with_match(
tuple, prev_rec, offsets, &match);
if (mode == PAGE_CUR_GE) {
@@ -837,7 +838,7 @@ btr_search_check_guess(
}
offsets = rec_get_offsets(next_rec, cursor->index, offsets,
- n_unique, &heap);
+ true, n_unique, &heap);
cmp = cmp_dtuple_rec_with_match(
tuple, next_rec, offsets, &match);
if (mode == PAGE_CUR_LE) {
@@ -1139,6 +1140,7 @@ retry:
|| buf_block_get_state(block) == BUF_BLOCK_REMOVE_HASH
|| rw_lock_own(&block->lock, RW_LOCK_S)
|| rw_lock_own(&block->lock, RW_LOCK_X));
+ ut_ad(page_is_leaf(block->frame));
/* We must not dereference index here, because it could be freed
if (index->table->n_ref_count == 0 && !mutex_own(&dict_sys->mutex)).
@@ -1229,7 +1231,7 @@ retry:
while (!page_rec_is_supremum(rec)) {
offsets = rec_get_offsets(
- rec, index, offsets,
+ rec, index, offsets, true,
btr_search_get_n_fields(n_fields, n_bytes),
&heap);
fold = rec_fold(rec, offsets, n_fields, n_bytes, index_id);
@@ -1392,6 +1394,7 @@ btr_search_build_page_hash_index(
ut_ad(index);
ut_ad(block->page.id.space() == index->space);
ut_a(!dict_index_is_ibuf(index));
+ ut_ad(page_is_leaf(block->frame));
ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_S)
@@ -1445,7 +1448,7 @@ btr_search_build_page_hash_index(
rec = page_rec_get_next(page_get_infimum_rec(page));
offsets = rec_get_offsets(
- rec, index, offsets,
+ rec, index, offsets, true,
btr_search_get_n_fields(n_fields, n_bytes),
&heap);
ut_ad(page_rec_is_supremum(rec)
@@ -1476,7 +1479,7 @@ btr_search_build_page_hash_index(
}
offsets = rec_get_offsets(
- next_rec, index, offsets,
+ next_rec, index, offsets, true,
btr_search_get_n_fields(n_fields, n_bytes), &heap);
next_fold = rec_fold(next_rec, offsets, n_fields,
n_bytes, index->id);
@@ -1630,9 +1633,11 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor)
mem_heap_t* heap = NULL;
rec_offs_init(offsets_);
+ ut_ad(page_is_leaf(btr_cur_get_page(cursor)));
#ifdef MYSQL_INDEX_DISABLE_AHI
if (cursor->index->disable_ahi) return;
#endif
+
if (!btr_search_enabled) {
return;
}
@@ -1658,7 +1663,7 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor)
rec = btr_cur_get_rec(cursor);
- fold = rec_fold(rec, rec_get_offsets(rec, index, offsets_,
+ fold = rec_fold(rec, rec_get_offsets(rec, index, offsets_, true,
ULINT_UNDEFINED, &heap),
block->curr_n_fields, block->curr_n_bytes, index->id);
if (UNIV_LIKELY_NULL(heap)) {
@@ -1777,6 +1782,7 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor)
ulint* offsets = offsets_;
rec_offs_init(offsets_);
+ ut_ad(page_is_leaf(btr_cur_get_page(cursor)));
#ifdef MYSQL_INDEX_DISABLE_AHI
if (cursor->index->disable_ahi) return;
#endif
@@ -1816,13 +1822,13 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor)
ins_rec = page_rec_get_next_const(rec);
next_rec = page_rec_get_next_const(ins_rec);
- offsets = rec_get_offsets(ins_rec, index, offsets,
+ offsets = rec_get_offsets(ins_rec, index, offsets, true,
ULINT_UNDEFINED, &heap);
ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, index->id);
if (!page_rec_is_supremum(next_rec)) {
offsets = rec_get_offsets(
- next_rec, index, offsets,
+ next_rec, index, offsets, true,
btr_search_get_n_fields(n_fields, n_bytes), &heap);
next_fold = rec_fold(next_rec, offsets, n_fields,
n_bytes, index->id);
@@ -1830,7 +1836,7 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor)
if (!page_rec_is_infimum(rec)) {
offsets = rec_get_offsets(
- rec, index, offsets,
+ rec, index, offsets, true,
btr_search_get_n_fields(n_fields, n_bytes), &heap);
fold = rec_fold(rec, offsets, n_fields, n_bytes, index->id);
} else {
@@ -2029,7 +2035,7 @@ btr_search_hash_table_validate(ulint hash_table_id)
page_index_id = btr_page_get_index_id(block->frame);
offsets = rec_get_offsets(
- node->data, block->index, offsets,
+ node->data, block->index, offsets, true,
btr_search_get_n_fields(block->curr_n_fields,
block->curr_n_bytes),
&heap);
diff --git a/storage/innobase/data/data0data.cc b/storage/innobase/data/data0data.cc
index e511a676054..9ed4faa8e70 100644
--- a/storage/innobase/data/data0data.cc
+++ b/storage/innobase/data/data0data.cc
@@ -803,14 +803,11 @@ big_rec_t::alloc(
return(rec);
}
-/** Create a deep copy of this object
-@param[in] heap the memory heap in which the clone will be
- created.
-
-@return the cloned object. */
+/** Create a deep copy of this object.
+@param[in,out] heap memory heap in which the clone will be created
+@return the cloned object */
dfield_t*
-dfield_t::clone(
- mem_heap_t* heap)
+dfield_t::clone(mem_heap_t* heap) const
{
const ulint size = len == UNIV_SQL_NULL ? 0 : len;
dfield_t* obj = static_cast<dfield_t*>(
diff --git a/storage/innobase/dict/dict0defrag_bg.cc b/storage/innobase/dict/dict0defrag_bg.cc
index ccb73e02f43..3d1ee3f76e9 100644
--- a/storage/innobase/dict/dict0defrag_bg.cc
+++ b/storage/innobase/dict/dict0defrag_bg.cc
@@ -290,7 +290,7 @@ dict_stats_save_defrag_summary(
dberr_t ret=DB_SUCCESS;
lint now = (lint) ut_time();
- if (dict_index_is_univ(index)) {
+ if (dict_index_is_ibuf(index)) {
return DB_SUCCESS;
}
@@ -320,7 +320,7 @@ dict_stats_save_defrag_stats(
{
dberr_t ret;
- if (dict_index_is_univ(index)) {
+ if (dict_index_is_ibuf(index)) {
return DB_SUCCESS;
}
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 55429b2680f..ecd8839c36e 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -5654,7 +5654,7 @@ dict_index_build_node_ptr(
dtype_set(dfield_get_type(field), DATA_SYS_CHILD, DATA_NOT_NULL, 4);
- rec_copy_prefix_to_dtuple(tuple, rec, index, n_unique, heap);
+ rec_copy_prefix_to_dtuple(tuple, rec, index, !level, n_unique, heap);
dtuple_set_info_bits(tuple, dtuple_get_info_bits(tuple)
| REC_STATUS_NODE_PTR);
@@ -5686,7 +5686,7 @@ dict_index_copy_rec_order_prefix(
ut_a(!dict_table_is_comp(index->table));
n = rec_get_n_fields_old(rec);
} else {
- if (page_is_leaf(page_align(rec))) {
+ if (page_rec_is_leaf(rec)) {
n = dict_index_get_n_unique_in_tree(index);
} else {
n = dict_index_get_n_unique_in_tree_nonleaf(index);
@@ -5703,16 +5703,22 @@ dict_index_copy_rec_order_prefix(
return(rec_copy_prefix_to_buf(rec, index, n, buf, buf_size));
}
-/**********************************************************************//**
-Builds a typed data tuple out of a physical record.
+/** Convert a physical record into a search tuple.
+@param[in] rec index record (not necessarily in an index page)
+@param[in] index index
+@param[in] leaf whether rec is in a leaf page
+@param[in] n_fields number of data fields
+@param[in,out] heap memory heap for allocation
@return own: data tuple */
dtuple_t*
-dict_index_build_data_tuple(
-/*========================*/
- dict_index_t* index, /*!< in: index tree */
- rec_t* rec, /*!< in: record for which to build data tuple */
- ulint n_fields,/*!< in: number of data fields */
- mem_heap_t* heap) /*!< in: memory heap where tuple created */
+dict_index_build_data_tuple_func(
+ const rec_t* rec,
+ const dict_index_t* index,
+#ifdef UNIV_DEBUG
+ bool leaf,
+#endif /* UNIV_DEBUG */
+ ulint n_fields,
+ mem_heap_t* heap)
{
dtuple_t* tuple;
@@ -5723,7 +5729,7 @@ dict_index_build_data_tuple(
dict_index_copy_types(tuple, index, n_fields);
- rec_copy_prefix_to_dtuple(tuple, rec, index, n_fields, heap);
+ rec_copy_prefix_to_dtuple(tuple, rec, index, leaf, n_fields, heap);
ut_ad(dtuple_check_typed(tuple));
diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc
index 177a16a2b37..17e66b3d99c 100644
--- a/storage/innobase/dict/dict0stats.cc
+++ b/storage/innobase/dict/dict0stats.cc
@@ -1172,6 +1172,7 @@ dict_stats_analyze_index_level(
prev_rec_offsets = rec_get_offsets(
prev_rec, index, prev_rec_offsets,
+ true,
n_uniq, &heap);
prev_rec = rec_copy_prefix_to_buf(
@@ -1185,7 +1186,7 @@ dict_stats_analyze_index_level(
continue;
}
rec_offsets = rec_get_offsets(
- rec, index, rec_offsets, n_uniq, &heap);
+ rec, index, rec_offsets, !level, n_uniq, &heap);
(*total_recs)++;
@@ -1193,7 +1194,7 @@ dict_stats_analyze_index_level(
ulint matched_fields;
prev_rec_offsets = rec_get_offsets(
- prev_rec, index, prev_rec_offsets,
+ prev_rec, index, prev_rec_offsets, !level,
n_uniq, &heap);
cmp_rec_rec_with_match(rec,
@@ -1399,7 +1400,7 @@ dict_stats_scan_page(
return(NULL);
}
- offsets_rec = rec_get_offsets(rec, index, offsets_rec,
+ offsets_rec = rec_get_offsets(rec, index, offsets_rec, is_leaf,
ULINT_UNDEFINED, &heap);
if (should_count_external_pages) {
@@ -1416,7 +1417,7 @@ dict_stats_scan_page(
ulint matched_fields;
offsets_next_rec = rec_get_offsets(next_rec, index,
- offsets_next_rec,
+ offsets_next_rec, is_leaf,
ULINT_UNDEFINED,
&heap);
@@ -1522,8 +1523,9 @@ dict_stats_analyze_index_below_cur(
rec_offs_set_n_alloc(offsets2, size);
rec = btr_cur_get_rec(cur);
+ ut_ad(!page_rec_is_leaf(rec));
- offsets_rec = rec_get_offsets(rec, index, offsets1,
+ offsets_rec = rec_get_offsets(rec, index, offsets1, false,
ULINT_UNDEFINED, &heap);
page_id_t page_id(dict_index_get_space(index),
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 60cc3c91fef..dd8de511b21 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -3460,10 +3460,10 @@ fts_add_doc_by_id(
}
- offsets = rec_get_offsets(clust_rec, clust_index,
- NULL, ULINT_UNDEFINED, &heap);
+ offsets = rec_get_offsets(clust_rec, clust_index, NULL, true,
+ ULINT_UNDEFINED, &heap);
- for (ulint i = 0; i < num_idx; ++i) {
+ for (ulint i = 0; i < num_idx; ++i) {
fts_doc_t doc;
dict_table_t* table;
fts_get_doc_t* get_doc;
@@ -3633,7 +3633,7 @@ fts_get_max_doc_id(
}
offsets = rec_get_offsets(
- rec, index, offsets, ULINT_UNDEFINED, &heap);
+ rec, index, offsets, true, ULINT_UNDEFINED, &heap);
data = rec_get_nth_field(rec, offsets, 0, &len);
@@ -5120,7 +5120,7 @@ fts_get_doc_id_from_rec(
rec_offs_init(offsets_);
offsets = rec_get_offsets(
- rec, index, offsets, ULINT_UNDEFINED, &my_heap);
+ rec, index, offsets, true, ULINT_UNDEFINED, &my_heap);
col_no = dict_col_get_index_pos(
&table->cols[table->fts->doc_col], index);
diff --git a/storage/innobase/gis/gis0rtree.cc b/storage/innobase/gis/gis0rtree.cc
index d14bafff72b..b8220d73ec0 100644
--- a/storage/innobase/gis/gis0rtree.cc
+++ b/storage/innobase/gis/gis0rtree.cc
@@ -85,7 +85,8 @@ rtr_page_split_initialize_nodes(
stop = task + n_recs;
rec = page_rec_get_next(page_get_infimum_rec(page));
- *offsets = rec_get_offsets(rec, cursor->index, *offsets,
+ ut_d(const bool is_leaf = page_is_leaf(page));
+ *offsets = rec_get_offsets(rec, cursor->index, *offsets, is_leaf,
n_uniq, &heap);
source_cur = rec_get_nth_field(rec, *offsets, 0, &len);
@@ -98,7 +99,7 @@ rtr_page_split_initialize_nodes(
rec = page_rec_get_next(rec);
*offsets = rec_get_offsets(rec, cursor->index, *offsets,
- n_uniq, &heap);
+ is_leaf, n_uniq, &heap);
source_cur = rec_get_nth_field(rec, *offsets, 0, &len);
}
@@ -324,7 +325,7 @@ rtr_update_mbr_field(
if (cursor2) {
rec_t* del_rec = btr_cur_get_rec(cursor2);
offsets2 = rec_get_offsets(btr_cur_get_rec(cursor2),
- index, NULL,
+ index, NULL, false,
ULINT_UNDEFINED, &heap);
del_page_no = btr_node_ptr_get_child_page_no(del_rec, offsets2);
cur2_pos = page_rec_get_n_recs_before(btr_cur_get_rec(cursor2));
@@ -389,7 +390,7 @@ rtr_update_mbr_field(
= page_rec_get_nth(page, cur2_pos);
}
offsets2 = rec_get_offsets(btr_cur_get_rec(cursor2),
- index, NULL,
+ index, NULL, false,
ULINT_UNDEFINED, &heap);
ut_ad(del_page_no == btr_node_ptr_get_child_page_no(
cursor2->page_cur.rec,
@@ -427,8 +428,7 @@ rtr_update_mbr_field(
ut_ad(old_rec != insert_rec);
page_cur_position(old_rec, block, &page_cur);
- offsets2 = rec_get_offsets(old_rec,
- index, NULL,
+ offsets2 = rec_get_offsets(old_rec, index, NULL, !level,
ULINT_UNDEFINED, &heap);
page_cur_delete_rec(&page_cur, index, offsets2, mtr);
@@ -458,6 +458,7 @@ update_mbr:
cur2_rec = cursor2->page_cur.rec;
offsets2 = rec_get_offsets(cur2_rec, index, NULL,
+ !level,
ULINT_UNDEFINED, &heap);
cur2_rec_info = rec_get_info_bits(cur2_rec,
@@ -517,7 +518,7 @@ update_mbr:
if (ins_suc) {
btr_cur_position(index, insert_rec, block, cursor);
offsets = rec_get_offsets(insert_rec,
- index, offsets,
+ index, offsets, !level,
ULINT_UNDEFINED, &heap);
}
@@ -532,6 +533,7 @@ update_mbr:
cur2_rec = btr_cur_get_rec(cursor2);
offsets2 = rec_get_offsets(cur2_rec, index, NULL,
+ !level,
ULINT_UNDEFINED, &heap);
/* If the cursor2 position is on a wrong rec, we
@@ -545,6 +547,7 @@ update_mbr:
while (!page_rec_is_supremum(cur2_rec)) {
offsets2 = rec_get_offsets(cur2_rec, index,
NULL,
+ !level,
ULINT_UNDEFINED,
&heap);
cur2_pno = btr_node_ptr_get_child_page_no(
@@ -862,6 +865,7 @@ rtr_split_page_move_rec_list(
rec_move = static_cast<rtr_rec_move_t*>(mem_heap_alloc(
heap,
sizeof (*rec_move) * max_to_move));
+ const bool is_leaf = page_is_leaf(page);
/* Insert the recs in group 2 to new page. */
for (cur_split_node = node_array;
@@ -871,11 +875,10 @@ rtr_split_page_move_rec_list(
block, cur_split_node->key);
offsets = rec_get_offsets(cur_split_node->key,
- index, offsets,
+ index, offsets, is_leaf,
ULINT_UNDEFINED, &heap);
- ut_ad (cur_split_node->key != first_rec
- || !page_is_leaf(page));
+ ut_ad(!is_leaf || cur_split_node->key != first_rec);
rec = page_cur_insert_rec_low(
page_cur_get_rec(&new_page_cursor),
@@ -910,8 +913,7 @@ rtr_split_page_move_rec_list(
same temp-table in parallel.
max_trx_id is ignored for temp tables because it not required
for MVCC. */
- if (page_is_leaf(page)
- && !dict_table_is_temporary(index->table)) {
+ if (is_leaf && !dict_table_is_temporary(index->table)) {
page_update_max_trx_id(new_block, NULL,
page_get_max_trx_id(page),
mtr);
@@ -964,7 +966,7 @@ rtr_split_page_move_rec_list(
block, &page_cursor);
offsets = rec_get_offsets(
page_cur_get_rec(&page_cursor), index,
- offsets, ULINT_UNDEFINED,
+ offsets, is_leaf, ULINT_UNDEFINED,
&heap);
page_cur_delete_rec(&page_cursor,
index, offsets, mtr);
@@ -1183,9 +1185,8 @@ func_start:
*offsets = rec_get_offsets(
page_cur_get_rec(page_cursor),
- cursor->index,
- *offsets, ULINT_UNDEFINED,
- heap);
+ cursor->index, *offsets, !page_level,
+ ULINT_UNDEFINED, heap);
page_cur_delete_rec(page_cursor,
cursor->index, *offsets, mtr);
@@ -1201,9 +1202,8 @@ func_start:
block, page_cursor);
*offsets = rec_get_offsets(
page_cur_get_rec(page_cursor),
- cursor->index,
- *offsets, ULINT_UNDEFINED,
- heap);
+ cursor->index, *offsets, !page_level,
+ ULINT_UNDEFINED, heap);
page_cur_delete_rec(page_cursor,
cursor->index, *offsets, mtr);
}
@@ -1461,13 +1461,14 @@ rtr_page_copy_rec_list_end_no_locks(
cur_rec = page_rec_get_next(cur_rec);
}
- offsets1 = rec_get_offsets(cur1_rec, index, offsets1,
+ offsets1 = rec_get_offsets(cur1_rec, index, offsets1, is_leaf,
ULINT_UNDEFINED, &heap);
while (!page_rec_is_supremum(cur_rec)) {
ulint cur_matched_fields = 0;
int cmp;
offsets2 = rec_get_offsets(cur_rec, index, offsets2,
+ is_leaf,
ULINT_UNDEFINED, &heap);
cmp = cmp_rec_rec_with_match(cur1_rec, cur_rec,
offsets1, offsets2,
@@ -1503,7 +1504,7 @@ rtr_page_copy_rec_list_end_no_locks(
cur_rec = page_cur_get_rec(&page_cur);
- offsets1 = rec_get_offsets(cur1_rec, index, offsets1,
+ offsets1 = rec_get_offsets(cur1_rec, index, offsets1, is_leaf,
ULINT_UNDEFINED, &heap);
ins_rec = page_cur_insert_rec_low(cur_rec, index,
@@ -1579,7 +1580,7 @@ rtr_page_copy_rec_list_start_no_locks(
cur_rec = page_rec_get_next(cur_rec);
}
- offsets1 = rec_get_offsets(cur1_rec, index, offsets1,
+ offsets1 = rec_get_offsets(cur1_rec, index, offsets1, is_leaf,
ULINT_UNDEFINED, &heap);
while (!page_rec_is_supremum(cur_rec)) {
@@ -1587,6 +1588,7 @@ rtr_page_copy_rec_list_start_no_locks(
int cmp;
offsets2 = rec_get_offsets(cur_rec, index, offsets2,
+ is_leaf,
ULINT_UNDEFINED, &heap);
cmp = cmp_rec_rec_with_match(cur1_rec, cur_rec,
offsets1, offsets2,
@@ -1624,7 +1626,7 @@ rtr_page_copy_rec_list_start_no_locks(
cur_rec = page_cur_get_rec(&page_cur);
- offsets1 = rec_get_offsets(cur1_rec, index, offsets1,
+ offsets1 = rec_get_offsets(cur1_rec, index, offsets1, is_leaf,
ULINT_UNDEFINED, &heap);
ins_rec = page_cur_insert_rec_low(cur_rec, index,
@@ -1787,7 +1789,7 @@ rtr_check_same_block(
while (!page_rec_is_supremum(rec)) {
offsets = rec_get_offsets(
- rec, index, NULL, ULINT_UNDEFINED, &heap);
+ rec, index, NULL, false, ULINT_UNDEFINED, &heap);
if (btr_node_ptr_get_child_page_no(rec, offsets) == page_no) {
btr_cur_position(index, rec, parentb, cursor);
@@ -1913,7 +1915,8 @@ rtr_estimate_n_rows_in_range(
heap = mem_heap_create(512);
rec = page_rec_get_next(page_get_infimum_rec(page));
- offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
+ offsets = rec_get_offsets(rec, index, offsets, page_rec_is_leaf(rec),
+ ULINT_UNDEFINED, &heap);
/* Scan records in root page and calculate area. */
double area = 0;
diff --git a/storage/innobase/gis/gis0sea.cc b/storage/innobase/gis/gis0sea.cc
index 97163cae410..87ebd9ad34a 100644
--- a/storage/innobase/gis/gis0sea.cc
+++ b/storage/innobase/gis/gis0sea.cc
@@ -533,7 +533,7 @@ rtr_compare_cursor_rec(
rec = btr_cur_get_rec(cursor);
offsets = rec_get_offsets(
- rec, index, NULL, ULINT_UNDEFINED, heap);
+ rec, index, NULL, false, ULINT_UNDEFINED, heap);
return(btr_node_ptr_get_child_page_no(rec, offsets) == page_no);
}
@@ -723,7 +723,7 @@ rtr_page_get_father_node_ptr(
user_rec = btr_cur_get_rec(cursor);
ut_a(page_rec_is_user_rec(user_rec));
- offsets = rec_get_offsets(user_rec, index, offsets,
+ offsets = rec_get_offsets(user_rec, index, offsets, !level,
ULINT_UNDEFINED, &heap);
rtr_get_mbr_from_rec(user_rec, offsets, &mbr);
@@ -740,7 +740,7 @@ rtr_page_get_father_node_ptr(
node_ptr = btr_cur_get_rec(cursor);
ut_ad(!page_rec_is_comp(node_ptr)
|| rec_get_status(node_ptr) == REC_STATUS_NODE_PTR);
- offsets = rec_get_offsets(node_ptr, index, offsets,
+ offsets = rec_get_offsets(node_ptr, index, offsets, false,
ULINT_UNDEFINED, &heap);
ulint child_page = btr_node_ptr_get_child_page_no(node_ptr, offsets);
@@ -757,13 +757,14 @@ rtr_page_get_father_node_ptr(
print_rec = page_rec_get_next(
page_get_infimum_rec(page_align(user_rec)));
- offsets = rec_get_offsets(print_rec, index,
- offsets, ULINT_UNDEFINED, &heap);
+ offsets = rec_get_offsets(print_rec, index, offsets,
+ page_rec_is_leaf(user_rec),
+ ULINT_UNDEFINED, &heap);
error << "; child ";
rec_print(error.m_oss, print_rec,
rec_get_info_bits(print_rec, rec_offs_comp(offsets)),
offsets);
- offsets = rec_get_offsets(node_ptr, index, offsets,
+ offsets = rec_get_offsets(node_ptr, index, offsets, false,
ULINT_UNDEFINED, &heap);
error << "; parent ";
rec_print(error.m_oss, print_rec,
@@ -1310,10 +1311,10 @@ rtr_cur_restore_position(
heap = mem_heap_create(256);
offsets1 = rec_get_offsets(
- r_cursor->old_rec, index, NULL,
+ r_cursor->old_rec, index, NULL, !level,
r_cursor->old_n_fields, &heap);
offsets2 = rec_get_offsets(
- rec, index, NULL,
+ rec, index, NULL, !level,
r_cursor->old_n_fields, &heap);
comp = rec_offs_comp(offsets1);
@@ -1351,7 +1352,7 @@ rtr_cur_restore_position(
heap = mem_heap_create(256);
- tuple = dict_index_build_data_tuple(index, r_cursor->old_rec,
+ tuple = dict_index_build_data_tuple(r_cursor->old_rec, index, !level,
r_cursor->old_n_fields, heap);
page_cursor = btr_pcur_get_page_cur(r_cursor);
@@ -1383,10 +1384,10 @@ search_again:
rec = btr_pcur_get_rec(r_cursor);
offsets1 = rec_get_offsets(
- r_cursor->old_rec, index, NULL,
+ r_cursor->old_rec, index, NULL, !level,
r_cursor->old_n_fields, &heap);
offsets2 = rec_get_offsets(
- rec, index, NULL,
+ rec, index, NULL, !level,
r_cursor->old_n_fields, &heap);
comp = rec_offs_comp(offsets1);
@@ -1433,6 +1434,7 @@ rtr_leaf_push_match_rec(
rtr_rec_t rtr_rec;
buf = match_rec->block.frame + match_rec->used;
+ ut_ad(page_rec_is_leaf(rec));
copy = rec_copy(buf, rec, offsets);
@@ -1661,11 +1663,9 @@ rtr_cur_search_with_match(
ulint* offsets = offsets_;
mem_heap_t* heap = NULL;
int cmp = 1;
- bool is_leaf;
double least_inc = DBL_MAX;
const rec_t* best_rec;
const rec_t* last_match_rec = NULL;
- ulint level;
bool match_init = false;
ulint space = block->page.id.space();
page_cur_mode_t orig_mode = mode;
@@ -1679,8 +1679,8 @@ rtr_cur_search_with_match(
page = buf_block_get_frame(block);
- is_leaf = page_is_leaf(page);
- level = btr_page_get_level(page, mtr);
+ const ulint level = btr_page_get_level(page, mtr);
+ const bool is_leaf = !level;
if (mode == PAGE_CUR_RTREE_LOCATE) {
ut_ad(level != 0);
@@ -1702,7 +1702,7 @@ rtr_cur_search_with_match(
ulint new_rec_size = rec_get_converted_size(index, tuple, 0);
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, is_leaf,
dtuple_get_n_fields_cmp(tuple),
&heap);
@@ -1723,7 +1723,7 @@ rtr_cur_search_with_match(
}
while (!page_rec_is_supremum(rec)) {
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, is_leaf,
dtuple_get_n_fields_cmp(tuple),
&heap);
if (!is_leaf) {
@@ -1818,7 +1818,7 @@ rtr_cur_search_with_match(
== PAGE_CUR_RTREE_GET_FATHER);
offsets = rec_get_offsets(
- rec, index, offsets,
+ rec, index, offsets, false,
ULINT_UNDEFINED, &heap);
page_no = btr_node_ptr_get_child_page_no(
@@ -1867,7 +1867,7 @@ rtr_cur_search_with_match(
/* Collect matched records on page */
offsets = rec_get_offsets(
- rec, index, offsets,
+ rec, index, offsets, true,
ULINT_UNDEFINED, &heap);
rtr_leaf_push_match_rec(
rec, rtr_info, offsets,
@@ -1899,9 +1899,8 @@ rtr_cur_search_with_match(
ulint child_no;
ut_ad(least_inc < DBL_MAX);
offsets = rec_get_offsets(
- best_rec, index,
- offsets, ULINT_UNDEFINED,
- &heap);
+ best_rec, index, offsets,
+ false, ULINT_UNDEFINED, &heap);
child_no =
btr_node_ptr_get_child_page_no(
best_rec, offsets);
@@ -1953,12 +1952,12 @@ rtr_cur_search_with_match(
/* Verify the record to be positioned is the same
as the last record in matched_rec vector */
offsets2 = rec_get_offsets(test_rec.r_rec, index,
- offsets2, ULINT_UNDEFINED,
- &heap);
+ offsets2, true,
+ ULINT_UNDEFINED, &heap);
offsets = rec_get_offsets(last_match_rec, index,
- offsets, ULINT_UNDEFINED,
- &heap);
+ offsets, true,
+ ULINT_UNDEFINED, &heap);
ut_ad(cmp_rec_rec(test_rec.r_rec, last_match_rec,
offsets2, offsets, index) == 0);
@@ -1975,7 +1974,8 @@ rtr_cur_search_with_match(
ut_ad(!last_match_rec && rec);
offsets = rec_get_offsets(
- rec, index, offsets, ULINT_UNDEFINED, &heap);
+ rec, index, offsets, false,
+ ULINT_UNDEFINED, &heap);
child_no = btr_node_ptr_get_child_page_no(rec, offsets);
@@ -1997,7 +1997,7 @@ rtr_cur_search_with_match(
&& mode != PAGE_CUR_RTREE_INSERT) {
ulint page_no;
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, false,
ULINT_UNDEFINED, &heap);
page_no = btr_node_ptr_get_child_page_no(rec, offsets);
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index d0380cd914c..2fa38b24ad9 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -71,8 +71,7 @@ static const char *MSG_UNSUPPORTED_ALTER_ONLINE_ON_VIRTUAL_COLUMN=
/** Operations for creating secondary indexes (no rebuild needed) */
static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ONLINE_CREATE
= Alter_inplace_info::ADD_INDEX
- | Alter_inplace_info::ADD_UNIQUE_INDEX
- | Alter_inplace_info::ADD_SPATIAL_INDEX;
+ | Alter_inplace_info::ADD_UNIQUE_INDEX;
/** Operations for rebuilding a table in place */
static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ALTER_REBUILD
@@ -702,11 +701,11 @@ ha_innobase::check_if_supported_inplace_alter(
codes for certain types. In some cases the signed/unsigned bit was
generated differently too.
- Online ALTER would change the mtype/unsigned_flag (to what the
+ Inplace ALTER would change the mtype/unsigned_flag (to what the
current code generates) without changing the underlying data
represenation, and it might result in data corruption.
- Don't do online ALTER if mtype/unsigned_flag are wrong.
+ Don't do inplace ALTER if mtype/unsigned_flag are wrong.
*/
for (ulint i = 0, icol= 0; i < table->s->fields; i++) {
const Field* field = table->field[i];
@@ -897,29 +896,6 @@ ha_innobase::check_if_supported_inplace_alter(
DBUG_ASSERT(!m_prebuilt->table->fts || m_prebuilt->table->fts->doc_col
< dict_table_get_n_user_cols(m_prebuilt->table));
- /* Spatial indexes should use copy method for now.
- TOO: remove this when below ADD_SPATIAL_INDEX supported. */
- for (uint i = 0; i < ha_alter_info->index_add_count; i++) {
- const KEY* key =
- &ha_alter_info->key_info_buffer[
- ha_alter_info->index_add_buffer[i]];
- if (key->flags & HA_SPATIAL) {
- ha_alter_info->unsupported_reason = innobase_get_err_msg(
- ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_GIS);
-
- DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
- }
- }
-
-#ifdef MYSQL_SPATIAL_INDEX
- if (ha_alter_info->handler_flags
- & Alter_inplace_info::ADD_SPATIAL_INDEX) {
- ha_alter_info->unsupported_reason = innobase_get_err_msg(
- ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_GIS);
- online = false;
- }
-#endif
-
if (m_prebuilt->table->fts
&& innobase_fulltext_exist(altered_table)) {
/* FULLTEXT indexes are supposed to remain. */
@@ -964,7 +940,7 @@ ha_innobase::check_if_supported_inplace_alter(
operation is possible. */
} else if (((ha_alter_info->handler_flags
& Alter_inplace_info::ADD_PK_INDEX)
- || innobase_need_rebuild(ha_alter_info, table))
+ || innobase_need_rebuild(ha_alter_info, table))
&& (innobase_fulltext_exist(altered_table)
|| innobase_spatial_exist(altered_table))) {
/* Refuse to rebuild the table online, if
@@ -982,8 +958,6 @@ ha_innobase::check_if_supported_inplace_alter(
ha_alter_info->unsupported_reason =
innobase_get_err_msg(
ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_GIS);
-
- DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
} else {
ha_alter_info->unsupported_reason =
innobase_get_err_msg(
@@ -991,10 +965,15 @@ ha_innobase::check_if_supported_inplace_alter(
}
} else if ((ha_alter_info->handler_flags
& Alter_inplace_info::ADD_INDEX)) {
- /* Building a full-text index requires a lock.
- We could do without a lock if the table already contains
- an FTS_DOC_ID column, but in that case we would have
- to apply the modification log to the full-text indexes. */
+ /* ADD FULLTEXT|SPATIAL INDEX requires a lock.
+
+ We could do ADD FULLTEXT INDEX without a lock if the
+ table already contains an FTS_DOC_ID column, but in
+ that case we would have to apply the modification log
+ to the full-text indexes.
+
+ We could also do ADD SPATIAL INDEX by implementing
+ row_log_apply() for it. */
for (uint i = 0; i < ha_alter_info->index_add_count; i++) {
const KEY* key =
@@ -1011,6 +990,12 @@ ha_innobase::check_if_supported_inplace_alter(
online = false;
break;
}
+ if (key->flags & HA_SPATIAL) {
+ ha_alter_info->unsupported_reason = innobase_get_err_msg(
+ ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_GIS);
+ online = false;
+ break;
+ }
}
}
@@ -5609,10 +5594,7 @@ ha_innobase::prepare_inplace_alter_table(
/* The clustered index is corrupted. */
my_error(ER_CHECK_NO_SUCH_TABLE, MYF(0));
DBUG_RETURN(true);
- }
-
- if (ha_alter_info->handler_flags
- & Alter_inplace_info::CHANGE_CREATE_OPTION) {
+ } else {
const char* invalid_opt = info.create_options_are_invalid();
/* Check engine specific table options */
diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc
index eda6684e69f..b53ede41427 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.cc
+++ b/storage/innobase/ibuf/ibuf0ibuf.cc
@@ -559,7 +559,7 @@ ibuf_init_at_db_start(void)
ibuf->index = dict_mem_index_create(
"innodb_change_buffer", "CLUST_IND",
- IBUF_SPACE_ID, DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, 1);
+ IBUF_SPACE_ID, DICT_CLUSTERED | DICT_IBUF, 1);
ibuf->index->id = DICT_IBUF_ID_MIN + IBUF_SPACE_ID;
ibuf->index->table = dict_mem_table_create(
"innodb_change_buffer", IBUF_SPACE_ID, 1, 0, 0, 0);
@@ -1502,6 +1502,7 @@ ibuf_dummy_index_create(
/* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */
index->cached = TRUE;
+ ut_d(index->is_dummy = true);
return(index);
}
@@ -4000,8 +4001,8 @@ dump:
row_ins_sec_index_entry_by_modify(BTR_MODIFY_LEAF). */
ut_ad(rec_get_deleted_flag(rec, page_is_comp(page)));
- offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED,
- &heap);
+ offsets = rec_get_offsets(rec, index, NULL, true,
+ ULINT_UNDEFINED, &heap);
update = row_upd_build_sec_rec_difference_binary(
rec, index, offsets, entry, heap);
@@ -4193,7 +4194,7 @@ ibuf_delete(
rec_offs_init(offsets_);
offsets = rec_get_offsets(
- rec, index, offsets, ULINT_UNDEFINED, &heap);
+ rec, index, offsets, true, ULINT_UNDEFINED, &heap);
if (page_get_n_recs(page) <= 1
|| !(REC_INFO_DELETED_FLAG
diff --git a/storage/innobase/include/data0data.h b/storage/innobase/include/data0data.h
index 87a2228ff2d..b6187d46025 100644
--- a/storage/innobase/include/data0data.h
+++ b/storage/innobase/include/data0data.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, MariaDB Corporation.
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
@@ -586,11 +587,10 @@ struct dfield_t{
unsigned len; /*!< data length; UNIV_SQL_NULL if SQL null */
dtype_t type; /*!< type of data */
- /** Create a deep copy of this object
- @param[in] heap the memory heap in which the clone will be
- created.
- @return the cloned object. */
- dfield_t* clone(mem_heap_t* heap);
+ /** Create a deep copy of this object.
+ @param[in,out] heap memory heap in which the clone will be created
+ @return the cloned object */
+ dfield_t* clone(mem_heap_t* heap) const;
};
/** Structure for an SQL data tuple of fields (logical record) */
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index 7802366a149..ace0029e632 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -1451,17 +1451,31 @@ dict_index_copy_rec_order_prefix(
copied prefix, or NULL */
ulint* buf_size)/*!< in/out: buffer size */
MY_ATTRIBUTE((nonnull, warn_unused_result));
-/**********************************************************************//**
-Builds a typed data tuple out of a physical record.
+/** Convert a physical record into a search tuple.
+@param[in] rec index record (not necessarily in an index page)
+@param[in] index index
+@param[in] leaf whether rec is in a leaf page
+@param[in] n_fields number of data fields
+@param[in,out] heap memory heap for allocation
@return own: data tuple */
dtuple_t*
-dict_index_build_data_tuple(
-/*========================*/
- dict_index_t* index, /*!< in: index */
- rec_t* rec, /*!< in: record for which to build data tuple */
- ulint n_fields,/*!< in: number of data fields */
- mem_heap_t* heap) /*!< in: memory heap where tuple created */
+dict_index_build_data_tuple_func(
+ const rec_t* rec,
+ const dict_index_t* index,
+#ifdef UNIV_DEBUG
+ bool leaf,
+#endif /* UNIV_DEBUG */
+ ulint n_fields,
+ mem_heap_t* heap)
MY_ATTRIBUTE((nonnull, warn_unused_result));
+#ifdef UNIV_DEBUG
+# define dict_index_build_data_tuple(rec, index, leaf, n_fields, heap) \
+ dict_index_build_data_tuple_func(rec, index, leaf, n_fields, heap)
+#else /* UNIV_DEBUG */
+# define dict_index_build_data_tuple(rec, index, leaf, n_fields, heap) \
+ dict_index_build_data_tuple_func(rec, index, n_fields, heap)
+#endif /* UNIV_DEBUG */
+
/*********************************************************************//**
Gets the space id of the root of the index tree.
@return space id */
diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic
index 9220e46e759..62561c8af4f 100644
--- a/storage/innobase/include/dict0dict.ic
+++ b/storage/innobase/include/dict0dict.ic
@@ -327,20 +327,6 @@ dict_index_is_unique(
}
/********************************************************************//**
-Check whether the index is an universal index tree.
-@return nonzero for universal tree, zero for other indexes */
-UNIV_INLINE
-ulint
-dict_index_is_univ(
-/*===============*/
- const dict_index_t* index) /*!< in: index */
-{
- ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
-
- return(index->type & DICT_UNIVERSAL);
-}
-
-/********************************************************************//**
Check whether the index is a Spatial Index.
@return nonzero for Spatial Index, zero for other indexes */
UNIV_INLINE
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 0155d1d5d20..034729e1595 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -66,8 +66,6 @@ combination of types */
auto-generated clustered indexes,
also DICT_UNIQUE will be set */
#define DICT_UNIQUE 2 /*!< unique index */
-#define DICT_UNIVERSAL 4 /*!< index which can contain records from any
- other index */
#define DICT_IBUF 8 /*!< insert buffer tree */
#define DICT_CORRUPT 16 /*!< bit to store the corrupted flag
in SYS_INDEXES.TYPE */
@@ -864,6 +862,8 @@ struct dict_index_t{
data dictionary yet */
#ifdef UNIV_DEBUG
+ /** whether this is a dummy index object */
+ bool is_dummy;
uint32_t magic_n;/*!< magic number */
/** Value of dict_index_t::magic_n */
# define DICT_INDEX_MAGIC_N 76789786
diff --git a/storage/innobase/include/gis0rtree.ic b/storage/innobase/include/gis0rtree.ic
index 7f64a9b13a1..e852ebd8028 100644
--- a/storage/innobase/include/gis0rtree.ic
+++ b/storage/innobase/include/gis0rtree.ic
@@ -57,7 +57,8 @@ rtr_page_cal_mbr(
page = buf_block_get_frame(block);
rec = page_rec_get_next(page_get_infimum_rec(page));
- offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
+ offsets = rec_get_offsets(rec, index, offsets, page_is_leaf(page),
+ ULINT_UNDEFINED, &heap);
do {
/* The mbr address is in the first field. */
diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h
index 7b3726b1fef..459304fc712 100644
--- a/storage/innobase/include/ha_prototypes.h
+++ b/storage/innobase/include/ha_prototypes.h
@@ -43,7 +43,6 @@ class THD;
#undef MYSQL_PFS
#undef MYSQL_RENAME_INDEX
#undef MYSQL_REPLACE_TRX_IN_THD
-#undef MYSQL_SPATIAL_INDEX
#undef MYSQL_STORE_FTS_DOC_ID
/*******************************************************************//**
diff --git a/storage/innobase/include/page0cur.ic b/storage/innobase/include/page0cur.ic
index 5eb1bc0cbc5..3e6d40cba4a 100644
--- a/storage/innobase/include/page0cur.ic
+++ b/storage/innobase/include/page0cur.ic
@@ -280,7 +280,9 @@ page_cur_tuple_insert(
rec = rec_convert_dtuple_to_rec((byte*) mem_heap_alloc(*heap, size),
index, tuple, n_ext);
- *offsets = rec_get_offsets(rec, index, *offsets, ULINT_UNDEFINED, heap);
+ *offsets = rec_get_offsets(rec, index, *offsets,
+ page_is_leaf(cursor->block->frame),
+ ULINT_UNDEFINED, heap);
if (buf_block_get_page_zip(cursor->block)) {
rec = page_cur_insert_rec_zip(
diff --git a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h
index 9243bcaa717..3b6a0215249 100644
--- a/storage/innobase/include/page0page.h
+++ b/storage/innobase/include/page0page.h
@@ -167,25 +167,196 @@ directory. */
#define PAGE_DIR_SLOT_MIN_N_OWNED 4
extern my_bool srv_immediate_scrub_data_uncompressed;
+#endif /* UNIV_INNOCHECKSUM */
-/************************************************************//**
-Gets the start of a page.
-@return start of the page */
-UNIV_INLINE
+/** Get the start of a page frame.
+@param[in] ptr pointer within a page frame
+@return start of the page frame */
+MY_ATTRIBUTE((const))
+inline
page_t*
-page_align(
-/*=======*/
- const void* ptr) /*!< in: pointer to page frame */
- MY_ATTRIBUTE((const));
-/************************************************************//**
-Gets the offset within a page.
+page_align(const void* ptr)
+{
+ return(static_cast<page_t*>(ut_align_down(ptr, UNIV_PAGE_SIZE)));
+}
+
+/** Gets the byte offset within a page frame.
+@param[in] ptr pointer within a page frame
@return offset from the start of the page */
-UNIV_INLINE
+MY_ATTRIBUTE((const))
+inline
ulint
-page_offset(
-/*========*/
- const void* ptr) /*!< in: pointer to page frame */
- MY_ATTRIBUTE((const));
+page_offset(const void* ptr)
+{
+ return(ut_align_offset(ptr, UNIV_PAGE_SIZE));
+}
+
+/** Determine whether an index page is not in ROW_FORMAT=REDUNDANT.
+@param[in] page index page
+@return nonzero if ROW_FORMAT is one of COMPACT,DYNAMIC,COMPRESSED
+@retval 0 if ROW_FORMAT=REDUNDANT */
+inline
+byte
+page_is_comp(const page_t* page)
+{
+ ut_ad(!ut_align_offset(page, UNIV_ZIP_SIZE_MIN));
+ return(page[PAGE_HEADER + PAGE_N_HEAP] & 0x80);
+}
+
+/** Determine whether an index page is empty.
+@param[in] page index page
+@return whether the page is empty (PAGE_N_RECS = 0) */
+inline
+bool
+page_is_empty(const page_t* page)
+{
+ ut_ad(!ut_align_offset(page, UNIV_ZIP_SIZE_MIN));
+ return !*reinterpret_cast<const uint16_t*>(PAGE_HEADER + PAGE_N_RECS
+ + page);
+}
+
+/** Determine whether an index page contains garbage.
+@param[in] page index page
+@return whether the page contains garbage (PAGE_GARBAGE is not 0) */
+inline
+bool
+page_has_garbage(const page_t* page)
+{
+ ut_ad(!ut_align_offset(page, UNIV_ZIP_SIZE_MIN));
+ return *reinterpret_cast<const uint16_t*>(PAGE_HEADER + PAGE_GARBAGE
+ + page);
+}
+
+/** Determine whether an B-tree or R-tree index page is a leaf page.
+@param[in] page index page
+@return true if the page is a leaf (PAGE_LEVEL = 0) */
+inline
+bool
+page_is_leaf(const page_t* page)
+{
+ ut_ad(!ut_align_offset(page, UNIV_ZIP_SIZE_MIN));
+ return !*reinterpret_cast<const uint16_t*>(PAGE_HEADER + PAGE_LEVEL
+ + page);
+}
+
+#ifndef UNIV_INNOCHECKSUM
+/** Determine whether an index page record is not in ROW_FORMAT=REDUNDANT.
+@param[in] rec record in an index page frame (not a copy)
+@return nonzero if ROW_FORMAT is one of COMPACT,DYNAMIC,COMPRESSED
+@retval 0 if ROW_FORMAT=REDUNDANT */
+inline
+byte
+page_rec_is_comp(const byte* rec)
+{
+ return(page_is_comp(page_align(rec)));
+}
+
+/** Determine the offset of the infimum record on the page.
+@param[in] page index page
+@return offset of the infimum record in record list, relative from page */
+inline
+unsigned
+page_get_infimum_offset(const page_t* page)
+{
+ ut_ad(!page_offset(page));
+ return page_is_comp(page) ? PAGE_NEW_INFIMUM : PAGE_OLD_INFIMUM;
+}
+
+/** Determine the offset of the supremum record on the page.
+@param[in] page index page
+@return offset of the supremum record in record list, relative from page */
+inline
+unsigned
+page_get_supremum_offset(const page_t* page)
+{
+ ut_ad(!page_offset(page));
+ return page_is_comp(page) ? PAGE_NEW_SUPREMUM : PAGE_OLD_SUPREMUM;
+}
+
+/** Determine whether an index page record is a user record.
+@param[in] offset record offset in the page
+@retval true if a user record
+@retval false if the infimum or supremum pseudo-record */
+inline
+bool
+page_rec_is_user_rec_low(ulint offset)
+{
+ compile_time_assert(PAGE_OLD_INFIMUM >= PAGE_NEW_INFIMUM);
+ compile_time_assert(PAGE_OLD_SUPREMUM >= PAGE_NEW_SUPREMUM);
+ compile_time_assert(PAGE_NEW_INFIMUM < PAGE_OLD_SUPREMUM);
+ compile_time_assert(PAGE_OLD_INFIMUM < PAGE_NEW_SUPREMUM);
+ compile_time_assert(PAGE_NEW_SUPREMUM < PAGE_OLD_SUPREMUM_END);
+ compile_time_assert(PAGE_OLD_SUPREMUM < PAGE_NEW_SUPREMUM_END);
+ ut_ad(offset >= PAGE_NEW_INFIMUM);
+ ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
+
+ return(offset != PAGE_NEW_SUPREMUM
+ && offset != PAGE_NEW_INFIMUM
+ && offset != PAGE_OLD_INFIMUM
+ && offset != PAGE_OLD_SUPREMUM);
+}
+
+/** Determine if a record is the supremum record on an index page.
+@param[in] offset record offset in an index page
+@return true if the supremum record */
+inline
+bool
+page_rec_is_supremum_low(ulint offset)
+{
+ ut_ad(offset >= PAGE_NEW_INFIMUM);
+ ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
+ return(offset == PAGE_NEW_SUPREMUM || offset == PAGE_OLD_SUPREMUM);
+}
+
+/** Determine if a record is the infimum record on an index page.
+@param[in] offset record offset in an index page
+@return true if the infimum record */
+inline
+bool
+page_rec_is_infimum_low(ulint offset)
+{
+ ut_ad(offset >= PAGE_NEW_INFIMUM);
+ ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
+ return(offset == PAGE_NEW_INFIMUM || offset == PAGE_OLD_INFIMUM);
+}
+
+/** Determine whether an B-tree or R-tree index record is in a leaf page.
+@param[in] rec index record in an index page
+@return true if the record is in a leaf page */
+inline
+bool
+page_rec_is_leaf(const page_t* rec)
+{
+ const page_t* page = page_align(rec);
+ ut_ad(rec - page >= page_get_infimum_offset(page));
+ bool leaf = page_is_leaf(page);
+ ut_ad(!page_rec_is_comp(rec)
+ || !page_rec_is_user_rec_low(rec - page)
+ || leaf == !rec_get_node_ptr_flag(rec));
+ return leaf;
+}
+
+/** Determine whether an index page record is a user record.
+@param[in] rec record in an index page
+@return true if a user record */
+inline
+bool
+page_rec_is_user_rec(const rec_t* rec);
+
+/** Determine whether an index page record is the supremum record.
+@param[in] rec record in an index page
+@return true if the supremum record */
+inline
+bool
+page_rec_is_supremum(const rec_t* rec);
+
+/** Determine whether an index page record is the infimum record.
+@param[in] rec record in an index page
+@return true if the infimum record */
+inline
+bool
+page_rec_is_infimum(const rec_t* rec);
+
/*************************************************************//**
Returns the max trx id field value. */
UNIV_INLINE
@@ -321,22 +492,6 @@ page_header_reset_last_insert(
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be updated, or NULL */
mtr_t* mtr); /*!< in: mtr */
-/************************************************************//**
-Gets the offset of the first record on the page.
-@return offset of the first record in record list, relative from page */
-UNIV_INLINE
-ulint
-page_get_infimum_offset(
-/*====================*/
- const page_t* page); /*!< in: page which must have record(s) */
-/************************************************************//**
-Gets the offset of the last record on the page.
-@return offset of the last record in record list, relative from page */
-UNIV_INLINE
-ulint
-page_get_supremum_offset(
-/*=====================*/
- const page_t* page); /*!< in: page which must have record(s) */
#define page_get_infimum_rec(page) ((page) + page_get_infimum_offset(page))
#define page_get_supremum_rec(page) ((page) + page_get_supremum_offset(page))
@@ -522,23 +677,7 @@ ulint
page_dir_find_owner_slot(
/*=====================*/
const rec_t* rec); /*!< in: the physical record */
-/************************************************************//**
-Determine whether the page is in new-style compact format.
-@return nonzero if the page is in compact format, zero if it is in
-old-style format */
-UNIV_INLINE
-ulint
-page_is_comp(
-/*=========*/
- const page_t* page); /*!< in: index page */
-/************************************************************//**
-TRUE if the record is on a page in compact format.
-@return nonzero if in compact format */
-UNIV_INLINE
-ulint
-page_rec_is_comp(
-/*=============*/
- const rec_t* rec); /*!< in: record */
+
/***************************************************************//**
Returns the heap number of a record.
@return heap number */
@@ -547,24 +686,6 @@ ulint
page_rec_get_heap_no(
/*=================*/
const rec_t* rec); /*!< in: the physical record */
-/************************************************************//**
-Determine whether the page is a B-tree leaf.
-@return true if the page is a B-tree leaf (PAGE_LEVEL = 0) */
-UNIV_INLINE
-bool
-page_is_leaf(
-/*=========*/
- const page_t* page) /*!< in: page */
- MY_ATTRIBUTE((warn_unused_result));
-/************************************************************//**
-Determine whether the page is empty.
-@return true if the page is empty (PAGE_N_RECS = 0) */
-UNIV_INLINE
-bool
-page_is_empty(
-/*==========*/
- const page_t* page) /*!< in: page */
- MY_ATTRIBUTE((warn_unused_result));
/** Determine whether a page is an index root page.
@param[in] page page frame
@return true if the page is a root page of an index */
@@ -574,15 +695,6 @@ page_is_root(
const page_t* page)
MY_ATTRIBUTE((warn_unused_result));
/************************************************************//**
-Determine whether the page contains garbage.
-@return true if the page contains garbage (PAGE_GARBAGE is not 0) */
-UNIV_INLINE
-bool
-page_has_garbage(
-/*=============*/
- const page_t* page) /*!< in: page */
- MY_ATTRIBUTE((warn_unused_result));
-/************************************************************//**
Gets the pointer to the next record on the page.
@return pointer to next record */
UNIV_INLINE
@@ -645,62 +757,6 @@ page_rec_get_prev(
/*==============*/
rec_t* rec); /*!< in: pointer to record,
must not be page infimum */
-/************************************************************//**
-TRUE if the record is a user record on the page.
-@return TRUE if a user record */
-UNIV_INLINE
-ibool
-page_rec_is_user_rec_low(
-/*=====================*/
- ulint offset) /*!< in: record offset on page */
- MY_ATTRIBUTE((const));
-/************************************************************//**
-TRUE if the record is the supremum record on a page.
-@return TRUE if the supremum record */
-UNIV_INLINE
-ibool
-page_rec_is_supremum_low(
-/*=====================*/
- ulint offset) /*!< in: record offset on page */
- MY_ATTRIBUTE((const));
-/************************************************************//**
-TRUE if the record is the infimum record on a page.
-@return TRUE if the infimum record */
-UNIV_INLINE
-ibool
-page_rec_is_infimum_low(
-/*====================*/
- ulint offset) /*!< in: record offset on page */
- MY_ATTRIBUTE((const));
-
-/************************************************************//**
-TRUE if the record is a user record on the page.
-@return TRUE if a user record */
-UNIV_INLINE
-ibool
-page_rec_is_user_rec(
-/*=================*/
- const rec_t* rec) /*!< in: record */
- MY_ATTRIBUTE((warn_unused_result));
-/************************************************************//**
-TRUE if the record is the supremum record on a page.
-@return TRUE if the supremum record */
-UNIV_INLINE
-ibool
-page_rec_is_supremum(
-/*=================*/
- const rec_t* rec) /*!< in: record */
- MY_ATTRIBUTE((warn_unused_result));
-
-/************************************************************//**
-TRUE if the record is the infimum record on a page.
-@return TRUE if the infimum record */
-UNIV_INLINE
-ibool
-page_rec_is_infimum(
-/*================*/
- const rec_t* rec) /*!< in: record */
- MY_ATTRIBUTE((warn_unused_result));
/************************************************************//**
true if the record is the first user record on a page.
diff --git a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic
index db98f2e6558..0062db56bfa 100644
--- a/storage/innobase/include/page0page.ic
+++ b/storage/innobase/include/page0page.ic
@@ -40,32 +40,7 @@ Created 2/2/1994 Heikki Tuuri
#undef UNIV_INLINE
#define UNIV_INLINE
#endif
-#endif /* !UNIV_INNOCHECKSUM */
-/************************************************************//**
-Gets the start of a page.
-@return start of the page */
-UNIV_INLINE
-page_t*
-page_align(
-/*=======*/
- const void* ptr) /*!< in: pointer to page frame */
-{
- return((page_t*) ut_align_down(ptr, UNIV_PAGE_SIZE));
-}
-
-#ifndef UNIV_INNOCHECKSUM
-/************************************************************//**
-Gets the offset within a page.
-@return offset from the start of the page */
-UNIV_INLINE
-ulint
-page_offset(
-/*========*/
- const void* ptr) /*!< in: pointer to page frame */
-{
- return(ut_align_offset(ptr, UNIV_PAGE_SIZE));
-}
/*************************************************************//**
Returns the max trx id field value. */
UNIV_INLINE
@@ -286,34 +261,6 @@ page_header_reset_last_insert(
}
}
-#endif /* !UNIV_INNOCHECKSUM */
-
-/************************************************************//**
-Determine whether the page is in new-style compact format.
-@return nonzero if the page is in compact format, zero if it is in
-old-style format */
-UNIV_INLINE
-ulint
-page_is_comp(
-/*=========*/
- const page_t* page) /*!< in: index page */
-{
- return(page[PAGE_HEADER + PAGE_N_HEAP] & 0x80);
-}
-
-#ifndef UNIV_INNOCHECKSUM
-/************************************************************//**
-TRUE if the record is on a page in compact format.
-@return nonzero if in compact format */
-UNIV_INLINE
-ulint
-page_rec_is_comp(
-/*=============*/
- const rec_t* rec) /*!< in: record */
-{
- return(page_is_comp(page_align(rec)));
-}
-
/***************************************************************//**
Returns the heap number of a record.
@return heap number */
@@ -330,33 +277,6 @@ page_rec_get_heap_no(
}
}
-#endif /* !UNIV_INNOCHECKSUM */
-
-/************************************************************//**
-Determine whether the page is a B-tree leaf.
-@return true if the page is a B-tree leaf (PAGE_LEVEL = 0) */
-UNIV_INLINE
-bool
-page_is_leaf(
-/*=========*/
- const page_t* page) /*!< in: page */
-{
- return(!*(const uint16*) (page + (PAGE_HEADER + PAGE_LEVEL)));
-}
-
-#ifndef UNIV_INNOCHECKSUM
-/************************************************************//**
-Determine whether the page is empty.
-@return true if the page is empty (PAGE_N_RECS = 0) */
-UNIV_INLINE
-bool
-page_is_empty(
-/*==========*/
- const page_t* page) /*!< in: page */
-{
- return(!*(const uint16*) (page + (PAGE_HEADER + PAGE_N_RECS)));
-}
-
/** Determine whether a page is an index root page.
@param[in] page page frame
@return true if the page is a root page of an index */
@@ -382,162 +302,36 @@ page_is_root(
== IB_UINT64_MAX);
}
-/************************************************************//**
-Determine whether the page contains garbage.
-@return true if the page contains garbage (PAGE_GARBAGE is not 0) */
-UNIV_INLINE
+/** Determine whether an index page record is a user record.
+@param[in] rec record in an index page
+@return true if a user record */
+inline
bool
-page_has_garbage(
-/*=============*/
- const page_t* page) /*!< in: page */
-{
- return(!!*(const uint16*) (page + (PAGE_HEADER + PAGE_GARBAGE)));
-}
-
-/************************************************************//**
-Gets the offset of the first record on the page.
-@return offset of the first record in record list, relative from page */
-UNIV_INLINE
-ulint
-page_get_infimum_offset(
-/*====================*/
- const page_t* page) /*!< in: page which must have record(s) */
-{
- ut_ad(page);
- ut_ad(!page_offset(page));
-
- if (page_is_comp(page)) {
- return(PAGE_NEW_INFIMUM);
- } else {
- return(PAGE_OLD_INFIMUM);
- }
-}
-
-/************************************************************//**
-Gets the offset of the last record on the page.
-@return offset of the last record in record list, relative from page */
-UNIV_INLINE
-ulint
-page_get_supremum_offset(
-/*=====================*/
- const page_t* page) /*!< in: page which must have record(s) */
-{
- ut_ad(page);
- ut_ad(!page_offset(page));
-
- if (page_is_comp(page)) {
- return(PAGE_NEW_SUPREMUM);
- } else {
- return(PAGE_OLD_SUPREMUM);
- }
-}
-
-/************************************************************//**
-TRUE if the record is a user record on the page.
-@return TRUE if a user record */
-UNIV_INLINE
-ibool
-page_rec_is_user_rec_low(
-/*=====================*/
- ulint offset) /*!< in: record offset on page */
-{
- ut_ad(offset >= PAGE_NEW_INFIMUM);
-#if PAGE_OLD_INFIMUM < PAGE_NEW_INFIMUM
-# error "PAGE_OLD_INFIMUM < PAGE_NEW_INFIMUM"
-#endif
-#if PAGE_OLD_SUPREMUM < PAGE_NEW_SUPREMUM
-# error "PAGE_OLD_SUPREMUM < PAGE_NEW_SUPREMUM"
-#endif
-#if PAGE_NEW_INFIMUM > PAGE_OLD_SUPREMUM
-# error "PAGE_NEW_INFIMUM > PAGE_OLD_SUPREMUM"
-#endif
-#if PAGE_OLD_INFIMUM > PAGE_NEW_SUPREMUM
-# error "PAGE_OLD_INFIMUM > PAGE_NEW_SUPREMUM"
-#endif
-#if PAGE_NEW_SUPREMUM > PAGE_OLD_SUPREMUM_END
-# error "PAGE_NEW_SUPREMUM > PAGE_OLD_SUPREMUM_END"
-#endif
-#if PAGE_OLD_SUPREMUM > PAGE_NEW_SUPREMUM_END
-# error "PAGE_OLD_SUPREMUM > PAGE_NEW_SUPREMUM_END"
-#endif
- ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
-
- return(offset != PAGE_NEW_SUPREMUM
- && offset != PAGE_NEW_INFIMUM
- && offset != PAGE_OLD_INFIMUM
- && offset != PAGE_OLD_SUPREMUM);
-}
-
-/************************************************************//**
-TRUE if the record is the supremum record on a page.
-@return TRUE if the supremum record */
-UNIV_INLINE
-ibool
-page_rec_is_supremum_low(
-/*=====================*/
- ulint offset) /*!< in: record offset on page */
-{
- ut_ad(offset >= PAGE_NEW_INFIMUM);
- ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
-
- return(offset == PAGE_NEW_SUPREMUM
- || offset == PAGE_OLD_SUPREMUM);
-}
-
-/************************************************************//**
-TRUE if the record is the infimum record on a page.
-@return TRUE if the infimum record */
-UNIV_INLINE
-ibool
-page_rec_is_infimum_low(
-/*====================*/
- ulint offset) /*!< in: record offset on page */
-{
- ut_ad(offset >= PAGE_NEW_INFIMUM);
- ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
-
- return(offset == PAGE_NEW_INFIMUM || offset == PAGE_OLD_INFIMUM);
-}
-
-/************************************************************//**
-TRUE if the record is a user record on the page.
-@return TRUE if a user record */
-UNIV_INLINE
-ibool
-page_rec_is_user_rec(
-/*=================*/
- const rec_t* rec) /*!< in: record */
+page_rec_is_user_rec(const rec_t* rec)
{
ut_ad(page_rec_check(rec));
-
return(page_rec_is_user_rec_low(page_offset(rec)));
}
-/************************************************************//**
-TRUE if the record is the supremum record on a page.
-@return TRUE if the supremum record */
-UNIV_INLINE
-ibool
-page_rec_is_supremum(
-/*=================*/
- const rec_t* rec) /*!< in: record */
+/** Determine whether an index page record is the supremum record.
+@param[in] rec record in an index page
+@return true if the supremum record */
+inline
+bool
+page_rec_is_supremum(const rec_t* rec)
{
ut_ad(page_rec_check(rec));
-
return(page_rec_is_supremum_low(page_offset(rec)));
}
-/************************************************************//**
-TRUE if the record is the infimum record on a page.
-@return TRUE if the infimum record */
-UNIV_INLINE
-ibool
-page_rec_is_infimum(
-/*================*/
- const rec_t* rec) /*!< in: record */
+/** Determine whether an index page record is the infimum record.
+@param[in] rec record in an index page
+@return true if the infimum record */
+inline
+bool
+page_rec_is_infimum(const rec_t* rec)
{
ut_ad(page_rec_check(rec));
-
return(page_rec_is_infimum_low(page_offset(rec)));
}
diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h
index 61220d4f533..6e927da9bd9 100644
--- a/storage/innobase/include/rem0rec.h
+++ b/storage/innobase/include/rem0rec.h
@@ -444,38 +444,41 @@ rec_get_n_extern_new(
ulint n) /*!< in: number of columns to scan */
MY_ATTRIBUTE((nonnull, warn_unused_result));
-/******************************************************//**
-The following function determines the offsets to each field
-in the record. It can reuse a previously allocated array.
+/** Determine the offsets to each field in an index record.
+@param[in] rec physical record
+@param[in] index the index that the record belongs to
+@param[in,out] offsets array comprising offsets[0] allocated elements,
+ or an array from rec_get_offsets(), or NULL
+@param[in] leaf whether this is a leaf-page record
+@param[in] n_fields maximum number of offsets to compute
+ (ULINT_UNDEFINED to compute all offsets)
+@param[in,out] heap memory heap
@return the new offsets */
ulint*
rec_get_offsets_func(
-/*=================*/
- const rec_t* rec, /*!< in: physical record */
- const dict_index_t* index, /*!< in: record descriptor */
- ulint* offsets,/*!< in/out: array consisting of
- offsets[0] allocated elements,
- or an array from rec_get_offsets(),
- or NULL */
- ulint n_fields,/*!< in: maximum number of
- initialized fields
- (ULINT_UNDEFINED if all fields) */
+ const rec_t* rec,
+ const dict_index_t* index,
+ ulint* offsets,
+#ifdef UNIV_DEBUG
+ bool leaf,
+#endif /* UNIV_DEBUG */
+ ulint n_fields,
#ifdef UNIV_DEBUG
const char* file, /*!< in: file name where called */
unsigned line, /*!< in: line number where called */
#endif /* UNIV_DEBUG */
mem_heap_t** heap) /*!< in/out: memory heap */
#ifdef UNIV_DEBUG
- MY_ATTRIBUTE((nonnull(1,2,5,7),warn_unused_result));
+ MY_ATTRIBUTE((nonnull(1,2,6,8),warn_unused_result));
#else /* UNIV_DEBUG */
MY_ATTRIBUTE((nonnull(1,2,5),warn_unused_result));
#endif /* UNIV_DEBUG */
#ifdef UNIV_DEBUG
-# define rec_get_offsets(rec,index,offsets,n,heap) \
- rec_get_offsets_func(rec,index,offsets,n,__FILE__,__LINE__,heap)
+# define rec_get_offsets(rec, index, offsets, leaf, n, heap) \
+ rec_get_offsets_func(rec,index,offsets,leaf,n,__FILE__,__LINE__,heap)
#else /* UNIV_DEBUG */
-# define rec_get_offsets(rec, index, offsets, n, heap) \
+# define rec_get_offsets(rec, index, offsets, leaf, n, heap) \
rec_get_offsets_func(rec, index, offsets, n, heap)
#endif /* UNIV_DEBUG */
@@ -933,19 +936,31 @@ rec_get_converted_size(
const dtuple_t* dtuple, /*!< in: data tuple */
ulint n_ext) /*!< in: number of externally stored columns */
MY_ATTRIBUTE((warn_unused_result, nonnull));
-/**************************************************************//**
-Copies the first n fields of a physical record to a data tuple.
-The fields are copied to the memory heap. */
+/** Copy the first n fields of a (copy of a) physical record to a data tuple.
+The fields are copied into the memory heap.
+@param[out] tuple data tuple
+@param[in] rec index record, or a copy thereof
+@param[in] is_leaf whether rec is a leaf page record
+@param[in] n_fields number of fields to copy
+@param[in,out] heap memory heap */
void
-rec_copy_prefix_to_dtuple(
-/*======================*/
- dtuple_t* tuple, /*!< out: data tuple */
- const rec_t* rec, /*!< in: physical record */
- const dict_index_t* index, /*!< in: record descriptor */
- ulint n_fields, /*!< in: number of fields
- to copy */
- mem_heap_t* heap) /*!< in: memory heap */
+rec_copy_prefix_to_dtuple_func(
+ dtuple_t* tuple,
+ const rec_t* rec,
+ const dict_index_t* index,
+#ifdef UNIV_DEBUG
+ bool is_leaf,
+#endif /* UNIV_DEBUG */
+ ulint n_fields,
+ mem_heap_t* heap)
MY_ATTRIBUTE((nonnull));
+#ifdef UNIV_DEBUG
+# define rec_copy_prefix_to_dtuple(tuple,rec,index,leaf,n_fields,heap) \
+ rec_copy_prefix_to_dtuple_func(tuple,rec,index,leaf,n_fields,heap)
+#else /* UNIV_DEBUG */
+# define rec_copy_prefix_to_dtuple(tuple,rec,index,leaf,n_fields,heap) \
+ rec_copy_prefix_to_dtuple_func(tuple,rec,index,n_fields,heap)
+#endif /* UNIV_DEBUG */
/***************************************************************//**
Validates the consistency of a physical record.
@return TRUE if ok */
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 3166bb810a1..90755445d95 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -5595,13 +5595,14 @@ lock_rec_print(FILE* file, const lock_t* lock)
fprintf(file, "Record lock, heap no %lu", (ulong) i);
if (block) {
+ ut_ad(page_is_leaf(block->frame));
const rec_t* rec;
rec = page_find_rec_with_heap_no(
buf_block_get_frame(block), i);
offsets = rec_get_offsets(
- rec, lock->index, offsets,
+ rec, lock->index, offsets, true,
ULINT_UNDEFINED, &heap);
putc(' ', file);
@@ -6433,8 +6434,10 @@ loop:
rec = page_find_rec_with_heap_no(block->frame, i);
ut_a(rec);
+ ut_ad(page_rec_is_leaf(rec));
offsets = rec_get_offsets(rec, lock->index, offsets,
- ULINT_UNDEFINED, &heap);
+ true, ULINT_UNDEFINED,
+ &heap);
/* If this thread is holding the file space
latch (fil_space_t::latch), the following
@@ -6777,7 +6780,7 @@ lock_rec_insert_check_and_lock(
const ulint* offsets;
rec_offs_init(offsets_);
- offsets = rec_get_offsets(next_rec, index, offsets_,
+ offsets = rec_get_offsets(next_rec, index, offsets_, true,
ULINT_UNDEFINED, &heap);
ut_ad(lock_rec_queue_validate(
@@ -7004,7 +7007,7 @@ lock_sec_rec_modify_check_and_lock(
const ulint* offsets;
rec_offs_init(offsets_);
- offsets = rec_get_offsets(rec, index, offsets_,
+ offsets = rec_get_offsets(rec, index, offsets_, true,
ULINT_UNDEFINED, &heap);
ut_ad(lock_rec_queue_validate(
@@ -7214,7 +7217,8 @@ lock_clust_rec_read_check_and_lock_alt(
dberr_t err;
rec_offs_init(offsets_);
- offsets = rec_get_offsets(rec, index, offsets,
+ ut_ad(page_rec_is_leaf(rec));
+ offsets = rec_get_offsets(rec, index, offsets, true,
ULINT_UNDEFINED, &tmp_heap);
err = lock_clust_rec_read_check_and_lock(flags, block, rec, index,
offsets, mode, gap_mode, thr);
diff --git a/storage/innobase/mtr/mtr0log.cc b/storage/innobase/mtr/mtr0log.cc
index 7d97aaa3f42..8cfde15a3ba 100644
--- a/storage/innobase/mtr/mtr0log.cc
+++ b/storage/innobase/mtr/mtr0log.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, MariaDB Corporation.
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
@@ -443,10 +444,11 @@ mlog_open_and_write_index(
alloc = mtr_buf_t::MAX_DATA_SIZE;
}
+ const bool is_leaf = page_is_leaf(page_align(rec));
+
/* For spatial index, on non-leaf page, we just keep
2 fields, MBR and page no. */
- if (dict_index_is_spatial(index)
- && !page_is_leaf(page_align(rec))) {
+ if (!is_leaf && dict_index_is_spatial(index)) {
n = DICT_INDEX_SPATIAL_NODEPTR_SIZE;
}
@@ -464,7 +466,7 @@ mlog_open_and_write_index(
mach_write_to_2(log_ptr, n);
log_ptr += 2;
- if (page_is_leaf(page_align(rec))) {
+ if (is_leaf) {
mach_write_to_2(
log_ptr, dict_index_get_n_unique_in_tree(index));
} else {
@@ -601,6 +603,7 @@ mlog_parse_index(
}
/* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */
ind->cached = TRUE;
+ ut_d(ind->is_dummy = true);
*index = ind;
return(ptr);
}
diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc
index e5c903935f1..23a11fcfaa3 100644
--- a/storage/innobase/page/page0cur.cc
+++ b/storage/innobase/page/page0cur.cc
@@ -107,9 +107,10 @@ page_cur_try_search_shortcut(
rec_offs_init(offsets_);
ut_ad(dtuple_check_typed(tuple));
+ ut_ad(page_is_leaf(page));
rec = page_header_get_ptr(page, PAGE_LAST_INSERT);
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, true,
dtuple_get_n_fields(tuple), &heap);
ut_ad(rec);
@@ -124,7 +125,7 @@ page_cur_try_search_shortcut(
next_rec = page_rec_get_next_const(rec);
if (!page_rec_is_supremum(next_rec)) {
- offsets = rec_get_offsets(next_rec, index, offsets,
+ offsets = rec_get_offsets(next_rec, index, offsets, true,
dtuple_get_n_fields(tuple), &heap);
if (cmp_dtuple_rec_with_match(tuple, next_rec, offsets,
@@ -190,9 +191,10 @@ page_cur_try_search_shortcut_bytes(
rec_offs_init(offsets_);
ut_ad(dtuple_check_typed(tuple));
+ ut_ad(page_is_leaf(page));
rec = page_header_get_ptr(page, PAGE_LAST_INSERT);
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, true,
dtuple_get_n_fields(tuple), &heap);
ut_ad(rec);
@@ -213,7 +215,7 @@ page_cur_try_search_shortcut_bytes(
next_rec = page_rec_get_next_const(rec);
if (!page_rec_is_supremum(next_rec)) {
- offsets = rec_get_offsets(next_rec, index, offsets,
+ offsets = rec_get_offsets(next_rec, index, offsets, true,
dtuple_get_n_fields(tuple), &heap);
if (cmp_dtuple_rec_with_match_bytes(
@@ -354,9 +356,10 @@ page_cur_search_with_match(
#endif /* UNIV_ZIP_DEBUG */
ut_d(page_check_dir(page));
+ const bool is_leaf = page_is_leaf(page);
#ifdef BTR_CUR_HASH_ADAPT
- if (page_is_leaf(page)
+ if (is_leaf
&& (mode == PAGE_CUR_LE)
&& !dict_index_is_spatial(index)
&& (page_header_get_field(page, PAGE_N_DIRECTION) > 3)
@@ -383,7 +386,7 @@ page_cur_search_with_match(
if (dict_index_is_spatial(index) && mode > PAGE_CUR_LE) {
/* For leaf level insert, we still use the traditional
compare function for now */
- if (mode == PAGE_CUR_RTREE_INSERT && page_is_leaf(page)){
+ if (mode == PAGE_CUR_RTREE_INSERT && is_leaf) {
mode = PAGE_CUR_LE;
} else {
rtr_cur_search_with_match(
@@ -428,7 +431,7 @@ page_cur_search_with_match(
offsets = offsets_;
offsets = rec_get_offsets(
- mid_rec, index, offsets,
+ mid_rec, index, offsets, is_leaf,
dtuple_get_n_fields_cmp(tuple), &heap);
cmp = cmp_dtuple_rec_with_match(
@@ -482,7 +485,7 @@ up_slot_match:
offsets = offsets_;
offsets = rec_get_offsets(
- mid_rec, index, offsets,
+ mid_rec, index, offsets, is_leaf,
dtuple_get_n_fields_cmp(tuple), &heap);
cmp = cmp_dtuple_rec_with_match(
@@ -664,6 +667,7 @@ page_cur_search_with_match_bytes(
/* Perform binary search until the lower and upper limit directory
slots come to the distance 1 of each other */
+ ut_d(bool is_leaf = page_is_leaf(page));
while (up - low > 1) {
mid = (low + up) / 2;
@@ -675,7 +679,7 @@ page_cur_search_with_match_bytes(
up_matched_fields, up_matched_bytes);
offsets = rec_get_offsets(
- mid_rec, index, offsets_,
+ mid_rec, index, offsets_, is_leaf,
dtuple_get_n_fields_cmp(tuple), &heap);
cmp = cmp_dtuple_rec_with_match_bytes(
@@ -732,7 +736,7 @@ up_slot_match:
up_matched_fields, up_matched_bytes);
offsets = rec_get_offsets(
- mid_rec, index, offsets_,
+ mid_rec, index, offsets_, is_leaf,
dtuple_get_n_fields_cmp(tuple), &heap);
cmp = cmp_dtuple_rec_with_match_bytes(
@@ -850,15 +854,9 @@ page_cur_insert_rec_write_log(
const byte* log_end;
ulint i;
- /* Avoid REDO logging to save on costly IO because
- temporary tables are not recovered during crash recovery. */
if (dict_table_is_temporary(index->table)) {
- byte* log_ptr = mlog_open(mtr, 0);
- if (log_ptr == NULL) {
- return;
- }
- mlog_close(mtr, log_ptr);
- log_ptr = NULL;
+ ut_ad(!mlog_open(mtr, 0));
+ return;
}
ut_a(rec_size < UNIV_PAGE_SIZE);
@@ -867,6 +865,8 @@ page_cur_insert_rec_write_log(
ut_ad(!page_rec_is_comp(insert_rec)
== !dict_table_is_comp(index->table));
+ ut_d(const bool is_leaf = page_rec_is_leaf(cursor_rec));
+
{
mem_heap_t* heap = NULL;
ulint cur_offs_[REC_OFFS_NORMAL_SIZE];
@@ -879,9 +879,9 @@ page_cur_insert_rec_write_log(
rec_offs_init(ins_offs_);
cur_offs = rec_get_offsets(cursor_rec, index, cur_offs_,
- ULINT_UNDEFINED, &heap);
+ is_leaf, ULINT_UNDEFINED, &heap);
ins_offs = rec_get_offsets(insert_rec, index, ins_offs_,
- ULINT_UNDEFINED, &heap);
+ is_leaf, ULINT_UNDEFINED, &heap);
extra_size = rec_offs_extra_size(ins_offs);
cur_extra_size = rec_offs_extra_size(cur_offs);
@@ -1139,7 +1139,9 @@ page_cur_parse_insert_rec(
/* Read from the log the inserted index record end segment which
differs from the cursor record */
- offsets = rec_get_offsets(cursor_rec, index, offsets,
+ ut_d(bool is_leaf = page_is_leaf(page));
+
+ offsets = rec_get_offsets(cursor_rec, index, offsets, is_leaf,
ULINT_UNDEFINED, &heap);
if (!(end_seg_len & 0x1UL)) {
@@ -1184,7 +1186,7 @@ page_cur_parse_insert_rec(
page_cur_position(cursor_rec, block, &cursor);
offsets = rec_get_offsets(buf + origin_offset, index, offsets,
- ULINT_UNDEFINED, &heap);
+ is_leaf, ULINT_UNDEFINED, &heap);
if (UNIV_UNLIKELY(!page_cur_rec_insert(&cursor,
buf + origin_offset,
index, offsets, mtr))) {
@@ -1275,7 +1277,8 @@ page_cur_insert_rec_low(
rec_offs_init(foffsets_);
foffsets = rec_get_offsets(
- free_rec, index, foffsets, ULINT_UNDEFINED, &heap);
+ free_rec, index, foffsets, page_is_leaf(page),
+ ULINT_UNDEFINED, &heap);
if (rec_offs_size(foffsets) < rec_size) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
@@ -1705,6 +1708,7 @@ page_cur_insert_rec_zip(
rec_offs_init(foffsets_);
foffsets = rec_get_offsets(free_rec, index, foffsets,
+ page_rec_is_leaf(free_rec),
ULINT_UNDEFINED, &heap);
if (rec_offs_size(foffsets) < rec_size) {
too_small:
@@ -2052,7 +2056,6 @@ page_copy_rec_list_end_to_created_page(
page_header_set_ptr(new_page, NULL, PAGE_HEAP_TOP,
new_page + UNIV_PAGE_SIZE - 1);
#endif
-
log_ptr = page_copy_rec_list_to_created_page_write_log(new_page,
index, mtr);
@@ -2075,8 +2078,10 @@ page_copy_rec_list_end_to_created_page(
slot_index = 0;
n_recs = 0;
+ ut_d(const bool is_leaf = page_is_leaf(new_page));
+
do {
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, is_leaf,
ULINT_UNDEFINED, &heap);
insert_rec = rec_copy(heap_top, rec, offsets);
@@ -2251,6 +2256,7 @@ page_cur_parse_delete_rec(
page_cur_delete_rec(&cursor, index,
rec_get_offsets(rec, index, offsets_,
+ page_rec_is_leaf(rec),
ULINT_UNDEFINED, &heap),
mtr);
if (UNIV_LIKELY_NULL(heap)) {
diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc
index b2c27acfbaa..fcc77aeb591 100644
--- a/storage/innobase/page/page0page.cc
+++ b/storage/innobase/page/page0page.cc
@@ -598,6 +598,7 @@ page_copy_rec_list_end_no_locks(
ut_a(page_is_comp(new_page) == page_rec_is_comp(rec));
ut_a(mach_read_from_2(new_page + UNIV_PAGE_SIZE - 10) == (ulint)
(page_is_comp(new_page) ? PAGE_NEW_INFIMUM : PAGE_OLD_INFIMUM));
+ ut_d(const bool is_leaf = page_is_leaf(block->frame));
cur2 = page_get_infimum_rec(buf_block_get_frame(new_block));
@@ -606,7 +607,7 @@ page_copy_rec_list_end_no_locks(
while (!page_cur_is_after_last(&cur1)) {
rec_t* cur1_rec = page_cur_get_rec(&cur1);
rec_t* ins_rec;
- offsets = rec_get_offsets(cur1_rec, index, offsets,
+ offsets = rec_get_offsets(cur1_rec, index, offsets, is_leaf,
ULINT_UNDEFINED, &heap);
ins_rec = page_cur_insert_rec_low(cur2, index,
cur1_rec, offsets, mtr);
@@ -835,6 +836,8 @@ page_copy_rec_list_start(
cur2 = ret;
+ const bool is_leaf = page_rec_is_leaf(rec);
+
/* Copy records from the original page to the new page */
if (dict_index_is_spatial(index)) {
ulint max_to_move = page_get_n_recs(
@@ -856,6 +859,7 @@ page_copy_rec_list_start(
while (page_cur_get_rec(&cur1) != rec) {
rec_t* cur1_rec = page_cur_get_rec(&cur1);
offsets = rec_get_offsets(cur1_rec, index, offsets,
+ is_leaf,
ULINT_UNDEFINED, &heap);
cur2 = page_cur_insert_rec_low(cur2, index,
cur1_rec, offsets, mtr);
@@ -872,8 +876,7 @@ page_copy_rec_list_start(
same temp-table in parallel.
max_trx_id is ignored for temp tables because it not required
for MVCC. */
- if (dict_index_is_sec_or_ibuf(index)
- && page_is_leaf(page_align(rec))
+ if (is_leaf && dict_index_is_sec_or_ibuf(index)
&& !dict_table_is_temporary(index->table)) {
page_update_max_trx_id(new_block, NULL,
page_get_max_trx_id(page_align(rec)),
@@ -1103,6 +1106,8 @@ delete_all:
? MLOG_COMP_LIST_END_DELETE
: MLOG_LIST_END_DELETE, mtr);
+ ut_d(const bool is_leaf = page_is_leaf(page));
+
if (page_zip) {
mtr_log_t log_mode;
@@ -1115,7 +1120,7 @@ delete_all:
page_cur_t cur;
page_cur_position(rec, block, &cur);
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, is_leaf,
ULINT_UNDEFINED, &heap);
rec = rec_get_next_ptr(rec, TRUE);
#ifdef UNIV_ZIP_DEBUG
@@ -1149,6 +1154,7 @@ delete_all:
do {
ulint s;
offsets = rec_get_offsets(rec2, index, offsets,
+ is_leaf,
ULINT_UNDEFINED, &heap);
s = rec_offs_size(offsets);
ut_ad(rec2 - page + s - rec_offs_extra_size(offsets)
@@ -1291,10 +1297,12 @@ page_delete_rec_list_start(
/* Individual deletes are not logged */
mtr_log_t log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE);
+ ut_d(const bool is_leaf = page_rec_is_leaf(rec));
while (page_cur_get_rec(&cur1) != rec) {
offsets = rec_get_offsets(page_cur_get_rec(&cur1), index,
- offsets, ULINT_UNDEFINED, &heap);
+ offsets, is_leaf,
+ ULINT_UNDEFINED, &heap);
page_cur_delete_rec(&cur1, index, offsets, mtr);
}
@@ -2466,6 +2474,7 @@ page_validate(
for (;;) {
offsets = rec_get_offsets(rec, index, offsets,
+ page_is_leaf(page),
ULINT_UNDEFINED, &heap);
if (page_is_comp(page) && page_rec_is_user_rec(rec)
@@ -2635,6 +2644,7 @@ n_owned_zero:
while (rec != NULL) {
offsets = rec_get_offsets(rec, index, offsets,
+ page_is_leaf(page),
ULINT_UNDEFINED, &heap);
if (UNIV_UNLIKELY(!page_rec_validate(rec, offsets))) {
diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc
index 277af52eaef..10d905e0c8b 100644
--- a/storage/innobase/page/page0zip.cc
+++ b/storage/innobase/page/page0zip.cc
@@ -885,7 +885,7 @@ page_zip_compress_node_ptrs(
do {
const rec_t* rec = *recs++;
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, false,
ULINT_UNDEFINED, &heap);
/* Only leaf nodes may contain externally stored columns. */
ut_ad(!rec_offs_any_extern(offsets));
@@ -1134,7 +1134,7 @@ page_zip_compress_clust(
do {
const rec_t* rec = *recs++;
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, true,
ULINT_UNDEFINED, &heap);
ut_ad(rec_offs_n_fields(offsets)
== dict_index_get_n_fields(index));
@@ -2078,6 +2078,7 @@ page_zip_apply_log(
sorted by address (indexed by
heap_no - PAGE_HEAP_NO_USER_LOW) */
ulint n_dense,/*!< in: size of recs[] */
+ bool is_leaf,/*!< in: whether this is a leaf page */
ulint trx_id_col,/*!< in: column number of trx_id in the index,
or ULINT_UNDEFINED if none */
ulint heap_status,
@@ -2153,7 +2154,7 @@ page_zip_apply_log(
/* Clear the data bytes of the record. */
mem_heap_t* heap = NULL;
ulint* offs;
- offs = rec_get_offsets(rec, index, offsets,
+ offs = rec_get_offsets(rec, index, offsets, is_leaf,
ULINT_UNDEFINED, &heap);
memset(rec, 0, rec_offs_data_size(offs));
@@ -2349,7 +2350,7 @@ page_zip_decompress_node_ptrs(
}
/* Read the offsets. The status bits are needed here. */
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, false,
ULINT_UNDEFINED, &heap);
/* Non-leaf nodes should not have any externally
@@ -2435,7 +2436,7 @@ zlib_done:
const byte* mod_log_ptr;
mod_log_ptr = page_zip_apply_log(d_stream->next_in,
d_stream->avail_in + 1,
- recs, n_dense,
+ recs, n_dense, false,
ULINT_UNDEFINED, heap_status,
index, offsets);
@@ -2466,7 +2467,7 @@ zlib_done:
for (slot = 0; slot < n_dense; slot++) {
rec_t* rec = recs[slot];
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, false,
ULINT_UNDEFINED, &heap);
/* Non-leaf nodes should not have any externally
stored columns. */
@@ -2587,7 +2588,7 @@ zlib_done:
const byte* mod_log_ptr;
mod_log_ptr = page_zip_apply_log(d_stream->next_in,
d_stream->avail_in + 1,
- recs, n_dense,
+ recs, n_dense, true,
ULINT_UNDEFINED, heap_status,
index, offsets);
@@ -2790,7 +2791,7 @@ page_zip_decompress_clust(
}
/* Read the offsets. The status bits are needed here. */
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, true,
ULINT_UNDEFINED, &heap);
/* This is a leaf page in a clustered index. */
@@ -2916,7 +2917,7 @@ zlib_done:
const byte* mod_log_ptr;
mod_log_ptr = page_zip_apply_log(d_stream->next_in,
d_stream->avail_in + 1,
- recs, n_dense,
+ recs, n_dense, true,
trx_id_col, heap_status,
index, offsets);
@@ -2952,7 +2953,7 @@ zlib_done:
rec_t* rec = recs[slot];
ibool exists = !page_zip_dir_find_free(
page_zip, page_offset(rec));
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, true,
ULINT_UNDEFINED, &heap);
dst = rec_get_nth_field(rec, offsets,
@@ -3463,6 +3464,7 @@ page_zip_validate_low(
page + PAGE_NEW_INFIMUM, TRUE);
trec = page_rec_get_next_low(
temp_page + PAGE_NEW_INFIMUM, TRUE);
+ ut_d(const bool is_leaf = page_is_leaf(page));
do {
if (page_offset(rec) != page_offset(trec)) {
@@ -3477,7 +3479,7 @@ page_zip_validate_low(
if (index) {
/* Compare the data. */
offsets = rec_get_offsets(
- rec, index, offsets,
+ rec, index, offsets, is_leaf,
ULINT_UNDEFINED, &heap);
if (memcmp(rec - rec_offs_extra_size(offsets),
diff --git a/storage/innobase/rem/rem0cmp.cc b/storage/innobase/rem/rem0cmp.cc
index 7c965f791be..0e2bc9b30de 100644
--- a/storage/innobase/rem/rem0cmp.cc
+++ b/storage/innobase/rem/rem0cmp.cc
@@ -797,7 +797,6 @@ cmp_dtuple_rec_with_match_bytes(
ut_ad(dtuple_check_typed(dtuple));
ut_ad(rec_offs_validate(rec, index, offsets));
- //ut_ad(page_is_leaf(page_align(rec)));
ut_ad(!(REC_INFO_MIN_REC_FLAG
& dtuple_get_info_bits(dtuple)));
ut_ad(!(REC_INFO_MIN_REC_FLAG
diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc
index 66e8ccec178..d4d1a2bab14 100644
--- a/storage/innobase/rem/rem0rec.cc
+++ b/storage/innobase/rem/rem0rec.cc
@@ -520,22 +520,25 @@ resolved:
}
}
-/******************************************************//**
-The following function determines the offsets to each field
-in the record. It can reuse a previously returned array.
+/** Determine the offsets to each field in an index record.
+@param[in] rec physical record
+@param[in] index the index that the record belongs to
+@param[in,out] offsets array comprising offsets[0] allocated elements,
+ or an array from rec_get_offsets(), or NULL
+@param[in] leaf whether this is a leaf-page record
+@param[in] n_fields maximum number of offsets to compute
+ (ULINT_UNDEFINED to compute all offsets)
+@param[in,out] heap memory heap
@return the new offsets */
ulint*
rec_get_offsets_func(
-/*=================*/
- const rec_t* rec, /*!< in: physical record */
- const dict_index_t* index, /*!< in: record descriptor */
- ulint* offsets,/*!< in/out: array consisting of
- offsets[0] allocated elements,
- or an array from rec_get_offsets(),
- or NULL */
- ulint n_fields,/*!< in: maximum number of
- initialized fields
- (ULINT_UNDEFINED if all fields) */
+ const rec_t* rec,
+ const dict_index_t* index,
+ ulint* offsets,
+#ifdef UNIV_DEBUG
+ bool leaf,
+#endif /* UNIV_DEBUG */
+ ulint n_fields,
#ifdef UNIV_DEBUG
const char* file, /*!< in: file name where called */
unsigned line, /*!< in: line number where called */
@@ -553,17 +556,23 @@ rec_get_offsets_func(
switch (UNIV_EXPECT(rec_get_status(rec),
REC_STATUS_ORDINARY)) {
case REC_STATUS_ORDINARY:
+ ut_ad(leaf);
n = dict_index_get_n_fields(index);
break;
case REC_STATUS_NODE_PTR:
/* Node pointer records consist of the
uniquely identifying fields of the record
followed by a child page number field. */
+ ut_ad(!leaf);
n = dict_index_get_n_unique_in_tree_nonleaf(index) + 1;
break;
case REC_STATUS_INFIMUM:
case REC_STATUS_SUPREMUM:
/* infimum or supremum record */
+ ut_ad(rec_get_heap_no_new(rec)
+ == (rec_get_status(rec) == REC_STATUS_INFIMUM
+ ? PAGE_HEAP_NO_INFIMUM
+ : PAGE_HEAP_NO_SUPREMUM));
n = 1;
break;
default:
@@ -572,6 +581,28 @@ rec_get_offsets_func(
}
} else {
n = rec_get_n_fields_old(rec);
+ /* Here, rec can be allocated from the heap (copied
+ from an index page record), or it can be located in an
+ index page. If rec is not in an index page, then
+ page_rec_is_user_rec(rec) and similar predicates
+ cannot be evaluated. We can still distinguish the
+ infimum and supremum record based on the heap number. */
+ ut_d(const bool is_user_rec = rec_get_heap_no_old(rec)
+ >= PAGE_HEAP_NO_USER_LOW);
+ ut_ad(n <= ulint(index->n_fields + !leaf) || index->is_dummy
+ || dict_index_is_ibuf(index));
+ /* The infimum and supremum records carry 1 field. */
+ ut_ad(is_user_rec || n == 1);
+ ut_ad(!is_user_rec || leaf || index->is_dummy
+ || dict_index_is_ibuf(index)
+ || n
+ == dict_index_get_n_unique_in_tree_nonleaf(index) + 1);
+ ut_ad(!is_user_rec || !leaf || index->is_dummy
+ || dict_index_is_ibuf(index)
+ || n == n_fields /* btr_pcur_restore_position() */
+ || n == index->n_fields
+ || (index->id == DICT_INDEXES_ID
+ && (n == DICT_NUM_FIELDS__SYS_INDEXES - 1)));
}
if (UNIV_UNLIKELY(n_fields < n)) {
@@ -1468,30 +1499,6 @@ rec_convert_dtuple_to_rec(
rec = rec_convert_dtuple_to_rec_old(buf, dtuple, n_ext);
}
-#ifdef UNIV_DEBUG
- {
- mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- const ulint* offsets;
- ulint i;
- rec_offs_init(offsets_);
-
- offsets = rec_get_offsets(rec, index,
- offsets_, ULINT_UNDEFINED, &heap);
- ut_ad(rec_validate(rec, offsets));
- ut_ad(dtuple_get_n_fields(dtuple)
- == rec_offs_n_fields(offsets));
-
- for (i = 0; i < rec_offs_n_fields(offsets); i++) {
- ut_ad(!dfield_is_ext(dtuple_get_nth_field(dtuple, i))
- == !rec_offs_nth_extern(offsets, i));
- }
-
- if (UNIV_LIKELY_NULL(heap)) {
- mem_heap_free(heap);
- }
- }
-#endif /* UNIV_DEBUG */
return(rec);
}
@@ -1541,25 +1548,32 @@ rec_convert_dtuple_to_temp(
REC_STATUS_ORDINARY, true);
}
-/**************************************************************//**
-Copies the first n fields of a physical record to a data tuple. The fields
-are copied to the memory heap. */
+/** Copy the first n fields of a (copy of a) physical record to a data tuple.
+The fields are copied into the memory heap.
+@param[out] tuple data tuple
+@param[in] rec index record, or a copy thereof
+@param[in] is_leaf whether rec is a leaf page record
+@param[in] n_fields number of fields to copy
+@param[in,out] heap memory heap */
void
-rec_copy_prefix_to_dtuple(
-/*======================*/
- dtuple_t* tuple, /*!< out: data tuple */
- const rec_t* rec, /*!< in: physical record */
- const dict_index_t* index, /*!< in: record descriptor */
- ulint n_fields, /*!< in: number of fields
- to copy */
- mem_heap_t* heap) /*!< in: memory heap */
+rec_copy_prefix_to_dtuple_func(
+ dtuple_t* tuple,
+ const rec_t* rec,
+ const dict_index_t* index,
+#ifdef UNIV_DEBUG
+ bool is_leaf,
+#endif /* UNIV_DEBUG */
+ ulint n_fields,
+ mem_heap_t* heap)
{
- ulint i;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
rec_offs_init(offsets_);
- offsets = rec_get_offsets(rec, index, offsets, n_fields, &heap);
+ ut_ad(is_leaf || n_fields <= index->n_uniq + 1);
+
+ offsets = rec_get_offsets(rec, index, offsets, is_leaf,
+ n_fields, &heap);
ut_ad(rec_validate(rec, offsets));
ut_ad(dtuple_check_typed(tuple));
@@ -1567,7 +1581,7 @@ rec_copy_prefix_to_dtuple(
dtuple_set_info_bits(tuple, rec_get_info_bits(
rec, dict_table_is_comp(index->table)));
- for (i = 0; i < n_fields; i++) {
+ for (ulint i = 0; i < n_fields; i++) {
dfield_t* field;
const byte* data;
ulint len;
@@ -2155,6 +2169,7 @@ rec_print(
rec_print_new(file, rec,
rec_get_offsets(rec, index, offsets_,
+ page_rec_is_leaf(rec),
ULINT_UNDEFINED, &heap));
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
@@ -2225,7 +2240,8 @@ operator<<(std::ostream& o, const rec_index_print& r)
{
mem_heap_t* heap = NULL;
ulint* offsets = rec_get_offsets(
- r.m_rec, r.m_index, NULL, ULINT_UNDEFINED, &heap);
+ r.m_rec, r.m_index, NULL, page_rec_is_leaf(r.m_rec),
+ ULINT_UNDEFINED, &heap);
rec_print(o, r.m_rec,
rec_get_info_bits(r.m_rec, rec_offs_comp(offsets)),
offsets);
@@ -2272,10 +2288,12 @@ rec_get_trx_id(
ut_ad(mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID)
== index->id);
ut_ad(dict_index_is_clust(index));
+ ut_ad(page_rec_is_leaf(rec));
ut_ad(trx_id_col > 0);
ut_ad(trx_id_col != ULINT_UNDEFINED);
- offsets = rec_get_offsets(rec, index, offsets, trx_id_col + 1, &heap);
+ offsets = rec_get_offsets(rec, index, offsets, true,
+ trx_id_col + 1, &heap);
trx_id = rec_get_nth_field(rec, offsets, trx_id_col, &len);
@@ -2323,7 +2341,7 @@ wsrep_rec_get_foreign_key(
ut_ad(index_ref);
rec_offs_init(offsets_);
- offsets = rec_get_offsets(rec, index_for, offsets_,
+ offsets = rec_get_offsets(rec, index_for, offsets_, true,
ULINT_UNDEFINED, &heap);
ut_ad(rec_offs_validate(rec, NULL, offsets));
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 0b538660c9b..c109afe2682 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -1735,7 +1735,7 @@ PageConverter::update_records(
if (deleted || clust_index) {
m_offsets = rec_get_offsets(
- rec, m_index->m_srv_index, m_offsets,
+ rec, m_index->m_srv_index, m_offsets, true,
ULINT_UNDEFINED, &m_heap);
}
@@ -2323,7 +2323,7 @@ row_import_set_sys_max_row_id(
rec_offs_init(offsets_);
offsets = rec_get_offsets(
- rec, index, offsets_, ULINT_UNDEFINED, &heap);
+ rec, index, offsets_, true, ULINT_UNDEFINED, &heap);
field = rec_get_nth_field(
rec, offsets,
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index b7f28e633a3..a8258fa2c0f 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -952,7 +952,7 @@ row_ins_foreign_fill_virtual(
ulint offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs_init(offsets_);
const ulint* offsets =
- rec_get_offsets(rec, index, offsets_,
+ rec_get_offsets(rec, index, offsets_, true,
ULINT_UNDEFINED, &cascade->heap);
mem_heap_t* v_heap = NULL;
upd_t* update = cascade->update;
@@ -1732,8 +1732,8 @@ row_ins_check_foreign_constraint(
continue;
}
- offsets = rec_get_offsets(rec, check_index,
- offsets, ULINT_UNDEFINED, &heap);
+ offsets = rec_get_offsets(rec, check_index, offsets, true,
+ ULINT_UNDEFINED, &heap);
if (page_rec_is_supremum(rec)) {
@@ -2122,7 +2122,7 @@ row_ins_scan_sec_index_for_duplicate(
continue;
}
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, true,
ULINT_UNDEFINED, &offsets_heap);
if (flags & BTR_NO_LOCKING_FLAG) {
@@ -2251,7 +2251,7 @@ row_ins_duplicate_error_in_clust_online(
const rec_t* rec = btr_cur_get_rec(cursor);
if (cursor->low_match >= n_uniq && !page_rec_is_infimum(rec)) {
- *offsets = rec_get_offsets(rec, cursor->index, *offsets,
+ *offsets = rec_get_offsets(rec, cursor->index, *offsets, true,
ULINT_UNDEFINED, heap);
err = row_ins_duplicate_online(n_uniq, entry, rec, *offsets);
if (err != DB_SUCCESS) {
@@ -2262,7 +2262,7 @@ row_ins_duplicate_error_in_clust_online(
rec = page_rec_get_next_const(btr_cur_get_rec(cursor));
if (cursor->up_match >= n_uniq && !page_rec_is_supremum(rec)) {
- *offsets = rec_get_offsets(rec, cursor->index, *offsets,
+ *offsets = rec_get_offsets(rec, cursor->index, *offsets, true,
ULINT_UNDEFINED, heap);
err = row_ins_duplicate_online(n_uniq, entry, rec, *offsets);
}
@@ -2318,6 +2318,7 @@ row_ins_duplicate_error_in_clust(
if (!page_rec_is_infimum(rec)) {
offsets = rec_get_offsets(rec, cursor->index, offsets,
+ true,
ULINT_UNDEFINED, &heap);
ulint lock_type;
@@ -2377,6 +2378,7 @@ duplicate:
if (!page_rec_is_supremum(rec)) {
offsets = rec_get_offsets(rec, cursor->index, offsets,
+ true,
ULINT_UNDEFINED, &heap);
if (trx->duplicates) {
@@ -2492,7 +2494,7 @@ row_ins_index_entry_big_rec(
btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_MODIFY_TREE,
&pcur, &mtr);
rec = btr_pcur_get_rec(&pcur);
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, true,
ULINT_UNDEFINED, heap);
DEBUG_SYNC_C_IF_THD(thd, "before_row_ins_extern");
@@ -3052,7 +3054,7 @@ row_ins_sec_index_entry_low(
ut_ad(!page_rec_is_infimum(rec));
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, true,
ULINT_UNDEFINED, &offsets_heap);
err = row_ins_set_exclusive_rec_lock(
@@ -3083,7 +3085,7 @@ row_ins_sec_index_entry_low(
prefix, we must convert the insert into a modify of an
existing record */
offsets = rec_get_offsets(
- btr_cur_get_rec(&cursor), index, offsets,
+ btr_cur_get_rec(&cursor), index, offsets, true,
ULINT_UNDEFINED, &offsets_heap);
err = row_ins_sec_index_entry_by_modify(
diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc
index 93ddb8ee45b..58c316c6327 100644
--- a/storage/innobase/row/row0log.cc
+++ b/storage/innobase/row/row0log.cc
@@ -998,7 +998,7 @@ row_log_table_low(
&index->lock,
RW_LOCK_FLAG_S | RW_LOCK_FLAG_X | RW_LOCK_FLAG_SX));
ut_ad(fil_page_get_type(page_align(rec)) == FIL_PAGE_INDEX);
- ut_ad(page_is_leaf(page_align(rec)));
+ ut_ad(page_rec_is_leaf(rec));
ut_ad(!page_is_comp(page_align(rec)) == !rec_offs_comp(offsets));
/* old_pk=row_log_table_get_pk() [not needed in INSERT] is a prefix
of the clustered index record (PRIMARY KEY,DB_TRX_ID,DB_ROLL_PTR),
@@ -1263,8 +1263,8 @@ row_log_table_get_pk(
if (!offsets) {
offsets = rec_get_offsets(
- rec, index, NULL, pos + 1,
- heap);
+ rec, index, NULL, true,
+ pos + 1, heap);
}
trx_id_offs = rec_get_nth_field_offs(
@@ -1313,7 +1313,7 @@ row_log_table_get_pk(
}
if (!offsets) {
- offsets = rec_get_offsets(rec, index, NULL,
+ offsets = rec_get_offsets(rec, index, NULL, true,
ULINT_UNDEFINED, heap);
}
@@ -1998,7 +1998,7 @@ all_done:
return(DB_SUCCESS);
}
- offsets = rec_get_offsets(btr_pcur_get_rec(&pcur), index, NULL,
+ offsets = rec_get_offsets(btr_pcur_get_rec(&pcur), index, NULL, true,
ULINT_UNDEFINED, &offsets_heap);
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ut_a(!rec_offs_any_null_extern(btr_pcur_get_rec(&pcur), offsets));
@@ -2204,8 +2204,8 @@ func_exit_committed:
/* Prepare to update (or delete) the record. */
ulint* cur_offsets = rec_get_offsets(
- btr_pcur_get_rec(&pcur),
- index, NULL, ULINT_UNDEFINED, &offsets_heap);
+ btr_pcur_get_rec(&pcur), index, NULL, true,
+ ULINT_UNDEFINED, &offsets_heap);
if (!log->same_pk) {
/* Only update the record if DB_TRX_ID,DB_ROLL_PTR match what
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index 68af56e5639..b2e4657476c 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -2060,7 +2060,7 @@ end_of_index:
rec = page_cur_get_rec(cur);
if (online) {
- offsets = rec_get_offsets(rec, clust_index, NULL,
+ offsets = rec_get_offsets(rec, clust_index, NULL, true,
ULINT_UNDEFINED, &row_heap);
rec_trx_id = row_get_rec_trx_id(rec, clust_index,
offsets);
@@ -2152,7 +2152,7 @@ end_of_index:
duplicate keys. */
continue;
} else {
- offsets = rec_get_offsets(rec, clust_index, NULL,
+ offsets = rec_get_offsets(rec, clust_index, NULL, true,
ULINT_UNDEFINED, &row_heap);
/* This is a locking ALTER TABLE.
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 313a0d55a67..583acdc482b 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -2031,7 +2031,6 @@ run_again:
node->cascade_upd_nodes = cascade_upd_nodes;
cascade_upd_nodes->pop_front();
thr->fk_cascade_depth++;
- prebuilt->m_mysql_table = NULL;
goto run_again;
}
@@ -2245,7 +2244,7 @@ row_unlock_for_mysql(
ulint* offsets = offsets_;
rec_offs_init(offsets_);
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, true,
ULINT_UNDEFINED, &heap);
rec_trx_id = row_get_rec_trx_id(rec, index, offsets);
@@ -5069,7 +5068,7 @@ func_exit:
rec = buf + mach_read_from_4(buf);
- offsets = rec_get_offsets(rec, index, offsets_,
+ offsets = rec_get_offsets(rec, index, offsets_, true,
ULINT_UNDEFINED, &heap);
if (prev_entry != NULL) {
diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc
index 4bdb8b34a80..ba6c1282eaa 100644
--- a/storage/innobase/row/row0purge.cc
+++ b/storage/innobase/row/row0purge.cc
@@ -152,7 +152,7 @@ row_purge_remove_clust_if_poss_low(
rec = btr_pcur_get_rec(&node->pcur);
offsets = rec_get_offsets(
- rec, index, offsets_, ULINT_UNDEFINED, &heap);
+ rec, index, offsets_, true, ULINT_UNDEFINED, &heap);
if (node->roll_ptr != row_get_rec_roll_ptr(rec, index, offsets)) {
/* Someone else has modified the record later: do not remove */
@@ -686,7 +686,7 @@ row_purge_reset_trx_id(purge_node_t* node, mtr_t* mtr)
ulint offsets_[REC_OFFS_HEADER_SIZE + MAX_REF_PARTS + 2];
rec_offs_init(offsets_);
ulint* offsets = rec_get_offsets(
- rec, index, offsets_, trx_id_pos + 2, &heap);
+ rec, index, offsets_, true, trx_id_pos + 2, &heap);
ut_ad(heap == NULL);
ut_ad(dict_index_get_nth_field(index, trx_id_pos)
@@ -1215,7 +1215,8 @@ purge_node_t::validate_pcur()
dict_index_t* clust_index = pcur.btr_cur.index;
ulint* offsets = rec_get_offsets(
- pcur.old_rec, clust_index, NULL, pcur.old_n_fields, &heap);
+ pcur.old_rec, clust_index, NULL, true,
+ pcur.old_n_fields, &heap);
/* Here we are comparing the purge ref record and the stored initial
part in persistent cursor. Both cases we store n_uniq fields of the
diff --git a/storage/innobase/row/row0row.cc b/storage/innobase/row/row0row.cc
index 69cecf2d79f..a61adb7cd15 100644
--- a/storage/innobase/row/row0row.cc
+++ b/storage/innobase/row/row0row.cc
@@ -400,7 +400,7 @@ row_build_low(
ut_ad(!col_map || col_table);
if (!offsets) {
- offsets = rec_get_offsets(rec, index, offsets_,
+ offsets = rec_get_offsets(rec, index, offsets_, true,
ULINT_UNDEFINED, &tmp_heap);
} else {
ut_ad(rec_offs_validate(rec, index, offsets));
@@ -792,7 +792,7 @@ row_build_row_ref(
ut_ad(heap != NULL);
ut_ad(!dict_index_is_clust(index));
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, true,
ULINT_UNDEFINED, &tmp_heap);
/* Secondary indexes must not contain externally stored columns. */
ut_ad(!rec_offs_any_extern(offsets));
@@ -904,7 +904,7 @@ row_build_row_ref_in_tuple(
ut_ad(clust_index);
if (!offsets) {
- offsets = rec_get_offsets(rec, index, offsets_,
+ offsets = rec_get_offsets(rec, index, offsets_, true,
ULINT_UNDEFINED, &heap);
} else {
ut_ad(rec_offs_validate(rec, index, offsets));
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 984890791bd..1b045a23fe9 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -197,9 +197,9 @@ row_sel_sec_rec_is_for_clust_rec(
heap = mem_heap_create(256);
clust_offs = rec_get_offsets(clust_rec, clust_index, clust_offs,
- ULINT_UNDEFINED, &heap);
+ true, ULINT_UNDEFINED, &heap);
sec_offs = rec_get_offsets(sec_rec, sec_index, sec_offs,
- ULINT_UNDEFINED, &heap);
+ true, ULINT_UNDEFINED, &heap);
n = dict_index_get_n_ordering_defined_by_user(sec_index);
@@ -904,7 +904,7 @@ row_sel_get_clust_rec(
offsets = rec_get_offsets(rec,
btr_pcur_get_btr_cur(&plan->pcur)->index,
- offsets, ULINT_UNDEFINED, &heap);
+ offsets, true, ULINT_UNDEFINED, &heap);
row_build_row_ref_fast(plan->clust_ref, plan->clust_map, rec, offsets);
@@ -939,7 +939,7 @@ row_sel_get_clust_rec(
goto func_exit;
}
- offsets = rec_get_offsets(clust_rec, index, offsets,
+ offsets = rec_get_offsets(clust_rec, index, offsets, true,
ULINT_UNDEFINED, &heap);
if (!node->read_view) {
@@ -1158,7 +1158,7 @@ re_scan:
rec = btr_pcur_get_rec(pcur);
my_offsets = offsets_;
- my_offsets = rec_get_offsets(rec, index, my_offsets,
+ my_offsets = rec_get_offsets(rec, index, my_offsets, true,
ULINT_UNDEFINED, &heap);
/* No match record */
@@ -1181,8 +1181,8 @@ re_scan:
rtr_rec_t* rtr_rec = &(*it);
my_offsets = rec_get_offsets(
- rtr_rec->r_rec, index, my_offsets,
- ULINT_UNDEFINED, &heap);
+ rtr_rec->r_rec, index, my_offsets, true,
+ ULINT_UNDEFINED, &heap);
err = lock_sec_rec_read_check_and_lock(
0, &match->block, rtr_rec->r_rec, index,
@@ -1196,12 +1196,10 @@ re_scan:
} else {
goto func_end;
}
-
}
match->locked = true;
-
func_end:
rw_lock_x_unlock(&(match->block.lock));
if (heap != NULL) {
@@ -1510,7 +1508,8 @@ row_sel_try_search_shortcut(
/* This is a non-locking consistent read: if necessary, fetch
a previous version of the record */
- offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
+ offsets = rec_get_offsets(rec, index, offsets, true,
+ ULINT_UNDEFINED, &heap);
if (dict_index_is_clust(index)) {
if (!lock_clust_rec_cons_read_sees(rec, index, offsets,
@@ -1768,6 +1767,7 @@ rec_loop:
trx = thr_get_trx(thr);
offsets = rec_get_offsets(next_rec, index, offsets,
+ true,
ULINT_UNDEFINED, &heap);
/* If innodb_locks_unsafe_for_binlog option is used
@@ -1826,7 +1826,7 @@ skip_lock:
ulint lock_type;
trx_t* trx;
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, true,
ULINT_UNDEFINED, &heap);
trx = thr_get_trx(thr);
@@ -1913,7 +1913,8 @@ skip_lock:
/* PHASE 3: Get previous version in a consistent read */
cons_read_requires_clust_rec = FALSE;
- offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
+ offsets = rec_get_offsets(rec, index, offsets, true,
+ ULINT_UNDEFINED, &heap);
if (consistent_read) {
/* This is a non-locking consistent read: if necessary, fetch
@@ -1943,7 +1944,7 @@ skip_lock:
exhausted. */
offsets = rec_get_offsets(
- rec, index, offsets,
+ rec, index, offsets, true,
ULINT_UNDEFINED, &heap);
/* Fetch the columns needed in
@@ -3392,23 +3393,12 @@ row_sel_get_clust_rec_for_mysql(
goto func_exit;
}
- ulint page_no = page_get_page_no(
- btr_pcur_get_page(
- prebuilt->pcur));
-
- page_id_t page_id(dict_index_get_space(sec_index),
- page_no);
-
- buf_block_t* block = buf_page_get_gen(
- page_id,
- dict_table_page_size(sec_index->table),
- RW_NO_LATCH, NULL, BUF_GET,
- __FILE__, __LINE__, mtr, &err);
-
+ buf_block_t* block = btr_pcur_get_block(
+ prebuilt->pcur);
mem_heap_t* heap = mem_heap_create(256);
dtuple_t* tuple = dict_index_build_data_tuple(
- sec_index, const_cast<rec_t*>(rec),
- dict_index_get_n_fields(sec_index), heap);;
+ rec, sec_index, true,
+ sec_index->n_fields, heap);
page_cur_t page_cursor;
ulint low_match = page_cur_search(
@@ -3457,7 +3447,7 @@ row_sel_get_clust_rec_for_mysql(
goto func_exit;
}
- *offsets = rec_get_offsets(clust_rec, clust_index, *offsets,
+ *offsets = rec_get_offsets(clust_rec, clust_index, *offsets, true,
ULINT_UNDEFINED, offset_heap);
if (prebuilt->select_lock_type != LOCK_NONE) {
@@ -3901,7 +3891,7 @@ row_sel_try_search_shortcut_for_mysql(
/* This is a non-locking consistent read: if necessary, fetch
a previous version of the record */
- *offsets = rec_get_offsets(rec, index, *offsets,
+ *offsets = rec_get_offsets(rec, index, *offsets, true,
ULINT_UNDEFINED, heap);
if (!lock_clust_rec_cons_read_sees(
@@ -4031,8 +4021,9 @@ row_sel_fill_vrow(
rec_offs_init(offsets_);
ut_ad(!(*vrow));
+ ut_ad(page_rec_is_leaf(rec));
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, true,
ULINT_UNDEFINED, &heap);
*vrow = dtuple_create_with_vcol(
@@ -4585,6 +4576,7 @@ wait_table_again:
pcur->trx_if_known = trx;
rec = btr_pcur_get_rec(pcur);
+ ut_ad(page_rec_is_leaf(rec));
if (!moves_up
&& !page_rec_is_supremum(rec)
@@ -4599,6 +4591,7 @@ wait_table_again:
const rec_t* next_rec = page_rec_get_next_const(rec);
offsets = rec_get_offsets(next_rec, index, offsets,
+ true,
ULINT_UNDEFINED, &heap);
err = sel_set_rec_lock(pcur,
next_rec, index, offsets,
@@ -4656,6 +4649,7 @@ rec_loop:
}
ut_ad(!!page_rec_is_comp(rec) == comp);
+ ut_ad(page_rec_is_leaf(rec));
if (page_rec_is_infimum(rec)) {
@@ -4681,7 +4675,7 @@ rec_loop:
level we do not lock gaps. Supremum record is really
a gap and therefore we do not set locks there. */
- offsets = rec_get_offsets(rec, index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets, true,
ULINT_UNDEFINED, &heap);
err = sel_set_rec_lock(pcur,
rec, index, offsets,
@@ -4771,7 +4765,8 @@ wrong_offs:
ut_ad(fil_page_index_page_check(btr_pcur_get_page(pcur)));
ut_ad(btr_page_get_index_id(btr_pcur_get_page(pcur)) == index->id);
- offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
+ offsets = rec_get_offsets(rec, index, offsets, true,
+ ULINT_UNDEFINED, &heap);
if (UNIV_UNLIKELY(srv_force_recovery > 0)) {
if (!rec_validate(rec, offsets)
@@ -4992,8 +4987,8 @@ no_gap_lock:
Do a normal locking read. */
offsets = rec_get_offsets(
- rec, index, offsets, ULINT_UNDEFINED,
- &heap);
+ rec, index, offsets, true,
+ ULINT_UNDEFINED, &heap);
goto locks_ok;
case DB_DEADLOCK:
goto lock_wait_or_error;
@@ -5432,6 +5427,7 @@ requires_clust_rec:
/* We used 'offsets' for the clust
rec, recalculate them for 'rec' */
offsets = rec_get_offsets(rec, index, offsets,
+ true,
ULINT_UNDEFINED,
&heap);
result_rec = rec;
@@ -5929,8 +5925,10 @@ row_search_autoinc_read_column(
ulint* offsets = offsets_;
rec_offs_init(offsets_);
+ ut_ad(page_rec_is_leaf(rec));
- offsets = rec_get_offsets(rec, index, offsets, col_no + 1, &heap);
+ offsets = rec_get_offsets(rec, index, offsets, true,
+ col_no + 1, &heap);
if (rec_offs_nth_sql_null(offsets, col_no)) {
/* There is no non-NULL value in the auto-increment column. */
diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc
index 0fce0731307..60a9f49b576 100644
--- a/storage/innobase/row/row0uins.cc
+++ b/storage/innobase/row/row0uins.cc
@@ -112,7 +112,7 @@ row_undo_ins_remove_clust_rec(
const rec_t* rec = btr_cur_get_rec(btr_cur);
mem_heap_t* heap = NULL;
const ulint* offsets = rec_get_offsets(
- rec, index, NULL, ULINT_UNDEFINED, &heap);
+ rec, index, NULL, true, ULINT_UNDEFINED, &heap);
row_log_table_delete(rec, node->row, index, offsets, NULL);
mem_heap_free(heap);
}
diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc
index 5a0b41e2c26..1ed25e7076a 100644
--- a/storage/innobase/row/row0umod.cc
+++ b/storage/innobase/row/row0umod.cc
@@ -196,7 +196,7 @@ row_undo_mod_remove_clust_low(
offsets = rec_get_offsets(
btr_cur_get_rec(btr_cur), btr_cur_get_index(btr_cur),
- NULL, trx_id_col + 1, &heap);
+ NULL, true, trx_id_col + 1, &heap);
trx_id_offset = rec_get_nth_field_offs(
offsets, trx_id_col, &len);
@@ -751,7 +751,7 @@ try_again:
offsets_heap = NULL;
offsets = rec_get_offsets(
btr_cur_get_rec(btr_cur),
- index, NULL, ULINT_UNDEFINED, &offsets_heap);
+ index, NULL, true, ULINT_UNDEFINED, &offsets_heap);
update = row_upd_build_sec_rec_difference_binary(
btr_cur_get_rec(btr_cur), index, offsets, entry, heap);
if (upd_get_n_fields(update) == 0) {
diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc
index 4742e17b5e8..0679b29b6ca 100644
--- a/storage/innobase/row/row0undo.cc
+++ b/storage/innobase/row/row0undo.cc
@@ -185,7 +185,7 @@ row_undo_search_clust_to_pcur(
rec = btr_pcur_get_rec(&node->pcur);
- offsets = rec_get_offsets(rec, clust_index, offsets,
+ offsets = rec_get_offsets(rec, clust_index, offsets, true,
ULINT_UNDEFINED, &heap);
found = row_get_rec_roll_ptr(rec, clust_index, offsets)
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index c6e05bd236a..1444f6f7c7d 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -1069,7 +1069,7 @@ row_upd_build_difference_binary(
== trx_id_pos + 1);
if (!offsets) {
- offsets = rec_get_offsets(rec, index, offsets_,
+ offsets = rec_get_offsets(rec, index, offsets_, true,
ULINT_UNDEFINED, &heap);
} else {
ut_ad(rec_offs_validate(rec, index, offsets));
@@ -2196,7 +2196,7 @@ row_upd_store_row(
rec = btr_pcur_get_rec(node->pcur);
- offsets = rec_get_offsets(rec, clust_index, offsets_,
+ offsets = rec_get_offsets(rec, clust_index, offsets_, true,
ULINT_UNDEFINED, &heap);
if (dict_table_has_atomic_blobs(node->table)) {
@@ -2444,8 +2444,8 @@ row_upd_sec_index_entry(
&& !wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
ulint* offsets = rec_get_offsets(
- rec, index, NULL, ULINT_UNDEFINED,
- &heap);
+ rec, index, NULL, true,
+ ULINT_UNDEFINED, &heap);
err = wsrep_row_upd_check_foreign_constraints(
node, &pcur, index->table,
@@ -2481,7 +2481,7 @@ row_upd_sec_index_entry(
ulint* offsets;
offsets = rec_get_offsets(
- rec, index, NULL, ULINT_UNDEFINED,
+ rec, index, NULL, true, ULINT_UNDEFINED,
&heap);
/* NOTE that the following call loses
@@ -2690,7 +2690,7 @@ row_upd_clust_rec_by_insert(
we update the primary key. Delete-mark the old record
in the clustered index and prepare to insert a new entry. */
rec = btr_cur_get_rec(btr_cur);
- offsets = rec_get_offsets(rec, index, NULL,
+ offsets = rec_get_offsets(rec, index, NULL, true,
ULINT_UNDEFINED, &heap);
ut_ad(page_rec_is_user_rec(rec));
@@ -2965,7 +2965,8 @@ row_upd_del_mark_clust_rec(
entries */
row_upd_store_row(node, trx->mysql_thd,
- thr->prebuilt ? thr->prebuilt->m_mysql_table : NULL);
+ thr->prebuilt && thr->prebuilt->table == node->table
+ ? thr->prebuilt->m_mysql_table : NULL);
/* Mark the clustered index record deleted; we do not have to check
locks, because we assume that we have an x-lock on the record */
@@ -3131,7 +3132,7 @@ row_upd_clust_step(
}
rec = btr_pcur_get_rec(pcur);
- offsets = rec_get_offsets(rec, index, offsets_,
+ offsets = rec_get_offsets(rec, index, offsets_, true,
ULINT_UNDEFINED, &heap);
if (!flags && !node->has_clust_rec_x_lock) {
diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc
index 26f6739c3ae..a659042bb2f 100644
--- a/storage/innobase/row/row0vers.cc
+++ b/storage/innobase/row/row0vers.cc
@@ -108,7 +108,7 @@ row_vers_impl_x_locked_low(
heap = mem_heap_create(1024);
clust_offsets = rec_get_offsets(
- clust_rec, clust_index, NULL, ULINT_UNDEFINED, &heap);
+ clust_rec, clust_index, NULL, true, ULINT_UNDEFINED, &heap);
trx_id = row_get_rec_trx_id(clust_rec, clust_index, clust_offsets);
if (trx_id == 0) {
@@ -219,8 +219,8 @@ row_vers_impl_x_locked_low(
}
clust_offsets = rec_get_offsets(
- prev_version, clust_index, NULL, ULINT_UNDEFINED,
- &heap);
+ prev_version, clust_index, NULL, true,
+ ULINT_UNDEFINED, &heap);
vers_del = rec_get_deleted_flag(prev_version, comp);
@@ -581,7 +581,8 @@ row_vers_build_cur_vrow_low(
}
clust_offsets = rec_get_offsets(prev_version, clust_index,
- NULL, ULINT_UNDEFINED, &heap);
+ NULL,
+ true, ULINT_UNDEFINED, &heap);
ulint entry_len = dict_index_get_n_fields(index);
@@ -719,7 +720,8 @@ row_vers_vc_matches_cluster(
}
clust_offsets = rec_get_offsets(prev_version, clust_index,
- NULL, ULINT_UNDEFINED, &heap);
+ NULL,
+ true, ULINT_UNDEFINED, &heap);
ulint entry_len = dict_index_get_n_fields(index);
@@ -845,7 +847,7 @@ row_vers_build_cur_vrow(
index, roll_ptr, trx_id, v_heap, &cur_vrow, mtr);
}
- *clust_offsets = rec_get_offsets(rec, clust_index, NULL,
+ *clust_offsets = rec_get_offsets(rec, clust_index, NULL, true,
ULINT_UNDEFINED, &heap);
return(cur_vrow);
}
@@ -894,7 +896,7 @@ row_vers_old_has_index_entry(
comp = page_rec_is_comp(rec);
ut_ad(!dict_table_is_comp(index->table) == !comp);
heap = mem_heap_create(1024);
- clust_offsets = rec_get_offsets(rec, clust_index, NULL,
+ clust_offsets = rec_get_offsets(rec, clust_index, NULL, true,
ULINT_UNDEFINED, &heap);
if (dict_index_has_virtual(index)) {
@@ -968,6 +970,7 @@ row_vers_old_has_index_entry(
}
}
clust_offsets = rec_get_offsets(rec, clust_index, NULL,
+ true,
ULINT_UNDEFINED, &heap);
} else {
@@ -1042,7 +1045,8 @@ row_vers_old_has_index_entry(
}
clust_offsets = rec_get_offsets(prev_version, clust_index,
- NULL, ULINT_UNDEFINED, &heap);
+ NULL, true,
+ ULINT_UNDEFINED, &heap);
if (dict_index_has_virtual(index)) {
if (vrow) {
@@ -1187,8 +1191,8 @@ row_vers_build_for_consistent_read(
}
*offsets = rec_get_offsets(
- prev_version, index, *offsets, ULINT_UNDEFINED,
- offset_heap);
+ prev_version, index, *offsets,
+ true, ULINT_UNDEFINED, offset_heap);
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ut_a(!rec_offs_any_null_extern(prev_version, *offsets));
@@ -1323,6 +1327,7 @@ committed_version_trx:
version = rec;
*offsets = rec_get_offsets(version,
index, *offsets,
+ true,
ULINT_UNDEFINED,
offset_heap);
}
@@ -1367,7 +1372,7 @@ committed_version_trx:
}
version = prev_version;
- *offsets = rec_get_offsets(version, index, *offsets,
+ *offsets = rec_get_offsets(version, index, *offsets, true,
ULINT_UNDEFINED, offset_heap);
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ut_a(!rec_offs_any_null_extern(version, *offsets));
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 4089a4f99ed..d87ffeea21f 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -2130,7 +2130,7 @@ files_checked:
compile_time_assert(IBUF_SPACE_ID == 0);
ulint ibuf_root = btr_create(
- DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
+ DICT_CLUSTERED | DICT_IBUF,
0, univ_page_size, DICT_IBUF_ID_MIN,
dict_ind_redundant, NULL, &mtr);
diff --git a/storage/innobase/trx/trx0i_s.cc b/storage/innobase/trx/trx0i_s.cc
index 7854ad2ab5a..327ebf79211 100644
--- a/storage/innobase/trx/trx0i_s.cc
+++ b/storage/innobase/trx/trx0i_s.cc
@@ -726,8 +726,7 @@ fill_lock_data(
ut_a(n_fields > 0);
heap = NULL;
- offsets = rec_get_offsets(rec, index, offsets, n_fields,
- &heap);
+ offsets = rec_get_offsets(rec, index, offsets, true, n_fields, &heap);
/* format and store the data */
diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc
index 02a9f82b3c6..5a8e1e23546 100644
--- a/storage/innobase/trx/trx0rec.cc
+++ b/storage/innobase/trx/trx0rec.cc
@@ -2305,8 +2305,8 @@ trx_undo_prev_version_build(
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
ut_a(!rec_offs_any_null_extern(
- *old_vers, rec_get_offsets(
- *old_vers, index, NULL, ULINT_UNDEFINED, &heap)));
+ *old_vers, rec_get_offsets(*old_vers, index, NULL, true,
+ ULINT_UNDEFINED, &heap)));
#endif // defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
if (vrow && !(cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc
index 63e29eb7767..a332f6047d1 100644
--- a/storage/innobase/trx/trx0sys.cc
+++ b/storage/innobase/trx/trx0sys.cc
@@ -680,6 +680,7 @@ trx_sys_close(void)
/*********************************************************************
Check if there are any active (non-prepared) transactions.
+This is only used to check if it's safe to shutdown.
@return total number of active transactions or 0 if none */
ulint
trx_sys_any_active_transactions(void)
@@ -689,8 +690,13 @@ trx_sys_any_active_transactions(void)
trx_sys_mutex_enter();
- total_trx = UT_LIST_GET_LEN(trx_sys->rw_trx_list)
- + UT_LIST_GET_LEN(trx_sys->mysql_trx_list);
+ total_trx = UT_LIST_GET_LEN(trx_sys->rw_trx_list);
+
+ for (trx_t* trx = UT_LIST_GET_FIRST(trx_sys->mysql_trx_list);
+ trx != NULL;
+ trx = UT_LIST_GET_NEXT(mysql_trx_list, trx)) {
+ total_trx += trx->state != TRX_STATE_NOT_STARTED;
+ }
ut_a(total_trx >= trx_sys->n_prepared_trx);
total_trx -= trx_sys->n_prepared_trx;
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 7ee903200da..cd69f3cd8ee 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -2373,6 +2373,17 @@ ha_myisam::check_if_supported_inplace_alter(TABLE *new_table,
}
+static bool directories_differ(const char *d1, const char *d2)
+{
+ if (!d1 && !d2)
+ return false;
+ if (!d1 || !d2)
+ return true;
+ size_t l1= dirname_length(d1), l2= dirname_length(d2);
+ return l1 != l2 || strncmp(d1, d2, l1);
+}
+
+
bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *create_info,
uint table_changes)
{
@@ -2380,8 +2391,8 @@ bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *create_info,
if ((create_info->used_fields & HA_CREATE_USED_AUTO &&
create_info->auto_increment_value != stats.auto_increment_value) ||
- create_info->data_file_name != data_file_name ||
- create_info->index_file_name != index_file_name ||
+ directories_differ(create_info->data_file_name, data_file_name) ||
+ directories_differ(create_info->index_file_name, index_file_name) ||
table_changes == IS_EQUAL_NO ||
table_changes & IS_EQUAL_PACK_LENGTH) // Not implemented yet
return COMPATIBLE_DATA_NO;
diff --git a/storage/test_sql_discovery/mysql-test/sql_discovery/simple.result b/storage/test_sql_discovery/mysql-test/sql_discovery/simple.result
index 7ca36e07438..23b7804638f 100644
--- a/storage/test_sql_discovery/mysql-test/sql_discovery/simple.result
+++ b/storage/test_sql_discovery/mysql-test/sql_discovery/simple.result
@@ -4,7 +4,7 @@ test_sql_discovery_statement
test_sql_discovery_write_frm ON
set sql_quote_show_create=0;
create table t1 (a int) engine=test_sql_discovery;
-ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database")
+ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by the engine")
select * from t1;
ERROR 42S02: Table 'test.t1' doesn't exist
set @@test_sql_discovery_statement='t1:foobar bwa-ha-ha';
diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt
index ad96328b8db..73e4bf37a06 100644
--- a/storage/tokudb/CMakeLists.txt
+++ b/storage/tokudb/CMakeLists.txt
@@ -1,4 +1,4 @@
-SET(TOKUDB_VERSION 5.6.36-82.1)
+SET(TOKUDB_VERSION 5.6.37-82.2)
# PerconaFT only supports x86-64 and cmake-2.8.9+
IF(CMAKE_VERSION VERSION_LESS "2.8.9")
MESSAGE(STATUS "CMake 2.8.9 or higher is required by TokuDB")
@@ -24,7 +24,7 @@ SET(TOKUDB_SOURCES
tokudb_thread.cc
tokudb_dir_cmd.cc)
MYSQL_ADD_PLUGIN(tokudb ${TOKUDB_SOURCES} STORAGE_ENGINE MODULE_ONLY
- COMPONENT tokudb-engine)
+ COMPONENT tokudb-engine CONFIG tokudb.cnf)
IF(NOT TARGET tokudb)
RETURN()
@@ -111,8 +111,3 @@ TARGET_LINK_LIBRARIES(tokudb tokufractaltree_static tokuportability_static
SET(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} -flto -fuse-linker-plugin")
SET(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO} -flto -fuse-linker-plugin")
-
-IF (INSTALL_SYSCONF2DIR)
- INSTALL(FILES tokudb.cnf DESTINATION ${INSTALL_SYSCONF2DIR}
- COMPONENT tokudb-engine)
-ENDIF(INSTALL_SYSCONF2DIR)
diff --git a/storage/tokudb/PerconaFT/buildheader/make_tdb.cc b/storage/tokudb/PerconaFT/buildheader/make_tdb.cc
index 6f0b7c5f419..0fa876f2bd8 100644
--- a/storage/tokudb/PerconaFT/buildheader/make_tdb.cc
+++ b/storage/tokudb/PerconaFT/buildheader/make_tdb.cc
@@ -231,6 +231,8 @@ static void print_defines (void) {
printf("#define DB_SET_RANGE_REVERSE 252\n"); // private tokudb
//printf("#define DB_GET_BOTH_RANGE_REVERSE 251\n"); // private tokudb. No longer supported #2862.
dodefine(DB_RMW);
+
+ printf("#define DB_LOCKING_READ 0x80000000\n");
printf("#define DB_IS_RESETTING_OP 0x01000000\n"); // private tokudb
printf("#define DB_PRELOCKED 0x00800000\n"); // private tokudb
printf("#define DB_PRELOCKED_WRITE 0x00400000\n"); // private tokudb
diff --git a/storage/tokudb/PerconaFT/src/ydb-internal.h b/storage/tokudb/PerconaFT/src/ydb-internal.h
index a1eb43a67c5..db2041095f7 100644
--- a/storage/tokudb/PerconaFT/src/ydb-internal.h
+++ b/storage/tokudb/PerconaFT/src/ydb-internal.h
@@ -239,13 +239,16 @@ struct __toku_dbc_internal {
struct simple_dbt skey_s,sval_s;
struct simple_dbt *skey,*sval;
- // if the rmw flag is asserted, cursor operations (like set) grab write locks instead of read locks
+ // if the rmw flag is asserted, cursor operations (like set) grab write
+ // locks instead of read locks
// the rmw flag is set when the cursor is created with the DB_RMW flag set
bool rmw;
+ bool locking_read;
};
-static_assert(sizeof(__toku_dbc_internal) <= sizeof(((DBC *) nullptr)->_internal),
- "__toku_dbc_internal doesn't fit in the internal portion of a DBC");
+static_assert(
+ sizeof(__toku_dbc_internal) <= sizeof(((DBC *)nullptr)->_internal),
+ "__toku_dbc_internal doesn't fit in the internal portion of a DBC");
static inline __toku_dbc_internal *dbc_struct_i(DBC *c) {
union dbc_union {
diff --git a/storage/tokudb/PerconaFT/src/ydb_cursor.cc b/storage/tokudb/PerconaFT/src/ydb_cursor.cc
index 015e302f1c6..1f4f00b7423 100644
--- a/storage/tokudb/PerconaFT/src/ydb_cursor.cc
+++ b/storage/tokudb/PerconaFT/src/ydb_cursor.cc
@@ -110,12 +110,14 @@ c_get_wrapper_callback(DBT const *key, DBT const *val, void *extra) {
return r;
}
-static inline uint32_t
-get_cursor_prelocked_flags(uint32_t flags, DBC* dbc) {
+static inline uint32_t get_cursor_prelocked_flags(uint32_t flags, DBC *dbc) {
uint32_t lock_flags = flags & (DB_PRELOCKED | DB_PRELOCKED_WRITE);
- //DB_READ_UNCOMMITTED and DB_READ_COMMITTED transactions 'own' all read locks for user-data dictionaries.
- if (dbc_struct_i(dbc)->iso != TOKU_ISO_SERIALIZABLE) {
+ // DB_READ_UNCOMMITTED and DB_READ_COMMITTED transactions 'own' all read
+ // locks for user-data dictionaries.
+ if (dbc_struct_i(dbc)->iso != TOKU_ISO_SERIALIZABLE &&
+ !(dbc_struct_i(dbc)->iso == TOKU_ISO_SNAPSHOT &&
+ dbc_struct_i(dbc)->locking_read)) {
lock_flags |= DB_PRELOCKED;
}
return lock_flags;
@@ -671,37 +673,44 @@ int toku_c_close(DBC *c) {
return 0;
}
-static int
-c_set_bounds(DBC *dbc, const DBT *left_key, const DBT *right_key, bool pre_acquire, int out_of_range_error) {
+static int c_set_bounds(DBC *dbc,
+ const DBT *left_key,
+ const DBT *right_key,
+ bool pre_acquire,
+ int out_of_range_error) {
if (out_of_range_error != DB_NOTFOUND &&
- out_of_range_error != TOKUDB_OUT_OF_RANGE &&
- out_of_range_error != 0) {
- return toku_ydb_do_error(
- dbc->dbp->dbenv,
- EINVAL,
- "Invalid out_of_range_error [%d] for %s\n",
- out_of_range_error,
- __FUNCTION__
- );
- }
- if (left_key == toku_dbt_negative_infinity() && right_key == toku_dbt_positive_infinity()) {
+ out_of_range_error != TOKUDB_OUT_OF_RANGE && out_of_range_error != 0) {
+ return toku_ydb_do_error(dbc->dbp->dbenv,
+ EINVAL,
+ "Invalid out_of_range_error [%d] for %s\n",
+ out_of_range_error,
+ __FUNCTION__);
+ }
+ if (left_key == toku_dbt_negative_infinity() &&
+ right_key == toku_dbt_positive_infinity()) {
out_of_range_error = 0;
}
DB *db = dbc->dbp;
DB_TXN *txn = dbc_struct_i(dbc)->txn;
HANDLE_PANICKED_DB(db);
- toku_ft_cursor_set_range_lock(dbc_ftcursor(dbc), left_key, right_key,
- (left_key == toku_dbt_negative_infinity()),
- (right_key == toku_dbt_positive_infinity()),
- out_of_range_error);
+ toku_ft_cursor_set_range_lock(dbc_ftcursor(dbc),
+ left_key,
+ right_key,
+ (left_key == toku_dbt_negative_infinity()),
+ (right_key == toku_dbt_positive_infinity()),
+ out_of_range_error);
if (!db->i->lt || !txn || !pre_acquire)
return 0;
- //READ_UNCOMMITTED and READ_COMMITTED transactions do not need read locks.
- if (!dbc_struct_i(dbc)->rmw && dbc_struct_i(dbc)->iso != TOKU_ISO_SERIALIZABLE)
+ // READ_UNCOMMITTED and READ_COMMITTED transactions do not need read locks.
+ if (!dbc_struct_i(dbc)->rmw &&
+ dbc_struct_i(dbc)->iso != TOKU_ISO_SERIALIZABLE &&
+ !(dbc_struct_i(dbc)->iso == TOKU_ISO_SNAPSHOT &&
+ dbc_struct_i(dbc)->locking_read))
return 0;
- toku::lock_request::type lock_type = dbc_struct_i(dbc)->rmw ?
- toku::lock_request::type::WRITE : toku::lock_request::type::READ;
+ toku::lock_request::type lock_type = dbc_struct_i(dbc)->rmw
+ ? toku::lock_request::type::WRITE
+ : toku::lock_request::type::READ;
int r = toku_db_get_range_lock(db, txn, left_key, right_key, lock_type);
return r;
}
@@ -783,18 +792,20 @@ toku_c_get(DBC* c, DBT* key, DBT* val, uint32_t flag) {
return r;
}
-int
-toku_db_cursor_internal(DB * db, DB_TXN * txn, DBC *c, uint32_t flags, int is_temporary_cursor) {
+int toku_db_cursor_internal(DB *db,
+ DB_TXN *txn,
+ DBC *c,
+ uint32_t flags,
+ int is_temporary_cursor) {
HANDLE_PANICKED_DB(db);
HANDLE_DB_ILLEGAL_WORKING_PARENT_TXN(db, txn);
- DB_ENV* env = db->dbenv;
+ DB_ENV *env = db->dbenv;
- if (flags & ~(DB_SERIALIZABLE | DB_INHERIT_ISOLATION | DB_RMW | DBC_DISABLE_PREFETCHING)) {
+ if (flags &
+ ~(DB_SERIALIZABLE | DB_INHERIT_ISOLATION | DB_LOCKING_READ | DB_RMW |
+ DBC_DISABLE_PREFETCHING)) {
return toku_ydb_do_error(
- env,
- EINVAL,
- "Invalid flags set for toku_db_cursor\n"
- );
+ env, EINVAL, "Invalid flags set for toku_db_cursor\n");
}
#define SCRS(name) c->name = name
@@ -819,8 +830,8 @@ toku_db_cursor_internal(DB * db, DB_TXN * txn, DBC *c, uint32_t flags, int is_te
c->dbp = db;
dbc_struct_i(c)->txn = txn;
- dbc_struct_i(c)->skey_s = (struct simple_dbt){0,0};
- dbc_struct_i(c)->sval_s = (struct simple_dbt){0,0};
+ dbc_struct_i(c)->skey_s = (struct simple_dbt){0, 0};
+ dbc_struct_i(c)->sval_s = (struct simple_dbt){0, 0};
if (is_temporary_cursor) {
dbc_struct_i(c)->skey = &db->i->skey;
dbc_struct_i(c)->sval = &db->i->sval;
@@ -831,28 +842,27 @@ toku_db_cursor_internal(DB * db, DB_TXN * txn, DBC *c, uint32_t flags, int is_te
if (flags & DB_SERIALIZABLE) {
dbc_struct_i(c)->iso = TOKU_ISO_SERIALIZABLE;
} else {
- dbc_struct_i(c)->iso = txn ? db_txn_struct_i(txn)->iso : TOKU_ISO_SERIALIZABLE;
+ dbc_struct_i(c)->iso =
+ txn ? db_txn_struct_i(txn)->iso : TOKU_ISO_SERIALIZABLE;
}
dbc_struct_i(c)->rmw = (flags & DB_RMW) != 0;
- enum cursor_read_type read_type = C_READ_ANY; // default, used in serializable and read uncommitted
+ dbc_struct_i(c)->locking_read = (flags & DB_LOCKING_READ) != 0;
+ enum cursor_read_type read_type =
+ C_READ_ANY; // default, used in serializable and read uncommitted
if (txn) {
if (dbc_struct_i(c)->iso == TOKU_ISO_READ_COMMITTED ||
- dbc_struct_i(c)->iso == TOKU_ISO_SNAPSHOT)
- {
+ dbc_struct_i(c)->iso == TOKU_ISO_SNAPSHOT) {
read_type = C_READ_SNAPSHOT;
- }
- else if (dbc_struct_i(c)->iso == TOKU_ISO_READ_COMMITTED_ALWAYS) {
+ } else if (dbc_struct_i(c)->iso == TOKU_ISO_READ_COMMITTED_ALWAYS) {
read_type = C_READ_COMMITTED;
}
}
- int r = toku_ft_cursor_create(
- db->i->ft_handle,
- dbc_ftcursor(c),
- txn ? db_txn_struct_i(txn)->tokutxn : NULL,
- read_type,
- ((flags & DBC_DISABLE_PREFETCHING) != 0),
- is_temporary_cursor != 0
- );
+ int r = toku_ft_cursor_create(db->i->ft_handle,
+ dbc_ftcursor(c),
+ txn ? db_txn_struct_i(txn)->tokutxn : NULL,
+ read_type,
+ ((flags & DBC_DISABLE_PREFETCHING) != 0),
+ is_temporary_cursor != 0);
if (r != 0) {
invariant(r == TOKUDB_MVCC_DICTIONARY_TOO_NEW);
}
diff --git a/storage/tokudb/ha_tokudb.cc b/storage/tokudb/ha_tokudb.cc
index 6cc3ad915cf..4bd00722623 100644
--- a/storage/tokudb/ha_tokudb.cc
+++ b/storage/tokudb/ha_tokudb.cc
@@ -7631,7 +7631,13 @@ static bool tokudb_check_db_dir_exist_from_table_name(const char *table_name) {
memcpy(db_name, db_name_begin, db_name_size);
db_name[db_name_size] = '\0';
- mysql_dir_exists = (check_db_dir_existence(db_name) == 0);
+
+ // At this point, db_name contains the MySQL formatted database name.
+ // This is exactly the same format that would come into us through a
+ // CREATE TABLE. Some charaters (like ':' for example) might be expanded
+ // into hex (':' would papear as "@003a").
+ // We need to check that the MySQL destination database directory exists.
+ mysql_dir_exists = (my_access(db_name, F_OK) == 0);
return mysql_dir_exists;
}
diff --git a/storage/tokudb/mysql-test/rpl/r/rpl_row_log_tokudb.result b/storage/tokudb/mysql-test/rpl/r/rpl_row_log_tokudb.result
deleted file mode 100644
index 73c010c6eb7..00000000000
--- a/storage/tokudb/mysql-test/rpl/r/rpl_row_log_tokudb.result
+++ /dev/null
@@ -1,315 +0,0 @@
-include/master-slave.inc
-[connection master]
-connection slave;
-include/stop_slave.inc
-include/wait_for_slave_to_stop.inc
-reset master;
-reset slave;
-start slave;
-include/wait_for_slave_to_start.inc
-connection slave;
-set @save_slave_ddl_exec_mode=@@global.slave_ddl_exec_mode;
-set @@global.slave_ddl_exec_mode=STRICT;
-connection master;
-create table t1(n int not null auto_increment primary key)ENGINE=TokuDB;
-insert into t1 values (NULL);
-drop table t1;
-create table t1 (word char(20) not null)ENGINE=TokuDB;
-load data infile 'LOAD_FILE' into table t1 ignore 1 lines;
-select count(*) from t1;
-count(*)
-69
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=TokuDB
-master-bin.000001 # Gtid # # BEGIN GTID #-#-#
-master-bin.000001 # Annotate_rows # # insert into t1 values (NULL)
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
-master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; create table t1 (word char(20) not null)ENGINE=TokuDB
-master-bin.000001 # Gtid # # BEGIN GTID #-#-#
-master-bin.000001 # Annotate_rows # # load data infile '../../std_data/words.dat' into table t1 ignore 1 lines
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=TokuDB
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=TokuDB
-master-bin.000001 # Gtid # # BEGIN GTID #-#-#
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Gtid # # BEGIN GTID #-#-#
-master-bin.000001 # Annotate_rows # # insert into t1 values (NULL)
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
-flush logs;
-create table t3 (a int)ENGINE=TokuDB;
-connection master;
-select * from t1 order by 1 asc;
-word
-Aarhus
-Aaron
-Aaron
-Ababa
-Ababa
-aback
-aback
-abaft
-abaft
-abandon
-abandon
-abandoned
-abandoned
-abandoning
-abandoning
-abandonment
-abandonment
-abandons
-abandons
-abase
-abased
-abasement
-abasements
-abases
-abash
-abashed
-abashes
-abashing
-abasing
-abate
-abated
-abatement
-abatements
-abater
-abates
-abating
-Abba
-abbe
-abbey
-abbeys
-abbot
-abbots
-Abbott
-abbreviate
-abbreviated
-abbreviates
-abbreviating
-abbreviation
-abbreviations
-Abby
-abdomen
-abdomens
-abdominal
-abduct
-abducted
-abduction
-abductions
-abductor
-abductors
-abducts
-Abe
-abed
-Abel
-Abelian
-Abelson
-Aberdeen
-Abernathy
-aberrant
-aberration
-connection slave;
-select * from t1 order by 1 asc;
-word
-Aarhus
-Aaron
-Aaron
-Ababa
-Ababa
-aback
-aback
-abaft
-abaft
-abandon
-abandon
-abandoned
-abandoned
-abandoning
-abandoning
-abandonment
-abandonment
-abandons
-abandons
-abase
-abased
-abasement
-abasements
-abases
-abash
-abashed
-abashes
-abashing
-abasing
-abate
-abated
-abatement
-abatements
-abater
-abates
-abating
-Abba
-abbe
-abbey
-abbeys
-abbot
-abbots
-Abbott
-abbreviate
-abbreviated
-abbreviates
-abbreviating
-abbreviation
-abbreviations
-Abby
-abdomen
-abdomens
-abdominal
-abduct
-abducted
-abduction
-abductions
-abductor
-abductors
-abducts
-Abe
-abed
-Abel
-Abelian
-Abelson
-Aberdeen
-Abernathy
-aberrant
-aberration
-flush logs;
-include/stop_slave.inc
-include/start_slave.inc
-connection master;
-create table t2 (n int)ENGINE=TokuDB;
-insert into t2 values (1);
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=TokuDB
-master-bin.000001 # Gtid # # BEGIN GTID #-#-#
-master-bin.000001 # Annotate_rows # # insert into t1 values (NULL)
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
-master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; create table t1 (word char(20) not null)ENGINE=TokuDB
-master-bin.000001 # Gtid # # BEGIN GTID #-#-#
-master-bin.000001 # Annotate_rows # # load data infile '../../std_data/words.dat' into table t1 ignore 1 lines
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
-master-bin.000001 # Rotate # # master-bin.000002;pos=POS
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000002 # Binlog_checkpoint # # master-bin.000002
-master-bin.000002 # Gtid # # GTID #-#-#
-master-bin.000002 # Query # # use `test`; create table t3 (a int)ENGINE=TokuDB
-master-bin.000002 # Gtid # # GTID #-#-#
-master-bin.000002 # Query # # use `test`; create table t2 (n int)ENGINE=TokuDB
-master-bin.000002 # Gtid # # BEGIN GTID #-#-#
-master-bin.000002 # Annotate_rows # # insert into t2 values (1)
-master-bin.000002 # Table_map # # table_id: # (test.t2)
-master-bin.000002 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-master-bin.000002 # Xid # # COMMIT /* XID */
-show binary logs;
-Log_name File_size
-master-bin.000001 #
-master-bin.000002 #
-connection slave;
-show binary logs;
-Log_name File_size
-slave-bin.000001 #
-slave-bin.000002 #
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-slave-bin.000001 # Gtid # # GTID #-#-#
-slave-bin.000001 # Query # # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=TokuDB
-slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
-slave-bin.000001 # Annotate_rows # # insert into t1 values (NULL)
-slave-bin.000001 # Table_map # # table_id: # (test.t1)
-slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-slave-bin.000001 # Xid # # COMMIT /* XID */
-slave-bin.000001 # Gtid # # GTID #-#-#
-slave-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
-slave-bin.000001 # Gtid # # GTID #-#-#
-slave-bin.000001 # Query # # use `test`; create table t1 (word char(20) not null)ENGINE=TokuDB
-slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
-slave-bin.000001 # Annotate_rows # # load data infile '../../std_data/words.dat' into table t1 ignore 1 lines
-slave-bin.000001 # Table_map # # table_id: # (test.t1)
-slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-slave-bin.000001 # Xid # # COMMIT /* XID */
-slave-bin.000001 # Gtid # # GTID #-#-#
-slave-bin.000001 # Query # # use `test`; create table t3 (a int)ENGINE=TokuDB
-slave-bin.000001 # Rotate # # slave-bin.000002;pos=POS
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-slave-bin.000002 # Binlog_checkpoint # # slave-bin.000002
-slave-bin.000002 # Gtid # # GTID #-#-#
-slave-bin.000002 # Query # # use `test`; create table t2 (n int)ENGINE=TokuDB
-slave-bin.000002 # Gtid # # BEGIN GTID #-#-#
-slave-bin.000002 # Annotate_rows # # insert into t2 values (1)
-slave-bin.000002 # Table_map # # table_id: # (test.t2)
-slave-bin.000002 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-slave-bin.000002 # Xid # # COMMIT /* XID */
-include/check_slave_is_running.inc
-show binlog events in 'slave-bin.000005' from 4;
-ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log
-connection master;
-DROP TABLE t1;
-DROP TABLE t2;
-DROP TABLE t3;
-include/rpl_reset.inc
-connection master;
-create table t1(a int auto_increment primary key, b int);
-insert into t1 values (NULL, 1);
-set insert_id=5;
-insert into t1 values (NULL, last_insert_id()), (NULL, last_insert_id());
-include/show_binlog_events.inc
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Gtid # # GTID #-#-#
-master-bin.000001 # Query # # use `test`; create table t1(a int auto_increment primary key, b int)
-master-bin.000001 # Gtid # # BEGIN GTID #-#-#
-master-bin.000001 # Annotate_rows # # insert into t1 values (NULL, 1)
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # COMMIT
-master-bin.000001 # Gtid # # BEGIN GTID #-#-#
-master-bin.000001 # Annotate_rows # # insert into t1 values (NULL, last_insert_id()), (NULL, last_insert_id())
-master-bin.000001 # Table_map # # table_id: # (test.t1)
-master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # COMMIT
-select * from t1;
-a b
-1 1
-5 1
-6 1
-drop table t1;
-connection slave;
-set @@global.slave_ddl_exec_mode=@save_slave_ddl_exec_mode;
-connection master;
-include/rpl_end.inc
diff --git a/storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb-master.opt b/storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb-master.opt
deleted file mode 100644
index 773ec62bef2..00000000000
--- a/storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb-master.opt
+++ /dev/null
@@ -1,2 +0,0 @@
---skip-external-locking
---default-storage-engine=MyISAM
diff --git a/storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb.test b/storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb.test
deleted file mode 100644
index 826eb5eab86..00000000000
--- a/storage/tokudb/mysql-test/rpl/t/rpl_row_log_tokudb.test
+++ /dev/null
@@ -1,14 +0,0 @@
-###################################
-# Wrapper for rpl_row_log.test #
-# Added wrapper so that MyISAM & #
-# Innodb and NDB could all use the#
-# Same test. NDB produced a diff #
-# bin-log #
-###################################
--- source include/have_binlog_format_row.inc
--- source include/have_tokudb.inc
--- source include/master-slave.inc
-let $engine_type=TokuDB;
--- source extra/rpl_tests/rpl_log.test
-
---source include/rpl_end.inc
diff --git a/storage/tokudb/mysql-test/tokudb/r/dir_per_db.result b/storage/tokudb/mysql-test/tokudb/r/dir_per_db.result
index 371f97406c8..30d4e4244fd 100644
--- a/storage/tokudb/mysql-test/tokudb/r/dir_per_db.result
+++ b/storage/tokudb/mysql-test/tokudb/r/dir_per_db.result
@@ -1,3 +1,4 @@
+SET @orig_tokudb_dir_per_db=@@global.tokudb_dir_per_db;
########
# tokudb_dir_per_db = 1
########
@@ -177,4 +178,11 @@ t1_status_id.tokudb
DROP TABLE t2;
## Looking for *.tokudb files in data_dir
## Looking for *.tokudb files in data_dir/test
-SET GLOBAL tokudb_dir_per_db=default;
+CREATE DATABASE `a::a@@`;
+CREATE TABLE `a::a@@`.`t1` (a INT) ENGINE=TOKUDB;
+CREATE DATABASE `!@#$%^&*()`;
+ALTER TABLE `a::a@@`.`t1` RENAME `!@#$%^&*()`.`t1`;
+DROP TABLE `!@#$%^&*()`.`t1`;
+DROP DATABASE `!@#$%^&*()`;
+DROP DATABASE `a::a@@`;
+SET GLOBAL tokudb_dir_per_db=@orig_tokudb_dir_per_db;
diff --git a/storage/tokudb/mysql-test/tokudb/t/dir_per_db.test b/storage/tokudb/mysql-test/tokudb/t/dir_per_db.test
index b638b706d87..64745cb049c 100644
--- a/storage/tokudb/mysql-test/tokudb/t/dir_per_db.test
+++ b/storage/tokudb/mysql-test/tokudb/t/dir_per_db.test
@@ -1,5 +1,7 @@
source include/have_tokudb.inc;
+SET @orig_tokudb_dir_per_db=@@global.tokudb_dir_per_db;
+
--let $DB= test
--let $DATADIR= `select @@datadir`
--let $i= 2
@@ -73,4 +75,17 @@ while ($i) {
--source dir_per_db_show_table_files.inc
}
-SET GLOBAL tokudb_dir_per_db=default;
+
+# test case for TDB-72 : Can not rename table in database with non alphanum
+# characters in its name.
+CREATE DATABASE `a::a@@`;
+CREATE TABLE `a::a@@`.`t1` (a INT) ENGINE=TOKUDB;
+CREATE DATABASE `!@#$%^&*()`;
+ALTER TABLE `a::a@@`.`t1` RENAME `!@#$%^&*()`.`t1`;
+
+DROP TABLE `!@#$%^&*()`.`t1`;
+DROP DATABASE `!@#$%^&*()`;
+DROP DATABASE `a::a@@`;
+
+# cleanup
+SET GLOBAL tokudb_dir_per_db=@orig_tokudb_dir_per_db;