---
title: "The PL/pgSQL \"return\" statement"
url: "https://docs.yugabyte.com/stable/api/ysql/user-defined-subprograms-and-anon-blocks/language-plpgsql-subprograms/plpgsql-syntax-and-semantics/executable-section/basic-statements/return-statement/"
---

# The PL/pgSQL "return" statement

Describes the syntax and semantics various PL/pgSQL "return" statement variants[YSQL].

## Syntax

- [![Grammar Icon](/icons/file-lines.svg)Grammar](#grammar-1)
- [![Diagram Icon](/icons/diagram.svg)Diagram](#diagram-1)

```output.ebnf
plpgsql_return_stmt ::= RETURN [ expression
                                 | NEXT
                                 | NEW
                                 | OLD
                                 | NULL ]
```

#### plpgsql\_return\_stmt

RETURN[expression](/stable/api/ysql/user-defined-subprograms-and-anon-blocks/language-plpgsql-subprograms/plpgsql-syntax-and-semantics/executable-section/basic-statements/return-statement/syntax_resources/grammar_diagrams#expression)NEXTNEWOLDNULL

## Semantics

### The bare "return" statement

You can use the bare *return* statement to exit from any top-level PL/pgSQL block statement (even if it is invoked within a deeply-nested block statement). In particular, you can use it to exit from a procedure or a *do* statement. However, this use is very rarely seen—and many programers would consider it to be a bad practice. Rather, the preferred practice is to let the point of execution simply reach the final *end;*— by virtue of the use of "proper" flow control with the *if* statement or the *case* statement. Then the procedure is automatically exited just as if the bare *return* were written here (and only here).

### The "return expression" statement

This is legal only in a regular function (but *not* in a table function). In fact every regular function *must* have at least one such statement and the point of execution must reach one of these. If you fail to satisfy this rule, then there's no syntax error. But you'll get the *2F005* run-time error saying that the function finished without executing a *return expression* statement. The expression must match what the *returns* clause, in the function's header, specifies.

### The "return next" statement

This is legal only in a table function. In fact every table function *must* have at least one such statement and the point of execution must reach one of these. Often, the *return next* statement is written within a loop so that the table function returns many rows. Notice that the *return next* statement takes no argument. Rather, you must assign value(s) ordinarily before invoking it, just as if these identified ordinary *in out* formal arguments, using the identifier(s) that the *returns table(...)* clause, in the function's header, specifies.

### The "return new", "return old" and "return null" statements

These are legal only in a DML trigger function. In fact every DML trigger function *must* have at least one such statement and the point of execution must reach one of these. A DML trigger function is created as such by using the *returns trigger* clause in the function's header.

Coming soon

More detail, and code examples, about these uses will follow.
