mycli

package
v0.27.0 Latest Latest
Warning

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

Go to latest
Published: Mar 1, 2026 License: Apache-2.0 Imports: 129 Imported by: 0

Documentation

Overview

Copyright 2020 Google LLC

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.

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.

System Variables Naming Convention: - Variables that correspond to java-spanner JDBC properties use the same names - Variables that are spanner-mycli specific MUST use CLI_ prefix - This ensures compatibility with existing JDBC tooling while clearly identifying custom extensions

This file contains the registry-based implementation of system variables

InterceptorLogger adapts zap logger to interceptor logger.

Index

Constants

View Source
const (
	DefaultAnalyzeColumns = "Rows:{{.Rows.Total}},Exec.:{{.ExecutionSummary.NumExecutions}},Total Latency:{{.Latency}}"
)

Variables

View Source
var (
	ErrNoTransaction             = errors.New("no active transaction")
	ErrNotInReadWriteTransaction = errors.New("not in read-write transaction")
	ErrNotInReadOnlyTransaction  = errors.New("not in read-only transaction")
	ErrNotInPendingTransaction   = errors.New("not in pending transaction")
)

Transaction state errors

View Source
var DefaultParsedAnalyzeColumns = lo.Must(customListToTableRenderDefs(DefaultAnalyzeColumns))

Functions

func GetExitCode

func GetExitCode(err error) int

GetExitCode returns the appropriate exit code based on the error type. It checks for ExitCodeError first and returns its exit code if found. Otherwise, it returns exitCodeSuccess for nil errors and exitCodeError for all other errors.

In the future, this function could be further enhanced to return different exit codes based on other error types, such as:

var validationErr *ValidationError
if errors.As(err, &validationErr) {
    return exitCodeValidationError // e.g., 2
}

This would require defining additional exit code constants.

func GetTerminalSize

func GetTerminalSize(w io.Writer) (int, error)

GetTerminalSize returns the width of the terminal for the given io.Writer. It attempts to type assert the writer to *os.File to get the file descriptor. Returns an error if the terminal size cannot be determined.

func InterceptorLogger

func InterceptorLogger(l *zap.Logger) logging.Logger

This code is simple enough to be copied and not imported.

func IsMetaCommand

func IsMetaCommand(line string) bool

IsMetaCommand checks if a line starts with a backslash (meta command)

func LinkTypePred

func LinkTypePred(typ string) func(cl *sppb.PlanNode_ChildLink) bool

func ListAvailableSamples

func ListAvailableSamples() string

ListAvailableSamples returns a formatted list of available sample databases

func Main

func Main(version, installFrom string)

Main is the entry point called from the root main package. version and installFrom are passed from main via ldflags.

func NewExitCodeError

func NewExitCodeError(exitCode int) error

NewExitCodeError creates a new ExitCodeError

func PS1PS2FuncToPromptFunc

func PS1PS2FuncToPromptFunc(ps1F func() string, ps2F func(ps1 string) string) func(w io.Writer, lnum int) (int, error)

func ParseStatements

func ParseStatements(content []byte, filename string) ([]string, error)

ParseStatements parses DDL or DML statements from SQL/SDL content using memefish

func SetLogLevel

func SetLogLevel(logLevel string) (slog.Level, error)

func ValidateSpannerOptions

func ValidateSpannerOptions(opts *spannerOptions) error

ValidateSpannerOptions validates the spannerOptions struct.

Types

type AbortBatchStatement

type AbortBatchStatement struct{}

func (*AbortBatchStatement) Execute

func (s *AbortBatchStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type AddSplitPointsStatement

type AddSplitPointsStatement struct {
	SplitPoints []*databasepb.SplitPoints
}

func (*AddSplitPointsStatement) Execute

func (s *AddSplitPointsStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type BatchDMLStatement

type BatchDMLStatement struct {
	DMLs []spanner.Statement
}

func (*BatchDMLStatement) Execute

func (s *BatchDMLStatement) Execute(ctx context.Context, session *Session) (*Result, error)

func (BatchDMLStatement) IsMutationStatement

func (BatchDMLStatement) IsMutationStatement()

type BatchInfo

type BatchInfo struct {
	Mode batchMode
	Size int
}

type BeginRoStatement

type BeginRoStatement struct {
	TimestampBoundType timestampBoundType
	Staleness          time.Duration
	Timestamp          time.Time
	Priority           sppb.RequestOptions_Priority
}

func (*BeginRoStatement) Execute

func (s *BeginRoStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type BeginRwStatement

type BeginRwStatement struct {
	IsolationLevel sppb.TransactionOptions_IsolationLevel
	Priority       sppb.RequestOptions_Priority
}

func (*BeginRwStatement) Execute

func (s *BeginRwStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type BeginStatement

type BeginStatement struct {
	IsolationLevel sppb.TransactionOptions_IsolationLevel
	Priority       sppb.RequestOptions_Priority
}

func (*BeginStatement) Execute

func (s *BeginStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type BufferedProcessor

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

BufferedProcessor collects all rows in memory before formatting. This is the traditional approach used by spanner-mycli.

func NewBufferedProcessor

func NewBufferedProcessor(formatter format.FormatFunc, out io.Writer, screenWidth int) *BufferedProcessor

NewBufferedProcessor creates a processor that collects all rows before formatting.

func (*BufferedProcessor) Finish

func (p *BufferedProcessor) Finish(stats QueryStats, rowCount int64) error

Finish formats and outputs all collected rows.

func (*BufferedProcessor) Init

func (p *BufferedProcessor) Init(metadata *sppb.ResultSetMetadata, sysVars *systemVariables) error

Init initializes the buffered processor with metadata.

func (*BufferedProcessor) ProcessRow

func (p *BufferedProcessor) ProcessRow(row Row) error

ProcessRow adds a row to the buffer.

type BulkDdlStatement

type BulkDdlStatement struct {
	Ddls []string
}

func (*BulkDdlStatement) Execute

func (s *BulkDdlStatement) Execute(ctx context.Context, session *Session) (*Result, error)

func (BulkDdlStatement) IsMutationStatement

func (BulkDdlStatement) IsMutationStatement()

func (*BulkDdlStatement) String

func (s *BulkDdlStatement) String() string

type CQLStatement

type CQLStatement struct {
	CQL string
}

Cassandra interface

func (*CQLStatement) Execute

func (cs *CQLStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type Cli

type Cli struct {
	SessionHandler  *SessionHandler
	Credential      []byte
	SystemVariables *systemVariables
	// contains filtered or unexported fields
}

func NewCli

func NewCli(ctx context.Context, credential []byte, sysVars *systemVariables) (*Cli, error)

func (*Cli) ExitOnError

func (c *Cli) ExitOnError(err error) int

func (*Cli) GetErrStream

func (c *Cli) GetErrStream() io.Writer

GetErrStream returns the error stream

func (*Cli) GetInStream

func (c *Cli) GetInStream() io.ReadCloser

GetInStream returns the input stream

func (*Cli) GetTerminalSizeWithTty

func (c *Cli) GetTerminalSizeWithTty(w io.Writer) (int, error)

GetTerminalSizeWithTty returns the width of the terminal. It uses the TtyOutStream from StreamManager if available, otherwise falls back to attempting to type assert the writer to *os.File. Returns an error if the terminal size cannot be determined.

func (*Cli) GetTtyStream

func (c *Cli) GetTtyStream() *os.File

GetTtyStream returns the TTY stream for terminal operations

func (*Cli) GetWriter

func (c *Cli) GetWriter() io.Writer

GetWriter returns the current output writer (with or without tee)

func (*Cli) PrintBatchError

func (c *Cli) PrintBatchError(err error)

func (*Cli) PrintInteractiveError

func (c *Cli) PrintInteractiveError(err error)

func (*Cli) PrintProgressingMark

func (c *Cli) PrintProgressingMark(w io.Writer) func()

func (*Cli) PrintResult

func (c *Cli) PrintResult(screenWidth int, result *Result, interactive bool, input string, w io.Writer) error

func (*Cli) RunBatch

func (c *Cli) RunBatch(ctx context.Context, input string) error

func (*Cli) RunInteractive

func (c *Cli) RunInteractive(ctx context.Context) error

func (*Cli) RunMCP

func (c *Cli) RunMCP(ctx context.Context) error

RunMCP runs the MCP server

type CommitStatement

type CommitStatement struct{}

func (*CommitStatement) Execute

func (s *CommitStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type CreateDatabaseStatement

type CreateDatabaseStatement struct {
	CreateStatement string
}

func (*CreateDatabaseStatement) Execute

func (s *CreateDatabaseStatement) Execute(ctx context.Context, session *Session) (*Result, error)

func (CreateDatabaseStatement) IsMutationStatement

func (CreateDatabaseStatement) IsMutationStatement()

func (*CreateDatabaseStatement) String

func (s *CreateDatabaseStatement) String() string

type CustomVar

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

CustomVar wraps a variable with custom getter/setter

func (*CustomVar) Description

func (c *CustomVar) Description() string

func (*CustomVar) Get

func (c *CustomVar) Get() (string, error)

func (*CustomVar) IsReadOnly

func (c *CustomVar) IsReadOnly() bool

func (*CustomVar) Set

func (c *CustomVar) Set(value string) error

type DMLResult

type DMLResult struct {
	Affected       int64                   // Total number of rows affected by the DML operation
	CommitResponse spanner.CommitResponse  // Commit response including timestamp and stats
	Plan           *sppb.QueryPlan         // Query execution plan (when requested)
	Metadata       *sppb.ResultSetMetadata // Metadata about the result set
}

DMLResult holds the results of a DML operation execution including commit information.

type DdlStatement

type DdlStatement struct {
	Ddl string
}

func (*DdlStatement) Execute

func (s *DdlStatement) Execute(ctx context.Context, session *Session) (*Result, error)

func (*DdlStatement) String

func (s *DdlStatement) String() string

type DependencyResolver

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

DependencyResolver manages table dependency resolution Note: This implementation works at the table level. For row-level dependency resolution that can handle circular FK relationships, see issue #438.

func NewDependencyResolver

func NewDependencyResolver() *DependencyResolver

NewDependencyResolver creates a new dependency resolver

func (*DependencyResolver) BuildDependencyGraphWithTxn

func (dr *DependencyResolver) BuildDependencyGraphWithTxn(ctx context.Context, txn *spanner.ReadOnlyTransaction) error

BuildDependencyGraphWithTxn queries the database and builds the complete dependency graph using a transaction

func (*DependencyResolver) GetDependencyInfo

func (dr *DependencyResolver) GetDependencyInfo(tableName string) (*TableDependency, error)

GetDependencyInfo returns detailed dependency information for a table

func (*DependencyResolver) GetOrderForTables

func (dr *DependencyResolver) GetOrderForTables(tablesToExport []string) ([]string, error)

GetOrderForTables returns specific tables in safe execution order

func (*DependencyResolver) GetTableOrder

func (dr *DependencyResolver) GetTableOrder() ([]string, error)

GetTableOrder returns all tables in safe execution order. It assumes that BuildDependencyGraph has already been called.

type DescribeStatement

type DescribeStatement struct {
	Statement string
	IsDML     bool // Whether the statement being described is a DML
}

func (*DescribeStatement) Execute

func (s *DescribeStatement) Execute(ctx context.Context, session *Session) (*Result, error)

Execute processes `DESCRIBE` statement for queries and DMLs.

func (*DescribeStatement) String

func (s *DescribeStatement) String() string

type DetachStatement

type DetachStatement struct {
	NopStatement
}

DetachStatement is actually implemented in cli.go because it needs to replace Session pointer in Cli.

type DetachedCompatible

type DetachedCompatible interface {
	// contains filtered or unexported methods
}

DetachedCompatible is a marker interface for statements that can run in Detached session mode (admin operation only mode). Statements implementing this interface can execute when session.IsDetached() is true.

type DisableOutputRedirectMetaCommand

type DisableOutputRedirectMetaCommand struct{}

DisableOutputRedirectMetaCommand disables output redirect using \o (with no args) syntax

func (*DisableOutputRedirectMetaCommand) Execute

func (d *DisableOutputRedirectMetaCommand) Execute(ctx context.Context, session *Session) (*Result, error)

Execute disables output redirect (returns to stdout)

type DisableTeeMetaCommand

type DisableTeeMetaCommand struct{}

DisableTeeMetaCommand disables output tee using \t syntax

func (*DisableTeeMetaCommand) Execute

func (d *DisableTeeMetaCommand) Execute(ctx context.Context, session *Session) (*Result, error)

Execute disables tee output

type DmlStatement

type DmlStatement struct {
	Dml string
}

func (*DmlStatement) Execute

func (s *DmlStatement) Execute(ctx context.Context, session *Session) (*Result, error)

func (*DmlStatement) String

func (s *DmlStatement) String() string

type DropDatabaseStatement

type DropDatabaseStatement struct {
	DatabaseId string
}

func (*DropDatabaseStatement) Execute

func (s *DropDatabaseStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type DumpDatabaseStatement

type DumpDatabaseStatement struct{}

DumpDatabaseStatement represents DUMP DATABASE statement It exports both DDL and data for all tables in the database

func (*DumpDatabaseStatement) Execute

func (s *DumpDatabaseStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type DumpSchemaStatement

type DumpSchemaStatement struct{}

DumpSchemaStatement represents DUMP SCHEMA statement It exports only DDL statements without any data

func (*DumpSchemaStatement) Execute

func (s *DumpSchemaStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type DumpTablesStatement

type DumpTablesStatement struct {
	Tables []string
}

DumpTablesStatement represents DUMP TABLES statement It exports data only for specified tables (no DDL)

func (*DumpTablesStatement) Execute

func (s *DumpTablesStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type EndpointVar

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

EndpointVar handles CLI_ENDPOINT (host:port)

func (*EndpointVar) Description

func (e *EndpointVar) Description() string

func (*EndpointVar) Get

func (e *EndpointVar) Get() (string, error)

func (*EndpointVar) IsReadOnly

func (e *EndpointVar) IsReadOnly() bool

func (*EndpointVar) Set

func (e *EndpointVar) Set(value string) error

type EnumVar

type EnumVar[T comparable] struct {
	// contains filtered or unexported fields
}

EnumVar handles enum-like variables

func AutocommitDMLModeVar

func AutocommitDMLModeVar(ptr *enums.AutocommitDMLMode, desc string) *EnumVar[enums.AutocommitDMLMode]

AutocommitDMLModeVar handles AUTOCOMMIT_DML_MODE using enumer-generated methods

func DisplayModeVar

func DisplayModeVar(ptr *enums.DisplayMode, desc string) *EnumVar[enums.DisplayMode]

DisplayModeVar creates an enum handler for DisplayMode

func ExplainFormatVar

func ExplainFormatVar(ptr *enums.ExplainFormat, desc string) *EnumVar[enums.ExplainFormat]

ExplainFormatVar creates an enum handler for ExplainFormat

func ParseModeVar

func ParseModeVar(ptr *enums.ParseMode, desc string) *EnumVar[enums.ParseMode]

ParseModeVar creates an enum handler for ParseMode

func StreamingModeVar

func StreamingModeVar(ptr *enums.StreamingMode, desc string) *EnumVar[enums.StreamingMode]

StreamingModeVar creates an enum handler for StreamingMode

func (*EnumVar[T]) Description

func (e *EnumVar[T]) Description() string

func (*EnumVar[T]) Get

func (e *EnumVar[T]) Get() (string, error)

func (*EnumVar[T]) IsReadOnly

func (e *EnumVar[T]) IsReadOnly() bool

func (*EnumVar[T]) Set

func (e *EnumVar[T]) Set(value string) error

func (*EnumVar[T]) ValidValues

func (e *EnumVar[T]) ValidValues() []string

ValidValues returns sorted valid values as GoogleSQL string literals.

type ErrAddNotSupported

type ErrAddNotSupported struct {
	Name string
}

ErrAddNotSupported is returned when ADD operation is not supported for a variable

func (*ErrAddNotSupported) Error

func (e *ErrAddNotSupported) Error() string

type ErrUnknownVariable

type ErrUnknownVariable struct {
	Name string
}

ErrUnknownVariable is returned when a variable name is not recognized

func (*ErrUnknownVariable) Error

func (e *ErrUnknownVariable) Error() string

type ExecuteStatementArgs

type ExecuteStatementArgs struct {
	Statement string `json:"statement" jsonschema:"Valid spanner-mycli statement to execute"`
}

ExecuteStatementArgs represents the arguments for the execute_statement tool

type ExitCodeError

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

ExitCodeError represents an error that only carries an exit code without a message

func (*ExitCodeError) Error

func (e *ExitCodeError) Error() string

Error implements the error interface

type ExitStatement

type ExitStatement struct {
	NopStatement
}

type ExplainAnalyzeDmlStatement

type ExplainAnalyzeDmlStatement struct {
	Dml    string
	Format enums.ExplainFormat
	Width  int64
}

func (*ExplainAnalyzeDmlStatement) Execute

func (s *ExplainAnalyzeDmlStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type ExplainAnalyzeStatement

type ExplainAnalyzeStatement struct {
	Query  string
	Format enums.ExplainFormat
	Width  int64
}

func (*ExplainAnalyzeStatement) Execute

func (s *ExplainAnalyzeStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type ExplainLastQueryStatement

type ExplainLastQueryStatement struct {
	Analyze bool
	Format  enums.ExplainFormat
	Width   int64
}

func (*ExplainLastQueryStatement) Execute

func (s *ExplainLastQueryStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type ExplainStatement

type ExplainStatement struct {
	Explain string
	IsDML   bool // Whether the statement being explained is a DML
	Format  enums.ExplainFormat
	Width   int64
}

func (*ExplainStatement) Execute

func (s *ExplainStatement) Execute(ctx context.Context, session *Session) (*Result, error)

Execute processes `EXPLAIN` statement for queries and DMLs.

func (*ExplainStatement) String

func (s *ExplainStatement) String() string

type FKReference

type FKReference struct {
	ConstraintName string `spanner:"CONSTRAINT_NAME"`
	ChildTable     string `spanner:"CHILD_TABLE"`
	ParentTable    string `spanner:"PARENT_TABLE"`
}

FKReference represents a foreign key relationship between tables

type GeminiStatement

type GeminiStatement struct {
	Text string
}

func (*GeminiStatement) Execute

func (s *GeminiStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type HelpStatement

type HelpStatement struct{}

func (*HelpStatement) Execute

func (s *HelpStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type HelpVariablesStatement

type HelpVariablesStatement struct{}

func (*HelpVariablesStatement) Execute

func (s *HelpVariablesStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type History

type History interface {
	readline.IHistory
	Add(string)
}

type IntGetterVar

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

IntGetterVar handles integer variables with custom getters

func (*IntGetterVar) Description

func (i *IntGetterVar) Description() string

func (*IntGetterVar) Get

func (i *IntGetterVar) Get() (string, error)

func (*IntGetterVar) IsReadOnly

func (i *IntGetterVar) IsReadOnly() bool

func (*IntGetterVar) Set

func (i *IntGetterVar) Set(value string) error

type LastQueryCache

type LastQueryCache struct {
	QueryPlan       *sppb.QueryPlan
	QueryStats      map[string]any
	ReadTimestamp   time.Time
	CommitTimestamp time.Time
}

type LogLevelVar

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

LogLevelVar handles CLI_LOG_LEVEL

func (*LogLevelVar) Description

func (l *LogLevelVar) Description() string

func (*LogLevelVar) Get

func (l *LogLevelVar) Get() (string, error)

func (*LogLevelVar) IsReadOnly

func (l *LogLevelVar) IsReadOnly() bool

func (*LogLevelVar) Set

func (l *LogLevelVar) Set(value string) error

func (*LogLevelVar) ValidValues

func (l *LogLevelVar) ValidValues() []string

ValidValues returns the standard log level names as GoogleSQL string literals.

type MetaCommandStatement

type MetaCommandStatement interface {
	Statement
	// contains filtered or unexported methods
}

MetaCommandStatement is a marker interface for meta commands (commands starting with \). Meta commands are not SQL statements and have special handling in the CLI.

type MutateStatement

type MutateStatement struct {
	Table     string
	Operation string
	Body      string
}

func (*MutateStatement) Execute

func (s *MutateStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type MutationStatement

type MutationStatement interface {
	// contains filtered or unexported methods
}

MutationStatement is a marker interface for mutation statements. Mutation statements are not permitted in a read-only transaction. It determines pending transactions.

type NopStatement

type NopStatement struct{}

func (*NopStatement) Execute

func (s *NopStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type OutputContext

type OutputContext struct {
	Verbose         bool
	IsExecutedDML   bool
	ReadTimestamp   string
	CommitTimestamp string
	Stats           *QueryStats
	CommitStats     *sppb.CommitResponse_CommitStats
	Metrics         *metrics.ExecutionMetrics
}

type OutputRedirectMetaCommand

type OutputRedirectMetaCommand struct {
	FilePath string
}

OutputRedirectMetaCommand redirects output to a file using \o syntax (PostgreSQL-style: file only)

func (*OutputRedirectMetaCommand) Execute

func (o *OutputRedirectMetaCommand) Execute(ctx context.Context, session *Session) (*Result, error)

Execute enables output redirect to the specified file (file only)

type PartitionStatement

type PartitionStatement struct{ SQL string }

func (*PartitionStatement) Execute

func (s *PartitionStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type PartitionedDmlStatement

type PartitionedDmlStatement struct {
	Dml string
}

func (*PartitionedDmlStatement) Execute

func (s *PartitionedDmlStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type PromptMetaCommand

type PromptMetaCommand struct {
	PromptString string
}

PromptMetaCommand changes the prompt string using \R syntax

func (*PromptMetaCommand) Execute

func (p *PromptMetaCommand) Execute(ctx context.Context, session *Session) (*Result, error)

Execute updates the CLI_PROMPT system variable

type ProtoDescriptorVar

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

ProtoDescriptorVar handles CLI_PROTO_DESCRIPTOR_FILE with ADD support

func (*ProtoDescriptorVar) Add

func (p *ProtoDescriptorVar) Add(value string) error

func (*ProtoDescriptorVar) Description

func (p *ProtoDescriptorVar) Description() string

func (*ProtoDescriptorVar) Get

func (p *ProtoDescriptorVar) Get() (string, error)

func (*ProtoDescriptorVar) IsReadOnly

func (p *ProtoDescriptorVar) IsReadOnly() bool

func (*ProtoDescriptorVar) Set

func (p *ProtoDescriptorVar) Set(value string) error

type ProtoEnumVar

type ProtoEnumVar[T ~int32] struct {
	// contains filtered or unexported fields
}

ProtoEnumVar handles Protocol Buffer enum variables

func ReadLockModeVar

ReadLockModeVar creates an enum handler for ReadLockMode

func (*ProtoEnumVar[T]) Description

func (p *ProtoEnumVar[T]) Description() string

func (*ProtoEnumVar[T]) Get

func (p *ProtoEnumVar[T]) Get() (string, error)

func (*ProtoEnumVar[T]) IsReadOnly

func (p *ProtoEnumVar[T]) IsReadOnly() bool

func (*ProtoEnumVar[T]) Set

func (p *ProtoEnumVar[T]) Set(value string) error

func (*ProtoEnumVar[T]) ValidValues

func (p *ProtoEnumVar[T]) ValidValues() []string

ValidValues returns sorted prefix-stripped valid values as GoogleSQL string literals.

type QueryIndexAdvice

type QueryIndexAdvice struct {
	DDL               []string
	ImprovementFactor float64
}

QueryIndexAdvice holds an index recommendation from the Spanner query advisor.

type QueryResult

type QueryResult struct {
	Iterator    *spanner.RowIterator
	Transaction *spanner.ReadOnlyTransaction
}

QueryResult holds the result of a query operation with optional transaction.

type QueryStats

type QueryStats struct {
	ElapsedTime                string `json:"elapsed_time"`
	CPUTime                    string `json:"cpu_time"`
	RowsReturned               string `json:"rows_returned"`
	RowsScanned                string `json:"rows_scanned"`
	DeletedRowsScanned         string `json:"deleted_rows_scanned"`
	OptimizerVersion           string `json:"optimizer_version"`
	OptimizerStatisticsPackage string `json:"optimizer_statistics_package"`
	RemoteServerCalls          string `json:"remote_server_calls"`
	MemoryPeakUsageBytes       string `json:"memory_peak_usage_bytes"`
	TotalMemoryPeakUsageByte   string `json:"total_memory_peak_usage_byte"`
	QueryText                  string `json:"query_text"`
	BytesReturned              string `json:"bytes_returned"`
	RuntimeCreationTime        string `json:"runtime_creation_time"`
	StatisticsLoadTime         string `json:"statistics_load_time"`
	MemoryUsagePercentage      string `json:"memory_usage_percentage"`
	FilesystemDelaySeconds     string `json:"filesystem_delay_seconds"`
	LockingDelay               string `json:"locking_delay"`
	QueryPlanCreationTime      string `json:"query_plan_creation_time"`
	ServerQueueDelay           string `json:"server_queue_delay"`
	DataBytesRead              string `json:"data_bytes_read"`
	IsGraphQuery               string `json:"is_graph_query"`
	RuntimeCached              string `json:"runtime_cached"`
	QueryPlanCached            string `json:"query_plan_cached"`

	Unknown jsontext.Value `json:",unknown" pp:"-"`
}

QueryStats contains query statistics. Some fields may not have a valid value depending on the environment. For example, only ElapsedTime and RowsReturned has valid value for Cloud Spanner Emulator.

type ReadOnlyVar

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

ReadOnlyVar creates a read-only variable with custom getter

func NewReadOnlyVar

func NewReadOnlyVar(getter func() string, desc string) *ReadOnlyVar

NewReadOnlyVar creates a new read-only variable

func (*ReadOnlyVar) Description

func (r *ReadOnlyVar) Description() string

func (*ReadOnlyVar) Get

func (r *ReadOnlyVar) Get() (string, error)

func (*ReadOnlyVar) IsReadOnly

func (r *ReadOnlyVar) IsReadOnly() bool

func (*ReadOnlyVar) Set

func (r *ReadOnlyVar) Set(value string) error

type Result

type Result struct {
	ColumnAlign      []tw.Align // optional
	Rows             []Row
	Predicates       []string
	AffectedRows     int
	AffectedRowsType rowCountType
	Stats            QueryStats

	// IsExecutedDML indicates this is an executed DML statement (INSERT/UPDATE/DELETE) that can report affected rows
	IsExecutedDML bool

	ReadTimestamp   time.Time // For SELECT/read-only transactions
	CommitTimestamp time.Time // For COMMIT/DML operations
	ForceVerbose    bool
	CommitStats     *sppb.CommitResponse_CommitStats
	KeepVariables   bool

	TableHeader TableHeader

	ForceWrap   bool
	LintResults []string
	IndexAdvice []QueryIndexAdvice // Index recommendations from query advisor
	PreInput    string

	// HasSQLFormattedValues indicates that the row values have been formatted as SQL literals
	// using spanvalue.LiteralFormatConfig instead of regular display formatting.
	// This flag is set to true only when:
	// - executeSQL is called with SQL export format (SQL_INSERT, SQL_INSERT_OR_IGNORE, SQL_INSERT_OR_UPDATE)
	// - The values in Rows are valid SQL literals that can be used in INSERT statements
	// When false, SQL export formats will fall back to table format to prevent invalid SQL generation.
	// Examples of statements that have this as false:
	// - SHOW CREATE TABLE, SHOW TABLES (metadata queries)
	// - EXPLAIN, EXPLAIN ANALYZE (query plan information)
	// - DML with THEN RETURN (uses regular formatting)
	HasSQLFormattedValues bool

	// IsDirectOutput indicates that Rows contain pre-formatted text lines that should
	// be printed directly without any table formatting. Used by DUMP statements and
	// potentially other commands that produce pre-formatted output.
	// When true, Rows bypass normal table formatting and are output as-is.
	IsDirectOutput bool

	// SQLTableNameForExport stores the auto-detected or explicitly set table name for SQL export.
	// This field is populated during query execution when SQL export formats are used.
	// It ensures the table name is available during the formatting phase, even in buffered mode.
	SQLTableNameForExport string

	BatchInfo      *BatchInfo
	PartitionCount int
	Streamed       bool                      // Indicates rows were streamed and not buffered
	Metrics        *metrics.ExecutionMetrics // Performance metrics for query execution
}

type RollbackStatement

type RollbackStatement struct{}

func (*RollbackStatement) Execute

func (s *RollbackStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type Row

type Row = format.Row

Row is a row of string values. It is a type alias for format.Row (= []string).

type RowIterResult

type RowIterResult struct {
	Metadata   *sppb.ResultSetMetadata
	Rows       iter.Seq[Row]
	QueryStats map[string]interface{}
	RowCount   int64
	QueryPlan  *sppb.QueryPlan
	Error      error
}

RowIterResult contains metadata and a row iterator sequence. The metadata is available immediately after the first row is fetched.

type RowProcessor

type RowProcessor interface {
	// Init is called once after metadata becomes available (after first row fetch).
	// This is where headers are written for formats like CSV, or table initialization occurs.
	Init(metadata *sppb.ResultSetMetadata, sysVars *systemVariables) error

	// ProcessRow is called for each row in the result set.
	// In buffered mode, rows are collected. In streaming mode, rows are output immediately.
	ProcessRow(row Row) error

	// Finish is called after all rows have been processed.
	// It receives final statistics and row count for summary output.
	Finish(stats QueryStats, rowCount int64) error
}

RowProcessor handles rows either in buffered or streaming mode. It provides a unified interface for processing query results regardless of whether rows are collected first or streamed directly.

func NewStreamingProcessorForMode

func NewStreamingProcessorForMode(mode enums.DisplayMode, out io.Writer, sysVars *systemVariables, screenWidth int) RowProcessor

NewStreamingProcessorForMode creates a streaming processor for the given display mode. Returns nil if the mode doesn't support streaming yet. This is primarily used for testing - production code uses createStreamingProcessor.

type RunBatchStatement

type RunBatchStatement struct{}

func (*RunBatchStatement) Execute

func (s *RunBatchStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type RunPartitionStatement

type RunPartitionStatement struct{ Token string }

func (*RunPartitionStatement) Execute

func (s *RunPartitionStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type RunPartitionedQueryStatement

type RunPartitionedQueryStatement struct{ SQL string }

func (*RunPartitionedQueryStatement) Execute

func (s *RunPartitionedQueryStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type SampleDatabase

type SampleDatabase struct {
	Name        string `json:"name"`              // Unique identifier for the sample
	Description string `json:"description"`       // Human-readable description
	Dialect     string `json:"dialect"`           // SQL dialect (GOOGLE_STANDARD_SQL or POSTGRESQL)
	SchemaURI   string `json:"schemaURI"`         // URI to schema file (can be relative or absolute)
	DataURI     string `json:"dataURI,omitempty"` // URI to data file (optional)
	Source      string `json:"source,omitempty"`  // Documentation URL or description (optional)

	// Runtime fields (not in JSON)
	BaseDir       string                     `json:"-"` // Base directory for relative path resolution
	IsEmbedded    bool                       `json:"-"` // Distinguishes embedded:// from file:// base URIs
	ParsedDialect databasepb.DatabaseDialect `json:"-"` // Parsed dialect enum value
}

SampleDatabase represents both metadata and runtime configuration

func (*SampleDatabase) ResolveURIs

func (s *SampleDatabase) ResolveURIs()

ResolveURIs converts relative paths to absolute URIs based on BaseDir

type SelectStatement

type SelectStatement struct {
	Query string
}

func (*SelectStatement) Execute

func (s *SelectStatement) Execute(ctx context.Context, session *Session) (*Result, error)

func (*SelectStatement) String

func (s *SelectStatement) String() string

type Session

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

Session represents a database session with transaction management.

Mutex Protection Rationale:

While spanner-mycli is primarily a CLI tool with sequential user interactions, mutex protection is essential for several reasons:

1. **Goroutine safety**: Even in a CLI, operations may spawn goroutines:

  • Background heartbeat for long-running transactions
  • Progress bars and monitoring features
  • Future parallel query execution features
  • Signal handlers (Ctrl+C) that may access transaction state

2. **Correctness over performance**: The mutex ensures:

  • Atomic check-and-act operations (e.g., checking transaction state before modifying)
  • Prevention of use-after-free bugs if transaction is closed concurrently
  • Consistent transaction state across all operations

3. **Future extensibility**: The mutex-based design allows for:

  • Safe addition of concurrent features without major refactoring
  • Integration with tools that may access session state concurrently
  • Support for multiplexed connections or parallel operations

4. **Best practices**: Following Go's concurrency principles:

  • "Don't communicate by sharing memory; share memory by communicating"
  • When sharing is necessary (as with session state), protect it properly
  • Make the zero value useful - mutex provides safe default behavior

The performance overhead of mutex operations is negligible for CLI usage patterns, while the safety guarantees prevent subtle bugs that could corrupt user data.

func NewAdminSession

func NewAdminSession(ctx context.Context, sysVars *systemVariables, opts ...option.ClientOption) (*Session, error)

func NewSession

func NewSession(ctx context.Context, sysVars *systemVariables, opts ...option.ClientOption) (*Session, error)

func (*Session) BeginPendingTransaction

func (s *Session) BeginPendingTransaction(ctx context.Context, isolationLevel sppb.TransactionOptions_IsolationLevel, priority sppb.RequestOptions_Priority) error

BeginPendingTransaction starts pending transaction. The actual start of the transaction is delayed until the first operation in the transaction is executed.

func (*Session) BeginReadOnlyTransaction

func (s *Session) BeginReadOnlyTransaction(ctx context.Context, typ timestampBoundType, staleness time.Duration, timestamp time.Time, priority sppb.RequestOptions_Priority) (time.Time, error)

BeginReadOnlyTransaction starts read-only transaction and returns the snapshot timestamp for the transaction if successful.

func (*Session) BeginReadOnlyTransactionLocked

func (s *Session) BeginReadOnlyTransactionLocked(ctx context.Context, typ timestampBoundType, staleness time.Duration, timestamp time.Time, priority sppb.RequestOptions_Priority) (time.Time, error)

BeginReadOnlyTransactionLocked starts read-only transaction and returns the snapshot timestamp for the transaction if successful. Caller must hold s.tcMutex.

func (*Session) BeginReadWriteTransaction

func (s *Session) BeginReadWriteTransaction(ctx context.Context, isolationLevel sppb.TransactionOptions_IsolationLevel, priority sppb.RequestOptions_Priority) error

BeginReadWriteTransaction starts read-write transaction.

func (*Session) BeginReadWriteTransactionLocked

func (s *Session) BeginReadWriteTransactionLocked(ctx context.Context, isolationLevel sppb.TransactionOptions_IsolationLevel, priority sppb.RequestOptions_Priority) error

BeginReadWriteTransactionLocked starts read-write transaction. Caller must hold s.tcMutex.

func (*Session) Close

func (s *Session) Close()

func (*Session) ClosePendingTransaction

func (s *Session) ClosePendingTransaction() error

ClosePendingTransaction closes a pending transaction.

func (*Session) CloseReadOnlyTransaction

func (s *Session) CloseReadOnlyTransaction() error

CloseReadOnlyTransaction closes a running read-only transaction.

func (*Session) CommitReadWriteTransaction

func (s *Session) CommitReadWriteTransaction(ctx context.Context) (spanner.CommitResponse, error)

CommitReadWriteTransaction commits read-write transaction and returns commit timestamp if successful.

func (*Session) CommitReadWriteTransactionLocked

func (s *Session) CommitReadWriteTransactionLocked(ctx context.Context) (spanner.CommitResponse, error)

CommitReadWriteTransactionLocked commits read-write transaction and returns commit timestamp if successful. Caller must hold s.tcMutex.

func (*Session) ConnectToDatabase

func (s *Session) ConnectToDatabase(ctx context.Context, databaseId string) error

func (*Session) DatabaseExists

func (s *Session) DatabaseExists(ctx context.Context) (bool, error)

func (*Session) DatabasePath

func (s *Session) DatabasePath() string

func (*Session) DetermineTransaction

func (s *Session) DetermineTransaction(ctx context.Context) (time.Time, error)

DetermineTransaction determines the type of transaction to start based on the pending transaction and system variables. It returns the timestamp for read-only transactions or a zero time for read-write transactions.

func (*Session) DetermineTransactionAndState

func (s *Session) DetermineTransactionAndState(ctx context.Context) (time.Time, bool, error)

DetermineTransactionAndState determines transaction and returns both the timestamp and current transaction state. This combines DetermineTransaction and InTransaction checks in a single lock acquisition.

func (*Session) DetermineTransactionLocked

func (s *Session) DetermineTransactionLocked(ctx context.Context) (time.Time, error)

DetermineTransactionLocked determines the type of transaction to start based on the pending transaction and system variables. It returns the timestamp for read-only transactions or a zero time for read-write transactions. Caller must hold s.tcMutex.

func (*Session) ExecuteStatement

func (s *Session) ExecuteStatement(ctx context.Context, stmt Statement) (result *Result, err error)

ExecuteStatement executes stmt. If stmt is a MutationStatement, pending transaction is determined and fails if there is an active read-only transaction.

func (*Session) GetDatabaseSchema

func (s *Session) GetDatabaseSchema(ctx context.Context) ([]string, *descriptorpb.FileDescriptorSet, error)

func (*Session) GetTransactionFlagsWithLock

func (s *Session) GetTransactionFlagsWithLock() (inTransaction bool, inReadWriteTransaction bool)

GetTransactionFlagsWithLock returns multiple transaction state flags in a single lock acquisition. This is useful for avoiding multiple lock acquisitions when checking different transaction states. Acquires RLock for concurrent read access.

func (*Session) InPendingTransaction

func (s *Session) InPendingTransaction() bool

InPendingTransaction returns true if the session is running pending transaction.

func (*Session) InReadOnlyTransaction

func (s *Session) InReadOnlyTransaction() bool

InReadOnlyTransaction returns true if the session is running read-only transaction.

func (*Session) InReadWriteTransaction

func (s *Session) InReadWriteTransaction() bool

InReadWriteTransaction returns true if the session is running read-write transaction.

func (*Session) InTransaction

func (s *Session) InTransaction() bool

InTransaction returns true if the session is running transaction.

func (*Session) IncrementSchemaGeneration

func (s *Session) IncrementSchemaGeneration()

IncrementSchemaGeneration bumps the schema generation counter, signaling that schema-dependent caches should be invalidated.

func (*Session) InstanceExists

func (s *Session) InstanceExists() (bool, error)

func (*Session) InstancePath

func (s *Session) InstancePath() string

func (*Session) IsDetached

func (s *Session) IsDetached() bool

func (*Session) Mode

func (s *Session) Mode() SessionMode

func (*Session) NewTransactionOptionsBuilder

func (s *Session) NewTransactionOptionsBuilder() *TransactionOptionsBuilder

NewTransactionOptionsBuilder creates a new builder with session defaults.

func (*Session) RecreateClient

func (s *Session) RecreateClient() error

RecreateClient closes the current client and creates a new client for the session.

func (*Session) RequiresDatabaseConnection

func (s *Session) RequiresDatabaseConnection() bool

func (*Session) RollbackReadWriteTransaction

func (s *Session) RollbackReadWriteTransaction(ctx context.Context) error

RollbackReadWriteTransaction rollbacks read-write transaction.

func (*Session) RollbackReadWriteTransactionLocked

func (s *Session) RollbackReadWriteTransactionLocked(ctx context.Context) error

RollbackReadWriteTransactionLocked rollbacks read-write transaction. Caller must hold s.tcMutex.

func (*Session) RunAnalyzeQuery

func (s *Session) RunAnalyzeQuery(ctx context.Context, stmt spanner.Statement) (*sppb.QueryPlan, *sppb.ResultSetMetadata, error)

RunAnalyzeQuery analyzes a statement either on the running transaction or on the temporal read-only transaction.

func (*Session) RunInNewOrExistRwTx

func (s *Session) RunInNewOrExistRwTx(ctx context.Context,
	f func(tx *spanner.ReadWriteStmtBasedTransaction, implicit bool) (affected int64, plan *sppb.QueryPlan, metadata *sppb.ResultSetMetadata, err error),
) (*DMLResult, error)

RunInNewOrExistRwTx is a helper function for DML execution. It executes a function in the current RW transaction or an implicit RW transaction. If there is an error, the transaction will be rolled back.

func (*Session) RunInNewOrExistRwTxLocked

func (s *Session) RunInNewOrExistRwTxLocked(ctx context.Context,
	f func(tx *spanner.ReadWriteStmtBasedTransaction, implicit bool) (affected int64, plan *sppb.QueryPlan, metadata *sppb.ResultSetMetadata, err error),
) (*DMLResult, error)

RunInNewOrExistRwTxLocked is a helper function for DML execution. It executes a function in the current RW transaction or an implicit RW transaction. If there is an error, the transaction will be rolled back. Caller must hold s.tcMutex.

func (*Session) RunPartitionQuery

func (*Session) RunQuery

RunQuery executes a statement either on the running transaction or on the temporal read-only transaction. It returns row iterator and read-only transaction if the statement was executed on the read-only transaction.

func (*Session) RunQueryWithStats

func (s *Session) RunQueryWithStats(ctx context.Context, stmt spanner.Statement, implicit bool) (*spanner.RowIterator, *spanner.ReadOnlyTransaction)

RunQueryWithStats executes a statement with stats either on the running transaction or on the temporal read-only transaction. It returns row iterator and read-only transaction if the statement was executed on the read-only transaction.

func (*Session) RunUpdate

func (s *Session) RunUpdate(ctx context.Context, stmt spanner.Statement, implicit bool) ([]Row, map[string]any, int64,
	*sppb.ResultSetMetadata, *sppb.QueryPlan, error,
)

RunUpdate executes a DML statement on the running read-write transaction. It returns error if there is no running read-write transaction.

func (*Session) SchemaGeneration

func (s *Session) SchemaGeneration() uint64

SchemaGeneration returns the current schema generation counter.

func (*Session) TransactionAttrsWithLock

func (s *Session) TransactionAttrsWithLock() transactionAttributes

TransactionAttrs returns a copy of all transaction attributes. This allows safe inspection of transaction state without holding the mutex. If no transaction is active, returns a zero-value struct with mode=transactionModeUndetermined.

Design decision: This method uses RLock for read-only access, allowing concurrent reads of transaction state.

Naming convention: - TransactionAttrsWithLock() - Acquires read lock internally (this method) - transactionAttrsLocked() - Assumes caller holds lock (read or write)

func (*Session) TransactionMode

func (s *Session) TransactionMode() transactionMode

TransactionMode returns the current transaction mode. Deprecated: Use TransactionState() for new code.

func (*Session) TransactionState

func (s *Session) TransactionState() (mode transactionMode, isActive bool)

TransactionState returns the current transaction mode and whether a transaction is active. This consolidates multiple transaction state checks into a single method.

func (*Session) TransitTransaction

func (s *Session) TransitTransaction(ctx context.Context, fn func(tc *transactionContext) (*transactionContext, error)) error

TransitTransaction implements a functional state transition pattern for transaction management. It atomically transitions from one transaction state to another, handling cleanup of the old state. The transition function receives the current context and returns the new context. If an error occurs during transition, the original state is preserved.

func (*Session) ValidateDatabaseOperation

func (s *Session) ValidateDatabaseOperation() error

func (*Session) ValidateDetachedOperation

func (s *Session) ValidateDetachedOperation() error

func (*Session) ValidateStatementExecution

func (s *Session) ValidateStatementExecution(stmt Statement) error

type SessionHandler

type SessionHandler struct {
	*Session
}

SessionHandler manages a session pointer and can handle session-changing statements

func NewSessionHandler

func NewSessionHandler(session *Session) *SessionHandler

func (*SessionHandler) Close

func (h *SessionHandler) Close()

func (*SessionHandler) ExecuteStatement

func (h *SessionHandler) ExecuteStatement(ctx context.Context, stmt Statement) (*Result, error)

ExecuteStatement executes a statement, handling session-changing statements appropriately

func (*SessionHandler) GetSession

func (h *SessionHandler) GetSession() *Session

type SessionMode

type SessionMode int
const (
	Detached SessionMode = iota
	DatabaseConnected
)

type SetAddStatement

type SetAddStatement struct {
	VarName string
	Value   string
}

func (*SetAddStatement) Execute

func (s *SetAddStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type SetParamTypeStatement

type SetParamTypeStatement struct {
	Name string
	Type string
}

func (*SetParamTypeStatement) Execute

func (s *SetParamTypeStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type SetParamValueStatement

type SetParamValueStatement struct {
	Name  string
	Value string
}

func (*SetParamValueStatement) Execute

func (s *SetParamValueStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type SetStatement

type SetStatement struct {
	VarName string
	Value   string
}

func (*SetStatement) Execute

func (s *SetStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type SetTransactionStatement

type SetTransactionStatement struct {
	IsReadOnly bool
}

func (*SetTransactionStatement) Execute

func (s *SetTransactionStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type ShellMetaCommand

type ShellMetaCommand struct {
	Command string
}

ShellMetaCommand executes system shell commands using \! syntax

func (*ShellMetaCommand) Execute

func (s *ShellMetaCommand) Execute(ctx context.Context, session *Session) (*Result, error)

Execute runs the shell command

type ShowColumnsStatement

type ShowColumnsStatement struct {
	Schema string
	Table  string
}

func (*ShowColumnsStatement) Execute

func (s *ShowColumnsStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type ShowCreateStatement

type ShowCreateStatement struct {
	ObjectType string
	Schema     string
	Name       string
}

func (*ShowCreateStatement) Execute

func (s *ShowCreateStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type ShowDatabasesStatement

type ShowDatabasesStatement struct{}

func (*ShowDatabasesStatement) Execute

func (s *ShowDatabasesStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type ShowDdlsStatement

type ShowDdlsStatement struct{}

func (*ShowDdlsStatement) Execute

func (s *ShowDdlsStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type ShowIndexStatement

type ShowIndexStatement struct {
	Schema string
	Table  string
}

func (*ShowIndexStatement) Execute

func (s *ShowIndexStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type ShowLocalProtoStatement

type ShowLocalProtoStatement struct{}

func (*ShowLocalProtoStatement) Execute

func (s *ShowLocalProtoStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type ShowOperationStatement

type ShowOperationStatement struct {
	OperationId string
	Mode        string // "ASYNC" or "SYNC"
}

func (*ShowOperationStatement) Execute

func (s *ShowOperationStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type ShowParamsStatement

type ShowParamsStatement struct{}

func (*ShowParamsStatement) Execute

func (s *ShowParamsStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type ShowPlanNodeStatement

type ShowPlanNodeStatement struct {
	NodeID int
}

func (*ShowPlanNodeStatement) Execute

func (s *ShowPlanNodeStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type ShowQueryProfileStatement

type ShowQueryProfileStatement struct {
	Fprint int64
}

func (*ShowQueryProfileStatement) Execute

func (s *ShowQueryProfileStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type ShowQueryProfilesStatement

type ShowQueryProfilesStatement struct{}

func (*ShowQueryProfilesStatement) Execute

func (s *ShowQueryProfilesStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type ShowRemoteProtoStatement

type ShowRemoteProtoStatement struct{}

func (*ShowRemoteProtoStatement) Execute

func (s *ShowRemoteProtoStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type ShowSchemaUpdateOperations

type ShowSchemaUpdateOperations struct{}

func (*ShowSchemaUpdateOperations) Execute

func (s *ShowSchemaUpdateOperations) Execute(ctx context.Context, session *Session) (*Result, error)

type ShowSplitPointsStatement

type ShowSplitPointsStatement struct{}

func (*ShowSplitPointsStatement) Execute

func (s *ShowSplitPointsStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type ShowTablesStatement

type ShowTablesStatement struct {
	Schema string
}

func (*ShowTablesStatement) Execute

func (s *ShowTablesStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type ShowVariableStatement

type ShowVariableStatement struct {
	VarName string
}

func (*ShowVariableStatement) Execute

func (s *ShowVariableStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type ShowVariablesStatement

type ShowVariablesStatement struct{}

func (*ShowVariablesStatement) Execute

func (s *ShowVariablesStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type SourceMetaCommand

type SourceMetaCommand struct {
	FilePath string
}

SourceMetaCommand executes SQL statements from a file using \. syntax

func (*SourceMetaCommand) Execute

func (s *SourceMetaCommand) Execute(ctx context.Context, session *Session) (*Result, error)

Execute is not used for SourceMetaCommand as it's handled specially in CLI

type StartBatchStatement

type StartBatchStatement struct {
	Mode batchMode
}

func (*StartBatchStatement) Execute

func (s *StartBatchStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type Statement

type Statement interface {
	Execute(ctx context.Context, session *Session) (*Result, error)
}

func BuildCLIStatement

func BuildCLIStatement(stripped, raw string) (Statement, error)

func BuildNativeStatementLexical

func BuildNativeStatementLexical(stripped string, raw string) (Statement, error)

func BuildNativeStatementMemefish

func BuildNativeStatementMemefish(stripped, raw string) (Statement, error)

func BuildStatement

func BuildStatement(input string) (Statement, error)

func BuildStatementWithComments

func BuildStatementWithComments(stripped, raw string) (Statement, error)

func BuildStatementWithCommentsWithMode

func BuildStatementWithCommentsWithMode(stripped, raw string, mode enums.ParseMode) (Statement, error)

func ParseMetaCommand

func ParseMetaCommand(input string) (Statement, error)

ParseMetaCommand parses a meta command string into a Statement

type StreamingProcessor

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

StreamingProcessor processes rows immediately as they arrive. This reduces memory usage and improves Time To First Byte for large result sets.

func NewStreamingProcessor

func NewStreamingProcessor(formatter format.StreamingFormatter, out io.Writer, screenWidth int) *StreamingProcessor

NewStreamingProcessor creates a processor that outputs rows immediately.

func (*StreamingProcessor) Finish

func (p *StreamingProcessor) Finish(stats QueryStats, rowCount int64) error

Finish completes the streaming output.

func (*StreamingProcessor) Init

func (p *StreamingProcessor) Init(metadata *sppb.ResultSetMetadata, sysVars *systemVariables) error

Init initializes the streaming processor and writes headers if needed.

func (*StreamingProcessor) ProcessRow

func (p *StreamingProcessor) ProcessRow(row Row) error

ProcessRow immediately outputs a row.

type SyncProtoStatement

type SyncProtoStatement struct {
	UpsertPaths []string
	DeletePaths []string
}

func (*SyncProtoStatement) Execute

func (s *SyncProtoStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type TableDependency

type TableDependency struct {
	TableName      string
	ParentTable    string        // INTERLEAVE parent
	OnDeleteAction string        // CASCADE, NO ACTION for INTERLEAVE
	ChildrenTables []string      // Tables that interleave in this table
	ForeignKeys    []FKReference // Foreign key references FROM this table
	ReferencedBy   []FKReference // Foreign key references TO this table
	Level          int           // INTERLEAVE depth (0-7)
}

TableDependency represents a table with all its dependencies

type TableHeader

type TableHeader interface {
	// Render returns the header strings. When verbose is true, type information is included.
	// Use renderTableHeader() as a nil-safe wrapper.
	Render(verbose bool) []string
	// contains filtered or unexported methods
}

type TablePreviewProcessor

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

TablePreviewProcessor collects a configurable number of rows for table width calculation. This allows table formats to determine optimal column widths before starting output.

func NewTablePreviewProcessor

func NewTablePreviewProcessor(formatter format.StreamingFormatter, previewSize int) *TablePreviewProcessor

NewTablePreviewProcessor creates a processor that previews rows for width calculation. previewSize of 0 means collect all rows (non-streaming mode).

func (*TablePreviewProcessor) Finish

func (p *TablePreviewProcessor) Finish(stats QueryStats, rowCount int64) error

Finish ensures formatter is initialized and completes output.

func (*TablePreviewProcessor) Init

func (p *TablePreviewProcessor) Init(metadata *sppb.ResultSetMetadata, sysVars *systemVariables) error

Init stores metadata for later use.

func (*TablePreviewProcessor) ProcessRow

func (p *TablePreviewProcessor) ProcessRow(row Row) error

ProcessRow collects rows for preview or passes them through after initialization.

type TeeOutputMetaCommand

type TeeOutputMetaCommand struct {
	FilePath string
}

TeeOutputMetaCommand enables output tee to a file using \T syntax (MySQL-style: both screen and file)

func (*TeeOutputMetaCommand) Execute

func (t *TeeOutputMetaCommand) Execute(ctx context.Context, session *Session) (*Result, error)

Execute enables tee output to the specified file (both screen and file)

type TemplateVar

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

TemplateVar handles template variables like CLI_ANALYZE_COLUMNS

func (*TemplateVar) Description

func (t *TemplateVar) Description() string

func (*TemplateVar) Get

func (t *TemplateVar) Get() (string, error)

func (*TemplateVar) IsReadOnly

func (t *TemplateVar) IsReadOnly() bool

func (*TemplateVar) Set

func (t *TemplateVar) Set(value string) error

type TimestampBoundVar

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

TimestampBoundVar handles READ_ONLY_STALENESS variable

func (*TimestampBoundVar) Description

func (t *TimestampBoundVar) Description() string

func (*TimestampBoundVar) Get

func (t *TimestampBoundVar) Get() (string, error)

func (*TimestampBoundVar) IsReadOnly

func (t *TimestampBoundVar) IsReadOnly() bool

func (*TimestampBoundVar) Set

func (t *TimestampBoundVar) Set(value string) error

type TimestampVar

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

TimestampVar handles timestamp formatting for read-only timestamp variables

func (*TimestampVar) Description

func (t *TimestampVar) Description() string

func (*TimestampVar) Get

func (t *TimestampVar) Get() (string, error)

func (*TimestampVar) IsReadOnly

func (t *TimestampVar) IsReadOnly() bool

func (*TimestampVar) Set

func (t *TimestampVar) Set(value string) error

type TransactionOptionsBuilder

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

TransactionOptionsBuilder helps build transaction options with proper defaults.

func (*TransactionOptionsBuilder) Build

Build creates the final TransactionOptions with resolved defaults.

func (*TransactionOptionsBuilder) BuildIsolationLevel

BuildIsolationLevel returns just the resolved isolation level.

func (*TransactionOptionsBuilder) BuildPriority

BuildPriority returns just the resolved priority.

func (*TransactionOptionsBuilder) WithIsolationLevel

WithIsolationLevel sets the transaction isolation level.

func (*TransactionOptionsBuilder) WithPriority

WithPriority sets the transaction priority.

func (*TransactionOptionsBuilder) WithTag

WithTag sets the transaction tag.

type TruncateTableStatement

type TruncateTableStatement struct {
	Schema string
	Table  string
}

func (*TruncateTableStatement) Execute

func (s *TruncateTableStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type TryPartitionedQueryStatement

type TryPartitionedQueryStatement struct{ SQL string }

func (*TryPartitionedQueryStatement) Execute

func (s *TryPartitionedQueryStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type UnimplementedVar

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

UnimplementedVar handles unimplemented variables

func (*UnimplementedVar) Description

func (u *UnimplementedVar) Description() string

func (*UnimplementedVar) Get

func (u *UnimplementedVar) Get() (string, error)

func (*UnimplementedVar) IsReadOnly

func (u *UnimplementedVar) IsReadOnly() bool

func (*UnimplementedVar) Set

func (u *UnimplementedVar) Set(value string) error

type UnsetParamStatement

type UnsetParamStatement struct {
	Name string
}

func (*UnsetParamStatement) Execute

func (s *UnsetParamStatement) Execute(ctx context.Context, session *Session) (*Result, error)

type UpdateResult

type UpdateResult struct {
	Rows     []Row                   // Rows returned by the update operation (e.g., from RETURNING clause)
	Stats    map[string]any          // Query statistics from the operation
	Count    int64                   // Number of rows affected by the update
	Metadata *sppb.ResultSetMetadata // Metadata about the result set
	Plan     *sppb.QueryPlan         // Query execution plan (when requested)
}

UpdateResult holds the complete result of an update operation.

type UseDatabaseMetaCommand

type UseDatabaseMetaCommand struct {
	Database string
}

UseDatabaseMetaCommand switches database using \u syntax

func (*UseDatabaseMetaCommand) Execute

func (s *UseDatabaseMetaCommand) Execute(ctx context.Context, session *Session) (*Result, error)

Execute is required by Statement interface but the actual logic is handled in SessionHandler

type UseStatement

type UseStatement struct {
	Database string
	Role     string
	NopStatement
}

UseStatement is actually implemented in cli.go because it needs to replace Session pointer in Cli.

type ValidValuesEnumerator

type ValidValuesEnumerator interface {
	ValidValues() []string
}

ValidValuesEnumerator is implemented by variables that have a constrained set of valid values. Used by fuzzy completion to offer value candidates for SET <name> = <Ctrl+T>. Values must be returned as valid GoogleSQL literals (e.g., 'TABLE' for strings, TRUE for booleans).

type VarHandler

type VarHandler[T any] struct {
	// contains filtered or unexported fields
}

VarHandler handles get/set operations for a variable

TODO: Consider adding native support for session-init-only variables. Currently, variables like CLI_ENABLE_ADC_PLUS use custom setters to check if CurrentSession != nil, but this could be better supported as a first-class feature. Potential implementation:

  • Add a sessionInitOnly bool field to VarHandler
  • Move the CurrentSession check logic into the Set method
  • This would centralize the behavior and make it declarative rather than imperative

func BoolVar

func BoolVar(ptr *bool, desc string) *VarHandler[bool]

BoolVar creates a handler for bool variables

func IntVar

func IntVar(ptr *int64, desc string) *VarHandler[int64]

IntVar creates a handler for int64 variables

func NullableDurationVar

func NullableDurationVar(ptr **time.Duration, desc string) *VarHandler[*time.Duration]

NullableDurationVar creates a handler for nullable duration variables

func NullableIntVar

func NullableIntVar(ptr **int64, desc string) *VarHandler[*int64]

NullableIntVar creates a handler for nullable int64 variables

func StringVar

func StringVar(ptr *string, desc string) *VarHandler[string]

StringVar creates a handler for string variables

func (*VarHandler[T]) AsReadOnly

func (h *VarHandler[T]) AsReadOnly() *VarHandler[T]

AsReadOnly makes the handler read-only

func (*VarHandler[T]) Description

func (h *VarHandler[T]) Description() string

Description returns the variable description

func (*VarHandler[T]) Get

func (h *VarHandler[T]) Get() (string, error)

Get returns the formatted value

func (*VarHandler[T]) IsReadOnly

func (h *VarHandler[T]) IsReadOnly() bool

IsReadOnly returns whether the variable is read-only

func (*VarHandler[T]) Set

func (h *VarHandler[T]) Set(value string) error

Set parses and sets the value

func (*VarHandler[T]) ValidValues

func (h *VarHandler[T]) ValidValues() []string

ValidValues returns the constrained valid values, if any. Implements ValidValuesEnumerator for VarHandler instances with enumValues set.

func (*VarHandler[T]) WithValidator

func (h *VarHandler[T]) WithValidator(validate func(T) error) *VarHandler[T]

WithValidator adds a validator function

type VarRegistry

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

VarRegistry is a registry for system variables

func NewVarRegistry

func NewVarRegistry(sv *systemVariables) *VarRegistry

NewVarRegistry creates a new variable registry

func (*VarRegistry) Add

func (r *VarRegistry) Add(name, value string) error

Add performs ADD operation on a variable

func (*VarRegistry) Get

func (r *VarRegistry) Get(name string) (string, error)

Get retrieves a variable value

func (*VarRegistry) GetDescription

func (r *VarRegistry) GetDescription(name string) (string, error)

GetDescription returns variable description

func (*VarRegistry) GetVariable

func (r *VarRegistry) GetVariable(name string) Variable

GetVariable retrieves the Variable handler by name, or nil if not found.

func (*VarRegistry) IsReadOnly

func (r *VarRegistry) IsReadOnly(name string) (bool, error)

IsReadOnly checks if a variable is read-only

func (*VarRegistry) ListVariableInfo

func (r *VarRegistry) ListVariableInfo() map[string]struct {
	Description string
	ReadOnly    bool
	CanAdd      bool
}

ListVariableInfo returns information about all variables

func (*VarRegistry) ListVariables

func (r *VarRegistry) ListVariables() map[string]string

ListVariables returns a map of all variables with their current values

func (*VarRegistry) Register

func (r *VarRegistry) Register(name string, v Variable)

Register adds a variable to the registry

func (*VarRegistry) RegisterWithAdd

func (r *VarRegistry) RegisterWithAdd(name string, v Variable, addFunc func(string) error)

RegisterWithAdd adds a variable with ADD support

func (*VarRegistry) Set

func (r *VarRegistry) Set(name, value string, isGoogleSQL bool) error

Set sets a variable value

type Variable

type Variable interface {
	Get() (string, error)
	Set(string) error
	Description() string
	IsReadOnly() bool
}

Variable interface that all handlers implement

Directories

Path Synopsis
Package format implements SQL export formatting for query results.
Package format implements SQL export formatting for query results.
StreamManager manages all I/O streams for the CLI.
StreamManager manages all I/O streams for the CLI.

Jump to

Keyboard shortcuts

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