Skip to content

Commit fe2e206

Browse files
committed
Inline the fast path of plpgsql's exec_cast_value().
In the common case where this function isn't actually asked to perform any type conversion, there's nothing it has to do beyond comparing the arguments. Arrange for that part to be inlined into callers, with the slower path remaining out-of-line. This seems to be good for several percent speedup on simple cases, with only minimal code bloat. Amit Khandekar Discussion: https://postgr.es/m/CAJ3gD9eBNrmUD7WBBLG8ohaZ485H9y+4eihQTgr+K8Lhka3vcQ@mail.gmail.com
1 parent 90b2d8c commit fe2e206

File tree

1 file changed

+43
-22
lines changed

1 file changed

+43
-22
lines changed

src/pl/plpgsql/src/pl_exec.c

+43-22
Original file line numberDiff line numberDiff line change
@@ -417,10 +417,14 @@ static void instantiate_empty_record_variable(PLpgSQL_execstate *estate,
417417
PLpgSQL_rec *rec);
418418
static char *convert_value_to_string(PLpgSQL_execstate *estate,
419419
Datum value, Oid valtype);
420-
static Datum exec_cast_value(PLpgSQL_execstate *estate,
421-
Datum value, bool *isnull,
422-
Oid valtype, int32 valtypmod,
423-
Oid reqtype, int32 reqtypmod);
420+
static inline Datum exec_cast_value(PLpgSQL_execstate *estate,
421+
Datum value, bool *isnull,
422+
Oid valtype, int32 valtypmod,
423+
Oid reqtype, int32 reqtypmod);
424+
static Datum do_cast_value(PLpgSQL_execstate *estate,
425+
Datum value, bool *isnull,
426+
Oid valtype, int32 valtypmod,
427+
Oid reqtype, int32 reqtypmod);
424428
static plpgsql_CastHashEntry *get_cast_hashentry(PLpgSQL_execstate *estate,
425429
Oid srctype, int32 srctypmod,
426430
Oid dsttype, int32 dsttypmod);
@@ -7825,7 +7829,7 @@ convert_value_to_string(PLpgSQL_execstate *estate, Datum value, Oid valtype)
78257829
* done with the result.
78267830
* ----------
78277831
*/
7828-
static Datum
7832+
static inline Datum
78297833
exec_cast_value(PLpgSQL_execstate *estate,
78307834
Datum value, bool *isnull,
78317835
Oid valtype, int32 valtypmod,
@@ -7837,30 +7841,47 @@ exec_cast_value(PLpgSQL_execstate *estate,
78377841
if (valtype != reqtype ||
78387842
(valtypmod != reqtypmod && reqtypmod != -1))
78397843
{
7840-
plpgsql_CastHashEntry *cast_entry;
7844+
/* We keep the slow path out-of-line. */
7845+
value = do_cast_value(estate, value, isnull, valtype, valtypmod,
7846+
reqtype, reqtypmod);
7847+
}
78417848

7842-
cast_entry = get_cast_hashentry(estate,
7843-
valtype, valtypmod,
7844-
reqtype, reqtypmod);
7845-
if (cast_entry)
7846-
{
7847-
ExprContext *econtext = estate->eval_econtext;
7848-
MemoryContext oldcontext;
7849+
return value;
7850+
}
78497851

7850-
oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
7852+
/* ----------
7853+
* do_cast_value Slow path for exec_cast_value.
7854+
* ----------
7855+
*/
7856+
static Datum
7857+
do_cast_value(PLpgSQL_execstate *estate,
7858+
Datum value, bool *isnull,
7859+
Oid valtype, int32 valtypmod,
7860+
Oid reqtype, int32 reqtypmod)
7861+
{
7862+
plpgsql_CastHashEntry *cast_entry;
78517863

7852-
econtext->caseValue_datum = value;
7853-
econtext->caseValue_isNull = *isnull;
7864+
cast_entry = get_cast_hashentry(estate,
7865+
valtype, valtypmod,
7866+
reqtype, reqtypmod);
7867+
if (cast_entry)
7868+
{
7869+
ExprContext *econtext = estate->eval_econtext;
7870+
MemoryContext oldcontext;
78547871

7855-
cast_entry->cast_in_use = true;
7872+
oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
78567873

7857-
value = ExecEvalExpr(cast_entry->cast_exprstate, econtext,
7858-
isnull);
7874+
econtext->caseValue_datum = value;
7875+
econtext->caseValue_isNull = *isnull;
78597876

7860-
cast_entry->cast_in_use = false;
7877+
cast_entry->cast_in_use = true;
78617878

7862-
MemoryContextSwitchTo(oldcontext);
7863-
}
7879+
value = ExecEvalExpr(cast_entry->cast_exprstate, econtext,
7880+
isnull);
7881+
7882+
cast_entry->cast_in_use = false;
7883+
7884+
MemoryContextSwitchTo(oldcontext);
78647885
}
78657886

78667887
return value;

0 commit comments

Comments
 (0)