1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-22 12:22:45 +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:
Tom Lane
2005-03-29 00:17:27 +00:00
parent 119191609c
commit 70c9763d48
61 changed files with 819 additions and 581 deletions

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.123 2005/01/27 23:23:51 neilc Exp $
* $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.124 2005/03/29 00:16:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -78,7 +78,7 @@ ProcedureCreate(const char *procedureName,
char nulls[Natts_pg_proc];
Datum values[Natts_pg_proc];
char replaces[Natts_pg_proc];
Oid typev[FUNC_MAX_ARGS];
oidvector *proargtypes;
Datum namesarray;
Oid relid;
NameData procname;
@@ -125,10 +125,9 @@ ProcedureCreate(const char *procedureName,
errdetail("A function returning \"anyarray\" or \"anyelement\" must have at least one argument of either type.")));
}
/* Make sure we have a zero-padded param type array */
MemSet(typev, 0, FUNC_MAX_ARGS * sizeof(Oid));
if (parameterCount > 0)
memcpy(typev, parameterTypes, parameterCount * sizeof(Oid));
/* Convert param types to oidvector */
/* (Probably we should make caller pass it this way to start with) */
proargtypes = buildoidvector(parameterTypes, parameterCount);
/* Process param names, if given */
namesarray = create_parameternames_array(parameterCount, parameterNames);
@@ -137,13 +136,13 @@ ProcedureCreate(const char *procedureName,
* don't allow functions of complex types that have the same name as
* existing attributes of the type
*/
if (parameterCount == 1 && OidIsValid(typev[0]) &&
(relid = typeidTypeRelid(typev[0])) != InvalidOid &&
if (parameterCount == 1 && OidIsValid(parameterTypes[0]) &&
(relid = typeidTypeRelid(parameterTypes[0])) != InvalidOid &&
get_attnum(relid, procedureName) != InvalidAttrNumber)
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_COLUMN),
errmsg("\"%s\" is already an attribute of type %s",
procedureName, format_type_be(typev[0]))));
procedureName, format_type_be(parameterTypes[0]))));
/*
* All seems OK; prepare the data to be inserted into pg_proc.
@@ -162,15 +161,15 @@ ProcedureCreate(const char *procedureName,
values[i++] = ObjectIdGetDatum(procNamespace); /* pronamespace */
values[i++] = Int32GetDatum(GetUserId()); /* proowner */
values[i++] = ObjectIdGetDatum(languageObjectId); /* prolang */
values[i++] = BoolGetDatum(isAgg); /* proisagg */
values[i++] = BoolGetDatum(isAgg); /* proisagg */
values[i++] = BoolGetDatum(security_definer); /* prosecdef */
values[i++] = BoolGetDatum(isStrict); /* proisstrict */
values[i++] = BoolGetDatum(returnsSet); /* proretset */
values[i++] = CharGetDatum(volatility); /* provolatile */
values[i++] = UInt16GetDatum(parameterCount); /* pronargs */
values[i++] = ObjectIdGetDatum(returnType); /* prorettype */
values[i++] = PointerGetDatum(typev); /* proargtypes */
values[i++] = namesarray; /* proargnames */
values[i++] = PointerGetDatum(proargtypes); /* proargtypes */
values[i++] = namesarray; /* proargnames */
if (namesarray == PointerGetDatum(NULL))
nulls[Anum_pg_proc_proargnames - 1] = 'n';
values[i++] = DirectFunctionCall1(textin, /* prosrc */
@@ -183,11 +182,11 @@ ProcedureCreate(const char *procedureName,
tupDesc = RelationGetDescr(rel);
/* Check for pre-existing definition */
oldtup = SearchSysCache(PROCNAMENSP,
oldtup = SearchSysCache(PROCNAMEARGSNSP,
PointerGetDatum(procedureName),
UInt16GetDatum(parameterCount),
PointerGetDatum(typev),
ObjectIdGetDatum(procNamespace));
PointerGetDatum(proargtypes),
ObjectIdGetDatum(procNamespace),
0);
if (HeapTupleIsValid(oldtup))
{
@@ -290,7 +289,7 @@ ProcedureCreate(const char *procedureName,
for (i = 0; i < parameterCount; i++)
{
referenced.classId = RelOid_pg_type;
referenced.objectId = typev[i];
referenced.objectId = parameterTypes[i];
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
@@ -492,16 +491,16 @@ fmgr_sql_validator(PG_FUNCTION_ARGS)
haspolyarg = false;
for (i = 0; i < proc->pronargs; i++)
{
if (get_typtype(proc->proargtypes[i]) == 'p')
if (get_typtype(proc->proargtypes.values[i]) == 'p')
{
if (proc->proargtypes[i] == ANYARRAYOID ||
proc->proargtypes[i] == ANYELEMENTOID)
if (proc->proargtypes.values[i] == ANYARRAYOID ||
proc->proargtypes.values[i] == ANYELEMENTOID)
haspolyarg = true;
else
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("SQL functions cannot have arguments of type %s",
format_type_be(proc->proargtypes[i]))));
format_type_be(proc->proargtypes.values[i]))));
}
}
@@ -534,7 +533,7 @@ fmgr_sql_validator(PG_FUNCTION_ARGS)
if (!haspolyarg)
{
querytree_list = pg_parse_and_rewrite(prosrc,
proc->proargtypes,
proc->proargtypes.values,
proc->pronargs);
(void) check_sql_fn_retval(proc->prorettype, functyptype,
querytree_list, NULL);