]> granicus.if.org Git - postgresql/commitdiff
Moved Informix stuff to its own compat library. Interval datetype is now fully functi...
authorMichael Meskes <meskes@postgresql.org>
Sun, 30 Mar 2003 11:48:19 +0000 (11:48 +0000)
committerMichael Meskes <meskes@postgresql.org>
Sun, 30 Mar 2003 11:48:19 +0000 (11:48 +0000)
14 files changed:
src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/Makefile
src/interfaces/ecpg/ecpglib/execute.c
src/interfaces/ecpg/include/ecpg_informix.h
src/interfaces/ecpg/include/pgtypes_date.h
src/interfaces/ecpg/include/pgtypes_error.h
src/interfaces/ecpg/include/pgtypes_numeric.h
src/interfaces/ecpg/pgtypeslib/Makefile
src/interfaces/ecpg/pgtypeslib/datetime.c
src/interfaces/ecpg/pgtypeslib/dt.h
src/interfaces/ecpg/pgtypeslib/dt_common.c
src/interfaces/ecpg/pgtypeslib/numeric.c
src/interfaces/ecpg/pgtypeslib/timestamp.c
src/interfaces/ecpg/test/dt_test.pgc

index 77ab60c2b3c0c984cf2eaaa12303cc3d43d3da7a..321bd3a63c6d3b8909f1557ac7e7dbeb693a668f 100644 (file)
@@ -1376,7 +1376,17 @@ Thu Mar 27 15:23:58 CET 2003
        - Some more updates to pgtypeslib.
        - Set optimization to -O1 until I find the reason why code is broken
          with -O2.
+
+Sat Mar 29 22:03:16 CET 2003
+
+       - Moved Informix compatibility stuff its own library.
+       - Added interval datetypes.
+
+Sun Mar 30 13:43:13 CEST 2003
+
+       - Interval datetype now fully functional.
        - Set ecpg version to 2.12.0.
        - Set ecpg library to 3.4.2.
        - Set pgtypes library to 1.0.0
+       - Set compat library to 1.0.0
 
index 50b97bc2d59b5bfcfab73b3e4f63128fbc220940..74286ce6ece54a662322801e0c6733d486a8fc68 100644 (file)
@@ -6,11 +6,13 @@ all install installdirs uninstall dep depend distprep:
        $(MAKE) -C include $@
        $(MAKE) -C ecpglib $@
        $(MAKE) -C pgtypeslib $@
+       $(MAKE) -C compatlib $@
        $(MAKE) -C preproc $@
 
 clean distclean maintainer-clean:
        -$(MAKE) -C include $@
        -$(MAKE) -C ecpglib $@
        -$(MAKE) -C pgtypeslib $@
+       -$(MAKE) -C compatlib $@
        -$(MAKE) -C preproc $@
        -$(MAKE) -C test clean
index a1e0f5456b4dfddfdb7d2a0fed0b7f4b3a40f610..6a9b38e7a884048239c40f2d7512ed74459138a1 100644 (file)
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.6 2003/03/27 14:29:17 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.7 2003/03/30 11:48:18 meskes Exp $ */
 
 /*
  * The aim is to get a simpler inteface to the database routines.
@@ -847,7 +847,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
                                        {
                                                for (element = 0; element < var->arrsize; element++)
                                                {
-                                                       str = PGTYPESnumeric_ntoa((Numeric *)((var + var->offset * element)->value));
+                                                       str = PGTYPESnumeric_ntoa((Numeric *)((var + var->offset * element)->value), 0);
                                                        slen = strlen (str);
                                                        
                                                        if (!(mallocedval = ECPGrealloc(mallocedval, strlen(mallocedval) + slen + 5, stmt->lineno)))
@@ -863,7 +863,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
                                        }
                                        else
                                        {
-                                               str = PGTYPESnumeric_ntoa((Numeric *)(var->value));
+                                               str = PGTYPESnumeric_ntoa((Numeric *)(var->value), 0);
                                                slen = strlen (str);
                                        
                                                if (!(mallocedval = ECPGalloc(slen + 1, stmt->lineno)))
@@ -1239,7 +1239,9 @@ ECPGexecute(struct statement * stmt)
        {
                ECPGlog("ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
                                stmt->lineno, notify->relname, notify->be_pid);
-               PQfreemem(notify);
+/*             PQfreemem(notify);*/
+               free(notify);
+#warning Remove PQfreemem define
        }
 
        return status;
index 3d39c90b02be8b53a75034826d41539c732b4bb9..46df5a2d32a73bbce161a85078b0f7768adb3ecf 100644 (file)
@@ -2,6 +2,9 @@
  * This file contains stuff needed to be as compatible to Informix as possible.
  */
 
+#include <decimal.h>
+#include <datetime.h>
+
 #define SQLNOTFOUND 100
 
 #ifndef Date
index 882ddab82df7952763a2dc84613586d2c1495c48..76dedb866cf20aba8e1bac8084015c9327158927 100644 (file)
@@ -1,12 +1,17 @@
 #ifndef PGTYPES_DATETIME
 #define PGTYPES_DATETIME
 
+#include <pgtypes_timestamp.h>
+
 #define Date long
 
 extern Date PGTYPESdate_atod(char *, char **);
 extern char *PGTYPESdate_dtoa(Date);
-extern int PGTYPESdate_julmdy(Date, int*);
-extern int PGTYPESdate_mdyjul(int*, Date *);
-extern int PGTYPESdate_day(Date);
-
+extern Date PGTYPESdate_ttod(Timestamp);
+extern void PGTYPESdate_julmdy(Date, int*);
+extern void PGTYPESdate_mdyjul(int*, Date *);
+extern int PGTYPESdate_dayofweek(Date);
+extern void PGTYPESdate_today (Date *);
+extern int PGTYPESdate_defmtdate(Date *, char *, char *);
+extern int PGTYPESdate_fmtdate(Date, char *, char *);
 #endif /* PGTYPES_DATETIME */
index 7cab1971b98960fd7dc4ffddabd16f2cf20ec462..2965a01476e2a60e14711df30a664662181e699e 100644 (file)
@@ -1,8 +1,15 @@
-#define        PGTYPES_OVERFLOW        201
-#define PGTYPES_BAD_NUMERIC    202
-#define PGTYPES_DIVIDE_ZERO    203
+#define        PGTYPES_NUM_OVERFLOW            201
+#define PGTYPES_NUM_BAD_NUMERIC                202
+#define PGTYPES_NUM_DIVIDE_ZERO                203
 
-#define PGTYPES_BAD_DATE       210
+#define PGTYPES_DATE_BAD_DATE          210
+#define PGTYPES_DATE_ERR_EARGS         211
+#define PGTYPES_DATE_ERR_ENOSHORTDATE  212
+#define PGTYPES_DATE_ERR_ENOTDMY       213
+#define PGTYPES_DATE_BAD_DAY           214
+#define PGTYPES_DATE_BAD_MONTH         215
 
-#define PGTYPES_BAD_TIMESTAMP  220
+#define PGTYPES_TS_BAD_TIMESTAMP       220
+
+#define PGTYPES_INTVL_BAD_INTERVAL     230
 
index 3fe849a3ad9730e76428b24f87f857c5ef91ecd7..977233afca0daafb8f7af63edf27e2d4c4d601be 100644 (file)
@@ -23,7 +23,7 @@ typedef struct
 Numeric *PGTYPESnew(void);
 void PGTYPESnumeric_free(Numeric *);
 Numeric *PGTYPESnumeric_aton(char *, char **);
