Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ node_modules
coverage
.eslintcache
src/parser/grammar.ts
**/*.Identifier
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ All fields are optional and all fields that are not specified will be filled wit
- [**`linesBetweenQueries`**](docs/linesBetweenQueries.md) how many newlines to insert between queries.
- [**`denseOperators`**](docs/denseOperators.md) packs operators densely without spaces.
- [**`newlineBeforeSemicolon`**](docs/newlineBeforeSemicolon.md) places semicolon on separate line.
- [**`createTableColumnAlignment`**](docs/createTableColumnAlignment.md) aligns CREATE TABLE column definitions into three left-aligned columns (column name, column definition, other). (**experimental!**)
- [**`createTableColumnAlignment_breakwidth`**](docs/createTableColumnAlignment.md#createtablecolumnalignment_breakwidth) max width of the third column before wrapping to a new line. (**experimental!**)
- [**`params`**](docs/params.md) collection of values for placeholder replacement.
- [**`paramTypes`**](docs/paramTypes.md) specifies parameter placeholders types to support.

Expand Down
131 changes: 131 additions & 0 deletions docs/createTableColumnAlignment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# createTableColumnAlignment

When `true`, formats `CREATE TABLE` column definitions in a three-column
aligned layout:

- **Column 1** – the column name (`col_name`), left-aligned.
- **Column 2** – the column definition / data type (`column_definition`),
e.g. `INT`, `VARCHAR(100)`, `DECIMAL(10, 2)`, left-aligned.
- **Column 3** – everything else (`PRIMARY KEY`, `NOT NULL`, `DEFAULT`,
`COMMENT`, `UNIQUE`, ...), left-aligned.

The width of each column is sized to the widest entry in that column across
all column definitions in the same `CREATE TABLE` statement, so the starts
of columns 2 and 3 line up vertically across rows.

Table-level constraints (`CONSTRAINT name UNIQUE (...)`,
`PRIMARY KEY (...)`, `FOREIGN KEY (...)`, `CHECK (...)`, ...) do not have
the `col_name / column_definition / other` shape, so they are emitted on
their own line without padding.

Defaults to `false` (preserves the legacy single-space layout).

## Options

- `true` – enable three-column alignment for `CREATE TABLE` column lists.
- `false` (default) – use the legacy single-space layout.

## Example

### false (default)

```sql
CREATE TABLE users (
id INT PRIMARY KEY NOT NULL,
name VARCHAR(100) NOT NULL,
age INT,
email VARCHAR(255) UNIQUE
);
```

### true

```sql
CREATE TABLE users (
id INT PRIMARY KEY NOT NULL,
name VARCHAR(100) NOT NULL,
age INT,
email VARCHAR(255) UNIQUE
);
```

## Scope and limitations

- The alignment only applies to the column-list parenthesis that directly
follows a `CREATE TABLE` clause keyword (e.g. `CREATE TABLE`,
`CREATE OR REPLACE TABLE`, `CREATE TEMP TABLE`, `CREATE TABLE IF NOT EXISTS`,
`CREATE EXTERNAL TABLE`, ...). It does **not** apply to nested parentheses
such as the size list of `VARCHAR(100)` or the column list of a
`CHECK (...)` constraint.
- A short `CREATE TABLE` whose column list fits on a single line (under
[`expressionWidth`](./expressionWidth.md)) stays on a single line — the
alignment only kicks in when the column list is split across multiple
lines.
- If a particular column entry can't be formatted as a single line (for
example because it contains a multi-line comment, or because the
"other" part contains a sub-clause like `ON UPDATE` in dialects that
reserve `UPDATE` as a clause keyword), the whole `CREATE TABLE`
column list falls back to the legacy multi-line layout for that
statement.

## createTableColumnAlignment_breakwidth

Maximum character width of the third column (constraints, comments,
defaults, ...) in a `CREATE TABLE` column definition. When the third
column's content exceeds this width, it is wrapped onto a new continuation
line indented to align with the start of the third column.

Only takes effect when [`createTableColumnAlignment`](#createtablecolumnalignment)
is `true`. Ignored otherwise.

### Options

- a positive number (e.g. `30`) — wrap the "other" part to a new line when
its length exceeds this many characters.
- `0` — always wrap the "other" part to a new line, even when it's short.
- `Infinity` (default) — never wrap; the "other" part is always kept on the
same line as the column name and data type, regardless of length.

### Example

Given the following input:

```sql
CREATE TABLE tbl (a INT NOT NULL DEFAULT 1 COMMENT "a very long comment that exceeds the default expression width", b INT NOT NULL DEFAULT 1);
```

#### `createTableColumnAlignment_breakwidth: Infinity` (default)

```sql
CREATE TABLE tbl (
a INT NOT NULL DEFAULT 1 COMMENT "a very long comment that exceeds the default expression width",
b INT NOT NULL DEFAULT 1
);
```

#### `createTableColumnAlignment_breakwidth: 30`

The long "other" part of column `a` is wrapped to a continuation line
indented to align with the start of the third column:

```sql
CREATE TABLE tbl (
a INT
NOT NULL DEFAULT 1 COMMENT "a very long comment that exceeds the default expression width",
b INT NOT NULL DEFAULT 1
);
```

#### `createTableColumnAlignment_breakwidth: 0`

Every non-empty "other" part is wrapped to a continuation line:

```sql
CREATE TABLE tbl (
a INT
NOT NULL DEFAULT 1,
b INT
NOT NULL DEFAULT 1
);
```

10 changes: 10 additions & 0 deletions schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@
"type": "boolean",
"default": false
},
"createTableColumnAlignment": {
"description": "[Experimental] When true, aligns CREATE TABLE column definitions into three left-aligned columns: column name, column definition (data type), and the rest (constraints, comments, defaults, ...).",
"type": "boolean",
"default": false
},
"createTableColumnAlignment_breakwidth": {
"description": "[Experimental] Maximum character width of the third column (constraints, comments, defaults, ...) in a CREATE TABLE column definition. When the third column exceeds this width, it is wrapped to a new continuation line aligned with the start of the third column. Only takes effect when createTableColumnAlignment is true. Use 0 to always wrap. Defaults to Infinity (never wrap).",
"type": "number",
"minimum": 0
},
"expressionWidth": {
"description": "Determines maximum length of parenthesized expressions.",
"type": "number",
Expand Down
40 changes: 40 additions & 0 deletions src/FormatOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,44 @@ export interface FormatOptions {
newlineBeforeSemicolon: boolean;
params?: ParamItems | string[];
paramTypes?: ParamTypes;
/**
* When true, formats CREATE TABLE column definitions in a column-aligned
* layout: column name in the first column, column definition (data type)
* in the second column, and the remaining clauses (constraints, comments,
* defaults, ...) in the third column. All three columns are left-aligned
* and padded so the start of each column lines up across rows.
*
* Defaults to false (preserves the legacy single-space layout).
*
* Table-level constraints (e.g. PRIMARY KEY (...), FOREIGN KEY (...),
* CONSTRAINT ...) are not column definitions, so they are emitted on their
* own line without column padding.
*/
createTableColumnAlignment?: boolean;
/**
* Maximum character length of the "other" (third) column in a CREATE TABLE
* column-definition entry when `createTableColumnAlignment` is enabled.
*
* When the "other" part of a column (constraints, comments, defaults,
* ...) is shorter than or equal to this width, it is placed on the same
* line as the column name and data type:
*
* col_name data_type NOT NULL DEFAULT 1 COMMENT 'short'
*
* When it exceeds this width, it is wrapped to a new line, indented to
* align with the start of the "other" column (i.e. after the padded
* col_name + col_def + two separator spaces):
*
* col_name data_type
* NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
* CURRENT_TIMESTAMP COMMENT 'a very long comment'
*
* Defaults to `Infinity`, meaning the "other" part is always kept on the
* same line regardless of length (matches the v1 behavior of the option).
* Set to `0` to always wrap the "other" part to a new line.
*
* Only takes effect when `createTableColumnAlignment: true`. Ignored
* otherwise.
*/
createTableColumnAlignment_breakwidth?: number;
}
Loading