mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
Merge 10.0-connect -> 10.0
This commit is contained in:
@@ -166,6 +166,7 @@ my $DEFAULT_SUITES= join(',', map { "$_-" } qw(
|
|||||||
main
|
main
|
||||||
archive
|
archive
|
||||||
binlog
|
binlog
|
||||||
|
connect
|
||||||
csv
|
csv
|
||||||
federated
|
federated
|
||||||
funcs_1
|
funcs_1
|
||||||
@@ -380,7 +381,6 @@ sub main {
|
|||||||
mtr_report("Logging: $0 ", join(" ", @ARGV));
|
mtr_report("Logging: $0 ", join(" ", @ARGV));
|
||||||
|
|
||||||
$DEFAULT_SUITES.= ',' . join(',', qw(
|
$DEFAULT_SUITES.= ',' . join(',', qw(
|
||||||
connect
|
|
||||||
query_response_time
|
query_response_time
|
||||||
sequence
|
sequence
|
||||||
spider
|
spider
|
||||||
|
@@ -264,6 +264,19 @@ int main() {
|
|||||||
ENDIF(UNIX)
|
ENDIF(UNIX)
|
||||||
ENDIF(CONNECT_WITH_ODBC)
|
ENDIF(CONNECT_WITH_ODBC)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Installing tests
|
||||||
|
#
|
||||||
|
IF(INSTALL_MYSQLTESTDIR)
|
||||||
|
INSTALL(
|
||||||
|
DIRECTORY mysql-test/connect
|
||||||
|
DESTINATION ${INSTALL_MYSQLTESTDIR}/suite
|
||||||
|
USE_SOURCE_PERMISSIONS
|
||||||
|
COMPONENT Test
|
||||||
|
PATTERN "*~" EXCLUDE
|
||||||
|
)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Plugin definition
|
# Plugin definition
|
||||||
|
@@ -164,8 +164,7 @@ bool COLBLK::CheckSort(PTDB tdbp)
|
|||||||
/* Now we use Format.Length for the len parameter to avoid strings */
|
/* Now we use Format.Length for the len parameter to avoid strings */
|
||||||
/* to be truncated when converting from string to coded string. */
|
/* to be truncated when converting from string to coded string. */
|
||||||
/* Added in version 1.5 is the arguments GetPrecision() and Domain */
|
/* Added in version 1.5 is the arguments GetPrecision() and Domain */
|
||||||
/* in calling AllocateValue. Domain is used for TYPE_TOKEN only, */
|
/* in calling AllocateValue. Domain is used for TYPE_DATE only. */
|
||||||
/* but why was GetPrecision() not specified ? To be checked. */
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool COLBLK::InitValue(PGLOBAL g)
|
bool COLBLK::InitValue(PGLOBAL g)
|
||||||
{
|
{
|
||||||
@@ -174,8 +173,7 @@ bool COLBLK::InitValue(PGLOBAL g)
|
|||||||
|
|
||||||
// Allocate a Value object
|
// Allocate a Value object
|
||||||
if (!(Value = AllocateValue(g, Buf_Type, Format.Length,
|
if (!(Value = AllocateValue(g, Buf_Type, Format.Length,
|
||||||
GetPrecision(), GetDomain(),
|
GetPrecision(), GetDomain())))
|
||||||
(To_Tdb) ? To_Tdb->GetCat() : NULL)))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
AddStatus(BUF_READY);
|
AddStatus(BUF_READY);
|
||||||
|
@@ -251,7 +251,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
|
|||||||
return true;
|
return true;
|
||||||
} // endif tdbp
|
} // endif tdbp
|
||||||
|
|
||||||
tdbp->SetMode(mode);
|
//tdbp->SetMode(mode); done in ha_connect::GetTDB
|
||||||
|
|
||||||
if (!c1) {
|
if (!c1) {
|
||||||
if (mode == MODE_INSERT)
|
if (mode == MODE_INSERT)
|
||||||
@@ -498,8 +498,8 @@ RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all)
|
|||||||
|
|
||||||
if (!tdbp || tdbp->GetMode() != MODE_DELETE)
|
if (!tdbp || tdbp->GetMode() != MODE_DELETE)
|
||||||
return RC_FX;
|
return RC_FX;
|
||||||
// else
|
else if (tdbp->IsReadOnly())
|
||||||
// ((PTDBDOX)tdbp)->SetModified(true);
|
return RC_NF;
|
||||||
|
|
||||||
if (((PTDBASE)tdbp)->GetDef()->Indexable() && all)
|
if (((PTDBASE)tdbp)->GetDef()->Indexable() && all)
|
||||||
((PTDBDOS)tdbp)->Cardinal= 0;
|
((PTDBDOS)tdbp)->Cardinal= 0;
|
||||||
@@ -518,17 +518,13 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
|
|||||||
int rc= RC_OK;
|
int rc= RC_OK;
|
||||||
TDBDOX *tbxp= NULL;
|
TDBDOX *tbxp= NULL;
|
||||||
|
|
||||||
if (!tdbp)
|
if (!tdbp || tdbp->GetUse() != USE_OPEN)
|
||||||
return rc; // Already done
|
return rc; // Nothing to do
|
||||||
|
|
||||||
if (xtrace)
|
if (xtrace)
|
||||||
printf("CntCloseTable: tdbp=%p mode=%d\n", tdbp, tdbp->GetMode());
|
printf("CntCloseTable: tdbp=%p mode=%d\n", tdbp, tdbp->GetMode());
|
||||||
|
|
||||||
/*********************************************************************/
|
if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN)
|
||||||
/* This will close the table file(s) and also finalize write */
|
|
||||||
/* operations such as Insert, Update, or Delete. */
|
|
||||||
/*********************************************************************/
|
|
||||||
if (tdbp->GetMode() == MODE_DELETE)
|
|
||||||
rc= tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine
|
rc= tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine
|
||||||
|
|
||||||
// Prepare error return
|
// Prepare error return
|
||||||
@@ -543,6 +539,8 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
|
|||||||
goto err;
|
goto err;
|
||||||
} // endif
|
} // endif
|
||||||
|
|
||||||
|
// This will close the table file(s) and also finalize write
|
||||||
|
// operations such as Insert, Update, or Delete.
|
||||||
tdbp->CloseDB(g);
|
tdbp->CloseDB(g);
|
||||||
|
|
||||||
g->jump_level--;
|
g->jump_level--;
|
||||||
|
@@ -17,8 +17,6 @@ typedef class BLKFAM *PBLKFAM;
|
|||||||
typedef class DOSDEF *PDOSDEF;
|
typedef class DOSDEF *PDOSDEF;
|
||||||
typedef class TDBDOS *PTDBDOS;
|
typedef class TDBDOS *PTDBDOS;
|
||||||
|
|
||||||
#define TYPE_AM_BLK (AMT)160
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* This is the base class for all file access method classes. */
|
/* This is the base class for all file access method classes. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -91,7 +91,7 @@ typedef struct _vecheader {
|
|||||||
/* Conversion of block values allowed conditionally for insert only. */
|
/* Conversion of block values allowed conditionally for insert only. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PVBLK AllocValBlock(PGLOBAL, void *, int, int, int, int,
|
PVBLK AllocValBlock(PGLOBAL, void *, int, int, int, int,
|
||||||
bool check = true, bool blank = true);
|
bool check = true, bool blank = true, bool un = false);
|
||||||
|
|
||||||
/* -------------------------- Class VCTFAM --------------------------- */
|
/* -------------------------- Class VCTFAM --------------------------- */
|
||||||
|
|
||||||
|
@@ -10,9 +10,6 @@
|
|||||||
|
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
|
|
||||||
#define TYPE_AM_ZIP (AMT)150
|
|
||||||
#define TYPE_AM_ZLIB (AMT)155
|
|
||||||
|
|
||||||
typedef class ZIPFAM *PZIPFAM;
|
typedef class ZIPFAM *PZIPFAM;
|
||||||
typedef class ZBKFAM *PZBKFAM;
|
typedef class ZBKFAM *PZBKFAM;
|
||||||
typedef class ZIXFAM *PZIXFAM;
|
typedef class ZIXFAM *PZIXFAM;
|
||||||
|
@@ -165,7 +165,7 @@ extern "C" char nmfile[];
|
|||||||
extern "C" char pdebug[];
|
extern "C" char pdebug[];
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
char version[]= "Version 1.01.0008 August 18, 2013";
|
char version[]= "Version 1.01.0009 October 29, 2013";
|
||||||
|
|
||||||
#if defined(XMSG)
|
#if defined(XMSG)
|
||||||
char msglang[]; // Default message language
|
char msglang[]; // Default message language
|
||||||
@@ -183,7 +183,7 @@ ulong ha_connect::num= 0;
|
|||||||
//int DTVAL::Shift= 0;
|
//int DTVAL::Shift= 0;
|
||||||
|
|
||||||
static PCONNECT GetUser(THD *thd, PCONNECT xp);
|
static PCONNECT GetUser(THD *thd, PCONNECT xp);
|
||||||
static PGLOBAL GetPlug(THD *thd, PCONNECT lxp);
|
static PGLOBAL GetPlug(THD *thd, PCONNECT& lxp);
|
||||||
|
|
||||||
static handler *connect_create_handler(handlerton *hton,
|
static handler *connect_create_handler(handlerton *hton,
|
||||||
TABLE_SHARE *table,
|
TABLE_SHARE *table,
|
||||||
@@ -258,17 +258,21 @@ ha_create_table_option connect_field_option_list[]=
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Push G->Message as a MySQL warning. */
|
/* Push G->Message as a MySQL warning. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool PushWarning(PGLOBAL g, PTDBASE tdbp)
|
bool PushWarning(PGLOBAL g, PTDBASE tdbp, int level)
|
||||||
{
|
{
|
||||||
PHC phc;
|
PHC phc;
|
||||||
THD *thd;
|
THD *thd;
|
||||||
MYCAT *cat= (MYCAT*)tdbp->GetDef()->GetCat();
|
MYCAT *cat= (MYCAT*)tdbp->GetDef()->GetCat();
|
||||||
|
Sql_condition::enum_warning_level wlvl;
|
||||||
|
|
||||||
|
|
||||||
if (!cat || !(phc= cat->GetHandler()) || !phc->GetTable() ||
|
if (!cat || !(phc= cat->GetHandler()) || !phc->GetTable() ||
|
||||||
!(thd= (phc->GetTable())->in_use))
|
!(thd= (phc->GetTable())->in_use))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
|
//push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
|
||||||
|
wlvl= (Sql_condition::enum_warning_level)level;
|
||||||
|
push_warning(thd, wlvl, 0, g->Message);
|
||||||
return false;
|
return false;
|
||||||
} // end of PushWarning
|
} // end of PushWarning
|
||||||
|
|
||||||
@@ -552,7 +556,7 @@ static PCONNECT GetUser(THD *thd, PCONNECT xp)
|
|||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/* Get the global pointer of the user of this handler. */
|
/* Get the global pointer of the user of this handler. */
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
static PGLOBAL GetPlug(THD *thd, PCONNECT lxp)
|
static PGLOBAL GetPlug(THD *thd, PCONNECT& lxp)
|
||||||
{
|
{
|
||||||
lxp= GetUser(thd, lxp);
|
lxp= GetUser(thd, lxp);
|
||||||
return (lxp) ? lxp->g : NULL;
|
return (lxp) ? lxp->g : NULL;
|
||||||
@@ -659,6 +663,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);
|
||||||
@@ -1096,19 +1102,20 @@ PTDB ha_connect::GetTDB(PGLOBAL g)
|
|||||||
&& (tdbp->GetMode() == xmod
|
&& (tdbp->GetMode() == xmod
|
||||||
|| tdbp->GetAmType() == TYPE_AM_XML)) {
|
|| tdbp->GetAmType() == TYPE_AM_XML)) {
|
||||||
tp= tdbp;
|
tp= tdbp;
|
||||||
tp->SetMode(xmod);
|
// tp->SetMode(xmod);
|
||||||
} else if ((tp= CntGetTDB(g, table_name, xmod, this)))
|
} else if ((tp= CntGetTDB(g, table_name, xmod, this)))
|
||||||
valid_query_id= xp->last_query_id;
|
valid_query_id= xp->last_query_id;
|
||||||
else
|
else
|
||||||
printf("GetTDB: %s\n", g->Message);
|
printf("GetTDB: %s\n", g->Message);
|
||||||
|
|
||||||
|
tp->SetMode(xmod);
|
||||||
return tp;
|
return tp;
|
||||||
} // end of GetTDB
|
} // end of GetTDB
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/* Open a CONNECT table, restricting column list if cols is true. */
|
/* Open a CONNECT table, restricting column list if cols is true. */
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
bool ha_connect::OpenTable(PGLOBAL g, bool del)
|
int ha_connect::OpenTable(PGLOBAL g, bool del)
|
||||||
{
|
{
|
||||||
bool rc= false;
|
bool rc= false;
|
||||||
char *c1= NULL, *c2=NULL;
|
char *c1= NULL, *c2=NULL;
|
||||||
@@ -1116,11 +1123,11 @@ bool ha_connect::OpenTable(PGLOBAL g, bool del)
|
|||||||
// Double test to be on the safe side
|
// Double test to be on the safe side
|
||||||
if (!g || !table) {
|
if (!g || !table) {
|
||||||
printf("OpenTable logical error; g=%p table=%p\n", g, table);
|
printf("OpenTable logical error; g=%p table=%p\n", g, table);
|
||||||
return true;
|
return HA_ERR_INITIALIZATION;
|
||||||
} // endif g
|
} // endif g
|
||||||
|
|
||||||
if (!(tdbp= GetTDB(g)))
|
if (!(tdbp= GetTDB(g)))
|
||||||
return true;
|
return RC_FX;
|
||||||
else if (tdbp->IsReadOnly())
|
else if (tdbp->IsReadOnly())
|
||||||
switch (xmod) {
|
switch (xmod) {
|
||||||
case MODE_WRITE:
|
case MODE_WRITE:
|
||||||
@@ -1128,7 +1135,7 @@ bool ha_connect::OpenTable(PGLOBAL g, bool del)
|
|||||||
case MODE_UPDATE:
|
case MODE_UPDATE:
|
||||||
case MODE_DELETE:
|
case MODE_DELETE:
|
||||||
strcpy(g->Message, MSG(READ_ONLY));
|
strcpy(g->Message, MSG(READ_ONLY));
|
||||||
return true;
|
return HA_ERR_TABLE_READONLY;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
} // endswitch xmode
|
} // endswitch xmode
|
||||||
@@ -1205,7 +1212,7 @@ bool ha_connect::OpenTable(PGLOBAL g, bool del)
|
|||||||
valid_info= false;
|
valid_info= false;
|
||||||
} // endif rc
|
} // endif rc
|
||||||
|
|
||||||
return rc;
|
return (rc) ? HA_ERR_INITIALIZATION : 0;
|
||||||
} // end of OpenTable
|
} // end of OpenTable
|
||||||
|
|
||||||
|
|
||||||
@@ -1239,15 +1246,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 +1271,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++) {
|
||||||
@@ -1300,6 +1308,9 @@ int ha_connect::MakeRecord(char *buf)
|
|||||||
case MYSQL_TYPE_TIME:
|
case MYSQL_TYPE_TIME:
|
||||||
fmt= "%H:%M:%S";
|
fmt= "%H:%M:%S";
|
||||||
break;
|
break;
|
||||||
|
case MYSQL_TYPE_YEAR:
|
||||||
|
fmt= "%Y";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fmt= "%Y-%m-%d %H:%M:%S";
|
fmt= "%Y-%m-%d %H:%M:%S";
|
||||||
break;
|
break;
|
||||||
@@ -1401,24 +1412,25 @@ int ha_connect::ScanRecord(PGLOBAL g, uchar *buf)
|
|||||||
value->SetValue(fp->val_real());
|
value->SetValue(fp->val_real());
|
||||||
break;
|
break;
|
||||||
case TYPE_DATE:
|
case TYPE_DATE:
|
||||||
if (!sdvalin) {
|
if (!sdvalin)
|
||||||
sdvalin= (DTVAL*)AllocateValue(xp->g, TYPE_DATE, 19);
|
sdvalin= (DTVAL*)AllocateValue(xp->g, TYPE_DATE, 19);
|
||||||
|
|
||||||
// Get date in the format produced by MySQL fields
|
// Get date in the format produced by MySQL fields
|
||||||
switch (fp->type()) {
|
switch (fp->type()) {
|
||||||
case MYSQL_TYPE_DATE:
|
case MYSQL_TYPE_DATE:
|
||||||
fmt= "YYYY-MM-DD";
|
fmt= "YYYY-MM-DD";
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_TIME:
|
case MYSQL_TYPE_TIME:
|
||||||
fmt= "hh:mm:ss";
|
fmt= "hh:mm:ss";
|
||||||
break;
|
break;
|
||||||
default:
|
case MYSQL_TYPE_YEAR:
|
||||||
fmt= "YYYY-MM-DD hh:mm:ss";
|
fmt= "YYYY";
|
||||||
} // endswitch type
|
break;
|
||||||
|
default:
|
||||||
((DTVAL*)sdvalin)->SetFormat(g, fmt, strlen(fmt));
|
fmt= "YYYY-MM-DD hh:mm:ss";
|
||||||
} // endif sdvalin
|
} // endswitch type
|
||||||
|
|
||||||
|
((DTVAL*)sdvalin)->SetFormat(g, fmt, strlen(fmt));
|
||||||
fp->val_str(&attribute);
|
fp->val_str(&attribute);
|
||||||
sdvalin->SetValue_psz(attribute.c_ptr_safe());
|
sdvalin->SetValue_psz(attribute.c_ptr_safe());
|
||||||
value->SetValue_pval(sdvalin);
|
value->SetValue_pval(sdvalin);
|
||||||
@@ -1557,8 +1569,9 @@ const char *ha_connect::GetValStr(OPVAL vop, bool neg)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
|
PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
|
||||||
{
|
{
|
||||||
|
char *body= filp->Body;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
bool ismul= false;
|
bool ismul= false, x= (tty == TYPE_AM_MYX || tty == TYPE_AM_XDBC);
|
||||||
PPARM pfirst= NULL, pprec= NULL, pp[2]= {NULL, NULL};
|
PPARM pfirst= NULL, pprec= NULL, pp[2]= {NULL, NULL};
|
||||||
OPVAL vop= OP_XX;
|
OPVAL vop= OP_XX;
|
||||||
|
|
||||||
@@ -1572,6 +1585,9 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
|
|||||||
char *p1, *p2;
|
char *p1, *p2;
|
||||||
Item_cond *cond_item= (Item_cond *)cond;
|
Item_cond *cond_item= (Item_cond *)cond;
|
||||||
|
|
||||||
|
if (x)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (xtrace > 1)
|
if (xtrace > 1)
|
||||||
printf("Cond: Ftype=%d name=%s\n", cond_item->functype(),
|
printf("Cond: Ftype=%d name=%s\n", cond_item->functype(),
|
||||||
cond_item->func_name());
|
cond_item->func_name());
|
||||||
@@ -1586,7 +1602,7 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
|
|||||||
List_iterator<Item> li(*arglist);
|
List_iterator<Item> li(*arglist);
|
||||||
Item *subitem;
|
Item *subitem;
|
||||||
|
|
||||||
p1= filp + strlen(filp);
|
p1= body + strlen(body);
|
||||||
strcpy(p1, "(");
|
strcpy(p1, "(");
|
||||||
p2= p1 + 1;
|
p2= p1 + 1;
|
||||||
|
|
||||||
@@ -1615,7 +1631,7 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
|
|||||||
} else if (cond->type() == COND::FUNC_ITEM) {
|
} else if (cond->type() == COND::FUNC_ITEM) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
// int n;
|
// int n;
|
||||||
bool iscol, neg= FALSE;
|
bool iscol, neg= FALSE;
|
||||||
Item_func *condf= (Item_func *)cond;
|
Item_func *condf= (Item_func *)cond;
|
||||||
Item* *args= condf->arguments();
|
Item* *args= condf->arguments();
|
||||||
|
|
||||||
@@ -1644,6 +1660,9 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
|
|||||||
else if (ismul && tty == TYPE_AM_WMI)
|
else if (ismul && tty == TYPE_AM_WMI)
|
||||||
return NULL; // Not supported by WQL
|
return NULL; // Not supported by WQL
|
||||||
|
|
||||||
|
if (x && (neg || !(vop == OP_EQ || vop == OP_IN)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
for (i= 0; i < condf->argument_count(); i++) {
|
for (i= 0; i < condf->argument_count(); i++) {
|
||||||
if (xtrace > 1)
|
if (xtrace > 1)
|
||||||
printf("Argtype(%d)=%d\n", i, args[i]->type());
|
printf("Argtype(%d)=%d\n", i, args[i]->type());
|
||||||
@@ -1660,6 +1679,9 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
|
|||||||
ha_field_option_struct *fop;
|
ha_field_option_struct *fop;
|
||||||
Item_field *pField= (Item_field *)args[i];
|
Item_field *pField= (Item_field *)args[i];
|
||||||
|
|
||||||
|
if (x && i)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (pField->field->table != table)
|
if (pField->field->table != table)
|
||||||
return NULL; // Field does not belong to this table
|
return NULL; // Field does not belong to this table
|
||||||
else
|
else
|
||||||
@@ -1685,10 +1707,10 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
|
|||||||
if (i && ismul)
|
if (i && ismul)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
strcat(filp, fnm);
|
strcat(body, fnm);
|
||||||
} else {
|
} else {
|
||||||
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];
|
||||||
|
|
||||||
if ((res= pval->val_str(&tmp)) == NULL)
|
if ((res= pval->val_str(&tmp)) == NULL)
|
||||||
@@ -1698,26 +1720,46 @@ PFIL ha_connect::CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond)
|
|||||||
printf("Value=%.*s\n", res->length(), res->ptr());
|
printf("Value=%.*s\n", res->length(), res->ptr());
|
||||||
|
|
||||||
// IN and BETWEEN clauses should be col VOP list
|
// IN and BETWEEN clauses should be col VOP list
|
||||||
if (!i && ismul)
|
if (!i && (x || ismul))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// Append the value to the filter
|
if (!x) {
|
||||||
if (args[i]->type() == COND::STRING_ITEM)
|
// Append the value to the filter
|
||||||
strcat(strcat(strcat(filp, "'"), res->ptr()), "'");
|
if (args[i]->field_type() == MYSQL_TYPE_VARCHAR)
|
||||||
else
|
strcat(strcat(strcat(body, "'"), res->ptr()), "'");
|
||||||
strncat(filp, res->ptr(), res->length());
|
else
|
||||||
|
strncat(body, res->ptr(), res->length());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (args[i]->field_type() == MYSQL_TYPE_VARCHAR) {
|
||||||
|
// Add the command to the list
|
||||||
|
PCMD *ncp, cmdp= new(g) CMD(g, (char*)res->ptr());
|
||||||
|
|
||||||
|
for (ncp= &filp->Cmds; *ncp; ncp= &(*ncp)->Next) ;
|
||||||
|
|
||||||
|
*ncp= cmdp;
|
||||||
|
} else
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} // endif x
|
||||||
|
|
||||||
} // endif
|
} // endif
|
||||||
|
|
||||||
if (!i)
|
if (!x) {
|
||||||
strcat(filp, GetValStr(vop, neg));
|
if (!i)
|
||||||
else if (vop == OP_XX && i == 1)
|
strcat(body, GetValStr(vop, neg));
|
||||||
strcat(filp, " AND ");
|
else if (vop == OP_XX && i == 1)
|
||||||
else if (vop == OP_IN)
|
strcat(body, " AND ");
|
||||||
strcat(filp, (i == condf->argument_count() - 1) ? ")" : ",");
|
else if (vop == OP_IN)
|
||||||
|
strcat(body, (i == condf->argument_count() - 1) ? ")" : ",");
|
||||||
|
|
||||||
|
} // endif x
|
||||||
|
|
||||||
} // endfor i
|
} // endfor i
|
||||||
|
|
||||||
|
if (x)
|
||||||
|
filp->Op= vop;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (xtrace > 1)
|
if (xtrace > 1)
|
||||||
printf("Unsupported condition\n");
|
printf("Unsupported condition\n");
|
||||||
@@ -1753,23 +1795,31 @@ const COND *ha_connect::cond_push(const COND *cond)
|
|||||||
DBUG_ENTER("ha_connect::cond_push");
|
DBUG_ENTER("ha_connect::cond_push");
|
||||||
|
|
||||||
if (tdbp) {
|
if (tdbp) {
|
||||||
AMT tty= tdbp->GetAmType();
|
AMT tty= tdbp->GetAmType();
|
||||||
|
bool x= (tty == TYPE_AM_MYX || tty == TYPE_AM_XDBC);
|
||||||
|
|
||||||
if (tty == TYPE_AM_WMI || tty == TYPE_AM_ODBC ||
|
if (tty == TYPE_AM_WMI || tty == TYPE_AM_ODBC ||
|
||||||
tty == TYPE_AM_TBL || tty == TYPE_AM_MYSQL) {
|
tty == TYPE_AM_TBL || tty == TYPE_AM_MYSQL || x) {
|
||||||
PGLOBAL& g= xp->g;
|
PGLOBAL& g= xp->g;
|
||||||
PFIL filp= (PFIL)PlugSubAlloc(g, NULL, 0);
|
PFIL filp= (PFIL)PlugSubAlloc(g, NULL, sizeof(FILTER));
|
||||||
|
|
||||||
*filp= 0;
|
filp->Body= (char*)PlugSubAlloc(g, NULL, (x) ? 128 : 0);
|
||||||
|
*filp->Body= 0;
|
||||||
|
filp->Op= OP_XX;
|
||||||
|
filp->Cmds= NULL;
|
||||||
|
|
||||||
if (CheckCond(g, filp, tty, (Item *)cond)) {
|
if (CheckCond(g, filp, tty, (Item *)cond)) {
|
||||||
if (xtrace)
|
if (xtrace)
|
||||||
puts(filp);
|
puts(filp->Body);
|
||||||
|
|
||||||
|
if (!x)
|
||||||
|
PlugSubAlloc(g, NULL, strlen(filp->Body) + 1);
|
||||||
|
else
|
||||||
|
cond= NULL; // Does this work?
|
||||||
|
|
||||||
tdbp->SetFilter(filp);
|
tdbp->SetFilter(filp);
|
||||||
// cond= NULL; // This does not work anyway
|
} else if (x && cond)
|
||||||
PlugSubAlloc(g, NULL, strlen(filp) + 1);
|
tdbp->SetFilter(filp); // Wrong filter
|
||||||
} // endif filp
|
|
||||||
|
|
||||||
} // endif tty
|
} // endif tty
|
||||||
|
|
||||||
@@ -1965,14 +2015,8 @@ int ha_connect::write_row(uchar *buf)
|
|||||||
if (IsOpened())
|
if (IsOpened())
|
||||||
CloseTable(g);
|
CloseTable(g);
|
||||||
|
|
||||||
if (OpenTable(g)) {
|
if ((rc= OpenTable(g)))
|
||||||
if (strstr(g->Message, "read only"))
|
|
||||||
rc= HA_ERR_TABLE_READONLY;
|
|
||||||
else
|
|
||||||
rc= HA_ERR_INITIALIZATION;
|
|
||||||
|
|
||||||
DBUG_RETURN(rc);
|
DBUG_RETURN(rc);
|
||||||
} // endif tdbp
|
|
||||||
|
|
||||||
} // endif isopened
|
} // endif isopened
|
||||||
|
|
||||||
@@ -2337,6 +2381,7 @@ int ha_connect::index_next_same(uchar *buf, const uchar *key, uint keylen)
|
|||||||
*/
|
*/
|
||||||
int ha_connect::rnd_init(bool scan)
|
int ha_connect::rnd_init(bool scan)
|
||||||
{
|
{
|
||||||
|
int rc;
|
||||||
PGLOBAL g= ((table && table->in_use) ? GetPlug(table->in_use, xp) :
|
PGLOBAL g= ((table && table->in_use) ? GetPlug(table->in_use, xp) :
|
||||||
(xp) ? xp->g : NULL);
|
(xp) ? xp->g : NULL);
|
||||||
DBUG_ENTER("ha_connect::rnd_init");
|
DBUG_ENTER("ha_connect::rnd_init");
|
||||||
@@ -2344,18 +2389,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 ((rc= OpenTable(g, xmod == MODE_DELETE)))
|
||||||
|
DBUG_RETURN(rc);
|
||||||
|
|
||||||
xp->nrd= xp->fnd= xp->nfd= 0;
|
xp->nrd= xp->fnd= xp->nfd= 0;
|
||||||
xp->tb1= my_interval_timer();
|
xp->tb1= my_interval_timer();
|
||||||
@@ -2566,7 +2614,6 @@ int ha_connect::info(uint flag)
|
|||||||
xp->CheckCleanup();
|
xp->CheckCleanup();
|
||||||
} // endif xmod
|
} // endif xmod
|
||||||
|
|
||||||
// tdbp= OpenTable(g, xmod == MODE_DELETE);
|
|
||||||
tdbp= GetTDB(g);
|
tdbp= GetTDB(g);
|
||||||
} // endif tdbp
|
} // endif tdbp
|
||||||
|
|
||||||
@@ -2661,18 +2708,19 @@ int ha_connect::delete_all_rows()
|
|||||||
PGLOBAL g= xp->g;
|
PGLOBAL g= xp->g;
|
||||||
DBUG_ENTER("ha_connect::delete_all_rows");
|
DBUG_ENTER("ha_connect::delete_all_rows");
|
||||||
|
|
||||||
if (tdbp && tdbp->GetAmType() != TYPE_AM_XML)
|
if (tdbp && tdbp->GetUse() == USE_OPEN &&
|
||||||
|
tdbp->GetAmType() != TYPE_AM_XML &&
|
||||||
|
((PTDBASE)tdbp)->GetFtype() != RECFM_NAF)
|
||||||
// Close and reopen the table so it will be deleted
|
// Close and reopen the table so it will be deleted
|
||||||
rc= CloseTable(g);
|
rc= CloseTable(g);
|
||||||
|
|
||||||
if (!(OpenTable(g))) {
|
if (!(rc= OpenTable(g))) {
|
||||||
if (CntDeleteRow(g, tdbp, true)) {
|
if (CntDeleteRow(g, tdbp, true)) {
|
||||||
printf("%s\n", g->Message);
|
printf("%s\n", g->Message);
|
||||||
rc= HA_ERR_INTERNAL_ERROR;
|
rc= HA_ERR_INTERNAL_ERROR;
|
||||||
} // endif
|
} // endif
|
||||||
|
|
||||||
} else
|
} // endif rc
|
||||||
rc= HA_ERR_INITIALIZATION;
|
|
||||||
|
|
||||||
DBUG_RETURN(rc);
|
DBUG_RETURN(rc);
|
||||||
} // end of delete_all_rows
|
} // end of delete_all_rows
|
||||||
@@ -3461,12 +3509,13 @@ static bool add_fields(PGLOBAL g,
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
} // end of add_fields
|
} // end of add_fields
|
||||||
#else // !NEW_WAY
|
#else // !NEW_WAY
|
||||||
static bool add_field(String *sql, const char *field_name, int typ, int len,
|
static bool add_field(String *sql, const char *field_name, int typ,
|
||||||
int dec, uint tm, const char *rem, int flag, bool dbf)
|
int len, int dec, uint tm, const char *rem,
|
||||||
|
int flag, bool dbf, char v)
|
||||||
{
|
{
|
||||||
|
char var = (len > 255) ? 'V' : v;
|
||||||
bool error= false;
|
bool error= false;
|
||||||
const char *type= PLGtoMYSQLtype(typ, dbf);
|
const char *type= PLGtoMYSQLtype(typ, dbf, var);
|
||||||
// type= PLGtoMYSQLtype(typ, true); ?????
|
|
||||||
|
|
||||||
error|= sql->append('`');
|
error|= sql->append('`');
|
||||||
error|= sql->append(field_name);
|
error|= sql->append(field_name);
|
||||||
@@ -3479,7 +3528,8 @@ static bool add_field(String *sql, const char *field_name, int typ, int len,
|
|||||||
|
|
||||||
if (!strcmp(type, "DOUBLE")) {
|
if (!strcmp(type, "DOUBLE")) {
|
||||||
error|= sql->append(',');
|
error|= sql->append(',');
|
||||||
error|= sql->append_ulonglong(dec);
|
// dec must be <= len and <= 31
|
||||||
|
error|= sql->append_ulonglong(min(dec, (len - 1)));
|
||||||
} // endif dec
|
} // endif dec
|
||||||
|
|
||||||
error|= sql->append(')');
|
error|= sql->append(')');
|
||||||
@@ -3518,6 +3568,8 @@ static int init_table_share(THD *thd,
|
|||||||
HA_CREATE_INFO *create_info,
|
HA_CREATE_INFO *create_info,
|
||||||
Alter_info *alter_info)
|
Alter_info *alter_info)
|
||||||
{
|
{
|
||||||
|
KEY *not_used_1;
|
||||||
|
uint not_used_2;
|
||||||
int rc= 0;
|
int rc= 0;
|
||||||
handler *file;
|
handler *file;
|
||||||
LEX_CUSTRING frm= {0,0};
|
LEX_CUSTRING frm= {0,0};
|
||||||
@@ -3577,9 +3629,8 @@ static int init_table_share(THD *thd,
|
|||||||
tmp_disable_binlog(thd);
|
tmp_disable_binlog(thd);
|
||||||
|
|
||||||
file= mysql_create_frm_image(thd, table_s->db.str, table_s->table_name.str,
|
file= mysql_create_frm_image(thd, table_s->db.str, table_s->table_name.str,
|
||||||
create_info, alter_info,
|
create_info, alter_info, C_ORDINARY_CREATE,
|
||||||
// &thd->lex->create_info, &thd->lex->alter_info,
|
¬_used_1, ¬_used_2, &frm);
|
||||||
C_ORDINARY_CREATE, &frm);
|
|
||||||
if (file)
|
if (file)
|
||||||
delete file;
|
delete file;
|
||||||
else
|
else
|
||||||
@@ -3772,13 +3823,14 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
TABTYPE ttp= TAB_UNDEF;
|
TABTYPE ttp= TAB_UNDEF;
|
||||||
PQRYRES qrp= NULL;
|
PQRYRES qrp= NULL;
|
||||||
PCOLRES crp;
|
PCOLRES crp;
|
||||||
PGLOBAL g= GetPlug(thd, NULL);
|
PCONNECT xp= NULL;
|
||||||
|
PGLOBAL g= GetPlug(thd, xp);
|
||||||
PTOS topt= table_s->option_struct;
|
PTOS topt= table_s->option_struct;
|
||||||
#if defined(NEW_WAY)
|
#if defined(NEW_WAY)
|
||||||
//CHARSET_INFO *cs;
|
//CHARSET_INFO *cs;
|
||||||
Alter_info alter_info;
|
Alter_info alter_info;
|
||||||
#else // !NEW_WAY
|
#else // !NEW_WAY
|
||||||
char buf[1024];
|
char v, buf[1024];
|
||||||
String sql(buf, sizeof(buf), system_charset_info);
|
String sql(buf, sizeof(buf), system_charset_info);
|
||||||
|
|
||||||
sql.copy(STRING_WITH_LEN("CREATE TABLE whatever ("), system_charset_info);
|
sql.copy(STRING_WITH_LEN("CREATE TABLE whatever ("), system_charset_info);
|
||||||
@@ -3821,7 +3873,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
port= atoi(GetListOption(g, "port", topt->oplist, "0"));
|
port= atoi(GetListOption(g, "port", topt->oplist, "0"));
|
||||||
mxr= atoi(GetListOption(g,"maxerr", topt->oplist, "0"));
|
mxr= atoi(GetListOption(g,"maxerr", topt->oplist, "0"));
|
||||||
|
#if defined(PROMPT_OK)
|
||||||
cop= atoi(GetListOption(g, "checkdsn", topt->oplist, "0"));
|
cop= atoi(GetListOption(g, "checkdsn", topt->oplist, "0"));
|
||||||
|
#endif // PROMPT_OK
|
||||||
} else {
|
} else {
|
||||||
host= "localhost";
|
host= "localhost";
|
||||||
user= "root";
|
user= "root";
|
||||||
@@ -3879,14 +3933,16 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
case TAB_ODBC:
|
case TAB_ODBC:
|
||||||
dsn= create_info->connect_string.str;
|
dsn= create_info->connect_string.str;
|
||||||
|
|
||||||
if (fnc & (FNC_DSN | FNC_DRIVER))
|
if (fnc & (FNC_DSN | FNC_DRIVER)) {
|
||||||
ok= true;
|
ok= true;
|
||||||
else if (!stricmp(thd->main_security_ctx.host, "localhost")
|
#if defined(PROMPT_OK)
|
||||||
|
} else if (!stricmp(thd->main_security_ctx.host, "localhost")
|
||||||
&& cop == 1) {
|
&& cop == 1) {
|
||||||
if ((dsn = ODBCCheckConnection(g, dsn, cop)) != NULL) {
|
if ((dsn = ODBCCheckConnection(g, dsn, cop)) != NULL) {
|
||||||
thd->make_lex_string(&create_info->connect_string, dsn, strlen(dsn));
|
thd->make_lex_string(&create_info->connect_string, dsn, strlen(dsn));
|
||||||
ok= true;
|
ok= true;
|
||||||
} // endif dsn
|
} // endif dsn
|
||||||
|
#endif // PROMPT_OK
|
||||||
|
|
||||||
} else if (!dsn)
|
} else if (!dsn)
|
||||||
sprintf(g->Message, "Missing %s connection string", topt->type);
|
sprintf(g->Message, "Missing %s connection string", topt->type);
|
||||||
@@ -4098,7 +4154,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
NOT_NULL_FLAG, "", flg, dbf);
|
NOT_NULL_FLAG, "", flg, dbf);
|
||||||
#else // !NEW_WAY
|
#else // !NEW_WAY
|
||||||
// Now add the field
|
// Now add the field
|
||||||
if (add_field(&sql, cnm, typ, len, dec, NOT_NULL_FLAG, 0, flg, dbf))
|
if (add_field(&sql, cnm, typ, len, dec, NOT_NULL_FLAG, 0, flg, dbf, 0))
|
||||||
rc= HA_ERR_OUT_OF_MEM;
|
rc= HA_ERR_OUT_OF_MEM;
|
||||||
#endif // !NEW_WAY
|
#endif // !NEW_WAY
|
||||||
} // endfor crp
|
} // endfor crp
|
||||||
@@ -4122,6 +4178,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
break;
|
break;
|
||||||
case FLD_TYPE:
|
case FLD_TYPE:
|
||||||
typ= crp->Kdata->GetIntValue(i);
|
typ= crp->Kdata->GetIntValue(i);
|
||||||
|
v = (crp->Nulls) ? crp->Nulls[i] : 0;
|
||||||
break;
|
break;
|
||||||
case FLD_PREC:
|
case FLD_PREC:
|
||||||
len= crp->Kdata->GetIntValue(i);
|
len= crp->Kdata->GetIntValue(i);
|
||||||
@@ -4152,7 +4209,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
int plgtyp;
|
int plgtyp;
|
||||||
|
|
||||||
// typ must be PLG type, not SQL type
|
// typ must be PLG type, not SQL type
|
||||||
if (!(plgtyp= TranslateSQLType(typ, dec, len))) {
|
if (!(plgtyp= TranslateSQLType(typ, dec, len, v))) {
|
||||||
sprintf(g->Message, "Unsupported SQL type %d", typ);
|
sprintf(g->Message, "Unsupported SQL type %d", typ);
|
||||||
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
||||||
return HA_ERR_INTERNAL_ERROR;
|
return HA_ERR_INTERNAL_ERROR;
|
||||||
@@ -4177,7 +4234,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
rc= add_fields(g, thd, &alter_info, cnm, typ, len, dec,
|
rc= add_fields(g, thd, &alter_info, cnm, typ, len, dec,
|
||||||
tm, rem, 0, true);
|
tm, rem, 0, true);
|
||||||
#else // !NEW_WAY
|
#else // !NEW_WAY
|
||||||
if (add_field(&sql, cnm, typ, len, dec, tm, rem, 0, true))
|
if (add_field(&sql, cnm, typ, len, dec, tm, rem, 0, dbf, v))
|
||||||
rc= HA_ERR_OUT_OF_MEM;
|
rc= HA_ERR_OUT_OF_MEM;
|
||||||
#endif // !NEW_WAY
|
#endif // !NEW_WAY
|
||||||
} // endfor i
|
} // endfor i
|
||||||
@@ -4671,6 +4728,6 @@ maria_declare_plugin(connect)
|
|||||||
NULL, /* status variables */
|
NULL, /* status variables */
|
||||||
NULL, /* system variables */
|
NULL, /* system variables */
|
||||||
"0.1", /* string version */
|
"0.1", /* string version */
|
||||||
MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */
|
MariaDB_PLUGIN_MATURITY_ALPHA /* maturity */
|
||||||
}
|
}
|
||||||
maria_declare_plugin_end;
|
maria_declare_plugin_end;
|
||||||
|
@@ -174,7 +174,7 @@ public:
|
|||||||
bool IsSameIndex(PIXDEF xp1, PIXDEF xp2);
|
bool IsSameIndex(PIXDEF xp1, PIXDEF xp2);
|
||||||
|
|
||||||
PTDB GetTDB(PGLOBAL g);
|
PTDB GetTDB(PGLOBAL g);
|
||||||
bool OpenTable(PGLOBAL g, bool del= false);
|
int OpenTable(PGLOBAL g, bool del= false);
|
||||||
bool IsOpened(void);
|
bool IsOpened(void);
|
||||||
int CloseTable(PGLOBAL g);
|
int CloseTable(PGLOBAL g);
|
||||||
int MakeRecord(char *buf);
|
int MakeRecord(char *buf);
|
||||||
|
@@ -8,6 +8,9 @@
|
|||||||
#include <libxml/tree.h>
|
#include <libxml/tree.h>
|
||||||
#include <libxml/xpath.h>
|
#include <libxml/xpath.h>
|
||||||
#include <libxml/xpathInternals.h>
|
#include <libxml/xpathInternals.h>
|
||||||
|
#include <libxml/catalog.h>
|
||||||
|
#include <libxml/xmlschemastypes.h>
|
||||||
|
#include <libxml/relaxng.h>
|
||||||
//#if defined(WIN32)
|
//#if defined(WIN32)
|
||||||
//#include <windows.h>
|
//#include <windows.h>
|
||||||
//#else // !WIN32
|
//#else // !WIN32
|
||||||
@@ -290,10 +293,46 @@ if (!rc)
|
|||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
/* XML library cleanup function. */
|
/* XML library cleanup function. */
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
|
/*
|
||||||
|
This is a copy of xmlCleanupParser() from the libxml2 sources
|
||||||
|
with xmlResetLastError() commented.
|
||||||
|
|
||||||
|
xmlResetLastError() called from the original xmlCleanupParser() causes
|
||||||
|
valgrind to report memory leaks. This happens because
|
||||||
|
ha_initialize_handlerton() is called from the main thread in mysqld.cc,
|
||||||
|
while ha_finalize_handlerton() is called from a non-main thread.
|
||||||
|
libxml2 gets confused because of xmlInitParser() and xmlCleanupParser()
|
||||||
|
being called from the different threads.
|
||||||
|
|
||||||
|
Perhaps the code in mysqld.cc should eventually be modified
|
||||||
|
to shutdown plugins from the main thread.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
xmlCleanupParser_replacement(void)
|
||||||
|
{
|
||||||
|
xmlCleanupCharEncodingHandlers();
|
||||||
|
#ifdef LIBXML_CATALOG_ENABLED
|
||||||
|
xmlCatalogCleanup();
|
||||||
|
#endif
|
||||||
|
xmlDictCleanup();
|
||||||
|
xmlCleanupInputCallbacks();
|
||||||
|
#ifdef LIBXML_OUTPUT_ENABLED
|
||||||
|
xmlCleanupOutputCallbacks();
|
||||||
|
#endif
|
||||||
|
#ifdef LIBXML_SCHEMAS_ENABLED
|
||||||
|
xmlSchemaCleanupTypes();
|
||||||
|
xmlRelaxNGCleanupTypes();
|
||||||
|
#endif
|
||||||
|
//xmlResetLastError();
|
||||||
|
xmlCleanupGlobals();
|
||||||
|
xmlCleanupThreads(); /* must be last if called not from the main thread */
|
||||||
|
xmlCleanupMemory();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void XmlCleanupParserLib(void)
|
void XmlCleanupParserLib(void)
|
||||||
{
|
{
|
||||||
xmlCleanupParser();
|
xmlCleanupParser_replacement();
|
||||||
xmlMemoryDump();
|
|
||||||
} // end of XmlCleanupParserLib
|
} // end of XmlCleanupParserLib
|
||||||
|
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
|
@@ -87,7 +87,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
|||||||
FLD_KEY, FLD_SCALE, FLD_RADIX, FLD_NULL,
|
FLD_KEY, FLD_SCALE, FLD_RADIX, FLD_NULL,
|
||||||
FLD_REM, FLD_NO, FLD_CHARSET};
|
FLD_REM, FLD_NO, FLD_CHARSET};
|
||||||
static unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 256, 32, 32};
|
static unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 256, 32, 32};
|
||||||
char *fld, *fmt, cmd[128];
|
char *fld, *fmt, v, cmd[128];
|
||||||
int i, n, nf, ncol = sizeof(buftyp) / sizeof(int);
|
int i, n, nf, ncol = sizeof(buftyp) / sizeof(int);
|
||||||
int len, type, prec, rc, k = 0;
|
int len, type, prec, rc, k = 0;
|
||||||
PQRYRES qrp;
|
PQRYRES qrp;
|
||||||
@@ -139,6 +139,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
|||||||
// Some columns must be renamed
|
// Some columns must be renamed
|
||||||
for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next)
|
for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next)
|
||||||
switch (++i) {
|
switch (++i) {
|
||||||
|
case 2: crp->Nulls = (char*)PlugSubAlloc(g, NULL, n); break;
|
||||||
case 4: crp->Name = "Length"; break;
|
case 4: crp->Name = "Length"; break;
|
||||||
case 5: crp->Name = "Key"; break;
|
case 5: crp->Name = "Key"; break;
|
||||||
case 10: crp->Name = "Date_fmt"; break;
|
case 10: crp->Name = "Date_fmt"; break;
|
||||||
@@ -166,7 +167,8 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
|||||||
// Get type, type name, and precision
|
// Get type, type name, and precision
|
||||||
fld = myc.GetCharField(1);
|
fld = myc.GetCharField(1);
|
||||||
prec = 0;
|
prec = 0;
|
||||||
len = 255; // Default for text or blob
|
len = 0;
|
||||||
|
v = 0;
|
||||||
|
|
||||||
if ((nf = sscanf(fld, "%[^(](%d,%d", cmd, &len, &prec)) < 1) {
|
if ((nf = sscanf(fld, "%[^(](%d,%d", cmd, &len, &prec)) < 1) {
|
||||||
sprintf(g->Message, MSG(BAD_FIELD_TYPE), fld);
|
sprintf(g->Message, MSG(BAD_FIELD_TYPE), fld);
|
||||||
@@ -175,14 +177,16 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
|
|||||||
} else
|
} else
|
||||||
qrp->Nblin++;
|
qrp->Nblin++;
|
||||||
|
|
||||||
if ((type = MYSQLtoPLG(cmd)) == TYPE_ERROR) {
|
if ((type = MYSQLtoPLG(cmd, &v)) == TYPE_ERROR) {
|
||||||
sprintf(g->Message, "Unsupported column type %s", cmd);
|
sprintf(g->Message, "Unsupported column type %s", cmd);
|
||||||
myc.Close();
|
myc.Close();
|
||||||
return NULL;
|
return NULL;
|
||||||
} // endif type
|
} else if (type == TYPE_STRING)
|
||||||
|
len = min(len, 4096);
|
||||||
|
|
||||||
crp = crp->Next; // Data_Type
|
crp = crp->Next; // Data_Type
|
||||||
crp->Kdata->SetValue(type, i);
|
crp->Kdata->SetValue(type, i);
|
||||||
|
crp->Nulls[i] = v;
|
||||||
crp = crp->Next; // Type_Name
|
crp = crp->Next; // Type_Name
|
||||||
crp->Kdata->SetValue(cmd, i);
|
crp->Kdata->SetValue(cmd, i);
|
||||||
|
|
||||||
@@ -253,6 +257,7 @@ PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db,
|
|||||||
const char *user, const char *pwd,
|
const char *user, const char *pwd,
|
||||||
const char *srcdef, int port)
|
const char *srcdef, int port)
|
||||||
{
|
{
|
||||||
|
char *query;
|
||||||
int w;
|
int w;
|
||||||
MYSQLC myc;
|
MYSQLC myc;
|
||||||
PQRYRES qrp = NULL;
|
PQRYRES qrp = NULL;
|
||||||
@@ -260,12 +265,15 @@ PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db,
|
|||||||
if (!port)
|
if (!port)
|
||||||
port = mysqld_port;
|
port = mysqld_port;
|
||||||
|
|
||||||
|
query = (char *)PlugSubAlloc(g, NULL, strlen(srcdef) + 9);
|
||||||
|
strcat(strcpy(query, srcdef), " LIMIT 0");
|
||||||
|
|
||||||
// Open a MySQL connection for this table
|
// Open a MySQL connection for this table
|
||||||
if (myc.Open(g, host, db, user, pwd, port))
|
if (myc.Open(g, host, db, user, pwd, port))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// Send the source command to MySQL
|
// Send the source command to MySQL
|
||||||
if (myc.ExecSQL(g, srcdef, &w) == RC_OK)
|
if (myc.ExecSQL(g, query, &w) == RC_OK)
|
||||||
qrp = myc.GetResult(g);
|
qrp = myc.GetResult(g);
|
||||||
|
|
||||||
myc.Close();
|
myc.Close();
|
||||||
@@ -701,7 +709,7 @@ PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb)
|
|||||||
crp->Clen = GetTypeSize(crp->Type, crp->Length);
|
crp->Clen = GetTypeSize(crp->Type, crp->Length);
|
||||||
|
|
||||||
if (!(crp->Kdata = AllocValBlock(g, NULL, crp->Type, m_Rows,
|
if (!(crp->Kdata = AllocValBlock(g, NULL, crp->Type, m_Rows,
|
||||||
crp->Clen, 0, FALSE, TRUE))) {
|
crp->Clen, 0, FALSE, TRUE, FALSE))) {
|
||||||
sprintf(g->Message, MSG(INV_RESULT_TYPE),
|
sprintf(g->Message, MSG(INV_RESULT_TYPE),
|
||||||
GetFormatType(crp->Type));
|
GetFormatType(crp->Type));
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -778,6 +786,42 @@ void MYSQLC::Rewind(void)
|
|||||||
|
|
||||||
} // end of Rewind
|
} // end of Rewind
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Exec the Select SQL command and return ncol or afrws (TDBMYEXC). */
|
||||||
|
/***********************************************************************/
|
||||||
|
int MYSQLC::ExecSQLcmd(PGLOBAL g, const char *query, int *w)
|
||||||
|
{
|
||||||
|
int rc = RC_OK;
|
||||||
|
|
||||||
|
if (!m_DB) {
|
||||||
|
strcpy(g->Message, "MySQL not connected");
|
||||||
|
return RC_FX;
|
||||||
|
} else
|
||||||
|
*w = 0;
|
||||||
|
|
||||||
|
if (!stricmp(query, "Warning") || !stricmp(query, "Note")
|
||||||
|
|| !stricmp(query, "Error"))
|
||||||
|
return RC_INFO;
|
||||||
|
else
|
||||||
|
m_Afrw = 0;
|
||||||
|
|
||||||
|
//if (mysql_query(m_DB, query) != 0) {
|
||||||
|
if (mysql_real_query(m_DB, query, strlen(query))) {
|
||||||
|
m_Afrw = (int)mysql_errno(m_DB);
|
||||||
|
sprintf(g->Message, "Remote: %s", mysql_error(m_DB));
|
||||||
|
rc = RC_FX;
|
||||||
|
//} else if (!(m_Fields = mysql_field_count(m_DB))) {
|
||||||
|
} else if (!(m_Fields = (int)m_DB->field_count)) {
|
||||||
|
// m_Afrw = (int)mysql_affected_rows(m_DB);
|
||||||
|
m_Afrw = (int)m_DB->affected_rows;
|
||||||
|
rc = RC_NF;
|
||||||
|
} // endif's
|
||||||
|
|
||||||
|
//*w = mysql_warning_count(m_DB);
|
||||||
|
*w = m_DB->warning_count;
|
||||||
|
return rc;
|
||||||
|
} // end of ExecSQLcmd
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Close the connection. */
|
/* Close the connection. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -26,7 +26,6 @@
|
|||||||
#define DllItem
|
#define DllItem
|
||||||
#endif // !WIN32
|
#endif // !WIN32
|
||||||
|
|
||||||
//#define TYPE_AM_MYSQL (AMT)192
|
|
||||||
#define MYSQL_ENABLED 0x00000001
|
#define MYSQL_ENABLED 0x00000001
|
||||||
#define MYSQL_LOGON 0x00000002
|
#define MYSQL_LOGON 0x00000002
|
||||||
|
|
||||||
@@ -75,9 +74,12 @@ class DllItem MYSQLC {
|
|||||||
//const char *ServerInfo(void);
|
//const char *ServerInfo(void);
|
||||||
int KillQuery(ulong id);
|
int KillQuery(ulong id);
|
||||||
int ExecSQL(PGLOBAL g, const char *query, int *w = NULL);
|
int ExecSQL(PGLOBAL g, const char *query, int *w = NULL);
|
||||||
|
int ExecSQLcmd(PGLOBAL g, const char *query, int *w);
|
||||||
|
#if defined(MYSQL_PREPARED_STATEMENTS)
|
||||||
int PrepareSQL(PGLOBAL g, const char *query);
|
int PrepareSQL(PGLOBAL g, const char *query);
|
||||||
int ExecStmt(PGLOBAL g);
|
int ExecStmt(PGLOBAL g);
|
||||||
int BindParams(PGLOBAL g, MYSQL_BIND *bind);
|
int BindParams(PGLOBAL g, MYSQL_BIND *bind);
|
||||||
|
#endif // MYSQL_PREPARED_STATEMENTS
|
||||||
PQRYRES GetResult(PGLOBAL g, bool pdb = FALSE);
|
PQRYRES GetResult(PGLOBAL g, bool pdb = FALSE);
|
||||||
int Fetch(PGLOBAL g, int pos);
|
int Fetch(PGLOBAL g, int pos);
|
||||||
char *GetCharField(int i);
|
char *GetCharField(int i);
|
||||||
@@ -99,5 +101,6 @@ class DllItem MYSQLC {
|
|||||||
int m_Rows; // The number of rows of the result
|
int m_Rows; // The number of rows of the result
|
||||||
int N;
|
int N;
|
||||||
int m_Fields; // The number of result fields
|
int m_Fields; // The number of result fields
|
||||||
|
int m_Afrw; // The number of affected rows
|
||||||
}; // end of class MYSQLC
|
}; // end of class MYSQLC
|
||||||
|
|
||||||
|
15
storage/connect/mysql-test/connect/my.cnf
Normal file
15
storage/connect/mysql-test/connect/my.cnf
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# Use default setting for mysqld processes
|
||||||
|
!include include/default_mysqld.cnf
|
||||||
|
!include include/default_client.cnf
|
||||||
|
|
||||||
|
[mysqld.1]
|
||||||
|
#log-bin= master-bin
|
||||||
|
|
||||||
|
[mysqld.2]
|
||||||
|
|
||||||
|
[ENV]
|
||||||
|
MASTER_MYPORT= @mysqld.1.port
|
||||||
|
MASTER_MYSOCK= @mysqld.1.socket
|
||||||
|
|
||||||
|
SLAVE_MYPORT= @mysqld.2.port
|
||||||
|
SLAVE_MYSOCK= @mysqld.2.socket
|
@@ -48,7 +48,7 @@ salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F',
|
|||||||
dept INT(4) NOT NULL FIELD_FORMAT='S'
|
dept INT(4) NOT NULL FIELD_FORMAT='S'
|
||||||
) ENGINE=CONNECT TABLE_TYPE=BIN READONLY=Yes FILE_NAME='Testbal.dat';
|
) ENGINE=CONNECT TABLE_TYPE=BIN READONLY=Yes FILE_NAME='Testbal.dat';
|
||||||
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
|
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
ALTER TABLE t1 READONLY=NO;
|
ALTER TABLE t1 READONLY=NO;
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
||||||
@@ -84,7 +84,7 @@ t1 CREATE TABLE `t1` (
|
|||||||
`dept` int(4) NOT NULL `FIELD_FORMAT`='S'
|
`dept` int(4) NOT NULL `FIELD_FORMAT`='S'
|
||||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=BIN `FILE_NAME`='Testbal.dat' `READONLY`=YES
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=BIN `FILE_NAME`='Testbal.dat' `READONLY`=YES
|
||||||
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
|
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
# Testing that the underlying file is created
|
# Testing that the underlying file is created
|
||||||
|
@@ -50,13 +50,13 @@ children SMALLINT(2) NOT NULL
|
|||||||
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv'
|
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv'
|
||||||
HEADER=1 SEP_CHAR=';' QUOTED=1 READONLY=yes;
|
HEADER=1 SEP_CHAR=';' QUOTED=1 READONLY=yes;
|
||||||
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
|
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
UPDATE t1 SET children=6 WHERE name='BILL';
|
UPDATE t1 SET children=6 WHERE name='BILL';
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
DELETE FROM t1 WHERE name='BILL';
|
DELETE FROM t1 WHERE name='BILL';
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
TRUNCATE TABLE t1;
|
TRUNCATE TABLE t1;
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
name birth children
|
name birth children
|
||||||
Archibald 2001-05-17 3
|
Archibald 2001-05-17 3
|
||||||
@@ -90,7 +90,7 @@ t1 CREATE TABLE `t1` (
|
|||||||
`children` smallint(2) NOT NULL
|
`children` smallint(2) NOT NULL
|
||||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=CSV `FILE_NAME`='people.csv' `HEADER`=1 `SEP_CHAR`=';' `QUOTED`=1 `READONLY`=1
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=CSV `FILE_NAME`='people.csv' `HEADER`=1 `SEP_CHAR`=';' `QUOTED`=1 `READONLY`=1
|
||||||
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
|
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
name birth children
|
name birth children
|
||||||
Archibald 2001-05-17 3
|
Archibald 2001-05-17 3
|
||||||
|
@@ -77,13 +77,13 @@ t1 CREATE TABLE `t1` (
|
|||||||
`a` int(11) NOT NULL
|
`a` int(11) NOT NULL
|
||||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=DBF `FILE_NAME`='t1.dbf' `READONLY`=Yes
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=DBF `FILE_NAME`='t1.dbf' `READONLY`=Yes
|
||||||
INSERT INTO t1 VALUES (30);
|
INSERT INTO t1 VALUES (30);
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
UPDATE t1 SET a=30 WHERE a=10;
|
UPDATE t1 SET a=30 WHERE a=10;
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
DELETE FROM t1 WHERE a=10;
|
DELETE FROM t1 WHERE a=10;
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
TRUNCATE TABLE t1;
|
TRUNCATE TABLE t1;
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
ALTER TABLE t1 READONLY=NO;
|
ALTER TABLE t1 READONLY=NO;
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
||||||
|
@@ -30,13 +30,13 @@ t1 CREATE TABLE `t1` (
|
|||||||
`id` int(11) NOT NULL
|
`id` int(11) NOT NULL
|
||||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=FIX `FILE_NAME`='t1.txt' `READONLY`=1
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=FIX `FILE_NAME`='t1.txt' `READONLY`=1
|
||||||
INSERT INTO t1 VALUES (20);
|
INSERT INTO t1 VALUES (20);
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
UPDATE t1 SET id=20 WHERE id=10;
|
UPDATE t1 SET id=20 WHERE id=10;
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
DELETE FROM t1 WHERE id=10;
|
DELETE FROM t1 WHERE id=10;
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
TRUNCATE TABLE t1;
|
TRUNCATE TABLE t1;
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
ALTER TABLE t1 READONLY=0;
|
ALTER TABLE t1 READONLY=0;
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
||||||
|
@@ -194,13 +194,13 @@ t1 CREATE TABLE `t1` (
|
|||||||
`c2` char(60) DEFAULT NULL
|
`c2` char(60) DEFAULT NULL
|
||||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=INI `FILE_NAME`='t1.ini' `READONLY`=1
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=INI `FILE_NAME`='t1.ini' `READONLY`=1
|
||||||
INSERT INTO t1 VALUES ('US',40);
|
INSERT INTO t1 VALUES ('US',40);
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
UPDATE t1 SET c2=20 WHERE c2=10;
|
UPDATE t1 SET c2=20 WHERE c2=10;
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
DELETE FROM t1 WHERE c2=10;
|
DELETE FROM t1 WHERE c2=10;
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
TRUNCATE TABLE t1;
|
TRUNCATE TABLE t1;
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
ALTER TABLE t1 READONLY=0;
|
ALTER TABLE t1 READONLY=0;
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
||||||
|
@@ -44,7 +44,7 @@ SHOW CREATE TABLE t2;
|
|||||||
Table Create Table
|
Table Create Table
|
||||||
t2 CREATE TABLE `t2` (
|
t2 CREATE TABLE `t2` (
|
||||||
`a` int(11) DEFAULT NULL,
|
`a` int(11) DEFAULT NULL,
|
||||||
`b` varchar(10) DEFAULT NULL
|
`b` char(10) DEFAULT NULL
|
||||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MYSQL' `TABNAME`='t1' `OPTION_LIST`='host=localhost,user=root,port=PORT'
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MYSQL' `TABNAME`='t1' `OPTION_LIST`='host=localhost,user=root,port=PORT'
|
||||||
SELECT * FROM t2;
|
SELECT * FROM t2;
|
||||||
a b
|
a b
|
||||||
@@ -176,7 +176,7 @@ t1 CREATE TABLE `t1` (
|
|||||||
SHOW CREATE TABLE t2;
|
SHOW CREATE TABLE t2;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t2 CREATE TABLE `t2` (
|
t2 CREATE TABLE `t2` (
|
||||||
`a` varchar(10) DEFAULT NULL
|
`a` char(10) DEFAULT NULL
|
||||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MYSQL' `TABNAME`='t1' `OPTION_LIST`='host=localhost,user=root,port=PORT'
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MYSQL' `TABNAME`='t1' `OPTION_LIST`='host=localhost,user=root,port=PORT'
|
||||||
SELECT * FROM t2;
|
SELECT * FROM t2;
|
||||||
a
|
a
|
||||||
|
42
storage/connect/mysql-test/connect/r/mysql_discovery.result
Normal file
42
storage/connect/mysql-test/connect/r/mysql_discovery.result
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
CREATE DATABASE connect;
|
||||||
|
CREATE DATABASE connect;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
`id` int(20) primary key,
|
||||||
|
`group` int NOT NULL default 1,
|
||||||
|
`a\\b` int NOT NULL default 2,
|
||||||
|
`a\\` int unsigned,
|
||||||
|
`name` varchar(32) default 'name')
|
||||||
|
DEFAULT CHARSET=latin1;
|
||||||
|
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1';
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`id` int(20) NOT NULL,
|
||||||
|
`group` int(11) NOT NULL,
|
||||||
|
`a\\b` int(11) NOT NULL,
|
||||||
|
`a\\` int(10) DEFAULT NULL,
|
||||||
|
`name` varchar(32) DEFAULT NULL
|
||||||
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1' `TABLE_TYPE`='MYSQL'
|
||||||
|
INSERT INTO t1 (id, name) VALUES (1, 'foo');
|
||||||
|
Warnings:
|
||||||
|
Warning 1364 Field 'group' doesn't have a default value
|
||||||
|
Warning 1364 Field 'a\\b' doesn't have a default value
|
||||||
|
INSERT INTO t1 (id, name) VALUES (2, 'fee');
|
||||||
|
Warnings:
|
||||||
|
Warning 1364 Field 'group' doesn't have a default value
|
||||||
|
Warning 1364 Field 'a\\b' doesn't have a default value
|
||||||
|
SELECT * FROM t1;
|
||||||
|
id group a\\b a\\ name
|
||||||
|
1 1 2 NULL foo
|
||||||
|
2 1 2 NULL fee
|
||||||
|
DROP TABLE t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
id group a\\b a\\ name
|
||||||
|
1 1 2 NULL foo
|
||||||
|
2 1 2 NULL fee
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE IF EXISTS connect.t1;
|
||||||
|
DROP DATABASE IF EXISTS connect;
|
||||||
|
DROP TABLE IF EXISTS connect.t1;
|
||||||
|
DROP DATABASE IF EXISTS connect;
|
62
storage/connect/mysql-test/connect/r/mysql_exec.result
Normal file
62
storage/connect/mysql-test/connect/r/mysql_exec.result
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
CREATE DATABASE connect;
|
||||||
|
CREATE DATABASE connect;
|
||||||
|
#
|
||||||
|
# Checking Sending Commands
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
command VARCHAR(128) NOT NULL,
|
||||||
|
warnings INT(4) NOT NULL FLAG=3,
|
||||||
|
number INT(5) NOT NULL FLAG=1,
|
||||||
|
message VARCHAR(255) FLAG=2)
|
||||||
|
ENGINE=CONNECT TABLE_TYPE=MYSQL CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test' OPTION_LIST='Execsrc=1,maxerr=2';
|
||||||
|
SELECT * FROM t1 WHERE command IN ('Warning','Note',
|
||||||
|
'drop table if exists t1',
|
||||||
|
'create table t1 (id int key auto_increment, msg varchar(32) not null)',
|
||||||
|
"insert into t1(msg) values('One'),(NULL),('Three')",
|
||||||
|
"insert into t1 values(2,'Deux') on duplicate key update msg = 'Two'",
|
||||||
|
"insert into t1(message) values('Four'),('Five'),('Six')",
|
||||||
|
'insert into t1(id) values(NULL)',
|
||||||
|
"update t1 set msg = 'Four' where id = 4",
|
||||||
|
'select * from t1');
|
||||||
|
command warnings number message
|
||||||
|
drop table if exists t1 1 0 Affected rows
|
||||||
|
Note 0 1051 Unknown table 'test.t1'
|
||||||
|
create table t1 (id int key auto_increment, msg varchar(32) not null) 0 0 Affected rows
|
||||||
|
insert into t1(msg) values('One'),(NULL),('Three') 1 3 Affected rows
|
||||||
|
Warning 0 1048 Column 'msg' cannot be null
|
||||||
|
insert into t1 values(2,'Deux') on duplicate key update msg = 'Two' 0 2 Affected rows
|
||||||
|
insert into t1(message) values('Four'),('Five'),('Six') 0 1054 Remote: Unknown column 'message' in 'field list'
|
||||||
|
insert into t1(id) values(NULL) 1 1 Affected rows
|
||||||
|
Warning 0 1364 Field 'msg' doesn't have a default value
|
||||||
|
update t1 set msg = 'Four' where id = 4 0 1 Affected rows
|
||||||
|
select * from t1 0 2 Result set columns
|
||||||
|
#
|
||||||
|
# Checking Using Procedure
|
||||||
|
#
|
||||||
|
DROP PROCEDURE IF EXISTS p1;
|
||||||
|
Warnings:
|
||||||
|
Note 1305 PROCEDURE test.p1 does not exist
|
||||||
|
CREATE PROCEDURE p1(cmd varchar(512))
|
||||||
|
READS SQL DATA
|
||||||
|
SELECT * FROM t1 WHERE command IN ('Warning','Note',cmd);
|
||||||
|
CALL p1('insert into t1(id) values(NULL)');
|
||||||
|
command warnings number message
|
||||||
|
insert into t1(id) values(NULL) 1 1 Affected rows
|
||||||
|
Warning 0 1364 Field 'msg' doesn't have a default value
|
||||||
|
CALL p1('update t1 set msg = "Five" where id = 5');
|
||||||
|
command warnings number message
|
||||||
|
update t1 set msg = "Five" where id = 5 0 1 Affected rows
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
id msg
|
||||||
|
1 One
|
||||||
|
2 Two
|
||||||
|
3 Three
|
||||||
|
4 Four
|
||||||
|
5 Five
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE IF EXISTS connect.t1;
|
||||||
|
DROP DATABASE IF EXISTS connect;
|
||||||
|
DROP TABLE IF EXISTS connect.t1;
|
||||||
|
DROP DATABASE IF EXISTS connect;
|
218
storage/connect/mysql-test/connect/r/mysql_new.result
Normal file
218
storage/connect/mysql-test/connect/r/mysql_new.result
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
CREATE DATABASE connect;
|
||||||
|
CREATE DATABASE connect;
|
||||||
|
CREATE TABLE t1 (a int, b char(10));
|
||||||
|
INSERT INTO t1 VALUES (NULL,NULL),(0,'test00'),(1,'test01'),(2,'test02'),(3,'test03');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b
|
||||||
|
NULL NULL
|
||||||
|
0 test00
|
||||||
|
1 test01
|
||||||
|
2 test02
|
||||||
|
3 test03
|
||||||
|
#
|
||||||
|
# Testing errors
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://unknown@127.0.0.1:SLAVE_PORT/test/t1';
|
||||||
|
ERROR HY000: (1045) Access denied for user 'unknown'@'localhost' (using password: NO)
|
||||||
|
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/unknown/t1';
|
||||||
|
ERROR HY000: (1049) Unknown database 'unknown'
|
||||||
|
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
OPTION_LIST='host=127.0.0.1,user=root,port=SLAVE_PORT' DBNAME='unknown' TABNAME='t1';
|
||||||
|
ERROR HY000: (1049) Unknown database 'unknown'
|
||||||
|
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/unknown';
|
||||||
|
ERROR HY000: (1146) Table 'test.unknown' doesn't exist [SHOW FULL COLUMNS FROM unknown FROM test]
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||||
|
CREATE TABLE t1 (x int, y char(10)) ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1';
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`x` int(11) DEFAULT NULL,
|
||||||
|
`y` char(10) DEFAULT NULL
|
||||||
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1' `TABLE_TYPE`=MYSQL
|
||||||
|
SELECT * FROM t1;
|
||||||
|
ERROR HY000: Got error 174 '(1054) Unknown column 'x' in 'field list' [SELECT `x`, `y` FROM `t1`]' from CONNECT
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1';
|
||||||
|
ALTER TABLE t1 RENAME t1backup;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
ERROR HY000: Got error 174 '(1146) Table 'test.t1' doesn't exist [SELECT `a`, `b` FROM `t1`]' from CONNECT
|
||||||
|
ALTER TABLE t1backup RENAME t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Testing SELECT, etc.
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1';
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` int(11) DEFAULT NULL,
|
||||||
|
`b` char(10) DEFAULT NULL
|
||||||
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1' `TABLE_TYPE`='MYSQL'
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b
|
||||||
|
NULL NULL
|
||||||
|
0 test00
|
||||||
|
1 test01
|
||||||
|
2 test02
|
||||||
|
3 test03
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1'
|
||||||
|
OPTION_LIST='host=127.0.0.1,user=root,port=SLAVE_PORT';
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` int(11) DEFAULT NULL,
|
||||||
|
`b` char(10) DEFAULT NULL
|
||||||
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=MYSQL `TABNAME`='t1' `OPTION_LIST`='host=127.0.0.1,user=root,port=SLAVE_PORT'
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b
|
||||||
|
NULL NULL
|
||||||
|
0 test00
|
||||||
|
1 test01
|
||||||
|
2 test02
|
||||||
|
3 test03
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a INT NOT NULL, b CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
OPTION_LIST='host=127.0.0.1,user=root,port=SLAVE_PORT';
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` int(11) NOT NULL,
|
||||||
|
`b` char(10) NOT NULL
|
||||||
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=MYSQL `OPTION_LIST`='host=127.0.0.1,user=root,port=SLAVE_PORT'
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b
|
||||||
|
0
|
||||||
|
0 test00
|
||||||
|
1 test01
|
||||||
|
2 test02
|
||||||
|
3 test03
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a char(10), b int) ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1';
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` char(10) DEFAULT NULL,
|
||||||
|
`b` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1' `TABLE_TYPE`=MYSQL
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b
|
||||||
|
NULL NULL
|
||||||
|
0 0
|
||||||
|
1 0
|
||||||
|
2 0
|
||||||
|
3 0
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Testing numeric data types
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a tinyint, b smallint, c mediumint, d int, e bigint, f float, g double, h decimal(20,5));
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` tinyint(4) DEFAULT NULL,
|
||||||
|
`b` smallint(6) DEFAULT NULL,
|
||||||
|
`c` mediumint(9) DEFAULT NULL,
|
||||||
|
`d` int(11) DEFAULT NULL,
|
||||||
|
`e` bigint(20) DEFAULT NULL,
|
||||||
|
`f` float DEFAULT NULL,
|
||||||
|
`g` double DEFAULT NULL,
|
||||||
|
`h` decimal(20,5) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
INSERT INTO t1 VALUES(100,3333,41235,1234567890,235000000000,3.14159265,3.14159265,3141.59265);
|
||||||
|
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
OPTION_LIST='host=127.0.0.1,user=root,port=SLAVE_PORT';
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` tinyint(4) DEFAULT NULL,
|
||||||
|
`b` smallint(6) DEFAULT NULL,
|
||||||
|
`c` int(9) DEFAULT NULL,
|
||||||
|
`d` int(11) DEFAULT NULL,
|
||||||
|
`e` bigint(20) DEFAULT NULL,
|
||||||
|
`f` double DEFAULT NULL,
|
||||||
|
`g` double DEFAULT NULL,
|
||||||
|
`h` double(20,5) DEFAULT NULL
|
||||||
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MYSQL' `OPTION_LIST`='host=127.0.0.1,user=root,port=SLAVE_PORT'
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b c d e f g h
|
||||||
|
100 3333 41235 1234567890 235000000000 3.14159 3.14159265 3141.59265
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Testing character data types
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a char(12), b varchar(12));
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` char(12) DEFAULT NULL,
|
||||||
|
`b` varchar(12) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
INSERT INTO t1 VALUES('Welcome','Hello, World');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b
|
||||||
|
Welcome Hello, World
|
||||||
|
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT';
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` char(12) DEFAULT NULL,
|
||||||
|
`b` varchar(12) DEFAULT NULL
|
||||||
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT' `TABLE_TYPE`='MYSQL'
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b
|
||||||
|
Welcome Hello, World
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Testing temporal data types
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a date, b datetime, c time, d timestamp, e year);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` date DEFAULT NULL,
|
||||||
|
`b` datetime DEFAULT NULL,
|
||||||
|
`c` time DEFAULT NULL,
|
||||||
|
`d` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`e` year(4) DEFAULT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
INSERT INTO t1 VALUES('2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23');
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'a' at row 1
|
||||||
|
Note 1265 Data truncated for column 'c' at row 1
|
||||||
|
Warning 1265 Data truncated for column 'e' at row 1
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b c d e
|
||||||
|
2003-05-27 2003-05-27 10:45:23 10:45:23 2003-05-27 10:45:23 2003
|
||||||
|
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT';
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` date DEFAULT NULL,
|
||||||
|
`b` datetime DEFAULT NULL,
|
||||||
|
`c` time DEFAULT NULL,
|
||||||
|
`d` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||||
|
`e` year(4) DEFAULT NULL
|
||||||
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT' `TABLE_TYPE`='MYSQL'
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b c d e
|
||||||
|
2003-05-27 2003-05-27 10:45:23 10:45:23 2003-05-27 10:45:23 2003
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE IF EXISTS connect.t1;
|
||||||
|
DROP DATABASE IF EXISTS connect;
|
||||||
|
DROP TABLE IF EXISTS connect.t1;
|
||||||
|
DROP DATABASE IF EXISTS connect;
|
@@ -1,6 +1,6 @@
|
|||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`Description` varchar(128) NOT NULL,
|
`Description` char(128) NOT NULL,
|
||||||
`Attributes` varchar(256) NOT NULL
|
`Attributes` varchar(256) NOT NULL
|
||||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='ODBC' `CATFUNC`='Drivers'
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='ODBC' `CATFUNC`='Drivers'
|
||||||
SET NAMES utf8;
|
SET NAMES utf8;
|
||||||
@@ -41,3 +41,13 @@ test2
|
|||||||
ÆÇÈÉË
|
ÆÇÈÉË
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 ENGINE=CONNECT CATFUNC=Columns TABNAME='t1' TABLE_TYPE=ODBC CONNECTION='Driver=SQLite3 ODBC Driver;Database=MTR_SUITE_DIR/std_data/test.sqlite3;NoWCHAR=yes' CHARSET=utf8 DATA_CHARSET=utf8;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
Table_Qualif Table_Owner Table_Name Column_Name Data_Type Type_Name Precision Length Scale Radix Nullable Remarks
|
||||||
|
t1 a 12 varchar(64) 64 64 10 0 1
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 ENGINE=CONNECT CATFUNC=Tables TABNAME='t1' TABLE_TYPE=ODBC CONNECTION='Driver=SQLite3 ODBC Driver;Database=MTR_SUITE_DIR/std_data/test.sqlite3;NoWCHAR=yes' CHARSET=utf8 DATA_CHARSET=utf8;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
Table_Qualifier Table_Owner Table_Name Table_Type Remark
|
||||||
|
t1 TABLE
|
||||||
|
DROP TABLE t1;
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`Description` varchar(128) NOT NULL,
|
`Description` char(128) NOT NULL,
|
||||||
`Attributes` varchar(256) NOT NULL
|
`Attributes` varchar(256) NOT NULL
|
||||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='ODBC' `CATFUNC`='Drivers'
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='ODBC' `CATFUNC`='Drivers'
|
||||||
SET NAMES utf8;
|
SET NAMES utf8;
|
||||||
|
@@ -13,3 +13,14 @@ Thomas Dominique NULL
|
|||||||
Lemonnier Nathalie Directeur Marketing Client
|
Lemonnier Nathalie Directeur Marketing Client
|
||||||
Menseau Eric NULL
|
Menseau Eric NULL
|
||||||
DROP TABLE contact;
|
DROP TABLE contact;
|
||||||
|
CREATE TABLE t1 ENGINE=CONNECT CATFUNC=Tables TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineXLS;DBQ=DATADIR/test/contacts.xls' CHARSET=utf8 DATA_CHARSET=latin1;;
|
||||||
|
SELECT * FROM t1 WHERE Table_name='CONTACT';
|
||||||
|
Table_Qualifier Table_Owner Table_Name Table_Type Remark
|
||||||
|
DATADIR/test/contacts CONTACT TABLE
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 ENGINE=CONNECT CATFUNC=Columns TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineXLS;DBQ=DATADIR/test/contacts.xls' CHARSET=utf8 DATA_CHARSET=latin1;;
|
||||||
|
SELECT * FROM t1 WHERE Table_name='CONTACT' AND Column_name IN ('Nom','Fonction');
|
||||||
|
Table_Qualif Table_Owner Table_Name Column_Name Data_Type Type_Name Precision Length Scale Radix Nullable Remarks
|
||||||
|
DATADIR/test/contacts CONTACT Nom 12 VARCHAR 255 510 0 0 1
|
||||||
|
DATADIR/test/contacts CONTACT Fonction 12 VARCHAR 255 510 0 0 1
|
||||||
|
DROP TABLE t1;
|
||||||
|
@@ -103,13 +103,13 @@ t1 CREATE TABLE `t1` (
|
|||||||
`b` char(10) NOT NULL
|
`b` char(10) NOT NULL
|
||||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 MAX_ROWS=10 `TABLE_TYPE`=VEC `FILE_NAME`='t1vec' `READONLY`=yes
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 MAX_ROWS=10 `TABLE_TYPE`=VEC `FILE_NAME`='t1vec' `READONLY`=yes
|
||||||
INSERT INTO t1 VALUES (4,'test04');
|
INSERT INTO t1 VALUES (4,'test04');
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
UPDATE t1 SET b='test04' WHERE a=3;
|
UPDATE t1 SET b='test04' WHERE a=3;
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
DELETE FROM t1 WHERE a=3;
|
DELETE FROM t1 WHERE a=3;
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
TRUNCATE TABLE t1;
|
TRUNCATE TABLE t1;
|
||||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
ERROR HY000: Table 't1' is read only
|
||||||
ALTER TABLE t1 READONLY=no;
|
ALTER TABLE t1 READONLY=no;
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
||||||
|
@@ -413,7 +413,7 @@ DROP TABLE t1;
|
|||||||
SET @a=LOAD_FILE('MYSQLD_DATADIR/test/t1.xml');
|
SET @a=LOAD_FILE('MYSQLD_DATADIR/test/t1.xml');
|
||||||
SELECT CAST(@a AS CHAR CHARACTER SET latin1);
|
SELECT CAST(@a AS CHAR CHARACTER SET latin1);
|
||||||
CAST(@a AS CHAR CHARACTER SET latin1) <?xml version="1.0" encoding="iso-8859-1"?>
|
CAST(@a AS CHAR CHARACTER SET latin1) <?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
<!-- Created by CONNECT Version 1.01.0008 August 18, 2013 -->
|
<!-- Created by CONNECT Version 1.01.0009 October 29, 2013 -->
|
||||||
<t1>
|
<t1>
|
||||||
<line>
|
<line>
|
||||||
<node>ÀÁÂÃ</node>
|
<node>ÀÁÂÃ</node>
|
||||||
|
@@ -46,7 +46,7 @@ CREATE TABLE t1
|
|||||||
salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F',
|
salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F',
|
||||||
dept INT(4) NOT NULL FIELD_FORMAT='S'
|
dept INT(4) NOT NULL FIELD_FORMAT='S'
|
||||||
) ENGINE=CONNECT TABLE_TYPE=BIN READONLY=Yes FILE_NAME='Testbal.dat';
|
) ENGINE=CONNECT TABLE_TYPE=BIN READONLY=Yes FILE_NAME='Testbal.dat';
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
|
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
|
||||||
ALTER TABLE t1 READONLY=NO;
|
ALTER TABLE t1 READONLY=NO;
|
||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
@@ -54,7 +54,7 @@ INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
ALTER TABLE t1 READONLY=YES;
|
ALTER TABLE t1 READONLY=YES;
|
||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
|
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
@@ -45,13 +45,13 @@ CREATE TABLE t1
|
|||||||
children SMALLINT(2) NOT NULL
|
children SMALLINT(2) NOT NULL
|
||||||
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv'
|
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv'
|
||||||
HEADER=1 SEP_CHAR=';' QUOTED=1 READONLY=yes;
|
HEADER=1 SEP_CHAR=';' QUOTED=1 READONLY=yes;
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
|
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
UPDATE t1 SET children=6 WHERE name='BILL';
|
UPDATE t1 SET children=6 WHERE name='BILL';
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
DELETE FROM t1 WHERE name='BILL';
|
DELETE FROM t1 WHERE name='BILL';
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
TRUNCATE TABLE t1;
|
TRUNCATE TABLE t1;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
ALTER TABLE t1 READONLY=no;
|
ALTER TABLE t1 READONLY=no;
|
||||||
@@ -60,7 +60,7 @@ INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
ALTER TABLE t1 READONLY=1;
|
ALTER TABLE t1 READONLY=1;
|
||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
|
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
@@ -66,13 +66,13 @@ INSERT INTO t1 VALUES (10),(20);
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
ALTER TABLE t1 READONLY=Yes;
|
ALTER TABLE t1 READONLY=Yes;
|
||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
INSERT INTO t1 VALUES (30);
|
INSERT INTO t1 VALUES (30);
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
UPDATE t1 SET a=30 WHERE a=10;
|
UPDATE t1 SET a=30 WHERE a=10;
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
DELETE FROM t1 WHERE a=10;
|
DELETE FROM t1 WHERE a=10;
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
TRUNCATE TABLE t1;
|
TRUNCATE TABLE t1;
|
||||||
ALTER TABLE t1 READONLY=NO;
|
ALTER TABLE t1 READONLY=NO;
|
||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
|
@@ -28,13 +28,13 @@ INSERT INTO t1 VALUES (10);
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
ALTER TABLE t1 READONLY=1;
|
ALTER TABLE t1 READONLY=1;
|
||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
INSERT INTO t1 VALUES (20);
|
INSERT INTO t1 VALUES (20);
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
UPDATE t1 SET id=20 WHERE id=10;
|
UPDATE t1 SET id=20 WHERE id=10;
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
DELETE FROM t1 WHERE id=10;
|
DELETE FROM t1 WHERE id=10;
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
TRUNCATE TABLE t1;
|
TRUNCATE TABLE t1;
|
||||||
ALTER TABLE t1 READONLY=0;
|
ALTER TABLE t1 READONLY=0;
|
||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
|
@@ -99,13 +99,13 @@ INSERT INTO t1 VALUES ('UK',10),('FR',20),('RU',30);
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
ALTER TABLE t1 READONLY=1;
|
ALTER TABLE t1 READONLY=1;
|
||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
INSERT INTO t1 VALUES ('US',40);
|
INSERT INTO t1 VALUES ('US',40);
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
UPDATE t1 SET c2=20 WHERE c2=10;
|
UPDATE t1 SET c2=20 WHERE c2=10;
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
DELETE FROM t1 WHERE c2=10;
|
DELETE FROM t1 WHERE c2=10;
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
TRUNCATE TABLE t1;
|
TRUNCATE TABLE t1;
|
||||||
ALTER TABLE t1 READONLY=0;
|
ALTER TABLE t1 READONLY=0;
|
||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
|
27
storage/connect/mysql-test/connect/t/myconn.inc
Normal file
27
storage/connect/mysql-test/connect/t/myconn.inc
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
--source include/not_embedded.inc
|
||||||
|
|
||||||
|
let $PORT= `select @@port`;
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
--replace_result $PORT PORT
|
||||||
|
--error 0,ER_UNKNOWN_ERROR
|
||||||
|
eval CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/tx1';
|
||||||
|
if (!`SELECT count(*) FROM INFORMATION_SCHEMA.TABLES
|
||||||
|
WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'
|
||||||
|
AND ENGINE='CONNECT'
|
||||||
|
AND CREATE_OPTIONS LIKE '%`table_type`=MySQL%'`)
|
||||||
|
{
|
||||||
|
Skip Need MySQL support;
|
||||||
|
}
|
||||||
|
DROP TABLE t1;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,);
|
||||||
|
connect (slave,127.0.0.1,root,,test,$SLAVE_MYPORT,);
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
CREATE DATABASE connect;
|
||||||
|
|
||||||
|
connection slave;
|
||||||
|
CREATE DATABASE connect;
|
9
storage/connect/mysql-test/connect/t/myconn_cleanup.inc
Normal file
9
storage/connect/mysql-test/connect/t/myconn_cleanup.inc
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
connection master;
|
||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS connect.t1;
|
||||||
|
DROP DATABASE IF EXISTS connect;
|
||||||
|
|
||||||
|
connection slave;
|
||||||
|
DROP TABLE IF EXISTS connect.t1;
|
||||||
|
DROP DATABASE IF EXISTS connect;
|
||||||
|
--enable_warnings
|
33
storage/connect/mysql-test/connect/t/mysql_discovery.test
Normal file
33
storage/connect/mysql-test/connect/t/mysql_discovery.test
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
-- source myconn.inc
|
||||||
|
|
||||||
|
connection slave;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
`id` int(20) primary key,
|
||||||
|
`group` int NOT NULL default 1,
|
||||||
|
`a\\b` int NOT NULL default 2,
|
||||||
|
`a\\` int unsigned,
|
||||||
|
`name` varchar(32) default 'name')
|
||||||
|
DEFAULT CHARSET=latin1;
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1';
|
||||||
|
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
INSERT INTO t1 (id, name) VALUES (1, 'foo');
|
||||||
|
INSERT INTO t1 (id, name) VALUES (2, 'fee');
|
||||||
|
--sorted_result
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
connection slave;
|
||||||
|
--sorted_result
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
-- source myconn_cleanup.inc
|
||||||
|
|
45
storage/connect/mysql-test/connect/t/mysql_exec.test
Normal file
45
storage/connect/mysql-test/connect/t/mysql_exec.test
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
-- source myconn.inc
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Checking Sending Commands
|
||||||
|
--echo #
|
||||||
|
connection master;
|
||||||
|
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
eval CREATE TABLE t1 (
|
||||||
|
command VARCHAR(128) NOT NULL,
|
||||||
|
warnings INT(4) NOT NULL FLAG=3,
|
||||||
|
number INT(5) NOT NULL FLAG=1,
|
||||||
|
message VARCHAR(255) FLAG=2)
|
||||||
|
ENGINE=CONNECT TABLE_TYPE=MYSQL CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test' OPTION_LIST='Execsrc=1,maxerr=2';
|
||||||
|
|
||||||
|
SELECT * FROM t1 WHERE command IN ('Warning','Note',
|
||||||
|
'drop table if exists t1',
|
||||||
|
'create table t1 (id int key auto_increment, msg varchar(32) not null)',
|
||||||
|
"insert into t1(msg) values('One'),(NULL),('Three')",
|
||||||
|
"insert into t1 values(2,'Deux') on duplicate key update msg = 'Two'",
|
||||||
|
"insert into t1(message) values('Four'),('Five'),('Six')",
|
||||||
|
'insert into t1(id) values(NULL)',
|
||||||
|
"update t1 set msg = 'Four' where id = 4",
|
||||||
|
'select * from t1');
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Checking Using Procedure
|
||||||
|
--echo #
|
||||||
|
DROP PROCEDURE IF EXISTS p1;
|
||||||
|
CREATE PROCEDURE p1(cmd varchar(512))
|
||||||
|
READS SQL DATA
|
||||||
|
SELECT * FROM t1 WHERE command IN ('Warning','Note',cmd);
|
||||||
|
|
||||||
|
CALL p1('insert into t1(id) values(NULL)');
|
||||||
|
CALL p1('update t1 set msg = "Five" where id = 5');
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
connection slave;
|
||||||
|
--sorted_result
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
-- source myconn_cleanup.inc
|
||||||
|
|
325
storage/connect/mysql-test/connect/t/mysql_new.test
Normal file
325
storage/connect/mysql-test/connect/t/mysql_new.test
Normal file
@@ -0,0 +1,325 @@
|
|||||||
|
-- source myconn.inc
|
||||||
|
|
||||||
|
#
|
||||||
|
# This test is run against a remote MySQL server
|
||||||
|
#
|
||||||
|
|
||||||
|
connection slave;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a int, b char(10));
|
||||||
|
INSERT INTO t1 VALUES (NULL,NULL),(0,'test00'),(1,'test01'),(2,'test02'),(3,'test03');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Testing errors
|
||||||
|
--echo #
|
||||||
|
connection master;
|
||||||
|
|
||||||
|
# Bad user name
|
||||||
|
# Suppress "mysql_real_connect failed:" (printed in _DEBUG build)
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT "mysql_real_connect failed: " ""
|
||||||
|
--error ER_UNKNOWN_ERROR
|
||||||
|
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://unknown@127.0.0.1:$SLAVE_MYPORT/test/t1';
|
||||||
|
|
||||||
|
# Bad database name
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT "mysql_real_connect failed: " ""
|
||||||
|
--error ER_UNKNOWN_ERROR
|
||||||
|
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/unknown/t1';
|
||||||
|
|
||||||
|
# Bad database name, with OPTION_LIST going first.
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT "mysql_real_connect failed: " ""
|
||||||
|
--error ER_UNKNOWN_ERROR
|
||||||
|
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
OPTION_LIST='host=127.0.0.1,user=root,port=$SLAVE_MYPORT' DBNAME='unknown' TABNAME='t1';
|
||||||
|
|
||||||
|
# Bad table name
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
--error ER_UNKNOWN_ERROR
|
||||||
|
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/unknown';
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
|
||||||
|
# Bad column name
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
eval CREATE TABLE t1 (x int, y char(10)) ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1';
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
--error ER_GET_ERRMSG
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
# The remote table disappeared
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
eval CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1';
|
||||||
|
|
||||||
|
connection slave;
|
||||||
|
ALTER TABLE t1 RENAME t1backup;
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
--error ER_GET_ERRMSG
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
connection slave;
|
||||||
|
ALTER TABLE t1backup RENAME t1;
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Testing SELECT, etc.
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
# Automatic table structure
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1';
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
# Explicit table structure
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
eval CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1'
|
||||||
|
OPTION_LIST='host=127.0.0.1,user=root,port=$SLAVE_MYPORT';
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
# Explicit table structure: remote NULL, local NOT NULL
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
eval CREATE TABLE t1 (a INT NOT NULL, b CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
OPTION_LIST='host=127.0.0.1,user=root,port=$SLAVE_MYPORT';
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
# Explicit table structure with wrong column types
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
eval CREATE TABLE t1 (a char(10), b int) ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1';
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
connection slave;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Testing numeric data types
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
# TODO: mediumint is converted to int, float is converted to double, decimal is converted to double
|
||||||
|
CREATE TABLE t1 (a tinyint, b smallint, c mediumint, d int, e bigint, f float, g double, h decimal(20,5));
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
INSERT INTO t1 VALUES(100,3333,41235,1234567890,235000000000,3.14159265,3.14159265,3141.59265);
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
OPTION_LIST='host=127.0.0.1,user=root,port=$SLAVE_MYPORT';
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
connection slave;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
# TODO: unsigned does not work
|
||||||
|
#CREATE TABLE t1 (a tinyint unsigned);
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
|
||||||
|
#connection master;
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=127.0.0.1,user=root,port=$SLAVE_MYPORT';
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#SELECT * FROM t1;
|
||||||
|
#DROP TABLE t1;
|
||||||
|
|
||||||
|
#connection slave;
|
||||||
|
#DROP TABLE t1;
|
||||||
|
|
||||||
|
# TODO: add test for BIT
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Testing character data types
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a char(12), b varchar(12));
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
INSERT INTO t1 VALUES('Welcome','Hello, World');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT';
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
connection slave;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
# TODO: ERROR 1105: Unsupported column type tinytext
|
||||||
|
#CREATE TABLE t1 (a tinytext);
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=127.0.0.1,user=root,port=$SLAVE_MYPORT'
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#SELECT * FROM t1;
|
||||||
|
#DROP TABLE t1, t1;
|
||||||
|
|
||||||
|
# TODO: ERROR 1105: Unsupported column type mediumtext
|
||||||
|
#CREATE TABLE t1 (a mediumtext);
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=127.0.0.1,user=root,port=$SLAVE_MYPORT'
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#SELECT * FROM t1;
|
||||||
|
#DROP TABLE t1, t1;
|
||||||
|
|
||||||
|
# TODO: text is converted to varchar(256)
|
||||||
|
#CREATE TABLE t1 (a text);
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=127.0.0.1,user=root,port=$SLAVE_MYPORT'
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#SELECT * FROM t1;
|
||||||
|
#DROP TABLE t1, t1;
|
||||||
|
|
||||||
|
# TODO: ERROR 1105: Unsupported column type longtext
|
||||||
|
#CREATE TABLE t1 (a longtext);
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=127.0.0.1,user=root,port=$SLAVE_MYPORT'
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#SELECT * FROM t1;
|
||||||
|
#DROP TABLE t1, t1;
|
||||||
|
|
||||||
|
#TODO: add tests for ENUM
|
||||||
|
#TODO: add tests for SET
|
||||||
|
|
||||||
|
#--echo #
|
||||||
|
#--echo # Testing binary data types
|
||||||
|
#--echo #
|
||||||
|
|
||||||
|
# TODO: ERROR 1105: Unsupported column type binary
|
||||||
|
#CREATE TABLE t1 (a binary(10));
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=127.0.0.1,user=root,port=$SLAVE_MYPORT'
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#SELECT * FROM t1;
|
||||||
|
#DROP TABLE t1, t1;
|
||||||
|
|
||||||
|
# TODO: ERROR 1105: Unsupported column type varbinary
|
||||||
|
#CREATE TABLE t1 (a varbinary(10));
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=127.0.0.1,user=root,port=$SLAVE_MYPORT'
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#SELECT * FROM t1;
|
||||||
|
#DROP TABLE t1, t1;
|
||||||
|
|
||||||
|
# TODO: ERROR 1105: Unsupported column type tinyblob
|
||||||
|
#CREATE TABLE t1 (a tinyblob);
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=127.0.0.1,user=root,port=$SLAVE_MYPORT'
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#SELECT * FROM t1;
|
||||||
|
#DROP TABLE t1, t1;
|
||||||
|
|
||||||
|
# TODO: ERROR 1105: Unsupported column type mediumblob
|
||||||
|
#CREATE TABLE t1 (a mediumblob);
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=127.0.0.1,user=root,port=$SLAVE_MYPORT'
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#SELECT * FROM t1;
|
||||||
|
#DROP TABLE t1, t1;
|
||||||
|
|
||||||
|
# TODO: blob is converted to varchar(256)
|
||||||
|
#CREATE TABLE t1 (a blob);
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=127.0.0.1,user=root,port=$SLAVE_MYPORT'
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#SELECT * FROM t1;
|
||||||
|
#DROP TABLE t1, t1;
|
||||||
|
|
||||||
|
# TODO: ERROR 1105: Unsupported column type longblob
|
||||||
|
#CREATE TABLE t1 (a longblob);
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=127.0.0.1,user=root,port=$SLAVE_MYPORT'
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#SELECT * FROM t1;
|
||||||
|
#DROP TABLE t1, t1;
|
||||||
|
|
||||||
|
# TODO: ERROR 1105: Unsupported column type geometry
|
||||||
|
#CREATE TABLE t1 (a geometry);
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=127.0.0.1,user=root,port=$SLAVE_MYPORT'
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
#SHOW CREATE TABLE t1;
|
||||||
|
#SELECT * FROM t1;
|
||||||
|
#DROP TABLE t1, t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Testing temporal data types
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a date, b datetime, c time, d timestamp, e year);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
INSERT INTO t1 VALUES('2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
|
||||||
|
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT';
|
||||||
|
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
connection slave;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
-- source myconn_cleanup.inc
|
||||||
|
|
@@ -67,3 +67,13 @@ SELECT * FROM v1;
|
|||||||
|
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--replace_result $MTR_SUITE_DIR MTR_SUITE_DIR
|
||||||
|
--eval CREATE TABLE t1 ENGINE=CONNECT CATFUNC=Columns TABNAME='t1' TABLE_TYPE=ODBC CONNECTION='Driver=SQLite3 ODBC Driver;Database=$Database;NoWCHAR=yes' CHARSET=utf8 DATA_CHARSET=utf8
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--replace_result $MTR_SUITE_DIR MTR_SUITE_DIR
|
||||||
|
--eval CREATE TABLE t1 ENGINE=CONNECT CATFUNC=Tables TABNAME='t1' TABLE_TYPE=ODBC CONNECTION='Driver=SQLite3 ODBC Driver;Database=$Database;NoWCHAR=yes' CHARSET=utf8 DATA_CHARSET=utf8
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
@@ -23,4 +23,17 @@ let $MYSQLD_DATADIR= `select @@datadir`;
|
|||||||
SELECT Nom, Fonction FROM contact WHERE Repertoire='ascii';
|
SELECT Nom, Fonction FROM contact WHERE Repertoire='ascii';
|
||||||
DROP TABLE contact;
|
DROP TABLE contact;
|
||||||
|
|
||||||
|
|
||||||
|
--replace_result $MYSQLD_DATADIR DATADIR
|
||||||
|
--eval CREATE TABLE t1 ENGINE=CONNECT CATFUNC=Tables TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineXLS;DBQ=$MYSQLD_DATADIR/test/contacts.xls' CHARSET=utf8 DATA_CHARSET=latin1;
|
||||||
|
--replace_result $MYSQLD_DATADIR DATADIR
|
||||||
|
SELECT * FROM t1 WHERE Table_name='CONTACT';
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--replace_result $MYSQLD_DATADIR DATADIR
|
||||||
|
--eval CREATE TABLE t1 ENGINE=CONNECT CATFUNC=Columns TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEngineXLS;DBQ=$MYSQLD_DATADIR/test/contacts.xls' CHARSET=utf8 DATA_CHARSET=latin1;
|
||||||
|
--replace_result $MYSQLD_DATADIR DATADIR
|
||||||
|
SELECT * FROM t1 WHERE Table_name='CONTACT' AND Column_name IN ('Nom','Fonction');
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--remove_file $MYSQLD_DATADIR/test/contacts.xls
|
--remove_file $MYSQLD_DATADIR/test/contacts.xls
|
||||||
|
@@ -52,13 +52,13 @@ SELECT fname, ftype, size FROM dir1 ORDER BY fname, ftype;
|
|||||||
--echo #
|
--echo #
|
||||||
ALTER TABLE t1 READONLY=yes;
|
ALTER TABLE t1 READONLY=yes;
|
||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
INSERT INTO t1 VALUES (4,'test04');
|
INSERT INTO t1 VALUES (4,'test04');
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
UPDATE t1 SET b='test04' WHERE a=3;
|
UPDATE t1 SET b='test04' WHERE a=3;
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
DELETE FROM t1 WHERE a=3;
|
DELETE FROM t1 WHERE a=3;
|
||||||
--error ER_GET_ERRMSG
|
--error ER_OPEN_AS_READONLY
|
||||||
TRUNCATE TABLE t1;
|
TRUNCATE TABLE t1;
|
||||||
ALTER TABLE t1 READONLY=no;
|
ALTER TABLE t1 READONLY=no;
|
||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
|
@@ -29,7 +29,7 @@
|
|||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* Convert from MySQL type name to PlugDB type number */
|
/* Convert from MySQL type name to PlugDB type number */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
int MYSQLtoPLG(char *typname)
|
int MYSQLtoPLG(char *typname, char *var)
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
@@ -56,6 +56,28 @@ int MYSQLtoPLG(char *typname)
|
|||||||
else
|
else
|
||||||
type = TYPE_ERROR;
|
type = TYPE_ERROR;
|
||||||
|
|
||||||
|
if (var) {
|
||||||
|
// This is to make the difference between CHAR and VARCHAR
|
||||||
|
if (type == TYPE_STRING && stricmp(typname, "char"))
|
||||||
|
*var = 'V';
|
||||||
|
|
||||||
|
// This is to make the difference between temporal values
|
||||||
|
if (type == TYPE_DATE) {
|
||||||
|
if (!stricmp(typname, "date"))
|
||||||
|
*var = 'D';
|
||||||
|
else if (!stricmp(typname, "datetime"))
|
||||||
|
*var = 'A';
|
||||||
|
else if (!stricmp(typname, "timestamp"))
|
||||||
|
*var = 'S';
|
||||||
|
else if (!stricmp(typname, "time"))
|
||||||
|
*var = 'T';
|
||||||
|
else if (!stricmp(typname, "year"))
|
||||||
|
*var = 'Y';
|
||||||
|
|
||||||
|
} // endif type
|
||||||
|
|
||||||
|
} // endif var
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
} // end of MYSQLtoPLG
|
} // end of MYSQLtoPLG
|
||||||
|
|
||||||
@@ -98,14 +120,18 @@ enum enum_field_types PLGtoMYSQL(int type, bool dbf)
|
|||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* Convert from PlugDB type to MySQL type name */
|
/* Convert from PlugDB type to MySQL type name */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
const char *PLGtoMYSQLtype(int type, bool dbf)
|
const char *PLGtoMYSQLtype(int type, bool dbf, char v)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TYPE_INT: return "INT";
|
case TYPE_INT: return "INT";
|
||||||
case TYPE_SHORT: return "SMALLINT";
|
case TYPE_SHORT: return "SMALLINT";
|
||||||
case TYPE_FLOAT: return "DOUBLE";
|
case TYPE_FLOAT: return "DOUBLE";
|
||||||
case TYPE_DATE: return dbf ? "DATE" : "DATETIME";
|
case TYPE_DATE: return dbf ? "DATE" :
|
||||||
case TYPE_STRING: return "VARCHAR";
|
(v == 'S') ? "TIMESTAMP" :
|
||||||
|
(v == 'D') ? "DATE" :
|
||||||
|
(v == 'T') ? "TIME" :
|
||||||
|
(v == 'Y') ? "YEAR" : "DATETIME";
|
||||||
|
case TYPE_STRING: return v ? "VARCHAR" : "CHAR";
|
||||||
case TYPE_BIGINT: return "BIGINT";
|
case TYPE_BIGINT: return "BIGINT";
|
||||||
case TYPE_TINY: return "TINYINT";
|
case TYPE_TINY: return "TINYINT";
|
||||||
default: return "CHAR(0)";
|
default: return "CHAR(0)";
|
||||||
|
@@ -1,9 +1,14 @@
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Prototypes of Functions used externally. */
|
/* Prototypes of Functions used externally. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
#ifndef __MYUTIL__H
|
||||||
|
#define __MYUTIL__H
|
||||||
|
|
||||||
enum enum_field_types PLGtoMYSQL(int type, bool dbf);
|
enum enum_field_types PLGtoMYSQL(int type, bool dbf);
|
||||||
const char *PLGtoMYSQLtype(int type, bool dbf);
|
const char *PLGtoMYSQLtype(int type, bool dbf, char var = NULL);
|
||||||
int MYSQLtoPLG(char *typname);
|
int MYSQLtoPLG(char *typname, char *var = NULL);
|
||||||
int MYSQLtoPLG(int mytype);
|
int MYSQLtoPLG(int mytype);
|
||||||
char *MyDateFmt(int mytype);
|
char *MyDateFmt(int mytype);
|
||||||
char *MyDateFmt(char *typname);
|
char *MyDateFmt(char *typname);
|
||||||
|
|
||||||
|
#endif // __MYUTIL__H
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* ODBC catalog function prototypes. */
|
/* ODBC catalog function prototypes. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
#if defined(PROMPT_OK)
|
||||||
char *ODBCCheckConnection(PGLOBAL g, char *dsn, int cop);
|
char *ODBCCheckConnection(PGLOBAL g, char *dsn, int cop);
|
||||||
|
#endif // PROMPT_OK
|
||||||
PQRYRES ODBCDataSources(PGLOBAL g, bool info);
|
PQRYRES ODBCDataSources(PGLOBAL g, bool info);
|
||||||
PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *table,
|
PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *table,
|
||||||
char *colpat, bool info);
|
char *colpat, bool info);
|
||||||
|
@@ -108,16 +108,18 @@ static int GetSQLCType(int type)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* TranslateSQLType: translate a SQL Type to a PLG type. */
|
/* TranslateSQLType: translate a SQL Type to a PLG type. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
int TranslateSQLType(int stp, int prec, int& len)
|
int TranslateSQLType(int stp, int prec, int& len, char& v)
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
switch (stp) {
|
switch (stp) {
|
||||||
case SQL_CHAR: // 1
|
|
||||||
case SQL_VARCHAR: // 12
|
case SQL_VARCHAR: // 12
|
||||||
|
v = 'V';
|
||||||
|
case SQL_CHAR: // 1
|
||||||
type = TYPE_STRING;
|
type = TYPE_STRING;
|
||||||
break;
|
break;
|
||||||
case SQL_LONGVARCHAR: // (-1)
|
case SQL_LONGVARCHAR: // (-1)
|
||||||
|
v = 'V';
|
||||||
type = TYPE_STRING;
|
type = TYPE_STRING;
|
||||||
len = min(abs(len), 255);
|
len = min(abs(len), 255);
|
||||||
break;
|
break;
|
||||||
@@ -172,6 +174,7 @@ int TranslateSQLType(int stp, int prec, int& len)
|
|||||||
return type;
|
return type;
|
||||||
} // end of TranslateSQLType
|
} // end of TranslateSQLType
|
||||||
|
|
||||||
|
#if defined(PROMPT_OK)
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* ODBCCheckConnection: Check completeness of connection string. */
|
/* ODBCCheckConnection: Check completeness of connection string. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -203,6 +206,7 @@ char *ODBCCheckConnection(PGLOBAL g, char *dsn, int cop)
|
|||||||
ocp->Close();
|
ocp->Close();
|
||||||
return newdsn; // Return complete connection string
|
return newdsn; // Return complete connection string
|
||||||
} // end of ODBCCheckConnection
|
} // end of ODBCCheckConnection
|
||||||
|
#endif // PROMPT_OK
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Allocate the structure used to refer to the result set. */
|
/* Allocate the structure used to refer to the result set. */
|
||||||
@@ -871,7 +875,8 @@ ODBConn::ODBConn(PGLOBAL g, TDBODBC *tdbp)
|
|||||||
m_Connect = NULL;
|
m_Connect = NULL;
|
||||||
m_Updatable = true;
|
m_Updatable = true;
|
||||||
m_Transact = false;
|
m_Transact = false;
|
||||||
m_IDQuoteChar = '\'';
|
m_IDQuoteChar[0] = '"';
|
||||||
|
m_IDQuoteChar[1] = 0;
|
||||||
//*m_ErrMsg = '\0';
|
//*m_ErrMsg = '\0';
|
||||||
} // end of ODBConn
|
} // end of ODBConn
|
||||||
|
|
||||||
@@ -889,7 +894,7 @@ bool ODBConn::Check(RETCODE rc)
|
|||||||
{
|
{
|
||||||
switch (rc) {
|
switch (rc) {
|
||||||
case SQL_SUCCESS_WITH_INFO:
|
case SQL_SUCCESS_WITH_INFO:
|
||||||
if (trace > 1) {
|
if (trace) {
|
||||||
DBX x(rc);
|
DBX x(rc);
|
||||||
|
|
||||||
x.BuildErrorMessage(this, m_hstmt);
|
x.BuildErrorMessage(this, m_hstmt);
|
||||||
@@ -1113,7 +1118,7 @@ bool ODBConn::Connect(DWORD Options)
|
|||||||
if (hWnd == NULL)
|
if (hWnd == NULL)
|
||||||
hWnd = GetDesktopWindow();
|
hWnd = GetDesktopWindow();
|
||||||
#else // !WIN32
|
#else // !WIN32
|
||||||
HWND hWnd = 1;
|
HWND hWnd = (HWND)1;
|
||||||
#endif // !WIN32
|
#endif // !WIN32
|
||||||
PGLOBAL& g = m_G;
|
PGLOBAL& g = m_G;
|
||||||
PDBUSER dup = PlgGetUser(g);
|
PDBUSER dup = PlgGetUser(g);
|
||||||
@@ -1230,20 +1235,13 @@ void ODBConn::GetConnectInfo()
|
|||||||
SQL_MODE_READ_ONLY);
|
SQL_MODE_READ_ONLY);
|
||||||
#endif // 0
|
#endif // 0
|
||||||
|
|
||||||
// Cache the quote char to use when constructing SQL
|
// Get the quote char to use when constructing SQL
|
||||||
char QuoteChar[2];
|
|
||||||
|
|
||||||
rc = SQLGetInfo(m_hdbc, SQL_IDENTIFIER_QUOTE_CHAR,
|
rc = SQLGetInfo(m_hdbc, SQL_IDENTIFIER_QUOTE_CHAR,
|
||||||
QuoteChar, sizeof(QuoteChar), &nResult);
|
m_IDQuoteChar, sizeof(m_IDQuoteChar), &nResult);
|
||||||
|
|
||||||
if (Check(rc) && nResult == 1)
|
|
||||||
m_IDQuoteChar = QuoteChar[0];
|
|
||||||
else
|
|
||||||
m_IDQuoteChar = ' ';
|
|
||||||
|
|
||||||
if (trace)
|
if (trace)
|
||||||
htrc("DBMS: %s, Version: %s",
|
htrc("DBMS: %s, Version: %s, rc=%d\n",
|
||||||
GetStringInfo(SQL_DBMS_NAME), GetStringInfo(SQL_DBMS_VER));
|
GetStringInfo(SQL_DBMS_NAME), GetStringInfo(SQL_DBMS_VER), rc);
|
||||||
|
|
||||||
} // end of GetConnectInfo
|
} // end of GetConnectInfo
|
||||||
|
|
||||||
@@ -1511,14 +1509,16 @@ int ODBConn::PrepareSQL(char *sql)
|
|||||||
|
|
||||||
hstmt = m_hstmt;
|
hstmt = m_hstmt;
|
||||||
m_hstmt = NULL;
|
m_hstmt = NULL;
|
||||||
ThrowDBX(MSG(SEQUENCE_ERROR));
|
|
||||||
} else {
|
|
||||||
rc = SQLAllocStmt(m_hdbc, &hstmt);
|
|
||||||
|
|
||||||
if (!Check(rc))
|
if (m_Tdb->GetAmType() != TYPE_AM_XDBC)
|
||||||
ThrowDBX(SQL_INVALID_HANDLE, "SQLAllocStmt");
|
ThrowDBX(MSG(SEQUENCE_ERROR));
|
||||||
|
|
||||||
} // endif hstmt
|
} // endif m_hstmt
|
||||||
|
|
||||||
|
rc = SQLAllocStmt(m_hdbc, &hstmt);
|
||||||
|
|
||||||
|
if (!Check(rc))
|
||||||
|
ThrowDBX(SQL_INVALID_HANDLE, "SQLAllocStmt");
|
||||||
|
|
||||||
OnSetOptions(hstmt);
|
OnSetOptions(hstmt);
|
||||||
b = true;
|
b = true;
|
||||||
@@ -1565,7 +1565,7 @@ int ODBConn::PrepareSQL(char *sql)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Execute a prepared statement. */
|
/* Execute a prepared statement. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
int ODBConn::ExecuteSQL(bool x)
|
int ODBConn::ExecuteSQL(void)
|
||||||
{
|
{
|
||||||
PGLOBAL& g = m_G;
|
PGLOBAL& g = m_G;
|
||||||
SWORD ncol = 0;
|
SWORD ncol = 0;
|
||||||
@@ -1580,26 +1580,17 @@ int ODBConn::ExecuteSQL(bool x)
|
|||||||
if (!Check(rc))
|
if (!Check(rc))
|
||||||
ThrowDBX(rc, "SQLExecute", m_hstmt);
|
ThrowDBX(rc, "SQLExecute", m_hstmt);
|
||||||
|
|
||||||
if (!Check(SQLNumResultCols(m_hstmt, &ncol)))
|
if (!Check(rc = SQLNumResultCols(m_hstmt, &ncol)))
|
||||||
ThrowDBX(rc, "SQLNumResultCols", m_hstmt);
|
ThrowDBX(rc, "SQLNumResultCols", m_hstmt);
|
||||||
|
|
||||||
if (ncol) {
|
if (ncol) {
|
||||||
if (x) {
|
// This should never happen while inserting
|
||||||
afrw = ncol;
|
strcpy(g->Message, "Logical error while inserting");
|
||||||
strcpy(g->Message, "Result set column number");
|
|
||||||
} else {
|
|
||||||
// This should never happen while inserting
|
|
||||||
strcpy(g->Message, "Logical error while inserting");
|
|
||||||
} // endif ncol
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Insert, Update or Delete statement
|
// Insert, Update or Delete statement
|
||||||
if (!Check(SQLRowCount(m_hstmt, &afrw)))
|
if (!Check(rc = SQLRowCount(m_hstmt, &afrw)))
|
||||||
ThrowDBX(rc, "SQLRowCount", m_hstmt);
|
ThrowDBX(rc, "SQLRowCount", m_hstmt);
|
||||||
|
|
||||||
if (x)
|
|
||||||
strcpy(g->Message, "Affected rows");
|
|
||||||
|
|
||||||
} // endif ncol
|
} // endif ncol
|
||||||
|
|
||||||
} catch(DBX *x) {
|
} catch(DBX *x) {
|
||||||
@@ -1613,6 +1604,7 @@ int ODBConn::ExecuteSQL(bool x)
|
|||||||
m_Transact = false;
|
m_Transact = false;
|
||||||
} // endif m_Transact
|
} // endif m_Transact
|
||||||
|
|
||||||
|
afrw = -1;
|
||||||
} // end try/catch
|
} // end try/catch
|
||||||
|
|
||||||
return (int)afrw;
|
return (int)afrw;
|
||||||
@@ -1667,6 +1659,112 @@ bool ODBConn::BindParam(ODBCCOL *colp)
|
|||||||
return false;
|
return false;
|
||||||
} // end of BindParam
|
} // end of BindParam
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Execute an SQL command. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool ODBConn::ExecSQLcommand(char *sql)
|
||||||
|
{
|
||||||
|
char cmd[16];
|
||||||
|
bool b, rcd = false;
|
||||||
|
UINT txn = 0;
|
||||||
|
PGLOBAL& g = m_G;
|
||||||
|
SWORD ncol = 0;
|
||||||
|
SQLLEN afrw;
|
||||||
|
RETCODE rc;
|
||||||
|
HSTMT hstmt;
|
||||||
|
|
||||||
|
try {
|
||||||
|
b = FALSE;
|
||||||
|
|
||||||
|
// Check whether we should use transaction
|
||||||
|
if (sscanf(sql, " %15s ", cmd) == 1) {
|
||||||
|
if (!stricmp(cmd, "INSERT") || !stricmp(cmd, "UPDATE") ||
|
||||||
|
!stricmp(cmd, "DELETE") || !stricmp(cmd, "REPLACE")) {
|
||||||
|
// Does the data source support transactions
|
||||||
|
rc = SQLGetInfo(m_hdbc, SQL_TXN_CAPABLE, &txn, 0, NULL);
|
||||||
|
|
||||||
|
if (Check(rc) && txn != SQL_TC_NONE) {
|
||||||
|
rc = SQLSetConnectAttr(m_hdbc, SQL_ATTR_AUTOCOMMIT,
|
||||||
|
SQL_AUTOCOMMIT_OFF, SQL_IS_UINTEGER);
|
||||||
|
|
||||||
|
if (!Check(rc))
|
||||||
|
ThrowDBX(SQL_INVALID_HANDLE, "SQLSetConnectAttr");
|
||||||
|
|
||||||
|
m_Transact = TRUE;
|
||||||
|
} // endif txn
|
||||||
|
|
||||||
|
} // endif cmd
|
||||||
|
|
||||||
|
} // endif sql
|
||||||
|
|
||||||
|
// Allocate the statement handle
|
||||||
|
rc = SQLAllocStmt(m_hdbc, &hstmt);
|
||||||
|
|
||||||
|
if (!Check(rc))
|
||||||
|
ThrowDBX(SQL_INVALID_HANDLE, "SQLAllocStmt");
|
||||||
|
|
||||||
|
OnSetOptions(hstmt);
|
||||||
|
b = true;
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc("ExecSQLcommand hstmt=%p %.64s\n", hstmt, sql);
|
||||||
|
|
||||||
|
// Proceed with command execution
|
||||||
|
do {
|
||||||
|
rc = SQLExecDirect(hstmt, (PUCHAR)sql, SQL_NTS);
|
||||||
|
} while (rc == SQL_STILL_EXECUTING);
|
||||||
|
|
||||||
|
if (!Check(rc))
|
||||||
|
ThrowDBX(rc, "SQLExecDirect", hstmt);
|
||||||
|
|
||||||
|
// Check whether this is a query returning a result set
|
||||||
|
if (!Check(rc = SQLNumResultCols(hstmt, &ncol)))
|
||||||
|
ThrowDBX(rc, "SQLNumResultCols", hstmt);
|
||||||
|
|
||||||
|
if (!ncol) {
|
||||||
|
if (!Check(SQLRowCount(hstmt, &afrw)))
|
||||||
|
ThrowDBX(rc, "SQLRowCount", hstmt);
|
||||||
|
|
||||||
|
m_Tdb->AftRows = (int)afrw;
|
||||||
|
strcpy(g->Message, "Affected rows");
|
||||||
|
} else {
|
||||||
|
m_Tdb->AftRows = (int)ncol;
|
||||||
|
strcpy(g->Message, "Result set column number");
|
||||||
|
} // endif ncol
|
||||||
|
|
||||||
|
} catch(DBX *x) {
|
||||||
|
if (trace)
|
||||||
|
for (int i = 0; i < MAX_NUM_OF_MSG && x->m_ErrMsg[i]; i++)
|
||||||
|
htrc(x->m_ErrMsg[i]);
|
||||||
|
|
||||||
|
sprintf(g->Message, "Remote: %s", x->GetErrorMessage(0));
|
||||||
|
|
||||||
|
if (b)
|
||||||
|
SQLCancel(hstmt);
|
||||||
|
|
||||||
|
m_Tdb->AftRows = -1;
|
||||||
|
rcd = true;
|
||||||
|
} // end try/catch
|
||||||
|
|
||||||
|
if (!Check(rc = SQLFreeStmt(hstmt, SQL_CLOSE)))
|
||||||
|
sprintf(g->Message, "SQLFreeStmt: rc=%d", rc);
|
||||||
|
|
||||||
|
if (m_Transact) {
|
||||||
|
// Terminate the transaction
|
||||||
|
if (!Check(rc = SQLEndTran(SQL_HANDLE_DBC, m_hdbc,
|
||||||
|
(rcd) ? SQL_ROLLBACK : SQL_COMMIT)))
|
||||||
|
sprintf(g->Message, "SQLEndTran: rc=%d", rc);
|
||||||
|
|
||||||
|
if (!Check(rc = SQLSetConnectAttr(m_hdbc, SQL_ATTR_AUTOCOMMIT,
|
||||||
|
(SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_IS_UINTEGER)))
|
||||||
|
sprintf(g->Message, "SQLSetConnectAttr: rc=%d", rc);
|
||||||
|
|
||||||
|
m_Transact = false;
|
||||||
|
} // endif m_Transact
|
||||||
|
|
||||||
|
return rcd;
|
||||||
|
} // end of ExecSQLcommand
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* GetMetaData: constructs the result blocks containing the */
|
/* GetMetaData: constructs the result blocks containing the */
|
||||||
/* description of all the columns of an SQL command. */
|
/* description of all the columns of an SQL command. */
|
||||||
|
@@ -127,7 +127,7 @@ class ODBConn : public BLOCK {
|
|||||||
|
|
||||||
// Attributes
|
// Attributes
|
||||||
public:
|
public:
|
||||||
char GetQuoteChar(void) {return m_IDQuoteChar;}
|
char *GetQuoteChar(void) {return m_IDQuoteChar;}
|
||||||
// Database successfully opened?
|
// Database successfully opened?
|
||||||
bool IsOpen(void) {return m_hdbc != SQL_NULL_HDBC;}
|
bool IsOpen(void) {return m_hdbc != SQL_NULL_HDBC;}
|
||||||
PSZ GetStringInfo(ushort infotype);
|
PSZ GetStringInfo(ushort infotype);
|
||||||
@@ -142,8 +142,9 @@ class ODBConn : public BLOCK {
|
|||||||
int ExecDirectSQL(char *sql, ODBCCOL *tocols);
|
int ExecDirectSQL(char *sql, ODBCCOL *tocols);
|
||||||
int Fetch(void);
|
int Fetch(void);
|
||||||
int PrepareSQL(char *sql);
|
int PrepareSQL(char *sql);
|
||||||
int ExecuteSQL(bool x);
|
int ExecuteSQL(void);
|
||||||
bool BindParam(ODBCCOL *colp);
|
bool BindParam(ODBCCOL *colp);
|
||||||
|
bool ExecSQLcommand(char *sql);
|
||||||
int GetCatInfo(CATPARM *cap);
|
int GetCatInfo(CATPARM *cap);
|
||||||
bool GetDataSources(PQRYRES qrp);
|
bool GetDataSources(PQRYRES qrp);
|
||||||
bool GetDrivers(PQRYRES qrp);
|
bool GetDrivers(PQRYRES qrp);
|
||||||
@@ -183,9 +184,9 @@ class ODBConn : public BLOCK {
|
|||||||
DWORD m_QueryTimeout;
|
DWORD m_QueryTimeout;
|
||||||
DWORD m_UpdateOptions;
|
DWORD m_UpdateOptions;
|
||||||
DWORD m_RowsetSize;
|
DWORD m_RowsetSize;
|
||||||
|
char m_IDQuoteChar[2];
|
||||||
int m_Catver;
|
int m_Catver;
|
||||||
PSZ m_Connect;
|
PSZ m_Connect;
|
||||||
bool m_Updatable;
|
bool m_Updatable;
|
||||||
bool m_Transact;
|
bool m_Transact;
|
||||||
char m_IDQuoteChar;
|
|
||||||
}; // end of ODBConn class definition
|
}; // end of ODBConn class definition
|
||||||
|
@@ -106,13 +106,20 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
|
|||||||
TYPE_AM_DOM = 80, /* DOM access method type no */
|
TYPE_AM_DOM = 80, /* DOM access method type no */
|
||||||
TYPE_AM_DIR = 90, /* DIR access method type no */
|
TYPE_AM_DIR = 90, /* DIR access method type no */
|
||||||
TYPE_AM_ODBC = 100, /* ODBC access method type no */
|
TYPE_AM_ODBC = 100, /* ODBC access method type no */
|
||||||
|
TYPE_AM_XDBC = 101, /* XDBC access method type no */
|
||||||
TYPE_AM_OEM = 110, /* OEM access method type no */
|
TYPE_AM_OEM = 110, /* OEM access method type no */
|
||||||
TYPE_AM_TBL = 115, /* TBL access method type no */
|
TYPE_AM_TBL = 115, /* TBL access method type no */
|
||||||
TYPE_AM_PIVOT = 120, /* PIVOT access method type no */
|
TYPE_AM_PIVOT = 120, /* PIVOT access method type no */
|
||||||
TYPE_AM_SRC = 121, /* PIVOT multiple column type no */
|
TYPE_AM_SRC = 121, /* PIVOT multiple column type no */
|
||||||
TYPE_AM_FNC = 122, /* PIVOT source column type no */
|
TYPE_AM_FNC = 122, /* PIVOT source column type no */
|
||||||
|
TYPE_AM_XCOL = 124, /* XCOL access method type no */
|
||||||
TYPE_AM_XML = 127, /* XML access method type no */
|
TYPE_AM_XML = 127, /* XML access method type no */
|
||||||
|
TYPE_AM_OCCUR = 128, /* OCCUR access method type no */
|
||||||
|
TYPE_AM_PRX = 129, /* PROXY access method type no */
|
||||||
TYPE_AM_XTB = 130, /* SYS table access method type */
|
TYPE_AM_XTB = 130, /* SYS table access method type */
|
||||||
|
TYPE_AM_BLK = 131, /* BLK access method type no */
|
||||||
|
TYPE_AM_ZIP = 132, /* ZIP access method type no */
|
||||||
|
TYPE_AM_ZLIB = 133, /* ZLIB access method type no */
|
||||||
TYPE_AM_MAC = 137, /* MAC table access method type */
|
TYPE_AM_MAC = 137, /* MAC table access method type */
|
||||||
TYPE_AM_WMI = 139, /* WMI table access method type */
|
TYPE_AM_WMI = 139, /* WMI table access method type */
|
||||||
TYPE_AM_XCL = 140, /* SYS column access method type */
|
TYPE_AM_XCL = 140, /* SYS column access method type */
|
||||||
@@ -123,7 +130,8 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
|
|||||||
TYPE_AM_DMY = 172, /* DMY Dummy tables am type no */
|
TYPE_AM_DMY = 172, /* DMY Dummy tables am type no */
|
||||||
TYPE_AM_SET = 180, /* SET Set tables am type no */
|
TYPE_AM_SET = 180, /* SET Set tables am type no */
|
||||||
TYPE_AM_MYSQL = 192, /* MYSQL access method type no */
|
TYPE_AM_MYSQL = 192, /* MYSQL access method type no */
|
||||||
TYPE_AM_CAT = 193, /* Catalog access method type no */
|
TYPE_AM_MYX = 193, /* MYSQL EXEC access method type */
|
||||||
|
TYPE_AM_CAT = 195, /* Catalog access method type no */
|
||||||
TYPE_AM_OUT = 200}; /* Output relations (storage) */
|
TYPE_AM_OUT = 200}; /* Output relations (storage) */
|
||||||
|
|
||||||
enum RECFM {RECFM_NAF = -2, /* Not a file */
|
enum RECFM {RECFM_NAF = -2, /* Not a file */
|
||||||
@@ -585,4 +593,4 @@ int global_open(GLOBAL *g, int msgid, const char *filename, int flags, int mode)
|
|||||||
DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR name, LPCSTR dir);
|
DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR name, LPCSTR dir);
|
||||||
char *MakeEscape(PGLOBAL g, char* str, char q);
|
char *MakeEscape(PGLOBAL g, char* str, char q);
|
||||||
|
|
||||||
bool PushWarning(PGLOBAL, PTDBASE);
|
bool PushWarning(PGLOBAL, PTDBASE, int level = 1);
|
||||||
|
@@ -330,7 +330,7 @@ PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
|
|||||||
// Allocate the Value Block that will contain data
|
// Allocate the Value Block that will contain data
|
||||||
if (crp->Length || nonull)
|
if (crp->Length || nonull)
|
||||||
crp->Kdata = AllocValBlock(g, NULL, crp->Type, maxres,
|
crp->Kdata = AllocValBlock(g, NULL, crp->Type, maxres,
|
||||||
crp->Length, 0, true, blank);
|
crp->Length, 0, true, blank, false);
|
||||||
else
|
else
|
||||||
crp->Kdata = NULL;
|
crp->Kdata = NULL;
|
||||||
|
|
||||||
|
@@ -77,7 +77,7 @@ extern "C" int trace;
|
|||||||
/* No conversion of block values (check = true). */
|
/* No conversion of block values (check = true). */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PVBLK AllocValBlock(PGLOBAL, void *, int, int, int len = 0, int prec = 0,
|
PVBLK AllocValBlock(PGLOBAL, void *, int, int, int len = 0, int prec = 0,
|
||||||
bool check = true, bool blank = false);
|
bool check = true, bool blank = false, bool un = false);
|
||||||
|
|
||||||
/* --------------------------- Class DOSDEF -------------------------- */
|
/* --------------------------- Class DOSDEF -------------------------- */
|
||||||
|
|
||||||
|
@@ -524,6 +524,7 @@ bool TDBCAT::OpenDB(PGLOBAL g)
|
|||||||
if (Initialize(g))
|
if (Initialize(g))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
Use = USE_OPEN;
|
||||||
return InitCol(g);
|
return InitCol(g);
|
||||||
} // end of OpenDB
|
} // end of OpenDB
|
||||||
|
|
||||||
|
@@ -321,7 +321,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
Portnumber = Cat->GetIntCatInfo("Port", GetDefaultPort());
|
Portnumber = Cat->GetIntCatInfo("Port", GetDefaultPort());
|
||||||
Server = Hostname;
|
Server = Hostname;
|
||||||
} else if (ParseURL(g, url))
|
} else if (ParseURL(g, url))
|
||||||
return TRUE;
|
return true;
|
||||||
|
|
||||||
Bind = !!Cat->GetIntCatInfo("Bind", 0);
|
Bind = !!Cat->GetIntCatInfo("Bind", 0);
|
||||||
Delayed = !!Cat->GetIntCatInfo("Delayed", 0);
|
Delayed = !!Cat->GetIntCatInfo("Delayed", 0);
|
||||||
@@ -344,7 +344,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
char *locdb = Database;
|
char *locdb = Database;
|
||||||
|
|
||||||
if (ParseURL(g, url))
|
if (ParseURL(g, url))
|
||||||
return TRUE;
|
return true;
|
||||||
|
|
||||||
Database = locdb;
|
Database = locdb;
|
||||||
} // endif url
|
} // endif url
|
||||||
@@ -353,9 +353,15 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
} // endif am
|
} // endif am
|
||||||
|
|
||||||
if ((Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL)))
|
if ((Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL)))
|
||||||
Isview = TRUE;
|
Isview = true;
|
||||||
|
|
||||||
Xsrc = Cat->GetBoolCatInfo("Execsrc", FALSE);
|
// Used for Update and Delete
|
||||||
|
Qrystr = Cat->GetStringCatInfo(g, "Query_String", "?");
|
||||||
|
Quoted = Cat->GetIntCatInfo("Quoted", 0);
|
||||||
|
|
||||||
|
// Specific for command executing tables
|
||||||
|
Xsrc = Cat->GetBoolCatInfo("Execsrc", false);
|
||||||
|
Mxr = Cat->GetIntCatInfo("Maxerr", 0);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} // end of DefineAM
|
} // end of DefineAM
|
||||||
|
|
||||||
@@ -388,6 +394,8 @@ TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp)
|
|||||||
User = tdp->Username;
|
User = tdp->Username;
|
||||||
Pwd = tdp->Password;
|
Pwd = tdp->Password;
|
||||||
Server = tdp->Server;
|
Server = tdp->Server;
|
||||||
|
Qrystr = tdp->Qrystr;
|
||||||
|
Quoted = max(0, tdp->Quoted);
|
||||||
Port = tdp->Portnumber;
|
Port = tdp->Portnumber;
|
||||||
Isview = tdp->Isview;
|
Isview = tdp->Isview;
|
||||||
Prep = tdp->Bind;
|
Prep = tdp->Bind;
|
||||||
@@ -400,6 +408,8 @@ TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp)
|
|||||||
User = NULL;
|
User = NULL;
|
||||||
Pwd = NULL;
|
Pwd = NULL;
|
||||||
Server = NULL;
|
Server = NULL;
|
||||||
|
Qrystr = NULL;
|
||||||
|
Quoted = 0;
|
||||||
Port = 0;
|
Port = 0;
|
||||||
Isview = FALSE;
|
Isview = FALSE;
|
||||||
Prep = FALSE;
|
Prep = FALSE;
|
||||||
@@ -424,6 +434,8 @@ TDBMYSQL::TDBMYSQL(PGLOBAL g, PTDBMY tdbp) : TDBASE(tdbp)
|
|||||||
Srcdef = tdbp->Srcdef;
|
Srcdef = tdbp->Srcdef;
|
||||||
User = tdbp->User;
|
User = tdbp->User;
|
||||||
Pwd = tdbp->Pwd;
|
Pwd = tdbp->Pwd;
|
||||||
|
Qrystr = tdbp->Qrystr;
|
||||||
|
Quoted = tdbp->Quoted;
|
||||||
Port = tdbp->Port;
|
Port = tdbp->Port;
|
||||||
Isview = tdbp->Isview;
|
Isview = tdbp->Isview;
|
||||||
Prep = tdbp->Prep;
|
Prep = tdbp->Prep;
|
||||||
@@ -516,7 +528,7 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g)
|
|||||||
strcat(strcat(strcat(strcat(Query, " FROM "), tk), Tabname), tk);
|
strcat(strcat(strcat(strcat(Query, " FROM "), tk), Tabname), tk);
|
||||||
|
|
||||||
if (To_Filter)
|
if (To_Filter)
|
||||||
strcat(strcat(Query, " WHERE "), To_Filter);
|
strcat(strcat(Query, " WHERE "), To_Filter->Body);
|
||||||
|
|
||||||
if (trace)
|
if (trace)
|
||||||
htrc("Query=%s\n", Query);
|
htrc("Query=%s\n", Query);
|
||||||
@@ -610,118 +622,109 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
} // end of MakeInsert
|
} // end of MakeInsert
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* MakeCommand: make the Update or Delete statement to send to the */
|
||||||
|
/* MySQL server. Limited to remote values and filtering. */
|
||||||
|
/***********************************************************************/
|
||||||
|
int TDBMYSQL::MakeCommand(PGLOBAL g)
|
||||||
|
{
|
||||||
|
Query = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
|
||||||
|
|
||||||
|
if (Quoted > 0 || stricmp(Name, Tabname)) {
|
||||||
|
char *p, *qrystr, name[68];
|
||||||
|
bool qtd = Quoted > 0;
|
||||||
|
|
||||||
|
|
||||||
|
// Make a lower case copy of the originale query
|
||||||
|
qrystr = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 1);
|
||||||
|
strlwr(strcpy(qrystr, Qrystr));
|
||||||
|
|
||||||
|
// 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), "`"));
|
||||||
|
|
||||||
|
if (!strstr("`update`delete`low_priority`ignore`quick`from`", name))
|
||||||
|
strlwr(strcpy(name, Name)); // Not a keyword
|
||||||
|
|
||||||
|
if ((p = strstr(qrystr, name))) {
|
||||||
|
memcpy(Query, Qrystr, p - qrystr);
|
||||||
|
Query[p - qrystr] = 0;
|
||||||
|
|
||||||
|
if (qtd && *(p-1) == ' ')
|
||||||
|
strcat(strcat(strcat(Query, "`"), Tabname), "`");
|
||||||
|
else
|
||||||
|
strcat(Query, Tabname);
|
||||||
|
|
||||||
|
strcat(Query, Qrystr + (p - qrystr) + strlen(name));
|
||||||
|
} else {
|
||||||
|
sprintf(g->Message, "Cannot use this %s command",
|
||||||
|
(Mode == MODE_UPDATE) ? "UPDATE" : "DELETE");
|
||||||
|
return RC_FX;
|
||||||
|
} // endif p
|
||||||
|
|
||||||
|
} else
|
||||||
|
strcpy(Query, Qrystr);
|
||||||
|
|
||||||
|
return RC_OK;
|
||||||
|
} // end of MakeCommand
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* MakeUpdate: make the Update statement use with MySQL connection. */
|
/* MakeUpdate: make the Update statement use with MySQL connection. */
|
||||||
/* Note: currently limited to local values and filtering. */
|
/* Limited to remote values and filtering. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool TDBMYSQL::MakeUpdate(PGLOBAL g, PSELECT selist)
|
int TDBMYSQL::MakeUpdate(PGLOBAL g)
|
||||||
{
|
{
|
||||||
char *setlist, *colname, *where = NULL, *tk = "`";
|
char *qc, cmd[8], tab[96], end[1024];
|
||||||
int len = 0, nset = 0;
|
|
||||||
bool b = FALSE;
|
|
||||||
PXOB xp;
|
|
||||||
PSELECT selp;
|
|
||||||
|
|
||||||
if (Query)
|
Query = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
|
||||||
return FALSE; // already done
|
memset(end, 0, sizeof(end));
|
||||||
|
|
||||||
if (To_Filter)
|
if (sscanf(Qrystr, "%s `%[^`]`%1023c", cmd, tab, end) > 2 ||
|
||||||
if (To_Filter->CheckLocal(this)) {
|
sscanf(Qrystr, "%s \"%[^\"]\"%1023c", cmd, tab, end) > 2)
|
||||||
where = (char*)PlugSubAlloc(g, NULL, 512); // Should be enough
|
qc = "`";
|
||||||
*where = '\0';
|
else if (sscanf(Qrystr, "%s %s%1023c", cmd, tab, end) > 2
|
||||||
|
&& !stricmp(tab, Name))
|
||||||
|
qc = (Quoted) ? "`" : "";
|
||||||
|
else {
|
||||||
|
strcpy(g->Message, "Cannot use this UPDATE command");
|
||||||
|
return RC_FX;
|
||||||
|
} // endif sscanf
|
||||||
|
|
||||||
if (!PlugRephraseSQL(g, where, To_Filter, TYPE_FILTER, tk))
|
assert(!stricmp(cmd, "update"));
|
||||||
return TRUE;
|
strcat(strcat(strcat(strcpy(Query, "UPDATE "), qc), Tabname), qc);
|
||||||
|
strcat(Query, end);
|
||||||
To_Filter = NULL;
|
return RC_OK;
|
||||||
len = strlen(where);
|
|
||||||
} else {
|
|
||||||
strcpy(g->Message, MSG(NO_REF_UPDATE));
|
|
||||||
return TRUE;
|
|
||||||
} // endif Local
|
|
||||||
|
|
||||||
for (selp = selist; selp; selp = selp->GetNext_Proj())
|
|
||||||
nset++;
|
|
||||||
|
|
||||||
assert(nset);
|
|
||||||
|
|
||||||
// Allocate a pretty big buffer
|
|
||||||
setlist = (char*)PlugSubAlloc(g, NULL, 256 * nset);
|
|
||||||
*setlist = '\0';
|
|
||||||
|
|
||||||
for (selp = selist; selp; selp = selp->GetNext_Proj()) {
|
|
||||||
if (selp->GetSetType() == TYPE_COLBLK) {
|
|
||||||
colname = selp->GetSetCol()->GetName();
|
|
||||||
} else if (selp->GetSetType() == TYPE_COLUMN) {
|
|
||||||
colname = (char*)((PCOLUMN)selp->GetSetCol())->GetName();
|
|
||||||
} else {
|
|
||||||
sprintf(g->Message, MSG(BAD_SET_TYPE), selp->GetSetType());
|
|
||||||
return TRUE;
|
|
||||||
} // endif Type
|
|
||||||
|
|
||||||
if (b)
|
|
||||||
strcat(setlist, ", ");
|
|
||||||
else
|
|
||||||
b = TRUE;
|
|
||||||
|
|
||||||
strcat(strcat(strcat(strcat(setlist, tk), colname), tk), " = ");
|
|
||||||
|
|
||||||
xp = selp->GetObject();
|
|
||||||
|
|
||||||
if (!xp->CheckLocal(this)) {
|
|
||||||
strcpy(g->Message, MSG(NO_REF_UPDATE));
|
|
||||||
return TRUE;
|
|
||||||
} else if (xp->GetType() == TYPE_SUBQ)
|
|
||||||
// Cannot be correlated because CheckLocal would have failed
|
|
||||||
xp = new(g) CONSTANT(xp->GetValue());
|
|
||||||
|
|
||||||
if (!PlugRephraseSQL(g, setlist + strlen(setlist),
|
|
||||||
xp, TYPE_XOBJECT, tk))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
} // endfor selp
|
|
||||||
|
|
||||||
// Below 16 is enough to take care of the fixed part of the query
|
|
||||||
len += (strlen(setlist) + strlen(Tabname) + 16);
|
|
||||||
Query = (char*)PlugSubAlloc(g, NULL, len);
|
|
||||||
strcat(strcat(strcat(strcpy(Query, "UPDATE "), tk), Tabname), tk);
|
|
||||||
strcat(strcat(Query, " SET "), setlist);
|
|
||||||
|
|
||||||
if (where)
|
|
||||||
strcat(Query, where);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
} // end of MakeUpdate
|
} // end of MakeUpdate
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* MakeDelete: make the Delete statement use with MySQL connection. */
|
/* MakeDelete: make the Delete statement used with MySQL connection. */
|
||||||
/* If no filtering Truncate is used because it is faster than Delete. */
|
/* Limited to remote filtering. */
|
||||||
/* However, the number of deleted lines is not returned by MySQL. */
|
|
||||||
/* Note: currently limited to local filtering. */
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool TDBMYSQL::MakeDelete(PGLOBAL g)
|
int TDBMYSQL::MakeDelete(PGLOBAL g)
|
||||||
{
|
{
|
||||||
char *tk = "`";
|
char *qc, cmd[8], from[8], tab[96], end[512];
|
||||||
int len = 0;
|
|
||||||
|
|
||||||
if (Query)
|
Query = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
|
||||||
return FALSE; // already done
|
memset(end, 0, sizeof(end));
|
||||||
|
|
||||||
if (!To_Filter)
|
if (sscanf(Qrystr, "%s %s `%[^`]`%511c", cmd, from, tab, end) > 2 ||
|
||||||
AftRows = -1; // Means "all lines deleted"
|
sscanf(Qrystr, "%s %s \"%[^\"]\"%511c", cmd, from, tab, end) > 2)
|
||||||
|
qc = "`";
|
||||||
|
else if (sscanf(Qrystr, "%s %s %s%511c", cmd, from, tab, end) > 2)
|
||||||
|
qc = (Quoted) ? "`" : "";
|
||||||
|
else {
|
||||||
|
strcpy(g->Message, "Cannot use this DELETE command");
|
||||||
|
return RC_FX;
|
||||||
|
} // endif sscanf
|
||||||
|
|
||||||
// Below 16 is more than length of 'delete from ' + 3
|
assert(!stricmp(cmd, "delete") && !stricmp(from, "from"));
|
||||||
len += (strlen(Tabname) + 16);
|
strcat(strcat(strcat(strcpy(Query, "DELETE FROM "), qc), Tabname), qc);
|
||||||
len += (To_Filter ? strlen(To_Filter) + 7 : 0);
|
|
||||||
Query = (char*)PlugSubAlloc(g, NULL, len);
|
|
||||||
strcpy(Query, (To_Filter) ? "DELETE FROM " : "TRUNCATE ");
|
|
||||||
strcat(strcat(strcat(Query, tk), Tabname), tk);
|
|
||||||
|
|
||||||
if (To_Filter)
|
if (*end)
|
||||||
strcat(strcat(Query, " WHERE "), To_Filter);
|
strcat(Query, end);
|
||||||
|
|
||||||
return FALSE;
|
return RC_OK;
|
||||||
} // end of MakeDelete
|
} // end of MakeDelete
|
||||||
#endif // 0
|
#endif // 0
|
||||||
|
|
||||||
@@ -751,7 +754,8 @@ int TDBMYSQL::GetMaxSize(PGLOBAL g)
|
|||||||
Query = NULL; // Must be remade when columns are known
|
Query = NULL; // Must be remade when columns are known
|
||||||
#endif // 0
|
#endif // 0
|
||||||
|
|
||||||
MaxSize = 10; // To make MySQL happy
|
// Return 0 in mode DELETE in case of delete all.
|
||||||
|
MaxSize = (Mode == MODE_DELETE) ? 0 : 10; // To make MySQL happy
|
||||||
} // endif MaxSize
|
} // endif MaxSize
|
||||||
|
|
||||||
return MaxSize;
|
return MaxSize;
|
||||||
@@ -766,12 +770,11 @@ int TDBMYSQL::RowNumber(PGLOBAL g, bool b)
|
|||||||
} // end of RowNumber
|
} // end of RowNumber
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Return 0 in mode DELETE to tell that the delete is done. */
|
/* Return 0 in mode UPDATE to tell that the update is done. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
int TDBMYSQL::GetProgMax(PGLOBAL g)
|
int TDBMYSQL::GetProgMax(PGLOBAL g)
|
||||||
{
|
{
|
||||||
return (Mode == MODE_DELETE || Mode == MODE_UPDATE) ? 0
|
return (Mode == MODE_UPDATE) ? 0 : GetMaxSize(g);
|
||||||
: GetMaxSize(g);
|
|
||||||
} // end of GetProgMax
|
} // end of GetProgMax
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -874,33 +877,17 @@ bool TDBMYSQL::OpenDB(PGLOBAL g)
|
|||||||
m_Rc = Myc.ExecSQL(g, cmd, &w);
|
m_Rc = Myc.ExecSQL(g, cmd, &w);
|
||||||
} // endif m_Rc
|
} // endif m_Rc
|
||||||
|
|
||||||
#if 0
|
} else
|
||||||
} else if (Next) {
|
// m_Rc = (Mode == MODE_DELETE) ? MakeDelete(g) : MakeUpdate(g);
|
||||||
strcpy(g->Message, MSG(NO_JOIN_UPDEL));
|
m_Rc = MakeCommand(g);
|
||||||
} else if (Mode == MODE_DELETE) {
|
|
||||||
strcpy(g->Message, "MySQL table delete not implemented yet\n");
|
|
||||||
bool rc = MakeDelete(g);
|
|
||||||
|
|
||||||
if (!rc && Myc.ExecSQL(g, Query) == RC_NF) {
|
|
||||||
if (!AftRows)
|
|
||||||
AftRows = Myc.GetRows();
|
|
||||||
|
|
||||||
m_Rc = RC_OK;
|
|
||||||
} // endif ExecSQL
|
|
||||||
#endif // 0
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// bool rc = MakeUpdate(g, sqlp->GetProj());
|
|
||||||
strcpy(g->Message, "MySQL table delete/update not implemented yet\n");
|
|
||||||
} // endelse
|
|
||||||
|
|
||||||
if (m_Rc == RC_FX) {
|
if (m_Rc == RC_FX) {
|
||||||
Myc.Close();
|
Myc.Close();
|
||||||
return TRUE;
|
return true;
|
||||||
} // endif rc
|
} // endif rc
|
||||||
|
|
||||||
Use = USE_OPEN; // Do it now in case we are recursively called
|
Use = USE_OPEN;
|
||||||
return FALSE;
|
return false;
|
||||||
} // end of OpenDB
|
} // end of OpenDB
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -975,6 +962,38 @@ char *TDBMYSQL::FindFieldColumn(char *name)
|
|||||||
return cp;
|
return cp;
|
||||||
} // end of FindFieldColumn
|
} // end of FindFieldColumn
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Send an UPDATE or DELETE command to the remote server. */
|
||||||
|
/***********************************************************************/
|
||||||
|
int TDBMYSQL::SendCommand(PGLOBAL g)
|
||||||
|
{
|
||||||
|
int w;
|
||||||
|
|
||||||
|
if (Myc.ExecSQLcmd(g, Query, &w) == RC_NF) {
|
||||||
|
AftRows = Myc.m_Afrw;
|
||||||
|
sprintf(g->Message, "%s: %d affected rows", Tabname, AftRows);
|
||||||
|
PushWarning(g, this, 0); // 0 means a Note
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc("%s\n", g->Message);
|
||||||
|
|
||||||
|
if (w && Myc.ExecSQL(g, "SHOW WARNINGS") == RC_OK) {
|
||||||
|
// We got warnings from the remote server
|
||||||
|
while (Myc.Fetch(g, -1) == RC_OK) {
|
||||||
|
sprintf(g->Message, "%s: (%s) %s", Tabname,
|
||||||
|
Myc.GetCharField(1), Myc.GetCharField(2));
|
||||||
|
PushWarning(g, this);
|
||||||
|
} // endwhile Fetch
|
||||||
|
|
||||||
|
Myc.FreeResult();
|
||||||
|
} // endif w
|
||||||
|
|
||||||
|
return RC_EF; // Nothing else to do
|
||||||
|
} else
|
||||||
|
return RC_FX; // Error
|
||||||
|
|
||||||
|
} // end of SendCommand
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Data Base read routine for MYSQL access method. */
|
/* Data Base read routine for MYSQL access method. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -986,6 +1005,9 @@ int TDBMYSQL::ReadDB(PGLOBAL g)
|
|||||||
htrc("MySQL ReadDB: R%d Mode=%d key=%p link=%p Kindex=%p\n",
|
htrc("MySQL ReadDB: R%d Mode=%d key=%p link=%p Kindex=%p\n",
|
||||||
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)
|
||||||
|
return SendCommand(g);
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* Now start the reading process. */
|
/* Now start the reading process. */
|
||||||
/* Here is the place to fetch the line. */
|
/* Here is the place to fetch the line. */
|
||||||
@@ -1041,12 +1063,16 @@ int TDBMYSQL::WriteDB(PGLOBAL g)
|
|||||||
} // end of WriteDB
|
} // end of WriteDB
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Data Base delete line routine for MYSQL access methods. */
|
/* Data Base delete all routine for MYSQL access methods. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
int TDBMYSQL::DeleteDB(PGLOBAL g, int irc)
|
int TDBMYSQL::DeleteDB(PGLOBAL g, int irc)
|
||||||
{
|
{
|
||||||
strcpy(g->Message, MSG(NO_MYSQL_DELETE));
|
if (irc == RC_FX)
|
||||||
return RC_FX;
|
// Send the DELETE (all) command to the remote table
|
||||||
|
return (SendCommand(g) == RC_FX) ? RC_FX : RC_OK;
|
||||||
|
else
|
||||||
|
return RC_OK; // Ignore
|
||||||
|
|
||||||
} // end of DeleteDB
|
} // end of DeleteDB
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -1237,7 +1263,7 @@ void MYSQLCOL::InitBind(PGLOBAL g)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
void MYSQLCOL::ReadColumn(PGLOBAL g)
|
void MYSQLCOL::ReadColumn(PGLOBAL g)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *p, *buf, tim[20];
|
||||||
int rc;
|
int rc;
|
||||||
PTDBMY tdbp = (PTDBMY)To_Tdb;
|
PTDBMY tdbp = (PTDBMY)To_Tdb;
|
||||||
|
|
||||||
@@ -1257,7 +1283,14 @@ void MYSQLCOL::ReadColumn(PGLOBAL g)
|
|||||||
if (trace)
|
if (trace)
|
||||||
htrc("MySQL ReadColumn: name=%s buf=%s\n", Name, buf);
|
htrc("MySQL ReadColumn: name=%s buf=%s\n", Name, buf);
|
||||||
|
|
||||||
Value->SetValue_char(buf, min((unsigned)Long, strlen(buf)));
|
// TODO: have a true way to differenciate temporal values
|
||||||
|
if (strlen(buf) == 8)
|
||||||
|
// This is a TIME value
|
||||||
|
p = strcat(strcpy(tim, "1970-01-01 "), buf);
|
||||||
|
else
|
||||||
|
p = buf;
|
||||||
|
|
||||||
|
Value->SetValue_char(p, strlen(p));
|
||||||
} else {
|
} else {
|
||||||
if (Nullable)
|
if (Nullable)
|
||||||
Value->SetNull(true);
|
Value->SetNull(true);
|
||||||
@@ -1294,8 +1327,30 @@ void MYSQLCOL::WriteColumn(PGLOBAL g)
|
|||||||
/* ------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------- */
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Implementation of the TDBMYSQL class. */
|
/* Implementation of the TDBMYEXC class. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
TDBMYEXC::TDBMYEXC(PMYDEF tdp) : TDBMYSQL(tdp)
|
||||||
|
{
|
||||||
|
Cmdlist = NULL;
|
||||||
|
Cmdcol = NULL;
|
||||||
|
Shw = false;
|
||||||
|
Havew = false;
|
||||||
|
Isw = false;
|
||||||
|
Warnings = 0;
|
||||||
|
Mxr = tdp->Mxr;
|
||||||
|
Nerr = 0;
|
||||||
|
} // end of TDBMYEXC constructor
|
||||||
|
|
||||||
|
TDBMYEXC::TDBMYEXC(PGLOBAL g, PTDBMYX tdbp) : TDBMYSQL(g, tdbp)
|
||||||
|
{
|
||||||
|
Cmdlist = tdbp->Cmdlist;
|
||||||
|
Cmdcol = tdbp->Cmdcol;
|
||||||
|
Shw = tdbp->Shw;
|
||||||
|
Havew = tdbp->Havew;
|
||||||
|
Isw = tdbp->Isw;
|
||||||
|
Mxr = tdbp->Mxr;
|
||||||
|
Nerr = tdbp->Nerr;
|
||||||
|
} // end of TDBMYEXC copy constructor
|
||||||
|
|
||||||
// Is this really useful ???
|
// Is this really useful ???
|
||||||
PTDB TDBMYEXC::CopyOne(PTABS t)
|
PTDB TDBMYEXC::CopyOne(PTABS t)
|
||||||
@@ -1331,23 +1386,15 @@ PCOL TDBMYEXC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* MakeCMD: make the SQL statement to send to MYSQL connection. */
|
/* MakeCMD: make the SQL statement to send to MYSQL connection. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
char *TDBMYEXC::MakeCMD(PGLOBAL g)
|
PCMD TDBMYEXC::MakeCMD(PGLOBAL g)
|
||||||
{
|
{
|
||||||
char *xcmd = NULL;
|
PCMD xcmd = NULL;
|
||||||
|
|
||||||
if (To_Filter) {
|
if (To_Filter) {
|
||||||
if (Cmdcol) {
|
if (Cmdcol) {
|
||||||
char col[128], cmd[1024];
|
if (!stricmp(Cmdcol, To_Filter->Body) &&
|
||||||
int n;
|
(To_Filter->Op == OP_EQ || To_Filter->Op == OP_IN)) {
|
||||||
|
xcmd = To_Filter->Cmds;
|
||||||
memset(cmd, 0, sizeof(cmd));
|
|
||||||
n = sscanf(To_Filter, "%s = '%1023c", col, cmd);
|
|
||||||
|
|
||||||
if (n == 2 && !stricmp(col, Cmdcol)) {
|
|
||||||
xcmd = (char*)PlugSubAlloc(g, NULL, strlen(cmd) + 1);
|
|
||||||
|
|
||||||
strcpy(xcmd, cmd);
|
|
||||||
xcmd[strlen(xcmd) - 1] = 0;
|
|
||||||
} else
|
} else
|
||||||
strcpy(g->Message, "Invalid command specification filter");
|
strcpy(g->Message, "Invalid command specification filter");
|
||||||
|
|
||||||
@@ -1357,7 +1404,7 @@ char *TDBMYEXC::MakeCMD(PGLOBAL g)
|
|||||||
} else if (!Srcdef)
|
} else if (!Srcdef)
|
||||||
strcpy(g->Message, "No Srcdef default command");
|
strcpy(g->Message, "No Srcdef default command");
|
||||||
else
|
else
|
||||||
xcmd = Srcdef;
|
xcmd = new(g) CMD(g, Srcdef);
|
||||||
|
|
||||||
return xcmd;
|
return xcmd;
|
||||||
} // end of MakeCMD
|
} // end of MakeCMD
|
||||||
@@ -1368,7 +1415,7 @@ char *TDBMYEXC::MakeCMD(PGLOBAL g)
|
|||||||
int TDBMYEXC::GetMaxSize(PGLOBAL g)
|
int TDBMYEXC::GetMaxSize(PGLOBAL g)
|
||||||
{
|
{
|
||||||
if (MaxSize < 0) {
|
if (MaxSize < 0) {
|
||||||
MaxSize = 1;
|
MaxSize = 10; // a guess
|
||||||
} // endif MaxSize
|
} // endif MaxSize
|
||||||
|
|
||||||
return MaxSize;
|
return MaxSize;
|
||||||
@@ -1379,8 +1426,6 @@ int TDBMYEXC::GetMaxSize(PGLOBAL g)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool TDBMYEXC::OpenDB(PGLOBAL g)
|
bool TDBMYEXC::OpenDB(PGLOBAL g)
|
||||||
{
|
{
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (Use == USE_OPEN) {
|
if (Use == USE_OPEN) {
|
||||||
strcpy(g->Message, "Multiple execution is not allowed");
|
strcpy(g->Message, "Multiple execution is not allowed");
|
||||||
return true;
|
return true;
|
||||||
@@ -1407,20 +1452,11 @@ bool TDBMYEXC::OpenDB(PGLOBAL g)
|
|||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* Get the command to execute. */
|
/* Get the command to execute. */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
if (!(Query = MakeCMD(g))) {
|
if (!(Cmdlist = MakeCMD(g))) {
|
||||||
Myc.Close();
|
Myc.Close();
|
||||||
return true;
|
return true;
|
||||||
} // endif Query
|
} // endif Query
|
||||||
|
|
||||||
if ((rc = Myc.ExecSQL(g, Query)) == RC_NF) {
|
|
||||||
strcpy(g->Message, "Affected rows");
|
|
||||||
AftRows = Myc.m_Rows;
|
|
||||||
} else if (rc == RC_OK) {
|
|
||||||
sprintf(g->Message, "Columns and %d rows", Myc.m_Rows);
|
|
||||||
AftRows = Myc.m_Fields;
|
|
||||||
} else
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} // end of OpenDB
|
} // end of OpenDB
|
||||||
|
|
||||||
@@ -1429,7 +1465,54 @@ bool TDBMYEXC::OpenDB(PGLOBAL g)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
int TDBMYEXC::ReadDB(PGLOBAL g)
|
int TDBMYEXC::ReadDB(PGLOBAL g)
|
||||||
{
|
{
|
||||||
return (++N) ? RC_EF : RC_OK;
|
if (Havew) {
|
||||||
|
// Process result set from SHOW WARNINGS
|
||||||
|
if (Myc.Fetch(g, -1) != RC_OK) {
|
||||||
|
Myc.FreeResult();
|
||||||
|
Havew = Isw = false;
|
||||||
|
} else {
|
||||||
|
N++;
|
||||||
|
Isw = true;
|
||||||
|
return RC_OK;
|
||||||
|
} // endif Fetch
|
||||||
|
|
||||||
|
} // endif m_Res
|
||||||
|
|
||||||
|
if (Cmdlist) {
|
||||||
|
// Process query to send
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
do {
|
||||||
|
Query = Cmdlist->Cmd;
|
||||||
|
|
||||||
|
switch (rc = Myc.ExecSQLcmd(g, Query, &Warnings)) {
|
||||||
|
case RC_NF:
|
||||||
|
AftRows = Myc.m_Afrw;
|
||||||
|
strcpy(g->Message, "Affected rows");
|
||||||
|
break;
|
||||||
|
case RC_OK:
|
||||||
|
AftRows = Myc.m_Fields;
|
||||||
|
strcpy(g->Message, "Result set columns");
|
||||||
|
break;
|
||||||
|
case RC_FX:
|
||||||
|
AftRows = Myc.m_Afrw;
|
||||||
|
Nerr++;
|
||||||
|
break;
|
||||||
|
case RC_INFO:
|
||||||
|
Shw = true;
|
||||||
|
} // endswitch rc
|
||||||
|
|
||||||
|
Cmdlist = (Nerr > Mxr) ? NULL : Cmdlist->Next;
|
||||||
|
} while (rc == RC_INFO);
|
||||||
|
|
||||||
|
if (Shw && Warnings)
|
||||||
|
Havew = (Myc.ExecSQL(g, "SHOW WARNINGS") == RC_OK);
|
||||||
|
|
||||||
|
++N;
|
||||||
|
return RC_OK;
|
||||||
|
} else
|
||||||
|
return RC_EF;
|
||||||
|
|
||||||
} // end of ReadDB
|
} // end of ReadDB
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -1480,12 +1563,23 @@ void MYXCOL::ReadColumn(PGLOBAL g)
|
|||||||
{
|
{
|
||||||
PTDBMYX tdbp = (PTDBMYX)To_Tdb;
|
PTDBMYX tdbp = (PTDBMYX)To_Tdb;
|
||||||
|
|
||||||
switch (Flag) {
|
if (tdbp->Isw) {
|
||||||
case 0: Value->SetValue_psz(tdbp->Query); break;
|
char *buf = NULL;
|
||||||
case 1: Value->SetValue(tdbp->AftRows); break;
|
|
||||||
case 2: Value->SetValue_psz(g->Message); break;
|
if (Flag < 3) {
|
||||||
default: Value->SetValue_psz("Invalid Flag"); break;
|
buf = tdbp->Myc.GetCharField(Flag);
|
||||||
} // endswitch Flag
|
Value->SetValue_psz(buf);
|
||||||
|
} else
|
||||||
|
Value->Reset();
|
||||||
|
|
||||||
|
} else
|
||||||
|
switch (Flag) {
|
||||||
|
case 0: Value->SetValue_psz(tdbp->Query); break;
|
||||||
|
case 1: Value->SetValue(tdbp->AftRows); break;
|
||||||
|
case 2: Value->SetValue_psz(g->Message); break;
|
||||||
|
case 3: Value->SetValue(tdbp->Warnings); break;
|
||||||
|
default: Value->SetValue_psz("Invalid Flag"); break;
|
||||||
|
} // endswitch Flag
|
||||||
|
|
||||||
} // end of ReadColumn
|
} // end of ReadColumn
|
||||||
|
|
||||||
|
@@ -20,6 +20,7 @@ typedef class MYSQLC *PMYC;
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
class MYSQLDEF : public TABDEF {/* Logical table description */
|
class MYSQLDEF : public TABDEF {/* Logical table description */
|
||||||
friend class TDBMYSQL;
|
friend class TDBMYSQL;
|
||||||
|
friend class TDBMYEXC;
|
||||||
friend class TDBMCL;
|
friend class TDBMCL;
|
||||||
friend class ha_connect;
|
friend class ha_connect;
|
||||||
public:
|
public:
|
||||||
@@ -52,7 +53,10 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
|
|||||||
PSZ Username; /* User logon name */
|
PSZ Username; /* User logon name */
|
||||||
PSZ Password; /* Password logon info */
|
PSZ Password; /* Password logon info */
|
||||||
PSZ Server; /* PServerID */
|
PSZ Server; /* PServerID */
|
||||||
|
PSZ Qrystr; /* The original query */
|
||||||
int Portnumber; /* MySQL port number (0 = default) */
|
int Portnumber; /* MySQL port number (0 = default) */
|
||||||
|
int Mxr; /* Maxerr for an Exec table */
|
||||||
|
int Quoted; /* Identifier quoting level */
|
||||||
bool Isview; /* TRUE if this table is a MySQL view */
|
bool Isview; /* TRUE if this table is a MySQL view */
|
||||||
bool Bind; /* Use prepared statement on insert */
|
bool Bind; /* Use prepared statement on insert */
|
||||||
bool Delayed; /* Delayed insert */
|
bool Delayed; /* Delayed insert */
|
||||||
@@ -102,9 +106,11 @@ class TDBMYSQL : public TDBASE {
|
|||||||
// Internal functions
|
// Internal functions
|
||||||
bool MakeSelect(PGLOBAL g);
|
bool MakeSelect(PGLOBAL g);
|
||||||
bool MakeInsert(PGLOBAL g);
|
bool MakeInsert(PGLOBAL g);
|
||||||
//bool MakeUpdate(PGLOBAL g);
|
|
||||||
//bool MakeDelete(PGLOBAL g);
|
|
||||||
int BindColumns(PGLOBAL g);
|
int BindColumns(PGLOBAL g);
|
||||||
|
int MakeCommand(PGLOBAL g);
|
||||||
|
//int MakeUpdate(PGLOBAL g);
|
||||||
|
//int MakeDelete(PGLOBAL g);
|
||||||
|
int SendCommand(PGLOBAL g);
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
MYSQLC Myc; // MySQL connection class
|
MYSQLC Myc; // MySQL connection class
|
||||||
@@ -118,6 +124,7 @@ class TDBMYSQL : public TDBASE {
|
|||||||
char *Server; // The server ID
|
char *Server; // The server ID
|
||||||
char *Query; // Points to SQL query
|
char *Query; // Points to SQL query
|
||||||
char *Qbuf; // Used for not prepared insert
|
char *Qbuf; // Used for not prepared insert
|
||||||
|
char *Qrystr; // The original query
|
||||||
bool Fetched; // True when fetch was done
|
bool Fetched; // True when fetch was done
|
||||||
bool Isview; // True if this table is a MySQL view
|
bool Isview; // True if this table is a MySQL view
|
||||||
bool Prep; // Use prepared statement on insert
|
bool Prep; // Use prepared statement on insert
|
||||||
@@ -127,6 +134,7 @@ class TDBMYSQL : public TDBASE {
|
|||||||
int N; // The current table index
|
int N; // The current table index
|
||||||
int Port; // MySQL port number (0 = default)
|
int Port; // MySQL port number (0 = default)
|
||||||
int Nparm; // The number of statement parameters
|
int Nparm; // The number of statement parameters
|
||||||
|
int Quoted; // The identifier quoting level
|
||||||
}; // end of class TDBMYSQL
|
}; // end of class TDBMYSQL
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -167,13 +175,12 @@ class MYSQLCOL : public COLBLK {
|
|||||||
class TDBMYEXC : public TDBMYSQL {
|
class TDBMYEXC : public TDBMYSQL {
|
||||||
friend class MYXCOL;
|
friend class MYXCOL;
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructors
|
||||||
TDBMYEXC(PMYDEF tdp) : TDBMYSQL(tdp) {Cmdcol = NULL;}
|
TDBMYEXC(PMYDEF tdp);
|
||||||
TDBMYEXC(PGLOBAL g, PTDBMYX tdbp) : TDBMYSQL(g, tdbp)
|
TDBMYEXC(PGLOBAL g, PTDBMYX tdbp);
|
||||||
{Cmdcol = tdbp->Cmdcol;}
|
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
//virtual AMT GetAmType(void) {return TYPE_AM_MYSQL;}
|
virtual AMT GetAmType(void) {return TYPE_AM_MYX;}
|
||||||
virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBMYEXC(g, this);}
|
virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBMYEXC(g, this);}
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
@@ -203,13 +210,20 @@ class TDBMYEXC : public TDBMYSQL {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Internal functions
|
// Internal functions
|
||||||
char *MakeCMD(PGLOBAL g);
|
PCMD MakeCMD(PGLOBAL g);
|
||||||
//bool MakeSelect(PGLOBAL g);
|
//bool MakeSelect(PGLOBAL g);
|
||||||
//bool MakeInsert(PGLOBAL g);
|
//bool MakeInsert(PGLOBAL g);
|
||||||
//int BindColumns(PGLOBAL g);
|
//int BindColumns(PGLOBAL g);
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
|
PCMD Cmdlist; // The commands to execute
|
||||||
char *Cmdcol; // The name of the Xsrc command column
|
char *Cmdcol; // The name of the Xsrc command column
|
||||||
|
bool Shw; // Show warnings
|
||||||
|
bool Havew; // True when processing warnings
|
||||||
|
bool Isw; // True for warning lines
|
||||||
|
int Warnings; // Warnings number
|
||||||
|
int Mxr; // Maximum errors before closing
|
||||||
|
int Nerr; // Number of errors so far
|
||||||
}; // end of class TDBMYEXC
|
}; // end of class TDBMYEXC
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -495,6 +495,7 @@ bool TDBOCCUR::OpenDB(PGLOBAL g)
|
|||||||
if (Tdbp->OpenDB(g))
|
if (Tdbp->OpenDB(g))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
Use = USE_OPEN;
|
||||||
return ViewColumnList(g);
|
return ViewColumnList(g);
|
||||||
} // end of OpenDB
|
} // end of OpenDB
|
||||||
|
|
||||||
|
@@ -3,8 +3,6 @@
|
|||||||
|
|
||||||
#include "tabutil.h"
|
#include "tabutil.h"
|
||||||
|
|
||||||
#define TYPE_AM_OCCUR (AMT)128
|
|
||||||
|
|
||||||
typedef class OCCURDEF *POCCURDEF;
|
typedef class OCCURDEF *POCCURDEF;
|
||||||
typedef class TDBOCCUR *PTDBOCCUR;
|
typedef class TDBOCCUR *PTDBOCCUR;
|
||||||
typedef class OCCURCOL *POCCURCOL;
|
typedef class OCCURCOL *POCCURCOL;
|
||||||
|
@@ -90,8 +90,8 @@ 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 = Qrystr = NULL;
|
||||||
Catver = Options = 0;
|
Catver = Options = Quoted = 0;
|
||||||
Xsrc = false;
|
Xsrc = false;
|
||||||
} // end of ODBCDEF constructor
|
} // end of ODBCDEF constructor
|
||||||
|
|
||||||
@@ -107,9 +107,11 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
Tabowner = Cat->GetStringCatInfo(g, "Owner", "");
|
Tabowner = Cat->GetStringCatInfo(g, "Owner", "");
|
||||||
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", "");
|
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);
|
||||||
|
Quoted = Cat->GetIntCatInfo("Quoted", 0);
|
||||||
Options = ODBConn::noOdbcDialog;
|
Options = ODBConn::noOdbcDialog;
|
||||||
Pseudo = 2; // FILID is Ok but not ROWID
|
Pseudo = 2; // FILID is Ok but not ROWID
|
||||||
return false;
|
return false;
|
||||||
@@ -169,8 +171,9 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp)
|
|||||||
Owner = tdp->Tabowner;
|
Owner = tdp->Tabowner;
|
||||||
Qualifier = tdp->Tabqual;
|
Qualifier = tdp->Tabqual;
|
||||||
Srcdef = tdp->Srcdef;
|
Srcdef = tdp->Srcdef;
|
||||||
Quote = tdp->GetQchar();
|
Qrystr = tdp->Qrystr;
|
||||||
Options = tdp->Options;
|
Options = tdp->Options;
|
||||||
|
Quoted = max(0, tdp->GetQuoted());
|
||||||
Rows = tdp->GetElemt();
|
Rows = tdp->GetElemt();
|
||||||
Catver = tdp->Catver;
|
Catver = tdp->Catver;
|
||||||
} else {
|
} else {
|
||||||
@@ -179,12 +182,14 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp)
|
|||||||
Owner = NULL;
|
Owner = NULL;
|
||||||
Qualifier = NULL;
|
Qualifier = NULL;
|
||||||
Srcdef = NULL;
|
Srcdef = NULL;
|
||||||
Quote = NULL;
|
Qrystr = NULL;
|
||||||
Options = 0;
|
Options = 0;
|
||||||
|
Quoted = 0;
|
||||||
Rows = 0;
|
Rows = 0;
|
||||||
Catver = 0;
|
Catver = 0;
|
||||||
} // endif tdp
|
} // endif tdp
|
||||||
|
|
||||||
|
Quote = NULL;
|
||||||
Query = NULL;
|
Query = NULL;
|
||||||
Count = NULL;
|
Count = NULL;
|
||||||
//Where = NULL;
|
//Where = NULL;
|
||||||
@@ -207,6 +212,7 @@ TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp)
|
|||||||
Owner = tdbp->Owner;
|
Owner = tdbp->Owner;
|
||||||
Qualifier = tdbp->Qualifier;
|
Qualifier = tdbp->Qualifier;
|
||||||
Srcdef = tdbp->Srcdef;
|
Srcdef = tdbp->Srcdef;
|
||||||
|
Qrystr = tdbp->Qrystr;
|
||||||
Quote = tdbp->Quote;
|
Quote = tdbp->Quote;
|
||||||
Query = tdbp->Query;
|
Query = tdbp->Query;
|
||||||
Count = tdbp->Count;
|
Count = tdbp->Count;
|
||||||
@@ -214,6 +220,7 @@ TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp)
|
|||||||
MulConn = tdbp->MulConn;
|
MulConn = tdbp->MulConn;
|
||||||
DBQ = tdbp->DBQ;
|
DBQ = tdbp->DBQ;
|
||||||
Options = tdbp->Options;
|
Options = tdbp->Options;
|
||||||
|
Quoted = tdbp->Quoted;
|
||||||
Rows = tdbp->Rows;
|
Rows = tdbp->Rows;
|
||||||
Fpos = tdbp->Fpos;
|
Fpos = tdbp->Fpos;
|
||||||
AftRows = tdbp->AftRows;
|
AftRows = tdbp->AftRows;
|
||||||
@@ -395,7 +402,7 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
|
|||||||
|
|
||||||
// Below 14 is length of 'select ' + length of ' from ' + 1
|
// Below 14 is length of 'select ' + length of ' from ' + 1
|
||||||
len = (strlen(colist) + strlen(buf) + 14);
|
len = (strlen(colist) + strlen(buf) + 14);
|
||||||
len += (To_Filter ? strlen(To_Filter) + 7 : 0);
|
len += (To_Filter ? strlen(To_Filter->Body) + 7 : 0);
|
||||||
|
|
||||||
// if (tablep->GetQualifier()) This is used when using a table
|
// if (tablep->GetQualifier()) This is used when using a table
|
||||||
// qualp = tablep->GetQualifier(); from anotherPlugDB database but
|
// qualp = tablep->GetQualifier(); from anotherPlugDB database but
|
||||||
@@ -432,7 +439,7 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
|
|||||||
strcat(sql, tabname);
|
strcat(sql, tabname);
|
||||||
|
|
||||||
if (To_Filter)
|
if (To_Filter)
|
||||||
strcat(strcat(sql, " WHERE "), To_Filter);
|
strcat(strcat(sql, " WHERE "), To_Filter->Body);
|
||||||
|
|
||||||
return sql;
|
return sql;
|
||||||
} // end of MakeSQL
|
} // end of MakeSQL
|
||||||
@@ -440,21 +447,18 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* MakeInsert: make the Insert statement used with ODBC connection. */
|
/* MakeInsert: make the Insert statement used with ODBC connection. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool TDBODBC::MakeInsert(PGLOBAL g)
|
char *TDBODBC::MakeInsert(PGLOBAL g)
|
||||||
{
|
{
|
||||||
char *colist, *valist;
|
char *stmt, *colist, *valist;
|
||||||
// char *tk = "`";
|
// char *tk = "`";
|
||||||
int len = 0;
|
int len = 0;
|
||||||
bool b = FALSE;
|
bool b = FALSE;
|
||||||
PCOL colp;
|
PCOL colp;
|
||||||
|
|
||||||
if (Query)
|
|
||||||
return false; // already done
|
|
||||||
|
|
||||||
for (colp = Columns; colp; colp = colp->GetNext())
|
for (colp = Columns; colp; colp = colp->GetNext())
|
||||||
if (colp->IsSpecial()) {
|
if (colp->IsSpecial()) {
|
||||||
strcpy(g->Message, MSG(NO_ODBC_SPECOL));
|
strcpy(g->Message, MSG(NO_ODBC_SPECOL));
|
||||||
return true;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
len += (strlen(colp->GetName()) + 4);
|
len += (strlen(colp->GetName()) + 4);
|
||||||
((PODBCCOL)colp)->Rank = ++Nparm;
|
((PODBCCOL)colp)->Rank = ++Nparm;
|
||||||
@@ -482,18 +486,18 @@ bool TDBODBC::MakeInsert(PGLOBAL g)
|
|||||||
|
|
||||||
// Below 32 is enough to contain the fixed part of the query
|
// Below 32 is enough to contain the fixed part of the query
|
||||||
len = (strlen(TableName) + strlen(colist) + strlen(valist) + 32);
|
len = (strlen(TableName) + strlen(colist) + strlen(valist) + 32);
|
||||||
Query = (char*)PlugSubAlloc(g, NULL, len);
|
stmt = (char*)PlugSubAlloc(g, NULL, len);
|
||||||
strcpy(Query, "INSERT INTO ");
|
strcpy(stmt, "INSERT INTO ");
|
||||||
|
|
||||||
if (Quote)
|
if (Quote)
|
||||||
strcat(strcat(strcat(Query, Quote), TableName), Quote);
|
strcat(strcat(strcat(stmt, Quote), TableName), Quote);
|
||||||
else
|
else
|
||||||
strcat(Query, TableName);
|
strcat(stmt, TableName);
|
||||||
|
|
||||||
strcat(strcat(strcat(Query, " ("), colist), ") VALUES (");
|
strcat(strcat(strcat(stmt, " ("), colist), ") VALUES (");
|
||||||
strcat(strcat(Query, valist), ")");
|
strcat(strcat(stmt, valist), ")");
|
||||||
|
|
||||||
return false;
|
return stmt;
|
||||||
} // end of MakeInsert
|
} // end of MakeInsert
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -514,6 +518,127 @@ bool TDBODBC::BindParameters(PGLOBAL g)
|
|||||||
return false;
|
return false;
|
||||||
} // end of BindParameters
|
} // end of BindParameters
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* MakeCommand: make the Update or Delete statement to send to the */
|
||||||
|
/* MySQL server. Limited to remote values and filtering. */
|
||||||
|
/***********************************************************************/
|
||||||
|
char *TDBODBC::MakeCommand(PGLOBAL g)
|
||||||
|
{
|
||||||
|
char *p, name[68], *qc = Ocp->GetQuoteChar();
|
||||||
|
char *stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
|
||||||
|
char *qrystr = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 1);
|
||||||
|
bool qtd = Quoted > 0;
|
||||||
|
int i = 0, k = 0;
|
||||||
|
|
||||||
|
// Make a lower case copy of the originale query and change
|
||||||
|
// back ticks to the data source identifier quoting character
|
||||||
|
do {
|
||||||
|
qrystr[i] = (Qrystr[i] == '`') ? *qc : tolower(Qrystr[i]);
|
||||||
|
} while (Qrystr[i++]);
|
||||||
|
|
||||||
|
// 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), " "));
|
||||||
|
|
||||||
|
if (!strstr(" update delete low_priority ignore quick from ", name))
|
||||||
|
strlwr(strcpy(name, Name)); // Not a keyword
|
||||||
|
else
|
||||||
|
strlwr(strcat(strcat(strcpy(name, qc), Name), qc));
|
||||||
|
|
||||||
|
if ((p = strstr(qrystr, name))) {
|
||||||
|
for (i = 0; i < p - qrystr; i++)
|
||||||
|
stmt[i] = (Qrystr[i] == '`') ? *qc : Qrystr[i];
|
||||||
|
|
||||||
|
stmt[i] = 0;
|
||||||
|
k = i + (int)strlen(Name);
|
||||||
|
|
||||||
|
if (qtd && *(p-1) == ' ')
|
||||||
|
strcat(strcat(strcat(stmt, qc), TableName), qc);
|
||||||
|
else
|
||||||
|
strcat(stmt, TableName);
|
||||||
|
|
||||||
|
i = (int)strlen(stmt);
|
||||||
|
|
||||||
|
do {
|
||||||
|
stmt[i++] = (Qrystr[k] == '`') ? *qc : Qrystr[k];
|
||||||
|
} while (Qrystr[k++]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
sprintf(g->Message, "Cannot use this %s command",
|
||||||
|
(Mode == MODE_UPDATE) ? "UPDATE" : "DELETE");
|
||||||
|
return NULL;
|
||||||
|
} // endif p
|
||||||
|
|
||||||
|
return stmt;
|
||||||
|
} // end of MakeCommand
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/***********************************************************************/
|
||||||
|
/* MakeUpdate: make the SQL statement to send to ODBC connection. */
|
||||||
|
/***********************************************************************/
|
||||||
|
char *TDBODBC::MakeUpdate(PGLOBAL g)
|
||||||
|
{
|
||||||
|
char *qc, *stmt = NULL, cmd[8], tab[96], end[1024];
|
||||||
|
|
||||||
|
stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
|
||||||
|
memset(end, 0, sizeof(end));
|
||||||
|
|
||||||
|
if (sscanf(Qrystr, "%s `%[^`]`%1023c", cmd, tab, end) > 2 ||
|
||||||
|
sscanf(Qrystr, "%s \"%[^\"]\"%1023c", cmd, tab, end) > 2)
|
||||||
|
qc = Ocp->GetQuoteChar();
|
||||||
|
else if (sscanf(Qrystr, "%s %s%1023c", cmd, tab, end) > 2)
|
||||||
|
qc = (Quoted) ? Quote : "";
|
||||||
|
else {
|
||||||
|
strcpy(g->Message, "Cannot use this UPDATE command");
|
||||||
|
return NULL;
|
||||||
|
} // endif sscanf
|
||||||
|
|
||||||
|
assert(!stricmp(cmd, "update"));
|
||||||
|
strcat(strcat(strcat(strcpy(stmt, "UPDATE "), qc), TableName), qc);
|
||||||
|
|
||||||
|
for (int i = 0; end[i]; i++)
|
||||||
|
if (end[i] == '`')
|
||||||
|
end[i] = *qc;
|
||||||
|
|
||||||
|
strcat(stmt, end);
|
||||||
|
return stmt;
|
||||||
|
} // end of MakeUpdate
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* MakeDelete: make the SQL statement to send to ODBC connection. */
|
||||||
|
/***********************************************************************/
|
||||||
|
char *TDBODBC::MakeDelete(PGLOBAL g)
|
||||||
|
{
|
||||||
|
char *qc, *stmt = NULL, cmd[8], from[8], tab[96], end[512];
|
||||||
|
|
||||||
|
stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
|
||||||
|
memset(end, 0, sizeof(end));
|
||||||
|
|
||||||
|
if (sscanf(Qrystr, "%s %s `%[^`]`%511c", cmd, from, tab, end) > 2 ||
|
||||||
|
sscanf(Qrystr, "%s %s \"%[^\"]\"%511c", cmd, from, tab, end) > 2)
|
||||||
|
qc = Ocp->GetQuoteChar();
|
||||||
|
else if (sscanf(Qrystr, "%s %s %s%511c", cmd, from, tab, end) > 2)
|
||||||
|
qc = (Quoted) ? Quote : "";
|
||||||
|
else {
|
||||||
|
strcpy(g->Message, "Cannot use this DELETE command");
|
||||||
|
return NULL;
|
||||||
|
} // endif sscanf
|
||||||
|
|
||||||
|
assert(!stricmp(cmd, "delete") && !stricmp(from, "from"));
|
||||||
|
strcat(strcat(strcat(strcpy(stmt, "DELETE FROM "), qc), TableName), qc);
|
||||||
|
|
||||||
|
if (*end) {
|
||||||
|
for (int i = 0; end[i]; i++)
|
||||||
|
if (end[i] == '`')
|
||||||
|
end[i] = *qc;
|
||||||
|
|
||||||
|
strcat(stmt, end);
|
||||||
|
} // endif end
|
||||||
|
|
||||||
|
return stmt;
|
||||||
|
} // end of MakeDelete
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* ResetSize: call by TDBMUL when calculating size estimate. */
|
/* ResetSize: call by TDBMUL when calculating size estimate. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -533,7 +658,7 @@ int TDBODBC::GetMaxSize(PGLOBAL g)
|
|||||||
{
|
{
|
||||||
if (MaxSize < 0) {
|
if (MaxSize < 0) {
|
||||||
// Make MariaDB happy
|
// Make MariaDB happy
|
||||||
MaxSize = 100;
|
MaxSize = (Mode == MODE_DELETE) ? 0 : 10;
|
||||||
#if 0
|
#if 0
|
||||||
// This is unuseful and takes time
|
// This is unuseful and takes time
|
||||||
if (Srcdef) {
|
if (Srcdef) {
|
||||||
@@ -616,51 +741,40 @@ bool TDBODBC::OpenDB(PGLOBAL g)
|
|||||||
|
|
||||||
if (Ocp->Open(Connect, Options) < 1)
|
if (Ocp->Open(Connect, Options) < 1)
|
||||||
return true;
|
return true;
|
||||||
|
else if (Quoted)
|
||||||
|
Quote = Ocp->GetQuoteChar();
|
||||||
|
|
||||||
Use = USE_OPEN; // Do it now in case we are recursively called
|
Use = USE_OPEN; // Do it now in case we are recursively called
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* Allocate whatever is used for getting results. */
|
/* Make the command and allocate whatever is used for getting results. */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
if (Mode == MODE_READ) {
|
if (Mode == MODE_READ) {
|
||||||
/*******************************************************************/
|
if ((Query = MakeSQL(g, false))) {
|
||||||
/* The issue here is that if max result size is needed, it must be */
|
for (PODBCCOL colp = (PODBCCOL)Columns; colp;
|
||||||
/* calculated before the result set for the final data retrieval is*/
|
colp = (PODBCCOL)colp->GetNext())
|
||||||
/* allocated and the final statement prepared so we call GetMaxSize*/
|
if (!colp->IsSpecial())
|
||||||
/* here. It can be a waste of time if the max size is not needed */
|
colp->AllocateBuffers(g, Rows);
|
||||||
/* but currently we always are asking for it (for progress info). */
|
|
||||||
/*******************************************************************/
|
|
||||||
GetMaxSize(g); // Will be set for next call
|
|
||||||
|
|
||||||
if (!Query)
|
rc = ((Rows = Ocp->ExecDirectSQL(Query, (PODBCCOL)Columns)) < 0);
|
||||||
if ((Query = MakeSQL(g, false))) {
|
|
||||||
for (PODBCCOL colp = (PODBCCOL)Columns;
|
|
||||||
colp; colp = (PODBCCOL)colp->GetNext())
|
|
||||||
if (!colp->IsSpecial())
|
|
||||||
colp->AllocateBuffers(g, Rows);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Ocp->Close();
|
|
||||||
return true;
|
|
||||||
} // endif Query
|
} // endif Query
|
||||||
|
|
||||||
if (!rc)
|
|
||||||
rc = ((Rows = Ocp->ExecDirectSQL(Query, (PODBCCOL)Columns)) < 0);
|
|
||||||
|
|
||||||
} else if (Mode == MODE_INSERT) {
|
} else if (Mode == MODE_INSERT) {
|
||||||
if (!(rc = MakeInsert(g)))
|
if ((Query = MakeInsert(g))) {
|
||||||
if (Nparm != Ocp->PrepareSQL(Query)) {
|
if (Nparm != Ocp->PrepareSQL(Query)) {
|
||||||
strcpy(g->Message, MSG(PARM_CNT_MISS));
|
strcpy(g->Message, MSG(PARM_CNT_MISS));
|
||||||
rc = true;
|
rc = true;
|
||||||
} else
|
} else
|
||||||
rc = BindParameters(g);
|
rc = BindParameters(g);
|
||||||
|
|
||||||
} else {
|
} // endif Query
|
||||||
strcpy(g->Message, "No DELETE/UPDATE of ODBC tablesd");
|
|
||||||
return true;
|
|
||||||
} // endelse
|
|
||||||
|
|
||||||
if (rc) {
|
} else if (Mode == MODE_UPDATE || Mode == MODE_DELETE)
|
||||||
|
Query = MakeCommand(g);
|
||||||
|
else
|
||||||
|
sprintf(g->Message, "Invalid mode %d", Mode);
|
||||||
|
|
||||||
|
if (!Query || rc) {
|
||||||
Ocp->Close();
|
Ocp->Close();
|
||||||
return true;
|
return true;
|
||||||
} // endif rc
|
} // endif rc
|
||||||
@@ -691,6 +805,21 @@ int TDBODBC::ReadDB(PGLOBAL g)
|
|||||||
htrc("ODBC ReadDB: R%d Mode=%d key=%p link=%p Kindex=%p\n",
|
htrc("ODBC ReadDB: R%d Mode=%d key=%p link=%p Kindex=%p\n",
|
||||||
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) {
|
||||||
|
// Send the UPDATE/DELETE command to the remote table
|
||||||
|
if (!Ocp->ExecSQLcommand(Query)) {
|
||||||
|
sprintf(g->Message, "%s: %d affected rows", TableName, AftRows);
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc("%s\n", g->Message);
|
||||||
|
|
||||||
|
PushWarning(g, this, 0); // 0 means a Note
|
||||||
|
return RC_EF; // Nothing else to do
|
||||||
|
} else
|
||||||
|
return RC_FX; // Error
|
||||||
|
|
||||||
|
} // endif Mode
|
||||||
|
|
||||||
if (To_Kindex) {
|
if (To_Kindex) {
|
||||||
// Direct access of ODBC tables is not implemented yet
|
// Direct access of ODBC tables is not implemented yet
|
||||||
strcpy(g->Message, MSG(NO_ODBC_DIRECT));
|
strcpy(g->Message, MSG(NO_ODBC_DIRECT));
|
||||||
@@ -720,7 +849,7 @@ int TDBODBC::ReadDB(PGLOBAL g)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
int TDBODBC::WriteDB(PGLOBAL g)
|
int TDBODBC::WriteDB(PGLOBAL g)
|
||||||
{
|
{
|
||||||
int n = Ocp->ExecuteSQL(false);
|
int n = Ocp->ExecuteSQL();
|
||||||
|
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
AftRows = n;
|
AftRows = n;
|
||||||
@@ -736,8 +865,22 @@ int TDBODBC::WriteDB(PGLOBAL g)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
int TDBODBC::DeleteDB(PGLOBAL g, int irc)
|
int TDBODBC::DeleteDB(PGLOBAL g, int irc)
|
||||||
{
|
{
|
||||||
strcpy(g->Message, MSG(NO_ODBC_DELETE));
|
if (irc == RC_FX) {
|
||||||
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);
|
||||||
|
|
||||||
|
if (trace)
|
||||||
|
htrc("%s\n", g->Message);
|
||||||
|
|
||||||
|
PushWarning(g, this, 0); // 0 means a Note
|
||||||
|
return RC_OK; // This is a delete all
|
||||||
|
} else
|
||||||
|
return RC_FX; // Error
|
||||||
|
|
||||||
|
} else
|
||||||
|
return RC_OK; // Ignore
|
||||||
|
|
||||||
} // end of DeleteDB
|
} // end of DeleteDB
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -751,6 +894,7 @@ void TDBODBC::CloseDB(PGLOBAL g)
|
|||||||
// } // endif
|
// } // endif
|
||||||
|
|
||||||
if (Ocp)
|
if (Ocp)
|
||||||
|
|
||||||
Ocp->Close();
|
Ocp->Close();
|
||||||
|
|
||||||
if (trace)
|
if (trace)
|
||||||
@@ -934,7 +1078,7 @@ void ODBCCOL::AllocateBuffers(PGLOBAL g, int rows)
|
|||||||
if (Buf_Type == TYPE_DATE)
|
if (Buf_Type == TYPE_DATE)
|
||||||
Bufp = PlugSubAlloc(g, NULL, rows * sizeof(TIMESTAMP_STRUCT));
|
Bufp = PlugSubAlloc(g, NULL, rows * sizeof(TIMESTAMP_STRUCT));
|
||||||
else {
|
else {
|
||||||
Blkp = AllocValBlock(g, NULL, Buf_Type, rows, Long+1, 0, true, false);
|
Blkp = AllocValBlock(g, NULL, Buf_Type, rows, Long+1, 0, true, false, false);
|
||||||
Bufp = Blkp->GetValPointer();
|
Bufp = Blkp->GetValPointer();
|
||||||
} // endelse
|
} // endelse
|
||||||
|
|
||||||
@@ -1004,6 +1148,22 @@ void ODBCCOL::WriteColumn(PGLOBAL g)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Implementation of the TDBODBC class. */
|
/* Implementation of the TDBODBC class. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
TDBXDBC::TDBXDBC(PODEF tdp) : TDBODBC(tdp)
|
||||||
|
{
|
||||||
|
Cmdlist = NULL;
|
||||||
|
Cmdcol = NULL;
|
||||||
|
Mxr = tdp->Mxr;
|
||||||
|
Nerr = 0;
|
||||||
|
} // end of TDBXDBC constructor
|
||||||
|
|
||||||
|
TDBXDBC::TDBXDBC(PTDBXDBC tdbp) : TDBODBC(tdbp)
|
||||||
|
{
|
||||||
|
Cmdlist = tdbp->Cmdlist;
|
||||||
|
Cmdcol = tdbp->Cmdcol;
|
||||||
|
Mxr = tdbp->Mxr;
|
||||||
|
Nerr = tdbp->Nerr;
|
||||||
|
} // end of TDBXDBC copy constructor
|
||||||
|
|
||||||
PTDB TDBXDBC::CopyOne(PTABS t)
|
PTDB TDBXDBC::CopyOne(PTABS t)
|
||||||
{
|
{
|
||||||
PTDB tp;
|
PTDB tp;
|
||||||
@@ -1036,23 +1196,15 @@ PCOL TDBXDBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* MakeCMD: make the SQL statement to send to ODBC connection. */
|
/* MakeCMD: make the SQL statement to send to ODBC connection. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
char *TDBXDBC::MakeCMD(PGLOBAL g)
|
PCMD TDBXDBC::MakeCMD(PGLOBAL g)
|
||||||
{
|
{
|
||||||
char *xcmd = NULL;
|
PCMD xcmd = NULL;
|
||||||
|
|
||||||
if (To_Filter) {
|
if (To_Filter) {
|
||||||
if (Cmdcol) {
|
if (Cmdcol) {
|
||||||
char col[128], cmd[1024];
|
if (!stricmp(Cmdcol, To_Filter->Body) &&
|
||||||
int n;
|
(To_Filter->Op == OP_EQ || To_Filter->Op == OP_IN)) {
|
||||||
|
xcmd = To_Filter->Cmds;
|
||||||
memset(cmd, 0, sizeof(cmd));
|
|
||||||
n = sscanf(To_Filter, "%s = '%1023c", col, cmd);
|
|
||||||
|
|
||||||
if (n == 2 && !stricmp(col, Cmdcol)) {
|
|
||||||
xcmd = (char*)PlugSubAlloc(g, NULL, strlen(cmd) + 1);
|
|
||||||
|
|
||||||
strcpy(xcmd, cmd);
|
|
||||||
xcmd[strlen(xcmd) - 1] = 0;
|
|
||||||
} else
|
} else
|
||||||
strcpy(g->Message, "Invalid command specification filter");
|
strcpy(g->Message, "Invalid command specification filter");
|
||||||
|
|
||||||
@@ -1062,7 +1214,7 @@ char *TDBXDBC::MakeCMD(PGLOBAL g)
|
|||||||
} else if (!Srcdef)
|
} else if (!Srcdef)
|
||||||
strcpy(g->Message, "No Srcdef default command");
|
strcpy(g->Message, "No Srcdef default command");
|
||||||
else
|
else
|
||||||
xcmd = Srcdef;
|
xcmd = new(g) CMD(g, Srcdef);
|
||||||
|
|
||||||
return xcmd;
|
return xcmd;
|
||||||
} // end of MakeCMD
|
} // end of MakeCMD
|
||||||
@@ -1088,12 +1240,12 @@ bool TDBXDBC::BindParameters(PGLOBAL g)
|
|||||||
#endif // 0
|
#endif // 0
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* XDBC GetMaxSize: returns table size (always one row). */
|
/* XDBC GetMaxSize: returns table size (not always one row). */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
int TDBXDBC::GetMaxSize(PGLOBAL g)
|
int TDBXDBC::GetMaxSize(PGLOBAL g)
|
||||||
{
|
{
|
||||||
if (MaxSize < 0)
|
if (MaxSize < 0)
|
||||||
MaxSize = 1;
|
MaxSize = 10; // Just a guess
|
||||||
|
|
||||||
return MaxSize;
|
return MaxSize;
|
||||||
} // end of GetMaxSize
|
} // end of GetMaxSize
|
||||||
@@ -1142,19 +1294,12 @@ bool TDBXDBC::OpenDB(PGLOBAL g)
|
|||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* Get the command to execute. */
|
/* Get the command to execute. */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
if (!(Query = MakeCMD(g))) {
|
if (!(Cmdlist = MakeCMD(g))) {
|
||||||
Ocp->Close();
|
Ocp->Close();
|
||||||
return true;
|
return true;
|
||||||
} // endif Query
|
} // endif Query
|
||||||
|
|
||||||
Rows = 1;
|
Rows = 1;
|
||||||
|
|
||||||
if (Ocp->PrepareSQL(Query)) {
|
|
||||||
strcpy(g->Message, "Parameters not supported");
|
|
||||||
AftRows = -1;
|
|
||||||
} else
|
|
||||||
AftRows = 0;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} // end of OpenDB
|
} // end of OpenDB
|
||||||
|
|
||||||
@@ -1163,18 +1308,18 @@ bool TDBXDBC::OpenDB(PGLOBAL g)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
int TDBXDBC::ReadDB(PGLOBAL g)
|
int TDBXDBC::ReadDB(PGLOBAL g)
|
||||||
{
|
{
|
||||||
if (trace)
|
if (Cmdlist) {
|
||||||
htrc("XDBC ReadDB: query=%s\n", SVP(Query));
|
Query = Cmdlist->Cmd;
|
||||||
|
|
||||||
if (Rows--) {
|
if (Ocp->ExecSQLcommand(Query))
|
||||||
if (!AftRows)
|
Nerr++;
|
||||||
AftRows = Ocp->ExecuteSQL(true);
|
|
||||||
|
|
||||||
|
Fpos++; // Used for progress info
|
||||||
|
Cmdlist = (Nerr > Mxr) ? NULL : Cmdlist->Next;
|
||||||
|
return RC_OK;
|
||||||
} else
|
} else
|
||||||
return RC_EF;
|
return RC_EF;
|
||||||
|
|
||||||
Fpos++; // Used for progress info
|
|
||||||
return RC_OK;
|
|
||||||
} // end of ReadDB
|
} // end of ReadDB
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -1186,6 +1331,15 @@ int TDBXDBC::WriteDB(PGLOBAL g)
|
|||||||
return RC_FX;
|
return RC_FX;
|
||||||
} // end of DeleteDB
|
} // end of DeleteDB
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Data Base delete line routine for ODBC access method. */
|
||||||
|
/***********************************************************************/
|
||||||
|
int TDBXDBC::DeleteDB(PGLOBAL g, int irc)
|
||||||
|
{
|
||||||
|
strcpy(g->Message, MSG(NO_ODBC_DELETE));
|
||||||
|
return RC_FX;
|
||||||
|
} // end of DeleteDB
|
||||||
|
|
||||||
/* --------------------------- XSRCCOL ------------------------------- */
|
/* --------------------------- XSRCCOL ------------------------------- */
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -34,7 +34,7 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
|
|||||||
PSZ GetTabowner(void) {return Tabowner;}
|
PSZ GetTabowner(void) {return Tabowner;}
|
||||||
PSZ GetTabqual(void) {return Tabqual;}
|
PSZ GetTabqual(void) {return Tabqual;}
|
||||||
PSZ GetSrcdef(void) {return Srcdef;}
|
PSZ GetSrcdef(void) {return Srcdef;}
|
||||||
PSZ GetQchar(void) {return (Qchar && *Qchar) ? Qchar : NULL;}
|
int GetQuoted(void) {return Quoted;}
|
||||||
int GetCatver(void) {return Catver;}
|
int GetCatver(void) {return Catver;}
|
||||||
int GetOptions(void) {return Options;}
|
int GetOptions(void) {return Options;}
|
||||||
|
|
||||||
@@ -50,8 +50,11 @@ 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 Quoted; /* Identifier quoting level */
|
||||||
|
int Mxr; /* Maxerr for an Exec table */
|
||||||
bool Xsrc; /* Execution type */
|
bool Xsrc; /* Execution type */
|
||||||
}; // end of ODBCDEF
|
}; // end of ODBCDEF
|
||||||
|
|
||||||
@@ -96,13 +99,14 @@ 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);
|
char *MakeInsert(PGLOBAL g);
|
||||||
bool MakeInsert(PGLOBAL g);
|
char *MakeCommand(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 *MakeUpdate(PGLOBAL g);
|
||||||
|
//char *MakeDelete(PGLOBAL g);
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
ODBConn *Ocp; // Points to an ODBC connection class
|
ODBConn *Ocp; // Points to an ODBC connection class
|
||||||
@@ -118,7 +122,9 @@ 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 Quoted; // The identifier quoting level
|
||||||
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
|
||||||
int Rows; // Rowset size
|
int Rows; // Rowset size
|
||||||
@@ -179,12 +185,12 @@ class TDBXDBC : public TDBODBC {
|
|||||||
friend class XSRCCOL;
|
friend class XSRCCOL;
|
||||||
friend class ODBConn;
|
friend class ODBConn;
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructors
|
||||||
TDBXDBC(PODEF tdp = NULL) : TDBODBC(tdp) {Cmdcol = NULL;}
|
TDBXDBC(PODEF tdp = NULL);
|
||||||
TDBXDBC(PTDBXDBC tdbp) : TDBODBC(tdbp) {Cmdcol = tdbp->Cmdcol;}
|
TDBXDBC(PTDBXDBC tdbp);
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
//virtual AMT GetAmType(void) {return TYPE_AM_ODBC;}
|
virtual AMT GetAmType(void) {return TYPE_AM_XDBC;}
|
||||||
virtual PTDB Duplicate(PGLOBAL g)
|
virtual PTDB Duplicate(PGLOBAL g)
|
||||||
{return (PTDB)new(g) TDBXDBC(this);}
|
{return (PTDB)new(g) TDBXDBC(this);}
|
||||||
|
|
||||||
@@ -204,16 +210,19 @@ class TDBXDBC : public TDBODBC {
|
|||||||
virtual bool OpenDB(PGLOBAL g);
|
virtual bool OpenDB(PGLOBAL g);
|
||||||
virtual int ReadDB(PGLOBAL g);
|
virtual int ReadDB(PGLOBAL g);
|
||||||
virtual int WriteDB(PGLOBAL g);
|
virtual int WriteDB(PGLOBAL g);
|
||||||
//virtual int DeleteDB(PGLOBAL g, int irc);
|
virtual int DeleteDB(PGLOBAL g, int irc);
|
||||||
//virtual void CloseDB(PGLOBAL g);
|
//virtual void CloseDB(PGLOBAL g);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Internal functions
|
// Internal functions
|
||||||
char *MakeCMD(PGLOBAL g);
|
PCMD MakeCMD(PGLOBAL g);
|
||||||
//bool BindParameters(PGLOBAL g);
|
//bool BindParameters(PGLOBAL g);
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
|
PCMD Cmdlist; // The commands to execute
|
||||||
char *Cmdcol; // The name of the Xsrc command column
|
char *Cmdcol; // The name of the Xsrc command column
|
||||||
|
int Mxr; // Maximum errors before closing
|
||||||
|
int Nerr; // Number of errors so far
|
||||||
}; // end of class TDBXDBC
|
}; // end of class TDBXDBC
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -607,6 +607,8 @@ bool TDBPIVOT::OpenDB(PGLOBAL g)
|
|||||||
if (Tdbp->OpenDB(g))
|
if (Tdbp->OpenDB(g))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
Use = USE_OPEN; // Do it now in case we are recursively called
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* Make all required pivot columns for object views. */
|
/* Make all required pivot columns for object views. */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
@@ -295,15 +295,18 @@ bool TDBTBL::InitTableList(PGLOBAL g)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool TDBTBL::TestFil(PGLOBAL g, PFIL filp, PTABLE tabp)
|
bool TDBTBL::TestFil(PGLOBAL g, PFIL filp, PTABLE tabp)
|
||||||
{
|
{
|
||||||
char *fil, op[8], tn[NAME_LEN];
|
char *body, *fil, op[8], tn[NAME_LEN];
|
||||||
bool neg;
|
bool neg;
|
||||||
|
|
||||||
if (!filp)
|
if (!filp)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
else if (strstr(filp, " OR ") || strstr(filp, " AND "))
|
else
|
||||||
|
body = filp->Body;
|
||||||
|
|
||||||
|
if (strstr(body, " OR ") || strstr(body, " AND "))
|
||||||
return TRUE; // Not handled yet
|
return TRUE; // Not handled yet
|
||||||
else
|
else
|
||||||
fil = filp + (*filp == '(' ? 1 : 0);
|
fil = body + (*body == '(' ? 1 : 0);
|
||||||
|
|
||||||
if (sscanf(fil, "TABID %s", op) != 1)
|
if (sscanf(fil, "TABID %s", op) != 1)
|
||||||
return TRUE; // ignore invalid filter
|
return TRUE; // ignore invalid filter
|
||||||
|
@@ -495,6 +495,7 @@ bool TDBPRX::OpenDB(PGLOBAL g)
|
|||||||
if (Tdbp->OpenDB(g))
|
if (Tdbp->OpenDB(g))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
Use = USE_OPEN;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} // end of OpenDB
|
} // end of OpenDB
|
||||||
|
|
||||||
|
@@ -6,8 +6,6 @@
|
|||||||
|
|
||||||
//#include "tabtbl.h"
|
//#include "tabtbl.h"
|
||||||
|
|
||||||
#define TYPE_AM_PRX (AMT)129
|
|
||||||
|
|
||||||
typedef class PRXDEF *PPRXDEF;
|
typedef class PRXDEF *PPRXDEF;
|
||||||
typedef class TDBPRX *PTDBPRX;
|
typedef class TDBPRX *PTDBPRX;
|
||||||
typedef class XXLCOL *PXXLCOL;
|
typedef class XXLCOL *PXXLCOL;
|
||||||
|
@@ -81,7 +81,7 @@ char *strerror(int num);
|
|||||||
/* Conversion of block values allowed conditionally for insert only. */
|
/* Conversion of block values allowed conditionally for insert only. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PVBLK AllocValBlock(PGLOBAL, void *, int, int, int, int,
|
PVBLK AllocValBlock(PGLOBAL, void *, int, int, int, int,
|
||||||
bool check = true, bool blank = true);
|
bool check = true, bool blank = true, bool un = false);
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------- Class VCTDEF -------------------------- */
|
/* --------------------------- Class VCTDEF -------------------------- */
|
||||||
|
@@ -480,18 +480,19 @@ bool TDBWMI::Initialize(PGLOBAL g)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
void TDBWMI::DoubleSlash(PGLOBAL g)
|
void TDBWMI::DoubleSlash(PGLOBAL g)
|
||||||
{
|
{
|
||||||
if (To_Filter && strchr(To_Filter, '\\')) {
|
if (To_Filter && strchr(To_Filter->Body, '\\')) {
|
||||||
char *buf = (char*)PlugSubAlloc(g, NULL, strlen(To_Filter) * 2);
|
char *body = To_Filter->Body;
|
||||||
|
char *buf = (char*)PlugSubAlloc(g, NULL, strlen(body) * 2);
|
||||||
int i = 0, k = 0;
|
int i = 0, k = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (To_Filter[i] == '\\')
|
if (body[i] == '\\')
|
||||||
buf[k++] = '\\';
|
buf[k++] = '\\';
|
||||||
|
|
||||||
buf[k++] = To_Filter[i];
|
buf[k++] = body[i];
|
||||||
} while (To_Filter[i++]);
|
} while (body[i++]);
|
||||||
|
|
||||||
To_Filter = buf;
|
To_Filter->Body = buf;
|
||||||
} // endif To_Filter
|
} // endif To_Filter
|
||||||
|
|
||||||
} // end of DoubleSlash
|
} // end of DoubleSlash
|
||||||
@@ -539,13 +540,13 @@ char *TDBWMI::MakeWQL(PGLOBAL g)
|
|||||||
|
|
||||||
// Below 14 is length of 'select ' + length of ' from ' + 1
|
// Below 14 is length of 'select ' + length of ' from ' + 1
|
||||||
len = (strlen(colist) + strlen(Wclass) + 14);
|
len = (strlen(colist) + strlen(Wclass) + 14);
|
||||||
len += (To_Filter ? strlen(To_Filter) + 7 : 0);
|
len += (To_Filter ? strlen(To_Filter->Body) + 7 : 0);
|
||||||
wql = (char*)PlugSubAlloc(g, NULL, len);
|
wql = (char*)PlugSubAlloc(g, NULL, len);
|
||||||
strcat(strcat(strcpy(wql, "SELECT "), colist), " FROM ");
|
strcat(strcat(strcpy(wql, "SELECT "), colist), " FROM ");
|
||||||
strcat(wql, Wclass);
|
strcat(wql, Wclass);
|
||||||
|
|
||||||
if (To_Filter)
|
if (To_Filter)
|
||||||
strcat(strcat(wql, " WHERE "), To_Filter);
|
strcat(strcat(wql, " WHERE "), To_Filter->Body);
|
||||||
|
|
||||||
return wql;
|
return wql;
|
||||||
} // end of MakeWQL
|
} // end of MakeWQL
|
||||||
@@ -666,6 +667,8 @@ bool TDBWMI::OpenDB(PGLOBAL g)
|
|||||||
} else
|
} else
|
||||||
DoubleSlash(g);
|
DoubleSlash(g);
|
||||||
|
|
||||||
|
Use = USE_OPEN; // Do it now in case we are recursively called
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* Initialize the WMI processing. */
|
/* Initialize the WMI processing. */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
@@ -193,6 +193,7 @@ bool TDBXCL::OpenDB(PGLOBAL g)
|
|||||||
if (Tdbp->OpenDB(g))
|
if (Tdbp->OpenDB(g))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
Use = USE_OPEN;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} // end of OpenDB
|
} // end of OpenDB
|
||||||
|
|
||||||
|
@@ -3,8 +3,6 @@
|
|||||||
|
|
||||||
#include "tabutil.h"
|
#include "tabutil.h"
|
||||||
|
|
||||||
#define TYPE_AM_XCOL (AMT)124
|
|
||||||
|
|
||||||
typedef class XCLDEF *PXCLDEF;
|
typedef class XCLDEF *PXCLDEF;
|
||||||
typedef class TDBXCL *PTDBXCL;
|
typedef class TDBXCL *PTDBXCL;
|
||||||
typedef class XCLCOL *PXCLCOL;
|
typedef class XCLCOL *PXCLCOL;
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/************ Valblk C++ Functions Source Code File (.CPP) *************/
|
/************ Valblk C++ Functions Source Code File (.CPP) *************/
|
||||||
/* Name: VALBLK.CPP Version 1.7 */
|
/* Name: VALBLK.CPP Version 2.0 */
|
||||||
/* */
|
/* */
|
||||||
/* (C) Copyright to the author Olivier BERTRAND 2005-2013 */
|
/* (C) Copyright to the author Olivier BERTRAND 2005-2013 */
|
||||||
/* */
|
/* */
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
/* types of objects, we shall have more classes to update. */
|
/* types of objects, we shall have more classes to update. */
|
||||||
/* This is why we are now using a template class for many types. */
|
/* This is why we are now using a template class for many types. */
|
||||||
/* Currently the only implemented types are PSZ, chars, int, short, */
|
/* Currently the only implemented types are PSZ, chars, int, short, */
|
||||||
/* DATE, longlong, and double. Shortly we should add more types. */
|
/* DATE, longlong, double and tiny. Fix numeric ones can be unsigned. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
/* AllocValBlock: allocate a VALBLK according to type. */
|
/* AllocValBlock: allocate a VALBLK according to type. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len,
|
PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len,
|
||||||
int prec, bool check, bool blank)
|
int prec, bool check, bool blank, bool un)
|
||||||
{
|
{
|
||||||
PVBLK blkp;
|
PVBLK blkp;
|
||||||
|
|
||||||
@@ -64,22 +64,38 @@ PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len,
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case TYPE_SHORT:
|
case TYPE_SHORT:
|
||||||
blkp = new(g) TYPBLK<short>(mp, nval, type);
|
if (un)
|
||||||
|
blkp = new(g) TYPBLK<ushort>(mp, nval, type, 0, true);
|
||||||
|
else
|
||||||
|
blkp = new(g) TYPBLK<short>(mp, nval, type);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TYPE_INT:
|
case TYPE_INT:
|
||||||
blkp = new(g) TYPBLK<int>(mp, nval, type);
|
if (un)
|
||||||
|
blkp = new(g) TYPBLK<uint>(mp, nval, type, 0, true);
|
||||||
|
else
|
||||||
|
blkp = new(g) TYPBLK<int>(mp, nval, type);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TYPE_DATE: // ?????
|
case TYPE_DATE: // ?????
|
||||||
blkp = new(g) DATBLK(mp, nval);
|
blkp = new(g) DATBLK(mp, nval);
|
||||||
break;
|
break;
|
||||||
case TYPE_BIGINT:
|
case TYPE_BIGINT:
|
||||||
blkp = new(g) TYPBLK<longlong>(mp, nval, type);
|
if (un)
|
||||||
|
blkp = new(g) TYPBLK<ulonglong>(mp, nval, type, 0, true);
|
||||||
|
else
|
||||||
|
blkp = new(g) TYPBLK<longlong>(mp, nval, type);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TYPE_FLOAT:
|
case TYPE_FLOAT:
|
||||||
blkp = new(g) TYPBLK<double>(mp, nval, prec, type);
|
blkp = new(g) TYPBLK<double>(mp, nval, type, prec);
|
||||||
break;
|
break;
|
||||||
case TYPE_TINY:
|
case TYPE_TINY:
|
||||||
blkp = new(g) TYPBLK<char>(mp, nval, type);
|
if (un)
|
||||||
|
blkp = new(g) TYPBLK<uchar>(mp, nval, type, 0, true);
|
||||||
|
else
|
||||||
|
blkp = new(g) TYPBLK<char>(mp, nval, type);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sprintf(g->Message, MSG(BAD_VALBLK_TYPE), type);
|
sprintf(g->Message, MSG(BAD_VALBLK_TYPE), type);
|
||||||
@@ -95,12 +111,13 @@ PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len,
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Constructor. */
|
/* Constructor. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
VALBLK::VALBLK(void *mp, int type, int nval)
|
VALBLK::VALBLK(void *mp, int type, int nval, bool un)
|
||||||
{
|
{
|
||||||
Blkp = mp;
|
Blkp = mp;
|
||||||
To_Nulls = NULL;
|
To_Nulls = NULL;
|
||||||
Check = true;
|
Check = true;
|
||||||
Nullable = false;
|
Nullable = false;
|
||||||
|
Unsigned = un;
|
||||||
Type = type;
|
Type = type;
|
||||||
Nval = nval;
|
Nval = nval;
|
||||||
Prec = 0;
|
Prec = 0;
|
||||||
@@ -195,23 +212,15 @@ void VALBLK::ChkTyp(PVBLK vb)
|
|||||||
/* -------------------------- Class TYPBLK --------------------------- */
|
/* -------------------------- Class TYPBLK --------------------------- */
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Constructors. */
|
/* Constructor. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
template <class TYPE>
|
template <class TYPE>
|
||||||
TYPBLK<TYPE>::TYPBLK(void *mp, int nval, int type)
|
TYPBLK<TYPE>::TYPBLK(void *mp, int nval, int type, int prec, bool un)
|
||||||
: VALBLK(mp, type, nval), Typp((TYPE*&)Blkp)
|
: VALBLK(mp, type, nval, un), Typp((TYPE*&)Blkp)
|
||||||
{
|
{
|
||||||
Fmt = GetFmt(Type);
|
|
||||||
} // end of TYPBLK constructor
|
|
||||||
|
|
||||||
template <class TYPE>
|
|
||||||
TYPBLK<TYPE>::TYPBLK(void *mp, int nval, int prec, int type)
|
|
||||||
: VALBLK(mp, type, nval), Typp((TYPE*&)Blkp)
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(Type == TYPE_FLOAT);
|
|
||||||
Prec = prec;
|
Prec = prec;
|
||||||
Fmt = GetFmt(Type);
|
Fmt = GetFmt(Type);
|
||||||
} // end of DBLBLK constructor
|
} // end of TYPBLK constructor
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Initialization routine. */
|
/* Initialization routine. */
|
||||||
@@ -249,14 +258,26 @@ template <>
|
|||||||
int TYPBLK<int>::GetTypedValue(PVAL valp)
|
int TYPBLK<int>::GetTypedValue(PVAL valp)
|
||||||
{return valp->GetIntValue();}
|
{return valp->GetIntValue();}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
uint TYPBLK<uint>::GetTypedValue(PVAL valp)
|
||||||
|
{return valp->GetUIntValue();}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
short TYPBLK<short>::GetTypedValue(PVAL valp)
|
short TYPBLK<short>::GetTypedValue(PVAL valp)
|
||||||
{return valp->GetShortValue();}
|
{return valp->GetShortValue();}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
ushort TYPBLK<ushort>::GetTypedValue(PVAL valp)
|
||||||
|
{return valp->GetUShortValue();}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
longlong TYPBLK<longlong>::GetTypedValue(PVAL valp)
|
longlong TYPBLK<longlong>::GetTypedValue(PVAL valp)
|
||||||
{return valp->GetBigintValue();}
|
{return valp->GetBigintValue();}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
ulonglong TYPBLK<ulonglong>::GetTypedValue(PVAL valp)
|
||||||
|
{return valp->GetUBigintValue();}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
double TYPBLK<double>::GetTypedValue(PVAL valp)
|
double TYPBLK<double>::GetTypedValue(PVAL valp)
|
||||||
{return valp->GetFloatValue();}
|
{return valp->GetFloatValue();}
|
||||||
@@ -265,6 +286,10 @@ template <>
|
|||||||
char TYPBLK<char>::GetTypedValue(PVAL valp)
|
char TYPBLK<char>::GetTypedValue(PVAL valp)
|
||||||
{return valp->GetTinyValue();}
|
{return valp->GetTinyValue();}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
uchar TYPBLK<uchar>::GetTypedValue(PVAL valp)
|
||||||
|
{return valp->GetUTinyValue();}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Set one value in a block from a zero terminated string. */
|
/* Set one value in a block from a zero terminated string. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -286,13 +311,21 @@ void TYPBLK<TYPE>::SetValue(PSZ p, int n)
|
|||||||
template <>
|
template <>
|
||||||
int TYPBLK<int>::GetTypedValue(PSZ p) {return atol(p);}
|
int TYPBLK<int>::GetTypedValue(PSZ p) {return atol(p);}
|
||||||
template <>
|
template <>
|
||||||
|
uint TYPBLK<uint>::GetTypedValue(PSZ p) {return (unsigned)atol(p);}
|
||||||
|
template <>
|
||||||
short TYPBLK<short>::GetTypedValue(PSZ p) {return (short)atoi(p);}
|
short TYPBLK<short>::GetTypedValue(PSZ p) {return (short)atoi(p);}
|
||||||
template <>
|
template <>
|
||||||
|
ushort TYPBLK<ushort>::GetTypedValue(PSZ p) {return (ushort)atoi(p);}
|
||||||
|
template <>
|
||||||
longlong TYPBLK<longlong>::GetTypedValue(PSZ p) {return atoll(p);}
|
longlong TYPBLK<longlong>::GetTypedValue(PSZ p) {return atoll(p);}
|
||||||
template <>
|
template <>
|
||||||
|
ulonglong TYPBLK<ulonglong>::GetTypedValue(PSZ p) {return (unsigned)atoll(p);}
|
||||||
|
template <>
|
||||||
double TYPBLK<double>::GetTypedValue(PSZ p) {return atof(p);}
|
double TYPBLK<double>::GetTypedValue(PSZ p) {return atof(p);}
|
||||||
template <>
|
template <>
|
||||||
char TYPBLK<char>::GetTypedValue(PSZ p) {return (char)atoi(p);}
|
char TYPBLK<char>::GetTypedValue(PSZ p) {return (char)atoi(p);}
|
||||||
|
template <>
|
||||||
|
uchar TYPBLK<uchar>::GetTypedValue(PSZ p) {return (uchar)atoi(p);}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Set one value in a block from an array of characters. */
|
/* Set one value in a block from an array of characters. */
|
||||||
@@ -333,14 +366,26 @@ template <>
|
|||||||
int TYPBLK<int>::GetTypedValue(PVBLK blk, int n)
|
int TYPBLK<int>::GetTypedValue(PVBLK blk, int n)
|
||||||
{return blk->GetIntValue(n);}
|
{return blk->GetIntValue(n);}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
uint TYPBLK<uint>::GetTypedValue(PVBLK blk, int n)
|
||||||
|
{return blk->GetUIntValue(n);}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
short TYPBLK<short>::GetTypedValue(PVBLK blk, int n)
|
short TYPBLK<short>::GetTypedValue(PVBLK blk, int n)
|
||||||
{return blk->GetShortValue(n);}
|
{return blk->GetShortValue(n);}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
ushort TYPBLK<ushort>::GetTypedValue(PVBLK blk, int n)
|
||||||
|
{return blk->GetUShortValue(n);}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
longlong TYPBLK<longlong>::GetTypedValue(PVBLK blk, int n)
|
longlong TYPBLK<longlong>::GetTypedValue(PVBLK blk, int n)
|
||||||
{return blk->GetBigintValue(n);}
|
{return blk->GetBigintValue(n);}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
ulonglong TYPBLK<ulonglong>::GetTypedValue(PVBLK blk, int n)
|
||||||
|
{return blk->GetUBigintValue(n);}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
double TYPBLK<double>::GetTypedValue(PVBLK blk, int n)
|
double TYPBLK<double>::GetTypedValue(PVBLK blk, int n)
|
||||||
{return blk->GetFloatValue(n);}
|
{return blk->GetFloatValue(n);}
|
||||||
@@ -349,6 +394,10 @@ template <>
|
|||||||
char TYPBLK<char>::GetTypedValue(PVBLK blk, int n)
|
char TYPBLK<char>::GetTypedValue(PVBLK blk, int n)
|
||||||
{return blk->GetTinyValue(n);}
|
{return blk->GetTinyValue(n);}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
uchar TYPBLK<uchar>::GetTypedValue(PVBLK blk, int n)
|
||||||
|
{return blk->GetUTinyValue(n);}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Set many values in a block from values in another block. */
|
/* Set many values in a block from values in another block. */
|
||||||
@@ -516,6 +565,14 @@ short CHRBLK::GetShortValue(int n)
|
|||||||
return (short)atoi((char *)GetValPtrEx(n));
|
return (short)atoi((char *)GetValPtrEx(n));
|
||||||
} // end of GetShortValue
|
} // end of GetShortValue
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Return the value of the nth element converted to ushort. */
|
||||||
|
/***********************************************************************/
|
||||||
|
ushort CHRBLK::GetUShortValue(int n)
|
||||||
|
{
|
||||||
|
return (ushort)atoi((char *)GetValPtrEx(n));
|
||||||
|
} // end of GetShortValue
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Return the value of the nth element converted to int. */
|
/* Return the value of the nth element converted to int. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -524,6 +581,14 @@ int CHRBLK::GetIntValue(int n)
|
|||||||
return atol((char *)GetValPtrEx(n));
|
return atol((char *)GetValPtrEx(n));
|
||||||
} // end of GetIntValue
|
} // end of GetIntValue
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Return the value of the nth element converted to uint. */
|
||||||
|
/***********************************************************************/
|
||||||
|
uint CHRBLK::GetUIntValue(int n)
|
||||||
|
{
|
||||||
|
return (unsigned)atol((char *)GetValPtrEx(n));
|
||||||
|
} // end of GetIntValue
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Return the value of the nth element converted to big int. */
|
/* Return the value of the nth element converted to big int. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -532,6 +597,14 @@ longlong CHRBLK::GetBigintValue(int n)
|
|||||||
return atoll((char *)GetValPtrEx(n));
|
return atoll((char *)GetValPtrEx(n));
|
||||||
} // end of GetBigintValue
|
} // end of GetBigintValue
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Return the value of the nth element converted to unsigned big int. */
|
||||||
|
/***********************************************************************/
|
||||||
|
ulonglong CHRBLK::GetUBigintValue(int n)
|
||||||
|
{
|
||||||
|
return (unsigned)atoll((char *)GetValPtrEx(n));
|
||||||
|
} // end of GetBigintValue
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Return the value of the nth element converted to double. */
|
/* Return the value of the nth element converted to double. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -548,6 +621,14 @@ char CHRBLK::GetTinyValue(int n)
|
|||||||
return (char)atoi((char *)GetValPtrEx(n));
|
return (char)atoi((char *)GetValPtrEx(n));
|
||||||
} // end of GetTinyValue
|
} // end of GetTinyValue
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Return the value of the nth element converted to unsigned tiny int.*/
|
||||||
|
/***********************************************************************/
|
||||||
|
uchar CHRBLK::GetUTinyValue(int n)
|
||||||
|
{
|
||||||
|
return (uchar)atoi((char *)GetValPtrEx(n));
|
||||||
|
} // end of GetTinyValue
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Set one value in a block. */
|
/* Set one value in a block. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*************** Valblk H Declares Source Code File (.H) ***************/
|
/*************** Valblk H Declares Source Code File (.H) ***************/
|
||||||
/* Name: VALBLK.H Version 1.9 */
|
/* Name: VALBLK.H Version 2.0 */
|
||||||
/* */
|
/* */
|
||||||
/* (C) Copyright to the author Olivier BERTRAND 2005-2013 */
|
/* (C) Copyright to the author Olivier BERTRAND 2005-2013 */
|
||||||
/* */
|
/* */
|
||||||
@@ -18,8 +18,9 @@
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Utility used to allocate value blocks. */
|
/* Utility used to allocate value blocks. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
DllExport PVBLK AllocValBlock(PGLOBAL, void*, int, int, int, int, bool, bool);
|
DllExport PVBLK AllocValBlock(PGLOBAL, void*, int, int, int, int,
|
||||||
const char *GetFmt(int type);
|
bool, bool, bool);
|
||||||
|
const char *GetFmt(int type, bool un = false);
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Class VALBLK represent a base class for variable blocks. */
|
/* Class VALBLK represent a base class for variable blocks. */
|
||||||
@@ -28,7 +29,7 @@ class VALBLK : public BLOCK {
|
|||||||
//friend void SemColData(PGLOBAL g, PSEM semp);
|
//friend void SemColData(PGLOBAL g, PSEM semp);
|
||||||
public:
|
public:
|
||||||
// Constructors
|
// Constructors
|
||||||
VALBLK(void *mp, int type, int nval);
|
VALBLK(void *mp, int type, int nval, bool un = false);
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
int GetNval(void) {return Nval;}
|
int GetNval(void) {return Nval;}
|
||||||
@@ -48,10 +49,14 @@ class VALBLK : public BLOCK {
|
|||||||
virtual int GetVlen(void) = 0;
|
virtual int GetVlen(void) = 0;
|
||||||
virtual PSZ GetCharValue(int n);
|
virtual PSZ GetCharValue(int n);
|
||||||
virtual short GetShortValue(int n) = 0;
|
virtual short GetShortValue(int n) = 0;
|
||||||
|
virtual ushort GetUShortValue(int n) = 0;
|
||||||
virtual int GetIntValue(int n) = 0;
|
virtual int GetIntValue(int n) = 0;
|
||||||
|
virtual uint GetUIntValue(int n) = 0;
|
||||||
virtual longlong GetBigintValue(int n) = 0;
|
virtual longlong GetBigintValue(int n) = 0;
|
||||||
|
virtual ulonglong GetUBigintValue(int n) = 0;
|
||||||
virtual double GetFloatValue(int n) = 0;
|
virtual double GetFloatValue(int n) = 0;
|
||||||
virtual char GetTinyValue(int n) = 0;
|
virtual char GetTinyValue(int n) = 0;
|
||||||
|
virtual uchar GetUTinyValue(int n) = 0;
|
||||||
virtual void ReAlloc(void *mp, int n) {Blkp = mp; Nval = n;}
|
virtual void ReAlloc(void *mp, int n) {Blkp = mp; Nval = n;}
|
||||||
virtual void Reset(int n) = 0;
|
virtual void Reset(int n) = 0;
|
||||||
virtual bool SetFormat(PGLOBAL g, PSZ fmt, int len, int year = 0);
|
virtual bool SetFormat(PGLOBAL g, PSZ fmt, int len, int year = 0);
|
||||||
@@ -60,10 +65,14 @@ class VALBLK : public BLOCK {
|
|||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
virtual void SetValue(short sval, int n) {assert(false);}
|
virtual void SetValue(short sval, int n) {assert(false);}
|
||||||
|
virtual void SetValue(ushort sval, int n) {assert(false);}
|
||||||
virtual void SetValue(int lval, int n) {assert(false);}
|
virtual void SetValue(int lval, int n) {assert(false);}
|
||||||
|
virtual void SetValue(uint lval, int n) {assert(false);}
|
||||||
virtual void SetValue(longlong lval, int n) {assert(false);}
|
virtual void SetValue(longlong lval, int n) {assert(false);}
|
||||||
|
virtual void SetValue(ulonglong lval, int n) {assert(false);}
|
||||||
virtual void SetValue(double fval, int n) {assert(false);}
|
virtual void SetValue(double fval, int n) {assert(false);}
|
||||||
virtual void SetValue(char cval, int n) {assert(false);}
|
virtual void SetValue(char cval, int n) {assert(false);}
|
||||||
|
virtual void SetValue(uchar cval, int n) {assert(false);}
|
||||||
virtual void SetValue(PSZ sp, int n) {assert(false);}
|
virtual void SetValue(PSZ sp, int n) {assert(false);}
|
||||||
virtual void SetValue(char *sp, uint len, int n) {assert(false);}
|
virtual void SetValue(char *sp, uint len, int n) {assert(false);}
|
||||||
virtual void SetValue(PVAL valp, int n) = 0;
|
virtual void SetValue(PVAL valp, int n) = 0;
|
||||||
@@ -94,6 +103,7 @@ class VALBLK : public BLOCK {
|
|||||||
void *Blkp; // To value block
|
void *Blkp; // To value block
|
||||||
bool Check; // If true SetValue types must match
|
bool Check; // If true SetValue types must match
|
||||||
bool Nullable; // True if values can be null
|
bool Nullable; // True if values can be null
|
||||||
|
bool Unsigned; // True if values are unsigned
|
||||||
int Type; // Type of individual values
|
int Type; // Type of individual values
|
||||||
int Nval; // Max number of values in block
|
int Nval; // Max number of values in block
|
||||||
int Prec; // Precision of float values
|
int Prec; // Precision of float values
|
||||||
@@ -106,18 +116,22 @@ template <class TYPE>
|
|||||||
class TYPBLK : public VALBLK {
|
class TYPBLK : public VALBLK {
|
||||||
public:
|
public:
|
||||||
// Constructors
|
// Constructors
|
||||||
TYPBLK(void *mp, int size, int type);
|
TYPBLK(void *mp, int size, int type, int prec = 0, bool un = false);
|
||||||
TYPBLK(void *mp, int size, int prec, int type);
|
//TYPBLK(void *mp, int size, int prec, int type);
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
virtual void Init(PGLOBAL g, bool check);
|
virtual void Init(PGLOBAL g, bool check);
|
||||||
virtual int GetVlen(void) {return sizeof(TYPE);}
|
virtual int GetVlen(void) {return sizeof(TYPE);}
|
||||||
//virtual PSZ GetCharValue(int n);
|
//virtual PSZ GetCharValue(int n);
|
||||||
virtual short GetShortValue(int n) {return (short)Typp[n];}
|
virtual short GetShortValue(int n) {return (short)Typp[n];}
|
||||||
|
virtual ushort GetUShortValue(int n) {return (ushort)Typp[n];}
|
||||||
virtual int GetIntValue(int n) {return (int)Typp[n];}
|
virtual int GetIntValue(int n) {return (int)Typp[n];}
|
||||||
|
virtual uint GetUIntValue(int n) {return (uint)Typp[n];}
|
||||||
virtual longlong GetBigintValue(int n) {return (longlong)Typp[n];}
|
virtual longlong GetBigintValue(int n) {return (longlong)Typp[n];}
|
||||||
|
virtual ulonglong GetUBigintValue(int n) {return (ulonglong)Typp[n];}
|
||||||
virtual double GetFloatValue(int n) {return (double)Typp[n];}
|
virtual double GetFloatValue(int n) {return (double)Typp[n];}
|
||||||
virtual char GetTinyValue(int n) {return (char)Typp[n];}
|
virtual char GetTinyValue(int n) {return (char)Typp[n];}
|
||||||
|
virtual uchar GetUTinyValue(int n) {return (uchar)Typp[n];}
|
||||||
virtual void Reset(int n) {Typp[n] = 0;}
|
virtual void Reset(int n) {Typp[n] = 0;}
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
@@ -125,14 +139,22 @@ class TYPBLK : public VALBLK {
|
|||||||
virtual void SetValue(char *sp, uint len, int n);
|
virtual void SetValue(char *sp, uint len, int n);
|
||||||
virtual void SetValue(short sval, int n)
|
virtual void SetValue(short sval, int n)
|
||||||
{Typp[n] = (TYPE)sval; SetNull(n, false);}
|
{Typp[n] = (TYPE)sval; SetNull(n, false);}
|
||||||
|
virtual void SetValue(ushort sval, int n)
|
||||||
|
{Typp[n] = (TYPE)sval; SetNull(n, false);}
|
||||||
virtual void SetValue(int lval, int n)
|
virtual void SetValue(int lval, int n)
|
||||||
{Typp[n] = (TYPE)lval; SetNull(n, false);}
|
{Typp[n] = (TYPE)lval; SetNull(n, false);}
|
||||||
|
virtual void SetValue(uint lval, int n)
|
||||||
|
{Typp[n] = (TYPE)lval; SetNull(n, false);}
|
||||||
virtual void SetValue(longlong lval, int n)
|
virtual void SetValue(longlong lval, int n)
|
||||||
{Typp[n] = (TYPE)lval; SetNull(n, false);}
|
{Typp[n] = (TYPE)lval; SetNull(n, false);}
|
||||||
|
virtual void SetValue(ulonglong lval, int n)
|
||||||
|
{Typp[n] = (TYPE)lval; SetNull(n, false);}
|
||||||
virtual void SetValue(double fval, int n)
|
virtual void SetValue(double fval, int n)
|
||||||
{Typp[n] = (TYPE)fval; SetNull(n, false);}
|
{Typp[n] = (TYPE)fval; SetNull(n, false);}
|
||||||
virtual void SetValue(char cval, int n)
|
virtual void SetValue(char cval, int n)
|
||||||
{Typp[n] = (TYPE)cval; SetNull(n, false);}
|
{Typp[n] = (TYPE)cval; SetNull(n, false);}
|
||||||
|
virtual void SetValue(uchar cval, int n)
|
||||||
|
{Typp[n] = (TYPE)cval; SetNull(n, false);}
|
||||||
virtual void SetValue(PVAL valp, int n);
|
virtual void SetValue(PVAL valp, int n);
|
||||||
virtual void SetValue(PVBLK pv, int n1, int n2);
|
virtual void SetValue(PVBLK pv, int n1, int n2);
|
||||||
//virtual void SetValues(PVBLK pv, int k, int n);
|
//virtual void SetValues(PVBLK pv, int k, int n);
|
||||||
@@ -168,10 +190,14 @@ class CHRBLK : public VALBLK {
|
|||||||
virtual int GetVlen(void) {return Long;}
|
virtual int GetVlen(void) {return Long;}
|
||||||
virtual PSZ GetCharValue(int n);
|
virtual PSZ GetCharValue(int n);
|
||||||
virtual short GetShortValue(int n);
|
virtual short GetShortValue(int n);
|
||||||
|
virtual ushort GetUShortValue(int n);
|
||||||
virtual int GetIntValue(int n);
|
virtual int GetIntValue(int n);
|
||||||
|
virtual uint GetUIntValue(int n);
|
||||||
virtual longlong GetBigintValue(int n);
|
virtual longlong GetBigintValue(int n);
|
||||||
|
virtual ulonglong GetUBigintValue(int n);
|
||||||
virtual double GetFloatValue(int n);
|
virtual double GetFloatValue(int n);
|
||||||
virtual char GetTinyValue(int n);
|
virtual char GetTinyValue(int n);
|
||||||
|
virtual uchar GetUTinyValue(int n);
|
||||||
virtual void Reset(int n);
|
virtual void Reset(int n);
|
||||||
virtual void SetPrec(int p) {Ci = (p != 0);}
|
virtual void SetPrec(int p) {Ci = (p != 0);}
|
||||||
virtual bool IsCi(void) {return Ci;}
|
virtual bool IsCi(void) {return Ci;}
|
||||||
@@ -217,10 +243,14 @@ class STRBLK : public VALBLK {
|
|||||||
virtual int GetVlen(void) {return sizeof(PSZ);}
|
virtual int GetVlen(void) {return sizeof(PSZ);}
|
||||||
virtual PSZ GetCharValue(int n) {return Strp[n];}
|
virtual PSZ GetCharValue(int n) {return Strp[n];}
|
||||||
virtual short GetShortValue(int n) {return (short)atoi(Strp[n]);}
|
virtual short GetShortValue(int n) {return (short)atoi(Strp[n]);}
|
||||||
|
virtual ushort GetUShortValue(int n) {return (ushort)atoi(Strp[n]);}
|
||||||
virtual int GetIntValue(int n) {return atol(Strp[n]);}
|
virtual int GetIntValue(int n) {return atol(Strp[n]);}
|
||||||
|
virtual uint GetUIntValue(int n) {return (unsigned)atol(Strp[n]);}
|
||||||
virtual longlong GetBigintValue(int n) {return atoll(Strp[n]);}
|
virtual longlong GetBigintValue(int n) {return atoll(Strp[n]);}
|
||||||
|
virtual ulonglong GetUBigintValue(int n) {return (unsigned)atoll(Strp[n]);}
|
||||||
virtual double GetFloatValue(int n) {return atof(Strp[n]);}
|
virtual double GetFloatValue(int n) {return atof(Strp[n]);}
|
||||||
virtual char GetTinyValue(int n) {return (char)atoi(Strp[n]);}
|
virtual char GetTinyValue(int n) {return (char)atoi(Strp[n]);}
|
||||||
|
virtual uchar GetUTinyValue(int n) {return (uchar)atoi(Strp[n]);}
|
||||||
virtual void Reset(int n) {Strp[n] = NULL;}
|
virtual void Reset(int n) {Strp[n] = NULL;}
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/************* Value C++ Functions Source Code File (.CPP) *************/
|
/************* Value C++ Functions Source Code File (.CPP) *************/
|
||||||
/* Name: VALUE.CPP Version 2.2 */
|
/* Name: VALUE.CPP Version 2.3 */
|
||||||
/* */
|
/* */
|
||||||
/* (C) Copyright to the author Olivier BERTRAND 2001-2013 */
|
/* (C) Copyright to the author Olivier BERTRAND 2001-2013 */
|
||||||
/* */
|
/* */
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
/* functions used on one family only. The drawback is that for new */
|
/* functions used on one family only. The drawback is that for new */
|
||||||
/* types of objects, we shall have more classes to update. */
|
/* types of objects, we shall have more classes to update. */
|
||||||
/* Currently the only implemented types are STRING, INT, SHORT, TINY, */
|
/* Currently the only implemented types are STRING, INT, SHORT, TINY, */
|
||||||
/* DATE and LONGLONG. Shortly we should add at least UNSIGNED types. */
|
/* DATE and LONGLONG. Recently we added some UNSIGNED types. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -92,40 +92,12 @@ PSZ strlwr(PSZ s);
|
|||||||
}
|
}
|
||||||
#endif // !WIN32
|
#endif // !WIN32
|
||||||
|
|
||||||
#ifdef NOT_USED
|
|
||||||
/***********************************************************************/
|
|
||||||
/* Returns the bitmap representing the conditions that must not be */
|
|
||||||
/* met when returning from TestValue for a given operator. */
|
|
||||||
/* Bit one is EQ, bit 2 is LT, and bit 3 is GT. */
|
|
||||||
/***********************************************************************/
|
|
||||||
static BYTE OpBmp(PGLOBAL g, OPVAL opc)
|
|
||||||
{
|
|
||||||
BYTE bt;
|
|
||||||
|
|
||||||
switch (opc) {
|
|
||||||
case OP_IN:
|
|
||||||
case OP_EQ: bt = 0x06; break;
|
|
||||||
case OP_NE: bt = 0x01; break;
|
|
||||||
case OP_GT: bt = 0x03; break;
|
|
||||||
case OP_GE: bt = 0x02; break;
|
|
||||||
case OP_LT: bt = 0x05; break;
|
|
||||||
case OP_LE: bt = 0x04; break;
|
|
||||||
case OP_EXIST: bt = 0x00; break;
|
|
||||||
default:
|
|
||||||
sprintf(g->Message, MSG(BAD_FILTER_OP), opc);
|
|
||||||
longjmp(g->jumper[g->jump_level], 777);
|
|
||||||
} // endswitch opc
|
|
||||||
|
|
||||||
return bt;
|
|
||||||
} // end of OpBmp
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* GetTypeName: returns the PlugDB internal type name. */
|
/* GetTypeName: returns the PlugDB internal type name. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PSZ GetTypeName(int type)
|
PSZ GetTypeName(int type)
|
||||||
{
|
{
|
||||||
PSZ name = "UNKNOWN";
|
PSZ name;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TYPE_STRING: name = "CHAR"; break;
|
case TYPE_STRING: name = "CHAR"; break;
|
||||||
@@ -135,6 +107,7 @@ PSZ GetTypeName(int type)
|
|||||||
case TYPE_DATE: name = "DATE"; break;
|
case TYPE_DATE: name = "DATE"; break;
|
||||||
case TYPE_FLOAT: name = "FLOAT"; break;
|
case TYPE_FLOAT: name = "FLOAT"; break;
|
||||||
case TYPE_TINY: name = "TINY"; break;
|
case TYPE_TINY: name = "TINY"; break;
|
||||||
|
default: name = "UNKNOWN"; break;
|
||||||
} // endswitch type
|
} // endswitch type
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
@@ -153,7 +126,6 @@ int GetTypeSize(int type, int len)
|
|||||||
case TYPE_DATE: len = sizeof(int); break;
|
case TYPE_DATE: len = sizeof(int); break;
|
||||||
case TYPE_FLOAT: len = sizeof(double); break;
|
case TYPE_FLOAT: len = sizeof(double); break;
|
||||||
case TYPE_TINY: len = sizeof(char); break;
|
case TYPE_TINY: len = sizeof(char); break;
|
||||||
break;
|
|
||||||
default: len = 0;
|
default: len = 0;
|
||||||
} // endswitch type
|
} // endswitch type
|
||||||
|
|
||||||
@@ -236,21 +208,22 @@ bool IsTypeNum(int type)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* GetFmt: returns the format to use with a typed value. */
|
/* GetFmt: returns the format to use with a typed value. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
const char *GetFmt(int type)
|
const char *GetFmt(int type, bool un)
|
||||||
{
|
{
|
||||||
const char *fmt;
|
const char *fmt;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TYPE_STRING: fmt = "%s"; break;
|
case TYPE_STRING: fmt = "%s"; break;
|
||||||
case TYPE_SHORT: fmt = "%hd"; break;
|
case TYPE_SHORT: fmt = (un) ? "%hu" : "%hd"; break;
|
||||||
case TYPE_BIGINT: fmt = "%lld"; break;
|
case TYPE_BIGINT: fmt = (un) ? "%llu" : "%lld"; break;
|
||||||
case TYPE_FLOAT: fmt = "%.*lf"; break;
|
case TYPE_FLOAT: fmt = "%.*lf"; break;
|
||||||
default: fmt = "%d"; break;
|
default: fmt = (un) ? "%u" : "%d"; break;
|
||||||
} // endswitch Type
|
} // endswitch Type
|
||||||
|
|
||||||
return fmt;
|
return fmt;
|
||||||
} // end of GetFmt
|
} // end of GetFmt
|
||||||
|
|
||||||
|
#if 0
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* ConvertType: what this function does is to determine the type to */
|
/* ConvertType: what this function does is to determine the type to */
|
||||||
/* which should be converted a value so no precision would be lost. */
|
/* which should be converted a value so no precision would be lost. */
|
||||||
@@ -297,6 +270,7 @@ int ConvertType(int target, int type, CONV kind, bool match)
|
|||||||
} // endswitch kind
|
} // endswitch kind
|
||||||
|
|
||||||
} // end of ConvertType
|
} // end of ConvertType
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* AllocateConstant: allocates a constant Value. */
|
/* AllocateConstant: allocates a constant Value. */
|
||||||
@@ -322,7 +296,7 @@ PVAL AllocateValue(PGLOBAL g, void *value, short type)
|
|||||||
valp = new(g) TYPVAL<longlong>(*(longlong*)value, TYPE_BIGINT);
|
valp = new(g) TYPVAL<longlong>(*(longlong*)value, TYPE_BIGINT);
|
||||||
break;
|
break;
|
||||||
case TYPE_FLOAT:
|
case TYPE_FLOAT:
|
||||||
valp = new(g) TYPVAL<double>(*(double *)value, TYPE_FLOAT);
|
valp = new(g) TYPVAL<double>(*(double *)value, TYPE_FLOAT, 2);
|
||||||
break;
|
break;
|
||||||
case TYPE_TINY:
|
case TYPE_TINY:
|
||||||
valp = new(g) TYPVAL<char>(*(char *)value, TYPE_TINY);
|
valp = new(g) TYPVAL<char>(*(char *)value, TYPE_TINY);
|
||||||
@@ -339,8 +313,7 @@ PVAL AllocateValue(PGLOBAL g, void *value, short type)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Allocate a variable Value according to type, length and precision. */
|
/* Allocate a variable Value according to type, length and precision. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PVAL AllocateValue(PGLOBAL g, int type, int len, int prec,
|
PVAL AllocateValue(PGLOBAL g, int type, int len, int prec, PSZ fmt)
|
||||||
PSZ dom, PCATLG cat)
|
|
||||||
{
|
{
|
||||||
PVAL valp;
|
PVAL valp;
|
||||||
|
|
||||||
@@ -349,22 +322,38 @@ PVAL AllocateValue(PGLOBAL g, int type, int len, int prec,
|
|||||||
valp = new(g) TYPVAL<PSZ>(g, (PSZ)NULL, len, prec);
|
valp = new(g) TYPVAL<PSZ>(g, (PSZ)NULL, len, prec);
|
||||||
break;
|
break;
|
||||||
case TYPE_DATE:
|
case TYPE_DATE:
|
||||||
valp = new(g) DTVAL(g, len, prec, dom);
|
valp = new(g) DTVAL(g, len, prec, fmt);
|
||||||
break;
|
break;
|
||||||
case TYPE_INT:
|
case TYPE_INT:
|
||||||
valp = new(g) TYPVAL<int>((int)0, TYPE_INT);
|
if (prec)
|
||||||
|
valp = new(g) TYPVAL<uint>((uint)0, TYPE_INT, 0, true);
|
||||||
|
else
|
||||||
|
valp = new(g) TYPVAL<int>((int)0, TYPE_INT);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TYPE_BIGINT:
|
case TYPE_BIGINT:
|
||||||
valp = new(g) TYPVAL<longlong>((longlong)0, TYPE_BIGINT);
|
if (prec)
|
||||||
|
valp = new(g) TYPVAL<ulonglong>((ulonglong)0, TYPE_BIGINT, 0, true);
|
||||||
|
else
|
||||||
|
valp = new(g) TYPVAL<longlong>((longlong)0, TYPE_BIGINT);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TYPE_SHORT:
|
case TYPE_SHORT:
|
||||||
valp = new(g) TYPVAL<short>((short)0, TYPE_SHORT);
|
if (prec)
|
||||||
|
valp = new(g) TYPVAL<ushort>((ushort)0, TYPE_SHORT, 0, true);
|
||||||
|
else
|
||||||
|
valp = new(g) TYPVAL<short>((short)0, TYPE_SHORT);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TYPE_FLOAT:
|
case TYPE_FLOAT:
|
||||||
valp = new(g) TYPVAL<double>(0.0, prec, TYPE_FLOAT);
|
valp = new(g) TYPVAL<double>(0.0, TYPE_FLOAT, prec);
|
||||||
break;
|
break;
|
||||||
case TYPE_TINY:
|
case TYPE_TINY:
|
||||||
valp = new(g) TYPVAL<char>((char)0, TYPE_TINY);
|
if (prec)
|
||||||
|
valp = new(g) TYPVAL<uchar>((uchar)0, TYPE_TINY, 0, true);
|
||||||
|
else
|
||||||
|
valp = new(g) TYPVAL<char>((char)0, TYPE_TINY);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sprintf(g->Message, MSG(BAD_VALUE_TYPE), type);
|
sprintf(g->Message, MSG(BAD_VALUE_TYPE), type);
|
||||||
@@ -379,9 +368,10 @@ PVAL AllocateValue(PGLOBAL g, int type, int len, int prec,
|
|||||||
/* Allocate a constant Value converted to newtype. */
|
/* Allocate a constant Value converted to newtype. */
|
||||||
/* Can also be used to copy a Value eventually converted. */
|
/* Can also be used to copy a Value eventually converted. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PVAL AllocateValue(PGLOBAL g, PVAL valp, int newtype)
|
PVAL AllocateValue(PGLOBAL g, PVAL valp, int newtype, int uns)
|
||||||
{
|
{
|
||||||
PSZ p, sp;
|
PSZ p, sp;
|
||||||
|
bool un = (uns < 0) ? false : (uns > 0) ? true : valp->IsUnsigned();
|
||||||
|
|
||||||
if (newtype == TYPE_VOID) // Means allocate a value of the same type
|
if (newtype == TYPE_VOID) // Means allocate a value of the same type
|
||||||
newtype = valp->GetType();
|
newtype = valp->GetType();
|
||||||
@@ -396,22 +386,42 @@ PVAL AllocateValue(PGLOBAL g, PVAL valp, int newtype)
|
|||||||
valp = new(g) TYPVAL<PSZ>(g, p, valp->GetValLen(), valp->GetValPrec());
|
valp = new(g) TYPVAL<PSZ>(g, p, valp->GetValLen(), valp->GetValPrec());
|
||||||
break;
|
break;
|
||||||
case TYPE_SHORT:
|
case TYPE_SHORT:
|
||||||
valp = new(g) TYPVAL<short>(valp->GetShortValue(), TYPE_SHORT);
|
if (un)
|
||||||
|
valp = new(g) TYPVAL<ushort>(valp->GetUShortValue(),
|
||||||
|
TYPE_SHORT, 0, true);
|
||||||
|
else
|
||||||
|
valp = new(g) TYPVAL<short>(valp->GetShortValue(), TYPE_SHORT);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TYPE_INT:
|
case TYPE_INT:
|
||||||
valp = new(g) TYPVAL<int>(valp->GetIntValue(), TYPE_INT);
|
if (un)
|
||||||
|
valp = new(g) TYPVAL<uint>(valp->GetUIntValue(), TYPE_INT, 0, true);
|
||||||
|
else
|
||||||
|
valp = new(g) TYPVAL<int>(valp->GetIntValue(), TYPE_INT);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TYPE_BIGINT:
|
case TYPE_BIGINT:
|
||||||
valp = new(g) TYPVAL<longlong>(valp->GetBigintValue(), TYPE_BIGINT);
|
if (un)
|
||||||
|
valp = new(g) TYPVAL<ulonglong>(valp->GetUBigintValue(),
|
||||||
|
TYPE_BIGINT, 0, true);
|
||||||
|
else
|
||||||
|
valp = new(g) TYPVAL<longlong>(valp->GetBigintValue(), TYPE_BIGINT);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TYPE_DATE:
|
case TYPE_DATE:
|
||||||
valp = new(g) DTVAL(g, valp->GetIntValue());
|
valp = new(g) DTVAL(g, valp->GetIntValue());
|
||||||
break;
|
break;
|
||||||
case TYPE_FLOAT:
|
case TYPE_FLOAT:
|
||||||
valp = new(g) TYPVAL<double>(valp->GetFloatValue(), TYPE_FLOAT);
|
valp = new(g) TYPVAL<double>(valp->GetFloatValue(), TYPE_FLOAT,
|
||||||
|
valp->GetValPrec());
|
||||||
break;
|
break;
|
||||||
case TYPE_TINY:
|
case TYPE_TINY:
|
||||||
valp = new(g) TYPVAL<char>(valp->GetTinyValue(), TYPE_TINY);
|
if (un)
|
||||||
|
valp = new(g) TYPVAL<uchar>(valp->GetUTinyValue(),
|
||||||
|
TYPE_TINY, 0, true);
|
||||||
|
else
|
||||||
|
valp = new(g) TYPVAL<char>(valp->GetTinyValue(), TYPE_TINY);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sprintf(g->Message, MSG(BAD_VALUE_TYPE), newtype);
|
sprintf(g->Message, MSG(BAD_VALUE_TYPE), newtype);
|
||||||
@@ -428,14 +438,15 @@ PVAL AllocateValue(PGLOBAL g, PVAL valp, int newtype)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Class VALUE protected constructor. */
|
/* Class VALUE protected constructor. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
VALUE::VALUE(int type) : Type(type)
|
VALUE::VALUE(int type, bool un) : Type(type)
|
||||||
{
|
{
|
||||||
Fmt = GetFmt(Type);
|
|
||||||
Xfmt = GetXfmt();
|
|
||||||
Null = false;
|
Null = false;
|
||||||
Nullable = false;
|
Nullable = false;
|
||||||
|
Unsigned = un;
|
||||||
Clen = 0;
|
Clen = 0;
|
||||||
Prec = 0;
|
Prec = 0;
|
||||||
|
Fmt = GetFmt(Type, Unsigned);
|
||||||
|
Xfmt = GetXfmt();
|
||||||
} // end of VALUE constructor
|
} // end of VALUE constructor
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -446,11 +457,11 @@ const char *VALUE::GetXfmt(void)
|
|||||||
const char *fmt;
|
const char *fmt;
|
||||||
|
|
||||||
switch (Type) {
|
switch (Type) {
|
||||||
case TYPE_STRING: fmt = "%*s"; break;
|
case TYPE_STRING: fmt = "%*s"; break;
|
||||||
case TYPE_SHORT: fmt = "%*hd"; break;
|
case TYPE_SHORT: fmt = (Unsigned) ? "%*hu" : "%*hd"; break;
|
||||||
case TYPE_BIGINT: fmt = "%*lld"; break;
|
case TYPE_BIGINT: fmt = (Unsigned) ? "%*llu" : "%*lld"; break;
|
||||||
case TYPE_FLOAT: fmt = "%*.*lf"; break;
|
case TYPE_FLOAT: fmt = "%*.*lf"; break;
|
||||||
default: fmt = "%*d"; break;
|
default: fmt = (Unsigned) ? "%*u" : "%*d"; break;
|
||||||
} // endswitch Type
|
} // endswitch Type
|
||||||
|
|
||||||
return fmt;
|
return fmt;
|
||||||
@@ -462,22 +473,11 @@ const char *VALUE::GetXfmt(void)
|
|||||||
/* TYPVAL public constructor from a constant typed value. */
|
/* TYPVAL public constructor from a constant typed value. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
template <class TYPE>
|
template <class TYPE>
|
||||||
TYPVAL<TYPE>::TYPVAL(TYPE n, int type) : VALUE(type)
|
TYPVAL<TYPE>::TYPVAL(TYPE n, int type, int prec, bool un)
|
||||||
|
: VALUE(type, un)
|
||||||
{
|
{
|
||||||
Tval = n;
|
Tval = n;
|
||||||
Clen = sizeof(TYPE);
|
Clen = sizeof(TYPE);
|
||||||
Prec = (Type == TYPE_FLOAT) ? 2 : 0;
|
|
||||||
} // end of TYPVAL constructor
|
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
/* TYPVAL public constructor from typed value. */
|
|
||||||
/***********************************************************************/
|
|
||||||
template <class TYPE>
|
|
||||||
TYPVAL<TYPE>::TYPVAL(TYPE n, int prec, int type) : VALUE(type)
|
|
||||||
{
|
|
||||||
assert(Type == TYPE_FLOAT);
|
|
||||||
Tval = n;
|
|
||||||
Clen = sizeof(TYPE);
|
|
||||||
Prec = prec;
|
Prec = prec;
|
||||||
} // end of TYPVAL constructor
|
} // end of TYPVAL constructor
|
||||||
|
|
||||||
@@ -522,14 +522,26 @@ template <>
|
|||||||
short TYPVAL<short>::GetTypedValue(PVAL valp)
|
short TYPVAL<short>::GetTypedValue(PVAL valp)
|
||||||
{return valp->GetShortValue();}
|
{return valp->GetShortValue();}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
ushort TYPVAL<ushort>::GetTypedValue(PVAL valp)
|
||||||
|
{return valp->GetUShortValue();}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
int TYPVAL<int>::GetTypedValue(PVAL valp)
|
int TYPVAL<int>::GetTypedValue(PVAL valp)
|
||||||
{return valp->GetIntValue();}
|
{return valp->GetIntValue();}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
uint TYPVAL<uint>::GetTypedValue(PVAL valp)
|
||||||
|
{return valp->GetUIntValue();}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
longlong TYPVAL<longlong>::GetTypedValue(PVAL valp)
|
longlong TYPVAL<longlong>::GetTypedValue(PVAL valp)
|
||||||
{return valp->GetBigintValue();}
|
{return valp->GetBigintValue();}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
ulonglong TYPVAL<ulonglong>::GetTypedValue(PVAL valp)
|
||||||
|
{return valp->GetUBigintValue();}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
double TYPVAL<double>::GetTypedValue(PVAL valp)
|
double TYPVAL<double>::GetTypedValue(PVAL valp)
|
||||||
{return valp->GetFloatValue();}
|
{return valp->GetFloatValue();}
|
||||||
@@ -538,6 +550,10 @@ template <>
|
|||||||
char TYPVAL<char>::GetTypedValue(PVAL valp)
|
char TYPVAL<char>::GetTypedValue(PVAL valp)
|
||||||
{return valp->GetTinyValue();}
|
{return valp->GetTinyValue();}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
uchar TYPVAL<uchar>::GetTypedValue(PVAL valp)
|
||||||
|
{return valp->GetUTinyValue();}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* TYPVAL SetValue: convert chars extracted from a line to TYPE value.*/
|
/* TYPVAL SetValue: convert chars extracted from a line to TYPE value.*/
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -545,7 +561,7 @@ template <class TYPE>
|
|||||||
void TYPVAL<TYPE>::SetValue_char(char *p, int n)
|
void TYPVAL<TYPE>::SetValue_char(char *p, int n)
|
||||||
{
|
{
|
||||||
char *p2, buf[32];
|
char *p2, buf[32];
|
||||||
bool minus;
|
bool minus = false;
|
||||||
|
|
||||||
for (p2 = p + n; p < p2 && *p == ' '; p++) ;
|
for (p2 = p + n; p < p2 && *p == ' '; p++) ;
|
||||||
|
|
||||||
@@ -570,7 +586,7 @@ void TYPVAL<TYPE>::SetValue_char(char *p, int n)
|
|||||||
} // endswitch *p
|
} // endswitch *p
|
||||||
|
|
||||||
if (minus && Tval)
|
if (minus && Tval)
|
||||||
Tval = - Tval;
|
Tval = (-(signed)Tval) ? -(signed)Tval : Tval;
|
||||||
|
|
||||||
if (trace > 1)
|
if (trace > 1)
|
||||||
htrc(strcat(strcat(strcpy(buf, " setting %s to: "), Fmt), "\n"),
|
htrc(strcat(strcat(strcpy(buf, " setting %s to: "), Fmt), "\n"),
|
||||||
@@ -622,13 +638,21 @@ void TYPVAL<TYPE>::SetValue_psz(PSZ s)
|
|||||||
template <>
|
template <>
|
||||||
int TYPVAL<int>::GetTypedValue(PSZ s) {return atol(s);}
|
int TYPVAL<int>::GetTypedValue(PSZ s) {return atol(s);}
|
||||||
template <>
|
template <>
|
||||||
|
uint TYPVAL<uint>::GetTypedValue(PSZ s) {return (unsigned)atol(s);}
|
||||||
|
template <>
|
||||||
short TYPVAL<short>::GetTypedValue(PSZ s) {return (short)atoi(s);}
|
short TYPVAL<short>::GetTypedValue(PSZ s) {return (short)atoi(s);}
|
||||||
template <>
|
template <>
|
||||||
|
ushort TYPVAL<ushort>::GetTypedValue(PSZ s) {return (ushort)atoi(s);}
|
||||||
|
template <>
|
||||||
longlong TYPVAL<longlong>::GetTypedValue(PSZ s) {return atoll(s);}
|
longlong TYPVAL<longlong>::GetTypedValue(PSZ s) {return atoll(s);}
|
||||||
template <>
|
template <>
|
||||||
|
ulonglong TYPVAL<ulonglong>::GetTypedValue(PSZ s) {return (unsigned)atoll(s);}
|
||||||
|
template <>
|
||||||
double TYPVAL<double>::GetTypedValue(PSZ s) {return atof(s);}
|
double TYPVAL<double>::GetTypedValue(PSZ s) {return atof(s);}
|
||||||
template <>
|
template <>
|
||||||
char TYPVAL<char>::GetTypedValue(PSZ s) {return (char)atoi(s);}
|
char TYPVAL<char>::GetTypedValue(PSZ s) {return (char)atoi(s);}
|
||||||
|
template <>
|
||||||
|
uchar TYPVAL<uchar>::GetTypedValue(PSZ s) {return (uchar)atoi(s);}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* TYPVAL SetValue: set value with a TYPE extracted from a block. */
|
/* TYPVAL SetValue: set value with a TYPE extracted from a block. */
|
||||||
@@ -644,14 +668,26 @@ template <>
|
|||||||
int TYPVAL<int>::GetTypedValue(PVBLK blk, int n)
|
int TYPVAL<int>::GetTypedValue(PVBLK blk, int n)
|
||||||
{return blk->GetIntValue(n);}
|
{return blk->GetIntValue(n);}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
uint TYPVAL<uint>::GetTypedValue(PVBLK blk, int n)
|
||||||
|
{return (unsigned)blk->GetIntValue(n);}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
short TYPVAL<short>::GetTypedValue(PVBLK blk, int n)
|
short TYPVAL<short>::GetTypedValue(PVBLK blk, int n)
|
||||||
{return blk->GetShortValue(n);}
|
{return blk->GetShortValue(n);}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
ushort TYPVAL<ushort>::GetTypedValue(PVBLK blk, int n)
|
||||||
|
{return (unsigned)blk->GetShortValue(n);}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
longlong TYPVAL<longlong>::GetTypedValue(PVBLK blk, int n)
|
longlong TYPVAL<longlong>::GetTypedValue(PVBLK blk, int n)
|
||||||
{return blk->GetBigintValue(n);}
|
{return blk->GetBigintValue(n);}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
ulonglong TYPVAL<ulonglong>::GetTypedValue(PVBLK blk, int n)
|
||||||
|
{return (unsigned)blk->GetBigintValue(n);}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
double TYPVAL<double>::GetTypedValue(PVBLK blk, int n)
|
double TYPVAL<double>::GetTypedValue(PVBLK blk, int n)
|
||||||
{return blk->GetFloatValue(n);}
|
{return blk->GetFloatValue(n);}
|
||||||
@@ -660,6 +696,10 @@ template <>
|
|||||||
char TYPVAL<char>::GetTypedValue(PVBLK blk, int n)
|
char TYPVAL<char>::GetTypedValue(PVBLK blk, int n)
|
||||||
{return blk->GetTinyValue(n);}
|
{return blk->GetTinyValue(n);}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
uchar TYPVAL<uchar>::GetTypedValue(PVBLK blk, int n)
|
||||||
|
{return (unsigned)blk->GetTinyValue(n);}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* TYPVAL SetBinValue: with bytes extracted from a line. */
|
/* TYPVAL SetBinValue: with bytes extracted from a line. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -684,7 +724,7 @@ bool TYPVAL<TYPE>::GetBinValue(void *buf, int buflen, bool go)
|
|||||||
// be different from the variable length because no conversion is done.
|
// be different from the variable length because no conversion is done.
|
||||||
// Therefore this test is useless anyway.
|
// Therefore this test is useless anyway.
|
||||||
//#if defined(_DEBUG)
|
//#if defined(_DEBUG)
|
||||||
// if (sizeof(int) > buflen)
|
// if (sizeof(TYPE) > buflen)
|
||||||
// return true;
|
// return true;
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
@@ -730,6 +770,7 @@ char *TYPVAL<double>::GetCharString(char *p)
|
|||||||
return p;
|
return p;
|
||||||
} // end of GetCharString
|
} // end of GetCharString
|
||||||
|
|
||||||
|
#if 0
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* TYPVAL GetShortString: get short representation of a typed value. */
|
/* TYPVAL GetShortString: get short representation of a typed value. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -779,6 +820,7 @@ char *TYPVAL<TYPE>::GetTinyString(char *p, int n)
|
|||||||
sprintf(p, "%*d", n, (int)(char)Tval);
|
sprintf(p, "%*d", n, (int)(char)Tval);
|
||||||
return p;
|
return p;
|
||||||
} // end of GetIntString
|
} // end of GetIntString
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* TYPVAL compare value with another Value. */
|
/* TYPVAL compare value with another Value. */
|
||||||
@@ -875,7 +917,6 @@ TYPVAL<PSZ>::TYPVAL(PSZ s) : VALUE(TYPE_STRING)
|
|||||||
TYPVAL<PSZ>::TYPVAL(PGLOBAL g, PSZ s, int n, int c)
|
TYPVAL<PSZ>::TYPVAL(PGLOBAL g, PSZ s, int n, int c)
|
||||||
: VALUE(TYPE_STRING)
|
: VALUE(TYPE_STRING)
|
||||||
{
|
{
|
||||||
assert(Type == TYPE_STRING);
|
|
||||||
Len = (g) ? n : strlen(s);
|
Len = (g) ? n : strlen(s);
|
||||||
|
|
||||||
if (!s) {
|
if (!s) {
|
||||||
@@ -981,6 +1022,24 @@ void TYPVAL<PSZ>::SetValue(int n)
|
|||||||
Null = false;
|
Null = false;
|
||||||
} // end of SetValue
|
} // end of SetValue
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* STRING SetValue: get the character representation of an uint. */
|
||||||
|
/***********************************************************************/
|
||||||
|
void TYPVAL<PSZ>::SetValue(uint n)
|
||||||
|
{
|
||||||
|
char buf[16];
|
||||||
|
PGLOBAL& g = Global;
|
||||||
|
int k = sprintf(buf, "%u", n);
|
||||||
|
|
||||||
|
if (k > Len) {
|
||||||
|
sprintf(g->Message, MSG(VALSTR_TOO_LONG), buf, Len);
|
||||||
|
longjmp(g->jumper[g->jump_level], 138);
|
||||||
|
} else
|
||||||
|
SetValue_psz(buf);
|
||||||
|
|
||||||
|
Null = false;
|
||||||
|
} // end of SetValue
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* STRING SetValue: get the character representation of a short int. */
|
/* STRING SetValue: get the character representation of a short int. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -990,6 +1049,15 @@ void TYPVAL<PSZ>::SetValue(short i)
|
|||||||
Null = false;
|
Null = false;
|
||||||
} // end of SetValue
|
} // end of SetValue
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* STRING SetValue: get the character representation of a ushort int. */
|
||||||
|
/***********************************************************************/
|
||||||
|
void TYPVAL<PSZ>::SetValue(ushort i)
|
||||||
|
{
|
||||||
|
SetValue((uint)i);
|
||||||
|
Null = false;
|
||||||
|
} // end of SetValue
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* STRING SetValue: get the character representation of a big integer.*/
|
/* STRING SetValue: get the character representation of a big integer.*/
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -1008,6 +1076,24 @@ void TYPVAL<PSZ>::SetValue(longlong n)
|
|||||||
Null = false;
|
Null = false;
|
||||||
} // end of SetValue
|
} // end of SetValue
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* STRING SetValue: get the character representation of a big integer.*/
|
||||||
|
/***********************************************************************/
|
||||||
|
void TYPVAL<PSZ>::SetValue(ulonglong n)
|
||||||
|
{
|
||||||
|
char buf[24];
|
||||||
|
PGLOBAL& g = Global;
|
||||||
|
int k = sprintf(buf, "%llu", n);
|
||||||
|
|
||||||
|
if (k > Len) {
|
||||||
|
sprintf(g->Message, MSG(VALSTR_TOO_LONG), buf, Len);
|
||||||
|
longjmp(g->jumper[g->jump_level], 138);
|
||||||
|
} else
|
||||||
|
SetValue_psz(buf);
|
||||||
|
|
||||||
|
Null = false;
|
||||||
|
} // end of SetValue
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* STRING SetValue: get the character representation of a double. */
|
/* STRING SetValue: get the character representation of a double. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -1042,6 +1128,15 @@ void TYPVAL<PSZ>::SetValue(char c)
|
|||||||
Null = false;
|
Null = false;
|
||||||
} // end of SetValue
|
} // end of SetValue
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* STRING SetValue: get the character representation of a tiny int. */
|
||||||
|
/***********************************************************************/
|
||||||
|
void TYPVAL<PSZ>::SetValue(uchar c)
|
||||||
|
{
|
||||||
|
SetValue((uint)c);
|
||||||
|
Null = false;
|
||||||
|
} // end of SetValue
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* STRING SetBinValue: fill string with chars extracted from a line. */
|
/* STRING SetBinValue: fill string with chars extracted from a line. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -1086,6 +1181,7 @@ char *TYPVAL<PSZ>::GetCharString(char *p)
|
|||||||
return Strp;
|
return Strp;
|
||||||
} // end of GetCharString
|
} // end of GetCharString
|
||||||
|
|
||||||
|
#if 0
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* STRING GetShortString: get short representation of a char value. */
|
/* STRING GetShortString: get short representation of a char value. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -1130,6 +1226,7 @@ char *TYPVAL<PSZ>::GetTinyString(char *p, int n)
|
|||||||
sprintf(p, "%*d", n, (Null) ? 0 : (char)atoi(Strp));
|
sprintf(p, "%*d", n, (Null) ? 0 : (char)atoi(Strp));
|
||||||
return p;
|
return p;
|
||||||
} // end of GetIntString
|
} // end of GetIntString
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* STRING compare value with another Value. */
|
/* STRING compare value with another Value. */
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/**************** Value H Declares Source Code File (.H) ***************/
|
/**************** Value H Declares Source Code File (.H) ***************/
|
||||||
/* Name: VALUE.H Version 1.9 */
|
/* Name: VALUE.H Version 2.0 */
|
||||||
/* */
|
/* */
|
||||||
/* (C) Copyright to the author Olivier BERTRAND 2001-2013 */
|
/* (C) Copyright to the author Olivier BERTRAND 2001-2013 */
|
||||||
/* */
|
/* */
|
||||||
@@ -45,16 +45,16 @@ DllExport PSZ GetTypeName(int);
|
|||||||
DllExport int GetTypeSize(int, int);
|
DllExport int GetTypeSize(int, int);
|
||||||
#ifdef ODBC_SUPPORT
|
#ifdef ODBC_SUPPORT
|
||||||
/* This function is exported for use in EOM table type DLLs */
|
/* This function is exported for use in EOM table type DLLs */
|
||||||
DllExport int TranslateSQLType(int stp, int prec, int& len);
|
DllExport int TranslateSQLType(int stp, int prec, int& len, char& v);
|
||||||
#endif
|
#endif
|
||||||
DllExport char *GetFormatType(int);
|
DllExport char *GetFormatType(int);
|
||||||
DllExport int GetFormatType(char);
|
DllExport int GetFormatType(char);
|
||||||
DllExport bool IsTypeChar(int type);
|
DllExport bool IsTypeChar(int type);
|
||||||
DllExport bool IsTypeNum(int type);
|
DllExport bool IsTypeNum(int type);
|
||||||
DllExport int ConvertType(int, int, CONV, bool match = false);
|
//lExport int ConvertType(int, int, CONV, bool match = false);
|
||||||
DllExport PVAL AllocateValue(PGLOBAL, PVAL, int = TYPE_VOID);
|
DllExport PVAL AllocateValue(PGLOBAL, PVAL, int = TYPE_VOID, int = 0);
|
||||||
DllExport PVAL AllocateValue(PGLOBAL, int, int len = 0, int prec = 2,
|
DllExport PVAL AllocateValue(PGLOBAL, int, int len = 0, int prec = 0,
|
||||||
PSZ dom = NULL, PCATLG cat = NULL);
|
PSZ fmt = NULL);
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Class VALUE represents a constant or variable of any valid type. */
|
/* Class VALUE represents a constant or variable of any valid type. */
|
||||||
@@ -68,6 +68,7 @@ class DllExport VALUE : public BLOCK {
|
|||||||
virtual bool IsTypeNum(void) = 0;
|
virtual bool IsTypeNum(void) = 0;
|
||||||
virtual bool IsZero(void) = 0;
|
virtual bool IsZero(void) = 0;
|
||||||
virtual bool IsCi(void) {return false;}
|
virtual bool IsCi(void) {return false;}
|
||||||
|
virtual bool IsUnsigned(void) {return Unsigned;}
|
||||||
virtual void Reset(void) = 0;
|
virtual void Reset(void) = 0;
|
||||||
virtual int GetSize(void) = 0;
|
virtual int GetSize(void) = 0;
|
||||||
virtual int GetValLen(void) = 0;
|
virtual int GetValLen(void) = 0;
|
||||||
@@ -75,9 +76,13 @@ class DllExport VALUE : public BLOCK {
|
|||||||
virtual int GetLength(void) {return 1;}
|
virtual int GetLength(void) {return 1;}
|
||||||
virtual PSZ GetCharValue(void) {assert(false); return NULL;}
|
virtual PSZ GetCharValue(void) {assert(false); return NULL;}
|
||||||
virtual char GetTinyValue(void) {assert(false); return 0;}
|
virtual char GetTinyValue(void) {assert(false); return 0;}
|
||||||
|
virtual uchar GetUTinyValue(void) {assert(false); return 0;}
|
||||||
virtual short GetShortValue(void) {assert(false); return 0;}
|
virtual short GetShortValue(void) {assert(false); return 0;}
|
||||||
|
virtual ushort GetUShortValue(void) {assert(false); return 0;}
|
||||||
virtual int GetIntValue(void) = 0;
|
virtual int GetIntValue(void) = 0;
|
||||||
|
virtual uint GetUIntValue(void) = 0;
|
||||||
virtual longlong GetBigintValue(void) = 0;
|
virtual longlong GetBigintValue(void) = 0;
|
||||||
|
virtual ulonglong GetUBigintValue(void) = 0;
|
||||||
virtual double GetFloatValue(void) = 0;
|
virtual double GetFloatValue(void) = 0;
|
||||||
virtual void *GetTo_Val(void) = 0;
|
virtual void *GetTo_Val(void) = 0;
|
||||||
virtual void SetPrec(int prec) {Prec = prec;}
|
virtual void SetPrec(int prec) {Prec = prec;}
|
||||||
@@ -94,20 +99,24 @@ class DllExport VALUE : public BLOCK {
|
|||||||
virtual void SetValue_char(char *p, int n) = 0;
|
virtual void SetValue_char(char *p, int n) = 0;
|
||||||
virtual void SetValue_psz(PSZ s) = 0;
|
virtual void SetValue_psz(PSZ s) = 0;
|
||||||
virtual void SetValue(char c) {assert(false);}
|
virtual void SetValue(char c) {assert(false);}
|
||||||
|
virtual void SetValue(uchar c) {assert(false);}
|
||||||
virtual void SetValue(short i) {assert(false);}
|
virtual void SetValue(short i) {assert(false);}
|
||||||
|
virtual void SetValue(ushort i) {assert(false);}
|
||||||
virtual void SetValue(int n) {assert(false);}
|
virtual void SetValue(int n) {assert(false);}
|
||||||
|
virtual void SetValue(uint n) {assert(false);}
|
||||||
virtual void SetValue(longlong n) {assert(false);}
|
virtual void SetValue(longlong n) {assert(false);}
|
||||||
|
virtual void SetValue(ulonglong n) {assert(false);}
|
||||||
virtual void SetValue(double f) {assert(false);}
|
virtual void SetValue(double f) {assert(false);}
|
||||||
virtual void SetValue_pvblk(PVBLK blk, int n) = 0;
|
virtual void SetValue_pvblk(PVBLK blk, int n) = 0;
|
||||||
virtual void SetBinValue(void *p) = 0;
|
virtual void SetBinValue(void *p) = 0;
|
||||||
virtual bool GetBinValue(void *buf, int buflen, bool go) = 0;
|
virtual bool GetBinValue(void *buf, int buflen, bool go) = 0;
|
||||||
virtual char *ShowValue(char *buf, int len = 0) = 0;
|
virtual char *ShowValue(char *buf, int len = 0) = 0;
|
||||||
virtual char *GetCharString(char *p) = 0;
|
virtual char *GetCharString(char *p) = 0;
|
||||||
virtual char *GetShortString(char *p, int n) {return "#####";}
|
//virtual char *GetShortString(char *p, int n) {return "#####";}
|
||||||
virtual char *GetIntString(char *p, int n) = 0;
|
//virtual char *GetIntString(char *p, int n) = 0;
|
||||||
virtual char *GetBigintString(char *p, int n) = 0;
|
//virtual char *GetBigintString(char *p, int n) = 0;
|
||||||
virtual char *GetFloatString(char *p, int n, int prec) = 0;
|
//virtual char *GetFloatString(char *p, int n, int prec) = 0;
|
||||||
virtual char *GetTinyString(char *p, int n) {return "?";}
|
//virtual char *GetTinyString(char *p, int n) {return "?";}
|
||||||
virtual bool IsEqual(PVAL vp, bool chktype) = 0;
|
virtual bool IsEqual(PVAL vp, bool chktype) = 0;
|
||||||
virtual bool FormatValue(PVAL vp, char *fmt) = 0;
|
virtual bool FormatValue(PVAL vp, char *fmt) = 0;
|
||||||
|
|
||||||
@@ -116,7 +125,7 @@ class DllExport VALUE : public BLOCK {
|
|||||||
const char *GetXfmt(void);
|
const char *GetXfmt(void);
|
||||||
|
|
||||||
// Constructor used by derived classes
|
// Constructor used by derived classes
|
||||||
VALUE(int type);
|
VALUE(int type, bool un = false);
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
PGLOBAL Global; // To reduce arglist
|
PGLOBAL Global; // To reduce arglist
|
||||||
@@ -124,6 +133,7 @@ class DllExport VALUE : public BLOCK {
|
|||||||
const char *Xfmt;
|
const char *Xfmt;
|
||||||
bool Nullable; // True if value can be null
|
bool Nullable; // True if value can be null
|
||||||
bool Null; // True if value is null
|
bool Null; // True if value is null
|
||||||
|
bool Unsigned; // True if unsigned
|
||||||
int Type; // The value type
|
int Type; // The value type
|
||||||
int Clen; // Internal value length
|
int Clen; // Internal value length
|
||||||
int Prec;
|
int Prec;
|
||||||
@@ -135,9 +145,8 @@ class DllExport VALUE : public BLOCK {
|
|||||||
template <class TYPE>
|
template <class TYPE>
|
||||||
class DllExport TYPVAL : public VALUE {
|
class DllExport TYPVAL : public VALUE {
|
||||||
public:
|
public:
|
||||||
// Constructors
|
// Constructor
|
||||||
TYPVAL(TYPE n, int type);
|
TYPVAL(TYPE n, int type, int prec = 0, bool un = false);
|
||||||
TYPVAL(TYPE n, int prec, int type);
|
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
virtual bool IsTypeNum(void) {return true;}
|
virtual bool IsTypeNum(void) {return true;}
|
||||||
@@ -148,9 +157,13 @@ class DllExport TYPVAL : public VALUE {
|
|||||||
virtual int GetSize(void) {return sizeof(TYPE);}
|
virtual int GetSize(void) {return sizeof(TYPE);}
|
||||||
virtual PSZ GetCharValue(void) {return VALUE::GetCharValue();}
|
virtual PSZ GetCharValue(void) {return VALUE::GetCharValue();}
|
||||||
virtual char GetTinyValue(void) {return (char)Tval;}
|
virtual char GetTinyValue(void) {return (char)Tval;}
|
||||||
|
virtual uchar GetUTinyValue(void) {return (uchar)Tval;}
|
||||||
virtual short GetShortValue(void) {return (short)Tval;}
|
virtual short GetShortValue(void) {return (short)Tval;}
|
||||||
|
virtual ushort GetUShortValue(void) {return (ushort)Tval;}
|
||||||
virtual int GetIntValue(void) {return (int)Tval;}
|
virtual int GetIntValue(void) {return (int)Tval;}
|
||||||
|
virtual uint GetUIntValue(void) {return (uint)Tval;}
|
||||||
virtual longlong GetBigintValue(void) {return (longlong)Tval;}
|
virtual longlong GetBigintValue(void) {return (longlong)Tval;}
|
||||||
|
virtual ulonglong GetUBigintValue(void) {return (ulonglong)Tval;}
|
||||||
virtual double GetFloatValue(void) {return (double)Tval;}
|
virtual double GetFloatValue(void) {return (double)Tval;}
|
||||||
virtual void *GetTo_Val(void) {return &Tval;}
|
virtual void *GetTo_Val(void) {return &Tval;}
|
||||||
|
|
||||||
@@ -159,20 +172,24 @@ class DllExport TYPVAL : public VALUE {
|
|||||||
virtual void SetValue_char(char *p, int n);
|
virtual void SetValue_char(char *p, int n);
|
||||||
virtual void SetValue_psz(PSZ s);
|
virtual void SetValue_psz(PSZ s);
|
||||||
virtual void SetValue(char c) {Tval = (TYPE)c; Null = false;}
|
virtual void SetValue(char c) {Tval = (TYPE)c; Null = false;}
|
||||||
|
virtual void SetValue(uchar c) {Tval = (TYPE)c; Null = false;}
|
||||||
virtual void SetValue(short i) {Tval = (TYPE)i; Null = false;}
|
virtual void SetValue(short i) {Tval = (TYPE)i; Null = false;}
|
||||||
|
virtual void SetValue(ushort i) {Tval = (TYPE)i; Null = false;}
|
||||||
virtual void SetValue(int n) {Tval = (TYPE)n; Null = false;}
|
virtual void SetValue(int n) {Tval = (TYPE)n; Null = false;}
|
||||||
|
virtual void SetValue(uint n) {Tval = (TYPE)n; Null = false;}
|
||||||
virtual void SetValue(longlong n) {Tval = (TYPE)n; Null = false;}
|
virtual void SetValue(longlong n) {Tval = (TYPE)n; Null = false;}
|
||||||
|
virtual void SetValue(ulonglong n) {Tval = (TYPE)n; Null = false;}
|
||||||
virtual void SetValue(double f) {Tval = (TYPE)f; Null = false;}
|
virtual void SetValue(double f) {Tval = (TYPE)f; Null = false;}
|
||||||
virtual void SetValue_pvblk(PVBLK blk, int n);
|
virtual void SetValue_pvblk(PVBLK blk, int n);
|
||||||
virtual void SetBinValue(void *p);
|
virtual void SetBinValue(void *p);
|
||||||
virtual bool GetBinValue(void *buf, int buflen, bool go);
|
virtual bool GetBinValue(void *buf, int buflen, bool go);
|
||||||
virtual char *ShowValue(char *buf, int);
|
virtual char *ShowValue(char *buf, int);
|
||||||
virtual char *GetCharString(char *p);
|
virtual char *GetCharString(char *p);
|
||||||
virtual char *GetShortString(char *p, int n);
|
//virtual char *GetShortString(char *p, int n);
|
||||||
virtual char *GetIntString(char *p, int n);
|
//virtual char *GetIntString(char *p, int n);
|
||||||
virtual char *GetBigintString(char *p, int n);
|
//virtual char *GetBigintString(char *p, int n);
|
||||||
virtual char *GetFloatString(char *p, int n, int prec = -1);
|
//virtual char *GetFloatString(char *p, int n, int prec = -1);
|
||||||
virtual char *GetTinyString(char *p, int n);
|
//virtual char *GetTinyString(char *p, int n);
|
||||||
virtual bool IsEqual(PVAL vp, bool chktype);
|
virtual bool IsEqual(PVAL vp, bool chktype);
|
||||||
virtual bool SetConstFormat(PGLOBAL, FORMAT&);
|
virtual bool SetConstFormat(PGLOBAL, FORMAT&);
|
||||||
virtual bool FormatValue(PVAL vp, char *fmt);
|
virtual bool FormatValue(PVAL vp, char *fmt);
|
||||||
@@ -211,9 +228,13 @@ class DllExport TYPVAL<PSZ>: public VALUE {
|
|||||||
virtual int GetSize(void) {return (Strp) ? strlen(Strp) : 0;}
|
virtual int GetSize(void) {return (Strp) ? strlen(Strp) : 0;}
|
||||||
virtual PSZ GetCharValue(void) {return Strp;}
|
virtual PSZ GetCharValue(void) {return Strp;}
|
||||||
virtual char GetTinyValue(void) {return (char)atoi(Strp);}
|
virtual char GetTinyValue(void) {return (char)atoi(Strp);}
|
||||||
|
virtual uchar GetUTinyValue(void) {return (uchar)atoi(Strp);}
|
||||||
virtual short GetShortValue(void) {return (short)atoi(Strp);}
|
virtual short GetShortValue(void) {return (short)atoi(Strp);}
|
||||||
|
virtual ushort GetUShortValue(void) {return (ushort)atoi(Strp);}
|
||||||
virtual int GetIntValue(void) {return atol(Strp);}
|
virtual int GetIntValue(void) {return atol(Strp);}
|
||||||
|
virtual uint GetUIntValue(void) {return (uint)atol(Strp);}
|
||||||
virtual longlong GetBigintValue(void) {return atoll(Strp);}
|
virtual longlong GetBigintValue(void) {return atoll(Strp);}
|
||||||
|
virtual ulonglong GetUBigintValue(void) {return (ulonglong)atoll(Strp);}
|
||||||
virtual double GetFloatValue(void) {return atof(Strp);}
|
virtual double GetFloatValue(void) {return atof(Strp);}
|
||||||
virtual void *GetTo_Val(void) {return Strp;}
|
virtual void *GetTo_Val(void) {return Strp;}
|
||||||
virtual void SetPrec(int prec) {Ci = prec != 0;}
|
virtual void SetPrec(int prec) {Ci = prec != 0;}
|
||||||
@@ -224,30 +245,34 @@ class DllExport TYPVAL<PSZ>: public VALUE {
|
|||||||
virtual void SetValue_psz(PSZ s);
|
virtual void SetValue_psz(PSZ s);
|
||||||
virtual void SetValue_pvblk(PVBLK blk, int n);
|
virtual void SetValue_pvblk(PVBLK blk, int n);
|
||||||
virtual void SetValue(char c);
|
virtual void SetValue(char c);
|
||||||
|
virtual void SetValue(uchar c);
|
||||||
virtual void SetValue(short i);
|
virtual void SetValue(short i);
|
||||||
|
virtual void SetValue(ushort i);
|
||||||
virtual void SetValue(int n);
|
virtual void SetValue(int n);
|
||||||
|
virtual void SetValue(uint n);
|
||||||
virtual void SetValue(longlong n);
|
virtual void SetValue(longlong n);
|
||||||
|
virtual void SetValue(ulonglong n);
|
||||||
virtual void SetValue(double f);
|
virtual void SetValue(double f);
|
||||||
virtual void SetBinValue(void *p);
|
virtual void SetBinValue(void *p);
|
||||||
virtual bool GetBinValue(void *buf, int buflen, bool go);
|
virtual bool GetBinValue(void *buf, int buflen, bool go);
|
||||||
virtual char *ShowValue(char *buf, int);
|
virtual char *ShowValue(char *buf, int);
|
||||||
virtual char *GetCharString(char *p);
|
virtual char *GetCharString(char *p);
|
||||||
virtual char *GetShortString(char *p, int n);
|
//virtual char *GetShortString(char *p, int n);
|
||||||
virtual char *GetIntString(char *p, int n);
|
//virtual char *GetIntString(char *p, int n);
|
||||||
virtual char *GetBigintString(char *p, int n);
|
//virtual char *GetBigintString(char *p, int n);
|
||||||
virtual char *GetFloatString(char *p, int n, int prec = -1);
|
//virtual char *GetFloatString(char *p, int n, int prec = -1);
|
||||||
virtual char *GetTinyString(char *p, int n);
|
//virtual char *GetTinyString(char *p, int n);
|
||||||
virtual bool IsEqual(PVAL vp, bool chktype);
|
virtual bool IsEqual(PVAL vp, bool chktype);
|
||||||
virtual bool FormatValue(PVAL vp, char *fmt);
|
virtual bool FormatValue(PVAL vp, char *fmt);
|
||||||
virtual bool SetConstFormat(PGLOBAL, FORMAT&);
|
virtual bool SetConstFormat(PGLOBAL, FORMAT&);
|
||||||
|
|
||||||
// Specialized functions
|
// Specialized functions
|
||||||
template <class T>
|
//template <class T>
|
||||||
T GetValue_as(T type) {return Strp;}
|
//T GetValue_as(T type) {return Strp;}
|
||||||
int GetValue_as(int type) {return atol(Strp);}
|
//int GetValue_as(int type) {return atol(Strp);}
|
||||||
short GetValue_as(short type) {return (short)atoi(Strp);}
|
//short GetValue_as(short type) {return (short)atoi(Strp);}
|
||||||
longlong GetValue_as(longlong type) {return atoll(Strp);}
|
//longlong GetValue_as(longlong type) {return atoll(Strp);}
|
||||||
double GetValue_as(double type) {return atof(Strp);}
|
//double GetValue_as(double type) {return atof(Strp);}
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
PSZ Strp;
|
PSZ Strp;
|
||||||
|
@@ -66,7 +66,7 @@ extern MBLOCK Nmblk; /* Used to initialize MBLOCK's */
|
|||||||
/* to have rows filled by blanks to be compatible with QRY blocks. */
|
/* to have rows filled by blanks to be compatible with QRY blocks. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PVBLK AllocValBlock(PGLOBAL, void *, int, int, int, int,
|
PVBLK AllocValBlock(PGLOBAL, void *, int, int, int, int,
|
||||||
bool check = true, bool blank = true);
|
bool check = true, bool blank = true, bool un = false);
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Check whether we have to create/update permanent indexes. */
|
/* Check whether we have to create/update permanent indexes. */
|
||||||
@@ -2919,7 +2919,7 @@ void KXYCOL::SetValue(PCOL colp, int i)
|
|||||||
assert (Kblp != NULL);
|
assert (Kblp != NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Kblp->SetValue(colp->GetValue(), (int)i);
|
Kblp->SetValue(colp->GetValue(), i);
|
||||||
} // end of SetValue
|
} // end of SetValue
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -2970,7 +2970,7 @@ void KXYCOL::FillValue(PVAL valp)
|
|||||||
int KXYCOL::Compare(int i1, int i2)
|
int KXYCOL::Compare(int i1, int i2)
|
||||||
{
|
{
|
||||||
// Do the actual comparison between values.
|
// Do the actual comparison between values.
|
||||||
register int k = (int)Kblp->CompVal((int)i1, (int)i2);
|
register int k = Kblp->CompVal(i1, i2);
|
||||||
|
|
||||||
#ifdef DEBUG2
|
#ifdef DEBUG2
|
||||||
htrc("Compare done result=%d\n", k);
|
htrc("Compare done result=%d\n", k);
|
||||||
@@ -2991,7 +2991,7 @@ int KXYCOL::CompVal(int i)
|
|||||||
htrc("Compare done result=%d\n", k);
|
htrc("Compare done result=%d\n", k);
|
||||||
return k;
|
return k;
|
||||||
#endif
|
#endif
|
||||||
return (int)Kblp->CompVal(Valp, (int)i);
|
return Kblp->CompVal(Valp, i);
|
||||||
} // end of CompVal
|
} // end of CompVal
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -3000,7 +3000,7 @@ int KXYCOL::CompVal(int i)
|
|||||||
int KXYCOL::CompBval(int i)
|
int KXYCOL::CompBval(int i)
|
||||||
{
|
{
|
||||||
// Do the actual comparison between key values.
|
// Do the actual comparison between key values.
|
||||||
return (int)Blkp->CompVal(Valp, (int)i);
|
return Blkp->CompVal(Valp, i);
|
||||||
} // end of CompBval
|
} // end of CompBval
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -18,8 +18,28 @@
|
|||||||
#include "colblk.h"
|
#include "colblk.h"
|
||||||
#include "m_ctype.h"
|
#include "m_ctype.h"
|
||||||
|
|
||||||
//pedef class INDEXDEF *PIXDEF;
|
typedef class CMD *PCMD;
|
||||||
typedef char *PFIL; // Specific to CONNECT
|
|
||||||
|
// Commands executed by XDBC and MYX tables
|
||||||
|
class CMD : public BLOCK {
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
CMD(PGLOBAL g, char *cmd) {
|
||||||
|
Cmd = (char*)PlugSubAlloc(g, NULL, strlen(cmd) + 1);
|
||||||
|
strcpy(Cmd, cmd); Next = NULL; }
|
||||||
|
|
||||||
|
// Members
|
||||||
|
PCMD Next;
|
||||||
|
char *Cmd;
|
||||||
|
}; // end of class CMD
|
||||||
|
|
||||||
|
// Filter passed all tables
|
||||||
|
typedef struct _filter {
|
||||||
|
char *Body;
|
||||||
|
OPVAL Op;
|
||||||
|
PCMD Cmds;
|
||||||
|
} FILTER, *PFIL;
|
||||||
|
|
||||||
typedef class TDBCAT *PTDBCAT;
|
typedef class TDBCAT *PTDBCAT;
|
||||||
typedef class CATCOL *PCATCOL;
|
typedef class CATCOL *PCATCOL;
|
||||||
|
|
||||||
@@ -39,24 +59,16 @@ class DllExport TBX: public BLOCK { // Base class for OPJOIN and TDB classes.
|
|||||||
inline PFIL GetFilter(void) {return To_Filter;}
|
inline PFIL GetFilter(void) {return To_Filter;}
|
||||||
inline void SetOrig(PTBX txp) {To_Orig = txp;}
|
inline void SetOrig(PTBX txp) {To_Orig = txp;}
|
||||||
inline void SetFilter(PFIL fp) {To_Filter = fp;}
|
inline void SetFilter(PFIL fp) {To_Filter = fp;}
|
||||||
//inline JTYPE GetJtype(void) {return Jtype;}
|
|
||||||
//inline void SetJtype(JTYPE jt) {Jtype = jt;}
|
|
||||||
//inline PFIL GetNoleft(void) {return To_Noleft;}
|
|
||||||
//inline void SetNoleft(PFIL fp) {To_Noleft = fp;}
|
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
virtual bool IsSame(PTBX tp) {return tp == this;}
|
virtual bool IsSame(PTBX tp) {return tp == this;}
|
||||||
//virtual bool Include(PTBX tbxp) = 0;
|
|
||||||
//virtual bool CheckFilter(void) = 0;
|
|
||||||
virtual int GetTdb_No(void) = 0; // Convenience during conversion
|
virtual int GetTdb_No(void) = 0; // Convenience during conversion
|
||||||
virtual PTDB GetNext(void) = 0;
|
virtual PTDB GetNext(void) = 0;
|
||||||
//virtual int GetMaxSame(PGLOBAL) = 0;
|
|
||||||
virtual int Cardinality(PGLOBAL) = 0;
|
virtual int Cardinality(PGLOBAL) = 0;
|
||||||
virtual int GetMaxSize(PGLOBAL) = 0;
|
virtual int GetMaxSize(PGLOBAL) = 0;
|
||||||
virtual int GetProgMax(PGLOBAL) = 0;
|
virtual int GetProgMax(PGLOBAL) = 0;
|
||||||
virtual int GetProgCur(void) = 0;
|
virtual int GetProgCur(void) = 0;
|
||||||
virtual int GetBadLines(void) {return 0;}
|
virtual int GetBadLines(void) {return 0;}
|
||||||
//virtual bool IsJoin(void) = 0;
|
|
||||||
virtual PTBX Copy(PTABS t) = 0;
|
virtual PTBX Copy(PTABS t) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -66,8 +78,6 @@ class DllExport TBX: public BLOCK { // Base class for OPJOIN and TDB classes.
|
|||||||
// Members
|
// Members
|
||||||
PTBX To_Orig; // Pointer to original if it is a copy
|
PTBX To_Orig; // Pointer to original if it is a copy
|
||||||
PFIL To_Filter;
|
PFIL To_Filter;
|
||||||
//PFIL To_Noleft; // To filter not involved in LEFT JOIN
|
|
||||||
//JTYPE Jtype;
|
|
||||||
TUSE Use;
|
TUSE Use;
|
||||||
}; // end of class TBX
|
}; // end of class TBX
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user