varchar size

From: Bruce Momjian <maillist(at)candle(dot)pha(dot)pa(dot)us>
To: hackers(at)postgreSQL(dot)org (PostgreSQL-development)
Subject: varchar size
Date: 1998-01-07 19:41:21
Message-ID: 199801071941.OAA22353@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: 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(at)candle(dot)pha(dot)pa(dot)us

Browse pgsql-hackers by date

  From Date Subject
Next Message David Wetzel 1998-01-07 21:34:09 libpq on NT?
Previous Message Bruce Momjian 1998-01-07 19:26:49 Re: [HACKERS] database size