mirror of
https://github.com/pikami/cosmium.git
synced 2025-12-19 17:00:37 +00:00
Partial JOIN implementation
This commit is contained in:
57
parsers/nosql/join_test.go
Normal file
57
parsers/nosql/join_test.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package nosql_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/pikami/cosmium/parsers"
|
||||
)
|
||||
|
||||
func Test_Parse_Join(t *testing.T) {
|
||||
|
||||
t.Run("Should parse simple JOIN", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT c.id, c["pk"] FROM c JOIN cc IN c["tags"]`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{Path: []string{"c", "id"}},
|
||||
{Path: []string{"c", "pk"}},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
JoinItems: []parsers.JoinItem{
|
||||
{
|
||||
Table: parsers.Table{
|
||||
Value: "cc",
|
||||
},
|
||||
SelectItem: parsers.SelectItem{
|
||||
Path: []string{"c", "tags"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse JOIN VALUE", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT VALUE cc FROM c JOIN cc IN c["tags"]`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{Path: []string{"cc"}, IsTopLevel: true},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
JoinItems: []parsers.JoinItem{
|
||||
{
|
||||
Table: parsers.Table{
|
||||
Value: "cc",
|
||||
},
|
||||
SelectItem: parsers.SelectItem{
|
||||
Path: []string{"c", "tags"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@ package nosql
|
||||
import "github.com/pikami/cosmium/parsers"
|
||||
|
||||
func makeSelectStmt(
|
||||
columns, table,
|
||||
columns, table, joinItems,
|
||||
whereClause interface{}, distinctClause interface{},
|
||||
count interface{}, groupByClause interface{}, orderList interface{},
|
||||
offsetClause interface{},
|
||||
@@ -14,6 +14,13 @@ func makeSelectStmt(
|
||||
Table: table.(parsers.Table),
|
||||
}
|
||||
|
||||
if joinItemsArray, ok := joinItems.([]interface{}); ok && len(joinItemsArray) > 0 {
|
||||
selectStmt.JoinItems = make([]parsers.JoinItem, len(joinItemsArray))
|
||||
for i, joinItem := range joinItemsArray {
|
||||
selectStmt.JoinItems[i] = joinItem.(parsers.JoinItem)
|
||||
}
|
||||
}
|
||||
|
||||
switch v := whereClause.(type) {
|
||||
case parsers.ComparisonExpression, parsers.LogicalExpression, parsers.Constant, parsers.SelectItem:
|
||||
selectStmt.Filters = v
|
||||
@@ -48,6 +55,13 @@ func makeSelectStmt(
|
||||
return selectStmt, nil
|
||||
}
|
||||
|
||||
func makeJoin(table interface{}, column interface{}) (parsers.JoinItem, error) {
|
||||
return parsers.JoinItem{
|
||||
Table: table.(parsers.Table),
|
||||
SelectItem: column.(parsers.SelectItem),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func makeSelectItem(name interface{}, path interface{}, selectItemType parsers.SelectItemType) (parsers.SelectItem, error) {
|
||||
ps := path.([]interface{})
|
||||
|
||||
@@ -161,13 +175,15 @@ Input <- selectStmt:SelectStmt {
|
||||
|
||||
SelectStmt <- Select ws
|
||||
distinctClause:DistinctClause? ws
|
||||
topClause:TopClause? ws columns:Selection ws
|
||||
topClause:TopClause? ws
|
||||
columns:Selection ws
|
||||
From ws table:TableName ws
|
||||
joinClauses:JoinClause* ws
|
||||
whereClause:(ws Where ws condition:Condition { return condition, nil })?
|
||||
groupByClause:(ws GroupBy ws columns:ColumnList { return columns, nil })?
|
||||
orderByClause:OrderByClause?
|
||||
offsetClause:OffsetClause? {
|
||||
return makeSelectStmt(columns, table, whereClause,
|
||||
return makeSelectStmt(columns, table, joinClauses, whereClause,
|
||||
distinctClause, topClause, groupByClause, orderByClause, offsetClause)
|
||||
}
|
||||
|
||||
@@ -177,6 +193,10 @@ TopClause <- Top ws count:Integer {
|
||||
return count, nil
|
||||
}
|
||||
|
||||
JoinClause <- Join ws table:TableName ws "IN"i ws column:SelectItem {
|
||||
return makeJoin(table, column)
|
||||
}
|
||||
|
||||
OffsetClause <- "OFFSET"i ws offset:IntegerLiteral ws "LIMIT"i ws limit:IntegerLiteral {
|
||||
return []interface{}{offset.(parsers.Constant).Value, limit.(parsers.Constant).Value}, nil
|
||||
}
|
||||
@@ -300,6 +320,8 @@ As <- "AS"i
|
||||
|
||||
From <- "FROM"i
|
||||
|
||||
Join <- "JOIN"i
|
||||
|
||||
Where <- "WHERE"i
|
||||
|
||||
And <- "AND"i
|
||||
|
||||
Reference in New Issue
Block a user