1;; CLISP interface to PostgreSQL <http://www.postgresql.org/>
2;; Copyright (C) 1999-2010 Sam Steingold
3;; This is free software, distributed under the GNU GPL v2+
4
5;; this file is in sync with libpq-fe.h 1.147
6;; CVS tags: REL8_5_ALPHA3_BRANCH, REL8_5_ALPHA3, REL8_5_ALPHA2_BRANCH, REL8_5_ALPHA2, REL8_5_ALPHA1_BRANCH, REL8_5_ALPHA1, REL8_4_STABLE, REL8_4_RC2, REL8_4_RC1, REL8_4_4, REL8_4_3, REL8_4_2, REL8_4_1, REL8_4_0
7;; http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/src/interfaces/libpq/libpq-fe.h
8;; and with postgres_ext.h 1.17
9;; CVS tags: REL9_0_BETA1, REL9_0_ALPHA5_BRANCH, REL9_0_ALPHA5, REL9_0_ALPHA4_BRANCH, REL9_0_ALPHA4, REL8_5_ALPHA3_BRANCH, REL8_5_ALPHA3, REL8_5_ALPHA2_BRANCH, REL8_5_ALPHA2, REL8_5_ALPHA1_BRANCH, REL8_5_ALPHA1, REL8_4_STABLE, REL8_4_RC2, REL8_4_RC1, REL8_4_BETA2, REL8_4_BETA1, REL8_4_4, REL8_4_3, REL8_4_2, REL8_4_1, REL8_4_0, REL8_3_STABLE, REL8_3_RC2, REL8_3_RC1, REL8_3_BETA4, REL8_3_BETA3, REL8_3_BETA2, REL8_3_BETA1, REL8_3_9, REL8_3_8, REL8_3_7, REL8_3_6, REL8_3_5, REL8_3_4, REL8_3_3, REL8_3_2, REL8_3_11, REL8_3_10, REL8_3_1, REL8_3_0
10;; http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/src/include/postgres_ext.h
11
12(pushnew :PostgreSQL *features*)
13
14(defpackage "SQL"
15  (:nicknames "POSTGRES" "POSTGRESQL")
16  (:modern t)
17  (:use "COMMON-LISP" "FFI")
18  (:shadowing-import-from "EXPORTING"
19    #:defconstant #:defun #:defmacro #:defvar #:def-c-const
20    #:def-c-type #:def-c-enum #:def-c-struct #:def-c-var #:def-call-out))
21
22(in-package "SQL")
23
24(setf (documentation (find-package "SQL") 'sys::impnotes) "postgresql")
25
26(ffi:default-foreign-language :stdc)
27(eval-when (compile) (setq *foreign-guard* t))
28
29(c-lines "#include \"config.h\"~%") ; local PostgreSQL config
30
31(c-lines "#if defined(HAVE_POSTGRES_EXT_H)
32#  include <postgres_ext.h>
33#elif defined(HAVE_POSTGRESQL_POSTGRES_EXT_H)
34#  include <postgresql/postgres_ext.h>
35#elif defined(HAVE_PGSQL_POSTGRES_EXT_H)
36#  include <pgsql/postgres_ext.h>
37#else
38#  error PostgreSQL is not found
39#endif~%")
40
41(def-c-type Oid)
42
43(eval-when (load compile eval)
44  (defconstant NAMEDATALEN 64)
45  (defconstant MAX-PARAM 64)
46  (defconstant BUFSIZ 1024))
47
48;; Identifiers of error message fields.
49(def-c-const PG_DIAG_SEVERITY)           ; 'S'
50(def-c-const PG_DIAG_SQLSTATE)           ; 'C'
51(def-c-const PG_DIAG_MESSAGE_PRIMARY)    ; 'M'
52(def-c-const PG_DIAG_MESSAGE_DETAIL)     ; 'D'
53(def-c-const PG_DIAG_MESSAGE_HINT)       ; 'H'
54(def-c-const PG_DIAG_STATEMENT_POSITION) ; 'P'
55(def-c-const PG_DIAG_INTERNAL_POSITION)  ; 'p'
56(def-c-const PG_DIAG_INTERNAL_QUERY)     ; 'q'
57(def-c-const PG_DIAG_CONTEXT)            ; 'W'
58(def-c-const PG_DIAG_SOURCE_FILE)        ; 'F'
59(def-c-const PG_DIAG_SOURCE_LINE)        ; 'L'
60(def-c-const PG_DIAG_SOURCE_FUNCTION)    ; 'R'
61
62(c-lines "#if defined(HAVE_POSTGRES_EXT_H)
63#  include <libpq-fe.h>
64#elif defined(HAVE_POSTGRESQL_POSTGRES_EXT_H)
65#  include <postgresql/libpq-fe.h>
66#elif defined(HAVE_PGSQL_POSTGRES_EXT_H)
67#  include <pgsql/libpq-fe.h>
68#else
69#  error PostgreSQL is not found
70#endif~%")
71
72(def-c-const PG_COPYRES_ATTRS)         ; 0x01
73(def-c-const PG_COPYRES_TUPLES)        ; 0x02 Implies PG_COPYRES_ATTRS
74(def-c-const PG_COPYRES_EVENTS)        ; 0x04
75(def-c-const PG_COPYRES_NOTICEHOOKS)   ; 0x08
76
77(def-c-enum ConnStatusType
78  CONNECTION_OK
79  CONNECTION_BAD
80  CONNECTION_STARTED          ; Waiting for connection to be made.
81  CONNECTION_MADE             ; Connection OK; waiting to send.
82  CONNECTION_AWAITING_RESPONSE ; Waiting for a response from the postmaster.
83  CONNECTION_AUTH_OK ; Received authentication; waiting for backend startup.
84  CONNECTION_SETENV           ; Negotiating environment.
85  CONNECTION_SSL_STARTUP      ; Negotiating SSL.
86  CONNECTION_NEEDED)          ; Internal state: connect() needed
87
88(def-c-enum PostgresPollingStatusType
89  (PGRES_POLLING_FAILED 0)
90  PGRES_POLLING_READING         ; These two indicate that one may
91  PGRES_POLLING_WRITING         ; use select before polling again.
92  PGRES_POLLING_OK
93  PGRES_POLLING_ACTIVE) ; unused; keep for awhile for backwards compatibility
94
95(def-c-enum ExecStatusType
96  (PGRES_EMPTY_QUERY 0)         ; empty query string was executed
97  PGRES_COMMAND_OK              ; a query command that doesn't return anything
98                                ; was executed properly by the backend
99  PGRES_TUPLES_OK ; a query command that returns tuples was executed properly
100                  ; by the backend, PGresult contains the result tuples
101  PGRES_COPY_OUT                ; Copy Out data transfer in progress
102  PGRES_COPY_IN                 ; Copy In data transfer in progress
103  PGRES_BAD_RESPONSE ; an unexpected response was recv'd from the backend
104  PGRES_NONFATAL_ERROR          ; notice or warning message
105  PGRES_FATAL_ERROR)            ; query failed
106
107(def-c-enum PGTransactionStatusType
108  PQTRANS_IDLE                  ; connection idle
109  PQTRANS_ACTIVE                ; command in progress
110  PQTRANS_INTRANS               ; idle, within transaction block
111  PQTRANS_INERROR               ; idle, within failed transaction
112  PQTRANS_UNKNOW)               ; cannot determine status
113
114(def-c-enum PGVerbosity
115  PQERRORS_TERSE                ; single-line error messages
116  PQERRORS_DEFAULT              ; recommended style
117  PQERRORS_VERBOSE)             ; all the facts, ma'am
118
119;;(def-c-type PGconn (c-struct vector)) ; components unknown
120;;(def-c-type PGresult (c-struct vector)) ; components unknown
121;;(def-c-struct PGconn) ; components unknown
122;;(def-c-struct PGresult) ; components unknown
123(def-c-type PGconn c-pointer) ; components unknown
124(def-c-type PGresult c-pointer) ; components unknown
125(def-c-type PGcancel c-pointer) ; components unknown
126
127(def-c-struct PGnotify
128  (relname c-string)
129  (be_pid int)
130  (extra c-string)
131  ;; private:
132  (next (c-pointer PGnotify)))
133
134;; typedef void (*PQnoticeReceiver) (void *arg, const PGresult *res)
135;; typedef void (*PQnoticeProcessor) (void *arg, const char *message)
136(def-c-type PQnoticeReceiver
137    (c-function (:arguments (p1 c-pointer) (res PGresult))
138                (:return-type nil)))
139(def-c-type PQnoticeProcessor
140    (c-function (:arguments (p1 c-pointer) (message c-string))
141                (:return-type nil)))
142
143(def-c-type pqbool)             ; for PQprint()
144
145(def-c-struct PQprintOpt
146  (header pqbool)           ; print output field headings and row count
147  (align pqbool)            ; fill align the fields
148  (standard pqbool)         ; old brain dead format
149  (html3 pqbool)            ; output html tables
150  (expanded pqbool)         ; expand tables
151  (pager pqbool)            ; use pager for output if needed
152  (fieldSep c-string)       ; field separator
153  (tableOpt c-string)       ; insert to HTML <table ...>
154  (caption c-string)        ; HTML <caption>
155  (fieldName (c-array-ptr c-string))) ; null terminated array of replacement field names
156
157(def-c-struct PQconninfoOption
158  (keyword c-string)        ; The keyword of the option
159  (envvar c-string)         ; Fallback environment variable name
160  (compiled c-string)       ; Fallback compiled in default value
161  (val c-string)            ; Option's current value, or NULL
162  (label c-string)          ; Label for field in connect dialog
163  (dispchar c-string) ; Indicates how to display this field in a
164                      ; connect dialog. Values are: ""
165                      ; Display entered value as is "*"
166                      ; Password field - hide value "D"
167                      ; Debug option - don't show by default
168  (dispsize int))     ; Field size in characters for dialog
169
170(def-c-struct PQArgBlock
171  (len int)
172  (isint int)
173  (u c-pointer))                ; (c-union (ptr c-pointer) (integer int))
174
175(def-c-struct PGresAttDesc
176  (name c-string)                  ; column name
177  (tableid Oid)                    ; source table, if known
178  (columnid int)                   ; source column, if known
179  (format int)                     ; format code for value (text/binary)
180  (typid Oid)                      ; type id
181  (typlen int)                     ; type size
182  (atttypmod int))                 ; type-specific modifier info
183
184;; === fe-connect.c ===
185;; make a new client connection to the backend
186;; Asynchronous (non-blocking)
187(def-call-out PQconnectStart (:return-type PGconn)
188  (:arguments (conninfo c-string)))
189(def-call-out PQconnectPoll (:return-type PostgresPollingStatusType)
190  (:arguments (conn PGconn)))
191
192;; Synchronous (blocking)
193(def-call-out PQconnectdb (:return-type PGconn)
194  (:arguments (conninfo c-string)))
195(def-call-out PQsetdbLogin (:return-type PGconn)
196  (:arguments (pghost c-string) (pgport c-string) (pgoptions c-string)
197              (pgtty c-string) (dbname c-string) (login c-string)
198              (pwd c-string)))
199(defmacro PQsetdb (a0 a1 a2 a3 a4) `(PQsetdbLogin ,a0 ,a1 ,a2 ,a3 ,a4 nil nil))
200
201;; close the current connection and free the PGconn data structure
202(def-call-out PQfinish (:arguments (conn PGconn)) (:return-type nil))
203
204;; get info about connection options known to PQconnectdb
205(def-call-out PQconndefaults (:return-type (c-ptr PQconninfoOption))
206  (:arguments))
207;; parse connection options in same way as PQconnectdb
208(def-call-out PQconninfoParse (:return-type (c-ptr PQconninfoOption))
209  (:arguments (conninfo c-string) (errmsg (c-ptr c-string) :out)))
210;; free the data structure returned by PQconndefaults() & PQconninfoParse()
211(def-call-out PQconninfoFree (:return-type nil)
212  (:arguments (connOptions (c-ptr PQconninfoOption))))
213
214;; close the current connection and restablish a new one with the same
215;; parameters:
216;; Asynchronous (non-blocking)
217;; extern int PQresetStart(PGconn *conn);
218(def-call-out PQresetStart (:return-type int) (:arguments (conn PGconn)))
219;; extern PostgresPollingStatusType PQresetPoll(PGconn *conn);
220(def-call-out PQresetPoll (:return-type PostgresPollingStatusType)
221  (:arguments (conn PGconn)))
222;; Synchronous (blocking)
223;; extern void PQreset(PGconn *conn);
224(def-call-out PQreset (:return-type nil) (:arguments (conn PGconn)))
225
226;; request a cancel structure
227(def-call-out PQgetCancel (:return-type PGcancel) (:arguments (conn PGconn)))
228;; free a cancel structure
229(def-call-out PQfreeCancel (:return-type nil) (:arguments (conn PGcancel)))
230;; issue a cancel request
231(def-call-out PQcancel (:return-type int)
232  (:arguments (cancel PGcancel)
233              (errbuf (c-ptr (c-array-max char #.BUFSIZ)) :out :alloca)
234              (errbufsize int))) ; pass BUFSIZ
235;; backwards compatible version of PQcancel; not thread-safe
236(def-call-out PQrequestCancel (:return-type int) (:arguments (conn PGconn)))
237
238;; Accessor functions for PGconn objects
239(def-call-out PQdb (:return-type c-string) (:arguments (conn PGconn)))
240(def-call-out PQuser (:return-type c-string) (:arguments (conn PGconn)))
241(def-call-out PQpass (:return-type c-string) (:arguments (conn PGconn)))
242(def-call-out PQhost (:return-type c-string) (:arguments (conn PGconn)))
243(def-call-out PQport (:return-type c-string) (:arguments (conn PGconn)))
244(def-call-out PQtty (:return-type c-string) (:arguments (conn PGconn)))
245(def-call-out PQoptions (:return-type c-string) (:arguments (conn PGconn)))
246(def-call-out PQstatus (:return-type ConnStatusType) (:arguments (conn PGconn)))
247(def-call-out PQtransactionStatus (:return-type PGTransactionStatusType)
248  (:arguments (conn PGconn)))
249(def-call-out PQparameterStatus (:return-type c-string)
250  (:arguments (conn PGconn) (param-name c-string)))
251(def-call-out PQprotocolVersion (:return-type int) (:arguments (conn PGconn)))
252(def-call-out PQserverVersion (:return-type int) (:arguments (conn PGconn)))
253(def-call-out PQerrorMessage (:return-type c-string) (:arguments (conn PGconn)))
254(def-call-out PQsocket (:return-type int) (:arguments (conn PGconn)))
255(def-call-out PQbackendPID (:return-type int) (:arguments (conn PGconn)))
256(def-call-out PQconnectionNeedsPassword (:return-type int)
257  (:arguments (conn PGconn)))
258(def-call-out PQconnectionUsedPassword (:return-type int)
259  (:arguments (conn PGconn)))
260(def-call-out PQclientEncoding (:return-type int) (:arguments (conn PGconn)))
261(def-call-out PQsetClientEncoding (:return-type int)
262  (:arguments (conn PGconn) (encoding c-string)))
263
264;; Get the OpenSSL structure associated with a connection. Returns NULL for
265;; unencrypted connections or if any other TLS library is in use.
266(def-call-out PQgetssl (:arguments (conn PGconn)) (:return-type c-pointer))
267;; Tell libpq whether it needs to initialize OpenSSL (not in libpq 8.0)
268(def-call-out PQinitSSL (:return-type nil) (:arguments (do_init int)))
269;; More detailed way to tell libpq whether it needs to initialize OpenSSL
270(def-call-out PQinitOpenSSL (:return-type nil)
271  (:arguments (do_ssl int) (do_crypto int)))
272
273;; Set verbosity for PQerrorMessage and PQresultErrorMessage
274(def-call-out PQsetErrorVerbosity (:return-type PGVerbosity)
275  (:arguments (conn PGconn) (verbosity PGVerbosity)))
276
277;; Enable/disable tracing
278(def-call-out PQtrace (:return-type nil)
279  (:arguments (conn PGconn) (debug_port FILE)))
280(def-call-out PQuntrace (:return-type nil) (:arguments (conn PGconn)))
281
282;; Override default notice handling routines
283(def-call-out PQsetNoticeReceiver (:return-type PQnoticeReceiver)
284  (:arguments (conn PGconn) (proc PQnoticeProcessor) (arg c-pointer)))
285(def-call-out PQsetNoticeProcessor (:return-type PQnoticeProcessor)
286  (:arguments (conn PGconn) (proc PQnoticeProcessor) (arg c-pointer)))
287
288;; Used to set callback that prevents concurrent access to
289;; non-thread safe functions that libpq needs.
290;; The default implementation uses a libpq internal mutex.
291;; Only required for multithreaded apps that use kerberos
292;; both within their app and for postgresql connections.
293;;typedef void (*pgthreadlock_t) (int acquire);
294;;extern pgthreadlock_t PQregisterThreadLock(pgthreadlock_t newhandler);
295
296;; === fe-exec.c ===
297;; Simple synchronous query
298(def-call-out PQexec (:return-type PGresult)
299  (:arguments (conn PGconn) (query c-string)))
300(def-call-out PQexecParams (:return-type PGresult)
301  (:arguments (conn PGconn) (command c-string) (nParams int)
302              (paramTypes (c-array-ptr Oid)) ; at least nParams
303              (paramValues (c-array-ptr c-string)) ; ditto
304              (paramLengths (c-array-ptr int))     ; ditto
305              (paramFormats (c-array-ptr int))     ; ditto
306              (resultFormat int)))
307(def-call-out PQprepare (:return-type PGresult)
308  (:arguments (conn PGconn) (stmtName c-string) (query c-string) (nParams int)
309              (paramTypes (c-array-ptr Oid)))) ; at least nParams
310(def-call-out PQexecPrepared (:return-type PGresult)
311  (:arguments (conn PGconn) (stmtName c-string) (nParams int)
312              (paramValues (c-array-ptr c-string)) ; at least nParams
313              (paramLengths (c-array-ptr int))     ; ditto
314              (paramFormats (c-array-ptr int))     ; ditto
315              (resultFormat int)))
316
317;; Interface for multiple-result or asynchronous queries
318(def-call-out PQsendQuery (:return-type int)
319  (:arguments (conn PGconn) (query c-string)))
320(def-call-out PQsendQueryParams (:return-type int)
321  (:arguments (conn PGconn) (command c-string) (nParams int)
322              (paramTypes (c-array-ptr Oid)) ; at least nParams
323              (paramValues (c-array-ptr c-string)) ; ditto
324              (paramLengths (c-array-ptr int))     ; ditto
325              (paramFormats (c-array-ptr int))     ; ditto
326              (resultFormat int)))
327(def-call-out PQsendPrepare (:return-type int)
328  (:arguments (conn PGconn) (stmtName c-string) (query c-string) (nParams int)
329              (paramTypes (c-array-ptr Oid)))) ; at least nParams
330(def-call-out PQsendQueryPrepared (:return-type int)
331  (:arguments (conn PGconn) (stmtName c-string) (nParams int)
332              (paramValues (c-array-ptr c-string)) ; at least nParams
333              (paramLengths (c-array-ptr int))     ; ditto
334              (paramFormats (c-array-ptr int))     ; ditto
335              (resultFormat int)))
336(def-call-out PQgetResult (:return-type PGresult) (:arguments (conn PGconn)))
337
338;; Routines for managing an asynchronous query
339(def-call-out PQisBusy (:return-type int) (:arguments (conn PGconn)))
340(def-call-out PQconsumeInput (:return-type int) (:arguments (conn PGconn)))
341
342;; LISTEN/NOTIFY support
343(def-call-out PQnotifies (:return-type (c-ptr PGnotify))
344  (:arguments (conn PGconn)))
345
346;; Routines for copy in/out
347(def-call-out PQputCopyData (:return-type int)
348  (:arguments (conn PGconn) (buffer c-string) (nbytes int)))
349(def-call-out PQputCopyEnd (:return-type int)
350  (:arguments (conn PGconn) (errormsg c-string)))
351(def-call-out PQgetCopyData (:return-type int)
352  (:arguments (conn PGconn) (buffer (c-ptr c-string) :out) (async int)))
353
354;; Deprecated routines for copy in/out
355(def-call-out PQgetline (:return-type int)
356  (:arguments (conn PGconn) (string c-string) (length int)))
357(def-call-out PQputline (:return-type int)
358  (:arguments (conn PGconn) (string c-string)))
359(def-call-out PQgetlineAsync (:return-type int)
360  (:arguments (conn PGconn) (buffer c-string) (bufsize int)))
361(def-call-out PQputnbytes (:return-type int)
362  (:arguments (conn PGconn) (buffer c-string) (nbytes int)))
363(def-call-out PQendcopy (:arguments (conn PGconn)) (:return-type int))
364
365;; Set blocking/nonblocking connection to the backend
366(def-call-out PQsetnonblocking (:return-type int)
367  (:arguments (conn PGconn) (arg int)))
368(def-call-out PQisnonblocking (:return-type int) (:arguments (conn PGconn)))
369(def-call-out PQisthreadsafe (:return-type int) (:arguments))
370
371;; Force the write buffer to be written (or at least try)
372(def-call-out PQflush (:return-type int) (:arguments (conn PGconn)))
373
374;; "Fast path" interface --- not really recommended for application use
375(def-call-out PQfn (:return-type PGresult)
376  (:arguments (conn PGconn) (fnid int) (result_buf (c-ptr int) :out)
377              (result_len (c-ptr int) :out) (result_is_int int)
378              (args (c-array-ptr PQArgBlock)) ; at least nargs
379              (nargs int)))
380
381;; Accessor functions for PGresult objects
382(def-call-out PQresultStatus (:return-type ExecStatusType)
383  (:arguments (res PGresult)))
384(def-call-out PQresStatus (:return-type c-string)
385  (:arguments (status ExecStatusType)))
386(def-call-out PQresultErrorMessage (:return-type c-string)
387  (:arguments (res PGresult)))
388(def-call-out PQresultErrorField (:return-type c-string)
389  (:arguments (res PGresult) (fieldcode int)))
390(def-call-out PQntuples (:return-type int) (:arguments (res PGresult)))
391(def-call-out PQnfields (:return-type int) (:arguments (res PGresult)))
392(def-call-out PQbinaryTuples (:return-type int) (:arguments (res PGresult)))
393(def-call-out PQfname (:return-type c-string)
394  (:arguments (res PGresult) (field_num int)))
395(def-call-out PQfnumber (:return-type int)
396  (:arguments (res PGresult) (field_name c-string)))
397(def-call-out PQftable (:return-type Oid)
398  (:arguments (res PGresult) (field_num int)))
399(def-call-out PQftablecol (:return-type int)
400  (:arguments (res PGresult) (field_num int)))
401(def-call-out PQfformat (:return-type int)
402  (:arguments (res PGresult) (field_num int)))
403(def-call-out PQftype (:return-type Oid)
404  (:arguments (res PGresult) (field_num int)))
405(def-call-out PQfsize (:return-type int)
406  (:arguments (res PGresult) (field_num int)))
407(def-call-out PQfmod (:return-type int)
408  (:arguments (res PGresult) (field_num int)))
409(def-call-out PQcmdStatus (:return-type c-string)
410  (:arguments (res PGresult)))
411(def-call-out PQoidStatus (:return-type c-string) ; old and ugly
412  (:arguments (res PGresult)))
413(def-call-out PQoidValue (:return-type Oid) ; new and improved
414  (:arguments (res PGresult)))
415(def-call-out PQcmdTuples (:return-type c-string)
416  (:arguments (res PGresult)))
417(def-call-out PQgetvalue (:return-type c-string)
418  (:arguments (res PGresult) (tup_num int) (field_num int)))
419(def-call-out PQgetlength (:return-type int)
420  (:arguments (res PGresult) (tup_num int) (field_num int)))
421(def-call-out PQgetisnull (:return-type int)
422  (:arguments (res PGresult) (tup_num int) (field_num int)))
423(def-call-out PQnparams (:return-type int) (:arguments (res PGresult)))
424(def-call-out PQparamtype (:return-type Oid)
425  (:arguments (res PGresult) (param_num int)))
426
427;; Describe prepared statements and portals
428(def-call-out PQdescribePrepared (:return-type PGresult)
429  (:arguments (conn PGconn) (stmt c-string)))
430(def-call-out PQdescribePortal (:return-type PGresult)
431  (:arguments (conn PGconn) (portal c-string)))
432(def-call-out PQsendDescribePrepared (:return-type int)
433  (:arguments (conn PGconn) (stmt c-string)))
434(def-call-out PQsendDescribePortal (:return-type int)
435  (:arguments (conn PGconn) (portal c-string)))
436
437;; Delete a PGresult
438(def-call-out PQclear (:return-type nil) (:arguments (res PGresult)))
439
440;; For freeing other alloc'd results, such as PGnotify structs
441(def-call-out PQfreemem (:return-type nil) (:arguments (res c-pointer)))
442
443;; Create and manipulate PGresults
444(def-call-out PQmakeEmptyPGresult (:return-type PGresult)
445  (:arguments (conn PGconn) (status ExecStatusType)))
446(def-call-out PQcopyResult (:return-type PGresult)
447  (:arguments (src PGresult) (flags int)))
448(def-call-out PQsetResultAttrs (:return-type int)
449  (:arguments (res PGresult) (numAttributes int)
450              (attDescs (c-pointer PGresAttDesc))))
451(def-call-out PQresultAlloc (:return-type c-pointer)
452  (:arguments (res PGresult) (nBytes size_t)))
453(def-call-out PQsetvalue (:return-type int)
454  (:arguments (res PGresult) (tup_num int) (field_num int)
455              (value c-pointer) (len int)))
456
457;; Quoting strings before inclusion in queries
458(def-call-out PQescapeStringConn (:return-type size_t)
459  (:arguments (conn PGconn)
460              (to (c-ptr (c-array-max char #.BUFSIZ)) :out :alloca)
461              (from c-string) (length size_t) (error (c-ptr int) :out)))
462(def-call-out PQescapeByteaConn (:return-type (c-array-max uchar #.BUFSIZ))
463  (:arguments (conn PGconn)
464              (from (c-array-ptr uchar)) ; at least from_length
465              (from_length size_t)
466              (to_length (c-ptr size_t) :out)))
467(def-call-out PQunescapeBytea (:return-type (c-array-max uchar #.BUFSIZ))
468  (:arguments (strtext (c-ptr (c-array-max uchar #.BUFSIZ)) :in-out)
469              (retbuflen (c-ptr size_t) :out)))
470
471;; These forms are deprecated!
472(def-call-out PQescapeString (:return-type size_t)
473  (:arguments (to (c-ptr (c-array-max char #.BUFSIZ)) :out :alloca)
474              (from c-string) (length size_t)))
475(def-call-out PQescapeBytea (:return-type (c-array-max char #.BUFSIZ))
476  (:arguments (from (c-ptr (c-array-max char #.BUFSIZ)) :in-out)
477              (from_length size_t) (to_length (c-ptr size_t) :out)))
478
479;; === fe-print.c ===
480(def-call-out PQprint (:return-type nil)
481  (:arguments (fout FILE)
482              (res PGresult)
483              (ps (c-ptr PQprintOpt))))
484(def-call-out PQdisplayTuples (:return-type nil)
485  (:arguments (res PGresult) (fp FILE)
486              (fillAlign int) (fieldSep c-string)
487              (printHeader int) (quiet int)))
488(def-call-out PQprintTuples (:return-type nil)
489  (:arguments (res PGresult) (fout FILE)
490              (printAttName int) (terseOutput int) (width int)))
491
492;; === fe-lobj.c ===
493;; Large-object access routines
494(def-call-out lo_open (:return-type int)
495  (:arguments (conn PGconn) (lobjId Oid) (mode int)))
496(def-call-out lo_close (:return-type int)
497  (:arguments (conn PGconn) (fd int)))
498(def-call-out lo_read (:return-type int)
499  (:arguments (conn PGconn) (fd int) (buf c-string) (len int)))
500(def-call-out lo_write (:return-type int)
501  (:arguments (conn PGconn) (fd int) (buf c-string) (len int)))
502(def-call-out lo_lseek (:return-type int)
503  (:arguments (conn PGconn) (fd int) (offset int) (whence int)))
504(def-call-out lo_creat (:return-type Oid)
505  (:arguments (conn PGconn) (mode int)))
506(def-call-out lo_create (:return-type Oid)
507  (:arguments (conn PGconn) (lobjId Oid)))
508(def-call-out lo_tell (:return-type int)
509  (:arguments (conn PGconn) (fd int)))
510(def-call-out lo_truncate (:return-type int)
511  (:arguments (conn PGconn) (fd int) (len size_t)))
512(def-call-out lo_unlink (:return-type int)
513  (:arguments (conn PGconn) (lobjId Oid)))
514(def-call-out lo_import (:return-type Oid)
515  (:arguments (conn PGconn) (filename c-string)))
516(def-call-out lo_import_with_oid (:return-type Oid)
517  (:arguments (conn PGconn) (filename c-string) (lobjId Oid)))
518(def-call-out lo_export (:return-type int)
519  (:arguments (conn PGconn) (lobjId Oid) (filename c-string)))
520
521;; === fe-misc.c ===
522;; Determine length of multibyte encoded char at *s
523(def-call-out PQmblen (:return-type int)
524  (:arguments (s (c-pointer uchar)) (encoding int)))
525;; Determine display length of multibyte encoded char at *s
526(def-call-out PQdsplen (:return-type int)
527  (:arguments (s (c-pointer uchar)) (encoding int)))
528;; Get encoding id from environment variable PGCLIENTENCODING
529(def-call-out PQenv2encoding (:return-type int) (:arguments))
530
531;; === fe-auth.c ===
532(def-call-out PQencryptPassword (:return-type c-string)
533  (:arguments (passwd c-string) (user c-string)))
534
535;; === encnames.c ===
536;; 8.1.4: detected by configure by not declared in headers
537;; (def-call-out pg_char_to_encoding (:return-type int)
538;;   (:arguments (name c-string)))
539;; (def-call-out pg_encoding_to_char (:return-type c-string)
540;;   (:arguments (encoding int)))
541(def-call-out pg_valid_server_encoding_id (:return-type int)
542  (:arguments (encoding int)))
543
544(provide "postgresql")
545