Commit e5c589a8 authored by Olivier Bertrand's avatar Olivier Bertrand

- 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
parent 056f35d0
...@@ -659,6 +659,8 @@ char *ha_connect::GetStringOption(char *opname, char *sdef) ...@@ -659,6 +659,8 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
opval= (char*)options->colist; opval= (char*)options->colist;
else if (!stricmp(opname, "Data_charset")) else if (!stricmp(opname, "Data_charset"))
opval= (char*)options->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) if (!opval && options && options->oplist)
opval= GetListOption(xp->g, opname, options->oplist); opval= GetListOption(xp->g, opname, options->oplist);
...@@ -1239,15 +1241,16 @@ int ha_connect::CloseTable(PGLOBAL g) ...@@ -1239,15 +1241,16 @@ int ha_connect::CloseTable(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
int ha_connect::MakeRecord(char *buf) int ha_connect::MakeRecord(char *buf)
{ {
char *p, *fmt, val[32]; char *p, *fmt, val[32];
int rc= 0; int rc= 0;
Field* *field; Field* *field;
Field *fp; Field *fp;
my_bitmap_map *org_bitmap; my_bitmap_map *org_bitmap;
CHARSET_INFO *charset= tdbp->data_charset(); CHARSET_INFO *charset= tdbp->data_charset();
const MY_BITMAP *map; //MY_BITMAP readmap;
PVAL value; MY_BITMAP *map;
PCOL colp= NULL; PVAL value;
PCOL colp= NULL;
DBUG_ENTER("ha_connect::MakeRecord"); DBUG_ENTER("ha_connect::MakeRecord");
if (xtrace > 1) if (xtrace > 1)
...@@ -1263,7 +1266,7 @@ int ha_connect::MakeRecord(char *buf) ...@@ -1263,7 +1266,7 @@ int ha_connect::MakeRecord(char *buf)
memset(buf, 0, table->s->null_bytes); memset(buf, 0, table->s->null_bytes);
// When sorting read_set selects all columns, so we use def_read_set // 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 // Make the pseudo record from field values
for (field= table->field; *field && !rc; field++) { for (field= table->field; *field && !rc; field++) {
...@@ -2382,18 +2385,21 @@ int ha_connect::rnd_init(bool scan) ...@@ -2382,18 +2385,21 @@ int ha_connect::rnd_init(bool scan)
if (xtrace) if (xtrace)
printf("%p in rnd_init: scan=%d\n", this, scan); printf("%p in rnd_init: scan=%d\n", this, scan);
if (g) { if (!g || !table || xmod == MODE_INSERT)
if (!table || xmod == MODE_INSERT) DBUG_RETURN(HA_ERR_INITIALIZATION);
DBUG_RETURN(HA_ERR_INITIALIZATION);
// Close the table if it was opened yet (locked?) // Close the table if it was opened yet (locked?)
if (IsOpened()) if (IsOpened())
CloseTable(g); CloseTable(g);
if (OpenTable(g, xmod == MODE_DELETE)) // When updating, to avoid skipped update, force the table
DBUG_RETURN(HA_ERR_INITIALIZATION); // 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->nrd= xp->fnd= xp->nfd= 0;
xp->tb1= my_interval_timer(); xp->tb1= my_interval_timer();
......
...@@ -90,7 +90,7 @@ extern int num_read, num_there, num_eq[2]; // Statistics ...@@ -90,7 +90,7 @@ extern int num_read, num_there, num_eq[2]; // Statistics
/***********************************************************************/ /***********************************************************************/
ODBCDEF::ODBCDEF(void) ODBCDEF::ODBCDEF(void)
{ {
Connect = Tabname = Tabowner = Tabqual = Srcdef = Qchar = NULL; Connect = Tabname = Tabowner = Tabqual = Srcdef = Qchar = Qrystr = NULL;
Catver = Options = 0; Catver = Options = 0;
Xsrc = false; Xsrc = false;
} // end of ODBCDEF constructor } // end of ODBCDEF constructor
...@@ -108,6 +108,7 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) ...@@ -108,6 +108,7 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Tabqual = Cat->GetStringCatInfo(g, "Qualifier", ""); Tabqual = Cat->GetStringCatInfo(g, "Qualifier", "");
Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL); Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL);
Qchar = Cat->GetStringCatInfo(g, "Qchar", ""); Qchar = Cat->GetStringCatInfo(g, "Qchar", "");
Qrystr = Cat->GetStringCatInfo(g, "Query_String", "?");
Catver = Cat->GetIntCatInfo("Catver", 2); Catver = Cat->GetIntCatInfo("Catver", 2);
Xsrc = Cat->GetBoolCatInfo("Execsrc", FALSE); Xsrc = Cat->GetBoolCatInfo("Execsrc", FALSE);
Mxr = Cat->GetIntCatInfo("Maxerr", 0); Mxr = Cat->GetIntCatInfo("Maxerr", 0);
...@@ -171,6 +172,7 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp) ...@@ -171,6 +172,7 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp)
Qualifier = tdp->Tabqual; Qualifier = tdp->Tabqual;
Srcdef = tdp->Srcdef; Srcdef = tdp->Srcdef;
Quote = tdp->GetQchar(); Quote = tdp->GetQchar();
Qrystr = tdp->Qrystr;
Options = tdp->Options; Options = tdp->Options;
Rows = tdp->GetElemt(); Rows = tdp->GetElemt();
Catver = tdp->Catver; Catver = tdp->Catver;
...@@ -181,6 +183,7 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp) ...@@ -181,6 +183,7 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp)
Qualifier = NULL; Qualifier = NULL;
Srcdef = NULL; Srcdef = NULL;
Quote = NULL; Quote = NULL;
Qrystr = NULL;
Options = 0; Options = 0;
Rows = 0; Rows = 0;
Catver = 0; Catver = 0;
...@@ -209,6 +212,7 @@ TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp) ...@@ -209,6 +212,7 @@ TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp)
Qualifier = tdbp->Qualifier; Qualifier = tdbp->Qualifier;
Srcdef = tdbp->Srcdef; Srcdef = tdbp->Srcdef;
Quote = tdbp->Quote; Quote = tdbp->Quote;
Qrystr = tdbp->Qrystr;
Query = tdbp->Query; Query = tdbp->Query;
Count = tdbp->Count; Count = tdbp->Count;
//Where = tdbp->Where; //Where = tdbp->Where;
...@@ -515,6 +519,40 @@ bool TDBODBC::BindParameters(PGLOBAL g) ...@@ -515,6 +519,40 @@ bool TDBODBC::BindParameters(PGLOBAL g)
return false; return false;
} // end of BindParameters } // 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. */ /* ResetSize: call by TDBMUL when calculating size estimate. */
/***********************************************************************/ /***********************************************************************/
......
...@@ -50,6 +50,7 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */ ...@@ -50,6 +50,7 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
PSZ Tabqual; /* External table qualifier */ PSZ Tabqual; /* External table qualifier */
PSZ Srcdef; /* The source table SQL definition */ PSZ Srcdef; /* The source table SQL definition */
PSZ Qchar; /* Identifier quoting character */ PSZ Qchar; /* Identifier quoting character */
PSZ Qrystr; /* The original query */
int Catver; /* ODBC version for catalog functions */ int Catver; /* ODBC version for catalog functions */
int Options; /* Open connection options */ int Options; /* Open connection options */
int Mxr; /* Maxerr for an Exec table */ int Mxr; /* Maxerr for an Exec table */
...@@ -97,13 +98,12 @@ class TDBODBC : public TDBASE { ...@@ -97,13 +98,12 @@ class TDBODBC : public TDBASE {
protected: protected:
// Internal functions // 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); char *MakeSQL(PGLOBAL g, bool cnt);
//bool MakeUpdate(PGLOBAL g, PSELECT selist);
bool MakeInsert(PGLOBAL g); bool MakeInsert(PGLOBAL g);
//bool MakeDelete(PGLOBAL g);
//bool MakeFilter(PGLOBAL g, bool c); //bool MakeFilter(PGLOBAL g, bool c);
bool BindParameters(PGLOBAL g); bool BindParameters(PGLOBAL g);
char *MakeStmt(PGLOBAL g);
// Members // Members
ODBConn *Ocp; // Points to an ODBC connection class ODBConn *Ocp; // Points to an ODBC connection class
...@@ -119,6 +119,7 @@ class TDBODBC : public TDBASE { ...@@ -119,6 +119,7 @@ class TDBODBC : public TDBASE {
char *Quote; // The identifier quoting character char *Quote; // The identifier quoting character
char *MulConn; // Used for multiple ODBC tables char *MulConn; // Used for multiple ODBC tables
char *DBQ; // The address part of Connect string char *DBQ; // The address part of Connect string
char *Qrystr; // The original query
int Options; // Connect options int Options; // Connect options
int Fpos; // Position of last read record int Fpos; // Position of last read record
int AftRows; // The number of affected rows int AftRows; // The number of affected rows
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment