mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
- 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
This commit is contained in:
@@ -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)
|
||||
@@ -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
|
||||
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);
|
||||
|
Reference in New Issue
Block a user