* PQfn - Send a function call to the POSTGRES backend. * * See fe-exec.c for documentation. */
| 2151 | * See fe-exec.c for documentation. |
| 2152 | */ |
| 2153 | PGresult * |
| 2154 | pqFunctionCall3(PGconn *conn, Oid fnid, |
| 2155 | int *result_buf, int *actual_result_len, |
| 2156 | int result_is_int, |
| 2157 | const PQArgBlock *args, int nargs) |
| 2158 | { |
| 2159 | bool needInput = false; |
| 2160 | ExecStatusType status = PGRES_FATAL_ERROR; |
| 2161 | char id; |
| 2162 | int msgLength; |
| 2163 | int avail; |
| 2164 | int i; |
| 2165 | |
| 2166 | /* already validated by PQfn */ |
| 2167 | Assert(conn->pipelineStatus == PQ_PIPELINE_OFF); |
| 2168 | |
| 2169 | /* PQfn already validated connection state */ |
| 2170 | |
| 2171 | if (pqPutMsgStart('F', conn) < 0 || /* function call msg */ |
| 2172 | pqPutInt(fnid, 4, conn) < 0 || /* function id */ |
| 2173 | pqPutInt(1, 2, conn) < 0 || /* # of format codes */ |
| 2174 | pqPutInt(1, 2, conn) < 0 || /* format code: BINARY */ |
| 2175 | pqPutInt(nargs, 2, conn) < 0) /* # of args */ |
| 2176 | { |
| 2177 | /* error message should be set up already */ |
| 2178 | return NULL; |
| 2179 | } |
| 2180 | |
| 2181 | for (i = 0; i < nargs; ++i) |
| 2182 | { /* len.int4 + contents */ |
| 2183 | if (pqPutInt(args[i].len, 4, conn)) |
| 2184 | return NULL; |
| 2185 | if (args[i].len == -1) |
| 2186 | continue; /* it's NULL */ |
| 2187 | |
| 2188 | if (args[i].isint) |
| 2189 | { |
| 2190 | if (pqPutInt(args[i].u.integer, args[i].len, conn)) |
| 2191 | return NULL; |
| 2192 | } |
| 2193 | else |
| 2194 | { |
| 2195 | if (pqPutnchar((char *) args[i].u.ptr, args[i].len, conn)) |
| 2196 | return NULL; |
| 2197 | } |
| 2198 | } |
| 2199 | |
| 2200 | if (pqPutInt(1, 2, conn) < 0) /* result format code: BINARY */ |
| 2201 | return NULL; |
| 2202 | |
| 2203 | if (pqPutMsgEnd(conn) < 0 || |
| 2204 | pqFlush(conn)) |
| 2205 | return NULL; |
| 2206 | |
| 2207 | for (;;) |
| 2208 | { |
| 2209 | if (needInput) |
| 2210 | { |
no test coverage detected