diff options
author | Olivier Bertrand <bertrandop@gmail.com> | 2014-04-27 19:18:20 +0200 |
---|---|---|
committer | Olivier Bertrand <bertrandop@gmail.com> | 2014-04-27 19:18:20 +0200 |
commit | f3af6da9765a4541d63de91e8a848d3c3116e957 (patch) | |
tree | 7d725fe7e7ac037890850614ae59c331769aa0aa | |
parent | 24369d217578bfc8140d0617169b6ad527e61e78 (diff) | |
download | mariadb-git-f3af6da9765a4541d63de91e8a848d3c3116e957.tar.gz |
- Enable MYSQL tables to USE result instead of STORE result.
See the issue reported in MDEV-6142.
modified:
storage/connect/myconn.cpp
storage/connect/myconn.h
storage/connect/tabmysql.cpp
storage/connect/tabmysql.h
-rw-r--r-- | storage/connect/myconn.cpp | 71 | ||||
-rw-r--r-- | storage/connect/myconn.h | 1 | ||||
-rw-r--r-- | storage/connect/tabmysql.cpp | 51 | ||||
-rw-r--r-- | storage/connect/tabmysql.h | 5 |
4 files changed, 100 insertions, 28 deletions
diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp index 2e563dbaf1e..8700a24ac96 100644 --- a/storage/connect/myconn.cpp +++ b/storage/connect/myconn.cpp @@ -31,6 +31,10 @@ /* */ /************************************************************************/ #include "my_global.h" +#if !defined(MYSQL_PREPARED_STATEMENTS) +#include "my_sys.h" +#include "mysqld_error.h" +#endif // !MYSQL_PREPARED_STATEMENTS #if defined(WIN32) //#include <windows.h> #else // !WIN32 @@ -59,6 +63,59 @@ uint GetDefaultPort(void) return mysqld_port; } // end of GetDefaultPort +#if !defined(MYSQL_PREPARED_STATEMENTS) +/************************************************************************** + Alloc struct for use with unbuffered reads. Data is fetched by domand + when calling to mysql_fetch_row. + mysql_data_seek is a noop. + + No other queries may be specified with the same MYSQL handle. + There shouldn't be much processing per row because mysql server shouldn't + have to wait for the client (and will not wait more than 30 sec/packet). + NOTE: copied from client.c cli_use_result +**************************************************************************/ +static MYSQL_RES *connect_use_result(MYSQL *mysql) +{ + MYSQL_RES *result; + DBUG_ENTER("connect_use_result"); + + if (!mysql->fields) + DBUG_RETURN(NULL); + + if (mysql->status != MYSQL_STATUS_GET_RESULT) { + my_message(ER_UNKNOWN_ERROR, "Command out of sync", MYF(0)); + DBUG_RETURN(NULL); + } // endif status + + if (!(result = (MYSQL_RES*) my_malloc(sizeof(*result) + + sizeof(ulong) * mysql->field_count, + MYF(MY_WME | MY_ZEROFILL)))) + DBUG_RETURN(NULL); + + result->lengths = (ulong*)(result+1); + result->methods = mysql->methods; + + /* Ptrs: to one row */ + if (!(result->row = (MYSQL_ROW)my_malloc(sizeof(result->row[0]) * + (mysql->field_count+1), MYF(MY_WME)))) { + my_free(result); + DBUG_RETURN(NULL); + } // endif row + + result->fields = mysql->fields; + result->field_alloc = mysql->field_alloc; + result->field_count = mysql->field_count; + result->current_field = 0; + result->handle = mysql; + result->current_row = 0; + mysql->fields = 0; /* fields is now in result */ + clear_alloc_root(&mysql->field_alloc); + mysql->status = MYSQL_STATUS_USE_RESULT; + mysql->unbuffered_fetch_owner = &result->unbuffered_fetch_cancelled; + DBUG_RETURN(result); /* Data is ready to be fetched */ +} // end of connect_use_result +#endif // !MYSQL_PREPARED_STATEMENTS + /************************************************************************/ /* MyColumns: constructs the result blocks containing all columns */ /* of a MySQL table or view. */ @@ -339,6 +396,7 @@ MYSQLC::MYSQLC(void) m_Row = NULL; m_Fields = -1; N = 0; + m_Use = false; } // end of MYSQLC constructor /***********************************************************************/ @@ -600,7 +658,16 @@ int MYSQLC::ExecSQL(PGLOBAL g, const char *query, int *w) rc = RC_FX; //} else if (mysql_field_count(m_DB) > 0) { } else if (m_DB->field_count > 0) { - if (!(m_Res = mysql_store_result(m_DB))) { + if (m_Use) +#if defined(MYSQL_PREPARED_STATEMENTS) + m_Res = mysql_use_result(m_DB); +#else // !MYSQL_PREPARED_STATEMENTS) + m_Res = connect_use_result(m_DB); +#endif // !MYSQL_PREPARED_STATEMENTS + else + m_Res = mysql_store_result(m_DB); + + if (!m_Res) { char *msg = (char*)PlugSubAlloc(g, NULL, 512 + strlen(query)); sprintf(msg, "mysql_store_result failed: %s", mysql_error(m_DB)); @@ -609,7 +676,7 @@ int MYSQLC::ExecSQL(PGLOBAL g, const char *query, int *w) rc = RC_FX; } else { m_Fields = mysql_num_fields(m_Res); - m_Rows = (int)mysql_num_rows(m_Res); + m_Rows = (!m_Use) ? (int)mysql_num_rows(m_Res) : 0; } // endif m_Res } else { diff --git a/storage/connect/myconn.h b/storage/connect/myconn.h index 5bfa58ffb0c..7e892eece34 100644 --- a/storage/connect/myconn.h +++ b/storage/connect/myconn.h @@ -96,5 +96,6 @@ class DllItem MYSQLC { int N; int m_Fields; // The number of result fields int m_Afrw; // The number of affected rows + bool m_Use; // Use or store result set }; // end of class MYSQLC diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp index a57c7b21c94..dea6978f73e 100644 --- a/storage/connect/tabmysql.cpp +++ b/storage/connect/tabmysql.cpp @@ -84,10 +84,11 @@ MYSQLDEF::MYSQLDEF(void) Username = NULL; Password = NULL; Portnumber = 0; - Isview = FALSE; - Bind = FALSE; - Delayed = FALSE; - Xsrc = FALSE; + Isview = false; + Bind = false; + Delayed = false; + Xsrc = false; + Huge = false; } // end of MYSQLDEF constructor /***********************************************************************/ @@ -329,7 +330,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) } else { // MYSQL access from a PROXY table Database = GetStringCatInfo(g, "Database", "*"); - Isview = GetBoolCatInfo("View", FALSE); + Isview = GetBoolCatInfo("View", false); // We must get other connection parms from the calling table Remove_tshp(Cat); @@ -363,7 +364,8 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) // Specific for command executing tables Xsrc = GetBoolCatInfo("Execsrc", false); Mxr = GetIntCatInfo("Maxerr", 0); - return FALSE; + Huge = GetBoolCatInfo("Huge", false); + return false; } // end of DefineAM /***********************************************************************/ @@ -401,6 +403,7 @@ TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp) Isview = tdp->Isview; Prep = tdp->Bind; Delayed = tdp->Delayed; + Myc.m_Use = tdp->Huge; } else { Host = NULL; Database = NULL; @@ -412,15 +415,15 @@ TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp) Qrystr = NULL; Quoted = 0; Port = 0; - Isview = FALSE; - Prep = FALSE; - Delayed = FALSE; + Isview = false; + Prep = false; + Delayed = false; } // endif tdp Bind = NULL; Query = NULL; Qbuf = NULL; - Fetched = FALSE; + Fetched = false; m_Rc = RC_FX; AftRows = 0; N = -1; @@ -555,17 +558,17 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g) char *colist, *valist = NULL; char *tk = "`"; int len = 0, qlen = 0; - bool b = FALSE; + bool b = false; PCOL colp; if (Query) - return FALSE; // already done + return false; // already done for (colp = Columns; colp; colp = colp->GetNext()) if (!colp->IsSpecial()) { // if (colp->IsSpecial()) { // strcpy(g->Message, MSG(NO_SPEC_COL)); -// return TRUE; +// return true; // } else { len += (strlen(colp->GetName()) + 4); ((PMYCOL)colp)->Rank = Nparm++; @@ -581,7 +584,7 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g) #else // !MYSQL_PREPARED_STATEMENTS strcpy(g->Message, "Prepared statements not used (not supported)"); PushWarning(g, this); - Prep = FALSE; + Prep = false; #endif // !MYSQL_PREPARED_STATEMENTS } // endif Prep @@ -590,7 +593,7 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g) strcat(colist, ", "); if (Prep) strcat(valist, ","); } else - b = TRUE; + b = true; strcat(strcat(strcat(colist, tk), colp->GetName()), tk); @@ -628,7 +631,7 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g) Qbuf = (char *)PlugSubAlloc(g, NULL, qlen); } // endelse Prep - return FALSE; + return false; } // end of MakeInsert /***********************************************************************/ @@ -906,9 +909,9 @@ bool TDBMYSQL::SetColumnRanks(PGLOBAL g) { for (PCOL colp = Columns; colp; colp = colp->GetNext()) if (((PMYCOL)colp)->FindRank(g)) - return TRUE; + return true; - return FALSE; + return false; } // end of SetColumnRanks /***********************************************************************/ @@ -1233,7 +1236,7 @@ bool MYSQLCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check) { if (!(To_Val = value)) { sprintf(g->Message, MSG(VALUE_ERROR), Name); - return TRUE; + return true; } else if (Buf_Type == value->GetType()) { // Values are of the (good) column type if (Buf_Type == TYPE_DATE) { @@ -1253,12 +1256,12 @@ bool MYSQLCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check) if (check) { sprintf(g->Message, MSG(TYPE_VALUE_ERR), Name, GetTypeName(Buf_Type), GetTypeName(value->GetType())); - return TRUE; + return true; } // endif check newval: if (InitValue(g)) // Allocate the matching value block - return TRUE; + return true; } // endif's Value, Buf_Type @@ -1269,7 +1272,7 @@ bool MYSQLCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check) // Set the Column Status = (ok) ? BUF_EMPTY : BUF_NO; - return FALSE; + return false; } // end of SetBuffer /***********************************************************************/ @@ -1317,7 +1320,7 @@ void MYSQLCOL::ReadColumn(PGLOBAL g) longjmp(g->jumper[g->jump_level], 11); } else - tdbp->Fetched = TRUE; + tdbp->Fetched = true; if ((buf = ((PTDBMY)To_Tdb)->Myc.GetCharField(Rank))) { if (trace > 1) @@ -1354,7 +1357,7 @@ void MYSQLCOL::WriteColumn(PGLOBAL g) /* Do convert the column value if necessary. */ /*********************************************************************/ if (Value != To_Val) - Value->SetValue_pval(To_Val, FALSE); // Convert the inserted value + Value->SetValue_pval(To_Val, false); // Convert the inserted value #if defined(MYSQL_PREPARED_STATEMENTS) if (((PTDBMY)To_Tdb)->Prep) { diff --git a/storage/connect/tabmysql.h b/storage/connect/tabmysql.h index 0387fcc7da9..96991fb14c1 100644 --- a/storage/connect/tabmysql.h +++ b/storage/connect/tabmysql.h @@ -58,10 +58,11 @@ class MYSQLDEF : public TABDEF {/* Logical table description */ int Portnumber; /* MySQL port number (0 = default) */ int Mxr; /* Maxerr for an Exec table */ int Quoted; /* Identifier quoting level */ - bool Isview; /* TRUE if this table is a MySQL view */ + bool Isview; /* true if this table is a MySQL view */ bool Bind; /* Use prepared statement on insert */ bool Delayed; /* Delayed insert */ bool Xsrc; /* Execution type */ + bool Huge; /* True for big table */ }; // end of MYSQLDEF /***********************************************************************/ @@ -84,7 +85,7 @@ class TDBMYSQL : public TDBASE { virtual int GetRecpos(void) {return N;} virtual int GetProgMax(PGLOBAL g); virtual void ResetDB(void) {N = 0;} - virtual int RowNumber(PGLOBAL g, bool b = FALSE); + virtual int RowNumber(PGLOBAL g, bool b = false); virtual bool IsView(void) {return Isview;} virtual PSZ GetServer(void) {return Server;} void SetDatabase(LPCSTR db) {Database = (char*)db;} |