1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-12 05:01:15 +03:00

bpchar, varchar, bytea, numeric are toastable --- if you initdb, which

I did not force.  I marked numeric as compressable-but-not-move-off-able,
partly to test that storage mode and partly because I've got doubts
that numerics are large enough to need external storage.
This commit is contained in:
Tom Lane
2000-07-29 03:26:51 +00:00
parent 20f6a1e562
commit 1ebe1da296
10 changed files with 825 additions and 851 deletions

View File

@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------
* formatting.c
*
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.19 2000/07/05 23:11:35 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.20 2000/07/29 03:26:41 tgl Exp $
*
*
* Portions Copyright (c) 1999-2000, PostgreSQL, Inc
@@ -4066,7 +4066,9 @@ numeric_to_char(PG_FUNCTION_ARGS)
x = DatumGetNumeric(DirectFunctionCall2(numeric_round,
NumericGetDatum(value),
Int32GetDatum(0)));
numstr = orgnum = int_to_roman(numeric_int4(x));
numstr = orgnum =
int_to_roman(DatumGetInt32(DirectFunctionCall1(numeric_int4,
NumericGetDatum(x))));
pfree(x);
}
else
@@ -4080,8 +4082,12 @@ numeric_to_char(PG_FUNCTION_ARGS)
Numeric b = DatumGetNumeric(DirectFunctionCall1(int4_numeric,
Int32GetDatum(Num.multi)));
x = numeric_power(a, b);
val = numeric_mul(value, x);
x = DatumGetNumeric(DirectFunctionCall2(numeric_power,
NumericGetDatum(a),
NumericGetDatum(b)));
val = DatumGetNumeric(DirectFunctionCall2(numeric_mul,
NumericGetDatum(value),
NumericGetDatum(x)));
pfree(x);
pfree(a);
pfree(b);

File diff suppressed because it is too large Load Diff

View File

@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.75 2000/07/06 05:48:11 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.76 2000/07/29 03:26:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -818,7 +818,8 @@ convert_numeric_to_scalar(Datum value, Oid typid)
case FLOAT8OID:
return (double) DatumGetFloat8(value);
case NUMERICOID:
return (double) (*numeric_float8((Numeric) DatumGetPointer(value)));
return (double) DatumGetFloat8(DirectFunctionCall1(numeric_float8,
value));
case OIDOID:
case REGPROCOID:
/* we can treat OIDs as integers... */
@@ -1825,11 +1826,13 @@ string_lessthan(const char *str1, const char *str2, Oid datatype)
break;
case BPCHAROID:
result = bpcharlt((char *) datum1, (char *) datum2);
result = DatumGetBool(DirectFunctionCall2(bpcharlt,
datum1, datum2));
break;
case VARCHAROID:
result = varcharlt((char *) datum1, (char *) datum2);
result = DatumGetBool(DirectFunctionCall2(varcharlt,
datum1, datum2));
break;
case NAMEOID:

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.68 2000/07/07 21:12:50 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.69 2000/07/29 03:26:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -260,19 +260,20 @@ char_bpchar(PG_FUNCTION_ARGS)
/* bpchar_name()
* Converts a bpchar() type to a NameData type.
*/
NameData *
bpchar_name(char *s)
Datum
bpchar_name(PG_FUNCTION_ARGS)
{
NameData *result;
BpChar *s = PG_GETARG_BPCHAR_P(0);
Name result;
int len;
if (s == NULL)
return NULL;
len = VARSIZE(s) - VARHDRSZ;
/* Truncate to max length for a Name */
if (len >= NAMEDATALEN)
len = NAMEDATALEN-1;
/* Remove trailing blanks */
while (len > 0)
{
if (*(VARDATA(s) + len - 1) != ' ')
@@ -280,49 +281,36 @@ bpchar_name(char *s)
len--;
}
#ifdef STRINGDEBUG
printf("bpchar- convert string length %d (%d) ->%d\n",
VARSIZE(s) - VARHDRSZ, VARSIZE(s), len);
#endif
result = (NameData *) palloc(NAMEDATALEN);
memcpy(NameStr(*result), VARDATA(s), len);
/* now null pad to full length... */
/* Now null pad to full length... */
while (len < NAMEDATALEN)
{
*(NameStr(*result) + len) = '\0';
len++;
}
return result;
} /* bpchar_name() */
PG_RETURN_NAME(result);
}
/* name_bpchar()
* Converts a NameData type to a bpchar type.
*/
char *
name_bpchar(NameData *s)
Datum
name_bpchar(PG_FUNCTION_ARGS)
{
char *result;
Name s = PG_GETARG_NAME(0);
BpChar *result;
int len;
if (s == NULL)
return NULL;
len = strlen(NameStr(*s));
#ifdef STRINGDEBUG
printf("bpchar- convert string length %d (%d) ->%d\n",
VARSIZE(s) - VARHDRSZ, VARSIZE(s), len);
#endif
result = (char *) palloc(VARHDRSZ + len);
result = (BpChar *) palloc(VARHDRSZ + len);
memcpy(VARDATA(result), NameStr(*s), len);
VARATT_SIZEP(result) = len + VARHDRSZ;
return result;
} /* name_bpchar() */
PG_RETURN_BPCHAR_P(result);
}
/*****************************************************************************
@@ -446,13 +434,9 @@ _varchar(PG_FUNCTION_ARGS)
return array_map(&locfcinfo, VARCHAROID, VARCHAROID);
}
/*****************************************************************************
* Comparison Functions used for bpchar
*****************************************************************************/
/* "True" length (not counting trailing blanks) of a BpChar */
static int
bcTruelen(char *arg)
bcTruelen(BpChar *arg)
{
char *s = VARDATA(arg);
int i;
@@ -467,19 +451,16 @@ bcTruelen(char *arg)
return i + 1;
}
int32
bpcharlen(char *arg)
Datum
bpcharlen(PG_FUNCTION_ARGS)
{
BpChar *arg = PG_GETARG_BPCHAR_P(0);
#ifdef MULTIBYTE
unsigned char *s;
int len,
l,
wl;
#endif
if (!PointerIsValid(arg))
elog(ERROR, "Bad (null) char() external representation");
#ifdef MULTIBYTE
l = VARSIZE(arg) - VARHDRSZ;
len = 0;
s = VARDATA(arg);
@@ -490,318 +471,176 @@ bpcharlen(char *arg)
s += wl;
len++;
}
return (len);
PG_RETURN_INT32(len);
#else
return (VARSIZE(arg) - VARHDRSZ);
PG_RETURN_INT32(VARSIZE(arg) - VARHDRSZ);
#endif
}
int32
bpcharoctetlen(char *arg)
Datum
bpcharoctetlen(PG_FUNCTION_ARGS)
{
if (!PointerIsValid(arg))
elog(ERROR, "Bad (null) char() external representation");
BpChar *arg = PG_GETARG_BPCHAR_P(0);
return (VARSIZE(arg) - VARHDRSZ);
PG_RETURN_INT32(VARSIZE(arg) - VARHDRSZ);
}
bool
bpchareq(char *arg1, char *arg2)
{
int len1,
len2;
if (arg1 == NULL || arg2 == NULL)
return (bool) 0;
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
if (len1 != len2)
return 0;
return strncmp(VARDATA(arg1), VARDATA(arg2), len1) == 0;
}
bool
bpcharne(char *arg1, char *arg2)
{
int len1,
len2;
if (arg1 == NULL || arg2 == NULL)
return (bool) 0;
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
if (len1 != len2)
return 1;
return strncmp(VARDATA(arg1), VARDATA(arg2), len1) != 0;
}
bool
bpcharlt(char *arg1, char *arg2)
{
int len1,
len2;
int cmp;
if (arg1 == NULL || arg2 == NULL)
return (bool) 0;
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
if (cmp == 0)
return len1 < len2;
else
return cmp < 0;
}
bool
bpcharle(char *arg1, char *arg2)
{
int len1,
len2;
int cmp;
if (arg1 == NULL || arg2 == NULL)
return (bool) 0;
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
if (0 == cmp)
return (bool) (len1 <= len2 ? 1 : 0);
else
return (bool) (cmp <= 0);
}
bool
bpchargt(char *arg1, char *arg2)
{
int len1,
len2;
int cmp;
if (arg1 == NULL || arg2 == NULL)
return (bool) 0;
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
if (cmp == 0)
return len1 > len2;
else
return cmp > 0;
}
bool
bpcharge(char *arg1, char *arg2)
{
int len1,
len2;
int cmp;
if (arg1 == NULL || arg2 == NULL)
return (bool) 0;
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
if (0 == cmp)
return (bool) (len1 >= len2 ? 1 : 0);
else
return (bool) (cmp >= 0);
}
int32
bpcharcmp(char *arg1, char *arg2)
{
int len1,
len2;
int cmp;
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
if ((0 == cmp) && (len1 != len2))
return (int32) (len1 < len2 ? -1 : 1);
else
return cmp;
}
/*****************************************************************************
* Comparison Functions used for varchar
* Comparison Functions used for bpchar
*
* Note: btree indexes need these routines not to leak memory; therefore,
* be careful to free working copies of toasted datums. Most places don't
* need to be so careful.
*****************************************************************************/
int32
varcharlen(char *arg)
{
#ifdef MULTIBYTE
unsigned char *s;
int len,
l,
wl;
#endif
if (!PointerIsValid(arg))
elog(ERROR, "Bad (null) varchar() external representation");
#ifdef MULTIBYTE
len = 0;
s = VARDATA(arg);
l = VARSIZE(arg) - VARHDRSZ;
while (l > 0)
{
wl = pg_mblen(s);
l -= wl;
s += wl;
len++;
}
return (len);
#else
return VARSIZE(arg) - VARHDRSZ;
#endif
}
int32
varcharoctetlen(char *arg)
{
if (!PointerIsValid(arg))
elog(ERROR, "Bad (null) varchar() external representation");
return VARSIZE(arg) - VARHDRSZ;
}
bool
varchareq(char *arg1, char *arg2)
Datum
bpchareq(PG_FUNCTION_ARGS)
{
BpChar *arg1 = PG_GETARG_BPCHAR_P(0);
BpChar *arg2 = PG_GETARG_BPCHAR_P(1);
int len1,
len2;
bool result;
if (arg1 == NULL || arg2 == NULL)
return (bool) 0;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
if (len1 != len2)
return 0;
result = false;
else
result = (strncmp(VARDATA(arg1), VARDATA(arg2), len1) == 0);
return strncmp(VARDATA(arg1), VARDATA(arg2), len1) == 0;
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(result);
}
bool
varcharne(char *arg1, char *arg2)
Datum
bpcharne(PG_FUNCTION_ARGS)
{
BpChar *arg1 = PG_GETARG_BPCHAR_P(0);
BpChar *arg2 = PG_GETARG_BPCHAR_P(1);
int len1,
len2;
bool result;
if (arg1 == NULL || arg2 == NULL)
return (bool) 0;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
if (len1 != len2)
return 1;
result = true;
else
result = (strncmp(VARDATA(arg1), VARDATA(arg2), len1) != 0);
return strncmp(VARDATA(arg1), VARDATA(arg2), len1) != 0;
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(result);
}
bool
varcharlt(char *arg1, char *arg2)
Datum
bpcharlt(PG_FUNCTION_ARGS)
{
BpChar *arg1 = PG_GETARG_BPCHAR_P(0);
BpChar *arg2 = PG_GETARG_BPCHAR_P(1);
int len1,
len2;
int cmp;
if (arg1 == NULL || arg2 == NULL)
return (bool) 0;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
if (cmp == 0)
return len1 < len2;
else
return cmp < 0;
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(cmp < 0);
}
bool
varcharle(char *arg1, char *arg2)
Datum
bpcharle(PG_FUNCTION_ARGS)
{
BpChar *arg1 = PG_GETARG_BPCHAR_P(0);
BpChar *arg2 = PG_GETARG_BPCHAR_P(1);
int len1,
len2;
int cmp;
if (arg1 == NULL || arg2 == NULL)
return (bool) 0;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
if (0 == cmp)
return (bool) (len1 <= len2 ? 1 : 0);
else
return (bool) (cmp <= 0);
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(cmp <= 0);
}
bool
varchargt(char *arg1, char *arg2)
Datum
bpchargt(PG_FUNCTION_ARGS)
{
BpChar *arg1 = PG_GETARG_BPCHAR_P(0);
BpChar *arg2 = PG_GETARG_BPCHAR_P(1);
int len1,
len2;
int cmp;
if (arg1 == NULL || arg2 == NULL)
return (bool) 0;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
if (cmp == 0)
return len1 > len2;
else
return cmp > 0;
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(cmp > 0);
}
bool
varcharge(char *arg1, char *arg2)
Datum
bpcharge(PG_FUNCTION_ARGS)
{
BpChar *arg1 = PG_GETARG_BPCHAR_P(0);
BpChar *arg2 = PG_GETARG_BPCHAR_P(1);
int len1,
len2;
int cmp;
if (arg1 == NULL || arg2 == NULL)
return (bool) 0;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
if (0 == cmp)
return (bool) (len1 >= len2 ? 1 : 0);
else
return (bool) (cmp >= 0);
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(cmp >= 0);
}
int32
varcharcmp(char *arg1, char *arg2)
Datum
bpcharcmp(PG_FUNCTION_ARGS)
{
BpChar *arg1 = PG_GETARG_BPCHAR_P(0);
BpChar *arg2 = PG_GETARG_BPCHAR_P(1);
int len1,
len2;
int cmp;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
if ((0 == cmp) && (len1 != len2))
return (int32) (len1 < len2 ? -1 : 1);
else
return (int32) (cmp);
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_INT32(cmp);
}
/*
* bpchar needs a specialized hash function because we want to ignore
* trailing blanks in comparisons. (varchar can use plain hashvarlena.)
@@ -814,7 +653,201 @@ hashbpchar(PG_FUNCTION_ARGS)
int keylen;
keydata = VARDATA(key);
keylen = bcTruelen((char *) key);
keylen = bcTruelen(key);
return hash_any(keydata, keylen);
}
/*****************************************************************************
* Functions used for varchar
*****************************************************************************/
Datum
varcharlen(PG_FUNCTION_ARGS)
{
VarChar *arg = PG_GETARG_VARCHAR_P(0);
#ifdef MULTIBYTE
unsigned char *s;
int len,
l,
wl;
len = 0;
s = VARDATA(arg);
l = VARSIZE(arg) - VARHDRSZ;
while (l > 0)
{
wl = pg_mblen(s);
l -= wl;
s += wl;
len++;
}
PG_RETURN_INT32(len);
#else
PG_RETURN_INT32(VARSIZE(arg) - VARHDRSZ);
#endif
}
Datum
varcharoctetlen(PG_FUNCTION_ARGS)
{
VarChar *arg = PG_GETARG_VARCHAR_P(0);
PG_RETURN_INT32(VARSIZE(arg) - VARHDRSZ);
}
/*****************************************************************************
* Comparison Functions used for varchar
*
* Note: btree indexes need these routines not to leak memory; therefore,
* be careful to free working copies of toasted datums. Most places don't
* need to be so careful.
*****************************************************************************/
Datum
varchareq(PG_FUNCTION_ARGS)
{
VarChar *arg1 = PG_GETARG_VARCHAR_P(0);
VarChar *arg2 = PG_GETARG_VARCHAR_P(1);
int len1,
len2;
bool result;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
if (len1 != len2)
result = false;
else
result = (strncmp(VARDATA(arg1), VARDATA(arg2), len1) == 0);
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(result);
}
Datum
varcharne(PG_FUNCTION_ARGS)
{
VarChar *arg1 = PG_GETARG_VARCHAR_P(0);
VarChar *arg2 = PG_GETARG_VARCHAR_P(1);
int len1,
len2;
bool result;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
if (len1 != len2)
result = true;
else
result = (strncmp(VARDATA(arg1), VARDATA(arg2), len1) != 0);
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(result);
}
Datum
varcharlt(PG_FUNCTION_ARGS)
{
VarChar *arg1 = PG_GETARG_VARCHAR_P(0);
VarChar *arg2 = PG_GETARG_VARCHAR_P(1);
int len1,
len2;
int cmp;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(cmp < 0);
}
Datum
varcharle(PG_FUNCTION_ARGS)
{
VarChar *arg1 = PG_GETARG_VARCHAR_P(0);
VarChar *arg2 = PG_GETARG_VARCHAR_P(1);
int len1,
len2;
int cmp;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(cmp <= 0);
}
Datum
varchargt(PG_FUNCTION_ARGS)
{
VarChar *arg1 = PG_GETARG_VARCHAR_P(0);
VarChar *arg2 = PG_GETARG_VARCHAR_P(1);
int len1,
len2;
int cmp;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(cmp > 0);
}
Datum
varcharge(PG_FUNCTION_ARGS)
{
VarChar *arg1 = PG_GETARG_VARCHAR_P(0);
VarChar *arg2 = PG_GETARG_VARCHAR_P(1);
int len1,
len2;
int cmp;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(cmp >= 0);
}
Datum
varcharcmp(PG_FUNCTION_ARGS)
{
VarChar *arg1 = PG_GETARG_VARCHAR_P(0);
VarChar *arg2 = PG_GETARG_VARCHAR_P(1);
int len1,
len2;
int cmp;
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_INT32(cmp);
}

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.64 2000/07/12 02:37:19 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.65 2000/07/29 03:26:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -41,18 +41,17 @@ static int text_cmp(text *arg1, text *arg2);
* The input is scaned twice.
* The error checking of input is minimal.
*/
bytea *
byteain(char *inputText)
Datum
byteain(PG_FUNCTION_ARGS)
{
char *inputText = PG_GETARG_CSTRING(0);
char *tp;
char *rp;
int byte;
bytea *result;
if (inputText == NULL)
elog(ERROR, "Bad input string for type bytea");
for (byte = 0, tp = inputText; *tp != '\0'; byte++)
{
if (*tp++ == '\\')
{
if (*tp == '\\')
@@ -62,12 +61,16 @@ byteain(char *inputText)
!isdigit((int) *tp++))
elog(ERROR, "Bad input string for type bytea");
}
tp = inputText;
}
byte += VARHDRSZ;
result = (bytea *) palloc(byte);
result->vl_len = byte; /* varlena? */
result->vl_len = byte; /* set varlena length */
tp = inputText;
rp = result->vl_dat;
while (*tp != '\0')
{
if (*tp != '\\' || *++tp == '\\')
*rp++ = *tp++;
else
@@ -78,7 +81,9 @@ byteain(char *inputText)
byte <<= 3;
*rp++ = byte + VAL(*tp++);
}
return result;
}
PG_RETURN_BYTEA_P(result);
}
/*
@@ -89,9 +94,10 @@ byteain(char *inputText)
*
* NULL vlena should be an error--returning string with NULL for now.
*/
char *
byteaout(bytea *vlena)
Datum
byteaout(PG_FUNCTION_ARGS)
{
bytea *vlena = PG_GETARG_BYTEA_P(0);
char *result;
char *vp;
char *rp;
@@ -99,47 +105,42 @@ byteaout(bytea *vlena)
int i;
int len;
if (vlena == NULL)
{
result = (char *) palloc(2);
result[0] = '-';
result[1] = '\0';
return result;
}
vp = vlena->vl_dat;
len = 1; /* empty string has 1 char */
vp = vlena->vl_dat;
for (i = vlena->vl_len - VARHDRSZ; i != 0; i--, vp++)
{
if (*vp == '\\')
len += 2;
else if (isascii((int) *vp) && isprint((int) *vp))
len++;
else
len += VARHDRSZ;
len += 4;
}
rp = result = (char *) palloc(len);
vp = vlena->vl_dat;
for (i = vlena->vl_len - VARHDRSZ; i != 0; i--)
for (i = vlena->vl_len - VARHDRSZ; i != 0; i--, vp++)
{
if (*vp == '\\')
{
vp++;
*rp++ = '\\';
*rp++ = '\\';
}
else if (isascii((int) *vp) && isprint((int) *vp))
*rp++ = *vp++;
*rp++ = *vp;
else
{
val = *vp++;
*rp = '\\';
rp += 3;
*rp-- = DIG(val & 07);
val = *vp;
rp[0] = '\\';
rp[3] = DIG(val & 07);
val >>= 3;
*rp-- = DIG(val & 07);
rp[2] = DIG(val & 07);
val >>= 3;
*rp = DIG(val & 03);
rp += 3;
rp[1] = DIG(val & 03);
rp += 4;
}
}
*rp = '\0';
return result;
PG_RETURN_CSTRING(result);
}
@@ -663,13 +664,12 @@ text_smaller(PG_FUNCTION_ARGS)
* get the number of bytes contained in an instance of type 'bytea'
*-------------------------------------------------------------
*/
int32
byteaoctetlen(bytea *v)
Datum
byteaoctetlen(PG_FUNCTION_ARGS)
{
if (!PointerIsValid(v))
return 0;
bytea *v = PG_GETARG_BYTEA_P(0);
return VARSIZE(v) - VARHDRSZ;
PG_RETURN_INT32(VARSIZE(v) - VARHDRSZ);
}
/*-------------------------------------------------------------