backend

package
v0.0.0-...-6e34275 Latest Latest
Warning

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

Go to latest
Published: Sep 19, 2026 License: Apache-2.0 Imports: 44 Imported by: 0

Documentation

Overview

Copyright 2024-2025 ApeCloud, Ltd.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Copyright 2024-2025 ApeCloud, Ltd.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Copyright 2024-2025 ApeCloud, Ltd.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ApplyQueryRowLimit

func ApplyQueryRowLimit(ctx *sql.Context, schema sql.Schema, iter sql.RowIter) sql.RowIter

ApplyQueryRowLimit wraps result rows with the limit configured on the current session. Non-row results and sessions with no limit are unchanged.

func IsPureDataQuery

func IsPureDataQuery(ctx *sql.Context, n sql.Node) bool

IsPureDataQuery inspects if the plan is a pure data query, i.e., it operates on (>=1) data tables and does not touch any system tables. The following examples are NOT pure data queries: - `SELECT * FROM mysql.*` - `TRUNCATE mysql.user` - `SELECT DATABASE()`

func IsWriteQueryText

func IsWriteQueryText(query string) bool

IsWriteQueryText classifies statements that could not be parsed by the protocol-specific engine. Parsed statements should use their AST instead.

func NewSessionBuilder

func NewSessionBuilder(provider *catalog.DatabaseProvider, opts ...SessionOption) func(ctx context.Context, conn *mysql.Conn, addr string) (sql.Session, error)

NewSessionBuilder returns a session builder for the given database provider.

func QueryForJSONScan

func QueryForJSONScan(query string, schema sql.Schema) string

QueryForJSONScan casts JSON result columns to VARCHAR before the DuckDB Go driver can collapse JSON null into SQL NULL.

func RegisterImplicitTransactionCleanupForContext

func RegisterImplicitTransactionCleanupForContext(
	ctx *sql.Context,
	tx sql.Transaction,
	callback func() error,
) func(success bool)

RegisterImplicitTransactionCleanupForContext lets wrappers avoid a direct type assertion while keeping the concrete implementation in this package.

func RegisterPostPhysicalTransactionCleanupForContext

func RegisterPostPhysicalTransactionCleanupForContext(
	ctx *sql.Context,
	tx *stdsql.Tx,
	release func(success bool),
) bool

RegisterPostPhysicalTransactionCleanupForContext lets protocol adapters defer an operation release until a raw database/sql transaction has been finalized. It is deliberately optional so narrow session doubles retain the legacy iterator-close behavior.

func RemoveAllPipes

func RemoveAllPipes(dataDir string) error

func RewriteIncomingQuery

func RewriteIncomingQuery(query string) string

RewriteIncomingQuery applies the default request modifiers. Tests and protocol handlers use this so replica-dump DDL is rewritten the same way as live MySQL connections.

func RewriteSQLRelations

func RewriteSQLRelations(query string, routes map[string]string) (string, bool)

RewriteSQLRelations replaces table references in relation positions. It is intentionally a small lexer rather than strings.Replace: quoted literals, dollar-quoted bodies, and comments may contain table-looking text and must remain untouched.

Routes are keyed by an unquoted, case-insensitive relation name. A qualified key (for example, "app.orders") takes precedence over a bare table key. Values are emitted verbatim and are expected to be trusted, already-quoted DuckDB identifiers supplied by the catalog layer.

func WrapHandler

func WrapHandler(
	provider *catalog.DatabaseProvider,
	engine *sqle.Engine,
	newContext func(context.Context, *mysql.Conn, string) (*sql.Context, error),
	readOnly bool,
) server.HandlerWrapper

func WrapRowIterWithLeases

func WrapRowIterWithLeases(
	ctx *sql.Context,
	iter sql.RowIter,
	snapshotRelease func(),
	operationRelease func(),
) sql.RowIter

WrapRowIterWithLeases is the legacy explicit split entry point. The snapshot lease is released at child termination; operationRelease is deferred until a logical transaction's post-finalization hook when one is available. Callers that already hold an atomic physical transaction should use WrapRowIterWithLeasesAndTx so wrapper construction never performs a binding lookup.

func WrapRowIterWithLeasesAndTx

func WrapRowIterWithLeasesAndTx(
	ctx *sql.Context,
	iter sql.RowIter,
	physicalTx *stdsql.Tx,
	snapshotRelease func(),
	operationRelease func(),
) sql.RowIter

WrapRowIterWithLeasesAndTx is the binding-aware exported entry point for protocol adapters that already hold an atomic execution snapshot. Passing physicalTx avoids a second lifecycle lookup while the snapshot lease is active; the legacy four-argument function remains available for adapters that do not expose a physical transaction.

func WrapRowIterWithRelease

func WrapRowIterWithRelease(iter sql.RowIter, release func()) sql.RowIter

WrapRowIterWithRelease keeps a caller-owned lifecycle lease until the wrapped iterator has been fully consumed or explicitly closed. The release callback is invoked at most once, after the child iterator is closed, and the wrapper preserves the mutable-child and ValueRowIter behavior used by GMS execution nodes.

This is intentionally a thin export of the same wrapper used for the provider's DuckLake operation lease. PostgreSQL protocol paths can therefore retain an execution snapshot without introducing a second iterator lifetime implementation.

Types

type DuckBuilder

type DuckBuilder struct {
	FlushDeltaBuffer func(*sql.Context) error
	// contains filtered or unexported fields
}

func NewDuckBuilder

func NewDuckBuilder(base *rowexec.BaseBuilder, provider *catalog.DatabaseProvider) *DuckBuilder

func NewEngine

func NewEngine(provider *catalog.DatabaseProvider) (*sqle.Engine, *DuckBuilder)

NewEngine constructs the MySQL engine with MyDuck's parser and executor compatibility boundaries installed consistently.

func (*DuckBuilder) Build

func (b *DuckBuilder) Build(ctx *sql.Context, root sql.Node, r sql.Row) (iter sql.RowIter, err error)

func (*DuckBuilder) CreatePipe

func (h *DuckBuilder) CreatePipe(ctx *sql.Context, subdir string) (string, error)

func (*DuckBuilder) Provider

func (b *DuckBuilder) Provider() *catalog.DatabaseProvider

type ImplicitTransactionCleanupRegistrar

type ImplicitTransactionCleanupRegistrar interface {
	RegisterImplicitTransactionCleanup(*sql.Context, sql.Transaction, func() error) func(success bool)
}

ImplicitTransactionCleanupRegistrar is implemented by sessions that can retain a callback for the GMS autocommit transaction. GMS clears an implicitly-created transaction with SetTransaction(nil), which has no error return and no context argument; the callback gives the session a chance to close the statement iterator and release its operation/connection leases before it performs the compensating rollback.

type MyHandler

type MyHandler struct {
	*server.Handler
	// contains filtered or unexported fields
}

func (*MyHandler) ComBind

func (h *MyHandler) ComBind(ctx context.Context, c *mysql.Conn, query string, parsedQuery mysql.ParsedQuery, prepare *mysql.PrepareData) (mysql.BoundQuery, []*querypb.Field, error)

func (*MyHandler) ComExecuteBound

func (h *MyHandler) ComExecuteBound(ctx context.Context, c *mysql.Conn, query string, boundQuery mysql.BoundQuery, callback mysql.ResultSpoolFn) (returnErr error)

func (*MyHandler) ComInitDB

func (h *MyHandler) ComInitDB(c *mysql.Conn, schemaName string) error

func (*MyHandler) ComMultiQuery

func (h *MyHandler) ComMultiQuery(
	ctx context.Context,
	c *mysql.Conn,
	query string,
	callback mysql.ResultSpoolFn,
) (rest string, returnErr error)

func (*MyHandler) ComParsedQuery

func (h *MyHandler) ComParsedQuery(ctx context.Context, c *mysql.Conn, query string, parsed sqlparser.Statement, callback mysql.ResultSpoolFn) (returnErr error)

func (*MyHandler) ComPrepare

func (h *MyHandler) ComPrepare(ctx context.Context, c *mysql.Conn, query string, prepare *mysql.PrepareData) ([]*querypb.Field, error)

func (*MyHandler) ComPrepareParsed

func (h *MyHandler) ComPrepareParsed(ctx context.Context, c *mysql.Conn, query string, parsed sqlparser.Statement, prepare *mysql.PrepareData) (mysql.ParsedQuery, []*querypb.Field, error)

func (*MyHandler) ComQuery

func (h *MyHandler) ComQuery(
	ctx context.Context,
	c *mysql.Conn,
	query string,
	callback mysql.ResultSpoolFn,
) (returnErr error)

Naive query rewriting. This is just a temporary solution and should be replaced with a more robust implementation.

func (*MyHandler) ComStmtExecute

func (h *MyHandler) ComStmtExecute(ctx context.Context, c *mysql.Conn, prepare *mysql.PrepareData, callback func(*sqltypes.Result) error) (returnErr error)

func (*MyHandler) ConnectionClosed

func (h *MyHandler) ConnectionClosed(c *mysql.Conn)

type PhysicalPostTransactionCleanupRegistrar

type PhysicalPostTransactionCleanupRegistrar interface {
	RegisterPostPhysicalTransactionCleanup(*sql.Context, *stdsql.Tx, func(success bool)) bool
}

PhysicalPostTransactionCleanupRegistrar is the protocol-facing counterpart for a raw database/sql transaction which is finalized outside GMS's TransactionSession callbacks.

type PostTransactionCleanupRegistrar

type PostTransactionCleanupRegistrar interface {
	RegisterPostTransactionCleanup(*sql.Context, sql.Transaction, func(success bool)) bool
}

PostTransactionCleanupRegistrar is implemented by sessions that can retain a callback until a logical GMS transaction has physically and logically finished. The callback receives true only for a successful commit; rollback and every failed finalization receive false.

type QueryAudit

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

QueryAudit records the outcome of one ordinary protocol query.

func NewQueryAudit

func NewQueryAudit(conn *mysql.Conn, protocol, query string) *QueryAudit

NewQueryAudit starts an audit record for a user-facing protocol query.

func (*QueryAudit) AddRows

func (audit *QueryAudit) AddRows(rows int)

AddRows records rows successfully handed to the protocol callback.

func (*QueryAudit) Complete

func (audit *QueryAudit) Complete(err error)

Complete emits the query's single structured audit record.

type RequestModifier

type RequestModifier func(string, *[]ResultModifier) string

RequestModifier is a function type that transforms a query string

type ResultModifier

type ResultModifier func(*sqltypes.Result) *sqltypes.Result

ResultModifier transforms a Result.

type SQLRowIter

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

SQLRowIter wraps a standard sql.Rows as a RowIter.

func NewSQLRowIter

func NewSQLRowIter(rows *stdsql.Rows, schema sql.Schema) (*SQLRowIter, error)

func (*SQLRowIter) Close

func (iter *SQLRowIter) Close(ctx *sql.Context) error

Close closes the underlying sql.Rows.

func (*SQLRowIter) Next

func (iter *SQLRowIter) Next(ctx *sql.Context) (sql.Row, error)

Next retrieves the next row. It will return io.EOF if it's the last row.

type Session

type Session struct {
	*memory.Session
	// contains filtered or unexported fields
}

func NewSession

func NewSession(base *memory.Session, provider *catalog.DatabaseProvider, opts ...SessionOption) *Session

func (*Session) AutocommitCleanupError

func (sess *Session) AutocommitCleanupError() error

AutocommitCleanupError observes the retained cleanup error without clearing it. It is useful to include the error in a surrounding protocol response before a later owner consumes it.

func (*Session) BeginDuckLakeOperation

