From cb0382620100b61267f58649ad54878f3bc9c50b Mon Sep 17 00:00:00 2001 From: "Thomas G. Lockhart" Date: Sat, 9 May 1998 22:45:14 +0000 Subject: [PATCH] Add routines to convert between varchar and bpchar. Add routines to allow sizing of varchar and bpchar into target columns. --- src/backend/utils/adt/varchar.c | 127 +++++++++++++++++++++++++++++++- src/backend/utils/adt/varlena.c | 23 +++--- src/include/utils/builtins.h | 6 +- 3 files changed, 141 insertions(+), 15 deletions(-) diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c index cbd113bba8..7f30f2bab6 100644 --- a/src/backend/utils/adt/varchar.c +++ b/src/backend/utils/adt/varchar.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.30 1998/04/27 17:08:26 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.31 1998/05/09 22:42:07 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -130,12 +130,103 @@ bpcharout(char *s) return (result); } +/* bpchar() + * Converts a char() type to a specific internal length. + * len is the length specified in () plus VARHDRSZ bytes. + */ +char * +bpchar(char *s, int32 len) +{ + char *result, + *r; + int rlen, slen; + int i; + + if (s == NULL) + return ((char *) NULL); + + if ((len == -1) || (len == VARSIZE(s))) + return (s); + + rlen = len - VARHDRSZ; + + if (rlen > 4096) + elog(ERROR, "bpchar: length of char() must be less than 4096"); + +#ifdef STRINGDEBUG +printf("bpchar- convert string length %d (%d) ->%d (%d)\n", + VARSIZE(s)-VARHDRSZ, VARSIZE(s), rlen, len); +#endif + + result = (char *) palloc(len); + VARSIZE(result) = len; + r = VARDATA(result); + slen = VARSIZE(s) - VARHDRSZ; + s = VARDATA(s); + +#ifdef STRINGDEBUG +printf("bpchar- string is '"); +#endif + + for (i = 0; (i < rlen) && (i < slen); i++) + { + if (*s == '\0') + break; + +#ifdef STRINGDEBUG +printf("%c", *s); +#endif + + *r++ = *s++; + } + +#ifdef STRINGDEBUG +printf("'\n"); +#endif + + /* blank pad the string if necessary */ + for (; i < rlen; i++) + { + *r++ = ' '; + } + + return (result); +} /* bpchar() */ + + +/* bpchar_char() + * Convert bpchar(1) to char. + */ +int32 +bpchar_char(char *s) +{ + return ((int32) *VARDATA(s)); +} /* char_bpchar() */ + + +/* char_bpchar() + * Convert char to bpchar(1). + */ +char * +char_bpchar(int32 c) +{ + char *result; + + result = palloc(VARHDRSZ+1); + + VARSIZE(result) = VARHDRSZ+1; + *(VARDATA(result)) = (char) c; + + return result; +} /* char_bpchar() */ + + /***************************************************************************** * varchar - varchar() * *****************************************************************************/ /* - * vcharin - + * varcharin - * converts a string of varchar() type to the internal representation. * len is the length specified in () plus VARHDRSZ bytes. (XXX dummy is here * because we pass typelem as the second argument for array_in.) @@ -193,6 +284,38 @@ varcharout(char *s) return (result); } +/* varchar() + * Converts a varchar() type to the specified size. + * slen is the length specified in () plus VARHDRSZ bytes. + */ +char * +varchar(char *s, int32 slen) +{ + char *result; + int len; + + if (s == NULL) + return ((char *) NULL); + + len = VARSIZE(s); + if ((slen == -1) || (len <= slen)) + return ((char *) s); + + /* only reach here if we need to truncate string... */ + + len = slen - VARHDRSZ; + + if (len > 4096) + elog(ERROR, "varchar: length of varchar() must be less than 4096"); + + result = (char *) palloc(slen); + VARSIZE(result) = slen; + strncpy(VARDATA(result), VARDATA(s), len); + + return (result); +} /* varchar() */ + + /***************************************************************************** * Comparison Functions used for bpchar *****************************************************************************/ diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index d094924db1..1fad410b85 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.33 1998/04/27 17:08:28 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.34 1998/05/09 22:42:07 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -255,8 +255,6 @@ textoctetlen(text *t) * Updated by Thomas, Thomas.Lockhart@jpl.nasa.gov 1997-07-10. * Allocate space for output in all cases. * XXX - thomas 1997-07-10 - * As in previous code, allow concatenation when one string is NULL. - * Is this OK? */ text * textcat(text *t1, text *t2) @@ -267,33 +265,34 @@ textcat(text *t1, text *t2) char *ptr; text *result; - if (!PointerIsValid(t1) && !PointerIsValid(t2)) + if (!PointerIsValid(t1) || !PointerIsValid(t2)) return (NULL); - len1 = (PointerIsValid(t1) ? (VARSIZE(t1) - VARHDRSZ) : 0); + len1 = (VARSIZE(t1) - VARHDRSZ); if (len1 < 0) len1 = 0; while (len1 > 0 && VARDATA(t1)[len1 - 1] == '\0') len1--; - len2 = (PointerIsValid(t2) ? (VARSIZE(t2) - VARHDRSZ) : 0); + len2 = (VARSIZE(t2) - VARHDRSZ); if (len2 < 0) len2 = 0; while (len2 > 0 && VARDATA(t2)[len2 - 1] == '\0') len2--; - result = palloc(len = len1 + len2 + VARHDRSZ); + len = len1 + len2 + VARHDRSZ; + result = palloc(len); + + /* Set size of result string... */ + VARSIZE(result) = len; /* Fill data field of result string... */ ptr = VARDATA(result); - if (PointerIsValid(t1)) + if (len1 > 0) memcpy(ptr, VARDATA(t1), len1); - if (PointerIsValid(t2)) + if (len2 > 0) memcpy(ptr + len1, VARDATA(t2), len2); - /* Set size of result string... */ - VARSIZE(result) = len; - return (result); } /* textcat() */ diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 9e83ba12e6..3d47cc7f46 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: builtins.h,v 1.41 1998/04/27 17:09:28 scrappy Exp $ + * $Id: builtins.h,v 1.42 1998/05/09 22:45:14 thomas Exp $ * * NOTES * This should normally only be included by fmgr.h. @@ -392,6 +392,9 @@ time_t datetime_timestamp(DateTime *datetime); /* varchar.c */ extern char *bpcharin(char *s, int dummy, int16 atttypmod); extern char *bpcharout(char *s); +extern char *bpchar(char *s, int32 slen); +extern char *char_bpchar(int32 c); +extern int32 bpchar_char(char *s); extern bool bpchareq(char *arg1, char *arg2); extern bool bpcharne(char *arg1, char *arg2); extern bool bpcharlt(char *arg1, char *arg2); @@ -405,6 +408,7 @@ extern uint32 hashbpchar(struct varlena * key); extern char *varcharin(char *s, int dummy, int16 atttypmod); extern char *varcharout(char *s); +extern char *varchar(char *s, int32 slen); extern bool varchareq(char *arg1, char *arg2); extern bool varcharne(char *arg1, char *arg2); extern bool varcharlt(char *arg1, char *arg2); -- 2.40.0