Commit 614611d7 authored by Olivier Bertrand's avatar Olivier Bertrand

- Fix MDEV-13621 JDBC UPDATE containing single or double quote chars produces wrong result

  in ha_connect::GetStringOption
  modified:   storage/connect/ha_connect.cc

- Begin implement data type BINARY
  modified:   storage/connect/ha_connect.cc
  modified:   storage/connect/myutil.cpp
  modified:   storage/connect/valblk.cpp
  modified:   storage/connect/valblk.h
  modified:   storage/connect/value.cpp

- Fix MDEV-12422 CONNECT Engine to support CHECK TABLE
  Adding a fake check function returning HA_ADMIN_OK.
  modified:   storage/connect/ha_connect.h

- Treat TBL (thread) as local when connected to the current server
  and return by timeout when a TBL remote table connection fail (Thread only)
  modified:   storage/connect/myconn.cpp
  modified:   storage/connect/tabmysql.h
  modified:   storage/connect/tabtbl.cpp
  modified:   storage/connect/tabtbl.h

- Update some tests and result files
  modified:   storage/connect/mysql-test/connect/r/tbl_thread.result
  modified:   storage/connect/mysql-test/connect/t/tbl_thread.test
  modified:   storage/connect/mysql-test/connect/r/updelx.result

- Add the GetCsName function
  modified:   storage/connect/reldef.h
