Skip to content

Conversation

@lucasbn
Copy link
Owner

@lucasbn lucasbn commented Jan 28, 2026

Summary

  • Generate instructions that read sqlite_schema (page 1) at runtime to find the target table's root page
  • Add four new VM instructions: String, Ne, Goto, OpenReadFromRegister
  • Remove hardcoded root page from generator, enabling queries on any table by name

Test plan

  • go test ./... passes
  • Verified with ./sqlite-clone sample.db "SELECT * FROM oranges;"
  • Verified with ./sqlite-clone sample.db "SELECT * FROM apples;"

🤖 Generated with Claude Code

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>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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, and OpenReadFromRegister to 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 Generate function signature to accept a resultConstructor parameter 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.

Comment on lines +32 to +58
// 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
}
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe T should be a "comparable" or something like that rather than any

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.

2 participants