mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
- Set connection charset before calling mysql_real_connect for MYSQL
tables. This should fix bug MDEV-7343. modified: storage/connect/ha_connect.cc storage/connect/myconn.cpp storage/connect/myconn.h storage/connect/reldef.cpp storage/connect/reldef.h storage/connect/table.cpp storage/connect/tabmysql.cpp storage/connect/xtable.h - Prevent double column evaluation when CONNECT does filtering modified: storage/connect/connect.cc - Export CreateFileMap and CloseMemMap (for OEM tables) modified: storage/connect/maputil.h - Add the compute function to be used on VALUE types. Preserve precision for DOUBLE values. modified: storage/connect/value.cpp storage/connect/value.h - Typo (in preparation to the future JSON table type) modified: storage/connect/ha_connect.cc storage/connect/mycat.cc storage/connect/plgdbsem.h
This commit is contained in:
@@ -52,7 +52,7 @@
|
|||||||
/* Routines called internally by semantic routines. */
|
/* Routines called internally by semantic routines. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
void CntEndDB(PGLOBAL);
|
void CntEndDB(PGLOBAL);
|
||||||
RCODE EvalColumns(PGLOBAL g, PTDB tdbp, bool mrr= false);
|
RCODE EvalColumns(PGLOBAL g, PTDB tdbp, bool reset, bool mrr= false);
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* MySQL routines called externally by semantic routines. */
|
/* MySQL routines called externally by semantic routines. */
|
||||||
@@ -388,7 +388,7 @@ bool CntRewindTable(PGLOBAL g, PTDB tdbp)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Evaluate all columns after a record is read. */
|
/* Evaluate all columns after a record is read. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
RCODE EvalColumns(PGLOBAL g, PTDB tdbp, bool mrr)
|
RCODE EvalColumns(PGLOBAL g, PTDB tdbp, bool reset, bool mrr)
|
||||||
{
|
{
|
||||||
RCODE rc= RC_OK;
|
RCODE rc= RC_OK;
|
||||||
PCOL colp;
|
PCOL colp;
|
||||||
@@ -413,7 +413,8 @@ RCODE EvalColumns(PGLOBAL g, PTDB tdbp, bool mrr)
|
|||||||
|
|
||||||
for (colp= tdbp->GetColumns(); rc == RC_OK && colp;
|
for (colp= tdbp->GetColumns(); rc == RC_OK && colp;
|
||||||
colp= colp->GetNext()) {
|
colp= colp->GetNext()) {
|
||||||
colp->Reset();
|
if (reset)
|
||||||
|
colp->Reset();
|
||||||
|
|
||||||
// Virtual columns are computed by MariaDB
|
// Virtual columns are computed by MariaDB
|
||||||
if (!colp->GetColUse(U_VIRTUAL) && (!mrr || colp->GetKcol()))
|
if (!colp->GetColUse(U_VIRTUAL) && (!mrr || colp->GetKcol()))
|
||||||
@@ -457,6 +458,10 @@ RCODE CntReadNext(PGLOBAL g, PTDB tdbp)
|
|||||||
goto err;
|
goto err;
|
||||||
} // endif rc
|
} // endif rc
|
||||||
|
|
||||||
|
// Do it now to avoid double eval when filtering
|
||||||
|
for (PCOL colp= tdbp->GetColumns(); colp; colp= colp->GetNext())
|
||||||
|
colp->Reset();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if ((rc= (RCODE)tdbp->ReadDB(g)) == RC_OK)
|
if ((rc= (RCODE)tdbp->ReadDB(g)) == RC_OK)
|
||||||
if (!ApplyFilter(g, tdbp->GetFilter()))
|
if (!ApplyFilter(g, tdbp->GetFilter()))
|
||||||
@@ -466,7 +471,7 @@ RCODE CntReadNext(PGLOBAL g, PTDB tdbp)
|
|||||||
|
|
||||||
err:
|
err:
|
||||||
g->jump_level--;
|
g->jump_level--;
|
||||||
return (rc != RC_OK) ? rc : EvalColumns(g, tdbp);
|
return (rc != RC_OK) ? rc : EvalColumns(g, tdbp, false);
|
||||||
} // end of CntReadNext
|
} // end of CntReadNext
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -812,7 +817,7 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
|
|||||||
|
|
||||||
rnd:
|
rnd:
|
||||||
if ((rc= (RCODE)ptdb->ReadDB(g)) == RC_OK)
|
if ((rc= (RCODE)ptdb->ReadDB(g)) == RC_OK)
|
||||||
rc= EvalColumns(g, ptdb, mrr);
|
rc= EvalColumns(g, ptdb, true, mrr);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
} // end of CntIndexRead
|
} // end of CntIndexRead
|
||||||
|
@@ -1055,6 +1055,14 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
|
|||||||
opval= (char*)options->colist;
|
opval= (char*)options->colist;
|
||||||
else if (!stricmp(opname, "Data_charset"))
|
else if (!stricmp(opname, "Data_charset"))
|
||||||
opval= (char*)options->data_charset;
|
opval= (char*)options->data_charset;
|
||||||
|
else if (!stricmp(opname, "Table_charset")) {
|
||||||
|
const CHARSET_INFO *chif= (tshp) ? tshp->table_charset
|
||||||
|
: table->s->table_charset;
|
||||||
|
|
||||||
|
if (chif)
|
||||||
|
opval= (char*)chif->csname;
|
||||||
|
|
||||||
|
} // endif Table_charset
|
||||||
|
|
||||||
if (!opval && options && options->oplist)
|
if (!opval && options && options->oplist)
|
||||||
opval= GetListOption(xp->g, opname, options->oplist);
|
opval= GetListOption(xp->g, opname, options->oplist);
|
||||||
@@ -3806,6 +3814,7 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn)
|
|||||||
case TAB_XML:
|
case TAB_XML:
|
||||||
case TAB_INI:
|
case TAB_INI:
|
||||||
case TAB_VEC:
|
case TAB_VEC:
|
||||||
|
// case TAB_JSON:
|
||||||
if (options->filename && *options->filename) {
|
if (options->filename && *options->filename) {
|
||||||
char *s, path[FN_REFLEN], dbpath[FN_REFLEN];
|
char *s, path[FN_REFLEN], dbpath[FN_REFLEN];
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
|
@@ -11,8 +11,8 @@ typedef struct {
|
|||||||
DWORD lenH;
|
DWORD lenH;
|
||||||
} MEMMAP;
|
} MEMMAP;
|
||||||
|
|
||||||
HANDLE CreateFileMap(PGLOBAL, LPCSTR, MEMMAP *, MODE, bool);
|
DllExport HANDLE CreateFileMap(PGLOBAL, LPCSTR, MEMMAP *, MODE, bool);
|
||||||
bool CloseMemMap(void *memory, size_t dwSize);
|
DllExport bool CloseMemMap(void *memory, size_t dwSize);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) Olivier Bertrand 2004 - 2013
|
/* Copyright (C) Olivier Bertrand 2004 - 2014
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
/* ------------- */
|
/* ------------- */
|
||||||
/* Version 1.4 */
|
/* Version 1.4 */
|
||||||
/* */
|
/* */
|
||||||
/* Author: Olivier Bertrand 2012 - 2013 */
|
/* Author: Olivier Bertrand 2012 - 2014 */
|
||||||
/* */
|
/* */
|
||||||
/* WHAT THIS PROGRAM DOES: */
|
/* WHAT THIS PROGRAM DOES: */
|
||||||
/* ----------------------- */
|
/* ----------------------- */
|
||||||
@@ -89,6 +89,7 @@
|
|||||||
#include "tabpivot.h"
|
#include "tabpivot.h"
|
||||||
#endif // PIVOT_SUPPORT
|
#endif // PIVOT_SUPPORT
|
||||||
#include "tabvir.h"
|
#include "tabvir.h"
|
||||||
|
//#include "tabjson.h"
|
||||||
#include "ha_connect.h"
|
#include "ha_connect.h"
|
||||||
#include "mycat.h"
|
#include "mycat.h"
|
||||||
|
|
||||||
@@ -139,6 +140,7 @@ TABTYPE GetTypeID(const char *type)
|
|||||||
: (!stricmp(type, "PIVOT")) ? TAB_PIVOT
|
: (!stricmp(type, "PIVOT")) ? TAB_PIVOT
|
||||||
#endif
|
#endif
|
||||||
: (!stricmp(type, "VIR")) ? TAB_VIR
|
: (!stricmp(type, "VIR")) ? TAB_VIR
|
||||||
|
// : (!stricmp(type, "JSON")) ? TAB_JSON
|
||||||
: (!stricmp(type, "OEM")) ? TAB_OEM : TAB_NIY;
|
: (!stricmp(type, "OEM")) ? TAB_OEM : TAB_NIY;
|
||||||
} // end of GetTypeID
|
} // end of GetTypeID
|
||||||
|
|
||||||
@@ -159,6 +161,7 @@ bool IsFileType(TABTYPE type)
|
|||||||
case TAB_XML:
|
case TAB_XML:
|
||||||
case TAB_INI:
|
case TAB_INI:
|
||||||
case TAB_VEC:
|
case TAB_VEC:
|
||||||
|
// case TAB_JSON:
|
||||||
isfile= true;
|
isfile= true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -181,6 +184,7 @@ bool IsExactType(TABTYPE type)
|
|||||||
case TAB_BIN:
|
case TAB_BIN:
|
||||||
case TAB_DBF:
|
case TAB_DBF:
|
||||||
// case TAB_XML: depends on Multiple || Xpand || Coltype
|
// case TAB_XML: depends on Multiple || Xpand || Coltype
|
||||||
|
// case TAB_JSON: depends on Multiple || Xpand || Coltype
|
||||||
case TAB_VEC:
|
case TAB_VEC:
|
||||||
case TAB_VIR:
|
case TAB_VIR:
|
||||||
exact= true;
|
exact= true;
|
||||||
@@ -214,7 +218,7 @@ bool IsTypeNullable(TABTYPE type)
|
|||||||
} // end of IsTypeNullable
|
} // end of IsTypeNullable
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Return true for indexable table by XINDEX. */
|
/* Return true for fixed record length tables. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool IsTypeFixed(TABTYPE type)
|
bool IsTypeFixed(TABTYPE type)
|
||||||
{
|
{
|
||||||
@@ -538,6 +542,7 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, LPCSTR name, LPCSTR am)
|
|||||||
case TAB_PIVOT: tdp= new(g) PIVOTDEF; break;
|
case TAB_PIVOT: tdp= new(g) PIVOTDEF; break;
|
||||||
#endif // PIVOT_SUPPORT
|
#endif // PIVOT_SUPPORT
|
||||||
case TAB_VIR: tdp= new(g) VIRDEF; break;
|
case TAB_VIR: tdp= new(g) VIRDEF; break;
|
||||||
|
// case TAB_JSON: tdp= new(g) JSONDEF; break;
|
||||||
default:
|
default:
|
||||||
sprintf(g->Message, MSG(BAD_TABLE_TYPE), am, name);
|
sprintf(g->Message, MSG(BAD_TABLE_TYPE), am, name);
|
||||||
} // endswitch
|
} // endswitch
|
||||||
|
@@ -430,10 +430,11 @@ int MYSQLC::GetResultSize(PGLOBAL g, PSZ sql)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
|
int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
|
||||||
const char *user, const char *pwd,
|
const char *user, const char *pwd,
|
||||||
int pt)
|
int pt, const char *csname)
|
||||||
{
|
{
|
||||||
const char *pipe = NULL;
|
const char *pipe = NULL;
|
||||||
uint cto = 6000, nrt = 12000;
|
uint cto = 6000, nrt = 12000;
|
||||||
|
my_bool my_true= 1;
|
||||||
|
|
||||||
m_DB = mysql_init(NULL);
|
m_DB = mysql_init(NULL);
|
||||||
|
|
||||||
@@ -470,6 +471,18 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
|
|||||||
} // endif pwd
|
} // endif pwd
|
||||||
#endif // 0
|
#endif // 0
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* BUG# 17044 Federated Storage Engine is not UTF8 clean */
|
||||||
|
/* Add set names to whatever charset the table is at open of table */
|
||||||
|
/* this sets the csname like 'set names utf8'. */
|
||||||
|
/***********************************************************************/
|
||||||
|
if (csname)
|
||||||
|
mysql_options(m_DB, MYSQL_SET_CHARSET_NAME, csname);
|
||||||
|
|
||||||
|
// Don't know what this one do but FEDERATED does it
|
||||||
|
mysql_options(m_DB, MYSQL_OPT_USE_THREAD_SPECIFIC_MEMORY,
|
||||||
|
(char*)&my_true);
|
||||||
|
|
||||||
if (!mysql_real_connect(m_DB, host, user, pwd, db, pt, pipe, CLIENT_MULTI_RESULTS)) {
|
if (!mysql_real_connect(m_DB, host, user, pwd, db, pt, pipe, CLIENT_MULTI_RESULTS)) {
|
||||||
#if defined(_DEBUG)
|
#if defined(_DEBUG)
|
||||||
sprintf(g->Message, "mysql_real_connect failed: (%d) %s",
|
sprintf(g->Message, "mysql_real_connect failed: (%d) %s",
|
||||||
|
@@ -67,7 +67,7 @@ class DllItem MYSQLC {
|
|||||||
int GetTableSize(PGLOBAL g, PSZ query);
|
int GetTableSize(PGLOBAL g, PSZ query);
|
||||||
int Open(PGLOBAL g, const char *host, const char *db,
|
int Open(PGLOBAL g, const char *host, const char *db,
|
||||||
const char *user= "root", const char *pwd= "*",
|
const char *user= "root", const char *pwd= "*",
|
||||||
int pt= 0);
|
int pt= 0, const char *csname = NULL);
|
||||||
int KillQuery(ulong id);
|
int KillQuery(ulong id);
|
||||||
int ExecSQL(PGLOBAL g, const char *query, int *w = NULL);
|
int ExecSQL(PGLOBAL g, const char *query, int *w = NULL);
|
||||||
int ExecSQLcmd(PGLOBAL g, const char *query, int *w);
|
int ExecSQLcmd(PGLOBAL g, const char *query, int *w);
|
||||||
@@ -98,5 +98,6 @@ class DllItem MYSQLC {
|
|||||||
int m_Fields; // The number of result fields
|
int m_Fields; // The number of result fields
|
||||||
int m_Afrw; // The number of affected rows
|
int m_Afrw; // The number of affected rows
|
||||||
bool m_Use; // Use or store result set
|
bool m_Use; // Use or store result set
|
||||||
|
const char *csname; // Table charset name
|
||||||
}; // end of class MYSQLC
|
}; // end of class MYSQLC
|
||||||
|
|
||||||
|
@@ -74,9 +74,11 @@ enum TABTYPE {TAB_UNDEF = 0, /* Table of undefined type */
|
|||||||
TAB_PLG = 20, /* PLG NIY */
|
TAB_PLG = 20, /* PLG NIY */
|
||||||
TAB_PIVOT = 21, /* PIVOT table */
|
TAB_PIVOT = 21, /* PIVOT table */
|
||||||
TAB_VIR = 22, /* Virtual tables */
|
TAB_VIR = 22, /* Virtual tables */
|
||||||
TAB_JCT = 23, /* Junction tables NIY */
|
TAB_JSON = 23, /* JSON tables */
|
||||||
TAB_DMY = 24, /* DMY Dummy tables NIY */
|
TAB_JSN = 24, /* Semi-json tables */
|
||||||
TAB_NIY = 25}; /* Table not implemented yet */
|
TAB_JCT = 25, /* Junction tables NIY */
|
||||||
|
TAB_DMY = 26, /* DMY Dummy tables NIY */
|
||||||
|
TAB_NIY = 27}; /* Table not implemented yet */
|
||||||
|
|
||||||
enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
|
enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */
|
||||||
TYPE_AM_ROWID = 1, /* ROWID type (special column) */
|
TYPE_AM_ROWID = 1, /* ROWID type (special column) */
|
||||||
|
@@ -202,6 +202,8 @@ TABDEF::TABDEF(void)
|
|||||||
Degree = 0;
|
Degree = 0;
|
||||||
Pseudo = 0;
|
Pseudo = 0;
|
||||||
Read_Only = false;
|
Read_Only = false;
|
||||||
|
m_data_charset = NULL;
|
||||||
|
csname = NULL;
|
||||||
} // end of TABDEF constructor
|
} // end of TABDEF constructor
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -224,6 +226,7 @@ bool TABDEF::Define(PGLOBAL g, PCATLG cat, LPCSTR name, LPCSTR am)
|
|||||||
m_data_charset= data_charset_name ?
|
m_data_charset= data_charset_name ?
|
||||||
get_charset_by_csname(data_charset_name, MY_CS_PRIMARY, 0):
|
get_charset_by_csname(data_charset_name, MY_CS_PRIMARY, 0):
|
||||||
NULL;
|
NULL;
|
||||||
|
csname = GetStringCatInfo(g, "Table_charset", NULL);
|
||||||
|
|
||||||
// Get The column definitions
|
// Get The column definitions
|
||||||
if ((poff = GetColCatInfo(g)) < 0)
|
if ((poff = GetColCatInfo(g)) < 0)
|
||||||
|
@@ -68,6 +68,7 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */
|
|||||||
friend class CATALOG;
|
friend class CATALOG;
|
||||||
friend class PLUGCAT;
|
friend class PLUGCAT;
|
||||||
friend class MYCAT;
|
friend class MYCAT;
|
||||||
|
friend class TDBASE;
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
TABDEF(void); // Constructor
|
TABDEF(void); // Constructor
|
||||||
@@ -110,6 +111,7 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */
|
|||||||
int Pseudo; /* Bit: 1 ROWID Ok, 2 FILEID Ok */
|
int Pseudo; /* Bit: 1 ROWID Ok, 2 FILEID Ok */
|
||||||
bool Read_Only; /* true for read only tables */
|
bool Read_Only; /* true for read only tables */
|
||||||
const CHARSET_INFO *m_data_charset;
|
const CHARSET_INFO *m_data_charset;
|
||||||
|
const char *csname; /* Table charset name */
|
||||||
}; // end of TABDEF
|
}; // end of TABDEF
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -146,6 +146,7 @@ TDBASE::TDBASE(PTABDEF tdp) : TDB(tdp)
|
|||||||
Knum = 0;
|
Knum = 0;
|
||||||
Read_Only = (tdp) ? tdp->IsReadOnly() : false;
|
Read_Only = (tdp) ? tdp->IsReadOnly() : false;
|
||||||
m_data_charset= (tdp) ? tdp->data_charset() : NULL;
|
m_data_charset= (tdp) ? tdp->data_charset() : NULL;
|
||||||
|
csname = (tdp) ? tdp->csname : NULL;
|
||||||
} // end of TDBASE constructor
|
} // end of TDBASE constructor
|
||||||
|
|
||||||
TDBASE::TDBASE(PTDBASE tdbp) : TDB(tdbp)
|
TDBASE::TDBASE(PTDBASE tdbp) : TDB(tdbp)
|
||||||
@@ -161,6 +162,7 @@ TDBASE::TDBASE(PTDBASE tdbp) : TDB(tdbp)
|
|||||||
Knum = tdbp->Knum;
|
Knum = tdbp->Knum;
|
||||||
Read_Only = tdbp->Read_Only;
|
Read_Only = tdbp->Read_Only;
|
||||||
m_data_charset= tdbp->m_data_charset;
|
m_data_charset= tdbp->m_data_charset;
|
||||||
|
csname = tdbp->csname;
|
||||||
} // end of TDBASE copy constructor
|
} // end of TDBASE copy constructor
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -777,7 +777,7 @@ int TDBMYSQL::Cardinality(PGLOBAL g)
|
|||||||
char query[96];
|
char query[96];
|
||||||
MYSQLC myc;
|
MYSQLC myc;
|
||||||
|
|
||||||
if (myc.Open(g, Host, Database, User, Pwd, Port))
|
if (myc.Open(g, Host, Database, User, Pwd, Port, csname))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
strcpy(query, "SELECT COUNT(*) FROM ");
|
strcpy(query, "SELECT COUNT(*) FROM ");
|
||||||
@@ -871,7 +871,7 @@ bool TDBMYSQL::OpenDB(PGLOBAL g)
|
|||||||
/* servers allowing concurency in getting results ??? */
|
/* servers allowing concurency in getting results ??? */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
if (!Myc.Connected()) {
|
if (!Myc.Connected()) {
|
||||||
if (Myc.Open(g, Host, Database, User, Pwd, Port))
|
if (Myc.Open(g, Host, Database, User, Pwd, Port, csname))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} // endif Connected
|
} // endif Connected
|
||||||
|
@@ -330,7 +330,7 @@ int ConvertType(int target, int type, CONV kind, bool match)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* AllocateConstant: allocates a constant Value. */
|
/* AllocateConstant: allocates a constant Value. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PVAL AllocateValue(PGLOBAL g, void *value, short type)
|
PVAL AllocateValue(PGLOBAL g, void *value, short type, short prec)
|
||||||
{
|
{
|
||||||
PVAL valp;
|
PVAL valp;
|
||||||
|
|
||||||
@@ -351,7 +351,7 @@ PVAL AllocateValue(PGLOBAL g, void *value, short type)
|
|||||||
valp = new(g) TYPVAL<longlong>(*(longlong*)value, TYPE_BIGINT);
|
valp = new(g) TYPVAL<longlong>(*(longlong*)value, TYPE_BIGINT);
|
||||||
break;
|
break;
|
||||||
case TYPE_DOUBLE:
|
case TYPE_DOUBLE:
|
||||||
valp = new(g) TYPVAL<double>(*(double *)value, TYPE_DOUBLE, 2);
|
valp = new(g) TYPVAL<double>(*(double *)value, TYPE_DOUBLE, prec);
|
||||||
break;
|
break;
|
||||||
case TYPE_TINY:
|
case TYPE_TINY:
|
||||||
valp = new(g) TYPVAL<char>(*(char *)value, TYPE_TINY);
|
valp = new(g) TYPVAL<char>(*(char *)value, TYPE_TINY);
|
||||||
@@ -475,7 +475,7 @@ PVAL AllocateValue(PGLOBAL g, PVAL valp, int newtype, int uns)
|
|||||||
break;
|
break;
|
||||||
case TYPE_DOUBLE:
|
case TYPE_DOUBLE:
|
||||||
valp = new(g) TYPVAL<double>(valp->GetFloatValue(), TYPE_DOUBLE,
|
valp = new(g) TYPVAL<double>(valp->GetFloatValue(), TYPE_DOUBLE,
|
||||||
valp->GetValPrec());
|
(uns) ? uns : valp->GetValPrec());
|
||||||
break;
|
break;
|
||||||
case TYPE_TINY:
|
case TYPE_TINY:
|
||||||
if (un)
|
if (un)
|
||||||
@@ -542,6 +542,15 @@ BYTE VALUE::TestValue(PVAL vp)
|
|||||||
return (n > 0) ? 0x04 : (n < 0) ? 0x02 : 0x01;
|
return (n > 0) ? 0x04 : (n < 0) ? 0x02 : 0x01;
|
||||||
} // end of TestValue
|
} // end of TestValue
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Compute a function on a string. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool VALUE::Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op)
|
||||||
|
{
|
||||||
|
strcpy(g->Message, "Compute not implemented for this value type");
|
||||||
|
return true;
|
||||||
|
} // end of Compute
|
||||||
|
|
||||||
/* -------------------------- Class TYPVAL ---------------------------- */
|
/* -------------------------- Class TYPVAL ---------------------------- */
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -930,6 +939,188 @@ int TYPVAL<TYPE>::CompareValue(PVAL vp)
|
|||||||
return (Tval > n) ? 1 : (Tval < n) ? (-1) : 0;
|
return (Tval > n) ? 1 : (Tval < n) ? (-1) : 0;
|
||||||
} // end of CompareValue
|
} // end of CompareValue
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Return max type value if b is true, else min type value. */
|
||||||
|
/***********************************************************************/
|
||||||
|
template <>
|
||||||
|
short TYPVAL<short>::MinMaxVal(bool b)
|
||||||
|
{return (b) ? MAXINT16 : MININT16;}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
USHORT TYPVAL<USHORT>::MinMaxVal(bool b)
|
||||||
|
{return (b) ? MAXUINT16 : 0;}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
int TYPVAL<int>::MinMaxVal(bool b)
|
||||||
|
{return (b) ? MAXINT32 : MININT32;}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
UINT TYPVAL<UINT>::MinMaxVal(bool b)
|
||||||
|
{return (b) ? MAXUINT32 : 0;}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
longlong TYPVAL<longlong>::MinMaxVal(bool b)
|
||||||
|
{return (b) ? MAXINT64 : MININT64;}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
ulonglong TYPVAL<ulonglong>::MinMaxVal(bool b)
|
||||||
|
{return (b) ? MAXUINT64 : 0;}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
double TYPVAL<double>::MinMaxVal(bool b)
|
||||||
|
{assert(false); return 0.0;}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
char TYPVAL<char>::MinMaxVal(bool b)
|
||||||
|
{return (b) ? MAXINT8 : MININT8;}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
UCHAR TYPVAL<UCHAR>::MinMaxVal(bool b)
|
||||||
|
{return (b) ? MAXUINT8 : 0;}
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* SafeAdd: adds a value and test whether overflow/underflow occured. */
|
||||||
|
/***********************************************************************/
|
||||||
|
template <class TYPE>
|
||||||
|
TYPE TYPVAL<TYPE>::SafeAdd(TYPE n1, TYPE n2)
|
||||||
|
{
|
||||||
|
PGLOBAL& g = Global;
|
||||||
|
TYPE n = n1 + n2;
|
||||||
|
|
||||||
|
if ((n2 > 0) && (n < n1)) {
|
||||||
|
// Overflow
|
||||||
|
strcpy(g->Message, MSG(FIX_OVFLW_ADD));
|
||||||
|
longjmp(g->jumper[g->jump_level], 138);
|
||||||
|
} else if ((n2 < 0) && (n > n1)) {
|
||||||
|
// Underflow
|
||||||
|
strcpy(g->Message, MSG(FIX_UNFLW_ADD));
|
||||||
|
longjmp(g->jumper[g->jump_level], 138);
|
||||||
|
} // endif's n2
|
||||||
|
|
||||||
|
return n;
|
||||||
|
} // end of SafeAdd
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline double TYPVAL<double>::SafeAdd(double n1, double n2)
|
||||||
|
{
|
||||||
|
assert(false); return 0;
|
||||||
|
} // end of SafeAdd
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* SafeMult: multiply values and test whether overflow occured. */
|
||||||
|
/***********************************************************************/
|
||||||
|
template <class TYPE>
|
||||||
|
TYPE TYPVAL<TYPE>::SafeMult(TYPE n1, TYPE n2)
|
||||||
|
{
|
||||||
|
PGLOBAL& g = Global;
|
||||||
|
double n = (double)n1 * (double)n2;
|
||||||
|
|
||||||
|
if (n > MinMaxVal(true)) {
|
||||||
|
// Overflow
|
||||||
|
strcpy(g->Message, MSG(FIX_OVFLW_TIMES));
|
||||||
|
longjmp(g->jumper[g->jump_level], 138);
|
||||||
|
} else if (n < MinMaxVal(false)) {
|
||||||
|
// Underflow
|
||||||
|
strcpy(g->Message, MSG(FIX_UNFLW_TIMES));
|
||||||
|
longjmp(g->jumper[g->jump_level], 138);
|
||||||
|
} // endif's n2
|
||||||
|
|
||||||
|
return (TYPE)n;
|
||||||
|
} // end of SafeMult
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline double TYPVAL<double>::SafeMult(double n1, double n2)
|
||||||
|
{
|
||||||
|
assert(false); return 0;
|
||||||
|
} // end of SafeMult
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Compute defined functions for the type. */
|
||||||
|
/***********************************************************************/
|
||||||
|
template <class TYPE>
|
||||||
|
bool TYPVAL<TYPE>::Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op)
|
||||||
|
{
|
||||||
|
bool rc = false;
|
||||||
|
TYPE val[2];
|
||||||
|
|
||||||
|
assert(np == 2);
|
||||||
|
|
||||||
|
for (int i = 0; i < np; i++)
|
||||||
|
val[i] = GetTypedValue(vp[i]);
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case OP_ADD:
|
||||||
|
// Tval = SafeAdd(val[0], val[1]);
|
||||||
|
Tval = val[0] + val[1];
|
||||||
|
break;
|
||||||
|
case OP_MULT:
|
||||||
|
// Tval = SafeMult(val[0], val[1]);
|
||||||
|
Tval = val[0] * val[1];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rc = Compall(g, vp, np, op);
|
||||||
|
break;
|
||||||
|
} // endswitch op
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
} // end of Compute
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
template <>
|
||||||
|
bool TYPVAL<double>::Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op)
|
||||||
|
{
|
||||||
|
bool rc = false;
|
||||||
|
double val[2];
|
||||||
|
|
||||||
|
assert(np == 2);
|
||||||
|
|
||||||
|
for (int i = 0; i < np; i++)
|
||||||
|
val[i] = vp[i]->GetFloatValue();
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case OP_ADD:
|
||||||
|
Tval = val[0] + val[1];
|
||||||
|
break;
|
||||||
|
case OP_MULT:
|
||||||
|
Tval = val[0] * val[1];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rc = Compall(g, vp, np, op);
|
||||||
|
} // endswitch op
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
} // end of Compute
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Compute a function for all types. */
|
||||||
|
/***********************************************************************/
|
||||||
|
template <class TYPE>
|
||||||
|
bool TYPVAL<TYPE>::Compall(PGLOBAL g, PVAL *vp, int np, OPVAL op)
|
||||||
|
{
|
||||||
|
TYPE val[2];
|
||||||
|
|
||||||
|
for (int i = 0; i < np; i++)
|
||||||
|
val[i] = GetTypedValue(vp[i]);
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case OP_MIN:
|
||||||
|
Tval = MY_MIN(val[0], val[1]);
|
||||||
|
break;
|
||||||
|
case OP_MAX:
|
||||||
|
Tval = MY_MAX(val[0], val[1]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// sprintf(g->Message, MSG(BAD_EXP_OPER), op);
|
||||||
|
strcpy(g->Message, "Function not supported");
|
||||||
|
return true;
|
||||||
|
} // endswitch op
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} // end of Compall
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* FormatValue: This function set vp (a STRING value) to the string */
|
/* FormatValue: This function set vp (a STRING value) to the string */
|
||||||
/* constructed from its own value formated using the fmt format. */
|
/* constructed from its own value formated using the fmt format. */
|
||||||
@@ -1409,6 +1600,45 @@ int TYPVAL<PSZ>::CompareValue(PVAL vp)
|
|||||||
return (n > 0) ? 1 : (n < 0) ? -1 : 0;
|
return (n > 0) ? 1 : (n < 0) ? -1 : 0;
|
||||||
} // end of CompareValue
|
} // end of CompareValue
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Compute a function on a string. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool TYPVAL<PSZ>::Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op)
|
||||||
|
{
|
||||||
|
char *p[2], val[2][32];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < np; i++)
|
||||||
|
p[i] = vp[i]->GetCharString(val[i]);
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case OP_CNC:
|
||||||
|
assert(np == 1 || np == 2);
|
||||||
|
|
||||||
|
if (np == 2)
|
||||||
|
strncpy(Strp, p[0], Len);
|
||||||
|
|
||||||
|
if ((i = Len - (signed)strlen(Strp)) > 0)
|
||||||
|
strncat(Strp, p[np - 1], i);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case OP_MIN:
|
||||||
|
assert(np == 2);
|
||||||
|
strcpy(Strp, (strcmp(p[0], p[1]) < 0) ? p[0] : p[1]);
|
||||||
|
break;
|
||||||
|
case OP_MAX:
|
||||||
|
assert(np == 2);
|
||||||
|
strcpy(Strp, (strcmp(p[0], p[1]) > 0) ? p[0] : p[1]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// sprintf(g->Message, MSG(BAD_EXP_OPER), op);
|
||||||
|
strcpy(g->Message, "Function not supported");
|
||||||
|
return true;
|
||||||
|
} // endswitch op
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} // end of Compute
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* FormatValue: This function set vp (a STRING value) to the string */
|
/* FormatValue: This function set vp (a STRING value) to the string */
|
||||||
/* constructed from its own value formated using the fmt format. */
|
/* constructed from its own value formated using the fmt format. */
|
||||||
|
@@ -29,12 +29,9 @@ enum CONV {CNV_ANY = 0, /* Convert to any type */
|
|||||||
class CONSTANT; // For friend setting
|
class CONSTANT; // For friend setting
|
||||||
typedef struct _datpar *PDTP; // For DTVAL
|
typedef struct _datpar *PDTP; // For DTVAL
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Utilities used to test types and to allocated values. */
|
/* Utilities used to test types and to allocated values. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PVAL AllocateValue(PGLOBAL, void *, short);
|
|
||||||
|
|
||||||
// Exported functions
|
// Exported functions
|
||||||
DllExport PSZ GetTypeName(int);
|
DllExport PSZ GetTypeName(int);
|
||||||
DllExport int GetTypeSize(int, int);
|
DllExport int GetTypeSize(int, int);
|
||||||
@@ -47,6 +44,7 @@ DllExport int GetFormatType(char);
|
|||||||
DllExport bool IsTypeChar(int type);
|
DllExport bool IsTypeChar(int type);
|
||||||
DllExport bool IsTypeNum(int type);
|
DllExport bool IsTypeNum(int type);
|
||||||
DllExport int ConvertType(int, int, CONV, bool match = false);
|
DllExport int ConvertType(int, int, CONV, bool match = false);
|
||||||
|
DllExport PVAL AllocateValue(PGLOBAL, void *, short, short = 2);
|
||||||
DllExport PVAL AllocateValue(PGLOBAL, PVAL, int = TYPE_VOID, int = 0);
|
DllExport PVAL AllocateValue(PGLOBAL, PVAL, int = TYPE_VOID, int = 0);
|
||||||
DllExport PVAL AllocateValue(PGLOBAL, int, int len = 0, int prec = 0,
|
DllExport PVAL AllocateValue(PGLOBAL, int, int len = 0, int prec = 0,
|
||||||
bool uns = false, PSZ fmt = NULL);
|
bool uns = false, PSZ fmt = NULL);
|
||||||
@@ -114,6 +112,7 @@ class DllExport VALUE : public BLOCK {
|
|||||||
virtual char *ShowValue(char *buf, int len = 0) = 0;
|
virtual char *ShowValue(char *buf, int len = 0) = 0;
|
||||||
virtual char *GetCharString(char *p) = 0;
|
virtual char *GetCharString(char *p) = 0;
|
||||||
virtual bool IsEqual(PVAL vp, bool chktype) = 0;
|
virtual bool IsEqual(PVAL vp, bool chktype) = 0;
|
||||||
|
virtual bool Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op);
|
||||||
virtual bool FormatValue(PVAL vp, char *fmt) = 0;
|
virtual bool FormatValue(PVAL vp, char *fmt) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -149,9 +148,9 @@ class DllExport TYPVAL : public VALUE {
|
|||||||
virtual bool IsZero(void) {return Tval == 0;}
|
virtual bool IsZero(void) {return Tval == 0;}
|
||||||
virtual void Reset(void) {Tval = 0;}
|
virtual void Reset(void) {Tval = 0;}
|
||||||
virtual int GetValLen(void);
|
virtual int GetValLen(void);
|
||||||
virtual int GetValPrec() {return 0;}
|
virtual int GetValPrec() {return Prec;}
|
||||||
virtual int GetSize(void) {return sizeof(TYPE);}
|
virtual int GetSize(void) {return sizeof(TYPE);}
|
||||||
virtual PSZ GetCharValue(void) {return VALUE::GetCharValue();}
|
//virtual PSZ GetCharValue(void) {return VALUE::GetCharValue();}
|
||||||
virtual char GetTinyValue(void) {return (char)Tval;}
|
virtual char GetTinyValue(void) {return (char)Tval;}
|
||||||
virtual uchar GetUTinyValue(void) {return (uchar)Tval;}
|
virtual uchar GetUTinyValue(void) {return (uchar)Tval;}
|
||||||
virtual short GetShortValue(void) {return (short)Tval;}
|
virtual short GetShortValue(void) {return (short)Tval;}
|
||||||
@@ -184,12 +183,18 @@ class DllExport TYPVAL : public VALUE {
|
|||||||
virtual char *ShowValue(char *buf, int);
|
virtual char *ShowValue(char *buf, int);
|
||||||
virtual char *GetCharString(char *p);
|
virtual char *GetCharString(char *p);
|
||||||
virtual bool IsEqual(PVAL vp, bool chktype);
|
virtual bool IsEqual(PVAL vp, bool chktype);
|
||||||
|
virtual bool Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op);
|
||||||
virtual bool SetConstFormat(PGLOBAL, FORMAT&);
|
virtual bool SetConstFormat(PGLOBAL, FORMAT&);
|
||||||
virtual bool FormatValue(PVAL vp, char *fmt);
|
virtual bool FormatValue(PVAL vp, char *fmt);
|
||||||
virtual void Print(PGLOBAL g, FILE *, uint);
|
virtual void Print(PGLOBAL g, FILE *, uint);
|
||||||
virtual void Print(PGLOBAL g, char *, uint);
|
virtual void Print(PGLOBAL g, char *, uint);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
//static TYPE MinMaxVal(bool b);
|
||||||
|
// TYPE SafeAdd(TYPE n1, TYPE n2);
|
||||||
|
// TYPE SafeMult(TYPE n1, TYPE n2);
|
||||||
|
bool Compall(PGLOBAL g, PVAL *vp, int np, OPVAL op);
|
||||||
|
|
||||||
// Default constructor not to be used
|
// Default constructor not to be used
|
||||||
TYPVAL(void) : VALUE(TYPE_ERROR) {}
|
TYPVAL(void) : VALUE(TYPE_ERROR) {}
|
||||||
|
|
||||||
@@ -253,6 +258,7 @@ class DllExport TYPVAL<PSZ>: public VALUE {
|
|||||||
virtual char *ShowValue(char *buf, int);
|
virtual char *ShowValue(char *buf, int);
|
||||||
virtual char *GetCharString(char *p);
|
virtual char *GetCharString(char *p);
|
||||||
virtual bool IsEqual(PVAL vp, bool chktype);
|
virtual bool IsEqual(PVAL vp, bool chktype);
|
||||||
|
virtual bool Compute(PGLOBAL g, PVAL *vp, int np, OPVAL op);
|
||||||
virtual bool FormatValue(PVAL vp, char *fmt);
|
virtual bool FormatValue(PVAL vp, char *fmt);
|
||||||
virtual bool SetConstFormat(PGLOBAL, FORMAT&);
|
virtual bool SetConstFormat(PGLOBAL, FORMAT&);
|
||||||
|
|
||||||
|
@@ -209,6 +209,7 @@ class DllExport TDBASE : public TDB {
|
|||||||
int Knum; // Size of key arrays
|
int Knum; // Size of key arrays
|
||||||
bool Read_Only; // True for read only tables
|
bool Read_Only; // True for read only tables
|
||||||
const CHARSET_INFO *m_data_charset;
|
const CHARSET_INFO *m_data_charset;
|
||||||
|
const char *csname; // Table charset name
|
||||||
}; // end of class TDBASE
|
}; // end of class TDBASE
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
Reference in New Issue
Block a user