1 /*
2    Copyright (c) 2000-2021 Greg Sabino Mullane and others: see the Changes file
3    Copyright (c) 1997-2000 Edmund Mergl
4    Portions Copyright (c) 1994-1997 Tim Bunce
5 
6    You may distribute under the terms of either the GNU General Public
7    License or the Artistic License, as specified in the Perl README file.
8 
9 */
10 
11 #include <wchar.h>
12 
13 #ifdef WIN32
14 #if (!defined(_MSC_VER) || (_MSC_VER < 1900))
15 static int errno;
16 #endif
17 #include <string.h>
18 #define strcasecmp(s1,s2) stricmp((s1), (s2))
19 #else
20 #include <strings.h>
21 #endif
22 
23 #define DBDPG_TRUE (bool)1
24 #define DBDPG_FALSE (bool)0
25 #define PG_ASYNC 1
26 #define PG_OLDQUERY_CANCEL 2
27 #define PG_OLDQUERY_WAIT 4
28 #define PG_UNKNOWN_VERSION 0
29 
30 /* Force preprocessors to use this variable. Default to something valid yet noticeable */
31 #ifndef PGLIBVERSION
32 #define PGLIBVERSION 80009
33 #endif
34 
35 #include "libpq-fe.h"
36 
37 #ifndef INV_READ
38 #define INV_READ 0x00040000
39 #endif
40 #ifndef INV_WRITE
41 #define INV_WRITE 0x00020000
42 #endif
43 
44 #ifndef PGRES_COPY_BOTH
45 #define PGRES_COPY_BOTH 8
46 #endif
47 
48 #ifdef BUFSIZ
49 #undef BUFSIZ
50 #endif
51 /* this should improve I/O performance for large objects */
52 #define BUFSIZ 32768
53 
54 #define NEED_DBIXS_VERSION 93
55 
56 #define PERL_NO_GET_CONTEXT
57 
58 #include <DBIXS.h>      /* installed by the DBI module */
59 
60 #include <dbivport.h>   /* DBI portability macros */
61 
62 #include <dbd_xsh.h>    /* installed by the DBI module */
63 
64 DBISTATE_DECLARE;
65 
66 #include "types.h"
67 #include "dbdimp.h"
68 #include "quote.h"
69 
70 #define TLEVEL_slow     (DBIS->debug & DBIc_TRACE_LEVEL_MASK)
71 #define TFLAGS_slow     (DBIS->debug & DBIc_TRACE_FLAGS_MASK)
72 
73 #define TSQL            (TFLAGS_slow & 256) /* Defined in DBI */
74 
75 #define FLAGS_LIBPQ    0x01000000
76 #define FLAGS_START    0x02000000
77 #define FLAGS_END      0x04000000
78 #define FLAGS_PREFIX   0x08000000
79 #define FLAGS_LOGIN    0x10000000
80 
81 #define TFLIBPQ_slow      (TFLAGS_slow & FLAGS_LIBPQ)
82 #define TFSTART_slow      (TFLAGS_slow & FLAGS_START)
83 #define TFEND_slow        (TFLAGS_slow & FLAGS_END)
84 #define TFPREFIX_slow     (TFLAGS_slow & FLAGS_PREFIX)
85 #define TFLOGIN_slow      (TFLAGS_slow & FLAGS_LOGIN)
86 
87 #define TRACE1_slow       (TLEVEL_slow >= 1) /* Avoid using directly: DBI only */
88 #define TRACE2_slow       (TLEVEL_slow >= 2) /* Avoid using directly: DBI only */
89 #define TRACE3_slow       (TLEVEL_slow >= 3) /* Basic debugging */
90 #define TRACE4_slow       (TLEVEL_slow >= 4) /* More detailed debugging */
91 #define TRACE5_slow       (TLEVEL_slow >= 5) /* Very detailed debugging */
92 #define TRACE6_slow       (TLEVEL_slow >= 6)
93 #define TRACE7_slow       (TLEVEL_slow >= 7)
94 #define TRACE8_slow       (TLEVEL_slow >= 8)
95 
96 #define TLIBPQ_slow       (TRACE5_slow || TFLIBPQ_slow)
97 #define TSTART_slow       (TRACE4_slow || TFSTART_slow) /* Start of a major function */
98 #define TEND_slow         (TRACE4_slow || TFEND_slow)   /* End of a major function   */
99 #define TLOGIN_slow       (TRACE5_slow || TFLOGIN_slow) /* Connect and disconnect    */
100 
101 #define TRACEWARN_slow    (TRACE1_slow) /* Non-fatal but serious problems */
102 
103 /* Do we show a "dbdpg: " header? */
104 #define THEADER_slow      (TFPREFIX_slow) ? "dbdpg: " : ""
105 
106 #define TRC (void)PerlIO_printf
107 
108 /* Fancy stuff for tracing of commonly used libpq functions */
109 #define TRACE_XX                   if (TLIBPQ_slow) TRC(DBILOGFP,
110 /* XXX every use of every one of these costs at least one call to DBIS
111  * and possibly +1 for DBILOGFP and another for THEADER_slow!
112  * A better approach may be something like DBD::Oracle's
113  * http://cpansearch.perl.org/src/PYTHIAN/DBD-Oracle-1.42/ocitrace.h
114  * #define PGfooBar_log_stat(imp_xxh, stat, a,b,c) ... where imp_xxh
115  * is used to determine the logging and stat holds the result.
116  * That makes the code uncluttered and gives good flexibility.
117  */
118 #define TRACE_PQBACKENDPID         TRACE_XX "%sPQbackendPID\n",          THEADER_slow)
119 #define TRACE_PQCANCEL             TRACE_XX "%sPQcancel\n",              THEADER_slow)
120 #define TRACE_PQCLEAR              TRACE_XX "%sPQclear\n",               THEADER_slow)
121 #define TRACE_PQCMDSTATUS          TRACE_XX "%sPQcmdStatus\n",           THEADER_slow)
122 #define TRACE_PQCMDTUPLES          TRACE_XX "%sPQcmdTuples\n",           THEADER_slow)
123 #define TRACE_PQCONNECTDB          TRACE_XX "%sPQconnectdb\n",           THEADER_slow)
124 #define TRACE_PQCONSUMEINPUT       TRACE_XX "%sPQconsumeInput\n",        THEADER_slow)
125 #define TRACE_PQDB                 TRACE_XX "%sPQdb\n",                  THEADER_slow)
126 #define TRACE_PQENDCOPY            TRACE_XX "%sPQendcopy\n",             THEADER_slow)
127 #define TRACE_PQERRORMESSAGE       TRACE_XX "%sPQerrorMessage\n",        THEADER_slow)
128 #define TRACE_PQEXEC               TRACE_XX "%sPQexec\n",                THEADER_slow)
129 #define TRACE_PQEXECPARAMS         TRACE_XX "%sPQexecParams\n",          THEADER_slow)
130 #define TRACE_PQEXECPREPARED       TRACE_XX "%sPQexecPrepared\n",        THEADER_slow)
131 #define TRACE_PQFINISH             TRACE_XX "%sPQfinish\n",              THEADER_slow)
132 #define TRACE_PQFMOD               TRACE_XX "%sPQfmod\n",                THEADER_slow)
133 #define TRACE_PQFNAME              TRACE_XX "%sPQfname\n",               THEADER_slow)
134 #define TRACE_PQFREECANCEL         TRACE_XX "%sPQfreeCancel\n",          THEADER_slow)
135 #define TRACE_PQFREEMEM            TRACE_XX "%sPQfreemem\n",             THEADER_slow)
136 #define TRACE_PQFSIZE              TRACE_XX "%sPQfsize\n",               THEADER_slow)
137 #define TRACE_PQFTABLECOL          TRACE_XX "%sPQftableCol\n",           THEADER_slow)
138 #define TRACE_PQFTABLE             TRACE_XX "%sPQftable\n",              THEADER_slow)
139 #define TRACE_PQFTYPE              TRACE_XX "%sPQftype\n",               THEADER_slow)
140 #define TRACE_PQGETCANCEL          TRACE_XX "%sPQgetCancel\n",           THEADER_slow)
141 #define TRACE_PQGETCOPYDATA        TRACE_XX "%sPQgetCopyData\n",         THEADER_slow)
142 #define TRACE_PQGETISNULL          TRACE_XX "%sPQgetisnull\n",           THEADER_slow)
143 #define TRACE_PQGETRESULT          TRACE_XX "%sPQgetResult\n",           THEADER_slow)
144 #define TRACE_PQGETLENGTH          TRACE_XX "%sPQgetLength\n",           THEADER_slow)
145 #define TRACE_PQGETVALUE           TRACE_XX "%sPQgetvalue\n",            THEADER_slow)
146 #define TRACE_PQHOST               TRACE_XX "%sPQhost\n",                THEADER_slow)
147 #define TRACE_PQISBUSY             TRACE_XX "%sPQisBusy\n",              THEADER_slow)
148 #define TRACE_PQNFIELDS            TRACE_XX "%sPQnfields\n",             THEADER_slow)
149 #define TRACE_PQNOTIFIES           TRACE_XX "%sPQnotifies\n",            THEADER_slow)
150 #define TRACE_PQNTUPLES            TRACE_XX "%sPQntuples\n",             THEADER_slow)
151 #define TRACE_PQOIDVALUE           TRACE_XX "%sPQoidValue\n",            THEADER_slow)
152 #define TRACE_PQOPTIONS            TRACE_XX "%sPQoptions\n",             THEADER_slow)
153 #define TRACE_PQPARAMETERSTATUS    TRACE_XX "%sPQparameterStatus\n",     THEADER_slow)
154 #define TRACE_PQPASS               TRACE_XX "%sPQpass\n",                THEADER_slow)
155 #define TRACE_PQPORT               TRACE_XX "%sPQport\n",                THEADER_slow)
156 #define TRACE_PQPREPARE            TRACE_XX "%sPQprepare\n",             THEADER_slow)
157 #define TRACE_PQPROTOCOLVERSION    TRACE_XX "%sPQprotocolVersion\n",     THEADER_slow)
158 #define TRACE_PQPUTCOPYDATA        TRACE_XX "%sPQputCopyData\n",         THEADER_slow)
159 #define TRACE_PQPUTCOPYEND         TRACE_XX "%sPQputCopyEnd\n",          THEADER_slow)
160 #define TRACE_PQRESULTERRORFIELD   TRACE_XX "%sPQresultErrorField\n",    THEADER_slow)
161 #define TRACE_PQRESULTSTATUS       TRACE_XX "%sPQresultStatus\n",        THEADER_slow)
162 #define TRACE_PQSENDQUERY          TRACE_XX "%sPQsendQuery\n",           THEADER_slow)
163 #define TRACE_PQSENDQUERYPARAMS    TRACE_XX "%sPQsendQueryParams\n",     THEADER_slow)
164 #define TRACE_PQSENDQUERYPREPARED  TRACE_XX "%sPQsendQueryPrepared\n",   THEADER_slow)
165 #define TRACE_PQSERVERVERSION      TRACE_XX "%sPQserverVersion\n",       THEADER_slow)
166 #define TRACE_PQSETERRORVERBOSITY  TRACE_XX "%sPQsetErrorVerbosity\n",   THEADER_slow)
167 #define TRACE_PQSETNOTICEPROCESSOR TRACE_XX "%sPQsetNoticeProcessor\n",  THEADER_slow)
168 #define TRACE_PQSOCKET             TRACE_XX "%sPQsocket\n",              THEADER_slow)
169 #define TRACE_PQSTATUS             TRACE_XX "%sPQstatus\n",              THEADER_slow)
170 #define TRACE_PQTRACE              TRACE_XX "%sPQtrace\n",               THEADER_slow)
171 #define TRACE_PQTRANSACTIONSTATUS  TRACE_XX "%sPQtransactionStatus\n",   THEADER_slow)
172 #define TRACE_PQUNTRACE            TRACE_XX "%sPQuntrace\n",             THEADER_slow)
173 #define TRACE_PQUSER               TRACE_XX "%sPQuser\n",                THEADER_slow)
174 
175 /* end of Pg.h */
176