📄 preproc.y
字号:
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.311.2.2 2005/12/02 15:04:48 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 *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, ...){ va_list ap; fprintf(stderr, "%s:%d: ", input_filename, yylineno); switch(type) { case ET_WARNING: fprintf(stderr, "WARNING: "); break; case ET_ERROR: case ET_FATAL: fprintf(stderr, "ERROR: "); break; } va_start(ap, error); vfprintf(stderr, error, ap); va_end(ap); fprintf(stderr, "\n"); switch(type) { case ET_WARNING: break; case ET_ERROR: ret_value = error_code; break; case ET_FATAL: 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. * for instance you can declare variables in a function, and then subsequently use them * { * declare_vars(); * exec sql ... which uses vars declared in the above function * * 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_varchar && 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 if ((ptr->variable->type->type == ECPGt_varchar || 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->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++); } 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) { mmerror(PARSE_ERROR, ET_ERROR, "trying to access an undeclared cursor %s\n", name); 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_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_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 ADMIN AFTER AGGREGATE ALL ALSO ALTER ANALYSE ANALYZE AND ANY ARRAY AS ASC ASSERTION ASSIGNMENT ASYMMETRIC 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 CONNECTION CONSTRAINT CONSTRAINTS CONVERSION_P CONVERT COPY CREATE CREATEDB CREATEROLE CREATEUSER CROSS CSV CURRENT_DATE CURRENT_ROLE 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 DISABLE_P DISTINCT DO DOMAIN_P DOUBLE_P DROP EACH ELSE ENABLE_P 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 GRANTED GREATEST GROUP_P HANDLER HAVING HEADER HOLD HOUR_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING INCREMENT INDEX INHERIT INHERITS INITIALLY INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -