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 }