mirror of
https://github.com/postgres/postgres.git
synced 2025-11-12 05:01:15 +03:00
Pgindent run for 8.0.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.110 2004/08/29 04:12:51 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.111 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -38,9 +38,9 @@ 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 void check_circularity(const Acl *old_acl, const AclItem *mod_aip,
|
||||
AclId ownerid);
|
||||
AclId ownerid);
|
||||
static Acl *recursive_revoke(Acl *acl, AclId grantee, AclMode revoke_privs,
|
||||
AclId ownerid, DropBehavior behavior);
|
||||
AclId ownerid, DropBehavior behavior);
|
||||
static bool in_group(AclId uid, AclId gid);
|
||||
|
||||
static AclMode convert_priv_string(text *priv_type_text);
|
||||
@@ -55,7 +55,7 @@ static Oid convert_language_name(text *languagename);
|
||||
static AclMode convert_language_priv_string(text *priv_type_text);
|
||||
static Oid convert_schema_name(text *schemaname);
|
||||
static AclMode convert_schema_priv_string(text *priv_type_text);
|
||||
static Oid convert_tablespace_name(text *tablespacename);
|
||||
static Oid convert_tablespace_name(text *tablespacename);
|
||||
static AclMode convert_tablespace_priv_string(text *priv_type_text);
|
||||
|
||||
|
||||
@@ -107,8 +107,8 @@ getid(const char *s, char *n)
|
||||
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;
|
||||
}
|
||||
@@ -195,13 +195,13 @@ aclparse(const char *s, AclItem *aip)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("unrecognized key word: \"%s\"", name),
|
||||
errhint("ACL key word must be \"group\" or \"user\".")));
|
||||
errhint("ACL key word 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\" or \"user\" key word.")));
|
||||
errhint("A name must follow the \"group\" or \"user\" key word.")));
|
||||
}
|
||||
if (name[0] == '\0')
|
||||
idtype = ACL_IDTYPE_WORLD;
|
||||
@@ -295,7 +295,7 @@ aclparse(const char *s, AclItem *aip)
|
||||
aip->ai_grantor = BOOTSTRAP_USESYSID;
|
||||
ereport(WARNING,
|
||||
(errcode(ERRCODE_INVALID_GRANTOR),
|
||||
errmsg("defaulting grantor to user ID %u", BOOTSTRAP_USESYSID)));
|
||||
errmsg("defaulting grantor to user ID %u", BOOTSTRAP_USESYSID)));
|
||||
}
|
||||
|
||||
ACLITEM_SET_PRIVS_IDTYPE(*aip, privs, goption, idtype);
|
||||
@@ -568,8 +568,8 @@ acldefault(GrantObjectType objtype, AclId ownerid)
|
||||
/*
|
||||
* Note that the owner's entry shows all ordinary privileges but no
|
||||
* grant options. This is because his grant options come "from the
|
||||
* system" and not from his own efforts. (The SQL spec says that
|
||||
* the owner's rights come from a "_SYSTEM" authid.) However, we do
|
||||
* system" and not from his own efforts. (The SQL spec says that the
|
||||
* owner's rights come from a "_SYSTEM" authid.) However, we do
|
||||
* consider that the owner's ordinary privileges are self-granted;
|
||||
* this lets him revoke them. We implement the owner's grant options
|
||||
* without any explicit "_SYSTEM"-like ACL entry, by internally
|
||||
@@ -679,7 +679,7 @@ aclupdate(const Acl *old_acl, const AclItem *mod_aip,
|
||||
break;
|
||||
case ACL_MODECHG_DEL:
|
||||
ACLITEM_SET_RIGHTS(new_aip[dst],
|
||||
old_rights & ~ACLITEM_GET_RIGHTS(*mod_aip));
|
||||
old_rights & ~ACLITEM_GET_RIGHTS(*mod_aip));
|
||||
break;
|
||||
case ACL_MODECHG_EQL:
|
||||
ACLITEM_SET_RIGHTS(new_aip[dst],
|
||||
@@ -703,8 +703,8 @@ aclupdate(const Acl *old_acl, const AclItem *mod_aip,
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove abandoned privileges (cascading revoke). Currently we
|
||||
* can only handle this when the grantee is a user.
|
||||
* Remove abandoned privileges (cascading revoke). Currently we can
|
||||
* only handle this when the grantee is a user.
|
||||
*/
|
||||
if ((old_goptions & ~new_goptions) != 0)
|
||||
{
|
||||
@@ -732,11 +732,11 @@ Acl *
|
||||
aclnewowner(const Acl *old_acl, AclId oldownerid, AclId newownerid)
|
||||
{
|
||||
Acl *new_acl;
|
||||
AclItem *new_aip;
|
||||
AclItem *old_aip;
|
||||
AclItem *dst_aip;
|
||||
AclItem *src_aip;
|
||||
AclItem *targ_aip;
|
||||
AclItem *new_aip;
|
||||
AclItem *old_aip;
|
||||
AclItem *dst_aip;
|
||||
AclItem *src_aip;
|
||||
AclItem *targ_aip;
|
||||
bool newpresent = false;
|
||||
int dst,
|
||||
src,
|
||||
@@ -745,8 +745,8 @@ aclnewowner(const Acl *old_acl, AclId oldownerid, AclId newownerid)
|
||||
|
||||
/*
|
||||
* Make a copy of the given ACL, substituting new owner ID for old
|
||||
* wherever it appears as either grantor or grantee. Also note if
|
||||
* the new owner ID is already present.
|
||||
* wherever it appears as either grantor or grantee. Also note if the
|
||||
* new owner ID is already present.
|
||||
*/
|
||||
num = ACL_NUM(old_acl);
|
||||
old_aip = ACL_DAT(old_acl);
|
||||
@@ -771,7 +771,7 @@ aclnewowner(const Acl *old_acl, AclId oldownerid, AclId newownerid)
|
||||
|
||||
/*
|
||||
* If the old ACL contained any references to the new owner, then we
|
||||
* may now have generated an ACL containing duplicate entries. Find
|
||||
* may now have generated an ACL containing duplicate entries. Find
|
||||
* them and merge them so that there are not duplicates. (This is
|
||||
* relatively expensive since we use a stupid O(N^2) algorithm, but
|
||||
* it's unlikely to be the normal case.)
|
||||
@@ -779,11 +779,12 @@ aclnewowner(const Acl *old_acl, AclId oldownerid, AclId newownerid)
|
||||
* To simplify deletion of duplicate entries, we temporarily leave them
|
||||
* in the array but set their privilege masks to zero; when we reach
|
||||
* such an entry it's just skipped. (Thus, a side effect of this code
|
||||
* will be to remove privilege-free entries, should there be any in the
|
||||
* input.) dst is the next output slot, targ is the currently considered
|
||||
* input slot (always >= dst), and src scans entries to the right of targ
|
||||
* looking for duplicates. Once an entry has been emitted to dst it is
|
||||
* known duplicate-free and need not be considered anymore.
|
||||
* will be to remove privilege-free entries, should there be any in
|
||||
* the input.) dst is the next output slot, targ is the currently
|
||||
* considered input slot (always >= dst), and src scans entries to the
|
||||
* right of targ looking for duplicates. Once an entry has been
|
||||
* emitted to dst it is known duplicate-free and need not be
|
||||
* considered anymore.
|
||||
*/
|
||||
if (newpresent)
|
||||
{
|
||||
@@ -845,7 +846,7 @@ check_circularity(const Acl *old_acl, const AclItem *mod_aip,
|
||||
|
||||
/*
|
||||
* For now, grant options can only be granted to users, not groups or
|
||||
* PUBLIC. Otherwise we'd have to work a bit harder here.
|
||||
* PUBLIC. Otherwise we'd have to work a bit harder here.
|
||||
*/
|
||||
Assert(ACLITEM_GET_IDTYPE(*mod_aip) == ACL_IDTYPE_UID);
|
||||
|
||||
@@ -884,7 +885,7 @@ cc_restart:
|
||||
own_privs = aclmask(acl,
|
||||
mod_aip->ai_grantor,
|
||||
ownerid,
|
||||
ACL_GRANT_OPTION_FOR(ACLITEM_GET_GOPTIONS(*mod_aip)),
|
||||
ACL_GRANT_OPTION_FOR(ACLITEM_GET_GOPTIONS(*mod_aip)),
|
||||
ACLMASK_ALL);
|
||||
own_privs = ACL_OPTION_TO_PRIVS(own_privs);
|
||||
|
||||
@@ -1036,7 +1037,7 @@ aclmask(const Acl *acl, AclId userid, AclId ownerid,
|
||||
*/
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
AclItem *aidata = &aidat[i];
|
||||
AclItem *aidata = &aidat[i];
|
||||
|
||||
if (ACLITEM_GET_IDTYPE(*aidata) == ACL_IDTYPE_WORLD
|
||||
|| (ACLITEM_GET_IDTYPE(*aidata) == ACL_IDTYPE_UID
|
||||
@@ -1049,13 +1050,13 @@ aclmask(const Acl *acl, AclId userid, AclId ownerid,
|
||||
}
|
||||
|
||||
/*
|
||||
* Check privileges granted via groups. We do this in a separate
|
||||
* pass to minimize expensive lookups in pg_group.
|
||||
* Check privileges granted via groups. We do this in a separate pass
|
||||
* to minimize expensive lookups in pg_group.
|
||||
*/
|
||||
remaining = (mask & ~result);
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
AclItem *aidata = &aidat[i];
|
||||
AclItem *aidata = &aidat[i];
|
||||
|
||||
if (ACLITEM_GET_IDTYPE(*aidata) == ACL_IDTYPE_GID
|
||||
&& (aidata->ai_privs & remaining)
|
||||
@@ -1187,7 +1188,7 @@ makeaclitem(PG_FUNCTION_ARGS)
|
||||
|
||||
if (u_grantee == 0 && g_grantee == 0)
|
||||
{
|
||||
aclitem->ai_grantee = ACL_ID_WORLD;
|
||||
aclitem ->ai_grantee = ACL_ID_WORLD;
|
||||
|
||||
ACLITEM_SET_IDTYPE(*aclitem, ACL_IDTYPE_WORLD);
|
||||
}
|
||||
@@ -1199,18 +1200,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 /* (g_grantee != 0) */
|
||||
else
|
||||
/* (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)
|
||||
@@ -2474,11 +2476,11 @@ has_tablespace_privilege_id_id(PG_FUNCTION_ARGS)
|
||||
static Oid
|
||||
convert_tablespace_name(text *tablespacename)
|
||||
{
|
||||
char *spcname;
|
||||
char *spcname;
|
||||
Oid oid;
|
||||
|
||||
spcname = DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(tablespacename)));
|
||||
PointerGetDatum(tablespacename)));
|
||||
oid = get_tablespace_oid(spcname);
|
||||
|
||||
if (!OidIsValid(oid))
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* Copyright (c) 2003, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/array_userfuncs.c,v 1.12 2003/11/29 19:51:57 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/array_userfuncs.c,v 1.13 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -96,7 +96,7 @@ array_push(PG_FUNCTION_ARGS)
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATA_EXCEPTION),
|
||||
errmsg("argument must be empty or one-dimensional array")));
|
||||
errmsg("argument must be empty or one-dimensional array")));
|
||||
|
||||
/*
|
||||
* We arrange to look up info about element type only once per series
|
||||
@@ -245,8 +245,8 @@ array_cat(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
||||
errmsg("cannot concatenate incompatible arrays"),
|
||||
errdetail("Arrays with differing element dimensions are "
|
||||
"not compatible for concatenation.")));
|
||||
errdetail("Arrays with differing element dimensions are "
|
||||
"not compatible for concatenation.")));
|
||||
|
||||
dims[i] = dims1[i];
|
||||
lbs[i] = lbs1[i];
|
||||
@@ -351,7 +351,7 @@ create_singleton_array(FunctionCallInfo fcinfo,
|
||||
if (element_type == 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("invalid array element type OID: %u", element_type)));
|
||||
errmsg("invalid array element type OID: %u", element_type)));
|
||||
if (ndims < 1)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.109 2004/08/29 04:12:51 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.110 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -110,9 +110,9 @@ static void array_insert_slice(int ndim, int *dim, int *lb,
|
||||
int typlen, bool typbyval, char typalign);
|
||||
static int array_cmp(FunctionCallInfo fcinfo);
|
||||
static Datum array_type_length_coerce_internal(ArrayType *src,
|
||||
int32 desttypmod,
|
||||
bool isExplicit,
|
||||
FmgrInfo *fmgr_info);
|
||||
int32 desttypmod,
|
||||
bool isExplicit,
|
||||
FmgrInfo *fmgr_info);
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------
|
||||
@@ -292,13 +292,13 @@ array_in(PG_FUNCTION_ARGS)
|
||||
if (ndim_braces != ndim)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("array dimensions incompatible with array literal")));
|
||||
errmsg("array dimensions incompatible with array literal")));
|
||||
for (i = 0; i < ndim; ++i)
|
||||
{
|
||||
if (dim[i] != dim_braces[i])
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("array dimensions incompatible with array literal")));
|
||||
errmsg("array dimensions incompatible with array literal")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,17 +365,17 @@ typedef enum
|
||||
static int
|
||||
ArrayCount(char *str, int *dim, char typdelim)
|
||||
{
|
||||
int nest_level = 0,
|
||||
i;
|
||||
int ndim = 1,
|
||||
temp[MAXDIM],
|
||||
nelems[MAXDIM],
|
||||
nelems_last[MAXDIM];
|
||||
bool scanning_string = false;
|
||||
bool eoArray = false;
|
||||
bool empty_array = true;
|
||||
char *ptr;
|
||||
ArrayParseState parse_state = ARRAY_NO_LEVEL;
|
||||
int nest_level = 0,
|
||||
i;
|
||||
int ndim = 1,
|
||||
temp[MAXDIM],
|
||||
nelems[MAXDIM],
|
||||
nelems_last[MAXDIM];
|
||||
bool scanning_string = false;
|
||||
bool eoArray = false;
|
||||
bool empty_array = true;
|
||||
char *ptr;
|
||||
ArrayParseState parse_state = ARRAY_NO_LEVEL;
|
||||
|
||||
for (i = 0; i < MAXDIM; ++i)
|
||||
{
|
||||
@@ -397,7 +397,7 @@ ArrayCount(char *str, int *dim, char typdelim)
|
||||
if (parse_state == ARRAY_ELEM_STARTED ||
|
||||
parse_state == ARRAY_QUOTED_ELEM_STARTED)
|
||||
empty_array = false;
|
||||
|
||||
|
||||
switch (*ptr)
|
||||
{
|
||||
case '\0':
|
||||
@@ -407,18 +407,19 @@ ArrayCount(char *str, int *dim, char typdelim)
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
break;
|
||||
case '\\':
|
||||
|
||||
/*
|
||||
* An escape must be after a level start, after an
|
||||
* element start, or after an element delimiter. In any
|
||||
* case we now must be past an element start.
|
||||
* element start, or after an element delimiter. In
|
||||
* any case we now must be past an element start.
|
||||
*/
|
||||
if (parse_state != ARRAY_LEVEL_STARTED &&
|
||||
parse_state != ARRAY_ELEM_STARTED &&
|
||||
parse_state != ARRAY_QUOTED_ELEM_STARTED &&
|
||||
parse_state != ARRAY_ELEM_DELIMITED)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
if (parse_state != ARRAY_QUOTED_ELEM_STARTED)
|
||||
parse_state = ARRAY_ELEM_STARTED;
|
||||
/* skip the escaped character */
|
||||
@@ -430,17 +431,18 @@ ArrayCount(char *str, int *dim, char typdelim)
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
break;
|
||||
case '\"':
|
||||
|
||||
/*
|
||||
* A quote must be after a level start, after a quoted
|
||||
* element start, or after an element delimiter. In any
|
||||
* case we now must be past an element start.
|
||||
* element start, or after an element delimiter. In
|
||||
* any case we now must be past an element start.
|
||||
*/
|
||||
if (parse_state != ARRAY_LEVEL_STARTED &&
|
||||
parse_state != ARRAY_QUOTED_ELEM_STARTED &&
|
||||
parse_state != ARRAY_ELEM_DELIMITED)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
scanning_string = !scanning_string;
|
||||
if (scanning_string)
|
||||
parse_state = ARRAY_QUOTED_ELEM_STARTED;
|
||||
@@ -452,15 +454,15 @@ ArrayCount(char *str, int *dim, char typdelim)
|
||||
{
|
||||
/*
|
||||
* A left brace can occur if no nesting has
|
||||
* occurred yet, after a level start, or
|
||||
* after a level delimiter.
|
||||
* occurred yet, after a level start, or after a
|
||||
* level delimiter.
|
||||
*/
|
||||
if (parse_state != ARRAY_NO_LEVEL &&
|
||||
parse_state != ARRAY_LEVEL_STARTED &&
|
||||
parse_state != ARRAY_LEVEL_DELIMITED)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
parse_state = ARRAY_LEVEL_STARTED;
|
||||
if (nest_level >= MAXDIM)
|
||||
ereport(ERROR,
|
||||
@@ -478,17 +480,17 @@ ArrayCount(char *str, int *dim, char typdelim)
|
||||
{
|
||||
/*
|
||||
* A right brace can occur after an element start,
|
||||
* an element completion, a quoted element completion,
|
||||
* or a level completion.
|
||||
* an element completion, a quoted element
|
||||
* completion, or a level completion.
|
||||
*/
|
||||
if (parse_state != ARRAY_ELEM_STARTED &&
|
||||
parse_state != ARRAY_ELEM_COMPLETED &&
|
||||
parse_state != ARRAY_QUOTED_ELEM_COMPLETED &&
|
||||
parse_state != ARRAY_LEVEL_COMPLETED &&
|
||||
!(nest_level == 1 && parse_state == ARRAY_LEVEL_STARTED))
|
||||
!(nest_level == 1 && parse_state == ARRAY_LEVEL_STARTED))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
parse_state = ARRAY_LEVEL_COMPLETED;
|
||||
if (nest_level == 0)
|
||||
ereport(ERROR,
|
||||
@@ -497,12 +499,12 @@ ArrayCount(char *str, int *dim, char typdelim)
|
||||
nest_level--;
|
||||
|
||||
if ((nelems_last[nest_level] != 1) &&
|
||||
(nelems[nest_level] != nelems_last[nest_level]))
|
||||
(nelems[nest_level] != nelems_last[nest_level]))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("multidimensional arrays must have "
|
||||
"array expressions with matching "
|
||||
"dimensions")));
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("multidimensional arrays must have "
|
||||
"array expressions with matching "
|
||||
"dimensions")));
|
||||
nelems_last[nest_level] = nelems[nest_level];
|
||||
nelems[nest_level] = 1;
|
||||
if (nest_level == 0)
|
||||
@@ -523,17 +525,17 @@ ArrayCount(char *str, int *dim, char typdelim)
|
||||
if (*ptr == typdelim)
|
||||
{
|
||||
/*
|
||||
* Delimiters can occur after an element start,
|
||||
* an element completion, a quoted element
|
||||
* completion, or a level completion.
|
||||
*/
|
||||
* Delimiters can occur after an element
|
||||
* start, an element completion, a quoted
|
||||
* element completion, or a level completion.
|
||||
*/
|
||||
if (parse_state != ARRAY_ELEM_STARTED &&
|
||||
parse_state != ARRAY_ELEM_COMPLETED &&
|
||||
parse_state != ARRAY_QUOTED_ELEM_COMPLETED &&
|
||||
parse_state != ARRAY_QUOTED_ELEM_COMPLETED &&
|
||||
parse_state != ARRAY_LEVEL_COMPLETED)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
if (parse_state == ARRAY_LEVEL_COMPLETED)
|
||||
parse_state = ARRAY_LEVEL_DELIMITED;
|
||||
else
|
||||
@@ -544,17 +546,17 @@ ArrayCount(char *str, int *dim, char typdelim)
|
||||
else if (!isspace(*ptr))
|
||||
{
|
||||
/*
|
||||
* Other non-space characters must be after a level
|
||||
* start, after an element start, or after an element
|
||||
* delimiter. In any case we now must be past an
|
||||
* element start.
|
||||
*/
|
||||
* Other non-space characters must be after a
|
||||
* level start, after an element start, or
|
||||
* after an element delimiter. In any case we
|
||||
* now must be past an element start.
|
||||
*/
|
||||
if (parse_state != ARRAY_LEVEL_STARTED &&
|
||||
parse_state != ARRAY_ELEM_STARTED &&
|
||||
parse_state != ARRAY_ELEM_DELIMITED)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
parse_state = ARRAY_ELEM_STARTED;
|
||||
}
|
||||
}
|
||||
@@ -566,20 +568,20 @@ ArrayCount(char *str, int *dim, char typdelim)
|
||||
temp[ndim - 1]++;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
|
||||
/* only whitespace is allowed after the closing brace */
|
||||
while (*ptr)
|
||||
{
|
||||
if (!isspace(*ptr++))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed array literal: \"%s\"", str)));
|
||||
}
|
||||
|
||||
|
||||
/* special case for an empty array */
|
||||
if (empty_array)
|
||||
return 0;
|
||||
|
||||
|
||||
for (i = 0; i < ndim; ++i)
|
||||
dim[i] = temp[i];
|
||||
|
||||
@@ -675,7 +677,11 @@ ReadArrayStr(char *arrayStr,
|
||||
if (scanning_string)
|
||||
{
|
||||
itemquoted = true;
|
||||
/* Crunch the string on top of the first quote. */
|
||||
|
||||
/*
|
||||
* Crunch the string on top of the first
|
||||
* quote.
|
||||
*/
|
||||
for (cptr = ptr; *cptr != '\0'; cptr++)
|
||||
*cptr = *(cptr + 1);
|
||||
/* Back up to not miss following character. */
|
||||
@@ -874,11 +880,12 @@ array_out(PG_FUNCTION_ARGS)
|
||||
*tmp,
|
||||
*retval,
|
||||
**values,
|
||||
/*
|
||||
* 33 per dim since we assume 15 digits per number + ':' +'[]'
|
||||
*
|
||||
* +2 allows for assignment operator + trailing null
|
||||
*/
|
||||
|
||||
/*
|
||||
* 33 per dim since we assume 15 digits per number + ':' +'[]'
|
||||
*
|
||||
* +2 allows for assignment operator + trailing null
|
||||
*/
|
||||
dims_str[(MAXDIM * 33) + 2];
|
||||
bool *needquotes,
|
||||
needdims = false;
|
||||
@@ -941,8 +948,8 @@ array_out(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
/*
|
||||
* we will need to add explicit dimensions if any dimension
|
||||
* has a lower bound other than one
|
||||
* we will need to add explicit dimensions if any dimension has a
|
||||
* lower bound other than one
|
||||
*/
|
||||
for (i = 0; i < ndim; i++)
|
||||
{
|
||||
@@ -970,7 +977,7 @@ array_out(PG_FUNCTION_ARGS)
|
||||
itemvalue = fetch_att(p, typbyval, typlen);
|
||||
values[i] = DatumGetCString(FunctionCall3(&my_extra->proc,
|
||||
itemvalue,
|
||||
ObjectIdGetDatum(typioparam),
|
||||
ObjectIdGetDatum(typioparam),
|
||||
Int32GetDatum(-1)));
|
||||
p = att_addlength(p, typlen, PointerGetDatum(p));
|
||||
p = (char *) att_align(p, typalign);
|
||||
@@ -1012,7 +1019,7 @@ array_out(PG_FUNCTION_ARGS)
|
||||
/* add explicit dimensions if required */
|
||||
if (needdims)
|
||||
{
|
||||
char *ptr = dims_str;
|
||||
char *ptr = dims_str;
|
||||
|
||||
for (i = 0; i < ndim; i++)
|
||||
{
|
||||
@@ -1392,7 +1399,7 @@ array_send(PG_FUNCTION_ARGS)
|
||||
|
||||
outputbytes = DatumGetByteaP(FunctionCall2(&my_extra->proc,
|
||||
itemvalue,
|
||||
ObjectIdGetDatum(typioparam)));
|
||||
ObjectIdGetDatum(typioparam)));
|
||||
/* We assume the result will not have been toasted */
|
||||
pq_sendint(&buf, VARSIZE(outputbytes) - VARHDRSZ, 4);
|
||||
pq_sendbytes(&buf, VARDATA(outputbytes),
|
||||
@@ -2540,8 +2547,8 @@ array_eq(PG_FUNCTION_ARGS)
|
||||
/*
|
||||
* We arrange to look up the equality function only once per
|
||||
* series of calls, assuming the element type doesn't change
|
||||
* underneath us. The typcache is used so that we have no
|
||||
* memory leakage when being used as an index support function.
|
||||
* underneath us. The typcache is used so that we have no memory
|
||||
* leakage when being used as an index support function.
|
||||
*/
|
||||
typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
|
||||
if (typentry == NULL ||
|
||||
@@ -2688,10 +2695,10 @@ array_cmp(FunctionCallInfo fcinfo)
|
||||
errmsg("cannot compare arrays of different element types")));
|
||||
|
||||
/*
|
||||
* We arrange to look up the comparison function only once per series of
|
||||
* calls, assuming the element type doesn't change underneath us.
|
||||
* The typcache is used so that we have no memory leakage when being used
|
||||
* as an index support function.
|
||||
* We arrange to look up the comparison function only once per series
|
||||
* of calls, assuming the element type doesn't change underneath us.
|
||||
* The typcache is used so that we have no memory leakage when being
|
||||
* used as an index support function.
|
||||
*/
|
||||
typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
|
||||
if (typentry == NULL ||
|
||||
@@ -2702,8 +2709,8 @@ array_cmp(FunctionCallInfo fcinfo)
|
||||
if (!OidIsValid(typentry->cmp_proc_finfo.fn_oid))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_FUNCTION),
|
||||
errmsg("could not identify a comparison function for type %s",
|
||||
format_type_be(element_type))));
|
||||
errmsg("could not identify a comparison function for type %s",
|
||||
format_type_be(element_type))));
|
||||
fcinfo->flinfo->fn_extra = (void *) typentry;
|
||||
}
|
||||
typlen = typentry->typlen;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Portions Copyright (c) 1999-2004, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ascii.c,v 1.21 2004/08/29 04:12:51 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ascii.c,v 1.22 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -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("encoding conversion from %s to ASCII not supported",
|
||||
pg_encoding_to_char(enc))));
|
||||
errmsg("encoding conversion from %s to ASCII not supported",
|
||||
pg_encoding_to_char(enc))));
|
||||
return; /* keep compiler quiet */
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/bool.c,v 1.34 2004/08/29 04:12:51 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/bool.c,v 1.35 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -256,7 +256,8 @@ isnotfalse(PG_FUNCTION_ARGS)
|
||||
/* function for standard EVERY aggregate implementation conforming to SQL 2003.
|
||||
* must be strict. It is also named bool_and for homogeneity.
|
||||
*/
|
||||
Datum booland_statefunc(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
booland_statefunc(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_RETURN_BOOL(PG_GETARG_BOOL(0) && PG_GETARG_BOOL(1));
|
||||
}
|
||||
@@ -264,7 +265,8 @@ Datum booland_statefunc(PG_FUNCTION_ARGS)
|
||||
/* function for standard ANY/SOME aggregate conforming to SQL 2003.
|
||||
* must be strict. The name of the aggregate is bool_or. See the doc.
|
||||
*/
|
||||
Datum boolor_statefunc(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
boolor_statefunc(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_RETURN_BOOL(PG_GETARG_BOOL(0) || PG_GETARG_BOOL(1));
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* workings can be found in the book "Software Solutions in C" by
|
||||
* Dale Schumacher, Academic Press, ISBN: 0-12-632360-7.
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/cash.c,v 1.63 2004/05/07 00:24:58 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/cash.c,v 1.64 2004/08/29 05:06:49 momjian Exp $
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
@@ -195,7 +195,7 @@ cash_in(PG_FUNCTION_ARGS)
|
||||
if (*s != '\0')
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type money: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for type money: \"%s\"", str)));
|
||||
|
||||
result = (value * sgn);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.101 2004/08/29 04:12:51 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.102 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -57,7 +57,7 @@ date_in(PG_FUNCTION_ARGS)
|
||||
char *str = PG_GETARG_CSTRING(0);
|
||||
DateADT date;
|
||||
fsec_t fsec;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
int tzp;
|
||||
int dtype;
|
||||
@@ -111,7 +111,7 @@ date_out(PG_FUNCTION_ARGS)
|
||||
{
|
||||
DateADT date = PG_GETARG_DATEADT(0);
|
||||
char *result;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
char buf[MAXDATELEN + 1];
|
||||
|
||||
@@ -292,7 +292,7 @@ static TimestampTz
|
||||
date2timestamptz(DateADT dateVal)
|
||||
{
|
||||
TimestampTz result;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
int tz;
|
||||
|
||||
@@ -407,8 +407,8 @@ Datum
|
||||
date_eq_timestamptz(PG_FUNCTION_ARGS)
|
||||
{
|
||||
DateADT dateVal = PG_GETARG_DATEADT(0);
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
|
||||
dt1 = date2timestamptz(dateVal);
|
||||
|
||||
@@ -419,8 +419,8 @@ Datum
|
||||
date_ne_timestamptz(PG_FUNCTION_ARGS)
|
||||
{
|
||||
DateADT dateVal = PG_GETARG_DATEADT(0);
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
|
||||
dt1 = date2timestamptz(dateVal);
|
||||
|
||||
@@ -431,8 +431,8 @@ Datum
|
||||
date_lt_timestamptz(PG_FUNCTION_ARGS)
|
||||
{
|
||||
DateADT dateVal = PG_GETARG_DATEADT(0);
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
|
||||
dt1 = date2timestamptz(dateVal);
|
||||
|
||||
@@ -443,8 +443,8 @@ Datum
|
||||
date_gt_timestamptz(PG_FUNCTION_ARGS)
|
||||
{
|
||||
DateADT dateVal = PG_GETARG_DATEADT(0);
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
|
||||
dt1 = date2timestamptz(dateVal);
|
||||
|
||||
@@ -455,8 +455,8 @@ Datum
|
||||
date_le_timestamptz(PG_FUNCTION_ARGS)
|
||||
{
|
||||
DateADT dateVal = PG_GETARG_DATEADT(0);
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
|
||||
dt1 = date2timestamptz(dateVal);
|
||||
|
||||
@@ -467,8 +467,8 @@ Datum
|
||||
date_ge_timestamptz(PG_FUNCTION_ARGS)
|
||||
{
|
||||
DateADT dateVal = PG_GETARG_DATEADT(0);
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
|
||||
dt1 = date2timestamptz(dateVal);
|
||||
|
||||
@@ -479,8 +479,8 @@ Datum
|
||||
date_cmp_timestamptz(PG_FUNCTION_ARGS)
|
||||
{
|
||||
DateADT dateVal = PG_GETARG_DATEADT(0);
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
|
||||
dt1 = date2timestamptz(dateVal);
|
||||
|
||||
@@ -574,9 +574,9 @@ timestamp_cmp_date(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
timestamptz_eq_date(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
DateADT dateVal = PG_GETARG_DATEADT(1);
|
||||
TimestampTz dt2;
|
||||
TimestampTz dt2;
|
||||
|
||||
dt2 = date2timestamptz(dateVal);
|
||||
|
||||
@@ -586,9 +586,9 @@ timestamptz_eq_date(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
timestamptz_ne_date(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
DateADT dateVal = PG_GETARG_DATEADT(1);
|
||||
TimestampTz dt2;
|
||||
TimestampTz dt2;
|
||||
|
||||
dt2 = date2timestamptz(dateVal);
|
||||
|
||||
@@ -598,9 +598,9 @@ timestamptz_ne_date(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
timestamptz_lt_date(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
DateADT dateVal = PG_GETARG_DATEADT(1);
|
||||
TimestampTz dt2;
|
||||
TimestampTz dt2;
|
||||
|
||||
dt2 = date2timestamptz(dateVal);
|
||||
|
||||
@@ -610,9 +610,9 @@ timestamptz_lt_date(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
timestamptz_gt_date(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
DateADT dateVal = PG_GETARG_DATEADT(1);
|
||||
TimestampTz dt2;
|
||||
TimestampTz dt2;
|
||||
|
||||
dt2 = date2timestamptz(dateVal);
|
||||
|
||||
@@ -622,9 +622,9 @@ timestamptz_gt_date(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
timestamptz_le_date(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
DateADT dateVal = PG_GETARG_DATEADT(1);
|
||||
TimestampTz dt2;
|
||||
TimestampTz dt2;
|
||||
|
||||
dt2 = date2timestamptz(dateVal);
|
||||
|
||||
@@ -634,9 +634,9 @@ timestamptz_le_date(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
timestamptz_ge_date(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
DateADT dateVal = PG_GETARG_DATEADT(1);
|
||||
TimestampTz dt2;
|
||||
TimestampTz dt2;
|
||||
|
||||
dt2 = date2timestamptz(dateVal);
|
||||
|
||||
@@ -646,9 +646,9 @@ timestamptz_ge_date(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
timestamptz_cmp_date(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
DateADT dateVal = PG_GETARG_DATEADT(1);
|
||||
TimestampTz dt2;
|
||||
TimestampTz dt2;
|
||||
|
||||
dt2 = date2timestamptz(dateVal);
|
||||
|
||||
@@ -719,7 +719,7 @@ timestamp_date(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
|
||||
DateADT result;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
fsec_t fsec;
|
||||
|
||||
@@ -760,7 +760,7 @@ timestamptz_date(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimestampTz timestamp = PG_GETARG_TIMESTAMP(0);
|
||||
DateADT result;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
fsec_t fsec;
|
||||
int tz;
|
||||
@@ -788,7 +788,7 @@ abstime_date(PG_FUNCTION_ARGS)
|
||||
{
|
||||
AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0);
|
||||
DateADT result;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
int tz;
|
||||
|
||||
@@ -889,7 +889,7 @@ time_in(PG_FUNCTION_ARGS)
|
||||
int32 typmod = PG_GETARG_INT32(2);
|
||||
TimeADT result;
|
||||
fsec_t fsec;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
int tz;
|
||||
int nf;
|
||||
@@ -963,7 +963,7 @@ time_out(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimeADT time = PG_GETARG_TIMEADT(0);
|
||||
char *result;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
fsec_t fsec;
|
||||
char buf[MAXDATELEN + 1];
|
||||
@@ -1324,7 +1324,7 @@ timestamp_time(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
|
||||
TimeADT result;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
fsec_t fsec;
|
||||
|
||||
@@ -1359,7 +1359,7 @@ timestamptz_time(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimestampTz timestamp = PG_GETARG_TIMESTAMP(0);
|
||||
TimeADT result;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
int tz;
|
||||
fsec_t fsec;
|
||||
@@ -1615,7 +1615,7 @@ time_part(PG_FUNCTION_ARGS)
|
||||
if (type == UNITS)
|
||||
{
|
||||
fsec_t fsec;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
|
||||
time2tm(time, tm, &fsec);
|
||||
@@ -1729,7 +1729,7 @@ timetz_in(PG_FUNCTION_ARGS)
|
||||
int32 typmod = PG_GETARG_INT32(2);
|
||||
TimeTzADT *result;
|
||||
fsec_t fsec;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
int tz;
|
||||
int nf;
|
||||
@@ -1760,7 +1760,7 @@ timetz_out(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimeTzADT *time = PG_GETARG_TIMETZADT_P(0);
|
||||
char *result;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
fsec_t fsec;
|
||||
int tz;
|
||||
@@ -2211,7 +2211,7 @@ time_timetz(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimeADT time = PG_GETARG_TIMEADT(0);
|
||||
TimeTzADT *result;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
fsec_t fsec;
|
||||
int tz;
|
||||
@@ -2237,7 +2237,7 @@ timestamptz_timetz(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimestampTz timestamp = PG_GETARG_TIMESTAMP(0);
|
||||
TimeTzADT *result;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
int tz;
|
||||
fsec_t fsec;
|
||||
@@ -2327,8 +2327,8 @@ text_timetz(PG_FUNCTION_ARGS)
|
||||
if (VARSIZE(str) - VARHDRSZ > MAXDATELEN)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("invalid input syntax for type time with time zone: \"%s\"",
|
||||
VARDATA(str))));
|
||||
errmsg("invalid input syntax for type time with time zone: \"%s\"",
|
||||
VARDATA(str))));
|
||||
|
||||
sp = VARDATA(str);
|
||||
dp = dstr;
|
||||
@@ -2368,7 +2368,7 @@ timetz_part(PG_FUNCTION_ARGS)
|
||||
double dummy;
|
||||
int tz;
|
||||
fsec_t fsec;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
|
||||
timetz2tm(time, tm, &fsec, &tz);
|
||||
@@ -2452,8 +2452,8 @@ timetz_part(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("\"time with time zone\" units \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
errmsg("\"time with time zone\" units \"%s\" not recognized",
|
||||
DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(units))))));
|
||||
|
||||
result = 0;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.132 2004/08/29 04:12:51 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.133 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1223,7 +1223,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
case DTK_TIME:
|
||||
/* previous field was "t" for ISO time */
|
||||
dterr = DecodeNumberField(strlen(field[i]), field[i],
|
||||
(fmask | DTK_DATE_M),
|
||||
(fmask | DTK_DATE_M),
|
||||
&tmask, tm,
|
||||
fsec, &is2digits);
|
||||
if (dterr < 0)
|
||||
@@ -1543,7 +1543,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
|
||||
/*
|
||||
* Check for valid day of month, now that we know for sure the
|
||||
* month and year. Note we don't use MD_FIELD_OVERFLOW here,
|
||||
* month and year. Note we don't use MD_FIELD_OVERFLOW here,
|
||||
* since it seems unlikely that "Feb 29" is a YMD-order error.
|
||||
*/
|
||||
if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
|
||||
@@ -1582,7 +1582,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
* any faster than this code.
|
||||
*/
|
||||
int
|
||||
DetermineLocalTimeZone(struct pg_tm *tm)
|
||||
DetermineLocalTimeZone(struct pg_tm * tm)
|
||||
{
|
||||
int tz;
|
||||
int date,
|
||||
@@ -1592,7 +1592,7 @@ DetermineLocalTimeZone(struct pg_tm *tm)
|
||||
locsec,
|
||||
delta1,
|
||||
delta2;
|
||||
struct pg_tm *tx;
|
||||
struct pg_tm *tx;
|
||||
|
||||
if (HasCTZSet)
|
||||
{
|
||||
@@ -1602,9 +1602,9 @@ DetermineLocalTimeZone(struct pg_tm *tm)
|
||||
|
||||
/*
|
||||
* First, generate the pg_time_t value corresponding to the given
|
||||
* y/m/d/h/m/s taken as GMT time. If this overflows, punt and
|
||||
* decide the timezone is GMT. (We only need to worry about overflow
|
||||
* on machines where pg_time_t is 32 bits.)
|
||||
* y/m/d/h/m/s taken as GMT time. If this overflows, punt and decide
|
||||
* the timezone is GMT. (We only need to worry about overflow on
|
||||
* machines where pg_time_t is 32 bits.)
|
||||
*/
|
||||
if (!IS_VALID_JULIAN(tm->tm_year, tm->tm_mon, tm->tm_mday))
|
||||
goto overflow;
|
||||
@@ -1619,8 +1619,8 @@ DetermineLocalTimeZone(struct pg_tm *tm)
|
||||
goto overflow;
|
||||
|
||||
/*
|
||||
* Use pg_localtime to convert that pg_time_t to broken-down time,
|
||||
* and reassemble to get a representation of local time. (We could get
|
||||
* Use pg_localtime to convert that pg_time_t to broken-down time, and
|
||||
* reassemble to get a representation of local time. (We could get
|
||||
* overflow of a few hours in the result, but the delta calculation
|
||||
* should still work.)
|
||||
*/
|
||||
@@ -1638,12 +1638,12 @@ DetermineLocalTimeZone(struct pg_tm *tm)
|
||||
delta1 = mysec - locsec;
|
||||
|
||||
/*
|
||||
* However, if that GMT time and the local time we are
|
||||
* actually interested in are on opposite sides of a
|
||||
* daylight-savings-time transition, then this is not the time
|
||||
* offset we want. So, adjust the pg_time_t to be what we think
|
||||
* the GMT time corresponding to our target local time is, and
|
||||
* repeat the pg_localtime() call and delta calculation.
|
||||
* However, if that GMT time and the local time we are actually
|
||||
* interested in are on opposite sides of a daylight-savings-time
|
||||
* transition, then this is not the time offset we want. So, adjust
|
||||
* the pg_time_t to be what we think the GMT time corresponding to our
|
||||
* target local time is, and repeat the pg_localtime() call and delta
|
||||
* calculation.
|
||||
*
|
||||
* We have to watch out for overflow while adjusting the pg_time_t.
|
||||
*/
|
||||
@@ -1662,13 +1662,13 @@ DetermineLocalTimeZone(struct pg_tm *tm)
|
||||
/*
|
||||
* We may have to do it again to get the correct delta.
|
||||
*
|
||||
* It might seem we should just loop until we get the same delta
|
||||
* twice in a row, but if we've been given an "impossible" local
|
||||
* time (in the gap during a spring-forward transition) we'd never
|
||||
* get out of the loop. The behavior we want is that "impossible"
|
||||
* times are taken as standard time, and also that ambiguous times
|
||||
* (during a fall-back transition) are taken as standard time.
|
||||
* Therefore, we bias the code to prefer the standard-time solution.
|
||||
* It might seem we should just loop until we get the same delta twice in
|
||||
* a row, but if we've been given an "impossible" local time (in the
|
||||
* gap during a spring-forward transition) we'd never get out of the
|
||||
* loop. The behavior we want is that "impossible" times are taken as
|
||||
* standard time, and also that ambiguous times (during a fall-back
|
||||
* transition) are taken as standard time. Therefore, we bias the code
|
||||
* to prefer the standard-time solution.
|
||||
*/
|
||||
if (delta2 != delta1 && tx->tm_isdst != 0)
|
||||
{
|
||||
@@ -1679,7 +1679,7 @@ DetermineLocalTimeZone(struct pg_tm *tm)
|
||||
mysec += delta2;
|
||||
tx = pg_localtime(&mysec);
|
||||
if (!tx)
|
||||
goto overflow; /* probably can't happen */
|
||||
goto overflow; /* probably can't happen */
|
||||
day = date2j(tx->tm_year + 1900, tx->tm_mon + 1, tx->tm_mday) -
|
||||
UNIX_EPOCH_JDATE;
|
||||
locsec = tx->tm_sec + (tx->tm_min + (day * 24 + tx->tm_hour) * 60) * 60;
|
||||
@@ -1985,7 +1985,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
|
||||
case DTK_TIME:
|
||||
/* previous field was "t" for ISO time */
|
||||
dterr = DecodeNumberField(strlen(field[i]), field[i],
|
||||
(fmask | DTK_DATE_M),
|
||||
(fmask | DTK_DATE_M),
|
||||
&tmask, tm,
|
||||
fsec, &is2digits);
|
||||
if (dterr < 0)
|
||||
@@ -2034,7 +2034,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
|
||||
* fields later. Example: 20011223 or 040506
|
||||
*/
|
||||
dterr = DecodeNumberField(flen, field[i],
|
||||
(fmask | DTK_DATE_M),
|
||||
(fmask | DTK_DATE_M),
|
||||
&tmask, tm,
|
||||
fsec, &is2digits);
|
||||
if (dterr < 0)
|
||||
@@ -2214,7 +2214,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
|
||||
/* timezone not specified? then find local timezone if possible */
|
||||
if ((tzp != NULL) && (!(fmask & DTK_M(TZ))))
|
||||
{
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tmp = &tt;
|
||||
|
||||
/*
|
||||
@@ -2567,11 +2567,12 @@ DecodeNumber(int flen, char *str, bool haveTextMonth, int fmask,
|
||||
if (haveTextMonth)
|
||||
{
|
||||
/*
|
||||
* We are at the first numeric field of a date that included
|
||||
* a textual month name. We want to support the variants
|
||||
* MON-DD-YYYY, DD-MON-YYYY, and YYYY-MON-DD as unambiguous
|
||||
* inputs. We will also accept MON-DD-YY or DD-MON-YY in
|
||||
* either DMY or MDY modes, as well as YY-MON-DD in YMD mode.
|
||||
* We are at the first numeric field of a date that
|
||||
* included a textual month name. We want to support the
|
||||
* variants MON-DD-YYYY, DD-MON-YYYY, and YYYY-MON-DD as
|
||||
* unambiguous inputs. We will also accept MON-DD-YY or
|
||||
* DD-MON-YY in either DMY or MDY modes, as well as
|
||||
* YY-MON-DD in YMD mode.
|
||||
*/
|
||||
if (flen >= 3 || DateOrder == DATEORDER_YMD)
|
||||
{
|
||||
@@ -2599,7 +2600,7 @@ DecodeNumber(int flen, char *str, bool haveTextMonth, int fmask,
|
||||
if (flen >= 3 && *is2digits)
|
||||
{
|
||||
/* Guess that first numeric field is day was wrong */
|
||||
*tmask = DTK_M(DAY); /* YEAR is already set */
|
||||
*tmask = DTK_M(DAY); /* YEAR is already set */
|
||||
tm->tm_mday = tm->tm_year;
|
||||
tm->tm_year = val;
|
||||
*is2digits = FALSE;
|
||||
@@ -2645,8 +2646,8 @@ DecodeNumber(int flen, char *str, bool haveTextMonth, int fmask,
|
||||
}
|
||||
|
||||
/*
|
||||
* When processing a year field, mark it for adjustment if it's
|
||||
* only one or two digits.
|
||||
* When processing a year field, mark it for adjustment if it's only
|
||||
* one or two digits.
|
||||
*/
|
||||
if (*tmask == DTK_M(YEAR))
|
||||
*is2digits = (flen <= 2);
|
||||
@@ -2664,7 +2665,7 @@ DecodeNumber(int flen, char *str, bool haveTextMonth, int fmask,
|
||||
*/
|
||||
static int
|
||||
DecodeNumberField(int len, char *str, int fmask,
|
||||
int *tmask, struct pg_tm * tm, fsec_t *fsec, int *is2digits)
|
||||
int *tmask, struct pg_tm * tm, fsec_t *fsec, int *is2digits)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
@@ -2974,7 +2975,7 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct pg_tm * tm,
|
||||
while ((*cp != '\0') && (*cp != ':') && (*cp != '.'))
|
||||
cp++;
|
||||
if ((*cp == ':') &&
|
||||
(DecodeTime(field[i] + 1, fmask, &tmask, tm, fsec) == 0))
|
||||
(DecodeTime(field[i] + 1, fmask, &tmask, tm, fsec) == 0))
|
||||
{
|
||||
if (*field[i] == '-')
|
||||
{
|
||||
@@ -3328,9 +3329,9 @@ DateTimeParseError(int dterr, const char *str, const char *datatype)
|
||||
break;
|
||||
case DTERR_TZDISP_OVERFLOW:
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE),
|
||||
errmsg("time zone displacement out of range: \"%s\"",
|
||||
str)));
|
||||
(errcode(ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE),
|
||||
errmsg("time zone displacement out of range: \"%s\"",
|
||||
str)));
|
||||
break;
|
||||
case DTERR_BAD_FORMAT:
|
||||
default:
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/encode.c,v 1.12 2004/08/29 04:12:51 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/encode.c,v 1.13 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -175,7 +175,7 @@ hex_decode(const uint8 *src, unsigned len, uint8 *dst)
|
||||
if (s >= srcend)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("invalid hexadecimal data: odd number of digits")));
|
||||
errmsg("invalid hexadecimal data: odd number of digits")));
|
||||
|
||||
v2 = get_hex(*s++);
|
||||
*p++ = v1 | v2;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.108 2004/08/29 04:12:51 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.109 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -102,6 +102,7 @@ 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);
|
||||
|
||||
#ifndef HAVE_CBRT
|
||||
static double cbrt(double x);
|
||||
#endif /* HAVE_CBRT */
|
||||
@@ -123,10 +124,11 @@ get_float8_infinity(void)
|
||||
/* C99 standard way */
|
||||
return (double) INFINITY;
|
||||
#else
|
||||
|
||||
/*
|
||||
* On some platforms, HUGE_VAL is an infinity, elsewhere it's just the
|
||||
* largest normal double. We assume forcing an overflow will get us
|
||||
* a true infinity.
|
||||
* largest normal double. We assume forcing an overflow will get us a
|
||||
* true infinity.
|
||||
*/
|
||||
return (double) (HUGE_VAL * HUGE_VAL);
|
||||
#endif
|
||||
@@ -139,10 +141,11 @@ get_float4_infinity(void)
|
||||
/* C99 standard way */
|
||||
return (float) INFINITY;
|
||||
#else
|
||||
|
||||
/*
|
||||
* On some platforms, HUGE_VAL is an infinity, elsewhere it's just the
|
||||
* largest normal double. We assume forcing an overflow will get us
|
||||
* a true infinity.
|
||||
* largest normal double. We assume forcing an overflow will get us a
|
||||
* true infinity.
|
||||
*/
|
||||
return (float) (HUGE_VAL * HUGE_VAL);
|
||||
#endif
|
||||
@@ -183,7 +186,7 @@ get_float4_nan(void)
|
||||
int
|
||||
is_infinite(double val)
|
||||
{
|
||||
int inf = isinf(val);
|
||||
int inf = isinf(val);
|
||||
|
||||
if (inf == 0)
|
||||
return 0;
|
||||
@@ -250,20 +253,19 @@ float4in(PG_FUNCTION_ARGS)
|
||||
|
||||
/*
|
||||
* endptr points to the first character _after_ the sequence we
|
||||
* recognized as a valid floating point number. orig_num points to
|
||||
* the original input string.
|
||||
* recognized as a valid floating point number. orig_num points to the
|
||||
* original input string.
|
||||
*/
|
||||
orig_num = num;
|
||||
|
||||
/*
|
||||
* Check for an empty-string input to begin with, to avoid
|
||||
* the vagaries of strtod() on different platforms.
|
||||
* Check for an empty-string input to begin with, to avoid the
|
||||
* vagaries of strtod() on different platforms.
|
||||
*
|
||||
* In releases prior to 8.0, we accepted an empty string as valid
|
||||
* input (yielding a float4 of 0). In 8.0, we accept empty
|
||||
* strings, but emit a warning noting that the feature is
|
||||
* deprecated. In 8.1+, the warning should be replaced by an
|
||||
* error.
|
||||
* In releases prior to 8.0, we accepted an empty string as valid input
|
||||
* (yielding a float4 of 0). In 8.0, we accept empty strings, but emit
|
||||
* a warning noting that the feature is deprecated. In 8.1+, the
|
||||
* warning should be replaced by an error.
|
||||
*/
|
||||
if (*num == '\0')
|
||||
{
|
||||
@@ -286,9 +288,9 @@ float4in(PG_FUNCTION_ARGS)
|
||||
if (endptr == num || errno != 0)
|
||||
{
|
||||
/*
|
||||
* C99 requires that strtod() accept NaN and [-]Infinity, but
|
||||
* not all platforms support that yet (and some accept them but
|
||||
* set ERANGE anyway...) Therefore, we check for these inputs
|
||||
* C99 requires that strtod() accept NaN and [-]Infinity, but not
|
||||
* all platforms support that yet (and some accept them but set
|
||||
* ERANGE anyway...) Therefore, we check for these inputs
|
||||
* ourselves.
|
||||
*/
|
||||
if (pg_strncasecmp(num, "NaN", 3) == 0)
|
||||
@@ -303,7 +305,7 @@ float4in(PG_FUNCTION_ARGS)
|
||||
}
|
||||
else if (pg_strncasecmp(num, "-Infinity", 9) == 0)
|
||||
{
|
||||
val = - get_float4_infinity();
|
||||
val = -get_float4_infinity();
|
||||
endptr = num + 9;
|
||||
}
|
||||
else if (errno == ERANGE)
|
||||
@@ -322,13 +324,13 @@ float4in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/*
|
||||
* Many versions of Solaris have a bug wherein strtod sets endptr
|
||||
* to point one byte beyond the end of the string when given
|
||||
* "inf" or "infinity".
|
||||
* to point one byte beyond the end of the string when given "inf"
|
||||
* or "infinity".
|
||||
*/
|
||||
if (endptr != num && endptr[-1] == '\0')
|
||||
endptr--;
|
||||
}
|
||||
#endif /* HAVE_BUGGY_SOLARIS_STRTOD */
|
||||
#endif /* HAVE_BUGGY_SOLARIS_STRTOD */
|
||||
|
||||
/* skip trailing whitespace */
|
||||
while (*endptr != '\0' && isspace((unsigned char) *endptr))
|
||||
@@ -373,13 +375,14 @@ float4out(PG_FUNCTION_ARGS)
|
||||
strcpy(ascii, "-Infinity");
|
||||
break;
|
||||
default:
|
||||
{
|
||||
int ndig = FLT_DIG + extra_float_digits;
|
||||
if (ndig < 1)
|
||||
ndig = 1;
|
||||
{
|
||||
int ndig = FLT_DIG + extra_float_digits;
|
||||
|
||||
sprintf(ascii, "%.*g", ndig, num);
|
||||
}
|
||||
if (ndig < 1)
|
||||
ndig = 1;
|
||||
|
||||
sprintf(ascii, "%.*g", ndig, num);
|
||||
}
|
||||
}
|
||||
|
||||
PG_RETURN_CSTRING(ascii);
|
||||
@@ -427,26 +430,25 @@ float8in(PG_FUNCTION_ARGS)
|
||||
|
||||
/*
|
||||
* endptr points to the first character _after_ the sequence we
|
||||
* recognized as a valid floating point number. orig_num points to
|
||||
* the original input string.
|
||||
* recognized as a valid floating point number. orig_num points to the
|
||||
* original input string.
|
||||
*/
|
||||
orig_num = num;
|
||||
|
||||
/*
|
||||
* Check for an empty-string input to begin with, to avoid
|
||||
* the vagaries of strtod() on different platforms.
|
||||
* Check for an empty-string input to begin with, to avoid the
|
||||
* vagaries of strtod() on different platforms.
|
||||
*
|
||||
* In releases prior to 8.0, we accepted an empty string as valid
|
||||
* input (yielding a float8 of 0). In 8.0, we accept empty
|
||||
* strings, but emit a warning noting that the feature is
|
||||
* deprecated. In 8.1+, the warning should be replaced by an
|
||||
* error.
|
||||
* In releases prior to 8.0, we accepted an empty string as valid input
|
||||
* (yielding a float8 of 0). In 8.0, we accept empty strings, but emit
|
||||
* a warning noting that the feature is deprecated. In 8.1+, the
|
||||
* warning should be replaced by an error.
|
||||
*/
|
||||
if (*num == '\0')
|
||||
{
|
||||
ereport(WARNING,
|
||||
(errcode(ERRCODE_WARNING_DEPRECATED_FEATURE),
|
||||
errmsg("deprecated input syntax for type double precision: \"\""),
|
||||
errmsg("deprecated input syntax for type double precision: \"\""),
|
||||
errdetail("This input will be rejected in "
|
||||
"a future release of PostgreSQL.")));
|
||||
PG_RETURN_FLOAT8(0.0);
|
||||
@@ -463,9 +465,9 @@ float8in(PG_FUNCTION_ARGS)
|
||||
if (endptr == num || errno != 0)
|
||||
{
|
||||
/*
|
||||
* C99 requires that strtod() accept NaN and [-]Infinity, but
|
||||
* not all platforms support that yet (and some accept them but
|
||||
* set ERANGE anyway...) Therefore, we check for these inputs
|
||||
* C99 requires that strtod() accept NaN and [-]Infinity, but not
|
||||
* all platforms support that yet (and some accept them but set
|
||||
* ERANGE anyway...) Therefore, we check for these inputs
|
||||
* ourselves.
|
||||
*/
|
||||
if (pg_strncasecmp(num, "NaN", 3) == 0)
|
||||
@@ -480,14 +482,14 @@ float8in(PG_FUNCTION_ARGS)
|
||||
}
|
||||
else if (pg_strncasecmp(num, "-Infinity", 9) == 0)
|
||||
{
|
||||
val = - get_float8_infinity();
|
||||
val = -get_float8_infinity();
|
||||
endptr = num + 9;
|
||||
}
|
||||
else if (errno == ERANGE)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||
errmsg("\"%s\" is out of range for type double precision",
|
||||
orig_num)));
|
||||
errmsg("\"%s\" is out of range for type double precision",
|
||||
orig_num)));
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
@@ -499,13 +501,13 @@ float8in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/*
|
||||
* Many versions of Solaris have a bug wherein strtod sets endptr
|
||||
* to point one byte beyond the end of the string when given
|
||||
* "inf" or "infinity".
|
||||
* to point one byte beyond the end of the string when given "inf"
|
||||
* or "infinity".
|
||||
*/
|
||||
if (endptr != num && endptr[-1] == '\0')
|
||||
endptr--;
|
||||
}
|
||||
#endif /* HAVE_BUGGY_SOLARIS_STRTOD */
|
||||
#endif /* HAVE_BUGGY_SOLARIS_STRTOD */
|
||||
|
||||
/* skip trailing whitespace */
|
||||
while (*endptr != '\0' && isspace((unsigned char) *endptr))
|
||||
@@ -515,8 +517,8 @@ float8in(PG_FUNCTION_ARGS)
|
||||
if (*endptr != '\0')
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type double precision: \"%s\"",
|
||||
orig_num)));
|
||||
errmsg("invalid input syntax for type double precision: \"%s\"",
|
||||
orig_num)));
|
||||
|
||||
if (!isinf(val))
|
||||
CheckFloat8Val(val);
|
||||
@@ -546,13 +548,14 @@ float8out(PG_FUNCTION_ARGS)
|
||||
strcpy(ascii, "-Infinity");
|
||||
break;
|
||||
default:
|
||||
{
|
||||
int ndig = DBL_DIG + extra_float_digits;
|
||||
if (ndig < 1)
|
||||
ndig = 1;
|
||||
{
|
||||
int ndig = DBL_DIG + extra_float_digits;
|
||||
|
||||
sprintf(ascii, "%.*g", ndig, num);
|
||||
}
|
||||
if (ndig < 1)
|
||||
ndig = 1;
|
||||
|
||||
sprintf(ascii, "%.*g", ndig, num);
|
||||
}
|
||||
}
|
||||
|
||||
PG_RETURN_CSTRING(ascii);
|
||||
@@ -1474,8 +1477,8 @@ dpow(PG_FUNCTION_ARGS)
|
||||
float8 result;
|
||||
|
||||
/*
|
||||
* The SQL spec requires that we emit a particular SQLSTATE error
|
||||
* code for certain error conditions.
|
||||
* The SQL spec requires that we emit a particular SQLSTATE error code
|
||||
* for certain error conditions.
|
||||
*/
|
||||
if ((arg1 == 0 && arg2 < 0) ||
|
||||
(arg1 < 0 && floor(arg2) != arg2))
|
||||
@@ -1543,8 +1546,8 @@ dlog1(PG_FUNCTION_ARGS)
|
||||
float8 result;
|
||||
|
||||
/*
|
||||
* Emit particular SQLSTATE error codes for ln(). This is required
|
||||
* by the SQL standard.
|
||||
* Emit particular SQLSTATE error codes for ln(). This is required by
|
||||
* the SQL standard.
|
||||
*/
|
||||
if (arg1 == 0.0)
|
||||
ereport(ERROR,
|
||||
@@ -1573,9 +1576,8 @@ dlog10(PG_FUNCTION_ARGS)
|
||||
|
||||
/*
|
||||
* Emit particular SQLSTATE error codes for log(). The SQL spec
|
||||
* doesn't define log(), but it does define ln(), so it makes
|
||||
* sense to emit the same error code for an analogous error
|
||||
* condition.
|
||||
* doesn't define log(), but it does define ln(), so it makes sense to
|
||||
* emit the same error code for an analogous error condition.
|
||||
*/
|
||||
if (arg1 == 0.0)
|
||||
ereport(ERROR,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
* formatting.c
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.76 2004/08/29 04:12:51 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.77 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1999-2004, PostgreSQL Global Development Group
|
||||
@@ -409,7 +409,7 @@ typedef struct
|
||||
*/
|
||||
typedef struct TmToChar
|
||||
{
|
||||
struct pg_tm tm; /* classic 'tm' struct */
|
||||
struct pg_tm tm; /* classic 'tm' struct */
|
||||
fsec_t fsec; /* fractional seconds */
|
||||
char *tzn; /* timezone */
|
||||
} TmToChar;
|
||||
@@ -896,7 +896,7 @@ static int dch_global(int arg, char *inout, int suf, int flag, FormatNode *node,
|
||||
static int dch_time(int arg, char *inout, int suf, int flag, FormatNode *node, void *data);
|
||||
static int dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data);
|
||||
static void do_to_timestamp(text *date_txt, text *fmt,
|
||||
struct pg_tm *tm, fsec_t *fsec);
|
||||
struct pg_tm * tm, fsec_t *fsec);
|
||||
static char *fill_str(char *str, int c, int max);
|
||||
static FormatNode *NUM_cache(int len, NUMDesc *Num, char *pars_str, bool *shouldFree);
|
||||
static char *int_to_roman(int number);
|
||||
@@ -1309,13 +1309,14 @@ DCH_processor(FormatNode *node, char *inout, int flag, void *data)
|
||||
|
||||
for (n = node, s = inout; n->type != NODE_TYPE_END; n++)
|
||||
{
|
||||
if (flag == FROM_CHAR && *s=='\0')
|
||||
if (flag == FROM_CHAR && *s == '\0')
|
||||
|
||||
/*
|
||||
* The input string is shorter than format picture,
|
||||
* so it's good time to break this loop...
|
||||
*
|
||||
* Note: this isn't relevant for TO_CHAR mode, beacuse
|
||||
* it use 'inout' allocated by format picture length.
|
||||
* The input string is shorter than format picture, so it's
|
||||
* good time to break this loop...
|
||||
*
|
||||
* Note: this isn't relevant for TO_CHAR mode, beacuse it use
|
||||
* 'inout' allocated by format picture length.
|
||||
*/
|
||||
break;
|
||||
|
||||
@@ -1353,7 +1354,7 @@ DCH_processor(FormatNode *node, char *inout, int flag, void *data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
++s; /* ! */
|
||||
}
|
||||
|
||||
@@ -1694,7 +1695,7 @@ static int
|
||||
dch_time(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
|
||||
{
|
||||
char *p_inout = inout;
|
||||
struct pg_tm *tm = NULL;
|
||||
struct pg_tm *tm = NULL;
|
||||
TmFromChar *tmfc = NULL;
|
||||
TmToChar *tmtc = NULL;
|
||||
|
||||
@@ -2056,7 +2057,7 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
|
||||
*p_inout;
|
||||
int i,
|
||||
len;
|
||||
struct pg_tm *tm = NULL;
|
||||
struct pg_tm *tm = NULL;
|
||||
TmFromChar *tmfc = NULL;
|
||||
TmToChar *tmtc = NULL;
|
||||
|
||||
@@ -2467,21 +2468,21 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
|
||||
{
|
||||
if (tm->tm_year <= 9999 && tm->tm_year >= -9998)
|
||||
sprintf(inout, "%0*d",
|
||||
S_FM(suf) ? 0 : 4,
|
||||
arg == DCH_YYYY ?
|
||||
YEAR_ABS(tm->tm_year) :
|
||||
YEAR_ABS(date2isoyear(
|
||||
tm->tm_year,
|
||||
tm->tm_mon,
|
||||
tm->tm_mday)));
|
||||
S_FM(suf) ? 0 : 4,
|
||||
arg == DCH_YYYY ?
|
||||
YEAR_ABS(tm->tm_year) :
|
||||
YEAR_ABS(date2isoyear(
|
||||
tm->tm_year,
|
||||
tm->tm_mon,
|
||||
tm->tm_mday)));
|
||||
else
|
||||
sprintf(inout, "%d",
|
||||
arg == DCH_YYYY ?
|
||||
YEAR_ABS(tm->tm_year) :
|
||||
YEAR_ABS(date2isoyear(
|
||||
tm->tm_year,
|
||||
tm->tm_mon,
|
||||
tm->tm_mday)));
|
||||
arg == DCH_YYYY ?
|
||||
YEAR_ABS(tm->tm_year) :
|
||||
YEAR_ABS(date2isoyear(
|
||||
tm->tm_year,
|
||||
tm->tm_mon,
|
||||
tm->tm_mday)));
|
||||
if (S_THth(suf))
|
||||
str_numth(p_inout, inout, S_TH_TYPE(suf));
|
||||
return strlen(p_inout) - 1;
|
||||
@@ -2505,10 +2506,10 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
|
||||
if (flag == TO_CHAR)
|
||||
{
|
||||
snprintf(buff, sizeof(buff), "%03d",
|
||||
arg == DCH_YYY ?
|
||||
YEAR_ABS(tm->tm_year) :
|
||||
YEAR_ABS(date2isoyear(tm->tm_year,
|
||||
tm->tm_mon, tm->tm_mday)));
|
||||
arg == DCH_YYY ?
|
||||
YEAR_ABS(tm->tm_year) :
|
||||
YEAR_ABS(date2isoyear(tm->tm_year,
|
||||
tm->tm_mon, tm->tm_mday)));
|
||||
i = strlen(buff);
|
||||
strcpy(inout, buff + (i - 3));
|
||||
if (S_THth(suf))
|
||||
@@ -2540,10 +2541,10 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
|
||||
if (flag == TO_CHAR)
|
||||
{
|
||||
snprintf(buff, sizeof(buff), "%02d",
|
||||
arg == DCH_YY ?
|
||||
YEAR_ABS(tm->tm_year) :
|
||||
YEAR_ABS(date2isoyear(tm->tm_year,
|
||||
tm->tm_mon, tm->tm_mday)));
|
||||
arg == DCH_YY ?
|
||||
YEAR_ABS(tm->tm_year) :
|
||||
YEAR_ABS(date2isoyear(tm->tm_year,
|
||||
tm->tm_mon, tm->tm_mday)));
|
||||
i = strlen(buff);
|
||||
strcpy(inout, buff + (i - 2));
|
||||
if (S_THth(suf))
|
||||
@@ -2575,10 +2576,10 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
|
||||
if (flag == TO_CHAR)
|
||||
{
|
||||
snprintf(buff, sizeof(buff), "%1d",
|
||||
arg == DCH_Y ?
|
||||
YEAR_ABS(tm->tm_year) :
|
||||
YEAR_ABS(date2isoyear(tm->tm_year,
|
||||
tm->tm_mon, tm->tm_mday)));
|
||||
arg == DCH_Y ?
|
||||
YEAR_ABS(tm->tm_year) :
|
||||
YEAR_ABS(date2isoyear(tm->tm_year,
|
||||
tm->tm_mon, tm->tm_mday)));
|
||||
i = strlen(buff);
|
||||
strcpy(inout, buff + (i - 1));
|
||||
if (S_THth(suf))
|
||||
@@ -2730,7 +2731,7 @@ DCH_cache_getnew(char *str)
|
||||
return ent;
|
||||
}
|
||||
|
||||
return NULL; /* never */
|
||||
return NULL; /* never */
|
||||
}
|
||||
|
||||
static DCHCacheEntry *
|
||||
@@ -2767,11 +2768,11 @@ static text *
|
||||
datetime_to_char_body(TmToChar *tmtc, text *fmt)
|
||||
{
|
||||
FormatNode *format;
|
||||
struct pg_tm *tm = NULL;
|
||||
struct pg_tm *tm = NULL;
|
||||
char *fmt_str,
|
||||
*result;
|
||||
bool incache;
|
||||
int fmt_len = VARSIZE(fmt) - VARHDRSZ;
|
||||
*result;
|
||||
bool incache;
|
||||
int fmt_len = VARSIZE(fmt) - VARHDRSZ;
|
||||
|
||||
tm = tmtcTm(tmtc);
|
||||
tm->tm_wday = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + 1) % 7;
|
||||
@@ -2791,7 +2792,7 @@ datetime_to_char_body(TmToChar *tmtc, text *fmt)
|
||||
|
||||
/*
|
||||
* Allocate new memory if format picture is bigger than static cache
|
||||
* and not use cache (call parser always)
|
||||
* and not use cache (call parser always)
|
||||
*/
|
||||
if (fmt_len > DCH_CACHE_SIZE)
|
||||
{
|
||||
@@ -2801,7 +2802,7 @@ datetime_to_char_body(TmToChar *tmtc, text *fmt)
|
||||
parse_format(format, fmt_str, DCH_keywords,
|
||||
DCH_suff, DCH_index, DCH_TYPE, NULL);
|
||||
|
||||
(format + fmt_len)->type = NODE_TYPE_END; /* Paranoia? */
|
||||
(format + fmt_len)->type = NODE_TYPE_END; /* Paranoia? */
|
||||
|
||||
}
|
||||
else
|
||||
@@ -2810,6 +2811,7 @@ datetime_to_char_body(TmToChar *tmtc, text *fmt)
|
||||
* Use cache buffers
|
||||
*/
|
||||
DCHCacheEntry *ent;
|
||||
|
||||
incache = TRUE;
|
||||
|
||||
if ((ent = DCH_cache_search(fmt_str)) == NULL)
|
||||
@@ -2824,7 +2826,7 @@ datetime_to_char_body(TmToChar *tmtc, text *fmt)
|
||||
parse_format(ent->format, fmt_str, DCH_keywords,
|
||||
DCH_suff, DCH_index, DCH_TYPE, NULL);
|
||||
|
||||
(ent->format + fmt_len)->type = NODE_TYPE_END; /* Paranoia? */
|
||||
(ent->format + fmt_len)->type = NODE_TYPE_END; /* Paranoia? */
|
||||
|
||||
#ifdef DEBUG_TO_FROM_CHAR
|
||||
/* dump_node(ent->format, fmt_len); */
|
||||
@@ -2847,8 +2849,8 @@ datetime_to_char_body(TmToChar *tmtc, text *fmt)
|
||||
*/
|
||||
if (result && *result)
|
||||
{
|
||||
int len = strlen(result);
|
||||
|
||||
int len = strlen(result);
|
||||
|
||||
if (len)
|
||||
{
|
||||
text *res = (text *) palloc(len + 1 + VARHDRSZ);
|
||||
@@ -2961,7 +2963,7 @@ to_timestamp(PG_FUNCTION_ARGS)
|
||||
text *fmt = PG_GETARG_TEXT_P(1);
|
||||
Timestamp result;
|
||||
int tz;
|
||||
struct pg_tm tm;
|
||||
struct pg_tm tm;
|
||||
fsec_t fsec;
|
||||
|
||||
do_to_timestamp(date_txt, fmt, &tm, &fsec);
|
||||
@@ -2987,7 +2989,7 @@ to_date(PG_FUNCTION_ARGS)
|
||||
text *date_txt = PG_GETARG_TEXT_P(0);
|
||||
text *fmt = PG_GETARG_TEXT_P(1);
|
||||
DateADT result;
|
||||
struct pg_tm tm;
|
||||
struct pg_tm tm;
|
||||
fsec_t fsec;
|
||||
|
||||
do_to_timestamp(date_txt, fmt, &tm, &fsec);
|
||||
@@ -3005,11 +3007,11 @@ to_date(PG_FUNCTION_ARGS)
|
||||
*/
|
||||
static void
|
||||
do_to_timestamp(text *date_txt, text *fmt,
|
||||
struct pg_tm *tm, fsec_t *fsec)
|
||||
struct pg_tm * tm, fsec_t *fsec)
|
||||
{
|
||||
FormatNode *format;
|
||||
TmFromChar tmfc;
|
||||
int fmt_len;
|
||||
int fmt_len;
|
||||
|
||||
ZERO_tm(tm);
|
||||
*fsec = 0;
|
||||
@@ -3020,11 +3022,11 @@ do_to_timestamp(text *date_txt, text *fmt,
|
||||
|
||||
if (fmt_len)
|
||||
{
|
||||
int date_len;
|
||||
char *fmt_str;
|
||||
char *date_str;
|
||||
bool incache;
|
||||
|
||||
int date_len;
|
||||
char *fmt_str;
|
||||
char *date_str;
|
||||
bool incache;
|
||||
|
||||
fmt_str = (char *) palloc(fmt_len + 1);
|
||||
memcpy(fmt_str, VARDATA(fmt), fmt_len);
|
||||
*(fmt_str + fmt_len) = '\0';
|
||||
@@ -3041,7 +3043,7 @@ do_to_timestamp(text *date_txt, text *fmt,
|
||||
parse_format(format, fmt_str, DCH_keywords,
|
||||
DCH_suff, DCH_index, DCH_TYPE, NULL);
|
||||
|
||||
(format + fmt_len)->type = NODE_TYPE_END; /* Paranoia? */
|
||||
(format + fmt_len)->type = NODE_TYPE_END; /* Paranoia? */
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3049,6 +3051,7 @@ do_to_timestamp(text *date_txt, text *fmt,
|
||||
* Use cache buffers
|
||||
*/
|
||||
DCHCacheEntry *ent;
|
||||
|
||||
incache = TRUE;
|
||||
|
||||
if ((ent = DCH_cache_search(fmt_str)) == NULL)
|
||||
@@ -3063,7 +3066,7 @@ do_to_timestamp(text *date_txt, text *fmt,
|
||||
parse_format(ent->format, fmt_str, DCH_keywords,
|
||||
DCH_suff, DCH_index, DCH_TYPE, NULL);
|
||||
|
||||
(ent->format + fmt_len)->type = NODE_TYPE_END; /* Paranoia? */
|
||||
(ent->format + fmt_len)->type = NODE_TYPE_END; /* Paranoia? */
|
||||
#ifdef DEBUG_TO_FROM_CHAR
|
||||
/* dump_node(ent->format, fmt_len); */
|
||||
/* dump_index(DCH_keywords, DCH_index); */
|
||||
@@ -3207,7 +3210,7 @@ do_to_timestamp(text *date_txt, text *fmt,
|
||||
if (!tm->tm_year)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
|
||||
errmsg("cannot calculate day of year without year information")));
|
||||
errmsg("cannot calculate day of year without year information")));
|
||||
|
||||
y = ysum[isleap(tm->tm_year)];
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/geo_ops.c,v 1.86 2004/08/29 04:12:51 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/geo_ops.c,v 1.87 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -387,7 +387,7 @@ box_in(PG_FUNCTION_ARGS)
|
||||
|| (*s != '\0'))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type box: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for type box: \"%s\"", str)));
|
||||
|
||||
/* reorder corners if necessary... */
|
||||
if (box->high.x < box->low.x)
|
||||
@@ -900,7 +900,7 @@ line_in(PG_FUNCTION_ARGS)
|
||||
|| (*s != '\0'))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type line: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for type line: \"%s\"", str)));
|
||||
|
||||
line = (LINE *) palloc(sizeof(LINE));
|
||||
line_construct_pts(line, &lseg.p[0], &lseg.p[1]);
|
||||
@@ -1315,14 +1315,16 @@ line_interpt_internal(LINE *l1, LINE *l2)
|
||||
Datum
|
||||
path_area(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PATH *path = PG_GETARG_PATH_P(0);
|
||||
double area = 0.0;
|
||||
int i,j;
|
||||
PATH *path = PG_GETARG_PATH_P(0);
|
||||
double area = 0.0;
|
||||
int i,
|
||||
j;
|
||||
|
||||
if (!path->closed)
|
||||
PG_RETURN_NULL();
|
||||
|
||||
for (i = 0; i < path->npts; i++) {
|
||||
for (i = 0; i < path->npts; i++)
|
||||
{
|
||||
j = (i + 1) % path->npts;
|
||||
area += path->p[i].x * path->p[j].y;
|
||||
area -= path->p[i].y * path->p[j].x;
|
||||
@@ -1347,7 +1349,7 @@ path_in(PG_FUNCTION_ARGS)
|
||||
if ((npts = pair_count(str, ',')) <= 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type path: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for type path: \"%s\"", str)));
|
||||
|
||||
s = str;
|
||||
while (isspace((unsigned char) *s))
|
||||
@@ -1370,7 +1372,7 @@ path_in(PG_FUNCTION_ARGS)
|
||||
&& (!((depth == 0) && (*s == '\0'))) && !((depth >= 1) && (*s == RDELIM)))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type path: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for type path: \"%s\"", str)));
|
||||
|
||||
path->closed = (!isopen);
|
||||
|
||||
@@ -1407,7 +1409,7 @@ path_recv(PG_FUNCTION_ARGS)
|
||||
if (npts < 0 || npts >= (int32) ((INT_MAX - offsetof(PATH, p[0])) / sizeof(Point)))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
||||
errmsg("invalid number of points in external \"path\" value")));
|
||||
errmsg("invalid number of points in external \"path\" value")));
|
||||
|
||||
size = offsetof(PATH, p[0]) +sizeof(path->p[0]) * npts;
|
||||
path = (PATH *) palloc(size);
|
||||
@@ -1748,7 +1750,7 @@ point_in(PG_FUNCTION_ARGS)
|
||||
if (!pair_decode(str, &x, &y, &s) || (*s != '\0'))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type point: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for type point: \"%s\"", str)));
|
||||
|
||||
point = (Point *) palloc(sizeof(Point));
|
||||
|
||||
@@ -1976,7 +1978,7 @@ lseg_in(PG_FUNCTION_ARGS)
|
||||
|| (*s != '\0'))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type lseg: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for type lseg: \"%s\"", str)));
|
||||
|
||||
#ifdef NOT_USED
|
||||
lseg->m = point_sl(&lseg->p[0], &lseg->p[1]);
|
||||
@@ -3384,7 +3386,7 @@ poly_in(PG_FUNCTION_ARGS)
|
||||
if ((npts = pair_count(str, ',')) <= 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type polygon: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for type polygon: \"%s\"", str)));
|
||||
|
||||
size = offsetof(POLYGON, p[0]) +sizeof(poly->p[0]) * npts;
|
||||
poly = (POLYGON *) palloc0(size); /* zero any holes */
|
||||
@@ -3396,7 +3398,7 @@ poly_in(PG_FUNCTION_ARGS)
|
||||
|| (*s != '\0'))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type polygon: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for type polygon: \"%s\"", str)));
|
||||
|
||||
make_bound_box(poly);
|
||||
|
||||
@@ -4242,7 +4244,7 @@ circle_in(PG_FUNCTION_ARGS)
|
||||
if (!pair_decode(s, &circle->center.x, &circle->center.y, &s))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type circle: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for type circle: \"%s\"", str)));
|
||||
|
||||
if (*s == DELIM)
|
||||
s++;
|
||||
@@ -4252,7 +4254,7 @@ circle_in(PG_FUNCTION_ARGS)
|
||||
if ((!single_decode(s, &circle->radius, &s)) || (circle->radius < 0))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type circle: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for type circle: \"%s\"", str)));
|
||||
|
||||
while (depth > 0)
|
||||
{
|
||||
@@ -4267,13 +4269,13 @@ circle_in(PG_FUNCTION_ARGS)
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type circle: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for type circle: \"%s\"", str)));
|
||||
}
|
||||
|
||||
if (*s != '\0')
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type circle: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for type circle: \"%s\"", str)));
|
||||
|
||||
PG_RETURN_CIRCLE_P(circle);
|
||||
}
|
||||
@@ -4824,7 +4826,7 @@ circle_poly(PG_FUNCTION_ARGS)
|
||||
if (FPzero(circle->radius))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("cannot convert circle with radius zero to polygon")));
|
||||
errmsg("cannot convert circle with radius zero to polygon")));
|
||||
|
||||
if (npts < 2)
|
||||
ereport(ERROR,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.61 2004/08/29 04:12:51 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.62 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -50,7 +50,7 @@ typedef struct
|
||||
int32 current;
|
||||
int32 finish;
|
||||
int32 step;
|
||||
} generate_series_fctx;
|
||||
} generate_series_fctx;
|
||||
|
||||
/*****************************************************************************
|
||||
* USER I/O ROUTINES *
|
||||
@@ -1042,17 +1042,17 @@ generate_series_int4(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
generate_series_step_int4(PG_FUNCTION_ARGS)
|
||||
{
|
||||
FuncCallContext *funcctx;
|
||||
generate_series_fctx *fctx;
|
||||
int32 result;
|
||||
MemoryContext oldcontext;
|
||||
FuncCallContext *funcctx;
|
||||
generate_series_fctx *fctx;
|
||||
int32 result;
|
||||
MemoryContext oldcontext;
|
||||
|
||||
/* stuff done only on the first call of the function */
|
||||
if (SRF_IS_FIRSTCALL())
|
||||
{
|
||||
int32 start = PG_GETARG_INT32(0);
|
||||
int32 finish = PG_GETARG_INT32(1);
|
||||
int32 step = 1;
|
||||
int32 start = PG_GETARG_INT32(0);
|
||||
int32 finish = PG_GETARG_INT32(1);
|
||||
int32 step = 1;
|
||||
|
||||
/* see if we were given an explicit step size */
|
||||
if (PG_NARGS() == 3)
|
||||
@@ -1075,8 +1075,8 @@ generate_series_step_int4(PG_FUNCTION_ARGS)
|
||||
fctx = (generate_series_fctx *) palloc(sizeof(generate_series_fctx));
|
||||
|
||||
/*
|
||||
* Use fctx to keep state from call to call.
|
||||
* Seed current with the original start value
|
||||
* Use fctx to keep state from call to call. Seed current with the
|
||||
* original start value
|
||||
*/
|
||||
fctx->current = start;
|
||||
fctx->finish = finish;
|
||||
@@ -1090,8 +1090,8 @@ generate_series_step_int4(PG_FUNCTION_ARGS)
|
||||
funcctx = SRF_PERCALL_SETUP();
|
||||
|
||||
/*
|
||||
* get the saved state and use current as the result for
|
||||
* this iteration
|
||||
* get the saved state and use current as the result for this
|
||||
* iteration
|
||||
*/
|
||||
fctx = funcctx->user_fctx;
|
||||
result = fctx->current;
|
||||
@@ -1109,4 +1109,3 @@ generate_series_step_int4(PG_FUNCTION_ARGS)
|
||||
/* do when there is no more left */
|
||||
SRF_RETURN_DONE(funcctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/int8.c,v 1.54 2004/08/29 04:12:51 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/int8.c,v 1.55 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -29,7 +29,7 @@ typedef struct
|
||||
int64 current;
|
||||
int64 finish;
|
||||
int64 step;
|
||||
} generate_series_fctx;
|
||||
} generate_series_fctx;
|
||||
|
||||
/***********************************************************************
|
||||
**
|
||||
@@ -93,7 +93,7 @@ scanint8(const char *str, bool errorOK, int64 *result)
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type bigint: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for type bigint: \"%s\"", str)));
|
||||
}
|
||||
|
||||
/* process digits */
|
||||
@@ -124,7 +124,7 @@ scanint8(const char *str, bool errorOK, int64 *result)
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type bigint: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for type bigint: \"%s\"", str)));
|
||||
}
|
||||
|
||||
*result = (sign < 0) ? -tmp : tmp;
|
||||
@@ -960,17 +960,17 @@ generate_series_int8(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
generate_series_step_int8(PG_FUNCTION_ARGS)
|
||||
{
|
||||
FuncCallContext *funcctx;
|
||||
generate_series_fctx *fctx;
|
||||
int64 result;
|
||||
MemoryContext oldcontext;
|
||||
FuncCallContext *funcctx;
|
||||
generate_series_fctx *fctx;
|
||||
int64 result;
|
||||
MemoryContext oldcontext;
|
||||
|
||||
/* stuff done only on the first call of the function */
|
||||
if (SRF_IS_FIRSTCALL())
|
||||
{
|
||||
int64 start = PG_GETARG_INT64(0);
|
||||
int64 finish = PG_GETARG_INT64(1);
|
||||
int64 step = 1;
|
||||
int64 start = PG_GETARG_INT64(0);
|
||||
int64 finish = PG_GETARG_INT64(1);
|
||||
int64 step = 1;
|
||||
|
||||
/* see if we were given an explicit step size */
|
||||
if (PG_NARGS() == 3)
|
||||
@@ -993,8 +993,8 @@ generate_series_step_int8(PG_FUNCTION_ARGS)
|
||||
fctx = (generate_series_fctx *) palloc(sizeof(generate_series_fctx));
|
||||
|
||||
/*
|
||||
* Use fctx to keep state from call to call.
|
||||
* Seed current with the original start value
|
||||
* Use fctx to keep state from call to call. Seed current with the
|
||||
* original start value
|
||||
*/
|
||||
fctx->current = start;
|
||||
fctx->finish = finish;
|
||||
@@ -1008,8 +1008,8 @@ generate_series_step_int8(PG_FUNCTION_ARGS)
|
||||
funcctx = SRF_PERCALL_SETUP();
|
||||
|
||||
/*
|
||||
* get the saved state and use current as the result for
|
||||
* this iteration
|
||||
* get the saved state and use current as the result for this
|
||||
* iteration
|
||||
*/
|
||||
fctx = funcctx->user_fctx;
|
||||
result = fctx->current;
|
||||
@@ -1027,4 +1027,3 @@ generate_series_step_int8(PG_FUNCTION_ARGS)
|
||||
/* do when there is no more left */
|
||||
SRF_RETURN_DONE(funcctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* PostgreSQL type definitions for MAC addresses.
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/mac.c,v 1.33 2003/11/29 19:51:58 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/mac.c,v 1.34 2004/08/29 05:06:49 momjian Exp $
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
@@ -62,14 +62,14 @@ macaddr_in(PG_FUNCTION_ARGS)
|
||||
if (count != 6)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type macaddr: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for type macaddr: \"%s\"", str)));
|
||||
|
||||
if ((a < 0) || (a > 255) || (b < 0) || (b > 255) ||
|
||||
(c < 0) || (c > 255) || (d < 0) || (d > 255) ||
|
||||
(e < 0) || (e > 255) || (f < 0) || (f > 255))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||
errmsg("invalid octet value in \"macaddr\" value: \"%s\"", str)));
|
||||
errmsg("invalid octet value in \"macaddr\" value: \"%s\"", str)));
|
||||
|
||||
result = (macaddr *) palloc(sizeof(macaddr));
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.37 2004/08/29 04:12:51 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.38 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -72,29 +72,30 @@ current_database(PG_FUNCTION_ARGS)
|
||||
* Functions to send signals to other backends.
|
||||
*/
|
||||
|
||||
static int pg_signal_backend(int pid, int sig)
|
||||
static int
|
||||
pg_signal_backend(int pid, int sig)
|
||||
{
|
||||
if (!superuser())
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
(errmsg("must be superuser to signal other server processes"))));
|
||||
|
||||
(errmsg("must be superuser to signal other server processes"))));
|
||||
|
||||
if (!IsBackendPid(pid))
|
||||
{
|
||||
/*
|
||||
* This is just a warning so a loop-through-resultset will not abort
|
||||
* if one backend terminated on it's own during the run
|
||||
* This is just a warning so a loop-through-resultset will not
|
||||
* abort if one backend terminated on it's own during the run
|
||||
*/
|
||||
ereport(WARNING,
|
||||
(errmsg("PID %d is not a PostgreSQL server process", pid)));
|
||||
(errmsg("PID %d is not a PostgreSQL server process", pid)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (kill(pid, sig))
|
||||
if (kill(pid, sig))
|
||||
{
|
||||
/* Again, just a warning to allow loops */
|
||||
ereport(WARNING,
|
||||
(errmsg("could not send signal to process %d: %m",pid)));
|
||||
(errmsg("could not send signal to process %d: %m", pid)));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -103,7 +104,7 @@ static int pg_signal_backend(int pid, int sig)
|
||||
Datum
|
||||
pg_cancel_backend(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_RETURN_INT32(pg_signal_backend(PG_GETARG_INT32(0),SIGINT));
|
||||
PG_RETURN_INT32(pg_signal_backend(PG_GETARG_INT32(0), SIGINT));
|
||||
}
|
||||
|
||||
#ifdef NOT_USED
|
||||
@@ -113,21 +114,21 @@ pg_cancel_backend(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
pg_terminate_backend(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_RETURN_INT32(pg_signal_backend(PG_GETARG_INT32(0),SIGTERM));
|
||||
PG_RETURN_INT32(pg_signal_backend(PG_GETARG_INT32(0), SIGTERM));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Function to find out which databases make use of a tablespace */
|
||||
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
char *location;
|
||||
DIR *dirdesc;
|
||||
char *location;
|
||||
DIR *dirdesc;
|
||||
} ts_db_fctx;
|
||||
|
||||
Datum pg_tablespace_databases(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
pg_tablespace_databases(PG_FUNCTION_ARGS)
|
||||
{
|
||||
FuncCallContext *funcctx;
|
||||
struct dirent *de;
|
||||
@@ -136,18 +137,18 @@ Datum pg_tablespace_databases(PG_FUNCTION_ARGS)
|
||||
if (SRF_IS_FIRSTCALL())
|
||||
{
|
||||
MemoryContext oldcontext;
|
||||
Oid tablespaceOid=PG_GETARG_OID(0);
|
||||
Oid tablespaceOid = PG_GETARG_OID(0);
|
||||
|
||||
funcctx=SRF_FIRSTCALL_INIT();
|
||||
funcctx = SRF_FIRSTCALL_INIT();
|
||||
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
||||
|
||||
fctx = palloc(sizeof(ts_db_fctx));
|
||||
|
||||
/*
|
||||
* size = path length + tablespace dirname length
|
||||
* + 2 dir sep chars + oid + terminator
|
||||
* size = path length + tablespace dirname length + 2 dir sep
|
||||
* chars + oid + terminator
|
||||
*/
|
||||
fctx->location = (char*) palloc(strlen(DataDir) + 11 + 10 + 1);
|
||||
fctx->location = (char *) palloc(strlen(DataDir) + 11 + 10 + 1);
|
||||
if (tablespaceOid == GLOBALTABLESPACE_OID)
|
||||
{
|
||||
fctx->dirdesc = NULL;
|
||||
@@ -160,8 +161,8 @@ Datum pg_tablespace_databases(PG_FUNCTION_ARGS)
|
||||
sprintf(fctx->location, "%s/base", DataDir);
|
||||
else
|
||||
sprintf(fctx->location, "%s/pg_tblspc/%u", DataDir,
|
||||
tablespaceOid);
|
||||
|
||||
tablespaceOid);
|
||||
|
||||
fctx->dirdesc = AllocateDir(fctx->location);
|
||||
|
||||
if (!fctx->dirdesc)
|
||||
@@ -173,25 +174,26 @@ Datum pg_tablespace_databases(PG_FUNCTION_ARGS)
|
||||
errmsg("could not open directory \"%s\": %m",
|
||||
fctx->location)));
|
||||
ereport(WARNING,
|
||||
(errmsg("%u is not a tablespace oid", tablespaceOid)));
|
||||
(errmsg("%u is not a tablespace oid", tablespaceOid)));
|
||||
}
|
||||
}
|
||||
funcctx->user_fctx = fctx;
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
}
|
||||
|
||||
funcctx=SRF_PERCALL_SETUP();
|
||||
fctx = (ts_db_fctx*) funcctx->user_fctx;
|
||||
funcctx = SRF_PERCALL_SETUP();
|
||||
fctx = (ts_db_fctx *) funcctx->user_fctx;
|
||||
|
||||
if (!fctx->dirdesc) /* not a tablespace */
|
||||
if (!fctx->dirdesc) /* not a tablespace */
|
||||
SRF_RETURN_DONE(funcctx);
|
||||
|
||||
while ((de = readdir(fctx->dirdesc)) != NULL)
|
||||
{
|
||||
char *subdir;
|
||||
DIR *dirdesc;
|
||||
char *subdir;
|
||||
DIR *dirdesc;
|
||||
|
||||
Oid datOid = atooid(de->d_name);
|
||||
|
||||
Oid datOid = atooid(de->d_name);
|
||||
/* this test skips . and .., but is awfully weak */
|
||||
if (!datOid)
|
||||
continue;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.124 2004/08/29 04:12:51 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.125 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -181,7 +181,7 @@ void
|
||||
abstime2tm(AbsoluteTime _time, int *tzp, struct pg_tm * tm, char **tzn)
|
||||
{
|
||||
pg_time_t time = (pg_time_t) _time;
|
||||
struct pg_tm *tx;
|
||||
struct pg_tm *tx;
|
||||
|
||||
/*
|
||||
* If HasCTZSet is true then we have a brute force time zone
|
||||
@@ -302,7 +302,7 @@ abstimein(PG_FUNCTION_ARGS)
|
||||
AbsoluteTime result;
|
||||
fsec_t fsec;
|
||||
int tz = 0;
|
||||
struct pg_tm date,
|
||||
struct pg_tm date,
|
||||
*tm = &date;
|
||||
int dterr;
|
||||
char *field[MAXDATEFIELDS];
|
||||
@@ -368,7 +368,7 @@ abstimeout(PG_FUNCTION_ARGS)
|
||||
char *result;
|
||||
int tz;
|
||||
double fsec = 0;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
char buf[MAXDATELEN + 1];
|
||||
char zone[MAXDATELEN + 1],
|
||||
@@ -445,9 +445,9 @@ static int
|
||||
abstime_cmp_internal(AbsoluteTime a, AbsoluteTime b)
|
||||
{
|
||||
/*
|
||||
* We consider all INVALIDs to be equal and larger than any non-INVALID.
|
||||
* This is somewhat arbitrary; the important thing is to have a
|
||||
* consistent sort order.
|
||||
* We consider all INVALIDs to be equal and larger than any
|
||||
* non-INVALID. This is somewhat arbitrary; the important thing is to
|
||||
* have a consistent sort order.
|
||||
*/
|
||||
if (a == INVALID_ABSTIME)
|
||||
{
|
||||
@@ -551,7 +551,7 @@ timestamp_abstime(PG_FUNCTION_ARGS)
|
||||
AbsoluteTime result;
|
||||
fsec_t fsec;
|
||||
int tz;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
|
||||
if (TIMESTAMP_IS_NOBEGIN(timestamp))
|
||||
@@ -582,7 +582,7 @@ abstime_timestamp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0);
|
||||
Timestamp result;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
int tz;
|
||||
char zone[MAXDATELEN + 1],
|
||||
@@ -627,7 +627,7 @@ timestamptz_abstime(PG_FUNCTION_ARGS)
|
||||
TimestampTz timestamp = PG_GETARG_TIMESTAMP(0);
|
||||
AbsoluteTime result;
|
||||
fsec_t fsec;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
|
||||
if (TIMESTAMP_IS_NOBEGIN(timestamp))
|
||||
@@ -655,7 +655,7 @@ abstime_timestamptz(PG_FUNCTION_ARGS)
|
||||
{
|
||||
AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0);
|
||||
TimestampTz result;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
int tz;
|
||||
char zone[MAXDATELEN + 1],
|
||||
@@ -703,7 +703,7 @@ reltimein(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *str = PG_GETARG_CSTRING(0);
|
||||
RelativeTime result;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
fsec_t fsec;
|
||||
int dtype;
|
||||
@@ -751,7 +751,7 @@ reltimeout(PG_FUNCTION_ARGS)
|
||||
{
|
||||
RelativeTime time = PG_GETARG_RELATIVETIME(0);
|
||||
char *result;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
char buf[MAXDATELEN + 1];
|
||||
|
||||
@@ -882,7 +882,7 @@ tintervalrecv(PG_FUNCTION_ARGS)
|
||||
interval->status == T_INTERVAL_VALID))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
||||
errmsg("invalid status in external \"tinterval\" value")));
|
||||
errmsg("invalid status in external \"tinterval\" value")));
|
||||
|
||||
interval->data[0] = pq_getmsgint(buf, sizeof(interval->data[0]));
|
||||
interval->data[1] = pq_getmsgint(buf, sizeof(interval->data[1]));
|
||||
@@ -1138,9 +1138,9 @@ static int
|
||||
reltime_cmp_internal(RelativeTime a, RelativeTime b)
|
||||
{
|
||||
/*
|
||||
* We consider all INVALIDs to be equal and larger than any non-INVALID.
|
||||
* This is somewhat arbitrary; the important thing is to have a
|
||||
* consistent sort order.
|
||||
* We consider all INVALIDs to be equal and larger than any
|
||||
* non-INVALID. This is somewhat arbitrary; the important thing is to
|
||||
* have a consistent sort order.
|
||||
*/
|
||||
if (a == INVALID_RELTIME)
|
||||
{
|
||||
@@ -1252,7 +1252,7 @@ tintervalsame(PG_FUNCTION_ARGS)
|
||||
* tinterval comparison routines
|
||||
*
|
||||
* Note: comparison is based on the lengths of the intervals, not on
|
||||
* endpoint value. This is pretty bogus, but since it's only a legacy
|
||||
* endpoint value. This is pretty bogus, but since it's only a legacy
|
||||
* datatype I'm not going to propose changing it.
|
||||
*/
|
||||
static int
|
||||
@@ -1264,9 +1264,9 @@ tinterval_cmp_internal(TimeInterval a, TimeInterval b)
|
||||
AbsoluteTime b_len;
|
||||
|
||||
/*
|
||||
* We consider all INVALIDs to be equal and larger than any non-INVALID.
|
||||
* This is somewhat arbitrary; the important thing is to have a
|
||||
* consistent sort order.
|
||||
* We consider all INVALIDs to be equal and larger than any
|
||||
* non-INVALID. This is somewhat arbitrary; the important thing is to
|
||||
* have a consistent sort order.
|
||||
*/
|
||||
a_invalid = ((a->status == T_INTERVAL_INVAL) ||
|
||||
(a->data[0] == INVALID_ABSTIME) ||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* PostgreSQL type definitions for the INET and CIDR types.
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/network.c,v 1.52 2004/06/13 21:57:25 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/network.c,v 1.53 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
* Jon Postel RIP 16 Oct 1998
|
||||
*/
|
||||
@@ -195,7 +195,7 @@ inet_recv(PG_FUNCTION_ARGS)
|
||||
ip_family(addr) != PGSQL_AF_INET6)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
||||
errmsg("invalid address family in external \"inet\" value")));
|
||||
errmsg("invalid address family in external \"inet\" value")));
|
||||
bits = pq_getmsgbyte(buf);
|
||||
if (bits < 0 || bits > ip_maxbits(addr))
|
||||
ereport(ERROR,
|
||||
@@ -995,29 +995,30 @@ network_scan_last(Datum in)
|
||||
Datum
|
||||
inet_client_addr(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Port *port = MyProcPort;
|
||||
char remote_host[NI_MAXHOST];
|
||||
int ret;
|
||||
Port *port = MyProcPort;
|
||||
char remote_host[NI_MAXHOST];
|
||||
int ret;
|
||||
|
||||
if (port == NULL)
|
||||
PG_RETURN_NULL();
|
||||
|
||||
switch (port->raddr.addr.ss_family) {
|
||||
case AF_INET:
|
||||
switch (port->raddr.addr.ss_family)
|
||||
{
|
||||
case AF_INET:
|
||||
#ifdef HAVE_IPV6
|
||||
case AF_INET6:
|
||||
case AF_INET6:
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
PG_RETURN_NULL();
|
||||
break;
|
||||
default:
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
remote_host[0] = '\0';
|
||||
|
||||
ret = getnameinfo_all(&port->raddr.addr, port->raddr.salen,
|
||||
remote_host, sizeof(remote_host),
|
||||
NULL, 0,
|
||||
NI_NUMERICHOST | NI_NUMERICSERV);
|
||||
remote_host, sizeof(remote_host),
|
||||
NULL, 0,
|
||||
NI_NUMERICHOST | NI_NUMERICSERV);
|
||||
if (ret)
|
||||
PG_RETURN_NULL();
|
||||
|
||||
@@ -1031,29 +1032,30 @@ inet_client_addr(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
inet_client_port(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Port *port = MyProcPort;
|
||||
char remote_port[NI_MAXSERV];
|
||||
int ret;
|
||||
Port *port = MyProcPort;
|
||||
char remote_port[NI_MAXSERV];
|
||||
int ret;
|
||||
|
||||
if (port == NULL)
|
||||
PG_RETURN_NULL();
|
||||
|
||||
switch (port->raddr.addr.ss_family) {
|
||||
case AF_INET:
|
||||
switch (port->raddr.addr.ss_family)
|
||||
{
|
||||
case AF_INET:
|
||||
#ifdef HAVE_IPV6
|
||||
case AF_INET6:
|
||||
case AF_INET6:
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
PG_RETURN_NULL();
|
||||
break;
|
||||
default:
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
remote_port[0] = '\0';
|
||||
|
||||
ret = getnameinfo_all(&port->raddr.addr, port->raddr.salen,
|
||||
NULL, 0,
|
||||
remote_port, sizeof(remote_port),
|
||||
NI_NUMERICHOST | NI_NUMERICSERV);
|
||||
NULL, 0,
|
||||
remote_port, sizeof(remote_port),
|
||||
NI_NUMERICHOST | NI_NUMERICSERV);
|
||||
if (ret)
|
||||
PG_RETURN_NULL();
|
||||
|
||||
@@ -1067,29 +1069,30 @@ inet_client_port(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
inet_server_addr(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Port *port = MyProcPort;
|
||||
char local_host[NI_MAXHOST];
|
||||
int ret;
|
||||
Port *port = MyProcPort;
|
||||
char local_host[NI_MAXHOST];
|
||||
int ret;
|
||||
|
||||
if (port == NULL)
|
||||
PG_RETURN_NULL();
|
||||
|
||||
switch (port->laddr.addr.ss_family) {
|
||||
case AF_INET:
|
||||
switch (port->laddr.addr.ss_family)
|
||||
{
|
||||
case AF_INET:
|
||||
#ifdef HAVE_IPV6
|
||||
case AF_INET6:
|
||||
case AF_INET6:
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
PG_RETURN_NULL();
|
||||
break;
|
||||
default:
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
local_host[0] = '\0';
|
||||
|
||||
ret = getnameinfo_all(&port->laddr.addr, port->laddr.salen,
|
||||
local_host, sizeof(local_host),
|
||||
NULL, 0,
|
||||
NI_NUMERICHOST | NI_NUMERICSERV);
|
||||
local_host, sizeof(local_host),
|
||||
NULL, 0,
|
||||
NI_NUMERICHOST | NI_NUMERICSERV);
|
||||
if (ret)
|
||||
PG_RETURN_NULL();
|
||||
|
||||
@@ -1103,29 +1106,30 @@ inet_server_addr(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
inet_server_port(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Port *port = MyProcPort;
|
||||
char local_port[NI_MAXSERV];
|
||||
int ret;
|
||||
Port *port = MyProcPort;
|
||||
char local_port[NI_MAXSERV];
|
||||
int ret;
|
||||
|
||||
if (port == NULL)
|
||||
PG_RETURN_NULL();
|
||||
|
||||
switch (port->laddr.addr.ss_family) {
|
||||
case AF_INET:
|
||||
switch (port->laddr.addr.ss_family)
|
||||
{
|
||||
case AF_INET:
|
||||
#ifdef HAVE_IPV6
|
||||
case AF_INET6:
|
||||
case AF_INET6:
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
PG_RETURN_NULL();
|
||||
break;
|
||||
default:
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
local_port[0] = '\0';
|
||||
|
||||
ret = getnameinfo_all(&port->laddr.addr, port->laddr.salen,
|
||||
NULL, 0,
|
||||
local_port, sizeof(local_port),
|
||||
NI_NUMERICHOST | NI_NUMERICSERV);
|
||||
NULL, 0,
|
||||
local_port, sizeof(local_port),
|
||||
NI_NUMERICHOST | NI_NUMERICSERV);
|
||||
if (ret)
|
||||
PG_RETURN_NULL();
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/not_in.c,v 1.40 2004/08/29 04:12:52 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/not_in.c,v 1.41 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -62,7 +62,7 @@ int4notin(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_NAME),
|
||||
errmsg("invalid name syntax"),
|
||||
errhint("Must provide \"relationname.columnname\".")));
|
||||
errhint("Must provide \"relationname.columnname\".")));
|
||||
attribute = strVal(llast(names));
|
||||
names = list_truncate(names, nnames - 1);
|
||||
relrv = makeRangeVarFromNameList(names);
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* Copyright (c) 1998-2004, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.77 2004/08/29 04:12:52 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.78 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -287,7 +287,7 @@ static void round_var(NumericVar *var, int rscale);
|
||||
static void trunc_var(NumericVar *var, int rscale);
|
||||
static void strip_var(NumericVar *var);
|
||||
static void compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
|
||||
NumericVar *count_var, NumericVar *result_var);
|
||||
NumericVar *count_var, NumericVar *result_var);
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@@ -415,7 +415,7 @@ numeric_recv(PG_FUNCTION_ARGS)
|
||||
if (d < 0 || d >= NBASE)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
||||
errmsg("invalid digit in external \"numeric\" value")));
|
||||
errmsg("invalid digit in external \"numeric\" value")));
|
||||
value.digits[i] = d;
|
||||
}
|
||||
|
||||
@@ -831,8 +831,8 @@ width_bucket_numeric(PG_FUNCTION_ARGS)
|
||||
|
||||
if (count <= 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
|
||||
errmsg("count must be greater than zero")));
|
||||
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
|
||||
errmsg("count must be greater than zero")));
|
||||
|
||||
init_var(&result_var);
|
||||
init_var(&count_var);
|
||||
@@ -844,10 +844,10 @@ width_bucket_numeric(PG_FUNCTION_ARGS)
|
||||
{
|
||||
case 0:
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
|
||||
errmsg("lower bound cannot equal upper bound")));
|
||||
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
|
||||
errmsg("lower bound cannot equal upper bound")));
|
||||
|
||||
/* bound1 < bound2 */
|
||||
/* bound1 < bound2 */
|
||||
case -1:
|
||||
if (cmp_numerics(operand, bound1) < 0)
|
||||
set_var_from_var(&const_zero, &result_var);
|
||||
@@ -858,7 +858,7 @@ width_bucket_numeric(PG_FUNCTION_ARGS)
|
||||
&count_var, &result_var);
|
||||
break;
|
||||
|
||||
/* bound1 > bound2 */
|
||||
/* bound1 > bound2 */
|
||||
case 1:
|
||||
if (cmp_numerics(operand, bound1) > 0)
|
||||
set_var_from_var(&const_zero, &result_var);
|
||||
@@ -889,9 +889,9 @@ static void
|
||||
compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
|
||||
NumericVar *count_var, NumericVar *result_var)
|
||||
{
|
||||
NumericVar bound1_var;
|
||||
NumericVar bound2_var;
|
||||
NumericVar operand_var;
|
||||
NumericVar bound1_var;
|
||||
NumericVar bound2_var;
|
||||
NumericVar operand_var;
|
||||
|
||||
init_var(&bound1_var);
|
||||
init_var(&bound2_var);
|
||||
@@ -924,7 +924,7 @@ compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
|
||||
free_var(&bound1_var);
|
||||
free_var(&bound2_var);
|
||||
free_var(&operand_var);
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
*
|
||||
@@ -1692,8 +1692,8 @@ numeric_power(PG_FUNCTION_ARGS)
|
||||
trunc_var(&arg2_trunc, 0);
|
||||
|
||||
/*
|
||||
* Return special SQLSTATE error codes for a few conditions
|
||||
* mandated by the standard.
|
||||
* Return special SQLSTATE error codes for a few conditions mandated
|
||||
* by the standard.
|
||||
*/
|
||||
if ((cmp_var(&arg1, &const_zero) == 0 &&
|
||||
cmp_var(&arg2, &const_zero) < 0) ||
|
||||
@@ -1776,8 +1776,8 @@ numeric_int4(PG_FUNCTION_ARGS)
|
||||
static int32
|
||||
numericvar_to_int4(NumericVar *var)
|
||||
{
|
||||
int32 result;
|
||||
int64 val;
|
||||
int32 result;
|
||||
int64 val;
|
||||
|
||||
if (!numericvar_to_int8(var, &val))
|
||||
ereport(ERROR,
|
||||
@@ -2717,7 +2717,7 @@ 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 type numeric: \"%s\"", str)));
|
||||
errmsg("invalid input syntax for type numeric: \"%s\"", str)));
|
||||
|
||||
decdigits = (unsigned char *) palloc(strlen(cp) + DEC_DIGITS * 2);
|
||||
|
||||
@@ -2740,8 +2740,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 type numeric: \"%s\"",
|
||||
str)));
|
||||
errmsg("invalid input syntax for type numeric: \"%s\"",
|
||||
str)));
|
||||
have_dp = TRUE;
|
||||
cp++;
|
||||
}
|
||||
@@ -2764,15 +2764,15 @@ set_var_from_str(const char *str, NumericVar *dest)
|
||||
if (endptr == cp)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type numeric: \"%s\"",
|
||||
str)));
|
||||
errmsg("invalid input syntax for type numeric: \"%s\"",
|
||||
str)));
|
||||
cp = endptr;
|
||||
if (exponent > NUMERIC_MAX_PRECISION ||
|
||||
exponent < -NUMERIC_MAX_PRECISION)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type numeric: \"%s\"",
|
||||
str)));
|
||||
errmsg("invalid input syntax for type numeric: \"%s\"",
|
||||
str)));
|
||||
dweight += (int) exponent;
|
||||
dscale -= (int) exponent;
|
||||
if (dscale < 0)
|
||||
@@ -2785,8 +2785,8 @@ set_var_from_str(const char *str, NumericVar *dest)
|
||||
if (!isspace((unsigned char) *cp))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type numeric: \"%s\"",
|
||||
str)));
|
||||
errmsg("invalid input syntax for type numeric: \"%s\"",
|
||||
str)));
|
||||
cp++;
|
||||
}
|
||||
|
||||
@@ -3295,8 +3295,8 @@ numeric_to_double_no_overflow(Numeric num)
|
||||
/* shouldn't happen ... */
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type double precision: \"%s\"",
|
||||
tmp)));
|
||||
errmsg("invalid input syntax for type double precision: \"%s\"",
|
||||
tmp)));
|
||||
}
|
||||
|
||||
pfree(tmp);
|
||||
@@ -3321,8 +3321,8 @@ numericvar_to_double_no_overflow(NumericVar *var)
|
||||
/* shouldn't happen ... */
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type double precision: \"%s\"",
|
||||
tmp)));
|
||||
errmsg("invalid input syntax for type double precision: \"%s\"",
|
||||
tmp)));
|
||||
}
|
||||
|
||||
pfree(tmp);
|
||||
@@ -4211,8 +4211,8 @@ sqrt_var(NumericVar *arg, NumericVar *result, int rscale)
|
||||
}
|
||||
|
||||
/*
|
||||
* SQL2003 defines sqrt() in terms of power, so we need to emit
|
||||
* the right SQLSTATE error code if the operand is negative.
|
||||
* SQL2003 defines sqrt() in terms of power, so we need to emit the
|
||||
* right SQLSTATE error code if the operand is negative.
|
||||
*/
|
||||
if (stat < 0)
|
||||
ereport(ERROR,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/numutils.c,v 1.64 2004/08/29 04:12:52 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/numutils.c,v 1.65 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -85,8 +85,8 @@ pg_atoi(char *s, int size, int c)
|
||||
s)));
|
||||
|
||||
/*
|
||||
* Skip any trailing whitespace; if anything but whitespace
|
||||
* remains before the terminating character, bail out
|
||||
* Skip any trailing whitespace; if anything but whitespace remains
|
||||
* before the terminating character, bail out
|
||||
*/
|
||||
while (*badp != c && isspace((unsigned char) *badp))
|
||||
badp++;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/oid.c,v 1.58 2004/08/29 04:12:52 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/oid.c,v 1.59 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -35,9 +35,9 @@ oidin_subr(const char *funcname, const char *s, char **endloc)
|
||||
|
||||
/*
|
||||
* In releases prior to 8.0, we accepted an empty string as valid
|
||||
* input (yielding an OID of 0). In 8.0, we accept empty strings,
|
||||
* but emit a warning noting that the feature is deprecated. In
|
||||
* 8.1+, the warning should be replaced by an error.
|
||||
* input (yielding an OID of 0). In 8.0, we accept empty strings, but
|
||||
* emit a warning noting that the feature is deprecated. In 8.1+, the
|
||||
* warning should be replaced by an error.
|
||||
*/
|
||||
if (*s == '\0')
|
||||
ereport(WARNING,
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/oracle_compat.c,v 1.54 2004/08/29 04:12:52 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/oracle_compat.c,v 1.55 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -35,7 +35,7 @@
|
||||
/*
|
||||
* If the system provides the needed functions for wide-character manipulation
|
||||
* (which are all standardized by C99), then we implement upper/lower/initcap
|
||||
* using wide-character functions. Otherwise we use the traditional <ctype.h>
|
||||
* using wide-character functions. Otherwise we use the traditional <ctype.h>
|
||||
* functions, which of course will not work as desired in multibyte character
|
||||
* sets. Note that in either case we are effectively assuming that the
|
||||
* database character encoding matches the encoding implied by LC_CTYPE.
|
||||
@@ -62,7 +62,7 @@ texttowcs(const text *txt)
|
||||
{
|
||||
int nbytes = VARSIZE(txt) - VARHDRSZ;
|
||||
char *workstr;
|
||||
wchar_t *result;
|
||||
wchar_t *result;
|
||||
size_t ncodes;
|
||||
|
||||
/* Overflow paranoia */
|
||||
@@ -86,12 +86,12 @@ texttowcs(const text *txt)
|
||||
if (ncodes == (size_t) -1)
|
||||
{
|
||||
/*
|
||||
* Invalid multibyte character encountered. We try to give a useful
|
||||
* error message by letting pg_verifymbstr check the string. But
|
||||
* it's possible that the string is OK to us, and not OK to mbstowcs
|
||||
* --- this suggests that the LC_CTYPE locale is different from the
|
||||
* database encoding. Give a generic error message if verifymbstr
|
||||
* can't find anything wrong.
|
||||
* Invalid multibyte character encountered. We try to give a
|
||||
* useful error message by letting pg_verifymbstr check the
|
||||
* string. But it's possible that the string is OK to us, and not
|
||||
* OK to mbstowcs --- this suggests that the LC_CTYPE locale is
|
||||
* different from the database encoding. Give a generic error
|
||||
* message if verifymbstr can't find anything wrong.
|
||||
*/
|
||||
pg_verifymbstr(workstr, nbytes, false);
|
||||
ereport(ERROR,
|
||||
@@ -144,8 +144,7 @@ wcstotext(const wchar_t *str, int ncodes)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* USE_WIDE_UPPER_LOWER */
|
||||
#endif /* USE_WIDE_UPPER_LOWER */
|
||||
|
||||
|
||||
/********************************************************************
|
||||
@@ -171,7 +170,7 @@ lower(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *string = PG_GETARG_TEXT_P(0);
|
||||
text *result;
|
||||
wchar_t *workspace;
|
||||
wchar_t *workspace;
|
||||
int i;
|
||||
|
||||
workspace = texttowcs(string);
|
||||
@@ -186,13 +185,16 @@ lower(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
else
|
||||
#endif /* USE_WIDE_UPPER_LOWER */
|
||||
#endif /* USE_WIDE_UPPER_LOWER */
|
||||
{
|
||||
text *string = PG_GETARG_TEXT_P_COPY(0);
|
||||
char *ptr;
|
||||
int m;
|
||||
|
||||
/* Since we copied the string, we can scribble directly on the value */
|
||||
/*
|
||||
* Since we copied the string, we can scribble directly on the
|
||||
* value
|
||||
*/
|
||||
ptr = VARDATA(string);
|
||||
m = VARSIZE(string) - VARHDRSZ;
|
||||
|
||||
@@ -230,7 +232,7 @@ upper(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *string = PG_GETARG_TEXT_P(0);
|
||||
text *result;
|
||||
wchar_t *workspace;
|
||||
wchar_t *workspace;
|
||||
int i;
|
||||
|
||||
workspace = texttowcs(string);
|
||||
@@ -245,13 +247,16 @@ upper(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
else
|
||||
#endif /* USE_WIDE_UPPER_LOWER */
|
||||
#endif /* USE_WIDE_UPPER_LOWER */
|
||||
{
|
||||
text *string = PG_GETARG_TEXT_P_COPY(0);
|
||||
char *ptr;
|
||||
int m;
|
||||
|
||||
/* Since we copied the string, we can scribble directly on the value */
|
||||
/*
|
||||
* Since we copied the string, we can scribble directly on the
|
||||
* value
|
||||
*/
|
||||
ptr = VARDATA(string);
|
||||
m = VARSIZE(string) - VARHDRSZ;
|
||||
|
||||
@@ -292,7 +297,7 @@ initcap(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *string = PG_GETARG_TEXT_P(0);
|
||||
text *result;
|
||||
wchar_t *workspace;
|
||||
wchar_t *workspace;
|
||||
int wasalnum = 0;
|
||||
int i;
|
||||
|
||||
@@ -314,14 +319,17 @@ initcap(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
else
|
||||
#endif /* USE_WIDE_UPPER_LOWER */
|
||||
#endif /* USE_WIDE_UPPER_LOWER */
|
||||
{
|
||||
text *string = PG_GETARG_TEXT_P_COPY(0);
|
||||
int wasalnum = 0;
|
||||
char *ptr;
|
||||
int m;
|
||||
|
||||
/* Since we copied the string, we can scribble directly on the value */
|
||||
/*
|
||||
* Since we copied the string, we can scribble directly on the
|
||||
* value
|
||||
*/
|
||||
ptr = VARDATA(string);
|
||||
m = VARSIZE(string) - VARHDRSZ;
|
||||
|
||||
@@ -1068,7 +1076,7 @@ ascii(PG_FUNCTION_ARGS)
|
||||
********************************************************************/
|
||||
|
||||
Datum
|
||||
chr(PG_FUNCTION_ARGS)
|
||||
chr (PG_FUNCTION_ARGS)
|
||||
{
|
||||
int32 cvalue = PG_GETARG_INT32(0);
|
||||
text *result;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*
|
||||
* Portions Copyright (c) 2002-2004, PostgreSQL Global Development Group
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/pg_locale.c,v 1.27 2004/08/29 04:12:52 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/pg_locale.c,v 1.28 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -133,9 +133,11 @@ locale_messages_assign(const char *value, bool doit, GucSource source)
|
||||
if (!setlocale(LC_MESSAGES, value))
|
||||
{
|
||||
#ifdef WIN32
|
||||
|
||||
/*
|
||||
* Win32 returns NULL when you set LC_MESSAGES to "". So don't
|
||||
* complain unless we're trying to set it to something else.
|
||||
* Win32 returns NULL when you set LC_MESSAGES to "". So
|
||||
* don't complain unless we're trying to set it to something
|
||||
* else.
|
||||
*/
|
||||
if (value[0])
|
||||
return NULL;
|
||||
@@ -146,7 +148,7 @@ locale_messages_assign(const char *value, bool doit, GucSource source)
|
||||
}
|
||||
else
|
||||
value = locale_xxx_assign(LC_MESSAGES, value, false, source);
|
||||
#endif /* LC_MESSAGES */
|
||||
#endif /* LC_MESSAGES */
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/regproc.c,v 1.90 2004/08/29 04:12:52 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/regproc.c,v 1.91 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -114,7 +114,7 @@ regprocin(PG_FUNCTION_ARGS)
|
||||
if (matches == 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_FUNCTION),
|
||||
errmsg("function \"%s\" does not exist", pro_name_or_oid)));
|
||||
errmsg("function \"%s\" does not exist", pro_name_or_oid)));
|
||||
|
||||
else if (matches > 1)
|
||||
ereport(ERROR,
|
||||
@@ -135,7 +135,7 @@ regprocin(PG_FUNCTION_ARGS)
|
||||
if (clist == NULL)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_FUNCTION),
|
||||
errmsg("function \"%s\" does not exist", pro_name_or_oid)));
|
||||
errmsg("function \"%s\" does not exist", pro_name_or_oid)));
|
||||
else if (clist->next != NULL)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_AMBIGUOUS_FUNCTION),
|
||||
@@ -287,7 +287,7 @@ regprocedurein(PG_FUNCTION_ARGS)
|
||||
if (clist == NULL)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_FUNCTION),
|
||||
errmsg("function \"%s\" does not exist", pro_name_or_oid)));
|
||||
errmsg("function \"%s\" does not exist", pro_name_or_oid)));
|
||||
|
||||
result = clist->oid;
|
||||
|
||||
@@ -464,7 +464,7 @@ regoperin(PG_FUNCTION_ARGS)
|
||||
if (matches == 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_FUNCTION),
|
||||
errmsg("operator does not exist: %s", opr_name_or_oid)));
|
||||
errmsg("operator does not exist: %s", opr_name_or_oid)));
|
||||
else if (matches > 1)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_AMBIGUOUS_FUNCTION),
|
||||
@@ -834,7 +834,7 @@ regclassin(PG_FUNCTION_ARGS)
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_TABLE),
|
||||
errmsg("relation \"%s\" does not exist", class_name_or_oid)));
|
||||
errmsg("relation \"%s\" does not exist", class_name_or_oid)));
|
||||
|
||||
/* We assume there can be only one match */
|
||||
|
||||
@@ -1000,7 +1000,7 @@ regtypein(PG_FUNCTION_ARGS)
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||
errmsg("type \"%s\" does not exist", typ_name_or_oid)));
|
||||
errmsg("type \"%s\" does not exist", typ_name_or_oid)));
|
||||
|
||||
/* We assume there can be only one match */
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*
|
||||
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.70 2004/08/29 04:12:52 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.71 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
* ----------
|
||||
*/
|
||||
@@ -381,8 +381,8 @@ RI_FKey_check(PG_FUNCTION_ARGS)
|
||||
if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
|
||||
{
|
||||
if (HeapTupleHeaderGetXmin(old_row->t_data) !=
|
||||
GetCurrentTransactionId() &&
|
||||
ri_KeysEqual(fk_rel, old_row, new_row, &qkey,
|
||||
GetCurrentTransactionId() &&
|
||||
ri_KeysEqual(fk_rel, old_row, new_row, &qkey,
|
||||
RI_KEYPAIR_FK_IDX))
|
||||
{
|
||||
heap_close(pk_rel, RowShareLock);
|
||||
@@ -761,7 +761,7 @@ RI_FKey_noaction_del(PG_FUNCTION_ARGS)
|
||||
ri_PerformCheck(&qkey, qplan,
|
||||
fk_rel, pk_rel,
|
||||
old_row, NULL,
|
||||
true, /* must detect new rows */
|
||||
true, /* must detect new rows */
|
||||
SPI_OK_SELECT,
|
||||
tgargs[RI_CONSTRAINT_NAME_ARGNO]);
|
||||
|
||||
@@ -952,7 +952,7 @@ RI_FKey_noaction_upd(PG_FUNCTION_ARGS)
|
||||
ri_PerformCheck(&qkey, qplan,
|
||||
fk_rel, pk_rel,
|
||||
old_row, NULL,
|
||||
true, /* must detect new rows */
|
||||
true, /* must detect new rows */
|
||||
SPI_OK_SELECT,
|
||||
tgargs[RI_CONSTRAINT_NAME_ARGNO]);
|
||||
|
||||
@@ -1113,7 +1113,7 @@ RI_FKey_cascade_del(PG_FUNCTION_ARGS)
|
||||
ri_PerformCheck(&qkey, qplan,
|
||||
fk_rel, pk_rel,
|
||||
old_row, NULL,
|
||||
true, /* must detect new rows */
|
||||
true, /* must detect new rows */
|
||||
SPI_OK_DELETE,
|
||||
tgargs[RI_CONSTRAINT_NAME_ARGNO]);
|
||||
|
||||
@@ -1297,7 +1297,7 @@ RI_FKey_cascade_upd(PG_FUNCTION_ARGS)
|
||||
ri_PerformCheck(&qkey, qplan,
|
||||
fk_rel, pk_rel,
|
||||
old_row, new_row,
|
||||
true, /* must detect new rows */
|
||||
true, /* must detect new rows */
|
||||
SPI_OK_UPDATE,
|
||||
tgargs[RI_CONSTRAINT_NAME_ARGNO]);
|
||||
|
||||
@@ -1466,7 +1466,7 @@ RI_FKey_restrict_del(PG_FUNCTION_ARGS)
|
||||
ri_PerformCheck(&qkey, qplan,
|
||||
fk_rel, pk_rel,
|
||||
old_row, NULL,
|
||||
true, /* must detect new rows */
|
||||
true, /* must detect new rows */
|
||||
SPI_OK_SELECT,
|
||||
tgargs[RI_CONSTRAINT_NAME_ARGNO]);
|
||||
|
||||
@@ -1647,7 +1647,7 @@ RI_FKey_restrict_upd(PG_FUNCTION_ARGS)
|
||||
ri_PerformCheck(&qkey, qplan,
|
||||
fk_rel, pk_rel,
|
||||
old_row, NULL,
|
||||
true, /* must detect new rows */
|
||||
true, /* must detect new rows */
|
||||
SPI_OK_SELECT,
|
||||
tgargs[RI_CONSTRAINT_NAME_ARGNO]);
|
||||
|
||||
@@ -1817,7 +1817,7 @@ RI_FKey_setnull_del(PG_FUNCTION_ARGS)
|
||||
ri_PerformCheck(&qkey, qplan,
|
||||
fk_rel, pk_rel,
|
||||
old_row, NULL,
|
||||
true, /* must detect new rows */
|
||||
true, /* must detect new rows */
|
||||
SPI_OK_UPDATE,
|
||||
tgargs[RI_CONSTRAINT_NAME_ARGNO]);
|
||||
|
||||
@@ -2035,7 +2035,7 @@ RI_FKey_setnull_upd(PG_FUNCTION_ARGS)
|
||||
ri_PerformCheck(&qkey, qplan,
|
||||
fk_rel, pk_rel,
|
||||
old_row, NULL,
|
||||
true, /* must detect new rows */
|
||||
true, /* must detect new rows */
|
||||
SPI_OK_UPDATE,
|
||||
tgargs[RI_CONSTRAINT_NAME_ARGNO]);
|
||||
|
||||
@@ -2205,7 +2205,7 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
|
||||
ri_PerformCheck(&qkey, qplan,
|
||||
fk_rel, pk_rel,
|
||||
old_row, NULL,
|
||||
true, /* must detect new rows */
|
||||
true, /* must detect new rows */
|
||||
SPI_OK_UPDATE,
|
||||
tgargs[RI_CONSTRAINT_NAME_ARGNO]);
|
||||
|
||||
@@ -2410,7 +2410,7 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
|
||||
ri_PerformCheck(&qkey, qplan,
|
||||
fk_rel, pk_rel,
|
||||
old_row, NULL,
|
||||
true, /* must detect new rows */
|
||||
true, /* must detect new rows */
|
||||
SPI_OK_UPDATE,
|
||||
tgargs[RI_CONSTRAINT_NAME_ARGNO]);
|
||||
|
||||
@@ -2479,8 +2479,8 @@ RI_FKey_keyequal_upd(TriggerData *trigdata)
|
||||
(tgnargs % 2) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
|
||||
errmsg("function \"%s\" called with wrong number of trigger arguments",
|
||||
"RI_FKey_keyequal_upd")));
|
||||
errmsg("function \"%s\" called with wrong number of trigger arguments",
|
||||
"RI_FKey_keyequal_upd")));
|
||||
|
||||
/*
|
||||
* Nothing to do if no column names to compare given
|
||||
@@ -2497,9 +2497,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 table \"%s\"",
|
||||
trigdata->tg_trigger->tgname,
|
||||
RelationGetRelationName(trigdata->tg_relation)),
|
||||
errmsg("no target table given for trigger \"%s\" on table \"%s\"",
|
||||
trigdata->tg_trigger->tgname,
|
||||
RelationGetRelationName(trigdata->tg_relation)),
|
||||
errhint("Remove this referential integrity trigger and its mates, then do ALTER TABLE ADD CONSTRAINT.")));
|
||||
|
||||
fk_rel = heap_open(trigdata->tg_trigger->tgconstrrelid, AccessShareLock);
|
||||
@@ -2565,46 +2565,46 @@ RI_Initial_Check(FkConstraint *fkconstraint, Relation rel, Relation pkrel)
|
||||
{
|
||||
const char *constrname = fkconstraint->constr_name;
|
||||
char querystr[MAX_QUOTED_REL_NAME_LEN * 2 + 250 +
|
||||
(MAX_QUOTED_NAME_LEN + 32) * ((RI_MAX_NUMKEYS * 4)+1)];
|
||||
(MAX_QUOTED_NAME_LEN + 32) * ((RI_MAX_NUMKEYS * 4) + 1)];
|
||||
char pkrelname[MAX_QUOTED_REL_NAME_LEN];
|
||||
char relname[MAX_QUOTED_REL_NAME_LEN];
|
||||
char attname[MAX_QUOTED_NAME_LEN];
|
||||
char fkattname[MAX_QUOTED_NAME_LEN];
|
||||
const char *sep;
|
||||
ListCell *l;
|
||||
ListCell *l2;
|
||||
ListCell *l;
|
||||
ListCell *l2;
|
||||
int old_work_mem;
|
||||
char workmembuf[32];
|
||||
int spi_result;
|
||||
void *qplan;
|
||||
void *qplan;
|
||||
|
||||
/*
|
||||
* Check to make sure current user has enough permissions to do the
|
||||
* test query. (If not, caller can fall back to the trigger method,
|
||||
* test query. (If not, caller can fall back to the trigger method,
|
||||
* which works because it changes user IDs on the fly.)
|
||||
*
|
||||
* XXX are there any other show-stopper conditions to check?
|
||||
*/
|
||||
if (pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), ACL_SELECT) != ACLCHECK_OK)
|
||||
return false;
|
||||
if (pg_class_aclcheck(RelationGetRelid(pkrel), GetUserId(), ACL_SELECT) != ACLCHECK_OK)
|
||||
if (pg_class_aclcheck(RelationGetRelid(pkrel), GetUserId(), ACL_SELECT) != ACLCHECK_OK)
|
||||
return false;
|
||||
|
||||
/*----------
|
||||
* The query string built is:
|
||||
* SELECT fk.keycols FROM ONLY relname fk
|
||||
* LEFT OUTER JOIN ONLY pkrelname pk
|
||||
* ON (pk.pkkeycol1=fk.keycol1 [AND ...])
|
||||
* WHERE pk.pkkeycol1 IS NULL AND
|
||||
* SELECT fk.keycols FROM ONLY relname fk
|
||||
* LEFT OUTER JOIN ONLY pkrelname pk
|
||||
* ON (pk.pkkeycol1=fk.keycol1 [AND ...])
|
||||
* WHERE pk.pkkeycol1 IS NULL AND
|
||||
* For MATCH unspecified:
|
||||
* (fk.keycol1 IS NOT NULL [AND ...])
|
||||
* (fk.keycol1 IS NOT NULL [AND ...])
|
||||
* For MATCH FULL:
|
||||
* (fk.keycol1 IS NOT NULL [OR ...])
|
||||
* (fk.keycol1 IS NOT NULL [OR ...])
|
||||
*----------
|
||||
*/
|
||||
|
||||
sprintf(querystr, "SELECT ");
|
||||
sep="";
|
||||
sep = "";
|
||||
foreach(l, fkconstraint->fk_attrs)
|
||||
{
|
||||
quoteOneName(attname, strVal(lfirst(l)));
|
||||
@@ -2619,7 +2619,7 @@ RI_Initial_Check(FkConstraint *fkconstraint, Relation rel, Relation pkrel)
|
||||
" FROM ONLY %s fk LEFT OUTER JOIN ONLY %s pk ON (",
|
||||
relname, pkrelname);
|
||||
|
||||
sep="";
|
||||
sep = "";
|
||||
forboth(l, fkconstraint->pk_attrs, l2, fkconstraint->fk_attrs)
|
||||
{
|
||||
quoteOneName(attname, strVal(lfirst(l)));
|
||||
@@ -2629,6 +2629,7 @@ RI_Initial_Check(FkConstraint *fkconstraint, Relation rel, Relation pkrel)
|
||||
sep, attname, fkattname);
|
||||
sep = " AND ";
|
||||
}
|
||||
|
||||
/*
|
||||
* It's sufficient to test any one pk attribute for null to detect a
|
||||
* join failure.
|
||||
@@ -2637,7 +2638,7 @@ RI_Initial_Check(FkConstraint *fkconstraint, Relation rel, Relation pkrel)
|
||||
snprintf(querystr + strlen(querystr), sizeof(querystr) - strlen(querystr),
|
||||
") WHERE pk.%s IS NULL AND (", attname);
|
||||
|
||||
sep="";
|
||||
sep = "";
|
||||
foreach(l, fkconstraint->fk_attrs)
|
||||
{
|
||||
quoteOneName(attname, strVal(lfirst(l)));
|
||||
@@ -2647,10 +2648,10 @@ RI_Initial_Check(FkConstraint *fkconstraint, Relation rel, Relation pkrel)
|
||||
switch (fkconstraint->fk_matchtype)
|
||||
{
|
||||
case FKCONSTR_MATCH_UNSPECIFIED:
|
||||
sep=" AND ";
|
||||
sep = " AND ";
|
||||
break;
|
||||
case FKCONSTR_MATCH_FULL:
|
||||
sep=" OR ";
|
||||
sep = " OR ";
|
||||
break;
|
||||
case FKCONSTR_MATCH_PARTIAL:
|
||||
ereport(ERROR,
|
||||
@@ -2667,12 +2668,13 @@ RI_Initial_Check(FkConstraint *fkconstraint, Relation rel, Relation pkrel)
|
||||
")");
|
||||
|
||||
/*
|
||||
* Temporarily increase work_mem so that the check query can be executed
|
||||
* more efficiently. It seems okay to do this because the query is simple
|
||||
* enough to not use a multiple of work_mem, and one typically would not
|
||||
* have many large foreign-key validations happening concurrently. So
|
||||
* this seems to meet the criteria for being considered a "maintenance"
|
||||
* operation, and accordingly we use maintenance_work_mem.
|
||||
* Temporarily increase work_mem so that the check query can be
|
||||
* executed more efficiently. It seems okay to do this because the
|
||||
* query is simple enough to not use a multiple of work_mem, and one
|
||||
* typically would not have many large foreign-key validations
|
||||
* happening concurrently. So this seems to meet the criteria for
|
||||
* being considered a "maintenance" operation, and accordingly we use
|
||||
* maintenance_work_mem.
|
||||
*
|
||||
* We do the equivalent of "SET LOCAL work_mem" so that transaction abort
|
||||
* will restore the old value if we lose control due to an error.
|
||||
@@ -2688,7 +2690,7 @@ RI_Initial_Check(FkConstraint *fkconstraint, Relation rel, Relation pkrel)
|
||||
|
||||
/*
|
||||
* Generate the plan. We don't need to cache it, and there are no
|
||||
* arguments to the plan.
|
||||
* arguments to the plan.
|
||||
*/
|
||||
qplan = SPI_prepare(querystr, 0, NULL);
|
||||
|
||||
@@ -2697,9 +2699,9 @@ RI_Initial_Check(FkConstraint *fkconstraint, Relation rel, Relation pkrel)
|
||||
|
||||
/*
|
||||
* Run the plan. For safety we force a current query snapshot to be
|
||||
* used. (In serializable mode, this arguably violates serializability,
|
||||
* but we really haven't got much choice.) We need at most one tuple
|
||||
* returned, so pass limit = 1.
|
||||
* used. (In serializable mode, this arguably violates
|
||||
* serializability, but we really haven't got much choice.) We need
|
||||
* at most one tuple returned, so pass limit = 1.
|
||||
*/
|
||||
spi_result = SPI_execp_current(qplan, NULL, NULL, true, 1);
|
||||
|
||||
@@ -2714,16 +2716,16 @@ RI_Initial_Check(FkConstraint *fkconstraint, Relation rel, Relation pkrel)
|
||||
TupleDesc tupdesc = SPI_tuptable->tupdesc;
|
||||
int nkeys = list_length(fkconstraint->fk_attrs);
|
||||
int i;
|
||||
RI_QueryKey qkey;
|
||||
RI_QueryKey qkey;
|
||||
|
||||
/*
|
||||
* If it's MATCH FULL, and there are any nulls in the FK keys,
|
||||
* complain about that rather than the lack of a match. MATCH FULL
|
||||
* disallows partially-null FK rows.
|
||||
* complain about that rather than the lack of a match. MATCH
|
||||
* FULL disallows partially-null FK rows.
|
||||
*/
|
||||
if (fkconstraint->fk_matchtype == FKCONSTR_MATCH_FULL)
|
||||
{
|
||||
bool isnull = false;
|
||||
bool isnull = false;
|
||||
|
||||
for (i = 1; i <= nkeys; i++)
|
||||
{
|
||||
@@ -2760,9 +2762,9 @@ RI_Initial_Check(FkConstraint *fkconstraint, Relation rel, Relation pkrel)
|
||||
elog(ERROR, "SPI_finish failed");
|
||||
|
||||
/*
|
||||
* Restore work_mem for the remainder of the current transaction.
|
||||
* This is another SET LOCAL, so it won't affect the session value,
|
||||
* nor any tentative value if there is one.
|
||||
* Restore work_mem for the remainder of the current transaction. This
|
||||
* is another SET LOCAL, so it won't affect the session value, nor any
|
||||
* tentative value if there is one.
|
||||
*/
|
||||
snprintf(workmembuf, sizeof(workmembuf), "%d", old_work_mem);
|
||||
(void) set_config_option("work_mem", workmembuf,
|
||||
@@ -2912,7 +2914,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("function \"%s\" was not called by trigger manager", funcname)));
|
||||
errmsg("function \"%s\" was not called by trigger manager", funcname)));
|
||||
|
||||
/*
|
||||
* Check proper event
|
||||
@@ -2921,7 +2923,7 @@ ri_CheckTrigger(FunctionCallInfo fcinfo, const char *funcname, int tgkind)
|
||||
!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
|
||||
errmsg("function \"%s\" must be fired AFTER ROW", funcname)));
|
||||
errmsg("function \"%s\" must be fired AFTER ROW", funcname)));
|
||||
|
||||
switch (tgkind)
|
||||
{
|
||||
@@ -2962,8 +2964,8 @@ ri_CheckTrigger(FunctionCallInfo fcinfo, const char *funcname, int tgkind)
|
||||
(tgnargs % 2) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
|
||||
errmsg("function \"%s\" called with wrong number of trigger arguments",
|
||||
funcname)));
|
||||
errmsg("function \"%s\" called with wrong number of trigger arguments",
|
||||
funcname)));
|
||||
|
||||
/*
|
||||
* Check that tgconstrrelid is known. We need to check here because
|
||||
@@ -2972,9 +2974,9 @@ ri_CheckTrigger(FunctionCallInfo fcinfo, const char *funcname, int tgkind)
|
||||
if (!OidIsValid(trigdata->tg_trigger->tgconstrrelid))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||
errmsg("no target table given for trigger \"%s\" on table \"%s\"",
|
||||
trigdata->tg_trigger->tgname,
|
||||
RelationGetRelationName(trigdata->tg_relation)),
|
||||
errmsg("no target table given for trigger \"%s\" on table \"%s\"",
|
||||
trigdata->tg_trigger->tgname,
|
||||
RelationGetRelationName(trigdata->tg_relation)),
|
||||
errhint("Remove this referential integrity trigger and its mates, then do ALTER TABLE ADD CONSTRAINT.")));
|
||||
}
|
||||
|
||||
@@ -3094,17 +3096,15 @@ ri_PerformCheck(RI_QueryKey *qkey, void *qplan,
|
||||
/*
|
||||
* In READ COMMITTED mode, we just need to make sure the regular query
|
||||
* snapshot is up-to-date, and we will see all rows that could be
|
||||
* interesting. In SERIALIZABLE mode, we can't update the regular query
|
||||
* snapshot. If the caller passes detectNewRows == false then it's okay
|
||||
* to do the query with the transaction snapshot; otherwise we tell the
|
||||
* executor to force a current snapshot (and error out if it finds any
|
||||
* rows under current snapshot that wouldn't be visible per the
|
||||
* transaction snapshot).
|
||||
* interesting. In SERIALIZABLE mode, we can't update the regular
|
||||
* query snapshot. If the caller passes detectNewRows == false then
|
||||
* it's okay to do the query with the transaction snapshot; otherwise
|
||||
* we tell the executor to force a current snapshot (and error out if
|
||||
* it finds any rows under current snapshot that wouldn't be visible
|
||||
* per the transaction snapshot).
|
||||
*/
|
||||
if (IsXactIsoLevelSerializable)
|
||||
{
|
||||
useCurrentSnapshot = detectNewRows;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetQuerySnapshot();
|
||||
@@ -3207,7 +3207,7 @@ ri_ReportViolation(RI_QueryKey *qkey, const char *constrname,
|
||||
errhint("This is most likely due to a rule having rewritten the query.")));
|
||||
|
||||
/*
|
||||
* Determine which relation to complain about. If tupdesc wasn't
|
||||
* Determine which relation to complain about. If tupdesc wasn't
|
||||
* passed by caller, assume the violator tuple came from there.
|
||||
*/
|
||||
onfk = (qkey->constr_queryno == RI_PLAN_CHECK_LOOKUPPK);
|
||||
@@ -3272,18 +3272,18 @@ ri_ReportViolation(RI_QueryKey *qkey, const char *constrname,
|
||||
(errcode(ERRCODE_FOREIGN_KEY_VIOLATION),
|
||||
errmsg("insert or update on table \"%s\" violates foreign key constraint \"%s\"",
|
||||
RelationGetRelationName(fk_rel), constrname),
|
||||
errdetail("Key (%s)=(%s) is not present in table \"%s\".",
|
||||
key_names, key_values,
|
||||
RelationGetRelationName(pk_rel))));
|
||||
errdetail("Key (%s)=(%s) is not present in table \"%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 table \"%s\".",
|
||||
key_names, key_values,
|
||||
RelationGetRelationName(fk_rel))));
|
||||
errdetail("Key (%s)=(%s) is still referenced from table \"%s\".",
|
||||
key_names, key_values,
|
||||
RelationGetRelationName(fk_rel))));
|
||||
}
|
||||
|
||||
/* ----------
|
||||
@@ -3626,8 +3626,8 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
|
||||
if (!OidIsValid(typentry->eq_opr_finfo.fn_oid))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_FUNCTION),
|
||||
errmsg("could not identify an equality operator for type %s",
|
||||
format_type_be(typeid))));
|
||||
errmsg("could not identify an equality operator for type %s",
|
||||
format_type_be(typeid))));
|
||||
|
||||
/*
|
||||
* Call the type specific '=' function
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/rowtypes.c,v 1.5 2004/08/29 04:12:52 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/rowtypes.c,v 1.6 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -67,15 +67,15 @@ record_in(PG_FUNCTION_ARGS)
|
||||
StringInfoData buf;
|
||||
|
||||
/*
|
||||
* Use the passed type unless it's RECORD; we can't support input
|
||||
* of anonymous types, mainly because there's no good way to figure
|
||||
* out which anonymous type is wanted. Note that for RECORD,
|
||||
* what we'll probably actually get is RECORD's typelem, ie, zero.
|
||||
* Use the passed type unless it's RECORD; we can't support input of
|
||||
* anonymous types, mainly because there's no good way to figure out
|
||||
* which anonymous type is wanted. Note that for RECORD, what we'll
|
||||
* probably actually get is RECORD's typelem, ie, zero.
|
||||
*/
|
||||
if (tupType == InvalidOid || tupType == RECORDOID)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("input of anonymous composite types is not implemented")));
|
||||
errmsg("input of anonymous composite types is not implemented")));
|
||||
tupTypmod = -1; /* for all non-anonymous types */
|
||||
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
|
||||
ncolumns = tupdesc->natts;
|
||||
@@ -112,8 +112,8 @@ record_in(PG_FUNCTION_ARGS)
|
||||
nulls = (char *) palloc(ncolumns * sizeof(char));
|
||||
|
||||
/*
|
||||
* Scan the string. We use "buf" to accumulate the de-quoted data
|
||||
* for each column, which is then fed to the appropriate input converter.
|
||||
* Scan the string. We use "buf" to accumulate the de-quoted data for
|
||||
* each column, which is then fed to the appropriate input converter.
|
||||
*/
|
||||
ptr = string;
|
||||
/* Allow leading whitespace */
|
||||
@@ -145,10 +145,11 @@ record_in(PG_FUNCTION_ARGS)
|
||||
/* Skip comma that separates prior field from this one */
|
||||
if (*ptr == ',')
|
||||
ptr++;
|
||||
else /* *ptr must be ')' */
|
||||
else
|
||||
/* *ptr must be ')' */
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed record literal: \"%s\"", string),
|
||||
errmsg("malformed record literal: \"%s\"", string),
|
||||
errdetail("Too few columns.")));
|
||||
}
|
||||
|
||||
@@ -161,13 +162,13 @@ record_in(PG_FUNCTION_ARGS)
|
||||
else
|
||||
{
|
||||
/* Extract string for this column */
|
||||
bool inquote = false;
|
||||
bool inquote = false;
|
||||
|
||||
buf.len = 0;
|
||||
buf.data[0] = '\0';
|
||||
while (inquote || !(*ptr == ',' || *ptr == ')'))
|
||||
{
|
||||
char ch = *ptr++;
|
||||
char ch = *ptr++;
|
||||
|
||||
if (ch == '\0')
|
||||
ereport(ERROR,
|
||||
@@ -179,10 +180,10 @@ record_in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (*ptr == '\0')
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed record literal: \"%s\"",
|
||||
string),
|
||||
errdetail("Unexpected end of input.")));
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("malformed record literal: \"%s\"",
|
||||
string),
|
||||
errdetail("Unexpected end of input.")));
|
||||
appendStringInfoChar(&buf, *ptr++);
|
||||
}
|
||||
else if (ch == '\"')
|
||||
@@ -216,8 +217,8 @@ record_in(PG_FUNCTION_ARGS)
|
||||
|
||||
values[i] = FunctionCall3(&column_info->proc,
|
||||
CStringGetDatum(buf.data),
|
||||
ObjectIdGetDatum(column_info->typioparam),
|
||||
Int32GetDatum(tupdesc->attrs[i]->atttypmod));
|
||||
ObjectIdGetDatum(column_info->typioparam),
|
||||
Int32GetDatum(tupdesc->attrs[i]->atttypmod));
|
||||
nulls[i] = ' ';
|
||||
}
|
||||
|
||||
@@ -333,9 +334,9 @@ record_out(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ColumnIOData *column_info = &my_extra->columns[i];
|
||||
Oid column_type = tupdesc->attrs[i]->atttypid;
|
||||
char *value;
|
||||
char *tmp;
|
||||
bool nq;
|
||||
char *value;
|
||||
char *tmp;
|
||||
bool nq;
|
||||
|
||||
/* Ignore dropped columns in datatype */
|
||||
if (tupdesc->attrs[i]->attisdropped)
|
||||
@@ -356,7 +357,7 @@ record_out(PG_FUNCTION_ARGS)
|
||||
*/
|
||||
if (column_info->column_type != column_type)
|
||||
{
|
||||
bool typIsVarlena;
|
||||
bool typIsVarlena;
|
||||
|
||||
getTypeOutputInfo(column_type,
|
||||
&column_info->typiofunc,
|
||||
@@ -369,8 +370,8 @@ record_out(PG_FUNCTION_ARGS)
|
||||
|
||||
value = DatumGetCString(FunctionCall3(&column_info->proc,
|
||||
values[i],
|
||||
ObjectIdGetDatum(column_info->typioparam),
|
||||
Int32GetDatum(tupdesc->attrs[i]->atttypmod)));
|
||||
ObjectIdGetDatum(column_info->typioparam),
|
||||
Int32GetDatum(tupdesc->attrs[i]->atttypmod)));
|
||||
|
||||
/* Detect whether we need double quotes for this value */
|
||||
nq = (value[0] == '\0'); /* force quotes for empty string */
|
||||
@@ -430,15 +431,15 @@ record_recv(PG_FUNCTION_ARGS)
|
||||
char *nulls;
|
||||
|
||||
/*
|
||||
* Use the passed type unless it's RECORD; we can't support input
|
||||
* of anonymous types, mainly because there's no good way to figure
|
||||
* out which anonymous type is wanted. Note that for RECORD,
|
||||
* what we'll probably actually get is RECORD's typelem, ie, zero.
|
||||
* Use the passed type unless it's RECORD; we can't support input of
|
||||
* anonymous types, mainly because there's no good way to figure out
|
||||
* which anonymous type is wanted. Note that for RECORD, what we'll
|
||||
* probably actually get is RECORD's typelem, ie, zero.
|
||||
*/
|
||||
if (tupType == InvalidOid || tupType == RECORDOID)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("input of anonymous composite types is not implemented")));
|
||||
errmsg("input of anonymous composite types is not implemented")));
|
||||
tupTypmod = -1; /* for all non-anonymous types */
|
||||
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
|
||||
ncolumns = tupdesc->natts;
|
||||
@@ -531,9 +532,10 @@ record_recv(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
StringInfoData item_buf;
|
||||
char csave;
|
||||
@@ -561,7 +563,7 @@ record_recv(PG_FUNCTION_ARGS)
|
||||
|
||||
values[i] = FunctionCall2(&column_info->proc,
|
||||
PointerGetDatum(&item_buf),
|
||||
ObjectIdGetDatum(column_info->typioparam));
|
||||
ObjectIdGetDatum(column_info->typioparam));
|
||||
|
||||
nulls[i] = ' ';
|
||||
|
||||
@@ -569,8 +571,8 @@ record_recv(PG_FUNCTION_ARGS)
|
||||
if (item_buf.cursor != itemlen)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
||||
errmsg("improper binary format in record column %d",
|
||||
i + 1)));
|
||||
errmsg("improper binary format in record column %d",
|
||||
i + 1)));
|
||||
|
||||
buf->data[buf->cursor] = csave;
|
||||
}
|
||||
@@ -694,7 +696,7 @@ record_send(PG_FUNCTION_ARGS)
|
||||
*/
|
||||
if (column_info->column_type != column_type)
|
||||
{
|
||||
bool typIsVarlena;
|
||||
bool typIsVarlena;
|
||||
|
||||
getTypeBinaryOutputInfo(column_type,
|
||||
&column_info->typiofunc,
|
||||
@@ -707,7 +709,7 @@ record_send(PG_FUNCTION_ARGS)
|
||||
|
||||
outputbytes = DatumGetByteaP(FunctionCall2(&column_info->proc,
|
||||
values[i],
|
||||
ObjectIdGetDatum(column_info->typioparam)));
|
||||
ObjectIdGetDatum(column_info->typioparam)));
|
||||
|
||||
/* We assume the result will not have been toasted */
|
||||
pq_sendint(&buf, VARSIZE(outputbytes) - VARHDRSZ, 4);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* back to source text
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.178 2004/08/19 20:57:41 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.179 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||
*
|
||||
@@ -157,12 +157,12 @@ static void decompile_column_index_array(Datum column_index_array, Oid relId,
|
||||
StringInfo buf);
|
||||
static char *pg_get_ruledef_worker(Oid ruleoid, int prettyFlags);
|
||||
static char *pg_get_indexdef_worker(Oid indexrelid, int colno,
|
||||
int prettyFlags);
|
||||
int prettyFlags);
|
||||
static char *pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
|
||||
int prettyFlags);
|
||||
int prettyFlags);
|
||||
static char *pg_get_expr_worker(text *expr, Oid relid, char *relname,
|
||||
int prettyFlags);
|
||||
static Oid get_constraint_index(Oid constraintRelOid, Oid constraintOid);
|
||||
int prettyFlags);
|
||||
static Oid get_constraint_index(Oid constraintRelOid, Oid constraintOid);
|
||||
static void make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc,
|
||||
int prettyFlags);
|
||||
static void make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc,
|
||||
@@ -204,7 +204,7 @@ static void get_from_clause(Query *query, deparse_context *context);
|
||||
static void get_from_clause_item(Node *jtnode, Query *query,
|
||||
deparse_context *context);
|
||||
static void get_from_clause_alias(Alias *alias, int varno,
|
||||
Query *query, deparse_context *context);
|
||||
Query *query, deparse_context *context);
|
||||
static void get_from_clause_coldeflist(List *coldeflist,
|
||||
deparse_context *context);
|
||||
static void get_opclass_name(Oid opclass, Oid actual_datatype,
|
||||
@@ -774,13 +774,13 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, int prettyFlags)
|
||||
appendStringInfoChar(&buf, ')');
|
||||
|
||||
/*
|
||||
* If the index is in a different tablespace from its parent,
|
||||
* tell about that
|
||||
* If the index is in a different tablespace from its parent, tell
|
||||
* about that
|
||||
*/
|
||||
if (OidIsValid(idxrelrec->reltablespace) &&
|
||||
idxrelrec->reltablespace != get_rel_tablespace(indrelid))
|
||||
{
|
||||
char *spcname = get_tablespace_name(idxrelrec->reltablespace);
|
||||
char *spcname = get_tablespace_name(idxrelrec->reltablespace);
|
||||
|
||||
if (spcname) /* just paranoia... */
|
||||
{
|
||||
@@ -837,7 +837,7 @@ pg_get_constraintdef(PG_FUNCTION_ARGS)
|
||||
Oid constraintId = PG_GETARG_OID(0);
|
||||
|
||||
PG_RETURN_TEXT_P(string_to_text(pg_get_constraintdef_worker(constraintId,
|
||||
false, 0)));
|
||||
false, 0)));
|
||||
}
|
||||
|
||||
Datum
|
||||
@@ -849,7 +849,7 @@ pg_get_constraintdef_ext(PG_FUNCTION_ARGS)
|
||||
|
||||
prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : 0;
|
||||
PG_RETURN_TEXT_P(string_to_text(pg_get_constraintdef_worker(constraintId,
|
||||
false, prettyFlags)));
|
||||
false, prettyFlags)));
|
||||
}
|
||||
|
||||
/* Internal version that returns a palloc'd C string */
|
||||
@@ -1042,17 +1042,17 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
|
||||
constraintId);
|
||||
if (OidIsValid(indexOid))
|
||||
{
|
||||
Oid reltablespace;
|
||||
Oid indtablespace;
|
||||
Oid reltablespace;
|
||||
Oid indtablespace;
|
||||
|
||||
reltablespace = get_rel_tablespace(conForm->conrelid);
|
||||
indtablespace = get_rel_tablespace(indexOid);
|
||||
if (OidIsValid(indtablespace) &&
|
||||
indtablespace != reltablespace)
|
||||
{
|
||||
char *spcname = get_tablespace_name(indtablespace);
|
||||
char *spcname = get_tablespace_name(indtablespace);
|
||||
|
||||
if (spcname) /* just paranoia... */
|
||||
if (spcname) /* just paranoia... */
|
||||
{
|
||||
appendStringInfo(&buf, " USING INDEX TABLESPACE %s",
|
||||
quote_identifier(spcname));
|
||||
@@ -1098,13 +1098,15 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
|
||||
prettyFlags, 0);
|
||||
|
||||
/*
|
||||
* Now emit the constraint definition. There are cases where
|
||||
* the constraint expression will be fully parenthesized and
|
||||
* we don't need the outer parens ... but there are other
|
||||
* cases where we do need 'em. Be conservative for now.
|
||||
* Now emit the constraint definition. There are cases
|
||||
* where the constraint expression will be fully
|
||||
* parenthesized and we don't need the outer parens ...
|
||||
* but there are other cases where we do need 'em. Be
|
||||
* conservative for now.
|
||||
*
|
||||
* Note that simply checking for leading '(' and trailing ')'
|
||||
* would NOT be good enough, consider "(x > 0) AND (y > 0)".
|
||||
* would NOT be good enough, consider "(x > 0) AND (y >
|
||||
* 0)".
|
||||
*/
|
||||
appendStringInfo(&buf, "CHECK (%s)", consrc);
|
||||
|
||||
@@ -1270,13 +1272,13 @@ pg_get_userbyid(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
pg_get_serial_sequence(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *tablename = PG_GETARG_TEXT_P(0);
|
||||
text *columnname = PG_GETARG_TEXT_P(1);
|
||||
text *tablename = PG_GETARG_TEXT_P(0);
|
||||
text *columnname = PG_GETARG_TEXT_P(1);
|
||||
RangeVar *tablerv;
|
||||
Oid tableOid;
|
||||
char *column;
|
||||
char *column;
|
||||
AttrNumber attnum;
|
||||
Oid sequenceId = InvalidOid;
|
||||
Oid sequenceId = InvalidOid;
|
||||
Relation depRel;
|
||||
ScanKeyData key[3];
|
||||
SysScanDesc scan;
|
||||
@@ -1284,12 +1286,12 @@ pg_get_serial_sequence(PG_FUNCTION_ARGS)
|
||||
|
||||
/* Get the OID of the table */
|
||||
tablerv = makeRangeVarFromNameList(textToQualifiedNameList(tablename,
|
||||
"pg_get_serial_sequence"));
|
||||
"pg_get_serial_sequence"));
|
||||
tableOid = RangeVarGetRelid(tablerv, false);
|
||||
|
||||
/* Get the number of the column */
|
||||
column = DatumGetCString(DirectFunctionCall1(textout,
|
||||
PointerGetDatum(columnname)));
|
||||
PointerGetDatum(columnname)));
|
||||
|
||||
attnum = get_attnum(tableOid, column);
|
||||
if (attnum == InvalidAttrNumber)
|
||||
@@ -1319,7 +1321,7 @@ pg_get_serial_sequence(PG_FUNCTION_ARGS)
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(scan)))
|
||||
{
|
||||
Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
|
||||
Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
|
||||
|
||||
/*
|
||||
* We assume any internal dependency of a relation on a column
|
||||
@@ -1340,9 +1342,9 @@ pg_get_serial_sequence(PG_FUNCTION_ARGS)
|
||||
if (OidIsValid(sequenceId))
|
||||
{
|
||||
HeapTuple classtup;
|
||||
Form_pg_class classtuple;
|
||||
char *nspname;
|
||||
char *result;
|
||||
Form_pg_class classtuple;
|
||||
char *nspname;
|
||||
char *result;
|
||||
|
||||
/* Get the sequence's pg_class entry */
|
||||
classtup = SearchSysCache(RELOID,
|
||||
@@ -1410,11 +1412,11 @@ get_constraint_index(Oid constraintRelOid, Oid constraintOid)
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(scan)))
|
||||
{
|
||||
Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
|
||||
Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
|
||||
|
||||
/*
|
||||
* We assume any internal dependency of a relation on the constraint
|
||||
* must be what we are looking for.
|
||||
* We assume any internal dependency of a relation on the
|
||||
* constraint must be what we are looking for.
|
||||
*/
|
||||
if (deprec->classid == RelOid_pg_class &&
|
||||
deprec->objsubid == 0 &&
|
||||
@@ -1984,9 +1986,9 @@ get_select_query_def(Query *query, deparse_context *context,
|
||||
sortcoltype = exprType(sortexpr);
|
||||
/* See whether operator is default < or > for datatype */
|
||||
typentry = lookup_type_cache(sortcoltype,
|
||||
TYPECACHE_LT_OPR | TYPECACHE_GT_OPR);
|
||||
TYPECACHE_LT_OPR | TYPECACHE_GT_OPR);
|
||||
if (srt->sortop == typentry->lt_opr)
|
||||
/* ASC is default, so emit nothing */ ;
|
||||
/* ASC is default, so emit nothing */ ;
|
||||
else if (srt->sortop == typentry->gt_opr)
|
||||
appendStringInfo(buf, " DESC");
|
||||
else
|
||||
@@ -2181,10 +2183,10 @@ get_setop_query(Node *setOp, Query *query, deparse_context *context,
|
||||
SetOperationStmt *op = (SetOperationStmt *) setOp;
|
||||
|
||||
/*
|
||||
* We force parens whenever nesting two SetOperationStmts.
|
||||
* There are some cases in which parens are needed around a leaf
|
||||
* query too, but those are more easily handled at the next level
|
||||
* down (see code above).
|
||||
* We force parens whenever nesting two SetOperationStmts. There
|
||||
* are some cases in which parens are needed around a leaf query
|
||||
* too, but those are more easily handled at the next level down
|
||||
* (see code above).
|
||||
*/
|
||||
need_paren = !IsA(op->larg, RangeTblRef);
|
||||
|
||||
@@ -2330,12 +2332,13 @@ get_insert_query_def(Query *query, deparse_context *context)
|
||||
* tle->resname, since resname will fail to track RENAME.
|
||||
*/
|
||||
appendStringInfoString(buf,
|
||||
quote_identifier(get_relid_attribute_name(rte->relid,
|
||||
tle->resdom->resno)));
|
||||
quote_identifier(get_relid_attribute_name(rte->relid,
|
||||
tle->resdom->resno)));
|
||||
|
||||
/*
|
||||
* Print any indirection needed (subfields or subscripts), and strip
|
||||
* off the top-level nodes representing the indirection assignments.
|
||||
* Print any indirection needed (subfields or subscripts), and
|
||||
* strip off the top-level nodes representing the indirection
|
||||
* assignments.
|
||||
*/
|
||||
strippedexprs = lappend(strippedexprs,
|
||||
processIndirection((Node *) tle->expr,
|
||||
@@ -2351,7 +2354,7 @@ get_insert_query_def(Query *query, deparse_context *context)
|
||||
sep = "";
|
||||
foreach(l, strippedexprs)
|
||||
{
|
||||
Node *expr = lfirst(l);
|
||||
Node *expr = lfirst(l);
|
||||
|
||||
appendStringInfo(buf, sep);
|
||||
sep = ", ";
|
||||
@@ -2372,10 +2375,10 @@ get_insert_query_def(Query *query, deparse_context *context)
|
||||
static void
|
||||
get_update_query_def(Query *query, deparse_context *context)
|
||||
{
|
||||
StringInfo buf = context->buf;
|
||||
char *sep;
|
||||
RangeTblEntry *rte;
|
||||
ListCell *l;
|
||||
StringInfo buf = context->buf;
|
||||
char *sep;
|
||||
RangeTblEntry *rte;
|
||||
ListCell *l;
|
||||
|
||||
/*
|
||||
* Start the query with UPDATE relname SET
|
||||
@@ -2396,7 +2399,7 @@ get_update_query_def(Query *query, deparse_context *context)
|
||||
foreach(l, query->targetList)
|
||||
{
|
||||
TargetEntry *tle = (TargetEntry *) lfirst(l);
|
||||
Node *expr;
|
||||
Node *expr;
|
||||
|
||||
if (tle->resdom->resjunk)
|
||||
continue; /* ignore junk entries */
|
||||
@@ -2409,12 +2412,13 @@ get_update_query_def(Query *query, deparse_context *context)
|
||||
* tle->resname, since resname will fail to track RENAME.
|
||||
*/
|
||||
appendStringInfoString(buf,
|
||||
quote_identifier(get_relid_attribute_name(rte->relid,
|
||||
tle->resdom->resno)));
|
||||
quote_identifier(get_relid_attribute_name(rte->relid,
|
||||
tle->resdom->resno)));
|
||||
|
||||
/*
|
||||
* Print any indirection needed (subfields or subscripts), and strip
|
||||
* off the top-level nodes representing the indirection assignments.
|
||||
* Print any indirection needed (subfields or subscripts), and
|
||||
* strip off the top-level nodes representing the indirection
|
||||
* assignments.
|
||||
*/
|
||||
expr = processIndirection((Node *) tle->expr, context);
|
||||
|
||||
@@ -2583,13 +2587,13 @@ get_names_for_var(Var *var, deparse_context *context,
|
||||
static RangeTblEntry *
|
||||
find_rte_by_refname(const char *refname, deparse_context *context)
|
||||
{
|
||||
RangeTblEntry *result = NULL;
|
||||
ListCell *nslist;
|
||||
RangeTblEntry *result = NULL;
|
||||
ListCell *nslist;
|
||||
|
||||
foreach(nslist, context->namespaces)
|
||||
{
|
||||
deparse_namespace *dpns = (deparse_namespace *) lfirst(nslist);
|
||||
ListCell *rtlist;
|
||||
ListCell *rtlist;
|
||||
|
||||
foreach(rtlist, dpns->rtable)
|
||||
{
|
||||
@@ -2777,10 +2781,10 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
|
||||
case T_BoolExpr: /* lower precedence */
|
||||
case T_ArrayRef: /* other separators */
|
||||
case T_ArrayExpr: /* other separators */
|
||||
case T_RowExpr: /* other separators */
|
||||
case T_RowExpr: /* other separators */
|
||||
case T_CoalesceExpr: /* own parentheses */
|
||||
case T_NullIfExpr: /* other separators */
|
||||
case T_Aggref: /* own parentheses */
|
||||
case T_Aggref: /* own parentheses */
|
||||
case T_CaseExpr: /* other separators */
|
||||
return true;
|
||||
default:
|
||||
@@ -2824,10 +2828,10 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
|
||||
}
|
||||
case T_ArrayRef: /* other separators */
|
||||
case T_ArrayExpr: /* other separators */
|
||||
case T_RowExpr: /* other separators */
|
||||
case T_RowExpr: /* other separators */
|
||||
case T_CoalesceExpr: /* own parentheses */
|
||||
case T_NullIfExpr: /* other separators */
|
||||
case T_Aggref: /* own parentheses */
|
||||
case T_Aggref: /* own parentheses */
|
||||
case T_CaseExpr: /* other separators */
|
||||
return true;
|
||||
default:
|
||||
@@ -3008,8 +3012,8 @@ get_rule_expr(Node *node, deparse_context *context,
|
||||
bool need_parens;
|
||||
|
||||
/*
|
||||
* Parenthesize the argument unless it's a simple Var or
|
||||
* a FieldSelect. (In particular, if it's another ArrayRef,
|
||||
* Parenthesize the argument unless it's a simple Var or a
|
||||
* FieldSelect. (In particular, if it's another ArrayRef,
|
||||
* we *must* parenthesize to avoid confusion.)
|
||||
*/
|
||||
need_parens = !IsA(aref->refexpr, Var) &&
|
||||
@@ -3020,6 +3024,7 @@ get_rule_expr(Node *node, deparse_context *context,
|
||||
if (need_parens)
|
||||
appendStringInfoChar(buf, ')');
|
||||
printSubscripts(aref, context);
|
||||
|
||||
/*
|
||||
* Array assignment nodes should have been handled in
|
||||
* processIndirection().
|
||||
@@ -3166,11 +3171,13 @@ get_rule_expr(Node *node, deparse_context *context,
|
||||
format_type_be(argType));
|
||||
fieldname = get_relid_attribute_name(typrelid,
|
||||
fselect->fieldnum);
|
||||
|
||||
/*
|
||||
* Parenthesize the argument unless it's an ArrayRef or
|
||||
* another FieldSelect. Note in particular that it would be
|
||||
* WRONG to not parenthesize a Var argument; simplicity is not
|
||||
* the issue here, having the right number of names is.
|
||||
* another FieldSelect. Note in particular that it would
|
||||
* be WRONG to not parenthesize a Var argument; simplicity
|
||||
* is not the issue here, having the right number of names
|
||||
* is.
|
||||
*/
|
||||
need_parens = !IsA(fselect->arg, ArrayRef) &&
|
||||
!IsA(fselect->arg, FieldSelect);
|
||||
@@ -3184,6 +3191,7 @@ get_rule_expr(Node *node, deparse_context *context,
|
||||
break;
|
||||
|
||||
case T_FieldStore:
|
||||
|
||||
/*
|
||||
* We shouldn't see FieldStore here; it should have been
|
||||
* stripped off by processIndirection().
|
||||
@@ -3239,7 +3247,7 @@ get_rule_expr(Node *node, deparse_context *context,
|
||||
if (caseexpr->arg)
|
||||
{
|
||||
/* Show only the RHS of "CaseTestExpr = RHS" */
|
||||
Node *rhs;
|
||||
Node *rhs;
|
||||
|
||||
Assert(IsA(when->expr, OpExpr));
|
||||
rhs = (Node *) lsecond(((OpExpr *) when->expr)->args);
|
||||
@@ -3284,16 +3292,16 @@ get_rule_expr(Node *node, deparse_context *context,
|
||||
|
||||
case T_RowExpr:
|
||||
{
|
||||
RowExpr *rowexpr = (RowExpr *) node;
|
||||
RowExpr *rowexpr = (RowExpr *) node;
|
||||
TupleDesc tupdesc = NULL;
|
||||
ListCell *arg;
|
||||
int i;
|
||||
char *sep;
|
||||
|
||||
/*
|
||||
* If it's a named type and not RECORD, we may have to skip
|
||||
* dropped columns and/or claim there are NULLs for added
|
||||
* columns.
|
||||
* If it's a named type and not RECORD, we may have to
|
||||
* skip dropped columns and/or claim there are NULLs for
|
||||
* added columns.
|
||||
*/
|
||||
if (rowexpr->row_typeid != RECORDOID)
|
||||
{
|
||||
@@ -3302,8 +3310,8 @@ get_rule_expr(Node *node, deparse_context *context,
|
||||
}
|
||||
|
||||
/*
|
||||
* SQL99 allows "ROW" to be omitted when there is more than
|
||||
* one column, but for simplicity we always print it.
|
||||
* SQL99 allows "ROW" to be omitted when there is more
|
||||
* than one column, but for simplicity we always print it.
|
||||
*/
|
||||
appendStringInfo(buf, "ROW(");
|
||||
sep = "";
|
||||
@@ -3337,7 +3345,7 @@ get_rule_expr(Node *node, deparse_context *context,
|
||||
appendStringInfo(buf, ")");
|
||||
if (rowexpr->row_format == COERCE_EXPLICIT_CAST)
|
||||
appendStringInfo(buf, "::%s",
|
||||
format_type_with_typemod(rowexpr->row_typeid, -1));
|
||||
format_type_with_typemod(rowexpr->row_typeid, -1));
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -3674,7 +3682,7 @@ get_const_expr(Const *constval, deparse_context *context)
|
||||
|
||||
extval = DatumGetCString(OidFunctionCall3(typoutput,
|
||||
constval->constvalue,
|
||||
ObjectIdGetDatum(typioparam),
|
||||
ObjectIdGetDatum(typioparam),
|
||||
Int32GetDatum(-1)));
|
||||
|
||||
switch (constval->consttype)
|
||||
@@ -4096,7 +4104,7 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
|
||||
if (col != list_head(j->using))
|
||||
appendStringInfo(buf, ", ");
|
||||
appendStringInfoString(buf,
|
||||
quote_identifier(strVal(lfirst(col))));
|
||||
quote_identifier(strVal(lfirst(col))));
|
||||
}
|
||||
appendStringInfoChar(buf, ')');
|
||||
}
|
||||
@@ -4137,7 +4145,7 @@ get_from_clause_alias(Alias *alias, int varno,
|
||||
{
|
||||
StringInfo buf = context->buf;
|
||||
ListCell *col;
|
||||
AttrNumber attnum;
|
||||
AttrNumber attnum;
|
||||
bool first = true;
|
||||
|
||||
if (alias == NULL || alias->colnames == NIL)
|
||||
@@ -4230,7 +4238,10 @@ get_opclass_name(Oid opclass, Oid actual_datatype,
|
||||
elog(ERROR, "cache lookup failed for opclass %u", opclass);
|
||||
opcrec = (Form_pg_opclass) GETSTRUCT(ht_opc);
|
||||
|
||||
/* Special case for ARRAY_OPS: pretend it is default for any array type */
|
||||
/*
|
||||
* Special case for ARRAY_OPS: pretend it is default for any array
|
||||
* type
|
||||
*/
|
||||
if (OidIsValid(actual_datatype))
|
||||
{
|
||||
if (opcrec->opcintype == ANYARRAYOID &&
|
||||
@@ -4240,7 +4251,7 @@ get_opclass_name(Oid opclass, Oid actual_datatype,
|
||||
|
||||
/* Must force use of opclass name if not in search path */
|
||||
isvisible = OpclassIsVisible(opclass);
|
||||
|
||||
|
||||
if (actual_datatype != opcrec->opcintype || !opcrec->opcdefault ||
|
||||
!isvisible)
|
||||
{
|
||||
@@ -4287,16 +4298,18 @@ processIndirection(Node *node, deparse_context *context)
|
||||
if (!OidIsValid(typrelid))
|
||||
elog(ERROR, "argument type %s of FieldStore is not a tuple type",
|
||||
format_type_be(fstore->resulttype));
|
||||
|
||||
/*
|
||||
* Get the field name. Note we assume here that there's only
|
||||
* Get the field name. Note we assume here that there's only
|
||||
* one field being assigned to. This is okay in stored rules
|
||||
* but could be wrong in executable target lists. Presently no
|
||||
* problem since explain.c doesn't print plan targetlists, but
|
||||
* someday may have to think of something ...
|
||||
* but could be wrong in executable target lists. Presently
|
||||
* no problem since explain.c doesn't print plan targetlists,
|
||||
* but someday may have to think of something ...
|
||||
*/
|
||||
fieldname = get_relid_attribute_name(typrelid,
|
||||
linitial_int(fstore->fieldnums));
|
||||
linitial_int(fstore->fieldnums));
|
||||
appendStringInfo(buf, ".%s", quote_identifier(fieldname));
|
||||
|
||||
/*
|
||||
* We ignore arg since it should be an uninteresting reference
|
||||
* to the target column or subcolumn.
|
||||
@@ -4310,9 +4323,10 @@ processIndirection(Node *node, deparse_context *context)
|
||||
if (aref->refassgnexpr == NULL)
|
||||
break;
|
||||
printSubscripts(aref, context);
|
||||
|
||||
/*
|
||||
* We ignore refexpr since it should be an uninteresting reference
|
||||
* to the target column or subcolumn.
|
||||
* We ignore refexpr since it should be an uninteresting
|
||||
* reference to the target column or subcolumn.
|
||||
*/
|
||||
node = (Node *) aref->refassgnexpr;
|
||||
}
|
||||
@@ -4330,7 +4344,7 @@ printSubscripts(ArrayRef *aref, deparse_context *context)
|
||||
ListCell *lowlist_item;
|
||||
ListCell *uplist_item;
|
||||
|
||||
lowlist_item = list_head(aref->reflowerindexpr); /* could be NULL */
|
||||
lowlist_item = list_head(aref->reflowerindexpr); /* could be NULL */
|
||||
foreach(uplist_item, aref->refupperindexpr)
|
||||
{
|
||||
appendStringInfoChar(buf, '[');
|
||||
@@ -4612,8 +4626,8 @@ generate_operator_name(Oid operid, Oid arg1, Oid arg2)
|
||||
static void
|
||||
print_operator_name(StringInfo buf, List *opname)
|
||||
{
|
||||
ListCell *op = list_head(opname);
|
||||
int nnames = list_length(opname);
|
||||
ListCell *op = list_head(opname);
|
||||
int nnames = list_length(opname);
|
||||
|
||||
if (nnames == 1)
|
||||
appendStringInfoString(buf, strVal(lfirst(op)));
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.163 2004/08/29 04:12:52 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.164 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -192,16 +192,16 @@ static double convert_one_bytea_to_scalar(unsigned char *value, int valuelen,
|
||||
static unsigned char *convert_string_datum(Datum value, Oid typid);
|
||||
static double convert_timevalue_to_scalar(Datum value, Oid typid);
|
||||
static bool get_restriction_variable(Query *root, List *args, int varRelid,
|
||||
VariableStatData *vardata, Node **other,
|
||||
bool *varonleft);
|
||||
VariableStatData *vardata, Node **other,
|
||||
bool *varonleft);
|
||||
static void get_join_variables(Query *root, List *args,
|
||||
VariableStatData *vardata1,
|
||||
VariableStatData *vardata2);
|
||||
VariableStatData *vardata1,
|
||||
VariableStatData *vardata2);
|
||||
static void examine_variable(Query *root, Node *node, int varRelid,
|
||||
VariableStatData *vardata);
|
||||
VariableStatData *vardata);
|
||||
static double get_variable_numdistinct(VariableStatData *vardata);
|
||||
static bool get_variable_maximum(Query *root, VariableStatData *vardata,
|
||||
Oid sortop, Datum *max);
|
||||
Oid sortop, Datum *max);
|
||||
static Selectivity prefix_selectivity(Query *root, VariableStatData *vardata,
|
||||
Oid opclass, Const *prefix);
|
||||
static Selectivity pattern_selectivity(Const *patt, Pattern_Type ptype);
|
||||
@@ -704,8 +704,8 @@ scalarltsel(PG_FUNCTION_ARGS)
|
||||
double selec;
|
||||
|
||||
/*
|
||||
* If expression is not variable op something or something op variable,
|
||||
* then punt and return a default estimate.
|
||||
* If expression is not variable op something or something op
|
||||
* variable, then punt and return a default estimate.
|
||||
*/
|
||||
if (!get_restriction_variable(root, args, varRelid,
|
||||
&vardata, &other, &varonleft))
|
||||
@@ -780,8 +780,8 @@ scalargtsel(PG_FUNCTION_ARGS)
|
||||
double selec;
|
||||
|
||||
/*
|
||||
* If expression is not variable op something or something op variable,
|
||||
* then punt and return a default estimate.
|
||||
* If expression is not variable op something or something op
|
||||
* variable, then punt and return a default estimate.
|
||||
*/
|
||||
if (!get_restriction_variable(root, args, varRelid,
|
||||
&vardata, &other, &varonleft))
|
||||
@@ -1238,9 +1238,9 @@ booltestsel(Query *root, BoolTestType booltesttype, Node *arg,
|
||||
{
|
||||
/*
|
||||
* If we can't get variable statistics for the argument, perhaps
|
||||
* clause_selectivity can do something with it. We ignore
|
||||
* the possibility of a NULL value when using clause_selectivity,
|
||||
* and just assume the value is either TRUE or FALSE.
|
||||
* clause_selectivity can do something with it. We ignore the
|
||||
* possibility of a NULL value when using clause_selectivity, and
|
||||
* just assume the value is either TRUE or FALSE.
|
||||
*/
|
||||
switch (booltesttype)
|
||||
{
|
||||
@@ -1258,7 +1258,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",
|
||||
@@ -1334,7 +1334,7 @@ nulltestsel(Query *root, NullTestType nulltesttype, Node *arg, int varRelid)
|
||||
default:
|
||||
elog(ERROR, "unrecognized nulltesttype: %d",
|
||||
(int) nulltesttype);
|
||||
return (Selectivity) 0; /* keep compiler quiet */
|
||||
return (Selectivity) 0; /* keep compiler quiet */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1407,17 +1407,16 @@ eqjoinsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/*
|
||||
* We have most-common-value lists for both relations. Run
|
||||
* through the lists to see which MCVs actually join to each
|
||||
* other with the given operator. This allows us to determine
|
||||
* the exact join selectivity for the portion of the relations
|
||||
* represented by the MCV lists. We still have to estimate
|
||||
* for the remaining population, but in a skewed distribution
|
||||
* this gives us a big leg up in accuracy. For motivation see
|
||||
* the analysis in Y. Ioannidis and S. Christodoulakis, "On
|
||||
* the propagation of errors in the size of join results",
|
||||
* Technical Report 1018, Computer Science Dept., University
|
||||
* of Wisconsin, Madison, March 1991 (available from
|
||||
* ftp.cs.wisc.edu).
|
||||
* through the lists to see which MCVs actually join to each other
|
||||
* with the given operator. This allows us to determine the exact
|
||||
* join selectivity for the portion of the relations represented
|
||||
* by the MCV lists. We still have to estimate for the remaining
|
||||
* population, but in a skewed distribution this gives us a big
|
||||
* leg up in accuracy. For motivation see the analysis in Y.
|
||||
* Ioannidis and S. Christodoulakis, "On the propagation of errors
|
||||
* in the size of join results", Technical Report 1018, Computer
|
||||
* Science Dept., University of Wisconsin, Madison, March 1991
|
||||
* (available from ftp.cs.wisc.edu).
|
||||
*/
|
||||
FmgrInfo eqproc;
|
||||
bool *hasmatch1;
|
||||
@@ -1441,22 +1440,20 @@ 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.
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
if (jointype == JOIN_IN ||
|
||||
jointype == JOIN_REVERSE_IN ||
|
||||
@@ -1471,11 +1468,10 @@ eqjoinsel(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
/*
|
||||
* Note we assume that each MCV will match at most one member
|
||||
* of the other MCV list. If the operator isn't really
|
||||
* equality, there could be multiple matches --- but we don't
|
||||
* look for them, both for speed and because the math wouldn't
|
||||
* add up...
|
||||
* Note we assume that each MCV will match at most one member of
|
||||
* the other MCV list. If the operator isn't really equality,
|
||||
* there could be multiple matches --- but we don't look for them,
|
||||
* both for speed and because the math wouldn't add up...
|
||||
*/
|
||||
matchprodfreq = 0.0;
|
||||
nmatches = 0;
|
||||
@@ -1524,8 +1520,8 @@ eqjoinsel(PG_FUNCTION_ARGS)
|
||||
pfree(hasmatch2);
|
||||
|
||||
/*
|
||||
* Compute total frequency of non-null values that are not in
|
||||
* the MCV lists.
|
||||
* Compute total frequency of non-null values that are not in the
|
||||
* MCV lists.
|
||||
*/
|
||||
otherfreq1 = 1.0 - nullfrac1 - matchfreq1 - unmatchfreq1;
|
||||
otherfreq2 = 1.0 - nullfrac2 - matchfreq2 - unmatchfreq2;
|
||||
@@ -1533,12 +1529,12 @@ eqjoinsel(PG_FUNCTION_ARGS)
|
||||
CLAMP_PROBABILITY(otherfreq2);
|
||||
|
||||
/*
|
||||
* We can estimate the total selectivity from the point of
|
||||
* view of relation 1 as: the known selectivity for matched
|
||||
* MCVs, plus unmatched MCVs that are assumed to match against
|
||||
* random members of relation 2's non-MCV population, plus
|
||||
* non-MCV values that are assumed to match against random
|
||||
* members of relation 2's unmatched MCVs plus non-MCV values.
|
||||
* We can estimate the total selectivity from the point of view of
|
||||
* relation 1 as: the known selectivity for matched MCVs, plus
|
||||
* unmatched MCVs that are assumed to match against random members
|
||||
* of relation 2's non-MCV population, plus non-MCV values that
|
||||
* are assumed to match against random members of relation 2's
|
||||
* unmatched MCVs plus non-MCV values.
|
||||
*/
|
||||
totalsel1 = matchprodfreq;
|
||||
if (nd2 > nvalues2)
|
||||
@@ -1555,11 +1551,10 @@ eqjoinsel(PG_FUNCTION_ARGS)
|
||||
(nd1 - nmatches);
|
||||
|
||||
/*
|
||||
* Use the smaller of the two estimates. This can be
|
||||
* justified in essentially the same terms as given below for
|
||||
* the no-stats case: to a first approximation, we are
|
||||
* estimating from the point of view of the relation with
|
||||
* smaller nd.
|
||||
* Use the smaller of the two estimates. This can be justified in
|
||||
* essentially the same terms as given below for the no-stats
|
||||
* case: to a first approximation, we are estimating from the
|
||||
* point of view of the relation with smaller nd.
|
||||
*/
|
||||
selec = (totalsel1 < totalsel2) ? totalsel1 : totalsel2;
|
||||
}
|
||||
@@ -1567,26 +1562,24 @@ 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
|
||||
* 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.
|
||||
* 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
|
||||
* other side, we end up with the same answer anyway.
|
||||
* 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 other side,
|
||||
* we end up with the same answer anyway.
|
||||
*/
|
||||
double nullfrac1 = stats1 ? stats1->stanullfrac : 0.0;
|
||||
double nullfrac2 = stats2 ? stats2->stanullfrac : 0.0;
|
||||
@@ -2849,7 +2842,7 @@ get_restriction_variable(Query *root, List *args, int varRelid,
|
||||
right = (Node *) lsecond(args);
|
||||
|
||||
/*
|
||||
* Examine both sides. Note that when varRelid is nonzero, Vars of
|
||||
* Examine both sides. Note that when varRelid is nonzero, Vars of
|
||||
* other relations will be treated as pseudoconstants.
|
||||
*/
|
||||
examine_variable(root, left, varRelid, vardata);
|
||||
@@ -2961,18 +2954,18 @@ examine_variable(Query *root, Node *node, int varRelid,
|
||||
{
|
||||
vardata->statsTuple = SearchSysCache(STATRELATT,
|
||||
ObjectIdGetDatum(relid),
|
||||
Int16GetDatum(var->varattno),
|
||||
Int16GetDatum(var->varattno),
|
||||
0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* XXX This means the Var comes from a JOIN or sub-SELECT. Later
|
||||
* add code to dig down into the join etc and see if we can trace
|
||||
* the variable to something with stats. (But beware of
|
||||
* sub-SELECTs with DISTINCT/GROUP BY/etc. Perhaps there are
|
||||
* no cases where this would really be useful, because we'd have
|
||||
* flattened the subselect if it is??)
|
||||
* XXX This means the Var comes from a JOIN or sub-SELECT.
|
||||
* Later add code to dig down into the join etc and see if we
|
||||
* can trace the variable to something with stats. (But
|
||||
* beware of sub-SELECTs with DISTINCT/GROUP BY/etc. Perhaps
|
||||
* there are no cases where this would really be useful,
|
||||
* because we'd have flattened the subselect if it is??)
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -2981,8 +2974,8 @@ examine_variable(Query *root, Node *node, int varRelid,
|
||||
|
||||
/*
|
||||
* Okay, it's a more complicated expression. Determine variable
|
||||
* membership. Note that when varRelid isn't zero, only vars of
|
||||
* that relation are considered "real" vars.
|
||||
* membership. Note that when varRelid isn't zero, only vars of that
|
||||
* relation are considered "real" vars.
|
||||
*/
|
||||
varnos = pull_varnos(node);
|
||||
|
||||
@@ -2997,7 +2990,7 @@ examine_variable(Query *root, Node *node, int varRelid,
|
||||
if (varRelid == 0 || bms_is_member(varRelid, varnos))
|
||||
{
|
||||
onerel = find_base_rel(root,
|
||||
(varRelid ? varRelid : bms_singleton_member(varnos)));
|
||||
(varRelid ? varRelid : bms_singleton_member(varnos)));
|
||||
vardata->rel = onerel;
|
||||
}
|
||||
/* else treat it as a constant */
|
||||
@@ -3026,13 +3019,13 @@ examine_variable(Query *root, Node *node, int varRelid,
|
||||
if (onerel)
|
||||
{
|
||||
/*
|
||||
* We have an expression in vars of a single relation. Try to
|
||||
* We have an expression in vars of a single relation. Try to
|
||||
* match it to expressional index columns, in hopes of finding
|
||||
* some statistics.
|
||||
*
|
||||
* XXX it's conceivable that there are multiple matches with
|
||||
* different index opclasses; if so, we need to pick one that
|
||||
* matches the operator we are estimating for. FIXME later.
|
||||
* matches the operator we are estimating for. FIXME later.
|
||||
*/
|
||||
ListCell *ilist;
|
||||
|
||||
@@ -3067,8 +3060,8 @@ examine_variable(Query *root, Node *node, int varRelid,
|
||||
if (equal(node, indexkey))
|
||||
{
|
||||
/*
|
||||
* Found a match ... is it a unique index?
|
||||
* Tests here should match has_unique_index().
|
||||
* Found a match ... is it a unique index? Tests
|
||||
* here should match has_unique_index().
|
||||
*/
|
||||
if (index->unique &&
|
||||
index->ncolumns == 1 &&
|
||||
@@ -3076,8 +3069,8 @@ examine_variable(Query *root, Node *node, int varRelid,
|
||||
vardata->isunique = true;
|
||||
/* Has it got stats? */
|
||||
vardata->statsTuple = SearchSysCache(STATRELATT,
|
||||
ObjectIdGetDatum(index->indexoid),
|
||||
Int16GetDatum(pos + 1),
|
||||
ObjectIdGetDatum(index->indexoid),
|
||||
Int16GetDatum(pos + 1),
|
||||
0, 0);
|
||||
if (vardata->statsTuple)
|
||||
break;
|
||||
@@ -3107,9 +3100,9 @@ get_variable_numdistinct(VariableStatData *vardata)
|
||||
double ntuples;
|
||||
|
||||
/*
|
||||
* Determine the stadistinct value to use. There are cases where
|
||||
* we can get an estimate even without a pg_statistic entry, or
|
||||
* can get a better value than is in pg_statistic.
|
||||
* Determine the stadistinct value to use. There are cases where we
|
||||
* can get an estimate even without a pg_statistic entry, or can get a
|
||||
* better value than is in pg_statistic.
|
||||
*/
|
||||
if (HeapTupleIsValid(vardata->statsTuple))
|
||||
{
|
||||
@@ -3124,16 +3117,16 @@ get_variable_numdistinct(VariableStatData *vardata)
|
||||
/*
|
||||
* Special-case boolean columns: presumably, two distinct values.
|
||||
*
|
||||
* Are there any other datatypes we should wire in special
|
||||
* estimates for?
|
||||
* Are there any other datatypes we should wire in special estimates
|
||||
* for?
|
||||
*/
|
||||
stadistinct = 2.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* We don't keep statistics for system columns, but in some
|
||||
* cases we can infer distinctness anyway.
|
||||
* We don't keep statistics for system columns, but in some cases
|
||||
* we can infer distinctness anyway.
|
||||
*/
|
||||
if (vardata->var && IsA(vardata->var, Var))
|
||||
{
|
||||
@@ -3141,27 +3134,28 @@ get_variable_numdistinct(VariableStatData *vardata)
|
||||
{
|
||||
case ObjectIdAttributeNumber:
|
||||
case SelfItemPointerAttributeNumber:
|
||||
stadistinct = -1.0; /* unique */
|
||||
stadistinct = -1.0; /* unique */
|
||||
break;
|
||||
case TableOidAttributeNumber:
|
||||
stadistinct = 1.0; /* only 1 value */
|
||||
stadistinct = 1.0; /* only 1 value */
|
||||
break;
|
||||
default:
|
||||
stadistinct = 0.0; /* means "unknown" */
|
||||
stadistinct = 0.0; /* means "unknown" */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
stadistinct = 0.0; /* means "unknown" */
|
||||
stadistinct = 0.0; /* means "unknown" */
|
||||
|
||||
/*
|
||||
* XXX consider using estimate_num_groups on expressions?
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is a unique index for the variable, assume it is unique
|
||||
* no matter what pg_statistic says (the statistics could be out
|
||||
* of date). Can skip search if we already think it's unique.
|
||||
* If there is a unique index for the variable, assume it is unique no
|
||||
* matter what pg_statistic says (the statistics could be out of
|
||||
* date). Can skip search if we already think it's unique.
|
||||
*/
|
||||
if (stadistinct != -1.0)
|
||||
{
|
||||
@@ -3169,7 +3163,7 @@ get_variable_numdistinct(VariableStatData *vardata)
|
||||
stadistinct = -1.0;
|
||||
else if (vardata->var && IsA(vardata->var, Var) &&
|
||||
vardata->rel &&
|
||||
has_unique_index(vardata->rel,
|
||||
has_unique_index(vardata->rel,
|
||||
((Var *) vardata->var)->varattno))
|
||||
stadistinct = -1.0;
|
||||
}
|
||||
@@ -3381,7 +3375,7 @@ like_fixed_prefix(Const *patt_const, bool case_insensitive,
|
||||
}
|
||||
else
|
||||
{
|
||||
bytea *bstr = DatumGetByteaP(patt_const->constvalue);
|
||||
bytea *bstr = DatumGetByteaP(patt_const->constvalue);
|
||||
|
||||
pattlen = VARSIZE(bstr) - VARHDRSZ;
|
||||
if (pattlen > 0)
|
||||
@@ -3768,7 +3762,7 @@ like_selectivity(Const *patt_const, bool case_insensitive)
|
||||
}
|
||||
else
|
||||
{
|
||||
bytea *bstr = DatumGetByteaP(patt_const->constvalue);
|
||||
bytea *bstr = DatumGetByteaP(patt_const->constvalue);
|
||||
|
||||
pattlen = VARSIZE(bstr) - VARHDRSZ;
|
||||
if (pattlen > 0)
|
||||
@@ -4005,12 +3999,12 @@ make_greater_string(const Const *str_const)
|
||||
if (datatype == NAMEOID)
|
||||
{
|
||||
workstr = DatumGetCString(DirectFunctionCall1(nameout,
|
||||
str_const->constvalue));
|
||||
str_const->constvalue));
|
||||
len = strlen(workstr);
|
||||
}
|
||||
else if (datatype == BYTEAOID)
|
||||
{
|
||||
bytea *bstr = DatumGetByteaP(str_const->constvalue);
|
||||
bytea *bstr = DatumGetByteaP(str_const->constvalue);
|
||||
|
||||
len = VARSIZE(bstr) - VARHDRSZ;
|
||||
if (len > 0)
|
||||
@@ -4027,7 +4021,7 @@ make_greater_string(const Const *str_const)
|
||||
else
|
||||
{
|
||||
workstr = DatumGetCString(DirectFunctionCall1(textout,
|
||||
str_const->constvalue));
|
||||
str_const->constvalue));
|
||||
len = strlen(workstr);
|
||||
}
|
||||
|
||||
@@ -4123,8 +4117,8 @@ string_to_const(const char *str, Oid datatype)
|
||||
static Const *
|
||||
string_to_bytea_const(const char *str, size_t str_len)
|
||||
{
|
||||
bytea *bstr = palloc(VARHDRSZ + str_len);
|
||||
Datum conval;
|
||||
bytea *bstr = palloc(VARHDRSZ + str_len);
|
||||
Datum conval;
|
||||
|
||||
memcpy(VARDATA(bstr), str, str_len);
|
||||
VARATT_SIZEP(bstr) = VARHDRSZ + str_len;
|
||||
@@ -4162,30 +4156,31 @@ genericcostestimate(Query *root, RelOptInfo *rel,
|
||||
/*
|
||||
* If the index is partial, AND the index predicate with the
|
||||
* explicitly given indexquals to produce a more accurate idea of the
|
||||
* index selectivity. This may produce redundant clauses. We get rid
|
||||
* of exact duplicates in the code below. We expect that most
|
||||
* cases of partial redundancy (such as "x < 4" from the qual and
|
||||
* "x < 5" from the predicate) will be recognized and handled correctly
|
||||
* by clauselist_selectivity(). This assumption is somewhat fragile,
|
||||
* index selectivity. This may produce redundant clauses. We get rid
|
||||
* of exact duplicates in the code below. We expect that most cases
|
||||
* of partial redundancy (such as "x < 4" from the qual and "x < 5"
|
||||
* from the predicate) will be recognized and handled correctly by
|
||||
* clauselist_selectivity(). This assumption is somewhat fragile,
|
||||
* since it depends on pred_test() and clauselist_selectivity() having
|
||||
* similar capabilities, and there are certainly many cases where we will
|
||||
* end up with a too-low selectivity estimate. This will bias the system
|
||||
* in favor of using partial indexes where possible, which is not
|
||||
* necessarily a bad thing. But it'd be nice to do better someday.
|
||||
* similar capabilities, and there are certainly many cases where we
|
||||
* will end up with a too-low selectivity estimate. This will bias
|
||||
* the system in favor of using partial indexes where possible, which
|
||||
* is not necessarily a bad thing. But it'd be nice to do better
|
||||
* someday.
|
||||
*
|
||||
* Note that index->indpred and indexQuals are both in implicit-AND form,
|
||||
* so ANDing them together just takes merging the lists. However,
|
||||
* eliminating duplicates is a bit trickier because indexQuals contains
|
||||
* RestrictInfo nodes and the indpred does not. It is okay to pass a
|
||||
* mixed list to clauselist_selectivity, but we have to work a bit to
|
||||
* generate a list without logical duplicates. (We could just list_union
|
||||
* indpred and strippedQuals, but then we'd not get caching of per-qual
|
||||
* selectivity estimates.)
|
||||
* eliminating duplicates is a bit trickier because indexQuals
|
||||
* contains RestrictInfo nodes and the indpred does not. It is okay
|
||||
* to pass a mixed list to clauselist_selectivity, but we have to work
|
||||
* a bit to generate a list without logical duplicates. (We could
|
||||
* just list_union indpred and strippedQuals, but then we'd not get
|
||||
* caching of per-qual selectivity estimates.)
|
||||
*/
|
||||
if (index->indpred != NIL)
|
||||
{
|
||||
List *strippedQuals;
|
||||
List *predExtraQuals;
|
||||
List *strippedQuals;
|
||||
List *predExtraQuals;
|
||||
|
||||
strippedQuals = get_actual_clauses(indexQuals);
|
||||
predExtraQuals = list_difference(index->indpred, strippedQuals);
|
||||
@@ -4236,22 +4231,22 @@ genericcostestimate(Query *root, RelOptInfo *rel,
|
||||
/*
|
||||
* Compute the index access cost.
|
||||
*
|
||||
* Disk cost: our generic assumption is that the index pages will be
|
||||
* read sequentially, so they have cost 1.0 each, not random_page_cost.
|
||||
* Disk cost: our generic assumption is that the index pages will be read
|
||||
* sequentially, so they have cost 1.0 each, not random_page_cost.
|
||||
*/
|
||||
*indexTotalCost = numIndexPages;
|
||||
|
||||
/*
|
||||
* CPU cost: any complex expressions in the indexquals will need to
|
||||
* be evaluated once at the start of the scan to reduce them to runtime
|
||||
* keys to pass to the index AM (see nodeIndexscan.c). We model the
|
||||
* per-tuple CPU costs as cpu_index_tuple_cost plus one cpu_operator_cost
|
||||
* per indexqual operator.
|
||||
* CPU cost: any complex expressions in the indexquals will need to be
|
||||
* evaluated once at the start of the scan to reduce them to runtime
|
||||
* keys to pass to the index AM (see nodeIndexscan.c). We model the
|
||||
* per-tuple CPU costs as cpu_index_tuple_cost plus one
|
||||
* cpu_operator_cost per indexqual operator.
|
||||
*
|
||||
* Note: this neglects the possible costs of rechecking lossy operators
|
||||
* and OR-clause expressions. Detecting that that might be needed seems
|
||||
* more expensive than it's worth, though, considering all the other
|
||||
* inaccuracies here ...
|
||||
* and OR-clause expressions. Detecting that that might be needed
|
||||
* seems more expensive than it's worth, though, considering all the
|
||||
* other inaccuracies here ...
|
||||
*/
|
||||
cost_qual_eval(&index_qual_cost, indexQuals);
|
||||
qual_op_cost = cpu_operator_cost * list_length(indexQuals);
|
||||
@@ -4290,12 +4285,13 @@ btcostestimate(PG_FUNCTION_ARGS)
|
||||
indexSelectivity, indexCorrelation);
|
||||
|
||||
/*
|
||||
* If we can get an estimate of the first column's ordering correlation C
|
||||
* from pg_statistic, estimate the index correlation as C for a single-
|
||||
* column index, or C * 0.75 for multiple columns. (The idea here is
|
||||
* that multiple columns dilute the importance of the first column's
|
||||
* ordering, but don't negate it entirely. Before 8.0 we divided the
|
||||
* correlation by the number of columns, but that seems too strong.)
|
||||
* If we can get an estimate of the first column's ordering
|
||||
* correlation C from pg_statistic, estimate the index correlation as
|
||||
* C for a single- column index, or C * 0.75 for multiple columns.
|
||||
* (The idea here is that multiple columns dilute the importance of
|
||||
* the first column's ordering, but don't negate it entirely. Before
|
||||
* 8.0 we divided the correlation by the number of columns, but that
|
||||
* seems too strong.)
|
||||
*/
|
||||
if (index->indexkeys[0] != 0)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/tid.c,v 1.46 2004/08/29 04:12:52 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/tid.c,v 1.47 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* input routine largely stolen from boxin().
|
||||
@@ -242,7 +242,7 @@ currtid_for_view(Relation viewrel, ItemPointer tid)
|
||||
if (list_length(rewrite->actions) != 1)
|
||||
elog(ERROR, "only one select rule is allowed in views");
|
||||
query = (Query *) linitial(rewrite->actions);
|
||||
tle = get_tle_by_resno(query->targetList, tididx+1);
|
||||
tle = get_tle_by_resno(query->targetList, tididx + 1);
|
||||
if (tle && tle->expr && IsA(tle->expr, Var))
|
||||
{
|
||||
Var *var = (Var *) tle->expr;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.111 2004/08/29 04:12:52 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.112 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -70,7 +70,7 @@ timestamp_in(PG_FUNCTION_ARGS)
|
||||
int32 typmod = PG_GETARG_INT32(2);
|
||||
Timestamp result;
|
||||
fsec_t fsec;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
int tz;
|
||||
int dtype;
|
||||
@@ -137,7 +137,7 @@ timestamp_out(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
|
||||
char *result;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
fsec_t fsec;
|
||||
char *tzn = NULL;
|
||||
@@ -167,7 +167,7 @@ timestamp_recv(PG_FUNCTION_ARGS)
|
||||
{
|
||||
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
|
||||
Timestamp timestamp;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
fsec_t fsec;
|
||||
|
||||
@@ -179,7 +179,7 @@ timestamp_recv(PG_FUNCTION_ARGS)
|
||||
|
||||
/* rangecheck: see if timestamp_out would like it */
|
||||
if (TIMESTAMP_NOT_FINITE(timestamp))
|
||||
/* ok */;
|
||||
/* ok */ ;
|
||||
else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
||||
@@ -310,7 +310,7 @@ timestamptz_in(PG_FUNCTION_ARGS)
|
||||
int32 typmod = PG_GETARG_INT32(2);
|
||||
TimestampTz result;
|
||||
fsec_t fsec;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
int tz;
|
||||
int dtype;
|
||||
@@ -378,7 +378,7 @@ timestamptz_out(PG_FUNCTION_ARGS)
|
||||
TimestampTz dt = PG_GETARG_TIMESTAMPTZ(0);
|
||||
char *result;
|
||||
int tz;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
fsec_t fsec;
|
||||
char *tzn;
|
||||
@@ -407,9 +407,9 @@ Datum
|
||||
timestamptz_recv(PG_FUNCTION_ARGS)
|
||||
{
|
||||
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
|
||||
TimestampTz timestamp;
|
||||
TimestampTz timestamp;
|
||||
int tz;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
fsec_t fsec;
|
||||
char *tzn;
|
||||
@@ -422,7 +422,7 @@ timestamptz_recv(PG_FUNCTION_ARGS)
|
||||
|
||||
/* rangecheck: see if timestamptz_out would like it */
|
||||
if (TIMESTAMP_NOT_FINITE(timestamp))
|
||||
/* ok */;
|
||||
/* ok */ ;
|
||||
else if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
||||
@@ -486,7 +486,7 @@ interval_in(PG_FUNCTION_ARGS)
|
||||
int32 typmod = PG_GETARG_INT32(2);
|
||||
Interval *result;
|
||||
fsec_t fsec;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
int dtype;
|
||||
int nf;
|
||||
@@ -550,7 +550,7 @@ interval_out(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Interval *span = PG_GETARG_INTERVAL_P(0);
|
||||
char *result;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
fsec_t fsec;
|
||||
char buf[MAXDATELEN + 1];
|
||||
@@ -961,7 +961,7 @@ dt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
|
||||
* -1 on out of range
|
||||
*/
|
||||
int
|
||||
timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, char **tzn)
|
||||
timestamp2tm(Timestamp dt, int *tzp, struct pg_tm * tm, fsec_t *fsec, char **tzn)
|
||||
{
|
||||
Timestamp date;
|
||||
Timestamp time;
|
||||
@@ -1042,7 +1042,7 @@ timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, char **tzn)
|
||||
*
|
||||
* First, convert to an integral timestamp, avoiding possibly
|
||||
* platform-specific roundoff-in-wrong-direction errors, and adjust to
|
||||
* Unix epoch. Then see if we can convert to pg_time_t without loss.
|
||||
* Unix epoch. Then see if we can convert to pg_time_t without loss.
|
||||
* This coding avoids hardwiring any assumptions about the width of
|
||||
* pg_time_t, so it should behave sanely on machines without int64.
|
||||
*/
|
||||
@@ -1056,7 +1056,7 @@ timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, char **tzn)
|
||||
utime = (pg_time_t) dt;
|
||||
if ((Timestamp) utime == dt)
|
||||
{
|
||||
struct pg_tm *tx = pg_localtime(&utime);
|
||||
struct pg_tm *tx = pg_localtime(&utime);
|
||||
|
||||
tm->tm_year = tx->tm_year + 1900;
|
||||
tm->tm_mon = tx->tm_mon + 1;
|
||||
@@ -1102,6 +1102,7 @@ tm2timestamp(struct pg_tm * tm, fsec_t fsec, int *tzp, Timestamp *result)
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
int date;
|
||||
int64 time;
|
||||
|
||||
#else
|
||||
double date,
|
||||
time;
|
||||
@@ -1139,6 +1140,7 @@ interval2tm(Interval span, struct pg_tm * tm, fsec_t *fsec)
|
||||
{
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
int64 time;
|
||||
|
||||
#else
|
||||
double time;
|
||||
#endif
|
||||
@@ -1252,8 +1254,8 @@ interval_finite(PG_FUNCTION_ARGS)
|
||||
void
|
||||
GetEpochTime(struct pg_tm * tm)
|
||||
{
|
||||
struct pg_tm *t0;
|
||||
pg_time_t epoch = 0;
|
||||
struct pg_tm *t0;
|
||||
pg_time_t epoch = 0;
|
||||
|
||||
t0 = pg_gmtime(&epoch);
|
||||
|
||||
@@ -1272,7 +1274,7 @@ Timestamp
|
||||
SetEpochTimestamp(void)
|
||||
{
|
||||
Timestamp dt;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
|
||||
GetEpochTime(tm);
|
||||
@@ -1399,8 +1401,8 @@ Datum
|
||||
timestamp_eq_timestamptz(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
|
||||
dt1 = timestamp2timestamptz(timestampVal);
|
||||
|
||||
@@ -1411,8 +1413,8 @@ Datum
|
||||
timestamp_ne_timestamptz(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
|
||||
dt1 = timestamp2timestamptz(timestampVal);
|
||||
|
||||
@@ -1423,8 +1425,8 @@ Datum
|
||||
timestamp_lt_timestamptz(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
|
||||
dt1 = timestamp2timestamptz(timestampVal);
|
||||
|
||||
@@ -1435,8 +1437,8 @@ Datum
|
||||
timestamp_gt_timestamptz(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
|
||||
dt1 = timestamp2timestamptz(timestampVal);
|
||||
|
||||
@@ -1447,8 +1449,8 @@ Datum
|
||||
timestamp_le_timestamptz(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
|
||||
dt1 = timestamp2timestamptz(timestampVal);
|
||||
|
||||
@@ -1459,8 +1461,8 @@ Datum
|
||||
timestamp_ge_timestamptz(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
|
||||
dt1 = timestamp2timestamptz(timestampVal);
|
||||
|
||||
@@ -1471,8 +1473,8 @@ Datum
|
||||
timestamp_cmp_timestamptz(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1);
|
||||
TimestampTz dt1;
|
||||
|
||||
dt1 = timestamp2timestamptz(timestampVal);
|
||||
|
||||
@@ -1482,9 +1484,9 @@ timestamp_cmp_timestamptz(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
timestamptz_eq_timestamp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
|
||||
TimestampTz dt2;
|
||||
TimestampTz dt2;
|
||||
|
||||
dt2 = timestamp2timestamptz(timestampVal);
|
||||
|
||||
@@ -1494,9 +1496,9 @@ timestamptz_eq_timestamp(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
timestamptz_ne_timestamp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
|
||||
TimestampTz dt2;
|
||||
TimestampTz dt2;
|
||||
|
||||
dt2 = timestamp2timestamptz(timestampVal);
|
||||
|
||||
@@ -1506,9 +1508,9 @@ timestamptz_ne_timestamp(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
timestamptz_lt_timestamp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
|
||||
TimestampTz dt2;
|
||||
TimestampTz dt2;
|
||||
|
||||
dt2 = timestamp2timestamptz(timestampVal);
|
||||
|
||||
@@ -1518,9 +1520,9 @@ timestamptz_lt_timestamp(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
timestamptz_gt_timestamp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
|
||||
TimestampTz dt2;
|
||||
TimestampTz dt2;
|
||||
|
||||
dt2 = timestamp2timestamptz(timestampVal);
|
||||
|
||||
@@ -1530,9 +1532,9 @@ timestamptz_gt_timestamp(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
timestamptz_le_timestamp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
|
||||
TimestampTz dt2;
|
||||
TimestampTz dt2;
|
||||
|
||||
dt2 = timestamp2timestamptz(timestampVal);
|
||||
|
||||
@@ -1542,9 +1544,9 @@ timestamptz_le_timestamp(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
timestamptz_ge_timestamp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
|
||||
TimestampTz dt2;
|
||||
TimestampTz dt2;
|
||||
|
||||
dt2 = timestamp2timestamptz(timestampVal);
|
||||
|
||||
@@ -1554,9 +1556,9 @@ timestamptz_ge_timestamp(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
timestamptz_cmp_timestamp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0);
|
||||
Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
|
||||
TimestampTz dt2;
|
||||
TimestampTz dt2;
|
||||
|
||||
dt2 = timestamp2timestamptz(timestampVal);
|
||||
|
||||
@@ -1892,7 +1894,7 @@ timestamp_pl_interval(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (span->month != 0)
|
||||
{
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
fsec_t fsec;
|
||||
|
||||
@@ -1970,7 +1972,7 @@ timestamptz_pl_interval(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (span->month != 0)
|
||||
{
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
fsec_t fsec;
|
||||
|
||||
@@ -2292,11 +2294,11 @@ timestamp_age(PG_FUNCTION_ARGS)
|
||||
fsec_t fsec,
|
||||
fsec1,
|
||||
fsec2;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
struct pg_tm tt1,
|
||||
struct pg_tm tt1,
|
||||
*tm1 = &tt1;
|
||||
struct pg_tm tt2,
|
||||
struct pg_tm tt2,
|
||||
*tm2 = &tt2;
|
||||
|
||||
result = (Interval *) palloc(sizeof(Interval));
|
||||
@@ -2403,11 +2405,11 @@ timestamptz_age(PG_FUNCTION_ARGS)
|
||||
fsec_t fsec,
|
||||
fsec1,
|
||||
fsec2;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
struct pg_tm tt1,
|
||||
struct pg_tm tt1,
|
||||
*tm1 = &tt1;
|
||||
struct pg_tm tt2,
|
||||
struct pg_tm tt2,
|
||||
*tm2 = &tt2;
|
||||
|
||||
result = (Interval *) palloc(sizeof(Interval));
|
||||
@@ -2698,7 +2700,7 @@ timestamp_trunc(PG_FUNCTION_ARGS)
|
||||
val;
|
||||
char *lowunits;
|
||||
fsec_t fsec;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
|
||||
if (TIMESTAMP_NOT_FINITE(timestamp))
|
||||
@@ -2720,7 +2722,7 @@ timestamp_trunc(PG_FUNCTION_ARGS)
|
||||
switch (val)
|
||||
{
|
||||
case DTK_WEEK:
|
||||
isoweek2date( date2isoweek( tm->tm_year, tm->tm_mon, tm->tm_mday ), &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday) );
|
||||
isoweek2date(date2isoweek(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;
|
||||
@@ -2729,15 +2731,15 @@ timestamp_trunc(PG_FUNCTION_ARGS)
|
||||
case DTK_MILLENNIUM:
|
||||
/* see comments in timestamptz_trunc */
|
||||
if (tm->tm_year > 0)
|
||||
tm->tm_year = ((tm->tm_year+999) / 1000) * 1000 - 999;
|
||||
tm->tm_year = ((tm->tm_year + 999) / 1000) * 1000 - 999;
|
||||
else
|
||||
tm->tm_year = - ((999 - (tm->tm_year-1))/1000) * 1000 + 1;
|
||||
tm->tm_year = -((999 - (tm->tm_year - 1)) / 1000) * 1000 + 1;
|
||||
case DTK_CENTURY:
|
||||
/* see comments in timestamptz_trunc */
|
||||
if (tm->tm_year > 0)
|
||||
tm->tm_year = ((tm->tm_year+99) / 100) * 100 - 99;
|
||||
tm->tm_year = ((tm->tm_year + 99) / 100) * 100 - 99;
|
||||
else
|
||||
tm->tm_year = - ((99 - (tm->tm_year-1))/100) * 100 + 1;
|
||||
tm->tm_year = -((99 - (tm->tm_year - 1)) / 100) * 100 + 1;
|
||||
case DTK_DECADE:
|
||||
/* see comments in timestamptz_trunc */
|
||||
if (val != DTK_MILLENNIUM && val != DTK_CENTURY)
|
||||
@@ -2745,7 +2747,7 @@ timestamp_trunc(PG_FUNCTION_ARGS)
|
||||
if (tm->tm_year > 0)
|
||||
tm->tm_year = (tm->tm_year / 10) * 10;
|
||||
else
|
||||
tm->tm_year = - ((8-(tm->tm_year-1)) / 10) * 10;
|
||||
tm->tm_year = -((8 - (tm->tm_year - 1)) / 10) * 10;
|
||||
}
|
||||
case DTK_YEAR:
|
||||
tm->tm_mon = 1;
|
||||
@@ -2817,7 +2819,7 @@ timestamptz_trunc(PG_FUNCTION_ARGS)
|
||||
char *lowunits;
|
||||
fsec_t fsec;
|
||||
char *tzn;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
|
||||
if (TIMESTAMP_NOT_FINITE(timestamp))
|
||||
@@ -2839,7 +2841,7 @@ timestamptz_trunc(PG_FUNCTION_ARGS)
|
||||
switch (val)
|
||||
{
|
||||
case DTK_WEEK:
|
||||
isoweek2date( date2isoweek( tm->tm_year, tm->tm_mon, tm->tm_mday ), &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday) );
|
||||
isoweek2date(date2isoweek(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;
|
||||
@@ -2847,22 +2849,26 @@ timestamptz_trunc(PG_FUNCTION_ARGS)
|
||||
break;
|
||||
/* one may consider DTK_THOUSAND and DTK_HUNDRED... */
|
||||
case DTK_MILLENNIUM:
|
||||
/* truncating to the millennium? what is this supposed to mean?
|
||||
* let us put the first year of the millennium...
|
||||
|
||||
/*
|
||||
* truncating to the millennium? what is this supposed to
|
||||
* mean? let us put the first year of the millennium...
|
||||
* i.e. -1000, 1, 1001, 2001...
|
||||
*/
|
||||
if (tm->tm_year > 0)
|
||||
tm->tm_year = ((tm->tm_year+999) / 1000) * 1000 - 999;
|
||||
tm->tm_year = ((tm->tm_year + 999) / 1000) * 1000 - 999;
|
||||
else
|
||||
tm->tm_year = - ((999 - (tm->tm_year-1))/1000) * 1000 + 1;
|
||||
tm->tm_year = -((999 - (tm->tm_year - 1)) / 1000) * 1000 + 1;
|
||||
case DTK_CENTURY:
|
||||
/* truncating to the century? as above: -100, 1, 101... */
|
||||
if (tm->tm_year > 0)
|
||||
tm->tm_year = ((tm->tm_year+99) / 100) * 100 - 99 ;
|
||||
tm->tm_year = ((tm->tm_year + 99) / 100) * 100 - 99;
|
||||
else
|
||||
tm->tm_year = - ((99 - (tm->tm_year-1))/100) * 100 + 1;
|
||||
tm->tm_year = -((99 - (tm->tm_year - 1)) / 100) * 100 + 1;
|
||||
case DTK_DECADE:
|
||||
/* truncating to the decade? first year of the decade.
|
||||
|
||||
/*
|
||||
* truncating to the decade? first year of the decade.
|
||||
* must not be applied if year was truncated before!
|
||||
*/
|
||||
if (val != DTK_MILLENNIUM && val != DTK_CENTURY)
|
||||
@@ -2870,7 +2876,7 @@ timestamptz_trunc(PG_FUNCTION_ARGS)
|
||||
if (tm->tm_year > 0)
|
||||
tm->tm_year = (tm->tm_year / 10) * 10;
|
||||
else
|
||||
tm->tm_year = - ((8-(tm->tm_year-1)) / 10) * 10;
|
||||
tm->tm_year = -((8 - (tm->tm_year - 1)) / 10) * 10;
|
||||
}
|
||||
case DTK_YEAR:
|
||||
tm->tm_mon = 1;
|
||||
@@ -2941,7 +2947,7 @@ interval_trunc(PG_FUNCTION_ARGS)
|
||||
val;
|
||||
char *lowunits;
|
||||
fsec_t fsec;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
|
||||
result = (Interval *) palloc(sizeof(Interval));
|
||||
@@ -3039,7 +3045,7 @@ isoweek2date(int woy, int *year, int *mon, int *mday)
|
||||
if (!*year)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("cannot calculate week number without year information")));
|
||||
errmsg("cannot calculate week number without year information")));
|
||||
|
||||
/* fourth day of current year */
|
||||
day4 = date2j(*year, 1, 4);
|
||||
@@ -3113,10 +3119,10 @@ date2isoweek(int year, int mon, int mday)
|
||||
int
|
||||
date2isoyear(int year, int mon, int mday)
|
||||
{
|
||||
float8 result;
|
||||
int day0,
|
||||
day4,
|
||||
dayn;
|
||||
float8 result;
|
||||
int day0,
|
||||
day4,
|
||||
dayn;
|
||||
|
||||
/* current day */
|
||||
dayn = date2j(year, mon, mday);
|
||||
@@ -3155,9 +3161,7 @@ date2isoyear(int year, int mon, int mday)
|
||||
day0 = j2day(day4 - 1);
|
||||
|
||||
if (dayn >= (day4 - day0))
|
||||
{
|
||||
year++;
|
||||
}
|
||||
}
|
||||
|
||||
return year;
|
||||
@@ -3177,7 +3181,7 @@ timestamp_part(PG_FUNCTION_ARGS)
|
||||
val;
|
||||
char *lowunits;
|
||||
fsec_t fsec;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
|
||||
if (TIMESTAMP_NOT_FINITE(timestamp))
|
||||
@@ -3255,39 +3259,43 @@ timestamp_part(PG_FUNCTION_ARGS)
|
||||
if (tm->tm_year > 0)
|
||||
result = tm->tm_year;
|
||||
else
|
||||
/* there is no year 0, just 1 BC and 1 AD*/
|
||||
result = tm->tm_year - 1;
|
||||
/* there is no year 0, just 1 BC and 1 AD */
|
||||
result = tm->tm_year - 1;
|
||||
break;
|
||||
|
||||
case DTK_DECADE:
|
||||
/* what is a decade wrt dates?
|
||||
* let us assume that decade 199 is 1990 thru 1999...
|
||||
* decade 0 starts on year 1 BC, and -1 is 11 BC thru 2 BC...
|
||||
|
||||
/*
|
||||
* what is a decade wrt dates? let us assume that decade
|
||||
* 199 is 1990 thru 1999... decade 0 starts on year 1 BC,
|
||||
* and -1 is 11 BC thru 2 BC...
|
||||
*/
|
||||
if (tm->tm_year>=0)
|
||||
if (tm->tm_year >= 0)
|
||||
result = (tm->tm_year / 10);
|
||||
else
|
||||
result = -((8-(tm->tm_year-1)) / 10);
|
||||
result = -((8 - (tm->tm_year - 1)) / 10);
|
||||
break;
|
||||
|
||||
case DTK_CENTURY:
|
||||
/* centuries AD, c>0: year in [ (c-1)*100+1 : c*100 ]
|
||||
* centuries BC, c<0: year in [ c*100 : (c+1)*100-1 ]
|
||||
* there is no number 0 century.
|
||||
|
||||
/*
|
||||
* centuries AD, c>0: year in [ (c-1)*100+1 : c*100
|
||||
* ] centuries BC, c<0: year in [ c*100 :
|
||||
* (c+1)*100-1 ] there is no number 0 century.
|
||||
*/
|
||||
if (tm->tm_year > 0)
|
||||
result = ((tm->tm_year+99) / 100);
|
||||
result = ((tm->tm_year + 99) / 100);
|
||||
else
|
||||
/* caution: C division may have negative remainder */
|
||||
result = - ((99 - (tm->tm_year-1))/100);
|
||||
result = -((99 - (tm->tm_year - 1)) / 100);
|
||||
break;
|
||||
|
||||
case DTK_MILLENNIUM:
|
||||
/* see comments above. */
|
||||
if (tm->tm_year > 0)
|
||||
result = ((tm->tm_year+999) / 1000);
|
||||
result = ((tm->tm_year + 999) / 1000);
|
||||
else
|
||||
result = - ((999 - (tm->tm_year-1))/1000);
|
||||
result = -((999 - (tm->tm_year - 1)) / 1000);
|
||||
break;
|
||||
|
||||
case DTK_JULIAN:
|
||||
@@ -3397,7 +3405,7 @@ timestamptz_part(PG_FUNCTION_ARGS)
|
||||
double dummy;
|
||||
fsec_t fsec;
|
||||
char *tzn;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
|
||||
if (TIMESTAMP_NOT_FINITE(timestamp))
|
||||
@@ -3492,26 +3500,26 @@ timestamptz_part(PG_FUNCTION_ARGS)
|
||||
|
||||
case DTK_DECADE:
|
||||
/* see comments in timestamp_part */
|
||||
if (tm->tm_year>0)
|
||||
if (tm->tm_year > 0)
|
||||
result = (tm->tm_year / 10);
|
||||
else
|
||||
result = - ((8-(tm->tm_year-1)) / 10);
|
||||
result = -((8 - (tm->tm_year - 1)) / 10);
|
||||
break;
|
||||
|
||||
case DTK_CENTURY:
|
||||
/* see comments in timestamp_part */
|
||||
if (tm->tm_year > 0)
|
||||
result = ((tm->tm_year+99) / 100);
|
||||
result = ((tm->tm_year + 99) / 100);
|
||||
else
|
||||
result = - ((99 - (tm->tm_year-1))/100);
|
||||
result = -((99 - (tm->tm_year - 1)) / 100);
|
||||
break;
|
||||
|
||||
case DTK_MILLENNIUM:
|
||||
/* see comments in timestamp_part */
|
||||
if (tm->tm_year > 0)
|
||||
result = ((tm->tm_year+999) / 1000);
|
||||
result = ((tm->tm_year + 999) / 1000);
|
||||
else
|
||||
result = - ((999 - (tm->tm_year-1))/1000);
|
||||
result = -((999 - (tm->tm_year - 1)) / 1000);
|
||||
break;
|
||||
|
||||
case DTK_JULIAN:
|
||||
@@ -3598,7 +3606,7 @@ interval_part(PG_FUNCTION_ARGS)
|
||||
val;
|
||||
char *lowunits;
|
||||
fsec_t fsec;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
|
||||
lowunits = downcase_truncate_identifier(VARDATA(units),
|
||||
@@ -3812,7 +3820,7 @@ static TimestampTz
|
||||
timestamp2timestamptz(Timestamp timestamp)
|
||||
{
|
||||
TimestampTz result;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
fsec_t fsec;
|
||||
int tz;
|
||||
@@ -3845,7 +3853,7 @@ timestamptz_timestamp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(0);
|
||||
Timestamp result;
|
||||
struct pg_tm tt,
|
||||
struct pg_tm tt,
|
||||
*tm = &tt;
|
||||
fsec_t fsec;
|
||||
char *tzn;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.41 2004/08/29 04:12:52 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.42 2004/08/29 05:06:49 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1215,9 +1215,7 @@ bitfromint4(PG_FUNCTION_ARGS)
|
||||
}
|
||||
/* store last fractional byte */
|
||||
if (destbitsleft > 0)
|
||||
{
|
||||
*r = (bits8) ((a << (8 - destbitsleft)) & BITMASK);
|
||||
}
|
||||
|
||||
PG_RETURN_VARBIT_P(result);
|
||||
}
|
||||
@@ -1296,9 +1294,7 @@ bitfromint8(PG_FUNCTION_ARGS)
|
||||
}
|
||||
/* store last fractional byte */
|
||||
if (destbitsleft > 0)
|
||||
{
|
||||
*r = (bits8) ((a << (8 - destbitsleft)) & BITMASK);
|
||||
}
|
||||
|
||||
PG_RETURN_VARBIT_P(result);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/varchar.c,v 1.106 2004/08/29 04:12:52 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/varchar.c,v 1.107 2004/08/29 05:06:50 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -221,9 +221,9 @@ bpchar(PG_FUNCTION_ARGS)
|
||||
for (i = maxmblen - VARHDRSZ; i < len - VARHDRSZ; i++)
|
||||
if (*(VARDATA(source) + i) != ' ')
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
|
||||
errmsg("value too long for type character(%d)",
|
||||
maxlen - VARHDRSZ)));
|
||||
(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
|
||||
errmsg("value too long for type character(%d)",
|
||||
maxlen - VARHDRSZ)));
|
||||
}
|
||||
|
||||
len = maxmblen;
|
||||
@@ -514,7 +514,7 @@ bpcharlen(PG_FUNCTION_ARGS)
|
||||
|
||||
/* get number of bytes, ignoring trailing spaces */
|
||||
len = bcTruelen(arg);
|
||||
|
||||
|
||||
/* in multibyte encoding, convert to number of characters */
|
||||
if (pg_database_encoding_max_length() != 1)
|
||||
len = pg_mbstrlen_with_len(VARDATA(arg), len);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.116 2004/08/29 04:12:52 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.117 2004/08/29 05:06:50 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -415,7 +415,7 @@ textlen(PG_FUNCTION_ARGS)
|
||||
* Does the real work for textlen()
|
||||
*
|
||||
* This is broken out so it can be called directly by other string processing
|
||||
* functions. Note that the argument is passed as a Datum, to indicate that
|
||||
* functions. Note that the argument is passed as a Datum, to indicate that
|
||||
* it may still be in compressed form. We can avoid decompressing it at all
|
||||
* in some cases.
|
||||
*/
|
||||
@@ -547,7 +547,7 @@ text_substr_no_len(PG_FUNCTION_ARGS)
|
||||
* Does the real work for text_substr() and text_substr_no_len()
|
||||
*
|
||||
* This is broken out so it can be called directly by other string processing
|
||||
* functions. Note that the argument is passed as a Datum, to indicate that
|
||||
* functions. Note that the argument is passed as a Datum, to indicate that
|
||||
* it may still be in compressed/toasted form. We can avoid detoasting all
|
||||
* of it in some cases.
|
||||
*/
|
||||
@@ -1728,8 +1728,10 @@ SplitIdentifierString(char *rawstring, char separator,
|
||||
endp = nextp;
|
||||
if (curname == nextp)
|
||||
return false; /* empty unquoted name not allowed */
|
||||
|
||||
/*
|
||||
* Downcase the identifier, using same code as main lexer does.
|
||||
* Downcase the identifier, using same code as main lexer
|
||||
* does.
|
||||
*
|
||||
* XXX because we want to overwrite the input in-place, we cannot
|
||||
* support a downcasing transformation that increases the
|
||||
@@ -2119,7 +2121,7 @@ text_to_array(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/* otherwise create array and exit */
|
||||
PG_RETURN_ARRAYTYPE_P(makeArrayResult(astate,
|
||||
CurrentMemoryContext));
|
||||
CurrentMemoryContext));
|
||||
}
|
||||
}
|
||||
else if (start_posn == 0)
|
||||
@@ -2139,7 +2141,7 @@ text_to_array(PG_FUNCTION_ARGS)
|
||||
/* interior field requested */
|
||||
result_text = text_substring(PointerGetDatum(inputstring),
|
||||
start_posn + fldsep_len,
|
||||
end_posn - start_posn - fldsep_len,
|
||||
end_posn - start_posn - fldsep_len,
|
||||
false);
|
||||
}
|
||||
|
||||
@@ -2230,7 +2232,7 @@ array_to_text(PG_FUNCTION_ARGS)
|
||||
|
||||
value = DatumGetCString(FunctionCall3(&my_extra->proc,
|
||||
itemvalue,
|
||||
ObjectIdGetDatum(typioparam),
|
||||
ObjectIdGetDatum(typioparam),
|
||||
Int32GetDatum(-1)));
|
||||
|
||||
if (i > 0)
|
||||
|
||||
Reference in New Issue
Block a user