Coder Social home page Coder Social logo

go-sql-driver / mysql Goto Github PK

View Code? Open in Web Editor NEW
14.2K 409.0 2.3K 1.27 MB

Go MySQL Driver is a MySQL driver for Go's (golang) database/sql package

Home Page: https://pkg.go.dev/github.com/go-sql-driver/mysql

License: Mozilla Public License 2.0

Go 100.00%
go mysql sql database mysql-driver mariadb

mysql's Introduction

Go-MySQL-Driver

A MySQL-Driver for Go's database/sql package

Go-MySQL-Driver logo



Features

  • Lightweight and fast
  • Native Go implementation. No C-bindings, just pure Go
  • Connections over TCP/IPv4, TCP/IPv6, Unix domain sockets or custom protocols
  • Automatic handling of broken connections
  • Automatic Connection Pooling (by database/sql package)
  • Supports queries larger than 16MB
  • Full sql.RawBytes support.
  • Intelligent LONG DATA handling in prepared statements
  • Secure LOAD DATA LOCAL INFILE support with file allowlisting and io.Reader support
  • Optional time.Time parsing
  • Optional placeholder interpolation

Requirements

  • Go 1.20 or higher. We aim to support the 3 latest versions of Go.
  • MySQL (5.7+) and MariaDB (10.5+) are supported.
  • TiDB is supported by PingCAP.
    • Do not ask questions about TiDB in our issue tracker or forum.
    • Document
    • Forum
  • go-mysql would work with Percona Server, Google CloudSQL or Sphinx (2.2.3+).
    • Maintainers won't support them. Do not expect issues are investigated and resolved by maintainers.
    • Investigate issues yourself and please send a pull request to fix it.

Installation

Simple install the package to your $GOPATH with the go tool from shell:

go get -u github.com/go-sql-driver/mysql

Make sure Git is installed on your machine and in your system's PATH.

Usage

Go MySQL Driver is an implementation of Go's database/sql/driver interface. You only need to import the driver and can use the full database/sql API then.

Use mysql as driverName and a valid DSN as dataSourceName:

import (
	"database/sql"
	"time"

	_ "github.com/go-sql-driver/mysql"
)

// ...

db, err := sql.Open("mysql", "user:password@/dbname")
if err != nil {
	panic(err)
}
// See "Important settings" section.
db.SetConnMaxLifetime(time.Minute * 3)
db.SetMaxOpenConns(10)
db.SetMaxIdleConns(10)

Examples are available in our Wiki.

Important settings

db.SetConnMaxLifetime() is required to ensure connections are closed by the driver safely before connection is closed by MySQL server, OS, or other middlewares. Since some middlewares close idle connections by 5 minutes, we recommend timeout shorter than 5 minutes. This setting helps load balancing and changing system variables too.

db.SetMaxOpenConns() is highly recommended to limit the number of connection used by the application. There is no recommended limit number because it depends on application and MySQL server.

db.SetMaxIdleConns() is recommended to be set same to db.SetMaxOpenConns(). When it is smaller than SetMaxOpenConns(), connections can be opened and closed much more frequently than you expect. Idle connections can be closed by the db.SetConnMaxLifetime(). If you want to close idle connections more rapidly, you can use db.SetConnMaxIdleTime() since Go 1.15.

DSN (Data Source Name)

The Data Source Name has a common format, like e.g. PEAR DB uses it, but without type-prefix (optional parts marked by squared brackets):

[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...&paramN=valueN]

A DSN in its fullest form:

username:password@protocol(address)/dbname?param=value

Except for the databasename, all values are optional. So the minimal DSN is:

/dbname

If you do not want to preselect a database, leave dbname empty:

/

This has the same effect as an empty DSN string:


dbname is escaped by PathEscape() since v1.8.0. If your database name is dbname/withslash, it becomes:

/dbname%2Fwithslash

Alternatively, Config.FormatDSN can be used to create a DSN string by filling a struct.

Password

Passwords can consist of any character. Escaping is not necessary.

Protocol

See net.Dial for more information which networks are available. In general you should use a Unix domain socket if available and TCP otherwise for best performance.

Address

For TCP and UDP networks, addresses have the form host[:port]. If port is omitted, the default port will be used. If host is a literal IPv6 address, it must be enclosed in square brackets. The functions net.JoinHostPort and net.SplitHostPort manipulate addresses in this form.

For Unix domain sockets the address is the absolute path to the MySQL-Server-socket, e.g. /var/run/mysqld/mysqld.sock or /tmp/mysql.sock.

Parameters

Parameters are case-sensitive!

Notice that any of true, TRUE, True or 1 is accepted to stand for a true boolean value. Not surprisingly, false can be specified as any of: false, FALSE, False or 0.

allowAllFiles
Type:           bool
Valid Values:   true, false
Default:        false

allowAllFiles=true disables the file allowlist for LOAD DATA LOCAL INFILE and allows all files. Might be insecure!

allowCleartextPasswords
Type:           bool
Valid Values:   true, false
Default:        false

allowCleartextPasswords=true allows using the cleartext client side plugin if required by an account, such as one defined with the PAM authentication plugin. Sending passwords in clear text may be a security problem in some configurations. To avoid problems if there is any possibility that the password would be intercepted, clients should connect to MySQL Server using a method that protects the password. Possibilities include TLS / SSL, IPsec, or a private network.

allowFallbackToPlaintext
Type:           bool
Valid Values:   true, false
Default:        false

allowFallbackToPlaintext=true acts like a --ssl-mode=PREFERRED MySQL client as described in Command Options for Connecting to the Server

allowNativePasswords
Type:           bool
Valid Values:   true, false
Default:        true

allowNativePasswords=false disallows the usage of MySQL native password method.

allowOldPasswords
Type:           bool
Valid Values:   true, false
Default:        false

allowOldPasswords=true allows the usage of the insecure old password method. This should be avoided, but is necessary in some cases. See also the old_passwords wiki page.

charset
Type:           string
Valid Values:   <name>
Default:        none

Sets the charset used for client-server interaction ("SET NAMES <value>"). If multiple charsets are set (separated by a comma), the following charset is used if setting the charset fails. This enables for example support for utf8mb4 (introduced in MySQL 5.5.3) with fallback to utf8 for older servers (charset=utf8mb4,utf8).

See also Unicode Support.

checkConnLiveness
Type:           bool
Valid Values:   true, false
Default:        true

On supported platforms connections retrieved from the connection pool are checked for liveness before using them. If the check fails, the respective connection is marked as bad and the query retried with another connection. checkConnLiveness=false disables this liveness check of connections.

collation
Type:           string
Valid Values:   <name>
Default:        utf8mb4_general_ci

Sets the collation used for client-server interaction on connection. In contrast to charset, collation does not issue additional queries. If the specified collation is unavailable on the target server, the connection will fail.

A list of valid charsets for a server is retrievable with SHOW COLLATION.

The default collation (utf8mb4_general_ci) is supported from MySQL 5.5. You should use an older collation (e.g. utf8_general_ci) for older MySQL.

Collations for charset "ucs2", "utf16", "utf16le", and "utf32" can not be used (ref).

See also Unicode Support.

clientFoundRows
Type:           bool
Valid Values:   true, false
Default:        false

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

columnsWithAlias
Type:           bool
Valid Values:   true, false
Default:        false

When columnsWithAlias is true, calls to sql.Rows.Columns() will return the table alias and the column name separated by a dot. For example:

SELECT u.id FROM users as u

will return u.id instead of just id if columnsWithAlias=true.

interpolateParams
Type:           bool
Valid Values:   true, false
Default:        false

If interpolateParams is true, placeholders (?) in calls to db.Query() and db.Exec() are interpolated into a single query string with given parameters. This reduces the number of roundtrips, since the driver has to prepare a statement, execute it with given parameters and close the statement again with interpolateParams=false.

This can not be used together with the multibyte encodings BIG5, CP932, GB2312, GBK or SJIS. These are rejected as they may introduce a SQL injection vulnerability!

loc
Type:           string
Valid Values:   <escaped name>
Default:        UTC

Sets the location for time.Time values (when using parseTime=true). "Local" sets the system's location. See time.LoadLocation for details.

