Commit 41a2ca5c authored by Sergei Golubchik's avatar Sergei Golubchik

10.0-connect merge

parents 9d04a256 5c5834b0
......@@ -271,6 +271,7 @@ ENDIF(CONNECT_WITH_ODBC)
MYSQL_ADD_PLUGIN(connect ${CONNECT_SOURCES}
STORAGE_ENGINE
COMPONENT connect-engine
RECOMPILE_FOR_EMBEDDED
LINK_LIBRARIES ${ZLIB_LIBRARY} ${XML_LIBRARY} ${ICONV_LIBRARY}
${ODBC_LIBRARY} ${IPHLPAPI_LIBRARY})
......@@ -38,10 +38,9 @@ typedef class BLOCK *PBLOCK;
class DllExport BLOCK {
public:
void * operator new(size_t size, PGLOBAL g, void *p = NULL) {
#ifdef DEBTRACE
if (debug != NULL)
htrc("New BLOCK: size=%d g=%p p=%p\n", size, g, p);
#endif
// if (trace > 2)
// htrc("New BLOCK: size=%d g=%p p=%p\n", size, g, p);
return (PlugSubAlloc(g, p, size));
} // end of new
......
......@@ -43,7 +43,6 @@ typedef struct _colinfo {
int Key;
int Precision;
int Scale;
int Opt;
char *Remark;
char *Datefmt;
char *Fieldfmt;
......
......@@ -23,6 +23,8 @@
#include "xindex.h"
#include "xtable.h"
extern "C" int trace;
/***********************************************************************/
/* COLBLK protected constructor. */
/***********************************************************************/
......@@ -36,7 +38,6 @@ COLBLK::COLBLK(PCOLDEF cdp, PTDB tdbp, int i)
if ((Cdp = cdp)) {
Name = cdp->Name;
Format = cdp->F;
Opt = cdp->Opt;
Long = cdp->Long;
Precision = cdp->Precision;
Buf_Type = cdp->Buf_Type;
......@@ -46,7 +47,6 @@ COLBLK::COLBLK(PCOLDEF cdp, PTDB tdbp, int i)
} else {
Name = NULL;
memset(&Format, 0, sizeof(FORMAT));
Opt = 0;
Long = 0;
Precision = 0;
Buf_Type = TYPE_ERROR;
......@@ -74,9 +74,8 @@ COLBLK::COLBLK(PCOL col1, PTDB tdbp)
//To_Orig = col1;
To_Tdb = tdbp;
#ifdef DEBTRACE
if (trace > 1)
htrc(" copying COLBLK %s from %p to %p\n", Name, col1, this);
#endif
if (tdbp)
// Attach the new column to the table block
......@@ -114,31 +113,21 @@ bool COLBLK::SetFormat(PGLOBAL g, FORMAT& fmt)
{
fmt = Format;
#ifdef DEBTRACE
if (trace > 1)
htrc("COLBLK: %p format=%c(%d,%d)\n",
this, *fmt.Type, fmt.Length, fmt.Prec);
#endif
return false;
} // end of SetFormat
/***********************************************************************/
/* CheckColumn: a column descriptor is found, say it by returning 1. */
/***********************************************************************/
int COLBLK::CheckColumn(PGLOBAL g, PSQL sqlp, PXOB &p, int &ag)
{
return 1;
} // end of CheckColumn
/***********************************************************************/
/* Eval: get the column value from the last read record or from a */
/* matching Index column if there is one. */
/***********************************************************************/
bool COLBLK::Eval(PGLOBAL g)
{
#ifdef DEBTRACE
if (trace > 1)
htrc("Col Eval: %s status=%.4X\n", Name, Status);
#endif
if (!GetStatus(BUF_READ)) {
// if (To_Tdb->IsNull())
......@@ -154,15 +143,6 @@ bool COLBLK::Eval(PGLOBAL g)
return false;
} // end of Eval
/***********************************************************************/
/* CheckSort: */
/* Used to check that a table is involved in the sort list items. */
/***********************************************************************/
bool COLBLK::CheckSort(PTDB tdbp)
{
return (tdbp == To_Tdb);
} // end of CheckSort
/***********************************************************************/
/* InitValue: prepare a column block for read operation. */
/* Now we use Format.Length for the len parameter to avoid strings */
......@@ -183,10 +163,9 @@ bool COLBLK::InitValue(PGLOBAL g)
AddStatus(BUF_READY);
Value->SetNullable(Nullable);
#ifdef DEBTRACE
if (trace > 1)
htrc(" colp=%p type=%d value=%p coluse=%.4X status=%.4X\n",
this, Buf_Type, Value, ColUse, Status);
#endif
return false;
} // end of InitValue
......
......@@ -39,7 +39,6 @@ class DllExport COLBLK : public XOBJECT {
PCOL GetNext(void) {return Next;}
PSZ GetName(void) {return Name;}
int GetIndex(void) {return Index;}
int GetOpt(void) {return Opt;}
ushort GetColUse(void) {return ColUse;}
ushort GetColUse(ushort u) {return (ColUse & u);}
ushort GetStatus(void) {return Status;}
......@@ -62,10 +61,7 @@ class DllExport COLBLK : public XOBJECT {
virtual void Reset(void);
virtual bool Compare(PXOB xp);
virtual bool SetFormat(PGLOBAL, FORMAT&);
virtual int CheckColumn(PGLOBAL g, PSQL sqlp, PXOB &xp, int &ag);
virtual bool IsSpecial(void) {return false;}
virtual int CheckSpcCol(PTDB tdbp, int n) {return 2;}
virtual bool CheckSort(PTDB tdbp);
virtual bool Eval(PGLOBAL g);
virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
virtual void SetTo_Val(PVAL valp) {}
......@@ -73,8 +69,6 @@ class DllExport COLBLK : public XOBJECT {
virtual void WriteColumn(PGLOBAL g);
virtual void Print(PGLOBAL g, FILE *, uint);
virtual void Print(PGLOBAL g, char *, uint);
virtual bool VarSize(void) {return false;}
virtual bool IsColInside(PCOL colp) {return this == colp;}
bool InitValue(PGLOBAL g);
protected:
......@@ -87,7 +81,6 @@ class DllExport COLBLK : public XOBJECT {
bool Nullable; // True if nullable
bool Unsigned; // True if unsigned
int Index; // Column number in table
int Opt; // Cluster/sort information
int Buf_Type; // Data type
int Long; // Internal length in table
int Precision; // Column length (as for ODBC)
......@@ -150,8 +143,6 @@ class DllExport FIDBLK : public SPCBLK {
// Methods
virtual void Reset(void) {} // This is a pseudo constant column
virtual int CheckSpcCol(PTDB tdbp, int n)
{return (n == 2 && tdbp == To_Tdb) ? 1 : 2;}
virtual void ReadColumn(PGLOBAL g);
protected:
......@@ -171,8 +162,6 @@ class DllExport TIDBLK : public SPCBLK {
// Methods
virtual void Reset(void) {} // This is a pseudo constant column
virtual int CheckSpcCol(PTDB tdbp, int n)
{return (n == 3 && tdbp == To_Tdb) ? 1 : 2;}
virtual void ReadColumn(PGLOBAL g);
protected:
......@@ -196,8 +185,6 @@ class DllExport SIDBLK : public SPCBLK {
// Methods
virtual void Reset(void) {} // This is a pseudo constant column
virtual int CheckSpcCol(PTDB tdbp, int n)
{return (n == 3 && tdbp == To_Tdb) ? 1 : 2;}
virtual void ReadColumn(PGLOBAL g);
protected:
......
......@@ -51,7 +51,7 @@
/***********************************************************************/
/* DB static variables. */
/***********************************************************************/
extern int xtrace;
extern "C" int trace;
/***********************************************************************/
/* Routines called internally by semantic routines. */
......@@ -110,14 +110,14 @@ bool CntCheckDB(PGLOBAL g, PHC handler, const char *pathname)
bool rc= false;
PDBUSER dbuserp= PlgGetUser(g);
if (xtrace) {
if (trace) {
printf("CntCheckDB: dbuserp=%p\n", dbuserp);
} // endif xtrace
} // endif trace
if (!dbuserp || !handler)
return true;
if (xtrace)
if (trace)
printf("cat=%p oldhandler=%p newhandler=%p\n", dbuserp->Catalog,
(dbuserp->Catalog) ? ((MYCAT*)dbuserp->Catalog)->GetHandler() : NULL,
handler);
......@@ -149,7 +149,7 @@ bool CntCheckDB(PGLOBAL g, PHC handler, const char *pathname)
/*********************************************************************/
sprintf(g->Message, MSG(DATABASE_LOADED), "???");
if (xtrace)
if (trace)
printf("msg=%s\n", g->Message);
return rc;
......@@ -193,7 +193,7 @@ PTDB CntGetTDB(PGLOBAL g, LPCSTR name, MODE mode, PHC h)
PDBUSER dup= PlgGetUser(g);
PCATLG cat= (dup) ? dup->Catalog : NULL; // Safe over longjmp
if (xtrace)
if (trace)
printf("CntGetTDB: name=%s mode=%d cat=%p\n", name, mode, cat);
if (!cat)
......@@ -213,7 +213,7 @@ PTDB CntGetTDB(PGLOBAL g, LPCSTR name, MODE mode, PHC h)
// Get table object from the catalog
tabp= new(g) XTAB(name);
if (xtrace)
if (trace)
printf("CntGetTDB: tabp=%p\n", tabp);
// Perhaps this should be made thread safe
......@@ -223,7 +223,7 @@ PTDB CntGetTDB(PGLOBAL g, LPCSTR name, MODE mode, PHC h)
printf("CntGetTDB: %s\n", g->Message);
err:
if (xtrace)
if (trace)
printf("Returning tdbp=%p mode=%d\n", tdbp, mode);
g->jump_level--;
......@@ -237,12 +237,13 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
bool del, PHC h)
{
char *p;
int i, n;
int i, n, rc;
bool rcop= true;
PCOL colp;
//PCOLUMN cp;
PDBUSER dup= PlgGetUser(g);
if (xtrace)
if (trace)
printf("CntOpenTable: tdbp=%p mode=%d\n", tdbp, mode);
if (!tdbp) {
......@@ -251,7 +252,15 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
return true;
} // endif tdbp
//tdbp->SetMode(mode); done in ha_connect::GetTDB
// Save stack and allocation environment and prepare error return
if (g->jump_level == MAX_JUMP) {
strcpy(g->Message, MSG(TOO_MANY_JUMPS));
return true;
} // endif jump_level
if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) {
goto err;
} // endif rc
if (!c1) {
if (mode == MODE_INSERT)
......@@ -260,7 +269,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
} else for (p= c1; *p; p+= n) {
// Allocate only used column blocks
if (xtrace)
if (trace)
printf("Allocating column %s\n", p);
// if (*p == '*') {
......@@ -273,7 +282,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
if (!colp) {
sprintf(g->Message, "Column %s not found in %s", p, tdbp->GetName());
return true;
goto err;
} // endif colp
n= strlen(p) + 1;
......@@ -281,12 +290,12 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
for (i= 0, colp= tdbp->GetColumns(); colp; i++, colp= colp->GetNext()) {
if (colp->InitValue(g))
return true;
goto err;
if (mode == MODE_INSERT)
// Allow type conversion
if (colp->SetBuffer(g, colp->GetValue(), true, false))
return true;
goto err;
colp->AddColUse(U_P); // For PLG tables
} // endfor colp
......@@ -301,7 +310,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
if (!(utp= (PTDBASE)tdbp->Duplicate(g))) {
sprintf(g->Message, MSG(INV_UPDT_TABLE), tdbp->GetName());
return true;
goto err;
} // endif tp
if (!c2)
......@@ -315,10 +324,10 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
for (i= 0, colp= utp->GetColumns(); colp; i++, colp= colp->GetNext()) {
if (colp->InitValue(g))
return true;
goto err;
if (colp->SetBuffer(g, colp->GetValue(), true, false))
return true;
goto err;
} // endfor colp
......@@ -328,7 +337,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
((PTDBASE)tdbp)->SetSetCols(tdbp->GetColumns());
// Now do open the physical table
if (xtrace)
if (trace)
printf("Opening table %s in mode %d tdbp=%p\n",
tdbp->GetName(), mode, tdbp);
......@@ -344,19 +353,23 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
} // endif del
if (xtrace)
if (trace)
printf("About to open the table: tdbp=%p\n", tdbp);
if (mode != MODE_ANY && mode != MODE_ALTER) {
if (tdbp->OpenDB(g)) {
printf("%s\n", g->Message);
return true;
goto err;
} else
tdbp->SetNext(NULL);
} // endif mode
return false;
rcop= false;
err:
g->jump_level--;
return rcop;
} // end of CntOpenTable
/***********************************************************************/
......@@ -381,7 +394,7 @@ RCODE EvalColumns(PGLOBAL g, PTDB tdbp)
// Save stack and allocation environment and prepare error return
if (g->jump_level == MAX_JUMP) {
if (xtrace) {
if (trace) {
strcpy(g->Message, MSG(TOO_MANY_JUMPS));
printf("EvalColumns: %s\n", g->Message);
} // endif
......@@ -390,7 +403,7 @@ RCODE EvalColumns(PGLOBAL g, PTDB tdbp)
} // endif jump_level
if (setjmp(g->jumper[++g->jump_level]) != 0) {
if (xtrace)
if (trace)
printf("Error reading columns: %s\n", g->Message);
rc= RC_FX;
......@@ -432,8 +445,21 @@ RCODE CntReadNext(PGLOBAL g, PTDB tdbp)
((PTDBASE)tdbp)->SetKindex(NULL);
} // endif index
// Save stack and allocation environment and prepare error return
if (g->jump_level == MAX_JUMP) {
strcpy(g->Message, MSG(TOO_MANY_JUMPS));
return RC_FX;
} // endif jump_level
if ((setjmp(g->jumper[++g->jump_level])) != 0) {
rc= RC_FX;
goto err;
} // endif rc
while ((rc= (RCODE)tdbp->ReadDB(g)) == RC_NF) ;
err:
g->jump_level--;
return (rc != RC_OK) ? rc : EvalColumns(g, tdbp);
} // end of CntReadNext
......@@ -521,7 +547,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
if (!tdbp || tdbp->GetUse() != USE_OPEN)
return rc; // Nothing to do
if (xtrace)
if (trace)
printf("CntCloseTable: tdbp=%p mode=%d\n", tdbp, tdbp->GetMode());
if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN)
......@@ -545,7 +571,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
g->jump_level--;
if (xtrace > 1)
if (trace > 1)
printf("Table %s closed\n", tdbp->GetName());
//if (!((PTDBDOX)tdbp)->GetModified())
......@@ -554,8 +580,8 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
if (tdbp->GetMode() == MODE_READ || tdbp->GetMode() == MODE_ANY)
return 0;
if (xtrace > 1)
printf("About to reset opt\n");
if (trace > 1)
printf("About to reset indexes\n");
// Make all the eventual indexes
tbxp= (TDBDOX*)tdbp;
......@@ -564,7 +590,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
rc= tbxp->ResetTableOpt(g, ((PTDBASE)tdbp)->GetDef()->Indexable());
err:
if (xtrace > 1)
if (trace > 1)
printf("Done rc=%d\n", rc);
return (rc == RC_OK || rc == RC_INFO) ? 0 : rc;
......@@ -833,10 +859,10 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
} else
valp->SetBinValue((void*)p);
if (xtrace) {
if (trace) {
char bf[32];
printf("i=%d n=%d key=%s\n", i, n, valp->GetCharString(bf));
} // endif xtrace
} // endif trace
p+= valp->GetClen();
......@@ -855,7 +881,7 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
xbp->SetNval(n);
if (xtrace)
if (trace)
printf("xbp=%p Nval=%d i=%d incl=%d\n", xbp, n, i, incl[i]);
k[i]= xbp->Range(g, i + 1, incl[i]);
......@@ -864,7 +890,7 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
} // endfor i
if (xtrace)
if (trace)
printf("k1=%d k0=%d\n", k[1], k[0]);
return k[1] - k[0];
......
......@@ -17,7 +17,6 @@
/* Name: CONNECT.H Version 2.4 */
/* This file contains the some based classes declares. */
/***********************************************************************/
//#include "xtable.h" // Base class declares
#include "filamtxt.h"
#include "tabdos.h"
......@@ -51,8 +50,6 @@ PGLOBAL CntExit(PGLOBAL g);
/* These classes purpose is chiefly to access protected items! */
/***********************************************************************/
class DOXDEF: public DOSDEF {
//friend class TDBDOX;
//friend int MakeIndex(PGLOBAL, PTDB, PIXDEF);
friend int CntIndexInit(PGLOBAL, PTDB, int);
}; // end of class DOXDEF
......@@ -73,10 +70,7 @@ class TDBDOX: public TDBDOS {
class XKPDEF: public KPARTDEF {
friend class TDBDOX;
friend class ha_connect;
//friend int CntMakeIndex(PGLOBAL, const char *, PIXDEF);
friend int CntIndexInit(PGLOBAL, PTDB, int);
public:
XKPDEF(const char *name, int n) : KPARTDEF((PSZ)name, n) {}
}; // end of class XKPDEF
//RCODE CheckRecord(PGLOBAL g, PTDB tdbp, char *oldbuf, char *newbuf);
......@@ -22,9 +22,7 @@
#define THRESH 4 /* Threshold for insertion (was 4) */
#define MTHRESH 6 /* Threshold for median */
#ifdef DEBTRACE
extern FILE *debug; /* Debug file */
#endif
//extern FILE *debug; /* Debug file */
typedef int* const CPINT;
......
......@@ -59,7 +59,9 @@ void CloseXMLFile(PGLOBAL g, PFBLOCK fp, bool all)
xp->Count--;
} else if (xp && xp->Count > 0) {
try {
if (xp->Docp)
xp->Docp->Release();
} catch(_com_error e) {
sprintf(g->Message, "%s %s", MSG(COM_ERROR), e.Description());
} catch(...) {}
......
......@@ -20,7 +20,6 @@ typedef struct _xblock { /* Loaded XML file block */
short Type; /* TYPE_FB_XML */
int Retcode; /* Return code from Load */
MSXML2::IXMLDOMDocumentPtr Docp;/* Document interface pointer */
//IXMLDOMNodeListPtr Nlist;
} XBLOCK, *PXBLOCK;
/******************************************************************/
......@@ -123,9 +122,6 @@ class DOMATTR : public XMLATTRIBUTE {
friend class DOMDOC;
friend class DOMNODE;
public:
// Properties
//virtual char *GetText(void);
// Methods
virtual bool SetText(PGLOBAL g, char *txtp, int len);
......
......@@ -46,6 +46,8 @@
#include "filamap.h"
#include "tabdos.h"
extern "C" int trace;
/* --------------------------- Class MAPFAM -------------------------- */
/***********************************************************************/
......@@ -89,9 +91,8 @@ int MAPFAM::GetFileLength(PGLOBAL g)
len = (To_Fb) ? To_Fb->Length : TXTFAM::GetFileLength(g);
#ifdef DEBTRACE
if (trace)
htrc("Mapped file length=%d\n", len);
#endif
return len;
} // end of GetFileLength
......@@ -128,9 +129,9 @@ bool MAPFAM::OpenTableFile(PGLOBAL g)
&& fp->Count && fp->Mode == mode)
break;
#ifdef DEBTRACE
if (trace)
htrc("Mapping file, fp=%p\n", fp);
#endif
} else
fp = NULL;
......@@ -166,9 +167,9 @@ bool MAPFAM::OpenTableFile(PGLOBAL g)
sprintf(g->Message, MSG(OPEN_MODE_ERROR),
"map", (int) rc, filename);
#ifdef DEBTRACE
htrc("%s\n", g->Message);
#endif
if (trace)
htrc("CreateFileMap: %s\n", g->Message);
return (mode == MODE_READ && rc == ENOENT)
? PushWarning(g, Tdbp) : true;
} // endif hFile
......@@ -228,10 +229,9 @@ bool MAPFAM::OpenTableFile(PGLOBAL g)
Fpos = Mempos = Memory;
Top = Memory + len;
#ifdef DEBTRACE
if (trace)
htrc("fp=%p count=%d MapView=%p len=%d Top=%p\n",
fp, fp->Count, Memory, len, Top);
#endif
return AllocateBuffer(g); // Useful for DBF files
} // end of OpenTableFile
......@@ -365,20 +365,19 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
{
int n;
#ifdef DEBTRACE
fprintf(debug,
"MAP DeleteDB: irc=%d mempos=%p tobuf=%p Tpos=%p Spos=%p\n",
if (trace)
htrc("MAP DeleteDB: irc=%d mempos=%p tobuf=%p Tpos=%p Spos=%p\n",
irc, Mempos, To_Buf, Tpos, Spos);
#endif
if (irc != RC_OK) {
/*******************************************************************/
/* EOF: position Fpos at the top of map position. */
/*******************************************************************/
Fpos = Top;
#ifdef DEBTRACE
if (trace)
htrc("Fpos placed at file top=%p\n", Fpos);
#endif
} // endif irc
if (Tpos == Spos)
......@@ -394,17 +393,16 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
memmove(Tpos, Spos, n);
Tpos += n;
#ifdef DEBTRACE
if (trace)
htrc("move %d bytes\n", n);
#endif
} // endif n
if (irc == RC_OK) {
Spos = Mempos; // New start position
#ifdef DEBTRACE
if (trace)
htrc("after: Tpos=%p Spos=%p\n", Tpos, Spos);
#endif
} else if (To_Fb) { // Can be NULL for deleted files
/*******************************************************************/
......@@ -432,9 +430,8 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
return RC_FX;
} // endif
#ifdef DEBTRACE
if (trace)
htrc("done, Tpos=%p newsize=%d drc=%d\n", Tpos, n, drc);
#endif
if (!SetEndOfFile(fp->Handle)) {
sprintf(g->Message, MSG(FUNCTION_ERROR),
......@@ -466,10 +463,10 @@ void MAPFAM::CloseTableFile(PGLOBAL g)
PlugCloseFile(g, To_Fb);
To_Fb = NULL; // To get correct file size in Cardinality
#ifdef DEBTRACE
if (trace)
htrc("MAP Close: closing %s count=%d\n",
To_File, (To_Fb) ? To_Fb->Count : 0);
#endif
} // end of CloseTableFile
/***********************************************************************/
......@@ -491,7 +488,7 @@ MBKFAM::MBKFAM(PDOSDEF tdp) : MAPFAM(tdp)
Block = tdp->GetBlock();
Last = tdp->GetLast();
Nrec = tdp->GetElemt();
BlkPos = tdp->GetTo_Pos();
BlkPos = NULL;
CurNum = Nrec;
} // end of MBKFAM standard constructor
......@@ -537,37 +534,8 @@ int MBKFAM::GetRowID(void)
/***********************************************************************/
int MBKFAM::ReadBuffer(PGLOBAL g)
{
int len;
/*********************************************************************/
/* Sequential block reading when Placed is not true. */
/*********************************************************************/
if (Placed) {
Placed = false;
} else if (Mempos >= Top) { // Are we at the end of the memory
return RC_EF;
} else if (++CurNum < Nrec) {
Fpos = Mempos;
} else {
/*******************************************************************/
/* New block. */
/*******************************************************************/
CurNum = 0;
if (++CurBlk >= Block)
return RC_EF;
Fpos = Mempos = Memory + BlkPos[CurBlk];
} // endif's
// Immediately calculate next position (Used by DeleteDB)
while (*Mempos++ != '\n') ; // What about Unix ???
// Set caller line buffer
len = (Mempos - Fpos) - Ending;
memcpy(Tdbp->GetLine(), Fpos, len);
Tdbp->GetLine()[len] = '\0';
return RC_OK;
strcpy(g->Message, "This AM cannot be used in this version");
return RC_FX;
} // end of ReadBuffer
/***********************************************************************/
......
......@@ -33,7 +33,6 @@ class DllExport MAPFAM : public TXTFAM {
virtual void Reset(void);
virtual int GetFileLength(PGLOBAL g);
virtual int Cardinality(PGLOBAL g) {return (g) ? -1 : 0;}
virtual int MaxBlkSize(PGLOBAL g, int s) {return s;}
virtual int GetRowID(void);
virtual bool RecordPos(PGLOBAL g);
virtual bool SetPos(PGLOBAL g, int recpos);
......@@ -72,8 +71,6 @@ class DllExport MBKFAM : public MAPFAM {
// Methods
virtual void Reset(void);
virtual int Cardinality(PGLOBAL g);
virtual int MaxBlkSize(PGLOBAL g, int s)
{return TXTFAM::MaxBlkSize(g, s);}
virtual int GetRowID(void);
virtual int SkipRecord(PGLOBAL g, bool header);
virtual int ReadBuffer(PGLOBAL g);
......@@ -99,9 +96,6 @@ class DllExport MPXFAM : public MBKFAM {
// Methods
virtual int Cardinality(PGLOBAL g) {return TXTFAM::Cardinality(g);}
virtual int MaxBlkSize(PGLOBAL g, int s)
{return TXTFAM::MaxBlkSize(g, s);}
//virtual int GetRowID(void);
virtual bool SetPos(PGLOBAL g, int recpos);
virtual bool DeferReading(void) {return false;}
virtual int ReadBuffer(PGLOBAL g);
......
......@@ -485,16 +485,15 @@ bool DBFFAM::OpenTableFile(PGLOBAL g)
PlugSetPath(filename, To_File, Tdbp->GetPath());
if (!(Stream = PlugOpenFile(g, filename, opmode))) {
#ifdef DEBTRACE
if (trace)
htrc("%s\n", g->Message);
#endif
return (mode == MODE_READ && errno == ENOENT)
? PushWarning(g, Tdbp) : true;
} // endif Stream
#ifdef DEBTRACE
if (trace)
htrc("File %s is open in mode %s\n", filename, opmode);
#endif
To_Fb = dbuserp->Openlist; // Keep track of File block
......@@ -853,10 +852,10 @@ void DBFFAM::CloseTableFile(PGLOBAL g)
rc = PlugCloseFile(g, To_Fb);
fin:
#ifdef DEBTRACE
if (trace)
htrc("DBF CloseTableFile: closing %s mode=%d wrc=%d rc=%d\n",
To_File, mode, wrc, rc);
#endif
Stream = NULL; // So we can know whether table is open
} // end of CloseTableFile
......
......@@ -43,7 +43,6 @@ class DllExport DBFBASE {
int Nerr; /* Number of bad records */
int Maxerr; /* Maximum number of bad records */
int ReadMode; /* 1: ALL 2: DEL 0: NOT DEL */
//PSZ Defpath; /* Default data path */
}; // end of class DBFBASE
/****************************************************************************/
......@@ -63,22 +62,18 @@ class DllExport DBFFAM : public FIXFAM, public DBFBASE {
// Methods
virtual int GetNerr(void) {return Nerr;}
virtual int Cardinality(PGLOBAL g);
//virtual int GetRowID(void); // Temporarily suppressed
virtual bool OpenTableFile(PGLOBAL g);
virtual bool AllocateBuffer(PGLOBAL g);
virtual void ResetBuffer(PGLOBAL g);
virtual int ReadBuffer(PGLOBAL g);
//virtual int WriteBuffer(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc);
virtual void CloseTableFile(PGLOBAL g);
virtual void Rewind(void);
protected:
// Members
virtual bool CopyHeader(PGLOBAL g);
//int Records; in TXTFAM
//int Headlen; in TXTFAM
// Members
}; // end of class DBFFAM
/****************************************************************************/
......@@ -100,17 +95,13 @@ class DllExport DBMFAM : public MPXFAM, public DBFBASE {
// Methods
virtual int GetNerr(void) {return Nerr;}
virtual int Cardinality(PGLOBAL g);
//virtual int GetRowID(void); // Temporarily suppressed
virtual bool AllocateBuffer(PGLOBAL g);
virtual int ReadBuffer(PGLOBAL g);
//virtual int WriteBuffer(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc);
virtual void Rewind(void);
protected:
// Members
//int Records; in TXTFAM
//int Headlen; in TXTFAM
}; // end of class DBFFAM
#endif // __FILAMDBF_H
This diff is collapsed.
......@@ -31,8 +31,6 @@ class DllExport FIXFAM : public BLKFAM {
// Methods
virtual int Cardinality(PGLOBAL g) {return TXTFAM::Cardinality(g);}
virtual int MaxBlkSize(PGLOBAL g, int s)
{return TXTFAM::MaxBlkSize(g, s);}
virtual bool AllocateBuffer(PGLOBAL g);
virtual void ResetBuffer(PGLOBAL g);
virtual int ReadBuffer(PGLOBAL g);
......@@ -64,7 +62,6 @@ class BGXFAM : public FIXFAM {
{return (PTXF)new(g) BGXFAM(this);}
// Methods
//virtual void Reset(void);
virtual int Cardinality(PGLOBAL g);
virtual bool OpenTableFile(PGLOBAL g);
virtual int ReadBuffer(PGLOBAL g);
......@@ -84,7 +81,6 @@ class BGXFAM : public FIXFAM {
// Members
HANDLE Hfile; // Handle(descriptor) to big file
HANDLE Tfile; // Handle(descriptor) to big temp file
//BIGINT Xpos; // Current file position
}; // end of class BGXFAM
#endif // __FILAMFIX_H
......@@ -228,25 +228,6 @@ int TXTFAM::Cardinality(PGLOBAL g)
} // end of Cardinality
/***********************************************************************/
/* Use BlockTest to reduce the table estimated size. */
/* Note: This function is meant only for fixed length files but is */
/* placed here to be available to FIXFAM and MPXFAM classes. */
/***********************************************************************/
int TXTFAM::MaxBlkSize(PGLOBAL g, int s)
{
int savcur = CurBlk, blm1 = Block - 1;
int size, last = s - blm1 * Nrec;
// Roughly estimate the table size as the sum of blocks
// that can contain good rows
for (size = 0, CurBlk = 0; CurBlk < Block; CurBlk++)
size += (CurBlk == blm1) ? last : Nrec;
CurBlk = savcur;
return size;
} // end of MaxBlkSize
/* --------------------------- Class DOSFAM -------------------------- */
/***********************************************************************/
......@@ -313,15 +294,6 @@ int DOSFAM::Cardinality(PGLOBAL g)
return (g) ? -1 : 0;
} // end of Cardinality
/***********************************************************************/
/* Use BlockTest to reduce the table estimated size. */
/* Note: This function is not really implemented yet. */
/***********************************************************************/
int DOSFAM::MaxBlkSize(PGLOBAL g, int s)
{
return s;
} // end of MaxBlkSize
/***********************************************************************/
/* OpenTableFile: Open a DOS/UNIX table file using C standard I/Os. */
/***********************************************************************/
......@@ -915,6 +887,7 @@ int DOSFAM::RenameTempFile(PGLOBAL g)
// This loop is necessary because, in case of join,
// To_File can have been open several times.
for (PFBLOCK fb = PlgGetUser(g)->Openlist; fb; fb = fb->Next)
if (fb == To_Fb || fb == To_Fbt)
rc = PlugCloseFile(g, fb);
tempname = (char*)To_Fbt->Fname;
......@@ -976,7 +949,9 @@ void DOSFAM::CloseTableFile(PGLOBAL g)
/***********************************************************************/
void DOSFAM::Rewind(void)
{
if (Stream) // Can be NULL when making index on void table
rewind(Stream);
Rows = 0;
OldBlk = CurBlk = -1;
} // end of Rewind
......@@ -993,7 +968,7 @@ BLKFAM::BLKFAM(PDOSDEF tdp) : DOSFAM(tdp)
Last = tdp->GetLast();
Nrec = tdp->GetElemt();
Closing = false;
BlkPos = tdp->GetTo_Pos();
BlkPos = NULL;
CurLine = NULL;
NxtLine = NULL;
OutBuf = NULL;
......@@ -1028,23 +1003,6 @@ int BLKFAM::Cardinality(PGLOBAL g)
//return (g) ? (int)((Block - 1) * Nrec + Last) : 1;
} // end of Cardinality
/***********************************************************************/
/* Use BlockTest to reduce the table estimated size. */
/***********************************************************************/
int BLKFAM::MaxBlkSize(PGLOBAL g, int s)
{
int savcur = CurBlk;
int size;
// Roughly estimate the table size as the sum of blocks
// that can contain good rows
for (size = 0, CurBlk = 0; CurBlk < Block; CurBlk++)
size += (CurBlk == Block - 1) ? Last : Nrec;
CurBlk = savcur;
return size;
} // end of MaxBlkSize
/***********************************************************************/
/* Allocate the line buffer. For mode Delete or when a temp file is */
/* used another big buffer has to be allocated because is it used */
......@@ -1150,97 +1108,8 @@ int BLKFAM::SkipRecord(PGLOBAL g, bool header)
/***********************************************************************/
int BLKFAM::ReadBuffer(PGLOBAL g)
{
int i, n, rc = RC_OK;
/*********************************************************************/
/* Sequential reading when Placed is not true. */
/*********************************************************************/
if (Placed) {
Placed = false;
} else if (++CurNum < Rbuf) {
CurLine = NxtLine;
// Get the position of the next line in the buffer
while (*NxtLine++ != '\n') ;
// Set caller line buffer
n = NxtLine - CurLine - Ending;
memcpy(Tdbp->GetLine(), CurLine, n);
Tdbp->GetLine()[n] = '\0';
goto fin;
} else if (Rbuf < Nrec && CurBlk != -1) {
return RC_EF;
} else {
/*******************************************************************/
/* New block. */
/*******************************************************************/
CurNum = 0;
if (++CurBlk >= Block)
return RC_EF;
} // endif's
if (OldBlk == CurBlk)
goto ok; // Block is already there
// fseek is required only in non sequential reading
if (CurBlk != OldBlk + 1)
if (fseek(Stream, BlkPos[CurBlk], SEEK_SET)) {
sprintf(g->Message, MSG(FSETPOS_ERROR), BlkPos[CurBlk]);
strcpy(g->Message, "This AM cannot be used in this version");
return RC_FX;
} // endif fseek
// Calculate the length of block to read
BlkLen = BlkPos[CurBlk + 1] - BlkPos[CurBlk];
if (trace)
htrc("File position is now %d\n", ftell(Stream));
// Read the entire next block
n = fread(To_Buf, 1, (size_t)BlkLen, Stream);
if (n == BlkLen) {
// ReadBlks++;
num_read++;
Rbuf = (CurBlk == Block - 1) ? Last : Nrec;
ok:
rc = RC_OK;
// Get the position of the current line
for (i = 0, CurLine = To_Buf; i < CurNum; i++)
while (*CurLine++ != '\n') ; // What about Unix ???
// Now get the position of the next line
for (NxtLine = CurLine; *NxtLine++ != '\n';) ;
// Set caller line buffer
n = NxtLine - CurLine - Ending;
memcpy(Tdbp->GetLine(), CurLine, n);
Tdbp->GetLine()[n] = '\0';
} else if (feof(Stream)) {
rc = RC_EF;
} else {
#if defined(UNIX)
sprintf(g->Message, MSG(READ_ERROR), To_File, strerror(errno));
#else
sprintf(g->Message, MSG(READ_ERROR), To_File, _strerror(NULL));
#endif
if (trace)
htrc("%s\n", g->Message);
return RC_FX;
} // endelse
OldBlk = CurBlk; // Last block actually read
IsRead = true; // Is read indeed
fin:
// Store the current record file position for Delete and Update
Fpos = BlkPos[CurBlk] + CurLine - To_Buf;
return rc;
} // end of ReadBuffer
/***********************************************************************/
......
......@@ -53,7 +53,6 @@ class DllExport TXTFAM : public BLOCK {
virtual void Reset(void);
virtual int GetFileLength(PGLOBAL g);
virtual int Cardinality(PGLOBAL g);
virtual int MaxBlkSize(PGLOBAL g, int s);
virtual bool AllocateBuffer(PGLOBAL g) {return false;}
virtual void ResetBuffer(PGLOBAL g) {}
virtual int GetNerr(void) {return 0;}
......@@ -125,7 +124,6 @@ class DllExport DOSFAM : public TXTFAM {
virtual void Reset(void);
virtual int GetFileLength(PGLOBAL g);
virtual int Cardinality(PGLOBAL g);
virtual int MaxBlkSize(PGLOBAL g, int s);
virtual bool AllocateBuffer(PGLOBAL g);
virtual int GetRowID(void);
virtual bool RecordPos(PGLOBAL g);
......@@ -174,7 +172,6 @@ class DllExport BLKFAM : public DOSFAM {
// Methods
virtual void Reset(void);
virtual int Cardinality(PGLOBAL g);
virtual int MaxBlkSize(PGLOBAL g, int s);
virtual bool AllocateBuffer(PGLOBAL g);
virtual int GetRowID(void);
virtual bool RecordPos(PGLOBAL g);
......
......@@ -244,23 +244,6 @@ bool VCTFAM::SetBlockInfo(PGLOBAL g)
return rc;
} // end of SetBlockInfo
/***********************************************************************/
/* Use BlockTest to reduce the table estimated size. */
/***********************************************************************/
int VCTFAM::MaxBlkSize(PGLOBAL g, int s)
{
int savcur = CurBlk;
int size;
// Roughly estimate the table size as the sum of blocks
// that can contain good rows
for (size = 0, CurBlk = 0; CurBlk < Block; CurBlk++)
size += (CurBlk == Block - 1) ? Last : Nrec;
CurBlk = savcur;
return size;
} // end of MaxBlkSize
/***********************************************************************/
/* VCT Cardinality: returns table cardinality in number of rows. */
/* This function can be called with a null argument to test the */
......
......@@ -40,7 +40,6 @@ class DllExport VCTFAM : public FIXFAM {
// Methods
virtual void Reset(void);
virtual int MaxBlkSize(PGLOBAL g, int s);
virtual bool AllocateBuffer(PGLOBAL g);
virtual bool InitInsert(PGLOBAL g);
virtual void ResetBuffer(PGLOBAL g) {}
......
......@@ -62,6 +62,7 @@
/* DB static variables. */
/***********************************************************************/
extern int num_read, num_there, num_eq[]; // Statistics
extern "C" int trace;
/* ------------------------------------------------------------------- */
......@@ -203,9 +204,8 @@ bool ZIPFAM::AllocateBuffer(PGLOBAL g)
Buflen = Lrecl + 2; // Lrecl does not include CRLF
//Buflen *= ((Mode == MODE_DELETE) ? DOS_BUFF_LEN : 1); NIY
#ifdef DEBTRACE
if (trace)
htrc("SubAllocating a buffer of %d bytes\n", Buflen);
#endif
To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen);
......@@ -331,9 +331,9 @@ int ZIPFAM::ReadBuffer(PGLOBAL g)
} else
rc = Zerror(g);
#ifdef DEBTRACE
if (trace > 1)
htrc(" Read: '%s' rc=%d\n", To_Buf, rc);
#endif
return rc;
} // end of ReadBuffer
......@@ -373,9 +373,8 @@ void ZIPFAM::CloseTableFile(PGLOBAL g)
{
int rc = gzclose(Zfile);
#ifdef DEBTRACE
if (trace)
htrc("ZIP CloseDB: closing %s rc=%d\n", To_File, rc);
#endif
Zfile = NULL; // So we can know whether table is open
//To_Fb->Count = 0; // Avoid double closing by PlugCloseAll
......@@ -403,7 +402,7 @@ ZBKFAM::ZBKFAM(PDOSDEF tdp) : ZIPFAM(tdp)
CurLine = NULL;
NxtLine = NULL;
Closing = false;
BlkPos = tdp->GetTo_Pos();
BlkPos = NULL;
} // end of ZBKFAM standard constructor
ZBKFAM::ZBKFAM(PZBKFAM txfp) : ZIPFAM(txfp)
......@@ -413,23 +412,6 @@ ZBKFAM::ZBKFAM(PZBKFAM txfp) : ZIPFAM(txfp)
Closing = txfp->Closing;
} // end of ZBKFAM copy constructor
/***********************************************************************/
/* Use BlockTest to reduce the table estimated size. */
/***********************************************************************/
int ZBKFAM::MaxBlkSize(PGLOBAL g, int s)
{
int savcur = CurBlk;
int size;
// Roughly estimate the table size as the sum of blocks
// that can contain good rows
for (size = 0, CurBlk = 0; CurBlk < Block; CurBlk++)
size += (CurBlk == Block - 1) ? Last : Nrec;
CurBlk = savcur;
return size;
} // end of MaxBlkSize
/***********************************************************************/
/* ZBK Cardinality: returns table cardinality in number of rows. */
/* This function can be called with a null argument to test the */
......@@ -509,56 +491,8 @@ int ZBKFAM::SkipRecord(PGLOBAL g, bool header)
/***********************************************************************/
int ZBKFAM::ReadBuffer(PGLOBAL g)
{
int n, rc = RC_OK;
/*********************************************************************/
/* Sequential reading when Placed is not true. */
/*********************************************************************/
if (++CurNum < Rbuf) {
CurLine = NxtLine;
// Get the position of the next line in the buffer
while (*NxtLine++ != '\n') ;
// Set caller line buffer
n = NxtLine - CurLine - Ending;
memcpy(Tdbp->GetLine(), CurLine, n);
Tdbp->GetLine()[n] = '\0';
return RC_OK;
} else if (Rbuf < Nrec && CurBlk != -1)
return RC_EF;
/*********************************************************************/
/* New block. */
/*********************************************************************/
CurNum = 0;
if (++CurBlk >= Block)
return RC_EF;
BlkLen = BlkPos[CurBlk + 1] - BlkPos[CurBlk];
if (!(n = gzread(Zfile, To_Buf, BlkLen))) {
rc = RC_EF;
} else if (n > 0) {
// Get the position of the current line
CurLine = To_Buf;
// Now get the position of the next line
for (NxtLine = CurLine; *NxtLine++ != '\n';) ;
// Set caller line buffer
n = NxtLine - CurLine - Ending;
memcpy(Tdbp->GetLine(), CurLine, n);
Tdbp->GetLine()[n] = '\0';
Rbuf = (CurBlk == Block - 1) ? Last : Nrec;
IsRead = true;
rc = RC_OK;
num_read++;
} else
rc = Zerror(g);
return rc;
strcpy(g->Message, "This AM cannot be used in this version");
return RC_FX;
} // end of ReadBuffer
/***********************************************************************/
......@@ -664,9 +598,8 @@ void ZBKFAM::CloseTableFile(PGLOBAL g)
} else
rc = gzclose(Zfile);
#ifdef DEBTRACE
if (trace)
htrc("ZIP CloseDB: closing %s rc=%d\n", To_File, rc);
#endif
Zfile = NULL; // So we can know whether table is open
//To_Fb->Count = 0; // Avoid double closing by PlugCloseAll
......@@ -770,9 +703,6 @@ int ZIXFAM::ReadBuffer(PGLOBAL g)
CurNum = 0;
Tdbp->SetLine(To_Buf);
//if (++CurBlk >= Block)
// return RC_EF;
if (!(n = gzread(Zfile, To_Buf, Buflen))) {
rc = RC_EF;
} else if (n > 0) {
......
......@@ -38,7 +38,6 @@ class DllExport ZIPFAM : public TXTFAM {
virtual void Reset(void);
virtual int GetFileLength(PGLOBAL g);
virtual int Cardinality(PGLOBAL g) {return (g) ? -1 : 0;}
virtual int MaxBlkSize(PGLOBAL g, int s) {return s;}
virtual bool AllocateBuffer(PGLOBAL g);
virtual int GetRowID(void);
virtual bool RecordPos(PGLOBAL g);
......@@ -78,7 +77,6 @@ class DllExport ZBKFAM : public ZIPFAM {
// Methods
virtual int Cardinality(PGLOBAL g);
virtual int MaxBlkSize(PGLOBAL g, int s);
virtual bool AllocateBuffer(PGLOBAL g);
virtual int GetRowID(void);
virtual bool RecordPos(PGLOBAL g);
......@@ -122,7 +120,7 @@ class DllExport ZIXFAM : public ZBKFAM {
// No additional Members
}; // end of class ZIXFAM
#ifdef NOT_USED
#if 0
/***********************************************************************/
/* This is the DOS/UNIX Access Method class declaration for PlugDB */
/* fixed/variable files compressed using the zlib library functions. */
......@@ -166,6 +164,6 @@ class DllExport ZLBFAM : public BLKFAM {
int *Zlenp; // Pointer to block length
bool Optimized; // true when opt file is available
}; // end of class ZLBFAM
#endif // NOT_USED
#endif // 0
#endif // __FILAMZIP_H
This diff is collapsed.
......@@ -122,8 +122,6 @@ struct ha_table_option_struct {
struct ha_field_option_struct
{
ulonglong offset;
ulonglong freq; // Not used by this version
ulonglong opt; // Not used by this version
ulonglong fldlen;
const char *dateformat;
const char *fieldformat;
......@@ -173,11 +171,13 @@ public:
bool GetBooleanOption(char *opname, bool bdef);
bool SetBooleanOption(char *opname, bool b);
int GetIntegerOption(char *opname);
bool CheckString(const char *str1, const char *str2);
bool SameString(TABLE *tab, char *opn);
bool SetIntegerOption(char *opname, int n);
bool SameChar(TABLE *tab, char *opn);
bool SameInt(TABLE *tab, char *opn);
bool SameBool(TABLE *tab, char *opn);
bool FileExists(const char *fn);
bool NoFieldOptionChange(TABLE *tab);
PFOS GetFieldOptionStruct(Field *fp);
void *GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf);
PIXDEF GetIndexInfo(TABLE_SHARE *s= NULL);
......@@ -241,8 +241,8 @@ public:
*/
ulong index_flags(uint inx, uint part, bool all_parts) const
{
return HA_READ_NEXT | HA_READ_RANGE;
}
return HA_READ_NEXT | HA_READ_RANGE | HA_READ_ORDER | HA_KEYREAD_ONLY;
} // end of index_flags
/** @brief
unireg.cc will call max_supported_record_length(), max_supported_keys(),
......@@ -328,7 +328,7 @@ public:
condition stack.
*/
virtual const COND *cond_push(const COND *cond);
PFIL CheckCond(PGLOBAL g, PFIL filp, AMT tty, Item *cond);
PCFIL CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond);
const char *GetValStr(OPVAL vop, bool neg);
/**
......@@ -418,6 +418,9 @@ const char *GetValStr(OPVAL vop, bool neg);
*/
//int index_last(uchar *buf);
/* Index condition pushdown implementation */
//Item *idx_cond_push(uint keyno, Item* idx_cond);
/** @brief
Unlike index_init(), rnd_init() can be called two consecutive times
without rnd_end() in between (it only makes sense if scan=1). In this
......
......@@ -96,7 +96,7 @@
extern "C" HINSTANCE s_hModule; // Saved module handle
#endif // !WIN32
extern int xtrace;
extern "C" int trace;
PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
......@@ -167,6 +167,29 @@ bool IsFileType(TABTYPE type)
return isfile;
} // end of IsFileType
/***********************************************************************/
/* Return true for table types returning exact row count. */
/***********************************************************************/
bool IsExactType(TABTYPE type)
{
bool exact;
switch (type) {
case TAB_FIX:
case TAB_BIN:
case TAB_DBF:
// case TAB_XML: depends on Multiple || Xpand || Coltype
case TAB_VEC:
exact= true;
break;
default:
exact= false;
break;
} // endswitch type
return exact;
} // end of IsExactType
/***********************************************************************/
/* Return true for table types accepting null fields. */
/***********************************************************************/
......@@ -693,7 +716,7 @@ bool MYCAT::GetIndexInfo(PGLOBAL g, PTABDEF defp)
PRELDEF MYCAT::GetTableDesc(PGLOBAL g, LPCSTR name,
LPCSTR type, PRELDEF *prp)
{
if (xtrace)
if (trace)
printf("GetTableDesc: name=%s am=%s\n", name, SVP(type));
// If not specified get the type of this table
......@@ -712,7 +735,7 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am)
TABTYPE tc;
PRELDEF tdp= NULL;
if (xtrace)
if (trace)
printf("MakeTableDesc: name=%s am=%s\n", name, SVP(am));
/*********************************************************************/
......@@ -771,14 +794,14 @@ PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode, LPCSTR type)
PTDB tdbp= NULL;
LPCSTR name= tablep->GetName();
if (xtrace)
if (trace)
printf("GetTableDB: name=%s\n", name);
// Look for the description of the requested table
tdp= GetTableDesc(g, name, type);
if (tdp) {
if (xtrace)
if (trace)
printf("tdb=%p type=%s\n", tdp, tdp->GetType());
if (tablep->GetQualifier())
......@@ -788,7 +811,7 @@ PTDB MYCAT::GetTable(PGLOBAL g, PTABLE tablep, MODE mode, LPCSTR type)
} // endif tdp
if (tdbp) {
if (xtrace)
if (trace)
printf("tdbp=%p name=%s amtype=%d\n", tdbp, tdbp->GetName(),
tdbp->GetAmType());
tablep->SetTo_Tdb(tdbp);
......
......@@ -36,6 +36,7 @@ typedef class ha_connect *PHC;
TABTYPE GetTypeID(const char *type);
bool IsFileType(TABTYPE type);
bool IsExactType(TABTYPE type);
bool IsTypeNullable(TABTYPE type);
bool IsTypeFixed(TABTYPE type);
bool IsTypeIndexable(TABTYPE type);
......
/************** MyConn C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: MYCONN */
/* ------------- */
/* Version 1.7 */
/* Version 1.8 */
/* */
/* COPYRIGHT: */
/* ---------- */
/* (C) Copyright to the author Olivier BERTRAND 2007-2013 */
/* (C) Copyright to the author Olivier BERTRAND 2007-2014 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
......@@ -48,6 +48,7 @@
extern "C" int trace;
extern MYSQL_PLUGIN_IMPORT uint mysqld_port;
extern MYSQL_PLUGIN_IMPORT char *mysqld_unix_port;
// Returns the current used port
uint GetDefaultPort(void)
......@@ -283,8 +284,11 @@ 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
query = (char *)srcdef;
// Open a MySQL connection for this table
if (myc.Open(g, host, db, user, pwd, port))
......@@ -292,7 +296,7 @@ PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db,
// Send the source command to MySQL
if (myc.ExecSQL(g, query, &w) == RC_OK)
qrp = myc.GetResult(g);
qrp = myc.GetResult(g, true);
myc.Close();
return qrp;
......@@ -337,6 +341,7 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
const char *user, const char *pwd,
int pt)
{
const char *pipe = NULL;
uint cto = 60, nrt = 120;
m_DB = mysql_init(NULL);
......@@ -353,6 +358,16 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
mysql_options(m_DB, MYSQL_OPT_READ_TIMEOUT, &nrt);
//mysql_options(m_DB, MYSQL_OPT_WRITE_TIMEOUT, ...);
#if defined(WIN32)
if (!strcmp(host, ".")) {
mysql_options(m_DB, MYSQL_OPT_NAMED_PIPE, NULL);
pipe = mysqld_unix_port;
} // endif host
#else // !WIN32
if (!strcmp(host, "localhost"))
pipe = mysqld_unix_port;
#endif // !WIN32
#if 0
if (pwd && !strcmp(pwd, "*")) {
if (GetPromptAnswer(g, "*Enter password:")) {
......@@ -364,7 +379,7 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
} // endif pwd
#endif // 0
if (!mysql_real_connect(m_DB, host, user, pwd, db, pt, NULL, CLIENT_MULTI_RESULTS)) {
if (!mysql_real_connect(m_DB, host, user, pwd, db, pt, pipe, CLIENT_MULTI_RESULTS)) {
#if defined(_DEBUG)
sprintf(g->Message, "mysql_real_connect failed: (%d) %s",
mysql_errno(m_DB), mysql_error(m_DB));
......@@ -673,7 +688,7 @@ MYSQL_FIELD *MYSQLC::GetNextField(void)
/***********************************************************************/
PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb)
{
char *fmt;
char *fmt, v;
int n;
bool uns;
PCOLRES *pcrp, crp;
......@@ -702,7 +717,6 @@ PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb)
qrp->Nblin = 0;
qrp->Cursor = 0;
//for (fld = mysql_fetch_field(m_Res); fld;
// fld = mysql_fetch_field(m_Res)) {
for (fld = GetNextField(); fld; fld = GetNextField()) {
......@@ -715,17 +729,19 @@ PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb)
crp->Name = (char*)PlugSubAlloc(g, NULL, fld->name_length + 1);
strcpy(crp->Name, fld->name);
if ((crp->Type = MYSQLtoPLG(fld->type)) == TYPE_ERROR) {
if ((crp->Type = MYSQLtoPLG(fld->type, &v)) == TYPE_ERROR) {
sprintf(g->Message, "Type %d not supported for column %s",
fld->type, crp->Name);
return NULL;
} else if (crp->Type == TYPE_DATE && !pdb)
// For direct MySQL connection, display the MySQL date string
crp->Type = TYPE_STRING;
else
crp->Var = v;
crp->Prec = (crp->Type == TYPE_DOUBLE || crp->Type == TYPE_DECIM)
? fld->decimals : 0;
crp->Length = fld->max_length;
crp->Length = max(fld->length, fld->max_length);
crp->Clen = GetTypeSize(crp->Type, crp->Length);
uns = (fld->flags & (UNSIGNED_FLAG | ZEROFILL_FLAG)) ? true : false;
......
......@@ -63,15 +63,10 @@ class DllItem MYSQLC {
bool Connected(void);
// Methods
// int GetCurPos(void) {return (m_Res) ? N : 0;}
// int GetProgCur(void) {return N;}
int GetResultSize(PGLOBAL g, PSZ sql);
int Open(PGLOBAL g, const char *host, const char *db,
const char *user= "root", const char *pwd= "*",
int pt= 0);
//ulong GetThreadID(void);
//ulong ServerVersion(void);
//const char *ServerInfo(void);
int KillQuery(ulong id);
int ExecSQL(PGLOBAL g, const char *query, int *w = NULL);
int ExecSQLcmd(PGLOBAL g, const char *query, int *w);
......@@ -87,7 +82,6 @@ class DllItem MYSQLC {
void Rewind(void);
void FreeResult(void);
void Close(void);
//void DiscardResults(void);
protected:
MYSQL_FIELD *GetNextField(void);
......
#
# Testing indexing with ALTER on inward table (in-place)
#
CREATE TABLE t1 (c INT NOT NULL, d CHAR(10) NOT NULL) ENGINE=CONNECT;
Warnings:
Warning 1105 No table_type. Will be set to DOS
Warning 1105 No file name. Table will use t1.dos
INSERT INTO t1 VALUES (1,'One'), (2,'Two'), (3,'Three');
SELECT * FROM t1;
c d
1 One
2 Two
3 Three
CREATE INDEX xc ON t1(c);
DESCRIBE SELECT * FROM t1 WHERE c = 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref xc xc 4 const 1
DROP INDEX xc ON t1;
CREATE INDEX xd ON t1(d);
DROP INDEX xd ON t1;
ALTER TABLE t1 ADD INDEX xc (c), ADD INDEX xd (d);
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 1 xc 1 c A NULL NULL NULL XPLUG
t1 1 xd 1 d A NULL NULL NULL XPLUG
ALTER TABLE t1 DROP INDEX xc, DROP INDEX xd;
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
#
# Testing modifying columns inward table (not in-place)
#
ALTER TABLE t1 MODIFY COLUMN c CHAR(5) NOT NULL;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` char(5) NOT NULL,
`d` char(10) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1
SELECT * FROM t1;
c d
1 One
2 Two
3 Three
ALTER TABLE t1 MODIFY COLUMN c INT NOT NULL;
#
# Fails because indexing must be in-place
#
ALTER TABLE t1 MODIFY COLUMN c CHAR(10) NOT NULL, ADD INDEX xd (d);
ERROR 0A000: Alter operations not supported together by CONNECT
#
# Testing changing table type (not in-place)
#
ALTER TABLE t1 TABLE_TYPE=CSV HEADER=1 QUOTED=1;
SELECT * FROM t1;
c d
1 One
2 Two
3 Three
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` int(11) NOT NULL,
`d` char(10) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=CSV `HEADER`=1 `QUOTED`=1
# create an outward table used to see the t1 file
CREATE TABLE t2 (line VARCHAR(100) NOT NULL) ENGINE=CONNECT FILE_NAME='t1.csv';
Warnings:
Warning 1105 No table_type. Will be set to DOS
SELECT * FROM t2;
line
"c","d"
1,"One"
2,"Two"
3,"Three"
#
# Testing changing engine
#
DROP TABLE t1;
CREATE TABLE t1 (c INT NOT NULL, d CHAR(10) NOT NULL) ENGINE=CONNECT;
Warnings:
Warning 1105 No table_type. Will be set to DOS
Warning 1105 No file name. Table will use t1.dos
INSERT INTO t1 VALUES (1,'One'), (2,'Two'), (3,'Three');
ALTER TABLE t1 ADD INDEX xc (c), ADD INDEX xd (d);
ALTER TABLE t1 ENGINE = MYISAM;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` int(11) NOT NULL,
`d` char(10) NOT NULL,
KEY `xc` (`c`),
KEY `xd` (`d`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 1 xc 1 c A NULL NULL NULL BTREE
t1 1 xd 1 d A NULL NULL NULL BTREE
SELECT * FROM t1;
c d
1 One
2 Two
3 Three
ALTER TABLE t1 ENGINE = CONNECT TABLE_TYPE=DBF;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` int(11) NOT NULL,
`d` char(10) NOT NULL,
KEY `xc` (`c`),
KEY `xd` (`d`)
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=DBF
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 1 xc 1 c A NULL NULL NULL XPLUG
t1 1 xd 1 d A NULL NULL NULL XPLUG
SELECT * FROM t1;
c d
1 One
2 Two
3 Three
DROP TABLE t1, t2;
#
# Testing ALTER on outward tables
#
CREATE TABLE t1 (c INT NOT NULL, d CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='tf1.txt' ENDING=1;
INSERT INTO t1 VALUES (1,'One'), (2,'Two'), (3,'Three');
SELECT * FROM t1;
c d
1 One
2 Two
3 Three
CREATE TABLE t2 (line VARCHAR(100) NOT NULL) ENGINE=CONNECT FILE_NAME='tf1.txt';
Warnings:
Warning 1105 No table_type. Will be set to DOS
SELECT * FROM t2;
line
1One
2Two
3Three
#
# Indexing works the same
#
ALTER TABLE t1 ADD INDEX xc (c), ADD INDEX xd (d);
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t1 1 xc 1 c A NULL NULL NULL XPLUG
t1 1 xd 1 d A NULL NULL NULL XPLUG
SELECT d FROM t1 WHERE c = 2;
d
Two
ALTER TABLE t1 DROP INDEX xc, DROP INDEX xd;
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
#
# Other alterations do not modify the file
#
ALTER TABLE t1 MODIFY COLUMN c CHAR(5) NOT NULL;
Warnings:
Warning 1105 This is an outward table, table data were not modified.
SELECT * FROM t2;
line
1One
2Two
3Three
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` char(5) NOT NULL,
`d` char(10) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=fix `FILE_NAME`='tf1.txt' `ENDING`=1
SELECT * FROM t1;
ERROR HY000: Got error 174 'File tf1.txt is not fixed length, len=66 lrecl=16' from CONNECT
ALTER TABLE t1 MODIFY COLUMN c INT NOT NULL;
Warnings:
Warning 1105 This is an outward table, table data were not modified.
#
# Changing column order
#
ALTER TABLE t1 MODIFY COLUMN c INT NOT NULL AFTER d;
Warnings:
Warning 1105 This is an outward table, table data were not modified.
SELECT * FROM t2;
line
1One
2Two
3Three
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`d` char(10) NOT NULL,
`c` int(11) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=fix `FILE_NAME`='tf1.txt' `ENDING`=1
# Wrong result
SELECT * FROM t1;
d c
1
2
3
ALTER TABLE t1 MODIFY COLUMN c INT NOT NULL FIRST;
Warnings:
Warning 1105 This is an outward table, table data were not modified.
# What should have been done
ALTER TABLE t1 MODIFY c INT NOT NULL FLAG=0 AFTER d, MODIFY d CHAR(10) NOT NULL FLAG=11;
Warnings:
Warning 1105 This is an outward table, table data were not modified.
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`d` char(10) NOT NULL `FLAG`=11,
`c` int(11) NOT NULL `FLAG`=0
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=fix `FILE_NAME`='tf1.txt' `ENDING`=1
SELECT * FROM t1;
d c
One 1
Two 2
Three 3
#
# Changing to another engine is Ok
# However, the data file is not deleted.
#
ALTER TABLE t1 ENGINE=MARIA;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`d` char(10) NOT NULL `FLAG`=11,
`c` int(11) NOT NULL `FLAG`=0
) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 `TABLE_TYPE`=fix `FILE_NAME`='tf1.txt' `ENDING`=1
SELECT * from t1;
d c
One 1
Two 2
Three 3
SELECT * from t2;
line
1One
2Two
3Three
#
# Changing back to CONNECT fails
# Sure enough, the data file was not deleted.
#
ALTER TABLE t1 ENGINE=CONNECT;
ERROR HY000: Operation denied. Table data would be lost.
#
# But changing back to CONNECT succeed
# if the data file does not exist.
#
ALTER TABLE t1 ENGINE=CONNECT;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`d` char(10) NOT NULL `FLAG`=11,
`c` int(11) NOT NULL `FLAG`=0
) ENGINE=CONNECT DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 `TABLE_TYPE`=fix `FILE_NAME`='tf1.txt' `ENDING`=1
SELECT * from t1;
d c
One 1
Two 2
Three 3
SELECT * from t2;
line
1One
2Two
3Three
DROP TABLE t1, t2;
Warnings:
Warning 1105 No file name. Table will use t1.xml
#
# Testing changing table type (not in-place)
#
CREATE TABLE t1 (c INT NOT NULL, d CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=CSV HEADER=1 QUOTED=1;
Warnings:
Warning 1105 No file name. Table will use t1.csv
INSERT INTO t1 VALUES (1,'One'), (2,'Two'), (3,'Three');
SELECT * FROM t1;
c d
1 One
2 Two
3 Three
# This would fail if the top node name is not specified.
# This is because the XML top node name defaults to the table name.
# Sure enough the temporary table name begins with '#' and is rejected by XML.
# Therefore the top node name must be specified (along with the row nodes name).
ALTER TABLE t1 TABLE_TYPE=XML TABNAME=t1 OPTION_LIST='rownode=row';
SELECT * FROM t1;
c d
1 One
2 Two
3 Three
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` int(11) NOT NULL,
`d` char(10) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `HEADER`=1 `QUOTED`=1 `TABLE_TYPE`=XML `TABNAME`=t1 `OPTION_LIST`='rownode=row'
# Let us see the XML file
CREATE TABLE t2 (line VARCHAR(100) NOT NULL) ENGINE=CONNECT FILE_NAME='t1.xml';
Warnings:
Warning 1105 No table_type. Will be set to DOS
SELECT * FROM t2;
line
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created by CONNECT Version 1.02.0002 March 16, 2014 -->
<t1>
<row>
<TH>c</TH>
<TH>d</TH>
</row>
<row>
<c>1</c>
<d>One</d>
</row>
<row>
<c>2</c>
<d>Two</d>
</row>
<row>
<c>3</c>
<d>Three</d>
</row>
</t1>
# NOTE: The first (ignored) row is due to the remaining HEADER=1 option.
# Testing field option modification
ALTER TABLE t1 MODIFY d CHAR(10) NOT NULL FIELD_FORMAT='@', HEADER=0;
SELECT * FROM t1;
c d
1 One
2 Two
3 Three
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` int(11) NOT NULL,
`d` char(10) NOT NULL `FIELD_FORMAT`='@'
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `QUOTED`=1 `TABLE_TYPE`=XML `TABNAME`=t1 `OPTION_LIST`='rownode=row' `HEADER`=0
SELECT * FROM t2;
line
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created by CONNECT Version 1.02.0002 March 16, 2014 -->
<t1>
<row d="One">
<c>1</c>
</row>
<row d="Two">
<c>2</c>
</row>
<row d="Three">
<c>3</c>
</row>
</t1>
DROP TABLE t1, t2;
......@@ -390,22 +390,22 @@ CREATE TABLE t1
(
a BLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
ERROR HY000: Unsupported type for column a
ERROR 42000: Storage engine CONNECT doesn't support BLOB/TEXT columns
CREATE TABLE t1
(
a TINYBLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
ERROR HY000: Unsupported type for column a
ERROR 42000: Storage engine CONNECT doesn't support BLOB/TEXT columns
CREATE TABLE t1
(
a MEDIUMBLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
ERROR HY000: Unsupported type for column a
ERROR 42000: Storage engine CONNECT doesn't support BLOB/TEXT columns
CREATE TABLE t1
(
a LONGBLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
ERROR HY000: Unsupported type for column a
ERROR 42000: Storage engine CONNECT doesn't support BLOB/TEXT columns
#
# Testing DATE
#
......
......@@ -68,64 +68,64 @@ DROP TABLE t1;
CREATE TABLE t1
(
name char(12) not null,
city char(12) not null,
city char(11) not null,
birth date not null date_format='DD/MM/YYYY',
hired date not null date_format='DD/MM/YYYY' flag=36
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boys.txt' ENDING=1;
SELECT * FROM t1;
name city birth hired
John Boston 2 1986-01-05 2010-06-02
Henry Boston 0 1987-06-07 2008-04-01
George San Jose 1 1981-08-01 2010-06-02
Sam Chicago 2 1979-11-02 2007-10-10
James Dallas 1 1992-05-03 2009-12-14
Bill Boston 1 1986-09-01 2008-02-10
John Boston 1986-01-25 2010-06-02
Henry Boston 1987-06-07 2008-04-01
George San Jose 1981-08-10 2010-06-02
Sam Chicago 1979-11-22 2007-10-10
James Dallas 1992-05-13 2009-12-14
Bill Boston 1986-09-11 2008-02-10
DROP TABLE t1;
CREATE TABLE t1
(
name char(12) not null,
city char(12) not null,
city char(11) not null,
birth date not null date_format='DD/MM/YYYY',
hired date not null date_format='DD/MM/YYYY' flag=36
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boys.txt' LRECL=47 ENDING=1;
SELECT * FROM t1;
name city birth hired
John Boston 2 1986-01-05 2010-06-02
Henry Boston 0 1987-06-07 2008-04-01
George San Jose 1 1981-08-01 2010-06-02
Sam Chicago 2 1979-11-02 2007-10-10
James Dallas 1 1992-05-03 2009-12-14
Bill Boston 1 1986-09-01 2008-02-10
John Boston 1986-01-25 2010-06-02
Henry Boston 1987-06-07 2008-04-01
George San Jose 1981-08-10 2010-06-02
Sam Chicago 1979-11-22 2007-10-10
James Dallas 1992-05-13 2009-12-14
Bill Boston 1986-09-11 2008-02-10
DROP TABLE t1;
CREATE TABLE t1
(
name char(12) not null,
city char(12) not null,
city char(11) not null,
birth date not null date_format='DD/MM/YYYY',
hired date not null date_format='DD/MM/YYYY' flag=36
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boyswin.txt' ENDING=2;
SELECT * FROM t1;
name city birth hired
John Boston 2 1986-01-05 2010-06-02
Henry Boston 0 1987-06-07 2008-04-01
George San Jose 1 1981-08-01 2010-06-02
Sam Chicago 2 1979-11-02 2007-10-10
James Dallas 1 1992-05-03 2009-12-14
Bill Boston 1 1986-09-01 2008-02-10
John Boston 1986-01-25 2010-06-02
Henry Boston 1987-06-07 2008-04-01
George San Jose 1981-08-10 2010-06-02
Sam Chicago 1979-11-22 2007-10-10
James Dallas 1992-05-13 2009-12-14
Bill Boston 1986-09-11 2008-02-10
DROP TABLE t1;
CREATE TABLE t1
(
name char(12) not null,
city char(12) not null,
city char(11) not null,
birth date not null date_format='DD/MM/YYYY',
hired date not null date_format='DD/MM/YYYY' flag=36
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boyswin.txt' LRECL=47 ENDING=2;
SELECT * FROM t1;
name city birth hired
John Boston 2 1986-01-05 2010-06-02
Henry Boston 0 1987-06-07 2008-04-01
George San Jose 1 1981-08-01 2010-06-02
Sam Chicago 2 1979-11-02 2007-10-10
James Dallas 1 1992-05-03 2009-12-14
Bill Boston 1 1986-09-01 2008-02-10
John Boston 1986-01-25 2010-06-02
Henry Boston 1987-06-07 2008-04-01
George San Jose 1981-08-10 2010-06-02
Sam Chicago 1979-11-22 2007-10-10
James Dallas 1992-05-13 2009-12-14
Bill Boston 1986-09-11 2008-02-10
DROP TABLE t1;
......@@ -224,3 +224,30 @@ Kevin 0 2 6
Donald 1 0 3
DROP TABLE pivet;
DROP TABLE pets;
#
# MDEV-5734
#
CREATE TABLE fruit (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(32) DEFAULT NULL,
`cnt` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
INSERT INTO fruit VALUES (1,'apple',1),(2,'banana',1),(3,'apple',2),(4,'cherry',4),(5,'durazno',2);
SELECT * FROM fruit;
id name cnt
1 apple 1
2 banana 1
3 apple 2
4 cherry 4
5 durazno 2
CREATE TABLE fruit_pivot ENGINE=CONNECT TABLE_TYPE=pivot TABNAME=fruit;
SELECT * FROM fruit_pivot;
id apple banana cherry durazno
1 1 0 0 0
2 0 1 0 0
3 2 0 0 0
4 0 0 4 0
5 0 0 0 2
DROP TABLE fruit_pivot;
DROP TABLE fruit;
......@@ -413,7 +413,7 @@ DROP TABLE t1;
SET @a=LOAD_FILE('MYSQLD_DATADIR/test/t1.xml');
SELECT CAST(@a AS CHAR CHARACTER SET latin1);
CAST(@a AS CHAR CHARACTER SET latin1) <?xml version="1.0" encoding="iso-8859-1"?>
<!-- Created by CONNECT Version 1.02.0001 February 03, 2014 -->
<!-- Created by CONNECT Version 1.02.0002 March 16, 2014 -->
<t1>
<line>
<node>ÀÁÂÃ</node>
......
......@@ -5,6 +5,11 @@ package My::Suite::Connect;
return "No CONNECT engine" unless $ENV{HA_CONNECT_SO} or
$::mysqld_variables{'connect'} eq "ON";
# RECOMPILE_FOR_EMBEDDED also means that a plugin
# cannot be dynamically loaded into embedded
return "Not run for embedded server" if $::opt_embedded_server and
$ENV{HA_CONNECT_SO};
sub is_default { 1 }
bless { };
......
let $MYSQLD_DATADIR= `select @@datadir`;
--echo #
--echo # Testing indexing with ALTER on inward table (in-place)
--echo #
CREATE TABLE t1 (c INT NOT NULL, d CHAR(10) NOT NULL) ENGINE=CONNECT;
INSERT INTO t1 VALUES (1,'One'), (2,'Two'), (3,'Three');
SELECT * FROM t1;
CREATE INDEX xc ON t1(c);
DESCRIBE SELECT * FROM t1 WHERE c = 2;
DROP INDEX xc ON t1;
CREATE INDEX xd ON t1(d);
DROP INDEX xd ON t1;
ALTER TABLE t1 ADD INDEX xc (c), ADD INDEX xd (d);
SHOW INDEX FROM t1;
ALTER TABLE t1 DROP INDEX xc, DROP INDEX xd;
SHOW INDEX FROM t1;
--echo #
--echo # Testing modifying columns inward table (not in-place)
--echo #
ALTER TABLE t1 MODIFY COLUMN c CHAR(5) NOT NULL;
SHOW CREATE TABLE t1;
SELECT * FROM t1;
ALTER TABLE t1 MODIFY COLUMN c INT NOT NULL;
--echo #
--echo # Fails because indexing must be in-place
--echo #
--error ER_ALTER_OPERATION_NOT_SUPPORTED
ALTER TABLE t1 MODIFY COLUMN c CHAR(10) NOT NULL, ADD INDEX xd (d);
--echo #
--echo # Testing changing table type (not in-place)
--echo #
ALTER TABLE t1 TABLE_TYPE=CSV HEADER=1 QUOTED=1;
SELECT * FROM t1;
SHOW CREATE TABLE t1;
--echo # create an outward table used to see the t1 file
CREATE TABLE t2 (line VARCHAR(100) NOT NULL) ENGINE=CONNECT FILE_NAME='t1.csv';
SELECT * FROM t2;
--echo #
--echo # Testing changing engine
--echo #
DROP TABLE t1;
CREATE TABLE t1 (c INT NOT NULL, d CHAR(10) NOT NULL) ENGINE=CONNECT;
INSERT INTO t1 VALUES (1,'One'), (2,'Two'), (3,'Three');
ALTER TABLE t1 ADD INDEX xc (c), ADD INDEX xd (d);
ALTER TABLE t1 ENGINE = MYISAM;
SHOW CREATE TABLE t1;
SHOW INDEX FROM t1;
SELECT * FROM t1;
ALTER TABLE t1 ENGINE = CONNECT TABLE_TYPE=DBF;
SHOW CREATE TABLE t1;
SHOW INDEX FROM t1;
SELECT * FROM t1;
DROP TABLE t1, t2;
--echo #
--echo # Testing ALTER on outward tables
--echo #
CREATE TABLE t1 (c INT NOT NULL, d CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='tf1.txt' ENDING=1;
INSERT INTO t1 VALUES (1,'One'), (2,'Two'), (3,'Three');
SELECT * FROM t1;
CREATE TABLE t2 (line VARCHAR(100) NOT NULL) ENGINE=CONNECT FILE_NAME='tf1.txt';
SELECT * FROM t2;
--echo #
--echo # Indexing works the same
--echo #
ALTER TABLE t1 ADD INDEX xc (c), ADD INDEX xd (d);
SHOW INDEX FROM t1;
SELECT d FROM t1 WHERE c = 2;
ALTER TABLE t1 DROP INDEX xc, DROP INDEX xd;
SHOW INDEX FROM t1;
--echo #
--echo # Other alterations do not modify the file
--echo #
ALTER TABLE t1 MODIFY COLUMN c CHAR(5) NOT NULL;
SELECT * FROM t2;
SHOW CREATE TABLE t1;
#Wrong result
--error ER_GET_ERRMSG
SELECT * FROM t1;
ALTER TABLE t1 MODIFY COLUMN c INT NOT NULL;
--echo #
--echo # Changing column order
--echo #
ALTER TABLE t1 MODIFY COLUMN c INT NOT NULL AFTER d;
SELECT * FROM t2;
SHOW CREATE TABLE t1;
--echo # Wrong result
SELECT * FROM t1;
ALTER TABLE t1 MODIFY COLUMN c INT NOT NULL FIRST;
--echo # What should have been done
ALTER TABLE t1 MODIFY c INT NOT NULL FLAG=0 AFTER d, MODIFY d CHAR(10) NOT NULL FLAG=11;
SHOW CREATE TABLE t1;
SELECT * FROM t1;
--echo #
--echo # Changing to another engine is Ok
--echo # However, the data file is not deleted.
--echo #
ALTER TABLE t1 ENGINE=MARIA;
SHOW CREATE TABLE t1;
SELECT * from t1;
SELECT * from t2;
--echo #
--echo # Changing back to CONNECT fails
--echo # Sure enough, the data file was not deleted.
--echo #
--error ER_UNKNOWN_ERROR
ALTER TABLE t1 ENGINE=CONNECT;
--echo #
--echo # But changing back to CONNECT succeed
--echo # if the data file does not exist.
--echo #
--remove_file $MYSQLD_DATADIR/test/tf1.txt
ALTER TABLE t1 ENGINE=CONNECT;
SHOW CREATE TABLE t1;
SELECT * from t1;
SELECT * from t2;
DROP TABLE t1, t2;
#
# Clean up
#
--remove_file $MYSQLD_DATADIR/test/tf1.txt
--source have_libxml2.inc
--echo #
--echo # Testing changing table type (not in-place)
--echo #
CREATE TABLE t1 (c INT NOT NULL, d CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=CSV HEADER=1 QUOTED=1;
INSERT INTO t1 VALUES (1,'One'), (2,'Two'), (3,'Three');
SELECT * FROM t1;
--echo # This would fail if the top node name is not specified.
--echo # This is because the XML top node name defaults to the table name.
--echo # Sure enough the temporary table name begins with '#' and is rejected by XML.
--echo # Therefore the top node name must be specified (along with the row nodes name).
ALTER TABLE t1 TABLE_TYPE=XML TABNAME=t1 OPTION_LIST='rownode=row';
SELECT * FROM t1;
SHOW CREATE TABLE t1;
--echo # Let us see the XML file
CREATE TABLE t2 (line VARCHAR(100) NOT NULL) ENGINE=CONNECT FILE_NAME='t1.xml';
SELECT * FROM t2;
--echo # NOTE: The first (ignored) row is due to the remaining HEADER=1 option.
--echo # Testing field option modification
ALTER TABLE t1 MODIFY d CHAR(10) NOT NULL FIELD_FORMAT='@', HEADER=0;
SELECT * FROM t1;
SHOW CREATE TABLE t1;
SELECT * FROM t2;
DROP TABLE t1, t2;
......@@ -293,22 +293,22 @@ CREATE TABLE t1
--echo #
--echo # Testing BLOB
--echo #
--error ER_UNKNOWN_ERROR
--error ER_TABLE_CANT_HANDLE_BLOB
CREATE TABLE t1
(
a BLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR
--error ER_TABLE_CANT_HANDLE_BLOB
CREATE TABLE t1
(
a TINYBLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR
--error ER_TABLE_CANT_HANDLE_BLOB
CREATE TABLE t1
(
a MEDIUMBLOB
) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.dbf';
--error ER_UNKNOWN_ERROR
--error ER_TABLE_CANT_HANDLE_BLOB
CREATE TABLE t1
(
a LONGBLOB
......
......@@ -61,7 +61,7 @@ DROP TABLE t1;
CREATE TABLE t1
(
name char(12) not null,
city char(12) not null,
city char(11) not null,
birth date not null date_format='DD/MM/YYYY',
hired date not null date_format='DD/MM/YYYY' flag=36
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boys.txt' ENDING=1;
......@@ -71,7 +71,7 @@ DROP TABLE t1;
CREATE TABLE t1
(
name char(12) not null,
city char(12) not null,
city char(11) not null,
birth date not null date_format='DD/MM/YYYY',
hired date not null date_format='DD/MM/YYYY' flag=36
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boys.txt' LRECL=47 ENDING=1;
......@@ -82,7 +82,7 @@ DROP TABLE t1;
CREATE TABLE t1
(
name char(12) not null,
city char(12) not null,
city char(11) not null,
birth date not null date_format='DD/MM/YYYY',
hired date not null date_format='DD/MM/YYYY' flag=36
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boyswin.txt' ENDING=2;
......@@ -92,7 +92,7 @@ DROP TABLE t1;
CREATE TABLE t1
(
name char(12) not null,
city char(12) not null,
city char(11) not null,
birth date not null date_format='DD/MM/YYYY',
hired date not null date_format='DD/MM/YYYY' flag=36
) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boyswin.txt' LRECL=47 ENDING=2;
......
......@@ -143,4 +143,21 @@ SELECT * FROM pivet;
DROP TABLE pivet;
DROP TABLE pets;
--echo #
--echo # MDEV-5734
--echo #
CREATE TABLE fruit (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(32) DEFAULT NULL,
`cnt` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
INSERT INTO fruit VALUES (1,'apple',1),(2,'banana',1),(3,'apple',2),(4,'cherry',4),(5,'durazno',2);
SELECT * FROM fruit;
CREATE TABLE fruit_pivot ENGINE=CONNECT TABLE_TYPE=pivot TABNAME=fruit;
SELECT * FROM fruit_pivot;
DROP TABLE fruit_pivot;
DROP TABLE fruit;
--remove_file $MYSQLD_DATADIR/test/expenses.txt
......@@ -58,12 +58,8 @@ int MYSQLtoPLG(char *typname, char *var)
type = TYPE_ERROR;
if (var) {
// This is to make the difference between CHAR and VARCHAR
if (type == TYPE_STRING && stricmp(typname, "char"))
*var = 'V';
// This is to make the difference between temporal values
if (type == TYPE_DATE) {
// This is to make the difference between temporal values
if (!stricmp(typname, "date"))
*var = 'D';
else if (!stricmp(typname, "datetime"))
......@@ -75,7 +71,11 @@ int MYSQLtoPLG(char *typname, char *var)
else if (!stricmp(typname, "year"))
*var = 'Y';
} // endif type
} else if (type == TYPE_STRING && stricmp(typname, "char"))
// This is to make the difference between CHAR and VARCHAR
*var = 'V';
else
*var = 0;
} // endif var
......@@ -200,7 +200,6 @@ int MYSQLtoPLG(int mytype, char *var)
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
if (var) *var = 'V';
case MYSQL_TYPE_STRING:
type = TYPE_STRING;
break;
......@@ -208,6 +207,25 @@ int MYSQLtoPLG(int mytype, char *var)
type = TYPE_ERROR;
} // endswitch mytype
if (var) switch (mytype) {
// This is to make the difference between CHAR and VARCHAR
case MYSQL_TYPE_VAR_STRING:
#if !defined(ALPHA)
case MYSQL_TYPE_VARCHAR:
#endif // !ALPHA)
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB: *var = 'V'; break;
// This is to make the difference between temporal values
case MYSQL_TYPE_TIMESTAMP: *var = 'S'; break;
case MYSQL_TYPE_DATE: *var = 'D'; break;
case MYSQL_TYPE_DATETIME: *var = 'A'; break;
case MYSQL_TYPE_YEAR: *var = 'Y'; break;
case MYSQL_TYPE_TIME: *var = 'T'; break;
default: *var = 0;
} // endswitch mytype
return type;
} // end of MYSQLtoPLG
......
......@@ -78,7 +78,7 @@ void _splitpath(LPCSTR name, LPSTR drive, LPSTR dir, LPSTR fn, LPSTR ft)
LPCSTR p2, p = name;
#ifdef DEBTRACE
fprintf(debug,"SplitPath: name=%s [%s (%d)]\n",
htrc("SplitPath: name=%s [%s (%d)]\n",
XSTR(name), XSTR(__FILE__), __LINE__);
#endif
......@@ -100,7 +100,7 @@ void _splitpath(LPCSTR name, LPSTR drive, LPSTR dir, LPSTR fn, LPSTR ft)
if (fn) strcpy(fn, p);
#ifdef DEBTRACE
fprintf(debug,"SplitPath: name=%s drive=%s dir=%s filename=%s type=%s [%s(%d)]\n",
htrc("SplitPath: name=%s drive=%s dir=%s filename=%s type=%s [%s(%d)]\n",
XSTR(name), XSTR(drive), XSTR(dir), XSTR(fn), XSTR(ft), __FILE__, __LINE__);
#endif
} /* end of _splitpath */
......@@ -181,7 +181,8 @@ char *_fullpath(char *absPath, const char *relPath, size_t maxLength)
} else {
char buff[2*_MAX_PATH];
assert(getcwd(buff, _MAX_PATH) != NULL);
p= getcwd(buff, _MAX_PATH);
assert(p);
strcat(buff,"/");
strcat(buff, relPath);
strncpy(absPath, buff, maxLength);
......
......@@ -62,146 +62,6 @@ enum INFO {INDX_RC, /* Index of PlugDB return code field */
INDX_SIZE, /* Index of returned data size field */
INDX_MAX}; /* Size of info array */
#ifdef NOT_USED
/**************************************************************************/
/* Internal message types. */
/**************************************************************************/
enum MSGTYP {MST_OPEN = 10, /* Code for old connecting message */
MST_COMMAND = 11, /* Code for send command message */
MST_RESULT = 12, /* Code for get result message */
MST_CLOSE = 13, /* Code for disconnecting message */
MST_PROGRESS = 14, /* Code for progress message */
MST_CANCEL = 15, /* Code for cancel message */
MST_PROCESSED = 16, /* Code for already processed msg */
MST_ERROR = 17, /* Code for get error message */
MST_CHAR = 18, /* Code for get char value message */
MST_LONG = 19, /* Code for get int value message */
MST_COLUMN = 20, /* Code for get col value message */
MST_MESSAGE = 21, /* Code for get message message */
MST_HEADER = 22, /* Code for get header message */
MST_SOCKET = 23, /* Code for socket error message */
MST_SHUTDOWN = 24, /* Code for shutdown message */
MST_SOCKPROG = 25, /* Code for socket progress message */
MST_POST = 26, /* Code for post command message */
MST_NEW_OPEN = 27, /* Code for new connecting message */
MST_PROG_NUM = 5}; /* Num of integers in progress msg */
/**************************************************************************/
/* Vendors. */
/**************************************************************************/
enum VENDOR {VDR_UNKNOWN = -2, /* Not known or not connected */
VDR_PlugDB = -1, /* PlugDB */
VDR_OTHER = 0}; /* OEM */
/**************************************************************************/
/* Attribute keys of Result Description structure (arranged by type). */
/**************************************************************************/
enum CKEYS {K_ProgMsg, K_Lang, K_ActiveDB, K_Cmax};
enum LKEYS {K_NBcol, K_NBlin, K_CurPos, K_RC, K_Result, K_Elapsed,
K_Continued, K_Maxsize, K_Affrows, K_Lmax, K_Maxcol,
K_Maxres, K_Maxlin, K_NBparm};
enum NKEYS {K_Type, K_Length, K_Prec, K_DataLen, K_Unsigned, K_Nmax};
/**************************************************************************/
/* Result description structures. */
/**************************************************************************/
typedef struct _MsgTagAttr {
bool fSupplied;
char Attr[MAXMESSAGE];
} MTAG, *PMTAG;
typedef struct _CharTagAttr {
bool fSupplied;
char Attr[MAXDBNAME];
} CTAG, *PCTAG;
typedef struct _LongTagAttr {
bool fSupplied;
int Attr;
} LTAG, *PLTAG;
typedef struct _ColVar {
LTAG Lat[K_Nmax];
CTAG Cat;
} COLVAR, *LPCOLVAR;
typedef struct _ResDesc {
int Maxcol; /* Max number of columns */
int Colnum; /* Number of columns */
MTAG Mat; /* Message */
CTAG Cat[K_Cmax]; /* Character attributes */
LTAG Lat[K_Lmax]; /* Long int attributes */
COLVAR Col[1]; /* Column attributes */
} RDESC, *PRDESC;
/**************************************************************************/
/* Exported PlugDB client functions in Plgcnx DLL. */
/**************************************************************************/
#if !defined(CNXFUNC)
#if defined(UNIX) || defined(UNIV_LINUX)
#undef __stdcall
#define __stdcall
#endif
#if defined(NOLIB) /* Dynamic link of plgcnx.dll */
#define CNXFUNC(f) (__stdcall *f)
#else /* LIB */ /* Static link with plgcnx.lib */
#define CNXFUNC(f) __stdcall f
#endif
#endif
#if !defined(CNXKEY)
#define CNXKEY uint
#endif
#if !defined(XTRN)
#define XTRN
#endif
//#if !defined(NO_FUNC)
#ifdef __cplusplus
extern "C" {
#endif
XTRN int CNXFUNC(PLGConnect) (CNXKEY *, const char *, bool);
XTRN int CNXFUNC(PLGSendCommand) (CNXKEY, const char *, void *, int, int *);
XTRN int CNXFUNC(PLGGetResult) (CNXKEY, void *, int, int *, bool);
XTRN int CNXFUNC(PLGDisconnect) (CNXKEY);
XTRN int CNXFUNC(PLGGetErrorMsg) (CNXKEY, char *, int, int *);
XTRN bool CNXFUNC(PLGGetCharValue)(CNXKEY, char *, int, int);
XTRN bool CNXFUNC(PLGGetIntValue)(CNXKEY, int *, int);
XTRN bool CNXFUNC(PLGGetColValue) (CNXKEY, int *, int, int);
XTRN bool CNXFUNC(PLGGetMessage) (CNXKEY, char *, int);
XTRN bool CNXFUNC(PLGGetHeader) (CNXKEY, char *, int, int, int);
#ifdef __cplusplus
}
#endif
//#endif /* !NO_FUNC */
/**************************************************************************/
/* Convenience function Definitions */
/**************************************************************************/
#define PLGPostCommand(T,C) PLGSendCommand(T,C,NULL,0,NULL)
#if defined(FNCMAC)
#define PLGGetProgMsg(T,C,S) PLGGetCharValue(T,C,S,K_ProgMsg)
#define PLGGetLangID(T,C,S) PLGGetCharValue(T,C,S,K_Lang)
#define PLGGetActiveDB(T,C,S) PLGGetCharValue(T,C,S,K_ActiveDB)
#define PLGGetCursorPos(T,L) PLGGetIntValue(T,L,K_CurPos)
#define PLGGetResultType(T,L) PLGGetIntValue(T,L,K_Result)
#define PLGGetNBcol(T,L) PLGGetIntValue(T,L,K_NBcol)
#define PLGGetNBlin(T,L) PLGGetIntValue(T,L,K_NBlin)
#define PLGGetRetCode(T,L) PLGGetIntValue(T,L,K_RC)
#define PLGGetElapsed(T,L) PLGGetIntValue(T,L,K_Elapsed)
#define PLGGetContinued(T,L) PLGGetIntValue(T,L,K_Continued)
#define PLGGetMaxSize(T,L) PLGGetIntValue(T,L,K_Maxsize)
#define PLGGetLength(T,L,C) PLGGetColValue(T,L,K_Length,C)
#define PLGGetDataSize(T,L,C) PLGGetColValue(T,L,K_DataLen,C)
#define PLGGetDecimal(T,L,C) PLGGetColValue(T,L,K_Prec,C)
#define PLGGetType(T,L,C) PLGGetColValue(T,L,K_Type,C)
#endif /* FNCMAC */
#endif // NOT_USED
#endif /* !_PLGCNX_H */
/* ------------------------- End of Plgcnx.h ---------------------------- */
......@@ -26,7 +26,6 @@
enum BLKTYP {TYPE_TABLE = 50, /* Table Name/Srcdef/... Block */
TYPE_COLUMN = 51, /* Column Name/Qualifier Block */
// TYPE_OPVAL = 52, /* Operator value (OPVAL) */
TYPE_TDB = 53, /* Table Description Block */
TYPE_COLBLK = 54, /* Column Description Block */
TYPE_PSZ = 64, /* Pointer to String ended by 0 */
......@@ -34,8 +33,6 @@ enum BLKTYP {TYPE_TABLE = 50, /* Table Name/Srcdef/... Block */
TYPE_XOBJECT = 69, /* Extended DB object */
TYPE_COLCRT = 71, /* Column creation block */
TYPE_CONST = 72, /* Constant */
// TYPE_INDEXDEF = 73, /* Index definition block */
// TYPE_OPER = 74, /* Operator block (OPER) */
/*-------------------- type tokenized string --------------------------*/
TYPE_DATE = 8, /* Timestamp */
......@@ -144,21 +141,19 @@ enum RECFM {RECFM_NAF = -2, /* Not a file */
RECFM_PLG = 5, /* Table accessed via PLGconn */
RECFM_DBF = 6}; /* DBase formatted file */
#if 0
enum MISC {DB_TABNO = 1, /* DB routines in Utility Table */
MAX_MULT_KEY = 10, /* Max multiple key number */
NAM_LEN = 128, /* Length of col and tab names */
ARRAY_SIZE = 50, /* Default array block size */
MAXRES = 500, /* Default maximum result lines */
MAXLIN = 10000, /* Default maximum data lines */
// MAXRES = 500, /* Default maximum result lines */
// MAXLIN = 10000, /* Default maximum data lines */
MAXBMP = 32}; /* Default XDB2 max bitmap size */
#if 0
enum ALGMOD {AMOD_AUTO = 0, /* PLG chooses best algorithm */
AMOD_SQL = 1, /* Use SQL algorithm */
AMOD_QRY = 2}; /* Use QUERY algorithm */
#else // !0
#define NAM_LEN 128
#endif // !0
#endif // 0
enum MODE {MODE_ERROR = -1, /* Invalid mode */
MODE_ANY = 0, /* Unspecified mode */
......@@ -342,9 +337,7 @@ typedef class XTAB *PTABLE;
typedef class COLUMN *PCOLUMN;
typedef class XOBJECT *PXOB;
typedef class COLBLK *PCOL;
typedef class TBX *PTBX;
typedef class TDB *PTDB;
typedef void *PSQL; // Not used
typedef class TDBASE *PTDBASE;
typedef class TDBDOS *PTDBDOS;
typedef class TDBFIX *PTDBFIX;
......@@ -413,41 +406,25 @@ typedef struct _mblock { /* Memory block */
/* The QUERY application User Block. */
/***********************************************************************/
typedef struct { /* User application block */
//void *Act2; /* RePoint to activity block */
//short LineLen; /* Current output line len */
NAME Name; /* User application name */
//NAME Password; /* User application password */
//PSZ UserFile; /* User application filename */
char Server[17]; /* Server name */
char DBName[17]; /* Current database name */
//char Host[65]; /* Caller's host name */
//char User[17]; /* Caller's user name */
//uint Granted; /* Grant bitmap */
PCATLG Catalog; /* To CATALOG class */
PQRYRES Result; /* To query result blocks */
PFBLOCK Openlist; /* To file/map open list */
PMBLOCK Memlist; /* To memory block list */
PXUSED Xlist; /* To used index list */
//int Maxres; /* Result Max nb of lines */
//int Maxtmp; /* Intermediate tables Maxres */
//int Maxlin; /* Query Max nb of data lines */
//int Maxbmp; /* Maximum XDB2 bitmap size */
int Check; /* General level of checking */
int Numlines; /* Number of lines involved */
//ALGMOD AlgChoice; /* Choice of algorithm mode */
//AREADEF DescArea; /* Table desc. area size */
USETEMP UseTemp; /* Use temporary file */
//int Curtype; /* 0: static else: dynamic */
int Vtdbno; /* Used for TDB number setting */
bool Remote; /* true: if remotely called */
//bool NotFinal; /* true: for intermediate table */
bool Proginfo; /* true: return progress info */
bool Subcor; /* Used for Progress info */
size_t ProgMax; /* Used for Progress info */
size_t ProgCur; /* Used for Progress info */
size_t ProgSav; /* Used for Progress info */
LPCSTR Step; /* Execution step name */
//char Work[_MAX_PATH]; /* Local work path */
} DBUSERBLK, *PDBUSER;
/***********************************************************************/
......@@ -535,6 +512,7 @@ typedef struct _colres {
int Prec; /* Precision */
int Flag; /* Flag option value */
XFLD Fld; /* Type of field info */
char Var; /* Type added information */
} COLRES;
#if defined(WIN32) && !defined(NOEX)
......@@ -578,9 +556,6 @@ DllExport void PlgDBfree(MBLOCK&);
DllExport void *PlgDBSubAlloc(PGLOBAL g, void *memp, size_t size);
DllExport void *PlgDBalloc(PGLOBAL, void *, MBLOCK&);
DllExport void *PlgDBrealloc(PGLOBAL, void *, MBLOCK&, size_t);
//lExport PSZ GetIniString(PGLOBAL, void *, LPCSTR, LPCSTR, LPCSTR, LPCSTR);
//lExport int GetIniSize(char *, char *, char *, char *);
//lExport bool WritePrivateProfileInt(LPCSTR, LPCSTR, int, LPCSTR);
DllExport void NewPointer(PTABS, void *, void *);
DllExport char *GetIni(int n= 0);
DllExport void SetTrc(void);
......
......@@ -80,9 +80,6 @@ extern pthread_mutex_t parmut;
#endif // !WIN32
#endif // THREAD
#define PLGINI "plugdb.ini" /* Configuration settings file */
#define PLGXINI "plgcnx.ini" /* Configuration settings file */
/***********************************************************************/
/* DB static variables. */
/***********************************************************************/
......@@ -90,27 +87,13 @@ bool Initdone = false;
bool plugin = false; // True when called by the XDB plugin handler
extern "C" {
extern char connectini[];
char plgxini[_MAX_PATH] = PLGXINI;
char plgini[_MAX_PATH] = PLGINI;
#if defined(WIN32)
char nmfile[_MAX_PATH] = ".\\Log\\plugdb.out";
char pdebug[_MAX_PATH] = ".\\Log\\plgthread.out";
HINSTANCE s_hModule; // Saved module handle
#else // !WIN32
char nmfile[_MAX_PATH] = "./Log/plugdb.out";
char pdebug[_MAX_PATH] = "./Log/plgthread.out";
#endif // !WIN32
#if defined(XMSG)
char msglang[16] = "ENGLISH"; // Default language
#endif
extern int trace;
extern char version[];
} // extern "C"
extern "C" int trace;
extern "C" char version[];
// The debug trace used by the main thread
FILE *pfile = NULL;
......@@ -219,27 +202,6 @@ int global_open(GLOBAL *g, int msgid, const char *path, int flags, int mode)
return h;
}
/**************************************************************************/
/* Utility for external callers (such as XDB) */
/**************************************************************************/
DllExport char *GetIni(int n)
{
switch (n) {
case 1: return plgxini; break;
case 2: return nmfile; break;
case 3: return pdebug; break;
case 4: return version; break;
#if defined(XMSG)
case 5: return msglang; break;
#endif // XMSG
case 6: return connectini; break;
// default: return plgini;
} // endswitch GetIni
return plgini;
} // end of GetIni
DllExport void SetTrc(void)
{
// If tracing is on, debug must be initialized.
......@@ -427,138 +389,9 @@ char *PlgGetDataPath(PGLOBAL g)
{
PCATLG cat = PlgGetCatalog(g, false);
//if (!cat)
// return GetIniString(g, NULL, "DataBase", "DataPath", "", plgini);
return (cat) ? cat->GetDataPath() : NULL;
} // end of PlgGetDataPath
#if 0
/***********************************************************************/
/* PlgGetXdbPath: sets the fully qualified file name of a database */
/* description file in lgn and the new datapath in dp. */
/* New database description file is a Configuration Settings file */
/* that will be used and updated in case of DB modifications such */
/* as Insert into a VCT file. Look for it and use it if found. */
/* By default the configuration file is DataPath\name.xdb but the */
/* configuration file name may also be specified in Plugdb.ini. */
/***********************************************************************/
bool PlgSetXdbPath(PGLOBAL g, PSZ dbname, PSZ dbpath,
char *lgn, int lgsize,
char *path, int psize)
{
char *dp, datapath[_MAX_PATH], ft[_MAX_EXT] = ".xdb";
int n;
if (path) {
dp = path;
n = psize;
} else {
dp = datapath;
n = sizeof(datapath);
} // endif path
GetPrivateProfileString("DataBase", "DataPath", "", dp, n, plgini);
if (trace)
htrc("PlgSetXdbPath: path=%s\n", dp);
if (dbpath) {
char fn[_MAX_FNAME];
strcpy(lgn, dbpath);
_splitpath(lgn, NULL, NULL, fn, NULL);
if (!*fn) // Old style use command
strcat(lgn, dbname);
_splitpath(lgn, NULL, NULL, dbname, NULL); // Extract DB name
} else if (strcspn(dbname, ":/\\.") < strlen(dbname)) {
// dbname name contains the path name of the XDB file
strcpy(lgn, dbname);
_splitpath(lgn, NULL, NULL, dbname, NULL); // Extract DB name
} else
/*******************************************************************/
/* New database description file is a Configuration Settings file */
/* that will be used and updated in case of DB modifications such */
/* as Insert into a VCT file. Look for it and use it if found. */
/* By default the configuration file is DataPath\name.xdb but the */
/* configuration file name may also be specified in Plugdb.ini. */
/*******************************************************************/
GetPrivateProfileString("DBnames", dbname, "", lgn, lgsize, plgini);
if (*lgn) {
#if !defined(UNIX)
char drive[_MAX_DRIVE];
char direc[_MAX_DIR];
#endif
char fname[_MAX_FNAME];
char ftype[_MAX_EXT];
_splitpath(lgn, NULL, NULL, fname, ftype);
if (!*ftype)
strcat(lgn, ft);
else if (!stricmp(ftype, ".var")) {
strcpy(g->Message, MSG(NO_MORE_VAR));
return true;
} // endif ftype
// Given DB description path may be relative to data path
PlugSetPath(lgn, lgn, dp);
// New data path is the path of the configuration setting file
#if !defined(UNIX)
_splitpath(lgn, drive, direc, NULL, NULL);
_makepath(dp, drive, direc, "", "");
#else
//#error This must be tested for trailing slash
_splitpath(lgn, NULL, dp, NULL, NULL);
#endif
} else {
// Try dbname[.ext] in the current directory
strcpy(lgn, dbname);
if (!strchr(dbname, '.'))
strcat(lgn, ft);
PlugSetPath(lgn, lgn, dp);
} // endif lgn
if (trace)
htrc("PlgSetXdbPath: new DB description file=%s\n", lgn);
return false;
} // end of PlgSetXdbPath
#endif // 0
/***********************************************************************/
/* Extract from a path name the required component. */
/* This function assumes there is enough space in the buffer. */
/***********************************************************************/
#if 0
char *ExtractFromPath(PGLOBAL g, char *pBuff, char *FileName, OPVAL op)
{
char *drive = NULL, *direc = NULL, *fname = NULL, *ftype = NULL;
switch (op) { // Determine which part to extract
#if !defined(UNIX)
case OP_FDISK: drive = pBuff; break;
#endif // !UNIX
case OP_FPATH: direc = pBuff; break;
case OP_FNAME: fname = pBuff; break;
case OP_FTYPE: ftype = pBuff; break;
default:
sprintf(g->Message, MSG(INVALID_OPER), op, "ExtractFromPath");
return NULL;
} // endswitch op
// Now do the extraction
_splitpath(FileName, drive, direc, fname, ftype);
return pBuff;
} // end of PlgExtractFromPath
#endif
/***********************************************************************/
/* Check the occurence and matching of a pattern against a string. */
/* Because this function is only used for catalog name checking, */
......@@ -853,7 +686,7 @@ int ExtractDate(char *dts, PDTP pdp, int defy, int val[6])
else // assume standard MySQL date format
fmt = "%4d-%2d-%2d %2d:%2d:%2d";
if (trace)
if (trace > 1)
htrc("ExtractDate: dts=%s fmt=%s defy=%d\n", dts, fmt, defy);
// Set default values for time only use
......@@ -935,7 +768,7 @@ int ExtractDate(char *dts, PDTP pdp, int defy, int val[6])
} // endfor i
if (trace)
if (trace > 1)
htrc("numval=%d val=(%d,%d,%d,%d,%d,%d)\n",
numval, val[0], val[1], val[2], val[3], val[4], val[5]);
......@@ -1468,19 +1301,17 @@ void *PlgDBSubAlloc(PGLOBAL g, void *memp, size_t size)
size = ((size + 7) / 8) * 8; /* Round up size to multiple of 8 */
pph = (PPOOLHEADER)memp;
#if defined(DEBTRACE)
if (trace > 1)
htrc("PlgDBSubAlloc: memp=%p size=%d used=%d free=%d\n",
memp, size, pph->To_Free, pph->FreeBlk);
#endif
if ((uint)size > pph->FreeBlk) { /* Not enough memory left in pool */
sprintf(g->Message,
"Not enough memory in Work area for request of %d (used=%d free=%d)",
(int) size, pph->To_Free, pph->FreeBlk);
#if defined(DEBTRACE)
if (trace)
htrc("%s\n", g->Message);
#endif
return NULL;
} // endif size
......@@ -1491,10 +1322,11 @@ void *PlgDBSubAlloc(PGLOBAL g, void *memp, size_t size)
memp = MakePtr(memp, pph->To_Free); // Points to suballocated block
pph->To_Free += size; // New offset of pool free block
pph->FreeBlk -= size; // New size of pool free block
#if defined(DEBTRACE)
if (trace > 1)
htrc("Done memp=%p used=%d free=%d\n",
memp, pph->To_Free, pph->FreeBlk);
#endif
return (memp);
} // end of PlgDBSubAlloc
......
......@@ -37,8 +37,6 @@
/* IBM Linker */
/* */
/***********************************************************************/
//efine DEBTRACE 3
//efine DEBTRACE2
/***********************************************************************/
/* */
......@@ -83,7 +81,6 @@
extern HINSTANCE s_hModule; /* Saved module handle */
#endif // WIN32
extern char plgini[];
extern int trace;
#if defined(XMSG)
......
......@@ -3,31 +3,6 @@
#include "checklvl.h"
/***********************************************************************/
/* Struct of variables used by the SQL pre-parsers. */
/***********************************************************************/
typedef struct _prepar {
struct _prepar *Next;
char *Debinp; // Start of input buffer
char *Endinp; // End of input buffer
char *Pluginp; // Points on current parsing position
char *Plugbuf; // Start of output buffer
char *Plugptr; // Current output position
char *Debchar; // Next/current start of command
char *Debselp; // Beginning of selection
char *Debline; // Start of current line
char *Plugpar[32]; // Parameters
int Numparms; // Number of defined parameters
int Nprms; // Number of ODBC parameters
int Lines; // Line number
int Chars; // Index of selection start in line
int Endchars; // Index of selection end in line
int Frinp, Frbuf; // 0: no, 1: free, 2: delete Debinp/Plugbuf
int Outsize; // Size of output buffer
FILE *Argfile; // File containing arguments
int Addargs; // 1 if arguments are added to the list
} PREPAR, *PPREP;
/***********************************************************************/
/* Struct of variables used by the date format pre-parser. */
/***********************************************************************/
......@@ -49,8 +24,6 @@ typedef struct _datpar {
extern "C" {
#endif
int sqlflex(PPREP pp);
int sqpflex(PPREP pp);
int fmdflex(PDTP pp);
#ifdef __cplusplus
......
......@@ -47,10 +47,6 @@
#include "valblk.h"
#include "tabmul.h"
/***********************************************************************/
/* External static variables. */
/***********************************************************************/
//extern "C" char plgini[];
/* --------------------------- Class RELDEF -------------------------- */
......@@ -204,6 +200,7 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g)
return xdefp;
} // end of GetXdef
#if 0
/***********************************************************************/
/* DeleteTableFile: Delete an OEM table file if applicable. */
/***********************************************************************/
......@@ -214,6 +211,7 @@ bool OEMDEF::DeleteTableFile(PGLOBAL g)
return (Pxdef) ? Pxdef->DeleteTableFile(g) : true;
} // end of DeleteTableFile
#endif // 0
/***********************************************************************/
/* Define: initialize the table definition block from XDB file. */
......@@ -286,7 +284,6 @@ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode)
txfp = new(g) ZIPFAM(defp);
else {
strcpy(g->Message, "Compress 2 not supported yet");
// txfp = new(g) ZLBFAM(defp);
return NULL;
} // endelse
#else // !ZIP_SUPPORT
......@@ -341,7 +338,6 @@ COLCRT::COLCRT(PSZ name)
Precision = -1;
Key = -1;
Scale = -1;
Opt = -1;
DataType = '*';
} // end of COLCRT constructor for table creation
......@@ -357,7 +353,6 @@ COLCRT::COLCRT(void)
Precision = 0;
Key = 0;
Scale = 0;
Opt = 0;
DataType = '*';
} // end of COLCRT constructor for table & view definition
......@@ -399,9 +394,7 @@ int COLDEF::Define(PGLOBAL g, void *memp, PCOLINFO cfp, int poff)
Precision = cfp->Precision;
Scale = cfp->Scale;
Long = cfp->Length;
Opt = cfp->Opt;
Key = cfp->Key;
// Freq = cfp->Freq;
if (cfp->Remark && *cfp->Remark) {
Desc = (PSZ)PlugSubAlloc(g, memp, strlen(cfp->Remark) + 1);
......
......@@ -38,7 +38,6 @@ class DllExport RELDEF : public BLOCK { // Relation definition block
void SetCat(PCATLG cat) { Cat=cat; }
// Methods
virtual bool DeleteTableFile(PGLOBAL g) {return true;}
virtual bool Indexable(void) {return false;}
virtual bool Define(PGLOBAL g, PCATLG cat, LPCSTR name, LPCSTR am) = 0;
virtual PTDB GetTable(PGLOBAL g, MODE mode) = 0;
......@@ -116,7 +115,6 @@ class DllExport OEMDEF : public TABDEF { /* OEM table */
virtual AMT GetDefType(void) {return TYPE_AM_OEM;}
// Methods
virtual bool DeleteTableFile(PGLOBAL g);
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE mode);
......@@ -147,7 +145,6 @@ class DllExport COLCRT : public BLOCK { /* Column description block
PSZ GetName(void) {return Name;}
PSZ GetDecode(void) {return Decode;}
PSZ GetFmt(void) {return Fmt;}
int GetOpt(void) {return Opt;}
int GetLong(void) {return Long;}
int GetPrecision(void) {return Precision;}
int GetOffset(void) {return Offset;}
......@@ -164,7 +161,6 @@ class DllExport COLCRT : public BLOCK { /* Column description block
int Key; /* Key (greater than 1 if multiple) */
int Precision; /* Logical column length */
int Scale; /* Decimals for float/decimal values */
int Opt; /* 0:Not 1:clustered 2:sorted-asc 3:desc */
char DataType; /* Internal data type (C, N, F, T) */
}; // end of COLCRT
......
......@@ -22,6 +22,8 @@
#include "xtable.h"
#include "tabcol.h"
extern "C" int trace;
/***********************************************************************/
/* XTAB public constructor. */
/***********************************************************************/
......@@ -33,9 +35,9 @@ XTAB::XTAB(LPCSTR name, LPCSTR srcdef) : Name(name)
Schema = NULL;
Qualifier = NULL;
#ifdef DEBTRACE
htrc(" making new TABLE %s %s\n", Name, Srcdef);
#endif
if (trace)
htrc("XTAB: making new TABLE %s %s\n", Name, Srcdef);
} // end of XTAB constructor
/***********************************************************************/
......@@ -49,9 +51,9 @@ XTAB::XTAB(PTABLE tp) : Name(tp->Name)
Schema = tp->Schema;
Qualifier = tp->Qualifier;
#ifdef DEBTRACE
if (trace)
htrc(" making copy TABLE %s %s\n", Name, Srcdef);
#endif
} // end of XTAB constructor
/***********************************************************************/
......@@ -61,9 +63,8 @@ PTABLE XTAB::Link(PTABLE tab2)
{
PTABLE tabp;
#ifdef DEBTRACE
if (trace)
htrc("Linking tables %s... to %s\n", Name, tab2->Name);
#endif
for (tabp = this; tabp->Next; tabp = tabp->Next) ;
......@@ -118,9 +119,9 @@ COLUMN::COLUMN(LPCSTR name) : Name(name)
To_Col = NULL;
Qualifier = NULL;
#ifdef DEBTRACE
if (trace)
htrc(" making new COLUMN %s\n", Name);
#endif
} // end of COLUMN constructor
/***********************************************************************/
......
......@@ -85,8 +85,6 @@ class DllExport COLUMN: public XOBJECT { // Column Name/Qualifier block.
virtual bool Compare(PXOB) {assert(false); return false;}
virtual bool SetFormat(PGLOBAL, FORMAT&);
virtual bool Eval(PGLOBAL) {assert(false); return true;}
virtual int CheckSpcCol(PTDB, int) {assert(false); return 2;}
virtual bool CheckSort(PTDB) {assert(false); return false;}
private:
// Members
......
This diff is collapsed.
This diff is collapsed.
/************* TabFix C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABFIX */
/* ------------- */
/* Version 4.8 */
/* Version 4.9 */
/* */
/* COPYRIGHT: */
/* ---------- */
/* (C) Copyright to the author Olivier BERTRAND 1998-2012 */
/* (C) Copyright to the author Olivier BERTRAND 1998-2014 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
......
......@@ -460,7 +460,6 @@ PTDB CSVDEF::GetTable(PGLOBAL g, MODE mode)
txfp = new(g) ZIPFAM(this);
else {
strcpy(g->Message, "Compress 2 not supported yet");
// txfp = new(g) ZLBFAM(defp);
return NULL;
} // endelse
#else // !ZIP_SUPPORT
......@@ -1272,25 +1271,6 @@ CSVCOL::CSVCOL(CSVCOL *col1, PTDB tdbp) : DOSCOL(col1, tdbp)
Fldnum = col1->Fldnum;
} // end of CSVCOL copy constructor
/***********************************************************************/
/* VarSize: This function tells UpdateDB whether or not the block */
/* optimization file must be redone if this column is updated, even */
/* it is not sorted or clustered. This applies to a blocked table, */
/* because if it is updated using a temporary file, the block size */
/* may be modified. */
/***********************************************************************/
bool CSVCOL::VarSize(void)
{
PTXF txfp = ((PTDBCSV)To_Tdb)->Txfp;
if (txfp->IsBlocked() && txfp->GetUseTemp())
// Blocked table using a temporary file
return true;
else
return false;
} // end VarSize
/***********************************************************************/
/* ReadColumn: call DOSCOL::ReadColumn after having set the offet */
/* and length of the field to read as calculated by TDBCSV::ReadDB. */
......@@ -1353,7 +1333,7 @@ void CSVCOL::ReadColumn(PGLOBAL g)
/***********************************************************************/
void CSVCOL::WriteColumn(PGLOBAL g)
{
char *p, buf[32];
char *p, buf[64];
int flen;
PTDBCSV tdbp = (PTDBCSV)To_Tdb;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment