IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Dec 14, 2006, 1:03:40 PM (19 years ago)
Author:
magnier
Message:

enabled relative comparisons for double/float; cleaned up error messages

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/db/psDB.c

    r10708 r10737  
    1212 *  @author Joshua Hoblitt
    1313 *
    14  *  @version $Revision: 1.122 $ $Name: not supported by cvs2svn $
    15  *  @date $Date: 2006-12-14 05:13:58 $
     14 *  @version $Revision: 1.123 $ $Name: not supported by cvs2svn $
     15 *  @date $Date: 2006-12-14 23:03:40 $
    1616 *
    1717 *  Copyright (C) 2005-2006  Joshua Hoblitt, University of Hawaii
     
    18641864}
    18651865
     1866typedef enum {
     1867    PS_DB_OP_EQ,
     1868    PS_DB_OP_LT,
     1869    PS_DB_OP_GT,
     1870    PS_DB_OP_LE,
     1871    PS_DB_OP_GE,
     1872} psDBOpValue;
     1873
     1874# define PS_DB_FLT_PAD (FLT_EPSILON * 10)
     1875# define PS_DB_DBL_PAD (DBL_EPSILON * 10)
     1876
    18661877static psString psDBGenerateConditionalSQL(const psMetadataItem *item, const char *tableName)
    18671878{
     
    18901901
    18911902    // default to exact match ('=')
    1892     char *op = "=";
     1903    char *opStr = "=";
     1904    psDBOpValue op = PS_DB_OP_EQ;
    18931905    if (item->comment) {
    18941906        // arbitrary semantic, precedence is: >=, <=, >, <, = (default)
    18951907        if (strstr(item->comment, ">=")) {
    1896             op = ">=";
     1908            opStr = ">=";
     1909            op = PS_DB_OP_GE;
    18971910        } else if (strstr(item->comment, "<=")) {
    1898             op = "<=";
     1911            opStr = "<=";
     1912            op = PS_DB_OP_LE;
    18991913        } else if (strstr(item->comment, ">")) {
    1900             op = ">";
     1914            opStr = ">";
     1915            op = PS_DB_OP_GT;
    19011916        } else if (strstr(item->comment, "<")) {
    1902             op = "<";
    1903         }
    1904     }
     1917            opStr = "<";
     1918            op = PS_DB_OP_LT;
     1919        }
     1920    }
     1921
     1922    // XXX why are >, < searches not supported here????
     1923    // fix this immediately!!
     1924    // for datetime comparisons, we need to use single-quotes around the string value:
     1925    // where dateobs < '2002-09-06' and dateobs > '2002-09-05,15:40:22'
    19051926
    19061927    switch (item->type) {
    19071928    case PS_DATA_S32:
    1908         psStringAppend(&query, "%s %s %d", itemName, op, (int)(item->data.S32));
     1929        // the raw opStr is good enough in the query
     1930        psStringAppend(&query, "%s %s %d", itemName, opStr, (int)(item->data.S32));
    19091931        break;
    19101932    case PS_DATA_F32:
    1911         psStringAppend(&query, "(ABS(%s - %.8f) < %.8f)", itemName, (float)(item->data.F32), FLT_EPSILON * 10);
     1933        // need to handle floating-point round-off issues (use a padding of 10*FLT_EPSILON)
     1934        switch (op) {
     1935        case PS_DB_OP_EQ:
     1936            psStringAppend(&query, "(ABS(%s - %.8f) < %.8f)", itemName, (float)(item->data.F32), PS_DB_FLT_PAD);
     1937            break;
     1938        case PS_DB_OP_LE:
     1939        case PS_DB_OP_LT:
     1940            // A < B becomes A < B + epsilon
     1941            psStringAppend(&query, "(%s < %.8f + %.8f)", itemName, (float)(item->data.F32), PS_DB_FLT_PAD);
     1942            break;
     1943        case PS_DB_OP_GE:
     1944        case PS_DB_OP_GT:
     1945            // A > B becomes A > B - epsilon
     1946            psStringAppend(&query, "(%s > %.8f - %.8f)", itemName, (float)(item->data.F32), PS_DB_FLT_PAD);
     1947            break;
     1948        }
    19121949        break;
    19131950    case PS_DATA_F64:
    1914         psStringAppend(&query, "(ABS(%s - %.17f) < %.17f)", itemName, (double)(item->data.F64), DBL_EPSILON * 10);
     1951        // need to handle floating-point round-off issues (use a padding of 10*FLT_EPSILON)
     1952        switch (op) {
     1953        case PS_DB_OP_EQ:
     1954            psStringAppend(&query, "(ABS(%s - %.17f) < %.17f)", itemName, (float)(item->data.F64), PS_DB_DBL_PAD);
     1955            break;
     1956        case PS_DB_OP_LE:
     1957        case PS_DB_OP_LT:
     1958            // A < B becomes A < B + epsilon
     1959            psStringAppend(&query, "(%s < %.17f + %.17f)", itemName, (float)(item->data.F64), PS_DB_DBL_PAD);
     1960            break;
     1961        case PS_DB_OP_GE:
     1962        case PS_DB_OP_GT:
     1963            // A > B becomes A > B - epsilon
     1964            psStringAppend(&query, "(%s > %.17f - %.17f)", itemName, (float)(item->data.F64), PS_DB_DBL_PAD);
     1965            break;
     1966        }
    19151967        break;
    19161968    case PS_DATA_BOOL:
    1917         psStringAppend(&query, "%s = %d", itemName, (int)(item->data.B));
     1969        switch (op) {
     1970        case PS_DB_OP_EQ:
     1971            psStringAppend(&query, "%s = %d", itemName, (int)(item->data.B));
     1972            break;
     1973        default:
     1974            psError(PS_ERR_UNKNOWN, true, "NULL psBool can't be compared with any operator other than '=='");
     1975            psFree(itemName);
     1976            return NULL;
     1977        }
    19181978        break;
    19191979    case PS_DATA_STRING:
     1980        // XXX EAM : probably need to add some regex-like operations here
    19201981        // + column name + _ + like + _ + ' + value + '
    19211982        // check for NULL and empty ("") strings
     
    19371998            if (item->data.V) {
    19381999                psString timeStr = psTimeToISO(item->data.V);
    1939                 psStringAppend(&query, "%s %s '%s'", itemName, op, timeStr);
     2000                psStringAppend(&query, "%s %s '%s'", itemName, opStr, timeStr);
    19402001                psFree(timeStr);
    1941             } else if (strstr(op, "=")) {
     2002            } else if (strstr(opStr, "=")) {
    19422003                psStringAppend(&query, "%s IS NULL", itemName);
    19432004            } else {
    1944                 psError(PS_ERR_UNKNOWN, true, "NULL psTime can't be compared with any operator other than '=='");
     2005                psError(PS_ERR_UNKNOWN, true, "psTime comparison value is NULL: A NULL psTime value can't be compared with any operator other than '=='");
    19452006                psFree(itemName);
    19462007                return NULL;
Note: See TracChangeset for help on using the changeset viewer.