Skip to content

Commit fd333bc

Browse files
committed
Speed up plpgsql trigger startup by introducing "promises".
Over the years we've accreted quite a few special variables that are predefined in plpgsql trigger functions. The cost of initializing these variables to their defined values turns out to be a significant part of the runtime of simple triggers; but, undoubtedly, most real-world triggers never examine the values of most of these variables. To improve matters, invent the notion of a variable that has a "promise" attached to it, specifying which of the predetermined values should be assigned to the variable if anything ever reads it. This eliminates all the unneeded startup overhead, in return for a small penalty on accesses to these variables. Tom Lane, reviewed by Pavel Stehule Discussion: https://postgr.es/m/11986.1514407114@sss.pgh.pa.us
1 parent 40301c1 commit fd333bc

File tree

5 files changed

+306
-142
lines changed

5 files changed

+306
-142
lines changed

src/pl/plpgsql/src/pl_comp.c

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -607,79 +607,99 @@ do_compile(FunctionCallInfo fcinfo,
607607
-1,
608608
InvalidOid),
609609
true);
610-
function->tg_name_varno = var->dno;
610+
Assert(var->dtype == PLPGSQL_DTYPE_VAR);
611+
var->dtype = PLPGSQL_DTYPE_PROMISE;
612+
((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_NAME;
611613

612614
/* Add the variable tg_when */
613615
var = plpgsql_build_variable("tg_when", 0,
614616
plpgsql_build_datatype(TEXTOID,
615617
-1,
616618
function->fn_input_collation),
617619
true);
618-
function->tg_when_varno = var->dno;
620+
Assert(var->dtype == PLPGSQL_DTYPE_VAR);
621+
var->dtype = PLPGSQL_DTYPE_PROMISE;
622+
((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_WHEN;
619623

620624
/* Add the variable tg_level */
621625
var = plpgsql_build_variable("tg_level", 0,
622626
plpgsql_build_datatype(TEXTOID,
623627
-1,
624628
function->fn_input_collation),
625629
true);
626-
function->tg_level_varno = var->dno;
630+
Assert(var->dtype == PLPGSQL_DTYPE_VAR);
631+
var->dtype = PLPGSQL_DTYPE_PROMISE;
632+
((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_LEVEL;
627633

628634
/* Add the variable tg_op */
629635
var = plpgsql_build_variable("tg_op", 0,
630636
plpgsql_build_datatype(TEXTOID,
631637
-1,
632638
function->fn_input_collation),
633639
true);
634-
function->tg_op_varno = var->dno;
640+
Assert(var->dtype == PLPGSQL_DTYPE_VAR);
641+
var->dtype = PLPGSQL_DTYPE_PROMISE;
642+
((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_OP;
635643

636644
/* Add the variable tg_relid */
637645
var = plpgsql_build_variable("tg_relid", 0,
638646
plpgsql_build_datatype(OIDOID,
639647
-1,
640648
InvalidOid),
641649
true);
642-
function->tg_relid_varno = var->dno;
650+
Assert(var->dtype == PLPGSQL_DTYPE_VAR);
651+
var->dtype = PLPGSQL_DTYPE_PROMISE;
652+
((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_RELID;
643653

644654
/* Add the variable tg_relname */
645655
var = plpgsql_build_variable("tg_relname", 0,
646656
plpgsql_build_datatype(NAMEOID,
647657
-1,
648658
InvalidOid),
649659
true);
650-
function->tg_relname_varno = var->dno;
660+
Assert(var->dtype == PLPGSQL_DTYPE_VAR);
661+
var->dtype = PLPGSQL_DTYPE_PROMISE;
662+
((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_TABLE_NAME;
651663

652664
/* tg_table_name is now preferred to tg_relname */
653665
var = plpgsql_build_variable("tg_table_name", 0,
654666
plpgsql_build_datatype(NAMEOID,
655667
-1,
656668
InvalidOid),
657669
true);
658-
function->tg_table_name_varno = var->dno;
670+
Assert(var->dtype == PLPGSQL_DTYPE_VAR);
671+
var->dtype = PLPGSQL_DTYPE_PROMISE;
672+
((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_TABLE_NAME;
659673

660674
/* add the variable tg_table_schema */
661675
var = plpgsql_build_variable("tg_table_schema", 0,
662676
plpgsql_build_datatype(NAMEOID,
663677
-1,
664678
InvalidOid),
665679
true);
666-
function->tg_table_schema_varno = var->dno;
680+
Assert(var->dtype == PLPGSQL_DTYPE_VAR);
681+
var->dtype = PLPGSQL_DTYPE_PROMISE;
682+
((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_TABLE_SCHEMA;
667683

668684
/* Add the variable tg_nargs */
669685
var = plpgsql_build_variable("tg_nargs", 0,
670686
plpgsql_build_datatype(INT4OID,
671687
-1,
672688
InvalidOid),
673689
true);
674-
function->tg_nargs_varno = var->dno;
690+
Assert(var->dtype == PLPGSQL_DTYPE_VAR);
691+
var->dtype = PLPGSQL_DTYPE_PROMISE;
692+
((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_NARGS;
675693

676694
/* Add the variable tg_argv */
677695
var = plpgsql_build_variable("tg_argv", 0,
678696
plpgsql_build_datatype(TEXTARRAYOID,
679697
-1,
680698
function->fn_input_collation),
681699
true);
682-
function->tg_argv_varno = var->dno;
700+
Assert(var->dtype == PLPGSQL_DTYPE_VAR);
701+
var->dtype = PLPGSQL_DTYPE_PROMISE;
702+
((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_ARGV;
683703

684704
break;
685705

@@ -701,15 +721,19 @@ do_compile(FunctionCallInfo fcinfo,
701721
-1,
702722
function->fn_input_collation),
703723
true);
704-
function->tg_event_varno = var->dno;
724+
Assert(var->dtype == PLPGSQL_DTYPE_VAR);
725+
var->dtype = PLPGSQL_DTYPE_PROMISE;
726+
((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_EVENT;
705727

706728
/* Add the variable tg_tag */
707729
var = plpgsql_build_variable("tg_tag", 0,
708730
plpgsql_build_datatype(TEXTOID,
709731
-1,
710732
function->fn_input_collation),
711733
true);
712-
function->tg_tag_varno = var->dno;
734+
Assert(var->dtype == PLPGSQL_DTYPE_VAR);
735+
var->dtype = PLPGSQL_DTYPE_PROMISE;
736+
((PLpgSQL_var *) var)->promise = PLPGSQL_PROMISE_TG_TAG;
713737

714738
break;
715739

@@ -1878,6 +1902,7 @@ build_row_from_vars(PLpgSQL_variable **vars, int numvars)
18781902
switch (var->dtype)
18791903
{
18801904
case PLPGSQL_DTYPE_VAR:
1905+
case PLPGSQL_DTYPE_PROMISE:
18811906
typoid = ((PLpgSQL_var *) var)->datatype->typoid;
18821907
typmod = ((PLpgSQL_var *) var)->datatype->atttypmod;
18831908
typcoll = ((PLpgSQL_var *) var)->datatype->collation;
@@ -2196,6 +2221,7 @@ plpgsql_finish_datums(PLpgSQL_function *function)
21962221
switch (function->datums[i]->dtype)
21972222
{
21982223
case PLPGSQL_DTYPE_VAR:
2224+
case PLPGSQL_DTYPE_PROMISE:
21992225
copiable_size += MAXALIGN(sizeof(PLpgSQL_var));
22002226
break;
22012227
case PLPGSQL_DTYPE_REC:

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy