@@ -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{
129133 BpChar * result ;
130134 char * r ;
@@ -153,7 +157,7 @@ bpchar_input(const char *s, size_t len, int32 atttypmod)
153157 for (j = mbmaxlen ; j < len ; j ++ )
154158 {
155159 if (s [j ] != ' ' )
156- ereport ( ERROR ,
160+ ereturn ( escontext , NULL ,
157161 (errcode (ERRCODE_STRING_DATA_RIGHT_TRUNCATION ),
158162 errmsg ("value too long for type character(%d)" ,
159163 (int ) maxlen )));
@@ -195,14 +199,13 @@ Datum
195199bpcharin (PG_FUNCTION_ARGS )
196200{
197201 char * s = PG_GETARG_CSTRING (0 );
198-
199202#ifdef NOT_USED
200203 Oid typelem = PG_GETARG_OID (1 );
201204#endif
202205 int32 atttypmod = PG_GETARG_INT32 (2 );
203206 BpChar * result ;
204207
205- result = bpchar_input (s , strlen (s ), atttypmod );
208+ result = bpchar_input (s , strlen (s ), atttypmod , fcinfo -> context );
206209 PG_RETURN_BPCHAR_P (result );
207210}
208211
@@ -228,7 +231,6 @@ Datum
228231bpcharrecv (PG_FUNCTION_ARGS )
229232{
230233 StringInfo buf = (StringInfo ) PG_GETARG_POINTER (0 );
231-
232234#ifdef NOT_USED
233235 Oid typelem = PG_GETARG_OID (1 );
234236#endif
@@ -238,7 +240,7 @@ bpcharrecv(PG_FUNCTION_ARGS)
238240 int nbytes ;
239241
240242 str = pq_getmsgtext (buf , buf -> len - buf -> cursor , & nbytes );
241- result = bpchar_input (str , nbytes , atttypmod );
243+ result = bpchar_input (str , nbytes , atttypmod , NULL );
242244 pfree (str );
243245 PG_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{
457460 VarChar * result ;
458461 size_t maxlen ;
@@ -468,7 +471,7 @@ varchar_input(const char *s, size_t len, int32 atttypmod)
468471 for (j = mbmaxlen ; j < len ; j ++ )
469472 {
470473 if (s [j ] != ' ' )
471- ereport ( ERROR ,
474+ ereturn ( escontext , NULL ,
472475 (errcode (ERRCODE_STRING_DATA_RIGHT_TRUNCATION ),
473476 errmsg ("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)
477480 len = mbmaxlen ;
478481 }
479482
483+ /*
484+ * We can use cstring_to_text_with_len because VarChar and text are
485+ * binary-compatible types.
486+ */
480487 result = (VarChar * ) cstring_to_text_with_len (s , len );
481488 return result ;
482489}
@@ -489,14 +496,13 @@ Datum
489496varcharin (PG_FUNCTION_ARGS )
490497{
491498 char * s = PG_GETARG_CSTRING (0 );
492-
493499#ifdef NOT_USED
494500 Oid typelem = PG_GETARG_OID (1 );
495501#endif
496502 int32 atttypmod = PG_GETARG_INT32 (2 );
497503 VarChar * result ;
498504
499- result = varchar_input (s , strlen (s ), atttypmod );
505+ result = varchar_input (s , strlen (s ), atttypmod , fcinfo -> context );
500506 PG_RETURN_VARCHAR_P (result );
501507}
502508
@@ -522,7 +528,6 @@ Datum
522528varcharrecv (PG_FUNCTION_ARGS )
523529{
524530 StringInfo buf = (StringInfo ) PG_GETARG_POINTER (0 );
525-
526531#ifdef NOT_USED
527532 Oid typelem = PG_GETARG_OID (1 );
528533#endif
@@ -532,7 +537,7 @@ varcharrecv(PG_FUNCTION_ARGS)
532537 int nbytes ;
533538
534539 str = pq_getmsgtext (buf , buf -> len - buf -> cursor , & nbytes );
535- result = varchar_input (str , nbytes , atttypmod );
540+ result = varchar_input (str , nbytes , atttypmod , NULL );
536541 pfree (str );
537542 PG_RETURN_VARCHAR_P (result );
538543}
0 commit comments