Fixes about SQLDescribeCol() or SQLColAttribute().
authorHiroshi Inoue <h-inoue@dream.email.ne.jp>
Sun, 19 Mar 2017 06:04:47 +0000 (15:04 +0900)
committerHiroshi Inoue <h-inoue@dream.email.ne.jp>
Sun, 19 Mar 2017 11:38:42 +0000 (20:38 +0900)
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
results.c
test/expected/colattribute.out
test/expected/colattribute_1.out
test/expected/colattribute_2.out

index 98a3b987ae57d5307dcd438753177d2896038d94..bb482fbe787fcb52f3b11b56599fc9a6283df42f 100644 (file)
--- 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;
    }
 }
 
index 93f92be0096130cb533658a4eb4fea49365f2f74..d87ab9eb97404fa5e95ca1c7ed4ede463202b68a 100644 (file)
--- 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)
    {
index f4b562aa067ff3dc8f59797374626222e2b8c4ae..3fb501baebeae5ec771a5871ee49483225d690d4 100644 (file)
@@ -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 --
index b4387e631912675dfce73cda223df4ef8bb25e24..e19766f80232bd189c16937a62390b60155fb9d0 100644 (file)
@@ -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 --
index fda16738b09da7004903490bfb4580bf13775423..20163225aaf69ee77d630c59d4d683d5dd2a7ad1 100644 (file)
@@ -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 --