]> granicus.if.org Git - postgresql/commitdiff
- Added some Informix error codes in Informix mode.
authorMichael Meskes <meskes@postgresql.org>
Fri, 1 Aug 2003 08:21:04 +0000 (08:21 +0000)
committerMichael Meskes <meskes@postgresql.org>
Fri, 1 Aug 2003 08:21:04 +0000 (08:21 +0000)
- Added just another pgtypeslib function.

20 files changed:
src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/compatlib/informix.c
src/interfaces/ecpg/ecpglib/connect.c
src/interfaces/ecpg/ecpglib/data.c
src/interfaces/ecpg/ecpglib/descriptor.c
src/interfaces/ecpg/ecpglib/error.c
src/interfaces/ecpg/ecpglib/execute.c
src/interfaces/ecpg/ecpglib/memory.c
src/interfaces/ecpg/ecpglib/misc.c
src/interfaces/ecpg/ecpglib/prepare.c
src/interfaces/ecpg/include/ecpgerrno.h
src/interfaces/ecpg/include/ecpglib.h
src/interfaces/ecpg/include/pgtypes_timestamp.h
src/interfaces/ecpg/pgtypeslib/common.c
src/interfaces/ecpg/pgtypeslib/datetime.c
src/interfaces/ecpg/pgtypeslib/dt_common.c
src/interfaces/ecpg/pgtypeslib/extern.h
src/interfaces/ecpg/pgtypeslib/timestamp.c
src/interfaces/ecpg/preproc/ecpg.c
src/interfaces/ecpg/test/dt_test.pgc

index 5c007b0ae436612d53378f6ed929d35cb16ae65b..8bdda60ed1ae66ad416a25e5f9b4792ba61d03f5 100644 (file)
@@ -1595,6 +1595,11 @@ Thu Jul 24 10:33:51 CEST 2003
 Fri Jul 25 18:08:18 CEST 2003
 
        - Added explicit casts for date/timestamp/interval.
+       
+Fri Aug  1 08:54:02 CEST 2003
+       
+       - Added some Informix error codes in Informix mode.
+       - Added just another pgtypeslib function.
        - Set ecpg version to 3.0.0
        - Set ecpg library to 4.0.0
        - Set pgtypes library to 1.0.0
index 807349fd835c8fa1ab96c6015f8b2f36143073f4..e1b073f400253af3be463a83d415a9c7b73ac0f9 100644 (file)
@@ -823,7 +823,7 @@ rtypwidth(int sqltype, int sqllen)
 int
 dtcvfmtasc (char *inbuf, char *fmtstr, dtime_t *dtvalue)
 {
-       return 0;
+       return PGTYPEStimestamp_defmt_asc(inbuf, fmtstr, dtvalue); 
 }
 
 static struct var_list
index d187d32f7081bda0e82e0ae18a307dfffdabb0db..44b088481c7a8deacc1f780b9623b07cc144f1fe 100644 (file)
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.12 2003/07/15 12:38:38 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.13 2003/08/01 08:21:04 meskes Exp $ */
 
 #define POSTGRES_ECPG_INTERNAL
 #include "postgres_fe.h"
@@ -116,7 +116,7 @@ ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
                {
                        if ((results = PQexec(con->connection, "begin transaction")) == NULL)
                        {
-                               ECPGraise(lineno, ECPG_TRANS, NULL);
+                               ECPGraise(lineno, ECPG_TRANS, NULL, ECPG_COMPAT_PGSQL);
                                return false;
                        }
                        PQclear(results);
@@ -130,7 +130,7 @@ ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
                {
                        if ((results = PQexec(con->connection, "commit")) == NULL)
                        {
-                               ECPGraise(lineno, ECPG_TRANS, NULL);
+                               ECPGraise(lineno, ECPG_TRANS, NULL, ECPG_COMPAT_PGSQL);
                                return false;
                        }
                        PQclear(results);
@@ -406,7 +406,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
                                        if (strncmp(dbname, "unix:", 5) != 0)
                                        {
                                                ECPGlog("connect: socketname %s given for TCP connection in line %d\n", host, lineno);
-                                               ECPGraise(lineno, ECPG_CONNECT, realname ? realname : "<DEFAULT>");
+                                               ECPGraise(lineno, ECPG_CONNECT, realname ? realname : "<DEFAULT>", ECPG_COMPAT_PGSQL);
                                                if (host)
                                                        ECPGfree(host);
                                                if (port)
@@ -429,7 +429,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
                                if (strcmp(dbname + offset, "localhost") != 0 && strcmp(dbname + offset, "127.0.0.1") != 0)
                                {
                                        ECPGlog("connect: non-localhost access via sockets in line %d\n", lineno);
-                                       ECPGraise(lineno, ECPG_CONNECT, realname ? realname : "<DEFAULT>");
+                                       ECPGraise(lineno, ECPG_CONNECT, realname ? realname : "<DEFAULT>", ECPG_COMPAT_PGSQL);
                                        if (host)
                                                ECPGfree(host);
                                        if (port)
@@ -497,7 +497,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
                                user ? "for user " : "", user ? user : "",
                                lineno, errmsg);
         
-               ECPGraise(lineno, ECPG_CONNECT, db);
+               ECPGraise(lineno, ECPG_CONNECT, db, ECPG_COMPAT_PGSQL);
                if (host)
                        ECPGfree(host);
                if (port)
index e783e4f077b0e66821c9d3af9e35a33d8fa0750e..361dfa73a4a6676cb8773bd05cf0f507fb7e6c3e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.13 2003/07/18 14:32:56 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.14 2003/08/01 08:21:04 meskes Exp $ */
 
 #define POSTGRES_ECPG_INTERNAL
 #include "postgres_fe.h"
@@ -34,7 +34,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
        {
                if (*pval != '{')
                {
-                       ECPGraise(lineno, ECPG_DATA_NOT_ARRAY, NULL);
+                       ECPGraise(lineno, ECPG_DATA_NOT_ARRAY, NULL, compat);
                        return (false);
                }
 
@@ -90,13 +90,13 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                }
                                else
                                {
-                                       ECPGraise(lineno, ECPG_MISSING_INDICATOR, NULL);
+                                       ECPGraise(lineno, ECPG_MISSING_INDICATOR, NULL, compat);
                                        return (false);
                                }
                        }
                        break;
                default:
-                       ECPGraise(lineno, ECPG_UNSUPPORTED, ECPGtype_name(ind_type));
+                       ECPGraise(lineno, ECPG_UNSUPPORTED, ECPGtype_name(ind_type), compat);
                        return (false);
                        break;
        }
@@ -126,7 +126,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                        if ((isarray && *scan_length != ',' && *scan_length != '}')
                                                || (!isarray && *scan_length != '\0' && *scan_length != ' '))   /* Garbage left */
                                        {
-                                               ECPGraise(lineno, ECPG_INT_FORMAT, pval);
+                                               ECPGraise(lineno, ECPG_INT_FORMAT, pval, compat);
                                                return (false);
                                        }
                                }
@@ -159,7 +159,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                        if ((isarray && *scan_length != ',' && *scan_length != '}')
                                                || (!isarray && *scan_length != '\0' && *scan_length != ' '))   /* Garbage left */
                                        {
-                                               ECPGraise(lineno, ECPG_UINT_FORMAT, pval);
+                                               ECPGraise(lineno, ECPG_UINT_FORMAT, pval, compat);
                                                return (false);
                                        }
                                }
@@ -192,7 +192,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                        if ((isarray && *scan_length != ',' && *scan_length != '}')
                                                || (!isarray && *scan_length != '\0' && *scan_length != ' '))   /* Garbage left */
                                        {
-                                               ECPGraise(lineno, ECPG_INT_FORMAT, pval);
+                                               ECPGraise(lineno, ECPG_INT_FORMAT, pval, compat);
                                                return (false);
                                        }
                                }
@@ -209,7 +209,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                        if ((isarray && *scan_length != ',' && *scan_length != '}')
                                                || (!isarray && *scan_length != '\0' && *scan_length != ' '))   /* Garbage left */
                                        {
-                                               ECPGraise(lineno, ECPG_UINT_FORMAT, pval);
+                                               ECPGraise(lineno, ECPG_UINT_FORMAT, pval, compat);
                                                return (false);
                                        }
                                }
@@ -235,7 +235,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                        if ((isarray && *scan_length != ',' && *scan_length != '}')
                                                || (!isarray && *scan_length != '\0' && *scan_length != ' '))   /* Garbage left */
                                        {
-                                               ECPGraise(lineno, ECPG_FLOAT_FORMAT, pval);
+                                               ECPGraise(lineno, ECPG_FLOAT_FORMAT, pval, compat);
                                                return (false);
                                        }
                                }
@@ -266,7 +266,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                                else if (offset == sizeof(int))
                                                        *((int *) (var + offset * act_tuple)) = false;
                                                else
-                                                       ECPGraise(lineno, ECPG_CONVERT_BOOL, "different size");
+                                                       ECPGraise(lineno, ECPG_CONVERT_BOOL, "different size", compat);
                                                break;
                                        }
                                        else if (pval[0] == 't' && pval[1] == '\0')
@@ -276,7 +276,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                                else if (offset == sizeof(int))
                                                        *((int *) (var + offset * act_tuple)) = true;
                                                else
-                                                       ECPGraise(lineno, ECPG_CONVERT_BOOL, "different size");
+                                                       ECPGraise(lineno, ECPG_CONVERT_BOOL, "different size", compat);
                                                break;
                                        }
                                        else if (pval[0] == '\0' && PQgetisnull(results, act_tuple, act_field))
@@ -286,7 +286,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                        }
                                }
 
-                               ECPGraise(lineno, ECPG_CONVERT_BOOL, pval);
+                               ECPGraise(lineno, ECPG_CONVERT_BOOL, pval, compat);
                                return (false);
                                break;
 
@@ -396,7 +396,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                        if ((isarray && *scan_length != ',' && *scan_length != '}')
                                                || (!isarray && *scan_length != '\0' && *scan_length != ' '))   /* Garbage left */
                                        {
-                                               ECPGraise(lineno, ECPG_NUMERIC_FORMAT, pval);
+                                               ECPGraise(lineno, ECPG_NUMERIC_FORMAT, pval, compat);
                                                return (false);
                                        }
                                }
@@ -423,7 +423,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                        if ((isarray && *scan_length != ',' && *scan_length != '}')
                                                || (!isarray && *scan_length != '\0' && *scan_length != ' '))   /* Garbage left */
                                        {
-                                               ECPGraise(lineno, ECPG_INTERVAL_FORMAT, pval);
+                                               ECPGraise(lineno, ECPG_INTERVAL_FORMAT, pval, compat);
                                                return (false);
                                        }
                                }
@@ -446,7 +446,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                        if ((isarray && *scan_length != ',' && *scan_length != '}')
                                                || (!isarray && *scan_length != '\0' && *scan_length != ' '))   /* Garbage left */
                                        {
-                                               ECPGraise(lineno, ECPG_DATE_FORMAT, pval);
+                                               ECPGraise(lineno, ECPG_DATE_FORMAT, pval, compat);
                                                return (false);
                                        }
 
@@ -468,7 +468,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                        if ((isarray && *scan_length != ',' && *scan_length != '}')
                                                || (!isarray && *scan_length != '\0' && *scan_length != ' '))   /* Garbage left */
                                        {
-                                               ECPGraise(lineno, ECPG_TIMESTAMP_FORMAT, pval);
+                                               ECPGraise(lineno, ECPG_TIMESTAMP_FORMAT, pval, compat);
                                                return (false);
                                        }
 
@@ -477,7 +477,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                break;
                                
                        default:
-                               ECPGraise(lineno, ECPG_UNSUPPORTED, ECPGtype_name(type));
+                               ECPGraise(lineno, ECPG_UNSUPPORTED, ECPGtype_name(type), compat);
                                return (false);
                                break;
                }
index ade737beeaee1fbe37decfc31c5acfc20103f040..bdb308810da428913b2869d34ae21fa8c718f307 100644 (file)
@@ -1,6 +1,6 @@
 /* dynamic SQL support routines
  *
- * $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/descriptor.c,v 1.3 2003/06/15 04:07:58 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/descriptor.c,v 1.4 2003/08/01 08:21:04 meskes Exp $
  */
 
 #define POSTGRES_ECPG_INTERNAL
@@ -103,7 +103,7 @@ get_int_item(int lineno, void *var, enum ECPGttype vartype, int value)
                        *(double *) var = (double) value;
                        break;
                default:
-                       ECPGraise(lineno, ECPG_VAR_NOT_NUMERIC, NULL);
+                       ECPGraise(lineno, ECPG_VAR_NOT_NUMERIC, NULL, ECPG_COMPAT_PGSQL);
                        return (false);
        }
 
@@ -135,7 +135,7 @@ get_char_item(int lineno, void *var, enum ECPGttype vartype, char *value, int va
                        }
                        break;
                default:
-                       ECPGraise(lineno, ECPG_VAR_NOT_CHAR, NULL);
+                       ECPGraise(lineno, ECPG_VAR_NOT_CHAR, NULL, ECPG_COMPAT_PGSQL);
                        return (false);
        }
 
@@ -162,13 +162,13 @@ ECPGget_desc(int lineno, char *desc_name, int index,...)
        ntuples = PQntuples(ECPGresult);
        if (ntuples < 1)
        {
-               ECPGraise(lineno, ECPG_NOT_FOUND, NULL);
+               ECPGraise(lineno, ECPG_NOT_FOUND, NULL, ECPG_COMPAT_PGSQL);
                return (false);
        }
 
        if (index < 1 || index > PQnfields(ECPGresult))
        {
-               ECPGraise(lineno, ECPG_INVALID_DESCRIPTOR_INDEX, NULL);
+               ECPGraise(lineno, ECPG_INVALID_DESCRIPTOR_INDEX, NULL, ECPG_COMPAT_PGSQL);
                return (false);
        }
 
@@ -300,7 +300,7 @@ ECPGget_desc(int lineno, char *desc_name, int index,...)
                                {
                                        ECPGlog("ECPGget_desc line %d: Incorrect number of matches: %d don't fit into array of %d\n",
                                                        lineno, ntuples, arrsize);
-                                       ECPGraise(lineno, ECPG_TOO_MANY_MATCHES, NULL);
+                                       ECPGraise(lineno, ECPG_TOO_MANY_MATCHES, NULL, ECPG_COMPAT_PGSQL);
                                        return false;
                                }
                                /* allocate storage if needed */
@@ -324,7 +324,7 @@ ECPGget_desc(int lineno, char *desc_name, int index,...)
 
                        default:
                                snprintf(type_str, sizeof(type_str), "%d", type);
-                               ECPGraise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, type_str);
+                               ECPGraise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, type_str, ECPG_COMPAT_PGSQL);
                                return (false);
                }
 
@@ -361,7 +361,7 @@ ECPGget_desc(int lineno, char *desc_name, int index,...)
                {
                        ECPGlog("ECPGget_desc line %d: Incorrect number of matches (indicator): %d don't fit into array of %d\n",
                                        lineno, ntuples, data_var.ind_arrsize);
-                       ECPGraise(lineno, ECPG_TOO_MANY_MATCHES, NULL);
+                       ECPGraise(lineno, ECPG_TOO_MANY_MATCHES, NULL, ECPG_COMPAT_PGSQL);
                        return false;
                }
                /* allocate storage if needed */
@@ -404,7 +404,7 @@ ECPGdeallocate_desc(int line, const char *name)
                        return true;
                }
        }
-       ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, name);
+       ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, name, ECPG_COMPAT_PGSQL);
        return false;
 }
 
@@ -430,7 +430,7 @@ ECPGallocate_desc(int line, const char *name)
        {
                ECPGfree(new->name);
                ECPGfree(new);
-               ECPGraise(line, ECPG_OUT_OF_MEMORY, NULL);
+               ECPGraise(line, ECPG_OUT_OF_MEMORY, NULL, ECPG_COMPAT_PGSQL);
                return false;
        }
        strcpy(new->name, name);
@@ -449,7 +449,7 @@ ECPGdescriptor_lvalue(int line, const char *descriptor)
                        return &i->result;
        }
 
-       ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, (char *) descriptor);
+       ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, (char *) descriptor, ECPG_COMPAT_PGSQL);
        return NULL;
 }
 
index 5566c0edf66584babcec20a53aba5bb85efa1f73..0b4b563d85a3bcb3252effaa82676a3f4ee27eb4 100644 (file)
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/error.c,v 1.3 2003/07/15 12:38:38 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/error.c,v 1.4 2003/08/01 08:21:04 meskes Exp $ */
 
 #define POSTGRES_ECPG_INTERNAL
 #include "postgres_fe.h"
@@ -12,7 +12,7 @@
 #include "sqlca.h"
 
 void
-ECPGraise(int line, int code, const char *str)
+ECPGraise(int line, int code, const char *str, int compat)
 {
        struct sqlca_t *sqlca = ECPGget_sqlca();
        sqlca->sqlcode = code;
@@ -139,9 +139,9 @@ ECPGraise(int line, int code, const char *str)
                                snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),
                                                 "'%.*s' in line %d.", slen, str, line);
                                if (strncmp(str, "ERROR:  Cannot insert a duplicate key", strlen("ERROR:  Cannot insert a duplicate key")) == 0)
-                                               sqlca->sqlcode = ECPG_DUPLICATE_KEY;
+                                       sqlca->sqlcode = INFORMIX_MODE(compat) ? ECPG_INFORMIX_DUPLICATE_KEY : ECPG_DUPLICATE_KEY;
                                else if (strncmp(str, "ERROR:  More than one tuple returned by a subselect", strlen("ERROR:  More than one tuple returned by a subselect")) == 0)
-                                               sqlca->sqlcode = ECPG_SUBSELECT_NOT_ONE;
+                                       sqlca->sqlcode = INFORMIX_MODE(compat) ? ECPG_INFORMIX_SUBSELECT_NOT_ONE : ECPG_SUBSELECT_NOT_ONE;
                                
                                break;
                        }
index f9557a861a4d43255d049bcdc901f5f6339dbd69..8e9545f0ab4b96826bd3b3f57d8108d32c3fc3cd 100644 (file)
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.20 2003/07/25 16:10:26 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.21 2003/08/01 08:21:04 meskes Exp $ */
 
 /*
  * The aim is to get a simpler inteface to the database routines.
@@ -124,7 +124,7 @@ create_statement(int lineno, int compat, int force_indicator, struct connection
                        /* if variable is NULL, the statement hasn't been prepared */
                        if (var->pointer == NULL)
                        {
-                               ECPGraise(lineno, ECPG_INVALID_STMT, NULL);
+                               ECPGraise(lineno, ECPG_INVALID_STMT, NULL, compat);
                                ECPGfree(var);
                                return false;
                        }
@@ -351,7 +351,7 @@ ECPGstore_result(const PGresult *results, int act_field,
                {
                        ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d don't fit into array of %d\n",
                                        stmt->lineno, ntuples, var->arrsize);
-                       ECPGraise(stmt->lineno, ECPG_TOO_MANY_MATCHES, NULL);
+                       ECPGraise(stmt->lineno, ECPG_TOO_MANY_MATCHES, NULL, ECPG_COMPAT_PGSQL);
                        return false;
                }
        }
@@ -362,7 +362,7 @@ ECPGstore_result(const PGresult *results, int act_field,
                 */
                if (var->arrsize == 0)
                {
-                       ECPGraise(stmt->lineno, ECPG_NO_ARRAY, NULL);
+                       ECPGraise(stmt->lineno, ECPG_NO_ARRAY, NULL, ECPG_COMPAT_PGSQL);
                        return false;
                }
        }
@@ -484,7 +484,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
 
 /*      if (var->arrsize > 1 && ...)
         {
-               ECPGraise(stmt->lineno, ECPG_ARRAY_INSERT, NULL);
+               ECPGraise(stmt->lineno, ECPG_ARRAY_INSERT, NULL, compat);
                return false;
         }*/
 
@@ -757,7 +757,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
                                                for (element = 0; element < var->arrsize; element++)
                                                        sprintf(mallocedval + strlen(mallocedval), "%c,", (((int *) var->value)[element]) ? 't' : 'f');
                                        else
-                                               ECPGraise(stmt->lineno, ECPG_CONVERT_BOOL, "different size");
+                                               ECPGraise(stmt->lineno, ECPG_CONVERT_BOOL, "different size", ECPG_COMPAT_PGSQL);
 
                                        strcpy(mallocedval + strlen(mallocedval) - 1, "]");
                                }
@@ -768,7 +768,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
                                        else if (var->offset == sizeof(int))
                                                sprintf(mallocedval, "'%c'", (*((int *) var->value)) ? 't' : 'f');
                                        else
-                                               ECPGraise(stmt->lineno, ECPG_CONVERT_BOOL, "different size");
+                                               ECPGraise(stmt->lineno, ECPG_CONVERT_BOOL, "different size", ECPG_COMPAT_PGSQL);
                                }
 
                                *tobeinserted_p = mallocedval;
@@ -1021,7 +1021,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
                                
                        default:
                                /* Not implemented yet */
-                               ECPGraise(stmt->lineno, ECPG_UNSUPPORTED, (char *) ECPGtype_name(var->type));
+                               ECPGraise(stmt->lineno, ECPG_UNSUPPORTED, (char *) ECPGtype_name(var->type), ECPG_COMPAT_PGSQL);
                                return false;
                                break;
                }
@@ -1073,7 +1073,7 @@ ECPGexecute(struct statement * stmt)
                         * We have an argument but we dont have the matched up string
                         * in the string
                         */
-                       ECPGraise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, NULL);
+                       ECPGraise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, NULL, stmt->compat);
                        return false;
                }
                else
@@ -1111,7 +1111,7 @@ ECPGexecute(struct statement * stmt)
        /* Check if there are unmatched things left. */
        if (next_insert(copiedquery) != NULL)
        {
-               ECPGraise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS, NULL);
+               ECPGraise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS, NULL, stmt->compat);
                return false;
        }
 
