Changeset: d1b2fe5d87cd for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=d1b2fe5d87cd
Modified Files:
        clients/odbc/driver/ODBCConvert.c
        clients/odbc/driver/ODBCUtil.c
        clients/odbc/driver/ODBCUtil.h
        gdk/gdk_bat.c
Branch: default
Log Message:

Merge with Aug2018 branch.


diffs (truncated from 304 to 300 lines):

diff --git a/clients/odbc/driver/ODBCConvert.c 
b/clients/odbc/driver/ODBCConvert.c
--- a/clients/odbc/driver/ODBCConvert.c
+++ b/clients/odbc/driver/ODBCConvert.c
@@ -1236,25 +1236,44 @@ ODBCFetch(ODBCStmt *stmt,
                origlenp = lenp;
                if (type == SQL_C_WCHAR) {
                        /* allocate temporary space */
-                       buflen = 511; /* should be enough for most types */
-                       if (data != NULL &&
-                           (sql_type == SQL_CHAR ||
-                            sql_type == SQL_VARCHAR ||
-                            sql_type == SQL_LONGVARCHAR ||
-                            sql_type == SQL_WCHAR ||
-                            sql_type == SQL_WVARCHAR ||
-                            sql_type == SQL_WLONGVARCHAR))
-                               buflen = (SQLLEN) datalen + 1; /* but this is 
certainly enough for strings */
-                       ptr = malloc(buflen);
-                       if (ptr == NULL) {
-                               /* Memory allocation error */
-                               addStmtError(stmt, "HY001", NULL, 0);
-                               return SQL_ERROR;
+                       switch (sql_type) {
+                       case SQL_CHAR:
+                       case SQL_VARCHAR:
+                       case SQL_LONGVARCHAR:
+                       case SQL_WCHAR:
+                       case SQL_WVARCHAR:
+                       case SQL_WLONGVARCHAR:
+                       case SQL_BINARY:
+                       case SQL_VARBINARY:
+                       case SQL_LONGVARBINARY:
+                       case SQL_GUID:
+                                /* this is certainly enough for strings */
+                               buflen = (SQLLEN) datalen + 1;
+                               ptr = NULL;
+                               break;
+                       default:
+                               /* should be enough for most types */
+                               buflen = 511;
+                               ptr = malloc(buflen);
+                               if (ptr == NULL) {
+                                       /* Memory allocation error */
+                                       addStmtError(stmt, "HY001", NULL, 0);
+                                       return SQL_ERROR;
+                               }
+                               break;
                        }
-
                        lenp = NULL;
                }
                switch (sql_type) {
+               case SQL_BINARY:
+               case SQL_VARBINARY:
+               case SQL_LONGVARBINARY:
+                       if (buflen > 0 && (buflen & 1) == 0) {
+                               /* return even number of bytes + NULL
+                                * (i.e. buflen must be odd) */
+                               buflen--;
+                       }
+                       /* fall through */
                default:
                case SQL_CHAR:
                case SQL_VARCHAR:
@@ -1265,71 +1284,22 @@ ODBCFetch(ODBCStmt *stmt,
                case SQL_GUID:
                        if (irdrec->already_returned >= datalen) {
                                /* no more data to return */
-                               if (type == SQL_C_WCHAR)
-                                       free(ptr);
-                               return SQL_NO_DATA;
-                       }
-                       data += irdrec->already_returned;
-                       datalen -= irdrec->already_returned;
-                       copyString(data, datalen, ptr, buflen, lenp, SQLLEN,
-                                  addStmtError, stmt, return SQL_ERROR);
-                       if (datalen < (size_t) buflen)
-                               irdrec->already_returned += datalen;
-                       else
-                               irdrec->already_returned += buflen - 1;
-                       break;
-               case SQL_BINARY:
-               case SQL_VARBINARY:
-               case SQL_LONGVARBINARY: {
-                       size_t k;
-                       int n;
-                       unsigned char c = 0;
-                       SQLLEN j;
-                       unsigned char *p = ptr;
-
-                       if (irdrec->already_returned >= datalen) {
-                               /* no more data to return */
-                               if (type == SQL_C_WCHAR)
+                               if (type == SQL_C_WCHAR && ptr)
                                        free(ptr);
                                return SQL_NO_DATA;
                        }
                        data += irdrec->already_returned;
                        datalen -= irdrec->already_returned;
-                       for (k = 0, j = 0; k < datalen && j < buflen; k++) {
-                               if (isdigit((unsigned char) data[k]))
-                                       n = data[k] - '0';
-                               else if ('A' <= data[k] && data[k] <= 'F')
-                                       n = data[k] - 'A' + 10;
-                               else if ('a' <= data[k] && data[k] <= 'f')
-                                       n = data[k] - 'a' + 10;
-                               else {
-                                       /* should not happen */
-                                       /* General error */
-                                       addStmtError(stmt, "HY000", "Unexpected 
data from server", 0);
-                                       if (type == SQL_C_WCHAR)
-                                               free(ptr);
-                                       return SQL_ERROR;
-                               }
-                               if (k & 1) {
-                                       c |= n;
-                                       p[j] = c;
-                                       j++;
-                               } else
-                                       c = n << 4;
+                       if (ptr) {
+                               copyString(data, datalen, ptr, buflen, lenp,
+                                          SQLLEN, addStmtError, stmt,
+                                          return SQL_ERROR);
                        }
-                       if (k & 1) {
-                               /* should not happen: uneven length */
-                               /* General error */
-                               addStmtError(stmt, "HY000", "Unexpected data 
from server", 0);
-                               if (type == SQL_C_WCHAR)
-                                       free(ptr);
-                               return SQL_ERROR;
-                       }
-                       irdrec->already_returned += k;
-                       if (lenp)
-                               *lenp = datalen / 2;
+                       if (datalen < (size_t) buflen)
+                               irdrec->already_returned += datalen;
+                       else
+                               irdrec->already_returned += buflen - 1;
                        break;
-               }
                case SQL_TINYINT:
                case SQL_SMALLINT:
                case SQL_INTEGER:
@@ -1866,11 +1836,20 @@ ODBCFetch(ODBCStmt *stmt,
                }
                if (type == SQL_C_WCHAR) {
                        SQLSMALLINT n;
-                       SQLINTEGER i;
+                       size_t i;
 
-                       ODBCutf82wchar((SQLCHAR *) ptr, SQL_NTS,
-                                      (SQLWCHAR *) origptr,
-                                      origbuflen / sizeof(SQLWCHAR), &n, &i);
+                       if (ptr) {
+                               ODBCutf82wchar((SQLCHAR *) ptr, SQL_NTS,
+                                              (SQLWCHAR *) origptr,
+                                              origbuflen / sizeof(SQLWCHAR),
+                                              &n, &i);
+                               free(ptr);
+                       } else {
+                               ODBCutf82wchar((SQLCHAR *) data, SQL_NTS,
+                                              (SQLWCHAR *) origptr,
+                                              origbuflen / sizeof(SQLWCHAR),
+                                              &n, &i);
+                       }
 #ifdef ODBCDEBUG
                        ODBCLOG("Writing %d bytes to %p\n",
                                (int) (n * sizeof(SQLWCHAR)),
@@ -1879,18 +1858,20 @@ ODBCFetch(ODBCStmt *stmt,
 
                        if (origlenp)
                                *origlenp = n * sizeof(SQLWCHAR); /* # of 
bytes, not chars */
-                       free(ptr);
                        irdrec->already_returned -= datalen;
                        irdrec->already_returned += i;
+                       if (i < datalen) {
+                               /* String data, right-truncated */
+                               addStmtError(stmt, "01004", NULL, 0);
+                       }
                }
 #ifdef ODBCDEBUG
                else
-                       ODBCLOG("Writing %d bytes to %p\n",
-                               (int) strlen(ptr), ptr);
+                       ODBCLOG("Writing %zu bytes to %p\n", strlen(ptr), ptr);
 #endif
                break;
        }
-       case SQL_C_BINARY:
+       case SQL_C_BINARY: {
                if (buflen < 0) {
                        /* Invalid string or buffer length */
                        addStmtError(stmt, "HY090", NULL, 0);
@@ -1933,8 +1914,63 @@ ODBCFetch(ODBCStmt *stmt,
                        /* Restricted data type attribute violation */
                        addStmtError(stmt, "07006", NULL, 0);
                        return SQL_ERROR;
+               case SQL_BINARY:
+               case SQL_VARBINARY:
+               case SQL_LONGVARBINARY:
+                       break;
                }
-               /* break;  -- not reached */
+               if (irdrec->already_returned >= datalen) {
+                       /* no more data to return */
+                       return SQL_NO_DATA;
+               }
+               data += irdrec->already_returned;
+               datalen -= irdrec->already_returned;
+
+               size_t k;
+               SQLLEN j;
+               unsigned char *p = ptr;
+
+               for (k = 0, j = 0; k < datalen && j < buflen; k++) {
+                       unsigned int n;
+
+                       if (isdigit((unsigned char) data[k]))
+                               n = data[k] - '0';
+                       else if ('A' <= data[k] && data[k] <= 'F')
+                               n = data[k] - 'A' + 10;
+                       else if ('a' <= data[k] && data[k] <= 'f')
+                               n = data[k] - 'a' + 10;
+                       else {
+                               /* should not happen: not a hex character */
+                               /* General error */
+                               addStmtError(stmt, "HY000", "Unexpected data 
from server", 0);
+                               if (type == SQL_C_WCHAR)
+                                       free(ptr);
+                               return SQL_ERROR;
+                       }
+                       if (k & 1) {
+                               p[j] |= n;
+                               j++;
+                       } else {
+                               p[j] = n << 4;
+                       }
+               }
+               if (k & 1) {
+                       /* should not happen: uneven length */
+                       /* General error */
+                       addStmtError(stmt, "HY000", "Unexpected data from 
server", 0);
+                       if (type == SQL_C_WCHAR)
+                               free(ptr);
+                       return SQL_ERROR;
+               }
+               irdrec->already_returned += k;
+               if (lenp)
+                       *lenp = datalen / 2;
+               if (k < datalen) {
+                       /* String data, right-truncated */
+                       addStmtError(stmt, "01004", NULL, 0);
+               }
+               break;
+       }
        case SQL_C_BIT:
                if (ardrec && row > 0)
                        ptr = (SQLPOINTER) ((char *) ptr + row * (bind_type == 
SQL_BIND_BY_COLUMN ? (SQLINTEGER) sizeof(unsigned char) : bind_type));
diff --git a/clients/odbc/driver/ODBCUtil.c b/clients/odbc/driver/ODBCUtil.c
--- a/clients/odbc/driver/ODBCUtil.c
+++ b/clients/odbc/driver/ODBCUtil.c
@@ -188,7 +188,7 @@ ODBCutf82wchar(const SQLCHAR *src,
               SQLWCHAR *buf,
               SQLLEN buflen,
               SQLSMALLINT *buflenout,
-              SQLINTEGER *consumed)
+              size_t *consumed)
 {
        SQLLEN i = 0;
        SQLINTEGER j = 0;
@@ -263,7 +263,7 @@ ODBCutf82wchar(const SQLCHAR *src,
        if (buflen > 0)
                buf[i] = 0;
        if (consumed)
-               *consumed = j;
+               *consumed = (size_t) j;
        while (j < length && src[j]) {
                i++;
                if ((src[j+0] & 0x80) == 0) {
diff --git a/clients/odbc/driver/ODBCUtil.h b/clients/odbc/driver/ODBCUtil.h
--- a/clients/odbc/driver/ODBCUtil.h
+++ b/clients/odbc/driver/ODBCUtil.h
@@ -100,7 +100,7 @@ extern char *dupODBCstring(const SQLCHAR
        } while (0)
 
 extern SQLCHAR *ODBCwchar2utf8(const SQLWCHAR *s, SQLLEN length, const char 
**errmsg);
-extern const char *ODBCutf82wchar(const SQLCHAR *s, SQLINTEGER length, 
SQLWCHAR *buf, SQLLEN buflen, SQLSMALLINT *buflenout, SQLINTEGER *consumed);
+extern const char *ODBCutf82wchar(const SQLCHAR *s, SQLINTEGER length, 
SQLWCHAR *buf, SQLLEN buflen, SQLSMALLINT *buflenout, size_t *consumed);
 
 #define fixWcharIn(ws, wsl, t, s, errfunc, hdl, exit)                  \
        do {                                                            \
diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c
--- a/gdk/gdk_bat.c
+++ b/gdk/gdk_bat.c
@@ -1007,7 +1007,7 @@ BUNappend(BAT *b, const void *t, bool fo
 
        BATcheck(b, "BUNappend", GDK_FAIL);
 
-       assert(!isVIEW(b));
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to