Changeset: 1b56cc8e870c for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=1b56cc8e870c
Modified Files:
        clients/odbc/driver/ODBCConvert.c
        clients/odbc/driver/ODBCUtil.c
        common/utils/muuid.c
        monetdb5/modules/atoms/uuid.c
Branch: linear-hashing
Log Message:

Use uuid library when available; fix ODBC roundtrip of UUID values.
We don't use the uuid library for parsing UUID strings (uuid_parse)
since we want to accept UUID strings without hyphens.


diffs (truncated from 427 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
@@ -39,6 +39,15 @@ typedef struct {
 #endif
 } bignum_t;
 
+typedef union {
+       SQLGUID g;
+       struct {
+               uint32_t d1;
+               uint16_t d2, d3;
+               uint8_t d4[8];
+       } d;
+} uuid_t;
+
 /* Parse a number and store in a bignum_t.
  * 1 is returned if all is well;
  * 2 is returned if there is loss of precision (i.e. overflow of the value);
@@ -2795,44 +2804,22 @@ ODBCFetch(ODBCStmt *stmt,
 #ifdef ODBCDEBUG
                ODBCLOG("Writing 16 bytes to %p\n", ptr);
 #endif
-               for (i = 0; i < 16; i++) {
-                       if (i == 8 || i == 12 || i == 16 || i == 20) {
-                               if (*data != '-') {
-                                       /* Restricted data type
-                                        * attribute violation */
-                                       addStmtError(stmt, "07006", NULL, 0);
-                                       return SQL_ERROR;
-                               }
-                               data++;
-                       }
-                       if (isdigit((unsigned char) *data))
-                               ((unsigned char *) ptr)[i] = *data - '0';
-                       else if ('a' <= *data && *data <= 'f')
-                               ((unsigned char *) ptr)[i] = *data - 'a' + 10;
-                       else if ('A' <= *data && *data <= 'F')
-                               ((unsigned char *) ptr)[i] = *data - 'A' + 10;
-                       else {
-                               /* Restricted data type attribute
-                                * violation */
-                               addStmtError(stmt, "07006", NULL, 0);
-                               return SQL_ERROR;
-                       }
-                       ((unsigned char *) ptr)[i] <<= 4;
-                       data++;
-                       if (isdigit((unsigned char) *data))
-                               ((unsigned char *) ptr)[i] |= *data - '0';
-                       else if ('a' <= *data && *data <= 'f')
-                               ((unsigned char *) ptr)[i] |= *data - 'a' + 10;
-                       else if ('A' <= *data && *data <= 'F')
-                               ((unsigned char *) ptr)[i] |= *data - 'A' + 10;
-                       else {
-                               /* Restricted data type attribute
-                                * violation */
-                               addStmtError(stmt, "07006", NULL, 0);
-                               return SQL_ERROR;
-                       }
-                       data++;
+               uuid_t u;
+               if (sscanf(data, "%8"SCNx32"-%4"SCNx16"-%4"SCNx16
+                          "-%2"SCNx8"%2"SCNx8"-%2"SCNx8"%2"SCNx8
+                          "%2"SCNx8"%2"SCNx8"%2"SCNx8"%2"SCNx8,
+                          &u.d.d1, &u.d.d2, &u.d.d3, &u.d.d4[0],
+                          &u.d.d4[1], &u.d.d4[2], &u.d.d4[3],
+                          &u.d.d4[4], &u.d.d4[5], &u.d.d4[6],
+                          &u.d.d4[7]) != 11) {
+                       /* Restricted data type attribute
+                        * violation */
+                       addStmtError(stmt, "07006", NULL, 0);
+                       return SQL_ERROR;
                }
+               WriteData(ptr, u.g, SQLGUID);
+               if (lenp)
+                       *lenp = sizeof(SQLGUID);
                break;
        default:
                /* Invalid application buffer type */
@@ -2902,6 +2889,7 @@ ODBCStore(ODBCStmt *stmt,
        TIMESTAMP_STRUCT tsval;
        int ivalprec = 0;       /* interval second precision */
        SQL_INTERVAL_STRUCT ival;
+       uuid_t u;
        char *buf = *bufp;
        size_t bufpos = *bufposp;
        size_t buflen = *buflenp;
@@ -3365,25 +3353,16 @@ ODBCStore(ODBCStmt *stmt,
                        }
                        break;
                case SQL_C_GUID:
+                       u.g = *(SQLGUID *)ptr;
                        snprintf(data, sizeof(data),
-                                "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
-                                "%02x%02x-%02x%02x%02x%02x%02x%02x",
-                                ((unsigned char *) ptr)[0],
-                                ((unsigned char *) ptr)[1],
-                                ((unsigned char *) ptr)[2],
-                                ((unsigned char *) ptr)[3],
-                                ((unsigned char *) ptr)[4],
-                                ((unsigned char *) ptr)[5],
-                                ((unsigned char *) ptr)[6],
-                                ((unsigned char *) ptr)[7],
-                                ((unsigned char *) ptr)[8],
-                                ((unsigned char *) ptr)[9],
-                                ((unsigned char *) ptr)[10],
-                                ((unsigned char *) ptr)[11],
-                                ((unsigned char *) ptr)[12],
-                                ((unsigned char *) ptr)[13],
-                                ((unsigned char *) ptr)[14],
-                                ((unsigned char *) ptr)[15]);
+                                "%08"PRIx32"-%04"PRIx16"-%04"PRIx16
+                                "-%02"PRIx8"%02"PRIx8
+                                "-%02"PRIx8"%02"PRIx8"%02"PRIx8
+                                "%02"PRIx8"%02"PRIx8"%02"PRIx8,
+                                u.d.d1, u.d.d2, u.d.d3, u.d.d4[0],
+                                u.d.d4[1], u.d.d4[2], u.d.d4[3],
+                                u.d.d4[4], u.d.d4[5], u.d.d4[6],
+                                u.d.d4[7]);
                        break;
                }
                assign(buf, bufpos, buflen, '\'', stmt);
