⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 preproc.y

📁 PostgreSQL7.4.6 for Linux
💻 Y
📖 第 1 页 / 共 5 页
字号:
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.263.2.17 2004/06/27 12:32:47 meskes Exp $ *//* Copyright comment */%{#include "postgres_fe.h"#include "extern.h"/* * Variables containing simple states. */int struct_level = 0;int braces_open; /* brace level counter */int ecpg_informix_var = 0;char	errortext[128];char	*connection = NULL;char	*input_filename = NULL;static int	QueryIsRule = 0, FoundInto = 0;static int	initializer = 0;static struct this_type actual_type[STRUCT_DEPTH];static char *actual_startline[STRUCT_DEPTH];/* temporarily store struct members while creating the data structure */struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL };/* also store struct type so we can do a sizeof() later */static char *ECPGstruct_sizeof = NULL;/* for forward declarations we have to store some data as well */static char *forward_name = NULL;struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, 0L, NULL, {NULL}};struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, NULL, {NULL}};static struct inf_compat_col{	char *name;	char *indirection;	struct inf_compat_col *next;} *informix_col;static struct inf_compat_val{	char *val;	struct inf_compat_val *next;} *informix_val;/* * Handle parsing errors and warnings */voidmmerror(int error_code, enum errortype type, char * error){	switch(type)	{		case ET_WARNING:			fprintf(stderr, "%s:%d: WARNING: %s\n", input_filename, yylineno, error);			break;		case ET_ERROR:			fprintf(stderr, "%s:%d: ERROR: %s\n", input_filename, yylineno, error);			ret_value = error_code;			break;		case ET_FATAL:			fprintf(stderr, "%s:%d: ERROR: %s\n", input_filename, yylineno, error);			exit(error_code);	}}/* * string concatenation */static char *cat2_str(char *str1, char *str2){	char * res_str	= (char *)mm_alloc(strlen(str1) + strlen(str2) + 2);	strcpy(res_str, str1);	strcat(res_str, " ");	strcat(res_str, str2);	free(str1);	free(str2);	return(res_str);}static char *cat_str(int count, ...){	va_list		args;	int			i;	char		*res_str;	va_start(args, count);	res_str = va_arg(args, char *);	/* now add all other strings */	for (i = 1; i < count; i++)		res_str = cat2_str(res_str, va_arg(args, char *));	va_end(args);	return(res_str);}char *make_str(const char *str){	char * res_str = (char *)mm_alloc(strlen(str) + 1);	strcpy(res_str, str);	return res_str;}static char *make2_str(char *str1, char *str2){	char * res_str	= (char *)mm_alloc(strlen(str1) + strlen(str2) + 1);	strcpy(res_str, str1);	strcat(res_str, str2);	free(str1);	free(str2);	return(res_str);}static char *make3_str(char *str1, char *str2, char *str3){	char * res_str	= (char *)mm_alloc(strlen(str1) + strlen(str2) +strlen(str3) + 1);	strcpy(res_str, str1);	strcat(res_str, str2);	strcat(res_str, str3);	free(str1);	free(str2);	free(str3);	return(res_str);}/* and the rest */static char *make_name(void){	char * name = (char *)mm_alloc(yyleng + 1);	strncpy(name, yytext, yyleng);	name[yyleng] = '\0';	return(name);}static char *create_questionmarks(char *name, bool array){	struct variable *p = find_variable(name);	int count;	char *result = EMPTY;	/* In case we have a struct, we have to print as many "?" as there are attributes in the struct 	 * An array is only allowed together with an element argument 	 * This is essantially only used for inserts, but using a struct as input parameter is an error anywhere else 	 * so we don't have to worry here. */		if (p->type->type == ECPGt_struct || (array && p->type->type == ECPGt_array && p->type->u.element->type == ECPGt_struct))	{		struct ECPGstruct_member *m;		if (p->type->type == ECPGt_struct)			m = p->type->u.members;		else			m = p->type->u.element->u.members;		for (count = 0; m != NULL; m=m->next, count++);	}	else		count = 1;	for (; count > 0; count --)		result = cat2_str(result, make_str("? , "));	/* removed the trailing " ," */	result[strlen(result)-3] = '\0';	return(result);}static char *adjust_informix(struct arguments *list){	/* Informix accepts DECLARE with variables that are out of scope when OPEN is called.	 * This breaks standard and leads to some very dangerous programming. 	 * Since they do, we have to work around and accept their syntax as well.	 * But we will do so ONLY in Informix mode.	 * We have to change the variables to our own struct and just store the pointer instead of the variable */	 struct arguments *ptr;	 char *result = make_str("");	 for (ptr = list; ptr != NULL; ptr = ptr->next)	 {	 	char temp[20]; /* this should be sufficient unless you have 8 byte integers */		char *original_var;			 	/* change variable name to "ECPG_informix_get_var(<counter>)" */		original_var = ptr->variable->name;		sprintf(temp, "%d))", ecpg_informix_var);				if ((ptr->variable->type->type != ECPGt_char && ptr->variable->type->type != ECPGt_unsigned_char) && atoi(ptr->variable->type->size) > 1)		{			ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ECPGtype_name(ptr->variable->type->u.element->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type, make_str("1")), ptr->variable->type->size), 0);			sprintf(temp, "%d, (", ecpg_informix_var++);		}		else		{			ptr->variable = new_variable(cat_str(4, make_str("*("), mm_strdup(ECPGtype_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size), 0);			sprintf(temp, "%d, &(", ecpg_informix_var++);		}				/* create call to "ECPG_informix_set_var(<counter>, <pointer>. <linen number>)" */		result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n"));				/* now the indicator if there is one */		if (ptr->indicator->type->type != ECPGt_NO_INDICATOR)		{			/* change variable name to "ECPG_informix_get_var(<counter>)" */			original_var = ptr->indicator->name;			sprintf(temp, "%d))", ecpg_informix_var);						/* create call to "ECPG_informix_set_var(<counter>, <pointer>. <linen number>)" */			if (atoi(ptr->indicator->type->size) > 1)			{				ptr->indicator = new_variable(cat_str(4, make_str("("), mm_strdup(ECPGtype_name(ptr->indicator->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->indicator->type->type, ptr->indicator->type->size), 0);				sprintf(temp, "%d, (", ecpg_informix_var++);			}			else			{				ptr->indicator = new_variable(cat_str(4, make_str("*("), mm_strdup(ECPGtype_name(ptr->indicator->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->indicator->type->type, ptr->indicator->type->size), 0);				sprintf(temp, "%d, &(", ecpg_informix_var++);			}			result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n"));		}	 }	 return result;}static struct cursor *add_additional_variables(char *name, bool insert){	struct cursor *ptr;	struct arguments *p;	for (ptr = cur; ptr != NULL; ptr=ptr->next)	{		if (strcmp(ptr->name, name) == 0)			break;	}	if (ptr == NULL)	{		snprintf(errortext, sizeof(errortext), "trying to access an undeclared cursor %s\n", name);		mmerror(PARSE_ERROR, ET_ERROR, errortext);		return NULL;	}	if (insert)	{		/* add all those input variables that were given earlier 		 * note that we have to append here but have to keep the existing order */		for (p = ptr->argsinsert; p; p = p->next)			add_variable_to_tail(&argsinsert, p->variable, p->indicator);	}	/* add all those output variables that were given earlier */	for (p = ptr->argsresult; p; p = p->next)		add_variable_to_tail(&argsresult, p->variable, p->indicator);		return ptr;}%}%union {	double	dval;	char	*str;	int     ival;	struct	when		action;	struct	index		index;	int		tagname;	struct	this_type	type;	enum	ECPGttype	type_enum;	enum	ECPGdtype	dtype_enum;	struct	fetch_desc	descriptor;	struct  su_symbol	struct_union;}/* special embedded SQL token */%token	SQL_ALLOCATE SQL_AUTOCOMMIT SQL_BOOL SQL_BREAK		SQL_CALL SQL_CARDINALITY SQL_CONNECT SQL_CONNECTION		SQL_CONTINUE SQL_COUNT SQL_CURRENT SQL_DATA 		SQL_DATETIME_INTERVAL_CODE		SQL_DATETIME_INTERVAL_PRECISION SQL_DESCRIBE		SQL_DESCRIPTOR SQL_DISCONNECT SQL_ENUM SQL_FOUND		SQL_FREE SQL_GO SQL_GOTO SQL_IDENTIFIED		SQL_INDICATOR SQL_KEY_MEMBER SQL_LENGTH		SQL_LONG SQL_NAME SQL_NULLABLE SQL_OCTET_LENGTH		SQL_OPEN SQL_OUTPUT SQL_RELEASE SQL_REFERENCE		SQL_RETURNED_LENGTH SQL_RETURNED_OCTET_LENGTH SQL_SCALE		SQL_SECTION SQL_SHORT SQL_SIGNED SQL_SQL SQL_SQLERROR		SQL_SQLPRINT SQL_SQLWARNING SQL_START SQL_STOP		SQL_STRUCT SQL_UNSIGNED SQL_VALUE SQL_VAR SQL_WHENEVER/* C token */%token	S_ADD S_AND S_ANYTHING S_AUTO S_CONST S_DEC S_DIV		S_DOTPOINT S_EQUAL S_EXTERN S_INC S_LSHIFT S_MEMPOINT		S_MEMBER S_MOD S_MUL S_NEQUAL S_OR S_REGISTER S_RSHIFT		S_STATIC S_SUB S_VOLATILE		S_TYPEDEF/* I need this and don't know where it is defined inside the backend */%token	TYPECAST/* ordinary key words in alphabetical order */%token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD AFTER        AGGREGATE ALL ALTER ANALYSE ANALYZE AND ANY ARRAY AS ASC	ASSERTION ASSIGNMENT AT AUTHORIZATION        BACKWARD BEFORE BEGIN_P BETWEEN BIGINT BINARY BIT        BOOLEAN_P BOTH BY        CACHE CALLED CASCADE CASE CAST CHAIN CHAR_P	CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE	CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT	COMMITTED CONSTRAINT CONSTRAINTS CONVERSION_P CONVERT COPY        CREATE CREATEDB CREATEUSER CROSS CURRENT_DATE CURRENT_TIME        CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE        DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS	DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS	DESC DISTINCT DO DOMAIN_P DOUBLE_P DROP        EACH ELSE ENCODING ENCRYPTED END_P ESCAPE EXCEPT EXCLUSIVE EXCLUDING        EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT        FALSE_P FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD FREEZE FROM        FULL FUNCTION	GET GLOBAL GRANT GROUP_P        HANDLER HAVING HOLD HOUR_P	ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING INCREMENT	INDEX INHERITS INITIALLY INNER_P INOUT INPUT_P	INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT	INTERVAL INTO INVOKER IS ISNULL ISOLATION        JOIN        KEY	LANCOMPILER LANGUAGE LAST_P LEADING LEFT LEVEL LIKE LIMIT LISTEN        LOAD LOCAL LOCATION LOCK_P	MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE	NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB        NOCREATEUSER NONE NOT NOTHING NOTIFY NOTNULL NULL_P NULLIF        NUMERIC	OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR ORDER        OUT_P OUTER_P OVERLAPS OVERLAY OWNER	PARTIAL PASSWORD PATH_P PENDANT PLACING POSITION	PRECISION PRESERVE PREPARE PRIMARY PRIOR PRIVILEGES PROCEDURAL PROCEDURE	READ REAL RECHECK REFERENCES REINDEX RELATIVE_P RENAME REPLACE	RESET RESTART RESTRICT RETURNS REVOKE RIGHT ROLLBACK ROW ROWS RULE	SCHEMA SCROLL SECOND_P SECURITY SELECT SEQUENCE SERIALIZABLE        SESSION SESSION_USER SET SETOF SHARE SHOW SIMILAR SIMPLE SMALLINT SOME        STABLE START STATEMENT STATISTICS STDIN STDOUT STORAGE STRICT_P        SUBSTRING SYSID        TABLE TEMP TEMPLATE TEMPORARY THEN TIME TIMESTAMP TO TOAST        TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P TRUNCATE TRUSTED TYPE_P        UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL UPDATE USAGE

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -