Skip to content

Commit

Permalink
Implement big(date)time types
Browse files Browse the repository at this point in the history
These new types was added in Sybase 15.7.

Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
  • Loading branch information
freddy77 committed Sep 21, 2015
2 parents 5a84363 + e59c48a commit adb893f
Show file tree
Hide file tree
Showing 25 changed files with 400 additions and 11 deletions.
2 changes: 2 additions & 0 deletions include/cspublic.h
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,8 @@ enum
#define CS_UINT_TYPE TDS_STATIC_CAST(CS_INT, 32)
#define CS_UBIGINT_TYPE TDS_STATIC_CAST(CS_INT, 33)
#define CS_XML_TYPE TDS_STATIC_CAST(CS_INT, 34)
#define CS_BIGDATETIME_TYPE TDS_STATIC_CAST(CS_INT, 35)
#define CS_BIGTIME_TYPE TDS_STATIC_CAST(CS_INT, 36)
#define CS_UNIQUE_TYPE TDS_STATIC_CAST(CS_INT, 40)

#define CS_USER_TYPE TDS_STATIC_CAST(CS_INT, 100)
Expand Down
2 changes: 2 additions & 0 deletions include/freetds/convert.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ typedef union conv_result
TDS_DATETIMEALL dta;
TDS_TIME time;
TDS_DATE date;
TDS_BIGTIME bigtime;
TDS_BIGDATETIME bigdatetime;
TDS_NUMERIC n;
TDS_UNIQUE u;

Expand Down
9 changes: 9 additions & 0 deletions include/freetds/data.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ tds_func_put_info tds_clrudt_put_info;
#define tds_clrudt_put tds_generic_put
tds_func_check tds_clrudt_check;

tds_func_get_info tds_sybbigtime_get_info;
tds_func_row_len tds_sybbigtime_row_len;
tds_func_get_data tds_sybbigtime_get;
tds_func_put_info_len tds_sybbigtime_put_info_len;
tds_func_put_info tds_sybbigtime_put_info;
tds_func_put_data tds_sybbigtime_put;
tds_func_check tds_sybbigtime_check;

/**
* If TDS_DONT_DEFINE_DEFAULT_FUNCTIONS is no defined
* define default implementations for these tables
Expand All @@ -90,6 +98,7 @@ TDS_DEFINE_DEFAULT_FUNCS(numeric);
TDS_DEFINE_DEFAULT_FUNCS(variant);
TDS_DEFINE_DEFAULT_FUNCS(msdatetime);
TDS_DEFINE_DEFAULT_FUNCS(clrudt);
TDS_DEFINE_DEFAULT_FUNCS(sybbigtime);
#endif

#include <freetds/popvis.h>
Expand Down
4 changes: 3 additions & 1 deletion include/freetds/enum_cap.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ typedef enum tds_request_capability
, TDS_REQ_CURINFO3 = 86
, TDS_REQ_DBRPC2 = 87
, TDS_REQ_MIGRATE = 89
, TDS_REQ_CAP_MAX = 89 /* repeats last enum */
, TDS_REQ_DATA_BIGDATETIME = 93
, TDS_REQ_DATA_BIGTIME = 94
, TDS_REQ_CAP_MAX = 94 /* repeats last enum */
} TDS_REQUEST_CAPABILITY;

typedef enum tds_response_capability
Expand Down
5 changes: 5 additions & 0 deletions include/freetds/proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ typedef struct tdsunique
typedef TDS_INT TDS_DATE;
typedef TDS_INT TDS_TIME;

typedef TDS_UINT8 TDS_BIGTIME;
typedef TDS_UINT8 TDS_BIGDATETIME;

#define TDS5_PARAMFMT2_TOKEN 32 /* 0x20 */
#define TDS_LANGUAGE_TOKEN 33 /* 0x21 TDS 5.0 only */
#define TDS_ORDERBY2_TOKEN 34 /* 0x22 */
Expand Down Expand Up @@ -222,6 +225,8 @@ typedef enum
SYBUINTN = 68, /* 0x44 */
SYBUNITEXT = 174, /* 0xAE */
SYBXML = 163, /* 0xA3 */
SYB5BIGDATETIME = 187, /* 0xBB */
SYB5BIGTIME = 188, /* 0xBC */

} TDS_SERVER_TYPE;

