From 1ac78aa950d6dadb8ec430675f4e85117a942df0 Mon Sep 17 00:00:00 2001 From: Tobie Morgan Hitchcock Date: Sun, 26 Nov 2017 13:45:48 +0000 Subject: [PATCH] A single *Thing in a subquery is the same as LIMIT 1 --- db/fetch.go | 17 +++++++++++++++++ db/select.go | 4 ++-- db/select_test.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/db/fetch.go b/db/fetch.go index c1058183..dfa550a2 100644 --- a/db/fetch.go +++ b/db/fetch.go @@ -275,6 +275,23 @@ func (e *executor) fetchVersion(ctx context.Context, val sql.Expr) (int64, error } +func (e *executor) fetchOutputs(ctx context.Context, stm *sql.SelectStatement) (int, error) { + + l, err := e.fetchLimit(ctx, stm.Limit) + if err != nil { + return -1, err + } + + if len(stm.What) == 1 { + if _, ok := stm.What[0].(*sql.Thing); ok { + l = 1 + } + } + + return l, nil + +} + func calcAsBool(i interface{}) bool { switch v := i.(type) { diff --git a/db/select.go b/db/select.go index 991e686f..118faf0b 100644 --- a/db/select.go +++ b/db/select.go @@ -95,12 +95,12 @@ func (e *executor) fetchSelect(ctx context.Context, stm *sql.SelectStatement, do return nil, err } - lim, err := e.fetchLimit(ctx, stm.Limit) + cnt, err := e.fetchOutputs(ctx, stm) if err != nil { return nil, err } - switch lim { + switch cnt { case 1: switch len(stm.Expr) { case 1: diff --git a/db/select_test.go b/db/select_test.go index 12a54801..daace62a 100644 --- a/db/select_test.go +++ b/db/select_test.go @@ -159,6 +159,28 @@ func TestSelect(t *testing.T) { }) + Convey("Select records using an * subquery, specifying a single record", t, func() { + + setupDB() + + txt := ` + USE NS test DB test; + CREATE person:1 SET name="Tobias"; + CREATE person:2 SET name="Silvana"; + CREATE person:3 SET name="Jonathan"; + CREATE person:4 SET name="Benjamin"; + CREATE person:5 SET name="Alexander"; + SELECT * FROM (SELECT * FROM person:5); + ` + + res, err := Execute(setupKV(), txt, nil) + So(err, ShouldBeNil) + So(res, ShouldHaveLength, 7) + So(res[6].Result, ShouldHaveLength, 1) + So(data.Consume(res[6].Result[0]).Get("name").Data(), ShouldEqual, "Alexander") + + }) + Convey("Select records using an id subquery", t, func() { setupDB() @@ -204,6 +226,28 @@ func TestSelect(t *testing.T) { }) + Convey("Select records using an id subquery, specifying a single record", t, func() { + + setupDB() + + txt := ` + USE NS test DB test; + CREATE person:1 SET name="Tobias"; + CREATE person:2 SET name="Silvana"; + CREATE person:3 SET name="Jonathan"; + CREATE person:4 SET name="Benjamin"; + CREATE person:5 SET name="Alexander"; + SELECT * FROM (SELECT id FROM (SELECT * FROM person:5)); + ` + + res, err := Execute(setupKV(), txt, nil) + So(err, ShouldBeNil) + So(res, ShouldHaveLength, 7) + So(res[6].Result, ShouldHaveLength, 1) + So(data.Consume(res[6].Result[0]).Get("name").Data(), ShouldEqual, "Alexander") + + }) + Convey("Select records using a single field subquery", t, func() { setupDB()