func (sess *Session) BeginDuckLakeOperation(ctx context.Context) func()

BeginDuckLakeOperation reserves provider-wide admission for a top-level frontend statement. Keeping this small forwarding method on the session lets the execution builder use the session lifecycle without reaching into provider internals or changing the existing ConnectionHolder contract.

func (*Session) BeginDuckLakeOperationWithError

func (sess *Session) BeginDuckLakeOperationWithError(ctx context.Context) (func(), error)

BeginDuckLakeOperationWithError is the production admission surface used by execution builders that can return an error. Keeping the error-bearing form here prevents a poisoned provider generation from being represented as the legacy no-op release closure.

func (*Session) CloseConn

func (sess *Session) CloseConn()

CloseConn implements adapter.ConnectionHolder.

func (*Session) CloseConnIf

func (sess *Session) CloseConnIf(conn *stdsql.Conn) error

CloseConnIf implements adapter.IdentityConnectionCloser.

func (*Session) CloseConnIfBinding

func (sess *Session) CloseConnIfBinding(conn *stdsql.Conn, tx *stdsql.Tx) error

CloseConnIfBinding implements adapter.IdentityConnectionBindingCloser. Pool teardown verifies the exact physical connection and transaction pair while holding the session lifecycle lock.

func (*Session) CloseTxn

func (sess *Session) CloseTxn()

CloseTxn implements adapter.ConnectionHolder.

func (*Session) CloseTxnIf

func (sess *Session) CloseTxnIf(tx *stdsql.Tx)

CloseTxnIf implements adapter.IdentityTransactionCloser.

func (*Session) CommandBegin

func (sess *Session) CommandBegin() error

CommandBegin and CommandEnd opt the session into GMS lifecycle callbacks. MyDuck does not need per-command bookkeeping, but implementing the optional interface is important because SessionEnd is the only callback GMS gives an integrator when a MySQL session is reset or disconnected.

func (*Session) CommandEnd

func (sess *Session) CommandEnd()

func (*Session) CommitTransaction

func (sess *Session) CommitTransaction(ctx *sql.Context, tx sql.Transaction) error

CommitTransaction implements sql.TransactionSession.

func (*Session) CommitTxn

func (sess *Session) CommitTxn(tx *stdsql.Tx) error

CommitTxn implements adapter.TransactionFinalizer. The pool performs the driver operation and identity check while holding its lifecycle lock, so a delayed GMS callback cannot finalize or evict a replacement transaction.

func (*Session) ConsumeAutocommitCleanupError

func (sess *Session) ConsumeAutocommitCleanupError() error

ConsumeAutocommitCleanupError is an explicit alias for callers that prefer the verb used by other session error queues.

func (*Session) CurrentSchemaOfUnderlyingConn

func (sess *Session) CurrentSchemaOfUnderlyingConn() string

func (*Session) ExecContext

func (sess *Session) ExecContext(ctx context.Context, query string, args ...any) (stdsql.Result, error)

func (*Session) GetCatalogConn

func (sess *Session) GetCatalogConn(ctx context.Context) (*stdsql.Conn, error)

GetCatalogConn implements adapter.ConnectionHolder.

func (*Session) GetCatalogTxn

func (sess *Session) GetCatalogTxn(ctx context.Context, options *stdsql.TxOptions) (*stdsql.Tx, error)

GetCatalogTxn implements adapter.ConnectionHolder.

func (*Session) GetConn

func (sess *Session) GetConn(ctx context.Context) (*stdsql.Conn, error)

GetConn implements adapter.ConnectionHolder.

func (*Session) GetCurrentCatalog

func (sess *Session) GetCurrentCatalog() string

GetCurrentCatalog implements adapter.ConnectionHolder.

func (*Session) GetCurrentSchema

func (sess *Session) GetCurrentSchema() string

GetCurrentSchema implements adapter.ConnectionHolder.

func (*Session) GetExecutionSnapshot

func (sess *Session) GetExecutionSnapshot(ctx context.Context, catalogOnly bool) (*stdsql.Conn, *stdsql.Tx, error)

GetExecutionSnapshot implements adapter.ExecutionSnapshotHolder. The pool selects the physical owner and transaction under one lifecycle lock; catalog snapshots deliberately avoid changing the current schema.

func (*Session) GetExecutionSnapshotLease

func (sess *Session) GetExecutionSnapshotLease(
	ctx context.Context,
	catalogOnly bool,
) (*stdsql.Conn, *stdsql.Tx, func(), error)

GetExecutionSnapshotLease implements adapter.ExecutionSnapshotLeaseHolder. The returned release callback keeps the selected pool generation alive until the caller has finished consuming its iterator.

func (*Session) GetPersistedValue

func (sess *Session) GetPersistedValue(k string) (interface{}, error)

GetPersistedValue implements sql.PersistableSession.

func (*Session) GetTxn

func (sess *Session) GetTxn(ctx context.Context, options *stdsql.TxOptions) (*stdsql.Tx, error)

GetTxn implements adapter.ConnectionHolder.

func (*Session) GetTxnBinding

func (sess *Session) GetTxnBinding() (*stdsql.Conn, *stdsql.Tx)

GetTxnBinding implements adapter.TransactionBindingHolder. The pool returns the physical connection and transaction from one lifecycle snapshot.

func (*Session) GetTxnBindingForRelease

func (sess *Session) GetTxnBindingForRelease() (*stdsql.Conn, *stdsql.Tx)

GetTxnBindingForRelease implements adapter.ReleaseTransactionBindingHolder. Close/finalizer paths may still capture this snapshot after pool shutdown has been announced; the pool admits it through the release lifecycle gate.

func (*Session) HasImplicitTransactionCleanup

func (sess *Session) HasImplicitTransactionCleanup(tx sql.Transaction) bool

HasImplicitTransactionCleanup reports whether tx is currently backed by the frontend implicit-autocommit marker. Iterator wrappers use this distinction before registering a pre-finalization callback: explicit transactions and MySQL's DDL transaction wrapper intentionally have no such marker, and a failed registration must not close their live child iterator immediately.

func (*Session) PersistGlobal

func (sess *Session) PersistGlobal(ctx *sql.Context, sysVarName string, value interface{}) error

PersistGlobal implements sql.PersistableSession.

func (*Session) Provider

func (sess *Session) Provider() *catalog.DatabaseProvider

Provider returns the database provider for the session.

func (*Session) QueryRow

func (sess *Session) QueryRow(ctx context.Context, query string, args ...any) *adapter.LeasedRow

func (*Session) QueryRowLimit

func (sess *Session) QueryRowLimit() uint64

QueryRowLimit returns the maximum number of rows a query may return. Zero means unlimited.

func (*Session) RegisterImplicitTransactionCleanup

func (sess *Session) RegisterImplicitTransactionCleanup(
	ctx *sql.Context,
	tx sql.Transaction,
	callback func() error,
) func(success bool)

RegisterImplicitTransactionCleanup attaches a resource-release callback to the currently tracked GMS implicit transaction. The returned handle is a success-path disarmer: false is intentionally a no-op (the callback carries terminal failure state), while true disarms the marker after a successful commit. Resource callbacks are run by CommitTransaction or the rollback path, never by the success handle itself.

The callback is intentionally allowed to return an error, but the handle has no error result because it is normally called from iterator/finalizer paths that cannot return one. Such errors are retained by the session and exposed through TakeAutocommitCleanupError. SetTransaction(nil) still performs the rollback when a callback fails.

func (*Session) RegisterPostPhysicalTransactionCleanup

func (sess *Session) RegisterPostPhysicalTransactionCleanup(
	_ *sql.Context,
	tx *stdsql.Tx,
	callback func(success bool),
) bool

RegisterPostPhysicalTransactionCleanup retains a callback for a raw database/sql transaction finalized directly by a protocol adapter. This is used by PostgreSQL's extended/COPY paths, whose transaction controls bypass GMS's logical TransactionSession methods.

