[prev in list] [next in list] [prev in thread] [next in thread] 

List:       fdo-commits
Subject:    [fdo-commits] r4862 - in trunk/Providers/SQLite/Src: Provider
From:       svn_fdo () osgeo ! org
Date:       2009-07-27 15:52:23
Message-ID: 20090727155223.98047E000B8 () lists ! osgeo ! org
[Download RAW message or body]

Author: romicadascalescu
Date: 2009-07-27 11:52:22 -0400 (Mon, 27 Jul 2009)
New Revision: 4862

Modified:
   trunk/Providers/SQLite/Src/Provider/SltConversionUtils.cpp
   trunk/Providers/SQLite/Src/Provider/SltConversionUtils.h
   trunk/Providers/SQLite/Src/Provider/SltExprExtensions.cpp
   trunk/Providers/SQLite/Src/Provider/SltExprExtensions.h
   trunk/Providers/SQLite/Src/Provider/SltProvider.cpp
   trunk/Providers/SQLite/Src/Provider/SltQueryTranslator.cpp
   trunk/Providers/SQLite/Src/Provider/SltQueryTranslator.h
   trunk/Providers/SQLite/Src/Provider/SltReader.cpp
   trunk/Providers/SQLite/Src/Provider/StringUtil.h
   trunk/Providers/SQLite/Src/Provider/stdafx.h
   trunk/Providers/SQLite/Src/UnitTest/FdoExpressionFunctionTest.cpp
   trunk/Providers/SQLite/Src/UnitTest/FdoExpressionFunctionTest.h
Log:
#504 SQLite improvements: implement ToDate & ToString(date, format) functions
 - Implement ToDate using a format.
 - Implement ToString(date, [format])
 - Added support in ToString for day of the week
 - Fixed calculations based on other calculations failed to execute the query
 - Improve the performance of query translator by using direct conversion 
functions.
 - fixed cases like: "date > string date" in provider query translator




Modified: trunk/Providers/SQLite/Src/Provider/SltConversionUtils.cpp
===================================================================
--- trunk/Providers/SQLite/Src/Provider/SltConversionUtils.cpp	2009-07-26 00:53:36 \
                UTC (rev 4861)
+++ trunk/Providers/SQLite/Src/Provider/SltConversionUtils.cpp	2009-07-27 15:52:22 \
UTC (rev 4862) @@ -19,6 +19,7 @@
 #include "stdafx.h"
 #include "SpatialIndex.h"
 #include "SltConversionUtils.h"
+#include <locale.h>
 
 std::string W2A_SLOW(const wchar_t* input)
 {
@@ -195,10 +196,12 @@
     else if (dt->IsTime())
     {
         _snprintf(s, nBytes, "%02d:%02d:%0.3f", dt->hour, dt->minute, dt->seconds);
+        EnsureNoIsLocalIndep(s);
     }
     else
     {
         _snprintf(s, nBytes, "%04d-%02d-%02dT%02d:%02d:%0.3f", dt->year, dt->month, \
dt->day, dt->hour, dt->minute, dt->seconds); +        EnsureNoIsLocalIndep(s);
     }
 }
 
@@ -289,9 +292,9 @@
                 {
                     FdoDateTimeValue* v = (FdoDateTimeValue*)dv;
                     FdoDateTime dtm = v->GetDateTime();
-                    char s[64];
+                    char s[31];
 
-                    DateToString(&dtm, s, 64);
+                    DateToString(&dtm, s, 31);
                     
                     rc = sqlite3_bind_text(stmt, i, s, -1, SQLITE_TRANSIENT);
                 }
@@ -365,4 +368,97 @@
     }
 }
 
+SLT_API TokenDateFormatType StringToDateFormat(const char* specifier)
+{
+    if (strncmp(specifier, "YY", 2) == 0)
+        return TokenDateFormatType_Year2;
 
+    if (strncmp(specifier, "YYYY", 4) == 0)
+        return TokenDateFormatType_Year4;
+
+    if (strncmp(specifier, "MONTH", 5) == 0)
+        return TokenDateFormatType_Month_FullName_All_Upper;
+
+    if (strncmp(specifier, "Month", 5) == 0)
+        return TokenDateFormatType_Month_FullName_First_Upper;
+
+    if (strncmp(specifier, "month", 5) == 0)
+        return TokenDateFormatType_Month_FullName_All_Lower;
+
+    if (strncmp(specifier, "MON", 3) == 0)
+        return TokenDateFormatType_Month_AbbName_All_Upper;
+
+    if (strncmp(specifier, "mon", 3) == 0)
+        return TokenDateFormatType_Month_AbbName_All_Lower;
+
+    if (strncmp(specifier, "MM", 2) == 0)
+        return TokenDateFormatType_Month_Number;
+
+    if (strncmp(specifier, "DAY", 3) == 0)
+        return TokenDateFormatType_Day_FullName_All_Upper;
+
+    if (strncmp(specifier, "Day", 3) == 0)
+        return TokenDateFormatType_Day_FullName_First_Upper;
+
+    if (strncmp(specifier, "day", 3) == 0)
+        return TokenDateFormatType_Day_FullName_All_Lower;
+
+    if (strncmp(specifier, "DY", 2) == 0)
+        return TokenDateFormatType_Day_AbbName_All_Upper;
+
+    if (strncmp(specifier, "dy", 2) == 0)
+        return TokenDateFormatType_Day_AbbName_All_Lower;
+
+    if (strncmp(specifier, "DD", 2) == 0)
+        return TokenDateFormatType_Day_Number;
+
+    if (strncmp(specifier, "hh24", 4) == 0 || strncmp(specifier, "hh", 2) == 0)
+        return TokenDateFormatType_Hour24;
+
+    if (strncmp(specifier, "hh12", 4) == 0)
+        return TokenDateFormatType_Hour12;
+
+    if (strncmp(specifier, "mm", 2) == 0)
+        return TokenDateFormatType_Minute;
+
+    if (strncmp(specifier, "ss", 2) == 0)
+        return TokenDateFormatType_Second;
+
+    if (strncmp(specifier, "am", 2) == 0 || strncmp(specifier, "AM", 2) == 0)
+        return TokenDateFormatType_am;
+
+    if (strncmp(specifier, "pm", 2) == 0 || strncmp(specifier, "PM", 2) == 0)
+        return TokenDateFormatType_pm;
+
+    // should we thow an exception !?
+    // we lose custom formats like "My date YY/MM/DD"
+    return TokenDateFormatType_Unknown;
+}
+
+char* EnsureNoIsLocalIndep(char* str)
+{
+    char* strtmp = str;
+    struct lconv* nls = localeconv();
+    char radix = (nls != NULL && *nls->decimal_point != '\0') ? *nls->decimal_point \
: '.'; +    if (radix == '.')
+    {
+        while(*strtmp != '\0' && *strtmp != radix) strtmp++;
+        if (*strtmp == radix)
+            *strtmp = '.';
+    }
+    return str;
+}
+
+wchar_t* EnsureNoIsLocalIndep(wchar_t* str)
+{
+    wchar_t* strtmp = str;
+    struct lconv* nls = localeconv();
+    wchar_t radix = (nls != NULL && *nls->decimal_point != L'\0') ? \
*nls->decimal_point : L'.'; +    if (radix == L'.')
+    {
+        while(*strtmp != L'\0' && *strtmp != radix) strtmp++;
+        if (*strtmp == radix)
+            *strtmp = L'.';
+    }
+    return str;
+}

Modified: trunk/Providers/SQLite/Src/Provider/SltConversionUtils.h
===================================================================
--- trunk/Providers/SQLite/Src/Provider/SltConversionUtils.h	2009-07-26 00:53:36 UTC \
                (rev 4861)
+++ trunk/Providers/SQLite/Src/Provider/SltConversionUtils.h	2009-07-27 15:52:22 UTC \
(rev 4862) @@ -22,6 +22,32 @@
 struct DBounds;
 struct sqlite3_stmt;
 
+enum TokenDateFormatType
+{
+    TokenDateFormatType_Unknown,
+    TokenDateFormatType_Separator,
+    TokenDateFormatType_Year2,
+    TokenDateFormatType_Year4,
+    TokenDateFormatType_Month_AbbName_All_Lower,
+    TokenDateFormatType_Month_AbbName_All_Upper,
+    TokenDateFormatType_Month_FullName_All_Lower,
+    TokenDateFormatType_Month_FullName_All_Upper,
+    TokenDateFormatType_Month_FullName_First_Upper,
+    TokenDateFormatType_Month_Number,
+    TokenDateFormatType_Day_AbbName_All_Lower,
+    TokenDateFormatType_Day_AbbName_All_Upper,
+    TokenDateFormatType_Day_FullName_All_Lower,
+    TokenDateFormatType_Day_FullName_All_Upper,
+    TokenDateFormatType_Day_FullName_First_Upper,
+    TokenDateFormatType_Day_Number,
+    TokenDateFormatType_Hour24,
+    TokenDateFormatType_Hour12,
+    TokenDateFormatType_Minute,
+    TokenDateFormatType_Second,
+    TokenDateFormatType_am,
+    TokenDateFormatType_pm
+};
+
 SLT_API std::string W2A_SLOW(const wchar_t* input);
 
 SLT_API std::wstring A2W_SLOW(const char* input);
@@ -40,5 +66,10 @@
 SLT_API void BindPropValue(sqlite3_stmt* stmt, int i, FdoLiteralValue* lv);
 SLT_API int StringContains(const char* str, const char* val);
 
+SLT_API TokenDateFormatType StringToDateFormat(const char* specifier);
+
+SLT_API char* EnsureNoIsLocalIndep(char* str);
+SLT_API wchar_t* EnsureNoIsLocalIndep(wchar_t* str);
+
 #endif
 

Modified: trunk/Providers/SQLite/Src/Provider/SltExprExtensions.cpp
===================================================================
--- trunk/Providers/SQLite/Src/Provider/SltExprExtensions.cpp	2009-07-26 00:53:36 UTC \
                (rev 4861)
