This is a major update concerning many source files.

Fix MDEV-12035.
  modified:   storage/connect/jsonudf.cpp

Working on MDEV-11832: Srcdef performance enhancement
This require to mark place holders into srcdef to indicate where to insert
the where/having clauses that are retrieved in push_cond.
However this also make necessary to handle aliases in the srcdef.
This was the opportunity to base all external tables on common classes
called EXTDEF, TABEXT and EXTCOL.
  modified:   storage/connect/array.cpp
  modified:   storage/connect/array.h
  modified:   storage/connect/colblk.cpp
  modified:   storage/connect/connect.cc
  modified:   storage/connect/filamdbf.cpp
  modified:   storage/connect/ha_connect.cc
  modified:   storage/connect/jdbconn.cpp
  modified:   storage/connect/mycat.cc
  modified:   storage/connect/myconn.cpp
  modified:   storage/connect/odbconn.cpp
  modified:   storage/connect/plgdbsem.h
  modified:   storage/connect/reldef.cpp
  modified:   storage/connect/reldef.h
  modified:   storage/connect/tabdos.cpp
  modified:   storage/connect/tabdos.h
  modified:   storage/connect/tabfix.cpp
  modified:   storage/connect/tabfix.h
  modified:   storage/connect/tabfmt.cpp
  modified:   storage/connect/tabfmt.h
  modified:   storage/connect/tabjdbc.cpp
  modified:   storage/connect/tabjdbc.h
  modified:   storage/connect/tabjson.cpp
  modified:   storage/connect/tabjson.h
  modified:   storage/connect/table.cpp
  modified:   storage/connect/tabmac.cpp
  modified:   storage/connect/tabmac.h
  modified:   storage/connect/tabmul.cpp
  modified:   storage/connect/tabmul.h
  modified:   storage/connect/tabmysql.cpp
  modified:   storage/connect/tabmysql.h
  modified:   storage/connect/taboccur.cpp
  modified:   storage/connect/tabodbc.cpp
  modified:   storage/connect/tabodbc.h
  modified:   storage/connect/tabpivot.cpp
  modified:   storage/connect/tabpivot.h
  modified:   storage/connect/tabsys.cpp
  modified:   storage/connect/tabsys.h
  modified:   storage/connect/tabtbl.cpp
  modified:   storage/connect/tabutil.cpp
  modified:   storage/connect/tabutil.h
  modified:   storage/connect/tabvct.cpp
  modified:   storage/connect/tabvct.h
  modified:   storage/connect/tabvir.cpp
  modified:   storage/connect/tabwmi.cpp
  modified:   storage/connect/tabxcl.cpp
  modified:   storage/connect/tabxcl.h
  modified:   storage/connect/tabxml.cpp
  modified:   storage/connect/tabxml.h
  modified:   storage/connect/xindex.cpp
  modified:   storage/connect/xindex.h
  modified:   storage/connect/xobject.h
  modified:   storage/connect/xtable.h
  added:      storage/connect/tabext.cpp
  added:      storage/connect/tabext.h
This commit is contained in:
Olivier Bertrand 2017-02-14 12:20:20 +01:00
parent 9fa0d2fe98
commit 5c2c68d454
55 changed files with 2124 additions and 1450 deletions

View file

@ -1,7 +1,7 @@
/************* Array C++ Functions Source Code File (.CPP) *************/
/* Name: ARRAY.CPP Version 2.3 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2005-2015 */
/* (C) Copyright to the author Olivier BERTRAND 2005-2017 */
/* */
/* This file contains the XOBJECT derived class ARRAY functions. */
/* ARRAY is used for elaborate type of processing, such as sorting */
@ -141,7 +141,7 @@ PARRAY MakeValueArray(PGLOBAL g, PPARM pp)
/* ARRAY public constructor. */
/***********************************************************************/
ARRAY::ARRAY(PGLOBAL g, int type, int size, int length, int prec)
: CSORT(FALSE)
: CSORT(false)
{
Nval = 0;
Ndif = 0;
@ -188,14 +188,14 @@ ARRAY::ARRAY(PGLOBAL g, int type, int size, int length, int prec)
else if (type != TYPE_PCHAR)
Value = AllocateValue(g, type, Len, prec);
Constant = TRUE;
Constant = true;
} // end of ARRAY constructor
#if 0
/***********************************************************************/
/* ARRAY public constructor from a QUERY. */
/***********************************************************************/
ARRAY::ARRAY(PGLOBAL g, PQUERY qryp) : CSORT(FALSE)
ARRAY::ARRAY(PGLOBAL g, PQUERY qryp) : CSORT(false)
{
Type = qryp->GetColType(0);
Nval = qryp->GetNblin();
@ -206,7 +206,7 @@ ARRAY::ARRAY(PGLOBAL g, PQUERY qryp) : CSORT(FALSE)
Xsize = -1;
Len = qryp->GetColLength(0);
X = Inf = Sup = 0;
Correlated = FALSE;
Correlated = false;
switch (Type) {
case TYPE_STRING:
@ -229,13 +229,13 @@ ARRAY::ARRAY(PGLOBAL g, PQUERY qryp) : CSORT(FALSE)
// The error message was built by ???
Type = TYPE_ERROR;
Constant = TRUE;
Constant = true;
} // end of ARRAY constructor
/***********************************************************************/
/* ARRAY constructor from a TYPE_LIST subarray. */
/***********************************************************************/
ARRAY::ARRAY(PGLOBAL g, PARRAY par, int k) : CSORT(FALSE)
ARRAY::ARRAY(PGLOBAL g, PARRAY par, int k) : CSORT(false)
{
int prec;
LSTBLK *lp;
@ -260,7 +260,7 @@ ARRAY::ARRAY(PGLOBAL g, PARRAY par, int k) : CSORT(FALSE)
Len = (Type == TYPE_STRING) ? Vblp->GetVlen() : 0;
prec = (Type == TYPE_FLOAT) ? 2 : 0;
Value = AllocateValue(g, Type, Len, prec, NULL);
Constant = TRUE;
Constant = true;
} // end of ARRAY constructor
/***********************************************************************/
@ -283,7 +283,7 @@ bool ARRAY::AddValue(PGLOBAL g, PSZ strp)
{
if (Type != TYPE_STRING) {
sprintf(g->Message, MSG(ADD_BAD_TYPE), GetTypeName(Type), "CHAR");
return TRUE;
return true;
} // endif Type
if (trace)
@ -292,7 +292,7 @@ bool ARRAY::AddValue(PGLOBAL g, PSZ strp)
//Value->SetValue_psz(strp);
//Vblp->SetValue(valp, Nval++);
Vblp->SetValue(strp, Nval++);
return FALSE;
return false;
} // end of AddValue
/***********************************************************************/
@ -302,14 +302,14 @@ bool ARRAY::AddValue(PGLOBAL g, void *p)
{
if (Type != TYPE_PCHAR) {
sprintf(g->Message, MSG(ADD_BAD_TYPE), GetTypeName(Type), "PCHAR");
return TRUE;
return true;
} // endif Type
if (trace)
htrc(" adding pointer(%d): %p\n", Nval, p);
Vblp->SetValue((PSZ)p, Nval++);
return FALSE;
return false;
} // end of AddValue
/***********************************************************************/
@ -319,7 +319,7 @@ bool ARRAY::AddValue(PGLOBAL g, short n)
{
if (Type != TYPE_SHORT) {
sprintf(g->Message, MSG(ADD_BAD_TYPE), GetTypeName(Type), "SHORT");
return TRUE;
return true;
} // endif Type
if (trace)
@ -328,7 +328,7 @@ bool ARRAY::AddValue(PGLOBAL g, short n)
//Value->SetValue(n);
//Vblp->SetValue(valp, Nval++);
Vblp->SetValue(n, Nval++);
return FALSE;
return false;
} // end of AddValue
/***********************************************************************/
@ -338,7 +338,7 @@ bool ARRAY::AddValue(PGLOBAL g, int n)
{
if (Type != TYPE_INT) {
sprintf(g->Message, MSG(ADD_BAD_TYPE), GetTypeName(Type), "INTEGER");
return TRUE;
return true;
} // endif Type
if (trace)
@ -347,7 +347,7 @@ bool ARRAY::AddValue(PGLOBAL g, int n)
//Value->SetValue(n);
//Vblp->SetValue(valp, Nval++);
Vblp->SetValue(n, Nval++);
return FALSE;
return false;
} // end of AddValue
/***********************************************************************/
@ -357,7 +357,7 @@ bool ARRAY::AddValue(PGLOBAL g, double d)
{
if (Type != TYPE_DOUBLE) {
sprintf(g->Message, MSG(ADD_BAD_TYPE), GetTypeName(Type), "DOUBLE");
return TRUE;
return true;
} // endif Type
if (trace)
@ -365,7 +365,7 @@ bool ARRAY::AddValue(PGLOBAL g, double d)
Value->SetValue(d);
Vblp->SetValue(Value, Nval++);
return FALSE;
return false;
} // end of AddValue
/***********************************************************************/
@ -376,7 +376,7 @@ bool ARRAY::AddValue(PGLOBAL g, PXOB xp)
if (Type != xp->GetResultType()) {
sprintf(g->Message, MSG(ADD_BAD_TYPE),
GetTypeName(xp->GetResultType()), GetTypeName(Type));
return TRUE;
return true;
} // endif Type
if (trace)
@ -384,7 +384,7 @@ bool ARRAY::AddValue(PGLOBAL g, PXOB xp)
//AddValue(xp->GetValue());
Vblp->SetValue(xp->GetValue(), Nval++);
return FALSE;
return false;
} // end of AddValue
/***********************************************************************/
@ -395,14 +395,14 @@ bool ARRAY::AddValue(PGLOBAL g, PVAL vp)
if (Type != vp->GetType()) {
sprintf(g->Message, MSG(ADD_BAD_TYPE),
GetTypeName(vp->GetType()), GetTypeName(Type));
return TRUE;
return true;
} // endif Type
if (trace)
htrc(" adding (%d) from vp=%p\n", Nval, vp);
Vblp->SetValue(vp, Nval++);
return FALSE;
return false;
} // end of AddValue
/***********************************************************************/
@ -423,12 +423,12 @@ bool ARRAY::GetSubValue(PGLOBAL g, PVAL valp, int *kp)
if (Type != TYPE_LIST) {
sprintf(g->Message, MSG(NO_SUB_VAL), Type);
return TRUE;
return true;
} // endif Type
vblp = ((LSTBLK*)Vblp)->Mbvk[kp[0]]->Vblk;
valp->SetValue_pvblk(vblp, kp[1]);
return FALSE;
return false;
} // end of GetSubValue
#endif // 0
@ -476,11 +476,11 @@ bool ARRAY::Find(PVAL valp)
else if (n > 0)
Inf = X;
else
return TRUE;
return true;
} // endwhile
return FALSE;
return false;
} // end of Find
/***********************************************************************/
@ -504,9 +504,9 @@ bool ARRAY::FilTest(PGLOBAL g, PVAL valp, OPVAL opc, int opm)
int top = Nval - 1;
if (top < 0) // Array is empty
// Return TRUE for ALL because it means that there are no item that
// Return true for ALL because it means that there are no item that
// does not verify the condition, which is true indeed.
// Return FALSE for ANY because TRUE means that there is at least
// Return false for ANY because true means that there is at least
// one item that verifies the condition, which is false.
return opm == 2;
@ -528,9 +528,9 @@ bool ARRAY::FilTest(PGLOBAL g, PVAL valp, OPVAL opc, int opm)
else if (opc == OP_NE && opm == 2)
return !Find(vp);
else if (opc == OP_EQ && opm == 2)
return (Ndif == 1) ? !(Vcompare(vp, 0) & bt) : FALSE;
return (Ndif == 1) ? !(Vcompare(vp, 0) & bt) : false;
else if (opc == OP_NE && opm == 1)
return (Ndif == 1) ? !(Vcompare(vp, 0) & bt) : TRUE;
return (Ndif == 1) ? !(Vcompare(vp, 0) & bt) : true;
if (Type != TYPE_LIST) {
if (opc == OP_GT || opc == OP_GE)
@ -544,15 +544,15 @@ bool ARRAY::FilTest(PGLOBAL g, PVAL valp, OPVAL opc, int opm)
if (opm == 2) {
for (i = 0; i < Nval; i++)
if (Vcompare(vp, i) & bt)
return FALSE;
return false;
return TRUE;
return true;
} else { // opm == 1
for (i = 0; i < Nval; i++)
if (!(Vcompare(vp, i) & bt))
return TRUE;
return true;
return FALSE;
return false;
} // endif opm
} // end of FilTest
@ -566,7 +566,7 @@ bool ARRAY::CanBeShort(void)
int* To_Val = (int*)Valblk->GetMemp();
if (Type != TYPE_INT || !Ndif)
return FALSE;
return false;
// Because the array is sorted, this is true if all the array
// int values are in the range of SHORT values
@ -582,7 +582,7 @@ bool ARRAY::CanBeShort(void)
int ARRAY::Convert(PGLOBAL g, int k, PVAL vp)
{
int i, prec = 0;
bool b = FALSE;
bool b = false;
PMBV ovblk = Valblk;
PVBLK ovblp = Vblp;
@ -619,7 +619,7 @@ int ARRAY::Convert(PGLOBAL g, int k, PVAL vp)
if (((DTVAL*)Value)->SetFormat(g, vp))
return TYPE_ERROR;
else
b = TRUE; // Sort the new array on date internal values
b = true; // Sort the new array on date internal values
/*********************************************************************/
/* Do the actual conversion. */
@ -706,7 +706,7 @@ void ARRAY::SetPrecision(PGLOBAL g, int p)
/***********************************************************************/
/* Sort and eliminate distinct values from an array. */
/* Note: this is done by making a sorted index on distinct values. */
/* Returns FALSE if Ok or TRUE in case of error. */
/* Returns false if Ok or true in case of error. */
/***********************************************************************/
bool ARRAY::Sort(PGLOBAL g)
{
@ -789,14 +789,14 @@ bool ARRAY::Sort(PGLOBAL g)
Bot = -1; // For non optimized search
Top = Ndif; // Find searches the whole array.
return FALSE;
return false;
error:
Nval = Ndif = 0;
Valblk->Free();
PlgDBfree(Index);
PlgDBfree(Offset);
return TRUE;
return true;
} // end of Sort
/***********************************************************************/
@ -839,9 +839,9 @@ void *ARRAY::GetSortIndex(PGLOBAL g)
/***********************************************************************/
/* Block filter testing for IN operator on Column/Array operands. */
/* Here we call Find that returns TRUE if the value is in the array */
/* Here we call Find that returns true if the value is in the array */
/* with X equal to the index of the found value in the array, or */
/* FALSE if the value is not in the array with Inf and Sup being the */
/* false if the value is not in the array with Inf and Sup being the */
/* indexes of the array values that are immediately below and over */
/* the not found value. This enables to restrict the array to the */
/* values that are between the min and max block values and to return */
@ -854,9 +854,9 @@ int ARRAY::BlockTest(PGLOBAL, int opc, int opm,
bool bin, bax, pin, pax, veq, all = (opm == 2);
if (Ndif == 0) // Array is empty
// Return TRUE for ALL because it means that there are no item that
// Return true for ALL because it means that there are no item that
// does not verify the condition, which is true indeed.
// Return FALSE for ANY because TRUE means that there is at least
// Return false for ANY because true means that there is at least
// one item that verifies the condition, which is false.
return (all) ? 2 : -2;
else if (opc == OP_EQ && all && Ndif > 1)
@ -864,7 +864,7 @@ int ARRAY::BlockTest(PGLOBAL, int opc, int opm,
else if (opc == OP_NE && !all && Ndif > 1)
return 2;
// else if (Ndif == 1)
// all = FALSE;
// all = false;
// veq is true when all values in the block are equal
switch (Type) {
@ -874,7 +874,7 @@ int ARRAY::BlockTest(PGLOBAL, int opc, int opm,
case TYPE_SHORT: veq = *(short*)minp == *(short*)maxp; break;
case TYPE_INT: veq = *(int*)minp == *(int*)maxp; break;
case TYPE_DOUBLE: veq = *(double*)minp == *(double*)maxp; break;
default: veq = FALSE; // Error ?
default: veq = false; // Error ?
} // endswitch type
if (!s)
@ -898,7 +898,7 @@ int ARRAY::BlockTest(PGLOBAL, int opc, int opm,
case OP_GT: return -1; break;
} // endswitch opc
pax = (opc == OP_GE) ? (X < Ndif - 1) : TRUE;
pax = (opc == OP_GE) ? (X < Ndif - 1) : true;
} else if (Inf == Bot) {
// Max value is smaller than min list value
return (opc == OP_LT || opc == OP_LE || opc == OP_NE) ? 1 : -1;
@ -924,7 +924,7 @@ int ARRAY::BlockTest(PGLOBAL, int opc, int opm,
case OP_LT: return (s) ? -2 : -1; break;
} // endswitch opc
pin = (opc == OP_LE) ? (X > 0) : TRUE;
pin = (opc == OP_LE) ? (X > 0) : true;
} else if (Sup == Ndif) {
// Min value is greater than max list value
if (opc == OP_GT || opc == OP_GE || opc == OP_NE)
@ -956,7 +956,7 @@ int ARRAY::BlockTest(PGLOBAL, int opc, int opm,
// the only possible overlaps between the array and the block are:
// Array: +-------+ +-------+ +-------+ +-----+
// Block: +-----+ +---+ +------+ +--------+
// TRUE: pax pin pax pin
// true: pax pin pax pin
if (all) switch (opc) {
case OP_GT:
case OP_GE: return (pax) ? -1 : 0; break;
@ -1052,7 +1052,7 @@ void ARRAY::Print(PGLOBAL, char *ps, uint z)
/***********************************************************************/
/* MULAR public constructor. */
/***********************************************************************/
MULAR::MULAR(PGLOBAL g, int n) : CSORT(FALSE)
MULAR::MULAR(PGLOBAL g, int n) : CSORT(false)
{
Narray = n;
Pars = (PARRAY*)PlugSubAlloc(g, NULL, n * sizeof(PARRAY));
@ -1075,7 +1075,7 @@ int MULAR::Qcompare(int *i1, int *i2)
/***********************************************************************/
/* Sort and eliminate distinct values from multiple arrays. */
/* Note: this is done by making a sorted index on distinct values. */
/* Returns FALSE if Ok or TRUE in case of error. */
/* Returns false if Ok or true in case of error. */
/***********************************************************************/
bool MULAR::Sort(PGLOBAL g)
{
@ -1087,7 +1087,7 @@ bool MULAR::Sort(PGLOBAL g)
for (n = 1; n < Narray; n++)
if (Pars[n]->Nval != nval) {
strcpy(g->Message, MSG(BAD_ARRAY_VAL));
return TRUE;
return true;
} // endif nval
// Prepare non conservative sort with offet values
@ -1161,10 +1161,10 @@ bool MULAR::Sort(PGLOBAL g)
Pars[n]->Top = ndif; // Find searches the whole array.
} // endfor n
return FALSE;
return false;
error:
PlgDBfree(Index);
PlgDBfree(Offset);
return TRUE;
return true;
} // end of Sort

View file

@ -1,7 +1,7 @@
/**************** Array H Declares Source Code File (.H) ***************/
/* Name: ARRAY.H Version 3.1 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2005-2014 */
/* (C) Copyright to the author Olivier BERTRAND 2005-2017 */
/* */
/* This file contains the ARRAY and VALBASE derived classes declares. */
/***********************************************************************/
@ -53,8 +53,8 @@ class DllExport ARRAY : public XOBJECT, public CSORT { // Array descblock
using XOBJECT::GetIntValue;
virtual void Reset(void) {Bot = -1;}
virtual int Qcompare(int *, int *);
virtual bool Compare(PXOB) {assert(FALSE); return FALSE;}
virtual bool SetFormat(PGLOBAL, FORMAT&) {assert(FALSE); return FALSE;}
virtual bool Compare(PXOB) {assert(false); return false;}
virtual bool SetFormat(PGLOBAL, FORMAT&) {assert(false); return false;}
//virtual int CheckSpcCol(PTDB, int) {return 0;}
virtual void Print(PGLOBAL g, FILE *f, uint n);
virtual void Print(PGLOBAL g, char *ps, uint z);

View file

@ -1,7 +1,7 @@
/************* Colblk C++ Functions Source Code File (.CPP) ************/
/* Name: COLBLK.CPP Version 2.1 */
/* Name: COLBLK.CPP Version 2.2 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 1998-2015 */
/* (C) Copyright to the author Olivier BERTRAND 1998-2017 */
/* */
/* This file contains the COLBLK class functions. */
/***********************************************************************/
@ -300,7 +300,7 @@ FIDBLK::FIDBLK(PCOLUMN cp, OPVAL op) : SPCBLK(cp), Op(op)
#if defined(__WIN__)
Format.Prec = 1; // Case insensitive
#endif // __WIN__
Constant = (!((PTDBASE)To_Tdb)->GetDef()->GetMultiple() &&
Constant = (!To_Tdb->GetDef()->GetMultiple() &&
To_Tdb->GetAmType() != TYPE_AM_PLG &&
To_Tdb->GetAmType() != TYPE_AM_PLM);
Fn = NULL;
@ -312,11 +312,11 @@ FIDBLK::FIDBLK(PCOLUMN cp, OPVAL op) : SPCBLK(cp), Op(op)
/***********************************************************************/
void FIDBLK::ReadColumn(PGLOBAL g)
{
if (Fn != ((PTDBASE)To_Tdb)->GetFile(g)) {
if (Fn != To_Tdb->GetFile(g)) {
char filename[_MAX_PATH];
Fn = ((PTDBASE)To_Tdb)->GetFile(g);
PlugSetPath(filename, Fn, ((PTDBASE)To_Tdb)->GetPath());
Fn = To_Tdb->GetFile(g);
PlugSetPath(filename, Fn, To_Tdb->GetPath());
if (Op != OP_XX) {
char buff[_MAX_PATH];
@ -378,10 +378,8 @@ void PRTBLK::ReadColumn(PGLOBAL g)
{
if (Pname == NULL) {
char *p;
PTDBASE tdbp = (PTDBASE)To_Tdb;
Pname = tdbp->GetDef()->GetStringCatInfo(g, "partname", "?");
Pname = To_Tdb->GetDef()->GetStringCatInfo(g, "partname", "?");
p = strrchr(Pname, '#');
Value->SetValue_psz((p) ? p + 1 : Pname);
} // endif Pname

View file

@ -159,7 +159,7 @@ bool CntCheckDB(PGLOBAL g, PHC handler, const char *pathname)
bool CntInfo(PGLOBAL g, PTDB tp, PXF info)
{
if (tp) {
bool b = ((PTDBASE)tp)->GetFtype() == RECFM_NAF;
bool b = (tp->GetFtype() == RECFM_NAF);
PTDBDOS tdbp = b ? NULL : (PTDBDOS)tp;
info->data_file_length = (b) ? 0 : (ulonglong)tdbp->GetFileLength(g);
@ -331,9 +331,9 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
} // endfor colp
// Attach the updated columns list to the main table
((PTDBASE)tdbp)->SetSetCols(utp->GetColumns());
tdbp->SetSetCols(utp->GetColumns());
} else if (tdbp && mode == MODE_INSERT)
((PTDBASE)tdbp)->SetSetCols(tdbp->GetColumns());
tdbp->SetSetCols(tdbp->GetColumns());
// Now do open the physical table
if (trace)
@ -342,7 +342,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
//tdbp->SetMode(mode);
if (del/* && ((PTDBASE)tdbp)->GetFtype() != RECFM_NAF*/) {
if (del/* && (tdbp->GetFtype() != RECFM_NAF*/) {
// To avoid erasing the table when doing a partial delete
// make a fake Next
// PDOSDEF ddp= new(g) DOSDEF;
@ -435,7 +435,7 @@ RCODE CntReadNext(PGLOBAL g, PTDB tdbp)
if (!tdbp)
return RC_FX;
else if (((PTDBASE)tdbp)->GetKindex()) {
else if (tdbp->GetKindex()) {
// Reading sequencially an indexed table. This happens after the
// handler function records_in_range was called and MySQL decides
// to quit using the index (!!!) Drop the index.
@ -482,7 +482,7 @@ RCODE CntWriteRow(PGLOBAL g, PTDB tdbp)
{
RCODE rc;
PCOL colp;
PTDBASE tp= (PTDBASE)tdbp;
//PTDBASE tp= (PTDBASE)tdbp;
if (!tdbp)
return RC_FX;
@ -500,13 +500,13 @@ RCODE CntWriteRow(PGLOBAL g, PTDB tdbp)
} // endif rc
// Store column values in table write buffer(s)
for (colp= tp->GetSetCols(); colp; colp= colp->GetNext())
for (colp= tdbp->GetSetCols(); colp; colp= colp->GetNext())
if (!colp->GetColUse(U_VIRTUAL))
colp->WriteColumn(g);
if (tp->IsIndexed())
if (tdbp->IsIndexed())
// Index values must be sorted before updating
rc= (RCODE)((PTDBDOS)tp)->GetTxfp()->StoreValues(g, true);
rc= (RCODE)((PTDBDOS)tdbp)->GetTxfp()->StoreValues(g, true);
else
// Return result code from write operation
rc= (RCODE)tdbp->WriteDB(g);
@ -534,7 +534,7 @@ RCODE CntUpdateRow(PGLOBAL g, PTDB tdbp)
RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all)
{
RCODE rc;
PTDBASE tp= (PTDBASE)tdbp;
//PTDBASE tp= (PTDBASE)tdbp;
if (!tdbp || tdbp->GetMode() != MODE_DELETE)
return RC_FX;
@ -542,16 +542,16 @@ RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all)
return RC_NF;
if (all) {
if (((PTDBASE)tdbp)->GetDef()->Indexable())
if (tdbp->GetDef()->Indexable())
((PTDBDOS)tdbp)->Cardinal= 0;
// Note: if all, this call will be done when closing the table
rc= (RCODE)tdbp->DeleteDB(g, RC_FX);
//} else if (tp->GetKindex() && !tp->GetKindex()->IsSorted() &&
// tp->Txfp->GetAmType() != TYPE_AM_DBF) {
} else if(tp->IsIndexed()) {
//} else if (tdbp->GetKindex() && !((PTDBASE)tdbp)->GetKindex()->IsSorted() &&
// ((PTDBASE)tdbp)->Txfp->GetAmType() != TYPE_AM_DBF) {
} else if(tdbp->IsIndexed()) {
// Index values must be sorted before updating
rc= (RCODE)((PTDBDOS)tp)->GetTxfp()->StoreValues(g, false);
rc= (RCODE)((PTDBDOS)tdbp)->GetTxfp()->StoreValues(g, false);
} else // Return result code from delete operation
rc= (RCODE)tdbp->DeleteDB(g, RC_OK);
@ -564,7 +564,7 @@ RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all)
int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
{
int rc= RC_OK;
TDBASE *tbxp= (PTDBASE)tdbp;
//TDBASE *tbxp= (PTDBASE)tdbp;
if (!tdbp)
return rc; // Nothing to do
@ -580,13 +580,13 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
tdbp, tdbp->GetMode(), nox, abort);
if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN) {
if (tbxp->IsIndexed())
if (tdbp->IsIndexed())
rc= ((PTDBDOS)tdbp)->GetTxfp()->DeleteSortedRows(g);
if (!rc)
rc= tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine
} else if (tbxp->GetMode() == MODE_UPDATE && tbxp->IsIndexed())
} else if (tdbp->GetMode() == MODE_UPDATE && tdbp->IsIndexed())
rc= ((PTDBDOX)tdbp)->Txfp->UpdateSortedRows(g);
switch(rc) {
@ -594,7 +594,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
abort= true;
break;
case RC_INFO:
PushWarning(g, tbxp);
PushWarning(g, tdbp);
break;
} // endswitch rc
@ -630,11 +630,13 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
if (trace > 1)
printf("About to reset opt\n");
// Make all the eventual indexes
tbxp= (TDBDOX*)tdbp;
tbxp->ResetKindex(g, NULL);
tbxp->SetKey_Col(NULL);
rc= tbxp->ResetTableOpt(g, true, tbxp->GetDef()->Indexable() == 1);
if (!tdbp->IsRemote()) {
// Make all the eventual indexes
PTDBDOX tbxp = (PTDBDOX)tdbp;
tbxp->ResetKindex(g, NULL);
tbxp->SetKey_Col(NULL);
rc = tbxp->ResetTableOpt(g, true, tbxp->GetDef()->Indexable() == 1);
} // endif remote
err:
if (trace > 1)
@ -656,10 +658,10 @@ int CntIndexInit(PGLOBAL g, PTDB ptdb, int id, bool sorted)
if (!ptdb)
return -1;
else if (!((PTDBASE)ptdb)->GetDef()->Indexable()) {
else if (!ptdb->GetDef()->Indexable()) {
sprintf(g->Message, MSG(TABLE_NO_INDEX), ptdb->GetName());
return 0;
} else if (((PTDBASE)ptdb)->GetDef()->Indexable() == 3) {
} else if (ptdb->GetDef()->Indexable() == 3) {
return 1;
} else
tdbp= (PTDBDOX)ptdb;
@ -744,7 +746,7 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
if (!ptdb)
return RC_FX;
else
x= ((PTDBASE)ptdb)->GetDef()->Indexable();
x= ptdb->GetDef()->Indexable();
if (!x) {
sprintf(g->Message, MSG(TABLE_NO_INDEX), ptdb->GetName());
@ -874,7 +876,7 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
if (!ptdb)
return -1;
x= ((PTDBASE)ptdb)->GetDef()->Indexable();
x= ptdb->GetDef()->Indexable();
if (!x) {
sprintf(g->Message, MSG(TABLE_NO_INDEX), ptdb->GetName());

View file

@ -5,7 +5,7 @@
/* */
/* COPYRIGHT: */
/* ---------- */
/* (C) Copyright to the author Olivier BERTRAND 2005-2015 */
/* (C) Copyright to the author Olivier BERTRAND 2005-2017 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@ -593,6 +593,7 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
if (Accept) {
Lrecl = reclen;
Blksize = Nrec * Lrecl;
PushWarning(g, Tdbp);
} else
return true;
@ -609,7 +610,7 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
header->Filedate[1] = datm->tm_mon + 1;
header->Filedate[2] = datm->tm_mday;
header->SetHeadlen((ushort)hlen);
header->SetReclen((ushort)reclen);
header->SetReclen(reclen);
descp = (DESCRIPTOR*)header;
// Currently only standard Xbase types are supported
@ -675,6 +676,7 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
if (Accept) {
Lrecl = header.Reclen();
Blksize = Nrec * Lrecl;
PushWarning(g, Tdbp);
} else
return true;
@ -967,6 +969,7 @@ int DBMFAM::Cardinality(PGLOBAL g)
if (Accept) {
Lrecl = rln;
Blksize = Nrec * Lrecl;
PushWarning(g, Tdbp);
} else
return -1;
@ -1019,6 +1022,7 @@ bool DBMFAM::AllocateBuffer(PGLOBAL g)
if (Accept) {
Lrecl = hp->Reclen();
Blksize = Nrec * Lrecl;
PushWarning(g, Tdbp);
} else
return true;

View file

@ -125,6 +125,8 @@
#endif // UNIX
#include "global.h"
#include "plgdbsem.h"
#include "xtable.h"
#include "tabext.h"
#if defined(ODBC_SUPPORT)
#include "odbccat.h"
#endif // ODBC_SUPPORT
@ -132,12 +134,11 @@
#include "tabjdbc.h"
#include "jdbconn.h"
#endif // JDBC_SUPPORT
#include "xtable.h"
#include "tabmysql.h"
#include "filamdbf.h"
#include "tabxcl.h"
#include "tabfmt.h"
#include "reldef.h"
//#include "reldef.h"
#include "tabcol.h"
#include "xindex.h"
#if defined(__WIN__)
@ -557,7 +558,7 @@ ha_create_table_option connect_index_option_list[]=
/***********************************************************************/
/* Push G->Message as a MySQL warning. */
/***********************************************************************/
bool PushWarning(PGLOBAL g, PTDBASE tdbp, int level)
bool PushWarning(PGLOBAL g, PTDB tdbp, int level)
{
PHC phc;
THD *thd;
@ -1025,7 +1026,7 @@ char *GetListOption(PGLOBAL g, const char *opname,
char key[16], val[256];
char *pk, *pv, *pn;
char *opval= (char*) def;
char *opval= (char*)def;
int n;
for (pk= (char*)oplist; pk; pk= ++pn) {
@ -1033,26 +1034,17 @@ char *GetListOption(PGLOBAL g, const char *opname,
pv= strchr(pk, '=');
if (pv && (!pn || pv < pn)) {
n= pv - pk;
n= MY_MIN(pv - pk, sizeof(key) - 1);
memcpy(key, pk, n);
key[n]= 0;
pv++;
if (pn) {
n= pn - pv;
memcpy(val, pv, n);
val[n]= 0;
} else
strcpy(val, pv);
n= MY_MIN((pn ? pn - pv : strlen(pv)), sizeof(val) - 1);
memcpy(val, pv, n);
val[n]= 0;
} else {
if (pn) {
n= MY_MIN(pn - pk, 15);
memcpy(key, pk, n);
key[n]= 0;
} else
strcpy(key, pk);
n= MY_MIN((pn ? pn - pk : strlen(pk)), sizeof(key) - 1);
memcpy(key, pk, n);
key[n]= 0;
val[0]= 0;
} // endif pv
@ -1106,7 +1098,7 @@ char *GetStringTableOption(PGLOBAL g, PTOS options, char *opname, char *sdef)
else if (!stricmp(opname, "Data_charset"))
opval= options->data_charset;
if (!opval && options && options->oplist)
if (!opval && options->oplist)
opval= GetListOption(g, opname, options->oplist);
return opval ? (char*)opval : sdef;
@ -2114,7 +2106,7 @@ int ha_connect::ScanRecord(PGLOBAL g, uchar *)
PCOL colp;
PVAL value, sdvalin;
Field *fp;
PTDBASE tp= (PTDBASE)tdbp;
//PTDBASE tp= (PTDBASE)tdbp;
String attribute(attr_buffer, sizeof(attr_buffer),
table->s->table_charset);
my_bitmap_map *bmap= dbug_tmp_use_all_columns(table, table->read_set);
@ -2133,7 +2125,7 @@ int ha_connect::ScanRecord(PGLOBAL g, uchar *)
&& tdbp->GetAmType() != TYPE_AM_ODBC
&& tdbp->GetAmType() != TYPE_AM_JDBC) ||
bitmap_is_set(table->write_set, fp->field_index)) {
for (colp= tp->GetSetCols(); colp; colp= colp->GetNext())
for (colp= tdbp->GetSetCols(); colp; colp= colp->GetNext())
if (!stricmp(colp->GetName(), fp->field_name))
break;
@ -2220,7 +2212,7 @@ int ha_connect::ScanRecord(PGLOBAL g, uchar *)
} else if (xmod == MODE_UPDATE) {
PCOL cp;
for (cp= tp->GetColumns(); cp; cp= cp->GetNext())
for (cp= tdbp->GetColumns(); cp; cp= cp->GetNext())
if (!stricmp(colp->GetName(), cp->GetName()))
break;
@ -2687,7 +2679,8 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
{
AMT tty = filp->Type;
char *body= filp->Body;
unsigned int i;
char *havg= filp->Having;
unsigned int i;
bool ismul= false, x= (tty == TYPE_AM_MYX || tty == TYPE_AM_XDBC);
bool nonul= ((tty == TYPE_AM_ODBC || tty == TYPE_AM_JDBC) &&
(tdbp->GetMode() == MODE_INSERT || tdbp->GetMode() == MODE_DELETE));
@ -2700,7 +2693,8 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
htrc("Cond type=%d\n", cond->type());
if (cond->type() == COND::COND_ITEM) {
char *p1, *p2;
char *pb0, *pb1, *pb2, *ph0, *ph1, *ph2;
bool bb = false, bh = false;
Item_cond *cond_item= (Item_cond *)cond;
if (x)
@ -2720,38 +2714,78 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
List_iterator<Item> li(*arglist);
const Item *subitem;
p1= body + strlen(body);
strcpy(p1, "(");
p2= p1 + 1;
pb0= pb1= body + strlen(body);
strcpy(pb0, "(");
pb2= pb1 + 1;
if (havg) {
ph0= ph1= havg + strlen(havg);
strcpy(ph0, "(");
ph2= ph1 + 1;
} // endif havg
for (i= 0; i < arglist->elements; i++)
if ((subitem= li++)) {
if (!CheckCond(g, filp, subitem)) {
if (vop == OP_OR || nonul)
return NULL;
else
*p2= 0;
else {
*pb2= 0;
if (havg) *ph2= 0;
} // endelse
} else {
p1= p2 + strlen(p2);
strcpy(p1, GetValStr(vop, false));
p2= p1 + strlen(p1);
if (filp->Bd) {
pb1= pb2 + strlen(pb2);
strcpy(pb1, GetValStr(vop, false));
pb2= pb1 + strlen(pb1);
} // endif Bd
if (filp->Hv) {
ph1= ph2 + strlen(ph2);
strcpy(ph1, GetValStr(vop, false));
ph2= ph1 + strlen(ph1);
} // endif Hv
} // endif CheckCond
bb |= filp->Bd;
bh |= filp->Hv;
filp->Bd = filp->Hv = false;
} else
return NULL;
if (*p1 != '(')
strcpy(p1, ")");
else
return NULL;
if (bb) {
strcpy(pb1, ")");
filp->Bd = bb;
} else
*pb0= 0;
if (havg) {
if (bb && bh && vop == OP_OR) {
// Cannot or'ed a where clause with a having clause
bb= bh= 0;
*pb0 = 0;
*ph0 = 0;
} else if (bh) {
strcpy(ph1, ")");
filp->Hv= bh;
} else
*ph0 = 0;
} // endif havg
if (!bb && !bh)
return NULL;
} else if (cond->type() == COND::FUNC_ITEM) {
unsigned int i;
bool iscol, neg= FALSE;
bool iscol, ishav= false, neg= false;
Item_func *condf= (Item_func *)cond;
Item* *args= condf->arguments();
filp->Bd = filp->Hv = false;
if (trace)
htrc("Func type=%d argnum=%d\n", condf->functype(),
condf->argument_count());
@ -2800,8 +2834,9 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
ha_field_option_struct *fop;
Item_field *pField= (Item_field *)args[i];
if (x && i)
return NULL;
// IN and BETWEEN clauses should be col VOP list
if (i && (x || ismul))
return NULL; // IN and BETWEEN clauses should be col VOP list
else if (pField->field->table != table)
return NULL; // Field does not belong to this table
else if (tty != TYPE_AM_WMI && IsIndexed(pField->field))
@ -2817,10 +2852,19 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
else
return NULL;
} else if (tty == TYPE_AM_TBL)
return NULL;
else
fnm= pField->field->field_name;
} else if (tty == TYPE_AM_TBL) {
return NULL;
} else {
bool h;
fnm = filp->Chk(pField->field->field_name, &h);
if (h && i && !ishav)
return NULL; // Having should be col VOP arg
else
ishav = h;
} // endif's
if (trace) {
htrc("Field index=%d\n", pField->field->field_index);
@ -2829,11 +2873,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
htrc("Field_type=%d\n", args[i]->field_type());
} // endif trace
// IN and BETWEEN clauses should be col VOP list
if (i && ismul)
return NULL;
strcat(body, fnm);
strcat((ishav ? havg : body), fnm);
} else if (args[i]->type() == COND::FUNC_ITEM) {
if (tty == TYPE_AM_MYSQL) {
if (!CheckCond(g, filp, args[i]))
@ -2872,32 +2912,34 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
return NULL;
if (!x) {
char *s = (ishav) ? havg : body;
// Append the value to the filter
switch (args[i]->field_type()) {
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATETIME:
if (tty == TYPE_AM_ODBC) {
strcat(body, "{ts '");
strncat(body, res->ptr(), res->length());
strcat(s, "{ts '");
strncat(s, res->ptr(), res->length());
if (res->length() < 19)
strcat(body, "1970-01-01 00:00:00" + res->length());
strcat(s, "1970-01-01 00:00:00" + res->length());
strcat(body, "'}");
strcat(s, "'}");
break;
} // endif ODBC
case MYSQL_TYPE_DATE:
if (tty == TYPE_AM_ODBC) {
strcat(body, "{d '");
strcat(strncat(body, res->ptr(), res->length()), "'}");
strcat(s, "{d '");
strcat(strncat(s, res->ptr(), res->length()), "'}");
break;
} // endif ODBC
case MYSQL_TYPE_TIME:
if (tty == TYPE_AM_ODBC) {
strcat(body, "{t '");
strcat(strncat(body, res->ptr(), res->length()), "'}");
strcat(s, "{t '");
strcat(strncat(s, res->ptr(), res->length()), "'}");
break;
} // endif ODBC
@ -2906,39 +2948,39 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
switch (args[0]->field_type()) {
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATETIME:
strcat(body, "{ts '");
strncat(body, res->ptr(), res->length());
strcat(s, "{ts '");
strncat(s, res->ptr(), res->length());
if (res->length() < 19)
strcat(body, "1970-01-01 00:00:00" + res->length());
strcat(s, "1970-01-01 00:00:00" + res->length());
strcat(body, "'}");
strcat(s, "'}");
break;
case MYSQL_TYPE_DATE:
strcat(body, "{d '");
strncat(body, res->ptr(), res->length());
strcat(body, "'}");
strcat(s, "{d '");
strncat(s, res->ptr(), res->length());
strcat(s, "'}");
break;
case MYSQL_TYPE_TIME:
strcat(body, "{t '");
strncat(body, res->ptr(), res->length());
strcat(body, "'}");
strcat(s, "{t '");
strncat(s, res->ptr(), res->length());
strcat(s, "'}");
break;
default:
strcat(body, "'");
strncat(body, res->ptr(), res->length());
strcat(body, "'");
strcat(s, "'");
strncat(s, res->ptr(), res->length());
strcat(s, "'");
} // endswitch field type
} else {
strcat(body, "'");
strncat(body, res->ptr(), res->length());
strcat(body, "'");
strcat(s, "'");
strncat(s, res->ptr(), res->length());
strcat(s, "'");
} // endif tty
break;
default:
strncat(body, res->ptr(), res->length());
strncat(s, res->ptr(), res->length());
} // endswitch field type
} else {
@ -2954,22 +2996,28 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
} // endif x
} // endif
} // endif's Type
if (!x) {
if (!i)
strcat(body, GetValStr(vop, neg));
char *s = (ishav) ? havg : body;
if (!i)
strcat(s, GetValStr(vop, neg));
else if (vop == OP_XX && i == 1)
strcat(body, " AND ");
strcat(s, " AND ");
else if (vop == OP_IN)
strcat(body, (i == condf->argument_count() - 1) ? ")" : ",");
strcat(s, (i == condf->argument_count() - 1) ? ")" : ",");
} // endif x
} // endfor i
if (x)
filp->Op= vop;
if (x)
filp->Op = vop;
else if (ishav)
filp->Hv = true;
else
filp->Bd = true;
} else {
if (trace)
@ -3026,16 +3074,28 @@ const COND *ha_connect::cond_push(const COND *cond)
if (b) {
PCFIL filp;
int rc;
if ((filp= tdbp->GetCondFil()) && filp->Cond == cond &&
filp->Idx == active_index && filp->Type == tty)
goto fin; // Already done
filp= new(g) CONDFIL(cond, active_index, tty);
filp->Body= (char*)PlugSubAlloc(g, NULL, (x) ? 128 : 0);
*filp->Body= 0;
rc = filp->Init(g, this);
if (rc == RC_INFO) {
filp->Having = (char*)PlugSubAlloc(g, NULL, 256);
*filp->Having = 0;
} else if (rc == RC_FX)
goto fin;
filp->Body = (char*)PlugSubAlloc(g, NULL, (x) ? 128 : 0);
*filp->Body = 0;
if (CheckCond(g, filp, cond)) {
if (filp->Having && strlen(filp->Having) > 255)
goto fin; // Memory collapse
if (trace)
htrc("cond_push: %s\n", filp->Body);
@ -3208,9 +3268,9 @@ int ha_connect::optimize(THD* thd, HA_CHECK_OPT*)
tdbp= GetTDB(g);
dup->Check |= CHK_OPT;
if (tdbp) {
if (tdbp && !tdbp->IsRemote()) {
bool dop= IsTypeIndexable(GetRealType(NULL));
bool dox= (((PTDBASE)tdbp)->GetDef()->Indexable() == 1);
bool dox= (tdbp->GetDef()->Indexable() == 1);
if ((rc= ((PTDBASE)tdbp)->ResetTableOpt(g, dop, dox))) {
if (rc == RC_INFO) {
@ -3221,7 +3281,7 @@ int ha_connect::optimize(THD* thd, HA_CHECK_OPT*)
} // endif rc
} else
} else if (!tdbp)
rc= HA_ERR_INTERNAL_ERROR;
return rc;
@ -3464,9 +3524,9 @@ int ha_connect::index_init(uint idx, bool sorted)
htrc("index_init CONNECT: %s\n", g->Message);
active_index= MAX_KEY;
rc= HA_ERR_INTERNAL_ERROR;
} else if (((PTDBDOX)tdbp)->To_Kindex) {
} else if (tdbp->GetKindex()) {
if (((PTDBDOX)tdbp)->To_Kindex->GetNum_K()) {
if (((PTDBASE)tdbp)->GetFtype() != RECFM_NAF)
if (tdbp->GetFtype() != RECFM_NAF)
((PTDBDOX)tdbp)->GetTxfp()->ResetBuffer(g);
active_index= idx;
@ -3880,11 +3940,10 @@ int ha_connect::rnd_next(uchar *buf)
void ha_connect::position(const uchar *)
{
DBUG_ENTER("ha_connect::position");
//if (((PTDBASE)tdbp)->GetDef()->Indexable())
my_store_ptr(ref, ref_length, (my_off_t)((PTDBASE)tdbp)->GetRecpos());
my_store_ptr(ref, ref_length, (my_off_t)tdbp->GetRecpos());
if (trace > 1)
htrc("position: pos=%d\n", ((PTDBASE)tdbp)->GetRecpos());
htrc("position: pos=%d\n", tdbp->GetRecpos());
DBUG_VOID_RETURN;
} // end of position
@ -3909,14 +3968,14 @@ void ha_connect::position(const uchar *)
int ha_connect::rnd_pos(uchar *buf, uchar *pos)
{
int rc;
PTDBASE tp= (PTDBASE)tdbp;
//PTDBASE tp= (PTDBASE)tdbp;
DBUG_ENTER("ha_connect::rnd_pos");
if (!tp->SetRecpos(xp->g, (int)my_get_ptr(pos, ref_length))) {
if (!tdbp->SetRecpos(xp->g, (int)my_get_ptr(pos, ref_length))) {
if (trace)
htrc("rnd_pos: %d\n", tp->GetRecpos());
htrc("rnd_pos: %d\n", tdbp->GetRecpos());
tp->SetFilter(NULL);
tdbp->SetFilter(NULL);
rc= rnd_next(buf);
} else
rc= HA_ERR_KEY_NOT_FOUND;
@ -4094,7 +4153,7 @@ int ha_connect::delete_all_rows()
if (tdbp && tdbp->GetUse() == USE_OPEN &&
tdbp->GetAmType() != TYPE_AM_XML &&
((PTDBASE)tdbp)->GetFtype() != RECFM_NAF)
tdbp->GetFtype() != RECFM_NAF)
// Close and reopen the table so it will be deleted
rc= CloseTable(g);
@ -4472,12 +4531,12 @@ int ha_connect::external_lock(THD *thd, int lock_type)
if (!tdbp) {
if (!(tdbp= GetTDB(g)))
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
else if (!((PTDBASE)tdbp)->GetDef()->Indexable()) {
else if (!tdbp->GetDef()->Indexable()) {
sprintf(g->Message, "external_lock: Table %s is not indexable", tdbp->GetName());
// DBUG_RETURN(HA_ERR_INTERNAL_ERROR); causes assert error
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
DBUG_RETURN(0);
} else if (((PTDBASE)tdbp)->GetDef()->Indexable() == 1) {
} else if (tdbp->GetDef()->Indexable() == 1) {
bool oldsep= ((PCHK)g->Xchk)->oldsep;
bool newsep= ((PCHK)g->Xchk)->newsep;
PTDBDOS tdp= (PTDBDOS)tdbp;
@ -4558,7 +4617,7 @@ int ha_connect::external_lock(THD *thd, int lock_type)
rc= 0;
} // endif MakeIndex
} else if (((PTDBASE)tdbp)->GetDef()->Indexable() == 3) {
} else if (tdbp->GetDef()->Indexable() == 3) {
if (CheckVirtualIndex(NULL)) {
// Make it a warning to avoid crash
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
@ -5425,8 +5484,8 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
if (mydef->GetPassword())
pwd= mydef->GetPassword();
if (mydef->GetDatabase())
db= mydef->GetDatabase();
if (mydef->GetTabschema())
db = mydef->GetTabschema();
if (mydef->GetTabname())
tab= mydef->GetTabname();
@ -6052,8 +6111,8 @@ int ha_connect::create(const char *name, TABLE *table_arg,
if (mydef->GetHostname())
host= mydef->GetHostname();
if (mydef->GetDatabase())
db= mydef->GetDatabase();
if (mydef->GetTabschema())
db = mydef->GetTabschema();
if (mydef->GetTabname())
tab= mydef->GetTabname();

View file

@ -1,7 +1,7 @@
/************ Jdbconn C++ Functions Source Code File (.CPP) ************/
/* Name: JDBCONN.CPP Version 1.0 */
/* Name: JDBCONN.CPP Version 1.1 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2016 */
/* (C) Copyright to the author Olivier BERTRAND 2016-2017 */
/* */
/* This file contains the JDBC connection classes functions. */
/***********************************************************************/
@ -45,9 +45,9 @@
#include "plgdbsem.h"
#include "xobject.h"
#include "xtable.h"
#include "tabext.h"
#include "tabjdbc.h"
//#include "jdbconn.h"
//#include "plgcnx.h" // For DB types
#include "resource.h"
#include "valblk.h"
#include "osutil.h"
@ -318,13 +318,21 @@ PQRYRES JDBCColumns(PGLOBAL g, char *db, char *table, char *colpat,
/**************************************************************************/
PQRYRES JDBCSrcCols(PGLOBAL g, char *src, PJPARM sjp)
{
char *sqry;
PQRYRES qrp;
JDBConn *jcp = new(g)JDBConn(g, NULL);
if (jcp->Open(sjp))
return NULL;
qrp = jcp->GetMetaData(g, src);
if (strstr(src, "%s")) {
// Place holder for an eventual where clause
sqry = (char*)PlugSubAlloc(g, NULL, strlen(src) + 2);
sprintf(sqry, src, "1=1"); // dummy where clause
} else
sqry = src;
qrp = jcp->GetMetaData(g, sqry);
jcp->Close();
return qrp;
} // end of JDBCSrcCols

View file

@ -1,6 +1,6 @@
/****************** jsonudf C++ Program Source Code File (.CPP) ******************/
/* PROGRAM NAME: jsonudf Version 1.4 */
/* (C) Copyright to the author Olivier BERTRAND 2015-2016 */
/* PROGRAM NAME: jsonudf Version 1.5 */
/* (C) Copyright to the author Olivier BERTRAND 2015-2017 */
/* This program are the JSON User Defined Functions . */
/*********************************************************************************/
@ -242,13 +242,16 @@ my_bool JSNX::ParseJpath(PGLOBAL g)
// Jpath = Name;
return true;
pbuf = PlugDup(g, Jpath);
if (!(pbuf = PlgDBDup(g, Jpath)))
return true;
// The Jpath must be analyzed
for (i = 0, p = pbuf; (p = strchr(p, ':')); i++, p++)
Nod++; // One path node found
Nodes = (PJNODE)PlugSubAlloc(g, NULL, (++Nod) * sizeof(JNODE));
if (!(Nodes = (PJNODE)PlgDBSubAlloc(g, NULL, (++Nod) * sizeof(JNODE))))
return true;
memset(Nodes, 0, (Nod)* sizeof(JNODE));
// Analyze the Jpath for this column
@ -1086,9 +1089,10 @@ inline void JsonFreeMem(PGLOBAL g)
/*********************************************************************************/
static my_bool JsonInit(UDF_INIT *initid, UDF_ARGS *args,
char *message, my_bool mbn,
unsigned long reslen, unsigned long memlen)
unsigned long reslen, unsigned long memlen,
unsigned long more = 0)
{
PGLOBAL g = PlugInit(NULL, memlen);
PGLOBAL g = PlugInit(NULL, memlen + more);
if (!g) {
strcpy(message, "Allocation error");
@ -1100,6 +1104,7 @@ static my_bool JsonInit(UDF_INIT *initid, UDF_ARGS *args,
} // endif g
g->Mrr = (args->arg_count && args->args[0]) ? 1 : 0;
g->ActivityStart = (PACTIVITY)more;
initid->maybe_null = mbn;
initid->max_length = reslen;
initid->ptr = (char*)g;
@ -1444,6 +1449,8 @@ static my_bool CheckMemory(PGLOBAL g, UDF_INIT *initid, UDF_ARGS *args, uint n,
} // endif b
ml += (unsigned long)g->ActivityStart; // more
if (ml > g->Sarea_Size) {
free(g->Sarea);
@ -2758,7 +2765,7 @@ void json_item_merge_deinit(UDF_INIT* initid)
/*********************************************************************************/
my_bool json_get_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen;
unsigned long reslen, memlen, more;
int n = IsJson(args, 0);
if (args->arg_count < 2) {
@ -2767,7 +2774,7 @@ my_bool json_get_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
} else if (!n && args->arg_type[0] != STRING_RESULT) {
strcpy(message, "First argument must be a json item");
return true;
} else if (args->arg_type[1] != STRING_RESULT) {
} else if (args->arg_type[1] != STRING_RESULT) {
strcpy(message, "Second argument is not a string (jpath)");
return true;
} else
@ -2780,11 +2787,13 @@ my_bool json_get_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
memcpy(fn, args->args[0], args->lengths[0]);
fn[args->lengths[0]] = 0;
fl = GetFileLength(fn);
memlen += fl * 3;
} else if (n != 3)
memlen += args->lengths[0] * 3;
more = fl * 3;
} else if (n != 3) {
more = args->lengths[0] * 3;
} else
more = 0;
return JsonInit(initid, args, message, true, reslen, memlen);
return JsonInit(initid, args, message, true, reslen, memlen, more);
} // end of json_get_item_init
char *json_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
@ -2885,7 +2894,7 @@ my_bool jsonget_string_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
} // endif's
CalcLen(args, false, reslen, memlen);
memlen += more;
//memlen += more;
if (n == 2 && args->args[0]) {
char fn[_MAX_PATH];
@ -2894,11 +2903,11 @@ my_bool jsonget_string_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
memcpy(fn, args->args[0], args->lengths[0]);
fn[args->lengths[0]] = 0;
fl = GetFileLength(fn);
memlen += fl * 3;
more += fl * 3;
} else if (n != 3)
memlen += args->lengths[0] * 3;
more += args->lengths[0] * 3;
return JsonInit(initid, args, message, true, reslen, memlen);
return JsonInit(initid, args, message, true, reslen, memlen, more);
} // end of jsonget_string_init
char *jsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result,
@ -2994,7 +3003,7 @@ void jsonget_string_deinit(UDF_INIT* initid)
/*********************************************************************************/
my_bool jsonget_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen;
unsigned long reslen, memlen, more;
if (args->arg_count != 2) {
strcpy(message, "This function must have 2 arguments");
@ -3008,10 +3017,10 @@ my_bool jsonget_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
} else
CalcLen(args, false, reslen, memlen);
if (IsJson(args, 0) != 3)
memlen += 1000; // TODO: calculate this
// TODO: calculate this
more = (IsJson(args, 0) != 3) ? 1000 : 0;
return JsonInit(initid, args, message, true, reslen, memlen);
return JsonInit(initid, args, message, true, reslen, memlen, more);
} // end of jsonget_int_init
long long jsonget_int(UDF_INIT *initid, UDF_ARGS *args,
@ -3100,7 +3109,7 @@ void jsonget_int_deinit(UDF_INIT* initid)
/*********************************************************************************/
my_bool jsonget_real_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen;
unsigned long reslen, memlen, more;
if (args->arg_count < 2) {
strcpy(message, "At least 2 arguments required");
@ -3123,10 +3132,10 @@ my_bool jsonget_real_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
CalcLen(args, false, reslen, memlen);
if (IsJson(args, 0) != 3)
memlen += 1000; // TODO: calculate this
// TODO: calculate this
more = (IsJson(args, 0) != 3) ? 1000 : 0;
return JsonInit(initid, args, message, true, reslen, memlen);
return JsonInit(initid, args, message, true, reslen, memlen, more);
} // end of jsonget_real_init
double jsonget_real(UDF_INIT *initid, UDF_ARGS *args,
@ -3234,10 +3243,11 @@ my_bool jsonlocate_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
CalcLen(args, false, reslen, memlen);
if (IsJson(args, 0) != 3)
memlen += more; // TODO: calculate this
// TODO: calculate this
if (IsJson(args, 0) == 3)
more = 0;
return JsonInit(initid, args, message, true, reslen, memlen);
return JsonInit(initid, args, message, true, reslen, memlen, more);
} // end of jsonlocate_init
char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result,
@ -3358,10 +3368,11 @@ my_bool json_locate_all_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
CalcLen(args, false, reslen, memlen);
if (IsJson(args, 0) != 3)
memlen += more; // TODO: calculate this
// TODO: calculate this
if (IsJson(args, 0) == 3)
more = 0;
return JsonInit(initid, args, message, true, reslen, memlen);
return JsonInit(initid, args, message, true, reslen, memlen, more);
} // end of json_locate_all_init
char *json_locate_all(UDF_INIT *initid, UDF_ARGS *args, char *result,
@ -3485,12 +3496,12 @@ my_bool jsoncontains_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
} // endif's
CalcLen(args, false, reslen, memlen);
memlen += more;
//memlen += more;
if (IsJson(args, 0) != 3)
memlen += 1000; // TODO: calculate this
// TODO: calculate this
more += (IsJson(args, 0) != 3 ? 1000 : 0);
return JsonInit(initid, args, message, false, reslen, memlen);
return JsonInit(initid, args, message, false, reslen, memlen, more);
} // end of jsoncontains_init
long long jsoncontains(UDF_INIT *initid, UDF_ARGS *args, char *result,
@ -3537,12 +3548,12 @@ my_bool jsoncontains_path_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
} // endif's
CalcLen(args, false, reslen, memlen);
memlen += more;
//memlen += more;
if (IsJson(args, 0) != 3)
memlen += 1000; // TODO: calculate this
// TODO: calculate this
more += (IsJson(args, 0) != 3 ? 1000 : 0);
return JsonInit(initid, args, message, true, reslen, memlen);
return JsonInit(initid, args, message, true, reslen, memlen, more);
} // end of jsoncontains_path_init
long long jsoncontains_path(UDF_INIT *initid, UDF_ARGS *args, char *result,
@ -3736,7 +3747,7 @@ fin:
/*********************************************************************************/
my_bool json_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen;
unsigned long reslen, memlen, more = 0;
int n = IsJson(args, 0);
if (!(args->arg_count % 2)) {
@ -3755,11 +3766,11 @@ my_bool json_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
memcpy(fn, args->args[0], args->lengths[0]);
fn[args->lengths[0]] = 0;
fl = GetFileLength(fn);
memlen += fl * 3;
more += fl * 3;
} else if (n != 3)
memlen += args->lengths[0] * 3;
more += args->lengths[0] * 3;
if (!JsonInit(initid, args, message, true, reslen, memlen)) {
if (!JsonInit(initid, args, message, true, reslen, memlen, more)) {
PGLOBAL g = (PGLOBAL)initid->ptr;
// This is a constant function
@ -3954,7 +3965,7 @@ void json_file_deinit(UDF_INIT* initid)
/*********************************************************************************/
my_bool jfile_make_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen, more = 1024;
unsigned long reslen, memlen;
if (args->arg_count < 1 || args->arg_count > 3) {
strcpy(message, "Wrong number of arguments");
@ -4993,7 +5004,7 @@ fin:
/*********************************************************************************/
my_bool jbin_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen;
unsigned long reslen, memlen, more = 0;
int n = IsJson(args, 0);
if (!(args->arg_count % 2)) {
@ -5012,11 +5023,11 @@ my_bool jbin_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
memcpy(fn, args->args[0], args->lengths[0]);
fn[args->lengths[0]] = 0;
fl = GetFileLength(fn);
memlen += fl * 3;
more = fl * 3;
} else if (n != 3)
memlen += args->lengths[0] * 3;
more = args->lengths[0] * 3;
return JsonInit(initid, args, message, true, reslen, memlen);
return JsonInit(initid, args, message, true, reslen, memlen, more);
} // end of jbin_set_item_init
char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
@ -5104,8 +5115,8 @@ my_bool jbin_file_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
fl = GetFileLength(args->args[0]);
reslen += fl;
more += fl * M;
memlen += more;
return JsonInit(initid, args, message, true, reslen, memlen);
//memlen += more;
return JsonInit(initid, args, message, true, reslen, memlen, more);
} // end of jbin_file_init
char *jbin_file(UDF_INIT *initid, UDF_ARGS *args, char *result,

View file

@ -1,4 +1,4 @@
/* Copyright (C) Olivier Bertrand 2004 - 2016
/* Copyright (C) Olivier Bertrand 2004 - 2017
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -16,9 +16,9 @@
/*************** Mycat CC Program Source Code File (.CC) ***************/
/* PROGRAM NAME: MYCAT */
/* ------------- */
/* Version 1.5 */
/* Version 1.6 */
/* */
/* Author: Olivier Bertrand 2012 - 2016 */
/* Author: Olivier Bertrand 2012 - 2017 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@ -58,9 +58,10 @@
#endif // UNIX
#include "global.h"
#include "plgdbsem.h"
#include "reldef.h"
#include "tabcol.h"
//#include "reldef.h"
#include "xtable.h"
#include "tabext.h"
#include "tabcol.h"
#include "filamtxt.h"
#include "tabdos.h"
#include "tabfmt.h"
@ -559,13 +560,13 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am)
case TAB_XML: tdp= new(g) XMLDEF; break;
#endif // XML_SUPPORT
#if defined(VCT_SUPPORT)
case TAB_VEC: tdp = new(g)VCTDEF; break;
case TAB_VEC: tdp = new(g) VCTDEF; break;
#endif // VCT_SUPPORT
#if defined(ODBC_SUPPORT)
case TAB_ODBC: tdp= new(g) ODBCDEF; break;
#endif // ODBC_SUPPORT
#if defined(JDBC_SUPPORT)
case TAB_JDBC: tdp= new(g)JDBCDEF; break;
case TAB_JDBC: tdp= new(g) JDBCDEF; break;
#endif // JDBC_SUPPORT
#if defined(__WIN__)
case TAB_MAC: tdp= new(g) MACDEF; break;

View file

@ -1,11 +1,11 @@
/************** MyConn C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: MYCONN */
/* ------------- */
/* Version 1.8 */
/* Version 1.9 */
/* */
/* COPYRIGHT: */
/* ---------- */
/* (C) Copyright to the author Olivier BERTRAND 2007-2016 */
/* (C) Copyright to the author Olivier BERTRAND 2007-2017 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@ -375,10 +375,18 @@ PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db,
if (!port)
port = mysqld_port;
if (!strnicmp(srcdef, "select ", 7)) {
query = (char *)PlugSubAlloc(g, NULL, strlen(srcdef) + 9);
strcat(strcpy(query, srcdef), " LIMIT 0");
} else
if (!strnicmp(srcdef, "select ", 7) || strstr(srcdef, "%s")) {
query = (char *)PlugSubAlloc(g, NULL, strlen(srcdef) + 10);
if (strstr(srcdef, "%s"))
sprintf(query, srcdef, "1=1"); // dummy where clause
else
strcpy(query, srcdef);
if (!strnicmp(srcdef, "select ", 7))
strcat(query, " LIMIT 0");
} else
query = (char *)srcdef;
// Open a MySQL connection for this table

View file

@ -35,8 +35,8 @@
#include "global.h"
#include "plgdbsem.h"
#include "xobject.h"
//#include "kindex.h"
#include "xtable.h"
#include "tabext.h"
#include "odbccat.h"
#include "tabodbc.h"
#include "plgcnx.h" // For DB types
@ -413,12 +413,20 @@ PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *db, char *table,
/**************************************************************************/
PQRYRES ODBCSrcCols(PGLOBAL g, char *dsn, char *src, POPARM sop)
{
char *sqry;
ODBConn *ocp = new(g) ODBConn(g, NULL);
if (ocp->Open(dsn, sop, 10) < 1) // openReadOnly + noOdbcDialog
return NULL;
return ocp->GetMetaData(g, dsn, src);
if (strstr(src, "%s")) {
// Place holder for an eventual where clause
sqry = (char*)PlugSubAlloc(g, NULL, strlen(src) + 3);
sprintf(sqry, src, "1=1", "1=1"); // dummy where clause
} else
sqry = src;
return ocp->GetMetaData(g, dsn, sqry);
} // end of ODBCSrcCols
#if 0
@ -1417,7 +1425,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols)
b = true;
if (trace)
htrc("ExecDirect hstmt=%p %.64s\n", hstmt, sql);
htrc("ExecDirect hstmt=%p %.256s\n", hstmt, sql);
if (m_Tdb->Srcdef) {
// Be sure this is a query returning a result set

View file

@ -1,7 +1,7 @@
/************** PlgDBSem H Declares Source Code File (.H) **************/
/* Name: PLGDBSEM.H Version 3.7 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 1998-2016 */
/* (C) Copyright to the author Olivier BERTRAND 1998-2017 */
/* */
/* This file contains the CONNECT storage engine definitions. */
/***********************************************************************/
@ -57,7 +57,7 @@ enum TABTYPE {TAB_UNDEF = 0, /* Table of undefined type */
TAB_FIX = 2, /* Fixed column offset, fixed LRECL */
TAB_BIN = 3, /* Like FIX but can have binary fields */
TAB_CSV = 4, /* DOS files with CSV records */
TAB_FMT = 5, /* DOS files with formatted recordss */
TAB_FMT = 5, /* DOS files with formatted records */
TAB_DBF = 6, /* DBF Dbase or Foxpro files */
TAB_XML = 7, /* XML or HTML files */
TAB_INI = 8, /* INI or CFG files */
@ -212,11 +212,24 @@ enum OPVAL {OP_EQ = 1, /* Filtering operator = */
OP_SUB = 17, /* Expression Substract operator */
OP_MULT = 18, /* Expression Multiply operator */
OP_DIV = 19, /* Expression Divide operator */
OP_NOP = 21, /* Scalar function is nopped */
OP_NUM = 22, /* Scalar function Op Num */
OP_ABS = 23, /* Scalar function Op Abs */
OP_MAX = 24, /* Scalar function Op Max */
OP_MIN = 25, /* Scalar function Op Min */
OP_EXP = 36, /* Scalar function Op Exp */
OP_FDISK = 94, /* Operator Disk of fileid */
OP_FPATH = 95, /* Operator Path of fileid */
OP_FNAME = 96, /* Operator Name of fileid */
OP_FTYPE = 97, /* Operator Type of fileid */
OP_LAST = 82, /* Index operator Find Last */
OP_FIRST = 106, /* Index operator Find First */
OP_NEXT = 107, /* Index operator Find Next */
OP_SAME = 108, /* Index operator Find Next Same */
OP_FSTDIF = 109, /* Index operator Find First dif */
OP_NXTDIF = 110, /* Index operator Find Next dif */
OP_PREV = 116}; /* Index operator Find Previous */
#if 0
OP_NOP = 21, /* Scalar function is nopped */
OP_ABS = 23, /* Scalar function Op Abs */
OP_CEIL = 26, /* Scalar function Op Ceil */
OP_FLOOR = 27, /* Scalar function Op Floor */
OP_MOD = 28, /* Scalar function Op Mod */
@ -312,6 +325,7 @@ enum OPVAL {OP_EQ = 1, /* Filtering operator = */
OP_REMOVE = 201, /* Scalar function Op Remove */
OP_RENAME = 202, /* Scalar function Op Rename */
OP_FCOMP = 203}; /* Scalar function Op Compare */
#endif // 0
enum TUSE {USE_NO = 0, /* Table is not yet linearized */
USE_LIN = 1, /* Table is linearized */
@ -356,6 +370,7 @@ typedef class XOBJECT *PXOB;
typedef class COLBLK *PCOL;
typedef class TDB *PTDB;
typedef class TDBASE *PTDBASE;
typedef class TDBEXT *PTDBEXT;
typedef class TDBDOS *PTDBDOS;
typedef class TDBFIX *PTDBFIX;
typedef class TDBFMT *PTDBFMT;
@ -374,6 +389,7 @@ typedef class KXYCOL *PXCOL;
typedef class CATALOG *PCATLG;
typedef class RELDEF *PRELDEF;
typedef class TABDEF *PTABDEF;
typedef class EXTDEF *PEXTBDEF;
typedef class DOSDEF *PDOSDEF;
typedef class CSVDEF *PCSVDEF;
typedef class VCTDEF *PVCTDEF;
@ -619,4 +635,4 @@ int global_open(GLOBAL *g, int msgid, const char *filename, int flags, int mode)
DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR name, LPCSTR dir);
char *MakeEscape(PGLOBAL g, char* str, char q);
DllExport bool PushWarning(PGLOBAL, PTDBASE, int level = 1);
DllExport bool PushWarning(PGLOBAL, PTDB, int level = 1);

View file

@ -621,8 +621,8 @@ bool OEMDEF::DefineAM(PGLOBAL g, LPCSTR, int)
/***********************************************************************/
PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode)
{
RECFM rfm;
PTDBASE tdbp = NULL;
RECFM rfm;
PTDB tdbp = NULL;
// If define block not here yet, get it now
if (!Pxdef && !(Pxdef = GetXdef(g)))
@ -632,7 +632,7 @@ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode)
/* Allocate a TDB of the proper type. */
/* Column blocks will be allocated only when needed. */
/*********************************************************************/
if (!(tdbp = (PTDBASE)Pxdef->GetTable(g, mode)))
if (!(tdbp = Pxdef->GetTable(g, mode)))
return NULL;
else
rfm = tdbp->GetFtype();

View file

@ -64,15 +64,16 @@ class DllExport RELDEF : public BLOCK { // Relation definition block
}; // end of RELDEF
/***********************************************************************/
/* These classes correspond to the data base description contained in */
/* a .XDB file the A.M. DOS, FIX, CSV, MAP, BIN, VCT, PLG, ODBC, DOM. */
/* This class corresponds to the data base description for tables */
/* of type DOS, FIX, CSV, DBF, BIN, VCT, JSON, XML... */
/***********************************************************************/
class DllExport TABDEF : public RELDEF { /* Logical table descriptor */
friend class CATALOG;
friend class PLUGCAT;
friend class MYCAT;
friend class TDBASE;
public:
friend class TDB;
friend class TDBEXT;
public:
// Constructor
TABDEF(void); // Constructor
@ -112,11 +113,11 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */
int Sort; /* Table already sorted ??? */
int Multiple; /* 0: No 1: DIR 2: Section 3: filelist */
int Degree; /* Number of columns in the table */
int Pseudo; /* Bit: 1 ROWID Ok, 2 FILEID Ok */
int Pseudo; /* Bit: 1 ROWID }Ok, 2 FILEID Ok */
bool Read_Only; /* true for read only tables */
const CHARSET_INFO *m_data_charset;
const char *csname; /* Table charset name */
}; // end of TABDEF
}; // end of TABDEF
/***********************************************************************/
/* Externally defined OEM tables. */
@ -190,11 +191,12 @@ class DllExport COLCRT : public BLOCK { /* Column description block
/***********************************************************************/
/* Column definition block. */
/***********************************************************************/
class DllExport COLDEF : public COLCRT { /* Column description block */
class DllExport COLDEF : public COLCRT { /* Column description block */
friend class TABDEF;
friend class COLBLK;
friend class DBFFAM;
friend class TDBASE;
friend class TDB;
friend class TDBASE;
friend class TDBDOS;
public:
COLDEF(void); // Constructor

View file

@ -504,7 +504,7 @@ TDBDOS::TDBDOS(PGLOBAL g, PTDBDOS tdbp) : TDBASE(tdbp)
} // end of TDBDOS copy constructor
// Method
PTDB TDBDOS::CopyOne(PTABS t)
PTDB TDBDOS::Clone(PTABS t)
{
PTDB tp;
PDOSCOL cp1, cp2;
@ -518,7 +518,7 @@ PTDB TDBDOS::CopyOne(PTABS t)
} // endfor cp1
return tp;
} // end of CopyOne
} // end of Clone
/***********************************************************************/
/* Allocate DOS column description block. */

View file

@ -142,7 +142,7 @@ class DllExport TDBDOS : public TDBASE {
{return (PTDB)new(g) TDBDOS(g, this);}
// Methods
virtual PTDB CopyOne(PTABS t);
virtual PTDB Clone(PTABS t);
virtual void ResetDB(void) {Txfp->Reset();}
virtual bool IsUsingTemp(PGLOBAL g);
virtual bool IsIndexed(void) {return Indxd;}

636
storage/connect/tabext.cpp Normal file
View file

@ -0,0 +1,636 @@
/************* Tabext C++ Functions Source Code File (.CPP) ************/
/* Name: TABEXT.CPP Version 1.0 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2017 */
/* */
/* This file contains the TBX, TDB and OPJOIN classes functions. */
/***********************************************************************/
/***********************************************************************/
/* Include relevant MariaDB header file. */
/***********************************************************************/
#define MYSQL_SERVER 1
#include "my_global.h"
#include "sql_class.h"
#include "sql_servers.h"
#include "sql_string.h"
/***********************************************************************/
/* Include required application header files */
/* global.h is header containing all global Plug declarations. */
/* plgdbsem.h is header containing the DB applic. declarations. */
/* xobject.h is header containing XOBJECT derived classes declares. */
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
#include "xtable.h"
#include "tabext.h"
#include "ha_connect.h"
/* -------------------------- Class CONDFIL -------------------------- */
/***********************************************************************/
/* CONDFIL Constructor. */
/***********************************************************************/
CONDFIL::CONDFIL(const Item *cond, uint idx, AMT type)
{
Cond = cond;
Idx = idx;
Type = type;
Op = OP_XX;
Cmds = NULL;
Alist = NULL;
All = true;
Bd = false;
Hv = false;
Body = NULL,
Having = NULL;
} // end of CONDFIL constructor
/***********************************************************************/
/* Make and allocate the alias list. */
/***********************************************************************/
int CONDFIL::Init(PGLOBAL g, PHC hc)
{
PTOS options = hc->GetTableOptionStruct();
char *p, *cn, *cal, *alt = NULL;
int rc = RC_OK;
bool h;
if (options)
alt = GetListOption(g, "Alias", options->oplist, NULL);
while (alt) {
if (!(p = strchr(alt, '='))) {
strcpy(g->Message, "Invalid alias list");
rc = RC_FX;
break;
} // endif !p
cal = alt; // Alias
*p++ = 0;
if ((h = *p == '*')) {
rc = RC_INFO;
p++;
} // endif h
cn = p; // Remote column name
if ((alt = strchr(p, ';')))
*alt++ = 0;
if (*cn == 0)
cn = alt;
Alist = new(g) ALIAS(Alist, cn, cal, h);
} // endwhile alt
return rc;
} // end of Init
/***********************************************************************/
/* Make and allocate the alias list. */
/***********************************************************************/
const char *CONDFIL::Chk(const char *fln, bool *h)
{
for (PAL pal = Alist; pal; pal = pal->Next)
if (!stricmp(fln, pal->Alias)) {
*h = pal->Having;
return pal->Name;
} // endif fln
*h = false;
return fln;
} // end of Chk
/* --------------------------- Class EXTDEF -------------------------- */
/***********************************************************************/
/* EXTDEF Constructor. */
/***********************************************************************/
EXTDEF::EXTDEF(void)
{
Tabname = Tabschema = Username = Password = Tabcat = Tabtyp = NULL;
Colpat = Srcdef = Qchar = Qrystr = Sep = Phpos = NULL;
Options = Cto = Qto = Quoted = Maxerr = Maxres = Memory = 0;
Scrollable = Xsrc = false;
} // end of EXTDEF constructor
/***********************************************************************/
/* DefineAM: define specific AM block values from XDB file. */
/***********************************************************************/
bool EXTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
Desc = NULL;
Tabname = GetStringCatInfo(g, "Name",
(Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
Tabname = GetStringCatInfo(g, "Tabname", Tabname);
Tabschema = GetStringCatInfo(g, "Dbname", NULL);
Tabschema = GetStringCatInfo(g, "Schema", Tabschema);
Tabcat = GetStringCatInfo(g, "Qualifier", NULL);
Tabcat = GetStringCatInfo(g, "Catalog", Tabcat);
Username = GetStringCatInfo(g, "User", NULL);
Password = GetStringCatInfo(g, "Password", NULL);
if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL)))
Read_Only = true;
Qrystr = GetStringCatInfo(g, "Query_String", "?");
Sep = GetStringCatInfo(g, "Separator", NULL);
//Alias = GetStringCatInfo(g, "Alias", NULL);
Phpos = GetStringCatInfo(g, "Phpos", NULL);
Xsrc = GetBoolCatInfo("Execsrc", FALSE);
Maxerr = GetIntCatInfo("Maxerr", 0);
Maxres = GetIntCatInfo("Maxres", 0);
Quoted = GetIntCatInfo("Quoted", 0);
Options = 0;
Cto = 0;
Qto = 0;
if ((Scrollable = GetBoolCatInfo("Scrollable", false)) && !Elemt)
Elemt = 1; // Cannot merge SQLFetch and SQLExtendedFetch
if (Catfunc == FNC_COL)
Colpat = GetStringCatInfo(g, "Colpat", NULL);
if (Catfunc == FNC_TABLE)
Tabtyp = GetStringCatInfo(g, "Tabtype", NULL);
// Memory was Boolean, it is now integer
if (!(Memory = GetIntCatInfo("Memory", 0)))
Memory = GetBoolCatInfo("Memory", false) ? 1 : 0;
Pseudo = 2; // FILID is Ok but not ROWID
return false;
} // end of DefineAM
/* ---------------------------TDBEXT class --------------------------- */
/***********************************************************************/
/* Implementation of the TDBEXT class. */
/***********************************************************************/
TDBEXT::TDBEXT(EXTDEF *tdp) : TDB(tdp)
{
Qrp = NULL;
if (tdp) {
TableName = tdp->Tabname;
Schema = tdp->Tabschema;
User = tdp->Username;
Pwd = tdp->Password;
Catalog = tdp->Tabcat;
Srcdef = tdp->Srcdef;
Qrystr = tdp->Qrystr;
Sep = tdp->GetSep();
Options = tdp->Options;
Cto = tdp->Cto;
Qto = tdp->Qto;
Quoted = MY_MAX(0, tdp->GetQuoted());
Rows = tdp->GetElemt();
Memory = tdp->Memory;
Scrollable = tdp->Scrollable;
} else {
TableName = NULL;
Schema = NULL;
User = NULL;
Pwd = NULL;
Catalog = NULL;
Srcdef = NULL;
Qrystr = NULL;
Sep = 0;
Options = 0;
Cto = 0;
Qto = 0;
Quoted = 0;
Rows = 0;
Memory = 0;
Scrollable = false;
} // endif tdp
Quote = NULL;
Query = NULL;
Count = NULL;
//Where = NULL;
MulConn = NULL;
DBQ = NULL;
Qrp = NULL;
Fpos = 0;
Curpos = 0;
AftRows = 0;
CurNum = 0;
Rbuf = 0;
BufSize = 0;
Nparm = 0;
Ncol = 0;
Placed = false;
} // end of TDBEXT constructor
TDBEXT::TDBEXT(PTDBEXT tdbp) : TDB(tdbp)
{
Qrp = tdbp->Qrp;
TableName = tdbp->TableName;
Schema = tdbp->Schema;
User = tdbp->User;
Pwd = tdbp->Pwd;
Catalog = tdbp->Catalog;
Srcdef = tdbp->Srcdef;
Qrystr = tdbp->Qrystr;
Sep = tdbp->Sep;
Options = tdbp->Options;
Cto = tdbp->Cto;
Qto = tdbp->Qto;
Quoted = tdbp->Quoted;
Rows = tdbp->Rows;
Memory = tdbp->Memory;
Scrollable = tdbp->Scrollable;
Quote = tdbp->Quote;
Query = tdbp->Query;
Count = tdbp->Count;
//Where = tdbp->Where;
MulConn = tdbp->MulConn;
DBQ = tdbp->DBQ;
Fpos = 0;
Curpos = 0;
AftRows = 0;
CurNum = 0;
Rbuf = 0;
BufSize = tdbp->BufSize;
Nparm = tdbp->Nparm;
Ncol = tdbp->Ncol;
Placed = false;
} // end of TDBEXT copy constructor
/******************************************************************/
/* Convert an UTF-8 string to latin characters. */
/******************************************************************/
int TDBEXT::Decode(char *txt, char *buf, size_t n)
{
uint dummy_errors;
uint32 len = copy_and_convert(buf, n, &my_charset_latin1,
txt, strlen(txt),
&my_charset_utf8_general_ci,
&dummy_errors);
buf[len] = '\0';
return 0;
} // end of Decode
/***********************************************************************/
/* MakeSQL: make the SQL statement use with remote connection. */
/* TODO: when implementing remote filtering, column only used in */
/* local filter should be removed from column list. */
/***********************************************************************/
bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
{
char *schmp = NULL, *catp = NULL, buf[NAM_LEN * 3];
int len;
bool oom = false, first = true;
PTABLE tablep = To_Table;
PCOL colp;
if (Srcdef) {
if ((catp = strstr(Srcdef, "%s"))) {
char *fil1, *fil2;
PSZ ph = ((EXTDEF*)To_Def)->Phpos;
if (!ph)
ph = (strstr(catp + 2, "%s")) ? "WH" : "W";
if (stricmp(ph, "H")) {
fil1 = (To_CondFil && *To_CondFil->Body)
? To_CondFil->Body : PlugDup(g, "1=1");
} // endif ph
if (stricmp(ph, "W")) {
fil2 = (To_CondFil && To_CondFil->Having && *To_CondFil->Having)
? To_CondFil->Having : PlugDup(g, "1=1");
} // endif ph
if (!stricmp(ph, "W")) {
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1));
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil1));
} else if (!stricmp(ph, "WH")) {
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1) + strlen(fil2));
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil1, fil2));
} else if (!stricmp(ph, "H")) {
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil2));
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil2));
} else if (!stricmp(ph, "HW")) {
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1) + strlen(fil2));
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil2, fil1));
} else {
strcpy(g->Message, "MakeSQL: Wrong place holders specification");
return true;
} // endif's ph
} else
Query = new(g)STRING(g, 0, Srcdef);
return false;
} // endif Srcdef
// Allocate the string used to contain the Query
Query = new(g)STRING(g, 1023, "SELECT ");
if (!cnt) {
if (Columns) {
// Normal SQL statement to retrieve results
for (colp = Columns; colp; colp = colp->GetNext())
if (!colp->IsSpecial()) {
if (!first)
oom |= Query->Append(", ");
else
first = false;
// Column name can be encoded in UTF-8
Decode(colp->GetName(), buf, sizeof(buf));
if (Quote) {
// Put column name between identifier quotes in case in contains blanks
oom |= Query->Append(Quote);
oom |= Query->Append(buf);
oom |= Query->Append(Quote);
} else
oom |= Query->Append(buf);
((PEXTCOL)colp)->SetRank(++Ncol);
} // endif colp
} else
// !Columns can occur for queries such that sql count(*) from...
// for which we will count the rows from sql * from...
oom |= Query->Append('*');
} else
// SQL statement used to retrieve the size of the result
oom |= Query->Append("count(*)");
oom |= Query->Append(" FROM ");
if (Catalog && *Catalog)
catp = Catalog;
//if (tablep->GetSchema())
// schmp = (char*)tablep->GetSchema();
//else
if (Schema && *Schema)
schmp = Schema;
if (catp) {
oom |= Query->Append(catp);
if (schmp) {
oom |= Query->Append('.');
oom |= Query->Append(schmp);
} // endif schmp
oom |= Query->Append('.');
} else if (schmp) {
oom |= Query->Append(schmp);
oom |= Query->Append('.');
} // endif schmp
// Table name can be encoded in UTF-8
Decode(TableName, buf, sizeof(buf));
if (Quote) {
// Put table name between identifier quotes in case in contains blanks
oom |= Query->Append(Quote);
oom |= Query->Append(buf);
oom |= Query->Append(Quote);
} else
oom |= Query->Append(buf);
len = Query->GetLength();
if (To_CondFil) {
if (Mode == MODE_READ) {
oom |= Query->Append(" WHERE ");
oom |= Query->Append(To_CondFil->Body);
len = Query->GetLength() + 1;
} else
len += (strlen(To_CondFil->Body) + 256);
} else
len += ((Mode == MODE_READX) ? 256 : 1);
if (oom || Query->Resize(len)) {
strcpy(g->Message, "MakeSQL: Out of memory");
return true;
} // endif oom
if (trace)
htrc("Query=%s\n", Query->GetStr());
return false;
} // end of MakeSQL
/***********************************************************************/
/* MakeCommand: make the Update or Delete statement to send to the */
/* MySQL server. Limited to remote values and filtering. */
/***********************************************************************/
bool TDBEXT::MakeCommand(PGLOBAL g)
{
char *p, *stmt, name[68], *body = NULL;
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] == '`') ? *Quote : tolower(Qrystr[i]);
} while (Qrystr[i++]);
if (To_CondFil && (p = strstr(qrystr, " where "))) {
p[7] = 0; // Remove where clause
Qrystr[(p - qrystr) + 7] = 0;
body = To_CondFil->Body;
stmt = (char*)PlugSubAlloc(g, NULL, strlen(qrystr)
+ strlen(body) + 64);
} else
stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
// Check whether the table name is equal to a keyword
// If so, it must be quoted in the original query
strlwr(strcat(strcat(strcpy(name, " "), Name), " "));
if (strstr(" update delete low_priority ignore quick from ", name)) {
strlwr(strcat(strcat(strcpy(name, Quote), Name), Quote));
k += 2;
} else
strlwr(strcpy(name, Name)); // Not a keyword
if ((p = strstr(qrystr, name))) {
for (i = 0; i < p - qrystr; i++)
stmt[i] = (Qrystr[i] == '`') ? *Quote : Qrystr[i];
stmt[i] = 0;
k += i + (int)strlen(Name);
if (qtd && *(p - 1) == ' ')
strcat(strcat(strcat(stmt, Quote), TableName), Quote);
else
strcat(stmt, TableName);
i = (int)strlen(stmt);
do {
stmt[i++] = (Qrystr[k] == '`') ? *Quote : Qrystr[k];
} while (Qrystr[k++]);
if (body)
strcat(stmt, body);
} else {
sprintf(g->Message, "Cannot use this %s command",
(Mode == MODE_UPDATE) ? "UPDATE" : "DELETE");
return true;
} // endif p
if (trace)
htrc("Command=%s\n", stmt);
Query = new(g)STRING(g, 0, stmt);
return (!Query->GetSize());
} // end of MakeCommand
/***********************************************************************/
/* GetRecpos: return the position of last read record. */
/***********************************************************************/
int TDBEXT::GetRecpos(void)
{
return Fpos;
} // end of GetRecpos
/***********************************************************************/
/* ODBC GetMaxSize: returns table size estimate in number of lines. */
/***********************************************************************/
int TDBEXT::GetMaxSize(PGLOBAL g)
{
if (MaxSize < 0) {
if (Mode == MODE_DELETE)
// Return 0 in mode DELETE in case of delete all.
MaxSize = 0;
else if (!Cardinality(NULL))
MaxSize = 10; // To make MySQL happy
else if ((MaxSize = Cardinality(g)) < 0)
MaxSize = 12; // So we can see an error occurred
} // endif MaxSize
return MaxSize;
} // end of GetMaxSize
/***********************************************************************/
/* Return max size value. */
/***********************************************************************/
int TDBEXT::GetProgMax(PGLOBAL g)
{
return GetMaxSize(g);
} // end of GetProgMax
/* ---------------------------EXTCOL class --------------------------- */
/***********************************************************************/
/* EXTCOL public constructor. */
/***********************************************************************/
EXTCOL::EXTCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
: COLBLK(cdp, tdbp, i)
{
if (cprec) {
Next = cprec->GetNext();
cprec->SetNext(this);
} else {
Next = tdbp->GetColumns();
tdbp->SetColumns(this);
} // endif cprec
if (trace)
htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this);
// Set additional remote access method information for column.
Crp = NULL;
Long = Precision;
To_Val = NULL;
Bufp = NULL;
Blkp = NULL;
Rank = 0; // Not known yet
} // end of JDBCCOL constructor
/***********************************************************************/
/* EXTCOL private constructor. */
/***********************************************************************/
EXTCOL::EXTCOL(void) : COLBLK()
{
Crp = NULL;
Buf_Type = TYPE_INT; // This is a count(*) column
// Set additional Dos access method information for column.
Long = sizeof(int);
To_Val = NULL;
Bufp = NULL;
Blkp = NULL;
Rank = 1;
} // end of EXTCOL constructor
/***********************************************************************/
/* EXTCOL constructor used for copying columns. */
/* tdbp is the pointer to the new table descriptor. */
/***********************************************************************/
EXTCOL::EXTCOL(PEXTCOL col1, PTDB tdbp) : COLBLK(col1, tdbp)
{
Crp = col1->Crp;
Long = col1->Long;
To_Val = col1->To_Val;
Bufp = col1->Bufp;
Blkp = col1->Blkp;
Rank = col1->Rank;
} // end of JDBCCOL copy constructor
/***********************************************************************/
/* SetBuffer: prepare a column block for write operation. */
/***********************************************************************/
bool EXTCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
{
if (!(To_Val = value)) {
sprintf(g->Message, MSG(VALUE_ERROR), Name);
return true;
} else if (Buf_Type == value->GetType()) {
// Values are of the (good) column type
if (Buf_Type == TYPE_DATE) {
// If any of the date values is formatted
// output format must be set for the receiving table
if (GetDomain() || ((DTVAL *)value)->IsFormatted())
goto newval; // This will make a new value;
} else if (Buf_Type == TYPE_DOUBLE)
// Float values must be written with the correct (column) precision
// Note: maybe this should be forced by ShowValue instead of this ?
value->SetPrec(GetScale());
Value = value; // Directly access the external value
} else {
// Values are not of the (good) column type
if (check) {
sprintf(g->Message, MSG(TYPE_VALUE_ERR), Name,
GetTypeName(Buf_Type), GetTypeName(value->GetType()));
return true;
} // endif check
newval:
if (InitValue(g)) // Allocate the matching value block
return true;
} // endif's Value, Buf_Type
// Because Colblk's have been made from a copy of the original TDB in
// case of Update, we must reset them to point to the original one.
if (To_Tdb->GetOrig())
To_Tdb = (PTDB)To_Tdb->GetOrig();
// Set the Column
Status = (ok) ? BUF_EMPTY : BUF_NO;
return false;
} // end of SetBuffer

200
storage/connect/tabext.h Normal file
View file

@ -0,0 +1,200 @@
/*************** Tabext H Declares Source Code File (.H) ***************/
/* Name: TABEXT.H Version 1.0 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2017 */
/* */
/* This is the EXTDEF, TABEXT and EXTCOL classes definitions. */
/***********************************************************************/
#ifndef __TABEXT_H
#define __TABEXTF_H
#include "reldef.h"
typedef class ALIAS *PAL;
class ALIAS : public BLOCK {
public:
ALIAS(PAL x, PSZ n, PSZ a, bool h)
{Next = x, Name = n, Alias = a, Having = h;}
PAL Next;
PSZ Name;
PSZ Alias;
bool Having;
}; // end of class ALIAS
// Condition filter structure
class CONDFIL : public BLOCK {
public:
// Constructor
CONDFIL(const Item *cond, uint idx, AMT type);
// Functions
int Init(PGLOBAL g, PHC hc);
const char *Chk(const char *cln, bool *h);
// Members
const Item *Cond;
AMT Type;
uint Idx;
OPVAL Op;
PCMD Cmds;
PAL Alist;
bool All;
bool Bd;
bool Hv;
char *Body;
char *Having;
}; // end of class CONDFIL
/***********************************************************************/
/* This class corresponds to the data base description for external */
/* tables of type MYSQL, ODBC, JDBC... */
/***********************************************************************/
class DllExport EXTDEF : public TABDEF { /* EXT table */
friend TDBEXT;
public:
// Constructor
EXTDEF(void); // Constructor
// Implementation
virtual const char *GetType(void) { return "EXT"; }
inline PSZ GetTabname(void) { return Tabname; }
inline PSZ GetTabschema(void) { return Tabschema; }
inline PSZ GetUsername(void) { return Username; };
inline PSZ GetPassword(void) { return Password; };
inline PSZ GetTabcat(void) { return Tabcat; }
inline PSZ GetSrcdef(void) { return Srcdef; }
inline char GetSep(void) { return (Sep) ? *Sep : 0; }
inline int GetQuoted(void) { return Quoted; }
inline int GetOptions(void) { return Options; }
// Methods
virtual int Indexable(void) { return 2; }
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
protected:
// Members
PSZ Tabname; /* External table name */
PSZ Tabschema; /* External table schema */
PSZ Username; /* User connect name */
PSZ Password; /* Password connect info */
PSZ Tabcat; /* External table catalog */
PSZ Tabtyp; /* Catalog table type */
PSZ Colpat; /* Catalog column pattern */
PSZ Srcdef; /* The source table SQL definition */
PSZ Qchar; /* Identifier quoting character */
PSZ Qrystr; /* The original query */
PSZ Sep; /* Decimal separator */
//PSZ Alias; /* Column alias list */
PSZ Phpos; /* Place holer positions */
int Options; /* Open connection options */
int Cto; /* Open connection timeout */
int Qto; /* Query (command) timeout */
int Quoted; /* Identifier quoting level */
int Maxerr; /* Maxerr for an Exec table */
int Maxres; /* Maxres for a catalog table */
int Memory; /* Put result set in memory */
bool Scrollable; /* Use scrollable cursor */
bool Xsrc; /* Execution type */
}; // end of EXTDEF
/***********************************************************************/
/* This is the base class for all external tables. */
/***********************************************************************/
class DllExport TDBEXT : public TDB {
public:
// Constructors
TDBEXT(EXTDEF *tdp);
TDBEXT(PTDBEXT tdbp);
// Implementation
// Properties
virtual bool IsRemote(void) { return true; }
// Methods
virtual PSZ GetServer(void) { return "Remote"; }
virtual int GetRecpos(void);
// Database routines
virtual int GetMaxSize(PGLOBAL g);
virtual int GetProgMax(PGLOBAL g);
protected:
// Internal functions
virtual bool MakeSQL(PGLOBAL g, bool cnt);
//virtual bool MakeInsert(PGLOBAL g);
virtual bool MakeCommand(PGLOBAL g);
int Decode(char *utf, char *buf, size_t n);
// Members
PQRYRES Qrp; // Points to storage result
PSTRG Query; // Constructed SQL query
char *TableName; // Points to ODBC table name
char *Schema; // Points to ODBC table Schema
char *User; // User connect info
char *Pwd; // Password connect info
char *Catalog; // Points to ODBC table Catalog
char *Srcdef; // The source table SQL definition
char *Count; // Points to count(*) SQL statement
//char *Where; // Points to local where clause
char *Quote; // The identifier quoting character
char *MulConn; // Used for multiple ODBC tables
char *DBQ; // The address part of Connect string
char *Qrystr; // The original query
char Sep; // The decimal separator
int Options; // Connect options
int Cto; // Connect timeout
int Qto; // Query timeout
int Quoted; // The identifier quoting level
int Fpos; // Position of last read record
int Curpos; // Cursor position of last fetch
int AftRows; // The number of affected rows
int Rows; // Rowset size
int CurNum; // Current buffer line number
int Rbuf; // Number of lines read in buffer
int BufSize; // Size of connect string buffer
int Nparm; // The number of statement parameters
int Memory; // 0: No 1: Alloc 2: Put 3: Get
int Ncol; // The column number (JDBC)
bool Scrollable; // Use scrollable cursor
bool Placed; // True for position reading
}; // end of class TDBEXT
/***********************************************************************/
/* Virual class EXTCOL: external column. */
/***********************************************************************/
class DllExport EXTCOL : public COLBLK {
friend class TDBEXT;
public:
// Constructor
EXTCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am);
EXTCOL(PEXTCOL colp, PTDB tdbp); // Constructor used in copy process
// Implementation
inline int GetRank(void) { return Rank; }
inline void SetRank(int k) { Rank = k; }
//inline PVBLK GetBlkp(void) {return Blkp;}
inline void SetCrp(PCOLRES crp) { Crp = crp; }
// Methods
virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
virtual void ReadColumn(PGLOBAL) = 0;
virtual void WriteColumn(PGLOBAL) = 0;
protected:
// Constructor for count(*) column
EXTCOL(void);
// Members
PCOLRES Crp; // To storage result
void *Bufp; // To extended buffer
PVBLK Blkp; // To Value Block
PVAL To_Val; // To value used for Insert
int Rank; // Rank (position) number in the query
//int Flag; // ???
}; // end of class EXTCOL
#endif // __TABEXT_H

View file

@ -77,7 +77,7 @@ TDBFIX::TDBFIX(PGLOBAL g, PTDBFIX tdbp) : TDBDOS(g, tdbp)
} // end of TDBFIX copy constructor
// Method
PTDB TDBFIX::CopyOne(PTABS t)
PTDB TDBFIX::Clone(PTABS t)
{
PTDB tp;
PGLOBAL g = t->G;
@ -105,7 +105,7 @@ PTDB TDBFIX::CopyOne(PTABS t)
} // endif Ftype
return tp;
} // end of CopyOne
} // end of Clone
/***********************************************************************/
/* Reset read/write position values. */

View file

@ -34,7 +34,7 @@ class DllExport TDBFIX : public TDBDOS {
{return (PTDB)new(g) TDBFIX(g, this);}
// Methods
virtual PTDB CopyOne(PTABS t);
virtual PTDB Clone(PTABS t);
virtual void ResetDB(void);
virtual bool IsUsingTemp(PGLOBAL g);
virtual int RowNumber(PGLOBAL g, bool b = false);

View file

@ -661,7 +661,7 @@ TDBCSV::TDBCSV(PGLOBAL g, PTDBCSV tdbp) : TDBDOS(g, tdbp)
} // end of TDBCSV copy constructor
// Method
PTDB TDBCSV::CopyOne(PTABS t)
PTDB TDBCSV::Clone(PTABS t)
{
PTDB tp;
PCSVCOL cp1, cp2;
@ -675,7 +675,7 @@ PTDB TDBCSV::CopyOne(PTABS t)
} // endfor cp1
return tp;
} // end of CopyOne
} // end of Clone
/***********************************************************************/
/* Allocate CSV column description block. */
@ -1169,7 +1169,7 @@ TDBFMT::TDBFMT(PGLOBAL g, PTDBFMT tdbp) : TDBCSV(g, tdbp)
} // end of TDBFMT copy constructor
// Method
PTDB TDBFMT::CopyOne(PTABS t)
PTDB TDBFMT::Clone(PTABS t)
{
PTDB tp;
PCSVCOL cp1, cp2;
@ -1186,7 +1186,7 @@ PTDB TDBFMT::CopyOne(PTABS t)
} // endfor cp1
return tp;
} // end of CopyOne
} // end of Clone
/***********************************************************************/
/* Allocate FMT column description block. */

