mirror of
https://github.com/postgres/postgres.git
synced 2025-11-29 23:43:17 +03:00
Downgrade implicit casts to text to be assignment-only, except for the ones
from the other string-category types; this eliminates a lot of surprising interpretations that the parser could formerly make when there was no directly applicable operator. Create a general mechanism that supports casts to and from the standard string types (text,varchar,bpchar) for *every* datatype, by invoking the datatype's I/O functions. These new casts are assignment-only in the to-string direction, explicit-only in the other, and therefore should create no surprising behavior. Remove a bunch of thereby-obsoleted datatype-specific casting functions. The "general mechanism" is a new expression node type CoerceViaIO that can actually convert between *any* two datatypes if their external text representations are compatible. This is more general than needed for the immediate feature, but might be useful in plpgsql or other places in future. This commit does nothing about the issue that applying the concatenation operator || to non-text types will now fail, often with strange error messages due to misinterpreting the operator as array concatenation. Since it often (not always) worked before, we should either make it succeed or at least give a more user-friendly error; but details are still under debate. Peter Eisentraut and Tom Lane
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/bool.c,v 1.39 2007/06/01 23:40:18 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/bool.c,v 1.40 2007/06/05 21:31:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -142,22 +142,11 @@ boolsend(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
||||
}
|
||||
|
||||
/*
|
||||
* textbool - cast function for text => bool
|
||||
*/
|
||||
Datum
|
||||
textbool(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Datum in_text = PG_GETARG_DATUM(0);
|
||||
char *str;
|
||||
|
||||
str = DatumGetCString(DirectFunctionCall1(textout, in_text));
|
||||
|
||||
PG_RETURN_DATUM(DirectFunctionCall1(boolin, CStringGetDatum(str)));
|
||||
}
|
||||
|
||||
/*
|
||||
* booltext - cast function for bool => text
|
||||
*
|
||||
* We need this because it's different from the behavior of boolout();
|
||||
* this function follows the SQL-spec result (except for producing lower case)
|
||||
*/
|
||||
Datum
|
||||
booltext(PG_FUNCTION_ARGS)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.131 2007/06/02 16:41:09 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.132 2007/06/05 21:31:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -873,65 +873,6 @@ abstime_date(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
|
||||
/* date_text()
|
||||
* Convert date to text data type.
|
||||
*/
|
||||
Datum
|
||||
date_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/* Input is a Date, but may as well leave it in Datum form */
|
||||
Datum date = PG_GETARG_DATUM(0);
|
||||
text *result;
|
||||
char *str;
|
||||
int len;
|
||||
|
||||
str = DatumGetCString(DirectFunctionCall1(date_out, date));
|
||||
|
||||
len = strlen(str) + VARHDRSZ;
|
||||
|
||||
result = palloc(len);
|
||||
|
||||
SET_VARSIZE(result, len);
|
||||
memcpy(VARDATA(result), str, (len - VARHDRSZ));
|
||||
|
||||
pfree(str);
|
||||
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
||||
|
||||
/* text_date()
|
||||
* Convert text string to date.
|
||||
* Text type is not null terminated, so use temporary string
|
||||
* then call the standard input routine.
|
||||
*/
|
||||
Datum
|
||||
text_date(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *str = PG_GETARG_TEXT_P(0);
|
||||
int i;
|
||||
char *sp,
|
||||
*dp,
|
||||
dstr[MAXDATELEN + 1];
|
||||
|
||||
if (VARSIZE(str) - VARHDRSZ > MAXDATELEN)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for type date: \"%s\"",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(str))))));
|
||||
|
||||
sp = VARDATA(str);
|
||||
dp = dstr;
|
||||
for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++)
|
||||
*dp++ = *sp++;
|
||||
*dp = '\0';
|
||||
|
||||
return DirectFunctionCall1(date_in,
|
||||
CStringGetDatum(dstr));
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Time ADT
|
||||
*****************************************************************************/
|
||||
@@ -1617,62 +1558,6 @@ time_mi_interval(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
|
||||
/* time_text()
|
||||
* Convert time to text data type.
|
||||
*/
|
||||
Datum
|
||||
time_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/* Input is a Time, but may as well leave it in Datum form */
|
||||
Datum time = PG_GETARG_DATUM(0);
|
||||
text *result;
|
||||
char *str;
|
||||
int len;
|
||||
|
||||
str = DatumGetCString(DirectFunctionCall1(time_out, time));
|
||||
|
||||
len = strlen(str) + VARHDRSZ;
|
||||
|
||||
result = palloc(len);
|
||||
|
||||
SET_VARSIZE(result, len);
|
||||
memcpy(VARDATA(result), str, len - VARHDRSZ);
|
||||
|
||||
pfree(str);
|
||||
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
||||
|
||||
/* text_time()
|
||||
* Convert text string to time.
|
||||
* Text type is not null terminated, so use temporary string
|
||||
* then call the standard input routine.
|
||||
*/
|
||||
Datum
|
||||
text_time(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *str = PG_GETARG_TEXT_P(0);
|
||||
char dstr[MAXDATELEN + 1];
|
||||
size_t len;
|
||||
|
||||
if (VARSIZE(str) - VARHDRSZ > MAXDATELEN)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for type time: \"%s\"",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(str))))));
|
||||
|
||||
len = VARSIZE(str) - VARHDRSZ;
|
||||
memcpy(dstr, VARDATA(str), len);
|
||||
dstr[len] = '\0';
|
||||
|
||||
return DirectFunctionCall3(time_in,
|
||||
CStringGetDatum(dstr),
|
||||
ObjectIdGetDatum(InvalidOid),
|
||||
Int32GetDatum(-1));
|
||||
}
|
||||
|
||||
/* time_part()
|
||||
* Extract specified field from time type.
|
||||
*/
|
||||
@@ -2400,66 +2285,6 @@ datetimetz_timestamptz(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
|
||||
/* timetz_text()
|
||||
* Convert timetz to text data type.
|
||||
*/
|
||||
Datum
|
||||
timetz_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/* Input is a Timetz, but may as well leave it in Datum form */
|
||||
Datum timetz = PG_GETARG_DATUM(0);
|
||||
text *result;
|
||||
char *str;
|
||||
int len;
|
||||
|
||||
str = DatumGetCString(DirectFunctionCall1(timetz_out, timetz));
|
||||
|
||||
len = strlen(str) + VARHDRSZ;
|
||||
|
||||
result = palloc(len);
|
||||
|
||||
SET_VARSIZE(result, len);
|
||||
memcpy(VARDATA(result), str, (len - VARHDRSZ));
|
||||
|
||||
pfree(str);
|
||||
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
||||
|
||||
/* text_timetz()
|
||||
* Convert text string to timetz.
|
||||
* Text type is not null terminated, so use temporary string
|
||||
* then call the standard input routine.
|
||||
*/
|
||||
Datum
|
||||
text_timetz(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *str = PG_GETARG_TEXT_P(0);
|
||||
int i;
|
||||
char *sp,
|
||||
*dp,
|
||||
dstr[MAXDATELEN + 1];
|
||||
|
||||
if (VARSIZE(str) - VARHDRSZ > MAXDATELEN)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for type time with time zone: \"%s\"",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(str))))));
|
||||
|
||||
sp = VARDATA(str);
|
||||
dp = dstr;
|
||||
for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++)
|
||||
*dp++ = *sp++;
|
||||
*dp = '\0';
|
||||
|
||||
return DirectFunctionCall3(timetz_in,
|
||||
CStringGetDatum(dstr),
|
||||
ObjectIdGetDatum(InvalidOid),
|
||||
Int32GetDatum(-1));
|
||||
}
|
||||
|
||||
/* timetz_part()
|
||||
* Extract specified field from time type.
|
||||
*/
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/enum.c,v 1.2 2007/04/02 22:14:17 adunstan Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/enum.c,v 1.3 2007/06/05 21:31:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -21,8 +21,6 @@
|
||||
#include "utils/syscache.h"
|
||||
|
||||
|
||||
static Oid cstring_enum(char *name, Oid enumtypoid);
|
||||
static char *enum_cstring(Oid enumval);
|
||||
static ArrayType *enum_range_internal(Oid enumtypoid, Oid lower, Oid upper);
|
||||
static int enum_elem_cmp(const void *left, const void *right);
|
||||
|
||||
@@ -32,75 +30,60 @@ static int enum_elem_cmp(const void *left, const void *right);
|
||||
Datum
|
||||
enum_in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *name = PG_GETARG_CSTRING(0);
|
||||
Oid enumtypoid = PG_GETARG_OID(1);
|
||||
|
||||
PG_RETURN_OID(cstring_enum(name, enumtypoid));
|
||||
}
|
||||
|
||||
/* guts of enum_in and text-to-enum */
|
||||
static Oid
|
||||
cstring_enum(char *name, Oid enumtypoid)
|
||||
{
|
||||
HeapTuple tup;
|
||||
char *name = PG_GETARG_CSTRING(0);
|
||||
Oid enumtypoid = PG_GETARG_OID(1);
|
||||
Oid enumoid;
|
||||
HeapTuple tup;
|
||||
|
||||
/* must check length to prevent Assert failure within SearchSysCache */
|
||||
|
||||
if (strlen(name) >= NAMEDATALEN)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input value for enum %s: \"%s\"",
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input value for enum %s: \"%s\"",
|
||||
format_type_be(enumtypoid),
|
||||
name)));
|
||||
name)));
|
||||
|
||||
tup = SearchSysCache(ENUMTYPOIDNAME,
|
||||
ObjectIdGetDatum(enumtypoid),
|
||||
CStringGetDatum(name),
|
||||
0, 0);
|
||||
if (tup == NULL)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input value for enum %s: \"%s\"",
|
||||
if (!HeapTupleIsValid(tup))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input value for enum %s: \"%s\"",
|
||||
format_type_be(enumtypoid),
|
||||
name)));
|
||||
name)));
|
||||
|
||||
enumoid = HeapTupleGetOid(tup);
|
||||
|
||||
ReleaseSysCache(tup);
|
||||
return enumoid;
|
||||
|
||||
PG_RETURN_OID(enumoid);
|
||||
}
|
||||
|
||||
Datum
|
||||
enum_out(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid enumoid = PG_GETARG_OID(0);
|
||||
|
||||
PG_RETURN_CSTRING(enum_cstring(enumoid));
|
||||
}
|
||||
|
||||
/* guts of enum_out and enum-to-text */
|
||||
static char *
|
||||
enum_cstring(Oid enumval)
|
||||
{
|
||||
Oid enumval = PG_GETARG_OID(0);
|
||||
char *result;
|
||||
HeapTuple tup;
|
||||
Form_pg_enum en;
|
||||
char *label;
|
||||
|
||||
tup = SearchSysCache(ENUMOID,
|
||||
ObjectIdGetDatum(enumval),
|
||||
0, 0, 0);
|
||||
if (tup == NULL)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
||||
errmsg("invalid internal value for enum: %u",
|
||||
enumval)));
|
||||
if (!HeapTupleIsValid(tup))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
||||
errmsg("invalid internal value for enum: %u",
|
||||
enumval)));
|
||||
en = (Form_pg_enum) GETSTRUCT(tup);
|
||||
|
||||
label = pstrdup(NameStr(en->enumlabel));
|
||||
result = pstrdup(NameStr(en->enumlabel));
|
||||
|
||||
ReleaseSysCache(tup);
|
||||
return label;
|
||||
|
||||
PG_RETURN_CSTRING(result);
|
||||
}
|
||||
|
||||
/* Comparison functions and related */
|
||||
@@ -191,47 +174,6 @@ enum_cmp(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_INT32(-1);
|
||||
}
|
||||
|
||||
/* Casts between text and enum */
|
||||
|
||||
Datum
|
||||
enum_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid enumval = PG_GETARG_OID(0);
|
||||
text *result;
|
||||
char *cstr;
|
||||
int len;
|
||||
|
||||
cstr = enum_cstring(enumval);
|
||||
len = strlen(cstr);
|
||||
result = (text *) palloc(VARHDRSZ + len);
|
||||
SET_VARSIZE(result, VARHDRSZ + len);
|
||||
memcpy(VARDATA(result), cstr, len);
|
||||
pfree(cstr);
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
||||
Datum
|
||||
text_enum(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *textval = PG_GETARG_TEXT_P(0);
|
||||
Oid enumtypoid;
|
||||
char *str;
|
||||
|
||||
/*
|
||||
* We rely on being able to get the specific enum type from the calling
|
||||
* expression tree.
|
||||
*/
|
||||
enumtypoid = get_fn_expr_rettype(fcinfo->flinfo);
|
||||
if (enumtypoid == InvalidOid)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("could not determine actual enum type")));
|
||||
|
||||
str = DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(textval)));
|
||||
PG_RETURN_OID(cstring_enum(str, enumtypoid));
|
||||
}
|
||||
|
||||
/* Enum programming support functions */
|
||||
|
||||
Datum
|
||||
@@ -266,7 +208,7 @@ enum_first(PG_FUNCTION_ARGS)
|
||||
|
||||
ReleaseCatCacheList(list);
|
||||
|
||||
if (!OidIsValid(min)) /* should not happen */
|
||||
if (!OidIsValid(min)) /* should not happen */
|
||||
elog(ERROR, "no values found for enum %s",
|
||||
format_type_be(enumtypoid));
|
||||
|
||||
@@ -276,10 +218,10 @@ enum_first(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
enum_last(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid enumtypoid;
|
||||
Oid max = InvalidOid;
|
||||
CatCList *list;
|
||||
int num, i;
|
||||
Oid enumtypoid;
|
||||
Oid max = InvalidOid;
|
||||
CatCList *list;
|
||||
int num, i;
|
||||
|
||||
/*
|
||||
* We rely on being able to get the specific enum type from the calling
|
||||
@@ -292,24 +234,24 @@ enum_last(PG_FUNCTION_ARGS)
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("could not determine actual enum type")));
|
||||
|
||||
list = SearchSysCacheList(ENUMTYPOIDNAME, 1,
|
||||
ObjectIdGetDatum(enumtypoid),
|
||||
list = SearchSysCacheList(ENUMTYPOIDNAME, 1,
|
||||
ObjectIdGetDatum(enumtypoid),
|
||||
0, 0, 0);
|
||||
num = list->n_members;
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
num = list->n_members;
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
Oid valoid = HeapTupleHeaderGetOid(list->members[i]->tuple.t_data);
|
||||
if(!OidIsValid(max) || valoid > max)
|
||||
max = valoid;
|
||||
}
|
||||
if (!OidIsValid(max) || valoid > max)
|
||||
max = valoid;
|
||||
}
|
||||
|
||||
ReleaseCatCacheList(list);
|
||||
|
||||
if (!OidIsValid(max)) /* should not happen */
|
||||
if (!OidIsValid(max)) /* should not happen */
|
||||
elog(ERROR, "no values found for enum %s",
|
||||
format_type_be(enumtypoid));
|
||||
|
||||
PG_RETURN_OID(max);
|
||||
PG_RETURN_OID(max);
|
||||
}
|
||||
|
||||
/* 2-argument variant of enum_range */
|
||||
@@ -368,26 +310,26 @@ static ArrayType *
|
||||
enum_range_internal(Oid enumtypoid, Oid lower, Oid upper)
|
||||
{
|
||||
ArrayType *result;
|
||||
CatCList *list;
|
||||
int total, i, j;
|
||||
Datum *elems;
|
||||
CatCList *list;
|
||||
int total, i, j;
|
||||
Datum *elems;
|
||||
|
||||
list = SearchSysCacheList(ENUMTYPOIDNAME, 1,
|
||||
ObjectIdGetDatum(enumtypoid),
|
||||
ObjectIdGetDatum(enumtypoid),
|
||||
0, 0, 0);
|
||||
total = list->n_members;
|
||||
|
||||
elems = (Datum *) palloc(total * sizeof(Datum));
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < total; i++)
|
||||
{
|
||||
for (i = 0; i < total; i++)
|
||||
{
|
||||
Oid val = HeapTupleGetOid(&(list->members[i]->tuple));
|
||||
|
||||
if ((!OidIsValid(lower) || lower <= val) &&
|
||||
(!OidIsValid(upper) || val <= upper))
|
||||
elems[j++] = ObjectIdGetDatum(val);
|
||||
}
|
||||
elems[j++] = ObjectIdGetDatum(val);
|
||||
}
|
||||
|
||||
/* shouldn't need the cache anymore */
|
||||
ReleaseCatCacheList(list);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.149 2007/02/27 23:48:08 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.150 2007/06/05 21:31:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1196,108 +1196,6 @@ i2tof(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* float8_text - converts a float8 number to a text string
|
||||
*/
|
||||
Datum
|
||||
float8_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float8 num = PG_GETARG_FLOAT8(0);
|
||||
text *result;
|
||||
int len;
|
||||
char *str;
|
||||
|
||||
str = DatumGetCString(DirectFunctionCall1(float8out,
|
||||
Float8GetDatum(num)));
|
||||
|
||||
len = strlen(str) + VARHDRSZ;
|
||||
|
||||
result = (text *) palloc(len);
|
||||
|
||||
SET_VARSIZE(result, len);
|
||||
memcpy(VARDATA(result), str, (len - VARHDRSZ));
|
||||
|
||||
pfree(str);
|
||||
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* text_float8 - converts a text string to a float8 number
|
||||
*/
|
||||
Datum
|
||||
text_float8(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *string = PG_GETARG_TEXT_P(0);
|
||||
Datum result;
|
||||
int len;
|
||||
char *str;
|
||||
|
||||
len = (VARSIZE(string) - VARHDRSZ);
|
||||
str = palloc(len + 1);
|
||||
memcpy(str, VARDATA(string), len);
|
||||
*(str + len) = '\0';
|
||||
|
||||
result = DirectFunctionCall1(float8in, CStringGetDatum(str));
|
||||
|
||||
pfree(str);
|
||||
|
||||
PG_RETURN_DATUM(result);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* float4_text - converts a float4 number to a text string
|
||||
*/
|
||||
Datum
|
||||
float4_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float4 num = PG_GETARG_FLOAT4(0);
|
||||
text *result;
|
||||
int len;
|
||||
char *str;
|
||||
|
||||
str = DatumGetCString(DirectFunctionCall1(float4out,
|
||||
Float4GetDatum(num)));
|
||||
|
||||
len = strlen(str) + VARHDRSZ;
|
||||
|
||||
result = (text *) palloc(len);
|
||||
|
||||
SET_VARSIZE(result, len);
|
||||
memcpy(VARDATA(result), str, (len - VARHDRSZ));
|
||||
|
||||
pfree(str);
|
||||
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* text_float4 - converts a text string to a float4 number
|
||||
*/
|
||||
Datum
|
||||
text_float4(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *string = PG_GETARG_TEXT_P(0);
|
||||
Datum result;
|
||||
int len;
|
||||
char *str;
|
||||
|
||||
len = (VARSIZE(string) - VARHDRSZ);
|
||||
str = palloc(len + 1);
|
||||
memcpy(str, VARDATA(string), len);
|
||||
*(str + len) = '\0';
|
||||
|
||||
result = DirectFunctionCall1(float4in, CStringGetDatum(str));
|
||||
|
||||
pfree(str);
|
||||
|
||||
PG_RETURN_DATUM(result);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* =======================
|
||||
* RANDOM FLOAT8 OPERATORS
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.79 2007/02/27 23:48:08 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.80 2007/06/05 21:31:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -18,8 +18,6 @@
|
||||
* int2in, int2out, int2recv, int2send
|
||||
* int4in, int4out, int4recv, int4send
|
||||
* int2vectorin, int2vectorout, int2vectorrecv, int2vectorsend
|
||||
* Conversion routines:
|
||||
* itoi, int2_text, int4_text
|
||||
* Boolean operators:
|
||||
* inteq, intne, intlt, intle, intgt, intge
|
||||
* Arithmetic operators:
|
||||
@@ -343,68 +341,6 @@ i4toi2(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_INT16((int16) arg1);
|
||||
}
|
||||
|
||||
Datum
|
||||
int2_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int16 arg1 = PG_GETARG_INT16(0);
|
||||
text *result = (text *) palloc(7 + VARHDRSZ); /* sign,5 digits, '\0' */
|
||||
|
||||
pg_itoa(arg1, VARDATA(result));
|
||||
SET_VARSIZE(result, strlen(VARDATA(result)) + VARHDRSZ);
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
||||
Datum
|
||||
text_int2(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *string = PG_GETARG_TEXT_P(0);
|
||||
Datum result;
|
||||
int len;
|
||||
char *str;
|
||||
|
||||
len = VARSIZE(string) - VARHDRSZ;
|
||||
|
||||
str = palloc(len + 1);
|
||||
memcpy(str, VARDATA(string), len);
|
||||
*(str + len) = '\0';
|
||||
|
||||
result = DirectFunctionCall1(int2in, CStringGetDatum(str));
|
||||
pfree(str);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Datum
|
||||
int4_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int32 arg1 = PG_GETARG_INT32(0);
|
||||
text *result = (text *) palloc(12 + VARHDRSZ); /* sign,10 digits,'\0' */
|
||||
|
||||
pg_ltoa(arg1, VARDATA(result));
|
||||
SET_VARSIZE(result, strlen(VARDATA(result)) + VARHDRSZ);
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
||||
Datum
|
||||
text_int4(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *string = PG_GETARG_TEXT_P(0);
|
||||
Datum result;
|
||||
int len;
|
||||
char *str;
|
||||
|
||||
len = VARSIZE(string) - VARHDRSZ;
|
||||
|
||||
str = palloc(len + 1);
|
||||
memcpy(str, VARDATA(string), len);
|
||||
*(str + len) = '\0';
|
||||
|
||||
result = DirectFunctionCall1(int4in, CStringGetDatum(str));
|
||||
pfree(str);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Cast int4 -> bool */
|
||||
Datum
|
||||
int4_bool(PG_FUNCTION_ARGS)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/int8.c,v 1.65 2007/02/27 23:48:08 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/int8.c,v 1.66 2007/06/05 21:31:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1137,48 +1137,6 @@ oidtoi8(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_INT64((int64) arg);
|
||||
}
|
||||
|
||||
Datum
|
||||
text_int8(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *str = PG_GETARG_TEXT_P(0);
|
||||
int len;
|
||||
char *s;
|
||||
Datum result;
|
||||
|
||||
len = (VARSIZE(str) - VARHDRSZ);
|
||||
s = palloc(len + 1);
|
||||
memcpy(s, VARDATA(str), len);
|
||||
*(s + len) = '\0';
|
||||
|
||||
result = DirectFunctionCall1(int8in, CStringGetDatum(s));
|
||||
|
||||
pfree(s);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Datum
|
||||
int8_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/* arg is int64, but easier to leave it as Datum */
|
||||
Datum arg = PG_GETARG_DATUM(0);
|
||||
char *s;
|
||||
int len;
|
||||
text *result;
|
||||
|
||||
s = DatumGetCString(DirectFunctionCall1(int8out, arg));
|
||||
len = strlen(s);
|
||||
|
||||
result = (text *) palloc(VARHDRSZ + len);
|
||||
|
||||
SET_VARSIZE(result, VARHDRSZ + len);
|
||||
memcpy(VARDATA(result), s, len);
|
||||
|
||||
pfree(s);
|
||||
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* non-persistent numeric series generator
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* PostgreSQL type definitions for MAC addresses.
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/mac.c,v 1.37 2007/02/27 23:48:08 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/mac.c,v 1.38 2007/06/05 21:31:06 tgl Exp $
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
@@ -144,59 +144,6 @@ macaddr_send(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert macaddr to text data type.
|
||||
*/
|
||||
|
||||
Datum
|
||||
macaddr_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/* Input is a macaddr, but may as well leave it in Datum form */
|
||||
Datum addr = PG_GETARG_DATUM(0);
|
||||
text *result;
|
||||
char *str;
|
||||
int len;
|
||||
|
||||
str = DatumGetCString(DirectFunctionCall1(macaddr_out, addr));
|
||||
|
||||
len = (strlen(str) + VARHDRSZ);
|
||||
|
||||
result = palloc(len);
|
||||
|
||||
SET_VARSIZE(result, len);
|
||||
memcpy(VARDATA(result), str, (len - VARHDRSZ));
|
||||
|
||||
pfree(str);
|
||||
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert text to macaddr data type.
|
||||
*/
|
||||
|
||||
Datum
|
||||
text_macaddr(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *addr = PG_GETARG_TEXT_P(0);
|
||||
Datum result;
|
||||
char str[100];
|
||||
int len;
|
||||
|
||||
len = (VARSIZE(addr) - VARHDRSZ);
|
||||
if (len >= sizeof(str))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("text too long to convert to MAC address")));
|
||||
|
||||
memcpy(str, VARDATA(addr), len);
|
||||
*(str + len) = '\0';
|
||||
|
||||
result = DirectFunctionCall1(macaddr_in, CStringGetDatum(str));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Comparison function for sorting:
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* PostgreSQL type definitions for the INET and CIDR types.
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/network.c,v 1.70 2007/05/17 23:31:49 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/network.c,v 1.71 2007/06/05 21:31:06 tgl Exp $
|
||||
*
|
||||
* Jon Postel RIP 16 Oct 1998
|
||||
*/
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "utils/inet.h"
|
||||
|
||||
|
||||
static inet *text_network(text *src, bool is_cidr);
|
||||
static int32 network_cmp_internal(inet *a1, inet *a2);
|
||||
static int bitncmp(void *l, void *r, int n);
|
||||
static bool addressOK(unsigned char *a, int bits, int family);
|
||||
@@ -314,35 +313,6 @@ cidr_send(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
|
||||
static inet *
|
||||
text_network(text *src, bool is_cidr)
|
||||
{
|
||||
int len = VARSIZE(src) - VARHDRSZ;
|
||||
char *str = palloc(len + 1);
|
||||
|
||||
memcpy(str, VARDATA(src), len);
|
||||
str[len] = '\0';
|
||||
|
||||
return network_in(str, is_cidr);
|
||||
}
|
||||
|
||||
Datum
|
||||
text_inet(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *src = PG_GETARG_TEXT_P(0);
|
||||
|
||||
PG_RETURN_INET_P(text_network(src, false));
|
||||
}
|
||||
|
||||
Datum
|
||||
text_cidr(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *src = PG_GETARG_TEXT_P(0);
|
||||
|
||||
PG_RETURN_INET_P(text_network(src, true));
|
||||
}
|
||||
|
||||
|
||||
Datum
|
||||
inet_to_cidr(PG_FUNCTION_ARGS)
|
||||
{
|
||||
@@ -655,6 +625,11 @@ network_host(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_TEXT_P(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* network_show implements the inet and cidr casts to text. This is not
|
||||
* quite the same behavior as network_out, hence we can't drop it in favor
|
||||
* of CoerceViaIO.
|
||||
*/
|
||||
Datum
|
||||
network_show(PG_FUNCTION_ARGS)
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* Copyright (c) 1998-2007, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.102 2007/05/08 18:56:47 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.103 2007/06/05 21:31:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -2146,50 +2146,6 @@ numeric_float4(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
|
||||
Datum
|
||||
text_numeric(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *str = PG_GETARG_TEXT_P(0);
|
||||
int len;
|
||||
char *s;
|
||||
Datum result;
|
||||
|
||||
len = (VARSIZE(str) - VARHDRSZ);
|
||||
s = palloc(len + 1);
|
||||
memcpy(s, VARDATA(str), len);
|
||||
*(s + len) = '\0';
|
||||
|
||||
result = DirectFunctionCall3(numeric_in, CStringGetDatum(s),
|
||||
ObjectIdGetDatum(0), Int32GetDatum(-1));
|
||||
|
||||
pfree(s);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Datum
|
||||
numeric_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/* val is numeric, but easier to leave it as Datum */
|
||||
Datum val = PG_GETARG_DATUM(0);
|
||||
char *s;
|
||||
int len;
|
||||
text *result;
|
||||
|
||||
s = DatumGetCString(DirectFunctionCall1(numeric_out, val));
|
||||
len = strlen(s);
|
||||
|
||||
result = (text *) palloc(VARHDRSZ + len);
|
||||
|
||||
SET_VARSIZE(result, VARHDRSZ + len);
|
||||
memcpy(VARDATA(result), s, len);
|
||||
|
||||
pfree(s);
|
||||
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
*
|
||||
* Aggregate functions
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/oid.c,v 1.71 2007/02/27 23:48:08 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/oid.c,v 1.72 2007/06/05 21:31:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -31,7 +31,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
static Oid
|
||||
oidin_subr(const char *funcname, const char *s, char **endloc)
|
||||
oidin_subr(const char *s, char **endloc)
|
||||
{
|
||||
unsigned long cvt;
|
||||
char *endptr;
|
||||
@@ -116,7 +116,7 @@ oidin(PG_FUNCTION_ARGS)
|
||||
char *s = PG_GETARG_CSTRING(0);
|
||||
Oid result;
|
||||
|
||||
result = oidin_subr("oidin", s, NULL);
|
||||
result = oidin_subr(s, NULL);
|
||||
PG_RETURN_OID(result);
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ oidvectorin(PG_FUNCTION_ARGS)
|
||||
oidString++;
|
||||
if (*oidString == '\0')
|
||||
break;
|
||||
result->values[n] = oidin_subr("oidvectorin", oidString, &oidString);
|
||||
result->values[n] = oidin_subr(oidString, &oidString);
|
||||
}
|
||||
while (*oidString && isspace((unsigned char) *oidString))
|
||||
oidString++;
|
||||
@@ -419,45 +419,3 @@ oidvectorgt(PG_FUNCTION_ARGS)
|
||||
|
||||
PG_RETURN_BOOL(cmp > 0);
|
||||
}
|
||||
|
||||
Datum
|
||||
oid_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid oid = PG_GETARG_OID(0);
|
||||
text *result;
|
||||
int len;
|
||||
char *str;
|
||||
|
||||
str = DatumGetCString(DirectFunctionCall1(oidout,
|
||||
ObjectIdGetDatum(oid)));
|
||||
len = strlen(str) + VARHDRSZ;
|
||||
|
||||
result = (text *) palloc(len);
|
||||
|
||||
SET_VARSIZE(result, len);
|
||||
memcpy(VARDATA(result), str, (len - VARHDRSZ));
|
||||
pfree(str);
|
||||
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
||||
Datum
|
||||
text_oid(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *string = PG_GETARG_TEXT_P(0);
|
||||
Oid result;
|
||||
int len;
|
||||
char *str;
|
||||
|
||||
len = (VARSIZE(string) - VARHDRSZ);
|
||||
|
||||
str = palloc(len + 1);
|
||||
memcpy(str, VARDATA(string), len);
|
||||
*(str + len) = '\0';
|
||||
|
||||
result = oidin_subr("text_oid", str, NULL);
|
||||
|
||||
pfree(str);
|
||||
|
||||
PG_RETURN_OID(result);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/regproc.c,v 1.100 2007/01/05 22:19:41 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/regproc.c,v 1.101 2007/06/05 21:31:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1070,6 +1070,10 @@ regtypesend(PG_FUNCTION_ARGS)
|
||||
|
||||
/*
|
||||
* text_regclass: convert text to regclass
|
||||
*
|
||||
* This could be replaced by CoerceViaIO, except that we need to treat
|
||||
* text-to-regclass as an implicit cast to support legacy forms of nextval()
|
||||
* and related functions.
|
||||
*/
|
||||
Datum
|
||||
text_regclass(PG_FUNCTION_ARGS)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.94 2007/03/27 23:21:10 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.95 2007/06/05 21:31:06 tgl Exp $
|
||||
*
|
||||
* ----------
|
||||
*/
|
||||
@@ -3871,7 +3871,7 @@ ri_HashCompareOp(Oid eq_opr, Oid typeid)
|
||||
Oid lefttype,
|
||||
righttype,
|
||||
castfunc;
|
||||
bool arrayCoerce;
|
||||
CoercionPathType pathtype;
|
||||
|
||||
/* We always need to know how to call the equality operator */
|
||||
fmgr_info_cxt(get_opcode(eq_opr), &entry->eq_opr_finfo,
|
||||
@@ -3885,20 +3885,28 @@ ri_HashCompareOp(Oid eq_opr, Oid typeid)
|
||||
* here and in ri_AttributesEqual(). At the moment there is no
|
||||
* point because cases involving nonidentical array types will
|
||||
* be rejected at constraint creation time.
|
||||
*
|
||||
* XXX perhaps also consider supporting CoerceViaIO? No need at the
|
||||
* moment since that will never be generated for implicit coercions.
|
||||
*/
|
||||
op_input_types(eq_opr, &lefttype, &righttype);
|
||||
Assert(lefttype == righttype);
|
||||
if (typeid == lefttype)
|
||||
castfunc = InvalidOid; /* simplest case */
|
||||
else if (!find_coercion_pathway(lefttype, typeid, COERCION_IMPLICIT,
|
||||
&castfunc, &arrayCoerce)
|
||||
|| arrayCoerce) /* XXX fixme */
|
||||
else
|
||||
{
|
||||
/* If target is ANYARRAY, assume it's OK, else punt. */
|
||||
if (lefttype != ANYARRAYOID)
|
||||
elog(ERROR, "no conversion function from %s to %s",
|
||||
format_type_be(typeid),
|
||||
format_type_be(lefttype));
|
||||
pathtype = find_coercion_pathway(lefttype, typeid,
|
||||
COERCION_IMPLICIT,
|
||||
&castfunc);
|
||||
if (pathtype != COERCION_PATH_FUNC &&
|
||||
pathtype != COERCION_PATH_RELABELTYPE)
|
||||
{
|
||||
/* If target is ANYARRAY, assume it's OK, else punt. */
|
||||
if (lefttype != ANYARRAYOID)
|
||||
elog(ERROR, "no conversion function from %s to %s",
|
||||
format_type_be(typeid),
|
||||
format_type_be(lefttype));
|
||||
}
|
||||
}
|
||||
if (OidIsValid(castfunc))
|
||||
fmgr_info_cxt(castfunc, &entry->cast_func_finfo,
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.258 2007/05/24 18:58:42 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.259 2007/06/05 21:31:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -3127,6 +3127,9 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
|
||||
case T_RelabelType:
|
||||
return isSimpleNode((Node *) ((RelabelType *) node)->arg,
|
||||
node, prettyFlags);
|
||||
case T_CoerceViaIO:
|
||||
return isSimpleNode((Node *) ((CoerceViaIO *) node)->arg,
|
||||
node, prettyFlags);
|
||||
case T_ArrayCoerceExpr:
|
||||
return isSimpleNode((Node *) ((ArrayCoerceExpr *) node)->arg,
|
||||
node, prettyFlags);
|
||||
@@ -3595,6 +3598,27 @@ get_rule_expr(Node *node, deparse_context *context,
|
||||
}
|
||||
break;
|
||||
|
||||
case T_CoerceViaIO:
|
||||
{
|
||||
CoerceViaIO *iocoerce = (CoerceViaIO *) node;
|
||||
Node *arg = (Node *) iocoerce->arg;
|
||||
|
||||
if (iocoerce->coerceformat == COERCE_IMPLICIT_CAST &&
|
||||
!showimplicit)
|
||||
{
|
||||
/* don't show the implicit cast */
|
||||
get_rule_expr_paren(arg, context, false, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_coercion_expr(arg, context,
|
||||
iocoerce->resulttype,
|
||||
-1,
|
||||
node);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case T_ArrayCoerceExpr:
|
||||
{
|
||||
ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.176 2007/04/30 21:01:52 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.177 2007/06/05 21:31:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -3229,187 +3229,6 @@ timestamptz_age(PG_FUNCTION_ARGS)
|
||||
*---------------------------------------------------------*/
|
||||
|
||||
|
||||
/* timestamp_text()
|
||||
* Convert timestamp to text data type.
|
||||
*/
|
||||
Datum
|
||||
timestamp_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/* Input is a Timestamp, but may as well leave it in Datum form */
|
||||
Datum timestamp = PG_GETARG_DATUM(0);
|
||||
text *result;
|
||||
char *str;
|
||||
int len;
|
||||
|
||||
str = DatumGetCString(DirectFunctionCall1(timestamp_out, timestamp));
|
||||
|
||||
len = (strlen(str) + VARHDRSZ);
|
||||
|
||||
result = palloc(len);
|
||||
|
||||
SET_VARSIZE(result, len);
|
||||
memcpy(VARDATA(result), str, len - VARHDRSZ);
|
||||
|
||||
pfree(str);
|
||||
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
||||
|
||||
/* text_timestamp()
|
||||
* Convert text string to timestamp.
|
||||
* Text type is not null terminated, so use temporary string
|
||||
* then call the standard input routine.
|
||||
*/
|
||||
Datum
|
||||
text_timestamp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *str = PG_GETARG_TEXT_P(0);
|
||||
int i;
|
||||
char *sp,
|
||||
*dp,
|
||||
dstr[MAXDATELEN + 1];
|
||||
|
||||
if (VARSIZE(str) - VARHDRSZ > MAXDATELEN)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for type timestamp: \"%s\"",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(str))))));
|
||||
|
||||
sp = VARDATA(str);
|
||||
dp = dstr;
|
||||
for (i = 0; i < VARSIZE(str) - VARHDRSZ; i++)
|
||||
*dp++ = *sp++;
|
||||
*dp = '\0';
|
||||
|
||||
return DirectFunctionCall3(timestamp_in,
|
||||
CStringGetDatum(dstr),
|
||||
ObjectIdGetDatum(InvalidOid),
|
||||
Int32GetDatum(-1));
|
||||
}
|
||||
|
||||
|
||||
/* timestamptz_text()
|
||||
* Convert timestamp with time zone to text data type.
|
||||
*/
|
||||
Datum
|
||||
timestamptz_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/* Input is a Timestamp, but may as well leave it in Datum form */
|
||||
Datum timestamp = PG_GETARG_DATUM(0);
|
||||
text *result;
|
||||
char *str;
|
||||
int len;
|
||||
|
||||
str = DatumGetCString(DirectFunctionCall1(timestamptz_out, timestamp));
|
||||
|
||||
len = strlen(str) + VARHDRSZ;
|
||||
|
||||
result = palloc(len);
|
||||
|
||||
SET_VARSIZE(result, len);
|
||||
memcpy(VARDATA(result), str, len - VARHDRSZ);
|
||||
|
||||
pfree(str);
|
||||
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
||||
/* text_timestamptz()
|
||||
* Convert text string to timestamp with time zone.
|
||||
* Text type is not null terminated, so use temporary string
|
||||
* then call the standard input routine.
|
||||
*/
|
||||
Datum
|
||||
text_timestamptz(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *str = PG_GETARG_TEXT_P(0);
|
||||
int i;
|
||||
char *sp,
|
||||
*dp,
|
||||
dstr[MAXDATELEN + 1];
|
||||
|
||||
if (VARSIZE(str) - VARHDRSZ > MAXDATELEN)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for type timestamp with time zone: \"%s\"",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(str))))));
|
||||
|
||||
sp = VARDATA(str);
|
||||
dp = dstr;
|
||||
for (i = 0; i < VARSIZE(str) - VARHDRSZ; i++)
|
||||
*dp++ = *sp++;
|
||||
*dp = '\0';
|
||||
|
||||
return DirectFunctionCall3(timestamptz_in,
|
||||
CStringGetDatum(dstr),
|
||||
ObjectIdGetDatum(InvalidOid),
|
||||
Int32GetDatum(-1));
|
||||
}
|
||||
|
||||
|
||||
/* interval_text()
|
||||
* Convert interval to text data type.
|
||||
*/
|
||||
Datum
|
||||
interval_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Interval *interval = PG_GETARG_INTERVAL_P(0);
|
||||
text *result;
|
||||
char *str;
|
||||
int len;
|
||||
|
||||
str = DatumGetCString(DirectFunctionCall1(interval_out,
|
||||
IntervalPGetDatum(interval)));
|
||||
|
||||
len = strlen(str) + VARHDRSZ;
|
||||
|
||||
result = palloc(len);
|
||||
|
||||
SET_VARSIZE(result, len);
|
||||
memcpy(VARDATA(result), str, len - VARHDRSZ);
|
||||
|
||||
pfree(str);
|
||||
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
||||
|
||||
/* text_interval()
|
||||
* Convert text string to interval.
|
||||
* Text type may not be null terminated, so copy to temporary string
|
||||
* then call the standard input routine.
|
||||
*/
|
||||
Datum
|
||||
text_interval(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *str = PG_GETARG_TEXT_P(0);
|
||||
int i;
|
||||
char *sp,
|
||||
*dp,
|
||||
dstr[MAXDATELEN + 1];
|
||||
|
||||
if (VARSIZE(str) - VARHDRSZ > MAXDATELEN)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for type interval: \"%s\"",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(str))))));
|
||||
|
||||
sp = VARDATA(str);
|
||||
dp = dstr;
|
||||
for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++)
|
||||
*dp++ = *sp++;
|
||||
*dp = '\0';
|
||||
|
||||
return DirectFunctionCall3(interval_in,
|
||||
CStringGetDatum(dstr),
|
||||
ObjectIdGetDatum(InvalidOid),
|
||||
Int32GetDatum(-1));
|
||||
}
|
||||
|
||||
/* timestamp_trunc()
|
||||
* Truncate timestamp to specified units.
|
||||
*/
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* Copyright (c) 2007, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/uuid.c,v 1.3 2007/01/31 19:33:54 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/uuid.c,v 1.4 2007/06/05 21:31:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -238,32 +238,3 @@ uuid_hash(PG_FUNCTION_ARGS)
|
||||
pg_uuid_t *key = PG_GETARG_UUID_P(0);
|
||||
return hash_any(key->data, UUID_LEN);
|
||||
}
|
||||
|
||||
/* cast text to uuid */
|
||||
Datum
|
||||
text_uuid(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *input = PG_GETARG_TEXT_P(0);
|
||||
int length;
|
||||
char *str;
|
||||
Datum result;
|
||||
|
||||
length = VARSIZE(input) - VARHDRSZ;
|
||||
str = palloc(length + 1);
|
||||
memcpy(str, VARDATA(input), length);
|
||||
*(str + length) = '\0';
|
||||
|
||||
result = DirectFunctionCall1(uuid_in, CStringGetDatum(str));
|
||||
pfree(str);
|
||||
PG_RETURN_DATUM(result);
|
||||
}
|
||||
|
||||
/* cast uuid to text */
|
||||
Datum
|
||||
uuid_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
pg_uuid_t *uuid = PG_GETARG_UUID_P(0);
|
||||
Datum uuid_str = DirectFunctionCall1(uuid_out, UUIDPGetDatum(uuid));
|
||||
|
||||
PG_RETURN_DATUM(DirectFunctionCall1(textin, uuid_str));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user