Add dynamic schema table lookup via generated instructions#8
Add dynamic schema table lookup via generated instructions#8
Conversation
Instead of hardcoding the root page, the generator now produces instructions that read the sqlite_schema table (page 1) at runtime to find the target table's root page. This enables querying any table by name. New instructions: - String: Load string constant into register - Ne: Conditional jump if registers not equal - Goto: Unconditional jump - OpenReadFromRegister: Open cursor using page from register Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This pull request implements dynamic schema table lookup by generating bytecode that queries the sqlite_schema table at runtime to find a target table's root page number. This removes the hardcoded root page assumption from the generator, enabling queries on any table by name.
Changes:
- Added four new VM instructions:
String,Ne,Goto, andOpenReadFromRegisterto support dynamic schema lookup and conditional branching - Modified the generator to produce bytecode that searches the schema table (page 1) for the target table and extracts its root page
- Updated the
Generatefunction signature to accept aresultConstructorparameter for creating typed values
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| app/main.go | Updated call to generator.Generate to pass &types.EntryConstructor{} as the new required parameter |
| app/machine/instructions/string.go | New instruction that stores a string value (constructed as type T) into a register |
| app/machine/instructions/open_read_from_register.go | New instruction that opens a cursor using a root page number read from a register |
| app/machine/instructions/ne.go | New instruction that compares two register values and jumps if they are not equal |
| app/machine/instructions/goto.go | New instruction that performs an unconditional jump to a specified address |
| app/generator/generator.go | Complete rewrite to generate schema lookup bytecode, extract table name from SQL, and handle dynamic table lookup |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // compareValues compares two values for equality. It handles the specific | ||
| // Entry types used by this SQLite clone. | ||
| func compareValues[T any](a, b T) bool { | ||
| // Type assert to Entry interface and compare based on type | ||
| aEntry, aOk := any(a).(types.Entry) | ||
| bEntry, bOk := any(b).(types.Entry) | ||
|
|
||
| if !aOk || !bOk { | ||
| return false | ||
| } | ||
|
|
||
| switch aVal := aEntry.(type) { | ||
| case types.TextEntry: | ||
| if bVal, ok := bEntry.(types.TextEntry); ok { | ||
| return aVal.Value == bVal.Value | ||
| } | ||
| case types.NumberEntry: | ||
| if bVal, ok := bEntry.(types.NumberEntry); ok { | ||
| return aVal.Value == bVal.Value | ||
| } | ||
| case types.NullEntry: | ||
| _, ok := bEntry.(types.NullEntry) | ||
| return ok | ||
| } | ||
|
|
||
| return false | ||
| } |
There was a problem hiding this comment.
The compareValues function has hardcoded logic for the types.Entry interface and its concrete types (TextEntry, NumberEntry, NullEntry). This creates a tight coupling between a generic instruction and a specific type system, defeating the purpose of the generic T parameter.
Similar to OpenReadFromRegister, this should either be made non-generic (working only with Entry types) or refactored to use a more flexible comparison mechanism. Consider adding a comparison method to a constraint interface or making the instruction non-generic.
There was a problem hiding this comment.
Maybe T should be a "comparable" or something like that rather than any
Summary
sqlite_schema(page 1) at runtime to find the target table's root pageString,Ne,Goto,OpenReadFromRegisterTest plan
go test ./...passes./sqlite-clone sample.db "SELECT * FROM oranges;"./sqlite-clone sample.db "SELECT * FROM apples;"🤖 Generated with Claude Code