plpgsql
PostgreSQL procedural language (PL/pgSQL). Covers stored procedures, functions, triggers, exception handling, and control structures. Use for PostgreSQL server-side programming. USE WHEN: user mentions "plpgsql", "PostgreSQL functions", "PostgreSQL procedures", "PostgreSQL triggers", "RETURNS TABLE", "RETURNS SETOF", "RAISE NOTICE" DO NOT USE FOR: basic PostgreSQL SQL - use `postgresql` instead, PL/SQL (Oracle) - use `plsql` instead, T-SQL - use `tsql` instead
What this skill does
# PL/pgSQL Core Knowledge
> **Deep Knowledge**: Use `mcp__documentation__fetch_docs` with technology: `postgresql` for comprehensive documentation.
## Basic Structure
```sql
CREATE OR REPLACE FUNCTION function_name(param1 type, param2 type)
RETURNS return_type
LANGUAGE plpgsql
AS $$
DECLARE
-- Variable declarations
var1 type;
var2 type := default_value;
BEGIN
-- Function body
RETURN result;
END;
$$;
```
## Functions
### Basic Function
```sql
CREATE OR REPLACE FUNCTION get_user_name(user_id INT)
RETURNS VARCHAR
LANGUAGE plpgsql
AS $$
DECLARE
user_name VARCHAR;
BEGIN
SELECT name INTO user_name
FROM users
WHERE id = user_id;
RETURN user_name;
END;
$$;
-- Usage
SELECT get_user_name(1);
```
### Function with Multiple Return Values
```sql
CREATE OR REPLACE FUNCTION get_user_info(p_user_id INT)
RETURNS TABLE(name VARCHAR, email VARCHAR, order_count BIGINT)
LANGUAGE plpgsql
AS $$
BEGIN
RETURN QUERY
SELECT u.name, u.email, COUNT(o.id)::BIGINT
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE u.id = p_user_id
GROUP BY u.id;
END;
$$;
-- Usage
SELECT * FROM get_user_info(1);
```
### Function with OUT Parameters
```sql
CREATE OR REPLACE FUNCTION calculate_stats(
IN p_user_id INT,
OUT total_orders INT,
OUT total_amount NUMERIC
)
LANGUAGE plpgsql
AS $$
BEGIN
SELECT COUNT(*), COALESCE(SUM(total), 0)
INTO total_orders, total_amount
FROM orders
WHERE user_id = p_user_id;
END;
$$;
-- Usage
SELECT * FROM calculate_stats(1);
```
### SETOF Function (Multiple Rows)
```sql
CREATE OR REPLACE FUNCTION get_active_users()
RETURNS SETOF users
LANGUAGE plpgsql
AS $$
BEGIN
RETURN QUERY SELECT * FROM users WHERE status = 'active';
END;
$$;
-- Usage
SELECT * FROM get_active_users();
```
## Procedures (PostgreSQL 11+)
```sql
CREATE OR REPLACE PROCEDURE transfer_funds(
sender_id INT,
receiver_id INT,
amount NUMERIC
)
LANGUAGE plpgsql
AS $$
BEGIN
-- Deduct from sender
UPDATE accounts SET balance = balance - amount WHERE id = sender_id;
-- Add to receiver
UPDATE accounts SET balance = balance + amount WHERE id = receiver_id;
-- Commit transaction
COMMIT;
END;
$$;
-- Usage
CALL transfer_funds(1, 2, 100.00);
```
## Variables and Types
```sql
DECLARE
-- Scalar types
v_count INT := 0;
v_name VARCHAR(100);
v_amount NUMERIC(10,2) DEFAULT 0.00;
v_active BOOLEAN := TRUE;
v_created TIMESTAMP := NOW();
-- Type from column
v_email users.email%TYPE;
-- Type from row
v_user users%ROWTYPE;
-- Record (dynamic)
v_record RECORD;
-- Array
v_ids INT[] := ARRAY[1, 2, 3];
-- Constant
c_tax_rate CONSTANT NUMERIC := 0.21;
BEGIN
-- ...
END;
```
## Control Structures
### IF Statement
```sql
IF condition THEN
-- statements
ELSIF another_condition THEN
-- statements
ELSE
-- statements
END IF;
-- Example
IF v_count > 100 THEN
v_status := 'high';
ELSIF v_count > 50 THEN
v_status := 'medium';
ELSE
v_status := 'low';
END IF;
```
### CASE Statement
```sql
CASE expression
WHEN value1 THEN
-- statements
WHEN value2 THEN
-- statements
ELSE
-- statements
END CASE;
-- Searched CASE
CASE
WHEN condition1 THEN
-- statements
WHEN condition2 THEN
-- statements
ELSE
-- statements
END CASE;
```
### Loops
```sql
-- Simple loop
LOOP
-- statements
EXIT WHEN condition;
END LOOP;
-- WHILE loop
WHILE condition LOOP
-- statements
END LOOP;
-- FOR loop (integer range)
FOR i IN 1..10 LOOP
RAISE NOTICE 'i = %', i;
END LOOP;
-- FOR loop (reverse)
FOR i IN REVERSE 10..1 LOOP
-- statements
END LOOP;
-- FOR loop (query result)
FOR v_record IN SELECT * FROM users WHERE status = 'active' LOOP
RAISE NOTICE 'User: %', v_record.name;
END LOOP;
-- FOREACH (arrays)
FOREACH v_id IN ARRAY v_ids LOOP
RAISE NOTICE 'ID: %', v_id;
END LOOP;
```
## Exception Handling
```sql
BEGIN
-- Statements that might fail
INSERT INTO users (email) VALUES (p_email);
EXCEPTION
WHEN unique_violation THEN
RAISE NOTICE 'Email already exists: %', p_email;
RETURN NULL;
WHEN not_null_violation THEN
RAISE EXCEPTION 'Email cannot be null';
WHEN OTHERS THEN
RAISE EXCEPTION 'Unexpected error: % %', SQLERRM, SQLSTATE;
END;
```
### Common Exception Codes
| Exception | Description |
|-----------|-------------|
| `unique_violation` | Duplicate key |
| `not_null_violation` | NULL in NOT NULL column |
| `foreign_key_violation` | FK constraint failed |
| `check_violation` | CHECK constraint failed |
| `division_by_zero` | Division by zero |
| `no_data_found` | SELECT INTO returned no rows |
| `too_many_rows` | SELECT INTO returned multiple rows |
### Raising Exceptions
```sql
-- Notice (info)
RAISE NOTICE 'Processing user %', v_user_id;
-- Warning
RAISE WARNING 'Value seems too high: %', v_amount;
-- Exception (stops execution)
RAISE EXCEPTION 'Invalid user ID: %', v_user_id;
-- With error code
RAISE EXCEPTION 'Invalid input' USING ERRCODE = 'invalid_parameter_value';
```
## Triggers
### Basic Trigger
```sql
CREATE OR REPLACE FUNCTION update_timestamp()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
BEGIN
NEW.updated_at := NOW();
RETURN NEW;
END;
$$;
CREATE TRIGGER trg_users_update
BEFORE UPDATE ON users
FOR EACH ROW
EXECUTE FUNCTION update_timestamp();
```
### Trigger Variables
| Variable | Description |
|----------|-------------|
| `NEW` | New row (INSERT/UPDATE) |
| `OLD` | Old row (UPDATE/DELETE) |
| `TG_OP` | Operation: INSERT, UPDATE, DELETE |
| `TG_TABLE_NAME` | Table name |
| `TG_WHEN` | BEFORE or AFTER |
### Audit Trigger
```sql
CREATE OR REPLACE FUNCTION audit_changes()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
BEGIN
IF TG_OP = 'INSERT' THEN
INSERT INTO audit_log (table_name, operation, new_data)
VALUES (TG_TABLE_NAME, 'INSERT', row_to_json(NEW));
RETURN NEW;
ELSIF TG_OP = 'UPDATE' THEN
INSERT INTO audit_log (table_name, operation, old_data, new_data)
VALUES (TG_TABLE_NAME, 'UPDATE', row_to_json(OLD), row_to_json(NEW));
RETURN NEW;
ELSIF TG_OP = 'DELETE' THEN
INSERT INTO audit_log (table_name, operation, old_data)
VALUES (TG_TABLE_NAME, 'DELETE', row_to_json(OLD));
RETURN OLD;
END IF;
END;
$$;
CREATE TRIGGER trg_users_audit
AFTER INSERT OR UPDATE OR DELETE ON users
FOR EACH ROW
EXECUTE FUNCTION audit_changes();
```
### Conditional Trigger
```sql
CREATE TRIGGER trg_orders_notify
AFTER INSERT ON orders
FOR EACH ROW
WHEN (NEW.total > 1000)
EXECUTE FUNCTION notify_high_value_order();
```
## Dynamic SQL
```sql
CREATE OR REPLACE FUNCTION search_table(
p_table TEXT,
p_column TEXT,
p_value TEXT
)
RETURNS SETOF RECORD
LANGUAGE plpgsql
AS $$
BEGIN
RETURN QUERY EXECUTE format(
'SELECT * FROM %I WHERE %I = $1',
p_table, p_column
) USING p_value;
END;
$$;
-- With EXECUTE INTO
DECLARE
v_count INT;
BEGIN
EXECUTE 'SELECT COUNT(*) FROM ' || quote_ident(p_table)
INTO v_count;
END;
```
## Cursors
```sql
CREATE OR REPLACE FUNCTION process_orders()
RETURNS VOID
LANGUAGE plpgsql
AS $$
DECLARE
v_cursor CURSOR FOR SELECT * FROM orders WHERE status = 'pending';
v_order orders%ROWTYPE;
BEGIN
OPEN v_cursor;
LOOP
FETCH v_cursor INTO v_order;
EXIT WHEN NOT FOUND;
-- Process order
UPDATE orders SET status = 'processing' WHERE id = v_order.id;
END LOOP;
CLOSE v_cursor;
END;
$$;
-- FOR loop cursor (auto open/close)
FOR v_order IN SELECT * FROM orders WHERE status = 'pending' LOOP
-- Process
END LOOP;
```
## Best Practices
### DO
- Use `%TYPE` and `%ROWTYPE` for type safety
- Use `STRICT` for SELECT INTO when expecting exactly one row
- Use `format()` with `%I` for identifiers in dynamic SQL
- Use exception blocks for error handlingRelated in Backend & APIs
jfrog
IncludedInteract with the JFrog Platform via the JFrog CLI and REST/GraphQL APIs. Use this skill when the user wants to manage Artifactory repositories, upload or download artifacts, manage builds, configure permissions, manage users and groups, work with access tokens, configure JFrog CLI servers, search artifacts, manage properties, set up replication, manage JFrog Projects, run security audits or scans, look up CVE details, query exposures scan results from JFrog Advanced Security, manage release bundles and lifecycle operations, aggregate or export platform data, or perform any JFrog Platform administration task. Also use when the user mentions jf, jfrog, artifactory, xray, distribution, evidence, apptrust, onemodel, graphql, workers, mission control, curation, advanced security, exposures, or any JFrog product name.
cupynumeric-migration-readiness
IncludedPre-migration readiness assessor for porting NumPy to cuPyNumeric. Use BEFORE substantial porting work begins when the user asks whether code will scale on GPU, whether they should migrate to cuPyNumeric, which NumPy patterns transfer cleanly, what must be refactored before porting, or mentions pre-port assessment, scaling analysis, or refactor planning. Inspect the user's source code, look up NumPy usage, cross-reference the cuPyNumeric API support manifest, and distinguish distributed-scaling-friendly patterns from blockers such as unsupported APIs, scalar synchronization, host round-trips, Python/object-heavy control flow, shape/data-dependent branching, and in-place mutation hazards. Produce a verdict of READY, LIGHT REFACTOR, SIGNIFICANT REFACTOR, or NOT RECOMMENDED, with concrete refactor pointers.
alibabacloud-data-agent-skill
IncludedInvoke Alibaba Cloud Apsara Data Agent for Analytics via CLI to perform natural language-driven data analysis on enterprise databases. Data Agent for Analytics is an intelligent data analysis agent developed by Alibaba Cloud Database team for enterprise users. It automatically completes requirement analysis, data understanding, analysis insights, and report generation based on natural language descriptions. This tool supports: discovering data resources (instances/databases/tables) managed in DMS, initiating query or deep analysis sessions, real-time progress tracking, and retrieving analysis conclusions and generated reports. Use this Skill when users need to query databases, analyze data trends, generate data reports, ask questions in natural language, or mention "Data Agent", "data analysis", "database query", "SQL analysis", "data insights".
token-optimizer
IncludedReduce OpenClaw token usage and API costs through smart model routing, heartbeat optimization, budget tracking, and native 2026.2.15 features (session pruning, bootstrap size limits, cache TTL alignment). Use when token costs are high, API rate limits are being hit, or hosting multiple agents at scale. The 4 executable scripts (context_optimizer, model_router, heartbeat_optimizer, token_tracker) are local-only — no network requests, no subprocess calls, no system modifications. Reference files (PROVIDERS.md, config-patches.json) document optional multi-provider strategies that require external API keys and network access if you choose to use them. See SECURITY.md for full breakdown.
resend-cli
IncludedUse this skill when the task is specifically about operating Resend from an AI agent, terminal session, or CI job via the official resend CLI: installing/authenticating the CLI, sending/listing/updating/cancelling emails, batch sends, domains and DNS, webhooks and local listeners, inbound receiving, contacts, topics, segments, broadcasts, templates, API keys, profiles, or debugging Resend CLI/API failures. Trigger on mentions of Resend CLI, `resend`, `resend doctor`, `resend emails send`, `resend domains`, `resend webhooks listen`, `resend emails receiving`, or agent-friendly terminal automation.
alibabacloud-odps-maxframe-coding
IncludedUse this skill for MaxFrame SDK development and documentation navigation on Alibaba Cloud MaxCompute (ODPS). Helps answer MaxFrame API, concept, official example, and supported pandas API questions; create data processing programs; read/write MaxCompute tables; debug jobs (remote or local); and build custom DPE runtime images. Trigger when users mention MaxFrame, MaxCompute with MaxFrame, ODPS table processing, DPE runtime, MaxFrame docs/examples, DataFrame/Tensor operations, or GPU runtime setup. Works for both English and Chinese queries about Alibaba Cloud data processing with MaxFrame.