mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Synced parser.
Made ecpg parser use backend provided keyword list. Changed whenever test so exit value is 0.
This commit is contained in:
		@@ -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.
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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 $
 | 
			
		||||
 * §
 | 
			
		||||
 *-------------------------------------------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
@@ -21,37 +21,39 @@
 | 
			
		||||
 *		 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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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.
 | 
			
		||||
 *
 | 
			
		||||
@@ -16,50 +23,129 @@
 | 
			
		||||
 *		 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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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"); }
 | 
			
		||||
 
 | 
			
		||||
@@ -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 */
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
}	
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
}	
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user