Commit 046ae9f5 authored by Sergei Golubchik's avatar Sergei Golubchik

10.0-connect merge

parents 7216afbc 6075c824
......@@ -123,7 +123,7 @@ IF(WIN32)
# /MP option of the Microsoft compiler does not work well with COM #import
string(REPLACE "/MP" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
string(REPLACE "/MP" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
OPTION(CONNECT_WITH_MSXML "Compile CONNECT storage engine with MSXML support" ON)
IF(CONNECT_WITH_MSXML)
find_library(MSXML_LIBRARY
......@@ -264,6 +264,17 @@ int main() {
ENDIF(UNIX)
ENDIF(CONNECT_WITH_ODBC)
#
# XMAP
#
OPTION(CONNECT_WITH_XMAP "Compile CONNECT storage engine with index file mapping support" ON)
IF(CONNECT_WITH_XMAP)
add_definitions(-DXMAP)
ENDIF(CONNECT_WITH_XMAP)
#
# Plugin definition
#
......
......@@ -71,16 +71,6 @@ class DllExport CATALOG {
// Methods
virtual void Reset(void) {}
virtual void SetDataPath(PGLOBAL g, const char *path) {}
virtual bool GetBoolCatInfo(PSZ what, bool bdef) {return bdef;}
virtual bool SetIntCatInfo(PSZ what, int ival) {return false;}
virtual int GetIntCatInfo(PSZ what, int idef) {return idef;}
virtual int GetSizeCatInfo(PSZ what, PSZ sdef) {return 0;}
virtual int GetCharCatInfo(PSZ what, PSZ sdef, char *buf, int size)
{strncpy(buf, sdef, size); return size;}
virtual char *GetStringCatInfo(PGLOBAL g, PSZ what, PSZ sdef)
{return sdef;}
virtual int GetColCatInfo(PGLOBAL g, PTABDEF defp) {return -1;}
virtual bool GetIndexInfo(PGLOBAL g, PTABDEF defp) {return true;}
virtual bool CheckName(PGLOBAL g, char *name) {return true;}
virtual bool ClearName(PGLOBAL g, PSZ name) {return true;}
virtual PRELDEF MakeOneTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am) {return NULL;}
......
......@@ -587,7 +587,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
tbxp= (TDBDOX*)tdbp;
tbxp->SetKindex(NULL);
tbxp->To_Key_Col= NULL;
rc= tbxp->ResetTableOpt(g, ((PTDBASE)tdbp)->GetDef()->Indexable());
rc= tbxp->ResetTableOpt(g, ((PTDBASE)tdbp)->GetDef()->Indexable() == 1);
err:
if (trace > 1)
......@@ -709,7 +709,7 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
const void *key, int len)
{
char *kp= (char*)key;
int n;
int n, x;
short lg;
bool rcb;
RCODE rc;
......@@ -720,9 +720,18 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
if (!ptdb)
return RC_FX;
if (!((PTDBASE)ptdb)->GetDef()->Indexable()) {
else
x= ((PTDBASE)ptdb)->GetDef()->Indexable();
if (!x) {
sprintf(g->Message, "CntIndexRead: Table %s is not indexable", ptdb->GetName());
return RC_FX;
} else if (x == 2) {
// Remote index
if (ptdb->ReadKey(g, op, key, len))
return RC_FX;
goto rnd;
} else
tdbp= (PTDBDOX)ptdb;
......@@ -782,8 +791,9 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
xbp->SetOp(op);
xbp->SetNth(0);
if ((rc= (RCODE)tdbp->ReadDB(g)) == RC_OK)
rc= EvalColumns(g, tdbp);
rnd:
if ((rc= (RCODE)ptdb->ReadDB(g)) == RC_OK)
rc= EvalColumns(g, ptdb);
return rc;
} // end of CntIndexRead
......@@ -795,7 +805,7 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
bool *incl, key_part_map *kmap)
{
const uchar *p, *kp;
int i, n, k[2];
int i, n, x, k[2];
short lg;
bool b, rcb;
PVAL valp;
......@@ -805,10 +815,16 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
if (!ptdb)
return -1;
else if (!((PTDBASE)ptdb)->GetDef()->Indexable()) {
x= ((PTDBASE)ptdb)->GetDef()->Indexable();
if (!x) {
sprintf(g->Message, "CntIndexRange: Table %s is not indexable", ptdb->GetName());
DBUG_PRINT("Range", ("%s", g->Message));
return -1;
} else if (x == 2) {
// Remote index
return 2;
} else
tdbp= (PTDBDOX)ptdb;
......
......@@ -295,7 +295,7 @@ int CSORT::Qsortx(void)
/*****************************************************************/
/* Call conservative insertion sort not using/setting offset. */
/*****************************************************************/
Istc(Pex, Pex + min(Nitem, Thresh), top);
Istc(Pex, Pex + MY_MIN(Nitem, Thresh), top);
} // endif Thresh
......@@ -669,7 +669,7 @@ int CSORT::Qsortc(void)
/*****************************************************************/
/* Call conservative insertion sort not using/setting offset. */
/*****************************************************************/
Istc(Pex, Pex + min(Nitem, Thresh), max);
Istc(Pex, Pex + MY_MIN(Nitem, Thresh), max);
} // endif Thresh
......
......@@ -476,7 +476,7 @@ bool FIXFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
return true;
} // endif
req = (size_t)min(n, Dbflen);
req = (size_t)MY_MIN(n, Dbflen);
len = fread(DelBuf, Lrecl, req, Stream);
if (trace > 1)
......@@ -1322,7 +1322,7 @@ bool BGXFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
if (BigSeek(g, Hfile, (BIGINT)Spos * (BIGINT)Lrecl))
return true;
req = min(n, Dbflen) * Lrecl;
req = MY_MIN(n, Dbflen) * Lrecl;
if ((nbr = BigRead(g, Hfile, DelBuf, req)) != req) {
sprintf(g->Message, MSG(DEL_READ_ERROR), req, nbr);
......
......@@ -836,7 +836,7 @@ bool DOSFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
return true;
} // endif
req = (size_t)min(n, Dbflen);
req = (size_t)MY_MIN(n, Dbflen);
len = fread(DelBuf, 1, req, Stream);
if (trace)
......
......@@ -477,7 +477,7 @@ bool VCTFAM::AllocateBuffer(PGLOBAL g)
Clens[i] = cdp->GetClen();
Deplac[i] = Headlen + cdp->GetPoff() * n * Nrec;
Isnum[i] = IsTypeNum(cdp->GetType());
Buflen = max(Buflen, cdp->GetClen());
Buflen = MY_MAX(Buflen, cdp->GetClen());
} // endfor cdp
if (!UseTemp || MaxBlk) {
......@@ -852,9 +852,9 @@ bool VCTFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
/* Non consecutive line to delete. Move intermediate lines. */
/*******************************************************************/
if (!MaxBlk)
req = (size_t)min(n, Nrec - max(Spos % Nrec, Tpos % Nrec));
req = (size_t)MY_MIN(n, Nrec - MY_MAX(Spos % Nrec, Tpos % Nrec));
else
req = (size_t)min(n, Nrec);
req = (size_t)MY_MIN(n, Nrec);
if (req) for (i = 0; i < Ncol; i++) {
if (MaxBlk) {
......@@ -985,7 +985,7 @@ bool VCTFAM::CleanUnusedSpace(PGLOBAL g)
/* Note: this seems to work even column blocks have been made */
/* with Blanks = true. Perhaps should it be set to false for VEC. */
/*******************************************************************/
req = (size_t)min(n, Nrec);
req = (size_t)MY_MIN(n, Nrec);
memset(To_Buf, 0, Buflen);
for (i = 0; i < Ncol; i++) {
......@@ -1093,13 +1093,12 @@ bool VCTFAM::ResetTableSize(PGLOBAL g, int block, int last)
// Update catalog values for Block and Last
PVCTDEF defp = (PVCTDEF)Tdbp->GetDef();
LPCSTR name = Tdbp->GetName();
PCATLG cat = PlgGetCatalog(g);
defp->SetBlock(Block);
defp->SetLast(Last);
if (!cat->SetIntCatInfo("Blocks", Block) ||
!cat->SetIntCatInfo("Last", Last)) {
if (!defp->SetIntCatInfo("Blocks", Block) ||
!defp->SetIntCatInfo("Last", Last)) {
sprintf(g->Message, MSG(UPDATE_ERROR), "Header");
rc = true;
} // endif
......@@ -1575,7 +1574,7 @@ int VCMFAM::DeleteRecords(PGLOBAL g, int irc)
for (n = Fpos - Spos; n > 0; n -= req) {
soff = Spos % Nrec;
toff = Tpos % Nrec;
req = (size_t)min(n, Nrec - max(soff, toff));
req = (size_t)MY_MIN(n, Nrec - MY_MAX(soff, toff));
for (i = 0; i < Ncol; i++) {
ps = Memcol[i] + (Spos / Nrec) * Blksize + soff * Clens[i];
......@@ -2006,7 +2005,7 @@ bool VECFAM::AllocateBuffer(PGLOBAL g)
for (i = 0; cdp && i < Ncol; i++, cdp = cdp->GetNext()) {
Clens[i] = cdp->GetClen();
Buflen = max(Buflen, cdp->GetClen());
Buflen = MY_MAX(Buflen, cdp->GetClen());
} // endfor cdp
} else { // Mode Update, only some columns are updated
......@@ -2017,7 +2016,7 @@ bool VECFAM::AllocateBuffer(PGLOBAL g)
T_Streams[i] = NULL; // Mark the streams to open
Clens[i] = cp->Clen;
Buflen = max(Buflen, cp->Clen);
Buflen = MY_MAX(Buflen, cp->Clen);
} // endfor cp
InitUpdate = true; // To be initialized
......@@ -2298,7 +2297,7 @@ bool VECFAM::MoveIntermediateLines(PGLOBAL g, bool *bn)
/*******************************************************************/
/* Non consecutive line to delete. Move intermediate lines. */
/*******************************************************************/
req = (size_t)min(n, Nrec);
req = (size_t)MY_MIN(n, Nrec);
for (i = 0; i < Ncol; i++) {
if (!T_Streams[i])
......@@ -3604,7 +3603,7 @@ bool BGVFAM::AllocateBuffer(PGLOBAL g)
Clens[i] = cdp->GetClen();
Isnum[i] = IsTypeNum(cdp->GetType());
Buflen = max(Buflen, cdp->GetClen());
Buflen = MY_MAX(Buflen, cdp->GetClen());
} // endfor cdp
if (!UseTemp || MaxBlk) {
......@@ -3908,9 +3907,9 @@ bool BGVFAM::MoveIntermediateLines(PGLOBAL g, bool *b)
/* Non consecutive line to delete. Move intermediate lines. */
/*******************************************************************/
if (!MaxBlk)
req = (DWORD)min(n, Nrec - max(Spos % Nrec, Tpos % Nrec));
req = (DWORD)MY_MIN(n, Nrec - MY_MAX(Spos % Nrec, Tpos % Nrec));
else
req = (DWORD)min(n, Nrec);
req = (DWORD)MY_MIN(n, Nrec);
if (req) for (i = 0; i < Ncol; i++) {
if (!MaxBlk) {
......@@ -4017,7 +4016,7 @@ bool BGVFAM::CleanUnusedSpace(PGLOBAL g)
/* This seems to work even column blocks have been made with */
/* Blanks = true. Perhaps should it be set to false for VEC. */
/*****************************************************************/
req = min(n, Nrec);
req = MY_MIN(n, Nrec);
for (i = 0; i < Ncol; i++) {
pos = BigDep[i] + (BIGINT)Tpos * (BIGINT)Clens[i];
......
......@@ -543,13 +543,12 @@ int ZBKFAM::DeleteRecords(PGLOBAL g, int irc)
if (irc == RC_EF) {
LPCSTR name = Tdbp->GetName();
PDOSDEF defp = (PDOSDEF)Tdbp->GetDef();
PCATLG cat = PlgGetCatalog(g);
defp->SetBlock(0);
defp->SetLast(Nrec);
if (!cat->SetIntCatInfo("Blocks", 0) ||
!cat->SetIntCatInfo("Last", 0)) {
if (!defp->SetIntCatInfo("Blocks", 0) ||
!defp->SetIntCatInfo("Last", 0)) {
sprintf(g->Message, MSG(UPDATE_ERROR), "Header");
return RC_FX;
} else
......@@ -568,7 +567,6 @@ void ZBKFAM::CloseTableFile(PGLOBAL g)
int rc = RC_OK;
if (Tdbp->GetMode() == MODE_INSERT) {
PCATLG cat = PlgGetCatalog(g);
LPCSTR name = Tdbp->GetName();
PDOSDEF defp = (PDOSDEF)Tdbp->GetDef();
......@@ -587,8 +585,8 @@ void ZBKFAM::CloseTableFile(PGLOBAL g)
if (rc != RC_FX) {
defp->SetBlock(Block);
defp->SetLast(Last);
cat->SetIntCatInfo("Blocks", Block);
cat->SetIntCatInfo("Last", Last);
defp->SetIntCatInfo("Blocks", Block);
defp->SetIntCatInfo("Last", Last);
} // endif
gzclose(Zfile);
......
......@@ -84,6 +84,7 @@
#define TYPE_LIST 6
#define TYPE_INT 7
#define TYPE_DECIM 9
#define TYPE_BIN 10
#if defined(OS32)
#define SYS_STAMP "OS32"
......
This diff is collapsed.
......@@ -165,7 +165,7 @@ class ha_connect: public handler
// CONNECT Implementation
static bool connect_init(void);
static bool connect_end(void);
TABTYPE GetRealType(PTOS pos);
TABTYPE GetRealType(PTOS pos= NULL);
char *GetStringOption(char *opname, char *sdef= NULL);
PTOS GetTableOptionStruct(TABLE *table_arg);
bool GetBooleanOption(char *opname, bool bdef);
......@@ -198,6 +198,8 @@ class ha_connect: public handler
int CheckRecord(PGLOBAL g, const uchar *oldbuf, uchar *newbuf);
int ReadIndexed(uchar *buf, OPVAL op, const uchar* key= NULL,
uint key_len= 0);
bool MakeKeyWhere(PGLOBAL g, char *qry, OPVAL op, char *q,
const void *key, int klen);
/** @brief
The name that will be used for display purposes.
......@@ -241,7 +243,8 @@ class ha_connect: public handler
*/
ulong index_flags(uint inx, uint part, bool all_parts) const
{
return HA_READ_NEXT | HA_READ_RANGE | HA_READ_ORDER | HA_KEYREAD_ONLY;
return HA_READ_NEXT | HA_READ_RANGE | HA_READ_ORDER |
HA_READ_PREV | HA_KEYREAD_ONLY | HA_KEY_SCAN_NOT_ROR;
} // end of index_flags
/** @brief
......@@ -404,7 +407,7 @@ const char *GetValStr(OPVAL vop, bool neg);
We implement this in ha_connect.cc. It's not an obligatory method;
skip it and and MySQL will treat it as not implemented.
*/
//int index_prev(uchar *buf);
int index_prev(uchar *buf);
/** @brief
We implement this in ha_connect.cc. It's not an obligatory method;
......@@ -416,7 +419,7 @@ const char *GetValStr(OPVAL vop, bool neg);
We implement this in ha_connect.cc. It's not an obligatory method;
skip it and and MySQL will treat it as not implemented.
*/
//int index_last(uchar *buf);
int index_last(uchar *buf);
/* Index condition pushdown implementation */
//Item *idx_cond_push(uint keyno, Item* idx_cond);
......
......@@ -152,7 +152,7 @@ static void PROFILE_CopyEntry( char *buffer, const char *value, uint len,
if (!p2)
continue; /* ignore it */
strncpy(env_val, p + 2, min((int) sizeof(env_val), (int)(p2-p)-1));
strncpy(env_val, p + 2, MY_MIN((int) sizeof(env_val), (int)(p2-p)-1));
if ((env_p = getenv(env_val)) != NULL) {
int buffer_len;
......
This diff is collapsed.
......@@ -40,6 +40,7 @@ bool IsExactType(TABTYPE type);
bool IsTypeNullable(TABTYPE type);
bool IsTypeFixed(TABTYPE type);
bool IsTypeIndexable(TABTYPE type);
int GetIndexType(TABTYPE type);
uint GetFuncID(const char *func);
/***********************************************************************/
......@@ -57,14 +58,6 @@ class MYCAT : public CATALOG {
void Reset(void);
void SetDataPath(PGLOBAL g, const char *path)
{SetPath(g, &DataPath, path);}
bool GetBoolCatInfo(PSZ what, bool bdef);
bool SetIntCatInfo(PSZ what, int ival);
int GetIntCatInfo(PSZ what, int idef);
int GetSizeCatInfo(PSZ what, PSZ sdef);
int GetCharCatInfo(PSZ what, PSZ sdef, char *buf, int size);
char *GetStringCatInfo(PGLOBAL g, PSZ what, PSZ sdef);
int GetColCatInfo(PGLOBAL g, PTABDEF defp);
bool GetIndexInfo(PGLOBAL g, PTABDEF defp);
bool StoreIndex(PGLOBAL g, PTABDEF defp) {return false;} // Temporary
PRELDEF GetTableDesc(PGLOBAL g, LPCSTR name,
LPCSTR type, PRELDEF *prp = NULL);
......
......@@ -47,9 +47,12 @@
#include "myconn.h"
extern "C" int trace;
extern "C" int zconv;
extern MYSQL_PLUGIN_IMPORT uint mysqld_port;
extern MYSQL_PLUGIN_IMPORT char *mysqld_unix_port;
DllExport void PushWarning(PGLOBAL, THD*, int level = 1);
// Returns the current used port
uint GetDefaultPort(void)
{
......@@ -61,7 +64,7 @@ uint GetDefaultPort(void)
/* of a MySQL table or view. */
/* info = TRUE to get catalog column informations. */
/************************************************************************/
PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
const char *user, const char *pwd,
const char *table, const char *colpat,
int port, bool info)
......@@ -75,7 +78,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
FLD_REM, FLD_NO, FLD_DEFAULT, FLD_EXTRA,
FLD_CHARSET};
unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0};
char *fld, *fmt, v, cmd[128], uns[16], zero[16];
char *fld, *colname, *chset, *fmt, v, cmd[128], uns[16], zero[16];
int i, n, nf, ncol = sizeof(buftyp) / sizeof(int);
int len, type, prec, rc, k = 0;
PQRYRES qrp;
......@@ -144,23 +147,24 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
/**********************************************************************/
/* Now get the results into blocks. */
/**********************************************************************/
for (i = 0; i < n; i++) {
if ((rc = myc.Fetch(g, -1) == RC_FX)) {
for (i = 0; i < n; /*i++*/) {
if ((rc = myc.Fetch(g, -1)) == RC_FX) {
myc.Close();
return NULL;
} else if (rc == RC_NF)
} else if (rc == RC_EF)
break;
// Get column name
fld = myc.GetCharField(0);
colname = myc.GetCharField(0);
crp = qrp->Colresp; // Column_Name
crp->Kdata->SetValue(fld, i);
crp->Kdata->SetValue(colname, i);
// Get type, type name, precision, unsigned and zerofill
chset = myc.GetCharField(2);
fld = myc.GetCharField(1);
prec = 0;
len = 0;
v = 0;
v = (chset && !strcmp(chset, "binary")) ? 'B' : 0;
*uns = 0;
*zero = 0;
......@@ -181,11 +185,28 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
} // endswitch nf
if ((type = MYSQLtoPLG(cmd, &v)) == TYPE_ERROR) {
sprintf(g->Message, "Unsupported column type %s", cmd);
if (v == 'K') {
// Skip this column
sprintf(g->Message, "Column %s skipped (unsupported type %s)",
colname, cmd);
PushWarning(g, thd);
continue;
} // endif v
sprintf(g->Message, "Column %s unsupported type %s", colname, cmd);
myc.Close();
return NULL;
} else if (type == TYPE_STRING)
len = min(len, 4096);
} else if (type == TYPE_STRING) {
if (v == 'X') {
len = zconv;
sprintf(g->Message, "Column %s converted to varchar(%d)",
colname, len);
PushWarning(g, thd);
v = 'V';
} else
len = MY_MIN(len, 4096);
} // endif type
qrp->Nblin++;
crp = crp->Next; // Data_Type
......@@ -241,8 +262,10 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
crp->Kdata->SetValue(fld, i);
crp = crp->Next; // New (charset)
fld = myc.GetCharField(2);
fld = chset;
crp->Kdata->SetValue(fld, i);
i++; // Can be skipped
} // endfor i
#if 0
......@@ -342,7 +365,7 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
int pt)
{
const char *pipe = NULL;
uint cto = 60, nrt = 120;
uint cto = 6000, nrt = 12000;
m_DB = mysql_init(NULL);
......@@ -741,7 +764,7 @@ PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb)
crp->Prec = (crp->Type == TYPE_DOUBLE || crp->Type == TYPE_DECIM)
? fld->decimals : 0;
crp->Length = max(fld->length, fld->max_length);
crp->Length = MY_MAX(fld->length, fld->max_length);
crp->Clen = GetTypeSize(crp->Type, crp->Length);
uns = (fld->flags & (UNSIGNED_FLAG | ZEROFILL_FLAG)) ? true : false;
......
......@@ -34,7 +34,7 @@ typedef class MYSQLC *PMYC;
/***********************************************************************/
/* Prototypes of info functions. */
/***********************************************************************/
PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
const char *user, const char *pwd,
const char *table, const char *colpat,
int port, bool info);
......
......@@ -229,7 +229,7 @@ DROP TABLE pets;
#
CREATE TABLE fruit (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(32) DEFAULT NULL,
`name` varchar(32) NOT NULL,
`cnt` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
......
......@@ -326,6 +326,9 @@ Warnings:
Level Warning
Code 1366
Message Incorrect string value: '\xC3\x81\xC3\x82\xC3\x83...' for column 'c' at row 1
Level Warning
Code 1105
Message Out of range value ÁÂÃÄÅÆÇ for column 'c' at row 1
DROP TABLE t1;
#
# Testing Cyrillic
......
-- source include/not_embedded.inc
let $MYSQLD_DATADIR= `select @@datadir`;
let $PORT= `select @@port`;
--copy_file $MTR_SUITE_DIR/std_data/expenses.txt $MYSQLD_DATADIR/test/expenses.txt
--echo #
--echo # Testing the PIVOT table type
--echo #
CREATE TABLE expenses (
Who CHAR(10) NOT NULL,
Week INT(2) NOT NULL,
What CHAR(12) NOT NULL,
Amount DOUBLE(8,2))
ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='expenses.txt' ENDING=2;
SELECT * FROM expenses;
--echo #
--echo # Pivoting from What
--echo #
CREATE TABLE pivex (
Who CHAR(10) NOT NULL,
Week INT(2) NOT NULL,
Beer DOUBLE(8,2) FLAG=1,
Car DOUBLE(8,2) FLAG=1,
Food DOUBLE(8,2) FLAG=1)
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=expenses;
--replace_result $PORT PORT
--eval ALTER TABLE pivex OPTION_LIST='port=$PORT'
SELECT * FROM pivex;
--echo #
--echo # Restricting the columns in a Pivot Table
--echo #
ALTER TABLE pivex DROP COLUMN week;
SELECT * FROM pivex;
--echo #
--echo # Using a source definition
--echo #
DROP TABLE pivex;
CREATE TABLE pivex (
Who CHAR(10) NOT NULL,
Week INT(2) NOT NULL,
Beer DOUBLE(8,2) FLAG=1,
Car DOUBLE(8,2) FLAG=1,
Food DOUBLE(8,2) FLAG=1)
ENGINE=CONNECT TABLE_TYPE=PIVOT
SRCDEF='select who, week, what, sum(amount) as amount from expenses where week in (4,5) group by who, week, what';
--replace_result $PORT PORT
--eval ALTER TABLE pivex OPTION_LIST='PivotCol=what,FncCol=amount,port=$PORT'
SELECT * FROM pivex;
--echo #
--echo # Pivoting from Week
--echo #
DROP TABLE pivex;
CREATE TABLE pivex (
Who CHAR(10) NOT NULL,
What CHAR(12) NOT NULL,
`3` DOUBLE(8,2) FLAG=1,
`4` DOUBLE(8,2) FLAG=1,
`5` DOUBLE(8,2) FLAG=1)
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=expenses;
--replace_result $PORT PORT
--eval ALTER TABLE pivex OPTION_LIST='PivotCol=Week,port=$PORT'
SELECT * FROM pivex;
--echo #
--echo # Using scalar functions and expresssions
--echo #
DROP TABLE pivex;
CREATE TABLE pivex (
Who CHAR(10) NOT NULL,
What CHAR(12) NOT NULL,
First DOUBLE(8,2) FLAG=1,
Middle DOUBLE(8,2) FLAG=1,
Last DOUBLE(8,2) FLAG=1)
ENGINE=CONNECT TABLE_TYPE=PIVOT
SRCDEF='select who, what, case when week=3 then ''First'' when week=5 then ''Last'' else ''Middle'' end as wk, sum(amount) * 6.56 as amnt from expenses group by who, what, wk';
--replace_result $PORT PORT
--eval ALTER TABLE pivex OPTION_LIST='PivotCol=wk,FncCol=amnt,port=$PORT'
SELECT * FROM pivex;
DROP TABLE pivex;
DROP TABLE expenses;
--echo #
--echo # Make the PETS table
--echo #
CREATE TABLE pets (
Name VARCHAR(12) NOT NULL,
Race CHAR(6) NOT NULL,
Number INT NOT NULL) ENGINE=MYISAM;
INSERT INTO pets VALUES('John','dog',2);
INSERT INTO pets VALUES('Bill','cat',1);
INSERT INTO pets VALUES('Mary','dog',1);
INSERT INTO pets VALUES('Mary','cat',1);
INSERT INTO pets VALUES('Lisbeth','rabbit',2);
INSERT INTO pets VALUES('Kevin','cat',2);
INSERT INTO pets VALUES('Kevin','bird',6);
INSERT INTO pets VALUES('Donald','dog',1);
INSERT INTO pets VALUES('Donald','fish',3);
SELECT * FROM pets;
--echo #
--echo # Pivot the PETS table
--echo #
CREATE TABLE pivet (
name VARCHAR(12) NOT NULL,
dog INT NOT NULL DEFAULT 0 FLAG=1,
cat INT NOT NULL DEFAULT 0 FLAG=1,
rabbit INT NOT NULL DEFAULT 0 FLAG=1,
bird INT NOT NULL DEFAULT 0 FLAG=1,
fish INT NOT NULL DEFAULT 0 FLAG=1)
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
SELECT * FROM pivet;
DROP TABLE pivet;
--echo #
--echo # Testing the "data" column list
--echo #
CREATE TABLE pivet (
name VARCHAR(12) NOT NULL,
dog INT NOT NULL DEFAULT 0 FLAG=1,
cat INT NOT NULL DEFAULT 0 FLAG=1)
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
--error ER_GET_ERRMSG
SELECT * FROM pivet;
ALTER TABLE pivet OPTION_LIST='PivotCol=race,groupby=1,accept=1';
SELECT * FROM pivet;
DROP TABLE pivet;
--echo #
--echo # Adding a "dump" column
--echo #
CREATE TABLE pivet (
name VARCHAR(12) NOT NULL,
dog INT NOT NULL DEFAULT 0 FLAG=1,
cat INT NOT NULL DEFAULT 0 FLAG=1,
other INT NOT NULL DEFAULT 0 FLAG=2)
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
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
-- source include/not_embedded.inc
let $MYSQLD_DATADIR= `select @@datadir`;
let $PORT= `select @@port`;
--copy_file $MTR_SUITE_DIR/std_data/expenses.txt $MYSQLD_DATADIR/test/expenses.txt
--echo #
--echo # Testing the PIVOT table type
--echo #
CREATE TABLE expenses (
Who CHAR(10) NOT NULL,
Week INT(2) NOT NULL,
What CHAR(12) NOT NULL,
Amount DOUBLE(8,2))
ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='expenses.txt' ENDING=2;
SELECT * FROM expenses;
--echo #
--echo # Pivoting from What
--echo #
CREATE TABLE pivex (
Who CHAR(10) NOT NULL,
Week INT(2) NOT NULL,
Beer DOUBLE(8,2) FLAG=1,
Car DOUBLE(8,2) FLAG=1,
Food DOUBLE(8,2) FLAG=1)
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=expenses;
--replace_result $PORT PORT
--eval ALTER TABLE pivex OPTION_LIST='port=$PORT'
SELECT * FROM pivex;
--echo #
--echo # Restricting the columns in a Pivot Table
--echo #
ALTER TABLE pivex DROP COLUMN week;
SELECT * FROM pivex;
--echo #
--echo # Using a source definition
--echo #
DROP TABLE pivex;
CREATE TABLE pivex (
Who CHAR(10) NOT NULL,
Week INT(2) NOT NULL,
Beer DOUBLE(8,2) FLAG=1,
Car DOUBLE(8,2) FLAG=1,
Food DOUBLE(8,2) FLAG=1)
ENGINE=CONNECT TABLE_TYPE=PIVOT
SRCDEF='select who, week, what, sum(amount) as amount from expenses where week in (4,5) group by who, week, what';
--replace_result $PORT PORT
--eval ALTER TABLE pivex OPTION_LIST='PivotCol=what,FncCol=amount,port=$PORT'
SELECT * FROM pivex;
--echo #
--echo # Pivoting from Week
--echo #
DROP TABLE pivex;
CREATE TABLE pivex (
Who CHAR(10) NOT NULL,
What CHAR(12) NOT NULL,
`3` DOUBLE(8,2) FLAG=1,
`4` DOUBLE(8,2) FLAG=1,
`5` DOUBLE(8,2) FLAG=1)
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=expenses;
--replace_result $PORT PORT
--eval ALTER TABLE pivex OPTION_LIST='PivotCol=Week,port=$PORT'
SELECT * FROM pivex;
--echo #
--echo # Using scalar functions and expresssions
--echo #
DROP TABLE pivex;
CREATE TABLE pivex (
Who CHAR(10) NOT NULL,
What CHAR(12) NOT NULL,
First DOUBLE(8,2) FLAG=1,
Middle DOUBLE(8,2) FLAG=1,
Last DOUBLE(8,2) FLAG=1)
ENGINE=CONNECT TABLE_TYPE=PIVOT
SRCDEF='select who, what, case when week=3 then ''First'' when week=5 then ''Last'' else ''Middle'' end as wk, sum(amount) * 6.56 as amnt from expenses group by who, what, wk';
--replace_result $PORT PORT
--eval ALTER TABLE pivex OPTION_LIST='PivotCol=wk,FncCol=amnt,port=$PORT'
SELECT * FROM pivex;
DROP TABLE pivex;
DROP TABLE expenses;
--echo #
--echo # Make the PETS table
--echo #
CREATE TABLE pets (
Name VARCHAR(12) NOT NULL,
Race CHAR(6) NOT NULL,
Number INT NOT NULL) ENGINE=MYISAM;
INSERT INTO pets VALUES('John','dog',2);
INSERT INTO pets VALUES('Bill','cat',1);
INSERT INTO pets VALUES('Mary','dog',1);
INSERT INTO pets VALUES('Mary','cat',1);
INSERT INTO pets VALUES('Lisbeth','rabbit',2);
INSERT INTO pets VALUES('Kevin','cat',2);
INSERT INTO pets VALUES('Kevin','bird',6);
INSERT INTO pets VALUES('Donald','dog',1);
INSERT INTO pets VALUES('Donald','fish',3);
SELECT * FROM pets;
--echo #
--echo # Pivot the PETS table
--echo #
CREATE TABLE pivet (
name VARCHAR(12) NOT NULL,
dog INT NOT NULL DEFAULT 0 FLAG=1,
cat INT NOT NULL DEFAULT 0 FLAG=1,
rabbit INT NOT NULL DEFAULT 0 FLAG=1,
bird INT NOT NULL DEFAULT 0 FLAG=1,
fish INT NOT NULL DEFAULT 0 FLAG=1)
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
SELECT * FROM pivet;
DROP TABLE pivet;
--echo #
--echo # Testing the "data" column list
--echo #
CREATE TABLE pivet (
name VARCHAR(12) NOT NULL,
dog INT NOT NULL DEFAULT 0 FLAG=1,
cat INT NOT NULL DEFAULT 0 FLAG=1)
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
--error ER_GET_ERRMSG
SELECT * FROM pivet;
ALTER TABLE pivet OPTION_LIST='PivotCol=race,groupby=1,accept=1';
SELECT * FROM pivet;
DROP TABLE pivet;
--echo #
--echo # Adding a "dump" column
--echo #
CREATE TABLE pivet (
name VARCHAR(12) NOT NULL,
dog INT NOT NULL DEFAULT 0 FLAG=1,
cat INT NOT NULL DEFAULT 0 FLAG=1,
other INT NOT NULL DEFAULT 0 FLAG=2)
ENGINE=CONNECT TABLE_TYPE=PIVOT TABNAME=pets OPTION_LIST='PivotCol=race,groupby=1';
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) NOT 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
/************** MyUtil C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: MYUTIL */
/* ------------- */
/* Version 1.1 */
/* Version 1.2 */
/* */
/* Author Olivier BERTRAND 2013 */
/* Author Olivier BERTRAND 2014 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
......@@ -26,6 +26,8 @@
#include "myutil.h"
#define DLL_EXPORT // Items are exported from this DLL
extern "C" int xconv;
/************************************************************************/
/* Convert from MySQL type name to PlugDB type number */
/************************************************************************/
......@@ -38,8 +40,7 @@ int MYSQLtoPLG(char *typname, char *var)
type = TYPE_INT;
else if (!stricmp(typname, "smallint"))
type = TYPE_SHORT;
else if (!stricmp(typname, "char") || !stricmp(typname, "varchar") ||
!stricmp(typname, "text") || !stricmp(typname, "blob"))
else if (!stricmp(typname, "char") || !stricmp(typname, "varchar"))
type = TYPE_STRING;
else if (!stricmp(typname, "double") || !stricmp(typname, "float") ||
!stricmp(typname, "real"))
......@@ -54,7 +55,20 @@ int MYSQLtoPLG(char *typname, char *var)
type = TYPE_BIGINT;
else if (!stricmp(typname, "tinyint"))
type = TYPE_TINY;
else
else if (!stricmp(typname, "text") && var) {
switch (xconv) {
case 1:
type = TYPE_STRING;
*var = 'X';
break;
case 2:
*var = 'K';
default:
type = TYPE_ERROR;
} // endswitch xconv
return type;
} else
type = TYPE_ERROR;
if (var) {
......@@ -71,9 +85,11 @@ int MYSQLtoPLG(char *typname, char *var)
else if (!stricmp(typname, "year"))
*var = 'Y';
} else if (type == TYPE_STRING && stricmp(typname, "char"))
} else if (type == TYPE_STRING && !stricmp(typname, "varchar"))
// This is to make the difference between CHAR and VARCHAR
*var = 'V';
else if (type == TYPE_ERROR && xconv == 2)
*var = 'K';
else
*var = 0;
......@@ -196,34 +212,50 @@ int MYSQLtoPLG(int mytype, char *var)
#if !defined(ALPHA)
case MYSQL_TYPE_VARCHAR:
#endif // !ALPHA)
case MYSQL_TYPE_STRING:
type = TYPE_STRING;
break;
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_STRING:
type = TYPE_STRING;
break;
if (var) {
switch (xconv) {
case 1:
if (*var != 'B') {
// This is a TEXT column
type = TYPE_STRING;
*var = 'X';
} else
type = TYPE_ERROR;
break;
case 2:
*var = 'K'; // Skip
default:
type = TYPE_ERROR;
} // endswitch xconv
return type;
} // endif var
default:
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;
case MYSQL_TYPE_VAR_STRING: *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;
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;
......
......@@ -124,7 +124,7 @@ int TranslateSQLType(int stp, int prec, int& len, char& v)
case SQL_LONGVARCHAR: // (-1)
v = 'V';
type = TYPE_STRING;
len = min(abs(len), 256);
len = MY_MIN(abs(len), 256);
break;
case SQL_NUMERIC: // 2
case SQL_DECIMAL: // 3
......@@ -312,7 +312,7 @@ PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *db, char *table,
if (table && !strchr(table, '%')) {
// We fix a MySQL limit because some data sources return 32767
n = ocp->GetMaxValue(SQL_MAX_COLUMNS_IN_TABLE);
maxres = (n) ? min(n, 4096) : 4096;
maxres = (n) ? MY_MIN(n, 4096) : 4096;
} else if (!maxres)
maxres = 20000;
......@@ -1858,7 +1858,7 @@ PQRYRES ODBConn::GetMetaData(PGLOBAL g, char *dsn, char *src)
if (!Check(rc))
ThrowDBX(rc, "SQLDescribeCol", hstmt);
length[0] = max(length[0], (UINT)nl);
length[0] = MY_MAX(length[0], (UINT)nl);
} // endfor i
} catch(DBX *x) {
......
......@@ -16,6 +16,7 @@ my_bool CloseFileHandle(HANDLE h)
#include <sys/stat.h>
#include <ctype.h>
#include <fcntl.h>
#include <pwd.h>
extern FILE *debug;
......@@ -172,13 +173,19 @@ char *_fullpath(char *absPath, const char *relPath, size_t maxLength)
// Fixme
char *p;
if( *relPath == '\\' || *relPath == '/' ) {
if ( *relPath == '\\' || *relPath == '/' ) {
strncpy(absPath, relPath, maxLength);
} else if(*relPath == '~') {
} else if (*relPath == '~') {
// get the path to the home directory
// Fixme
strncpy(absPath, relPath, maxLength);
} else {
struct passwd *pw = getpwuid(getuid());
const char *homedir = pw->pw_dir;
if (homedir)
strcat(strncpy(absPath, homedir, maxLength), relPath + 1);
else
strncpy(absPath, relPath, maxLength);
} else {
char buff[2*_MAX_PATH];
p= getcwd(buff, _MAX_PATH);
......
......@@ -9,16 +9,6 @@
#define MB_OK 0x00000000
#if !defined(__MINMAX_DEFINED)
#define __MINMAX_DEFINED
#ifndef max
#define max(x,y) (((x)>(y))?(x):(y))
#endif
#ifndef min
#define min(x,y) (((x)<(y))?(x):(y))
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
......
......@@ -158,6 +158,7 @@ enum ALGMOD {AMOD_AUTO = 0, /* PLG chooses best algorithm */
enum MODE {MODE_ERROR = -1, /* Invalid mode */
MODE_ANY = 0, /* Unspecified mode */
MODE_READ = 10, /* Input/Output mode */
MODE_READX = 11, /* Read indexed mode */
MODE_WRITE = 20, /* Input/Output mode */
MODE_UPDATE = 30, /* Input/Output mode */
MODE_INSERT = 40, /* Input/Output mode */
......@@ -291,6 +292,7 @@ enum OPVAL {OP_EQ = 1, /* Filtering operator = */
OP_CURDT = 113, /* Scalar function Op CurDate */
OP_NWEEK = 114, /* Scalar function Op Week number*/
OP_ROW = 115, /* Scalar function Op Row */
OP_PREV = 116, /* Index operator Find Previous */
OP_SYSTEM = 200, /* Scalar function Op System */
OP_REMOVE = 201, /* Scalar function Op Remove */
OP_RENAME = 202, /* Scalar function Op Rename */
......
......@@ -383,7 +383,7 @@ PCATLG PlgGetCatalog(PGLOBAL g, bool jump)
} // end of PlgGetCatalog
/***********************************************************************/
/* PlgGetCatalog: returns CATALOG class pointer. */
/* PlgGetDataPath: returns the default data path. */
/***********************************************************************/
char *PlgGetDataPath(PGLOBAL g)
{
......@@ -721,7 +721,7 @@ int ExtractDate(char *dts, PDTP pdp, int defy, int val[6])
n += 100;
val[0] = n;
numval = max(numval, 1);
numval = MY_MAX(numval, 1);
break;
case 1:
case 2:
......@@ -729,7 +729,7 @@ int ExtractDate(char *dts, PDTP pdp, int defy, int val[6])
case 4:
case 5:
val[k] = n;
numval = max(numval, k + 1);
numval = MY_MAX(numval, k + 1);
break;
case -1:
c = toupper(W[i][0]);
......@@ -753,7 +753,7 @@ int ExtractDate(char *dts, PDTP pdp, int defy, int val[6])
} /* endswitch c */
val[1] = n;
numval = max(numval, 2);
numval = MY_MAX(numval, 2);
break;
case -6:
c = toupper(W[i][0]);
......@@ -1225,7 +1225,7 @@ void *PlgDBrealloc(PGLOBAL g, void *area, MBLOCK& mp, size_t newsize)
if ((mp.Sub = (newsize <= (maxsub >> 2)))) {
mp.Memp = PlugSubAlloc(g, area, newsize);
memcpy(mp.Memp, m.Memp, min(m.Size, newsize));
memcpy(mp.Memp, m.Memp, MY_MIN(m.Size, newsize));
PlgDBfree(m); // Free the old block
} else if (!(mp.Memp = realloc(mp.Memp, newsize))) {
mp = m; // Possible only if newsize > Size
......@@ -1241,7 +1241,7 @@ void *PlgDBrealloc(PGLOBAL g, void *area, MBLOCK& mp, size_t newsize)
mp.Size = newsize;
if (PlgDBalloc(g, area, mp)) {
memcpy(mp.Memp, m.Memp, min(m.Size, newsize));
memcpy(mp.Memp, m.Memp, MY_MIN(m.Size, newsize));
PlgDBfree(m); // Free the old block
} else {
mp = m; // No space to realloc, do nothing
......
......@@ -115,11 +115,6 @@ void htrc(char const *fmt, ...)
va_list ap;
va_start (ap, fmt);
//if (trace == 0 || (trace == 1 && !debug) || !fmt) {
// printf("In %s wrong trace=%d debug=%p fmt=%p\n",
// __FILE__, trace, debug, fmt);
// trace = 0;
// } // endif trace
//if (trace == 1)
// vfprintf(debug, fmt, ap);
......@@ -255,7 +250,20 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath)
strcpy(pBuff, FileName); // FileName includes absolute path
return pBuff;
} // endif
#if !defined(WIN32)
if (*FileName == '~') {
if (_fullpath(pBuff, FileName, _MAX_PATH)) {
if (trace > 1)
htrc("pbuff='%s'\n", pBuff);
return pBuff;
} else
return FileName; // Error, return unchanged name
} // endif FileName
#endif // !WIN32
if (strcmp(prefix, ".") && !PlugIsAbsolutePath(defpath))
{
char tmp[_MAX_PATH];
......@@ -477,10 +485,9 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
size = ((size + 7) / 8) * 8; /* Round up size to multiple of 8 */
pph = (PPOOLHEADER)memp;
#if defined(DEBUG2) || defined(DEBUG3)
htrc("SubAlloc in %p size=%d used=%d free=%d\n",
memp, size, pph->To_Free, pph->FreeBlk);
#endif
if (trace > 2)
htrc("SubAlloc in %p size=%d used=%d free=%d\n",
memp, size, pph->To_Free, pph->FreeBlk);
if ((uint)size > pph->FreeBlk) { /* Not enough memory left in pool */
char *pname = "Work";
......@@ -489,9 +496,8 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
"Not enough memory in %s area for request of %u (used=%d free=%d)",
pname, (uint) size, pph->To_Free, pph->FreeBlk);
#if defined(DEBUG2) || defined(DEBUG3)
htrc("%s\n", g->Message);
#endif
if (trace)
htrc("PlugSubAlloc: %s\n", g->Message);
longjmp(g->jumper[g->jump_level], 1);
} /* endif size OS32 code */
......@@ -502,10 +508,11 @@ void *PlugSubAlloc(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(DEBUG2) || defined(DEBUG3)
htrc("Done memp=%p used=%d free=%d\n",
memp, pph->To_Free, pph->FreeBlk);
#endif
if (trace > 2)
htrc("Done memp=%p used=%d free=%d\n",
memp, pph->To_Free, pph->FreeBlk);
return (memp);
} /* end of PlugSubAlloc */
......
This diff is collapsed.
......@@ -13,7 +13,8 @@
#include "catalog.h"
#include "my_sys.h"
typedef class INDEXDEF *PIXDEF;
typedef class INDEXDEF *PIXDEF;
typedef class ha_connect *PHC;
/***********************************************************************/
/* Table or View (relation) definition block. */
......@@ -30,6 +31,7 @@ class DllExport RELDEF : public BLOCK { // Relation definition block
PSZ GetName(void) {return Name;}
PSZ GetDB(void) {return (PSZ)Database;}
PCOLDEF GetCols(void) {return To_Cols;}
PHC GetHandler(void) {return Hc;}
void SetCols(PCOLDEF pcd) {To_Cols = pcd;}
PCATLG GetCat(void) {return Cat;}
virtual const char *GetType(void) = 0;
......@@ -38,7 +40,13 @@ class DllExport RELDEF : public BLOCK { // Relation definition block
void SetCat(PCATLG cat) { Cat=cat; }
// Methods
virtual bool Indexable(void) {return false;}
bool GetBoolCatInfo(PSZ what, bool bdef);
bool SetIntCatInfo(PSZ what, int ival);
int GetIntCatInfo(PSZ what, int idef);
int GetSizeCatInfo(PSZ what, PSZ sdef);
int GetCharCatInfo(PSZ what, PSZ sdef, char *buf, int size);
char *GetStringCatInfo(PGLOBAL g, PSZ what, PSZ sdef);
virtual int Indexable(void) {return 0;}
virtual bool Define(PGLOBAL g, PCATLG cat, LPCSTR name, LPCSTR am) = 0;
virtual PTDB GetTable(PGLOBAL g, MODE mode) = 0;
......@@ -48,6 +56,7 @@ class DllExport RELDEF : public BLOCK { // Relation definition block
LPCSTR Database; /* Table database */
PCOLDEF To_Cols; /* To a list of column desc */
PCATLG Cat; /* To DB catalog info */
PHC Hc; /* The Connect handler */
}; // end of RELDEF
/***********************************************************************/
......@@ -71,7 +80,7 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */
int GetPseudo(void) {return Pseudo;}
PSZ GetPath(void)
{return (Database) ? (PSZ)Database : Cat->GetDataPath();}
bool SepIndex(void) {return Cat->GetBoolCatInfo("SepIndex", false);}
bool SepIndex(void) {return GetBoolCatInfo("SepIndex", false);}
bool IsReadOnly(void) {return Read_Only;}
virtual AMT GetDefType(void) {return TYPE_AM_TAB;}
virtual PIXDEF GetIndx(void) {return NULL;}
......@@ -80,6 +89,8 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */
const CHARSET_INFO *data_charset() {return m_data_charset;}
// Methods
int GetColCatInfo(PGLOBAL g);
void SetIndexInfo(void);
bool DropTable(PGLOBAL g, PSZ name);
virtual bool Define(PGLOBAL g, PCATLG cat, LPCSTR name, LPCSTR am);
virtual bool DefineAM(PGLOBAL, LPCSTR, int) = 0;
......@@ -168,9 +179,7 @@ class DllExport COLCRT : public BLOCK { /* Column description block
/* Column definition block. */
/***********************************************************************/
class DllExport COLDEF : public COLCRT { /* Column description block */
friend class CATALOG;
friend class PLUGCAT;
friend class MYCAT;
friend class TABDEF;
friend class COLBLK;
friend class DBFFAM;
friend class TDBASE;
......
......@@ -104,36 +104,37 @@ bool DOSDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
: (am && (*am == 'B' || *am == 'b')) ? "B"
: (am && !stricmp(am, "DBF")) ? "D" : "V";
Desc = Fn = Cat->GetStringCatInfo(g, "Filename", NULL);
Ofn = Cat->GetStringCatInfo(g, "Optname", Fn);
Cat->GetCharCatInfo("Recfm", (PSZ)dfm, buf, sizeof(buf));
Desc = Fn = GetStringCatInfo(g, "Filename", NULL);
Ofn = GetStringCatInfo(g, "Optname", Fn);
GetCharCatInfo("Recfm", (PSZ)dfm, buf, sizeof(buf));
Recfm = (toupper(*buf) == 'F') ? RECFM_FIX :
(toupper(*buf) == 'B') ? RECFM_BIN :
(toupper(*buf) == 'D') ? RECFM_DBF : RECFM_VAR;
Lrecl = Cat->GetIntCatInfo("Lrecl", 0);
Lrecl = GetIntCatInfo("Lrecl", 0);
if (Recfm != RECFM_DBF)
Compressed = Cat->GetIntCatInfo("Compressed", 0);
Compressed = GetIntCatInfo("Compressed", 0);
Mapped = Cat->GetBoolCatInfo("Mapped", map);
Block = Cat->GetIntCatInfo("Blocks", 0);
Last = Cat->GetIntCatInfo("Last", 0);
Ending = Cat->GetIntCatInfo("Ending", CRLF);
Mapped = GetBoolCatInfo("Mapped", map);
Block = GetIntCatInfo("Blocks", 0);
Last = GetIntCatInfo("Last", 0);
Ending = GetIntCatInfo("Ending", CRLF);
if (Recfm == RECFM_FIX || Recfm == RECFM_BIN) {
Huge = Cat->GetBoolCatInfo("Huge", Cat->GetDefHuge());
Padded = Cat->GetBoolCatInfo("Padded", false);
Blksize = Cat->GetIntCatInfo("Blksize", 0);
Eof = (Cat->GetIntCatInfo("EOF", 0) != 0);
Huge = GetBoolCatInfo("Huge", Cat->GetDefHuge());
Padded = GetBoolCatInfo("Padded", false);
Blksize = GetIntCatInfo("Blksize", 0);
Eof = (GetIntCatInfo("EOF", 0) != 0);
} else if (Recfm == RECFM_DBF) {
Maxerr = Cat->GetIntCatInfo("Maxerr", 0);
Accept = (Cat->GetIntCatInfo("Accept", 0) != 0);
ReadMode = Cat->GetIntCatInfo("Readmode", 0);
Maxerr = GetIntCatInfo("Maxerr", 0);
Accept = (GetIntCatInfo("Accept", 0) != 0);
ReadMode = GetIntCatInfo("Readmode", 0);
} else // (Recfm == RECFM_VAR)
AvgLen = Cat->GetIntCatInfo("Avglen", 0);
AvgLen = GetIntCatInfo("Avglen", 0);
// Ignore wrong Index definitions for catalog commands
return (Cat->GetIndexInfo(g, this) /*&& !Cat->GetCatFnc()*/);
SetIndexInfo();
return false;
} // end of DefineAM
#if 0
......@@ -190,7 +191,7 @@ bool DOSDEF::DeleteIndexFile(PGLOBAL g, PIXDEF pxdf)
return false; // No index
// If true indexes are in separate files
sep = Cat->GetBoolCatInfo("SepIndex", false);
sep = GetBoolCatInfo("SepIndex", false);
if (!sep && pxdf) {
strcpy(g->Message, MSG(NO_RECOV_SPACE));
......@@ -449,7 +450,6 @@ int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
//PCOLDEF cdp;
PXINDEX x;
PXLOAD pxp;
PCATLG cat = PlgGetCatalog(g);
Mode = MODE_READ;
Use = USE_READY;
......@@ -494,11 +494,11 @@ int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
} // endif Type
colp->InitValue(g);
n = max(n, xdp->GetNparts());
n = MY_MAX(n, xdp->GetNparts());
} // endfor kdp
keycols = (PCOL*)PlugSubAlloc(g, NULL, n * sizeof(PCOL));
sep = cat->GetBoolCatInfo("SepIndex", false);
sep = dfp->GetBoolCatInfo("SepIndex", false);
/*********************************************************************/
/* Construct and save the defined indexes. */
......@@ -687,7 +687,7 @@ int TDBDOS::EstimatedLength(PGLOBAL g)
// result if we set dep to 1
dep = 1 + cdp->GetLong() / 20; // Why 20 ?????
} else for (; cdp; cdp = cdp->GetNext())
dep = max(dep, cdp->GetOffset());
dep = MY_MAX(dep, cdp->GetOffset());
return (int)dep;
} // end of Estimated Length
......@@ -1004,7 +1004,7 @@ bool DOSCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
// Allocate the buffer used in WriteColumn for numeric columns
if (IsTypeNum(Buf_Type))
Buf = (char*)PlugSubAlloc(g, NULL, max(32, Long + Dcm + 1));
Buf = (char*)PlugSubAlloc(g, NULL, MY_MAX(32, Long + Dcm + 1));
// Because Colblk's have been made from a copy of the original TDB in
// case of Update, we must reset them to point to the original one.
......@@ -1133,7 +1133,7 @@ void DOSCOL::WriteColumn(PGLOBAL g)
memset(tdbp->To_Line + len, ' ', tdbp->Lrecl - len);
else
// The size actually available must be recalculated
field = min(len - Deplac, Long);
field = MY_MIN(len - Deplac, Long);
} // endif Ftype
......
......@@ -49,7 +49,7 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
int GetEnding(void) {return Ending;}
// Methods
virtual bool Indexable(void) {return Compressed != 1;}
virtual int Indexable(void) {return (Compressed != 1) ? 1 : 0;}
virtual bool DeleteIndexFile(PGLOBAL g, PIXDEF pxdf);
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE mode);
......@@ -146,10 +146,10 @@ class DllExport TDBDOS : public TDBASE {
virtual int ReadBuffer(PGLOBAL g) {return Txfp->ReadBuffer(g);}
// Specific routine
virtual int EstimatedLength(PGLOBAL g);
virtual int EstimatedLength(PGLOBAL g);
// Optimization routines
int MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add);
virtual int MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add);
protected:
// Members
......
......@@ -118,7 +118,7 @@ PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q,
} // endif fn
imax = hmax = nerr = 0;
mxr = max(0, mxr);
mxr = MY_MAX(0, mxr);
for (i = 0; i < MAXCOL; i++) {
colname[i] = NULL;
......@@ -190,7 +190,7 @@ PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q,
imax = hmax = i;
for (i = 0; i < hmax; i++)
length[0] = max(length[0], strlen(colname[i]));
length[0] = MY_MAX(length[0], strlen(colname[i]));
} // endif hdr
......@@ -228,11 +228,11 @@ PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q,
} // endif i
if (n) {
len[i] = max(len[i], n);
len[i] = MY_MAX(len[i], n);
type = (digit || (dec && n == 1)) ? TYPE_STRING
: (dec) ? TYPE_DOUBLE : TYPE_INT;
typ[i] = min(type, typ[i]);
prc[i] = max((typ[i] == TYPE_DOUBLE) ? (dec - 1) : 0, prc[i]);
typ[i] = MY_MIN(type, typ[i]);
prc[i] = MY_MAX((typ[i] == TYPE_DOUBLE) ? (dec - 1) : 0, prc[i]);
} // endif n
i++;
......@@ -308,14 +308,14 @@ PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q,
goto skip;
if (n) {
len[i] = max(len[i], n);
len[i] = MY_MAX(len[i], n);
type = (digit || n == 0 || (dec && n == 1)) ? TYPE_STRING
: (dec) ? TYPE_DOUBLE : TYPE_INT;
typ[i] = min(type, typ[i]);
prc[i] = max((typ[i] == TYPE_DOUBLE) ? (dec - 1) : 0, prc[i]);
typ[i] = MY_MIN(type, typ[i]);
prc[i] = MY_MAX((typ[i] == TYPE_DOUBLE) ? (dec - 1) : 0, prc[i]);
} // endif n
imax = max(imax, i+1);
imax = MY_MAX(imax, i+1);
skip: ; // Skip erroneous line
} // endfor num_read
......@@ -415,10 +415,10 @@ bool CSVDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
if (DOSDEF::DefineAM(g, "CSV", poff))
return true;
Cat->GetCharCatInfo("Separator", ",", buf, sizeof(buf));
GetCharCatInfo("Separator", ",", buf, sizeof(buf));
Sep = (strlen(buf) == 2 && buf[0] == '\\' && buf[1] == 't') ? '\t' : *buf;
Quoted = Cat->GetIntCatInfo("Quoted", -1);
Cat->GetCharCatInfo("Qchar", "", buf, sizeof(buf));
Quoted = GetIntCatInfo("Quoted", -1);
GetCharCatInfo("Qchar", "", buf, sizeof(buf));
Qot = *buf;
if (Qot && Quoted < 0)
......@@ -427,9 +427,9 @@ bool CSVDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Qot = '"';
Fmtd = (!Sep || (am && (*am == 'F' || *am == 'f')));
Header = (Cat->GetIntCatInfo("Header", 0) != 0);
Maxerr = Cat->GetIntCatInfo("Maxerr", 0);
Accept = (Cat->GetIntCatInfo("Accept", 0) != 0);
Header = (GetIntCatInfo("Header", 0) != 0);
Maxerr = GetIntCatInfo("Maxerr", 0);
Accept = (GetIntCatInfo("Accept", 0) != 0);
return false;
} // end of DefineAM
......@@ -599,7 +599,7 @@ int TDBCSV::EstimatedLength(PGLOBAL g)
for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next)
if (!colp->IsSpecial()) // Not a pseudo column
Fields = max(Fields, (int)colp->Fldnum);
Fields = MY_MAX(Fields, (int)colp->Fldnum);
if (Columns)
Fields++; // Fldnum was 0 based
......@@ -642,7 +642,7 @@ bool TDBCSV::OpenDB(PGLOBAL g)
if (Mode != MODE_UPDATE && Mode != MODE_INSERT) {
for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next)
if (!colp->IsSpecial()) // Not a pseudo column
Fields = max(Fields, (int)colp->Fldnum);
Fields = MY_MAX(Fields, (int)colp->Fldnum);
if (Columns)
Fields++; // Fldnum was 0 based
......@@ -1102,7 +1102,7 @@ bool TDBFMT::OpenDB(PGLOBAL g)
for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next)
if (!colp->IsSpecial()) // Not a pseudo column
Fields = max(Fields, (int)colp->Fldnum);
Fields = MY_MAX(Fields, (int)colp->Fldnum);
if (Columns)
Fields++; // Fldnum was 0 based
......
......@@ -591,9 +591,9 @@ void TDBMUL::CloseDB(PGLOBAL g)
/***********************************************************************/
bool DIRDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
Desc = Fn = Cat->GetStringCatInfo(g, "Filename", NULL);
Incl = (Cat->GetIntCatInfo("Subdir", 0) != 0);
Huge = (Cat->GetIntCatInfo("Huge", 0) != 0);
Desc = Fn = GetStringCatInfo(g, "Filename", NULL);
Incl = (GetIntCatInfo("Subdir", 0) != 0);
Huge = (GetIntCatInfo("Huge", 0) != 0);
return false;
} // end of DefineAM
......
......@@ -61,6 +61,7 @@
#include "tabmysql.h"
#include "valblk.h"
#include "tabutil.h"
#include "ha_connect.h"
#if defined(_CONSOLE)
void PrintResult(PGLOBAL, PSEM, PQRYRES);
......@@ -268,22 +269,22 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url, bool b)
// For unspecified values, get the values of old style options
// but only if called from MYSQLDEF, else set them to NULL
Portnumber = (sport && sport[0]) ? atoi(sport)
: (b) ? Cat->GetIntCatInfo("Port", GetDefaultPort()) : 0;
: (b) ? GetIntCatInfo("Port", GetDefaultPort()) : 0;
if (Username[0] == 0)
Username = (b) ? Cat->GetStringCatInfo(g, "User", "*") : NULL;
Username = (b) ? GetStringCatInfo(g, "User", "*") : NULL;
if (Hostname[0] == 0)
Hostname = (b) ? Cat->GetStringCatInfo(g, "Host", "localhost") : NULL;
Hostname = (b) ? GetStringCatInfo(g, "Host", "localhost") : NULL;
if (!Database || !*Database)
Database = (b) ? Cat->GetStringCatInfo(g, "Database", "*") : NULL;
Database = (b) ? GetStringCatInfo(g, "Database", "*") : NULL;
if (!Tabname || !*Tabname)
Tabname = (b) ? Cat->GetStringCatInfo(g, "Tabname", Name) : NULL;
Tabname = (b) ? GetStringCatInfo(g, "Tabname", Name) : NULL;
if (!Password)
Password = (b) ? Cat->GetStringCatInfo(g, "Password", NULL) : NULL;
Password = (b) ? GetStringCatInfo(g, "Password", NULL) : NULL;
} // endif URL
#if 0
......@@ -308,37 +309,37 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
if (stricmp(am, "MYPRX")) {
// Normal case of specific MYSQL table
url = Cat->GetStringCatInfo(g, "Connect", NULL);
url = GetStringCatInfo(g, "Connect", NULL);
if (!url || !*url) {
// Not using the connection URL
Hostname = Cat->GetStringCatInfo(g, "Host", "localhost");
Database = Cat->GetStringCatInfo(g, "Database", "*");
Tabname = Cat->GetStringCatInfo(g, "Name", Name); // Deprecated
Tabname = Cat->GetStringCatInfo(g, "Tabname", Tabname);
Username = Cat->GetStringCatInfo(g, "User", "*");
Password = Cat->GetStringCatInfo(g, "Password", NULL);
Portnumber = Cat->GetIntCatInfo("Port", GetDefaultPort());
Hostname = GetStringCatInfo(g, "Host", "localhost");
Database = GetStringCatInfo(g, "Database", "*");
Tabname = GetStringCatInfo(g, "Name", Name); // Deprecated
Tabname = GetStringCatInfo(g, "Tabname", Tabname);
Username = GetStringCatInfo(g, "User", "*");
Password = GetStringCatInfo(g, "Password", NULL);
Portnumber = GetIntCatInfo("Port", GetDefaultPort());
Server = Hostname;
} else if (ParseURL(g, url))
return true;
Bind = !!Cat->GetIntCatInfo("Bind", 0);
Delayed = !!Cat->GetIntCatInfo("Delayed", 0);
Bind = !!GetIntCatInfo("Bind", 0);
Delayed = !!GetIntCatInfo("Delayed", 0);
} else {
// MYSQL access from a PROXY table
Database = Cat->GetStringCatInfo(g, "Database", "*");
Isview = Cat->GetBoolCatInfo("View", FALSE);
Database = GetStringCatInfo(g, "Database", "*");
Isview = GetBoolCatInfo("View", FALSE);
// We must get other connection parms from the calling table
Remove_tshp(Cat);
url = Cat->GetStringCatInfo(g, "Connect", NULL);
url = GetStringCatInfo(g, "Connect", NULL);
if (!url || !*url) {
Hostname = Cat->GetStringCatInfo(g, "Host", "localhost");
Username = Cat->GetStringCatInfo(g, "User", "*");
Password = Cat->GetStringCatInfo(g, "Password", NULL);
Portnumber = Cat->GetIntCatInfo("Port", GetDefaultPort());
Hostname = GetStringCatInfo(g, "Host", "localhost");
Username = GetStringCatInfo(g, "User", "*");
Password = GetStringCatInfo(g, "Password", NULL);
Portnumber = GetIntCatInfo("Port", GetDefaultPort());
Server = Hostname;
} else {
char *locdb = Database;
......@@ -352,16 +353,16 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Tabname = Name;
} // endif am
if ((Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL)))
if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL)))
Isview = true;
// Used for Update and Delete
Qrystr = Cat->GetStringCatInfo(g, "Query_String", "?");
Quoted = Cat->GetIntCatInfo("Quoted", 0);
Qrystr = GetStringCatInfo(g, "Query_String", "?");
Quoted = GetIntCatInfo("Quoted", 0);
// Specific for command executing tables
Xsrc = Cat->GetBoolCatInfo("Execsrc", false);
Mxr = Cat->GetIntCatInfo("Maxerr", 0);
Xsrc = GetBoolCatInfo("Execsrc", false);
Mxr = GetIntCatInfo("Maxerr", 0);
return FALSE;
} // end of DefineAM
......@@ -395,7 +396,7 @@ TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp)
Pwd = tdp->Password;
Server = tdp->Server;
Qrystr = tdp->Qrystr;
Quoted = max(0, tdp->Quoted);
Quoted = MY_MAX(0, tdp->Quoted);
Port = tdp->Portnumber;
Isview = tdp->Isview;
Prep = tdp->Bind;
......@@ -481,16 +482,16 @@ PCOL TDBMYSQL::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
/* Note: when implementing EOM filtering, column only used in local */
/* filter should be removed from column list. */
/***********************************************************************/
bool TDBMYSQL::MakeSelect(PGLOBAL g)
bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx)
{
char *tk = "`";
int rank = 0;
bool b = FALSE;
int len = 0, rank = 0;
bool b = false;
PCOL colp;
//PDBUSER dup = PlgGetUser(g);
if (Query)
return FALSE; // already done
return false; // already done
if (Srcdef) {
Query = Srcdef;
......@@ -506,12 +507,12 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g)
if (!colp->IsSpecial()) {
// if (colp->IsSpecial()) {
// strcpy(g->Message, MSG(NO_SPEC_COL));
// return TRUE;
// return true;
// } else {
if (b)
strcat(Query, ", ");
else
b = TRUE;
b = true;
strcat(strcat(strcat(Query, tk), colp->GetName()), tk);
((PMYCOL)colp)->Rank = rank++;
......@@ -526,16 +527,24 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g)
} // endif ncol
strcat(strcat(strcat(strcat(Query, " FROM "), tk), Tabname), tk);
len = strlen(Query);
if (To_CondFil) {
if (!mx) {
strcat(strcat(Query, " WHERE "), To_CondFil->Body);
len = strlen(Query) + 1;
} else
len += (strlen(To_CondFil->Body) + 256);
if (To_CondFil)
strcat(strcat(Query, " WHERE "), To_CondFil->Body);
} else
len += (mx ? 256 : 1);
if (trace)
htrc("Query=%s\n", Query);
// Now we know how much to suballocate
PlugSubAlloc(g, NULL, strlen(Query) + 1);
return FALSE;
PlugSubAlloc(g, NULL, len);
return false;
} // end of MakeSelect
/***********************************************************************/
......@@ -833,9 +842,9 @@ bool TDBMYSQL::OpenDB(PGLOBAL g)
/*********************************************************************/
/* Allocate whatever is used for getting results. */
/*********************************************************************/
if (Mode == MODE_READ) {
if (!MakeSelect(g))
m_Rc = Myc.ExecSQL(g, Query);
if (Mode == MODE_READ || Mode == MODE_READX) {
MakeSelect(g, Mode == MODE_READX);
m_Rc = (Mode == MODE_READ) ? Myc.ExecSQL(g, Query) : RC_OK;
#if 0
if (!Myc.m_Res || !Myc.m_Fields) {
......@@ -994,6 +1003,35 @@ int TDBMYSQL::SendCommand(PGLOBAL g)
} // end of SendCommand
/***********************************************************************/
/* Data Base indexed read routine for MYSQL access method. */
/***********************************************************************/
bool TDBMYSQL::ReadKey(PGLOBAL g, OPVAL op, const void *key, int len)
{
int oldlen = strlen(Query);
if (op == OP_NEXT)
return false;
else if (op == OP_FIRST) {
if (To_CondFil)
strcat(strcat(Query, " WHERE "), To_CondFil->Body);
} else {
if (Myc.m_Res)
Myc.FreeResult();
To_Def->GetHandler()->MakeKeyWhere(g, Query, op, "`", key, len);
if (To_CondFil)
strcat(strcat(strcat(Query, " AND ("), To_CondFil->Body), ")");
} // endif's op
m_Rc = Myc.ExecSQL(g, Query);
Query[oldlen] = 0;
return false;
} // end of ReadKey
/***********************************************************************/
/* Data Base read routine for MYSQL access method. */
/***********************************************************************/
......@@ -1134,9 +1172,12 @@ MYSQLCOL::MYSQLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
MYSQLCOL::MYSQLCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PSZ am)
: COLBLK(NULL, tdbp, i)
{
const char *chset = get_charset_name(fld->charsetnr);
char v = (!strcmp(chset, "binary")) ? 'B' : 0;
Name = fld->name;
Precision = Long = fld->length;
Buf_Type = MYSQLtoPLG(fld->type);
Buf_Type = MYSQLtoPLG(fld->type, &v);
strcpy(Format.Type, GetFormatType(Buf_Type));
Format.Length = Long;
Format.Prec = fld->decimals;
......@@ -1448,7 +1489,7 @@ bool TDBMYEXC::OpenDB(PGLOBAL g)
Use = USE_OPEN; // Do it now in case we are recursively called
if (Mode != MODE_READ) {
if (Mode != MODE_READ && Mode != MODE_READX) {
strcpy(g->Message, "No INSERT/DELETE/UPDATE of MYSQL EXEC tables");
return true;
} // endif Mode
......@@ -1615,5 +1656,5 @@ TDBMCL::TDBMCL(PMYDEF tdp) : TDBCAT(tdp)
/***********************************************************************/
PQRYRES TDBMCL::GetResult(PGLOBAL g)
{
return MyColumns(g, Host, Db, User, Pwd, Tab, NULL, Port, false);
return MyColumns(g, NULL, Host, Db, User, Pwd, Tab, NULL, Port, false);
} // end of GetResult
......@@ -39,6 +39,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
inline int GetPortnumber(void) {return Portnumber;}
// Methods
virtual int Indexable(void) {return 2;}
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE m);
bool ParseURL(PGLOBAL g, char *url, bool b = true);
......@@ -96,6 +97,7 @@ class TDBMYSQL : public TDBASE {
virtual int WriteDB(PGLOBAL g);
virtual int DeleteDB(PGLOBAL g, int irc);
virtual void CloseDB(PGLOBAL g);
virtual bool ReadKey(PGLOBAL g, OPVAL op, const void *key, int len);
// Specific routines
bool SetColumnRanks(PGLOBAL g);
......@@ -104,7 +106,7 @@ class TDBMYSQL : public TDBASE {
protected:
// Internal functions
bool MakeSelect(PGLOBAL g);
bool MakeSelect(PGLOBAL g, bool mx);
bool MakeInsert(PGLOBAL g);
int BindColumns(PGLOBAL g);
int MakeCommand(PGLOBAL g);
......
......@@ -106,7 +106,7 @@ bool OcrColumns(PGLOBAL g, PQRYRES qrp, const char *col,
} // endif m
for (k = 0, pn = colist; k < m; k++, pn += (strlen(pn) + 1))
n = max(n, (signed)strlen(pn));
n = MY_MAX(n, (signed)strlen(pn));
} // endif k
......@@ -199,7 +199,7 @@ bool OcrSrcCols(PGLOBAL g, PQRYRES qrp, const char *col,
if ((rk = (rank && *rank)))
for (k = 0, pn = colist; k < m; k++, pn += (strlen(pn) + 1))
n = max(n, (signed)strlen(pn));
n = MY_MAX(n, (signed)strlen(pn));
// Default occur column name is the 1st colist column name
if (!ocr || !*ocr)
......@@ -264,9 +264,9 @@ bool OcrSrcCols(PGLOBAL g, PQRYRES qrp, const char *col,
/***********************************************************************/
bool OCCURDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
Rcol = Cat->GetStringCatInfo(g, "RankCol", "");
Colist = Cat->GetStringCatInfo(g, "Colist", "");
Xcol = Cat->GetStringCatInfo(g, "OccurCol", Colist);
Rcol = GetStringCatInfo(g, "RankCol", "");
Colist = GetStringCatInfo(g, "Colist", "");
Xcol = GetStringCatInfo(g, "OccurCol", Colist);
return PRXDEF::DefineAM(g, am, poff);
} // end of DefineAM
......
......@@ -100,22 +100,22 @@ ODBCDEF::ODBCDEF(void)
/***********************************************************************/
bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
Desc = Connect = Cat->GetStringCatInfo(g, "Connect", "");
Tabname = Cat->GetStringCatInfo(g, "Name",
Desc = Connect = GetStringCatInfo(g, "Connect", "");
Tabname = GetStringCatInfo(g, "Name",
(Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
Tabname = Cat->GetStringCatInfo(g, "Tabname", Tabname);
Tabschema = Cat->GetStringCatInfo(g, "Dbname", NULL);
Tabschema = Cat->GetStringCatInfo(g, "Schema", Tabschema);
Tabcat = Cat->GetStringCatInfo(g, "Qualifier", NULL);
Tabcat = Cat->GetStringCatInfo(g, "Catalog", Tabcat);
Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL);
Qrystr = Cat->GetStringCatInfo(g, "Query_String", "?");
Sep = Cat->GetStringCatInfo(g, "Separator", NULL);
Catver = Cat->GetIntCatInfo("Catver", 2);
Xsrc = Cat->GetBoolCatInfo("Execsrc", FALSE);
Maxerr = Cat->GetIntCatInfo("Maxerr", 0);
Maxres = Cat->GetIntCatInfo("Maxres", 0);
Quoted = Cat->GetIntCatInfo("Quoted", 0);
Tabname = GetStringCatInfo(g, "Tabname", Tabname);
Tabschema = GetStringCatInfo(g, "Dbname", NULL);
Tabschema = GetStringCatInfo(g, "Schema", Tabschema);
Tabcat = GetStringCatInfo(g, "Qualifier", NULL);
Tabcat = GetStringCatInfo(g, "Catalog", Tabcat);
Srcdef = GetStringCatInfo(g, "Srcdef", NULL);
Qrystr = GetStringCatInfo(g, "Query_String", "?");
Sep = GetStringCatInfo(g, "Separator", NULL);
Catver = GetIntCatInfo("Catver", 2);
Xsrc = GetBoolCatInfo("Execsrc", FALSE);
Maxerr = GetIntCatInfo("Maxerr", 0);
Maxres = GetIntCatInfo("Maxres", 0);
Quoted = GetIntCatInfo("Quoted", 0);
Options = ODBConn::noOdbcDialog;
Pseudo = 2; // FILID is Ok but not ROWID
return false;
......@@ -178,7 +178,7 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp)
Qrystr = tdp->Qrystr;
Sep = tdp->GetSep();
Options = tdp->Options;
Quoted = max(0, tdp->GetQuoted());
Quoted = MY_MAX(0, tdp->GetQuoted());
Rows = tdp->GetElemt();
Catver = tdp->Catver;
} else {
......@@ -752,7 +752,7 @@ bool TDBODBC::OpenDB(PGLOBAL g)
/*********************************************************************/
/* Make the command and allocate whatever is used for getting results. */
/*********************************************************************/
if (Mode == MODE_READ) {
if (Mode == MODE_READ || Mode == MODE_READX) {
if ((Query = MakeSQL(g, false))) {
for (PODBCCOL colp = (PODBCCOL)Columns; colp;
colp = (PODBCCOL)colp->GetNext())
......@@ -1315,7 +1315,7 @@ bool TDBXDBC::OpenDB(PGLOBAL g)
Use = USE_OPEN; // Do it now in case we are recursively called
if (Mode != MODE_READ) {
if (Mode != MODE_READ && Mode != MODE_READX) {
strcpy(g->Message, "No INSERT/DELETE/UPDATE of XDBC tables");
return true;
} // endif Mode
......
......@@ -90,6 +90,7 @@ class TDBODBC : public TDBASE {
virtual void ResetSize(void);
virtual int GetAffectedRows(void) {return AftRows;}
virtual PSZ GetServer(void) {return "ODBC";}
virtual int Indexable(void) {return 2;}
// Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
......@@ -100,6 +101,8 @@ class TDBODBC : public TDBASE {
virtual int WriteDB(PGLOBAL g);
virtual int DeleteDB(PGLOBAL g, int irc);
virtual void CloseDB(PGLOBAL g);
virtual bool ReadKey(PGLOBAL g, OPVAL op, const void *key, int len)
{return true;}
protected:
// Internal functions
......
......@@ -58,11 +58,11 @@ extern "C" int trace;
/***********************************************************************/
PQRYRES PivotColumns(PGLOBAL g, const char *tab, const char *src,
const char *picol, const char *fncol,
const char *host, const char *db,
const char *user, const char *pwd,
int port)
const char *skcol, const char *host,
const char *db, const char *user,
const char *pwd, int port)
{
PIVAID pvd(tab, src, picol, fncol, host, db, user, pwd, port);
PIVAID pvd(tab, src, picol, fncol, skcol, host, db, user, pwd, port);
return pvd.MakePivotColumns(g);
} // end of PivotColumns
......@@ -72,10 +72,10 @@ PQRYRES PivotColumns(PGLOBAL g, const char *tab, const char *src,
/***********************************************************************/
/* PIVAID constructor. */
/***********************************************************************/
PIVAID::PIVAID(const char *tab, const char *src, const char *picol,
const char *fncol, const char *host, const char *db,
const char *user, const char *pwd, int port)
: CSORT(false)
PIVAID::PIVAID(const char *tab, const char *src, const char *picol,
const char *fncol, const char *skcol, const char *host,
const char *db, const char *user, const char *pwd,
int port) : CSORT(false)
{
Host = (char*)host;
User = (char*)user;
......@@ -86,24 +86,65 @@ PIVAID::PIVAID(const char *tab, const char *src, const char *picol,
Tabsrc = (char*)src;
Picol = (char*)picol;
Fncol = (char*)fncol;
Skcol = (char*)skcol;
Rblkp = NULL;
Port = (port) ? port : GetDefaultPort();
} // end of PIVAID constructor
/***********************************************************************/
/* Skip columns that are in the skipped column list. */
/***********************************************************************/
bool PIVAID::SkipColumn(PCOLRES crp, char *skc)
{
if (skc)
for (char *p = skc; *p; p += (strlen(p) + 1))
if (!stricmp(crp->Name, p))
return true;
return false;
} // end of SkipColumn
/***********************************************************************/
/* Make the Pivot table column list. */
/***********************************************************************/
PQRYRES PIVAID::MakePivotColumns(PGLOBAL g)
{
char *query, *colname, buf[64];
int ndif, nblin, w = 0;
PVAL valp;
char *p, *query, *colname, *skc, buf[64];
int rc, ndif, nblin, w = 0;
bool b = false;
PVAL valp;
PQRYRES qrp;
PCOLRES *pcrp, crp, fncrp = NULL;
// Save stack and allocation environment and prepare error return
if (g->jump_level == MAX_JUMP) {
strcpy(g->Message, MSG(TOO_MANY_JUMPS));
return NULL;
} // endif jump_level
if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) {
goto err;
} // endif rc
// Are there columns to skip?
if (Skcol) {
uint n = strlen(Skcol);
skc = (char*)PlugSubAlloc(g, NULL, n + 2);
strcpy(skc, Skcol);
skc[n + 1] = 0;
// Replace ; by nulls in skc
for (p = strchr(skc, ';'); p; p = strchr(p, ';'))
*p++ = 0;
} else
skc = NULL;
if (!Tabsrc && Tabname) {
// Locate the query
query = (char*)PlugSubAlloc(g, NULL, strlen(Tabname) + 16);
sprintf(query, "SELECT * FROM %s", Tabname);
query = (char*)PlugSubAlloc(g, NULL, strlen(Tabname) + 26);
sprintf(query, "SELECT * FROM `%s` LIMIT 1", Tabname);
} else if (!Tabsrc) {
strcpy(g->Message, MSG(SRC_TABLE_UNDEF));
return NULL;
......@@ -113,25 +154,25 @@ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g)
// Open a MySQL connection for this table
if (Myc.Open(g, Host, Database, User, Pwd, Port))
return NULL;
else
b = true;
// Send the source command to MySQL
if (Myc.ExecSQL(g, query, &w) == RC_FX) {
Myc.Close();
return NULL;
} // endif Exec
if (Myc.ExecSQL(g, query, &w) == RC_FX)
goto err;
// We must have a storage query to get pivot column values
Qryp = Myc.GetResult(g, true);
Myc.Close();
if (!(Qryp = Myc.GetResult(g, true)))
goto err;
if (!Fncol) {
for (crp = Qryp->Colresp; crp; crp = crp->Next)
if (!Picol || stricmp(Picol, crp->Name))
if ((!Picol || stricmp(Picol, crp->Name)) && !SkipColumn(crp, skc))
Fncol = crp->Name;
if (!Fncol) {
strcpy(g->Message, MSG(NO_DEF_FNCCOL));
return NULL;
goto err;
} // endif Fncol
} // endif Fncol
......@@ -139,19 +180,27 @@ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g)
if (!Picol) {
// Find default Picol as the last one not equal to Fncol
for (crp = Qryp->Colresp; crp; crp = crp->Next)
if (stricmp(Fncol, crp->Name))
if (stricmp(Fncol, crp->Name) && !SkipColumn(crp, skc))
Picol = crp->Name;
if (!Picol) {
strcpy(g->Message, MSG(NO_DEF_PIVOTCOL));
return NULL;
goto err;
} // endif Picol
} // endif picol
// Prepare the column list
for (pcrp = &Qryp->Colresp; crp = *pcrp; )
if (!stricmp(Picol, crp->Name)) {
if (SkipColumn(crp, skc)) {
// Ignore this column
*pcrp = crp->Next;
} else if (!stricmp(Picol, crp->Name)) {
if (crp->Nulls) {
sprintf(g->Message, "Pivot column %s cannot be nullable", Picol);
goto err;
} // endif Nulls
Rblkp = crp->Kdata;
*pcrp = crp->Next;
} else if (!stricmp(Fncol, crp->Name)) {
......@@ -162,31 +211,59 @@ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g)
if (!Rblkp) {
strcpy(g->Message, MSG(NO_DEF_PIVOTCOL));
return NULL;
goto err;
} else if (!fncrp) {
strcpy(g->Message, MSG(NO_DEF_FNCCOL));
return NULL;
goto err;
} // endif
// Before calling sort, initialize all
nblin = Qryp->Nblin;
if (Tabsrc) {
Myc.Close();
b = false;
Index.Size = nblin * sizeof(int);
Index.Sub = TRUE; // Should be small enough
// Before calling sort, initialize all
nblin = Qryp->Nblin;
if (!PlgDBalloc(g, NULL, Index))
return NULL;
Index.Size = nblin * sizeof(int);
Index.Sub = TRUE; // Should be small enough
Offset.Size = (nblin + 1) * sizeof(int);
Offset.Sub = TRUE; // Should be small enough
if (!PlgDBalloc(g, NULL, Index))
return NULL;
if (!PlgDBalloc(g, NULL, Offset))
return NULL;
Offset.Size = (nblin + 1) * sizeof(int);
Offset.Sub = TRUE; // Should be small enough
ndif = Qsort(g, nblin);
if (!PlgDBalloc(g, NULL, Offset))
return NULL;
if (ndif < 0) // error
return NULL;
ndif = Qsort(g, nblin);
if (ndif < 0) // error
return NULL;
} else {
// The query was limited, we must get pivot column values
query = (char*)PlugSubAlloc(g, NULL, 0);
sprintf(query, "SELECT DISTINCT `%s` FROM `%s`", Picol, Tabname);
PlugSubAlloc(g, NULL, strlen(query) + 1);
Myc.FreeResult();
// Send the source command to MySQL
if (Myc.ExecSQL(g, query, &w) == RC_FX)
goto err;
// We must have a storage query to get pivot column values
if (!(qrp = Myc.GetResult(g, true)))
goto err;
Myc.Close();
b = false;
// Get the column list
crp = qrp->Colresp;
Rblkp = crp->Kdata;
ndif = qrp->Nblin;
} // endif Tabsrc
// Allocate the Value used to retieve column names
if (!(valp = AllocateValue(g, Rblkp->GetType(),
......@@ -203,7 +280,11 @@ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g)
crp = fncrp;
// Get the value that will be the generated column name
valp->SetValue_pvblk(Rblkp, Pex[Pof[i]]);
if (Tabsrc)
valp->SetValue_pvblk(Rblkp, Pex[Pof[i]]);
else
valp->SetValue_pvblk(Rblkp, i);
colname = valp->GetCharString(buf);
crp->Name = (char*)PlugSubAlloc(g, NULL, strlen(colname) + 1);
strcpy(crp->Name, colname);
......@@ -218,6 +299,12 @@ PQRYRES PIVAID::MakePivotColumns(PGLOBAL g)
// We added ndif columns and removed 2 (picol and fncol)
Qryp->Nbcol += (ndif - 2);
return Qryp;
err:
if (b)
Myc.Close();
return NULL;
} // end of MakePivotColumns
/***********************************************************************/
......@@ -257,11 +344,11 @@ bool PIVOTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
DB = (char*)Tablep->GetQualifier();
Tabsrc = (char*)Tablep->GetSrc();
Host = Cat->GetStringCatInfo(g, "Host", "localhost");
User = Cat->GetStringCatInfo(g, "User", "*");
Pwd = Cat->GetStringCatInfo(g, "Password", NULL);
Picol = Cat->GetStringCatInfo(g, "PivotCol", NULL);
Fncol = Cat->GetStringCatInfo(g, "FncCol", NULL);
Host = GetStringCatInfo(g, "Host", "localhost");
User = GetStringCatInfo(g, "User", "*");
Pwd = GetStringCatInfo(g, "Password", NULL);
Picol = GetStringCatInfo(g, "PivotCol", NULL);
Fncol = GetStringCatInfo(g, "FncCol", NULL);
// If fncol is like avg(colname), separate Fncol and Function
if (Fncol && (p1 = strchr(Fncol, '(')) && (p2 = strchr(p1, ')')) &&
......@@ -270,11 +357,11 @@ bool PIVOTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Function = Fncol;
Fncol = p1;
} else
Function = Cat->GetStringCatInfo(g, "Function", "SUM");
Function = GetStringCatInfo(g, "Function", "SUM");
GBdone = Cat->GetBoolCatInfo("Groupby", false);
Accept = Cat->GetBoolCatInfo("Accept", false);
Port = Cat->GetIntCatInfo("Port", 3306);
GBdone = GetBoolCatInfo("Groupby", false);
Accept = GetBoolCatInfo("Accept", false);
Port = GetIntCatInfo("Port", 3306);
Desc = (Tabsrc) ? Tabsrc : Tabname;
return FALSE;
} // end of DefineAM
......
......@@ -18,12 +18,13 @@ class PIVAID : public CSORT {
friend class SRCCOL;
public:
// Constructor
PIVAID(const char *tab, const char *src, const char *picol,
const char *fncol, const char *host, const char *db,
const char *user, const char *pwd, int port);
PIVAID(const char *tab, const char *src, const char *picol,
const char *fncol, const char *skcol, const char *host,
const char *db, const char *user, const char *pwd, int port);
// Methods
PQRYRES MakePivotColumns(PGLOBAL g);
bool SkipColumn(PCOLRES crp, char *skc);
// The sorting function
virtual int Qcompare(int *, int *);
......@@ -40,6 +41,7 @@ class PIVAID : public CSORT {
char *Tabsrc; // SQL of source table
char *Picol; // Pivot column name
char *Fncol; // Function column name
char *Skcol; // Skipped columns
PVBLK Rblkp; // The value block of the pivot column
int Port; // MySQL port number
}; // end of class PIVAID
......@@ -191,6 +193,6 @@ class SRCCOL : public PRXCOL {
PQRYRES PivotColumns(PGLOBAL g, const char *tab, const char *src,
const char *picol, const char *fncol,
const char *host, const char *db,
const char *user, const char *pwd,
int port);
const char *skcol, const char *host,
const char *db, const char *user,
const char *pwd, int port);
......@@ -76,8 +76,8 @@ bool INIDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
char buf[8];
Fn = Cat->GetStringCatInfo(g, "Filename", NULL);
Cat->GetCharCatInfo("Layout", "C", buf, sizeof(buf));
Fn = GetStringCatInfo(g, "Filename", NULL);
GetCharCatInfo("Layout", "C", buf, sizeof(buf));
Layout = toupper(*buf);
if (Fn) {
......@@ -90,7 +90,7 @@ bool INIDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
return true;
} // endif Fn
Ln = Cat->GetSizeCatInfo("Secsize", "8K");
Ln = GetSizeCatInfo("Secsize", "8K");
Desc = Fn;
return false;
} // end of DefineAM
......
......@@ -111,9 +111,9 @@ bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
char *tablist, *dbname, *def = NULL;
Desc = "Table list table";
tablist = Cat->GetStringCatInfo(g, "Tablist", "");
dbname = Cat->GetStringCatInfo(g, "Dbname", "*");
def = Cat->GetStringCatInfo(g, "Srcdef", NULL);
tablist = GetStringCatInfo(g, "Tablist", "");
dbname = GetStringCatInfo(g, "Dbname", "*");
def = GetStringCatInfo(g, "Srcdef", NULL);
Ntables = 0;
if (*tablist) {
......@@ -155,9 +155,9 @@ bool TBLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
} // endfor pdb
Maxerr = Cat->GetIntCatInfo("Maxerr", 0);
Accept = Cat->GetBoolCatInfo("Accept", false);
Thread = Cat->GetBoolCatInfo("Thread", false);
Maxerr = GetIntCatInfo("Maxerr", 0);
Accept = GetBoolCatInfo("Accept", false);
Thread = GetBoolCatInfo("Thread", false);
} // endif tablist
return FALSE;
......
......@@ -55,6 +55,7 @@
#include "ha_connect.h"
extern "C" int trace;
extern "C" int zconv;
/************************************************************************/
/* Used by MYSQL tables to get MySQL parameters from the calling proxy */
......@@ -129,7 +130,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
FLD_LENGTH, FLD_SCALE, FLD_RADIX, FLD_NULL,
FLD_REM, FLD_NO, FLD_CHARSET};
unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 32, 32};
char *fld, *fmt, v;
char *fld, *colname, *chset, *fmt, v;
int i, n, ncol = sizeof(buftyp) / sizeof(int);
int prec, len, type, scale;
bool mysql;
......@@ -176,21 +177,37 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
/**********************************************************************/
/* Now get the results into blocks. */
/**********************************************************************/
for (i = 0, field= s->field; *field; i++, field++) {
for (i = 0, field= s->field; *field; field++) {
fp= *field;
// Get column name
crp = qrp->Colresp; // Column_Name
fld = (char *)fp->field_name;
crp->Kdata->SetValue(fld, i);
v = 0;
colname = (char *)fp->field_name;
crp->Kdata->SetValue(colname, i);
chset = (char *)fp->charset()->name;
v = (!strcmp(chset, "binary")) ? 'B' : 0;
if ((type = MYSQLtoPLG(fp->type(), &v)) == TYPE_ERROR) {
sprintf(g->Message, "Unsupported column type %s", GetTypeName(type));
if (v == 'K') {
// Skip this column
sprintf(g->Message, "Column %s skipped (unsupported type)", colname);
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
continue;
} // endif v
sprintf(g->Message, "Column %s unsupported type", colname);
qrp = NULL;
break;
} // endif type
if (v == 'X') {
len = zconv;
sprintf(g->Message, "Column %s converted to varchar(%d)",
colname, len);
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
} // endif v
crp = crp->Next; // Data_Type
crp->Kdata->SetValue(type, i);
......@@ -198,11 +215,12 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
crp->Nulls[i] = 'Z';
else if (fp->flags & UNSIGNED_FLAG)
crp->Nulls[i] = 'U';
else
crp->Nulls[i] = v;
else // X means TEXT field
crp->Nulls[i] = (v == 'X') ? 'V' : v;
crp = crp->Next; // Type_Name
crp->Kdata->SetValue(GetTypeName(type), i);
fmt = NULL;
if (type == TYPE_DATE) {
// When creating tables we do need info about date columns
......@@ -214,7 +232,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
prec = len = fp->field_length;
} // endif mysql
} else {
} else if (v != 'X') {
if (type == TYPE_DECIM)
prec = ((Field_new_decimal*)fp)->precision;
else
......@@ -222,8 +240,8 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
// prec = (prec(???) == NOT_FIXED_DEC) ? 0 : fp->field_length;
len = fp->char_length();
fmt = NULL;
} // endif type
} else
prec = len = zconv;
crp = crp->Next; // Precision
crp->Kdata->SetValue(prec, i);
......@@ -259,6 +277,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
// Add this item
qrp->Nblin++;
i++; // Can be skipped
} // endfor field
/**********************************************************************/
......@@ -288,10 +307,10 @@ bool PRXDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
char *pn, *db, *tab, *def = NULL;
db = Cat->GetStringCatInfo(g, "Dbname", "*");
def = Cat->GetStringCatInfo(g, "Srcdef", NULL);
db = GetStringCatInfo(g, "Dbname", "*");
def = GetStringCatInfo(g, "Srcdef", NULL);
if (!(tab = Cat->GetStringCatInfo(g, "Tabname", NULL))) {
if (!(tab = GetStringCatInfo(g, "Tabname", NULL))) {
if (!def) {
strcpy(g->Message, "Missing object table definition");
return TRUE;
......
......@@ -95,13 +95,13 @@ bool VCTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
DOSDEF::DefineAM(g, "BIN", poff);
Estimate = Cat->GetIntCatInfo("Estimate", 0);
Split = Cat->GetIntCatInfo("Split", (Estimate) ? 0 : 1);
Header = Cat->GetIntCatInfo("Header", 0);
Estimate = GetIntCatInfo("Estimate", 0);
Split = GetIntCatInfo("Split", (Estimate) ? 0 : 1);
Header = GetIntCatInfo("Header", 0);
// CONNECT must have Block/Last info for VEC tables
if (Estimate && !Split && !Header) {
char *fn = Cat->GetStringCatInfo(g, "Filename", "?");
char *fn = GetStringCatInfo(g, "Filename", "?");
// No separate header file fo urbi tables
Header = (*fn == '?') ? 3 : 2;
......@@ -112,7 +112,7 @@ bool VCTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
// For packed files the logical record length is calculated in poff
if (poff != Lrecl) {
Lrecl = poff;
Cat->SetIntCatInfo("Lrecl", poff);
SetIntCatInfo("Lrecl", poff);
} // endif poff
Padded = false;
......
......@@ -335,8 +335,8 @@ PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *cls, bool info)
/***********************************************************************/
bool WMIDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
Nspace = Cat->GetStringCatInfo(g, "Namespace", "Root\\CimV2");
Wclass = Cat->GetStringCatInfo(g, "Class",
Nspace = GetStringCatInfo(g, "Namespace", "Root\\CimV2");
Wclass = GetStringCatInfo(g, "Class",
(!stricmp(Nspace, "root\\cimv2") ? "ComputerSystemProduct" :
!stricmp(Nspace, "root\\cli") ? "Msft_CliAlias" : ""));
......@@ -349,7 +349,7 @@ bool WMIDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
} // endif Wclass
if (Catfunc == FNC_NO)
Ems = Cat->GetIntCatInfo("Estimate", 100);
Ems = GetIntCatInfo("Estimate", 100);
return false;
} // end of DefineAM
......
......@@ -78,10 +78,10 @@ bool XCLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
char buf[8];
Xcol = Cat->GetStringCatInfo(g, "Colname", "");
Cat->GetCharCatInfo("Separator", ",", buf, sizeof(buf));
Xcol = GetStringCatInfo(g, "Colname", "");
GetCharCatInfo("Separator", ",", buf, sizeof(buf));
Sep = (strlen(buf) == 2 && buf[0] == '\\' && buf[1] == 't') ? '\t' : *buf;
Mult = Cat->GetIntCatInfo("Mult", 10);
Mult = GetIntCatInfo("Mult", 10);
return PRXDEF::DefineAM(g, am, poff);
} // end of DefineAM
......
......@@ -95,21 +95,21 @@ bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
//void *memp = Cat->GetDescp();
//PSZ dbfile = Cat->GetDescFile();
Fn = Cat->GetStringCatInfo(g, "Filename", NULL);
Encoding = Cat->GetStringCatInfo(g, "Encoding", "UTF-8");
Fn = GetStringCatInfo(g, "Filename", NULL);
Encoding = GetStringCatInfo(g, "Encoding", "UTF-8");
if (*Fn == '?') {
strcpy(g->Message, MSG(MISSING_FNAME));
return true;
} // endif fn
if ((signed)Cat->GetIntCatInfo("Flag", -1) != -1) {
if ((signed)GetIntCatInfo("Flag", -1) != -1) {
strcpy(g->Message, MSG(DEPREC_FLAG));
return true;
} // endif flag
defrow = defcol = "";
Cat->GetCharCatInfo("Coltype", "", buf, sizeof(buf));
GetCharCatInfo("Coltype", "", buf, sizeof(buf));
switch (toupper(*buf)) {
case 'A': // Attribute
......@@ -136,25 +136,25 @@ bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
return true;
} // endswitch typname
Tabname = Cat->GetStringCatInfo(g, "Name", Name); // Deprecated
Tabname = Cat->GetStringCatInfo(g, "Table_name", Tabname); // Deprecated
Tabname = Cat->GetStringCatInfo(g, "Tabname", Tabname);
Rowname = Cat->GetStringCatInfo(g, "Rownode", defrow);
Colname = Cat->GetStringCatInfo(g, "Colnode", defcol);
Mulnode = Cat->GetStringCatInfo(g, "Mulnode", "");
XmlDB = Cat->GetStringCatInfo(g, "XmlDB", "");
Nslist = Cat->GetStringCatInfo(g, "Nslist", "");
DefNs = Cat->GetStringCatInfo(g, "DefNs", "");
Limit = Cat->GetIntCatInfo("Limit", 2);
Xpand = (Cat->GetIntCatInfo("Expand", 0) != 0);
Header = Cat->GetIntCatInfo("Header", 0);
Cat->GetCharCatInfo("Xmlsup", "*", buf, sizeof(buf));
Tabname = GetStringCatInfo(g, "Name", Name); // Deprecated
Tabname = GetStringCatInfo(g, "Table_name", Tabname); // Deprecated
Tabname = GetStringCatInfo(g, "Tabname", Tabname);
Rowname = GetStringCatInfo(g, "Rownode", defrow);
Colname = GetStringCatInfo(g, "Colnode", defcol);
Mulnode = GetStringCatInfo(g, "Mulnode", "");
XmlDB = GetStringCatInfo(g, "XmlDB", "");
Nslist = GetStringCatInfo(g, "Nslist", "");
DefNs = GetStringCatInfo(g, "DefNs", "");
Limit = GetIntCatInfo("Limit", 2);
Xpand = (GetIntCatInfo("Expand", 0) != 0);
Header = GetIntCatInfo("Header", 0);
GetCharCatInfo("Xmlsup", "*", buf, sizeof(buf));
//if (*buf == '*') // Try the old (deprecated) option
// Cat->GetCharCatInfo("Method", "*", buf, sizeof(buf));
// GetCharCatInfo("Method", "*", buf, sizeof(buf));
//if (*buf == '*') // Is there a default for the database?
// Cat->GetCharCatInfo("Defxml", XMLSUP, buf, sizeof(buf));
// GetCharCatInfo("Defxml", XMLSUP, buf, sizeof(buf));
// Note that if no support is specified, the default is MS-DOM
// on Windows and libxml2 otherwise
......@@ -168,8 +168,8 @@ bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Usedom = (toupper(*buf) == 'M' || toupper(*buf) == 'D');
// Get eventual table node attribute
Attrib = Cat->GetStringCatInfo(g, "Attribute", "");
Hdattr = Cat->GetStringCatInfo(g, "HeadAttr", "");
Attrib = GetStringCatInfo(g, "Attribute", "");
Hdattr = GetStringCatInfo(g, "HeadAttr", "");
return false;
} // end of DefineAM
......
......@@ -28,7 +28,7 @@
*/
/****************************************************************************/
/* Author: Olivier Bertrand -- bertrandop@gmail.com -- 2004-2012 */
/* Author: Olivier Bertrand -- bertrandop@gmail.com -- 2004-2014 */
/****************************************************************************/
#ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation
......@@ -48,6 +48,7 @@
#include "mycat.h"
extern "C" int trace;
extern uint worksize;
/****************************************************************************/
/* Initialize the user_connect static member. */
......@@ -94,8 +95,9 @@ bool user_connect::user_init()
PDBUSER dup= NULL;
// Areasize= 64M because of VEC tables. Should be parameterisable
g= PlugInit(NULL, 67108864);
//g= PlugInit(NULL, 67108864);
//g= PlugInit(NULL, 134217728); // 128M was because of old embedded tests
g= PlugInit(NULL, worksize);
// Check whether the initialization is complete
if (!g || !g->Sarea || PlugSubSet(g, g->Sarea, g->Sarea_Size)
......@@ -142,6 +144,20 @@ bool user_connect::CheckCleanup(void)
{
if (thdp->query_id > last_query_id) {
PlugCleanup(g, true);
if (g->Sarea_Size != worksize) {
if (g->Sarea)
free(g->Sarea);
// Check whether the work area size was changed
if (!(g->Sarea = PlugAllocMem(g, worksize))) {
g->Sarea = PlugAllocMem(g, g->Sarea_Size);
worksize = g->Sarea_Size; // Was too big
} else
g->Sarea_Size = worksize; // Ok
} // endif worksize
PlugSubSet(g, g->Sarea, g->Sarea_Size);
g->Xchk = NULL;
g->Createas = 0;
......
......@@ -44,6 +44,7 @@
#define CheckParms(V, N) ChkIndx(N); ChkTyp(V);
extern "C" int trace;
extern MBLOCK Nmblk; /* Used to initialize MBLOCK's */
/***********************************************************************/
/* AllocValBlock: allocate a VALBLK according to type. */
......@@ -105,8 +106,7 @@ PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len,
return NULL;
} // endswitch Type
blkp->Init(g, check);
return blkp;
return (blkp->Init(g, check)) ? NULL : blkp;
} // end of AllocValBlock
/* -------------------------- Class VALBLK --------------------------- */
......@@ -116,6 +116,7 @@ PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len,
/***********************************************************************/
VALBLK::VALBLK(void *mp, int type, int nval, bool un)
{
Mblk = Nmblk;
Blkp = mp;
To_Nulls = NULL;
Check = true;
......@@ -179,6 +180,22 @@ void VALBLK::SetNullable(bool b)
} // end of SetNullable
/***********************************************************************/
/* Buffer allocation routine. */
/***********************************************************************/
bool VALBLK::AllocBuff(PGLOBAL g, size_t size)
{
Mblk.Size = size;
if (!(Blkp = PlgDBalloc(g, NULL, Mblk))) {
sprintf(g->Message, MSG(MEM_ALLOC_ERR), "Blkp", (int) Mblk.Size);
fprintf(stderr, "%s\n", g->Message);
return true;
} // endif Blkp
return false;
} // end of AllocBuff
/***********************************************************************/
/* Check functions. */
/***********************************************************************/
......@@ -229,13 +246,15 @@ TYPBLK<TYPE>::TYPBLK(void *mp, int nval, int type, int prec, bool un)
/* Initialization routine. */
/***********************************************************************/
template <class TYPE>
void TYPBLK<TYPE>::Init(PGLOBAL g, bool check)
bool TYPBLK<TYPE>::Init(PGLOBAL g, bool check)
{
if (!Blkp)
Blkp = PlugSubAlloc(g, NULL, Nval * sizeof(TYPE));
if (AllocBuff(g, Nval * sizeof(TYPE)))
return true;
Check = check;
Global = g;
return false;
} // end of Init
/***********************************************************************/
......@@ -552,7 +571,7 @@ int TYPBLK<TYPE>::GetMaxLength(void)
for (i = n = 0; i < Nval; i++) {
m = sprintf(buf, Fmt, Typp[i]);
n = max(n, m);
n = MY_MAX(n, m);
} // endfor i
return n;
......@@ -576,16 +595,18 @@ CHRBLK::CHRBLK(void *mp, int nval, int len, int prec, bool blank)
/***********************************************************************/
/* Initialization routine. */
/***********************************************************************/
void CHRBLK::Init(PGLOBAL g, bool check)
bool CHRBLK::Init(PGLOBAL g, bool check)
{
Valp = (char*)PlugSubAlloc(g, NULL, Long + 1);
Valp[Long] = '\0';
if (!Blkp)
Blkp = PlugSubAlloc(g, NULL, Nval * Long);
if (AllocBuff(g, Nval * Long))
return true;
Check = check;
Global = g;
return false;
} // end of Init
/***********************************************************************/
......@@ -747,7 +768,7 @@ void CHRBLK::SetValue(char *sp, uint len, int n)
#endif // _DEBUG
if (sp)
memcpy(p, sp, min((unsigned)Long, len));
memcpy(p, sp, MY_MIN((unsigned)Long, len));
if (Blanks) {
// Suppress eventual ending zero and right fill with blanks
......@@ -913,7 +934,7 @@ int CHRBLK::GetMaxLength(void)
for (i = n = 0; i < Nval; i++)
if (!IsNull(i)) {
GetValPtrEx(i);
n = max(n, (signed)strlen(Valp));
n = MY_MAX(n, (signed)strlen(Valp));
} // endif null
return n;
......@@ -936,13 +957,15 @@ STRBLK::STRBLK(PGLOBAL g, void *mp, int nval)
/***********************************************************************/
/* Initialization routine. */
/***********************************************************************/
void STRBLK::Init(PGLOBAL g, bool check)
bool STRBLK::Init(PGLOBAL g, bool check)
{
if (!Blkp)
Blkp = PlugSubAlloc(g, NULL, Nval * sizeof(PSZ));
if (AllocBuff(g, Nval * sizeof(PSZ)))
return true;
Check = check;
Global = g;
return false;
} // end of Init
/***********************************************************************/
......@@ -1185,7 +1208,7 @@ int STRBLK::GetMaxLength(void)
for (i = n = 0; i < Nval; i++)
if (Strp[i])
n = max(n, (signed)strlen(Strp[i]));
n = MY_MAX(n, (signed)strlen(Strp[i]));
return n;
} // end of GetMaxLength
......
......@@ -45,7 +45,7 @@ class VALBLK : public BLOCK {
virtual bool IsNull(int n) {return To_Nulls && To_Nulls[n];}
virtual void SetNullable(bool b);
virtual bool IsUnsigned(void) {return Unsigned;}
virtual void Init(PGLOBAL g, bool check) = 0;
virtual bool Init(PGLOBAL g, bool check) = 0;
virtual int GetVlen(void) = 0;
virtual PSZ GetCharValue(int n);
virtual char GetTinyValue(int n) = 0;
......@@ -88,12 +88,14 @@ class VALBLK : public BLOCK {
bool Locate(PVAL vp, int& i);
protected:
bool AllocBuff(PGLOBAL g, size_t size);
void ChkIndx(int n);
void ChkTyp(PVAL v);
void ChkTyp(PVBLK vb);
// Members
PGLOBAL Global; // Used for messages and allocation
MBLOCK Mblk; // Used to allocate buffer
char *To_Nulls; // Null values array
void *Blkp; // To value block
bool Check; // If true SetValue types must match
......@@ -114,7 +116,7 @@ class TYPBLK : public VALBLK {
TYPBLK(void *mp, int size, int type, int prec = 0, bool un = false);
// Implementation
virtual void Init(PGLOBAL g, bool check);
virtual bool Init(PGLOBAL g, bool check);
virtual int GetVlen(void) {return sizeof(TYPE);}
virtual char GetTinyValue(int n) {return (char)Typp[n];}
virtual uchar GetUTinyValue(int n) {return (uchar)Typp[n];}
......@@ -179,7 +181,7 @@ class CHRBLK : public VALBLK {
CHRBLK(void *mp, int size, int len, int prec, bool b);
// Implementation
virtual void Init(PGLOBAL g, bool check);
virtual bool Init(PGLOBAL g, bool check);
virtual int GetVlen(void) {return Long;}
virtual PSZ GetCharValue(int n);
virtual char GetTinyValue(int n);
......@@ -211,11 +213,11 @@ class CHRBLK : public VALBLK {
protected:
// Members
char* const &Chrp; // Pointer to char buffer
PSZ Valp; // Used to make a zero ended value
bool Blanks; // True for right filling with blanks
bool Ci; // True if case insensitive
int Long; // Length of each string
char* const &Chrp; // Pointer to char buffer
PSZ Valp; // Used to make a zero ended value
bool Blanks; // True for right filling with blanks
bool Ci; // True if case insensitive
int Long; // Length of each string
}; // end of class CHRBLK
/***********************************************************************/
......@@ -232,7 +234,7 @@ class STRBLK : public VALBLK {
virtual void SetNull(int n, bool b) {if (b) {Strp[n] = NULL;}}
virtual bool IsNull(int n) {return Strp[n] == NULL;}
virtual void SetNullable(bool b) {} // Always nullable
virtual void Init(PGLOBAL g, bool check);
virtual bool Init(PGLOBAL g, bool check);
virtual int GetVlen(void) {return sizeof(PSZ);}
virtual PSZ GetCharValue(int n) {return Strp[n];}
virtual char GetTinyValue(int n);
......
This diff is collapsed.
/**************** Value H Declares Source Code File (.H) ***************/
/* Name: VALUE.H Version 2.0 */
/* Name: VALUE.H Version 2.1 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2001-2013 */
/* (C) Copyright to the author Olivier BERTRAND 2001-2014 */
/* */
/* This file contains the VALUE and derived classes declares. */
/***********************************************************************/
......@@ -276,6 +276,62 @@ class DllExport DECVAL: public TYPVAL<PSZ> {
// Members
}; // end of class DECVAL
/***********************************************************************/
/* Specific BINARY class. */
/***********************************************************************/
class DllExport BINVAL: public VALUE {
public:
// Constructors
//BINVAL(void *p);
BINVAL(PGLOBAL g, void *p, int cl, int n);
// Implementation
virtual bool IsTypeNum(void) {return false;}
virtual bool IsZero(void);
virtual void Reset(void);
virtual int GetValLen(void) {return Clen;};
virtual int GetValPrec() {return 0;}
virtual int GetSize(void) {return Len;}
virtual PSZ GetCharValue(void) {return (PSZ)Binp;}
virtual char GetTinyValue(void);
virtual uchar GetUTinyValue(void);
virtual short GetShortValue(void);
virtual ushort GetUShortValue(void);
virtual int GetIntValue(void);
virtual uint GetUIntValue(void);
virtual longlong GetBigintValue(void);
virtual ulonglong GetUBigintValue(void);
virtual double GetFloatValue(void);
virtual void *GetTo_Val(void) {return Binp;}
// Methods
virtual bool SetValue_pval(PVAL valp, bool chktype);
virtual bool SetValue_char(char *p, int n);
virtual void SetValue_psz(PSZ s);
virtual void SetValue_pvblk(PVBLK blk, int n);
virtual void SetValue(char c);
virtual void SetValue(uchar c);
virtual void SetValue(short i);
virtual void SetValue(ushort i);
virtual void SetValue(int n);
virtual void SetValue(uint n);
virtual void SetValue(longlong n);
virtual void SetValue(ulonglong n);
virtual void SetValue(double f);
virtual void SetBinValue(void *p);
virtual bool GetBinValue(void *buf, int buflen, bool go);
virtual char *ShowValue(char *buf, int);
virtual char *GetCharString(char *p);
virtual bool IsEqual(PVAL vp, bool chktype);
virtual bool FormatValue(PVAL vp, char *fmt);
virtual bool SetConstFormat(PGLOBAL, FORMAT&);
// Members
void *Binp;
char *Chrp;
int Len;
}; // end of class BINVAL
/***********************************************************************/
/* Class DTVAL: represents a time stamp value. */
/***********************************************************************/
......
This diff is collapsed.
This diff is collapsed.
......@@ -107,6 +107,7 @@ class DllExport TDB: public BLOCK { // Table Descriptor Block.
virtual int DeleteDB(PGLOBAL, int) = 0;
virtual void CloseDB(PGLOBAL) = 0;
virtual int CheckWrite(PGLOBAL g) {return 0;}
virtual bool ReadKey(PGLOBAL, OPVAL, const void *, int) = 0;
protected:
// Members
......@@ -176,6 +177,11 @@ class DllExport TDBASE : public TDB {
virtual PCOL InsertSpecialColumn(PGLOBAL g, PCOL colp);
virtual PCOL InsertSpcBlk(PGLOBAL g, PCOLDEF cdp);
virtual void MarkDB(PGLOBAL g, PTDB tdb2);
virtual int MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
{strcpy(g->Message, "Remote index"); return RC_INFO;}
virtual bool ReadKey(PGLOBAL g, OPVAL op, const void *key, int len)
{assert(false); return true;}
protected:
// Members
......
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