mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
- Add the DECIMAL data type (TYPE_DECIM)
Change the variable name of the DOUBLE type from TYPE_FLOAT to TYPE_DOUBLE Change some names to reflect ODBC version 3. This affects some variable names, function names and catalog table column names. Qualifier -> Catalog Owner (Creator) -> Schema Length -> Precision Prec -> Scale modified: storage/connect/catalog.h storage/connect/colblk.cpp storage/connect/colblk.h storage/connect/filamdbf.cpp storage/connect/global.h storage/connect/ha_connect.cc storage/connect/myconn.cpp storage/connect/mysql-test/connect/r/mysql_new.result storage/connect/mysql-test/connect/r/odbc_oracle.result storage/connect/myutil.cpp storage/connect/odbconn.cpp storage/connect/plgdbutl.cpp storage/connect/rcmsg.c storage/connect/reldef.cpp storage/connect/reldef.h storage/connect/tabcol.cpp storage/connect/tabcol.h storage/connect/tabdos.cpp storage/connect/tabfmt.cpp storage/connect/tabmysql.cpp storage/connect/tabodbc.cpp storage/connect/tabodbc.h storage/connect/tabsys.cpp storage/connect/tabutil.cpp storage/connect/tabwmi.cpp storage/connect/tabxml.cpp storage/connect/valblk.cpp storage/connect/value.cpp storage/connect/value.h storage/connect/xindex.cpp storage/connect/xobject.cpp storage/connect/xobject.h - Fix crash when GetTDB returned NULL in Open_Table modified: storage/connect/ha_connect.cc - Fix assert error setting double values from PSZ modified: storage/connect/valblk.cpp
This commit is contained in:
@@ -41,7 +41,8 @@ typedef struct _colinfo {
|
|||||||
int Offset;
|
int Offset;
|
||||||
int Length;
|
int Length;
|
||||||
int Key;
|
int Key;
|
||||||
int Prec;
|
int Precision;
|
||||||
|
int Scale;
|
||||||
int Opt;
|
int Opt;
|
||||||
char *Remark;
|
char *Remark;
|
||||||
char *Datefmt;
|
char *Datefmt;
|
||||||
|
@@ -38,6 +38,7 @@ COLBLK::COLBLK(PCOLDEF cdp, PTDB tdbp, int i)
|
|||||||
Format = cdp->F;
|
Format = cdp->F;
|
||||||
Opt = cdp->Opt;
|
Opt = cdp->Opt;
|
||||||
Long = cdp->Long;
|
Long = cdp->Long;
|
||||||
|
Precision = cdp->Precision;
|
||||||
Buf_Type = cdp->Buf_Type;
|
Buf_Type = cdp->Buf_Type;
|
||||||
ColUse |= cdp->Flags; // Used by CONNECT
|
ColUse |= cdp->Flags; // Used by CONNECT
|
||||||
Nullable = !!(cdp->Flags & U_NULLS);
|
Nullable = !!(cdp->Flags & U_NULLS);
|
||||||
@@ -47,6 +48,7 @@ COLBLK::COLBLK(PCOLDEF cdp, PTDB tdbp, int i)
|
|||||||
memset(&Format, 0, sizeof(FORMAT));
|
memset(&Format, 0, sizeof(FORMAT));
|
||||||
Opt = 0;
|
Opt = 0;
|
||||||
Long = 0;
|
Long = 0;
|
||||||
|
Precision = 0;
|
||||||
Buf_Type = TYPE_ERROR;
|
Buf_Type = TYPE_ERROR;
|
||||||
Nullable = false;
|
Nullable = false;
|
||||||
Unsigned = false;
|
Unsigned = false;
|
||||||
@@ -165,7 +167,7 @@ bool COLBLK::CheckSort(PTDB tdbp)
|
|||||||
/* InitValue: prepare a column block for read operation. */
|
/* InitValue: prepare a column block for read operation. */
|
||||||
/* Now we use Format.Length for the len parameter to avoid strings */
|
/* Now we use Format.Length for the len parameter to avoid strings */
|
||||||
/* to be truncated when converting from string to coded string. */
|
/* to be truncated when converting from string to coded string. */
|
||||||
/* Added in version 1.5 is the arguments GetPrecision() and Domain */
|
/* Added in version 1.5 is the arguments GetScale() and Domain */
|
||||||
/* in calling AllocateValue. Domain is used for TYPE_DATE only. */
|
/* in calling AllocateValue. Domain is used for TYPE_DATE only. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool COLBLK::InitValue(PGLOBAL g)
|
bool COLBLK::InitValue(PGLOBAL g)
|
||||||
@@ -173,12 +175,9 @@ bool COLBLK::InitValue(PGLOBAL g)
|
|||||||
if (Value)
|
if (Value)
|
||||||
return false; // Already done
|
return false; // Already done
|
||||||
|
|
||||||
// Unsigned can be set only for valid value types
|
|
||||||
int prec = (Unsigned) ? 1 : GetPrecision();
|
|
||||||
|
|
||||||
// Allocate a Value object
|
// Allocate a Value object
|
||||||
if (!(Value = AllocateValue(g, Buf_Type, Format.Length,
|
if (!(Value = AllocateValue(g, Buf_Type, Precision,
|
||||||
prec, GetDomain())))
|
GetScale(), Unsigned, GetDomain())))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
AddStatus(BUF_READY);
|
AddStatus(BUF_READY);
|
||||||
@@ -270,7 +269,7 @@ SPCBLK::SPCBLK(PCOLUMN cp)
|
|||||||
: COLBLK((PCOLDEF)NULL, cp->GetTo_Table()->GetTo_Tdb(), 0)
|
: COLBLK((PCOLDEF)NULL, cp->GetTo_Table()->GetTo_Tdb(), 0)
|
||||||
{
|
{
|
||||||
Name = (char*)cp->GetName();
|
Name = (char*)cp->GetName();
|
||||||
Long = 0;
|
Precision = Long = 0;
|
||||||
Buf_Type = TYPE_ERROR;
|
Buf_Type = TYPE_ERROR;
|
||||||
} // end of SPCBLK constructor
|
} // end of SPCBLK constructor
|
||||||
|
|
||||||
@@ -290,7 +289,7 @@ void SPCBLK::WriteColumn(PGLOBAL g)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
RIDBLK::RIDBLK(PCOLUMN cp, bool rnm) : SPCBLK(cp)
|
RIDBLK::RIDBLK(PCOLUMN cp, bool rnm) : SPCBLK(cp)
|
||||||
{
|
{
|
||||||
Long = 10;
|
Precision = Long = 10;
|
||||||
Buf_Type = TYPE_INT;
|
Buf_Type = TYPE_INT;
|
||||||
Rnm = rnm;
|
Rnm = rnm;
|
||||||
*Format.Type = 'N';
|
*Format.Type = 'N';
|
||||||
@@ -313,7 +312,7 @@ void RIDBLK::ReadColumn(PGLOBAL g)
|
|||||||
FIDBLK::FIDBLK(PCOLUMN cp) : SPCBLK(cp)
|
FIDBLK::FIDBLK(PCOLUMN cp) : SPCBLK(cp)
|
||||||
{
|
{
|
||||||
//Is_Key = 2; for when the MUL table indexed reading will be implemented.
|
//Is_Key = 2; for when the MUL table indexed reading will be implemented.
|
||||||
Long = _MAX_PATH;
|
Precision = Long = _MAX_PATH;
|
||||||
Buf_Type = TYPE_STRING;
|
Buf_Type = TYPE_STRING;
|
||||||
*Format.Type = 'C';
|
*Format.Type = 'C';
|
||||||
Format.Length = Long;
|
Format.Length = Long;
|
||||||
@@ -348,7 +347,7 @@ void FIDBLK::ReadColumn(PGLOBAL g)
|
|||||||
TIDBLK::TIDBLK(PCOLUMN cp) : SPCBLK(cp)
|
TIDBLK::TIDBLK(PCOLUMN cp) : SPCBLK(cp)
|
||||||
{
|
{
|
||||||
//Is_Key = 2; for when the MUL table indexed reading will be implemented.
|
//Is_Key = 2; for when the MUL table indexed reading will be implemented.
|
||||||
Long = 64;
|
Precision = Long = 64;
|
||||||
Buf_Type = TYPE_STRING;
|
Buf_Type = TYPE_STRING;
|
||||||
*Format.Type = 'C';
|
*Format.Type = 'C';
|
||||||
Format.Length = Long;
|
Format.Length = Long;
|
||||||
@@ -375,7 +374,7 @@ void TIDBLK::ReadColumn(PGLOBAL g)
|
|||||||
SIDBLK::SIDBLK(PCOLUMN cp) : SPCBLK(cp)
|
SIDBLK::SIDBLK(PCOLUMN cp) : SPCBLK(cp)
|
||||||
{
|
{
|
||||||
//Is_Key = 2; for when the MUL table indexed reading will be implemented.
|
//Is_Key = 2; for when the MUL table indexed reading will be implemented.
|
||||||
Long = 64;
|
Precision = Long = 64;
|
||||||
Buf_Type = TYPE_STRING;
|
Buf_Type = TYPE_STRING;
|
||||||
*Format.Type = 'C';
|
*Format.Type = 'C';
|
||||||
Format.Length = Long;
|
Format.Length = Long;
|
||||||
|
@@ -29,7 +29,8 @@ class DllExport COLBLK : public XOBJECT {
|
|||||||
// Implementation
|
// Implementation
|
||||||
virtual int GetType(void) {return TYPE_COLBLK;}
|
virtual int GetType(void) {return TYPE_COLBLK;}
|
||||||
virtual int GetResultType(void) {return Buf_Type;}
|
virtual int GetResultType(void) {return Buf_Type;}
|
||||||
virtual int GetPrecision(void) {return Format.Prec;}
|
virtual int GetScale(void) {return Format.Prec;}
|
||||||
|
virtual int GetPrecision(void) {return Precision;}
|
||||||
virtual int GetLength(void) {return Long;}
|
virtual int GetLength(void) {return Long;}
|
||||||
virtual int GetLengthEx(void);
|
virtual int GetLengthEx(void);
|
||||||
virtual int GetAmType() {return TYPE_AM_ERROR;}
|
virtual int GetAmType() {return TYPE_AM_ERROR;}
|
||||||
@@ -53,6 +54,7 @@ class DllExport COLBLK : public XOBJECT {
|
|||||||
PSZ GetDomain(void) {return (Cdp) ? Cdp->Decode : NULL;}
|
PSZ GetDomain(void) {return (Cdp) ? Cdp->Decode : NULL;}
|
||||||
PSZ GetDesc(void) {return (Cdp) ? Cdp->Desc : NULL;}
|
PSZ GetDesc(void) {return (Cdp) ? Cdp->Desc : NULL;}
|
||||||
PSZ GetFmt(void) {return (Cdp) ? Cdp->Fmt : NULL;}
|
PSZ GetFmt(void) {return (Cdp) ? Cdp->Fmt : NULL;}
|
||||||
|
bool IsUnsigned(void) {return Unsigned;}
|
||||||
bool IsNullable(void) {return Nullable;}
|
bool IsNullable(void) {return Nullable;}
|
||||||
void SetNullable(bool b) {Nullable = b;}
|
void SetNullable(bool b) {Nullable = b;}
|
||||||
|
|
||||||
@@ -88,6 +90,7 @@ class DllExport COLBLK : public XOBJECT {
|
|||||||
int Opt; // Cluster/sort information
|
int Opt; // Cluster/sort information
|
||||||
int Buf_Type; // Data type
|
int Buf_Type; // Data type
|
||||||
int Long; // Internal length in table
|
int Long; // Internal length in table
|
||||||
|
int Precision; // Column length (as for ODBC)
|
||||||
FORMAT Format; // Output format
|
FORMAT Format; // Output format
|
||||||
ushort ColUse; // Column usage
|
ushort ColUse; // Column usage
|
||||||
ushort Status; // Column read status
|
ushort Status; // Column read status
|
||||||
|
@@ -271,11 +271,11 @@ PQRYRES DBFColumns(PGLOBAL g, const char *fn, BOOL info)
|
|||||||
type = TYPE_STRING;
|
type = TYPE_STRING;
|
||||||
break;
|
break;
|
||||||
case 'N':
|
case 'N':
|
||||||
type = (thisfield.Decimals) ? TYPE_FLOAT
|
type = (thisfield.Decimals) ? TYPE_DOUBLE
|
||||||
: (len > 10) ? TYPE_BIGINT : TYPE_INT;
|
: (len > 10) ? TYPE_BIGINT : TYPE_INT;
|
||||||
break;
|
break;
|
||||||
case 'F':
|
case 'F':
|
||||||
type = TYPE_FLOAT;
|
type = TYPE_DOUBLE;
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
type = TYPE_DATE; // Is this correct ???
|
type = TYPE_DATE; // Is this correct ???
|
||||||
|
@@ -77,12 +77,13 @@
|
|||||||
#define TYPE_SEMX 0 /* Initial semantic function type? */
|
#define TYPE_SEMX 0 /* Initial semantic function type? */
|
||||||
#define TYPE_ERROR 0
|
#define TYPE_ERROR 0
|
||||||
#define TYPE_STRING 1
|
#define TYPE_STRING 1
|
||||||
#define TYPE_FLOAT 2
|
#define TYPE_DOUBLE 2
|
||||||
#define TYPE_SHORT 3
|
#define TYPE_SHORT 3
|
||||||
#define TYPE_TINY 4
|
#define TYPE_TINY 4
|
||||||
#define TYPE_BIGINT 5
|
#define TYPE_BIGINT 5
|
||||||
#define TYPE_LIST 6
|
#define TYPE_LIST 6
|
||||||
#define TYPE_INT 7
|
#define TYPE_INT 7
|
||||||
|
#define TYPE_DECIM 9
|
||||||
|
|
||||||
#if defined(OS32)
|
#if defined(OS32)
|
||||||
#define SYS_STAMP "OS32"
|
#define SYS_STAMP "OS32"
|
||||||
|
@@ -862,12 +862,14 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
|
|||||||
return fldp;
|
return fldp;
|
||||||
} // endif special
|
} // endif special
|
||||||
|
|
||||||
pcf->Prec= 0;
|
pcf->Scale= 0;
|
||||||
pcf->Opt= (fop) ? (int)fop->opt : 0;
|
pcf->Opt= (fop) ? (int)fop->opt : 0;
|
||||||
|
|
||||||
if ((pcf->Length= fp->field_length) < 0)
|
if ((pcf->Length= fp->field_length) < 0)
|
||||||
pcf->Length= 256; // BLOB?
|
pcf->Length= 256; // BLOB?
|
||||||
|
|
||||||
|
pcf->Precision= pcf->Length;
|
||||||
|
|
||||||
if (fop) {
|
if (fop) {
|
||||||
pcf->Offset= (int)fop->offset;
|
pcf->Offset= (int)fop->offset;
|
||||||
// pcf->Freq= fop->freq;
|
// pcf->Freq= fop->freq;
|
||||||
@@ -898,13 +900,17 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
|
|||||||
|
|
||||||
// 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")) {
|
||||||
pcf->Prec= 1; // Case insensitive
|
pcf->Scale= 1; // Case insensitive
|
||||||
pcf->Opt= 0; // Prevent index opt until it is safe
|
pcf->Opt= 0; // Prevent index opt until it is safe
|
||||||
} // endif ci
|
} // endif ci
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TYPE_FLOAT:
|
case TYPE_DOUBLE:
|
||||||
pcf->Prec= max(min(fp->decimals(), ((unsigned)pcf->Length - 2)), 0);
|
pcf->Scale= max(min(fp->decimals(), ((unsigned)pcf->Length - 2)), 0);
|
||||||
|
break;
|
||||||
|
case TYPE_DECIM:
|
||||||
|
pcf->Precision= ((Field_new_decimal*)fp)->precision;
|
||||||
|
pcf->Scale= fp->decimals();
|
||||||
break;
|
break;
|
||||||
case TYPE_DATE:
|
case TYPE_DATE:
|
||||||
// Field_length is only used for DATE columns
|
// Field_length is only used for DATE columns
|
||||||
@@ -1109,12 +1115,12 @@ PTDB ha_connect::GetTDB(PGLOBAL g)
|
|||||||
|| tdbp->GetAmType() == TYPE_AM_XML)) {
|
|| tdbp->GetAmType() == TYPE_AM_XML)) {
|
||||||
tp= tdbp;
|
tp= tdbp;
|
||||||
// tp->SetMode(xmod);
|
// tp->SetMode(xmod);
|
||||||
} else if ((tp= CntGetTDB(g, table_name, xmod, this)))
|
} else if ((tp= CntGetTDB(g, table_name, xmod, this))) {
|
||||||
valid_query_id= xp->last_query_id;
|
valid_query_id= xp->last_query_id;
|
||||||
else
|
tp->SetMode(xmod);
|
||||||
|
} else
|
||||||
printf("GetTDB: %s\n", g->Message);
|
printf("GetTDB: %s\n", g->Message);
|
||||||
|
|
||||||
tp->SetMode(xmod);
|
|
||||||
return tp;
|
return tp;
|
||||||
} // end of GetTDB
|
} // end of GetTDB
|
||||||
|
|
||||||
@@ -1326,7 +1332,7 @@ int ha_connect::MakeRecord(char *buf)
|
|||||||
value->FormatValue(sdvalout, fmt);
|
value->FormatValue(sdvalout, fmt);
|
||||||
p= sdvalout->GetCharValue();
|
p= sdvalout->GetCharValue();
|
||||||
break;
|
break;
|
||||||
case TYPE_FLOAT:
|
case TYPE_DOUBLE:
|
||||||
p= NULL;
|
p= NULL;
|
||||||
break;
|
break;
|
||||||
case TYPE_STRING:
|
case TYPE_STRING:
|
||||||
@@ -1422,7 +1428,7 @@ int ha_connect::ScanRecord(PGLOBAL g, uchar *buf)
|
|||||||
|
|
||||||
value->Reset();
|
value->Reset();
|
||||||
} else switch (value->GetType()) {
|
} else switch (value->GetType()) {
|
||||||
case TYPE_FLOAT:
|
case TYPE_DOUBLE:
|
||||||
value->SetValue(fp->val_real());
|
value->SetValue(fp->val_real());
|
||||||
break;
|
break;
|
||||||
case TYPE_DATE:
|
case TYPE_DATE:
|
||||||
@@ -3129,7 +3135,17 @@ int ha_connect::external_lock(THD *thd, int lock_type)
|
|||||||
|
|
||||||
if (adp)
|
if (adp)
|
||||||
// Here we do make the new indexes
|
// Here we do make the new indexes
|
||||||
tdp->MakeIndex(g, adp, true);
|
if (tdp->MakeIndex(g, adp, true) == RC_FX) {
|
||||||
|
//#if defined(_DEBUG)
|
||||||
|
// Make it a warning to avoid crash on debug
|
||||||
|
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||||
|
0, g->Message);
|
||||||
|
rc= 0;
|
||||||
|
//#else // !_DEBUG
|
||||||
|
// my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
|
||||||
|
// rc= HA_ERR_INTERNAL_ERROR;
|
||||||
|
//#endif // !DEBUG
|
||||||
|
} // endif MakeIndex
|
||||||
|
|
||||||
} // endif Mode
|
} // endif Mode
|
||||||
|
|
||||||
@@ -3508,7 +3524,7 @@ static bool add_fields(PGLOBAL g,
|
|||||||
length= (char*)PlugSubAlloc(g, NULL, 8);
|
length= (char*)PlugSubAlloc(g, NULL, 8);
|
||||||
sprintf(length, "%d", len);
|
sprintf(length, "%d", len);
|
||||||
|
|
||||||
if (typ == TYPE_FLOAT) {
|
if (typ == TYPE_DOUBLE) {
|
||||||
decimals= (char*)PlugSubAlloc(g, NULL, 8);
|
decimals= (char*)PlugSubAlloc(g, NULL, 8);
|
||||||
sprintf(decimals, "%d", min(dec, (min(len, 31) - 1)));
|
sprintf(decimals, "%d", min(dec, (min(len, 31) - 1)));
|
||||||
} // endif dec
|
} // endif dec
|
||||||
@@ -3574,6 +3590,10 @@ static bool add_field(String *sql, const char *field_name, int typ,
|
|||||||
error|= sql->append(',');
|
error|= sql->append(',');
|
||||||
// dec must be < len and < 31
|
// dec must be < len and < 31
|
||||||
error|= sql->append_ulonglong(min(dec, (min(len, 31) - 1)));
|
error|= sql->append_ulonglong(min(dec, (min(len, 31) - 1)));
|
||||||
|
} else if (dec > 0 && !strcmp(type, "DECIMAL")) {
|
||||||
|
error|= sql->append(',');
|
||||||
|
// dec must be < len
|
||||||
|
error|= sql->append_ulonglong(min(dec, len - 1));
|
||||||
} // endif dec
|
} // endif dec
|
||||||
|
|
||||||
error|= sql->append(')');
|
error|= sql->append(')');
|
||||||
@@ -3590,7 +3610,7 @@ static bool add_field(String *sql, const char *field_name, int typ,
|
|||||||
if (dft && *dft) {
|
if (dft && *dft) {
|
||||||
error|= sql->append(" DEFAULT ");
|
error|= sql->append(" DEFAULT ");
|
||||||
|
|
||||||
if (IsTypeChar(typ)) {
|
if (!IsTypeNum(typ)) {
|
||||||
error|= sql->append("'");
|
error|= sql->append("'");
|
||||||
error|= sql->append_for_single_quote(dft, strlen(dft));
|
error|= sql->append_for_single_quote(dft, strlen(dft));
|
||||||
error|= sql->append("'");
|
error|= sql->append("'");
|
||||||
@@ -4086,7 +4106,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
case TAB_TBL:
|
case TAB_TBL:
|
||||||
case TAB_XCL:
|
case TAB_XCL:
|
||||||
case TAB_OCCUR:
|
case TAB_OCCUR:
|
||||||
if (!stricmp(tab, create_info->alias) &&
|
if (!src && !stricmp(tab, create_info->alias) &&
|
||||||
(!db || !stricmp(db, table_s->db.str)))
|
(!db || !stricmp(db, table_s->db.str)))
|
||||||
sprintf(g->Message, "A %s table cannot refer to itself", topt->type);
|
sprintf(g->Message, "A %s table cannot refer to itself", topt->type);
|
||||||
else
|
else
|
||||||
@@ -4295,11 +4315,15 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
} else
|
} else
|
||||||
typ= plgtyp;
|
typ= plgtyp;
|
||||||
|
|
||||||
|
switch (typ) {
|
||||||
|
case TYPE_DOUBLE:
|
||||||
// Some data sources do not count dec in length (prec)
|
// Some data sources do not count dec in length (prec)
|
||||||
if (typ == TYPE_FLOAT)
|
|
||||||
prec += (dec + 2); // To be safe
|
prec += (dec + 2); // To be safe
|
||||||
else
|
case TYPE_DECIM:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
dec= 0;
|
dec= 0;
|
||||||
|
} // endswitch typ
|
||||||
|
|
||||||
} // endif ttp
|
} // endif ttp
|
||||||
#endif // ODBC_SUPPORT
|
#endif // ODBC_SUPPORT
|
||||||
@@ -4307,7 +4331,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
|
|||||||
// Make the arguments as required by add_fields
|
// Make the arguments as required by add_fields
|
||||||
if (typ == TYPE_DATE)
|
if (typ == TYPE_DATE)
|
||||||
prec= 0;
|
prec= 0;
|
||||||
else if (typ == TYPE_FLOAT)
|
else if (typ == TYPE_DOUBLE)
|
||||||
prec= len;
|
prec= len;
|
||||||
|
|
||||||
// Now add the field
|
// Now add the field
|
||||||
|
@@ -723,7 +723,8 @@ PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb)
|
|||||||
// For direct MySQL connection, display the MySQL date string
|
// For direct MySQL connection, display the MySQL date string
|
||||||
crp->Type = TYPE_STRING;
|
crp->Type = TYPE_STRING;
|
||||||
|
|
||||||
crp->Prec = (crp->Type == TYPE_FLOAT) ? fld->decimals : 0;
|
crp->Prec = (crp->Type == TYPE_DOUBLE || crp->Type == TYPE_DECIM)
|
||||||
|
? fld->decimals : 0;
|
||||||
crp->Length = fld->max_length;
|
crp->Length = fld->max_length;
|
||||||
crp->Clen = GetTypeSize(crp->Type, crp->Length);
|
crp->Clen = GetTypeSize(crp->Type, crp->Length);
|
||||||
uns = (fld->flags & (UNSIGNED_FLAG | ZEROFILL_FLAG)) ? true : false;
|
uns = (fld->flags & (UNSIGNED_FLAG | ZEROFILL_FLAG)) ? true : false;
|
||||||
|
@@ -141,7 +141,7 @@ t1 CREATE TABLE `t1` (
|
|||||||
`e` bigint(20) DEFAULT NULL,
|
`e` bigint(20) DEFAULT NULL,
|
||||||
`f` double DEFAULT NULL,
|
`f` double DEFAULT NULL,
|
||||||
`g` double DEFAULT NULL,
|
`g` double DEFAULT NULL,
|
||||||
`h` double(20,5) DEFAULT NULL
|
`h` decimal(20,5) DEFAULT NULL
|
||||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MYSQL' `OPTION_LIST`='host=127.0.0.1,user=root,port=SLAVE_PORT'
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MYSQL' `OPTION_LIST`='host=127.0.0.1,user=root,port=SLAVE_PORT'
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
a b c d e f g h
|
a b c d e f g h
|
||||||
|
@@ -126,7 +126,7 @@ TABNAME='T1';
|
|||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`A` double(40,0) DEFAULT NULL,
|
`A` decimal(38,0) DEFAULT NULL,
|
||||||
`B` double(40,0) DEFAULT NULL
|
`B` double(40,0) DEFAULT NULL
|
||||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='T1'
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='T1'
|
||||||
SELECT * FROM t1 ORDER BY A;
|
SELECT * FROM t1 ORDER BY A;
|
||||||
@@ -138,7 +138,7 @@ CREATE TABLE t2 AS SELECT * FROM t1;
|
|||||||
SHOW CREATE TABLE t2;
|
SHOW CREATE TABLE t2;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t2 CREATE TABLE `t2` (
|
t2 CREATE TABLE `t2` (
|
||||||
`A` double(40,0) DEFAULT NULL,
|
`A` decimal(38,0) DEFAULT NULL,
|
||||||
`B` double(40,0) DEFAULT NULL
|
`B` double(40,0) DEFAULT NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
SELECT * FROM t2;
|
SELECT * FROM t2;
|
||||||
@@ -162,7 +162,7 @@ TABNAME='MTR.T1';
|
|||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`A` double(40,0) DEFAULT NULL,
|
`A` decimal(38,0) DEFAULT NULL,
|
||||||
`B` double(40,0) DEFAULT NULL
|
`B` double(40,0) DEFAULT NULL
|
||||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.T1'
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.T1'
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
@@ -178,7 +178,7 @@ TABNAME='MTR.V1';
|
|||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`A` double(40,0) DEFAULT NULL,
|
`A` decimal(38,0) DEFAULT NULL,
|
||||||
`B` double(40,0) DEFAULT NULL
|
`B` double(40,0) DEFAULT NULL
|
||||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.V1'
|
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEngineOracle;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='MTR.V1'
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
@@ -190,7 +190,7 @@ CREATE TABLE t2 AS SELECT * FROM t1;
|
|||||||
SHOW CREATE TABLE t2;
|
SHOW CREATE TABLE t2;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t2 CREATE TABLE `t2` (
|
t2 CREATE TABLE `t2` (
|
||||||
`A` double(40,0) DEFAULT NULL,
|
`A` decimal(38,0) DEFAULT NULL,
|
||||||
`B` double(40,0) DEFAULT NULL
|
`B` double(40,0) DEFAULT NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
SELECT * FROM t2;
|
SELECT * FROM t2;
|
||||||
|
@@ -42,9 +42,10 @@ int MYSQLtoPLG(char *typname, char *var)
|
|||||||
!stricmp(typname, "text") || !stricmp(typname, "blob"))
|
!stricmp(typname, "text") || !stricmp(typname, "blob"))
|
||||||
type = TYPE_STRING;
|
type = TYPE_STRING;
|
||||||
else if (!stricmp(typname, "double") || !stricmp(typname, "float") ||
|
else if (!stricmp(typname, "double") || !stricmp(typname, "float") ||
|
||||||
!stricmp(typname, "real") ||
|
!stricmp(typname, "real"))
|
||||||
!stricmp(typname, "decimal") || !stricmp(typname, "numeric"))
|
type = TYPE_DOUBLE;
|
||||||
type = TYPE_FLOAT;
|
else if (!stricmp(typname, "decimal") || !stricmp(typname, "numeric"))
|
||||||
|
type = TYPE_DECIM;
|
||||||
else if (!stricmp(typname, "date") || !stricmp(typname, "datetime") ||
|
else if (!stricmp(typname, "date") || !stricmp(typname, "datetime") ||
|
||||||
!stricmp(typname, "time") || !stricmp(typname, "timestamp") ||
|
!stricmp(typname, "time") || !stricmp(typname, "timestamp") ||
|
||||||
!stricmp(typname, "year"))
|
!stricmp(typname, "year"))
|
||||||
@@ -95,7 +96,7 @@ enum enum_field_types PLGtoMYSQL(int type, bool dbf, char v)
|
|||||||
case TYPE_SHORT:
|
case TYPE_SHORT:
|
||||||
mytype = MYSQL_TYPE_SHORT;
|
mytype = MYSQL_TYPE_SHORT;
|
||||||
break;
|
break;
|
||||||
case TYPE_FLOAT:
|
case TYPE_DOUBLE:
|
||||||
mytype = MYSQL_TYPE_DOUBLE;
|
mytype = MYSQL_TYPE_DOUBLE;
|
||||||
break;
|
break;
|
||||||
case TYPE_DATE:
|
case TYPE_DATE:
|
||||||
@@ -114,6 +115,13 @@ enum enum_field_types PLGtoMYSQL(int type, bool dbf, char v)
|
|||||||
case TYPE_TINY:
|
case TYPE_TINY:
|
||||||
mytype = MYSQL_TYPE_TINY;
|
mytype = MYSQL_TYPE_TINY;
|
||||||
break;
|
break;
|
||||||
|
case TYPE_DECIM:
|
||||||
|
#if !defined(ALPHA)
|
||||||
|
mytype = MYSQL_TYPE_NEWDECIMAL;
|
||||||
|
#else // ALPHA
|
||||||
|
mytype = MYSQL_TYPE_DECIMAL;
|
||||||
|
#endif // ALPHA
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
mytype = MYSQL_TYPE_NULL;
|
mytype = MYSQL_TYPE_NULL;
|
||||||
} // endswitch mytype
|
} // endswitch mytype
|
||||||
@@ -129,7 +137,7 @@ const char *PLGtoMYSQLtype(int type, bool dbf, char v)
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case TYPE_INT: return "INT";
|
case TYPE_INT: return "INT";
|
||||||
case TYPE_SHORT: return "SMALLINT";
|
case TYPE_SHORT: return "SMALLINT";
|
||||||
case TYPE_FLOAT: return "DOUBLE";
|
case TYPE_DOUBLE: return "DOUBLE";
|
||||||
case TYPE_DATE: return dbf ? "DATE" :
|
case TYPE_DATE: return dbf ? "DATE" :
|
||||||
(v == 'S') ? "TIMESTAMP" :
|
(v == 'S') ? "TIMESTAMP" :
|
||||||
(v == 'D') ? "DATE" :
|
(v == 'D') ? "DATE" :
|
||||||
@@ -138,6 +146,7 @@ const char *PLGtoMYSQLtype(int type, bool dbf, char v)
|
|||||||
case TYPE_STRING: return v ? "VARCHAR" : "CHAR";
|
case TYPE_STRING: return v ? "VARCHAR" : "CHAR";
|
||||||
case TYPE_BIGINT: return "BIGINT";
|
case TYPE_BIGINT: return "BIGINT";
|
||||||
case TYPE_TINY: return "TINYINT";
|
case TYPE_TINY: return "TINYINT";
|
||||||
|
case TYPE_DECIM: return "DECIMAL";
|
||||||
default: return "CHAR(0)";
|
default: return "CHAR(0)";
|
||||||
} // endswitch mytype
|
} // endswitch mytype
|
||||||
|
|
||||||
@@ -170,9 +179,11 @@ int MYSQLtoPLG(int mytype, char *var)
|
|||||||
#if !defined(ALPHA)
|
#if !defined(ALPHA)
|
||||||
case MYSQL_TYPE_NEWDECIMAL:
|
case MYSQL_TYPE_NEWDECIMAL:
|
||||||
#endif // !ALPHA)
|
#endif // !ALPHA)
|
||||||
|
type = TYPE_DECIM;
|
||||||
|
break;
|
||||||
case MYSQL_TYPE_FLOAT:
|
case MYSQL_TYPE_FLOAT:
|
||||||
case MYSQL_TYPE_DOUBLE:
|
case MYSQL_TYPE_DOUBLE:
|
||||||
type = TYPE_FLOAT;
|
type = TYPE_DOUBLE;
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_TIMESTAMP:
|
case MYSQL_TYPE_TIMESTAMP:
|
||||||
case MYSQL_TYPE_DATE:
|
case MYSQL_TYPE_DATE:
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/************ Odbconn C++ Functions Source Code File (.CPP) ************/
|
/************ Odbconn C++ Functions Source Code File (.CPP) ************/
|
||||||
/* Name: ODBCONN.CPP Version 1.8 */
|
/* Name: ODBCONN.CPP Version 1.9 */
|
||||||
/* */
|
/* */
|
||||||
/* (C) Copyright to the author Olivier BERTRAND 1998-2013 */
|
/* (C) Copyright to the author Olivier BERTRAND 1998-2013 */
|
||||||
/* */
|
/* */
|
||||||
@@ -78,8 +78,9 @@ static short GetSQLType(int type)
|
|||||||
case TYPE_INT: tp = SQL_INTEGER; break;
|
case TYPE_INT: tp = SQL_INTEGER; break;
|
||||||
case TYPE_DATE: tp = SQL_TIMESTAMP; break;
|
case TYPE_DATE: tp = SQL_TIMESTAMP; break;
|
||||||
case TYPE_BIGINT: tp = SQL_BIGINT; break; // (-5)
|
case TYPE_BIGINT: tp = SQL_BIGINT; break; // (-5)
|
||||||
case TYPE_FLOAT: tp = SQL_DOUBLE; break;
|
case TYPE_DOUBLE: tp = SQL_DOUBLE; break;
|
||||||
case TYPE_TINY : tp = SQL_TINYINT; break;
|
case TYPE_TINY: tp = SQL_TINYINT; break;
|
||||||
|
case TYPE_DECIM: tp = SQL_DECIMAL; break;
|
||||||
} // endswitch type
|
} // endswitch type
|
||||||
|
|
||||||
return tp;
|
return tp;
|
||||||
@@ -98,8 +99,9 @@ static int GetSQLCType(int type)
|
|||||||
case TYPE_INT: tp = SQL_C_LONG; break;
|
case TYPE_INT: tp = SQL_C_LONG; break;
|
||||||
case TYPE_DATE: tp = SQL_C_TIMESTAMP; break;
|
case TYPE_DATE: tp = SQL_C_TIMESTAMP; break;
|
||||||
case TYPE_BIGINT: tp = SQL_C_SBIGINT; break;
|
case TYPE_BIGINT: tp = SQL_C_SBIGINT; break;
|
||||||
case TYPE_FLOAT: tp = SQL_C_DOUBLE; break;
|
case TYPE_DOUBLE: tp = SQL_C_DOUBLE; break;
|
||||||
case TYPE_TINY : tp = SQL_C_TINYINT; break;
|
case TYPE_TINY : tp = SQL_C_TINYINT; break;
|
||||||
|
case TYPE_DECIM: tp = SQL_C_CHAR; break;
|
||||||
} // endswitch type
|
} // endswitch type
|
||||||
|
|
||||||
return tp;
|
return tp;
|
||||||
@@ -125,8 +127,9 @@ int TranslateSQLType(int stp, int prec, int& len, char& v)
|
|||||||
break;
|
break;
|
||||||
case SQL_NUMERIC: // 2
|
case SQL_NUMERIC: // 2
|
||||||
case SQL_DECIMAL: // 3
|
case SQL_DECIMAL: // 3
|
||||||
type = (prec || len > 20) ? TYPE_FLOAT
|
// type = (prec || len > 20) ? TYPE_DOUBLE
|
||||||
: (len > 10) ? TYPE_BIGINT : TYPE_INT;
|
// : (len > 10) ? TYPE_BIGINT : TYPE_INT;
|
||||||
|
type = TYPE_DECIM;
|
||||||
break;
|
break;
|
||||||
case SQL_INTEGER: // 4
|
case SQL_INTEGER: // 4
|
||||||
type = TYPE_INT;
|
type = TYPE_INT;
|
||||||
@@ -141,7 +144,7 @@ int TranslateSQLType(int stp, int prec, int& len, char& v)
|
|||||||
case SQL_FLOAT: // 6
|
case SQL_FLOAT: // 6
|
||||||
case SQL_REAL: // 7
|
case SQL_REAL: // 7
|
||||||
case SQL_DOUBLE: // 8
|
case SQL_DOUBLE: // 8
|
||||||
type = TYPE_FLOAT;
|
type = TYPE_DOUBLE;
|
||||||
break;
|
break;
|
||||||
case SQL_DATETIME: // 9
|
case SQL_DATETIME: // 9
|
||||||
// case SQL_DATE: // 9
|
// case SQL_DATE: // 9
|
||||||
@@ -312,9 +315,9 @@ PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *db, char *table,
|
|||||||
} else if (!maxres)
|
} else if (!maxres)
|
||||||
maxres = 20000;
|
maxres = 20000;
|
||||||
|
|
||||||
// n = ocp->GetMaxValue(SQL_MAX_QUALIFIER_NAME_LEN);
|
// n = ocp->GetMaxValue(SQL_MAX_CATALOG_NAME_LEN);
|
||||||
// length[0] = (n) ? (n + 1) : 0;
|
// length[0] = (n) ? (n + 1) : 0;
|
||||||
// n = ocp->GetMaxValue(SQL_MAX_USER_NAME_LEN);
|
// n = ocp->GetMaxValue(SQL_MAX_SCHEMA_NAME_LEN);
|
||||||
// length[1] = (n) ? (n + 1) : 0;
|
// length[1] = (n) ? (n + 1) : 0;
|
||||||
// n = ocp->GetMaxValue(SQL_MAX_TABLE_NAME_LEN);
|
// n = ocp->GetMaxValue(SQL_MAX_TABLE_NAME_LEN);
|
||||||
// length[2] = (n) ? (n + 1) : 0;
|
// length[2] = (n) ? (n + 1) : 0;
|
||||||
@@ -425,7 +428,7 @@ PQRYRES MyODBCCols(PGLOBAL g, char *dsn, char *tab, bool info)
|
|||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* Keep only the info used by ha_connect::pre_create. */
|
/* Keep only the info used by ha_connect::pre_create. */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
qrp->Colresp = qrp->Colresp->Next->Next; // Skip Owner and Table names
|
qrp->Colresp = qrp->Colresp->Next->Next; // Skip Schema and Table names
|
||||||
|
|
||||||
crpt = qrp->Colresp->Next; // SQL type
|
crpt = qrp->Colresp->Next; // SQL type
|
||||||
crpl = crpt->Next->Next; // Length
|
crpl = crpt->Next->Next; // Length
|
||||||
@@ -440,7 +443,7 @@ PQRYRES MyODBCCols(PGLOBAL g, char *dsn, char *tab, bool info)
|
|||||||
crpt->Kdata->SetValue(type, i);
|
crpt->Kdata->SetValue(type, i);
|
||||||
|
|
||||||
// Some data sources do not count prec in length
|
// Some data sources do not count prec in length
|
||||||
if (type == TYPE_FLOAT)
|
if (type == TYPE_DOUBLE)
|
||||||
len += (prec + 2); // To be safe
|
len += (prec + 2); // To be safe
|
||||||
|
|
||||||
// Could have been changed for blobs or numeric
|
// Could have been changed for blobs or numeric
|
||||||
@@ -588,9 +591,9 @@ PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *db, char *tabpat,
|
|||||||
if (!maxres)
|
if (!maxres)
|
||||||
maxres = 10000; // This is completely arbitrary
|
maxres = 10000; // This is completely arbitrary
|
||||||
|
|
||||||
// n = ocp->GetMaxValue(SQL_MAX_QUALIFIER_NAME_LEN);
|
// n = ocp->GetMaxValue(SQL_MAX_CATALOG_NAME_LEN);
|
||||||
// length[0] = (n) ? (n + 1) : 0;
|
// length[0] = (n) ? (n + 1) : 0;
|
||||||
// n = ocp->GetMaxValue(SQL_MAX_USER_NAME_LEN);
|
// n = ocp->GetMaxValue(SQL_MAX_SCHEMA_NAME_LEN);
|
||||||
// length[1] = (n) ? (n + 1) : 0;
|
// length[1] = (n) ? (n + 1) : 0;
|
||||||
n = ocp->GetMaxValue(SQL_MAX_TABLE_NAME_LEN);
|
n = ocp->GetMaxValue(SQL_MAX_TABLE_NAME_LEN);
|
||||||
length[2] = (n) ? (n + 1) : 128;
|
length[2] = (n) ? (n + 1) : 128;
|
||||||
@@ -678,9 +681,9 @@ PQRYRES ODBCPrimaryKeys(PGLOBAL g, ODBConn *op, char *dsn, char *table)
|
|||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
n = ocp->GetMaxValue(SQL_MAX_COLUMNS_IN_TABLE);
|
n = ocp->GetMaxValue(SQL_MAX_COLUMNS_IN_TABLE);
|
||||||
maxres = (n) ? (int)n : 250;
|
maxres = (n) ? (int)n : 250;
|
||||||
n = ocp->GetMaxValue(SQL_MAX_QUALIFIER_NAME_LEN);
|
n = ocp->GetMaxValue(SQL_MAX_CATALOG_NAME_LEN);
|
||||||
length[0] = (n) ? (n + 1) : 128;
|
length[0] = (n) ? (n + 1) : 128;
|
||||||
n = ocp->GetMaxValue(SQL_MAX_USER_NAME_LEN);
|
n = ocp->GetMaxValue(SQL_MAX_SCHEMA_NAME_LEN);
|
||||||
length[1] = (n) ? (n + 1) : 128;
|
length[1] = (n) ? (n + 1) : 128;
|
||||||
n = ocp->GetMaxValue(SQL_MAX_TABLE_NAME_LEN);
|
n = ocp->GetMaxValue(SQL_MAX_TABLE_NAME_LEN);
|
||||||
length[2] = (n) ? (n + 1) : 128;
|
length[2] = (n) ? (n + 1) : 128;
|
||||||
@@ -761,11 +764,11 @@ PQRYRES ODBCStatistics(PGLOBAL g, ODBConn *op, char *dsn, char *pat,
|
|||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
n = 1 + ocp->GetMaxValue(SQL_MAX_COLUMNS_IN_INDEX);
|
n = 1 + ocp->GetMaxValue(SQL_MAX_COLUMNS_IN_INDEX);
|
||||||
maxres = (n) ? (int)n : 32;
|
maxres = (n) ? (int)n : 32;
|
||||||
n = ocp->GetMaxValue(SQL_MAX_USER_NAME_LEN);
|
n = ocp->GetMaxValue(SQL_MAX_SCHEMA_NAME_LEN);
|
||||||
length[1] = (n) ? (n + 1) : 128;
|
length[1] = (n) ? (n + 1) : 128;
|
||||||
n = ocp->GetMaxValue(SQL_MAX_TABLE_NAME_LEN);
|
n = ocp->GetMaxValue(SQL_MAX_TABLE_NAME_LEN);
|
||||||
length[2] = length[5] = (n) ? (n + 1) : 128;
|
length[2] = length[5] = (n) ? (n + 1) : 128;
|
||||||
n = ocp->GetMaxValue(SQL_MAX_QUALIFIER_NAME_LEN);
|
n = ocp->GetMaxValue(SQL_MAX_CATALOG_NAME_LEN);
|
||||||
length[0] = length[4] = (n) ? (n + 1) : length[2];
|
length[0] = length[4] = (n) ? (n + 1) : length[2];
|
||||||
n = ocp->GetMaxValue(SQL_MAX_COLUMN_NAME_LEN);
|
n = ocp->GetMaxValue(SQL_MAX_COLUMN_NAME_LEN);
|
||||||
length[7] = (n) ? (n + 1) : 128;
|
length[7] = (n) ? (n + 1) : 128;
|
||||||
@@ -1649,34 +1652,34 @@ int ODBConn::ExecuteSQL(void)
|
|||||||
bool ODBConn::BindParam(ODBCCOL *colp)
|
bool ODBConn::BindParam(ODBCCOL *colp)
|
||||||
{
|
{
|
||||||
void *buf;
|
void *buf;
|
||||||
UWORD n = colp->GetRank();
|
int buftype = colp->GetResultType();
|
||||||
SWORD ct, sqlt;
|
SQLUSMALLINT n = colp->GetRank();
|
||||||
UDWORD len;
|
SQLSMALLINT ct, sqlt, dec, nul;
|
||||||
|
SQLULEN colsize;
|
||||||
|
SQLLEN len;
|
||||||
SQLLEN *strlen = colp->GetStrLen();
|
SQLLEN *strlen = colp->GetStrLen();
|
||||||
RETCODE rc;
|
SQLRETURN rc;
|
||||||
|
|
||||||
#if 0
|
|
||||||
try {
|
try {
|
||||||
SWORD dec, nul;
|
rc = SQLDescribeParam(m_hstmt, n, &sqlt, &colsize, &dec, &nul);
|
||||||
rc = SQLDescribeParam(m_hstmt, n, &sqlt, &len, &dec, &nul);
|
|
||||||
|
|
||||||
if (!Check(rc))
|
if (!Check(rc))
|
||||||
ThrowDBX(rc, m_hstmt);
|
ThrowDBX(rc, "SQLDescribeParam", m_hstmt);
|
||||||
|
|
||||||
} catch(DBX *x) {
|
} catch(DBX *x) {
|
||||||
strcpy(m_G->Message, x->GetErrorMessage(0));
|
strcpy(m_G->Message, x->GetErrorMessage(0));
|
||||||
|
colsize = colp->GetPrecision();
|
||||||
|
sqlt = GetSQLType(buftype);
|
||||||
} // end try/catch
|
} // end try/catch
|
||||||
#endif // 0
|
|
||||||
|
|
||||||
buf = colp->GetBuffer(0);
|
buf = colp->GetBuffer(0);
|
||||||
len = IsTypeNum(colp->GetResultType()) ? 0 : colp->GetBuflen();
|
len = IsTypeChar(buftype) ? colp->GetBuflen() : 0;
|
||||||
ct = GetSQLCType(colp->GetResultType());
|
ct = GetSQLCType(buftype);
|
||||||
sqlt = GetSQLType(colp->GetResultType());
|
*strlen = IsTypeChar(buftype) ? SQL_NTS : 0;
|
||||||
*strlen = IsTypeNum(colp->GetResultType()) ? 0 : SQL_NTS;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
rc = SQLBindParameter(m_hstmt, n, SQL_PARAM_INPUT, ct, sqlt,
|
rc = SQLBindParameter(m_hstmt, n, SQL_PARAM_INPUT, ct, sqlt,
|
||||||
len, 0, buf, 0, strlen);
|
colsize, dec, buf, len, strlen);
|
||||||
|
|
||||||
if (!Check(rc))
|
if (!Check(rc))
|
||||||
ThrowDBX(rc, "SQLBindParameter", m_hstmt);
|
ThrowDBX(rc, "SQLBindParameter", m_hstmt);
|
||||||
@@ -2228,7 +2231,7 @@ int ODBConn::GetCatInfo(CATPARM *cap)
|
|||||||
((STRBLK*)crp->Kdata)->SetSorted(true);
|
((STRBLK*)crp->Kdata)->SetSorted(true);
|
||||||
} // endif len
|
} // endif len
|
||||||
|
|
||||||
pval[n] = AllocateValue(g, crp->Type, len, 0);
|
pval[n] = AllocateValue(g, crp->Type, len);
|
||||||
buffer = pval[n]->GetTo_Val();
|
buffer = pval[n]->GetTo_Val();
|
||||||
vl = vlen + n;
|
vl = vlen + n;
|
||||||
|
|
||||||
|
@@ -1523,7 +1523,7 @@ void PlugPutOut(PGLOBAL g, FILE *f, short t, void *v, uint n)
|
|||||||
fprintf(f, "%s%s\n", m, (PSZ)v);
|
fprintf(f, "%s%s\n", m, (PSZ)v);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_FLOAT:
|
case TYPE_DOUBLE:
|
||||||
fprintf(f, "%s%lf\n", m, *(double *)v);
|
fprintf(f, "%s%lf\n", m, *(double *)v);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@@ -38,13 +38,13 @@ char *GetMsgid(int id)
|
|||||||
case IDS_13: p = "%s: cl<63> de connexion invalide %d"; break;
|
case IDS_13: p = "%s: cl<63> de connexion invalide %d"; break;
|
||||||
case IDS_14: p = "SafeDB: %s rc=%d"; break;
|
case IDS_14: p = "SafeDB: %s rc=%d"; break;
|
||||||
case IDS_15: p = "Mauvaise Dll de communication appel<65>e par le moteur %s"; break;
|
case IDS_15: p = "Mauvaise Dll de communication appel<65>e par le moteur %s"; break;
|
||||||
case IDS_TAB_01: p = "Qualificateur"; break;
|
case IDS_TAB_01: p = "Catalogue"; break;
|
||||||
case IDS_TAB_02: p = "Propri<EFBFBD>taire"; break;
|
case IDS_TAB_02: p = "Sch<EFBFBD>ma"; break;
|
||||||
case IDS_TAB_03: p = "Nom"; break;
|
case IDS_TAB_03: p = "Nom"; break;
|
||||||
case IDS_TAB_04: p = "Type"; break;
|
case IDS_TAB_04: p = "Type"; break;
|
||||||
case IDS_TAB_05: p = "Remarque"; break;
|
case IDS_TAB_05: p = "Remarque"; break;
|
||||||
case IDS_COL_01: p = "Qualif_Table"; break;
|
case IDS_COL_01: p = "Cat_Table"; break;
|
||||||
case IDS_COL_02: p = "Prop_Tabl"; break;
|
case IDS_COL_02: p = "Schem_Table"; break;
|
||||||
case IDS_COL_03: p = "Nom_Table"; break;
|
case IDS_COL_03: p = "Nom_Table"; break;
|
||||||
case IDS_COL_04: p = "Nom_Colonne"; break;
|
case IDS_COL_04: p = "Nom_Colonne"; break;
|
||||||
case IDS_COL_05: p = "Type_Donn<EFBFBD>es"; break;
|
case IDS_COL_05: p = "Type_Donn<EFBFBD>es"; break;
|
||||||
@@ -70,18 +70,18 @@ char *GetMsgid(int id)
|
|||||||
case IDS_INF_13: p = "Nom_Type_Local"; break;
|
case IDS_INF_13: p = "Nom_Type_Local"; break;
|
||||||
case IDS_INF_14: p = "Echelle_Minimum"; break;
|
case IDS_INF_14: p = "Echelle_Minimum"; break;
|
||||||
case IDS_INF_15: p = "Echelle_Maximum"; break;
|
case IDS_INF_15: p = "Echelle_Maximum"; break;
|
||||||
case IDS_PKY_01: p = "Qualif_Table"; break;
|
case IDS_PKY_01: p = "Cat_Table"; break;
|
||||||
case IDS_PKY_02: p = "Prop_Table"; break;
|
case IDS_PKY_02: p = "Schem_Table"; break;
|
||||||
case IDS_PKY_03: p = "Nom_Table"; break;
|
case IDS_PKY_03: p = "Nom_Table"; break;
|
||||||
case IDS_PKY_04: p = "Nom_Colonne"; break;
|
case IDS_PKY_04: p = "Nom_Colonne"; break;
|
||||||
case IDS_PKY_05: p = "Num<EFBFBD>ro_Cl<EFBFBD>"; break;
|
case IDS_PKY_05: p = "Num<EFBFBD>ro_Cl<EFBFBD>"; break;
|
||||||
case IDS_PKY_06: p = "Nom_Cl<EFBFBD>"; break;
|
case IDS_PKY_06: p = "Nom_Cl<EFBFBD>"; break;
|
||||||
case IDS_FKY_01: p = "PKTable_Qualifier"; break;
|
case IDS_FKY_01: p = "PKTable_Catalog"; break;
|
||||||
case IDS_FKY_02: p = "PKTable_Owner"; break;
|
case IDS_FKY_02: p = "PKTable_Schema"; break;
|
||||||
case IDS_FKY_03: p = "PKTable_Name"; break;
|
case IDS_FKY_03: p = "PKTable_Name"; break;
|
||||||
case IDS_FKY_04: p = "PKColumn_Name"; break;
|
case IDS_FKY_04: p = "PKColumn_Name"; break;
|
||||||
case IDS_FKY_05: p = "FKTable_Qualifier"; break;
|
case IDS_FKY_05: p = "FKTable_Catalog"; break;
|
||||||
case IDS_FKY_06: p = "FKTable_Owner"; break;
|
case IDS_FKY_06: p = "FKTable_Schema"; break;
|
||||||
case IDS_FKY_07: p = "FKTable_Name"; break;
|
case IDS_FKY_07: p = "FKTable_Name"; break;
|
||||||
case IDS_FKY_08: p = "FKColumn_Name"; break;
|
case IDS_FKY_08: p = "FKColumn_Name"; break;
|
||||||
case IDS_FKY_09: p = "Key_Seq"; break;
|
case IDS_FKY_09: p = "Key_Seq"; break;
|
||||||
@@ -89,8 +89,8 @@ char *GetMsgid(int id)
|
|||||||
case IDS_FKY_11: p = "Delete_Rule"; break;
|
case IDS_FKY_11: p = "Delete_Rule"; break;
|
||||||
case IDS_FKY_12: p = "FK_Name"; break;
|
case IDS_FKY_12: p = "FK_Name"; break;
|
||||||
case IDS_FKY_13: p = "PK_Name"; break;
|
case IDS_FKY_13: p = "PK_Name"; break;
|
||||||
case IDS_STA_01: p = "Table_Qualifier"; break;
|
case IDS_STA_01: p = "Table_Catalog"; break;
|
||||||
case IDS_STA_02: p = "Table_Owner"; break;
|
case IDS_STA_02: p = "Table_Schema"; break;
|
||||||
case IDS_STA_03: p = "Table_Name"; break;
|
case IDS_STA_03: p = "Table_Name"; break;
|
||||||
case IDS_STA_04: p = "Non_Unique"; break;
|
case IDS_STA_04: p = "Non_Unique"; break;
|
||||||
case IDS_STA_05: p = "Index_Qualifier"; break;
|
case IDS_STA_05: p = "Index_Qualifier"; break;
|
||||||
@@ -162,18 +162,18 @@ char *GetMsgid(int id)
|
|||||||
case IDS_INF_13: p = "Local_Type_Name"; break;
|
case IDS_INF_13: p = "Local_Type_Name"; break;
|
||||||
case IDS_INF_14: p = "Minimum_Scale"; break;
|
case IDS_INF_14: p = "Minimum_Scale"; break;
|
||||||
case IDS_INF_15: p = "Maximum_Scale"; break;
|
case IDS_INF_15: p = "Maximum_Scale"; break;
|
||||||
case IDS_PKY_01: p = "Table_Qualifier"; break;
|
case IDS_PKY_01: p = "Table_Catalog"; break;
|
||||||
case IDS_PKY_02: p = "Table_Owner"; break;
|
case IDS_PKY_02: p = "Table_Schema"; break;
|
||||||
case IDS_PKY_03: p = "Table_Name"; break;
|
case IDS_PKY_03: p = "Table_Name"; break;
|
||||||
case IDS_PKY_04: p = "Column_Name"; break;
|
case IDS_PKY_04: p = "Column_Name"; break;
|
||||||
case IDS_PKY_05: p = "Key_Seq"; break;
|
case IDS_PKY_05: p = "Key_Seq"; break;
|
||||||
case IDS_PKY_06: p = "Pk_Name"; break;
|
case IDS_PKY_06: p = "Pk_Name"; break;
|
||||||
case IDS_FKY_01: p = "PKTable_Qualifier"; break;
|
case IDS_FKY_01: p = "PKTable_Catalog"; break;
|
||||||
case IDS_FKY_02: p = "PKTable_Owner"; break;
|
case IDS_FKY_02: p = "PKTable_Schema"; break;
|
||||||
case IDS_FKY_03: p = "PKTable_Name"; break;
|
case IDS_FKY_03: p = "PKTable_Name"; break;
|
||||||
case IDS_FKY_04: p = "PKColumn_Name"; break;
|
case IDS_FKY_04: p = "PKColumn_Name"; break;
|
||||||
case IDS_FKY_05: p = "FKTable_Qualifier"; break;
|
case IDS_FKY_05: p = "FKTable_Catalog"; break;
|
||||||
case IDS_FKY_06: p = "FKTable_Owner"; break;
|
case IDS_FKY_06: p = "FKTable_Schema"; break;
|
||||||
case IDS_FKY_07: p = "FKTable_Name"; break;
|
case IDS_FKY_07: p = "FKTable_Name"; break;
|
||||||
case IDS_FKY_08: p = "FKColumn_Name"; break;
|
case IDS_FKY_08: p = "FKColumn_Name"; break;
|
||||||
case IDS_FKY_09: p = "Key_Seq"; break;
|
case IDS_FKY_09: p = "Key_Seq"; break;
|
||||||
@@ -181,8 +181,8 @@ char *GetMsgid(int id)
|
|||||||
case IDS_FKY_11: p = "Delete_Rule"; break;
|
case IDS_FKY_11: p = "Delete_Rule"; break;
|
||||||
case IDS_FKY_12: p = "FK_Name"; break;
|
case IDS_FKY_12: p = "FK_Name"; break;
|
||||||
case IDS_FKY_13: p = "PK_Name"; break;
|
case IDS_FKY_13: p = "PK_Name"; break;
|
||||||
case IDS_STA_01: p = "Table_Qualifier"; break;
|
case IDS_STA_01: p = "Table_Catalog"; break;
|
||||||
case IDS_STA_02: p = "Table_Owner"; break;
|
case IDS_STA_02: p = "Table_Schema"; break;
|
||||||
case IDS_STA_03: p = "Table_Name"; break;
|
case IDS_STA_03: p = "Table_Name"; break;
|
||||||
case IDS_STA_04: p = "Non_Unique"; break;
|
case IDS_STA_04: p = "Non_Unique"; break;
|
||||||
case IDS_STA_05: p = "Index_Qualifier"; break;
|
case IDS_STA_05: p = "Index_Qualifier"; break;
|
||||||
|
@@ -73,7 +73,7 @@ RELDEF::RELDEF(void)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
TABDEF::TABDEF(void)
|
TABDEF::TABDEF(void)
|
||||||
{
|
{
|
||||||
Owner = NULL;
|
Schema = NULL;
|
||||||
Desc = NULL;
|
Desc = NULL;
|
||||||
Catfunc = FNC_NO;
|
Catfunc = FNC_NO;
|
||||||
Card = 0;
|
Card = 0;
|
||||||
@@ -338,9 +338,9 @@ COLCRT::COLCRT(PSZ name)
|
|||||||
Fmt = NULL;
|
Fmt = NULL;
|
||||||
Offset = -1;
|
Offset = -1;
|
||||||
Long = -1;
|
Long = -1;
|
||||||
//Freq = -1;
|
Precision = -1;
|
||||||
Key = -1;
|
Key = -1;
|
||||||
Prec = -1;
|
Scale = -1;
|
||||||
Opt = -1;
|
Opt = -1;
|
||||||
DataType = '*';
|
DataType = '*';
|
||||||
} // end of COLCRT constructor for table creation
|
} // end of COLCRT constructor for table creation
|
||||||
@@ -354,9 +354,9 @@ COLCRT::COLCRT(void)
|
|||||||
Fmt = NULL;
|
Fmt = NULL;
|
||||||
Offset = 0;
|
Offset = 0;
|
||||||
Long = 0;
|
Long = 0;
|
||||||
//Freq = 0;
|
Precision = 0;
|
||||||
Key = 0;
|
Key = 0;
|
||||||
Prec = 0;
|
Scale = 0;
|
||||||
Opt = 0;
|
Opt = 0;
|
||||||
DataType = '*';
|
DataType = '*';
|
||||||
} // end of COLCRT constructor for table & view definition
|
} // end of COLCRT constructor for table & view definition
|
||||||
@@ -394,8 +394,10 @@ int COLDEF::Define(PGLOBAL g, void *memp, PCOLINFO cfp, int poff)
|
|||||||
|
|
||||||
strcpy(F.Type, GetFormatType(Buf_Type));
|
strcpy(F.Type, GetFormatType(Buf_Type));
|
||||||
F.Length = cfp->Length;
|
F.Length = cfp->Length;
|
||||||
F.Prec = cfp->Prec;
|
F.Prec = cfp->Scale;
|
||||||
Offset = (cfp->Offset < 0) ? poff : cfp->Offset;
|
Offset = (cfp->Offset < 0) ? poff : cfp->Offset;
|
||||||
|
Precision = cfp->Precision;
|
||||||
|
Scale = cfp->Scale;
|
||||||
Long = cfp->Length;
|
Long = cfp->Length;
|
||||||
Opt = cfp->Opt;
|
Opt = cfp->Opt;
|
||||||
Key = cfp->Key;
|
Key = cfp->Key;
|
||||||
|
@@ -87,7 +87,7 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Members
|
// Members
|
||||||
PSZ Owner; /* Table owner (for ODBC) */
|
PSZ Schema; /* Table schema (for ODBC) */
|
||||||
PSZ Desc; /* Table description */
|
PSZ Desc; /* Table description */
|
||||||
uint Catfunc; /* Catalog function ID */
|
uint Catfunc; /* Catalog function ID */
|
||||||
int Card; /* (max) number of rows in table */
|
int Card; /* (max) number of rows in table */
|
||||||
@@ -149,6 +149,7 @@ class DllExport COLCRT : public BLOCK { /* Column description block
|
|||||||
PSZ GetFmt(void) {return Fmt;}
|
PSZ GetFmt(void) {return Fmt;}
|
||||||
int GetOpt(void) {return Opt;}
|
int GetOpt(void) {return Opt;}
|
||||||
int GetLong(void) {return Long;}
|
int GetLong(void) {return Long;}
|
||||||
|
int GetPrecision(void) {return Precision;}
|
||||||
int GetOffset(void) {return Offset;}
|
int GetOffset(void) {return Offset;}
|
||||||
void SetOffset(int offset) {Offset = offset;}
|
void SetOffset(int offset) {Offset = offset;}
|
||||||
|
|
||||||
@@ -161,7 +162,8 @@ class DllExport COLCRT : public BLOCK { /* Column description block
|
|||||||
int Offset; /* Offset of field within record */
|
int Offset; /* Offset of field within record */
|
||||||
int Long; /* Length of field in file record (!BIN) */
|
int Long; /* Length of field in file record (!BIN) */
|
||||||
int Key; /* Key (greater than 1 if multiple) */
|
int Key; /* Key (greater than 1 if multiple) */
|
||||||
int Prec; /* Precision for float values */
|
int Precision; /* Logical column length */
|
||||||
|
int Scale; /* Decimals for float/decimal values */
|
||||||
int Opt; /* 0:Not 1:clustered 2:sorted-asc 3:desc */
|
int Opt; /* 0:Not 1:clustered 2:sorted-asc 3:desc */
|
||||||
char DataType; /* Internal data type (C, N, F, T) */
|
char DataType; /* Internal data type (C, N, F, T) */
|
||||||
}; // end of COLCRT
|
}; // end of COLCRT
|
||||||
|
@@ -30,7 +30,7 @@ XTAB::XTAB(LPCSTR name, LPCSTR srcdef) : Name(name)
|
|||||||
Next = NULL;
|
Next = NULL;
|
||||||
To_Tdb = NULL;
|
To_Tdb = NULL;
|
||||||
Srcdef = srcdef;
|
Srcdef = srcdef;
|
||||||
Creator = NULL;
|
Schema = NULL;
|
||||||
Qualifier = NULL;
|
Qualifier = NULL;
|
||||||
|
|
||||||
#ifdef DEBTRACE
|
#ifdef DEBTRACE
|
||||||
@@ -46,7 +46,7 @@ XTAB::XTAB(PTABLE tp) : Name(tp->Name)
|
|||||||
Next = NULL;
|
Next = NULL;
|
||||||
To_Tdb = NULL;
|
To_Tdb = NULL;
|
||||||
Srcdef = tp->Srcdef;
|
Srcdef = tp->Srcdef;
|
||||||
Creator = tp->Creator;
|
Schema = tp->Schema;
|
||||||
Qualifier = tp->Qualifier;
|
Qualifier = tp->Qualifier;
|
||||||
|
|
||||||
#ifdef DEBTRACE
|
#ifdef DEBTRACE
|
||||||
@@ -83,7 +83,7 @@ void XTAB::Print(PGLOBAL g, FILE *f, uint n)
|
|||||||
|
|
||||||
for (PTABLE tp = this; tp; tp = tp->Next) {
|
for (PTABLE tp = this; tp; tp = tp->Next) {
|
||||||
fprintf(f, "%sTABLE: %s.%s %s\n",
|
fprintf(f, "%sTABLE: %s.%s %s\n",
|
||||||
m, SVP(tp->Creator), tp->Name, SVP(tp->Srcdef));
|
m, SVP(tp->Schema), tp->Name, SVP(tp->Srcdef));
|
||||||
PlugPutOut(g, f, TYPE_TDB, tp->To_Tdb, n + 2);
|
PlugPutOut(g, f, TYPE_TDB, tp->To_Tdb, n + 2);
|
||||||
} /* endfor tp */
|
} /* endfor tp */
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ void XTAB::Print(PGLOBAL g, char *ps, uint z)
|
|||||||
|
|
||||||
for (PTABLE tp = this; tp && n > 0; tp = tp->Next) {
|
for (PTABLE tp = this; tp && n > 0; tp = tp->Next) {
|
||||||
i = sprintf(buf, "TABLE: %s.%s %s To_Tdb=%p ",
|
i = sprintf(buf, "TABLE: %s.%s %s To_Tdb=%p ",
|
||||||
SVP(tp->Creator), tp->Name, SVP(tp->Srcdef), tp->To_Tdb);
|
SVP(tp->Schema), tp->Name, SVP(tp->Srcdef), tp->To_Tdb);
|
||||||
strncat(ps, buf, n);
|
strncat(ps, buf, n);
|
||||||
n -= i;
|
n -= i;
|
||||||
} // endif tp
|
} // endif tp
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Definition of class XTAB with all its method functions. */
|
/* Definition of class XTAB with all its method functions. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
class DllExport XTAB: public BLOCK { // Table Name-Owner-Srcdef block.
|
class DllExport XTAB: public BLOCK { // Table Name-Schema-Srcdef block.
|
||||||
friend class TDBPRX;
|
friend class TDBPRX;
|
||||||
friend class TDBTBM;
|
friend class TDBTBM;
|
||||||
public:
|
public:
|
||||||
@@ -28,12 +28,12 @@ class DllExport XTAB: public BLOCK { // Table Name-Owner-Srcdef block.
|
|||||||
PTDB GetTo_Tdb(void) {return To_Tdb;}
|
PTDB GetTo_Tdb(void) {return To_Tdb;}
|
||||||
LPCSTR GetName(void) {return Name;}
|
LPCSTR GetName(void) {return Name;}
|
||||||
LPCSTR GetSrc(void) {return Srcdef;}
|
LPCSTR GetSrc(void) {return Srcdef;}
|
||||||
LPCSTR GetCreator(void) {return Creator;}
|
LPCSTR GetSchema(void) {return Schema;}
|
||||||
LPCSTR GetQualifier(void) {return Qualifier;}
|
LPCSTR GetQualifier(void) {return Qualifier;}
|
||||||
void SetTo_Tdb(PTDB tdbp) {To_Tdb = tdbp;}
|
void SetTo_Tdb(PTDB tdbp) {To_Tdb = tdbp;}
|
||||||
void SetName(LPCSTR name) {Name = name;}
|
void SetName(LPCSTR name) {Name = name;}
|
||||||
void SetSrc(LPCSTR srcdef) {Srcdef = srcdef;}
|
void SetSrc(LPCSTR srcdef) {Srcdef = srcdef;}
|
||||||
void SetCreator(LPCSTR crname) {Creator = crname;}
|
void SetSchema(LPCSTR schname) {Schema = schname;}
|
||||||
void SetQualifier(LPCSTR qname) {Qualifier = qname;}
|
void SetQualifier(LPCSTR qname) {Qualifier = qname;}
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
@@ -47,7 +47,7 @@ class DllExport XTAB: public BLOCK { // Table Name-Owner-Srcdef block.
|
|||||||
PTDB To_Tdb; // Points to Table description Block
|
PTDB To_Tdb; // Points to Table description Block
|
||||||
LPCSTR Name; // Table name
|
LPCSTR Name; // Table name
|
||||||
LPCSTR Srcdef; // Table Source definition
|
LPCSTR Srcdef; // Table Source definition
|
||||||
LPCSTR Creator; // Creator name
|
LPCSTR Schema; // Schema name
|
||||||
LPCSTR Qualifier; // Qualifier name
|
LPCSTR Qualifier; // Qualifier name
|
||||||
}; // end of class XTAB
|
}; // end of class XTAB
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ class DllExport COLUMN: public XOBJECT { // Column Name/Qualifier block.
|
|||||||
virtual int GetResultType(void) {assert(false); return TYPE_VOID;}
|
virtual int GetResultType(void) {assert(false); return TYPE_VOID;}
|
||||||
virtual int GetLength(void) {assert(false); return 0;}
|
virtual int GetLength(void) {assert(false); return 0;}
|
||||||
virtual int GetLengthEx(void) {assert(false); return 0;}
|
virtual int GetLengthEx(void) {assert(false); return 0;}
|
||||||
virtual int GetPrecision() {assert(false); return 0;};
|
virtual int GetScale() {assert(false); return 0;};
|
||||||
LPCSTR GetName(void) {return Name;}
|
LPCSTR GetName(void) {return Name;}
|
||||||
LPCSTR GetQualifier(void) {return Qualifier;}
|
LPCSTR GetQualifier(void) {return Qualifier;}
|
||||||
PTABLE GetTo_Table(void) {return To_Table;}
|
PTABLE GetTo_Table(void) {return To_Table;}
|
||||||
|
@@ -499,7 +499,10 @@ int TDBDOS::MakeIndex(PGLOBAL g, PIXDEF pxdf, bool add)
|
|||||||
if (!(colp = ColDB(g, kdp->GetName(), 0))) {
|
if (!(colp = ColDB(g, kdp->GetName(), 0))) {
|
||||||
sprintf(g->Message, MSG(INDX_COL_NOTIN), kdp->GetName(), Name);
|
sprintf(g->Message, MSG(INDX_COL_NOTIN), kdp->GetName(), Name);
|
||||||
goto err;
|
goto err;
|
||||||
} // endif colp
|
} else if (colp->GetResultType() == TYPE_DECIM) {
|
||||||
|
sprintf(g->Message, "Decimal columns are not indexable yet");
|
||||||
|
goto err;
|
||||||
|
} // endif Type
|
||||||
|
|
||||||
colp->InitValue(g);
|
colp->InitValue(g);
|
||||||
n = max(n, xdp->GetNparts());
|
n = max(n, xdp->GetNparts());
|
||||||
@@ -944,7 +947,7 @@ DOSCOL::DOSCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PSZ am)
|
|||||||
} // endswitch p
|
} // endswitch p
|
||||||
|
|
||||||
// Set number of decimal digits
|
// Set number of decimal digits
|
||||||
Dcm = (*p) ? atoi(p) : GetPrecision();
|
Dcm = (*p) ? atoi(p) : GetScale();
|
||||||
} // endif fmt
|
} // endif fmt
|
||||||
|
|
||||||
if (trace)
|
if (trace)
|
||||||
@@ -1006,10 +1009,10 @@ bool DOSCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
|
|||||||
if (GetDomain() || ((DTVAL *)value)->IsFormatted())
|
if (GetDomain() || ((DTVAL *)value)->IsFormatted())
|
||||||
goto newval; // This will make a new value;
|
goto newval; // This will make a new value;
|
||||||
|
|
||||||
} else if (Buf_Type == TYPE_FLOAT)
|
} else if (Buf_Type == TYPE_DOUBLE)
|
||||||
// Float values must be written with the correct (column) precision
|
// Float values must be written with the correct (column) precision
|
||||||
// Note: maybe this should be forced by ShowValue instead of this ?
|
// Note: maybe this should be forced by ShowValue instead of this ?
|
||||||
value->SetPrec(GetPrecision());
|
value->SetPrec(GetScale());
|
||||||
|
|
||||||
Value = value; // Directly access the external value
|
Value = value; // Directly access the external value
|
||||||
} else {
|
} else {
|
||||||
@@ -1094,7 +1097,7 @@ void DOSCOL::ReadColumn(PGLOBAL g)
|
|||||||
} // endif SetValue_char
|
} // endif SetValue_char
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TYPE_FLOAT:
|
case TYPE_DOUBLE:
|
||||||
Value->SetValue_char(p, field);
|
Value->SetValue_char(p, field);
|
||||||
dval = Value->GetFloatValue();
|
dval = Value->GetFloatValue();
|
||||||
|
|
||||||
@@ -1207,7 +1210,7 @@ void DOSCOL::WriteColumn(PGLOBAL g)
|
|||||||
|
|
||||||
len = sprintf(Buf, fmt, field - i, Value->GetTinyValue());
|
len = sprintf(Buf, fmt, field - i, Value->GetTinyValue());
|
||||||
break;
|
break;
|
||||||
case TYPE_FLOAT:
|
case TYPE_DOUBLE:
|
||||||
strcpy(fmt, (Ldz) ? "%0*.*lf" : "%*.*lf");
|
strcpy(fmt, (Ldz) ? "%0*.*lf" : "%*.*lf");
|
||||||
sprintf(Buf, fmt, field + ((Nod && Dcm) ? 1 : 0),
|
sprintf(Buf, fmt, field + ((Nod && Dcm) ? 1 : 0),
|
||||||
Dcm, Value->GetFloatValue());
|
Dcm, Value->GetFloatValue());
|
||||||
|
@@ -72,7 +72,7 @@ extern "C" int trace;
|
|||||||
/* CSVColumns: constructs the result blocks containing the description */
|
/* CSVColumns: constructs the result blocks containing the description */
|
||||||
/* of all the columns of a CSV file that will be retrieved by #GetData.*/
|
/* of all the columns of a CSV file that will be retrieved by #GetData.*/
|
||||||
/* Note: the algorithm to set the type is based on the internal values */
|
/* Note: the algorithm to set the type is based on the internal values */
|
||||||
/* of types (TYPE_STRING < TYPE_FLOAT < TYPE_INT) (1 < 2 < 7). */
|
/* of types (TYPE_STRING < TYPE_DOUBLE < TYPE_INT) (1 < 2 < 7). */
|
||||||
/* If these values are changed, this will have to be revisited. */
|
/* If these values are changed, this will have to be revisited. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q,
|
PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q,
|
||||||
@@ -230,9 +230,9 @@ PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q,
|
|||||||
if (n) {
|
if (n) {
|
||||||
len[i] = max(len[i], n);
|
len[i] = max(len[i], n);
|
||||||
type = (digit || (dec && n == 1)) ? TYPE_STRING
|
type = (digit || (dec && n == 1)) ? TYPE_STRING
|
||||||
: (dec) ? TYPE_FLOAT : TYPE_INT;
|
: (dec) ? TYPE_DOUBLE : TYPE_INT;
|
||||||
typ[i] = min(type, typ[i]);
|
typ[i] = min(type, typ[i]);
|
||||||
prc[i] = max((typ[i] == TYPE_FLOAT) ? (dec - 1) : 0, prc[i]);
|
prc[i] = max((typ[i] == TYPE_DOUBLE) ? (dec - 1) : 0, prc[i]);
|
||||||
} // endif n
|
} // endif n
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
@@ -310,9 +310,9 @@ PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q,
|
|||||||
if (n) {
|
if (n) {
|
||||||
len[i] = max(len[i], n);
|
len[i] = max(len[i], n);
|
||||||
type = (digit || n == 0 || (dec && n == 1)) ? TYPE_STRING
|
type = (digit || n == 0 || (dec && n == 1)) ? TYPE_STRING
|
||||||
: (dec) ? TYPE_FLOAT : TYPE_INT;
|
: (dec) ? TYPE_DOUBLE : TYPE_INT;
|
||||||
typ[i] = min(type, typ[i]);
|
typ[i] = min(type, typ[i]);
|
||||||
prc[i] = max((typ[i] == TYPE_FLOAT) ? (dec - 1) : 0, prc[i]);
|
prc[i] = max((typ[i] == TYPE_DOUBLE) ? (dec - 1) : 0, prc[i]);
|
||||||
} // endif n
|
} // endif n
|
||||||
|
|
||||||
imax = max(imax, i+1);
|
imax = max(imax, i+1);
|
||||||
|
@@ -1117,7 +1117,7 @@ MYSQLCOL::MYSQLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
|
|||||||
} // endif cprec
|
} // endif cprec
|
||||||
|
|
||||||
// Set additional MySQL access method information for column.
|
// Set additional MySQL access method information for column.
|
||||||
Long = cdp->GetLong();
|
Precision = Long = cdp->GetLong();
|
||||||
Bind = NULL;
|
Bind = NULL;
|
||||||
To_Val = NULL;
|
To_Val = NULL;
|
||||||
Slen = 0;
|
Slen = 0;
|
||||||
@@ -1136,7 +1136,7 @@ MYSQLCOL::MYSQLCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PSZ am)
|
|||||||
{
|
{
|
||||||
Name = fld->name;
|
Name = fld->name;
|
||||||
Opt = 0;
|
Opt = 0;
|
||||||
Long = fld->length;
|
Precision = Long = fld->length;
|
||||||
Buf_Type = MYSQLtoPLG(fld->type);
|
Buf_Type = MYSQLtoPLG(fld->type);
|
||||||
strcpy(Format.Type, GetFormatType(Buf_Type));
|
strcpy(Format.Type, GetFormatType(Buf_Type));
|
||||||
Format.Length = Long;
|
Format.Length = Long;
|
||||||
@@ -1144,6 +1144,9 @@ MYSQLCOL::MYSQLCOL(MYSQL_FIELD *fld, PTDB tdbp, int i, PSZ am)
|
|||||||
ColUse = U_P;
|
ColUse = U_P;
|
||||||
Nullable = !IS_NOT_NULL(fld->flags);
|
Nullable = !IS_NOT_NULL(fld->flags);
|
||||||
|
|
||||||
|
if (Buf_Type == TYPE_DECIM)
|
||||||
|
Precision = ((Field_new_decimal*)fld)->precision;
|
||||||
|
|
||||||
// Set additional MySQL access method information for column.
|
// Set additional MySQL access method information for column.
|
||||||
Bind = NULL;
|
Bind = NULL;
|
||||||
To_Val = NULL;
|
To_Val = NULL;
|
||||||
@@ -1202,10 +1205,10 @@ bool MYSQLCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
|
|||||||
if (GetDomain() || ((DTVAL *)value)->IsFormatted())
|
if (GetDomain() || ((DTVAL *)value)->IsFormatted())
|
||||||
goto newval; // This will make a new value;
|
goto newval; // This will make a new value;
|
||||||
|
|
||||||
} else if (Buf_Type == TYPE_FLOAT)
|
} else if (Buf_Type == TYPE_DOUBLE)
|
||||||
// Float values must be written with the correct (column) precision
|
// Float values must be written with the correct (column) precision
|
||||||
// Note: maybe this should be forced by ShowValue instead of this ?
|
// Note: maybe this should be forced by ShowValue instead of this ?
|
||||||
value->SetPrec(GetPrecision());
|
value->SetPrec(GetScale());
|
||||||
|
|
||||||
Value = value; // Directly access the external value
|
Value = value; // Directly access the external value
|
||||||
} else {
|
} else {
|
||||||
|
@@ -90,7 +90,7 @@ extern int num_read, num_there, num_eq[2]; // Statistics
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
ODBCDEF::ODBCDEF(void)
|
ODBCDEF::ODBCDEF(void)
|
||||||
{
|
{
|
||||||
Connect = Tabname = Tabowner = Tabqual = Srcdef = Qchar = Qrystr = NULL;
|
Connect= Tabname= Tabschema= Tabcat= Srcdef= Qchar= Qrystr= Sep= NULL;
|
||||||
Catver = Options = Quoted = Maxerr = Maxres = 0;
|
Catver = Options = Quoted = Maxerr = Maxres = 0;
|
||||||
Xsrc = false;
|
Xsrc = false;
|
||||||
} // end of ODBCDEF constructor
|
} // end of ODBCDEF constructor
|
||||||
@@ -104,11 +104,13 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||||||
Tabname = Cat->GetStringCatInfo(g, "Name",
|
Tabname = Cat->GetStringCatInfo(g, "Name",
|
||||||
(Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
|
(Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name);
|
||||||
Tabname = Cat->GetStringCatInfo(g, "Tabname", Tabname);
|
Tabname = Cat->GetStringCatInfo(g, "Tabname", Tabname);
|
||||||
//Tabowner = Cat->GetStringCatInfo(g, "Owner", NULL);
|
Tabschema = Cat->GetStringCatInfo(g, "Dbname", NULL);
|
||||||
Tabowner = Cat->GetStringCatInfo(g, "Dbname", NULL);
|
Tabschema = Cat->GetStringCatInfo(g, "Schema", Tabschema);
|
||||||
Tabqual = Cat->GetStringCatInfo(g, "Qualifier", NULL);
|
Tabcat = Cat->GetStringCatInfo(g, "Qualifier", NULL);
|
||||||
|
Tabcat = Cat->GetStringCatInfo(g, "Catalog", Tabcat);
|
||||||
Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL);
|
Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL);
|
||||||
Qrystr = Cat->GetStringCatInfo(g, "Query_String", "?");
|
Qrystr = Cat->GetStringCatInfo(g, "Query_String", "?");
|
||||||
|
Sep = Cat->GetStringCatInfo(g, "Separator", NULL);
|
||||||
Catver = Cat->GetIntCatInfo("Catver", 2);
|
Catver = Cat->GetIntCatInfo("Catver", 2);
|
||||||
Xsrc = Cat->GetBoolCatInfo("Execsrc", FALSE);
|
Xsrc = Cat->GetBoolCatInfo("Execsrc", FALSE);
|
||||||
Maxerr = Cat->GetIntCatInfo("Maxerr", 0);
|
Maxerr = Cat->GetIntCatInfo("Maxerr", 0);
|
||||||
@@ -170,10 +172,11 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp)
|
|||||||
if (tdp) {
|
if (tdp) {
|
||||||
Connect = tdp->Connect;
|
Connect = tdp->Connect;
|
||||||
TableName = tdp->Tabname;
|
TableName = tdp->Tabname;
|
||||||
Owner = tdp->Tabowner;
|
Schema = tdp->Tabschema;
|
||||||
Qualifier = tdp->Tabqual;
|
Catalog = tdp->Tabcat;
|
||||||
Srcdef = tdp->Srcdef;
|
Srcdef = tdp->Srcdef;
|
||||||
Qrystr = tdp->Qrystr;
|
Qrystr = tdp->Qrystr;
|
||||||
|
Sep = tdp->GetSep();
|
||||||
Options = tdp->Options;
|
Options = tdp->Options;
|
||||||
Quoted = max(0, tdp->GetQuoted());
|
Quoted = max(0, tdp->GetQuoted());
|
||||||
Rows = tdp->GetElemt();
|
Rows = tdp->GetElemt();
|
||||||
@@ -181,10 +184,11 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp)
|
|||||||
} else {
|
} else {
|
||||||
Connect = NULL;
|
Connect = NULL;
|
||||||
TableName = NULL;
|
TableName = NULL;
|
||||||
Owner = NULL;
|
Schema = NULL;
|
||||||
Qualifier = NULL;
|
Catalog = NULL;
|
||||||
Srcdef = NULL;
|
Srcdef = NULL;
|
||||||
Qrystr = NULL;
|
Qrystr = NULL;
|
||||||
|
Sep = 0;
|
||||||
Options = 0;
|
Options = 0;
|
||||||
Quoted = 0;
|
Quoted = 0;
|
||||||
Rows = 0;
|
Rows = 0;
|
||||||
@@ -211,8 +215,8 @@ TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp)
|
|||||||
Cnp = tdbp->Cnp;
|
Cnp = tdbp->Cnp;
|
||||||
Connect = tdbp->Connect;
|
Connect = tdbp->Connect;
|
||||||
TableName = tdbp->TableName;
|
TableName = tdbp->TableName;
|
||||||
Owner = tdbp->Owner;
|
Schema = tdbp->Schema;
|
||||||
Qualifier = tdbp->Qualifier;
|
Catalog = tdbp->Catalog;
|
||||||
Srcdef = tdbp->Srcdef;
|
Srcdef = tdbp->Srcdef;
|
||||||
Qrystr = tdbp->Qrystr;
|
Qrystr = tdbp->Qrystr;
|
||||||
Quote = tdbp->Quote;
|
Quote = tdbp->Quote;
|
||||||
@@ -336,7 +340,7 @@ int TDBODBC::Decode(char *txt, char *buf, size_t n)
|
|||||||
char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
|
char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
|
||||||
{
|
{
|
||||||
char *colist, *tabname, *sql, buf[64];
|
char *colist, *tabname, *sql, buf[64];
|
||||||
LPCSTR ownp = NULL, qualp = NULL;
|
LPCSTR schmp = NULL, catp = NULL;
|
||||||
int len, ncol = 0;
|
int len, ncol = 0;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
PTABLE tablep = To_Table;
|
PTABLE tablep = To_Table;
|
||||||
@@ -406,37 +410,34 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
|
|||||||
len = (strlen(colist) + strlen(buf) + 14);
|
len = (strlen(colist) + strlen(buf) + 14);
|
||||||
len += (To_Filter ? strlen(To_Filter->Body) + 7 : 0);
|
len += (To_Filter ? strlen(To_Filter->Body) + 7 : 0);
|
||||||
|
|
||||||
// if (tablep->GetQualifier()) This is used when using a table
|
if (Catalog && *Catalog)
|
||||||
// qualp = tablep->GetQualifier(); from anotherPlugDB database but
|
catp = Catalog;
|
||||||
// else makes no sense for ODBC.
|
|
||||||
if (Qualifier && *Qualifier)
|
|
||||||
qualp = Qualifier;
|
|
||||||
|
|
||||||
if (qualp)
|
if (catp)
|
||||||
len += (strlen(qualp) + 2);
|
len += (strlen(catp) + 2);
|
||||||
|
|
||||||
if (tablep->GetCreator())
|
if (tablep->GetSchema())
|
||||||
ownp = tablep->GetCreator();
|
schmp = tablep->GetSchema();
|
||||||
else if (Owner && *Owner)
|
else if (Schema && *Schema)
|
||||||
ownp = Owner;
|
schmp = Schema;
|
||||||
|
|
||||||
if (ownp)
|
if (schmp)
|
||||||
len += (strlen(ownp) + 1);
|
len += (strlen(schmp) + 1);
|
||||||
|
|
||||||
sql = (char*)PlugSubAlloc(g, NULL, len);
|
sql = (char*)PlugSubAlloc(g, NULL, len);
|
||||||
strcat(strcat(strcpy(sql, "SELECT "), colist), " FROM ");
|
strcat(strcat(strcpy(sql, "SELECT "), colist), " FROM ");
|
||||||
|
|
||||||
if (qualp) {
|
if (catp) {
|
||||||
strcat(sql, qualp);
|
strcat(sql, catp);
|
||||||
|
|
||||||
if (ownp)
|
if (schmp)
|
||||||
strcat(strcat(sql, "."), ownp);
|
strcat(strcat(sql, "."), schmp);
|
||||||
else
|
else
|
||||||
strcat(sql, ".");
|
strcat(sql, ".");
|
||||||
|
|
||||||
strcat(sql, ".");
|
strcat(sql, ".");
|
||||||
} else if (ownp)
|
} else if (schmp)
|
||||||
strcat(strcat(sql, ownp), ".");
|
strcat(strcat(sql, schmp), ".");
|
||||||
|
|
||||||
strcat(sql, tabname);
|
strcat(sql, tabname);
|
||||||
|
|
||||||
@@ -921,7 +922,8 @@ ODBCCOL::ODBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am)
|
|||||||
} // endif cprec
|
} // endif cprec
|
||||||
|
|
||||||
// Set additional ODBC access method information for column.
|
// Set additional ODBC access method information for column.
|
||||||
Long = cdp->GetLong();
|
//Long = cdp->GetLong();
|
||||||
|
Long = Precision;
|
||||||
//strcpy(F_Date, cdp->F_Date);
|
//strcpy(F_Date, cdp->F_Date);
|
||||||
To_Val = NULL;
|
To_Val = NULL;
|
||||||
Slen = 0;
|
Slen = 0;
|
||||||
@@ -986,10 +988,10 @@ bool ODBCCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
|
|||||||
if (GetDomain() || ((DTVAL *)value)->IsFormatted())
|
if (GetDomain() || ((DTVAL *)value)->IsFormatted())
|
||||||
goto newval; // This will make a new value;
|
goto newval; // This will make a new value;
|
||||||
|
|
||||||
} else if (Buf_Type == TYPE_FLOAT)
|
} else if (Buf_Type == TYPE_DOUBLE)
|
||||||
// Float values must be written with the correct (column) precision
|
// Float values must be written with the correct (column) precision
|
||||||
// Note: maybe this should be forced by ShowValue instead of this ?
|
// Note: maybe this should be forced by ShowValue instead of this ?
|
||||||
value->SetPrec(GetPrecision());
|
value->SetPrec(GetScale());
|
||||||
|
|
||||||
Value = value; // Directly access the external value
|
Value = value; // Directly access the external value
|
||||||
} else {
|
} else {
|
||||||
@@ -1036,12 +1038,14 @@ void ODBCCOL::ReadColumn(PGLOBAL g)
|
|||||||
} else
|
} else
|
||||||
Value->SetNull(false);
|
Value->SetNull(false);
|
||||||
|
|
||||||
if (Bufp && tdbp->Rows)
|
if (Bufp && tdbp->Rows) {
|
||||||
if (Buf_Type == TYPE_DATE)
|
if (Buf_Type == TYPE_DATE)
|
||||||
*Sqlbuf = ((TIMESTAMP_STRUCT*)Bufp)[n];
|
*Sqlbuf = ((TIMESTAMP_STRUCT*)Bufp)[n];
|
||||||
else
|
else
|
||||||
Value->SetValue_pvblk(Blkp, n);
|
Value->SetValue_pvblk(Blkp, n);
|
||||||
|
|
||||||
|
} // endif Bufp
|
||||||
|
|
||||||
if (Buf_Type == TYPE_DATE) {
|
if (Buf_Type == TYPE_DATE) {
|
||||||
struct tm dbtime = {0,0,0,0,0,0,0,0,0};
|
struct tm dbtime = {0,0,0,0,0,0,0,0,0};
|
||||||
|
|
||||||
@@ -1052,6 +1056,13 @@ void ODBCCOL::ReadColumn(PGLOBAL g)
|
|||||||
dbtime.tm_mon = (int)Sqlbuf->month - 1;
|
dbtime.tm_mon = (int)Sqlbuf->month - 1;
|
||||||
dbtime.tm_year = (int)Sqlbuf->year - 1900;
|
dbtime.tm_year = (int)Sqlbuf->year - 1900;
|
||||||
((DTVAL*)Value)->MakeTime(&dbtime);
|
((DTVAL*)Value)->MakeTime(&dbtime);
|
||||||
|
} else if (Buf_Type == TYPE_DECIM && tdbp->Sep) {
|
||||||
|
// Be sure to use decimal point
|
||||||
|
char *p = strchr(Value->GetCharValue(), tdbp->Sep);
|
||||||
|
|
||||||
|
if (p)
|
||||||
|
*p = '.';
|
||||||
|
|
||||||
} // endif Buf_Type
|
} // endif Buf_Type
|
||||||
|
|
||||||
if (g->Trace) {
|
if (g->Trace) {
|
||||||
@@ -1080,7 +1091,8 @@ void ODBCCOL::AllocateBuffers(PGLOBAL g, int rows)
|
|||||||
if (Buf_Type == TYPE_DATE)
|
if (Buf_Type == TYPE_DATE)
|
||||||
Bufp = PlugSubAlloc(g, NULL, rows * sizeof(TIMESTAMP_STRUCT));
|
Bufp = PlugSubAlloc(g, NULL, rows * sizeof(TIMESTAMP_STRUCT));
|
||||||
else {
|
else {
|
||||||
Blkp = AllocValBlock(g, NULL, Buf_Type, rows, Long+1, 0, true, false, false);
|
Blkp = AllocValBlock(g, NULL, Buf_Type, rows, GetBuflen(),
|
||||||
|
GetScale(), true, false, false);
|
||||||
Bufp = Blkp->GetValPointer();
|
Bufp = Blkp->GetValPointer();
|
||||||
} // endelse
|
} // endelse
|
||||||
|
|
||||||
@@ -1107,13 +1119,21 @@ void *ODBCCOL::GetBuffer(DWORD rows)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
SWORD ODBCCOL::GetBuflen(void)
|
SWORD ODBCCOL::GetBuflen(void)
|
||||||
{
|
{
|
||||||
if (Buf_Type == TYPE_DATE)
|
SWORD flen;
|
||||||
return (SWORD)sizeof(TIMESTAMP_STRUCT);
|
|
||||||
else if (Buf_Type == TYPE_STRING)
|
|
||||||
return (SWORD)Value->GetClen() + 1;
|
|
||||||
else
|
|
||||||
return (SWORD)Value->GetClen();
|
|
||||||
|
|
||||||
|
switch (Buf_Type) {
|
||||||
|
case TYPE_DATE:
|
||||||
|
flen = (SWORD)sizeof(TIMESTAMP_STRUCT);
|
||||||
|
break;
|
||||||
|
case TYPE_STRING:
|
||||||
|
case TYPE_DECIM:
|
||||||
|
flen = (SWORD)Value->GetClen() + 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
flen = (SWORD)Value->GetClen();
|
||||||
|
} // endswitch Buf_Type
|
||||||
|
|
||||||
|
return flen;
|
||||||
} // end of GetBuflen
|
} // end of GetBuflen
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -1137,11 +1157,18 @@ void ODBCCOL::WriteColumn(PGLOBAL g)
|
|||||||
Sqlbuf->month = dbtime->tm_mon + 1;
|
Sqlbuf->month = dbtime->tm_mon + 1;
|
||||||
Sqlbuf->year = dbtime->tm_year + 1900;
|
Sqlbuf->year = dbtime->tm_year + 1900;
|
||||||
Sqlbuf->fraction = 0;
|
Sqlbuf->fraction = 0;
|
||||||
|
} else if (Buf_Type == TYPE_DECIM) {
|
||||||
|
// Some data sources require local decimal separator
|
||||||
|
char *p, sep = ((PTDBODBC)To_Tdb)->Sep;
|
||||||
|
|
||||||
|
if (sep && (p = strchr(Value->GetCharValue(), '.')))
|
||||||
|
*p = sep;
|
||||||
|
|
||||||
} // endif Buf_Type
|
} // endif Buf_Type
|
||||||
|
|
||||||
if (Nullable)
|
if (Nullable)
|
||||||
*StrLen = (Value->IsNull()) ? SQL_NULL_DATA :
|
*StrLen = (Value->IsNull()) ? SQL_NULL_DATA :
|
||||||
(IsTypeNum(Buf_Type)) ? 0 : SQL_NTS;
|
(IsTypeChar(Buf_Type)) ? SQL_NTS : 0;
|
||||||
|
|
||||||
} // end of WriteColumn
|
} // end of WriteColumn
|
||||||
|
|
||||||
@@ -1415,7 +1442,7 @@ PQRYRES TDBSRC::GetResult(PGLOBAL g)
|
|||||||
TDBOTB::TDBOTB(PODEF tdp) : TDBDRV(tdp)
|
TDBOTB::TDBOTB(PODEF tdp) : TDBDRV(tdp)
|
||||||
{
|
{
|
||||||
Dsn = tdp->GetConnect();
|
Dsn = tdp->GetConnect();
|
||||||
Schema = tdp->GetTabowner();
|
Schema = tdp->GetTabschema();
|
||||||
Tab = tdp->GetTabname();
|
Tab = tdp->GetTabname();
|
||||||
} // end of TDBOTB constructor
|
} // end of TDBOTB constructor
|
||||||
|
|
||||||
|
@@ -32,9 +32,10 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
|
|||||||
virtual const char *GetType(void) {return "ODBC";}
|
virtual const char *GetType(void) {return "ODBC";}
|
||||||
PSZ GetConnect(void) {return Connect;}
|
PSZ GetConnect(void) {return Connect;}
|
||||||
PSZ GetTabname(void) {return Tabname;}
|
PSZ GetTabname(void) {return Tabname;}
|
||||||
PSZ GetTabowner(void) {return Tabowner;}
|
PSZ GetTabschema(void) {return Tabschema;}
|
||||||
PSZ GetTabqual(void) {return Tabqual;}
|
PSZ GetTabcat(void) {return Tabcat;}
|
||||||
PSZ GetSrcdef(void) {return Srcdef;}
|
PSZ GetSrcdef(void) {return Srcdef;}
|
||||||
|
char GetSep(void) {return (Sep) ? *Sep : 0;}
|
||||||
int GetQuoted(void) {return Quoted;}
|
int GetQuoted(void) {return Quoted;}
|
||||||
int GetCatver(void) {return Catver;}
|
int GetCatver(void) {return Catver;}
|
||||||
int GetOptions(void) {return Options;}
|
int GetOptions(void) {return Options;}
|
||||||
@@ -47,11 +48,12 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
|
|||||||
// Members
|
// Members
|
||||||
PSZ Connect; /* ODBC connection string */
|
PSZ Connect; /* ODBC connection string */
|
||||||
PSZ Tabname; /* External table name */
|
PSZ Tabname; /* External table name */
|
||||||
PSZ Tabowner; /* External table owner */
|
PSZ Tabschema; /* External table schema */
|
||||||
PSZ Tabqual; /* External table qualifier */
|
PSZ Tabcat; /* External table catalog */
|
||||||
PSZ Srcdef; /* The source table SQL definition */
|
PSZ Srcdef; /* The source table SQL definition */
|
||||||
PSZ Qchar; /* Identifier quoting character */
|
PSZ Qchar; /* Identifier quoting character */
|
||||||
PSZ Qrystr; /* The original query */
|
PSZ Qrystr; /* The original query */
|
||||||
|
PSZ Sep; /* Decimal separator */
|
||||||
int Catver; /* ODBC version for catalog functions */
|
int Catver; /* ODBC version for catalog functions */
|
||||||
int Options; /* Open connection options */
|
int Options; /* Open connection options */
|
||||||
int Quoted; /* Identifier quoting level */
|
int Quoted; /* Identifier quoting level */
|
||||||
@@ -115,8 +117,8 @@ class TDBODBC : public TDBASE {
|
|||||||
ODBCCOL *Cnp; // Points to count(*) column
|
ODBCCOL *Cnp; // Points to count(*) column
|
||||||
char *Connect; // Points to connection string
|
char *Connect; // Points to connection string
|
||||||
char *TableName; // Points to ODBC table name
|
char *TableName; // Points to ODBC table name
|
||||||
char *Owner; // Points to ODBC table Owner
|
char *Schema; // Points to ODBC table Schema
|
||||||
char *Qualifier; // Points to ODBC table Qualifier
|
char *Catalog; // Points to ODBC table Catalog
|
||||||
char *Srcdef; // The source table SQL definition
|
char *Srcdef; // The source table SQL definition
|
||||||
char *Query; // Points to SQL statement
|
char *Query; // Points to SQL statement
|
||||||
char *Count; // Points to count(*) SQL statement
|
char *Count; // Points to count(*) SQL statement
|
||||||
@@ -125,6 +127,7 @@ class TDBODBC : public TDBASE {
|
|||||||
char *MulConn; // Used for multiple ODBC tables
|
char *MulConn; // Used for multiple ODBC tables
|
||||||
char *DBQ; // The address part of Connect string
|
char *DBQ; // The address part of Connect string
|
||||||
char *Qrystr; // The original query
|
char *Qrystr; // The original query
|
||||||
|
char Sep; // The decimal separator
|
||||||
int Options; // Connect options
|
int Options; // Connect options
|
||||||
int Quoted; // The identifier quoting level
|
int Quoted; // The identifier quoting level
|
||||||
int Fpos; // Position of last read record
|
int Fpos; // Position of last read record
|
||||||
|
@@ -416,10 +416,10 @@ bool INICOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
|
|||||||
if (GetDomain() || ((DTVAL *)value)->IsFormatted())
|
if (GetDomain() || ((DTVAL *)value)->IsFormatted())
|
||||||
goto newval; // This will make a new value;
|
goto newval; // This will make a new value;
|
||||||
|
|
||||||
} else if (Buf_Type == TYPE_FLOAT)
|
} else if (Buf_Type == TYPE_DOUBLE || Buf_Type == TYPE_DECIM)
|
||||||
// Float values must be written with the correct (column) precision
|
// Float values must be written with the correct (column) precision
|
||||||
// Note: maybe this should be forced by ShowValue instead of this ?
|
// Note: maybe this should be forced by ShowValue instead of this ?
|
||||||
value->SetPrec(GetPrecision());
|
value->SetPrec(GetScale());
|
||||||
|
|
||||||
Value = value; // Directly access the external value
|
Value = value; // Directly access the external value
|
||||||
} else {
|
} else {
|
||||||
|
@@ -122,16 +122,16 @@ TABLE_SHARE *GetTableShare(PGLOBAL g, THD *thd, const char *db,
|
|||||||
PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
|
PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
|
||||||
const char *name, bool& info)
|
const char *name, bool& info)
|
||||||
{
|
{
|
||||||
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
|
int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
|
||||||
TYPE_INT, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT,
|
TYPE_INT, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT,
|
||||||
TYPE_STRING, TYPE_STRING, TYPE_STRING};
|
TYPE_STRING, TYPE_STRING, TYPE_STRING};
|
||||||
static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC,
|
XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC,
|
||||||
FLD_LENGTH, FLD_SCALE, FLD_RADIX, FLD_NULL,
|
FLD_LENGTH, FLD_SCALE, FLD_RADIX, FLD_NULL,
|
||||||
FLD_REM, FLD_NO, FLD_CHARSET};
|
FLD_REM, FLD_NO, FLD_CHARSET};
|
||||||
static unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 32, 32};
|
unsigned int length[] = {0, 4, 16, 4, 4, 4, 4, 4, 0, 32, 32};
|
||||||
char *fld, *fmt, v;
|
char *fld, *fmt, v;
|
||||||
int i, n, ncol = sizeof(buftyp) / sizeof(int);
|
int i, n, ncol = sizeof(buftyp) / sizeof(int);
|
||||||
int len, type, prec;
|
int prec, len, type, scale;
|
||||||
bool mysql;
|
bool mysql;
|
||||||
TABLE_SHARE *s = NULL;
|
TABLE_SHARE *s = NULL;
|
||||||
Field* *field;
|
Field* *field;
|
||||||
@@ -208,27 +208,32 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
|
|||||||
// When creating tables we do need info about date columns
|
// When creating tables we do need info about date columns
|
||||||
if (mysql) {
|
if (mysql) {
|
||||||
fmt = MyDateFmt(fp->type());
|
fmt = MyDateFmt(fp->type());
|
||||||
len = strlen(fmt);
|
prec = len = strlen(fmt);
|
||||||
} else {
|
} else {
|
||||||
fmt = (char*)fp->option_struct->dateformat;
|
fmt = (char*)fp->option_struct->dateformat;
|
||||||
len = fp->field_length;
|
prec = len = fp->field_length;
|
||||||
} // endif mysql
|
} // endif mysql
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
fmt = NULL;
|
if (type == TYPE_DECIM)
|
||||||
|
prec = ((Field_new_decimal*)fp)->precision;
|
||||||
|
else
|
||||||
|
prec = (prec == NOT_FIXED_DEC) ? 0 : fp->field_length;
|
||||||
|
|
||||||
len = fp->char_length();
|
len = fp->char_length();
|
||||||
|
fmt = NULL;
|
||||||
} // endif type
|
} // endif type
|
||||||
|
|
||||||
crp = crp->Next; // Precision
|
crp = crp->Next; // Precision
|
||||||
crp->Kdata->SetValue(len, i);
|
crp->Kdata->SetValue(prec, i);
|
||||||
|
|
||||||
crp = crp->Next; // Length
|
crp = crp->Next; // Length
|
||||||
prec = (type == TYPE_FLOAT) ? fp->decimals() : 0;
|
|
||||||
len = (prec == 31) ? 0 : fp->field_length;
|
|
||||||
crp->Kdata->SetValue(len, i);
|
crp->Kdata->SetValue(len, i);
|
||||||
|
|
||||||
crp = crp->Next; // Scale
|
crp = crp->Next; // Scale
|
||||||
crp->Kdata->SetValue(prec, i);
|
scale = (type == TYPE_DOUBLE || type == TYPE_DECIM) ? fp->decimals()
|
||||||
|
: 0;
|
||||||
|
crp->Kdata->SetValue(scale, i);
|
||||||
|
|
||||||
crp = crp->Next; // Radix
|
crp = crp->Next; // Radix
|
||||||
crp->Kdata->SetValue(0, i);
|
crp->Kdata->SetValue(0, i);
|
||||||
|
@@ -269,7 +269,7 @@ PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *cls, bool info)
|
|||||||
case CIM_REAL64:
|
case CIM_REAL64:
|
||||||
case CIM_REAL32:
|
case CIM_REAL32:
|
||||||
prec = 2;
|
prec = 2;
|
||||||
typ = TYPE_FLOAT;
|
typ = TYPE_DOUBLE;
|
||||||
lng = 15;
|
lng = 15;
|
||||||
break;
|
break;
|
||||||
case CIM_SINT64:
|
case CIM_SINT64:
|
||||||
|
@@ -1168,10 +1168,10 @@ bool XMLCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
|
|||||||
if (GetDomain() || ((DTVAL *)value)->IsFormatted())
|
if (GetDomain() || ((DTVAL *)value)->IsFormatted())
|
||||||
goto newval; // This will make a new value;
|
goto newval; // This will make a new value;
|
||||||
|
|
||||||
} else if (Buf_Type == TYPE_FLOAT)
|
} else if (Buf_Type == TYPE_DOUBLE)
|
||||||
// Float values must be written with the correct (column) precision
|
// Float values must be written with the correct (column) precision
|
||||||
// Note: maybe this should be forced by ShowValue instead of this ?
|
// Note: maybe this should be forced by ShowValue instead of this ?
|
||||||
value->SetPrec(GetPrecision());
|
value->SetPrec(GetScale());
|
||||||
|
|
||||||
Value = value; // Directly access the external value
|
Value = value; // Directly access the external value
|
||||||
} else {
|
} else {
|
||||||
|
@@ -57,6 +57,7 @@ PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len,
|
|||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TYPE_STRING:
|
case TYPE_STRING:
|
||||||
|
case TYPE_DECIM:
|
||||||
if (len)
|
if (len)
|
||||||
blkp = new(g) CHRBLK(mp, nval, len, prec, blank);
|
blkp = new(g) CHRBLK(mp, nval, len, prec, blank);
|
||||||
else
|
else
|
||||||
@@ -87,7 +88,7 @@ PVBLK AllocValBlock(PGLOBAL g, void *mp, int type, int nval, int len,
|
|||||||
blkp = new(g) TYPBLK<longlong>(mp, nval, type);
|
blkp = new(g) TYPBLK<longlong>(mp, nval, type);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TYPE_FLOAT:
|
case TYPE_DOUBLE:
|
||||||
blkp = new(g) TYPBLK<double>(mp, nval, type, prec);
|
blkp = new(g) TYPBLK<double>(mp, nval, type, prec);
|
||||||
break;
|
break;
|
||||||
case TYPE_TINY:
|
case TYPE_TINY:
|
||||||
@@ -343,6 +344,21 @@ ulonglong TYPBLK<longlong>::MaxVal(void) {return INT_MAX64;}
|
|||||||
template <>
|
template <>
|
||||||
ulonglong TYPBLK<ulonglong>::MaxVal(void) {return ULONGLONG_MAX;}
|
ulonglong TYPBLK<ulonglong>::MaxVal(void) {return ULONGLONG_MAX;}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void TYPBLK<double>::SetValue(PSZ p, int n)
|
||||||
|
{
|
||||||
|
ChkIndx(n);
|
||||||
|
|
||||||
|
if (Check) {
|
||||||
|
PGLOBAL& g = Global;
|
||||||
|
strcpy(g->Message, MSG(BAD_SET_STRING));
|
||||||
|
longjmp(g->jumper[g->jump_level], Type);
|
||||||
|
} // endif Check
|
||||||
|
|
||||||
|
Typp[n] = atof(p);
|
||||||
|
SetNull(n, false);
|
||||||
|
} // end of SetValue
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Set one value in a block from an array of characters. */
|
/* Set one value in a block from an array of characters. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -1163,7 +1179,7 @@ DATBLK::DATBLK(void *mp, int nval) : TYPBLK<int>(mp, nval, TYPE_INT)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool DATBLK::SetFormat(PGLOBAL g, PSZ fmt, int len, int year)
|
bool DATBLK::SetFormat(PGLOBAL g, PSZ fmt, int len, int year)
|
||||||
{
|
{
|
||||||
if (!(Dvalp = AllocateValue(g, TYPE_DATE, len, year, fmt)))
|
if (!(Dvalp = AllocateValue(g, TYPE_DATE, len, year, false, fmt)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@@ -153,8 +153,9 @@ PSZ GetTypeName(int type)
|
|||||||
case TYPE_INT: name = "INTEGER"; break;
|
case TYPE_INT: name = "INTEGER"; break;
|
||||||
case TYPE_BIGINT: name = "BIGINT"; break;
|
case TYPE_BIGINT: name = "BIGINT"; break;
|
||||||
case TYPE_DATE: name = "DATE"; break;
|
case TYPE_DATE: name = "DATE"; break;
|
||||||
case TYPE_FLOAT: name = "FLOAT"; break;
|
case TYPE_DOUBLE: name = "DOUBLE"; break;
|
||||||
case TYPE_TINY: name = "TINY"; break;
|
case TYPE_TINY: name = "TINY"; break;
|
||||||
|
case TYPE_DECIM: name = "DECIMAL"; break;
|
||||||
default: name = "UNKNOWN"; break;
|
default: name = "UNKNOWN"; break;
|
||||||
} // endswitch type
|
} // endswitch type
|
||||||
|
|
||||||
@@ -167,12 +168,13 @@ PSZ GetTypeName(int type)
|
|||||||
int GetTypeSize(int type, int len)
|
int GetTypeSize(int type, int len)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case TYPE_DECIM:
|
||||||
case TYPE_STRING: len = len * sizeof(char); break;
|
case TYPE_STRING: len = len * sizeof(char); break;
|
||||||
case TYPE_SHORT: len = sizeof(short); break;
|
case TYPE_SHORT: len = sizeof(short); break;
|
||||||
case TYPE_INT: len = sizeof(int); break;
|
case TYPE_INT: len = sizeof(int); break;
|
||||||
case TYPE_BIGINT: len = sizeof(longlong); break;
|
case TYPE_BIGINT: len = sizeof(longlong); break;
|
||||||
case TYPE_DATE: len = sizeof(int); break;
|
case TYPE_DATE: len = sizeof(int); break;
|
||||||
case TYPE_FLOAT: len = sizeof(double); break;
|
case TYPE_DOUBLE: len = sizeof(double); break;
|
||||||
case TYPE_TINY: len = sizeof(char); break;
|
case TYPE_TINY: len = sizeof(char); break;
|
||||||
default: len = 0;
|
default: len = 0;
|
||||||
} // endswitch type
|
} // endswitch type
|
||||||
@@ -192,9 +194,10 @@ char *GetFormatType(int type)
|
|||||||
case TYPE_SHORT: c = "S"; break;
|
case TYPE_SHORT: c = "S"; break;
|
||||||
case TYPE_INT: c = "N"; break;
|
case TYPE_INT: c = "N"; break;
|
||||||
case TYPE_BIGINT: c = "L"; break;
|
case TYPE_BIGINT: c = "L"; break;
|
||||||
case TYPE_FLOAT: c = "F"; break;
|
case TYPE_DOUBLE: c = "F"; break;
|
||||||
case TYPE_DATE: c = "D"; break;
|
case TYPE_DATE: c = "D"; break;
|
||||||
case TYPE_TINY: c = "T"; break;
|
case TYPE_TINY: c = "T"; break;
|
||||||
|
case TYPE_DECIM: c = "M"; break;
|
||||||
} // endswitch type
|
} // endswitch type
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
@@ -212,15 +215,15 @@ int GetFormatType(char c)
|
|||||||
case 'S': type = TYPE_SHORT; break;
|
case 'S': type = TYPE_SHORT; break;
|
||||||
case 'N': type = TYPE_INT; break;
|
case 'N': type = TYPE_INT; break;
|
||||||
case 'L': type = TYPE_BIGINT; break;
|
case 'L': type = TYPE_BIGINT; break;
|
||||||
case 'F': type = TYPE_FLOAT; break;
|
case 'F': type = TYPE_DOUBLE; break;
|
||||||
case 'D': type = TYPE_DATE; break;
|
case 'D': type = TYPE_DATE; break;
|
||||||
case 'T': type = TYPE_TINY; break;
|
case 'T': type = TYPE_TINY; break;
|
||||||
|
case 'M': type = TYPE_DECIM; break;
|
||||||
} // endswitch type
|
} // endswitch type
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
} // end of GetFormatType
|
} // end of GetFormatType
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* IsTypeChar: returns true for character type(s). */
|
/* IsTypeChar: returns true for character type(s). */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -228,6 +231,7 @@ bool IsTypeChar(int type)
|
|||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TYPE_STRING:
|
case TYPE_STRING:
|
||||||
|
case TYPE_DECIM:
|
||||||
return true;
|
return true;
|
||||||
} // endswitch type
|
} // endswitch type
|
||||||
|
|
||||||
@@ -243,10 +247,11 @@ bool IsTypeNum(int type)
|
|||||||
case TYPE_INT:
|
case TYPE_INT:
|
||||||
case TYPE_BIGINT:
|
case TYPE_BIGINT:
|
||||||
case TYPE_DATE:
|
case TYPE_DATE:
|
||||||
case TYPE_FLOAT:
|
case TYPE_DOUBLE:
|
||||||
case TYPE_SHORT:
|
case TYPE_SHORT:
|
||||||
case TYPE_NUM:
|
case TYPE_NUM:
|
||||||
case TYPE_TINY:
|
case TYPE_TINY:
|
||||||
|
case TYPE_DECIM:
|
||||||
return true;
|
return true;
|
||||||
} // endswitch type
|
} // endswitch type
|
||||||
|
|
||||||
@@ -261,10 +266,11 @@ const char *GetFmt(int type, bool un)
|
|||||||
const char *fmt;
|
const char *fmt;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case TYPE_DECIM:
|
||||||
case TYPE_STRING: fmt = "%s"; break;
|
case TYPE_STRING: fmt = "%s"; break;
|
||||||
case TYPE_SHORT: fmt = (un) ? "%hu" : "%hd"; break;
|
case TYPE_SHORT: fmt = (un) ? "%hu" : "%hd"; break;
|
||||||
case TYPE_BIGINT: fmt = (un) ? "%llu" : "%lld"; break;
|
case TYPE_BIGINT: fmt = (un) ? "%llu" : "%lld"; break;
|
||||||
case TYPE_FLOAT: fmt = "%.*lf"; break;
|
case TYPE_DOUBLE: fmt = "%.*lf"; break;
|
||||||
default: fmt = (un) ? "%u" : "%d"; break;
|
default: fmt = (un) ? "%u" : "%d"; break;
|
||||||
} // endswitch Type
|
} // endswitch Type
|
||||||
|
|
||||||
@@ -293,7 +299,7 @@ int ConvertType(int target, int type, CONV kind, bool match)
|
|||||||
if (match && (!IsTypeNum(target) || !IsTypeNum(type)))
|
if (match && (!IsTypeNum(target) || !IsTypeNum(type)))
|
||||||
return TYPE_ERROR;
|
return TYPE_ERROR;
|
||||||
|
|
||||||
return (target == TYPE_FLOAT || type == TYPE_FLOAT) ? TYPE_FLOAT
|
return (target == TYPE_DOUBLE || type == TYPE_DOUBLE) ? TYPE_DOUBLE
|
||||||
: (target == TYPE_DATE || type == TYPE_DATE) ? TYPE_DATE
|
: (target == TYPE_DATE || type == TYPE_DATE) ? TYPE_DATE
|
||||||
: (target == TYPE_BIGINT || type == TYPE_BIGINT) ? TYPE_BIGINT
|
: (target == TYPE_BIGINT || type == TYPE_BIGINT) ? TYPE_BIGINT
|
||||||
: (target == TYPE_INT || type == TYPE_INT) ? TYPE_INT
|
: (target == TYPE_INT || type == TYPE_INT) ? TYPE_INT
|
||||||
@@ -307,7 +313,7 @@ int ConvertType(int target, int type, CONV kind, bool match)
|
|||||||
(IsTypeNum(target) && !IsTypeNum(type))))
|
(IsTypeNum(target) && !IsTypeNum(type))))
|
||||||
return TYPE_ERROR;
|
return TYPE_ERROR;
|
||||||
|
|
||||||
return (target == TYPE_FLOAT || type == TYPE_FLOAT) ? TYPE_FLOAT
|
return (target == TYPE_DOUBLE || type == TYPE_DOUBLE) ? TYPE_DOUBLE
|
||||||
: (target == TYPE_DATE || type == TYPE_DATE) ? TYPE_DATE
|
: (target == TYPE_DATE || type == TYPE_DATE) ? TYPE_DATE
|
||||||
: (target == TYPE_BIGINT || type == TYPE_BIGINT) ? TYPE_BIGINT
|
: (target == TYPE_BIGINT || type == TYPE_BIGINT) ? TYPE_BIGINT
|
||||||
: (target == TYPE_INT || type == TYPE_INT) ? TYPE_INT
|
: (target == TYPE_INT || type == TYPE_INT) ? TYPE_INT
|
||||||
@@ -343,8 +349,8 @@ PVAL AllocateValue(PGLOBAL g, void *value, short type)
|
|||||||
case TYPE_BIGINT:
|
case TYPE_BIGINT:
|
||||||
valp = new(g) TYPVAL<longlong>(*(longlong*)value, TYPE_BIGINT);
|
valp = new(g) TYPVAL<longlong>(*(longlong*)value, TYPE_BIGINT);
|
||||||
break;
|
break;
|
||||||
case TYPE_FLOAT:
|
case TYPE_DOUBLE:
|
||||||
valp = new(g) TYPVAL<double>(*(double *)value, TYPE_FLOAT, 2);
|
valp = new(g) TYPVAL<double>(*(double *)value, TYPE_DOUBLE, 2);
|
||||||
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);
|
||||||
@@ -361,7 +367,8 @@ PVAL AllocateValue(PGLOBAL g, void *value, short type)
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Allocate a variable Value according to type, length and precision. */
|
/* Allocate a variable Value according to type, length and precision. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
PVAL AllocateValue(PGLOBAL g, int type, int len, int prec, PSZ fmt)
|
PVAL AllocateValue(PGLOBAL g, int type, int len, int prec,
|
||||||
|
bool uns, PSZ fmt)
|
||||||
{
|
{
|
||||||
PVAL valp;
|
PVAL valp;
|
||||||
|
|
||||||
@@ -373,35 +380,38 @@ PVAL AllocateValue(PGLOBAL g, int type, int len, int prec, PSZ fmt)
|
|||||||
valp = new(g) DTVAL(g, len, prec, fmt);
|
valp = new(g) DTVAL(g, len, prec, fmt);
|
||||||
break;
|
break;
|
||||||
case TYPE_INT:
|
case TYPE_INT:
|
||||||
if (prec)
|
if (uns)
|
||||||
valp = new(g) TYPVAL<uint>((uint)0, TYPE_INT, 0, true);
|
valp = new(g) TYPVAL<uint>((uint)0, TYPE_INT, 0, true);
|
||||||
else
|
else
|
||||||
valp = new(g) TYPVAL<int>((int)0, TYPE_INT);
|
valp = new(g) TYPVAL<int>((int)0, TYPE_INT);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TYPE_BIGINT:
|
case TYPE_BIGINT:
|
||||||
if (prec)
|
if (uns)
|
||||||
valp = new(g) TYPVAL<ulonglong>((ulonglong)0, TYPE_BIGINT, 0, true);
|
valp = new(g) TYPVAL<ulonglong>((ulonglong)0, TYPE_BIGINT, 0, true);
|
||||||
else
|
else
|
||||||
valp = new(g) TYPVAL<longlong>((longlong)0, TYPE_BIGINT);
|
valp = new(g) TYPVAL<longlong>((longlong)0, TYPE_BIGINT);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TYPE_SHORT:
|
case TYPE_SHORT:
|
||||||
if (prec)
|
if (uns)
|
||||||
valp = new(g) TYPVAL<ushort>((ushort)0, TYPE_SHORT, 0, true);
|
valp = new(g) TYPVAL<ushort>((ushort)0, TYPE_SHORT, 0, true);
|
||||||
else
|
else
|
||||||
valp = new(g) TYPVAL<short>((short)0, TYPE_SHORT);
|
valp = new(g) TYPVAL<short>((short)0, TYPE_SHORT);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TYPE_FLOAT:
|
case TYPE_DOUBLE:
|
||||||
valp = new(g) TYPVAL<double>(0.0, TYPE_FLOAT, prec);
|
valp = new(g) TYPVAL<double>(0.0, TYPE_DOUBLE, prec);
|
||||||
break;
|
break;
|
||||||
case TYPE_TINY:
|
case TYPE_TINY:
|
||||||
if (prec)
|
if (uns)
|
||||||
valp = new(g) TYPVAL<uchar>((uchar)0, TYPE_TINY, 0, true);
|
valp = new(g) TYPVAL<uchar>((uchar)0, TYPE_TINY, 0, true);
|
||||||
else
|
else
|
||||||
valp = new(g) TYPVAL<char>((char)0, TYPE_TINY);
|
valp = new(g) TYPVAL<char>((char)0, TYPE_TINY);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case TYPE_DECIM:
|
||||||
|
valp = new(g) DECVAL(g, (PSZ)NULL, len, prec, uns);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sprintf(g->Message, MSG(BAD_VALUE_TYPE), type);
|
sprintf(g->Message, MSG(BAD_VALUE_TYPE), type);
|
||||||
@@ -412,6 +422,7 @@ PVAL AllocateValue(PGLOBAL g, int type, int len, int prec, PSZ fmt)
|
|||||||
return valp;
|
return valp;
|
||||||
} // end of AllocateValue
|
} // end of AllocateValue
|
||||||
|
|
||||||
|
#if 0
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Allocate a constant Value converted to newtype. */
|
/* Allocate a constant Value converted to newtype. */
|
||||||
/* Can also be used to copy a Value eventually converted. */
|
/* Can also be used to copy a Value eventually converted. */
|
||||||
@@ -459,8 +470,8 @@ PVAL AllocateValue(PGLOBAL g, PVAL valp, int newtype, int uns)
|
|||||||
case TYPE_DATE:
|
case TYPE_DATE:
|
||||||
valp = new(g) DTVAL(g, valp->GetIntValue());
|
valp = new(g) DTVAL(g, valp->GetIntValue());
|
||||||
break;
|
break;
|
||||||
case TYPE_FLOAT:
|
case TYPE_DOUBLE:
|
||||||
valp = new(g) TYPVAL<double>(valp->GetFloatValue(), TYPE_FLOAT,
|
valp = new(g) TYPVAL<double>(valp->GetFloatValue(), TYPE_DOUBLE,
|
||||||
valp->GetValPrec());
|
valp->GetValPrec());
|
||||||
break;
|
break;
|
||||||
case TYPE_TINY:
|
case TYPE_TINY:
|
||||||
@@ -479,7 +490,7 @@ PVAL AllocateValue(PGLOBAL g, PVAL valp, int newtype, int uns)
|
|||||||
valp->SetGlobal(g);
|
valp->SetGlobal(g);
|
||||||
return valp;
|
return valp;
|
||||||
} // end of AllocateValue
|
} // end of AllocateValue
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
/* -------------------------- Class VALUE ---------------------------- */
|
/* -------------------------- Class VALUE ---------------------------- */
|
||||||
|
|
||||||
@@ -505,10 +516,11 @@ const char *VALUE::GetXfmt(void)
|
|||||||
const char *fmt;
|
const char *fmt;
|
||||||
|
|
||||||
switch (Type) {
|
switch (Type) {
|
||||||
|
case TYPE_DECIM:
|
||||||
case TYPE_STRING: fmt = "%*s"; break;
|
case TYPE_STRING: fmt = "%*s"; break;
|
||||||
case TYPE_SHORT: fmt = (Unsigned) ? "%*hu" : "%*hd"; break;
|
case TYPE_SHORT: fmt = (Unsigned) ? "%*hu" : "%*hd"; break;
|
||||||
case TYPE_BIGINT: fmt = (Unsigned) ? "%*llu" : "%*lld"; break;
|
case TYPE_BIGINT: fmt = (Unsigned) ? "%*llu" : "%*lld"; break;
|
||||||
case TYPE_FLOAT: fmt = "%*.*lf"; break;
|
case TYPE_DOUBLE: fmt = "%*.*lf"; break;
|
||||||
default: fmt = (Unsigned) ? "%*u" : "%*d"; break;
|
default: fmt = (Unsigned) ? "%*u" : "%*d"; break;
|
||||||
} // endswitch Type
|
} // endswitch Type
|
||||||
|
|
||||||
@@ -1355,6 +1367,234 @@ bool TYPVAL<PSZ>::SetConstFormat(PGLOBAL g, FORMAT& fmt)
|
|||||||
return false;
|
return false;
|
||||||
} // end of SetConstFormat
|
} // end of SetConstFormat
|
||||||
|
|
||||||
|
/* -------------------------- Class DECIMAL -------------------------- */
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* DECIMAL public constructor from a constant string. */
|
||||||
|
/***********************************************************************/
|
||||||
|
DECVAL::DECVAL(PSZ s) : TYPVAL<PSZ>(s)
|
||||||
|
{
|
||||||
|
if (s) {
|
||||||
|
char *p = strchr(Strp, '.');
|
||||||
|
|
||||||
|
Prec = (p) ? Len - (p - Strp) : 0;
|
||||||
|
} // endif s
|
||||||
|
|
||||||
|
Type = TYPE_DECIM;
|
||||||
|
} // end of DECVAL constructor
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* DECIMAL public constructor from char. */
|
||||||
|
/***********************************************************************/
|
||||||
|
DECVAL::DECVAL(PGLOBAL g, PSZ s, int n, int prec, bool uns)
|
||||||
|
: TYPVAL<PSZ>(g, s, n + (prec ? 1 : 0) + (uns ? 0 : 1), 0)
|
||||||
|
{
|
||||||
|
Prec = prec;
|
||||||
|
Unsigned = uns;
|
||||||
|
Type = TYPE_DECIM;
|
||||||
|
} // end of DECVAL constructor
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* DECIMAL: Check whether the numerica value is equal to 0. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool DECVAL::IsZero(void)
|
||||||
|
{
|
||||||
|
for (int i = 0; Strp[i]; i++)
|
||||||
|
if (!strchr("0 +-.", Strp[i]))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} // end of IsZero
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* DECIMAL: Reset value to zero. */
|
||||||
|
/***********************************************************************/
|
||||||
|
void DECVAL::Reset(void)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
Strp[i++] = '0';
|
||||||
|
|
||||||
|
if (Prec) {
|
||||||
|
Strp[i++] = '.';
|
||||||
|
|
||||||
|
do {
|
||||||
|
Strp[i++] = '0';
|
||||||
|
} while (i < Prec + 2);
|
||||||
|
|
||||||
|
} // endif Prec
|
||||||
|
|
||||||
|
Strp[i] = 0;
|
||||||
|
} // end of Reset
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* DECIMAL ShowValue: get string representation right justified. */
|
||||||
|
/***********************************************************************/
|
||||||
|
char *DECVAL::ShowValue(char *buf, int len)
|
||||||
|
{
|
||||||
|
sprintf(buf, Xfmt, len, Strp);
|
||||||
|
return buf;
|
||||||
|
} // end of ShowValue
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* GetBinValue: fill a buffer with the internal binary value. */
|
||||||
|
/* This function checks whether the buffer length is enough and */
|
||||||
|
/* returns true if not. Actual filling occurs only if go is true. */
|
||||||
|
/* Currently used by WriteColumn of binary files. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool DECVAL::GetBinValue(void *buf, int buflen, bool go)
|
||||||
|
{
|
||||||
|
int len = (Null) ? 0 : strlen(Strp);
|
||||||
|
|
||||||
|
if (len > buflen)
|
||||||
|
return true;
|
||||||
|
else if (go) {
|
||||||
|
memset(buf, ' ', buflen - len);
|
||||||
|
memcpy((char*)buf + buflen - len, Strp, len);
|
||||||
|
} // endif go
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} // end of GetBinValue
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/***********************************************************************/
|
||||||
|
/* DECIMAL SetValue: copy the value of another Value object. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool DECVAL::SetValue_pval(PVAL valp, bool chktype)
|
||||||
|
{
|
||||||
|
if (chktype && (valp->GetType() != Type || valp->GetSize() > Len))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
char buf[32];
|
||||||
|
|
||||||
|
if (!(Null = valp->IsNull() && Nullable))
|
||||||
|
strncpy(Strp, valp->GetCharString(buf), Len);
|
||||||
|
else
|
||||||
|
Reset();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} // end of SetValue_pval
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* DECIMAL SetValue: fill string with chars extracted from a line. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool DECVAL::SetValue_char(char *p, int n)
|
||||||
|
{
|
||||||
|
bool rc;
|
||||||
|
|
||||||
|
if (p) {
|
||||||
|
rc = n > Len;
|
||||||
|
|
||||||
|
if ((n = min(n, Len))) {
|
||||||
|
strncpy(Strp, p, n);
|
||||||
|
|
||||||
|
// for (p = Strp + n - 1; p >= Strp && (*p == ' ' || *p == '\0'); p--) ;
|
||||||
|
for (p = Strp + n - 1; p >= Strp; p--)
|
||||||
|
if (*p && *p != ' ')
|
||||||
|
break;
|
||||||
|
|
||||||
|
*(++p) = '\0';
|
||||||
|
|
||||||
|
if (trace > 1)
|
||||||
|
htrc(" Setting string to: '%s'\n", Strp);
|
||||||
|
|
||||||
|
} else
|
||||||
|
Reset();
|
||||||
|
|
||||||
|
Null = false;
|
||||||
|
} else {
|
||||||
|
rc = false;
|
||||||
|
Reset();
|
||||||
|
Null = Nullable;
|
||||||
|
} // endif p
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
} // end of SetValue_char
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* DECIMAL SetValue: fill string with another string. */
|
||||||
|
/***********************************************************************/
|
||||||
|
void DECVAL::SetValue_psz(PSZ s)
|
||||||
|
{
|
||||||
|
if (s) {
|
||||||
|
strncpy(Strp, s, Len);
|
||||||
|
Null = false;
|
||||||
|
} else {
|
||||||
|
Reset();
|
||||||
|
Null = Nullable;
|
||||||
|
} // endif s
|
||||||
|
|
||||||
|
} // end of SetValue_psz
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* DECIMAL SetValue: fill string with a string extracted from a block.*/
|
||||||
|
/***********************************************************************/
|
||||||
|
void DECVAL::SetValue_pvblk(PVBLK blk, int n)
|
||||||
|
{
|
||||||
|
// STRBLK's can return a NULL pointer
|
||||||
|
SetValue_psz(blk->GetCharValue(n));
|
||||||
|
} // end of SetValue_pvblk
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* DECIMAL SetBinValue: fill string with chars extracted from a line. */
|
||||||
|
/***********************************************************************/
|
||||||
|
void DECVAL::SetBinValue(void *p)
|
||||||
|
{
|
||||||
|
SetValue_char((char *)p, Len);
|
||||||
|
} // end of SetBinValue
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* DECIMAL GetCharString: get string representation of a char value. */
|
||||||
|
/***********************************************************************/
|
||||||
|
char *DECVAL::GetCharString(char *p)
|
||||||
|
{
|
||||||
|
return Strp;
|
||||||
|
} // end of GetCharString
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* DECIMAL compare value with another Value. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool DECVAL::IsEqual(PVAL vp, bool chktype)
|
||||||
|
{
|
||||||
|
if (this == vp)
|
||||||
|
return true;
|
||||||
|
else if (chktype && Type != vp->GetType())
|
||||||
|
return false;
|
||||||
|
else if (Null || vp->IsNull())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
char buf[32];
|
||||||
|
|
||||||
|
return !strcmp(Strp, vp->GetCharString(buf));
|
||||||
|
} // end of IsEqual
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/***********************************************************************/
|
||||||
|
/* FormatValue: This function set vp (a STRING value) to the string */
|
||||||
|
/* constructed from its own value formated using the fmt format. */
|
||||||
|
/* This function assumes that the format matches the value type. */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool DECVAL::FormatValue(PVAL vp, char *fmt)
|
||||||
|
{
|
||||||
|
char *buf = (char*)vp->GetTo_Val(); // Should be big enough
|
||||||
|
int n = sprintf(buf, fmt, Strp);
|
||||||
|
|
||||||
|
return (n > vp->GetValLen());
|
||||||
|
} // end of FormatValue
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* DECIMAL SetFormat function (used to set SELECT output format). */
|
||||||
|
/***********************************************************************/
|
||||||
|
bool DECVAL::SetConstFormat(PGLOBAL g, FORMAT& fmt)
|
||||||
|
{
|
||||||
|
fmt.Type[0] = 'C';
|
||||||
|
fmt.Length = Len;
|
||||||
|
fmt.Prec = 0;
|
||||||
|
return false;
|
||||||
|
} // end of SetConstFormat
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
/* -------------------------- Class DTVAL ---------------------------- */
|
/* -------------------------- Class DTVAL ---------------------------- */
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -47,9 +47,9 @@ DllExport int GetFormatType(char);
|
|||||||
DllExport bool IsTypeChar(int type);
|
DllExport bool IsTypeChar(int type);
|
||||||
DllExport bool IsTypeNum(int type);
|
DllExport bool IsTypeNum(int type);
|
||||||
//lExport int ConvertType(int, int, CONV, bool match = false);
|
//lExport int ConvertType(int, int, CONV, bool match = false);
|
||||||
DllExport PVAL AllocateValue(PGLOBAL, PVAL, int = TYPE_VOID, int = 0);
|
//lExport 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,
|
||||||
PSZ fmt = NULL);
|
bool uns = false, PSZ fmt = NULL);
|
||||||
DllExport ulonglong CharToNumber(char *, int, ulonglong, bool,
|
DllExport ulonglong CharToNumber(char *, int, ulonglong, bool,
|
||||||
bool *minus = NULL, bool *rc = NULL);
|
bool *minus = NULL, bool *rc = NULL);
|
||||||
|
|
||||||
@@ -255,6 +255,37 @@ class DllExport TYPVAL<PSZ>: public VALUE {
|
|||||||
int Len;
|
int Len;
|
||||||
}; // end of class TYPVAL<PSZ>
|
}; // end of class TYPVAL<PSZ>
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
/* Specific DECIMAL class. */
|
||||||
|
/***********************************************************************/
|
||||||
|
class DllExport DECVAL: public TYPVAL<PSZ> {
|
||||||
|
public:
|
||||||
|
// Constructors
|
||||||
|
DECVAL(PSZ s);
|
||||||
|
DECVAL(PGLOBAL g, PSZ s, int n, int prec, bool uns);
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
virtual bool IsTypeNum(void) {return true;}
|
||||||
|
virtual bool IsZero(void);
|
||||||
|
virtual void Reset(void);
|
||||||
|
virtual int GetValPrec() {return Prec;}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
//virtual bool SetValue_pval(PVAL valp, bool chktype);
|
||||||
|
//virtual bool SetValue_char(char *p, int n);
|
||||||
|
//virtual void SetValue_psz(PSZ s);
|
||||||
|
//virtual void SetValue_pvblk(PVBLK blk, int n);
|
||||||
|
//virtual void SetBinValue(void *p);
|
||||||
|
virtual bool GetBinValue(void *buf, int buflen, bool go);
|
||||||
|
virtual char *ShowValue(char *buf, int);
|
||||||
|
//virtual char *GetCharString(char *p);
|
||||||
|
virtual bool IsEqual(PVAL vp, bool chktype);
|
||||||
|
//virtual bool FormatValue(PVAL vp, char *fmt);
|
||||||
|
//virtual bool SetConstFormat(PGLOBAL, FORMAT&);
|
||||||
|
|
||||||
|
// Members
|
||||||
|
}; // end of class DECVAL
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Class DTVAL: represents a time stamp value. */
|
/* Class DTVAL: represents a time stamp value. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@@ -2753,7 +2753,7 @@ KXYCOL::KXYCOL(PKXBASE kp) : To_Keys(Keys.Memp),
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
bool KXYCOL::Init(PGLOBAL g, PCOL colp, int n, bool sm, int kln)
|
bool KXYCOL::Init(PGLOBAL g, PCOL colp, int n, bool sm, int kln)
|
||||||
{
|
{
|
||||||
int len = colp->GetLength(), prec = colp->GetPrecision();
|
int len = colp->GetLength(), prec = colp->GetScale();
|
||||||
|
|
||||||
// Currently no indexing on NULL columns
|
// Currently no indexing on NULL columns
|
||||||
if (colp->IsNullable()) {
|
if (colp->IsNullable()) {
|
||||||
@@ -2774,7 +2774,8 @@ bool KXYCOL::Init(PGLOBAL g, PCOL colp, int n, bool sm, int kln)
|
|||||||
// Allocate the Value object used when moving items
|
// Allocate the Value object used when moving items
|
||||||
Type = colp->GetResultType();
|
Type = colp->GetResultType();
|
||||||
|
|
||||||
if (!(Valp = AllocateValue(g, Type, len, colp->GetPrecision())))
|
if (!(Valp = AllocateValue(g, Type, len, colp->GetScale(),
|
||||||
|
colp->IsUnsigned())))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
Klen = Valp->GetClen();
|
Klen = Valp->GetClen();
|
||||||
@@ -2825,7 +2826,7 @@ BYTE* KXYCOL::MapInit(PGLOBAL g, PCOL colp, int *n, BYTE *m)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Allocate the Value object used when moving items
|
// Allocate the Value object used when moving items
|
||||||
Valp = AllocateValue(g, Type, len, prec, NULL);
|
Valp = AllocateValue(g, Type, len, prec, false, NULL);
|
||||||
Klen = Valp->GetClen();
|
Klen = Valp->GetClen();
|
||||||
|
|
||||||
if (n[2]) {
|
if (n[2]) {
|
||||||
|
@@ -109,6 +109,7 @@ int CONSTANT::GetLengthEx(void)
|
|||||||
return Value->GetValLen();
|
return Value->GetValLen();
|
||||||
} // end of GetLengthEx
|
} // end of GetLengthEx
|
||||||
|
|
||||||
|
#if 0
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Convert a constant to the given type. */
|
/* Convert a constant to the given type. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -119,6 +120,7 @@ void CONSTANT::Convert(PGLOBAL g, int newtype)
|
|||||||
longjmp(g->jumper[g->jump_level], TYPE_CONST);
|
longjmp(g->jumper[g->jump_level], TYPE_CONST);
|
||||||
|
|
||||||
} // end of Convert
|
} // end of Convert
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Compare: returns true if this object is equivalent to xp. */
|
/* Compare: returns true if this object is equivalent to xp. */
|
||||||
@@ -151,7 +153,7 @@ bool CONSTANT::Rephrase(PGLOBAL g, PSZ work)
|
|||||||
case TYPE_DATE:
|
case TYPE_DATE:
|
||||||
sprintf(work + strlen(work), "%d", Value->GetIntValue());
|
sprintf(work + strlen(work), "%d", Value->GetIntValue());
|
||||||
break;
|
break;
|
||||||
case TYPE_FLOAT:
|
case TYPE_DOUBLE:
|
||||||
sprintf(work + strlen(work), "%lf", Value->GetFloatValue());
|
sprintf(work + strlen(work), "%lf", Value->GetFloatValue());
|
||||||
break;
|
break;
|
||||||
case TYPE_BIGINT:
|
case TYPE_BIGINT:
|
||||||
|
@@ -52,7 +52,7 @@ class DllExport XOBJECT : public BLOCK {
|
|||||||
virtual short GetShortValue(void);
|
virtual short GetShortValue(void);
|
||||||
virtual int GetIntValue(void);
|
virtual int GetIntValue(void);
|
||||||
virtual double GetFloatValue(void);
|
virtual double GetFloatValue(void);
|
||||||
virtual int GetPrecision(void) = 0;
|
virtual int GetScale(void) = 0;
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
virtual void Reset(void) {}
|
virtual void Reset(void) {}
|
||||||
@@ -92,7 +92,7 @@ class DllExport XVOID : public XOBJECT {
|
|||||||
virtual PSZ GetCharValue(void) {return NULL;}
|
virtual PSZ GetCharValue(void) {return NULL;}
|
||||||
virtual int GetIntValue(void) {return 0;}
|
virtual int GetIntValue(void) {return 0;}
|
||||||
virtual double GetFloatValue(void) {return 0.0;}
|
virtual double GetFloatValue(void) {return 0.0;}
|
||||||
virtual int GetPrecision() {return 0;}
|
virtual int GetScale() {return 0;}
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
virtual bool Compare(PXOB xp) {return xp->GetType() == TYPE_VOID;}
|
virtual bool Compare(PXOB xp) {return xp->GetType() == TYPE_VOID;}
|
||||||
@@ -115,7 +115,7 @@ class DllExport CONSTANT : public XOBJECT {
|
|||||||
virtual int GetType(void) {return TYPE_CONST;}
|
virtual int GetType(void) {return TYPE_CONST;}
|
||||||
virtual int GetResultType(void) {return Value->Type;}
|
virtual int GetResultType(void) {return Value->Type;}
|
||||||
virtual int GetLength(void) {return Value->GetValLen();}
|
virtual int GetLength(void) {return Value->GetValLen();}
|
||||||
virtual int GetPrecision() {return Value->GetValPrec();}
|
virtual int GetScale() {return Value->GetValPrec();}
|
||||||
virtual int GetLengthEx(void);
|
virtual int GetLengthEx(void);
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
@@ -123,7 +123,7 @@ class DllExport CONSTANT : public XOBJECT {
|
|||||||
virtual bool SetFormat(PGLOBAL g, FORMAT& fmt)
|
virtual bool SetFormat(PGLOBAL g, FORMAT& fmt)
|
||||||
{return Value->SetConstFormat(g, fmt);}
|
{return Value->SetConstFormat(g, fmt);}
|
||||||
virtual int CheckSpcCol(PTDB, int) {return 1;}
|
virtual int CheckSpcCol(PTDB, int) {return 1;}
|
||||||
void Convert(PGLOBAL g, int newtype);
|
// void Convert(PGLOBAL g, int newtype);
|
||||||
// bool Rephrase(PGLOBAL g, PSZ work);
|
// bool Rephrase(PGLOBAL g, PSZ work);
|
||||||
void SetValue(PVAL vp) {Value = vp;}
|
void SetValue(PVAL vp) {Value = vp;}
|
||||||
virtual bool VerifyColumn(PTBX txp) {return true;}
|
virtual bool VerifyColumn(PTBX txp) {return true;}
|
||||||
|
Reference in New Issue
Block a user