Skip to content

Commit 511937c

Browse files
committed
Merge pull request #289 from chrismoos/expose_aliases
Add support for returning table alias on Columns()
2 parents 04cf947 + 3454863 commit 511937c

File tree

7 files changed

+59
-18
lines changed

7 files changed

+59
-18
lines changed

AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
Aaron Hopkins <go-sql-driver at die.net>
1515
Arne Hormann <arnehormann at gmail.com>
1616
Carlos Nieto <jose.carlos at menteslibres.net>
17+
Chris Moos <chris at tech9computers.com>
1718
DisposaBoy <disposaboy at dby.me>
1819
Frederick Mayle <frederickmayle at gmail.com>
1920
Gustavo Kristic <gkristic at gmail.com>

README.md

+15
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,21 @@ Default: false
166166

167167
`clientFoundRows=true` causes an UPDATE to return the number of matching rows instead of the number of rows changed.
168168

169+
##### `columnsWithAlias`
170+
171+
```
172+
Type: bool
173+
Valid Values: true, false
174+
Default: false
175+
```
176+
177+
When `columnsWithAlias` is true, calls to `sql.Rows.Columns()` will return the table alias and the column name separated by a dot. For example:
178+
179+
```
180+
SELECT u.id FROM users as u
181+
```
182+
183+
will return `u.id` instead of just `id` if `columnsWithAlias=true`.
169184

170185
##### `loc`
171186

connection.go

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ type config struct {
4545
allowAllFiles bool
4646
allowOldPasswords bool
4747
clientFoundRows bool
48+
columnsWithAlias bool
4849
}
4950

5051
// Handles parameters set in DSN after the connection is established

packets.go

+13-4
Original file line numberDiff line numberDiff line change
@@ -530,11 +530,20 @@ func (mc *mysqlConn) readColumns(count int) ([]mysqlField, error) {
530530
pos += n
531531

532532
// Table [len coded string]
533-
n, err = skipLengthEncodedString(data[pos:])
534-
if err != nil {
535-
return nil, err
533+
if mc.cfg.columnsWithAlias {
534+
tableName, _, n, err := readLengthEncodedString(data[pos:])
535+
if err != nil {
536+
return nil, err
537+
}
538+
pos += n
539+
columns[i].tableName = string(tableName)
540+
} else {
541+
n, err = skipLengthEncodedString(data[pos:])
542+
if err != nil {
543+
return nil, err
544+
}
545+
pos += n
536546
}
537-
pos += n
538547

539548
// Original table [len coded string]
540549
n, err = skipLengthEncodedString(data[pos:])

rows.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
)
1515

1616
type mysqlField struct {
17+
tableName string
1718
name string
1819
flags fieldFlag
1920
fieldType byte
@@ -37,8 +38,14 @@ type emptyRows struct{}
3738

3839
func (rows *mysqlRows) Columns() []string {
3940
columns := make([]string, len(rows.columns))
40-
for i := range columns {
41-
columns[i] = rows.columns[i].name
41+
if rows.mc.cfg.columnsWithAlias {
42+
for i := range columns {
43+
columns[i] = rows.columns[i].tableName + "." + rows.columns[i].name
44+
}
45+
} else {
46+
for i := range columns {
47+
columns[i] = rows.columns[i].name
48+
}
4249
}
4350
return columns
4451
}

utils.go

+7
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,13 @@ func parseDSNParams(cfg *config, params string) (err error) {
216216
}
217217
cfg.collation = collation
218218
break
219+
220+
case "columnsWithAlias":
221+
var isBool bool
222+
cfg.columnsWithAlias, isBool = readBool(value)
223+
if !isBool {
224+
return fmt.Errorf("Invalid Bool value: %s", value)
225+
}
219226

220227
// Time Location
221228
case "loc":

utils_test.go

+13-12
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,19 @@ var testDSNs = []struct {
2222
out string
2323
loc *time.Location
2424
}{
25-
{"username:password@protocol(address)/dbname?param=value", "&{user:username passwd:password net:protocol addr:address dbname:dbname params:map[param:value] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false}", time.UTC},
26-
{"user@unix(/path/to/socket)/dbname?charset=utf8", "&{user:user passwd: net:unix addr:/path/to/socket dbname:dbname params:map[charset:utf8] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false}", time.UTC},
27-
{"user:password@tcp(localhost:5555)/dbname?charset=utf8&tls=true", "&{user:user passwd:password net:tcp addr:localhost:5555 dbname:dbname params:map[charset:utf8] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false}", time.UTC},
28-
{"user:password@tcp(localhost:5555)/dbname?charset=utf8mb4,utf8&tls=skip-verify", "&{user:user passwd:password net:tcp addr:localhost:5555 dbname:dbname params:map[charset:utf8mb4,utf8] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false}", time.UTC},
29-
{"user:password@/dbname?loc=UTC&timeout=30s&allowAllFiles=1&clientFoundRows=true&allowOldPasswords=TRUE&collation=utf8mb4_unicode_ci", "&{user:user passwd:password net:tcp addr:127.0.0.1:3306 dbname:dbname params:map[] loc:%p tls:<nil> timeout:30000000000 collation:224 allowAllFiles:true allowOldPasswords:true clientFoundRows:true}", time.UTC},
30-
{"user:p@ss(word)@tcp([de:ad:be:ef::ca:fe]:80)/dbname?loc=Local", "&{user:user passwd:p@ss(word) net:tcp addr:[de:ad:be:ef::ca:fe]:80 dbname:dbname params:map[] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false}", time.Local},
31-
{"/dbname", "&{user: passwd: net:tcp addr:127.0.0.1:3306 dbname:dbname params:map[] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false}", time.UTC},
32-
{"@/", "&{user: passwd: net:tcp addr:127.0.0.1:3306 dbname: params:map[] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false}", time.UTC},
33-
{"/", "&{user: passwd: net:tcp addr:127.0.0.1:3306 dbname: params:map[] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false}", time.UTC},
34-
{"", "&{user: passwd: net:tcp addr:127.0.0.1:3306 dbname: params:map[] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false}", time.UTC},
35-
{"user:p@/ssword@/", "&{user:user passwd:p@/ssword net:tcp addr:127.0.0.1:3306 dbname: params:map[] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false}", time.UTC},
36-
{"unix/?arg=%2Fsome%2Fpath.ext", "&{user: passwd: net:unix addr:/tmp/mysql.sock dbname: params:map[arg:/some/path.ext] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false}", time.UTC},
25+
{"username:password@protocol(address)/dbname?param=value", "&{user:username passwd:password net:protocol addr:address dbname:dbname params:map[param:value] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false columnsWithAlias:false}", time.UTC},
26+
{"username:password@protocol(address)/dbname?param=value&columnsWithAlias=true", "&{user:username passwd:password net:protocol addr:address dbname:dbname params:map[param:value] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false columnsWithAlias:true}", time.UTC},
27+
{"user@unix(/path/to/socket)/dbname?charset=utf8", "&{user:user passwd: net:unix addr:/path/to/socket dbname:dbname params:map[charset:utf8] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false columnsWithAlias:false}", time.UTC},
28+
{"user:password@tcp(localhost:5555)/dbname?charset=utf8&tls=true", "&{user:user passwd:password net:tcp addr:localhost:5555 dbname:dbname params:map[charset:utf8] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false columnsWithAlias:false}", time.UTC},
29+
{"user:password@tcp(localhost:5555)/dbname?charset=utf8mb4,utf8&tls=skip-verify", "&{user:user passwd:password net:tcp addr:localhost:5555 dbname:dbname params:map[charset:utf8mb4,utf8] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false columnsWithAlias:false}", time.UTC},
30+
{"user:password@/dbname?loc=UTC&timeout=30s&allowAllFiles=1&clientFoundRows=true&allowOldPasswords=TRUE&collation=utf8mb4_unicode_ci", "&{user:user passwd:password net:tcp addr:127.0.0.1:3306 dbname:dbname params:map[] loc:%p tls:<nil> timeout:30000000000 collation:224 allowAllFiles:true allowOldPasswords:true clientFoundRows:true columnsWithAlias:false}", time.UTC},
31+
{"user:p@ss(word)@tcp([de:ad:be:ef::ca:fe]:80)/dbname?loc=Local", "&{user:user passwd:p@ss(word) net:tcp addr:[de:ad:be:ef::ca:fe]:80 dbname:dbname params:map[] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false columnsWithAlias:false}", time.Local},
32+
{"/dbname", "&{user: passwd: net:tcp addr:127.0.0.1:3306 dbname:dbname params:map[] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false columnsWithAlias:false}", time.UTC},
33+
{"@/", "&{user: passwd: net:tcp addr:127.0.0.1:3306 dbname: params:map[] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false columnsWithAlias:false}", time.UTC},
34+
{"/", "&{user: passwd: net:tcp addr:127.0.0.1:3306 dbname: params:map[] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false columnsWithAlias:false}", time.UTC},
35+
{"", "&{user: passwd: net:tcp addr:127.0.0.1:3306 dbname: params:map[] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false columnsWithAlias:false}", time.UTC},
36+
{"user:p@/ssword@/", "&{user:user passwd:p@/ssword net:tcp addr:127.0.0.1:3306 dbname: params:map[] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false columnsWithAlias:false}", time.UTC},
37+
{"unix/?arg=%2Fsome%2Fpath.ext", "&{user: passwd: net:unix addr:/tmp/mysql.sock dbname: params:map[arg:/some/path.ext] loc:%p tls:<nil> timeout:0 collation:33 allowAllFiles:false allowOldPasswords:false clientFoundRows:false columnsWithAlias:false}", time.UTC},
3738
}
3839

3940
func TestDSNParser(t *testing.T) {

0 commit comments

Comments
 (0)