@@ -1121,7 +1121,7 @@ ECPGexecute(struct statement * stmt)
        {
                if ((results = PQexec(stmt->connection->connection, "begin transaction")) == NULL)
                {
-                       ECPGraise(stmt->lineno, ECPG_TRANS, NULL);
+                       ECPGraise(stmt->lineno, ECPG_TRANS, NULL, stmt->compat);
                        return false;
                }
                PQclear(results);
@@ -1136,7 +1136,7 @@ ECPGexecute(struct statement * stmt)
        {
                errmsg = PQerrorMessage(stmt->connection->connection);
                ECPGlog("ECPGexecute line %d: error: %s", stmt->lineno, errmsg);
-               ECPGraise(stmt->lineno, ECPG_PGSQL, errmsg);
+               ECPGraise(stmt->lineno, ECPG_PGSQL, errmsg, stmt->compat);
        }
        else
 
@@ -1167,7 +1167,7 @@ ECPGexecute(struct statement * stmt)
                                        if (ntuples)
                                                ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d\n",
                                                                stmt->lineno, ntuples);
-                                       ECPGraise(stmt->lineno, ECPG_NOT_FOUND, NULL);
+                                       ECPGraise(stmt->lineno, ECPG_NOT_FOUND, NULL, stmt->compat);
                                        status = false;
                                        break;
                                }
@@ -1198,21 +1198,21 @@ ECPGexecute(struct statement * stmt)
                                                }
                                                else if (!INFORMIX_MODE(stmt->compat))
                                                {
-                                                       ECPGraise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS, NULL);
+                                                       ECPGraise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS, NULL, stmt->compat);
                                                        return (false);
                                                }
                                        }
 
                                if (status && var != NULL)
                                {
-                                       ECPGraise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, NULL);
+                                       ECPGraise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, NULL, stmt->compat);
                                        status = false;
                                }
 
                                break;
                        case PGRES_EMPTY_QUERY:
                                /* do nothing */
-                               ECPGraise(stmt->lineno, ECPG_EMPTY, NULL);
+                               ECPGraise(stmt->lineno, ECPG_EMPTY, NULL, stmt->compat);
                                break;
                        case PGRES_COMMAND_OK:
                                status = true;
@@ -1225,13 +1225,13 @@ ECPGexecute(struct statement * stmt)
                                                        ( !strncmp(cmdstat, "UPDATE", 6)
                                                          || !strncmp(cmdstat, "INSERT", 6)
                                                          || !strncmp(cmdstat, "DELETE", 6)))
-                                       ECPGraise(stmt->lineno, ECPG_NOT_FOUND, NULL);
+                                       ECPGraise(stmt->lineno, ECPG_NOT_FOUND, NULL, stmt->compat);
                                break;
                        case PGRES_NONFATAL_ERROR:
                        case PGRES_FATAL_ERROR:
                        case PGRES_BAD_RESPONSE:
                                ECPGlog("ECPGexecute line %d: Error: %s", stmt->lineno, errmsg);
-                               ECPGraise(stmt->lineno, ECPG_PGSQL, errmsg);
+                               ECPGraise(stmt->lineno, ECPG_PGSQL, errmsg, stmt->compat);
                                status = false;
                                break;
                        case PGRES_COPY_OUT:
@@ -1245,7 +1245,7 @@ ECPGexecute(struct statement * stmt)
                        default:
                                ECPGlog("ECPGexecute line %d: Got something else, postgres error.\n",
                                                stmt->lineno);
-                               ECPGraise(stmt->lineno, ECPG_PGSQL, errmsg);
+                               ECPGraise(stmt->lineno, ECPG_PGSQL, errmsg, stmt->compat);
                                status = false;
                                break;
                }
@@ -1300,7 +1300,7 @@ ECPGdo(int lineno, int compat, int force_indicator, const char *connection_name,
        if (con == NULL || con->connection == NULL)
        {
                free_statement(stmt);
-               ECPGraise(lineno, ECPG_NOT_CONN, (con) ? con->name : "<empty>");
+               ECPGraise(lineno, ECPG_NOT_CONN, (con) ? con->name : "<empty>", stmt->compat);
                setlocale(LC_NUMERIC, oldlocale);
                ECPGfree(oldlocale);
                return false;
index 1a5de833d1ce4ec1519bb2e60e0f682a070b8542..0a77da4f09528760a55bd849b54e522521f34faa 100644 (file)
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/memory.c,v 1.2 2003/06/15 04:07:58 momjian Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/memory.c,v 1.3 2003/08/01 08:21:04 meskes Exp $ */
 
 #define POSTGRES_ECPG_INTERNAL
 #include "postgres_fe.h"
@@ -21,7 +21,7 @@ ECPGalloc(long size, int lineno)
 
        if (!new)
        {
-               ECPGraise(lineno, ECPG_OUT_OF_MEMORY, NULL);
+               ECPGraise(lineno, ECPG_OUT_OF_MEMORY, NULL, ECPG_COMPAT_PGSQL);
                return NULL;
        }
 
@@ -36,7 +36,7 @@ ECPGrealloc(void *ptr, long size, int lineno)
 
        if (!new)
        {
-               ECPGraise(lineno, ECPG_OUT_OF_MEMORY, NULL);
+               ECPGraise(lineno, ECPG_OUT_OF_MEMORY, NULL, ECPG_COMPAT_PGSQL);
                return NULL;
        }
 
@@ -50,7 +50,7 @@ ECPGstrdup(const char *string, int lineno)
 
        if (!new)
        {
-               ECPGraise(lineno, ECPG_OUT_OF_MEMORY, NULL);
+               ECPGraise(lineno, ECPG_OUT_OF_MEMORY, NULL, ECPG_COMPAT_PGSQL);
                return NULL;
        }
 
index b9e0c35d0ca4acbe416b390e21f131fe20f00834..4334844d61d6a2b66b609d6ab945a03c1cbd1edc 100644 (file)
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.10 2003/07/17 07:54:29 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.11 2003/08/01 08:21:04 meskes Exp $ */
 
 #define POSTGRES_ECPG_INTERNAL
 #include "postgres_fe.h"
@@ -103,7 +103,7 @@ ECPGinit(const struct connection * con, const char *connection_name, const int l
        ECPGinit_sqlca(sqlca);
        if (con == NULL)
        {
-               ECPGraise(lineno, ECPG_NO_CONN, connection_name ? connection_name : "NULL");
+               ECPGraise(lineno, ECPG_NO_CONN, connection_name ? connection_name : "NULL", ECPG_COMPAT_PGSQL);
                return (false);
        }
 
@@ -150,7 +150,7 @@ ECPGstatus(int lineno, const char *connection_name)
        /* are we connected? */
        if (con->connection == NULL)
        {
-               ECPGraise(lineno, ECPG_NOT_CONN, con->name);
+               ECPGraise(lineno, ECPG_NOT_CONN, con->name, ECPG_COMPAT_PGSQL);
                return false;
        }
 
@@ -179,7 +179,7 @@ ECPGtrans(int lineno, const char *connection_name, const char *transaction)
                {
                        if ((res = PQexec(con->connection, transaction)) == NULL)
                        {
-                               ECPGraise(lineno, ECPG_TRANS, NULL);
+                               ECPGraise(lineno, ECPG_TRANS, NULL, ECPG_COMPAT_PGSQL);
                                return FALSE;
                        }
                        PQclear(res);
index 8b0d523c6a3a18add7ed57f498de331a86467d22..76c58d1238cb3c9c599b8c8dff52b83e7012dc42 100644 (file)
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.6 2003/07/14 10:16:44 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.7 2003/08/01 08:21:04 meskes Exp $ */
 
 #define POSTGRES_ECPG_INTERNAL
 #include "postgres_fe.h"
@@ -120,7 +120,7 @@ ECPGdeallocate(int lineno, int c, char *name)
        }
        
        if (!ret) 
-               ECPGraise(lineno, ECPG_INVALID_STMT, name);
+               ECPGraise(lineno, ECPG_INVALID_STMT, name, ECPG_COMPAT_PGSQL);
 
        return ret;
 }
index b78ecc634cfc27bc62a5e6a8948d0435ca2db815..eb1936beb182ec84012d27382ed50df905b30d7e 100644 (file)
 #define ECPG_DUPLICATE_KEY             -403
 #define ECPG_SUBSELECT_NOT_ONE         -404
 
+/* for compatibility we define some different error codes for the same error
+ * if adding a new one make sure to not double define it */
+#define ECPG_INFORMIX_DUPLICATE_KEY    -239
+#define ECPG_INFORMIX_SUBSELECT_NOT_ONE        -284
+
 /* backend WARNINGs, starting at 600 */
 #define ECPG_WARNING_UNRECOGNIZED         -600
  /* WARNING:  (transaction aborted): queries ignored until END */
index 66985bf3b60a496d924f99a944b54c1bd12b93c1..e99c50bc8664cc15afa118ce97bb20eb9a535d2d 100644 (file)
@@ -71,7 +71,7 @@ bool ECPGdo_descriptor(int line, const char *connection,
                                  const char *descriptor, const char *query);
 bool           ECPGdeallocate_desc(int line, const char *name);
 bool           ECPGallocate_desc(int line, const char *name);
-void           ECPGraise(int line, int code, const char *str);
+void           ECPGraise(int line, int code, const char *str, int);
 bool           ECPGget_desc_header(int, char *, int *);
 bool           ECPGget_desc(int, char *, int,...);
 
index 189d09a2d23025ec97ae4ad0ad2dd36a09621a97..9294e1d77a06cd986afb9416a6fca134b353b0ec 100644 (file)
@@ -17,6 +17,6 @@ extern char *PGTYPEStimestamp_to_asc(Timestamp);
 extern int PGTYPEStimestamp_sub (Timestamp *, Timestamp *, Interval *);
 extern int PGTYPEStimestamp_fmt_asc (Timestamp *, char *, int, char *);
 extern void PGTYPEStimestamp_current (Timestamp *);
-       
+extern int PGTYPEStimestamp_defmt_asc(char *, char *, Timestamp *);
 
 #endif /* PGTYPES_TIMESTAMP */
index 03a45870c02521a9d45cabe37ae361b8b5a816b5..d1202eb59a112d9f105fc204c884acbeb04804e6 100644 (file)
@@ -28,33 +28,33 @@ pgtypes_strdup(char *str)
 }
 
 int
-pgtypes_fmt_replace(union un_fmt_replace replace_val, int replace_type, char** output, int *pstr_len) {
+pgtypes_fmt_replace(union un_fmt_comb replace_val, int replace_type, char** output, int *pstr_len) {
        /* general purpose variable, set to 0 in order to fix compiler
         * warning */
        int i = 0;
        switch(replace_type) {
-               case PGTYPES_REPLACE_NOTHING:
+               case PGTYPES_TYPE_NOTHING:
                        break;
-               case PGTYPES_REPLACE_STRING_CONSTANT:
-               case PGTYPES_REPLACE_STRING_MALLOCED:
-                       i = strlen(replace_val.replace_str);
+               case PGTYPES_TYPE_STRING_CONSTANT:
+               case PGTYPES_TYPE_STRING_MALLOCED:
+                       i = strlen(replace_val.str_val);
                        if (i + 1 <= *pstr_len) {
                                /* copy over i + 1 bytes, that includes the
                                 * tailing terminator */
-                               strncpy(*output, replace_val.replace_str, i + 1);
+                               strncpy(*output, replace_val.str_val, i + 1);
                                *pstr_len -= i;
                                *output += i;
-                               if (replace_type == PGTYPES_REPLACE_STRING_MALLOCED) {
-                                       free(replace_val.replace_str);
+                               if (replace_type == PGTYPES_TYPE_STRING_MALLOCED) {
+                                       free(replace_val.str_val);
                                }
                                return 0;
                        } else {
                                return -1;
                        }
                        break;
-               case PGTYPES_REPLACE_CHAR:
+               case PGTYPES_TYPE_CHAR:
                        if (*pstr_len >= 2) {
-                               (*output)[0] = replace_val.replace_char;
+                               (*output)[0] = replace_val.char_val;
                                (*output)[1] = '\0';
                                (*pstr_len)--;
                                (*output)++;
@@ -63,48 +63,48 @@ pgtypes_fmt_replace(union un_fmt_replace replace_val, int replace_type, char** o
                                return -1;
                        }
                        break;
-               case PGTYPES_REPLACE_DOUBLE_NF:
-               case PGTYPES_REPLACE_INT64:
-               case PGTYPES_REPLACE_UINT:
-               case PGTYPES_REPLACE_UINT_2_LZ:
-               case PGTYPES_REPLACE_UINT_2_LS:
-               case PGTYPES_REPLACE_UINT_3_LZ:
-               case PGTYPES_REPLACE_UINT_4_LZ:
+               case PGTYPES_TYPE_DOUBLE_NF:
+               case PGTYPES_TYPE_INT64:
+               case PGTYPES_TYPE_UINT:
+               case PGTYPES_TYPE_UINT_2_LZ:
+               case PGTYPES_TYPE_UINT_2_LS:
+               case PGTYPES_TYPE_UINT_3_LZ:
+               case PGTYPES_TYPE_UINT_4_LZ:
                        {
                                char* t = pgtypes_alloc(PGTYPES_FMT_NUM_MAX_DIGITS);
                                if (!t) {
                                        return ENOMEM;
                                }
                                switch (replace_type) {
-                                       case PGTYPES_REPLACE_DOUBLE_NF:
+                                       case PGTYPES_TYPE_DOUBLE_NF:
                                                i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
-                                                               "%0.0g", replace_val.replace_double);
+                                                               "%0.0g", replace_val.double_val);
                                                break;
 #ifdef HAVE_INT6
-                                       case PGTYPES_REPLACE_INT64:
+                                       case PGTYPES_TYPE_INT64:
                                                i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
                                                                INT64_FORMAT, replace_val.replace_int64);
                                                break;
 #endif
-                                       case PGTYPES_REPLACE_UINT:
+                                       case PGTYPES_TYPE_UINT:
                                                        i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
-                                                                       "%u", replace_val.replace_uint);
+                                                                       "%u", replace_val.uint_val);
                                                break;
-                                       case PGTYPES_REPLACE_UINT_2_LZ:
+                                       case PGTYPES_TYPE_UINT_2_LZ:
                                                        i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
-                                                                       "%02u", replace_val.replace_uint);
+                                                                       "%02u", replace_val.uint_val);
                                                break;
-                                       case PGTYPES_REPLACE_UINT_2_LS:
+                                       case PGTYPES_TYPE_UINT_2_LS:
                                                        i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
-                                                                       "%2u", replace_val.replace_uint);
+                                                                       "%2u", replace_val.uint_val);
                                                break;
-                                       case PGTYPES_REPLACE_UINT_3_LZ:
+                                       case PGTYPES_TYPE_UINT_3_LZ:
                                                        i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
-                                                                       "%03u", replace_val.replace_uint);
+                                                                       "%03u", replace_val.uint_val);
                                                break;
-                                       case PGTYPES_REPLACE_UINT_4_LZ:
+                                       case PGTYPES_TYPE_UINT_4_LZ:
                                                        i = snprintf(t, PGTYPES_FMT_NUM_MAX_DIGITS,
-                                                                       "%04u", replace_val.replace_uint);
+                                                                       "%04u", replace_val.uint_val);
                                                break;
                                }
 
index 26afea2c646464f360f4530030cc965898a76925..789f8400fa7d0171f3ea33b76832cd1cfd0ff1c6 100644 (file)
@@ -168,10 +168,7 @@ PGTYPESdate_fmt_asc(Date dDate, char* fmtstring, char* outbuf) {
                         { NULL, 0 }
        };
 
-       union {
-               char* replace_str;
-               unsigned int replace_uint;
-       } replace_val;
+       union un_fmt_comb replace_val;
        int replace_type;
 
        int i;
@@ -191,76 +188,76 @@ PGTYPESdate_fmt_asc(Date dDate, char* fmtstring, char* outbuf) {
                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_REPLACE_STRING_CONSTANT;
+                                       replace_val.str_val = pgtypes_date_weekdays_short[dow];
+                                       replace_type = PGTYPES_TYPE_STRING_CONSTANT;
                                        break;
                                case PGTYPES_FMTDATE_DAY_DIGITS_LZ:
-                                       replace_val.replace_uint = tm.tm_mday;
-                                       replace_type = PGTYPES_REPLACE_UINT_2_LZ;
+                                       replace_val.uint_val = tm.tm_mday;
+                                       replace_type = PGTYPES_TYPE_UINT_2_LZ;
                                        break;
                                case PGTYPES_FMTDATE_MONTH_LITERAL_SHORT:
-                                       replace_val.replace_str = months[tm.tm_mon-1];
-                                       replace_type = PGTYPES_REPLACE_STRING_CONSTANT;
+                                       replace_val.str_val = months[tm.tm_mon-1];
+                                       replace_type = PGTYPES_TYPE_STRING_CONSTANT;
                                        break;
                                case PGTYPES_FMTDATE_MONTH_DIGITS_LZ:
-                                       replace_val.replace_uint = tm.tm_mon;
-                                       replace_type = PGTYPES_REPLACE_UINT_2_LZ;
+                                       replace_val.uint_val = tm.tm_mon;
+                                       replace_type = PGTYPES_TYPE_UINT_2_LZ;
                                        break;
                                case PGTYPES_FMTDATE_YEAR_DIGITS_LONG:
-                                       replace_val.replace_uint = tm.tm_year;
-                                       replace_type = PGTYPES_REPLACE_UINT_4_LZ;
+                                       replace_val.uint_val = tm.tm_year;
+                                       replace_type = PGTYPES_TYPE_UINT_4_LZ;
                                        break;
                                case PGTYPES_FMTDATE_YEAR_DIGITS_SHORT:
-                                       replace_val.replace_uint = tm.tm_year % 1000;
-                                       replace_type = PGTYPES_REPLACE_UINT_2_LZ;
+                                       replace_val.uint_val = tm.tm_year % 1000;
+                                       replace_type = PGTYPES_TYPE_UINT_2_LZ;
                                        break;
                                default:
                                        /* should not happen, set something
                                         * anyway */
-                                       replace_val.replace_str = " ";
-                                       replace_type = PGTYPES_REPLACE_STRING_CONSTANT;
+                                       replace_val.str_val = " ";
+                                       replace_type = PGTYPES_TYPE_STRING_CONSTANT;
                        }
                        switch(replace_type) {
-                               case PGTYPES_REPLACE_STRING_MALLOCED:
-                               case PGTYPES_REPLACE_STRING_CONSTANT:
-                                       strncpy(start_pattern, replace_val.replace_str,
-                                                       strlen(replace_val.replace_str));
-                                       if (replace_type == PGTYPES_REPLACE_STRING_MALLOCED) {
-                                               free(replace_val.replace_str);
+                               case PGTYPES_TYPE_STRING_MALLOCED:
+                               case PGTYPES_TYPE_STRING_CONSTANT:
+                                       strncpy(start_pattern, replace_val.str_val,
+                                                       strlen(replace_val.str_val));
+                                       if (replace_type == PGTYPES_TYPE_STRING_MALLOCED) {
+                                               free(replace_val.str_val);
                                        }
                                        break;
-                               case PGTYPES_REPLACE_UINT:
+                               case PGTYPES_TYPE_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);
+                                                               "%u", replace_val.uint_val);
                                                strncpy(start_pattern, t, strlen(t));
                                                free(t);
                                        }
                                        break;
-                               case PGTYPES_REPLACE_UINT_2_LZ:
+                               case PGTYPES_TYPE_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);
+                                                               "%02u", replace_val.uint_val);
                                                strncpy(start_pattern, t, strlen(t));
                                                free(t);
                                        }
                                        break;
-                               case PGTYPES_REPLACE_UINT_4_LZ:
+                               case PGTYPES_TYPE_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);
+                                                               "%04u", replace_val.uint_val);
                                                strncpy(start_pattern, t, strlen(t));
                                                free(t);
                                        }
@@ -268,7 +265,7 @@ PGTYPESdate_fmt_asc(Date dDate, char* fmtstring, char* outbuf) {
                                default:
                                        /* doesn't happen (we set
                                         * replace_type to
-                                        * PGTYPES_REPLACE_STRING_CONSTANT
+                                        * PGTYPES_TYPE_STRING_CONSTANT
                                         * in case of an error above) */
                                        break;
                        }
index 8d41d6f1e03c9a94dd669cd3146825ded362fea8..98761f594144cfb54330d83383eb3f85b72decc1 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "extern.h"
 #include "dt.h"
+#include "pgtypes_timestamp.h"
 
 static int day_tab[2][13] = {
                {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0},
@@ -13,6 +14,8 @@ static int day_tab[2][13] = {
 
 typedef long AbsoluteTime;
 
+int tm2timestamp(struct tm *, fsec_t, int *, Timestamp *);
+       
 #define ABS_SIGNBIT             ((char) 0200)
 #define POS(n)                  (n)
 #define NEG(n)                  ((n)|ABS_SIGNBIT)
@@ -2559,3 +2562,505 @@ DecodeDateTime(char **field, int *ftype, int nf,
        return 0;
 }      /* DecodeDateTime() */
 
+/* Function works as follows:
+ *
+ *
+ * */
+
+static char* find_end_token(char* str, char* fmt) {
+       /* str: here is28the day12the hour
+        * fmt: here is%dthe day%hthe hour
+        *
+        * we extract the 28, we read the percent sign and the type "d"
+        * then this functions gets called as
+        * find_end_token("28the day12the hour", "the day%hthehour")
+        *
+        * fmt points to "the day%hthehour", next_percent points to
+        * %hthehour and we have to find a match for everything between
+        * these positions ("the day"). We look for "the day" in str and
+        * know that the pattern we are about to scan ends where this string
+        * starts (right after the "28")
+        *
+        * At the end, *fmt is '\0' and *str isn't. end_position then is
+        * unchanged.
+        */
+       char* end_position = NULL;
+       char* next_percent, *subst_location = NULL;
+       int scan_offset = 0;
+       char last_char;
+
+       /* are we at the end? */
+       if (!*fmt) {
+               end_position = fmt;
+               return end_position;
+       }
+
+       /* not at the end */
+       while (fmt[scan_offset] == '%' && fmt[scan_offset+1]) {
+               /* there is no delimiter, skip to the next delimiter
+                * if we're reading a number and then something that is not
+                * a number "9:15pm", we might be able to recover with the
+                * strtol end pointer. Go for the next percent sign */
+               scan_offset += 2;
+       }
+       next_percent = strchr(fmt+scan_offset, '%');
+       if (next_percent) {
+               /* we don't want to allocate extra memory, so we temporarily
+                * set the '%' sign to '\0' and call strstr
+                * However since we allow whitespace to float around
+                * everything, we have to shorten the pattern until we reach
+                * a non-whitespace character */
+               
+               subst_location = next_percent;
+               while(*(subst_location-1) == ' ' && subst_location-1 > fmt+scan_offset) {
+                       subst_location--;
+               }
+               last_char = *subst_location;
+               *subst_location = '\0';
+
+               /* the haystack is the str and the needle is the original
+                * fmt but it ends at the position where the next percent
+                * sign would be */
+               /* There is one special case. Imagine:
+                * str = " 2", fmt = "%d %...",
+                * since we want to allow blanks as "dynamic" padding we
+                * have to accept this. Now, we are called with a fmt of
+                * " %..." and look for " " in str. We find it at the first
+                * position and never read the 2... */
+               while (*str == ' ') { str++; }
+               end_position = strstr(str, fmt+scan_offset);
+               *subst_location = last_char;
+       } else {
+               /* there is no other percent sign. So everything up to
+                * the end has to match. */
+               end_position = str + strlen(str);
+       }
+       if (!end_position) {
+               /* maybe we have the following case:
+                *
+                * str = "4:15am"
+                * fmt = "%M:%S %p"
+                *
+                * at this place we could have
+                *
+                * str = "15am"
+                * fmt = " %p"
+                *
+                * and have set fmt to " " because overwrote the % sign with
+                * a NULL
+                *
+                * In this case where we would have to match a space but
+                * can't find it, set end_position to the end of the string */
+               if ((fmt+scan_offset)[0] == ' ' && fmt+scan_offset+1 == subst_location) {
+                       end_position = str + strlen(str);
+               }
+       }
+       return end_position;
+}
+
+static int pgtypes_defmt_scan(union un_fmt_comb* scan_val, int scan_type, char** pstr, char* pfmt) {
+       /* scan everything between pstr and pstr_end.
+        * This is not including the last character so we might set it to
+        * '\0' for the parsing */
+
+       char last_char;
+       int err = 0;
+       char* pstr_end;
+       char* strtol_end = NULL;
+       
+       while (**pstr == ' ') { pstr++; }
+       pstr_end = find_end_token(*pstr, pfmt);
+       if (!pstr_end) {
+               /* there was an error, no match */
+               err = 1;
+               return err;
+       }
+       last_char = *pstr_end;
+       *pstr_end = '\0';
+
+       switch(scan_type) {
+               case PGTYPES_TYPE_UINT:
+                       /* numbers may be blank-padded, this is the only
+                        * deviation from the fmt-string we accept */
+                       while (**pstr == ' ') { (*pstr)++; }
+                       errno = 0;
+                       scan_val->uint_val = (unsigned int) strtol(*pstr, &strtol_end, 10);
+                       if (errno) { err = 1; }
+                       break;
+               case PGTYPES_TYPE_UINT_LONG:
+                       while (**pstr == ' ') { (*pstr)++; }
+                       errno = 0;
+                       scan_val->uint_val = (unsigned long int) strtol(*pstr, &strtol_end, 10);
+                       if (errno) { err = 1; }
+                       break;
+               case PGTYPES_TYPE_STRING_MALLOCED:
+                       if (pstr) {
+                               scan_val->str_val = pgtypes_strdup(*pstr);
+                       }
+       }
+       if (strtol_end && *strtol_end) {
+               *pstr = strtol_end;
+       } else {
+               *pstr = pstr_end;
+       }
+       *pstr_end = last_char;
+       return err;
+}
+
+/* XXX range checking */
+int PGTYPEStimestamp_defmt_scan(char**, char*, Timestamp *, int*, int*, int*,
+                                               int*, int*, int*, int*);
+
+int PGTYPEStimestamp_defmt_scan(char** str, char* fmt, Timestamp *d,
+                       int* year, int* month, int* day,
+                       int* hour, int* minute, int* second,
+                       int* tz) {
+       union un_fmt_comb scan_val;
+       int scan_type;
+
+       char *pstr, *pfmt, *tmp;
+       int err = 1;
+       int j;
+       struct tm tm;
+
+       pfmt = fmt;
+       pstr = *str;
+       
+       while (*pfmt) {
+               err = 0;
+               while (*pfmt == ' ') { pfmt++; }
+               while (*pstr == ' ') { pstr++; }
+               if (*pfmt != '%') {
+                       if (*pfmt == *pstr) {
+                               pfmt++;
+                               pstr++;
+                       } else {
+                               /* XXX Error: no match */
+                               err = 1;
+                               return err;
+                       }
+                       continue;
+               }
+               /* here *pfmt equals '%' */
+               pfmt++;
+               switch(*pfmt) {
+                       case 'a':
+                               pfmt++;
+                               /* we parse the day and see if it is a week
+                                * day but we do not check if the week day
+                                * really matches the date
+                                * */
+                               err = 1; j = 0;
+                               while(pgtypes_date_weekdays_short[j]) {
+                                       if (strncmp(pgtypes_date_weekdays_short[j], pstr,
+                                                       strlen(pgtypes_date_weekdays_short[j])) == 0) {
+                                               /* found it */
+                                               err = 0;
+                                               pstr += strlen(pgtypes_date_weekdays_short[j]);
+                                               break;
+                                       }
+                                       j++;
+                               }
+                               break;
+                       case 'A':
+                               /* see note above */
+                               pfmt++;
+                               err = 1; j = 0;
+                               while(days[j]) {
+                                       if (strncmp(days[j], pstr, strlen(days[j])) == 0) {
+                                               /* found it */
+                                               err = 0;
+                                               pstr += strlen(days[j]);
+                                               break;
+                                       }
+                                       j++;
+                               }
+                               break;
+                       case 'b':
+                       case 'h':
+                               pfmt++;
+                               err = 1; j = 0;
+                               while(months[j]) {
+                                       if (strncmp(months[j], pstr, strlen(months[j])) == 0) {
+                                               /* found it */
+                                               err = 0;
+                                               pstr += strlen(months[j]);
+                                               *month = j+1;
+                                               break;
+                                       }
+                                       j++;
+                               }
+                               break;
+                       case 'B':
+                               /* see note above */
+                               pfmt++;
+                               err = 1; j = 0;
+                               while(pgtypes_date_months[j]) {
+                                       if (strncmp(pgtypes_date_months[j], pstr, strlen(pgtypes_date_months[j])) == 0) {
+                                               /* found it */
+                                               err = 0;
+                                               pstr += strlen(pgtypes_date_months[j]);
+                                               *month = j+1;
+                                               break;
+                                       }
+                                       j++;
+                               }
+                               break;
+                       case 'c':
+                               /* XXX */
+                               break;
+                       case 'C':
+                               pfmt++;
+                               scan_type = PGTYPES_TYPE_UINT;
+                               err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
+                               *year = scan_val.uint_val * 100;
+                               break;
+                       case 'd':
+                       case 'e':
+                               pfmt++;
+                               scan_type = PGTYPES_TYPE_UINT;
+                               err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
+                               *day = scan_val.uint_val;
+                               break;
+                       case 'D':
+                               /* we have to concatenate the strings in
+                                * order to be able to find the end of the
+                                * substitution */
+                               pfmt++;
+                               tmp = pgtypes_alloc(strlen("%m/%d/%y") + strlen(pstr) + 1);
+                               strcpy(tmp, "%m/%d/%y");
+                               strcat(tmp, pfmt);
+                               err = PGTYPEStimestamp_defmt_scan(&pstr, tmp, d, year, month, day, hour, minute, second, tz);
+                               free(tmp);
+                               return err;
+                       case 'm':
+                               pfmt++;
+                               scan_type = PGTYPES_TYPE_UINT;
+                               err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
+                               *month = scan_val.uint_val;
+                               break;
+                       case 'y':
+                       case 'g': /* XXX difference to y (ISO) */
+                               pfmt++;
+                               scan_type = PGTYPES_TYPE_UINT;
+                               err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
+                               if (*year < 0) {
+                                       /* not yet set */
+                                       *year = scan_val.uint_val;
+                               } else {
+                                       *year += scan_val.uint_val;
+                               }
+                               if (*year < 100) { *year += 1900; }
+                               break;
+                       case 'G':
+                               /* XXX difference to %V (ISO) */
+                               pfmt++;
+                               scan_type = PGTYPES_TYPE_UINT;
+                               err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
+                               *year = scan_val.uint_val;
+                               break;
+                       case 'H':
+                       case 'I':
+                       case 'k':
+                       case 'l':
+                               pfmt++;
+                               scan_type = PGTYPES_TYPE_UINT;
+                               err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
+                               *hour += scan_val.uint_val;
+                               break;
+                       case 'j':
+                               pfmt++;
+                               scan_type = PGTYPES_TYPE_UINT;
+                               err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
+                               /* XXX what should we do with that? 
+                                * We could say that it's sufficient if we
+                                * have the year and the day within the year
+                                * to get at least a specific day. */
+                               break;
+                       case 'M':
+                               pfmt++;
+                               scan_type = PGTYPES_TYPE_UINT;
+                               err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
+                               *minute = scan_val.uint_val;
+                               break;
+                       case 'n':
+                               pfmt++;
+                               if (*pstr == '\n') { pstr++; } else { err = 1; }
+                               break;
+                       case 'p':
+                               err = 1;
+                               pfmt++;
+                               if (strncmp(pstr, "am", 2)   == 0) { *hour += 0; err = 0; pstr += 2; }
+                               if (strncmp(pstr, "a.m.", 4) == 0) { *hour += 0; err = 0; pstr += 4; }
+                               if (strncmp(pstr, "pm", 2)   == 0) { *hour += 12; err = 0; pstr += 2; }
+                               if (strncmp(pstr, "p.m.", 4) == 0) { *hour += 12; err = 0; pstr += 4; }
+                               break;    
+                       case 'P':
+                               err = 1;
+                               pfmt++;
+                               if (strncmp(pstr, "AM", 2)   == 0) { *hour += 0;  err = 0; pstr += 2; }
+                               if (strncmp(pstr, "A.M.", 4) == 0) { *hour += 0;  err = 0; pstr += 4; }
+                               if (strncmp(pstr, "PM", 2)   == 0) { *hour += 12; err = 0; pstr += 2; }
+                               if (strncmp(pstr, "P.M.", 4) == 0) { *hour += 12; err = 0; pstr += 4; }
+                               break;
+                       case 'r':
+                               pfmt++;
+                               tmp = pgtypes_alloc(strlen("%I:%M:%S %p") + strlen(pstr) + 1);
+                               strcpy(tmp, "%I:%M:%S %p");
+                               strcat(tmp, pfmt);
+                               err = PGTYPEStimestamp_defmt_scan(&pstr, tmp, d, year, month, day, hour, minute, second, tz);
+                               free(tmp);
+                               return err;
+                       case 'R':
+                               pfmt++;
+                               tmp = pgtypes_alloc(strlen("%H:%M") + strlen(pstr) + 1);
+                               strcpy(tmp, "%H:%M");
+                               strcat(tmp, pfmt);
+                               err = PGTYPEStimestamp_defmt_scan(&pstr, tmp, d, year, month, day, hour, minute, second, tz);
+                               free(tmp);
+                               return err;
+                       case 's':
+                               pfmt++;
+                               scan_type = PGTYPES_TYPE_UINT_LONG;
+                               err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
+                               /* number of seconds in scan_val.luint_val */
+                               {
+                                       struct tm *tms;
+                                       time_t et = (time_t) scan_val.luint_val;
+                                       tms = gmtime(&et);
+                                       *year = tms->tm_year;
+                                       *month = tms->tm_mon;
+                                       *day = tms->tm_mday;
+                                       *hour = tms->tm_hour;
+                                       *minute = tms->tm_min;
+                                       *second = tms->tm_sec;
+                               }
+                               break;
+                       case 'S':
+                               pfmt++;
+                               scan_type = PGTYPES_TYPE_UINT;
+                               err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
+                               *second = scan_val.uint_val;
+                               break;
+                       case 't':
+                               pfmt++;
+                               if (*pstr == '\t') { pstr++; } else { err = 1; }
+                               break;
+                       case 'T':
+                               pfmt++;
+                               tmp = pgtypes_alloc(strlen("%H:%M:%S") + strlen(pstr) + 1);
+                               strcpy(tmp, "%H:%M:%S");
+                               strcat(tmp, pfmt);
+                               err = PGTYPEStimestamp_defmt_scan(&pstr, tmp, d, year, month, day, hour, minute, second, tz);
+                               free(tmp);
+                               return err;
+                       case 'u':
+                               pfmt++;
+                               scan_type = PGTYPES_TYPE_UINT;
+                               err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
+                               if (scan_val.uint_val < 1 || scan_val.uint_val > 7) { err = 1; }
+                               break;
+                       case 'U':
+                               pfmt++;
+                               scan_type = PGTYPES_TYPE_UINT;
+                               err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
+                               if (scan_val.uint_val < 0 || scan_val.uint_val > 53) { err = 1; }
+                               break;
+                       case 'V':
+                               pfmt++;
+                               scan_type = PGTYPES_TYPE_UINT;
+                               err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
+                               if (scan_val.uint_val < 1 || scan_val.uint_val > 53) { err = 1; }
+                               break;
+                       case 'w':
+                               pfmt++;
+                               scan_type = PGTYPES_TYPE_UINT;
+                               err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
+                               if (scan_val.uint_val < 0 || scan_val.uint_val > 6) { err = 1; }
+                               break;
+                       case 'W':
+                               pfmt++;
+                               scan_type = PGTYPES_TYPE_UINT;
+                               err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
+                               if (scan_val.uint_val < 0 || scan_val.uint_val > 53) { err = 1; }
+                               break;
+                       case 'x':
+                       case 'X':
+                               /* XXX */
+                               break;
+                       case 'Y':
+                               pfmt++;
+                               scan_type = PGTYPES_TYPE_UINT;
+                               err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
+                               *year = scan_val.uint_val;
+                               break;
+                       case 'z':
+                               pfmt++;
+                               scan_type = PGTYPES_TYPE_STRING_MALLOCED;
+                               err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
+                               if (!err) {
+                                       err = DecodeTimezone(scan_val.str_val, tz);
+                                       free(scan_val.str_val);
+                               }
+                               break;
+                       case 'Z':
+                               pfmt++;
+                               scan_type = PGTYPES_TYPE_STRING_MALLOCED;
+                               err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);
+                               /* XXX use DecodeSpecial instead ? - it's
+                                * declared static but the arrays as well.
+                                * :-( */
+                               for (j = 0; !err && j < szdatetktbl; j++) {
+                                       if (strcasecmp(datetktbl[j].token, scan_val.str_val) == 0) {
+                                               /* tz calculates the offset
+                                                * for the seconds, the
+                                                * timezone value of the
+                                                * datetktbl table is in
+                                                * quarter hours */
+                                               *tz = -15 * 60 * datetktbl[j].value;
+                                               break;
+                                       }
+                               }
+                               free(scan_val.str_val);
+                               break;
+                       case '+':
+                               /* XXX */
+                               break;
+                       case '%':
+                               pfmt++;
+                               if (*pstr == '%') { pstr++; } else { err = 1; }
+                               break;
+                       default:
+                               err = 1;
+               }
+       }
+       if (!err) {
+               if (*second < 0) { *second = 0; }
+               if (*minute < 0) { *minute = 0; }
+               if (*hour < 0) { *hour = 0; }
+               if (*day < 0) { err = 1;   *day = 1; }
+               if (*month < 0) { err = 1; *month = 1; }
+               if (*year < 0) { err = 1;  *year = 1970; }
+
+               if (*second > 59) { err = 1; *second = 0; }
+               if (*minute > 59) { err = 1; *minute = 0; }
+               if (*hour   > 23) { err = 1; *hour = 0; }
+               if (*month  > 12) { err = 1; *month = 1; }
+               if (*day > day_tab[isleap(*year)][*month-1]) {
+                       *day = day_tab[isleap(*year)][*month-1];
+                       err = 1;
+               }
+
+               tm.tm_sec = *second;
+               tm.tm_min = *minute;
+               tm.tm_hour = *hour;
+               tm.tm_mday = *day;
+               tm.tm_mon = *month;
+               tm.tm_year = *year;
+
+               tm2timestamp(&tm, 0, tz, d);
+       }
+       return err;
+}
+
+/* XXX: 1900 is compiled in as the base for years */
index 90125ffd4525d420bc8bc29c18ef1f2535d6dd61..8004e3d421669b124c11b8ccff91abce4ffcc50c 100644 (file)
@@ -5,32 +5,33 @@
 
 /* These are the constants that decide which printf() format we'll use in
  * order to get a string representation of the value */
-#define PGTYPES_REPLACE_NOTHING                        0
-#define PGTYPES_REPLACE_STRING_MALLOCED                1
-#define PGTYPES_REPLACE_STRING_CONSTANT                2
-#define PGTYPES_REPLACE_CHAR                   3
-#define PGTYPES_REPLACE_DOUBLE_NF              4   /* no fractional part */
-#define PGTYPES_REPLACE_INT64                  5
-#define PGTYPES_REPLACE_UINT                   6
-#define PGTYPES_REPLACE_UINT_2_LZ              7   /* 2 digits, pad with leading zero */
-#define PGTYPES_REPLACE_UINT_2_LS              8   /* 2 digits, pad with leading space */
-#define PGTYPES_REPLACE_UINT_3_LZ              9
-#define PGTYPES_REPLACE_UINT_4_LZ              10
+#define PGTYPES_TYPE_NOTHING                   0
+#define PGTYPES_TYPE_STRING_MALLOCED           1
+#define PGTYPES_TYPE_STRING_CONSTANT           2
+#define PGTYPES_TYPE_CHAR                      3
+#define PGTYPES_TYPE_DOUBLE_NF                 4   /* no fractional part */
+#define PGTYPES_TYPE_INT64                     5
+#define PGTYPES_TYPE_UINT                      6
+#define PGTYPES_TYPE_UINT_2_LZ                 7   /* 2 digits, pad with leading zero */
+#define PGTYPES_TYPE_UINT_2_LS                 8   /* 2 digits, pad with leading space */
+#define PGTYPES_TYPE_UINT_3_LZ                 9
+#define PGTYPES_TYPE_UINT_4_LZ                 10
+#define PGTYPES_TYPE_UINT_LONG                 11
 
 #define PGTYPES_FMT_NUM_MAX_DIGITS             40
 
-union un_fmt_replace {
-       char*                   replace_str;
-       unsigned int            replace_uint;
-       char                    replace_char;
-       unsigned long int       replace_luint;
-       double                  replace_double;
+union un_fmt_comb {
+       char*                   str_val;
+       unsigned int            uint_val;
+       char                    char_val;
+       unsigned long int       luint_val;
+       double                  double_val;
 #ifdef HAVE_INT64_TIMESTAMP
-       int64                   replace_int64;
+       int64                   int64_val;
 #endif
 };
 
-int pgtypes_fmt_replace(union un_fmt_replace, int, char**, int*);
+int pgtypes_fmt_replace(union un_fmt_comb, int, char**, int*);
 
 char *pgtypes_alloc(long);
 char *pgtypes_strdup(char *);
index 564e1f83c6b769c94568383ff375736b8fb457e3..a0b4626bf065df1ad0af69b0da40f92066dfc6b9 100644 (file)
@@ -13,6 +13,9 @@
 #include "pgtypes_date.h"
 #include "datetime.h"
 
+int PGTYPEStimestamp_defmt_scan(char**, char*, Timestamp *, int*, int*, int*,
+                               int*, int*, int*, int*);
+
 #ifdef HAVE_INT64_TIMESTAMP
 static int64
 time2t(const int hour, const int min, const int sec, const fsec_t fsec)
@@ -47,7 +50,7 @@ dt2local(Timestamp dt, int tz)
  *
  * Returns -1 on failure (overflow).
  */
-static int
+int
 tm2timestamp(struct tm * tm, fsec_t fsec, int *tzp, Timestamp *result)
 {
 #ifdef HAVE_INT64_TIMESTAMP
@@ -372,7 +375,7 @@ static int
 dttofmtasc_replace (Timestamp *ts, Date dDate, int dow, struct tm* tm,
                                        char* output, int *pstr_len, char *fmtstr)
 {
-       union un_fmt_replace replace_val;
+       union un_fmt_comb replace_val;
        int replace_type;
        int i;
        char* p = fmtstr;
@@ -382,35 +385,35 @@ dttofmtasc_replace (Timestamp *ts, Date dDate, int dow, struct tm* tm,
                if (*p == '%') {
                        p++;
                        /* fix compiler warning */
-                       replace_type = PGTYPES_REPLACE_NOTHING;
+                       replace_type = PGTYPES_TYPE_NOTHING;
                        switch (*p) {
                                case 'a':
-                                       replace_val.replace_str = pgtypes_date_weekdays_short[dow];
-                                       replace_type = PGTYPES_REPLACE_STRING_CONSTANT;
+                                       replace_val.str_val = pgtypes_date_weekdays_short[dow];
+                                       replace_type = PGTYPES_TYPE_STRING_CONSTANT;
                                        break;
                                case 'A':
-                                       replace_val.replace_str = days[dow];
-                                       replace_type = PGTYPES_REPLACE_STRING_CONSTANT;
+                                       replace_val.str_val = days[dow];
+                                       replace_type = PGTYPES_TYPE_STRING_CONSTANT;
                                        break;
                                case 'b':
                                case 'h':
-                                       replace_val.replace_str = months[tm->tm_mon];
-                                       replace_type = PGTYPES_REPLACE_STRING_CONSTANT;
+                                       replace_val.str_val = months[tm->tm_mon];
+                                       replace_type = PGTYPES_TYPE_STRING_CONSTANT;
                                        break;
                                case 'B':
-                                       replace_val.replace_str = pgtypes_date_months[tm->tm_mon];
-                                       replace_type = PGTYPES_REPLACE_STRING_CONSTANT;
+                                       replace_val.str_val = pgtypes_date_months[tm->tm_mon];
+                                       replace_type = PGTYPES_TYPE_STRING_CONSTANT;
                                        break;
                                case 'c':
                                        /* XXX */
                                        break;
                                case 'C':
-                                       replace_val.replace_uint = (tm->tm_year + 1900) / 100;
-                                       replace_type = PGTYPES_REPLACE_UINT_2_LZ;
+                                       replace_val.uint_val = (tm->tm_year + 1900) / 100;
+                                       replace_type = PGTYPES_TYPE_UINT_2_LZ;
                                        break;
                                case 'd':
-                                       replace_val.replace_uint = tm->tm_mday;
-                                       replace_type = PGTYPES_REPLACE_UINT_2_LZ;
+                                       replace_val.uint_val = tm->tm_mday;
+                                       replace_type = PGTYPES_TYPE_UINT_2_LZ;
                                        break;
                                case 'D':
                                        /* ts, dDate, dow, tm is
@@ -428,8 +431,8 @@ dttofmtasc_replace (Timestamp *ts, Date dDate, int dow, struct tm* tm,
                                        if (i) { return i; }
                                        break;
                                case 'e':
-                                       replace_val.replace_uint = tm->tm_mday;
-                                       replace_type = PGTYPES_REPLACE_UINT_2_LS;
+                                       replace_val.uint_val = tm->tm_mday;
+                                       replace_type = PGTYPES_TYPE_UINT_2_LS;
                                        break;
                                case 'E':
                                        {
@@ -450,7 +453,7 @@ dttofmtasc_replace (Timestamp *ts, Date dDate, int dow, struct tm* tm,
                                                        (*pstr_len)--;
                                                }
                                                tm->tm_mon += 1;
-                                               replace_type = PGTYPES_REPLACE_NOTHING;
+                                               replace_type = PGTYPES_TYPE_NOTHING;
                                                break;
                                        }
                                case 'G':
@@ -463,7 +466,7 @@ dttofmtasc_replace (Timestamp *ts, Date dDate, int dow, struct tm* tm,
                                                (*pstr_len)--;
                                        }
                                        tm->tm_mon += 1;
-                                       replace_type = PGTYPES_REPLACE_NOTHING;
+                                       replace_type = PGTYPES_TYPE_NOTHING;
                                        break;
                                case 'g':
                                        /* XXX: fall back to strftime */
@@ -478,56 +481,56 @@ dttofmtasc_replace (Timestamp *ts, Date dDate, int dow, struct tm* tm,
                                                        (*pstr_len)--;
                                                }
                                                tm->tm_mon += 1;
-                                               replace_type = PGTYPES_REPLACE_NOTHING;
+                                               replace_type = PGTYPES_TYPE_NOTHING;
                                        }
                                        break;
                                case 'H':
-                                       replace_val.replace_uint = tm->tm_hour;
-                                       replace_type = PGTYPES_REPLACE_UINT_2_LZ;
+                                       replace_val.uint_val = tm->tm_hour;
+                                       replace_type = PGTYPES_TYPE_UINT_2_LZ;
                                        break;
                                case 'I':
-                                       replace_val.replace_uint = tm->tm_hour % 12;
-                                       replace_type = PGTYPES_REPLACE_UINT_2_LZ;
+                                       replace_val.uint_val = tm->tm_hour % 12;
+                                       replace_type = PGTYPES_TYPE_UINT_2_LZ;
                                        break;
                                case 'j':
-                                       replace_val.replace_uint = tm->tm_yday;
-                                       replace_type = PGTYPES_REPLACE_UINT_3_LZ;
+                                       replace_val.uint_val = tm->tm_yday;
+                                       replace_type = PGTYPES_TYPE_UINT_3_LZ;
                                        break;
                                case 'k':
-                                       replace_val.replace_uint = tm->tm_hour;
-                                       replace_type = PGTYPES_REPLACE_UINT_2_LS;
+                                       replace_val.uint_val = tm->tm_hour;
+                                       replace_type = PGTYPES_TYPE_UINT_2_LS;
                                        break;
                                case 'l':
-                                       replace_val.replace_uint = tm->tm_hour % 12;
-                                       replace_type = PGTYPES_REPLACE_UINT_2_LS;
+                                       replace_val.uint_val = tm->tm_hour % 12;
+                                       replace_type = PGTYPES_TYPE_UINT_2_LS;
                                        break;
                                case 'm':
-                                       replace_val.replace_uint = tm->tm_mon;
-                                       replace_type = PGTYPES_REPLACE_UINT_2_LZ;
+                                       replace_val.uint_val = tm->tm_mon;
+                                       replace_type = PGTYPES_TYPE_UINT_2_LZ;
                                        break;
                                case 'M':
-                                       replace_val.replace_uint = tm->tm_min;
-                                       replace_type = PGTYPES_REPLACE_UINT_2_LZ;
+                                       replace_val.uint_val = tm->tm_min;
+                                       replace_type = PGTYPES_TYPE_UINT_2_LZ;
                                        break;
                                case 'n':
-                                       replace_val.replace_char = '\n';
-                                       replace_type = PGTYPES_REPLACE_CHAR;
+                                       replace_val.char_val = '\n';
+                                       replace_type = PGTYPES_TYPE_CHAR;
                                        break;
                                case 'p':
                                        if (tm->tm_hour < 12) {
-                                               replace_val.replace_str = "AM";
+                                               replace_val.str_val = "AM";
                                        } else {
-                                               replace_val.replace_str = "PM";
+                                               replace_val.str_val = "PM";
                                        }
-                                       replace_type = PGTYPES_REPLACE_STRING_CONSTANT;
+                                       replace_type = PGTYPES_TYPE_STRING_CONSTANT;
                                        break;
                                case 'P':
                                        if (tm->tm_hour < 12) {
-                                               replace_val.replace_str = "am";
+                                               replace_val.str_val = "am";
                                        } else {
-                                               replace_val.replace_str = "pm";
+                                               replace_val.str_val = "pm";
                                        }
-                                       replace_type = PGTYPES_REPLACE_STRING_CONSTANT;
+                                       replace_type = PGTYPES_TYPE_STRING_CONSTANT;
                                        break;
                                case 'r':
                                        i = dttofmtasc_replace(ts, dDate, dow, tm,
@@ -544,19 +547,19 @@ dttofmtasc_replace (Timestamp *ts, Date dDate, int dow, struct tm* tm,
                                case 's':
 #ifdef HAVE_INT64_TIMESTAMP
                                        replace_val.replace_int64 = ((*ts - SetEpochTimestamp()) / 1000000e0);
-                                       replace_type = PGTYPES_REPLACE_INT64;
+                                       replace_type = PGTYPES_TYPE_INT64;
 #else
-                                       replace_val.replace_double = *ts - SetEpochTimestamp();
-                                       replace_type = PGTYPES_REPLACE_DOUBLE_NF;
+                                       replace_val.double_val = *ts - SetEpochTimestamp();
+                                       replace_type = PGTYPES_TYPE_DOUBLE_NF;
 #endif
                                        break;
                                case 'S':
-                                       replace_val.replace_uint = tm->tm_sec;
-                                       replace_type = PGTYPES_REPLACE_UINT;
+                                       replace_val.uint_val = tm->tm_sec;
+                                       replace_type = PGTYPES_TYPE_UINT;
                                        break;
                                case 't':
-                                       replace_val.replace_char = '\t';
-                                       replace_type = PGTYPES_REPLACE_CHAR;
+                                       replace_val.char_val = '\t';
+                                       replace_type = PGTYPES_TYPE_CHAR;
                                        break;
                                case 'T':
                                        i = dttofmtasc_replace(ts, dDate, dow, tm,
@@ -566,8 +569,8 @@ dttofmtasc_replace (Timestamp *ts, Date dDate, int dow, struct tm* tm,
                                        break;
                                case 'u':
                                        if (dow == 0) { dow = 7; }
-                                       replace_val.replace_uint = dow;
-                                       replace_type = PGTYPES_REPLACE_UINT;
+                                       replace_val.uint_val = dow;
+                                       replace_type = PGTYPES_TYPE_UINT;
                                        break;
                                case 'U':
                                        /* XXX: fall back to strftime */
@@ -579,7 +582,7 @@ dttofmtasc_replace (Timestamp *ts, Date dDate, int dow, struct tm* tm,
                                                (*pstr_len)--;
                                        }
                                        tm->tm_mon += 1;
-                                       replace_type = PGTYPES_REPLACE_NOTHING;
+                                       replace_type = PGTYPES_TYPE_NOTHING;
                                        break;
                                case 'V':
                                        /* XXX: fall back to strftime */
@@ -589,11 +592,11 @@ dttofmtasc_replace (Timestamp *ts, Date dDate, int dow, struct tm* tm,
                                                q++;
                                                (*pstr_len)--;
                                        }
-                                       replace_type = PGTYPES_REPLACE_NOTHING;
+                                       replace_type = PGTYPES_TYPE_NOTHING;
                                        break;
                                case 'w':
-                                       replace_val.replace_uint = dow;
-                                       replace_type = PGTYPES_REPLACE_UINT;
+                                       replace_val.uint_val = dow;
+                                       replace_type = PGTYPES_TYPE_UINT;
                                        break;
                                case 'W':
                                        /* XXX: fall back to strftime */
@@ -605,7 +608,7 @@ dttofmtasc_replace (Timestamp *ts, Date dDate, int dow, struct tm* tm,
                                                (*pstr_len)--;
                                        }
                                        tm->tm_mon += 1;
-                                       replace_type = PGTYPES_REPLACE_NOTHING;
+                                       replace_type = PGTYPES_TYPE_NOTHING;
                                        break;
                                case 'x':
                                        /* XXX: fall back to strftime */
@@ -620,7 +623,7 @@ dttofmtasc_replace (Timestamp *ts, Date dDate, int dow, struct tm* tm,
                                                        (*pstr_len)--;
                                                }
                                                tm->tm_mon += 1;
-                                               replace_type = PGTYPES_REPLACE_NOTHING;
+                                               replace_type = PGTYPES_TYPE_NOTHING;
                                        }
                                        break;
                                case 'X':
@@ -633,15 +636,15 @@ dttofmtasc_replace (Timestamp *ts, Date dDate, int dow, struct tm* tm,
                                                (*pstr_len)--;
                                        }
                                        tm->tm_mon += 1;
-                                       replace_type = PGTYPES_REPLACE_NOTHING;
+                                       replace_type = PGTYPES_TYPE_NOTHING;
                                        break;
                                case 'y':
-                                       replace_val.replace_uint = tm->tm_year % 100;
-                                       replace_type = PGTYPES_REPLACE_UINT_2_LZ;
+                                       replace_val.uint_val = tm->tm_year % 100;
+                                       replace_type = PGTYPES_TYPE_UINT_2_LZ;
                                        break;
                                case 'Y':
-                                       replace_val.replace_uint = tm->tm_year + 1900;
-                                       replace_type = PGTYPES_REPLACE_UINT;
+                                       replace_val.uint_val = tm->tm_year + 1900;
+                                       replace_type = PGTYPES_TYPE_UINT;
                                        break;
                                case 'z':
                                        /* XXX: fall back to strftime */
@@ -653,7 +656,7 @@ dttofmtasc_replace (Timestamp *ts, Date dDate, int dow, struct tm* tm,
                                                (*pstr_len)--;
                                        }
                                        tm->tm_mon += 1;
-                                       replace_type = PGTYPES_REPLACE_NOTHING;
+                                       replace_type = PGTYPES_TYPE_NOTHING;
                                        break;
                                case 'Z':
                                        /* XXX: fall back to strftime */
@@ -665,11 +668,11 @@ dttofmtasc_replace (Timestamp *ts, Date dDate, int dow, struct tm* tm,
                                                (*pstr_len)--;
                                        }
                                        tm->tm_mon += 1;
-                                       replace_type = PGTYPES_REPLACE_NOTHING;
+                                       replace_type = PGTYPES_TYPE_NOTHING;
                                        break;
                                case '%':
-                                       replace_val.replace_char = '%';
-                                       replace_type = PGTYPES_REPLACE_CHAR;
+                                       replace_val.char_val = '%';
+                                       replace_type = PGTYPES_TYPE_CHAR;
                                        break;
                                case '\0':
                                        /* fmtstr: blabla%' */
@@ -749,3 +752,33 @@ PGTYPEStimestamp_sub (Timestamp *ts1, Timestamp *ts2, Interval *iv)
        return 0;
 }
 
+int PGTYPEStimestamp_defmt_asc(char* str, char *fmt, Timestamp *d) {
+       int year, month, day;
+       int hour, minute, second;
+       int tz;
+
+       int i;
+       char* mstr;
+       char* mfmt;
+
+       if (!fmt) {
+               fmt = "%Y-%m-%d %H:%M:%S";
+       }
+       if (!fmt[0]) {
+               return 1;
+       }
+
+       mstr = pgtypes_strdup(str);
+       mfmt = pgtypes_strdup(fmt);
+       /* initialize with impossible values so that we can see if the
+        * fields where specified at all */
+       /* XXX ambiguity with 1 BC for year? */
+       year = -1; month = -1; day = -1; hour = 0; minute = -1; second = -1;
+       tz = 0;
+
+       i = PGTYPEStimestamp_defmt_scan(&mstr, mfmt, d, &year, &month, &day, &hour, &minute, &second, &tz);
+       free(mstr);
+       free(mfmt);
+       return i;
+}
+
index 42f278057ce31a822b9bce026b3101a266f086cb..fb0f6dcb8598c115a2dc75916b481b2038336113 100644 (file)
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.75 2003/06/26 11:37:05 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.76 2003/08/01 08:21:04 meskes Exp $ */
 
 /* New main for ecpg, the PostgreSQL embedded SQL precompiler. */
 /* (C) Michael Meskes <meskes@postgresql.org> Feb 5th, 1998 */
@@ -382,11 +382,13 @@ main(int argc, char *const argv[])
                                lex_init();
 
                                /* we need several includes */
-                               fprintf(yyout, "/* Processed by ecpg (%d.%d.%d) */\n/* These four include files are added by the preprocessor */\n#include <ecpgtype.h>\n#include <ecpglib.h>\n#include <ecpgerrno.h>\n#include <sqlca.h>\n#line 1 \"%s\"\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL, input_filename);
+                               fprintf(yyout, "/* Processed by ecpg (%d.%d.%d) */\n/* These include files are added by the preprocessor */\n#include <ecpgtype.h>\n#include <ecpglib.h>\n#include <ecpgerrno.h>\n#include <sqlca.h>\n#line 1 \"%s\"\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL, input_filename);
 
                                /* add some compatibility headers */
                                if (INFORMIX_MODE)
                                        fprintf(yyout, "/* Needed for informix compatibility */\n#include <ecpg_informix.h>\n");
+                               
+                               fprintf(yyout, "/* End of automatic include section */\n");
 
                                /* and parse the source */
                                yyparse();
index ef8ebbca126cad5a61626e9f9b933c0700629f10..df6edc30a82d437ef14f05f7de6075bbb49171a5 100644 (file)
@@ -19,7 +19,7 @@ main()
        char *fmt, *out, *in;
        char *d1 = "Mon Jan 17 1966";
        char *t1 = "2000-7-12 17:34:29";
-       
+       int i;
        FILE *dbgs;
 
         if ((dbgs = fopen("log", "w")) != NULL)
@@ -71,7 +71,7 @@ main()
        printf("Today in format \"%s\" is \"%s\"\n", fmt, out);
        free(out);
 
-       /* rdefmtdate() */
+       /* rdate_defmt_asc() */
 
        date1 = 0; text = "";
        fmt = "yy/mm/dd";
@@ -81,78 +81,232 @@ main()
         */
        PGTYPESdate_defmt_asc(&date1, fmt, in);
        text = PGTYPESdate_to_asc(date1);
-       printf("defmtdate1: %s\n", text);
+       printf("date_defmt_asc1: %s\n", text);
 
        date1 = 0; text = "";
        fmt = "mmmm. dd. yyyy";
        in = "12/25/95";
        PGTYPESdate_defmt_asc(&date1, fmt, in);
        text = PGTYPESdate_to_asc(date1);
-       printf("defmtdate2: %s\n", text);
+       printf("date_defmt_asc2: %s\n", text);
 
        date1 = 0; text = "";
        fmt = "yy/mm/dd";
        in = "95/12/25";
        PGTYPESdate_defmt_asc(&date1, fmt, in);
        text = PGTYPESdate_to_asc(date1);
-       printf("defmtdate3: %s\n", text);
+       printf("date_defmt_asc3: %s\n", text);
 
        date1 = 0; text = "";
        fmt = "yy/mm/dd";
        in = "1995, December 25th";
        PGTYPESdate_defmt_asc(&date1, fmt, in);
        text = PGTYPESdate_to_asc(date1);
-       printf("defmtdate4: %s\n", text);
+       printf("date_defmt_asc4: %s\n", text);
 
        date1 = 0; text = "";
        fmt = "dd-mm-yy";
        in = "This is 25th day of December, 1995";
        PGTYPESdate_defmt_asc(&date1, fmt, in);
        text = PGTYPESdate_to_asc(date1);
-       printf("defmtdate5: %s\n", text);
+       printf("date_defmt_asc5: %s\n", text);
 
        date1 = 0; text = "";
        fmt = "mmddyy";
        in = "Dec. 25th, 1995";
        PGTYPESdate_defmt_asc(&date1, fmt, in);
        text = PGTYPESdate_to_asc(date1);
-       printf("defmtdate6: %s\n", text);
+       printf("date_defmt_asc6: %s\n", text);
 
        date1 = 0; text = "";
        fmt = "mmm. dd. yyyy";
        in = "dec 25th 1995";
        PGTYPESdate_defmt_asc(&date1, fmt, in);
        text = PGTYPESdate_to_asc(date1);
-       printf("defmtdate7: %s\n", text);
+       printf("date_defmt_asc7: %s\n", text);
 
        date1 = 0; text = "";
        fmt = "mmm. dd. yyyy";
        in = "DEC-25-1995";
        PGTYPESdate_defmt_asc(&date1, fmt, in);
        text = PGTYPESdate_to_asc(date1);
-       printf("defmtdate8: %s\n", text);
+       printf("date_defmt_asc8: %s\n", text);
 
        date1 = 0; text = "";
        fmt = "mm yy   dd.";
        in = "12199525";
        PGTYPESdate_defmt_asc(&date1, fmt, in);
        text = PGTYPESdate_to_asc(date1);
-       printf("defmtdate9: %s\n", text);
+       printf("date_defmt_asc9: %s\n", text);
 
        date1 = 0; text = "";
        fmt = "yyyy fierj mm   dd.";
        in = "19951225";
        PGTYPESdate_defmt_asc(&date1, fmt, in);
        text = PGTYPESdate_to_asc(date1);
-       printf("defmtdate10: %s\n", text);
+       printf("date_defmt_asc10: %s\n", text);
 
        date1 = 0; text = "";
        fmt = "mm/dd/yy";
        in = "122595";
        PGTYPESdate_defmt_asc(&date1, fmt, in);
        text = PGTYPESdate_to_asc(date1);
-       printf("defmtdate12: %s\n", text);
+       printf("date_defmt_asc12: %s\n", text);
+
+       PGTYPEStimestamp_current(&ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_current: Now: %s\n", text);
+
+       ts1 = PGTYPEStimestamp_from_asc("96-02-29", NULL);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_to_asc1: %s\n", text);
+
+       ts1 = PGTYPEStimestamp_from_asc("1994-02-11 3:10:35", NULL);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_to_asc2: %s\n", text);
+
+       ts1 = PGTYPEStimestamp_from_asc("1994-02-11 26:10:35", NULL);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_to_asc3: %s\n", text);
+
+/*     abc-03:10:35-def-02/11/94-gh  */
+/*      12345678901234567890123456789 */
+
+       out = (char*) malloc(32);
+       i = PGTYPEStimestamp_fmt_asc(&ts1, out, 31, "abc-%X-def-%x-ghi%%");
+       printf("timestamp_fmt_asc: %d: %s\n", i, out);
+
+       fmt = "This is a %m/%d/%y %H-%Ml%Stest";
+       in =  "This is a 4/12/80 3-39l12test";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
+
+       fmt = "%a %b %d %H:%M:%S %z %Y";
+       in =  "Tue Jul 22 17:28:44 +0200 2003";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
+
+       fmt = "%a %b %d %H:%M:%S %z %Y";
+       in =  "Tue Feb 29 17:28:44 +0200 2000";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
+
+       fmt = "%a %b %d %H:%M:%S %z %Y";
+       in =  "Tue Feb 29 17:28:44 +0200 1900";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
+
+       fmt = "%a %b %d %H:%M:%S %z %Y";
+       in =  "Tue Feb 29 17:28:44 +0200 1996";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
+
+       fmt = "%b %d %H:%M:%S %z %Y";
+       in =  "      Jul 31 17:28:44 +0200 1996";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
+
+       fmt = "%b %d %H:%M:%S %z %Y";
+       in =  "      Jul 32 17:28:44 +0200 1996";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
+
+       fmt = "%a %b %d %H:%M:%S %z %Y";
+       in =  "Tue Feb 29 17:28:44 +0200 1997";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
 
+       fmt = "%";
+       in =  "Tue Jul 22 17:28:44 +0200 2003";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
+
+       fmt = "a %";
+       in =  "Tue Jul 22 17:28:44 +0200 2003";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
+
+       fmt = "%b, %d %H_%M`%S %z %Y";
+       in =  "    Jul, 22 17_28 `44 +0200  2003  ";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
+
+       fmt = "%a %b %%%d %H:%M:%S %Z %Y";
+       in =  "Tue Jul %22 17:28:44 CEST 2003";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
+
+       fmt = "%a %b %%%d %H:%M:%S %Z %Y";
+       in =  "Tue Jul %22 17:28:44 CEST 2003";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
+
+       fmt = "abc%n %C %B %%%d %H:%M:%S %Z %Y";
+       in =  "abc\n   19 October %22 17:28:44 CEST 2003";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
+
+       fmt = "abc%n %C %B %%%d %H:%M:%S %Z %y";
+       in =  "abc\n   18 October %34 17:28:44 CEST 80";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
+
+       fmt = "";
+       in =  "abc\n   18 October %34 17:28:44 CEST 80";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error (should be error!): %d\n", in, fmt, text, i);
+
+       fmt = NULL;
+       in =  "1980-04-12 3:49:44      ";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
+
+       fmt = "%B %d, %Y. Time: %I:%M%p";
+       in =  "July 14, 1988. Time: 9:15am";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
+
+       in = "September 6 at 01:30 pm in the year 1983";
+       fmt = "%B %d at %I:%M %p in the year %Y";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
+
+       in = "  1976, July 14. Time: 9:15am";
+       fmt = "%Y,   %B %d. Time: %I:%M %p";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
+
+       in = "  1976, July 14. Time: 9:15 am";
+       fmt = "%Y,   %B %d. Time: %I:%M%p";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
+
+       in = "  1976, P.M. July 14. Time: 9:15";
+       fmt = "%Y, %P  %B %d. Time: %I:%M";
+       i = PGTYPEStimestamp_defmt_asc(in, fmt, &ts1);
+       text = PGTYPEStimestamp_to_asc(ts1);
+       printf("timestamp_defmt_asc(%s, %s) = %s, error: %d\n", in, fmt, text, i);
        exec sql rollback;
         exec sql disconnect;