Boszormenyi Zoltan írta: > I think you forget that in this case, only global variables are > usable in the DECLARE in this case, no local variables in > functions preceding the DECLARE are visible to it. > > What we need here is an extra check in ECPGdump_a_type(). > We need to raise an error if > ECPGdump_a_type(name, type, ...) > and > var = with find_variable(name); > on the passed name disagrees in the variable type and maybe > a warning if they disagree in the brace_level. The same applies > to the indicator variable. For that, we need to pass the brace_level > to ECPGdump_a_type() for both the variable and the indicator. >
I was thinking about something like the attached patch. It passes all the regression tests. Best regards, Zoltán Böszörményi -- Bible has answers for everything. Proof: "But let your communication be, Yea, yea; Nay, nay: for whatsoever is more than these cometh of evil." (Matthew 5:37) - basics of digital technology. "May your kingdom come" - superficial description of plate tectonics ---------------------------------- Zoltán Böszörményi Cybertec Schönig & Schönig GmbH http://www.postgresql.at/
diff -dcrp pgsql.orig/src/interfaces/ecpg/preproc/descriptor.c pgsql/src/interfaces/ecpg/preproc/descriptor.c *** pgsql.orig/src/interfaces/ecpg/preproc/descriptor.c 2010-03-10 14:31:49.000000000 +0100 --- pgsql/src/interfaces/ecpg/preproc/descriptor.c 2010-03-31 12:34:46.000000000 +0200 *************** output_get_descr(char *desc_name, char * *** 188,194 **** break; } fprintf(yyout, "%s,", get_dtype(results->value)); ! ECPGdump_a_type(yyout, v->name, v->type, NULL, NULL, NULL, NULL, make_str("0"), NULL, NULL); } drop_assignments(); fputs("ECPGd_EODT);\n", yyout); --- 188,194 ---- break; } fprintf(yyout, "%s,", get_dtype(results->value)); ! ECPGdump_a_type(yyout, v->name, v->type, NULL, NULL, NULL, NULL, make_str("0"), NULL, NULL, v->brace_level, -1); } drop_assignments(); fputs("ECPGd_EODT);\n", yyout); *************** output_set_descr(char *desc_name, char * *** 293,299 **** case ECPGd_length: case ECPGd_type: fprintf(yyout, "%s,", get_dtype(results->value)); ! ECPGdump_a_type(yyout, v->name, v->type, NULL, NULL, NULL, NULL, make_str("0"), NULL, NULL); break; default: --- 293,299 ---- case ECPGd_length: case ECPGd_type: fprintf(yyout, "%s,", get_dtype(results->value)); ! ECPGdump_a_type(yyout, v->name, v->type, NULL, NULL, NULL, NULL, make_str("0"), NULL, NULL, v->brace_level, -1); break; default: diff -dcrp pgsql.orig/src/interfaces/ecpg/preproc/type.c pgsql/src/interfaces/ecpg/preproc/type.c *** pgsql.orig/src/interfaces/ecpg/preproc/type.c 2010-03-31 12:44:07.000000000 +0200 --- pgsql/src/interfaces/ecpg/preproc/type.c 2010-03-31 13:11:24.000000000 +0200 *************** ECPGstruct_member_dup(struct ECPGstruct_ *** 54,60 **** * if this array does contain a struct again, we have to * create the struct too */ ! if (rm->type->u.element->type == ECPGt_struct) type = ECPGmake_struct_type(rm->type->u.element->u.members, rm->type->u.element->type, rm->type->u.element->type_name, rm->type->u.element->struct_sizeof); else type = ECPGmake_array_type(ECPGmake_simple_type(rm->type->u.element->type, rm->type->u.element->size, rm->type->u.element->counter), rm->type->size); --- 54,60 ---- * if this array does contain a struct again, we have to * create the struct too */ ! if (rm->type->u.element->type == ECPGt_struct || rm->type->u.element->type == ECPGt_union) type = ECPGmake_struct_type(rm->type->u.element->u.members, rm->type->u.element->type, rm->type->u.element->type_name, rm->type->u.element->struct_sizeof); else type = ECPGmake_array_type(ECPGmake_simple_type(rm->type->u.element->type, rm->type->u.element->size, rm->type->u.element->counter), rm->type->size); *************** ECPGdump_a_type(FILE *o, const char *nam *** 240,247 **** const char *ind_name, struct ECPGtype * ind_type, const char *prefix, const char *ind_prefix, char *arr_str_siz, const char *struct_sizeof, ! const char *ind_struct_sizeof) { switch (type->type) { case ECPGt_array: --- 240,283 ---- const char *ind_name, struct ECPGtype * ind_type, const char *prefix, const char *ind_prefix, char *arr_str_siz, const char *struct_sizeof, ! const char *ind_struct_sizeof, ! const int brace_level, const int ind_brace_level) { + struct variable *var; + + if (type->type != ECPGt_descriptor && type->type != ECPGt_sqlda && + type->type != ECPGt_char_variable && + brace_level >= 0) + { + char *str; + + str = strdup(name); + var = find_variable(str); + free(str); + + if ((var->type->type != type->type) || + (var->type->type_name && !type->type_name) || + (!var->type->type_name && type->type_name) || + (var->type->type_name && type->type_name && strcmp(var->type->type_name, type->type_name))) + mmerror(PARSE_ERROR, ET_WARNING, "variable (%s) is hidden by a local variable of a different type", name); + else if (var->brace_level != brace_level) + mmerror(PARSE_ERROR, ET_WARNING, "variable (%s) is hidden by a local variable", name); + + if (ind_name && ind_type && ind_type->type != ECPGt_NO_INDICATOR && ind_brace_level >= 0) + { + str = strdup(ind_name); + var = find_variable(str); + free(str); + if ((var->type->type != ind_type->type) || + (var->type->type_name && !ind_type->type_name) || + (!var->type->type_name && ind_type->type_name) || + (var->type->type_name && ind_type->type_name && strcmp(var->type->type_name, ind_type->type_name))) + mmerror(PARSE_ERROR, ET_WARNING, "indicator variable (%s) is hidden by a local variable of a different type", ind_name); + else if (var->brace_level != ind_brace_level) + mmerror(PARSE_ERROR, ET_WARNING, "indicator variable (%s) is hidden by a local variable", ind_name); + } + } + switch (type->type) { case ECPGt_array: *************** ECPGdump_a_struct(FILE *o, const char *n *** 503,509 **** (ind_p != NULL) ? ind_p->name : NULL, (ind_p != NULL) ? ind_p->type : NULL, prefix, ind_prefix, arrsiz, type->struct_sizeof, ! (ind_p != NULL) ? ind_type->struct_sizeof : NULL); if (ind_p != NULL && ind_p != &struct_no_indicator) ind_p = ind_p->next; } --- 539,546 ---- (ind_p != NULL) ? ind_p->name : NULL, (ind_p != NULL) ? ind_p->type : NULL, prefix, ind_prefix, arrsiz, type->struct_sizeof, ! (ind_p != NULL) ? ind_type->struct_sizeof : NULL, ! -1, -1); if (ind_p != NULL && ind_p != &struct_no_indicator) ind_p = ind_p->next; } diff -dcrp pgsql.orig/src/interfaces/ecpg/preproc/type.h pgsql/src/interfaces/ecpg/preproc/type.h *** pgsql.orig/src/interfaces/ecpg/preproc/type.h 2010-03-10 14:31:49.000000000 +0100 --- pgsql/src/interfaces/ecpg/preproc/type.h 2010-03-30 19:26:26.000000000 +0200 *************** void ECPGfree_type(struct ECPGtype *); *** 57,63 **** */ void ECPGdump_a_type(FILE *, const char *, struct ECPGtype *, const char *, struct ECPGtype *, const char *, ! const char *, char *, const char *, const char *); /* A simple struct to keep a variable and its type. */ struct ECPGtemp_type --- 57,64 ---- */ void ECPGdump_a_type(FILE *, const char *, struct ECPGtype *, const char *, struct ECPGtype *, const char *, ! const char *, char *, const char *, const char *, ! const int, const int); /* A simple struct to keep a variable and its type. */ struct ECPGtemp_type diff -dcrp pgsql.orig/src/interfaces/ecpg/preproc/variable.c pgsql/src/interfaces/ecpg/preproc/variable.c *** pgsql.orig/src/interfaces/ecpg/preproc/variable.c 2010-03-10 14:31:49.000000000 +0100 --- pgsql/src/interfaces/ecpg/preproc/variable.c 2010-03-31 13:02:31.000000000 +0200 *************** new_variable(const char *name, struct EC *** 22,28 **** } static struct variable * ! find_struct_member(char *name, char *str, struct ECPGstruct_member * members, int brace_level) { char *next = strpbrk(++str, ".-["), *end, --- 22,28 ---- } static struct variable * ! find_struct_member(const char *name, char *str, struct ECPGstruct_member * members, int brace_level) { char *next = strpbrk(++str, ".-["), *end, *************** dump_variables(struct arguments * list, *** 446,452 **** /* Then the current element and its indicator */ ECPGdump_a_type(yyout, list->variable->name, list->variable->type, list->indicator->name, list->indicator->type, ! NULL, NULL, make_str("0"), NULL, NULL); /* Then release the list element. */ if (mode != 0) --- 446,453 ---- /* Then the current element and its indicator */ ECPGdump_a_type(yyout, list->variable->name, list->variable->type, list->indicator->name, list->indicator->type, ! NULL, NULL, make_str("0"), NULL, NULL, ! list->variable->brace_level, list->indicator->brace_level); /* Then release the list element. */ if (mode != 0)
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers