--- id: functions title: Functions description: Creating and using Postgres functions. --- import Tabs from '@theme/Tabs'; import TabsPanel from '@theme/TabsPanel'; Postgres has built-in support for [SQL functions](https://www.postgresql.org/docs/current/sql-createfunction.html). These functions live inside your database, and they can be [used with the API](/docs/reference/javascript/rpc). ## Quick demo ## Creating Functions Supabase provides several options for creating database functions. You can use the Dashboard or create them directly using SQL. We provide a SQL editor within the Dashboard, or you can [connect](/docs/guides/database/connecting/connecting-to-postgres) to your database and run the SQL queries yourself. 1. Go to the "SQL editor" section. 2. Click "New Query". 3. Enter the SQL to create or replace your Database function. 4. Click "Run" or cmd+enter (ctrl+enter). ## Examples ### Data set For this guide we'll use the following example data: ```sql create table planets ( id serial primary key, name text ); insert into planets (id, name) values (1, 'Tattoine'), (2, 'Alderaan'), (3, 'Kashyyyk'); create table people ( id serial primary key, name text, planet_id bigint references planets ); insert into people (id, name, planet_id) values (1, 'Anakin Skywalker', 1), (2, 'Luke Skywalker', 1), (3, 'Princess Leia', 2), (4, 'Chewbacca', 3); ```

Planets

| id | name | | ---- | ---- | | 1 | Tattoine | | 2 | Alderaan | | 3 | Kashyyyk |

People

| id | name | planet_id | | ---- | ---- | ---- | | 1 | Anakin Skywalker | 1 | | 2 | Luke Skywalker | 1 | | 3 | Princess Leia | 2 | | 4 | Chewbacca | 3 |
### Basic function A basic example which returns a string "hello world". ```sql create or replace function hello_world() -- 1 returns text -- 2 language sql -- 3 as $$ -- 4 select 'hello world'; -- 5 $$; --6 ```
Show/Hide Details At it's most basic a function has the following parts: 1. `create or replace function hello_world()`: The function declaration, where `hello_world` is the name of the function. You can use either `create` when creating a new function or `replace` when replacing an existing function. Or you can use `create or replace` together to handle either. 2. `returns text`: The type of data that the function returns. If it returns nothing, you can `returns void`. 3. `language sql`: The language used inside the function body. This can also be a procedural language: `plpgsql`, `plv8`, `plpython`, etc. 4. `as $$`: The function wrapper. Anything enclosed inside the `$$` symbols will be part of the function body. 5. `select 'hello world';`: A simple function body. The final `select` statement inside a function body will be returned if there are no statements following it. 6. `$$;`: The closing symbols of the funciton wrapper.
#### Execute ```sql select hello_world(); ``` ```js const { data, error } = supabase .rpc('hello_world') ``` Reference: [rpc()](/docs/reference/javascript/rpc) ```dart final res = await supabase .rpc('hello_world') .execute(); ``` Reference: [rpc()](/docs/reference/dart/rpc) ### Return table sets A basic example which return all the `planets` in our example data set. ```sql create or replace function get_planets() returns setof planets language sql as $$ select * from planets; $$; ``` #### Execute Because this function returns a table set, we can also apply filters and selectors. For example, if we only wanted the first planet: ```sql select * from get_planets() where id = 1; ``` ```js const { data, error } = supabase .rpc('get_planets') .eq('id', 1) ``` Reference: [rpc()](/docs/reference/javascript/rpc) ```dart final res = await supabase .rpc('get_planets') .eq('id', 1) .execute(); ``` Reference: [rpc()](/docs/reference/dart/rpc) ### With parameters A basic example which will insert a new planet into the `planets` and return the new ID. Note that this time we're using the `plpgsql` language. ```sql create or replace function add_planet(name text) returns bigint language plpgsql as $$ declare new_row bigint; begin insert into planets(name) values (add_planet.name) returning id into new_row; return new_row; end; $$; ``` #### Execute Because this function returns a table set, we can also apply filters and selectors. For example, if we only wanted the `name` of the first planet: ```sql select * from add_planet('Jakku'); ``` ```js const { data, error } = supabase .rpc('add_planet', { name: 'Jakku' }) ``` Reference: [rpc()](/docs/reference/javascript/rpc) ```dart final res = await supabase .rpc('add_planet', params: { 'name': 'Jakku' }) .execute(); ``` Reference: [rpc()](/docs/reference/dart/rpc) ## Resources - PostgreSQL Official Docs: [Chapter 9. Functions and Operators](https://www.postgresql.org/docs/current/functions.html) - PostgreSQL Reference: [CREATE FUNCTION](https://www.postgresql.org/docs/9.1/sql-createfunction.html)