+++ trunk/Providers/SQLite/Src/Provider/SltExprExtensions.cpp	2009-07-27 15:52:22 UTC \
(rev 4862) @@ -4,6 +4,7 @@
 #include "SltConversionUtils.h"
 #include "SltGeomUtils.h"
 #include "FdoCommonOSUtil.h"
+#include "StringUtil.h"
 #include <math.h>
 #include <algorithm>
 #include <limits>       // For quiet_NaN()
@@ -18,6 +19,569 @@
   len = (z2 - str);                                                                  \
\  }                                                                                  \
\  
+class DateTokenFormat;
+
+class DateToken
+{
+    friend class DateTokenFormat;
+    std::string m_value;
+    TokenDateFormatType m_type;
+private:
+    DateToken(const char* val, TokenDateFormatType type = \
TokenDateFormatType_Unknown) +        : m_type(type), m_value(val)
+    {
+        
+    }
+    DateToken(const char* val, size_t sz, TokenDateFormatType type = \
TokenDateFormatType_Unknown) +        : m_type(type)
+    {
+        m_value = std::string(val, sz);
+    }
+public:
+    size_t GetTokenLen()
+    {
+        return m_value.size();
+    }
+    const char* GetTokenValue()
+    {
+        return m_value.c_str();
+    }
+    TokenDateFormatType GetTokenType()
+    {
+        return m_type;
+    }
+};
+
+class DateTokenFormat
+{
+    std::vector<DateToken*> m_values;
+    StringBuffer m_result;
+    bool m_hasValidTokens;
+
+public:
+    DateTokenFormat() : m_hasValidTokens(false)
+    {
+    }
+    ~DateTokenFormat()
+    {
+        Clear();
+    }
+    void Clear()
+    {
+        for(std::vector<DateToken*>::iterator it = m_values.begin(); it < \
m_values.end(); it++) +            delete *it;
+        m_values.clear();
+    }
+    bool HasValidTokens() {return m_hasValidTokens;}
+    DateToken* AddDateToken(const char* val, TokenDateFormatType type = \
TokenDateFormatType_Unknown) +    {
+        DateToken* ret = new DateToken(val, type);
+        m_values.push_back(ret);
+        return ret;
+    }
+    DateToken* AddDateToken(const char* val, size_t sz, TokenDateFormatType type = \
TokenDateFormatType_Unknown) +    {
+        DateToken* ret = new DateToken(val, sz, type);
+        m_values.push_back(ret);
+        return ret;
+    }
+    bool IsLeapYear (FdoInt16 year)
+    {
+        if (year % 4 != 0) return false;
+        if (year % 100 != 0) return true;
+        return ( year % 400 == 0 );
+    }
+
+    int CountOfFeb29 (FdoInt16 year)
+    {
+        int ret = 0;
+        if( year > 0 )
+        {
+            ret = 1; // Year 0 is a leap year
+            year--;  // Year nYear is not in the period
+        }
+        ret += year/4 - year/100 + year/400;
+        return ret;
+    } 
+
+    FdoInt8 DayOfWeek(FdoInt16 year, FdoInt8 month, FdoInt8 day)
+    {
+        int ret = 0;
+        const static int daysBeforeMonth[] = {0, 0, 31, 59, 90, 120, 151, 181, 212, \
243, 273, 304, 334, 365}; +        
+        if (year < 0 || (month < 1 || month > 12) || !(day <= \
(daysBeforeMonth[month+1]-daysBeforeMonth[month]) ||  +            ( month == 2 && \
day == 29 && IsLeapYear(year) ))) +            throw \
FdoException::Create(L"Unexpected result for function ToString"); +
+        // The day of Jan 1, year
+        ret = 6 + year % 7 + CountOfFeb29(year) % 7 + 14;
+        // The day of month 1, year
+        ret += daysBeforeMonth[month];
+        if (month > 2 && IsLeapYear(year))
+            ret++;
+        // The day of month day, year
+        ret += day - 1;
+        ret %= 7;
+        return (FdoInt8)ret; 
+    }
+
+    void ProcessFormat(const char* str)
+    {
+        Clear();
+        if (str != NULL && *str != '\0')
+        {
+            size_t startPos = 0;
+            const char* strtmp = str;
+            int state = -1;
+            do
+            {
+                bool isSepChar = !isalnum(*strtmp);
+                switch(state)
+                {
+                case -1: // start
+                    state = isSepChar ? 0 : 1;
+                    break;
+                case 0: // separators
+                    if (!isSepChar)
+                    {
+                        AddDateToken(str + startPos, (int)(strtmp-str) - startPos, \
TokenDateFormatType_Separator); +                        state = 1;
+                        startPos = (int)(strtmp-str);
+                    }            
+                    break;
+                case 1: // tokens
+                    if (isSepChar)
+                    {
+                        TokenDateFormatType type = StringToDateFormat(str + \
startPos); +                        if (type != TokenDateFormatType_Unknown && type \
!= TokenDateFormatType_Separator) +                            m_hasValidTokens = \
true; +                        AddDateToken(str + startPos, (int)(strtmp-str) - \
startPos, type); +                        state = 0;
+                        startPos = (int)(strtmp-str);
+                    }            
+                    break;
+                }
+                strtmp++;
+            }
+            while (*strtmp != '\0');
+            if (state == 0)
+                AddDateToken(str + startPos, TokenDateFormatType_Separator);
+            else
+            {
+                TokenDateFormatType type = StringToDateFormat(str + startPos);
+                if (type != TokenDateFormatType_Unknown && type != \
TokenDateFormatType_Separator) +                    m_hasValidTokens = true;
+                AddDateToken(str + startPos, type);
+            }
+        }
+        else
+        {
+            // use the default format e.g.  "21-JUL-2009 13:24:14.000"
+            AddDateToken("", TokenDateFormatType_Day_Number);
+            AddDateToken("-", TokenDateFormatType_Separator);
+            AddDateToken("", TokenDateFormatType_Month_AbbName_All_Upper);
+            AddDateToken("-", TokenDateFormatType_Separator);
+            AddDateToken("", TokenDateFormatType_Year4);
+            AddDateToken(" ", TokenDateFormatType_Separator);
+            AddDateToken("", TokenDateFormatType_Hour24);
+            AddDateToken(":", TokenDateFormatType_Separator);
+            AddDateToken("", TokenDateFormatType_Minute);
+            AddDateToken(":", TokenDateFormatType_Separator);
+            AddDateToken("", TokenDateFormatType_Second);
+            m_hasValidTokens = true;
+        }
+    }
+    const char* ToString(FdoDateTime dt)
+    {
+        char tmpUse[31];
+        const char* usePtr = NULL;
+        size_t idx = 0;
+
+        if (m_result.Length() == 0)
+        {
+            for(std::vector<DateToken*>::iterator it = m_values.begin(); it < \
m_values.end(); it++) +            {
+                idx = 0;
+                DateToken* tk = *it;
+                switch(tk->GetTokenType())
+                {
+                case TokenDateFormatType_Year2:
+                    if (dt.year == -1)
+                        m_result.Append("00", 2);
+                    else
+                        m_result.Append(dt.year, "%04d", 2);
+                    break;
+
+                case TokenDateFormatType_Year4:
+                    if (dt.year == -1)
+                        m_result.Append("0000", 4);
+                    else
+                        m_result.Append(dt.year, "%04d");
+                    break;
+
+                case TokenDateFormatType_Month_AbbName_All_Lower:
+                    {
+                        FdoInt8 month = (dt.month == -1) ? 1 : dt.month;
+                        if (month < 1 || month > 12)
+                            throw FdoException::Create(L"Unexpected result for \
function ToString"); +                        usePtr = g_month_names[month-1];
+                        while(*usePtr != '\0')
+                        {
+                            tmpUse[idx++] = sqlite3Tolower(*usePtr);
+                            usePtr++;
+                        }
+                        tmpUse[idx] = '\0';
+                        m_result.Append(tmpUse, 3);
+                    }
+                    break;
+
+                case TokenDateFormatType_Month_AbbName_All_Upper:
+                    {
+                        FdoInt8 month = (dt.month == -1) ? 1 : dt.month;
+                        if (month < 1 || month > 12)
+                            throw FdoException::Create(L"Unexpected result for \
function ToString"); +                        usePtr = g_month_names[month-1];
+                        while(*usePtr != '\0')
+                        {
+                            tmpUse[idx++] = sqlite3Toupper(*usePtr);
+                            usePtr++;
+                        }
+                        tmpUse[idx] = '\0';
+                        m_result.Append(tmpUse, 3);
+                    }
+                    break;
+
+                case TokenDateFormatType_Month_FullName_All_Lower:
+                    {
+                        FdoInt8 month = (dt.month == -1) ? 1 : dt.month;
+                        if (month < 1 || month > 12)
+                            throw FdoException::Create(L"Unexpected result for \
function ToString"); +                        usePtr = g_month_names[month-1];
+                        while(*usePtr != '\0')
+                        {
+                            tmpUse[idx++] = sqlite3Tolower(*usePtr);
+                            usePtr++;
+                        }
+                        tmpUse[idx] = '\0';
+                        m_result.Append(tmpUse);
+                    }
+                    break;
+
+                case TokenDateFormatType_Month_FullName_All_Upper:
+                    {
+                        FdoInt8 month = (dt.month == -1) ? 1 : dt.month;
+                        if (month < 1 || month > 12)
+                            throw FdoException::Create(L"Unexpected result for \
function ToString"); +                        usePtr = g_month_names[month-1];
+                        while(*usePtr != '\0')
+                        {
+                            tmpUse[idx++] = sqlite3Toupper(*usePtr);
+                            usePtr++;
+                        }
+                        tmpUse[idx] = '\0';
+                        m_result.Append(tmpUse);
+                    }
+                    break;
+
+                case TokenDateFormatType_Month_FullName_First_Upper:
+                    {
+                        FdoInt8 month = (dt.month == -1) ? 1 : dt.month;
+                        if (month < 1 || month > 12)
+                            throw FdoException::Create(L"Unexpected result for \
function ToString"); +                        \
m_result.Append(g_month_names[month-1]); +                    }
+                    break;
+
+                case TokenDateFormatType_Month_Number:
+                    {
+                        FdoInt8 month = (dt.month == -1) ? 1 : dt.month;
+                        if (month < 1 || month > 12)
+                            throw FdoException::Create(L"Unexpected result for \
function ToString"); +                        m_result.Append(month, "%02d");
+                    }
+                    break;
+
+                case TokenDateFormatType_Day_AbbName_All_Lower:
+                    {
+                        FdoInt8 dayweek = DayOfWeek(dt.year, dt.month, dt.day);
+                        if (dayweek < 0 || dayweek > 6)
+                            throw FdoException::Create(L"Unexpected result for \
function ToString"); +                        usePtr = g_day_names[dayweek];
+                        while(*usePtr != '\0')
+                        {
+                            tmpUse[idx++] = sqlite3Tolower(*usePtr);
+                            usePtr++;
+                        }
+                        tmpUse[idx] = '\0';
+                        m_result.Append(tmpUse, 3);
+                    }
+                    break;
+
+                case TokenDateFormatType_Day_AbbName_All_Upper:
+                    {
+                        FdoInt8 dayweek = DayOfWeek(dt.year, dt.month, dt.day);
+                        if (dayweek < 0 || dayweek > 6)
+                            throw FdoException::Create(L"Unexpected result for \
function ToString"); +                        usePtr = g_day_names[dayweek];
+                        while(*usePtr != '\0')
+                        {
+                            tmpUse[idx++] = sqlite3Toupper(*usePtr);
+                            usePtr++;
+                        }
+                        tmpUse[idx] = '\0';
+                        m_result.Append(tmpUse, 3);
+                    }
+                    break;
+
+                case TokenDateFormatType_Day_FullName_All_Lower:
+                    {
+                        FdoInt8 dayweek = DayOfWeek(dt.year, dt.month, dt.day);
+                        if (dayweek < 0 || dayweek > 6)
+                            throw FdoException::Create(L"Unexpected result for \
function ToString"); +                        usePtr = g_day_names[dayweek];
+                        while(*usePtr != '\0')
+                        {
+                            tmpUse[idx++] = sqlite3Tolower(*usePtr);
+                            usePtr++;
+                        }
+                        tmpUse[idx] = '\0';
+                        m_result.Append(tmpUse);
+                    }
+                    break;
+
+                case TokenDateFormatType_Day_FullName_All_Upper:
+                    {
+                        FdoInt8 dayweek = DayOfWeek(dt.year, dt.month, dt.day);
+                        if (dayweek < 0 || dayweek > 6)
+                            throw FdoException::Create(L"Unexpected result for \
function ToString"); +                        usePtr = g_day_names[dayweek];
+                        while(*usePtr != '\0')
+                        {
+                            tmpUse[idx++] = sqlite3Toupper(*usePtr);
+                            usePtr++;
+                        }
+                        tmpUse[idx] = '\0';
+                        m_result.Append(tmpUse);
+                    }
+                    break;
+
+                case TokenDateFormatType_Day_FullName_First_Upper:
+                    {
+                        FdoInt8 dayweek = DayOfWeek(dt.year, dt.month, dt.day);
+                        if (dayweek < 0 || dayweek > 6)
+                            throw FdoException::Create(L"Unexpected result for \
function ToString"); +                        m_result.Append(g_day_names[dayweek]);
+                    }
+                    break;
+
+                case TokenDateFormatType_Day_Number:
+                    {
+                        FdoInt8 day = (dt.day == -1) ? 1 : dt.day;
+                        if (day < 1 || day > 31)
+                            throw FdoException::Create(L"Unexpected result for \
function ToString"); +                        m_result.Append(day, "%02d");
+                    }
+                    break;
+                case TokenDateFormatType_Hour24:
+                    {
+                        FdoInt8 hour = (dt.hour == -1) ? 0 : dt.hour;
+                        if (hour < 0 || hour > 23)
+                            throw FdoException::Create(L"Unexpected result for \
function ToString"); +                        m_result.Append(hour, "%02d");
+                    }
+                    break;
+                case TokenDateFormatType_Hour12:
+                    {
+                        FdoInt8 hour = (dt.hour == -1) ? 0 : dt.hour;
+                        if (hour < 0 || hour > 23)
+                            throw FdoException::Create(L"Unexpected result for \
function ToString"); +                        m_result.Append((hour > 12) ? (hour - \
12) : hour, "%02d"); +                    }
+                    break;
+                case TokenDateFormatType_Minute:
+                    {
+                        FdoInt8 minute = (dt.minute == -1) ? 0 : dt.minute;
+                        if (minute < 0 || minute > 59)
+                            throw FdoException::Create(L"Unexpected result for \
function ToString"); +                        m_result.Append(minute, "%02d");
+                    }
+                    break;
+                case TokenDateFormatType_Second:
+                    {
+                        if (dt.seconds == -1.0f)
+                            m_result.Append("00");
+                        else
+                        {
+                            if (dt.seconds < 0.0f || dt.seconds >= 60.0f)
+                                throw FdoException::Create(L"Unexpected result for \
function ToString"); +                            m_result.Append(dt.seconds, \
"%0.3f"); +                        }
+                    }
+                    break;
+                case TokenDateFormatType_am:
+                case TokenDateFormatType_pm:
+                    {
+                        FdoInt8 hour = (dt.hour == -1) ? 0 : dt.hour;
+                        if (hour < 0 || hour > 23)
+                            throw FdoException::Create(L"Unexpected result for \
function ToString"); +                        if (hour > 12)
+                            m_result.Append("PM", 2);
+                        else
+                            m_result.Append("AM", 2);
+                    }
+                    break;
+                default: // Separator & Unknown
+                    m_result.Append(tk->GetTokenValue(), tk->GetTokenLen());
+                    break;
+                }
+            }
+        }
+        return m_result.Data();
+    }
+
+    FdoDateTime ToDateTime(const char* str, size_t sz)
+    {
+        FdoDateTime dt;
+        if (!m_hasValidTokens || str == NULL || *str == '\0')
+            return dt;
+        const char* strtmp = str;
+        for(std::vector<DateToken*>::iterator it = m_values.begin(); it < \
m_values.end(); it++) +        {
+            DateToken* tk = *it;
+            switch(tk->GetTokenType())
+            {
+            case TokenDateFormatType_Year2:
+                if ((size_t)(strtmp-str+2) <= sz)
+                {
+                    m_result.Reset();
+                    m_result.Append(strtmp, 2);
+                    dt.year = (FdoInt16)atoi(m_result.Data());
+                    // year can be 09 = 2009 or 55 = 1955/2055 !?
+                    // it's hard to know the real year when two characters are used
+                    // let's split in half for now
+                    if (dt.year > 0 && dt.year < 50)
+                        dt.year += 2000;
+                    strtmp += 2;
+                }
+                break;
+
+            case TokenDateFormatType_Year4:
+                if ((size_t)(strtmp-str+4) <= sz)
+                {
+                    m_result.Reset();
+                    m_result.Append(strtmp, 4);
+                    dt.year = (FdoInt16)atoi(m_result.Data());
+                    strtmp += 4;
+                }
+                break;
+
+            case TokenDateFormatType_Month_AbbName_All_Lower:
+            case TokenDateFormatType_Month_AbbName_All_Upper:
+            case TokenDateFormatType_Month_FullName_All_Lower:
+            case TokenDateFormatType_Month_FullName_All_Upper:
+            case TokenDateFormatType_Month_FullName_First_Upper:
+                {
+                    if ((size_t)(strtmp-str+3) <= sz)
+                    {
+                        FdoInt8 idx = 0;
+                        for (; idx < 12; idx++)
+                        {
+                            if (_strnicmp(strtmp, g_month_names[idx], 3) == 0)
+                            {
+                                dt.month = idx+1;
+                                strtmp += 3;
+                                break;
+                            }
+                        }
+                        if (idx == 12)
+                            strtmp++;
+                    }
+                }
+                break;
+
+            case TokenDateFormatType_Month_Number:
+                if ((size_t)(strtmp-str+2) <= sz)
+                {
+                    m_result.Reset();
+                    m_result.Append(strtmp, 2);
+                    dt.month = (FdoInt16)atoi(m_result.Data());
+                    strtmp += 2;
+                }
+                break;
+
+            case TokenDateFormatType_Day_AbbName_All_Lower:
+            case TokenDateFormatType_Day_AbbName_All_Upper:
+            case TokenDateFormatType_Day_FullName_All_Lower:
+            case TokenDateFormatType_Day_FullName_All_Upper:
+            case TokenDateFormatType_Day_FullName_First_Upper:
+                // nothing to do here since day of the week don't help us
+                if ((size_t)(strtmp-str+3) <= sz)
+                    strtmp += 3;
+                break;
+
+            case TokenDateFormatType_Day_Number:
+                if ((size_t)(strtmp-str+2) <= sz)
+                {
+                    m_result.Reset();
+                    m_result.Append(strtmp, 2);
+                    dt.day = (FdoInt16)atoi(m_result.Data());
+                    strtmp += 2;
+                }
+                break;
+            case TokenDateFormatType_Hour24:
+            case TokenDateFormatType_Hour12:
+                if ((size_t)(strtmp-str+2) <= sz)
+                {
+                    m_result.Reset();
+                    m_result.Append(strtmp, 2);
+                    dt.hour = (FdoInt16)atoi(m_result.Data());
+                    strtmp += 2;
+                }
+                break;
+            case TokenDateFormatType_Minute:
+                if ((size_t)(strtmp-str+2) <= sz)
+                {
+                    m_result.Reset();
+                    m_result.Append(strtmp, 2);
+                    dt.minute = (FdoInt16)atoi(m_result.Data());
+                    strtmp += 2;
+                }
+                break;
+            case TokenDateFormatType_Second:
+                if ((size_t)(strtmp-str+1) <= sz) // at least one character
+                {
+                    // this will work since atof ignores other characters after \
numbers +                    dt.seconds = (float)atof(strtmp);
+                    strtmp++; // just advance one position to be on number
+                }
+                break;
+            case TokenDateFormatType_am:
+            case TokenDateFormatType_pm:
+                if ((size_t)(strtmp-str+2) <= sz)
+                {
+                    // if it's PM we need to add 12 to hour
+                    if (dt.hour >= 0 && dt.hour < 12 && _strnicmp(strtmp, "PM", 2) \
== 0) +                        dt.hour += 12;
+                    strtmp += 2;
+                }
+                break;
+            default: // Separator & Unknown
+                {
+                    // can we get the token value?
+                    int pos = StringContains(strtmp, tk->GetTokenValue());
+                    if (pos != -1) // in case yes jump over the position
+                        strtmp += (pos + tk->GetTokenLen());
+                }
+                break;
+            }
+            // stop in case we are at the end of date time string
+            if ((strtmp-str) >= sz)
+                break;
+        }
+        return dt;
+    }
+};
+
 //===============================================================================
 //  Basic math functions
 //===============================================================================
