Commit 96ba1f14 authored by Olivier Bertrand's avatar Olivier Bertrand

- Handle the use of date/time values when making queries for MYSQL or

  ODBC. Was raised by 7549.
modified:
  storage/connect/ha_connect.cc
  storage/connect/odbconn.cpp
  storage/connect/tabodbc.cpp
parent 35548d57
...@@ -2519,6 +2519,8 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond) ...@@ -2519,6 +2519,8 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
char *body= filp->Body; char *body= filp->Body;
unsigned int i; unsigned int i;
bool ismul= false, x= (tty == TYPE_AM_MYX || tty == TYPE_AM_XDBC); bool ismul= false, x= (tty == TYPE_AM_MYX || tty == TYPE_AM_XDBC);
bool nonul= (tty == TYPE_AM_ODBC && (tdbp->GetMode() == MODE_INSERT ||
tdbp->GetMode() == MODE_DELETE));
OPVAL vop= OP_XX; OPVAL vop= OP_XX;
if (!cond) if (!cond)
...@@ -2536,7 +2538,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond) ...@@ -2536,7 +2538,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
if (trace) if (trace)
htrc("Cond: Ftype=%d name=%s\n", cond_item->functype(), htrc("Cond: Ftype=%d name=%s\n", cond_item->functype(),
cond_item->func_name()); cond_item->func_name());
switch (cond_item->functype()) { switch (cond_item->functype()) {
case Item_func::COND_AND_FUNC: vop= OP_AND; break; case Item_func::COND_AND_FUNC: vop= OP_AND; break;
...@@ -2555,7 +2557,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond) ...@@ -2555,7 +2557,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
for (i= 0; i < arglist->elements; i++) for (i= 0; i < arglist->elements; i++)
if ((subitem= li++)) { if ((subitem= li++)) {
if (!CheckCond(g, filp, tty, subitem)) { if (!CheckCond(g, filp, tty, subitem)) {
if (vop == OP_OR) if (vop == OP_OR || nonul)
return NULL; return NULL;
else else
*p2= 0; *p2= 0;
...@@ -2651,6 +2653,8 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond) ...@@ -2651,6 +2653,8 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
if (trace) { if (trace) {
htrc("Field index=%d\n", pField->field->field_index); htrc("Field index=%d\n", pField->field->field_index);
htrc("Field name=%s\n", pField->field->field_name); htrc("Field name=%s\n", pField->field->field_name);
htrc("Field type=%d\n", pField->field->type());
htrc("Field_type=%d\n", args[i]->field_type());
} // endif trace } // endif trace
// IN and BETWEEN clauses should be col VOP list // IN and BETWEEN clauses should be col VOP list
...@@ -2670,8 +2674,9 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond) ...@@ -2670,8 +2674,9 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
char buff[256]; char buff[256];
String *res, tmp(buff, sizeof(buff), &my_charset_bin); String *res, tmp(buff, sizeof(buff), &my_charset_bin);
Item_basic_constant *pval= (Item_basic_constant *)args[i]; Item_basic_constant *pval= (Item_basic_constant *)args[i];
Item::Type type= args[i]->real_type();
switch (args[i]->real_type()) { switch (type) {
case COND::STRING_ITEM: case COND::STRING_ITEM:
case COND::INT_ITEM: case COND::INT_ITEM:
case COND::REAL_ITEM: case COND::REAL_ITEM:
...@@ -2696,10 +2701,64 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond) ...@@ -2696,10 +2701,64 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
if (!x) { if (!x) {
// Append the value to the filter // Append the value to the filter
if (args[i]->field_type() == MYSQL_TYPE_VARCHAR) switch (args[i]->field_type()) {
strcat(strncat(strcat(body, "'"), res->ptr(), res->length()), "'"); case MYSQL_TYPE_TIMESTAMP:
else case MYSQL_TYPE_DATETIME:
strncat(body, res->ptr(), res->length()); if (tty == TYPE_AM_ODBC) {
strcat(body, "{ts '");
strcat(strncat(body, res->ptr(), res->length()), "'}");
break;
} // endif ODBC
case MYSQL_TYPE_DATE:
if (tty == TYPE_AM_ODBC) {
strcat(body, "{d '");
strcat(strncat(body, res->ptr(), res->length()), "'}");
break;
} // endif ODBC
case MYSQL_TYPE_TIME:
if (tty == TYPE_AM_ODBC) {
strcat(body, "{t '");
strcat(strncat(body, res->ptr(), res->length()), "'}");
break;
} // endif ODBC
case MYSQL_TYPE_VARCHAR:
if (tty == TYPE_AM_ODBC && i) {
switch (args[0]->field_type()) {
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATETIME:
strcat(body, "{ts '");
strncat(body, res->ptr(), res->length());
strcat(body, "'}");
break;
case MYSQL_TYPE_DATE:
strcat(body, "{d '");
strncat(body, res->ptr(), res->length());
strcat(body, "'}");
break;
case MYSQL_TYPE_TIME:
strcat(body, "{t '");
strncat(body, res->ptr(), res->length());
strcat(body, "'}");
break;
default:
strcat(body, "'");
strncat(body, res->ptr(), res->length());
strcat(body, "'");
} // endswitch field type
} else {
strcat(body, "'");
strncat(body, res->ptr(), res->length());
strcat(body, "'");
} // endif tty
break;
default:
strncat(body, res->ptr(), res->length());
} // endswitch field type
} else { } else {
if (args[i]->field_type() == MYSQL_TYPE_VARCHAR) { if (args[i]->field_type() == MYSQL_TYPE_VARCHAR) {
......
...@@ -1740,6 +1740,8 @@ bool ODBConn::BindParam(ODBCCOL *colp) ...@@ -1740,6 +1740,8 @@ bool ODBConn::BindParam(ODBCCOL *colp)
strcpy(m_G->Message, x->GetErrorMessage(0)); strcpy(m_G->Message, x->GetErrorMessage(0));
colsize = colp->GetPrecision(); colsize = colp->GetPrecision();
sqlt = GetSQLType(buftype); sqlt = GetSQLType(buftype);
dec = IsTypeChar(buftype) ? 0 : colp->GetScale();
nul = SQL_NULLABLE_UNKNOWN;
} // end try/catch } // end try/catch
buf = colp->GetBuffer(0); buf = colp->GetBuffer(0);
......
...@@ -573,8 +573,7 @@ bool TDBODBC::BindParameters(PGLOBAL g) ...@@ -573,8 +573,7 @@ bool TDBODBC::BindParameters(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
char *TDBODBC::MakeCommand(PGLOBAL g) char *TDBODBC::MakeCommand(PGLOBAL g)
{ {
char *p, name[68], *qc = Ocp->GetQuoteChar(); char *p, *stmt, name[68], *body = NULL, *qc = Ocp->GetQuoteChar();
char *stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
char *qrystr = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 1); char *qrystr = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 1);
bool qtd = Quoted > 0; bool qtd = Quoted > 0;
int i = 0, k = 0; int i = 0, k = 0;
...@@ -585,6 +584,15 @@ char *TDBODBC::MakeCommand(PGLOBAL g) ...@@ -585,6 +584,15 @@ char *TDBODBC::MakeCommand(PGLOBAL g)
qrystr[i] = (Qrystr[i] == '`') ? *qc : tolower(Qrystr[i]); qrystr[i] = (Qrystr[i] == '`') ? *qc : tolower(Qrystr[i]);
} while (Qrystr[i++]); } while (Qrystr[i++]);
if (To_CondFil && (p = strstr(qrystr, " where "))) {
p[7] = 0; // Remove where clause
Qrystr[(p - qrystr) + 7] = 0;
body = To_CondFil->Body;
stmt = (char*)PlugSubAlloc(g, NULL, strlen(qrystr)
+ strlen(body) + 64);
} else
stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
// Check whether the table name is equal to a keyword // Check whether the table name is equal to a keyword
// If so, it must be quoted in the original query // If so, it must be quoted in the original query
strlwr(strcat(strcat(strcpy(name, " "), Name), " ")); strlwr(strcat(strcat(strcpy(name, " "), Name), " "));
...@@ -612,6 +620,9 @@ char *TDBODBC::MakeCommand(PGLOBAL g) ...@@ -612,6 +620,9 @@ char *TDBODBC::MakeCommand(PGLOBAL g)
stmt[i++] = (Qrystr[k] == '`') ? *qc : Qrystr[k]; stmt[i++] = (Qrystr[k] == '`') ? *qc : Qrystr[k];
} while (Qrystr[k++]); } while (Qrystr[k++]);
if (body)
strcat(stmt, body);
} else { } else {
sprintf(g->Message, "Cannot use this %s command", sprintf(g->Message, "Cannot use this %s command",
(Mode == MODE_UPDATE) ? "UPDATE" : "DELETE"); (Mode == MODE_UPDATE) ? "UPDATE" : "DELETE");
...@@ -774,7 +785,7 @@ int TDBODBC::GetProgMax(PGLOBAL g) ...@@ -774,7 +785,7 @@ int TDBODBC::GetProgMax(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
bool TDBODBC::OpenDB(PGLOBAL g) bool TDBODBC::OpenDB(PGLOBAL g)
{ {
bool rc = false; bool rc = true;
if (g->Trace) if (g->Trace)
htrc("ODBC OpenDB: tdbp=%p tdb=R%d use=%dmode=%d\n", htrc("ODBC OpenDB: tdbp=%p tdb=R%d use=%dmode=%d\n",
...@@ -849,12 +860,12 @@ bool TDBODBC::OpenDB(PGLOBAL g) ...@@ -849,12 +860,12 @@ bool TDBODBC::OpenDB(PGLOBAL g)
} // endif Query } // endif Query
} else if (Mode == MODE_UPDATE || Mode == MODE_DELETE) } else if (Mode == MODE_UPDATE || Mode == MODE_DELETE) {
Query = MakeCommand(g); rc = false; // wait for CheckCond before calling MakeCommand(g);
else } else
sprintf(g->Message, "Invalid mode %d", Mode); sprintf(g->Message, "Invalid mode %d", Mode);
if (!Query || rc) { if (rc) {
Ocp->Close(); Ocp->Close();
return true; return true;
} // endif rc } // endif rc
...@@ -886,6 +897,9 @@ int TDBODBC::ReadDB(PGLOBAL g) ...@@ -886,6 +897,9 @@ int TDBODBC::ReadDB(PGLOBAL g)
GetTdb_No(), Mode, To_Key_Col, To_Link, To_Kindex); GetTdb_No(), Mode, To_Key_Col, To_Link, To_Kindex);
if (Mode == MODE_UPDATE || Mode == MODE_DELETE) { if (Mode == MODE_UPDATE || Mode == MODE_DELETE) {
if (!Query && !(Query = MakeCommand(g)))
return RC_FX;
// Send the UPDATE/DELETE command to the remote table // Send the UPDATE/DELETE command to the remote table
if (!Ocp->ExecSQLcommand(Query)) { if (!Ocp->ExecSQLcommand(Query)) {
sprintf(g->Message, "%s: %d affected rows", TableName, AftRows); sprintf(g->Message, "%s: %d affected rows", TableName, AftRows);
...@@ -955,6 +969,9 @@ int TDBODBC::WriteDB(PGLOBAL g) ...@@ -955,6 +969,9 @@ int TDBODBC::WriteDB(PGLOBAL g)
int TDBODBC::DeleteDB(PGLOBAL g, int irc) int TDBODBC::DeleteDB(PGLOBAL g, int irc)
{ {
if (irc == RC_FX) { if (irc == RC_FX) {
if (!Query && !(Query = MakeCommand(g)))
return RC_FX;
// Send the DELETE (all) command to the remote table // Send the DELETE (all) command to the remote table
if (!Ocp->ExecSQLcommand(Query)) { if (!Ocp->ExecSQLcommand(Query)) {
sprintf(g->Message, "%s: %d affected rows", TableName, AftRows); sprintf(g->Message, "%s: %d affected rows", TableName, AftRows);
......
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