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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list