mirror of
https://github.com/pikami/cosmium.git
synced 2025-06-08 00:20:28 +01:00
Compare commits
No commits in common. "11851297f5626377f1e1dcf83e82ce11dcef01a1" and "e20a6ca7cd06a75b369f00a9cb30403675779349" have entirely different histories.
11851297f5
...
e20a6ca7cd
@ -34,7 +34,6 @@ const (
|
|||||||
SelectItemTypeConstant
|
SelectItemTypeConstant
|
||||||
SelectItemTypeFunctionCall
|
SelectItemTypeFunctionCall
|
||||||
SelectItemTypeSubQuery
|
SelectItemTypeSubQuery
|
||||||
SelectItemTypeExpression
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SelectItem struct {
|
type SelectItem struct {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -4,137 +4,137 @@ package nosql
|
|||||||
import "github.com/pikami/cosmium/parsers"
|
import "github.com/pikami/cosmium/parsers"
|
||||||
|
|
||||||
func makeSelectStmt(
|
func makeSelectStmt(
|
||||||
columns, fromClause, joinItems,
|
columns, fromClause, joinItems,
|
||||||
whereClause interface{}, distinctClause interface{},
|
whereClause interface{}, distinctClause interface{},
|
||||||
count interface{}, groupByClause interface{}, orderList interface{},
|
count interface{}, groupByClause interface{}, orderList interface{},
|
||||||
offsetClause interface{},
|
offsetClause interface{},
|
||||||
) (parsers.SelectStmt, error) {
|
) (parsers.SelectStmt, error) {
|
||||||
selectStmt := parsers.SelectStmt{
|
selectStmt := parsers.SelectStmt{
|
||||||
SelectItems: columns.([]parsers.SelectItem),
|
SelectItems: columns.([]parsers.SelectItem),
|
||||||
}
|
}
|
||||||
|
|
||||||
if fromTable, ok := fromClause.(parsers.Table); ok {
|
if fromTable, ok := fromClause.(parsers.Table); ok {
|
||||||
selectStmt.Table = fromTable
|
selectStmt.Table = fromTable
|
||||||
}
|
}
|
||||||
|
|
||||||
if joinItemsArray, ok := joinItems.([]interface{}); ok && len(joinItemsArray) > 0 {
|
if joinItemsArray, ok := joinItems.([]interface{}); ok && len(joinItemsArray) > 0 {
|
||||||
selectStmt.JoinItems = make([]parsers.JoinItem, len(joinItemsArray))
|
selectStmt.JoinItems = make([]parsers.JoinItem, len(joinItemsArray))
|
||||||
for i, joinItem := range joinItemsArray {
|
for i, joinItem := range joinItemsArray {
|
||||||
selectStmt.JoinItems[i] = joinItem.(parsers.JoinItem)
|
selectStmt.JoinItems[i] = joinItem.(parsers.JoinItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch v := whereClause.(type) {
|
switch v := whereClause.(type) {
|
||||||
case parsers.ComparisonExpression, parsers.LogicalExpression, parsers.Constant, parsers.SelectItem:
|
case parsers.ComparisonExpression, parsers.LogicalExpression, parsers.Constant, parsers.SelectItem:
|
||||||
selectStmt.Filters = v
|
selectStmt.Filters = v
|
||||||
}
|
}
|
||||||
|
|
||||||
if distinctClause != nil {
|
if distinctClause != nil {
|
||||||
selectStmt.Distinct = true
|
selectStmt.Distinct = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if n, ok := count.(int); ok {
|
if n, ok := count.(int); ok {
|
||||||
selectStmt.Count = n
|
selectStmt.Count = n
|
||||||
}
|
}
|
||||||
|
|
||||||
if offsetArr, ok := offsetClause.([]interface{}); ok && len(offsetArr) == 2 {
|
if offsetArr, ok := offsetClause.([]interface{}); ok && len(offsetArr) == 2 {
|
||||||
if n, ok := offsetArr[0].(int); ok {
|
if n, ok := offsetArr[0].(int); ok {
|
||||||
selectStmt.Offset = n
|
selectStmt.Offset = n
|
||||||
}
|
}
|
||||||
|
|
||||||
if n, ok := offsetArr[1].(int); ok {
|
if n, ok := offsetArr[1].(int); ok {
|
||||||
selectStmt.Count = n
|
selectStmt.Count = n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if orderExpressions, ok := orderList.([]parsers.OrderExpression); ok {
|
if orderExpressions, ok := orderList.([]parsers.OrderExpression); ok {
|
||||||
selectStmt.OrderExpressions = orderExpressions
|
selectStmt.OrderExpressions = orderExpressions
|
||||||
}
|
}
|
||||||
|
|
||||||
if groupByClause != nil {
|
if groupByClause != nil {
|
||||||
selectStmt.GroupBy = groupByClause.([]parsers.SelectItem)
|
selectStmt.GroupBy = groupByClause.([]parsers.SelectItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
return selectStmt, nil
|
return selectStmt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeJoin(table interface{}, column interface{}) (parsers.JoinItem, error) {
|
func makeJoin(table interface{}, column interface{}) (parsers.JoinItem, error) {
|
||||||
joinItem := parsers.JoinItem{}
|
joinItem := parsers.JoinItem{}
|
||||||
|
|
||||||
if selectItem, isSelectItem := column.(parsers.SelectItem); isSelectItem {
|
if selectItem, isSelectItem := column.(parsers.SelectItem); isSelectItem {
|
||||||
joinItem.SelectItem = selectItem
|
joinItem.SelectItem = selectItem
|
||||||
joinItem.Table.Value = selectItem.Alias
|
joinItem.Table.Value = selectItem.Alias
|
||||||
}
|
}
|
||||||
|
|
||||||
if tableTyped, isTable := table.(parsers.Table); isTable {
|
if tableTyped, isTable := table.(parsers.Table); isTable {
|
||||||
joinItem.Table = tableTyped
|
joinItem.Table = tableTyped
|
||||||
}
|
}
|
||||||
|
|
||||||
return joinItem, nil
|
return joinItem, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeSelectItem(name interface{}, path interface{}, selectItemType parsers.SelectItemType) (parsers.SelectItem, error) {
|
func makeSelectItem(name interface{}, path interface{}, selectItemType parsers.SelectItemType) (parsers.SelectItem, error) {
|
||||||
ps := path.([]interface{})
|
ps := path.([]interface{})
|
||||||
|
|
||||||
paths := make([]string, 1)
|
paths := make([]string, 1)
|
||||||
paths[0] = name.(string)
|
paths[0] = name.(string)
|
||||||
for _, p := range ps {
|
for _, p := range ps {
|
||||||
paths = append(paths, p.(string))
|
paths = append(paths, p.(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
return parsers.SelectItem{Path: paths, Type: selectItemType}, nil
|
return parsers.SelectItem{Path: paths, Type: selectItemType}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeColumnList(column interface{}, other_columns interface{}) ([]parsers.SelectItem, error) {
|
func makeColumnList(column interface{}, other_columns interface{}) ([]parsers.SelectItem, error) {
|
||||||
collsAsArray := other_columns.([]interface{})
|
collsAsArray := other_columns.([]interface{})
|
||||||
columnList := make([]parsers.SelectItem, len(collsAsArray) + 1)
|
columnList := make([]parsers.SelectItem, len(collsAsArray) + 1)
|
||||||
columnList[0] = column.(parsers.SelectItem)
|
columnList[0] = column.(parsers.SelectItem)
|
||||||
|
|
||||||
for i, v := range collsAsArray {
|
for i, v := range collsAsArray {
|
||||||
if col, ok := v.(parsers.SelectItem); ok {
|
if col, ok := v.(parsers.SelectItem); ok {
|
||||||
columnList[i+1] = col
|
columnList[i+1] = col
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return columnList, nil
|
return columnList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeSelectArray(columns interface{}) (parsers.SelectItem, error) {
|
func makeSelectArray(columns interface{}) (parsers.SelectItem, error) {
|
||||||
return parsers.SelectItem{
|
return parsers.SelectItem{
|
||||||
SelectItems: columns.([]parsers.SelectItem),
|
SelectItems: columns.([]parsers.SelectItem),
|
||||||
Type: parsers.SelectItemTypeArray,
|
Type: parsers.SelectItemTypeArray,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeSelectObject(field interface{}, other_fields interface{}) (parsers.SelectItem, error) {
|
func makeSelectObject(field interface{}, other_fields interface{}) (parsers.SelectItem, error) {
|
||||||
fieldsAsArray := other_fields.([]interface{})
|
fieldsAsArray := other_fields.([]interface{})
|
||||||
fieldsList := make([]parsers.SelectItem, len(fieldsAsArray)+1)
|
fieldsList := make([]parsers.SelectItem, len(fieldsAsArray)+1)
|
||||||
fieldsList[0] = field.(parsers.SelectItem)
|
fieldsList[0] = field.(parsers.SelectItem)
|
||||||
|
|
||||||
for i, v := range fieldsAsArray {
|
for i, v := range fieldsAsArray {
|
||||||
if col, ok := v.(parsers.SelectItem); ok {
|
if col, ok := v.(parsers.SelectItem); ok {
|
||||||
fieldsList[i+1] = col
|
fieldsList[i+1] = col
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return parsers.SelectItem{
|
return parsers.SelectItem{
|
||||||
SelectItems: fieldsList,
|
SelectItems: fieldsList,
|
||||||
Type: parsers.SelectItemTypeObject,
|
Type: parsers.SelectItemTypeObject,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeOrderByClause(ex1 interface{}, others interface{}) ([]parsers.OrderExpression, error) {
|
func makeOrderByClause(ex1 interface{}, others interface{}) ([]parsers.OrderExpression, error) {
|
||||||
othersArray := others.([]interface{})
|
othersArray := others.([]interface{})
|
||||||
orderList := make([]parsers.OrderExpression, len(othersArray)+1)
|
orderList := make([]parsers.OrderExpression, len(othersArray)+1)
|
||||||
orderList[0] = ex1.(parsers.OrderExpression)
|
orderList[0] = ex1.(parsers.OrderExpression)
|
||||||
|
|
||||||
for i, v := range othersArray {
|
for i, v := range othersArray {
|
||||||
if col, ok := v.(parsers.OrderExpression); ok {
|
if col, ok := v.(parsers.OrderExpression); ok {
|
||||||
orderList[i+1] = col
|
orderList[i+1] = col
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return orderList, nil
|
return orderList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeOrderExpression(field interface{}, order interface{}) (parsers.OrderExpression, error) {
|
func makeOrderExpression(field interface{}, order interface{}) (parsers.OrderExpression, error) {
|
||||||
@ -144,8 +144,8 @@ func makeOrderExpression(field interface{}, order interface{}) (parsers.OrderExp
|
|||||||
}
|
}
|
||||||
|
|
||||||
if orderValue, ok := order.(parsers.OrderDirection); ok {
|
if orderValue, ok := order.(parsers.OrderDirection); ok {
|
||||||
value.Direction = orderValue
|
value.Direction = orderValue
|
||||||
}
|
}
|
||||||
|
|
||||||
return value, nil
|
return value, nil
|
||||||
}
|
}
|
||||||
@ -169,13 +169,13 @@ func joinStrings(array []interface{}) string {
|
|||||||
|
|
||||||
func combineExpressions(ex1 interface{}, exs interface{}, operation parsers.LogicalExpressionType) (interface{}, error) {
|
func combineExpressions(ex1 interface{}, exs interface{}, operation parsers.LogicalExpressionType) (interface{}, error) {
|
||||||
if exs == nil || len(exs.([]interface{})) < 1 {
|
if exs == nil || len(exs.([]interface{})) < 1 {
|
||||||
return ex1, nil
|
return ex1, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return parsers.LogicalExpression{
|
return parsers.LogicalExpression{
|
||||||
Expressions: append([]interface{}{ex1}, exs.([]interface{})...),
|
Expressions: append([]interface{}{ex1}, exs.([]interface{})...),
|
||||||
Operation: operation,
|
Operation: operation,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -204,16 +204,16 @@ TopClause <- Top ws count:Integer {
|
|||||||
return count, nil
|
return count, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
FromClause <- From ws table:TableName selectItem:(ws In ws column:SelectItemWithAlias { return column, nil }) {
|
FromClause <- From ws table:TableName selectItem:(ws In ws column:SelectItem { return column, nil }) {
|
||||||
tableTyped := table.(parsers.Table)
|
tableTyped := table.(parsers.Table)
|
||||||
|
|
||||||
if selectItem != nil {
|
if selectItem != nil {
|
||||||
tableTyped.SelectItem = selectItem.(parsers.SelectItem)
|
tableTyped.SelectItem = selectItem.(parsers.SelectItem)
|
||||||
tableTyped.IsInSelect = true
|
tableTyped.IsInSelect = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return tableTyped, nil
|
return tableTyped, nil
|
||||||
} / From ws column:SelectItemWithAlias {
|
} / From ws column:SelectItem {
|
||||||
tableSelectItem := column.(parsers.SelectItem)
|
tableSelectItem := column.(parsers.SelectItem)
|
||||||
table := parsers.Table{
|
table := parsers.Table{
|
||||||
Value: tableSelectItem.Alias,
|
Value: tableSelectItem.Alias,
|
||||||
@ -222,11 +222,11 @@ FromClause <- From ws table:TableName selectItem:(ws In ws column:SelectItemWith
|
|||||||
return table, nil
|
return table, nil
|
||||||
} / From ws subQuery:SubQuerySelectItem {
|
} / From ws subQuery:SubQuerySelectItem {
|
||||||
subQueryTyped := subQuery.(parsers.SelectItem)
|
subQueryTyped := subQuery.(parsers.SelectItem)
|
||||||
table := parsers.Table{
|
table := parsers.Table{
|
||||||
Value: subQueryTyped.Alias,
|
Value: subQueryTyped.Alias,
|
||||||
SelectItem: subQueryTyped,
|
SelectItem: subQueryTyped,
|
||||||
}
|
}
|
||||||
return table, nil
|
return table, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
SubQuery <- exists:(exists:Exists ws { return exists, nil })? "(" ws selectStmt:SelectStmt ws ")" {
|
SubQuery <- exists:(exists:Exists ws { return exists, nil })? "(" ws selectStmt:SelectStmt ws ")" {
|
||||||
@ -251,7 +251,7 @@ SubQuerySelectItem <- subQuery:SubQuery asClause:(ws alias:AsClause { return ali
|
|||||||
return selectItem, nil
|
return selectItem, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
JoinClause <- Join ws table:TableName ws In ws column:SelectItemWithAlias {
|
JoinClause <- Join ws table:TableName ws In ws column:SelectItem {
|
||||||
return makeJoin(table, column)
|
return makeJoin(table, column)
|
||||||
} / Join ws subQuery:SubQuerySelectItem {
|
} / Join ws subQuery:SubQuerySelectItem {
|
||||||
return makeJoin(nil, subQuery)
|
return makeJoin(nil, subQuery)
|
||||||
@ -265,40 +265,17 @@ Selection <- SelectValueSpec / ColumnList / SelectAsterisk
|
|||||||
|
|
||||||
SelectAsterisk <- "*" {
|
SelectAsterisk <- "*" {
|
||||||
selectItem, _ := makeSelectItem("c", make([]interface{}, 0), parsers.SelectItemTypeField)
|
selectItem, _ := makeSelectItem("c", make([]interface{}, 0), parsers.SelectItemTypeField)
|
||||||
selectItem.IsTopLevel = true
|
selectItem.IsTopLevel = true
|
||||||
return makeColumnList(selectItem, make([]interface{}, 0))
|
return makeColumnList(selectItem, make([]interface{}, 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnList <- column:ExpressionOrSelectItem other_columns:(ws "," ws coll:ExpressionOrSelectItem {return coll, nil })* {
|
ColumnList <- column:SelectItem other_columns:(ws "," ws coll:SelectItem {return coll, nil })* {
|
||||||
return makeColumnList(column, other_columns)
|
return makeColumnList(column, other_columns)
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpressionOrSelectItem <- expression:OrExpression asClause:AsClause? {
|
SelectValueSpec <- "VALUE"i ws column:SelectItem {
|
||||||
switch typedValue := expression.(type) {
|
|
||||||
case parsers.ComparisonExpression, parsers.LogicalExpression:
|
|
||||||
selectItem := parsers.SelectItem{
|
|
||||||
Type: parsers.SelectItemTypeExpression,
|
|
||||||
Value: typedValue,
|
|
||||||
}
|
|
||||||
|
|
||||||
if aliasValue, ok := asClause.(string); ok {
|
|
||||||
selectItem.Alias = aliasValue
|
|
||||||
}
|
|
||||||
|
|
||||||
return selectItem, nil
|
|
||||||
case parsers.SelectItem:
|
|
||||||
if aliasValue, ok := asClause.(string); ok {
|
|
||||||
typedValue.Alias = aliasValue
|
|
||||||
}
|
|
||||||
return typedValue, nil
|
|
||||||
default:
|
|
||||||
return typedValue, nil
|
|
||||||
}
|
|
||||||
} / item:SelectItemWithAlias { return item, nil }
|
|
||||||
|
|
||||||
SelectValueSpec <- "VALUE"i ws column:SelectItemWithAlias {
|
|
||||||
selectItem := column.(parsers.SelectItem)
|
selectItem := column.(parsers.SelectItem)
|
||||||
selectItem.IsTopLevel = true
|
selectItem.IsTopLevel = true
|
||||||
return makeColumnList(selectItem, make([]interface{}, 0))
|
return makeColumnList(selectItem, make([]interface{}, 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,30 +291,22 @@ SelectObject <- "{" ws field:SelectObjectField ws other_fields:(ws "," ws coll:S
|
|||||||
return makeSelectObject(field, other_fields)
|
return makeSelectObject(field, other_fields)
|
||||||
} / "{" ws "}" {
|
} / "{" ws "}" {
|
||||||
return parsers.SelectItem{
|
return parsers.SelectItem{
|
||||||
SelectItems: []parsers.SelectItem{},
|
SelectItems: []parsers.SelectItem{},
|
||||||
Type: parsers.SelectItemTypeObject,
|
Type: parsers.SelectItemTypeObject,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectObjectField <- name:(Identifier / "\"" key:Identifier "\"" { return key, nil }) 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
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectProperty <- name:Identifier path:(DotFieldAccess / ArrayFieldAccess)* {
|
SelectProperty <- name:Identifier path:(DotFieldAccess / ArrayFieldAccess)* {
|
||||||
return makeSelectItem(name, path, parsers.SelectItemTypeField)
|
return makeSelectItem(name, path, parsers.SelectItemTypeField)
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectItemWithAlias <- selectItem:SelectItem asClause:AsClause? {
|
SelectItem <- selectItem:(SubQuerySelectItem / Literal / FunctionCall / SelectArray / SelectObject / SelectProperty) asClause:AsClause? {
|
||||||
item := selectItem.(parsers.SelectItem)
|
|
||||||
if aliasValue, ok := asClause.(string); ok {
|
|
||||||
item.Alias = aliasValue
|
|
||||||
}
|
|
||||||
return item, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
SelectItem <- selectItem:(SubQuerySelectItem / Literal / FunctionCall / SelectArray / SelectObject / SelectProperty) {
|
|
||||||
var itemResult parsers.SelectItem
|
var itemResult parsers.SelectItem
|
||||||
switch typedValue := selectItem.(type) {
|
switch typedValue := selectItem.(type) {
|
||||||
case parsers.SelectItem:
|
case parsers.SelectItem:
|
||||||
@ -354,7 +323,11 @@ SelectItem <- selectItem:(SubQuerySelectItem / Literal / FunctionCall / SelectAr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return itemResult, nil
|
if aliasValue, ok := asClause.(string); ok {
|
||||||
|
itemResult.Alias = aliasValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemResult, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
AsClause <- (ws As)? ws !ExcludedKeywords alias:Identifier {
|
AsClause <- (ws As)? ws !ExcludedKeywords alias:Identifier {
|
||||||
@ -392,10 +365,10 @@ ComparisonExpression <- "(" ws ex:OrExpression ws ")" { return ex, nil }
|
|||||||
return parsers.ComparisonExpression{Left:left,Right:right,Operation:op.(string)}, nil
|
return parsers.ComparisonExpression{Left:left,Right:right,Operation:op.(string)}, nil
|
||||||
} / inv:(Not ws)? ex:SelectItem {
|
} / inv:(Not ws)? ex:SelectItem {
|
||||||
if inv != nil {
|
if inv != nil {
|
||||||
ex1 := ex.(parsers.SelectItem)
|
ex1 := ex.(parsers.SelectItem)
|
||||||
ex1.Invert = true
|
ex1.Invert = true
|
||||||
return ex1, nil
|
return ex1, nil
|
||||||
}
|
}
|
||||||
return ex, nil
|
return ex, nil
|
||||||
} / ex:BooleanLiteral { return ex, nil }
|
} / ex:BooleanLiteral { return ex, nil }
|
||||||
|
|
||||||
@ -409,10 +382,10 @@ OrderExpression <- field:SelectProperty ws order:OrderDirection? {
|
|||||||
|
|
||||||
OrderDirection <- ("ASC"i / "DESC"i) {
|
OrderDirection <- ("ASC"i / "DESC"i) {
|
||||||
if strings.EqualFold(string(c.text), "DESC") {
|
if strings.EqualFold(string(c.text), "DESC") {
|
||||||
return parsers.OrderDirectionDesc, nil
|
return parsers.OrderDirectionDesc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return parsers.OrderDirectionAsc, nil
|
return parsers.OrderDirectionAsc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
Select <- "SELECT"i
|
Select <- "SELECT"i
|
||||||
|
@ -195,73 +195,4 @@ func Test_Parse_Select(t *testing.T) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Should parse comparison expressions in SELECT", func(t *testing.T) {
|
|
||||||
testQueryParse(
|
|
||||||
t,
|
|
||||||
`SELECT c["id"] = "123", c["pk"] > 456 FROM c`,
|
|
||||||
parsers.SelectStmt{
|
|
||||||
SelectItems: []parsers.SelectItem{
|
|
||||||
{
|
|
||||||
Type: parsers.SelectItemTypeExpression,
|
|
||||||
Value: parsers.ComparisonExpression{
|
|
||||||
Operation: "=",
|
|
||||||
Left: testutils.SelectItem_Path("c", "id"),
|
|
||||||
Right: testutils.SelectItem_Constant_String("123"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: parsers.SelectItemTypeExpression,
|
|
||||||
Value: parsers.ComparisonExpression{
|
|
||||||
Operation: ">",
|
|
||||||
Left: testutils.SelectItem_Path("c", "pk"),
|
|
||||||
Right: testutils.SelectItem_Constant_Int(456),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Table: parsers.Table{SelectItem: testutils.SelectItem_Path("c")},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Should parse logical expressions in SELECT", func(t *testing.T) {
|
|
||||||
testQueryParse(
|
|
||||||
t,
|
|
||||||
`SELECT c["id"] = "123" OR c["pk"] > 456, c["isCool"] AND c["hasRizz"] AS isRizzler FROM c`,
|
|
||||||
parsers.SelectStmt{
|
|
||||||
SelectItems: []parsers.SelectItem{
|
|
||||||
{
|
|
||||||
Type: parsers.SelectItemTypeExpression,
|
|
||||||
Value: parsers.LogicalExpression{
|
|
||||||
Operation: parsers.LogicalExpressionTypeOr,
|
|
||||||
Expressions: []interface{}{
|
|
||||||
parsers.ComparisonExpression{
|
|
||||||
Operation: "=",
|
|
||||||
Left: testutils.SelectItem_Path("c", "id"),
|
|
||||||
Right: testutils.SelectItem_Constant_String("123"),
|
|
||||||
},
|
|
||||||
parsers.ComparisonExpression{
|
|
||||||
Operation: ">",
|
|
||||||
Left: testutils.SelectItem_Path("c", "pk"),
|
|
||||||
Right: testutils.SelectItem_Constant_Int(456),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: parsers.SelectItemTypeExpression,
|
|
||||||
Alias: "isRizzler",
|
|
||||||
Value: parsers.LogicalExpression{
|
|
||||||
Operation: parsers.LogicalExpressionTypeAnd,
|
|
||||||
Expressions: []interface{}{
|
|
||||||
testutils.SelectItem_Path("c", "isCool"),
|
|
||||||
testutils.SelectItem_Path("c", "hasRizz"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Table: parsers.Table{SelectItem: testutils.SelectItem_Path("c")},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -69,19 +69,6 @@ func (r rowContext) resolveSelectItem(selectItem parsers.SelectItem) interface{}
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if selectItem.Type == parsers.SelectItemTypeExpression {
|
|
||||||
if typedExpression, ok := selectItem.Value.(parsers.ComparisonExpression); ok {
|
|
||||||
return r.filters_ComparisonExpression(typedExpression)
|
|
||||||
}
|
|
||||||
|
|
||||||
if typedExpression, ok := selectItem.Value.(parsers.LogicalExpression); ok {
|
|
||||||
return r.filters_LogicalExpression(typedExpression)
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.ErrorLn("parsers.SelectItem has incorrect Value type (expected parsers.ComparisonExpression)")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return r.selectItem_SelectItemTypeField(selectItem)
|
return r.selectItem_SelectItemTypeField(selectItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,92 +0,0 @@
|
|||||||
package memoryexecutor_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/pikami/cosmium/parsers"
|
|
||||||
memoryexecutor "github.com/pikami/cosmium/query_executors/memory_executor"
|
|
||||||
testutils "github.com/pikami/cosmium/test_utils"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_Execute_Expressions(t *testing.T) {
|
|
||||||
mockData := []memoryexecutor.RowType{
|
|
||||||
map[string]interface{}{"id": "123", "age": 10, "isCool": true},
|
|
||||||
map[string]interface{}{"id": "456", "age": 20, "isCool": false},
|
|
||||||
map[string]interface{}{"id": "789", "age": 30, "isCool": true},
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Run("Should execute comparison expressions in SELECT", func(t *testing.T) {
|
|
||||||
testQueryExecute(
|
|
||||||
t,
|
|
||||||
parsers.SelectStmt{
|
|
||||||
SelectItems: []parsers.SelectItem{
|
|
||||||
{
|
|
||||||
Path: []string{"c", "id"},
|
|
||||||
Type: parsers.SelectItemTypeField,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Alias: "isAdult",
|
|
||||||
Type: parsers.SelectItemTypeExpression,
|
|
||||||
Value: parsers.ComparisonExpression{
|
|
||||||
Operation: ">=",
|
|
||||||
Left: testutils.SelectItem_Path("c", "age"),
|
|
||||||
Right: testutils.SelectItem_Constant_Int(18),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Alias: "isNotCool",
|
|
||||||
Type: parsers.SelectItemTypeExpression,
|
|
||||||
Value: parsers.ComparisonExpression{
|
|
||||||
Operation: "!=",
|
|
||||||
Left: testutils.SelectItem_Path("c", "isCool"),
|
|
||||||
Right: testutils.SelectItem_Constant_Bool(true),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Table: parsers.Table{SelectItem: testutils.SelectItem_Path("c")},
|
|
||||||
},
|
|
||||||
mockData,
|
|
||||||
[]memoryexecutor.RowType{
|
|
||||||
map[string]interface{}{"id": "123", "isAdult": false, "isNotCool": false},
|
|
||||||
map[string]interface{}{"id": "456", "isAdult": true, "isNotCool": true},
|
|
||||||
map[string]interface{}{"id": "789", "isAdult": true, "isNotCool": false},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Should execute logical expressions in SELECT", func(t *testing.T) {
|
|
||||||
testQueryExecute(
|
|
||||||
t,
|
|
||||||
parsers.SelectStmt{
|
|
||||||
SelectItems: []parsers.SelectItem{
|
|
||||||
{
|
|
||||||
Path: []string{"c", "id"},
|
|
||||||
Type: parsers.SelectItemTypeField,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Alias: "isCoolAndAdult",
|
|
||||||
Type: parsers.SelectItemTypeExpression,
|
|
||||||
Value: parsers.LogicalExpression{
|
|
||||||
Operation: parsers.LogicalExpressionTypeAnd,
|
|
||||||
Expressions: []interface{}{
|
|
||||||
testutils.SelectItem_Path("c", "isCool"),
|
|
||||||
parsers.ComparisonExpression{
|
|
||||||
Operation: ">=",
|
|
||||||
Left: testutils.SelectItem_Path("c", "age"),
|
|
||||||
Right: testutils.SelectItem_Constant_Int(18),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Table: parsers.Table{SelectItem: testutils.SelectItem_Path("c")},
|
|
||||||
},
|
|
||||||
mockData,
|
|
||||||
[]memoryexecutor.RowType{
|
|
||||||
map[string]interface{}{"id": "123", "isCoolAndAdult": false},
|
|
||||||
map[string]interface{}{"id": "456", "isCoolAndAdult": false},
|
|
||||||
map[string]interface{}{"id": "789", "isCoolAndAdult": true},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user