@@ -635,7 +1199,7 @@
 //  Conversion fuctions
 //===============================================================================
 //NOTE: these are implemented only for compatibility with FDO filters -- SQLite
-//expression evaluation uses implicit type conversion, so they are not sctrictly
+//expression evaluation uses implicit type conversion, so they are not strictly
 //necessary
 static void convFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
 {
@@ -645,46 +1209,103 @@
 
     switch(optype)
     {
-    case 1: //todate
+    case 1: //todouble
         {
-            //assumes date is stored in ISO 8601 string format
-            const char* s = (const char*)sqlite3_value_text(argv[0]);
-            sqlite3_result_text(context, s, -1, SQLITE_TRANSIENT);
-        }
-        break;
-    case 2: //todouble
-        {
             double d = sqlite3_value_double(argv[0]);
             sqlite3_result_double(context, d);
         }
         break;
-    case 3: //tofloat
+    case 2: //tofloat
         {
             float f = (float)sqlite3_value_double(argv[0]);
             sqlite3_result_double(context, f);
         }
         break;
-    case 4: //toint32
+    case 3: //toint32
         {
             int i = sqlite3_value_int(argv[0]);
             sqlite3_result_int(context, i);
         }
         break;
-    case 5: //toint64
+    case 4: //toint64
         {
             sqlite_int64 i = sqlite3_value_int64(argv[0]);
             sqlite3_result_int64(context, i);
         }
         break;
-    case 6: //tostring
+    }
+}
+
+static void todateFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
+{
+    assert(argc == 1 || argc == 2);
+    int type = sqlite3_value_type(argv[0]);
+    const char* dateStr = (const char*)sqlite3_value_text(argv[0]);
+    if (type == SQLITE_NULL || dateStr == NULL || sqlite3_value_bytes(argv[0]) == 0)
+    {
+        sqlite3_result_null(context);
+    }
+    else if (type != SQLITE_TEXT)
+    {
+        sqlite3_result_null(context);
+    }
+    else
+    {
+        FdoDateTime dt = DateFromString(dateStr, false);
+        if (dt.IsDate() || dt.IsTime() || dt.IsDateTime())
         {
             const char* s = (const char*)sqlite3_value_text(argv[0]);
             sqlite3_result_text(context, s, -1, SQLITE_TRANSIENT);
         }
-        break;
+        else
+        {
+            DateTokenFormat dtc;
+            if (argc == 2 && sqlite3_value_type(argv[1]) == SQLITE_TEXT && \
sqlite3_value_bytes(argv[1]) != 0) +                dtc.ProcessFormat((const \
char*)sqlite3_value_text(argv[1])); +            else
+                dtc.ProcessFormat(NULL);
+
+            dt = dtc.ToDateTime(dateStr, sqlite3_value_bytes(argv[0]));
+            if (dt.IsDate() || dt.IsTime() || dt.IsDateTime())
+            {
+                char dateBuff[31];
+                *dateBuff = '\0';
+                DateToString(&dt, dateBuff, 31);
+                sqlite3_result_text(context, dateBuff, -1, SQLITE_TRANSIENT);
+            }
+            else
+                sqlite3_result_null(context);
+        }
     }
 }
 
