Skip to content

Commit

Permalink
- Handle the use of date/time values when making queries for MYSQL or
Browse files Browse the repository at this point in the history
  ODBC. Was raised by 7549.
modified:
  storage/connect/ha_connect.cc
  storage/connect/odbconn.cpp
  storage/connect/tabodbc.cpp
  • Loading branch information
Buggynours committed Feb 8, 2015
1 parent 35548d5 commit 96ba1f1
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 14 deletions.
73 changes: 66 additions & 7 deletions storage/connect/ha_connect.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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:
Expand All @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions storage/connect/odbconn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
31 changes: 24 additions & 7 deletions storage/connect/tabodbc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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), " "));
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 96ba1f1

Please sign in to comment.