Source file src/database/sql/driver/driver.go
1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package driver defines interfaces to be implemented by database 6 // drivers as used by package sql. 7 // 8 // Most code should use the [database/sql] package. 9 // 10 // The driver interface has evolved over time. Drivers should implement 11 // [Connector] and [DriverContext] interfaces. 12 // The Connector.Connect and Driver.Open methods should never return [ErrBadConn]. 13 // [ErrBadConn] should only be returned from [Validator], [SessionResetter], or 14 // a query method if the connection is already in an invalid (e.g. closed) state. 15 // 16 // All [Conn] implementations should implement the following interfaces: 17 // [Pinger], [SessionResetter], and [Validator]. 18 // 19 // If named parameters or context are supported, the driver's [Conn] should implement: 20 // [ExecerContext], [QueryerContext], [ConnPrepareContext], and [ConnBeginTx]. 21 // 22 // To support custom data types, implement [NamedValueChecker]. [NamedValueChecker] 23 // also allows queries to accept per-query options as a parameter by returning 24 // [ErrRemoveArgument] from CheckNamedValue. 25 // 26 // If multiple result sets are supported, [Rows] should implement [RowsNextResultSet]. 27 // If the driver knows how to describe the types present in the returned result 28 // it should implement the following interfaces: [RowsColumnTypeScanType], 29 // [RowsColumnTypeDatabaseTypeName], [RowsColumnTypeLength], [RowsColumnTypeNullable], 30 // and [RowsColumnTypePrecisionScale]. A given row value may also return a [Rows] 31 // type, which may represent a database cursor value. 32 // 33 // If a [Conn] implements [Validator], then the IsValid method is called 34 // before returning the connection to the connection pool. If an entry in the 35 // connection pool implements [SessionResetter], then ResetSession 36 // is called before reusing the connection for another query. If a connection is 37 // never returned to the connection pool but is immediately reused, then 38 // ResetSession is called prior to reuse but IsValid is not called. 39 package driver 40 41 import ( 42 "context" 43 "database/sql/internal" 44 "errors" 45 "reflect" 46 ) 47 48 // Value is a value that drivers must be able to handle. 49 // It is either nil, a type handled by a database driver's [NamedValueChecker] 50 // interface, or an instance of one of these types: 51 // 52 // int64 53 // float64 54 // bool 55 // []byte 56 // string 57 // time.Time 58 // 59 // If the driver supports cursors, a returned Value may also implement the [Rows] interface 60 // in this package. This is used, for example, when a user selects a cursor 61 // such as "select cursor(select * from my_table) from dual". If the [Rows] 62 // from the select is closed, the cursor [Rows] will also be closed. 63 type Value any 64 65 // NamedValue holds both the value name and value. 66 type NamedValue struct { 67 // If the Name is not empty it should be used for the parameter identifier and 68 // not the ordinal position. 69 // 70 // Name will not have a symbol prefix. 71 Name string 72 73 // Ordinal position of the parameter starting from one and is always set. 74 Ordinal int 75 76 // Value is the parameter value. 77 Value Value 78 } 79 80 // Driver is the interface that must be implemented by a database 81 // driver. 82 // 83 // Database drivers may implement [DriverContext] for access 84 // to contexts and to parse the name only once for a pool of connections, 85 // instead of once per connection. 86 type Driver interface { 87 // Open returns a new connection to the database. 88 // The name is a string in a driver-specific format. 89 // 90 // Open may return a cached connection (one previously 91 // closed), but doing so is unnecessary; the sql package 92 // maintains a pool of idle connections for efficient re-use. 93 // 94 // The returned connection is only used by one goroutine at a 95 // time. 96 Open(name string) (Conn, error) 97 } 98 99 // If a [Driver] implements DriverContext, then [database/sql.DB] will call 100 // OpenConnector to obtain a [Connector] and then invoke 101 // that [Connector]'s Connect method to obtain each needed connection, 102 // instead of invoking the [Driver]'s Open method for each connection. 103 // The two-step sequence allows drivers to parse the name just once 104 // and also provides access to per-[Conn] contexts. 105 type DriverContext interface { 106 // OpenConnector must parse the name in the same format that Driver.Open 107 // parses the name parameter. 108 OpenConnector(name string) (Connector, error) 109 } 110 111 // A Connector represents a driver in a fixed configuration 112 // and can create any number of equivalent Conns for use 113 // by multiple goroutines. 114 // 115 // A Connector can be passed to [database/sql.OpenDB], to allow drivers 116 // to implement their own [database/sql.DB] constructors, or returned by 117 // [DriverContext]'s OpenConnector method, to allow drivers 118 // access to context and to avoid repeated parsing of driver 119 // configuration. 120 // 121 // If a Connector implements [io.Closer], the [database/sql.DB.Close] 122 // method will call the Close method and return error (if any). 123 type Connector interface { 124 // Connect returns a connection to the database. 125 // Connect may return a cached connection (one previously 126 // closed), but doing so is unnecessary; the sql package 127 // maintains a pool of idle connections for efficient re-use. 128 // 129 // The provided context.Context is for dialing purposes only 130 // (see net.DialContext) and should not be stored or used for 131 // other purposes. A default timeout should still be used 132 // when dialing as a connection pool may call Connect 133 // asynchronously to any query. 134 // 135 // The returned connection is only used by one goroutine at a 136 // time. 137 Connect(context.Context) (Conn, error) 138 139 // Driver returns the underlying Driver of the Connector, 140 // mainly to maintain compatibility with the Driver method 141 // on sql.DB. 142 Driver() Driver 143 } 144 145 // ErrSkip may be returned by some optional interfaces' methods to 146 // indicate at runtime that the fast path is unavailable and the sql 147 // package should continue as if the optional interface was not 148 // implemented. ErrSkip is only supported where explicitly 149 // documented. 150 var ErrSkip = errors.New("driver: skip fast-path; continue as if unimplemented") 151 152 // ErrBadConn should be returned by a driver to signal to the [database/sql] 153 // package that a driver.[Conn] is in a bad state (such as the server 154 // having earlier closed the connection) and the [database/sql] package should 155 // retry on a new connection. 156 // 157 // To prevent duplicate operations, ErrBadConn should NOT be returned 158 // if there's a possibility that the database server might have 159 // performed the operation. Even if the server sends back an error, 160 // you shouldn't return ErrBadConn. 161 // 162 // Errors will be checked using [errors.Is]. An error may 163 // wrap ErrBadConn or implement the Is(error) bool method. 164 var ErrBadConn = errors.New("driver: bad connection") 165 166 // Pinger is an optional interface that may be implemented by a [Conn]. 167 // 168 // If a [Conn] does not implement Pinger, the [database/sql.DB.Ping] and 169 // [database/sql.DB.PingContext] will check if there is at least one [Conn] available. 170 // 171 // If Conn.Ping returns [ErrBadConn], [database/sql.DB.Ping] and [database/sql.DB.PingContext] will remove 172 // the [Conn] from pool. 173 type Pinger interface { 174 Ping(ctx context.Context) error 175 } 176 177 // Execer is an optional interface that may be implemented by a [Conn]. 178 // 179 // If a [Conn] implements neither [ExecerContext] nor [Execer], 180 // the [database/sql.DB.Exec] will first prepare a query, execute the statement, 181 // and then close the statement. 182 // 183 // Exec may return [ErrSkip]. 184 // 185 // Deprecated: Drivers should implement [ExecerContext] instead. 186 type Execer interface { 187 Exec(query string, args []Value) (Result, error) 188 } 189 190 // ExecerContext is an optional interface that may be implemented by a [Conn]. 191 // 192 // If a [Conn] does not implement [ExecerContext], the [database/sql.DB.Exec] 193 // will fall back to [Execer]; if the Conn does not implement Execer either, 194 // [database/sql.DB.Exec] will first prepare a query, execute the statement, and then 195 // close the statement. 196 // 197 // ExecContext may return [ErrSkip]. 198 // 199 // ExecContext must honor the context timeout and return when the context is canceled. 200 type ExecerContext interface { 201 ExecContext(ctx context.Context, query string, args []NamedValue) (Result, error) 202 } 203 204 // Queryer is an optional interface that may be implemented by a [Conn]. 205 // 206 // If a [Conn] implements neither [QueryerContext] nor [Queryer], 207 // the [database/sql.DB.Query] will first prepare a query, execute the statement, 208 // and then close the statement. 209 // 210 // Query may return [ErrSkip]. 211 // 212 // Deprecated: Drivers should implement [QueryerContext] instead. 213 type Queryer interface { 214 Query(query string, args []Value) (Rows, error) 215 } 216 217 // QueryerContext is an optional interface that may be implemented by a [Conn]. 218 // 219 // If a [Conn] does not implement QueryerContext, the [database/sql.DB.Query] 220 // will fall back to [Queryer]; if the [Conn] does not implement [Queryer] either, 221 // [database/sql.DB.Query] will first prepare a query, execute the statement, and then 222 // close the statement. 223 // 224 // QueryContext may return [ErrSkip]. 225 // 226 // QueryContext must honor the context timeout and return when the context is canceled. 227 type QueryerContext interface { 228 QueryContext(ctx context.Context, query string, args []NamedValue) (Rows, error) 229 } 230 231 // Conn is a connection to a database. It is not used concurrently 232 // by multiple goroutines. 233 // 234 // Conn is assumed to be stateful. 235 type Conn interface { 236 // Prepare returns a prepared statement, bound to this connection. 237 Prepare(query string) (Stmt, error) 238 239 // Close invalidates and potentially stops any current 240 // prepared statements and transactions, marking this 241 // connection as no longer in use. 242 // 243 // Because the sql package maintains a free pool of 244 // connections and only calls Close when there's a surplus of 245 // idle connections, it shouldn't be necessary for drivers to 246 // do their own connection caching. 247 // 248 // Drivers must ensure all network calls made by Close 249 // do not block indefinitely (e.g. apply a timeout). 250 Close() error 251 252 // Begin starts and returns a new transaction. 253 // 254 // Deprecated: Drivers should implement ConnBeginTx instead (or additionally). 255 Begin() (Tx, error) 256 } 257 258 // ConnPrepareContext enhances the [Conn] interface with context. 259 type ConnPrepareContext interface { 260 // PrepareContext returns a prepared statement, bound to this connection. 261 // context is for the preparation of the statement, 262 // it must not store the context within the statement itself. 263 PrepareContext(ctx context.Context, query string) (Stmt, error) 264 } 265 266 // IsolationLevel is the transaction isolation level stored in [TxOptions]. 267 // 268 // This type should be considered identical to [database/sql.IsolationLevel] along 269 // with any values defined on it. 270 type IsolationLevel int 271 272 // TxOptions holds the transaction options. 273 // 274 // This type should be considered identical to [database/sql.TxOptions]. 275 type TxOptions struct { 276 Isolation IsolationLevel 277 ReadOnly bool 278 } 279 280 // ConnBeginTx enhances the [Conn] interface with context and [TxOptions]. 281 type ConnBeginTx interface { 282 // BeginTx starts and returns a new transaction. 283 // If the context is canceled by the user the sql package will 284 // call Tx.Rollback before discarding and closing the connection. 285 // 286 // This must check opts.Isolation to determine if there is a set 287 // isolation level. If the driver does not support a non-default 288 // level and one is set or if there is a non-default isolation level 289 // that is not supported, an error must be returned. 290 // 291 // This must also check opts.ReadOnly to determine if the read-only 292 // value is true to either set the read-only transaction property if supported 293 // or return an error if it is not supported. 294 BeginTx(ctx context.Context, opts TxOptions) (Tx, error) 295 } 296 297 // SessionResetter may be implemented by [Conn] to allow drivers to reset the 298 // session state associated with the connection and to signal a bad connection. 299 type SessionResetter interface { 300 // ResetSession is called prior to executing a query on the connection 301 // if the connection has been used before. If the driver returns ErrBadConn 302 // the connection is discarded. 303 ResetSession(ctx context.Context) error 304 } 305 306 // Validator may be implemented by [Conn] to allow drivers to 307 // signal if a connection is valid or if it should be discarded. 308 // 309 // If implemented, drivers may return the underlying error from queries, 310 // even if the connection should be discarded by the connection pool. 311 type Validator interface { 312 // IsValid is called prior to placing the connection into the 313 // connection pool. The connection will be discarded if false is returned. 314 IsValid() bool 315 } 316 317 // Result is the result of a query execution. 318 type Result interface { 319 // LastInsertId returns the database's auto-generated ID 320 // after, for example, an INSERT into a table with primary 321 // key. 322 LastInsertId() (int64, error) 323 324 // RowsAffected returns the number of rows affected by the 325 // query. 326 RowsAffected() (int64, error) 327 } 328 329 // Stmt is a prepared statement. It is bound to a [Conn] and not 330 // used by multiple goroutines concurrently. 331 type Stmt interface { 332 // Close closes the statement. 333 // 334 // As of Go 1.1, a Stmt will not be closed if it's in use 335 // by any queries. 336 // 337 // Drivers must ensure all network calls made by Close 338 // do not block indefinitely (e.g. apply a timeout). 339 Close() error 340 341 // NumInput returns the number of placeholder parameters. 342 // 343 // If NumInput returns >= 0, the sql package will sanity check 344 // argument counts from callers and return errors to the caller 345 // before the statement's Exec or Query methods are called. 346 // 347 // NumInput may also return -1, if the driver doesn't know 348 // its number of placeholders. In that case, the sql package 349 // will not sanity check Exec or Query argument counts. 350 NumInput() int 351 352 // Exec executes a query that doesn't return rows, such 353 // as an INSERT or UPDATE. 354 // 355 // Deprecated: Drivers should implement StmtExecContext instead (or additionally). 356 Exec(args []Value) (Result, error) 357 358 // Query executes a query that may return rows, such as a 359 // SELECT. 360 // 361 // Deprecated: Drivers should implement StmtQueryContext instead (or additionally). 362 Query(args []Value) (Rows, error) 363 } 364 365 // StmtExecContext enhances the [Stmt] interface by providing Exec with context. 366 type StmtExecContext interface { 367 // ExecContext executes a query that doesn't return rows, such 368 // as an INSERT or UPDATE. 369 // 370 // ExecContext must honor the context timeout and return when it is canceled. 371 ExecContext(ctx context.Context, args []NamedValue) (Result, error) 372 } 373 374 // StmtQueryContext enhances the [Stmt] interface by providing Query with context. 375 type StmtQueryContext interface { 376 // QueryContext executes a query that may return rows, such as a 377 // SELECT. 378 // 379 // QueryContext must honor the context timeout and return when it is canceled. 380 QueryContext(ctx context.Context, args []NamedValue) (Rows, error) 381 } 382 383 // ErrRemoveArgument may be returned from [NamedValueChecker] to instruct the 384 // [database/sql] package to not pass the argument to the driver query interface. 385 // Return when accepting query specific options or structures that aren't 386 // SQL query arguments. 387 var ErrRemoveArgument = errors.New("driver: remove argument from query") 388 389 // NamedValueChecker may be optionally implemented by [Conn] or [Stmt]. It provides 390 // the driver more control to handle Go and database types beyond the default 391 // [Value] types allowed. 392 // 393 // The [database/sql] package checks for value checkers in the following order, 394 // stopping at the first found match: Stmt.NamedValueChecker, Conn.NamedValueChecker, 395 // Stmt.ColumnConverter, [DefaultParameterConverter]. 396 // 397 // If CheckNamedValue returns [ErrRemoveArgument], the [NamedValue] will not be included in 398 // the final query arguments. This may be used to pass special options to 399 // the query itself. 400 // 401 // If [ErrSkip] is returned the column converter error checking 402 // path is used for the argument. Drivers may wish to return [ErrSkip] after 403 // they have exhausted their own special cases. 404 type NamedValueChecker interface { 405 // CheckNamedValue is called before passing arguments to the driver 406 // and is called in place of any ColumnConverter. CheckNamedValue must do type 407 // validation and conversion as appropriate for the driver. 408 CheckNamedValue(*NamedValue) error 409 } 410 411 // ColumnConverter may be optionally implemented by [Stmt] if the 412 // statement is aware of its own columns' types and can convert from 413 // any type to a driver [Value]. 414 // 415 // Deprecated: Drivers should implement [NamedValueChecker]. 416 type ColumnConverter interface { 417 // ColumnConverter returns a ValueConverter for the provided 418 // column index. If the type of a specific column isn't known 419 // or shouldn't be handled specially, [DefaultParameterConverter] 420 // can be returned. 421 ColumnConverter(idx int) ValueConverter 422 } 423 424 // Rows is an iterator over an executed query's results. 425 type Rows interface { 426 // Columns returns the names of the columns. The number of 427 // columns of the result is inferred from the length of the 428 // slice. If a particular column name isn't known, an empty 429 // string should be returned for that entry. 430 Columns() []string 431 432 // Close closes the rows iterator. 433 Close() error 434 435 // Next is called to populate the next row of data into 436 // the provided slice. The provided slice will be the same 437 // size as the Columns() are wide. 438 // 439 // Next should return io.EOF when there are no more rows. 440 // 441 // The dest should not be written to outside of Next. Care 442 // should be taken when closing Rows not to modify 443 // a buffer held in dest. 444 Next(dest []Value) error 445 } 446 447 // ScanContext carries state related to the current query 448 // through a [RowsColumnScanner.ScanColumn] function to [database/sql.ConvertAssign]. 449 type ScanContext internal.ScanContext 450 451 // RowsColumnScanner extends the [Rows] interface by providing a way for the driver 452 // to scan directly into the user-provided destination. 453 // 454 // RowsColumnScanner supersedes the [Rows.Next] method. 455 // 456 // As of Go 1.27, database/sql will not call Next if a Rows implements RowsColumnScanner. 457 // Rows implementations may still implement the Next method to support older versions of Go. 458 type RowsColumnScanner interface { 459 Rows 460 461 // NextRow advances to the next row of data. 462 // It should return io.EOF when there are no more rows. 463 NextRow() error 464 465 // ScanColumn copies the column at the given index in the current row 466 // into the value pointed to by dest. 467 // 468 // The driver may assign a driver.Value to dest using [database/sql.ConvertAssign]. 469 ScanColumn(scanCtx ScanContext, index int, dest any) error 470 } 471 472 // RowsNextResultSet extends the [Rows] interface by providing a way to signal 473 // the driver to advance to the next result set. 474 type RowsNextResultSet interface { 475 Rows 476 477 // HasNextResultSet is called at the end of the current result set and 478 // reports whether there is another result set after the current one. 479 HasNextResultSet() bool 480 481 // NextResultSet advances the driver to the next result set even 482 // if there are remaining rows in the current result set. 483 // 484 // NextResultSet should return io.EOF when there are no more result sets. 485 NextResultSet() error 486 } 487 488 // RowsColumnTypeScanType may be implemented by [Rows]. It should return 489 // the value type that can be used to scan types into. For example, the database 490 // column type "bigint" this should return "[reflect.TypeOf](int64(0))". 491 type RowsColumnTypeScanType interface { 492 Rows 493 ColumnTypeScanType(index int) reflect.Type 494 } 495 496 // RowsColumnTypeDatabaseTypeName may be implemented by [Rows]. It should return the 497 // database system type name without the length. Type names should be uppercase. 498 // Examples of returned types: "VARCHAR", "NVARCHAR", "VARCHAR2", "CHAR", "TEXT", 499 // "DECIMAL", "SMALLINT", "INT", "BIGINT", "BOOL", "[]BIGINT", "JSONB", "XML", 500 // "TIMESTAMP". 501 type RowsColumnTypeDatabaseTypeName interface { 502 Rows 503 ColumnTypeDatabaseTypeName(index int) string 504 } 505 506 // RowsColumnTypeLength may be implemented by [Rows]. It should return the length 507 // of the column type if the column is a variable length type. If the column is 508 // not a variable length type ok should return false. 509 // If length is not limited other than system limits, it should return [math.MaxInt64]. 510 // The following are examples of returned values for various types: 511 // 512 // TEXT (math.MaxInt64, true) 513 // varchar(10) (10, true) 514 // nvarchar(10) (10, true) 515 // decimal (0, false) 516 // int (0, false) 517 // bytea(30) (30, true) 518 type RowsColumnTypeLength interface { 519 Rows 520 ColumnTypeLength(index int) (length int64, ok bool) 521 } 522 523 // RowsColumnTypeNullable may be implemented by [Rows]. The nullable value should 524 // be true if it is known the column may be null, or false if the column is known 525 // to be not nullable. 526 // If the column nullability is unknown, ok should be false. 527 type RowsColumnTypeNullable interface { 528 Rows 529 ColumnTypeNullable(index int) (nullable, ok bool) 530 } 531 532 // RowsColumnTypePrecisionScale may be implemented by [Rows]. It should return 533 // the precision and scale for decimal types. If not applicable, ok should be false. 534 // The following are examples of returned values for various types: 535 // 536 // decimal(38, 4) (38, 4, true) 537 // int (0, 0, false) 538 // decimal (math.MaxInt64, math.MaxInt64, true) 539 type RowsColumnTypePrecisionScale interface { 540 Rows 541 ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) 542 } 543 544 // Tx is a transaction. 545 type Tx interface { 546 Commit() error 547 Rollback() error 548 } 549 550 // RowsAffected implements [Result] for an INSERT or UPDATE operation 551 // which mutates a number of rows. 552 type RowsAffected int64 553 554 var _ Result = RowsAffected(0) 555 556 func (RowsAffected) LastInsertId() (int64, error) { 557 return 0, errors.New("LastInsertId is not supported by this driver") 558 } 559 560 func (v RowsAffected) RowsAffected() (int64, error) { 561 return int64(v), nil 562 } 563 564 // ResultNoRows is a pre-defined [Result] for drivers to return when a DDL 565 // command (such as a CREATE TABLE) succeeds. It returns an error for both 566 // LastInsertId and [RowsAffected]. 567 var ResultNoRows noRows 568 569 type noRows struct{} 570 571 var _ Result = noRows{} 572 573 func (noRows) LastInsertId() (int64, error) { 574 return 0, errors.New("no LastInsertId available after DDL statement") 575 } 576 577 func (noRows) RowsAffected() (int64, error) { 578 return 0, errors.New("no RowsAffected available after DDL statement") 579 } 580