-char *PGTYPESnumeric_ntoa(Numeric *);
+char *PGTYPESnumeric_ntoa(Numeric *, int);
 int PGTYPESnumeric_add(Numeric *, Numeric *, Numeric *);
 int PGTYPESnumeric_sub(Numeric *, Numeric *, Numeric *);
 int PGTYPESnumeric_mul(Numeric *, Numeric *, Numeric *);
index 97d8cbb24ea91f69af2a44423df06de73d825287..5a9e66408e56a803c38258d5116d7b1b34cc9308 100644 (file)
@@ -4,7 +4,7 @@
 #
 # Copyright (c) 1994, Regents of the University of California
 #
-# $Header: /cvsroot/pgsql/src/interfaces/ecpg/pgtypeslib/Makefile,v 1.3 2003/03/27 14:29:17 meskes Exp $
+# $Header: /cvsroot/pgsql/src/interfaces/ecpg/pgtypeslib/Makefile,v 1.4 2003/03/30 11:48:18 meskes Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -18,7 +18,7 @@ SO_MINOR_VERSION= 0.0
 
 override CPPFLAGS := -O1 -g -I$(top_srcdir)/src/interfaces/ecpg/include -I$(top_srcdir)/src/include/utils $(CPPFLAGS)
 
-OBJS= numeric.o datetime.o common.o dt_common.o timestamp.o
+OBJS= numeric.o datetime.o common.o dt_common.o timestamp.o interval.o
 
 all: all-lib
 
index 4bd5c1051796ef58cc965d3e91646278507effd0..fbc55462bf39c75ba4d2394547fa60b6b5c4be7b 100644 (file)
@@ -9,7 +9,31 @@
 #include "extern.h"
 #include "pgtypes_error.h"
 #include "pgtypes_date.h"
-#include "ecpg_informix.h"
+
+/* XXX: currently not used.
+ * pgsql: timestamp_date()
+ * Convert timestamp to date data type.
+ */
+Date
+PGTYPESdate_ttod(Timestamp dt)
+{
+       Date            dDate;
+
+       dDate = 0; /* suppress compiler warning */
+
+       if (TIMESTAMP_NOT_FINITE(dt))
+               return 
+
+#ifdef HAVE_INT64_TIMESTAMP
+       /* Microseconds to days */
+       dDate = (dt / INT64CONST(86400000000));
+#else
+       /* Seconds to days */
+       dDate = (dt / 86400.0);
+#endif
+
+       return dDate;
+}
 
 Date
 PGTYPESdate_atod(char *str, char **endptr)
@@ -32,14 +56,14 @@ PGTYPESdate_atod(char *str, char **endptr)
 
        if (strlen(str) >= sizeof(lowstr))
        {
-               errno = PGTYPES_BAD_DATE;
+               errno = PGTYPES_DATE_BAD_DATE;
                return -1;
        }
 
        if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf, ptr) != 0)
         || (DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tzp, EuroDates) != 0))
        {
-               errno = PGTYPES_BAD_DATE;
+               errno = PGTYPES_DATE_BAD_DATE;
                return -1;
        }
 
@@ -53,7 +77,7 @@ PGTYPESdate_atod(char *str, char **endptr)
                        break;
 
                default:
-                       errno = PGTYPES_BAD_DATE;
+                       errno = PGTYPES_DATE_BAD_DATE;
                        return -1;
        }
 
@@ -75,74 +99,521 @@ PGTYPESdate_dtoa(Date dDate)
        return pgtypes_strdup(buf);
 }
 
-int
+void
 PGTYPESdate_julmdy(Date jd, int* mdy)
 {
-       printf("day: %d\n", mdy[0]);
-       printf("month: %d\n", mdy[1]);
-       printf("year: %d\n", mdy[2]);
-       j2date((int) jd, mdy+2, mdy+1, mdy+0);
-       return 0;
+       int y, m, d;
+       
+       j2date((int) jd, &y, &m, &d);
+       mdy[0] = (short int) m;
+       mdy[1] = (short int) d;
+       mdy[2] = (short int) y;
 }
 
-int
+void
 PGTYPESdate_mdyjul(int* mdy, Date *jdate)
 {
        /* month is mdy[0] */
        /* day   is mdy[1] */
        /* year  is mdy[2] */
-       printf("day: %d\n", mdy[1]);
-       printf("month: %d\n", mdy[0]);
-       printf("year: %d\n", mdy[2]);
-       *jdate = (Date) date2j(mdy[2], mdy[0], mdy[1]);
-       return 0;
-}
 
-int
-PGTYPESdate_day(Date dDate)
-{
-       return j2day(dDate);
+       *jdate = (Date) date2j(mdy[2], mdy[0], mdy[1]);
 }
 
 int
-rdatestr (Date d, char *str)
+PGTYPESdate_dayofweek(Date dDate)
 {
-       return 0;
+       /*
+            Sunday:      0
+            Monday:      1
+            Tuesday:     2
+            Wednesday:   3
+            Thursday:    4
+            Friday:      5
+            Saturday:    6
+       */
+       return 6-j2day(dDate+3);
 }
 
 void
-rtoday (Date *d)
+PGTYPESdate_today (Date *d)
 {
+       struct tm       ts;
+
+       GetCurrentDateTime(&ts);
+       *d = date2j(ts.tm_year, ts.tm_mon, ts.tm_mday) - date2j(2000, 1, 1);
        return;
 }
 
-int
-rjulmdy (Date d, short mdy[3])
-{
-       return 0;
-}
+#define PGTYPES_DATE_NUM_MAX_DIGITS            20 /* should suffice for most years... */
 
-int
-rdefmtdate (Date *d, char *fmt, char *str)
-{
-       return 0;
-}
+#define PGTYPES_FMTDATE_DAY_DIGITS_LZ          1  /* LZ means "leading zeroes" */
+#define PGTYPES_FMTDATE_DOW_LITERAL_SHORT      2
+#define PGTYPES_FMTDATE_MONTH_DIGITS_LZ                3
+#define PGTYPES_FMTDATE_MONTH_LITERAL_SHORT    4
+#define PGTYPES_FMTDATE_YEAR_DIGITS_SHORT      5
+#define PGTYPES_FMTDATE_YEAR_DIGITS_LONG       6
 
