- 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
This commit is contained in:
parent
24369d2175
commit
f3af6da976
@ -31,6 +31,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
#include "my_global.h"
|
#include "my_global.h"
|
||||||
|
#if !defined(MYSQL_PREPARED_STATEMENTS)
|
||||||
|
#include "my_sys.h"
|
||||||
|
#include "mysqld_error.h"
|
||||||
|
#endif // !MYSQL_PREPARED_STATEMENTS
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
//#include <windows.h>
|
//#include <windows.h>
|
||||||
#else // !WIN32
|
#else // !WIN32
|
||||||
@ -59,6 +63,59 @@ uint GetDefaultPort(void)
|
|||||||
return mysqld_port;
|
return mysqld_port;
|
||||||
} // end of GetDefaultPort
|
} // 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 */
|
/* MyColumns: constructs the result blocks containing all columns */
|
||||||
/* of a MySQL table or view. */
|
/* of a MySQL table or view. */
|
||||||
@ -339,6 +396,7 @@ MYSQLC::MYSQLC(void)
|
|||||||
m_Row = NULL;
|
m_Row = NULL;
|
||||||
m_Fields = -1;
|
m_Fields = -1;
|
||||||
N = 0;
|
N = 0;
|
||||||
|
m_Use = false;
|
||||||
} // end of MYSQLC constructor
|
} // end of MYSQLC constructor
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@ -600,7 +658,16 @@ int MYSQLC::ExecSQL(PGLOBAL g, const char *query, int *w)
|
|||||||
rc = RC_FX;
|
rc = RC_FX;
|
||||||
//} else if (mysql_field_count(m_DB) > 0) {
|
//} else if (mysql_field_count(m_DB) > 0) {
|
||||||
} else if (m_DB->field_count > 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));
|
char *msg = (char*)PlugSubAlloc(g, NULL, 512 + strlen(query));
|
||||||
|
|
||||||
sprintf(msg, "mysql_store_result failed: %s", mysql_error(m_DB));
|
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;
|
rc = RC_FX;
|
||||||
} else {
|
} else {
|
||||||
m_Fields = mysql_num_fields(m_Res);
|
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
|
} // endif m_Res
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -96,5 +96,6 @@ class DllItem MYSQLC {
|
|||||||
int N;
|
int N;
|
||||||
int m_Fields; // The number of result fields
|
int m_Fields; // The number of result fields
|
||||||
int m_Afrw; // The number of affected rows
|
int m_Afrw; // The number of affected rows
|
||||||
|
bool m_Use; // Use or store result set
|
||||||
}; // end of class MYSQLC
|
}; // end of class MYSQLC
|
||||||
|
|
||||||
|
@ -84,10 +84,11 @@ MYSQLDEF::MYSQLDEF(void)
|
|||||||
Username = NULL;
|
Username = NULL;
|
||||||
Password = NULL;
|
Password = NULL;
|
||||||
Portnumber = 0;
|
Portnumber = 0;
|
||||||
Isview = FALSE;
|
Isview = false;
|
||||||
Bind = FALSE;
|
Bind = false;
|
||||||
Delayed = FALSE;
|
Delayed = false;
|
||||||
Xsrc = FALSE;
|
Xsrc = false;
|
||||||
|
Huge = false;
|
||||||
} // end of MYSQLDEF constructor
|
} // end of MYSQLDEF constructor
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@ -329,7 +330,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
} else {
|
} else {
|
||||||
// MYSQL access from a PROXY table
|
// MYSQL access from a PROXY table
|
||||||
Database = GetStringCatInfo(g, "Database", "*");
|
Database = GetStringCatInfo(g, "Database", "*");
|
||||||
Isview = GetBoolCatInfo("View", FALSE);
|
Isview = GetBoolCatInfo("View", false);
|
||||||
|
|
||||||
// We must get other connection parms from the calling table
|
// We must get other connection parms from the calling table
|
||||||
Remove_tshp(Cat);
|
Remove_tshp(Cat);
|
||||||
@ -363,7 +364,8 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
// Specific for command executing tables
|
// Specific for command executing tables
|
||||||
Xsrc = GetBoolCatInfo("Execsrc", false);
|
Xsrc = GetBoolCatInfo("Execsrc", false);
|
||||||
Mxr = GetIntCatInfo("Maxerr", 0);
|
Mxr = GetIntCatInfo("Maxerr", 0);
|
||||||
return FALSE;
|
Huge = GetBoolCatInfo("Huge", false);
|
||||||
|
return false;
|
||||||
} // end of DefineAM
|
} // end of DefineAM
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@ -401,6 +403,7 @@ TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp)
|
|||||||
Isview = tdp->Isview;
|
Isview = tdp->Isview;
|
||||||
Prep = tdp->Bind;
|
Prep = tdp->Bind;
|
||||||
Delayed = tdp->Delayed;
|
Delayed = tdp->Delayed;
|
||||||
|
Myc.m_Use = tdp->Huge;
|
||||||
} else {
|
} else {
|
||||||
Host = NULL;
|
Host = NULL;
|
||||||
Database = NULL;
|
Database = NULL;
|
||||||
@ -412,15 +415,15 @@ TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp)
|
|||||||
Qrystr = NULL;
|
Qrystr = NULL;
|
||||||
Quoted = 0;
|
Quoted = 0;
|
||||||
Port = 0;
|
Port = 0;
|
||||||
Isview = FALSE;
|
Isview = false;
|
||||||
Prep = FALSE;
|
Prep = false;
|
||||||
Delayed = FALSE;
|
Delayed = false;
|
||||||
} // endif tdp
|
} // endif tdp
|
||||||
|
|
||||||
Bind = NULL;
|
Bind = NULL;
|
||||||
Query = NULL;
|
Query = NULL;
|
||||||
Qbuf = NULL;
|
Qbuf = NULL;
|
||||||
Fetched = FALSE;
|
Fetched = false;
|
||||||
m_Rc = RC_FX;
|
m_Rc = RC_FX;
|
||||||
AftRows = 0;
|
AftRows = 0;
|
||||||
N = -1;
|
N = -1;
|
||||||
@ -555,17 +558,17 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
|
|||||||
char *colist, *valist = NULL;
|
char *colist, *valist = NULL;
|
||||||
char *tk = "`";
|
char *tk = "`";
|
||||||
int len = 0, qlen = 0;
|
int len = 0, qlen = 0;
|
||||||
bool b = FALSE;
|
bool b = false;
|
||||||
PCOL colp;
|
PCOL colp;
|
||||||
|
|
||||||
if (Query)
|
if (Query)
|
||||||
return FALSE; // already done
|
return false; // already done
|
||||||
|
|
||||||
for (colp = Columns; colp; colp = colp->GetNext())
|
for (colp = Columns; colp; colp = colp->GetNext())
|
||||||
if (!colp->IsSpecial()) {
|
if (!colp->IsSpecial()) {
|
||||||
// if (colp->IsSpecial()) {
|
// if (colp->IsSpecial()) {
|
||||||
// strcpy(g->Message, MSG(NO_SPEC_COL));
|
// strcpy(g->Message, MSG(NO_SPEC_COL));
|
||||||
// return TRUE;
|
// return true;
|
||||||
// } else {
|
// } else {
|
||||||
len += (strlen(colp->GetName()) + 4);
|
len += (strlen(colp->GetName()) + 4);
|
||||||
((PMYCOL)colp)->Rank = Nparm++;
|
((PMYCOL)colp)->Rank = Nparm++;
|
||||||
@ -581,7 +584,7 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
|
|||||||
#else // !MYSQL_PREPARED_STATEMENTS
|
#else // !MYSQL_PREPARED_STATEMENTS
|
||||||
strcpy(g->Message, "Prepared statements not used (not supported)");
|
strcpy(g->Message, "Prepared statements not used (not supported)");
|
||||||
PushWarning(g, this);
|
PushWarning(g, this);
|
||||||
Prep = FALSE;
|
Prep = false;
|
||||||
#endif // !MYSQL_PREPARED_STATEMENTS
|
#endif // !MYSQL_PREPARED_STATEMENTS
|
||||||
} // endif Prep
|
} // endif Prep
|
||||||
|
|
||||||
@ -590,7 +593,7 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
|
|||||||
strcat(colist, ", ");
|
strcat(colist, ", ");
|
||||||
if (Prep) strcat(valist, ",");
|
if (Prep) strcat(valist, ",");
|
||||||
} else
|
} else
|
||||||
b = TRUE;
|
b = true;
|
||||||
|
|
||||||
strcat(strcat(strcat(colist, tk), colp->GetName()), tk);
|
strcat(strcat(strcat(colist, tk), colp->GetName()), tk);
|
||||||
|
|
||||||
@ -628,7 +631,7 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
|
|||||||
Qbuf = (char *)PlugSubAlloc(g, NULL, qlen);
|
Qbuf = (char *)PlugSubAlloc(g, NULL, qlen);
|
||||||
} // endelse Prep
|
} // endelse Prep
|
||||||
|
|
||||||
return FALSE;
|
return false;
|
||||||
} // end of MakeInsert
|
} // end of MakeInsert
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@ -906,9 +909,9 @@ bool TDBMYSQL::SetColumnRanks(PGLOBAL g)
|
|||||||
{
|
{
|
||||||
for (PCOL colp = Columns; colp; colp = colp->GetNext())
|
for (PCOL colp = Columns; colp; colp = colp->GetNext())
|
||||||
if (((PMYCOL)colp)->FindRank(g))
|
if (((PMYCOL)colp)->FindRank(g))
|
||||||
return TRUE;
|
return true;
|
||||||
|
|
||||||
return FALSE;
|
return false;
|
||||||
} // end of SetColumnRanks
|
} // end of SetColumnRanks
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@ -1233,7 +1236,7 @@ bool MYSQLCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
|
|||||||
{
|
{
|
||||||
if (!(To_Val = value)) {
|
if (!(To_Val = value)) {
|
||||||
sprintf(g->Message, MSG(VALUE_ERROR), Name);
|
sprintf(g->Message, MSG(VALUE_ERROR), Name);
|
||||||
return TRUE;
|
return true;
|
||||||
} else if (Buf_Type == value->GetType()) {
|
} else if (Buf_Type == value->GetType()) {
|
||||||
// Values are of the (good) column type
|
// Values are of the (good) column type
|
||||||
if (Buf_Type == TYPE_DATE) {
|
if (Buf_Type == TYPE_DATE) {
|
||||||
@ -1253,12 +1256,12 @@ bool MYSQLCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
|
|||||||
if (check) {
|
if (check) {
|
||||||
sprintf(g->Message, MSG(TYPE_VALUE_ERR), Name,
|
sprintf(g->Message, MSG(TYPE_VALUE_ERR), Name,
|
||||||
GetTypeName(Buf_Type), GetTypeName(value->GetType()));
|
GetTypeName(Buf_Type), GetTypeName(value->GetType()));
|
||||||
return TRUE;
|
return true;
|
||||||
} // endif check
|
} // endif check
|
||||||
|
|
||||||
newval:
|
newval:
|
||||||
if (InitValue(g)) // Allocate the matching value block
|
if (InitValue(g)) // Allocate the matching value block
|
||||||
return TRUE;
|
return true;
|
||||||
|
|
||||||
} // endif's Value, Buf_Type
|
} // endif's Value, Buf_Type
|
||||||
|
|
||||||
@ -1269,7 +1272,7 @@ bool MYSQLCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
|
|||||||
|
|
||||||
// Set the Column
|
// Set the Column
|
||||||
Status = (ok) ? BUF_EMPTY : BUF_NO;
|
Status = (ok) ? BUF_EMPTY : BUF_NO;
|
||||||
return FALSE;
|
return false;
|
||||||
} // end of SetBuffer
|
} // end of SetBuffer
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@ -1317,7 +1320,7 @@ void MYSQLCOL::ReadColumn(PGLOBAL g)
|
|||||||
|
|
||||||
longjmp(g->jumper[g->jump_level], 11);
|
longjmp(g->jumper[g->jump_level], 11);
|
||||||
} else
|
} else
|
||||||
tdbp->Fetched = TRUE;
|
tdbp->Fetched = true;
|
||||||
|
|
||||||
if ((buf = ((PTDBMY)To_Tdb)->Myc.GetCharField(Rank))) {
|
if ((buf = ((PTDBMY)To_Tdb)->Myc.GetCharField(Rank))) {
|
||||||
if (trace > 1)
|
if (trace > 1)
|
||||||
@ -1354,7 +1357,7 @@ void MYSQLCOL::WriteColumn(PGLOBAL g)
|
|||||||
/* Do convert the column value if necessary. */
|
/* Do convert the column value if necessary. */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
if (Value != To_Val)
|
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 defined(MYSQL_PREPARED_STATEMENTS)
|
||||||
if (((PTDBMY)To_Tdb)->Prep) {
|
if (((PTDBMY)To_Tdb)->Prep) {
|
||||||
|
@ -58,10 +58,11 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
|
|||||||
int Portnumber; /* MySQL port number (0 = default) */
|
int Portnumber; /* MySQL port number (0 = default) */
|
||||||
int Mxr; /* Maxerr for an Exec table */
|
int Mxr; /* Maxerr for an Exec table */
|
||||||
int Quoted; /* Identifier quoting level */
|
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 Bind; /* Use prepared statement on insert */
|
||||||
bool Delayed; /* Delayed insert */
|
bool Delayed; /* Delayed insert */
|
||||||
bool Xsrc; /* Execution type */
|
bool Xsrc; /* Execution type */
|
||||||
|
bool Huge; /* True for big table */
|
||||||
}; // end of MYSQLDEF
|
}; // end of MYSQLDEF
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@ -84,7 +85,7 @@ class TDBMYSQL : public TDBASE {
|
|||||||
virtual int GetRecpos(void) {return N;}
|
virtual int GetRecpos(void) {return N;}
|
||||||
virtual int GetProgMax(PGLOBAL g);
|
virtual int GetProgMax(PGLOBAL g);
|
||||||
virtual void ResetDB(void) {N = 0;}
|
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 bool IsView(void) {return Isview;}
|
||||||
virtual PSZ GetServer(void) {return Server;}
|
virtual PSZ GetServer(void) {return Server;}
|
||||||
void SetDatabase(LPCSTR db) {Database = (char*)db;}
|
void SetDatabase(LPCSTR db) {Database = (char*)db;}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user