Expand Down
6 changes: 6 additions & 0 deletions include/sybdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,10 @@ enum
#define SYBDATE SYBDATE
SYBTIME = 51, /* 0x33 */
#define SYBTIME SYBTIME
SYBBIGDATETIME = 187, /* 0xBB */
#define SYBBIGDATETIME SYBBIGDATETIME
SYBBIGTIME = 188, /* 0xBC */
#define SYBBIGTIME SYBBIGTIME
};

#define SYBAOPCNT 0x4b
Expand Down Expand Up @@ -500,6 +504,8 @@ typedef int (*MHANDLEFUNC) (DBPROCESS * dbproc, DBINT msgno, int msgstate, int s
#define SRCDECIMALBIND 20
#define DATEBIND 21
#define TIMEBIND 22
#define BIGDATETIMEBIND 23
#define BIGTIMEBIND 24
#define BIGINTBIND 30
#define DATETIME2BIND 31
#define MAXBINDTYPES 32 /* keep last */
Expand Down
2 changes: 2 additions & 0 deletions misc/types.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
Name;vendor;varint;fixed;nullable;variable;blob;numeric;collate;unicode;ascii;datetime;size;nullable type;display size;
SYB5BIGTIME;SYB;1;0;1;0;0;0;0;0;0;1;8;0;15;
SYB5BIGDATETIME;SYB;1;0;1;0;0;0;0;0;0;1;8;0;26;
SYB5INT8;SYB;0;1;0;0;0;0;0;0;0;0;8;SYBINTN;20;
SYBBINARY;ALL;1;0;0;1;0;0;0;0;0;0;-1;0;2*S;
SYBBIT;ALL;0;1;0;0;0;0;0;0;0;0;1;SYBBITN;1;
Expand Down
4 changes: 4 additions & 0 deletions src/apps/datacopy.c
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,8 @@ transfer_data(BCPPARAMDATA params, DBPROCESS * dbsrc, DBPROCESS * dbdest)
case SYBDATETIME4:
case SYBTIME:
case SYBDATE:
case SYBBIGTIME:
case SYBBIGDATETIME:
case SYBCHAR:
case SYBTEXT:
case SYBBINARY:
Expand Down Expand Up @@ -719,6 +721,8 @@ transfer_data(BCPPARAMDATA params, DBPROCESS * dbsrc, DBPROCESS * dbdest)
case SYBDATETIME4:
case SYBTIME:
case SYBDATE:
case SYBBIGTIME:
case SYBBIGDATETIME:
case SYBMONEY:
case SYBMONEY4:
case SYBCHAR:
Expand Down
4 changes: 4 additions & 0 deletions src/ctlib/cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,8 @@ cs_convert(CS_CONTEXT * ctx, CS_DATAFMT * srcfmt, CS_VOID * srcdata, CS_DATAFMT
case SYBDATETIME4:
case SYBTIME:
case SYBDATE:
case SYB5BIGDATETIME:
case SYB5BIGTIME:
*resultlen = tds_get_size_by_type(src_type);
if (*resultlen > 0)
memcpy(dest, srcdata, *resultlen);
Expand Down Expand Up @@ -748,6 +750,8 @@ cs_convert(CS_CONTEXT * ctx, CS_DATAFMT * srcfmt, CS_VOID * srcdata, CS_DATAFMT
case SYBTIME:
case SYBDATE:
case SYBUNIQUE:
case SYB5BIGDATETIME:
case SYB5BIGTIME:
*resultlen = tds_get_size_by_type(desttype);
memcpy(dest, &(cres.ti), *resultlen);
ret = CS_SUCCEED;
Expand Down
8 changes: 8 additions & 0 deletions src/ctlib/ct.c
Original file line number Diff line number Diff line change
Expand Up @@ -2030,6 +2030,14 @@ _ct_get_server_type(TDSSOCKET *tds, int datatype)
if (!tds || tds_capability_has_req(tds->conn, TDS_REQ_DATA_TIME))
return SYBDATE;
return SYBDATETIME;
case CS_BIGDATETIME_TYPE:
if (!tds || tds_capability_has_req(tds->conn, TDS_REQ_DATA_BIGDATETIME))
return SYB5BIGDATETIME;
return SYBDATETIME;
case CS_BIGTIME_TYPE:
if (!tds || tds_capability_has_req(tds->conn, TDS_REQ_DATA_BIGTIME))
return SYB5BIGTIME;
return SYBDATETIME;

default:
return -1;
Expand Down
31 changes: 28 additions & 3 deletions src/dblib/dblib.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,8 +466,8 @@ static NULLREP default_null_representations[MAXBINDTYPES] = {
/* SRCDECIMALBIND 20 */ , { (BYTE*) &null_NUMERIC, sizeof(null_NUMERIC) }
/* DATEBIND 21 */ , { (BYTE*) &null_INT, sizeof(null_INT) }
/* TIMEBIND 22 */ , { (BYTE*) &null_INT, sizeof(null_INT) }
/* 23 */ , { NULL, 0 }
/* 24 */ , { NULL, 0 }
/* BIGDATETIMEBIND 23 */ , { (BYTE*) &null_BIGINT, sizeof(null_BIGINT) }
/* BIGTIMEBIND 24 */ , { (BYTE*) &null_BIGINT, sizeof(null_BIGINT) }
/* 25 */ , { NULL, 0 }
/* 26 */ , { NULL, 0 }
/* 27 */ , { NULL, 0 }
Expand Down Expand Up @@ -497,7 +497,10 @@ dbbindtype(int datatype)

case SYBDATE: return DATEBIND;
case SYBTIME: return TIMEBIND;


case SYB5BIGDATETIME: return BIGDATETIMEBIND;
case SYB5BIGTIME: return BIGTIMEBIND;

case SYBDECIMAL: return DECIMALBIND;
case SYBNUMERIC: return NUMERICBIND;

Expand Down Expand Up @@ -582,6 +585,8 @@ dbgetnull(DBPROCESS *dbproc, int bindtype, int varlen, BYTE* varaddr)
case BITBIND:
case TIMEBIND:
case DATEBIND:
case BIGDATETIMEBIND:
case BIGTIMEBIND:
memcpy(varaddr, pnullrep->bindval, pnullrep->len);
return SUCCEED;
case CHARBIND:
Expand Down Expand Up @@ -1953,6 +1958,8 @@ dbsetnull(DBPROCESS * dbproc, int bindtype, int bindlen, BYTE *bindval)
case BIGINTBIND:
case DATEBIND:
case TIMEBIND:
case BIGDATETIMEBIND:
case BIGTIMEBIND:
bindlen = (int)default_null_representations[bindtype].len;
break;

Expand Down Expand Up @@ -2172,6 +2179,12 @@ dblib_bound_type(int bindtype)
case TIMEBIND:
return SYBTIME;
break;
case BIGDATETIMEBIND:
return SYB5BIGDATETIME;
break;
case BIGTIMEBIND:
return SYB5BIGTIME;
break;
case MONEYBIND:
return SYBMONEY;
break;
Expand Down Expand Up @@ -2377,6 +2390,8 @@ dbconvert_ps(DBPROCESS * dbproc, int srctype, const BYTE * src, DBINT srclen,
case SYBDATETIME4:
case SYBDATE:
case SYBTIME:
case SYB5BIGDATETIME:
case SYB5BIGTIME:
case SYBUNIQUE:
ret = tds_get_size_by_type(desttype);
memcpy(dest, src, ret);
Expand Down Expand Up @@ -2448,6 +2463,8 @@ dbconvert_ps(DBPROCESS * dbproc, int srctype, const BYTE * src, DBINT srclen,
case SYBDATETIME4:
case SYBTIME:
case SYBDATE:
case SYB5BIGDATETIME:
case SYB5BIGTIME:
case SYBUNIQUE:
case SYBMSDATE:
case SYBMSTIME:
Expand Down Expand Up @@ -3596,10 +3613,12 @@ _get_printable_size(TDSCOLUMN * colinfo)
case SYBMONEY:
case SYBMONEY4:
return 12;
case SYB5BIGDATETIME:
case SYBDATETIME:
case SYBDATETIME4:
return 26;
case SYBTIME:
case SYB5BIGTIME:
return 15;
case SYBDATE:
return 10;
Expand Down Expand Up @@ -7148,6 +7167,8 @@ tds_prdatatype(TDS_SERVER_TYPE datatype_token)
case SYBMSDATETIMEOFFSET: return "SYBMSDATETIMEOFFSET";
case SYBDATE: return "SYBDATE";
case SYBTIME: return "SYBTIME";
case SYB5BIGDATETIME: return "SYBBIGDATETIME";
case SYB5BIGTIME: return "SYBBIGTIME";
default: break;
}
return "(unknown)";
Expand Down Expand Up @@ -7297,6 +7318,8 @@ copy_data_to_host_var(DBPROCESS * dbproc, int srctype, const BYTE * src, DBINT s
case SYBDATETIME4:
case SYBDATE:
case SYBTIME:
case SYB5BIGDATETIME:
case SYB5BIGTIME:
case SYBUNIQUE:
ret = tds_get_size_by_type(desttype);
memcpy(dest, src, ret);
Expand Down Expand Up @@ -7373,6 +7396,8 @@ copy_data_to_host_var(DBPROCESS * dbproc, int srctype, const BYTE * src, DBINT s
case SYBUNIQUE:
case SYBMSDATE:
case SYBMSTIME:
case SYB5BIGDATETIME:
case SYB5BIGTIME:
case SYBMSDATETIME2:
case SYBMSDATETIMEOFFSET:
memcpy(dest, &(dres.ti), len);
Expand Down
24 changes: 19 additions & 5 deletions src/odbc/convert_tds2sql.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ odbc_convert_datetime_to_binary(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype,
tds_datecrack(srctype, dta, &when);

len = 0;
if (srctype != SYBMSTIME && srctype != SYBTIME) {
if (srctype != SYBMSTIME && srctype != SYBTIME && srctype != SYB5BIGTIME) {
buf[0] = when.year;
buf[1] = when.month + 1;
buf[2] = when.day;
Expand Down Expand Up @@ -226,6 +226,8 @@ odbc_convert_to_binary(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR
case SYBMSDATETIMEOFFSET:
case SYBDATE:
case SYBTIME:
case SYB5BIGTIME:
case SYB5BIGDATETIME:
return odbc_convert_datetime_to_binary(stmt, curcol, srctype, (TDS_DATETIMEALL *) src, dest, destlen);
}

Expand Down Expand Up @@ -352,23 +354,35 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
if (desttype == SQL_C_CHAR || desttype == SQL_C_WCHAR) {
char buf[48];
TDSDATEREC when;
int prec = 3;
int prec;
const char *fmt = NULL;
const TDS_DATETIMEALL *dta = (const TDS_DATETIMEALL *) src;

switch (srctype) {
case SYBMSDATETIMEOFFSET:
case SYBMSDATETIME2:
prec = dta->time_prec;
goto datetime;
case SYB5BIGDATETIME:
prec = 6;
goto datetime;
case SYBDATETIME:
fmt = "%Y-%m-%d %H:%M:%S.%z";
break;
prec = 3;
goto datetime;
case SYBDATETIME4:
fmt = "%Y-%m-%d %H:%M:%S";
prec = 0;
datetime:
fmt = "%Y-%m-%d %H:%M:%S.%z";
break;
case SYBMSTIME:
prec = dta->time_prec;
goto time;
case SYB5BIGTIME:
prec = 6;
goto time;
case SYBTIME:
prec = 3;
time:
fmt = "%H:%M:%S.%z";
break;
case SYBMSDATE:
Expand Down
26 changes: 26 additions & 0 deletions src/odbc/odbc_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,31 @@ data_clrudt_set_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odb
drec->sql_desc_display_size = col->column_size * 2;
}

static void
data_sybbigtime_set_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver)
{
if (col->on_server.column_type == SYB5BIGTIME) {
drec->sql_desc_concise_type = SQL_SS_TIME2;
/* we always format using hh:mm:ss[.ffffff], see convert_tds2sql.c */
drec->sql_desc_display_size = 15;
drec->sql_desc_octet_length = sizeof(SQL_SS_TIME2_STRUCT);
drec->sql_desc_precision = 6;
drec->sql_desc_scale = 6;
drec->sql_desc_datetime_interval_code = SQL_CODE_TIMESTAMP;
SET_INFO2("bigtime", "'", "'", 15);
}

assert(col->on_server.column_type == SYB5BIGDATETIME);

drec->sql_desc_concise_type = SQL_TYPE_TIMESTAMP;
drec->sql_desc_display_size = 26;
drec->sql_desc_octet_length = sizeof(TIMESTAMP_STRUCT);
drec->sql_desc_precision = 6;
drec->sql_desc_scale = 6;
drec->sql_desc_datetime_interval_code = SQL_CODE_TIMESTAMP;
SET_INFO2("bigdatetime", "'", "'", 26);
}

static void
data_generic_set_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver)
{
Expand Down Expand Up @@ -378,3 +403,4 @@ TDS_DEFINE_FUNCS(numeric);
TDS_DEFINE_FUNCS(variant);
TDS_DEFINE_FUNCS(msdatetime);
TDS_DEFINE_FUNCS(clrudt);
TDS_DEFINE_FUNCS(sybbigtime);
10 changes: 10 additions & 0 deletions src/odbc/odbc_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -799,12 +799,16 @@ odbc_sql_to_server_type(TDSCONNECTION * conn, int sql_type, int sql_unsigned)
case SQL_TIMESTAMP:
/* ODBC version 3 */
case SQL_TYPE_DATE:
if (IS_TDS50(conn) && tds_capability_has_req(conn, TDS_REQ_DATA_BIGDATETIME))
return SYB5BIGDATETIME;
if (IS_TDS50(conn) && tds_capability_has_req(conn, TDS_REQ_DATA_DATE))
return SYBDATE;
if (IS_TDS73_PLUS(conn))
return SYBMSDATE;
goto type_timestamp;
case SQL_TYPE_TIME:
if (IS_TDS50(conn) && tds_capability_has_req(conn, TDS_REQ_DATA_BIGTIME))
return SYB5BIGTIME;
if (IS_TDS50(conn) && tds_capability_has_req(conn, TDS_REQ_DATA_TIME))
return SYBTIME;
if (IS_TDS73_PLUS(conn))
Expand All @@ -813,14 +817,20 @@ odbc_sql_to_server_type(TDSCONNECTION * conn, int sql_type, int sql_unsigned)
case SQL_TYPE_TIMESTAMP:
if (IS_TDS73_PLUS(conn))
return SYBMSDATETIME2;
if (IS_TDS50(conn) && tds_capability_has_req(conn, TDS_REQ_DATA_BIGDATETIME))
return SYB5BIGDATETIME;
return SYBDATETIME;
case SQL_SS_TIME2:
if (IS_TDS73_PLUS(conn))
return SYBMSTIME;
if (IS_TDS50(conn) && tds_capability_has_req(conn, TDS_REQ_DATA_BIGDATETIME))
return SYB5BIGDATETIME;
return SYBDATETIME;
case SQL_SS_TIMESTAMPOFFSET:
if (IS_TDS73_PLUS(conn))
return SYBMSDATETIMEOFFSET;
if (IS_TDS50(conn) && tds_capability_has_req(conn, TDS_REQ_DATA_BIGDATETIME))
return SYB5BIGDATETIME;
return SYBDATETIME;
case SQL_BINARY:
return SYBBINARY;
Expand Down
Loading

0 comments on commit adb893f

Please sign in to comment.