*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/varchar.c,v 1.109 2005/04/12 04:26:26 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/varchar.c,v 1.110 2005/05/29 20:15:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* length also. (eg. in INSERTs, we have the tupleDescriptor which contains
* the length of the attributes and hence the exact length of the char() or
* varchar(). We pass this to bpcharin() or varcharin().) In the case where
- * we cannot determine the length, we pass in -1 instead and the input string
- * must be null-terminated.
+ * we cannot determine the length, we pass in -1 instead and the input
+ * converter does not enforce any length check.
*
* We actually implement this as a varlena so that we don't have to pass in
* the length for the comparison functions. (The difference between these
char *r;
size_t len,
maxlen;
- int i;
- int charlen; /* number of charcters in the input string */
/* verify encoding */
len = strlen(s);
pg_verifymbstr(s, len, false);
- charlen = pg_mbstrlen(s);
-
/* If typmod is -1 (or invalid), use the actual string length */
if (atttypmod < (int32) VARHDRSZ)
- maxlen = charlen;
+ maxlen = len;
else
- maxlen = atttypmod - VARHDRSZ;
-
- if (charlen > maxlen)
{
- /* Verify that extra characters are spaces, and clip them off */
- size_t mbmaxlen = pg_mbcharcliplen(s, len, maxlen);
+ size_t charlen; /* number of CHARACTERS in the input */
- /*
- * at this point, len is the actual BYTE length of the input
- * string, maxlen is the max number of CHARACTERS allowed for this
- * bpchar type.
- */
- if (strspn(s + mbmaxlen, " ") == len - mbmaxlen)
- len = mbmaxlen;
+ maxlen = atttypmod - VARHDRSZ;
+ charlen = pg_mbstrlen(s);
+ if (charlen > maxlen)
+ {
+ /* Verify that extra characters are spaces, and clip them off */
+ size_t mbmaxlen = pg_mbcharcliplen(s, len, maxlen);
+
+ /*
+ * at this point, len is the actual BYTE length of the input
+ * string, maxlen is the max number of CHARACTERS allowed for this
+ * bpchar type.
+ */
+ if (strspn(s + mbmaxlen, " ") == len - mbmaxlen)
+ len = mbmaxlen;
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
+ errmsg("value too long for type character(%d)",
+ (int) maxlen)));
+
+ /*
+ * Now we set maxlen to the necessary byte length, not
+ * the number of CHARACTERS!
+ */
+ maxlen = len;
+ }
else
- ereport(ERROR,
- (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
- errmsg("value too long for type character(%d)",
- (int) maxlen)));
-
- /*
- * XXX: at this point, maxlen is the necessary byte length, not
- * the number of CHARACTERS!
- */
- maxlen = len;
- }
- else
- {
- /*
- * XXX: at this point, maxlen is the necessary byte length, not
- * the number of CHARACTERS!
- */
- maxlen = len + (maxlen - charlen);
+ {
+ /*
+ * Now we set maxlen to the necessary byte length, not
+ * the number of CHARACTERS!
+ */
+ maxlen = len + (maxlen - charlen);
+ }
}
result = palloc(maxlen + VARHDRSZ);
VARATT_SIZEP(result) = maxlen + VARHDRSZ;
r = VARDATA(result);
- for (i = 0; i < len; i++)
- *r++ = *s++;
+ memcpy(r, s, len);
/* blank pad the string if necessary */
- for (; i < maxlen; i++)
- *r++ = ' ';
+ if (maxlen > len)
+ memset(r + len, ' ', maxlen - len);
PG_RETURN_BPCHAR_P(result);
}
int charlen; /* number of charcters in the input string
* + VARHDRSZ */
+ /* No work if typmod is invalid */
+ if (maxlen < (int32) VARHDRSZ)
+ PG_RETURN_BPCHAR_P(source);
+
len = VARSIZE(source);
charlen = pg_mbstrlen_with_len(VARDATA(source), len - VARHDRSZ) + VARHDRSZ;
- /* No work if typmod is invalid or supplied data matches it already */
- if (maxlen < (int32) VARHDRSZ || charlen == maxlen)
+ /* No work if supplied data matches typmod already */
+ if (charlen == maxlen)
PG_RETURN_BPCHAR_P(source);
if (charlen > maxlen)
VARATT_SIZEP(result) = maxlen;
r = VARDATA(result);
- for (i = 0; i < len - VARHDRSZ; i++)
- *r++ = *s++;
+ memcpy(r, s, len - VARHDRSZ);
/* blank pad the string if necessary */
- for (; i < maxlen - VARHDRSZ; i++)
- *r++ = ' ';
+ if (maxlen > len)
+ memset(r + len - VARHDRSZ, ' ', maxlen - len);
PG_RETURN_BPCHAR_P(result);
}