Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
8b788af
fix(types): refuse a non-boolean unsigned when the type is rendered
vistart Oct 11, 2026
709544b
test(types): assert the unsigned refusal where it now happens
vistart Oct 11, 2026
42a3eeb
test(types): refuse the non-boolean flag at the render, for MEDIUMINT…
vistart Oct 11, 2026
6a70267
fix(mysql): converge the constraint switches onto the (self) probe pr…
vistart Oct 13, 2026
8ba84de
refactor(mysql): follow the statement and expression renames
vistart Oct 13, 2026
3d643d6
refactor(mysql): migrate constraints onto the two-level branch nodes
vistart Oct 14, 2026
0ae569c
refactor(mysql): split the wildcard by grammar position
vistart Oct 14, 2026
edf1279
ci: point testsuite at the matching branch
vistart Oct 14, 2026
a611b65
test(mysql): carry the wildcard-split follow-ups into the roundtrip m…
vistart Oct 14, 2026
034eae8
docs(mysql): carry the renames into the README and docs
vistart Oct 14, 2026
ec04b89
refactor(expression): follow the W3c class renames
vistart Oct 16, 2026
ee5f1f6
refactor(expression): follow the R1 signature alignment
vistart Oct 16, 2026
a6a7389
refactor(expression): name the arithmetic operation and class the agg…
vistart Oct 16, 2026
037bc6c
refactor(expression): build the aggregate through its class
vistart Oct 16, 2026
8961ea1
test(mysql): vendor the roundtrip harness the testsuite retired
vistart Oct 17, 2026
a7f3867
refactor(mysql): read declared fields instead of probing with getattr
vistart Oct 17, 2026
0af72eb
feat(mysql): adopt the typed value nodes with MySQL literal spellings
vistart Oct 18, 2026
ad70d93
fix(mysql): follow the classed function entry points and the bare VAL…
vistart Oct 18, 2026
cd47e79
fix(mysql): store the SHOW statement parameters under their declared …
vistart Oct 18, 2026
ddbd2fd
refactor(mysql): follow the ALTER action renames the core settled
vistart Oct 18, 2026
6ce2ea2
refactor(mysql): follow the literal architecture the core settled
vistart Oct 18, 2026
f3b3a66
fix(mysql): carry the params the artifact can spell
vistart Oct 19, 2026
a973e85
test(mysql): reconcile the roundtrip matrix with the plain-JSON artifact
vistart Oct 19, 2026
3c57bac
refactor(mysql): audit the kinds this backend overrides and owns
vistart Oct 19, 2026
58a10c2
refactor(mysql): name the formatter entry each kind dispatches to
vistart Oct 19, 2026
f4f502b
refactor(mysql): read declared fields instead of probing with getattr
vistart Oct 19, 2026
eb45de1
test(mysql): move the live-connection checks out of expression tests
vistart Oct 19, 2026
4b8f3cc
fix(mysql): reconcile the roundtrip matrix with the comparison and lo…
vistart Oct 19, 2026
e4c44f3
fix(mysql): write the locking clause from the strength phrase, not th…
vistart Oct 19, 2026
931b8ed
fix(mysql): compose the DDL-position values inline in the two tests t…
vistart Oct 19, 2026
b637e9d
fix(mysql): construct CustomType under the keyword-only raw signature
vistart Oct 19, 2026
d937a40
fix(mysql): compose collate over a Literal with the factory, not a chain
vistart Oct 19, 2026
76e7e55
fix(mysql): call the transaction setters by their current names
vistart Oct 19, 2026
35018b4
fix(mysql): vendor the parse round-trip sweep beside the roundtrip ha…
vistart Oct 19, 2026
4d42f89
fix(mysql): import CountFunction in the partition operations tests
vistart Oct 19, 2026
282b374
fix(mysql): pass the LIKE operator as its enum, not the SQL keyword
vistart Oct 20, 2026
ed70783
refactor(mysql): build introspection queries from nodes, not text
vistart Oct 20, 2026
f5971cb
refactor(mysql): render SHOW through its own expressions
vistart Oct 20, 2026
b223710
test(expression): drop the stale datetime pins and re-read the four t…
vistart Oct 20, 2026
d54d566
chore: ignore .worktree/, the branch toolchain directories
vistart Oct 21, 2026
32491fe
fix(mysql): the dialect surface, and the type positions it decides
vistart Oct 22, 2026
9a6606c
refactor(expression)!: follow core's statement rename
vistart Oct 22, 2026
d974d78
refactor(show)!: SHOW CREATE TABLE is a statement
vistart Oct 22, 2026
7e4a61b
fix(test): drop the stale _NOT_RENDERED row for ColumnGeneratedConstr…
vistart Oct 22, 2026
84d1def
refactor(expression)!: name statement nodes, kinds and formatters alike
vistart Oct 23, 2026
806c00b
refactor(backend)!: call the core helpers by their public names
vistart Oct 23, 2026
413626c
fix(introspection): take the cache from the manager, not the mixin
vistart Oct 23, 2026
b817dfc
refactor(introspection)!: render table options and partitions through…
vistart Oct 23, 2026
aa99a17
docs(cli): say what introspect can ask about
vistart Oct 24, 2026
ba5df38
refactor(cli): name the namespace after the engine, not after the slot
vistart Oct 24, 2026
89da55c
feat(cli): derive the introspect type list from the dialect
vistart Oct 24, 2026
62513b4
fix(partition): restore the return the inserted switch displaced
vistart Oct 24, 2026
4beecc3
refactor(mysql)!: drop the underscores from the introspection contract
vistart Oct 25, 2026
e7ac166
fix(mysql): declare the partitions family in the protocol that mirror…
vistart Oct 25, 2026
401a2d9
refactor(mysql): the storage-option and partition questions are state…
vistart Oct 25, 2026
8eeb802
feat(cli)!: the introspect table aggregate is gone
vistart Oct 26, 2026
8264f5e
fix(mysql): the introspect CLI asks the server what version it is
vistart Oct 27, 2026
65db7e2
test(transaction): the local copy becomes a shim over the shared cont…
vistart Oct 27, 2026
604f3eb
feat(cli): a catalogue family takes an optional name, and the type li…
vistart Oct 30, 2026
bcfc34f
test(cli): pin the type surface and what NAME means for each type
vistart Oct 30, 2026
e1a94a1
docs(cli): the introspect types, their names, and why SHOW stays in t…
vistart Oct 30, 2026
4244a97
fix(cli): a missing required name is an incomplete invocation, not a …
vistart Oct 30, 2026
40cd12e
test(cli): the surface test spells Optional, so 3.8 and 3.9 can colle…
vistart Oct 30, 2026
1db54f7
ci: install core from the release branch now that #127 has merged
vistart Oct 30, 2026
b990b7a
docs(changelog): the fragments for #62
vistart Oct 31, 2026
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
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
- name: Install activerecord and testsuite
run: |
pip install "rhosocial-activerecord @ git+https://github.com/rhosocial/python-activerecord.git@release/v1.0.0.dev30"
pip install "rhosocial-activerecord-testsuite @ git+https://github.com/rhosocial/python-activerecord-testsuite.git@release/v1.0.0.dev17"
pip install "rhosocial-activerecord-testsuite @ git+https://github.com/rhosocial/python-activerecord-testsuite.git@fix/column-constraint-gates"

