Header And Logo

PostgreSQL
| The world's most advanced open source database.

dest.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * dest.c
00004  *    support for communication destinations
00005  *
00006  *
00007  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00008  * Portions Copyright (c) 1994, Regents of the University of California
00009  *
00010  * IDENTIFICATION
00011  *    src/backend/tcop/dest.c
00012  *
00013  *-------------------------------------------------------------------------
00014  */
00015 /*
00016  *   INTERFACE ROUTINES
00017  *      BeginCommand - initialize the destination at start of command
00018  *      CreateDestReceiver - create tuple receiver object for destination
00019  *      EndCommand - clean up the destination at end of command
00020  *      NullCommand - tell dest that an empty query string was recognized
00021  *      ReadyForQuery - tell dest that we are ready for a new query
00022  *
00023  *   NOTES
00024  *      These routines do the appropriate work before and after
00025  *      tuples are returned by a query to keep the backend and the
00026  *      "destination" portals synchronized.
00027  */
00028 
00029 #include "postgres.h"
00030 
00031 #include "access/printtup.h"
00032 #include "access/xact.h"
00033 #include "commands/copy.h"
00034 #include "commands/createas.h"
00035 #include "commands/matview.h"
00036 #include "executor/functions.h"
00037 #include "executor/tstoreReceiver.h"
00038 #include "libpq/libpq.h"
00039 #include "libpq/pqformat.h"
00040 #include "utils/portal.h"
00041 
00042 
00043 /* ----------------
00044  *      dummy DestReceiver functions
00045  * ----------------
00046  */
00047 static void
00048 donothingReceive(TupleTableSlot *slot, DestReceiver *self)
00049 {
00050 }
00051 
00052 static void
00053 donothingStartup(DestReceiver *self, int operation, TupleDesc typeinfo)
00054 {
00055 }
00056 
00057 static void
00058 donothingCleanup(DestReceiver *self)
00059 {
00060     /* this is used for both shutdown and destroy methods */
00061 }
00062 
00063 /* ----------------
00064  *      static DestReceiver structs for dest types needing no local state
00065  * ----------------
00066  */
00067 static DestReceiver donothingDR = {
00068     donothingReceive, donothingStartup, donothingCleanup, donothingCleanup,
00069     DestNone
00070 };
00071 
00072 static DestReceiver debugtupDR = {
00073     debugtup, debugStartup, donothingCleanup, donothingCleanup,
00074     DestDebug
00075 };
00076 
00077 static DestReceiver spi_printtupDR = {
00078     spi_printtup, spi_dest_startup, donothingCleanup, donothingCleanup,
00079     DestSPI
00080 };
00081 
00082 /* Globally available receiver for DestNone */
00083 DestReceiver *None_Receiver = &donothingDR;
00084 
00085 
00086 /* ----------------
00087  *      BeginCommand - initialize the destination at start of command
00088  * ----------------
00089  */
00090 void
00091 BeginCommand(const char *commandTag, CommandDest dest)
00092 {
00093     /* Nothing to do at present */
00094 }
00095 
00096 /* ----------------
00097  *      CreateDestReceiver - return appropriate receiver function set for dest
00098  * ----------------
00099  */
00100 DestReceiver *
00101 CreateDestReceiver(CommandDest dest)
00102 {
00103     switch (dest)
00104     {
00105         case DestRemote:
00106         case DestRemoteExecute:
00107             return printtup_create_DR(dest);
00108 
00109         case DestNone:
00110             return &donothingDR;
00111 
00112         case DestDebug:
00113             return &debugtupDR;
00114 
00115         case DestSPI:
00116             return &spi_printtupDR;
00117 
00118         case DestTuplestore:
00119             return CreateTuplestoreDestReceiver();
00120 
00121         case DestIntoRel:
00122             return CreateIntoRelDestReceiver(NULL);
00123 
00124         case DestCopyOut:
00125             return CreateCopyDestReceiver();
00126 
00127         case DestSQLFunction:
00128             return CreateSQLFunctionDestReceiver();
00129 
00130         case DestTransientRel:
00131             return CreateTransientRelDestReceiver(InvalidOid);
00132     }
00133 
00134     /* should never get here */
00135     return &donothingDR;
00136 }
00137 
00138 /* ----------------
00139  *      EndCommand - clean up the destination at end of command
00140  * ----------------
00141  */
00142 void
00143 EndCommand(const char *commandTag, CommandDest dest)
00144 {
00145     switch (dest)
00146     {
00147         case DestRemote:
00148         case DestRemoteExecute:
00149 
00150             /*
00151              * We assume the commandTag is plain ASCII and therefore requires
00152              * no encoding conversion.
00153              */
00154             pq_putmessage('C', commandTag, strlen(commandTag) + 1);
00155             break;
00156 
00157         case DestNone:
00158         case DestDebug:
00159         case DestSPI:
00160         case DestTuplestore:
00161         case DestIntoRel:
00162         case DestCopyOut:
00163         case DestSQLFunction:
00164         case DestTransientRel:
00165             break;
00166     }
00167 }
00168 
00169 /* ----------------
00170  *      NullCommand - tell dest that an empty query string was recognized
00171  *
00172  *      In FE/BE protocol version 1.0, this hack is necessary to support
00173  *      libpq's crufty way of determining whether a multiple-command
00174  *      query string is done.  In protocol 2.0 it's probably not really
00175  *      necessary to distinguish empty queries anymore, but we still do it
00176  *      for backwards compatibility with 1.0.  In protocol 3.0 it has some
00177  *      use again, since it ensures that there will be a recognizable end
00178  *      to the response to an Execute message.
00179  * ----------------
00180  */
00181 void
00182 NullCommand(CommandDest dest)
00183 {
00184     switch (dest)
00185     {
00186         case DestRemote:
00187         case DestRemoteExecute:
00188 
00189             /*
00190              * tell the fe that we saw an empty query string.  In protocols
00191              * before 3.0 this has a useless empty-string message body.
00192              */
00193             if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
00194                 pq_putemptymessage('I');
00195             else
00196                 pq_putmessage('I', "", 1);
00197             break;
00198 
00199         case DestNone:
00200         case DestDebug:
00201         case DestSPI:
00202         case DestTuplestore:
00203         case DestIntoRel:
00204         case DestCopyOut:
00205         case DestSQLFunction:
00206         case DestTransientRel:
00207             break;
00208     }
00209 }
00210 
00211 /* ----------------
00212  *      ReadyForQuery - tell dest that we are ready for a new query
00213  *
00214  *      The ReadyForQuery message is sent in protocol versions 2.0 and up
00215  *      so that the FE can tell when we are done processing a query string.
00216  *      In versions 3.0 and up, it also carries a transaction state indicator.
00217  *
00218  *      Note that by flushing the stdio buffer here, we can avoid doing it
00219  *      most other places and thus reduce the number of separate packets sent.
00220  * ----------------
00221  */
00222 void
00223 ReadyForQuery(CommandDest dest)
00224 {
00225     switch (dest)
00226     {
00227         case DestRemote:
00228         case DestRemoteExecute:
00229             if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
00230             {
00231                 StringInfoData buf;
00232 
00233                 pq_beginmessage(&buf, 'Z');
00234                 pq_sendbyte(&buf, TransactionBlockStatusCode());
00235                 pq_endmessage(&buf);
00236             }
00237             else if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
00238                 pq_putemptymessage('Z');
00239             /* Flush output at end of cycle in any case. */
00240             pq_flush();
00241             break;
00242 
00243         case DestNone:
00244         case DestDebug:
00245         case DestSPI:
00246         case DestTuplestore:
00247         case DestIntoRel:
00248         case DestCopyOut:
00249         case DestSQLFunction:
00250         case DestTransientRel:
00251             break;
00252     }
00253 }