Commit 18fc51f5 authored by Alexander Barkov's avatar Alexander Barkov

Merge with 10.0-connect

parents 51e28066 0993d4b4
......@@ -350,8 +350,7 @@ TIDBLK::TIDBLK(PCOLUMN cp) : SPCBLK(cp)
*Format.Type = 'C';
Format.Length = Long;
Format.Prec = 1; // Case insensitive
Constant = (To_Tdb->GetAmType() != TYPE_AM_PLG &&
To_Tdb->GetAmType() != TYPE_AM_PLM);
Constant = (To_Tdb->GetAmType() != TYPE_AM_TBL);
Tname = NULL;
} // end of TIDBLK constructor
......@@ -367,3 +366,30 @@ void TIDBLK::ReadColumn(PGLOBAL g)
} // end of ReadColumn
/***********************************************************************/
/* SIDBLK constructor for the SERVID special column. */
/***********************************************************************/
SIDBLK::SIDBLK(PCOLUMN cp) : SPCBLK(cp)
{
//Is_Key = 2; for when the MUL table indexed reading will be implemented.
Long = 64;
Buf_Type = TYPE_STRING;
*Format.Type = 'C';
Format.Length = Long;
Format.Prec = 1; // Case insensitive
Constant = (To_Tdb->GetAmType() != TYPE_AM_TBL);
Sname = NULL;
} // end of TIDBLK constructor
/***********************************************************************/
/* ReadColumn: what this routine does is to return the server ID. */
/***********************************************************************/
void SIDBLK::ReadColumn(PGLOBAL g)
{
//if (Sname == NULL) {
Sname = (char*)To_Tdb->GetServer();
Value->SetValue_psz(Sname);
// } // endif Sname
} // end of ReadColumn
......@@ -62,7 +62,7 @@ class DllExport COLBLK : public XOBJECT {
virtual bool SetFormat(PGLOBAL, FORMAT&);
virtual int CheckColumn(PGLOBAL g, PSQL sqlp, PXOB &xp, int &ag);
virtual bool IsSpecial(void) {return false;}
virtual int CheckSpcCol(PTDB tdbp, int n) {return 2;}
virtual int CheckSpcCol(PTDB tdbp, int n) {return 2;}
virtual bool CheckSort(PTDB tdbp);
virtual bool Eval(PGLOBAL g);
virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check);
......@@ -168,7 +168,7 @@ class TIDBLK : public SPCBLK {
// Methods
virtual void Reset(void) {} // This is a pseudo constant column
virtual int CheckSpcCol(PTDB tdbp, int n)
{return (n == 3 && tdbp == To_Tdb) ? 1 : 2;}
{return (n == 3 && tdbp == To_Tdb) ? 1 : 2;}
virtual void ReadColumn(PGLOBAL g);
protected:
......@@ -179,4 +179,29 @@ class TIDBLK : public SPCBLK {
PSZ Tname; // The current table name
}; // end of class TIDBLK
/***********************************************************************/
/* Class SIDBLK: SERVID special column descriptor. */
/***********************************************************************/
class SIDBLK : public SPCBLK {
public:
// Constructor
SIDBLK(PCOLUMN cp);
// Implementation
virtual int GetAmType(void) {return TYPE_AM_SRVID;}
// Methods
virtual void Reset(void) {} // This is a pseudo constant column
virtual int CheckSpcCol(PTDB tdbp, int n)
{return (n == 3 && tdbp == To_Tdb) ? 1 : 2;}
virtual void ReadColumn(PGLOBAL g);
protected:
// Default constructor not to be used
SIDBLK(void) {}
// Members
PSZ Sname; // The current server name
}; // end of class SIDBLK
#endif // __COLBLK__H
......@@ -239,7 +239,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
char *p;
int i, n;
PCOL colp;
PCOLUMN cp;
//PCOLUMN cp;
PDBUSER dup= PlgGetUser(g);
if (xtrace)
......@@ -251,6 +251,8 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
return true;
} // endif tdbp
tdbp->SetMode(mode);
if (!c1) {
if (mode == MODE_INSERT)
// Allocate all column blocks for that table
......@@ -261,12 +263,12 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
if (xtrace)
printf("Allocating column %s\n", p);
if (*p == '*') {
// This is a special column
cp= new(g) COLUMN(p + 1);
cp->SetTo_Table(tdbp->GetTable());
colp= ((PTDBASE)tdbp)->InsertSpcBlk(g, cp);
} else
// if (*p == '*') {
// // This is a special column
// cp= new(g) COLUMN(p + 1);
// cp->SetTo_Table(tdbp->GetTable());
// colp= ((PTDBASE)tdbp)->InsertSpcBlk(g, cp);
// } else
colp= tdbp->ColDB(g, p, 0);
if (!colp) {
......@@ -330,7 +332,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
printf("Opening table %s in mode %d tdbp=%p\n",
tdbp->GetName(), mode, tdbp);
tdbp->SetMode(mode);
//tdbp->SetMode(mode);
if (del && ((PTDBASE)tdbp)->GetFtype() != RECFM_NAF) {
// To avoid erasing the table when doing a partial delete
......
......@@ -47,20 +47,9 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
PGLOBAL CntExit(PGLOBAL g);
/***********************************************************************/
/* Definition of classes XCOLCRT, XIXDEF, XKPDEF, DOXDEF, TDBDOX */
/* Definition of classes XKPDEF, DOXDEF, TDBDOX */
/* These classes purpose is chiefly to access protected items! */
/***********************************************************************/
class XCOLCRT: public COLCRT {
friend class ha_connect;
friend bool CntCreateTable(PGLOBAL, char *, PCXF);
public:
XCOLCRT(PSZ name) : COLCRT(name) {Nulls= -1;} // Constructor
bool HasNulls(void) {return (Nulls != 0);}
private:
int Nulls;
}; // end of class XCOLCRT
class DOXDEF: public DOSDEF {
//friend class TDBDOX;
//friend int MakeIndex(PGLOBAL, PTDB, PIXDEF);
......@@ -87,11 +76,7 @@ class XKPDEF: public KPARTDEF {
//friend int CntMakeIndex(PGLOBAL, const char *, PIXDEF);
friend int CntIndexInit(PGLOBAL, PTDB, int);
public:
XKPDEF(const char *name, int n) : KPARTDEF((PSZ)name, n) {HasNulls= false;}
void SetNulls(bool b) {HasNulls= b;}
protected:
bool HasNulls; /* Can have null values */
XKPDEF(const char *name, int n) : KPARTDEF((PSZ)name, n) {}
}; // end of class XKPDEF
//RCODE CheckRecord(PGLOBAL g, PTDB tdbp, char *oldbuf, char *newbuf);
This diff is collapsed.
......@@ -167,9 +167,9 @@ class ha_connect: public handler
PIXDEF GetIndexInfo(void);
const char *GetDBName(const char *name);
const char *GetTableName(void);
int GetColNameLen(Field *fp);
char *GetColName(Field *fp);
void AddColName(char *cp, Field *fp);
//int GetColNameLen(Field *fp);
//char *GetColName(Field *fp);
//void AddColName(char *cp, Field *fp);
TABLE *GetTable(void) {return table;}
bool IsSameIndex(PIXDEF xp1, PIXDEF xp2);
......@@ -208,7 +208,7 @@ class ha_connect: public handler
return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_HAS_RECORDS |
HA_NO_AUTO_INCREMENT | HA_NO_PREFIX_CHAR_KEYS |
HA_NO_COPY_ON_ALTER | HA_CAN_VIRTUAL_COLUMNS |
HA_NULL_IN_KEY | HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE);
/*HA_NULL_IN_KEY |*/ HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE);
}
/** @brief
......@@ -319,6 +319,21 @@ const char *GetValStr(OPVAL vop, bool neg);
*/
virtual ha_rows records();
/**
Type of table for caching query
CONNECT should not use caching because its tables are external
data prone to me modified out of MariaDB
*/
virtual uint8 table_cache_type(void)
{
#if defined(MEMORY_TRACE)
// Temporary until bug MDEV-4771 is fixed
return HA_CACHE_TBL_NONTRANSACT;
#else
return HA_CACHE_TBL_NOCACHE;
#endif
}
/** @brief
We implement this in ha_connect.cc; it's a required method.
*/
......@@ -400,6 +415,7 @@ const char *GetValStr(OPVAL vop, bool neg);
void position(const uchar *record); ///< required
int info(uint); ///< required
int extra(enum ha_extra_function operation);
int start_stmt(THD *thd, thr_lock_type lock_type);
int external_lock(THD *thd, int lock_type); ///< required
int delete_all_rows(void);
ha_rows records_in_range(uint inx, key_range *min_key,
......@@ -429,6 +445,7 @@ const char *GetValStr(OPVAL vop, bool neg);
protected:
bool check_privileges(THD *thd, PTOS options);
MODE CheckMode(PGLOBAL g, THD *thd, MODE newmode, bool *chk, bool *cras);
// Members
static ulong num; // Tracable handler number
......@@ -446,6 +463,7 @@ const char *GetValStr(OPVAL vop, bool neg);
bool valid_info; // True if xinfo is valid
bool stop; // Used when creating index
int indexing; // Type of indexing for CONNECT
int locked; // Table lock
THR_LOCK_DATA lock_data;
public:
......
......@@ -315,4 +315,4 @@ bool MACINFO::GetOneInfo(PGLOBAL g, int flag, void *v, int lv)
*((int*)v) = n;
return false;
} // end of ReadColumn
} // end of GetOneInfo
......@@ -468,9 +468,9 @@ int MYCAT::GetColCatInfo(PGLOBAL g, PTABDEF defp)
break;
} // endswitch tc
do {
// do {
field= Hc->GetColumnOption(g, field, pcf);
} while (field && (*pcf->Name =='*' /*|| pcf->Flags & U_VIRTUAL*/));
// } while (field && (*pcf->Name =='*' /*|| pcf->Flags & U_VIRTUAL*/));
if (tc == TAB_DBF && pcf->Type == TYPE_DATE && !pcf->Datefmt) {
// DBF date format defaults to 'YYYMMDD'
......
......@@ -134,7 +134,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
/* Allocate the structures used to refer to the result set. */
/**********************************************************************/
qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
buftyp, fldtyp, length, true, true);
buftyp, fldtyp, length, false, true);
// Some columns must be renamed
for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next)
......
......@@ -30,10 +30,12 @@ t2 CREATE TABLE `t2` (
SELECT * FROM t2;
ERROR HY000: Got error 174 '(1054) Unknown column 'x' in 'field list' [SELECT `x`, `y` FROM `t1`]' from CONNECT
DROP TABLE t2;
CREATE TABLE t2 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=PORT';
ALTER TABLE t1 RENAME t1backup;
SELECT * FROM t2;
ERROR 42S02: Table 'test.t2' doesn't exist
ERROR HY000: Got error 174 '(1146) Table 'test.t1' doesn't exist [SELECT `a`, `b` FROM `t1`]' from CONNECT
ALTER TABLE t1backup RENAME t1;
DROP TABLE t2;
#
# Testing SELECT, etc.
#
......
......@@ -78,6 +78,8 @@ 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';
Warnings:
Warning 1105 Cannot check looping reference
ALTER TABLE pivex OPTION_LIST='PivotCol=what,FncCol=amount,port=PORT';
Warnings:
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
......@@ -125,6 +127,8 @@ 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';
Warnings:
Warning 1105 Cannot check looping reference
ALTER TABLE pivex OPTION_LIST='PivotCol=wk,FncCol=amnt,port=PORT';
Warnings:
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
......
......@@ -413,7 +413,7 @@ DROP TABLE t1;
SET @a=LOAD_FILE('MYSQLD_DATADIR/test/t1.xml');
SELECT CAST(@a AS CHAR CHARACTER SET latin1);
CAST(@a AS CHAR CHARACTER SET latin1) <?xml version="1.0" encoding="iso-8859-1"?>
<!-- Created by CONNECT Version 1.01.0006 Mai 21, 2013 -->
<!-- Created by CONNECT Version 1.01.0007 July 26, 2013 -->
<t1>
<line>
<node>ÀÁÂÃ</node>
......
This diff is collapsed.
......@@ -151,7 +151,8 @@ enum ALGMOD {AMOD_AUTO = 0, /* PLG chooses best algorithm */
#define NAM_LEN 128
#endif // !0
enum MODE {MODE_ANY = 0, /* Unspecified mode */
enum MODE {MODE_ERROR = -1, /* Invalid mode */
MODE_ANY = 0, /* Unspecified mode */
MODE_READ = 10, /* Input/Output mode */
MODE_WRITE = 20, /* Input/Output mode */
MODE_UPDATE = 30, /* Input/Output mode */
......@@ -319,7 +320,8 @@ enum COLUSE {U_P = 0x01, /* the projection list. */
U_VAR = 0x10, /* a VARCHAR column */
U_VIRTUAL = 0x20, /* a VIRTUAL column */
U_NULLS = 0x40, /* The column may have nulls */
U_IS_NULL = 0x80}; /* The column has a null value */
U_IS_NULL = 0x80, /* The column has a null value */
U_SPECIAL = 0x100}; /* The column is special */
/***********************************************************************/
/* DB description class and block pointer definitions. */
......
......@@ -383,32 +383,35 @@ int COLDEF::Define(PGLOBAL g, void *memp, PCOLINFO cfp, int poff)
Name = (PSZ)PlugSubAlloc(g, memp, strlen(cfp->Name) + 1);
strcpy(Name, cfp->Name);
Poff = poff;
Buf_Type = cfp->Type;
if ((Clen = GetTypeSize(Buf_Type, cfp->Length)) <= 0) {
sprintf(g->Message, MSG(BAD_COL_TYPE), GetTypeName(Buf_Type), Name);
return -1;
} // endswitch
strcpy(F.Type, GetFormatType(Buf_Type));
F.Length = cfp->Length;
F.Prec = cfp->Prec;
Offset = (cfp->Offset < 0) ? poff : cfp->Offset;
Long = cfp->Length;
Opt = cfp->Opt;
Key = cfp->Key;
//Freq = cfp->Freq;
if (cfp->Remark && *cfp->Remark) {
Desc = (PSZ)PlugSubAlloc(g, memp, strlen(cfp->Remark) + 1);
strcpy(Desc, cfp->Remark);
} // endif Remark
if (cfp->Datefmt) {
Decode = (PSZ)PlugSubAlloc(g, memp, strlen(cfp->Datefmt) + 1);
strcpy(Decode, cfp->Datefmt);
} // endif Datefmt
if (!(cfp->Flags & U_SPECIAL)) {
Poff = poff;
Buf_Type = cfp->Type;
if ((Clen = GetTypeSize(Buf_Type, cfp->Length)) <= 0) {
sprintf(g->Message, MSG(BAD_COL_TYPE), GetTypeName(Buf_Type), Name);
return -1;
} // endswitch
strcpy(F.Type, GetFormatType(Buf_Type));
F.Length = cfp->Length;
F.Prec = cfp->Prec;
Offset = (cfp->Offset < 0) ? poff : cfp->Offset;
Long = cfp->Length;
Opt = cfp->Opt;
Key = cfp->Key;
// Freq = cfp->Freq;
if (cfp->Remark && *cfp->Remark) {
Desc = (PSZ)PlugSubAlloc(g, memp, strlen(cfp->Remark) + 1);
strcpy(Desc, cfp->Remark);
} // endif Remark
if (cfp->Datefmt) {
Decode = (PSZ)PlugSubAlloc(g, memp, strlen(cfp->Datefmt) + 1);
strcpy(Decode, cfp->Datefmt);
} // endif Datefmt
} // endif special
if (cfp->Fieldfmt) {
Fmt = (PSZ)PlugSubAlloc(g, memp, strlen(cfp->Fieldfmt) + 1);
......@@ -416,7 +419,7 @@ int COLDEF::Define(PGLOBAL g, void *memp, PCOLINFO cfp, int poff)
} // endif Fieldfmt
Flags = cfp->Flags;
return (Flags & U_VIRTUAL) ? 0 : Long;
return (Flags & (U_VIRTUAL|U_SPECIAL)) ? 0 : Long;
} // end of Define
/* ------------------------- End of RelDef --------------------------- */
......@@ -175,6 +175,7 @@ class DllExport COLDEF : public COLCRT { /* Column description block
friend class MYCAT;
friend class COLBLK;
friend class DBFFAM;
friend class TDBASE;
public:
COLDEF(void); // Constructor
......
......@@ -339,7 +339,7 @@ PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q,
/* Allocate the structures used to refer to the result set. */
/*********************************************************************/
qrp = PlgAllocResult(g, ncol, imax, IDS_COLUMNS + 3,
buftyp, fldtyp, length, true, false);
buftyp, fldtyp, length, false, false);
qrp->Nblin = imax;
if (info)
......
......@@ -307,15 +307,17 @@ PCOL TDBASE::ColDB(PGLOBAL g, PSZ name, int num)
/*****************************************************************/
if (cp)
colp = cp;
else
else if (!(cdp->Flags & U_SPECIAL))
colp = MakeCol(g, cdp, cprec, i);
else if (Mode == MODE_READ)
colp = InsertSpcBlk(g, cdp);
if (trace)
htrc("colp=%p\n", colp);
if (name || num)
break;
else if (colp)
else if (colp && !colp->IsSpecial())
cprec = colp;
} // endif Name
......@@ -339,30 +341,35 @@ PCOL TDBASE::InsertSpecialColumn(PGLOBAL g, PCOL colp)
/***********************************************************************/
/* Make a special COLBLK to insert in a table. */
/***********************************************************************/
PCOL TDBASE::InsertSpcBlk(PGLOBAL g, PCOLUMN cp)
PCOL TDBASE::InsertSpcBlk(PGLOBAL g, PCOLDEF cdp)
{
char *name = (char*)cp->GetName();
PCOL colp;
//char *name = cdp->GetName();
char *name = cdp->GetFmt();
PCOLUMN cp;
PCOL colp;
if (!strcmp(name, "FILEID")) {
// !strcmp(name, "SERVID")) {
cp= new(g) COLUMN(cdp->GetName());
cp->SetTo_Table(To_Table);
if (!stricmp(name, "FILEID") ||
!stricmp(name, "SERVID")) {
if (!To_Def || !(To_Def->GetPseudo() & 2)) {
sprintf(g->Message, MSG(BAD_SPEC_COLUMN));
return NULL;
} // endif Pseudo
// if (!strcmp(name, "FILEID"))
if (!stricmp(name, "FILEID"))
colp = new(g) FIDBLK(cp);
// else
// colp = new(g) SIDBLK(cp);
else
colp = new(g) SIDBLK(cp);
} else if (!strcmp(name, "TABID")) {
} else if (!stricmp(name, "TABID")) {
colp = new(g) TIDBLK(cp);
//} else if (!strcmp(name, "CONID")) {
//} else if (!stricmp(name, "CONID")) {
// colp = new(g) CIDBLK(cp);
} else if (!strcmp(name, "ROWID")) {
} else if (!stricmp(name, "ROWID")) {
colp = new(g) RIDBLK(cp, false);
} else if (!strcmp(name, "ROWNUM")) {
} else if (!stricmp(name, "ROWNUM")) {
colp = new(g) RIDBLK(cp, true);
} else {
sprintf(g->Message, MSG(BAD_SPECIAL_COL), name);
......
......@@ -194,6 +194,7 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url)
if (trace)
htrc("server: %s Tabname: %s", url, Tabname);
Server = url;
return GetServerInfo(g, url);
} else {
// URL, parse it
......@@ -216,8 +217,10 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url)
if (!(Hostname = strchr(Username, '@'))) {
strcpy(g->Message, "No host specified in URL");
return true;
} else
} else {
*Hostname++ = 0; // End Username
Server = Hostname;
} // endif Hostname
if ((Password = strchr(Username, ':'))) {
*Password++ = 0; // End username
......@@ -308,6 +311,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Username = Cat->GetStringCatInfo(g, "User", "*");
Password = Cat->GetStringCatInfo(g, "Password", NULL);
Portnumber = Cat->GetIntCatInfo("Port", GetDefaultPort());
Server = Hostname;
} else if (ParseURL(g, url))
return TRUE;
......@@ -327,6 +331,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Username = Cat->GetStringCatInfo(g, "User", "*");
Password = Cat->GetStringCatInfo(g, "Password", NULL);
Portnumber = Cat->GetIntCatInfo("Port", GetDefaultPort());
Server = Hostname;
} else {
char *locdb = Database;
......@@ -365,13 +370,14 @@ PTDB MYSQLDEF::GetTable(PGLOBAL g, MODE m)
TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp)
{
if (tdp) {
Host = tdp->GetHostname();
Database = tdp->GetDatabase();
Tabname = tdp->GetTabname();
Srcdef = tdp->GetSrcdef();
User = tdp->GetUsername();
Pwd = tdp->GetPassword();
Port = tdp->GetPortnumber();
Host = tdp->Hostname;
Database = tdp->Database;
Tabname = tdp->Tabname;
Srcdef = tdp->Srcdef;
User = tdp->Username;
Pwd = tdp->Password;
Server = tdp->Server;
Port = tdp->Portnumber;
Isview = tdp->Isview;
Prep = tdp->Bind;
Delayed = tdp->Delayed;
......@@ -382,6 +388,7 @@ TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp)
Srcdef = NULL;
User = NULL;
Pwd = NULL;
Server = NULL;
Port = 0;
Isview = FALSE;
Prep = FALSE;
......@@ -473,10 +480,11 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g)
if (Columns) {
for (colp = Columns; colp; colp = colp->GetNext())
if (colp->IsSpecial()) {
strcpy(g->Message, MSG(NO_SPEC_COL));
return TRUE;
} else {
if (!colp->IsSpecial()) {
// if (colp->IsSpecial()) {
// strcpy(g->Message, MSG(NO_SPEC_COL));
// return TRUE;
// } else {
if (b)
strcat(Query, ", ");
else
......@@ -519,10 +527,11 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
return FALSE; // already done
for (colp = Columns; colp; colp = colp->GetNext())
if (colp->IsSpecial()) {
strcpy(g->Message, MSG(NO_SPEC_COL));
return TRUE;
} else {
if (!colp->IsSpecial()) {
// if (colp->IsSpecial()) {
// strcpy(g->Message, MSG(NO_SPEC_COL));
// return TRUE;
// } else {
len += (strlen(colp->GetName()) + 4);
((PMYCOL)colp)->Rank = Nparm++;
} // endif colp
......@@ -1232,7 +1241,7 @@ void MYSQLCOL::ReadColumn(PGLOBAL g)
if (trace)
htrc("MySQL ReadColumn: name=%s buf=%s\n", Name, buf);
Value->SetValue_char(buf, Long);
Value->SetValue_char(buf, min((unsigned)Long, strlen(buf)));
} else {
if (Nullable)
Value->SetNull(true);
......
......@@ -49,6 +49,7 @@ class MYSQLDEF : public TABDEF {/* Logical table description */
PSZ Srcdef; /* The source table SQL definition */
PSZ Username; /* User logon name */
PSZ Password; /* Password logon info */
PSZ Server; /* PServerID */
int Portnumber; /* MySQL port number (0 = default) */
bool Isview; /* TRUE if this table is a MySQL view */
bool Bind; /* Use prepared statement on insert */
......@@ -77,6 +78,7 @@ class TDBMYSQL : public TDBASE {
virtual void ResetDB(void) {N = 0;}
virtual int RowNumber(PGLOBAL g, bool b = FALSE);
virtual bool IsView(void) {return Isview;}
virtual PSZ GetServer(void) {return Server;}
void SetDatabase(LPCSTR db) {Database = (char*)db;}
// Database routines
......@@ -110,6 +112,7 @@ class TDBMYSQL : public TDBASE {
char *Database; // Database to be used by server
char *Tabname; // External table name
char *Srcdef; // The source table SQL definition
char *Server; // The server ID
char *Query; // Points to SQL query
char *Qbuf; // Used for not prepared insert
bool Fetched; // True when fetch was done
......
......@@ -71,10 +71,11 @@ class TDBODBC : public TDBASE {
// Methods
virtual PTDB CopyOne(PTABS t);
virtual int GetRecpos(void);
virtual PSZ GetFile(PGLOBAL g);
virtual PSZ GetFile(PGLOBAL g);
virtual void SetFile(PGLOBAL g, PSZ fn);
virtual void ResetSize(void);
virtual int GetAffectedRows(void) {return AftRows;}
virtual PSZ GetServer(void) {return "ODBC";}
// Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
......
......@@ -36,7 +36,9 @@
#include "global.h"
#include "plgdbsem.h"
#include "reldef.h"
//#include "xobject.h"
#if !defined(WIN32)
#include "osutil.h"
#endif // !WIN32
#include "filamtxt.h"
#include "tabdos.h"
#include "tabsys.h"
......@@ -320,7 +322,11 @@ int TDBINI::DeleteDB(PGLOBAL g, int irc)
break;
case RC_FX:
while (ReadDB(g) == RC_OK)
WritePrivateProfileString(Section, NULL, NULL, Ifile);
if (!WritePrivateProfileString(Section, NULL, NULL, Ifile)) {
sprintf(g->Message, "Error %d accessing %s",
GetLastError(), Ifile);
return RC_FX;
} // endif
break;
default:
......@@ -328,7 +334,11 @@ int TDBINI::DeleteDB(PGLOBAL g, int irc)
strcpy(g->Message, MSG(NO_SECTION_NAME));
return RC_FX;
} else
WritePrivateProfileString(Section, NULL, NULL, Ifile);
if (!WritePrivateProfileString(Section, NULL, NULL, Ifile)) {
sprintf(g->Message, "Error %d accessing %s",
GetLastError(), Ifile);
return RC_FX;
} // endif rc
} // endswitch irc
......@@ -461,13 +471,13 @@ void INICOL::ReadColumn(PGLOBAL g)
Valbuf[Long] = '\0';
break;
default:
GetPrivateProfileString(tdbp->Section, Name, "",
GetPrivateProfileString(tdbp->Section, Name, "\b",
Valbuf, Long + 1, tdbp->Ifile);
break;
} // endswitch Flag
// Missing keys are interpreted as null values
if (!strcmp(Valbuf, "")) {
if (!strcmp(Valbuf, "\b")) {
if (Nullable)
Value->SetNull(true);
......@@ -485,6 +495,7 @@ void INICOL::ReadColumn(PGLOBAL g)
void INICOL::WriteColumn(PGLOBAL g)
{
char *p;
bool rc;
PTDBINI tdbp = (PTDBINI)To_Tdb;
if (trace > 1)
......@@ -510,11 +521,12 @@ void INICOL::WriteColumn(PGLOBAL g)
if (tdbp->Mode == MODE_UPDATE) {
strcpy(g->Message, MSG(NO_SEC_UPDATE));
longjmp(g->jumper[g->jump_level], 31);
} else {
} else if (*p) {
tdbp->Section = p;
return;
} // endif Mode
} else
tdbp->Section = NULL;
return;
} else if (!tdbp->Section) {
strcpy(g->Message, MSG(SEC_NAME_FIRST));
longjmp(g->jumper[g->jump_level], 31);
......@@ -523,8 +535,16 @@ void INICOL::WriteColumn(PGLOBAL g)
/*********************************************************************/
/* Updating must be done only when not in checking pass. */
/*********************************************************************/
if (Status)
WritePrivateProfileString(tdbp->Section, Name, p, tdbp->Ifile);
if (Status) {
rc = WritePrivateProfileString(tdbp->Section, Name, p, tdbp->Ifile);
if (!rc) {
sprintf(g->Message, "Error %d writing to %s",
GetLastError(), tdbp->Ifile);
longjmp(g->jumper[g->jump_level], 31);
} // endif rc
} // endif Status
} // end of WriteColumn
......@@ -724,14 +744,21 @@ int TDBXIN::DeleteDB(PGLOBAL g, int irc)
if (irc == RC_EF) {
} else if (irc == RC_FX) {
for (Section = Seclist; *Section; Section += (strlen(Section) + 1))
WritePrivateProfileString(Section, NULL, NULL, Ifile);
if (!WritePrivateProfileString(Section, NULL, NULL, Ifile)) {
sprintf(g->Message, "Error %d accessing %s",
GetLastError(), Ifile);
return RC_FX;
} // endif
} else if (Section) {
WritePrivateProfileString(Section, Keycur, NULL, Ifile);
} else {
} else if (!Section) {
strcpy(g->Message, MSG(NO_SECTION_NAME));
return RC_FX;
} // endif's
} else
if (!WritePrivateProfileString(Section, Keycur, NULL, Ifile)) {
sprintf(g->Message, "Error %d accessing %s",
GetLastError(), Ifile);
return RC_FX;
} // endif
return RC_OK;
} // end of DeleteDB
......@@ -792,6 +819,7 @@ void XINCOL::ReadColumn(PGLOBAL g)
void XINCOL::WriteColumn(PGLOBAL g)
{
char *p;
bool rc;
PTDBXIN tdbp = (PTDBXIN)To_Tdb;
if (trace > 1)
......@@ -813,20 +841,22 @@ void XINCOL::WriteColumn(PGLOBAL g)
if (tdbp->Mode == MODE_UPDATE) {
strcpy(g->Message, MSG(NO_SEC_UPDATE));
longjmp(g->jumper[g->jump_level], 31);
} else {
} else if (*p) {
tdbp->Section = p;
return;
} // endif Mode
} else
tdbp->Section = NULL;
return;
} else if (Flag == 2) {
if (tdbp->Mode == MODE_UPDATE) {
strcpy(g->Message, MSG(NO_KEY_UPDATE));
longjmp(g->jumper[g->jump_level], 31);
} else {
} else if (*p) {
tdbp->Keycur = p;
return;
} // endif Mode
} else
tdbp->Keycur = NULL;
return;
} else if (!tdbp->Section || !tdbp->Keycur) {
strcpy(g->Message, MSG(SEC_KEY_FIRST));
longjmp(g->jumper[g->jump_level], 31);
......@@ -835,8 +865,16 @@ void XINCOL::WriteColumn(PGLOBAL g)
/*********************************************************************/
/* Updating must be done only when not in checking pass. */
/*********************************************************************/
if (Status)
WritePrivateProfileString(tdbp->Section, tdbp->Keycur, p, tdbp->Ifile);
if (Status) {
rc = WritePrivateProfileString(tdbp->Section, tdbp->Keycur, p, tdbp->Ifile);
if (!rc) {
sprintf(g->Message, "Error %d writing to %s",
GetLastError(), tdbp->Ifile);
longjmp(g->jumper[g->jump_level], 31);
} // endif rc
} // endif Status
} // end of WriteColumn
......
......@@ -380,7 +380,8 @@ int TDBTBL::GetMaxSize(PGLOBAL g)
void TDBTBL::ResetDB(void)
{
for (PCOL colp = Columns; colp; colp = colp->GetNext())
if (colp->GetAmType() == TYPE_AM_TABID)
if (colp->GetAmType() == TYPE_AM_TABID ||
colp->GetAmType() == TYPE_AM_SRVID)
colp->COLBLK::Reset();
for (PTABLE tabp = Tablist; tabp; tabp = tabp->GetNext())
......@@ -492,7 +493,8 @@ int TDBTBL::ReadDB(PGLOBAL g)
// Check and initialize the subtable columns
for (PCOL cp = Columns; cp; cp = cp->GetNext())
if (cp->GetAmType() == TYPE_AM_TABID)
if (cp->GetAmType() == TYPE_AM_TABID ||
cp->GetAmType() == TYPE_AM_SRVID)
cp->COLBLK::Reset();
else if (((PPRXCOL)cp)->Init(g) && !Accept)
return RC_FX;
......
......@@ -159,7 +159,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
/* Allocate the structures used to refer to the result set. */
/**********************************************************************/
qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
buftyp, fldtyp, length, true, true);
buftyp, fldtyp, length, false, true);
// Some columns must be renamed
for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next)
......@@ -226,8 +226,12 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
crp->Kdata->SetValue((fp->null_ptr != 0) ? 1 : 0, i);
crp = crp->Next; // Remark
fld = fp->comment.str;
crp->Kdata->SetValue(fld, fp->comment.length, i);
// For Valgrind
if (fp->comment.length > 0 && (fld = fp->comment.str))
crp->Kdata->SetValue(fld, fp->comment.length, i);
else
crp->Kdata->Reset(i);
crp = crp->Next; // New
crp->Kdata->SetValue((fmt) ? fmt : (char*) "", i);
......@@ -364,7 +368,11 @@ PTDBASE TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp, bool b)
#if defined(MYSQL_SUPPORT)
// Access sub-table via MySQL API
if (!(tdbp= cat->GetTable(g, tabp, MODE_READ, "MYPRX"))) {
sprintf(g->Message, "Cannot access %s.%s", db, name);
char buf[MAX_STR];
strcpy(buf, g->Message);
sprintf(g->Message, "Error accessing %s.%s: %s", db, name, buf);
hc->tshp = NULL;
goto err;
} // endif Define
......
......@@ -70,6 +70,7 @@ class DllExport TDBPRX : public TDBASE {
virtual int GetRecpos(void) {return Tdbp->GetRecpos();}
virtual void ResetDB(void) {Tdbp->ResetDB();}
virtual int RowNumber(PGLOBAL g, bool b = FALSE);
virtual PSZ GetServer(void) {return (Tdbp) ? Tdbp->GetServer() : "?";}
// Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
......
......@@ -211,7 +211,7 @@ PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *cls, bool info)
/* Allocate the structures used to refer to the result set. */
/*********************************************************************/
qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
buftyp, fldtyp, length, true, true);
buftyp, fldtyp, length, false, true);
if (info)
return qrp;
......
......@@ -592,7 +592,7 @@ void CHRBLK::SetValue(char *sp, uint len, int n)
#endif
if (sp)
memcpy(p, sp, Long);
memcpy(p, sp, min((unsigned)Long, len));
if (Blanks) {
// Suppress eventual ending zero and right fill with blanks
......@@ -712,7 +712,7 @@ void *CHRBLK::GetValPtrEx(int n)
// For VCT blocks we must remove rightmost blanks.
char *p = Valp + Long;
for (p--; *p == ' ' && p >= Valp; p--) ;
for (p--; p >= Valp && *p == ' '; p--) ;
*(++p) = '\0';
} // endif Blanks
......
......@@ -583,12 +583,12 @@ template <>
void TYPVAL<double>::SetValue_char(char *p, int n)
{
if (p) {
char *p2, buf[32];
char buf[32];
for (p2 = p + n; p < p2 && *p == ' '; p++) ;
for (; n > 0 && *p == ' '; p++)
n--;
n = min(p2 - p, 31);
memcpy(buf, p, n);
memcpy(buf, p, min(n, 31));
buf[n] = '\0';
Tval = atof(buf);
......@@ -875,12 +875,16 @@ TYPVAL<PSZ>::TYPVAL(PSZ s) : VALUE(TYPE_STRING)
TYPVAL<PSZ>::TYPVAL(PGLOBAL g, PSZ s, int n, int c)
: VALUE(TYPE_STRING)
{
assert(Type == TYPE_STRING && (g || s));
assert(Type == TYPE_STRING);
Len = (g) ? n : strlen(s);
if (g && !s) {
Strp = (char *)PlugSubAlloc(g, NULL, Len + 1);
Strp[Len] = '\0';
if (!s) {
if (g) {
Strp = (char *)PlugSubAlloc(g, NULL, Len + 1);
Strp[Len] = '\0';
} else
assert(false);
} else
Strp = s;
......@@ -912,15 +916,21 @@ bool TYPVAL<PSZ>::SetValue_pval(PVAL valp, bool chktype)
void TYPVAL<PSZ>::SetValue_char(char *p, int n)
{
if (p) {
n = min(n, Len);
strncpy(Strp, p, n);
if ((n = min(n, Len))) {
strncpy(Strp, p, n);
for (p = Strp + n - 1; (*p == ' ' || *p == '\0') && p >= Strp; p--) ;
// for (p = Strp + n - 1; p >= Strp && (*p == ' ' || *p == '\0'); p--) ;
for (p = Strp + n - 1; p >= Strp; p--)
if (*p && *p != ' ')
break;
*(++p) = '\0';
*(++p) = '\0';
if (trace > 1)
htrc(" Setting string to: '%s'\n", Strp);
if (trace > 1)
htrc(" Setting string to: '%s'\n", Strp);
} else
Reset();
Null = false;
} else {
......
......@@ -83,6 +83,7 @@ class DllExport VALUE : public BLOCK {
virtual void SetPrec(int prec) {Prec = prec;}
bool IsNull(void) {return Null;}
void SetNull(bool b) {Null = b;}
bool GetNullable(void) {return Nullable;}
void SetNullable(bool b) {Nullable = b;}
int GetType(void) {return Type;}
int GetClen(void) {return Clen;}
......
......@@ -1832,8 +1832,9 @@ int XINDXS::Range(PGLOBAL g, int limit, bool incl)
/*********************************************************************/
if (xp->GetType() == TYPE_CONST) {
kp->Valp->SetValue_pval(xp->GetValue(), !kp->Prefix);
k = FastFind(Nval);
if ((k = FastFind(Nval)) < Num_K)
if (k < Num_K || Op != OP_EQ)
if (limit)
n = (Mul) ? k : kp->Val_K;
else
......@@ -2797,7 +2798,7 @@ bool KXYCOL::Init(PGLOBAL g, PCOL colp, int n, bool sm, int kln)
if (Asc)
IsSorted = colp->GetOpt() < 0;
//MayHaveNulls = colp->HasNulls();
//SetNulls(colp->IsNullable()); for when null columns will be indexable
return false;
} // end of Init
......@@ -2956,6 +2957,11 @@ void KXYCOL::InitBinFind(void *vp)
void KXYCOL::FillValue(PVAL valp)
{
valp->SetValue_pvblk(Kblp, Val_K);
// Set null when applicable (NIY)
//if (valp->GetNullable())
// valp->SetNull(valp->IsZero());
} // end of FillValue
/***********************************************************************/
......
......@@ -473,10 +473,10 @@ class KXYCOL: public BLOCK {
protected:
// Members
PXCOL Next; // To next in the key part list
PXCOL Next; // To next in the key part list
PXCOL Previous; // To previous in the key part list
PKXBASE Kxp; // To the INDEX class block
PCOL Colp; // To matching object if a column
PCOL Colp; // To matching object if a column
bool IsSorted; // true if column is already sorted
bool Asc; // true for ascending sort, false for Desc
MBLOCK Keys; // Data array allocation block
......
......@@ -113,6 +113,7 @@ class DllExport TDB: public TBX { // Table Descriptor Block.
{fprintf(f, "%s AM(%d)\n", m, GetAmType());}
virtual void Print(PGLOBAL g, FILE *f, uint n);
virtual void Print(PGLOBAL g, char *ps, uint z);
virtual PSZ GetServer(void) = 0;
// Database pure virtual routines
virtual PCOL ColDB(PGLOBAL g, PSZ name, int num) = 0;
......@@ -192,13 +193,14 @@ class DllExport TDBASE : public TDB {
virtual void ResetSize(void) {MaxSize = -1;}
virtual void RestoreNrec(void) {}
virtual int ResetTableOpt(PGLOBAL g, bool dox);
virtual PSZ GetServer(void) {return "Current";}
// Database routines
virtual PCOL ColDB(PGLOBAL g, PSZ name, int num);
virtual PCOL MakeCol(PGLOBAL, PCOLDEF, PCOL, int)
{assert(false); return NULL;}
virtual PCOL InsertSpecialColumn(PGLOBAL g, PCOL colp);
virtual PCOL InsertSpcBlk(PGLOBAL g, PCOLUMN cp);
virtual PCOL InsertSpcBlk(PGLOBAL g, PCOLDEF cdp);
virtual void MarkDB(PGLOBAL g, PTDB tdb2);
protected:
......
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