Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions processlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ func (pl *ProcessList) BeginQuery(
ctx *sql.Context,
query string,
) (*sql.Context, error) {
if ctx.IsInterpreted() {
return ctx, nil
}
pl.mu.Lock()
defer pl.mu.Unlock()

Expand Down Expand Up @@ -144,6 +147,9 @@ func (pl *ProcessList) BeginQuery(
}

func (pl *ProcessList) EndQuery(ctx *sql.Context) {
if ctx.IsInterpreted() {
return
}
pl.mu.Lock()
defer pl.mu.Unlock()
id := ctx.Session.ID()
Expand Down Expand Up @@ -177,6 +183,9 @@ func (pl *ProcessList) EndQuery(ctx *sql.Context) {
// bracketed with EndOperation(). Should certainly be used for any
// Handler callbacks which may access the database, like Prepare.
func (pl *ProcessList) BeginOperation(ctx *sql.Context) (*sql.Context, error) {
if ctx.IsInterpreted() {
return ctx, nil
}
pl.mu.Lock()
defer pl.mu.Unlock()
id := ctx.Session.ID()
Expand All @@ -193,6 +202,9 @@ func (pl *ProcessList) BeginOperation(ctx *sql.Context) (*sql.Context, error) {
}

func (pl *ProcessList) EndOperation(ctx *sql.Context) {
if ctx.IsInterpreted() {
return
}
pl.mu.Lock()
defer pl.mu.Unlock()
id := ctx.Session.ID()
Expand Down
2 changes: 1 addition & 1 deletion sql/rowexec/transaction_iters.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ type TransactionCommittingIter struct {

func AddTransactionCommittingIter(ctx *sql.Context, qFlags *sql.QueryFlags, iter sql.RowIter) (sql.RowIter, error) {
// TODO: This is a bit of a hack. Need to figure out better relationship between new transaction node and warnings.
if qFlags != nil && qFlags.IsSet(sql.QFlagShowWarnings) {
if (qFlags != nil && qFlags.IsSet(sql.QFlagShowWarnings)) || ctx.IsInterpreted() {
return iter, nil
}

Expand Down
19 changes: 19 additions & 0 deletions sql/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ type Context struct {
queryTime time.Time
tracer trace.Tracer
rootSpan trace.Span
interpreted bool
Version AnalyzerVersion
}

Expand Down Expand Up @@ -328,6 +329,17 @@ func RunWithNowFunc(nowFunc func() time.Time, fn func() error) error {
return fn()
}

// RunInterpreted modifies the context such that all calls to Context.IsInterpreted will return `true`. It is safe to
// recursively call this.
func RunInterpreted[T any](ctx *Context, f func(ctx *Context) (T, error)) (T, error) {
current := ctx.interpreted
ctx.interpreted = true
defer func() {
ctx.interpreted = current
}()
return f(ctx)
}

func swapNowFunc(newNowFunc func() time.Time) func() time.Time {
ctxNowFuncMutex.Lock()
defer ctxNowFuncMutex.Unlock()
Expand Down Expand Up @@ -388,6 +400,13 @@ func (c *Context) ApplyOpts(opts ...ContextOption) {
// NewEmptyContext returns a default context with default values.
func NewEmptyContext() *Context { return NewContext(context.TODO()) }

// IsInterpreted returns `true` when this is being called from within RunInterpreted. In such cases, GMS will choose to
// handle logic differently, as running from within an interpreted function requires different considerations than
// running in a standard environment.
func (c *Context) IsInterpreted() bool {
return c.interpreted
}

// Pid returns the process id associated with this context.
func (c *Context) Pid() uint64 {
if c == nil {
Expand Down