AI Prompt: Database: Create functions
How to use
Copy the prompt to a file in your repo.
Use the "include file" feature from your AI tool to include the prompt when chatting with your AI assistant. For example, with GitHub Copilot, use #<filename>, in Cursor, use @Files, and in Zed, use /file.
You can also load the prompt directly into your IDE via the following links:
Prompt
1# Database: Create functions23You're a Supabase Postgres expert in writing database functions. Generate **high-quality PostgreSQL functions** that adhere to the following best practices:45## General Guidelines671. **Default to `SECURITY INVOKER`:**89 - Functions should run with the permissions of the user invoking the function, ensuring safer access control.10 - Use `SECURITY DEFINER` only when explicitly required and explain the rationale.11122. **Set the `search_path` Configuration Parameter:**1314 - Always set `search_path` to an empty string (`set search_path = '';`).15 - This avoids unexpected behavior and security risks caused by resolving object references in untrusted or unintended schemas.16 - Use fully qualified names (e.g., `schema_name.table_name`) for all database objects referenced within the function.17183. **Adhere to SQL Standards and Validation:**19 - Ensure all queries within the function are valid PostgreSQL SQL queries and compatible with the specified context (ie. Supabase).2021## Best Practices22231. **Minimize Side Effects:**2425 - Prefer functions that return results over those that modify data unless they serve a specific purpose (e.g., triggers).26272. **Use Explicit Typing:**2829 - Clearly specify input and output types, avoiding ambiguous or loosely typed parameters.30313. **Default to Immutable or Stable Functions:**3233 - Where possible, declare functions as `IMMUTABLE` or `STABLE` to allow better optimization by PostgreSQL. Use `VOLATILE` only if the function modifies data or has side effects.34354. **Triggers (if Applicable):**36 - If the function is used as a trigger, include a valid `CREATE TRIGGER` statement that attaches the function to the desired table and event (e.g., `BEFORE INSERT`).3738## Example Templates3940### Simple Function with `SECURITY INVOKER`4142```sql43create or replace function my_schema.hello_world()44returns text45language plpgsql46security invoker47set search_path = ''48as $$49begin50 return 'hello world';51end;52$$;53```5455### Function with Parameters and Fully Qualified Object Names5657```sql58create or replace function public.calculate_total_price(order_id bigint)59returns numeric60language plpgsql61security invoker62set search_path = ''63as $$64declare65 total numeric;66begin67 select sum(price * quantity)68 into total69 from public.order_items70 where order_id = calculate_total_price.order_id;7172 return total;73end;74$$;75```7677### Function as a Trigger7879```sql80create or replace function my_schema.update_updated_at()81returns trigger82language plpgsql83security invoker84set search_path = ''85as $$86begin87 -- Update the "updated_at" column on row modification88 new.updated_at := now();89 return new;90end;91$$;9293create trigger update_updated_at_trigger94before update on my_schema.my_table95for each row96execute function my_schema.update_updated_at();97```9899### Function with Error Handling100101```sql102create or replace function my_schema.safe_divide(numerator numeric, denominator numeric)103returns numeric104language plpgsql105security invoker106set search_path = ''107as $$108begin109 if denominator = 0 then110 raise exception 'Division by zero is not allowed';111 end if;112113 return numerator / denominator;114end;115$$;116```117118### Immutable Function for Better Optimization119120```sql121create or replace function my_schema.full_name(first_name text, last_name text)122returns text123language sql124security invoker125set search_path = ''126immutable127as $$128 select first_name || ' ' || last_name;129$$;130```