aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/oid.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-03-29 00:17:27 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-03-29 00:17:27 +0000
commit70c9763d4815ac847f0f7694f43eb6a59a236868 (patch)
tree7d8aa05f668f1ef7809ff521b6c1e12d31125fd7 /src/backend/utils/adt/oid.c
parent119191609c507528b20d74c59be69f2129127575 (diff)
downloadpostgresql-70c9763d4815ac847f0f7694f43eb6a59a236868.tar.gz
postgresql-70c9763d4815ac847f0f7694f43eb6a59a236868.zip
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.
Diffstat (limited to 'src/backend/utils/adt/oid.c')
-rw-r--r--src/backend/utils/adt/oid.c154
1 files changed, 82 insertions, 72 deletions
diff --git a/src/backend/utils/adt/oid.c b/src/backend/utils/adt/oid.c
index ababe641b21..4329f07b830 100644
--- a/src/backend/utils/adt/oid.c
+++ b/src/backend/utils/adt/oid.c
@@ -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;
-
- for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
- result[slot] = (Oid) pq_getmsgint(buf, sizeof(Oid));
+ oidvector *result;
+
+ 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;
-
- for (i = 0; i < INDEX_MAX_KEYS; i++)
- if (arg1[i] != arg2[i])
- PG_RETURN_BOOL(arg1[i] < arg2[i]);
- PG_RETURN_BOOL(false);
+ int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
+
+ 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;
-
- for (i = 0; i < INDEX_MAX_KEYS; i++)
- if (arg1[i] != arg2[i])
- PG_RETURN_BOOL(arg1[i] <= arg2[i]);
- PG_RETURN_BOOL(true);
+ int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
+
+ 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;
-
- for (i = 0; i < INDEX_MAX_KEYS; i++)
- if (arg1[i] != arg2[i])
- PG_RETURN_BOOL(arg1[i] >= arg2[i]);
- PG_RETURN_BOOL(true);
+ int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
+
+ 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;
-
- for (i = 0; i < INDEX_MAX_KEYS; i++)
- if (arg1[i] != arg2[i])
- PG_RETURN_BOOL(arg1[i] > arg2[i]);
- PG_RETURN_BOOL(false);
+ int32 cmp = DatumGetInt32(btoidvectorcmp(fcinfo));
+
+ PG_RETURN_BOOL(cmp > 0);
}
Datum