2 * Description: This module contains functions related to
3 * managing result information (i.e, fetching rows
4 * from the backend, managing the tuple cache, etc.)
5 * and retrieving it. Depending on the situation, a
6 * QResultClass will hold either data from the backend
7 * or a manually built result.
10 #include "statement.h"
18 * Used for building a Manual Result only
19 * All info functions call this function to create the manual result set.
21 void QR_set_num_fields(QResultClass
* self
, int new_num_fields
)
23 BOOL allocrelatt
= FALSE
;
27 mylog("in QR_set_num_fields\n");
29 CI_set_num_fields(self
->fields
, new_num_fields
, allocrelatt
);
31 mylog("exit QR_set_num_fields\n");
35 void QR_set_position(QResultClass
* self
, SQLLEN pos
)
38 self
->backend_tuples
+
39 ((QR_get_rowstart_in_cache(self
) + pos
) * self
->num_fields
);
43 void QR_set_cache_size(QResultClass
* self
, SQLLEN cache_size
)
45 self
->cache_size
= cache_size
;
49 void QR_set_rowset_size(QResultClass
* self
, Int4 rowset_size
)
51 self
->rowset_size_include_ommitted
= rowset_size
;
54 void QR_set_cursor(QResultClass
* self
, const char *name
)
56 ConnectionClass
*conn
= QR_get_conn(self
);
58 if (self
->cursor_name
)
60 free(self
->cursor_name
);
63 CONNLOCK_ACQUIRE(conn
);
65 CONNLOCK_RELEASE(conn
);
72 self
->cursor_name
= strdup(name
);
75 CONNLOCK_ACQUIRE(conn
);
77 CONNLOCK_RELEASE(conn
);
81 self
->cursor_name
= NULL
;
82 QR_set_no_cursor(self
);
87 void QR_set_num_cached_rows(QResultClass
* self
, SQLLEN num_rows
)
89 self
->num_cached_rows
= num_rows
;
90 if (QR_synchronize_keys(self
))
91 self
->num_cached_keys
= self
->num_cached_rows
;
94 void QR_set_rowstart_in_cache(QResultClass
* self
, SQLLEN start
)
96 mylog("qrflags:%x\n", (int)self
->flags
);
97 if (QR_synchronize_keys(self
))
98 self
->key_base
= start
;
102 void QR_inc_rowstart_in_cache(QResultClass
* self
, SQLLEN base_inc
)
104 if (!QR_has_valid_base(self
))
106 ("QR_inc_rowstart_in_cache called while the cache is not ready\n");
107 self
->base
+= base_inc
;
108 if (QR_synchronize_keys(self
))
109 self
->key_base
= self
->base
;
116 QResultClass
*QR_Constructor()
120 mylog("in QR_Constructor\n");
121 rv
= (QResultClass
*) malloc(sizeof(QResultClass
));
125 rv
->rstatus
= PORES_EMPTY_QUERY
;
128 /* construct the column info */
129 if (!(rv
->fields
= CI_Constructor()))
134 rv
->backend_tuples
= NULL
;
135 rv
->sqlstate
[0] = '\0';
142 rv
->count_backend_allocated
= 0;
143 rv
->count_keyset_allocated
= 0;
144 rv
->num_total_read
= 0;
145 rv
->num_cached_rows
= 0;
146 rv
->num_cached_keys
= 0;
147 rv
->fetch_number
= 0;
149 QR_set_rowstart_in_cache(rv
, -1);
151 rv
->recent_processed_row_count
= -1;
155 rv
->num_key_fields
= PG_NUM_NORMAL_KEYS
; /* CTID + OID */
156 rv
->tupleField
= NULL
;
157 rv
->cursor_name
= NULL
;
161 rv
->rowset_size_include_ommitted
= 1;
162 rv
->move_direction
= 0;
164 rv
->reload_count
= 0;
170 rv
->added_keyset
= NULL
;
171 rv
->added_tuples
= NULL
;
175 rv
->updated_keyset
= NULL
;
176 rv
->updated_tuples
= NULL
;
180 rv
->deleted_keyset
= NULL
;
183 mylog("exit QR_Constructor\n");
188 // VX_CLEANUP: There's a decent chance this is useless
189 void QR_close_result(QResultClass
* self
, BOOL destroy
)
191 ConnectionClass
*conn
;
195 mylog("QResult: in QR_close_result\n");
198 * If conn is defined, then we may have used "backend_tuples", so in
199 * case we need to, free it up. Also, close the cursor.
201 QR_free_memory(self
); /* safe to call anyway */
203 /* Should have been freed in the close() but just in case... */
204 QR_set_cursor(self
, NULL
);
206 /* Free up column info */
207 if (destroy
&& self
->fields
)
209 CI_Destructor(self
->fields
);
213 /* Free command info (this is from strdup()) */
217 self
->command
= NULL
;
220 /* Free message info (this is from strdup()) */
224 self
->message
= NULL
;
227 /* Free notice info (this is from strdup()) */
233 /* Destruct the result object in the chain */
234 QR_Destructor(self
->next
);
237 mylog("QResult: exit close_result\n");
244 void QR_Destructor(QResultClass
* self
)
246 mylog("QResult: enter DESTRUCTOR (%p)\n", self
);
249 QR_close_result(self
, TRUE
);
251 mylog("QResult: exit DESTRUCTOR\n");
255 void QR_set_command(QResultClass
* self
, const char *msg
)
260 self
->command
= msg
? strdup(msg
) : NULL
;
264 void QR_set_message(QResultClass
* self
, const char *msg
)
269 self
->message
= msg
? strdup(msg
) : NULL
;
272 void QR_add_message(QResultClass
* self
, const char *msg
)
274 char *message
= self
->message
;
281 pos
= strlen(message
) + 1;
282 alsize
= pos
+ strlen(msg
) + 1;
286 alsize
= strlen(msg
) + 1;
288 message
= (char *)realloc(message
, alsize
);
290 message
[pos
- 1] = ';';
291 strcpy(message
+ pos
, msg
);
292 self
->message
= message
;
296 void QR_set_notice(QResultClass
* self
, const char *msg
)
301 self
->notice
= msg
? strdup(msg
) : NULL
;
304 void QR_add_notice(QResultClass
* self
, const char *msg
)
306 char *message
= self
->notice
;
313 pos
= strlen(message
) + 1;
314 alsize
= pos
+ strlen(msg
) + 1;
318 alsize
= strlen(msg
) + 1;
320 message
= (char *)realloc(message
, alsize
);
322 message
[pos
- 1] = ';';
323 strcpy(message
+ pos
, msg
);
324 self
->notice
= message
;
328 TupleField
*QR_AddNew(QResultClass
* self
)
335 inolog("QR_AddNew %dth row(%d fields) alloc=%d\n",
336 self
->num_cached_rows
, QR_NumResultCols(self
),
337 self
->count_backend_allocated
);
338 if (num_fields
= QR_NumResultCols(self
), !num_fields
)
340 if (self
->num_fields
<= 0)
342 self
->num_fields
= num_fields
;
343 QR_set_reached_eof(self
);
345 alloc
= self
->count_backend_allocated
;
346 if (!self
->backend_tuples
)
348 self
->num_cached_rows
= 0;
349 alloc
= TUPLE_MALLOC_INC
;
350 self
->backend_tuples
= (TupleField
*)
351 malloc(alloc
* sizeof(TupleField
) * num_fields
);
352 } else if (self
->num_cached_rows
>= self
->count_backend_allocated
)
354 alloc
= self
->count_backend_allocated
* 2;
355 self
->backend_tuples
= (TupleField
*)
356 realloc(self
->backend_tuples
,
357 alloc
* sizeof(TupleField
) * num_fields
);
359 self
->count_backend_allocated
= alloc
;
361 if (self
->backend_tuples
)
363 memset(self
->backend_tuples
+
364 num_fields
* self
->num_cached_rows
, 0,
365 num_fields
* sizeof(TupleField
));
366 self
->num_cached_rows
++;
369 return self
->backend_tuples
+ num_fields
* (self
->num_cached_rows
-
373 void QR_free_memory(QResultClass
* self
)
375 SQLLEN num_backend_rows
= self
->num_cached_rows
;
376 int num_fields
= self
->num_fields
;
378 mylog("QResult: free memory in, fcount=%d\n", num_backend_rows
);
380 if (self
->backend_tuples
)
382 ClearCachedRows(self
->backend_tuples
, num_fields
,
384 free(self
->backend_tuples
);
385 self
->count_backend_allocated
= 0;
386 self
->backend_tuples
= NULL
;
390 ConnectionClass
*conn
= QR_get_conn(self
);
394 self
->count_keyset_allocated
= 0;
395 // VX_CLEANUP: It might be smart to find whatever allocates this, and
397 // VX_CLEANUP: Some of the remainder here might also be useless.
398 self
->reload_count
= 0;
402 free(self
->rollback
);
405 self
->rollback
= NULL
;
410 self
->deleted
= NULL
;
412 if (self
->deleted_keyset
)
414 free(self
->deleted_keyset
);
415 self
->deleted_keyset
= NULL
;
419 /* clear added info */
420 if (self
->added_keyset
)
422 free(self
->added_keyset
);
423 self
->added_keyset
= NULL
;
425 if (self
->added_tuples
)
427 ClearCachedRows(self
->added_tuples
, num_fields
, self
->ad_count
);
428 free(self
->added_tuples
);
429 self
->added_tuples
= NULL
;
433 /* clear updated info */
437 self
->updated
= NULL
;
439 if (self
->updated_keyset
)
441 free(self
->updated_keyset
);
442 self
->updated_keyset
= NULL
;
444 if (self
->updated_tuples
)
446 ClearCachedRows(self
->updated_tuples
, num_fields
,
448 free(self
->updated_tuples
);
449 self
->updated_tuples
= NULL
;
454 self
->num_total_read
= 0;
455 self
->num_cached_rows
= 0;
456 self
->num_cached_keys
= 0;
457 self
->cursTuple
= -1;
460 mylog("QResult: free memory out\n");
464 static SQLLEN
enlargeKeyCache(QResultClass
* self
, SQLLEN add_size
,
467 size_t alloc
, alloc_req
;
468 Int4 num_fields
= self
->num_fields
;
469 BOOL curs
= (NULL
!= QR_get_cursor(self
));
472 return self
->count_keyset_allocated
;
473 alloc
= self
->count_backend_allocated
;
475 && ((alloc_req
= (Int4
) self
->num_cached_rows
+ add_size
) >
476 alloc
|| !self
->backend_tuples
))
485 TUPLE_MALLOC_INC
? alloc_req
: TUPLE_MALLOC_INC
);
492 while (alloc
< alloc_req
);
494 self
->count_backend_allocated
= 0;
495 QR_REALLOC_return_with_error(self
->backend_tuples
, TupleField
,
496 num_fields
* sizeof(TupleField
) *
497 alloc
, self
, message
, -1);
498 self
->count_backend_allocated
= alloc
;
500 alloc
= self
->count_keyset_allocated
;
501 if (QR_haskeyset(self
)
502 && ((alloc_req
= (Int4
) self
->num_cached_keys
+ add_size
) >
503 alloc
|| !self
->keyset
))
512 TUPLE_MALLOC_INC
? alloc_req
: TUPLE_MALLOC_INC
);
519 while (alloc
< alloc_req
);
521 self
->count_keyset_allocated
= 0;
522 QR_REALLOC_return_with_error(self
->keyset
, KeySet
,
523 sizeof(KeySet
) * alloc
, self
,
525 self
->count_keyset_allocated
= alloc
;