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)
char *body= filp->Body;
unsigned int i;
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;
if (!cond)
......@@ -2536,7 +2538,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
if (trace)
htrc("Cond: Ftype=%d name=%s\n", cond_item->functype(),
cond_item->func_name());
cond_item->func_name());
switch (cond_item->functype()) {
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)
for (i= 0; i < arglist->elements; i++)
if ((subitem= li++)) {
if (!CheckCond(g, filp, tty, subitem)) {
if (vop == OP_OR)
if (vop == OP_OR || nonul)
return NULL;
else
*p2= 0;
......@@ -2651,6 +2653,8 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
if (trace) {
htrc("Field index=%d\n", pField->field->field_index);
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
// 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)
char buff[256];
String *res, tmp(buff, sizeof(buff), &my_charset_bin);
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::INT_ITEM:
case COND::REAL_ITEM:
......@@ -2696,10 +2701,64 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
if (!x) {
// Append the value to the filter
if (args[i]->field_type() == MYSQL_TYPE_VARCHAR)
strcat(strncat(strcat(body, "'"), res->ptr(), res->length()), "'");
else
strncat(body, res->ptr(), res->length());
switch (args[i]->field_type()) {
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATETIME:
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 {
if (args[i]->field_type() == MYSQL_TYPE_VARCHAR) {
......
......@@ -1740,6 +1740,8 @@ bool ODBConn::BindParam(ODBCCOL *colp)
strcpy(m_G->Message, x->GetErrorMessage(0));
colsize = colp->GetPrecision();
sqlt = GetSQLType(buftype);
dec = IsTypeChar(buftype) ? 0 : colp->GetScale();
nul = SQL_NULLABLE_UNKNOWN;
} // end try/catch
buf = colp->GetBuffer(0);
......
......@@ -573,8 +573,7 @@ bool TDBODBC::BindParameters(PGLOBAL g)
/***********************************************************************/
char *TDBODBC::MakeCommand(PGLOBAL g)
{
char *p, name[68], *qc = Ocp->GetQuoteChar();
char *stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
char *p, *stmt, name[68], *body = NULL, *qc = Ocp->GetQuoteChar();
char *qrystr = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 1);
bool qtd = Quoted > 0;
int i = 0, k = 0;
......@@ -585,6 +584,15 @@ char *TDBODBC::MakeCommand(PGLOBAL g)
qrystr[i] = (Qrystr[i] == '`') ? *qc : tolower(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
// If so, it must be quoted in the original query
strlwr(strcat(strcat(strcpy(name, " "), Name), " "));
......@@ -612,6 +620,9 @@ char *TDBODBC::MakeCommand(PGLOBAL g)
stmt[i++] = (Qrystr[k] == '`') ? *qc : Qrystr[k];
} while (Qrystr[k++]);
if (body)
strcat(stmt, body);
} else {
sprintf(g->Message, "Cannot use this %s command",
(Mode == MODE_UPDATE) ? "UPDATE" : "DELETE");
......@@ -774,7 +785,7 @@ int TDBODBC::GetProgMax(PGLOBAL g)
/***********************************************************************/
bool TDBODBC::OpenDB(PGLOBAL g)
{
bool rc = false;
bool rc = true;
if (g->Trace)
htrc("ODBC OpenDB: tdbp=%p tdb=R%d use=%dmode=%d\n",
......@@ -849,12 +860,12 @@ bool TDBODBC::OpenDB(PGLOBAL g)
} // endif Query
} else if (Mode == MODE_UPDATE || Mode == MODE_DELETE)
Query = MakeCommand(g);
else
} else if (Mode == MODE_UPDATE || Mode == MODE_DELETE) {
rc = false; // wait for CheckCond before calling MakeCommand(g);
} else
sprintf(g->Message, "Invalid mode %d", Mode);
if (!Query || rc) {
if (rc) {
Ocp->Close();
return true;
} // endif rc
......@@ -886,6 +897,9 @@ int TDBODBC::ReadDB(PGLOBAL g)
GetTdb_No(), Mode, To_Key_Col, To_Link, To_Kindex);
if (Mode == MODE_UPDATE || Mode == MODE_DELETE) {
if (!Query && !(Query = MakeCommand(g)))
return RC_FX;
// Send the UPDATE/DELETE command to the remote table
if (!Ocp->ExecSQLcommand(Query)) {
sprintf(g->Message, "%s: %d affected rows", TableName, AftRows);
......@@ -955,6 +969,9 @@ int TDBODBC::WriteDB(PGLOBAL g)
int TDBODBC::DeleteDB(PGLOBAL g, int irc)
{
if (irc == RC_FX) {
if (!Query && !(Query = MakeCommand(g)))
return RC_FX;
// Send the DELETE (all) command to the remote table
if (!Ocp->ExecSQLcommand(Query)) {
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