Skip to content

feat(parser): MINUS as EXCEPT synonym for Snowflake/Oracle (#483)#494

Merged
ajitpratap0 merged 2 commits intomainfrom
feat/minus-as-except-483
Apr 8, 2026
Merged

feat(parser): MINUS as EXCEPT synonym for Snowflake/Oracle (#483)#494
ajitpratap0 merged 2 commits intomainfrom
feat/minus-as-except-483

Conversation

@ajitpratap0
Copy link
Copy Markdown
Owner

Summary

MINUS is a Snowflake and Oracle synonym for the `EXCEPT` set operator. Previously `SELECT id FROM a MINUS SELECT id FROM b` silently parsed as two separate statements with MINUS consumed as a table alias.

Implementation

  • New `isMinusSetOp` helper in `select_set_ops.go` — detects an identifier-token `MINUS` gated to Snowflake/Oracle.
  • Set-operation loop accepts it and normalizes the operator name to "EXCEPT" on the resulting `ast.SetOperation`.
  • FROM table-alias guard in `parseFromTableReference` (both branches) now refuses to consume MINUS as an alias in those dialects.

Test plan

  • `TestMinusAsExceptSynonym`: parses for both Snowflake and Oracle, asserts the AST has a single `SetOperation` with `Operator == "EXCEPT"`
  • `TestMinusNotSetOpInOtherDialects`: verifies PostgreSQL does not hijack MINUS
  • `go test -race ./pkg/sql/parser/ ./pkg/gosqlx/ ./pkg/sql/ast/` green

Part of #483.

🤖 Generated with Claude Code

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 8, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
gosqlx-website Ready Ready Preview, Comment Apr 8, 2026 2:02pm

@github-actions github-actions bot added the parser label Apr 8, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 8, 2026

Claude finished @ajitpratap0's task —— View job


PR Review: MINUS as EXCEPT Synonym Implementation

I'll review this PR for code quality, best practices, potential issues, performance, security, and test coverage.

Review Tasks

  • Read and analyze changed files
  • Review code quality and best practices
  • Check for potential bugs or issues
  • Evaluate performance considerations
  • Assess security concerns
  • Review test coverage
  • Provide comprehensive feedback

🔍 Code Review Findings

Overall Assessment: HIGH QUALITY

This is a well-implemented feature that follows GoSQLX patterns and best practices. The implementation is clean, safe, and thoroughly tested.

📋 Code Quality & Best Practices

Excellent:

  • Dialect-specific gating: select_set_ops.go:100-102 properly restricts MINUS to Snowflake/Oracle only
  • Normalization pattern: select_set_ops.go:54 correctly normalizes MINUS to "EXCEPT" in the AST for consistency
  • Safe type assertions: Test uses proper two-value form (minus_set_op_test.go:34-36)
  • Comprehensive error handling: Follows GoSQLX error patterns with structured errors
  • Documentation: Clear comments explaining the dialect-specific behavior

Good:

  • Follows existing GoSQLX parser patterns and conventions
  • Uses case-insensitive matching (strings.EqualFold) for SQL keywords
  • Proper integration with existing set operation parsing logic

🐛 Potential Issues: NONE FOUND

The implementation appears bug-free:

  • Properly handles dialect restrictions to prevent hijacking in other dialects
  • Correct precedence in table alias parsing guards
  • Safe token advancement and error handling

Performance Considerations: OPTIMAL

  • Zero overhead: Only adds isMinusSetOp() checks when parsing set operations
  • Short-circuit evaluation: Dialect check happens first in isMinusSetOp()
  • No memory allocations: Uses existing string comparison and token handling
  • Minimal impact: Only affects Snowflake/Oracle parsing paths

🔒 Security Concerns: NONE

  • No SQL injection vectors introduced
  • Proper input validation through existing tokenizer
  • Safe string handling with strings.EqualFold
  • No external dependencies or unsafe operations

🧪 Test Coverage: EXCELLENT

Comprehensive test scenarios:

  • TestMinusAsExceptSynonym: Tests both Snowflake and Oracle dialects
  • TestMinusNotSetOpInOtherDialects: Critical regression protection for PostgreSQL
  • ✅ Validates AST normalization to "EXCEPT"
  • ✅ Ensures no accidental hijacking in unsupported dialects

Test quality:

  • Uses proper test table pattern for dialects
  • Safe type assertions with error handling
  • Clear test documentation explaining regression protection

🔧 Implementation Details

File: select_set_ops.go

  • Lines 49-50: Clean integration into existing set operation loop
  • Lines 96-108: Well-structured helper function with proper guards
  • Follows left-associative parsing pattern correctly

File: select_subquery.go

  • Lines 104, 218: Smart addition to alias parsing guards prevents MINUS consumption as table alias

📝 Minor Suggestions

  1. Consider adding benchmark test (optional): Given the performance-critical nature of GoSQLX, a benchmark comparing parse performance with/without MINUS could be valuable
  2. Edge case documentation: The comments are excellent, but could mention the specific tokenization behavior of MINUS as identifier vs keyword

🎯 Summary

This is a high-quality implementation that:

  • ✅ Solves the stated problem correctly
  • ✅ Maintains backward compatibility
  • ✅ Follows all GoSQLX patterns and conventions
  • ✅ Includes comprehensive test coverage
  • ✅ Has zero performance or security impact
  • ✅ Is properly documented

Recommendation: APPROVE - This PR is ready to merge.


@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 8, 2026

Claude finished @ajitpratap0's task —— View job


PR Review: MINUS as EXCEPT Synonym Implementation

I'll review this PR for code quality, best practices, potential issues, performance, security, and test coverage.

Review Tasks

  • Read and analyze changed files
  • Review code quality and best practices
  • Check for potential bugs or issues
  • Evaluate performance considerations
  • Assess security concerns
  • Review test coverage
  • Provide comprehensive feedback

🔍 Code Review Findings

Overall Assessment: HIGH QUALITY

This is a well-implemented feature that follows GoSQLX patterns and best practices. The implementation is clean, safe, and thoroughly tested.

📋 Code Quality & Best Practices

Excellent:

  • Dialect-specific gating: select_set_ops.go:100-102 properly restricts MINUS to Snowflake/Oracle only
  • Normalization pattern: select_set_ops.go:54 correctly normalizes MINUS to "EXCEPT" in the AST for consistency
  • Safe type assertions: Test uses proper two-value form (minus_set_op_test.go:34-36)
  • Comprehensive error handling: Follows GoSQLX error patterns with structured errors
  • Documentation: Clear comments explaining the dialect-specific behavior

Good:

  • Follows existing GoSQLX parser patterns and conventions
  • Uses case-insensitive matching (strings.EqualFold) for SQL keywords
  • Proper integration with existing set operation parsing logic

🐛 Potential Issues: NONE FOUND

The implementation appears bug-free:

  • Properly handles dialect restrictions to prevent hijacking in other dialects
  • Correct precedence in table alias parsing guards
  • Safe token advancement and error handling

Performance Considerations: OPTIMAL

  • Zero overhead: Only adds isMinusSetOp() checks when parsing set operations
  • Short-circuit evaluation: Dialect check happens first in isMinusSetOp()
  • No memory allocations: Uses existing string comparison and token handling
  • Minimal impact: Only affects Snowflake/Oracle parsing paths

🔒 Security Concerns: NONE

  • No SQL injection vectors introduced
  • Proper input validation through existing tokenizer
  • Safe string handling with strings.EqualFold
  • No external dependencies or unsafe operations

🧪 Test Coverage: EXCELLENT

Comprehensive test scenarios:

  • TestMinusAsExceptSynonym: Tests both Snowflake and Oracle dialects
  • TestMinusNotSetOpInOtherDialects: Critical regression protection for PostgreSQL
  • ✅ Validates AST normalization to "EXCEPT"
  • ✅ Ensures no accidental hijacking in unsupported dialects

Test quality:

  • Uses proper test table pattern for dialects
  • Safe type assertions with error handling
  • Clear test documentation explaining regression protection

🔧 Implementation Details

File: select_set_ops.go

  • Lines 49-50: Clean integration into existing set operation loop
  • Lines 96-108: Well-structured helper function with proper guards
  • Follows left-associative parsing pattern correctly

File: select_subquery.go

  • Lines 104, 218: Smart addition to alias parsing guards prevents MINUS consumption as table alias

📝 Minor Suggestions

  1. Consider adding benchmark test (optional): Given the performance-critical nature of GoSQLX, a benchmark comparing parse performance with/without MINUS could be valuable
  2. Edge case documentation: The comments are excellent, but could mention the specific tokenization behavior of MINUS as identifier vs keyword

🎯 Summary

This is a high-quality implementation that:

  • ✅ Solves the stated problem correctly
  • ✅ Maintains backward compatibility
  • ✅ Follows all GoSQLX patterns and conventions
  • ✅ Includes comprehensive test coverage
  • ✅ Has zero performance or security impact
  • ✅ Is properly documented

Recommendation: APPROVE - This PR is ready to merge.


@ajitpratap0 ajitpratap0 merged commit d72b4d8 into main Apr 8, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant