diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2005-03-29 00:17:27 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2005-03-29 00:17:27 +0000 |
commit | 70c9763d4815ac847f0f7694f43eb6a59a236868 (patch) | |
tree | 7d8aa05f668f1ef7809ff521b6c1e12d31125fd7 /src/backend/commands/trigger.c | |
parent | 119191609c507528b20d74c59be69f2129127575 (diff) | |
download | postgresql-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/commands/trigger.c')
-rw-r--r-- | src/backend/commands/trigger.c | 47 |
1 files changed, 35 insertions, 12 deletions
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 277d8744488..a9e8bc9e7f1 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.181 2005/03/25 21:57:58 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.182 2005/03/29 00:16:57 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -67,7 +67,7 @@ Oid CreateTrigger(CreateTrigStmt *stmt, bool forConstraint) { int16 tgtype; - int16 tgattr[FUNC_MAX_ARGS]; + int2vector *tgattr; Datum values[Natts_pg_trigger]; char nulls[Natts_pg_trigger]; Relation rel; @@ -77,7 +77,7 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint) ScanKeyData key; Relation pgrel; HeapTuple tuple; - Oid fargtypes[FUNC_MAX_ARGS]; + Oid fargtypes[1]; /* dummy */ Oid funcoid; Oid funcrettype; Oid trigoid; @@ -275,7 +275,6 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint) /* * Find and validate the trigger function. */ - MemSet(fargtypes, 0, FUNC_MAX_ARGS * sizeof(Oid)); funcoid = LookupFuncName(stmt->funcname, 0, fargtypes, false); funcrettype = get_func_rettype(funcoid); if (funcrettype != TRIGGEROID) @@ -359,7 +358,8 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint) values[Anum_pg_trigger_tgargs - 1] = DirectFunctionCall1(byteain, CStringGetDatum("")); } - MemSet(tgattr, 0, FUNC_MAX_ARGS * sizeof(int16)); + /* tgattr is currently always a zero-length array */ + tgattr = buildint2vector(NULL, 0); values[Anum_pg_trigger_tgattr - 1] = PointerGetDatum(tgattr); tuple = heap_formtuple(tgrel->rd_att, values, nulls); @@ -774,8 +774,16 @@ RelationBuildTriggers(Relation relation) build->tgdeferrable = pg_trigger->tgdeferrable; build->tginitdeferred = pg_trigger->tginitdeferred; build->tgnargs = pg_trigger->tgnargs; - memcpy(build->tgattr, &(pg_trigger->tgattr), - FUNC_MAX_ARGS * sizeof(int16)); + /* tgattr is first var-width field, so OK to access directly */ + build->tgnattr = pg_trigger->tgattr.dim1; + if (build->tgnattr > 0) + { + build->tgattr = (int2 *) palloc(build->tgnattr * sizeof(int2)); + memcpy(build->tgattr, &(pg_trigger->tgattr.values), + build->tgnattr * sizeof(int2)); + } + else + build->tgattr = NULL; if (build->tgnargs > 0) { bytea *val; @@ -783,9 +791,10 @@ RelationBuildTriggers(Relation relation) char *p; int i; - val = (bytea *) fastgetattr(htup, - Anum_pg_trigger_tgargs, - tgrel->rd_att, &isnull); + val = (bytea *) + DatumGetPointer(fastgetattr(htup, + Anum_pg_trigger_tgargs, + tgrel->rd_att, &isnull)); if (isnull) elog(ERROR, "tgargs is null in trigger for relation \"%s\"", RelationGetRelationName(relation)); @@ -928,6 +937,15 @@ CopyTriggerDesc(TriggerDesc *trigdesc) for (i = 0; i < trigdesc->numtriggers; i++) { trigger->tgname = pstrdup(trigger->tgname); + if (trigger->tgnattr > 0) + { + int2 *newattr; + + newattr = (int2 *) palloc(trigger->tgnattr * sizeof(int2)); + memcpy(newattr, trigger->tgattr, + trigger->tgnattr * sizeof(int2)); + trigger->tgattr = newattr; + } if (trigger->tgnargs > 0) { char **newargs; @@ -1031,6 +1049,8 @@ FreeTriggerDesc(TriggerDesc *trigdesc) for (i = 0; i < trigdesc->numtriggers; i++) { pfree(trigger->tgname); + if (trigger->tgnattr > 0) + pfree(trigger->tgattr); if (trigger->tgnargs > 0) { while (--(trigger->tgnargs) >= 0) @@ -1092,8 +1112,11 @@ equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2) return false; if (trig1->tgnargs != trig2->tgnargs) return false; - if (memcmp(trig1->tgattr, trig2->tgattr, - sizeof(trig1->tgattr)) != 0) + if (trig1->tgnattr != trig2->tgnattr) + return false; + if (trig1->tgnattr > 0 && + memcmp(trig1->tgattr, trig2->tgattr, + trig1->tgnattr * sizeof(int2)) != 0) return false; for (j = 0; j < trig1->tgnargs; j++) if (strcmp(trig1->tgargs[j], trig2->tgargs[j]) != 0) |