parent 2db52e17
...@@ -1285,9 +1285,15 @@ PCSZ ha_connect::GetStringOption(PCSZ opname, PCSZ sdef) ...@@ -1285,9 +1285,15 @@ PCSZ ha_connect::GetStringOption(PCSZ opname, PCSZ sdef)
else else
opval= GetListOption(xp->g, opname, options->oplist); opval= GetListOption(xp->g, opname, options->oplist);
} else if (!stricmp(opname, "Query_String")) } else if (!stricmp(opname, "Query_String")) {
opval= thd_query_string(table->in_use)->str; // This escapes everything and returns a wrong query
else if (!stricmp(opname, "Partname")) // opval = thd_query_string(table->in_use)->str;
size_t len = thd_query_string(table->in_use)->length;
opval = (PCSZ)PlugSubAlloc(xp->g, NULL, len + 1);
sprintf((char*)opval, "%s", thd_query_string(table->in_use)->str);
((char*)opval)[len] = 0;
} else if (!stricmp(opname, "Partname"))
opval= partname; opval= partname;
else if (!stricmp(opname, "Table_charset")) { else if (!stricmp(opname, "Table_charset")) {
const CHARSET_INFO *chif= (tshp) ? tshp->table_charset const CHARSET_INFO *chif= (tshp) ? tshp->table_charset
...@@ -1501,8 +1507,9 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf) ...@@ -1501,8 +1507,9 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
switch (pcf->Type) { switch (pcf->Type) {
case TYPE_STRING: case TYPE_STRING:
case TYPE_BIN:
// Do something for case // Do something for case
cp= fp->charset()->name; cp= chset;
// Find if collation name ends by _ci // Find if collation name ends by _ci
if (!strcmp(cp + strlen(cp) - 3, "_ci")) { if (!strcmp(cp + strlen(cp) - 3, "_ci")) {
...@@ -2114,6 +2121,11 @@ int ha_connect::MakeRecord(char *buf) ...@@ -2114,6 +2121,11 @@ int ha_connect::MakeRecord(char *buf)
charset= tdbp->data_charset(); charset= tdbp->data_charset();
rc= fp->store(p, strlen(p), charset, CHECK_FIELD_WARN); rc= fp->store(p, strlen(p), charset, CHECK_FIELD_WARN);
break; break;
case TYPE_BIN:
p = value->GetCharValue();
charset = &my_charset_bin;
rc = fp->store(p, strlen(p), charset, CHECK_FIELD_WARN);
break;
case TYPE_DOUBLE: case TYPE_DOUBLE:
rc= fp->store(value->GetFloatValue()); rc= fp->store(value->GetFloatValue());
break; break;
......
...@@ -348,6 +348,13 @@ const char *GetValStr(OPVAL vop, bool neg); ...@@ -348,6 +348,13 @@ const char *GetValStr(OPVAL vop, bool neg);
PFIL CondFilter(PGLOBAL g, Item *cond); PFIL CondFilter(PGLOBAL g, Item *cond);
//PFIL CheckFilter(PGLOBAL g); //PFIL CheckFilter(PGLOBAL g);
/** admin commands - called from mysql_admin_table */
virtual int check(THD* thd, HA_CHECK_OPT* check_opt)
{
// TODO: implement it
return HA_ADMIN_OK; // Just to avoid error message with checktables
} // end of check
/** /**
Number of rows in table. It will only be called if Number of rows in table. It will only be called if
(table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0 (table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0
......
...@@ -472,7 +472,7 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db, ...@@ -472,7 +472,7 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
int pt, const char *csname) int pt, const char *csname)
{ {
const char *pipe = NULL; const char *pipe = NULL;
uint cto = 6000, nrt = 12000; uint cto = 10, nrt = 20;
my_bool my_true= 1; my_bool my_true= 1;
m_DB = mysql_init(NULL); m_DB = mysql_init(NULL);
...@@ -525,7 +525,8 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db, ...@@ -525,7 +525,8 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db,
mysql_options(m_DB, MYSQL_OPT_USE_THREAD_SPECIFIC_MEMORY, mysql_options(m_DB, MYSQL_OPT_USE_THREAD_SPECIFIC_MEMORY,
(char*)&my_true); (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 | CLIENT_REMEMBER_OPTIONS)) {
#if defined(_DEBUG) #if defined(_DEBUG)
sprintf(g->Message, "mysql_real_connect failed: (%d) %s", sprintf(g->Message, "mysql_real_connect failed: (%d) %s",
mysql_errno(m_DB), mysql_error(m_DB)); mysql_errno(m_DB), mysql_error(m_DB));
......
...@@ -35,6 +35,22 @@ a b ...@@ -35,6 +35,22 @@ a b
9 test09 9 test09
10 test10 10 test10
11 test11 11 test11
CREATE TABLE rt4 (a int, b char(10));
INSERT INTO rt4 VALUES (12,'test12'),(13,'test13'),(14,'test14'),(15,'test15');
SELECT * FROM rt4;
a b
12 test12
13 test13
14 test14
15 test15
CREATE TABLE rt5 (a int, b char(10));
INSERT INTO rt5 VALUES (16,'test16'),(17,'test17'),(18,'test18'),(19,'test19');
SELECT * FROM rt5;
a b
16 test16
17 test17
18 test18
19 test19
connection default; connection default;
CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:MASTER_PORT/test/rt2'; CONNECTION='mysql://root@127.0.0.1:MASTER_PORT/test/rt2';
...@@ -52,11 +68,35 @@ a b ...@@ -52,11 +68,35 @@ a b
9 test09 9 test09
10 test10 10 test10
11 test11 11 test11
CREATE TABLE t4 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/rt4';
SELECT * FROM t4;
a b
12 test12
13 test13
14 test14
15 test15
CREATE TABLE t5 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/rt5';
SELECT * FROM t5;
a b
16 test16
17 test17
18 test18
19 test19
CREATE TABLE total (a int, b char(10)) CREATE TABLE total (a int, b char(10))
ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2,t3' ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2,t3,t4,t5'
OPTION_LIST='thread=yes,port=PORT'; OPTION_LIST='thread=yes,port=PORT';
SELECT * FROM total order by a desc; SELECT * FROM total order by a desc;
a b a b
19 test19
18 test18
17 test17
16 test16
15 test15
14 test14
13 test13
12 test12
11 test11 11 test11
10 test10 10 test10
9 test09 9 test09
...@@ -72,9 +112,9 @@ a b ...@@ -72,9 +112,9 @@ a b
connection master; connection master;
DROP TABLE rt2; DROP TABLE rt2;
connection slave; connection slave;
DROP TABLE rt3; DROP TABLE rt3,rt4,rt5;
connection default; connection default;
DROP TABLE t1,t2,t3,total; DROP TABLE t1,t2,t3,t4,t5,total;
# #
# Old thread TBL tables test modified # Old thread TBL tables test modified
# #
...@@ -95,6 +135,22 @@ DROP TABLE t1,t2,total; ...@@ -95,6 +135,22 @@ DROP TABLE t1,t2,total;
# #
# Old thread TBL tables test not modified (suppressed until MDEV-10179 is fixed) # Old thread TBL tables test not modified (suppressed until MDEV-10179 is fixed)
# #
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL SRCDEF='select 11 as v';
SELECT * FROM t1;
v
11
CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL SRCDEF='select 22 as v';
SELECT * FROM t2;
v
22
CREATE TABLE total (v BIGINT(20) UNSIGNED NOT NULL) ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2' OPTION_LIST='thread=yes,port=PORT';;
SELECT * FROM total order by v desc;
v
22
11
DROP TABLE total;
DROP TABLE t1;
DROP TABLE t2;
connection master; connection master;
DROP TABLE IF EXISTS connect.t1; DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect; DROP DATABASE IF EXISTS connect;
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
connection default; connection default;
let $PORT= `select @@port`;
--echo # --echo #
--echo # Checking thread TBL tables --echo # Checking thread TBL tables
--echo # --echo #
...@@ -24,6 +22,14 @@ CREATE TABLE rt3 (a int, b char(10)); ...@@ -24,6 +22,14 @@ CREATE TABLE rt3 (a int, b char(10));
INSERT INTO rt3 VALUES (8,'test08'),(9,'test09'),(10,'test10'),(11,'test11'); INSERT INTO rt3 VALUES (8,'test08'),(9,'test09'),(10,'test10'),(11,'test11');
SELECT * FROM rt3; SELECT * FROM rt3;
CREATE TABLE rt4 (a int, b char(10));
INSERT INTO rt4 VALUES (12,'test12'),(13,'test13'),(14,'test14'),(15,'test15');
SELECT * FROM rt4;
CREATE TABLE rt5 (a int, b char(10));
INSERT INTO rt5 VALUES (16,'test16'),(17,'test17'),(18,'test18'),(19,'test19');
SELECT * FROM rt5;
connection default; connection default;
--replace_result $MASTER_MYPORT MASTER_PORT --replace_result $MASTER_MYPORT MASTER_PORT
...@@ -36,9 +42,19 @@ eval CREATE TABLE t3 ENGINE=CONNECT TABLE_TYPE=MYSQL ...@@ -36,9 +42,19 @@ eval CREATE TABLE t3 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/rt3'; CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/rt3';
SELECT * FROM t3; SELECT * FROM t3;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE t4 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/rt4';
SELECT * FROM t4;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE t5 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/rt5';
SELECT * FROM t5;
--replace_result $PORT PORT --replace_result $PORT PORT
eval CREATE TABLE total (a int, b char(10)) eval CREATE TABLE total (a int, b char(10))
ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2,t3' ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2,t3,t4,t5'
OPTION_LIST='thread=yes,port=$PORT'; OPTION_LIST='thread=yes,port=$PORT';
SELECT * FROM total order by a desc; SELECT * FROM total order by a desc;
...@@ -48,11 +64,11 @@ DROP TABLE rt2; ...@@ -48,11 +64,11 @@ DROP TABLE rt2;
connection slave; connection slave;
DROP TABLE rt3; DROP TABLE rt3,rt4,rt5;
connection default; connection default;
DROP TABLE t1,t2,t3,total; DROP TABLE t1,t2,t3,t4,t5,total;
--echo # --echo #
--echo # Old thread TBL tables test modified --echo # Old thread TBL tables test modified
...@@ -73,18 +89,18 @@ DROP TABLE t1,t2,total; ...@@ -73,18 +89,18 @@ DROP TABLE t1,t2,total;
--echo # --echo #
--echo # Old thread TBL tables test not modified (suppressed until MDEV-10179 is fixed) --echo # Old thread TBL tables test not modified (suppressed until MDEV-10179 is fixed)
--echo # --echo #
#CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL SRCDEF='select 11 as v'; CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL SRCDEF='select 11 as v';
#SELECT * FROM t1; SELECT * FROM t1;
#CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL SRCDEF='select 22 as v'; CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL SRCDEF='select 22 as v';
#SELECT * FROM t2; SELECT * FROM t2;
#--replace_result $PORT PORT --replace_result $PORT PORT
#--eval CREATE TABLE total (v BIGINT(20) UNSIGNED NOT NULL) ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2' OPTION_LIST='thread=yes,port=$PORT'; --eval CREATE TABLE total (v BIGINT(20) UNSIGNED NOT NULL) ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2' OPTION_LIST='thread=yes,port=$PORT';
#SELECT * FROM total order by v desc; SELECT * FROM total order by v desc;
#DROP TABLE total; DROP TABLE total;
#DROP TABLE t1; DROP TABLE t1;
#DROP TABLE t2; DROP TABLE t2;
-- source myconn_cleanup.inc -- source myconn_cleanup.inc
...@@ -218,7 +218,7 @@ int MYSQLtoPLG(int mytype, char *var) ...@@ -218,7 +218,7 @@ int MYSQLtoPLG(int mytype, char *var)
case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VARCHAR:
#endif // !ALPHA) #endif // !ALPHA)
case MYSQL_TYPE_STRING: case MYSQL_TYPE_STRING:
type = TYPE_STRING; type = (*var == 'B') ? TYPE_BIN : TYPE_STRING;
break; break;
case MYSQL_TYPE_BLOB: case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_TINY_BLOB:
...@@ -232,7 +232,7 @@ int MYSQLtoPLG(int mytype, char *var) ...@@ -232,7 +232,7 @@ int MYSQLtoPLG(int mytype, char *var)
type = TYPE_STRING; type = TYPE_STRING;
*var = 'X'; *var = 'X';
} else } else
type = TYPE_ERROR; type = TYPE_BIN;
break; break;
case TPC_SKIP: case TPC_SKIP:
......
...@@ -94,6 +94,7 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */ ...@@ -94,6 +94,7 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */
virtual void SetIndx(PIXDEF) {} virtual void SetIndx(PIXDEF) {}
virtual bool IsHuge(void) {return false;} virtual bool IsHuge(void) {return false;}
const CHARSET_INFO *data_charset() {return m_data_charset;} const CHARSET_INFO *data_charset() {return m_data_charset;}
const char *GetCsName(void) {return csname;}
// Methods // Methods
int GetColCatInfo(PGLOBAL g); int GetColCatInfo(PGLOBAL g);
......
...@@ -69,6 +69,7 @@ class MYSQLDEF : public EXTDEF {/* Logical table description */ ...@@ -69,6 +69,7 @@ class MYSQLDEF : public EXTDEF {/* Logical table description */
/***********************************************************************/ /***********************************************************************/
class TDBMYSQL : public TDBEXT { class TDBMYSQL : public TDBEXT {
friend class MYSQLCOL; friend class MYSQLCOL;
friend class TDBTBM;
public: public:
// Constructor // Constructor
TDBMYSQL(PMYDEF tdp); TDBMYSQL(PMYDEF tdp);
......
...@@ -578,10 +578,19 @@ pthread_handler_t ThreadOpen(void *p) ...@@ -578,10 +578,19 @@ pthread_handler_t ThreadOpen(void *p)
// Try to open the connection // Try to open the connection
if (!cmp->Tap->GetTo_Tdb()->OpenDB(cmp->G)) { if (!cmp->Tap->GetTo_Tdb()->OpenDB(cmp->G)) {
pthread_mutex_lock(&tblmut); pthread_mutex_lock(&tblmut);
if (trace)
htrc("Table %s ready\n", cmp->Tap->GetName());
cmp->Ready = true; cmp->Ready = true;
pthread_mutex_unlock(&tblmut); pthread_mutex_unlock(&tblmut);
} else } else {
pthread_mutex_lock(&tblmut);
if (trace)
htrc("Opening %s failed\n", cmp->Tap->GetName());
cmp->Rc = RC_FX; cmp->Rc = RC_FX;
pthread_mutex_unlock(&tblmut);
} // endif OpenDB
my_thread_end(); my_thread_end();
} else } else
...@@ -632,6 +641,18 @@ int TDBTBM::RowNumber(PGLOBAL g, bool b) ...@@ -632,6 +641,18 @@ int TDBTBM::RowNumber(PGLOBAL g, bool b)
return Tdbp->RowNumber(g) + ((b) ? 0 : Rows); return Tdbp->RowNumber(g) + ((b) ? 0 : Rows);
} // end of RowNumber } // end of RowNumber
/***********************************************************************/
/* Returns true if this MYSQL table refers to a local table. */
/***********************************************************************/
bool TDBTBM::IsLocal(PTABLE tbp)
{
TDBMYSQL *tdbp = (TDBMYSQL*)tbp->GetTo_Tdb();
return ((!stricmp(tdbp->Host, "localhost") ||
!strcmp(tdbp->Host, "127.0.0.1")) &&
tdbp->Port == GetDefaultPort());
} // end of IsLocal
/***********************************************************************/ /***********************************************************************/
/* Initialyze table parallel processing. */ /* Initialyze table parallel processing. */
/***********************************************************************/ /***********************************************************************/
...@@ -644,7 +665,7 @@ bool TDBTBM::OpenTables(PGLOBAL g) ...@@ -644,7 +665,7 @@ bool TDBTBM::OpenTables(PGLOBAL g)
// Allocates the TBMT blocks for the tables // Allocates the TBMT blocks for the tables
for (tabp = Tablist; tabp; tabp = tabp->Next) for (tabp = Tablist; tabp; tabp = tabp->Next)
if (tabp->GetTo_Tdb()->GetAmType() == TYPE_AM_MYSQL) { if (tabp->GetTo_Tdb()->GetAmType() == TYPE_AM_MYSQL && !IsLocal(tabp)) {
// Remove remote table from the local list // Remove remote table from the local list
*ptabp = tabp->Next; *ptabp = tabp->Next;
...@@ -788,7 +809,7 @@ int TDBTBM::ReadDB(PGLOBAL g) ...@@ -788,7 +809,7 @@ int TDBTBM::ReadDB(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
int TDBTBM::ReadNextRemote(PGLOBAL g) int TDBTBM::ReadNextRemote(PGLOBAL g)
{ {
bool b = false; bool b;
if (Tdbp) if (Tdbp)
Tdbp->CloseDB(g); Tdbp->CloseDB(g);
...@@ -796,9 +817,12 @@ int TDBTBM::ReadNextRemote(PGLOBAL g) ...@@ -796,9 +817,12 @@ int TDBTBM::ReadNextRemote(PGLOBAL g)
Cmp = NULL; Cmp = NULL;
retry: retry:
b = false;
// Search for a remote table having its result set // Search for a remote table having its result set
pthread_mutex_lock(&tblmut); pthread_mutex_lock(&tblmut);
for (PTBMT tp = Tmp; tp; tp = tp->Next) for (PTBMT tp = Tmp; tp; tp = tp->Next)
if (tp->Rc != RC_FX) {
if (tp->Ready) { if (tp->Ready) {
if (!tp->Complete) { if (!tp->Complete) {
Cmp = tp; Cmp = tp;
...@@ -808,6 +832,8 @@ int TDBTBM::ReadNextRemote(PGLOBAL g) ...@@ -808,6 +832,8 @@ int TDBTBM::ReadNextRemote(PGLOBAL g)
} else } else
b = true; b = true;
} // endif Rc
pthread_mutex_unlock(&tblmut); pthread_mutex_unlock(&tblmut);
if (!Cmp) { if (!Cmp) {
......
...@@ -146,6 +146,7 @@ class DllExport TDBTBM : public TDBTBL { ...@@ -146,6 +146,7 @@ class DllExport TDBTBM : public TDBTBL {
protected: protected:
// Internal functions // Internal functions
bool IsLocal(PTABLE tbp);
bool OpenTables(PGLOBAL g); bool OpenTables(PGLOBAL g);
int ReadNextRemote(PGLOBAL g); int ReadNextRemote(PGLOBAL g);
......
...@@ -59,11 +59,12 @@ PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len, ...@@ -59,11 +59,12 @@ PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len,
switch (type) { switch (type) {
case TYPE_STRING: case TYPE_STRING:
case TYPE_BIN:
case TYPE_DECIM: case TYPE_DECIM:
if (len) if (len)
blkp = new(g) CHRBLK(mp, nval, len, prec, blank); blkp = new(g) CHRBLK(mp, nval, type, len, prec, blank);
else else
blkp = new(g) STRBLK(g, mp, nval); blkp = new(g) STRBLK(g, mp, nval, type);
break; break;
case TYPE_SHORT: case TYPE_SHORT:
...@@ -615,8 +616,8 @@ int TYPBLK<TYPE>::GetMaxLength(void) ...@@ -615,8 +616,8 @@ int TYPBLK<TYPE>::GetMaxLength(void)
/***********************************************************************/ /***********************************************************************/
/* Constructor. */ /* Constructor. */
/***********************************************************************/ /***********************************************************************/
CHRBLK::CHRBLK(void *mp, int nval, int len, int prec, bool blank) CHRBLK::CHRBLK(void *mp, int nval, int type, int len, int prec, bool blank)
: VALBLK(mp, TYPE_STRING, nval), Chrp((char*&)Blkp) : VALBLK(mp, type, nval), Chrp((char*&)Blkp)
{ {
Valp = NULL; Valp = NULL;
Blanks = blank; Blanks = blank;
...@@ -1008,8 +1009,8 @@ int CHRBLK::GetMaxLength(void) ...@@ -1008,8 +1009,8 @@ int CHRBLK::GetMaxLength(void)
/***********************************************************************/ /***********************************************************************/
/* Constructor. */ /* Constructor. */
/***********************************************************************/ /***********************************************************************/
STRBLK::STRBLK(PGLOBAL g, void *mp, int nval) STRBLK::STRBLK(PGLOBAL g, void *mp, int nval, int type)
: VALBLK(mp, TYPE_STRING, nval), Strp((PSZ*&)Blkp) : VALBLK(mp, type, nval), Strp((PSZ*&)Blkp)
{ {
Global = g; Global = g;
Nullable = true; Nullable = true;
......
...@@ -214,7 +214,7 @@ class TYPBLK : public VALBLK { ...@@ -214,7 +214,7 @@ class TYPBLK : public VALBLK {
class CHRBLK : public VALBLK { class CHRBLK : public VALBLK {
public: public:
// Constructors // Constructors
CHRBLK(void *mp, int size, int len, int prec, bool b); CHRBLK(void *mp, int size, int type, int len, int prec, bool b);
// Implementation // Implementation
virtual bool Init(PGLOBAL g, bool check); virtual bool Init(PGLOBAL g, bool check);
...@@ -267,7 +267,7 @@ class CHRBLK : public VALBLK { ...@@ -267,7 +267,7 @@ class CHRBLK : public VALBLK {
class STRBLK : public VALBLK { class STRBLK : public VALBLK {
public: public:
// Constructors // Constructors
STRBLK(PGLOBAL g, void *mp, int size); STRBLK(PGLOBAL g, void *mp, int size, int type);
// Implementation // Implementation
virtual void SetNull(int n, bool b) {if (b) {Strp[n] = NULL;}} virtual void SetNull(int n, bool b) {if (b) {Strp[n] = NULL;}}
...@@ -345,7 +345,7 @@ class PTRBLK : public STRBLK { ...@@ -345,7 +345,7 @@ class PTRBLK : public STRBLK {
bool, bool, bool); bool, bool, bool);
protected: protected:
// Constructors // Constructors
PTRBLK(PGLOBAL g, void *mp, int size) : STRBLK(g, mp, size) {} PTRBLK(PGLOBAL g, void *mp, int size) : STRBLK(g, mp, size, TYPE_PCHAR) {}
// Implementation // Implementation
......
...@@ -236,6 +236,7 @@ bool IsTypeChar(int type) ...@@ -236,6 +236,7 @@ bool IsTypeChar(int type)
switch (type) { switch (type) {
case TYPE_STRING: case TYPE_STRING:
case TYPE_DECIM: case TYPE_DECIM:
case TYPE_BIN:
return true; return true;
} // endswitch type } // endswitch type
...@@ -1857,7 +1858,8 @@ int DECVAL::CompareValue(PVAL vp) ...@@ -1857,7 +1858,8 @@ int DECVAL::CompareValue(PVAL vp)
BINVAL::BINVAL(PGLOBAL g, void *p, int cl, int n) : VALUE(TYPE_BIN) BINVAL::BINVAL(PGLOBAL g, void *p, int cl, int n) : VALUE(TYPE_BIN)
{ {
assert(g); assert(g);
Len = n; //Len = n;
Len = (g) ? n : (p) ? strlen((char*)p) : 0;
Clen = cl; Clen = cl;
Binp = PlugSubAlloc(g, NULL, Clen + 1); Binp = PlugSubAlloc(g, NULL, Clen + 1);
memset(Binp, 0, Clen + 1); memset(Binp, 0, Clen + 1);
...@@ -1991,10 +1993,15 @@ bool BINVAL::SetValue_pval(PVAL valp, bool chktype) ...@@ -1991,10 +1993,15 @@ bool BINVAL::SetValue_pval(PVAL valp, bool chktype)
return true; return true;
if (!(Null = valp->IsNull() && Nullable)) { if (!(Null = valp->IsNull() && Nullable)) {
int len = Len;
if ((rc = (Len = valp->GetSize()) > Clen)) if ((rc = (Len = valp->GetSize()) > Clen))
Len = Clen; Len = Clen;
else if (len > Len)
memset(Binp, 0, len);
memcpy(Binp, valp->GetTo_Val(), Len); memcpy(Binp, valp->GetTo_Val(), Len);
((char*)Binp)[Len] = 0;
} else } else
Reset(); Reset();
...@@ -2011,9 +2018,14 @@ bool BINVAL::SetValue_char(const char *p, int n) ...@@ -2011,9 +2018,14 @@ bool BINVAL::SetValue_char(const char *p, int n)
bool rc; bool rc;
if (p && n > 0) { if (p && n > 0) {
rc = n > Clen; int len = Len;
Len = MY_MIN(n, Clen);
if (len > (Len = MY_MIN(n, Clen)))
memset(Binp, 0, len);
memcpy(Binp, p, Len); memcpy(Binp, p, Len);
((char*)Binp)[Len] = 0;
rc = n > Clen;
Null = false; Null = false;
} else { } else {
rc = false; rc = false;
...@@ -2030,8 +2042,13 @@ bool BINVAL::SetValue_char(const char *p, int n) ...@@ -2030,8 +2042,13 @@ bool BINVAL::SetValue_char(const char *p, int n)
void BINVAL::SetValue_psz(PCSZ s) void BINVAL::SetValue_psz(PCSZ s)
{ {
if (s) { if (s) {
Len = MY_MIN(Clen, (signed)strlen(s)); int len = Len;
if (len > (Len = MY_MIN(Clen, (signed)strlen(s))))
memset(Binp, 0, len);
memcpy(Binp, s, Len); memcpy(Binp, s, Len);
((char*)Binp)[Len] = 0;
Null = false; Null = false;
} else { } else {
Reset(); Reset();
...@@ -2052,13 +2069,18 @@ void BINVAL::SetValue_pvblk(PVBLK blk, int n) ...@@ -2052,13 +2069,18 @@ void BINVAL::SetValue_pvblk(PVBLK blk, int n)
Reset(); Reset();
Null = Nullable; Null = Nullable;
} else if (vp != Binp) { } else if (vp != Binp) {
int len = Len;
if (blk->GetType() == TYPE_STRING) if (blk->GetType() == TYPE_STRING)
Len = strlen((char*)vp); Len = strlen((char*)vp);
else else
Len = blk->GetVlen(); Len = blk->GetVlen();
Len = MY_MIN(Clen, Len); if (len > (Len = MY_MIN(Clen, Len)))
memset(Binp, 0, len);
memcpy(Binp, vp, Len); memcpy(Binp, vp, Len);
((char*)Binp)[Len] = 0;
Null = false; Null = false;
} // endif vp } // endif vp
...@@ -2070,6 +2092,9 @@ void BINVAL::SetValue_pvblk(PVBLK blk, int n) ...@@ -2070,6 +2092,9 @@ void BINVAL::SetValue_pvblk(PVBLK blk, int n)
void BINVAL::SetValue(int n) void BINVAL::SetValue(int n)
{ {
if (Clen >= 4) { if (Clen >= 4) {
if (Len > 4)
memset(Binp, 0, Len);
*((int*)Binp) = n; *((int*)Binp) = n;
Len = 4; Len = 4;
} else } else
...@@ -2083,6 +2108,9 @@ void BINVAL::SetValue(int n) ...@@ -2083,6 +2108,9 @@ void BINVAL::SetValue(int n)
void BINVAL::SetValue(uint n) void BINVAL::SetValue(uint n)
{ {
if (Clen >= 4) { if (Clen >= 4) {
if (Len > 4)
memset(Binp, 0, Len);
*((uint*)Binp) = n; *((uint*)Binp) = n;
Len = 4; Len = 4;
} else } else
...@@ -2096,6 +2124,9 @@ void BINVAL::SetValue(uint n) ...@@ -2096,6 +2124,9 @@ void BINVAL::SetValue(uint n)
void BINVAL::SetValue(short i) void BINVAL::SetValue(short i)
{ {
if (Clen >= 2) { if (Clen >= 2) {
if (Len > 2)
memset(Binp, 0, Len);
*((int*)Binp) = i; *((int*)Binp) = i;
Len = 2; Len = 2;
} else } else
...@@ -2109,6 +2140,9 @@ void BINVAL::SetValue(short i) ...@@ -2109,6 +2140,9 @@ void BINVAL::SetValue(short i)
void BINVAL::SetValue(ushort i) void BINVAL::SetValue(ushort i)
{ {
if (Clen >= 2) { if (Clen >= 2) {
if (Len > 2)
memset(Binp, 0, Len);
*((uint*)Binp) = i; *((uint*)Binp) = i;
Len = 2; Len = 2;
} else } else
...@@ -2122,6 +2156,9 @@ void BINVAL::SetValue(ushort i) ...@@ -2122,6 +2156,9 @@ void BINVAL::SetValue(ushort i)
void BINVAL::SetValue(longlong n) void BINVAL::SetValue(longlong n)
{ {
if (Clen >= 8) { if (Clen >= 8) {
if (Len > 8)
memset(Binp, 0, Len);
*((longlong*)Binp) = n; *((longlong*)Binp) = n;
Len = 8; Len = 8;
} else } else
...@@ -2135,6 +2172,9 @@ void BINVAL::SetValue(longlong n) ...@@ -2135,6 +2172,9 @@ void BINVAL::SetValue(longlong n)
void BINVAL::SetValue(ulonglong n) void BINVAL::SetValue(ulonglong n)
{ {
if (Clen >= 8) { if (Clen >= 8) {
if (Len > 8)
memset(Binp, 0, Len);
*((ulonglong*)Binp) = n; *((ulonglong*)Binp) = n;
Len = 8; Len = 8;
} else } else
...@@ -2146,6 +2186,9 @@ void BINVAL::SetValue(ulonglong n) ...@@ -2146,6 +2186,9 @@ void BINVAL::SetValue(ulonglong n)
/***********************************************************************/ /***********************************************************************/
void BINVAL::SetValue(double n) void BINVAL::SetValue(double n)
{ {
if (Len > 8)
memset(Binp, 0, Len);
if (Clen >= 8) { if (Clen >= 8) {
*((double*)Binp) = n; *((double*)Binp) = n;
Len = 8; Len = 8;
...@@ -2162,6 +2205,9 @@ void BINVAL::SetValue(double n) ...@@ -2162,6 +2205,9 @@ void BINVAL::SetValue(double n)
/***********************************************************************/ /***********************************************************************/
void BINVAL::SetValue(char c) void BINVAL::SetValue(char c)
{ {
if (Len > 1)
memset(Binp, 0, Len);
*((char*)Binp) = c; *((char*)Binp) = c;
Len = 1; Len = 1;
} // end of SetValue } // end of SetValue
...@@ -2171,6 +2217,9 @@ void BINVAL::SetValue(char c) ...@@ -2171,6 +2217,9 @@ void BINVAL::SetValue(char c)
/***********************************************************************/ /***********************************************************************/
void BINVAL::SetValue(uchar c) void BINVAL::SetValue(uchar c)
{ {
if (Len > 1)
memset(Binp, 0, Len);
*((uchar*)Binp) = c; *((uchar*)Binp) = c;
Len = 1; Len = 1;
} // end of SetValue } // end of SetValue
...@@ -2181,6 +2230,7 @@ void BINVAL::SetValue(uchar c) ...@@ -2181,6 +2230,7 @@ void BINVAL::SetValue(uchar c)
void BINVAL::SetBinValue(void *p) void BINVAL::SetBinValue(void *p)
{ {
memcpy(Binp, p, Clen); memcpy(Binp, p, Clen);
Len = Clen;
} // end of SetBinValue } // end of SetBinValue
/***********************************************************************/ /***********************************************************************/
...@@ -2206,10 +2256,11 @@ bool BINVAL::GetBinValue(void *buf, int buflen, bool go) ...@@ -2206,10 +2256,11 @@ bool BINVAL::GetBinValue(void *buf, int buflen, bool go)
/***********************************************************************/ /***********************************************************************/
char *BINVAL::ShowValue(char *buf, int len) char *BINVAL::ShowValue(char *buf, int len)
{ {
int n = MY_MIN(Len, len / 2); //int n = MY_MIN(Len, len / 2);
sprintf(buf, GetXfmt(), n, Binp); //sprintf(buf, GetXfmt(), n, Binp);
return buf; //return buf;
return (char*)Binp;
} // end of ShowValue } // end of ShowValue
/***********************************************************************/ /***********************************************************************/
......
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