Skip to content
This repository was archived by the owner on Jun 14, 2019. It is now read-only.

Commit 0d73aa4

Browse files
committed
Fix issues & optimize codes
1 parent 8d67d30 commit 0d73aa4

File tree

4 files changed

+33
-18
lines changed

4 files changed

+33
-18
lines changed

builder_limit.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,25 @@ func (b *Builder) limitWriteTo(w Writer) error {
1414
if strings.TrimSpace(b.dialect) == "" {
1515
return errors.New("field `dialect` must be set up when performing LIMIT, try use `Dialect(dbType)` at first")
1616
}
17-
if !(b.optype == selectType || b.optype == unionType) {
18-
return errors.New("LIMIT operation is limited in SELECT and UNION")
19-
}
2017

2118
if b.limitation != nil {
2219
limit := b.limitation
2320
if limit.offset < 0 || limit.limitN <= 0 {
2421
return errors.New("unexpected offset/limitN")
2522
}
26-
27-
selects := b.selects
2823
// erase limit condition
2924
b.limitation = nil
30-
// flush writer, both buffer & args
3125
ow := w.(*BytesWriter)
32-
ow.writer.Reset()
33-
ow.args = nil
3426

3527
var final *Builder
3628

3729
switch strings.ToLower(strings.TrimSpace(b.dialect)) {
3830
case ORACLE:
31+
// flush writer, both buffer & args
32+
ow.writer.Reset()
33+
ow.args = nil
34+
35+
selects := b.selects
3936
b.selects = append(selects, "ROWNUM RN")
4037
if limit.offset == 0 {
4138
final = Dialect(b.dialect).Select(selects...).From("at", b).PK(b.pk...).
@@ -54,14 +51,22 @@ func (b *Builder) limitWriteTo(w Writer) error {
5451

5552
return final.WriteTo(ow)
5653
case SQLITE, MYSQL, POSTGRES:
57-
b.WriteTo(ow)
54+
// if type UNION, we need to write previous content back to current writer
55+
if b.optype == unionType {
56+
b.WriteTo(ow)
57+
}
5858

5959
if limit.offset == 0 {
6060
fmt.Fprint(ow, " LIMIT ", limit.limitN)
6161
} else {
6262
fmt.Fprintf(ow, " LIMIT %v OFFSET %v", limit.limitN, limit.offset)
6363
}
6464
case MSSQL:
65+
// flush writer, both buffer & args
66+
ow.writer.Reset()
67+
ow.args = nil
68+
69+
selects := b.selects
6570
if limit.offset == 0 {
6671
if len(selects) == 0 {
6772
selects = append(selects, "*")

builder_select.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ func (b *Builder) selectWriteTo(w Writer) error {
104104
if err := b.limitWriteTo(w); err != nil {
105105
return err
106106
}
107-
108107
}
109108

110109
return nil

builder_select_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,9 @@ func TestBuilder_Limit(t *testing.T) {
178178
// union with limit -- MsSQL style
179179
sql, args, err = Dialect(MSSQL).Select("a", "b", "c").From("table1").
180180
PK("id1").Where(Eq{"a": 1}).OrderBy("a ASC").Limit(5, 6).Union("ALL",
181-
Select("a", "b").From("table1").Where(Eq{"a": 2}).OrderBy("a DESC").Limit(10)).
181+
Select("a", "b").From("table1").Where(Eq{"b": 2}).OrderBy("a DESC").Limit(10)).
182182
OrderBy("b DESC").Limit(7).ToSQL()
183183
assert.NoError(t, err)
184-
// assert.EqualValues(t, 6, len(args))
184+
assert.EqualValues(t, 4, len(args))
185185
fmt.Println(sql, args)
186186
}

builder_union.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,24 @@ func (b *Builder) unionWriteTo(w Writer) error {
2828
fmt.Fprint(w, "(")
2929

3030
if current.limitation != nil {
31-
tw := NewWriter()
32-
if err := current.selectWriteTo(tw); err != nil {
33-
return err
31+
switch current.dialect {
32+
case ORACLE, MSSQL:
33+
// if dialect is Oracle or Mssql, we need to make a copy of current context
34+
// coz the result of current will turn into a sub-query when building LIMIT query
35+
tw := NewWriter()
36+
if err := current.selectWriteTo(tw); err != nil {
37+
return err
38+
}
39+
40+
fmt.Fprintf(w, tw.writer.String())
41+
w.(*BytesWriter).args = append(w.(*BytesWriter).args, tw.args...)
42+
case MYSQL, SQLITE, POSTGRES:
43+
if err := current.selectWriteTo(w); err != nil {
44+
return err
45+
}
46+
default:
47+
return ErrNotSupportType
3448
}
35-
36-
fmt.Fprintf(w, tw.writer.String())
37-
w.(*BytesWriter).args = append(w.(*BytesWriter).args, tw.args...)
3849
} else {
3950
if err := current.selectWriteTo(w); err != nil {
4051
return err

0 commit comments

Comments
 (0)