Skip to content

Commit

Permalink
fix: configuration defined OrderBy + cursor combo not working #507
Browse files Browse the repository at this point in the history
  • Loading branch information
dosco committed May 11, 2024
1 parent 0dfc853 commit bdb20fe
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 21 deletions.
22 changes: 18 additions & 4 deletions core/internal/psql/exp.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,18 @@ func (c *expContext) renderOp(ex *qcode.Exp) {
table = ex.Left.Table
}

var colName string
if ex.Left.ColName != "" {
colName = ex.Left.ColName
} else {
colName = ex.Left.Col.Name
}

c.w.WriteString(`((`)
if ex.Left.ID == -1 {
c.colWithTable(table, ex.Left.Col.Name)
c.colWithTable(table, colName)
} else {
c.colWithTableID(table, ex.Left.ID, ex.Left.Col.Name)
c.colWithTableID(table, ex.Left.ID, colName)
}
c.w.WriteString(`) `)
}
Expand Down Expand Up @@ -344,6 +351,13 @@ func (c *expContext) renderVal(ex *qcode.Exp) {
table = ex.Right.Table
}

var colName string
if ex.Right.ColName != "" {
colName = ex.Right.ColName
} else {
colName = ex.Right.Col.Name
}

pid := ex.Right.ID
if ex.Right.ID != -1 {
pid = ex.Right.ID
Expand All @@ -354,9 +368,9 @@ func (c *expContext) renderVal(ex *qcode.Exp) {
c.renderValArrayColumn(ex, table, pid)
} else {
if pid == -1 {
c.colWithTable(table, ex.Right.Col.Name)
c.colWithTable(table, colName)
} else {
c.colWithTableID(table, pid, ex.Right.Col.Name)
c.colWithTableID(table, pid, colName)
}
}
c.w.WriteString(`)`)
Expand Down
12 changes: 10 additions & 2 deletions core/internal/psql/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,11 @@ func (c *compilerContext) renderCursorCTE(sel *qcode.Select) {
int32String(c.w, int32(i+2))
c.w.WriteString(`), ',', -1), '') AS `)
// c.w.WriteString(ob.Col.Type)
c.quoted(ob.Col.Name)
if ob.KeyVar != "" && ob.Key != "" {
c.quoted(ob.Col.Name + "_" + ob.Key)
} else {
c.quoted(ob.Col.Name)
}
}
c.w.WriteString(` FROM ((SELECT `)
c.renderParam(Param{Name: "cursor", Type: "text"})
Expand All @@ -587,7 +591,11 @@ func (c *compilerContext) renderCursorCTE(sel *qcode.Select) {
c.w.WriteString(`] :: `)
c.w.WriteString(ob.Col.Type)
c.w.WriteString(` AS `)
c.quoted(ob.Col.Name)
if ob.KeyVar != "" && ob.Key != "" {
c.quoted(ob.Col.Name + "_" + ob.Key)
} else {
c.quoted(ob.Col.Name)
}
}
c.w.WriteString(` FROM STRING_TO_ARRAY(`)
c.renderParam(Param{Name: "cursor", Type: "text"})
Expand Down
23 changes: 19 additions & 4 deletions core/internal/qcode/qcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,16 +166,18 @@ type Exp struct {
OrderBy bool

Left struct {
ID int32
Table string
Col sdata.DBColumn
ID int32
Table string
Col sdata.DBColumn
ColName string
}
Right struct {
ValType ValType
Val string
ID int32
Table string
Col sdata.DBColumn
ColName string
ListType ValType
ListVal []string
Path []string
Expand Down Expand Up @@ -871,11 +873,16 @@ func (co *Compiler) addSeekPredicate(sel *Select) {
obLen := len(sel.OrderBy)

if obLen != 0 {
ob := sel.OrderBy[0]
or = newExpOp(OpOr)

isnull := newExpOp(OpIsNull)
isnull.Left.Table = "__cur"
isnull.Left.Col = sel.OrderBy[0].Col
isnull.Left.Col = ob.Col

if ob.Key != "" {
isnull.Left.ColName = ob.Col.Name + "_" + ob.Key
}

or.Children = []*Exp{isnull}
}
Expand All @@ -895,6 +902,10 @@ func (co *Compiler) addSeekPredicate(sel *Select) {
f.Right.Table = "__cur"
f.Right.Col = ob.Col

if ob.Key != "" {
f.Right.ColName = ob.Col.Name + "_" + ob.Key
}

switch {
case i > 0 && n != i:
f.Op = OpEquals
Expand All @@ -917,6 +928,10 @@ func (co *Compiler) addSeekPredicate(sel *Select) {
isnull2 := newExpOp(OpIsNull)
isnull2.Left.Col = ob.Col

if ob.Key != "" {
isnull1.Left.ColName = ob.Col.Name + "_" + ob.Key
}

or1 := newExpOp(OpOr)
or1.Children = append(or.Children, isnull1, isnull2, f)

Expand Down
8 changes: 8 additions & 0 deletions tests/dbint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"flag"
"fmt"
"os"
"regexp"
"testing"

"github.com/dosco/graphjin/core/v3"
Expand Down Expand Up @@ -151,3 +152,10 @@ func stdJSON(val []byte) string {
func printJSON(val []byte) {
fmt.Println(stdJSON(val))
}

var re = regexp.MustCompile(`([:,])\s|`)

func printJSONString(val string) {
v := re.ReplaceAllString(val, `$1`)
fmt.Println(v)
}
54 changes: 43 additions & 11 deletions tests/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,11 @@ func Example_queryWithUser() {
func Example_queryWithDynamicOrderBy() {
gql := `
query getProducts {
products(order_by: $order, where: { id: { lt: 6 } }, limit: 5) {
products(
order_by: $order,
where: { id: { lt: 6 } },
limit: 5,
before: $cursor) {
id
price
}
Expand All @@ -124,6 +128,12 @@ func Example_queryWithDynamicOrderBy() {
}},
})

type result struct {
Products json.RawMessage `json:"products"`
Cursor string `json:"products_cursor"`
}
var val result

gj, err := core.NewGraphJin(conf, db)
if err != nil {
panic(err)
Expand All @@ -132,23 +142,45 @@ func Example_queryWithDynamicOrderBy() {
vars1 := json.RawMessage(`{ "order": "price_and_id" }`)

res1, err1 := gj.GraphQL(context.Background(), gql, vars1, nil)
if err != nil {
fmt.Println(err1)
} else {
printJSON(res1.Data)
if err1 != nil {
fmt.Println(err)
return
}

if err := json.Unmarshal(res1.Data, &val); err != nil {
fmt.Println(err)
return
}

if val.Cursor == "" {
fmt.Println("product_cursor value missing")
return
}
printJSONString(string(val.Products))

vars2 := json.RawMessage(`{ "order": "just_id" }`)

res2, err2 := gj.GraphQL(context.Background(), gql, vars2, nil)
if err != nil {
fmt.Println(err2)
} else {
printJSON(res2.Data)
if err2 != nil {
fmt.Println(err)
return
}

if err := json.Unmarshal(res2.Data, &val); err != nil {
fmt.Println(err)
return
}

if val.Cursor == "" {
fmt.Println("product_cursor value missing")
return
}

printJSONString(string(val.Products))

// Output:
//{"products":[{"id":5,"price":15.5},{"id":4,"price":14.5},{"id":3,"price":13.5},{"id":2,"price":12.5},{"id":1,"price":11.5}]}
//{"products":[{"id":1,"price":11.5},{"id":2,"price":12.5},{"id":3,"price":13.5},{"id":4,"price":14.5},{"id":5,"price":15.5}]}
//[{"id":5,"price":15.5},{"id":4,"price":14.5},{"id":3,"price":13.5},{"id":2,"price":12.5},{"id":1,"price":11.5}]
//[{"id":1,"price":11.5},{"id":2,"price":12.5},{"id":3,"price":13.5},{"id":4,"price":14.5},{"id":5,"price":15.5}]
}

func Example_queryWithNestedOrderBy() {
Expand Down

0 comments on commit bdb20fe

Please sign in to comment.