View file

@ -65,7 +65,7 @@ public:
{return (PTDB)new(g) TDBCSV(g, this);}
// Methods
virtual PTDB CopyOne(PTABS t);
virtual PTDB Clone(PTABS t);
//virtual bool IsUsingTemp(PGLOBAL g);
virtual int GetBadLines(void) {return (int)Nerr;}
@ -148,7 +148,7 @@ class DllExport TDBFMT : public TDBCSV {
{return (PTDB)new(g) TDBFMT(g, this);}
// Methods
virtual PTDB CopyOne(PTABS t);
virtual PTDB Clone(PTABS t);
// Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);

View file

@ -1,11 +1,11 @@
/************* TabJDBC C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: TABJDBC */
/* ------------- */
/* Version 1.1 */
/* Version 1.2 */
/* */
/* COPYRIGHT: */
/* ---------- */
/* (C) Copyright to the author Olivier BERTRAND 2016 */
/* (C) Copyright to the author Olivier BERTRAND 2016-2017 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@ -69,9 +69,10 @@
#include "plgdbsem.h"
#include "mycat.h"
#include "xtable.h"
#include "tabext.h"
#include "tabjdbc.h"
#include "tabmul.h"
#include "reldef.h"
//#include "reldef.h"
#include "tabcol.h"
#include "valblk.h"
#include "ha_connect.h"
@ -96,10 +97,7 @@ bool ExactInfo(void);
/***********************************************************************/
JDBCDEF::JDBCDEF(void)
{
Driver = Url = Wrapname =Tabname = Tabschema = Username = Colpat = NULL;
Password = Tabcat = Tabtype = Srcdef = Qchar = Qrystr = Sep = NULL;
Options = Quoted = Maxerr = Maxres = Memory = 0;
Scrollable = Xsrc = false;
Driver = Url = Wrapname = NULL;
} // end of JDBCDEF constructor
/***********************************************************************/
@ -134,23 +132,26 @@ bool JDBCDEF::SetParms(PJPARM sjp)
int JDBCDEF::ParseURL(PGLOBAL g, char *url, bool b)
{
if (strncmp(url, "jdbc:", 5)) {
PSZ p;
// No "jdbc:" in connection string. Must be a straight
// "server" or "server/table"
// ok, so we do a little parsing, but not completely!
if ((Tabname= strchr(url, '/'))) {
if ((p = strchr(url, '/'))) {
// If there is a single '/' in the connection string,
// this means the user is specifying a table name
*Tabname++= '\0';
*p++= '\0';
// there better not be any more '/'s !
if (strchr(Tabname, '/'))
if (strchr(p, '/'))
return RC_FX;
} else if (b) {
// Otherwise, straight server name,
Tabname = GetStringCatInfo(g, "Name", NULL);
Tabname = GetStringCatInfo(g, "Tabname", Tabname);
} // endelse
Tabname = p;
// } else if (b) {
// // Otherwise, straight server name,
// Tabname = GetStringCatInfo(g, "Name", NULL);
// Tabname = GetStringCatInfo(g, "Tabname", Tabname);
} // endif
if (trace)
htrc("server: %s Tabname: %s", url, Tabname);
@ -204,6 +205,9 @@ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
int rc = RC_OK;
if (EXTDEF::DefineAM(g, am, poff))
return true;
Driver = GetStringCatInfo(g, "Driver", NULL);
Desc = Url = GetStringCatInfo(g, "Connect", NULL);
@ -223,41 +227,41 @@ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
if (rc == RC_FX) // Error
return true;
else if (rc == RC_OK) { // Url was not a server name
Tabname = GetStringCatInfo(g, "Name",
(Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
Tabname = GetStringCatInfo(g, "Tabname", Tabname);
Username = GetStringCatInfo(g, "User", NULL);
Password = GetStringCatInfo(g, "Password", NULL);
} // endif rc
//else if (rc == RC_OK) { // Url was not a server name
// Tabname = GetStringCatInfo(g, "Name",
// (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
// Tabname = GetStringCatInfo(g, "Tabname", Tabname);
// Username = GetStringCatInfo(g, "User", NULL);
// Password = GetStringCatInfo(g, "Password", NULL);
//} // endif rc
if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL)))
Read_Only = true;
//if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL)))
// Read_Only = true;
Wrapname = GetStringCatInfo(g, "Wrapper", NULL);
//Prop = GetStringCatInfo(g, "Properties", NULL);
Tabcat = GetStringCatInfo(g, "Qualifier", NULL);
Tabcat = GetStringCatInfo(g, "Catalog", Tabcat);
Tabschema = GetStringCatInfo(g, "Dbname", NULL);
Tabschema = GetStringCatInfo(g, "Schema", Tabschema);
//Tabcat = GetStringCatInfo(g, "Qualifier", NULL);
//Tabcat = GetStringCatInfo(g, "Catalog", Tabcat);
//Tabschema = GetStringCatInfo(g, "Dbname", NULL);
//Tabschema = GetStringCatInfo(g, "Schema", Tabschema);
if (Catfunc == FNC_COL)
Colpat = GetStringCatInfo(g, "Colpat", NULL);
//if (Catfunc == FNC_COL)
// Colpat = GetStringCatInfo(g, "Colpat", NULL);
if (Catfunc == FNC_TABLE)
Tabtype = GetStringCatInfo(g, "Tabtype", NULL);
//if (Catfunc == FNC_TABLE)
// Tabtyp = GetStringCatInfo(g, "Tabtype", NULL);
Qrystr = GetStringCatInfo(g, "Query_String", "?");
Sep = GetStringCatInfo(g, "Separator", NULL);
Xsrc = GetBoolCatInfo("Execsrc", FALSE);
Maxerr = GetIntCatInfo("Maxerr", 0);
Maxres = GetIntCatInfo("Maxres", 0);
Quoted = GetIntCatInfo("Quoted", 0);
//Cto= GetIntCatInfo("ConnectTimeout", DEFAULT_LOGIN_TIMEOUT);
//Qto= GetIntCatInfo("QueryTimeout", DEFAULT_QUERY_TIMEOUT);
Scrollable = GetBoolCatInfo("Scrollable", false);
Memory = GetIntCatInfo("Memory", 0);
Pseudo = 2; // FILID is Ok but not ROWID
//Qrystr = GetStringCatInfo(g, "Query_String", "?");
//Sep = GetStringCatInfo(g, "Separator", NULL);
//Xsrc = GetBoolCatInfo("Execsrc", FALSE);
//Maxerr = GetIntCatInfo("Maxerr", 0);
//Maxres = GetIntCatInfo("Maxres", 0);
//Quoted = GetIntCatInfo("Quoted", 0);
// Cto= GetIntCatInfo("ConnectTimeout", DEFAULT_LOGIN_TIMEOUT);
// Qto= GetIntCatInfo("QueryTimeout", DEFAULT_QUERY_TIMEOUT);
//Scrollable = GetBoolCatInfo("Scrollable", false);
//Memory = GetIntCatInfo("Memory", 0);
//Pseudo = 2; // FILID is Ok but not ROWID
return false;
} // end of DefineAM
@ -266,7 +270,7 @@ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
/***********************************************************************/
PTDB JDBCDEF::GetTable(PGLOBAL g, MODE m)
{
PTDBASE tdbp = NULL;
PTDB tdbp = NULL;
/*********************************************************************/
/* Allocate a TDB of the proper type. */
@ -326,7 +330,7 @@ int JDBCPARM::CheckSize(int rows)
/***********************************************************************/
/* Implementation of the TDBJDBC class. */
/***********************************************************************/
TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBASE(tdp)
TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBEXT(tdp)
{
Jcp = NULL;
Cnp = NULL;
@ -335,101 +339,45 @@ TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBASE(tdp)
Ops.Driver = tdp->Driver;
Ops.Url = tdp->Url;
WrapName = tdp->Wrapname;
TableName = tdp->Tabname;
Schema = tdp->Tabschema;
Ops.User = tdp->Username;
Ops.Pwd = tdp->Password;
// Ops.Properties = tdp->Prop;
Catalog = tdp->Tabcat;
Srcdef = tdp->Srcdef;
Qrystr = tdp->Qrystr;
Sep = tdp->GetSep();
Options = tdp->Options;
// Ops.Cto = tdp->Cto;
// Ops.Qto = tdp->Qto;
Quoted = MY_MAX(0, tdp->GetQuoted());
Rows = tdp->GetElemt();
Memory = tdp->Memory;
Ops.Scrollable = tdp->Scrollable;
} else {
WrapName = NULL;
TableName = NULL;
Schema = NULL;
Ops.Driver = NULL;
Ops.Url = NULL;
Ops.User = NULL;
Ops.Pwd = NULL;
// Ops.Properties = NULL;
Catalog = NULL;
Srcdef = NULL;
Qrystr = NULL;
Sep = 0;
Options = 0;
// Ops.Cto = DEFAULT_LOGIN_TIMEOUT;
// Ops.Qto = DEFAULT_QUERY_TIMEOUT;
Quoted = 0;
Rows = 0;
Memory = 0;
Ops.Scrollable = false;
} // endif tdp
Quote = NULL;
Query = NULL;
Count = NULL;
//Where = NULL;
MulConn = NULL;
DBQ = NULL;
Qrp = NULL;
Fpos = 0;
Curpos = 0;
AftRows = 0;
CurNum = 0;
Rbuf = 0;
BufSize = 0;
Ncol = 0;
Nparm = 0;
Placed = false;
//Ncol = 0;
Prepared = false;
Werr = false;
Rerr = false;
Ops.Fsize = Ops.CheckSize(Rows);
} // end of TDBJDBC standard constructor
TDBJDBC::TDBJDBC(PTDBJDBC tdbp) : TDBASE(tdbp)
TDBJDBC::TDBJDBC(PTDBJDBC tdbp) : TDBEXT(tdbp)
{
Jcp = tdbp->Jcp; // is that right ?
Cnp = tdbp->Cnp;
WrapName = tdbp->WrapName;
TableName = tdbp->TableName;
Schema = tdbp->Schema;
Ops = tdbp->Ops;
Catalog = tdbp->Catalog;
Srcdef = tdbp->Srcdef;
Qrystr = tdbp->Qrystr;
Memory = tdbp->Memory;
//Scrollable = tdbp->Scrollable;
Quote = tdbp->Quote;
Query = tdbp->Query;
Count = tdbp->Count;
//Where = tdbp->Where;
MulConn = tdbp->MulConn;
DBQ = tdbp->DBQ;
Options = tdbp->Options;
Quoted = tdbp->Quoted;
Rows = tdbp->Rows;
Fpos = 0;
Curpos = 0;
AftRows = 0;
CurNum = 0;
Rbuf = 0;
BufSize = tdbp->BufSize;
Nparm = tdbp->Nparm;
Qrp = tdbp->Qrp;
Placed = false;
//Ncol = tdbp->Ncol;
Prepared = tdbp->Prepared;
Werr = tdbp->Werr;
Rerr = tdbp->Rerr;
} // end of TDBJDBC copy constructor
// Method
PTDB TDBJDBC::CopyOne(PTABS t)
PTDB TDBJDBC::Clone(PTABS t)
{
PTDB tp;
PJDBCCOL cp1, cp2;
@ -443,7 +391,7 @@ PTDB TDBJDBC::CopyOne(PTABS t)
} // endfor cp1
return tp;
} // end of CopyOne
} // end of Clone
/***********************************************************************/
/* Allocate JDBC column description block. */
@ -453,134 +401,6 @@ PCOL TDBJDBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
return new(g)JDBCCOL(cdp, this, cprec, n);
} // end of MakeCol
/******************************************************************/
/* Convert an UTF-8 string to latin characters. */
/******************************************************************/
int TDBJDBC::Decode(char *txt, char *buf, size_t n)
{
uint dummy_errors;
uint32 len= copy_and_convert(buf, n, &my_charset_latin1,
txt, strlen(txt),
&my_charset_utf8_general_ci,
&dummy_errors);
buf[len]= '\0';
return 0;
} // end of Decode
/***********************************************************************/
/* MakeSQL: make the SQL statement use with JDBC connection. */
/* TODO: when implementing EOM filtering, column only used in local */
/* filter should be removed from column list. */
/***********************************************************************/
bool TDBJDBC::MakeSQL(PGLOBAL g, bool cnt)
{
char *schmp = NULL, *catp = NULL, buf[NAM_LEN * 3];
int len;
bool oom = false, first = true;
PTABLE tablep = To_Table;
PCOL colp;
if (Srcdef) {
Query = new(g)STRING(g, 0, Srcdef);
return false;
} // endif Srcdef
// Allocate the string used to contain the Query
Query = new(g)STRING(g, 1023, "SELECT ");
if (!cnt) {
if (Columns) {
// Normal SQL statement to retrieve results
for (colp = Columns; colp; colp = colp->GetNext())
if (!colp->IsSpecial()) {
if (!first)
oom |= Query->Append(", ");
else
first = false;
// Column name can be encoded in UTF-8
Decode(colp->GetName(), buf, sizeof(buf));
if (Quote) {
// Put column name between identifier quotes in case in contains blanks
oom |= Query->Append(Quote);
oom |= Query->Append(buf);
oom |= Query->Append(Quote);
} else
oom |= Query->Append(buf);
((PJDBCCOL)colp)->Rank = ++Ncol;
} // endif colp
} else
// !Columns can occur for queries such that sql count(*) from...
// for which we will count the rows from sql * from...
oom |= Query->Append('*');
} else
// SQL statement used to retrieve the size of the result
oom |= Query->Append("count(*)");
oom |= Query->Append(" FROM ");
if (Catalog && *Catalog)
catp = Catalog;
//if (tablep->GetSchema())
// schmp = (char*)tablep->GetSchema();
//else
if (Schema && *Schema)
schmp = Schema;
if (catp) {
oom |= Query->Append(catp);
if (schmp) {
oom |= Query->Append('.');
oom |= Query->Append(schmp);
} // endif schmp
oom |= Query->Append('.');
} else if (schmp) {
oom |= Query->Append(schmp);
oom |= Query->Append('.');
} // endif schmp
// Table name can be encoded in UTF-8
Decode(TableName, buf, sizeof(buf));
if (Quote) {
// Put table name between identifier quotes in case in contains blanks
oom |= Query->Append(Quote);
oom |= Query->Append(buf);
oom |= Query->Append(Quote);
} else
oom |= Query->Append(buf);
len = Query->GetLength();
if (To_CondFil) {
if (Mode == MODE_READ) {
oom |= Query->Append(" WHERE ");
oom |= Query->Append(To_CondFil->Body);
len = Query->GetLength() + 1;
} else
len += (strlen(To_CondFil->Body) + 256);
} else
len += ((Mode == MODE_READX) ? 256 : 1);
if (oom || Query->Resize(len)) {
strcpy(g->Message, "MakeSQL: Out of memory");
return true;
} // endif oom
if (trace)
htrc("Query=%s\n", Query->GetStr());
return false;
} // end of MakeSQL
/***********************************************************************/
/* MakeInsert: make the Insert statement used with JDBC connection. */
/***********************************************************************/
@ -601,7 +421,7 @@ bool TDBJDBC::MakeInsert(PGLOBAL g)
// Column name can be encoded in UTF-8
Decode(colp->GetName(), buf, sizeof(buf));
len += (strlen(buf) + 6); // comma + quotes + valist
((PJDBCCOL)colp)->Rank = ++Nparm;
((PEXTCOL)colp)->SetRank(++Nparm);
} // endif colp
// Below 32 is enough to contain the fixed part of the query
@ -710,76 +530,6 @@ bool TDBJDBC::SetParameters(PGLOBAL g)
return false;
} // end of SetParameters
/***********************************************************************/
/* MakeCommand: make the Update or Delete statement to send to the */
/* MySQL server. Limited to remote values and filtering. */
/***********************************************************************/
bool TDBJDBC::MakeCommand(PGLOBAL g)
{
char *p, *stmt, name[68], *body = NULL, *qc = Jcp->GetQuoteChar();
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++]);
if (To_CondFil && (p = strstr(qrystr, " where "))) {
p[7] = 0; // Remove where clause
Qrystr[(p - qrystr) + 7] = 0;
body = To_CondFil->Body;
stmt = (char*)PlugSubAlloc(g, NULL, strlen(qrystr)
+ strlen(body) + 64);
} else
stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
// Check whether the table name is equal to a keyword
// If so, it must be quoted in the original query
strlwr(strcat(strcat(strcpy(name, " "), Name), " "));
if (strstr(" update delete low_priority ignore quick from ", name)) {
strlwr(strcat(strcat(strcpy(name, qc), Name), qc));
k += 2;
} else
strlwr(strcpy(name, Name)); // Not a keyword
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++]);
if (body)
strcat(stmt, body);
} else {
sprintf(g->Message, "Cannot use this %s command",
(Mode == MODE_UPDATE) ? "UPDATE" : "DELETE");
return NULL;
} // endif p
if (trace)
htrc("Command=%s\n", stmt);
Query = new(g)STRING(g, 0, stmt);
return (!Query->GetSize());
} // end of MakeCommand
/***********************************************************************/
/* ResetSize: call by TDBMUL when calculating size estimate. */
/***********************************************************************/
@ -833,33 +583,6 @@ int TDBJDBC::Cardinality(PGLOBAL g)
return Cardinal;
} // end of Cardinality
/***********************************************************************/
/* JDBC GetMaxSize: returns table size estimate in number of lines. */
/***********************************************************************/
int TDBJDBC::GetMaxSize(PGLOBAL g)
{
if (MaxSize < 0) {
if (Mode == MODE_DELETE)
// Return 0 in mode DELETE in case of delete all.
MaxSize = 0;
else if (!Cardinality(NULL))
MaxSize = 10; // To make MySQL happy
else if ((MaxSize = Cardinality(g)) < 0)
MaxSize = 12; // So we can see an error occured
} // endif MaxSize
return MaxSize;
} // end of GetMaxSize
/***********************************************************************/
/* Return max size value. */
/***********************************************************************/
int TDBJDBC::GetProgMax(PGLOBAL g)
{
return GetMaxSize(g);
} // end of GetProgMax
/***********************************************************************/
/* JDBC Access Method opening routine. */
/* New method now that this routine is called recursively (last table */
@ -997,6 +720,7 @@ bool TDBJDBC::OpenDB(PGLOBAL g)
return false;
} // end of OpenDB
#if 0
/***********************************************************************/
/* GetRecpos: return the position of last read record. */
/***********************************************************************/
@ -1004,6 +728,7 @@ int TDBJDBC::GetRecpos(void)
{
return Fpos;
} // end of GetRecpos
#endif // 0
/***********************************************************************/
/* SetRecpos: set the position of next read record. */
@ -1105,8 +830,7 @@ int TDBJDBC::ReadDB(PGLOBAL g)
int rc;
if (trace > 1)
htrc("JDBC ReadDB: R%d Mode=%d key=%p link=%p Kindex=%p\n",
GetTdb_No(), Mode, To_Key_Col, To_Link, To_Kindex);
htrc("JDBC ReadDB: R%d Mode=%d\n", GetTdb_No(), Mode);
if (Mode == MODE_UPDATE || Mode == MODE_DELETE) {
if (!Query && MakeCommand(g))
@ -1125,12 +849,6 @@ int TDBJDBC::ReadDB(PGLOBAL g)
} // endif Mode
if (To_Kindex) {
// Direct access of JDBC tables is not implemented
strcpy(g->Message, "No JDBC direct access");
return RC_FX;
} // endif To_Kindex
/*********************************************************************/
/* Now start the reading process. */
/* Here is the place to fetch the line(s). */
@ -1302,70 +1020,26 @@ void TDBJDBC::CloseDB(PGLOBAL g)
/* JDBCCOL public constructor. */
/***********************************************************************/
JDBCCOL::JDBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
: COLBLK(cdp, tdbp, i)
: EXTCOL(cdp, tdbp, cprec, i, am)
{
if (cprec) {
Next = cprec->GetNext();
cprec->SetNext(this);
} else {
Next = tdbp->GetColumns();
tdbp->SetColumns(this);
} // endif cprec
// Set additional JDBC access method information for column.
Crp = NULL;
//Long = cdp->GetLong();
Long = Precision;
//strcpy(F_Date, cdp->F_Date);
To_Val = NULL;
//Slen = 0;
//StrLen = &Slen;
//Sqlbuf = NULL;
Bufp = NULL;
Blkp = NULL;
Rank = 0; // Not known yet
if (trace)
htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this);
} // end of JDBCCOL constructor
/***********************************************************************/
/* JDBCCOL private constructor. */
/***********************************************************************/
JDBCCOL::JDBCCOL(void) : COLBLK()
JDBCCOL::JDBCCOL(void) : EXTCOL()
{
Crp = NULL;
Buf_Type = TYPE_INT; // This is a count(*) column
// Set additional Dos access method information for column.
Long = sizeof(int);
To_Val = NULL;
//Slen = 0;
//StrLen = &Slen;
//Sqlbuf = NULL;
Bufp = NULL;
Blkp = NULL;
Rank = 1;
} // end of JDBCCOL constructor
/***********************************************************************/
/* JDBCCOL constructor used for copying columns. */
/* tdbp is the pointer to the new table descriptor. */
/***********************************************************************/
JDBCCOL::JDBCCOL(JDBCCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp)
JDBCCOL::JDBCCOL(JDBCCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp)
{
Crp = col1->Crp;
Long = col1->Long;
//strcpy(F_Date, col1->F_Date);
To_Val = col1->To_Val;
//Slen = col1->Slen;
//StrLen = col1->StrLen;
//Sqlbuf = col1->Sqlbuf;
Bufp = col1->Bufp;
Blkp = col1->Blkp;
Rank = col1->Rank;
} // end of JDBCCOL copy constructor
#if 0
/***********************************************************************/
/* SetBuffer: prepare a column block for write operation. */
/***********************************************************************/
@ -1411,6 +1085,7 @@ bool JDBCCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
Status = (ok) ? BUF_EMPTY : BUF_NO;
return false;
} // end of SetBuffer
#endif // 0
/***********************************************************************/
/* ReadColumn: when SQLFetch is used there is nothing to do as the */
@ -1456,72 +1131,8 @@ void JDBCCOL::ReadColumn(PGLOBAL g)
} // end of ReadColumn
#if 0
/***********************************************************************/
/* AllocateBuffers: allocate the extended buffer for SQLExtendedFetch */
/* or Fetch. Note: we use Long+1 here because JDBC must have space */
/* for the ending null character. */
/***********************************************************************/
void JDBCCOL::AllocateBuffers(PGLOBAL g, int rows)
{
if (Buf_Type == TYPE_DATE)
Sqlbuf = (TIMESTAMP_STRUCT*)PlugSubAlloc(g, NULL,
sizeof(TIMESTAMP_STRUCT));
if (!rows)
return;
if (Buf_Type == TYPE_DATE)
Bufp = PlugSubAlloc(g, NULL, rows * sizeof(TIMESTAMP_STRUCT));
else {
Blkp = AllocValBlock(g, NULL, Buf_Type, rows, GetBuflen(),
GetScale(), true, false, false);
Bufp = Blkp->GetValPointer();
} // endelse
if (rows > 1)
StrLen = (SQLLEN *)PlugSubAlloc(g, NULL, rows * sizeof(SQLLEN));
} // end of AllocateBuffers
/***********************************************************************/
/* Returns the buffer to use for Fetch or Extended Fetch. */
/***********************************************************************/
void *JDBCCOL::GetBuffer(DWORD rows)
{
if (rows && To_Tdb) {
assert(rows == (DWORD)((TDBJDBC*)To_Tdb)->Rows);
return Bufp;
} else
return (Buf_Type == TYPE_DATE) ? Sqlbuf : Value->GetTo_Val();
} // end of GetBuffer
/***********************************************************************/
/* Returns the buffer length to use for Fetch or Extended Fetch. */
/***********************************************************************/
SWORD JDBCCOL::GetBuflen(void)
{
SWORD flen;
switch (Buf_Type) {
case TYPE_DATE:
flen = (SWORD)sizeof(TIMESTAMP_STRUCT);
break;
case TYPE_STRING:
case TYPE_DECIM:
flen = (SWORD)Value->GetClen() + 1;
break;
default:
flen = (SWORD)Value->GetClen();
} // endswitch Buf_Type
return flen;
} // end of GetBuflen
#endif // 0
/***********************************************************************/
/* WriteColumn: make sure the bind buffer is updated. */
/* WriteColumn: Convert if necessary. */
/***********************************************************************/
void JDBCCOL::WriteColumn(PGLOBAL g)
{
@ -1531,30 +1142,6 @@ void JDBCCOL::WriteColumn(PGLOBAL g)
if (Value != To_Val)
Value->SetValue_pval(To_Val, FALSE); // Convert the inserted value
#if 0
if (Buf_Type == TYPE_DATE) {
struct tm tm, *dbtime = ((DTVAL*)Value)->GetGmTime(&tm);
Sqlbuf->second = dbtime->tm_sec;
Sqlbuf->minute = dbtime->tm_min;
Sqlbuf->hour = dbtime->tm_hour;
Sqlbuf->day = dbtime->tm_mday;
Sqlbuf->month = dbtime->tm_mon + 1;
Sqlbuf->year = dbtime->tm_year + 1900;
Sqlbuf->fraction = 0;
} else if (Buf_Type == TYPE_DECIM) {
// Some data sources require local decimal separator
char *p, sep = ((PTDBJDBC)To_Tdb)->Sep;
if (sep && (p = strchr(Value->GetCharValue(), '.')))
*p = sep;
} // endif Buf_Type
if (Nullable)
*StrLen = (Value->IsNull()) ? SQL_NULL_DATA :
(IsTypeChar(Buf_Type)) ? SQL_NTS : 0;
#endif // 0
} // end of WriteColumn
/* -------------------------- Class TDBXJDC -------------------------- */
@ -1795,7 +1382,7 @@ TDBJTB::TDBJTB(PJDBCDEF tdp) : TDBJDRV(tdp)
{
Schema = tdp->Tabschema;
Tab = tdp->Tabname;
Tabtype = tdp->Tabtype;
Tabtype = tdp->Tabtyp;
Ops.Driver = tdp->Driver;
Ops.Url = tdp->Url;
Ops.User = tdp->Username;

View file

@ -21,7 +21,7 @@ typedef class JSRCCOL *PJSRCCOL;
/***********************************************************************/
/* JDBC table. */
/***********************************************************************/
class DllExport JDBCDEF : public TABDEF { /* Logical table description */
class DllExport JDBCDEF : public EXTDEF { /* Logical table description */
friend class TDBJDBC;
friend class TDBXJDC;
friend class TDBJDRV;
@ -33,17 +33,8 @@ public:
// Implementation
virtual const char *GetType(void) { return "JDBC"; }
PSZ GetTabname(void) { return Tabname; }
PSZ GetTabschema(void) { return Tabschema; }
PSZ GetTabcat(void) { return Tabcat; }
PSZ GetSrcdef(void) { return Srcdef; }
char GetSep(void) { return (Sep) ? *Sep : 0; }
int GetQuoted(void) { return Quoted; }
//int GetCatver(void) { return Catver; }
int GetOptions(void) { return Options; }
// Methods
virtual int Indexable(void) { return 2; }
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE m);
int ParseURL(PGLOBAL g, char *url, bool b = true);
@ -53,28 +44,7 @@ protected:
// Members
PSZ Driver; /* JDBC driver */
PSZ Url; /* JDBC driver URL */
PSZ Tabname; /* External table name */
PSZ Wrapname; /* Java wrapper name */
PSZ Tabschema; /* External table schema */
PSZ Username; /* User connect name */
PSZ Password; /* Password connect info */
//PSZ Prop; /* Connection Properties */
PSZ Tabcat; /* External table catalog */
PSZ Tabtype; /* External table type */
PSZ Colpat; /* Catalog column pattern */
PSZ Srcdef; /* The source table SQL definition */
PSZ Qchar; /* Identifier quoting character */
PSZ Qrystr; /* The original query */
PSZ Sep; /* Decimal separator */
int Options; /* Open connection options */
//int Cto; /* Open connection timeout */
//int Qto; /* Query (command) timeout */
int Quoted; /* Identifier quoting level */
int Maxerr; /* Maxerr for an Exec table */
int Maxres; /* Maxres for a catalog table */
int Memory; /* Put result set in memory */
bool Scrollable; /* Use scrollable cursor */
bool Xsrc; /* Execution type */
}; // end of JDBCDEF
#if !defined(NJDBC)
@ -84,34 +54,34 @@ protected:
/* This is the JDBC Access Method class declaration for files from */
/* other DB drivers to be accessed via JDBC. */
/***********************************************************************/
class TDBJDBC : public TDBASE {
class TDBJDBC : public TDBEXT {
friend class JDBCCOL;
friend class JDBConn;
public:
// Constructor
TDBJDBC(PJDBCDEF tdp = NULL);
TDBJDBC(PTDBJDBC tdbp);
TDBJDBC(PTDBJDBC tdbp);
// Implementation
virtual AMT GetAmType(void) { return TYPE_AM_JDBC; }
virtual PTDB Duplicate(PGLOBAL g) { return (PTDB)new(g)TDBJDBC(this); }
virtual AMT GetAmType(void) {return TYPE_AM_JDBC;}
virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBJDBC(this);}
// Methods
virtual PTDB CopyOne(PTABS t);
virtual int GetRecpos(void);
virtual PTDB Clone(PTABS t);
//virtual int GetRecpos(void);
virtual bool SetRecpos(PGLOBAL g, int recpos);
//virtual PSZ GetFile(PGLOBAL g);
//virtual void SetFile(PGLOBAL g, PSZ fn);
virtual void ResetSize(void);
//virtual int GetAffectedRows(void) {return AftRows;}
//virtual int GetAffectedRows(void) {return AftRows;}
virtual PSZ GetServer(void) { return "JDBC"; }
virtual int Indexable(void) { return 2; }
// Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
virtual int Cardinality(PGLOBAL g);
virtual int GetMaxSize(PGLOBAL g);
virtual int GetProgMax(PGLOBAL g);
//virtual int GetMaxSize(PGLOBAL g);
//virtual int GetProgMax(PGLOBAL g);
virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g);
virtual int WriteDB(PGLOBAL g);
@ -121,97 +91,50 @@ public:
protected:
// Internal functions
int Decode(char *utf, char *buf, size_t n);
bool MakeSQL(PGLOBAL g, bool cnt);
//int Decode(char *utf, char *buf, size_t n);
//bool MakeSQL(PGLOBAL g, bool cnt);
bool MakeInsert(PGLOBAL g);
bool MakeCommand(PGLOBAL g);
//bool MakeFilter(PGLOBAL g, bool c);
//virtual bool MakeCommand(PGLOBAL g);
//bool MakeFilter(PGLOBAL g, bool c);
bool SetParameters(PGLOBAL g);
//char *MakeUpdate(PGLOBAL g);
//char *MakeDelete(PGLOBAL g);
//char *MakeUpdate(PGLOBAL g);
//char *MakeDelete(PGLOBAL g);
// Members
JDBConn *Jcp; // Points to a JDBC connection class
JDBCCOL *Cnp; // Points to count(*) column
JDBCPARM Ops; // Additional parameters
PSTRG Query; // Constructed SQL query
char *WrapName; // Points to Java wrapper name
char *TableName; // Points to JDBC table name
char *Schema; // Points to JDBC table Schema
char *User; // User connect info
char *Pwd; // Password connect info
char *Catalog; // Points to JDBC table Catalog
char *Srcdef; // The source table SQL definition
char *Count; // Points to count(*) SQL statement
//char *Where; // Points to local where clause
char *Quote; // The identifier quoting character
char *MulConn; // Used for multiple JDBC tables
char *DBQ; // The address part of Connect string
char *Qrystr; // The original query
char Sep; // The decimal separator
int Options; // Connect options
//int Cto; // Connect timeout
//int Qto; // Query timeout
int Quoted; // The identifier quoting level
int Fpos; // Position of last read record
int Curpos; // Cursor position of last fetch
int AftRows; // The number of affected rows
int Rows; // Rowset size
int CurNum; // Current buffer line number
int Rbuf; // Number of lines read in buffer
int BufSize; // Size of connect string buffer
int Ncol; // The column number
int Nparm; // The number of statement parameters
int Memory; // 0: No 1: Alloc 2: Put 3: Get
//bool Scrollable; // Use scrollable cursor --> in Ops
bool Placed; // True for position reading
//int Ncol; // The column number
bool Prepared; // True when using prepared statement
bool Werr; // Write error
bool Rerr; // Rewind error
PQRYRES Qrp; // Points to storage result
}; // end of class TDBJDBC
/***********************************************************************/
/* Class JDBCCOL: JDBC access method column descriptor. */
/* This A.M. is used for JDBC tables. */
/***********************************************************************/
class JDBCCOL : public COLBLK {
class JDBCCOL : public EXTCOL {
friend class TDBJDBC;
public:
// Constructors
JDBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "JDBC");
JDBCCOL(JDBCCOL *colp, PTDB tdbp); // Constructor used in copy process
JDBCCOL(JDBCCOL *colp, PTDB tdbp); // Constructor used in copy process
// Implementation
virtual int GetAmType(void) { return TYPE_AM_JDBC; }
//SQLLEN *GetStrLen(void) { return StrLen; }
int GetRank(void) { return Rank; }
//PVBLK GetBlkp(void) {return Blkp;}
void SetCrp(PCOLRES crp) { Crp = crp; }
virtual int GetAmType(void) { return TYPE_AM_JDBC; }
// Methods
virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
virtual void ReadColumn(PGLOBAL g);
virtual void WriteColumn(PGLOBAL g);
//void AllocateBuffers(PGLOBAL g, int rows);
//void *GetBuffer(DWORD rows);
//SWORD GetBuflen(void);
// void Print(PGLOBAL g, FILE *, uint);
//virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
virtual void ReadColumn(PGLOBAL g);
virtual void WriteColumn(PGLOBAL g);
protected:
// Constructor used by GetMaxSize
JDBCCOL(void);
// Constructor for count(*) column
JDBCCOL(void);
// Members
//TIMESTAMP_STRUCT *Sqlbuf; // To get SQL_TIMESTAMP's
PCOLRES Crp; // To storage result
void *Bufp; // To extended buffer
PVBLK Blkp; // To Value Block
//char F_Date[12]; // Internal Date format
PVAL To_Val; // To value used for Insert
//SQLLEN *StrLen; // As returned by JDBC
//SQLLEN Slen; // Used with Fetch
int Rank; // Rank (position) number in the query
}; // end of class JDBCCOL
/***********************************************************************/
@ -268,7 +191,7 @@ public:
JSRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "JDBC");
// Implementation
//virtual int GetAmType(void) {return TYPE_AM_JDBC;}
virtual int GetAmType(void) {return TYPE_AM_JDBC;}
// Methods
virtual void ReadColumn(PGLOBAL g);

