aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/varlena.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/varlena.c')
-rw-r--r--src/backend/utils/adt/varlena.c265
1 files changed, 137 insertions, 128 deletions
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index 8ddabdb4ee4..8247e16812d 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.62 2000/07/05 23:11:35 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.63 2000/07/06 05:48:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -196,21 +196,16 @@ textout(PG_FUNCTION_ARGS)
* returns the logical length of a text*
* (which is less than the VARSIZE of the text*)
*/
-int32
-textlen(text *t)
+Datum
+textlen(PG_FUNCTION_ARGS)
{
+ text *t = PG_GETARG_TEXT_P(0);
#ifdef MULTIBYTE
unsigned char *s;
int len,
l,
wl;
-#endif
-
- if (!PointerIsValid(t))
- return 0;
-
-#ifdef MULTIBYTE
len = 0;
s = VARDATA(t);
l = VARSIZE(t) - VARHDRSZ;
@@ -221,30 +216,35 @@ textlen(text *t)
s += wl;
len++;
}
- return (len);
+ PG_RETURN_INT32(len);
#else
- return VARSIZE(t) - VARHDRSZ;
+ PG_RETURN_INT32(VARSIZE(t) - VARHDRSZ);
#endif
-
-} /* textlen() */
+}
/*
* textoctetlen -
* returns the physical length of a text*
* (which is less than the VARSIZE of the text*)
+ *
+ * XXX is it actually appropriate to return the compressed length
+ * when the value is compressed? It's not at all clear to me that
+ * this is what SQL92 has in mind ...
*/
-int32
-textoctetlen(text *t)
+Datum
+textoctetlen(PG_FUNCTION_ARGS)
{
- if (!PointerIsValid(t))
- return 0;
+ struct varattrib *t = (struct varattrib *) PG_GETARG_RAW_VARLENA_P(0);
- return VARSIZE(t) - VARHDRSZ;
-} /* textoctetlen() */
+ if (!VARATT_IS_EXTERNAL(t))
+ PG_RETURN_INT32(VARATT_SIZE(t) - VARHDRSZ);
+
+ PG_RETURN_INT32(t->va_content.va_external.va_extsize);
+}
/*
* textcat -
- * takes two text* and returns a text* that is the concatentation of
+ * takes two text* and returns a text* that is the concatenation of
* the two.
*
* Rewritten by Sapa, sapa@hq.icb.chel.su. 8-Jul-96.
@@ -252,32 +252,27 @@ textoctetlen(text *t)
* Allocate space for output in all cases.
* XXX - thomas 1997-07-10
*/
-text *
-textcat(text *t1, text *t2)
+Datum
+textcat(PG_FUNCTION_ARGS)
{
+ text *t1 = PG_GETARG_TEXT_P(0);
+ text *t2 = PG_GETARG_TEXT_P(1);
int len1,
len2,
len;
- char *ptr;
text *result;
-
- if (!PointerIsValid(t1) || !PointerIsValid(t2))
- return NULL;
+ char *ptr;
len1 = (VARSIZE(t1) - VARHDRSZ);
if (len1 < 0)
len1 = 0;
- while (len1 > 0 && VARDATA(t1)[len1 - 1] == '\0')
- len1--;
len2 = (VARSIZE(t2) - VARHDRSZ);
if (len2 < 0)
len2 = 0;
- while (len2 > 0 && VARDATA(t2)[len2 - 1] == '\0')
- len2--;
len = len1 + len2 + VARHDRSZ;
- result = palloc(len);
+ result = (text *) palloc(len);
/* Set size of result string... */
VARATT_SIZEP(result) = len;
@@ -289,8 +284,8 @@ textcat(text *t1, text *t2)
if (len2 > 0)
memcpy(ptr + len1, VARDATA(t2), len2);
- return result;
-} /* textcat() */
+ PG_RETURN_TEXT_P(result);
+}
/*
* text_substr()
@@ -383,9 +378,11 @@ text_substr(PG_FUNCTION_ARGS)
* Added multi-byte support.
* - Tatsuo Ishii 1998-4-21
*/
-int32
-textpos(text *t1, text *t2)
+Datum
+textpos(PG_FUNCTION_ARGS)
{
+ text *t1 = PG_GETARG_TEXT_P(0);
+ text *t2 = PG_GETARG_TEXT_P(1);
int pos;
int px,
p;
@@ -393,18 +390,13 @@ textpos(text *t1, text *t2)
len2;
pg_wchar *p1,
*p2;
-
#ifdef MULTIBYTE
pg_wchar *ps1,
*ps2;
-
#endif
- if (!PointerIsValid(t1) || !PointerIsValid(t2))
- return 0;
-
- if (VARSIZE(t2) <= 0)
- return 1;
+ if (VARSIZE(t2) <= VARHDRSZ)
+ PG_RETURN_INT32(1); /* result for empty pattern */
len1 = (VARSIZE(t1) - VARHDRSZ);
len2 = (VARSIZE(t2) - VARHDRSZ);
@@ -438,43 +430,51 @@ textpos(text *t1, text *t2)
pfree(ps1);
pfree(ps2);
#endif
- return pos;
-} /* textpos() */
+ PG_RETURN_INT32(pos);
+}
/*
- * texteq - returns 1 iff arguments are equal
- * textne - returns 1 iff arguments are not equal
+ * texteq - returns true iff arguments are equal
+ * textne - returns true iff arguments are not equal
*/
-bool
-texteq(text *arg1, text *arg2)
+Datum
+texteq(PG_FUNCTION_ARGS)
{
+ text *arg1 = PG_GETARG_TEXT_P(0);
+ text *arg2 = PG_GETARG_TEXT_P(1);
int len;
char *a1p,
*a2p;
- if (arg1 == NULL || arg2 == NULL)
- return (bool) NULL;
- if ((len = arg1->vl_len) != arg2->vl_len)
- return (bool) 0;
- a1p = arg1->vl_dat;
- a2p = arg2->vl_dat;
+ if (VARSIZE(arg1) != VARSIZE(arg2))
+ PG_RETURN_BOOL(false);
- /*
- * Varlenas are stored as the total size (data + size variable)
- * followed by the data. Use VARHDRSZ instead of explicit sizeof() -
- * thomas 1997-07-10
- */
- len -= VARHDRSZ;
- while (len-- != 0)
- if (*a1p++ != *a2p++)
- return (bool) 0;
- return (bool) 1;
-} /* texteq() */
-
-bool
-textne(text *arg1, text *arg2)
+ len = VARSIZE(arg1) - VARHDRSZ;
+
+ a1p = VARDATA(arg1);
+ a2p = VARDATA(arg2);
+
+ PG_RETURN_BOOL(memcmp(a1p, a2p, len) == 0);
+}
+
+Datum
+textne(PG_FUNCTION_ARGS)
{
- return (bool) !texteq(arg1, arg2);
+ text *arg1 = PG_GETARG_TEXT_P(0);
+ text *arg2 = PG_GETARG_TEXT_P(1);
+ int len;
+ char *a1p,
+ *a2p;
+
+ if (VARSIZE(arg1) != VARSIZE(arg2))
+ PG_RETURN_BOOL(true);
+
+ len = VARSIZE(arg1) - VARHDRSZ;
+
+ a1p = VARDATA(arg1);
+ a2p = VARDATA(arg2);
+
+ PG_RETURN_BOOL(memcmp(a1p, a2p, len) != 0);
}
/* varstr_cmp()
@@ -515,7 +515,7 @@ varstr_cmp(char *arg1, int len1, char *arg2, int len2)
#endif
return result;
-} /* varstr_cmp() */
+}
/* text_cmp()
@@ -534,9 +534,6 @@ text_cmp(text *arg1, text *arg2)
int len1,
len2;
- if (arg1 == NULL || arg2 == NULL)
- return (bool) FALSE;
-
a1p = VARDATA(arg1);
a2p = VARDATA(arg2);
@@ -544,68 +541,82 @@ text_cmp(text *arg1, text *arg2)
len2 = VARSIZE(arg2) - VARHDRSZ;
return varstr_cmp(a1p, len1, a2p, len2);
-} /* text_cmp() */
+}
-/* text_lt()
- * Comparison function for text strings.
+/*
+ * Comparison functions for text strings.
*/
-bool
-text_lt(text *arg1, text *arg2)
+
+Datum
+text_lt(PG_FUNCTION_ARGS)
{
- return (bool) (text_cmp(arg1, arg2) < 0);
-} /* text_lt() */
+ text *arg1 = PG_GETARG_TEXT_P(0);
+ text *arg2 = PG_GETARG_TEXT_P(1);
-/* text_le()
- * Comparison function for text strings.
- */
-bool
-text_le(text *arg1, text *arg2)
+ PG_RETURN_BOOL(text_cmp(arg1, arg2) < 0);
+}
+
+Datum
+text_le(PG_FUNCTION_ARGS)
{
- return (bool) (text_cmp(arg1, arg2) <= 0);
-} /* text_le() */
+ text *arg1 = PG_GETARG_TEXT_P(0);
+ text *arg2 = PG_GETARG_TEXT_P(1);
-bool
-text_gt(text *arg1, text *arg2)
+ PG_RETURN_BOOL(text_cmp(arg1, arg2) <= 0);
+}
+
+Datum
+text_gt(PG_FUNCTION_ARGS)
{
- return (bool) !text_le(arg1, arg2);
+ text *arg1 = PG_GETARG_TEXT_P(0);
+ text *arg2 = PG_GETARG_TEXT_P(1);
+
+ PG_RETURN_BOOL(text_cmp(arg1, arg2) > 0);
}
-bool
-text_ge(text *arg1, text *arg2)
+Datum
+text_ge(PG_FUNCTION_ARGS)
{
- return (bool) !text_lt(arg1, arg2);
+ text *arg1 = PG_GETARG_TEXT_P(0);
+ text *arg2 = PG_GETARG_TEXT_P(1);
+
+ PG_RETURN_BOOL(text_cmp(arg1, arg2) >= 0);
}
-text *
-text_larger(text *arg1, text *arg2)
+Datum
+text_larger(PG_FUNCTION_ARGS)
{
+ text *arg1 = PG_GETARG_TEXT_P(0);
+ text *arg2 = PG_GETARG_TEXT_P(1);
text *result;
text *temp;
- temp = ((text_cmp(arg1, arg2) <= 0) ? arg2 : arg1);
+ temp = ((text_cmp(arg1, arg2) > 0) ? arg1 : arg2);
- /* Make a copy */
+ /* Make a copy --- temporary hack until nodeAgg.c is smarter */
result = (text *) palloc(VARSIZE(temp));
- memmove((char *) result, (char *) temp, VARSIZE(temp));
+ memcpy((char *) result, (char *) temp, VARSIZE(temp));
- return (result);
+ PG_RETURN_TEXT_P(result);
}
-text *
-text_smaller(text *arg1, text *arg2)
+Datum
+text_smaller(PG_FUNCTION_ARGS)
{
+ text *arg1 = PG_GETARG_TEXT_P(0);
+ text *arg2 = PG_GETARG_TEXT_P(1);
text *result;
text *temp;
- temp = ((text_cmp(arg1, arg2) > 0) ? arg2 : arg1);
+ temp = ((text_cmp(arg1, arg2) < 0) ? arg1 : arg2);
- /* Make a copy */
+ /* Make a copy --- temporary hack until nodeAgg.c is smarter */
result = (text *) palloc(VARSIZE(temp));
- memmove((char *) result, (char *) temp, VARSIZE(temp));
+ memcpy((char *) result, (char *) temp, VARSIZE(temp));
- return (result);
+ PG_RETURN_TEXT_P(result);
}
/*-------------------------------------------------------------
@@ -780,28 +791,28 @@ byteaSetBit(PG_FUNCTION_ARGS)
/* text_name()
- * Converts a text() type to a NameData type.
+ * Converts a text type to a Name type.
*/
-NameData *
-text_name(text *s)
+Datum
+text_name(PG_FUNCTION_ARGS)
{
- NameData *result;
+ text *s = PG_GETARG_TEXT_P(0);
+ Name result;
int len;
- if (s == NULL)
- return NULL;
-
len = VARSIZE(s) - VARHDRSZ;
- if (len > NAMEDATALEN)
- len = NAMEDATALEN;
+
+ /* Truncate oversize input */
+ if (len >= NAMEDATALEN)
+ len = NAMEDATALEN-1;
#ifdef STRINGDEBUG
printf("text- convert string length %d (%d) ->%d\n",
VARSIZE(s) - VARHDRSZ, VARSIZE(s), len);
#endif
- result = palloc(NAMEDATALEN);
- StrNCpy(NameStr(*result), VARDATA(s), NAMEDATALEN);
+ result = (Name) palloc(NAMEDATALEN);
+ memcpy(NameStr(*result), VARDATA(s), len);
/* now null pad to full length... */
while (len < NAMEDATALEN)
@@ -810,21 +821,19 @@ text_name(text *s)
len++;
}
- return result;
-} /* text_name() */
+ PG_RETURN_NAME(result);
+}
/* name_text()
- * Converts a NameData type to a text type.
+ * Converts a Name type to a text type.
*/
-text *
-name_text(NameData *s)
+Datum
+name_text(PG_FUNCTION_ARGS)
{
+ Name s = PG_GETARG_NAME(0);
text *result;
int len;
- if (s == NULL)
- return NULL;
-
len = strlen(NameStr(*s));
#ifdef STRINGDEBUG
@@ -833,8 +842,8 @@ name_text(NameData *s)
#endif
result = palloc(VARHDRSZ + len);
- strncpy(VARDATA(result), NameStr(*s), len);
- VARATT_SIZEP(result) = len + VARHDRSZ;
+ VARATT_SIZEP(result) = VARHDRSZ + len;
+ memcpy(VARDATA(result), NameStr(*s), len);
- return result;
-} /* name_text() */
+ PG_RETURN_TEXT_P(result);
+}