Synced parser.
authorMichael Meskes <meskes@postgresql.org>
Tue, 20 May 2008 23:17:32 +0000 (23:17 +0000)
committerMichael Meskes <meskes@postgresql.org>
Tue, 20 May 2008 23:17:32 +0000 (23:17 +0000)
Made ecpg parser use backend provided keyword list.
Changed whenever test so exit value is 0.

13 files changed:
src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/preproc/Makefile
src/interfaces/ecpg/preproc/c_keywords.c
src/interfaces/ecpg/preproc/ecpg_keywords.c
src/interfaces/ecpg/preproc/extern.h
src/interfaces/ecpg/preproc/keywords.c [deleted file]
src/interfaces/ecpg/preproc/pgc.l
src/interfaces/ecpg/preproc/preproc.y
src/interfaces/ecpg/preproc/type.h
src/interfaces/ecpg/test/expected/connect-test1.stderr
src/interfaces/ecpg/test/expected/preproc-whenever.c
src/interfaces/ecpg/test/expected/preproc-whenever.stderr
src/interfaces/ecpg/test/preproc/whenever.pgc

index 0572925d08d4abad4bac58e51190e439d6e144b8..1b3d619017c8a67a139620aec2fa62dddbcb385d 100644 (file)
@@ -2351,6 +2351,13 @@ Mon, 12 May 2008 18:19:08 +0200
 
    - Check for non-existant connection in prepare statement handling.
    - Do not close files that weren't opened.
+
+Tue, 20 May 2008 17:31:01 +0200
+
+   - Synced parser.
+   - Made ecpg parser use backend provided keyword list. One less file to
+     sync manually.
+   - Changed whenever test so exit value is 0.
    - Set pgtypes library version to 3.1.
    - Set compat library version to 3.1.
    - Set ecpg library version to 6.2.
index f03e69fa1d60bd51886270b24c9584acdb4226df..6dd0fa6266dc805e06f350ed737554f2a24222dc 100644 (file)
@@ -4,7 +4,7 @@
 #
 # Copyright (c) 1998-2008, PostgreSQL Global Development Group
 #
-# $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.132 2008/03/18 17:46:23 petere Exp $
+# $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.133 2008/05/20 23:17:32 meskes Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -25,7 +25,7 @@ override CPPFLAGS := -I../include -I$(top_srcdir)/src/interfaces/ecpg/include \
 override CFLAGS += $(PTHREAD_CFLAGS)
 
 OBJS=  preproc.o type.o ecpg.o output.o parser.o \
-   keywords.o c_keywords.o ../ecpglib/typename.o descriptor.o variable.o \
+   keywords.o c_keywords.o ecpg_keywords.o ../ecpglib/typename.o descriptor.o variable.o \
    $(WIN32RES)
 
 all: submake-libpgport ecpg
@@ -56,6 +56,11 @@ endif
 
 c_keywords.o keywords.o preproc.o parser.o: preproc.h
 
+# instead of maintaining our own list, take the one from the backend
+# we cannot just link it in, but must copy and make some minor changes
+keywords.c: % : $(top_srcdir)/src/backend/parser/%
+   sed -e 's/#include "parser\/parse.h"/#include "preproc.h"/' $< > $@
+
 distprep: $(srcdir)/preproc.c $(srcdir)/preproc.h $(srcdir)/pgc.c
 
 install: all installdirs
@@ -68,7 +73,7 @@ uninstall:
    rm -f '$(DESTDIR)$(bindir)/ecpg$(X)'
 
 clean distclean:
-   rm -f *.o ecpg$(X)
+   rm -f keywords.c *.o ecpg$(X)
 # garbage from partial builds
    @rm -f y.tab.c y.tab.h
 # garbage from development
index bd76ac15e64690223482c1158e236edc20612bc9..3ab4f0ed95f6cb5605b0629e290584c2c65049dc 100644 (file)
@@ -3,7 +3,7 @@
  * keywords.c
  *   lexical token lookup for reserved words in postgres embedded SQL
  *
- * $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/c_keywords.c,v 1.21 2007/08/22 08:20:58 meskes Exp $
+ * $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/c_keywords.c,v 1.22 2008/05/20 23:17:32 meskes Exp $
  * ยง
  *-------------------------------------------------------------------------
  */
  *      search is used to locate entries.
  */
 static const ScanKeyword ScanCKeywords[] = {
-   /* name                 value           */
-   {"VARCHAR", VARCHAR},
-   {"auto", S_AUTO},
-   {"bool", SQL_BOOL},
-   {"char", CHAR_P},
-   {"const", S_CONST},
-   {"enum", ENUM_P},
-   {"extern", S_EXTERN},
-   {"float", FLOAT_P},
-   {"hour", HOUR_P},
-   {"int", INT_P},
-   {"long", SQL_LONG},
-   {"minute", MINUTE_P},
-   {"month", MONTH_P},
-   {"register", S_REGISTER},
-   {"second", SECOND_P},
-   {"short", SQL_SHORT},
-   {"signed", SQL_SIGNED},
-   {"static", S_STATIC},
-   {"struct", SQL_STRUCT},
-   {"to", TO},
-   {"typedef", S_TYPEDEF},
-   {"union", UNION},
-   {"unsigned", SQL_UNSIGNED},
-   {"varchar", VARCHAR},
-   {"volatile", S_VOLATILE},
-   {"year", YEAR_P},
+   /* name, value, category */
+   /* category is not needed in ecpg, it is only here so we can share
+         * the data structure with the backend */
+   {"VARCHAR", VARCHAR, 0},
+   {"auto", S_AUTO, 0},
+   {"bool", SQL_BOOL, 0},
+   {"char", CHAR_P, 0},
+   {"const", S_CONST, 0},
+   {"enum", ENUM_P, 0},
+   {"extern", S_EXTERN, 0},
+   {"float", FLOAT_P, 0},
+   {"hour", HOUR_P, 0},
+   {"int", INT_P, 0},
+   {"long", SQL_LONG, 0},
+   {"minute", MINUTE_P, 0},
+   {"month", MONTH_P, 0},
+   {"register", S_REGISTER, 0},
+   {"second", SECOND_P, 0},
+   {"short", SQL_SHORT, 0},
+   {"signed", SQL_SIGNED, 0},
+   {"static", S_STATIC, 0},
+   {"struct", SQL_STRUCT, 0},
+   {"to", TO, 0},
+   {"typedef", S_TYPEDEF, 0},
+   {"union", UNION, 0},
+   {"unsigned", SQL_UNSIGNED, 0},
+   {"varchar", VARCHAR, 0},
+   {"volatile", S_VOLATILE, 0},
+   {"year", YEAR_P, 0},
 };
 
 const ScanKeyword *
