fe-exec.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:48k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * fe-exec.c
  4.  *   functions related to sending a query down to the backend
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  *
  9.  * IDENTIFICATION
  10.  *   $Header: /usr/local/cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.81 1999/05/28 01:54:53 tgl Exp $
  11.  *
  12.  *-------------------------------------------------------------------------
  13.  */
  14. #include "libpq-fe.h"
  15. #include "libpq-int.h"
  16. #include "postgres.h"
  17. #ifdef WIN32
  18. #include "win32.h"
  19. #else
  20. #if !defined(NO_UNISTD_H)
  21. #include <unistd.h>
  22. #endif
  23. #endif
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <errno.h>
  27. #include <ctype.h>
  28. /* keep this in same order as ExecStatusType in libpq-fe.h */
  29. const char *const pgresStatus[] = {
  30. "PGRES_EMPTY_QUERY",
  31. "PGRES_COMMAND_OK",
  32. "PGRES_TUPLES_OK",
  33. "PGRES_COPY_OUT",
  34. "PGRES_COPY_IN",
  35. "PGRES_BAD_RESPONSE",
  36. "PGRES_NONFATAL_ERROR",
  37. "PGRES_FATAL_ERROR"
  38. };
  39. #define DONOTICE(conn,message) 
  40. ((*(conn)->noticeHook) ((conn)->noticeArg, (message)))
  41. static int addTuple(PGresult *res, PGresAttValue *tup);
  42. static void parseInput(PGconn *conn);
  43. static void handleSendFailure(PGconn *conn);
  44. static int getRowDescriptions(PGconn *conn);
  45. static int getAnotherTuple(PGconn *conn, int binary);
  46. static int getNotify(PGconn *conn);
  47. static int getNotice(PGconn *conn);
  48. /* ----------------
  49.  * Space management for PGresult.
  50.  *
  51.  * Formerly, libpq did a separate malloc() for each field of each tuple
  52.  * returned by a query.  This was remarkably expensive --- malloc/free
  53.  * consumed a sizable part of the application's runtime.  And there is
  54.  * no real need to keep track of the fields separately, since they will
  55.  * all be freed together when the PGresult is released.  So now, we grab
  56.  * large blocks of storage from malloc and allocate space for query data
  57.  * within these blocks, using a trivially simple allocator.  This reduces
  58.  * the number of malloc/free calls dramatically, and it also avoids
  59.  * fragmentation of the malloc storage arena.
  60.  * The PGresult structure itself is still malloc'd separately.  We could
  61.  * combine it with the first allocation block, but that would waste space
  62.  * for the common case that no extra storage is actually needed (that is,
  63.  * the SQL command did not return tuples).
  64.  * We also malloc the top-level array of tuple pointers separately, because
  65.  * we need to be able to enlarge it via realloc, and our trivial space
  66.  * allocator doesn't handle that effectively.  (Too bad the FE/BE protocol
  67.  * doesn't tell us up front how many tuples will be returned.)
  68.  * All other subsidiary storage for a PGresult is kept in PGresult_data blocks
  69.  * of size PGRESULT_DATA_BLOCKSIZE.  The overhead at the start of each block
  70.  * is just a link to the next one, if any. Free-space management info is
  71.  * kept in the owning PGresult.
  72.  * A query returning a small amount of data will thus require three malloc
  73.  * calls: one for the PGresult, one for the tuples pointer array, and one
  74.  * PGresult_data block.
  75.  * Only the most recently allocated PGresult_data block is a candidate to
  76.  * have more stuff added to it --- any extra space left over in older blocks
  77.  * is wasted.  We could be smarter and search the whole chain, but the point
  78.  * here is to be simple and fast.  Typical applications do not keep a PGresult
  79.  * around very long anyway, so some wasted space within one is not a problem.
  80.  *
  81.  * Tuning constants for the space allocator are:
  82.  * PGRESULT_DATA_BLOCKSIZE: size of a standard allocation block, in bytes
  83.  * PGRESULT_ALIGN_BOUNDARY: assumed alignment requirement for binary data
  84.  * PGRESULT_SEP_ALLOC_THRESHOLD: objects bigger than this are given separate
  85.  *  blocks, instead of being crammed into a regular allocation block.
  86.  * Requirements for correct function are:
  87.  * PGRESULT_ALIGN_BOUNDARY must be a multiple of the alignment requirements
  88.  * of all machine data types. (Currently this is set from configure
  89.  * tests, so it should be OK automatically.)
  90.  * PGRESULT_SEP_ALLOC_THRESHOLD + PGRESULT_BLOCK_OVERHEAD <=
  91.  * PGRESULT_DATA_BLOCKSIZE
  92.  * pqResultAlloc assumes an object smaller than the threshold will fit
  93.  * in a new block.
  94.  * The amount of space wasted at the end of a block could be as much as
  95.  * PGRESULT_SEP_ALLOC_THRESHOLD, so it doesn't pay to make that too large.
  96.  * ----------------
  97.  */
  98. #ifdef MAX
  99. #undef MAX
  100. #endif
  101. #define MAX(a,b)  ((a) > (b) ? (a) : (b))
  102. #define PGRESULT_DATA_BLOCKSIZE 2048
  103. #define PGRESULT_ALIGN_BOUNDARY MAXIMUM_ALIGNOF /* from configure */
  104. #define PGRESULT_BLOCK_OVERHEAD MAX(sizeof(PGresult_data), PGRESULT_ALIGN_BOUNDARY)
  105. #define PGRESULT_SEP_ALLOC_THRESHOLD (PGRESULT_DATA_BLOCKSIZE / 2)
  106. /*
  107.  * PQmakeEmptyPGresult
  108.  *  returns a newly allocated, initialized PGresult with given status.
  109.  *  If conn is not NULL and status indicates an error, the conn's
  110.  *  errorMessage is copied.
  111.  *
  112.  * Note this is exported --- you wouldn't think an application would need
  113.  * to build its own PGresults, but this has proven useful in both libpgtcl
  114.  * and the Perl5 interface, so maybe it's not so unreasonable.
  115.  */
  116. PGresult   *
  117. PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
  118. {
  119. PGresult   *result;
  120. result = (PGresult *) malloc(sizeof(PGresult));
  121. result->conn = conn; /* might be NULL */
  122. result->ntups = 0;
  123. result->numAttributes = 0;
  124. result->attDescs = NULL;
  125. result->tuples = NULL;
  126. result->tupArrSize = 0;
  127. result->resultStatus = status;
  128. result->cmdStatus[0] = '';
  129. result->binary = 0;
  130. result->errMsg = NULL;
  131. result->null_field[0] = '';
  132. result->curBlock = NULL;
  133. result->curOffset = 0;
  134. result->spaceLeft = 0;
  135. if (conn) /* consider copying conn's errorMessage */
  136. {
  137. switch (status)
  138. {
  139. case PGRES_EMPTY_QUERY:
  140. case PGRES_COMMAND_OK:
  141. case PGRES_TUPLES_OK:
  142. case PGRES_COPY_OUT:
  143. case PGRES_COPY_IN:
  144. /* non-error cases */
  145. break;
  146. default:
  147. pqSetResultError(result, conn->errorMessage);
  148. break;
  149. }
  150. }
  151. return result;
  152. }
  153. /*
  154.  * pqResultAlloc -
  155.  * Allocate subsidiary storage for a PGresult.
  156.  *
  157.  * nBytes is the amount of space needed for the object.
  158.  * If isBinary is true, we assume that we need to align the object on
  159.  * a machine allocation boundary.
  160.  * If isBinary is false, we assume the object is a char string and can
  161.  * be allocated on any byte boundary.
  162.  */
  163. void *
  164. pqResultAlloc(PGresult *res, int nBytes, int isBinary)
  165. {
  166. char    *space;
  167. PGresult_data *block;
  168. if (!res)
  169. return NULL;
  170. if (nBytes <= 0)
  171. return res->null_field;
  172. /*
  173.  * If alignment is needed, round up the current position to an
  174.  * alignment boundary.
  175.  */
  176. if (isBinary)
  177. {
  178. int offset = res->curOffset % PGRESULT_ALIGN_BOUNDARY;
  179. if (offset)
  180. {
  181. res->curOffset += PGRESULT_ALIGN_BOUNDARY - offset;
  182. res->spaceLeft -= PGRESULT_ALIGN_BOUNDARY - offset;
  183. }
  184. }
  185. /* If there's enough space in the current block, no problem. */
  186. if (nBytes <= res->spaceLeft)
  187. {
  188. space = res->curBlock->space + res->curOffset;
  189. res->curOffset += nBytes;
  190. res->spaceLeft -= nBytes;
  191. return space;
  192. }
  193. /*
  194.  * If the requested object is very large, give it its own block; this
  195.  * avoids wasting what might be most of the current block to start a
  196.  * new block.  (We'd have to special-case requests bigger than the
  197.  * block size anyway.) The object is always given binary alignment in
  198.  * this case.
  199.  */
  200. if (nBytes >= PGRESULT_SEP_ALLOC_THRESHOLD)
  201. {
  202. block = (PGresult_data *) malloc(nBytes + PGRESULT_BLOCK_OVERHEAD);
  203. if (!block)
  204. return NULL;
  205. space = block->space + PGRESULT_BLOCK_OVERHEAD;
  206. if (res->curBlock)
  207. {
  208. /*
  209.  * Tuck special block below the active block, so that we don't
  210.  * have to waste the free space in the active block.
  211.  */
  212. block->next = res->curBlock->next;
  213. res->curBlock->next = block;
  214. }
  215. else
  216. {
  217. /* Must set up the new block as the first active block. */
  218. block->next = NULL;
  219. res->curBlock = block;
  220. res->spaceLeft = 0; /* be sure it's marked full */
  221. }
  222. return space;
  223. }
  224. /* Otherwise, start a new block. */
  225. block = (PGresult_data *) malloc(PGRESULT_DATA_BLOCKSIZE);
  226. if (!block)
  227. return NULL;
  228. block->next = res->curBlock;
  229. res->curBlock = block;
  230. if (isBinary)
  231. {
  232. /* object needs full alignment */
  233. res->curOffset = PGRESULT_BLOCK_OVERHEAD;
  234. res->spaceLeft = PGRESULT_DATA_BLOCKSIZE - PGRESULT_BLOCK_OVERHEAD;
  235. }
  236. else
  237. {
  238. /* we can cram it right after the overhead pointer */
  239. res->curOffset = sizeof(PGresult_data);
  240. res->spaceLeft = PGRESULT_DATA_BLOCKSIZE - sizeof(PGresult_data);
  241. }
  242. space = block->space + res->curOffset;
  243. res->curOffset += nBytes;
  244. res->spaceLeft -= nBytes;
  245. return space;
  246. }
  247. /*
  248.  * pqResultStrdup -
  249.  * Like strdup, but the space is subsidiary PGresult space.
  250.  */
  251. char *
  252. pqResultStrdup(PGresult *res, const char *str)
  253. {
  254. char    *space = (char *) pqResultAlloc(res, strlen(str) + 1, FALSE);
  255. if (space)
  256. strcpy(space, str);
  257. return space;
  258. }
  259. /*
  260.  * pqSetResultError -
  261.  * assign a new error message to a PGresult
  262.  */
  263. void
  264. pqSetResultError(PGresult *res, const char *msg)
  265. {
  266. if (!res)
  267. return;
  268. if (msg && *msg)
  269. res->errMsg = pqResultStrdup(res, msg);
  270. else
  271. res->errMsg = NULL;
  272. }
  273. /*
  274.  * PQclear -
  275.  *   free's the memory associated with a PGresult
  276.  */
  277. void
  278. PQclear(PGresult *res)
  279. {
  280. PGresult_data *block;
  281. if (!res)
  282. return;
  283. /* Free all the subsidiary blocks */
  284. while ((block = res->curBlock) != NULL)
  285. {
  286. res->curBlock = block->next;
  287. free(block);
  288. }
  289. /* Free the top-level tuple pointer array */
  290. if (res->tuples)
  291. free(res->tuples);
  292. /* Free the PGresult structure itself */
  293. free(res);
  294. }
  295. /*
  296.  * Handy subroutine to deallocate any partially constructed async result.
  297.  */
  298. void
  299. pqClearAsyncResult(PGconn *conn)
  300. {
  301. if (conn->result)
  302. PQclear(conn->result);
  303. conn->result = NULL;
  304. conn->curTuple = NULL;
  305. }
  306. /*
  307.  * addTuple
  308.  *   add a row pointer to the PGresult structure, growing it if necessary
  309.  *   Returns TRUE if OK, FALSE if not enough memory to add the row
  310.  */
  311. static int
  312. addTuple(PGresult *res, PGresAttValue *tup)
  313. {
  314. if (res->ntups >= res->tupArrSize)
  315. {
  316. /*
  317.  * Try to grow the array.
  318.  *
  319.  * We can use realloc because shallow copying of the structure is
  320.  * okay.  Note that the first time through, res->tuples is NULL.
  321.  * While ANSI says that realloc() should act like malloc() in that
  322.  * case, some old C libraries (like SunOS 4.1.x) coredump instead.
  323.  * On failure realloc is supposed to return NULL without damaging
  324.  * the existing allocation. Note that the positions beyond
  325.  * res->ntups are garbage, not necessarily NULL.
  326.  */
  327. int newSize = (res->tupArrSize > 0) ? res->tupArrSize * 2 : 128;
  328. PGresAttValue **newTuples;
  329. if (res->tuples == NULL)
  330. newTuples = (PGresAttValue **)
  331. malloc(newSize * sizeof(PGresAttValue *));
  332. else
  333. newTuples = (PGresAttValue **)
  334. realloc(res->tuples, newSize * sizeof(PGresAttValue *));
  335. if (!newTuples)
  336. return FALSE; /* malloc or realloc failed */
  337. res->tupArrSize = newSize;
  338. res->tuples = newTuples;
  339. }
  340. res->tuples[res->ntups] = tup;
  341. res->ntups++;
  342. return TRUE;
  343. }
  344. /*
  345.  * PQsendQuery
  346.  *  Submit a query, but don't wait for it to finish
  347.  *
  348.  * Returns: 1 if successfully submitted
  349.  * 0 if error (conn->errorMessage is set)
  350.  */
  351. int
  352. PQsendQuery(PGconn *conn, const char *query)
  353. {
  354. if (!conn)
  355. return 0;
  356. if (!query)
  357. {
  358. sprintf(conn->errorMessage, "PQsendQuery() -- query pointer is null.");
  359. return 0;
  360. }
  361. /* check to see if the query string is too long */
  362. if (strlen(query) > MAX_MESSAGE_LEN - 2)
  363. {
  364. sprintf(conn->errorMessage, "PQsendQuery() -- query is too long.  "
  365. "Maximum length is %dn", MAX_MESSAGE_LEN - 2);
  366. return 0;
  367. }
  368. /* Don't try to send if we know there's no live connection. */
  369. if (conn->status != CONNECTION_OK)
  370. {
  371. sprintf(conn->errorMessage, "PQsendQuery() -- There is no connection "
  372. "to the backend.n");
  373. return 0;
  374. }
  375. /* Can't send while already busy, either. */
  376. if (conn->asyncStatus != PGASYNC_IDLE)
  377. {
  378. sprintf(conn->errorMessage,
  379. "PQsendQuery() -- another query already in progress.");
  380. return 0;
  381. }
  382. /* clear the error string */
  383. conn->errorMessage[0] = '';
  384. /* initialize async result-accumulation state */
  385. conn->result = NULL;
  386. conn->curTuple = NULL;
  387. /* send the query to the backend; */
  388. /* the frontend-backend protocol uses 'Q' to designate queries */
  389. if (pqPutnchar("Q", 1, conn) ||
  390. pqPuts(query, conn) ||
  391. pqFlush(conn))
  392. {
  393. handleSendFailure(conn);
  394. return 0;
  395. }
  396. /* OK, it's launched! */
  397. conn->asyncStatus = PGASYNC_BUSY;
  398. return 1;
  399. }
  400. /*
  401.  * handleSendFailure: try to clean up after failure to send command.
  402.  *
  403.  * Primarily, what we want to accomplish here is to process an async
  404.  * NOTICE message that the backend might have sent just before it died.
  405.  *
  406.  * NOTE: this routine should only be called in PGASYNC_IDLE state.
  407.  */
  408. static void
  409. handleSendFailure(PGconn *conn)
  410. {
  411. /* Preserve the error message emitted by the failing output routine */
  412. char * svErrMsg = strdup(conn->errorMessage);
  413. /*
  414.  * Accept any available input data, ignoring errors.  Note that if
  415.  * pqReadData decides the backend has closed the channel, it will
  416.  * close our side of the socket --- that's just what we want here.
  417.  */
  418. while (pqReadData(conn) > 0)
  419. /* loop until no more data readable */ ;
  420. /*
  421.  * Parse any available input messages.  Since we are in PGASYNC_IDLE
  422.  * state, only NOTICE and NOTIFY messages will be eaten.
  423.  */
  424. parseInput(conn);
  425. /* Restore error message generated by output routine, if any. */
  426. if (*svErrMsg != '')
  427. strcpy(conn->errorMessage, svErrMsg);
  428. free(svErrMsg);
  429. }
  430. /*
  431.  * Consume any available input from the backend
  432.  * 0 return: some kind of trouble
  433.  * 1 return: no problem
  434.  */
  435. int
  436. PQconsumeInput(PGconn *conn)
  437. {
  438. if (!conn)
  439. return 0;
  440. /*
  441.  * Load more data, if available. We do this no matter what state we
  442.  * are in, since we are probably getting called because the
  443.  * application wants to get rid of a read-select condition. Note that
  444.  * we will NOT block waiting for more input.
  445.  */
  446. if (pqReadData(conn) < 0)
  447. return 0;
  448. /* Parsing of the data waits till later. */
  449. return 1;
  450. }
  451. /*
  452.  * parseInput: if appropriate, parse input data from backend
  453.  * until input is exhausted or a stopping state is reached.
  454.  * Note that this function will NOT attempt to read more data from the backend.
  455.  */
  456. static void
  457. parseInput(PGconn *conn)
  458. {
  459. char id;
  460. /*
  461.  * Loop to parse successive complete messages available in the buffer.
  462.  */
  463. for (;;)
  464. {
  465. /*
  466.  * Quit if in COPY_OUT state: we expect raw data from the server
  467.  * until PQendcopy is called.  Don't try to parse it according to
  468.  * the normal protocol.  (This is bogus.  The data lines ought to
  469.  * be part of the protocol and have identifying leading
  470.  * characters.)
  471.  */
  472. if (conn->asyncStatus == PGASYNC_COPY_OUT)
  473. return;
  474. /*
  475.  * OK to try to read a message type code.
  476.  */
  477. conn->inCursor = conn->inStart;
  478. if (pqGetc(&id, conn))
  479. return;
  480. /*
  481.  * NOTIFY and NOTICE messages can happen in any state besides COPY
  482.  * OUT; always process them right away.
  483.  */
  484. if (id == 'A')
  485. {
  486. if (getNotify(conn))
  487. return;
  488. }
  489. else if (id == 'N')
  490. {
  491. if (getNotice(conn))
  492. return;
  493. }
  494. else
  495. {
  496. /*
  497.  * Other messages should only be processed while in BUSY
  498.  * state. (In particular, in READY state we hold off further
  499.  * parsing until the application collects the current
  500.  * PGresult.) If the state is IDLE then we got trouble.
  501.  */
  502. if (conn->asyncStatus != PGASYNC_BUSY)
  503. {
  504. if (conn->asyncStatus == PGASYNC_IDLE)
  505. {
  506. sprintf(conn->errorMessage,
  507.   "Backend message type 0x%02x arrived while idlen",
  508. id);
  509. DONOTICE(conn, conn->errorMessage);
  510. /* Discard the unexpected message; good idea?? */
  511. conn->inStart = conn->inEnd;
  512. }
  513. return;
  514. }
  515. switch (id)
  516. {
  517. case 'C': /* command complete */
  518. if (conn->result == NULL)
  519. conn->result = PQmakeEmptyPGresult(conn,
  520.    PGRES_COMMAND_OK);
  521. if (pqGets(conn->result->cmdStatus, CMDSTATUS_LEN, conn))
  522. return;
  523. conn->asyncStatus = PGASYNC_READY;
  524. break;
  525. case 'E': /* error return */
  526. if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, conn))
  527. return;
  528. /* delete any partially constructed result */
  529. pqClearAsyncResult(conn);
  530. /* and build an error result holding the error message */
  531. conn->result = PQmakeEmptyPGresult(conn,
  532.    PGRES_FATAL_ERROR);
  533. conn->asyncStatus = PGASYNC_READY;
  534. break;
  535. case 'Z': /* backend is ready for new query */
  536. conn->asyncStatus = PGASYNC_IDLE;
  537. break;
  538. case 'I': /* empty query */
  539. /* read and throw away the closing '' */
  540. if (pqGetc(&id, conn))
  541. return;
  542. if (id != '')
  543. {
  544. sprintf(conn->errorMessage,
  545.   "unexpected character %c following 'I'n", id);
  546. DONOTICE(conn, conn->errorMessage);
  547. }
  548. if (conn->result == NULL)
  549. conn->result = PQmakeEmptyPGresult(conn,
  550.   PGRES_EMPTY_QUERY);
  551. conn->asyncStatus = PGASYNC_READY;
  552. break;
  553. case 'K': /* secret key data from the backend */
  554. /*
  555.  * This is expected only during backend startup, but
  556.  * it's just as easy to handle it as part of the main
  557.  * loop.  Save the data and continue processing.
  558.  */
  559. if (pqGetInt(&(conn->be_pid), 4, conn))
  560. return;
  561. if (pqGetInt(&(conn->be_key), 4, conn))
  562. return;
  563. break;
  564. case 'P': /* synchronous (normal) portal */
  565. if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, conn))
  566. return;
  567. /* We pretty much ignore this message type... */
  568. break;
  569. case 'T': /* row descriptions (start of query
  570.  * results) */
  571. if (conn->result == NULL)
  572. {
  573. /* First 'T' in a query sequence */
  574. if (getRowDescriptions(conn))
  575. return;
  576. }
  577. else
  578. {
  579. /*
  580.  * A new 'T' message is treated as the start of
  581.  * another PGresult.  (It is not clear that this
  582.  * is really possible with the current backend.)
  583.  * We stop parsing until the application accepts
  584.  * the current result.
  585.  */
  586. conn->asyncStatus = PGASYNC_READY;
  587. return;
  588. }
  589. break;
  590. case 'D': /* ASCII data tuple */
  591. if (conn->result != NULL)
  592. {
  593. /* Read another tuple of a normal query response */
  594. if (getAnotherTuple(conn, FALSE))
  595. return;
  596. }
  597. else
  598. {
  599. sprintf(conn->errorMessage,
  600.  "Backend sent D message without prior Tn");
  601. DONOTICE(conn, conn->errorMessage);
  602. /* Discard the unexpected message; good idea?? */
  603. conn->inStart = conn->inEnd;
  604. return;
  605. }
  606. break;
  607. case 'B': /* Binary data tuple */
  608. if (conn->result != NULL)
  609. {
  610. /* Read another tuple of a normal query response */
  611. if (getAnotherTuple(conn, TRUE))
  612. return;
  613. }
  614. else
  615. {
  616. sprintf(conn->errorMessage,
  617.  "Backend sent B message without prior Tn");
  618. DONOTICE(conn, conn->errorMessage);
  619. /* Discard the unexpected message; good idea?? */
  620. conn->inStart = conn->inEnd;
  621. return;
  622. }
  623. break;
  624. case 'G': /* Start Copy In */
  625. conn->asyncStatus = PGASYNC_COPY_IN;
  626. break;
  627. case 'H': /* Start Copy Out */
  628. conn->asyncStatus = PGASYNC_COPY_OUT;
  629. break;
  630. default:
  631. sprintf(conn->errorMessage,
  632. "unknown protocol character '%c' read from backend.  "
  633. "(The protocol character is the first character the "
  634. "backend sends in response to a query it receives).n",
  635. id);
  636. /* Discard the unexpected message; good idea?? */
  637. conn->inStart = conn->inEnd;
  638. /* delete any partially constructed result */
  639. pqClearAsyncResult(conn);
  640. /* and build an error result holding the error message */
  641. conn->result = PQmakeEmptyPGresult(conn,
  642.    PGRES_FATAL_ERROR);
  643. conn->asyncStatus = PGASYNC_READY;
  644. return;
  645. } /* switch on protocol character */
  646. }
  647. /* Successfully consumed this message */
  648. conn->inStart = conn->inCursor;
  649. }
  650. }
  651. /*
  652.  * parseInput subroutine to read a 'T' (row descriptions) message.
  653.  * We build a PGresult structure containing the attribute data.
  654.  * Returns: 0 if completed message, EOF if not enough data yet.
  655.  *
  656.  * Note that if we run out of data, we have to release the partially
  657.  * constructed PGresult, and rebuild it again next time.  Fortunately,
  658.  * that shouldn't happen often, since 'T' messages usually fit in a packet.
  659.  */
  660. static int
  661. getRowDescriptions(PGconn *conn)
  662. {
  663. PGresult   *result;
  664. int nfields;
  665. int i;
  666. result = PQmakeEmptyPGresult(conn, PGRES_TUPLES_OK);
  667. /* parseInput already read the 'T' label. */
  668. /* the next two bytes are the number of fields */
  669. if (pqGetInt(&(result->numAttributes), 2, conn))
  670. {
  671. PQclear(result);
  672. return EOF;
  673. }
  674. nfields = result->numAttributes;
  675. /* allocate space for the attribute descriptors */
  676. if (nfields > 0)
  677. {
  678. result->attDescs = (PGresAttDesc *)
  679. pqResultAlloc(result, nfields * sizeof(PGresAttDesc), TRUE);
  680. MemSet((char *) result->attDescs, 0, nfields * sizeof(PGresAttDesc));
  681. }
  682. /* get type info */
  683. for (i = 0; i < nfields; i++)
  684. {
  685. char typName[MAX_MESSAGE_LEN];
  686. int typid;
  687. int typlen;
  688. int atttypmod;
  689. if (pqGets(typName, MAX_MESSAGE_LEN, conn) ||
  690. pqGetInt(&typid, 4, conn) ||
  691. pqGetInt(&typlen, 2, conn) ||
  692. pqGetInt(&atttypmod, 4, conn))
  693. {
  694. PQclear(result);
  695. return EOF;
  696. }
  697. /*
  698.  * Since pqGetInt treats 2-byte integers as unsigned, we need to
  699.  * coerce the special value "-1" to signed form.  (-1 is sent for
  700.  * variable-length fields.)  Formerly, libpq effectively did a
  701.  * sign-extension on the 2-byte value by storing it in a signed
  702.  * short. Now we only coerce the single value 65535 == -1; values
  703.  * 32768..65534 are taken as valid field lengths.
  704.  */
  705. if (typlen == 0xFFFF)
  706. typlen = -1;
  707. result->attDescs[i].name = pqResultStrdup(result, typName);
  708. result->attDescs[i].typid = typid;
  709. result->attDescs[i].typlen = typlen;
  710. result->attDescs[i].atttypmod = atttypmod;
  711. }
  712. /* Success! */
  713. conn->result = result;
  714. return 0;
  715. }
  716. /*
  717.  * parseInput subroutine to read a 'B' or 'D' (row data) message.
  718.  * We add another tuple to the existing PGresult structure.
  719.  * Returns: 0 if completed message, EOF if error or not enough data yet.
  720.  *
  721.  * Note that if we run out of data, we have to suspend and reprocess
  722.  * the message after more data is received.  We keep a partially constructed
  723.  * tuple in conn->curTuple, and avoid reallocating already-allocated storage.
  724.  */
  725. static int
  726. getAnotherTuple(PGconn *conn, int binary)
  727. {
  728. PGresult   *result = conn->result;
  729. int nfields = result->numAttributes;
  730. PGresAttValue *tup;
  731. char bitmap[MAX_FIELDS]; /* the backend sends us a bitmap
  732.  * of which attributes are null */
  733. int i;
  734. int nbytes; /* the number of bytes in bitmap  */
  735. char bmap; /* One byte of the bitmap */
  736. int bitmap_index; /* Its index */
  737. int bitcnt; /* number of bits examined in current byte */
  738. int vlen; /* length of the current field value */
  739. result->binary = binary;
  740. /* Allocate tuple space if first time for this data message */
  741. if (conn->curTuple == NULL)
  742. {
  743. conn->curTuple = (PGresAttValue *)
  744. pqResultAlloc(result, nfields * sizeof(PGresAttValue), TRUE);
  745. if (conn->curTuple == NULL)
  746. goto outOfMemory;
  747. MemSet((char *) conn->curTuple, 0, nfields * sizeof(PGresAttValue));
  748. }
  749. tup = conn->curTuple;
  750. /* Get the null-value bitmap */
  751. nbytes = (nfields + BYTELEN - 1) / BYTELEN;
  752. if (nbytes >= MAX_FIELDS)
  753. {
  754. /* Replace partially constructed result with an error result */
  755. pqClearAsyncResult(conn);
  756. sprintf(conn->errorMessage,
  757. "getAnotherTuple() -- null-values bitmap is too largen");
  758. conn->result = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
  759. conn->asyncStatus = PGASYNC_READY;
  760. /* Discard the broken message */
  761. conn->inStart = conn->inEnd;
  762. return EOF;
  763. }
  764. if (pqGetnchar(bitmap, nbytes, conn))
  765. return EOF;
  766. /* Scan the fields */
  767. bitmap_index = 0;
  768. bmap = bitmap[bitmap_index];
  769. bitcnt = 0;
  770. for (i = 0; i < nfields; i++)
  771. {
  772. if (!(bmap & 0200))
  773. {
  774. /* if the field value is absent, make it a null string */
  775. tup[i].value = result->null_field;
  776. tup[i].len = NULL_LEN;
  777. }
  778. else
  779. {
  780. /* get the value length (the first four bytes are for length) */
  781. if (pqGetInt(&vlen, 4, conn))
  782. return EOF;
  783. if (binary == 0)
  784. vlen = vlen - 4;
  785. if (vlen < 0)
  786. vlen = 0;
  787. if (tup[i].value == NULL)
  788. {
  789. tup[i].value = (char *) pqResultAlloc(result, vlen + 1, binary);
  790. if (tup[i].value == NULL)
  791. goto outOfMemory;
  792. }
  793. tup[i].len = vlen;
  794. /* read in the value */
  795. if (vlen > 0)
  796. if (pqGetnchar((char *) (tup[i].value), vlen, conn))
  797. return EOF;
  798. /* we have to terminate this ourselves */
  799. tup[i].value[vlen] = '';
  800. }
  801. /* advance the bitmap stuff */
  802. bitcnt++;
  803. if (bitcnt == BYTELEN)
  804. {
  805. bitmap_index++;
  806. bmap = bitmap[bitmap_index];
  807. bitcnt = 0;
  808. }
  809. else
  810. bmap <<= 1;
  811. }
  812. /* Success!  Store the completed tuple in the result */
  813. if (!addTuple(result, tup))
  814. goto outOfMemory;
  815. /* and reset for a new message */
  816. conn->curTuple = NULL;
  817. return 0;
  818. outOfMemory:
  819. /* Replace partially constructed result with an error result */
  820. pqClearAsyncResult(conn);
  821. sprintf(conn->errorMessage,
  822. "getAnotherTuple() -- out of memory for resultn");
  823. conn->result = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
  824. conn->asyncStatus = PGASYNC_READY;
  825. /* Discard the failed message --- good idea? */
  826. conn->inStart = conn->inEnd;
  827. return EOF;
  828. }
  829. /*
  830.  * PQisBusy
  831.  *  Return TRUE if PQgetResult would block waiting for input.
  832.  */
  833. int
  834. PQisBusy(PGconn *conn)
  835. {
  836. if (!conn)
  837. return FALSE;
  838. /* Parse any available data, if our state permits. */
  839. parseInput(conn);
  840. /* PQgetResult will return immediately in all states except BUSY. */
  841. return conn->asyncStatus == PGASYNC_BUSY;
  842. }
  843. /*
  844.  * PQgetResult
  845.  *   Get the next PGresult produced by a query.
  846.  *   Returns NULL if and only if no query work remains.
  847.  */
  848. PGresult   *
  849. PQgetResult(PGconn *conn)
  850. {
  851. PGresult   *res;
  852. if (!conn)
  853. return NULL;
  854. /* Parse any available data, if our state permits. */
  855. parseInput(conn);
  856. /* If not ready to return something, block until we are. */
  857. while (conn->asyncStatus == PGASYNC_BUSY)
  858. {
  859. /* Wait for some more data, and load it. */
  860. if (pqWait(TRUE, FALSE, conn) ||
  861. pqReadData(conn) < 0)
  862. {
  863. pqClearAsyncResult(conn);
  864. conn->asyncStatus = PGASYNC_IDLE;
  865. /* conn->errorMessage has been set by pqWait or pqReadData. */
  866. return PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
  867. }
  868. /* Parse it. */
  869. parseInput(conn);
  870. }
  871. /* Return the appropriate thing. */
  872. switch (conn->asyncStatus)
  873. {
  874. case PGASYNC_IDLE:
  875. res = NULL; /* query is complete */
  876. break;
  877. case PGASYNC_READY:
  878. /*
  879.  * conn->result is the PGresult to return. If it is NULL
  880.  * (which probably shouldn't happen) we assume there is an
  881.  * appropriate error message in conn->errorMessage.
  882.  */
  883. res = conn->result;
  884. conn->result = NULL;/* handing over ownership to caller */
  885. conn->curTuple = NULL; /* just in case */
  886. if (!res)
  887. res = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
  888. else
  889. {
  890. /*
  891.  * Make sure PQerrorMessage agrees with result; it could
  892.  * be that we have done other operations that changed
  893.  * errorMessage since the result's error message was
  894.  * saved.
  895.  */
  896. strcpy(conn->errorMessage, PQresultErrorMessage(res));
  897. }
  898. /* Set the state back to BUSY, allowing parsing to proceed. */
  899. conn->asyncStatus = PGASYNC_BUSY;
  900. break;
  901. case PGASYNC_COPY_IN:
  902. res = PQmakeEmptyPGresult(conn, PGRES_COPY_IN);
  903. break;
  904. case PGASYNC_COPY_OUT:
  905. res = PQmakeEmptyPGresult(conn, PGRES_COPY_OUT);
  906. break;
  907. default:
  908. sprintf(conn->errorMessage,
  909. "PQgetResult: Unexpected asyncStatus %dn",
  910. (int) conn->asyncStatus);
  911. res = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
  912. break;
  913. }
  914. return res;
  915. }
  916. /*
  917.  * PQexec
  918.  *   send a query to the backend and package up the result in a PGresult
  919.  *
  920.  * If the query was not even sent, return NULL; conn->errorMessage is set to
  921.  * a relevant message.
  922.  * If the query was sent, a new PGresult is returned (which could indicate
  923.  * either success or failure).
  924.  * The user is responsible for freeing the PGresult via PQclear()
  925.  * when done with it.
  926.  */
  927. PGresult   *
  928. PQexec(PGconn *conn, const char *query)
  929. {
  930. PGresult   *result;
  931. PGresult   *lastResult;
  932. /*
  933.  * Silently discard any prior query result that application didn't
  934.  * eat. This is probably poor design, but it's here for backward
  935.  * compatibility.
  936.  */
  937. while ((result = PQgetResult(conn)) != NULL)
  938. {
  939. if (result->resultStatus == PGRES_COPY_IN ||
  940. result->resultStatus == PGRES_COPY_OUT)
  941. {
  942. PQclear(result);
  943. sprintf(conn->errorMessage,
  944. "PQexec: you gotta get out of a COPY state yourself.n");
  945. return NULL;
  946. }
  947. PQclear(result);
  948. }
  949. /* OK to send the message */
  950. if (!PQsendQuery(conn, query))
  951. return NULL;
  952. /*
  953.  * For backwards compatibility, return the last result if there are
  954.  * more than one.  We have to stop if we see copy in/out, however. We
  955.  * will resume parsing when application calls PQendcopy.
  956.  */
  957. lastResult = NULL;
  958. while ((result = PQgetResult(conn)) != NULL)
  959. {
  960. if (lastResult)
  961. PQclear(lastResult);
  962. lastResult = result;
  963. if (result->resultStatus == PGRES_COPY_IN ||
  964. result->resultStatus == PGRES_COPY_OUT)
  965. break;
  966. }
  967. return lastResult;
  968. }
  969. /*
  970.  * Attempt to read a Notice response message.
  971.  * This is possible in several places, so we break it out as a subroutine.
  972.  * Entry: 'N' flag character has already been consumed.
  973.  * Exit: returns 0 if successfully consumed Notice message.
  974.  *  returns EOF if not enough data.
  975.  */
  976. static int
  977. getNotice(PGconn *conn)
  978. {
  979. if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, conn))
  980. return EOF;
  981. DONOTICE(conn, conn->errorMessage);
  982. return 0;
  983. }
  984. /*
  985.  * Attempt to read a Notify response message.
  986.  * This is possible in several places, so we break it out as a subroutine.
  987.  * Entry: 'A' flag character has already been consumed.
  988.  * Exit: returns 0 if successfully consumed Notify message.
  989.  *  returns EOF if not enough data.
  990.  */
  991. static int
  992. getNotify(PGconn *conn)
  993. {
  994. PGnotify tempNotify;
  995. PGnotify   *newNotify;
  996. if (pqGetInt(&(tempNotify.be_pid), 4, conn))
  997. return EOF;
  998. if (pqGets(tempNotify.relname, NAMEDATALEN, conn))
  999. return EOF;
  1000. newNotify = (PGnotify *) malloc(sizeof(PGnotify));
  1001. memcpy(newNotify, &tempNotify, sizeof(PGnotify));
  1002. DLAddTail(conn->notifyList, DLNewElem(newNotify));
  1003. return 0;
  1004. }
  1005. /*
  1006.  * PQnotifies
  1007.  *   returns a PGnotify* structure of the latest async notification
  1008.  * that has not yet been handled
  1009.  *
  1010.  * returns NULL, if there is currently
  1011.  * no unhandled async notification from the backend
  1012.  *
  1013.  * the CALLER is responsible for FREE'ing the structure returned
  1014.  */
  1015. PGnotify   *
  1016. PQnotifies(PGconn *conn)
  1017. {
  1018. Dlelem    *e;
  1019. PGnotify   *event;
  1020. if (!conn)
  1021. return NULL;
  1022. /* Parse any available data to see if we can extract NOTIFY messages. */
  1023. parseInput(conn);
  1024. /* RemHead returns NULL if list is empty */
  1025. e = DLRemHead(conn->notifyList);
  1026. if (!e)
  1027. return NULL;
  1028. event = (PGnotify *) DLE_VAL(e);
  1029. DLFreeElem(e);
  1030. return event;
  1031. }
  1032. /*
  1033.  * PQgetline - gets a newline-terminated string from the backend.
  1034.  *
  1035.  * Chiefly here so that applications can use "COPY <rel> to stdout"
  1036.  * and read the output string. Returns a null-terminated string in s.
  1037.  *
  1038.  * PQgetline reads up to maxlen-1 characters (like fgets(3)) but strips
  1039.  * the terminating n (like gets(3)).
  1040.  *
  1041.  * CAUTION: the caller is responsible for detecting the end-of-copy signal
  1042.  * (a line containing just ".") when using this routine.
  1043.  *
  1044.  * RETURNS:
  1045.  * EOF if it is detected or invalid arguments are given
  1046.  * 0 if EOL is reached (i.e., n has been read)
  1047.  * (this is required for backward-compatibility -- this
  1048.  *  routine used to always return EOF or 0, assuming that
  1049.  *  the line ended within maxlen bytes.)
  1050.  * 1 in other cases (i.e., the buffer was filled before n is reached)
  1051.  */
  1052. int
  1053. PQgetline(PGconn *conn, char *s, int maxlen)
  1054. {
  1055. int result = 1; /* return value if buffer overflows */
  1056. if (!s || maxlen <= 0)
  1057. return EOF;
  1058. if (!conn || conn->sock < 0)
  1059. {
  1060. *s = '';
  1061. return EOF;
  1062. }
  1063. /*
  1064.  * Since this is a purely synchronous routine, we don't bother to
  1065.  * maintain conn->inCursor; there is no need to back up.
  1066.  */
  1067. while (maxlen > 1)
  1068. {
  1069. if (conn->inStart < conn->inEnd)
  1070. {
  1071. char c = conn->inBuffer[conn->inStart++];
  1072. if (c == 'n')
  1073. {
  1074. result = 0; /* success exit */
  1075. break;
  1076. }
  1077. *s++ = c;
  1078. maxlen--;
  1079. }
  1080. else
  1081. {
  1082. /* need to load more data */
  1083. if (pqWait(TRUE, FALSE, conn) ||
  1084. pqReadData(conn) < 0)
  1085. {
  1086. result = EOF;
  1087. break;
  1088. }
  1089. }
  1090. }
  1091. *s = '';
  1092. return result;
  1093. }
  1094. /*
  1095.  * PQgetlineAsync - gets a newline-terminated string without blocking.
  1096.  *
  1097.  * This routine is for applications that want to do "COPY <rel> to stdout"
  1098.  * asynchronously, that is without blocking.  Having issued the COPY command
  1099.  * and gotten a PGRES_COPY_OUT response, the app should call PQconsumeInput
  1100.  * and this routine until the end-of-data signal is detected.  Unlike
  1101.  * PQgetline, this routine takes responsibility for detecting end-of-data.
  1102.  *
  1103.  * On each call, PQgetlineAsync will return data if a complete newline-
  1104.  * terminated data line is available in libpq's input buffer, or if the
  1105.  * incoming data line is too long to fit in the buffer offered by the caller.
  1106.  * Otherwise, no data is returned until the rest of the line arrives.
  1107.  *
  1108.  * If -1 is returned, the end-of-data signal has been recognized (and removed
  1109.  * from libpq's input buffer).  The caller *must* next call PQendcopy and
  1110.  * then return to normal processing.
  1111.  *
  1112.  * RETURNS:
  1113.  *  -1    if the end-of-copy-data marker has been recognized
  1114.  *  0    if no data is available
  1115.  *  >0    the number of bytes returned.
  1116.  * The data returned will not extend beyond a newline character.  If possible
  1117.  * a whole line will be returned at one time.  But if the buffer offered by
  1118.  * the caller is too small to hold a line sent by the backend, then a partial
  1119.  * data line will be returned. This can be detected by testing whether the
  1120.  * last returned byte is 'n' or not.
  1121.  * The returned string is *not* null-terminated.
  1122.  */
  1123. int
  1124. PQgetlineAsync(PGconn *conn, char *buffer, int bufsize)
  1125. {
  1126. int avail;
  1127. if (!conn || conn->asyncStatus != PGASYNC_COPY_OUT)
  1128. return -1; /* we are not doing a copy... */
  1129. /*
  1130.  * Move data from libpq's buffer to the caller's. We want to accept
  1131.  * data only in units of whole lines, not partial lines.  This ensures
  1132.  * that we can recognize the terminator line "\.n".  (Otherwise, if
  1133.  * it happened to cross a packet/buffer boundary, we might hand the
  1134.  * first one or two characters off to the caller, which we shouldn't.)
  1135.  */
  1136. conn->inCursor = conn->inStart;
  1137. avail = bufsize;
  1138. while (avail > 0 && conn->inCursor < conn->inEnd)
  1139. {
  1140. char c = conn->inBuffer[conn->inCursor++];
  1141. *buffer++ = c;
  1142. --avail;
  1143. if (c == 'n')
  1144. {
  1145. /* Got a complete line; mark the data removed from libpq */
  1146. conn->inStart = conn->inCursor;
  1147. /* Is it the endmarker line? */
  1148. if (bufsize - avail == 3 && buffer[-3] == '\' && buffer[-2] == '.')
  1149. return -1;
  1150. /* No, return the data line to the caller */
  1151. return bufsize - avail;
  1152. }
  1153. }
  1154. /*
  1155.  * We don't have a complete line. We'd prefer to leave it in libpq's
  1156.  * buffer until the rest arrives, but there is a special case: what if
  1157.  * the line is longer than the buffer the caller is offering us?  In
  1158.  * that case we'd better hand over a partial line, else we'd get into
  1159.  * an infinite loop. Do this in a way that ensures we can't
  1160.  * misrecognize a terminator line later: leave last 3 characters in
  1161.  * libpq buffer.
  1162.  */
  1163. if (avail == 0 && bufsize > 3)
  1164. {
  1165. conn->inStart = conn->inCursor - 3;
  1166. return bufsize - 3;
  1167. }
  1168. return 0;
  1169. }
  1170. /*
  1171.  * PQputline -- sends a string to the backend.
  1172.  * Returns 0 if OK, EOF if not.
  1173.  *
  1174.  * Chiefly here so that applications can use "COPY <rel> from stdin".
  1175.  */
  1176. int
  1177. PQputline(PGconn *conn, const char *s)
  1178. {
  1179. if (!conn || conn->sock < 0)
  1180. return EOF;
  1181. return pqPutnchar(s, strlen(s), conn);
  1182. }
  1183. /*
  1184.  * PQputnbytes -- like PQputline, but buffer need not be null-terminated.
  1185.  * Returns 0 if OK, EOF if not.
  1186.  */
  1187. int
  1188. PQputnbytes(PGconn *conn, const char *buffer, int nbytes)
  1189. {
  1190. if (!conn || conn->sock < 0)
  1191. return EOF;
  1192. return pqPutnchar(buffer, nbytes, conn);
  1193. }
  1194. /*
  1195.  * PQendcopy
  1196.  * After completing the data transfer portion of a copy in/out,
  1197.  * the application must call this routine to finish the command protocol.
  1198.  *
  1199.  * RETURNS:
  1200.  * 0 on success
  1201.  * 1 on failure
  1202.  */
  1203. int
  1204. PQendcopy(PGconn *conn)
  1205. {
  1206. PGresult   *result;
  1207. if (!conn)
  1208. return 0;
  1209. if (conn->asyncStatus != PGASYNC_COPY_IN &&
  1210. conn->asyncStatus != PGASYNC_COPY_OUT)
  1211. {
  1212. sprintf(conn->errorMessage,
  1213.  "PQendcopy() -- I don't think there's a copy in progress.");
  1214. return 1;
  1215. }
  1216. (void) pqFlush(conn); /* make sure no data is waiting to be sent */
  1217. /* Return to active duty */
  1218. conn->asyncStatus = PGASYNC_BUSY;
  1219. conn->errorMessage[0] = '';
  1220. /* Wait for the completion response */
  1221. result = PQgetResult(conn);
  1222. /* Expecting a successful result */
  1223. if (result && result->resultStatus == PGRES_COMMAND_OK)
  1224. {
  1225. PQclear(result);
  1226. return 0;
  1227. }
  1228. /*
  1229.  * Trouble. The worst case is that we've lost sync with the backend
  1230.  * entirely due to application screwup of the copy in/out protocol. To
  1231.  * recover, reset the connection (talk about using a sledgehammer...)
  1232.  */
  1233. PQclear(result);
  1234. if (conn->errorMessage[0])
  1235. DONOTICE(conn, conn->errorMessage);
  1236. DONOTICE(conn, "PQendcopy: resetting connectionn");
  1237. PQreset(conn);
  1238. return 1;
  1239. }
  1240. /* ----------------
  1241.  * PQfn - Send a function call to the POSTGRES backend.
  1242.  *
  1243.  * conn : backend connection
  1244.  * fnid : function id
  1245.  * result_buf : pointer to result buffer (&int if integer)
  1246.  * result_len : length of return value.
  1247.  * actual_result_len: actual length returned. (differs from result_len
  1248.  *   for varlena structures.)
  1249.  * result_type : If the result is an integer, this must be 1,
  1250.  *   otherwise this should be 0
  1251.  * args : pointer to an array of function arguments.
  1252.  *   (each has length, if integer, and value/pointer)
  1253.  * nargs : # of arguments in args array.
  1254.  *
  1255.  * RETURNS
  1256.  * PGresult with status = PGRES_COMMAND_OK if successful.
  1257.  * *actual_result_len is > 0 if there is a return value, 0 if not.
  1258.  * PGresult with status = PGRES_FATAL_ERROR if backend returns an error.
  1259.  * NULL on communications failure.  conn->errorMessage will be set.
  1260.  * ----------------
  1261.  */
  1262. PGresult   *
  1263. PQfn(PGconn *conn,
  1264.  int fnid,
  1265.  int *result_buf,
  1266.  int *actual_result_len,
  1267.  int result_is_int,
  1268.  PQArgBlock *args,
  1269.  int nargs)
  1270. {
  1271. bool needInput = false;
  1272. ExecStatusType status = PGRES_FATAL_ERROR;
  1273. char id;
  1274. int i;
  1275. *actual_result_len = 0;
  1276. if (!conn)
  1277. return NULL;
  1278. if (conn->sock < 0 || conn->asyncStatus != PGASYNC_IDLE)
  1279. {
  1280. sprintf(conn->errorMessage, "PQfn() -- connection in wrong staten");
  1281. return NULL;
  1282. }
  1283. /* clear the error string */
  1284. conn->errorMessage[0] = '';
  1285. if (pqPuts("F ", conn) || /* function */
  1286. pqPutInt(fnid, 4, conn) || /* function id */
  1287. pqPutInt(nargs, 4, conn)) /* # of args */
  1288. {
  1289. handleSendFailure(conn);
  1290. return NULL;
  1291. }
  1292. for (i = 0; i < nargs; ++i)
  1293. { /* len.int4 + contents    */
  1294. if (pqPutInt(args[i].len, 4, conn))
  1295. {
  1296. handleSendFailure(conn);
  1297. return NULL;
  1298. }
  1299. if (args[i].isint)
  1300. {
  1301. if (pqPutInt(args[i].u.integer, 4, conn))
  1302. {
  1303. handleSendFailure(conn);
  1304. return NULL;
  1305. }
  1306. }
  1307. else
  1308. {
  1309. if (pqPutnchar((char *) args[i].u.ptr, args[i].len, conn))
  1310. {
  1311. handleSendFailure(conn);
  1312. return NULL;
  1313. }
  1314. }
  1315. }
  1316. if (pqFlush(conn))
  1317. {
  1318. handleSendFailure(conn);
  1319. return NULL;
  1320. }
  1321. for (;;)
  1322. {
  1323. if (needInput)
  1324. {
  1325. /* Wait for some data to arrive (or for the channel to close) */
  1326. if (pqWait(TRUE, FALSE, conn) ||
  1327. pqReadData(conn) < 0)
  1328. break;
  1329. }
  1330. /*
  1331.  * Scan the message. If we run out of data, loop around to try
  1332.  * again.
  1333.  */
  1334. conn->inCursor = conn->inStart;
  1335. needInput = true;
  1336. if (pqGetc(&id, conn))
  1337. continue;
  1338. /*
  1339.  * We should see V or E response to the command, but might get N
  1340.  * and/or A notices first. We also need to swallow the final Z
  1341.  * before returning.
  1342.  */
  1343. switch (id)
  1344. {
  1345. case 'V': /* function result */
  1346. if (pqGetc(&id, conn))
  1347. continue;
  1348. if (id == 'G')
  1349. {
  1350. /* function returned nonempty value */
  1351. if (pqGetInt(actual_result_len, 4, conn))
  1352. continue;
  1353. if (result_is_int)
  1354. {
  1355. if (pqGetInt(result_buf, 4, conn))
  1356. continue;
  1357. }
  1358. else
  1359. {
  1360. if (pqGetnchar((char *) result_buf,
  1361.    *actual_result_len,
  1362.    conn))
  1363. continue;
  1364. }
  1365. if (pqGetc(&id, conn)) /* get the last '0' */
  1366. continue;
  1367. }
  1368. if (id == '0')
  1369. {
  1370. /* correctly finished function result message */
  1371. status = PGRES_COMMAND_OK;
  1372. }
  1373. else
  1374. {
  1375. /* The backend violates the protocol. */
  1376. sprintf(conn->errorMessage,
  1377. "FATAL: PQfn: protocol error: id=%xn", id);
  1378. conn->inStart = conn->inCursor;
  1379. return PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
  1380. }
  1381. break;
  1382. case 'E': /* error return */
  1383. if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, conn))
  1384. continue;
  1385. status = PGRES_FATAL_ERROR;
  1386. break;
  1387. case 'A': /* notify message */
  1388. /* handle notify and go back to processing return values */
  1389. if (getNotify(conn))
  1390. continue;
  1391. break;
  1392. case 'N': /* notice */
  1393. /* handle notice and go back to processing return values */
  1394. if (getNotice(conn))
  1395. continue;
  1396. break;
  1397. case 'Z': /* backend is ready for new query */
  1398. /* consume the message and exit */
  1399. conn->inStart = conn->inCursor;
  1400. return PQmakeEmptyPGresult(conn, status);
  1401. default:
  1402. /* The backend violates the protocol. */
  1403. sprintf(conn->errorMessage,
  1404. "FATAL: PQfn: protocol error: id=%xn", id);
  1405. conn->inStart = conn->inCursor;
  1406. return PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
  1407. }
  1408. /* Completed this message, keep going */
  1409. conn->inStart = conn->inCursor;
  1410. needInput = false;
  1411. }
  1412. /* we fall out of the loop only upon failing to read data */
  1413. return PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
  1414. }
  1415. /* ====== accessor funcs for PGresult ======== */
  1416. ExecStatusType
  1417. PQresultStatus(PGresult *res)
  1418. {
  1419. if (!res)
  1420. return PGRES_NONFATAL_ERROR;
  1421. return res->resultStatus;
  1422. }
  1423. const char *
  1424. PQresStatus(ExecStatusType status)
  1425. {
  1426. if (((int) status) < 0 ||
  1427. ((int) status) >= (sizeof(pgresStatus) / sizeof(pgresStatus[0])))
  1428. return "Invalid ExecStatusType code";
  1429. return pgresStatus[status];
  1430. }
  1431. const char *
  1432. PQresultErrorMessage(PGresult *res)
  1433. {
  1434. if (!res || !res->errMsg)
  1435. return "";
  1436. return res->errMsg;
  1437. }
  1438. int
  1439. PQntuples(PGresult *res)
  1440. {
  1441. if (!res)
  1442. return 0;
  1443. return res->ntups;
  1444. }
  1445. int
  1446. PQnfields(PGresult *res)
  1447. {
  1448. if (!res)
  1449. return 0;
  1450. return res->numAttributes;
  1451. }
  1452. int
  1453. PQbinaryTuples(PGresult *res)
  1454. {
  1455. if (!res)
  1456. return 0;
  1457. return res->binary;
  1458. }
  1459. /*
  1460.  * Helper routines to range-check field numbers and tuple numbers.
  1461.  * Return TRUE if OK, FALSE if not
  1462.  */
  1463. static int
  1464. check_field_number(const char *routineName, PGresult *res, int field_num)
  1465. {
  1466. if (!res)
  1467. return FALSE; /* no way to display error message... */
  1468. if (field_num < 0 || field_num >= res->numAttributes)
  1469. {
  1470. if (res->conn)
  1471. {
  1472. sprintf(res->conn->errorMessage,
  1473. "%s: ERROR! field number %d is out of range 0..%dn",
  1474. routineName, field_num, res->numAttributes - 1);
  1475. DONOTICE(res->conn, res->conn->errorMessage);
  1476. }
  1477. return FALSE;
  1478. }
  1479. return TRUE;
  1480. }
  1481. static int
  1482. check_tuple_field_number(const char *routineName, PGresult *res,
  1483.  int tup_num, int field_num)
  1484. {
  1485. if (!res)
  1486. return FALSE; /* no way to display error message... */
  1487. if (tup_num < 0 || tup_num >= res->ntups)
  1488. {
  1489. if (res->conn)
  1490. {
  1491. sprintf(res->conn->errorMessage,
  1492. "%s: ERROR! tuple number %d is out of range 0..%dn",
  1493. routineName, tup_num, res->ntups - 1);
  1494. DONOTICE(res->conn, res->conn->errorMessage);
  1495. }
  1496. return FALSE;
  1497. }
  1498. if (field_num < 0 || field_num >= res->numAttributes)
  1499. {
  1500. if (res->conn)
  1501. {
  1502. sprintf(res->conn->errorMessage,
  1503. "%s: ERROR! field number %d is out of range 0..%dn",
  1504. routineName, field_num, res->numAttributes - 1);
  1505. DONOTICE(res->conn, res->conn->errorMessage);
  1506. }
  1507. return FALSE;
  1508. }
  1509. return TRUE;
  1510. }
  1511. /*
  1512.    returns NULL if the field_num is invalid
  1513. */
  1514. char *
  1515. PQfname(PGresult *res, int field_num)
  1516. {
  1517. if (!check_field_number("PQfname", res, field_num))
  1518. return NULL;
  1519. if (res->attDescs)
  1520. return res->attDescs[field_num].name;
  1521. else
  1522. return NULL;
  1523. }
  1524. /*
  1525.    returns -1 on a bad field name
  1526. */
  1527. int
  1528. PQfnumber(PGresult *res, const char *field_name)
  1529. {
  1530. int i;
  1531. char    *field_case;
  1532. if (!res)
  1533. return -1;
  1534. if (field_name == NULL ||
  1535. field_name[0] == '' ||
  1536. res->attDescs == NULL)
  1537. return -1;
  1538. field_case = strdup(field_name);
  1539. if (*field_case == '"')
  1540. {
  1541. strcpy(field_case, field_case + 1);
  1542. *(field_case + strlen(field_case) - 1) = '';
  1543. }
  1544. else
  1545. for (i = 0; field_case[i]; i++)
  1546. if (isascii((unsigned char) field_case[i]) &&
  1547. isupper(field_case[i]))
  1548. field_case[i] = tolower(field_case[i]);
  1549. for (i = 0; i < res->numAttributes; i++)
  1550. {
  1551. if (strcmp(field_case, res->attDescs[i].name) == 0)
  1552. {
  1553. free(field_case);
  1554. return i;
  1555. }
  1556. }
  1557. free(field_case);
  1558. return -1;
  1559. }
  1560. Oid
  1561. PQftype(PGresult *res, int field_num)
  1562. {
  1563. if (!check_field_number("PQftype", res, field_num))
  1564. return InvalidOid;
  1565. if (res->attDescs)
  1566. return res->attDescs[field_num].typid;
  1567. else
  1568. return InvalidOid;
  1569. }
  1570. int
  1571. PQfsize(PGresult *res, int field_num)
  1572. {
  1573. if (!check_field_number("PQfsize", res, field_num))
  1574. return 0;
  1575. if (res->attDescs)
  1576. return res->attDescs[field_num].typlen;
  1577. else
  1578. return 0;
  1579. }
  1580. int
  1581. PQfmod(PGresult *res, int field_num)
  1582. {
  1583. if (!check_field_number("PQfmod", res, field_num))
  1584. return 0;
  1585. if (res->attDescs)
  1586. return res->attDescs[field_num].atttypmod;
  1587. else
  1588. return 0;
  1589. }
  1590. char *
  1591. PQcmdStatus(PGresult *res)
  1592. {
  1593. if (!res)
  1594. return NULL;
  1595. return res->cmdStatus;
  1596. }
  1597. /*
  1598.    PQoidStatus -
  1599. if the last command was an INSERT, return the oid string
  1600. if not, return ""
  1601. */
  1602. const char *
  1603. PQoidStatus(PGresult *res)
  1604. {
  1605. char    *p,
  1606.    *e,
  1607.    *scan;
  1608. int slen,
  1609. olen;
  1610. if (!res)
  1611. return "";
  1612. if (strncmp(res->cmdStatus, "INSERT ", 7) != 0)
  1613. return "";
  1614. /*----------
  1615.  * The cmdStatus string looks like
  1616.  *    INSERT oid count
  1617.  * In order to be able to return an ordinary C string without
  1618.  * damaging the result for PQcmdStatus or PQcmdTuples, we copy
  1619.  * the oid part of the string to just after the null, so that
  1620.  * cmdStatus looks like
  1621.  *    INSERT oid countoid
  1622.  *  ^ our return value points here
  1623.  * Pretty klugy eh?  This routine should've just returned an Oid value.
  1624.  *----------
  1625.  */
  1626. slen = strlen(res->cmdStatus);
  1627. p = res->cmdStatus + 7; /* where oid is now */
  1628. e = res->cmdStatus + slen + 1; /* where to put the oid string */
  1629. for (scan = p; *scan && *scan != ' ';)
  1630. scan++;
  1631. olen = scan - p;
  1632. if (slen + olen + 2 > sizeof(res->cmdStatus))
  1633. return ""; /* something very wrong if it doesn't fit */
  1634. strncpy(e, p, olen);
  1635. e[olen] = '';
  1636. return e;
  1637. }
  1638. /*
  1639.    PQcmdTuples -
  1640. if the last command was an INSERT/UPDATE/DELETE, return number
  1641. of inserted/affected tuples, if not, return ""
  1642. */
  1643. const char *
  1644. PQcmdTuples(PGresult *res)
  1645. {
  1646. if (!res)
  1647. return "";
  1648. if (strncmp(res->cmdStatus, "INSERT", 6) == 0 ||
  1649. strncmp(res->cmdStatus, "DELETE", 6) == 0 ||
  1650. strncmp(res->cmdStatus, "UPDATE", 6) == 0)
  1651. {
  1652. char    *p = res->cmdStatus + 6;
  1653. if (*p == 0)
  1654. {
  1655. if (res->conn)
  1656. {
  1657. sprintf(res->conn->errorMessage,
  1658. "PQcmdTuples (%s) -- bad input from servern",
  1659. res->cmdStatus);
  1660. DONOTICE(res->conn, res->conn->errorMessage);
  1661. }
  1662. return "";
  1663. }
  1664. p++;
  1665. if (*(res->cmdStatus) != 'I') /* UPDATE/DELETE */
  1666. return p;
  1667. while (*p != ' ' && *p)
  1668. p++; /* INSERT: skip oid */
  1669. if (*p == 0)
  1670. {
  1671. if (res->conn)
  1672. {
  1673. sprintf(res->conn->errorMessage,
  1674.  "PQcmdTuples (INSERT) -- there's no # of tuplesn");
  1675. DONOTICE(res->conn, res->conn->errorMessage);
  1676. }
  1677. return "";
  1678. }
  1679. p++;
  1680. return p;
  1681. }
  1682. return "";
  1683. }
  1684. /*
  1685.    PQgetvalue:
  1686. return the value of field 'field_num' of row 'tup_num'
  1687. If res is binary, then the value returned is NOT a null-terminated
  1688. ASCII string, but the binary representation in the server's native
  1689. format.
  1690. if res is not binary, a null-terminated ASCII string is returned.
  1691. */
  1692. char *
  1693. PQgetvalue(PGresult *res, int tup_num, int field_num)
  1694. {
  1695. if (!check_tuple_field_number("PQgetvalue", res, tup_num, field_num))
  1696. return NULL;
  1697. return res->tuples[tup_num][field_num].value;
  1698. }
  1699. /* PQgetlength:
  1700.  returns the length of a field value in bytes. If res is binary,
  1701.  i.e. a result of a binary portal, then the length returned does
  1702.  NOT include the size field of the varlena.  (The data returned
  1703.  by PQgetvalue doesn't either.)
  1704. */
  1705. int
  1706. PQgetlength(PGresult *res, int tup_num, int field_num)
  1707. {
  1708. if (!check_tuple_field_number("PQgetlength", res, tup_num, field_num))
  1709. return 0;
  1710. if (res->tuples[tup_num][field_num].len != NULL_LEN)
  1711. return res->tuples[tup_num][field_num].len;
  1712. else
  1713. return 0;
  1714. }
  1715. /* PQgetisnull:
  1716.  returns the null status of a field value.
  1717. */
  1718. int
  1719. PQgetisnull(PGresult *res, int tup_num, int field_num)
  1720. {
  1721. if (!check_tuple_field_number("PQgetisnull", res, tup_num, field_num))
  1722. return 1; /* pretend it is null */
  1723. if (res->tuples[tup_num][field_num].len == NULL_LEN)
  1724. return 1;
  1725. else
  1726. return 0;
  1727. }