-
Notifications
You must be signed in to change notification settings - Fork 968
feat(expander): Add star expander for SELECT * and RETURNING * (PostgreSQL, MySQL, SQLite) #4203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+958
−3
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Adds a new expander package that expands * expressions in SQL queries to explicit column names by preparing the query against a PostgreSQL database. Features: - Expands SELECT * to explicit column list - Preserves table prefix for qualified stars (e.g., table.*) - Handles RETURNING * in INSERT/UPDATE/DELETE statements - Recursively expands CTEs, including dependent CTEs - Supports subqueries in FROM clause - Works with both cgo (pganalyze/pg_query_go) and non-cgo (wasilibs/go-pgquery) builds Example: SELECT * FROM authors → SELECT id, name, bio FROM authors 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Move expander from internal/engine/postgresql/expander to internal/x/expander and port it to use the internal AST types instead of pg_query nodes. Key changes: - Use internal AST types (*ast.SelectStmt, *ast.InsertStmt, etc.) - Use astutils.Search for star detection - Use ast.Format instead of pg_query deparse - Add Parser interface for dependency injection - Add test cases for COUNT(*) (should not be expanded) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
3ae2d2f to
475cfcf
Compare
- Rename TestExpand to TestExpandPostgreSQL - Add TestExpandMySQL for MySQL database support - Replace pgxpool.Pool with ColumnGetter interface for database-agnostic column resolution - Add PostgreSQLColumnGetter and MySQLColumnGetter implementations - MySQL tests skip edge cases (double star, star in middle) due to intermediate query formatting issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
MySQL doesn't support unqualified `*` mixed with other columns (e.g., `SELECT *, *` or `SELECT id, *, name`). These are valid PostgreSQL but invalid MySQL syntax. Update MySQL tests to use table-qualified stars which are valid: - `SELECT authors.*, authors.*` instead of `SELECT *, *` - `SELECT id, authors.*, name` instead of `SELECT id, *, name` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add TestExpandSQLite with 8 test cases using in-memory SQLite database - Rename MySQLColumnGetter to SQLColumnGetter since both MySQL and SQLite use the same database/sql-based implementation - SQLite supports the same star syntax as PostgreSQL (including `SELECT *, *` and `SELECT id, *, name`) Test results: - PostgreSQL: 14 tests - MySQL: 8 tests - SQLite: 8 tests 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Use PrepareContext to validate the query before executing it to get column metadata. While database/sql doesn't expose column names from prepared statements directly (unlike pgx), this at least validates the SQL syntax before execution. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Use the native sqlite3.Conn.Prepare and stmt.ColumnName/ColumnCount APIs to get column names without executing the query. This is more efficient and consistent with how PostgreSQL handles it. Changes: - Add SQLiteColumnGetter using native sqlite3.Conn - Rename SQLColumnGetter to MySQLColumnGetter (MySQL still needs to execute) - SQLite test now uses sqlite3.Open instead of sql.Open 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Update MySQLColumnGetter to use github.com/sqlc-dev/mysql fork with StmtMetadata interface for getting column names via prepare - Add replace directive to go.mod for the forked MySQL driver - Fix list formatting to use ", " separator instead of "," for proper SQL spacing (e.g., "SELECT id, name, bio" instead of "SELECT id,name,bio") - Update test expectations to reflect proper spacing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
3 tasks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Adds a new
expanderpackage underinternal/x/expander/that expands*expressions in SQL queries to explicit column names by preparing the query against a database.Features
SELECT *to explicit column listauthors.*→authors.id, authors.name, authors.bio)RETURNING *in INSERT/UPDATE/DELETE statements (PostgreSQL)ColumnGetterinterfaceSupported Databases
pgxpoolconnection to get column metadata viaPreparegithub.com/sqlc-dev/mysql) withStmtMetadatainterfacencruces/go-sqlite3API for column metadataExample
Test plan
🤖 Generated with Claude Code