+static void toStringFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
+{
+    assert(argc == 1 || argc == 2);
+    int type = sqlite3_value_type(argv[0]);
+    const char* dateStr = (const char*)sqlite3_value_text(argv[0]);
+    if (type == SQLITE_NULL || dateStr == NULL || sqlite3_value_bytes(argv[0]) == 0)
+    {
+        sqlite3_result_null(context);
+    }
+    else if (type != SQLITE_TEXT)
+    {
+        sqlite3_result_text(context, dateStr, -1, SQLITE_TRANSIENT);
+    }
+    else // process date time
+    {
+        DateTokenFormat dtc;
+        FdoDateTime dt = DateFromString(dateStr);
+        
+        if (argc == 2 && sqlite3_value_type(argv[1]) == SQLITE_TEXT && \
sqlite3_value_bytes(argv[1]) != 0) +            dtc.ProcessFormat((const \
char*)sqlite3_value_text(argv[1])); +        else
+            dtc.ProcessFormat(NULL);
+
+        sqlite3_result_text(context, dtc.ToString(dt), -1, SQLITE_TRANSIENT);
+    }
+}
+
 static void nullvalueFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
 {
     assert(argc == 2);
@@ -1218,12 +1839,14 @@
 
         { "GeomFromText",       1, 0, SQLITE_UTF8, 0, GeomFromText },
 
-        { "todate",             1, 1,  SQLITE_UTF8,    0, convFunc },
-        { "todouble",           1, 2,  SQLITE_UTF8,    0, convFunc },
-        { "tofloat",            1, 3,  SQLITE_UTF8,    0, convFunc },
-        { "toint32",            1, 4,  SQLITE_UTF8,    0, convFunc },
-        { "toint64",            1, 5,  SQLITE_UTF8,    0, convFunc },
-        { "tostring",           1, 6,  SQLITE_UTF8,    0, convFunc },
+        { "todate",             1, 1,  SQLITE_UTF8,    0, todateFunc },
+        { "todate",             2, 1,  SQLITE_UTF8,    0, todateFunc },
+        { "todouble",           1, 1,  SQLITE_UTF8,    0, convFunc },
+        { "tofloat",            1, 2,  SQLITE_UTF8,    0, convFunc },
+        { "toint32",            1, 3,  SQLITE_UTF8,    0, convFunc },
+        { "toint64",            1, 4,  SQLITE_UTF8,    0, convFunc },
+        { "tostring",           1, 1,  SQLITE_UTF8,    0, toStringFunc },
+        { "tostring",           2, 1,  SQLITE_UTF8,    0, toStringFunc },
         { "nullvalue",          2, 1,  SQLITE_UTF8,    0, nullvalueFunc }
 
     };

Modified: trunk/Providers/SQLite/Src/Provider/SltExprExtensions.h
===================================================================
--- trunk/Providers/SQLite/Src/Provider/SltExprExtensions.h	2009-07-26 00:53:36 UTC \
                (rev 4861)
+++ trunk/Providers/SQLite/Src/Provider/SltExprExtensions.h	2009-07-27 15:52:22 UTC \
(rev 4862) @@ -18,5 +18,31 @@
 "geom_bbox"
 };
 
+static const char* g_month_names[] = 
+{
+"January",
+"February",
+"March",
+"April",
+"May",
+"June",
+"July",
+"August",
+"September",
+"October",
+"November",
+"December"
+};
 
+static const char* g_day_names[] = 
+{
+"Sunday",
+"Monday",
+"Tuesday",
+"Wednesday",
+"Thursday",
+"Friday",
+"Saturday"
+};
+
 void RegisterExtensions (sqlite3* db);

Modified: trunk/Providers/SQLite/Src/Provider/SltProvider.cpp
===================================================================
--- trunk/Providers/SQLite/Src/Provider/SltProvider.cpp	2009-07-26 00:53:36 UTC (rev \
                4861)
+++ trunk/Providers/SQLite/Src/Provider/SltProvider.cpp	2009-07-27 15:52:22 UTC (rev \
4862) @@ -850,7 +850,7 @@
     }
     
     StringBuffer sb;
-    SltExpressionTranslator exTrans;
+    SltExpressionTranslator exTrans(properties);
     
     if (bDistinct)
     {

Modified: trunk/Providers/SQLite/Src/Provider/SltQueryTranslator.cpp
===================================================================
--- trunk/Providers/SQLite/Src/Provider/SltQueryTranslator.cpp	2009-07-26 00:53:36 \
                UTC (rev 4861)
+++ trunk/Providers/SQLite/Src/Provider/SltQueryTranslator.cpp	2009-07-27 15:52:22 \
UTC (rev 4862) @@ -20,7 +20,7 @@
 #include "SltGeomUtils.h"
 #include "SltQueryTranslator.h"
 #include "SltExprExtensions.h"
-
+#include <FdoExpressionEngineCopyFilter.h>
 #include <algorithm>
 
 recno_list* recno_list_union(recno_list* left, recno_list* right)
@@ -28,10 +28,10 @@
     //if one of the lists is null it means it iterates over all features...
     //so return that list as the union of the two
     if (left == NULL)
-        return left;
+        return right;
 
     if (right == NULL)
-        return right;
+        return left;
 
     std::sort(left->begin(), left->end(), std::less<__int64>());
     std::sort(right->begin(), right->end(), std::less<__int64>());
@@ -148,7 +148,6 @@
 
     FdoBinaryLogicalOperations op = filter.GetOperation();
 
-    StringBuffer spVal;
     FilterChunk* ret = NULL;
 
     //determine logical op we want as string
@@ -233,6 +232,7 @@
                 DBounds::Union(&ret->m_bounds, &lefts->m_bounds, &rights->m_bounds);
             }
             ret->m_ids = recno_list_intersection(lefts->m_ids, rights->m_ids);