func (*Session) RegisterPostTransactionCleanup

func (sess *Session) RegisterPostTransactionCleanup(
	_ *sql.Context,
	tx sql.Transaction,
	callback func(success bool),
) bool

RegisterPostTransactionCleanup retains a callback until the supplied logical transaction has completed. Unlike the pre-finalization implicit hook, this callback is deliberately not run by iterator close: an operation lease must remain admitted while commit/rollback is still deciding the transaction's outcome. If registration races a completed transaction, the callback is invoked immediately with the recorded outcome.

func (*Session) RemoveAllPersistedGlobals

func (sess *Session) RemoveAllPersistedGlobals() error

RemoveAllPersistedGlobals implements sql.PersistableSession.

func (*Session) RemovePersistedGlobal

func (sess *Session) RemovePersistedGlobal(sysVarName string) error

RemovePersistedGlobal implements sql.PersistableSession.

func (*Session) Rollback

func (sess *Session) Rollback(ctx *sql.Context, tx sql.Transaction) error

Rollback implements sql.TransactionSession.

func (*Session) RollbackTxn

func (sess *Session) RollbackTxn(tx *stdsql.Tx) (*stdsql.Conn, bool, error)

RollbackTxn implements adapter.TransactionFinalizer. The returned connection is the exact physical owner of tx and may be reused for post-rollback maintenance only when inactive is true.

func (*Session) RollbackTxnWithCleanup

func (sess *Session) RollbackTxnWithCleanup(tx *stdsql.Tx, cleanup func(*stdsql.Conn) error) (bool, error)

RollbackTxnWithCleanup keeps the session lifecycle lock held while the caller performs same-connection post-rollback maintenance.

func (*Session) SessionEnd

func (sess *Session) SessionEnd()

SessionEnd rolls back the exact logical transaction still owned by this session. GMS invokes this callback from SessionManager while replacing or removing a connection; the request context that started the transaction may already be canceled, so use a fresh, non-cancelable frontend context. The embedded setter is used only after rollback and only when the identity is unchanged, preserving a replacement transaction installed by a concurrent lifecycle path.

func (*Session) SetSessionVariable

func (sess *Session) SetSessionVariable(ctx *sql.Context, name string, value interface{}) error

func (*Session) SetTransaction

func (sess *Session) SetTransaction(tx sql.Transaction)

SetTransaction overrides the embedded BaseSession setter so GMS's clearAutocommitOnError path becomes a real rollback boundary. The setter has no error return, therefore callback/rollback failures are retained for the protocol layer to consume through TakeAutocommitCleanupError.

func (*Session) StartTransaction

func (sess *Session) StartTransaction(ctx *sql.Context, tCharacteristic sql.TransactionCharacteristic) (sql.Transaction, error)

StartTransaction implements sql.TransactionSession.

func (*Session) TakeAutocommitCleanupError

func (sess *Session) TakeAutocommitCleanupError() error

TakeAutocommitCleanupError returns and clears errors retained by an implicit rollback/lease cleanup path. SetTransaction cannot return an error, so GMS or a protocol adapter may consume this value after the original statement error has been recorded.

func (*Session) TryGetTxn

func (sess *Session) TryGetTxn() *stdsql.Tx

TryGetTxn implements adapter.ConnectionHolder.

func (*Session) TryGetTxnForRelease

func (sess *Session) TryGetTxnForRelease() *stdsql.Tx

TryGetTxnForRelease implements adapter.ReleaseTransactionHolder.

type SessionOption

type SessionOption func(*Session)

func WithQueryRowLimit

func WithQueryRowLimit(limit uint64) SessionOption

WithQueryRowLimit limits the number of rows returned by queries in a session. A limit of zero leaves query results unlimited.

type Transaction

type Transaction struct {
	memory.Transaction
	// contains filtered or unexported fields
}

Jump to

Keyboard shortcuts

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