-
Notifications
You must be signed in to change notification settings - Fork 105
chore: rewrite docs #491
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore: rewrite docs #491
Changes from 20 commits
76a8e25
e21ef94
de383a1
60b52b3
c7608db
213524a
9532c11
00e95b5
e278192
54dab85
e5f0bf2
fd2867b
853aaba
458c650
a56d71d
1f7123e
11bc970
4224607
7cedfee
ea4524c
35e0d88
1a2257b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
# Configuration | ||
|
||
This guide will help you to understand how to configure the Postgres Language Server. It explains the structure of the configuration file and how the configuration is resolved. | ||
|
||
The Postgres Language Server allows you to customize its behavior using CLI options or a configuration file named `postgrestools.jsonc`. We recommend that you create a configuration file for each project. This ensures that each team member has the same configuration in the CLI and in any editor that allows Biome integration. Many of the options available in a configuration file are also available in the CLI. | ||
|
||
## Configuration file structure | ||
|
||
A configuration file is usually placed in your project’s root folder. It is organized around the tools that are provided. All tools are enabled by default, but some require additional setup like a database connection or the `plpgsql_check` extension. | ||
|
||
```json | ||
{ | ||
"$schema": "https://pgtools.dev/latest/schema.json", | ||
"linter": { | ||
"enabled": true, | ||
"rules": { | ||
"recommended": true | ||
} | ||
}, | ||
"typecheck": { | ||
"enabled": true | ||
} | ||
"plpgsqlCheck": { | ||
"enabled" : true | ||
} | ||
} | ||
``` | ||
|
||
## Configuring a database connection | ||
|
||
Some tools that the Postgres Language Server provides are implemented as mere interfaces on top of functionality that is provided by the database itself. This ensures correctness, but requires an active connection to a Postgres database. We strongly recommend to only connect to a local development database. | ||
|
||
```json | ||
{ | ||
"$schema": "https://pgtools.dev/latest/schema.json", | ||
"db": { | ||
"host": "127.0.0.1", | ||
"port": 5432, | ||
"username": "postgres", | ||
"password": "postgres", | ||
"database": "postgres", | ||
"connTimeoutSecs": 10, | ||
"allowStatementExecutionsAgainst": ["127.0.0.1/*", "localhost/*"] | ||
} | ||
} | ||
``` | ||
|
||
|
||
## Specifying files to process | ||
|
||
You can control the files/folders to process using different strategies, either CLI, configuration and VCS. | ||
|
||
### Include files via CLI | ||
The first way to control which files and folders are processed is to list them in the CLI. In the following command, we only check `file1.sql` and all the files in the `src` folder, because folders are recursively traversed. | ||
|
||
```shell | ||
postgrestools check file1.js src/ | ||
``` | ||
|
||
### Control files via configuration | ||
|
||
The configuration file can be used to refine which files are processed. You can explicitly list the files to be processed using the `files.includes` field. `files.includes` accepts glob patterns such as sql/**/*.sql. Negated patterns starting with `!` can be used to exclude files. | ||
|
||
Paths and globs inside the configuration file are resolved relative to the folder the configuration file is in. An exception to this is when a configuration file is extended by another. | ||
|
||
#### Include files via configuration | ||
Let’s take the following configuration, where we want to include only SQL files (`.sql`) that are inside the `sql/` folder: | ||
|
||
```json | ||
{ | ||
"files": { | ||
"includes": ["sql/**/*.sql"] | ||
} | ||
} | ||
``` | ||
|
||
#### Exclude files via configuration | ||
If you want to exclude files and folders from being processed, you can use the `files.ignore` . | ||
|
||
In the following example, we include all files, except those in any test/ folder: | ||
|
||
```json | ||
{ | ||
"files": { | ||
"ignore": [ | ||
"**/test", | ||
] | ||
} | ||
} | ||
``` | ||
|
||
#### Control files via VCS | ||
You can ignore files ignored by your [VCS](/guides/vcs_integration.md). | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Autocompletion & Hover | ||
|
||
The language server provides autocompletion and hover information when connected to a database. | ||
|
||
## Autocompletion | ||
|
||
As you type SQL, the language server suggests relevant database objects based on your current context: | ||
|
||
- **Tables**: Available tables from your database schema | ||
- **Columns**: Columns from tables referenced in your query | ||
- **Functions**: Database functions and procedures | ||
- **Schemas**: Available schemas in your database | ||
- **Keywords**: SQL keywords and syntax | ||
|
||
The suggestions are context-aware - for example, when typing after `FROM`, you'll see table suggestions, and when typing after `SELECT`, you'll see column suggestions from relevant tables. | ||
|
||
## Hover Information | ||
|
||
Hovering over database objects in your SQL shows detailed information: | ||
|
||
- **Tables**: Schema, column list with data types | ||
- **Columns**: Data type, nullable status, table location | ||
- **Functions**: Return type, parameter information | ||
|
||
The hover information is pulled from your database schema. | ||
|
||
## Requirements | ||
|
||
Both features require: | ||
- A configured database connection | ||
- The language server must be able to read schema information from your database | ||
|
||
Without a database connection, these features are not available. | ||
|
||
## Configuration | ||
|
||
These features work automatically when you have a database connection configured. See the [database configuration guide](../guides/configure_database.md) for setup instructions. | ||
|
||
The language server caches schema information on startup. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# Linting | ||
|
||
The language server provides static analysis through linting rules that detect potential issues in your SQL code. The linter analyses SQL statements for safety issues, best practices violations, and problems that could break existing applications. | ||
|
||
## Rules | ||
|
||
Rules are organized into categories like Safety, Performance, and Style. Each rule can be configured individually or disabled entirely. | ||
|
||
See the [Rules Reference](../reference/rules.md) for the complete list of available rules and their descriptions. | ||
|
||
## Configuration | ||
|
||
Configure linting behavior in your `postgrestools.jsonc`: | ||
|
||
```json | ||
{ | ||
"linter": { | ||
// Enable/disable the linter entirely | ||
"enabled": true, | ||
"rules": { | ||
// Configure rule groups | ||
"safety": { | ||
// Individual rule configuration | ||
"banDropColumn": "error", // error, warn, info, hint, off | ||
"banDropTable": "warn", | ||
"addingRequiredField": "off" | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
## Suppressing Diagnostics | ||
|
||
You can suppress specific diagnostics using comments: | ||
|
||
```sql | ||
-- pgt-ignore-next-line safety/banDropColumn: Intentionally dropping deprecated column | ||
ALTER TABLE users DROP COLUMN deprecated_field; | ||
|
||
-- pgt-ignore safety/banDropTable: Cleanup during migration | ||
DROP TABLE temp_migration_table; | ||
``` | ||
|
||
For more details on suppressions check out [our guide]('../guides/suppressions.md'). | ||
|
||
## Schema-Aware Analysis | ||
|
||
Some rules require a database connection to perform schema-aware analysis. If no connection is configured, they are skipped. | ||
|
||
## CLI Usage | ||
|
||
The linter can also be used via the CLI for CI integration: | ||
|
||
```bash | ||
# Lint specific files | ||
postgrestools check migrations/ | ||
|
||
# With specific rules | ||
postgrestools check migrations/ --only safety/banDropColumn | ||
|
||
# Skip certain rules | ||
postgrestools check migrations/ --skip safety/banDropTable | ||
``` | ||
|
||
See the [CLI Reference](../reference/cli.md) for more options, and check the guide on [linting migrations]('../guides/checking_migrations.md'). |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# PL/pgSQL Support | ||
|
||
The Postgres Language Server partially supports `PL/pgSQL`. By default, use `libpg_query` to parse the function body and show any syntax error. This is a great way to quickly reduce the feedback loop when developing. Unfortunately, the reported errors do not contain any location information and we always report an error on the entire function body. | ||
|
||
To get more sophisticated and fine-grained errors, we strongly recommend to enable the [`plpgsql_check`](https://github.com/okbob/plpgsql_check) extension in your development database. | ||
|
||
```sql | ||
CREATE EXTENSION IF NOT EXISTS plpgsql_check; | ||
``` | ||
|
||
The language server will automatically detect the extension and start forwarding its reports as diagnostics. | ||
|
||
For any `CREATE FUNCTION` statement with the language `PL/pgSQL`, the following process occurs: | ||
|
||
1. The language server creates the function in a temporary transaction | ||
2. Calls `plpgsql_check_function()` to perform comprehensive static analysis of the function body | ||
3. For trigger functions, the analysis runs against each table that has triggers using this function, providing context-specific validation | ||
4. Errors are mapped back to source locations with token-level precision | ||
|
||
The integration provides more detailed and actionable feedback compared to basic syntax checking, including: | ||
|
||
> - checks fields of referenced database objects and types inside embedded SQL | ||
> - validates you are using the correct types for function parameters | ||
> - identifies unused variables and function arguments, unmodified OUT arguments | ||
> - partial detection of dead code (code after an RETURN command) | ||
> - detection of missing RETURN command in function (common after exception handlers, complex logic) | ||
> - tries to identify unwanted hidden casts, which can be a performance issue like unused indexes | ||
> - ability to collect relations and functions used by function | ||
> - ability to check EXECUTE statements against SQL injection vulnerability | ||
|
||
You can always disable the integration if you do not want the language server to hit your development database. | ||
|
||
```json | ||
{ | ||
"plpqsqlCheck": { | ||
"enabled": false | ||
} | ||
} | ||
``` | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,26 @@ | ||||||
# Syntax Diagnostics | ||||||
|
||||||
The Postgres Language Server reports diagnostics for syntax errors in your SQL files. Syntax diagnostics are enabled by default and cannot be disabled. | ||||||
|
||||||
## How it Works | ||||||
|
||||||
The language server uses [libpg_query](https://github.com/pganalyze/libpg_query) to parse SQL statements, which is the actual Postgre parser packaged as a library. This ensures 100% compatibility with Postgres syntax. | ||||||
|
||||||
When you type or modify SQL, the language server: | ||||||
1. Parses the SQL using `libpg_query` | ||||||
2. Reports any syntax errors as diagnostics | ||||||
|
||||||
## Features | ||||||
|
||||||
- Always correct: Uses the same parser as Postgres itself for accurate syntax validation | ||||||
- Named Parameter Support: Postgres does not support named parameters such as `:param` and `@param`. Since they are commonly used in ORMs and other tooling, we convert them to positional parameters (`$1`, `$2`) before parsing | ||||||
|
||||||
- `PL/pgSQL`: In addition to SQL, also validates `PL/pgSQL` function bodies for basic syntax errors | ||||||
|
||||||
## Error Information | ||||||
|
||||||
Syntax errors include: | ||||||
|
Syntax errors include: | |
Syntax errors include: |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- The exact error message from the Postgres parser | |
- The exact error message from the Postgres parser |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Source location when available (though `libpg_query` does not always provide precise positions) | |
- Source location when available (though `libpg_query` does not always provide precise positions) |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,56 @@ | ||||||||||||||||||||||||||
# Type Checking | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
The Postgres Language Server validates your SQL queries against your actual database schema. As you type, it checks that your tables exist, columns are spelled correctly, and data types match - just like Postgres would when executing the query. | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
## How it Works | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
When you write a SQL query, the language server: | ||||||||||||||||||||||||||
1. Connects to your database | ||||||||||||||||||||||||||
2. Asks Postgres to validate your query without running it | ||||||||||||||||||||||||||
3. Shows any errors directly in your editor | ||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
Since it uses your actual database, you get the exact same validation that would happen at runtime - but instantly as you type. | ||||||||||||||||||||||||||
|
Since it uses your actual database, you get the exact same validation that would happen at runtime - but instantly as you type. | |
Since it uses your actual database, you get the same validation that happens at runtime - as soon as you type. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we are using `EXPLAIN`, type checking is only available for DML statements: | |
- `SELECT` statements | |
- `INSERT` statements | |
- `UPDATE` statements | |
- `DELETE` statements | |
- Common Table Expressions (CTEs) | |
Since we are using `EXPLAIN`, type checking is only available for DML statements: | |
- `SELECT` statements | |
- `INSERT` statements | |
- `UPDATE` statements | |
- `DELETE` statements | |
- Common Table Expressions (CTEs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If not configured, defaults to `["public"]`. | |
Even if not specified, the LSP will always search`"public"` in last position. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.