Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9e3ad1a

Browse files
committed
Use fast path in plpgsql's RETURN/RETURN NEXT in more cases.
exec_stmt_return() and exec_stmt_return_next() have fast-path code forhandling a simple variable reference (i.e. "return var") without goingthrough the full expression evaluation machinery. For some reason,pl_gram.y was under the impression that this fast path only applied forrecord/row variables; but in reality code for handling regular scalarvariables has been there all along. Adjusting the logic to allow thatcode to be used actually results in a net savings of code in pl_gram.y(by eliminating some redundancy), and it buys a measurable though notvery impressive amount of speedup.Noted while fooling with my expanded-array patch, wherein this makes a muchbigger difference because it enables returning an expanded array variablewithout an extra flattening step. But AFAICS this is a win regardless,so commit it separately.
1 parent2c75531 commit9e3ad1a

File tree

2 files changed

+28
-24
lines changed

2 files changed

+28
-24
lines changed

‎src/pl/plpgsql/src/pl_exec.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2452,8 +2452,9 @@ exec_stmt_return(PLpgSQL_execstate *estate, PLpgSQL_stmt_return *stmt)
24522452
estate->retisnull= true;
24532453

24542454
/*
2455-
* This special-case path covers record/row variables in fn_retistuple
2456-
* functions, as well as functions with one or more OUT parameters.
2455+
* Special case path when the RETURN expression is a simple variable
2456+
* reference; in particular, this path is always taken in functions with
2457+
* one or more OUT parameters.
24572458
*/
24582459
if (stmt->retvarno >=0)
24592460
{
@@ -2576,8 +2577,9 @@ exec_stmt_return_next(PLpgSQL_execstate *estate,
25762577
natts=tupdesc->natts;
25772578

25782579
/*
2579-
* This special-case path covers record/row variables in fn_retistuple
2580-
* functions, as well as functions with one or more OUT parameters.
2580+
* Special case path when the RETURN NEXT expression is a simple variable
2581+
* reference; in particular, this path is always taken in functions with
2582+
* one or more OUT parameters.
25812583
*/
25822584
if (stmt->retvarno >=0)
25832585
{

‎src/pl/plpgsql/src/pl_gram.y

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3036,16 +3036,17 @@ make_return_stmt(int location)
30363036
errmsg("RETURN cannot have a parameter in function returning void"),
30373037
parser_errposition(yylloc)));
30383038
}
3039-
else if (plpgsql_curr_compile->fn_retistuple)
3039+
else
30403040
{
30413041
/*
3042-
* We want to special-case simplerow or recordreferences for
3043-
*efficiency.So peek ahead to see if that's what we have.
3042+
* We want to special-case simplevariablereferences for efficiency.
3043+
* So peek ahead to see if that's what we have.
30443044
*/
30453045
inttok = yylex();
30463046

30473047
if (tok == T_DATUM && plpgsql_peek() == ';' &&
3048-
(yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
3048+
(yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_VAR ||
3049+
yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
30493050
yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC))
30503051
{
30513052
new->retvarno = yylval.wdatum.datum->dno;
@@ -3055,19 +3056,16 @@ make_return_stmt(int location)
30553056
}
30563057
else
30573058
{
3058-
/* Not (just) a row/record name, so treat as expression*/
3059+
/*
3060+
* Not (just) a variable name, so treat as expression.
3061+
*
3062+
* Note that a well-formed expression is _required_ here;
3063+
* anything else is a compile-time error.
3064+
*/
30593065
plpgsql_push_back_token(tok);
30603066
new->expr = read_sql_expression(';', ";");
30613067
}
30623068
}
3063-
else
3064-
{
3065-
/*
3066-
* Note that a well-formed expression is _required_ here;
3067-
* anything else is a compile-time error.
3068-
*/
3069-
new->expr = read_sql_expression(';', ";");
3070-
}
30713069

30723070
return (PLpgSQL_stmt *) new;
30733071
}
@@ -3099,16 +3097,17 @@ make_return_next_stmt(int location)
30993097
parser_errposition(yylloc)));
31003098
new->retvarno = plpgsql_curr_compile->out_param_varno;
31013099
}
3102-
else if (plpgsql_curr_compile->fn_retistuple)
3100+
else
31033101
{
31043102
/*
3105-
* We want to special-case simplerow or recordreferences for
3106-
*efficiency.So peek ahead to see if that's what we have.
3103+
* We want to special-case simplevariablereferences for efficiency.
3104+
* So peek ahead to see if that's what we have.
31073105
*/
31083106
inttok = yylex();
31093107

31103108
if (tok == T_DATUM && plpgsql_peek() == ';' &&
3111-
(yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
3109+
(yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_VAR ||
3110+
yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
31123111
yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC))
31133112
{
31143113
new->retvarno = yylval.wdatum.datum->dno;
@@ -3118,13 +3117,16 @@ make_return_next_stmt(int location)
31183117
}
31193118
else
31203119
{
3121-
/* Not (just) a row/record name, so treat as expression*/
3120+
/*
3121+
* Not (just) a variable name, so treat as expression.
3122+
*
3123+
* Note that a well-formed expression is _required_ here;
3124+
* anything else is a compile-time error.
3125+
*/
31223126
plpgsql_push_back_token(tok);
31233127
new->expr = read_sql_expression(';', ";");
31243128
}
31253129
}
3126-
else
3127-
new->expr = read_sql_expression(';', ";");
31283130

31293131
return (PLpgSQL_stmt *) new;
31303132
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp