teradata

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 10, 2026 License: Apache-2.0 Imports: 31 Imported by: 0

README

go-sql-teradata

Pure Go Teradata driver for database/sql.

I started creating this driver while working on another Go project and wanted to be able to connect to Teradata. The project is still in a very early phase and likely contains issues. If anyone out there is interested in using it and find any issues please let me know.

Install

go get github.com/atl3/go-sql-teradata

Basic Usage

Approach 1 - Using NewConnector

package main

import (
	"database/sql"
	"log"

	teradata "github.com/atl3/go-sql-teradata"
)

func main() {
	config := teradata.NewConfig()
	config.Host = "..."
	config.User = "..."
	config.Password = "..."

	cnctr, err := teradata.NewConnector(config)
	if err != nil {
		log.Fatal(err)
	}

	db := sql.OpenDB(cnctr)
	defer db.Close()
	//...
}

Approach 2 - Using DSN/Connection String

package main

import (
	"database/sql"
	"log"

	_ "github.com/atl3/go-sql-teradata"
)

func main() {
	db, err := sql.Open("teradata", "user:pass@host?COP=OFF&...")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()
    // ...
}

Config Options

URL Param names should follow the official JDBC driver names and values. Reference the JDBC documentation for detail descriptions of the values.

To date the connection options implemented are:

Base Options:
Config Option URL Param Description Allowed Default
Tmode TMODE Transaction Mode DEFAULT,TERA,ANSI DEFAULT (Server Default)
CopMode COP Enable/Disable COP Discovery ON,OFF ON
CopLast COPLAST Performs DNS lookup of coplast to end COP discovery ON,OFF ON
Timeout TIMEOUT Connection Timeout in Seconds >0 60
Partition PARTITION DBC/SQL
ConnectFunction CONNECT_FUNCTION 0,1,2 0
MaxMessageSize MAX_MESSAGE_BODY >0 2097152
EncryptData ENCRYPTDATA ON=Encrypt query data when not using TLS connection, OFF=Only encrypt authentication ON,OFF OFF
TLS Options:
Config Option URL Param Description Allowed Default
SSLMode SSLMODE TLS Connection Mode (see JDBC connection string reference) DISABLE,ALLOW,PREFER,REQUIRE,VERIFY-CA,VERIFY-FULL PREFER
SSLProtocol SSLPROTOCOL TLS Protocol Version for TLS Connections TLSv1.3
SSLServerName SSLSERVERNAME For TLS hostname verification
SSLCA SSLCA Path to single PEM file
SSLCAPath SSLCAPATH Path to directory containing PEM files
SSLBase64 SSLBASE64 Base64 encoded contents of PEM file
SSLPort HTTPS_PORT Port to use for TLS connections 443
LOB Options:
Config Option URL Param Description Allowed Default
LOBSupport LOB_SUPPORT Enable/Disable LOB support ON,OFF ON
LOBRecieveThreshold SLOB_RECEIVE_THRESHOLD Threshold for inlining LOBs - use to tune memory usage >0 1000
LOBPrefetch LOB_PREFETCH Prefetch LOBs on rows.Next() - allows you to scan as string/[]byte directly but will have a negative memory impact for large LOBs ON,OFF OFF
FastLoad Options:
Config Option URL Param Description Allowed Default
MaxFastLoadSessions MAX_FASTLOAD_SESSIONS Max number of fastload data sessions >0 8

TLS

By default the driver using SSLMode=Prefer and port 443. This means it will first attempt to connect with TLS on port 443 but won't enforce any certificate or hostname validations. Additionally it will fallback to the non-TLS port (1025 by default) if unable to establish a TLS connection.

  • Setting SSLMode=REQUIRE will disable the fallback
  • Setting SSLMode=VERIFY-CA will additionally enforce certification validations using one or more of the SSLCA/Base64 params
  • Setting SSLMode=VERIFY-FULL will additionally enforce hostname validations.

LOB Support

LOB support is enabled by default. If its not-needed you can reduce some overhead by disabling it using LOBSupport=false config option.

By default LOBs won't be pre-fetched. Small LOBs will be inline from the server and available immediatly but large LOBs will require additional IO with the server to retreive. Example non-prefetched LOB usage (supressing err checks):

import (
	"database/sql"
	"github.com/atl3/go-sql-teradata"
)

func main() {
    ...
    var (
        id int64
        clob teradata.TeradataClob
        blob teradata.TeradataBlob
    )
    for rows.Next() {
        err := rows.Scan(&id, &clob, &blob)
        clobVal, err := clob.GetString()
        blobVal, err := blob.GetBytes()
        ...
    }
    ...
}

