60
convert.c
60
convert.c
@ -169,7 +169,7 @@ static const char *mapFunction(const char *func, int param_count);
|
|||||||
static BOOL convert_money(const char *s, char *sout, size_t soutmax);
|
static BOOL convert_money(const char *s, char *sout, size_t soutmax);
|
||||||
static char parse_datetime(const char *buf, SIMPLE_TIME *st);
|
static char parse_datetime(const char *buf, SIMPLE_TIME *st);
|
||||||
size_t convert_linefeeds(const char *s, char *dst, size_t max, BOOL convlf, BOOL *changed);
|
size_t convert_linefeeds(const char *s, char *dst, size_t max, BOOL convlf, BOOL *changed);
|
||||||
static size_t convert_from_pgbinary(const char *value, char *rgbValue, SQLLEN cbValueMax);
|
static size_t convert_from_pgbinary(const char *value, bool binary_rawout, char *rgbValue, SQLLEN cbValueMax);
|
||||||
static int convert_lo(StatementClass *stmt, const void *value, SQLSMALLINT fCType,
|
static int convert_lo(StatementClass *stmt, const void *value, SQLSMALLINT fCType,
|
||||||
PTR rgbValue, SQLLEN cbValueMax, SQLLEN *pcbValue);
|
PTR rgbValue, SQLLEN cbValueMax, SQLLEN *pcbValue);
|
||||||
static int conv_from_octal(const char *s);
|
static int conv_from_octal(const char *s);
|
||||||
@ -242,6 +242,39 @@ static unsigned ODBCINT64 ATOI64U(const char *val)
|
|||||||
static void ResolveNumericParam(const SQL_NUMERIC_STRUCT *ns, char *chrform);
|
static void ResolveNumericParam(const SQL_NUMERIC_STRUCT *ns, char *chrform);
|
||||||
static void parse_to_numeric_struct(const char *wv, SQL_NUMERIC_STRUCT *ns, BOOL *overflow);
|
static void parse_to_numeric_struct(const char *wv, SQL_NUMERIC_STRUCT *ns, BOOL *overflow);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* field_is_bytea
|
||||||
|
* 检查oid field_type在数据库中是否为类似bytea的二进制数据类型
|
||||||
|
* 返回0 表示不是二进制数据类型
|
||||||
|
* 返回1 表示是二进制数据类型,并且byteaout进行输出
|
||||||
|
* 有两种字符串输出方式 (由数据库的bytea_output选项控制,分别为hex和escape)
|
||||||
|
* a. 将数据的每个字节以十六进制输出,在最前面加上 \x (\x010203)
|
||||||
|
* b. 将数据的每个字节以八进制输出, 每个字节前加上 \ (\001\002\003),但如果是可打印字符,那么还是按字符打出
|
||||||
|
* 返回2 表示是二进制数据类型,并且rawout进行输出
|
||||||
|
* 将数据的每个字节以十六进制输出即可
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define FIELD_BINARY_BYTEAOUT 1
|
||||||
|
#define FIELD_BINARY_RAWOUT 2
|
||||||
|
static int
|
||||||
|
filed_is_bytea(const OID field_type)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
switch (field_type) {
|
||||||
|
case PG_TYPE_BYTEA:
|
||||||
|
case PG_TYPE_MYSQL_BINARY:
|
||||||
|
res = FIELD_BINARY_BYTEAOUT;
|
||||||
|
break;
|
||||||
|
case PG_TYPE_RAW:
|
||||||
|
case PG_TYPE_BLOB:
|
||||||
|
res = FIELD_BINARY_RAWOUT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res = 0;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TIMESTAMP <-----> SIMPLE_TIME
|
* TIMESTAMP <-----> SIMPLE_TIME
|
||||||
* precision support since 7.2.
|
* precision support since 7.2.
|
||||||
@ -900,6 +933,7 @@ setup_getdataclass(SQLLEN * const length_return, const char ** const ptr_return,
|
|||||||
BOOL changed = FALSE;
|
BOOL changed = FALSE;
|
||||||
int len_for_wcs_term = 0;
|
int len_for_wcs_term = 0;
|
||||||
|
|
||||||
|
bool binary_rawout = false;
|
||||||
#ifdef UNICODE_SUPPORT
|
#ifdef UNICODE_SUPPORT
|
||||||
char *allocbuf = NULL;
|
char *allocbuf = NULL;
|
||||||
int unicode_count = -1;
|
int unicode_count = -1;
|
||||||
@ -907,14 +941,28 @@ setup_getdataclass(SQLLEN * const length_return, const char ** const ptr_return,
|
|||||||
BOOL hybrid = FALSE;
|
BOOL hybrid = FALSE;
|
||||||
#endif /* UNICODE_SUPPORT */
|
#endif /* UNICODE_SUPPORT */
|
||||||
|
|
||||||
if (PG_TYPE_BYTEA == field_type)
|
// if (PG_TYPE_BYTEA == field_type)
|
||||||
|
if (FIELD_BINARY_BYTEAOUT == filed_is_bytea(field_type))
|
||||||
{
|
{
|
||||||
|
//BYTEA类型数据从pg内核发送过来时,会根据参数添加\x表示十六进制
|
||||||
|
//或者直接收到其二进制裸数据的八进制字符串(\001 \002 \003)
|
||||||
|
|
||||||
|
//如果以SQL_C_BINARY接收,则要将字符串转换成二进制字节流
|
||||||
if (SQL_C_BINARY == fCType)
|
if (SQL_C_BINARY == fCType)
|
||||||
bytea_process_kind = BYTEA_PROCESS_BINARY;
|
bytea_process_kind = BYTEA_PROCESS_BINARY;
|
||||||
else if (0 == strnicmp(neut_str, "\\x", 2)) /* hex format */
|
else if (0 == strnicmp(neut_str, "\\x", 2)) /* hex format */
|
||||||
neut_str += 2;
|
neut_str += 2;
|
||||||
else
|
else
|
||||||
bytea_process_kind = BYTEA_PROCESS_ESCAPE;
|
bytea_process_kind = BYTEA_PROCESS_ESCAPE;
|
||||||
|
}
|
||||||
|
else if (FIELD_BINARY_RAWOUT == filed_is_bytea(field_type))
|
||||||
|
{
|
||||||
|
//对于raw调用的rawout,将收到裸数据的十六进制字符串,且前面没有\x
|
||||||
|
if (SQL_C_BINARY == fCType)
|
||||||
|
{
|
||||||
|
bytea_process_kind = BYTEA_PROCESS_BINARY;
|
||||||
|
binary_rawout = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNICODE_SUPPORT
|
#ifdef UNICODE_SUPPORT
|
||||||
@ -947,7 +995,7 @@ setup_getdataclass(SQLLEN * const length_return, const char ** const ptr_return,
|
|||||||
if (fCType == SQL_C_WCHAR)
|
if (fCType == SQL_C_WCHAR)
|
||||||
{
|
{
|
||||||
if (BYTEA_PROCESS_ESCAPE == bytea_process_kind)
|
if (BYTEA_PROCESS_ESCAPE == bytea_process_kind)
|
||||||
unicode_count = convert_from_pgbinary(neut_str, NULL, 0) * 2;
|
unicode_count = convert_from_pgbinary(neut_str, binary_rawout, NULL, 0) * 2;
|
||||||
else if (hybrid)
|
else if (hybrid)
|
||||||
{
|
{
|
||||||
MYLOG(0, "hybrid estimate\n");
|
MYLOG(0, "hybrid estimate\n");
|
||||||
@ -979,7 +1027,7 @@ setup_getdataclass(SQLLEN * const length_return, const char ** const ptr_return,
|
|||||||
;
|
;
|
||||||
else if (0 != bytea_process_kind)
|
else if (0 != bytea_process_kind)
|
||||||
{
|
{
|
||||||
len = convert_from_pgbinary(neut_str, NULL, 0);
|
len = convert_from_pgbinary(neut_str, binary_rawout, NULL, 0);
|
||||||
if (BYTEA_PROCESS_BINARY != bytea_process_kind)
|
if (BYTEA_PROCESS_BINARY != bytea_process_kind)
|
||||||
len *= 2;
|
len *= 2;
|
||||||
changed = TRUE;
|
changed = TRUE;
|
||||||
@ -1021,7 +1069,7 @@ setup_getdataclass(SQLLEN * const length_return, const char ** const ptr_return,
|
|||||||
{
|
{
|
||||||
if (BYTEA_PROCESS_ESCAPE == bytea_process_kind)
|
if (BYTEA_PROCESS_ESCAPE == bytea_process_kind)
|
||||||
{
|
{
|
||||||
len = convert_from_pgbinary(neut_str, pgdc->ttlbuf, pgdc->ttlbuflen);
|
len = convert_from_pgbinary(neut_str, binary_rawout, pgdc->ttlbuf, pgdc->ttlbuflen);
|
||||||
len = pg_bin2whex(pgdc->ttlbuf, (SQLWCHAR *) pgdc->ttlbuf, len);
|
len = pg_bin2whex(pgdc->ttlbuf, (SQLWCHAR *) pgdc->ttlbuf, len);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1055,7 +1103,7 @@ setup_getdataclass(SQLLEN * const length_return, const char ** const ptr_return,
|
|||||||
;
|
;
|
||||||
else if (0 != bytea_process_kind)
|
else if (0 != bytea_process_kind)
|
||||||
{
|
{
|
||||||
len = convert_from_pgbinary(neut_str, pgdc->ttlbuf, pgdc->ttlbuflen);
|
len = convert_from_pgbinary(neut_str, binary_rawout, pgdc->ttlbuf, pgdc->ttlbuflen);
|
||||||
if (BYTEA_PROCESS_ESCAPE == bytea_process_kind)
|
if (BYTEA_PROCESS_ESCAPE == bytea_process_kind)
|
||||||
len = pg_bin2hex(pgdc->ttlbuf, pgdc->ttlbuf, len);
|
len = pg_bin2hex(pgdc->ttlbuf, pgdc->ttlbuf, len);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user