varchar size

Поиск
Список
Период
Сортировка
От Bruce Momjian
Тема varchar size
Дата
Msg-id 199801071941.OAA22353@candle.pha.pa.us
обсуждение исходный текст
Список pgsql-hackers
I have applied the following patch to allow varchar() fields to store
just the needed bytes, and not the maximum size.

I have made a few more cleanup changes related to this, and it seems to
work perfectly.

I think this is one of those "Why didn't we do this earlier?" patches.

    test=> create table testvarchar (x varchar(2));
    CREATE
    test=> insert into testvarchar values ('1');
    INSERT 912201 1
    test=> insert into testvarchar values ('22');
    INSERT 912202 1
    test=> insert into testvarchar values ('333');
    INSERT 912203 1
    test=> select * from testvarchar;
     x
    --
     1
    22
    33
    (3 rows)

And if I create a varchar(2000), it does not take several 8k blocks to
store 10 rows, like it did before.

This makes varchar() behave much more like text, with a pre-defined
length limit.

Also, the fact that varchar() no longer has all those trailing zero's
should make it more portable with other types.

---------------------------------------------------------------------------

*** ./backend/utils/adt/varchar.c.orig    Wed Jan  7 12:43:00 1998
--- ./backend/utils/adt/varchar.c    Wed Jan  7 13:26:16 1998
***************
*** 70,85 ****
          typlen = len + VARHDRSZ;
      }
      else
-     {
          len = typlen - VARHDRSZ;
-     }

      if (len > 4096)
          elog(ERROR, "bpcharin: length of char() must be less than 4096");

      result = (char *) palloc(typlen);
!     *(int32 *) result = typlen;
!     r = result + VARHDRSZ;
      for (i = 0; i < len; i++, r++, s++)
      {
          *r = *s;
--- 70,83 ----
          typlen = len + VARHDRSZ;
      }
      else
          len = typlen - VARHDRSZ;

      if (len > 4096)
          elog(ERROR, "bpcharin: length of char() must be less than 4096");

      result = (char *) palloc(typlen);
!     VARSIZE(result) = typlen;
!     r = VARDATA(result);
      for (i = 0; i < len; i++, r++, s++)
      {
          *r = *s;
***************
*** 108,116 ****
      }
      else
      {
!         len = *(int32 *) s - VARHDRSZ;
          result = (char *) palloc(len + 1);
!         StrNCpy(result, s + VARHDRSZ, len+1);    /* these are blank-padded */
      }
      return (result);
  }
--- 106,114 ----
      }
      else
      {
!         len = VARSIZE(s) - VARHDRSZ;
          result = (char *) palloc(len + 1);
!         StrNCpy(result, VARDATA(s), len+1);    /* these are blank-padded */
      }
      return (result);
  }
***************
*** 129,155 ****
  varcharin(char *s, int dummy, int typlen)
  {
      char       *result;
!     int            len = typlen - VARHDRSZ;

      if (s == NULL)
          return ((char *) NULL);

!     if (typlen == -1)
!     {
!
!         /*
!          * this is here because some functions can't supply the typlen
!          */
!         len = strlen(s);
!         typlen = len + VARHDRSZ;
!     }

      if (len > 4096)
          elog(ERROR, "varcharin: length of char() must be less than 4096");

!     result = (char *) palloc(typlen);
!     *(int32 *) result = typlen;
!     strncpy(result + VARHDRSZ, s, len+1);

      return (result);
  }
--- 127,147 ----
  varcharin(char *s, int dummy, int typlen)
  {
      char       *result;
!     int            len;

      if (s == NULL)
          return ((char *) NULL);

!     len = strlen(s) + VARHDRSZ;
!     if (typlen != -1 && len > typlen)
!         len = typlen;    /* clip the string at max length */

      if (len > 4096)
          elog(ERROR, "varcharin: length of char() must be less than 4096");

!     result = (char *) palloc(len);
!     VARSIZE(result) = len;
!     memmove(VARDATA(result), s, len - VARHDRSZ);

      return (result);
  }
***************
*** 168,176 ****
      }
      else
      {
!         len = *(int32 *) s - VARHDRSZ;
          result = (char *) palloc(len + 1);
!         StrNCpy(result, s + VARHDRSZ, len+1);
      }
      return (result);
  }
--- 160,168 ----
      }
      else
      {
!         len = VARSIZE(s) - VARHDRSZ;
          result = (char *) palloc(len + 1);
!         StrNCpy(result, VARDATA(s), len+1);
      }
      return (result);
  }

--
Bruce Momjian
maillist@candle.pha.pa.us

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Bruce Momjian
Дата:
Сообщение: Re: [HACKERS] database size
Следующее
От: David Wetzel
Дата:
Сообщение: libpq on NT?