Commit ee2f0445 authored by Olivier Bertrand's avatar Olivier Bertrand

- Add support for unsigned numeric types

added:
  storage/connect/mysql-test/connect/r/unsigned.result
  storage/connect/mysql-test/connect/t/unsigned.test
modified:
  storage/connect/colblk.cpp
  storage/connect/colblk.h
  storage/connect/connect.cc
  storage/connect/ha_connect.cc
  storage/connect/myconn.cpp
  storage/connect/mysql-test/connect/r/mysql_discovery.result
  storage/connect/mysql-test/connect/r/xml.result
  storage/connect/myutil.cpp
  storage/connect/myutil.h
  storage/connect/plgdbsem.h
  storage/connect/tabdos.cpp
  storage/connect/tabfix.cpp
  storage/connect/tabmysql.cpp
  storage/connect/tabutil.cpp
  storage/connect/valblk.cpp
  storage/connect/valblk.h
  storage/connect/value.cpp
  storage/connect/value.h
  storage/connect/xobject.cpp
  storage/connect/xobject.h
parent d240a041
......@@ -41,6 +41,7 @@ COLBLK::COLBLK(PCOLDEF cdp, PTDB tdbp, int i)
Buf_Type = cdp->Buf_Type;
ColUse |= cdp->Flags; // Used by CONNECT
Nullable = !!(cdp->Flags & U_NULLS);
Unsigned = !!(cdp->Flags & U_UNSIGNED);
} else {
Name = NULL;
memset(&Format, 0, sizeof(FORMAT));
......@@ -48,6 +49,7 @@ COLBLK::COLBLK(PCOLDEF cdp, PTDB tdbp, int i)
Long = 0;
Buf_Type = TYPE_ERROR;
Nullable = false;
Unsigned = false;
} // endif cdp
To_Tdb = tdbp;
......@@ -171,9 +173,12 @@ bool COLBLK::InitValue(PGLOBAL g)
if (Value)
return false; // Already done
// Unsigned can be set only for valid value types
int prec = (Unsigned) ? 1 : GetPrecision();
// Allocate a Value object
if (!(Value = AllocateValue(g, Buf_Type, Format.Length,
GetPrecision(), GetDomain())))
prec, GetDomain())))
return true;
AddStatus(BUF_READY);
......
......@@ -83,6 +83,7 @@ class DllExport COLBLK : public XOBJECT {
PTDB To_Tdb; // Points to Table Descriptor Block
PXCOL To_Kcol; // Points to Xindex matching column
bool Nullable; // True if nullable
bool Unsigned; // True if unsigned
int Index; // Column number in table
int Opt; // Cluster/sort information
int Buf_Type; // Data type
......
......@@ -685,6 +685,7 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
char *kp= (char*)key;
int n;
short lg;
bool rcb;
RCODE rc;
PVAL valp;
PCOL colp;
......@@ -719,9 +720,20 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
if (colp->GetColUse(U_VAR)) {
lg= *(short*)kp;
kp+= sizeof(short);
valp->SetValue_char(kp, (int)lg);
rcb= valp->SetValue_char(kp, (int)lg);
} else
valp->SetValue_char(kp, valp->GetClen());
rcb= valp->SetValue_char(kp, valp->GetClen());
if (rcb) {
if (tdbp->RowNumber(g))
sprintf(g->Message, "Out of range value for column %s at row %d",
colp->GetName(), tdbp->RowNumber(g));
else
sprintf(g->Message, "Out of range value for column %s",
colp->GetName());
PushWarning(g, tdbp);
} // endif b
} else
valp->SetBinValue((void*)kp);
......@@ -759,7 +771,7 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
const uchar *p, *kp;
int i, n, k[2];
short lg;
bool b;
bool b, rcb;
PVAL valp;
PCOL colp;
PTDBDOX tdbp;
......@@ -802,9 +814,21 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
if (colp->GetColUse(U_VAR)) {
lg= *(short*)p;
p+= sizeof(short);
valp->SetValue_char((char*)p, (int)lg);
rcb= valp->SetValue_char((char*)p, (int)lg);
} else
valp->SetValue_char((char*)p, valp->GetClen());
rcb= valp->SetValue_char((char*)p, valp->GetClen());
if (rcb) {
if (tdbp->RowNumber(g))
sprintf(g->Message,
"Out of range value for column %s at row %d",
colp->GetName(), tdbp->RowNumber(g));
else
sprintf(g->Message, "Out of range value for column %s",
colp->GetName());
PushWarning(g, tdbp);
} // endif b
} else
valp->SetBinValue((void*)p);
......
......@@ -165,7 +165,7 @@ extern "C" char nmfile[];
extern "C" char pdebug[];
extern "C" {
char version[]= "Version 1.01.0009 October 29, 2013";
char version[]= "Version 1.01.0010 November 30, 2013";
#if defined(XMSG)
char msglang[]; // Default message language
......@@ -777,7 +777,7 @@ int ha_connect::GetIntegerOption(char *opname)
if (opval == (ulonglong)NO_IVAL && options && options->oplist)
if ((pv= GetListOption(xp->g, opname, options->oplist)))
opval= (unsigned)atoll(pv);
opval= CharToNumber(pv, strlen(pv), ULONGLONG_MAX, true);
return (int)opval;
} // end of GetIntegerOption
......@@ -936,6 +936,12 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
break;
} // endswitch type
if (fp->flags & UNSIGNED_FLAG)
pcf->Flags |= U_UNSIGNED;
if (fp->flags & ZEROFILL_FLAG)
pcf->Flags |= U_ZEROFILL;
// This is used to skip null bit
if (fp->real_maybe_null())
pcf->Flags |= U_NULLS;
......@@ -1341,7 +1347,15 @@ int ha_connect::MakeRecord(char *buf)
} else
if (fp->store(value->GetFloatValue())) {
rc= HA_ERR_WRONG_IN_RECORD;
// rc= HA_ERR_WRONG_IN_RECORD; a Warning was ignored
char buf[128];
THD *thd= ha_thd();
sprintf(buf, "Out of range value for column '%s' at row %ld",
fp->field_name,
thd->get_stmt_da()->current_row_for_warning());
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, buf);
DBUG_PRINT("MakeRecord", ("%s", value->GetCharString(val)));
} // endif store
......@@ -3511,7 +3525,7 @@ static bool add_fields(PGLOBAL g,
#else // !NEW_WAY
static bool add_field(String *sql, const char *field_name, int typ,
int len, int dec, uint tm, const char *rem,
int flag, bool dbf, char v)
char *dft, int flag, bool dbf, char v)
{
char var = (len > 255) ? 'V' : v;
bool error= false;
......@@ -3535,9 +3549,26 @@ static bool add_field(String *sql, const char *field_name, int typ,
error|= sql->append(')');
} // endif len
if (v == 'U')
error|= sql->append(" UNSIGNED");
else if (v == 'Z')
error|= sql->append(" ZEROFILL");
if (tm)
error|= sql->append(STRING_WITH_LEN(" NOT NULL"), system_charset_info);
if (dft && *dft) {
error|= sql->append(" DEFAULT ");
if (IsTypeChar(typ)) {
error|= sql->append("'");
error|= sql->append_for_single_quote(dft, strlen(dft));
error|= sql->append("'");
} else
error|= sql->append(dft);
} // endif rem
if (rem && *rem) {
error|= sql->append(" COMMENT '");
error|= sql->append_for_single_quote(rem, strlen(rem));
......@@ -4044,8 +4075,8 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
} // endif src
if (ok) {
char *cnm, *rem;
int i, len, dec, typ, flg;
char *cnm, *rem, *dft;
int i, len, prec, dec, typ, flg;
PDBUSER dup= PlgGetUser(g);
PCATLG cat= (dup) ? dup->Catalog : NULL;
......@@ -4154,16 +4185,17 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
NOT_NULL_FLAG, "", flg, dbf);
#else // !NEW_WAY
// Now add the field
if (add_field(&sql, cnm, typ, len, dec, NOT_NULL_FLAG, 0, flg, dbf, 0))
if (add_field(&sql, cnm, typ, len, dec, NOT_NULL_FLAG, 0, NULL, flg, dbf, 0))
rc= HA_ERR_OUT_OF_MEM;
#endif // !NEW_WAY
} // endfor crp
} else // Not a catalog table
for (i= 0; !rc && i < qrp->Nblin; i++) {
typ= len= dec= 0;
typ= len= prec= dec= 0;
tm= NOT_NULL_FLAG;
cnm= (char*)"noname";
dft= NULL;
#if defined(NEW_WAY)
rem= "";
// cs= NULL;
......@@ -4181,6 +4213,10 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
v = (crp->Nulls) ? crp->Nulls[i] : 0;
break;
case FLD_PREC:
// PREC must be always before LENGTH
len= prec= crp->Kdata->GetIntValue(i);
break;
case FLD_LENGTH:
len= crp->Kdata->GetIntValue(i);
break;
case FLD_SCALE:
......@@ -4200,6 +4236,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
// cs= get_charset_by_name(csn, 0);
// break;
case FLD_DEFAULT:
dft= crp->Kdata->GetCharValue(i);
break;
default:
break; // Ignore
} // endswitch Fld
......@@ -4209,16 +4248,16 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
int plgtyp;
// typ must be PLG type, not SQL type
if (!(plgtyp= TranslateSQLType(typ, dec, len, v))) {
if (!(plgtyp= TranslateSQLType(typ, dec, prec, v))) {
sprintf(g->Message, "Unsupported SQL type %d", typ);
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
return HA_ERR_INTERNAL_ERROR;
} else
typ= plgtyp;
// Some data sources do not count dec in length
// Some data sources do not count dec in length (prec)
if (typ == TYPE_FLOAT)
len += (dec + 2); // To be safe
prec += (dec + 2); // To be safe
else
dec= 0;
......@@ -4227,14 +4266,16 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
// Make the arguments as required by add_fields
if (typ == TYPE_DATE)
len= 0;
prec= 0;
else if (typ == TYPE_FLOAT)
prec= len;
// Now add the field
#if defined(NEW_WAY)
rc= add_fields(g, thd, &alter_info, cnm, typ, len, dec,
tm, rem, 0, true);
#else // !NEW_WAY
if (add_field(&sql, cnm, typ, len, dec, tm, rem, 0, dbf, v))
if (add_field(&sql, cnm, typ, prec, dec, tm, rem, dft, 0, dbf, v))
rc= HA_ERR_OUT_OF_MEM;
#endif // !NEW_WAY
} // endfor i
......
......@@ -46,21 +46,6 @@
#define DLL_EXPORT // Items are exported from this DLL
#include "myconn.h"
#if defined(EMBEDDED)
static char *server_args[] = {
"this_program", /* this string is not used */
"--skip-bdb",
"--skip-innodb"
};
static char *server_groups[] = {
"PlugDB_SERVER",
"embedded",
"server",
(char *)NULL
};
#endif // EMBEDDED
extern "C" int trace;
extern MYSQL_PLUGIN_IMPORT uint mysqld_port;
......@@ -82,12 +67,12 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
{
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
TYPE_STRING, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT,
TYPE_STRING, TYPE_STRING, TYPE_STRING};
TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING};
static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC,
FLD_KEY, FLD_SCALE, FLD_RADIX, FLD_NULL,
FLD_REM, FLD_NO, FLD_CHARSET};
static unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 256, 32, 32};
char *fld, *fmt, v, cmd[128];
FLD_REM, FLD_NO, FLD_DEFAULT, FLD_CHARSET};
static unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 32, 0, 32};
char *fld, *fmt, v, cmd[128], uns[16], zero[16];
int i, n, nf, ncol = sizeof(buftyp) / sizeof(int);
int len, type, prec, rc, k = 0;
PQRYRES qrp;
......@@ -122,9 +107,10 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
} // endif n
/********************************************************************/
/* Get the size of the name columns. */
/* Get the size of the name and default columns. */
/********************************************************************/
length[0] = myc.GetFieldLength(0);
length[10] = myc.GetFieldLength(5);
} else {
n = 0;
length[0] = 128;
......@@ -164,18 +150,29 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
crp = qrp->Colresp; // Column_Name
crp->Kdata->SetValue(fld, i);
// Get type, type name, and precision
// Get type, type name, precision, unsigned and zerofill
fld = myc.GetCharField(1);
prec = 0;
len = 0;
v = 0;
if ((nf = sscanf(fld, "%[^(](%d,%d", cmd, &len, &prec)) < 1) {
sprintf(g->Message, MSG(BAD_FIELD_TYPE), fld);
myc.Close();
return NULL;
} else
qrp->Nblin++;
*uns = 0;
*zero = 0;
switch ((nf = sscanf(fld, "%[^(](%d,%d", cmd, &len, &prec))) {
case 3:
nf = sscanf(fld, "%[^(](%d,%d) %s %s", cmd, &len, &prec, uns, zero);
break;
case 2:
nf = sscanf(fld, "%[^(](%d) %s %s", cmd, &len, uns, zero) + 1;
break;
case 1:
nf = sscanf(fld, "%s %s %s", cmd, uns, zero) + 2;
break;
default:
sprintf(g->Message, MSG(BAD_FIELD_TYPE), fld);
myc.Close();
return NULL;
} // endswitch nf
if ((type = MYSQLtoPLG(cmd, &v)) == TYPE_ERROR) {
sprintf(g->Message, "Unsupported column type %s", cmd);
......@@ -184,9 +181,16 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
} else if (type == TYPE_STRING)
len = min(len, 4096);
qrp->Nblin++;
crp = crp->Next; // Data_Type
crp->Kdata->SetValue(type, i);
crp->Nulls[i] = v;
switch (nf) {
case 5: crp->Nulls[i] = 'Z'; break;
case 4: crp->Nulls[i] = 'U'; break;
default: crp->Nulls[i] = v; break;
} // endswitch nf
crp = crp->Next; // Type_Name
crp->Kdata->SetValue(cmd, i);
......@@ -200,7 +204,7 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
crp = crp->Next; // Precision
crp->Kdata->SetValue(len, i);
crp = crp->Next; // was Length
crp = crp->Next; // key (was Length)
fld = myc.GetCharField(4);
crp->Kdata->SetValue(fld, i);
......@@ -218,9 +222,13 @@ PQRYRES MyColumns(PGLOBAL g, const char *host, const char *db,
fld = myc.GetCharField(8);
crp->Kdata->SetValue(fld, i);
crp = crp->Next; // New
crp = crp->Next; // Date format
crp->Kdata->SetValue((fmt) ? fmt : (char*) "", i);
crp = crp->Next; // New (default)
fld = myc.GetCharField(5);
crp->Kdata->SetValue(fld, i);
crp = crp->Next; // New (charset)
fld = myc.GetCharField(2);
crp->Kdata->SetValue(fld, i);
......@@ -657,6 +665,7 @@ PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb)
{
char *fmt;
int n;
bool uns;
PCOLRES *pcrp, crp;
PQRYRES qrp;
MYSQL_FIELD *fld;
......@@ -707,9 +716,10 @@ PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb)
crp->Prec = (crp->Type == TYPE_FLOAT) ? fld->decimals : 0;
crp->Length = fld->max_length;
crp->Clen = GetTypeSize(crp->Type, crp->Length);
uns = (fld->flags & (UNSIGNED_FLAG | ZEROFILL_FLAG)) ? true : false;
if (!(crp->Kdata = AllocValBlock(g, NULL, crp->Type, m_Rows,
crp->Clen, 0, FALSE, TRUE, FALSE))) {
crp->Clen, 0, FALSE, TRUE, uns))) {
sprintf(g->Message, MSG(INV_RESULT_TYPE),
GetFormatType(crp->Type));
return NULL;
......
......@@ -15,7 +15,7 @@ t1 CREATE TABLE `t1` (
`id` int(20) NOT NULL,
`group` int(11) NOT NULL,
`a\\b` int(11) NOT NULL,
`a\\` int(10) DEFAULT NULL,
`a\\` int(10) unsigned DEFAULT NULL,
`name` varchar(32) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1' `TABLE_TYPE`='MYSQL'
INSERT INTO t1 (id, name) VALUES (1, 'foo');
......
#
# Testing unsigned types
#
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 'test.t1'
CREATE TABLE t1 (
a TINYINT UNSIGNED NOT NULL,
b SMALLINT ZEROFILL NOT NULL,
c INT UNSIGNED NOT NULL,
d BIGINT UNSIGNED NOT NULL,
e CHAR(32) NOT NULL DEFAULT '???') ENGINE=CONNECT TABLE_TYPE=FIX;
Warnings:
Warning 1105 No file name. Table will use t1.fix
DESCRIBE t1;
Field Type Null Key Default Extra
a tinyint(3) unsigned NO NULL
b smallint(5) unsigned zerofill NO NULL
c int(10) unsigned NO NULL
d bigint(20) unsigned NO NULL
e char(32) NO ???
INSERT INTO t1(a,b,c,d) VALUES(255,65535,4294967295,18446744073709551615);
SELECT * FROM t1;
a b c d e
255 65535 4294967295 18446744073709551615 ???
UPDATE t1 SET e = d;
SELECT * FROM t1;
a b c d e
255 65535 4294967295 18446744073709551615 18446744073709551615
UPDATE t1 SET c = d;
Warnings:
Warning 1264 Out of range value for column 'c' at row 1
SELECT * FROM t1;
a b c d e
255 65535 4294967295 18446744073709551615 18446744073709551615
UPDATE t1 SET c = e;
Warnings:
Warning 1264 Out of range value for column 'c' at row 1
SELECT * FROM t1;
a b c d e
255 65535 4294967295 18446744073709551615 18446744073709551615
UPDATE t1 SET d = e;
SELECT * FROM t1;
a b c d e
255 65535 4294967295 18446744073709551615 18446744073709551615
DROP TABLE IF EXISTS t2;
Warnings:
Note 1051 Unknown table 'test.t2'
CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=PROXY TABNAME=t1;
DESCRIBE t2;
Field Type Null Key Default Extra
a tinyint(3) unsigned NO NULL
b smallint(5) unsigned zerofill NO NULL
c int(10) unsigned NO NULL
d bigint(20) unsigned NO NULL
e char(32) NO NULL
SELECT * FROM t2;
a b c d e
255 65535 4294967295 18446744073709551615 18446744073709551615
DROP TABLE t2;
CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME=t1;
DESCRIBE t2;
Field Type Null Key Default Extra
a tinyint(3) unsigned NO NULL
b smallint(5) unsigned zerofill NO NULL
c int(10) unsigned NO NULL
d bigint(20) unsigned NO NULL
e char(32) NO ???
SELECT * FROM t2;
a b c d e
255 65535 4294967295 18446744073709551615 18446744073709551615
DROP TABLE t2;
DROP TABLE t1;
......@@ -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.0009 October 29, 2013 -->
<!-- Created by CONNECT Version 1.01.0010 November 30, 2013 -->
<t1>
<line>
<node>ÀÁÂÃ</node>
......
--echo #
--echo # Testing unsigned types
--echo #
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (
a TINYINT UNSIGNED NOT NULL,
b SMALLINT ZEROFILL NOT NULL,
c INT UNSIGNED NOT NULL,
d BIGINT UNSIGNED NOT NULL,
e CHAR(32) NOT NULL DEFAULT '???') ENGINE=CONNECT TABLE_TYPE=FIX;
DESCRIBE t1;
INSERT INTO t1(a,b,c,d) VALUES(255,65535,4294967295,18446744073709551615);
SELECT * FROM t1;
UPDATE t1 SET e = d;
SELECT * FROM t1;
UPDATE t1 SET c = d;
SELECT * FROM t1;
UPDATE t1 SET c = e;
SELECT * FROM t1;
UPDATE t1 SET d = e;
SELECT * FROM t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=PROXY TABNAME=t1;
DESCRIBE t2;
SELECT * FROM t2;
DROP TABLE t2;
CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL TABNAME=t1;
DESCRIBE t2;
SELECT * FROM t2;
DROP TABLE t2;
DROP TABLE t1;
......@@ -143,7 +143,7 @@ const char *PLGtoMYSQLtype(int type, bool dbf, char v)
/************************************************************************/
/* Convert from MySQL type to PlugDB type number */
/************************************************************************/
int MYSQLtoPLG(int mytype)
int MYSQLtoPLG(int mytype, char *var)
{
int type;
......@@ -177,7 +177,6 @@ int MYSQLtoPLG(int mytype)
case MYSQL_TYPE_TIME:
type = TYPE_DATE;
break;
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_VAR_STRING:
#if !defined(ALPHA)
case MYSQL_TYPE_VARCHAR:
......@@ -186,6 +185,8 @@ int MYSQLtoPLG(int mytype)
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
if (var) *var = 'V';
case MYSQL_TYPE_STRING:
type = TYPE_STRING;
break;
default:
......
......@@ -7,7 +7,7 @@
enum enum_field_types PLGtoMYSQL(int type, bool dbf);
const char *PLGtoMYSQLtype(int type, bool dbf, char var = NULL);
int MYSQLtoPLG(char *typname, char *var = NULL);
int MYSQLtoPLG(int mytype);
int MYSQLtoPLG(int mytype, char *var = NULL);
char *MyDateFmt(int mytype);
char *MyDateFmt(char *typname);
......
......@@ -330,7 +330,9 @@ enum COLUSE {U_P = 0x01, /* the projection list. */
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_SPECIAL = 0x100}; /* The column is special */
U_SPECIAL = 0x100, /* The column is special */
U_UNSIGNED = 0x200, /* The column type is unsigned */
U_ZEROFILL = 0x400}; /* The column is zero filled */
/***********************************************************************/
/* DB description class and block pointer definitions. */
......
......@@ -1087,7 +1087,12 @@ void DOSCOL::ReadColumn(PGLOBAL g)
case TYPE_SHORT:
case TYPE_TINY:
case TYPE_BIGINT:
Value->SetValue_char(p, field - Dcm);
if (Value->SetValue_char(p, field - Dcm)) {
sprintf(g->Message, "Out of range value for column %s at row %d",
Name, tdbp->RowNumber(g));
PushWarning(g, tdbp);
} // endif SetValue_char
break;
case TYPE_FLOAT:
Value->SetValue_char(p, field);
......@@ -1104,7 +1109,11 @@ void DOSCOL::ReadColumn(PGLOBAL g)
} // endswitch Buf_Type
else
Value->SetValue_char(p, field);
if (Value->SetValue_char(p, field)) {
sprintf(g->Message, "Out of range value for column %s at row %d",
Name, tdbp->RowNumber(g));
PushWarning(g, tdbp);
} // endif SetValue_char
break;
default:
......
......@@ -375,7 +375,12 @@ void BINCOL::ReadColumn(PGLOBAL g)
Value->SetValue(*(double*)p);
break;
case 'C': // Text
Value->SetValue_char(p, Long);
if (Value->SetValue_char(p, Long)) {
sprintf(g->Message, "Out of range value for column %s at row %d",
Name, tdbp->RowNumber(g));
PushWarning(g, tdbp);
} // endif SetValue_char
break;
default:
sprintf(g->Message, MSG(BAD_BIN_FMT), Fmt, Name);
......
......@@ -1284,13 +1284,18 @@ void MYSQLCOL::ReadColumn(PGLOBAL g)
htrc("MySQL ReadColumn: name=%s buf=%s\n", Name, buf);
// TODO: have a true way to differenciate temporal values
if (strlen(buf) == 8)
if (Buf_Type == TYPE_DATE && strlen(buf) == 8)
// This is a TIME value
p = strcat(strcpy(tim, "1970-01-01 "), buf);
else
p = buf;
Value->SetValue_char(p, strlen(p));
if (Value->SetValue_char(p, strlen(p))) {
sprintf(g->Message, "Out of range value for column %s at row %d",
Name, tdbp->RowNumber(g));
PushWarning(g, tdbp);
} // endif SetValue_char
} else {
if (Nullable)
Value->SetNull(true);
......
......@@ -117,7 +117,7 @@ TABLE_SHARE *GetTableShare(PGLOBAL g, THD *thd, const char *db,
/************************************************************************/
/* TabColumns: constructs the result blocks containing all the columns */
/* of the object table that will be retrieved by GetData commands. */
/* description of the object table that will be retrieved by discovery.*/
/************************************************************************/
PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
const char *name, bool& info)
......@@ -128,8 +128,8 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC,
FLD_LENGTH, FLD_SCALE, FLD_RADIX, FLD_NULL,
FLD_REM, FLD_NO, FLD_CHARSET};
static unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 256, 32, 32};
char *fld, *fmt;
static unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 32, 32};
char *fld, *fmt, v;
int i, n, ncol = sizeof(buftyp) / sizeof(int);
int len, type, prec;
bool mysql;
......@@ -164,6 +164,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
// Some columns must be renamed
for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next)
switch (++i) {
case 2: crp->Nulls = (char*)PlugSubAlloc(g, NULL, n); break;
case 10: crp->Name = "Date_fmt"; break;
case 11: crp->Name = "Collation"; break;
} // endswitch i
......@@ -181,8 +182,9 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
crp = qrp->Colresp; // Column_Name
fld = (char *)fp->field_name;
crp->Kdata->SetValue(fld, i);
v = 0;
if ((type = MYSQLtoPLG(fp->type())) == TYPE_ERROR) {
if ((type = MYSQLtoPLG(fp->type(), &v)) == TYPE_ERROR) {
sprintf(g->Message, "Unsupported column type %s", GetTypeName(type));
qrp = NULL;
break;
......@@ -190,6 +192,14 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
crp = crp->Next; // Data_Type
crp->Kdata->SetValue(type, i);
if (fp->flags & ZEROFILL_FLAG)
crp->Nulls[i] = 'Z';
else if (fp->flags & UNSIGNED_FLAG)
crp->Nulls[i] = 'U';
else
crp->Nulls[i] = v;
crp = crp->Next; // Type_Name
crp->Kdata->SetValue(GetTypeName(type), i);
......@@ -200,7 +210,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
len = strlen(fmt);
} else {
fmt = (char*)fp->option_struct->dateformat;
len = fp->field_length;
fp->field_length;
} // endif mysql
} else {
......@@ -212,10 +222,10 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
crp->Kdata->SetValue(len, i);
crp = crp->Next; // Length
len = fp->field_length;
prec = (type == TYPE_FLOAT) ? fp->decimals() : 0;
len = (prec == 31) ? 0 : fp->field_length;
crp->Kdata->SetValue(len, i);
prec = (type == TYPE_FLOAT) ? fp->decimals() : 0;
crp = crp->Next; // Scale
crp->Kdata->SetValue(prec, i);
......@@ -233,7 +243,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
else
crp->Kdata->Reset(i);
crp = crp->Next; // New
crp = crp->Next; // New (date format)
crp->Kdata->SetValue((fmt) ? fmt : (char*) "", i);
crp = crp->Next; // New (charset)
......
This diff is collapsed.
......@@ -45,9 +45,12 @@ class VALBLK : public BLOCK {
{if (To_Nulls) {To_Nulls[n] = (b) ? '*' : 0;}}
virtual bool IsNull(int n) {return To_Nulls && To_Nulls[n];}
virtual void SetNullable(bool b);
virtual bool IsUnsigned(void) {return Unsigned;}
virtual void Init(PGLOBAL g, bool check) = 0;
virtual int GetVlen(void) = 0;
virtual PSZ GetCharValue(int n);
virtual char GetTinyValue(int n) = 0;
virtual uchar GetUTinyValue(int n) = 0;
virtual short GetShortValue(int n) = 0;
virtual ushort GetUShortValue(int n) = 0;
virtual int GetIntValue(int n) = 0;
......@@ -55,8 +58,6 @@ class VALBLK : public BLOCK {
virtual longlong GetBigintValue(int n) = 0;
virtual ulonglong GetUBigintValue(int n) = 0;
virtual double GetFloatValue(int n) = 0;
virtual char GetTinyValue(int n) = 0;
virtual uchar GetUTinyValue(int n) = 0;
virtual void ReAlloc(void *mp, int n) {Blkp = mp; Nval = n;}
virtual void Reset(int n) = 0;
virtual bool SetFormat(PGLOBAL g, PSZ fmt, int len, int year = 0);
......@@ -123,6 +124,8 @@ class TYPBLK : public VALBLK {
virtual void Init(PGLOBAL g, bool check);
virtual int GetVlen(void) {return sizeof(TYPE);}
//virtual PSZ GetCharValue(int n);
virtual char GetTinyValue(int n) {return (char)Typp[n];}
virtual uchar GetUTinyValue(int n) {return (uchar)Typp[n];}
virtual short GetShortValue(int n) {return (short)Typp[n];}
virtual ushort GetUShortValue(int n) {return (ushort)Typp[n];}
virtual int GetIntValue(int n) {return (int)Typp[n];}
......@@ -130,8 +133,6 @@ class TYPBLK : public VALBLK {
virtual longlong GetBigintValue(int n) {return (longlong)Typp[n];}
virtual ulonglong GetUBigintValue(int n) {return (ulonglong)Typp[n];}
virtual double GetFloatValue(int n) {return (double)Typp[n];}
virtual char GetTinyValue(int n) {return (char)Typp[n];}
virtual uchar GetUTinyValue(int n) {return (uchar)Typp[n];}
virtual void Reset(int n) {Typp[n] = 0;}
// Methods
......@@ -168,9 +169,9 @@ class TYPBLK : public VALBLK {
protected:
// Specialized functions
static ulonglong MaxVal(void);
TYPE GetTypedValue(PVAL vp);
TYPE GetTypedValue(PVBLK blk, int n);
TYPE GetTypedValue(PSZ s);
// Members
TYPE* const &Typp;
......@@ -189,6 +190,8 @@ class CHRBLK : public VALBLK {
virtual void Init(PGLOBAL g, bool check);
virtual int GetVlen(void) {return Long;}
virtual PSZ GetCharValue(int n);
virtual char GetTinyValue(int n);
virtual uchar GetUTinyValue(int n);
virtual short GetShortValue(int n);
virtual ushort GetUShortValue(int n);
virtual int GetIntValue(int n);
......@@ -196,8 +199,6 @@ class CHRBLK : public VALBLK {
virtual longlong GetBigintValue(int n);
virtual ulonglong GetUBigintValue(int n);
virtual double GetFloatValue(int n);
virtual char GetTinyValue(int n);
virtual uchar GetUTinyValue(int n);
virtual void Reset(int n);
virtual void SetPrec(int p) {Ci = (p != 0);}
virtual bool IsCi(void) {return Ci;}
......@@ -242,15 +243,15 @@ class STRBLK : public VALBLK {
virtual void Init(PGLOBAL g, bool check);
virtual int GetVlen(void) {return sizeof(PSZ);}
virtual PSZ GetCharValue(int n) {return Strp[n];}
virtual short GetShortValue(int n) {return (short)atoi(Strp[n]);}
virtual ushort GetUShortValue(int n) {return (ushort)atoi(Strp[n]);}
virtual int GetIntValue(int n) {return atol(Strp[n]);}
virtual uint GetUIntValue(int n) {return (unsigned)atol(Strp[n]);}
virtual longlong GetBigintValue(int n) {return atoll(Strp[n]);}
virtual ulonglong GetUBigintValue(int n) {return (unsigned)atoll(Strp[n]);}
virtual char GetTinyValue(int n);
virtual uchar GetUTinyValue(int n);
virtual short GetShortValue(int n);
virtual ushort GetUShortValue(int n);
virtual int GetIntValue(int n);
virtual uint GetUIntValue(int n);
virtual longlong GetBigintValue(int n);
virtual ulonglong GetUBigintValue(int n);
virtual double GetFloatValue(int n) {return atof(Strp[n]);}
virtual char GetTinyValue(int n) {return (char)atoi(Strp[n]);}
virtual uchar GetUTinyValue(int n) {return (uchar)atoi(Strp[n]);}
virtual void Reset(int n) {Strp[n] = NULL;}
// Methods
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -16,11 +16,6 @@
#include "assert.h"
#include "block.h"
#if defined(WIN32)
#define strtoll _strtoi64
#define atoll(S) strtoll(S, NULL, 10)
#endif // WIN32
/***********************************************************************/
/* Types used in some class definitions. */
/***********************************************************************/
......@@ -55,6 +50,8 @@ DllExport bool IsTypeNum(int type);
DllExport PVAL AllocateValue(PGLOBAL, PVAL, int = TYPE_VOID, int = 0);
DllExport PVAL AllocateValue(PGLOBAL, int, int len = 0, int prec = 0,
PSZ fmt = NULL);
DllExport ulonglong CharToNumber(char *, int, ulonglong, bool,
bool *minus = NULL, bool *rc = NULL);
/***********************************************************************/
/* Class VALUE represents a constant or variable of any valid type. */
......@@ -96,7 +93,7 @@ class DllExport VALUE : public BLOCK {
// Methods
virtual bool SetValue_pval(PVAL valp, bool chktype = false) = 0;
virtual void SetValue_char(char *p, int n) = 0;
virtual bool SetValue_char(char *p, int n) = 0;
virtual void SetValue_psz(PSZ s) = 0;
virtual void SetValue(char c) {assert(false);}
virtual void SetValue(uchar c) {assert(false);}
......@@ -112,11 +109,6 @@ class DllExport VALUE : public BLOCK {
virtual bool GetBinValue(void *buf, int buflen, bool go) = 0;
virtual char *ShowValue(char *buf, int len = 0) = 0;
virtual char *GetCharString(char *p) = 0;
//virtual char *GetShortString(char *p, int n) {return "#####";}
//virtual char *GetIntString(char *p, int n) = 0;
//virtual char *GetBigintString(char *p, int n) = 0;
//virtual char *GetFloatString(char *p, int n, int prec) = 0;
//virtual char *GetTinyString(char *p, int n) {return "?";}
virtual bool IsEqual(PVAL vp, bool chktype) = 0;
virtual bool FormatValue(PVAL vp, char *fmt) = 0;
......@@ -169,7 +161,7 @@ class DllExport TYPVAL : public VALUE {
// Methods
virtual bool SetValue_pval(PVAL valp, bool chktype);
virtual void SetValue_char(char *p, int n);
virtual bool SetValue_char(char *p, int n);
virtual void SetValue_psz(PSZ s);
virtual void SetValue(char c) {Tval = (TYPE)c; Null = false;}
virtual void SetValue(uchar c) {Tval = (TYPE)c; Null = false;}
......@@ -185,11 +177,6 @@ class DllExport TYPVAL : public VALUE {
virtual bool GetBinValue(void *buf, int buflen, bool go);
virtual char *ShowValue(char *buf, int);
virtual char *GetCharString(char *p);
//virtual char *GetShortString(char *p, int n);
//virtual char *GetIntString(char *p, int n);
//virtual char *GetBigintString(char *p, int n);
//virtual char *GetFloatString(char *p, int n, int prec = -1);
//virtual char *GetTinyString(char *p, int n);
virtual bool IsEqual(PVAL vp, bool chktype);
virtual bool SetConstFormat(PGLOBAL, FORMAT&);
virtual bool FormatValue(PVAL vp, char *fmt);
......@@ -201,9 +188,10 @@ class DllExport TYPVAL : public VALUE {
TYPVAL(void) : VALUE(TYPE_ERROR) {}
// Specialized functions
TYPE GetTypedValue(PVAL vp);
TYPE GetTypedValue(PVBLK blk, int n);
TYPE GetTypedValue(PSZ s);
static ulonglong MaxVal(void);
TYPE GetTypedValue(PVAL vp);
TYPE GetTypedValue(PVBLK blk, int n);
// TYPE GetTypedValue(PSZ s);
// Members
TYPE Tval;
......@@ -227,21 +215,21 @@ class DllExport TYPVAL<PSZ>: public VALUE {
virtual int GetValPrec() {return (Ci) ? 1 : 0;}
virtual int GetSize(void) {return (Strp) ? strlen(Strp) : 0;}
virtual PSZ GetCharValue(void) {return Strp;}
virtual char GetTinyValue(void) {return (char)atoi(Strp);}
virtual uchar GetUTinyValue(void) {return (uchar)atoi(Strp);}
virtual short GetShortValue(void) {return (short)atoi(Strp);}
virtual ushort GetUShortValue(void) {return (ushort)atoi(Strp);}
virtual int GetIntValue(void) {return atol(Strp);}
virtual uint GetUIntValue(void) {return (uint)atol(Strp);}
virtual longlong GetBigintValue(void) {return atoll(Strp);}
virtual ulonglong GetUBigintValue(void) {return (ulonglong)atoll(Strp);}
virtual char GetTinyValue(void);
virtual uchar GetUTinyValue(void);
virtual short GetShortValue(void);
virtual ushort GetUShortValue(void);
virtual int GetIntValue(void);
virtual uint GetUIntValue(void);
virtual longlong GetBigintValue(void);
virtual ulonglong GetUBigintValue(void);
virtual double GetFloatValue(void) {return atof(Strp);}
virtual void *GetTo_Val(void) {return Strp;}
virtual void SetPrec(int prec) {Ci = prec != 0;}
// Methods
virtual bool SetValue_pval(PVAL valp, bool chktype);
virtual void SetValue_char(char *p, int n);
virtual bool SetValue_char(char *p, int n);
virtual void SetValue_psz(PSZ s);
virtual void SetValue_pvblk(PVBLK blk, int n);
virtual void SetValue(char c);
......@@ -257,23 +245,10 @@ class DllExport TYPVAL<PSZ>: public VALUE {
virtual bool GetBinValue(void *buf, int buflen, bool go);
virtual char *ShowValue(char *buf, int);
virtual char *GetCharString(char *p);
//virtual char *GetShortString(char *p, int n);
//virtual char *GetIntString(char *p, int n);
//virtual char *GetBigintString(char *p, int n);
//virtual char *GetFloatString(char *p, int n, int prec = -1);
//virtual char *GetTinyString(char *p, int n);
virtual bool IsEqual(PVAL vp, bool chktype);
virtual bool FormatValue(PVAL vp, char *fmt);
virtual bool SetConstFormat(PGLOBAL, FORMAT&);
// Specialized functions
//template <class T>
//T GetValue_as(T type) {return Strp;}
//int GetValue_as(int type) {return atol(Strp);}
//short GetValue_as(short type) {return (short)atoi(Strp);}
//longlong GetValue_as(longlong type) {return atoll(Strp);}
//double GetValue_as(double type) {return atof(Strp);}
// Members
PSZ Strp;
bool Ci; // true if case insensitive
......@@ -295,7 +270,7 @@ class DllExport DTVAL : public TYPVAL<int> {
// Implementation
virtual bool SetValue_pval(PVAL valp, bool chktype);
virtual void SetValue_char(char *p, int n);
virtual bool SetValue_char(char *p, int n);
virtual void SetValue_psz(PSZ s);
virtual void SetValue_pvblk(PVBLK blk, int n);
virtual char *GetCharString(char *p);
......@@ -304,15 +279,15 @@ class DllExport DTVAL : public TYPVAL<int> {
bool SetFormat(PGLOBAL g, PSZ fmt, int len, int year = 0);
bool SetFormat(PGLOBAL g, PVAL valp);
bool IsFormatted(void) {return Pdtp != NULL;}
bool GetTmMember(OPVAL op, int& mval);
bool DateDiff(DTVAL *dtp, OPVAL op, int& tdif);
// bool GetTmMember(OPVAL op, int& mval);
// bool DateDiff(DTVAL *dtp, OPVAL op, int& tdif);
bool MakeTime(struct tm *ptm);
static void SetTimeShift(void);
static int GetShift(void) {return Shift;}
// Methods
bool MakeDate(PGLOBAL g, int *val, int nval);
bool WeekNum(PGLOBAL g, int& nval);
// bool WeekNum(PGLOBAL g, int& nval);
struct tm *GetGmTime(struct tm *);
......
......@@ -134,6 +134,7 @@ bool CONSTANT::Compare(PXOB xp)
} // end of Compare
#if 0
/***********************************************************************/
/* Rephrase: temporary implementation used by PlugRephraseSQL. */
/***********************************************************************/
......@@ -166,6 +167,7 @@ bool CONSTANT::Rephrase(PGLOBAL g, PSZ work)
return false;
} // end of Rephrase
#endif // 0
/***********************************************************************/
/* Make file output of a constant object. */
......
......@@ -124,7 +124,7 @@ class DllExport CONSTANT : public XOBJECT {
{return Value->SetConstFormat(g, fmt);}
virtual int CheckSpcCol(PTDB, int) {return 1;}
void Convert(PGLOBAL g, int newtype);
bool Rephrase(PGLOBAL g, PSZ work);
// bool Rephrase(PGLOBAL g, PSZ work);
void SetValue(PVAL vp) {Value = vp;}
virtual bool VerifyColumn(PTBX txp) {return true;}
virtual bool VerifyTdb(PTDB& tdbp) {return true;}
......
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