+            lefts->m_ids = rights->m_ids = NULL;
         }
         break;
     case FdoBinaryLogicalOperations_Or:
@@ -259,6 +259,7 @@
                 DBounds::Union(&ret->m_bounds, &lefts->m_bounds, &rights->m_bounds);
             }
             ret->m_ids = recno_list_union(lefts->m_ids, rights->m_ids);
+            lefts->m_ids = rights->m_ids = NULL;
         }
         break;
     }
@@ -288,16 +289,16 @@
 
     FdoPtr<FdoIdentifier> pname = filter.GetPropertyName();
     //construct the SQLite function we want to use for this spatial op
-    StringBuffer spVal;
-    spVal.Append(sfunc);
-    spVal.Append("(", 1);
-    spVal.Append(pname->GetName());
-    spVal.Append(",", 1);
-    spVal.Append(expr->ToString());
-    spVal.Append(")", 1);
+    m_sb.Reset();
+    m_sb.Append(sfunc);
+    m_sb.Append("(", 1);
+    m_sb.Append(pname->GetName());
+    m_sb.Append(",", 1);
+    m_sb.Append(expr->ToString());
+    m_sb.Append(")", 1);
     DBounds bdGeom = expr->m_bounds;
 
-    FilterChunk* ret = CreateFilterChunk(spVal.Data(), spVal.Length(), \
StlSpatialTypeOperation_And); +    FilterChunk* ret = CreateFilterChunk(m_sb.Data(), \
m_sb.Length(), StlSpatialTypeOperation_And);  //for some operations, we can speed up \
the query by also  //performing a bbox check using the spatial index
     switch(op)
@@ -369,40 +370,112 @@
     FdoPtr<FdoExpression> left = filter.GetLeftExpression();
     FdoPtr<FdoExpression> right = filter.GetRightExpression();
 
-    FdoPtr<FdoDataPropertyDefinitionCollection> idpdc = \
                m_fc->GetIdentityProperties();
-    if (idpdc->GetCount() == 1)
+    if (filter.GetOperation() == FdoComparisonOperations_EqualTo)
     {
-        FdoPtr<FdoDataPropertyDefinition> idpd = idpdc->GetItem(0);
-        
-        if (filter.GetOperation() == FdoComparisonOperations_EqualTo && \
wcscmp(left->ToString(), idpd->GetName()) == 0) +        \
FdoPtr<FdoDataPropertyDefinitionCollection> idpdc = m_fc->GetIdentityProperties(); +  \
if (idpdc->GetCount() == 1)  {
-            __int64 idval = -1;
-            size_t len = 0;
-            int res = swscanf(right->ToString(), L"%lld%n", &idval, &len);
+            FdoPtr<FdoDataPropertyDefinition> idpd = idpdc->GetItem(0);
+            if (wcscmp(left->ToString(), idpd->GetName()) == 0)
+            {
+                __int64 idval = -1;
+                size_t len = 0;
+                int res = swscanf(right->ToString(), L"%lld%n", &idval, &len);
 
-            if (res == 1 && len == wcslen(right->ToString()))
-            {
-                ret = CreateFilterChunk(filter.ToString());
-                ret->m_ids = new recno_list;
-                ret->m_ids->push_back(idval);
-                m_canUseFastStepping = true;
+                if (res == 1 && len == wcslen(right->ToString()))
+                {
+                    ret = CreateFilterChunk(filter.ToString());
+                    ret->m_ids = new recno_list;
+                    ret->m_ids->push_back(idval);
+                    m_canUseFastStepping = true;
+                }
             }
         }
     }
+    if (ret == NULL)
+    {
+        // we need to be sure we handle datetime values, e.g. DATEPROP > DATE \
'10-10-2000' +        FdoPtr<FdoExpression> param = filter.GetLeftExpression();
+        param->Process(this);
+        FilterChunk* exprLeft = m_evalStack.back();
+        m_evalStack.pop_back();
+        
+        param = filter.GetRightExpression();
+        param->Process(this);
+        FilterChunk* exprRight = m_evalStack.back();
+        m_evalStack.pop_back();
 
-    m_evalStack.push_back((ret != NULL) ? ret : \
CreateFilterChunk(filter.ToString())); +        ComplexFilterChunk* compExp = \
CreateComplexFilterChunk(); +        ret = compExp;
+        compExp->AddToList(CreateFilterChunk("(", 1));
+        compExp->AddToList(exprLeft);
+        
+        switch(filter.GetOperation())
+        {
+        case FdoComparisonOperations_EqualTo:
+            compExp->AddToList(CreateFilterChunk("=", 1));
+            break;
+        case FdoComparisonOperations_NotEqualTo:
+            compExp->AddToList(CreateFilterChunk("<>", 2));
+            break;
+        case FdoComparisonOperations_GreaterThan:
+            compExp->AddToList(CreateFilterChunk(">", 1));
+            break;
+        case FdoComparisonOperations_GreaterThanOrEqualTo:
+            compExp->AddToList(CreateFilterChunk(">=", 2));
+            break;
+        case FdoComparisonOperations_LessThan:
+            compExp->AddToList(CreateFilterChunk("<", 1));
+            break;
+        case FdoComparisonOperations_LessThanOrEqualTo:
+            compExp->AddToList(CreateFilterChunk("<=", 2));
+            break;
+        case FdoComparisonOperations_Like:
+            compExp->AddToList(CreateFilterChunk(" LIKE ", 6));
+            break;
+        }
+        compExp->AddToList(exprRight);
+        compExp->AddToList(CreateFilterChunk(")", 1));
+    }
+    m_evalStack.push_back(ret);
 }
 
 void SltQueryTranslator::ProcessInCondition(FdoInCondition& filter)
 {
-    m_evalStack.push_back(CreateFilterChunk(filter.ToString()));
+    size_t szBefore = m_evalStack.size();
+    FdoPtr<FdoValueExpressionCollection> vals = filter.GetValues();
+    int cnt = vals->GetCount();
+    for(int idx = 0; idx < cnt; idx++)
+    {
+        FdoPtr<FdoValueExpression> exp = vals->GetItem(idx);
+        exp->Process(this);
+    }
+    size_t szAfter = m_evalStack.size();
+
+    m_sb.Reset();
+    FdoPtr<FdoIdentifier> prop = filter.GetPropertyName();
+    m_sb.AppendDQuoted(prop->GetName());
+    m_sb.Append(" IN(", 4);
+    FilterChunk* item = NULL;
+    for(size_t idx = szBefore; idx < szAfter; idx++)
+    {
+        item = m_evalStack[idx];
+        m_sb.Append(item->ToString());
+        m_sb.Append(", ", 2);
+    }
+    m_sb.Data()[m_sb.Length()-2] = ')';
+    // clean stack
+    m_evalStack.erase(m_evalStack.begin() + szBefore, m_evalStack.end());
+    m_evalStack.push_back(CreateFilterChunk(m_sb.Data(), m_sb.Length()));
 }
 
 void SltQueryTranslator::ProcessNullCondition(FdoNullCondition& filter)
 {
     FdoPtr<FdoIdentifier> idf = filter.GetPropertyName();
-    std::wstring val = std::wstring(L"\"" + std::wstring(idf->GetName()) + L"\" IS \
                NULL");
-    m_evalStack.push_back(CreateFilterChunk(val.c_str()));
+    m_sb.Reset();
+    m_sb.AppendDQuoted(idf->GetName());
+    m_sb.Append(" IS NULL", 8);
+    m_evalStack.push_back(CreateFilterChunk(m_sb.Data(), m_sb.Length()));
 }
 
 void SltQueryTranslator::ProcessDistanceCondition(FdoDistanceCondition& filter)
@@ -410,21 +483,100 @@
     m_evalStack.push_back(CreateFilterChunk(filter.ToString()));
 }
 