Note that this sets the location for time.Time values but does not change MySQL's time_zone setting. For that see the time_zone system variable, which can also be set as a DSN parameter.

Please keep in mind, that param values must be url.QueryEscape'ed. Alternatively you can manually replace the / with %2F. For example US/Pacific would be loc=US%2FPacific.

timeTruncate
Type:           duration
Default:        0

Truncate time values to the specified duration. The value must be a decimal number with a unit suffix ("ms", "s", "m", "h"), such as "30s", "0.5m" or "1m30s".

maxAllowedPacket
Type:          decimal number
Default:       64*1024*1024

Max packet size allowed in bytes. The default value is 64 MiB and should be adjusted to match the server settings. maxAllowedPacket=0 can be used to automatically fetch the max_allowed_packet variable from server on every connection.

multiStatements
Type:           bool
Valid Values:   true, false
Default:        false

Allow multiple statements in one query. This can be used to bach multiple queries. Use Rows.NextResultSet() to get result of the second and subsequent queries.

When multiStatements is used, ? parameters must only be used in the first statement. interpolateParams can be used to avoid this limitation unless prepared statement is used explicitly.

It's possible to access the last inserted ID and number of affected rows for multiple statements by using sql.Conn.Raw() and the mysql.Result. For example:

conn, _ := db.Conn(ctx)
conn.Raw(func(conn any) error {
  ex := conn.(driver.Execer)
  res, err := ex.Exec(`
  UPDATE point SET x = 1 WHERE y = 2;
  UPDATE point SET x = 2 WHERE y = 3;
  `, nil)
  // Both slices have 2 elements.
  log.Print(res.(mysql.Result).AllRowsAffected())
  log.Print(res.(mysql.Result).AllLastInsertIds())
})
parseTime
Type:           bool
Valid Values:   true, false
Default:        false

parseTime=true changes the output type of DATE and DATETIME values to time.Time instead of []byte / string The date or datetime like 0000-00-00 00:00:00 is converted into zero value of time.Time.

readTimeout
Type:           duration
Default:        0

I/O read timeout. The value must be a decimal number with a unit suffix ("ms", "s", "m", "h"), such as "30s", "0.5m" or "1m30s".

rejectReadOnly
Type:           bool
Valid Values:   true, false
Default:        false

rejectReadOnly=true causes the driver to reject read-only connections. This is for a possible race condition during an automatic failover, where the mysql client gets connected to a read-only replica after the failover.

Note that this should be a fairly rare case, as an automatic failover normally happens when the primary is down, and the race condition shouldn't happen unless it comes back up online as soon as the failover is kicked off. On the other hand, when this happens, a MySQL application can get stuck on a read-only connection until restarted. It is however fairly easy to reproduce, for example, using a manual failover on AWS Aurora's MySQL-compatible cluster.

If you are not relying on read-only transactions to reject writes that aren't supposed to happen, setting this on some MySQL providers (such as AWS Aurora) is safer for failovers.

Note that ERROR 1290 can be returned for a read-only server and this option will cause a retry for that error. However the same error number is used for some other cases. You should ensure your application will never cause an ERROR 1290 except for read-only mode when enabling this option.

serverPubKey
Type:           string
Valid Values:   <name>
Default:        none

Server public keys can be registered with mysql.RegisterServerPubKey, which can then be used by the assigned name in the DSN. Public keys are used to transmit encrypted data, e.g. for authentication. If the server's public key is known, it should be set manually to avoid expensive and potentially insecure transmissions of the public key from the server to the client each time it is required.

timeout
Type:           duration
Default:        OS default

Timeout for establishing connections, aka dial timeout. The value must be a decimal number with a unit suffix ("ms", "s", "m", "h"), such as "30s", "0.5m" or "1m30s".

tls
Type:           bool / string
Valid Values:   true, false, skip-verify, preferred, <name>
Default:        false

tls=true enables TLS / SSL encrypted connection to the server. Use skip-verify if you want to use a self-signed or invalid certificate (server side) or use preferred to use TLS only when advertised by the server. This is similar to skip-verify, but additionally allows a fallback to a connection which is not encrypted. Neither skip-verify nor preferred add any reliable security. You can use a custom TLS config after registering it with mysql.RegisterTLSConfig.

writeTimeout
Type:           duration
Default:        0

I/O write timeout. The value must be a decimal number with a unit suffix ("ms", "s", "m", "h"), such as "30s", "0.5m" or "1m30s".

connectionAttributes
Type:           comma-delimited string of user-defined "key:value" pairs
Valid Values:   (<name1>:<value1>,<name2>:<value2>,...)
Default:        none

Connection attributes are key-value pairs that application programs can pass to the server at connect time.

System Variables

Any other parameters are interpreted as system variables:

  • <boolean_var>=<value>: SET <boolean_var>=<value>
  • <enum_var>=<value>: SET <enum_var>=<value>
  • <string_var>=%27<value>%27: SET <string_var>='<value>'

Rules:

  • The values for string variables must be quoted with '.
  • The values must also be url.QueryEscape'ed! (which implies values of string variables must be wrapped with %27).

Examples:

Examples

user@unix(/path/to/socket)/dbname
root:pw@unix(/tmp/mysql.sock)/myDatabase?loc=Local
user:password@tcp(localhost:5555)/dbname?tls=skip-verify&autocommit=true

Treat warnings as errors by setting the system variable sql_mode:

user:password@/dbname?sql_mode=TRADITIONAL

TCP via IPv6:

user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname?timeout=90s&collation=utf8mb4_unicode_ci

TCP on a remote host, e.g. Amazon RDS:

id:password@tcp(your-amazonaws-uri.com:3306)/dbname

Google Cloud SQL on App Engine:

user:password@unix(/cloudsql/project-id:region-name:instance-name)/dbname

TCP using default port (3306) on localhost:

user:password@tcp/dbname?charset=utf8mb4,utf8&sys_var=esc%40ped

Use the default protocol (tcp) and host (localhost:3306):

user:password@/dbname

No Database preselected:

user:password@/

Connection pool and timeouts

The connection pool is managed by Go's database/sql package. For details on how to configure the size of the pool and how long connections stay in the pool see *DB.SetMaxOpenConns, *DB.SetMaxIdleConns, and *DB.SetConnMaxLifetime in the database/sql documentation. The read, write, and dial timeouts for each individual connection are configured with the DSN parameters readTimeout, writeTimeout, and timeout, respectively.

ColumnType Support

This driver supports the ColumnType interface introduced in Go 1.8, with the exception of ColumnType.Length(), which is currently not supported. All Unsigned database type names will be returned UNSIGNED with INT, TINYINT, SMALLINT, MEDIUMINT, BIGINT.

context.Context Support

Go 1.8 added database/sql support for context.Context. This driver supports query timeouts and cancellation via contexts. See context support in the database/sql package for more details.

LOAD DATA LOCAL INFILE support

For this feature you need direct access to the package. Therefore you must change the import path (no _):

import "github.com/go-sql-driver/mysql"

Files must be explicitly allowed by registering them with mysql.RegisterLocalFile(filepath) (recommended) or the allowlist check must be deactivated by using the DSN parameter allowAllFiles=true (Might be insecure!).

To use a io.Reader a handler function must be registered with mysql.RegisterReaderHandler(name, handler) which returns a io.Reader or io.ReadCloser. The Reader is available with the filepath Reader::<name> then. Choose different names for different handlers and DeregisterReaderHandler when you don't need it anymore.

See the godoc of Go-MySQL-Driver for details.

time.Time support

The default internal output type of MySQL DATE and DATETIME values is []byte which allows you to scan the value into a []byte, string or sql.RawBytes variable in your program.

However, many want to scan MySQL DATE and DATETIME values into time.Time variables, which is the logical equivalent in Go to DATE and DATETIME in MySQL. You can do that by changing the internal output type from []byte to time.Time with the DSN parameter parseTime=true. You can set the default time.Time location with the loc DSN parameter.

Caution: As of Go 1.1, this makes time.Time the only variable type you can scan DATE and DATETIME values into. This breaks for example sql.RawBytes support.

Unicode support

Since version 1.5 Go-MySQL-Driver automatically uses the collation utf8mb4_general_ci by default.

Other charsets / collations can be set using the charset or collation DSN parameter.

  • When only the charset is specified, the SET NAMES <charset> query is sent and the server's default collation is used.
  • When both the charset and collation are specified, the SET NAMES <charset> COLLATE <collation> query is sent.
  • When only the collation is specified, the collation is specified in the protocol handshake and the SET NAMES query is not sent. This can save one roundtrip, but note that the server may ignore the specified collation silently and use the server's default charset/collation instead.

See http://dev.mysql.com/doc/refman/8.0/en/charset-unicode.html for more details on MySQL's Unicode support.

Testing / Development

To run the driver tests you may need to adjust the configuration. See the Testing Wiki-Page for details.

Go-MySQL-Driver is not feature-complete yet. Your help is very appreciated. If you want to contribute, you can work on an open issue or review a pull request.

See the Contribution Guidelines for details.


License

Go-MySQL-Driver is licensed under the Mozilla Public License Version 2.0

Mozilla summarizes the license scope as follows:

MPL: The copyleft applies to any files containing MPLed code.

That means:

  • You can use the unchanged source code both in private and commercially.
  • When distributing, you must publish the source code of any changed files licensed under the MPL 2.0 under a) the MPL 2.0 itself or b) a compatible license (e.g. GPL 3.0 or Apache License 2.0).
  • You needn't publish the source code of your library as long as the files licensed under the MPL 2.0 are unchanged.

Please read the MPL 2.0 FAQ if you have further questions regarding the license.

You can read the full terms here: LICENSE.

Go Gopher and MySQL Dolphin

mysql's People

Contributors

aaron42net avatar achille-roussel avatar arnehormann avatar arvenil avatar badoet avatar carrotman42 avatar chanxuehong avatar cuishuang avatar cxmcc avatar dolmen avatar dveeden avatar hyandell avatar joshuaprunier avatar julienschmidt avatar lukescott avatar methane avatar mherr-google avatar mjkwoolnough avatar moredure avatar pib avatar runrioter avatar s7v7nislands avatar scop avatar shogo82148 avatar sjmudd avatar thenikso avatar vmg avatar xiam avatar zihengcat avatar zjj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mysql's Issues

How to use Query of type mysqlConn ,but not of mysqlStmt?

Create a db from DNS String and run Query, like this

db, e := sql.Open("mysql", "root:@tcp(127.0.0.1:3306)/mysql?charset=utf8")
rows, e := db.Query("select * from test.tb")

I found the Query is the method of mysqlStmt, How can I use the Query of mysqlConn.

int64 -> *sql.RawBytes Scan error

Hi,

I use your driver in my https://github.com/hgfischer/mysqlsuperdump/ project and in the latest builds I'm getting this kind of error, when dumping a database at Amazon's RDS from a EC2 Ubuntu 12.10 64bits.

"panic: sql: Scan error on column index 0: unsupported driver -> Scan pair: int64 -> *sql.RawBytes"

The error comes after trying to select data from the following database structure:

CREATE TABLE `address_region` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `country_id` bigint(20) NOT NULL,
  `symbol` varchar(2) NOT NULL,
  `name` varchar(255) NOT NULL,
  `slug` varchar(255) DEFAULT NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `UNIQ_343B74C95E237E06F92F3E70` (`name`,`country_id`),
  UNIQUE KEY `UNIQ_343B74C9ECC836F9F92F3E70` (`symbol`,`country_id`),
  UNIQUE KEY `slug` (`slug`,`country_id`),
  KEY `IDX_343B74C9F92F3E70` (`country_id`),
  KEY `idx_name` (`name`),
  KEY `idx_slug` (`slug`),
  KEY `idx_symbol` (`symbol`),
  KEY `idx_created_at` (`created_at`),
  KEY `idx_updated_at` (`updated_at`),
  CONSTRAINT `FK_343B74C9F92F3E70` FOREIGN KEY (`country_id`) REFERENCES `country` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8;

With the following query:

SELECT id, country_id, symbol, name, slug, created_at, updated_at FROM `address_region`

And the stack trace from mysqlsuperdump is this:

goroutine 1 [running]:
main.checkError(0xf8400491e0, 0xf8400a57a0)
    /var/lib/jenkins/workspace/mysqlsuperdump/mysqlsuperdump.go:90 +0x4e
main.dumpTableData(0xf840049600, 0xf840074160, 0xf8400449c0, 0xf840073600, 0x10000000e, ...)
    /var/lib/jenkins/workspace/mysqlsuperdump/mysqlsuperdump.go:239 +0x6df
main.main()
    /var/lib/jenkins/workspace/mysqlsuperdump/mysqlsuperdump.go:81 +0x3d6

I don't think it's a problem with mysqlsuperdump, since I've not changed the code between your driver updates. If something changed in the driver and my code is doing it wrong, please let me know.

Doesn't handle user/pass incorrect or denied. (and possibly other errors) [moved]

This is Issue 18 moved from a Google Code project.
Added by 2012-12-01T11:52:38.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.
Closed (Invalid).

Original labels: Type-Defect, Priority-High

Original description

<b>Problem summary:</b>
2012/12/01 06:39:42 &{0xf840059078 kevin:wrongpass@tcp(192.168.0.100:3306)/mysql
{0 0} [] false}
2012/12/01 06:39:42 <nil>
[MySQL] 2012/12/01 06:39:42 packets:78 EOF
[MySQL] 2012/12/01 06:39:42 packets:78 EOF
[MySQL] 2012/12/01 06:39:42 packets:78 EOF
[MySQL] 2012/12/01 06:39:42 packets:78 EOF
[MySQL] 2012/12/01 06:39:42 packets:78 EOF
[MySQL] 2012/12/01 06:39:42 packets:78 EOF
[MySQL] 2012/12/01 06:39:42 packets:78 EOF
[MySQL] 2012/12/01 06:39:42 packets:78 EOF
[MySQL] 2012/12/01 06:39:42 packets:78 EOF
[MySQL] 2012/12/01 06:39:42 packets:78 EOF
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x50 pc=0x401281]

goroutine 1 [running]:
main.main()
        D:/programming/db.go:32 +0x281

goroutine 2 [syscall]:
created by runtime.main
        D:/dev/go/src/pkg/runtime/proc.c:225

goroutine 3 [syscall]:
syscall.Syscall6(0x774fa4d0, 0x5, 0x98, 0xf84004df00, 0xf840059208, ...)
        D:/dev/go/src/pkg/runtime/zsyscall_windows_windows_amd64.c:97 +0x55
syscall.GetQueuedCompletionStatus(0x98, 0xf84004df00, 0xf840059208, 0xf840059200
, 0xffffffff, ...)
        D:/dev/go/src/pkg/syscall/zsyscall_windows_amd64.go:506 +0x9f
net.(*resultSrv).Run(0xf840059108, 0x0)
        D:/dev/go/src/pkg/net/fd_windows.go:123 +0x97
created by net.startServer
        D:/dev/go/src/pkg/net/fd_windows.go:252 +0xfd
exit status 2

<b>Used go-mysql-version (e.g. May 26, 2012):</b>
May 30, 2012

<b>MySQL-Server version (e.g. MySQL-Server 5.5 or MariaDB 5.1):</b>
mysqld  Ver 5.1.66-0ubuntu0.11.10.2 for debian-linux-gnu on x86_64 ((Ubuntu))

<b>Used Operation System (e.g. Windows 7 64bit, Ubuntu 12.04 64bit, OS X</b>
<b>10.8):</b>
Ubuntu 12.04 64bit

<b>Example code which reproduces the error (optional):</b>

NULL float64 not working

I have downloaded the latest version of the driver with

go get github.com/Go-SQL-Driver/MySQL

I am not getting errors is I use sql.NullString when loading null values but I am still getting the error for sql.NullFloat64

sql: Scan error on column index 4: converting string "" to a float64: strconv.ParseFloat: parsing "": invalid syntax

Is there only support for null strings? or should this be working for null float64?

mc.exec is masking last insert id on insert statement [moved]

This is Issue 14 moved from a Google Code project.
Added by 2012-10-12T00:31:05.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.
Closed (Fixed).

Original labels: Type-Defect, Priority-High

Original description

<b>Problem summary:</b>

