2011/9/23 Robert Haas <robertmh...@gmail.com>:
> On Fri, Sep 23, 2011 at 12:26 AM, Pavel Stehule <pavel.steh...@gmail.com> 
> wrote:
>> I fixed crash that described Tom. Do you know about other?
>
> No, I just don't see a new version of the patch.
>

sorry - my mistake - I sent it only to Tom

Regards

Pavel


> --
> Robert Haas
> EnterpriseDB: http://www.enterprisedb.com
> The Enterprise PostgreSQL Company
>
*** ./src/pl/plpgsql/src/gram.y.orig	2011-09-19 10:25:28.000000000 +0200
--- ./src/pl/plpgsql/src/gram.y	2011-09-22 22:02:11.000000000 +0200
***************
*** 998,1003 ****
--- 998,1004 ----
  						new->dtype		= PLPGSQL_DTYPE_ARRAYELEM;
  						new->subscript	= $3;
  						new->arrayparentno = $1;
+ 						new->arraytypoid = InvalidOid;
  
  						plpgsql_adddatum((PLpgSQL_datum *) new);
  
*** ./src/pl/plpgsql/src/pl_exec.c.orig	2011-09-19 10:25:28.000000000 +0200
--- ./src/pl/plpgsql/src/pl_exec.c	2011-09-22 22:14:46.000000000 +0200
***************
*** 3991,4008 ****
  				PLpgSQL_expr *subscripts[MAXDIM];
  				int			subscriptvals[MAXDIM];
  				bool		oldarrayisnull;
! 				Oid			arraytypeid,
! 							arrayelemtypeid;
  				int32		arraytypmod;
- 				int16		arraytyplen,
- 							elemtyplen;
- 				bool		elemtypbyval;
- 				char		elemtypalign;
  				Datum		oldarraydatum,
  							coerced_value;
  				ArrayType  *oldarrayval;
  				ArrayType  *newarrayval;
  				SPITupleTable *save_eval_tuptable;
  
  				/*
  				 * We need to do subscript evaluation, which might require
--- 3991,4004 ----
  				PLpgSQL_expr *subscripts[MAXDIM];
  				int			subscriptvals[MAXDIM];
  				bool		oldarrayisnull;
! 				Oid			arraytypoid;
  				int32		arraytypmod;
  				Datum		oldarraydatum,
  							coerced_value;
  				ArrayType  *oldarrayval;
  				ArrayType  *newarrayval;
  				SPITupleTable *save_eval_tuptable;
+ 				PLpgSQL_arrayelem *base_arrayelem;
  
  				/*
  				 * We need to do subscript evaluation, which might require
***************
*** 4027,4032 ****
--- 4023,4030 ----
  				{
  					PLpgSQL_arrayelem *arrayelem = (PLpgSQL_arrayelem *) target;
  
+ 					base_arrayelem = arrayelem;
+ 
  					if (nsubscripts >= MAXDIM)
  						ereport(ERROR,
  								(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
***************
*** 4038,4061 ****
  
  				/* Fetch current value of array datum */
  				exec_eval_datum(estate, target,
! 								&arraytypeid, &arraytypmod,
  								&oldarraydatum, &oldarrayisnull);
  
! 				/* If target is domain over array, reduce to base type */
! 				arraytypeid = getBaseTypeAndTypmod(arraytypeid, &arraytypmod);
  
! 				/* ... and identify the element type */
! 				arrayelemtypeid = get_element_type(arraytypeid);
! 				if (!OidIsValid(arrayelemtypeid))
! 					ereport(ERROR,
! 							(errcode(ERRCODE_DATATYPE_MISMATCH),
! 							 errmsg("subscripted object is not an array")));
  
! 				get_typlenbyvalalign(arrayelemtypeid,
! 									 &elemtyplen,
! 									 &elemtypbyval,
! 									 &elemtypalign);
! 				arraytyplen = get_typlen(arraytypeid);
  
  				/*
  				 * Evaluate the subscripts, switch into left-to-right order.
--- 4036,4067 ----
  
  				/* Fetch current value of array datum */
  				exec_eval_datum(estate, target,
! 								&arraytypoid, &arraytypmod,
  								&oldarraydatum, &oldarrayisnull);
  
! 				/* If base_arrayelem has initialized metadata, then use it */
! 				if (base_arrayelem->arraytypoid != arraytypoid ||
! 					base_arrayelem->arraytypmod != arraytypmod)
! 				{
! 					/* If target is domain over array, reduce to base type */
! 					arraytypoid = getBaseTypeAndTypmod(arraytypoid, &arraytypmod);
  
! 					base_arrayelem->arraytypoid = arraytypoid;
! 					base_arrayelem->arraytypmod = arraytypmod;
  
! 					/* ... and identify the element type */
! 					base_arrayelem->arrayelemtypoid = get_element_type(arraytypoid);
! 					if (!OidIsValid(base_arrayelem->arrayelemtypoid))
! 						ereport(ERROR,
! 								(errcode(ERRCODE_DATATYPE_MISMATCH),
! 								 errmsg("subscripted object is not an array")));
! 
! 					get_typlenbyvalalign(base_arrayelem->arrayelemtypoid,
! 										 &(base_arrayelem->elemtyplen),
! 										 &(base_arrayelem->elemtypbyval),
! 										 &(base_arrayelem->elemtypalign));
! 					base_arrayelem->arraytyplen = get_typlen(arraytypoid);
! 				}
  
  				/*
  				 * Evaluate the subscripts, switch into left-to-right order.
***************
*** 4093,4099 ****
  				/* Coerce source value to match array element type. */
  				coerced_value = exec_simple_cast_value(value,
  													   valtype,
! 													   arrayelemtypeid,
  													   arraytypmod,
  													   *isNull);
  