-int
-rfmtdate (Date d, char *fmt, char *str)
-{
-       return 0;
-}
+static char* pgtypes_date_weekdays_short[] = {"Sun", "Mon", "Tue", "Wed",
+       "Thu", "Fri", "Sat", NULL};
+
+static char* pgtypes_date_months[] = {"January", "February", "March", "April", "May", "June",
+       "July", "August", "September", "October", "November", "December", NULL};
+static char* pgtypes_date_months_short[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+       "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL};
 
 int
-rmdyjul (short mdy[3], Date *d)
-{
+PGTYPESdate_fmtdate(Date dDate, char* fmtstring, char* outbuf) {
+       static struct {
+               char* format;
+               int component;
+       } mapping[] = {
+               /* format items have to be sorted according to their length,
+                * since the first pattern that matches gets replaced by its
+                * value */
+                        {"ddd",  PGTYPES_FMTDATE_DOW_LITERAL_SHORT   },
+                        {"dd",   PGTYPES_FMTDATE_DAY_DIGITS_LZ       },
+                        {"mmm",  PGTYPES_FMTDATE_MONTH_LITERAL_SHORT },
+                        {"mm",   PGTYPES_FMTDATE_MONTH_DIGITS_LZ     },
+                        {"yyyy", PGTYPES_FMTDATE_YEAR_DIGITS_LONG    },
+                        {"yy",   PGTYPES_FMTDATE_YEAR_DIGITS_SHORT   },
+                        { NULL, 0 }
+       };
+
+
+/* These are the constants that decide which printf() format we'll use in
+ * order to get a string representation of the value */
+#define PGTYPES_DATE_REPLACE_STRING_MALLOCED   1
+#define PGTYPES_DATE_REPLACE_STRING_CONSTANT   2
+#define PGTYPES_DATE_REPLACE_UINT              3
+#define PGTYPES_DATE_REPLACE_UINT_2_LZ         4
+#define PGTYPES_DATE_REPLACE_UINT_4_LZ         5
+
+       union {
+               char* replace_str;
+               unsigned int replace_uint;
+       } replace_val;
+       int replace_type;
+
+       int i;
+       int dow;
+       char* start_pattern;
+       struct tm tm;
+
+       /* XXX error handling ? */
+       /* copy the string over */
+       strcpy(outbuf, fmtstring);
+
+       /* get the date */
+       j2date((dDate + date2j(2000, 1, 1)), &(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday));
+       dow = PGTYPESdate_dayofweek(dDate);
+
+       for (i = 0; mapping[i].format != NULL; i++) {
+               while ((start_pattern = strstr(outbuf, mapping[i].format)) != NULL) {
+                       switch(mapping[i].component) {
+                               case PGTYPES_FMTDATE_DOW_LITERAL_SHORT:
+                                       replace_val.replace_str = pgtypes_date_weekdays_short[dow];
+                                       replace_type = PGTYPES_DATE_REPLACE_STRING_CONSTANT;
+                                       break;
+                               case PGTYPES_FMTDATE_DAY_DIGITS_LZ:
+                                       replace_val.replace_uint = tm.tm_mday;
+                                       replace_type = PGTYPES_DATE_REPLACE_UINT_2_LZ;
+                                       break;
+                               case PGTYPES_FMTDATE_MONTH_LITERAL_SHORT:
+                                       replace_val.replace_str = pgtypes_date_months_short[tm.tm_mon-1];
+                                       replace_type = PGTYPES_DATE_REPLACE_STRING_CONSTANT;
+                                       break;
+                               case PGTYPES_FMTDATE_MONTH_DIGITS_LZ:
+                                       replace_val.replace_uint = tm.tm_mon;
+                                       replace_type = PGTYPES_DATE_REPLACE_UINT_2_LZ;
+                                       break;
+                               case PGTYPES_FMTDATE_YEAR_DIGITS_LONG:
+                                       replace_val.replace_uint = tm.tm_year;
+                                       replace_type = PGTYPES_DATE_REPLACE_UINT_4_LZ;
+                                       break;
+                               case PGTYPES_FMTDATE_YEAR_DIGITS_SHORT:
+                                       replace_val.replace_uint = tm.tm_year % 1000;
+                                       replace_type = PGTYPES_DATE_REPLACE_UINT_2_LZ;
+                                       break;
+                               default:
+                                       /* should not happen, set something
+                                        * anyway */
+                                       replace_val.replace_str = " ";
+                                       replace_type = PGTYPES_DATE_REPLACE_STRING_CONSTANT;
+                       }
+                       switch(replace_type) {
+                               case PGTYPES_DATE_REPLACE_STRING_MALLOCED:
+                               case PGTYPES_DATE_REPLACE_STRING_CONSTANT:
+                                       strncpy(start_pattern, replace_val.replace_str,
+                                                       strlen(replace_val.replace_str));
+                                       if (replace_type == PGTYPES_DATE_REPLACE_STRING_MALLOCED) {
+                                               free(replace_val.replace_str);
+                                       }
+                                       break;
+                               case PGTYPES_DATE_REPLACE_UINT:
+                                       {
+                                               char* t = pgtypes_alloc(PGTYPES_DATE_NUM_MAX_DIGITS);
+                                               if (!t) {
+                                                       return -1;
+                                               }
+                                               snprintf(t, PGTYPES_DATE_NUM_MAX_DIGITS,
+                                                               "%u", replace_val.replace_uint);
+                                               strncpy(start_pattern, t, strlen(t));
+                                               free(t);
+                                       }
+                                       break;
+                               case PGTYPES_DATE_REPLACE_UINT_2_LZ:
+                                       {
+                                               char* t = pgtypes_alloc(PGTYPES_DATE_NUM_MAX_DIGITS);
+                                               if (!t) {
+                                                       return -1;
+                                               }
+                                               snprintf(t, PGTYPES_DATE_NUM_MAX_DIGITS,
+                                                               "%02u", replace_val.replace_uint);
+                                               strncpy(start_pattern, t, strlen(t));
+                                               free(t);
+                                       }
+                                       break;
+                               case PGTYPES_DATE_REPLACE_UINT_4_LZ:
+                                       {
+                                               char* t = pgtypes_alloc(PGTYPES_DATE_NUM_MAX_DIGITS);
+                                               if (!t) {
+                                                       return -1;
+                                               }
+                                               snprintf(t, PGTYPES_DATE_NUM_MAX_DIGITS,
+                                                               "%04u", replace_val.replace_uint);
+                                               strncpy(start_pattern, t, strlen(t));
+                                               free(t);
+                                       }
+                                       break;
+                               default:
+                                       /* doesn't happen (we set
+                                        * replace_type to
+                                        * PGTYPES_DATE_REPLACE_STRING_CONSTANT
+                                        * in case of an error above) */
+                                       break;
+                       }
+               }
+       }
        return 0;
 }
 
+
+/*
+ * PGTYPESdate_rdefmtdate
+ *
+ * function works as follows:
+ *   - first we analyze the paramters
+ *   - if this is a special case with no delimiters, add delimters
+ *   - find the tokens. First we look for numerical values. If we have found
+ *     less than 3 tokens, we check for the months' names and thereafter for
+ *     the abbreviations of the months' names.
+ *   - then we see which parameter should be the date, the month and the
+ *     year and from these values we calculate the date
+ */
+
+#define PGTYPES_DATE_MONTH_MAXLENGTH           20  /* probably even less  :-) */
 int
-rstrdate (char *str, Date *d)
+PGTYPESdate_defmtdate(Date *d, char *fmt, char *str)
 {
+       /* token[2] = { 4,6 } means that token 2 starts at
+        * position 4 and ends at (including) position 6 */
+       int token[3][2];
+       int token_values[3] = { -1, -1, -1 };
+       char* fmt_token_order;
+       char* fmt_ystart, *fmt_mstart, *fmt_dstart;
+       int i;
+       int reading_digit;
+       int token_count;
+       char* str_copy;
+       struct tm tm;
+
+       if (!d || !str || !fmt) {
+               errno = PGTYPES_DATE_ERR_EARGS;
+               return -1;
+       }
+
+       /* analyze the fmt string */
+       fmt_ystart = strstr(fmt, "yy");
+       fmt_mstart = strstr(fmt, "mm");
+       fmt_dstart = strstr(fmt, "dd");
+
+       if (!fmt_ystart || !fmt_mstart || !fmt_dstart) {
+               errno = PGTYPES_DATE_ERR_EARGS;
+               return -1;
+       }
+
+       if (fmt_ystart < fmt_mstart) {
+               /* y m */
+               if (fmt_dstart < fmt_ystart) {
+                       /* d y m */
+                       fmt_token_order = "dym";
+               } else if (fmt_dstart > fmt_mstart) {
+                       /* y m d */
+                       fmt_token_order = "ymd";
+               } else {
+                       /* y d m */
+                       fmt_token_order = "ydm";
+               }
+       } else {
+               /* fmt_ystart > fmt_mstart */
+               /* m y */
+               if (fmt_dstart < fmt_mstart) {
+                       /* d m y */
+                       fmt_token_order = "dmy";
+               } else if (fmt_dstart > fmt_ystart) {
+                       /* m y d */
+                       fmt_token_order = "myd";
+               } else {
+                       /* m d y */
+                       fmt_token_order = "mdy";
+               }
+       }
+
+       /* handle the special cases where there is no delimiter between the
+        * digits. If we see this:
+        *
+        * only digits, 6 or 8 bytes then it might be ddmmyy and ddmmyyyy
+        * (or similar)
+        *
+        * we reduce it to a string with delimiters and continue processing
+        * */
+
+       /* check if we have only digits */
+       reading_digit = 1;
+       for (i = 0; str[i]; i++) {
+               if (!isdigit(str[i])) {
+                       reading_digit = 0;
+                       break;
+               }
+       }
+       if (reading_digit) {
+               int frag_length[3];
+               int target_pos;
+
+               i = strlen(str);
+               if (i != 8 && i != 6) {
+                       errno = PGTYPES_DATE_ERR_ENOSHORTDATE;
+                       return -1;
+               }
+               /* okay, this really is the special case */
+
+               /* as long as the string, one additional byte for the
+                * terminator and 2 for the delimiters between the 3 fiedls
+                * */
+               str_copy = pgtypes_alloc(strlen(str) + 1 + 2);
+               if (!str_copy) {
+                       return -1;
+               }
+
+               /* determine length of the fragments */
+               if (i == 6) {
+                       frag_length[0] = 2; frag_length[1] = 2; frag_length[2] = 2;
+               } else {
+                       if (fmt_token_order[0] == 'y') {
+                               frag_length[0] = 4; frag_length[1] = 2; frag_length[2] = 2;
+                       } else if (fmt_token_order[1] == 'y') {
+                               frag_length[0] = 2; frag_length[1] = 4; frag_length[2] = 2;
+                       } else {
+                               frag_length[0] = 2; frag_length[1] = 2; frag_length[2] = 4;
+                       }
+               }
+               target_pos = 0;
+               /* XXX: Here we could calculate the positions of the tokens
+                * and save the for loop down there where we again check
+                * with isdigit() for digits. */
+               for (i = 0; i < 3; i++) {
+                       int start_pos = 0;
+                       if (i >= 1) { start_pos += frag_length[0]; }
+                       if (i == 2) { start_pos += frag_length[1]; }
+
+                       strncpy(str_copy + target_pos, str + start_pos,
+                                               frag_length[i]);
+                       target_pos += frag_length[i];
+                       if (i != 2) {
+                               str_copy[target_pos] = ' ';
+                               target_pos++;
+                       }
+               }
+               str_copy[target_pos] = '\0';
+       } else {
+               str_copy = pgtypes_strdup(str);
+               if (!str_copy) {
+                       return -1;
+               }
+
+               /* convert the whole string to lower case */
+               for (i = 0; str_copy[i]; i++) {
+                       str_copy[i] = (char) tolower(str_copy[i]);
+               }
+       }
+
+       /* look for numerical tokens */
+       reading_digit = 0;
+       token_count   = 0;
+       for (i = 0; i < strlen(str_copy); i++) {
+               if (!isdigit(str_copy[i]) && reading_digit) {
+                       /* the token is finished */
+                       token[token_count][1] = i-1;
+                       reading_digit = 0;
+                       token_count++;
+               } else if (isdigit(str_copy[i]) && !reading_digit) {
+                       /* we have found a token */
+                       token[token_count][0] = i;
+                       reading_digit = 1;
+               }
+       }
+       /* we're at the end of the input string, but maybe we are still reading a
+        * number... */
+       if (reading_digit) {
+               token[token_count][1] = i-1;
+               token_count++;
+       }
+
+
+       if (token_count < 2) {
+               /* not all tokens found, no way to find 2 missing tokens
+                * with string matches */
+               free(str_copy);
+               errno = PGTYPES_DATE_ERR_ENOTDMY;
+               return -1;
+       }
+
+       if (token_count != 3) {
+               /* not all tokens found but we may find another one with
+                * string matches by testing for the months names and months
+                * abbreviations */
+               char *month_lower_tmp = pgtypes_alloc(PGTYPES_DATE_MONTH_MAXLENGTH);
+               char *start_pos;
+               int j;
+               int offset;
+               int found = 0;
+               char** list;
+
+               if (!month_lower_tmp) {
+                       /* free variables we alloc'ed before */
+                       free(str_copy);
+                       return -1;
+               }
+               list = pgtypes_date_months;
+               for (i = 0; list[i]; i++) {
+                       for (j = 0; j < PGTYPES_DATE_MONTH_MAXLENGTH; j++) {
+                               month_lower_tmp[j] = (char) tolower(list[i][j]);
+                               if (!month_lower_tmp[j]) {
+                                       /* properly terminated */
+                                       break;
+                               }
+                       }
+                       if ((start_pos = strstr(str_copy, month_lower_tmp))) {
+                               offset = start_pos - str_copy;
+                               /* sort the new token into the numeric
+                                * tokens, shift them if necessary */
+                               if (offset < token[0][0]) {
+                                       token[2][0] = token[1][0];
+                                       token[2][1] = token[1][1];
+                                       token[1][0] = token[0][0];
+                                       token[1][1] = token[0][1];
+                                       token_count = 0;
+                               } else if (offset < token[1][0]) {
+                                       token[2][0] = token[1][0];
+                                       token[2][1] = token[1][1];
+                                       token_count = 1;
+                               } else {
+                                       token_count = 2;
+                               }
+                               token[token_count][0] = offset;
+                               token[token_count][1] = offset + strlen(month_lower_tmp) - 1;
+                               /* the value is the index of the month in
+                                * the array of months + 1 (January is month
+                                * 0) */
+                               token_values[token_count] = i+1;
+                               found = 1;
+                               break;
+                       }
+                       /* evil[tm] hack:
+                        * if we read the pgtypes_date_months and haven't
+                        * found a match, reset list to point to
+                        * pgtypes_date_months_short and reset the counter
+                        * variable i */
+                       if (list == pgtypes_date_months) {
+                               if (list[i+1] == NULL) {
+                                       list = pgtypes_date_months_short;
+                                       i = -1;
+                               }
+                       }
+               }
+               if (!found) {
+                       free(month_lower_tmp);
+                       free(str_copy);
+                       errno = PGTYPES_DATE_ERR_ENOTDMY;
+                       return -1;
+               }
+
+               /* here we found a month. token[token_count] and
+                * token_values[token_count] reflect the month's details.
+                *
+                * only the month can be specified with a literal. Here we can do a
+                * quick check if the month is at the right position according to
+                * the format string because we can check if the token that
+                * we expect to be the month is at the position of the only
+                * token that already has a value. If we wouldn't check here
+                * we could say "December 4 1990" with a fmt string of
+                * "dd mm yy" for 12 April 1990.
+                */
+               if (fmt_token_order[token_count] != 'm') {
+                       /* deal with the error later on */
+                       token_values[token_count] = -1;
+               }
+               free(month_lower_tmp);
+       }
+
+       /* terminate the tokens with ASCII-0 and get their values */
+       for (i = 0; i < 3; i++) {
+               *(str_copy + token[i][1] + 1) = '\0';
+               /* A month already has a value set, check for token_value == -1 */
+               if (token_values[i] == -1) {
+                       errno = 0;
+                       token_values[i] = strtol(str_copy + token[i][0], (char **) NULL, 10);
+                       /* strtol sets errno in case of an error */
+                       if (errno) {
+                               token_values[i] = -1;
+                       }
+               }
+               if (fmt_token_order[i] == 'd') {
+                       tm.tm_mday = token_values[i];
+               } else if (fmt_token_order[i] == 'm') {
+                       tm.tm_mon = token_values[i];
+               } else if (fmt_token_order[i] == 'y') {
+                       tm.tm_year = token_values[i];
+               }
+       }
+       free(str_copy);
+
+       if (tm.tm_mday < 1 || tm.tm_mday > 31)
+       {
+               errno = PGTYPES_DATE_BAD_DAY;
+               return -1;
+       }
+
+       if (tm.tm_mon < 1 || tm.tm_mon > 12)
+       {
+               errno = PGTYPES_DATE_BAD_MONTH;
+               return -1;
+       }
+
+       if (tm.tm_mday == 31 && (tm.tm_mon == 4 || tm.tm_mon == 6 || tm.tm_mon == 9 || tm.tm_mon ==11))
+       {
+               errno = PGTYPES_DATE_BAD_DAY;
+               return -1;
+       }
+
+       if (tm.tm_mon == 2 && tm.tm_mday > 29)
+       {
+               errno = PGTYPES_DATE_BAD_DAY;
+               return -1;
+       }
+
+       *d = date2j(tm.tm_year, tm.tm_mon, tm.tm_mday) - date2j(2000, 1, 1);
+
        return 0;
 }
-
index d20c0cd819d04f4806b4cb6e94aad7cc07eaf0c7..e2019af32e0736cc81079a410e22fc64700458a8 100644 (file)
@@ -296,6 +296,7 @@ extern void GetEpochTime(struct tm *);
 extern int ParseDateTime(char *, char *, char **, int *, int, int *, char **);
 extern int DecodeDateTime(char **, int *, int, int *, struct tm *, fsec_t *, int *, bool);
 extern void j2date(int, int *, int *, int *);
+extern void GetCurrentDateTime(struct tm*);
 extern int date2j(int, int, int);
 extern double rint(double x);
 
index 3b85f7df1526c8509790eb277d77a12860512138..2da16b14d4ad798326e63634d658cc3008ee191a 100644 (file)
@@ -426,10 +426,81 @@ static datetkn datetktbl[] = {
        {ZULU, TZ, POS(0)},                     /* UTC */
 };
 
+static datetkn deltatktbl[] = {
+       /* text, token, lexval */
+       {"@", IGNORE_DTF, 0},           /* postgres relative prefix */
+       {DAGO, AGO, 0},                         /* "ago" indicates negative time offset */
+       {"c", UNITS, DTK_CENTURY},      /* "century" relative */
+       {"cent", UNITS, DTK_CENTURY},           /* "century" relative */
+       {"centuries", UNITS, DTK_CENTURY},      /* "centuries" relative */
+       {DCENTURY, UNITS, DTK_CENTURY},         /* "century" relative */
+       {"d", UNITS, DTK_DAY},          /* "day" relative */
+       {DDAY, UNITS, DTK_DAY},         /* "day" relative */
+       {"days", UNITS, DTK_DAY},       /* "days" relative */
+       {"dec", UNITS, DTK_DECADE}, /* "decade" relative */
+       {DDECADE, UNITS, DTK_DECADE},           /* "decade" relative */
+       {"decades", UNITS, DTK_DECADE},         /* "decades" relative */
+       {"decs", UNITS, DTK_DECADE},    /* "decades" relative */
+       {"h", UNITS, DTK_HOUR},         /* "hour" relative */
+       {DHOUR, UNITS, DTK_HOUR},       /* "hour" relative */
+       {"hours", UNITS, DTK_HOUR}, /* "hours" relative */
+       {"hr", UNITS, DTK_HOUR},        /* "hour" relative */
+       {"hrs", UNITS, DTK_HOUR},       /* "hours" relative */
+       {INVALID, RESERV, DTK_INVALID},         /* reserved for invalid time */
+       {"m", UNITS, DTK_MINUTE},       /* "minute" relative */
+       {"microsecon", UNITS, DTK_MICROSEC},            /* "microsecond" relative */
+       {"mil", UNITS, DTK_MILLENNIUM},         /* "millennium" relative */
+       {"millennia", UNITS, DTK_MILLENNIUM},           /* "millennia" relative */
+       {DMILLENNIUM, UNITS, DTK_MILLENNIUM},           /* "millennium" relative */
+       {"millisecon", UNITS, DTK_MILLISEC},            /* relative */
+       {"mils", UNITS, DTK_MILLENNIUM},        /* "millennia" relative */
+       {"min", UNITS, DTK_MINUTE}, /* "minute" relative */
+       {"mins", UNITS, DTK_MINUTE},    /* "minutes" relative */
+       {DMINUTE, UNITS, DTK_MINUTE},           /* "minute" relative */
+       {"minutes", UNITS, DTK_MINUTE},         /* "minutes" relative */
+       {"mon", UNITS, DTK_MONTH},      /* "months" relative */
+       {"mons", UNITS, DTK_MONTH}, /* "months" relative */
+       {DMONTH, UNITS, DTK_MONTH}, /* "month" relative */
+       {"months", UNITS, DTK_MONTH},
+       {"ms", UNITS, DTK_MILLISEC},
+       {"msec", UNITS, DTK_MILLISEC},
+       {DMILLISEC, UNITS, DTK_MILLISEC},
+       {"mseconds", UNITS, DTK_MILLISEC},
+       {"msecs", UNITS, DTK_MILLISEC},
+       {"qtr", UNITS, DTK_QUARTER},    /* "quarter" relative */
+       {DQUARTER, UNITS, DTK_QUARTER},         /* "quarter" relative */
+       {"reltime", IGNORE_DTF, 0}, /* pre-v6.1 "Undefined Reltime" */
+       {"s", UNITS, DTK_SECOND},
+       {"sec", UNITS, DTK_SECOND},
+       {DSECOND, UNITS, DTK_SECOND},
+       {"seconds", UNITS, DTK_SECOND},
+       {"secs", UNITS, DTK_SECOND},
+       {DTIMEZONE, UNITS, DTK_TZ}, /* "timezone" time offset */
+       {"timezone_h", UNITS, DTK_TZ_HOUR}, /* timezone hour units */
+       {"timezone_m", UNITS, DTK_TZ_MINUTE},           /* timezone minutes units */
+       {"undefined", RESERV, DTK_INVALID}, /* pre-v6.1 invalid time */
+       {"us", UNITS, DTK_MICROSEC},    /* "microsecond" relative */
+       {"usec", UNITS, DTK_MICROSEC},          /* "microsecond" relative */
+       {DMICROSEC, UNITS, DTK_MICROSEC},       /* "microsecond" relative */
+       {"useconds", UNITS, DTK_MICROSEC},      /* "microseconds" relative */
+       {"usecs", UNITS, DTK_MICROSEC},         /* "microseconds" relative */
+       {"w", UNITS, DTK_WEEK},         /* "week" relative */
+       {DWEEK, UNITS, DTK_WEEK},       /* "week" relative */
+       {"weeks", UNITS, DTK_WEEK}, /* "weeks" relative */
+       {"y", UNITS, DTK_YEAR},         /* "year" relative */
+       {DYEAR, UNITS, DTK_YEAR},       /* "year" relative */
+       {"years", UNITS, DTK_YEAR}, /* "years" relative */
+       {"yr", UNITS, DTK_YEAR},        /* "year" relative */
+       {"yrs", UNITS, DTK_YEAR},       /* "years" relative */
+};
+
 static unsigned int szdatetktbl = sizeof datetktbl / sizeof datetktbl[0];
+static unsigned int szdeltatktbl = sizeof deltatktbl / sizeof deltatktbl[0];
 
 static datetkn    *datecache[MAXDATEFIELDS] = {NULL};
 
+static datetkn    *deltacache[MAXDATEFIELDS] = {NULL};
+
 char       *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL};
 
 char       *days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", NULL};
@@ -561,6 +632,39 @@ datebsearch(char *key, datetkn *base, unsigned int nel)
            return NULL;
 }
 
