feat: parse multiple conditionals and capture conditional extension

This commit is contained in:
Yehoshua Sandler 2025-04-17 13:21:11 -05:00
parent 87bc13631a
commit 28d041e244
2 changed files with 47 additions and 2 deletions

View File

@ -137,6 +137,14 @@ func ParseSelectStatement(sql string) Select {
if !passedWHERE && token.Type == sqllexer.KEYWORD && strings.ToUpper(token.Value) == "WHERE" { if !passedWHERE && token.Type == sqllexer.KEYWORD && strings.ToUpper(token.Value) == "WHERE" {
passedWHERE = true passedWHERE = true
continue continue
} else if !passedWHERE && token.Type == sqllexer.KEYWORD && strings.ToUpper(token.Value) != "WHERE" {
passedWHERE = true
}
if passedWHERE && !passedConditionals {
if token.Type == sqllexer.KEYWORD && strings.ToUpper(token.Value) != "AND" && strings.ToUpper(token.Value) != "OR" && strings.ToUpper(token.Value) != "NOT" {
passedConditionals = true
}
} }
if passedWHERE && !passedConditionals { if passedWHERE && !passedConditionals {
@ -146,20 +154,26 @@ func ParseSelectStatement(sql string) Select {
workingConditional.Operator = token.Value workingConditional.Operator = token.Value
} else if token.Type == sqllexer.BOOLEAN || token.Type == sqllexer.NULL || token.Type == sqllexer.STRING || token.Type == sqllexer.NUMBER { } else if token.Type == sqllexer.BOOLEAN || token.Type == sqllexer.NULL || token.Type == sqllexer.STRING || token.Type == sqllexer.NUMBER {
workingConditional.Value = token.Value workingConditional.Value = token.Value
} else if token.Type == sqllexer.KEYWORD {
if strings.ToUpper(token.Value) == "AND" || strings.ToUpper(token.Value) == "OR" {
workingConditional.Extension = strings.ToUpper(token.Value)
}
} }
if workingConditional.Key != "" && workingConditional.Operator != "" && workingConditional.Value != "" { if workingConditional.Key != "" && workingConditional.Operator != "" && workingConditional.Value != "" {
query.Conditionals = append(query.Conditionals, workingConditional) query.Conditionals = append(query.Conditionals, workingConditional)
workingConditional = Conditional{} workingConditional = Conditional{}
passedConditionals = true }
if IsTokenEndOfStatement(token) {
break
} }
continue continue
} }
// Checking For ORDER BY // Checking For ORDER BY
if !passedOrderByKeywords && token.Type == sqllexer.KEYWORD { if passedConditionals && !passedOrderByKeywords && token.Type == sqllexer.KEYWORD {
unshiftBuffer(&lookBehindBuffer, *token) unshiftBuffer(&lookBehindBuffer, *token)
if strings.ToUpper(lookBehindBuffer[1].Value) == "ORDER" && strings.ToUpper(lookBehindBuffer[0].Value) == "BY" { if strings.ToUpper(lookBehindBuffer[1].Value) == "ORDER" && strings.ToUpper(lookBehindBuffer[0].Value) == "BY" {

View File

@ -78,6 +78,37 @@ func TestParseSelectStatement(t *testing.T) {
}, },
}, },
}, },
{
input: "SELECT id, streetNumber, streetName, city, state FROM Addresses WHERE state = 'AL' AND zip > 9000 ORDER BY zip DESC, streetNumber",
expected: Select{
Table: "Addresses",
IsWildcard: false,
Columns: []string{"id", "streetNumber", "streetName", "city", "state"},
Conditionals: []Conditional{
{
Key: "state",
Operator: "=",
Value: "'AL'",
},
{
Key: "zip",
Operator: ">",
Value: "9000",
Extension: "AND",
},
},
OrderBys: []OrderBy{
{
Key: "zip",
IsDescend: true,
},
{
Key: "streetNumber",
IsDescend: false,
},
},
},
},
} }
for _, sql := range testSqlStatements { for _, sql := range testSqlStatements {