estate->retisnull = true;
/*
- * This special-case path covers record/row variables in fn_retistuple
- * functions, as well as functions with one or more OUT parameters.
+ * Special case path when the RETURN expression is a simple variable
+ * reference; in particular, this path is always taken in functions with
+ * one or more OUT parameters.
*/
if (stmt->retvarno >= 0)
{
natts = tupdesc->natts;
/*
- * This special-case path covers record/row variables in fn_retistuple
- * functions, as well as functions with one or more OUT parameters.
+ * Special case path when the RETURN NEXT expression is a simple variable
+ * reference; in particular, this path is always taken in functions with
+ * one or more OUT parameters.
*/
if (stmt->retvarno >= 0)
{
errmsg("RETURN cannot have a parameter in function returning void"),
parser_errposition(yylloc)));
}
- else if (plpgsql_curr_compile->fn_retistuple)
+ else
{
/*
- * We want to special-case simple row or record references for
- * efficiency. So peek ahead to see if that's what we have.
+ * We want to special-case simple variable references for efficiency.
+ * So peek ahead to see if that's what we have.
*/
int tok = yylex();
if (tok == T_DATUM && plpgsql_peek() == ';' &&
- (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
+ (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_VAR ||
+ yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC))
{
new->retvarno = yylval.wdatum.datum->dno;
}
else
{
- /* Not (just) a row/record name, so treat as expression */
+ /*
+ * Not (just) a variable name, so treat as expression.
+ *
+ * Note that a well-formed expression is _required_ here;
+ * anything else is a compile-time error.
+ */
plpgsql_push_back_token(tok);
new->expr = read_sql_expression(';', ";");
}
}
- else
- {
- /*
- * Note that a well-formed expression is _required_ here;
- * anything else is a compile-time error.
- */
- new->expr = read_sql_expression(';', ";");
- }
return (PLpgSQL_stmt *) new;
}
parser_errposition(yylloc)));
new->retvarno = plpgsql_curr_compile->out_param_varno;
}
- else if (plpgsql_curr_compile->fn_retistuple)
+ else
{
/*
- * We want to special-case simple row or record references for
- * efficiency. So peek ahead to see if that's what we have.
+ * We want to special-case simple variable references for efficiency.
+ * So peek ahead to see if that's what we have.
*/
int tok = yylex();
if (tok == T_DATUM && plpgsql_peek() == ';' &&
- (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
+ (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_VAR ||
+ yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC))
{
new->retvarno = yylval.wdatum.datum->dno;
}
else
{
- /* Not (just) a row/record name, so treat as expression */
+ /*
+ * Not (just) a variable name, so treat as expression.
+ *
+ * Note that a well-formed expression is _required_ here;
+ * anything else is a compile-time error.
+ */
plpgsql_push_back_token(tok);
new->expr = read_sql_expression(';', ";");
}
}
- else
- new->expr = read_sql_expression(';', ";");
return (PLpgSQL_stmt *) new;
}