Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

sql.mysql.packets

import sql.mysql.packets

sql lifts part of this module out to its own top level; each name below is shown with the path that reaches it. Anything still spelled sql.mysql.packets.* needs import sql.mysql.packets.

The MySQL packet layer: framing, sequence numbering, compression and the integer and string encodings every message above is built from.

A MySQL connection is a stream of packets, each a three byte little-endian length, a one byte sequence number, and that many bytes of payload. The sequence number restarts at zero with every command a client sends and increments for each packet either side writes until that command is answered, which is how both ends notice a packet that went missing or arrived twice.

Why a packet is not always a message

The length field is three bytes, so a payload of 16777215 bytes is the largest that can be described. A message that long is split, and the split is signalled by a packet of exactly that size: the reader has to keep reading until it sees a shorter one. A message whose length is an exact multiple of the maximum therefore ends with an empty packet, which exists only to say the message is over.

Constants

MAX_PAYLOAD

sql.mysql.packets.MAX_PAYLOAD = 16777215

The largest payload a single packet can carry. A payload of exactly this size is always continued in the next packet.

COMPRESS_THRESHOLD

sql.mysql.packets.COMPRESS_THRESHOLD = 50

Below this, a compressed packet is sent uncompressed instead. Small payloads grow rather than shrink under zlib, and the protocol allows either, so the choice is the sender’s.

LENENC_NULL

sql.mysql.packets.LENENC_NULL = 251

The first byte of a length-encoded integer that means the value is NULL. Only meaningful where a column value is expected.

EXACT_INTEGER_LIMIT

sql.mysql.packets.EXACT_INTEGER_LIMIT = 9007199254740992

Largest integer a Zuri number holds exactly. A wider value read off the wire becomes a bigint rather than quietly losing its low bits.

Classes

Writer

class sql.mysql.packets.Writer

Builds one packet payload.

Bytes accumulate in a list, which payload() turns into the real thing. Every appending method returns the writer so that building a message reads as one expression.

Writer.byte()

sql.mysql.packets.Writer.byte(value: number) -> Writer

Appends one byte.

Parameters

  • value (number) — Only the low eight bits are used.

Returns Writer

Writer.int2()

sql.mysql.packets.Writer.int2(value: number) -> Writer

Appends a little-endian 16 bit integer.

Parameters

  • value (number)

Returns Writer

Writer.int3()

sql.mysql.packets.Writer.int3(value: number) -> Writer

Appends a little-endian 24 bit integer.

Parameters

  • value (number)

Returns Writer

Writer.int4()

sql.mysql.packets.Writer.int4(value: number) -> Writer

Appends a little-endian 32 bit integer.

Values are written unsigned. A negative number is written as its two’s complement, which is what the protocol expects wherever a signed field appears.

Parameters

  • value (number)

Returns Writer

Writer.int8()

sql.mysql.packets.Writer.int8(value) -> Writer

Appends a little-endian 64 bit integer.

Parameters

  • value (number|bigint)

Returns Writer

Writer.lenenc_int()

sql.mysql.packets.Writer.lenenc_int(value) -> Writer

Appends a length-encoded integer, in the shortest form that holds it.

Parameters

  • value (number|bigint)

Returns Writer

Writer.lenenc_string()

sql.mysql.packets.Writer.lenenc_string(value) -> Writer

Appends a string with its length in front of it.

Parameters

  • value (string|bytes)

Returns Writer

Writer.cstring()

sql.mysql.packets.Writer.cstring(value: string) -> Writer

Appends a string and the zero byte that ends it.

Parameters

  • value (string)

Returns Writer

Writer.string()

sql.mysql.packets.Writer.string(value) -> Writer

Appends a string with no length and no terminator, which only works where the reader knows the length some other way.

Parameters

  • value (string|bytes)

Returns Writer

Writer.zeros()

sql.mysql.packets.Writer.zeros(count: number) -> Writer

Appends count zero bytes, for the filler fields the protocol reserves and does not use.

Parameters

  • count (number)

Returns Writer

Writer.raw()

sql.mysql.packets.Writer.raw(values) -> Writer

Appends raw bytes.

Parameters

  • values (bytes|list)

Returns Writer

Writer.length()

sql.mysql.packets.Writer.length() -> number

How many bytes have accumulated.

Returns number

Writer.payload()

sql.mysql.packets.Writer.payload() -> bytes

The finished payload.

The buffer itself, not a copy, so the writer is done once this has been called.

Returns bytes

Cursor

class sql.mysql.packets.Cursor

Reads values out of one packet payload, keeping its own position.

Every read advances past what it read, so a message is decoded by naming its fields in order rather than by tracking offsets.

Constructor

sql.mysql.packets.Cursor(data)

Parameters

  • data (bytes) — One packet’s payload.

Cursor.remaining()

sql.mysql.packets.Cursor.remaining() -> number

How many bytes are left unread.

Returns number

Cursor.at_end()

sql.mysql.packets.Cursor.at_end() -> bool

Whether everything has been read.

Returns bool

Cursor.peek()

sql.mysql.packets.Cursor.peek() -> number|nil

The next byte without consuming it, or nil at the end.

Returns number|nil

Cursor.skip()

sql.mysql.packets.Cursor.skip(count: number) -> Cursor

Skips count bytes.

Parameters

  • count (number)

Returns Cursor

Cursor.byte()

sql.mysql.packets.Cursor.byte() -> number

Reads one byte.

Returns number

Cursor.int2()

sql.mysql.packets.Cursor.int2() -> number

Reads a little-endian 16 bit integer.

Returns number

Cursor.int3()

sql.mysql.packets.Cursor.int3() -> number

Reads a little-endian 24 bit integer.

Returns number

Cursor.int4()

sql.mysql.packets.Cursor.int4() -> number

Reads a little-endian 32 bit integer, unsigned.

Returns number

Cursor.int8()

sql.mysql.packets.Cursor.int8() -> number|bigint

Reads a little-endian 64 bit integer, unsigned.

Returns number|bigint — A bigint where the value will not fit in a number exactly.

Cursor.lenenc_int()

sql.mysql.packets.Cursor.lenenc_int() -> number|bigint|nil

Reads a length-encoded integer.

Returns number|bigint|nil — nil where the value is NULL, which only happens in a row.

Cursor.lenenc_bytes()

sql.mysql.packets.Cursor.lenenc_bytes() -> bytes|nil

Reads a length-encoded string as raw bytes.

Returns bytes|nil

Cursor.lenenc_string()

sql.mysql.packets.Cursor.lenenc_string() -> string|nil

Reads a length-encoded string as text.

Returns string|nil

Cursor.cstring()

sql.mysql.packets.Cursor.cstring() -> string

Reads up to the next zero byte, and past it.

A payload that simply ends is treated as terminated, since several messages end with a string whose terminator the server omits when nothing follows it.

Returns string

Cursor.fixed()

sql.mysql.packets.Cursor.fixed(count: number) -> bytes

Reads exactly count bytes.

Parameters

  • count (number)

Returns bytes

Cursor.rest()

sql.mysql.packets.Cursor.rest() -> bytes

Reads everything that is left.

Returns bytes


2026, Richard Ore and Zuri contributors