Check warning on line 61 in .github/workflows/test.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Using dependencies without locking resolved versions is security-sensitive.

See more on https://sonarcloud.io/project/issues?id=rhosocial_python-activerecord-mysql&issues=AaGQaTgCXbG6mhdF8Hmm&open=AaGQaTgCXbG6mhdF8Hmm&pullRequest=62

- name: Create and test database
run: |
Expand Down Expand Up @@ -253,7 +253,7 @@
- name: Install activerecord and testsuite
run: |
pip install "rhosocial-activerecord @ git+https://github.com/rhosocial/python-activerecord.git@release/v1.0.0.dev30"
pip install "rhosocial-activerecord-testsuite @ git+https://github.com/rhosocial/python-activerecord-testsuite.git@release/v1.0.0.dev17"
pip install "rhosocial-activerecord-testsuite @ git+https://github.com/rhosocial/python-activerecord-testsuite.git@fix/column-constraint-gates"

Check warning on line 256 in .github/workflows/test.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Using dependencies without locking resolved versions is security-sensitive.

See more on https://sonarcloud.io/project/issues?id=rhosocial_python-activerecord-mysql&issues=AaGQaTgCXbG6mhdF8Hmo&open=AaGQaTgCXbG6mhdF8Hmo&pullRequest=62

Check warning on line 256 in .github/workflows/test.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Omitting "--only-binary :all:" can lead to the execution of setup scripts. Make sure it is safe here.

See more on https://sonarcloud.io/project/issues?id=rhosocial_python-activerecord-mysql&issues=AaGQaTgCXbG6mhdF8Hmn&open=AaGQaTgCXbG6mhdF8Hmn&pullRequest=62

- name: Create and test database
run: |
Expand Down Expand Up @@ -360,7 +360,7 @@
- name: Install activerecord and testsuite
run: |
pip install "rhosocial-activerecord @ git+https://github.com/rhosocial/python-activerecord.git@release/v1.0.0.dev30"
pip install "rhosocial-activerecord-testsuite @ git+https://github.com/rhosocial/python-activerecord-testsuite.git@release/v1.0.0.dev17"
pip install "rhosocial-activerecord-testsuite @ git+https://github.com/rhosocial/python-activerecord-testsuite.git@fix/column-constraint-gates"

Check warning on line 363 in .github/workflows/test.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Using dependencies without locking resolved versions is security-sensitive.

See more on https://sonarcloud.io/project/issues?id=rhosocial_python-activerecord-mysql&issues=AaGQaTgCXbG6mhdF8Hmq&open=AaGQaTgCXbG6mhdF8Hmq&pullRequest=62

Check warning on line 363 in .github/workflows/test.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Omitting "--only-binary :all:" can lead to the execution of setup scripts. Make sure it is safe here.

See more on https://sonarcloud.io/project/issues?id=rhosocial_python-activerecord-mysql&issues=AaGQaTgCXbG6mhdF8Hmp&open=AaGQaTgCXbG6mhdF8Hmp&pullRequest=62

- name: Create and test database
run: |
Expand Down
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -212,4 +212,9 @@ tests/config/mysql_scenarios.yml
# Claude Code temporary files (local only)
.claude/tmp/
.claude/plans/
.claude/plan/
.claude/plan/
# Worktrees for feature/* and fix/* branches. Never tracked: a `git add -A`
# from the repo root would commit each branch's whole toolchain -- the venv, the
# build directory and the test artifacts -- and the directory disappears when the
# branch merges, so the history would keep a second copy of the source tree.
.worktree/
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ from typing import ClassVar, Optional
from rhosocial.activerecord.base import FieldProxy
from rhosocial.activerecord.backend.impl.mysql.backend import MySQLBackend
from rhosocial.activerecord.backend.impl.mysql.config import MySQLConnectionConfig
from rhosocial.activerecord.backend.expression import CreateTableExpression
from rhosocial.activerecord.backend.expression import CreateTableStatement
from rhosocial.activerecord.backend.expression.statements import (
ColumnConstraint,
ColumnConstraintType,
ColumnDefinition,
ColumnPrimaryKeyConstraint,
)
from rhosocial.activerecord.backend.expression.types import IntegerType, VarCharType
from rhosocial.activerecord.model import ActiveRecord
Expand Down Expand Up @@ -77,7 +77,7 @@ User.configure(
# DDL is expressed, not stringified. Note that every node takes the dialect as
# its first argument, and column types are DataType instances, not strings.
dialect = User.__backend__.dialect
create_users = CreateTableExpression(
create_users = CreateTableStatement(
dialect,
"users",
columns=[
Expand All @@ -86,8 +86,7 @@ create_users = CreateTableExpression(
constraints=[
ColumnConstraint(
dialect,
ColumnConstraintType.PRIMARY_KEY,
is_auto_increment=True,
branch=ColumnPrimaryKeyConstraint(dialect, is_auto_increment=True),
)
],
),
Expand Down
1 change: 1 addition & 0 deletions changelog.d/62.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The introspect CLI offers one type per catalogue question and derives the list from `_TYPE_CAPABILITIES`, so a family cannot be listed without a dialect switch behind it; `views NAME` answers for one view. Typed value nodes with MySQL's own literal spellings, and `SHOW` rendered through its own expressions.
1 change: 1 addition & 0 deletions changelog.d/62.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Every catalogue question is a statement class plus a dialect `format_*_query_statement`, and the `SHOW` parameters are stored under their declared names. A `NAME` the type cannot use is refused with exit 2 instead of being ignored, and a missing required name exits 1.
1 change: 1 addition & 0 deletions changelog.d/62.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
`introspect database` no longer crashes on a fresh session (the parser read a private version that no adaptation had set), the introspect command adapts after connecting, a non-boolean `unsigned` is refused where the type is rendered, and `LIKE` takes its operator enum rather than the SQL keyword.
1 change: 1 addition & 0 deletions changelog.d/62.internal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The expression round-trip harness is vendored beside the matrix rather than imported from the test suite, the expression area runs in parallel, and CI installs core from `release/v1.0.0.dev30` now that core #127 has merged. The test suite stays on its own branch reference until that branch merges.
22 changes: 11 additions & 11 deletions docs/en_US/ddl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ The MySQL backend supports the same type-safe DDL expressions as the core librar

| Operation | MySQL Support | Notes |
|----------|--------------|-------|
| `CreateTableExpression` | ✅ Full | PRIMARY KEY, NOT NULL, UNIQUE, etc. |
| `DropTableExpression` | ✅ Full | IF EXISTS support |
| `AlterTableExpression` | ✅ Full | ADD/DROP COLUMN |
| `CreateIndexExpression` | ✅ Full | Index types (BTREE, HASH) |
| `DropIndexExpression` | ✅ Full | |
| `CreateViewExpression` | ✅ Full | MySQL ALGORITHM options |
| `DropViewExpression` | ✅ Full | |
| `CreateTableExpression` | ✅ Full | Partition support (RANGE, LIST, HASH, KEY) |
| `CreateTableStatement` | ✅ Full | PRIMARY KEY, NOT NULL, UNIQUE, etc. |
| `DropTableStatement` | ✅ Full | IF EXISTS support |
| `AlterTableStatement` | ✅ Full | ADD/DROP COLUMN |
| `CreateIndexStatement` | ✅ Full | Index types (BTREE, HASH) |
| `DropIndexStatement` | ✅ Full | |
| `CreateViewStatement` | ✅ Full | MySQL ALGORITHM options |
| `DropViewStatement` | ✅ Full | |
| `CreateTableStatement` | ✅ Full | Partition support (RANGE, LIST, HASH, KEY) |
| `PartitionByRange` | ✅ Full | RANGE and RANGE COLUMNS partitioning |
| `PartitionByList` | ✅ Full | LIST and LIST COLUMNS partitioning |
| `PartitionByHash` | ✅ Full | HASH and LINEAR HASH partitioning |
Expand All @@ -39,7 +39,7 @@ partition = MySQLPartitionByRange(
],
)

create_table = CreateTableExpression(
create_table = CreateTableStatement(
dialect,
table_name="orders",
columns=[...],
Expand All @@ -54,7 +54,7 @@ MySQL views support ALGORITHM to control execution:
```python
from rhosocial.activerecord.backend.expression import ViewOptions, ViewAlgorithm

create_view = CreateViewExpression(
create_view = CreateViewStatement(
dialect,
view_name="optimized_view",
query=query,
Expand All @@ -67,7 +67,7 @@ create_view = CreateViewExpression(
MySQL supports specifying storage engine:

```python
create_table = CreateTableExpression(
create_table = CreateTableStatement(
dialect,
table_name="users",
columns=columns,
Expand Down
38 changes: 19 additions & 19 deletions docs/en_US/mysql_specific_features/dialect.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ MySQL has some specific SQL syntax and functions. This section covers commonly u
MySQL supports copying table structure using the `LIKE` clause. This is useful for creating table backups or test tables with identical structure.

```python
from rhosocial.activerecord.backend.expression import CreateTableExpression
from rhosocial.activerecord.backend.expression import CreateTableStatement
from rhosocial.activerecord.backend.impl.mysql.dialect import MySQLDialect

# Basic usage - copy table structure
create_expr = CreateTableExpression(
create_expr = CreateTableStatement(
dialect=MySQLDialect(),
table_name="users_copy",
columns=[],
Expand All @@ -24,7 +24,7 @@ create_expr = CreateTableExpression(
# Generates: CREATE TABLE `users_copy` LIKE `users`

# With schema-qualified source table
create_expr = CreateTableExpression(
create_expr = CreateTableStatement(
dialect=MySQLDialect(),
table_name="users_copy",
columns=[],
Expand All @@ -33,7 +33,7 @@ create_expr = CreateTableExpression(
# Generates: CREATE TABLE `users_copy` LIKE `production`.`users`

# With TEMPORARY and IF NOT EXISTS
create_expr = CreateTableExpression(
create_expr = CreateTableStatement(
dialect=MySQLDialect(),
table_name="temp_users",
columns=[],
Expand All @@ -59,16 +59,16 @@ from rhosocial.activerecord.backend.expression.functions.datetime import (
current_timestamp, now,
)
from rhosocial.activerecord.backend.expression.statements import (
ColumnDefinition, ColumnConstraint, ColumnConstraintType,
ColumnDefinition, ColumnConstraint, ColumnDefaultConstraint,
)

# Correct: Use factory functions for SQL:2003 niladic functions
ColumnDefinition(
name='created_at',
data_type='TIMESTAMP',
constraints=[
ColumnConstraint(ColumnConstraintType.DEFAULT,
default_value=current_timestamp(dialect)),
ColumnConstraint(dialect,
branch=ColumnDefaultConstraint(dialect, current_timestamp(dialect))),
# Generates: `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
# (no parentheses — SQL:2003 niladic form)
],
Expand All @@ -79,8 +79,8 @@ ColumnDefinition(
name='updated_at',
data_type='DATETIME',
constraints=[
ColumnConstraint(ColumnConstraintType.DEFAULT,
default_value=now(dialect)),
ColumnConstraint(dialect,
branch=ColumnDefaultConstraint(dialect, now(dialect))),
# Generates: `updated_at` DATETIME DEFAULT NOW()
],
)
Expand All @@ -90,7 +90,7 @@ ColumnDefinition(
name='is_active',
data_type='TINYINT(1)',
constraints=[
ColumnConstraint(ColumnConstraintType.DEFAULT, default_value=1),
ColumnConstraint(dialect, branch=ColumnDefaultConstraint(dialect, 1)),
# Generates: `is_active` TINYINT(1) DEFAULT 1
],
)
Expand All @@ -100,7 +100,7 @@ ColumnDefinition(
name='status',
data_type='VARCHAR(20)',
constraints=[
ColumnConstraint(ColumnConstraintType.DEFAULT, default_value='active'),
ColumnConstraint(dialect, branch=ColumnDefaultConstraint(dialect, 'active')),
# Generates: `status` VARCHAR(20) DEFAULT 'active'
],
)
Expand All @@ -111,7 +111,7 @@ ColumnDefinition(
```python
# WRONG: Passing SQL keywords as Python strings
# This would generate DEFAULT 'CURRENT_TIMESTAMP' (quoted, treated as string literal)
ColumnConstraint(ColumnConstraintType.DEFAULT, default_value='CURRENT_TIMESTAMP')
ColumnConstraint(dialect, branch=ColumnDefaultConstraint(dialect, 'CURRENT_TIMESTAMP'))
```

**Common statement-level constants reference:**
Expand Down Expand Up @@ -176,32 +176,32 @@ class GroupConcat(FunctionExpression):

## Querying Runtime Functions and Constants

MySQL supports querying runtime functions without a data source, such as `SELECT CURRENT_TIMESTAMP`, `SELECT NOW()`, `SELECT VERSION()`. Use `QueryExpression` without specifying `from_` to achieve this.
MySQL supports querying runtime functions without a data source, such as `SELECT CURRENT_TIMESTAMP`, `SELECT NOW()`, `SELECT VERSION()`. Use `QueryStatement` without specifying `from_` to achieve this.

```python
from rhosocial.activerecord.backend.expression import QueryExpression
from rhosocial.activerecord.backend.expression import QueryStatement
from rhosocial.activerecord.backend.expression.core import FunctionCall, Literal
from rhosocial.activerecord.backend.expression.functions.datetime import (
current_timestamp, now, current_date, current_time,
)

# SELECT CURRENT_TIMESTAMP (niladic — no parentheses)
query = QueryExpression(
query = QueryStatement(
dialect=dialect,
select=[current_timestamp(dialect)],
)
sql, params = query.to_sql()
# Generates: SELECT CURRENT_TIMESTAMP

# SELECT NOW()
query = QueryExpression(
query = QueryStatement(
dialect=dialect,
select=[now(dialect)],
)
# Generates: SELECT NOW()

# SELECT CURRENT_DATE, CURRENT_TIME (niladic — no parentheses)
query = QueryExpression(
query = QueryStatement(
dialect=dialect,
select=[
current_date(dialect),
Expand All @@ -211,7 +211,7 @@ query = QueryExpression(
# Generates: SELECT CURRENT_DATE, CURRENT_TIME

# Multi-function query with aliases
query = QueryExpression(
query = QueryStatement(
dialect=dialect,
select=[
now(dialect).as_('current_time'),
Expand All @@ -222,7 +222,7 @@ query = QueryExpression(
# Generates: SELECT NOW() AS `current_time`, DATABASE() AS `db_name`, VERSION() AS `db_version`

# Function calls with arguments
query = QueryExpression(
query = QueryStatement(
dialect=dialect,
select=[
FunctionCall(dialect, 'DATE_FORMAT',
Expand Down
27 changes: 15 additions & 12 deletions docs/en_US/mysql_specific_features/introspection.md
Original file line number Diff line number Diff line change
Expand Up @@ -457,8 +457,8 @@ Supports configuration via command-line arguments or environment variables:
### Querying Table Details

```bash
# Get complete table info (columns, indexes, foreign keys)
python -m rhosocial.activerecord.backend.impl.mysql introspect table users \
# Describe one view
python -m rhosocial.activerecord.backend.impl.mysql introspect views users_v \
--database mydb --user root

# Query only column information
Expand All @@ -484,16 +484,19 @@ python -m rhosocial.activerecord.backend.impl.mysql introspect triggers users \

### Introspection Types

| Type | Description | Table Name Required |
|------|-------------|---------------------|
| `tables` | List all tables | No |
| `views` | List all views | No |
| `database` | Database information | No |
| `table` | Complete table details (columns, indexes, foreign keys) | Yes |
| `columns` | Column information | Yes |
| `indexes` | Index information | Yes |
| `foreign-keys` | Foreign key information | Yes |
| `triggers` | Trigger information | Optional |
| Type | Description | Name |
|------|-------------|------|
| `tables` | List all tables | not accepted |
| `views` | List all views, or describe one | optional (view) |
| `database` | Database information | not accepted |
| `columns` | Column information | required (table) |
| `indexes` | Index information | required (table) |
| `foreign-keys` | Foreign key information | required (table) |
| `triggers` | Trigger information | optional (table) |
| `table-options` | Engine, row format, collation and byte sizes of one table | optional (table) |
| `partitions` | One table's partitions | required (table) |

A name the type cannot use is refused (exit 2) rather than ignored.

### Output Formats

Expand Down
Loading
Loading