14
14
*
15
15
*
16
16
* IDENTIFICATION
17
- * $Header: /cvsroot/pgsql/src/backend/commands/portalcmds.c,v 1.14 2003/05/05 00:44:55 tgl Exp $
17
+ * $Header: /cvsroot/pgsql/src/backend/commands/portalcmds.c,v 1.15 2003/05/06 20:26:26 tgl Exp $
18
18
*
19
19
*-------------------------------------------------------------------------
20
20
*/
23
23
24
24
#include <limits.h>
25
25
26
- #include "miscadmin.h"
27
26
#include "commands/portalcmds.h"
28
27
#include "executor/executor.h"
28
+ #include "executor/tstoreReceiver.h"
29
29
#include "optimizer/planner.h"
30
30
#include "rewrite/rewriteHandler.h"
31
31
#include "tcop/pquery.h"
37
37
* Execute SQL DECLARE CURSOR command.
38
38
*/
39
39
void
40
- PerformCursorOpen (DeclareCursorStmt * stmt , CommandDest dest )
40
+ PerformCursorOpen (DeclareCursorStmt * stmt )
41
41
{
42
42
List * rewritten ;
43
43
Query * query ;
@@ -142,9 +142,10 @@ PerformCursorOpen(DeclareCursorStmt *stmt, CommandDest dest)
142
142
*/
143
143
void
144
144
PerformPortalFetch (FetchStmt * stmt ,
145
- CommandDest dest ,
145
+ DestReceiver * dest ,
146
146
char * completionTag )
147
147
{
148
+ DestReceiver * mydest = dest ;
148
149
Portal portal ;
149
150
long nprocessed ;
150
151
@@ -168,29 +169,34 @@ PerformPortalFetch(FetchStmt *stmt,
168
169
}
169
170
170
171
/*
171
- * Adjust dest if needed. MOVE wants dest = None.
172
+ * Adjust dest if needed. MOVE wants destination None.
172
173
*
173
174
* If fetching from a binary cursor and the requested destination is
174
175
* Remote, change it to RemoteInternal. Note we do NOT change if the
175
176
* destination is RemoteExecute --- so the Execute message's format
176
177
* specification wins out over the cursor's type.
177
178
*/
178
179
if (stmt -> ismove )
179
- dest = None ;
180
- else if (dest == Remote && (portal -> cursorOptions & CURSOR_OPT_BINARY ))
181
- dest = RemoteInternal ;
180
+ mydest = CreateDestReceiver (None );
181
+ else if (dest -> mydest == Remote &&
182
+ (portal -> cursorOptions & CURSOR_OPT_BINARY ))
183
+ mydest = CreateDestReceiver (RemoteInternal );
182
184
183
185
/* Do it */
184
186
nprocessed = PortalRunFetch (portal ,
185
187
stmt -> direction ,
186
188
stmt -> howMany ,
187
- dest );
189
+ mydest );
188
190
189
191
/* Return command status if wanted */
190
192
if (completionTag )
191
193
snprintf (completionTag , COMPLETION_TAG_BUFSIZE , "%s %ld" ,
192
194
stmt -> ismove ? "MOVE" : "FETCH" ,
193
195
nprocessed );
196
+
197
+ /* Clean up if we created a local destination */
198
+ if (mydest != dest )
199
+ (mydest -> destroy ) (mydest );
194
200
}
195
201
196
202
/*
@@ -243,21 +249,6 @@ PortalCleanup(Portal portal, bool isError)
243
249
AssertArg (PortalIsValid (portal ));
244
250
AssertArg (portal -> cleanup == PortalCleanup );
245
251
246
- /*
247
- * Delete tuplestore if present. (Note: portalmem.c is responsible
248
- * for removing holdContext.) We should do this even under error
249
- * conditions; since the tuplestore would have been using cross-
250
- * transaction storage, its temp files need to be explicitly deleted.
251
- */
252
- if (portal -> holdStore )
253
- {
254
- MemoryContext oldcontext ;
255
-
256
- oldcontext = MemoryContextSwitchTo (portal -> holdContext );
257
- tuplestore_end (portal -> holdStore );
258
- MemoryContextSwitchTo (oldcontext );
259
- portal -> holdStore = NULL ;
260
- }
261
252
/*
262
253
* Shut down executor, if still running. We skip this during error
263
254
* abort, since other mechanisms will take care of releasing executor
284
275
PersistHoldablePortal (Portal portal )
285
276
{
286
277
QueryDesc * queryDesc = PortalGetQueryDesc (portal );
287
- Portal saveCurrentPortal ;
288
278
MemoryContext savePortalContext ;
289
279
MemoryContext saveQueryContext ;
290
280
MemoryContext oldcxt ;
@@ -294,26 +284,22 @@ PersistHoldablePortal(Portal portal)
294
284
* inside the transaction that originally created it.
295
285
*/
296
286
Assert (portal -> createXact == GetCurrentTransactionId ());
297
- Assert (portal -> holdStore == NULL );
298
287
Assert (queryDesc != NULL );
299
288
Assert (portal -> portalReady );
300
289
Assert (!portal -> portalDone );
301
290
302
291
/*
303
- * This context is used to store the tuple set.
304
- * Caller must have created it already.
292
+ * Caller must have created the tuplestore already.
305
293
*/
306
294
Assert (portal -> holdContext != NULL );
307
- oldcxt = MemoryContextSwitchTo (portal -> holdContext );
308
-
309
- /* XXX: Should SortMem be used for this? */
310
- portal -> holdStore = tuplestore_begin_heap (true, true, SortMem );
295
+ Assert (portal -> holdStore != NULL );
311
296
312
297
/*
313
- * Before closing down the executor, we must copy the tupdesc, since
314
- * it was created in executor memory. Note we are copying it into
315
- * the holdContext.
298
+ * Before closing down the executor, we must copy the tupdesc into
299
+ * long-term memory, since it was created in executor memory.
316
300
*/
301
+ oldcxt = MemoryContextSwitchTo (portal -> holdContext );
302
+
317
303
portal -> tupDesc = CreateTupleDescCopy (portal -> tupDesc );
318
304
319
305
MemoryContextSwitchTo (oldcxt );
@@ -326,10 +312,8 @@ PersistHoldablePortal(Portal portal)
326
312
portal -> portalActive = true;
327
313
328
314
/*
329
- * Set global portal and context pointers.
315
+ * Set global portal context pointers.
330
316
*/
331
- saveCurrentPortal = CurrentPortal ;
332
- CurrentPortal = portal ;
333
317
savePortalContext = PortalContext ;
334
318
PortalContext = PortalGetHeapMemory (portal );
335
319
saveQueryContext = QueryContext ;
@@ -344,12 +328,16 @@ PersistHoldablePortal(Portal portal)
344
328
*/
345
329
ExecutorRewind (queryDesc );
346
330
347
- /* Set the destination to output to the tuplestore */
348
- queryDesc -> dest = Tuplestore ;
331
+ /* Change the destination to output to the tuplestore */
332
+ queryDesc -> dest = CreateTuplestoreDestReceiver (portal -> holdStore ,
333
+ portal -> holdContext );
349
334
350
335
/* Fetch the result set into the tuplestore */
351
336
ExecutorRun (queryDesc , ForwardScanDirection , 0L );
352
337
338
+ (* queryDesc -> dest -> destroy ) (queryDesc -> dest );
339
+ queryDesc -> dest = NULL ;
340
+
353
341
/*
354
342
* Now shut down the inner executor.
355
343
*/
@@ -359,7 +347,6 @@ PersistHoldablePortal(Portal portal)
359
347
/* Mark portal not active */
360
348
portal -> portalActive = false;
361
349
362
- CurrentPortal = saveCurrentPortal ;
363
350
PortalContext = savePortalContext ;
364
351
QueryContext = saveQueryContext ;
365
352
0 commit comments