If you are working with small LOBs and want to avoid using TeradataClob/TeradataBlob you can enable LOB Prefetch and read directly to string/byte:


func main() {
    ...
    var (
        id int64
        clob sql.NullString
        blob []byte
    )
    for rows.Next() {
        err := rows.Scan(&id, &clob, &blob)
        ...
    }
    ...
}

FastLoad

Example:

import (
	"context"
	"fmt"
	"log"
	"time"

	teradata "github.com/atl3/go-sql-teradata"
)

func fastLoadDemo() {
	cfg := &teradata.Config{
		Host:     "...",
		User:     "...",
		Password: "...",
	}
	ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
	defer cancel()

	// Create Connection
	fcon, err := teradata.NewFastLoadConnection(cfg)
	if err != nil {
		log.Fatal(err)
	}
	defer fcon.Close()

	// Begin Load
	tx, err := fcon.BeginFastLoad(ctx, "DATABASE_NAME", "TABLE_NAME", "COL1", "COL2") // ...
	if err != nil {
		log.Fatal(err)
	}
	defer tx.Close()

	// Load
	for i := range 10000 {
		_, err = tx.AddRow(ctx, i+500, fmt.Sprintf("FastLoad Demo %d", i))
		if err != nil {
			tx.Abort(ctx)
			log.Fatal(err)
		}
	}

	// End
	results, err := tx.End(ctx)
	fmt.Printf("RowsSent=%d, RowsAccepted=%d, UniqueViolations=%d\n", results.RowsSent, results.RowsAccepted, results.UniqueViolations)
	if len(results.Errors) > 0 {
		fmt.Println("Errors:")
		for _, e := range results.Errors {
			fmt.Printf(" - FastLoad Error: RowNumber=%d, Column=%s, ErrorCode=%d\n", e.RowNumber, e.Column, e.ErrorCode)
		}
	}
}

Logging

By default the driver won't log anything but you can enable trace logging as follows:

import (
	"log/slog"
	"github.com/atl3/go-sql-teradata"
)

func main() {
    handler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
        Level: slog.Level(-8),
    })
    logger := slog.New(handler)

    cfg := &teradata.Config{
        ....,
        Logger: logger,
    }
    connector, err := teradata.NewConnector(cfg)
    ...
}

Not Yet Implemented / TODOs

  • XML Data Type
  • Stored procedure support
  • ARRAY / structured UDT data types
  • Query Banding

NOTE:

Teradata is a registered trademark of Teradata Corporation. This project is an independent open-source driver and is not affiliated with, endorsed by, or sponsored by Teradata Corporation.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidConn           = errors.New("invalid connection")
	ErrShortRead             = errors.New("short read")
	ErrReadFail              = errors.New("read failed")
	ErrInternal              = errors.New("internal driver error")
	ErrInvalidResponse       = errors.New("invalid response")
	ErrNoSupportAuth         = errors.New("no support auth mechanisms")
	ErrNoSecureChannel       = errors.New("unable to acquire a secure channel")
	ErrNotImplemented        = errors.New("not implemented")
	ErrInvalidRead           = errors.New("invalid read")
	ErrInvalidMetadata       = errors.New("invalid metadata from db")
	ErrInvalidParamIndex     = errors.New("invalid param index")
	ErrTransactionInProgress = errors.New("transaction already in progress")
	ErrTlsUpgradeFail        = errors.New("tls websocket upgrade failure")
	ErrTlsCaFail             = errors.New("tls CA verification failed")
	ErrTlsHostFail           = errors.New("tls hostname verification failed")
	ErrInvalidLobSize        = errors.New("invalid lob length on read")
	ErrTd2InvalidAlg         = errors.New("only AES with GCM96 is supported")
	ErrFastConnectFailed     = errors.New("fastload connection failed")
	ErrFastLoadNotClosed     = errors.New("fastload transaction in progress, it must be closed before starting a new one")
	ErrFastLoadNoColumns     = errors.New("fastload columns are required")
	ErrFastLoadUnsupported   = errors.New("fastload not supported for this table")
	ErrFastLoadFinished      = errors.New("fastload transaction has already ended or been aborted")
)

Functions

func NewConnector

func NewConnector(cfg *Config) (driver.Connector, error)

Types

type Config

type Config struct {
	Host     string // Hostname / IP
	Port     int    // Port Number
	Database string // Database Name
	User     string // Username
	Password string // Password

	// Base Options
	TMode           string        // TMODE allowed="TERA,ANSI,DEFAULT"
	CopMode         bool          // COP default="ON" allowed="ON,OFF"
	CopLast         bool          // COPLAST default="ON" allowed="ON,OFF"
	Timeout         time.Duration // TIMEOUT default="60"
	Partition       string        // PARTITION default="DBC/SQL"
	ConnectFunction int           // CONNECT_FUNCTION default="0" allowed="0,1,2"
	MaxMessageSize  int           // MAX_MESSAGE_BODY default=2097152
	EncryptData     bool          // ENCRYPTDATA default="OFF" allowed="ON,OFF"

	// TLS Options
	SSLMode       string // SSLMODE default="PREFER" allowed="DISABLE,ALLOW,PREFER,REQUIRE,VERIFY-CA,VERIFY-FULL"
	SSLProtocol   string // SSLPROTOCOL default="TLSv1.3"
	SSLCipher     string // SSLCIPHER default=""
	SSLServerName string // SSLSERVERNAME default=""
	SSLCA         string // SSLCA
	SSLCAPath     string // SSLCAPATH
	SSLBase64     string // SSLBASE64
	SSLPort       int    // HTTPS_PORT

	// LOB Options
	LOBSupport          bool // LOB_SUPPORT default="OFF" allowed="ON,OFF"
	LOBRecieveThreshold int  // SLOB_RECEIVE_THRESHOLD default=1000
	LOBPrefetch         bool // LOB_PREFETCH  default="OFF" allowed="ON,OFF"

	// Fastload
	MaxFastLoadSessions int

	Logger *slog.Logger
	// contains filtered or unexported fields
}

func NewConfig added in v0.1.1

func NewConfig() *Config

func NewTeradataConfig

func NewTeradataConfig(host, user, pass string) *Config

func ParseDSN

func ParseDSN(dsn string) (*Config, error)

func (*Config) FormatDSN added in v0.1.1

func (c *Config) FormatDSN() string

func (*Config) ToDSN

func (c *Config) ToDSN() (string, error)

type FastLoadConnection added in v0.2.0

type FastLoadConnection interface {
	// Teardown Connections and Abort Open Transactions
	Close() error
	// Begin a Load
	BeginFastLoad(ctx context.Context, database string, table string, columns ...string) (FastLoadTx, error)
}

func NewFastLoadConnection added in v0.2.0

func NewFastLoadConnection(cfg *Config) (FastLoadConnection, error)

Create new Fast Load connection to bulk import data

type FastLoadErrorRow added in v0.2.0

type FastLoadErrorRow struct {
	RowNumber int
	ErrorCode int
	Column    string
}

type FastLoadResult added in v0.2.0

type FastLoadResult struct {
	RowsSent         int64
	RowsAccepted     int64
	Errors           []FastLoadErrorRow
	UniqueViolations int64
}

type FastLoadTx added in v0.2.0

type FastLoadTx interface {
	// Add row to queue
	AddRow(ctx context.Context, values ...driver.Value) (int, error)
	// Send all queued rows to server, blocks until ackd
	Flush(ctx context.Context) error
	// End loading
	End(ctx context.Context) (*FastLoadResult, error)
	// Abort load and rollback
	Abort(ctx context.Context) error
	// Close underlying data connections
	Close() error
}

type TeradataBlob

type TeradataBlob struct {
	// contains filtered or unexported fields
}

func (TeradataBlob) GetBytes

func (l TeradataBlob) GetBytes() ([]byte, error)

func (TeradataBlob) GetBytesContext

func (l TeradataBlob) GetBytesContext(ctx context.Context) ([]byte, error)

func (*TeradataBlob) Scan

func (l *TeradataBlob) Scan(src any) error

type TeradataClob

type TeradataClob struct {
	// contains filtered or unexported fields
}

func (TeradataClob) GetBytes

func (l TeradataClob) GetBytes() ([]byte, error)

func (TeradataClob) GetBytesContext

func (l TeradataClob) GetBytesContext(ctx context.Context) ([]byte, error)

func (*TeradataClob) GetString

func (l *TeradataClob) GetString() (string, error)

func (*TeradataClob) GetStringContext

func (l *TeradataClob) GetStringContext(ctx context.Context) (string, error)

func (*TeradataClob) Scan

func (l *TeradataClob) Scan(src any) error

type TeradataConnectionError

type TeradataConnectionError struct {
	Message string
}

func (*TeradataConnectionError) Error

func (e *TeradataConnectionError) Error() string

type TeradataDriver

type TeradataDriver struct {
}

func (TeradataDriver) Open

func (d TeradataDriver) Open(dsn string) (driver.Conn, error)

func (TeradataDriver) OpenConnector

func (d TeradataDriver) OpenConnector(dsn string) (driver.Connector, error)

type TeradataError

type TeradataError struct {
	Code    uint16
	Message string
}

func (*TeradataError) Error

func (e *TeradataError) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL