diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2019-05-04 17:04:55 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2019-05-04 17:04:55 +0200 |
commit | 8cbb14ef5d180687f131bc44a4e8fc84083d033c (patch) | |
tree | 091f11e2d20f95656a7b12294782eb0488fd4fcc /storage | |
parent | 4345868382ca3525de5eb432302b6b9b957b47c1 (diff) | |
parent | b85aa20065504bdda4bc03c2bd7eb7de38865c5d (diff) | |
download | mariadb-git-8cbb14ef5d180687f131bc44a4e8fc84083d033c.tar.gz |
Merge branch '10.1' into 10.2
Diffstat (limited to 'storage')
27 files changed, 305 insertions, 160 deletions
diff --git a/storage/connect/filter.h b/storage/connect/filter.h index c6ab8fddd35..b0fea3d69e0 100644 --- a/storage/connect/filter.h +++ b/storage/connect/filter.h @@ -48,6 +48,7 @@ class DllExport FILTER : public XOBJECT { /* Filter description block */ PVAL &Val(int i) {return Test[i].Value;} bool &Conv(int i) {return Test[i].Conv;} void SetNext(PFIL filp) {Next = filp;} + bool MakeSelector(PGLOBAL g, PSTRG s); // Methods virtual void Reset(void); diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 859dc859a09..e0b2a4b938d 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -4730,8 +4730,24 @@ int ha_connect::start_stmt(THD *thd, thr_lock_type lock_type) break; } // endswitch mode - xmod= CheckMode(g, thd, newmode, &chk, &cras); - DBUG_RETURN((xmod == MODE_ERROR) ? HA_ERR_INTERNAL_ERROR : 0); + if (newmode == MODE_ANY) { + if (CloseTable(g)) { + // Make error a warning to avoid crash + push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); + rc = 0; + } // endif Close + + locked = 0; + xmod = MODE_ANY; // For info commands + DBUG_RETURN(rc); + } // endif MODE_ANY + + newmode = CheckMode(g, thd, newmode, &chk, &cras); + + if (newmode == MODE_ERROR) + DBUG_RETURN(HA_ERR_INTERNAL_ERROR); + + DBUG_RETURN(check_stmt(g, newmode, cras)); } // end of start_stmt /** @@ -4913,21 +4929,16 @@ int ha_connect::external_lock(THD *thd, int lock_type) // Make it a warning to avoid crash push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); rc= 0; - //my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); - //rc = HA_ERR_INTERNAL_ERROR; } // endif Close locked= 0; -// m_lock_type= lock_type; xmod= MODE_ANY; // For info commands DBUG_RETURN(rc); - } // endif MODE_ANY - else - if (check_privileges(thd, options, table->s->db.str)) { - strcpy(g->Message, "This operation requires the FILE privilege"); - htrc("%s\n", g->Message); - DBUG_RETURN(HA_ERR_INTERNAL_ERROR); - } // endif check_privileges + } else if (check_privileges(thd, options, table->s->db.str)) { + strcpy(g->Message, "This operation requires the FILE privilege"); + htrc("%s\n", g->Message); + DBUG_RETURN(HA_ERR_INTERNAL_ERROR); + } // endif check_privileges DBUG_ASSERT(table && table->s); @@ -4938,43 +4949,31 @@ int ha_connect::external_lock(THD *thd, int lock_type) if (newmode == MODE_ERROR) DBUG_RETURN(HA_ERR_INTERNAL_ERROR); - // If this is the start of a new query, cleanup the previous one + DBUG_RETURN(check_stmt(g, newmode, cras)); +} // end of external_lock + + +int ha_connect::check_stmt(PGLOBAL g, MODE newmode, bool cras) +{ + int rc = 0; + DBUG_ENTER("ha_connect::check_stmt"); + + // If this is the start of a new query, cleanup the previous one if (xp->CheckCleanup()) { tdbp= NULL; valid_info= false; - } // endif CheckCleanup - -#if 0 - if (xcheck) { - // This must occur after CheckCleanup - if (!g->Xchk) { - g->Xchk= new(g) XCHK; - ((PCHK)g->Xchk)->oldsep= GetBooleanOption("Sepindex", false); - ((PCHK)g->Xchk)->oldpix= GetIndexInfo(); - } // endif Xchk - - } else - g->Xchk= NULL; -#endif // 0 + } // endif CheckCleanup if (cras) g->Createas= 1; // To tell external tables of a multi-table command - if (trace(1)) { -#if 0 - htrc("xcheck=%d cras=%d\n", xcheck, cras); - - if (xcheck) - htrc("oldsep=%d oldpix=%p\n", - ((PCHK)g->Xchk)->oldsep, ((PCHK)g->Xchk)->oldpix); -#endif // 0 - htrc("Calling CntCheckDB db=%s cras=%d\n", GetDBName(NULL), cras); - } // endif trace + if (trace(1)) + htrc("Calling CntCheckDB db=%s cras=%d\n", GetDBName(NULL), cras); // Set or reset the good database environment if (CntCheckDB(g, this, GetDBName(NULL))) { - htrc("%p external_lock: %s\n", this, g->Message); - rc= HA_ERR_INTERNAL_ERROR; + htrc("%p check_stmt: %s\n", this, g->Message); + rc= HA_ERR_INTERNAL_ERROR; // This can NOT be called without open called first, but // the table can have been closed since then } else if (!tdbp || xp->CheckQuery(valid_query_id) || xmod != newmode) { @@ -4994,10 +4993,10 @@ int ha_connect::external_lock(THD *thd, int lock_type) } // endif tdbp if (trace(1)) - htrc("external_lock: rc=%d\n", rc); + htrc("check_stmt: rc=%d\n", rc); DBUG_RETURN(rc); -} // end of external_lock +} // end of check_stmt /** diff --git a/storage/connect/ha_connect.h b/storage/connect/ha_connect.h index 13c9aa4835b..de61f868038 100644 --- a/storage/connect/ha_connect.h +++ b/storage/connect/ha_connect.h @@ -511,7 +511,8 @@ private: protected: bool check_privileges(THD *thd, PTOS options, char *dbn, bool quick=false); MODE CheckMode(PGLOBAL g, THD *thd, MODE newmode, bool *chk, bool *cras); - char *GetDBfromName(const char *name); + int check_stmt(PGLOBAL g, MODE newmode, bool cras); + char *GetDBfromName(const char *name); // Members static ulong num; // Tracable handler number diff --git a/storage/connect/jmgoconn.cpp b/storage/connect/jmgoconn.cpp index bd1ddadd80d..c786e78a081 100644 --- a/storage/connect/jmgoconn.cpp +++ b/storage/connect/jmgoconn.cpp @@ -272,7 +272,7 @@ bool JMgoConn::MakeCursor(PGLOBAL g, PTDB tdbp, PCSZ options, if (MakeSelector(g, filp, s)) { strcpy(g->Message, "Failed making selector"); - return NULL; + return true; } else s->Append('}'); @@ -340,7 +340,7 @@ bool JMgoConn::MakeCursor(PGLOBAL g, PTDB tdbp, PCSZ options, if (MakeSelector(g, filp, s)) { strcpy(g->Message, "Failed making selector"); - return NULL; + return true; } // endif Selector tdbp->SetFilter(NULL); // Not needed anymore diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp index 29cbbb35765..4f6e2c81744 100644 --- a/storage/connect/tabdos.cpp +++ b/storage/connect/tabdos.cpp @@ -1,11 +1,11 @@ /************* TabDos C++ Program Source Code File (.CPP) **************/ /* PROGRAM NAME: TABDOS */ /* ------------- */ -/* Version 4.9.3 */ +/* Version 4.9.4 */ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 1998-2017 */ +/* (C) Copyright to the author Olivier BERTRAND 1998-2019 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -2492,8 +2492,10 @@ bool DOSCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check) } // endif's Value, Buf_Type // Allocate the buffer used in WriteColumn for numeric columns - if (!Buf && IsTypeNum(Buf_Type)) - Buf = (char*)PlugSubAlloc(g, NULL, MY_MAX(32, Long + Dcm + 1)); + if (!Buf && IsTypeNum(Buf_Type)) + Buf = (char*)PlugSubAlloc(g, NULL, MY_MAX(64, Long + 1)); + else // Text columns do not need additional buffer + Buf = (char*)Value->GetTo_Val(); // Because Colblk's have been made from a copy of the original TDB in // case of Update, we must reset them to point to the original one. @@ -2603,8 +2605,8 @@ void DOSCOL::ReadColumn(PGLOBAL g) /***********************************************************************/ void DOSCOL::WriteColumn(PGLOBAL g) { - char *p, *p2, fmt[32]; - int i, k, len, field; + char *p, fmt[32]; + int i, k, n, len, field; PTDBDOS tdbp = (PTDBDOS)To_Tdb; if (trace(2)) @@ -2679,8 +2681,8 @@ void DOSCOL::WriteColumn(PGLOBAL g) case TYPE_DOUBLE: case TYPE_DECIM: strcpy(fmt, (Ldz) ? "%0*.*lf" : "%*.*lf"); - sprintf(Buf, fmt, field + ((Nod && Dcm) ? 1 : 0), - Dcm, Value->GetFloatValue()); + len = field + ((Nod && Dcm) ? 1 : 0); + snprintf(Buf, len, fmt, len, Dcm, Value->GetFloatValue()); len = strlen(Buf); if (Nod && Dcm) @@ -2699,35 +2701,37 @@ void DOSCOL::WriteColumn(PGLOBAL g) throw 31; } // endswitch BufType - p2 = Buf; + n = strlen(Buf); } else // Standard CONNECT format - p2 = Value->ShowValue(Buf, field); + n = Value->ShowValue(Buf, field); if (trace(1)) - htrc("new length(%p)=%d\n", p2, strlen(p2)); + htrc("new length(%p)=%d\n", Buf, n); - if ((len = strlen(p2)) > field) { - sprintf(g->Message, MSG(VALUE_TOO_LONG), p2, Name, field); + if ((len = n) > field) { + char *p = Value->GetCharString(Buf); + + sprintf(g->Message, MSG(VALUE_TOO_LONG), p, Name, field); throw 31; } else if (Dsp) for (i = 0; i < len; i++) - if (p2[i] == '.') - p2[i] = Dsp; + if (Buf[i] == '.') + Buf[i] = Dsp; if (trace(2)) - htrc("buffer=%s\n", p2); + htrc("buffer=%s\n", Buf); /*******************************************************************/ /* Updating must be done only when not in checking pass. */ /*******************************************************************/ if (Status) { memset(p, ' ', field); - memcpy(p, p2, len); + memcpy(p, Buf, len); if (trace(2)) htrc(" col write: '%.*s'\n", len, p); - } // endif Use + } // endif Status } else // BIN compressed table /*******************************************************************/ @@ -2738,7 +2742,7 @@ void DOSCOL::WriteColumn(PGLOBAL g) sprintf(g->Message, MSG(BIN_F_TOO_LONG), Name, Value->GetSize(), Long); throw 31; - } // endif + } // endif } // end of WriteColumn diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp index 63fa2a63668..02720a3089a 100644 --- a/storage/connect/tabfmt.cpp +++ b/storage/connect/tabfmt.cpp @@ -1485,8 +1485,8 @@ void CSVCOL::ReadColumn(PGLOBAL g) /***********************************************************************/ void CSVCOL::WriteColumn(PGLOBAL g) { - char *p, buf[64]; - int flen; + char *p; + int n, flen; PTDBCSV tdbp = (PTDBCSV)To_Tdb; if (trace(2)) @@ -1508,13 +1508,14 @@ void CSVCOL::WriteColumn(PGLOBAL g) /*********************************************************************/ /* Get the string representation of the column value. */ /*********************************************************************/ - p = Value->ShowValue(buf); + p = Value->GetCharString(Buf); + n = strlen(p); if (trace(2)) - htrc("new length(%p)=%d\n", p, strlen(p)); + htrc("new length(%p)=%d\n", p, n); - if ((signed)strlen(p) > flen) { - sprintf(g->Message, MSG(BAD_FLD_LENGTH), Name, p, flen, + if (n > flen) { + sprintf(g->Message, MSG(BAD_FLD_LENGTH), Name, p, n, tdbp->RowNumber(g), tdbp->GetFile(g)); throw 34; } else if (Dsp) diff --git a/storage/connect/user_connect.cc b/storage/connect/user_connect.cc index a2a8faf9b38..d366e0222df 100644 --- a/storage/connect/user_connect.cc +++ b/storage/connect/user_connect.cc @@ -177,7 +177,8 @@ bool user_connect::CheckCleanup(bool force) g->Createas = 0; g->Alchecked = 0; g->Mrr = 0; - last_query_id= thdp->query_id; + g->More = 0; + last_query_id= thdp->query_id; if (trace(65) && !force) printf("=====> Begin new query %llu\n", last_query_id); diff --git a/storage/connect/value.cpp b/storage/connect/value.cpp index e159efaa989..d9330a68a15 100644 --- a/storage/connect/value.cpp +++ b/storage/connect/value.cpp @@ -1,7 +1,7 @@ /************* Value C++ Functions Source Code File (.CPP) *************/ -/* Name: VALUE.CPP Version 2.8 */ +/* Name: VALUE.CPP Version 2.9 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2001-2017 */ +/* (C) Copyright to the author Olivier BERTRAND 2001-2019 */ /* */ /* This file contains the VALUE and derived classes family functions. */ /* These classes contain values of different types. They are used so */ @@ -882,18 +882,16 @@ bool TYPVAL<TYPE>::GetBinValue(void *buf, int buflen, bool go) /* TYPVAL ShowValue: get string representation of a typed value. */ /***********************************************************************/ template <class TYPE> -char *TYPVAL<TYPE>::ShowValue(char *buf, int len) +int TYPVAL<TYPE>::ShowValue(char *buf, int len) { - sprintf(buf, Xfmt, len, Tval); - return buf; + return snprintf(buf, len + 1, Xfmt, len, Tval); } // end of ShowValue template <> -char *TYPVAL<double>::ShowValue(char *buf, int len) +int TYPVAL<double>::ShowValue(char *buf, int len) { - // TODO: use snprintf to avoid possible overflow - sprintf(buf, Xfmt, len, Prec, Tval); - return buf; + // TODO: use a more appropriate format to avoid possible truncation + return snprintf(buf, len + 1, Xfmt, len, Prec, Tval); } // end of ShowValue /***********************************************************************/ @@ -1588,10 +1586,17 @@ bool TYPVAL<PSZ>::GetBinValue(void *buf, int buflen, bool go) /***********************************************************************/ /* STRING ShowValue: get string representation of a char value. */ /***********************************************************************/ -char *TYPVAL<PSZ>::ShowValue(char *, int) - { - return Strp; - } // end of ShowValue +int TYPVAL<PSZ>::ShowValue(char *buf, int buflen) +{ + int len = (Null) ? 0 : strlen(Strp); + + if (buf && buf != Strp) { + memset(buf, ' ', buflen + 1); + memcpy(buf, Strp, MY_MIN(len, buflen)); + } // endif buf + + return len; +} // end of ShowValue /***********************************************************************/ /* STRING GetCharString: get string representation of a char value. */ @@ -1800,10 +1805,9 @@ void DECVAL::Reset(void) /***********************************************************************/ /* DECIMAL ShowValue: get string representation right justified. */ /***********************************************************************/ -char *DECVAL::ShowValue(char *buf, int len) +int DECVAL::ShowValue(char *buf, int len) { - sprintf(buf, Xfmt, len, Strp); - return buf; + return snprintf(buf, len + 1, Xfmt, len, Strp); } // end of ShowValue /***********************************************************************/ @@ -1868,14 +1872,13 @@ int DECVAL::CompareValue(PVAL vp) BINVAL::BINVAL(PGLOBAL g, void *p, int cl, int n) : VALUE(TYPE_BIN) { assert(g); -//Len = n; - Len = (g) ? n : (p) ? strlen((char*)p) : 0; + Len = n; Clen = cl; Binp = PlugSubAlloc(g, NULL, Clen + 1); memset(Binp, 0, Clen + 1); if (p) - memcpy(Binp, p, Len); + memcpy(Binp, p, MY_MIN(Len,Clen)); Chrp = NULL; } // end of BINVAL constructor @@ -2264,14 +2267,12 @@ bool BINVAL::GetBinValue(void *buf, int buflen, bool go) /***********************************************************************/ /* BINVAL ShowValue: get string representation of a binary value. */ /***********************************************************************/ -char *BINVAL::ShowValue(char *buf, int len) - { - //int n = MY_MIN(Len, len / 2); - - //sprintf(buf, GetXfmt(), n, Binp); - //return buf; - return (char*)Binp; - } // end of ShowValue +int BINVAL::ShowValue(char *buf, int len) +{ + memset(buf, 0, len + 1); + memcpy(buf, Binp, MY_MIN(len, Len)); + return Len; +} // end of ShowValue /***********************************************************************/ /* BINVAL GetCharString: get string representation of a binary value. */ @@ -2749,43 +2750,33 @@ char *DTVAL::GetCharString(char *p) /***********************************************************************/ /* DTVAL ShowValue: get string representation of a date value. */ /***********************************************************************/ -char *DTVAL::ShowValue(char *buf, int len) - { - if (Pdtp) { - char *p; +int DTVAL::ShowValue(char *buf, int len) +{ + int rv = 0; + if (Pdtp) { if (!Null) { - size_t m, n = 0; + size_t n = 0, m = len + 1; struct tm tm, *ptm = GetGmTime(&tm); - - - - if (Len < len) { - p = buf; - m = len; - } else { - p = Sdate; - m = Len + 1; - } // endif Len if (ptm) - n = strftime(p, m, Pdtp->OutFmt, ptm); + n = strftime(buf, m, Pdtp->OutFmt, ptm); if (!n) { - *p = '\0'; - strncat(p, "Error", m); - } // endif n + *buf = '\0'; + strncat(buf, "Error", m); + rv = 5; + } else + rv = (int)n; - } else { - p = buf; - *p = '\0'; // DEFAULT VALUE ??? - } // endif Null + } else + *buf = '\0'; // DEFAULT VALUE ??? - return p; } else - return TYPVAL<int>::ShowValue(buf, len); + rv = TYPVAL<int>::ShowValue(buf, len); - } // end of ShowValue + return rv; +} // end of ShowValue #if 0 // Not used by CONNECT /***********************************************************************/ diff --git a/storage/connect/value.h b/storage/connect/value.h index 6613e25100a..4f7d9a440fa 100644 --- a/storage/connect/value.h +++ b/storage/connect/value.h @@ -1,7 +1,7 @@ /**************** Value H Declares Source Code File (.H) ***************/ -/* Name: VALUE.H Version 2.3 */ +/* Name: VALUE.H Version 2.4 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2001-2017 */ +/* (C) Copyright to the author Olivier BERTRAND 2001-2019 */ /* */ /* This file contains the VALUE and derived classes declares. */ /***********************************************************************/ @@ -117,7 +117,7 @@ class DllExport VALUE : public BLOCK { virtual void SetValue_pvblk(PVBLK blk, int n) = 0; virtual void SetBinValue(void *p) = 0; virtual bool GetBinValue(void *buf, int buflen, bool go) = 0; - virtual char *ShowValue(char *buf, int len = 0) = 0; + virtual int ShowValue(char *buf, int len) = 0; virtual char *GetCharString(char *p) = 0; virtual bool IsEqual(PVAL vp, bool chktype) = 0; virtual bool Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op); @@ -229,7 +229,7 @@ class DllExport TYPVAL : public VALUE { virtual void SetValue_pvblk(PVBLK blk, int n); virtual void SetBinValue(void *p); virtual bool GetBinValue(void *buf, int buflen, bool go); - virtual char *ShowValue(char *buf, int); + virtual int ShowValue(char *buf, int len); virtual char *GetCharString(char *p); virtual bool IsEqual(PVAL vp, bool chktype); virtual bool Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op); @@ -302,7 +302,7 @@ class DllExport TYPVAL<PSZ>: public VALUE { virtual void SetBinValue(void *p); virtual int CompareValue(PVAL vp); virtual bool GetBinValue(void *buf, int buflen, bool go); - virtual char *ShowValue(char *buf, int); + virtual int ShowValue(char *buf, int len); virtual char *GetCharString(char *p); virtual bool IsEqual(PVAL vp, bool chktype); virtual bool Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op); @@ -334,7 +334,7 @@ class DllExport DECVAL: public TYPVAL<PSZ> { // Methods virtual bool GetBinValue(void *buf, int buflen, bool go); - virtual char *ShowValue(char *buf, int); + virtual int ShowValue(char *buf, int len); virtual bool IsEqual(PVAL vp, bool chktype); virtual int CompareValue(PVAL vp); @@ -387,7 +387,7 @@ class DllExport BINVAL: public VALUE { virtual void SetBinValue(void *p); virtual bool GetBinValue(void *buf, int buflen, bool go); virtual int CompareValue(PVAL) {assert(false); return 0;} - virtual char *ShowValue(char *buf, int); + virtual int ShowValue(char *buf, int len); virtual char *GetCharString(char *p); virtual bool IsEqual(PVAL vp, bool chktype); virtual bool FormatValue(PVAL vp, PCSZ fmt); @@ -415,7 +415,7 @@ class DllExport DTVAL : public TYPVAL<int> { virtual void SetValue_psz(PCSZ s); virtual void SetValue_pvblk(PVBLK blk, int n); virtual char *GetCharString(char *p); - virtual char *ShowValue(char *buf, int); + virtual int ShowValue(char *buf, int len); virtual bool FormatValue(PVAL vp, PCSZ fmt); bool SetFormat(PGLOBAL g, PCSZ fmt, int len, int year = 0); bool SetFormat(PGLOBAL g, PVAL valp); diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index d6d7845b2c3..6dd3c9c930f 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2009, 2018, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2009, 2019, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2015, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -3109,6 +3109,8 @@ dict_stats_update_for_index( if (dict_stats_persistent_storage_check(false)) { dict_table_stats_lock(index->table, RW_X_LATCH); dict_stats_analyze_index(index); + index->table->stat_sum_of_other_index_sizes + += index->stat_index_size; dict_table_stats_unlock(index->table, RW_X_LATCH); dict_stats_save(index->table, &index->id); DBUG_VOID_RETURN; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 005c0fd5adf..f470ac3ca4c 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2005, 2018, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2005, 2019, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2013, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -251,6 +251,23 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx } } + /** Share context between partitions. + @param[in] ctx context from another partition of the table */ + void set_shared_data(const inplace_alter_handler_ctx& ctx) + { + if (add_autoinc != ULINT_UNDEFINED) { + const ha_innobase_inplace_ctx& ha_ctx = + static_cast<const ha_innobase_inplace_ctx&> + (ctx); + /* When adding an AUTO_INCREMENT column to a + partitioned InnoDB table, we must share the + sequence for all partitions. */ + ut_ad(ha_ctx.add_autoinc == add_autoinc); + ut_ad(ha_ctx.sequence.last()); + sequence = ha_ctx.sequence; + } + } + private: // Disable copying ha_innobase_inplace_ctx(const ha_innobase_inplace_ctx&); @@ -4312,7 +4329,7 @@ prepare_inplace_alter_table_dict( (ha_alter_info->handler_ctx); DBUG_ASSERT((ctx->add_autoinc != ULINT_UNDEFINED) - == (ctx->sequence.m_max_value > 0)); + == (ctx->sequence.max_value() > 0)); DBUG_ASSERT(!ctx->num_to_drop_index == !ctx->drop_index); DBUG_ASSERT(!ctx->num_to_drop_fk == !ctx->drop_fk); DBUG_ASSERT(!add_fts_doc_id || add_fts_doc_id_idx); diff --git a/storage/innobase/include/handler0alter.h b/storage/innobase/include/handler0alter.h index 1c690839449..b20c59ebf74 100644 --- a/storage/innobase/include/handler0alter.h +++ b/storage/innobase/include/handler0alter.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2019, 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 @@ -91,9 +92,13 @@ struct ib_sequence_t { return(m_next_value); } - /** Maximum calumn value if adding an AUTOINC column else 0. Once - we reach the end of the sequence it will be set to ~0. */ - const ulonglong m_max_value; + /** @return maximum column value + @retval 0 if not adding AUTO_INCREMENT column */ + ulonglong max_value() const { return m_max_value; } + +private: + /** Maximum value if adding an AUTO_INCREMENT column, else 0 */ + ulonglong m_max_value; /** Value of auto_increment_increment */ ulong m_increment; diff --git a/storage/tokudb/.clang-format b/storage/tokudb/.clang-format new file mode 100644 index 00000000000..2ccc4b3fb24 --- /dev/null +++ b/storage/tokudb/.clang-format @@ -0,0 +1,40 @@ +# .clang-format file for Percona TokuDB +# Minimum required version of clang-format is 5.0.1. Earlier versions will work +# but may need removal of some parameters. +Language: Cpp +BasedOnStyle: Google + +# The following parameters are default for Google style, +# but as they are important for our project they +# are set explicitly here +AlignAfterOpenBracket: Align +BreakBeforeBinaryOperators: None +ColumnLimit: 80 +PointerAlignment: Left +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +UseTab: Never + +# Non-default parameters +NamespaceIndentation: All +IndentWidth: 4 +TabWidth: 4 +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +BinPackParameters: false +BinPackArguments: false +ExperimentalAutoDetectBinPacking: false +AllowAllParametersOfDeclarationOnNextLine: false +# not supported in 5.0.1 +#AlignConsecutiveAssignments: yes +#AlignConsecutiveDeclarations: yes +BreakStringLiterals: false +ReflowComments: true diff --git a/storage/tokudb/ha_tokudb.cc b/storage/tokudb/ha_tokudb.cc index 60e32f92285..5ddc739c5ad 100644 --- a/storage/tokudb/ha_tokudb.cc +++ b/storage/tokudb/ha_tokudb.cc @@ -3368,15 +3368,17 @@ void ha_tokudb::start_bulk_insert(ha_rows rows) { int ha_tokudb::bulk_insert_poll(void* extra, float progress) { LOADER_CONTEXT context = (LOADER_CONTEXT)extra; if (thd_killed(context->thd)) { - sprintf(context->write_status_msg, - "The process has been killed, aborting bulk load."); + snprintf(context->write_status_msg, + sizeof(context->write_status_msg), + "The process has been killed, aborting bulk load."); return ER_ABORTING_CONNECTION; } float percentage = progress * 100; - sprintf(context->write_status_msg, - "Loading of data t %s about %.1f%% done", - context->ha->share->full_table_name(), - percentage); + snprintf(context->write_status_msg, + sizeof(context->write_status_msg), + "Loading of data t %s about %.1f%% done", + context->ha->share->full_table_name(), + percentage); thd_proc_info(context->thd, context->write_status_msg); #ifdef HA_TOKUDB_HAS_THD_PROGRESS thd_progress_report(context->thd, (unsigned long long)percentage, 100); @@ -8534,15 +8536,17 @@ cleanup: int ha_tokudb::tokudb_add_index_poll(void* extra, float progress) { LOADER_CONTEXT context = (LOADER_CONTEXT)extra; if (thd_killed(context->thd)) { - sprintf(context->write_status_msg, - "The process has been killed, aborting add index."); + snprintf(context->write_status_msg, + sizeof(context->write_status_msg), + "The process has been killed, aborting add index."); return ER_ABORTING_CONNECTION; } float percentage = progress * 100; - sprintf(context->write_status_msg, - "Adding of indexes to %s about %.1f%% done", - context->ha->share->full_table_name(), - percentage); + snprintf(context->write_status_msg, + sizeof(context->write_status_msg), + "Adding of indexes to %s about %.1f%% done", + context->ha->share->full_table_name(), + percentage); thd_proc_info(context->thd, context->write_status_msg); #ifdef HA_TOKUDB_HAS_THD_PROGRESS thd_progress_report(context->thd, (unsigned long long)percentage, 100); diff --git a/storage/tokudb/ha_tokudb.h b/storage/tokudb/ha_tokudb.h index e322c3de18e..8012c051720 100644 --- a/storage/tokudb/ha_tokudb.h +++ b/storage/tokudb/ha_tokudb.h @@ -41,7 +41,7 @@ class ha_tokudb; typedef struct loader_context { THD* thd; - char write_status_msg[200]; + char write_status_msg[1024]; ha_tokudb* ha; } *LOADER_CONTEXT; diff --git a/storage/tokudb/ha_tokudb_mrr_mysql.cc b/storage/tokudb/ha_tokudb_mrr_mysql.cc index 84b64009ef2..480ae23802b 100644 --- a/storage/tokudb/ha_tokudb_mrr_mysql.cc +++ b/storage/tokudb/ha_tokudb_mrr_mysql.cc @@ -31,6 +31,7 @@ int ha_tokudb::multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, uint n_ranges, uint mode, HANDLER_BUFFER *buf) { + ds_mrr.init(this, table); return ds_mrr.dsmrr_init(this, seq, seq_init_param, n_ranges, mode, buf); } diff --git a/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_mixed_dml.result b/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_mixed_dml.result index 65057791b48..5f41fd328c9 100644 --- a/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_mixed_dml.result +++ b/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_mixed_dml.result @@ -682,6 +682,8 @@ DROP TRIGGER tr1; GRANT EVENT ON *.* TO 'root'@'localhost'; INSERT INTO t1 VALUES(1, 'test1'); CREATE EVENT e1 ON SCHEDULE EVERY '1' SECOND COMMENT 'e_second_comment' DO DELETE FROM t1; +Warnings: +Warning 1105 Event scheduler is switched off, use SET GLOBAL event_scheduler=ON to enable it. SHOW EVENTS; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation test_rpl e1 root@localhost SYSTEM RECURRING NULL 1 # # NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/PS-5158.result b/storage/tokudb/mysql-test/tokudb_bugs/r/PS-5158.result new file mode 100644 index 00000000000..3dfbb95aed9 --- /dev/null +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/PS-5158.result @@ -0,0 +1,6 @@ +CREATE DATABASE `new..............................................end`; +USE `new..............................................end`; +CREATE TABLE t1(a INT KEY,b INT)ENGINE=TokuDB; +INSERT INTO t1 VALUES(1,11),(2,12),(3,13),(4,14),(5,15); +USE test; +DROP DATABASE `new..............................................end`; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/PS-5163.result b/storage/tokudb/mysql-test/tokudb_bugs/r/PS-5163.result new file mode 100644 index 00000000000..27e19150945 --- /dev/null +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/PS-5163.result @@ -0,0 +1,5 @@ +CREATE TABLE t1(c1 INT default 0,c2 INT,c3 CHAR(10),c4 CHAR(10),c5 CHAR(10),PRIMARY KEY(c1),INDEX(c3,c4(1),c5(1)),INDEX(c2)) ENGINE=TokuDB; +INSERT INTO t1 VALUES(),(),(),(),(); +ERROR 23000: Duplicate entry '0' for key 'PRIMARY' +UPDATE t1 SET c1=1 WHERE c1=1 OR c2=1; +DROP TABLE t1; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/PS-5158-master.opt b/storage/tokudb/mysql-test/tokudb_bugs/t/PS-5158-master.opt new file mode 100644 index 00000000000..eb850c4bd78 --- /dev/null +++ b/storage/tokudb/mysql-test/tokudb_bugs/t/PS-5158-master.opt @@ -0,0 +1,2 @@ +--loose-tokudb_dir_per_db=ON + diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/PS-5158.test b/storage/tokudb/mysql-test/tokudb_bugs/t/PS-5158.test new file mode 100644 index 00000000000..e0235e7cebd --- /dev/null +++ b/storage/tokudb/mysql-test/tokudb_bugs/t/PS-5158.test @@ -0,0 +1,27 @@ +# Test for PS-5163 : [PS8QA] handle_fatal_signal (sig=11) in DsMrr_impl::dsmrr_init +# and PS-4828 : Inserting data into TokuDB database with name that contains non-alphanumerical characters can lead to the ZN9ha_tokudb16bulk_insert_pollEPvf assertion +# +# The cause is a buffer overrun in LOADER_CONTEXT where the char buffer used for +# maintaining the proc info string was too small and no validation or prevention +# was being done to ensure the string stayed within the limits of the buffer. +# Normally this would have been difficult to hit, but, now with the combination +# of tokudb_dir_per_db=ON and the expansion of the database name from latin1 +# (or whatever) to the fscs encoding the space required for a max length +# db.table name could be quite larger than the buffer was originally sized. + +--source include/have_tokudb.inc + +if (`SELECT @@tokudb_dir_per_db != 1`) { + skip Requires tokudb_dir_per_db=1; +} + +CREATE DATABASE `new..............................................end`; +USE `new..............................................end`; +CREATE TABLE t1(a INT KEY,b INT)ENGINE=TokuDB; + +# +# TokuDB bulk_insert_poll would crash here +# +INSERT INTO t1 VALUES(1,11),(2,12),(3,13),(4,14),(5,15); +USE test; +DROP DATABASE `new..............................................end`; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/PS-5163.test b/storage/tokudb/mysql-test/tokudb_bugs/t/PS-5163.test new file mode 100644 index 00000000000..d370bab6517 --- /dev/null +++ b/storage/tokudb/mysql-test/tokudb_bugs/t/PS-5163.test @@ -0,0 +1,11 @@ +--source include/have_tokudb.inc + +CREATE TABLE t1(c1 INT default 0,c2 INT,c3 CHAR(10),c4 CHAR(10),c5 CHAR(10),PRIMARY KEY(c1),INDEX(c3,c4(1),c5(1)),INDEX(c2)) ENGINE=TokuDB; +--error ER_DUP_ENTRY +INSERT INTO t1 VALUES(),(),(),(),(); + +# 8.0 asserts here down in data dictionary because ha_tokudb::ds_mrr did not +# properly call ds_mrr.init(this, table) +UPDATE t1 SET c1=1 WHERE c1=1 OR c2=1; + +DROP TABLE t1; diff --git a/storage/xtradb/dict/dict0stats.cc b/storage/xtradb/dict/dict0stats.cc index c1463e98ce0..06364689173 100644 --- a/storage/xtradb/dict/dict0stats.cc +++ b/storage/xtradb/dict/dict0stats.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2009, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2009, 2019, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2015, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -3207,6 +3207,8 @@ dict_stats_update_for_index( if (dict_stats_persistent_storage_check(false)) { dict_table_stats_lock(index->table, RW_X_LATCH); dict_stats_analyze_index(index); + index->table->stat_sum_of_other_index_sizes + += index->stat_index_size; dict_table_stats_unlock(index->table, RW_X_LATCH); dict_stats_save(index->table, &index->id); DBUG_VOID_RETURN; @@ -4006,7 +4008,6 @@ dict_stats_save_defrag_stats( { dberr_t ret; - if (index->is_readable()) { } else { return (dict_stats_report_error(index->table, true)); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 0b368f0cca4..a9fb00c9cef 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -19076,8 +19076,10 @@ innodb_track_changed_pages_validate( return 0; } - if (intbuf == srv_track_changed_pages) + if (intbuf == srv_track_changed_pages) { // == 0 + *reinterpret_cast<ulong*>(save) = srv_track_changed_pages; return 0; + } return 1; } diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index 638288cdb3c..b67ef728c2e 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2005, 2018, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2005, 2019, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2017, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -2181,6 +2181,23 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx @return whether the table will be rebuilt */ bool need_rebuild () const { return(old_table != new_table); } + /** Share context between partitions. + @param[in] ctx context from another partition of the table */ + void set_shared_data(const inplace_alter_handler_ctx& ctx) + { + if (add_autoinc != ULINT_UNDEFINED) { + const ha_innobase_inplace_ctx& ha_ctx = + static_cast<const ha_innobase_inplace_ctx&> + (ctx); + /* When adding an AUTO_INCREMENT column to a + partitioned InnoDB table, we must share the + sequence for all partitions. */ + ut_ad(ha_ctx.add_autoinc == add_autoinc); + ut_ad(ha_ctx.sequence.last()); + sequence = ha_ctx.sequence; + } + } + private: // Disable copying ha_innobase_inplace_ctx(const ha_innobase_inplace_ctx&); @@ -2727,7 +2744,7 @@ prepare_inplace_alter_table_dict( (ha_alter_info->handler_ctx); DBUG_ASSERT((ctx->add_autoinc != ULINT_UNDEFINED) - == (ctx->sequence.m_max_value > 0)); + == (ctx->sequence.max_value() > 0)); DBUG_ASSERT(!ctx->num_to_drop_index == !ctx->drop_index); DBUG_ASSERT(!ctx->num_to_drop_fk == !ctx->drop_fk); DBUG_ASSERT(!add_fts_doc_id || add_fts_doc_id_idx); diff --git a/storage/xtradb/include/handler0alter.h b/storage/xtradb/include/handler0alter.h index 3dd6c99eb6d..63379ad9371 100644 --- a/storage/xtradb/include/handler0alter.h +++ b/storage/xtradb/include/handler0alter.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2019, 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 @@ -96,9 +97,13 @@ struct ib_sequence_t { return(m_next_value); } - /** Maximum calumn value if adding an AUTOINC column else 0. Once - we reach the end of the sequence it will be set to ~0. */ - const ulonglong m_max_value; + /** @return maximum column value + @retval 0 if not adding AUTO_INCREMENT column */ + ulonglong max_value() const { return m_max_value; } + +private: + /** Maximum value if adding an AUTO_INCREMENT column, else 0 */ + ulonglong m_max_value; /** Value of auto_increment_increment */ ulong m_increment; diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index c35ec40e381..93e91083144 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -45,10 +45,10 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_MAJOR 5 #define INNODB_VERSION_MINOR 6 -#define INNODB_VERSION_BUGFIX 42 +#define INNODB_VERSION_BUGFIX 43 #ifndef PERCONA_INNODB_VERSION -#define PERCONA_INNODB_VERSION 84.2 +#define PERCONA_INNODB_VERSION 84.3 #endif /* Enable UNIV_LOG_ARCHIVE in XtraDB */ |