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

Reply via email to