mirror of
https://github.com/postgres/postgres.git
synced 2025-11-10 17:42:29 +03:00
Convert oidvector and int2vector into variable-length arrays. This
change saves a great deal of space in pg_proc and its primary index, and it eliminates the former requirement that INDEX_MAX_KEYS and FUNC_MAX_ARGS have the same value. INDEX_MAX_KEYS is still embedded in the on-disk representation (because it affects index tuple header size), but FUNC_MAX_ARGS is not. I believe it would now be possible to increase FUNC_MAX_ARGS at little cost, but haven't experimented yet. There are still a lot of vestigial references to FUNC_MAX_ARGS, which I will clean up in a separate pass. However, getting rid of it altogether would require changing the FunctionCallInfoData struct, and I'm not sure I want to buy into that.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.117 2005/03/24 21:50:37 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.118 2005/03/29 00:17:08 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -56,7 +56,7 @@
|
||||
*
|
||||
*
|
||||
* There are also some "fixed-length array" datatypes, such as NAME and
|
||||
* OIDVECTOR. These are simply a sequence of a fixed number of items each
|
||||
* POINT. These are simply a sequence of a fixed number of items each
|
||||
* of a fixed-length datatype, with no overhead; the item size must be
|
||||
* a multiple of its alignment requirement, because we do no padding.
|
||||
* We support subscripting on these types, but array_in() and array_out()
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/format_type.c,v 1.39 2004/12/31 22:01:21 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/format_type.c,v 1.40 2005/03/29 00:17:08 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -140,12 +140,15 @@ format_type_internal(Oid type_oid, int32 typemod,
|
||||
/*
|
||||
* Check if it's an array (and not a domain --- we don't want to show
|
||||
* the substructure of a domain type). Fixed-length array types such
|
||||
* as "name" shouldn't get deconstructed either.
|
||||
* as "name" shouldn't get deconstructed either. As of Postgres 8.1,
|
||||
* rather than checking typlen we check the toast property, and don't
|
||||
* deconstruct "plain storage" array types --- this is because we don't
|
||||
* want to show oidvector as oid[].
|
||||
*/
|
||||
array_base_type = typeform->typelem;
|
||||
|
||||
if (array_base_type != InvalidOid &&
|
||||
typeform->typlen == -1 &&
|
||||
typeform->typstorage != 'p' &&
|
||||
typeform->typtype != 'd')
|
||||
{
|
||||
/* Switch our attention to the array element type */
|
||||
@@ -459,29 +462,17 @@ type_maximum_size(Oid type_oid, int32 typemod)
|
||||
|
||||
/*
|
||||
* oidvectortypes - converts a vector of type OIDs to "typname" list
|
||||
*
|
||||
* The interface for this function is wrong: it should be told how many
|
||||
* OIDs are significant in the input vector, so that trailing InvalidOid
|
||||
* argument types can be recognized.
|
||||
*/
|
||||
Datum
|
||||
oidvectortypes(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid *oidArray = (Oid *) PG_GETARG_POINTER(0);
|
||||
oidvector *oidArray = (oidvector *) PG_GETARG_POINTER(0);
|
||||
char *result;
|
||||
int numargs;
|
||||
int numargs = oidArray->dim1;
|
||||
int num;
|
||||
size_t total;
|
||||
size_t left;
|
||||
|
||||
/* Try to guess how many args there are :-( */
|
||||
numargs = 0;
|
||||
for (num = 0; num < FUNC_MAX_ARGS; num++)
|
||||
{
|
||||
if (oidArray[num] != InvalidOid)
|
||||
numargs = num + 1;
|
||||
}
|
||||
|
||||
total = 20 * numargs + 1;
|
||||
result = palloc(total);
|
||||
result[0] = '\0';
|
||||
@@ -489,7 +480,7 @@ oidvectortypes(PG_FUNCTION_ARGS)
|
||||
|
||||
for (num = 0; num < numargs; num++)
|
||||
{
|
||||
char *typename = format_type_internal(oidArray[num], -1,
|
||||
char *typename = format_type_internal(oidArray->values[num], -1,
|
||||
false, true);
|
||||
size_t slen = strlen(typename);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.65 2005/02/27 08:31:30 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.66 2005/03/29 00:17:08 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -33,8 +33,10 @@
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "catalog/pg_type.h"
|
||||
#include "funcapi.h"
|
||||
#include "libpq/pqformat.h"
|
||||
#include "utils/array.h"
|
||||
#include "utils/builtins.h"
|
||||
|
||||
|
||||
@@ -47,6 +49,8 @@
|
||||
|
||||
#define SAMESIGN(a,b) (((a) < 0) == ((b) < 0))
|
||||
|
||||
#define Int2VectorSize(n) (offsetof(int2vector, values) + (n) * sizeof(int2))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32 current;
|
||||
@@ -109,20 +113,49 @@ int2send(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
/*
|
||||
* int2vectorin - converts "num num ..." to internal form
|
||||
* construct int2vector given a raw array of int2s
|
||||
*
|
||||
* Note: Fills any missing slots with zeroes.
|
||||
* If int2s is NULL then caller must fill values[] afterward
|
||||
*/
|
||||
int2vector *
|
||||
buildint2vector(const int2 *int2s, int n)
|
||||
{
|
||||
int2vector *result;
|
||||
|
||||
result = (int2vector *) palloc0(Int2VectorSize(n));
|
||||
|
||||
if (n > 0 && int2s)
|
||||
memcpy(result->values, int2s, n * sizeof(int2));
|
||||
|
||||
/*
|
||||
* Attach standard array header. For historical reasons, we set the
|
||||
* index lower bound to 0 not 1.
|
||||
*/
|
||||
result->size = Int2VectorSize(n);
|
||||
result->ndim = 1;
|
||||
result->flags = 0;
|
||||
result->elemtype = INT2OID;
|
||||
result->dim1 = n;
|
||||
result->lbound1 = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* int2vectorin - converts "num num ..." to internal form
|
||||
*/
|
||||
Datum
|
||||
int2vectorin(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *intString = PG_GETARG_CSTRING(0);
|
||||
int16 *result = (int16 *) palloc(sizeof(int16[INDEX_MAX_KEYS]));
|
||||
int slot;
|
||||
int2vector *result;
|
||||
int n;
|
||||
|
||||
for (slot = 0; *intString && slot < INDEX_MAX_KEYS; slot++)
|
||||
result = (int2vector *) palloc0(Int2VectorSize(FUNC_MAX_ARGS));
|
||||
|
||||
for (n = 0; *intString && n < FUNC_MAX_ARGS; n++)
|
||||
{
|
||||
if (sscanf(intString, "%hd", &result[slot]) != 1)
|
||||
if (sscanf(intString, "%hd", &result->values[n]) != 1)
|
||||
break;
|
||||
while (*intString && isspace((unsigned char) *intString))
|
||||
intString++;
|
||||
@@ -136,8 +169,12 @@ int2vectorin(PG_FUNCTION_ARGS)
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("int2vector has too many elements")));
|
||||
|
||||
while (slot < INDEX_MAX_KEYS)
|
||||
result[slot++] = 0;
|
||||
result->size = Int2VectorSize(n);
|
||||
result->ndim = 1;
|
||||
result->flags = 0;
|
||||
result->elemtype = INT2OID;
|
||||
result->dim1 = n;
|
||||
result->lbound1 = 0;
|
||||
|
||||
PG_RETURN_POINTER(result);
|
||||
}
|
||||
@@ -148,24 +185,19 @@ int2vectorin(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
int2vectorout(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int16 *int2Array = (int16 *) PG_GETARG_POINTER(0);
|
||||
int2vector *int2Array = (int2vector *) PG_GETARG_POINTER(0);
|
||||
int num,
|
||||
maxnum;
|
||||
nnums = int2Array->dim1;
|
||||
char *rp;
|
||||
char *result;
|
||||
|
||||
/* find last non-zero value in vector */
|
||||
for (maxnum = INDEX_MAX_KEYS - 1; maxnum >= 0; maxnum--)
|
||||
if (int2Array[maxnum] != 0)
|
||||
break;
|
||||
|
||||
/* assumes sign, 5 digits, ' ' */
|
||||
rp = result = (char *) palloc((maxnum + 1) * 7 + 1);
|
||||
for (num = 0; num <= maxnum; num++)
|
||||
rp = result = (char *) palloc(nnums * 7 + 1);
|
||||
for (num = 0; num < nnums; num++)
|
||||
{
|
||||
if (num != 0)
|
||||
*rp++ = ' ';
|
||||
pg_itoa(int2Array[num], rp);
|
||||
pg_itoa(int2Array->values[num], rp);
|
||||
while (*++rp != '\0')
|
||||
;
|
||||
}
|
||||
@@ -180,11 +212,19 @@ Datum
|
||||
int2vectorrecv(PG_FUNCTION_ARGS)
|
||||
{
|
||||
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
|
||||
int16 *result = (int16 *) palloc(sizeof(int16[INDEX_MAX_KEYS]));
|
||||
int slot;
|
||||
int2vector *result;
|
||||
|
||||
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
|
||||
result[slot] = (int16) pq_getmsgint(buf, sizeof(int16));
|
||||
result = (int2vector *)
|
||||
DatumGetPointer(DirectFunctionCall2(array_recv,
|
||||
PointerGetDatum(buf),
|
||||
ObjectIdGetDatum(INT2OID)));
|
||||
/* sanity checks: int2vector must be 1-D, no nulls */
|
||||
if (result->ndim != 1 ||
|
||||
result->flags != 0 ||
|
||||
result->elemtype != INT2OID)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
||||
errmsg("invalid int2vector data")));
|
||||
PG_RETURN_POINTER(result);
|
||||
}
|
||||
|
||||
@@ -194,14 +234,7 @@ int2vectorrecv(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
int2vectorsend(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int16 *int2Array = (int16 *) PG_GETARG_POINTER(0);
|
||||
StringInfoData buf;
|
||||
int slot;
|
||||
|
||||
pq_begintypsend(&buf);
|
||||
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
|
||||
pq_sendint(&buf, int2Array[slot], sizeof(int16));
|
||||
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
||||
return array_send(fcinfo);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -211,10 +244,12 @@ int2vectorsend(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
int2vectoreq(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int16 *arg1 = (int16 *) PG_GETARG_POINTER(0);
|
||||
int16 *arg2 = (int16 *) PG_GETARG_POINTER(1);
|
||||
int2vector *a = (int2vector *) PG_GETARG_POINTER(0);
|
||||
int2vector *b = (int2vector *) PG_GETARG_POINTER(1);
|
||||
|
||||
PG_RETURN_BOOL(memcmp(arg1, arg2, INDEX_MAX_KEYS * sizeof(int16)) == 0);
|
||||
if (a->dim1 != b->dim1)
|
||||
PG_RETURN_BOOL(false);
|
||||
PG_RETURN_BOOL(memcmp(a->values, b->values, a->dim1 * sizeof(int2)) == 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -8,20 +8,24 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/oid.c,v 1.61 2005/02/11 04:08:58 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/oid.c,v 1.62 2005/03/29 00:17:08 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "catalog/pg_type.h"
|
||||
#include "libpq/pqformat.h"
|
||||
#include "utils/array.h"
|
||||
#include "utils/builtins.h"
|
||||
|
||||
|
||||
#define OidVectorSize(n) (offsetof(oidvector, values) + (n) * sizeof(Oid))
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* USER I/O ROUTINES *
|
||||
*****************************************************************************/
|
||||
@@ -151,27 +155,54 @@ oidsend(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
||||
}
|
||||
|
||||
/*
|
||||
* construct oidvector given a raw array of Oids
|
||||
*
|
||||
* If oids is NULL then caller must fill values[] afterward
|
||||
*/
|
||||
oidvector *
|
||||
buildoidvector(const Oid *oids, int n)
|
||||
{
|
||||
oidvector *result;
|
||||
|
||||
result = (oidvector *) palloc0(OidVectorSize(n));
|
||||
|
||||
if (n > 0 && oids)
|
||||
memcpy(result->values, oids, n * sizeof(Oid));
|
||||
|
||||
/*
|
||||
* Attach standard array header. For historical reasons, we set the
|
||||
* index lower bound to 0 not 1.
|
||||
*/
|
||||
result->size = OidVectorSize(n);
|
||||
result->ndim = 1;
|
||||
result->flags = 0;
|
||||
result->elemtype = OIDOID;
|
||||
result->dim1 = n;
|
||||
result->lbound1 = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* oidvectorin - converts "num num ..." to internal form
|
||||
*
|
||||
* Note:
|
||||
* Fills any unsupplied positions with InvalidOid.
|
||||
*/
|
||||
Datum
|
||||
oidvectorin(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *oidString = PG_GETARG_CSTRING(0);
|
||||
Oid *result = (Oid *) palloc(sizeof(Oid[INDEX_MAX_KEYS]));
|
||||
int slot;
|
||||
oidvector *result;
|
||||
int n;
|
||||
|
||||
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
|
||||
result = (oidvector *) palloc0(OidVectorSize(FUNC_MAX_ARGS));
|
||||
|
||||
for (n = 0; n < FUNC_MAX_ARGS; n++)
|
||||
{
|
||||
while (*oidString && isspace((unsigned char) *oidString))
|
||||
oidString++;
|
||||
if (*oidString == '\0')
|
||||
break;
|
||||
result[slot] = oidin_subr("oidvectorin", oidString, &oidString);
|
||||
result->values[n] = oidin_subr("oidvectorin", oidString, &oidString);
|
||||
}
|
||||
while (*oidString && isspace((unsigned char) *oidString))
|
||||
oidString++;
|
||||
@@ -179,8 +210,13 @@ oidvectorin(PG_FUNCTION_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("oidvector has too many elements")));
|
||||
while (slot < INDEX_MAX_KEYS)
|
||||
result[slot++] = InvalidOid;
|
||||
|
||||
result->size = OidVectorSize(n);
|
||||
result->ndim = 1;
|
||||
result->flags = 0;
|
||||
result->elemtype = OIDOID;
|
||||
result->dim1 = n;
|
||||
result->lbound1 = 0;
|
||||
|
||||
PG_RETURN_POINTER(result);
|
||||
}
|
||||
@@ -191,24 +227,19 @@ oidvectorin(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
oidvectorout(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid *oidArray = (Oid *) PG_GETARG_POINTER(0);
|
||||
oidvector *oidArray = (oidvector *) PG_GETARG_POINTER(0);
|
||||
int num,
|
||||
maxnum;
|
||||
nnums = oidArray->dim1;
|
||||
char *rp;
|
||||
char *result;
|
||||
|
||||
/* find last non-zero value in vector */
|
||||
for (maxnum = INDEX_MAX_KEYS - 1; maxnum >= 0; maxnum--)
|
||||
if (oidArray[maxnum] != 0)
|
||||
break;
|
||||
|
||||
/* assumes sign, 10 digits, ' ' */
|
||||
rp = result = (char *) palloc((maxnum + 1) * 12 + 1);
|
||||
for (num = 0; num <= maxnum; num++)
|
||||
rp = result = (char *) palloc(nnums * 12 + 1);
|
||||
for (num = 0; num < nnums; num++)
|
||||
{
|
||||
if (num != 0)
|
||||
*rp++ = ' ';
|
||||
sprintf(rp, "%u", oidArray[num]);
|
||||
sprintf(rp, "%u", oidArray->values[num]);
|
||||
while (*++rp != '\0')
|
||||
;
|
||||
}
|
||||
@@ -223,11 +254,19 @@ Datum
|
||||
oidvectorrecv(PG_FUNCTION_ARGS)
|
||||
{
|
||||
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
|
||||
Oid *result = (Oid *) palloc(sizeof(Oid[INDEX_MAX_KEYS]));
|
||||
int slot;
|
||||
oidvector *result;
|
||||
|
||||
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
|
||||
result[slot] = (Oid) pq_getmsgint(buf, sizeof(Oid));
|
||||
result = (oidvector *)
|
||||
DatumGetPointer(DirectFunctionCall2(array_recv,
|
||||
PointerGetDatum(buf),
|
||||
ObjectIdGetDatum(OIDOID)));
|
||||
/* sanity checks: oidvector must be 1-D, no nulls */
|
||||
if (result->ndim != 1 ||
|
||||
result->flags != 0 ||
|
||||
result->elemtype != OIDOID)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
||||
errmsg("invalid oidvector data")));
|
||||
PG_RETURN_POINTER(result);
|
||||
}
|
||||
|
||||
@@ -237,14 +276,7 @@ oidvectorrecv(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
oidvectorsend(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid *oidArray = (Oid *) PG_GETARG_POINTER(0);
|
||||
StringInfoData buf;
|
||||
int slot;
|
||||
|
||||
pq_begintypsend(&buf);
|
||||
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
|
||||
pq_sendint(&buf, oidArray[slot], sizeof(Oid));
|
||||
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
|
||||
return array_send(fcinfo);
|
||||
}
|
||||
|
||||
|
||||
@@ -327,71 +359,49 @@ oidsmaller(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
oidvectoreq(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid *arg1 = (Oid *) PG_GETARG_POINTER(0);
|
||||
Oid *arg2 = (Oid *) PG_GETARG_POINTER(1);
|
||||
int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
|
||||
|
||||
PG_RETURN_BOOL(memcmp(arg1, arg2, INDEX_MAX_KEYS * sizeof(Oid)) == 0);
|
||||
PG_RETURN_BOOL(cmp == 0);
|
||||
}
|
||||
|
||||
Datum
|
||||
oidvectorne(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid *arg1 = (Oid *) PG_GETARG_POINTER(0);
|
||||
Oid *arg2 = (Oid *) PG_GETARG_POINTER(1);
|
||||
int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
|
||||
|
||||
PG_RETURN_BOOL(memcmp(arg1, arg2, INDEX_MAX_KEYS * sizeof(Oid)) != 0);
|
||||
PG_RETURN_BOOL(cmp != 0);
|
||||
}
|
||||
|
||||
Datum
|
||||
oidvectorlt(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid *arg1 = (Oid *) PG_GETARG_POINTER(0);
|
||||
Oid *arg2 = (Oid *) PG_GETARG_POINTER(1);
|
||||
int i;
|
||||
int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
|
||||
|
||||
for (i = 0; i < INDEX_MAX_KEYS; i++)
|
||||
if (arg1[i] != arg2[i])
|
||||
PG_RETURN_BOOL(arg1[i] < arg2[i]);
|
||||
PG_RETURN_BOOL(false);
|
||||
PG_RETURN_BOOL(cmp < 0);
|
||||
}
|
||||
|
||||
Datum
|
||||
oidvectorle(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid *arg1 = (Oid *) PG_GETARG_POINTER(0);
|
||||
Oid *arg2 = (Oid *) PG_GETARG_POINTER(1);
|
||||
int i;
|
||||
int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
|
||||
|
||||
for (i = 0; i < INDEX_MAX_KEYS; i++)
|
||||
if (arg1[i] != arg2[i])
|
||||
PG_RETURN_BOOL(arg1[i] <= arg2[i]);
|
||||
PG_RETURN_BOOL(true);
|
||||
PG_RETURN_BOOL(cmp <= 0);
|
||||
}
|
||||
|
||||
Datum
|
||||
oidvectorge(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid *arg1 = (Oid *) PG_GETARG_POINTER(0);
|
||||
Oid *arg2 = (Oid *) PG_GETARG_POINTER(1);
|
||||
int i;
|
||||
int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
|
||||
|
||||
for (i = 0; i < INDEX_MAX_KEYS; i++)
|
||||
if (arg1[i] != arg2[i])
|
||||
PG_RETURN_BOOL(arg1[i] >= arg2[i]);
|
||||
PG_RETURN_BOOL(true);
|
||||
PG_RETURN_BOOL(cmp >= 0);
|
||||
}
|
||||
|
||||
Datum
|
||||
oidvectorgt(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid *arg1 = (Oid *) PG_GETARG_POINTER(0);
|
||||
Oid *arg2 = (Oid *) PG_GETARG_POINTER(1);
|
||||
int i;
|
||||
int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
|
||||
|
||||
for (i = 0; i < INDEX_MAX_KEYS; i++)
|
||||
if (arg1[i] != arg2[i])
|
||||
PG_RETURN_BOOL(arg1[i] > arg2[i]);
|
||||
PG_RETURN_BOOL(false);
|
||||
PG_RETURN_BOOL(cmp > 0);
|
||||
}
|
||||
|
||||
Datum
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/regproc.c,v 1.92 2004/12/31 22:01:22 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/regproc.c,v 1.93 2005/03/29 00:17:08 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -98,7 +98,7 @@ regprocin(PG_FUNCTION_ARGS)
|
||||
CStringGetDatum(pro_name_or_oid));
|
||||
|
||||
hdesc = heap_openr(ProcedureRelationName, AccessShareLock);
|
||||
sysscan = systable_beginscan(hdesc, ProcedureNameNspIndex, true,
|
||||
sysscan = systable_beginscan(hdesc, ProcedureNameArgsNspIndex, true,
|
||||
SnapshotNow, 1, skey);
|
||||
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(sysscan)))
|
||||
@@ -336,7 +336,7 @@ format_procedure(Oid procedure_oid)
|
||||
quote_qualified_identifier(nspname, proname));
|
||||
for (i = 0; i < nargs; i++)
|
||||
{
|
||||
Oid thisargtype = procform->proargtypes[i];
|
||||
Oid thisargtype = procform->proargtypes.values[i];
|
||||
|
||||
if (i > 0)
|
||||
appendStringInfoChar(&buf, ',');
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* back to source text
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.188 2005/01/13 17:19:10 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.189 2005/03/29 00:17:08 tgl Exp $
|
||||
*
|
||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||
*
|
||||
@@ -553,9 +553,10 @@ pg_get_triggerdef(PG_FUNCTION_ARGS)
|
||||
char *p;
|
||||
int i;
|
||||
|
||||
val = (bytea *) fastgetattr(ht_trig,
|
||||
Anum_pg_trigger_tgargs,
|
||||
tgrel->rd_att, &isnull);
|
||||
val = (bytea *)
|
||||
DatumGetPointer(fastgetattr(ht_trig,
|
||||
Anum_pg_trigger_tgargs,
|
||||
tgrel->rd_att, &isnull));
|
||||
if (isnull)
|
||||
elog(ERROR, "tgargs is null for trigger %u", trigid);
|
||||
p = (char *) VARDATA(val);
|
||||
@@ -637,6 +638,9 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, int prettyFlags)
|
||||
Oid indrelid;
|
||||
int keyno;
|
||||
Oid keycoltype;
|
||||
Datum indclassDatum;
|
||||
bool isnull;
|
||||
oidvector *indclass;
|
||||
StringInfoData buf;
|
||||
char *str;
|
||||
char *sep;
|
||||
@@ -654,6 +658,12 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, int prettyFlags)
|
||||
indrelid = idxrec->indrelid;
|
||||
Assert(indexrelid == idxrec->indexrelid);
|
||||
|
||||
/* Must get indclass the hard way */
|
||||
indclassDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
|
||||
Anum_pg_index_indclass, &isnull);
|
||||
Assert(!isnull);
|
||||
indclass = (oidvector *) DatumGetPointer(indclassDatum);
|
||||
|
||||
/*
|
||||
* Fetch the pg_class tuple of the index relation
|
||||
*/
|
||||
@@ -720,7 +730,7 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, int prettyFlags)
|
||||
sep = "";
|
||||
for (keyno = 0; keyno < idxrec->indnatts; keyno++)
|
||||
{
|
||||
AttrNumber attnum = idxrec->indkey[keyno];
|
||||
AttrNumber attnum = idxrec->indkey.values[keyno];
|
||||
|
||||
if (!colno)
|
||||
appendStringInfo(&buf, sep);
|
||||
@@ -764,7 +774,7 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, int prettyFlags)
|
||||
* Add the operator class name
|
||||
*/
|
||||
if (!colno)
|
||||
get_opclass_name(idxrec->indclass[keyno], keycoltype,
|
||||
get_opclass_name(indclass->values[keyno], keycoltype,
|
||||
&buf);
|
||||
}
|
||||
|
||||
@@ -3537,7 +3547,10 @@ get_func_expr(FuncExpr *expr, deparse_context *context,
|
||||
nargs = 0;
|
||||
foreach(l, expr->args)
|
||||
{
|
||||
Assert(nargs < FUNC_MAX_ARGS);
|
||||
if (nargs >= FUNC_MAX_ARGS)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
|
||||
errmsg("too many arguments")));
|
||||
argtypes[nargs] = exprType((Node *) lfirst(l));
|
||||
nargs++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user