proto.go (6216B)
1 // From src/include/libpq/protocol.h and src/include/libpq/pqcomm.h – PostgreSQL 18.1 2 3 package proto 4 5 import ( 6 "fmt" 7 "strconv" 8 ) 9 10 // Constants from pqcomm.h 11 const ( 12 ProtocolVersion30 = (3 << 16) | 0 //lint:ignore SA4016 x 13 ProtocolVersion32 = (3 << 16) | 2 // PostgreSQL ≥18. 14 CancelRequestCode = (1234 << 16) | 5678 15 NegotiateSSLCode = (1234 << 16) | 5679 16 NegotiateGSSCode = (1234 << 16) | 5680 17 ) 18 19 // Constants from fe-connect.c 20 const ( 21 MaxErrlen = 30_000 // https://github.com/postgres/postgres/blob/c6a10a89f/src/interfaces/libpq/fe-connect.c#L4067 22 ) 23 24 // RequestCode is a request codes sent by the frontend. 25 type RequestCode byte 26 27 // These are the request codes sent by the frontend. 28 const ( 29 Bind = RequestCode('B') 30 Close = RequestCode('C') 31 Describe = RequestCode('D') 32 Execute = RequestCode('E') 33 FunctionCall = RequestCode('F') 34 Flush = RequestCode('H') 35 Parse = RequestCode('P') 36 Query = RequestCode('Q') 37 Sync = RequestCode('S') 38 Terminate = RequestCode('X') 39 CopyFail = RequestCode('f') 40 GSSResponse = RequestCode('p') 41 PasswordMessage = RequestCode('p') 42 SASLInitialResponse = RequestCode('p') 43 SASLResponse = RequestCode('p') 44 CopyDoneRequest = RequestCode('c') 45 CopyDataRequest = RequestCode('d') 46 ) 47 48 func (r RequestCode) String() string { 49 s, ok := map[RequestCode]string{ 50 Bind: "Bind", 51 Close: "Close", 52 Describe: "Describe", 53 Execute: "Execute", 54 FunctionCall: "FunctionCall", 55 Flush: "Flush", 56 Parse: "Parse", 57 Query: "Query", 58 Sync: "Sync", 59 Terminate: "Terminate", 60 CopyFail: "CopyFail", 61 // These are all the same :-/ 62 //GSSResponse: "GSSResponse", 63 PasswordMessage: "PasswordMessage", 64 //SASLInitialResponse: "SASLInitialResponse", 65 //SASLResponse: "SASLResponse", 66 CopyDoneRequest: "CopyDone", 67 CopyDataRequest: "CopyData", 68 }[r] 69 if !ok { 70 s = "<unknown>" 71 } 72 c := string(r) 73 if r <= 0x1f || r == 0x7f { 74 c = fmt.Sprintf("0x%x", string(r)) 75 } 76 return "(" + c + ") " + s 77 } 78 79 // ResponseCode is a response codes sent by the backend. 80 type ResponseCode byte 81 82 // These are the response codes sent by the backend. 83 const ( 84 ParseComplete = ResponseCode('1') 85 BindComplete = ResponseCode('2') 86 CloseComplete = ResponseCode('3') 87 NotificationResponse = ResponseCode('A') 88 CommandComplete = ResponseCode('C') 89 DataRow = ResponseCode('D') 90 ErrorResponse = ResponseCode('E') 91 CopyInResponse = ResponseCode('G') 92 CopyOutResponse = ResponseCode('H') 93 EmptyQueryResponse = ResponseCode('I') 94 BackendKeyData = ResponseCode('K') 95 NoticeResponse = ResponseCode('N') 96 AuthenticationRequest = ResponseCode('R') 97 ParameterStatus = ResponseCode('S') 98 RowDescription = ResponseCode('T') 99 FunctionCallResponse = ResponseCode('V') 100 CopyBothResponse = ResponseCode('W') 101 ReadyForQuery = ResponseCode('Z') 102 NoData = ResponseCode('n') 103 PortalSuspended = ResponseCode('s') 104 ParameterDescription = ResponseCode('t') 105 NegotiateProtocolVersion = ResponseCode('v') 106 CopyDoneResponse = ResponseCode('c') 107 CopyDataResponse = ResponseCode('d') 108 ) 109 110 func (r ResponseCode) String() string { 111 s, ok := map[ResponseCode]string{ 112 ParseComplete: "ParseComplete", 113 BindComplete: "BindComplete", 114 CloseComplete: "CloseComplete", 115 NotificationResponse: "NotificationResponse", 116 CommandComplete: "CommandComplete", 117 DataRow: "DataRow", 118 ErrorResponse: "ErrorResponse", 119 CopyInResponse: "CopyInResponse", 120 CopyOutResponse: "CopyOutResponse", 121 EmptyQueryResponse: "EmptyQueryResponse", 122 BackendKeyData: "BackendKeyData", 123 NoticeResponse: "NoticeResponse", 124 AuthenticationRequest: "AuthRequest", 125 ParameterStatus: "ParamStatus", 126 RowDescription: "RowDescription", 127 FunctionCallResponse: "FunctionCallResponse", 128 CopyBothResponse: "CopyBothResponse", 129 ReadyForQuery: "ReadyForQuery", 130 NoData: "NoData", 131 PortalSuspended: "PortalSuspended", 132 ParameterDescription: "ParamDescription", 133 NegotiateProtocolVersion: "NegotiateProtocolVersion", 134 CopyDoneResponse: "CopyDone", 135 CopyDataResponse: "CopyData", 136 }[r] 137 if !ok { 138 s = "<unknown>" 139 } 140 c := string(r) 141 if r <= 0x1f || r == 0x7f { 142 c = fmt.Sprintf("0x%x", string(r)) 143 } 144 return "(" + c + ") " + s 145 } 146 147 // AuthCode are authentication request codes sent by the backend. 148 type AuthCode int32 149 150 // These are the authentication request codes sent by the backend. 151 const ( 152 AuthReqOk = AuthCode(0) // User is authenticated 153 AuthReqKrb4 = AuthCode(1) // Kerberos V4. Not supported any more. 154 AuthReqKrb5 = AuthCode(2) // Kerberos V5. Not supported any more. 155 AuthReqPassword = AuthCode(3) // Password 156 AuthReqCrypt = AuthCode(4) // crypt password. Not supported any more. 157 AuthReqMD5 = AuthCode(5) // md5 password 158 _ = AuthCode(6) // 6 is available. It was used for SCM creds, not supported any more. 159 AuthReqGSS = AuthCode(7) // GSSAPI without wrap() 160 AuthReqGSSCont = AuthCode(8) // Continue GSS exchanges 161 AuthReqSSPI = AuthCode(9) // SSPI negotiate without wrap() 162 AuthReqSASL = AuthCode(10) // Begin SASL authentication 163 AuthReqSASLCont = AuthCode(11) // Continue SASL authentication 164 AuthReqSASLFin = AuthCode(12) // Final SASL message 165 ) 166 167 func (a AuthCode) String() string { 168 s, ok := map[AuthCode]string{ 169 AuthReqOk: "ok", 170 AuthReqKrb4: "krb4", 171 AuthReqKrb5: "krb5", 172 AuthReqPassword: "password", 173 AuthReqCrypt: "crypt", 174 AuthReqMD5: "md5", 175 AuthReqGSS: "GDD", 176 AuthReqGSSCont: "GSSCont", 177 AuthReqSSPI: "SSPI", 178 AuthReqSASL: "SASL", 179 AuthReqSASLCont: "SASLCont", 180 AuthReqSASLFin: "SASLFin", 181 }[a] 182 if !ok { 183 s = "<unknown>" 184 } 185 return s + " (" + strconv.Itoa(int(a)) + ")" 186 }