@@ -122,9 +122,13 @@ anychar_typmodout(int32 typmod)
122122 *
123123 * If the input string is too long, raise an error, unless the extra
124124 * characters are spaces, in which case they're truncated. (per SQL)
125+ *
126+ * If escontext points to an ErrorSaveContext node, that is filled instead
127+ * of throwing an error; the caller must check SOFT_ERROR_OCCURRED()
128+ * to detect errors.
125129 */
126130static BpChar *
127- bpchar_input (const char * s ,size_t len ,int32 atttypmod )
131+ bpchar_input (const char * s ,size_t len ,int32 atttypmod , Node * escontext )
128132{
129133BpChar * result ;
130134char * r ;
@@ -153,7 +157,7 @@ bpchar_input(const char *s, size_t len, int32 atttypmod)
153157for (j = mbmaxlen ;j < len ;j ++ )
154158{
155159if (s [j ]!= ' ' )
156- ereport ( ERROR ,
160+ ereturn ( escontext , NULL ,
157161(errcode (ERRCODE_STRING_DATA_RIGHT_TRUNCATION ),
158162errmsg ("value too long for type character(%d)" ,
159163(int )maxlen )));
@@ -195,14 +199,13 @@ Datum
195199bpcharin (PG_FUNCTION_ARGS )
196200{
197201char * s = PG_GETARG_CSTRING (0 );
198-
199202#ifdef NOT_USED
200203Oid typelem = PG_GETARG_OID (1 );
201204#endif
202205int32 atttypmod = PG_GETARG_INT32 (2 );
203206BpChar * result ;
204207
205- result = bpchar_input (s ,strlen (s ),atttypmod );
208+ result = bpchar_input (s ,strlen (s ),atttypmod , fcinfo -> context );
206209PG_RETURN_BPCHAR_P (result );
207210}
208211
@@ -228,7 +231,6 @@ Datum
228231bpcharrecv (PG_FUNCTION_ARGS )
229232{
230233StringInfo buf = (StringInfo )PG_GETARG_POINTER (0 );
231-
232234#ifdef NOT_USED
233235Oid typelem = PG_GETARG_OID (1 );
234236#endif
@@ -238,7 +240,7 @@ bpcharrecv(PG_FUNCTION_ARGS)
238240int nbytes ;
239241
240242str = pq_getmsgtext (buf ,buf -> len - buf -> cursor ,& nbytes );
241- result = bpchar_input (str ,nbytes ,atttypmod );
243+ result = bpchar_input (str ,nbytes ,atttypmod , NULL );
242244pfree (str );
243245PG_RETURN_BPCHAR_P (result );
244246}
@@ -448,11 +450,12 @@ bpchartypmodout(PG_FUNCTION_ARGS)
448450 * If the input string is too long, raise an error, unless the extra
449451 * characters are spaces, in which case they're truncated. (per SQL)
450452 *
451- * Uses the C string to text conversion function, which is only appropriate
452- * if VarChar and text are equivalent types.
453+ * If escontext points to an ErrorSaveContext node, that is filled instead
454+ * of throwing an error; the caller must check SOFT_ERROR_OCCURRED()
455+ * to detect errors.
453456 */
454457static VarChar *
455- varchar_input (const char * s ,size_t len ,int32 atttypmod )
458+ varchar_input (const char * s ,size_t len ,int32 atttypmod , Node * escontext )
456459{
457460VarChar * result ;
458461size_t maxlen ;
@@ -468,7 +471,7 @@ varchar_input(const char *s, size_t len, int32 atttypmod)
468471for (j = mbmaxlen ;j < len ;j ++ )
469472{
470473if (s [j ]!= ' ' )
471- ereport ( ERROR ,
474+ ereturn ( escontext , NULL ,
472475(errcode (ERRCODE_STRING_DATA_RIGHT_TRUNCATION ),
473476errmsg ("value too long for type character varying(%d)" ,
474477(int )maxlen )));
@@ -477,6 +480,10 @@ varchar_input(const char *s, size_t len, int32 atttypmod)
477480len = mbmaxlen ;
478481}
479482
483+ /*
484+ * We can use cstring_to_text_with_len because VarChar and text are
485+ * binary-compatible types.
486+ */
480487result = (VarChar * )cstring_to_text_with_len (s ,len );
481488return result ;
482489}
@@ -489,14 +496,13 @@ Datum
489496varcharin (PG_FUNCTION_ARGS )
490497{
491498char * s = PG_GETARG_CSTRING (0 );
492-
493499#ifdef NOT_USED
494500Oid typelem = PG_GETARG_OID (1 );
495501#endif
496502int32 atttypmod = PG_GETARG_INT32 (2 );
497503VarChar * result ;
498504
499- result = varchar_input (s ,strlen (s ),atttypmod );
505+ result = varchar_input (s ,strlen (s ),atttypmod , fcinfo -> context );
500506PG_RETURN_VARCHAR_P (result );
501507}
502508
@@ -522,7 +528,6 @@ Datum
522528varcharrecv (PG_FUNCTION_ARGS )
523529{
524530StringInfo buf = (StringInfo )PG_GETARG_POINTER (0 );
525-
526531#ifdef NOT_USED
527532Oid typelem = PG_GETARG_OID (1 );
528533#endif
@@ -532,7 +537,7 @@ varcharrecv(PG_FUNCTION_ARGS)
532537int nbytes ;
533538
534539str = pq_getmsgtext (buf ,buf -> len - buf -> cursor ,& nbytes );
535- result = varchar_input (str ,nbytes ,atttypmod );
540+ result = varchar_input (str ,nbytes ,atttypmod , NULL );
536541pfree (str );
537542PG_RETURN_VARCHAR_P (result );
538543}