Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions pkg/sql/parser/expressions.go
Original file line number Diff line number Diff line change
Expand Up @@ -557,11 +557,6 @@ func (p *Parser) isNumericLiteral() bool {
if p.currentToken.ModelType != modelTypeUnset {
return p.currentToken.ModelType == models.TokenTypeNumber
}
// String fallback for tokens created without ModelType
switch p.currentToken.Type {
case "INT", "NUMBER", "FLOAT":
return true
}
return false
}

Expand Down Expand Up @@ -866,7 +861,7 @@ func (p *Parser) parsePrimaryExpression() (ast.Expression, error) {
}

return nil, goerrors.UnexpectedTokenError(
string(p.currentToken.Type),
p.currentToken.ModelType.String(),
p.currentToken.Literal,
models.Location{Line: 0, Column: 0},
"",
Expand Down Expand Up @@ -1183,7 +1178,7 @@ func (p *Parser) parseSubquery() (ast.Statement, error) {

return nil, goerrors.ExpectedTokenError(
"SELECT or WITH",
string(p.currentToken.Type),
p.currentToken.ModelType.String(),
models.Location{Line: 0, Column: 0},
"",
)
Expand Down
53 changes: 34 additions & 19 deletions pkg/sql/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -661,10 +661,23 @@ func NewParser() *Parser {
//
//lint:ignore SA1019 intentional use during #215 migration
func (p *Parser) matchToken(expected token.Type) bool { //nolint:staticcheck // intentional use of deprecated type for Phase 1 bridge
// Convert both to strings for comparison
expectedStr := string(expected)
currentStr := string(p.currentToken.Type)
if currentStr == expectedStr {
if mt, ok := stringTypeToModelType[expected]; ok && mt != models.TokenTypeKeyword {
// Specific ModelType — use fast integer comparison
if p.currentToken.ModelType == mt {
p.advance()
return true
}
// Token may have generic ModelType (e.g., TokenTypeKeyword) if the converter
// didn't assign a specific type. Fall through to string comparison.
if p.currentToken.ModelType == models.TokenTypeKeyword &&
strings.EqualFold(string(p.currentToken.Type), string(expected)) {
p.advance()
return true
}
return false
}
// Generic keyword or unmapped token: compare strings
if strings.EqualFold(string(p.currentToken.Type), string(expected)) {
p.advance()
return true
}
Expand Down Expand Up @@ -984,14 +997,11 @@ func (p *Parser) isIdentifier() bool {
// Handles all string token subtypes (single-quoted, dollar-quoted, etc.)
// Also handles string fallback for tokens created without ModelType.
func (p *Parser) isStringLiteral() bool {
if p.currentToken.ModelType != modelTypeUnset {
switch p.currentToken.ModelType {
case models.TokenTypeString, models.TokenTypeSingleQuotedString, models.TokenTypeDollarQuotedString:
return true
}
return false
switch p.currentToken.ModelType {
case models.TokenTypeString, models.TokenTypeSingleQuotedString, models.TokenTypeDollarQuotedString:
return true
}
return p.currentToken.Type == "STRING"
return false
}

// isComparisonOperator checks if the current token is a comparison operator using O(1) switch.
Expand Down Expand Up @@ -1028,7 +1038,7 @@ func (p *Parser) isBooleanLiteral() bool {

// expectedError returns an error for unexpected token
func (p *Parser) expectedError(expected string) error {
return goerrors.ExpectedTokenError(expected, string(p.currentToken.Type), p.currentLocation(), "")
return goerrors.ExpectedTokenError(expected, p.currentToken.ModelType.String(), p.currentLocation(), "")
}

// parseIdent parses an identifier
Expand Down Expand Up @@ -1104,15 +1114,20 @@ func (p *Parser) parseTableReference() (*ast.TableReference, error) {
// isNonReservedKeyword checks if current token is a non-reserved keyword
// that can be used as a table or column name
func (p *Parser) isNonReservedKeyword() bool {
// These keywords can be used as table/column names in most SQL dialects
// Check uppercase version of token type for case-insensitive matching
upperType := strings.ToUpper(string(p.currentToken.Type))
switch upperType {
case "TARGET", "SOURCE", "MATCHED", "VALUE", "NAME", "TYPE", "STATUS":
// These keywords can be used as table/column names in most SQL dialects.
// Use ModelType where possible, with literal fallback for tokens that have
// the generic TokenTypeKeyword.
switch p.currentToken.ModelType {
case models.TokenTypeTarget, models.TokenTypeSource, models.TokenTypeMatched:
return true
default:
return false
case models.TokenTypeKeyword:
// Token may have generic ModelType; check literal for specific keywords
switch strings.ToUpper(p.currentToken.Literal) {
case "TARGET", "SOURCE", "MATCHED", "VALUE", "NAME", "TYPE", "STATUS":
return true
}
}
return false
}

// canBeAlias checks if current token can be used as an alias
Expand Down
9 changes: 0 additions & 9 deletions pkg/sql/parser/recovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,6 @@ func (p *Parser) isStatementStartingKeyword() bool {
return true
}
}
// Fallback: string comparison for tokens without ModelType (e.g., tests)
switch string(p.currentToken.Type) {
case "SELECT", "INSERT", "UPDATE", "DELETE", "CREATE", "ALTER", "DROP",
"WITH", "MERGE", "REFRESH", "TRUNCATE",
"EXPLAIN", "ANALYZE", "SHOW", "DESCRIBE", "GRANT", "REVOKE",
"SET", "USE", "BEGIN", "COMMIT", "ROLLBACK", "VACUUM",
"CALL", "EXECUTE":
return true
}
return false
}

Expand Down
8 changes: 4 additions & 4 deletions pkg/sql/parser/select.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func (p *Parser) parseColumnDef() (*ast.ColumnDef, error) {
if name == nil {
return nil, goerrors.ExpectedTokenError(
"column name",
string(p.currentToken.Type),
p.currentToken.ModelType.String(),
p.currentLocation(),
"",
)
Expand All @@ -29,7 +29,7 @@ func (p *Parser) parseColumnDef() (*ast.ColumnDef, error) {
if dataType == nil {
return nil, goerrors.ExpectedTokenError(
"data type",
string(p.currentToken.Type),
p.currentToken.ModelType.String(),
p.currentLocation(),
"",
)
Expand Down Expand Up @@ -651,7 +651,7 @@ func (p *Parser) parseSelectStatement() (ast.Statement, error) {
if !p.isType(models.TokenTypeJoin) {
return nil, goerrors.ExpectedTokenError(
"JOIN after "+joinType,
string(p.currentToken.Type),
p.currentToken.ModelType.String(),
p.currentLocation(),
"",
)
Expand Down Expand Up @@ -705,7 +705,7 @@ func (p *Parser) parseSelectStatement() (ast.Statement, error) {
if err != nil {
return nil, goerrors.ExpectedTokenError(
"table name after "+joinType+" JOIN",
string(p.currentToken.Type),
p.currentToken.ModelType.String(),
p.currentLocation(),
"",
)
Expand Down
Loading