+/* DecodeUnits()
+ * Decode text string using lookup table.
+ * This routine supports time interval decoding.
+ */
+int
+DecodeUnits(int field, char *lowtoken, int *val)
+{
+       int                     type;
+       datetkn    *tp;
+
+       if ((deltacache[field] != NULL)
+               && (strncmp(lowtoken, deltacache[field]->token, TOKMAXLEN) == 0))
+               tp = deltacache[field];
+       else
+               tp = datebsearch(lowtoken, deltatktbl, szdeltatktbl);
+       deltacache[field] = tp;
+       if (tp == NULL)
+       {
+               type = UNKNOWN_FIELD;
+               *val = 0;
+       }
+       else
+       {
+               type = tp->type;
+               if ((type == TZ) || (type == DTZ))
+                       *val = FROMVAL(tp);
+               else
+                       *val = tp->value;
+       }
+
+       return type;
+}      /* DecodeUnits() */
+
 /*
  * Calendar time to Julian date conversions.
  * Julian date is commonly used in astronomical applications,
@@ -1088,7 +1192,7 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn)
 #endif
 }
 
-static void
+void
 GetCurrentDateTime(struct tm * tm)
 {
        int                     tz;
index 9b0a1f2e14e9b0b7c62bf80c5e026287ee00cfe1..fc09a6e4ced275330f9099e1cadfbe8e977a2d44 100644 (file)
@@ -9,7 +9,6 @@
 #include "c.h"
 #include "extern.h"
 #include "pgtypes_error.h"
-#include "decimal.h"
 
 #define Max(x, y)               ((x) > (y) ? (x) : (y))
 #define Min(x, y)               ((x) < (y) ? (x) : (y))
@@ -96,7 +95,7 @@ apply_typmod(Numeric *var, long typmod)
 
                if (tweight >= maxweight && i < var->ndigits)
                {
-                       errno = PGTYPES_OVERFLOW;
+                       errno = PGTYPES_NUM_OVERFLOW;
                        return -1;
                }
        }
@@ -188,7 +187,7 @@ set_var_from_str(char *str, char **ptr, Numeric *dest)
 
        if (!isdigit((unsigned char) *(*ptr)))
        {
-               errno=PGTYPES_BAD_NUMERIC;
+               errno=PGTYPES_NUM_BAD_NUMERIC;
                return -1;
        }
 
@@ -206,7 +205,7 @@ set_var_from_str(char *str, char **ptr, Numeric *dest)
                {
                        if (have_dp)
                        {
-                               errno = PGTYPES_BAD_NUMERIC;
+                               errno = PGTYPES_NUM_BAD_NUMERIC;
                                return -1;
                        }
                        have_dp = TRUE;
@@ -227,14 +226,14 @@ set_var_from_str(char *str, char **ptr, Numeric *dest)
                exponent = strtol((*ptr), &endptr, 10);
                if (endptr == (*ptr))
                {
-                       errno = PGTYPES_BAD_NUMERIC;
+                       errno = PGTYPES_NUM_BAD_NUMERIC;
                        return -1;
                }
                (*ptr) = endptr;
                if (exponent > NUMERIC_MAX_PRECISION ||
                        exponent < -NUMERIC_MAX_PRECISION)
                {
-                       errno = PGTYPES_BAD_NUMERIC;
+                       errno = PGTYPES_NUM_BAD_NUMERIC;
                        return -1;
                }
                dest->weight += (int) exponent;
@@ -248,7 +247,7 @@ set_var_from_str(char *str, char **ptr, Numeric *dest)
        {
                if (!isspace((unsigned char) *(*ptr)))
                {
-                       errno = PGTYPES_BAD_NUMERIC;
+                       errno = PGTYPES_NUM_BAD_NUMERIC;
                        return -1;
                }
                (*ptr)++;
@@ -402,9 +401,12 @@ PGTYPESnumeric_aton(char *str, char **endptr)
  * ----------
  */
 char *
-PGTYPESnumeric_ntoa(Numeric *num)
+PGTYPESnumeric_ntoa(Numeric *num, int dscale)
 {
-       return(get_str_from_var(num, num->dscale));
+       if (dscale <= 0)
+               dscale = num->dscale;
+
+       return(get_str_from_var(num, dscale));
 }
 
 /* ----------
@@ -1117,7 +1119,7 @@ PGTYPESnumeric_div(Numeric *var1, Numeric *var2, Numeric *result)
        ndigits_tmp = var2->ndigits + 1;
        if (ndigits_tmp == 1)
        {
-               errno= PGTYPES_DIVIDE_ZERO;
+               errno= PGTYPES_NUM_DIVIDE_ZERO;
                return -1;
        }
 
@@ -1320,7 +1322,7 @@ PGTYPESnumeric_cmp(Numeric *var1, Numeric *var2) {
                return -1;
        }
 
-       errno = PGTYPES_BAD_NUMERIC;
+       errno = PGTYPES_NUM_BAD_NUMERIC;
        return INT_MAX;
 
 }
@@ -1438,7 +1440,7 @@ numericvar_to_double_no_overflow(Numeric *var, double *dp)
        {
                /* shouldn't happen ... */
                free(tmp);
-               errno = PGTYPES_BAD_NUMERIC;
+               errno = PGTYPES_NUM_BAD_NUMERIC;
                return -1;
        } 
        *dp = val;
@@ -1466,7 +1468,7 @@ PGTYPESnumeric_ntoi(Numeric* nv, int* ip) {
                return i;
 
        if (l < -INT_MAX || l > INT_MAX) {
-               errno = PGTYPES_OVERFLOW;
+               errno = PGTYPES_NUM_OVERFLOW;
                return -1;
        } 
 
@@ -1488,7 +1490,7 @@ PGTYPESnumeric_ntol(Numeric* nv, long* lp) {
                l++;
        }
        if (l > LONG_MAX || l < 0) {
-               errno = PGTYPES_OVERFLOW;
+               errno = PGTYPES_NUM_OVERFLOW;
                return -1;
        }
        
@@ -1499,196 +1501,3 @@ PGTYPESnumeric_ntol(Numeric* nv, long* lp) {
        return 0;
 }
 
-/* Finally we need some wrappers for the INFORMIX functions */
-int
-decadd(Numeric *arg1, Numeric *arg2, Numeric *sum)
-{
-       int i = PGTYPESnumeric_add(arg1, arg2, sum);
-
-       if (i == 0) /* No error */
-               return 0;
-       if (errno == PGTYPES_OVERFLOW)
-               return -1200;
-
-       return -1201;   
-}
-
-int
-deccmp(Numeric *arg1, Numeric *arg2)
-{
-       int i = PGTYPESnumeric_cmp(arg1, arg2);
-       
-       /* TODO: Need to return DECUNKNOWN instead of PGTYPES_BAD_NUMERIC */
-       return (i);
-}
-
-void
-deccopy(Numeric *src, Numeric *target)
-{
-       PGTYPESnumeric_copy(src, target);
-}
-
-static char *
-strndup(char *str, int len)
-{
-       int real_len = strlen(str);
-       int use_len = (real_len > len) ? len : real_len;
-       
-       char *new = pgtypes_alloc(use_len + 1);
-
-       if (new)
-       {
-               memcpy(str, new, use_len);
-               new[use_len] = '\0';
-       }
-
-       return new;
-}
-
-int
-deccvasc(char *cp, int len, Numeric *np)
-{
-       char *str = strndup(cp, len); /* Numeric_in always converts the complete string */
-       int ret = 0;
-       
-       if (!str)
-               ret = -1201;
-       else
-       {
-               np = PGTYPESnumeric_aton(str, NULL);
-               if (!np)
-               {
-                       switch (errno)
-                       {
-                               case PGTYPES_OVERFLOW:    ret = -1200;
-                                                         break;
-                               case PGTYPES_BAD_NUMERIC: ret = -1213;
-                                                         break;
-                               default:                  ret = -1216;
-                                                         break;
-                       }
-               }
-       }
-       
-       return ret;
-}
-
-int
-deccvdbl(double dbl, Numeric *np)
-{
-       return(PGTYPESnumeric_dton(dbl, np));
-}
-
-int
-deccvint(int in, Numeric *np)
-{
-       return(PGTYPESnumeric_iton(in, np));
-}
-
-int
-deccvlong(long lng, Numeric *np)
-{
-       return(PGTYPESnumeric_lton(lng, np));   
-}
-
-int
-decdiv(Numeric *n1, Numeric *n2, Numeric *n3)
-{
-       int i = PGTYPESnumeric_div(n1, n2, n3), ret = 0;
-
-       if (i != 0)
-               switch (errno)
-               {
-                       case PGTYPES_DIVIDE_ZERO: ret = -1202;
-                                                 break;
-                       case PGTYPES_OVERFLOW:    ret = -1200;
-                                                 break;
-                       default:                  ret = -1201;
-                                                 break;
-               }
-
-       return ret;
-}
-
-int 
-decmul(Numeric *n1, Numeric *n2, Numeric *n3)
-{
-       int i = PGTYPESnumeric_mul(n1, n2, n3), ret = 0;
-
-       if (i != 0)
-               switch (errno)
-               {
-                       case PGTYPES_OVERFLOW:    ret = -1200;
-                                                 break;
-                       default:                  ret = -1201;
-                                                 break;
-               }
-
-       return ret;
-}
-
-int
-decsub(Numeric *n1, Numeric *n2, Numeric *n3)
-{
-       int i = PGTYPESnumeric_sub(n1, n2, n3), ret = 0;
-
-       if (i != 0)
-               switch (errno)
-               {
-                       case PGTYPES_OVERFLOW:    ret = -1200;
-                                                 break;
-                       default:                  ret = -1201;
-                                                 break;
-               }
-
-       return ret;
-}
-
-int
-dectoasc(Numeric *np, char *cp, int len, int right)
-{
-       char *str;
-       
-       if (right >= 0)
-               str = get_str_from_var(np, right);
-       else
-               str = get_str_from_var(np, np->dscale);
-
-       if (!str)
-               return -1;
-       
-       /* TODO: have to take care of len here and create exponatial notion if necessary */
-       strncpy(cp, str, len);
-       free (str);
-
-       return 0;
-}
-
-int
-dectodbl(Numeric *np, double *dblp)
-{
-       return(PGTYPESnumeric_ntod(np, dblp));
-}
-
-int
-dectoint(Numeric *np, int *ip)
-{
-       int ret = PGTYPESnumeric_ntoi(np, ip);
-
-       if (ret == PGTYPES_OVERFLOW)
-               ret = -1200;
-       
-       return ret;
-}
-
-int
-dectolong(Numeric *np, long *lngp)     
-{
-       int ret = PGTYPESnumeric_ntol(np, lngp);
-
-       if (ret == PGTYPES_OVERFLOW)
-               ret = -1200;
-       
-       return ret;
-}
-
index bf1ca57c6ef4fc4e8569994913dcf5452fe4ab34..181e63dc2ae7a721d708017f6c425c335caf5ce8 100644 (file)
@@ -13,7 +13,6 @@
 #include "extern.h"
 #include "pgtypes_error.h"
 #include "pgtypes_timestamp.h"
-#include "pgtypes_interval.h"
 #include "datetime.h"
 
 #ifdef HAVE_INT64_TIMESTAMP
@@ -288,14 +287,14 @@ PGTYPEStimestamp_atot(char *str, char **endptr)
        errno = 0;
        if (strlen(str) >= sizeof(lowstr))
        {
-               errno = PGTYPES_BAD_TIMESTAMP;
+               errno = PGTYPES_TS_BAD_TIMESTAMP;
                return (noresult);
        }
 
        if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf, ptr) != 0)
          || (DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz, 0) != 0))
        {
-                errno = PGTYPES_BAD_TIMESTAMP;
+                errno = PGTYPES_TS_BAD_TIMESTAMP;
                 return (noresult);
         }
        
@@ -304,7 +303,7 @@ PGTYPEStimestamp_atot(char *str, char **endptr)
                case DTK_DATE:
                        if (tm2timestamp(tm, fsec, NULL, &result) != 0)
                        {
-                               errno = PGTYPES_BAD_TIMESTAMP;
+                               errno = PGTYPES_TS_BAD_TIMESTAMP;
                                return (noresult);;
                        }
                        break;
@@ -322,11 +321,11 @@ PGTYPEStimestamp_atot(char *str, char **endptr)
                        break;
 
                case DTK_INVALID:
-                       errno = PGTYPES_BAD_TIMESTAMP;
+                       errno = PGTYPES_TS_BAD_TIMESTAMP;
                        return (noresult);
 
                default:
-                       errno = PGTYPES_BAD_TIMESTAMP;
+                       errno = PGTYPES_TS_BAD_TIMESTAMP;
                        return (noresult);
        }
 
@@ -350,67 +349,8 @@ PGTYPEStimestamp_ttoa(Timestamp tstamp)
                 EncodeDateTime(tm, fsec, NULL, &tzn, DateStyle, buf, 0);
         else
        {
-               errno = PGTYPES_BAD_TIMESTAMP;
+               errno = PGTYPES_TS_BAD_TIMESTAMP;
                return NULL;
        }
         return pgtypes_strdup(buf);
 }
-
-void
-dtcurrent (Timestamp *ts)
-{
-       return;
-}
-
-int
-dtcvasc (char *str, Timestamp *ts)
-{
-       return 0;
-}
-
-int
-dtsub (Timestamp *ts1, Timestamp *ts2, Interval *iv)
-{
-       return 0;
-}
-
-int
-dttoasc (Timestamp *ts, char *output)
-{
-       return 0;
-}
-
-int
-dttofmtasc (Timestamp *ts, char *output, int str_len, char *fmtstr)
-{
-       return 0;
-}
-
-int
-intoasc(Interval *i, char *str)
-{
-       return 0;
-}
-
-Interval *
-PGTYPESinterval_atoi(char *str, char **endptr)
-{
-       Interval        *result = NULL;
-       
-       return result;
-}
-
-char *
-PGTYPESinterval_itoa(Interval *intvl)
-{
-        char            buf[MAXDATELEN + 1];
-
-        return pgtypes_strdup(buf);
-}
-
-int 
-PGTYPESinterval_copy(Interval *intvlsrc, Interval *intrcldest)
-{
-               return 0;
-}
-
index 34f520f891b57ca6859cc96845cb21fe51032a4f..68d099136ec52095dfb1886287626b8b9140dc08 100644 (file)
 #include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
 #include <pgtypes_date.h>
 #include <pgtypes_timestamp.h>
+#include <pgtypes_interval.h>
 
 int
 main()
 {
        exec sql begin declare section;
-       date date1;
-       timestamp ts1;
-       char *text;
+               date date1;
+               timestamp ts1;
+               interval iv1;
+               char *text;
        exec sql end declare section;
-#if 0
        Date date2;
-       short int mdy[3] = { 4, 19, 1998 };
-#endif
+       int mdy[3] = { 4, 19, 1998 };
+       char *fmt, *out, *in;
+       
        FILE *dbgs;
 
         if ((dbgs = fopen("log", "w")) != NULL)
                  ECPGdebug(1, dbgs);
         exec sql whenever sqlerror do sqlprint();
         exec sql connect to mm;
-        exec sql create table date_test (d date, ts timestamp);
+        exec sql create table date_test (d date, ts timestamp, iv interval);
 
-       exec sql insert into date_test(d, ts) values ('Mon Jan 17 1966', '2000-7-12 17:34:29');
+       exec sql insert into date_test(d, ts, iv) values ('Mon Jan 17 1966', '2000-7-12 17:34:29', now()-'Mon Jan 17 1966');
 
-       exec sql select * into :date1, :ts1 from date_test;
+       exec sql select * into :date1, :ts1 , :iv1 from date_test;
        
        text = PGTYPESdate_dtoa(date1);
        printf ("Date: %s\n", text);
-       ts1 = PGTYPEStimestamp_atot("2000-7-12 17:34:29", NULL);
+       
        text = PGTYPEStimestamp_ttoa(ts1);
        printf ("timestamp: %s\n", text);
-#if 0
+       
+       text = PGTYPESinterval_itoa(&iv1);
+       printf ("interval: %s\n", text);
+       
        PGTYPESdate_mdyjul(mdy, &date2);
        printf("m: %d, d: %d, y: %d\n", mdy[0], mdy[1], mdy[2]);
        /* reset */
        mdy[0] = mdy[1] = mdy[2] = 0;
 
+       printf("date seems to get encoded to julian %ld\n", date2);
+       
        PGTYPESdate_julmdy(date2, mdy);
        printf("m: %d, d: %d, y: %d\n", mdy[0], mdy[1], mdy[2]);
-#endif
-        exec sql rollback;
+       
+       ts1 = PGTYPEStimestamp_atot("2003-12-04 17:34:29", NULL);
+       text = PGTYPEStimestamp_ttoa(ts1);
+
+       printf("date_day of %s is %d\n", text, PGTYPESdate_dayofweek(ts1));
+
+       PGTYPESdate_today(&date1);
+       text = PGTYPESdate_dtoa(date1);
+       printf("today is %s\n", text);
+
+       fmt = "(ddd), mmm. dd, yyyy, repeat: (ddd), mmm. dd, yyyy. end";
+       out = (char*) malloc(strlen(fmt) + 1);
+
+       PGTYPESdate_fmtdate(date1, fmt, out);
+       printf("Today in format \"%s\" is \"%s\"\n", fmt, out);
+       free(out);
+
+       /* rdefmtdate() */
+
+       date1 = 0; text = "";
+       fmt = "yy/mm/dd";
+       in = "In the year 1995, the month of December, it is the 25th day";
+       /*    0123456789012345678901234567890123456789012345678901234567890
+        *    0         1         2         3         4         5         6
+        */
+       PGTYPESdate_defmtdate(&date1, fmt, in);
+       text = PGTYPESdate_dtoa(date1);
+       printf("defmtdate1: %s\n", text);
+
+       date1 = 0; text = "";
+       fmt = "mmmm. dd. yyyy";
+       in = "12/25/95";
+       PGTYPESdate_defmtdate(&date1, fmt, in);
+       text = PGTYPESdate_dtoa(date1);
+       printf("defmtdate2: %s\n", text);
+
+       date1 = 0; text = "";
+       fmt = "yy/mm/dd";
+       in = "95/12/25";
+       PGTYPESdate_defmtdate(&date1, fmt, in);
+       text = PGTYPESdate_dtoa(date1);
+       printf("defmtdate3: %s\n", text);
+
+       date1 = 0; text = "";
+       fmt = "yy/mm/dd";
+       in = "1995, December 25th";
+       PGTYPESdate_defmtdate(&date1, fmt, in);
+       text = PGTYPESdate_dtoa(date1);
+       printf("defmtdate4: %s\n", text);
+
+       date1 = 0; text = "";
+       fmt = "dd-mm-yy";
+       in = "This is 25th day of December, 1995";
+       PGTYPESdate_defmtdate(&date1, fmt, in);
+       text = PGTYPESdate_dtoa(date1);
+       printf("defmtdate5: %s\n", text);
+
+       date1 = 0; text = "";
+       fmt = "mmddyy";
+       in = "Dec. 25th, 1995";
+       PGTYPESdate_defmtdate(&date1, fmt, in);
+       text = PGTYPESdate_dtoa(date1);
+       printf("defmtdate6: %s\n", text);
+
+       date1 = 0; text = "";
+       fmt = "mmm. dd. yyyy";
+       in = "dec 25th 1995";
+       PGTYPESdate_defmtdate(&date1, fmt, in);
+       text = PGTYPESdate_dtoa(date1);
+       printf("defmtdate7: %s\n", text);
+
+       date1 = 0; text = "";
+       fmt = "mmm. dd. yyyy";
+       in = "DEC-25-1995";
+       PGTYPESdate_defmtdate(&date1, fmt, in);
+       text = PGTYPESdate_dtoa(date1);
+       printf("defmtdate8: %s\n", text);
+
+       date1 = 0; text = "";
+       fmt = "mm yy   dd.";
+       in = "12199525";
+       PGTYPESdate_defmtdate(&date1, fmt, in);
+       text = PGTYPESdate_dtoa(date1);
+       printf("defmtdate9: %s\n", text);
+
+       date1 = 0; text = "";
+       fmt = "yyyy fierj mm   dd.";
+       in = "19951225";
+       PGTYPESdate_defmtdate(&date1, fmt, in);
+       text = PGTYPESdate_dtoa(date1);
+       printf("defmtdate10: %s\n", text);
+
+       date1 = 0; text = "";
+       fmt = "mm/dd/yy";
+       in = "122595";
+       PGTYPESdate_defmtdate(&date1, fmt, in);
+       text = PGTYPESdate_dtoa(date1);
+       printf("defmtdate12: %s\n", text);
+
+       exec sql rollback;
         exec sql disconnect;
 
        if (dbgs != NULL)