-ScanCKeywordLookup(char *text)
+ScanCKeywordLookup(const char *text)
 {
    return DoLookup(text, &ScanCKeywords[0], endof(ScanCKeywords) - 1);
 }
index 98179fe39fcd7a1825da2a178dadd69e5540191e..3d8db4053791bc35e395ff3a789e5fabd10c254e 100644 (file)
@@ -4,11 +4,18 @@
  *   lexical token lookup for reserved words in postgres embedded SQL
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.37 2007/11/15 21:14:45 momjian Exp $
+ *   $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.38 2008/05/20 23:17:32 meskes Exp $
  *
  *-------------------------------------------------------------------------
  */
 
+#include "postgres_fe.h"
+
+#include <ctype.h>
+
+#include "extern.h"
+#include "preproc.h"
+
 /*
  * List of (keyword-name, keyword-token-value) pairs.
  *
  *      search is used to locate entries.
  */
 static const ScanKeyword ScanECPGKeywords[] = {
-   /* name                 value           */
-   {"allocate", SQL_ALLOCATE},
-   {"autocommit", SQL_AUTOCOMMIT},
-   {"bool", SQL_BOOL},
-   {"break", SQL_BREAK},
-   {"call", SQL_CALL},
-   {"cardinality", SQL_CARDINALITY},
-   {"connect", SQL_CONNECT},
-   {"continue", SQL_CONTINUE},
-   {"count", SQL_COUNT},
-   {"data", SQL_DATA},
-   {"datetime_interval_code", SQL_DATETIME_INTERVAL_CODE},
-   {"datetime_interval_precision", SQL_DATETIME_INTERVAL_PRECISION},
-   {"describe", SQL_DESCRIBE},
-   {"descriptor", SQL_DESCRIPTOR},
-   {"disconnect", SQL_DISCONNECT},
-   {"found", SQL_FOUND},
-   {"free", SQL_FREE},
-   {"go", SQL_GO},
-   {"goto", SQL_GOTO},
-   {"identified", SQL_IDENTIFIED},
-   {"indicator", SQL_INDICATOR},
-   {"key_member", SQL_KEY_MEMBER},
-   {"length", SQL_LENGTH},
-   {"long", SQL_LONG},
-   {"nullable", SQL_NULLABLE},
-   {"octet_length", SQL_OCTET_LENGTH},
-   {"open", SQL_OPEN},
-   {"output", SQL_OUTPUT},
-   {"reference", SQL_REFERENCE},
-   {"returned_length", SQL_RETURNED_LENGTH},
-   {"returned_octet_length", SQL_RETURNED_OCTET_LENGTH},
-   {"scale", SQL_SCALE},
-   {"section", SQL_SECTION},
-   {"short", SQL_SHORT},
-   {"signed", SQL_SIGNED},
-   {"sql", SQL_SQL},           /* strange thing, used for into sql descriptor
+   /* name, value, category */
+   /* category is not needed in ecpg, it is only here so we can share
+    * the data structure with the backend */
+   {"allocate", SQL_ALLOCATE, 0},
+   {"autocommit", SQL_AUTOCOMMIT, 0},
+   {"bool", SQL_BOOL, 0},
+   {"break", SQL_BREAK, 0},
+   {"call", SQL_CALL, 0},
+   {"cardinality", SQL_CARDINALITY, 0},
+   {"connect", SQL_CONNECT, 0},
+   {"count", SQL_COUNT, 0},
+   {"data", SQL_DATA, 0},
+   {"datetime_interval_code", SQL_DATETIME_INTERVAL_CODE, 0},
+   {"datetime_interval_precision", SQL_DATETIME_INTERVAL_PRECISION, 0},
+   {"describe", SQL_DESCRIBE, 0},
+   {"descriptor", SQL_DESCRIPTOR, 0},
+   {"disconnect", SQL_DISCONNECT, 0},
+   {"found", SQL_FOUND, 0},
+   {"free", SQL_FREE, 0},
+   {"get", SQL_GET, 0},
+   {"go", SQL_GO, 0},
+   {"goto", SQL_GOTO, 0},
+   {"identified", SQL_IDENTIFIED, 0},
+   {"indicator", SQL_INDICATOR, 0},
+   {"key_member", SQL_KEY_MEMBER, 0},
+   {"length", SQL_LENGTH, 0},
+   {"long", SQL_LONG, 0},
+   {"nullable", SQL_NULLABLE, 0},
+   {"octet_length", SQL_OCTET_LENGTH, 0},
+   {"open", SQL_OPEN, 0},
+   {"output", SQL_OUTPUT, 0},
+   {"reference", SQL_REFERENCE, 0},
+   {"returned_length", SQL_RETURNED_LENGTH, 0},
+   {"returned_octet_length", SQL_RETURNED_OCTET_LENGTH, 0},
+   {"scale", SQL_SCALE, 0},
+   {"section", SQL_SECTION, 0},
+   {"short", SQL_SHORT, 0},
+   {"signed", SQL_SIGNED, 0},
+   {"sql", SQL_SQL, 0},            /* strange thing, used for into sql descriptor
                                 * MYDESC; */
-   {"sqlerror", SQL_SQLERROR},
-   {"sqlprint", SQL_SQLPRINT},
-   {"sqlwarning", SQL_SQLWARNING},
-   {"stop", SQL_STOP},
-   {"struct", SQL_STRUCT},
-   {"unsigned", SQL_UNSIGNED},
-   {"var", SQL_VAR},
-   {"whenever", SQL_WHENEVER},
+   {"sqlerror", SQL_SQLERROR, 0},
+   {"sqlprint", SQL_SQLPRINT, 0},
+   {"sqlwarning", SQL_SQLWARNING, 0},
+   {"stop", SQL_STOP, 0},
+   {"struct", SQL_STRUCT, 0},
+   {"unsigned", SQL_UNSIGNED, 0},
+   {"var", SQL_VAR, 0},
+   {"whenever", SQL_WHENEVER, 0},
 };
+
+/* This is all taken from src/backend/parser/keyword.c and adjusted for our needs. */
+/*
+ * Do a binary search using plain strcmp() comparison.
+ */
+const ScanKeyword *
+DoLookup(const char *word, const ScanKeyword *low, const ScanKeyword *high)
+{
+   while (low <= high)
+   {
+       const ScanKeyword *middle;
+       int         difference;
+
+       middle = low + (high - low) / 2;
+       difference = strcmp(middle->name, word);
+       if (difference == 0)
+           return middle;
+       else if (difference < 0)
+           low = middle + 1;
+       else
+           high = middle - 1;
+   }
+
+   return NULL;
+}
+
+/*
+ * ScanECPGKeywordLookup - see if a given word is a keyword
+ *
+ * Returns a pointer to the ScanKeyword table entry, or NULL if no match.
+ *
+ * The match is done case-insensitively.  Note that we deliberately use a
+ * dumbed-down case conversion that will only translate 'A'-'Z' into 'a'-'z',
+ * even if we are in a locale where tolower() would produce more or different
+ * translations.  This is to conform to the SQL99 spec, which says that
+ * keywords are to be matched in this way even though non-keyword identifiers
+ * receive a different case-normalization mapping.
+ */
+const ScanKeyword *
+ScanECPGKeywordLookup(const char *text)
+{
+   int         len,
+               i;
+   char        word[NAMEDATALEN];
+   const ScanKeyword *res;
+
+   /* First check SQL symbols defined by the backend. */
+
+   res = ScanKeywordLookup(text);
+   if (res)
+       return res;
+
+   len = strlen(text);
+   /* We assume all keywords are shorter than NAMEDATALEN. */
+   if (len >= NAMEDATALEN)
+       return NULL;
+
+   /*
+    * Apply an ASCII-only downcasing. We must not use tolower() since it may
+    * produce the wrong translation in some locales (eg, Turkish).
+    */
+   for (i = 0; i < len; i++)
+   {
+       char        ch = text[i];
+
+       if (ch >= 'A' && ch <= 'Z')
+           ch += 'a' - 'A';
+       word[i] = ch;
+   }
+   word[len] = '\0';
+
+   /*
+    * Now do a binary search using plain strcmp() comparison.
+    */
+
+   return DoLookup(word, &ScanECPGKeywords[0], endof(ScanECPGKeywords) - 1);
+}
index c9097c87eec19e2785135950a323508bc1f34825..7f55441da347be019bb23714c47e5b1c894ee062 100644 (file)
@@ -1,9 +1,10 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/extern.h,v 1.70 2007/11/15 21:14:45 momjian Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/extern.h,v 1.71 2008/05/20 23:17:32 meskes Exp $ */
 
 #ifndef _ECPG_PREPROC_EXTERN_H
 #define _ECPG_PREPROC_EXTERN_H
 
 #include "type.h"
+#include "parser/keywords.h"
 
 #include <errno.h>
 #ifndef CHAR_BIT
@@ -74,7 +75,6 @@ extern void base_yyerror(const char *);
 extern void *mm_alloc(size_t), *mm_realloc(void *, size_t);
 extern char *mm_strdup(const char *);
 extern void mmerror(int, enum errortype, char *,...);
-extern const ScanKeyword *ScanCKeywordLookup(char *);
 extern void output_get_descr_header(char *);
 extern void output_get_descr(char *, char *);
 extern void output_set_descr_header(char *);
@@ -96,8 +96,9 @@ extern void check_indicator(struct ECPGtype *);
 extern void remove_typedefs(int);
 extern void remove_variables(int);
 extern struct variable *new_variable(const char *, struct ECPGtype *, int);
-extern const ScanKeyword *ScanKeywordLookup(char *text);
-extern const ScanKeyword *DoLookup(char *, const ScanKeyword *, const ScanKeyword *);
+extern const ScanKeyword *ScanCKeywordLookup(const char *);
+extern const ScanKeyword *ScanECPGKeywordLookup(const char *text);
+extern const ScanKeyword *DoLookup(const char *, const ScanKeyword *, const ScanKeyword *);
 extern void scanner_init(const char *);
 extern void parser_init(void);
 extern void scanner_finish(void);
diff --git a/src/interfaces/ecpg/preproc/keywords.c b/src/interfaces/ecpg/preproc/keywords.c
deleted file mode 100644 (file)
index 8a92bdf..0000000
+++ /dev/null
@@ -1,476 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * keywords.c
- *   lexical token lookup for reserved words in PostgreSQL
- *
- * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.85 2008/01/01 19:45:59 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-#include "postgres_fe.h"
-
-#include <ctype.h>
-
-#include "extern.h"
-#include "preproc.h"
-
-/* compile both keyword lists in one file because they are always scanned together */
-#include "ecpg_keywords.c"
-
-/*
- * List of (keyword-name, keyword-token-value) pairs.
- *
- * !!WARNING!!: This list must be sorted, because binary
- *      search is used to locate entries.
- */
-static const ScanKeyword ScanPGSQLKeywords[] = {
-   /* name, value */
-   {"abort", ABORT_P},
-   {"absolute", ABSOLUTE_P},
-   {"access", ACCESS},
-   {"action", ACTION},
-   {"add", ADD_P},
-   {"admin", ADMIN},
-   {"after", AFTER},
-   {"aggregate", AGGREGATE},
-   {"all", ALL},
-   {"also", ALSO},
-   {"alter", ALTER},
-   {"always", ALWAYS},
-   {"analyse", ANALYSE},       /* British spelling */
-   {"analyze", ANALYZE},
-   {"and", AND},
-   {"any", ANY},
-   {"array", ARRAY},
-   {"as", AS},
-   {"asc", ASC},
-   {"assertion", ASSERTION},
-   {"assignment", ASSIGNMENT},
-   {"asymmetric", ASYMMETRIC},
-   {"at", AT},
-   {"authorization", AUTHORIZATION},
-   {"backward", BACKWARD},
-   {"before", BEFORE},
-   {"begin", BEGIN_P},
-   {"between", BETWEEN},
-   {"bigint", BIGINT},
-   {"binary", BINARY},
-   {"bit", BIT},
-   {"boolean", BOOLEAN_P},
-   {"both", BOTH},
-   {"by", BY},
-   {"cache", CACHE},
-   {"called", CALLED},
-   {"cascade", CASCADE},
-   {"cascaded", CASCADED},
-   {"case", CASE},
-   {"cast", CAST},
-   {"chain", CHAIN},
-   {"char", CHAR_P},
-   {"character", CHARACTER},
-   {"characteristics", CHARACTERISTICS},
-   {"check", CHECK},
-   {"checkpoint", CHECKPOINT},
-   {"class", CLASS},
-   {"close", CLOSE},
-   {"cluster", CLUSTER},
-   {"coalesce", COALESCE},
-   {"collate", COLLATE},
-   {"column", COLUMN},
-   {"comment", COMMENT},
-   {"commit", COMMIT},
-   {"committed", COMMITTED},
-   {"concurrently", CONCURRENTLY},
-   {"configuration", CONFIGURATION},
-   {"connection", CONNECTION},
-   {"constraint", CONSTRAINT},
-   {"constraints", CONSTRAINTS},
-   {"content", CONTENT_P},
-   {"conversion", CONVERSION_P},
-   {"copy", COPY},
-   {"cost", COST},
-   {"create", CREATE},
-   {"createdb", CREATEDB},
-   {"createrole", CREATEROLE},
-   {"createuser", CREATEUSER},
-   {"cross", CROSS},
-   {"csv", CSV},
-   {"current", CURRENT_P},
-   {"current_date", CURRENT_DATE},
-   {"current_role", CURRENT_ROLE},
-   {"current_time", CURRENT_TIME},
-   {"current_timestamp", CURRENT_TIMESTAMP},
-   {"cursor", CURSOR},
-   {"cycle", CYCLE},
-   {"database", DATABASE},
-   {"day", DAY_P},
-   {"deallocate", DEALLOCATE},
-   {"dec", DEC},
-   {"decimal", DECIMAL_P},
-   {"declare", DECLARE},
-   {"default", DEFAULT},
-   {"defaults", DEFAULTS},
-   {"deferrable", DEFERRABLE},
-   {"deferred", DEFERRED},
-   {"definer", DEFINER},
-   {"delete", DELETE_P},
-   {"delimiter", DELIMITER},
-   {"delimiters", DELIMITERS},
-   {"desc", DESC},
-   {"dictionary", DICTIONARY},
-   {"disable", DISABLE_P},
-   {"discard", DISCARD},
-   {"distinct", DISTINCT},
-   {"do", DO},
-   {"document", DOCUMENT_P},
-   {"domain", DOMAIN_P},
-   {"double", DOUBLE_P},
-   {"drop", DROP},
-   {"each", EACH},
-   {"else", ELSE},
-   {"enable", ENABLE_P},
-   {"encoding", ENCODING},
-   {"encrypted", ENCRYPTED},
-   {"end", END_P},
-   {"enum", ENUM_P},
-   {"escape", ESCAPE},
-   {"except", EXCEPT},
-   {"excluding", EXCLUDING},
-   {"exclusive", EXCLUSIVE},
-   {"execute", EXECUTE},
-   {"exists", EXISTS},
-   {"explain", EXPLAIN},
-   {"external", EXTERNAL},
-   {"extract", EXTRACT},
-   {"false", FALSE_P},
-   {"family", FAMILY},
-   {"fetch", FETCH},
-   {"first", FIRST_P},
-   {"float", FLOAT_P},
-   {"for", FOR},
-   {"force", FORCE},
-   {"foreign", FOREIGN},
-   {"forward", FORWARD},
-   {"freeze", FREEZE},
-   {"from", FROM},
-   {"full", FULL},
-   {"function", FUNCTION},
-   {"get", GET},
-   {"global", GLOBAL},
-   {"grant", GRANT},
-   {"granted", GRANTED},
-   {"greatest", GREATEST},
-   {"group", GROUP_P},
-   {"handler", HANDLER},
-   {"having", HAVING},
-   {"header", HEADER_P},
-   {"hold", HOLD},
-   {"hour", HOUR_P},
-   {"if", IF_P},
-   {"ilike", ILIKE},
-   {"immediate", IMMEDIATE},
-   {"immutable", IMMUTABLE},
-   {"implicit", IMPLICIT_P},
-   {"in", IN_P},
-   {"including", INCLUDING},
-   {"increment", INCREMENT},
-   {"index", INDEX},
-   {"indexes", INDEXES},
-   {"inherit", INHERIT},
-   {"inherits", INHERITS},
-   {"initially", INITIALLY},
-   {"inner", INNER_P},
-   {"inout", INOUT},
-   {"input", INPUT_P},
-   {"insensitive", INSENSITIVE},
-   {"insert", INSERT},
-   {"instead", INSTEAD},
-   {"int", INT_P},
-   {"integer", INTEGER},
-   {"intersect", INTERSECT},
-   {"interval", INTERVAL},
-   {"into", INTO},
-   {"invoker", INVOKER},
-   {"is", IS},
-   {"isnull", ISNULL},
-   {"isolation", ISOLATION},
-   {"join", JOIN},
-   {"key", KEY},
-   {"lancompiler", LANCOMPILER},
-   {"language", LANGUAGE},
-   {"large", LARGE_P},
-   {"last", LAST_P},
-   {"leading", LEADING},
-   {"least", LEAST},
-   {"left", LEFT},
-   {"level", LEVEL},
-   {"like", LIKE},
-   {"limit", LIMIT},
-   {"listen", LISTEN},
-   {"load", LOAD},
-   {"local", LOCAL},
-   {"location", LOCATION},
-   {"lock", LOCK_P},
-   {"login", LOGIN_P},
-   {"mapping", MAPPING},
-   {"match", MATCH},
-   {"maxvalue", MAXVALUE},
-   {"minute", MINUTE_P},
-   {"minvalue", MINVALUE},
-   {"mode", MODE},
-   {"month", MONTH_P},
-   {"move", MOVE},
-   {"name", NAME_P},
-   {"names", NAMES},
-   {"national", NATIONAL},
-   {"natural", NATURAL},
-   {"nchar", NCHAR},
-   {"new", NEW},
-   {"next", NEXT},
-   {"no", NO},
-   {"nocreatedb", NOCREATEDB},
-   {"nocreaterole", NOCREATEROLE},
-   {"nocreateuser", NOCREATEUSER},
-   {"noinherit", NOINHERIT},
-   {"nologin", NOLOGIN_P},
-   {"none", NONE},
-   {"nosuperuser", NOSUPERUSER},
-   {"not", NOT},
-   {"nothing", NOTHING},
-   {"notify", NOTIFY},
-   {"notnull", NOTNULL},
-   {"nowait", NOWAIT},
-   {"null", NULL_P},
-   {"nullif", NULLIF},
-   {"nulls", NULLS_P},
-   {"numeric", NUMERIC},
-   {"object", OBJECT_P},
-   {"of", OF},
-   {"off", OFF},
-   {"offset", OFFSET},
-   {"oids", OIDS},
-   {"old", OLD},
-   {"on", ON},
-   {"only", ONLY},
-   {"operator", OPERATOR},
-   {"option", OPTION},
-   {"or", OR},
-   {"order", ORDER},
-   {"out", OUT_P},
-   {"outer", OUTER_P},
-   {"overlaps", OVERLAPS},
-   {"owned", OWNED},
-   {"owner", OWNER},
-   {"parser", PARSER},
-   {"partial", PARTIAL},
-   {"password", PASSWORD},
-   {"placing", PLACING},
-   {"plans", PLANS},
-   {"position", POSITION},
-   {"precision", PRECISION},
-   {"prepare", PREPARE},
-   {"prepared", PREPARED},
-   {"preserve", PRESERVE},
-   {"primary", PRIMARY},
-   {"prior", PRIOR},
-   {"privileges", PRIVILEGES},
-   {"procedural", PROCEDURAL},
-   {"procedure", PROCEDURE},
-   {"quote", QUOTE},
-   {"read", READ},
-   {"real", REAL},
-   {"reassign", REASSIGN},
-   {"recheck", RECHECK},
-   {"references", REFERENCES},
-   {"reindex", REINDEX},
-   {"relative", RELATIVE_P},
-   {"release", RELEASE},
-   {"rename", RENAME},
-   {"repeatable", REPEATABLE},
-   {"replace", REPLACE},
-   {"replica", REPLICA},
-   {"reset", RESET},
-   {"restart", RESTART},
-   {"restrict", RESTRICT},
-   {"returning", RETURNING},
-   {"returns", RETURNS},
-   {"revoke", REVOKE},
-   {"right", RIGHT},
-   {"role", ROLE},
-   {"rollback", ROLLBACK},
-   {"row", ROW},
-   {"rows", ROWS},
-   {"rule", RULE},
-   {"savepoint", SAVEPOINT},
-   {"schema", SCHEMA},
-   {"scroll", SCROLL},
-   {"search", SEARCH},
-   {"second", SECOND_P},
-   {"security", SECURITY},
-   {"select", SELECT},
-   {"sequence", SEQUENCE},
-   {"serializable", SERIALIZABLE},
-   {"session", SESSION},
-   {"session_user", SESSION_USER},
-   {"set", SET},
-   {"setof", SETOF},
-   {"share", SHARE},
-   {"show", SHOW},
-   {"similar", SIMILAR},
-   {"simple", SIMPLE},
-   {"smallint", SMALLINT},
-   {"some", SOME},
-   {"stable", STABLE},
-   {"standalone", STANDALONE_P},
-   {"start", START},
-   {"statement", STATEMENT},
-   {"statistics", STATISTICS},
-   {"stdin", STDIN},
-   {"stdout", STDOUT},
-   {"storage", STORAGE},
-   {"strict", STRICT_P},
-   {"strip", STRIP_P},
-   {"substring", SUBSTRING},
-   {"superuser", SUPERUSER_P},
-   {"symmetric", SYMMETRIC},
-   {"sysid", SYSID},
-   {"system", SYSTEM_P},
-   {"table", TABLE},
-   {"tablespace", TABLESPACE},
-   {"temp", TEMP},
-   {"template", TEMPLATE},
-   {"temporary", TEMPORARY},
-   {"text", TEXT_P},
-   {"then", THEN},
-   {"time", TIME},
-   {"timestamp", TIMESTAMP},
-   {"to", TO},
-   {"trailing", TRAILING},
-   {"transaction", TRANSACTION},
-   {"treat", TREAT},
-   {"trigger", TRIGGER},
-   {"trim", TRIM},
-   {"true", TRUE_P},
-   {"truncate", TRUNCATE},
-   {"trusted", TRUSTED},
-   {"type", TYPE_P},
-   {"uncommitted", UNCOMMITTED},
-   {"unencrypted", UNENCRYPTED},
-   {"union", UNION},
-   {"unique", UNIQUE},
-   {"unknown", UNKNOWN},
-   {"unlisten", UNLISTEN},
-   {"until", UNTIL},
-   {"update", UPDATE},
-   {"user", USER},
-   {"using", USING},
-   {"vacuum", VACUUM},
-   {"valid", VALID},
-   {"validator", VALIDATOR},
-   {"value", VALUE_P},
-   {"values", VALUES},
-   {"varchar", VARCHAR},
-   {"varying", VARYING},
-   {"verbose", VERBOSE},
-   {"version", VERSION_P},
-   {"view", VIEW},
-   {"volatile", VOLATILE},
-   {"when", WHEN},
-   {"where", WHERE},
-   {"whitespace", WHITESPACE_P},
-   {"with", WITH},
-   {"without", WITHOUT},
-   {"work", WORK},
-   {"write", WRITE},
-   {"xml", XML_P},
-   {"xmlattributes", XMLATTRIBUTES},
-   {"xmlconcat", XMLCONCAT},
-   {"xmlelement", XMLELEMENT},
-   {"xmlforest", XMLFOREST},
-   {"xmlparse", XMLPARSE},
-   {"xmlpi", XMLPI},
-   {"xmlroot", XMLROOT},
-   {"xmlserialize", XMLSERIALIZE},
-   {"year", YEAR_P},
-   {"yes", YES_P},
-   {"zone", ZONE},
-};
-
-
-/*
- * Now do a binary search using plain strcmp() comparison.
- */
-const ScanKeyword *
-DoLookup(char *word, const ScanKeyword *low, const ScanKeyword *high)
-{
-   while (low <= high)
-   {
-       const ScanKeyword *middle;
-       int         difference;
-
-       middle = low + (high - low) / 2;
-       difference = strcmp(middle->name, word);
-       if (difference == 0)
-           return middle;
-       else if (difference < 0)
-           low = middle + 1;
-       else
-           high = middle - 1;
-   }
-
-   return NULL;
-}
-
-/*
- * ScanKeywordLookup - see if a given word is a keyword
- *
- * Returns a pointer to the ScanKeyword table entry, or NULL if no match.
- *
- * The match is done case-insensitively.  Note that we deliberately use a
- * dumbed-down case conversion that will only translate 'A'-'Z' into 'a'-'z',
- * even if we are in a locale where tolower() would produce more or different
- * translations.  This is to conform to the SQL99 spec, which says that
- * keywords are to be matched in this way even though non-keyword identifiers
- * receive a different case-normalization mapping.
- */
-const ScanKeyword *
-ScanKeywordLookup(char *text)
-{
-   int         len,
-               i;
-   char        word[NAMEDATALEN];
-   const ScanKeyword *res;
-
-   len = strlen(text);
-   /* We assume all keywords are shorter than NAMEDATALEN. */
-   if (len >= NAMEDATALEN)
-       return NULL;
-
-   /*
-    * Apply an ASCII-only downcasing.  We must not use tolower() since it may
-    * produce the wrong translation in some locales (eg, Turkish).
-    */
-   for (i = 0; i < len; i++)
-   {
-       char        ch = text[i];
-
-       if (ch >= 'A' && ch <= 'Z')
-           ch += 'a' - 'A';
-       word[i] = ch;
-   }
-   word[len] = '\0';
-
-   /*
-    * Now do a binary search using plain strcmp() comparison.
-    */
-   res = DoLookup(word, &ScanPGSQLKeywords[0], endof(ScanPGSQLKeywords) - 1);
-   if (res)
-       return res;
-
-   return DoLookup(word, &ScanECPGKeywords[0], endof(ScanECPGKeywords) - 1);
-}
index be6f7b0d140b7c6cacf29e120546c7b5135b5c06..a08eb8e2035827b3b9b6e5b6aa339fadafdd58a4 100644 (file)
@@ -12,7 +12,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.165 2008/05/16 15:20:04 petere Exp $
+ *   $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.166 2008/05/20 23:17:32 meskes Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -680,7 +680,7 @@ cppline         {space}*#(.*\\{space})*.*{newline}
                        if (!isdefine())
                        {
                            /* Is it an SQL/ECPG keyword? */
-                           keyword = ScanKeywordLookup(yytext);
+                           keyword = ScanECPGKeywordLookup(yytext);
                            if (keyword != NULL)
                                return keyword->value;
 
index 49acea7640c64b31a584114115db1f520743e7ec..3d39b74580ca03ad172a78732d0f25b519799329 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.365 2008/05/16 15:20:04 petere Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.366 2008/05/20 23:17:32 meskes Exp $ */
 
 /* Copyright comment */
 %{
@@ -392,11 +392,11 @@ add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enu
 /* special embedded SQL token */
 %token SQL_ALLOCATE SQL_AUTOCOMMIT SQL_BOOL SQL_BREAK
        SQL_CALL SQL_CARDINALITY SQL_CONNECT
-       SQL_CONTINUE SQL_COUNT SQL_DATA
+       SQL_COUNT SQL_DATA
        SQL_DATETIME_INTERVAL_CODE
        SQL_DATETIME_INTERVAL_PRECISION SQL_DESCRIBE
        SQL_DESCRIPTOR SQL_DISCONNECT SQL_FOUND
-       SQL_FREE SQL_GO SQL_GOTO SQL_IDENTIFIED
+       SQL_FREE SQL_GET SQL_GO SQL_GOTO SQL_IDENTIFIED
        SQL_INDICATOR SQL_KEY_MEMBER SQL_LENGTH
        SQL_LONG SQL_NULLABLE SQL_OCTET_LENGTH
        SQL_OPEN SQL_OUTPUT SQL_REFERENCE
@@ -427,7 +427,7 @@ add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enu
    CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
    CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
    COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS 
-   CONTENT_P CONVERSION_P COPY COST CREATE CREATEDB
+   CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CREATEDB
    CREATEROLE CREATEUSER CROSS CSV CURRENT_P CURRENT_DATE CURRENT_ROLE
    CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
 
@@ -441,14 +441,14 @@ add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enu
    FALSE_P FAMILY FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD FREEZE FROM
    FULL FUNCTION
 
-   GET GLOBAL GRANT GRANTED GREATEST GROUP_P
+   GLOBAL GRANT GRANTED GREATEST GROUP_P
 
    HANDLER HAVING HEADER_P HOLD HOUR_P
 
-   IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING INCREMENT
-   INDEX INDEXES INHERIT INHERITS INITIALLY INNER_P INOUT INPUT_P
-   INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT
-   INTERVAL INTO INVOKER IS ISNULL ISOLATION
+   IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P
+   INCLUDING INCREMENT INDEX INDEXES INHERIT INHERITS INITIALLY
+   INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
+   INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
 
    JOIN
 
@@ -555,7 +555,7 @@ add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enu
 %type  <str>   ConstraintElem key_actions ColQualList cluster_index_specification
 %type  <str>   target_list target_el alias_clause type_func_name_keyword
 %type  <str>   qualified_name database_name alter_using type_function_name
-%type  <str>   access_method attr_name index_name name func_name
+%type  <str>   access_method attr_name index_name name func_name opt_restart_seqs
 %type  <str>   file_name AexprConst c_expr ConstTypename var_list
 %type  <str>   a_expr b_expr TruncateStmt CommentStmt OnCommitOption opt_by
 %type  <str>   opt_indirection expr_list extract_list extract_arg
@@ -1862,6 +1862,8 @@ OptSeqElem:  CACHE NumConst
            { $$ = cat2_str(make_str("owned by"), $3); }
        | START opt_with NumConst
            { $$ = cat_str(3, make_str("start"), $2, $3); }
+       | RESTART
+           { $$ = make_str("restart"); }
        | RESTART opt_with NumConst
            { $$ = cat_str(3, make_str("restart"), $2, $3); }
        ;
@@ -2179,7 +2181,10 @@ opt_opfamily:  FAMILY any_name       { $$ = cat2_str(make_str("family"), $2); }
                        | /*EMPTY*/ { $$ = EMPTY; }
                ;
 
-opt_recheck:   RECHECK { $$ = make_str("recheck"); }
+opt_recheck:   RECHECK     { 
+                   mmerror(PARSE_ERROR, ET_WARNING, "no longer supported RECHECK OPTION will be passed to backend");
+                   $$ = make_str("recheck");
+               }
        |  /*EMPTY*/    { $$ = EMPTY; }
        ;
 
@@ -2282,10 +2287,16 @@ attrs: '.' attr_name        { $$ = cat2_str(make_str("."), $2); }
  *                truncate table relname1, relname2, ....
  *
  *****************************************************************************/
-TruncateStmt:  TRUNCATE opt_table qualified_name_list opt_drop_behavior
-           { $$ = cat_str(4, make_str("truncate table"), $2, $3, $4); }
+TruncateStmt:  TRUNCATE opt_table qualified_name_list opt_restart_seqs opt_drop_behavior
+           { $$ = cat_str(5, make_str("truncate table"), $2, $3, $4, $5); }
        ;
 
+opt_restart_seqs:
+           CONTINUE_P IDENTITY_P   { $$ = cat2_str(make_str("continue"), make_str("identity")); }
+           | RESTART IDENTITY_P    { $$ = cat2_str(make_str("restart"), make_str("identity")); }
+           | /* EMPTY */       { $$ = EMPTY; }
+           ;
+
 /*****************************************************************************
  *
  *     QUERY:
@@ -2852,6 +2863,8 @@ RenameStmt:  ALTER AGGREGATE func_name aggr_args RENAME TO name
            { $$ = cat_str(4, make_str("alter text search template"), $5, make_str("rename to"), $8); }
        | ALTER TEXT_P SEARCH CONFIGURATION any_name RENAME TO name
            { $$ = cat_str(4, make_str("alter text search configuration"), $5, make_str("rename to"), $8); }
+       | ALTER TYPE_P any_name RENAME TO name
+           { $$ = cat_str(4, make_str("alter type"), $3, make_str("rename to"), $6); }
        ;
 
 opt_column:  COLUMN            { $$ = make_str("column"); }
@@ -2960,6 +2973,7 @@ event:    SELECT              { $$ = make_str("select"); }
        | UPDATE            { $$ = make_str("update"); }
        | DELETE_P          { $$ = make_str("delete"); }
        | INSERT            { $$ = make_str("insert"); }
+       | TRUNCATE          { $$ = make_str("truncate"); }
        ;
 
 opt_instead:  INSTEAD      { $$ = make_str("instead"); }
@@ -4538,29 +4552,26 @@ expr_list:  a_expr
            { $$ = cat_str(3, $1, make_str(","), $3); }
        ;
 
-extract_list:  extract_arg FROM a_expr
-           { $$ = cat_str(3, $1, make_str("from"), $3); }
-       | /* EMPTY */
-           { $$ = EMPTY; }
-       ;
-
 type_list:  Typename
            { $$ = $1; }
        | type_list ',' Typename
            { $$ = cat_str(3, $1, ',', $3); }
        ;
 
+array_expr: '[' expr_list ']'          { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
+       | '[' array_expr_list ']'   { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
+       | '[' ']'           { $$ = make_str("[]"); }
+       ;
+
 array_expr_list: array_expr                { $$ = $1; }
        | array_expr_list ',' array_expr    { $$ = cat_str(3, $1, make_str(","), $3); }
        ;
 
-
-array_expr: '[' expr_list ']'          { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
-       | '[' array_expr_list ']'   { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
+extract_list:  extract_arg FROM a_expr
+           { $$ = cat_str(3, $1, make_str("from"), $3); }
+       | /* EMPTY */
+           { $$ = EMPTY; }
        ;
-/* Allow delimited string SCONST in extract_arg as an SQL extension.
- * - thomas 2001-04-12
- */
 
 extract_arg:  ident                { $$ = $1; }
        | YEAR_P                { $$ = make_str("year"); }
@@ -4703,6 +4714,14 @@ target_list:  target_list ',' target_el
 
 target_el: a_expr AS ColLabel
            { $$ = cat_str(3, $1, make_str("as"), $3); }
+       /*
+        * We support omitting AS only for column labels that aren't
+        * any known keyword.  There is an ambiguity against postfix
+        * operators: is "a ! b" an infix expression, or a postfix
+        * expression and a column label?  We prefer to resolve this
+        * as an infix expression, which we accomplish by assigning
+        * IDENT a precedence higher than POSTFIXOP.
+        */
        | a_expr IDENT
            { $$ = cat_str(3, $1, make_str("as"), $2); }
        | a_expr
@@ -5999,7 +6018,7 @@ ECPGDeallocateDescr:  DEALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
  * manipulate a descriptor header
  */
 
-ECPGGetDescriptorHeader: GET SQL_DESCRIPTOR quoted_ident_stringvar ECPGGetDescHeaderItems
+ECPGGetDescriptorHeader: SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar ECPGGetDescHeaderItems
            {  $$ = $3; }
        ;
 
@@ -6034,7 +6053,7 @@ desc_header_item: SQL_COUNT           { $$ = ECPGd_count; }
  * manipulate a descriptor
  */
 
-ECPGGetDescriptor: GET SQL_DESCRIPTOR quoted_ident_stringvar VALUE_P IntConstVar ECPGGetDescItems
+ECPGGetDescriptor: SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar VALUE_P IntConstVar ECPGGetDescItems
            {  $$.str = $5; $$.name = $3; }
        ;
 
@@ -6214,7 +6233,7 @@ ECPGWhenever: SQL_WHENEVER SQL_SQLERROR action
        }
        ;
 
-action : SQL_CONTINUE
+action : CONTINUE_P
        {
            $<action>$.code = W_NOTHING;
            $<action>$.command = NULL;
@@ -6280,7 +6299,6 @@ ECPGKeywords: ECPGKeywords_vanames    { $$ = $1; }
 ECPGKeywords_vanames:  SQL_BREAK       { $$ = make_str("break"); }
        | SQL_CALL                      { $$ = make_str("call"); }
        | SQL_CARDINALITY               { $$ = make_str("cardinality"); }
-       | SQL_CONTINUE                  { $$ = make_str("continue"); }
        | SQL_COUNT                     { $$ = make_str("count"); }
        | SQL_DATA                      { $$ = make_str("data"); }
        | SQL_DATETIME_INTERVAL_CODE    { $$ = make_str("datetime_interval_code"); }
@@ -6467,6 +6485,7 @@ ECPGunreserved_con:     ABORT_P           { $$ = make_str("abort"); }
 /*     | CONNECTION        { $$ = make_str("connection"); }*/
        | CONSTRAINTS       { $$ = make_str("constraints"); }
        | CONTENT_P     { $$ = make_str("content"); }
+       | CONTINUE_P        { $$ = make_str("continue"); }
        | CONVERSION_P      { $$ = make_str("conversion"); }
        | COPY              { $$ = make_str("copy"); }
        | COST              { $$ = make_str("cost"); }
@@ -6515,6 +6534,7 @@ ECPGunreserved_con:     ABORT_P           { $$ = make_str("abort"); }
        | HEADER_P          { $$ = make_str("header"); }
        | HOLD              { $$ = make_str("hold"); }
 /*     | HOUR_P            { $$ = make_str("hour"); }*/
+       | IDENTITY_P            { $$ = make_str("identity"); }
        | IF_P              { $$ = make_str("if"); }
        | IMMEDIATE         { $$ = make_str("immediate"); }
        | IMMUTABLE         { $$ = make_str("immutable"); }
index 89195077baef1d20af84463d5ec0389b74001106..28cbbe62d7b7e8926e1b6d5c6966c65ec442112d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/type.h,v 1.49 2008/05/17 01:28:25 adunstan Exp $ 
+ * $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/type.h,v 1.50 2008/05/20 23:17:32 meskes Exp $ 
  */
 #ifndef _ECPG_PREPROC_TYPE_H
 #define _ECPG_PREPROC_TYPE_H
@@ -190,10 +190,4 @@ struct fetch_desc
    char       *name;
 };
 
-typedef struct ScanKeyword
-{
-   char       *name;
-   int         value;
-} ScanKeyword;
-
 #endif   /* _ECPG_PREPROC_TYPE_H */
index 30ebfac6074ea56848f7904cfc6995197a35b7e3..3737d5c681318cba042d070b034fe7b4788a6fd6 100644 (file)
@@ -2,68 +2,68 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database connectdb on <DEFAULT> port <DEFAULT>  
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute line 23: QUERY: alter user connectuser  encrypted password 'connectpw' with 0 parameter on connection main 
+[NO_PID]: ecpg_execute on line 23: query: alter user connectuser  encrypted password 'connectpw'; with 0 parameter(s) on connection main
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute line 23: using PQexec
+[NO_PID]: ecpg_execute on line 23: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute line 23 Ok: ALTER ROLE
+[NO_PID]: ecpg_execute on line 23: OK: ALTER ROLE
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection main closed.
+[NO_PID]: ecpg_finish: connection main closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database connectdb on localhost port <DEFAULT>  
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection main closed.
+[NO_PID]: ecpg_finish: connection main closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database <DEFAULT> on localhost port <DEFAULT>  for user connectdb
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection main closed.
+[NO_PID]: ecpg_finish: connection main closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database connectdb on localhost port <REGRESSION_PORT>  
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection main closed.
+[NO_PID]: ecpg_finish: connection main closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database <DEFAULT> on localhost port <REGRESSION_PORT>  for user connectdb
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection main closed.
+[NO_PID]: ecpg_finish: connection main closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database connectdb on <DEFAULT> port <REGRESSION_PORT>  
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection main closed.
+[NO_PID]: ecpg_finish: connection main closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database <DEFAULT> on <DEFAULT> port <REGRESSION_PORT>  for user connectdb
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection main closed.
+[NO_PID]: ecpg_finish: connection main closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database connectdb on localhost port <REGRESSION_PORT>  for user connectuser
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection connectdb closed.
+[NO_PID]: ecpg_finish: connection connectdb closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database <DEFAULT> on localhost port <REGRESSION_PORT>  for user connectdb
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection (null) closed.
+[NO_PID]: ecpg_finish: connection (null) closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database connectdb on localhost port <REGRESSION_PORT>  for user connectuser
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection connectdb closed.
+[NO_PID]: ecpg_finish: connection connectdb closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database connectdb on <DEFAULT> port <REGRESSION_PORT>  for user connectuser
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection connectdb closed.
+[NO_PID]: ecpg_finish: connection connectdb closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database connectdb on <DEFAULT> port <REGRESSION_PORT> with options connect_timeout=14 for user connectuser
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection connectdb closed.
+[NO_PID]: ecpg_finish: connection connectdb closed
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database nonexistant on localhost port <REGRESSION_PORT>  for user connectuser
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: could not open database: FATAL:  database "nonexistant" does not exist
 
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection nonexistant closed.
+[NO_PID]: ecpg_finish: connection nonexistant closed
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: raising sqlcode -402 in line 62, 'Could not connect to database nonexistant in line 62.'.
+[NO_PID]: raising sqlcode -402 on line 62: could not connect to database "nonexistant" on line 62
 [NO_PID]: sqlca: code: -402, state: 08001
-[NO_PID]: raising sqlcode -220 in line 63, 'No such connection CURRENT in line 63.'.
+[NO_PID]: raising sqlcode -220 on line 63: no such connection CURRENT on line 63
 [NO_PID]: sqlca: code: -220, state: 08003
 [NO_PID]: ECPGconnect: opening database connectdb on localhost port <REGRESSION_PORT>  for user connectuser
 [NO_PID]: sqlca: code: 0, state: 00000
@@ -72,9 +72,9 @@
    TCP/IP connections on port 20?
 
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_finish: Connection connectdb closed.
+[NO_PID]: ecpg_finish: connection connectdb closed
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: raising sqlcode -402 in line 66, 'Could not connect to database connectdb in line 66.'.
+[NO_PID]: raising sqlcode -402 on line 66: could not connect to database "connectdb" on line 66
 [NO_PID]: sqlca: code: -402, state: 08001
 [NO_PID]: ECPGconnect: opening database connectdb on <DEFAULT> port <REGRESSION_PORT>  for user connectuser
 [NO_PID]: sqlca: code: 0, state: 00000
index c3459205372b1ed0905eb8b0af88673e180578cf..9f15b7708b9ac273e3e2671683392c9973e25355 100644 (file)
@@ -220,25 +220,27 @@ if (sqlca.sqlcode < 0) goto error;}
    /* exec sql whenever sqlerror  stop ; */
 #line 61 "whenever.pgc"
 
-   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select  *  from nonexistant   ", ECPGt_EOIT, 
+   /* This cannot fail, thus we don't get an exit value not equal 0. */
+   /* However, it still test the precompiler output. */
+   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select  1     ", ECPGt_EOIT, 
    ECPGt_int,&(i),(long)1,(long)1,sizeof(int), 
    ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
-#line 62 "whenever.pgc"
+#line 64 "whenever.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') warn (  );
-#line 62 "whenever.pgc"
+#line 64 "whenever.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
-#line 62 "whenever.pgc"
+#line 64 "whenever.pgc"
 
    { ECPGtrans(__LINE__, NULL, "rollback");
-#line 63 "whenever.pgc"
+#line 65 "whenever.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') warn (  );
-#line 63 "whenever.pgc"
+#line 65 "whenever.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
-#line 63 "whenever.pgc"
+#line 65 "whenever.pgc"
 
    exit (0);
 }  
index 519cd8f684043bd01c37c6ce4752c09af1b70443..207e5fa766a9f07642eb1fad3cf4a49cc8990079 100644 (file)
@@ -82,11 +82,13 @@ sql error: relation "nonexistant" does not exist on line 47
 [NO_PID]: sqlca: code: -400, state: 42P01
 [NO_PID]: ECPGtrans on line 59: action "rollback"; connection "regress1"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 62: query: select  *  from nonexistant   ; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 64: query: select  1     ; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 62: using PQexec
+[NO_PID]: ecpg_execute on line 64: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_check_PQresult on line 62: ERROR:  relation "nonexistant" does not exist
+[NO_PID]: ecpg_execute on line 64: correctly got 1 tuples with 1 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 64: RESULT: 1 offset: -1; array: yes
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGtrans on line 65: action "rollback"; connection "regress1"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: raising sqlstate 42P01 (sqlcode -400) on line 62: relation "nonexistant" does not exist on line 62
-[NO_PID]: sqlca: code: -400, state: 42P01
index ad5632780448d06979debb2432cf796c6953d3a1..bba78ee02339b2bfa04c9a486c51eb945fa77036 100644 (file)
@@ -59,7 +59,9 @@ int main(void)
    exec sql rollback;
 
    exec sql whenever sqlerror stop;
-   exec sql select * into :i from nonexistant;
+   /* This cannot fail, thus we don't get an exit value not equal 0. */
+   /* However, it still test the precompiler output. */
+   exec sql select 1 into :i;
    exec sql rollback;
    exit (0);
 }