Marti Raudsepp <ma...@juffo.org> writes:
> On Sun, Jan 19, 2014 at 8:10 PM, Tom Lane <t...@sss.pgh.pa.us> wrote:
>> One thing that occurs to me just now is that perhaps we could report
>> the failure as if it were a syntax error

> That would be cool, if it can be made to work.

Just as a five-minute proof-of-concept hack, attached is a patch that
makes varchar() report an error position if it can get one.  This is
*very* far from being production quality --- debug_query_string is the
wrong thing to rely on in general, and we'd certainly want to encapsulate
the logic rather than have individual functions know about how to do it.
But here's some testing that shows that the idea seems to have promise
from a usability standpoint:

regression=# create table test (f1 varchar(10), f2 varchar(5), f3 varchar(10));
CREATE TABLE

regression=# insert into test values ('a', 'b', 'foobar');
INSERT 0 1

regression=# insert into test values ('foobar', 'foobar', 'foobar');
ERROR:  value too long for type character varying(5)
LINE 1: insert into test values ('foobar', 'foobar', 'foobar');
                                           ^

regression=# update test set f2 = f3 where f1 = 'a';
ERROR:  value too long for type character varying(5)
LINE 1: update test set f2 = f3 where f1 = 'a';
                             ^

The first error case points out a limitation of relying on the contents of
the string to figure out where your problem is.  The error-cursor approach
has its own limitations, of course; for instance the second case might not
be thought to be all that helpful.

                        regards, tom lane

diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c
index 502ca44..4438ed8 100644
*** a/src/backend/utils/adt/varchar.c
--- b/src/backend/utils/adt/varchar.c
***************
*** 19,24 ****
--- 19,25 ----
  #include "access/tuptoaster.h"
  #include "libpq/pqformat.h"
  #include "nodes/nodeFuncs.h"
+ #include "tcop/tcopprot.h"
  #include "utils/array.h"
  #include "utils/builtins.h"
  #include "mb/pg_wchar.h"
*************** varchar(PG_FUNCTION_ARGS)
*** 617,626 ****
  	{
  		for (i = maxmblen; i < len; i++)
  			if (s_data[i] != ' ')
  				ereport(ERROR,
  						(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
  					  errmsg("value too long for type character varying(%d)",
! 							 maxlen)));
  	}
  
  	PG_RETURN_VARCHAR_P((VarChar *) cstring_to_text_with_len(s_data,
--- 618,645 ----
  	{
  		for (i = maxmblen; i < len; i++)
  			if (s_data[i] != ' ')
+ 			{
+ 				int			pos = 0;
+ 
+ 				if (debug_query_string &&
+ 					fcinfo->flinfo->fn_expr)
+ 				{
+ 					int location = exprLocation(fcinfo->flinfo->fn_expr);
+ 
+ 					if (location >= 0)
+ 					{
+ 						/* Convert offset to character number */
+ 						pos = pg_mbstrlen_with_len(debug_query_string,
+ 												   location) + 1;
+ 					}
+ 				}
+ 
  				ereport(ERROR,
  						(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
  					  errmsg("value too long for type character varying(%d)",
! 							 maxlen),
! 						 errposition(pos)));
! 			}
  	}
  
  	PG_RETURN_VARCHAR_P((VarChar *) cstring_to_text_with_len(s_data,
-- 
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