From 7f9ec377dd1149fd68a6e938cf9af61d46e139a6 Mon Sep 17 00:00:00 2001 From: Hiroshi Inoue Date: Sun, 19 Mar 2017 15:04:47 +0900 Subject: [PATCH] Fixes about SQLDescribeCol() or SQLColAttribute(). 1. Report the size of constant strings using Unknown Sizes as Longest. 2. Correct the inconsistency between the sqltype of PG_TYPE_TEXT or PG_TYPE_UNKNOWN and the size in case of Unknown Sizes as Longeset. --- pgtypes.c | 74 +++++++++++++++++++------------- results.c | 14 +++++- test/expected/colattribute.out | 4 +- test/expected/colattribute_1.out | 4 +- test/expected/colattribute_2.out | 4 +- 5 files changed, 63 insertions(+), 37 deletions(-) diff --git a/pgtypes.c b/pgtypes.c index 98a3b98..bb482fb 100644 --- a/pgtypes.c +++ b/pgtypes.c @@ -287,6 +287,8 @@ inolog("!!! atttypmod < 0 ?\n"); if (atttypmod < 0 && adtsize_or_longestlen < 0) return maxsize; +inolog("!!! adtsize_or_logngest=%d\n", adtsize_or_longestlen); + p = adtsize_or_longestlen; /* longest */ /* * Catalog Result Sets -- use assigned column width (i.e., from * set_tuplefield_string) @@ -294,19 +296,18 @@ inolog("!!! atttypmod < 0 ?\n"); inolog("!!! catalog_result=%d\n", handle_unknown_size_as); if (UNKNOWNS_AS_LONGEST == handle_unknown_size_as) { - mylog("%s: LONGEST: p = %d\n", __FUNCTION__, adtsize_or_longestlen); - if (adtsize_or_longestlen > 0) - return adtsize_or_longestlen; + mylog("%s: LONGEST: p = %d\n", __FUNCTION__, p); + if (p > 0 && + (atttypmod < 0 || atttypmod > p)) + return p; } if (TYPE_MAY_BE_ARRAY(type)) { - if (adtsize_or_longestlen > 0) - return adtsize_or_longestlen; + if (p > 0) + return p; return maxsize; } -inolog("!!! adtsize_or_logngest=%d\n", adtsize_or_longestlen); - p = adtsize_or_longestlen; /* longest */ /* Size is unknown -- handle according to parameter */ if (atttypmod > 0) /* maybe the length is known */ { @@ -491,6 +492,7 @@ pgtype_attr_to_concise_type(const ConnectionClass *conn, OID type, int atttypmod #ifdef PG_INTERVAL_AS_SQL_INTERVAL SQLSMALLINT sqltype; #endif /* PG_INTERVAL_AS_SQL_INTERVAL */ + BOOL bLongVarchar, bFixed = FALSE; switch (type) { @@ -500,35 +502,41 @@ pgtype_attr_to_concise_type(const ConnectionClass *conn, OID type, int atttypmod case PG_TYPE_REFCURSOR: return ALLOW_WCHAR(conn) ? SQL_WVARCHAR : SQL_VARCHAR; -#ifdef UNICODE_SUPPORT case PG_TYPE_BPCHAR: - if (getCharColumnSizeX(conn, type, atttypmod, adtsize_or_longestlen, handle_unknown_size_as) > ci->drivers.max_varchar_size) - return ALLOW_WCHAR(conn) ? SQL_WLONGVARCHAR : SQL_LONGVARCHAR; - return ALLOW_WCHAR(conn) ? SQL_WCHAR : SQL_CHAR; - + bFixed = TRUE; case PG_TYPE_VARCHAR: if (getCharColumnSizeX(conn, type, atttypmod, adtsize_or_longestlen, handle_unknown_size_as) > ci->drivers.max_varchar_size) + bLongVarchar = TRUE; + else + bLongVarchar = FALSE; + if (bLongVarchar) +#ifdef UNICODE_SUPPORT return ALLOW_WCHAR(conn) ? SQL_WLONGVARCHAR : SQL_LONGVARCHAR; - return ALLOW_WCHAR(conn) ? SQL_WVARCHAR : SQL_VARCHAR; - + else if (bFixed) + return ALLOW_WCHAR(conn) ? SQL_WCHAR : SQL_CHAR; + else + return ALLOW_WCHAR(conn) ? SQL_WVARCHAR : SQL_VARCHAR; +#else + return SQL_LONGVARCHAR; + else + return bFixed ? SQL_CHAR : SQL_VARCHAR; +#endif /* UNICODE_SUPPORT */ case PG_TYPE_TEXT: - return ci->drivers.text_as_longvarchar ? + bLongVarchar = ci->drivers.text_as_longvarchar; + if (bLongVarchar) + { + int column_size = getCharColumnSizeX(conn, type, atttypmod, adtsize_or_longestlen, handle_unknown_size_as); + if (column_size > 0 && + column_size <= ci->drivers.max_varchar_size) + bLongVarchar = FALSE; + } +#ifdef UNICODE_SUPPORT + return bLongVarchar ? (ALLOW_WCHAR(conn) ? SQL_WLONGVARCHAR : SQL_LONGVARCHAR) : (ALLOW_WCHAR(conn) ? SQL_WVARCHAR : SQL_VARCHAR); #else - case PG_TYPE_BPCHAR: - if (getCharColumnSizeX(conn, type, atttypmod, adtsize_or_longestlen, handle_unknown_size_as) > ci->drivers.max_varchar_size) - return SQL_LONGVARCHAR; - return SQL_CHAR; - - case PG_TYPE_VARCHAR: - if (getCharColumnSizeX(conn, type, atttypmod, adtsize_or_longestlen, handle_unknown_size_as) > ci->drivers.max_varchar_size) - return SQL_LONGVARCHAR; - return SQL_VARCHAR; - - case PG_TYPE_TEXT: - return ci->drivers.text_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR; + return bLongVarchar ? SQL_LONGVARCHAR : SQL_VARCHAR; #endif /* UNICODE_SUPPORT */ case PG_TYPE_BYTEA: @@ -609,11 +617,19 @@ pgtype_attr_to_concise_type(const ConnectionClass *conn, OID type, int atttypmod if (type == conn->lobj_type) return SQL_LONGVARBINARY; + bLongVarchar = ci->drivers.unknowns_as_longvarchar; + if (bLongVarchar) + { + int column_size = getCharColumnSizeX(conn, type, atttypmod, adtsize_or_longestlen, handle_unknown_size_as); + if (column_size > 0 && + column_size <= ci->drivers.max_varchar_size) + bLongVarchar = FALSE; + } #ifdef EXPERIMENTAL_CURRENTLY if (ALLOW_WCHAR(conn)) - return ci->drivers.unknowns_as_longvarchar ? SQL_WLONGVARCHAR : SQL_WVARCHAR; + return bLongVarchar ? SQL_WLONGVARCHAR : SQL_WVARCHAR; #endif /* EXPERIMENTAL_CURRENTLY */ - return ci->drivers.unknowns_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR; + return bLongVarchar ? SQL_LONGVARCHAR : SQL_VARCHAR; } } diff --git a/results.c b/results.c index 93f92be..d87ab9e 100644 --- a/results.c +++ b/results.c @@ -335,16 +335,21 @@ inolog("answering bookmark info\n"); if (icol < irdflds->nfields && irdflds->fi) fi = irdflds->fi[icol]; } + res = SC_get_Curres(stmt); #ifdef SUPPRESS_LONGEST_ON_CURSORS if (UNKNOWNS_AS_LONGEST == unknown_sizes) { - if ((res = SC_get_Curres(stmt)) && - QR_once_reached_eof(res)) + if (QR_once_reached_eof(res)) unknown_sizes = UNKNOWNS_AS_LONGEST; else unknown_sizes = UNKNOWNS_AS_MAX; } #endif /* SUPPRESS_LONGEST_ON_CURSORS */ + /* handle constants */ + if (res && + -2 == QR_get_fieldsize(res, icol)) + unknown_sizes = UNKNOWNS_AS_LONGEST; + if (FI_is_applicable(fi)) { fieldtype = getEffectiveOid(conn, fi); @@ -641,6 +646,11 @@ inolog("answering bookmark info\n"); unknown_sizes = UNKNOWNS_AS_MAX; } #endif /* SUPPRESS_LONGEST_ON_CURSORS */ + /* handle constants */ + if (res && + -2 == QR_get_fieldsize(res, col_idx)) + unknown_sizes = UNKNOWNS_AS_LONGEST; + column_size = (USE_FI(fi, unknown_sizes) && fi->column_size > 0) ? fi->column_size : pgtype_column_size(stmt, field_type, col_idx, unknown_sizes); switch (fDescType) { diff --git a/test/expected/colattribute.out b/test/expected/colattribute.out index f4b562a..3fb501b 100644 --- a/test/expected/colattribute.out +++ b/test/expected/colattribute.out @@ -11,7 +11,7 @@ SQL_DESC_OCTET_LENGTH: 49140 SQL_DESC_TYPE_NAME: text -- Column 3: unknowncol -- -SQL_DESC_OCTET_LENGTH: 100 +SQL_DESC_OCTET_LENGTH: 84 SQL_DESC_TYPE_NAME: unknown -- Column 4: varcharcol -- @@ -43,7 +43,7 @@ SQL_DESC_OCTET_LENGTH: 49140 SQL_DESC_TYPE_NAME: text -- Column 3: unknowncol -- -SQL_DESC_OCTET_LENGTH: 100 +SQL_DESC_OCTET_LENGTH: 84 SQL_DESC_TYPE_NAME: unknown -- Column 4: varcharcol -- diff --git a/test/expected/colattribute_1.out b/test/expected/colattribute_1.out index b4387e6..e19766f 100644 --- a/test/expected/colattribute_1.out +++ b/test/expected/colattribute_1.out @@ -11,7 +11,7 @@ SQL_DESC_OCTET_LENGTH: 8190 SQL_DESC_TYPE_NAME: text -- Column 3: unknowncol -- -SQL_DESC_OCTET_LENGTH: 100 +SQL_DESC_OCTET_LENGTH: 14 SQL_DESC_TYPE_NAME: unknown -- Column 4: varcharcol -- @@ -43,7 +43,7 @@ SQL_DESC_OCTET_LENGTH: 8190 SQL_DESC_TYPE_NAME: text -- Column 3: unknowncol -- -SQL_DESC_OCTET_LENGTH: 100 +SQL_DESC_OCTET_LENGTH: 14 SQL_DESC_TYPE_NAME: unknown -- Column 4: varcharcol -- diff --git a/test/expected/colattribute_2.out b/test/expected/colattribute_2.out index fda1673..2016322 100644 --- a/test/expected/colattribute_2.out +++ b/test/expected/colattribute_2.out @@ -11,7 +11,7 @@ SQL_DESC_OCTET_LENGTH: 16380 SQL_DESC_TYPE_NAME: text -- Column 3: unknowncol -- -SQL_DESC_OCTET_LENGTH: 200 +SQL_DESC_OCTET_LENGTH: 28 SQL_DESC_TYPE_NAME: unknown -- Column 4: varcharcol -- @@ -43,7 +43,7 @@ SQL_DESC_OCTET_LENGTH: 16380 SQL_DESC_TYPE_NAME: text -- Column 3: unknowncol -- -SQL_DESC_OCTET_LENGTH: 200 +SQL_DESC_OCTET_LENGTH: 28 SQL_DESC_TYPE_NAME: unknown -- Column 4: varcharcol -- -- 2.39.5