dgraph-io / dgraph

The high-performance database for modern applications
https://dgraph.io
Other
20.23k stars 1.48k forks source link

[BUG]: @unique mutation/query parser is not whitespace insensitive #9102

Open ppp225 opened 1 month ago

ppp225 commented 1 month ago

What version of Dgraph are you using?

v24.0.0, docker image

Tell us a little more about your go-environment?

No response

Have you tried reproducing the issue with the latest release?

None

What is the hardware spec (RAM, CPU, OS)?

not applicable

What steps will reproduce the bug?

apply the following schema

userEmail: string @index(hash) @unique @upsert .

run the mutation through dgo:

package main

import (
    "context"
    "encoding/json"
    "log"
    "time"

    "github.com/dgraph-io/dgo/v230"
    "github.com/dgraph-io/dgo/v230/protos/api"
    "google.golang.org/grpc"
)

type DbUser struct {
    UID   string `json:"uid,omitempty"`
    Email string `json:"userEmail,omitempty"`
}

func main() {
    user := DbUser{Email: "test@test.io"}
    userInsert, _ := json.Marshal(&user)

    q := `{UNIQS as var(func: eq(userEmail, "test@test.io")) { count: count(uid) }}`

    r := &api.Request{
        Query: q,
        Mutations: []*api.Mutation{
            {
                Cond:    "@if(eq(len(UNIQS), 0))",
                SetJson: userInsert,
            },
        },
    }

    gc, err := grpc.Dial("localhost:9080", grpc.WithInsecure())
    if err != nil {
        log.Fatal(err)
    }

    DG := dgo.NewDgraphClient(
        api.NewDgraphClient(gc),
    )

    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()

    txn := DG.NewTxn()
    _, err = txn.Do(ctx, r)
    if err != nil {
        panic(err)
    }

    txn.Commit(ctx)
}

Expected behavior and actual result.

Mutation fails with error:

rpc error: code = Unknown desc = while lexing {UNIQS as var(func: eq(userEmail, "test@test.io")) { count: count(uid) __dgraph_uniquecheck_0__ as var(func: eq(userEmail,"test@test.io"))__dgraph_upsertcheck_0__ as var(func: uid(0)) @filter(eq(len(UNIQS), 0))
} at line 2 column 1: Unclosed action

I expect it to work.

Additional information

Works without @unique. Works with @unique, when we modify the query to contain a space before the closing bracket:

    q := `{UNIQS as var(func: eq(userEmail, "test@test.io")) { count: count(uid) }}` // errors
    q := `{UNIQS as var(func: eq(userEmail, "test@test.io")) { count: count(uid) } }` // works
AoAnima commented 1 month ago

this is because in the dgraph/edgraph /server.go uses a string.trimRight(qc.req.Query, "}") , which should be replaced with qc.req.Query = strings.TrimSuffix(qc.req.Query, "}") so that only one closing "}" is deleted