--- 4099,4105 ----
  				/* Coerce source value to match array element type. */
  				coerced_value = exec_simple_cast_value(value,
  													   valtype,
! 													   base_arrayelem->arrayelemtypoid,
  													   arraytypmod,
  													   *isNull);
  
***************
*** 4107,4118 ****
  				 * array, either, so that's a no-op too.  This is all ugly but
  				 * corresponds to the current behavior of ExecEvalArrayRef().
  				 */
! 				if (arraytyplen > 0 &&	/* fixed-length array? */
  					(oldarrayisnull || *isNull))
  					return;
  
  				if (oldarrayisnull)
! 					oldarrayval = construct_empty_array(arrayelemtypeid);
  				else
  					oldarrayval = (ArrayType *) DatumGetPointer(oldarraydatum);
  
--- 4113,4124 ----
  				 * array, either, so that's a no-op too.  This is all ugly but
  				 * corresponds to the current behavior of ExecEvalArrayRef().
  				 */
! 				if (base_arrayelem->arraytyplen > 0 &&	/* fixed-length array? */
  					(oldarrayisnull || *isNull))
  					return;
  
  				if (oldarrayisnull)
! 					oldarrayval = construct_empty_array(base_arrayelem->arrayelemtypoid);
  				else
  					oldarrayval = (ArrayType *) DatumGetPointer(oldarraydatum);
  
***************
*** 4124,4139 ****
  										subscriptvals,
  										coerced_value,
  										*isNull,
! 										arraytyplen,
! 										elemtyplen,
! 										elemtypbyval,
! 										elemtypalign);
  
  				/*
  				 * Avoid leaking the result of exec_simple_cast_value, if it
  				 * performed a conversion to a pass-by-ref type.
  				 */
! 				if (!*isNull && coerced_value != value && !elemtypbyval)
  					pfree(DatumGetPointer(coerced_value));
  
  				/*
--- 4130,4145 ----
  										subscriptvals,
  										coerced_value,
  										*isNull,
! 										base_arrayelem->arraytyplen,
! 										base_arrayelem->elemtyplen,
! 										base_arrayelem->elemtypbyval,
! 										base_arrayelem->elemtypalign);
  
  				/*
  				 * Avoid leaking the result of exec_simple_cast_value, if it
  				 * performed a conversion to a pass-by-ref type.
  				 */
! 				if (!*isNull && coerced_value != value && !base_arrayelem->elemtypbyval)
  					pfree(DatumGetPointer(coerced_value));
  
  				/*
***************
*** 4145,4151 ****
  				*isNull = false;
  				exec_assign_value(estate, target,
  								  PointerGetDatum(newarrayval),
! 								  arraytypeid, isNull);
  
  				/*
  				 * Avoid leaking the modified array value, too.
--- 4151,4157 ----
  				*isNull = false;
  				exec_assign_value(estate, target,
  								  PointerGetDatum(newarrayval),
! 								  arraytypoid, isNull);
  
  				/*
  				 * Avoid leaking the modified array value, too.
*** ./src/pl/plpgsql/src/plpgsql.h.orig	2011-09-19 10:25:28.000000000 +0200
--- ./src/pl/plpgsql/src/plpgsql.h	2011-09-22 22:11:10.000000000 +0200
***************
*** 299,304 ****
--- 299,311 ----
  	int			dno;
  	PLpgSQL_expr *subscript;
  	int			arrayparentno;	/* dno of parent array variable */
+ 	Oid arraytypoid;				/* oid of arraytype */
+ 	int32 arraytypmod;				/* tymod of arraytype */
+ 	int16 arraytyplen;				/* typlen of arraytype */
+ 	Oid	arrayelemtypoid;				/* oid of element type */
+ 	bool	elemtypbyval;				/* true when elementtype use byval copy */
+ 	int16	elemtyplen;				/* size of element value */
+ 	char	elemtypalign;				/* align of element type */
  } PLpgSQL_arrayelem;
  
  
*** ./src/test/regress/expected/plpgsql.out.orig	2011-09-19 10:25:28.000000000 +0200
--- ./src/test/regress/expected/plpgsql.out	2011-09-22 23:04:39.000000000 +0200
***************
*** 4509,4511 ****
--- 4509,4528 ----
  
  drop function foreach_test(anyarray);
  drop type xy_tuple;
+ create table rtype (id int, ar text[]);
+ create or replace function foo() returns text[] language plpgsql as $$
+ declare
+  r record;
+ begin
+   r := row(12, '{foo,bar,baz}')::rtype;
+   r.ar[2] := 'replace';
+   return r.ar;
+ end$$;
+ select foo();
+         foo        
+ -------------------
+  {foo,replace,baz}
+ (1 row)
+ 
+ drop function foo();
+ drop table rtype;
*** ./src/test/regress/sql/plpgsql.sql.orig	2011-09-22 23:02:16.442135414 +0200
--- ./src/test/regress/sql/plpgsql.sql	2011-09-22 23:04:11.733364057 +0200
***************
*** 3559,3561 ****
--- 3559,3577 ----
  
  drop function foreach_test(anyarray);
  drop type xy_tuple;
+ 
+ create table rtype (id int, ar text[]);
+ 
+ create or replace function foo() returns text[] language plpgsql as $$
+ declare
+  r record;
+ begin
+   r := row(12, '{foo,bar,baz}')::rtype;
+   r.ar[2] := 'replace';
+   return r.ar;
+ end$$;
+ 
+ select foo();
+ 
+ drop function foo();
+ drop table rtype;
-- 
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