Skip to content

refactor(schema): treat srid, dimensions and auto-increment as type parameters - #19

Merged
abnegate merged 1 commit into
mainfrom
refactor/untangle-internal-modifier-calls
Aug 14, 2026
Merged

refactor(schema): treat srid, dimensions and auto-increment as type parameters#19
abnegate merged 1 commit into
mainfrom
refactor/untangle-internal-modifier-calls

Conversation

@abnegate

Copy link
Copy Markdown
Member

Stacked on #18#17#16#15. Closes the entanglement I flagged as out of scope there.

The blocker, and why it dissolved

These three modifiers were dropped by dialects that can't emit them, but I couldn't move them in #18 because the library's own factories called them:

Table::point()        -> $col->srid($srid);
Table::id()           -> $col->autoIncrement();
Trait\Serial          -> $col->autoIncrement();
Table\*::vector()     -> $col->dimensions($dimensions);

Moving the modifier would have broken the factory on exactly the dialects that needed it.

The block turned out to be framing. srid and dimensions aren't modifiers at all — they're intrinsic to the column, the way length is. POINT SRID 3857, VECTOR(384): both are part of the column type, and the factories already take them as arguments. So they belong in the constructor next to length/precision/scale, threaded through newColumn(), with the auto-increment flag beside them.

Once the factories stop going through the public modifiers, the modifiers are free to live only where the value is emitted:

Modifier Now on Emits
srid() MySQL, MariaDB, PostgreSQL POINT SRID 3857, GEOMETRY(POINT, 3857)
dimensions() PostgreSQL VECTOR(384)
autoIncrement() MySQL, MariaDB, PostgreSQL, SQLite AUTO_INCREMENT, IDENTITY, AUTOINCREMENT

Callers are unaffected

point($name, $srid), id() and serial() still work on every dialect and still record the values — only the standalone modifiers are scoped. Verified byte-identical DDL against the pre-change output for all five dialects:

MySQL       id()     : CREATE TABLE `t` (`id` BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (`id`))
PostgreSQL  point()  : CREATE TABLE "t" ("g" GEOMETRY(POINT, 3857) NOT NULL)
SQLite      serial() : CREATE TABLE `t` (`s` INTEGER AUTOINCREMENT NOT NULL)
ClickHouse  id()     : CREATE TABLE `t` (`id` UInt64) ENGINE = MergeTree() ORDER BY (`id`)
PostgreSQL  vector() : CREATE TABLE "t" ("e" VECTOR(384) NOT NULL)

A test pins both halves: the modifier is absent on ClickHouse/MongoDB/SQLite while id()/serial()/point() still set isAutoIncrement and srid there.

One signature change

Table\ClickHouse::vector() and Table\MongoDB::vector() lose their $dimensions parameter. Array(Float64) and the array bsonType are unsized, so it could never be honoured — and two existing tests passed 768 while asserting output that ignored it:

->vector('embedding', 768)
// CREATE TABLE `embeddings` (`embedding` Array(Float64)) ENGINE = MergeTree() ...
//                                        ↑ 768 nowhere

That's the clearest evidence it was never wired to anything. Table\PostgreSQL::vector($name, $dimensions) keeps it, because PostgreSQL emits it.

Left as the one known gap

unsigned() stays on every dialect. It renders nothing on PostgreSQL and SQLite, but through an explicit overridable compileUnsigned() hook returning '' — a deliberate dialect mapping, not an oversight. It's the single remaining entry in the README's "Known gaps" note.

Test plan

  • composer test — 5323 tests, 12383 assertions, all pass (was 5321)
  • composer check — PHPStan level max, no errors
  • composer lint — pass
  • DDL output diffed against pre-change for all five dialects across id(), point(), serial(), vector() — identical

Integration tests need Docker and were not run locally; CI covers them.

🤖 Generated with Claude Code

…arameters

These three were the entanglement left over from the previous commit. The
modifiers were dropped by dialects that cannot emit them, but they could
not simply be moved, because the library's own factories called them:
Table::point() called srid(), Table::id() and Trait\Serial called
autoIncrement(), and the three vector() factories called dimensions().

The block was framing. srid and dimensions are intrinsic to the column the
way length is -- POINT SRID 3857, VECTOR(384) -- not modifiers applied
afterwards, and the factories already receive them as arguments. So they
move into Column::__construct() alongside length/precision/scale, threaded
through newColumn(), with auto-increment as a flag beside them.

That frees the modifiers to live only where the value is emitted:

  srid()           MySQL, MariaDB, PostgreSQL
  dimensions()     PostgreSQL
  autoIncrement()  MySQL, MariaDB, PostgreSQL, SQLite

The factories are untouched from a caller's perspective: point($name,
$srid), id() and serial() work on every dialect and still record the
values, so portable schema code is unaffected and every dialect emits
byte-identical DDL.

Table\ClickHouse::vector() and Table\MongoDB::vector() lose their
$dimensions parameter. Array(Float64) and the array bsonType are unsized,
so the argument could never be honoured -- two existing tests passed 768
and asserted output that ignored it, which is the clearest evidence it was
never wired to anything.

unsigned() stays on every dialect: it renders nothing on PostgreSQL and
SQLite, but through an explicit overridable compileUnsigned() hook, which
is a deliberate mapping rather than an oversight. It remains the single
documented known gap.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

📊 Coverage

Metric Covered Ratio
Lines 91.87% 7454 / 8114
Methods 84.13% 1108 / 1317
Classes 65.45% 144 / 220

Full per-file breakdown in the job summary.

@greptile-apps

greptile-apps Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR moves SRID, vector dimensions, and auto-increment state into column construction while limiting their standalone modifiers to dialects that emit them.

  • Threads intrinsic type state through Table::newColumn() and dialect overrides.
  • Adds dialect-specific SRID, dimensions, and auto-increment traits.
  • Removes unused vector dimensions from ClickHouse and MongoDB APIs and updates documentation and focused tests.

Confidence Score: 4/5

The PR should not merge until the base fluent-builder test is updated or the base Column autoIncrement() contract is restored.

The changed base Column no longer exposes autoIncrement(), while an unchanged test directly invokes that method on a base Column and will fail with an undefined-method error.

Files Needing Attention: src/Query/Schema/Column.php, tests/Query/Schema/FluentBuilderTest.php

Important Files Changed

Filename Overview
src/Query/Schema/Column.php Adds intrinsic constructor state but removes a base fluent method that an unchanged test still invokes.
src/Query/Schema/Table.php Threads SRID and auto-increment state directly through newColumn() for generic factories.
src/Query/Schema/Table/PostgreSQL.php Preserves PostgreSQL vector dimensions through the expanded column factory contract.
src/Query/Schema/Table/ClickHouse.php Removes the previously ignored vector-dimensions parameter and forwards the expanded constructor state.
src/Query/Schema/Table/MongoDB.php Removes the previously ignored vector-dimensions parameter and retains intrinsic factory state.
tests/Query/Schema/FluentBuilderTest.php Adds dialect-scoping assertions but leaves an existing base-Column autoIncrement() invocation that now fails.

Fix all with Greploop

Fix All in Claude Code Fix All in Codex

Prompt To Fix All With AI
### Issue 1
src/Query/Schema/Column.php:73-82
**Base auto-increment method removed**

When `FluentBuilderTest::testColumnReturnsItselfForChainingFluentMethods` creates a base `Column`, the test still calls `autoIncrement()`, but this change removes that method from the base class, causing the test suite to terminate with an undefined-method error.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "refactor(schema): treat srid, dimensions..." | Re-trigger Greptile

Comment thread src/Query/Schema/Column.php
Base automatically changed from refactor/remove-silent-drops to main August 14, 2026 01:42
@abnegate
abnegate merged commit c334515 into main Aug 14, 2026
7 checks passed
@abnegate
abnegate deleted the refactor/untangle-internal-modifier-calls branch August 14, 2026 01:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant