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 }