@@ -3919,19 +3898,18 @@ ODBCStore(ODBCStmt *stmt,
                        snprintf(data, sizeof(data), "%.36s", sval);
                        break;
                case SQL_C_GUID:
-                       snprintf(data, sizeof(data), "%08lx-%04x-%04x-%02x%02x-"
-                                "%02x%02x%02x%02x%02x%02x",
-                                (unsigned long) ((SQLGUID *) ptr)->Data1,
-                                (unsigned int) ((SQLGUID *) ptr)->Data2,
-                                (unsigned int) ((SQLGUID *) ptr)->Data3,
-                                (unsigned int) ((SQLGUID *) ptr)->Data4[0],
-                                (unsigned int) ((SQLGUID *) ptr)->Data4[1],
-                                (unsigned int) ((SQLGUID *) ptr)->Data4[2],
-                                (unsigned int) ((SQLGUID *) ptr)->Data4[3],
-                                (unsigned int) ((SQLGUID *) ptr)->Data4[4],
-                                (unsigned int) ((SQLGUID *) ptr)->Data4[5],
-                                (unsigned int) ((SQLGUID *) ptr)->Data4[6],
-                                (unsigned int) ((SQLGUID *) ptr)->Data4[7]);
+                       u.g = *(SQLGUID *)ptr;
+                       snprintf(data, sizeof(data),
+                                "UUID '"
+                                "%08"PRIx32"-%04"PRIx16"-%04"PRIx16
+                                "-%02"PRIx8"%02"PRIx8
+                                "-%02"PRIx8"%02"PRIx8"%02"PRIx8
+                                "%02"PRIx8"%02"PRIx8"%02"PRIx8
+                                "'",
+                                u.d.d1, u.d.d2, u.d.d3, u.d.d4[0],
+                                u.d.d4[1], u.d.d4[2], u.d.d4[3],
+                                u.d.d4[4], u.d.d4[5], u.d.d4[6],
+                                u.d.d4[7]);
                        break;
                default:
                        /* Restricted data type attribute violation */
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
@@ -464,6 +464,11 @@ ODBCTranslateSQL(ODBCDbc *dbc, const SQL
        unsigned yr, mt, dy, hr, mn, sc;
        unsigned long fr = 0;
        int n, pr;
+       struct {
+               uint32_t d1;
+               uint16_t d2, d3;
+               uint8_t d4[8];
+       } u;
 
        nquery = dupODBCstring(query, length);
        if (nquery == NULL)
@@ -603,6 +608,35 @@ ODBCTranslateSQL(ODBCDbc *dbc, const SQL
                        free(nquery);
                        nquery = q;
                        q += n;
+               } else if (sscanf(p, "guid '%8"SCNx32"-%4"SCNx16"-%4"SCNx16
+                                 "-%2"SCNx8"%2"SCNx8"-%2"SCNx8"%2"SCNx8
+                                 "%2"SCNx8"%2"SCNx8"%2"SCNx8"%2"SCNx8"'%n",
+                                 &u.d1, &u.d2, &u.d3, &u.d4[0], &u.d4[1],
+                                 &u.d4[2], &u.d4[3], &u.d4[4], &u.d4[5],
+                                 &u.d4[6], &u.d4[7], &n) >= 11) {
+                       p += n;
+                       while (*p == ' ')
+                               p++;
+                       if (*p != '}')
+                               continue;
+                       p++;
+                       snprintf(buf, sizeof(buf),
+                                "UUID '%08"PRIx32"-%04"PRIx16"-%04"PRIx16
+                                "-%02"PRIx8"%02"PRIx8"-%02"PRIx8"%02"PRIx8
+                                "%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8"'",
+                                u.d1, u.d2, u.d3, u.d4[0], u.d4[1], u.d4[2],
+                                u.d4[3], u.d4[4], u.d4[5], u.d4[6], u.d4[7]);
+                       n = (int) (q - nquery);
+                       pr = (int) (p - q);
+                       q = malloc(length - pr + strlen(buf) + 1);
+                       if (q == NULL) {
+                               free(nquery);
+                               return NULL;
+                       }
+                       length = (size_t) sprintf(q, "%.*s%s%s", n, nquery, 
buf, p);
+                       free(nquery);
+                       nquery = q;
+                       q += n;
                } else if (strncasecmp(p, "escape ", 7) == 0) {
                        /* note that in ODBC the syntax is
                         * {escape '\'}
diff --git a/common/utils/muuid.c b/common/utils/muuid.c
--- a/common/utils/muuid.c
+++ b/common/utils/muuid.c
@@ -49,7 +49,11 @@ generateUUID(void)
        char out[37];
 #ifdef HAVE_OPENSSL
        unsigned char randbuf[16];
-       if (RAND_bytes(randbuf, 16) >= 0)
+       if (RAND_bytes(randbuf, 16) >= 0) {
+               /* make sure this is a variant 1 UUID (RFC 4122/DCE 1.1) */
+               randbuf[8] = (randbuf[8] & 0x3F) | 0x80;
+               /* make sure this is version 4 (random UUID) */
+               randbuf[6] = (randbuf[6] & 0x0F) | 0x40;
                snprintf(out, sizeof(out),
                         "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
                         "%02x%02x%02x%02x%02x%02x",
@@ -57,11 +61,15 @@ generateUUID(void)
                         randbuf[4], randbuf[5], randbuf[6], randbuf[7],
                         randbuf[8], randbuf[9], randbuf[10], randbuf[11],
                         randbuf[12], randbuf[13], randbuf[14], randbuf[15]);
-       else
+       } else
 #else
 #ifdef HAVE_COMMONCRYPTO
        unsigned char randbuf[16];
-       if (CCRandomGenerateBytes(randbuf, 16) == kCCSuccess)
+       if (CCRandomGenerateBytes(randbuf, 16) == kCCSuccess) {
+               /* make sure this is a variant 1 UUID (RFC 4122/DCE 1.1) */
+               randbuf[8] = (randbuf[8] & 0x3F) | 0x80;
+               /* make sure this is version 4 (random UUID) */
+               randbuf[6] = (randbuf[6] & 0x0F) | 0x40;
                snprintf(out, sizeof(out),
                         "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
                         "%02x%02x%02x%02x%02x%02x",
@@ -69,18 +77,20 @@ generateUUID(void)
                         randbuf[4], randbuf[5], randbuf[6], randbuf[7],
                         randbuf[8], randbuf[9], randbuf[10], randbuf[11],
                         randbuf[12], randbuf[13], randbuf[14], randbuf[15]);
-       else
+       } else
 #endif
 #endif
+       {
                /* generate something like this:
-                * cefa7a9c-1dd2-11b2-8350-880020adbeef
+                * cefa7a9c-1dd2-41b2-8350-880020adbeef
                 * ("%08x-%04x-%04x-%04x-%012x") */
                snprintf(out, sizeof(out),
-                        "%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
-                        rand() % 65536, rand() % 65536,
+                        "%04x%04x-%04x-4%03x-8%03x-%04x%04x%04x",
                         rand() % 65536, rand() % 65536,
-                        rand() % 65536, rand() % 65536,
+                        rand() % 65536, rand() % 4096,
+                        rand() % 4096, rand() % 65536,
                         rand() % 65536, rand() % 65536);
+       }
 #endif
        return strdup(out);
 }
diff --git a/monetdb5/modules/atoms/uuid.c b/monetdb5/modules/atoms/uuid.c
--- a/monetdb5/modules/atoms/uuid.c
+++ b/monetdb5/modules/atoms/uuid.c
@@ -46,7 +46,7 @@ typedef union {
 #ifdef HAVE_UUID
        uuid_t u;
 #else
-       unsigned char u[UUID_SIZE];
+       uint8_t u[UUID_SIZE];
 #endif
 } uuid;
 
@@ -84,10 +84,17 @@ UUIDprelude(void *ret)
 #ifdef HAVE_HGE
        BATatoms[u].storage = TYPE_hge;
 #endif
+#ifdef HAVE_UUID
+       uuid_clear(uuid_nil.u);
+#endif
        return MAL_SUCCEED;
 }
 
+#ifdef HAVE_UUID
+#define is_uuid_nil(x) uuid_is_null((x)->u)
+#else
 #define is_uuid_nil(x) (memcmp((x)->u, uuid_nil.u, UUID_SIZE) == 0)
+#endif
 
 /**
  * Returns the string representation of the given uuid value.
@@ -106,18 +113,21 @@ UUIDtoString(str *retval, size_t *len, c
        }
        if (is_uuid_nil(value)) {
                if (external) {
-                       snprintf(*retval, *len, "nil");
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to