/* * Converts a VARCHAR2 type to the specified size. * * maxlen is the typmod, ie, declared length plus VARHDRSZ bytes. * isExplicit is true if this is for an explicit cast to varchar2(N). * * Truncation rules: for an explicit cast, silently truncate to the given * length; for an implicit cast, raise error if length limit is exceeded */ PGDLLEXPORT Datum varchar2(PG_FUNCTION_ARGS) { VarChar *source = PG_GETARG_VARCHAR_PP(0); int32 typmod = PG_GETARG_INT32(1); bool isExplicit = PG_GETARG_BOOL(2); int32 len, maxlen; char *s_data; len = VARSIZE_ANY_EXHDR(source); s_data = VARDATA_ANY(source); maxlen = typmod - VARHDRSZ; /* No work if typmod is invalid or supplied data fits it already */ if (maxlen < 0 || len <= maxlen) PG_RETURN_VARCHAR_P(source); /* error out if value too long unless it's an explicit cast */ if (!isExplicit) { if (len > maxlen) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("input value length is %d; too long for type varchar2(%d)",len ,maxlen))); } PG_RETURN_VARCHAR_P((VarChar *) cstring_to_text_with_len(s_data,maxlen)); }
/* * Converts a NVARCHAR2 type to the specified size. * * maxlen is the typmod, ie, declared length plus VARHDRSZ bytes. * isExplicit is true if this is for an explicit cast to nvarchar2(N). * * Truncation rules: for an explicit cast, silently truncate to the given * length; for an implicit cast, raise error if length limit is exceeded */ Datum nvarchar2(PG_FUNCTION_ARGS) { VarChar *source = PG_GETARG_VARCHAR_PP(0); int32 typmod = PG_GETARG_INT32(1); bool isExplicit = PG_GETARG_BOOL(2); int32 len, maxlen; size_t maxmblen; char *s_data; len = VARSIZE_ANY_EXHDR(source); s_data = VARDATA_ANY(source); maxlen = typmod - VARHDRSZ; /* No work if typmod is invalid or supplied data fits it already */ if (maxlen < 0 || len <= maxlen) PG_RETURN_VARCHAR_P(source); /* only reach here if string is too long... */ /* truncate multibyte string preserving multibyte boundary */ maxmblen = pg_mbcharcliplen(s_data, len, maxlen); /* error out if value too long unless it's an explicit cast */ if (!isExplicit) { /* if there is still data beyond maxmblen, error out * * Remember - no blankspace truncation on implicit cast */ if (len > maxmblen) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("input value too long for type nvarchar2(%d)", maxlen))); } PG_RETURN_VARCHAR_P((VarChar *) cstring_to_text_with_len(s_data, maxmblen)); }