Minor query parser fixes

This commit is contained in:
Pijus Kamandulis 2024-02-17 17:25:57 +02:00
parent 1e461d3548
commit eb7b3045d2
4 changed files with 507 additions and 347 deletions

View File

@ -19,6 +19,9 @@ build-linux-amd64:
@echo "Building Linux binary..." @echo "Building Linux binary..."
@GOOS=linux GOARCH=amd64 $(GOBUILD) -o $(DIST_DIR)/$(BINARY_NAME)-linux-amd64 . @GOOS=linux GOARCH=amd64 $(GOBUILD) -o $(DIST_DIR)/$(BINARY_NAME)-linux-amd64 .
generate-parser-nosql:
pigeon -o ./parsers/nosql/nosql.go ./parsers/nosql/nosql.peg
test: test:
@echo "Running unit tests..." @echo "Running unit tests..."
@$(GOTEST) -v ./... @$(GOTEST) -v ./...
@ -28,4 +31,4 @@ clean:
@$(GOCLEAN) @$(GOCLEAN)
@rm -rf $(DIST_DIR) @rm -rf $(DIST_DIR)
.PHONY: all test build-all build-macos build-linux clean .PHONY: all test build-all build-macos build-linux clean generate-parser-nosql

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,8 @@ func makeSelectStmt(columns, table, whereClause interface{}, count interface{})
selectStmt.Filters = filters selectStmt.Filters = filters
} else if filters, ok := whereClause.(parsers.LogicalExpression); ok { } else if filters, ok := whereClause.(parsers.LogicalExpression); ok {
selectStmt.Filters = filters selectStmt.Filters = filters
} else if filters, ok := whereClause.(parsers.Constant); ok {
selectStmt.Filters = filters
} }
if n, ok := count.(int); ok { if n, ok := count.(int); ok {
@ -142,7 +144,7 @@ SelectObject <- "{" ws field:SelectObjectField ws other_fields:(ws "," ws coll:S
return makeSelectObject(field, other_fields) return makeSelectObject(field, other_fields)
} }
SelectObjectField <- name:Identifier ws ":" ws selectItem:SelectItem { SelectObjectField <- name:(Identifier / "\"" key:Identifier "\"" { return key, nil }) ws ":" ws selectItem:SelectItem {
item := selectItem.(parsers.SelectItem) item := selectItem.(parsers.SelectItem)
item.Alias = name.(string) item.Alias = name.(string)
return item, nil return item, nil
@ -178,18 +180,18 @@ Condition <- expression:OrExpression {
return expression, nil return expression, nil
} }
OrExpression <- ex1:AndExpression ex2:(ws "OR" ws ex:AndExpression { return ex, nil })* { OrExpression <- ex1:AndExpression ex2:(ws Or ws ex:AndExpression { return ex, nil })* {
return combineExpressions(ex1, ex2, parsers.LogicalExpressionTypeOr) return combineExpressions(ex1, ex2, parsers.LogicalExpressionTypeOr)
} }
AndExpression <- ex1:ComparisonExpression ex2:(ws "AND" ws ex:ComparisonExpression { return ex, nil })* { AndExpression <- ex1:ComparisonExpression ex2:(ws And ws ex:ComparisonExpression { return ex, nil })* {
return combineExpressions(ex1, ex2, parsers.LogicalExpressionTypeAnd) return combineExpressions(ex1, ex2, parsers.LogicalExpressionTypeAnd)
} }
ComparisonExpression <- "(" ws ex:OrExpression ws ")" { return ex, nil } ComparisonExpression <- "(" ws ex:OrExpression ws ")" { return ex, nil }
/ left:(Literal / SelectItem) ws op:ComparisonOperator ws right:(Literal / SelectItem) { / left:(Literal / SelectItem) ws op:ComparisonOperator ws right:(Literal / SelectItem) {
return parsers.ComparisonExpression{Left:left,Right:right,Operation:string(op.([]uint8))}, nil return parsers.ComparisonExpression{Left:left,Right:right,Operation:string(op.([]uint8))}, nil
} } / ex:BooleanLiteral { return ex, nil }
Select <- ("select" / "SELECT") Select <- ("select" / "SELECT")
@ -201,15 +203,22 @@ From <- ("from" / "FROM")
Where <- ("where" / "WHERE") Where <- ("where" / "WHERE")
And <- ("and" / "AND")
Or <- ("or" / "OR")
ComparisonOperator <- "=" / "!=" / "<" / "<=" / ">" / ">=" { ComparisonOperator <- "=" / "!=" / "<" / "<=" / ">" / ">=" {
return string(c.text), nil return string(c.text), nil
} }
Literal <- FloatLiteral / IntegerLiteral / StringLiteral / BooleanLiteral / ParameterConstant Literal <- FloatLiteral / IntegerLiteral / StringLiteral / BooleanLiteral / ParameterConstant / NullConstant
ParameterConstant <- "@" Identifier { ParameterConstant <- "@" Identifier {
return parsers.Constant{Type: parsers.ConstantTypeParameterConstant, Value: string(c.text)}, nil return parsers.Constant{Type: parsers.ConstantTypeParameterConstant, Value: string(c.text)}, nil
} }
NullConstant <- "null" {
return parsers.Constant{Value: nil}, nil
}
IntegerLiteral <- number:Integer { IntegerLiteral <- number:Integer {
return parsers.Constant{Type: parsers.ConstantTypeInteger, Value: number.(int)}, nil return parsers.Constant{Type: parsers.ConstantTypeInteger, Value: number.(int)}, nil

View File

@ -1,6 +1,8 @@
package memoryexecutor package memoryexecutor
import ( import (
"fmt"
"github.com/pikami/cosmium/parsers" "github.com/pikami/cosmium/parsers"
) )
@ -40,11 +42,15 @@ func selectRow(selectItems []parsers.SelectItem, row RowType) interface{} {
// Construct a new row based on the selected columns // Construct a new row based on the selected columns
newRow := make(map[string]interface{}) newRow := make(map[string]interface{})
for _, column := range selectItems { for index, column := range selectItems {
destinationName := column.Alias destinationName := column.Alias
if destinationName == "" { if destinationName == "" {
if len(column.Path) < 1 {
destinationName = fmt.Sprintf("$%d", index+1)
} else {
destinationName = column.Path[len(column.Path)-1] destinationName = column.Path[len(column.Path)-1]
} }
}
newRow[destinationName] = getFieldValue(column, row) newRow[destinationName] = getFieldValue(column, row)
} }
@ -66,6 +72,8 @@ func evaluateFilters(expr ExpressionType, Parameters map[string]interface{}, row
switch typedValue.Operation { switch typedValue.Operation {
case "=": case "=":
return leftValue == rightValue return leftValue == rightValue
case "!=":
return leftValue != rightValue
// Handle other comparison operators as needed // Handle other comparison operators as needed
} }
case parsers.LogicalExpression: case parsers.LogicalExpression:
@ -90,6 +98,12 @@ func evaluateFilters(expr ExpressionType, Parameters map[string]interface{}, row
} }
} }
return result return result
case parsers.Constant:
if value, ok := typedValue.Value.(bool); ok {
return value
}
// TODO: Check if we should do something if it is not a boolean constant
return false
} }
return false return false
} }