mirror of
https://github.com/postgres/postgres.git
synced 2025-11-10 17:42:29 +03:00
pgindent run.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.92 2003/07/27 04:53:02 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.93 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -36,7 +36,7 @@ static Acl *allocacl(int n);
|
||||
static const char *aclparse(const char *s, AclItem *aip);
|
||||
static bool aclitem_match(const AclItem *a1, const AclItem *a2);
|
||||
static Acl *recursive_revoke(Acl *acl, AclId grantee,
|
||||
AclMode revoke_privs, DropBehavior behavior);
|
||||
AclMode revoke_privs, DropBehavior behavior);
|
||||
|
||||
static AclMode convert_priv_string(text *priv_type_text);
|
||||
|
||||
@@ -77,24 +77,22 @@ getid(const char *s, char *n)
|
||||
/* This test had better match what putid() does, below */
|
||||
for (;
|
||||
*s != '\0' &&
|
||||
(isalnum((unsigned char) *s) ||
|
||||
*s == '_' ||
|
||||
*s == '"' ||
|
||||
in_quotes);
|
||||
(isalnum((unsigned char) *s) ||
|
||||
*s == '_' ||
|
||||
*s == '"' ||
|
||||
in_quotes);
|
||||
s++)
|
||||
{
|
||||
if (*s == '"')
|
||||
{
|
||||
in_quotes = !in_quotes;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (len >= NAMEDATALEN-1)
|
||||
if (len >= NAMEDATALEN - 1)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NAME_TOO_LONG),
|
||||
errmsg("identifier too long"),
|
||||
errdetail("Identifier must be less than %d characters.",
|
||||
NAMEDATALEN)));
|
||||
errdetail("Identifier must be less than %d characters.",
|
||||
NAMEDATALEN)));
|
||||
|
||||
n[len++] = *s;
|
||||
}
|
||||
@@ -107,13 +105,13 @@ getid(const char *s, char *n)
|
||||
|
||||
/*
|
||||
* Write a user or group Name at *p, surrounding it with double quotes if
|
||||
* needed. There must be at least NAMEDATALEN+2 bytes available at *p.
|
||||
* needed. There must be at least NAMEDATALEN+2 bytes available at *p.
|
||||
*/
|
||||
static void
|
||||
putid(char *p, const char *s)
|
||||
{
|
||||
const char *src;
|
||||
bool safe = true;
|
||||
bool safe = true;
|
||||
|
||||
for (src = s; *src; src++)
|
||||
{
|
||||
@@ -153,7 +151,9 @@ putid(char *p, const char *s)
|
||||
static const char *
|
||||
aclparse(const char *s, AclItem *aip)
|
||||
{
|
||||
AclMode privs, goption, read;
|
||||
AclMode privs,
|
||||
goption,
|
||||
read;
|
||||
uint32 idtype;
|
||||
char name[NAMEDATALEN];
|
||||
char name2[NAMEDATALEN];
|
||||
@@ -174,13 +174,13 @@ aclparse(const char *s, AclItem *aip)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("unrecognized keyword: \"%s\"", name),
|
||||
errhint("ACL keyword must be \"group\" or \"user\".")));
|
||||
errhint("ACL keyword must be \"group\" or \"user\".")));
|
||||
s = getid(s, name); /* move s to the name beyond the keyword */
|
||||
if (name[0] == '\0')
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("missing name"),
|
||||
errhint("A name must follow the [group|user] keyword.")));
|
||||
errhint("A name must follow the [group|user] keyword.")));
|
||||
}
|
||||
if (name[0] == '\0')
|
||||
idtype = ACL_IDTYPE_WORLD;
|
||||
@@ -192,7 +192,7 @@ aclparse(const char *s, AclItem *aip)
|
||||
|
||||
privs = goption = ACL_NO_RIGHTS;
|
||||
|
||||
for (++s, read=0; isalpha((unsigned char) *s) || *s == '*'; s++)
|
||||
for (++s, read = 0; isalpha((unsigned char) *s) || *s == '*'; s++)
|
||||
{
|
||||
switch (*s)
|
||||
{
|
||||
@@ -235,8 +235,8 @@ aclparse(const char *s, AclItem *aip)
|
||||
default:
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid mode character: must be one of \"%s\"",
|
||||
ACL_ALL_RIGHTS_STR)));
|
||||
errmsg("invalid mode character: must be one of \"%s\"",
|
||||
ACL_ALL_RIGHTS_STR)));
|
||||
}
|
||||
|
||||
privs |= read;
|
||||
@@ -255,8 +255,10 @@ aclparse(const char *s, AclItem *aip)
|
||||
break;
|
||||
}
|
||||
|
||||
/* XXX Allow a degree of backward compatibility by defaulting the
|
||||
* grantor to the superuser. */
|
||||
/*
|
||||
* XXX Allow a degree of backward compatibility by defaulting the
|
||||
* grantor to the superuser.
|
||||
*/
|
||||
if (*s == '/')
|
||||
{
|
||||
s = getid(s + 1, name2);
|
||||
@@ -331,7 +333,7 @@ aclitemin(PG_FUNCTION_ARGS)
|
||||
if (*s)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("extra garbage at the end of the ACL specification")));
|
||||
errmsg("extra garbage at the end of the ACL specification")));
|
||||
|
||||
PG_RETURN_ACLITEM_P(aip);
|
||||
}
|
||||
@@ -356,7 +358,7 @@ aclitemout(PG_FUNCTION_ARGS)
|
||||
|
||||
out = palloc(strlen("group =/") +
|
||||
2 * N_ACL_RIGHTS +
|
||||
2 * (NAMEDATALEN+2) +
|
||||
2 * (NAMEDATALEN + 2) +
|
||||
1);
|
||||
|
||||
p = out;
|
||||
@@ -454,8 +456,8 @@ aclitem_match(const AclItem *a1, const AclItem *a2)
|
||||
Datum
|
||||
aclitem_eq(PG_FUNCTION_ARGS)
|
||||
{
|
||||
AclItem *a1 = PG_GETARG_ACLITEM_P(0);
|
||||
AclItem *a2 = PG_GETARG_ACLITEM_P(1);
|
||||
AclItem *a1 = PG_GETARG_ACLITEM_P(0);
|
||||
AclItem *a2 = PG_GETARG_ACLITEM_P(1);
|
||||
bool result;
|
||||
|
||||
result = a1->ai_privs == a2->ai_privs &&
|
||||
@@ -510,7 +512,7 @@ acldefault(GrantObjectType objtype, AclId ownerid)
|
||||
}
|
||||
|
||||
acl = allocacl((world_default != ACL_NO_RIGHTS ? 1 : 0)
|
||||
+ (ownerid ? 1 : 0));
|
||||
+ (ownerid ? 1 : 0));
|
||||
aip = ACL_DAT(acl);
|
||||
|
||||
if (world_default != ACL_NO_RIGHTS)
|
||||
@@ -522,7 +524,7 @@ acldefault(GrantObjectType objtype, AclId ownerid)
|
||||
|
||||
if (ownerid)
|
||||
{
|
||||
int index = (world_default != ACL_NO_RIGHTS ? 1: 0);
|
||||
int index = (world_default != ACL_NO_RIGHTS ? 1 : 0);
|
||||
|
||||
aip[index].ai_grantee = ownerid;
|
||||
aip[index].ai_grantor = ownerid;
|
||||
@@ -563,10 +565,10 @@ aclinsert3(const Acl *old_acl, const AclItem *mod_aip, unsigned modechg, DropBeh
|
||||
old_aip = ACL_DAT(old_acl);
|
||||
|
||||
/*
|
||||
* Search the ACL for an existing entry for this grantee and
|
||||
* grantor. If one exists, just modify the entry in-place (well,
|
||||
* in the same position, since we actually return a copy);
|
||||
* otherwise, insert the new entry at the end.
|
||||
* Search the ACL for an existing entry for this grantee and grantor.
|
||||
* If one exists, just modify the entry in-place (well, in the same
|
||||
* position, since we actually return a copy); otherwise, insert the
|
||||
* new entry at the end.
|
||||
*/
|
||||
|
||||
for (dst = 0; dst < num; ++dst)
|
||||
@@ -652,17 +654,17 @@ recursive_revoke(Acl *acl,
|
||||
AclMode revoke_privs,
|
||||
DropBehavior behavior)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
restart:
|
||||
for (i = 0; i < ACL_NUM(acl); i++)
|
||||
{
|
||||
AclItem *aip = ACL_DAT(acl);
|
||||
AclItem *aip = ACL_DAT(acl);
|
||||
|
||||
if (aip[i].ai_grantor == grantee
|
||||
&& (ACLITEM_GET_PRIVS(aip[i]) & revoke_privs) != 0)
|
||||
{
|
||||
AclItem mod_acl;
|
||||
AclItem mod_acl;
|
||||
|
||||
if (behavior == DROP_RESTRICT)
|
||||
ereport(ERROR,
|
||||
@@ -727,7 +729,7 @@ aclremove(PG_FUNCTION_ARGS)
|
||||
for (dst = 0;
|
||||
dst < old_num && !aclitem_match(mod_aip, old_aip + dst);
|
||||
++dst)
|
||||
/* continue */ ;
|
||||
/* continue */ ;
|
||||
|
||||
if (dst >= old_num)
|
||||
{
|
||||
@@ -797,15 +799,17 @@ makeaclitem(PG_FUNCTION_ARGS)
|
||||
int32 grantor = PG_GETARG_INT32(2);
|
||||
text *privtext = PG_GETARG_TEXT_P(3);
|
||||
bool goption = PG_GETARG_BOOL(4);
|
||||
AclItem *aclitem;
|
||||
AclItem *aclitem;
|
||||
AclMode priv;
|
||||
|
||||
priv = convert_priv_string(privtext);
|
||||
|
||||
aclitem = (AclItem *) palloc(sizeof(*aclitem));
|
||||
|
||||
if (u_grantee == 0 && g_grantee == 0)
|
||||
{
|
||||
aclitem->ai_grantee = 0;
|
||||
aclitem ->ai_grantee = 0;
|
||||
|
||||
ACLITEM_SET_IDTYPE(*aclitem, ACL_IDTYPE_WORLD);
|
||||
}
|
||||
else if (u_grantee != 0 && g_grantee != 0)
|
||||
@@ -816,16 +820,19 @@ makeaclitem(PG_FUNCTION_ARGS)
|
||||
}
|
||||
else if (u_grantee != 0)
|
||||
{
|
||||
aclitem->ai_grantee = u_grantee;
|
||||
aclitem ->ai_grantee = u_grantee;
|
||||
|
||||
ACLITEM_SET_IDTYPE(*aclitem, ACL_IDTYPE_UID);
|
||||
}
|
||||
else if (g_grantee != 0)
|
||||
{
|
||||
aclitem->ai_grantee = g_grantee;
|
||||
aclitem ->ai_grantee = g_grantee;
|
||||
|
||||
ACLITEM_SET_IDTYPE(*aclitem, ACL_IDTYPE_GID);
|
||||
}
|
||||
|
||||
aclitem->ai_grantor = grantor;
|
||||
aclitem ->ai_grantor = grantor;
|
||||
|
||||
ACLITEM_SET_PRIVS(*aclitem, priv);
|
||||
if (goption)
|
||||
ACLITEM_SET_GOPTIONS(*aclitem, priv);
|
||||
@@ -841,7 +848,7 @@ convert_priv_string(text *priv_type_text)
|
||||
char *priv_type;
|
||||
|
||||
priv_type = DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(priv_type_text)));
|
||||
PointerGetDatum(priv_type_text)));
|
||||
|
||||
if (strcasecmp(priv_type, "SELECT") == 0)
|
||||
return ACL_SELECT;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* Copyright (c) 2003, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/array_userfuncs.c,v 1.6 2003/07/27 04:53:02 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/array_userfuncs.c,v 1.7 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -81,7 +81,8 @@ array_push(PG_FUNCTION_ARGS)
|
||||
if (arg0_elemid != InvalidOid)
|
||||
{
|
||||
/* append newelem */
|
||||
int ub = dimv[0] + lb[0] - 1;
|
||||
int ub = dimv[0] + lb[0] - 1;
|
||||
|
||||
indx = ub + 1;
|
||||
}
|
||||
else
|
||||
@@ -105,7 +106,7 @@ array_push(PG_FUNCTION_ARGS)
|
||||
if (my_extra == NULL)
|
||||
{
|
||||
fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
|
||||
sizeof(ArrayMetaState));
|
||||
sizeof(ArrayMetaState));
|
||||
my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
|
||||
my_extra->element_type = InvalidOid;
|
||||
}
|
||||
@@ -138,11 +139,23 @@ array_push(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
array_cat(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ArrayType *v1, *v2;
|
||||
int *dims, *lbs, ndims, ndatabytes, nbytes;
|
||||
int *dims1, *lbs1, ndims1, ndatabytes1;
|
||||
int *dims2, *lbs2, ndims2, ndatabytes2;
|
||||
char *dat1, *dat2;
|
||||
ArrayType *v1,
|
||||
*v2;
|
||||
int *dims,
|
||||
*lbs,
|
||||
ndims,
|
||||
ndatabytes,
|
||||
nbytes;
|
||||
int *dims1,
|
||||
*lbs1,
|
||||
ndims1,
|
||||
ndatabytes1;
|
||||
int *dims2,
|
||||
*lbs2,
|
||||
ndims2,
|
||||
ndatabytes2;
|
||||
char *dat1,
|
||||
*dat2;
|
||||
Oid element_type;
|
||||
Oid element_type1;
|
||||
Oid element_type2;
|
||||
@@ -152,12 +165,10 @@ array_cat(PG_FUNCTION_ARGS)
|
||||
v2 = PG_GETARG_ARRAYTYPE_P(1);
|
||||
|
||||
/*
|
||||
* We must have one of the following combinations of inputs:
|
||||
* 1) one empty array, and one non-empty array
|
||||
* 2) both arrays empty
|
||||
* 3) two arrays with ndims1 == ndims2
|
||||
* 4) ndims1 == ndims2 - 1
|
||||
* 5) ndims1 == ndims2 + 1
|
||||
* We must have one of the following combinations of inputs: 1) one
|
||||
* empty array, and one non-empty array 2) both arrays empty 3) two
|
||||
* arrays with ndims1 == ndims2 4) ndims1 == ndims2 - 1 5) ndims1 ==
|
||||
* ndims2 + 1
|
||||
*/
|
||||
ndims1 = ARR_NDIM(v1);
|
||||
ndims2 = ARR_NDIM(v2);
|
||||
@@ -180,8 +191,8 @@ array_cat(PG_FUNCTION_ARGS)
|
||||
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
||||
errmsg("cannot concatenate incompatible arrays"),
|
||||
errdetail("Arrays of %d and %d dimensions are not "
|
||||
"compatible for concatenation.",
|
||||
ndims1, ndims2)));
|
||||
"compatible for concatenation.",
|
||||
ndims1, ndims2)));
|
||||
|
||||
element_type1 = ARR_ELEMTYPE(v1);
|
||||
element_type2 = ARR_ELEMTYPE(v2);
|
||||
@@ -192,7 +203,7 @@ array_cat(PG_FUNCTION_ARGS)
|
||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
errmsg("cannot concatenate incompatible arrays"),
|
||||
errdetail("Arrays with element types %s and %s are not "
|
||||
"compatible for concatenation.",
|
||||
"compatible for concatenation.",
|
||||
format_type_be(element_type1),
|
||||
format_type_be(element_type2))));
|
||||
|
||||
@@ -215,14 +226,14 @@ array_cat(PG_FUNCTION_ARGS)
|
||||
* resulting array has two element outer array made up of input
|
||||
* argument arrays
|
||||
*/
|
||||
int i;
|
||||
int i;
|
||||
|
||||
ndims = ndims1 + 1;
|
||||
dims = (int *) palloc(ndims * sizeof(int));
|
||||
lbs = (int *) palloc(ndims * sizeof(int));
|
||||
|
||||
dims[0] = 2; /* outer array made up of two input arrays */
|
||||
lbs[0] = 1; /* start lower bound at 1 */
|
||||
dims[0] = 2; /* outer array made up of two input arrays */
|
||||
lbs[0] = 1; /* start lower bound at 1 */
|
||||
|
||||
for (i = 0; i < ndims1; i++)
|
||||
{
|
||||
@@ -230,8 +241,8 @@ array_cat(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
||||
errmsg("cannot concatenate incompatible arrays"),
|
||||
errdetail("Arrays with differing dimensions are not "
|
||||
"compatible for concatenation.")));
|
||||
errdetail("Arrays with differing dimensions are not "
|
||||
"compatible for concatenation.")));
|
||||
|
||||
dims[i + 1] = dims1[i];
|
||||
lbs[i + 1] = lbs1[i];
|
||||
@@ -244,7 +255,7 @@ array_cat(PG_FUNCTION_ARGS)
|
||||
* with the first argument appended to the front of the outer
|
||||
* dimension
|
||||
*/
|
||||
int i;
|
||||
int i;
|
||||
|
||||
ndims = ndims2;
|
||||
dims = dims2;
|
||||
@@ -260,18 +271,18 @@ array_cat(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
||||
errmsg("cannot concatenate incompatible arrays"),
|
||||
errdetail("Arrays with differing dimensions are not "
|
||||
"compatible for concatenation.")));
|
||||
errdetail("Arrays with differing dimensions are not "
|
||||
"compatible for concatenation.")));
|
||||
}
|
||||
}
|
||||
else /* (ndims1 == ndims2 + 1) */
|
||||
else
|
||||
/* (ndims1 == ndims2 + 1) */
|
||||
{
|
||||
/*
|
||||
* resulting array has the first argument as the outer array,
|
||||
* with the second argument appended to the end of the outer
|
||||
* dimension
|
||||
* resulting array has the first argument as the outer array, with
|
||||
* the second argument appended to the end of the outer dimension
|
||||
*/
|
||||
int i;
|
||||
int i;
|
||||
|
||||
ndims = ndims1;
|
||||
dims = dims1;
|
||||
@@ -287,8 +298,8 @@ array_cat(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
||||
errmsg("cannot concatenate incompatible arrays"),
|
||||
errdetail("Arrays with differing dimensions are not "
|
||||
"compatible for concatenation.")));
|
||||
errdetail("Arrays with differing dimensions are not "
|
||||
"compatible for concatenation.")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,13 +331,13 @@ create_singleton_array(FunctionCallInfo fcinfo,
|
||||
Datum element,
|
||||
int ndims)
|
||||
{
|
||||
Datum dvalues[1];
|
||||
int16 typlen;
|
||||
bool typbyval;
|
||||
char typalign;
|
||||
int dims[MAXDIM];
|
||||
int lbs[MAXDIM];
|
||||
int i;
|
||||
Datum dvalues[1];
|
||||
int16 typlen;
|
||||
bool typbyval;
|
||||
char typalign;
|
||||
int dims[MAXDIM];
|
||||
int lbs[MAXDIM];
|
||||
int i;
|
||||
ArrayMetaState *my_extra;
|
||||
|
||||
if (element_type == 0)
|
||||
@@ -359,7 +370,7 @@ create_singleton_array(FunctionCallInfo fcinfo,
|
||||
if (my_extra == NULL)
|
||||
{
|
||||
fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
|
||||
sizeof(ArrayMetaState));
|
||||
sizeof(ArrayMetaState));
|
||||
my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
|
||||
my_extra->element_type = InvalidOid;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.94 2003/07/27 04:53:02 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.95 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -79,9 +79,9 @@ static Datum *ReadArrayStr(char *arrayStr, int nitems, int ndim, int *dim,
|
||||
int typlen, bool typbyval, char typalign,
|
||||
int *nbytes);
|
||||
static Datum *ReadArrayBinary(StringInfo buf, int nitems,
|
||||
FmgrInfo *receiveproc, Oid typelem,
|
||||
int typlen, bool typbyval, char typalign,
|
||||
int *nbytes);
|
||||
FmgrInfo *receiveproc, Oid typelem,
|
||||
int typlen, bool typbyval, char typalign,
|
||||
int *nbytes);
|
||||
static void CopyArrayEls(char *p, Datum *values, int nitems,
|
||||
int typlen, bool typbyval, char typalign,
|
||||
bool freedata);
|
||||
@@ -107,7 +107,7 @@ static void array_insert_slice(int ndim, int *dim, int *lb,
|
||||
char *destPtr,
|
||||
int *st, int *endp, char *srcPtr,
|
||||
int typlen, bool typbyval, char typalign);
|
||||
static int array_cmp(FunctionCallInfo fcinfo);
|
||||
static int array_cmp(FunctionCallInfo fcinfo);
|
||||
|
||||
/*---------------------------------------------------------------------
|
||||
* array_in :
|
||||
@@ -144,21 +144,24 @@ array_in(PG_FUNCTION_ARGS)
|
||||
|
||||
/*
|
||||
* We arrange to look up info about element type, including its input
|
||||
* conversion proc, only once per series of calls, assuming the element
|
||||
* type doesn't change underneath us.
|
||||
* conversion proc, only once per series of calls, assuming the
|
||||
* element type doesn't change underneath us.
|
||||
*/
|
||||
my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
|
||||
if (my_extra == NULL)
|
||||
{
|
||||
fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
|
||||
sizeof(ArrayMetaState));
|
||||
sizeof(ArrayMetaState));
|
||||
my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
|
||||
my_extra->element_type = InvalidOid;
|
||||
}
|
||||
|
||||
if (my_extra->element_type != element_type)
|
||||
{
|
||||
/* Get info about element type, including its input conversion proc */
|
||||
/*
|
||||
* Get info about element type, including its input conversion
|
||||
* proc
|
||||
*/
|
||||
get_type_io_data(element_type, IOFunc_input,
|
||||
&my_extra->typlen, &my_extra->typbyval,
|
||||
&my_extra->typalign, &my_extra->typdelim,
|
||||
@@ -242,7 +245,7 @@ array_in(PG_FUNCTION_ARGS)
|
||||
if (ub < lBound[ndim])
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
||||
errmsg("upper bound cannot be less than lower bound")));
|
||||
errmsg("upper bound cannot be less than lower bound")));
|
||||
|
||||
dim[ndim] = ub - lBound[ndim] + 1;
|
||||
ndim++;
|
||||
@@ -351,7 +354,7 @@ ArrayCount(char *str, int *dim, char typdelim)
|
||||
/* Signal a premature end of the string */
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
break;
|
||||
case '\\':
|
||||
/* skip the escaped character */
|
||||
@@ -359,8 +362,8 @@ ArrayCount(char *str, int *dim, char typdelim)
|
||||
ptr++;
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
break;
|
||||
case '\"':
|
||||
scanning_string = !scanning_string;
|
||||
@@ -370,9 +373,9 @@ ArrayCount(char *str, int *dim, char typdelim)
|
||||
{
|
||||
if (nest_level >= MAXDIM)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
||||
errmsg("number of array dimensions exceeds the maximum allowed, %d",
|
||||
MAXDIM)));
|
||||
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
||||
errmsg("number of array dimensions exceeds the maximum allowed, %d",
|
||||
MAXDIM)));
|
||||
temp[nest_level] = 0;
|
||||
nest_level++;
|
||||
if (ndim < nest_level)
|
||||
@@ -384,8 +387,8 @@ ArrayCount(char *str, int *dim, char typdelim)
|
||||
{
|
||||
if (nest_level == 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
nest_level--;
|
||||
if (nest_level == 0)
|
||||
eoArray = itemdone = true;
|
||||
@@ -479,7 +482,7 @@ ReadArrayStr(char *arrayStr,
|
||||
/* Signal a premature end of the string */
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", arrayStr)));
|
||||
errmsg("malformed array literal: \"%s\"", arrayStr)));
|
||||
break;
|
||||
case '\\':
|
||||
{
|
||||
@@ -490,8 +493,8 @@ ReadArrayStr(char *arrayStr,
|
||||
*cptr = *(cptr + 1);
|
||||
if (*ptr == '\0')
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", arrayStr)));
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", arrayStr)));
|
||||
break;
|
||||
}
|
||||
case '\"':
|
||||
@@ -511,8 +514,8 @@ ReadArrayStr(char *arrayStr,
|
||||
{
|
||||
if (nest_level >= ndim)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", arrayStr)));
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", arrayStr)));
|
||||
nest_level++;
|
||||
indx[nest_level - 1] = 0;
|
||||
/* skip leading whitespace */
|
||||
@@ -526,8 +529,8 @@ ReadArrayStr(char *arrayStr,
|
||||
{
|
||||
if (nest_level == 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", arrayStr)));
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", arrayStr)));
|
||||
if (i == -1)
|
||||
i = ArrayGetOffset0(ndim, indx, prod);
|
||||
indx[nest_level - 1] = 0;
|
||||
@@ -565,7 +568,7 @@ ReadArrayStr(char *arrayStr,
|
||||
if (i < 0 || i >= nitems)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", arrayStr)));
|
||||
errmsg("malformed array literal: \"%s\"", arrayStr)));
|
||||
|
||||
values[i] = FunctionCall3(inputproc,
|
||||
CStringGetDatum(itemstart),
|
||||
@@ -693,21 +696,24 @@ array_out(PG_FUNCTION_ARGS)
|
||||
|
||||
/*
|
||||
* We arrange to look up info about element type, including its output
|
||||
* conversion proc, only once per series of calls, assuming the element
|
||||
* type doesn't change underneath us.
|
||||
* conversion proc, only once per series of calls, assuming the
|
||||
* element type doesn't change underneath us.
|
||||
*/
|
||||
my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
|
||||
if (my_extra == NULL)
|
||||
{
|
||||
fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
|
||||
sizeof(ArrayMetaState));
|
||||
sizeof(ArrayMetaState));
|
||||
my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
|
||||
my_extra->element_type = InvalidOid;
|
||||
}
|
||||
|
||||
if (my_extra->element_type != element_type)
|
||||
{
|
||||
/* Get info about element type, including its output conversion proc */
|
||||
/*
|
||||
* Get info about element type, including its output conversion
|
||||
* proc
|
||||
*/
|
||||
get_type_io_data(element_type, IOFunc_output,
|
||||
&my_extra->typlen, &my_extra->typbyval,
|
||||
&my_extra->typalign, &my_extra->typdelim,
|
||||
@@ -922,15 +928,15 @@ array_recv(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
/*
|
||||
* We arrange to look up info about element type, including its receive
|
||||
* conversion proc, only once per series of calls, assuming the element
|
||||
* type doesn't change underneath us.
|
||||
* We arrange to look up info about element type, including its
|
||||
* receive conversion proc, only once per series of calls, assuming
|
||||
* the element type doesn't change underneath us.
|
||||
*/
|
||||
my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
|
||||
if (my_extra == NULL)
|
||||
{
|
||||
fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
|
||||
sizeof(ArrayMetaState));
|
||||
sizeof(ArrayMetaState));
|
||||
my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
|
||||
my_extra->element_type = InvalidOid;
|
||||
}
|
||||
@@ -945,8 +951,8 @@ array_recv(PG_FUNCTION_ARGS)
|
||||
if (!OidIsValid(my_extra->typiofunc))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_FUNCTION),
|
||||
errmsg("no binary input function available for type %s",
|
||||
format_type_be(element_type))));
|
||||
errmsg("no binary input function available for type %s",
|
||||
format_type_be(element_type))));
|
||||
fmgr_info_cxt(my_extra->typiofunc, &my_extra->proc,
|
||||
fcinfo->flinfo->fn_mcxt);
|
||||
my_extra->element_type = element_type;
|
||||
@@ -1004,9 +1010,9 @@ ReadArrayBinary(StringInfo buf,
|
||||
|
||||
for (i = 0; i < nitems; i++)
|
||||
{
|
||||
int itemlen;
|
||||
int itemlen;
|
||||
StringInfoData elem_buf;
|
||||
char csave;
|
||||
char csave;
|
||||
|
||||
/* Get and check the item length */
|
||||
itemlen = pq_getmsgint(buf, 4);
|
||||
@@ -1017,10 +1023,9 @@ ReadArrayBinary(StringInfo buf,
|
||||
|
||||
/*
|
||||
* Rather than copying data around, we just set up a phony
|
||||
* StringInfo pointing to the correct portion of the input
|
||||
* buffer. We assume we can scribble on the input buffer
|
||||
* so as to maintain the convention that StringInfos have
|
||||
* a trailing null.
|
||||
* StringInfo pointing to the correct portion of the input buffer.
|
||||
* We assume we can scribble on the input buffer so as to maintain
|
||||
* the convention that StringInfos have a trailing null.
|
||||
*/
|
||||
elem_buf.data = &buf->data[buf->cursor];
|
||||
elem_buf.maxlen = itemlen + 1;
|
||||
@@ -1042,7 +1047,7 @@ ReadArrayBinary(StringInfo buf,
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
||||
errmsg("improper binary format in array element %d",
|
||||
i + 1)));
|
||||
i + 1)));
|
||||
|
||||
buf->data[buf->cursor] = csave;
|
||||
}
|
||||
@@ -1051,9 +1056,7 @@ ReadArrayBinary(StringInfo buf,
|
||||
* Compute total data space needed
|
||||
*/
|
||||
if (typlen > 0)
|
||||
{
|
||||
*nbytes = nitems * att_align(typlen, typalign);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert(!typbyval);
|
||||
@@ -1100,14 +1103,14 @@ array_send(PG_FUNCTION_ARGS)
|
||||
|
||||
/*
|
||||
* We arrange to look up info about element type, including its send
|
||||
* conversion proc, only once per series of calls, assuming the element
|
||||
* type doesn't change underneath us.
|
||||
* conversion proc, only once per series of calls, assuming the
|
||||
* element type doesn't change underneath us.
|
||||
*/
|
||||
my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
|
||||
if (my_extra == NULL)
|
||||
{
|
||||
fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
|
||||
sizeof(ArrayMetaState));
|
||||
sizeof(ArrayMetaState));
|
||||
my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
|
||||
my_extra->element_type = InvalidOid;
|
||||
}
|
||||
@@ -1122,8 +1125,8 @@ array_send(PG_FUNCTION_ARGS)
|
||||
if (!OidIsValid(my_extra->typiofunc))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_FUNCTION),
|
||||
errmsg("no binary output function available for type %s",
|
||||
format_type_be(element_type))));
|
||||
errmsg("no binary output function available for type %s",
|
||||
format_type_be(element_type))));
|
||||
fmgr_info_cxt(my_extra->typiofunc, &my_extra->proc,
|
||||
fcinfo->flinfo->fn_mcxt);
|
||||
my_extra->element_type = element_type;
|
||||
@@ -1160,7 +1163,7 @@ array_send(PG_FUNCTION_ARGS)
|
||||
|
||||
outputbytes = DatumGetByteaP(FunctionCall2(&my_extra->proc,
|
||||
itemvalue,
|
||||
ObjectIdGetDatum(typelem)));
|
||||
ObjectIdGetDatum(typelem)));
|
||||
/* We assume the result will not have been toasted */
|
||||
pq_sendint(&buf, VARSIZE(outputbytes) - VARHDRSZ, 4);
|
||||
pq_sendbytes(&buf, VARDATA(outputbytes),
|
||||
@@ -1187,10 +1190,11 @@ array_length_coerce(PG_FUNCTION_ARGS)
|
||||
int32 len = PG_GETARG_INT32(1);
|
||||
bool isExplicit = PG_GETARG_BOOL(2);
|
||||
FmgrInfo *fmgr_info = fcinfo->flinfo;
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
Oid elemtype;
|
||||
FmgrInfo coerce_finfo;
|
||||
} alc_extra;
|
||||
} alc_extra;
|
||||
alc_extra *my_extra;
|
||||
FunctionCallInfoData locfcinfo;
|
||||
|
||||
@@ -1471,7 +1475,7 @@ array_get_slice(ArrayType *array,
|
||||
*/
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("slices of fixed-length arrays not implemented")));
|
||||
errmsg("slices of fixed-length arrays not implemented")));
|
||||
|
||||
/*
|
||||
* fixed-length arrays -- these are assumed to be 1-d, 0-based XXX
|
||||
@@ -1634,12 +1638,12 @@ array_set(ArrayType *array,
|
||||
|
||||
/*
|
||||
* if number of dims is zero, i.e. an empty array, create an array
|
||||
* with nSubscripts dimensions, and set the lower bounds to the supplied
|
||||
* subscripts
|
||||
* with nSubscripts dimensions, and set the lower bounds to the
|
||||
* supplied subscripts
|
||||
*/
|
||||
if (ndim == 0)
|
||||
{
|
||||
Oid elmtype = ARR_ELEMTYPE(array);
|
||||
Oid elmtype = ARR_ELEMTYPE(array);
|
||||
|
||||
for (i = 0; i < nSubscripts; i++)
|
||||
{
|
||||
@@ -1648,7 +1652,7 @@ array_set(ArrayType *array,
|
||||
}
|
||||
|
||||
return construct_md_array(&dataValue, nSubscripts, dim, lb, elmtype,
|
||||
elmlen, elmbyval, elmalign);
|
||||
elmlen, elmbyval, elmalign);
|
||||
}
|
||||
|
||||
if (ndim != nSubscripts || ndim <= 0 || ndim > MAXDIM)
|
||||
@@ -1818,17 +1822,17 @@ array_set_slice(ArrayType *array,
|
||||
|
||||
/*
|
||||
* if number of dims is zero, i.e. an empty array, create an array
|
||||
* with nSubscripts dimensions, and set the upper and lower bounds
|
||||
* to the supplied subscripts
|
||||
* with nSubscripts dimensions, and set the upper and lower bounds to
|
||||
* the supplied subscripts
|
||||
*/
|
||||
if (ndim == 0)
|
||||
{
|
||||
Datum *dvalues;
|
||||
int nelems;
|
||||
Oid elmtype = ARR_ELEMTYPE(array);
|
||||
Datum *dvalues;
|
||||
int nelems;
|
||||
Oid elmtype = ARR_ELEMTYPE(array);
|
||||
|
||||
deconstruct_array(srcArray, elmtype, elmlen, elmbyval, elmalign,
|
||||
&dvalues, &nelems);
|
||||
&dvalues, &nelems);
|
||||
|
||||
for (i = 0; i < nSubscripts; i++)
|
||||
{
|
||||
@@ -1837,7 +1841,7 @@ array_set_slice(ArrayType *array,
|
||||
}
|
||||
|
||||
return construct_md_array(dvalues, nSubscripts, dim, lb, elmtype,
|
||||
elmlen, elmbyval, elmalign);
|
||||
elmlen, elmbyval, elmalign);
|
||||
}
|
||||
|
||||
if (ndim < nSubscripts || ndim <= 0 || ndim > MAXDIM)
|
||||
@@ -2028,11 +2032,12 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
|
||||
bool typbyval;
|
||||
char typalign;
|
||||
char *s;
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
ArrayMetaState inp_extra;
|
||||
ArrayMetaState ret_extra;
|
||||
} am_extra;
|
||||
am_extra *my_extra;
|
||||
} am_extra;
|
||||
am_extra *my_extra;
|
||||
ArrayMetaState *inp_extra;
|
||||
ArrayMetaState *ret_extra;
|
||||
|
||||
@@ -2054,9 +2059,9 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
|
||||
PG_RETURN_ARRAYTYPE_P(v);
|
||||
|
||||
/*
|
||||
* We arrange to look up info about input and return element types only
|
||||
* once per series of calls, assuming the element type doesn't change
|
||||
* underneath us.
|
||||
* We arrange to look up info about input and return element types
|
||||
* only once per series of calls, assuming the element type doesn't
|
||||
* change underneath us.
|
||||
*/
|
||||
my_extra = (am_extra *) fcinfo->flinfo->fn_extra;
|
||||
if (my_extra == NULL)
|
||||
@@ -2179,8 +2184,8 @@ construct_array(Datum *elems, int nelems,
|
||||
Oid elmtype,
|
||||
int elmlen, bool elmbyval, char elmalign)
|
||||
{
|
||||
int dims[1];
|
||||
int lbs[1];
|
||||
int dims[1];
|
||||
int lbs[1];
|
||||
|
||||
dims[0] = nelems;
|
||||
lbs[0] = 1;
|
||||
@@ -2364,7 +2369,7 @@ array_eq(PG_FUNCTION_ARGS)
|
||||
if (element_type != ARR_ELEMTYPE(array2))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
errmsg("cannot compare arrays of different element types")));
|
||||
errmsg("cannot compare arrays of different element types")));
|
||||
|
||||
/* fast path if the arrays do not have the same number of elements */
|
||||
if (nitems1 != nitems2)
|
||||
@@ -2372,21 +2377,22 @@ array_eq(PG_FUNCTION_ARGS)
|
||||
else
|
||||
{
|
||||
/*
|
||||
* We arrange to look up the equality function only once per series of
|
||||
* calls, assuming the element type doesn't change underneath us.
|
||||
* We arrange to look up the equality function only once per
|
||||
* series of calls, assuming the element type doesn't change
|
||||
* underneath us.
|
||||
*/
|
||||
my_extra = (ArrayMetaState *) ae_fmgr_info->fn_extra;
|
||||
if (my_extra == NULL)
|
||||
{
|
||||
ae_fmgr_info->fn_extra = MemoryContextAlloc(ae_fmgr_info->fn_mcxt,
|
||||
sizeof(ArrayMetaState));
|
||||
sizeof(ArrayMetaState));
|
||||
my_extra = (ArrayMetaState *) ae_fmgr_info->fn_extra;
|
||||
my_extra->element_type = InvalidOid;
|
||||
}
|
||||
|
||||
if (my_extra->element_type != element_type)
|
||||
{
|
||||
Oid opfuncid = equality_oper_funcid(element_type);
|
||||
Oid opfuncid = equality_oper_funcid(element_type);
|
||||
|
||||
get_typlenbyvalalign(element_type,
|
||||
&my_extra->typlen,
|
||||
@@ -2410,9 +2416,9 @@ array_eq(PG_FUNCTION_ARGS)
|
||||
/* Loop over source data */
|
||||
for (i = 0; i < nitems1; i++)
|
||||
{
|
||||
Datum elt1;
|
||||
Datum elt2;
|
||||
bool oprresult;
|
||||
Datum elt1;
|
||||
Datum elt2;
|
||||
bool oprresult;
|
||||
|
||||
/* Get element pair */
|
||||
elt1 = fetch_att(p1, typbyval, typlen);
|
||||
@@ -2519,20 +2525,20 @@ array_cmp(FunctionCallInfo fcinfo)
|
||||
int i;
|
||||
typedef struct
|
||||
{
|
||||
Oid element_type;
|
||||
int16 typlen;
|
||||
bool typbyval;
|
||||
char typalign;
|
||||
FmgrInfo eqproc;
|
||||
FmgrInfo ordproc;
|
||||
} ac_extra;
|
||||
ac_extra *my_extra;
|
||||
Oid element_type;
|
||||
int16 typlen;
|
||||
bool typbyval;
|
||||
char typalign;
|
||||
FmgrInfo eqproc;
|
||||
FmgrInfo ordproc;
|
||||
} ac_extra;
|
||||
ac_extra *my_extra;
|
||||
|
||||
element_type = ARR_ELEMTYPE(array1);
|
||||
if (element_type != ARR_ELEMTYPE(array2))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
errmsg("cannot compare arrays of different element types")));
|
||||
errmsg("cannot compare arrays of different element types")));
|
||||
|
||||
/*
|
||||
* We arrange to look up the element type info and related functions
|
||||
@@ -2550,8 +2556,8 @@ array_cmp(FunctionCallInfo fcinfo)
|
||||
|
||||
if (my_extra->element_type != element_type)
|
||||
{
|
||||
Oid eqfuncid = equality_oper_funcid(element_type);
|
||||
Oid ordfuncid = ordering_oper_funcid(element_type);
|
||||
Oid eqfuncid = equality_oper_funcid(element_type);
|
||||
Oid ordfuncid = ordering_oper_funcid(element_type);
|
||||
|
||||
get_typlenbyvalalign(element_type,
|
||||
&my_extra->typlen,
|
||||
@@ -2569,10 +2575,10 @@ array_cmp(FunctionCallInfo fcinfo)
|
||||
|
||||
/* extract a C array of arg array datums */
|
||||
deconstruct_array(array1, element_type, typlen, typbyval, typalign,
|
||||
&dvalues1, &nelems1);
|
||||
&dvalues1, &nelems1);
|
||||
|
||||
deconstruct_array(array2, element_type, typlen, typbyval, typalign,
|
||||
&dvalues2, &nelems2);
|
||||
&dvalues2, &nelems2);
|
||||
|
||||
min_nelems = Min(nelems1, nelems2);
|
||||
for (i = 0; i < min_nelems; i++)
|
||||
@@ -2875,7 +2881,7 @@ array_insert_slice(int ndim,
|
||||
/*
|
||||
* array_type_coerce -- allow explicit or assignment coercion from
|
||||
* one array type to another.
|
||||
*
|
||||
*
|
||||
* Caller should have already verified that the source element type can be
|
||||
* coerced into the target element type.
|
||||
*/
|
||||
@@ -2885,11 +2891,12 @@ array_type_coerce(PG_FUNCTION_ARGS)
|
||||
ArrayType *src = PG_GETARG_ARRAYTYPE_P(0);
|
||||
Oid src_elem_type = ARR_ELEMTYPE(src);
|
||||
FmgrInfo *fmgr_info = fcinfo->flinfo;
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
Oid srctype;
|
||||
Oid desttype;
|
||||
FmgrInfo coerce_finfo;
|
||||
} atc_extra;
|
||||
} atc_extra;
|
||||
atc_extra *my_extra;
|
||||
FunctionCallInfoData locfcinfo;
|
||||
|
||||
@@ -2925,12 +2932,11 @@ array_type_coerce(PG_FUNCTION_ARGS)
|
||||
errmsg("target type is not an array")));
|
||||
|
||||
/*
|
||||
* We don't deal with domain constraints yet, so bail out.
|
||||
* This isn't currently a problem, because we also don't
|
||||
* support arrays of domain type elements either. But in the
|
||||
* future we might. At that point consideration should be given
|
||||
* to removing the check below and adding a domain constraints
|
||||
* check to the coercion.
|
||||
* We don't deal with domain constraints yet, so bail out. This
|
||||
* isn't currently a problem, because we also don't support arrays
|
||||
* of domain type elements either. But in the future we might. At
|
||||
* that point consideration should be given to removing the check
|
||||
* below and adding a domain constraints check to the coercion.
|
||||
*/
|
||||
if (getBaseType(tgt_elem_type) != tgt_elem_type)
|
||||
ereport(ERROR,
|
||||
@@ -2943,7 +2949,7 @@ array_type_coerce(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/* should never happen, but check anyway */
|
||||
elog(ERROR, "no conversion function from %s to %s",
|
||||
format_type_be(src_elem_type), format_type_be(tgt_elem_type));
|
||||
format_type_be(src_elem_type), format_type_be(tgt_elem_type));
|
||||
}
|
||||
if (OidIsValid(funcId))
|
||||
fmgr_info_cxt(funcId, &my_extra->coerce_finfo, fmgr_info->fn_mcxt);
|
||||
@@ -2954,13 +2960,13 @@ array_type_coerce(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
/*
|
||||
* If it's binary-compatible, modify the element type in the array header,
|
||||
* but otherwise leave the array as we received it.
|
||||
* If it's binary-compatible, modify the element type in the array
|
||||
* header, but otherwise leave the array as we received it.
|
||||
*/
|
||||
if (my_extra->coerce_finfo.fn_oid == InvalidOid)
|
||||
{
|
||||
ArrayType *result = DatumGetArrayTypePCopy(PG_GETARG_DATUM(0));
|
||||
|
||||
|
||||
ARR_ELEMTYPE(result) = my_extra->desttype;
|
||||
PG_RETURN_ARRAYTYPE_P(result);
|
||||
}
|
||||
@@ -2983,13 +2989,13 @@ array_type_coerce(PG_FUNCTION_ARGS)
|
||||
* rcontext is where to keep working state
|
||||
*/
|
||||
ArrayBuildState *
|
||||
accumArrayResult(ArrayBuildState *astate,
|
||||
accumArrayResult(ArrayBuildState * astate,
|
||||
Datum dvalue, bool disnull,
|
||||
Oid element_type,
|
||||
MemoryContext rcontext)
|
||||
{
|
||||
MemoryContext arr_context,
|
||||
oldcontext;
|
||||
oldcontext;
|
||||
|
||||
if (astate == NULL)
|
||||
{
|
||||
@@ -3021,7 +3027,7 @@ accumArrayResult(ArrayBuildState *astate,
|
||||
if ((astate->nelems % ARRAY_ELEMS_CHUNKSIZE) == 0)
|
||||
astate->dvalues = (Datum *)
|
||||
repalloc(astate->dvalues,
|
||||
(astate->nelems + ARRAY_ELEMS_CHUNKSIZE) * sizeof(Datum));
|
||||
(astate->nelems + ARRAY_ELEMS_CHUNKSIZE) * sizeof(Datum));
|
||||
}
|
||||
|
||||
if (disnull)
|
||||
@@ -3045,7 +3051,7 @@ accumArrayResult(ArrayBuildState *astate,
|
||||
* rcontext is where to construct result
|
||||
*/
|
||||
Datum
|
||||
makeArrayResult(ArrayBuildState *astate,
|
||||
makeArrayResult(ArrayBuildState * astate,
|
||||
MemoryContext rcontext)
|
||||
{
|
||||
int dims[1];
|
||||
@@ -3067,7 +3073,7 @@ makeArrayResult(ArrayBuildState *astate,
|
||||
* rcontext is where to construct result
|
||||
*/
|
||||
Datum
|
||||
makeMdArrayResult(ArrayBuildState *astate,
|
||||
makeMdArrayResult(ArrayBuildState * astate,
|
||||
int ndims,
|
||||
int *dims,
|
||||
int *lbs,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Portions Copyright (c) 1999-2002, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ascii.c,v 1.16 2003/07/27 04:53:03 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ascii.c,v 1.17 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "utils/ascii.h"
|
||||
|
||||
static void pg_to_ascii(unsigned char *src, unsigned char *src_end,
|
||||
unsigned char *dest, int enc);
|
||||
unsigned char *dest, int enc);
|
||||
static text *encode_to_ascii(text *data, int enc);
|
||||
|
||||
|
||||
@@ -65,8 +65,8 @@ pg_to_ascii(unsigned char *src, unsigned char *src_end, unsigned char *dest, int
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("unsupported encoding conversion from %s to ASCII",
|
||||
pg_encoding_to_char(enc))));
|
||||
errmsg("unsupported encoding conversion from %s to ASCII",
|
||||
pg_encoding_to_char(enc))));
|
||||
return; /* keep compiler quiet */
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ static text *
|
||||
encode_to_ascii(text *data, int enc)
|
||||
{
|
||||
pg_to_ascii((unsigned char *) VARDATA(data), /* src */
|
||||
(unsigned char *) (data) + VARSIZE(data), /* src end */
|
||||
(unsigned char *) (data) + VARSIZE(data), /* src end */
|
||||
(unsigned char *) VARDATA(data), /* dest */
|
||||
enc); /* encoding */
|
||||
|
||||
@@ -109,8 +109,8 @@ encode_to_ascii(text *data, int enc)
|
||||
Datum
|
||||
to_ascii_encname(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *data = PG_GETARG_TEXT_P_COPY(0);
|
||||
int enc = pg_char_to_encoding(NameStr(*PG_GETARG_NAME(1)));
|
||||
text *data = PG_GETARG_TEXT_P_COPY(0);
|
||||
int enc = pg_char_to_encoding(NameStr(*PG_GETARG_NAME(1)));
|
||||
|
||||
PG_RETURN_TEXT_P(encode_to_ascii(data, enc));
|
||||
}
|
||||
@@ -122,8 +122,8 @@ to_ascii_encname(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
to_ascii_enc(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *data = PG_GETARG_TEXT_P_COPY(0);
|
||||
int enc = PG_GETARG_INT32(1);
|
||||
text *data = PG_GETARG_TEXT_P_COPY(0);
|
||||
int enc = PG_GETARG_INT32(1);
|
||||
|
||||
PG_RETURN_TEXT_P(encode_to_ascii(data, enc));
|
||||
}
|
||||
@@ -135,8 +135,8 @@ to_ascii_enc(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
to_ascii_default(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *data = PG_GETARG_TEXT_P_COPY(0);
|
||||
int enc = GetDatabaseEncoding();
|
||||
text *data = PG_GETARG_TEXT_P_COPY(0);
|
||||
int enc = GetDatabaseEncoding();
|
||||
|
||||
PG_RETURN_TEXT_P(encode_to_ascii(data, enc));
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/char.c,v 1.36 2003/07/27 04:53:04 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/char.c,v 1.37 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -57,7 +57,7 @@ charout(PG_FUNCTION_ARGS)
|
||||
* charrecv - converts external binary format to char
|
||||
*
|
||||
* The external representation is one byte, with no character set
|
||||
* conversion. This is somewhat dubious, perhaps, but in many
|
||||
* conversion. This is somewhat dubious, perhaps, but in many
|
||||
* cases people use char for a 1-byte binary type.
|
||||
*/
|
||||
Datum
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.87 2003/07/27 04:53:04 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.88 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -97,7 +97,7 @@ date_in(PG_FUNCTION_ARGS)
|
||||
default:
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for date: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for date: \"%s\"", str)));
|
||||
}
|
||||
|
||||
date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
|
||||
@@ -465,7 +465,7 @@ abstime_date(PG_FUNCTION_ARGS)
|
||||
case NOEND_ABSTIME:
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("cannot convert reserved abstime value to date")));
|
||||
errmsg("cannot convert reserved abstime value to date")));
|
||||
|
||||
/*
|
||||
* pretend to drop through to make compiler think that result
|
||||
@@ -527,7 +527,7 @@ text_date(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for date: \"%s\"",
|
||||
VARDATA(str))));
|
||||
VARDATA(str))));
|
||||
|
||||
sp = VARDATA(str);
|
||||
dp = dstr;
|
||||
@@ -570,7 +570,7 @@ time_in(PG_FUNCTION_ARGS)
|
||||
errmsg("invalid input syntax for time: \"%s\"", str)));
|
||||
|
||||
if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
|
||||
|| (DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0))
|
||||
|| (DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for time: \"%s\"", str)));
|
||||
@@ -749,9 +749,9 @@ AdjustTimeForTypmod(TimeADT *time, int32 typmod)
|
||||
/*
|
||||
* Note: this round-to-nearest code is not completely consistent
|
||||
* about rounding values that are exactly halfway between integral
|
||||
* values. On most platforms, rint() will implement round-to-nearest-even,
|
||||
* but the integer code always rounds up (away from zero). Is it
|
||||
* worth trying to be consistent?
|
||||
* values. On most platforms, rint() will implement
|
||||
* round-to-nearest-even, but the integer code always rounds up
|
||||
* (away from zero). Is it worth trying to be consistent?
|
||||
*/
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
if (*time >= INT64CONST(0))
|
||||
@@ -761,8 +761,8 @@ AdjustTimeForTypmod(TimeADT *time, int32 typmod)
|
||||
}
|
||||
else
|
||||
{
|
||||
*time = - ((((- *time) + TimeOffsets[typmod]) / TimeScales[typmod])
|
||||
* TimeScales[typmod]);
|
||||
*time = -((((-*time) + TimeOffsets[typmod]) / TimeScales[typmod])
|
||||
* TimeScales[typmod]);
|
||||
}
|
||||
#else
|
||||
*time = (rint(((double) *time) * TimeScales[typmod])
|
||||
@@ -1093,7 +1093,7 @@ time_interval(PG_FUNCTION_ARGS)
|
||||
* Convert interval to time data type.
|
||||
*
|
||||
* This is defined as producing the fractional-day portion of the interval.
|
||||
* Therefore, we can just ignore the months field. It is not real clear
|
||||
* Therefore, we can just ignore the months field. It is not real clear
|
||||
* what to do with negative intervals, but we choose to subtract the floor,
|
||||
* so that, say, '-2 hours' becomes '22:00:00'.
|
||||
*/
|
||||
@@ -1114,7 +1114,7 @@ interval_time(PG_FUNCTION_ARGS)
|
||||
}
|
||||
else if (result < 0)
|
||||
{
|
||||
days = (-result + INT64CONST(86400000000-1)) / INT64CONST(86400000000);
|
||||
days = (-result + INT64CONST(86400000000 - 1)) / INT64CONST(86400000000);
|
||||
result += days * INT64CONST(86400000000);
|
||||
}
|
||||
#else
|
||||
@@ -1256,7 +1256,7 @@ text_time(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for time: \"%s\"",
|
||||
VARDATA(str))));
|
||||
VARDATA(str))));
|
||||
|
||||
sp = VARDATA(str);
|
||||
dp = dstr;
|
||||
@@ -1290,8 +1290,8 @@ time_part(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("TIME units \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
|
||||
up = VARDATA(units);
|
||||
lp = lowunits;
|
||||
@@ -1360,8 +1360,8 @@ time_part(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("TIME units \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
|
||||
result = 0;
|
||||
}
|
||||
@@ -1379,8 +1379,8 @@ time_part(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("TIME units \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
result = 0;
|
||||
}
|
||||
|
||||
@@ -1432,15 +1432,15 @@ timetz_in(PG_FUNCTION_ARGS)
|
||||
if (strlen(str) >= sizeof(lowstr))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for time with time zone: \"%s\"",
|
||||
str)));
|
||||
errmsg("invalid input syntax for time with time zone: \"%s\"",
|
||||
str)));
|
||||
|
||||
if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
|
||||
|| (DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for time with time zone: \"%s\"",
|
||||
str)));
|
||||
errmsg("invalid input syntax for time with time zone: \"%s\"",
|
||||
str)));
|
||||
|
||||
result = (TimeTzADT *) palloc(sizeof(TimeTzADT));
|
||||
tm2timetz(tm, fsec, tz, result);
|
||||
@@ -2019,8 +2019,8 @@ text_timetz(PG_FUNCTION_ARGS)
|
||||
if (VARSIZE(str) - VARHDRSZ > MAXDATELEN)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for time with time zone: \"%s\"",
|
||||
VARDATA(str))));
|
||||
errmsg("invalid input syntax for time with time zone: \"%s\"",
|
||||
VARDATA(str))));
|
||||
|
||||
sp = VARDATA(str);
|
||||
dp = dstr;
|
||||
@@ -2054,8 +2054,8 @@ timetz_part(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("TIMETZ units \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
|
||||
up = VARDATA(units);
|
||||
lp = lowunits;
|
||||
@@ -2138,8 +2138,8 @@ timetz_part(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("TIMETZ units \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
|
||||
result = 0;
|
||||
}
|
||||
@@ -2157,8 +2157,8 @@ timetz_part(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("TIMETZ units \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
|
||||
result = 0;
|
||||
}
|
||||
@@ -2187,8 +2187,8 @@ timetz_zone(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("time zone \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(zone))))));
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(zone))))));
|
||||
|
||||
up = VARDATA(zone);
|
||||
lp = lowzone;
|
||||
@@ -2246,8 +2246,8 @@ timetz_izone(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("INTERVAL time zone \"%s\" not legal",
|
||||
DatumGetCString(DirectFunctionCall1(interval_out,
|
||||
PointerGetDatum(zone))))));
|
||||
DatumGetCString(DirectFunctionCall1(interval_out,
|
||||
PointerGetDatum(zone))))));
|
||||
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
tz = -(zone->time / INT64CONST(1000000));
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.108 2003/07/29 00:03:18 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.109 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -575,9 +575,9 @@ static datetkn deltatktbl[] = {
|
||||
|
||||
static unsigned int szdeltatktbl = sizeof deltatktbl / sizeof deltatktbl[0];
|
||||
|
||||
static datetkn *datecache[MAXDATEFIELDS] = {NULL};
|
||||
static datetkn *datecache[MAXDATEFIELDS] = {NULL};
|
||||
|
||||
static datetkn *deltacache[MAXDATEFIELDS] = {NULL};
|
||||
static datetkn *deltacache[MAXDATEFIELDS] = {NULL};
|
||||
|
||||
|
||||
/*
|
||||
@@ -593,7 +593,7 @@ static datetkn *deltacache[MAXDATEFIELDS] = {NULL};
|
||||
*
|
||||
* Rewritten to eliminate overflow problems. This now allows the
|
||||
* routines to work correctly for all Julian day counts from
|
||||
* 0 to 2147483647 (Nov 24, -4713 to Jun 3, 5874898) assuming
|
||||
* 0 to 2147483647 (Nov 24, -4713 to Jun 3, 5874898) assuming
|
||||
* a 32-bit integer. Longer types should also work to the limits
|
||||
* of their precision.
|
||||
*/
|
||||
@@ -604,18 +604,21 @@ date2j(int y, int m, int d)
|
||||
int julian;
|
||||
int century;
|
||||
|
||||
if (m > 2) {
|
||||
if (m > 2)
|
||||
{
|
||||
m += 1;
|
||||
y += 4800;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
m += 13;
|
||||
y += 4799;
|
||||
}
|
||||
|
||||
century = y/100;
|
||||
julian = y*365 - 32167;
|
||||
julian += y/4 - century + century/4;
|
||||
julian += 7834*m/256 + d;
|
||||
century = y / 100;
|
||||
julian = y * 365 - 32167;
|
||||
julian += y / 4 - century + century / 4;
|
||||
julian += 7834 * m / 256 + d;
|
||||
|
||||
return julian;
|
||||
} /* date2j() */
|
||||
@@ -623,25 +626,25 @@ date2j(int y, int m, int d)
|
||||
void
|
||||
j2date(int jd, int *year, int *month, int *day)
|
||||
{
|
||||
unsigned int julian;
|
||||
unsigned int quad;
|
||||
unsigned int extra;
|
||||
unsigned int julian;
|
||||
unsigned int quad;
|
||||
unsigned int extra;
|
||||
int y;
|
||||
|
||||
julian = jd;
|
||||
julian += 32044;
|
||||
quad = julian/146097;
|
||||
extra = (julian - quad*146097)*4 + 3;
|
||||
julian += 60 + quad*3 + extra/146097;
|
||||
quad = julian/1461;
|
||||
julian -= quad*1461;
|
||||
quad = julian / 146097;
|
||||
extra = (julian - quad * 146097) * 4 + 3;
|
||||
julian += 60 + quad * 3 + extra / 146097;
|
||||
quad = julian / 1461;
|
||||
julian -= quad * 1461;
|
||||
y = julian * 4 / 1461;
|
||||
julian = ((y != 0) ? ((julian + 305) % 365) : ((julian + 306) % 366))
|
||||
+ 123;
|
||||
y += quad*4;
|
||||
y += quad * 4;
|
||||
*year = y - 4800;
|
||||
quad = julian * 2141 / 65536;
|
||||
*day = julian - 7834*quad/256;
|
||||
*day = julian - 7834 * quad / 256;
|
||||
*month = (quad + 10) % 12 + 1;
|
||||
|
||||
return;
|
||||
@@ -652,7 +655,7 @@ j2date(int jd, int *year, int *month, int *day)
|
||||
* j2day - convert Julian date to day-of-week (0..6 == Sun..Sat)
|
||||
*
|
||||
* Note: various places use the locution j2day(date - 1) to produce a
|
||||
* result according to the convention 0..6 = Mon..Sun. This is a bit of
|
||||
* result according to the convention 0..6 = Mon..Sun. This is a bit of
|
||||
* a crock, but will work as long as the computation here is just a modulo.
|
||||
*/
|
||||
int
|
||||
@@ -1252,8 +1255,8 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
{
|
||||
case DTK_CURRENT:
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("\"current\" is no longer supported")));
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("\"current\" is no longer supported")));
|
||||
|
||||
return -1;
|
||||
break;
|
||||
@@ -1269,7 +1272,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
*dtype = DTK_DATE;
|
||||
GetCurrentDateTime(tm);
|
||||
j2date((date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - 1),
|
||||
&tm->tm_year, &tm->tm_mon, &tm->tm_mday);
|
||||
&tm->tm_year, &tm->tm_mon, &tm->tm_mday);
|
||||
tm->tm_hour = 0;
|
||||
tm->tm_min = 0;
|
||||
tm->tm_sec = 0;
|
||||
@@ -1289,7 +1292,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
*dtype = DTK_DATE;
|
||||
GetCurrentDateTime(tm);
|
||||
j2date((date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + 1),
|
||||
&tm->tm_year, &tm->tm_mon, &tm->tm_mday);
|
||||
&tm->tm_year, &tm->tm_mon, &tm->tm_mday);
|
||||
tm->tm_hour = 0;
|
||||
tm->tm_min = 0;
|
||||
tm->tm_sec = 0;
|
||||
@@ -1435,8 +1438,8 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("inconsistent use of year %04d and \"BC\"",
|
||||
tm->tm_year)));
|
||||
errmsg("inconsistent use of year %04d and \"BC\"",
|
||||
tm->tm_year)));
|
||||
}
|
||||
else if (is2digits)
|
||||
{
|
||||
@@ -1994,8 +1997,8 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
|
||||
{
|
||||
case DTK_CURRENT:
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("\"current\" is no longer supported")));
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("\"current\" is no longer supported")));
|
||||
return -1;
|
||||
break;
|
||||
|
||||
@@ -2423,6 +2426,7 @@ DecodeNumber(int flen, char *str, int fmask,
|
||||
switch (fmask & DTK_DATE_M)
|
||||
{
|
||||
case 0:
|
||||
|
||||
/*
|
||||
* Nothing so far; make a decision about what we think the
|
||||
* input is. There used to be lots of heuristics here, but
|
||||
@@ -2487,9 +2491,7 @@ DecodeNumber(int flen, char *str, int fmask,
|
||||
* exactly two digits.
|
||||
*/
|
||||
if (*tmask == DTK_M(YEAR))
|
||||
{
|
||||
*is2digits = (flen == 2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -3300,8 +3302,8 @@ EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, cha
|
||||
tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min);
|
||||
|
||||
/*
|
||||
* Print fractional seconds if any. The field widths here should
|
||||
* be at least equal to MAX_TIMESTAMP_PRECISION.
|
||||
* Print fractional seconds if any. The field widths here
|
||||
* should be at least equal to MAX_TIMESTAMP_PRECISION.
|
||||
*
|
||||
* In float mode, don't print fractional seconds before 1 AD,
|
||||
* since it's unlikely there's any precision left ...
|
||||
@@ -3350,8 +3352,8 @@ EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, cha
|
||||
tm->tm_hour, tm->tm_min);
|
||||
|
||||
/*
|
||||
* Print fractional seconds if any. The field widths here should
|
||||
* be at least equal to MAX_TIMESTAMP_PRECISION.
|
||||
* Print fractional seconds if any. The field widths here
|
||||
* should be at least equal to MAX_TIMESTAMP_PRECISION.
|
||||
*
|
||||
* In float mode, don't print fractional seconds before 1 AD,
|
||||
* since it's unlikely there's any precision left ...
|
||||
@@ -3396,8 +3398,8 @@ EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, cha
|
||||
tm->tm_hour, tm->tm_min);
|
||||
|
||||
/*
|
||||
* Print fractional seconds if any. The field widths here should
|
||||
* be at least equal to MAX_TIMESTAMP_PRECISION.
|
||||
* Print fractional seconds if any. The field widths here
|
||||
* should be at least equal to MAX_TIMESTAMP_PRECISION.
|
||||
*
|
||||
* In float mode, don't print fractional seconds before 1 AD,
|
||||
* since it's unlikely there's any precision left ...
|
||||
@@ -3450,8 +3452,8 @@ EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, cha
|
||||
sprintf((str + 10), " %02d:%02d", tm->tm_hour, tm->tm_min);
|
||||
|
||||
/*
|
||||
* Print fractional seconds if any. The field widths here should
|
||||
* be at least equal to MAX_TIMESTAMP_PRECISION.
|
||||
* Print fractional seconds if any. The field widths here
|
||||
* should be at least equal to MAX_TIMESTAMP_PRECISION.
|
||||
*
|
||||
* In float mode, don't print fractional seconds before 1 AD,
|
||||
* since it's unlikely there's any precision left ...
|
||||
@@ -3746,7 +3748,7 @@ ClearDateCache(bool newval, bool doit, bool interactive)
|
||||
|
||||
/*
|
||||
* We've been burnt by stupid errors in the ordering of the datetkn tables
|
||||
* once too often. Arrange to check them during postmaster start.
|
||||
* once too often. Arrange to check them during postmaster start.
|
||||
*/
|
||||
static bool
|
||||
CheckDateTokenTable(const char *tablename, datetkn *base, unsigned int nel)
|
||||
@@ -3756,11 +3758,11 @@ CheckDateTokenTable(const char *tablename, datetkn *base, unsigned int nel)
|
||||
|
||||
for (i = 1; i < nel; i++)
|
||||
{
|
||||
if (strncmp(base[i-1].token, base[i].token, TOKMAXLEN) >= 0)
|
||||
if (strncmp(base[i - 1].token, base[i].token, TOKMAXLEN) >= 0)
|
||||
{
|
||||
elog(LOG, "ordering error in %s table: \"%.*s\" >= \"%.*s\"",
|
||||
tablename,
|
||||
TOKMAXLEN, base[i-1].token,
|
||||
TOKMAXLEN, base[i - 1].token,
|
||||
TOKMAXLEN, base[i].token);
|
||||
ok = false;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.91 2003/07/30 19:48:38 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.92 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -104,13 +104,13 @@ static double cbrt(double x);
|
||||
|
||||
|
||||
/* Configurable GUC parameter */
|
||||
int extra_float_digits = 0; /* Added to DBL_DIG or FLT_DIG */
|
||||
int extra_float_digits = 0; /* Added to DBL_DIG or FLT_DIG */
|
||||
|
||||
|
||||
static void CheckFloat4Val(double val);
|
||||
static void CheckFloat8Val(double val);
|
||||
static int float4_cmp_internal(float4 a, float4 b);
|
||||
static int float8_cmp_internal(float8 a, float8 b);
|
||||
static int float4_cmp_internal(float4 a, float4 b);
|
||||
static int float8_cmp_internal(float8 a, float8 b);
|
||||
|
||||
|
||||
/*
|
||||
@@ -198,7 +198,7 @@ float4in(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for float4: \"%s\"",
|
||||
num)));
|
||||
num)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
* formatting.c
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.64 2003/07/27 04:53:05 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.65 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1999-2002, PostgreSQL Global Development Group
|
||||
@@ -279,15 +279,15 @@ typedef struct
|
||||
#define NUM_F_DECIMAL (1 << 1)
|
||||
#define NUM_F_LDECIMAL (1 << 2)
|
||||
#define NUM_F_ZERO (1 << 3)
|
||||
#define NUM_F_BLANK (1 << 4)
|
||||
#define NUM_F_BLANK (1 << 4)
|
||||
#define NUM_F_FILLMODE (1 << 5)
|
||||
#define NUM_F_LSIGN (1 << 6)
|
||||
#define NUM_F_LSIGN (1 << 6)
|
||||
#define NUM_F_BRACKET (1 << 7)
|
||||
#define NUM_F_MINUS (1 << 8)
|
||||
#define NUM_F_MINUS (1 << 8)
|
||||
#define NUM_F_PLUS (1 << 9)
|
||||
#define NUM_F_ROMAN (1 << 10)
|
||||
#define NUM_F_ROMAN (1 << 10)
|
||||
#define NUM_F_MULTI (1 << 11)
|
||||
#define NUM_F_PLUS_POST (1 << 12)
|
||||
#define NUM_F_PLUS_POST (1 << 12)
|
||||
#define NUM_F_MINUS_POST (1 << 13)
|
||||
|
||||
#define NUM_LSIGN_PRE -1
|
||||
@@ -1018,7 +1018,7 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n)
|
||||
NUM_cache_remove(last_NUMCacheEntry);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||
errmsg("cannot use \"V\" and decimal point together")));
|
||||
errmsg("cannot use \"V\" and decimal point together")));
|
||||
}
|
||||
num->flag |= NUM_F_DECIMAL;
|
||||
break;
|
||||
@@ -1123,7 +1123,7 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n)
|
||||
NUM_cache_remove(last_NUMCacheEntry);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||
errmsg("cannot use \"V\" and decimal point together")));
|
||||
errmsg("cannot use \"V\" and decimal point together")));
|
||||
}
|
||||
num->flag |= NUM_F_MULTI;
|
||||
break;
|
||||
@@ -3072,7 +3072,7 @@ to_timestamp(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("inconsistent use of year %04d and \"BC\"",
|
||||
tm.tm_year)));
|
||||
tm.tm_year)));
|
||||
}
|
||||
|
||||
if (tmfc.j)
|
||||
@@ -3106,7 +3106,7 @@ to_timestamp(PG_FUNCTION_ARGS)
|
||||
if (!tm.tm_year)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("cannot convert yday without year information")));
|
||||
errmsg("cannot convert yday without year information")));
|
||||
|
||||
y = ysum[isleap(tm.tm_year)];
|
||||
|
||||
@@ -3600,7 +3600,7 @@ NUM_numpart_from_char(NUMProc *Np, int id, int plen)
|
||||
* simple + - < >
|
||||
*/
|
||||
if (*Np->inout_p == '-' || (IS_BRACKET(Np->Num) &&
|
||||
*Np->inout_p == '<'))
|
||||
*Np->inout_p == '<'))
|
||||
{
|
||||
|
||||
*Np->number = '-'; /* set - */
|
||||
@@ -3678,7 +3678,7 @@ NUM_numpart_from_char(NUMProc *Np, int id, int plen)
|
||||
(IS_ZERO((_n)->Num)==FALSE && \
|
||||
(_n)->number == (_n)->number_p && \
|
||||
*(_n)->number == '0' && \
|
||||
(_n)->Num->post != 0)
|
||||
(_n)->Num->post != 0)
|
||||
|
||||
/* ----------
|
||||
* Add digit or sign to number-string
|
||||
@@ -3687,8 +3687,8 @@ NUM_numpart_from_char(NUMProc *Np, int id, int plen)
|
||||
static void
|
||||
NUM_numpart_to_char(NUMProc *Np, int id)
|
||||
{
|
||||
int end;
|
||||
|
||||
int end;
|
||||
|
||||
if (IS_ROMAN(Np->Num))
|
||||
return;
|
||||
|
||||
@@ -3710,13 +3710,13 @@ NUM_numpart_to_char(NUMProc *Np, int id)
|
||||
Np->num_in = FALSE;
|
||||
|
||||
/*
|
||||
* Write sign if real number will write to output
|
||||
* Note: IS_PREDEC_SPACE() handle "9.9" --> " .1"
|
||||
* Write sign if real number will write to output Note:
|
||||
* IS_PREDEC_SPACE() handle "9.9" --> " .1"
|
||||
*/
|
||||
if (Np->sign_wrote == FALSE &&
|
||||
(Np->num_curr >= Np->num_pre || (IS_ZERO(Np->Num) && Np->Num->zero_start == Np->num_curr )) &&
|
||||
(IS_PREDEC_SPACE(Np)==FALSE || (Np->last_relevant && *Np->last_relevant == '.')))
|
||||
{
|
||||
if (Np->sign_wrote == FALSE &&
|
||||
(Np->num_curr >= Np->num_pre || (IS_ZERO(Np->Num) && Np->Num->zero_start == Np->num_curr)) &&
|
||||
(IS_PREDEC_SPACE(Np) == FALSE || (Np->last_relevant && *Np->last_relevant == '.')))
|
||||
{
|
||||
if (IS_LSIGN(Np->Num))
|
||||
{
|
||||
if (Np->Num->lsign == NUM_LSIGN_PRE)
|
||||
@@ -3739,7 +3739,7 @@ NUM_numpart_to_char(NUMProc *Np, int id)
|
||||
{
|
||||
if (!IS_FILLMODE(Np->Num))
|
||||
{
|
||||
*Np->inout_p = ' '; /* Write + */
|
||||
*Np->inout_p = ' '; /* Write + */
|
||||
++Np->inout_p;
|
||||
}
|
||||
Np->sign_wrote = TRUE;
|
||||
@@ -3751,8 +3751,8 @@ NUM_numpart_to_char(NUMProc *Np, int id)
|
||||
Np->sign_wrote = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* digits / FM / Zero / Dec. point
|
||||
*/
|
||||
@@ -3796,10 +3796,11 @@ NUM_numpart_to_char(NUMProc *Np, int id)
|
||||
strcpy(Np->inout_p, Np->decimal); /* Write DEC/D */
|
||||
Np->inout_p += strlen(Np->inout_p);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ora 'n' -- FM9.9 --> 'n.'
|
||||
*/
|
||||
else if (IS_FILLMODE(Np->Num) &&
|
||||
else if (IS_FILLMODE(Np->Num) &&
|
||||
Np->last_relevant && *Np->last_relevant == '.')
|
||||
{
|
||||
|
||||
@@ -3816,6 +3817,7 @@ NUM_numpart_to_char(NUMProc *Np, int id)
|
||||
if (Np->last_relevant && Np->number_p > Np->last_relevant &&
|
||||
id != NUM_0)
|
||||
;
|
||||
|
||||
/*
|
||||
* '0.1' -- 9.9 --> ' .1'
|
||||
*/
|
||||
@@ -3826,6 +3828,7 @@ NUM_numpart_to_char(NUMProc *Np, int id)
|
||||
*Np->inout_p = ' ';
|
||||
++Np->inout_p;
|
||||
}
|
||||
|
||||
/*
|
||||
* '0' -- FM9.9 --> '0.'
|
||||
*/
|
||||
@@ -3846,11 +3849,11 @@ NUM_numpart_to_char(NUMProc *Np, int id)
|
||||
}
|
||||
|
||||
end = Np->num_count + (Np->num_pre ? 1 : 0) + (IS_DECIMAL(Np->Num) ? 1 : 0);
|
||||
|
||||
|
||||
if (Np->last_relevant && Np->last_relevant == Np->number_p)
|
||||
end = Np->num_curr;
|
||||
|
||||
if (Np->num_curr+1 == end)
|
||||
|
||||
if (Np->num_curr + 1 == end)
|
||||
{
|
||||
if (Np->sign_wrote == TRUE && IS_BRACKET(Np->Num))
|
||||
{
|
||||
@@ -3895,7 +3898,7 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
|
||||
|
||||
if (Np->Num->zero_start)
|
||||
--Np->Num->zero_start;
|
||||
|
||||
|
||||
/*
|
||||
* Roman correction
|
||||
*/
|
||||
@@ -3923,20 +3926,18 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
|
||||
* Sign
|
||||
*/
|
||||
if (type == FROM_CHAR)
|
||||
{
|
||||
Np->sign = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Np->sign = sign;
|
||||
|
||||
|
||||
/* MI/PL/SG - write sign itself and not in number */
|
||||
if (IS_PLUS(Np->Num) || IS_MINUS(Np->Num))
|
||||
{
|
||||
if (IS_PLUS(Np->Num) && IS_MINUS(Np->Num)==FALSE)
|
||||
Np->sign_wrote = FALSE; /* need sign */
|
||||
if (IS_PLUS(Np->Num) && IS_MINUS(Np->Num) == FALSE)
|
||||
Np->sign_wrote = FALSE; /* need sign */
|
||||
else
|
||||
Np->sign_wrote = TRUE; /* needn't sign */
|
||||
Np->sign_wrote = TRUE; /* needn't sign */
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3950,10 +3951,10 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
|
||||
else if (Np->sign != '+' && IS_PLUS(Np->Num))
|
||||
Np->Num->flag &= ~NUM_F_PLUS;
|
||||
|
||||
if (Np->sign == '+' && IS_FILLMODE(Np->Num) && IS_LSIGN(Np->Num)==FALSE)
|
||||
Np->sign_wrote = TRUE; /* needn't sign */
|
||||
if (Np->sign == '+' && IS_FILLMODE(Np->Num) && IS_LSIGN(Np->Num) == FALSE)
|
||||
Np->sign_wrote = TRUE; /* needn't sign */
|
||||
else
|
||||
Np->sign_wrote = FALSE; /* need sign */
|
||||
Np->sign_wrote = FALSE; /* need sign */
|
||||
|
||||
if (Np->Num->lsign == NUM_LSIGN_PRE && Np->Num->pre == Np->Num->pre_lsign_num)
|
||||
Np->Num->lsign = NUM_LSIGN_POST;
|
||||
@@ -3973,12 +3974,12 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
|
||||
{
|
||||
if (IS_DECIMAL(Np->Num))
|
||||
Np->last_relevant = get_last_relevant_decnum(
|
||||
Np->number +
|
||||
Np->number +
|
||||
((Np->Num->zero_end - Np->num_pre > 0) ?
|
||||
Np->Num->zero_end - Np->num_pre : 0));
|
||||
}
|
||||
|
||||
if (Np->sign_wrote==FALSE && Np->num_pre == 0)
|
||||
if (Np->sign_wrote == FALSE && Np->num_pre == 0)
|
||||
++Np->num_count;
|
||||
}
|
||||
else
|
||||
@@ -4010,7 +4011,7 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
|
||||
IS_MINUS(Np->Num) ? "Yes" : "No",
|
||||
IS_FILLMODE(Np->Num) ? "Yes" : "No",
|
||||
IS_ROMAN(Np->Num) ? "Yes" : "No"
|
||||
);
|
||||
);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.78 2003/07/27 04:53:05 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.79 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -140,7 +140,7 @@ single_decode(char *str, float8 *x, char **s)
|
||||
static int
|
||||
single_encode(float8 x, char *str)
|
||||
{
|
||||
int ndig = DBL_DIG + extra_float_digits;
|
||||
int ndig = DBL_DIG + extra_float_digits;
|
||||
|
||||
if (ndig < 1)
|
||||
ndig = 1;
|
||||
@@ -196,7 +196,7 @@ pair_decode(char *str, float8 *x, float8 *y, char **s)
|
||||
static int
|
||||
pair_encode(float8 x, float8 y, char *str)
|
||||
{
|
||||
int ndig = DBL_DIG + extra_float_digits;
|
||||
int ndig = DBL_DIG + extra_float_digits;
|
||||
|
||||
if (ndig < 1)
|
||||
ndig = 1;
|
||||
@@ -3363,7 +3363,7 @@ poly_in(PG_FUNCTION_ARGS)
|
||||
if ((npts = pair_count(str, ',')) <= 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for polygon: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for polygon: \"%s\"", str)));
|
||||
|
||||
size = offsetof(POLYGON, p[0]) +sizeof(poly->p[0]) * npts;
|
||||
poly = (POLYGON *) palloc0(size); /* zero any holes */
|
||||
@@ -3375,7 +3375,7 @@ poly_in(PG_FUNCTION_ARGS)
|
||||
|| (*s != '\0'))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for polygon: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for polygon: \"%s\"", str)));
|
||||
|
||||
make_bound_box(poly);
|
||||
|
||||
@@ -3406,7 +3406,7 @@ Datum
|
||||
poly_recv(PG_FUNCTION_ARGS)
|
||||
{
|
||||
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
|
||||
POLYGON *poly;
|
||||
POLYGON *poly;
|
||||
int32 npts;
|
||||
int32 i;
|
||||
int size;
|
||||
@@ -3440,7 +3440,7 @@ poly_recv(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
poly_send(PG_FUNCTION_ARGS)
|
||||
{
|
||||
POLYGON *poly = PG_GETARG_POLYGON_P(0);
|
||||
POLYGON *poly = PG_GETARG_POLYGON_P(0);
|
||||
StringInfoData buf;
|
||||
int32 i;
|
||||
|
||||
@@ -4246,7 +4246,7 @@ circle_in(PG_FUNCTION_ARGS)
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for circle: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for circle: \"%s\"", str)));
|
||||
}
|
||||
|
||||
if (*s != '\0')
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.15 2003/06/25 01:08:13 momjian Exp $";
|
||||
static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.16 2003/08/04 00:43:25 momjian Exp $";
|
||||
#endif
|
||||
|
||||
#include "postgres.h"
|
||||
@@ -40,13 +40,13 @@ static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.15 2003/06/25 01:08:13 mom
|
||||
#endif
|
||||
|
||||
static char *inet_net_ntop_ipv4(const u_char *src, int bits,
|
||||
char *dst, size_t size);
|
||||
char *dst, size_t size);
|
||||
static char *inet_cidr_ntop_ipv4(const u_char *src, int bits,
|
||||
char *dst, size_t size);
|
||||
char *dst, size_t size);
|
||||
static char *inet_net_ntop_ipv6(const u_char *src, int bits,
|
||||
char *dst, size_t size);
|
||||
char *dst, size_t size);
|
||||
static char *inet_cidr_ntop_ipv6(const u_char *src, int bits,
|
||||
char *dst, size_t size);
|
||||
char *dst, size_t size);
|
||||
|
||||
/*
|
||||
* char *
|
||||
@@ -160,26 +160,30 @@ emsgsize:
|
||||
* 0x11110000 in its fourth octet.
|
||||
* author:
|
||||
* Vadim Kogan (UCB), June 2001
|
||||
* Original version (IPv4) by Paul Vixie (ISC), July 1996
|
||||
* Original version (IPv4) by Paul Vixie (ISC), July 1996
|
||||
*/
|
||||
|
||||
static char *
|
||||
inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
|
||||
{
|
||||
u_int m;
|
||||
int b;
|
||||
int p;
|
||||
int zero_s, zero_l, tmp_zero_s, tmp_zero_l;
|
||||
int i;
|
||||
int is_ipv4 = 0;
|
||||
int double_colon = 0;
|
||||
u_int m;
|
||||
int b;
|
||||
int p;
|
||||
int zero_s,
|
||||
zero_l,
|
||||
tmp_zero_s,
|
||||
tmp_zero_l;
|
||||
int i;
|
||||
int is_ipv4 = 0;
|
||||
int double_colon = 0;
|
||||
unsigned char inbuf[16];
|
||||
char outbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
|
||||
char *cp;
|
||||
int words;
|
||||
u_char *s;
|
||||
char outbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
|
||||
char *cp;
|
||||
int words;
|
||||
u_char *s;
|
||||
|
||||
if (bits < 0 || bits > 128) {
|
||||
if (bits < 0 || bits > 128)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
@@ -187,20 +191,24 @@ inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
|
||||
cp = outbuf;
|
||||
double_colon = 0;
|
||||
|
||||
if (bits == 0) {
|
||||
if (bits == 0)
|
||||
{
|
||||
*cp++ = ':';
|
||||
*cp++ = ':';
|
||||
*cp = '\0';
|
||||
double_colon = 1;
|
||||
} else {
|
||||
/* Copy src to private buffer. Zero host part. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy src to private buffer. Zero host part. */
|
||||
p = (bits + 7) / 8;
|
||||
memcpy(inbuf, src, p);
|
||||
memset(inbuf + p, 0, 16 - p);
|
||||
b = bits % 8;
|
||||
if (b != 0) {
|
||||
if (b != 0)
|
||||
{
|
||||
m = ~0 << (8 - b);
|
||||
inbuf[p-1] &= m;
|
||||
inbuf[p - 1] &= m;
|
||||
}
|
||||
|
||||
s = inbuf;
|
||||
@@ -212,13 +220,18 @@ inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
|
||||
|
||||
/* Find the longest substring of zero's */
|
||||
zero_s = zero_l = tmp_zero_s = tmp_zero_l = 0;
|
||||
for (i = 0; i < (words * 2); i += 2) {
|
||||
if ((s[i] | s[i+1]) == 0) {
|
||||
for (i = 0; i < (words * 2); i += 2)
|
||||
{
|
||||
if ((s[i] | s[i + 1]) == 0)
|
||||
{
|
||||
if (tmp_zero_l == 0)
|
||||
tmp_zero_s = i / 2;
|
||||
tmp_zero_l++;
|
||||
} else {
|
||||
if (tmp_zero_l && zero_l < tmp_zero_l) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tmp_zero_l && zero_l < tmp_zero_l)
|
||||
{
|
||||
zero_s = tmp_zero_s;
|
||||
zero_l = tmp_zero_l;
|
||||
tmp_zero_l = 0;
|
||||
@@ -226,23 +239,27 @@ inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
|
||||
}
|
||||
}
|
||||
|
||||
if (tmp_zero_l && zero_l < tmp_zero_l) {
|
||||
if (tmp_zero_l && zero_l < tmp_zero_l)
|
||||
{
|
||||
zero_s = tmp_zero_s;
|
||||
zero_l = tmp_zero_l;
|
||||
}
|
||||
|
||||
if (zero_l != words && zero_s == 0 && ((zero_l == 6) ||
|
||||
((zero_l == 5 && s[10] == 0xff && s[11] == 0xff) ||
|
||||
((zero_l == 7 && s[14] != 0 && s[15] != 1)))))
|
||||
((zero_l == 5 && s[10] == 0xff && s[11] == 0xff) ||
|
||||
((zero_l == 7 && s[14] != 0 && s[15] != 1)))))
|
||||
is_ipv4 = 1;
|
||||
|
||||
/* Format whole words. */
|
||||
for (p = 0; p < words; p++) {
|
||||
if (zero_l != 0 && p >= zero_s && p < zero_s + zero_l) {
|
||||
for (p = 0; p < words; p++)
|
||||
{
|
||||
if (zero_l != 0 && p >= zero_s && p < zero_s + zero_l)
|
||||
{
|
||||
/* Time to skip some zeros */
|
||||
if (p == zero_s)
|
||||
*cp++ = ':';
|
||||
if (p == words - 1) {
|
||||
if (p == words - 1)
|
||||
{
|
||||
*cp++ = ':';
|
||||
double_colon = 1;
|
||||
}
|
||||
@@ -251,15 +268,19 @@ inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_ipv4 && p > 5 ) {
|
||||
if (is_ipv4 && p > 5)
|
||||
{
|
||||
*cp++ = (p == 6) ? ':' : '.';
|
||||
cp += SPRINTF((cp, "%u", *s++));
|
||||
/* we can potentially drop the last octet */
|
||||
if (p != 7 || bits > 120) {
|
||||
if (p != 7 || bits > 120)
|
||||
{
|
||||
*cp++ = '.';
|
||||
cp += SPRINTF((cp, "%u", *s++));
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cp != outbuf)
|
||||
*cp++ = ':';
|
||||
cp += SPRINTF((cp, "%x", *s * 256 + s[1]));
|
||||
@@ -268,7 +289,8 @@ inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
|
||||
}
|
||||
}
|
||||
|
||||
if (!double_colon) {
|
||||
if (!double_colon)
|
||||
{
|
||||
if (bits < 128 - 32)
|
||||
cp += SPRINTF((cp, "::"));
|
||||
else if (bits < 128 - 16)
|
||||
@@ -281,7 +303,7 @@ inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
|
||||
if (strlen(outbuf) + 1 > size)
|
||||
goto emsgsize;
|
||||
strcpy(dst, outbuf);
|
||||
|
||||
|
||||
return (dst);
|
||||
|
||||
emsgsize:
|
||||
@@ -373,21 +395,24 @@ emsgsize:
|
||||
}
|
||||
|
||||
static int
|
||||
decoct(const u_char *src, int bytes, char *dst, size_t size) {
|
||||
char *odst = dst;
|
||||
char *t;
|
||||
int b;
|
||||
decoct(const u_char *src, int bytes, char *dst, size_t size)
|
||||
{
|
||||
char *odst = dst;
|
||||
char *t;
|
||||
int b;
|
||||
|
||||
for (b = 1; b <= bytes; b++) {
|
||||
for (b = 1; b <= bytes; b++)
|
||||
{
|
||||
if (size < sizeof "255.")
|
||||
return (0);
|
||||
t = dst;
|
||||
dst += SPRINTF((dst, "%u", *src++));
|
||||
if (b != bytes) {
|
||||
if (b != bytes)
|
||||
{
|
||||
*dst++ = '.';
|
||||
*dst = '\0';
|
||||
}
|
||||
size -= (size_t)(dst - t);
|
||||
size -= (size_t) (dst - t);
|
||||
}
|
||||
return (dst - odst);
|
||||
}
|
||||
@@ -402,42 +427,52 @@ inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
|
||||
* Keep this in mind if you think this function should have been coded
|
||||
* to use pointer overlays. All the world's not a VAX.
|
||||
*/
|
||||
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255/128"];
|
||||
char *tp;
|
||||
struct { int base, len; } best, cur;
|
||||
u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
|
||||
int i;
|
||||
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255/128"];
|
||||
char *tp;
|
||||
struct
|
||||
{
|
||||
int base,
|
||||
len;
|
||||
} best, cur;
|
||||
u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
|
||||
int i;
|
||||
|
||||
if ((bits < -1) || (bits > 128)) {
|
||||
if ((bits < -1) || (bits > 128))
|
||||
{
|
||||
errno = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Preprocess:
|
||||
* Copy the input (bytewise) array into a wordwise array.
|
||||
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||
* Preprocess: Copy the input (bytewise) array into a wordwise array.
|
||||
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||
*/
|
||||
memset(words, '\0', sizeof words);
|
||||
for (i = 0; i < NS_IN6ADDRSZ; i++)
|
||||
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
best.base = -1;
|
||||
cur.base = -1;
|
||||
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
|
||||
if (words[i] == 0) {
|
||||
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++)
|
||||
{
|
||||
if (words[i] == 0)
|
||||
{
|
||||
if (cur.base == -1)
|
||||
cur.base = i, cur.len = 1;
|
||||
else
|
||||
cur.len++;
|
||||
} else {
|
||||
if (cur.base != -1) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cur.base != -1)
|
||||
{
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
cur.base = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cur.base != -1) {
|
||||
if (cur.base != -1)
|
||||
{
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
}
|
||||
@@ -448,10 +483,12 @@ inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
|
||||
* Format the result.
|
||||
*/
|
||||
tp = tmp;
|
||||
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
|
||||
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++)
|
||||
{
|
||||
/* Are we inside the best run of 0x00's? */
|
||||
if (best.base != -1 && i >= best.base &&
|
||||
i < (best.base + best.len)) {
|
||||
i < (best.base + best.len))
|
||||
{
|
||||
if (i == best.base)
|
||||
*tp++ = ':';
|
||||
continue;
|
||||
@@ -461,12 +498,14 @@ inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
|
||||
*tp++ = ':';
|
||||
/* Is this address an encapsulated IPv4? */
|
||||
if (i == 6 && best.base == 0 && (best.len == 6 ||
|
||||
(best.len == 7 && words[7] != 0x0001) ||
|
||||
(best.len == 5 && words[5] == 0xffff))) {
|
||||
int n;
|
||||
(best.len == 7 && words[7] != 0x0001) ||
|
||||
(best.len == 5 && words[5] == 0xffff)))
|
||||
{
|
||||
int n;
|
||||
|
||||
n = decoct(src+12, 4, tp, sizeof tmp - (tp - tmp));
|
||||
if (n == 0) {
|
||||
n = decoct(src + 12, 4, tp, sizeof tmp - (tp - tmp));
|
||||
if (n == 0)
|
||||
{
|
||||
errno = EMSGSIZE;
|
||||
return (NULL);
|
||||
}
|
||||
@@ -477,8 +516,8 @@ inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
|
||||
}
|
||||
|
||||
/* Was it a trailing run of 0x00's? */
|
||||
if (best.base != -1 && (best.base + best.len) ==
|
||||
(NS_IN6ADDRSZ / NS_INT16SZ))
|
||||
if (best.base != -1 && (best.base + best.len) ==
|
||||
(NS_IN6ADDRSZ / NS_INT16SZ))
|
||||
*tp++ = ':';
|
||||
*tp = '\0';
|
||||
|
||||
@@ -488,7 +527,8 @@ inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
|
||||
/*
|
||||
* Check for overflow, copy, and we're done.
|
||||
*/
|
||||
if ((size_t)(tp - tmp) > size) {
|
||||
if ((size_t) (tp - tmp) > size)
|
||||
{
|
||||
errno = EMSGSIZE;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: inet_net_pton.c,v 1.15 2003/06/24 22:21:22 momjian Exp $";
|
||||
static const char rcsid[] = "$Id: inet_net_pton.c,v 1.16 2003/08/04 00:43:25 momjian Exp $";
|
||||
#endif
|
||||
|
||||
#include "postgres.h"
|
||||
@@ -35,8 +35,8 @@ static const char rcsid[] = "$Id: inet_net_pton.c,v 1.15 2003/06/24 22:21:22 mom
|
||||
|
||||
static int inet_net_pton_ipv4(const char *src, u_char *dst);
|
||||
static int inet_cidr_pton_ipv4(const char *src, u_char *dst, size_t size);
|
||||
static int inet_net_pton_ipv6(const char *src, u_char *dst);
|
||||
static int inet_cidr_pton_ipv6(const char *src, u_char *dst, size_t size);
|
||||
static int inet_net_pton_ipv6(const char *src, u_char *dst);
|
||||
static int inet_cidr_pton_ipv6(const char *src, u_char *dst, size_t size);
|
||||
|
||||
/*
|
||||
* static int
|
||||
@@ -339,24 +339,27 @@ emsgsize:
|
||||
}
|
||||
|
||||
static int
|
||||
getbits(const char *src, int *bitsp) {
|
||||
getbits(const char *src, int *bitsp)
|
||||
{
|
||||
static const char digits[] = "0123456789";
|
||||
int n;
|
||||
int val;
|
||||
char ch;
|
||||
int n;
|
||||
int val;
|
||||
char ch;
|
||||
|
||||
val = 0;
|
||||
n = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
while ((ch = *src++) != '\0')
|
||||
{
|
||||
const char *pch;
|
||||
|
||||
pch = strchr(digits, ch);
|
||||
if (pch != NULL) {
|
||||
if (pch != NULL)
|
||||
{
|
||||
if (n++ != 0 && val == 0) /* no leading zeros */
|
||||
return (0);
|
||||
val *= 10;
|
||||
val += (pch - digits);
|
||||
if (val > 128) /* range */
|
||||
if (val > 128) /* range */
|
||||
return (0);
|
||||
continue;
|
||||
}
|
||||
@@ -369,30 +372,34 @@ getbits(const char *src, int *bitsp) {
|
||||
}
|
||||
|
||||
static int
|
||||
getv4(const char *src, u_char *dst, int *bitsp) {
|
||||
getv4(const char *src, u_char *dst, int *bitsp)
|
||||
{
|
||||
static const char digits[] = "0123456789";
|
||||
u_char *odst = dst;
|
||||
int n;
|
||||
u_int val;
|
||||
char ch;
|
||||
u_char *odst = dst;
|
||||
int n;
|
||||
u_int val;
|
||||
char ch;
|
||||
|
||||
val = 0;
|
||||
n = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
while ((ch = *src++) != '\0')
|
||||
{
|
||||
const char *pch;
|
||||
|
||||
pch = strchr(digits, ch);
|
||||
if (pch != NULL) {
|
||||
if (pch != NULL)
|
||||
{
|
||||
if (n++ != 0 && val == 0) /* no leading zeros */
|
||||
return (0);
|
||||
val *= 10;
|
||||
val += (pch - digits);
|
||||
if (val > 255) /* range */
|
||||
if (val > 255) /* range */
|
||||
return (0);
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' || ch == '/') {
|
||||
if (dst - odst > 3) /* too many octets? */
|
||||
if (ch == '.' || ch == '/')
|
||||
{
|
||||
if (dst - odst > 3) /* too many octets? */
|
||||
return (0);
|
||||
*dst++ = val;
|
||||
if (ch == '/')
|
||||
@@ -405,7 +412,7 @@ getv4(const char *src, u_char *dst, int *bitsp) {
|
||||
}
|
||||
if (n == 0)
|
||||
return (0);
|
||||
if (dst - odst > 3) /* too many octets? */
|
||||
if (dst - odst > 3) /* too many octets? */
|
||||
return (0);
|
||||
*dst++ = val;
|
||||
return (1);
|
||||
@@ -422,15 +429,21 @@ inet_net_pton_ipv6(const char *src, u_char *dst)
|
||||
#define NS_INADDRSZ 4
|
||||
|
||||
static int
|
||||
inet_cidr_pton_ipv6(const char *src, u_char *dst, size_t size) {
|
||||
inet_cidr_pton_ipv6(const char *src, u_char *dst, size_t size)
|
||||
{
|
||||
static const char xdigits_l[] = "0123456789abcdef",
|
||||
xdigits_u[] = "0123456789ABCDEF";
|
||||
u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
const char *xdigits, *curtok;
|
||||
int ch, saw_xdigit;
|
||||
u_int val;
|
||||
int digits;
|
||||
int bits;
|
||||
xdigits_u[] = "0123456789ABCDEF";
|
||||
u_char tmp[NS_IN6ADDRSZ],
|
||||
*tp,
|
||||
*endp,
|
||||
*colonp;
|
||||
const char *xdigits,
|
||||
*curtok;
|
||||
int ch,
|
||||
saw_xdigit;
|
||||
u_int val;
|
||||
int digits;
|
||||
int bits;
|
||||
|
||||
if (size < NS_IN6ADDRSZ)
|
||||
goto emsgsize;
|
||||
@@ -447,12 +460,14 @@ inet_cidr_pton_ipv6(const char *src, u_char *dst, size_t size) {
|
||||
val = 0;
|
||||
digits = 0;
|
||||
bits = -1;
|
||||
while ((ch = *src++) != '\0') {
|
||||
while ((ch = *src++) != '\0')
|
||||
{
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
|
||||
pch = strchr((xdigits = xdigits_u), ch);
|
||||
if (pch != NULL) {
|
||||
if (pch != NULL)
|
||||
{
|
||||
val <<= 4;
|
||||
val |= (pch - xdigits);
|
||||
if (++digits > 4)
|
||||
@@ -460,14 +475,17 @@ inet_cidr_pton_ipv6(const char *src, u_char *dst, size_t size) {
|
||||
saw_xdigit = 1;
|
||||
continue;
|
||||
}
|
||||
if (ch == ':') {
|
||||
if (ch == ':')
|
||||
{
|
||||
curtok = src;
|
||||
if (!saw_xdigit) {
|
||||
if (!saw_xdigit)
|
||||
{
|
||||
if (colonp)
|
||||
goto enoent;
|
||||
colonp = tp;
|
||||
continue;
|
||||
} else if (*src == '\0')
|
||||
}
|
||||
else if (*src == '\0')
|
||||
goto enoent;
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
@@ -479,16 +497,18 @@ inet_cidr_pton_ipv6(const char *src, u_char *dst, size_t size) {
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
|
||||
getv4(curtok, tp, &bits) > 0) {
|
||||
getv4(curtok, tp, &bits) > 0)
|
||||
{
|
||||
tp += NS_INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
break; /* '\0' was seen by inet_pton4(). */
|
||||
break; /* '\0' was seen by inet_pton4(). */
|
||||
}
|
||||
if (ch == '/' && getbits(src, &bits) > 0)
|
||||
break;
|
||||
goto enoent;
|
||||
}
|
||||
if (saw_xdigit) {
|
||||
if (saw_xdigit)
|
||||
{
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
goto enoent;
|
||||
*tp++ = (u_char) (val >> 8) & 0xff;
|
||||
@@ -497,20 +517,22 @@ inet_cidr_pton_ipv6(const char *src, u_char *dst, size_t size) {
|
||||
if (bits == -1)
|
||||
bits = 128;
|
||||
|
||||
endp = tmp + 16;
|
||||
endp = tmp + 16;
|
||||
|
||||
if (colonp != NULL) {
|
||||
if (colonp != NULL)
|
||||
{
|
||||
/*
|
||||
* Since some memmove()'s erroneously fail to handle
|
||||
* overlapping regions, we'll do the shift by hand.
|
||||
* Since some memmove()'s erroneously fail to handle overlapping
|
||||
* regions, we'll do the shift by hand.
|
||||
*/
|
||||
const int n = tp - colonp;
|
||||
int i;
|
||||
const int n = tp - colonp;
|
||||
int i;
|
||||
|
||||
if (tp == endp)
|
||||
goto enoent;
|
||||
for (i = 1; i <= n; i++) {
|
||||
endp[- i] = colonp[n - i];
|
||||
for (i = 1; i <= n; i++)
|
||||
{
|
||||
endp[-i] = colonp[n - i];
|
||||
colonp[n - i] = 0;
|
||||
}
|
||||
tp = endp;
|
||||
@@ -525,11 +547,11 @@ inet_cidr_pton_ipv6(const char *src, u_char *dst, size_t size) {
|
||||
|
||||
return (bits);
|
||||
|
||||
enoent:
|
||||
enoent:
|
||||
errno = ENOENT;
|
||||
return (-1);
|
||||
|
||||
emsgsize:
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/int.c,v 1.55 2003/07/27 04:53:06 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/int.c,v 1.56 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -173,9 +173,7 @@ int2vectorrecv(PG_FUNCTION_ARGS)
|
||||
int slot;
|
||||
|
||||
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
|
||||
{
|
||||
result[slot] = (int16) pq_getmsgint(buf, sizeof(int16));
|
||||
}
|
||||
PG_RETURN_POINTER(result);
|
||||
}
|
||||
|
||||
@@ -191,9 +189,7 @@ int2vectorsend(PG_FUNCTION_ARGS)
|
||||
|
||||
pq_begintypsend(&buf);
|
||||
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
|
||||
{
|
||||
pq_sendint(&buf, int2Array[slot], sizeof(int16));
|
||||
}
|
||||
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/int8.c,v 1.45 2003/07/27 04:53:06 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/int8.c,v 1.46 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -85,7 +85,7 @@ scanint8(const char *str, bool errorOK, int64 *result)
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for int8: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for int8: \"%s\"", str)));
|
||||
}
|
||||
|
||||
/* process digits */
|
||||
@@ -113,7 +113,7 @@ scanint8(const char *str, bool errorOK, int64 *result)
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for int8: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for int8: \"%s\"", str)));
|
||||
}
|
||||
|
||||
*result = (sign < 0) ? -tmp : tmp;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/like.c,v 1.54 2003/07/27 04:53:06 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/like.c,v 1.55 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -451,7 +451,7 @@ like_escape_bytea(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE),
|
||||
errmsg("invalid escape string"),
|
||||
errhint("Escape string must be empty or one character.")));
|
||||
errhint("Escape string must be empty or one character.")));
|
||||
|
||||
e = VARDATA(esc);
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/like_match.c,v 1.5 2003/07/27 04:53:06 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/like_match.c,v 1.6 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -289,7 +289,7 @@ do_like_escape(text *pat, text *esc)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE),
|
||||
errmsg("invalid escape string"),
|
||||
errhint("Escape string must be empty or one character.")));
|
||||
errhint("Escape string must be empty or one character.")));
|
||||
|
||||
e = VARDATA(esc);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* PostgreSQL type definitions for MAC addresses.
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/mac.c,v 1.29 2003/07/27 04:53:06 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/mac.c,v 1.30 2003/08/04 00:43:25 momjian Exp $
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
@@ -62,7 +62,7 @@ macaddr_in(PG_FUNCTION_ARGS)
|
||||
if (count != 6)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for macaddr: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for macaddr: \"%s\"", str)));
|
||||
|
||||
if ((a < 0) || (a > 255) || (b < 0) || (b > 255) ||
|
||||
(c < 0) || (c > 255) || (d < 0) || (d > 255) ||
|
||||
@@ -110,7 +110,7 @@ Datum
|
||||
macaddr_recv(PG_FUNCTION_ARGS)
|
||||
{
|
||||
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
|
||||
macaddr *addr;
|
||||
macaddr *addr;
|
||||
|
||||
addr = (macaddr *) palloc(sizeof(macaddr));
|
||||
|
||||
@@ -130,7 +130,7 @@ macaddr_recv(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
macaddr_send(PG_FUNCTION_ARGS)
|
||||
{
|
||||
macaddr *addr = PG_GETARG_MACADDR_P(0);
|
||||
macaddr *addr = PG_GETARG_MACADDR_P(0);
|
||||
StringInfoData buf;
|
||||
|
||||
pq_begintypsend(&buf);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.111 2003/07/28 00:09:16 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.112 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -83,7 +83,7 @@ static int istinterval(char *i_string,
|
||||
AbsoluteTime *i_end);
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* GetCurrentAbsoluteTime()
|
||||
*
|
||||
* Get the current system time (relative to Unix epoch).
|
||||
@@ -152,7 +152,7 @@ GetCurrentDateTime(struct tm * tm)
|
||||
abstime2tm(GetCurrentTransactionStartTime(), &tz, tm, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* GetCurrentTimeUsec()
|
||||
*
|
||||
* Get the transaction start time ("now()") broken down as a struct tm,
|
||||
@@ -373,13 +373,13 @@ abstimein(PG_FUNCTION_ARGS)
|
||||
if (strlen(str) >= sizeof(lowstr))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for abstime: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for abstime: \"%s\"", str)));
|
||||
|
||||
if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
|
||||
|| (DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for abstime: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for abstime: \"%s\"", str)));
|
||||
|
||||
switch (dtype)
|
||||
{
|
||||
@@ -654,7 +654,7 @@ abstime_timestamp(PG_FUNCTION_ARGS)
|
||||
case INVALID_ABSTIME:
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("cannot convert \"invalid\" abstime to timestamp")));
|
||||
errmsg("cannot convert \"invalid\" abstime to timestamp")));
|
||||
TIMESTAMP_NOBEGIN(result);
|
||||
break;
|
||||
|
||||
@@ -727,7 +727,7 @@ abstime_timestamptz(PG_FUNCTION_ARGS)
|
||||
case INVALID_ABSTIME:
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("cannot convert \"invalid\" abstime to timestamp")));
|
||||
errmsg("cannot convert \"invalid\" abstime to timestamp")));
|
||||
TIMESTAMP_NOBEGIN(result);
|
||||
break;
|
||||
|
||||
@@ -776,13 +776,13 @@ reltimein(PG_FUNCTION_ARGS)
|
||||
if (strlen(str) >= sizeof(lowstr))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for reltime: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for reltime: \"%s\"", str)));
|
||||
|
||||
if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
|
||||
|| (DecodeInterval(field, ftype, nf, &dtype, tm, &fsec) != 0))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for reltime: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for reltime: \"%s\"", str)));
|
||||
|
||||
switch (dtype)
|
||||
{
|
||||
@@ -849,7 +849,7 @@ reltimesend(PG_FUNCTION_ARGS)
|
||||
static void
|
||||
reltime2tm(RelativeTime time, struct tm * tm)
|
||||
{
|
||||
double dtime = time;
|
||||
double dtime = time;
|
||||
|
||||
FMODULO(dtime, tm->tm_year, 31557600);
|
||||
FMODULO(dtime, tm->tm_mon, 2592000);
|
||||
@@ -1032,7 +1032,7 @@ reltime_interval(PG_FUNCTION_ARGS)
|
||||
case INVALID_RELTIME:
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("cannot convert \"invalid\" reltime to interval")));
|
||||
errmsg("cannot convert \"invalid\" reltime to interval")));
|
||||
result->time = 0;
|
||||
result->month = 0;
|
||||
break;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/name.c,v 1.47 2003/07/27 04:53:07 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/name.c,v 1.48 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -89,7 +89,7 @@ namerecv(PG_FUNCTION_ARGS)
|
||||
(errcode(ERRCODE_NAME_TOO_LONG),
|
||||
errmsg("identifier too long"),
|
||||
errdetail("Identifier must be less than %d characters.",
|
||||
NAMEDATALEN)));
|
||||
NAMEDATALEN)));
|
||||
result = (NameData *) palloc0(NAMEDATALEN);
|
||||
memcpy(result, str, nbytes);
|
||||
pfree(str);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* PostgreSQL type definitions for the INET and CIDR types.
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.44 2003/08/01 23:22:52 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.45 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
* Jon Postel RIP 16 Oct 1998
|
||||
*/
|
||||
@@ -21,9 +21,9 @@
|
||||
|
||||
static Datum text_network(text *src, int type);
|
||||
static int32 network_cmp_internal(inet *a1, inet *a2);
|
||||
static int bitncmp(void *l, void *r, int n);
|
||||
static int bitncmp(void *l, void *r, int n);
|
||||
static bool addressOK(unsigned char *a, int bits, int family);
|
||||
static int ip_addrsize(inet *inetptr);
|
||||
static int ip_addrsize(inet *inetptr);
|
||||
|
||||
/*
|
||||
* Access macros.
|
||||
@@ -50,13 +50,14 @@ static int ip_addrsize(inet *inetptr);
|
||||
static int
|
||||
ip_addrsize(inet *inetptr)
|
||||
{
|
||||
switch (ip_family(inetptr)) {
|
||||
case PGSQL_AF_INET:
|
||||
return 4;
|
||||
case PGSQL_AF_INET6:
|
||||
return 16;
|
||||
default:
|
||||
return -1;
|
||||
switch (ip_family(inetptr))
|
||||
{
|
||||
case PGSQL_AF_INET:
|
||||
return 4;
|
||||
case PGSQL_AF_INET6:
|
||||
return 16;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,34 +65,34 @@ ip_addrsize(inet *inetptr)
|
||||
static inet *
|
||||
network_in(char *src, int type)
|
||||
{
|
||||
int bits;
|
||||
int bits;
|
||||
inet *dst;
|
||||
|
||||
dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
|
||||
|
||||
/*
|
||||
* First, check to see if this is an IPv6 or IPv4 address. IPv6
|
||||
* addresses will have a : somewhere in them (several, in fact) so
|
||||
* if there is one present, assume it's V6, otherwise assume it's V4.
|
||||
* First, check to see if this is an IPv6 or IPv4 address. IPv6
|
||||
* addresses will have a : somewhere in them (several, in fact) so if
|
||||
* there is one present, assume it's V6, otherwise assume it's V4.
|
||||
*/
|
||||
|
||||
if (strchr(src, ':') != NULL)
|
||||
ip_family(dst) = PGSQL_AF_INET6;
|
||||
else
|
||||
ip_family(dst) = PGSQL_AF_INET;
|
||||
|
||||
|
||||
bits = inet_net_pton(ip_family(dst), src, ip_addr(dst),
|
||||
type ? ip_addrsize(dst) : -1);
|
||||
type ? ip_addrsize(dst) : -1);
|
||||
if ((bits < 0) || (bits > ip_maxbits(dst)))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
/* translator: first %s is inet or cidr */
|
||||
/* translator: first %s is inet or cidr */
|
||||
errmsg("invalid input syntax for %s: \"%s\"",
|
||||
type ? "cidr" : "inet", src)));
|
||||
type ? "cidr" : "inet", src)));
|
||||
|
||||
/*
|
||||
* Error check: CIDR values must not have any bits set beyond
|
||||
* the masklen.
|
||||
* Error check: CIDR values must not have any bits set beyond the
|
||||
* masklen.
|
||||
*/
|
||||
if (type)
|
||||
{
|
||||
@@ -141,7 +142,7 @@ inet_out(PG_FUNCTION_ARGS)
|
||||
int len;
|
||||
|
||||
dst = inet_net_ntop(ip_family(src), ip_addr(src), ip_bits(src),
|
||||
tmp, sizeof(tmp));
|
||||
tmp, sizeof(tmp));
|
||||
if (dst == NULL)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
||||
@@ -208,10 +209,10 @@ inet_recv(PG_FUNCTION_ARGS)
|
||||
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
||||
errmsg("invalid length in external inet")));
|
||||
VARATT_SIZEP(addr) = VARHDRSZ
|
||||
+ ((char *)ip_addr(addr) - (char *) VARDATA(addr))
|
||||
+ ((char *) ip_addr(addr) - (char *) VARDATA(addr))
|
||||
+ ip_addrsize(addr);
|
||||
|
||||
addrptr = (char *)ip_addr(addr);
|
||||
addrptr = (char *) ip_addr(addr);
|
||||
for (i = 0; i < nb; i++)
|
||||
addrptr[i] = pq_getmsgbyte(buf);
|
||||
|
||||
@@ -258,7 +259,7 @@ inet_send(PG_FUNCTION_ARGS)
|
||||
if (nb < 0)
|
||||
nb = 0;
|
||||
pq_sendbyte(&buf, nb);
|
||||
addrptr = (char *)ip_addr(addr);
|
||||
addrptr = (char *) ip_addr(addr);
|
||||
for (i = 0; i < nb; i++)
|
||||
pq_sendbyte(&buf, addrptr[i]);
|
||||
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
||||
@@ -305,8 +306,8 @@ inet_set_masklen(PG_FUNCTION_ARGS)
|
||||
int bits = PG_GETARG_INT32(1);
|
||||
inet *dst;
|
||||
|
||||
if ( bits == -1 )
|
||||
bits = ip_maxbits(src);
|
||||
if (bits == -1)
|
||||
bits = ip_maxbits(src);
|
||||
|
||||
if ((bits < 0) || (bits > ip_maxbits(src)))
|
||||
ereport(ERROR,
|
||||
@@ -341,7 +342,7 @@ network_cmp_internal(inet *a1, inet *a2)
|
||||
int order;
|
||||
|
||||
order = bitncmp(ip_addr(a1), ip_addr(a2),
|
||||
Min(ip_bits(a1), ip_bits(a2)));
|
||||
Min(ip_bits(a1), ip_bits(a2)));
|
||||
if (order != 0)
|
||||
return order;
|
||||
order = ((int) ip_bits(a1)) - ((int) ip_bits(a2));
|
||||
@@ -431,7 +432,7 @@ network_sub(PG_FUNCTION_ARGS)
|
||||
if (ip_family(a1) == ip_family(a2))
|
||||
{
|
||||
PG_RETURN_BOOL(ip_bits(a1) > ip_bits(a2)
|
||||
&& bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0);
|
||||
&& bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0);
|
||||
}
|
||||
|
||||
PG_RETURN_BOOL(false);
|
||||
@@ -446,7 +447,7 @@ network_subeq(PG_FUNCTION_ARGS)
|
||||
if (ip_family(a1) == ip_family(a2))
|
||||
{
|
||||
PG_RETURN_BOOL(ip_bits(a1) >= ip_bits(a2)
|
||||
&& bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0);
|
||||
&& bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0);
|
||||
}
|
||||
|
||||
PG_RETURN_BOOL(false);
|
||||
@@ -461,7 +462,7 @@ network_sup(PG_FUNCTION_ARGS)
|
||||
if (ip_family(a1) == ip_family(a2))
|
||||
{
|
||||
PG_RETURN_BOOL(ip_bits(a1) < ip_bits(a2)
|
||||
&& bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0);
|
||||
&& bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0);
|
||||
}
|
||||
|
||||
PG_RETURN_BOOL(false);
|
||||
@@ -476,7 +477,7 @@ network_supeq(PG_FUNCTION_ARGS)
|
||||
if (ip_family(a1) == ip_family(a2))
|
||||
{
|
||||
PG_RETURN_BOOL(ip_bits(a1) <= ip_bits(a2)
|
||||
&& bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0);
|
||||
&& bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0);
|
||||
}
|
||||
|
||||
PG_RETURN_BOOL(false);
|
||||
@@ -496,7 +497,7 @@ network_host(PG_FUNCTION_ARGS)
|
||||
|
||||
/* force display of max bits, regardless of masklen... */
|
||||
if (inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip),
|
||||
tmp, sizeof(tmp)) == NULL)
|
||||
tmp, sizeof(tmp)) == NULL)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
||||
errmsg("could not format inet value: %m")));
|
||||
@@ -522,7 +523,7 @@ network_show(PG_FUNCTION_ARGS)
|
||||
char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
|
||||
|
||||
if (inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip),
|
||||
tmp, sizeof(tmp)) == NULL)
|
||||
tmp, sizeof(tmp)) == NULL)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
||||
errmsg("could not format inet value: %m")));
|
||||
@@ -553,10 +554,10 @@ network_abbrev(PG_FUNCTION_ARGS)
|
||||
|
||||
if (ip_type(ip))
|
||||
dst = inet_cidr_ntop(ip_family(ip), ip_addr(ip),
|
||||
ip_bits(ip), tmp, sizeof(tmp));
|
||||
ip_bits(ip), tmp, sizeof(tmp));
|
||||
else
|
||||
dst = inet_net_ntop(ip_family(ip), ip_addr(ip),
|
||||
ip_bits(ip), tmp, sizeof(tmp));
|
||||
ip_bits(ip), tmp, sizeof(tmp));
|
||||
|
||||
if (dst == NULL)
|
||||
ereport(ERROR,
|
||||
@@ -582,18 +583,19 @@ network_masklen(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
network_family(PG_FUNCTION_ARGS)
|
||||
{
|
||||
inet *ip = PG_GETARG_INET_P(0);
|
||||
inet *ip = PG_GETARG_INET_P(0);
|
||||
|
||||
switch (ip_family(ip)) {
|
||||
case PGSQL_AF_INET:
|
||||
PG_RETURN_INT32(4);
|
||||
break;
|
||||
case PGSQL_AF_INET6:
|
||||
PG_RETURN_INT32(6);
|
||||
break;
|
||||
default:
|
||||
PG_RETURN_INT32(0);
|
||||
break;
|
||||
switch (ip_family(ip))
|
||||
{
|
||||
case PGSQL_AF_INET:
|
||||
PG_RETURN_INT32(4);
|
||||
break;
|
||||
case PGSQL_AF_INET6:
|
||||
PG_RETURN_INT32(6);
|
||||
break;
|
||||
default:
|
||||
PG_RETURN_INT32(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -602,38 +604,42 @@ network_broadcast(PG_FUNCTION_ARGS)
|
||||
{
|
||||
inet *ip = PG_GETARG_INET_P(0);
|
||||
inet *dst;
|
||||
int byte;
|
||||
int bits;
|
||||
int maxbytes;
|
||||
int byte;
|
||||
int bits;
|
||||
int maxbytes;
|
||||
unsigned char mask;
|
||||
unsigned char *a, *b;
|
||||
unsigned char *a,
|
||||
*b;
|
||||
|
||||
/* make sure any unused bits are zeroed */
|
||||
dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
|
||||
|
||||
if (ip_family(ip) == PGSQL_AF_INET) {
|
||||
if (ip_family(ip) == PGSQL_AF_INET)
|
||||
maxbytes = 4;
|
||||
} else {
|
||||
else
|
||||
maxbytes = 16;
|
||||
}
|
||||
|
||||
bits = ip_bits(ip);
|
||||
a = ip_addr(ip);
|
||||
b = ip_addr(dst);
|
||||
|
||||
for (byte = 0 ; byte < maxbytes ; byte++) {
|
||||
if (bits >= 8) {
|
||||
for (byte = 0; byte < maxbytes; byte++)
|
||||
{
|
||||
if (bits >= 8)
|
||||
{
|
||||
mask = 0x00;
|
||||
bits -= 8;
|
||||
} else if (bits == 0) {
|
||||
}
|
||||
else if (bits == 0)
|
||||
mask = 0xff;
|
||||
} else {
|
||||
else
|
||||
{
|
||||
mask = 0xff >> bits;
|
||||
bits = 0;
|
||||
}
|
||||
|
||||
b[byte] = a[byte] | mask;
|
||||
}
|
||||
}
|
||||
|
||||
ip_family(dst) = ip_family(ip);
|
||||
ip_bits(dst) = ip_bits(ip);
|
||||
@@ -650,38 +656,42 @@ network_network(PG_FUNCTION_ARGS)
|
||||
{
|
||||
inet *ip = PG_GETARG_INET_P(0);
|
||||
inet *dst;
|
||||
int byte;
|
||||
int bits;
|
||||
int maxbytes;
|
||||
int byte;
|
||||
int bits;
|
||||
int maxbytes;
|
||||
unsigned char mask;
|
||||
unsigned char *a, *b;
|
||||
unsigned char *a,
|
||||
*b;
|
||||
|
||||
/* make sure any unused bits are zeroed */
|
||||
dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
|
||||
|
||||
if (ip_family(ip) == PGSQL_AF_INET) {
|
||||
if (ip_family(ip) == PGSQL_AF_INET)
|
||||
maxbytes = 4;
|
||||
} else {
|
||||
else
|
||||
maxbytes = 16;
|
||||
}
|
||||
|
||||
bits = ip_bits(ip);
|
||||
a = ip_addr(ip);
|
||||
b = ip_addr(dst);
|
||||
|
||||
byte = 0;
|
||||
while (bits) {
|
||||
if (bits >= 8) {
|
||||
while (bits)
|
||||
{
|
||||
if (bits >= 8)
|
||||
{
|
||||
mask = 0xff;
|
||||
bits -= 8;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mask = 0xff << (8 - bits);
|
||||
bits = 0;
|
||||
}
|
||||
|
||||
b[byte] = a[byte] & mask;
|
||||
byte++;
|
||||
}
|
||||
}
|
||||
|
||||
ip_family(dst) = ip_family(ip);
|
||||
ip_bits(dst) = ip_bits(ip);
|
||||
@@ -698,43 +708,46 @@ network_netmask(PG_FUNCTION_ARGS)
|
||||
{
|
||||
inet *ip = PG_GETARG_INET_P(0);
|
||||
inet *dst;
|
||||
int byte;
|
||||
int bits;
|
||||
int maxbytes;
|
||||
int byte;
|
||||
int bits;
|
||||
int maxbytes;
|
||||
unsigned char mask;
|
||||
unsigned char *b;
|
||||
|
||||
/* make sure any unused bits are zeroed */
|
||||
dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
|
||||
|
||||
if (ip_family(ip) == PGSQL_AF_INET) {
|
||||
if (ip_family(ip) == PGSQL_AF_INET)
|
||||
maxbytes = 4;
|
||||
} else {
|
||||
else
|
||||
maxbytes = 16;
|
||||
}
|
||||
|
||||
bits = ip_bits(ip);
|
||||
b = ip_addr(dst);
|
||||
|
||||
byte = 0;
|
||||
while (bits) {
|
||||
if (bits >= 8) {
|
||||
while (bits)
|
||||
{
|
||||
if (bits >= 8)
|
||||
{
|
||||
mask = 0xff;
|
||||
bits -= 8;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mask = 0xff << (8 - bits);
|
||||
bits = 0;
|
||||
}
|
||||
|
||||
b[byte] = mask;
|
||||
byte++;
|
||||
}
|
||||
}
|
||||
|
||||
ip_family(dst) = ip_family(ip);
|
||||
ip_bits(dst) = ip_bits(ip);
|
||||
ip_type(dst) = 0;
|
||||
VARATT_SIZEP(dst) = VARHDRSZ
|
||||
+ ((char *)ip_addr(dst) - (char *) VARDATA(dst))
|
||||
+ ((char *) ip_addr(dst) - (char *) VARDATA(dst))
|
||||
+ ip_addrsize(dst);
|
||||
|
||||
PG_RETURN_INET_P(dst);
|
||||
@@ -745,43 +758,46 @@ network_hostmask(PG_FUNCTION_ARGS)
|
||||
{
|
||||
inet *ip = PG_GETARG_INET_P(0);
|
||||
inet *dst;
|
||||
int byte;
|
||||
int bits;
|
||||
int maxbytes;
|
||||
int byte;
|
||||
int bits;
|
||||
int maxbytes;
|
||||
unsigned char mask;
|
||||
unsigned char *b;
|
||||
|
||||
/* make sure any unused bits are zeroed */
|
||||
dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
|
||||
|
||||
if (ip_family(ip) == PGSQL_AF_INET) {
|
||||
if (ip_family(ip) == PGSQL_AF_INET)
|
||||
maxbytes = 4;
|
||||
} else {
|
||||
else
|
||||
maxbytes = 16;
|
||||
}
|
||||
|
||||
bits = ip_maxbits(ip) - ip_bits(ip);
|
||||
b = ip_addr(dst);
|
||||
|
||||
byte = maxbytes - 1;
|
||||
while (bits) {
|
||||
if (bits >= 8) {
|
||||
while (bits)
|
||||
{
|
||||
if (bits >= 8)
|
||||
{
|
||||
mask = 0xff;
|
||||
bits -= 8;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mask = 0xff >> (8 - bits);
|
||||
bits = 0;
|
||||
}
|
||||
|
||||
b[byte] = mask;
|
||||
byte--;
|
||||
}
|
||||
}
|
||||
|
||||
ip_family(dst) = ip_family(ip);
|
||||
ip_bits(dst) = ip_bits(ip);
|
||||
ip_type(dst) = 0;
|
||||
VARATT_SIZEP(dst) = VARHDRSZ
|
||||
+ ((char *)ip_addr(dst) - (char *) VARDATA(dst))
|
||||
+ ((char *) ip_addr(dst) - (char *) VARDATA(dst))
|
||||
+ ip_addrsize(dst);
|
||||
|
||||
PG_RETURN_INET_P(dst);
|
||||
@@ -806,13 +822,12 @@ convert_network_to_scalar(Datum value, Oid typid)
|
||||
case CIDROID:
|
||||
{
|
||||
inet *ip = DatumGetInetP(value);
|
||||
int len;
|
||||
double res;
|
||||
int i;
|
||||
int len;
|
||||
double res;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Note that we don't use the full address
|
||||
* here.
|
||||
* Note that we don't use the full address here.
|
||||
*/
|
||||
if (ip_family(ip) == PGSQL_AF_INET)
|
||||
len = 4;
|
||||
@@ -820,7 +835,8 @@ convert_network_to_scalar(Datum value, Oid typid)
|
||||
len = 5;
|
||||
|
||||
res = ip_family(ip);
|
||||
for (i = 0 ; i < len ; i++) {
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
res *= 256;
|
||||
res += ip_addr(ip)[i];
|
||||
}
|
||||
@@ -851,30 +867,34 @@ convert_network_to_scalar(Datum value, Oid typid)
|
||||
/*
|
||||
* int
|
||||
* bitncmp(l, r, n)
|
||||
* compare bit masks l and r, for n bits.
|
||||
* compare bit masks l and r, for n bits.
|
||||
* return:
|
||||
* -1, 1, or 0 in the libc tradition.
|
||||
* -1, 1, or 0 in the libc tradition.
|
||||
* note:
|
||||
* network byte order assumed. this means 192.5.5.240/28 has
|
||||
* 0x11110000 in its fourth octet.
|
||||
* network byte order assumed. this means 192.5.5.240/28 has
|
||||
* 0x11110000 in its fourth octet.
|
||||
* author:
|
||||
* Paul Vixie (ISC), June 1996
|
||||
* Paul Vixie (ISC), June 1996
|
||||
*/
|
||||
static int
|
||||
bitncmp(void *l, void *r, int n)
|
||||
{
|
||||
u_int lb, rb;
|
||||
int x, b;
|
||||
u_int lb,
|
||||
rb;
|
||||
int x,
|
||||
b;
|
||||
|
||||
b = n / 8;
|
||||
x = memcmp(l, r, b);
|
||||
if (x)
|
||||
return (x);
|
||||
|
||||
lb = ((const u_char *)l)[b];
|
||||
rb = ((const u_char *)r)[b];
|
||||
for (b = n % 8; b > 0; b--) {
|
||||
if ((lb & 0x80) != (rb & 0x80)) {
|
||||
lb = ((const u_char *) l)[b];
|
||||
rb = ((const u_char *) r)[b];
|
||||
for (b = n % 8; b > 0; b--)
|
||||
{
|
||||
if ((lb & 0x80) != (rb & 0x80))
|
||||
{
|
||||
if (lb & 0x80)
|
||||
return (1);
|
||||
return (-1);
|
||||
@@ -888,16 +908,19 @@ bitncmp(void *l, void *r, int n)
|
||||
static bool
|
||||
addressOK(unsigned char *a, int bits, int family)
|
||||
{
|
||||
int byte;
|
||||
int nbits;
|
||||
int maxbits;
|
||||
int maxbytes;
|
||||
int byte;
|
||||
int nbits;
|
||||
int maxbits;
|
||||
int maxbytes;
|
||||
unsigned char mask;
|
||||
|
||||
if (family == PGSQL_AF_INET) {
|
||||
if (family == PGSQL_AF_INET)
|
||||
{
|
||||
maxbits = 32;
|
||||
maxbytes = 4;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
maxbits = 128;
|
||||
maxbytes = 16;
|
||||
}
|
||||
@@ -912,7 +935,8 @@ addressOK(unsigned char *a, int bits, int family)
|
||||
if (bits != 0)
|
||||
mask >>= nbits;
|
||||
|
||||
while (byte < maxbytes) {
|
||||
while (byte < maxbytes)
|
||||
{
|
||||
if ((a[byte] & mask) != 0)
|
||||
return false;
|
||||
mask = 0xff;
|
||||
@@ -948,5 +972,5 @@ network_scan_last(Datum in)
|
||||
{
|
||||
return DirectFunctionCall2(inet_set_masklen,
|
||||
DirectFunctionCall1(network_broadcast, in),
|
||||
Int32GetDatum(-1));
|
||||
Int32GetDatum(-1));
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/not_in.c,v 1.33 2003/07/27 04:53:07 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/not_in.c,v 1.34 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -62,7 +62,7 @@ int4notin(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_NAME),
|
||||
errmsg("invalid name syntax"),
|
||||
errhint("Must provide \"relationname.attributename\".")));
|
||||
errhint("Must provide \"relationname.attributename\".")));
|
||||
attribute = strVal(nth(nnames - 1, names));
|
||||
names = ltruncate(nnames - 1, names);
|
||||
relrv = makeRangeVarFromNameList(names);
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* Copyright (c) 1998-2003, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v 1.64 2003/07/30 19:48:41 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v 1.65 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -57,7 +57,7 @@
|
||||
* Numeric values are represented in a base-NBASE floating point format.
|
||||
* Each "digit" ranges from 0 to NBASE-1. The type NumericDigit is signed
|
||||
* and wide enough to store a digit. We assume that NBASE*NBASE can fit in
|
||||
* an int. Although the purely calculational routines could handle any even
|
||||
* an int. Although the purely calculational routines could handle any even
|
||||
* NBASE that's less than sqrt(INT_MAX), in practice we are only interested
|
||||
* in NBASE a power of ten, so that I/O conversions and decimal rounding
|
||||
* are easy. Also, it's actually more efficient if NBASE is rather less than
|
||||
@@ -101,7 +101,7 @@ typedef int16 NumericDigit;
|
||||
* The value represented by a NumericVar is determined by the sign, weight,
|
||||
* ndigits, and digits[] array.
|
||||
* Note: the first digit of a NumericVar's value is assumed to be multiplied
|
||||
* by NBASE ** weight. Another way to say it is that there are weight+1
|
||||
* by NBASE ** weight. Another way to say it is that there are weight+1
|
||||
* digits before the decimal point. It is possible to have weight < 0.
|
||||
*
|
||||
* buf points at the physical start of the palloc'd digit buffer for the
|
||||
@@ -166,8 +166,10 @@ static NumericVar const_two =
|
||||
|
||||
#if DEC_DIGITS == 4
|
||||
static NumericDigit const_zero_point_five_data[1] = {5000};
|
||||
|
||||
#elif DEC_DIGITS == 2
|
||||
static NumericDigit const_zero_point_five_data[1] = {50};
|
||||
|
||||
#elif DEC_DIGITS == 1
|
||||
static NumericDigit const_zero_point_five_data[1] = {5};
|
||||
#endif
|
||||
@@ -176,8 +178,10 @@ static NumericVar const_zero_point_five =
|
||||
|
||||
#if DEC_DIGITS == 4
|
||||
static NumericDigit const_zero_point_nine_data[1] = {9000};
|
||||
|
||||
#elif DEC_DIGITS == 2
|
||||
static NumericDigit const_zero_point_nine_data[1] = {90};
|
||||
|
||||
#elif DEC_DIGITS == 1
|
||||
static NumericDigit const_zero_point_nine_data[1] = {9};
|
||||
#endif
|
||||
@@ -188,10 +192,12 @@ static NumericVar const_zero_point_nine =
|
||||
static NumericDigit const_zero_point_01_data[1] = {100};
|
||||
static NumericVar const_zero_point_01 =
|
||||
{1, -1, NUMERIC_POS, 2, NULL, const_zero_point_01_data};
|
||||
|
||||
#elif DEC_DIGITS == 2
|
||||
static NumericDigit const_zero_point_01_data[1] = {1};
|
||||
static NumericVar const_zero_point_01 =
|
||||
{1, -1, NUMERIC_POS, 2, NULL, const_zero_point_01_data};
|
||||
|
||||
#elif DEC_DIGITS == 1
|
||||
static NumericDigit const_zero_point_01_data[1] = {1};
|
||||
static NumericVar const_zero_point_01 =
|
||||
@@ -200,8 +206,10 @@ static NumericVar const_zero_point_01 =
|
||||
|
||||
#if DEC_DIGITS == 4
|
||||
static NumericDigit const_one_point_one_data[2] = {1, 1000};
|
||||
|
||||
#elif DEC_DIGITS == 2
|
||||
static NumericDigit const_one_point_one_data[2] = {1, 10};
|
||||
|
||||
#elif DEC_DIGITS == 1
|
||||
static NumericDigit const_one_point_one_data[2] = {1, 1};
|
||||
#endif
|
||||
@@ -212,7 +220,7 @@ static NumericVar const_nan =
|
||||
{0, 0, NUMERIC_NAN, 0, NULL, NULL};
|
||||
|
||||
#if DEC_DIGITS == 4
|
||||
static const int round_powers[4] = { 0, 1000, 100, 10 };
|
||||
static const int round_powers[4] = {0, 1000, 100, 10};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -263,9 +271,9 @@ static int cmp_var(NumericVar *var1, NumericVar *var2);
|
||||
static void add_var(NumericVar *var1, NumericVar *var2, NumericVar *result);
|
||||
static void sub_var(NumericVar *var1, NumericVar *var2, NumericVar *result);
|
||||
static void mul_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
int rscale);
|
||||
int rscale);
|
||||
static void div_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
int rscale);
|
||||
int rscale);
|
||||
static int select_div_scale(NumericVar *var1, NumericVar *var2);
|
||||
static void mod_var(NumericVar *var1, NumericVar *var2, NumericVar *result);
|
||||
static void ceil_var(NumericVar *var, NumericVar *result);
|
||||
@@ -278,7 +286,7 @@ static void ln_var(NumericVar *arg, NumericVar *result, int rscale);
|
||||
static void log_var(NumericVar *base, NumericVar *num, NumericVar *result);
|
||||
static void power_var(NumericVar *base, NumericVar *exp, NumericVar *result);
|
||||
static void power_var_int(NumericVar *base, int exp, NumericVar *result,
|
||||
int rscale);
|
||||
int rscale);
|
||||
|
||||
static int cmp_abs(NumericVar *var1, NumericVar *var2);
|
||||
static void add_abs(NumericVar *var1, NumericVar *var2, NumericVar *result);
|
||||
@@ -408,7 +416,7 @@ numeric_recv(PG_FUNCTION_ARGS)
|
||||
value.dscale = (uint16) pq_getmsgint(buf, sizeof(uint16));
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
NumericDigit d = pq_getmsgint(buf, sizeof(NumericDigit));
|
||||
NumericDigit d = pq_getmsgint(buf, sizeof(NumericDigit));
|
||||
|
||||
if (d < 0 || d >= NBASE)
|
||||
ereport(ERROR,
|
||||
@@ -1081,8 +1089,8 @@ numeric_mul(PG_FUNCTION_ARGS)
|
||||
|
||||
/*
|
||||
* Unpack the values, let mul_var() compute the result and return it.
|
||||
* Unlike add_var() and sub_var(), mul_var() will round its result.
|
||||
* In the case of numeric_mul(), which is invoked for the * operator on
|
||||
* Unlike add_var() and sub_var(), mul_var() will round its result. In
|
||||
* the case of numeric_mul(), which is invoked for the * operator on
|
||||
* numerics, we request exact representation for the product (rscale =
|
||||
* sum(dscale of arg1, dscale of arg2)).
|
||||
*/
|
||||
@@ -1303,7 +1311,7 @@ numeric_sqrt(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_NUMERIC(make_result(&const_nan));
|
||||
|
||||
/*
|
||||
* Unpack the argument and determine the result scale. We choose a
|
||||
* Unpack the argument and determine the result scale. We choose a
|
||||
* scale to give at least NUMERIC_MIN_SIG_DIGITS significant digits;
|
||||
* but in any case not less than the input's dscale.
|
||||
*/
|
||||
@@ -1356,7 +1364,7 @@ numeric_exp(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_NUMERIC(make_result(&const_nan));
|
||||
|
||||
/*
|
||||
* Unpack the argument and determine the result scale. We choose a
|
||||
* Unpack the argument and determine the result scale. We choose a
|
||||
* scale to give at least NUMERIC_MIN_SIG_DIGITS significant digits;
|
||||
* but in any case not less than the input's dscale.
|
||||
*/
|
||||
@@ -1369,8 +1377,8 @@ numeric_exp(PG_FUNCTION_ARGS)
|
||||
val = numericvar_to_double_no_overflow(&arg);
|
||||
|
||||
/*
|
||||
* log10(result) = num * log10(e), so this is approximately the decimal
|
||||
* weight of the result:
|
||||
* log10(result) = num * log10(e), so this is approximately the
|
||||
* decimal weight of the result:
|
||||
*/
|
||||
val *= 0.434294481903252;
|
||||
|
||||
@@ -2055,7 +2063,7 @@ numeric_variance(PG_FUNCTION_ARGS)
|
||||
}
|
||||
else
|
||||
{
|
||||
mul_var(&vN, &vNminus1, &vNminus1, 0); /* N * (N - 1) */
|
||||
mul_var(&vN, &vNminus1, &vNminus1, 0); /* N * (N - 1) */
|
||||
rscale = select_div_scale(&vsumX2, &vNminus1);
|
||||
div_var(&vsumX2, &vNminus1, &vsumX, rscale); /* variance */
|
||||
|
||||
@@ -2131,7 +2139,7 @@ numeric_stddev(PG_FUNCTION_ARGS)
|
||||
}
|
||||
else
|
||||
{
|
||||
mul_var(&vN, &vNminus1, &vNminus1, 0); /* N * (N - 1) */
|
||||
mul_var(&vN, &vNminus1, &vNminus1, 0); /* N * (N - 1) */
|
||||
rscale = select_div_scale(&vsumX2, &vNminus1);
|
||||
div_var(&vsumX2, &vNminus1, &vsumX, rscale); /* variance */
|
||||
sqrt_var(&vsumX, &vsumX, rscale); /* stddev */
|
||||
@@ -2409,7 +2417,6 @@ dump_var(const char *str, NumericVar *var)
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
#endif /* NUMERIC_DEBUG */
|
||||
|
||||
|
||||
@@ -2434,7 +2441,7 @@ alloc_var(NumericVar *var, int ndigits)
|
||||
{
|
||||
digitbuf_free(var->buf);
|
||||
var->buf = digitbuf_alloc(ndigits + 1);
|
||||
var->buf[0] = 0; /* spare digit for rounding */
|
||||
var->buf[0] = 0; /* spare digit for rounding */
|
||||
var->digits = var->buf + 1;
|
||||
var->ndigits = ndigits;
|
||||
}
|
||||
@@ -2495,8 +2502,8 @@ set_var_from_str(const char *str, NumericVar *dest)
|
||||
NumericDigit *digits;
|
||||
|
||||
/*
|
||||
* We first parse the string to extract decimal digits and determine the
|
||||
* correct decimal weight. Then convert to NBASE representation.
|
||||
* We first parse the string to extract decimal digits and determine
|
||||
* the correct decimal weight. Then convert to NBASE representation.
|
||||
*/
|
||||
|
||||
/* skip leading spaces */
|
||||
@@ -2529,9 +2536,9 @@ set_var_from_str(const char *str, NumericVar *dest)
|
||||
if (!isdigit((unsigned char) *cp))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for numeric: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for numeric: \"%s\"", str)));
|
||||
|
||||
decdigits = (unsigned char *) palloc(strlen(cp) + DEC_DIGITS*2);
|
||||
decdigits = (unsigned char *) palloc(strlen(cp) + DEC_DIGITS * 2);
|
||||
|
||||
/* leading padding for digit alignment later */
|
||||
memset(decdigits, 0, DEC_DIGITS);
|
||||
@@ -2552,8 +2559,8 @@ set_var_from_str(const char *str, NumericVar *dest)
|
||||
if (have_dp)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for numeric: \"%s\"",
|
||||
str)));
|
||||
errmsg("invalid input syntax for numeric: \"%s\"",
|
||||
str)));
|
||||
have_dp = TRUE;
|
||||
cp++;
|
||||
}
|
||||
@@ -2563,7 +2570,7 @@ set_var_from_str(const char *str, NumericVar *dest)
|
||||
|
||||
ddigits = i - DEC_DIGITS;
|
||||
/* trailing padding for digit alignment later */
|
||||
memset(decdigits + i, 0, DEC_DIGITS-1);
|
||||
memset(decdigits + i, 0, DEC_DIGITS - 1);
|
||||
|
||||
/* Handle exponent, if any */
|
||||
if (*cp == 'e' || *cp == 'E')
|
||||
@@ -2604,16 +2611,16 @@ set_var_from_str(const char *str, NumericVar *dest)
|
||||
|
||||
/*
|
||||
* Okay, convert pure-decimal representation to base NBASE. First we
|
||||
* need to determine the converted weight and ndigits. offset is the
|
||||
* need to determine the converted weight and ndigits. offset is the
|
||||
* number of decimal zeroes to insert before the first given digit to
|
||||
* have a correctly aligned first NBASE digit.
|
||||
*/
|
||||
if (dweight >= 0)
|
||||
weight = (dweight + 1 + DEC_DIGITS-1) / DEC_DIGITS - 1;
|
||||
weight = (dweight + 1 + DEC_DIGITS - 1) / DEC_DIGITS - 1;
|
||||
else
|
||||
weight = - ((-dweight - 1) / DEC_DIGITS + 1);
|
||||
weight = -((-dweight - 1) / DEC_DIGITS + 1);
|
||||
offset = (weight + 1) * DEC_DIGITS - (dweight + 1);
|
||||
ndigits = (ddigits + offset + DEC_DIGITS-1) / DEC_DIGITS;
|
||||
ndigits = (ddigits + offset + DEC_DIGITS - 1) / DEC_DIGITS;
|
||||
|
||||
alloc_var(dest, ndigits);
|
||||
dest->sign = sign;
|
||||
@@ -2626,10 +2633,10 @@ set_var_from_str(const char *str, NumericVar *dest)
|
||||
while (ndigits-- > 0)
|
||||
{
|
||||
#if DEC_DIGITS == 4
|
||||
*digits++ = ((decdigits[i] * 10 + decdigits[i+1]) * 10 +
|
||||
decdigits[i+2]) * 10 + decdigits[i+3];
|
||||
*digits++ = ((decdigits[i] * 10 + decdigits[i + 1]) * 10 +
|
||||
decdigits[i + 2]) * 10 + decdigits[i + 3];
|
||||
#elif DEC_DIGITS == 2
|
||||
*digits++ = decdigits[i] * 10 + decdigits[i+1];
|
||||
*digits++ = decdigits[i] * 10 + decdigits[i + 1];
|
||||
#elif DEC_DIGITS == 1
|
||||
*digits++ = decdigits[i];
|
||||
#else
|
||||
@@ -2704,9 +2711,10 @@ get_str_from_var(NumericVar *var, int dscale)
|
||||
char *endcp;
|
||||
int i;
|
||||
int d;
|
||||
NumericDigit dig;
|
||||
NumericDigit dig;
|
||||
|
||||
#if DEC_DIGITS > 1
|
||||
NumericDigit d1;
|
||||
NumericDigit d1;
|
||||
#endif
|
||||
|
||||
if (dscale < 0)
|
||||
@@ -2720,10 +2728,10 @@ get_str_from_var(NumericVar *var, int dscale)
|
||||
/*
|
||||
* Allocate space for the result.
|
||||
*
|
||||
* i is set to to # of decimal digits before decimal point.
|
||||
* dscale is the # of decimal digits we will print after decimal point.
|
||||
* We may generate as many as DEC_DIGITS-1 excess digits at the end,
|
||||
* and in addition we need room for sign, decimal point, null terminator.
|
||||
* i is set to to # of decimal digits before decimal point. dscale is the
|
||||
* # of decimal digits we will print after decimal point. We may
|
||||
* generate as many as DEC_DIGITS-1 excess digits at the end, and in
|
||||
* addition we need room for sign, decimal point, null terminator.
|
||||
*/
|
||||
i = (var->weight + 1) * DEC_DIGITS;
|
||||
if (i <= 0)
|
||||
@@ -2754,7 +2762,7 @@ get_str_from_var(NumericVar *var, int dscale)
|
||||
/* In the first digit, suppress extra leading decimal zeroes */
|
||||
#if DEC_DIGITS == 4
|
||||
{
|
||||
bool putit = (d > 0);
|
||||
bool putit = (d > 0);
|
||||
|
||||
d1 = dig / 1000;
|
||||
dig -= d1 * 1000;
|
||||
@@ -2789,7 +2797,7 @@ get_str_from_var(NumericVar *var, int dscale)
|
||||
|
||||
/*
|
||||
* If requested, output a decimal point and all the digits that follow
|
||||
* it. We initially put out a multiple of DEC_DIGITS digits, then
|
||||
* it. We initially put out a multiple of DEC_DIGITS digits, then
|
||||
* truncate if needed.
|
||||
*/
|
||||
if (dscale > 0)
|
||||
@@ -2966,7 +2974,7 @@ apply_typmod(NumericVar *var, int32 typmod)
|
||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||
errmsg("numeric field overflow"),
|
||||
errdetail("ABS(value) >= 10^%d for field with precision %d, scale %d.",
|
||||
ddigits-1, precision, scale)));
|
||||
ddigits - 1, precision, scale)));
|
||||
break;
|
||||
}
|
||||
ddigits -= DEC_DIGITS;
|
||||
@@ -2977,7 +2985,7 @@ apply_typmod(NumericVar *var, int32 typmod)
|
||||
/*
|
||||
* Convert numeric to int8, rounding if needed.
|
||||
*
|
||||
* If overflow, return FALSE (no error is raised). Return TRUE if okay.
|
||||
* If overflow, return FALSE (no error is raised). Return TRUE if okay.
|
||||
*
|
||||
* CAUTION: var's contents may be modified by rounding!
|
||||
*/
|
||||
@@ -3006,10 +3014,11 @@ numericvar_to_int8(NumericVar *var, int64 *result)
|
||||
|
||||
/*
|
||||
* For input like 10000000000, we must treat stripped digits as real.
|
||||
* So the loop assumes there are weight+1 digits before the decimal point.
|
||||
* So the loop assumes there are weight+1 digits before the decimal
|
||||
* point.
|
||||
*/
|
||||
weight = var->weight;
|
||||
Assert(weight >= 0 && ndigits <= weight+1);
|
||||
Assert(weight >= 0 && ndigits <= weight + 1);
|
||||
|
||||
/* Construct the result */
|
||||
digits = var->digits;
|
||||
@@ -3021,6 +3030,7 @@ numericvar_to_int8(NumericVar *var, int64 *result)
|
||||
val *= NBASE;
|
||||
if (i < ndigits)
|
||||
val += digits[i];
|
||||
|
||||
/*
|
||||
* The overflow check is a bit tricky because we want to accept
|
||||
* INT64_MIN, which will overflow the positive accumulator. We
|
||||
@@ -3051,7 +3061,7 @@ int8_to_numericvar(int64 val, NumericVar *var)
|
||||
int ndigits;
|
||||
|
||||
/* int8 can require at most 19 decimal digits; add one for safety */
|
||||
alloc_var(var, 20/DEC_DIGITS);
|
||||
alloc_var(var, 20 / DEC_DIGITS);
|
||||
if (val < 0)
|
||||
{
|
||||
var->sign = NUMERIC_NEG;
|
||||
@@ -3071,7 +3081,8 @@ int8_to_numericvar(int64 val, NumericVar *var)
|
||||
}
|
||||
ptr = var->digits + var->ndigits;
|
||||
ndigits = 0;
|
||||
do {
|
||||
do
|
||||
{
|
||||
ptr--;
|
||||
ndigits++;
|
||||
newuval = uval / NBASE;
|
||||
@@ -3420,7 +3431,7 @@ sub_var(NumericVar *var1, NumericVar *var2, NumericVar *result)
|
||||
* mul_var() -
|
||||
*
|
||||
* Multiplication on variable level. Product of var1 * var2 is stored
|
||||
* in result. Result is rounded to no more than rscale fractional digits.
|
||||
* in result. Result is rounded to no more than rscale fractional digits.
|
||||
*/
|
||||
static void
|
||||
mul_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
@@ -3439,6 +3450,7 @@ mul_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
ri,
|
||||
i1,
|
||||
i2;
|
||||
|
||||
/* copy these values into local vars for speed in inner loop */
|
||||
int var1ndigits = var1->ndigits;
|
||||
int var2ndigits = var2->ndigits;
|
||||
@@ -3462,9 +3474,10 @@ mul_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
|
||||
/*
|
||||
* Determine number of result digits to compute. If the exact result
|
||||
* would have more than rscale fractional digits, truncate the computation
|
||||
* with MUL_GUARD_DIGITS guard digits. We do that by pretending that
|
||||
* one or both inputs have fewer digits than they really do.
|
||||
* would have more than rscale fractional digits, truncate the
|
||||
* computation with MUL_GUARD_DIGITS guard digits. We do that by
|
||||
* pretending that one or both inputs have fewer digits than they
|
||||
* really do.
|
||||
*/
|
||||
res_ndigits = var1ndigits + var2ndigits + 1;
|
||||
maxdigits = res_weight + 1 + (rscale * DEC_DIGITS) + MUL_GUARD_DIGITS;
|
||||
@@ -3498,13 +3511,13 @@ mul_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
|
||||
/*
|
||||
* We do the arithmetic in an array "dig[]" of signed int's. Since
|
||||
* INT_MAX is noticeably larger than NBASE*NBASE, this gives us headroom
|
||||
* to avoid normalizing carries immediately.
|
||||
* INT_MAX is noticeably larger than NBASE*NBASE, this gives us
|
||||
* headroom to avoid normalizing carries immediately.
|
||||
*
|
||||
* maxdig tracks the maximum possible value of any dig[] entry;
|
||||
* when this threatens to exceed INT_MAX, we take the time to propagate
|
||||
* carries. To avoid overflow in maxdig itself, it actually represents
|
||||
* the max possible value divided by NBASE-1.
|
||||
* maxdig tracks the maximum possible value of any dig[] entry; when this
|
||||
* threatens to exceed INT_MAX, we take the time to propagate carries.
|
||||
* To avoid overflow in maxdig itself, it actually represents the max
|
||||
* possible value divided by NBASE-1.
|
||||
*/
|
||||
dig = (int *) palloc0(res_ndigits * sizeof(int));
|
||||
maxdig = 0;
|
||||
@@ -3512,24 +3525,24 @@ mul_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
ri = res_ndigits - 1;
|
||||
for (i1 = var1ndigits - 1; i1 >= 0; ri--, i1--)
|
||||
{
|
||||
int var1digit = var1digits[i1];
|
||||
int var1digit = var1digits[i1];
|
||||
|
||||
if (var1digit == 0)
|
||||
continue;
|
||||
|
||||
/* Time to normalize? */
|
||||
maxdig += var1digit;
|
||||
if (maxdig > INT_MAX/(NBASE-1))
|
||||
if (maxdig > INT_MAX / (NBASE - 1))
|
||||
{
|
||||
/* Yes, do it */
|
||||
carry = 0;
|
||||
for (i = res_ndigits-1; i >= 0; i--)
|
||||
for (i = res_ndigits - 1; i >= 0; i--)
|
||||
{
|
||||
newdig = dig[i] + carry;
|
||||
if (newdig >= NBASE)
|
||||
{
|
||||
carry = newdig/NBASE;
|
||||
newdig -= carry*NBASE;
|
||||
carry = newdig / NBASE;
|
||||
newdig -= carry * NBASE;
|
||||
}
|
||||
else
|
||||
carry = 0;
|
||||
@@ -3543,9 +3556,7 @@ mul_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
/* Add appropriate multiple of var2 into the accumulator */
|
||||
i = ri;
|
||||
for (i2 = var2ndigits - 1; i2 >= 0; i2--)
|
||||
{
|
||||
dig[i--] += var1digit * var2digits[i2];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3556,13 +3567,13 @@ mul_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
alloc_var(result, res_ndigits);
|
||||
res_digits = result->digits;
|
||||
carry = 0;
|
||||
for (i = res_ndigits-1; i >= 0; i--)
|
||||
for (i = res_ndigits - 1; i >= 0; i--)
|
||||
{
|
||||
newdig = dig[i] + carry;
|
||||
if (newdig >= NBASE)
|
||||
{
|
||||
carry = newdig/NBASE;
|
||||
newdig -= carry*NBASE;
|
||||
carry = newdig / NBASE;
|
||||
newdig -= carry * NBASE;
|
||||
}
|
||||
else
|
||||
carry = 0;
|
||||
@@ -3590,7 +3601,7 @@ mul_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
* div_var() -
|
||||
*
|
||||
* Division on variable level. Quotient of var1 / var2 is stored
|
||||
* in result. Result is rounded to no more than rscale fractional digits.
|
||||
* in result. Result is rounded to no more than rscale fractional digits.
|
||||
*/
|
||||
static void
|
||||
div_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
@@ -3611,6 +3622,7 @@ div_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
fquotient;
|
||||
int qi;
|
||||
int i;
|
||||
|
||||
/* copy these values into local vars for speed in inner loop */
|
||||
int var1ndigits = var1->ndigits;
|
||||
int var2ndigits = var2->ndigits;
|
||||
@@ -3645,7 +3657,7 @@ div_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
res_sign = NUMERIC_NEG;
|
||||
res_weight = var1->weight - var2->weight + 1;
|
||||
/* The number of accurate result digits we need to produce: */
|
||||
div_ndigits = res_weight + 1 + (rscale + DEC_DIGITS-1)/DEC_DIGITS;
|
||||
div_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
|
||||
/* Add guard digits for roundoff error */
|
||||
div_ndigits += DIV_GUARD_DIGITS;
|
||||
if (div_ndigits < DIV_GUARD_DIGITS)
|
||||
@@ -3656,8 +3668,8 @@ div_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
|
||||
/*
|
||||
* We do the arithmetic in an array "div[]" of signed int's. Since
|
||||
* INT_MAX is noticeably larger than NBASE*NBASE, this gives us headroom
|
||||
* to avoid normalizing carries immediately.
|
||||
* INT_MAX is noticeably larger than NBASE*NBASE, this gives us
|
||||
* headroom to avoid normalizing carries immediately.
|
||||
*
|
||||
* We start with div[] containing one zero digit followed by the
|
||||
* dividend's digits (plus appended zeroes to reach the desired
|
||||
@@ -3668,7 +3680,7 @@ div_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
*/
|
||||
div = (int *) palloc0((div_ndigits + 1) * sizeof(int));
|
||||
for (i = 0; i < var1ndigits; i++)
|
||||
div[i+1] = var1digits[i];
|
||||
div[i + 1] = var1digits[i];
|
||||
|
||||
/*
|
||||
* We estimate each quotient digit using floating-point arithmetic,
|
||||
@@ -3685,10 +3697,10 @@ div_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
fdivisorinverse = 1.0 / fdivisor;
|
||||
|
||||
/*
|
||||
* maxdiv tracks the maximum possible absolute value of any div[] entry;
|
||||
* when this threatens to exceed INT_MAX, we take the time to propagate
|
||||
* carries. To avoid overflow in maxdiv itself, it actually represents
|
||||
* the max possible abs. value divided by NBASE-1.
|
||||
* maxdiv tracks the maximum possible absolute value of any div[]
|
||||
* entry; when this threatens to exceed INT_MAX, we take the time to
|
||||
* propagate carries. To avoid overflow in maxdiv itself, it actually
|
||||
* represents the max possible abs. value divided by NBASE-1.
|
||||
*/
|
||||
maxdiv = 1;
|
||||
|
||||
@@ -3702,19 +3714,19 @@ div_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
for (i = 1; i < 4; i++)
|
||||
{
|
||||
fdividend *= NBASE;
|
||||
if (qi+i <= div_ndigits)
|
||||
fdividend += (double) div[qi+i];
|
||||
if (qi + i <= div_ndigits)
|
||||
fdividend += (double) div[qi + i];
|
||||
}
|
||||
/* Compute the (approximate) quotient digit */
|
||||
fquotient = fdividend * fdivisorinverse;
|
||||
qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
|
||||
(((int) fquotient) - 1); /* truncate towards -infinity */
|
||||
(((int) fquotient) - 1); /* truncate towards -infinity */
|
||||
|
||||
if (qdigit != 0)
|
||||
{
|
||||
/* Do we need to normalize now? */
|
||||
maxdiv += Abs(qdigit);
|
||||
if (maxdiv > INT_MAX/(NBASE-1))
|
||||
if (maxdiv > INT_MAX / (NBASE - 1))
|
||||
{
|
||||
/* Yes, do it */
|
||||
carry = 0;
|
||||
@@ -3723,13 +3735,13 @@ div_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
newdig = div[i] + carry;
|
||||
if (newdig < 0)
|
||||
{
|
||||
carry = -((-newdig-1)/NBASE) - 1;
|
||||
newdig -= carry*NBASE;
|
||||
carry = -((-newdig - 1) / NBASE) - 1;
|
||||
newdig -= carry * NBASE;
|
||||
}
|
||||
else if (newdig >= NBASE)
|
||||
{
|
||||
carry = newdig/NBASE;
|
||||
newdig -= carry*NBASE;
|
||||
carry = newdig / NBASE;
|
||||
newdig -= carry * NBASE;
|
||||
}
|
||||
else
|
||||
carry = 0;
|
||||
@@ -3737,12 +3749,14 @@ div_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
}
|
||||
newdig = div[qi] + carry;
|
||||
div[qi] = newdig;
|
||||
|
||||
/*
|
||||
* All the div[] digits except possibly div[qi] are now
|
||||
* in the range 0..NBASE-1.
|
||||
* All the div[] digits except possibly div[qi] are now in
|
||||
* the range 0..NBASE-1.
|
||||
*/
|
||||
maxdiv = Abs(newdig) / (NBASE-1);
|
||||
maxdiv = Abs(newdig) / (NBASE - 1);
|
||||
maxdiv = Max(maxdiv, 1);
|
||||
|
||||
/*
|
||||
* Recompute the quotient digit since new info may have
|
||||
* propagated into the top four dividend digits
|
||||
@@ -3751,33 +3765,34 @@ div_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
for (i = 1; i < 4; i++)
|
||||
{
|
||||
fdividend *= NBASE;
|
||||
if (qi+i <= div_ndigits)
|
||||
fdividend += (double) div[qi+i];
|
||||
if (qi + i <= div_ndigits)
|
||||
fdividend += (double) div[qi + i];
|
||||
}
|
||||
/* Compute the (approximate) quotient digit */
|
||||
fquotient = fdividend * fdivisorinverse;
|
||||
qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
|
||||
(((int) fquotient) - 1); /* truncate towards -infinity */
|
||||
(((int) fquotient) - 1); /* truncate towards
|
||||
* -infinity */
|
||||
maxdiv += Abs(qdigit);
|
||||
}
|
||||
|
||||
/* Subtract off the appropriate multiple of the divisor */
|
||||
if (qdigit != 0)
|
||||
{
|
||||
int istop = Min(var2ndigits, div_ndigits-qi+1);
|
||||
int istop = Min(var2ndigits, div_ndigits - qi + 1);
|
||||
|
||||
for (i = 0; i < istop; i++)
|
||||
div[qi+i] -= qdigit * var2digits[i];
|
||||
div[qi + i] -= qdigit * var2digits[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The dividend digit we are about to replace might still be nonzero.
|
||||
* Fold it into the next digit position. We don't need to worry about
|
||||
* overflow here since this should nearly cancel with the subtraction
|
||||
* of the divisor.
|
||||
* The dividend digit we are about to replace might still be
|
||||
* nonzero. Fold it into the next digit position. We don't need
|
||||
* to worry about overflow here since this should nearly cancel
|
||||
* with the subtraction of the divisor.
|
||||
*/
|
||||
div[qi+1] += div[qi] * NBASE;
|
||||
div[qi + 1] += div[qi] * NBASE;
|
||||
|
||||
div[qi] = qdigit;
|
||||
}
|
||||
@@ -3787,12 +3802,10 @@ div_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
*/
|
||||
fdividend = (double) div[qi];
|
||||
for (i = 1; i < 4; i++)
|
||||
{
|
||||
fdividend *= NBASE;
|
||||
}
|
||||
fquotient = fdividend * fdivisorinverse;
|
||||
qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
|
||||
(((int) fquotient) - 1); /* truncate towards -infinity */
|
||||
(((int) fquotient) - 1); /* truncate towards -infinity */
|
||||
div[qi] = qdigit;
|
||||
|
||||
/*
|
||||
@@ -3800,7 +3813,7 @@ div_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
* which we combine with storing the result digits into the output.
|
||||
* Note that this is still done at full precision w/guard digits.
|
||||
*/
|
||||
alloc_var(result, div_ndigits+1);
|
||||
alloc_var(result, div_ndigits + 1);
|
||||
res_digits = result->digits;
|
||||
carry = 0;
|
||||
for (i = div_ndigits; i >= 0; i--)
|
||||
@@ -3808,13 +3821,13 @@ div_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
|
||||
newdig = div[i] + carry;
|
||||
if (newdig < 0)
|
||||
{
|
||||
carry = -((-newdig-1)/NBASE) - 1;
|
||||
newdig -= carry*NBASE;
|
||||
carry = -((-newdig - 1) / NBASE) - 1;
|
||||
newdig -= carry * NBASE;
|
||||
}
|
||||
else if (newdig >= NBASE)
|
||||
{
|
||||
carry = newdig/NBASE;
|
||||
newdig -= carry*NBASE;
|
||||
carry = newdig / NBASE;
|
||||
newdig -= carry * NBASE;
|
||||
}
|
||||
else
|
||||
carry = 0;
|
||||
@@ -3889,8 +3902,8 @@ select_div_scale(NumericVar *var1, NumericVar *var2)
|
||||
}
|
||||
|
||||
/*
|
||||
* Estimate weight of quotient. If the two first digits are equal,
|
||||
* we can't be sure, but assume that var1 is less than var2.
|
||||
* Estimate weight of quotient. If the two first digits are equal, we
|
||||
* can't be sure, but assume that var1 is less than var2.
|
||||
*/
|
||||
qweight = weight1 - weight2;
|
||||
if (firstdigit1 <= firstdigit2)
|
||||
@@ -4176,16 +4189,17 @@ exp_var_internal(NumericVar *arg, NumericVar *result, int rscale)
|
||||
{
|
||||
ndiv2++;
|
||||
local_rscale++;
|
||||
mul_var(&x, &const_zero_point_five, &x, x.dscale+1);
|
||||
mul_var(&x, &const_zero_point_five, &x, x.dscale + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the Taylor series
|
||||
*
|
||||
* exp(x) = 1 + x + x^2/2! + x^3/3! + ...
|
||||
* exp(x) = 1 + x + x^2/2! + x^3/3! + ...
|
||||
*
|
||||
* Given the limited range of x, this should converge reasonably quickly.
|
||||
* We run the series until the terms fall below the local_rscale limit.
|
||||
* We run the series until the terms fall below the local_rscale
|
||||
* limit.
|
||||
*/
|
||||
add_var(&const_one, &x, result);
|
||||
set_var_from_var(&x, &xpow);
|
||||
@@ -4265,7 +4279,7 @@ ln_var(NumericVar *arg, NumericVar *result, int rscale)
|
||||
/*
|
||||
* We use the Taylor series for 0.5 * ln((1+z)/(1-z)),
|
||||
*
|
||||
* z + z^3/3 + z^5/5 + ...
|
||||
* z + z^3/3 + z^5/5 + ...
|
||||
*
|
||||
* where z = (x-1)/(x+1) is in the range (approximately) -0.053 .. 0.048
|
||||
* due to the above range-reduction of x.
|
||||
@@ -4292,7 +4306,7 @@ ln_var(NumericVar *arg, NumericVar *result, int rscale)
|
||||
|
||||
add_var(result, &elem, result);
|
||||
|
||||
if (elem.weight < (result->weight - local_rscale * 2/DEC_DIGITS))
|
||||
if (elem.weight < (result->weight - local_rscale * 2 / DEC_DIGITS))
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4391,7 +4405,7 @@ power_var(NumericVar *base, NumericVar *exp, NumericVar *result)
|
||||
set_var_from_var(exp, &x);
|
||||
if (numericvar_to_int8(&x, &expval64))
|
||||
{
|
||||
int expval = (int) expval64;
|
||||
int expval = (int) expval64;
|
||||
|
||||
/* Test for overflow by reverse-conversion. */
|
||||
if ((int64) expval == expval64)
|
||||
@@ -4420,11 +4434,11 @@ power_var(NumericVar *base, NumericVar *exp, NumericVar *result)
|
||||
dec_digits = (base->weight + 1) * DEC_DIGITS;
|
||||
|
||||
if (dec_digits > 1)
|
||||
rscale = NUMERIC_MIN_SIG_DIGITS*2 - (int) log10(dec_digits - 1);
|
||||
rscale = NUMERIC_MIN_SIG_DIGITS * 2 - (int) log10(dec_digits - 1);
|
||||
else if (dec_digits < 1)
|
||||
rscale = NUMERIC_MIN_SIG_DIGITS*2 - (int) log10(1 - dec_digits);
|
||||
rscale = NUMERIC_MIN_SIG_DIGITS * 2 - (int) log10(1 - dec_digits);
|
||||
else
|
||||
rscale = NUMERIC_MIN_SIG_DIGITS*2;
|
||||
rscale = NUMERIC_MIN_SIG_DIGITS * 2;
|
||||
|
||||
rscale = Max(rscale, base->dscale * 2);
|
||||
rscale = Max(rscale, exp->dscale * 2);
|
||||
@@ -4442,7 +4456,10 @@ power_var(NumericVar *base, NumericVar *exp, NumericVar *result)
|
||||
/* convert input to float8, ignoring overflow */
|
||||
val = numericvar_to_double_no_overflow(&ln_num);
|
||||
|
||||
/* log10(result) = num * log10(e), so this is approximately the weight: */
|
||||
/*
|
||||
* log10(result) = num * log10(e), so this is approximately the
|
||||
* weight:
|
||||
*/
|
||||
val *= 0.434294481903252;
|
||||
|
||||
/* limit to something that won't cause integer overflow */
|
||||
@@ -4483,7 +4500,7 @@ power_var_int(NumericVar *base, int exp, NumericVar *result, int rscale)
|
||||
(errcode(ERRCODE_FLOATING_POINT_EXCEPTION),
|
||||
errmsg("zero raised to zero is undefined")));
|
||||
set_var_from_var(&const_one, result);
|
||||
result->dscale = rscale; /* no need to round */
|
||||
result->dscale = rscale; /* no need to round */
|
||||
return;
|
||||
case 1:
|
||||
set_var_from_var(base, result);
|
||||
@@ -4500,8 +4517,8 @@ power_var_int(NumericVar *base, int exp, NumericVar *result, int rscale)
|
||||
}
|
||||
|
||||
/*
|
||||
* The general case repeatedly multiplies base according to the
|
||||
* bit pattern of exp. We do the multiplications with some extra
|
||||
* The general case repeatedly multiplies base according to the bit
|
||||
* pattern of exp. We do the multiplications with some extra
|
||||
* precision.
|
||||
*/
|
||||
neg = (exp < 0);
|
||||
@@ -4595,8 +4612,8 @@ cmp_abs(NumericVar *var1, NumericVar *var2)
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, we've run out of digits on one side or the other;
|
||||
* so any remaining nonzero digits imply that side is larger
|
||||
* At this point, we've run out of digits on one side or the other; so
|
||||
* any remaining nonzero digits imply that side is larger
|
||||
*/
|
||||
while (i1 < var1->ndigits)
|
||||
{
|
||||
@@ -4789,7 +4806,7 @@ sub_abs(NumericVar *var1, NumericVar *var2, NumericVar *result)
|
||||
static void
|
||||
round_var(NumericVar *var, int rscale)
|
||||
{
|
||||
NumericDigit *digits = var->digits;
|
||||
NumericDigit *digits = var->digits;
|
||||
int di;
|
||||
int ndigits;
|
||||
int carry;
|
||||
@@ -4800,8 +4817,8 @@ round_var(NumericVar *var, int rscale)
|
||||
di = (var->weight + 1) * DEC_DIGITS + rscale;
|
||||
|
||||
/*
|
||||
* If di = 0, the value loses all digits, but could round up to 1
|
||||
* if its first extra digit is >= 5. If di < 0 the result must be 0.
|
||||
* If di = 0, the value loses all digits, but could round up to 1 if
|
||||
* its first extra digit is >= 5. If di < 0 the result must be 0.
|
||||
*/
|
||||
if (di < 0)
|
||||
{
|
||||
@@ -4812,7 +4829,7 @@ round_var(NumericVar *var, int rscale)
|
||||
else
|
||||
{
|
||||
/* NBASE digits wanted */
|
||||
ndigits = (di + DEC_DIGITS-1) / DEC_DIGITS;
|
||||
ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
|
||||
|
||||
/* 0, or number of decimal digits to keep in last NBASE digit */
|
||||
di %= DEC_DIGITS;
|
||||
@@ -4827,14 +4844,12 @@ round_var(NumericVar *var, int rscale)
|
||||
carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
|
||||
#else
|
||||
if (di == 0)
|
||||
{
|
||||
carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Must round within last NBASE digit */
|
||||
int extra,
|
||||
pow10;
|
||||
int extra,
|
||||
pow10;
|
||||
|
||||
#if DEC_DIGITS == 4
|
||||
pow10 = round_powers[di];
|
||||
@@ -4846,7 +4861,7 @@ round_var(NumericVar *var, int rscale)
|
||||
extra = digits[--ndigits] % pow10;
|
||||
digits[ndigits] -= extra;
|
||||
carry = 0;
|
||||
if (extra >= pow10/2)
|
||||
if (extra >= pow10 / 2)
|
||||
{
|
||||
pow10 += digits[ndigits];
|
||||
if (pow10 >= NBASE)
|
||||
@@ -4917,7 +4932,7 @@ trunc_var(NumericVar *var, int rscale)
|
||||
else
|
||||
{
|
||||
/* NBASE digits wanted */
|
||||
ndigits = (di + DEC_DIGITS-1) / DEC_DIGITS;
|
||||
ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
|
||||
|
||||
if (ndigits <= var->ndigits)
|
||||
{
|
||||
@@ -4932,9 +4947,9 @@ trunc_var(NumericVar *var, int rscale)
|
||||
if (di > 0)
|
||||
{
|
||||
/* Must truncate within last NBASE digit */
|
||||
NumericDigit *digits = var->digits;
|
||||
int extra,
|
||||
pow10;
|
||||
NumericDigit *digits = var->digits;
|
||||
int extra,
|
||||
pow10;
|
||||
|
||||
#if DEC_DIGITS == 4
|
||||
pow10 = round_powers[di];
|
||||
@@ -4959,7 +4974,7 @@ trunc_var(NumericVar *var, int rscale)
|
||||
static void
|
||||
strip_var(NumericVar *var)
|
||||
{
|
||||
NumericDigit *digits = var->digits;
|
||||
NumericDigit *digits = var->digits;
|
||||
int ndigits = var->ndigits;
|
||||
|
||||
/* Strip leading zeroes */
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/numutils.c,v 1.55 2003/07/27 04:53:07 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/numutils.c,v 1.56 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -96,7 +96,7 @@ pg_atoi(char *s, int size, int c)
|
||||
case sizeof(int32):
|
||||
if (errno == ERANGE
|
||||
#if defined(HAVE_LONG_INT_64)
|
||||
/* won't get ERANGE on these with 64-bit longs... */
|
||||
/* won't get ERANGE on these with 64-bit longs... */
|
||||
|| l < INT_MIN || l > INT_MAX
|
||||
#endif
|
||||
)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/oid.c,v 1.49 2003/07/27 04:53:07 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/oid.c,v 1.50 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -222,9 +222,7 @@ oidvectorrecv(PG_FUNCTION_ARGS)
|
||||
int slot;
|
||||
|
||||
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
|
||||
{
|
||||
result[slot] = (Oid) pq_getmsgint(buf, sizeof(Oid));
|
||||
}
|
||||
PG_RETURN_POINTER(result);
|
||||
}
|
||||
|
||||
@@ -240,9 +238,7 @@ oidvectorsend(PG_FUNCTION_ARGS)
|
||||
|
||||
pq_begintypsend(&buf);
|
||||
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
|
||||
{
|
||||
pq_sendint(&buf, oidArray[slot], sizeof(Oid));
|
||||
}
|
||||
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/oracle_compat.c,v 1.46 2003/07/27 04:53:07 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/oracle_compat.c,v 1.47 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -22,8 +22,8 @@
|
||||
|
||||
|
||||
static text *dotrim(const char *string, int stringlen,
|
||||
const char *set, int setlen,
|
||||
bool doltrim, bool dortrim);
|
||||
const char *set, int setlen,
|
||||
bool doltrim, bool dortrim);
|
||||
|
||||
|
||||
/********************************************************************
|
||||
@@ -403,8 +403,8 @@ dotrim(const char *string, int stringlen,
|
||||
{
|
||||
/*
|
||||
* In the multibyte-encoding case, build arrays of pointers to
|
||||
* character starts, so that we can avoid inefficient checks in
|
||||
* the inner loops.
|
||||
* character starts, so that we can avoid inefficient checks
|
||||
* in the inner loops.
|
||||
*/
|
||||
const char **stringchars;
|
||||
const char **setchars;
|
||||
@@ -499,13 +499,14 @@ dotrim(const char *string, int stringlen,
|
||||
else
|
||||
{
|
||||
/*
|
||||
* In the single-byte-encoding case, we don't need such overhead.
|
||||
* In the single-byte-encoding case, we don't need such
|
||||
* overhead.
|
||||
*/
|
||||
if (doltrim)
|
||||
{
|
||||
while (stringlen > 0)
|
||||
{
|
||||
char str_ch = *string;
|
||||
char str_ch = *string;
|
||||
|
||||
for (i = 0; i < setlen; i++)
|
||||
{
|
||||
@@ -523,7 +524,7 @@ dotrim(const char *string, int stringlen,
|
||||
{
|
||||
while (stringlen > 0)
|
||||
{
|
||||
char str_ch = string[stringlen - 1];
|
||||
char str_ch = string[stringlen - 1];
|
||||
|
||||
for (i = 0; i < setlen; i++)
|
||||
{
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*
|
||||
* Portions Copyright (c) 2002, PostgreSQL Global Development Group
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v 1.21 2003/07/27 04:53:07 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v 1.22 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -25,7 +25,7 @@
|
||||
* Instead, we only set the locales briefly when needed, cache the
|
||||
* required information obtained from localeconv(), and set them back.
|
||||
* The cached information is only used by the formatting functions
|
||||
* (to_char, etc.) and the money type. For the user, this should all be
|
||||
* (to_char, etc.) and the money type. For the user, this should all be
|
||||
* transparent. (Actually, LC_TIME doesn't do anything at all right
|
||||
* now.)
|
||||
*
|
||||
@@ -40,7 +40,7 @@
|
||||
* fail = true;
|
||||
* setlocale(category, save);
|
||||
* DOES NOT WORK RELIABLY: on some platforms the second setlocale() call
|
||||
* will change the memory save is pointing at. To do this sort of thing
|
||||
* will change the memory save is pointing at. To do this sort of thing
|
||||
* safely, you *must* pstrdup what setlocale returns the first time.
|
||||
*----------
|
||||
*/
|
||||
@@ -134,9 +134,7 @@ locale_messages_assign(const char *value, bool doit, bool interactive)
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = locale_xxx_assign(LC_MESSAGES, value, false, interactive);
|
||||
}
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -308,11 +308,11 @@ pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PgStat_StatBeEntry *beentry;
|
||||
int32 beid;
|
||||
AbsoluteTime sec;
|
||||
int usec;
|
||||
TimestampTz result;
|
||||
PgStat_StatBeEntry *beentry;
|
||||
int32 beid;
|
||||
AbsoluteTime sec;
|
||||
int usec;
|
||||
TimestampTz result;
|
||||
|
||||
beid = PG_GETARG_INT32(0);
|
||||
|
||||
@@ -326,8 +326,8 @@ pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
|
||||
usec = beentry->activity_start_usec;
|
||||
|
||||
/*
|
||||
* No time recorded for start of current query -- this is the case
|
||||
* if the user hasn't enabled query-level stats collection.
|
||||
* No time recorded for start of current query -- this is the case if
|
||||
* the user hasn't enabled query-level stats collection.
|
||||
*/
|
||||
if (sec == 0 && usec == 0)
|
||||
PG_RETURN_NULL();
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/pseudotypes.c,v 1.9 2003/07/28 00:09:16 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/pseudotypes.c,v 1.10 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -191,7 +191,7 @@ anyarray_out(PG_FUNCTION_ARGS)
|
||||
* anyarray_recv - binary input routine for pseudo-type ANYARRAY.
|
||||
*
|
||||
* XXX this could actually be made to work, since the incoming array
|
||||
* data will contain the element type OID. Need to think through
|
||||
* data will contain the element type OID. Need to think through
|
||||
* type-safety issues before allowing it, however.
|
||||
*/
|
||||
Datum
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/regexp.c,v 1.46 2003/07/27 04:53:08 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/regexp.c,v 1.47 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
* Alistair Crooks added the code for the regex caching
|
||||
* agc - cached the regular expressions used - there's a good chance
|
||||
@@ -73,10 +73,10 @@ typedef struct cached_re_str
|
||||
text *cre_pat; /* original RE (untoasted TEXT form) */
|
||||
int cre_flags; /* compile flags: extended,icase etc */
|
||||
regex_t cre_re; /* the compiled regular expression */
|
||||
} cached_re_str;
|
||||
} cached_re_str;
|
||||
|
||||
static int num_res = 0; /* # of cached re's */
|
||||
static cached_re_str re_array[MAX_CACHED_RES]; /* cached re's */
|
||||
static cached_re_str re_array[MAX_CACHED_RES]; /* cached re's */
|
||||
|
||||
|
||||
/*
|
||||
@@ -88,7 +88,7 @@ static cached_re_str re_array[MAX_CACHED_RES]; /* cached re's */
|
||||
* dat --- the data to match against (need not be null-terminated)
|
||||
* dat_len --- the length of the data string
|
||||
* cflags --- compile options for the pattern
|
||||
* nmatch, pmatch --- optional return area for match details
|
||||
* nmatch, pmatch --- optional return area for match details
|
||||
*
|
||||
* Both pattern and data are given in the database encoding. We internally
|
||||
* convert to array of pg_wchar which is what Spencer's regex package wants.
|
||||
@@ -105,14 +105,14 @@ RE_compile_and_execute(text *text_re, unsigned char *dat, int dat_len,
|
||||
int i;
|
||||
int regcomp_result;
|
||||
int regexec_result;
|
||||
cached_re_str re_temp;
|
||||
cached_re_str re_temp;
|
||||
|
||||
/* Convert data string to wide characters */
|
||||
data = (pg_wchar *) palloc((dat_len + 1) * sizeof(pg_wchar));
|
||||
data_len = pg_mb2wchar_with_len(dat, data, dat_len);
|
||||
|
||||
/*
|
||||
* Look for a match among previously compiled REs. Since the data
|
||||
* Look for a match among previously compiled REs. Since the data
|
||||
* structure is self-organizing with most-used entries at the front,
|
||||
* our search strategy can just be to scan from the front.
|
||||
*/
|
||||
@@ -135,7 +135,7 @@ RE_compile_and_execute(text *text_re, unsigned char *dat, int dat_len,
|
||||
regexec_result = pg_regexec(&re_array[0].cre_re,
|
||||
data,
|
||||
data_len,
|
||||
NULL, /* no details */
|
||||
NULL, /* no details */
|
||||
nmatch,
|
||||
pmatch,
|
||||
0);
|
||||
@@ -213,7 +213,7 @@ RE_compile_and_execute(text *text_re, unsigned char *dat, int dat_len,
|
||||
regexec_result = pg_regexec(&re_array[0].cre_re,
|
||||
data,
|
||||
data_len,
|
||||
NULL, /* no details */
|
||||
NULL, /* no details */
|
||||
nmatch,
|
||||
pmatch,
|
||||
0);
|
||||
@@ -383,8 +383,8 @@ textregexsubstr(PG_FUNCTION_ARGS)
|
||||
/*
|
||||
* We pass two regmatch_t structs to get info about the overall match
|
||||
* and the match for the first parenthesized subexpression (if any).
|
||||
* If there is a parenthesized subexpression, we return what it matched;
|
||||
* else return what the whole regexp matched.
|
||||
* If there is a parenthesized subexpression, we return what it
|
||||
* matched; else return what the whole regexp matched.
|
||||
*/
|
||||
match = RE_compile_and_execute(p,
|
||||
(unsigned char *) VARDATA(s),
|
||||
@@ -395,8 +395,8 @@ textregexsubstr(PG_FUNCTION_ARGS)
|
||||
/* match? then return the substring matching the pattern */
|
||||
if (match)
|
||||
{
|
||||
int so,
|
||||
eo;
|
||||
int so,
|
||||
eo;
|
||||
|
||||
so = pmatch[1].rm_so;
|
||||
eo = pmatch[1].rm_eo;
|
||||
@@ -457,7 +457,7 @@ similar_escape(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE),
|
||||
errmsg("invalid escape string"),
|
||||
errhint("Escape string must be empty or one character.")));
|
||||
errhint("Escape string must be empty or one character.")));
|
||||
}
|
||||
|
||||
/* We need room for ^, $, and up to 2 output bytes per input byte */
|
||||
@@ -492,9 +492,7 @@ similar_escape(PG_FUNCTION_ARGS)
|
||||
*r++ = '*';
|
||||
}
|
||||
else if (pchar == '_')
|
||||
{
|
||||
*r++ = '.';
|
||||
}
|
||||
else if (pchar == '\\' || pchar == '.' || pchar == '?' ||
|
||||
pchar == '{')
|
||||
{
|
||||
@@ -502,14 +500,12 @@ similar_escape(PG_FUNCTION_ARGS)
|
||||
*r++ = pchar;
|
||||
}
|
||||
else
|
||||
{
|
||||
*r++ = pchar;
|
||||
}
|
||||
p++, plen--;
|
||||
}
|
||||
|
||||
*r++ = '$';
|
||||
|
||||
|
||||
VARATT_SIZEP(result) = r - ((unsigned char *) result);
|
||||
|
||||
PG_RETURN_TEXT_P(result);
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.79 2003/07/28 00:09:16 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.80 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -114,13 +114,13 @@ regprocin(PG_FUNCTION_ARGS)
|
||||
if (matches == 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_FUNCTION),
|
||||
errmsg("no procedure with name %s", pro_name_or_oid)));
|
||||
errmsg("no procedure with name %s", pro_name_or_oid)));
|
||||
|
||||
else if (matches > 1)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_AMBIGUOUS_FUNCTION),
|
||||
errmsg("more than one procedure named %s",
|
||||
pro_name_or_oid)));
|
||||
pro_name_or_oid)));
|
||||
|
||||
PG_RETURN_OID(result);
|
||||
}
|
||||
@@ -140,7 +140,7 @@ regprocin(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_AMBIGUOUS_FUNCTION),
|
||||
errmsg("more than one procedure named %s",
|
||||
pro_name_or_oid)));
|
||||
pro_name_or_oid)));
|
||||
|
||||
result = clist->oid;
|
||||
|
||||
@@ -464,12 +464,12 @@ regoperin(PG_FUNCTION_ARGS)
|
||||
if (matches == 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_FUNCTION),
|
||||
errmsg("no operator with name %s", opr_name_or_oid)));
|
||||
errmsg("no operator with name %s", opr_name_or_oid)));
|
||||
else if (matches > 1)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_AMBIGUOUS_FUNCTION),
|
||||
errmsg("more than one operator named %s",
|
||||
opr_name_or_oid)));
|
||||
opr_name_or_oid)));
|
||||
|
||||
PG_RETURN_OID(result);
|
||||
}
|
||||
@@ -489,7 +489,7 @@ regoperin(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_AMBIGUOUS_FUNCTION),
|
||||
errmsg("more than one operator named %s",
|
||||
opr_name_or_oid)));
|
||||
opr_name_or_oid)));
|
||||
|
||||
result = clist->oid;
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.52 2003/07/22 22:14:57 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.53 2003/08/04 00:43:25 momjian Exp $
|
||||
*
|
||||
* ----------
|
||||
*/
|
||||
@@ -150,29 +150,29 @@ static bool ri_OneKeyEqual(Relation rel, int column, HeapTuple oldtup,
|
||||
HeapTuple newtup, RI_QueryKey *key, int pairidx);
|
||||
static bool ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue);
|
||||
static bool ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel,
|
||||
HeapTuple old_row,
|
||||
Oid tgoid, int match_type,
|
||||
int tgnargs, char **tgargs);
|
||||
HeapTuple old_row,
|
||||
Oid tgoid, int match_type,
|
||||
int tgnargs, char **tgargs);
|
||||
|
||||
static void ri_InitHashTables(void);
|
||||
static void *ri_FetchPreparedPlan(RI_QueryKey *key);
|
||||
static void ri_HashPreparedPlan(RI_QueryKey *key, void *plan);
|
||||
|
||||
static void ri_CheckTrigger(FunctionCallInfo fcinfo, const char *funcname,
|
||||
int tgkind);
|
||||
int tgkind);
|
||||
static void *ri_PlanCheck(const char *querystr, int nargs, Oid *argtypes,
|
||||
RI_QueryKey *qkey, Relation fk_rel, Relation pk_rel,
|
||||
bool cache_plan);
|
||||
RI_QueryKey *qkey, Relation fk_rel, Relation pk_rel,
|
||||
bool cache_plan);
|
||||
static bool ri_PerformCheck(RI_QueryKey *qkey, void *qplan,
|
||||
Relation fk_rel, Relation pk_rel,
|
||||
HeapTuple old_tuple, HeapTuple new_tuple,
|
||||
int expect_OK, const char *constrname);
|
||||
Relation fk_rel, Relation pk_rel,
|
||||
HeapTuple old_tuple, HeapTuple new_tuple,
|
||||
int expect_OK, const char *constrname);
|
||||
static void ri_ExtractValues(RI_QueryKey *qkey, int key_idx,
|
||||
Relation rel, HeapTuple tuple,
|
||||
Datum *vals, char *nulls);
|
||||
Relation rel, HeapTuple tuple,
|
||||
Datum *vals, char *nulls);
|
||||
static void ri_ReportViolation(RI_QueryKey *qkey, const char *constrname,
|
||||
Relation pk_rel, Relation fk_rel,
|
||||
HeapTuple violator, bool spi_err);
|
||||
Relation pk_rel, Relation fk_rel,
|
||||
HeapTuple violator, bool spi_err);
|
||||
|
||||
|
||||
/* ----------
|
||||
@@ -341,7 +341,7 @@ RI_FKey_check(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FOREIGN_KEY_VIOLATION),
|
||||
errmsg("insert or update on \"%s\" violates foreign key constraint \"%s\"",
|
||||
RelationGetRelationName(trigdata->tg_relation),
|
||||
RelationGetRelationName(trigdata->tg_relation),
|
||||
tgargs[RI_CONSTRAINT_NAME_ARGNO]),
|
||||
errdetail("MATCH FULL does not allow mixing of NULL and non-NULL key values.")));
|
||||
heap_close(pk_rel, RowShareLock);
|
||||
@@ -366,7 +366,7 @@ RI_FKey_check(PG_FUNCTION_ARGS)
|
||||
*/
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("MATCH PARTIAL not yet implemented")));
|
||||
errmsg("MATCH PARTIAL not yet implemented")));
|
||||
heap_close(pk_rel, RowShareLock);
|
||||
return PointerGetDatum(NULL);
|
||||
}
|
||||
@@ -381,8 +381,8 @@ RI_FKey_check(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
/*
|
||||
* No need to check anything if old and new references are the
|
||||
* same on UPDATE.
|
||||
* No need to check anything if old and new references are the same on
|
||||
* UPDATE.
|
||||
*/
|
||||
if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
|
||||
{
|
||||
@@ -542,7 +542,7 @@ ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel,
|
||||
*/
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("MATCH PARTIAL not yet implemented")));
|
||||
errmsg("MATCH PARTIAL not yet implemented")));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -759,7 +759,8 @@ RI_FKey_noaction_del(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
/*
|
||||
* We have a plan now. Run it to check for existing references.
|
||||
* We have a plan now. Run it to check for existing
|
||||
* references.
|
||||
*/
|
||||
ri_PerformCheck(&qkey, qplan,
|
||||
fk_rel, pk_rel,
|
||||
@@ -897,8 +898,8 @@ RI_FKey_noaction_upd(PG_FUNCTION_ARGS)
|
||||
match_type, tgnargs, tgargs))
|
||||
{
|
||||
/*
|
||||
* There's either another row, or no row could match this one. In
|
||||
* either case, we don't need to do the check.
|
||||
* There's either another row, or no row could match this
|
||||
* one. In either case, we don't need to do the check.
|
||||
*/
|
||||
heap_close(fk_rel, RowShareLock);
|
||||
return PointerGetDatum(NULL);
|
||||
@@ -950,7 +951,8 @@ RI_FKey_noaction_upd(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
/*
|
||||
* We have a plan now. Run it to check for existing references.
|
||||
* We have a plan now. Run it to check for existing
|
||||
* references.
|
||||
*/
|
||||
ri_PerformCheck(&qkey, qplan,
|
||||
fk_rel, pk_rel,
|
||||
@@ -1110,9 +1112,9 @@ RI_FKey_cascade_del(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
/*
|
||||
* We have a plan now. Build up the arguments
|
||||
* from the key values in the deleted PK tuple and delete the
|
||||
* referencing rows
|
||||
* We have a plan now. Build up the arguments from the key
|
||||
* values in the deleted PK tuple and delete the referencing
|
||||
* rows
|
||||
*/
|
||||
ri_PerformCheck(&qkey, qplan,
|
||||
fk_rel, pk_rel,
|
||||
@@ -1296,7 +1298,8 @@ RI_FKey_cascade_upd(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
/*
|
||||
* We have a plan now. Run it to update the existing references.
|
||||
* We have a plan now. Run it to update the existing
|
||||
* references.
|
||||
*/
|
||||
ri_PerformCheck(&qkey, qplan,
|
||||
fk_rel, pk_rel,
|
||||
@@ -1465,7 +1468,8 @@ RI_FKey_restrict_del(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
/*
|
||||
* We have a plan now. Run it to check for existing references.
|
||||
* We have a plan now. Run it to check for existing
|
||||
* references.
|
||||
*/
|
||||
ri_PerformCheck(&qkey, qplan,
|
||||
fk_rel, pk_rel,
|
||||
@@ -1646,7 +1650,8 @@ RI_FKey_restrict_upd(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
/*
|
||||
* We have a plan now. Run it to check for existing references.
|
||||
* We have a plan now. Run it to check for existing
|
||||
* references.
|
||||
*/
|
||||
ri_PerformCheck(&qkey, qplan,
|
||||
fk_rel, pk_rel,
|
||||
@@ -1816,7 +1821,8 @@ RI_FKey_setnull_del(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
/*
|
||||
* We have a plan now. Run it to check for existing references.
|
||||
* We have a plan now. Run it to check for existing
|
||||
* references.
|
||||
*/
|
||||
ri_PerformCheck(&qkey, qplan,
|
||||
fk_rel, pk_rel,
|
||||
@@ -2034,7 +2040,8 @@ RI_FKey_setnull_upd(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
/*
|
||||
* We have a plan now. Run it to update the existing references.
|
||||
* We have a plan now. Run it to update the existing
|
||||
* references.
|
||||
*/
|
||||
ri_PerformCheck(&qkey, qplan,
|
||||
fk_rel, pk_rel,
|
||||
@@ -2209,14 +2216,14 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
|
||||
* appropriate column defaults, if any (if not, they stay
|
||||
* NULL).
|
||||
*
|
||||
* XXX This is really ugly; it'd be better to use "UPDATE
|
||||
* XXX This is really ugly; it'd be better to use "UPDATE
|
||||
* SET foo = DEFAULT", if we had it.
|
||||
*/
|
||||
spi_plan = (Plan *) lfirst(((_SPI_plan *) qplan)->ptlist);
|
||||
foreach(l, spi_plan->targetlist)
|
||||
{
|
||||
TargetEntry *tle = (TargetEntry *) lfirst(l);
|
||||
Node *dfl;
|
||||
Node *dfl;
|
||||
|
||||
/* Ignore any junk columns or Var=Var columns */
|
||||
if (tle->resdom->resjunk)
|
||||
@@ -2234,7 +2241,8 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
/*
|
||||
* We have a plan now. Run it to update the existing references.
|
||||
* We have a plan now. Run it to update the existing
|
||||
* references.
|
||||
*/
|
||||
ri_PerformCheck(&qkey, qplan,
|
||||
fk_rel, pk_rel,
|
||||
@@ -2444,14 +2452,14 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
|
||||
* appropriate column defaults, if any (if not, they stay
|
||||
* NULL).
|
||||
*
|
||||
* XXX This is really ugly; it'd be better to use "UPDATE
|
||||
* XXX This is really ugly; it'd be better to use "UPDATE
|
||||
* SET foo = DEFAULT", if we had it.
|
||||
*/
|
||||
spi_plan = (Plan *) lfirst(((_SPI_plan *) qplan)->ptlist);
|
||||
foreach(l, spi_plan->targetlist)
|
||||
{
|
||||
TargetEntry *tle = (TargetEntry *) lfirst(l);
|
||||
Node *dfl;
|
||||
Node *dfl;
|
||||
|
||||
/* Ignore any junk columns or Var=Var columns */
|
||||
if (tle->resdom->resjunk)
|
||||
@@ -2469,7 +2477,8 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
/*
|
||||
* We have a plan now. Run it to update the existing references.
|
||||
* We have a plan now. Run it to update the existing
|
||||
* references.
|
||||
*/
|
||||
ri_PerformCheck(&qkey, qplan,
|
||||
fk_rel, pk_rel,
|
||||
@@ -2542,8 +2551,8 @@ RI_FKey_keyequal_upd(TriggerData *trigdata)
|
||||
(tgnargs % 2) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
|
||||
errmsg("%s() called with wrong number of trigger arguments",
|
||||
"RI_FKey_keyequal_upd")));
|
||||
errmsg("%s() called with wrong number of trigger arguments",
|
||||
"RI_FKey_keyequal_upd")));
|
||||
|
||||
/*
|
||||
* Nothing to do if no column names to compare given
|
||||
@@ -2560,9 +2569,9 @@ RI_FKey_keyequal_upd(TriggerData *trigdata)
|
||||
if (!OidIsValid(trigdata->tg_trigger->tgconstrrelid))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||
errmsg("no target table given for trigger \"%s\" on \"%s\"",
|
||||
trigdata->tg_trigger->tgname,
|
||||
RelationGetRelationName(trigdata->tg_relation)),
|
||||
errmsg("no target table given for trigger \"%s\" on \"%s\"",
|
||||
trigdata->tg_trigger->tgname,
|
||||
RelationGetRelationName(trigdata->tg_relation)),
|
||||
errhint("Remove this RI trigger and its mates, then do ALTER TABLE ADD CONSTRAINT.")));
|
||||
|
||||
fk_rel = heap_open(trigdata->tg_trigger->tgconstrrelid, AccessShareLock);
|
||||
@@ -2750,7 +2759,7 @@ ri_CheckTrigger(FunctionCallInfo fcinfo, const char *funcname, int tgkind)
|
||||
if (!CALLED_AS_TRIGGER(fcinfo))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
|
||||
errmsg("%s() was not fired by trigger manager", funcname)));
|
||||
errmsg("%s() was not fired by trigger manager", funcname)));
|
||||
|
||||
/*
|
||||
* Check proper event
|
||||
@@ -2766,28 +2775,28 @@ ri_CheckTrigger(FunctionCallInfo fcinfo, const char *funcname, int tgkind)
|
||||
case RI_TRIGTYPE_INSERT:
|
||||
if (!TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
|
||||
errmsg("%s() must be fired for INSERT", funcname)));
|
||||
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
|
||||
errmsg("%s() must be fired for INSERT", funcname)));
|
||||
break;
|
||||
case RI_TRIGTYPE_UPDATE:
|
||||
if (!TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
|
||||
errmsg("%s() must be fired for UPDATE", funcname)));
|
||||
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
|
||||
errmsg("%s() must be fired for UPDATE", funcname)));
|
||||
break;
|
||||
case RI_TRIGTYPE_INUP:
|
||||
if (!TRIGGER_FIRED_BY_INSERT(trigdata->tg_event) &&
|
||||
!TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
|
||||
errmsg("%s() must be fired for INSERT or UPDATE",
|
||||
funcname)));
|
||||
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
|
||||
errmsg("%s() must be fired for INSERT or UPDATE",
|
||||
funcname)));
|
||||
break;
|
||||
case RI_TRIGTYPE_DELETE:
|
||||
if (!TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
|
||||
errmsg("%s() must be fired for DELETE", funcname)));
|
||||
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
|
||||
errmsg("%s() must be fired for DELETE", funcname)));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2800,19 +2809,19 @@ ri_CheckTrigger(FunctionCallInfo fcinfo, const char *funcname, int tgkind)
|
||||
(tgnargs % 2) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
|
||||
errmsg("%s() called with wrong number of trigger arguments",
|
||||
funcname)));
|
||||
errmsg("%s() called with wrong number of trigger arguments",
|
||||
funcname)));
|
||||
|
||||
/*
|
||||
* Check that tgconstrrelid is known. We need to check here because of
|
||||
* ancient pg_dump bug; see notes in CreateTrigger().
|
||||
* Check that tgconstrrelid is known. We need to check here because
|
||||
* of ancient pg_dump bug; see notes in CreateTrigger().
|
||||
*/
|
||||
if (!OidIsValid(trigdata->tg_trigger->tgconstrrelid))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||
errmsg("no target table given for trigger \"%s\" on \"%s\"",
|
||||
trigdata->tg_trigger->tgname,
|
||||
RelationGetRelationName(trigdata->tg_relation)),
|
||||
errmsg("no target table given for trigger \"%s\" on \"%s\"",
|
||||
trigdata->tg_trigger->tgname,
|
||||
RelationGetRelationName(trigdata->tg_relation)),
|
||||
errhint("Remove this RI trigger and its mates, then do ALTER TABLE ADD CONSTRAINT.")));
|
||||
}
|
||||
|
||||
@@ -2833,9 +2842,9 @@ ri_PlanCheck(const char *querystr, int nargs, Oid *argtypes,
|
||||
AclId save_uid;
|
||||
|
||||
/*
|
||||
* The query is always run against the FK table except
|
||||
* when this is an update/insert trigger on the FK table itself -
|
||||
* either RI_PLAN_CHECK_LOOKUPPK or RI_PLAN_CHECK_LOOKUPPK_NOCOLS
|
||||
* The query is always run against the FK table except when this is an
|
||||
* update/insert trigger on the FK table itself - either
|
||||
* RI_PLAN_CHECK_LOOKUPPK or RI_PLAN_CHECK_LOOKUPPK_NOCOLS
|
||||
*/
|
||||
if (qkey->constr_queryno == RI_PLAN_CHECK_LOOKUPPK ||
|
||||
qkey->constr_queryno == RI_PLAN_CHECK_LOOKUPPK_NOCOLS)
|
||||
@@ -2882,9 +2891,9 @@ ri_PerformCheck(RI_QueryKey *qkey, void *qplan,
|
||||
char nulls[RI_MAX_NUMKEYS * 2];
|
||||
|
||||
/*
|
||||
* The query is always run against the FK table except
|
||||
* when this is an update/insert trigger on the FK table itself -
|
||||
* either RI_PLAN_CHECK_LOOKUPPK or RI_PLAN_CHECK_LOOKUPPK_NOCOLS
|
||||
* The query is always run against the FK table except when this is an
|
||||
* update/insert trigger on the FK table itself - either
|
||||
* RI_PLAN_CHECK_LOOKUPPK or RI_PLAN_CHECK_LOOKUPPK_NOCOLS
|
||||
*/
|
||||
if (qkey->constr_queryno == RI_PLAN_CHECK_LOOKUPPK ||
|
||||
qkey->constr_queryno == RI_PLAN_CHECK_LOOKUPPK_NOCOLS)
|
||||
@@ -2893,10 +2902,10 @@ ri_PerformCheck(RI_QueryKey *qkey, void *qplan,
|
||||
query_rel = fk_rel;
|
||||
|
||||
/*
|
||||
* The values for the query are taken from the table on which the trigger
|
||||
* is called - it is normally the other one with respect to query_rel.
|
||||
* An exception is ri_Check_Pk_Match(), which uses the PK table for both
|
||||
* (the case when constrname == NULL)
|
||||
* The values for the query are taken from the table on which the
|
||||
* trigger is called - it is normally the other one with respect to
|
||||
* query_rel. An exception is ri_Check_Pk_Match(), which uses the PK
|
||||
* table for both (the case when constrname == NULL)
|
||||
*/
|
||||
if (qkey->constr_queryno == RI_PLAN_CHECK_LOOKUPPK && constrname != NULL)
|
||||
{
|
||||
@@ -2916,7 +2925,7 @@ ri_PerformCheck(RI_QueryKey *qkey, void *qplan,
|
||||
vals, nulls);
|
||||
if (old_tuple)
|
||||
ri_ExtractValues(qkey, key_idx, source_rel, old_tuple,
|
||||
vals + qkey->nkeypairs, nulls + qkey->nkeypairs);
|
||||
vals + qkey->nkeypairs, nulls + qkey->nkeypairs);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2930,9 +2939,9 @@ ri_PerformCheck(RI_QueryKey *qkey, void *qplan,
|
||||
|
||||
/*
|
||||
* If this is a select query (e.g., for a 'no action' or 'restrict'
|
||||
* trigger), we only need to see if there is a single row in the table,
|
||||
* matching the key. Otherwise, limit = 0 - because we want the query to
|
||||
* affect ALL the matching rows.
|
||||
* trigger), we only need to see if there is a single row in the
|
||||
* table, matching the key. Otherwise, limit = 0 - because we want
|
||||
* the query to affect ALL the matching rows.
|
||||
*/
|
||||
limit = (expect_OK == SPI_OK_SELECT) ? 1 : 0;
|
||||
|
||||
@@ -2954,7 +2963,7 @@ ri_PerformCheck(RI_QueryKey *qkey, void *qplan,
|
||||
|
||||
/* XXX wouldn't it be clearer to do this part at the caller? */
|
||||
if (constrname && expect_OK == SPI_OK_SELECT &&
|
||||
(SPI_processed==0) == (qkey->constr_queryno==RI_PLAN_CHECK_LOOKUPPK))
|
||||
(SPI_processed == 0) == (qkey->constr_queryno == RI_PLAN_CHECK_LOOKUPPK))
|
||||
ri_ReportViolation(qkey, constrname,
|
||||
pk_rel, fk_rel,
|
||||
new_tuple ? new_tuple : old_tuple,
|
||||
@@ -3049,9 +3058,9 @@ ri_ReportViolation(RI_QueryKey *qkey, const char *constrname,
|
||||
/* Get printable versions of the keys involved */
|
||||
for (idx = 0; idx < qkey->nkeypairs; idx++)
|
||||
{
|
||||
int fnum = qkey->keypair[idx][key_idx];
|
||||
char *name,
|
||||
*val;
|
||||
int fnum = qkey->keypair[idx][key_idx];
|
||||
char *name,
|
||||
*val;
|
||||
|
||||
name = SPI_fname(rel->rd_att, fnum);
|
||||
val = SPI_getvalue(violator, rel->rd_att, fnum);
|
||||
@@ -3075,22 +3084,22 @@ ri_ReportViolation(RI_QueryKey *qkey, const char *constrname,
|
||||
}
|
||||
|
||||
if (onfk)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FOREIGN_KEY_VIOLATION),
|
||||
errmsg("insert or update on \"%s\" violates foreign key constraint \"%s\"",
|
||||
RelationGetRelationName(fk_rel), constrname),
|
||||
errdetail("Key (%s)=(%s) is not present in \"%s\".",
|
||||
key_names, key_values,
|
||||
RelationGetRelationName(pk_rel))));
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FOREIGN_KEY_VIOLATION),
|
||||
errmsg("insert or update on \"%s\" violates foreign key constraint \"%s\"",
|
||||
RelationGetRelationName(fk_rel), constrname),
|
||||
errdetail("Key (%s)=(%s) is not present in \"%s\".",
|
||||
key_names, key_values,
|
||||
RelationGetRelationName(pk_rel))));
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FOREIGN_KEY_VIOLATION),
|
||||
errmsg("update or delete on \"%s\" violates foreign key constraint \"%s\" on \"%s\"",
|
||||
RelationGetRelationName(pk_rel),
|
||||
constrname, RelationGetRelationName(fk_rel)),
|
||||
errdetail("Key (%s)=(%s) is still referenced from \"%s\".",
|
||||
key_names, key_values,
|
||||
RelationGetRelationName(fk_rel))));
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FOREIGN_KEY_VIOLATION),
|
||||
errmsg("update or delete on \"%s\" violates foreign key constraint \"%s\" on \"%s\"",
|
||||
RelationGetRelationName(pk_rel),
|
||||
constrname, RelationGetRelationName(fk_rel)),
|
||||
errdetail("Key (%s)=(%s) is still referenced from \"%s\".",
|
||||
key_names, key_values,
|
||||
RelationGetRelationName(fk_rel))));
|
||||
}
|
||||
|
||||
/* ----------
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.142 2003/07/27 04:53:09 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.143 2003/08/04 00:43:26 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -180,7 +180,7 @@ static bool get_restriction_var(List *args, int varRelid,
|
||||
bool *varonleft);
|
||||
static void get_join_vars(List *args, Var **var1, Var **var2);
|
||||
static Selectivity prefix_selectivity(Query *root, Var *var,
|
||||
Oid opclass, Const *prefix);
|
||||
Oid opclass, Const *prefix);
|
||||
static Selectivity pattern_selectivity(Const *patt, Pattern_Type ptype);
|
||||
static Datum string_to_datum(const char *str, Oid datatype);
|
||||
static Const *string_to_const(const char *str, Oid datatype);
|
||||
@@ -871,8 +871,8 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
|
||||
/*
|
||||
* The right-hand const is type text or bytea for all supported
|
||||
* operators. We do not expect to see binary-compatible types here,
|
||||
* since const-folding should have relabeled the const to exactly match
|
||||
* the operator's declared type.
|
||||
* since const-folding should have relabeled the const to exactly
|
||||
* match the operator's declared type.
|
||||
*/
|
||||
if (consttype != TEXTOID && consttype != BYTEAOID)
|
||||
return DEFAULT_MATCH_SEL;
|
||||
@@ -890,10 +890,10 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
|
||||
* We should now be able to recognize the var's datatype. Choose the
|
||||
* index opclass from which we must draw the comparison operators.
|
||||
*
|
||||
* NOTE: It would be more correct to use the PATTERN opclasses than
|
||||
* the simple ones, but at the moment ANALYZE will not generate statistics
|
||||
* for the PATTERN operators. But our results are so approximate anyway
|
||||
* that it probably hardly matters.
|
||||
* NOTE: It would be more correct to use the PATTERN opclasses than the
|
||||
* simple ones, but at the moment ANALYZE will not generate statistics
|
||||
* for the PATTERN operators. But our results are so approximate
|
||||
* anyway that it probably hardly matters.
|
||||
*/
|
||||
switch (vartype)
|
||||
{
|
||||
@@ -921,22 +921,22 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
|
||||
pstatus = pattern_fixed_prefix(patt, ptype, &prefix, &rest);
|
||||
|
||||
/*
|
||||
* If necessary, coerce the prefix constant to the right type.
|
||||
* (The "rest" constant need not be changed.)
|
||||
* If necessary, coerce the prefix constant to the right type. (The
|
||||
* "rest" constant need not be changed.)
|
||||
*/
|
||||
if (prefix && prefix->consttype != vartype)
|
||||
{
|
||||
char *prefixstr;
|
||||
char *prefixstr;
|
||||
|
||||
switch (prefix->consttype)
|
||||
{
|
||||
case TEXTOID:
|
||||
prefixstr = DatumGetCString(DirectFunctionCall1(textout,
|
||||
prefix->constvalue));
|
||||
prefix->constvalue));
|
||||
break;
|
||||
case BYTEAOID:
|
||||
prefixstr = DatumGetCString(DirectFunctionCall1(byteaout,
|
||||
prefix->constvalue));
|
||||
prefix->constvalue));
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "unrecognized consttype: %u",
|
||||
@@ -1133,7 +1133,7 @@ booltestsel(Query *root, BoolTestType booltesttype, Node *arg,
|
||||
case IS_FALSE:
|
||||
case IS_NOT_TRUE:
|
||||
selec = 1.0 - (double) clause_selectivity(root, arg,
|
||||
varRelid, jointype);
|
||||
varRelid, jointype);
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "unrecognized booltesttype: %d",
|
||||
@@ -1523,27 +1523,29 @@ eqjoinsel(PG_FUNCTION_ARGS)
|
||||
hasmatch2 = (bool *) palloc0(nvalues2 * sizeof(bool));
|
||||
|
||||
/*
|
||||
* If we are doing any variant of JOIN_IN, pretend all the values
|
||||
* of the righthand relation are unique (ie, act as if it's been
|
||||
* DISTINCT'd).
|
||||
* If we are doing any variant of JOIN_IN, pretend all the
|
||||
* values of the righthand relation are unique (ie, act as if
|
||||
* it's been DISTINCT'd).
|
||||
*
|
||||
* NOTE: it might seem that we should unique-ify the lefthand
|
||||
* input when considering JOIN_REVERSE_IN. But this is not so,
|
||||
* because the join clause we've been handed has not been
|
||||
* commuted from the way the parser originally wrote it. We know
|
||||
* that the unique side of the IN clause is *always* on the right.
|
||||
* input when considering JOIN_REVERSE_IN. But this is not
|
||||
* so, because the join clause we've been handed has not been
|
||||
* commuted from the way the parser originally wrote it. We
|
||||
* know that the unique side of the IN clause is *always* on
|
||||
* the right.
|
||||
*
|
||||
* NOTE: it would be dangerous to try to be smart about JOIN_LEFT
|
||||
* or JOIN_RIGHT here, because we do not have enough information
|
||||
* to determine which var is really on which side of the join.
|
||||
* Perhaps someday we should pass in more information.
|
||||
* or JOIN_RIGHT here, because we do not have enough
|
||||
* information to determine which var is really on which side
|
||||
* of the join. Perhaps someday we should pass in more
|
||||
* information.
|
||||
*/
|
||||
if (jointype == JOIN_IN ||
|
||||
jointype == JOIN_REVERSE_IN ||
|
||||
jointype == JOIN_UNIQUE_INNER ||
|
||||
jointype == JOIN_UNIQUE_OUTER)
|
||||
{
|
||||
float4 oneovern = 1.0 / nd2;
|
||||
float4 oneovern = 1.0 / nd2;
|
||||
|
||||
for (i = 0; i < nvalues2; i++)
|
||||
numbers2[i] = oneovern;
|
||||
@@ -1647,20 +1649,22 @@ eqjoinsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/*
|
||||
* We do not have MCV lists for both sides. Estimate the join
|
||||
* selectivity as MIN(1/nd1,1/nd2)*(1-nullfrac1)*(1-nullfrac2).
|
||||
* This is plausible if we assume that the join operator is
|
||||
* strict and the non-null values are about equally distributed:
|
||||
* a given non-null tuple of rel1 will join to either zero or
|
||||
* N2*(1-nullfrac2)/nd2 rows of rel2, so total join rows are at
|
||||
* most N1*(1-nullfrac1)*N2*(1-nullfrac2)/nd2 giving a join
|
||||
* selectivity of not more than (1-nullfrac1)*(1-nullfrac2)/nd2.
|
||||
* By the same logic it is not more than
|
||||
* (1-nullfrac1)*(1-nullfrac2)/nd1, so the expression with MIN()
|
||||
* is an upper bound. Using the MIN() means we estimate from the
|
||||
* point of view of the relation with smaller nd (since the larger
|
||||
* nd is determining the MIN). It is reasonable to assume that
|
||||
* most tuples in this rel will have join partners, so the bound
|
||||
* is probably reasonably tight and should be taken as-is.
|
||||
* selectivity as
|
||||
* MIN(1/nd1,1/nd2)*(1-nullfrac1)*(1-nullfrac2). This is
|
||||
* plausible if we assume that the join operator is strict and
|
||||
* the non-null values are about equally distributed: a given
|
||||
* non-null tuple of rel1 will join to either zero or
|
||||
* N2*(1-nullfrac2)/nd2 rows of rel2, so total join rows are
|
||||
* at most N1*(1-nullfrac1)*N2*(1-nullfrac2)/nd2 giving a join
|
||||
* selectivity of not more than
|
||||
* (1-nullfrac1)*(1-nullfrac2)/nd2. By the same logic it is
|
||||
* not more than (1-nullfrac1)*(1-nullfrac2)/nd1, so the
|
||||
* expression with MIN() is an upper bound. Using the MIN()
|
||||
* means we estimate from the point of view of the relation
|
||||
* with smaller nd (since the larger nd is determining the
|
||||
* MIN). It is reasonable to assume that most tuples in this
|
||||
* rel will have join partners, so the bound is probably
|
||||
* reasonably tight and should be taken as-is.
|
||||
*
|
||||
* XXX Can we be smarter if we have an MCV list for just one
|
||||
* side? It seems that if we assume equal distribution for the
|
||||
@@ -1715,9 +1719,9 @@ neqjoinsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
result = DatumGetFloat8(DirectFunctionCall4(eqjoinsel,
|
||||
PointerGetDatum(root),
|
||||
ObjectIdGetDatum(eqop),
|
||||
ObjectIdGetDatum(eqop),
|
||||
PointerGetDatum(args),
|
||||
Int16GetDatum(jointype)));
|
||||
Int16GetDatum(jointype)));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1886,8 +1890,9 @@ mergejoinscansel(Query *root, Node *clause,
|
||||
righttype = exprType((Node *) right);
|
||||
|
||||
/*
|
||||
* Now skip any binary-compatible relabeling; there can only be one level
|
||||
* since constant-expression folder eliminates adjacent RelabelTypes.
|
||||
* Now skip any binary-compatible relabeling; there can only be one
|
||||
* level since constant-expression folder eliminates adjacent
|
||||
* RelabelTypes.
|
||||
*/
|
||||
if (IsA(left, RelabelType))
|
||||
left = (Var *) ((RelabelType *) left)->arg;
|
||||
@@ -2002,7 +2007,7 @@ mergejoinscansel(Query *root, Node *clause,
|
||||
* of values, clamp to the number of rows in the rel, and then multiply
|
||||
* by the selectivity of the restriction clauses for that rel. The
|
||||
* initial product is probably too high (it's the worst case) but since
|
||||
* we can clamp to the rel's rows it won't be hugely bad. Multiplying
|
||||
* we can clamp to the rel's rows it won't be hugely bad. Multiplying
|
||||
* by the restriction selectivity is effectively assuming that the
|
||||
* restriction clauses are independent of the grouping, which is a crummy
|
||||
* assumption, but it's hard to do better.
|
||||
@@ -2021,10 +2026,11 @@ estimate_num_groups(Query *root, List *groupExprs, double input_rows)
|
||||
List *varinfos = NIL;
|
||||
double numdistinct;
|
||||
List *l;
|
||||
typedef struct { /* varinfos is a List of these */
|
||||
Var *var;
|
||||
double ndistinct;
|
||||
} MyVarInfo;
|
||||
typedef struct
|
||||
{ /* varinfos is a List of these */
|
||||
Var *var;
|
||||
double ndistinct;
|
||||
} MyVarInfo;
|
||||
|
||||
/* We should not be called unless query has GROUP BY (or DISTINCT) */
|
||||
Assert(groupExprs != NIL);
|
||||
@@ -2036,9 +2042,10 @@ estimate_num_groups(Query *root, List *groupExprs, double input_rows)
|
||||
List *varshere;
|
||||
|
||||
varshere = pull_var_clause(groupexpr, false);
|
||||
|
||||
/*
|
||||
* If we find any variable-free GROUP BY item, then either it is
|
||||
* a constant (and we can ignore it) or it contains a volatile
|
||||
* If we find any variable-free GROUP BY item, then either it is a
|
||||
* constant (and we can ignore it) or it contains a volatile
|
||||
* function; in the latter case we punt and assume that each input
|
||||
* row will yield a distinct group.
|
||||
*/
|
||||
@@ -2065,13 +2072,13 @@ estimate_num_groups(Query *root, List *groupExprs, double input_rows)
|
||||
*/
|
||||
foreach(l, allvars)
|
||||
{
|
||||
Var *var = (Var *) lfirst(l);
|
||||
Oid relid = getrelid(var->varno, root->rtable);
|
||||
Var *var = (Var *) lfirst(l);
|
||||
Oid relid = getrelid(var->varno, root->rtable);
|
||||
HeapTuple statsTuple = NULL;
|
||||
Form_pg_statistic stats = NULL;
|
||||
double ndistinct;
|
||||
bool keep = true;
|
||||
List *l2;
|
||||
double ndistinct;
|
||||
bool keep = true;
|
||||
List *l2;
|
||||
|
||||
if (OidIsValid(relid))
|
||||
{
|
||||
@@ -2096,7 +2103,7 @@ estimate_num_groups(Query *root, List *groupExprs, double input_rows)
|
||||
l2 = lnext(l2);
|
||||
|
||||
if (var->varno != varinfo->var->varno &&
|
||||
exprs_known_equal(root, (Node *) var, (Node *) varinfo->var))
|
||||
exprs_known_equal(root, (Node *) var, (Node *) varinfo->var))
|
||||
{
|
||||
/* Found a match */
|
||||
if (varinfo->ndistinct <= ndistinct)
|
||||
@@ -2126,10 +2133,10 @@ estimate_num_groups(Query *root, List *groupExprs, double input_rows)
|
||||
/*
|
||||
* Steps 3/4: group Vars by relation and estimate total numdistinct.
|
||||
*
|
||||
* For each iteration of the outer loop, we process the frontmost
|
||||
* Var in varinfos, plus all other Vars in the same relation. We
|
||||
* remove these Vars from the newvarinfos list for the next iteration.
|
||||
* This is the easiest way to group Vars of same rel together.
|
||||
* For each iteration of the outer loop, we process the frontmost Var in
|
||||
* varinfos, plus all other Vars in the same relation. We remove
|
||||
* these Vars from the newvarinfos list for the next iteration. This
|
||||
* is the easiest way to group Vars of same rel together.
|
||||
*/
|
||||
Assert(varinfos != NIL);
|
||||
numdistinct = 1.0;
|
||||
@@ -2138,8 +2145,8 @@ estimate_num_groups(Query *root, List *groupExprs, double input_rows)
|
||||
{
|
||||
MyVarInfo *varinfo1 = (MyVarInfo *) lfirst(varinfos);
|
||||
RelOptInfo *rel = find_base_rel(root, varinfo1->var->varno);
|
||||
double reldistinct = varinfo1->ndistinct;
|
||||
List *newvarinfos = NIL;
|
||||
double reldistinct = varinfo1->ndistinct;
|
||||
List *newvarinfos = NIL;
|
||||
|
||||
/*
|
||||
* Get the largest numdistinct estimate of the Vars for this rel.
|
||||
@@ -2150,9 +2157,7 @@ estimate_num_groups(Query *root, List *groupExprs, double input_rows)
|
||||
MyVarInfo *varinfo2 = (MyVarInfo *) lfirst(l);
|
||||
|
||||
if (varinfo2->var->varno == varinfo1->var->varno)
|
||||
{
|
||||
reldistinct *= varinfo2->ndistinct;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* not time to process varinfo2 yet */
|
||||
@@ -2364,9 +2369,10 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
|
||||
* constant-folding will ensure that any Const passed to the operator
|
||||
* has been reduced to the correct type). However, the boundstypid is
|
||||
* the type of some variable that might be only binary-compatible with
|
||||
* the declared type; in particular it might be a domain type. Must
|
||||
* the declared type; in particular it might be a domain type. Must
|
||||
* fold the variable type down to base type so we can recognize it.
|
||||
* (But we can skip that lookup if the variable type matches the const.)
|
||||
* (But we can skip that lookup if the variable type matches the
|
||||
* const.)
|
||||
*/
|
||||
if (boundstypid != valuetypid)
|
||||
boundstypid = getBaseType(boundstypid);
|
||||
@@ -2696,15 +2702,15 @@ convert_string_datum(Datum value, Oid typid)
|
||||
|
||||
/*
|
||||
* Note: originally we guessed at a suitable output buffer size,
|
||||
* and only needed to call strxfrm twice if our guess was too small.
|
||||
* However, it seems that some versions of Solaris have buggy
|
||||
* strxfrm that can write past the specified buffer length in that
|
||||
* scenario. So, do it the dumb way for portability.
|
||||
* and only needed to call strxfrm twice if our guess was too
|
||||
* small. However, it seems that some versions of Solaris have
|
||||
* buggy strxfrm that can write past the specified buffer length
|
||||
* in that scenario. So, do it the dumb way for portability.
|
||||
*
|
||||
* Yet other systems (e.g., glibc) sometimes return a smaller value
|
||||
* from the second call than the first; thus the Assert must be <=
|
||||
* not == as you'd expect. Can't any of these people program their
|
||||
* way out of a paper bag?
|
||||
* not == as you'd expect. Can't any of these people program
|
||||
* their way out of a paper bag?
|
||||
*/
|
||||
xfrmlen = strxfrm(NULL, val, 0);
|
||||
xfrmstr = (char *) palloc(xfrmlen + 1);
|
||||
@@ -3113,7 +3119,7 @@ like_fixed_prefix(Const *patt_const, bool case_insensitive,
|
||||
if (typeid == BYTEAOID && case_insensitive)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("case insensitive matching not supported on type bytea")));
|
||||
errmsg("case insensitive matching not supported on type bytea")));
|
||||
|
||||
if (typeid != BYTEAOID)
|
||||
{
|
||||
@@ -3355,7 +3361,7 @@ pattern_fixed_prefix(Const *patt, Pattern_Type ptype,
|
||||
* "var >= 'foo' AND var < 'fop'" (see also indxqual.c).
|
||||
*
|
||||
* We use the >= and < operators from the specified btree opclass to do the
|
||||
* estimation. The given Var and Const must be of the associated datatype.
|
||||
* estimation. The given Var and Const must be of the associated datatype.
|
||||
*
|
||||
* XXX Note: we make use of the upper bound to estimate operator selectivity
|
||||
* even if the locale is such that we cannot rely on the upper-bound string.
|
||||
@@ -3476,7 +3482,7 @@ like_selectivity(Const *patt_const, bool case_insensitive)
|
||||
if (typeid == BYTEAOID && case_insensitive)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("case insensitive matching not supported on type bytea")));
|
||||
errmsg("case insensitive matching not supported on type bytea")));
|
||||
|
||||
if (typeid != BYTEAOID)
|
||||
{
|
||||
@@ -3917,8 +3923,8 @@ btcostestimate(PG_FUNCTION_ARGS)
|
||||
indexSelectivity, indexCorrelation);
|
||||
|
||||
/*
|
||||
* If the first column is a simple variable, and we can get an estimate
|
||||
* for its ordering correlation C from pg_statistic, estimate
|
||||
* If the first column is a simple variable, and we can get an
|
||||
* estimate for its ordering correlation C from pg_statistic, estimate
|
||||
* the index correlation as C / number-of-columns. (The idea here is
|
||||
* that multiple columns dilute the importance of the first column's
|
||||
* ordering, but don't negate it entirely.)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.56 2003/07/27 04:53:10 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.57 2003/08/04 00:43:26 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -154,14 +154,15 @@ seteval(PG_FUNCTION_ARGS)
|
||||
fcache = (FuncExprState *) fcinfo->flinfo->fn_extra;
|
||||
if (fcache == NULL)
|
||||
{
|
||||
MemoryContext oldcontext;
|
||||
MemoryContext oldcontext;
|
||||
FuncExpr *func;
|
||||
|
||||
oldcontext = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
|
||||
|
||||
func = makeNode(FuncExpr);
|
||||
func->funcid = funcoid;
|
||||
func->funcresulttype = InvalidOid; /* nothing will look at this */
|
||||
func->funcresulttype = InvalidOid; /* nothing will look at
|
||||
* this */
|
||||
func->funcretset = true;
|
||||
func->funcformat = COERCE_EXPLICIT_CALL;
|
||||
func->args = NIL; /* there are no arguments */
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.88 2003/07/27 04:53:10 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.89 2003/08/04 00:43:26 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -254,15 +254,15 @@ AdjustTimestampForTypmod(Timestamp *time, int32 typmod)
|
||||
if ((typmod < 0) || (typmod > MAX_TIMESTAMP_PRECISION))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("timestamp(%d) precision must be between %d and %d",
|
||||
typmod, 0, MAX_TIMESTAMP_PRECISION)));
|
||||
errmsg("timestamp(%d) precision must be between %d and %d",
|
||||
typmod, 0, MAX_TIMESTAMP_PRECISION)));
|
||||
|
||||
/*
|
||||
* Note: this round-to-nearest code is not completely consistent
|
||||
* about rounding values that are exactly halfway between integral
|
||||
* values. On most platforms, rint() will implement round-to-nearest-even,
|
||||
* but the integer code always rounds up (away from zero). Is it
|
||||
* worth trying to be consistent?
|
||||
* values. On most platforms, rint() will implement
|
||||
* round-to-nearest-even, but the integer code always rounds up
|
||||
* (away from zero). Is it worth trying to be consistent?
|
||||
*/
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
if (*time >= INT64CONST(0))
|
||||
@@ -272,8 +272,8 @@ AdjustTimestampForTypmod(Timestamp *time, int32 typmod)
|
||||
}
|
||||
else
|
||||
{
|
||||
*time = - ((((- *time) + TimestampOffsets[typmod]) / TimestampScales[typmod])
|
||||
* TimestampScales[typmod]);
|
||||
*time = -((((-*time) + TimestampOffsets[typmod]) / TimestampScales[typmod])
|
||||
* TimestampScales[typmod]);
|
||||
}
|
||||
#else
|
||||
*time = (rint(((double) *time) * TimestampScales[typmod])
|
||||
@@ -411,7 +411,7 @@ timestamptz_recv(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
timestamptz_send(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(0);
|
||||
TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(0);
|
||||
StringInfoData buf;
|
||||
|
||||
pq_begintypsend(&buf);
|
||||
@@ -829,15 +829,16 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod)
|
||||
if ((precision < 0) || (precision > MAX_INTERVAL_PRECISION))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("interval(%d) precision must be between %d and %d",
|
||||
precision, 0, MAX_INTERVAL_PRECISION)));
|
||||
errmsg("interval(%d) precision must be between %d and %d",
|
||||
precision, 0, MAX_INTERVAL_PRECISION)));
|
||||
|
||||
/*
|
||||
* Note: this round-to-nearest code is not completely consistent
|
||||
* about rounding values that are exactly halfway between integral
|
||||
* values. On most platforms, rint() will implement round-to-nearest-even,
|
||||
* but the integer code always rounds up (away from zero). Is it
|
||||
* worth trying to be consistent?
|
||||
* Note: this round-to-nearest code is not completely
|
||||
* consistent about rounding values that are exactly halfway
|
||||
* between integral values. On most platforms, rint() will
|
||||
* implement round-to-nearest-even, but the integer code
|
||||
* always rounds up (away from zero). Is it worth trying to
|
||||
* be consistent?
|
||||
*/
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
if (interval->time >= INT64CONST(0))
|
||||
@@ -847,8 +848,8 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod)
|
||||
}
|
||||
else
|
||||
{
|
||||
interval->time = - (((-interval->time + IntervalOffsets[precision]) / IntervalScales[precision])
|
||||
* IntervalScales[precision]);
|
||||
interval->time = -(((-interval->time + IntervalOffsets[precision]) / IntervalScales[precision])
|
||||
* IntervalScales[precision]);
|
||||
}
|
||||
#else
|
||||
interval->time = (rint(((double) interval->time) * IntervalScales[precision])
|
||||
@@ -1024,7 +1025,7 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, fsec_t *fsec, char **tzn)
|
||||
{
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
utime = ((dt / INT64CONST(1000000))
|
||||
+ ((date0 - UNIX_EPOCH_JDATE) * INT64CONST(86400)));
|
||||
+ ((date0 - UNIX_EPOCH_JDATE) * INT64CONST(86400)));
|
||||
#else
|
||||
utime = (dt + ((date0 - UNIX_EPOCH_JDATE) * 86400));
|
||||
#endif
|
||||
@@ -2410,7 +2411,7 @@ text_timestamp(PG_FUNCTION_ARGS)
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for timestamp: \"%s\"",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(str))))));
|
||||
PointerGetDatum(str))))));
|
||||
|
||||
sp = VARDATA(str);
|
||||
dp = dstr;
|
||||
@@ -2470,7 +2471,7 @@ text_timestamptz(PG_FUNCTION_ARGS)
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for timestamp with time zone: \"%s\"",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(str))))));
|
||||
PointerGetDatum(str))))));
|
||||
|
||||
sp = VARDATA(str);
|
||||
dp = dstr;
|
||||
@@ -2531,7 +2532,7 @@ text_interval(PG_FUNCTION_ARGS)
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for interval: \"%s\"",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(str))))));
|
||||
PointerGetDatum(str))))));
|
||||
|
||||
sp = VARDATA(str);
|
||||
dp = dstr;
|
||||
@@ -2568,8 +2569,8 @@ timestamp_trunc(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("timestamp units \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
|
||||
up = VARDATA(units);
|
||||
lp = lowunits;
|
||||
@@ -2676,9 +2677,9 @@ timestamptz_trunc(PG_FUNCTION_ARGS)
|
||||
if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("timestamp with time zone units \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
errmsg("timestamp with time zone units \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
up = VARDATA(units);
|
||||
lp = lowunits;
|
||||
for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)
|
||||
@@ -2737,8 +2738,8 @@ timestamptz_trunc(PG_FUNCTION_ARGS)
|
||||
default:
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("timestamp with time zone units \"%s\" not "
|
||||
"supported", lowunits)));
|
||||
errmsg("timestamp with time zone units \"%s\" not "
|
||||
"supported", lowunits)));
|
||||
result = 0;
|
||||
}
|
||||
|
||||
@@ -2753,8 +2754,8 @@ timestamptz_trunc(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("timestamp with time zone units \"%s\" not recognized",
|
||||
lowunits)));
|
||||
errmsg("timestamp with time zone units \"%s\" not recognized",
|
||||
lowunits)));
|
||||
result = 0;
|
||||
}
|
||||
|
||||
@@ -2786,8 +2787,8 @@ interval_trunc(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("interval units \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
up = VARDATA(units);
|
||||
lp = lowunits;
|
||||
for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)
|
||||
@@ -2841,7 +2842,7 @@ interval_trunc(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("interval units \"%s\" not supported",
|
||||
lowunits)));
|
||||
lowunits)));
|
||||
}
|
||||
|
||||
if (tm2interval(tm, fsec, result) != 0)
|
||||
@@ -2850,17 +2851,15 @@ interval_trunc(PG_FUNCTION_ARGS)
|
||||
errmsg("interval out of range")));
|
||||
}
|
||||
else
|
||||
{
|
||||
elog(ERROR, "could not convert interval to tm");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("interval units \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
*result = *interval;
|
||||
}
|
||||
|
||||
@@ -2882,7 +2881,7 @@ isoweek2date(int woy, int *year, int *mon, int *mday)
|
||||
if (!*year)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("cannot convert week number without year information")));
|
||||
errmsg("cannot convert week number without year information")));
|
||||
|
||||
/* fourth day of current year */
|
||||
day4 = date2j(*year, 1, 4);
|
||||
@@ -2972,8 +2971,8 @@ timestamp_part(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("timestamp units \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
up = VARDATA(units);
|
||||
lp = lowunits;
|
||||
for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)
|
||||
@@ -3081,7 +3080,7 @@ timestamp_part(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("timestamp units \"%s\" not supported",
|
||||
lowunits)));
|
||||
lowunits)));
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
@@ -3090,30 +3089,33 @@ timestamp_part(PG_FUNCTION_ARGS)
|
||||
switch (val)
|
||||
{
|
||||
case DTK_EPOCH:
|
||||
{
|
||||
int tz;
|
||||
TimestampTz timestamptz;
|
||||
{
|
||||
int tz;
|
||||
TimestampTz timestamptz;
|
||||
|
||||
/* convert to timestamptz to produce consistent results */
|
||||
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
||||
errmsg("timestamp out of range")));
|
||||
/*
|
||||
* convert to timestamptz to produce consistent
|
||||
* results
|
||||
*/
|
||||
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
||||
errmsg("timestamp out of range")));
|
||||
|
||||
tz = DetermineLocalTimeZone(tm);
|
||||
tz = DetermineLocalTimeZone(tm);
|
||||
|
||||
if (tm2timestamp(tm, fsec, &tz, ×tamptz) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
||||
errmsg("timestamp out of range")));
|
||||
if (tm2timestamp(tm, fsec, &tz, ×tamptz) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
||||
errmsg("timestamp out of range")));
|
||||
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
result = ((timestamptz - SetEpochTimestamp()) / 1000000e0);
|
||||
result = ((timestamptz - SetEpochTimestamp()) / 1000000e0);
|
||||
#else
|
||||
result = timestamptz - SetEpochTimestamp();
|
||||
result = timestamptz - SetEpochTimestamp();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DTK_DOW:
|
||||
if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) != 0)
|
||||
ereport(ERROR,
|
||||
@@ -3135,7 +3137,7 @@ timestamp_part(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("timestamp units \"%s\" not supported",
|
||||
lowunits)));
|
||||
lowunits)));
|
||||
result = 0;
|
||||
}
|
||||
|
||||
@@ -3144,7 +3146,7 @@ timestamp_part(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("timestamp units \"%s\" not recognized", lowunits)));
|
||||
errmsg("timestamp units \"%s\" not recognized", lowunits)));
|
||||
result = 0;
|
||||
}
|
||||
|
||||
@@ -3176,9 +3178,9 @@ timestamptz_part(PG_FUNCTION_ARGS)
|
||||
if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("timestamp with time zone units \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
errmsg("timestamp with time zone units \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
up = VARDATA(units);
|
||||
lp = lowunits;
|
||||
for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)
|
||||
@@ -3298,7 +3300,7 @@ timestamptz_part(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("timestamp with time zone units \"%s\" not supported",
|
||||
lowunits)));
|
||||
lowunits)));
|
||||
result = 0;
|
||||
}
|
||||
|
||||
@@ -3336,7 +3338,7 @@ timestamptz_part(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("timestamp with time zone units \"%s\" not supported",
|
||||
lowunits)));
|
||||
lowunits)));
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
@@ -3344,8 +3346,8 @@ timestamptz_part(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("timestamp with time zone units \"%s\" not recognized",
|
||||
lowunits)));
|
||||
errmsg("timestamp with time zone units \"%s\" not recognized",
|
||||
lowunits)));
|
||||
|
||||
result = 0;
|
||||
}
|
||||
@@ -3377,8 +3379,8 @@ interval_part(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("interval units \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
up = VARDATA(units);
|
||||
lp = lowunits;
|
||||
for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)
|
||||
@@ -3460,7 +3462,7 @@ interval_part(PG_FUNCTION_ARGS)
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("interval units \"%s\" not supported",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
PointerGetDatum(units))))));
|
||||
result = 0;
|
||||
}
|
||||
|
||||
@@ -3489,8 +3491,8 @@ interval_part(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("interval units \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
result = 0;
|
||||
}
|
||||
|
||||
@@ -3521,8 +3523,8 @@ timestamp_zone(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("time zone \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(zone))))));
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(zone))))));
|
||||
|
||||
if (TIMESTAMP_NOT_FINITE(timestamp))
|
||||
PG_RETURN_TIMESTAMPTZ(timestamp);
|
||||
@@ -3546,7 +3548,7 @@ timestamp_zone(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("time zone \"%s\" not recognized",
|
||||
lowzone)));
|
||||
lowzone)));
|
||||
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
@@ -3571,9 +3573,9 @@ timestamp_izone(PG_FUNCTION_ARGS)
|
||||
if (zone->month != 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("interval time zone \"%s\" must not specify month",
|
||||
DatumGetCString(DirectFunctionCall1(interval_out,
|
||||
PointerGetDatum(zone))))));
|
||||
errmsg("interval time zone \"%s\" must not specify month",
|
||||
DatumGetCString(DirectFunctionCall1(interval_out,
|
||||
PointerGetDatum(zone))))));
|
||||
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
tz = (zone->time / INT64CONST(1000000));
|
||||
@@ -3673,8 +3675,8 @@ timestamptz_zone(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("time zone \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(zone))))));
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(zone))))));
|
||||
up = VARDATA(zone);
|
||||
lp = lowzone;
|
||||
for (i = 0; i < (VARSIZE(zone) - VARHDRSZ); i++)
|
||||
@@ -3722,9 +3724,9 @@ timestamptz_izone(PG_FUNCTION_ARGS)
|
||||
if (zone->month != 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("interval time zone \"%s\" must not specify month",
|
||||
DatumGetCString(DirectFunctionCall1(interval_out,
|
||||
PointerGetDatum(zone))))));
|
||||
errmsg("interval time zone \"%s\" must not specify month",
|
||||
DatumGetCString(DirectFunctionCall1(interval_out,
|
||||
PointerGetDatum(zone))))));
|
||||
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
tz = -(zone->time / INT64CONST(1000000));
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varbit.c,v 1.32 2003/07/27 04:53:10 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varbit.c,v 1.33 2003/08/04 00:43:26 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -106,8 +106,8 @@ bit_in(PG_FUNCTION_ARGS)
|
||||
else if (bitlen != atttypmod)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
|
||||
errmsg("bit string length %d does not match type bit(%d)",
|
||||
bitlen, atttypmod)));
|
||||
errmsg("bit string length %d does not match type bit(%d)",
|
||||
bitlen, atttypmod)));
|
||||
|
||||
len = VARBITTOTALLEN(atttypmod);
|
||||
/* set to 0 so that *r is always initialised and string is zero-padded */
|
||||
@@ -260,8 +260,8 @@ bit(PG_FUNCTION_ARGS)
|
||||
if (!isExplicit)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
|
||||
errmsg("bit string length %d does not match type bit(%d)",
|
||||
VARBITLEN(arg), len)));
|
||||
errmsg("bit string length %d does not match type bit(%d)",
|
||||
VARBITLEN(arg), len)));
|
||||
|
||||
rlen = VARBITTOTALLEN(len);
|
||||
/* set to 0 so that string is zero-padded */
|
||||
@@ -346,7 +346,7 @@ varbit_in(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
|
||||
errmsg("bit string too long for type bit varying(%d)",
|
||||
atttypmod)));
|
||||
atttypmod)));
|
||||
|
||||
len = VARBITTOTALLEN(bitlen);
|
||||
/* set to 0 so that *r is always initialised and string is zero-padded */
|
||||
@@ -530,7 +530,7 @@ varbit(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
|
||||
errmsg("bit string too long for type bit varying(%d)",
|
||||
len)));
|
||||
len)));
|
||||
|
||||
rlen = VARBITTOTALLEN(len);
|
||||
result = (VarBit *) palloc(rlen);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.99 2003/07/27 04:53:10 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.100 2003/08/04 00:43:26 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -103,7 +103,7 @@ bpcharin(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
|
||||
errmsg("value too long for type character(%d)",
|
||||
(int) maxlen)));
|
||||
(int) maxlen)));
|
||||
|
||||
/*
|
||||
* XXX: at this point, maxlen is the necessary byte length, not
|
||||
@@ -190,7 +190,7 @@ bpcharsend(PG_FUNCTION_ARGS)
|
||||
*
|
||||
* Truncation rules: for an explicit cast, silently truncate to the given
|
||||
* length; for an implicit cast, raise error unless extra characters are
|
||||
* all spaces. (This is sort-of per SQL: the spec would actually have us
|
||||
* all spaces. (This is sort-of per SQL: the spec would actually have us
|
||||
* raise a "completion condition" for the explicit cast case, but Postgres
|
||||
* hasn't got such a concept.)
|
||||
*/
|
||||
@@ -230,8 +230,8 @@ bpchar(PG_FUNCTION_ARGS)
|
||||
if (*(VARDATA(source) + i) != ' ')
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
|
||||
errmsg("value too long for type character(%d)",
|
||||
maxlen - VARHDRSZ)));
|
||||
errmsg("value too long for type character(%d)",
|
||||
maxlen - VARHDRSZ)));
|
||||
}
|
||||
|
||||
len = maxmblen;
|
||||
@@ -388,8 +388,8 @@ varcharin(PG_FUNCTION_ARGS)
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
|
||||
errmsg("value too long for type character varying(%d)",
|
||||
(int) maxlen)));
|
||||
errmsg("value too long for type character varying(%d)",
|
||||
(int) maxlen)));
|
||||
}
|
||||
|
||||
result = palloc(len + VARHDRSZ);
|
||||
@@ -456,7 +456,7 @@ varcharsend(PG_FUNCTION_ARGS)
|
||||
*
|
||||
* Truncation rules: for an explicit cast, silently truncate to the given
|
||||
* length; for an implicit cast, raise error unless extra characters are
|
||||
* all spaces. (This is sort-of per SQL: the spec would actually have us
|
||||
* all spaces. (This is sort-of per SQL: the spec would actually have us
|
||||
* raise a "completion condition" for the explicit cast case, but Postgres
|
||||
* hasn't got such a concept.)
|
||||
*/
|
||||
@@ -488,8 +488,8 @@ varchar(PG_FUNCTION_ARGS)
|
||||
if (*(VARDATA(source) + i) != ' ')
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
|
||||
errmsg("value too long for type character varying(%d)",
|
||||
maxlen - VARHDRSZ)));
|
||||
errmsg("value too long for type character varying(%d)",
|
||||
maxlen - VARHDRSZ)));
|
||||
}
|
||||
|
||||
len = maxmblen + VARHDRSZ;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.102 2003/07/27 04:53:10 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.103 2003/08/04 00:43:26 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -34,7 +34,7 @@ typedef struct varlena unknown;
|
||||
#define DatumGetUnknownP(X) ((unknown *) PG_DETOAST_DATUM(X))
|
||||
#define DatumGetUnknownPCopy(X) ((unknown *) PG_DETOAST_DATUM_COPY(X))
|
||||
#define PG_GETARG_UNKNOWN_P(n) DatumGetUnknownP(PG_GETARG_DATUM(n))
|
||||
#define PG_GETARG_UNKNOWN_P_COPY(n) DatumGetUnknownPCopy(PG_GETARG_DATUM(n))
|
||||
#define PG_GETARG_UNKNOWN_P_COPY(n) DatumGetUnknownPCopy(PG_GETARG_DATUM(n))
|
||||
#define PG_RETURN_UNKNOWN_P(x) PG_RETURN_POINTER(x)
|
||||
|
||||
#define PG_TEXTARG_GET_STR(arg_) \
|
||||
@@ -120,7 +120,7 @@ byteain(PG_FUNCTION_ARGS)
|
||||
|
||||
byte += VARHDRSZ;
|
||||
result = (bytea *) palloc(byte);
|
||||
VARATT_SIZEP(result) = byte; /* set varlena length */
|
||||
VARATT_SIZEP(result) = byte; /* set varlena length */
|
||||
|
||||
tp = inputText;
|
||||
rp = VARDATA(result);
|
||||
@@ -376,7 +376,7 @@ Datum
|
||||
unknownrecv(PG_FUNCTION_ARGS)
|
||||
{
|
||||
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
|
||||
unknown *result;
|
||||
unknown *result;
|
||||
int nbytes;
|
||||
|
||||
nbytes = buf->len - buf->cursor;
|
||||
@@ -395,7 +395,7 @@ unknownrecv(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
unknownsend(PG_FUNCTION_ARGS)
|
||||
{
|
||||
unknown *vlena = PG_GETARG_UNKNOWN_P_COPY(0);
|
||||
unknown *vlena = PG_GETARG_UNKNOWN_P_COPY(0);
|
||||
|
||||
PG_RETURN_UNKNOWN_P(vlena);
|
||||
}
|
||||
@@ -584,7 +584,7 @@ text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
|
||||
if (E < S)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_SUBSTRING_ERROR),
|
||||
errmsg("negative substring length not allowed")));
|
||||
errmsg("negative substring length not allowed")));
|
||||
|
||||
/*
|
||||
* A zero or negative value for the end position can happen if
|
||||
@@ -648,7 +648,7 @@ text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
|
||||
if (E < S)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_SUBSTRING_ERROR),
|
||||
errmsg("negative substring length not allowed")));
|
||||
errmsg("negative substring length not allowed")));
|
||||
|
||||
/*
|
||||
* A zero or negative value for the end position can happen if
|
||||
@@ -851,10 +851,10 @@ varstr_cmp(char *arg1, int len1, char *arg2, int len2)
|
||||
|
||||
if (!lc_collate_is_c())
|
||||
{
|
||||
char a1buf[STACKBUFLEN];
|
||||
char a2buf[STACKBUFLEN];
|
||||
char *a1p,
|
||||
*a2p;
|
||||
char a1buf[STACKBUFLEN];
|
||||
char a2buf[STACKBUFLEN];
|
||||
char *a1p,
|
||||
*a2p;
|
||||
|
||||
if (len1 >= STACKBUFLEN)
|
||||
a1p = (char *) palloc(len1 + 1);
|
||||
@@ -1065,7 +1065,7 @@ text_smaller(PG_FUNCTION_ARGS)
|
||||
static int
|
||||
internal_text_pattern_compare(text *arg1, text *arg2)
|
||||
{
|
||||
int result;
|
||||
int result;
|
||||
|
||||
result = memcmp(VARDATA(arg1), VARDATA(arg2),
|
||||
Min(VARSIZE(arg1), VARSIZE(arg2)) - VARHDRSZ);
|
||||
@@ -2004,7 +2004,8 @@ split_text(PG_FUNCTION_ARGS)
|
||||
if (fldnum == 1) /* first field - just return the input
|
||||
* string */
|
||||
PG_RETURN_TEXT_P(inputstring);
|
||||
else /* otherwise return an empty string */
|
||||
else
|
||||
/* otherwise return an empty string */
|
||||
PG_RETURN_TEXT_P(PG_STR_GET_TEXT(""));
|
||||
}
|
||||
|
||||
@@ -2026,7 +2027,8 @@ split_text(PG_FUNCTION_ARGS)
|
||||
if (fldnum == 1) /* first field - just return the input
|
||||
* string */
|
||||
PG_RETURN_TEXT_P(inputstring);
|
||||
else /* otherwise return an empty string */
|
||||
else
|
||||
/* otherwise return an empty string */
|
||||
PG_RETURN_TEXT_P(PG_STR_GET_TEXT(""));
|
||||
}
|
||||
else if ((start_posn != 0) && (end_posn == 0))
|
||||
@@ -2073,32 +2075,36 @@ text_to_array(PG_FUNCTION_ARGS)
|
||||
if (inputstring_len < 1)
|
||||
PG_RETURN_NULL();
|
||||
|
||||
/* empty field separator
|
||||
* return one element, 1D, array using the input string */
|
||||
/*
|
||||
* empty field separator return one element, 1D, array using the input
|
||||
* string
|
||||
*/
|
||||
if (fldsep_len < 1)
|
||||
PG_RETURN_ARRAYTYPE_P(create_singleton_array(fcinfo, TEXTOID,
|
||||
CStringGetDatum(inputstring), 1));
|
||||
CStringGetDatum(inputstring), 1));
|
||||
|
||||
/* start with end position holding the initial start position */
|
||||
end_posn = 0;
|
||||
for (fldnum=1;;fldnum++) /* field number is 1 based */
|
||||
for (fldnum = 1;; fldnum++) /* field number is 1 based */
|
||||
{
|
||||
Datum dvalue;
|
||||
bool disnull = false;
|
||||
Datum dvalue;
|
||||
bool disnull = false;
|
||||
|
||||
start_posn = end_posn;
|
||||
end_posn = text_position(PointerGetDatum(inputstring),
|
||||
PointerGetDatum(fldsep),
|
||||
fldnum);
|
||||
|
||||
if ((start_posn == 0) && (end_posn == 0)) /* fldsep not found */
|
||||
if ((start_posn == 0) && (end_posn == 0)) /* fldsep not found */
|
||||
{
|
||||
if (fldnum == 1)
|
||||
{
|
||||
/* first element
|
||||
* return one element, 1D, array using the input string */
|
||||
/*
|
||||
* first element return one element, 1D, array using the
|
||||
* input string
|
||||
*/
|
||||
PG_RETURN_ARRAYTYPE_P(create_singleton_array(fcinfo, TEXTOID,
|
||||
CStringGetDatum(inputstring), 1));
|
||||
CStringGetDatum(inputstring), 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2143,7 +2149,9 @@ array_to_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ArrayType *v = PG_GETARG_ARRAYTYPE_P(0);
|
||||
char *fldsep = PG_TEXTARG_GET_STR(1);
|
||||
int nitems, *dims, ndims;
|
||||
int nitems,
|
||||
*dims,
|
||||
ndims;
|
||||
char *p;
|
||||
Oid element_type;
|
||||
int typlen;
|
||||
@@ -2167,21 +2175,24 @@ array_to_text(PG_FUNCTION_ARGS)
|
||||
|
||||
/*
|
||||
* We arrange to look up info about element type, including its output
|
||||
* conversion proc, only once per series of calls, assuming the element
|
||||
* type doesn't change underneath us.
|
||||
* conversion proc, only once per series of calls, assuming the
|
||||
* element type doesn't change underneath us.
|
||||
*/
|
||||
my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
|
||||
if (my_extra == NULL)
|
||||
{
|
||||
fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
|
||||
sizeof(ArrayMetaState));
|
||||
sizeof(ArrayMetaState));
|
||||
my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
|
||||
my_extra->element_type = InvalidOid;
|
||||
}
|
||||
|
||||
if (my_extra->element_type != element_type)
|
||||
{
|
||||
/* Get info about element type, including its output conversion proc */
|
||||
/*
|
||||
* Get info about element type, including its output conversion
|
||||
* proc
|
||||
*/
|
||||
get_type_io_data(element_type, IOFunc_output,
|
||||
&my_extra->typlen, &my_extra->typbyval,
|
||||
&my_extra->typalign, &my_extra->typdelim,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/xid.c,v 1.1 2003/05/12 23:08:50 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/xid.c,v 1.2 2003/08/04 00:43:26 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -151,7 +151,7 @@ cidrecv(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
cidsend(PG_FUNCTION_ARGS)
|
||||
{
|
||||
CommandId arg1 = PG_GETARG_COMMANDID(0);
|
||||
CommandId arg1 = PG_GETARG_COMMANDID(0);
|
||||
StringInfoData buf;
|
||||
|
||||
pq_begintypsend(&buf);
|
||||
|
||||
Reference in New Issue
Block a user