Skip to content

Commit c51714d

Browse files
committed
Cache last used type oid to do faster variable_insert(), variable_update()
1 parent 8da2d2d commit c51714d

File tree

1 file changed

+49
-21
lines changed

1 file changed

+49
-21
lines changed

pg_variables.c

+49-21
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ static Variable *createVariableInternal(Package *package,
5757
text *name, Oid typid,
5858
bool is_transactional);
5959
static void removePackageInternal(Package *package);
60+
static void resetVariablesCache(bool with_package);
6061

6162
/* Functions to work with transactional objects */
6263
static void createSavepoint(TransObject *object, TransObjectType type);
@@ -99,6 +100,8 @@ static MemoryContext ModuleContext = NULL;
99100
static Package *LastPackage = NULL;
100101
/* Recent variable */
101102
static Variable *LastVariable = NULL;
103+
/* Recent row type id */
104+
static Oid LastTypeId = InvalidOid;
102105

103106

104107
/* This stack contains lists of changed variables and packages per each subxact level */
@@ -291,7 +294,7 @@ variable_insert(PG_FUNCTION_ARGS)
291294

292295
Oid tupType;
293296
int32 tupTypmod;
294-
TupleDesc tupdesc;
297+
TupleDesc tupdesc = NULL;
295298
RecordVar *record;
296299

297300
/* Checks */
@@ -360,23 +363,34 @@ variable_insert(PG_FUNCTION_ARGS)
360363
/* Insert a record */
361364
tupType = HeapTupleHeaderGetTypeId(rec);
362365
tupTypmod = HeapTupleHeaderGetTypMod(rec);
363-
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
364366

365367
record = &(GetActualValue(variable).record);
366368
if (!record->tupdesc)
367369
{
368370
/*
369371
* This is the first record for the var_name. Initialize record.
370372
*/
373+
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
371374
init_record(record, tupdesc, variable);
372375
}
373-
else
376+
else if (LastTypeId == RECORDOID || !OidIsValid(LastTypeId) ||
377+
LastTypeId != tupType)
378+
{
379+
/*
380+
* We need to check attributes of the new row if this is a transient
381+
* record type or if last record has different id.
382+
*/
383+
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
374384
check_attributes(variable, tupdesc);
385+
}
386+
387+
LastTypeId = tupType;
375388

376389
insert_record(variable, rec);
377390

378391
/* Release resources */
379-
ReleaseTupleDesc(tupdesc);
392+
if (tupdesc)
393+
ReleaseTupleDesc(tupdesc);
380394

381395
PG_FREE_IF_COPY(package_name, 0);
382396
PG_FREE_IF_COPY(var_name, 1);
@@ -396,7 +410,6 @@ variable_update(PG_FUNCTION_ARGS)
396410
bool res;
397411
Oid tupType;
398412
int32 tupTypmod;
399-
TupleDesc tupdesc;
400413

401414
/* Checks */
402415
CHECK_ARGS_FOR_NULL();
@@ -447,14 +460,22 @@ variable_update(PG_FUNCTION_ARGS)
447460
/* Update a record */
448461
tupType = HeapTupleHeaderGetTypeId(rec);
449462
tupTypmod = HeapTupleHeaderGetTypMod(rec);
450-
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
451463

452-
check_attributes(variable, tupdesc);
464+
if (LastTypeId == RECORDOID || !OidIsValid(LastTypeId) ||
465+
LastTypeId != tupType)
466+
{
467+
TupleDesc tupdesc = NULL;
468+
469+
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
470+
check_attributes(variable, tupdesc);
471+
ReleaseTupleDesc(tupdesc);
472+
}
473+
474+
LastTypeId = tupType;
475+
453476
res = update_record(variable, rec);
454477

455478
/* Release resources */
456-
ReleaseTupleDesc(tupdesc);
457-
458479
PG_FREE_IF_COPY(package_name, 0);
459480
PG_FREE_IF_COPY(var_name, 1);
460481

@@ -867,8 +888,7 @@ remove_variable(PG_FUNCTION_ARGS)
867888
GetActualState(variable)->is_valid = false;
868889
}
869890

870-
/* Remove variable from cache */
871-
LastVariable = NULL;
891+
resetVariablesCache(false);
872892

873893
PG_FREE_IF_COPY(package_name, 0);
874894
PG_FREE_IF_COPY(var_name, 1);
@@ -904,9 +924,7 @@ remove_package(PG_FUNCTION_ARGS)
904924
errmsg("unrecognized package \"%s\"", key)));
905925
}
906926

907-
/* Remove package and variable from cache */
908-
LastPackage = NULL;
909-
LastVariable = NULL;
927+
resetVariablesCache(true);
910928

911929
PG_FREE_IF_COPY(package_name, 0);
912930
PG_RETURN_VOID();
@@ -934,6 +952,20 @@ removePackageInternal(Package *package)
934952
GetActualState(package)->is_valid = false;
935953
}
936954

955+
/*
956+
* Reset cache variables to their default values. It is necessary to do in case
957+
* of some changes: removing, rollbacking, etc.
958+
*/
959+
static void
960+
resetVariablesCache(bool with_package)
961+
{
962+
/* Remove package and variable from cache */
963+
if (with_package)
964+
LastPackage = NULL;
965+
LastVariable = NULL;
966+
LastTypeId = InvalidOid;
967+
}
968+
937969
/*
938970
* Remove all packages and variables.
939971
* Memory context will be released after committing.
@@ -955,9 +987,7 @@ remove_packages(PG_FUNCTION_ARGS)
955987
removePackageInternal(package);
956988
}
957989

958-
/* Remove package and variable from cache */
959-
LastPackage = NULL;
960-
LastVariable = NULL;
990+
resetVariablesCache(true);
961991

962992
PG_RETURN_VOID();
963993
}
@@ -1632,8 +1662,7 @@ removeObject(TransObject *object, TransObjectType type)
16321662
/* Remove object from hash table */
16331663
hash_search(hash, object->name, HASH_REMOVE, &found);
16341664

1635-
LastPackage = NULL;
1636-
LastVariable = NULL;
1665+
resetVariablesCache(true);
16371666
}
16381667

16391668
/*
@@ -2004,8 +2033,7 @@ processChanges(Action action)
20042033
MemoryContextDelete(ModuleContext);
20052034
packagesHash = NULL;
20062035
ModuleContext = NULL;
2007-
LastPackage = NULL;
2008-
LastVariable = NULL;
2036+
resetVariablesCache(true);
20092037
changesStack = NULL;
20102038
changesStackContext = NULL;
20112039
}

0 commit comments

Comments
 (0)