mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
- BUG fixed: When updating, to avoid skipped update, force the table
handler to retrieve write-only fields to be able to compare records and detect data change. modified: storage/connect/ha_connect.cc - Preparing UPDATE ad DELETE on ODBC tables (new function added but not used yet) modified: storage/connect/tabodbc.cpp storage/connect/tabodbc.h
This commit is contained in:
parent
056f35d0c1
commit
e5c589a8da
3 changed files with 68 additions and 23 deletions
|
@ -659,6 +659,8 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
|
|||
opval= (char*)options->colist;
|
||||
else if (!stricmp(opname, "Data_charset"))
|
||||
opval= (char*)options->data_charset;
|
||||
else if (!stricmp(opname, "Query_String"))
|
||||
opval= thd_query_string(table->in_use)->str;
|
||||
|
||||
if (!opval && options && options->oplist)
|
||||
opval= GetListOption(xp->g, opname, options->oplist);
|
||||
|
@ -1239,15 +1241,16 @@ int ha_connect::CloseTable(PGLOBAL g)
|
|||
/***********************************************************************/
|
||||
int ha_connect::MakeRecord(char *buf)
|
||||
{
|
||||
char *p, *fmt, val[32];
|
||||
int rc= 0;
|
||||
Field* *field;
|
||||
Field *fp;
|
||||
my_bitmap_map *org_bitmap;
|
||||
CHARSET_INFO *charset= tdbp->data_charset();
|
||||
const MY_BITMAP *map;
|
||||
PVAL value;
|
||||
PCOL colp= NULL;
|
||||
char *p, *fmt, val[32];
|
||||
int rc= 0;
|
||||
Field* *field;
|
||||
Field *fp;
|
||||
my_bitmap_map *org_bitmap;
|
||||
CHARSET_INFO *charset= tdbp->data_charset();
|
||||
//MY_BITMAP readmap;
|
||||
MY_BITMAP *map;
|
||||
PVAL value;
|
||||
PCOL colp= NULL;
|
||||
DBUG_ENTER("ha_connect::MakeRecord");
|
||||
|
||||
if (xtrace > 1)
|
||||
|
@ -1263,7 +1266,7 @@ int ha_connect::MakeRecord(char *buf)
|
|||
memset(buf, 0, table->s->null_bytes);
|
||||
|
||||
// When sorting read_set selects all columns, so we use def_read_set
|
||||
map= (const MY_BITMAP *)&table->def_read_set;
|
||||
map= (MY_BITMAP *)&table->def_read_set;
|
||||
|
||||
// Make the pseudo record from field values
|
||||
for (field= table->field; *field && !rc; field++) {
|
||||
|
@ -2382,18 +2385,21 @@ int ha_connect::rnd_init(bool scan)
|
|||
if (xtrace)
|
||||
printf("%p in rnd_init: scan=%d\n", this, scan);
|
||||
|
||||
if (g) {
|
||||
if (!table || xmod == MODE_INSERT)
|
||||
DBUG_RETURN(HA_ERR_INITIALIZATION);
|
||||
if (!g || !table || xmod == MODE_INSERT)
|
||||
DBUG_RETURN(HA_ERR_INITIALIZATION);
|
||||
|
||||
// Close the table if it was opened yet (locked?)
|
||||
if (IsOpened())
|
||||
CloseTable(g);
|
||||
// Close the table if it was opened yet (locked?)
|
||||
if (IsOpened())
|
||||
CloseTable(g);
|
||||
|
||||
if (OpenTable(g, xmod == MODE_DELETE))
|
||||
DBUG_RETURN(HA_ERR_INITIALIZATION);
|
||||
// When updating, to avoid skipped update, force the table
|
||||
// handler to retrieve write-only fields to be able to compare
|
||||
// records and detect data change.
|
||||
if (xmod == MODE_UPDATE)
|
||||
bitmap_union(table->read_set, table->write_set);
|
||||
|
||||
} // endif g
|
||||
if (OpenTable(g, xmod == MODE_DELETE))
|
||||
DBUG_RETURN(HA_ERR_INITIALIZATION);
|
||||
|
||||
xp->nrd= xp->fnd= xp->nfd= 0;
|
||||
xp->tb1= my_interval_timer();
|
||||
|
|
|
@ -90,7 +90,7 @@ extern int num_read, num_there, num_eq[2]; // Statistics
|
|||
/***********************************************************************/
|
||||
ODBCDEF::ODBCDEF(void)
|
||||
{
|
||||
Connect = Tabname = Tabowner = Tabqual = Srcdef = Qchar = NULL;
|
||||
Connect = Tabname = Tabowner = Tabqual = Srcdef = Qchar = Qrystr = NULL;
|
||||
Catver = Options = 0;
|
||||
Xsrc = false;
|
||||
} // end of ODBCDEF constructor
|
||||
|
@ -108,6 +108,7 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||
Tabqual = Cat->GetStringCatInfo(g, "Qualifier", "");
|
||||
Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL);
|
||||
Qchar = Cat->GetStringCatInfo(g, "Qchar", "");
|
||||
Qrystr = Cat->GetStringCatInfo(g, "Query_String", "?");
|
||||
Catver = Cat->GetIntCatInfo("Catver", 2);
|
||||
Xsrc = Cat->GetBoolCatInfo("Execsrc", FALSE);
|
||||
Mxr = Cat->GetIntCatInfo("Maxerr", 0);
|
||||
|
@ -171,6 +172,7 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp)
|
|||
Qualifier = tdp->Tabqual;
|
||||
Srcdef = tdp->Srcdef;
|
||||
Quote = tdp->GetQchar();
|
||||
Qrystr = tdp->Qrystr;
|
||||
Options = tdp->Options;
|
||||
Rows = tdp->GetElemt();
|
||||
Catver = tdp->Catver;
|
||||
|
@ -181,6 +183,7 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp)
|
|||
Qualifier = NULL;
|
||||
Srcdef = NULL;
|
||||
Quote = NULL;
|
||||
Qrystr = NULL;
|
||||
Options = 0;
|
||||
Rows = 0;
|
||||
Catver = 0;
|
||||
|
@ -209,6 +212,7 @@ TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp)
|
|||
Qualifier = tdbp->Qualifier;
|
||||
Srcdef = tdbp->Srcdef;
|
||||
Quote = tdbp->Quote;
|
||||
Qrystr = tdbp->Qrystr;
|
||||
Query = tdbp->Query;
|
||||
Count = tdbp->Count;
|
||||
//Where = tdbp->Where;
|
||||
|
@ -515,6 +519,40 @@ bool TDBODBC::BindParameters(PGLOBAL g)
|
|||
return false;
|
||||
} // end of BindParameters
|
||||
|
||||
/***********************************************************************/
|
||||
/* MakeCMD: make the SQL statement to send to ODBC connection. */
|
||||
/***********************************************************************/
|
||||
char *TDBODBC::MakeStmt(PGLOBAL g)
|
||||
{
|
||||
char *qc, *stmt = NULL, cmd[8], tab[96], end[512];
|
||||
int n = (Mode == MODE_DELETE) ? 1 : 2;
|
||||
|
||||
stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
|
||||
*end = 0;
|
||||
qc = (Quote) ? Quote : "\"";
|
||||
|
||||
if (sscanf(Qrystr, "%s `%[^`]`%511c", cmd, tab, end) > n ||
|
||||
sscanf(Qrystr, "%s \"%[^\"]\"%511c", cmd, tab, end) > n ||
|
||||
sscanf(Qrystr, "%s %s%511c", cmd, tab, end) > n)
|
||||
strcat(strcat(strcpy(tab, qc), TableName), qc);
|
||||
else {
|
||||
strcpy(g->Message, "Cannot use this UPDATE/DELETE command");
|
||||
return NULL;
|
||||
} // endif sscanf
|
||||
|
||||
strcat(strcat(strcpy(stmt, cmd), " "), tab);
|
||||
|
||||
if (*end) {
|
||||
for (int i = 0; end[i]; i++)
|
||||
if (end[i] == '`')
|
||||
end[i] = *qc;
|
||||
|
||||
strcat(stmt, end);
|
||||
} // endif end
|
||||
|
||||
return stmt;
|
||||
} // end of MakeStmt
|
||||
|
||||
/***********************************************************************/
|
||||
/* ResetSize: call by TDBMUL when calculating size estimate. */
|
||||
/***********************************************************************/
|
||||
|
|
|
@ -50,6 +50,7 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
|
|||
PSZ Tabqual; /* External table qualifier */
|
||||
PSZ Srcdef; /* The source table SQL definition */
|
||||
PSZ Qchar; /* Identifier quoting character */
|
||||
PSZ Qrystr; /* The original query */
|
||||
int Catver; /* ODBC version for catalog functions */
|
||||
int Options; /* Open connection options */
|
||||
int Mxr; /* Maxerr for an Exec table */
|
||||
|
@ -97,13 +98,12 @@ class TDBODBC : public TDBASE {
|
|||
|
||||
protected:
|
||||
// Internal functions
|
||||
int Decode(char *utf, char *buf, size_t n);
|
||||
int Decode(char *utf, char *buf, size_t n);
|
||||
char *MakeSQL(PGLOBAL g, bool cnt);
|
||||
//bool MakeUpdate(PGLOBAL g, PSELECT selist);
|
||||
bool MakeInsert(PGLOBAL g);
|
||||
//bool MakeDelete(PGLOBAL g);
|
||||
//bool MakeFilter(PGLOBAL g, bool c);
|
||||
bool BindParameters(PGLOBAL g);
|
||||
char *MakeStmt(PGLOBAL g);
|
||||
|
||||
// Members
|
||||
ODBConn *Ocp; // Points to an ODBC connection class
|
||||
|
@ -119,6 +119,7 @@ class TDBODBC : public TDBASE {
|
|||
char *Quote; // The identifier quoting character
|
||||
char *MulConn; // Used for multiple ODBC tables
|
||||
char *DBQ; // The address part of Connect string
|
||||
char *Qrystr; // The original query
|
||||
int Options; // Connect options
|
||||
int Fpos; // Position of last read record
|
||||
int AftRows; // The number of affected rows
|
||||
|
|
Loading…
Reference in a new issue