Partial JOIN implementation

This commit is contained in:
Pijus Kamandulis
2024-07-17 21:40:28 +03:00
parent 3bdff9b643
commit 20af73ee9c
7 changed files with 1866 additions and 1536 deletions

View 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

View File

@@ -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