From 12210d5e75d02418d421124a85ae98c7f898e843 Mon Sep 17 00:00:00 2001 From: Patrick Scott Date: Thu, 19 Mar 2015 10:11:19 -0400 Subject: [PATCH 1/2] Allow aliases to IdentifierExpressions. This allows me to write goqu.I("col").As(goqu.I("other")) as well as the original goqu.I("col").As("other"). --- example_test.go | 4 ++++ expressions.go | 24 ++++++++++++++++-------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/example_test.go b/example_test.go index f4b985fa..fb6d98e4 100644 --- a/example_test.go +++ b/example_test.go @@ -135,10 +135,14 @@ func ExampleAliasMethods() { sql, _, _ = db.From("test").Select(goqu.L("sum(amount)").As("total_amount")).ToSql() fmt.Println(sql) + + sql, _, _ = db.From("test").Select(goqu.I("test.a").As(goqu.I("test.b"))).ToSql() + fmt.Println(sql) // Output: // SELECT "a" AS "as_a" FROM "test" // SELECT COUNT(*) AS "count" FROM "test" // SELECT sum(amount) AS "total_amount" FROM "test" + // SELECT "test"."a" AS "test"."b" FROM "test" } diff --git a/expressions.go b/expressions.go index fef1dc5d..2286e053 100644 --- a/expressions.go +++ b/expressions.go @@ -399,7 +399,8 @@ type ( AliasMethods interface { //Returns an AliasedExpression // I("col").As("other_col") //"col" AS "other_col" - As(string) AliasedExpression + // I("col").As(I("other_col")) //"col" AS "other_col" + As(interface{}) AliasedExpression } //Interface that an expression should implement if it can be compared with other values. ComparisonMethods interface { @@ -621,7 +622,7 @@ func (me identifier) GetCol() interface{} { return me.col } func (me identifier) Set(val interface{}) UpdateExpression { return set(me, val) } //Alias an identifer (e.g "my_col" AS "other_col") -func (me identifier) As(as string) AliasedExpression { return aliased(me, as) } +func (me identifier) As(val interface{}) AliasedExpression { return aliased(me, val) } //Returns a BooleanExpression for equality (e.g "my_col" = 1) func (me identifier) Eq(val interface{}) BooleanExpression { return eq(me, val) } @@ -720,7 +721,7 @@ func (me literal) Args() []interface{} { } func (me literal) Expression() Expression { return me } -func (me literal) As(as string) AliasedExpression { return aliased(me, as) } +func (me literal) As(val interface{}) AliasedExpression { return aliased(me, val) } func (me literal) Eq(val interface{}) BooleanExpression { return eq(me, val) } func (me literal) Neq(val interface{}) BooleanExpression { return neq(me, val) } func (me literal) Gt(val interface{}) BooleanExpression { return gt(me, val) } @@ -982,7 +983,7 @@ func checkBoolExpType(op BooleanOperation, lhs Expression, rhs interface{}, inve type ( //Expression for Aliased expressions // I("a").As("b") -> "a" AS "b" - // SUM("a").As("a_sum") -> SUM("a") AS "a_sum" + // SUM("a").As(I("a_sum")) -> SUM("a") AS "a_sum" AliasedExpression interface { Expression //Returns the Epxression being aliased @@ -997,8 +998,15 @@ type ( ) //used internally by other expressions to create a new aliased expression -func aliased(exp Expression, alias string) AliasedExpression { - return aliasExpression{aliased: exp, alias: I(alias)} +func aliased(exp Expression, alias interface{}) AliasedExpression { + switch v := alias.(type) { + case string: + return aliasExpression{aliased: exp, alias: I(v)} + case IdentifierExpression: + return aliasExpression{aliased: exp, alias: v} + default: + panic(fmt.Sprintf("Cannot create alias from %+v", v)) + } } func (me aliasExpression) Clone() Expression { @@ -1178,7 +1186,7 @@ func (me sqlFunctionExpression) Clone() Expression { func (me sqlFunctionExpression) Expression() Expression { return me } func (me sqlFunctionExpression) Args() []interface{} { return me.args } func (me sqlFunctionExpression) Name() string { return me.name } -func (me sqlFunctionExpression) As(as string) AliasedExpression { return aliased(me, as) } +func (me sqlFunctionExpression) As(val interface{}) AliasedExpression { return aliased(me, val) } func (me sqlFunctionExpression) Eq(val interface{}) BooleanExpression { return eq(me, val) } func (me sqlFunctionExpression) Neq(val interface{}) BooleanExpression { return neq(me, val) } func (me sqlFunctionExpression) Gt(val interface{}) BooleanExpression { return gt(me, val) } @@ -1227,7 +1235,7 @@ func (me cast) Clone() Expression { } func (me cast) Expression() Expression { return me } -func (me cast) As(as string) AliasedExpression { return aliased(me, as) } +func (me cast) As(val interface{}) AliasedExpression { return aliased(me, val) } func (me cast) Eq(val interface{}) BooleanExpression { return eq(me, val) } func (me cast) Neq(val interface{}) BooleanExpression { return neq(me, val) } func (me cast) Gt(val interface{}) BooleanExpression { return gt(me, val) } From 310eb650d81415c2298395d8b3e1a203808c2a40 Mon Sep 17 00:00:00 2001 From: Patrick Scott Date: Thu, 19 Mar 2015 11:12:17 -0400 Subject: [PATCH 2/2] Use a better example of aliasing with identifier. Aliasing from table.column to anything with a period is not allowed (at least not in mysql). Provide a better example that works across databases. Add a test to TestLiteralAliasedExpression that uses an IdentifierExpression. --- dataset_test.go | 4 ++++ example_test.go | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/dataset_test.go b/dataset_test.go index 2ff35ba5..47465e62 100644 --- a/dataset_test.go +++ b/dataset_test.go @@ -369,6 +369,10 @@ func (me *datasetTest) TestLiteralAliasedExpression() { assert.NoError(t, ds.Literal(me.Truncate(buf), Literal("count(*)").As("count"))) assert.Equal(t, buf.args, []interface{}{}) assert.Equal(t, buf.String(), `count(*) AS "count"`) + + buf = NewSqlBuilder(false) + assert.NoError(t, ds.Literal(me.Truncate(buf), I("a").As(I("b")))) + assert.Equal(t, buf.String(), `"a" AS "b"`) } func (me *datasetTest) TestBooleanExpression() { diff --git a/example_test.go b/example_test.go index fb6d98e4..6141e43d 100644 --- a/example_test.go +++ b/example_test.go @@ -136,13 +136,13 @@ func ExampleAliasMethods() { sql, _, _ = db.From("test").Select(goqu.L("sum(amount)").As("total_amount")).ToSql() fmt.Println(sql) - sql, _, _ = db.From("test").Select(goqu.I("test.a").As(goqu.I("test.b"))).ToSql() + sql, _, _ = db.From("test").Select(goqu.I("a").As(goqu.I("as_a"))).ToSql() fmt.Println(sql) // Output: // SELECT "a" AS "as_a" FROM "test" // SELECT COUNT(*) AS "count" FROM "test" // SELECT sum(amount) AS "total_amount" FROM "test" - // SELECT "test"."a" AS "test"."b" FROM "test" + // SELECT "a" AS "as_a" FROM "test" }