"""SQLI wire-protocol message-type constants. Two distinct namespaces live here: * ``SQ_*`` — the post-login SQLI message-type tags from ``com.informix.jdbc.IfxMessageTypes``. Each one is a 16-bit big-endian short on the wire. See ``docs/PROTOCOL_NOTES.md`` §5 for categorization by purpose. * ``ASF_*``, ``SL_*``, ``PF_*`` — the connection-establishment markers used inside the binary login PDU body, defined locally in ``com.informix.asf.Connection`` (NOT in ``IfxMessageTypes``). These also appear on the wire as 16-bit shorts but they're a separate namespace whose values may overlap numerically with ``SQ_*`` constants. """ from __future__ import annotations from enum import IntEnum class MessageType(IntEnum): """SQLI post-login message-type tags. Wire format: 2 bytes, big-endian.""" # --- Statement execution --- SQ_COMMAND = 1 SQ_PREPARE = 2 SQ_CURNAME = 3 SQ_ID = 4 SQ_BIND = 5 SQ_OPEN = 6 SQ_EXECUTE = 7 SQ_DESCRIBE = 8 SQ_NFETCH = 9 SQ_CLOSE = 10 SQ_RELEASE = 11 SQ_NDESCRIBE = 22 # numerical describe — request column metadata after a PREPARE/COMMAND SQ_WANTDONE = 49 # request a SQ_DONE completion notification # Phase 18: server-side scrollable cursor. SQ_SFETCH = 23 # scroll-fetch: ``[short SFETCH][short scrolltype] # [int target][short bufSize]``. scrolltype values # per JDBC IfxSqli.getaRow: 1=NEXT, 4=LAST, 6=ABSOLUTE. SQ_SCROLL = 24 # cursor-open modifier — emitted *before* SQ_OPEN # to mark the cursor as scrollable. Server keeps # the result set materialized for random access. SQ_TUPID = 25 # server response tag carrying the row's 1-indexed # position. Body: ``[int tupleId]``. Sent before # SQ_TUPLE in scrollable-cursor responses. # --- Per-PDU framing --- SQ_EOT = 12 # end-of-transmission / flush marker; ends every PDU SQ_ERR = 13 # error response from the server SQ_TUPLE = 14 # one row of result data SQ_DONE = 15 # statement / result-set completion SQ_XACTSTAT = 99 # transaction-state event (logged DBs only). Body: # ``[short xcEvent][short xcNewLevel][short xcOldLevel]``. See # ``IfxSqli.receiveXactstat`` and the Phase 7 DECISION_LOG entry. # --- Transactions --- SQ_CMMTWORK = 19 SQ_RBWORK = 20 SQ_SVPOINT = 21 SQ_BEGIN = 35 SQ_DBOPEN = 36 SQ_DBCLOSE = 37 SQ_DBLIST = 26 # --- Connection lifecycle (post-login) --- SQ_VERSION = 53 SQ_EXIT = 56 # client-initiated session terminate (also returned as ack) SQ_INFO = 81 # info request, with sub-codes (see ``InfoSubtype`` below) SQ_CONNECT = 112 SQ_SETCONN = 113 SQ_DISCONNECT = 114 SQ_PROTOCOLS = 126 # --- Auth (server-initiated challenge/response, e.g. PAM) --- SQ_ACCEPT = 127 SQ_ACK = 128 SQ_CHALLENGE = 129 SQ_RESPONSE = 130 # --- Savepoints (newer) --- SQ_SQLISETSVPT = 137 SQ_SQLIRELSVPT = 138 SQ_SQLIRBACKSVPT = 139 # --- XA (distributed transactions) — Phase 6+ --- SQ_XROLLBACK = 65 SQ_XCLOSE = 66 SQ_XCOMMIT = 67 SQ_XEND = 68 SQ_XFORGET = 69 SQ_XPREPARE = 70 SQ_XRECOVER = 71 SQ_XSTART = 72 SQ_XERR = 73 SQ_XASTATE = 74 SQ_XOPEN = 82 # --- BLOB / LOB --- # Phase 8 (BYTE/TEXT in-row blobs) SQ_FETCHBLOB = 38 SQ_BLOB = 39 SQ_BBIND = 41 SQ_SBBIND = 52 SQ_FILE_READ = 106 SQ_FILE_WRITE = 107 # Phase 9+ (smart-LOB BLOB/CLOB) SQ_LODATA = 97 # smart-LOB data transfer with sub-commands: # 0=LO_READ, 1=LO_READWITHSEEK, 2=LO_WRITE. # Body: [short subCom][short loFd][int length] # [short bufSize=32000] (+ [int8 offset][short whence] # for LO_READWITHSEEK). See IfxSqli.sendLoData line 4864. SQ_GETROUTINE = 101 # request a routine handle by signature. # Body: [byte isRoutineById][int sigLen] # [sig bytes][pad if odd][short fparamFlag]. # Response is the same tag with body # [short dbNameLen][dbName][int handle]. SQ_EXFPROUTINE = 102 # execute a fast-path routine with bound # params. Body: [char dbName][int handle] # [short paramCount][short fparamFlag] # [SQ_BIND-format params]. SQ_FPROUTINE = 103 # response tag: fast-path return-value descriptor. # Body: [short numReturns] then per return: # [short type][maybe UDT info][short ind] # [short prec][data]. SQ_FPARAM = 104 # parameter metadata for SQ_FPROUTINE # --- RPC sub-protocol (range 200-205) — Phase 6+ --- SQ_INVOKE = 200 SQ_REPLY = 201 SQ_EXCEPTION = 202 SQ_VERSION_REQ = 203 SQ_VERSION_REPLY = 204 SQ_AMFPARAM = 205 class InfoSubtype(IntEnum): """Sub-codes for the ``SQ_INFO`` message body.""" INFO_DONE = 0 INFO_REQUEST = 1 INFO_VERSION = 2 INFO_TYPE = 3 INFO_CAPABILITY = 4 INFO_DB = 5 INFO_ENV = 6 class LoginMarker(IntEnum): """Login-PDU section markers from ``com.informix.asf.Connection``. These appear inside the binary login PDU as 16-bit shorts and tag the structural sub-blocks (association header, capability section, env vars, process info, etc.). Numerically distinct from ``MessageType``; do not mix the two. See ``docs/PROTOCOL_NOTES.md`` §3 for the full byte-by-byte layout. """ SQ_ASSOC = 100 # start of "association" record SQ_ASCBINARY = 101 # binary-format indicator SQ_ASCINITRESP = 102 # init response (error block follows in some paths) SQ_ASCDBLIST = 103 SQ_ASCINITREQ = 104 # init request marker (paired with ASF_XCONNECT=11) SQ_ASCENV = 106 # environment-vars sub-block SQ_ASCPINFO = 107 # process-info sub-block SQ_ASCBPARMS = 108 # binary parameters block SQ_ASSOCBIND = 110 SQ_ASSOCRESP = 111 SQ_ASCMISC_60 = 116 # misc / AppName section SQ_ASCEOT = 127 # end-of-PDU marker for the login class SLHeader(IntEnum): """SL header constants for the 6-byte login envelope.""" # slType byte (offset 2 of SLheader) SLTYPE_CONREQ = 1 # client → server: connection request SLTYPE_CONACC = 2 # server → client: connection accepted SLTYPE_CONREJ = 3 # server → client: connection rejected SLTYPE_REDIRECT = 13 # server → client: redirect to another node # slAttribute byte (offset 3 of SLheader): protocol version PF_PROT_SQLI_0600 = 60 # SQLI protocol family 6.00 (current) PF_PROT_SQLI_WITH_CSS = 61 # variant with column-storage support class StmtOptions(IntEnum): """Bit flags packed into the login-PDU stmtoptions int.""" ASF_AMBIG_SEOL = 3 # bits 0+1 (always set) ASF_GRPREF = 0x02000000 # bit 25 — sqlhosts group reference ASF_TRUSTCTXT = 0x04000000 # bit 26 — trusted context # Hardcoded constant strings emitted in the binary login PDU. # These are NOT free parameters — they identify our wire client to the server # and must match what IBM's JDBC driver sends, byte-for-byte. APPL_TYPE = b"sqlexec\x00\x00\x00\x00\x00" # 12 bytes, fixed-width nul-padded APPL_ID = b"sqli" # 4 bytes (length-prefix says 5 because of trailing nul) PROT_SQLIOL = b"ol\x00\x00\x00\x00\x00\x00" # 8 bytes; SQLI/OL protocol identifier NET_TLITCP = b"tlitcp\x00\x00" # 8 bytes; "TLI over TCP" network type FLOAT_TYPE = b"IEEEM" # 5 bytes; declares we want IEEE 754 float encoding CLIENT_VERSION = b"9.280" # 5 bytes; hardcoded by JDBC, NOT a real version CLIENT_SERIAL = b"RDS#R000000" # 11 bytes; hardcoded marketing/license artifact # Buffer / size constants from com.informix.asf.Connection MAX_BUFF_SIZE = 32768 MIN_BUFF_SIZE = 140 STREAM_BUF_SIZE = 4096 PFCONREQ_BUF_SIZE = 2048 SL_HEADER_SIZE = 6 # UTYPE_INTERNET — declares we're connecting over IP (vs. shared-memory etc.) UTYPE_INTERNET = 1 # ASF_XCONNECT — paired with SQ_ASCINITREQ in the login PDU init-request marker ASF_XCONNECT = 11