github.com/matrixorigin/matrixone@v1.2.0/pkg/proxy/event.go (about)

     1  // Copyright 2021 - 2023 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package proxy
    16  
    17  import (
    18  	"context"
    19  
    20  	"github.com/matrixorigin/matrixone/pkg/sql/parsers"
    21  	"github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect"
    22  	"github.com/matrixorigin/matrixone/pkg/sql/parsers/tree"
    23  )
    24  
    25  // eventType alias uint8, which indicates the type of event.
    26  type eventType uint8
    27  
    28  // String returns the string of event type.
    29  func (t eventType) String() string {
    30  	switch t {
    31  	case TypeKillQuery:
    32  		return "KillQuery"
    33  	case TypeSetVar:
    34  		return "SetVar"
    35  	}
    36  	return "Unknown"
    37  }
    38  
    39  const (
    40  	// TypeMin is the minimal event type.
    41  	TypeMin eventType = 0
    42  	// TypeKillQuery indicates the kill query statement.
    43  	TypeKillQuery eventType = 1
    44  	// TypeSetVar indicates the set variable statement.
    45  	TypeSetVar eventType = 2
    46  )
    47  
    48  // IEvent is the event interface.
    49  type IEvent interface {
    50  	// eventType returns the type of the event.
    51  	eventType() eventType
    52  }
    53  
    54  // baseEvent describes the base event information which happens in tunnel data flow.
    55  type baseEvent struct {
    56  	// typ is the event type.
    57  	typ eventType
    58  }
    59  
    60  // eventType implements the IEvent interface.
    61  func (e *baseEvent) eventType() eventType {
    62  	return TypeMin
    63  }
    64  
    65  // sendReq sends an event to event channel.
    66  func sendReq(e IEvent, c chan<- IEvent) {
    67  	c <- e
    68  }
    69  
    70  // sendResp receives an event response from the channel.
    71  func sendResp(r []byte, c chan<- []byte) {
    72  	c <- r
    73  }
    74  
    75  // makeEvent parses an event from message bytes. If we got no
    76  // supported event, just return nil. If the second return value
    77  // is true, means that the message has been consumed completely,
    78  // and do not need to send to dst anymore.
    79  func makeEvent(msg []byte, b *msgBuf) (IEvent, bool) {
    80  	if msg == nil || len(msg) < preRecvLen {
    81  		return nil, false
    82  	}
    83  	if isCmdQuery(msg) {
    84  		sql := getStatement(msg)
    85  		stmts, err := parsers.Parse(context.Background(), dialect.MYSQL, sql, 0, 0)
    86  		if err != nil {
    87  			return nil, false
    88  		}
    89  		if len(stmts) != 1 {
    90  			return nil, false
    91  		}
    92  		switch s := stmts[0].(type) {
    93  		case *tree.Kill:
    94  			return makeKillQueryEvent(sql, s.ConnectionId), true
    95  		case *tree.SetVar:
    96  			// This event should be sent to dst, so return false,
    97  			return makeSetVarEvent(sql), false
    98  		default:
    99  			return nil, false
   100  		}
   101  	}
   102  	return nil, false
   103  }
   104  
   105  // killQueryEvent is the event that "kill query" statement is captured.
   106  // We need to send this statement to a specified CN server which has
   107  // the connection ID on it.
   108  type killQueryEvent struct {
   109  	baseEvent
   110  	// stmt is the statement that will be sent to server.
   111  	stmt string
   112  	// The ID of connection that needs to be killed.
   113  	connID uint32
   114  }
   115  
   116  // makeKillQueryEvent creates a event with TypeKillQuery type.
   117  func makeKillQueryEvent(stmt string, connID uint64) IEvent {
   118  	e := &killQueryEvent{
   119  		stmt:   stmt,
   120  		connID: uint32(connID),
   121  	}
   122  	e.typ = TypeKillQuery
   123  	return e
   124  }
   125  
   126  // eventType implements the IEvent interface.
   127  func (e *killQueryEvent) eventType() eventType {
   128  	return TypeKillQuery
   129  }
   130  
   131  // setVarEvent is the event that set session variable or set user variable.
   132  // We need to check if the execution of this statement is successful, and
   133  // then keep the variable and its value to clientConn.
   134  type setVarEvent struct {
   135  	baseEvent
   136  	// stmt is the statement that will be sent to server.
   137  	stmt string
   138  }
   139  
   140  // makeSetVarEvent creates an event with TypeSetVar type.
   141  func makeSetVarEvent(stmt string) IEvent {
   142  	e := &setVarEvent{
   143  		stmt: stmt,
   144  	}
   145  	e.typ = TypeSetVar
   146  	return e
   147  }
   148  
   149  // eventType implements the IEvent interface.
   150  func (e *setVarEvent) eventType() eventType {
   151  	return TypeSetVar
   152  }