In connections.go mc.exec is masking the mc.insertId with 0.  To be more clear, I am running an Exec to insert into a table and getting errors while trying to read the LastInsertId() back on the a result set.  Unless I am mistaken, when doing an insert you should get a true result object back with a last insert id.  

Here is a suggested patch to fix the issue.


--- connection.go.orig  2012-10-11 18:19:59.000000000 -0600
+++ connection.go       2012-10-11 18:20:40.000000000 -0600
@@ -197,7 +197,7 @@
                return nil, e
        }

-       if mc.affectedRows == 0 {
+       if mc.affectedRows == 0 && mc.insertId == 0 {
                return driver.ResultNoRows, e
        }

@@ -222,7 +222,6 @@
        }

        mc.affectedRows = 0
-       mc.insertId = 0

        if resLen > 0 {
                _, e = mc.readUntilEOF()


PS.  Thanks for your code.  It has been a pleasure to work with your driver.


<b>Used go-mysql-version (e.g. May 26, 2012):</b>


MySQL-Server version: Custom Percona Build


Used Operation System (CenOS 5.8):


<b>Example code which reproduces the error (optional):</b>

Please see problem statement.  

DSN for create databases [moved]

This is Issue 22 moved from a Google Code project.
Added by 2013-01-05T09:28:30.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.
Closed (Duplicate).

Original labels: Type-Defect, Priority-Medium

Original description

<b>Problem summary:</b>

I want to create database, but I can't create a dsn without dbname

<b>Go-MySQL-Driver version (e.g. May 26, 2012):</b>


<b>MySQL-Server version (e.g. MySQL-Server 5.5 or MariaDB 5.1):</b>


<b>Operation System (e.g. Windows 7 64bit, Ubuntu 12.04 64bit, OS X</b>
<b>10.8):</b>


<b>Example code which reproduces the error (optional):</b>

driver fails to parse midnight timestamp (00:00:00) [moved]

This is Issue 5 moved from a Google Code project.
Added by 2012-05-30T12:21:24.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.
Closed (Fixed).

Original labels: Type-Defect, Priority-High, Usability, OpSys-All

Original description

<b>Problem summary:</b>
go-mysql-driver panics when trying to parse a datetime field that is timestamped at exactly midnight. Full stack trace attached and one solution to the problem mentioned below. (There might or might not be ways to fix it at lower level somewhere)

<b>Used go-mysql-version (e.g. May 26, 2012):</b>
May 26, 2012

<b>MySQL-Server version (e.g. MySQL-Server 5.5 or MariaDB 5.1):</b>
5.5.24 MySQL Community Server (GPL)

<b>Used Operation System (e.g. Windows 7 64bit, Ubuntu 12.04 64bit):</b>
Windows 7 64bit

<b>Example code which reproduces the error (optional):</b>
rows, err := db.Query(&quot;SELECT updated_at FROM table&quot;)
when the content of that datetime field in any of the returned rows is: 2010-04-29 00:00:00

Fix:
So.. might not be the best way, but one way to fix this is by changing the switch case from readBinaryRows in packets.go like this:

diff -r 787b14074e0f mysql/packets.go
--- a/mysql/packets.go  Sat May 26 17:50:45 2012 +0200
+++ b/mysql/packets.go  Wed May 30 13:11:16 2012 +0100
@@ -989,13 +989,20 @@
                                if num == 0 {
                                        row[i] = []byte(&quot;0000-00-00 00:00:00&quot;)
                                } else {
+                                       var timestampdata []byte
+                                       if len(data) < pos+7 {
+                                               timestampdata = make([]byte, pos+7)
+                                               copy(timestampdata, data)
+                                       } else {
+                                               timestampdata = data
+                                       }
                                        row[i] = []byte(fmt.Sprintf(&quot;%04d-%02d-%02d %02d:%02d:%02d&quot;,
-                                               bytesToUint16(data[pos:pos+2]),
-                                               data[pos+2],
-                                               data[pos+3],
-                                               data[pos+4],
-                                               data[pos+5],
-                                               data[pos+6]))
+                                               bytesToUint16(timestampdata[pos:pos+2]),
+                                               timestampdata[pos+2],
+                                               timestampdata[pos+3],
+                                               timestampdata[pos+4],
+                                               timestampdata[pos+5],
+                                               timestampdata[pos+6]))
                                }
                                pos += int(num)

Add strict mode - Treating warnings as errors

Go doesn't offer a way to see if the statement produced warnings (as far as I know). I thought about some way to access it but it doesn't seem possible through standard database/sql.

Could we have a setting that treats warnings as errors? This would be something I'd enable in development to help avoid writing code that may cause problems. The driver would need to check for warnings after every statement. This data is transmitted in the protocol; it doesn't require a SHOW WARNINGS statement. If there are warnings, a SHOW WARNINGS LIMIT 1 would get the first one, and the driver could return something like "statement caused $N warnings: $first_warning".

Thoughts?

bug: mysql 5.5.9-log version func Query&Prepare return Malformed Packet

hi,

I used this code to visit mysql. However, when vising mysql 5.5.9-log version,
Query & Prepare function will return "Malformed Packet"

And, they all run successfully on other version of mysql.

mysqlConf: ssss:ssss@tcp(11.11.11.11:3306)/ssss?charset=utf8

How i use:

    categoryDB, err := sql.Open("mysql", categoryDBConf)
    if err != nil {
        fmt.Printf("%v\n", err)
    }
    defer categoryDB.Close()
    rows, err := categoryDB.Query(`select 1`)
    if err != nil {
        fmt.Printf("%v\n", err)
    }

Please support more kinds of Exec() and Scan() data types [moved]

This is Issue 11 moved from a Google Code project.
Added by 2012-08-20T10:38:39.000Z by julian.morrison.
Please review that bug for more context and additional comments, but update this bug.
Closed (Duplicate).

Original labels: Type-Enhancement, Priority-Medium

Original description

In particular time.Time for all the time and date types, big.Rat for all the fixnum types, and unsigned numbers all the way up to uint64. (We are having to work around this by using strings.)

Suggestion: use 'git flow' and work in another branch, instead of master. Leave master for latest releases.

Hi,

The fact that "go get" does not handle versioning, is a problem for most of Go projects. So, to avoid breaking dependencies, I suggest using "git flow" (there's a package in macports and ubuntu) with default settings (master/develop/feature/hotfix) in this project. This makes your master point to the lates tagget release or hotfix, that will probably be a more stable interface.

thanks

why Prepare function Sleep ? [moved]

This is Issue 17 moved from a Google Code project.
Added by 2012-11-21T11:21:16.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.
Closed (Invalid).

Original labels: Type-Review, Priority-High

Original description

file: connection.go
117 time.Sleep(diff)

when I use many mysql tables, this will sleep #number_of_table seconds.

Row full of garbage returned when a query uses max() on an empty table [moved]

This is Issue 12 moved from a Google Code project.
Added by 2012-08-23T10:06:17.000Z by julian.morrison.
Please review that bug for more context and additional comments, but update this bug.

Original labels: Type-Defect, Priority-Medium

Original description

<b>Problem summary:</b>
Query of &quot;select max(id) from foo&quot; returns a row even when the foo table is empty (rows.Next() returns true, QueryRows().Scan() doesn't return sql.ErrNoRows). The row's column has a value of &quot;&quot; which breaks the Scan() into a uint64. It ought to return no rows.

<b>Used go-mysql-version (e.g. May 26, 2012):</b>
May 30, 2012

<b>MySQL-Server version (e.g. MySQL-Server 5.5 or MariaDB 5.1):</b>
MySQL-Server 5.5.24

<b>Used Operation System (e.g. Windows 7 64bit, Ubuntu 12.04 64bit):</b>
Ubuntu 12.04 32bit

Support "load data local infile", if possible with a Reader instead of a file

I'm using the driver in a backup program.
The restore part could really profit from "load data local infile" support, which would be even better if I can feed it from a Reader (so I can convert from a binary format to the required CSV format on the fly).

Please treat this as an enhancement request, I don't mind the support if it's only based on the local filesystem (which is the case for every other mysql connector I checked so far).

NULL results are not returned properly [moved]

This is Issue 20 moved from a Google Code project.
Added by 2012-12-18T21:28:10.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.

Original labels: Type-Defect, Priority-High

Original description

Currently the driver returns an empty []byte slice instead of nil

improve error reporting for unpreparable statements

This is a low-priority TODO, I'd like to wait until Brad's changes are in.

I got bitten by statments which can not be prepared. See MySQL documentation: SQL Syntax Allowed in Prepared Statements.
We should probably report errors in statments.go:Query(...) with len(args) > 0 if stmt.paramCount == 0 as an error caused by using prepared statements, right now it's a little confusing without background knowledge.
Currently, the error looks like sql: statement expects 0 inputs; got 1.
While checking this, I also spotted a missing closing brace in an error in packets.go.
I hit this while trying to use

SHOW TABLES FROM `?`

which should be a legitimate way to explore the databases and tables on a server.

Feature request: add streaming mode [moved]

This is Issue 10 moved from a Google Code project.
Added by 2012-08-03T15:01:57.000Z by julian.morrison.
Please review that bug for more context and additional comments, but update this bug.

Original labels: Type-Enhancement, Priority-Medium, OpSys-All

Original description

Please add the ability to use streaming mode, like this http://dev.mysql.com/doc/refman/5.0/en/mysql-use-result.html so that rows.Next() actually fetches the next row, rather than slicing an in-memory list of rows.

The company I work for has a use case where we want to read very large result sets that would be too large to fit in memory at once. (Right now we can do that by fetching the Id column only, and then reading blocks of results with new queries, but that's inefficient.)

Probably, this should be a parameter in the DSN.

Can't Connect to Any MySQL Server

I downloaded the most recent version of the MySQL driver and I cannot get it to connect to any databases. I've tried using a DSN for both socket and tcp connections.

Add Scan() support for time.Time

This is Issue 9 moved from a Google Code project.
Added by 2012-07-31T17:38:51.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.

Original labels: Type-Enhancement, Priority-Medium

Original description

<b>Problem summary:</b>

A table that has datetime fields can't be read as time.Time using Scan() 

<b>Used go-mysql-version (e.g. May 26, 2012):</b>

latest

<b>MySQL-Server version (e.g. MySQL-Server 5.5 or MariaDB 5.1):</b>

Server version: 5.1.37 MySQL Community Server (GPL)

Golang: 1.0.2

<b>Used Operation System (e.g. Windows 7 64bit, Ubuntu 12.04 64bit):</b>

OSX Mountain Lion

<b>Example code which reproduces the error (optional):</b>

Test case here: https://gist.github.com/3218753

Thread safe

I have the problem it opens many connections before closing them.

It should have a pool with max connection and never be able to get pass that. As i run the code, and gets the error with to many connections.

golang 1.0.2 error. Invalid Result Packet-Type [moved]

This is Issue 8 moved from a Google Code project.
Added by 2012-07-02T07:08:30.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.
Closed (Fixed).

Original labels: Type-Defect, Priority-Medium

Original description

<b>Problem summary:</b>


<b>Used go-mysql-version (e.g. May 26, 2012):</b>
 MySQL-Server 5.1 Windows 7 64bit 
Use golang 1.0.2 

error:

panic: runtime error: invalid memory address or nil pointer dereference

[signal 0xc0000005 code=0x0 addr=0x30 pc=0x42b004]
goroutine 1 [running]:
database/sql.(*Rows).Next(0x0, 0x100000001, 0x6572656800000006, 0x0)
.....

rows is :

Invalid Result Packet-Type

Queries opens new connections everytime

Hello Julien,

I ran into an issue today, I was trying to import a very big dataset into a MySQL table using your driver, it successfully inserted some items but then the server just killed the connection. I tracked the problem down, not sure about the cause but it seems that Go-SQL-Driver/MySQL is opening a connection each time it makes a query instead of using the previously opened one.

Steps to reproduce:

1 - Set max_connections to a low number, like 10, in my.cnf

2 - Reset MySQL

# systemctl restart mysqld

3 - Check active connections (2)

mysql -uroot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2

4 - Run this program that would normally execute 100 simple queries.

package main

import (
  "database/sql"
  _ "github.com/Go-SQL-Driver/MySQL"
)

func main() {
  db, err := sql.Open("mysql", "root:@/gotest?charset=utf8")

  if err != nil {
    panic(err)
  }

  defer db.Close()

  for i := 0; i < 100; i++ {
    _, err = db.Query("SELECT NOW()")
    if err != nil {
      panic(err)
    }   
  }
}

5 - Watch the client dying:

[MySQL] 2013/02/13 15:55:58 packets:80 EOF
[MySQL] 2013/02/13 15:55:58 packets:80 EOF
[MySQL] 2013/02/13 15:55:58 packets:80 EOF
[MySQL] 2013/02/13 15:55:58 packets:80 EOF
[MySQL] 2013/02/13 15:55:58 packets:80 EOF
[MySQL] 2013/02/13 15:55:58 packets:80 EOF
[MySQL] 2013/02/13 15:55:58 packets:80 EOF
[MySQL] 2013/02/13 15:55:58 packets:80 EOF
[MySQL] 2013/02/13 15:55:58 packets:80 EOF
panic: driver: bad connection

goroutine 1 [running]:
main.main()
    /home/xiam/gomysqlbug.go:20 +0x13b

goroutine 2 [syscall]:
created by runtime.main
    /usr/lib/go/src/pkg/runtime/proc.c:221

goroutine 3 [syscall]:
syscall.Syscall6()
    /usr/lib/go/src/pkg/syscall/asm_linux_amd64.s:40 +0x5
syscall.EpollWait(0xf800000006, 0xf84007b0c0, 0xa0000000a, 0xffffffff, 0xc, ...)
    /usr/lib/go/src/pkg/syscall/zerrors_linux_amd64.go:1846 +0xa1
net.(*pollster).WaitFD(0xf84007b0b0, 0xf840041980, 0x0, 0x0, 0x0, ...)
    /usr/lib/go/src/pkg/net/fd_linux.go:146 +0x110
net.(*pollServer).Run(0xf840041980, 0x0)
    /usr/lib/go/src/pkg/net/fd.go:236 +0xe4
created by net.newPollServer
    /usr/lib/go/src/pkg/net/newpollserver.go:35 +0x382
exit status 2

6 - Check active connections (it opened exactly 10, plus the current one)

mysql -uroot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 13

Another way to reproduce:

# Going to the projects directory
$ cd $GOPATH/src/github.com/Go-SQL-Driver/MySQL

# Checking connection ID (2)
$ mysql -uroot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
...
^C

# Executing tests
$ go test
PASS
ok      github.com/Go-SQL-Driver/MySQL  5.066s

# Check connections again, are we really using 29 connections?
$ mysql -uroot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 31
...

Hope it helps.

Regards,

José Carlos

DATETIME type cannot be scanned as time.Time [moved]

This is Issue 19 moved from a Google Code project.
Added by 2012-12-08T04:37:11.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.
Closed (Duplicate).

Original labels: Type-Defect, Priority-Medium

Original description

<b>Problem summary:</b>

  column index 3 is a field of DATETIME type, and here goes the error while calling rows.Scan()

    `sql: Scan error on column index 3: unsupported driver -> Scan pair: []uint8 -> *time.Time`

  Note that this driver works (https://github.com/ziutek/mymysql ) without any problem.

<b>Used go-mysql-version (e.g. May 26, 2012):</b>

  Oct. 30 2012

<b>MySQL-Server version (e.g. MySQL-Server 5.5 or MariaDB 5.1):</b>

  5.5.28-0

<b>Used Operation System (e.g. Windows 7 64bit, Ubuntu 12.04 64bit, OS X</b>
<b>10.8):</b>

  ubuntu0.12.04.2

<b>Example code which reproduces the error (optional):</b>

Regression in handling of `DATE`?

There appears to be a regression in the handling of DATE values:

db-val: 2012-06-14
old-val: 2012-06-14
new-val: 56324-07-06

DATETIME continues to work as expected

edit I new refers to current master, old refers to code.google.com/p/go-mysql-driver/mysql

Queries need Performance Optimization [moved]

This is Issue 4 moved from a Google Code project.
Added by 2012-05-25T02:25:57.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.
Closed (Fixed).

Original labels: Type-Task, Priority-Critical, Performance

Original description

In the current beta release Queries are conspicuously slow.
There seems to be a slow part somewhere at either fetching the result or at converting the result.

Some profiling and performance optimization is necessary here.

Transaction Rollback

I'm very impressed with this package from the testing that I've done thus far. It appears to be very fast. Testing is in early stages. I'm currently testing in Windows and haven't tried it with Linux yet. I use a deferred function for Transaction Rollback. I'm not sure if it's possible for application program to test for "inTransaction". I would prefer to be able to test if there is an active transaction in the Transaction object, rather than rely on the application program to set a flag. It's better IMHO to use inherent data than to set flags - just one more possible error (bug). Alternatively, as a second choice, I would prefer that Rollback did not return an error where there is no active transaction. Another possible better solution (if possible) would be to set Tx to nil when either Commit or Rollback completed, because as far as I can see, Tx cannot be "used" after that. Although this is a minor complaint, it would be good IMHO if you could look at it. I see from the Golang documentation that any call to Tx after a Commit or Rollback returns ErrTxDone. Perhaps that is an argument to set Tx to nil (if possible). My preference would be to set Tx to nil.

[Feature request] Support for charset utfmb4 with utf8 as fallback

MySQL's utf8 is not really utf8 and it's advisable to replace it with utf8mb4, if the server supports it (MySQL 5.5.3+).

Ideally, you could set it in the DSN and fall back to utf8 for older versions. I see four ways to get there:

My preferred way would be to specify charset twice in the connection string (first set it to utf8, then to utf8mb4 - if the second one fails we still at least have utf8), but params is a map and can only contain one charset. If it's converted to an array of of [2]string (or a key - value struct), this would be possible. This should also be highlighted/advised in the documentation.

Next, the client could ask the server for the supported charsets and automatically downgrade utf8mb4 to utf8 if it's not available.

A (nasty) workaround and the way no change to the code is required would be to set a charset twice (one time ending in or beginning with a space) and set the one first encountered by range mc.cfg.params to utf8 and the second one to utf8mb4. Your code sees it as two different parameters, but for MySQL both are the same. I dislike it as it's clumsy and fragile - it depends on the way in which map and the driver are implemented.

Last, you could provide a Register function like mymysql.

I'll try to help out with a pull-request if you want, I just want to know if you're interested in this and which way you'd prefer beforehand.

MySQL 4.1.21 EOF error [moved]

This is Issue 13 moved from a Google Code project.
Added by 2012-09-27T21:15:48.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.
Closed (WontFix).

Original labels: Type-Defect, Priority-Medium

Original description

<b>Problem summary:</b>
Any query that has an expected return (i.e. SELECT, SHOW, etc.) returns an EOF error on *sql.DB.Query() or *sql.DB.QueryRow(). CREATE TABLE and DROP TABLE work fine. Nonsense queries (e.g. on non-existant tables) and incorrect credentials generate the expected errors, so connecting to the DB isn't the problem.

Everything works fine on MySQL 5.0+

Used go-mysql-version (e.g. May 26, 2012):May 30, 2012


<b>MySQL-Server version (e.g. MySQL-Server 5.5 or MariaDB 5.1):</b>
MySQL-Server 4.1.21

<b>Used Operation System (e.g. Windows 7 64bit, Ubuntu 12.04 64bit):</b>
Server: CentOS 5.1, Client: OS X 10.8.2

<b>Example code which reproduces the error (optional):</b>

func main() {
    dbs, err := sharddbs.GetDBs()
    if err != nil {
        panic(err)
    }
    for _, db := range dbs {
        row := db.QueryRow(&quot;SHOW TABLES&quot;)
        var result string
        err = row.Scan(&result)
        if err != nil {
            panic(err) //panic happens here
        }
        fmt.Println(result)
    }
}

Stack trace:
panic: EOF

goroutine 1 [running]:
main.main()
    /Users/tamird/dev/go/src/15852/15852.go:18 +0x22c
----- stack segment boundary -----

goroutine 2 [syscall]:
created by runtime.main
    /usr/local/Cellar/go/1.0.3/src/pkg/runtime/proc.c:221

goroutine 3 [syscall]:
syscall.Syscall6()
    /usr/local/Cellar/go/1.0.3/src/pkg/syscall/asm_darwin_amd64.s:38 +0x5
syscall.kevent(0x14, 0x0, 0x0, 0xf84006d188, 0xa, ...)
    /usr/local/Cellar/go/1.0.3/src/pkg/syscall/zsyscall_darwin_amd64.go:199 +0x88
syscall.Kevent(0xf800000014, 0x0, 0x0, 0xf84006d188, 0xa0000000a, ...)
    /usr/local/Cellar/go/1.0.3/src/pkg/syscall/syscall_bsd.go:546 +0xa4
net.(*pollster).WaitFD(0xf84006d180, 0xf84008aac0, 0x0, 0x0, 0x0, ...)
    /usr/local/Cellar/go/1.0.3/src/pkg/net/fd_darwin.go:96 +0x185
net.(*pollServer).Run(0xf84008aac0, 0x0)
    /usr/local/Cellar/go/1.0.3/src/pkg/net/fd.go:236 +0xe4
created by net.newPollServer
    /usr/local/Cellar/go/1.0.3/src/pkg/net/newpollserver.go:35 +0x382
exit status 2

db.Open does not fail when there is no server [moved]

This is Issue 7 moved from a Google Code project.
Added by 2012-06-23T21:09:10.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.
Closed (WontFix).

Original labels: Type-Defect, Priority-High, OpSys-OSX

Original description

<b>Problem summary:</b>

Not sure if this is something particular to my system or if I am using the driver incorrectly, but when I call something similar to the following code with the mysql server shut off, it does not return an err:

    import (
        &quot;log&quot;
    &quot;database/sql&quot;
    _ &quot;code.google.com/p/go-mysql-driver/mysql&quot;
    )

    var database *sql.DB
    func main() {
        db, err := sql.Open(&quot;mysql&quot;, dsn)
        if err != nil {
            log.Fatal(&quot;Could not connect to:&quot;, k)
        }
        database = db
                // database later is accessed by various goroutines
                doMuchWorkHere()
   }

I am running the mysql server locally. Dsn similar to &quot;user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8&keepalive=1&quot;

I considered using db.Driver() to get the underlying driver and maybe using mc.Ping myself to test, but the documentation for database/sql seems to imply that Open would return a failure on setup if the server could not be contacted.

I thought maybe it was due to net.Dial being used instead of net.DialTimeout, but I am not sure.

Am I using the driver wrongly by expecting open to return an error if the server is down or it cannot be contacted?

Used go-mysql-version:
  changeset:   27:2c2c693701e6
  tag:         tip
  user:        Julien Schmidt
  date:        Wed May 30 16:00:01 2012 +0200

MySQL-Server version: mysql 5.5.25
Used Operation System: osx 10.7.4
Go version: go version go1.0.2

Query has unexpected behavior on linux_amd64

Steps:

db, err := sql.Open(
    "mysql",
    fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", user, pass, host, port, name),
)
if err != nil { panic(err) }

var i int
err = db.QueryRow("SELECT 1 FROM DUAL").Scan(&i)
if err != nil { panic(err) }

Everything works great here. Then I try to actually use it for a different query.

var thing string
err = db.QueryRow("SELECT thing FROM place WHERE id = ?", id).Scan(&thing)
if err != nil { panic(err) }

This reliably panics with one of the two "Commands out of sync" errors, but ONLY on linux_amd64. It works fine on darwin_amd64.

Any insight appreciated.

More informative error messages [moved]

This is Issue 1 moved from a Google Code project.
Added by 2012-05-14T12:46:58.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.
Closed (Fixed).

Original labels: Type-Enhancement, Priority-High, OpSys-All

Original description

<b>What steps will reproduce the problem?</b>
1. In query example at 

http://goseeds.blogspot.com/2012/05/google-go-and-mysql-tutorial.html
2. duplicate the row up to 500 row in my_db.document table on mysql server.

<b>What is the expected output? What do you see instead?</b>

3.  set the query return row limit from 10 to 410, the program runs ok. last line of output is &quot;Total: 410&quot;.
4. set the query return row limit from 10 to 500, the program die of &quot;driver: bad connection&quot;.

<b>What version of the product are you using? On what operating system?</b>
go version 1.0.1
mysql server 5.0.81

<b>Please provide any additional information below.</b>

Can't Scan a MySQL datetime to a time.Time

mysql> DESCRIBE foo;
+----------------+--------------+------+-----+-----------+----------------+
| Field          | Type         | Null | Key | Default   | Extra          |
+----------------+--------------+------+-----+-----------+----------------+
  ...
| created_at     | datetime     | YES  | MUL | NULL      |                |
  ...
type MyFoo struct {
    ...
    CreatedAt   time.Time
    ...
}
    rows, err := db.Query(
        `
        SELECT
          ...
            foo.created_at,
          ...
        FROM foo
        WHERE ...
        `,
    )

    err := rows.Scan(
        ...
        &myFoo.CreatedAt,
        ...
sql: Scan error on column index 3: unsupported driver -> Scan pair: []uint8 -> *time.Time

When the DB connection is bad, it is not reaped and reconnected, but continues giving errors [moved]

This is Issue 15 moved from a Google Code project.
Added by 2012-10-17T14:23:23.000Z by julian.morrison.
Please review that bug for more context and additional comments, but update this bug.
Closed (Duplicate).

Original labels: Type-Defect, Priority-Medium

Original description

<b>Problem summary:</b>
I had a &quot;too many open connections&quot; error on MySQL. The sql.DB connections I had open started giving errors like

    [MySQL] 2012/10/17 15:12:58 packets:102 write tcp 127.0.0.1:3306: broken pipe

They did not reconnect.

<b>Used go-mysql-version (e.g. May 26, 2012):</b>
May 30, 2012

<b>MySQL-Server version (e.g. MySQL-Server 5.5 or MariaDB 5.1):</b>
MySQL-Server 5.5.24

<b>Used Operation System (e.g. Windows 7 64bit, Ubuntu 12.04 64bit):</b>
Ubuntu 12.04 32bit

DB.Exec() always returns "no RowsAffected available after DDL statement". [moved]

This is Issue 16 moved from a Google Code project.
Added by 2012-10-28T06:12:01.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.
Closed (Fixed).

Original labels: Type-Defect, Priority-Critical

Original description

<b>Problem summary:</b>
DB.Exec() always returns &quot;no RowsAffected available after DDL statement&quot; even if it affected some rows indeed.

<b>Used go-mysql-version (e.g. May 26, 2012):</b>
May 30, 2012


<b>MySQL-Server version (e.g. MySQL-Server 5.5 or MariaDB 5.1):</b>
mysql  Ver 14.14 Distrib 5.5.24, for osx10.6 (i386) using readline 5.1


<b>Used Operation System (e.g. Windows 7 64bit, Ubuntu 12.04 64bit):</b>
Mac OS X 10.7.5



<b>Example code which reproduces the error (optional):</b>

// 1. Make sure the Test table in MyDatabase has a row with id 1.
// 2. Run the following code with go(version go1.0.3).

package main

import (
    &quot;fmt&quot;
    &quot;database/sql&quot;
    _ &quot;code.google.com/p/go-mysql-driver/mysql&quot;
    )

func main() {
    db, err := sql.Open(&quot;mysql&quot;, &quot;root:password@/MyDatabase?charset=utf8&quot;)
    if err != nil {
        panic(err)
    }

    if result, err := db.Exec(&quot;delete from Test where id=1&quot;); err != nil {
        panic(err)
    } else {
        fmt.Printf(&quot;result=%#v\n&quot;, result)
        if affected, err := result.RowsAffected(); err != nil {
            fmt.Println(err)
        } else {
            fmt.Printf(&quot;Deleted %v rows.\n&quot;, affected)
        }
    }
}

Password with @ inside cannot be parse [moved]

This is Issue 3 moved from a Google Code project.
Added by 2012-05-21T08:18:58.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.
Closed (Invalid).

Original labels: Type-Defect, Priority-Medium

Original description

<b>What steps will reproduce the problem?</b>
1. if the password has '@' inside, the DSN cannot be parsed correctly
<b>2.</b>
<b>3.</b>

<b>What is the expected output? What do you see instead?</b>


<b>What version of the product are you using? On what operating system?</b>


<b>Please provide any additional information below.</b>
@ is used to separate password and address. However, if the password itself has '@', the DSN cannot be parsed correctly.

*sql.RawBytes support

Hello Julien,

In previous revisions using *sql.RawBytes in Scan() worked perfectly, but now it looks like even the wiki example does not work anymore.

According to my tests, the last revision that supported *sql.RawBytes was a8a04cc28d45f986dbb9c4c2e76e805bf7b17787, but since 13d97656dab643725f7f2f6509dfab3763e44d6a it fails with the well known error:

panic: sql: Scan error on column index 0: unsupported driver -> Scan pair: uint64 -> *sql.RawBytes

Here is the full example I am using:

package main

import (
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
)

func main() {

    db, err := sql.Open("mysql", "gotest:gopass@unix(/var/run/mysqld/mysqld.sock)/gotest")

    if err != nil {
        fmt.Println(err)
        return
    }
    defer db.Close()

    sqls := []string{
        "drop table if exists foo",
        "create table foo (id bigint(20) unsigned not null auto_increment, primary key(id), name text)",
        "delete from foo",
    }
    for _, sql := range sqls {
        _, err = db.Exec(sql)
        if err != nil {
            fmt.Printf("%q: %s\n", err, sql)
            return
        }
    }

    for i := 0; i < 5; i++ {
        db.Exec(`INSERT INTO foo (name) VALUES ('Hello')`)
    }

    rows, err := db.Query(`SELECT * from foo`)

    // Get column names
    columns, err := rows.Columns()
    if err != nil {
        panic(err.Error())
    }

    // Make a slice for the values
    values := make([]sql.RawBytes, len(columns))

    // rows.Scan wants '[]interface{}' as an argument, so we must copy the
    // references into such a slice
    // See http://code.google.com/p/go-wiki/wiki/InterfaceSlice for details
    scanArgs := make([]interface{}, len(values))
    for i := range values {
        scanArgs[i] = &values[i]
    }

    // Fetch rows
    for rows.Next() {
        // get RawBytes from data
        err = rows.Scan(scanArgs...)
        if err != nil {
            panic(err.Error())
        }

        // Now do something with the data.
        // Here we just print each column as a string.
        var value string
        for i, col := range values {
            // Here we can check if the value is nil (NULL value)
            if col == nil {
                value = "NULL"
            } else {
                value = string(col)
            }
            fmt.Println(columns[i], ": ", value)
        }
        fmt.Println("-----------------------------------")
    }

}

I assume this *sql.RawBytes must be a pain to support and that's why practically all sql drivers seem to have issues with it but do you think it could be worked around again without removing features from your package? is there any alternative to get a plain []byte stream or *sql.RawBytes instead of an automatic conversion?

Thanks,

Carlos

parseDSN:if password include `@`,this would work well?

when i view the source code,i found the problem that if password include @,do parseDSN function will work well?
such as remotetest:!@#111111@tcp(8.8.8.8)/xxxx/?xxx,this example password is !@#111111, the parseDSN will match password as ! or !@#111111.if the match password is not !@#111111, may be that problem is a bug.
I'm sorry my english is so bad~

Impossible to connect without specifying database [moved]

This is Issue 21 moved from a Google Code project.
Added by 2012-12-31T14:55:22.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.

Original labels: Type-Defect, Priority-Medium

Original description

The DSN scheme requires you to specify a database to connect to. But it is perfectly valid (in general MySQL usage) to connect without specifying a database.

Broken Pipe [moved]

This is Issue 6 moved from a Google Code project.
Added by 2012-06-21T16:02:00.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.
Closed (WontFix).

Original labels: Type-Defect, Priority-Medium

Original description

<b>Problem summary:</b>

After some inactivity I get the following error:

2012-06-21_12:53:05.71328 [MySQL] 2012/06/21 12:53:05 packets:102 write unix /var/run/mysqld/mysqld.sock: broken pipe

<b>Used go-mysql-version (e.g. May 26, 2012):</b>

latest 

<b>MySQL-Server version (e.g. MySQL-Server 5.5 or MariaDB 5.1):</b>

Server version: 5.1.63-rel13.4 (Percona Server (GPL), 13.4, Revision 443)

<b>Used Operation System (e.g. Windows 7 64bit, Ubuntu 12.04 64bit):</b>

Linux go-playground 2.6.32-344-ec2 #46-Ubuntu SMP Wed Mar 7 13:47:05 UTC 2012 x86_64 GNU/Linux

<b>Example code which reproduces the error (optional):</b>

I connect to the database through unix socket, dsn is roughly: 

login:pass@unix(/var/run/mysqld/mysqld.sock)/stats?charset=utf8

After a short while all 10 connections are in broken pipe mode and will never be reconnected. 

undefined: driver.ErrBadConn

D:\>go get github.com/go-sql-driver/mysql
# github.com/go-sql-driver/mysql
go\src\github.com\go-sql-driver\mysql\infile.go:102: undefined: driver.ErrBadConn
go\src\github.com\go-sql-driver\mysql\infile.go:115: undefined: driver.ErrBadConn
go\src\github.com\go-sql-driver\mysql\packets.go:33: undefined: driver.ErrBadConn
go\src\github.com\go-sql-driver\mysql\packets.go:41: undefined: driver.ErrBadConn
go\src\github.com\go-sql-driver\mysql\packets.go:70: undefined: driver.ErrBadConn
go\src\github.com\go-sql-driver\mysql\packets.go:90: undefined: driver.ErrBadConn
go\src\github.com\go-sql-driver\mysql\packets.go:125: undefined: driver.ErrBadConn

D:\>

Query may fail on Windows (driver: bad connection) [moved]

This is Issue 2 moved from a Google Code project.
Added by 2012-05-21T08:15:55.000Z by [email protected].
Please review that bug for more context and additional comments, but update this bug.
Closed (Fixed).

Original labels: Type-Defect, Priority-High, OpSys-Windows

Original description

<b>What steps will reproduce the problem?</b>
1. on Windows
2. Query
<b>3.</b>

<b>What is the expected output? What do you see instead?</b>
expected output: success
actual output: driver: bad connection



<b>What version of the product are you using? On what operating system?</b>


<b>Please provide any additional information below.</b>
Suggested fix:
line 52 of packets.go
    n, e := mc.netconn.Read(data)
    if e != nil || n != int(pktLen) {
        e = driver.ErrBadConn
    }
Here, we assume Read only return when the data is filled. But at least on Go Windows version, it will return prematurely.

So maybe we can change the code to
   n, e := mc.netconn.Read(data)
   na := 0
   for e == nil && n < int(pktLen) {
       na, e = mc.netconn.Read(data[n:])
       n += na
   }

I've verified it on Windows, it works.     

runtime error: slice bounds out of range in packets.go

Trying to ApacheBench test a basic page created with Go, and I get this error:

2013/03/05 23:27:03 http: panic serving ipaddress:58369: runtime error: slice bounds out of range
/usr/local/go/src/pkg/net/http/server.go:589 (0x43eb1b)
        _func_004: buf.Write(debug.Stack())
/usr/local/go/src/pkg/runtime/proc.c:1443 (0x410aab)
        panic: reflect·call(d->fn, d->args, d->siz);
/usr/local/go/src/pkg/runtime/runtime.c:128 (0x411577)
        panicstring: runtime·panic(err);
/usr/local/go/src/pkg/runtime/runtime.c:91 (0x411448)
        panicslice: runtime·panicstring("slice bounds out of range");
/usr/local/go/src/pkg/github.com/Go-SQL-Driver/MySQL/packets.go:133 (0x44b2a6)
        com/Go-SQL-Driver/MySQL.(*mysqlConn).readInitPacket: mc.cipher = append(mc.cipher, data[pos:pos+12]...)
/usr/local/go/src/pkg/github.com/Go-SQL-Driver/MySQL/driver.go:46 (0x44a38a)
        com/Go-SQL-Driver/MySQL.(*mysqlDriver).Open: err = mc.readInitPacket()
/usr/local/go/src/pkg/database/sql/sql.go:248 (0x4435bd)
        (*DB).conn: return db.driver.Open(db.dsn)
/usr/local/go/src/pkg/database/sql/sql.go:310 (0x443b10)
        (*DB).prepare: ci, err := db.conn()
/usr/local/go/src/pkg/database/sql/sql.go:295 (0x443a33)
        (*DB).Prepare: stmt, err = db.prepare(query)
/usr/local/go/src/pkg/database/sql/sql.go:380 (0x444493)
        (*DB).Query: stmt, err := db.Prepare(query)
/myfolder/test.go:13 (0x400cd0)
        wwwHandler: result, e := db.Query("SELECT * FROM s WHERE sid=?",sid)
/myfolder/test.go:35 (0x401406)
        _func_001: wwwHandler(w, r, db)
/usr/local/go/src/pkg/net/http/server.go:703 (0x432964)
        HandlerFunc.ServeHTTP: f(w, r)
/usr/local/go/src/pkg/net/http/server.go:941 (0x4337b8)
        (*ServeMux).ServeHTTP: mux.handler(r).ServeHTTP(w, r)
/usr/local/go/src/pkg/net/http/server.go:669 (0x432777)
        (*conn).serve: handler.ServeHTTP(w, w.req)
/usr/local/go/src/pkg/runtime/proc.c:271 (0x40ebb1)
        goexit: runtime·goexit(void)

Here's my code:

package main

import (
    "fmt"
    "net/http"
    "database/sql"
    _ "github.com/Go-SQL-Driver/MySQL"
)

func wwwHandler(w http.ResponseWriter, r *http.Request, db *sql.DB) {
    for i := 0; i < 10; i++ {
        sid := 1
        result, e := db.Query("SELECT * FROM s WHERE sid=?",sid)
        if e != nil {
            panic(e.Error())
        }
        result.Next()
        var resultsid, created, posted, title, above_the_fold, below_the_fold sql.NullString
        var draft_or_final bool
        err := result.Scan(&resultsid,&created,&posted,&title,&above_the_fold,&below_the_fold,&draft_or_final)
        if err != nil {
            panic(err.Error())
        }
        fmt.Fprintf(w, "%s%s%s%s%s",resultsid.String,created.String,title.String,above_the_fold.String,below_the_fold.String)   
    }
}

func main() {
    db, e := sql.Open("mysql", "username:password@/dbname")
    if e != nil {
        panic(e.Error())
    }   
    defer db.Close()
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        wwwHandler(w, r, db)
    })  
    http.ListenAndServe(":80",nil)  
}

Can't scan a null into a *string

I used to use the code from Google Code. After updating to the latest code in master, I'm getting the following error I didn't get previously:

sql: Scan error on column index 7: unsupported driver -> Scan pair: <nil> -> *string

I will investigate more, but perhaps in the meantime you know something about this already?

BenchMark result

I wrote a benchmark test program to test this driver, but the test result is not good.

Only 500 querys pre second,
mysqlslap can process 5000 querys pre second in same machine.

I checked the mysql log
mysqlslap's logs:

130218 17:19:05
1002 Connect     [email protected] on
1003 Connect     [email protected] on test
1003 Query       SELECT * FROM users WHERE id = '00000'
1003 Query       SELECT * FROM users WHERE id = '00001'
....
1003 Query       SELECT * FROM users WHERE id = '00999'
1003 Quit

Go-MySQL-Driver's logs:

130218 17:18:32
2 Connect     [email protected] on test
2 Query       SET NAMES utf8
2 Prepare     [1] SELECT * FROM users WHERE id = '00000'
2 Execute     [1] SELECT * FROM users WHERE id = '00000'
3 Connect     [email protected] on test
3 Query       SET NAMES utf8
3 Prepare     [1] SELECT * FROM users WHERE id = '00001'
3 Execute     [1] SELECT * FROM users WHERE id = '00001'
....
1001 Connect     [email protected] on test
1001 Query       SET NAMES utf8
1001 Prepare     [1] SELECT * FROM users WHERE id = '00999'
1001 Execute     [1] SELECT * FROM users WHERE id = '00999'

Multi Result support

I am getting the following error when calling on my stored procedure

Error 1312: PROCEDURE mydb.GetAllNotes can't return a result set in the given context

I am calling on my stored procedure with this code

db.Query("CALL MyStoredProcedure()")

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.