Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
9f35f85857 | |||
f4f6420a30 |
@ -1,41 +0,0 @@
|
|||||||
INF roles_query not defined: attribute based access control disabled
|
|
||||||
all expectations were already fulfilled, call to Query 'SELECT jsonb_build_object('users', "__sj_0"."json", 'products', "__sj_1"."json") as "__root" FROM (SELECT coalesce(jsonb_agg("__sj_1"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_1".*) AS "json"FROM (SELECT "products_1"."id" AS "id", "products_1"."name" AS "name", "__sj_2"."json" AS "customers", "__sj_3"."json" AS "user" FROM (SELECT "products"."id", "products"."name", "products"."user_id" FROM "products" LIMIT ('20') :: integer) AS "products_1" LEFT OUTER JOIN LATERAL (SELECT to_jsonb("__sr_3".*) AS "json"FROM (SELECT "users_3"."full_name" AS "full_name", "users_3"."phone" AS "phone", "users_3"."email" AS "email" FROM (SELECT "users"."full_name", "users"."phone", "users"."email" FROM "users" WHERE ((("users"."id") = ("products_1"."user_id"))) LIMIT ('1') :: integer) AS "users_3") AS "__sr_3") AS "__sj_3" ON ('true') LEFT OUTER JOIN LATERAL (SELECT coalesce(jsonb_agg("__sj_2"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_2".*) AS "json"FROM (SELECT "customers_2"."id" AS "id", "customers_2"."email" AS "email" FROM (SELECT "customers"."id", "customers"."email" FROM "customers" LEFT OUTER JOIN "purchases" ON (("purchases"."product_id") = ("products_1"."id")) WHERE ((("customers"."id") = ("purchases"."customer_id"))) LIMIT ('20') :: integer) AS "customers_2") AS "__sr_2") AS "__sj_2") AS "__sj_2" ON ('true')) AS "__sr_1") AS "__sj_1") AS "__sj_1", (SELECT coalesce(jsonb_agg("__sj_0"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "users_0"."id" AS "id", "users_0"."name" AS "name" FROM (SELECT "users"."id" FROM "users" GROUP BY "users"."id" LIMIT ('20') :: integer) AS "users_0") AS "__sr_0") AS "__sj_0") AS "__sj_0"' with args [] was not expected
|
|
||||||
goos: darwin
|
|
||||||
goarch: amd64
|
|
||||||
pkg: github.com/dosco/super-graph/core
|
|
||||||
BenchmarkGraphQL-16 INF roles_query not defined: attribute based access control disabled
|
|
||||||
all expectations were already fulfilled, call to Query 'SELECT jsonb_build_object('users', "__sj_0"."json", 'products', "__sj_1"."json") as "__root" FROM (SELECT coalesce(jsonb_agg("__sj_1"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_1".*) AS "json"FROM (SELECT "products_1"."id" AS "id", "products_1"."name" AS "name", "__sj_2"."json" AS "customers", "__sj_3"."json" AS "user" FROM (SELECT "products"."id", "products"."name", "products"."user_id" FROM "products" LIMIT ('20') :: integer) AS "products_1" LEFT OUTER JOIN LATERAL (SELECT to_jsonb("__sr_3".*) AS "json"FROM (SELECT "users_3"."full_name" AS "full_name", "users_3"."phone" AS "phone", "users_3"."email" AS "email" FROM (SELECT "users"."full_name", "users"."phone", "users"."email" FROM "users" WHERE ((("users"."id") = ("products_1"."user_id"))) LIMIT ('1') :: integer) AS "users_3") AS "__sr_3") AS "__sj_3" ON ('true') LEFT OUTER JOIN LATERAL (SELECT coalesce(jsonb_agg("__sj_2"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_2".*) AS "json"FROM (SELECT "customers_2"."id" AS "id", "customers_2"."email" AS "email" FROM (SELECT "customers"."id", "customers"."email" FROM "customers" LEFT OUTER JOIN "purchases" ON (("purchases"."product_id") = ("products_1"."id")) WHERE ((("customers"."id") = ("purchases"."customer_id"))) LIMIT ('20') :: integer) AS "customers_2") AS "__sr_2") AS "__sj_2") AS "__sj_2" ON ('true')) AS "__sr_1") AS "__sj_1") AS "__sj_1", (SELECT coalesce(jsonb_agg("__sj_0"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "users_0"."id" AS "id", "users_0"."name" AS "name" FROM (SELECT "users"."id" FROM "users" GROUP BY "users"."id" LIMIT ('20') :: integer) AS "users_0") AS "__sr_0") AS "__sj_0") AS "__sj_0"' with args [] was not expected
|
|
||||||
INF roles_query not defined: attribute based access control disabled
|
|
||||||
all expectations were already fulfilled, call to Query 'SELECT jsonb_build_object('users', "__sj_0"."json", 'products', "__sj_1"."json") as "__root" FROM (SELECT coalesce(jsonb_agg("__sj_1"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_1".*) AS "json"FROM (SELECT "products_1"."id" AS "id", "products_1"."name" AS "name", "__sj_2"."json" AS "customers", "__sj_3"."json" AS "user" FROM (SELECT "products"."id", "products"."name", "products"."user_id" FROM "products" LIMIT ('20') :: integer) AS "products_1" LEFT OUTER JOIN LATERAL (SELECT to_jsonb("__sr_3".*) AS "json"FROM (SELECT "users_3"."full_name" AS "full_name", "users_3"."phone" AS "phone", "users_3"."email" AS "email" FROM (SELECT "users"."full_name", "users"."phone", "users"."email" FROM "users" WHERE ((("users"."id") = ("products_1"."user_id"))) LIMIT ('1') :: integer) AS "users_3") AS "__sr_3") AS "__sj_3" ON ('true') LEFT OUTER JOIN LATERAL (SELECT coalesce(jsonb_agg("__sj_2"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_2".*) AS "json"FROM (SELECT "customers_2"."id" AS "id", "customers_2"."email" AS "email" FROM (SELECT "customers"."id", "customers"."email" FROM "customers" LEFT OUTER JOIN "purchases" ON (("purchases"."product_id") = ("products_1"."id")) WHERE ((("customers"."id") = ("purchases"."customer_id"))) LIMIT ('20') :: integer) AS "customers_2") AS "__sr_2") AS "__sj_2") AS "__sj_2" ON ('true')) AS "__sr_1") AS "__sj_1") AS "__sj_1", (SELECT coalesce(jsonb_agg("__sj_0"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "users_0"."id" AS "id", "users_0"."name" AS "name" FROM (SELECT "users"."id" FROM "users" GROUP BY "users"."id" LIMIT ('20') :: integer) AS "users_0") AS "__sr_0") AS "__sj_0") AS "__sj_0"' with args [] was not expected
|
|
||||||
INF roles_query not defined: attribute based access control disabled
|
|
||||||
all expectations were already fulfilled, call to Query 'SELECT jsonb_build_object('users', "__sj_0"."json", 'products', "__sj_1"."json") as "__root" FROM (SELECT coalesce(jsonb_agg("__sj_1"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_1".*) AS "json"FROM (SELECT "products_1"."id" AS "id", "products_1"."name" AS "name", "__sj_2"."json" AS "customers", "__sj_3"."json" AS "user" FROM (SELECT "products"."id", "products"."name", "products"."user_id" FROM "products" LIMIT ('20') :: integer) AS "products_1" LEFT OUTER JOIN LATERAL (SELECT to_jsonb("__sr_3".*) AS "json"FROM (SELECT "users_3"."full_name" AS "full_name", "users_3"."phone" AS "phone", "users_3"."email" AS "email" FROM (SELECT "users"."full_name", "users"."phone", "users"."email" FROM "users" WHERE ((("users"."id") = ("products_1"."user_id"))) LIMIT ('1') :: integer) AS "users_3") AS "__sr_3") AS "__sj_3" ON ('true') LEFT OUTER JOIN LATERAL (SELECT coalesce(jsonb_agg("__sj_2"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_2".*) AS "json"FROM (SELECT "customers_2"."id" AS "id", "customers_2"."email" AS "email" FROM (SELECT "customers"."id", "customers"."email" FROM "customers" LEFT OUTER JOIN "purchases" ON (("purchases"."product_id") = ("products_1"."id")) WHERE ((("customers"."id") = ("purchases"."customer_id"))) LIMIT ('20') :: integer) AS "customers_2") AS "__sr_2") AS "__sj_2") AS "__sj_2" ON ('true')) AS "__sr_1") AS "__sj_1") AS "__sj_1", (SELECT coalesce(jsonb_agg("__sj_0"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "users_0"."id" AS "id", "users_0"."name" AS "name" FROM (SELECT "users"."id" FROM "users" GROUP BY "users"."id" LIMIT ('20') :: integer) AS "users_0") AS "__sr_0") AS "__sj_0") AS "__sj_0"' with args [] was not expected
|
|
||||||
105048 10398 ns/op 18342 B/op 55 allocs/op
|
|
||||||
PASS
|
|
||||||
ok github.com/dosco/super-graph/core 1.328s
|
|
||||||
PASS
|
|
||||||
ok github.com/dosco/super-graph/core/internal/allow 0.088s
|
|
||||||
? github.com/dosco/super-graph/core/internal/crypto [no test files]
|
|
||||||
? github.com/dosco/super-graph/core/internal/integration_tests [no test files]
|
|
||||||
PASS
|
|
||||||
ok github.com/dosco/super-graph/core/internal/integration_tests/cockroachdb 0.121s
|
|
||||||
PASS
|
|
||||||
ok github.com/dosco/super-graph/core/internal/integration_tests/postgresql 0.118s
|
|
||||||
goos: darwin
|
|
||||||
goarch: amd64
|
|
||||||
pkg: github.com/dosco/super-graph/core/internal/psql
|
|
||||||
BenchmarkCompile-16 79845 14428 ns/op 4584 B/op 39 allocs/op
|
|
||||||
BenchmarkCompileParallel-16 326205 3918 ns/op 4633 B/op 39 allocs/op
|
|
||||||
PASS
|
|
||||||
ok github.com/dosco/super-graph/core/internal/psql 2.696s
|
|
||||||
goos: darwin
|
|
||||||
goarch: amd64
|
|
||||||
pkg: github.com/dosco/super-graph/core/internal/qcode
|
|
||||||
BenchmarkQCompile-16 146953 8049 ns/op 3756 B/op 28 allocs/op
|
|
||||||
BenchmarkQCompileP-16 475936 2447 ns/op 3790 B/op 28 allocs/op
|
|
||||||
BenchmarkParse-16 140811 8163 ns/op 3902 B/op 18 allocs/op
|
|
||||||
BenchmarkParseP-16 571345 2041 ns/op 3903 B/op 18 allocs/op
|
|
||||||
BenchmarkSchemaParse-16 230715 5012 ns/op 3968 B/op 57 allocs/op
|
|
||||||
BenchmarkSchemaParseP-16 802426 1565 ns/op 3968 B/op 57 allocs/op
|
|
||||||
PASS
|
|
||||||
ok github.com/dosco/super-graph/core/internal/qcode 8.427s
|
|
||||||
? github.com/dosco/super-graph/core/internal/util [no test files]
|
|
@ -299,9 +299,13 @@ func (al *List) save(item Item) error {
|
|||||||
|
|
||||||
for _, v := range list {
|
for _, v := range list {
|
||||||
if v.Comment != "" {
|
if v.Comment != "" {
|
||||||
f.WriteString(fmt.Sprintf("/* %s */\n\n", v.Comment))
|
_, err = f.WriteString(fmt.Sprintf("/* %s */\n\n", v.Comment))
|
||||||
} else {
|
} else {
|
||||||
f.WriteString(fmt.Sprintf("/* %s */\n\n", v.Name))
|
_, err = f.WriteString(fmt.Sprintf("/* %s */\n\n", v.Name))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.Vars != "" {
|
if v.Vars != "" {
|
||||||
@ -320,18 +324,6 @@ func (al *List) save(item Item) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchPrefix(b []byte, i int, s string) bool {
|
|
||||||
if (len(b) - i) < len(s) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for n := 0; n < len(s); n++ {
|
|
||||||
if b[(i+n)] != s[n] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func QueryName(b string) string {
|
func QueryName(b string) string {
|
||||||
state, s := 0, 0
|
state, s := 0, 0
|
||||||
|
|
||||||
|
@ -220,10 +220,8 @@ func (co *Compiler) compileQueryWithMetadata(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(sel.Args) != 0 {
|
if len(sel.Args) != 0 {
|
||||||
i := 0
|
|
||||||
for _, v := range sel.Args {
|
for _, v := range sel.Args {
|
||||||
qcode.FreeNode(v, 500)
|
qcode.FreeNode(v)
|
||||||
i++
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -381,6 +381,26 @@ func withFragment3(t *testing.T) {
|
|||||||
compileGQLToPSQL(t, gql, nil, "anon")
|
compileGQLToPSQL(t, gql, nil, "anon")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func withInlineFragment(t *testing.T) {
|
||||||
|
gql := `
|
||||||
|
query {
|
||||||
|
users {
|
||||||
|
... on users {
|
||||||
|
id
|
||||||
|
email
|
||||||
|
}
|
||||||
|
created_at
|
||||||
|
... on user {
|
||||||
|
first_name
|
||||||
|
last_name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
compileGQLToPSQL(t, gql, nil, "anon")
|
||||||
|
}
|
||||||
|
|
||||||
func withCursor(t *testing.T) {
|
func withCursor(t *testing.T) {
|
||||||
gql := `query {
|
gql := `query {
|
||||||
Products(
|
Products(
|
||||||
@ -477,6 +497,7 @@ func TestCompileQuery(t *testing.T) {
|
|||||||
t.Run("withFragment1", withFragment1)
|
t.Run("withFragment1", withFragment1)
|
||||||
t.Run("withFragment2", withFragment2)
|
t.Run("withFragment2", withFragment2)
|
||||||
t.Run("withFragment3", withFragment3)
|
t.Run("withFragment3", withFragment3)
|
||||||
|
t.Run("withInlineFragment", withInlineFragment)
|
||||||
t.Run("jsonColumnAsTable", jsonColumnAsTable)
|
t.Run("jsonColumnAsTable", jsonColumnAsTable)
|
||||||
t.Run("withCursor", withCursor)
|
t.Run("withCursor", withCursor)
|
||||||
t.Run("nullForAuthRequiredInAnon", nullForAuthRequiredInAnon)
|
t.Run("nullForAuthRequiredInAnon", nullForAuthRequiredInAnon)
|
||||||
|
@ -8,8 +8,8 @@ WITH "_sg_input" AS (SELECT $1 :: json AS j), "products" AS (INSERT INTO "produc
|
|||||||
=== RUN TestCompileInsert/simpleInsertWithPresets
|
=== RUN TestCompileInsert/simpleInsertWithPresets
|
||||||
WITH "_sg_input" AS (SELECT $1 :: json AS j), "products" AS (INSERT INTO "products" ("name", "price", "created_at", "updated_at", "user_id") SELECT CAST( i.j ->>'name' AS character varying), CAST( i.j ->>'price' AS numeric(7,2)), 'now' :: timestamp without time zone, 'now' :: timestamp without time zone, $2 :: bigint FROM "_sg_input" i RETURNING *) SELECT jsonb_build_object('product', "__sj_0"."json") as "__root" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "products_0"."id" AS "id" FROM (SELECT "products"."id" FROM "products" LIMIT ('1') :: integer) AS "products_0") AS "__sr_0") AS "__sj_0"
|
WITH "_sg_input" AS (SELECT $1 :: json AS j), "products" AS (INSERT INTO "products" ("name", "price", "created_at", "updated_at", "user_id") SELECT CAST( i.j ->>'name' AS character varying), CAST( i.j ->>'price' AS numeric(7,2)), 'now' :: timestamp without time zone, 'now' :: timestamp without time zone, $2 :: bigint FROM "_sg_input" i RETURNING *) SELECT jsonb_build_object('product', "__sj_0"."json") as "__root" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "products_0"."id" AS "id" FROM (SELECT "products"."id" FROM "products" LIMIT ('1') :: integer) AS "products_0") AS "__sr_0") AS "__sj_0"
|
||||||
=== RUN TestCompileInsert/nestedInsertManyToMany
|
=== RUN TestCompileInsert/nestedInsertManyToMany
|
||||||
WITH "_sg_input" AS (SELECT $1 :: json AS j), "customers" AS (INSERT INTO "customers" ("full_name", "email") SELECT CAST( i.j ->>'full_name' AS character varying), CAST( i.j ->>'email' AS character varying) FROM "_sg_input" i RETURNING *), "products" AS (INSERT INTO "products" ("name", "price") SELECT CAST( i.j ->>'name' AS character varying), CAST( i.j ->>'price' AS numeric(7,2)) FROM "_sg_input" i RETURNING *), "purchases" AS (INSERT INTO "purchases" ("sale_type", "quantity", "due_date", "product_id", "customer_id") SELECT CAST( i.j ->>'sale_type' AS character varying), CAST( i.j ->>'quantity' AS integer), CAST( i.j ->>'due_date' AS timestamp without time zone), "products"."id", "customers"."id" FROM "_sg_input" i, "products", "customers" RETURNING *) SELECT jsonb_build_object('purchase', "__sj_0"."json") as "__root" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "purchases_0"."sale_type" AS "sale_type", "purchases_0"."quantity" AS "quantity", "purchases_0"."due_date" AS "due_date", "__sj_1"."json" AS "product", "__sj_2"."json" AS "customer" FROM (SELECT "purchases"."sale_type", "purchases"."quantity", "purchases"."due_date", "purchases"."product_id", "purchases"."customer_id" FROM "purchases" LIMIT ('1') :: integer) AS "purchases_0" LEFT OUTER JOIN LATERAL (SELECT to_jsonb("__sr_2".*) AS "json"FROM (SELECT "customers_2"."id" AS "id", "customers_2"."full_name" AS "full_name", "customers_2"."email" AS "email" FROM (SELECT "customers"."id", "customers"."full_name", "customers"."email" FROM "customers" WHERE ((("customers"."id") = ("purchases_0"."customer_id"))) LIMIT ('1') :: integer) AS "customers_2") AS "__sr_2") AS "__sj_2" ON ('true') LEFT OUTER JOIN LATERAL (SELECT to_jsonb("__sr_1".*) AS "json"FROM (SELECT "products_1"."id" AS "id", "products_1"."name" AS "name", "products_1"."price" AS "price" FROM (SELECT "products"."id", "products"."name", "products"."price" FROM "products" WHERE ((("products"."id") = ("purchases_0"."product_id"))) LIMIT ('1') :: integer) AS "products_1") AS "__sr_1") AS "__sj_1" ON ('true')) AS "__sr_0") AS "__sj_0"
|
|
||||||
WITH "_sg_input" AS (SELECT $1 :: json AS j), "products" AS (INSERT INTO "products" ("name", "price") SELECT CAST( i.j ->>'name' AS character varying), CAST( i.j ->>'price' AS numeric(7,2)) FROM "_sg_input" i RETURNING *), "customers" AS (INSERT INTO "customers" ("full_name", "email") SELECT CAST( i.j ->>'full_name' AS character varying), CAST( i.j ->>'email' AS character varying) FROM "_sg_input" i RETURNING *), "purchases" AS (INSERT INTO "purchases" ("sale_type", "quantity", "due_date", "customer_id", "product_id") SELECT CAST( i.j ->>'sale_type' AS character varying), CAST( i.j ->>'quantity' AS integer), CAST( i.j ->>'due_date' AS timestamp without time zone), "customers"."id", "products"."id" FROM "_sg_input" i, "customers", "products" RETURNING *) SELECT jsonb_build_object('purchase', "__sj_0"."json") as "__root" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "purchases_0"."sale_type" AS "sale_type", "purchases_0"."quantity" AS "quantity", "purchases_0"."due_date" AS "due_date", "__sj_1"."json" AS "product", "__sj_2"."json" AS "customer" FROM (SELECT "purchases"."sale_type", "purchases"."quantity", "purchases"."due_date", "purchases"."product_id", "purchases"."customer_id" FROM "purchases" LIMIT ('1') :: integer) AS "purchases_0" LEFT OUTER JOIN LATERAL (SELECT to_jsonb("__sr_2".*) AS "json"FROM (SELECT "customers_2"."id" AS "id", "customers_2"."full_name" AS "full_name", "customers_2"."email" AS "email" FROM (SELECT "customers"."id", "customers"."full_name", "customers"."email" FROM "customers" WHERE ((("customers"."id") = ("purchases_0"."customer_id"))) LIMIT ('1') :: integer) AS "customers_2") AS "__sr_2") AS "__sj_2" ON ('true') LEFT OUTER JOIN LATERAL (SELECT to_jsonb("__sr_1".*) AS "json"FROM (SELECT "products_1"."id" AS "id", "products_1"."name" AS "name", "products_1"."price" AS "price" FROM (SELECT "products"."id", "products"."name", "products"."price" FROM "products" WHERE ((("products"."id") = ("purchases_0"."product_id"))) LIMIT ('1') :: integer) AS "products_1") AS "__sr_1") AS "__sj_1" ON ('true')) AS "__sr_0") AS "__sj_0"
|
WITH "_sg_input" AS (SELECT $1 :: json AS j), "products" AS (INSERT INTO "products" ("name", "price") SELECT CAST( i.j ->>'name' AS character varying), CAST( i.j ->>'price' AS numeric(7,2)) FROM "_sg_input" i RETURNING *), "customers" AS (INSERT INTO "customers" ("full_name", "email") SELECT CAST( i.j ->>'full_name' AS character varying), CAST( i.j ->>'email' AS character varying) FROM "_sg_input" i RETURNING *), "purchases" AS (INSERT INTO "purchases" ("sale_type", "quantity", "due_date", "customer_id", "product_id") SELECT CAST( i.j ->>'sale_type' AS character varying), CAST( i.j ->>'quantity' AS integer), CAST( i.j ->>'due_date' AS timestamp without time zone), "customers"."id", "products"."id" FROM "_sg_input" i, "customers", "products" RETURNING *) SELECT jsonb_build_object('purchase', "__sj_0"."json") as "__root" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "purchases_0"."sale_type" AS "sale_type", "purchases_0"."quantity" AS "quantity", "purchases_0"."due_date" AS "due_date", "__sj_1"."json" AS "product", "__sj_2"."json" AS "customer" FROM (SELECT "purchases"."sale_type", "purchases"."quantity", "purchases"."due_date", "purchases"."product_id", "purchases"."customer_id" FROM "purchases" LIMIT ('1') :: integer) AS "purchases_0" LEFT OUTER JOIN LATERAL (SELECT to_jsonb("__sr_2".*) AS "json"FROM (SELECT "customers_2"."id" AS "id", "customers_2"."full_name" AS "full_name", "customers_2"."email" AS "email" FROM (SELECT "customers"."id", "customers"."full_name", "customers"."email" FROM "customers" WHERE ((("customers"."id") = ("purchases_0"."customer_id"))) LIMIT ('1') :: integer) AS "customers_2") AS "__sr_2") AS "__sj_2" ON ('true') LEFT OUTER JOIN LATERAL (SELECT to_jsonb("__sr_1".*) AS "json"FROM (SELECT "products_1"."id" AS "id", "products_1"."name" AS "name", "products_1"."price" AS "price" FROM (SELECT "products"."id", "products"."name", "products"."price" FROM "products" WHERE ((("products"."id") = ("purchases_0"."product_id"))) LIMIT ('1') :: integer) AS "products_1") AS "__sr_1") AS "__sj_1" ON ('true')) AS "__sr_0") AS "__sj_0"
|
||||||
|
WITH "_sg_input" AS (SELECT $1 :: json AS j), "customers" AS (INSERT INTO "customers" ("full_name", "email") SELECT CAST( i.j ->>'full_name' AS character varying), CAST( i.j ->>'email' AS character varying) FROM "_sg_input" i RETURNING *), "products" AS (INSERT INTO "products" ("name", "price") SELECT CAST( i.j ->>'name' AS character varying), CAST( i.j ->>'price' AS numeric(7,2)) FROM "_sg_input" i RETURNING *), "purchases" AS (INSERT INTO "purchases" ("sale_type", "quantity", "due_date", "product_id", "customer_id") SELECT CAST( i.j ->>'sale_type' AS character varying), CAST( i.j ->>'quantity' AS integer), CAST( i.j ->>'due_date' AS timestamp without time zone), "products"."id", "customers"."id" FROM "_sg_input" i, "products", "customers" RETURNING *) SELECT jsonb_build_object('purchase', "__sj_0"."json") as "__root" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "purchases_0"."sale_type" AS "sale_type", "purchases_0"."quantity" AS "quantity", "purchases_0"."due_date" AS "due_date", "__sj_1"."json" AS "product", "__sj_2"."json" AS "customer" FROM (SELECT "purchases"."sale_type", "purchases"."quantity", "purchases"."due_date", "purchases"."product_id", "purchases"."customer_id" FROM "purchases" LIMIT ('1') :: integer) AS "purchases_0" LEFT OUTER JOIN LATERAL (SELECT to_jsonb("__sr_2".*) AS "json"FROM (SELECT "customers_2"."id" AS "id", "customers_2"."full_name" AS "full_name", "customers_2"."email" AS "email" FROM (SELECT "customers"."id", "customers"."full_name", "customers"."email" FROM "customers" WHERE ((("customers"."id") = ("purchases_0"."customer_id"))) LIMIT ('1') :: integer) AS "customers_2") AS "__sr_2") AS "__sj_2" ON ('true') LEFT OUTER JOIN LATERAL (SELECT to_jsonb("__sr_1".*) AS "json"FROM (SELECT "products_1"."id" AS "id", "products_1"."name" AS "name", "products_1"."price" AS "price" FROM (SELECT "products"."id", "products"."name", "products"."price" FROM "products" WHERE ((("products"."id") = ("purchases_0"."product_id"))) LIMIT ('1') :: integer) AS "products_1") AS "__sr_1") AS "__sj_1" ON ('true')) AS "__sr_0") AS "__sj_0"
|
||||||
=== RUN TestCompileInsert/nestedInsertOneToMany
|
=== RUN TestCompileInsert/nestedInsertOneToMany
|
||||||
WITH "_sg_input" AS (SELECT $1 :: json AS j), "users" AS (INSERT INTO "users" ("full_name", "email", "created_at", "updated_at") SELECT CAST( i.j ->>'full_name' AS character varying), CAST( i.j ->>'email' AS character varying), CAST( i.j ->>'created_at' AS timestamp without time zone), CAST( i.j ->>'updated_at' AS timestamp without time zone) FROM "_sg_input" i RETURNING *), "products" AS (INSERT INTO "products" ("name", "price", "created_at", "updated_at", "user_id") SELECT CAST( i.j ->>'name' AS character varying), CAST( i.j ->>'price' AS numeric(7,2)), CAST( i.j ->>'created_at' AS timestamp without time zone), CAST( i.j ->>'updated_at' AS timestamp without time zone), "users"."id" FROM "_sg_input" i, "users" RETURNING *) SELECT jsonb_build_object('user', "__sj_0"."json") as "__root" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "users_0"."id" AS "id", "users_0"."full_name" AS "full_name", "users_0"."email" AS "email", "__sj_1"."json" AS "product" FROM (SELECT "users"."id", "users"."full_name", "users"."email" FROM "users" LIMIT ('1') :: integer) AS "users_0" LEFT OUTER JOIN LATERAL (SELECT to_jsonb("__sr_1".*) AS "json"FROM (SELECT "products_1"."id" AS "id", "products_1"."name" AS "name", "products_1"."price" AS "price" FROM (SELECT "products"."id", "products"."name", "products"."price" FROM "products" WHERE ((("products"."user_id") = ("users_0"."id"))) LIMIT ('1') :: integer) AS "products_1") AS "__sr_1") AS "__sj_1" ON ('true')) AS "__sr_0") AS "__sj_0"
|
WITH "_sg_input" AS (SELECT $1 :: json AS j), "users" AS (INSERT INTO "users" ("full_name", "email", "created_at", "updated_at") SELECT CAST( i.j ->>'full_name' AS character varying), CAST( i.j ->>'email' AS character varying), CAST( i.j ->>'created_at' AS timestamp without time zone), CAST( i.j ->>'updated_at' AS timestamp without time zone) FROM "_sg_input" i RETURNING *), "products" AS (INSERT INTO "products" ("name", "price", "created_at", "updated_at", "user_id") SELECT CAST( i.j ->>'name' AS character varying), CAST( i.j ->>'price' AS numeric(7,2)), CAST( i.j ->>'created_at' AS timestamp without time zone), CAST( i.j ->>'updated_at' AS timestamp without time zone), "users"."id" FROM "_sg_input" i, "users" RETURNING *) SELECT jsonb_build_object('user', "__sj_0"."json") as "__root" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "users_0"."id" AS "id", "users_0"."full_name" AS "full_name", "users_0"."email" AS "email", "__sj_1"."json" AS "product" FROM (SELECT "users"."id", "users"."full_name", "users"."email" FROM "users" LIMIT ('1') :: integer) AS "users_0" LEFT OUTER JOIN LATERAL (SELECT to_jsonb("__sr_1".*) AS "json"FROM (SELECT "products_1"."id" AS "id", "products_1"."name" AS "name", "products_1"."price" AS "price" FROM (SELECT "products"."id", "products"."name", "products"."price" FROM "products" WHERE ((("products"."user_id") = ("users_0"."id"))) LIMIT ('1') :: integer) AS "products_1") AS "__sr_1") AS "__sj_1" ON ('true')) AS "__sr_0") AS "__sj_0"
|
||||||
=== RUN TestCompileInsert/nestedInsertOneToOne
|
=== RUN TestCompileInsert/nestedInsertOneToOne
|
||||||
@ -20,7 +20,7 @@ WITH "_sg_input" AS (SELECT $1 :: json AS j), "users" AS (INSERT INTO "users" ("
|
|||||||
WITH "_sg_input" AS (SELECT $1 :: json AS j), "_x_users" AS (SELECT "id" FROM "_sg_input" i,"users" WHERE "users"."id"= ((i.j->'user'->'connect'->>'id'))::bigint LIMIT 1), "products" AS (INSERT INTO "products" ("name", "price", "created_at", "updated_at", "user_id") SELECT CAST( i.j ->>'name' AS character varying), CAST( i.j ->>'price' AS numeric(7,2)), CAST( i.j ->>'created_at' AS timestamp without time zone), CAST( i.j ->>'updated_at' AS timestamp without time zone), "_x_users"."id" FROM "_sg_input" i, "_x_users" RETURNING *) SELECT jsonb_build_object('product', "__sj_0"."json") as "__root" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "products_0"."id" AS "id", "products_0"."name" AS "name", "__sj_1"."json" AS "user", "__sj_2"."json" AS "tags" FROM (SELECT "products"."id", "products"."name", "products"."user_id", "products"."tags" FROM "products" LIMIT ('1') :: integer) AS "products_0" LEFT OUTER JOIN LATERAL (SELECT coalesce(jsonb_agg("__sj_2"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_2".*) AS "json"FROM (SELECT "tags_2"."id" AS "id", "tags_2"."name" AS "name" FROM (SELECT "tags"."id", "tags"."name" FROM "tags" WHERE ((("tags"."slug") = any ("products_0"."tags"))) LIMIT ('20') :: integer) AS "tags_2") AS "__sr_2") AS "__sj_2") AS "__sj_2" ON ('true') LEFT OUTER JOIN LATERAL (SELECT to_jsonb("__sr_1".*) AS "json"FROM (SELECT "users_1"."id" AS "id", "users_1"."full_name" AS "full_name", "users_1"."email" AS "email" FROM (SELECT "users"."id", "users"."full_name", "users"."email" FROM "users" WHERE ((("users"."id") = ("products_0"."user_id"))) LIMIT ('1') :: integer) AS "users_1") AS "__sr_1") AS "__sj_1" ON ('true')) AS "__sr_0") AS "__sj_0"
|
WITH "_sg_input" AS (SELECT $1 :: json AS j), "_x_users" AS (SELECT "id" FROM "_sg_input" i,"users" WHERE "users"."id"= ((i.j->'user'->'connect'->>'id'))::bigint LIMIT 1), "products" AS (INSERT INTO "products" ("name", "price", "created_at", "updated_at", "user_id") SELECT CAST( i.j ->>'name' AS character varying), CAST( i.j ->>'price' AS numeric(7,2)), CAST( i.j ->>'created_at' AS timestamp without time zone), CAST( i.j ->>'updated_at' AS timestamp without time zone), "_x_users"."id" FROM "_sg_input" i, "_x_users" RETURNING *) SELECT jsonb_build_object('product', "__sj_0"."json") as "__root" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "products_0"."id" AS "id", "products_0"."name" AS "name", "__sj_1"."json" AS "user", "__sj_2"."json" AS "tags" FROM (SELECT "products"."id", "products"."name", "products"."user_id", "products"."tags" FROM "products" LIMIT ('1') :: integer) AS "products_0" LEFT OUTER JOIN LATERAL (SELECT coalesce(jsonb_agg("__sj_2"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_2".*) AS "json"FROM (SELECT "tags_2"."id" AS "id", "tags_2"."name" AS "name" FROM (SELECT "tags"."id", "tags"."name" FROM "tags" WHERE ((("tags"."slug") = any ("products_0"."tags"))) LIMIT ('20') :: integer) AS "tags_2") AS "__sr_2") AS "__sj_2") AS "__sj_2" ON ('true') LEFT OUTER JOIN LATERAL (SELECT to_jsonb("__sr_1".*) AS "json"FROM (SELECT "users_1"."id" AS "id", "users_1"."full_name" AS "full_name", "users_1"."email" AS "email" FROM (SELECT "users"."id", "users"."full_name", "users"."email" FROM "users" WHERE ((("users"."id") = ("products_0"."user_id"))) LIMIT ('1') :: integer) AS "users_1") AS "__sr_1") AS "__sj_1" ON ('true')) AS "__sr_0") AS "__sj_0"
|
||||||
=== RUN TestCompileInsert/nestedInsertOneToOneWithConnectArray
|
=== RUN TestCompileInsert/nestedInsertOneToOneWithConnectArray
|
||||||
WITH "_sg_input" AS (SELECT $1 :: json AS j), "_x_users" AS (SELECT "id" FROM "_sg_input" i,"users" WHERE "users"."id" = ANY((select a::bigint AS list from json_array_elements_text((i.j->'user'->'connect'->>'id')::json) AS a)) LIMIT 1), "products" AS (INSERT INTO "products" ("name", "price", "created_at", "updated_at", "user_id") SELECT CAST( i.j ->>'name' AS character varying), CAST( i.j ->>'price' AS numeric(7,2)), CAST( i.j ->>'created_at' AS timestamp without time zone), CAST( i.j ->>'updated_at' AS timestamp without time zone), "_x_users"."id" FROM "_sg_input" i, "_x_users" RETURNING *) SELECT jsonb_build_object('product', "__sj_0"."json") as "__root" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "products_0"."id" AS "id", "products_0"."name" AS "name", "__sj_1"."json" AS "user" FROM (SELECT "products"."id", "products"."name", "products"."user_id" FROM "products" LIMIT ('1') :: integer) AS "products_0" LEFT OUTER JOIN LATERAL (SELECT to_jsonb("__sr_1".*) AS "json"FROM (SELECT "users_1"."id" AS "id", "users_1"."full_name" AS "full_name", "users_1"."email" AS "email" FROM (SELECT "users"."id", "users"."full_name", "users"."email" FROM "users" WHERE ((("users"."id") = ("products_0"."user_id"))) LIMIT ('1') :: integer) AS "users_1") AS "__sr_1") AS "__sj_1" ON ('true')) AS "__sr_0") AS "__sj_0"
|
WITH "_sg_input" AS (SELECT $1 :: json AS j), "_x_users" AS (SELECT "id" FROM "_sg_input" i,"users" WHERE "users"."id" = ANY((select a::bigint AS list from json_array_elements_text((i.j->'user'->'connect'->>'id')::json) AS a)) LIMIT 1), "products" AS (INSERT INTO "products" ("name", "price", "created_at", "updated_at", "user_id") SELECT CAST( i.j ->>'name' AS character varying), CAST( i.j ->>'price' AS numeric(7,2)), CAST( i.j ->>'created_at' AS timestamp without time zone), CAST( i.j ->>'updated_at' AS timestamp without time zone), "_x_users"."id" FROM "_sg_input" i, "_x_users" RETURNING *) SELECT jsonb_build_object('product', "__sj_0"."json") as "__root" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "products_0"."id" AS "id", "products_0"."name" AS "name", "__sj_1"."json" AS "user" FROM (SELECT "products"."id", "products"."name", "products"."user_id" FROM "products" LIMIT ('1') :: integer) AS "products_0" LEFT OUTER JOIN LATERAL (SELECT to_jsonb("__sr_1".*) AS "json"FROM (SELECT "users_1"."id" AS "id", "users_1"."full_name" AS "full_name", "users_1"."email" AS "email" FROM (SELECT "users"."id", "users"."full_name", "users"."email" FROM "users" WHERE ((("users"."id") = ("products_0"."user_id"))) LIMIT ('1') :: integer) AS "users_1") AS "__sr_1") AS "__sj_1" ON ('true')) AS "__sr_0") AS "__sj_0"
|
||||||
--- PASS: TestCompileInsert (0.02s)
|
--- PASS: TestCompileInsert (0.03s)
|
||||||
--- PASS: TestCompileInsert/simpleInsert (0.00s)
|
--- PASS: TestCompileInsert/simpleInsert (0.00s)
|
||||||
--- PASS: TestCompileInsert/singleInsert (0.00s)
|
--- PASS: TestCompileInsert/singleInsert (0.00s)
|
||||||
--- PASS: TestCompileInsert/bulkInsert (0.00s)
|
--- PASS: TestCompileInsert/bulkInsert (0.00s)
|
||||||
@ -92,6 +92,8 @@ SELECT jsonb_build_object('users', "__sj_0"."json") as "__root" FROM (SELECT coa
|
|||||||
SELECT jsonb_build_object('users', "__sj_0"."json") as "__root" FROM (SELECT coalesce(jsonb_agg("__sj_0"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "users_0"."first_name" AS "first_name", "users_0"."last_name" AS "last_name", "users_0"."created_at" AS "created_at", "users_0"."id" AS "id", "users_0"."email" AS "email" FROM (SELECT , "users"."created_at", "users"."id", "users"."email" FROM "users" GROUP BY "users"."created_at", "users"."id", "users"."email" LIMIT ('20') :: integer) AS "users_0") AS "__sr_0") AS "__sj_0") AS "__sj_0"
|
SELECT jsonb_build_object('users', "__sj_0"."json") as "__root" FROM (SELECT coalesce(jsonb_agg("__sj_0"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "users_0"."first_name" AS "first_name", "users_0"."last_name" AS "last_name", "users_0"."created_at" AS "created_at", "users_0"."id" AS "id", "users_0"."email" AS "email" FROM (SELECT , "users"."created_at", "users"."id", "users"."email" FROM "users" GROUP BY "users"."created_at", "users"."id", "users"."email" LIMIT ('20') :: integer) AS "users_0") AS "__sr_0") AS "__sj_0") AS "__sj_0"
|
||||||
=== RUN TestCompileQuery/withFragment3
|
=== RUN TestCompileQuery/withFragment3
|
||||||
SELECT jsonb_build_object('users', "__sj_0"."json") as "__root" FROM (SELECT coalesce(jsonb_agg("__sj_0"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "users_0"."first_name" AS "first_name", "users_0"."last_name" AS "last_name", "users_0"."created_at" AS "created_at", "users_0"."id" AS "id", "users_0"."email" AS "email" FROM (SELECT , "users"."created_at", "users"."id", "users"."email" FROM "users" GROUP BY "users"."created_at", "users"."id", "users"."email" LIMIT ('20') :: integer) AS "users_0") AS "__sr_0") AS "__sj_0") AS "__sj_0"
|
SELECT jsonb_build_object('users', "__sj_0"."json") as "__root" FROM (SELECT coalesce(jsonb_agg("__sj_0"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "users_0"."first_name" AS "first_name", "users_0"."last_name" AS "last_name", "users_0"."created_at" AS "created_at", "users_0"."id" AS "id", "users_0"."email" AS "email" FROM (SELECT , "users"."created_at", "users"."id", "users"."email" FROM "users" GROUP BY "users"."created_at", "users"."id", "users"."email" LIMIT ('20') :: integer) AS "users_0") AS "__sr_0") AS "__sj_0") AS "__sj_0"
|
||||||
|
=== RUN TestCompileQuery/withInlineFragment
|
||||||
|
SELECT jsonb_build_object('users', "__sj_0"."json") as "__root" FROM (SELECT coalesce(jsonb_agg("__sj_0"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "users_0"."id" AS "id", "users_0"."email" AS "email", "users_0"."created_at" AS "created_at", "users_0"."first_name" AS "first_name", "users_0"."last_name" AS "last_name" FROM (SELECT "users"."id", "users"."email", "users"."created_at" FROM "users" GROUP BY "users"."id", "users"."email", "users"."created_at" LIMIT ('20') :: integer) AS "users_0") AS "__sr_0") AS "__sj_0") AS "__sj_0"
|
||||||
=== RUN TestCompileQuery/jsonColumnAsTable
|
=== RUN TestCompileQuery/jsonColumnAsTable
|
||||||
SELECT jsonb_build_object('products', "__sj_0"."json") as "__root" FROM (SELECT coalesce(jsonb_agg("__sj_0"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "products_0"."id" AS "id", "products_0"."name" AS "name", "__sj_1"."json" AS "tag_count" FROM (SELECT "products"."id", "products"."name" FROM "products" LIMIT ('20') :: integer) AS "products_0" LEFT OUTER JOIN LATERAL (SELECT to_jsonb("__sr_1".*) AS "json"FROM (SELECT "tag_count_1"."count" AS "count", "__sj_2"."json" AS "tags" FROM (SELECT "tag_count"."count", "tag_count"."tag_id" FROM "products", json_to_recordset("products"."tag_count") AS "tag_count"(tag_id bigint, count int) WHERE ((("products"."id") = ("products_0"."id"))) LIMIT ('1') :: integer) AS "tag_count_1" LEFT OUTER JOIN LATERAL (SELECT coalesce(jsonb_agg("__sj_2"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_2".*) AS "json"FROM (SELECT "tags_2"."name" AS "name" FROM (SELECT "tags"."name" FROM "tags" WHERE ((("tags"."id") = ("tag_count_1"."tag_id"))) LIMIT ('20') :: integer) AS "tags_2") AS "__sr_2") AS "__sj_2") AS "__sj_2" ON ('true')) AS "__sr_1") AS "__sj_1" ON ('true')) AS "__sr_0") AS "__sj_0") AS "__sj_0"
|
SELECT jsonb_build_object('products', "__sj_0"."json") as "__root" FROM (SELECT coalesce(jsonb_agg("__sj_0"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_0".*) AS "json"FROM (SELECT "products_0"."id" AS "id", "products_0"."name" AS "name", "__sj_1"."json" AS "tag_count" FROM (SELECT "products"."id", "products"."name" FROM "products" LIMIT ('20') :: integer) AS "products_0" LEFT OUTER JOIN LATERAL (SELECT to_jsonb("__sr_1".*) AS "json"FROM (SELECT "tag_count_1"."count" AS "count", "__sj_2"."json" AS "tags" FROM (SELECT "tag_count"."count", "tag_count"."tag_id" FROM "products", json_to_recordset("products"."tag_count") AS "tag_count"(tag_id bigint, count int) WHERE ((("products"."id") = ("products_0"."id"))) LIMIT ('1') :: integer) AS "tag_count_1" LEFT OUTER JOIN LATERAL (SELECT coalesce(jsonb_agg("__sj_2"."json"), '[]') as "json" FROM (SELECT to_jsonb("__sr_2".*) AS "json"FROM (SELECT "tags_2"."name" AS "name" FROM (SELECT "tags"."name" FROM "tags" WHERE ((("tags"."id") = ("tag_count_1"."tag_id"))) LIMIT ('20') :: integer) AS "tags_2") AS "__sr_2") AS "__sj_2") AS "__sj_2" ON ('true')) AS "__sr_1") AS "__sj_1" ON ('true')) AS "__sr_0") AS "__sj_0") AS "__sj_0"
|
||||||
=== RUN TestCompileQuery/withCursor
|
=== RUN TestCompileQuery/withCursor
|
||||||
@ -126,6 +128,7 @@ SELECT jsonb_build_object('users', "__sj_0"."json") as "__root" FROM (SELECT coa
|
|||||||
--- PASS: TestCompileQuery/withFragment1 (0.00s)
|
--- PASS: TestCompileQuery/withFragment1 (0.00s)
|
||||||
--- PASS: TestCompileQuery/withFragment2 (0.00s)
|
--- PASS: TestCompileQuery/withFragment2 (0.00s)
|
||||||
--- PASS: TestCompileQuery/withFragment3 (0.00s)
|
--- PASS: TestCompileQuery/withFragment3 (0.00s)
|
||||||
|
--- PASS: TestCompileQuery/withInlineFragment (0.00s)
|
||||||
--- PASS: TestCompileQuery/jsonColumnAsTable (0.00s)
|
--- PASS: TestCompileQuery/jsonColumnAsTable (0.00s)
|
||||||
--- PASS: TestCompileQuery/withCursor (0.00s)
|
--- PASS: TestCompileQuery/withCursor (0.00s)
|
||||||
--- PASS: TestCompileQuery/nullForAuthRequiredInAnon (0.00s)
|
--- PASS: TestCompileQuery/nullForAuthRequiredInAnon (0.00s)
|
||||||
@ -160,4 +163,4 @@ WITH "_sg_input" AS (SELECT $1 :: json AS j), "_x_users" AS (SELECT * FROM (VALU
|
|||||||
--- PASS: TestCompileUpdate/nestedUpdateOneToOneWithConnect (0.00s)
|
--- PASS: TestCompileUpdate/nestedUpdateOneToOneWithConnect (0.00s)
|
||||||
--- PASS: TestCompileUpdate/nestedUpdateOneToOneWithDisconnect (0.00s)
|
--- PASS: TestCompileUpdate/nestedUpdateOneToOneWithDisconnect (0.00s)
|
||||||
PASS
|
PASS
|
||||||
ok github.com/dosco/super-graph/core/internal/psql 0.374s
|
ok github.com/dosco/super-graph/core/internal/psql 0.371s
|
||||||
|
13
core/internal/qcode/bench.11
Normal file
13
core/internal/qcode/bench.11
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
goos: darwin
|
||||||
|
goarch: amd64
|
||||||
|
pkg: github.com/dosco/super-graph/core/internal/qcode
|
||||||
|
BenchmarkQCompile-16 118282 9686 ns/op 4031 B/op 30 allocs/op
|
||||||
|
BenchmarkQCompileP-16 427531 2710 ns/op 4077 B/op 30 allocs/op
|
||||||
|
BenchmarkQCompileFragment-16 140588 8328 ns/op 8903 B/op 13 allocs/op
|
||||||
|
BenchmarkParse-16 131396 9212 ns/op 4175 B/op 18 allocs/op
|
||||||
|
BenchmarkParseP-16 503778 2310 ns/op 4176 B/op 18 allocs/op
|
||||||
|
BenchmarkParseFragment-16 143725 8158 ns/op 10193 B/op 9 allocs/op
|
||||||
|
BenchmarkSchemaParse-16 240609 5060 ns/op 3968 B/op 57 allocs/op
|
||||||
|
BenchmarkSchemaParseP-16 785116 1534 ns/op 3968 B/op 57 allocs/op
|
||||||
|
PASS
|
||||||
|
ok github.com/dosco/super-graph/core/internal/qcode 11.092s
|
@ -1,7 +1,6 @@
|
|||||||
package qcode
|
package qcode
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash/maphash"
|
"hash/maphash"
|
||||||
@ -35,7 +34,8 @@ const (
|
|||||||
NodeVar
|
NodeVar
|
||||||
)
|
)
|
||||||
|
|
||||||
type SelectionSet struct {
|
type Operation struct {
|
||||||
|
Type parserType
|
||||||
Name string
|
Name string
|
||||||
Args []Arg
|
Args []Arg
|
||||||
argsA [10]Arg
|
argsA [10]Arg
|
||||||
@ -43,11 +43,6 @@ type SelectionSet struct {
|
|||||||
fieldsA [10]Field
|
fieldsA [10]Field
|
||||||
}
|
}
|
||||||
|
|
||||||
type Operation struct {
|
|
||||||
Type parserType
|
|
||||||
SelectionSet
|
|
||||||
}
|
|
||||||
|
|
||||||
var zeroOperation = Operation{}
|
var zeroOperation = Operation{}
|
||||||
|
|
||||||
func (o *Operation) Reset() {
|
func (o *Operation) Reset() {
|
||||||
@ -55,9 +50,10 @@ func (o *Operation) Reset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Fragment struct {
|
type Fragment struct {
|
||||||
Name string
|
Name string
|
||||||
On string
|
On string
|
||||||
SelectionSet
|
Fields []Field
|
||||||
|
fieldsA [10]Field
|
||||||
}
|
}
|
||||||
|
|
||||||
var zeroFragment = Fragment{}
|
var zeroFragment = Fragment{}
|
||||||
@ -80,6 +76,7 @@ type Field struct {
|
|||||||
type Arg struct {
|
type Arg struct {
|
||||||
Name string
|
Name string
|
||||||
Val *Node
|
Val *Node
|
||||||
|
df bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Node struct {
|
type Node struct {
|
||||||
@ -158,9 +155,11 @@ func Parse(gql []byte) (*Operation, error) {
|
|||||||
|
|
||||||
if p.peek(itemFragment) {
|
if p.peek(itemFragment) {
|
||||||
p.ignore()
|
p.ignore()
|
||||||
if err = p.parseFragment(op); err != nil {
|
if f, err := p.parseFragment(false); err != nil {
|
||||||
|
fragPool.Put(f)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if !qf && p.peek(itemQuery, itemMutation, itemSub, itemObjOpen) {
|
if !qf && p.peek(itemQuery, itemMutation, itemSub, itemObjOpen) {
|
||||||
s = p.pos
|
s = p.pos
|
||||||
@ -175,53 +174,62 @@ func Parse(gql []byte) (*Operation, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, v := range p.frags {
|
||||||
|
fragPool.Put(v)
|
||||||
|
}
|
||||||
|
|
||||||
return op, nil
|
return op, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) parseFragment(op *Operation) error {
|
func (p *Parser) parseFragment(inline bool) (*Fragment, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
frag := fragPool.Get().(*Fragment)
|
frag := fragPool.Get().(*Fragment)
|
||||||
frag.Reset()
|
frag.Reset()
|
||||||
|
|
||||||
frag.Fields = frag.fieldsA[:0]
|
frag.Fields = frag.fieldsA[:0]
|
||||||
frag.Args = frag.argsA[:0]
|
|
||||||
|
|
||||||
if p.peek(itemName) {
|
if p.peek(itemName) {
|
||||||
frag.Name = p.val(p.next())
|
frag.Name = p.val(p.next())
|
||||||
|
} else if !inline {
|
||||||
|
return frag, errors.New("fragment: missing name")
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.peek(itemOn) {
|
if p.peek(itemOn) {
|
||||||
p.ignore()
|
p.ignore()
|
||||||
} else {
|
} else {
|
||||||
return errors.New("fragment: missing 'on' keyword")
|
return frag, errors.New("fragment: missing 'on' keyword")
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.peek(itemName) {
|
if p.peek(itemName) {
|
||||||
frag.On = p.vall(p.next())
|
frag.On = p.vall(p.next())
|
||||||
} else {
|
} else {
|
||||||
return errors.New("fragment: missing table name after 'on' keyword")
|
return frag, errors.New("fragment: missing table name after 'on' keyword")
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.peek(itemObjOpen) {
|
if p.peek(itemObjOpen) {
|
||||||
p.ignore()
|
p.ignore()
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("fragment: expecting a '{', got: %s", p.next())
|
return frag, fmt.Errorf("fragment: expecting a '{', got: %s", p.next())
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := p.parseSelectionSet(&frag.SelectionSet); err != nil {
|
frag.Fields, err = p.parseFields(frag.Fields)
|
||||||
return fmt.Errorf("fragment: %v", err)
|
if err != nil {
|
||||||
|
return frag, fmt.Errorf("fragment: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.frags == nil {
|
if !inline {
|
||||||
p.frags = make(map[uint64]*Fragment)
|
if p.frags == nil {
|
||||||
|
p.frags = make(map[uint64]*Fragment)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _ = p.h.WriteString(frag.Name)
|
||||||
|
k := p.h.Sum64()
|
||||||
|
p.h.Reset()
|
||||||
|
|
||||||
|
p.frags[k] = frag
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _ = p.h.WriteString(frag.Name)
|
return frag, nil
|
||||||
k := p.h.Sum64()
|
|
||||||
p.h.Reset()
|
|
||||||
|
|
||||||
p.frags[k] = frag
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) parseOp(op *Operation) error {
|
func (p *Parser) parseOp(op *Operation) error {
|
||||||
@ -249,7 +257,7 @@ func (p *Parser) parseOp(op *Operation) error {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
err = p.parseSelectionSet(&op.SelectionSet)
|
op.Fields, err = p.parseFields(op.Fields)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%s: %v", op.Type, err)
|
return fmt.Errorf("%s: %v", op.Type, err)
|
||||||
}
|
}
|
||||||
@ -293,17 +301,6 @@ func (p *Parser) parseOpTypeAndArgs(op *Operation) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) parseSelectionSet(selset *SelectionSet) error {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
selset.Fields, err = p.parseFields(selset.Fields)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseArgValue(argVal string) (*Node, error) {
|
func ParseArgValue(argVal string) (*Node, error) {
|
||||||
l := lexPool.Get().(*lexer)
|
l := lexPool.Get().(*lexer)
|
||||||
l.Reset()
|
l.Reset()
|
||||||
@ -324,6 +321,7 @@ func ParseArgValue(argVal string) (*Node, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) parseFields(fields []Field) ([]Field, error) {
|
func (p *Parser) parseFields(fields []Field) ([]Field, error) {
|
||||||
|
var err error
|
||||||
st := NewStack()
|
st := NewStack()
|
||||||
|
|
||||||
if !p.peek(itemName, itemSpread) {
|
if !p.peek(itemName, itemSpread) {
|
||||||
@ -358,83 +356,111 @@ func (p *Parser) parseFields(fields []Field) ([]Field, error) {
|
|||||||
isFrag = true
|
isFrag = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if !p.peek(itemName) {
|
|
||||||
if isFrag {
|
|
||||||
return nil, fmt.Errorf("expecting a fragment name, got: %s", p.next())
|
|
||||||
} else {
|
|
||||||
return nil, fmt.Errorf("expecting an alias or field name, got: %s", p.next())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var f *Field
|
|
||||||
|
|
||||||
if isFrag {
|
if isFrag {
|
||||||
name := p.val(p.next())
|
fields, err = p.parseFragmentFields(st, fields)
|
||||||
p.h.WriteString(name)
|
|
||||||
k := p.h.Sum64()
|
|
||||||
p.h.Reset()
|
|
||||||
|
|
||||||
fr, ok := p.frags[k]
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("no fragment named '%s' defined", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
n := int32(len(fields))
|
|
||||||
fields = append(fields, fr.Fields...)
|
|
||||||
|
|
||||||
for i := 0; i < len(fr.Fields); i++ {
|
|
||||||
k := (n + int32(i))
|
|
||||||
f := &fields[k]
|
|
||||||
f.ID = int32(k)
|
|
||||||
|
|
||||||
// If this is the top-level point the parent to the parent of the
|
|
||||||
// previous field.
|
|
||||||
if f.ParentID == -1 {
|
|
||||||
pid := st.Peek()
|
|
||||||
f.ParentID = pid
|
|
||||||
if f.ParentID != -1 {
|
|
||||||
fields[pid].Children = append(fields[f.ParentID].Children, f.ID)
|
|
||||||
}
|
|
||||||
// Update all the other parents id's by our new place in this new array
|
|
||||||
} else {
|
|
||||||
f.ParentID += n
|
|
||||||
}
|
|
||||||
|
|
||||||
f.Children = make([]int32, len(f.Children))
|
|
||||||
copy(f.Children, fr.Fields[i].Children)
|
|
||||||
|
|
||||||
// Update all the children which is needed.
|
|
||||||
for j := range f.Children {
|
|
||||||
f.Children[j] += n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
fields = append(fields, Field{ID: int32(len(fields))})
|
fields, err = p.parseNormalFields(st, fields)
|
||||||
|
|
||||||
f = &fields[(len(fields) - 1)]
|
|
||||||
f.Args = f.argsA[:0]
|
|
||||||
f.Children = f.childrenA[:0]
|
|
||||||
|
|
||||||
// Parse the field
|
|
||||||
if err := p.parseField(f); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if st.Len() == 0 {
|
|
||||||
f.ParentID = -1
|
|
||||||
} else {
|
|
||||||
pid := st.Peek()
|
|
||||||
f.ParentID = pid
|
|
||||||
fields[pid].Children = append(fields[pid].Children, f.ID)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The first opening curley brackets after this
|
if err != nil {
|
||||||
// comes the columns or child fields
|
return nil, err
|
||||||
if p.peek(itemObjOpen) {
|
}
|
||||||
p.ignore()
|
}
|
||||||
st.Push(f.ID)
|
|
||||||
|
return fields, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parser) parseNormalFields(st *Stack, fields []Field) ([]Field, error) {
|
||||||
|
if !p.peek(itemName) {
|
||||||
|
return nil, fmt.Errorf("expecting an alias or field name, got: %s", p.next())
|
||||||
|
}
|
||||||
|
|
||||||
|
fields = append(fields, Field{ID: int32(len(fields))})
|
||||||
|
|
||||||
|
f := &fields[(len(fields) - 1)]
|
||||||
|
f.Args = f.argsA[:0]
|
||||||
|
f.Children = f.childrenA[:0]
|
||||||
|
|
||||||
|
// Parse the field
|
||||||
|
if err := p.parseField(f); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if st.Len() == 0 {
|
||||||
|
f.ParentID = -1
|
||||||
|
} else {
|
||||||
|
pid := st.Peek()
|
||||||
|
f.ParentID = pid
|
||||||
|
fields[pid].Children = append(fields[pid].Children, f.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first opening curley brackets after this
|
||||||
|
// comes the columns or child fields
|
||||||
|
if p.peek(itemObjOpen) {
|
||||||
|
p.ignore()
|
||||||
|
st.Push(f.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fields, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parser) parseFragmentFields(st *Stack, fields []Field) ([]Field, error) {
|
||||||
|
var fr *Fragment
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if p.peek(itemOn) {
|
||||||
|
if fr, err = p.parseFragment(true); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer fragPool.Put(fr)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
var ok bool
|
||||||
|
|
||||||
|
if !p.peek(itemName) {
|
||||||
|
return nil, fmt.Errorf("expecting a fragment name, got: %s", p.next())
|
||||||
|
}
|
||||||
|
|
||||||
|
name := p.val(p.next())
|
||||||
|
_, _ = p.h.WriteString(name)
|
||||||
|
id := p.h.Sum64()
|
||||||
|
p.h.Reset()
|
||||||
|
|
||||||
|
if fr, ok = p.frags[id]; !ok {
|
||||||
|
return nil, fmt.Errorf("no fragment named '%s' defined", name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
n := int32(len(fields))
|
||||||
|
fields = append(fields, fr.Fields...)
|
||||||
|
|
||||||
|
for i := 0; i < len(fr.Fields); i++ {
|
||||||
|
k := (n + int32(i))
|
||||||
|
f := &fields[k]
|
||||||
|
f.ID = int32(k)
|
||||||
|
|
||||||
|
// If this is the top-level point the parent to the parent of the
|
||||||
|
// previous field.
|
||||||
|
if f.ParentID == -1 {
|
||||||
|
pid := st.Peek()
|
||||||
|
f.ParentID = pid
|
||||||
|
if f.ParentID != -1 {
|
||||||
|
fields[pid].Children = append(fields[f.ParentID].Children, f.ID)
|
||||||
|
}
|
||||||
|
// Update all the other parents id's by our new place in this new array
|
||||||
|
} else {
|
||||||
|
f.ParentID += n
|
||||||
|
}
|
||||||
|
|
||||||
|
f.Children = make([]int32, len(f.Children))
|
||||||
|
copy(f.Children, fr.Fields[i].Children)
|
||||||
|
|
||||||
|
f.Args = make([]Arg, len(f.Args))
|
||||||
|
copy(f.Args, fr.Fields[i].Args)
|
||||||
|
|
||||||
|
// Update all the children which is needed.
|
||||||
|
for j := range f.Children {
|
||||||
|
f.Children[j] += n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,6 +494,24 @@ func (p *Parser) parseField(f *Field) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func (p *Parser) parseInlineFragmentFields(st *Stack, fields []Field) ([]Field, error) {
|
||||||
|
// var err error
|
||||||
|
|
||||||
|
// if p.peek(itemName) {
|
||||||
|
// p.ignore()
|
||||||
|
// // frag.On = p.vall(p.next())
|
||||||
|
// } else {
|
||||||
|
// return nil, errors.New("inline fragment: missing table name after 'on' keyword")
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fields, err = p.parseNormalFields(st, fields)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, fmt.Errorf("inline fragment: %v", err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return fields, nil
|
||||||
|
// }
|
||||||
|
|
||||||
func (p *Parser) parseOpParams(args []Arg) ([]Arg, error) {
|
func (p *Parser) parseOpParams(args []Arg) ([]Arg, error) {
|
||||||
for {
|
for {
|
||||||
if len(args) >= maxArgs {
|
if len(args) >= maxArgs {
|
||||||
@ -676,11 +720,6 @@ func (p *Parser) ignore() {
|
|||||||
p.pos = n
|
p.pos = n
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) peekCurrent() string {
|
|
||||||
item := p.items[p.pos]
|
|
||||||
return b2s(p.input[item.pos:item.end])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Parser) peekNext() string {
|
func (p *Parser) peekNext() string {
|
||||||
item := p.items[p.pos+1]
|
item := p.items[p.pos+1]
|
||||||
return b2s(p.input[item.pos:item.end])
|
return b2s(p.input[item.pos:item.end])
|
||||||
@ -690,16 +729,6 @@ func (p *Parser) reset(to int) {
|
|||||||
p.pos = to
|
p.pos = to
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) fHash(name string, parentID int32) uint64 {
|
|
||||||
var b []byte
|
|
||||||
binary.LittleEndian.PutUint32(b, uint32(parentID))
|
|
||||||
p.h.WriteString(name)
|
|
||||||
p.h.Write(b)
|
|
||||||
v := p.h.Sum64()
|
|
||||||
p.h.Reset()
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func b2s(b []byte) string {
|
func b2s(b []byte) string {
|
||||||
return *(*string)(unsafe.Pointer(&b))
|
return *(*string)(unsafe.Pointer(&b))
|
||||||
}
|
}
|
||||||
@ -736,31 +765,6 @@ func (t parserType) String() string {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
// type Frees struct {
|
func FreeNode(n *Node) {
|
||||||
// n *Node
|
|
||||||
// loc int
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var freeList []Frees
|
|
||||||
|
|
||||||
// func FreeNode(n *Node, loc int) {
|
|
||||||
// j := -1
|
|
||||||
|
|
||||||
// for i := range freeList {
|
|
||||||
// if n == freeList[i].n {
|
|
||||||
// j = i
|
|
||||||
// break
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if j == -1 {
|
|
||||||
// nodePool.Put(n)
|
|
||||||
// freeList = append(freeList, Frees{n, loc})
|
|
||||||
// } else {
|
|
||||||
// fmt.Printf("(%d) RE_FREE %d %p %s %s\n", loc, freeList[j].loc, freeList[j].n, n.Name, n.Type)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
func FreeNode(n *Node, loc int) {
|
|
||||||
nodePool.Put(n)
|
nodePool.Put(n)
|
||||||
}
|
}
|
||||||
|
@ -277,6 +277,7 @@ func (com *Compiler) Compile(query []byte, role string) (*QCode, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
freeNodes(op)
|
||||||
opPool.Put(op)
|
opPool.Put(op)
|
||||||
|
|
||||||
return &qc, nil
|
return &qc, nil
|
||||||
@ -492,50 +493,42 @@ func (com *Compiler) AddFilters(qc *QCode, sel *Select, role string) {
|
|||||||
func (com *Compiler) compileArgs(qc *QCode, sel *Select, args []Arg, role string) error {
|
func (com *Compiler) compileArgs(qc *QCode, sel *Select, args []Arg, role string) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
// don't free this arg either previously done or will be free'd
|
|
||||||
// in the future like in psql
|
|
||||||
var df bool
|
|
||||||
|
|
||||||
for i := range args {
|
for i := range args {
|
||||||
arg := &args[i]
|
arg := &args[i]
|
||||||
|
|
||||||
switch arg.Name {
|
switch arg.Name {
|
||||||
case "id":
|
case "id":
|
||||||
err, df = com.compileArgID(sel, arg)
|
err = com.compileArgID(sel, arg)
|
||||||
|
|
||||||
case "search":
|
case "search":
|
||||||
err, df = com.compileArgSearch(sel, arg)
|
err = com.compileArgSearch(sel, arg)
|
||||||
|
|
||||||
case "where":
|
case "where":
|
||||||
err, df = com.compileArgWhere(sel, arg, role)
|
err = com.compileArgWhere(sel, arg, role)
|
||||||
|
|
||||||
case "orderby", "order_by", "order":
|
case "orderby", "order_by", "order":
|
||||||
err, df = com.compileArgOrderBy(sel, arg)
|
err = com.compileArgOrderBy(sel, arg)
|
||||||
|
|
||||||
case "distinct_on", "distinct":
|
case "distinct_on", "distinct":
|
||||||
err, df = com.compileArgDistinctOn(sel, arg)
|
err = com.compileArgDistinctOn(sel, arg)
|
||||||
|
|
||||||
case "limit":
|
case "limit":
|
||||||
err, df = com.compileArgLimit(sel, arg)
|
err = com.compileArgLimit(sel, arg)
|
||||||
|
|
||||||
case "offset":
|
case "offset":
|
||||||
err, df = com.compileArgOffset(sel, arg)
|
err = com.compileArgOffset(sel, arg)
|
||||||
|
|
||||||
case "first":
|
case "first":
|
||||||
err, df = com.compileArgFirstLast(sel, arg, PtForward)
|
err = com.compileArgFirstLast(sel, arg, PtForward)
|
||||||
|
|
||||||
case "last":
|
case "last":
|
||||||
err, df = com.compileArgFirstLast(sel, arg, PtBackward)
|
err = com.compileArgFirstLast(sel, arg, PtBackward)
|
||||||
|
|
||||||
case "after":
|
case "after":
|
||||||
err, df = com.compileArgAfterBefore(sel, arg, PtForward)
|
err = com.compileArgAfterBefore(sel, arg, PtForward)
|
||||||
|
|
||||||
case "before":
|
case "before":
|
||||||
err, df = com.compileArgAfterBefore(sel, arg, PtBackward)
|
err = com.compileArgAfterBefore(sel, arg, PtBackward)
|
||||||
}
|
|
||||||
|
|
||||||
if !df {
|
|
||||||
FreeNode(arg.Val, 5)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -646,39 +639,20 @@ func (com *Compiler) compileArgNode(st *util.Stack, node *Node, usePool bool) (*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if usePool {
|
|
||||||
st.Push(node)
|
|
||||||
|
|
||||||
for {
|
|
||||||
if st.Len() == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
intf := st.Pop()
|
|
||||||
node, ok := intf.(*Node)
|
|
||||||
if !ok || node == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for i := range node.Children {
|
|
||||||
st.Push(node.Children[i])
|
|
||||||
}
|
|
||||||
FreeNode(node, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return root, needsUser, nil
|
return root, needsUser, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (com *Compiler) compileArgID(sel *Select, arg *Arg) (error, bool) {
|
func (com *Compiler) compileArgID(sel *Select, arg *Arg) error {
|
||||||
if sel.ID != 0 {
|
if sel.ID != 0 {
|
||||||
return nil, false
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if sel.Where != nil && sel.Where.Op == OpEqID {
|
if sel.Where != nil && sel.Where.Op == OpEqID {
|
||||||
return nil, false
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if arg.Val.Type != NodeVar {
|
if arg.Val.Type != NodeVar {
|
||||||
return argErr("id", "variable"), false
|
return argErr("id", "variable")
|
||||||
}
|
}
|
||||||
|
|
||||||
ex := expPool.Get().(*Exp)
|
ex := expPool.Get().(*Exp)
|
||||||
@ -689,12 +663,12 @@ func (com *Compiler) compileArgID(sel *Select, arg *Arg) (error, bool) {
|
|||||||
ex.Val = arg.Val.Val
|
ex.Val = arg.Val.Val
|
||||||
|
|
||||||
sel.Where = ex
|
sel.Where = ex
|
||||||
return nil, false
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (com *Compiler) compileArgSearch(sel *Select, arg *Arg) (error, bool) {
|
func (com *Compiler) compileArgSearch(sel *Select, arg *Arg) error {
|
||||||
if arg.Val.Type != NodeVar {
|
if arg.Val.Type != NodeVar {
|
||||||
return argErr("search", "variable"), false
|
return argErr("search", "variable")
|
||||||
}
|
}
|
||||||
|
|
||||||
ex := expPool.Get().(*Exp)
|
ex := expPool.Get().(*Exp)
|
||||||
@ -709,18 +683,19 @@ func (com *Compiler) compileArgSearch(sel *Select, arg *Arg) (error, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sel.Args[arg.Name] = arg.Val
|
sel.Args[arg.Name] = arg.Val
|
||||||
|
arg.df = true
|
||||||
AddFilter(sel, ex)
|
AddFilter(sel, ex)
|
||||||
|
|
||||||
return nil, true
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (com *Compiler) compileArgWhere(sel *Select, arg *Arg, role string) (error, bool) {
|
func (com *Compiler) compileArgWhere(sel *Select, arg *Arg, role string) error {
|
||||||
st := util.NewStack()
|
st := util.NewStack()
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
ex, nu, err := com.compileArgObj(st, arg)
|
ex, nu, err := com.compileArgObj(st, arg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err, false
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if nu && role == "anon" {
|
if nu && role == "anon" {
|
||||||
@ -728,12 +703,12 @@ func (com *Compiler) compileArgWhere(sel *Select, arg *Arg, role string) (error,
|
|||||||
}
|
}
|
||||||
AddFilter(sel, ex)
|
AddFilter(sel, ex)
|
||||||
|
|
||||||
return nil, true
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (com *Compiler) compileArgOrderBy(sel *Select, arg *Arg) (error, bool) {
|
func (com *Compiler) compileArgOrderBy(sel *Select, arg *Arg) error {
|
||||||
if arg.Val.Type != NodeObj {
|
if arg.Val.Type != NodeObj {
|
||||||
return fmt.Errorf("expecting an object"), false
|
return fmt.Errorf("expecting an object")
|
||||||
}
|
}
|
||||||
|
|
||||||
st := util.NewStack()
|
st := util.NewStack()
|
||||||
@ -751,16 +726,15 @@ func (com *Compiler) compileArgOrderBy(sel *Select, arg *Arg) (error, bool) {
|
|||||||
node, ok := intf.(*Node)
|
node, ok := intf.(*Node)
|
||||||
|
|
||||||
if !ok || node == nil {
|
if !ok || node == nil {
|
||||||
return fmt.Errorf("17: unexpected value %v (%t)", intf, intf), false
|
return fmt.Errorf("17: unexpected value %v (%t)", intf, intf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := com.bl[node.Name]; ok {
|
if _, ok := com.bl[node.Name]; ok {
|
||||||
FreeNode(node, 2)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.Type != NodeStr && node.Type != NodeVar {
|
if node.Type != NodeStr && node.Type != NodeVar {
|
||||||
return fmt.Errorf("expecting a string or variable"), false
|
return fmt.Errorf("expecting a string or variable")
|
||||||
}
|
}
|
||||||
|
|
||||||
ob := &OrderBy{}
|
ob := &OrderBy{}
|
||||||
@ -779,25 +753,24 @@ func (com *Compiler) compileArgOrderBy(sel *Select, arg *Arg) (error, bool) {
|
|||||||
case "desc_nulls_last":
|
case "desc_nulls_last":
|
||||||
ob.Order = OrderDescNullsLast
|
ob.Order = OrderDescNullsLast
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("valid values include asc, desc, asc_nulls_first and desc_nulls_first"), false
|
return fmt.Errorf("valid values include asc, desc, asc_nulls_first and desc_nulls_first")
|
||||||
}
|
}
|
||||||
|
|
||||||
setOrderByColName(ob, node)
|
setOrderByColName(ob, node)
|
||||||
sel.OrderBy = append(sel.OrderBy, ob)
|
sel.OrderBy = append(sel.OrderBy, ob)
|
||||||
FreeNode(node, 3)
|
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (com *Compiler) compileArgDistinctOn(sel *Select, arg *Arg) (error, bool) {
|
func (com *Compiler) compileArgDistinctOn(sel *Select, arg *Arg) error {
|
||||||
node := arg.Val
|
node := arg.Val
|
||||||
|
|
||||||
if _, ok := com.bl[node.Name]; ok {
|
if _, ok := com.bl[node.Name]; ok {
|
||||||
return nil, false
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.Type != NodeList && node.Type != NodeStr {
|
if node.Type != NodeList && node.Type != NodeStr {
|
||||||
return fmt.Errorf("expecting a list of strings or just a string"), false
|
return fmt.Errorf("expecting a list of strings or just a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.Type == NodeStr {
|
if node.Type == NodeStr {
|
||||||
@ -806,58 +779,57 @@ func (com *Compiler) compileArgDistinctOn(sel *Select, arg *Arg) (error, bool) {
|
|||||||
|
|
||||||
for i := range node.Children {
|
for i := range node.Children {
|
||||||
sel.DistinctOn = append(sel.DistinctOn, node.Children[i].Val)
|
sel.DistinctOn = append(sel.DistinctOn, node.Children[i].Val)
|
||||||
FreeNode(node.Children[i], 5)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, false
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (com *Compiler) compileArgLimit(sel *Select, arg *Arg) (error, bool) {
|
func (com *Compiler) compileArgLimit(sel *Select, arg *Arg) error {
|
||||||
node := arg.Val
|
node := arg.Val
|
||||||
|
|
||||||
if node.Type != NodeInt {
|
if node.Type != NodeInt {
|
||||||
return argErr("limit", "number"), false
|
return argErr("limit", "number")
|
||||||
}
|
}
|
||||||
|
|
||||||
sel.Paging.Limit = node.Val
|
sel.Paging.Limit = node.Val
|
||||||
|
|
||||||
return nil, false
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (com *Compiler) compileArgOffset(sel *Select, arg *Arg) (error, bool) {
|
func (com *Compiler) compileArgOffset(sel *Select, arg *Arg) error {
|
||||||
node := arg.Val
|
node := arg.Val
|
||||||
|
|
||||||
if node.Type != NodeVar {
|
if node.Type != NodeVar {
|
||||||
return argErr("offset", "variable"), false
|
return argErr("offset", "variable")
|
||||||
}
|
}
|
||||||
|
|
||||||
sel.Paging.Offset = node.Val
|
sel.Paging.Offset = node.Val
|
||||||
return nil, false
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (com *Compiler) compileArgFirstLast(sel *Select, arg *Arg, pt PagingType) (error, bool) {
|
func (com *Compiler) compileArgFirstLast(sel *Select, arg *Arg, pt PagingType) error {
|
||||||
node := arg.Val
|
node := arg.Val
|
||||||
|
|
||||||
if node.Type != NodeInt {
|
if node.Type != NodeInt {
|
||||||
return argErr(arg.Name, "number"), false
|
return argErr(arg.Name, "number")
|
||||||
}
|
}
|
||||||
|
|
||||||
sel.Paging.Type = pt
|
sel.Paging.Type = pt
|
||||||
sel.Paging.Limit = node.Val
|
sel.Paging.Limit = node.Val
|
||||||
|
|
||||||
return nil, false
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (com *Compiler) compileArgAfterBefore(sel *Select, arg *Arg, pt PagingType) (error, bool) {
|
func (com *Compiler) compileArgAfterBefore(sel *Select, arg *Arg, pt PagingType) error {
|
||||||
node := arg.Val
|
node := arg.Val
|
||||||
|
|
||||||
if node.Type != NodeVar || node.Val != "cursor" {
|
if node.Type != NodeVar || node.Val != "cursor" {
|
||||||
return fmt.Errorf("value for argument '%s' must be a variable named $cursor", arg.Name), false
|
return fmt.Errorf("value for argument '%s' must be a variable named $cursor", arg.Name)
|
||||||
}
|
}
|
||||||
sel.Paging.Type = pt
|
sel.Paging.Type = pt
|
||||||
sel.Paging.Cursor = true
|
sel.Paging.Cursor = true
|
||||||
|
|
||||||
return nil, false
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// var zeroTrv = &trval{}
|
// var zeroTrv = &trval{}
|
||||||
@ -1237,3 +1209,81 @@ func FreeExp(ex *Exp) {
|
|||||||
func argErr(name, ty string) error {
|
func argErr(name, ty string) error {
|
||||||
return fmt.Errorf("value for argument '%s' must be a %s", name, ty)
|
return fmt.Errorf("value for argument '%s' must be a %s", name, ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func freeNodes(op *Operation) {
|
||||||
|
var st *util.Stack
|
||||||
|
fm := make(map[*Node]struct{})
|
||||||
|
|
||||||
|
for i := range op.Args {
|
||||||
|
arg := op.Args[i]
|
||||||
|
if arg.df {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range arg.Val.Children {
|
||||||
|
if st == nil {
|
||||||
|
st = util.NewStack()
|
||||||
|
}
|
||||||
|
c := arg.Val.Children[i]
|
||||||
|
if _, ok := fm[c]; !ok {
|
||||||
|
st.Push(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := fm[arg.Val]; !ok {
|
||||||
|
nodePool.Put(arg.Val)
|
||||||
|
fm[arg.Val] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range op.Fields {
|
||||||
|
f := op.Fields[i]
|
||||||
|
|
||||||
|
for j := range f.Args {
|
||||||
|
arg := f.Args[j]
|
||||||
|
if arg.df {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for k := range arg.Val.Children {
|
||||||
|
if st == nil {
|
||||||
|
st = util.NewStack()
|
||||||
|
}
|
||||||
|
c := arg.Val.Children[k]
|
||||||
|
if _, ok := fm[c]; !ok {
|
||||||
|
st.Push(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := fm[arg.Val]; !ok {
|
||||||
|
nodePool.Put(arg.Val)
|
||||||
|
fm[arg.Val] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if st == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
if st.Len() == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
intf := st.Pop()
|
||||||
|
node, ok := intf.(*Node)
|
||||||
|
if !ok || node == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range node.Children {
|
||||||
|
st.Push(node.Children[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := fm[node]; !ok {
|
||||||
|
nodePool.Put(node)
|
||||||
|
fm[node] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user