Index: /trunk/archive/psdb/psDB.c
===================================================================
--- /trunk/archive/psdb/psDB.c	(revision 3156)
+++ /trunk/archive/psdb/psDB.c	(revision 3157)
@@ -8,6 +8,6 @@
  *  @author Joshua Hoblitt
  *
- *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-02-08 02:55:32 $
+ *  @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-02-08 05:03:09 $
  *
  *  Copyright 2005 Joshua Hoblitt, University of Hawaii
@@ -88,5 +88,7 @@
     psFree(dbh);
 
-    // these lookup tables should probably be moved into psDB
+    // these lookup tables should probably be moved into psDB to prevent them
+    // from being flushed in the case that a database handle is closed while
+    // one or more are still open
     psDBMySQLToSQLTableCleanup();
     psDBPSToSQLTableCleanup();
@@ -102,4 +104,5 @@
     // init query with a psMemBlock
     query = psStringCopy("CREATE DATABASE ");
+
     psStringAppend(&query, dbname);
 
@@ -114,5 +117,5 @@
 bool psDBChange(psDB *dbh, const char *dbname)
 {
-    if(mysql_select_db(dbh->mysql, dbname) != 0) {
+    if (mysql_select_db(dbh->mysql, dbname) != 0) {
         fprintf(stderr, "Failed to change database.  Error: %s\n", mysql_error(dbh->mysql));
            
@@ -130,4 +133,5 @@
     // init query with a psMemBlock
     query = psStringCopy("DROP DATABASE ");
+
     psStringAppend(&query, dbname);
     
@@ -146,8 +150,10 @@
 
     query = psDBGenerateCreateTableSQL(tableName, md);
-
-    fprintf(stderr, "complete query is: %s\n", query);
+    if (!query) {
+        return NULL;
+    }
 
     status = psDBRunQuery(dbh, query);
+
     psFree(query);
 
@@ -162,4 +168,5 @@
     // init query with a psMemBlock
     query = psStringCopy("DROP TABLE ");
+
     psStringAppend(&query, tableName);
 
@@ -173,19 +180,19 @@
 psArray *psDBSelectColumn(psDB *dbh, const char *tableName, const char *col, const psU64 limit)
 {
-    MYSQL_RES       *result;
+    MYSQL_RES       *result;            // complete db result set
     MYSQL_ROW       row;
     char            *query;
-    psU64           rowCount;
-    psU64           dataSize;
-    unsigned int    fieldCount;
-    psArray         *column = NULL;
-    psPtr           data;
+    psU64           rowCount;           // number of rows in db result set
+    psU64           dataSize;           // size of field
+    unsigned int    fieldCount;         // number of fields in db result set
+    psArray         *column = NULL;     // return array
+    psPtr           data;               // copy of result field
 
     query = psDBGenerateSelectColumnSQL(tableName, col, limit);
-
-    if (psDBRunQuery(dbh, query)) {
-        result = mysql_store_result(dbh->mysql);
-    } else {
-        // error
+    if (!query) {
+        return NULL;
+    }
+
+    if (!psDBRunQuery(dbh, query)) {
         psFree(query);
 
@@ -193,43 +200,43 @@
     }
 
-    if (result) {
-        rowCount = (psU64)mysql_num_rows(result);
-
-        // pre-allocate enough elements to hold the complete result set
-        // then reset n to 0 so elements are added from the beginning of
-        // the array
-        column = psArrayAlloc(rowCount);
-        column->n = 0;
-        //column = psArrayAlloc(0);
-
-        while ((row = mysql_fetch_row(result))) {
-            dataSize = (psU64)(mysql_fetch_lengths(result))[0];
-
-            fprintf(stderr, "data: %s, size %d\n", row[0], (int)dataSize);
-
-            //data = psAlloc(dataSize + 1);
-            //memcpy(data, row[0], dataSize);
-
-            if (row[0] == NULL) {
-                data = psStringCopy("");
-                fprintf(stderr, "data is null\n");
-                fprintf(stderr, "new data: %s %d\n", (char *)data, (int)strlen(data));
-            } else {
-                data = psStringNCopy(row[0], dataSize);
-            }
-
-            psArrayAdd(column, 0, data);
-        }
-    } else {
+    result = mysql_store_result(dbh->mysql);
+    if (!result) {
         // no result set
         fieldCount = mysql_field_count(dbh->mysql);
 
-        if (fieldCount == 0) {
-            // query result was empty
-
-        } else { 
+        // if field count is zero the query should have returned no data.  If
+        // it's non-zero then something bad has happened.
+        if (fieldCount != 0) {
             // error, should have gotten data
             fprintf(stderr, "Query returned no data.  Error: %s\n", mysql_error(dbh->mysql));
-        }
+
+            psFree(query);
+
+            return NULL;
+        }
+    }
+
+    rowCount = (psU64)mysql_num_rows(result);
+
+    // pre-allocate enough elements to hold the complete result set
+    // then reset n to 0 so elements are added from the beginning of
+    // the array
+    column = psArrayAlloc(rowCount);
+    column->n = 0;
+
+    while ((row = mysql_fetch_row(result))) {
+        // get the first element of lengths array that is part of the
+        // result set
+        dataSize = (psU64)*mysql_fetch_lengths(result);
+
+        // represent NULL as an empty string
+        if (row[0] == NULL) {
+            data = psStringCopy("");
+        } else {
+            data = psStringNCopy(row[0], dataSize);
+        }
+
+        // add field to return array
+        psArrayAdd(column, 0, data);
     }
 
@@ -240,71 +247,74 @@
 }
 
-// a = assign too, b = source psArray, c = conversion function, d = type to cast to, e = psElemType
-#define STRINGARRAYTOPTYPE(a, b, c, d, e)   for (i = 0; i < b->n; i++) { \
-                                                if (strlen(b->data[i])) { \
-                                                    a = (d)atoi(b->data[i]); \
-                                                } else { \
-                                                    myNaN = psDBGetPTypeNaN(e); \
-                                                    a = *(d *)myNaN; \
-                                                    psFree(myNaN); \
-                                                } \
-                                            }
+// dest = assign too, source = source string psArray, conv = conversion function,
+// type = type to cast to, pType = psElemType
+#define STRINGARRAYTOPTYPE(dest, source, conv, type, pType) \
+{ \
+    psPtr           myNaN; \
+    int             i; \
+\
+    for (i = 0; i < source->n; i++) { \
+        if (strlen(source->data[i])) { \
+            dest[i] = (type)conv(source->data[i]); \
+        } else { \
+            myNaN = psDBGetPTypeNaN(pType); \
+            dest[i] = *(type *)myNaN; \
+            psFree(myNaN); \
+        } \
+    } \
+}
 
 psVector *psDBSelectColumnNum(psDB *dbh, const char *tableName, const char *col, psElemType pType, const psU64 limit)
 {
-    psArray         *stringColumn;
-    psVector        *column;
-    int             i;
-    psPtr           myNaN;
+    psArray         *stringColumn;      // source psArray
+    psVector        *column;            // dest psVector
 
     stringColumn = psDBSelectColumn(dbh, tableName, col, limit);
-
-    if (stringColumn) {
-        column = psVectorAlloc(stringColumn->n, pType);
-    } else {
-        // psDBSelectColumn() returned NULL
+    if (!stringColumn) {
         return NULL;
     }
 
-    // long long is 64b and long is 32b on x86
+    column = psVectorAlloc(stringColumn->n, pType);
+
+    // conversion functions are a portability issue
     switch (pType) {
         case PS_TYPE_S8:
-            STRINGARRAYTOPTYPE(column->data.S8[i], stringColumn, atoi, psS8, PS_TYPE_S8);
+            STRINGARRAYTOPTYPE(column->data.S8, stringColumn, atoi, psS8, PS_TYPE_S8);
             break;
         case PS_TYPE_S16:
-            STRINGARRAYTOPTYPE(column->data.S16[i], stringColumn, atoi, psS16, PS_TYPE_S16);
+            STRINGARRAYTOPTYPE(column->data.S16, stringColumn, atoi, psS16, PS_TYPE_S16);
             break;
         case PS_TYPE_S32:
-            STRINGARRAYTOPTYPE(column->data.S32[i], stringColumn, atoi, psS32, PS_TYPE_S32);
+            STRINGARRAYTOPTYPE(column->data.S32, stringColumn, atoi, psS32, PS_TYPE_S32);
             break;
         case PS_TYPE_S64:
-            STRINGARRAYTOPTYPE(column->data.S64[i], stringColumn, atoll, psS64, PS_TYPE_S64);
+            STRINGARRAYTOPTYPE(column->data.S64, stringColumn, atoll, psS64, PS_TYPE_S64);
             break;
         case PS_TYPE_U8:
             // missing from psVector in SDRS
-            STRINGARRAYTOPTYPE(column->data.U8[i], stringColumn, atoi, psU8, PS_TYPE_U8);
+            STRINGARRAYTOPTYPE(column->data.U8, stringColumn, atoi, psU8, PS_TYPE_U8);
             break;
         case PS_TYPE_U16:
-            STRINGARRAYTOPTYPE(column->data.U16[i], stringColumn, atoi, psU16, PS_TYPE_U16);
+            STRINGARRAYTOPTYPE(column->data.U16, stringColumn, atoi, psU16, PS_TYPE_U16);
             break;
         case PS_TYPE_U32:
-            STRINGARRAYTOPTYPE(column->data.U32[i], stringColumn, atoi, psU32, PS_TYPE_U32);
+            STRINGARRAYTOPTYPE(column->data.U32, stringColumn, atoi, psU32, PS_TYPE_U32);
             break;
         case PS_TYPE_U64:
-            STRINGARRAYTOPTYPE(column->data.U64[i], stringColumn, atoll, psU64, PS_TYPE_U64);
+            STRINGARRAYTOPTYPE(column->data.U64, stringColumn, atoll, psU64, PS_TYPE_U64);
             break;
         case PS_TYPE_F32:
-            STRINGARRAYTOPTYPE(column->data.F32[i], stringColumn, atof, psF32, PS_TYPE_F32);
+            STRINGARRAYTOPTYPE(column->data.F32, stringColumn, atof, psF32, PS_TYPE_F32);
             break;
         case PS_TYPE_F64:
-            STRINGARRAYTOPTYPE(column->data.F64[i], stringColumn, atof, psF64, PS_TYPE_F64);
+            STRINGARRAYTOPTYPE(column->data.F64, stringColumn, atof, psF64, PS_TYPE_F64);
             break;
         case PS_TYPE_C32:
             // this is a bogus SQL type
-            STRINGARRAYTOPTYPE(column->data.C32[i], stringColumn, atof, psC32, PS_TYPE_C32);
+            STRINGARRAYTOPTYPE(column->data.C32, stringColumn, atof, psC32, PS_TYPE_C32);
             break;
         case PS_TYPE_C64:
             // this is a bogus SQL type
-            STRINGARRAYTOPTYPE(column->data.C64[i], stringColumn, atof, psC64, PS_TYPE_C64);
+            STRINGARRAYTOPTYPE(column->data.C64, stringColumn, atof, psC64, PS_TYPE_C64);
             break;
         case PS_TYPE_BOOL:
@@ -323,31 +333,30 @@
 psArray *psDBSelectRows(psDB *dbh, const char *tableName, psMetadata *where)
 {
-    MYSQL_RES       *result;
+    MYSQL_RES       *result;            // complete db result set
     MYSQL_ROW       row;
-    MYSQL_FIELD     *field;
+    MYSQL_FIELD     *field;             // field type info
     char            *query;
-    psU64           rowCount;
-    psU64           fieldCount;
-    psU64           *fieldLength;
-    psArray         *resultSet;
-    int             i; // field index
-    psMetadataItem  *item;
-    psMetadata      *md;
+    psU64           rowCount;           // number of rows in db result set
+    psU64           fieldCount;         // number of fields in db result set
+    psU64           *fieldLength;       // field sizes
+    psArray         *resultSet;         // return array
+    int             i;                  // field index
+    psMetadataItem  *item;              // field of a row
+    psMetadata      *md;                // a row
     psHash          *mysqlToSQLTable;
     psHash          *sqlToPSTable;
     char            *key;
     char            *value;
-    psU32           pType;
-    psU32           type;
+    psU32           pType;              // psElemType of a field
+    psU32           type;               // psMetadataType of a a field
     char            *sqlType;
-    psPtr           data;
+    psPtr           data;               // copy of result field
 
     query = psDBGenerateSelectRowsSQL(tableName, where);
-
-    fprintf(stderr, "complete query is: %s\n", query);
-
-    if (psDBRunQuery(dbh, query)) {
-        result = mysql_store_result(dbh->mysql);
-    } else {
+    if (!query) {
+        return NULL;
+    }
+
+    if (!psDBRunQuery(dbh, query)) {
         // error
         psFree(query);
@@ -356,88 +365,92 @@
     }
 
-    if (result) {
-        rowCount = (psU64)mysql_num_rows(result);
-
-        // pre-allocate enough elements to hold the complete result set
-        // then reset n to 0 so elements are added from the beginning of
-        // the array
-        resultSet = psArrayAlloc(rowCount);
-        resultSet->n = 0;
-
-        field = mysql_fetch_fields(result);
-        fieldCount = mysql_num_fields(result);
-
-        mysqlToSQLTable = psDBGetMySQLToSQLTable();
-        sqlToPSTable = psDBGetSQLToPSTable();
-
-        while ((row = mysql_fetch_row(result))) {
-            md = psMetadataAlloc();
-            fieldLength = (psU64 *)(mysql_fetch_lengths(result));
-
-            for (i = 0; i < fieldCount; i++) {
-                // lookup MySQL column type
-                // MySQL column types can not be directly translated to PS types
-                // as the the mysql types do not tell you if the value is
-                // signed or unsigned
-                key = psDBIntToString((psU64)field[i].type); 
-                value = psHashLookup(mysqlToSQLTable, key);
-                sqlType = psStringCopy(value);
-                psFree(key);
-
-                if (field->flags & UNSIGNED_FLAG) {
-                    psStringPrepend(&sqlType, "UNSIGNED ");
-                }
-
-                // convert MySQL type to PS type
-                value = psHashLookup(sqlToPSTable, sqlType);
-                pType = (psU32)atol(value);
-                psFree(sqlType);
-
-                fprintf(stderr, "sqlType is: %s\n", sqlType);
-
-                // convert NULLs appropriately
-                if (pType == PS_TYPE_PTR) {
-                    type = PS_META_STR;
-                    data = fieldLength[i] ? psStringNCopy(row[i], fieldLength[i])
-                                          : psDBGetPTypeNaN(pType);
-                } else {
-                    type = PS_META_PRIMITIVE;
-                    if (fieldLength[i]) {
-                        data = psAlloc(fieldLength[i]);
-                        memcpy(data, row[i], fieldLength[i]);
-                    } else {
-                        data = psDBGetPTypeNaN(pType);
-                    }
-                }
-
-                // add field to row
-                item = psMetadataItemAlloc(field[i].name, pType, type, NULL, data);
-                psMetadataAddItem(md, item, i);
-
-                psFree(data);
-                psFree(item);
-            }
-
-            // add row to result set
-            psArrayAdd(resultSet, 0, md);
-        }
-    } else {
+    result = mysql_store_result(dbh->mysql);
+    if (!result) {
         // no result set
-        resultSet = NULL;
-
         fieldCount = mysql_field_count(dbh->mysql);
 
-        if (fieldCount == 0) {
-            // query result was empty
-
-        } else { 
+        // if field count is zero the query should have returned no data.  If
+        // it's non-zero then something bad has happened.
+        if (fieldCount != 0) {
             // error, should have gotten data
             fprintf(stderr, "Query returned no data.  Error: %s\n", mysql_error(dbh->mysql));
-        }
-    }
-
-    mysql_free_result(result);
+
+            psFree(query);
+
+            return NULL;
+        }
+    }
+
+    rowCount = (psU64)mysql_num_rows(result);
+
+    // pre-allocate enough elements to hold the complete result set
+    // then reset n to 0 so elements are added from the beginning of
+    // the array
+    resultSet = psArrayAlloc(rowCount);
+    resultSet->n = 0;
+
+    field = mysql_fetch_fields(result);
+    fieldCount = mysql_num_fields(result);
+
+    mysqlToSQLTable = psDBGetMySQLToSQLTable();
+    sqlToPSTable = psDBGetSQLToPSTable();
+
+    while ((row = mysql_fetch_row(result))) {
+        // allocate new psMetadata to represent a row
+        md = psMetadataAlloc();
+
+        fieldLength = (psU64 *)(mysql_fetch_lengths(result));
+
+        for (i = 0; i < fieldCount; i++) {
+            // lookup MySQL column type
+            key = psDBIntToString((psU64)field[i].type); 
+            value = psHashLookup(mysqlToSQLTable, key);
+            sqlType = psStringCopy(value);
+            psFree(key);
+
+            // MySQL column types can not be directly translated to PS
+            // types as the the mysql types do not tell you if the value is
+            // signed or unsigned.  The result is this ugly conversion from
+            // mysql -> ascii -> ptype
+            if (field->flags & UNSIGNED_FLAG) {
+                psStringPrepend(&sqlType, "UNSIGNED ");
+            }
+
+            // convert MySQL type to PS type
+            value = psHashLookup(sqlToPSTable, sqlType);
+            pType = (psU32)atol(value);
+            psFree(sqlType);
+
+            // copy field data and convert NULLs to the appropriate NaN value
+            if (pType == PS_TYPE_PTR) {
+                type = PS_META_STR;
+                data = fieldLength[i] ? psStringNCopy(row[i], fieldLength[i])
+                                      : psDBGetPTypeNaN(pType);
+            } else {
+                type = PS_META_PRIMITIVE;
+                if (fieldLength[i]) {
+                    data = psAlloc(fieldLength[i]);
+                    memcpy(data, row[i], fieldLength[i]);
+                } else {
+                    data = psDBGetPTypeNaN(pType);
+                }
+            }
+
+            // add new field to row
+            item = psMetadataItemAlloc(field[i].name, pType, type, NULL, data);
+            psMetadataAddItem(md, item, i);
+            psFree(item);
+
+            psFree(data);
+        }
+
+        // add row to result set
+        psArrayAdd(resultSet, 0, md);
+    }
+
     psFree(mysqlToSQLTable);
     psFree(sqlToPSTable);
+
+    mysql_free_result(result);
     psFree(query);
 
@@ -448,6 +461,6 @@
 {
     char            *query;
-    MYSQL_STMT      *stmt;
-    MYSQL_BIND      *bind;
+    MYSQL_STMT      *stmt;              // prepared db statement
+    MYSQL_BIND      *bind;              // field values to insert
     psU32           paramCount;
     psHash          *mysqlFieldType;
@@ -460,6 +473,7 @@
 
     query = psDBGenerateInsertRowSQL(tableName, row);
-
-    fprintf(stderr, "complete query is: %s\n", query);
+    if (!query) {
+        return NULL;
+    }
 
     stmt = mysql_stmt_init(dbh->mysql);
@@ -585,4 +599,5 @@
     }
 
+    // end of field names
     psStringAppend(&query, ") VALUES (");
 
@@ -593,6 +608,6 @@
         psStringAppend(&query, "?");
 
+        // + ", " between every place holder
         if (!cursor->offEnd) {
-            // + , + _
             psStringAppend(&query, ", ");
         }
@@ -615,5 +630,4 @@
     query = psStringCopy("WHERE ");
 
-    // get Metadata iterator
     cursor = psListIteratorAlloc(where->list, 0);
 
@@ -641,5 +655,4 @@
         // + " and " after every column declaration except the last one
         if (!cursor->offEnd) {
-            // + and
             psStringAppend(&query, " AND ");
         }
@@ -668,8 +681,6 @@
     psStringAppend(&query, " (");
 
-    // get pType lookup table
     colType = psDBGetPSToSQLTable();
 
-    // get Metadata iterator
     cursor = psListIteratorAlloc(table->list, 0);
 
@@ -688,5 +699,5 @@
             // + column type
             psStringAppend(&query, value);
-        } else if (item->type == PS_META_STR) {
+        } else if ((item->type == PS_META_STR) && (item->pType == PS_TYPE_PTR)) {
             // + varchar( + length + )
             psStringAppend(&query, "varchar(");
@@ -694,10 +705,10 @@
             psStringAppend(&query, ")");
         } else {
-            // error
+            // error, invalid type
+            return NULL;
         }
 
         // add a , after every column declaration except the last one
         if (!cursor->offEnd) {
-            // + ,
             psStringAppend(&query, ", ");
         }
@@ -723,5 +734,5 @@
     psFree(cursor);
 
-    // + ) + _ + ENGINE=innodb;
+    // end column types + table type
     psStringAppend(&query, ") ENGINE=innodb");
 
@@ -773,6 +784,7 @@
 }
 
-#define MYNAN(a, b) myNaN = psAlloc(sizeof(a));\
-                    *(a *)myNaN = b;
+#define MYNAN(dest, type, nan) \
+    dest = psAlloc(sizeof(type)); \
+    *(type *)dest = nan;
 
 static psPtr psDBGetPTypeNaN(psElemType pType)
@@ -782,41 +794,40 @@
     switch (pType) {
         case PS_TYPE_S8:
-            myNaN = psAlloc(sizeof(psS8));
-            *(psS8 *)myNaN = PS_MAX_S8;
+            MYNAN(myNaN, psS8, PS_MAX_S8);
             break;
         case PS_TYPE_S16:
-            MYNAN(psS16, PS_MAX_S16)
+            MYNAN(myNaN, psS16, PS_MAX_S16);
             break;
         case PS_TYPE_S32:
-            MYNAN(psS32, PS_MAX_S32)
+            MYNAN(myNaN, psS32, PS_MAX_S32);
             break;
         case PS_TYPE_S64:
-            MYNAN(psS64, PS_MAX_S64)
+            MYNAN(myNaN, psS64, PS_MAX_S64);
             break;
         case PS_TYPE_U8:
-            MYNAN(psU8, PS_MAX_U8)
+            MYNAN(myNaN, psU8, PS_MAX_U8);
             break;
         case PS_TYPE_U16:
-            MYNAN(psU16, PS_MAX_U16)
+            MYNAN(myNaN, psU16, PS_MAX_U16);
             break;
         case PS_TYPE_U32:
-            MYNAN(psU32, PS_MAX_U32)
+            MYNAN(myNaN, psU32, PS_MAX_U32);
             break;
         case PS_TYPE_U64:
-            MYNAN(psU64, PS_MAX_U64)
+            MYNAN(myNaN, psU64, PS_MAX_U64);
             break;
         case PS_TYPE_F32:
-            MYNAN(psF32, NAN)
+            MYNAN(myNaN, psF32, NAN);
             break;
         case PS_TYPE_F64:
-            MYNAN(psF64, NAN)
+            MYNAN(myNaN, psF64, NAN);
             break;
         case PS_TYPE_C32:
             // this is a bogus SQL type
-            MYNAN(psC32, NAN)
+            MYNAN(myNaN, psC32, NAN);
             break;
         case PS_TYPE_C64:
             // this is a bogus SQL type
-            MYNAN(psC64, NAN)
+            MYNAN(myNaN, psC64, NAN);
             break;
         case PS_TYPE_BOOL:
@@ -824,5 +835,5 @@
             break;
         case PS_TYPE_PTR:
-            MYNAN(char, '\0')
+            MYNAN(myNaN, char, '\0');
             break;
     }
@@ -831,6 +842,5 @@
 }
 
-// a = type , b = data, c = NaN value
-#define ISPTYPENAN(a, b, c) *(a *)b == c;
+#define ISTYPENAN(type, data, nan) *(type *)data == nan
 
 static bool psDBIsPTypeNaN(psElemType pType, psPtr data)
@@ -840,40 +850,40 @@
     switch (pType) {
         case PS_TYPE_S8:
-            isNaN = ISPTYPENAN(psS8, data, PS_MAX_S8)
+            isNaN = ISTYPENAN(psS8, data, PS_MAX_S8);
             break;
         case PS_TYPE_S16:
-            isNaN = ISPTYPENAN(psS16, data, PS_MAX_S16)
+            isNaN = ISTYPENAN(psS16, data, PS_MAX_S16);
             break;
         case PS_TYPE_S32:
-            isNaN = ISPTYPENAN(psS32, data, PS_MAX_S32)
+            isNaN = ISTYPENAN(psS32, data, PS_MAX_S32);
             break;
         case PS_TYPE_S64:
-            isNaN = ISPTYPENAN(psS64, data, PS_MAX_S64)
+            isNaN = ISTYPENAN(psS64, data, PS_MAX_S64);
             break;
         case PS_TYPE_U8:
-            isNaN = ISPTYPENAN(psU8, data, PS_MAX_U8)
+            isNaN = ISTYPENAN(psU8, data, PS_MAX_U8);
             break;
         case PS_TYPE_U16:
-            isNaN = ISPTYPENAN(psU16, data, PS_MAX_U16)
+            isNaN = ISTYPENAN(psU16, data, PS_MAX_U16);
             break;
         case PS_TYPE_U32:
-            isNaN = ISPTYPENAN(psU32, data, PS_MAX_U32)
+            isNaN = ISTYPENAN(psU32, data, PS_MAX_U32);
             break;
         case PS_TYPE_U64:
-            isNaN = ISPTYPENAN(psU64, data, PS_MAX_U64)
+            isNaN = ISTYPENAN(psU64, data, PS_MAX_U64);
             break;
         case PS_TYPE_F32:
-            isNaN = ISPTYPENAN(psF32, data, NAN)
+            isNaN = ISTYPENAN(psF32, data, NAN);
             break;
         case PS_TYPE_F64:
-            isNaN = ISPTYPENAN(psF64, data, NAN)
+            isNaN = ISTYPENAN(psF64, data, NAN);
             break;
         case PS_TYPE_C32:
             // this is a bogus SQL type
-            isNaN = ISPTYPENAN(psC32, data, NAN)
+            isNaN = ISTYPENAN(psC32, data, NAN);
             break;
         case PS_TYPE_C64:
             // this is a bogus SQL type
-            isNaN = ISPTYPENAN(psC64, data, NAN)
+            isNaN = ISTYPENAN(psC64, data, NAN);
             break;
         case PS_TYPE_BOOL:
@@ -881,5 +891,5 @@
             break;
         case PS_TYPE_PTR:
-            isNaN = ISPTYPENAN(char, data, '\0')
+            isNaN = ISTYPENAN(char, data, '\0');
             break;
     }
@@ -888,7 +898,8 @@
 }
 
-#define PTYPETOSTRING(a, b) length = (size_t)log10((double)*(a *)data) + 1;\
-                            string = psAlloc(length);\
-                            snprintf(string, length, b, *(a *)data);
+#define TYPETOSTRING(type, format, data) \
+    (size_t)log10((double)*(type *)data) + 1; \
+    string = psAlloc(length); \
+    snprintf(string, length, format, *(type *)data);
 
 static char *psDBPTypeAsString(psPtr data, psElemType pType)
@@ -897,34 +908,35 @@
     char            *string;
 
+    // formats are a portability issue
     switch (pType) {
         case PS_TYPE_S8:
-            PTYPETOSTRING(psS8, "%i");
+            length = TYPETOSTRING(psS8, "%i", data);
             break;
         case PS_TYPE_S16:
-            PTYPETOSTRING(psS16, "%i");
+            length = TYPETOSTRING(psS16, "%i", data);
             break;
         case PS_TYPE_S32:
-            PTYPETOSTRING(psS32, "%i");
+            length = TYPETOSTRING(psS32, "%i", data);
             break;
         case PS_TYPE_S64:
-            PTYPETOSTRING(psS64, "%li");
+            length = TYPETOSTRING(psS64, "%li", data);
             break;
         case PS_TYPE_U8:
-            PTYPETOSTRING(psU8, "%u");
+            length = TYPETOSTRING(psU8, "%u", data);
             break;
         case PS_TYPE_U16:
-            PTYPETOSTRING(psU16, "%u");
+            length = TYPETOSTRING(psU16, "%u", data);
             break;
         case PS_TYPE_U32:
-            PTYPETOSTRING(psU32, "%u");
+            length = TYPETOSTRING(psU32, "%u", data);
             break;
         case PS_TYPE_U64:
-            PTYPETOSTRING(psU64, "%lu");
+            length = TYPETOSTRING(psU64, "%lu", data);
             break;
         case PS_TYPE_F32:
-            PTYPETOSTRING(psF32, "%f");
+            length = TYPETOSTRING(psF32, "%f", data);
             break;
         case PS_TYPE_F64:
-            PTYPETOSTRING(psF32, "%f");
+            length = TYPETOSTRING(psF32, "%f", data);
             break;
         case PS_TYPE_C32:
@@ -935,5 +947,5 @@
             break;
         case PS_TYPE_BOOL:
-            PTYPETOSTRING(bool, "%u");
+            length = TYPETOSTRING(bool, "%u", data);
             break;
         case PS_TYPE_PTR:
@@ -1000,4 +1012,5 @@
         lookupTable = psHashAlloc(14);
 
+        // no support for CHAR, TEXT or GLOB
         psDBAddToLookupTable(lookupTable, PS_TYPE_S8,  "TINYINT");
         psDBAddToLookupTable(lookupTable, PS_TYPE_S16, "SMALLINT");
@@ -1013,5 +1026,4 @@
         psDBAddToLookupTable(lookupTable, PS_TYPE_C64, "PS_TYPE_C64 is not supported");
         psDBAddToLookupTable(lookupTable, PS_TYPE_BOOL,"BOOLEAN");
-        // no support for CHAR, TEXT or GLOB
         psDBAddToLookupTable(lookupTable, PS_TYPE_PTR, "VARCHAR");
     }
