]> granicus.if.org Git - postgresql/commitdiff
Marginal hack to save a little bit of time in bpcharin() when typmod is -1,
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 29 May 2005 20:15:59 +0000 (20:15 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 29 May 2005 20:15:59 +0000 (20:15 +0000)
which is a common case.

src/backend/utils/adt/varchar.c

index 17d775d23b9f7cd76218aeae1c30a19d7e913a51..6d89b3df2f70b9ed488d080804ba7984623eaeea 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * 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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -36,8 +36,8 @@
  * 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
@@ -72,63 +72,62 @@ bpcharin(PG_FUNCTION_ARGS)
        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);
 }
@@ -200,12 +199,16 @@ bpchar(PG_FUNCTION_ARGS)
        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)
@@ -249,12 +252,11 @@ bpchar(PG_FUNCTION_ARGS)
        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);
 }