Why
norm.generator.Column, norm.generator.Query, norm.generator.Catalog, norm.generator.Schema,
and norm.generator.Identifier still carry fields from the sqlc/Wire-proto era. The JDBC analyzer
never assigns them and no generator code reads them, so every reader of the model has to work out
which properties are live. Two documentation locations still describe the proto pipeline that no
longer exists.
Out of scope, deliberately: Column.embedTable, the sqlc.embed() branch in
TypeRepository.buildTypeProjectionForQuery, getTypeProjectionForTable's columnOffset, and the
four *_embeds scenarios. Embed support is planned (README TODO); leave every trace of it alone.
Current state (verified by git grep over generator/src/main and all src/test trees)
Declared in generator/src/main/kotlin/norm/generator/Model.kt, never assigned by
norm.generator.JdbcAnalyzer or norm.generator.PgCatalogLoader, never read anywhere, never
named in any test:
| Type |
Field |
Notes |
Column |
isNamedParam, isFuncCall, scope, tableAlias, isSqlcSlice, unsigned, length |
The word unsigned appears in e2e-tests/.../PlainArrayE2ETest.kt; confirm it is prose, not the field |
Query |
insertIntoTable |
|
Catalog |
name, comment |
Only defaultSchema and schemas are ever passed (JdbcAnalyzer.kt:47-50) |
Catalog |
defaultSchema |
Assigned at JdbcAnalyzer.kt:48, never read |
Schema |
comment, compositeTypes |
Schema(...) constructed once, JdbcAnalyzer.kt:39-44 |
CompositeType |
whole class |
Only referenced by Schema.compositeTypes |
Identifier |
catalog |
Every constructor call passes name/schema only |
Also populated but never read:
norm.generator.CteDefinition.hasColumnList (SqlCteClause.kt:32, set at :132-134). Its own
KDoc says no caller consults it.
norm.generator.ParsedCteClause.isRecursive (SqlCteClause.kt:49, set at :79).
- The alias-name
Set<String> half of parseOldNewAliasPrologue's return value
(SqlOutputClause.kt:475-487). The only caller (:175) takes .second. parseOldNewAliasName
(:501-513) exists solely to feed that discarded set.
Stale documentation:
JdbcAnalyzer.kt:10-11 says the analyzer "Produces the same Wire protobuf types". The model is
plain Kotlin data classes.
CLAUDE.md lists a proto/ module and says the model types are "Wire proto types from
proto/codegen.proto". git ls-files proto is empty.
PgNodeExpression.kt:263 refers to CteDefinition "in SqlUtils.kt". The file is
SqlCteClause.kt.
Target state
- Delete every field in the table above and the
CompositeType class. Update each type's
@property KDoc to match.
- Delete
CteDefinition.hasColumnList and its assignment; parseSingleCteDefinition still has to
skip the column list, it just stops recording that it did.
- Delete
ParsedCteClause.isRecursive. parseCteClause still skips the RECURSIVE keyword.
- Change
parseOldNewAliasPrologue to return Int (the item-list start index) and delete
parseOldNewAliasName. Keep the KDoc sentence explaining what the prologue is and why it must be
skipped.
- Fix the three stale documentation references. In
CLAUDE.md, remove the proto/ module from
the tree, remove "Wire" from Key Technologies, and reword the pipeline step and Key Files entries
that mention proto types to say "the model data classes in generator/.../Model.kt".
Test design
Deletion of unread code has no new behavior to pin. Proof is compilation plus the existing suite:
generator/src/test/kotlin/norm/generator/SqlCteClauseTest.kt and SqlOutputClauseTest.kt must
still pass unchanged; neither references the removed members (verified by grep). If either fails to
compile, a reference was missed, not a test that needs rewriting.
- No test may be deleted or weakened by this change.
Acceptance criteria
- None of the identifiers listed under "Current state" appear in
generator/src/main,
gradle-plugin/src/main, or any src/test tree (git grep returns nothing for each).
Column.embedTable, TypeRepository.getTypeProjectionForTable(table, columnOffset), and the
embedTable != null branches are byte-identical to before.
./gradlew :generator:check :gradle-plugin:test passes.
./gradlew :gradle-plugin:generateGoldenFiles then git status --porcelain test-scenarios test-scenarios-frameworks prints nothing.
git grep -n "Wire\|codegen.proto\|SqlUtils" -- CLAUDE.md generator/src/main prints nothing.
Files
generator/src/main/kotlin/norm/generator/Model.kt
generator/src/main/kotlin/norm/generator/JdbcAnalyzer.kt (buildCatalog, class KDoc)
generator/src/main/kotlin/norm/generator/SqlCteClause.kt
generator/src/main/kotlin/norm/generator/SqlOutputClause.kt
generator/src/main/kotlin/norm/generator/PgNodeExpression.kt (one KDoc line)
CLAUDE.md
Conventions every issue inherits
- Repo root:
/Volumes/Code/3rd-party/norm. Module under change is almost always generator/.
- Style: 2-space indent, 120 columns, full words in identifiers (
parameter, not param), no
section-separator comments, @Nested classes group tests. Format with ./gradlew spotlessApply.
- TDD: tests are written first or alongside. For a behavior-preserving refactor the existing suite is
the pin; each issue says which tests must also be added.
- Golden files under
test-scenarios*/ are never hand-edited. A refactor is behavior-preserving only
if ./gradlew :gradle-plugin:generateGoldenFiles leaves git status --porcelain test-scenarios test-scenarios-frameworks empty.
- Verification for a
generator/ change: ./gradlew :generator:check :gradle-plugin:test (Docker
required). Then the golden regeneration check above.
- Commit message explains the design decision, not the diff.
- Never run
./gradlew clean or disable the configuration/build cache to "fix" a build problem.
Why
norm.generator.Column,norm.generator.Query,norm.generator.Catalog,norm.generator.Schema,and
norm.generator.Identifierstill carry fields from the sqlc/Wire-proto era. The JDBC analyzernever assigns them and no generator code reads them, so every reader of the model has to work out
which properties are live. Two documentation locations still describe the proto pipeline that no
longer exists.
Out of scope, deliberately:
Column.embedTable, thesqlc.embed()branch inTypeRepository.buildTypeProjectionForQuery,getTypeProjectionForTable'scolumnOffset, and thefour
*_embedsscenarios. Embed support is planned (README TODO); leave every trace of it alone.Current state (verified by
git grepovergenerator/src/mainand allsrc/testtrees)Declared in
generator/src/main/kotlin/norm/generator/Model.kt, never assigned bynorm.generator.JdbcAnalyzerornorm.generator.PgCatalogLoader, never read anywhere, nevernamed in any test:
ColumnisNamedParam,isFuncCall,scope,tableAlias,isSqlcSlice,unsigned,lengthunsignedappears ine2e-tests/.../PlainArrayE2ETest.kt; confirm it is prose, not the fieldQueryinsertIntoTableCatalogname,commentdefaultSchemaandschemasare ever passed (JdbcAnalyzer.kt:47-50)CatalogdefaultSchemaJdbcAnalyzer.kt:48, never readSchemacomment,compositeTypesSchema(...)constructed once,JdbcAnalyzer.kt:39-44CompositeTypeSchema.compositeTypesIdentifiercatalogname/schemaonlyAlso populated but never read:
norm.generator.CteDefinition.hasColumnList(SqlCteClause.kt:32, set at:132-134). Its ownKDoc says no caller consults it.
norm.generator.ParsedCteClause.isRecursive(SqlCteClause.kt:49, set at:79).Set<String>half ofparseOldNewAliasPrologue's return value(
SqlOutputClause.kt:475-487). The only caller (:175) takes.second.parseOldNewAliasName(
:501-513) exists solely to feed that discarded set.Stale documentation:
JdbcAnalyzer.kt:10-11says the analyzer "Produces the same Wire protobuf types". The model isplain Kotlin data classes.
CLAUDE.mdlists aproto/module and says the model types are "Wire proto types fromproto/codegen.proto".git ls-files protois empty.PgNodeExpression.kt:263refers toCteDefinition"inSqlUtils.kt". The file isSqlCteClause.kt.Target state
CompositeTypeclass. Update each type's@propertyKDoc to match.CteDefinition.hasColumnListand its assignment;parseSingleCteDefinitionstill has toskip the column list, it just stops recording that it did.
ParsedCteClause.isRecursive.parseCteClausestill skips theRECURSIVEkeyword.parseOldNewAliasPrologueto returnInt(the item-list start index) and deleteparseOldNewAliasName. Keep the KDoc sentence explaining what the prologue is and why it must beskipped.
CLAUDE.md, remove theproto/module fromthe tree, remove "Wire" from Key Technologies, and reword the pipeline step and Key Files entries
that mention proto types to say "the model data classes in
generator/.../Model.kt".Test design
Deletion of unread code has no new behavior to pin. Proof is compilation plus the existing suite:
generator/src/test/kotlin/norm/generator/SqlCteClauseTest.ktandSqlOutputClauseTest.ktmuststill pass unchanged; neither references the removed members (verified by grep). If either fails to
compile, a reference was missed, not a test that needs rewriting.
Acceptance criteria
generator/src/main,gradle-plugin/src/main, or anysrc/testtree (git grepreturns nothing for each).Column.embedTable,TypeRepository.getTypeProjectionForTable(table, columnOffset), and theembedTable != nullbranches are byte-identical to before../gradlew :generator:check :gradle-plugin:testpasses../gradlew :gradle-plugin:generateGoldenFilesthengit status --porcelain test-scenarios test-scenarios-frameworksprints nothing.git grep -n "Wire\|codegen.proto\|SqlUtils" -- CLAUDE.md generator/src/mainprints nothing.Files
generator/src/main/kotlin/norm/generator/Model.ktgenerator/src/main/kotlin/norm/generator/JdbcAnalyzer.kt(buildCatalog, class KDoc)generator/src/main/kotlin/norm/generator/SqlCteClause.ktgenerator/src/main/kotlin/norm/generator/SqlOutputClause.ktgenerator/src/main/kotlin/norm/generator/PgNodeExpression.kt(one KDoc line)CLAUDE.mdConventions every issue inherits
/Volumes/Code/3rd-party/norm. Module under change is almost alwaysgenerator/.parameter, notparam), nosection-separator comments,
@Nestedclasses group tests. Format with./gradlew spotlessApply.the pin; each issue says which tests must also be added.
test-scenarios*/are never hand-edited. A refactor is behavior-preserving onlyif
./gradlew :gradle-plugin:generateGoldenFilesleavesgit status --porcelain test-scenarios test-scenarios-frameworksempty.generator/change:./gradlew :generator:check :gradle-plugin:test(Dockerrequired). Then the golden regeneration check above.
./gradlew cleanor disable the configuration/build cache to "fix" a build problem.