github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/cancel_sessions.go (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package sql
    12  
    13  import (
    14  	"context"
    15  	"fmt"
    16  
    17  	"github.com/cockroachdb/cockroach/pkg/server/serverpb"
    18  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
    19  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
    20  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    21  	"github.com/cockroachdb/errors"
    22  )
    23  
    24  type cancelSessionsNode struct {
    25  	rows     planNode
    26  	ifExists bool
    27  }
    28  
    29  func (n *cancelSessionsNode) startExec(runParams) error {
    30  	return nil
    31  }
    32  
    33  func (n *cancelSessionsNode) Next(params runParams) (bool, error) {
    34  	// TODO(knz): instead of performing the cancels sequentially,
    35  	// accumulate all the query IDs and then send batches to each of the
    36  	// nodes.
    37  
    38  	if ok, err := n.rows.Next(params); err != nil || !ok {
    39  		return ok, err
    40  	}
    41  
    42  	datum := n.rows.Values()[0]
    43  	if datum == tree.DNull {
    44  		return true, nil
    45  	}
    46  
    47  	statusServer, err := params.extendedEvalCtx.StatusServer.OptionalErr(47895)
    48  	if err != nil {
    49  		return false, err
    50  	}
    51  	sessionIDString, ok := tree.AsDString(datum)
    52  	if !ok {
    53  		return false, errors.AssertionFailedf("%q: expected *DString, found %T", datum, datum)
    54  	}
    55  
    56  	sessionID, err := StringToClusterWideID(string(sessionIDString))
    57  	if err != nil {
    58  		return false, pgerror.Wrapf(err, pgcode.Syntax, "invalid session ID %s", datum)
    59  	}
    60  
    61  	// Get the lowest 32 bits of the session ID.
    62  	nodeID := sessionID.GetNodeID()
    63  
    64  	request := &serverpb.CancelSessionRequest{
    65  		NodeId:    fmt.Sprintf("%d", nodeID),
    66  		SessionID: sessionID.GetBytes(),
    67  		Username:  params.SessionData().User,
    68  	}
    69  
    70  	response, err := statusServer.CancelSession(params.ctx, request)
    71  	if err != nil {
    72  		return false, err
    73  	}
    74  
    75  	if !response.Canceled && !n.ifExists {
    76  		return false, errors.Newf("could not cancel session %s: %s", sessionID, response.Error)
    77  	}
    78  
    79  	return true, nil
    80  }
    81  
    82  func (*cancelSessionsNode) Values() tree.Datums { return nil }
    83  
    84  func (n *cancelSessionsNode) Close(ctx context.Context) {
    85  	n.rows.Close(ctx)
    86  }