- This Project is forked from trinodb/trino-go-client and customized for NCP Data Query Service.
- Following codes are added/modified to support NCP IAM Authentication and Data Query connection parameters.
trino/trino.go(Modified)trino/third-party/dataquery/auth.go(Added)
go get github.com/NaverCloudPlatform/dataquery-go-clientimport "database/sql"
import _ "github.com/NaverCloudPlatform/dataquery-go-client/trino"
accessKey := "_your_access_key_"
secretKey := "_your_secret_key_"
dsn := fmt.Sprintf("https://%s:%s@kr.dataquery.naverncp.com?catalog=data_catalog&schema=default", accessKey, secretKey)
db, err := sql.Open("dataquery", dsn)reuse_query_result: Enable reuse query result if exist.- boolean type, default: false
reuse_query_max_age: When reuse-query-result enabled, maxAge(unit: minutes) will be used to find same query request within the period.- integer type, default: 60, range: 1~10800
import "database/sql"
import _ "github.com/NaverCloudPlatform/dataquery-go-client/trino"
accessKey := "_your_access_key_"
secretKey := "_your_secret_key_"
dsn := fmt.Sprintf("https://%s:%s@kr.dataquery.naverncp.com?catalog=data_catalog&schema=default&reuse_query_result=true&reuse_query_max_age=10", accessKey, secretKey)
db, err := sql.Open("dataquery", dsn)A Trino client for the Go programming language. It enables you to send SQL statements from your Go application to Trino, and receive the resulting data.
- Native Go implementation
- Connections over HTTP or HTTPS
- HTTP Basic, Kerberos, and JSON web token (JWT) authentication
- Per-query user information for access control
- Support custom HTTP client (tunable conn pools, timeouts, TLS)
- Supports conversion from Trino to native Go data types
string,sql.NullStringint64,sql.NullInt64float64,sql.NullFloat64map,trino.NullMaptime.Time,trino.NullTime- Up to 3-dimensional arrays to Go slices, of any supported type
- Go 1.22 or newer
- Trino 372 or newer
You need a working environment with Go installed and $GOPATH set.
Download and install Trino database/sql driver:
go get github.com/trinodb/trino-go-client/trinoMake sure you have Git installed and in your $PATH.
This Trino client is an implementation of Go's database/sql/driver interface.
In order to use it, you need to import the package and use the
database/sql API then.
Use trino as driverName and a valid DSN as the
dataSourceName.
Example:
import "database/sql"
import _ "github.com/trinodb/trino-go-client/trino"
dsn := "http://user@localhost:8080?catalog=default&schema=test"
db, err := sql.Open("trino", dsn)Both HTTP Basic, Kerberos, and JWT authentication are supported.
If the DSN contains a password, the client enables HTTP Basic authentication by
setting the Authorization header in every request to Trino.
HTTP Basic authentication is only supported on encrypted connections over HTTPS.
This driver supports Kerberos authentication by setting up the Kerberos fields in the Config struct.
Please refer to the Coordinator Kerberos Authentication for server-side configuration.
This driver supports JWT authentication by setting up the AccessToken field
in the
Config
struct.
Please refer to the Coordinator JWT Authentication for server-side configuration.
This driver supports forwarding authorization headers by adding a NamedArg with the name accessToken (e.g., accessToken=<your_access_token>) and setting the ForwardAuthorizationHeader field in the Config struct to true.
When enabled, this configuration will override the AccessToken set in the Config struct.
It's possible to pass user information to Trino, different from the principal used to authenticate to the coordinator. See the System Access Control documentation for details.
In order to pass user information in queries to Trino, you have to add a NamedArg to the query parameters where the key is X-Trino-User. This parameter is used by the driver to inform Trino about the user executing the query regardless of the authentication method for the actual connection, and its value is NOT passed to the query.
Example:
db.Query("SELECT * FROM foobar WHERE id=?", 1, sql.Named("X-Trino-User", string("Alice")))The position of the X-Trino-User NamedArg is irrelevant and does not affect the query in any way.
The Data Source Name is a URL with a mandatory username, and optional query string parameters that are supported by this driver, in the following format:
http[s]://user[:pass]@host[:port][?parameters]
The easiest way to build your DSN is by using the Config.FormatDSN helper function.
The driver supports both HTTP and HTTPS. If you use HTTPS it's recommended that
you also provide a custom http.Client that can validate (or skip) the
security checks of the server certificate, and/or to configure TLS client
authentication.
Parameters are case-sensitive
Refer to the Trino Concepts documentation for more information.
Type: string
Valid values: string describing the source of the connection to Trino
Default: empty
The source parameter is optional, but if used, can help Trino admins
troubleshoot queries and trace them back to the original client.
Type: string
Valid values: the name of a catalog configured in the Trino server
Default: empty
The catalog parameter defines the Trino catalog where schemas exist to
organize tables.
Type: string
Valid values: the name of an existing schema in the catalog
Default: empty
The schema parameter defines the Trino schema where tables exist. This is
also known as namespace in some environments.
Type: string
Valid values: comma-separated list of key=value session properties
Default: empty
The session_properties parameter must contain valid parameters accepted by
the Trino server. Run SHOW SESSION in Trino to get the current list.
Type: string
Valid values: the name of a client previously registered to the driver
Default: empty (defaults to http.DefaultClient)
The custom_client parameter allows the use of custom http.Client for the
communication with Trino.
Register your custom client in the driver, then refer to it by name in the DSN,
on the call to sql.Open:
foobarClient := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}).DialContext,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
TLSClientConfig: &tls.Config{
// your config here...
},
},
}
trino.RegisterCustomClient("foobar", foobarClient)
db, err := sql.Open("trino", "https://user@localhost:8080?custom_client=foobar")A custom client can also be used to add OpenTelemetry instrumentation. The otelhttp package provides a transport wrapper that creates spans for HTTP requests and propagates the trace ID in HTTP headers:
otelClient := &http.Client{
Transport: otelhttp.NewTransport(http.DefaultTransport),
}
trino.RegisterCustomClient("otel", otelClient)
db, err := sql.Open("trino", "https://user@localhost:8080?custom_client=otel")Type: time.Duration
Valid values: duration string
Default: nil
The queryTimeout parameter sets a timeout for the query. If the query takes longer than the timeout, it will be cancelled. If it is not set the default context timeout will be used.
http://user@localhost:8080?source=hello&catalog=default&schema=foobar
https://user@localhost:8443?session_properties=query_max_run_time=10m,query_priority=2
When passing arguments to queries, the driver supports the following Go data types:
- integers
boolstring[]byte- slices
trino.Numeric- a string representation of a numbertime.Time- passed to Trino as a timestamp with a time zone- the result of
trino.Date(year, month, day)- passed to Trino as a date - the result of
trino.Time(hour, minute, second, nanosecond)- passed to Trino as a time without a time zone - the result of
trino.TimeTz(hour, minute, second, nanosecond, location)- passed to Trino as a time with a time zone - the result of
trino.Timestamp(year, month, day, hour, minute, second, nanosecond)- passed to Trino as a timestamp without a time zone time.Duration- passed to Trino as an interval day to second. Because Trino does not support nanosecond precision for intervals, if the nanosecond part of the value is not zero, an error will be returned.
It's not yet possible to pass:
float32orfloat64bytejson.RawMessage- maps
To use the unsupported types, pass them as strings and use casts in the query, like so:
SELECT * FROM table WHERE col_double = cast(? AS DOUBLE) OR col_timestamp = CAST(? AS TIMESTAMP)When reading response rows, the driver supports most Trino data types, except:
- time and timestamps with precision - all time types are returned as
time.Time. All precisions up to nanoseconds (TIMESTAMP(9)orTIME(9)) are supported (since this is the maximum precision Golang'stime.Timesupports). If a query returns columns defined with a greater precision, values are trimmed to 9 decimal digits. UseCASTto reduce the returned precision, or convert the value to a string that then can be parsed manually. DECIMAL- returned as stringIPADDRESS- returned as stringINTERVAL YEAR TO MONTHandINTERVAL DAY TO SECOND- returned as stringUUID- returned as string
Data types like HyperLogLog, SetDigest, QDigest, and TDigest are not
supported and cannot be returned from a query.
For reading nullable columns, use:
trino.NullTimetrino.NullMap- which stores a map ofmap[string]interface{}or similar structs from thedatabase/sqlpackage, likesql.NullInt64
To read query results containing arrays or maps, pass one of the following
structs to the Scan() function:
trino.NullSliceBooltrino.NullSliceStringtrino.NullSliceInt64trino.NullSliceFloat64trino.NullSliceTimetrino.NullSliceMap
For two or three dimensional arrays, use trino.NullSlice2Bool and
trino.NullSlice3Bool or equivalents for other data types.
To read ROW values, implement the sql.Scanner interface in a struct. Its
Scan() function receives a []interface{} slice, with values of the
following types:
booljson.Numberfor any numeric Trino types[]interface{}for Trino arraysmap[string]interface{}for Trino mapsstringfor other Trino types, as character, date, time, or timestamp.
Note
VARBINARY columns are returned as base64-encoded strings when used within
ROW, MAP, or ARRAY values.
Apache License V2.0, as described in the LICENSE file.
You can build the client code locally and run tests with the following command:
go test -v -race -timeout 2m ./...
For contributing, development, and release guidelines, see CONTRIBUTING.md.