Documentation
¶
Overview ¶
Package drill is a highly efficient Pure Go client and driver for Apache Drill and Dremio.
A driver for the database/sql package is also provided via the driver subpackage. This can be used like so:
import ( "database/sql" _ "github.com/factset/go-drill/driver" ) func main() { props := []string{ "zk=zookeeper1,zookeeper2,zookeeper3", "auth=kerberos", "service=<krb_service_name>", "cluster=<clustername>", } db, err := sql.Open("drill", strings.Join(props, ";")) }
Also, currently logging of the internals can be turned on via the environment variable GO_DRILL_LOG_LEVEL. This uses github.com/rs/zerolog to do the logging so anything that is valid to pass to the zerolog.ParseLevel function is valid as a value for the environment variable.
Index ¶
- Constants
- Variables
- func ColMetaToArrowField(c ColumnMeta) arrow.Field
- type ArrowBatch
- func (a ArrowBatch) AffectedRows() (rows int32)
- func (a ArrowBatch) GetVectors() []DataVector
- func (a ArrowBatch) IsNullable(index int) bool
- func (a ArrowBatch) NumCols() int
- func (a ArrowBatch) NumRows() int32
- func (a ArrowBatch) PrecisionScale(index int) (precision, scale int64, ok bool)
- func (a ArrowBatch) TypeName(index int) string
- type ArrowVectorWrapper
- func (a ArrowVectorWrapper) GetNullBytemap() []byte
- func (a ArrowVectorWrapper) GetRawBytes() []byte
- func (a ArrowVectorWrapper) IsNull(index uint) bool
- func (a ArrowVectorWrapper) Type() reflect.Type
- func (a ArrowVectorWrapper) TypeLen() (int64, bool)
- func (a ArrowVectorWrapper) Value(index uint) interface{}
- type Client
- func (d *Client) Close() error
- func (d *Client) Connect(ctx context.Context) error
- func (d *Client) ConnectEndpoint(ctx context.Context, e Drillbit) error
- func (d *Client) ConnectWithZK(ctx context.Context, zkNode ...string) error
- func (d *Client) ExecuteStmt(hndl PreparedHandle) (DataHandler, error)
- func (d *Client) GetCatalogs(pattern string, escape *string) ([]*user.CatalogMetadata, error)
- func (d *Client) GetColumns(catalogPattern, schemaPattern, tablePattern, columnPattern string, ...) ([]*user.ColumnMetadata, error)
- func (d *Client) GetEndpoint() Drillbit
- func (d *Client) GetMetadata() (*user.ServerMeta, error)
- func (d *Client) GetSchemas(catalogPattern, schemaPattern string, escape *string) ([]*user.SchemaMetadata, error)
- func (d *Client) GetTables(catalogPattern, schemaPattern, tablePattern string, escape *string, ...) ([]*user.TableMetadata, error)
- func (d *Client) NewConnection(ctx context.Context) (Conn, error)
- func (d *Client) Ping(ctx context.Context) error
- func (d *Client) PrepareQuery(plan string) (PreparedHandle, error)
- func (d *Client) SubmitQuery(t QueryType, plan string) (DataHandler, error)
- type ColumnMeta
- type Conn
- type DataHandler
- type DataVector
- type Drillbit
- type NullableDataVector
- type Options
- type PreparedHandle
- type QueryType
- type ResultHandle
- type RowBatch
Examples ¶
Constants ¶
const ( TypeSQL QueryType = QueryType(shared.QueryType_SQL) TypeLogical = QueryType(shared.QueryType_LOGICAL) TypePhysical = QueryType(shared.QueryType_PHYSICAL) )
Variables ¶
var ( // This is returned when we get a query result status of Cancelled ErrQueryCancelled = errors.New("drill: query cancelled") // This is wrapped by the returned error if the query failed ErrQueryFailed = errors.New("drill: query failed") // This is returned if the query failed for some unknown reason ErrQueryUnknownState = errors.New("drill: query unknown state") )
These error types are potentially returned by calls to Next. If the query fails, the ErrQueryFailed type will be wrapped by the returned error, allowing usage like so:
err := handle.Next() if errors.Is(err, ErrQueryFailed) { err.Error() contains the actual error message // handle query failure }
Functions ¶
func ColMetaToArrowField ¶ added in v1.1.0
func ColMetaToArrowField(c ColumnMeta) arrow.Field
ColMetaToArrowField returns an arrow.Field for the column metadata provided, panics if not of type BOOLEAN, VARCHAR, VARBINARY, INTEGER, SMALLINT, BIGINT, TINYINT, DATE, TIME, TIMESTAMP, FLOAT, or DOUBLE.
TODO: handle decimal types
Adds the following metadata:
Default Value: key "default"
Types ¶
type ArrowBatch ¶
ArrowBatch is a record batch implementation of RowBatch which uses an arrow array.Record as the underlying storage instead.
func (ArrowBatch) AffectedRows ¶
func (a ArrowBatch) AffectedRows() (rows int32)
AffectedRows returns the number of rows listed as "Affected" by the response typically 0 unless the query was an insert/update.
func (ArrowBatch) GetVectors ¶
func (a ArrowBatch) GetVectors() []DataVector
GetVectors returns the actual columns of data for this row batch.
func (ArrowBatch) IsNullable ¶
func (a ArrowBatch) IsNullable(index int) bool
IsNullable reports whether the column index is a vector that can be null.
func (ArrowBatch) NumCols ¶
func (a ArrowBatch) NumCols() int
NumCols just returns the number of columns in the row batch.
func (ArrowBatch) NumRows ¶
func (a ArrowBatch) NumRows() int32
NumRows returns the number of rows in the rowbatch
func (ArrowBatch) PrecisionScale ¶
func (a ArrowBatch) PrecisionScale(index int) (precision, scale int64, ok bool)
PrecisionScale returns the precision and scale of the type for this column as defined in the RowsColumnTypePrecisionScale interface of database/sql/driver
func (ArrowBatch) TypeName ¶
func (a ArrowBatch) TypeName(index int) string
TypeName returns the Database Type string for the column as defined by the record definition from drill.
type ArrowVectorWrapper ¶
ArrowVectorWrapper is a thin wrapper around an arrow array to fit our DataVector interface so that we can use arrow Records as the underlying data storage for our record handling if desired. This allows future enhancements and also letting our current set up for returning data be allowed to return arrow records without having to change much.
func (ArrowVectorWrapper) GetNullBytemap ¶
func (a ArrowVectorWrapper) GetNullBytemap() []byte
GetNullBytemap returns the bytes of the bitmap from the underlying arrow array.
func (ArrowVectorWrapper) GetRawBytes ¶
func (a ArrowVectorWrapper) GetRawBytes() []byte
GetRawBytes returns the underlying raw data for the array.
func (ArrowVectorWrapper) IsNull ¶
func (a ArrowVectorWrapper) IsNull(index uint) bool
IsNull just forwards to the underlying IsNull for the arrow array.
func (ArrowVectorWrapper) Type ¶
func (a ArrowVectorWrapper) Type() reflect.Type
Type determines the go reflection type for the values of the array.
func (ArrowVectorWrapper) TypeLen ¶
func (a ArrowVectorWrapper) TypeLen() (int64, bool)
TypeLen returns the max length for variable length types (the second output is true) otherwise fixed length types return false for the second output.
func (ArrowVectorWrapper) Value ¶
func (a ArrowVectorWrapper) Value(index uint) interface{}
Value for now will always return nil, the expectation is to cast the wrapper to an array.Interface and use it directly via arrow rather than using the DataVector interface.
TODO: implement type switch from arrow to pull value for this
type Client ¶
type Client struct { // Modifying the options after connecting does not affect the current connection // it will only affect future connections of this client. Opts Options ZkNodes []string // contains filtered or unexported fields }
A Client is used for communicating to a drill cluster.
After creating a client via one of the NewDrillClient functions, one of the Connect functions can be called to actually connect to the cluster.
func NewClient ¶
NewClient initializes a Drill Client with the given options but does not actually connect yet. It also allows specifying the zookeeper cluster nodes here.
func NewDirectClient ¶
NewDirectClient initializes a Drill Client which connects to an endpoint directly rather than relying on ZooKeeper for finding drill bits.
func (*Client) Connect ¶
Connect attempts to use the current ZooKeeper cluster in order to find a drill bit to connect to. This will also populate the internal listing of drill bits from zookeeper.
As with ConnectEndpoint, the context provided will be passed to DialContext and will not be stored in the client.
func (*Client) ConnectEndpoint ¶
ConnectEndpoint connects to the provided endpoint directly rather than looking for drillbits via zookeeper. This is also used by the normal connect setup to connect to the desired drillbit once it has been chosen from the zookeeper information.
The provided context object will be passed to DialContext to control the deadlines for the socket connection, it will not be saved into the client.
func (*Client) ConnectWithZK ¶
ConnectWithZK overrides the current stored zookeeper cluster in the client, and uses the passed list of nodes to find a drillbit. This will replace the stored zookeeper nodes in the client with the new set provided.
As with ConnectEndpoint, the context provided will be passed to DialContext and will not be stored in the client.
func (*Client) ExecuteStmt ¶
func (d *Client) ExecuteStmt(hndl PreparedHandle) (DataHandler, error)
ExecuteStmt runs the passed prepared statement against the cluster and returns a handle to the results in the same way that SubmitQuery does.
func (*Client) GetCatalogs ¶
GetCatalogs uses the given pattern to search and return the catalogs available on the server. For drill, this is always only "DRILL". The syntax of the pattern is equivalent to using a LIKE sql expression. If there is no need to escape characters in the search filter, pass nil for the second argument, otherwise it should point to a string consisting of the characters used for escaping in the pattern.
func (*Client) GetColumns ¶
func (d *Client) GetColumns(catalogPattern, schemaPattern, tablePattern, columnPattern string, escape *string) ([]*user.ColumnMetadata, error)
GetColumns returns the metadata for all the columns from all the tables which fit the provided filter patterns.
The syntax for the filter pattern is the same as for GetCatalogs.
func (*Client) GetEndpoint ¶
GetEndpoint returns the currently configured endpoint that the client either is connected to or will connect to if Connect is called (in the case of a Direct connection client). Returns nil for a client using Zookeeper that hasn't connected yet, as the endpoint is only determined when connecting in that case.
func (*Client) GetMetadata ¶
func (d *Client) GetMetadata() (*user.ServerMeta, error)
GetMetadata returns a structure consisting of all of the Drill Server metadata including what sql keywords are supported, escape characters, max lengths etc.
func (*Client) GetSchemas ¶
func (d *Client) GetSchemas(catalogPattern, schemaPattern string, escape *string) ([]*user.SchemaMetadata, error)
GetSchemas returns all the schemas which fit the filter patterns provided.
The syntax for the filter pattern is the same as for GetCatalogs.
func (*Client) GetTables ¶
func (d *Client) GetTables(catalogPattern, schemaPattern, tablePattern string, escape *string, tableTypes ...string) ([]*user.TableMetadata, error)
GetTables returns the metadata for all the tables which fit the filter patterns provided and are of the table types passed in.
The syntax for the filter pattern is the same as for GetCatalogs.
func (*Client) NewConnection ¶
NewConnection will use the stored zookeeper quorum nodes and drill bit information to find the next drill bit to connect to in order to spread out the load.
The client returned from this will already be connected using the same options and zookeeper cluster as the current Client, just picking a different endpoint to connect to.
func (*Client) Ping ¶
Ping sends a ping to the server via this connection and waits for a Pong response. Returns database/sql/driver.ErrBadConn if it fails or nil if it succeeds.
func (*Client) PrepareQuery ¶
func (d *Client) PrepareQuery(plan string) (PreparedHandle, error)
PrepareQuery creates a prepared sql statement and returns a handle to it. This handle can be used with any client connected to the same cluster in order to actually execute it with ExecuteStmt.
func (*Client) SubmitQuery ¶
func (d *Client) SubmitQuery(t QueryType, plan string) (DataHandler, error)
SubmitQuery submits the specified query and query type returning a handle to the results This only blocks long enough to receive a Query ID from the cluster, it does not wait for the results to start coming in. The result handle can be used to do that.
If the query fails, this will not error but rather you'd retrieve that failure from the result handle itself.
type ColumnMeta ¶ added in v1.1.0
type ColumnMeta interface { GetColumnName() string GetIsNullable() bool GetDataType() string GetCharMaxLength() int32 GetCharOctetLength() int32 GetNumericPrecision() int32 GetNumericPrecisionRadix() int32 GetNumericScale() int32 GetDateTimePrecision() int32 GetIntervalType() string GetIntervalPrecision() int32 GetColumnSize() int32 GetDefaultValue() string }
type Conn ¶
type Conn interface { ConnectEndpoint(context.Context, Drillbit) error Connect(context.Context) error ConnectWithZK(context.Context, ...string) error GetEndpoint() Drillbit Ping(context.Context) error SubmitQuery(QueryType, string) (DataHandler, error) PrepareQuery(string) (PreparedHandle, error) ExecuteStmt(PreparedHandle) (DataHandler, error) NewConnection(context.Context) (Conn, error) Close() error }
A Conn represents a single connection to a drill bit. This interface is useful for things consuming the Client to maintain a separation so that it is easy to mock out for testing.
type DataHandler ¶
type DataHandler interface { Next() (RowBatch, error) Cancel() GetCols() []string GetRecordBatch() RowBatch Close() error }
A DataHandler is an object that allows iterating through record batches as the data comes in, or cancelling a running query.
type DataVector ¶
type DataVector data.DataVector
type NullableDataVector ¶
type NullableDataVector data.NullableDataVector
type Options ¶
type Options struct { // the default Schema to use Schema string // true if expected to use encryption for communication SaslEncrypt bool // the HOST portion to use for the spn to authenticate with, if _HOST or // empty, will use the address of the drillbit that is connected to ServiceHost string // the krb service name to use for authentication ServiceName string // what authentication mechanism to use, currently only supports kerberos // or no auth Auth string // the Drill clusters name which is used by ZooKeeper to store the endpoint // information ClusterName string // use this instead of ClusterName to fully specify the Zookeeper path instead // of using the /drill prefix ZKPath string // whether or not the server should support complex types such as List SupportComplexTypes bool // what Application Name to use for connecting to the server ApplicationName string // the username to authenticate as User string // Password to use for PLAIN auth Passwd string // the heartbeatfrequency to use, if nil then will use the default (15 seconds) // set to 0 to disable it. HeartbeatFreq *time.Duration // UseArrow controls whether the raw data in the results is underlined by arrow // arrays (if true) or not (if false, default) UseArrow bool }
Options for a Drill Connection
type PreparedHandle ¶
type PreparedHandle interface{}
A PreparedHandle is an opaque handle for a Prepared Statement.
This does not contain a reference to the client it originally came from as it can be passed to any valid drill client in order to execute it as long as it is connected to the same server cluster. This is because the prepared statement information is stored on the server, this object contains the server handle needed to execute the statement.
Keep in mind that Apache Drill *does not* support parameters in prepared statements
type ResultHandle ¶
type ResultHandle struct {
// contains filtered or unexported fields
}
A ResultHandle is an opaque handle for a given result set, implementing the DataHandler interface.
It contains a channel over which the client will send the data as it comes in allowing results to be streamed as they are retrieved. It also contains a handle to the original client that the result came from.
func (*ResultHandle) Cancel ¶
func (r *ResultHandle) Cancel()
Cancel will cancel the currently calculating query. Calls to Next can still be used to drain any remaining record batches.
func (*ResultHandle) Close ¶
func (r *ResultHandle) Close() error
Close the channel and remove the query handler from the client
func (*ResultHandle) GetCols ¶
func (r *ResultHandle) GetCols() []string
GetCols grabs the column names from the record batch definition.
This will potentially block on the data channel if we have not yet recieved the first record batch. If the query failed or otherwise then this will return an empty slice.
Example ¶
// using sample nation data set from Drill repo rh := getTestResultHandle(basicData) cols := rh.GetCols() for _, c := range cols { fmt.Println(c) }
Output: N_NATIONKEY N_NAME N_REGIONKEY N_COMMENT
func (*ResultHandle) GetRecordBatch ¶
func (r *ResultHandle) GetRecordBatch() RowBatch
GetRecordBatch will return the current record batch, if we have not yet recieved one it will attempt to check the channel and block for the first batch. If this returns nil then that means there is no data and calling Next will return the status.
Example ¶
// using sample nation data set from Drill repo rh := getTestResultHandle(basicData) // at the start the record batch is nil, so the first call will grab from the channel rb := rh.GetRecordBatch() fmt.Printf("Num Cols: %d\n", rb.NumCols()) fmt.Printf("Rows in this Batch: %d\n", rb.NumRows()) // 0 affected rows since this wasn't an insert / update fmt.Printf("Affected Rows: %d\n", rb.AffectedRows()) for idx, f := range rh.GetCols() { fmt.Printf("Col %d: %s\tNullable: %#v\tType: %s\n", idx, f, rb.IsNullable(idx), rb.TypeName(idx)) } // we didn't call Next, so GetRecordBatch still returns the same batch we're on batch := rh.GetRecordBatch() fmt.Println(rb == batch)
Output: Num Cols: 4 Rows in this Batch: 9 Affected Rows: 0 Col 0: N_NATIONKEY Nullable: false Type: BIGINT Col 1: N_NAME Nullable: false Type: VARBINARY Col 2: N_REGIONKEY Nullable: false Type: BIGINT Col 3: N_COMMENT Nullable: false Type: VARBINARY true
Example (Arrow) ¶
// use sample nation data set from drill repo, use arrow impl rh := getTestResultHandle(arrowData) // at the start the record batch is nil so the first call will grab from the channel rb := rh.GetRecordBatch() fmt.Printf("Num Cols: %d\n", rb.NumCols()) fmt.Printf("Rows in this Batch: %d\n", rb.NumRows()) // 0 affected rows since this wasn't an insert / update fmt.Printf("Affected Rows: %d\n", rb.AffectedRows()) for idx, f := range rh.GetCols() { fmt.Printf("Col %d: %s\tNullable: %#v\tType: %s\n", idx, f, rb.IsNullable(idx), rb.TypeName(idx)) }
Output: Num Cols: 4 Rows in this Batch: 9 Affected Rows: 0 Col 0: N_NATIONKEY Nullable: false Type: BIGINT Col 1: N_NAME Nullable: false Type: VARBINARY Col 2: N_REGIONKEY Nullable: false Type: BIGINT Col 3: N_COMMENT Nullable: false Type: VARBINARY
func (*ResultHandle) Next ¶
func (r *ResultHandle) Next() (RowBatch, error)
Next checks the data channel for the next record batch, dropping the reference to the current record batch.
Returns ¶
Next will return nil if it is successful in retrieving another record batch. Otherwise it will return io.EOF if the query completed successfully and there are no more record batches.
If there are no more record batches and the query did not complete successfully, it will return either an error wrapping ErrQueryFailed, or one of the other error types.
Example ¶
// using sample nation data set from Drill repo rh := getTestResultHandle(basicData) // iterate the batches batch, err := rh.Next() for ; err == nil; batch, err = rh.Next() { for i := int32(0); i < batch.NumRows(); i++ { for _, v := range batch.GetVectors() { val := v.Value(uint(i)) switch t := val.(type) { case []byte: fmt.Print("|", string(t)) default: fmt.Print("|", t) } } fmt.Println("|") } } fmt.Println(err == io.EOF)
Output: |0|ALGERIA|0| haggle. carefully final deposits detect slyly agai| |1|ARGENTINA|1|al foxes promise slyly according to the regular accounts. bold requests alon| |2|BRAZIL|1|y alongside of the pending deposits. carefully special packages are about the ironic forges. slyly special | |3|CANADA|1|eas hang ironic, silent packages. slyly regular packages are furiously over the tithes. fluffily bold| |4|EGYPT|4|y above the carefully unusual theodolites. final dugouts are quickly across the furiously regular d| |5|ETHIOPIA|0|ven packages wake quickly. regu| |6|FRANCE|3|refully final requests. regular, ironi| |7|GERMANY|3|l platelets. regular accounts x-ray: unusual, regular acco| |8|INDIA|2|ss excuses cajole slyly across the packages. deposits print aroun| |9|INDONESIA|2| slyly express asymptotes. regular deposits haggle slyly. carefully ironic hockey players sleep blithely. carefull| |10|IRAN|4|efully alongside of the slyly final dependencies. | |11|IRAQ|4|nic deposits boost atop the quickly final requests? quickly regula| |12|JAPAN|2|ously. final, express gifts cajole a| |13|JORDAN|4|ic deposits are blithely about the carefully regular pa| |14|KENYA|0| pending excuses haggle furiously deposits. pending, express pinto beans wake fluffily past t| |15|MOROCCO|0|rns. blithely bold courts among the closely regular packages use furiously bold platelets?| |16|MOZAMBIQUE|0|s. ironic, unusual asymptotes wake blithely r| |17|PERU|1|platelets. blithely pending dependencies use fluffily across the even pinto beans. carefully silent accoun| |18|CHINA|2|c dependencies. furiously express notornis sleep slyly regular accounts. ideas sleep. depos| |19|ROMANIA|3|ular asymptotes are about the furious multipliers. express dependencies nag above the ironically ironic account| |20|SAUDI ARABIA|4|ts. silent requests haggle. closely express packages sleep across the blithely| |21|VIETNAM|2|hely enticingly express accounts. even, final | |22|RUSSIA|3| requests against the platelets use never according to the quickly regular pint| |23|UNITED KINGDOM|3|eans boost carefully special requests. accounts are. carefull| |24|UNITED STATES|1|y final packages. slow foxes cajole quickly. quickly silent platelets breach ironic accounts. unusual pinto be| true
Example (Arrow) ¶
// use sample nation data set from Drill repo, with arrow impl rh := getTestResultHandle(arrowData) // iterate the batches for { batch, err := rh.Next() if err == io.EOF { break } if err != nil { fmt.Println(err) break } rec := batch.(ArrowBatch).Record defer rec.Release() for i := 0; int64(i) < rec.NumRows(); i++ { for _, col := range rec.Columns() { switch col.DataType().ID() { case arrow.BINARY: fmt.Print("|", col.(*array.Binary).ValueString(i)) case arrow.INT64: fmt.Print("|", col.(*array.Int64).Value(i)) } } fmt.Println("|") } }
Output: |0|ALGERIA|0| haggle. carefully final deposits detect slyly agai| |1|ARGENTINA|1|al foxes promise slyly according to the regular accounts. bold requests alon| |2|BRAZIL|1|y alongside of the pending deposits. carefully special packages are about the ironic forges. slyly special | |3|CANADA|1|eas hang ironic, silent packages. slyly regular packages are furiously over the tithes. fluffily bold| |4|EGYPT|4|y above the carefully unusual theodolites. final dugouts are quickly across the furiously regular d| |5|ETHIOPIA|0|ven packages wake quickly. regu| |6|FRANCE|3|refully final requests. regular, ironi| |7|GERMANY|3|l platelets. regular accounts x-ray: unusual, regular acco| |8|INDIA|2|ss excuses cajole slyly across the packages. deposits print aroun| |9|INDONESIA|2| slyly express asymptotes. regular deposits haggle slyly. carefully ironic hockey players sleep blithely. carefull| |10|IRAN|4|efully alongside of the slyly final dependencies. | |11|IRAQ|4|nic deposits boost atop the quickly final requests? quickly regula| |12|JAPAN|2|ously. final, express gifts cajole a| |13|JORDAN|4|ic deposits are blithely about the carefully regular pa| |14|KENYA|0| pending excuses haggle furiously deposits. pending, express pinto beans wake fluffily past t| |15|MOROCCO|0|rns. blithely bold courts among the closely regular packages use furiously bold platelets?| |16|MOZAMBIQUE|0|s. ironic, unusual asymptotes wake blithely r| |17|PERU|1|platelets. blithely pending dependencies use fluffily across the even pinto beans. carefully silent accoun| |18|CHINA|2|c dependencies. furiously express notornis sleep slyly regular accounts. ideas sleep. depos| |19|ROMANIA|3|ular asymptotes are about the furious multipliers. express dependencies nag above the ironically ironic account| |20|SAUDI ARABIA|4|ts. silent requests haggle. closely express packages sleep across the blithely| |21|VIETNAM|2|hely enticingly express accounts. even, final | |22|RUSSIA|3| requests against the platelets use never according to the quickly regular pint| |23|UNITED KINGDOM|3|eans boost carefully special requests. accounts are. carefull| |24|UNITED STATES|1|y final packages. slow foxes cajole quickly. quickly silent platelets breach ironic accounts. unusual pinto be|
Example (Cancelled) ¶
dc := make(chan *queryData) rh := &ResultHandle{dataChannel: dc} go func() { defer close(dc) dc <- &queryData{typ: int32(user.RpcType_QUERY_RESULT), msg: cancelledResult} }() _, err := rh.Next() if err == ErrQueryCancelled { fmt.Println(err.Error()) }
Output: drill: query cancelled
Example (Queryfailed) ¶
dc := make(chan *queryData) rh := &ResultHandle{dataChannel: dc} go func() { defer close(dc) dc <- &queryData{typ: int32(user.RpcType_QUERY_RESULT), msg: failureResult} }() _, err := rh.Next() if errors.Is(err, ErrQueryFailed) { fmt.Println(err.Error()) } // calling Next again with the closed channel just returns the same error _, err2 := rh.Next() fmt.Println(err.Error() == err2.Error())
Output: drill: query failed: Failure Error Test true
type RowBatch ¶
type RowBatch interface { NumCols() int NumRows() int32 AffectedRows() int32 IsNullable(index int) bool TypeName(index int) string PrecisionScale(index int) (precision, scale int64, ok bool) GetVectors() []DataVector ColumnName(i int) string }
RowBatch presents the interface for dealing with record batches so that we don't have to expose the object and can swap out our underlying implementation in the future if needed.
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
Package driver provides a driver compatible with the golang database/sql/driver standard package.
|
Package driver provides a driver compatible with the golang database/sql/driver standard package. |
internal
|
|
cmd/drillProto
Mainprog to update the protobuf definitions
|
Mainprog to update the protobuf definitions |
cmd/tmpl
Generator for templated type files
|
Generator for templated type files |
Package sasl provides the utilities for SASL authentication via gssapi
|
Package sasl provides the utilities for SASL authentication via gssapi |