Lang sql
npx -y skills add arhuman/claude-plugins --skill lang-sqlAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
SQL coding best practices and patterns. Use when working with SQL files, writing migrations, or reviewing schema design.
SKILL.md
6.2 KB, ~1.4k tokens by cl100k_base, as published. Nobody here has run it
lang-sql
This skill defines rules for writing correct, maintainable, and production-safe SQL — covering schema design, migrations, queries, and indexing.
Reference Guide
- PostgreSQL documentation: https://www.postgresql.org/docs/current/
- Use
EXPLAIN ANALYZEto verify query plans before merging slow queries TIMESTAMPTZ(with timezone) overTIMESTAMPfor any datetime column
Architecture Principles
Schema Design
- Use
SERIAL PRIMARY KEYfor surrogate keys - Prefer
TEXToverVARCHAR(n)unless a hard limit is meaningful (e.g.VARCHAR(45)for IP addresses,VARCHAR(500)for tokens) - Use
TIMESTAMPTZ NOT NULL DEFAULT NOW()for audit timestamps (created_at,computed_at) - Nullable columns should be explicit: use
DEFAULT NULLwhen adding optional columns - Use
UNIQUEconstraints on the table, not just application-level validation - Use
CHECKconstraints to enforce domain rules at the DB level (e.g. state machines, enum-like values)
State Machines in SQL
Model lifecycle states as a VARCHAR column with a CHECK constraint listing all valid values:
ADD COLUMN state VARCHAR(20) NOT NULL DEFAULT 'created'
CHECK (state IN ('created', 'answering', 'submitted', 'completed', 'expired'));
COMMENT ON COLUMN quizzes.state IS 'Quiz lifecycle: created → answering → submitted → completed (or expired)';
Document the transition flow in a COMMENT ON COLUMN.
Foreign Keys
- Add
ON DELETE CASCADEon child tables when child rows are meaningless without the parent - Remove FK constraints intentionally when data preservation matters more than referential integrity (e.g. soft-delete QCMs while preserving quiz history) — always document this trade-off in the migration comment
- Never silently drop an FK; write a comment explaining why
JSON Columns
- Use
JSONB(notJSON) for structured data that may be queried or indexed - Only use JSONB when the structure is variable or too large for normalized columns (e.g.
scores,question_sequence) - Avoid JSONB for fields that are queried by value — normalize them instead
MUST DO
- One migration = one concern: each SQL file addresses a single schema change
- Number migrations sequentially:
NN-description.sql(e.g.21-add-ip-address.sql) - Write a comment header explaining why the migration exists, especially for non-obvious changes
- Use
IF EXISTS/IF NOT EXISTSonDROPandCREATE INDEXin migrations to make them idempotent - Use partial indexes when a condition is almost always true (e.g.
WHERE session_token IS NOT NULL) - Use
ON CONFLICT ... DO UPDATE(upsert) instead of separate SELECT + INSERT/UPDATE - Use CTEs (
WITH) to make complex queries readable; avoid deeply nested subqueries - Use
COALESCEto handle NULLs explicitly in calculations rather than relying on implicit NULL propagation - Use
EXTRACT(EPOCH FROM interval) * 1000for millisecond durations from timestamp deltas - Use
LAG()window function for computing deltas between consecutive rows (e.g. answer timing) - Parameterize all queries — never interpolate user input into SQL strings
MUST NOT DO
- Do not use
SELECT *in application queries — always list columns explicitly - Do not add columns without a
DEFAULTon a large live table (it locks the table in old PG versions) - Do not use
TIMESTAMPwithout timezone — always useTIMESTAMPTZ - Do not drop a foreign key without a comment explaining the trade-off
- Do not use
JSON— alwaysJSONB - Do not put business logic (scoring, state transitions) in SQL — keep it in the application layer
- Do not use
COUNT(*)to check existence — useEXISTS (SELECT 1 FROM ...)instead
Coding Style
Formatting
- Keywords in UPPERCASE:
SELECT,FROM,WHERE,INSERT,ON DELETE CASCADE, etc. - Table and column names in
snake_case - Indent continuation lines by one tab/4 spaces
- One column per line in
CREATE TABLEandALTER TABLE ADD COLUMNblocks
Migration Files
-- Migration: Short description of what this migration does
--
-- Purpose: Why this change is needed
-- Impact: What tables/columns/indexes are affected
-- Trade-off: Any integrity or performance trade-off (if applicable)
ALTER TABLE quizzes
ADD COLUMN ip_address VARCHAR(45) DEFAULT NULL;
Indexes
-- Partial index: only index rows where token is set
CREATE INDEX idx_quizzes_session_token ON quizzes(session_token) WHERE session_token IS NOT NULL;
-- Composite index for analytics time-range queries
CREATE INDEX idx_answers_timing ON answers(quiz_id, answered_at);
Upsert Pattern
INSERT INTO answers (quiz_id, question_id, choice_id)
VALUES ($1, $2, $3)
ON CONFLICT (quiz_id, question_id)
DO UPDATE SET choice_id = EXCLUDED.choice_id;
Window Function for Timing
WITH ordered_answers AS (
SELECT
question_id,
answered_at,
LAG(answered_at) OVER (ORDER BY answered_at, id) AS prev_answered_at
FROM answers
WHERE quiz_id = $1
)
SELECT EXTRACT(EPOCH FROM (
answered_at - COALESCE(prev_answered_at, (SELECT created_at FROM quizzes WHERE id = $1))
)) * 1000
FROM ordered_answers
WHERE question_id = $2;
Quality Standards
- Every migration must be tested on a local DB before committing
- Migrations are not reversible by default — write a separate rollback file only when rollback is planned
- All indexes on high-write tables must be justified (indexes slow writes)
CHECKconstraints must cover all valid values of an enum-like column- IP address columns use
VARCHAR(45)to support both IPv4 and IPv6
Agent Behavior
- When asked to add a column, always produce a numbered migration file in
conf/initdb/ - When modifying a
CHECKconstraint, drop the old one first (DROP CONSTRAINT IF EXISTS) then add the new one - When writing a JOIN query, always use explicit
INNER JOIN/LEFT JOIN— never implicit comma joins - When unsure whether a query will be slow, suggest
EXPLAIN ANALYZEbefore shipping - Never generate a migration that drops a column or table without first asking for confirmation
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.
Gives 2 of the 12 instructions most databases sql skills give in ~1.4k tokens
Counted across 589 of the 662 authors here whose files we hold, read 2026-08-07
- Use parameterized querieshere, and in 37 of 589, across 34 files
- Use timestamptz for timestampshere, and in 30 of 589, across 14 files
- Index foreign keysin 29 of 589, across 18 files
- Create indexes concurrentlyin 29 of 589, across 24 files
- Use numeric type for moneyin 25 of 589, across 8 files
- Use cursor pagination instead of offsetin 24 of 589, across 17 files
- Select only required columnsin 24 of 589, across 20 files
- Add indexes manually on foreign key columnsin 22 of 589, across 12 files
- Normalize to third normal formin 19 of 589, across 10 files
- Configure connection poolingin 19 of 589, across 17 files
- Put equality columns before range columns in indexesin 18 of 589, across 10 files
- Read individual rule files for detailed explanationsin 18 of 589, across 4 files
Said here and by no other author read
- use uppercase for all SQL keywords
- use text over varchar unless a limit is meaningful
- include defaults when adding columns to live tables
- write a descriptive comment header for every migration
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.