View file

@ -574,7 +574,7 @@ TDBJSN::TDBJSN(TDBJSN *tdbp) : TDBDOS(NULL, tdbp)
} // end of TDBJSN copy constructor
// Used for update
PTDB TDBJSN::CopyOne(PTABS t)
PTDB TDBJSN::Clone(PTABS t)
{
G = NULL;
PTDB tp;
@ -589,7 +589,7 @@ PTDB TDBJSN::CopyOne(PTABS t)
} // endfor cp1
return tp;
} // end of CopyOne
} // end of Clone
/***********************************************************************/
/* Allocate JSN column description block. */
@ -1578,7 +1578,7 @@ TDBJSON::TDBJSON(PJTDB tdbp) : TDBJSN(tdbp)
} // end of TDBJSON copy constructor
// Used for update
PTDB TDBJSON::CopyOne(PTABS t)
PTDB TDBJSON::Clone(PTABS t)
{
PTDB tp;
PJCOL cp1, cp2;
@ -1592,7 +1592,7 @@ PTDB TDBJSON::CopyOne(PTABS t)
} // endfor cp1
return tp;
} // end of CopyOne
} // end of Clone
/***********************************************************************/
/* Make the document tree from the object path. */

View file

@ -82,7 +82,7 @@ public:
void SetG(PGLOBAL g) {G = g;}
// Methods
virtual PTDB CopyOne(PTABS t);
virtual PTDB Clone(PTABS t);
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
virtual PCOL InsertSpecialColumn(PCOL colp);
virtual int RowNumber(PGLOBAL g, bool b = FALSE)
@ -188,7 +188,7 @@ class TDBJSON : public TDBJSN {
PJAR GetDoc(void) {return Doc;}
// Methods
virtual PTDB CopyOne(PTABS t);
virtual PTDB Clone(PTABS t);
// Database routines
virtual int Cardinality(PGLOBAL g);

View file

@ -1,7 +1,7 @@
/************** Table C++ Functions Source Code File (.CPP) ************/
/* Name: TABLE.CPP Version 2.7 */
/* Name: TABLE.CPP Version 2.8 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 1999-2016 */
/* (C) Copyright to the author Olivier BERTRAND 1999-2017 */
/* */
/* This file contains the TBX, TDB and OPJOIN classes functions. */
/***********************************************************************/
@ -10,6 +10,7 @@
/* Include relevant MariaDB header file. */
/***********************************************************************/
#include "my_global.h"
#include "sql_string.h"
/***********************************************************************/
/* Include required application header files */
@ -40,8 +41,9 @@ void AddPointer(PTABS, void *);
/* TDB public constructors. */
/***********************************************************************/
TDB::TDB(PTABDEF tdp) : Tdb_No(++Tnum)
{
Use = USE_NO;
{
To_Def = tdp;
Use = USE_NO;
To_Orig = NULL;
To_Filter = NULL;
To_CondFil = NULL;
@ -49,14 +51,20 @@ TDB::TDB(PTABDEF tdp) : Tdb_No(++Tnum)
Name = (tdp) ? tdp->GetName() : NULL;
To_Table = NULL;
Columns = NULL;
Degree = (tdp) ? tdp->GetDegree() : 0;
To_SetCols = NULL;
Degree = (tdp) ? tdp->GetDegree() : 0;
Mode = MODE_ANY;
Cardinal = -1;
} // end of TDB standard constructor
MaxSize = -1;
Read_Only = (tdp) ? tdp->IsReadOnly() : false;
m_data_charset = (tdp) ? tdp->data_charset() : NULL;
csname = (tdp) ? tdp->csname : NULL;
} // end of TDB standard constructor
TDB::TDB(PTDB tdbp) : Tdb_No(++Tnum)
{
Use = tdbp->Use;
{
To_Def = tdbp->To_Def;
Use = tdbp->Use;
To_Orig = tdbp;
To_Filter = NULL;
To_CondFil = NULL;
@ -64,12 +72,192 @@ TDB::TDB(PTDB tdbp) : Tdb_No(++Tnum)
Name = tdbp->Name;
To_Table = tdbp->To_Table;
Columns = NULL;
Degree = tdbp->Degree;
To_SetCols = tdbp->To_SetCols; // ???
Degree = tdbp->Degree;
Mode = tdbp->Mode;
Cardinal = tdbp->Cardinal;
} // end of TDB copy constructor
MaxSize = tdbp->MaxSize;
Read_Only = tdbp->IsReadOnly();
m_data_charset = tdbp->data_charset();
csname = tdbp->csname;
} // end of TDB copy constructor
// Methods
/***********************************************************************/
/* Return the pointer on the charset of this table. */
/***********************************************************************/
CHARSET_INFO *TDB::data_charset(void)
{
// If no DATA_CHARSET is specified, we assume that character
// set of the remote data is the same with CHARACTER SET
// definition of the SQL column.
return m_data_charset ? m_data_charset : &my_charset_bin;
} // end of data_charset
/***********************************************************************/
/* Return the datapath of the DB this table belongs to. */
/***********************************************************************/
PSZ TDB::GetPath(void)
{
return To_Def->GetPath();
} // end of GetPath
/***********************************************************************/
/* Return true if name is a special column of this table. */
/***********************************************************************/
bool TDB::IsSpecial(PSZ name)
{
for (PCOLDEF cdp = To_Def->GetCols(); cdp; cdp = cdp->GetNext())
if (!stricmp(cdp->GetName(), name) && (cdp->Flags & U_SPECIAL))
return true; // Special column to ignore while inserting
return false; // Not found or not special or not inserting
} // end of IsSpecial
/***********************************************************************/
/* Initialize TDB based column description block construction. */
/* name is used to call columns by name. */
/* num is used by TBL to construct columns by index number. */
/* Note: name=Null and num=0 for constructing all columns (select *) */
/***********************************************************************/
PCOL TDB::ColDB(PGLOBAL g, PSZ name, int num)
{
int i;
PCOLDEF cdp;
PCOL cp, colp = NULL, cprec = NULL;
if (trace)
htrc("ColDB: am=%d colname=%s tabname=%s num=%d\n",
GetAmType(), SVP(name), Name, num);
for (cdp = To_Def->GetCols(), i = 1; cdp; cdp = cdp->GetNext(), i++)
if ((!name && !num) ||
(name && !stricmp(cdp->GetName(), name)) || num == i) {
/*****************************************************************/
/* Check for existence of desired column. */
/* Also find where to insert the new block. */
/*****************************************************************/
for (cp = Columns; cp; cp = cp->GetNext())
if ((num && cp->GetIndex() == i) ||
(name && !stricmp(cp->GetName(), name)))
break; // Found
else if (cp->GetIndex() < i)
cprec = cp;
if (trace)
htrc("cdp(%d).Name=%s cp=%p\n", i, cdp->GetName(), cp);
/*****************************************************************/
/* Now take care of Column Description Block. */
/*****************************************************************/
if (cp)
colp = cp;
else if (!(cdp->Flags & U_SPECIAL))
colp = MakeCol(g, cdp, cprec, i);
else if (Mode != MODE_INSERT)
colp = InsertSpcBlk(g, cdp);
if (trace)
htrc("colp=%p\n", colp);
if (name || num)
break;
else if (colp && !colp->IsSpecial())
cprec = colp;
} // endif Name
return (colp);
} // end of ColDB
/***********************************************************************/
/* InsertSpecialColumn: Put a special column ahead of the column list.*/
/***********************************************************************/
PCOL TDB::InsertSpecialColumn(PCOL colp)
{
if (!colp->IsSpecial())
return NULL;
colp->SetNext(Columns);
Columns = colp;
return colp;
} // end of InsertSpecialColumn
/***********************************************************************/
/* Make a special COLBLK to insert in a table. */
/***********************************************************************/
PCOL TDB::InsertSpcBlk(PGLOBAL g, PCOLDEF cdp)
{
//char *name = cdp->GetName();
char *name = cdp->GetFmt();
PCOLUMN cp;
PCOL colp;
cp = new(g)COLUMN(cdp->GetName());
if (!To_Table) {
strcpy(g->Message, "Cannot make special column: To_Table is NULL");
return NULL;
} else
cp->SetTo_Table(To_Table);
if (!stricmp(name, "FILEID") || !stricmp(name, "FDISK") ||
!stricmp(name, "FPATH") || !stricmp(name, "FNAME") ||
!stricmp(name, "FTYPE") || !stricmp(name, "SERVID")) {
if (!To_Def || !(To_Def->GetPseudo() & 2)) {
sprintf(g->Message, MSG(BAD_SPEC_COLUMN));
return NULL;
} // endif Pseudo
if (!stricmp(name, "FILEID"))
colp = new(g)FIDBLK(cp, OP_XX);
else if (!stricmp(name, "FDISK"))
colp = new(g)FIDBLK(cp, OP_FDISK);
else if (!stricmp(name, "FPATH"))
colp = new(g)FIDBLK(cp, OP_FPATH);
else if (!stricmp(name, "FNAME"))
colp = new(g)FIDBLK(cp, OP_FNAME);
else if (!stricmp(name, "FTYPE"))
colp = new(g)FIDBLK(cp, OP_FTYPE);
else
colp = new(g)SIDBLK(cp);
} else if (!stricmp(name, "TABID")) {
colp = new(g)TIDBLK(cp);
} else if (!stricmp(name, "PARTID")) {
colp = new(g)PRTBLK(cp);
//} else if (!stricmp(name, "CONID")) {
// colp = new(g) CIDBLK(cp);
} else if (!stricmp(name, "ROWID")) {
colp = new(g)RIDBLK(cp, false);
} else if (!stricmp(name, "ROWNUM")) {
colp = new(g)RIDBLK(cp, true);
} else {
sprintf(g->Message, MSG(BAD_SPECIAL_COL), name);
return NULL;
} // endif's name
if (!(colp = InsertSpecialColumn(colp))) {
sprintf(g->Message, MSG(BAD_SPECIAL_COL), name);
return NULL;
} // endif Insert
return (colp);
} // end of InsertSpcBlk
/***********************************************************************/
/* Marks DOS/MAP table columns used in internal joins. */
/* tdb2 is the top of tree or first tdb in chained tdb's and tdbp */
/* points to the currently marked tdb. */
/* Two questions here: exact meaning of U_J_INT ? */
/* Why is the eventual reference to To_Key_Col not marked U_J_EXT ? */
/***********************************************************************/
void TDB::MarkDB(PGLOBAL, PTDB tdb2)
{
if (trace)
htrc("DOS MarkDB: tdbp=%p tdb2=%p\n", this, tdb2);
} // end of MarkDB
/***********************************************************************/
/* RowNumber: returns the current row ordinal number. */
@ -86,7 +274,7 @@ PTDB TDB::Copy(PTABS t)
//PGLOBAL g = t->G; // Is this really useful ???
for (tdb1 = this; tdb1; tdb1 = tdb1->Next) {
tp = tdb1->CopyOne(t);
tp = tdb1->Clone(t);
if (!outp)
outp = tp;
@ -100,6 +288,15 @@ PTDB TDB::Copy(PTABS t)
return outp;
} // end of Copy
/***********************************************************************/
/* SetRecpos: Replace the table at the specified position. */
/***********************************************************************/
bool TDB::SetRecpos(PGLOBAL g, int)
{
strcpy(g->Message, MSG(SETRECPOS_NIY));
return true;
} // end of SetRecpos
void TDB::Print(PGLOBAL g, FILE *f, uint n)
{
PCOL cp;
@ -135,34 +332,34 @@ void TDB::Print(PGLOBAL, char *ps, uint)
/***********************************************************************/
TDBASE::TDBASE(PTABDEF tdp) : TDB(tdp)
{
To_Def = tdp;
//To_Def = tdp;
To_Link = NULL;
To_Key_Col = NULL;
To_Kindex = NULL;
To_Xdp = NULL;
To_SetCols = NULL;
//To_SetCols = NULL;
Ftype = RECFM_NAF;
MaxSize = -1;
//MaxSize = -1;
Knum = 0;
Read_Only = (tdp) ? tdp->IsReadOnly() : false;
m_data_charset= (tdp) ? tdp->data_charset() : NULL;
csname = (tdp) ? tdp->csname : NULL;
//Read_Only = (tdp) ? tdp->IsReadOnly() : false;
//m_data_charset= (tdp) ? tdp->data_charset() : NULL;
//csname = (tdp) ? tdp->csname : NULL;
} // end of TDBASE constructor
TDBASE::TDBASE(PTDBASE tdbp) : TDB(tdbp)
{
To_Def = tdbp->To_Def;
//To_Def = tdbp->To_Def;
To_Link = tdbp->To_Link;
To_Key_Col = tdbp->To_Key_Col;
To_Kindex = tdbp->To_Kindex;
To_Xdp = tdbp->To_Xdp;
To_SetCols = tdbp->To_SetCols; // ???
//To_SetCols = tdbp->To_SetCols; // ???
Ftype = tdbp->Ftype;
MaxSize = tdbp->MaxSize;
//MaxSize = tdbp->MaxSize;
Knum = tdbp->Knum;
Read_Only = tdbp->Read_Only;
m_data_charset= tdbp->m_data_charset;
csname = tdbp->csname;
//Read_Only = tdbp->Read_Only;
//m_data_charset= tdbp->m_data_charset;
//csname = tdbp->csname;
} // end of TDBASE copy constructor
/***********************************************************************/
@ -173,6 +370,7 @@ PCATLG TDBASE::GetCat(void)
return (To_Def) ? To_Def->GetCat() : NULL;
} // end of GetCat
#if 0
/***********************************************************************/
/* Return the pointer on the charset of this table. */
/***********************************************************************/
@ -334,6 +532,7 @@ PCOL TDBASE::InsertSpcBlk(PGLOBAL g, PCOLDEF cdp)
return (colp);
} // end of InsertSpcBlk
#endif // 0
/***********************************************************************/
/* ResetTableOpt: Wrong for this table type. */
@ -362,6 +561,7 @@ void TDBASE::ResetKindex(PGLOBAL g, PKXBASE kxp)
To_Kindex = kxp;
} // end of ResetKindex
#if 0
/***********************************************************************/
/* SetRecpos: Replace the table at the specified position. */
/***********************************************************************/
@ -370,6 +570,7 @@ bool TDBASE::SetRecpos(PGLOBAL g, int)
strcpy(g->Message, MSG(SETRECPOS_NIY));
return true;
} // end of SetRecpos
#endif // 0
/***********************************************************************/
/* Methods */
@ -379,6 +580,7 @@ void TDBASE::PrintAM(FILE *f, char *m)
fprintf(f, "%s AM(%d): mode=%d\n", m, GetAmType(), Mode);
} // end of PrintAM
#if 0
/***********************************************************************/
/* Marks DOS/MAP table columns used in internal joins. */
/* tdb2 is the top of tree or first tdb in chained tdb's and tdbp */
@ -392,6 +594,7 @@ void TDBASE::MarkDB(PGLOBAL, PTDB tdb2)
htrc("DOS MarkDB: tdbp=%p tdb2=%p\n", this, tdb2);
} // end of MarkDB
#endif // 0
/* ---------------------------TDBCAT class --------------------------- */

View file

@ -12,7 +12,7 @@
#include "global.h"
#include "plgdbsem.h"
//#include "catalog.h"
#include "reldef.h"
//#include "reldef.h"
#include "xtable.h"
#include "colblk.h"
#include "tabmac.h"

View file

@ -52,7 +52,7 @@ class TDBMAC : public TDBASE {
//virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBMAC(g, this);}
// Methods
//virtual PTDB CopyOne(PTABS t);
//virtual PTDB Clone(PTABS t);
virtual int GetRecpos(void) {return N;}
virtual int RowNumber(PGLOBAL g, bool b = false) {return N;}

View file

@ -1,11 +1,11 @@
/************* TabMul C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABMUL */
/* ------------- */
/* Version 1.7 */
/* Version 1.8 */
/* */
/* COPYRIGHT: */
/* ---------- */
/* (C) Copyright to PlugDB Software Development 2003 - 2015 */
/* (C) Copyright to PlugDB Software Development 2003 - 2017 */
/* Author: Olivier BERTRAND */
/* */
/* WHAT THIS PROGRAM DOES: */
@ -73,7 +73,7 @@
/***********************************************************************/
/* TABMUL constructors. */
/***********************************************************************/
TDBMUL::TDBMUL(PTDBASE tdbp) : TDBASE(tdbp->GetDef())
TDBMUL::TDBMUL(PTDB tdbp) : TDBASE(tdbp->GetDef())
{
Tdbp = tdbp;
Filenames = NULL;
@ -94,22 +94,22 @@ TDBMUL::TDBMUL(PTDBMUL tdbp) : TDBASE(tdbp)
} // end of TDBMUL copy constructor
// Method
PTDB TDBMUL::CopyOne(PTABS t)
PTDB TDBMUL::Clone(PTABS t)
{
PTDBMUL tp;
PGLOBAL g = t->G; // Is this really useful ???
tp = new(g) TDBMUL(this);
tp->Tdbp = (PTDBASE)Tdbp->CopyOne(t);
tp->Tdbp = Tdbp->Clone(t);
tp->Columns = tp->Tdbp->GetColumns();
return tp;
} // end of CopyOne
} // end of Clone
PTDB TDBMUL::Duplicate(PGLOBAL g)
{
PTDBMUL tmup = new(g) TDBMUL(this);
tmup->Tdbp = (PTDBASE)Tdbp->Duplicate(g);
tmup->Tdbp = Tdbp->Duplicate(g);
return tmup;
} // end of Duplicate
@ -658,7 +658,7 @@ TDBDIR::TDBDIR(PTDBDIR tdbp) : TDBASE(tdbp)
} // end of TDBDIR copy constructor
// Method
PTDB TDBDIR::CopyOne(PTABS t)
PTDB TDBDIR::Clone(PTABS t)
{
PTDB tp;
PGLOBAL g = t->G; // Is this really useful ???
@ -666,7 +666,7 @@ PTDB TDBDIR::CopyOne(PTABS t)
tp = new(g) TDBDIR(this);
tp->SetColumns(Columns);
return tp;
} // end of CopyOne
} // end of Clone
/***********************************************************************/
/* Initialize/get the components of the search file pattern. */
@ -974,7 +974,7 @@ TDBSDR::TDBSDR(PTDBSDR tdbp) : TDBDIR(tdbp)
} // end of TDBSDR copy constructor
// Method
PTDB TDBSDR::CopyOne(PTABS t)
PTDB TDBSDR::Clone(PTABS t)
{
PTDB tp;
PGLOBAL g = t->G; // Is this really useful ???
@ -982,7 +982,7 @@ PTDB TDBSDR::CopyOne(PTABS t)
tp = new(g) TDBSDR(this);
tp->SetColumns(Columns);
return tp;
} // end of CopyOne
} // end of Clone
/***********************************************************************/
/* SDR GetMaxSize: returns the number of retrieved files. */
@ -1251,7 +1251,7 @@ TDBDHR::TDBDHR(PTDBDHR tdbp) : TDBASE(tdbp)
} // end of TDBDHR copy constructor
// Method
PTDB TDBDHR::CopyOne(PTABS t)
PTDB TDBDHR::Clone(PTABS t)
{
PTDB tp;
PGLOBAL g = t->G; // Is this really useful ???
@ -1259,7 +1259,7 @@ PTDB TDBDHR::CopyOne(PTABS t)
tp = new(g) TDBDHR(this);
tp->Columns = Columns;
return tp;
} // end of CopyOne
} // end of Clone
/***********************************************************************/
/* Allocate DHR column description block. */

View file

@ -1,7 +1,7 @@
/*************** Tabmul H Declares Source Code File (.H) ***************/
/* Name: TABMUL.H Version 1.4 */
/* Name: TABMUL.H Version 1.5 */
/* */
/* (C) Copyright to PlugDB Software Development 2003-2012 */
/* (C) Copyright to PlugDB Software Development 2003-2017 */
/* Author: Olivier BERTRAND */
/* */
/* This file contains the TDBMUL and TDBDIR classes declares. */
@ -28,7 +28,7 @@ class DllExport TDBMUL : public TDBASE {
//friend class MULCOL;
public:
// Constructor
TDBMUL(PTDBASE tdbp);
TDBMUL(PTDB tdbp);
TDBMUL(PTDBMUL tdbp);
// Implementation
@ -37,7 +37,7 @@ class DllExport TDBMUL : public TDBASE {
// Methods
virtual void ResetDB(void);
virtual PTDB CopyOne(PTABS t);
virtual PTDB Clone(PTABS t);
virtual bool IsSame(PTDB tp) {return tp == (PTDB)Tdbp;}
virtual PSZ GetFile(PGLOBAL g) {return Tdbp->GetFile(g);}
virtual int GetRecpos(void) {return 0;}
@ -61,7 +61,7 @@ class DllExport TDBMUL : public TDBASE {
protected:
// Members
TDBASE *Tdbp; // Points to a (file) table class
PTDB Tdbp; // Points to a (file) table class
char* *Filenames; // Points to file names
int Rows; // Total rows of already read files
int Mul; // Type of multiple file list
@ -112,7 +112,7 @@ class TDBDIR : public TDBASE {
{return (PTDB)new(g) TDBDIR(this);}
// Methods
virtual PTDB CopyOne(PTABS t);
virtual PTDB Clone(PTABS t);
virtual int GetRecpos(void) {return iFile;}
// Database routines
@ -168,7 +168,7 @@ class TDBSDR : public TDBDIR {
{return (PTDB)new(g) TDBSDR(this);}
// Methods
virtual PTDB CopyOne(PTABS t);
virtual PTDB Clone(PTABS t);
// Database routines
virtual int GetMaxSize(PGLOBAL g);

View file

@ -1,11 +1,11 @@
/************* TabMySQL C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: TABMYSQL */
/* ------------- */
/* Version 1.9 */
/* Version 2.0 */
/* */
/* AUTHOR: */
/* ------- */
/* Olivier BERTRAND 2007-2015 */
/* Olivier BERTRAND 2007-2017 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@ -54,9 +54,10 @@
#include "global.h"
#include "plgdbsem.h"
#include "xtable.h"
#include "tabext.h"
#include "tabcol.h"
#include "colblk.h"
#include "reldef.h"
//#include "reldef.h"
#include "tabmysql.h"
#include "valblk.h"
#include "tabutil.h"
@ -84,16 +85,16 @@ MYSQLDEF::MYSQLDEF(void)
{
Pseudo = 2; // SERVID is Ok but not ROWID
Hostname = NULL;
Database = NULL;
Tabname = NULL;
Srcdef = NULL;
Username = NULL;
Password = NULL;
//Tabschema = NULL;
//Tabname = NULL;
//Srcdef = NULL;
//Username = NULL;
//Password = NULL;
Portnumber = 0;
Isview = false;
Bind = false;
Delayed = false;
Xsrc = false;
//Xsrc = false;
Huge = false;
} // end of MYSQLDEF constructor
@ -128,7 +129,7 @@ bool MYSQLDEF::GetServerInfo(PGLOBAL g, const char *server_name)
// TODO: We need to examine which of these can really be NULL
Hostname = PlugDup(g, server->host);
Database = PlugDup(g, server->db);
Tabschema = PlugDup(g, server->db);
Username = PlugDup(g, server->username);
Password = PlugDup(g, server->password);
Portnumber = (server->port) ? server->port : GetDefaultPort();
@ -200,7 +201,7 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url, bool b)
Tabname = (b) ? GetStringCatInfo(g, "Tabname", Name) : NULL;
if (trace)
htrc("server: %s Tabname: %s", url, Tabname);
htrc("server: %s TableName: %s", url, Tabname);
Server = url;
return GetServerInfo(g, url);
@ -253,10 +254,10 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url, bool b)
return true;
} // endif
if ((Database = strchr(Hostname, '/'))) {
*Database++ = 0;
if ((Tabschema = strchr(Hostname, '/'))) {
*Tabschema++ = 0;
if ((Tabname = strchr(Database, '/'))) {
if ((Tabname = strchr(Tabschema, '/'))) {
*Tabname++ = 0;
// Make sure there's not an extra /
@ -265,7 +266,7 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url, bool b)
return true;
} // endif /
} // endif Tabname
} // endif TableName
} // endif database
@ -283,8 +284,8 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url, bool b)
if (Hostname[0] == 0)
Hostname = (b) ? GetStringCatInfo(g, "Host", "localhost") : NULL;
if (!Database || !*Database)
Database = (b) ? GetStringCatInfo(g, "Database", "*") : NULL;
if (!Tabschema || !*Tabschema)
Tabschema = (b) ? GetStringCatInfo(g, "Database", "*") : NULL;
if (!Tabname || !*Tabname)
Tabname = (b) ? GetStringCatInfo(g, "Tabname", Name) : NULL;
@ -320,7 +321,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
if (!url || !*url) {
// Not using the connection URL
Hostname = GetStringCatInfo(g, "Host", "localhost");
Database = GetStringCatInfo(g, "Database", "*");
Tabschema = GetStringCatInfo(g, "Database", "*");
Tabname = GetStringCatInfo(g, "Name", Name); // Deprecated
Tabname = GetStringCatInfo(g, "Tabname", Tabname);
Username = GetStringCatInfo(g, "User", "*");
@ -334,7 +335,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
Delayed = !!GetIntCatInfo("Delayed", 0);
} else {
// MYSQL access from a PROXY table
Database = GetStringCatInfo(g, "Database", Schema ? Schema : PlugDup(g, "*"));
Tabschema = GetStringCatInfo(g, "Database", Tabschema ? Tabschema : PlugDup(g, "*"));
Isview = GetBoolCatInfo("View", false);
// We must get other connection parms from the calling table
@ -348,12 +349,12 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
Portnumber = GetIntCatInfo("Port", GetDefaultPort());
Server = Hostname;
} else {
char *locdb = Database;
char *locdb = Tabschema;
if (ParseURL(g, url))
return true;
Database = locdb;
Tabschema = locdb;
} // endif url
Tabname = Name;
@ -362,7 +363,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL))) {
Read_Only = true;
Isview = true;
} else if (CheckSelf(g, Hc->GetTable()->s, Hostname, Database,
} else if (CheckSelf(g, Hc->GetTable()->s, Hostname, Tabschema,
Tabname, Srcdef, Portnumber))
return true;
@ -372,7 +373,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
// Specific for command executing tables
Xsrc = GetBoolCatInfo("Execsrc", false);
Mxr = GetIntCatInfo("Maxerr", 0);
Maxerr = GetIntCatInfo("Maxerr", 0);
Huge = GetBoolCatInfo("Huge", false);
return false;
} // end of DefineAM
@ -396,17 +397,17 @@ PTDB MYSQLDEF::GetTable(PGLOBAL g, MODE)
/***********************************************************************/
/* Implementation of the TDBMYSQL class. */
/***********************************************************************/
TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp)
TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBEXT(tdp)
{
if (tdp) {
Host = tdp->Hostname;
Database = tdp->Database;
Tabname = tdp->Tabname;
Srcdef = tdp->Srcdef;
User = tdp->Username;
Pwd = tdp->Password;
// Schema = tdp->Tabschema;
// TableName = tdp->Tabname;
// Srcdef = tdp->Srcdef;
// User = tdp->Username;
// Pwd = tdp->Password;
Server = tdp->Server;
Qrystr = tdp->Qrystr;
// Qrystr = tdp->Qrystr;
Quoted = MY_MAX(0, tdp->Quoted);
Port = tdp->Portnumber;
Isview = tdp->Isview;
@ -415,14 +416,14 @@ TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp)
Myc.m_Use = tdp->Huge;
} else {
Host = NULL;
Database = NULL;
Tabname = NULL;
Srcdef = NULL;
User = NULL;
Pwd = NULL;
// Schema = NULL;
// TableName = NULL;
// Srcdef = NULL;
// User = NULL;
// Pwd = NULL;
Server = NULL;
Qrystr = NULL;
Quoted = 0;
// Qrystr = NULL;
// Quoted = 0;
Port = 0;
Isview = false;
Prep = false;
@ -430,39 +431,40 @@ TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp)
} // endif tdp
Bind = NULL;
Query = NULL;
//Query = NULL;
Fetched = false;
m_Rc = RC_FX;
AftRows = 0;
//AftRows = 0;
N = -1;
Nparm = 0;
//Nparm = 0;
} // end of TDBMYSQL constructor
TDBMYSQL::TDBMYSQL(PTDBMY tdbp) : TDBASE(tdbp)
TDBMYSQL::TDBMYSQL(PTDBMY tdbp) : TDBEXT(tdbp)
{
Host = tdbp->Host;
Database = tdbp->Database;
Tabname = tdbp->Tabname;
Srcdef = tdbp->Srcdef;
User = tdbp->User;
Pwd = tdbp->Pwd;
Qrystr = tdbp->Qrystr;
Quoted = tdbp->Quoted;
//Schema = tdbp->Schema;
//TableName = tdbp->TableName;
//Srcdef = tdbp->Srcdef;
//User = tdbp->User;
//Pwd = tdbp->Pwd;
//Qrystr = tdbp->Qrystr;
//Quoted = tdbp->Quoted;
Server = tdbp->Server;
Port = tdbp->Port;
Isview = tdbp->Isview;
Prep = tdbp->Prep;
Delayed = tdbp->Delayed;
Bind = NULL;
Query = tdbp->Query;
//Query = tdbp->Query;
Fetched = tdbp->Fetched;
m_Rc = tdbp->m_Rc;
AftRows = tdbp->AftRows;
//AftRows = tdbp->AftRows;
N = tdbp->N;
Nparm = tdbp->Nparm;
//Nparm = tdbp->Nparm;
} // end of TDBMYSQL copy constructor
// Is this really useful ???
PTDB TDBMYSQL::CopyOne(PTABS t)
// Is this really useful ??? --> Yes for UPDATE
PTDB TDBMYSQL::Clone(PTABS t)
{
PTDB tp;
PCOL cp1, cp2;
@ -477,7 +479,7 @@ PTDB TDBMYSQL::CopyOne(PTABS t)
} // endfor cp1
return tp;
} // end of CopyOne
} // end of Clone
/***********************************************************************/
/* Allocate MYSQL column description block. */
@ -504,10 +506,18 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx)
if (Query)
return false; // already done
if (Srcdef) {
Query = new(g)STRING(g, 0, Srcdef);
return false;
} // endif Srcdef
if (Srcdef) {
if (strstr(Srcdef, "%s")) {
char *fil;
fil = (To_CondFil) ? To_CondFil->Body : PlugDup(g, "1=1");
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil));
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil));
} else
Query = new(g)STRING(g, 0, Srcdef);
return false;
} // endif Srcdef
// Allocate the string used to contain Query
Query = new(g) STRING(g, 1023, "SELECT ");
@ -540,7 +550,7 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx)
oom |= Query->Append(" FROM ");
oom |= Query->Append(tk);
oom |= Query->Append(Tabname);
oom |= Query->Append(TableName);
oom |= Query->Append(tk);
len = Query->GetLength();
@ -608,7 +618,7 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
} // endif colp
// Below 40 is enough to contain the fixed part of the query
len += (strlen(Tabname) + 40);
len += (strlen(TableName) + 40);
Query = new(g) STRING(g, len);
if (Delayed)
@ -617,7 +627,7 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
oom = Query->Set("INSERT INTO ");
oom |= Query->Append(tk);
oom |= Query->Append(Tabname);
oom |= Query->Append(TableName);
oom |= Query->Append("` (");
for (colp = Columns; colp; colp = colp->GetNext()) {
@ -653,11 +663,11 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
/* MakeCommand: make the Update or Delete statement to send to the */
/* MySQL server. Limited to remote values and filtering. */
/***********************************************************************/
int TDBMYSQL::MakeCommand(PGLOBAL g)
bool TDBMYSQL::MakeCommand(PGLOBAL g)
{
Query = new(g) STRING(g, strlen(Qrystr) + 64);
if (Quoted > 0 || stricmp(Name, Tabname)) {
if (Quoted > 0 || stricmp(Name, TableName)) {
char *p, *qrystr, name[68];
bool qtd = Quoted > 0;
@ -678,29 +688,29 @@ int TDBMYSQL::MakeCommand(PGLOBAL g)
if (qtd && *(p-1) == ' ') {
oom |= Query->Append('`');
oom |= Query->Append(Tabname);
oom |= Query->Append(TableName);
oom |= Query->Append('`');
} else
oom |= Query->Append(Tabname);
oom |= Query->Append(TableName);
oom |= Query->Append(Qrystr + (p - qrystr) + strlen(name));
if (oom) {
strcpy(g->Message, "MakeCommand: Out of memory");
return RC_FX;
return true;
} else
strlwr(strcpy(qrystr, Query->GetStr()));
} else {
sprintf(g->Message, "Cannot use this %s command",
(Mode == MODE_UPDATE) ? "UPDATE" : "DELETE");
return RC_FX;
return true;
} // endif p
} else
(void)Query->Set(Qrystr);
return RC_OK;
return false;
} // end of MakeCommand
#if 0
@ -727,7 +737,7 @@ int TDBMYSQL::MakeUpdate(PGLOBAL g)
} // endif sscanf
assert(!stricmp(cmd, "update"));
strcat(strcat(strcat(strcpy(Query, "UPDATE "), qc), Tabname), qc);
strcat(strcat(strcat(strcpy(Query, "UPDATE "), qc), TableName), qc);
strcat(Query, end);
return RC_OK;
} // end of MakeUpdate
@ -754,7 +764,7 @@ int TDBMYSQL::MakeDelete(PGLOBAL g)
} // endif sscanf
assert(!stricmp(cmd, "delete") && !stricmp(from, "from"));
strcat(strcat(strcat(strcpy(Query, "DELETE FROM "), qc), Tabname), qc);
strcat(strcat(strcat(strcpy(Query, "DELETE FROM "), qc), TableName), qc);
if (*end)
strcat(Query, end);
@ -776,15 +786,15 @@ int TDBMYSQL::Cardinality(PGLOBAL g)
char query[96];
MYSQLC myc;
if (myc.Open(g, Host, Database, User, Pwd, Port, csname))
if (myc.Open(g, Host, Schema, User, Pwd, Port, csname))
return -1;
strcpy(query, "SELECT COUNT(*) FROM ");
if (Quoted > 0)
strcat(strcat(strcat(query, "`"), Tabname), "`");
strcat(strcat(strcat(query, "`"), TableName), "`");
else
strcat(query, Tabname);
strcat(query, TableName);
Cardinal = myc.GetTableSize(g, query);
myc.Close();
@ -794,6 +804,7 @@ int TDBMYSQL::Cardinality(PGLOBAL g)
return Cardinal;
} // end of Cardinality
#if 0
/***********************************************************************/
/* MYSQL GetMaxSize: returns the maximum number of rows in the table. */
/***********************************************************************/
@ -812,6 +823,7 @@ int TDBMYSQL::GetMaxSize(PGLOBAL g)
return MaxSize;
} // end of GetMaxSize
#endif // 0
/***********************************************************************/
/* This a fake routine as ROWID does not exist in MySQL. */
@ -872,7 +884,7 @@ bool TDBMYSQL::OpenDB(PGLOBAL g)
/* servers allowing concurency in getting results ??? */
/*********************************************************************/
if (!Myc.Connected()) {
if (Myc.Open(g, Host, Database, User, Pwd, Port, csname))
if (Myc.Open(g, Host, Schema, User, Pwd, Port, csname))
return true;
} // endif Connected
@ -931,14 +943,14 @@ bool TDBMYSQL::OpenDB(PGLOBAL g)
char cmd[64];
int w;
sprintf(cmd, "ALTER TABLE `%s` DISABLE KEYS", Tabname);
sprintf(cmd, "ALTER TABLE `%s` DISABLE KEYS", TableName);
m_Rc = Myc.ExecSQL(g, cmd, &w); // may fail for some engines
} // endif m_Rc
} else
// m_Rc = (Mode == MODE_DELETE) ? MakeDelete(g) : MakeUpdate(g);
m_Rc = MakeCommand(g);
m_Rc = (MakeCommand(g)) ? RC_FX : RC_OK;
if (m_Rc == RC_FX) {
Myc.Close();
@ -1030,7 +1042,7 @@ int TDBMYSQL::SendCommand(PGLOBAL g)
if (Myc.ExecSQLcmd(g, Query->GetStr(), &w) == RC_NF) {
AftRows = Myc.m_Afrw;
sprintf(g->Message, "%s: %d affected rows", Tabname, AftRows);
sprintf(g->Message, "%s: %d affected rows", TableName, AftRows);
PushWarning(g, this, 0); // 0 means a Note
if (trace)
@ -1039,7 +1051,7 @@ int TDBMYSQL::SendCommand(PGLOBAL g)
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,
sprintf(g->Message, "%s: (%s) %s", TableName,
Myc.GetCharField(1), Myc.GetCharField(2));
PushWarning(g, this);
} // endwhile Fetch
@ -1116,8 +1128,7 @@ int TDBMYSQL::ReadDB(PGLOBAL g)
int rc;
if (trace > 1)
htrc("MySQL ReadDB: R%d Mode=%d key=%p link=%p Kindex=%p\n",
GetTdb_No(), Mode, To_Key_Col, To_Link, To_Kindex);
htrc("MySQL ReadDB: R%d Mode=%d\n", GetTdb_No(), Mode);
if (Mode == MODE_UPDATE || Mode == MODE_DELETE)
return SendCommand(g);
@ -1205,7 +1216,7 @@ void TDBMYSQL::CloseDB(PGLOBAL g)
PDBUSER dup = PlgGetUser(g);
dup->Step = "Enabling indexes";
sprintf(cmd, "ALTER TABLE `%s` ENABLE KEYS", Tabname);
sprintf(cmd, "ALTER TABLE `%s` ENABLE KEYS", TableName);
Myc.m_Rows = -1; // To execute the query
m_Rc = Myc.ExecSQL(g, cmd, &w); // May fail for some engines
} // endif m_Rc
@ -1463,7 +1474,7 @@ TDBMYEXC::TDBMYEXC(PMYDEF tdp) : TDBMYSQL(tdp)
Havew = false;
Isw = false;
Warnings = 0;
Mxr = tdp->Mxr;
Mxr = tdp->Maxerr;
Nerr = 0;
} // end of TDBMYEXC constructor
@ -1479,7 +1490,7 @@ TDBMYEXC::TDBMYEXC(PTDBMYX tdbp) : TDBMYSQL(tdbp)
} // end of TDBMYEXC copy constructor
// Is this really useful ???
PTDB TDBMYEXC::CopyOne(PTABS t)
PTDB TDBMYEXC::Clone(PTABS t)
{
PTDB tp;
PCOL cp1, cp2;
@ -1494,7 +1505,7 @@ PTDB TDBMYEXC::CopyOne(PTABS t)
} // endfor cp1
return tp;
} // end of CopyOne
} // end of Clone
/***********************************************************************/
/* Allocate MYSQL column description block. */
@ -1565,7 +1576,7 @@ bool TDBMYEXC::OpenDB(PGLOBAL g)
/* servers allowing concurency in getting results ??? */
/*********************************************************************/
if (!Myc.Connected())
if (Myc.Open(g, Host, Database, User, Pwd, Port))
if (Myc.Open(g, Host, Schema, User, Pwd, Port))
return true;
Use = USE_OPEN; // Do it now in case we are recursively called
@ -1728,7 +1739,7 @@ void MYXCOL::WriteColumn(PGLOBAL)
TDBMCL::TDBMCL(PMYDEF tdp) : TDBCAT(tdp)
{
Host = tdp->Hostname;
Db = tdp->Database;
Db = tdp->Tabschema;
Tab = tdp->Tabname;
User = tdp->Username;
Pwd = tdp->Password;

View file

@ -1,4 +1,4 @@
// TDBMYSQL.H Olivier Bertrand 2007-2014
// TDBMYSQL.H Olivier Bertrand 2007-2017
#include "myconn.h" // MySQL connection declares
typedef class MYSQLDEF *PMYDEF;
@ -18,7 +18,7 @@ typedef class MYSQLC *PMYC;
/***********************************************************************/
/* MYSQL table. */
/***********************************************************************/
class MYSQLDEF : public TABDEF {/* Logical table description */
class MYSQLDEF : public EXTDEF {/* Logical table description */
friend class TDBMYSQL;
friend class TDBMYEXC;
friend class TDBMCL;
@ -27,19 +27,18 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
// Constructor
MYSQLDEF(void);
// Implementation
virtual const char *GetType(void) {return "MYSQL";}
inline PSZ GetHostname(void) {return Hostname;};
inline PSZ GetDatabase(void) {return Database;};
inline PSZ GetTabname(void) {return Tabname;}
inline PSZ GetSrcdef(void) {return Srcdef;}
inline PSZ GetUsername(void) {return Username;};
inline PSZ GetPassword(void) {return Password;};
//inline PSZ GetDatabase(void) {return Tabschema;};
//inline PSZ GetTabname(void) {return Tabname;}
//inline PSZ GetSrcdef(void) {return Srcdef;}
//inline PSZ GetUsername(void) {return Username;};
//inline PSZ GetPassword(void) {return Password;};
inline int GetPortnumber(void) {return Portnumber;}
// Methods
virtual int Indexable(void) {return 2;}
//virtual int Indexable(void) {return 2;}
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE m);
bool ParseURL(PGLOBAL g, char *url, bool b = true);
@ -48,27 +47,27 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
protected:
// Members
PSZ Hostname; /* Host machine to use */
PSZ Database; /* Database to be used by server */
PSZ Tabname; /* External table name */
PSZ Srcdef; /* The source table SQL definition */
PSZ Username; /* User logon name */
PSZ Password; /* Password logon info */
//PSZ Tabschema; /* Database to be used by server */
//PSZ Tabname; /* External table name */
//PSZ Srcdef; /* The source table SQL definition */
//PSZ Username; /* User logon name */
//PSZ Password; /* Password logon info */
PSZ Server; /* PServerID */
PSZ Qrystr; /* The original query */
//PSZ Qrystr; /* The original query */
int Portnumber; /* MySQL port number (0 = default) */
int Mxr; /* Maxerr for an Exec table */
int Quoted; /* Identifier quoting level */
//int Maxerr; /* Maxerr for an Exec table */
//int Quoted; /* Identifier quoting level */
bool Isview; /* true if this table is a MySQL view */
bool Bind; /* Use prepared statement on insert */
bool Delayed; /* Delayed insert */
bool Xsrc; /* Execution type */
//bool Xsrc; /* Execution type */
bool Huge; /* True for big table */
}; // end of MYSQLDEF
/***********************************************************************/
/* This is the class declaration for the MYSQL table. */
/***********************************************************************/
class TDBMYSQL : public TDBASE {
class TDBMYSQL : public TDBEXT {
friend class MYSQLCOL;
public:
// Constructor
@ -80,7 +79,7 @@ class TDBMYSQL : public TDBASE {
virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBMYSQL(this);}
// Methods
virtual PTDB CopyOne(PTABS t);
virtual PTDB Clone(PTABS t);
//virtual int GetAffectedRows(void) {return AftRows;}
virtual int GetRecpos(void) {return N;}
virtual int GetProgMax(PGLOBAL g);
@ -88,12 +87,12 @@ class TDBMYSQL : public TDBASE {
virtual int RowNumber(PGLOBAL g, bool b = false);
virtual bool IsView(void) {return Isview;}
virtual PSZ GetServer(void) {return Server;}
void SetDatabase(LPCSTR db) {Database = (char*)db;}
void SetDatabase(LPCSTR db) {Schema = (char*)db;}
// Database routines
// Schema routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
virtual int Cardinality(PGLOBAL g);
virtual int GetMaxSize(PGLOBAL g);
//virtual int GetMaxSize(PGLOBAL g);
virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g);
virtual int WriteDB(PGLOBAL g);
@ -111,7 +110,7 @@ class TDBMYSQL : public TDBASE {
bool MakeSelect(PGLOBAL g, bool mx);
bool MakeInsert(PGLOBAL g);
int BindColumns(PGLOBAL g);
int MakeCommand(PGLOBAL g);
virtual bool MakeCommand(PGLOBAL g);
//int MakeUpdate(PGLOBAL g);
//int MakeDelete(PGLOBAL g);
int SendCommand(PGLOBAL g);
@ -119,25 +118,25 @@ class TDBMYSQL : public TDBASE {
// Members
MYSQLC Myc; // MySQL connection class
MYSQL_BIND *Bind; // To the MySQL bind structure array
PSTRG Query; // Constructed SQL query
//PSTRG Query; // Constructed SQL query
char *Host; // Host machine to use
char *User; // User logon info
char *Pwd; // Password logon info
char *Database; // Database to be used by server
char *Tabname; // External table name
char *Srcdef; // The source table SQL definition
//char *User; // User logon info
//char *Pwd; // Password logon info
//char *Schema; // Database to be used by server
//char *TableName; // External table name
//char *Srcdef; // The source table SQL definition
char *Server; // The server ID
char *Qrystr; // The original query
//char *Qrystr; // The original query
bool Fetched; // True when fetch was done
bool Isview; // True if this table is a MySQL view
bool Prep; // Use prepared statement on insert
bool Delayed; // Use delayed insert
int m_Rc; // Return code from command
int AftRows; // The number of affected rows
//int AftRows; // The number of affected rows
int N; // The current table index
int Port; // MySQL port number (0 = default)
int Nparm; // The number of statement parameters
int Quoted; // The identifier quoting level
//int Nparm; // The number of statement parameters
//int Quoted; // The identifier quoting level
}; // end of class TDBMYSQL
/***********************************************************************/
@ -162,9 +161,6 @@ class MYSQLCOL : public COLBLK {
bool FindRank(PGLOBAL g);
protected:
// Default constructor not to be used
MYSQLCOL(void) {}
// Members
MYSQL_BIND *Bind; // This column bind structure pointer
PVAL To_Val; // To value used for Update/Insert
@ -187,7 +183,7 @@ class TDBMYEXC : public TDBMYSQL {
virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBMYEXC(this);}
// Methods
virtual PTDB CopyOne(PTABS t);
virtual PTDB Clone(PTABS t);
virtual bool IsView(void) {return Isview;}
// Database routines
@ -228,9 +224,6 @@ class MYXCOL : public MYSQLCOL {
virtual void WriteColumn(PGLOBAL g);
protected:
// Default constructor not to be used
MYXCOL(void) {}
// Members
char *Buffer; // To get returned message
int Flag; // Column content desc

View file

@ -1,7 +1,7 @@
/************ TabOccur CPP Declares Source Code File (.CPP) ************/
/* Name: TABOCCUR.CPP Version 1.1 */
/* Name: TABOCCUR.CPP Version 1.2 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2013 - 2015 */
/* (C) Copyright to the author Olivier BERTRAND 2013 - 2017 */
/* */
/* OCCUR: Table that provides a view of a source table where the */
/* contain of several columns of the source table is placed in only */
@ -39,12 +39,13 @@
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
#include "reldef.h"
#include "xtable.h"
#include "tabext.h"
//#include "reldef.h"
#include "filamtxt.h"
#include "tabdos.h"
#include "tabcol.h"
#include "taboccur.h"
#include "xtable.h"
#include "tabmysql.h"
#include "ha_connect.h"

View file

@ -67,10 +67,11 @@
#include "plgdbsem.h"
#include "mycat.h"
#include "xtable.h"
#include "tabext.h"
#include "odbccat.h"
#include "tabodbc.h"
#include "tabmul.h"
#include "reldef.h"
//#include "reldef.h"
#include "tabcol.h"
#include "valblk.h"
#include "ha_connect.h"
@ -95,10 +96,9 @@ bool ExactInfo(void);
/***********************************************************************/
ODBCDEF::ODBCDEF(void)
{
Connect = Tabname = Tabschema = Username = Password = NULL;
Tabcat = Colpat = Srcdef = Qchar = Qrystr = Sep = NULL;
Catver = Options = Cto = Qto = Quoted = Maxerr = Maxres = Memory = 0;
Scrollable = Xsrc = UseCnc = false;
Connect = NULL;
Catver = 0;
UseCnc = false;
} // end of ODBCDEF constructor
/***********************************************************************/
@ -113,47 +113,50 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
return true;
} // endif Connect
Tabname = GetStringCatInfo(g, "Name",
(Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
Tabname = GetStringCatInfo(g, "Tabname", Tabname);
Tabschema = GetStringCatInfo(g, "Dbname", NULL);
Tabschema = GetStringCatInfo(g, "Schema", Tabschema);
Tabcat = GetStringCatInfo(g, "Qualifier", NULL);
Tabcat = GetStringCatInfo(g, "Catalog", Tabcat);
Username = GetStringCatInfo(g, "User", NULL);
Password = GetStringCatInfo(g, "Password", NULL);
if (EXTDEF::DefineAM(g, am, poff))
return true;
if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL)))
Read_Only = true;
// Tabname = GetStringCatInfo(g, "Name",
// (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
// Tabname = GetStringCatInfo(g, "Tabname", Tabname);
// Tabschema = GetStringCatInfo(g, "Dbname", NULL);
// Tabschema = GetStringCatInfo(g, "Schema", Tabschema);
// Tabcat = GetStringCatInfo(g, "Qualifier", NULL);
// Tabcat = GetStringCatInfo(g, "Catalog", Tabcat);
//Username = GetStringCatInfo(g, "User", NULL);
// Password = GetStringCatInfo(g, "Password", NULL);
Qrystr = GetStringCatInfo(g, "Query_String", "?");
Sep = GetStringCatInfo(g, "Separator", NULL);
// if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL)))
// Read_Only = true;
// Qrystr = GetStringCatInfo(g, "Query_String", "?");
// Sep = GetStringCatInfo(g, "Separator", NULL);
Catver = GetIntCatInfo("Catver", 2);
Xsrc = GetBoolCatInfo("Execsrc", FALSE);
Maxerr = GetIntCatInfo("Maxerr", 0);
Maxres = GetIntCatInfo("Maxres", 0);
Quoted = GetIntCatInfo("Quoted", 0);
//Xsrc = GetBoolCatInfo("Execsrc", FALSE);
//Maxerr = GetIntCatInfo("Maxerr", 0);
//Maxres = GetIntCatInfo("Maxres", 0);
//Quoted = GetIntCatInfo("Quoted", 0);
Options = ODBConn::noOdbcDialog;
//Options = ODBConn::noOdbcDialog | ODBConn::useCursorLib;
Cto= GetIntCatInfo("ConnectTimeout", DEFAULT_LOGIN_TIMEOUT);
Qto= GetIntCatInfo("QueryTimeout", DEFAULT_QUERY_TIMEOUT);
if ((Scrollable = GetBoolCatInfo("Scrollable", false)) && !Elemt)
Elemt = 1; // Cannot merge SQLFetch and SQLExtendedFetch
//if ((Scrollable = GetBoolCatInfo("Scrollable", false)) && !Elemt)
// Elemt = 1; // Cannot merge SQLFetch and SQLExtendedFetch
if (Catfunc == FNC_COL)
Colpat = GetStringCatInfo(g, "Colpat", NULL);
//if (Catfunc == FNC_COL)
// Colpat = GetStringCatInfo(g, "Colpat", NULL);
if (Catfunc == FNC_TABLE)
Tabtyp = GetStringCatInfo(g, "Tabtype", NULL);
//if (Catfunc == FNC_TABLE)
// Tabtyp = GetStringCatInfo(g, "Tabtype", NULL);
UseCnc = GetBoolCatInfo("UseDSN", false);
// Memory was Boolean, it is now integer
if (!(Memory = GetIntCatInfo("Memory", 0)))
Memory = GetBoolCatInfo("Memory", false) ? 1 : 0;
//if (!(Memory = GetIntCatInfo("Memory", 0)))
// Memory = GetBoolCatInfo("Memory", false) ? 1 : 0;
Pseudo = 2; // FILID is Ok but not ROWID
//Pseudo = 2; // FILID is Ok but not ROWID
return false;
} // end of DefineAM
@ -162,7 +165,7 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
/***********************************************************************/
PTDB ODBCDEF::GetTable(PGLOBAL g, MODE m)
{
PTDBASE tdbp = NULL;
PTDB tdbp = NULL;
/*********************************************************************/
/* Allocate a TDB of the proper type. */
@ -200,103 +203,103 @@ PTDB ODBCDEF::GetTable(PGLOBAL g, MODE m)
/***********************************************************************/
/* Implementation of the TDBODBC class. */
/***********************************************************************/
TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp)
TDBODBC::TDBODBC(PODEF tdp) : TDBEXT(tdp)
{
Ocp = NULL;
Cnp = NULL;
if (tdp) {
Connect = tdp->Connect;
TableName = tdp->Tabname;
Schema = tdp->Tabschema;
//TableName = tdp->Tabname;
//Schema = tdp->Tabschema;
Ops.User = tdp->Username;
Ops.Pwd = tdp->Password;
Catalog = tdp->Tabcat;
Srcdef = tdp->Srcdef;
Qrystr = tdp->Qrystr;
Sep = tdp->GetSep();
Options = tdp->Options;
//Catalog = tdp->Tabcat;
//Srcdef = tdp->Srcdef;
//Qrystr = tdp->Qrystr;
//Sep = tdp->GetSep();
//Options = tdp->Options;
Ops.Cto = tdp->Cto;
Ops.Qto = tdp->Qto;
Quoted = MY_MAX(0, tdp->GetQuoted());
Rows = tdp->GetElemt();
//Quoted = MY_MAX(0, tdp->GetQuoted());
//Rows = tdp->GetElemt();
Catver = tdp->Catver;
Memory = tdp->Memory;
Scrollable = tdp->Scrollable;
//Memory = tdp->Memory;
//Scrollable = tdp->Scrollable;
Ops.UseCnc = tdp->UseCnc;
} else {
Connect = NULL;
TableName = NULL;
Schema = NULL;
//TableName = NULL;
//Schema = NULL;
Ops.User = NULL;
Ops.Pwd = NULL;
Catalog = NULL;
Srcdef = NULL;
Qrystr = NULL;
Sep = 0;
Options = 0;
//Catalog = NULL;
//Srcdef = NULL;
//Qrystr = NULL;
//Sep = 0;
//Options = 0;
Ops.Cto = DEFAULT_LOGIN_TIMEOUT;
Ops.Qto = DEFAULT_QUERY_TIMEOUT;
Quoted = 0;
Rows = 0;
//Quoted = 0;
//Rows = 0;
Catver = 0;
Memory = 0;
Scrollable = false;
//Memory = 0;
//Scrollable = false;
Ops.UseCnc = false;
} // endif tdp
Quote = NULL;
Query = NULL;
Count = NULL;
//Quote = NULL;
//Query = NULL;
//Count = NULL;
//Where = NULL;
MulConn = NULL;
DBQ = NULL;
Qrp = NULL;
Fpos = 0;
Curpos = 0;
AftRows = 0;
CurNum = 0;
Rbuf = 0;
BufSize = 0;
Nparm = 0;
Placed = false;
//MulConn = NULL;
//DBQ = NULL;
//Qrp = NULL;
//Fpos = 0;
//Curpos = 0;
//AftRows = 0;
//CurNum = 0;
//Rbuf = 0;
//BufSize = 0;
//Nparm = 0;
//Placed = false;
} // end of TDBODBC standard constructor
TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp)
TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBEXT(tdbp)
{
Ocp = tdbp->Ocp; // is that right ?
Cnp = tdbp->Cnp;
Connect = tdbp->Connect;
TableName = tdbp->TableName;
Schema = tdbp->Schema;
//TableName = tdbp->TableName;
//Schema = tdbp->Schema;
Ops = tdbp->Ops;
Catalog = tdbp->Catalog;
Srcdef = tdbp->Srcdef;
Qrystr = tdbp->Qrystr;
Memory = tdbp->Memory;
Scrollable = tdbp->Scrollable;
Quote = tdbp->Quote;
Query = tdbp->Query;
Count = tdbp->Count;
//Catalog = tdbp->Catalog;
//Srcdef = tdbp->Srcdef;
//Qrystr = tdbp->Qrystr;
//Memory = tdbp->Memory;
//Scrollable = tdbp->Scrollable;
//Quote = tdbp->Quote;
//Query = tdbp->Query;
//Count = tdbp->Count;
//Where = tdbp->Where;
MulConn = tdbp->MulConn;
DBQ = tdbp->DBQ;
Options = tdbp->Options;
Quoted = tdbp->Quoted;
Rows = tdbp->Rows;
Fpos = 0;
Curpos = 0;
AftRows = 0;
CurNum = 0;
Rbuf = 0;
BufSize = tdbp->BufSize;
Nparm = tdbp->Nparm;
Qrp = tdbp->Qrp;
Placed = false;
//MulConn = tdbp->MulConn;
//DBQ = tdbp->DBQ;
//Options = tdbp->Options;
//Quoted = tdbp->Quoted;
//Rows = tdbp->Rows;
//Fpos = 0;
//Curpos = 0;
//AftRows = 0;
//CurNum = 0;
//Rbuf = 0;
//BufSize = tdbp->BufSize;
//Nparm = tdbp->Nparm;
//Qrp = tdbp->Qrp;
//Placed = false;
} // end of TDBODBC copy constructor
// Method
PTDB TDBODBC::CopyOne(PTABS t)
PTDB TDBODBC::Clone(PTABS t)
{
PTDB tp;
PODBCCOL cp1, cp2;
@ -386,6 +389,7 @@ void TDBODBC::SetFile(PGLOBAL g, PSZ fn)
DBQ = fn;
} // end of SetFile
#if 0
/******************************************************************/
/* Convert an UTF-8 string to latin characters. */
/******************************************************************/
@ -414,7 +418,15 @@ bool TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
PCOL colp;
if (Srcdef) {
Query = new(g)STRING(g, 0, Srcdef);
if (strstr(Srcdef, "%s")) {
char *fil;
fil = (To_CondFil) ? To_CondFil->Body : PlugDup(g, "1=1");
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil));
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil));
} else
Query = new(g)STRING(g, 0, Srcdef);
return false;
} // endif Srcdef
@ -442,7 +454,8 @@ bool TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
} else
oom |= Query->Append(buf);
} // endif colp
((PEXTCOL)colp)->SetRank(++Ncol);
} // endif colp
} else
// !Columns can occur for queries such that sql count(*) from...
@ -458,10 +471,6 @@ bool TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
if (Catalog && *Catalog)
catp = Catalog;
// Following lines are commented because of MSDEV-10520
// Indeed the schema in the tablep is the local table database and
// is normally not related to the remote table database.
// TODO: Try to remember why this was done and if it was useful in some case.
//if (tablep->GetSchema())
// schmp = (char*)tablep->GetSchema();
//else
@ -516,6 +525,7 @@ bool TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
return false;
} // end of MakeSQL
#endif // 0
/***********************************************************************/
/* MakeInsert: make the Insert statement used with ODBC connection. */
@ -536,7 +546,7 @@ bool TDBODBC::MakeInsert(PGLOBAL g)
// Column name can be encoded in UTF-8
Decode(colp->GetName(), buf, sizeof(buf));
len += (strlen(buf) + 6); // comma + quotes + valist
((PODBCCOL)colp)->Rank = ++Nparm;
((PEXTCOL)colp)->SetRank(++Nparm);
} // endif colp
// Below 32 is enough to contain the fixed part of the query
@ -555,7 +565,7 @@ bool TDBODBC::MakeInsert(PGLOBAL g)
if (schmp)
len += strlen(schmp) + 1;
// Column name can be encoded in UTF-8
// Table name can be encoded in UTF-8
Decode(TableName, buf, sizeof(buf));
len += (strlen(buf) + 32);
Query = new(g) STRING(g, len, "INSERT INTO ");
@ -634,6 +644,7 @@ bool TDBODBC::BindParameters(PGLOBAL g)
return false;
} // end of BindParameters
#if 0
/***********************************************************************/
/* MakeCommand: make the Update or Delete statement to send to the */
/* MySQL server. Limited to remote values and filtering. */
@ -664,19 +675,20 @@ bool TDBODBC::MakeCommand(PGLOBAL g)
// 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 (strstr(" update delete low_priority ignore quick from ", name)) {
strlwr(strcat(strcat(strcpy(name, qc), Name), qc));
k += 2;
} else
strlwr(strcpy(name, Name)); // Not a keyword
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);
k += i + (int)strlen(Name);
if (qtd && *(p-1) == ' ')
if (qtd && *(p - 1) == ' ')
strcat(strcat(strcat(stmt, qc), TableName), qc);
else
strcat(stmt, TableName);
@ -692,15 +704,14 @@ bool TDBODBC::MakeCommand(PGLOBAL g)
} else {
sprintf(g->Message, "Cannot use this %s command",
(Mode == MODE_UPDATE) ? "UPDATE" : "DELETE");
return false;
(Mode == MODE_UPDATE) ? "UPDATE" : "DELETE");
return true;
} // endif p
Query = new(g) STRING(g, 0, stmt);
return (!Query->GetSize());
} // end of MakeCommand
#if 0
/***********************************************************************/
/* MakeUpdate: make the SQL statement to send to ODBC connection. */
/***********************************************************************/
@ -818,6 +829,7 @@ int TDBODBC::Cardinality(PGLOBAL g)
return Cardinal;
} // end of Cardinality
#if 0
/***********************************************************************/
/* ODBC GetMaxSize: returns table size estimate in number of lines. */
/***********************************************************************/
@ -844,6 +856,7 @@ int TDBODBC::GetProgMax(PGLOBAL g)
{
return GetMaxSize(g);
} // end of GetProgMax
#endif // 0
/***********************************************************************/
/* ODBC Access Method opening routine. */
@ -981,6 +994,7 @@ bool TDBODBC::OpenDB(PGLOBAL g)
return false;
} // end of OpenDB
#if 0
/***********************************************************************/
/* GetRecpos: return the position of last read record. */
/***********************************************************************/
@ -988,6 +1002,7 @@ int TDBODBC::GetRecpos(void)
{
return Fpos;
} // end of GetRecpos
#endif // 0
/***********************************************************************/
/* SetRecpos: set the position of next read record. */
@ -1081,8 +1096,9 @@ int TDBODBC::ReadDB(PGLOBAL g)
int rc;
if (trace > 1)
htrc("ODBC ReadDB: R%d Mode=%d key=%p link=%p Kindex=%p\n",
GetTdb_No(), Mode, To_Key_Col, To_Link, To_Kindex);
htrc("ODBC ReadDB: R%d Mode=%d\n", GetTdb_No(), Mode);
//htrc("ODBC ReadDB: R%d Mode=%d key=%p link=%p Kindex=%p\n",
// GetTdb_No(), Mode, To_Key_Col, To_Link, To_Kindex);
if (Mode == MODE_UPDATE || Mode == MODE_DELETE) {
if (!Query && MakeCommand(g))
@ -1102,11 +1118,11 @@ int TDBODBC::ReadDB(PGLOBAL g)
} // endif Mode
if (To_Kindex) {
// Direct access of ODBC tables is not implemented yet
strcpy(g->Message, MSG(NO_ODBC_DIRECT));
return RC_FX;
} // endif To_Kindex
//if (To_Kindex) {
// // Direct access of ODBC tables is not implemented yet
// strcpy(g->Message, MSG(NO_ODBC_DIRECT));
// return RC_FX;
// } // endif To_Kindex
/*********************************************************************/
/* Now start the reading process. */
@ -1212,70 +1228,58 @@ void TDBODBC::CloseDB(PGLOBAL g)
/* ODBCCOL public constructor. */
/***********************************************************************/
ODBCCOL::ODBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
: COLBLK(cdp, tdbp, i)
: EXTCOL(cdp, tdbp, cprec, i, am)
{
if (cprec) {
Next = cprec->GetNext();
cprec->SetNext(this);
} else {
Next = tdbp->GetColumns();
tdbp->SetColumns(this);
} // endif cprec
// Set additional ODBC access method information for column.
Crp = NULL;
//Long = cdp->GetLong();
Long = Precision;
//Crp = NULL;
//Long = Precision;
//strcpy(F_Date, cdp->F_Date);
To_Val = NULL;
//To_Val = NULL;
Slen = 0;
StrLen = &Slen;
Sqlbuf = NULL;
Bufp = NULL;
Blkp = NULL;
Rank = 0; // Not known yet
if (trace)
htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this);
//Bufp = NULL;
//Blkp = NULL;
//Rank = 0; // Not known yet
} // end of ODBCCOL constructor
/***********************************************************************/
/* ODBCCOL private constructor. */
/***********************************************************************/
ODBCCOL::ODBCCOL(void) : COLBLK()
ODBCCOL::ODBCCOL(void) : EXTCOL()
{
Crp = NULL;
Buf_Type = TYPE_INT; // This is a count(*) column
// Set additional Dos access method information for column.
Long = sizeof(int);
To_Val = NULL;
//Crp = NULL;
//Buf_Type = TYPE_INT; // This is a count(*) column
//// Set additional Dos access method information for column.
//Long = sizeof(int);
//To_Val = NULL;
Slen = 0;
StrLen = &Slen;
Sqlbuf = NULL;
Bufp = NULL;
Blkp = NULL;
Rank = 1;
//Bufp = NULL;
//Blkp = NULL;
//Rank = 1;
} // end of ODBCCOL constructor
/***********************************************************************/
/* ODBCCOL constructor used for copying columns. */
/* tdbp is the pointer to the new table descriptor. */
/***********************************************************************/
ODBCCOL::ODBCCOL(ODBCCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp)
ODBCCOL::ODBCCOL(ODBCCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp)
{
Crp = col1->Crp;
Long = col1->Long;
//Crp = col1->Crp;
//Long = col1->Long;
//strcpy(F_Date, col1->F_Date);
To_Val = col1->To_Val;
//To_Val = col1->To_Val;
Slen = col1->Slen;
StrLen = col1->StrLen;
Sqlbuf = col1->Sqlbuf;
Bufp = col1->Bufp;
Blkp = col1->Blkp;
Rank = col1->Rank;
//Bufp = col1->Bufp;
//Blkp = col1->Blkp;
//Rank = col1->Rank;
} // end of ODBCCOL copy constructor
#if 0
/***********************************************************************/
/* SetBuffer: prepare a column block for write operation. */
/***********************************************************************/
@ -1321,6 +1325,7 @@ bool ODBCCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
Status = (ok) ? BUF_EMPTY : BUF_NO;
return false;
} // end of SetBuffer
#endif // 0
/***********************************************************************/
/* ReadColumn: when SQLFetch is used there is nothing to do as the */
@ -1526,7 +1531,7 @@ TDBXDBC::TDBXDBC(PTDBXDBC tdbp) : TDBODBC(tdbp)
Nerr = tdbp->Nerr;
} // end of TDBXDBC copy constructor
PTDB TDBXDBC::CopyOne(PTABS t)
PTDB TDBXDBC::Clone(PTABS t)
{
PTDB tp;
PXSRCCOL cp1, cp2;

View file

@ -20,7 +20,7 @@ typedef class TDBSRC *PTDBSRC;
/***********************************************************************/
/* ODBC table. */
/***********************************************************************/
class DllExport ODBCDEF : public TABDEF { /* Logical table description */
class DllExport ODBCDEF : public EXTDEF { /* Logical table description */
friend class TDBODBC;
friend class TDBXDBC;
friend class TDBDRV;
@ -33,14 +33,14 @@ public:
// Implementation
virtual const char *GetType(void) {return "ODBC";}
PSZ GetConnect(void) {return Connect;}
PSZ GetTabname(void) {return Tabname;}
PSZ GetTabschema(void) {return Tabschema;}
PSZ GetTabcat(void) {return Tabcat;}
PSZ GetSrcdef(void) {return Srcdef;}
char GetSep(void) {return (Sep) ? *Sep : 0;}
int GetQuoted(void) {return Quoted;}
//PSZ GetTabname(void) {return Tabname;}
//PSZ GetTabschema(void) {return Tabschema;}
//PSZ GetTabcat(void) {return Tabcat;}
//PSZ GetSrcdef(void) {return Srcdef;}
//char GetSep(void) {return (Sep) ? *Sep : 0;}
//int GetQuoted(void) {return Quoted;}
int GetCatver(void) {return Catver;}
int GetOptions(void) {return Options;}
//int GetOptions(void) {return Options;}
// Methods
virtual int Indexable(void) {return 2;}
@ -50,27 +50,27 @@ public:
protected:
// Members
PSZ Connect; /* ODBC connection string */
PSZ Tabname; /* External table name */
PSZ Tabschema; /* External table schema */
PSZ Username; /* User connect name */
PSZ Password; /* Password connect info */
PSZ Tabcat; /* External table catalog */
PSZ Tabtyp; /* Catalog table type */
PSZ Colpat; /* Catalog column pattern */
PSZ Srcdef; /* The source table SQL definition */
PSZ Qchar; /* Identifier quoting character */
PSZ Qrystr; /* The original query */
PSZ Sep; /* Decimal separator */
//PSZ Tabname; /* External table name */
//PSZ Tabschema; /* External table schema */
//PSZ Username; /* User connect name */
//PSZ Password; /* Password connect info */
//PSZ Tabcat; /* External table catalog */
//PSZ Tabtyp; /* Catalog table type */
//PSZ Colpat; /* Catalog column pattern */
//PSZ Srcdef; /* The source table SQL definition */
//PSZ Qchar; /* Identifier quoting character */
//PSZ Qrystr; /* The original query */
//PSZ Sep; /* Decimal separator */
int Catver; /* ODBC version for catalog functions */
int Options; /* Open connection options */
int Cto; /* Open connection timeout */
int Qto; /* Query (command) timeout */
int Quoted; /* Identifier quoting level */
int Maxerr; /* Maxerr for an Exec table */
int Maxres; /* Maxres for a catalog table */
int Memory; /* Put result set in memory */
bool Scrollable; /* Use scrollable cursor */
bool Xsrc; /* Execution type */
//int Options; /* Open connection options */
//int Cto; /* Open connection timeout */
//int Qto; /* Query (command) timeout */
//int Quoted; /* Identifier quoting level */
//int Maxerr; /* Maxerr for an Exec table */
//int Maxres; /* Maxres for a catalog table */
//int Memory; /* Put result set in memory */
//bool Scrollable; /* Use scrollable cursor */
//bool Xsrc; /* Execution type */
bool UseCnc; /* Use SQLConnect (!SQLDriverConnect) */
}; // end of ODBCDEF
@ -81,7 +81,7 @@ public:
/* This is the ODBC Access Method class declaration for files from */
/* other DB drivers to be accessed via ODBC. */
/***********************************************************************/
class TDBODBC : public TDBASE {
class TDBODBC : public TDBEXT {
friend class ODBCCOL;
friend class ODBConn;
public:
@ -95,8 +95,8 @@ class TDBODBC : public TDBASE {
{return (PTDB)new(g) TDBODBC(this);}
// Methods
virtual PTDB CopyOne(PTABS t);
virtual int GetRecpos(void);
virtual PTDB Clone(PTABS t);
//virtual int GetRecpos(void);
virtual bool SetRecpos(PGLOBAL g, int recpos);
virtual PSZ GetFile(PGLOBAL g);
virtual void SetFile(PGLOBAL g, PSZ fn);
@ -108,8 +108,8 @@ class TDBODBC : public TDBASE {
// Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
virtual int Cardinality(PGLOBAL g);
virtual int GetMaxSize(PGLOBAL g);
virtual int GetProgMax(PGLOBAL g);
//virtual int GetMaxSize(PGLOBAL g);
//virtual int GetProgMax(PGLOBAL g);
virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g);
virtual int WriteDB(PGLOBAL g);
@ -119,10 +119,10 @@ class TDBODBC : public TDBASE {
protected:
// Internal functions
int Decode(char *utf, char *buf, size_t n);
bool MakeSQL(PGLOBAL g, bool cnt);
//int Decode(char *utf, char *buf, size_t n);
//bool MakeSQL(PGLOBAL g, bool cnt);
bool MakeInsert(PGLOBAL g);
bool MakeCommand(PGLOBAL g);
//virtual bool MakeCommand(PGLOBAL g);
//bool MakeFilter(PGLOBAL g, bool c);
bool BindParameters(PGLOBAL g);
//char *MakeUpdate(PGLOBAL g);
@ -132,46 +132,16 @@ class TDBODBC : public TDBASE {
ODBConn *Ocp; // Points to an ODBC connection class
ODBCCOL *Cnp; // Points to count(*) column
ODBCPARM Ops; // Additional parameters
PSTRG Query; // Constructed SQL query
char *Connect; // Points to connection string
char *TableName; // Points to ODBC table name
char *Schema; // Points to ODBC table Schema
char *User; // User connect info
char *Pwd; // Password connect info
char *Catalog; // Points to ODBC table Catalog
char *Srcdef; // The source table SQL definition
char *Count; // Points to count(*) SQL statement
//char *Where; // Points to local where clause
char *Quote; // The identifier quoting character
char *MulConn; // Used for multiple ODBC tables
char *DBQ; // The address part of Connect string
char *Qrystr; // The original query
char Sep; // The decimal separator
int Options; // Connect options
int Cto; // Connect timeout
int Qto; // Query timeout
int Quoted; // The identifier quoting level
int Fpos; // Position of last read record
int Curpos; // Cursor position of last fetch
int AftRows; // The number of affected rows
int Rows; // Rowset size
int Catver; // Catalog ODBC version
int CurNum; // Current buffer line number
int Rbuf; // Number of lines read in buffer
int BufSize; // Size of connect string buffer
int Nparm; // The number of statement parameters
int Memory; // 0: No 1: Alloc 2: Put 3: Get
bool Scrollable; // Use scrollable cursor
bool Placed; // True for position reading
bool UseCnc; // Use SQLConnect (!SQLDriverConnect)
PQRYRES Qrp; // Points to storage result
}; // end of class TDBODBC
/***********************************************************************/
/* Class ODBCCOL: ODBC access method column descriptor. */
/* This A.M. is used for ODBC tables. */
/***********************************************************************/
class ODBCCOL : public COLBLK {
class ODBCCOL : public EXTCOL {
friend class TDBODBC;
public:
// Constructors
@ -181,12 +151,12 @@ class ODBCCOL : public COLBLK {
// Implementation
virtual int GetAmType(void) {return TYPE_AM_ODBC;}
SQLLEN *GetStrLen(void) {return StrLen;}
int GetRank(void) {return Rank;}
// int GetRank(void) {return Rank;}
// PVBLK GetBlkp(void) {return Blkp;}
void SetCrp(PCOLRES crp) {Crp = crp;}
// void SetCrp(PCOLRES crp) {Crp = crp;}
// Methods
virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
//virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
virtual void ReadColumn(PGLOBAL g);
virtual void WriteColumn(PGLOBAL g);
void AllocateBuffers(PGLOBAL g, int rows);
@ -195,19 +165,19 @@ class ODBCCOL : public COLBLK {
// void Print(PGLOBAL g, FILE *, uint);
protected:
// Constructor used by GetMaxSize
// Constructor for count(*) column
ODBCCOL(void);
// Members
TIMESTAMP_STRUCT *Sqlbuf; // To get SQL_TIMESTAMP's
PCOLRES Crp; // To storage result
void *Bufp; // To extended buffer
PVBLK Blkp; // To Value Block
//PCOLRES Crp; // To storage result
//void *Bufp; // To extended buffer
//PVBLK Blkp; // To Value Block
//char F_Date[12]; // Internal Date format
PVAL To_Val; // To value used for Insert
//PVAL To_Val; // To value used for Insert
SQLLEN *StrLen; // As returned by ODBC
SQLLEN Slen; // Used with Fetch
int Rank; // Rank (position) number in the query
//int Rank; // Rank (position) number in the query
}; // end of class ODBCCOL
/***********************************************************************/
@ -228,28 +198,19 @@ class TDBXDBC : public TDBODBC {
{return (PTDB)new(g) TDBXDBC(this);}
// Methods
virtual PTDB CopyOne(PTABS t);
//virtual int GetRecpos(void);
//virtual PSZ GetFile(PGLOBAL g);
//virtual void SetFile(PGLOBAL g, PSZ fn);
//virtual void ResetSize(void);
//virtual int GetAffectedRows(void) {return AftRows;}
//virtual PSZ GetServer(void) {return "ODBC";}
virtual PTDB Clone(PTABS t);
// Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
//virtual int GetProgMax(PGLOBAL g);
virtual int GetMaxSize(PGLOBAL g);
virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g);
virtual int WriteDB(PGLOBAL g);
virtual int DeleteDB(PGLOBAL g, int irc);
//virtual void CloseDB(PGLOBAL g);
protected:
// Internal functions
PCMD MakeCMD(PGLOBAL g);
//bool BindParameters(PGLOBAL g);
// Members
PCMD Cmdlist; // The commands to execute

View file

@ -1,11 +1,11 @@
/************ TabPivot C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: TABPIVOT */
/* ------------- */
/* Version 1.6 */
/* Version 1.7 */
/* */
/* COPYRIGHT: */
/* ---------- */
/* (C) Copyright to the author Olivier BERTRAND 2005-2015 */
/* (C) Copyright to the author Olivier BERTRAND 2005-2017 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@ -41,6 +41,7 @@
#include "global.h"
#include "plgdbsem.h"
#include "xtable.h"
#include "tabext.h"
#include "tabcol.h"
#include "colblk.h"
#include "tabmysql.h"
@ -883,7 +884,7 @@ SRCCOL::SRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int n)
/***********************************************************************/
/* Initialize the column as pointing to the source column. */
/***********************************************************************/
bool SRCCOL::Init(PGLOBAL g, PTDBASE tp)
bool SRCCOL::Init(PGLOBAL g, PTDB tp)
{
if (PRXCOL::Init(g, tp))
return true;

View file

@ -183,7 +183,7 @@ class SRCCOL : public PRXCOL {
using PRXCOL::Init;
virtual void Reset(void) {}
void SetColumn(void);
virtual bool Init(PGLOBAL g, PTDBASE tp);
virtual bool Init(PGLOBAL g, PTDB tp);
bool CompareLast(void);
protected:

View file

@ -159,7 +159,7 @@ TDBINI::TDBINI(PTDBINI tdbp) : TDBASE(tdbp)
} // end of TDBINI copy constructor
// Is this really useful ???
PTDB TDBINI::CopyOne(PTABS t)
PTDB TDBINI::Clone(PTABS t)
{
PTDB tp;
PINICOL cp1, cp2;
@ -173,7 +173,7 @@ PTDB TDBINI::CopyOne(PTABS t)
} // endfor cp1
return tp;
} // end of CopyOne
} // end of Clone
/***********************************************************************/
/* Get the section list from the INI file. */
@ -565,7 +565,7 @@ TDBXIN::TDBXIN(PTDBXIN tdbp) : TDBINI(tdbp)
} // end of TDBXIN copy constructor
// Is this really useful ???
PTDB TDBXIN::CopyOne(PTABS t)
PTDB TDBXIN::Clone(PTABS t)
{
PTDB tp;
PXINCOL cp1, cp2;
@ -579,7 +579,7 @@ PTDB TDBXIN::CopyOne(PTABS t)
} // endfor cp1
return tp;
} // end of CopyOne
} // end of Clone
/***********************************************************************/
/* Get the key list from the INI file. */

View file

@ -57,7 +57,7 @@ class TDBINI : public TDBASE {
virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBINI(this);}
// Methods
virtual PTDB CopyOne(PTABS t);
virtual PTDB Clone(PTABS t);
virtual int GetRecpos(void) {return N;}
virtual int GetProgCur(void) {return N;}
//virtual int GetAffectedRows(void) {return 0;}
@ -136,7 +136,7 @@ class TDBXIN : public TDBINI {
virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBXIN(this);}
// Methods
virtual PTDB CopyOne(PTABS t);
virtual PTDB Clone(PTABS t);
virtual int GetRecpos(void);
virtual bool SetRecpos(PGLOBAL g, int recpos);
virtual void ResetDB(void)

View file

@ -1,11 +1,11 @@
/************* TabTbl C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABTBL */
/* ------------- */
/* Version 1.7 */
/* Version 1.8 */
/* */
/* COPYRIGHT: */
/* ---------- */
/* (C) Copyright to PlugDB Software Development 2008-2016 */
/* (C) Copyright to PlugDB Software Development 2008-2017 */
/* Author: Olivier BERTRAND */
/* */
/* WHAT THIS PROGRAM DOES: */
@ -70,6 +70,7 @@
#include "tabcol.h"
#include "tabdos.h" // TDBDOS and DOSCOL class dcls
#include "tabtbl.h"
#include "tabext.h"
#include "tabmysql.h"
#include "ha_connect.h"
@ -411,9 +412,9 @@ void TDBTBL::ResetDB(void)
colp->COLBLK::Reset();
for (PTABLE tabp = Tablist; tabp; tabp = tabp->GetNext())
((PTDBASE)tabp->GetTo_Tdb())->ResetDB();
tabp->GetTo_Tdb()->ResetDB();
Tdbp = (PTDBASE)Tablist->GetTo_Tdb();
Tdbp = Tablist->GetTo_Tdb();
Crp = 0;
} // end of ResetDB
@ -458,7 +459,7 @@ bool TDBTBL::OpenDB(PGLOBAL g)
return TRUE;
if ((CurTable = Tablist)) {
Tdbp = (PTDBASE)CurTable->GetTo_Tdb();
Tdbp = CurTable->GetTo_Tdb();
// Tdbp->SetMode(Mode);
// Tdbp->ResetDB();
// Tdbp->ResetSize();
@ -515,7 +516,7 @@ int TDBTBL::ReadDB(PGLOBAL g)
/* Continue reading from next table file. */
/***************************************************************/
Tdbp->CloseDB(g);
Tdbp = (PTDBASE)CurTable->GetTo_Tdb();
Tdbp = CurTable->GetTo_Tdb();
// Check and initialize the subtable columns
for (PCOL cp = Columns; cp; cp = cp->GetNext())
@ -609,13 +610,13 @@ void TDBTBM::ResetDB(void)
// Local tables
for (PTABLE tabp = Tablist; tabp; tabp = tabp->GetNext())
((PTDBASE)tabp->GetTo_Tdb())->ResetDB();
tabp->GetTo_Tdb()->ResetDB();
// Remote tables
for (PTBMT tp = Tmp; tp; tp = tp->Next)
((PTDBASE)tp->Tap->GetTo_Tdb())->ResetDB();
tp->Tap->GetTo_Tdb()->ResetDB();
Tdbp = (Tablist) ? (PTDBASE)Tablist->GetTo_Tdb() : NULL;
Tdbp = (Tablist) ? Tablist->GetTo_Tdb() : NULL;
Crp = 0;
} // end of ResetDB
@ -716,7 +717,7 @@ bool TDBTBM::OpenDB(PGLOBAL g)
/* Proceed with local tables. */
/*********************************************************************/
if ((CurTable = Tablist)) {
Tdbp = (PTDBASE)CurTable->GetTo_Tdb();
Tdbp = CurTable->GetTo_Tdb();
// Tdbp->SetMode(Mode);
// Check and initialize the subtable columns
@ -808,7 +809,7 @@ int TDBTBM::ReadNextRemote(PGLOBAL g)
} // endif Curtable
Tdbp = (PTDBASE)Cmp->Tap->GetTo_Tdb();
Tdbp = Cmp->Tap->GetTo_Tdb();
// Check and initialize the subtable columns
for (PCOL cp = Columns; cp; cp = cp->GetNext())

View file

@ -1,7 +1,7 @@
/************* Tabutil cpp Declares Source Code File (.CPP) ************/
/* Name: TABUTIL.CPP Version 1.1 */
/* Name: TABUTIL.CPP Version 1.2 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2013 - 2016 */
/* (C) Copyright to the author Olivier BERTRAND 2013 - 2017 */
/* */
/* Utility function used by the PROXY, XCOL, OCCUR, and TBL tables. */
/***********************************************************************/
@ -45,8 +45,9 @@
#include "myutil.h"
#include "valblk.h"
#include "resource.h"
#include "reldef.h"
//#include "reldef.h"
#include "xtable.h"
#include "tabext.h"
#include "tabmysql.h"
#include "tabcol.h"
#include "tabutil.h"
@ -356,7 +357,7 @@ TDBPRX::TDBPRX(PTDBPRX tdbp) : TDBASE(tdbp)
} // end of TDBPRX copy constructor
// Method
PTDB TDBPRX::CopyOne(PTABS t)
PTDB TDBPRX::Clone(PTABS t)
{
PTDB tp;
PPRXCOL cp1, cp2;
@ -370,12 +371,12 @@ PTDB TDBPRX::CopyOne(PTABS t)
} // endfor cp1
return tp;
} // end of CopyOne
} // end of Clone
/***********************************************************************/
/* Get the PTDB of the sub-table. */
/***********************************************************************/
PTDBASE TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp, bool b)
PTDB TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp, bool b)
{
const char *sp = NULL;
char *db, *name;
@ -456,13 +457,13 @@ PTDBASE TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp, bool b)
if (trace && tdbp)
htrc("Subtable %s in %s\n",
name, SVP(((PTDBASE)tdbp)->GetDef()->GetDB()));
name, SVP(tdbp->GetDef()->GetDB()));
err:
if (s)
free_table_share(s);
return (PTDBASE)tdbp;
return tdbp;
} // end of GetSubTable
/***********************************************************************/
@ -560,9 +561,9 @@ bool TDBPRX::OpenDB(PGLOBAL g)
/* its column blocks in mode write (required by XML tables). */
/*********************************************************************/
if (Mode == MODE_UPDATE) {
PTDBASE utp;
PTDB utp;
if (!(utp= (PTDBASE)Tdbp->Duplicate(g))) {
if (!(utp= Tdbp->Duplicate(g))) {
sprintf(g->Message, MSG(INV_UPDT_TABLE), Tdbp->GetName());
return true;
} // endif tp
@ -681,7 +682,7 @@ char *PRXCOL::Decode(PGLOBAL g, const char *cnm)
/* PRXCOL initialization routine. */
/* Look for the matching column in the object table. */
/***********************************************************************/
bool PRXCOL::Init(PGLOBAL g, PTDBASE tp)
bool PRXCOL::Init(PGLOBAL g, PTDB tp)
{
if (!tp)
tp = ((PTDBPRX)To_Tdb)->Tdbp;

View file

@ -67,7 +67,7 @@ class DllExport TDBPRX : public TDBASE {
{return (PTDB)new(g) TDBPRX(this);}
// Methods
virtual PTDB CopyOne(PTABS t);
virtual PTDB Clone(PTABS t);
virtual int GetRecpos(void) {return Tdbp->GetRecpos();}
virtual void ResetDB(void) {Tdbp->ResetDB();}
virtual int RowNumber(PGLOBAL g, bool b = FALSE);
@ -83,12 +83,12 @@ class DllExport TDBPRX : public TDBASE {
virtual int WriteDB(PGLOBAL g);
virtual int DeleteDB(PGLOBAL g, int irc);
virtual void CloseDB(PGLOBAL g) {if (Tdbp) Tdbp->CloseDB(g);}
PTDBASE GetSubTable(PGLOBAL g, PTABLE tabp, bool b = false);
PTDB GetSubTable(PGLOBAL g, PTABLE tabp, bool b = false);
void RemoveNext(PTABLE tp);
protected:
// Members
PTDBASE Tdbp; // The object table
PTDB Tdbp; // The object table
}; // end of class TDBPRX
/***********************************************************************/
@ -115,7 +115,7 @@ class DllExport PRXCOL : public COLBLK {
{return false;}
virtual void ReadColumn(PGLOBAL g);
virtual void WriteColumn(PGLOBAL g);
virtual bool Init(PGLOBAL g, PTDBASE tp);
virtual bool Init(PGLOBAL g, PTDB tp);
protected:
char *Decode(PGLOBAL g, const char *cnm);

View file

@ -241,7 +241,7 @@ PTDB VCTDEF::GetTable(PGLOBAL g, MODE mode)
/*********************************************************************/
if (mode != MODE_INSERT)
if (tdbp->GetBlockValues(g))
PushWarning(g, (PTDBASE)tdbp);
PushWarning(g, tdbp);
// return NULL; // causes a crash when deleting index
return tdbp;
@ -263,7 +263,7 @@ TDBVCT::TDBVCT(PGLOBAL g, PTDBVCT tdbp) : TDBFIX(g, tdbp)
} // end of TDBVCT copy constructor
// Method
PTDB TDBVCT::CopyOne(PTABS t)
PTDB TDBVCT::Clone(PTABS t)
{
PTDB tp;
PVCTCOL cp1, cp2;
@ -277,7 +277,7 @@ PTDB TDBVCT::CopyOne(PTABS t)
} // endfor cp1
return tp;
} // end of CopyOne
} // end of Clone
/***********************************************************************/
/* Allocate VCT column description block. */

View file

@ -68,7 +68,7 @@ class DllExport TDBVCT : public TDBFIX {
bool IsSplit(void) {return ((VCTDEF*)To_Def)->Split;}
// Methods
virtual PTDB CopyOne(PTABS t);
virtual PTDB Clone(PTABS t);
virtual bool IsUsingTemp(PGLOBAL g);
// Database routines

View file

@ -20,7 +20,7 @@
#include "plgdbsem.h"
#include "filter.h"
#include "xtable.h"
#include "reldef.h"
//#include "reldef.h"
#include "colblk.h"
#include "mycat.h" // for FNC_COL
#include "tabvir.h"

View file

@ -1,5 +1,5 @@
/***********************************************************************/
/* TABWMI: Author Olivier Bertrand -- PlugDB -- 2012 - 2013 */
/* TABWMI: Author Olivier Bertrand -- PlugDB -- 2012 - 2017 */
/* TABWMI: Virtual table to get WMI information. */
/***********************************************************************/
#if !defined(__WIN__)
@ -11,8 +11,9 @@
#include "global.h"
#include "plgdbsem.h"
#include "mycat.h"
#include "reldef.h"
//#include "reldef.h"
#include "xtable.h"
#include "tabext.h"
#include "colblk.h"
//#include "filter.h"
//#include "xindex.h"

View file

@ -1,7 +1,7 @@
/************* TabXcl CPP Declares Source Code File (.CPP) *************/
/* Name: TABXCL.CPP Version 1.0 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2013 */
/* (C) Copyright to the author Olivier BERTRAND 2013-2017 */
/* */
/* XCOL: Table having one column containing several values */
/* comma separated. When creating the table, the name of the X */
@ -45,12 +45,12 @@
#include "plgdbsem.h"
#include "plgcnx.h" // For DB types
#include "resource.h"
#include "reldef.h"
#include "xtable.h"
#include "tabext.h"
#include "filamtxt.h"
#include "tabdos.h"
#include "tabcol.h"
#include "tabxcl.h"
#include "xtable.h"
#include "tabmysql.h"
#include "ha_connect.h"
@ -246,7 +246,7 @@ XCLCOL::XCLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
/* XCLCOL initialization routine. */
/* Allocate Cbuf that will contain the Colp value. */
/***********************************************************************/
bool XCLCOL::Init(PGLOBAL g, PTDBASE tp)
bool XCLCOL::Init(PGLOBAL g, PTDB tp)
{
if (PRXCOL::Init(g, tp))
return true;

View file

@ -91,7 +91,7 @@ class XCLCOL : public PRXCOL {
using PRXCOL::Init;
virtual void Reset(void) {} // Evaluated only by TDBXCL
virtual void ReadColumn(PGLOBAL g);
virtual bool Init(PGLOBAL g, PTDBASE tp = NULL);
virtual bool Init(PGLOBAL g, PTDB tp = NULL);
protected:
// Default constructor not to be used

View file

@ -42,7 +42,7 @@
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
#include "reldef.h"
//#include "reldef.h"
#include "xtable.h"
#include "colblk.h"
#include "mycat.h"
@ -660,7 +660,7 @@ TDBXML::TDBXML(PTDBXML tdbp) : TDBASE(tdbp)
} // end of TDBXML copy constructor
// Used for update
PTDB TDBXML::CopyOne(PTABS t)
PTDB TDBXML::Clone(PTABS t)
{
PTDB tp;
PXMLCOL cp1, cp2;
@ -674,7 +674,7 @@ PTDB TDBXML::CopyOne(PTABS t)
} // endfor cp1
return tp;
} // end of CopyOne
} // end of Clone
/***********************************************************************/
/* Allocate XML column description block. */

View file

@ -71,7 +71,7 @@ class DllExport TDBXML : public TDBASE {
virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBXML(this);}
// Methods
virtual PTDB CopyOne(PTABS t);
virtual PTDB Clone(PTABS t);
virtual int GetRecpos(void);
virtual int GetProgCur(void) {return N;}
virtual PSZ GetFile(PGLOBAL g) {return Xfile;}

View file

@ -81,7 +81,7 @@ int PlgMakeIndex(PGLOBAL g, PSZ name, PIXDEF pxdf, bool add)
{
int rc;
PTABLE tablep;
PTDBASE tdbp;
PTDB tdbp;
PCATLG cat = PlgGetCatalog(g, true);
/*********************************************************************/
@ -89,12 +89,12 @@ int PlgMakeIndex(PGLOBAL g, PSZ name, PIXDEF pxdf, bool add)
/*********************************************************************/
tablep = new(g) XTAB(name);
if (!(tdbp = (PTDBASE)cat->GetTable(g, tablep)))
if (!(tdbp = cat->GetTable(g, tablep)))
rc = RC_NF;
else if (!tdbp->GetDef()->Indexable()) {
sprintf(g->Message, MSG(TABLE_NO_INDEX), name);
rc = RC_NF;
} else if ((rc = tdbp->MakeIndex(g, pxdf, add)) == RC_INFO)
} else if ((rc = ((PTDBASE)tdbp)->MakeIndex(g, pxdf, add)) == RC_INFO)
rc = RC_OK; // No or remote index
return rc;

View file

@ -184,7 +184,7 @@ class DllExport XXBASE : public CSORT, public BLOCK {
virtual bool IsRandom(void) {return true;}
virtual bool IsDynamic(void) {return Dynamic;}
virtual void SetDynamic(bool dyn) {Dynamic = dyn;}
virtual bool HaveSame(void) {return false;}
//virtual bool HaveSame(void) {return false;}
virtual int GetCurPos(void) {return Cur_K;}
virtual void SetNval(int n) {assert(n == 1);}
virtual void SetOp(OPVAL op) {Op = op;}
@ -256,7 +256,7 @@ class DllExport XINDEX : public XXBASE {
// Implementation
virtual IDT GetType(void) {return TYPE_IDX_INDX;}
virtual bool IsMul(void) {return (Nval < Nk) ? true : Mul;}
virtual bool HaveSame(void) {return Op == OP_SAME;}
//virtual bool HaveSame(void) {return Op == OP_SAME;}
virtual int GetCurPos(void) {return (Pex) ? Pex[Cur_K] : Cur_K;}
virtual void SetNval(int n) {Nval = n;}
int GetMaxSame(void) {return MaxSame;}

View file

@ -127,7 +127,8 @@ class DllExport STRING : public BLOCK {
// Implementation
inline int GetLength(void) {return (int)Length;}
inline PSZ GetStr(void) {return Strp;}
inline void SetLength(uint n) {Length = n;}
inline PSZ GetStr(void) {return Strp;}
inline uint32 GetSize(void) {return Size;}
// Methods

View file

@ -1,7 +1,7 @@
/**************** Table H Declares Source Code File (.H) ***************/
/* Name: TABLE.H Version 2.3 */
/* Name: TABLE.H Version 2.4 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 1999-2015 */
/* (C) Copyright to the author Olivier BERTRAND 1999-2017 */
/* */
/* This file contains the TBX, OPJOIN and TDB class definitions. */
/***********************************************************************/
@ -17,6 +17,7 @@
#include "block.h"
#include "colblk.h"
#include "m_ctype.h"
#include "reldef.h"
typedef class CMD *PCMD;
typedef struct st_key_range key_range;
@ -32,24 +33,30 @@ class CMD : public BLOCK {
char *Cmd;
}; // end of class CMD
#if 0
// Condition filter structure
class CONDFIL : public BLOCK {
public:
// Constructor
CONDFIL(const Item *cond, uint idx, AMT type)
{
Cond = cond; Idx = idx; Type = type; Body = NULL; Op = OP_XX; Cmds = NULL;
Cond = cond; Idx = idx; Type = type; Op = OP_XX;
Cmds = NULL; All = true; Body = NULL, Having = NULL;
}
// Members
const Item *Cond;
AMT Type;
uint Idx;
char *Body;
OPVAL Op;
PCMD Cmds;
bool All;
char *Body;
char *Having;
}; // end of class CONDFIL
#endif // 0
typedef class EXTCOL *PEXTCOL;
typedef class CONDFIL *PCFIL;
typedef class TDBCAT *PTDBCAT;
typedef class CATCOL *PCATCOL;
@ -64,47 +71,61 @@ class DllExport TDB: public BLOCK { // Table Descriptor Block.
TDB(PTDB tdbp);
// Implementation
static void SetTnum(int n) {Tnum = n;}
inline PTDB GetOrig(void) {return To_Orig;}
inline TUSE GetUse(void) {return Use;}
inline PCFIL GetCondFil(void) {return To_CondFil;}
inline LPCSTR GetName(void) {return Name;}
inline PTABLE GetTable(void) {return To_Table;}
inline PCOL GetColumns(void) {return Columns;}
inline int GetDegree(void) {return Degree;}
inline MODE GetMode(void) {return Mode;}
inline PFIL GetFilter(void) {return To_Filter;}
inline void SetFilter(PFIL fp) {To_Filter = fp;}
inline void SetOrig(PTDB txp) {To_Orig = txp;}
inline void SetUse(TUSE n) {Use = n;}
inline void SetCondFil(PCFIL cfp) {To_CondFil = cfp;}
inline void SetNext(PTDB tdbp) {Next = tdbp;}
inline void SetName(LPCSTR name) {Name = name;}
inline void SetTable(PTABLE tablep) {To_Table = tablep;}
inline void SetColumns(PCOL colp) {Columns = colp;}
inline void SetDegree(int degree) {Degree = degree;}
inline void SetMode(MODE mode) {Mode = mode;}
static void SetTnum(int n) {Tnum = n;}
inline PTABDEF GetDef(void) {return To_Def;}
inline PTDB GetOrig(void) {return To_Orig;}
inline TUSE GetUse(void) {return Use;}
inline PCFIL GetCondFil(void) {return To_CondFil;}
inline LPCSTR GetName(void) {return Name;}
inline PTABLE GetTable(void) {return To_Table;}
inline PCOL GetColumns(void) {return Columns;}
inline int GetDegree(void) {return Degree;}
inline MODE GetMode(void) {return Mode;}
inline PFIL GetFilter(void) {return To_Filter;}
inline PCOL GetSetCols(void) {return To_SetCols;}
inline void SetSetCols(PCOL colp) {To_SetCols = colp;}
inline void SetFilter(PFIL fp) {To_Filter = fp;}
inline void SetOrig(PTDB txp) {To_Orig = txp;}
inline void SetUse(TUSE n) {Use = n;}
inline void SetCondFil(PCFIL cfp) {To_CondFil = cfp;}
inline void SetNext(PTDB tdbp) {Next = tdbp;}
inline void SetName(LPCSTR name) {Name = name;}
inline void SetTable(PTABLE tablep) {To_Table = tablep;}
inline void SetColumns(PCOL colp) {Columns = colp;}
inline void SetDegree(int degree) {Degree = degree;}
inline void SetMode(MODE mode) {Mode = mode;}
// Properties
virtual AMT GetAmType(void) {return TYPE_AM_ERROR;}
virtual int GetTdb_No(void) {return Tdb_No;}
virtual PTDB GetNext(void) {return Next;}
virtual PCATLG GetCat(void) {return NULL;}
virtual void SetAbort(bool) {;}
virtual AMT GetAmType(void) {return TYPE_AM_ERROR;}
virtual bool IsRemote(void) {return false;}
virtual bool IsIndexed(void) {return false;}
virtual int GetTdb_No(void) {return Tdb_No;}
virtual PTDB GetNext(void) {return Next;}
virtual PCATLG GetCat(void) {return NULL;}
virtual void SetAbort(bool) {;}
virtual PKXBASE GetKindex(void) {return NULL;}
// Methods
virtual bool IsSame(PTDB tp) {return tp == this;}
virtual bool IsSpecial(PSZ name) = 0;
virtual bool GetBlockValues(PGLOBAL) {return false;}
virtual bool IsSpecial(PSZ name);
virtual bool IsReadOnly(void) {return Read_Only;}
virtual bool IsView(void) {return FALSE;}
virtual PSZ GetPath(void);
virtual RECFM GetFtype(void) {return RECFM_NAF;}
virtual bool GetBlockValues(PGLOBAL) { return false; }
virtual int Cardinality(PGLOBAL) {return 0;}
virtual int GetMaxSize(PGLOBAL) = 0;
virtual int GetRecpos(void) = 0;
virtual bool SetRecpos(PGLOBAL g, int recpos);
virtual int GetMaxSize(PGLOBAL) = 0;
virtual int GetProgMax(PGLOBAL) = 0;
virtual int GetProgCur(void) = 0;
virtual int RowNumber(PGLOBAL g, bool b = false);
virtual bool IsReadOnly(void) {return true;}
virtual const CHARSET_INFO *data_charset() {return NULL;}
virtual int GetProgCur(void) {return GetRecpos();}
virtual PSZ GetFile(PGLOBAL) {return "Not a file";}
virtual void SetFile(PGLOBAL, PSZ) {}
virtual void ResetDB(void) {}
virtual void ResetSize(void) {MaxSize = -1;}
virtual int RowNumber(PGLOBAL g, bool b = false);
virtual PTDB Duplicate(PGLOBAL) {return NULL;}
virtual PTDB CopyOne(PTABS) {return this;}
virtual PTDB Clone(PTABS) {return this;}
virtual PTDB Copy(PTABS t);
virtual void PrintAM(FILE *f, char *m)
{fprintf(f, "%s AM(%d)\n", m, GetAmType());}
@ -112,10 +133,15 @@ class DllExport TDB: public BLOCK { // Table Descriptor Block.
virtual void Print(PGLOBAL g, char *ps, uint z);
virtual PSZ GetServer(void) = 0;
virtual int GetBadLines(void) {return 0;}
virtual CHARSET_INFO *data_charset(void);
// Database pure virtual routines
virtual PCOL ColDB(PGLOBAL g, PSZ name, int num) = 0;
virtual void MarkDB(PGLOBAL, PTDB) = 0;
// Database routines
virtual PCOL ColDB(PGLOBAL g, PSZ name, int num);
virtual PCOL MakeCol(PGLOBAL, PCOLDEF, PCOL, int)
{assert(false); return NULL;}
virtual PCOL InsertSpecialColumn(PCOL colp);
virtual PCOL InsertSpcBlk(PGLOBAL g, PCOLDEF cdp);
virtual void MarkDB(PGLOBAL g, PTDB tdb2);
virtual bool OpenDB(PGLOBAL) = 0;
virtual int ReadDB(PGLOBAL) = 0;
virtual int WriteDB(PGLOBAL) = 0;
@ -126,20 +152,26 @@ class DllExport TDB: public BLOCK { // Table Descriptor Block.
protected:
// Members
PTDB To_Orig; // Pointer to original if it is a copy
TUSE Use;
PFIL To_Filter;
PCFIL To_CondFil; // To condition filter structure
static int Tnum; // Used to generate Tdb_no's
const int Tdb_No; // GetTdb_No() is always 0 for OPJOIN
PTDB Next; // Next in linearized queries
PTABLE To_Table; // Points to the XTAB object
LPCSTR Name; // Table name
PCOL Columns; // Points to the first column of the table
MODE Mode; // 10 Read, 30 Update, 40 Insert, 50 Delete
int Degree; // Number of columns
int Cardinal; // Table number of rows
}; // end of class TDB
PTDB To_Orig; // Pointer to original if it is a copy
PTABDEF To_Def; // Points to catalog description block
TUSE Use;
PFIL To_Filter;
PCFIL To_CondFil; // To condition filter structure
static int Tnum; // Used to generate Tdb_no's
const int Tdb_No; // GetTdb_No() is always 0 for OPJOIN
PTDB Next; // Next in linearized queries
PTABLE To_Table; // Points to the XTAB object
LPCSTR Name; // Table name
PCOL Columns; // Points to the first column of the table
PCOL To_SetCols; // Points to updated columns
MODE Mode; // 10 Read, 30 Update, 40 Insert, 50 Delete
int Degree; // Number of columns
int Cardinal; // Table number of rows
int MaxSize; // Max size in number of lines
bool Read_Only; // True for read only tables
const CHARSET_INFO *m_data_charset;
const char *csname; // Table charset name
}; // end of class TDB
/***********************************************************************/
/* This is the base class for all query tables (except decode). */
@ -155,50 +187,50 @@ class DllExport TDBASE : public TDB {
// Implementation
inline int GetKnum(void) {return Knum;}
inline PTABDEF GetDef(void) {return To_Def;}
inline PKXBASE GetKindex(void) {return To_Kindex;}
inline PCOL GetSetCols(void) {return To_SetCols;}
inline void SetSetCols(PCOL colp) {To_SetCols = colp;}
//inline PTABDEF GetDef(void) {return To_Def;}
//inline PCOL GetSetCols(void) {return To_SetCols;}
//inline void SetSetCols(PCOL colp) {To_SetCols = colp;}
inline void SetKey_Col(PCOL *cpp) {To_Key_Col = cpp;}
inline void SetXdp(PIXDEF xdp) {To_Xdp = xdp;}
inline void SetKindex(PKXBASE kxp) {To_Kindex = kxp;}
// Properties
void ResetKindex(PGLOBAL g, PKXBASE kxp);
virtual PKXBASE GetKindex(void) {return To_Kindex;}
void ResetKindex(PGLOBAL g, PKXBASE kxp);
PCOL Key(int i) {return (To_Key_Col) ? To_Key_Col[i] : NULL;}
// Methods
virtual bool IsUsingTemp(PGLOBAL) {return false;}
virtual bool IsIndexed(void) {return false;}
virtual bool IsSpecial(PSZ name);
//virtual bool IsIndexed(void) {return false;}
//virtual bool IsSpecial(PSZ name);
virtual PCATLG GetCat(void);
virtual PSZ GetPath(void);
//virtual PSZ GetPath(void);
virtual void PrintAM(FILE *f, char *m);
virtual RECFM GetFtype(void) {return RECFM_NAF;}
//virtual RECFM GetFtype(void) {return RECFM_NAF;}
//virtual int GetAffectedRows(void) {return -1;}
virtual int GetRecpos(void) = 0;
virtual bool SetRecpos(PGLOBAL g, int recpos);
virtual bool IsReadOnly(void) {return Read_Only;}
virtual bool IsView(void) {return FALSE;}
virtual CHARSET_INFO *data_charset(void);
//virtual int GetRecpos(void) = 0;
//virtual bool SetRecpos(PGLOBAL g, int recpos);
//virtual bool IsReadOnly(void) {return Read_Only;}
//virtual bool IsView(void) {return FALSE;}
//virtual CHARSET_INFO *data_charset(void);
virtual int GetProgMax(PGLOBAL g) {return GetMaxSize(g);}
virtual int GetProgCur(void) {return GetRecpos();}
virtual PSZ GetFile(PGLOBAL) {return "Not a file";}
virtual int GetRemote(void) {return 0;}
virtual void SetFile(PGLOBAL, PSZ) {}
virtual void ResetDB(void) {}
virtual void ResetSize(void) {MaxSize = -1;}
//virtual int GetProgCur(void) {return GetRecpos();}
//virtual PSZ GetFile(PGLOBAL) {return "Not a file";}
//virtual int GetRemote(void) {return 0;}
//virtual void SetFile(PGLOBAL, PSZ) {}
//virtual void ResetDB(void) {}
//virtual void ResetSize(void) {MaxSize = -1;}
virtual void RestoreNrec(void) {}
virtual int ResetTableOpt(PGLOBAL g, bool dop, bool dox);
virtual PSZ GetServer(void) {return "Current";}
// Database routines
virtual PCOL ColDB(PGLOBAL g, PSZ name, int num);
virtual PCOL MakeCol(PGLOBAL, PCOLDEF, PCOL, int)
{assert(false); return NULL;}
virtual PCOL InsertSpecialColumn(PCOL colp);
virtual PCOL InsertSpcBlk(PGLOBAL g, PCOLDEF cdp);
virtual void MarkDB(PGLOBAL g, PTDB tdb2);
//virtual PCOL ColDB(PGLOBAL g, PSZ name, int num);
//virtual PCOL MakeCol(PGLOBAL, PCOLDEF, PCOL, int)
// {assert(false); return NULL;}
//virtual PCOL InsertSpecialColumn(PCOL colp);
//virtual PCOL InsertSpcBlk(PGLOBAL g, PCOLDEF cdp);
//virtual void MarkDB(PGLOBAL g, PTDB tdb2);
virtual int MakeIndex(PGLOBAL g, PIXDEF, bool)
{strcpy(g->Message, "Remote index"); return RC_INFO;}
virtual bool ReadKey(PGLOBAL, OPVAL, const key_range *)
@ -209,19 +241,19 @@ class DllExport TDBASE : public TDB {
"This function should not be called for this table"); return true;}
// Members
PTABDEF To_Def; // Points to catalog description block
//PTABDEF To_Def; // Points to catalog description block
PXOB *To_Link; // Points to column of previous relations
PCOL *To_Key_Col; // Points to key columns in current file
PKXBASE To_Kindex; // Points to table key index
PIXDEF To_Xdp; // To the index definition block
PCOL To_SetCols; // Points to updated columns
//PCOL To_SetCols; // Points to updated columns
RECFM Ftype; // File type: 0-var 1-fixed 2-binary (VCT)
int MaxSize; // Max size in number of lines
//int MaxSize; // Max size in number of lines
int Knum; // Size of key arrays
bool Read_Only; // True for read only tables
const CHARSET_INFO *m_data_charset;
const char *csname; // Table charset name
}; // end of class TDBASE
//bool Read_Only; // True for read only tables
//const CHARSET_INFO *m_data_charset;
//const char *csname; // Table charset name
}; // end of class TDBASE
/***********************************************************************/
/* The abstract base class declaration for the catalog tables. */