Форматы сообщений
В этом разделе подробно описан формат каждого сообщения. Каждое сообщение помечено, чтобы указать, что оно может быть отправлено фронтендом (F), бэкендом (B) или обоими (F & B). Обратите внимание, что хотя каждое сообщение содержит счетчик байтов в начале, формат сообщения определен таким образом, что конец сообщения можно найти без ссылки на счетчик байтов. Это облегчает проверку достоверности. (Сообщение CopyData является исключением, потому что оно является частью потока данных; содержимое каждого отдельного сообщения CopyData не может быть интерпретировано самостоятельно).
AuthenticationOk (B)
Byte1('R')
Идентифицирует сообщение как запрос аутентификации.
Int32(8)
Длина содержимого сообщения в байтах, включая self.
Int32(0)
Указывает, что аутентификация прошла успешно.
AuthenticationKerberosV5 (B)
Byte1('R')
Идентифицирует сообщение как запрос аутентификации.
Int32(8)
Длина содержимого сообщения в байтах, включая self.
Int32(2)
Указывает, что требуется аутентификация Kerberos V5.
AuthenticationCleartextPassword (B)
Byte1('R')
Идентифицирует сообщение как запрос аутентификации.
Int32(8)
Длина содержимого сообщения в байтах, включая self.
Int32(3)
Указывает, что требуется пароль с открытым текстом.
AuthenticationMD5Password (B)
Byte1('R')
Идентифицирует сообщение как запрос аутентификации.
Int32(12)
Длина содержимого сообщения в байтах, включая self.
Int32(5)
Указывает, что требуется пароль, зашифрованный в MD5.
Byte4
Соль, которую следует использовать при шифровании пароля.
AuthenticationSCMCredential (B)
Byte1('R')
Идентифицирует сообщение как запрос аутентификации.
Int32(8)
Длина содержимого сообщения в байтах, включая self.
Int32(6)
Указывает, что требуется сообщение о полномочиях SCM.
AuthenticationGSS (B)
Byte1('R')
Идентифицирует сообщение как запрос аутентификации.
Int32(8)
Длина содержимого сообщения в байтах, включая self.
Int32(7)
Указывает, что требуется аутентификация GSSAPI.
AuthenticationGSSContinue (B)
Byte1('R')
Идентифицирует сообщение как запрос аутентификации.
Int32
Длина содержимого сообщения в байтах, включая self.
Int32(8)
Указывает, что это сообщение содержит данные GSSAPI или SSPI.
Byten
Данные аутентификации GSSAPI или SSPI.
AuthenticationSSPI (B)
Byte1('R')
Идентифицирует сообщение как запрос аутентификации.
Int32(8)
Длина содержимого сообщения в байтах, включая self.
Int32(9)
Указывает, что требуется аутентификация SSPI.
AuthenticationSASL (B)
Byte1('R')
Идентифи цирует сообщение как запрос аутентификации.
Int32
Длина содержимого сообщения в байтах, включая self.
Int32(10)
Указывает, что требуется аутентификация SASL.
Тело сообщения представляет собой список механизмов аутентификации SASL, расположенных в порядке предпочтения сервера. После последнего имени механизма аутентификации требуется нулевой байт в качестве терминатора. Для каждого механизма существует следующее:
String
Имя механизма аутентификации SASL.
AuthenticationSASLContinue (B)
Byte1('R')
Идентифицирует сообщение как запрос аутентификации.
Int32
Длина содержимого сообщения в байтах, включая self.
Int32(11)
Указывает, что это сообщение содержит вызов SASL.
Byten
Данные SASL, специфичные для используемого механизма SASL.
AuthenticationSASLFinal (B)
Byte1('R')
Идентифицирует сообщение как запрос аутентификации.
Int32
Длина содержимого сообщения в байтах, включая self.
Int32(12)
Указывает, что аутентификация SASL завершена.
Byten
Результат SASL - "дополнительные данные", специфичные для используемого механизма SASL.
BackendKeyData (B)
Byte1('K')
Идентифицирует сообщение как ключевые данные отмены. Фронтенд должен сохранить эти значения, если он хочет иметь возможность выдавать сообщения CancelRequest в дальнейшем.
Int32(12)
Длина содержимого сообщения в байтах, включая self.
Int32
Идентификатор процесса этого бэкэнда.
Int32
Секретный ключ этого бэкэнда.
Bind (F)
Byte1('B')
Идентифицирует сообщение как команду Bind.
Int32
Длина содержимого сообщения в байтах, включая self.
String
Имя портала назначения (пустая строка выбирает безымянный портал).
String
Имя исходного подготовленного оператора (пустая строка выбирает безымянный подготовленный оператор).
Int16
Количество следующих за ним кодов формата параметров (обозначается C ниже). Это может быть ноль, указывающий на отсутствие параметров или на то, что все параметры используют формат по умолчанию (текст); или единица, в этом случае указанный код формата применяется ко всем параметрам; или может быть равно фактическому количеству параметров.
Int16[C]
Коды формата параметров. Каждый из них должен быть равен нулю (текстовый) или единице (двоичный).
Int16
Количество последующих значений параметров (возможно, нулевое). Оно должно соответствовать количеству параметров, необходимых для запроса.
Далее для каждого параметра появляется следующая пара полей:
Int32
Длина значения параметра в байтах (в это число не входит сам параметр). Может быть равна нулю. В качестве особого случая -1 указывает на значение параметра NULL. В случае NULL байт значения не следует.
Byten
Значение параметра в формате, обозначенном соответствующим кодом формата. n - длина вышеуказанного параметра.
После последнего параметра появляются следующие поля:
Int16
Количество последующих кодов формата столбцов результатов (обозначается R ниже). Это может быть ноль, указывающий на отсутствие столбцов результатов или на то, что все столбцы результатов должны использовать формат по умолчанию (текст); или единица, в этом случае указанный код формата применяется ко всем столбцам результатов (если таковые имеются); или может быть равно фактическому количеству столбцов результатов запроса.
Int16[R]
Коды формата столбца результатов. Каждый из них должен быть равен нулю (текстовый) или единице (двоичный).
BindComplete (B)
Byte1('2')
Идентифицирует сообщение как индикатор Bind-complete.
Int32(4)
Длина содержимого сообщения в байтах, включая self.
CancelRequest (F)
Int32(16)
Длина содержимого сообщения в байтах, включая self.
Int32(80877102)
Код запроса на отмену. Значение выбирается таким образом, чтобы в старших 16 битах содержалось 1234, а в младших 16 битах - 5678. (Во избежание путаницы этот код не должен совпадать с номером версии протокола).
Int32
Идентификатор процесса целевого бэкенда.
Int32
Секретный ключ для целевого бэкенда.
Close (F)
Byte1('C')
Идентифицирует сообщение как команду "Закрыть".
Int32
Длина содержимого сообщения в байтах, включая self.
Byte1
'S', чтобы закрыть подготовленный отчет; или 'P', чтобы закрыть портал.
String
Имя подготовленного отчета или портала, который нужно закрыть (пустая строка выбирает безымянный подготовленный отчет или портал).
CloseComplete (B)
Byte1('3')
Идентифицирует сообщение как индикатор "Закрытие-завершение".
Int32(4)
Длина содержимого сообщения в байтах, включая self.
CommandComplete (B)
Byte1('C')
Идентифицирует сообщение как ответ, завершенный командой.
Int32
Длина содержимого сообщения в байтах, включая self.
String
Метка команды. Обычно это одно слово, которое определяет, какая команда SQL была выполнена.
Для команды INSERT
тег имеет вид INSERT
oid rows, где rows - количество вставленных строк. oid раньше был объектным идентификатором вставленной строки, если rows был равен 1, а целевая таблица имела OID, но системные столбцы OID больше не поддерживаются; поэтому oid всегда равен 0.
Для команды DELETE
тег имеет вид DELETE
rows, где rows - это количество удаляемых строк.
Для команды UPDATE
тег UPDATE
rows, где rows - количество обновленных строк.
Для команд ы MERGE
тег MERGE
rows, где rows - это количество вставленных, обновленных или удаленных строк.
Для команды SELECT
или CREATE TABLE AS
тег SELECT
rows, где rows количество полученных строк.
Для команды MOVE
тег MOVE rows, где rows - количество строк, на которые изменилась позиция курсора.
Для команды FETCH
тег имеет вид FETCH
rows, где rows - количество строк, которые были получены из курсора.
Для команды COPY
тег COPY
rows, где rows - количество скопированных строк. (Примечание: счетчик строк появляется только в PostgreSQL 8.2 и более поздних версиях).
CopyData (F & B)
Byte1('d')
Идентифицирует сообщение как данные COPY
.
Int32
Длина содержимого сообщения в байтах, включая self.
Byten
Данные, составляющие часть потока данных COPY
. Сообщения, отправленные с бэкенда, всегда будут соответствовать отдельным строкам данных, но сообщения, отправленные фронтендами, могут разделять поток данных произвольным образом.
CopyDone (F & B)
Byte1('c')
Идентифицирует сообще ние как индикатор COPY
-complete.
Int32(4)
Длина содержимого сообщения в байтах, включая self.
CopyFail (F)
Byte1('f')
Идентифицирует сообщение как индикатор сбоя COPY
.
Int32
Длина содержимого сообщения в байтах, включая self.
String
Сообщение об ошибке, сообщающее о причине сбоя.
CopyInResponse (B)
Byte1('G')
Идентифицирует сообщение как ответ Start Copy In. Теперь фронтенд должен отправить данные для копирования (если он не готов к этому, отправьте сообщение CopyFail).
Int32
Длина содержимого сообщения в байтах, включая self.
Int8
0 означает, что общий формат COPY является текстовым (строки отделяются новыми строками, столбцы - символами-разделителями и т. д.). 1 означает, что общий формат копии является двоичным (аналогично формату DataRow).
Int16
Количество столбцов в данных, которые необходимо скопировать (обозначается N ниже).
Int16[N]
Коды формата, которые будут использоваться для каждого столбца. Каждый из них должен быть равен нулю (текстовый) или единице (двоичный). Все они должны быть нулевыми, если общий формат копии - текстовый.
CopyOutResponse (B)
Byte1('H')
Идентифицирует сообщение как ответ Start Copy Out. За этим сообщением последуют данные копирования.
Int32
Длина содержимого сообщения в байтах, включая self.
Int8
0 означает, что общий формат COPY является текстовым (строки отделяются новыми строками, столбцы - символами-разделителями и т. д.). 1 означает, что общий формат копии является двоичным (аналогично формату DataRow).
Int16
Количество столбцов в данных, которые необходимо скопировать (обозначается N ниже).
Int16[N]
Коды формата, которые будут использоваться для каждого столбца. Каждый из них должен быть равен нулю (текстовый) или единице (двоичный). Все они должны быть нулевыми, если общий формат копии - текстовый.
CopyBothResponse (B)
Byte1('W')
Идентифицирует сообщение как ответ Start Copy Both. Это сообщение используется только для потоковой репликации.
Int32
Длина содержимого сообщения в байтах, включая self.
Int8
0 означает, что общий формат COPY является текстовым (строки разделены новыми строками, столбцы разделены символами-разделителями и т. д.). 1 означает, что общий формат копии является двоичным (аналогично формату DataRow).
Int16
Количество столбцов в данных, которые необходимо скопировать (обозначается N ниже).
Int16[N]
Коды формата, которые будут использоваться для каждого столбца. Каждый из них должен быть равен нулю (текстовый) или единице (двоичный). Все они должны быть нулевыми, если общий формат копии - текстовый.
DataRow (B)
Byte1('D')
Идентифицирует сообщение как строку данных.
Int32
Длина содержимого сообщения в байтах, включая self.
Int16
Количество значений столбца, которые следуют за ним (возможно, нулевое).
Затем для каждого столбца появится следующая пара полей:
Int32
Длина значения столбца, в байтах (в это число не входит сам столбец). Может быть равна нулю. В качестве особого случая -1 указывает на значение столбца NULL. В случае NULL байт значения не следует.
Byten
Значение столбца в формате, обозначенном соответствующим кодом формата. n - длина вышеуказанного столбца.
Describe (F)
Byte1('D')
Идентифицирует сообщение как команду Describe.
Int32
Длина содержимого сообщения в байтах, включая self.
Byte1
"S" - для описания подготовленного заявления; или "P" - для описания портала.
String
Имя подготовленного отчета или портала для описания (пустая строка выбирает безымянный подготовленный отчет или портал).
EmptyQueryResponse (B)
Byte1('I')
Идентифицирует сообщение как ответ на пустую строку запроса. (Этот параметр заменяет Com- mandComplete).
Int32(4)
Длина содержимого сообщения в байтах, включая self.
ErrorResponse (B)
Byte1('E')
Идентифицирует сообщение как ошибку.
Int32
Длина содержимого сообщения в байтах, включая self.
Тело сообщения состоит из одного или нескольких идентифицированных полей, за которыми следует нулевой байт в качестве терминатора. Поля могут располагаться в любом порядке. Для каждого поля существует следующее:
Byte1
Код, идентифицирующий тип поля; если он равен нулю, то это терминатор сообщения и за ним не следует никакой строк и. Определенные в настоящее время типы полей перечислены в разделе «Поля сообщений с ошибками и замечаниями». Поскольку в будущем могут быть добавлены дополнительные типы полей, фронтенды должны молча игнорировать поля с нераспознанным типом.
String
Значение поля.
Execute (F)
Byte1('E')
Идентифицирует сообщение как команду Execute.
Int32
Длина содержимого сообщения в байтах, включая self.
String
Имя портала для выполнения (пустая строка выбирает безымянный портал).
Int32
Максимальное количество возвращаемых строк, если портал содержит запрос, возвращающий строки (в противном случае игнорируется). Ноль означает "без ограничений".
Flush (F)
Byte1('H')
Идентифицирует сообщение как команду Flush.
Int32(4)
Длина содержимого сообщения в байтах, включая self.
FunctionCall (F)
Byte1('F')
Идентифицирует сообщение как вызов функции.
Int32
Длина содержимого сообщения в байтах, включая self.
Int32
Указывает идентификатор объекта функции для вызова.
Int16
Количество кодов формата аргументов, которые следуют за ним (обозначается C ниже). Это может быть ноль, чтобы указать, что аргументов нет или что все аргументы используют формат по умолчанию (текст); или единица, в этом случае указанный код формата применяется ко всем аргументам; или может быть равно фактическому количеству аргументов.
Int16[C]
Коды формата аргумента. Каждый из них должен быть равен нулю (текстовый) или единице (двоичный).
Int16
Указывает количество аргументов, передаваемых функции.
Далее для каждого аргумента появляется следующая пара полей:
Int32
Длина значения аргумента в байтах (в это число не входит сам аргумент). Может быть равна нулю. В качестве особого случая -1 указывает на NULL-значение аргумента. В случае NULL байт значения не следует.
Byten
Значение аргумента в формате, указанном соответствующим кодом формата. n - длина аргумента.
После последнего аргумента появится следующее поле:
Int16
Код формата для результата функции. В настоящее время должен быть равен нулю (тексто вый) или единице (двоичный).
FunctionCallResponse (B)
Byte1('V')
Идентифицирует сообщение как результат вызова функции.
Int32
Длина содержимого сообщения в байтах, включая self.
Int32
Длина значения результата функции, в байтах (в это число не входит сама функция). Может быть равна нулю. В качестве особого случая -1 указывает на NULL-результат функции. В случае NULL байт значения не следует.
Byten
Значение результата функции в формате, указанном соответствующим кодом формата. n - длина вышеуказанного значения.
GSSENCRequest (F)
Int32(8)
Длина содержимого сообщения в байтах, включая self.
Int32(80877104)
Код запроса шифрования GSSAPI. Значение выбирается таким образом, чтобы в старших 16 битах содержалось 1234, а в младших 16 битах - 5680. (Во избежание путаницы этот код не должен совпадать с номером версии протокола).
GSSResponse (F)
Byte1('p')
Идентифицирует сообщение как ответ GSSAPI или SSPI. Обратите внимание, что этот параметр также используется для ответных сообщений SASL и паролей. Точный тип сообщения можно определить из контекста.
Int32
Длина содержимого сообщения в байтах, включая self.
Byten
Данные сообщения, специфичные для GSSAPI/SSPI.
NegotiateProtocolVersion (B)
Byte1('v')
Идентифицирует сообщение как сообщение согласования версии протокола.
Int32
Длина содержимого сообщения в байтах, включая self.
Int32
Самая новая минорная версия протокола, поддерживаемая сервером, для мажорной версии протокола, запрашиваемой клиентом.
Int32
Количество опций протокола, не распознанных сервером.
Затем, для варианта протокола, не распознанного сервером, имеется следующее:
String
Имя опции.
NoData (B)
Byte1('n')
Идентифицирует сообщение как индикатор отсутствия данных.
Int32(4)
Длина содержимого сообщения в байтах, включая self.
NoticeResponse (B)
Byte1('N')
Идентифицирует сообщение как уведомление.
Int32
Длина содержимого сообщения в байтах, включая self.
Тело сообщения состоит из одного или нескольких идентифицированных полей, за которыми следует нулевой байт в качестве терминат ора. Поля могут располагаться в любом порядке. Для каждого поля существует следующее:
Byte1
Код, идентифицирующий тип поля; если он равен нулю, то это терминатор сообщения, и за ним не следует никакой строки. Определенные в настоящее время типы полей перечислены в разделе «Поля сообщений с ошибками и замечаниями». Поскольку в будущем могут быть добавлены дополнительные типы полей, фронтенды должны молча игнорировать поля с нераспознанным типом.
String
Значение поля.
NotificationResponse (B)
Byte1('A')
Идентифицирует сообщение как ответ на уведомление.
Int32
Длина содержимого сообщения в байтах, включая self.
Int32
Идентификатор процесса уведомляющего бэкэнд-процесса.
String
Имя канала, на котором было поднято уведомление.
String
Строка "полезной нагрузки", переданная из процесса уведомления.
ParameterDescription (B)
Byte1('t')
Идентифицирует сообщение как описание параметра.
Int32
Длина содержимого сообщения в байтах, включая self.
Int16
Количество параметров, используемых оператором (может быть равно нулю).
Тогда для каждого параметра существует следующее:
Int32
Указывает идентификатор объекта типа данных параметра.
ParameterStatus (B)
Byte1('S')
Идентифицирует сообщение как отчет о состоянии параметров времени выполнения.
Int32
Длина содержимого сообщения в байтах, включая self.
String
Имя параметра времени выполнения, о котором сообщается.
String
Текущее значение параметра.
Parse (F)
Byte1('P')
Идентифицирует сообщение как команду разбора.
Int32
Длина содержимого сообщения в байтах, включая self.
String
Имя целевого подготовленного оператора (пустая строка выбирает безымянный подготовленный оператор).
String
Строка запроса, которая будет разобрана.
Int16
Количество заданных типов данных параметров (может быть равно нулю). Обратите внимание, что это не показатель количества параметров, которые могут появиться в строке запроса, а только то количество, для которого фронтенд хочет предварительно указать типы.
Тогда для каждого параметра существует следующее:
Int32
Указывает идентификатор объекта типа данных параметра. Помещение здесь нуля эквивалентно оставлению типа неопределенным.
ParseComplete (B)
Byte1('1')
Идентифицирует сообщение как индикатор Parse-complete.
Int32(4)
Длина содержимого сообщения в байтах, включая self.
PasswordMessage (F)
Byte1('p')
Идентифицирует сообщение как ответ на пароль. Обратите внимание, что этот параметр также используется для ответных сообщений GSSAPI, SSPI и SASL. Точный тип сообщения можно определить из контекста.
Int32
Длина содержимого сообщения в байтах, включая self.
String
Пароль (зашифрованный, если требуется).
PortalSuspended (B)
Byte1('s')
Идентифицирует сообщение как индикатор приостановки портала. Обратите внимание, что он появляется только в том случае, если был достигнут предел количества строк в сообщении Execute.
Int32(4)
Длина содержимого сообщения в байтах, включая self.
Query (F)
Byte1('Q')
Идентифицирует сообщение как простой запрос.
Int32
Длина содержимого сообщения в байтах, включая self.
String
Сама строка запроса.
ReadyForQuery (B)
Byte1('Z')
Определяет тип сообщения. ReadyForQuery отправляется всякий раз, когда бэкэнд готов к новому циклу запросов.
Int32(5)
Длина содержимого сообщения в байтах, включая self.
Byte1
Индикатор текущего состояния транзакции бэкенда. Возможные значения: 'I' - если простаивает (не находится в блоке транзакций); 'T' - если находится в блоке транзакций; или 'E' - если находится в блоке неудачных транзакций (запросы будут отклоняться до тех пор, пока блок не завершится).
RowDescription (B)
Byte1('T')
Идентифицирует сообщение как описание строки.
Int32
Длина содержимого сообщения в байтах, включая self.
Int16
Указывает количество полей в строке (может быть равно нулю).
Затем для каждого поля есть следующее:
String
Имя поля.
Int32
Если поле может быть идентифицировано как столбец определенной таблицы, то идентификатор объекта таблицы; в противном случае - ноль.
Int16
Если поле может быть идентифицировано как столбец определенной таблицы, то номер атрибута столбца; в противном случае - ноль.
Int32
Идентификатор объекта типа данных поля.
Int16
Размер типа данных (см. pg_type.typlen). Обратите внимание, что отрицательные значения обозначают типы с переменной шириной.
Int32
Модификатор типа (см. pg_attribute.atttypmod). Значение модификатора зависит от типа.
Int16
Код формата, используемый для данного поля. В настоящее время это ноль (текстовый) или единица (двоичный). В RowDescription, возвращенном из варианта Describe, код формата еще не известен и всегда будет равен нулю.
SASLInitialResponse (F)
Byte1('p')
Идентифицирует сообщение как первоначальный ответ SASL. Обратите внимание, что этот параметр также используется для сообщений GSSAPI, SSPI и ответа на пароль. Точный тип сообщения определяется из контекста.
Int32
Длина содержимого сообщения в байтах, включая self.
String
Имя механизма аутентификации SASL, выбранного клиентом.
Int32
Длина специфического для механизма SASL "Начального ответа клиента", который следует за ним, или -1, если начальный ответ отсутствует.
Byten
Специфический механизм SASL "Первоначальный ответ".
SASLResponse (F)
Byte1('p')
Идентифицирует сообщение как ответ SASL. Обратите внимание, что этот параметр также используется для сообщений GSSAPI, SSPI и парольных ответов. Точный тип сообщения можно определить из контекста.
Int32
Длина содержимого сообщения в байтах, включая self.
Byten
Данные сообщения, специфичные для механизма SASL.
SSLRequest (F)
Int32(8)
Длина содержимого сообщения в байтах, включая self.
Int32(80877103)
Код запроса SSL. Значение выбирается таким образом, чтобы в старших 16 битах содержалось 1234, а в младших 16 битах - 5679. (Чтобы избежать путаницы, этот код не должен совпадать с номером версии протокола).
StartupMessage (F)
Int32
Длина содержимого сообщения в байтах, включая self.
Int32(196608)
Номер версии протокола. Старшие 16 бит - это основной номер версии (3 для описываемого здесь протокола). Меньшие 16 бит - номер минорной версии (0 для описываемо го здесь протокола).
За номером версии протокола следует одна или несколько пар строк имен и значений параметров. После последней пары имя/значение требуется нулевой байт в качестве терминатора. Параметры могут располагаться в любом порядке. Пользователь является обязательным, остальные - необязательными. Каждый параметр задается как:
String
Имя параметра. В настоящее время распознаются следующие имена:
user
Имя пользователя базы данных для подключения. Обязательно; по умолчанию не задается.
database
База данных, к которой необходимо подключиться. По умолчанию - имя пользователя.
options
Аргументы командной строки для бэкенда. (Это устарело в пользу установки отдельных параметров времени выполнения.) Пробелы в этой строке считаются разделяющими аргументы, если они не экранированы обратной косой чертой (\); напишите \\\, чтобы представить буквенную обратную косую черту.
replication
Используется для подключения в режиме потоковой репликации, когда вместо операторов SQL может быть выдан небольшой набор команд репликации. Значение может быть true, false или data- base, по умолчанию - false. Подробности см. в разделе «Протокол потоковой репликации»
Помимо перечисленных выше, могут быть указаны и другие параметры. Имена параметров, начинающиеся с pq. зарезервированы для использования в качестве расширений протокола, в то время как другие рассматриваются как параметры времени выполнения, которые должны быть установлены во время запуска бэкенда. Такие параметры будут применены во время запуска бэкенда (после разбора аргументов командной строки, если таковые имеются) и будут действовать как параметры сессии по умолчанию.
String
Значение параметра.
Sync (F)
Byte1('S')
Идентифицирует сообщение как команду синхронизации.
Int32(4)
Длина содержимого сообщения в байтах, включая self.
Terminate (F)
Byte1('X')
Идентифицирует сообщение как завершающее.
Int32(4)
Длина содержимого сообщения в байтах, включая self.