-
 //--------------------------------------------------------------------
 // FdoIExpressionProcessor
 //--------------------------------------------------------------------
 
 void SltQueryTranslator::ProcessBinaryExpression(FdoBinaryExpression& expr)
 {
+    FdoPtr<FdoExpression> param = expr.GetLeftExpression();
+    param->Process(this);
+    FilterChunk* exprLeft = m_evalStack.back();
+    m_evalStack.pop_back();
+    
+    param = expr.GetRightExpression();
+    param->Process(this);
+    FilterChunk* exprRight = m_evalStack.back();
+    m_evalStack.pop_back();
+
+    ComplexFilterChunk* ret = CreateComplexFilterChunk();
+    ret->AddToList(CreateFilterChunk("(", 1));
+    ret->AddToList(exprLeft);
+
+    switch(expr.GetOperation())
+    {
+    case FdoBinaryOperations_Add:
+        ret->AddToList(CreateFilterChunk("+", 1));
+        break;
+    case FdoBinaryOperations_Divide:
+        ret->AddToList(CreateFilterChunk("-", 1));
+        break;
+    case FdoBinaryOperations_Multiply:
+        ret->AddToList(CreateFilterChunk("*", 1));
+        break;
+    case FdoBinaryOperations_Subtract:
+        ret->AddToList(CreateFilterChunk("/", 1));
+        break;
+    }
+    ret->AddToList(exprRight);
+    ret->AddToList(CreateFilterChunk(")", 1));
+
+    m_evalStack.push_back(ret);
 }
 
 void SltQueryTranslator::ProcessUnaryExpression(FdoUnaryExpression& expr)
 {
+    FdoPtr<FdoExpression> arg = expr.GetExpression();
+    arg->Process(this);
+
+    FilterChunk* exprRez = m_evalStack.back();
+    m_evalStack.pop_back();
+
+    ComplexFilterChunk* ret = CreateComplexFilterChunk();
+    ret->AddToList(CreateFilterChunk(" (-(", 4));
+    ret->AddToList(exprRez);
+    ret->AddToList(CreateFilterChunk("))", 2));
+
+    m_evalStack.push_back(ret);
 }
 
 void SltQueryTranslator::ProcessFunction(FdoFunction& expr)
 {
+    // We need to handle this because of ToDate...
+    // "ToDate(DATE '10-10-2000')" which should be "ToDate('10-10-2000')"
+    // otherwise query will fail, because of syntax error
+
+    size_t szBefore = m_evalStack.size();
+    FdoPtr<FdoExpressionCollection> vals = expr.GetArguments();
+    int cnt = vals->GetCount();
+    for(int idx = 0; idx < cnt; idx++)
+    {
+        FdoPtr<FdoExpression> exp = vals->GetItem(idx);
+        exp->Process(this);
+    }
+    size_t szAfter = m_evalStack.size();
+    if (szAfter != szBefore)
+    {
+        m_sb.Reset();
+        m_sb.Append(expr.GetName());
+        m_sb.Append("(", 1);
+        for(size_t idx = szBefore; idx < szAfter; idx++)
+        {
+            m_sb.Append(m_evalStack[idx]->ToString());
+            m_sb.Append(", ", 2);
+        }
+        m_sb.Data()[m_sb.Length()-2] = ')';
+        // clean stack
+        m_evalStack.erase(m_evalStack.begin() + szBefore, m_evalStack.end());
+        m_evalStack.push_back(CreateFilterChunk(m_sb.Data(), m_sb.Length()));
+    }
+    else
+    {
+        m_sb.Reset();
+        m_sb.Append(expr.GetName());
+        m_sb.Append("()", 2);
+        m_evalStack.push_back(CreateFilterChunk(m_sb.Data(), m_sb.Length()));
+    }
 }
 
 void SltQueryTranslator::ProcessIdentifier(FdoIdentifier& expr)
@@ -458,63 +610,192 @@
         }
     }
 
-    m_evalStack.push_back(CreateFilterChunk(expr.GetName()));
+    m_sb.Reset();
+    m_sb.AppendDQuoted(expr.GetName());
+    m_evalStack.push_back(CreateFilterChunk(m_sb.Data(), m_sb.Length()));
 }
 
 void SltQueryTranslator::ProcessComputedIdentifier(FdoComputedIdentifier& expr)
 {
+    throw FdoException::Create(L"Unsupported FDO type in filters");
 }
 
 void SltQueryTranslator::ProcessParameter(FdoParameter& expr)
 {
+    throw FdoException::Create(L"Unsupported FDO type in filters");
 }
 
 void SltQueryTranslator::ProcessBooleanValue(FdoBooleanValue& expr)
 {
+    if (!expr.IsNull())
+    {
+        if (expr.GetBoolean())
+            m_evalStack.push_back(CreateFilterChunk("TRUE", 4));
+        else
+            m_evalStack.push_back(CreateFilterChunk("FALSE", 5));
+    }
+    else
+        m_evalStack.push_back(CreateFilterChunk("null", 4));
 }
 
 void SltQueryTranslator::ProcessByteValue(FdoByteValue& expr)
 {
+    if (!expr.IsNull())
+    {
+        m_sb.Reset();
+#ifdef _WIN32
+        _itoa_s(expr.GetByte() , m_sb.Data(), 256, 10);
+#else
+        itoa(expr.GetByte(), m_sb.Data(), 10);
+#endif
+        m_evalStack.push_back(CreateFilterChunk(m_sb.Data(), strlen(m_sb.Data())));
+    }
+    else
+        m_evalStack.push_back(CreateFilterChunk("null", 4));
 }
 
 void SltQueryTranslator::ProcessDateTimeValue(FdoDateTimeValue& expr)
 {
+    // the big issues here is FDO syntax add in front of the date
+    // DATE/TIME/TIMESTAMP which for SQLite should be removed
+    if (!expr.IsNull())
+    {
+        m_sb.Reset();
+        char* dateStr = m_sb.Data();
+        *dateStr = '\'';
+        FdoDateTime dt = expr.GetDateTime();
+        DateToString(&dt, dateStr+1, 31);
+        size_t sz = strlen(dateStr+1);
+        dateStr[sz+1] = '\'';
+        m_evalStack.push_back(CreateFilterChunk(dateStr, sz+2));
+    }
+    else
+        m_evalStack.push_back(CreateFilterChunk("null", 4));
 }
 
 void SltQueryTranslator::ProcessDecimalValue(FdoDecimalValue& expr)
 {
+    if (!expr.IsNull())
+    {
+        m_sb.Reset();
+        char* ptr = m_sb.Data();
+#ifdef _WIN32
+        _snprintf(ptr, 256, "%g", expr.GetDecimal());
+#else
+        sprintf(ptr, 256, "%g", expr.GetDecimal());
+#endif
+        EnsureNoIsLocalIndep(ptr);
+        m_evalStack.push_back(CreateFilterChunk(ptr, strlen(ptr)));
+    }
+    else
+        m_evalStack.push_back(CreateFilterChunk("null", 4));
 }
 
 void SltQueryTranslator::ProcessDoubleValue(FdoDoubleValue& expr)
 {
+    if (!expr.IsNull())
+    {
+        m_sb.Reset();
+        char* ptr = m_sb.Data();
+#ifdef _WIN32
+        _snprintf(ptr, 256, "%g", expr.GetDouble());
+#else
+        sprintf(ptr, 256, "%g", expr.GetDouble());
+#endif
+        EnsureNoIsLocalIndep(ptr);
+        m_evalStack.push_back(CreateFilterChunk(ptr, strlen(ptr)));
+    }
+    else
+        m_evalStack.push_back(CreateFilterChunk("null", 4));
 }
 
+void SltQueryTranslator::ProcessSingleValue(FdoSingleValue& expr)
+{
+    if (!expr.IsNull())
+    {
+        m_sb.Reset();
+        char* ptr = m_sb.Data();
+#ifdef _WIN32
+        _snprintf(ptr, 256, "%f", expr.GetSingle());
+#else
+        sprintf(ptr, 256, "%f", expr.GetSingle());
+#endif
+        EnsureNoIsLocalIndep(ptr);
+        m_evalStack.push_back(CreateFilterChunk(ptr, strlen(ptr)));
+    }
+    else
+        m_evalStack.push_back(CreateFilterChunk("null", 4));
+}
+
 void SltQueryTranslator::ProcessInt16Value(FdoInt16Value& expr)
 {
+    if (!expr.IsNull())
+    {
+        m_sb.Reset();
+#ifdef _WIN32
+        _itoa_s(expr.GetInt16(), m_sb.Data(), 256, 10);
+#else
+        itoa(expr.GetInt16(), m_sb.Data(), 10);
+#endif
+        m_evalStack.push_back(CreateFilterChunk(m_sb.Data(), strlen(m_sb.Data())));
+    }
+    else
+        m_evalStack.push_back(CreateFilterChunk("null", 4));
 }
 
 void SltQueryTranslator::ProcessInt32Value(FdoInt32Value& expr)
 {
+    if (!expr.IsNull())
+    {
+        m_sb.Reset();
+#ifdef _WIN32
+        _itoa_s(expr.GetInt32(), m_sb.Data(), 256, 10);
+#else
+        itoa(expr.GetInt32(), m_sb.Data(), 10);
+#endif
+        m_evalStack.push_back(CreateFilterChunk(m_sb.Data(), strlen(m_sb.Data())));
+    }
+    else
+        m_evalStack.push_back(CreateFilterChunk("null", 4));
 }
 
 void SltQueryTranslator::ProcessInt64Value(FdoInt64Value& expr)
 {
+    if (!expr.IsNull())
+    {
+        m_sb.Reset();
+#ifdef _WIN32
+        _i64toa_s(expr.GetInt64(), m_sb.Data(), 256, 10);
+#else
+        sprintf(m_sb.Data(), 256, "%lld", expr.GetInt64());
+#endif
+        m_evalStack.push_back(CreateFilterChunk(m_sb.Data(), strlen(m_sb.Data())));
+    }
+    else
+        m_evalStack.push_back(CreateFilterChunk("null", 4));
 }
 
-void SltQueryTranslator::ProcessSingleValue(FdoSingleValue& expr)
-{
-}
-
 void SltQueryTranslator::ProcessStringValue(FdoStringValue& expr)
 {
+    // it's faster than expr.ToString()
+    if (!expr.IsNull())
+    {
+        m_sb.Reset();
+        m_sb.AppendSQuoted(expr.GetString());
+        m_evalStack.push_back(CreateFilterChunk(m_sb.Data(), m_sb.Length()));
+    }
+    else
+        m_evalStack.push_back(CreateFilterChunk("null", 4));
 }
 
 void SltQueryTranslator::ProcessBLOBValue(FdoBLOBValue& expr)
 {
+    throw FdoException::Create(L"Unsupported FDO type in filters");
 }
 
 void SltQueryTranslator::ProcessCLOBValue(FdoCLOBValue& expr)
 {
+    throw FdoException::Create(L"Unsupported FDO type in filters");
 }
 
 void SltQueryTranslator::ProcessGeometryValue(FdoGeometryValue& expr)
@@ -577,15 +858,14 @@
     delete[] wstr;
 #else
     m_geomCount++;
-    wchar_t buf[70];
-    *buf = L'\0';
+    m_sb.Reset();
 #ifdef _WIN32
-    _i64tow_s((FdoInt64)fgf.p, buf, 70, 10);
+    _i64toa_s((FdoInt64)fgf.p, m_sb.Data(), 256, 10);
 #else
-    swprintf(buf, 70, L"%lld", (FdoInt64)fgf.p);
+    sprintf(m_sb.Data(), 256, "%lld", (FdoInt64)fgf.p);
 #endif
 
-    FilterChunk* ret = CreateFilterChunk(buf);
+    FilterChunk* ret = CreateFilterChunk(m_sb.Data(), strlen(m_sb.Data()));
 #endif
 
     ret->m_bounds = ext;
@@ -706,13 +986,10 @@
 
 void SltExpressionTranslator::ProcessUnaryExpression(FdoUnaryExpression& expr)
 {
-    if (expr.GetOperation() == FdoUnaryOperations_Negate)
-    {
-        m_expr.Append(" (-(", 4);
-        FdoPtr<FdoExpression> param = expr.GetExpression();
-        HandleExpr(param);
-        m_expr.Append("))", 2);
-    }
+    m_expr.Append(" (-(", 4);
+    FdoPtr<FdoExpression> param = expr.GetExpression();
+    HandleExpr(param);
+    m_expr.Append("))", 2);
 }
 
 void SltExpressionTranslator::ProcessFunction(FdoFunction& expr)
@@ -759,15 +1036,22 @@
 
 void SltExpressionTranslator::ProcessIdentifier(FdoIdentifier& expr)
 {
-    m_expr.Append(expr.ToString());
+    m_expr.AppendDQuoted(expr.GetName());
 }
 
 void SltExpressionTranslator::ProcessComputedIdentifier(FdoComputedIdentifier& expr)
 {
     FdoPtr<FdoExpression> param = expr.GetExpression();
-    HandleExpr(param);
+    if (m_props != NULL)
+    {
+        // expand the expressions in case we have expressions besad on other \
expressions. +        FdoPtr<FdoExpression> expandedExpression = \
FdoExpressionEngineCopyFilter::Copy(param, m_props); +        \
HandleExpr(expandedExpression); +    }
+    else
+        HandleExpr(param);
     m_expr.Append(" AS ", 4);
-    m_expr.Append(expr.GetName());
+    m_expr.AppendDQuoted(expr.GetName());
 }
 
 void SltExpressionTranslator::ProcessParameter(FdoParameter& expr)
@@ -776,51 +1060,142 @@
 }
 void SltExpressionTranslator::ProcessBooleanValue(FdoBooleanValue& expr)
 {
-    m_expr.Append(expr.ToString());
+    if (!expr.IsNull())
+    {
+        if (expr.GetBoolean())
+            m_expr.Append("TRUE", 4);
+        else
+            m_expr.Append("FALSE", 5);
+    }
+    else
+        m_expr.Append("null", 4);
 }
 void SltExpressionTranslator::ProcessByteValue(FdoByteValue& expr)
 {
-    m_expr.Append(expr.ToString());
+    if (!expr.IsNull())
+    {
+#ifdef _WIN32
+        _itoa_s(expr.GetByte(), m_useConv, 256, 10);
+#else
+        itoa(expr.GetByte(), m_useConv, 10);
+#endif
+        m_expr.Append(m_useConv, strlen(m_useConv));
+    }
+    else
+        m_expr.Append("null", 4);
 }
 
 void SltExpressionTranslator::ProcessDateTimeValue(FdoDateTimeValue& expr)
 {
-    m_expr.Append(expr.ToString());
+    if (!expr.IsNull())
+    {
+        FdoDateTime dt = expr.GetDateTime();
+        DateToString(&dt, m_useConv, 31);
+        m_expr.AppendSQuoted(m_useConv);
+    }
+    else
+        m_expr.Append("null", 4);
 }
 
 void SltExpressionTranslator::ProcessDecimalValue(FdoDecimalValue& expr)
 {
-    m_expr.Append(expr.ToString());
+    if (!expr.IsNull())
+    {
+#ifdef _WIN32
+        _snprintf(m_useConv, 256, "%g", expr.GetDecimal());
+#else
+        sprintf(m_useConv, 256, "%g", expr.GetDecimal());
+#endif
+        EnsureNoIsLocalIndep(m_useConv);
+        m_expr.Append(m_useConv, strlen(m_useConv));
+    }
+    else
+        m_expr.Append("null", 4);
 }
 
 void SltExpressionTranslator::ProcessDoubleValue(FdoDoubleValue& expr)
 {
-    m_expr.Append(expr.ToString());
+    if (!expr.IsNull())
+    {
+#ifdef _WIN32
+        _snprintf(m_useConv, 256, "%g", expr.GetDouble());
+#else
+        sprintf(m_useConv, 256, "%g", expr.GetDouble());
+#endif
+        EnsureNoIsLocalIndep(m_useConv);
+        m_expr.Append(m_useConv, strlen(m_useConv));
+    }
+    else
+        m_expr.Append("null", 4);
 }
 
 void SltExpressionTranslator::ProcessInt16Value(FdoInt16Value& expr)
 {
-    m_expr.Append(expr.ToString());
+    if (!expr.IsNull())
+    {
+#ifdef _WIN32
+        _itoa_s(expr.GetInt16(), m_useConv, 256, 10);
+#else
+        itoa(expr.GetInt16(), m_useConv, 10);
+#endif
+        m_expr.Append(m_useConv, strlen(m_useConv));
+    }
+    else
+        m_expr.Append("null", 4);
 }
 
 void SltExpressionTranslator::ProcessInt32Value(FdoInt32Value& expr)
 {
-    m_expr.Append(expr.ToString());
+    if (!expr.IsNull())
+    {
+#ifdef _WIN32
+        _itoa_s(expr.GetInt32(), m_useConv, 256, 10);
+#else
+        itoa(expr.GetInt32(), m_useConv, 10);
+#endif
+        m_expr.Append(m_useConv, strlen(m_useConv));
+    }
+    else
+        m_expr.Append("null", 4);
 }
 
 void SltExpressionTranslator::ProcessInt64Value(FdoInt64Value& expr)
 {
-    m_expr.Append(expr.ToString());
+    if (!expr.IsNull())
+    {
+#ifdef _WIN32
+        _i64toa_s(expr.GetInt64(), m_useConv, 256, 10);
+#else
+        sprintf(m_useConv, 256, "%lld", expr.GetInt64());
+#endif
+        m_expr.Append(m_useConv, strlen(m_useConv));
+    }
+    else
+        m_expr.Append("null", 4);
 }
 
 void SltExpressionTranslator::ProcessSingleValue(FdoSingleValue& expr)
 {
-    m_expr.Append(expr.ToString());
+    if (!expr.IsNull())
+    {
+#ifdef _WIN32
+        _snprintf(m_useConv, 256, "%f", expr.GetSingle());
+#else
+        sprintf(m_useConv, 256, "%f", expr.GetSingle());
+#endif
+        EnsureNoIsLocalIndep(m_useConv);
+        m_expr.Append(m_useConv, strlen(m_useConv));
+    }
+    else
+        m_expr.Append("null", 4);
 }
 
 void SltExpressionTranslator::ProcessStringValue(FdoStringValue& expr)
 {
-    m_expr.Append(expr.ToString());
+    if (!expr.IsNull())
+        m_expr.AppendSQuoted(expr.GetString());
+    else
+        m_expr.Append("null", 4);
 }
 
 void SltExpressionTranslator::ProcessBLOBValue(FdoBLOBValue& expr)

Modified: trunk/Providers/SQLite/Src/Provider/SltQueryTranslator.h
===================================================================
--- trunk/Providers/SQLite/Src/Provider/SltQueryTranslator.h	2009-07-26 00:53:36 UTC \
                (rev 4861)
+++ trunk/Providers/SQLite/Src/Provider/SltQueryTranslator.h	2009-07-27 15:52:22 UTC \
(rev 4862) @@ -201,6 +201,8 @@
 
     // list used to destroy the allocated objects at the end
     FilterChunkList             m_allocatedObjects;
+    // used as cache string operations
+    StringBuffer                m_sb;
 };
 
 //Translates an FDO Expression to a SQLite expression
@@ -210,8 +212,10 @@
 
 public:
 
-    SltExpressionTranslator()
-    {}
+    SltExpressionTranslator(FdoIdentifierCollection* props = NULL)
+    {
+        m_props = FDO_SAFE_ADDREF(props);
+    }
     ~SltExpressionTranslator()
     {}
 
@@ -254,8 +258,9 @@
     void Reset() { m_expr.Reset(); }
 
 private:
-    
+    FdoPtr<FdoIdentifierCollection> m_props;
     StringBuffer m_expr;
+    char m_useConv[256];
 };
 
 //Helper class used at spatial context and count queries

Modified: trunk/Providers/SQLite/Src/Provider/SltReader.cpp
===================================================================
--- trunk/Providers/SQLite/Src/Provider/SltReader.cpp	2009-07-26 00:53:36 UTC (rev \
                4861)
+++ trunk/Providers/SQLite/Src/Provider/SltReader.cpp	2009-07-27 15:52:22 UTC (rev \
4862) @@ -199,7 +199,7 @@
 	//so that he sees the properties he asked for. 
 	if (props && props->GetCount())
 	{
-        SltExpressionTranslator exTrans;
+        SltExpressionTranslator exTrans(props);
 		int nProps = props->GetCount();
         m_reissueProps.Reserve(nProps);
 		for (int i=0; i<nProps; i++)

Modified: trunk/Providers/SQLite/Src/Provider/StringUtil.h
===================================================================
--- trunk/Providers/SQLite/Src/Provider/StringUtil.h	2009-07-26 00:53:36 UTC (rev \
                4861)
+++ trunk/Providers/SQLite/Src/Provider/StringUtil.h	2009-07-27 15:52:22 UTC (rev \
4862) @@ -168,6 +168,31 @@
         Append(tmp);
     }
 
+    // used to format values like 12.34
+    void Append(double value, const char* format)
+    {
+        char tmp[64];
+        _snprintf(tmp, 32, format, value);
+        EnsureNoIsLocalIndep(tmp);
+        Append(tmp);
+    }
+    
+    // used to format values like 09
+    void Append(int value, const char* format)
+    {
+        char tmp[32];
+        _snprintf(tmp, 32, format, value);
+        Append(tmp);
+    }
+    
+    // used to format values like (result is 2009 and we need 09)
+    void Append(int value, const char* format, int startIdx)
+    {
+        char tmp[32];
+        _snprintf(tmp, 32, format, value);
+        Append(tmp+startIdx);
+    }
+    
     //append a string of unknown length
     inline void Append(const char* str)
     {

Modified: trunk/Providers/SQLite/Src/Provider/stdafx.h
===================================================================
--- trunk/Providers/SQLite/Src/Provider/stdafx.h	2009-07-26 00:53:36 UTC (rev 4861)
+++ trunk/Providers/SQLite/Src/Provider/stdafx.h	2009-07-27 15:52:22 UTC (rev 4862)
@@ -73,6 +73,7 @@
   #define __forceinline __inline__
   #define __fastcall 
   #define _wcsdup wcsdup
+  #define _strnicmp strncasecmp
   #define _strdup strdup
   #define _snprintf snprintf
   #define _wcsicmp wcscasecmp

Modified: trunk/Providers/SQLite/Src/UnitTest/FdoExpressionFunctionTest.cpp
===================================================================
--- trunk/Providers/SQLite/Src/UnitTest/FdoExpressionFunctionTest.cpp	2009-07-26 \
                00:53:36 UTC (rev 4861)
+++ trunk/Providers/SQLite/Src/UnitTest/FdoExpressionFunctionTest.cpp	2009-07-27 \
15:52:22 UTC (rev 4862) @@ -26,9 +26,11 @@
 
 #ifdef _WIN32
 static const wchar_t* EXPFCT_TEST_FILE = L"..\\..\\TestData\\ExpFctTest.slt";
+static const wchar_t* SC_TEST_FILE = L"..\\..\\TestData\\ExpressionsTest.slt";
 #else
 #include <unistd.h>
 static const wchar_t* EXPFCT_TEST_FILE = L"../../TestData/ExpFctTest.slt";
+static const wchar_t* SC_TEST_FILE = L"../../TestData/ExpressionsTest.slt";
 #endif
 
 CPPUNIT_TEST_SUITE_REGISTRATION(FdoExpressionFunctionTest);
@@ -91,6 +93,7 @@
     try {
 
       TestXYZMFunction();
+      TestDateStringConv();
 
     }  //  try ...
 
@@ -110,3 +113,136 @@
     return GetNaNOrdinate();
 }
 
+void FdoExpressionFunctionTest::TestDateStringConv()
+{
+    FdoPtr<FdoIConnection> conn;
+
+    try
+    {
+		conn = UnitTestUtil::OpenConnection( SC_TEST_FILE, true, true);
+		 
+        //apply schema
+		FdoPtr<FdoIApplySchema> applyschema = \
static_cast<FdoIApplySchema*>(conn->CreateCommand(FdoCommandType_ApplySchema)); +     \
FdoPtr<FdoFeatureSchemaCollection> schColl = \
FdoFeatureSchemaCollection::Create(NULL); +        \
schColl->ReadXml(L"SchPKTest.xml"); +        CPPUNIT_ASSERT(schColl->GetCount() == \
1); +        
+        FdoPtr<FdoFeatureSchema> schema = schColl->GetItem(0);
+		applyschema->SetFeatureSchema(schema);
+		applyschema->Execute();
+
+        FdoPtr<FdoIInsert> insCmd = \
static_cast<FdoIInsert*>(conn->CreateCommand(FdoCommandType_Insert)); +        \
FdoPtr<FdoPropertyValueCollection> vals = insCmd->GetPropertyValues(); +        \
FdoPtr<FdoPropertyValue> propIns; +        
+		FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
+		double coords[] = { 7.2068, 43.7556, 
+							77.2088, 43.7556, 
+							77.2088, 143.7574, 
+							7.2068, 143.7574, 
+							7.2068, 43.7556 }; 
+		FdoPtr<FdoILinearRing> outer = gf->CreateLinearRing(0, 10, coords);
+		FdoPtr<FdoIPolygon> poly = gf->CreatePolygon(outer, NULL);
+		FdoPtr<FdoByteArray> polyfgf = gf->GetFgf(poly);
+		FdoPtr<FdoGeometryValue> gv = FdoGeometryValue::Create(polyfgf);
+
+        FdoPtr<FdoPropertyValue> propGeomIns = FdoPropertyValue::Create(L"Geometry", \
gv); +        // insert test
+        insCmd->SetFeatureClassName(L"TestCompPK");
+        try
+        {
+            FdoDateTime dt(2005, 1, 22, 8, 5, 1.0);
+            FdoPtr<FdoDateTimeValue> dtValue = FdoDateTimeValue::Create(dt);
+            propIns = FdoPropertyValue::Create(L"PropDT", dtValue);
+            
+            FdoPtr<FdoInt64Value> id64Value = FdoInt64Value::Create(1);
+            FdoPtr<FdoPropertyValue> propInsId64 = \
FdoPropertyValue::Create(L"FeatId", id64Value); +            
+            FdoPtr<FdoStringValue> idStrValue = FdoStringValue::Create(L"city");
+            FdoPtr<FdoPropertyValue> propInsIdStr = \
FdoPropertyValue::Create(L"Name", idStrValue); +            
+            vals->Clear();
+            vals->Add(propIns);
+            vals->Add(propInsId64);
+            vals->Add(propInsIdStr);
+            vals->Add(propGeomIns);
+            FdoPtr<FdoIFeatureReader> rdr = insCmd->Execute();
+            CPPUNIT_ASSERT(rdr->ReadNext());
+            FdoPtr<FdoClassDefinition> clsrdr = rdr->GetClassDefinition();
+            CPPUNIT_ASSERT(rdr->GetInt64(L"FeatId") == 1);
+            CPPUNIT_ASSERT(((FdoStringP)rdr->GetString(L"Name")) == L"city");
+            
+            rdr->Close();
+        }
+        catch(FdoException* exc)
+        {
+            UnitTestUtil::PrintException(exc);
+            exc->Release();
+            CPPUNIT_FAIL("\nUnexpected exception: ");
+        }
+
+        try
+        {
+            FdoPtr<FdoISelect> select = \
(FdoISelect*)conn->CreateCommand(FdoCommandType_Select);  +	        \
select->SetFeatureClassName(L"TestCompPK"); +            FdoPtr<FdoFilter> filter = \
FdoFilter::Parse(L"PropDT IN ( TIMESTAMP '2005-01-22 08:05:01', TIMESTAMP '2009-07-10 \
22:57:56')"); +
+            select->SetFilter(filter);
+            FdoPtr<FdoIdentifierCollection> selColl = select->GetPropertyNames();
+            
+            FdoPtr<FdoExpression> exp = FdoExpression::Parse(L"ToString ( PropDT, \
'DD [Day] Month-YY' )"); +            FdoPtr<FdoIdentifier> idfCalc = \
FdoComputedIdentifier::Create(L"Calc", exp); +            selColl->Add(idfCalc);
+            
+            FdoPtr<FdoExpression> exp2 = FdoExpression::Parse(L"ToDate ( Calc, 'DD \
[Day] Month-YY' )"); +            FdoPtr<FdoIdentifier> idfCalc2 = \
FdoComputedIdentifier::Create(L"Calc2", exp2); +            selColl->Add(idfCalc2);
+            
+            FdoPtr<FdoIFeatureReader> rdr = select->Execute();
+            while(rdr->ReadNext())
+            {
+                if (!rdr->IsNull(L"Calc"))
+                {
+                    FdoString* val = rdr->GetString(L"Calc");
+                    printf ("Calc=%ls\n", val);
+                }
+                if (!rdr->IsNull(L"Calc2"))
+                {
+                    FdoDateTime dt = rdr->GetDateTime(L"Calc2");
+                    printf ("Calc2[year] = %d\n", dt.year);
+                }
+            }
+            FdoPtr<FdoClassDefinition> clsrdr = rdr->GetClassDefinition();
+            FdoPtr<FdoPropertyDefinitionCollection> rdrProps = \
clsrdr->GetProperties(); +            rdr->Close();
+
+            filter = FdoFilter::Parse(L"PropDT >= TIMESTAMP '2004-01-22 08:05:01'");
+            select->SetFilter(filter);
+            rdr = select->Execute();
+            CPPUNIT_ASSERT(rdr->ReadNext());
+            rdr->Close();
+
+            filter = FdoFilter::Parse(L"PropDT >= TIMESTAMP '2009-01-22 08:05:01'");
+            select->SetFilter(filter);
+            rdr = select->Execute();
+            CPPUNIT_ASSERT(!rdr->ReadNext());
+            rdr->Close();
+        }
+        catch(FdoException* exc)
+        {
+            UnitTestUtil::PrintException(exc);
+            exc->Release();
+            CPPUNIT_FAIL("\nUnexpected exception: ");
+        }
+
+    }
+	catch ( CppUnit::Exception e ) 
+	{
+		throw;
+	}
+   	catch (...)
+   	{
+   		CPPUNIT_FAIL ("caught unexpected exception");
+   	}
+	printf( "Done\n" );
+}

Modified: trunk/Providers/SQLite/Src/UnitTest/FdoExpressionFunctionTest.h
===================================================================
--- trunk/Providers/SQLite/Src/UnitTest/FdoExpressionFunctionTest.h	2009-07-26 \
                00:53:36 UTC (rev 4861)
+++ trunk/Providers/SQLite/Src/UnitTest/FdoExpressionFunctionTest.h	2009-07-27 \
15:52:22 UTC (rev 4862) @@ -54,6 +54,8 @@
 
     virtual double GetNullOrdinate();
 
+    void TestDateStringConv();
+
 };  //  class FdoExpressionFunctionTest
 
 #endif

_______________________________________________
fdo-commits mailing list
fdo-commits@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/fdo-commits


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic