From a1a277fcba1d941a8333b4b1f86aec6343a35e3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Nieto?= <jose.carlos@menteslibres.net> Date: Sat, 23 May 2015 09:05:46 -0500 Subject: [PATCH] Few convenience methods. --- util/sqlgen/column_value.go | 2 +- util/sqlgen/column_value_test.go | 68 +++++------ util/sqlgen/columns.go | 4 +- util/sqlgen/columns_test.go | 46 ++++---- util/sqlgen/database.go | 5 + util/sqlgen/group_by.go | 4 +- util/sqlgen/group_by_test.go | 46 ++++---- util/sqlgen/order_by.go | 6 +- util/sqlgen/order_by_test.go | 30 ++--- util/sqlgen/statement_test.go | 194 +++++++++++++++---------------- util/sqlgen/value.go | 29 +++-- util/sqlgen/value_test.go | 38 +++++- util/sqlgen/where_test.go | 40 +++---- 13 files changed, 277 insertions(+), 235 deletions(-) diff --git a/util/sqlgen/column_value.go b/util/sqlgen/column_value.go index 18acdec9..41122710 100644 --- a/util/sqlgen/column_value.go +++ b/util/sqlgen/column_value.go @@ -7,7 +7,7 @@ import ( // ColumnValue represents a bundle between a column and a corresponding value. type ColumnValue struct { - Column + Column Fragment Operator string Value Fragment hash string diff --git a/util/sqlgen/column_value_test.go b/util/sqlgen/column_value_test.go index 091f9ba0..b9b80779 100644 --- a/util/sqlgen/column_value_test.go +++ b/util/sqlgen/column_value_test.go @@ -8,7 +8,7 @@ import ( func TestColumnValueHash(t *testing.T) { var s, e string - c := ColumnValue{Column: Column{Name: "id"}, Operator: "=", Value: NewValue(1)} + c := ColumnValue{Column: ColumnWithName("id"), Operator: "=", Value: NewValue(1)} s = c.Hash() e = fmt.Sprintf(`ColumnValue{Name:%q, Operator:%q, Value:%q}`, c.Column.Hash(), c.Operator, c.Value.Hash()) @@ -22,8 +22,8 @@ func TestColumnValuesHash(t *testing.T) { var s, e string c := JoinColumnValues( - ColumnValue{Column: Column{Name: "id"}, Operator: "=", Value: NewValue(1)}, - ColumnValue{Column: Column{Name: "id"}, Operator: "=", Value: NewValue(2)}, + ColumnValue{Column: ColumnWithName("id"), Operator: "=", Value: NewValue(1)}, + ColumnValue{Column: ColumnWithName("id"), Operator: "=", Value: NewValue(2)}, ) s = c.Hash() @@ -39,7 +39,7 @@ func TestColumnValue(t *testing.T) { var s, e string var cv ColumnValue - cv = ColumnValue{Column: Column{Name: "id"}, Operator: "=", Value: NewValue(1)} + cv = ColumnValue{Column: ColumnWithName("id"), Operator: "=", Value: NewValue(1)} s = cv.Compile(defaultTemplate) e = `"id" = '1'` @@ -48,7 +48,7 @@ func TestColumnValue(t *testing.T) { t.Fatalf("Got: %s, Expecting: %s", s, e) } - cv = ColumnValue{Column: Column{Name: "date"}, Operator: "=", Value: NewValue(RawValue("NOW()"))} + cv = ColumnValue{Column: ColumnWithName("date"), Operator: "=", Value: NewValue(RawValue("NOW()"))} s = cv.Compile(defaultTemplate) e = `"date" = NOW()` @@ -62,11 +62,11 @@ func TestColumnValues(t *testing.T) { var s, e string cvs := JoinColumnValues( - ColumnValue{Column: Column{Name: "id"}, Operator: ">", Value: NewValue(8)}, - ColumnValue{Column: Column{Name: "other.id"}, Operator: "<", Value: NewValue(&Raw{Value: "100"})}, - ColumnValue{Column: Column{Name: "name"}, Operator: "=", Value: NewValue("Haruki Murakami")}, - ColumnValue{Column: Column{Name: "created"}, Operator: ">=", Value: NewValue(&Raw{Value: "NOW()"})}, - ColumnValue{Column: Column{Name: "modified"}, Operator: "<=", Value: NewValue(&Raw{Value: "NOW()"})}, + ColumnValue{Column: ColumnWithName("id"), Operator: ">", Value: NewValue(8)}, + ColumnValue{Column: ColumnWithName("other.id"), Operator: "<", Value: NewValue(&Raw{Value: "100"})}, + ColumnValue{Column: ColumnWithName("name"), Operator: "=", Value: NewValue("Haruki Murakami")}, + ColumnValue{Column: ColumnWithName("created"), Operator: ">=", Value: NewValue(&Raw{Value: "NOW()"})}, + ColumnValue{Column: ColumnWithName("modified"), Operator: "<=", Value: NewValue(&Raw{Value: "NOW()"})}, ) s = cvs.Compile(defaultTemplate) @@ -79,19 +79,19 @@ func TestColumnValues(t *testing.T) { func BenchmarkNewColumnValue(b *testing.B) { for i := 0; i < b.N; i++ { - _ = ColumnValue{Column: Column{Name: "a"}, Operator: "=", Value: NewValue(Raw{Value: "7"})} + _ = ColumnValue{Column: ColumnWithName("a"), Operator: "=", Value: NewValue(Raw{Value: "7"})} } } func BenchmarkColumnValueHash(b *testing.B) { - cv := ColumnValue{Column: Column{Name: "id"}, Operator: "=", Value: NewValue(1)} + cv := ColumnValue{Column: ColumnWithName("id"), Operator: "=", Value: NewValue(1)} for i := 0; i < b.N; i++ { cv.Hash() } } func BenchmarkColumnValueCompile(b *testing.B) { - cv := ColumnValue{Column: Column{Name: "id"}, Operator: "=", Value: NewValue(1)} + cv := ColumnValue{Column: ColumnWithName("id"), Operator: "=", Value: NewValue(1)} for i := 0; i < b.N; i++ { cv.Compile(defaultTemplate) } @@ -99,7 +99,7 @@ func BenchmarkColumnValueCompile(b *testing.B) { func BenchmarkColumnValueCompileNoCache(b *testing.B) { for i := 0; i < b.N; i++ { - cv := ColumnValue{Column: Column{Name: "id"}, Operator: "=", Value: NewValue(1)} + cv := ColumnValue{Column: ColumnWithName("id"), Operator: "=", Value: NewValue(1)} cv.Compile(defaultTemplate) } } @@ -107,22 +107,22 @@ func BenchmarkColumnValueCompileNoCache(b *testing.B) { func BenchmarkJoinColumnValues(b *testing.B) { for i := 0; i < b.N; i++ { _ = JoinColumnValues( - ColumnValue{Column: Column{Name: "id"}, Operator: ">", Value: NewValue(8)}, - ColumnValue{Column: Column{Name: "other.id"}, Operator: "<", Value: NewValue(Raw{Value: "100"})}, - ColumnValue{Column: Column{Name: "name"}, Operator: "=", Value: NewValue("Haruki Murakami")}, - ColumnValue{Column: Column{Name: "created"}, Operator: ">=", Value: NewValue(Raw{Value: "NOW()"})}, - ColumnValue{Column: Column{Name: "modified"}, Operator: "<=", Value: NewValue(Raw{Value: "NOW()"})}, + ColumnValue{Column: ColumnWithName("id"), Operator: ">", Value: NewValue(8)}, + ColumnValue{Column: ColumnWithName("other.id"), Operator: "<", Value: NewValue(Raw{Value: "100"})}, + ColumnValue{Column: ColumnWithName("name"), Operator: "=", Value: NewValue("Haruki Murakami")}, + ColumnValue{Column: ColumnWithName("created"), Operator: ">=", Value: NewValue(Raw{Value: "NOW()"})}, + ColumnValue{Column: ColumnWithName("modified"), Operator: "<=", Value: NewValue(Raw{Value: "NOW()"})}, ) } } func BenchmarkColumnValuesHash(b *testing.B) { cvs := JoinColumnValues( - ColumnValue{Column: Column{Name: "id"}, Operator: ">", Value: NewValue(8)}, - ColumnValue{Column: Column{Name: "other.id"}, Operator: "<", Value: NewValue(Raw{Value: "100"})}, - ColumnValue{Column: Column{Name: "name"}, Operator: "=", Value: NewValue("Haruki Murakami")}, - ColumnValue{Column: Column{Name: "created"}, Operator: ">=", Value: NewValue(Raw{Value: "NOW()"})}, - ColumnValue{Column: Column{Name: "modified"}, Operator: "<=", Value: NewValue(Raw{Value: "NOW()"})}, + ColumnValue{Column: ColumnWithName("id"), Operator: ">", Value: NewValue(8)}, + ColumnValue{Column: ColumnWithName("other.id"), Operator: "<", Value: NewValue(Raw{Value: "100"})}, + ColumnValue{Column: ColumnWithName("name"), Operator: "=", Value: NewValue("Haruki Murakami")}, + ColumnValue{Column: ColumnWithName("created"), Operator: ">=", Value: NewValue(Raw{Value: "NOW()"})}, + ColumnValue{Column: ColumnWithName("modified"), Operator: "<=", Value: NewValue(Raw{Value: "NOW()"})}, ) for i := 0; i < b.N; i++ { cvs.Hash() @@ -131,11 +131,11 @@ func BenchmarkColumnValuesHash(b *testing.B) { func BenchmarkColumnValuesCompile(b *testing.B) { cvs := JoinColumnValues( - ColumnValue{Column: Column{Name: "id"}, Operator: ">", Value: NewValue(8)}, - ColumnValue{Column: Column{Name: "other.id"}, Operator: "<", Value: NewValue(Raw{Value: "100"})}, - ColumnValue{Column: Column{Name: "name"}, Operator: "=", Value: NewValue("Haruki Murakami")}, - ColumnValue{Column: Column{Name: "created"}, Operator: ">=", Value: NewValue(Raw{Value: "NOW()"})}, - ColumnValue{Column: Column{Name: "modified"}, Operator: "<=", Value: NewValue(Raw{Value: "NOW()"})}, + ColumnValue{Column: ColumnWithName("id"), Operator: ">", Value: NewValue(8)}, + ColumnValue{Column: ColumnWithName("other.id"), Operator: "<", Value: NewValue(Raw{Value: "100"})}, + ColumnValue{Column: ColumnWithName("name"), Operator: "=", Value: NewValue("Haruki Murakami")}, + ColumnValue{Column: ColumnWithName("created"), Operator: ">=", Value: NewValue(Raw{Value: "NOW()"})}, + ColumnValue{Column: ColumnWithName("modified"), Operator: "<=", Value: NewValue(Raw{Value: "NOW()"})}, ) for i := 0; i < b.N; i++ { cvs.Compile(defaultTemplate) @@ -145,11 +145,11 @@ func BenchmarkColumnValuesCompile(b *testing.B) { func BenchmarkColumnValuesCompileNoCache(b *testing.B) { for i := 0; i < b.N; i++ { cvs := JoinColumnValues( - ColumnValue{Column: Column{Name: "id"}, Operator: ">", Value: NewValue(8)}, - ColumnValue{Column: Column{Name: "other.id"}, Operator: "<", Value: NewValue(Raw{Value: "100"})}, - ColumnValue{Column: Column{Name: "name"}, Operator: "=", Value: NewValue("Haruki Murakami")}, - ColumnValue{Column: Column{Name: "created"}, Operator: ">=", Value: NewValue(Raw{Value: "NOW()"})}, - ColumnValue{Column: Column{Name: "modified"}, Operator: "<=", Value: NewValue(Raw{Value: "NOW()"})}, + ColumnValue{Column: ColumnWithName("id"), Operator: ">", Value: NewValue(8)}, + ColumnValue{Column: ColumnWithName("other.id"), Operator: "<", Value: NewValue(Raw{Value: "100"})}, + ColumnValue{Column: ColumnWithName("name"), Operator: "=", Value: NewValue("Haruki Murakami")}, + ColumnValue{Column: ColumnWithName("created"), Operator: ">=", Value: NewValue(Raw{Value: "NOW()"})}, + ColumnValue{Column: ColumnWithName("modified"), Operator: "<=", Value: NewValue(Raw{Value: "NOW()"})}, ) cvs.Compile(defaultTemplate) } diff --git a/util/sqlgen/columns.go b/util/sqlgen/columns.go index 19b47739..507cb215 100644 --- a/util/sqlgen/columns.go +++ b/util/sqlgen/columns.go @@ -7,7 +7,7 @@ import ( // Columns represents an array of Column. type Columns struct { - Columns []Column + Columns []Fragment hash string } @@ -24,7 +24,7 @@ func (c *Columns) Hash() string { } // JoinColumns creates and returns an array of Column. -func JoinColumns(columns ...Column) *Columns { +func JoinColumns(columns ...Fragment) *Columns { return &Columns{Columns: columns} } diff --git a/util/sqlgen/columns_test.go b/util/sqlgen/columns_test.go index 03f4fdec..a4f43979 100644 --- a/util/sqlgen/columns_test.go +++ b/util/sqlgen/columns_test.go @@ -8,11 +8,11 @@ func TestColumns(t *testing.T) { var s, e string columns := JoinColumns( - Column{Name: "id"}, - Column{Name: "customer"}, - Column{Name: "service_id"}, - Column{Name: "role.name"}, - Column{Name: "role.id"}, + &Column{Name: "id"}, + &Column{Name: "customer"}, + &Column{Name: "service_id"}, + &Column{Name: "role.name"}, + &Column{Name: "role.id"}, ) s = columns.Compile(defaultTemplate) @@ -26,20 +26,20 @@ func TestColumns(t *testing.T) { func BenchmarkJoinColumns(b *testing.B) { for i := 0; i < b.N; i++ { _ = JoinColumns( - Column{Name: "a"}, - Column{Name: "b"}, - Column{Name: "c"}, + &Column{Name: "a"}, + &Column{Name: "b"}, + &Column{Name: "c"}, ) } } func BenchmarkColumnsHash(b *testing.B) { c := JoinColumns( - Column{Name: "id"}, - Column{Name: "customer"}, - Column{Name: "service_id"}, - Column{Name: "role.name"}, - Column{Name: "role.id"}, + &Column{Name: "id"}, + &Column{Name: "customer"}, + &Column{Name: "service_id"}, + &Column{Name: "role.name"}, + &Column{Name: "role.id"}, ) for i := 0; i < b.N; i++ { c.Hash() @@ -48,11 +48,11 @@ func BenchmarkColumnsHash(b *testing.B) { func BenchmarkColumnsCompile(b *testing.B) { c := JoinColumns( - Column{Name: "id"}, - Column{Name: "customer"}, - Column{Name: "service_id"}, - Column{Name: "role.name"}, - Column{Name: "role.id"}, + &Column{Name: "id"}, + &Column{Name: "customer"}, + &Column{Name: "service_id"}, + &Column{Name: "role.name"}, + &Column{Name: "role.id"}, ) for i := 0; i < b.N; i++ { c.Compile(defaultTemplate) @@ -62,11 +62,11 @@ func BenchmarkColumnsCompile(b *testing.B) { func BenchmarkColumnsCompileNoCache(b *testing.B) { for i := 0; i < b.N; i++ { c := JoinColumns( - Column{Name: "id"}, - Column{Name: "customer"}, - Column{Name: "service_id"}, - Column{Name: "role.name"}, - Column{Name: "role.id"}, + &Column{Name: "id"}, + &Column{Name: "customer"}, + &Column{Name: "service_id"}, + &Column{Name: "role.name"}, + &Column{Name: "role.id"}, ) c.Compile(defaultTemplate) } diff --git a/util/sqlgen/database.go b/util/sqlgen/database.go index 2a1dc578..df7001dd 100644 --- a/util/sqlgen/database.go +++ b/util/sqlgen/database.go @@ -10,6 +10,11 @@ type Database struct { hash string } +// DatabaseWithName returns a Database with the given name. +func DatabaseWithName(name string) *Database { + return &Database{Name: name} +} + // Hash returns a unique identifier. func (d *Database) Hash() string { if d.hash == "" { diff --git a/util/sqlgen/group_by.go b/util/sqlgen/group_by.go index 2f849d56..03762a58 100644 --- a/util/sqlgen/group_by.go +++ b/util/sqlgen/group_by.go @@ -6,7 +6,7 @@ import ( // GroupBy represents a SQL's "group by" statement. type GroupBy struct { - Columns *Columns + Columns Fragment hash string } @@ -23,7 +23,7 @@ func (g *GroupBy) Hash() string { } // GroupByColumns creates and returns a GroupBy with the given column. -func GroupByColumns(columns ...Column) *GroupBy { +func GroupByColumns(columns ...Fragment) *GroupBy { return &GroupBy{Columns: JoinColumns(columns...)} } diff --git a/util/sqlgen/group_by_test.go b/util/sqlgen/group_by_test.go index e43b2840..c6c6a6f3 100644 --- a/util/sqlgen/group_by_test.go +++ b/util/sqlgen/group_by_test.go @@ -8,11 +8,11 @@ func TestGroupBy(t *testing.T) { var s, e string columns := GroupByColumns( - Column{Name: "id"}, - Column{Name: "customer"}, - Column{Name: "service_id"}, - Column{Name: "role.name"}, - Column{Name: "role.id"}, + &Column{Name: "id"}, + &Column{Name: "customer"}, + &Column{Name: "service_id"}, + &Column{Name: "role.name"}, + &Column{Name: "role.id"}, ) s = columns.Compile(defaultTemplate) @@ -26,20 +26,20 @@ func TestGroupBy(t *testing.T) { func BenchmarkGroupByColumns(b *testing.B) { for i := 0; i < b.N; i++ { _ = GroupByColumns( - Column{Name: "a"}, - Column{Name: "b"}, - Column{Name: "c"}, + &Column{Name: "a"}, + &Column{Name: "b"}, + &Column{Name: "c"}, ) } } func BenchmarkGroupByHash(b *testing.B) { c := GroupByColumns( - Column{Name: "id"}, - Column{Name: "customer"}, - Column{Name: "service_id"}, - Column{Name: "role.name"}, - Column{Name: "role.id"}, + &Column{Name: "id"}, + &Column{Name: "customer"}, + &Column{Name: "service_id"}, + &Column{Name: "role.name"}, + &Column{Name: "role.id"}, ) for i := 0; i < b.N; i++ { c.Hash() @@ -48,11 +48,11 @@ func BenchmarkGroupByHash(b *testing.B) { func BenchmarkGroupByCompile(b *testing.B) { c := GroupByColumns( - Column{Name: "id"}, - Column{Name: "customer"}, - Column{Name: "service_id"}, - Column{Name: "role.name"}, - Column{Name: "role.id"}, + &Column{Name: "id"}, + &Column{Name: "customer"}, + &Column{Name: "service_id"}, + &Column{Name: "role.name"}, + &Column{Name: "role.id"}, ) for i := 0; i < b.N; i++ { c.Compile(defaultTemplate) @@ -62,11 +62,11 @@ func BenchmarkGroupByCompile(b *testing.B) { func BenchmarkGroupByCompileNoCache(b *testing.B) { for i := 0; i < b.N; i++ { c := GroupByColumns( - Column{Name: "id"}, - Column{Name: "customer"}, - Column{Name: "service_id"}, - Column{Name: "role.name"}, - Column{Name: "role.id"}, + &Column{Name: "id"}, + &Column{Name: "customer"}, + &Column{Name: "service_id"}, + &Column{Name: "role.name"}, + &Column{Name: "role.id"}, ) c.Compile(defaultTemplate) } diff --git a/util/sqlgen/order_by.go b/util/sqlgen/order_by.go index 5606cddc..edaa78f0 100644 --- a/util/sqlgen/order_by.go +++ b/util/sqlgen/order_by.go @@ -17,7 +17,7 @@ const ( // SortColumn represents the column-order relation in an ORDER BY clause. type SortColumn struct { - Column + Column Fragment Order hash string } @@ -29,7 +29,7 @@ type sortColumnT struct { // SortColumns represents the columns in an ORDER BY clause. type SortColumns struct { - Columns []SortColumn + Columns []Fragment hash string } @@ -44,7 +44,7 @@ type orderByT struct { } // JoinSortColumns creates and returns an array of column-order relations. -func JoinSortColumns(values ...SortColumn) *SortColumns { +func JoinSortColumns(values ...Fragment) *SortColumns { return &SortColumns{Columns: values} } diff --git a/util/sqlgen/order_by_test.go b/util/sqlgen/order_by_test.go index 3df754b2..bbb7ac84 100644 --- a/util/sqlgen/order_by_test.go +++ b/util/sqlgen/order_by_test.go @@ -7,7 +7,7 @@ import ( func TestOrderBy(t *testing.T) { o := JoinWithOrderBy( JoinSortColumns( - SortColumn{Column: Column{Name: "foo"}}, + &SortColumn{Column: &Column{Name: "foo"}}, ), ) @@ -22,7 +22,7 @@ func TestOrderBy(t *testing.T) { func TestOrderByDesc(t *testing.T) { o := JoinWithOrderBy( JoinSortColumns( - SortColumn{Column: Column{Name: "foo"}, Order: Descendent}, + &SortColumn{Column: &Column{Name: "foo"}, Order: Descendent}, ), ) @@ -38,7 +38,7 @@ func BenchmarkOrderBy(b *testing.B) { for i := 0; i < b.N; i++ { JoinWithOrderBy( JoinSortColumns( - SortColumn{Column: Column{Name: "foo"}}, + &SortColumn{Column: &Column{Name: "foo"}}, ), ) } @@ -47,7 +47,7 @@ func BenchmarkOrderBy(b *testing.B) { func BenchmarkOrderByHash(b *testing.B) { o := OrderBy{ SortColumns: JoinSortColumns( - SortColumn{Column: Column{Name: "foo"}}, + &SortColumn{Column: &Column{Name: "foo"}}, ), } for i := 0; i < b.N; i++ { @@ -58,7 +58,7 @@ func BenchmarkOrderByHash(b *testing.B) { func BenchmarkCompileOrderByCompile(b *testing.B) { o := OrderBy{ SortColumns: JoinSortColumns( - SortColumn{Column: Column{Name: "foo"}}, + &SortColumn{Column: &Column{Name: "foo"}}, ), } for i := 0; i < b.N; i++ { @@ -70,7 +70,7 @@ func BenchmarkCompileOrderByCompileNoCache(b *testing.B) { for i := 0; i < b.N; i++ { o := JoinWithOrderBy( JoinSortColumns( - SortColumn{Column: Column{Name: "foo"}}, + &SortColumn{Column: &Column{Name: "foo"}}, ), ) o.Compile(defaultTemplate) @@ -92,14 +92,14 @@ func BenchmarkCompileOrderCompileNoCache(b *testing.B) { } func BenchmarkSortColumnHash(b *testing.B) { - s := SortColumn{Column: Column{Name: "foo"}} + s := &SortColumn{Column: &Column{Name: "foo"}} for i := 0; i < b.N; i++ { s.Hash() } } func BenchmarkSortColumnCompile(b *testing.B) { - s := SortColumn{Column: Column{Name: "foo"}} + s := &SortColumn{Column: &Column{Name: "foo"}} for i := 0; i < b.N; i++ { s.Compile(defaultTemplate) } @@ -107,15 +107,15 @@ func BenchmarkSortColumnCompile(b *testing.B) { func BenchmarkSortColumnCompileNoCache(b *testing.B) { for i := 0; i < b.N; i++ { - s := SortColumn{Column: Column{Name: "foo"}} + s := &SortColumn{Column: &Column{Name: "foo"}} s.Compile(defaultTemplate) } } func BenchmarkSortColumnsHash(b *testing.B) { s := JoinSortColumns( - SortColumn{Column: Column{Name: "foo"}}, - SortColumn{Column: Column{Name: "bar"}}, + &SortColumn{Column: &Column{Name: "foo"}}, + &SortColumn{Column: &Column{Name: "bar"}}, ) for i := 0; i < b.N; i++ { s.Hash() @@ -124,8 +124,8 @@ func BenchmarkSortColumnsHash(b *testing.B) { func BenchmarkSortColumnsCompile(b *testing.B) { s := JoinSortColumns( - SortColumn{Column: Column{Name: "foo"}}, - SortColumn{Column: Column{Name: "bar"}}, + &SortColumn{Column: &Column{Name: "foo"}}, + &SortColumn{Column: &Column{Name: "bar"}}, ) for i := 0; i < b.N; i++ { s.Compile(defaultTemplate) @@ -135,8 +135,8 @@ func BenchmarkSortColumnsCompile(b *testing.B) { func BenchmarkSortColumnsCompileNoCache(b *testing.B) { for i := 0; i < b.N; i++ { s := JoinSortColumns( - SortColumn{Column: Column{Name: "foo"}}, - SortColumn{Column: Column{Name: "bar"}}, + &SortColumn{Column: &Column{Name: "foo"}}, + &SortColumn{Column: &Column{Name: "bar"}}, ) s.Compile(defaultTemplate) } diff --git a/util/sqlgen/statement_test.go b/util/sqlgen/statement_test.go index 84b7f195..7ec293a0 100644 --- a/util/sqlgen/statement_test.go +++ b/util/sqlgen/statement_test.go @@ -110,7 +110,7 @@ func TestCountWhere(t *testing.T) { Type: Count, Table: TableWithName("table_name"), Where: WhereConditions( - &ColumnValue{Column: Column{Name: "a"}, Operator: "=", Value: NewValue(RawValue("7"))}, + &ColumnValue{Column: &Column{Name: "a"}, Operator: "=", Value: NewValue(RawValue("7"))}, ), } @@ -217,7 +217,7 @@ func TestSelectArtistNameFrom(t *testing.T) { Type: Select, Table: TableWithName("artist"), Columns: JoinColumns( - Column{Name: "artist.name"}, + &Column{Name: "artist.name"}, ), } @@ -237,8 +237,8 @@ func TestSelectRawFrom(t *testing.T) { Type: Select, Table: TableWithName(`artist`), Columns: JoinColumns( - Column{Name: `artist.name`}, - Column{Name: Raw{Value: `CONCAT(artist.name, " ", artist.last_name)`}}, + &Column{Name: `artist.name`}, + &Column{Name: Raw{Value: `CONCAT(artist.name, " ", artist.last_name)`}}, ), } @@ -257,9 +257,9 @@ func TestSelectFieldsFrom(t *testing.T) { stmt = Statement{ Type: Select, Columns: JoinColumns( - Column{Name: "foo"}, - Column{Name: "bar"}, - Column{Name: "baz"}, + &Column{Name: "foo"}, + &Column{Name: "bar"}, + &Column{Name: "baz"}, ), Table: TableWithName("table_name"), } @@ -280,9 +280,9 @@ func TestSelectFieldsFromWithLimitOffset(t *testing.T) { stmt = Statement{ Type: Select, Columns: JoinColumns( - Column{Name: "foo"}, - Column{Name: "bar"}, - Column{Name: "baz"}, + &Column{Name: "foo"}, + &Column{Name: "bar"}, + &Column{Name: "baz"}, ), Limit: 42, Table: TableWithName("table_name"), @@ -299,9 +299,9 @@ func TestSelectFieldsFromWithLimitOffset(t *testing.T) { stmt = Statement{ Type: Select, Columns: JoinColumns( - Column{Name: "foo"}, - Column{Name: "bar"}, - Column{Name: "baz"}, + &Column{Name: "foo"}, + &Column{Name: "bar"}, + &Column{Name: "baz"}, ), Offset: 17, Table: TableWithName("table_name"), @@ -318,9 +318,9 @@ func TestSelectFieldsFromWithLimitOffset(t *testing.T) { stmt = Statement{ Type: Select, Columns: JoinColumns( - Column{Name: "foo"}, - Column{Name: "bar"}, - Column{Name: "baz"}, + &Column{Name: "foo"}, + &Column{Name: "bar"}, + &Column{Name: "baz"}, ), Limit: 42, Offset: 17, @@ -343,12 +343,12 @@ func TestStatementGroupBy(t *testing.T) { stmt = Statement{ Type: Select, Columns: JoinColumns( - Column{Name: "foo"}, - Column{Name: "bar"}, - Column{Name: "baz"}, + &Column{Name: "foo"}, + &Column{Name: "bar"}, + &Column{Name: "baz"}, ), GroupBy: GroupByColumns( - Column{Name: "foo"}, + &Column{Name: "foo"}, ), Table: TableWithName("table_name"), } @@ -363,13 +363,13 @@ func TestStatementGroupBy(t *testing.T) { stmt = Statement{ Type: Select, Columns: JoinColumns( - Column{Name: "foo"}, - Column{Name: "bar"}, - Column{Name: "baz"}, + &Column{Name: "foo"}, + &Column{Name: "bar"}, + &Column{Name: "baz"}, ), GroupBy: GroupByColumns( - Column{Name: "foo"}, - Column{Name: "bar"}, + &Column{Name: "foo"}, + &Column{Name: "bar"}, ), Table: TableWithName("table_name"), } @@ -390,13 +390,13 @@ func TestSelectFieldsFromWithOrderBy(t *testing.T) { stmt = Statement{ Type: Select, Columns: JoinColumns( - Column{Name: "foo"}, - Column{Name: "bar"}, - Column{Name: "baz"}, + &Column{Name: "foo"}, + &Column{Name: "bar"}, + &Column{Name: "baz"}, ), OrderBy: JoinWithOrderBy( JoinSortColumns( - SortColumn{Column: Column{Name: "foo"}}, + &SortColumn{Column: &Column{Name: "foo"}}, ), ), Table: TableWithName("table_name"), @@ -413,13 +413,13 @@ func TestSelectFieldsFromWithOrderBy(t *testing.T) { stmt = Statement{ Type: Select, Columns: JoinColumns( - Column{Name: "foo"}, - Column{Name: "bar"}, - Column{Name: "baz"}, + &Column{Name: "foo"}, + &Column{Name: "bar"}, + &Column{Name: "baz"}, ), OrderBy: JoinWithOrderBy( JoinSortColumns( - SortColumn{Column: Column{Name: "foo"}, Order: Ascendent}, + &SortColumn{Column: &Column{Name: "foo"}, Order: Ascendent}, ), ), Table: TableWithName("table_name"), @@ -436,13 +436,13 @@ func TestSelectFieldsFromWithOrderBy(t *testing.T) { stmt = Statement{ Type: Select, Columns: JoinColumns( - Column{Name: "foo"}, - Column{Name: "bar"}, - Column{Name: "baz"}, + &Column{Name: "foo"}, + &Column{Name: "bar"}, + &Column{Name: "baz"}, ), OrderBy: JoinWithOrderBy( JoinSortColumns( - SortColumn{Column: Column{Name: "foo"}, Order: Descendent}, + &SortColumn{Column: &Column{Name: "foo"}, Order: Descendent}, ), ), Table: TableWithName("table_name"), @@ -459,15 +459,15 @@ func TestSelectFieldsFromWithOrderBy(t *testing.T) { stmt = Statement{ Type: Select, Columns: JoinColumns( - Column{Name: "foo"}, - Column{Name: "bar"}, - Column{Name: "baz"}, + &Column{Name: "foo"}, + &Column{Name: "bar"}, + &Column{Name: "baz"}, ), OrderBy: JoinWithOrderBy( JoinSortColumns( - SortColumn{Column: Column{Name: "foo"}, Order: Descendent}, - SortColumn{Column: Column{Name: "bar"}, Order: Ascendent}, - SortColumn{Column: Column{Name: "baz"}, Order: Descendent}, + &SortColumn{Column: &Column{Name: "foo"}, Order: Descendent}, + &SortColumn{Column: &Column{Name: "bar"}, Order: Ascendent}, + &SortColumn{Column: &Column{Name: "baz"}, Order: Descendent}, ), ), Table: TableWithName("table_name"), @@ -484,14 +484,14 @@ func TestSelectFieldsFromWithOrderBy(t *testing.T) { stmt = Statement{ Type: Select, Columns: JoinColumns( - Column{Name: "foo"}, - Column{Name: "bar"}, - Column{Name: "baz"}, + &Column{Name: "foo"}, + &Column{Name: "bar"}, + &Column{Name: "baz"}, ), OrderBy: JoinWithOrderBy( JoinSortColumns( - SortColumn{Column: Column{Name: Raw{Value: "FOO()"}}, Order: Descendent}, - SortColumn{Column: Column{Name: Raw{Value: "BAR()"}}, Order: Ascendent}, + &SortColumn{Column: &Column{Name: Raw{Value: "FOO()"}}, Order: Descendent}, + &SortColumn{Column: &Column{Name: Raw{Value: "BAR()"}}, Order: Ascendent}, ), ), Table: TableWithName("table_name"), @@ -512,13 +512,13 @@ func TestSelectFieldsFromWhere(t *testing.T) { stmt = Statement{ Type: Select, Columns: JoinColumns( - Column{Name: "foo"}, - Column{Name: "bar"}, - Column{Name: "baz"}, + &Column{Name: "foo"}, + &Column{Name: "bar"}, + &Column{Name: "baz"}, ), Table: TableWithName("table_name"), Where: WhereConditions( - &ColumnValue{Column: Column{Name: "baz"}, Operator: "=", Value: NewValue(99)}, + &ColumnValue{Column: &Column{Name: "baz"}, Operator: "=", Value: NewValue(99)}, ), } @@ -537,13 +537,13 @@ func TestSelectFieldsFromWhereLimitOffset(t *testing.T) { stmt = Statement{ Type: Select, Columns: JoinColumns( - Column{Name: "foo"}, - Column{Name: "bar"}, - Column{Name: "baz"}, + &Column{Name: "foo"}, + &Column{Name: "bar"}, + &Column{Name: "baz"}, ), Table: TableWithName("table_name"), Where: WhereConditions( - &ColumnValue{Column: Column{Name: "baz"}, Operator: "=", Value: NewValue(99)}, + &ColumnValue{Column: &Column{Name: "baz"}, Operator: "=", Value: NewValue(99)}, ), Limit: 10, Offset: 23, @@ -565,7 +565,7 @@ func TestDelete(t *testing.T) { Type: Delete, Table: TableWithName("table_name"), Where: WhereConditions( - &ColumnValue{Column: Column{Name: "baz"}, Operator: "=", Value: NewValue(99)}, + &ColumnValue{Column: &Column{Name: "baz"}, Operator: "=", Value: NewValue(99)}, ), } @@ -585,10 +585,10 @@ func TestUpdate(t *testing.T) { Type: Update, Table: TableWithName("table_name"), ColumnValues: JoinColumnValues( - ColumnValue{Column: Column{Name: "foo"}, Operator: "=", Value: NewValue(76)}, + ColumnValue{Column: &Column{Name: "foo"}, Operator: "=", Value: NewValue(76)}, ), Where: WhereConditions( - &ColumnValue{Column: Column{Name: "baz"}, Operator: "=", Value: NewValue(99)}, + &ColumnValue{Column: &Column{Name: "baz"}, Operator: "=", Value: NewValue(99)}, ), } @@ -603,11 +603,11 @@ func TestUpdate(t *testing.T) { Type: Update, Table: TableWithName("table_name"), ColumnValues: JoinColumnValues( - ColumnValue{Column: Column{Name: "foo"}, Operator: "=", Value: NewValue(76)}, - ColumnValue{Column: Column{Name: "bar"}, Operator: "=", Value: NewValue(Raw{Value: "88"})}, + ColumnValue{Column: &Column{Name: "foo"}, Operator: "=", Value: NewValue(76)}, + ColumnValue{Column: &Column{Name: "bar"}, Operator: "=", Value: NewValue(Raw{Value: "88"})}, ), Where: WhereConditions( - &ColumnValue{Column: Column{Name: "baz"}, Operator: "=", Value: NewValue(99)}, + &ColumnValue{Column: &Column{Name: "baz"}, Operator: "=", Value: NewValue(99)}, ), } @@ -627,15 +627,15 @@ func TestInsert(t *testing.T) { Type: Insert, Table: TableWithName("table_name"), Columns: JoinColumns( - Column{Name: "foo"}, - Column{Name: "bar"}, - Column{Name: "baz"}, + &Column{Name: "foo"}, + &Column{Name: "bar"}, + &Column{Name: "baz"}, + ), + Values: JoinValues( + &Value{V: "1"}, + &Value{V: 2}, + &Value{V: Raw{Value: "3"}}, ), - Values: Values{ - Value{V: "1"}, - Value{V: 2}, - Value{V: Raw{Value: "3"}}, - }, } s = trim(stmt.Compile(defaultTemplate)) @@ -655,15 +655,15 @@ func TestInsertExtra(t *testing.T) { Table: TableWithName("table_name"), Extra: "RETURNING id", Columns: JoinColumns( - Column{Name: "foo"}, - Column{Name: "bar"}, - Column{Name: "baz"}, + &Column{Name: "foo"}, + &Column{Name: "bar"}, + &Column{Name: "baz"}, + ), + Values: JoinValues( + &Value{V: "1"}, + &Value{V: 2}, + &Value{V: Raw{Value: "3"}}, ), - Values: Values{ - Value{V: "1"}, - Value{V: 2}, - Value{V: Raw{Value: "3"}}, - }, } s = trim(stmt.Compile(defaultTemplate)) @@ -679,7 +679,7 @@ func BenchmarkStatementSimpleQuery(b *testing.B) { Type: Count, Table: TableWithName("table_name"), Where: WhereConditions( - &ColumnValue{Column: Column{Name: "a"}, Operator: "=", Value: NewValue(Raw{Value: "7"})}, + &ColumnValue{Column: &Column{Name: "a"}, Operator: "=", Value: NewValue(Raw{Value: "7"})}, ), } @@ -693,7 +693,7 @@ func BenchmarkStatementSimpleQueryHash(b *testing.B) { Type: Count, Table: TableWithName("table_name"), Where: WhereConditions( - &ColumnValue{Column: Column{Name: "a"}, Operator: "=", Value: NewValue(Raw{Value: "7"})}, + &ColumnValue{Column: &Column{Name: "a"}, Operator: "=", Value: NewValue(Raw{Value: "7"})}, ), } @@ -708,7 +708,7 @@ func BenchmarkStatementSimpleQueryNoCache(b *testing.B) { Type: Count, Table: TableWithName("table_name"), Where: WhereConditions( - &ColumnValue{Column: Column{Name: "a"}, Operator: "=", Value: NewValue(Raw{Value: "7"})}, + &ColumnValue{Column: &Column{Name: "a"}, Operator: "=", Value: NewValue(Raw{Value: "7"})}, ), } _ = stmt.Compile(defaultTemplate) @@ -720,15 +720,15 @@ func BenchmarkStatementComplexQuery(b *testing.B) { Type: Insert, Table: TableWithName("table_name"), Columns: JoinColumns( - Column{Name: "foo"}, - Column{Name: "bar"}, - Column{Name: "baz"}, + &Column{Name: "foo"}, + &Column{Name: "bar"}, + &Column{Name: "baz"}, + ), + Values: JoinValues( + &Value{V: "1"}, + &Value{V: 2}, + &Value{V: Raw{Value: "3"}}, ), - Values: Values{ - Value{V: "1"}, - Value{V: 2}, - Value{V: Raw{Value: "3"}}, - }, } for i := 0; i < b.N; i++ { @@ -742,15 +742,15 @@ func BenchmarkStatementComplexQueryNoCache(b *testing.B) { Type: Insert, Table: TableWithName("table_name"), Columns: JoinColumns( - Column{Name: "foo"}, - Column{Name: "bar"}, - Column{Name: "baz"}, + &Column{Name: "foo"}, + &Column{Name: "bar"}, + &Column{Name: "baz"}, + ), + Values: JoinValues( + &Value{V: "1"}, + &Value{V: 2}, + &Value{V: Raw{Value: "3"}}, ), - Values: Values{ - Value{V: "1"}, - Value{V: 2}, - Value{V: Raw{Value: "3"}}, - }, } _ = stmt.Compile(defaultTemplate) } diff --git a/util/sqlgen/value.go b/util/sqlgen/value.go index 8c9ff920..eb224e23 100644 --- a/util/sqlgen/value.go +++ b/util/sqlgen/value.go @@ -8,7 +8,10 @@ import ( ) // Values represents an array of Value. -type Values []Value +type Values struct { + Values []Fragment + hash string +} // Value represents an escaped SQL value. type Value struct { @@ -21,6 +24,11 @@ func NewValue(v interface{}) *Value { return &Value{V: v} } +// JoinValues creates and returns an array of values. +func JoinValues(v ...Fragment) *Values { + return &Values{Values: v} +} + // Hash returns a unique identifier. func (v *Value) Hash() string { if v.hash == "" { @@ -69,25 +77,28 @@ func (v *Value) Value() (driver.Value, error) { */ // Hash returns a unique identifier. -func (vs Values) Hash() string { - hash := make([]string, 0, len(vs)) - for i := range vs { - hash = append(hash, vs[i].Hash()) +func (vs *Values) Hash() string { + if vs.hash == "" { + hash := make([]string, len(vs.Values)) + for i := range vs.Values { + hash[i] = vs.Values[i].Hash() + } + vs.hash = `Values(` + strings.Join(hash, `,`) + `)` } - return `Values(` + strings.Join(hash, `,`) + `)` + return vs.hash } // Compile transforms the Values into an equivalent SQL representation. -func (vs Values) Compile(layout *Template) (compiled string) { +func (vs *Values) Compile(layout *Template) (compiled string) { if c, ok := layout.Read(vs); ok { return c } - l := len(vs) + l := len(vs.Values) if l > 0 { chunks := make([]string, 0, l) for i := 0; i < l; i++ { - chunks = append(chunks, vs[i].Compile(layout)) + chunks = append(chunks, vs.Values[i].Compile(layout)) } compiled = strings.Join(chunks, layout.ValueSeparator) } diff --git a/util/sqlgen/value_test.go b/util/sqlgen/value_test.go index 9124608e..8c621700 100644 --- a/util/sqlgen/value_test.go +++ b/util/sqlgen/value_test.go @@ -29,13 +29,12 @@ func TestValue(t *testing.T) { func TestValues(t *testing.T) { var s, e string - var val Values - val = Values{ - Value{V: &Raw{Value: "1"}}, - Value{V: &Raw{Value: "2"}}, - Value{V: "3"}, - } + val := JoinValues( + &Value{V: &Raw{Value: "1"}}, + &Value{V: &Raw{Value: "2"}}, + &Value{V: "3"}, + ) s = val.Compile(defaultTemplate) e = `1, 2, '3'` @@ -71,3 +70,30 @@ func BenchmarkValueCompileNoCache(b *testing.B) { _ = v.Compile(defaultTemplate) } } + +func BenchmarkValues(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = JoinValues(NewValue("a"), NewValue("b")) + } +} + +func BenchmarkValuesHash(b *testing.B) { + vs := JoinValues(NewValue("a"), NewValue("b")) + for i := 0; i < b.N; i++ { + _ = vs.Hash() + } +} + +func BenchmarkValuesCompile(b *testing.B) { + vs := JoinValues(NewValue("a"), NewValue("b")) + for i := 0; i < b.N; i++ { + _ = vs.Compile(defaultTemplate) + } +} + +func BenchmarkValuesCompileNoCache(b *testing.B) { + for i := 0; i < b.N; i++ { + vs := JoinValues(NewValue("a"), NewValue("b")) + _ = vs.Compile(defaultTemplate) + } +} diff --git a/util/sqlgen/where_test.go b/util/sqlgen/where_test.go index 7fc91846..c4b2a182 100644 --- a/util/sqlgen/where_test.go +++ b/util/sqlgen/where_test.go @@ -8,9 +8,9 @@ func TestWhereAnd(t *testing.T) { var s, e string and := JoinWithAnd( - &ColumnValue{Column: Column{Name: "id"}, Operator: ">", Value: NewValue(&Raw{Value: "8"})}, - &ColumnValue{Column: Column{Name: "id"}, Operator: "<", Value: NewValue(&Raw{Value: "99"})}, - &ColumnValue{Column: Column{Name: "name"}, Operator: "=", Value: NewValue("John")}, + &ColumnValue{Column: &Column{Name: "id"}, Operator: ">", Value: NewValue(&Raw{Value: "8"})}, + &ColumnValue{Column: &Column{Name: "id"}, Operator: "<", Value: NewValue(&Raw{Value: "99"})}, + &ColumnValue{Column: &Column{Name: "name"}, Operator: "=", Value: NewValue("John")}, ) s = and.Compile(defaultTemplate) @@ -25,8 +25,8 @@ func TestWhereOr(t *testing.T) { var s, e string or := JoinWithOr( - &ColumnValue{Column: Column{Name: "id"}, Operator: "=", Value: NewValue(&Raw{Value: "8"})}, - &ColumnValue{Column: Column{Name: "id"}, Operator: "=", Value: NewValue(&Raw{Value: "99"})}, + &ColumnValue{Column: &Column{Name: "id"}, Operator: "=", Value: NewValue(&Raw{Value: "8"})}, + &ColumnValue{Column: &Column{Name: "id"}, Operator: "=", Value: NewValue(&Raw{Value: "99"})}, ) s = or.Compile(defaultTemplate) @@ -41,12 +41,12 @@ func TestWhereAndOr(t *testing.T) { var s, e string and := JoinWithAnd( - &ColumnValue{Column: Column{Name: "id"}, Operator: ">", Value: NewValue(&Raw{Value: "8"})}, - &ColumnValue{Column: Column{Name: "id"}, Operator: "<", Value: NewValue(&Raw{Value: "99"})}, - &ColumnValue{Column: Column{Name: "name"}, Operator: "=", Value: NewValue("John")}, + &ColumnValue{Column: &Column{Name: "id"}, Operator: ">", Value: NewValue(&Raw{Value: "8"})}, + &ColumnValue{Column: &Column{Name: "id"}, Operator: "<", Value: NewValue(&Raw{Value: "99"})}, + &ColumnValue{Column: &Column{Name: "name"}, Operator: "=", Value: NewValue("John")}, JoinWithOr( - &ColumnValue{Column: Column{Name: "last_name"}, Operator: "=", Value: NewValue("Smith")}, - &ColumnValue{Column: Column{Name: "last_name"}, Operator: "=", Value: NewValue("Reyes")}, + &ColumnValue{Column: &Column{Name: "last_name"}, Operator: "=", Value: NewValue("Smith")}, + &ColumnValue{Column: &Column{Name: "last_name"}, Operator: "=", Value: NewValue("Reyes")}, ), ) @@ -63,18 +63,18 @@ func TestWhereAndRawOrAnd(t *testing.T) { where := WhereConditions( JoinWithAnd( - &ColumnValue{Column: Column{Name: "id"}, Operator: ">", Value: NewValue(&Raw{Value: "8"})}, - &ColumnValue{Column: Column{Name: "id"}, Operator: "<", Value: NewValue(&Raw{Value: "99"})}, + &ColumnValue{Column: &Column{Name: "id"}, Operator: ">", Value: NewValue(&Raw{Value: "8"})}, + &ColumnValue{Column: &Column{Name: "id"}, Operator: "<", Value: NewValue(&Raw{Value: "99"})}, ), - &ColumnValue{Column: Column{Name: "name"}, Operator: "=", Value: NewValue("John")}, + &ColumnValue{Column: &Column{Name: "name"}, Operator: "=", Value: NewValue("John")}, &Raw{Value: "city_id = 728"}, JoinWithOr( - &ColumnValue{Column: Column{Name: "last_name"}, Operator: "=", Value: NewValue("Smith")}, - &ColumnValue{Column: Column{Name: "last_name"}, Operator: "=", Value: NewValue("Reyes")}, + &ColumnValue{Column: &Column{Name: "last_name"}, Operator: "=", Value: NewValue("Smith")}, + &ColumnValue{Column: &Column{Name: "last_name"}, Operator: "=", Value: NewValue("Reyes")}, ), JoinWithAnd( - &ColumnValue{Column: Column{Name: "age"}, Operator: ">", Value: NewValue(&Raw{Value: "18"})}, - &ColumnValue{Column: Column{Name: "age"}, Operator: "<", Value: NewValue(&Raw{Value: "41"})}, + &ColumnValue{Column: &Column{Name: "age"}, Operator: ">", Value: NewValue(&Raw{Value: "18"})}, + &ColumnValue{Column: &Column{Name: "age"}, Operator: "<", Value: NewValue(&Raw{Value: "41"})}, ), ) @@ -89,14 +89,14 @@ func TestWhereAndRawOrAnd(t *testing.T) { func BenchmarkWhere(b *testing.B) { for i := 0; i < b.N; i++ { _ = WhereConditions( - &ColumnValue{Column: Column{Name: "baz"}, Operator: "=", Value: NewValue(99)}, + &ColumnValue{Column: &Column{Name: "baz"}, Operator: "=", Value: NewValue(99)}, ) } } func BenchmarkCompileWhere(b *testing.B) { w := WhereConditions( - &ColumnValue{Column: Column{Name: "baz"}, Operator: "=", Value: NewValue(99)}, + &ColumnValue{Column: &Column{Name: "baz"}, Operator: "=", Value: NewValue(99)}, ) for i := 0; i < b.N; i++ { w.Compile(defaultTemplate) @@ -106,7 +106,7 @@ func BenchmarkCompileWhere(b *testing.B) { func BenchmarkCompileWhereNoCache(b *testing.B) { for i := 0; i < b.N; i++ { w := WhereConditions( - &ColumnValue{Column: Column{Name: "baz"}, Operator: "=", Value: NewValue(99)}, + &ColumnValue{Column: &Column{Name: "baz"}, Operator: "=", Value: NewValue(99)}, ) w.Compile(defaultTemplate) } -- GitLab