36.3. Функции для исполнения команд #
После того как соединение с сервером было успешно установлено, функции, описанные в этом разделе, используются для выполнения SQL-запросов и команд.
36.3.1. Главные функции #
PQexec#Передаёт команду серверу и ожидает результата.
PGresult *PQexec(PGconn *conn, const char *command);
Возвращает указатель на
PGresultили, возможно, пустой указатель (null). Как правило, возвращается непустой указатель, исключением являются ситуации нехватки памяти или серьёзные ошибки, такие, как невозможность отправки команды серверу. Для проверки возвращаемого значения на наличие ошибок следует вызвать функциюPQresultStatus(в случае нулевого указателя она возвратитPGRES_FATAL_ERROR). Для получения дополнительной информации о таких ошибках используйте функциюPQerrorMessage.
Строка команды может включать в себя более одной SQL-команды (которые разделяются точкой с запятой). Несколько запросов, отправленных с помощью одного вызова PQexec, обрабатываются в рамках одной транзакции, если только команды BEGIN/COMMIT не включены явно в строку запроса, чтобы разделить его на несколько транзакций. (Подробнее о том, как сервер обрабатывает строки, включающие несколько команд, рассказывается в Подразделе 57.2.2.1.) Однако обратите внимание, что возвращаемая структура PGresult описывает только результат последней из выполненных команд, содержащихся в строке запроса. Если одна из команд завершается сбоем, то обработка строки запроса на этом останавливается, и возвращённая структура PGresult описывает состояние ошибки.
PQexecParams#Отправляет команду серверу и ожидает результата. Имеет возможность передать параметры отдельно от текста SQL-команды.
PGresult *PQexecParams(PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char * const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat);PQexecParamsподобнаPQexec, но предлагает дополнительную функциональность: значения параметров могут быть указаны отдельно от самой строки-команды, а результаты запроса могут быть затребованы либо в текстовом, либо в двоичном формате.Параметры функции следующие:
connОбъект, описывающий подключение, через которое пересылается команда.
commandСтрока SQL-команды, которая должна быть выполнена. Если используются параметры, то в строке команды на них ссылаются, как
$1,$2и т. д.nParamsЧисло предоставляемых параметров. Оно равно длине массивов
paramTypes[],paramValues[],paramLengths[]иparamFormats[]. (Указатели на массивы могут быть равныNULL, когдаnParamsравно нулю.)paramTypes[]Предписывает, посредством OID, типы данных, которые должны быть назначены параметрам. Если значение
paramTypesравноNULLили какой-либо отдельный элемент в массиве равен нулю, тогда сервер самостоятельно определит тип данных для параметра точно таким же образом, как он сделал бы для литеральной строки, тип которой не указан.paramValues[]Указывает фактические значения параметров. Нулевой указатель в этом массиве означает, что соответствующий параметр равен null; в противном случае указатель указывает на текстовую строку, завершающуюся нулевым символом (для текстового формата), или на двоичные данные в формате, которого ожидает сервер (для двоичного формата).
paramLengths[]Указывает фактические длины данных для параметров, представленных в двоичном формате. Он игнорируется для параметров, имеющих значение null, и для параметров, представленных в текстовом формате. Указатель на массив может быть нулевым, когда нет двоичных параметров.
paramFormats[]Указывает, являются ли параметры текстовыми (поместите нуль в элемент массива, соответствующий такому параметру) или двоичными (поместите единицу в элемент массива, соответствующий такому параметру). Если указатель на массив является нулевым, тогда все параметры считаются текстовыми строками.
Значения, переданные в двоичном формате, требуют знания внутреннего представления, которого ожидает сервер. Например, целые числа должны передаваться с использованием сетевого порядка байтов. Передача значений типа
numericтребует знания формата, в котором их хранит сервер.resultFormatТребует указать ноль, чтобы получить результаты в текстовом формате, или единицу, чтобы получить результаты в двоичном формате. (В настоящее время нет возможности получить различные столбцы результата в разных форматах, хотя это и возможно на уровне протокола, лежащего в основе подключений.)
Главным преимуществом PQexecParams перед PQexec является возможность отделить значения параметров от строки запроса. Это позволяет обойтись без кавычек и экранирующих символов, манипулирование которыми бывает трудоёмким и часто приводит к ошибкам.
В отличие от PQexec, PQexecParams позволяет включать не более одной SQL-команды в строку запроса. (В ней могут содержаться точки с запятой, однако может присутствовать не более одной непустой команды.) Это ограничение накладывается базовым протоколом, но оно приносит и некоторую пользу в качестве дополнительной защиты от атак методом SQL-инъекций.
Подсказка
Указание типов параметров с помощью OID является трудоёмким, особенно если вы предпочитаете не указывать явно значений OID в вашей программе. Однако вы можете избежать этого даже в случаях, когда сервер самостоятельно не может определить тип параметра или выбирает не тот тип, который вы хотите. В строке SQL-команды добавьте явное приведение типа для этого параметра, чтобы показать, какой тип данных вы будете отправлять. Например:
SELECT * FROM mytable WHERE x = $1::bigint;
Это приведёт к тому, что параметр $1 будет считаться имеющим тип bigint, в то время как по умолчанию ему был бы назначен тот же самый тип, что и x. Такое явное принятие решения о типе параметра либо с помощью описанного метода, либо путём задания числового OID строго рекомендуется, когда значения параметров отправляются в двоичном формате, поскольку двоичный формат имеет меньшую избыточность, чем текстовый, и поэтому гораздо менее вероятно, что сервер обнаружит ошибку несоответствия типов, допущенную вами.
PQprepare#Отправляет запрос, чтобы создать подготовленный оператор с конкретными параметрами, и ожидает завершения.
PGresult *PQprepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes);PQprepareсоздаёт подготовленный оператор для последующего исполнения с помощьюPQexecPrepared. Благодаря этому, команды, которые будут выполняться многократно, не потребуется разбирать и планировать каждый раз; за подробностями обратитесь к PREPARE.Функция создаёт подготовленный оператор с именем
stmtNameиз строкиquery, которая должна содержать единственную SQL-команду.stmtNameможет быть пустой строкой"", тогда будет создан неименованный оператор (в таком случае любой уже существующий неименованный оператор будет автоматически заменён), в противном случае, если имя оператора уже определено в текущем сеансе работы, будет ошибка. Если используются параметры, то в запросе к ним обращаются таким образом:$1,$2и т. д.nParamsпредставляет число параметров, типы данных для которых указаны в массивеparamTypes[]. (Указатель на массив может быть равенNULL, когда значениеnParamsравно нулю.)paramTypes[]указывает, посредством OID, типы данных, которые будут назначены параметрам. ЕслиparamTypesравенNULLили какой-либо элемент в этом массиве равен нулю, то сервер назначает тип данных соответствующему параметру точно таким же способом, как он сделал бы для литеральной строки, не имеющей типа. Также в запросе можно использовать параметры с номерами, большими, чемnParams; типы данных для них сервер также сможет подобрать. (См. описаниеPQdescribePrepared, где сказано, как можно определить, какие типы данных были подобраны).Как и при вызове
PQexec, результатом является объектPGresult, содержимое которого показывает успех или сбой на стороне сервера. Нулевой указатель означает нехватку памяти или невозможность вообще отправить команду. Для получения дополнительной информации о таких ошибках используйтеPQerrorMessage.
Подготовленные операторы для использования с PQexecPrepared можно также создать путём исполнения SQL-команд PREPARE.
PQexecPrepared#Отправляет запрос на исполнение подготовленного оператора с данными параметрами и ожидает результата.
PGresult *PQexecPrepared(PGconn *conn, const char *stmtName, int nParams, const char * const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat);PQexecPreparedподобнаPQexecParams, но команда, подлежащая исполнению, указывается путём передачи имени предварительно подготовленного оператора вместо передачи строки запроса. Эта возможность позволяет командам, которые вызываются многократно, подвергаться разбору и планированию только один раз, а не при каждом их исполнении. Оператор должен быть подготовлен предварительно в рамках текущего сеанса работы.Параметры идентичны
PQexecParams, за исключением того, что вместо строки запроса передаётся имя подготовленного оператора и отсутствует параметрparamTypes[](он не нужен, поскольку типы данных для параметров подготовленного оператора были определены при его создании).PQdescribePrepared#Передаёт запрос на получение информации об указанном подготовленном операторе и ожидает завершения.
PGresult *PQdescribePrepared(PGconn *conn, const char *stmtName);
PQdescribePreparedпозволяет приложению получить информацию о предварительно подготовленном операторе.Для ссылки на неименованный оператор значение
stmtNameможет быть пустой строкой""илиNULL, в противном случае оно должно быть именем существующего подготовленного оператора. В случае успешного выполнения возвращаетсяPGresultсо статусомPGRES_COMMAND_OK. ФункцииPQnparamsиPQparamtypeпозволяют извлечь изPGresultинформацию о параметрах подготовленного оператора, а функцииPQnfields,PQfname,PQftypeи т. п. предоставляют информацию о результирующих столбцах данного оператора (если они есть).PQdescribePortal#Передаёт запрос на получение информации об указанном портале и ожидает завершения.
PGresult *PQdescribePortal(PGconn *conn, const char *portalName);
PQdescribePortalпозволяет приложению получить информацию о предварительно созданном портале. (libpq не предоставляет прямого доступа к порталам, но вы можете использовать эту функцию для ознакомления со свойствами курсора, созданного с помощью SQL-командыDECLARE CURSOR.)Для ссылки на неименованный портал значение
portalNameможет быть пустой строкой""илиNULL, в противном случае оно должно быть именем существующего портала. В случае успешного завершения возвращаетсяPGresultсо статусомPGRES_COMMAND_OK. С помощью функцийPQnfields,PQfname,PQftypeи т. д. можно извлечь изPGresultинформацию о результирующих столбцах данного портала (если они есть).PQclosePrepared#Передаёт запрос на закрытие указанного подготовленного оператора и ожидает завершения.
PGresult *PQclosePrepared(PGconn *conn, const char *stmtName);
PQclosePreparedпозволяет приложению закрыть ранее подготовленный оператор. Закрытие оператора высвобождает все задействованные им ресурсы на сервере, а также позволяет переиспользовать его имя.Для ссылки на безымянный оператор значение
stmtNameможет быть пустой строкой""илиNULL. Если имя совпадает с именем существующего оператора, команда ничего не делает. В случае успешного завершения возвращаетсяPGresultсо статусомPGRES_COMMAND_OK.PQclosePortal#Передаёт запрос на закрытие указанного портала и ожидает завершения.
PGresult *PQclosePortal(PGconn *conn, const char *portalName);
PQclosePortalпозволяет приложению закрыть ранее созданный портал. Закрытие портала высвобождает все задействованные им ресурсы на сервере, а также позволяет переиспользовать его имя. (libpq не предоставляет прямого доступа к порталам, но вы можете использовать эту функцию, чтобы закрыть курсор, созданный с помощью SQL-командыDECLARE CURSOR.)Для ссылки на безымянный портал значение
portalNameможет быть пустой строкой""илиNULL. Если имя совпадает с именем существующего портала, команда ничего не делает. В случае успешного завершения возвращаетсяPGresultсо статусомPGRES_COMMAND_OK.
Структура PGresult содержит результат, возвращённый сервером. Разработчики приложений libpq должны тщательно поддерживать абстракцию PGresult. Для получения доступа к содержимому PGresult используйте функции доступа, описанные ниже. Избегайте непосредственного обращения к полям структуры PGresult, поскольку они могут измениться в будущем.
PQresultStatus#Возвращает статус результата выполнения команды.
ExecStatusType PQresultStatus(const PGresult *res);
PQresultStatusможет возвращать одно из следующих значений:PGRES_EMPTY_QUERY#Строка, отправленная серверу, была пустой.
PGRES_COMMAND_OK#Успешное завершение команды, не возвращающей никаких данных.
PGRES_TUPLES_OK#Успешное завершение команды, возвращающей данные (такой, как
SELECTилиSHOW).PGRES_COPY_OUT#Начат перенос данных Copy Out (с сервера).
PGRES_COPY_IN#Начат перенос данных Copy In (на сервер).
PGRES_BAD_RESPONSE#Ответ сервера не был распознан.
PGRES_NONFATAL_ERROR#Произошла некритическая ошибка (уведомление или предупреждение).
PGRES_FATAL_ERROR#Произошла критическая ошибка.
PGRES_COPY_BOTH#Начат перенос данных Copy In/Out (на сервер и с сервера). Эта функция в настоящее время используется только для потоковой репликации, поэтому такой статус не должен иметь место в обычных приложениях.
PGRES_SINGLE_TUPLE#Структура
PGresultсодержит только одну результирующую строку, возвращённую текущей командой. Этот статус имеет место только тогда, когда для данного запроса был выбран режим построчного вывода (см. Раздел 36.6).PGRES_TUPLES_CHUNK#Структура
PGresultсодержит несколько результирующих кортежей, возвращённых текущей командой. Этот статус имеет место только тогда, когда для данного запроса был выбран режим построчного вывода (см. Раздел 36.6). Количество кортежей не превысит ограниченияPQsetChunkedRowsMode.PGRES_PIPELINE_SYNC#PGresultпредставляет точку синхронизации в конвейерном режиме, запрошеннуюPQpipelineSyncилиPQsendPipelineSync. Этот статус возможен, только если выбран конвейерный режим.PGRES_PIPELINE_ABORTED#Структура
PGresultпредставляет конвейер, получивший ошибку от сервера. ФункцияPQgetResultдолжна вызываться неоднократно, и каждый раз она будет возвращать этот код состояния до конца текущего конвейера, после чего она вернётPGRES_PIPELINE_SYNCи сможет возобновиться нормальная обработка.
Если статус результата
PGRES_TUPLES_OK,PGRES_SINGLE_TUPLEилиPGRES_TUPLES_CHUNK, тогда для извлечения строк, возвращённых запросом, можно использовать функции, описанные ниже. Обратите внимание, что командаSELECT, даже когда она не извлекает ни одной строки, всё же показываетPGRES_TUPLES_OK.PGRES_COMMAND_OKпредназначен для команд, которые никогда не возвращают строки (INSERTилиUPDATEбез использования предложенияRETURNINGи др.). ОтветPGRES_EMPTY_QUERYможет указывать на наличие ошибки в клиентском программном обеспечении.Результат со статусом
PGRES_NONFATAL_ERRORникогда не будет возвращён напрямую функциейPQexecили другими функциями исполнения запросов; вместо этого результаты такого вида передаются обработчику уведомлений (см. Раздел 36.13).PQresStatus#Преобразует значение перечислимого типа, возвращённое функцией
PQresultStatus, в строковую константу, описывающую код статуса. Вызывающая функция не должна освобождать память, на которую указывает возвращаемый указатель.char *PQresStatus(ExecStatusType status);
PQresultErrorMessage#Возвращает сообщение об ошибке, связанное с командой, или пустую строку, если ошибки не произошло.
char *PQresultErrorMessage(const PGresult *res);
Если произошла ошибка, то возвращённая строка будет включать завершающий символ новой строки. Вызывающая функция не должна напрямую освобождать память, на которую указывает возвращаемый указатель. Она будет освобождена, когда соответствующий указатель
PGresultбудет передан функцииPQclear.Если непосредственно после вызова
PQexecилиPQgetResultвызвать функциюPQerrorMessage(для данного подключения), то она возвратит ту же самую строку, что иPQresultErrorMessage(для данного результата). ОднакоPGresultсохранит своё сообщение об ошибке до тех пор, пока не будет уничтожен, в то время как сообщение об ошибке, связанное с данным подключением, будет изменяться при выполнении последующих операций. Воспользуйтесь функциейPQresultErrorMessage, когда вы хотите узнать статус, связанный с конкретной структуройPGresult; используйте функциюPQerrorMessage, когда вы хотите узнать статус выполнения самой последней операции на данном соединении.PQresultVerboseErrorMessage#Возвращает переформатированную версию сообщения об ошибке, связанного с объектом
PGresult.char *PQresultVerboseErrorMessage(const PGresult *res, PGVerbosity verbosity, PGContextVisibility show_context);В некоторых ситуациях клиент может захотеть получить более подробную версию ранее выданного сообщения об ошибке. Эту потребность удовлетворяет функция
PQresultVerboseErrorMessage, формируя сообщение, которое было бы выдано функциейPQresultErrorMessage, если бы заданный уровень детализации был текущим для соединения в момент заполненияPGresult. Если же вPGresultне содержится ошибка, вместо этого выдаётся сообщение «PGresult is not an error result» (PGresult — не результат с ошибкой). Возвращаемое этой функцией сообщение завершается переводом строки.В отличие от многих других функций, извлекающих данные из
PGresult, результат этой функции — новая размещённая в памяти строка. Когда эта строка будет не нужна, вызывающий код должен освободить её место, вызвавPQfreemem().При нехватке памяти может быть возвращёно NULL.
PQresultErrorField#Возвращает индивидуальное поле из отчёта об ошибке.
char *PQresultErrorField(const PGresult *res, int fieldcode);
fieldcodeэто идентификатор поля ошибки; см. символические константы, перечисленные ниже. ЕслиPGresultне содержит ошибки или предупреждения или не включает указанное поле, то возвращаетсяNULL. Значения полей обычно не включают завершающий символ новой строки. Вызывающая функция не должна напрямую освобождать память, на которую указывает возвращаемый указатель. Она будет освобождена, когда соответствующий указательPGresultбудет передан функцииPQclear.Доступны следующие коды полей:
PG_DIAG_SEVERITY#Серьёзность; поле может содержать
ERROR,FATALилиPANIC(в сообщении об ошибке) либоWARNING,NOTICE,DEBUG,INFOилиLOG(в сообщении-уведомлении) либо локализованный перевод одного из этих значений. Присутствует всегда.PG_DIAG_SEVERITY_NONLOCALIZED#Серьёзность; поле может содержать
ERROR,FATALилиPANIC(в сообщении об ошибке) либоWARNING,NOTICE,DEBUG,INFOилиLOG(в сообщении-уведомлении). Это поле подобноPG_DIAG_SEVERITY, но его содержимое никогда не переводится. Присутствует только в отчётах, выдаваемых Postgres Pro версии 9.6 и новее.PG_DIAG_SQLSTATE#Код ошибки в соответствии с соглашением о кодах SQLSTATE. Код SQLSTATE идентифицирует тип случившейся ошибки; он может использоваться клиентскими приложениями, чтобы выполнять конкретные операции (такие, как обработка ошибок) в ответ на конкретную ошибку базы данных. Список возможных кодов SQLSTATE приведён в Приложении A. Это поле не подлежит локализации. Оно всегда присутствует.
PG_DIAG_MESSAGE_PRIMARY#Главное сообщение об ошибке, предназначенное для прочтения пользователем. Как правило составляет всего одну строку. Это поле всегда присутствует.
PG_DIAG_MESSAGE_DETAIL#Необязательное дополнительное сообщение об ошибке, передающее более детальную информацию о проблеме. Может занимать несколько строк.
PG_DIAG_MESSAGE_HINT#Подсказка: необязательное предположение о том, что можно сделать в данной проблемной ситуации. Оно должно отличаться от детальной информации в том смысле, что оно предлагает совет (возможно, и неподходящий), а не просто факты. Может занимать несколько строк.
PG_DIAG_STATEMENT_POSITION#Строка, содержащая десятичное целое число, указывающее позицию расположения ошибки в качестве индекса в оригинальной строке оператора. Первый символ имеет позицию 1, при этом позиции измеряются в символах а не в байтах.
PG_DIAG_INTERNAL_POSITION#Это поле определяется точно так же, как и поле
PG_DIAG_STATEMENT_POSITION, но оно используется, когда позиция местонахождения ошибки относится к команде, сгенерированной внутренними модулями, а не к команде, представленной клиентом. Когда появляется это поле, то всегда появляется и полеPG_DIAG_INTERNAL_QUERY.PG_DIAG_INTERNAL_QUERY#Текст команды, сгенерированной внутренними модулями, завершившейся сбоем. Это мог бы быть, например, SQL-запрос, выданный функцией на языке PL/pgSQL.
PG_DIAG_CONTEXT#Характеристика контекста, в котором произошла ошибка. В настоящее время она включает вывод стека вызовов активных функций процедурного языка и запросов, сгенерированных внутренними модулями. Стек выводится по одному элементу в строке, при этом первым идет самый последний из элементов (самый недавний вызов).
PG_DIAG_SCHEMA_NAME#Если ошибка была связана с конкретным объектом базы данных, то в это поле будет записано имя схемы, содержащей данный объект.
PG_DIAG_TABLE_NAME#Если ошибка была связана с конкретной таблицей, то в это поле будет записано имя таблицы. (Для получения имени схемы для данной таблицы обратитесь к полю, содержащему имя схемы.)
PG_DIAG_COLUMN_NAME#Если ошибка была связана с конкретным столбцом таблицы, то в это поле будет записано имя столбца. (Чтобы идентифицировать таблицу, обратитесь к полям, содержащим имена схемы и таблицы.)
PG_DIAG_DATATYPE_NAME#Если ошибка была связана с конкретным типом данных, то в это поле будет записано имя типа данных. (Чтобы получить имя схемы, которой принадлежит этот тип данных, обратитесь к полю, содержащему имя схемы.)
PG_DIAG_CONSTRAINT_NAME#Если ошибка была связана с конкретным ограничением, то в это поле будет записано имя ограничения. Чтобы получить имя таблицы или домена, связанных с этим ограничением, обратитесь к полям, перечисленным выше. (С этой целью индексы рассматриваются как ограничения, даже если они и не были созданы с помощью синтаксиса для создания ограничений.)
PG_DIAG_SOURCE_FILE#Имя файла, содержащего позицию в исходном коде, для которой было выдано сообщение об ошибка.
PG_DIAG_SOURCE_LINE#Номер строки той позиции в исходном коде, для которой было выдано сообщение об ошибке.
PG_DIAG_SOURCE_FUNCTION#Имя функции в исходном коде, сообщающей об ошибке.
Примечание
Поля для имени схемы, имени таблицы, имени столбца, имени типа данных и имени ограничения предоставляются лишь для ограниченного числа типов ошибок; см. Приложение A. Не рассчитывайте на то, что присутствие любого из этих полей гарантирует и присутствие какого-то другого поля. Базовые источники ошибок придерживаются взаимосвязей, описанных выше, но функции, определённые пользователем, могут использовать эти поля другими способами. Аналогично, не рассчитывайте на то, что эти поля обозначают объекты, существующие в текущей базе данных в настоящий момент.
Клиент отвечает за форматирование отображаемой информации в соответствии с его нуждами; в частности, он должен разбивать длинные строки, как требуется. Символы новой строки, встречающиеся в полях сообщения об ошибке, должны обрабатываться, как разрывы абзацев, а не строк.
Ошибки, сгенерированные внутренними модулями libpq, будут иметь поля серьёзности ошибки и основного сообщения, но, как правило, никаких других полей.
Заметьте, что поля ошибки доступны только из объектов
PGresult, а не из объектовPGconn. Не существует функцииPQerrorField.PQclear#Освобождает область памяти, связанную с
PGresult. Результат выполнения каждой команды должен быть освобождён с помощьюPQclear, когда он больше не нужен.void PQclear(PGresult *res);
Если аргумент является указателем
NULL, операция не выполняется.Вы можете сохранять объект
PGresult, пока он вам нужен; он не исчезает ни когда вы выдаёте новую команду, ни даже если вы закрываете соединение. Чтобы от него избавиться, вы должны вызватьPQclear. Если этого не делать, в вашем приложении будут иметь место утечки памяти.
36.3.2. Извлечение информации, связанной с результатом запроса #
Эти функции служат для извлечения информации из объекта PGresult, который представляет результат успешного запроса (то есть такого, который имеет статус PGRES_TUPLES_OK, PGRES_SINGLE_TUPLE или PGRES_TUPLES_CHUNK). Их также можно использовать для извлечения информации об успешной операции DESCRIBE: результат этой операции содержит всю ту же самую информацию о столбцах, которая была бы получена при реальном исполнении запроса, но не содержит ни одной строки. Для объектов, имеющих другие значения статуса, эти функции будут действовать таким образом, как будто результат не содержит ни одной строки и ни одного столбца.
PQntuples#Возвращает число строк (кортежей) в полученной выборке. (Заметьте, что объекты
PGresultне могут содержать более чемINT_MAXстрок, так что для результата достаточно типаint.)int PQntuples(const PGresult *res);
PQnfields#Возвращает число столбцов (полей) в каждой строке полученной выборки.
int PQnfields(const PGresult *res);
PQfname#Возвращает имя столбца, соответствующего данному номеру столбца. Номера столбцов начинаются с 0. Вызывающая функция не должна напрямую освобождать память, на которую указывает возвращаемый указатель. Она будет освобождена, когда соответствующий указатель на
PGresultбудет передан функцииPQclear.char *PQfname(const PGresult *res, int column_number);Если номер столбца выходит за пределы допустимого диапазона, то возвращается
NULL.PQfnumber#Возвращает номер столбца, соответствующий данному имени столбца.
int PQfnumber(const PGresult *res, const char *column_name);Если данное имя не совпадает с именем ни одного из столбцов, то возвращается -1.
Данное имя интерпретируется, как идентификатор в SQL-команде. Это означает, что оно переводится в нижний регистр, если только оно не заключено в двойные кавычки. Например, для выборки, сгенерированной с помощью такой SQL-команды:
SELECT 1 AS FOO, 2 AS "BAR";
мы получили бы следующие результаты:
PQfname(res, 0) foo PQfname(res, 1) BAR PQfnumber(res, "FOO") 0 PQfnumber(res, "foo") 0 PQfnumber(res, "BAR") -1 PQfnumber(res, "\"BAR\"") 1
PQftable#Возвращает OID таблицы, из которой был получен данный столбец. Номера столбцов начинаются с 0.
Oid PQftable(const PGresult *res, int column_number);В следующих случаях возвращается
InvalidOid: если номер столбца выходит за пределы допустимого диапазона; если указанный столбец не является простой ссылкой на столбец таблицы. Вы можете сделать запрос к системной таблицеpg_class, чтобы точно определить, к какой таблице было произведено обращение.Тип данных
Oidи константаInvalidOidбудут определены, когда вы включите заголовочный файл для libpq. Они будут принадлежать к одному из целочисленных типов.PQftablecol#Возвращает номер столбца (в пределах его таблицы) для указанного столбца в полученной выборке. Номера столбцов в полученной выборке начинаются с 0, но столбцы в таблице имеют ненулевые номера.
int PQftablecol(const PGresult *res, int column_number);В следующих случаях возвращается ноль: если номер столбца выходит за пределы допустимого диапазона; если указанный столбец не является простой ссылкой на столбец таблицы.
PQfformat#Возвращает код формата, показывающий формат данного столбца. Номера столбцов начинаются с 0.
int PQfformat(const PGresult *res, int column_number);Значение кода формата, равное нулю, указывает на текстовое представление данных, в то время, как значение, равное единице, означает двоичное представление. (Другие значения кодов зарезервированы для определения в будущем.)
PQftype#Возвращает тип данных, соответствующий данному номеру столбца. Возвращаемое целое значение является внутренним номером OID для этого типа. Номера столбцов начинаются с 0.
Oid PQftype(const PGresult *res, int column_number);Вы можете сделать запрос к системной таблице
pg_type, чтобы получить имена и свойства различных типов данных.PQfmod#Возвращает модификатор типа для столбца, соответствующего данному номеру. Номера столбцов начинаются с 0.
int PQfmod(const PGresult *res, int column_number);Интерпретация значений модификатора зависит от типа; они обычно показывают точность или предельные размеры. Значение -1 используется, чтобы показать «нет доступной информации». Большинство типов данных не используют модификаторов, в таком случае значение всегда будет -1.
PQfsize#Возвращает размер в байтах для столбца, соответствующего данному номеру. Номера столбцов начинаются с 0.
int PQfsize(const PGresult *res, int column_number);PQfsizeвозвращает размер пространства, выделенного для этого столбца в строке базы данных, другими словами, это размер внутреннего представления этого типа данных на сервере. (Следовательно, эта информация не является по-настоящему полезной для клиентов.) Отрицательное значение говорит о том, что тип данных имеет переменную длину.PQbinaryTuples#Возвращает 1, если
PGresultсодержит двоичные данные, или 0, если данные текстовые.int PQbinaryTuples(const PGresult *res);
Эта функция не рекомендуется к использованию (за исключением применения в связи с командой
COPY), поскольку один и тот жеPGresultможет содержать в некоторых столбцах текстовые данные, а в остальных — двоичные. Предпочтительнее использоватьPQfformat.PQbinaryTuplesвозвращает 1, только если все столбцы в выборке являются двоичными (код формата 1).PQgetvalue#Возвращает значение одного поля из одной строки, содержащейся в
PGresult. Номера строк и столбцов начинаются с 0. Вызывающая функция не должна напрямую освобождать память, на которую указывает возвращаемый указатель. Она будет освобождена, когда соответствующий указатель наPGresultбудет передан функцииPQclear.char *PQgetvalue(const PGresult *res, int row_number, int column_number);Для данных в текстовом формате значение, возвращаемое функцией
PQgetvalue, является значением поля, представленным в виде символьной строки с завершающим нулевым символом. Для данных в двоичном формате используется двоичное представление значения. Оно определяется функциямиtypsendиtypreceiveдля конкретного типа данных. (В этом случае к значению также добавляется нулевой байт, но обычно это не приносит пользы, поскольку вероятно, что значение уже содержит нулевые байты.)Пустая строка возвращается в том случае, когда поле содержит null. Чтобы отличить значения null от пустых строковых значений, воспользуйтесь функцией
PQgetisnull.Указатель, возвращаемый функцией
PQgetvalue, указывает на область памяти внутри структурыPGresult. Модифицировать данные, на которые указывает этот указатель, не следует. Вместо этого нужно явно скопировать данные в другую область памяти, если предполагается использовать их за рамками жизненного цикла структурыPGresult.PQgetisnull#Проверяет поле на предмет отсутствия значения (null). Номера строк и столбцов начинаются с 0.
int PQgetisnull(const PGresult *res, int row_number, int column_number);Эта функция возвращает 1, если значение в поле отсутствует (null), и 0, если поле содержит отличное от null значение. (Заметьте, что если поле содержит null, функция
PQgetvalueвозвращает пустую строку, а не нулевой указатель.)PQgetlength#Возвращает фактическую длину значения поля в байтах. Номера строк и столбцов начинаются с 0.
int PQgetlength(const PGresult *res, int row_number, int column_number);Это фактическая длина данных для конкретного значения данных, то есть размер объекта, на который указывает
PQgetvalue. Для текстового формата данных это то же самое, чтоstrlen(). Для двоичного же формата это существенная информация. Учтите, что при расчёте фактического объёма данных не следует полагаться наPQfsize.PQnparams#Возвращает число параметров подготовленного оператора.
int PQnparams(const PGresult *res);
Эта функция полезна только при исследовании результата работы функции
PQdescribePrepared. Для других типов результатов она возвратит ноль.PQparamtype#Возвращает тип данных для указанного параметра оператора. Номера параметров начинаются с 0.
Oid PQparamtype(const PGresult *res, int param_number);
Эта функция полезна только при исследовании результата работы функции
PQdescribePrepared. Для других типов результатов она возвратит ноль.PQprint#Выводит все строки и, по выбору, имена столбцов в указанный поток вывода.
void PQprint(FILE *fout, /* поток вывода */ const PGresult *res, const PQprintOpt *po); typedef struct { pqbool header; /* печатать заголовки полей и счётчик строк */ pqbool align; /* выравнивать поля */ pqbool standard; /* старый формат */ pqbool html3; /* выводить HTML-таблицы */ pqbool expanded; /* расширять таблицы */ pqbool pager; /* использовать программу для постраничного просмотра, если нужно */ char *fieldSep; /* разделитель полей */ char *tableOpt; /* атрибуты для HTML-таблицы */ char *caption; /* заголовок HTML-таблицы */ char **fieldName; /* массив заменителей для имён полей, завершающийся нулевым символом */ } PQprintOpt;Эту функцию прежде использовала утилита psql для вывода результатов запроса, но больше она её не использует. Обратите внимание, предполагается, что все данные представлены в текстовом формате.
36.3.3. Получение другой информации о результате #
Эти функции используются для получения остальной информации из объектов PGresult.
PQcmdStatus#Возвращает дескриптор статуса для SQL-команды, которая сгенерировала
PGresult.char *PQcmdStatus(PGresult *res);
Как правило, это просто имя команды, но могут быть включены и дополнительные сведения, такие, как число обработанных строк. Вызывающая функция не должна напрямую освобождать память, на которую указывает возвращаемый указатель. Она будет освобождена, когда соответствующий указатель на
PGresultбудет передан функцииPQclear.PQcmdTuples#Возвращает число строк, которые затронула SQL-команда.
char *PQcmdTuples(PGresult *res);
Эта функция возвращает строковое значение, содержащее число строк, которые затронул SQL-оператор, сгенерировавший данный
PGresult. Эту функцию можно использовать только сразу после выполнения командSELECT,CREATE TABLE AS,INSERT,UPDATE,DELETE,MERGE,MOVE,FETCHилиCOPY, а также после оператораEXECUTE, выполнившего подготовленный запрос, содержащий командыINSERT,UPDATE,DELETEилиMERGE. Если команда, которая сгенерировалаPGresult, была какой-то иной, тоPQcmdTuplesвозвращает пустую строку. Вызывающая функция не должна напрямую освобождать память, на которую указывает возвращаемый указатель. Она будет освобождена, когда соответствующий указатель наPGresultбудет передан функцииPQclear.PQoidValue#Возвращает OID вставленной строки, если SQL-команда была командой
INSERT, которая вставила ровно одну строку в таблицу, имеющую идентификаторы OID, или командойEXECUTE, которая выполнила подготовленный запрос, содержащий соответствующий операторINSERT. В противном случае эта функция возвращаетInvalidOid. Эта функция также возвратитInvalidOid, если таблица, затронутая командойINSERT, не содержит идентификаторов OID.Oid PQoidValue(const PGresult *res);
PQoidStatus#Эта функция считается не рекомендуемой к использованию (в качестве замены служит
PQoidValue), а также она не является потокобезопасной. Она возвращает строковое значение, содержащее OID вставленной строки, в то время какPQoidValueвозвращает значение OID.char *PQoidStatus(const PGresult *res);
36.3.4. Экранирование строковых значений для включения в SQL-команды #
PQescapeLiteral#char *PQescapeLiteral(PGconn *conn, const char *str, size_t length);
PQescapeLiteralэкранирует строковое значение для использования внутри SQL-команды. Это полезно при вставке в SQL-команды значений данных в виде строковых констант. Определённые символы (например, кавычки и обратная косая черта) должны экранироваться, чтобы предотвратить их специальную интерпретацию синтаксическим анализатором языка SQL. Эту операцию выполняетPQescapeLiteral.PQescapeLiteralвозвращает экранированную версию параметраstr, размещённую в области памяти, распределённой с помощью функцииmalloc(). Эту память нужно освобождать с помощью функцииPQfreemem(), когда возвращённое значение больше не требуется. Завершающий нулевой байт не нужен и не должен учитываться в параметреlength. (Если завершающий нулевой байт был найден до того, как были обработаныlengthбайт, тоPQescapeLiteralостанавливает работу на нулевом байте; таким образом, поведение функции напоминаетstrncpy.) В возвращённой строке все специальные символы заменены таким образом, что синтаксический анализатор строковых литералов Postgres Pro может обработать их должным образом. В строку также добавляется завершающий нулевой байт. Одинарные кавычки, которые должны окружать строковые литералы Postgres Pro, включаются в результирующую строку.В случае ошибки
PQescapeLiteralвозвращаетNULL, и в объектconnпомещается соответствующее сообщение.Подсказка
Особенно важно выполнять надлежащее экранирование при обработке строк, полученных из ненадёжных источников. В противном случае ваша безопасность подвергается риску из-за уязвимости в отношении атак с использованием «SQL-инъекций», с помощью которых нежелательные SQL-команды направляются в вашу базу данных.
Обратите внимание, что нет необходимости (и это будет даже некорректно) экранировать значения данных, передаваемых в виде отдельных параметров в функцию
PQexecParamsили родственные ей функции.PQescapeIdentifier#char *PQescapeIdentifier(PGconn *conn, const char *str, size_t length);
PQescapeIdentifierэкранирует строку, предназначенную для использования в качестве идентификатора SQL, например имени таблицы, столбца или функции. Это полезно, когда идентификатор, выбранный пользователем, может содержать специальные символы, которые в противном случае не интерпретировались бы синтаксическим анализатором SQL, как часть идентификатора, или когда идентификатор может содержать символы верхнего регистра и этот регистр требуется сохранить.PQescapeIdentifierвозвращает версию параметраstr, экранированную как SQL-идентификатор, и размещённую в области памяти, распределённой с помощью функцииmalloc(). Эту память нужно освобождать с помощью функцииPQfreemem(), когда возвращённое значение больше не требуется. Завершающий нулевой байт не нужен и не должен учитываться в параметреlength. (Если завершающий нулевой байт был найден до того, как были обработаныlengthбайт, тоPQescapeIdentifierостанавливается на нулевом байте; таким образом, поведение функции напоминаетstrncpy.) В возвращённой строке все специальные символы заменены таким образом, что она будет надлежащим образом обработана, как SQL-идентификатор. Завершающий нулевой байт также будет добавлен. Возвращённая строка также будет заключена в двойные кавычки.В случае ошибки
PQescapeIdentifierвозвращаетNULL, и в объектconnпомещается соответствующее сообщение.Подсказка
Как и в случае со строковыми литералами, для того чтобы предотвратить атаки с помощью SQL-инъекций, SQL-идентификаторы должны экранироваться, когда они получены из ненадёжного источника.
PQescapeStringConn#size_t PQescapeStringConn(PGconn *conn, char *to, const char *from, size_t length, int *error);PQescapeStringConnэкранирует строковые литералы наподобиеPQescapeLiteral. Но, в отличие отPQescapeLiteral, за предоставление буфера надлежащего размера отвечает вызывающая функция. Более того,PQescapeStringConnне добавляет одинарные кавычки, которые должны окружать строковые литералы Postgres Pro; они должны быть включены в SQL-команду, в которую вставляется результирующая строка. Параметрfromуказывает на первый символ строки, которая должна экранироваться, а параметрlengthзадаёт число байт в этой строке. Завершающий нулевой байт не требуется и не должен учитываться в параметреlength. (Если завершающий нулевой байт был найден до того, как были обработаныlengthбайт, тоPQescapeStringConnостанавливается на нулевом байте; таким образом, поведение функции напоминаетstrncpy.) Параметрtoдолжен указывать на буфер, который сможет вместить как минимум на один байт больше, чем предписывает удвоенное значение параметраlength, в противном случае поведение функции не определено. Поведение будет также не определено, если строкиtoиfromперекрываются.Если параметр
errorне равенNULL, тогда значение*errorустанавливается равным нулю в случае успешной работы и не равным нулю в случае ошибки. В настоящее время единственным возможным условием возникновения ошибки является неверная мультибайтовая кодировка в исходной строке. Выходная строка формируется даже при наличии ошибки, но можно ожидать, что сервер отвергнет её как неверно сформированную. В случае ошибки в объектconnзаписывается соответствующее сообщение независимо от того, равно лиNULLзначение параметраerror.PQescapeStringConnвозвращает число байт, записанных по адресуto, не включая завершающий нулевой байт.PQescapeString#PQescapeStringявляется более старой, не рекомендованной к использованию версией функцииPQescapeStringConn.size_t PQescapeString (char *to, const char *from, size_t length);
Единственное отличие от
PQescapeStringConnсостоит в том, что у функцииPQescapeStringнет параметровPGconnиerror. Поэтому она не может скорректировать своё поведение в зависимости от свойств подключения (таких, как кодировка символов) и, следовательно, она может выдавать неверные результаты. Также она не имеет возможности сообщить об ошибках.PQescapeStringможет безопасно использоваться в клиентских программах, которые работают лишь с одним подключением к Postgres Pro за один раз (в этом случае функция может найти то, что ей нужно знать, «за кулисами»). В других контекстах её использование несёт угрозу безопасности и его следует избегать в пользу применения функцииPQescapeStringConn.PQescapeByteaConn#Экранирует двоичные данные для их использования внутри SQL-команды с типом данных
bytea. Как и в случае сPQescapeStringConn, эта функция применяется только тогда, когда данные вставляются непосредственно в строку SQL-команды.unsigned char *PQescapeByteaConn(PGconn *conn, const unsigned char *from, size_t from_length, size_t *to_length);Байты, имеющие определённые значения, должны экранироваться, когда они используются внутри литерала, имеющего тип
bytea, в SQL-операторе.PQescapeByteaConnэкранирует байты, используя либо hex-кодирование, либо экранирование с помощью обратной косой черты. См. Раздел 8.4 для получения дополнительной информации.Параметр
fromуказывает на первый байт строки, которая должна экранироваться, а параметрfrom_lengthзадаёт число байт в этой двоичной строке. (Завершающий нулевой байт не нужен и не учитывается.) Параметрto_lengthуказывает на переменную, которая будет содержать длину результирующей экранированной строки. Эта длина включает завершающий нулевой байт результирующей строки.PQescapeByteaConnвозвращает экранированную версию двоичной строки, на которую указывает параметрfrom, и размещает её в памяти, распределённой с помощьюmalloc(). Эта память должна быть освобождена с помощью функцииPQfreemem(), когда результирующая строка больше не нужна. В возвращаемой строке все специальные символы заменены так, чтобы синтаксический анализатор литеральных строк Postgres Pro и функция ввода для типаbyteaмогли обработать их надлежащим образом. Завершающий нулевой байт также добавляется. Одинарные кавычки, которые должны окружать строковые литералы Postgres Pro, не являются частью результирующей строки.В случае ошибки возвращается нулевой указатель, и соответствующее сообщение об ошибке записывается в объект
conn. В настоящее время единственной возможной ошибкой может быть нехватка памяти для результирующей строки.PQescapeBytea#PQescapeByteaявляется устаревшей и не рекомендуемой к использованию версией функцииPQescapeByteaConn.unsigned char *PQescapeBytea(const unsigned char *from, size_t from_length, size_t *to_length);Единственное отличие от
PQescapeByteaConnсостоит в том, что у функцииPQescapeByteaнет параметраPGconn. ПоэтомуPQescapeByteaможет безопасно использоваться в клиентских программах, которые работают лишь с одним подключением к Postgres Pro в один момент времени (в этом случае функция может узнать то, что ей нужно, «за кулисами»). Она может выдавать неверные результаты при использовании в программах, которые устанавливает несколько подключений к базам данных (в таких случаях используйтеPQescapeByteaConn).PQunescapeBytea#Преобразует строковое представление двоичных данных в двоичные данные — является обратной функцией к функции
PQescapeBytea. Она нужна, когда данные типаbyteaизвлекаются в текстовом формате, но не когда они извлекаются в двоичном формате.unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length);
Параметр
fromуказывает на строку, такую, какую могла бы возвратить функцияPQgetvalue, применённая к столбцу типаbytea.PQunescapeByteaпреобразует это строковое представление в его двоичное представление. Она возвращает указатель на буфер, выделенный функциейmalloc(), илиNULLв случае ошибки и помещает размер буфера по адресуto_length. Когда результат не будет нужен, необходимо освободить его память, вызвавPQfreemem.Это преобразование не является точной инверсией для
PQescapeBytea, поскольку ожидается, что строка, полученная отPQgetvalue, не будет «экранированной». В частности, это означает, что учитывать режим спецпоследовательностей не нужно, и поэтому в параметреPGconnнет необходимости.
36.3. Command Execution Functions #
Once a connection to a database server has been successfully established, the functions described here are used to perform SQL queries and commands.
36.3.1. Main Functions #
PQexec#Submits a command to the server and waits for the result.
PGresult *PQexec(PGconn *conn, const char *command);
Returns a
PGresultpointer or possibly a null pointer. A non-null pointer will generally be returned except in out-of-memory conditions or serious errors such as inability to send the command to the server. ThePQresultStatusfunction should be called to check the return value for any errors (including the value of a null pointer, in which case it will returnPGRES_FATAL_ERROR). UsePQerrorMessageto get more information about such errors.
The command string can include multiple SQL commands (separated by semicolons). Multiple queries sent in a single PQexec call are processed in a single transaction, unless there are explicit BEGIN/COMMIT commands included in the query string to divide it into multiple transactions. (See Section 57.2.2.1 for more details about how the server handles multi-query strings.) Note however that the returned PGresult structure describes only the result of the last command executed from the string. Should one of the commands fail, processing of the string stops with it and the returned PGresult describes the error condition.
PQexecParams#Submits a command to the server and waits for the result, with the ability to pass parameters separately from the SQL command text.
PGresult *PQexecParams(PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char * const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat);PQexecParamsis likePQexec, but offers additional functionality: parameter values can be specified separately from the command string proper, and query results can be requested in either text or binary format.The function arguments are:
connThe connection object to send the command through.
commandThe SQL command string to be executed. If parameters are used, they are referred to in the command string as
$1,$2, etc.nParamsThe number of parameters supplied; it is the length of the arrays
paramTypes[],paramValues[],paramLengths[], andparamFormats[]. (The array pointers can beNULLwhennParamsis zero.)paramTypes[]Specifies, by OID, the data types to be assigned to the parameter symbols. If
paramTypesisNULL, or any particular element in the array is zero, the server infers a data type for the parameter symbol in the same way it would do for an untyped literal string.paramValues[]Specifies the actual values of the parameters. A null pointer in this array means the corresponding parameter is null; otherwise the pointer points to a zero-terminated text string (for text format) or binary data in the format expected by the server (for binary format).
paramLengths[]Specifies the actual data lengths of binary-format parameters. It is ignored for null parameters and text-format parameters. The array pointer can be null when there are no binary parameters.
paramFormats[]Specifies whether parameters are text (put a zero in the array entry for the corresponding parameter) or binary (put a one in the array entry for the corresponding parameter). If the array pointer is null then all parameters are presumed to be text strings.
Values passed in binary format require knowledge of the internal representation expected by the backend. For example, integers must be passed in network byte order. Passing
numericvalues requires knowledge of the server storage format.resultFormatSpecify zero to obtain results in text format, or one to obtain results in binary format. (There is not currently a provision to obtain different result columns in different formats, although that is possible in the underlying protocol.)
The primary advantage of PQexecParams over PQexec is that parameter values can be separated from the command string, thus avoiding the need for tedious and error-prone quoting and escaping.
Unlike PQexec, PQexecParams allows at most one SQL command in the given string. (There can be semicolons in it, but not more than one nonempty command.) This is a limitation of the underlying protocol, but has some usefulness as an extra defense against SQL-injection attacks.
Tip
Specifying parameter types via OIDs is tedious, particularly if you prefer not to hard-wire particular OID values into your program. However, you can avoid doing so even in cases where the server by itself cannot determine the type of the parameter, or chooses a different type than you want. In the SQL command text, attach an explicit cast to the parameter symbol to show what data type you will send. For example:
SELECT * FROM mytable WHERE x = $1::bigint;
This forces parameter $1 to be treated as bigint, whereas by default it would be assigned the same type as x. Forcing the parameter type decision, either this way or by specifying a numeric type OID, is strongly recommended when sending parameter values in binary format, because binary format has less redundancy than text format and so there is less chance that the server will detect a type mismatch mistake for you.
PQprepare#Submits a request to create a prepared statement with the given parameters, and waits for completion.
PGresult *PQprepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes);PQpreparecreates a prepared statement for later execution withPQexecPrepared. This feature allows commands to be executed repeatedly without being parsed and planned each time; see PREPARE for details.The function creates a prepared statement named
stmtNamefrom thequerystring, which must contain a single SQL command.stmtNamecan be""to create an unnamed statement, in which case any pre-existing unnamed statement is automatically replaced; otherwise it is an error if the statement name is already defined in the current session. If any parameters are used, they are referred to in the query as$1,$2, etc.nParamsis the number of parameters for which types are pre-specified in the arrayparamTypes[]. (The array pointer can beNULLwhennParamsis zero.)paramTypes[]specifies, by OID, the data types to be assigned to the parameter symbols. IfparamTypesisNULL, or any particular element in the array is zero, the server assigns a data type to the parameter symbol in the same way it would do for an untyped literal string. Also, the query can use parameter symbols with numbers higher thannParams; data types will be inferred for these symbols as well. (SeePQdescribePreparedfor a means to find out what data types were inferred.)As with
PQexec, the result is normally aPGresultobject whose contents indicate server-side success or failure. A null result indicates out-of-memory or inability to send the command at all. UsePQerrorMessageto get more information about such errors.
Prepared statements for use with PQexecPrepared can also be created by executing SQL PREPARE statements.
PQexecPrepared#Sends a request to execute a prepared statement with given parameters, and waits for the result.
PGresult *PQexecPrepared(PGconn *conn, const char *stmtName, int nParams, const char * const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat);PQexecPreparedis likePQexecParams, but the command to be executed is specified by naming a previously-prepared statement, instead of giving a query string. This feature allows commands that will be used repeatedly to be parsed and planned just once, rather than each time they are executed. The statement must have been prepared previously in the current session.The parameters are identical to
PQexecParams, except that the name of a prepared statement is given instead of a query string, and theparamTypes[]parameter is not present (it is not needed since the prepared statement's parameter types were determined when it was created).PQdescribePrepared#Submits a request to obtain information about the specified prepared statement, and waits for completion.
PGresult *PQdescribePrepared(PGconn *conn, const char *stmtName);
PQdescribePreparedallows an application to obtain information about a previously prepared statement.stmtNamecan be""orNULLto reference the unnamed statement, otherwise it must be the name of an existing prepared statement. On success, aPGresultwith statusPGRES_COMMAND_OKis returned. The functionsPQnparamsandPQparamtypecan be applied to thisPGresultto obtain information about the parameters of the prepared statement, and the functionsPQnfields,PQfname,PQftype, etc. provide information about the result columns (if any) of the statement.PQdescribePortal#Submits a request to obtain information about the specified portal, and waits for completion.
PGresult *PQdescribePortal(PGconn *conn, const char *portalName);
PQdescribePortalallows an application to obtain information about a previously created portal. (libpq does not provide any direct access to portals, but you can use this function to inspect the properties of a cursor created with aDECLARE CURSORSQL command.)portalNamecan be""orNULLto reference the unnamed portal, otherwise it must be the name of an existing portal. On success, aPGresultwith statusPGRES_COMMAND_OKis returned. The functionsPQnfields,PQfname,PQftype, etc. can be applied to thePGresultto obtain information about the result columns (if any) of the portal.PQclosePrepared#Submits a request to close the specified prepared statement, and waits for completion.
PGresult *PQclosePrepared(PGconn *conn, const char *stmtName);
PQclosePreparedallows an application to close a previously prepared statement. Closing a statement releases all of its associated resources on the server and allows its name to be reused.stmtNamecan be""orNULLto reference the unnamed statement. It is fine if no statement exists with this name, in that case the operation is a no-op. On success, aPGresultwith statusPGRES_COMMAND_OKis returned.PQclosePortal#Submits a request to close the specified portal, and waits for completion.
PGresult *PQclosePortal(PGconn *conn, const char *portalName);
PQclosePortalallows an application to trigger a close of a previously created portal. Closing a portal releases all of its associated resources on the server and allows its name to be reused. (libpq does not provide any direct access to portals, but you can use this function to close a cursor created with aDECLARE CURSORSQL command.)portalNamecan be""orNULLto reference the unnamed portal. It is fine if no portal exists with this name, in that case the operation is a no-op. On success, aPGresultwith statusPGRES_COMMAND_OKis returned.
The PGresult structure encapsulates the result returned by the server. libpq application programmers should be careful to maintain the PGresult abstraction. Use the accessor functions below to get at the contents of PGresult. Avoid directly referencing the fields of the PGresult structure because they are subject to change in the future.
PQresultStatus#Returns the result status of the command.
ExecStatusType PQresultStatus(const PGresult *res);
PQresultStatuscan return one of the following values:PGRES_EMPTY_QUERY#The string sent to the server was empty.
PGRES_COMMAND_OK#Successful completion of a command returning no data.
PGRES_TUPLES_OK#Successful completion of a command returning data (such as a
SELECTorSHOW).PGRES_COPY_OUT#Copy Out (from server) data transfer started.
PGRES_COPY_IN#Copy In (to server) data transfer started.
PGRES_BAD_RESPONSE#The server's response was not understood.
PGRES_NONFATAL_ERROR#A nonfatal error (a notice or warning) occurred.
PGRES_FATAL_ERROR#A fatal error occurred.
PGRES_COPY_BOTH#Copy In/Out (to and from server) data transfer started. This feature is currently used only for streaming replication, so this status should not occur in ordinary applications.
PGRES_SINGLE_TUPLE#The
PGresultcontains a single result tuple from the current command. This status occurs only when single-row mode has been selected for the query (see Section 36.6).PGRES_TUPLES_CHUNK#The
PGresultcontains several result tuples from the current command. This status occurs only when chunked mode has been selected for the query (see Section 36.6). The number of tuples will not exceed the limit passed toPQsetChunkedRowsMode.PGRES_PIPELINE_SYNC#The
PGresultrepresents a synchronization point in pipeline mode, requested by eitherPQpipelineSyncorPQsendPipelineSync. This status occurs only when pipeline mode has been selected.PGRES_PIPELINE_ABORTED#The
PGresultrepresents a pipeline that has received an error from the server.PQgetResultmust be called repeatedly, and each time it will return this status code until the end of the current pipeline, at which point it will returnPGRES_PIPELINE_SYNCand normal processing can resume.
If the result status is
PGRES_TUPLES_OK,PGRES_SINGLE_TUPLE, orPGRES_TUPLES_CHUNK, then the functions described below can be used to retrieve the rows returned by the query. Note that aSELECTcommand that happens to retrieve zero rows still showsPGRES_TUPLES_OK.PGRES_COMMAND_OKis for commands that can never return rows (INSERTorUPDATEwithout aRETURNINGclause, etc.). A response ofPGRES_EMPTY_QUERYmight indicate a bug in the client software.A result of status
PGRES_NONFATAL_ERRORwill never be returned directly byPQexecor other query execution functions; results of this kind are instead passed to the notice processor (see Section 36.13).PQresStatus#Converts the enumerated type returned by
PQresultStatusinto a string constant describing the status code. The caller should not free the result.char *PQresStatus(ExecStatusType status);
PQresultErrorMessage#Returns the error message associated with the command, or an empty string if there was no error.
char *PQresultErrorMessage(const PGresult *res);
If there was an error, the returned string will include a trailing newline. The caller should not free the result directly. It will be freed when the associated
PGresulthandle is passed toPQclear.Immediately following a
PQexecorPQgetResultcall,PQerrorMessage(on the connection) will return the same string asPQresultErrorMessage(on the result). However, aPGresultwill retain its error message until destroyed, whereas the connection's error message will change when subsequent operations are done. UsePQresultErrorMessagewhen you want to know the status associated with a particularPGresult; usePQerrorMessagewhen you want to know the status from the latest operation on the connection.PQresultVerboseErrorMessage#Returns a reformatted version of the error message associated with a
PGresultobject.char *PQresultVerboseErrorMessage(const PGresult *res, PGVerbosity verbosity, PGContextVisibility show_context);In some situations a client might wish to obtain a more detailed version of a previously-reported error.
PQresultVerboseErrorMessageaddresses this need by computing the message that would have been produced byPQresultErrorMessageif the specified verbosity settings had been in effect for the connection when the givenPGresultwas generated. If thePGresultis not an error result, “PGresult is not an error result” is reported instead. The returned string includes a trailing newline.Unlike most other functions for extracting data from a
PGresult, the result of this function is a freshly allocated string. The caller must free it usingPQfreemem()when the string is no longer needed.A NULL return is possible if there is insufficient memory.
PQresultErrorField#Returns an individual field of an error report.
char *PQresultErrorField(const PGresult *res, int fieldcode);
fieldcodeis an error field identifier; see the symbols listed below.NULLis returned if thePGresultis not an error or warning result, or does not include the specified field. Field values will normally not include a trailing newline. The caller should not free the result directly. It will be freed when the associatedPGresulthandle is passed toPQclear.The following field codes are available:
PG_DIAG_SEVERITY#The severity; the field contents are
ERROR,FATAL, orPANIC(in an error message), orWARNING,NOTICE,DEBUG,INFO, orLOG(in a notice message), or a localized translation of one of these. Always present.PG_DIAG_SEVERITY_NONLOCALIZED#The severity; the field contents are
ERROR,FATAL, orPANIC(in an error message), orWARNING,NOTICE,DEBUG,INFO, orLOG(in a notice message). This is identical to thePG_DIAG_SEVERITYfield except that the contents are never localized. This is present only in reports generated by Postgres Pro versions 9.6 and later.PG_DIAG_SQLSTATE#The SQLSTATE code for the error. The SQLSTATE code identifies the type of error that has occurred; it can be used by front-end applications to perform specific operations (such as error handling) in response to a particular database error. For a list of the possible SQLSTATE codes, see Appendix A. This field is not localizable, and is always present.
PG_DIAG_MESSAGE_PRIMARY#The primary human-readable error message (typically one line). Always present.
PG_DIAG_MESSAGE_DETAIL#Detail: an optional secondary error message carrying more detail about the problem. Might run to multiple lines.
PG_DIAG_MESSAGE_HINT#Hint: an optional suggestion what to do about the problem. This is intended to differ from detail in that it offers advice (potentially inappropriate) rather than hard facts. Might run to multiple lines.
PG_DIAG_STATEMENT_POSITION#A string containing a decimal integer indicating an error cursor position as an index into the original statement string. The first character has index 1, and positions are measured in characters not bytes.
PG_DIAG_INTERNAL_POSITION#This is defined the same as the
PG_DIAG_STATEMENT_POSITIONfield, but it is used when the cursor position refers to an internally generated command rather than the one submitted by the client. ThePG_DIAG_INTERNAL_QUERYfield will always appear when this field appears.PG_DIAG_INTERNAL_QUERY#The text of a failed internally-generated command. This could be, for example, an SQL query issued by a PL/pgSQL function.
PG_DIAG_CONTEXT#An indication of the context in which the error occurred. Presently this includes a call stack traceback of active procedural language functions and internally-generated queries. The trace is one entry per line, most recent first.
PG_DIAG_SCHEMA_NAME#If the error was associated with a specific database object, the name of the schema containing that object, if any.
PG_DIAG_TABLE_NAME#If the error was associated with a specific table, the name of the table. (Refer to the schema name field for the name of the table's schema.)
PG_DIAG_COLUMN_NAME#If the error was associated with a specific table column, the name of the column. (Refer to the schema and table name fields to identify the table.)
PG_DIAG_DATATYPE_NAME#If the error was associated with a specific data type, the name of the data type. (Refer to the schema name field for the name of the data type's schema.)
PG_DIAG_CONSTRAINT_NAME#If the error was associated with a specific constraint, the name of the constraint. Refer to fields listed above for the associated table or domain. (For this purpose, indexes are treated as constraints, even if they weren't created with constraint syntax.)
PG_DIAG_SOURCE_FILE#The file name of the source-code location where the error was reported.
PG_DIAG_SOURCE_LINE#The line number of the source-code location where the error was reported.
PG_DIAG_SOURCE_FUNCTION#The name of the source-code function reporting the error.
Note
The fields for schema name, table name, column name, data type name, and constraint name are supplied only for a limited number of error types; see Appendix A. Do not assume that the presence of any of these fields guarantees the presence of another field. Core error sources observe the interrelationships noted above, but user-defined functions may use these fields in other ways. In the same vein, do not assume that these fields denote contemporary objects in the current database.
The client is responsible for formatting displayed information to meet its needs; in particular it should break long lines as needed. Newline characters appearing in the error message fields should be treated as paragraph breaks, not line breaks.
Errors generated internally by libpq will have severity and primary message, but typically no other fields.
Note that error fields are only available from
PGresultobjects, notPGconnobjects; there is noPQerrorFieldfunction.PQclear#Frees the storage associated with a
PGresult. Every command result should be freed viaPQclearwhen it is no longer needed.void PQclear(PGresult *res);
If the argument is a
NULLpointer, no operation is performed.You can keep a
PGresultobject around for as long as you need it; it does not go away when you issue a new command, nor even if you close the connection. To get rid of it, you must callPQclear. Failure to do this will result in memory leaks in your application.
36.3.2. Retrieving Query Result Information #
These functions are used to extract information from a PGresult object that represents a successful query result (that is, one that has status PGRES_TUPLES_OK, PGRES_SINGLE_TUPLE, or PGRES_TUPLES_CHUNK). They can also be used to extract information from a successful Describe operation: a Describe's result has all the same column information that actual execution of the query would provide, but it has zero rows. For objects with other status values, these functions will act as though the result has zero rows and zero columns.
PQntuples#Returns the number of rows (tuples) in the query result. (Note that
PGresultobjects are limited to no more thanINT_MAXrows, so anintresult is sufficient.)int PQntuples(const PGresult *res);
PQnfields#Returns the number of columns (fields) in each row of the query result.
int PQnfields(const PGresult *res);
PQfname#Returns the column name associated with the given column number. Column numbers start at 0. The caller should not free the result directly. It will be freed when the associated
PGresulthandle is passed toPQclear.char *PQfname(const PGresult *res, int column_number);NULLis returned if the column number is out of range.PQfnumber#Returns the column number associated with the given column name.
int PQfnumber(const PGresult *res, const char *column_name);-1 is returned if the given name does not match any column.
The given name is treated like an identifier in an SQL command, that is, it is downcased unless double-quoted. For example, given a query result generated from the SQL command:
SELECT 1 AS FOO, 2 AS "BAR";
we would have the results:
PQfname(res, 0) foo PQfname(res, 1) BAR PQfnumber(res, "FOO") 0 PQfnumber(res, "foo") 0 PQfnumber(res, "BAR") -1 PQfnumber(res, "\"BAR\"") 1
PQftable#Returns the OID of the table from which the given column was fetched. Column numbers start at 0.
Oid PQftable(const PGresult *res, int column_number);InvalidOidis returned if the column number is out of range, or if the specified column is not a simple reference to a table column. You can query the system tablepg_classto determine exactly which table is referenced.The type
Oidand the constantInvalidOidwill be defined when you include the libpq header file. They will both be some integer type.PQftablecol#Returns the column number (within its table) of the column making up the specified query result column. Query-result column numbers start at 0, but table columns have nonzero numbers.
int PQftablecol(const PGresult *res, int column_number);Zero is returned if the column number is out of range, or if the specified column is not a simple reference to a table column.
PQfformat#Returns the format code indicating the format of the given column. Column numbers start at 0.
int PQfformat(const PGresult *res, int column_number);Format code zero indicates textual data representation, while format code one indicates binary representation. (Other codes are reserved for future definition.)
PQftype#Returns the data type associated with the given column number. The integer returned is the internal OID number of the type. Column numbers start at 0.
Oid PQftype(const PGresult *res, int column_number);You can query the system table
pg_typeto obtain the names and properties of the various data types.PQfmod#Returns the type modifier of the column associated with the given column number. Column numbers start at 0.
int PQfmod(const PGresult *res, int column_number);The interpretation of modifier values is type-specific; they typically indicate precision or size limits. The value -1 is used to indicate “no information available”. Most data types do not use modifiers, in which case the value is always -1.
PQfsize#Returns the size in bytes of the column associated with the given column number. Column numbers start at 0.
int PQfsize(const PGresult *res, int column_number);PQfsizereturns the space allocated for this column in a database row, in other words the size of the server's internal representation of the data type. (Accordingly, it is not really very useful to clients.) A negative value indicates the data type is variable-length.PQbinaryTuples#Returns 1 if the
PGresultcontains binary data and 0 if it contains text data.int PQbinaryTuples(const PGresult *res);
This function is deprecated (except for its use in connection with
COPY), because it is possible for a singlePGresultto contain text data in some columns and binary data in others.PQfformatis preferred.PQbinaryTuplesreturns 1 only if all columns of the result are binary (format 1).PQgetvalue#Returns a single field value of one row of a
PGresult. Row and column numbers start at 0. The caller should not free the result directly. It will be freed when the associatedPGresulthandle is passed toPQclear.char *PQgetvalue(const PGresult *res, int row_number, int column_number);For data in text format, the value returned by
PQgetvalueis a null-terminated character string representation of the field value. For data in binary format, the value is in the binary representation determined by the data type'stypsendandtypreceivefunctions. (The value is actually followed by a zero byte in this case too, but that is not ordinarily useful, since the value is likely to contain embedded nulls.)An empty string is returned if the field value is null. See
PQgetisnullto distinguish null values from empty-string values.The pointer returned by
PQgetvaluepoints to storage that is part of thePGresultstructure. One should not modify the data it points to, and one must explicitly copy the data into other storage if it is to be used past the lifetime of thePGresultstructure itself.PQgetisnull#Tests a field for a null value. Row and column numbers start at 0.
int PQgetisnull(const PGresult *res, int row_number, int column_number);This function returns 1 if the field is null and 0 if it contains a non-null value. (Note that
PQgetvaluewill return an empty string, not a null pointer, for a null field.)PQgetlength#Returns the actual length of a field value in bytes. Row and column numbers start at 0.
int PQgetlength(const PGresult *res, int row_number, int column_number);This is the actual data length for the particular data value, that is, the size of the object pointed to by
PQgetvalue. For text data format this is the same asstrlen(). For binary format this is essential information. Note that one should not rely onPQfsizeto obtain the actual data length.PQnparams#Returns the number of parameters of a prepared statement.
int PQnparams(const PGresult *res);
This function is only useful when inspecting the result of
PQdescribePrepared. For other types of results it will return zero.PQparamtype#Returns the data type of the indicated statement parameter. Parameter numbers start at 0.
Oid PQparamtype(const PGresult *res, int param_number);
This function is only useful when inspecting the result of
PQdescribePrepared. For other types of results it will return zero.PQprint#Prints out all the rows and, optionally, the column names to the specified output stream.
void PQprint(FILE *fout, /* output stream */ const PGresult *res, const PQprintOpt *po); typedef struct { pqbool header; /* print output field headings and row count */ pqbool align; /* fill align the fields */ pqbool standard; /* old brain dead format */ pqbool html3; /* output HTML tables */ pqbool expanded; /* expand tables */ pqbool pager; /* use pager for output if needed */ char *fieldSep; /* field separator */ char *tableOpt; /* attributes for HTML table element */ char *caption; /* HTML table caption */ char **fieldName; /* null-terminated array of replacement field names */ } PQprintOpt;This function was formerly used by psql to print query results, but this is no longer the case. Note that it assumes all the data is in text format.
36.3.3. Retrieving Other Result Information #
These functions are used to extract other information from PGresult objects.
PQcmdStatus#Returns the command status tag from the SQL command that generated the
PGresult.char *PQcmdStatus(PGresult *res);
Commonly this is just the name of the command, but it might include additional data such as the number of rows processed. The caller should not free the result directly. It will be freed when the associated
PGresulthandle is passed toPQclear.PQcmdTuples#Returns the number of rows affected by the SQL command.
char *PQcmdTuples(PGresult *res);
This function returns a string containing the number of rows affected by the SQL statement that generated the
PGresult. This function can only be used following the execution of aSELECT,CREATE TABLE AS,INSERT,UPDATE,DELETE,MERGE,MOVE,FETCH, orCOPYstatement, or anEXECUTEof a prepared query that contains anINSERT,UPDATE,DELETE, orMERGEstatement. If the command that generated thePGresultwas anything else,PQcmdTuplesreturns an empty string. The caller should not free the return value directly. It will be freed when the associatedPGresulthandle is passed toPQclear.PQoidValue#Returns the OID of the inserted row, if the SQL command was an
INSERTthat inserted exactly one row into a table that has OIDs, or aEXECUTEof a prepared query containing a suitableINSERTstatement. Otherwise, this function returnsInvalidOid. This function will also returnInvalidOidif the table affected by theINSERTstatement does not contain OIDs.Oid PQoidValue(const PGresult *res);
PQoidStatus#This function is deprecated in favor of
PQoidValueand is not thread-safe. It returns a string with the OID of the inserted row, whilePQoidValuereturns the OID value.char *PQoidStatus(const PGresult *res);
36.3.4. Escaping Strings for Inclusion in SQL Commands #
PQescapeLiteral#char *PQescapeLiteral(PGconn *conn, const char *str, size_t length);
PQescapeLiteralescapes a string for use within an SQL command. This is useful when inserting data values as literal constants in SQL commands. Certain characters (such as quotes and backslashes) must be escaped to prevent them from being interpreted specially by the SQL parser.PQescapeLiteralperforms this operation.PQescapeLiteralreturns an escaped version of thestrparameter in memory allocated withmalloc(). This memory should be freed usingPQfreemem()when the result is no longer needed. A terminating zero byte is not required, and should not be counted inlength. (If a terminating zero byte is found beforelengthbytes are processed,PQescapeLiteralstops at the zero; the behavior is thus rather likestrncpy.) The return string has all special characters replaced so that they can be properly processed by the Postgres Pro string literal parser. A terminating zero byte is also added. The single quotes that must surround Postgres Pro string literals are included in the result string.On error,
PQescapeLiteralreturnsNULLand a suitable message is stored in theconnobject.Tip
It is especially important to do proper escaping when handling strings that were received from an untrustworthy source. Otherwise there is a security risk: you are vulnerable to “SQL injection” attacks wherein unwanted SQL commands are fed to your database.
Note that it is neither necessary nor correct to do escaping when a data value is passed as a separate parameter in
PQexecParamsor its sibling routines.PQescapeIdentifier#char *PQescapeIdentifier(PGconn *conn, const char *str, size_t length);
PQescapeIdentifierescapes a string for use as an SQL identifier, such as a table, column, or function name. This is useful when a user-supplied identifier might contain special characters that would otherwise not be interpreted as part of the identifier by the SQL parser, or when the identifier might contain upper case characters whose case should be preserved.PQescapeIdentifierreturns a version of thestrparameter escaped as an SQL identifier in memory allocated withmalloc(). This memory must be freed usingPQfreemem()when the result is no longer needed. A terminating zero byte is not required, and should not be counted inlength. (If a terminating zero byte is found beforelengthbytes are processed,PQescapeIdentifierstops at the zero; the behavior is thus rather likestrncpy.) The return string has all special characters replaced so that it will be properly processed as an SQL identifier. A terminating zero byte is also added. The return string will also be surrounded by double quotes.On error,
PQescapeIdentifierreturnsNULLand a suitable message is stored in theconnobject.Tip
As with string literals, to prevent SQL injection attacks, SQL identifiers must be escaped when they are received from an untrustworthy source.
PQescapeStringConn#size_t PQescapeStringConn(PGconn *conn, char *to, const char *from, size_t length, int *error);PQescapeStringConnescapes string literals, much likePQescapeLiteral. UnlikePQescapeLiteral, the caller is responsible for providing an appropriately sized buffer. Furthermore,PQescapeStringConndoes not generate the single quotes that must surround Postgres Pro string literals; they should be provided in the SQL command that the result is inserted into. The parameterfrompoints to the first character of the string that is to be escaped, and thelengthparameter gives the number of bytes in this string. A terminating zero byte is not required, and should not be counted inlength. (If a terminating zero byte is found beforelengthbytes are processed,PQescapeStringConnstops at the zero; the behavior is thus rather likestrncpy.)toshall point to a buffer that is able to hold at least one more byte than twice the value oflength, otherwise the behavior is undefined. Behavior is likewise undefined if thetoandfromstrings overlap.If the
errorparameter is notNULL, then*erroris set to zero on success, nonzero on error. Presently the only possible error conditions involve invalid multibyte encoding in the source string. The output string is still generated on error, but it can be expected that the server will reject it as malformed. On error, a suitable message is stored in theconnobject, whether or noterrorisNULL.PQescapeStringConnreturns the number of bytes written toto, not including the terminating zero byte.PQescapeString#PQescapeStringis an older, deprecated version ofPQescapeStringConn.size_t PQescapeString (char *to, const char *from, size_t length);
The only difference from
PQescapeStringConnis thatPQescapeStringdoes not takePGconnorerrorparameters. Because of this, it cannot adjust its behavior depending on the connection properties (such as character encoding) and therefore it might give the wrong results. Also, it has no way to report error conditions.PQescapeStringcan be used safely in client programs that work with only one Postgres Pro connection at a time (in this case it can find out what it needs to know “behind the scenes”). In other contexts it is a security hazard and should be avoided in favor ofPQescapeStringConn.PQescapeByteaConn#Escapes binary data for use within an SQL command with the type
bytea. As withPQescapeStringConn, this is only used when inserting data directly into an SQL command string.unsigned char *PQescapeByteaConn(PGconn *conn, const unsigned char *from, size_t from_length, size_t *to_length);Certain byte values must be escaped when used as part of a
bytealiteral in an SQL statement.PQescapeByteaConnescapes bytes using either hex encoding or backslash escaping. See Section 8.4 for more information.The
fromparameter points to the first byte of the string that is to be escaped, and thefrom_lengthparameter gives the number of bytes in this binary string. (A terminating zero byte is neither necessary nor counted.) Theto_lengthparameter points to a variable that will hold the resultant escaped string length. This result string length includes the terminating zero byte of the result.PQescapeByteaConnreturns an escaped version of thefromparameter binary string in memory allocated withmalloc(). This memory should be freed usingPQfreemem()when the result is no longer needed. The return string has all special characters replaced so that they can be properly processed by the Postgres Pro string literal parser, and thebyteainput function. A terminating zero byte is also added. The single quotes that must surround Postgres Pro string literals are not part of the result string.On error, a null pointer is returned, and a suitable error message is stored in the
connobject. Currently, the only possible error is insufficient memory for the result string.PQescapeBytea#PQescapeByteais an older, deprecated version ofPQescapeByteaConn.unsigned char *PQescapeBytea(const unsigned char *from, size_t from_length, size_t *to_length);The only difference from
PQescapeByteaConnis thatPQescapeByteadoes not take aPGconnparameter. Because of this,PQescapeByteacan only be used safely in client programs that use a single Postgres Pro connection at a time (in this case it can find out what it needs to know “behind the scenes”). It might give the wrong results if used in programs that use multiple database connections (usePQescapeByteaConnin such cases).PQunescapeBytea#Converts a string representation of binary data into binary data — the reverse of
PQescapeBytea. This is needed when retrievingbyteadata in text format, but not when retrieving it in binary format.unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length);
The
fromparameter points to a string such as might be returned byPQgetvaluewhen applied to abyteacolumn.PQunescapeByteaconverts this string representation into its binary representation. It returns a pointer to a buffer allocated withmalloc(), orNULLon error, and puts the size of the buffer into_length. The result must be freed usingPQfreememwhen it is no longer needed.This conversion is not exactly the inverse of
PQescapeBytea, because the string is not expected to be “escaped” when received fromPQgetvalue. In particular this means there is no need for string quoting considerations, and so no need for aPGconnparameter.