4
* Description: This module contains routines related to
5
* reading and storing the field information from a query.
7
* Classes: ColumnInfoClass (Functions prefix: "CI_")
11
* Comments: See "notice.txt" for copyright and license information.
16
#include "columninfo.h"
18
#include "connection.h"
22
#include "pgapifunc.h"
29
rv = (ColumnInfoClass *) malloc(sizeof(ColumnInfoClass));
37
rv->display_size = NULL;
46
CI_Destructor(ColumnInfoClass *self)
55
* Read in field descriptions.
56
* If self is not null, then also store the information.
57
* If self is null, then just read, don't store.
60
CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
66
Int4 new_atttypmod = -1;
68
/* COLUMN_NAME_STORAGE_LEN may be sufficient but for safety */
69
char new_field_name[2 * COLUMN_NAME_STORAGE_LEN + 1];
73
sock = CC_get_socket(conn);
76
/* at first read in the number of fields that are in the query */
77
new_num_fields = (Int2) SOCK_get_int(sock, sizeof(Int2));
79
mylog("num_fields = %d\n", new_num_fields);
82
/* according to that allocate memory */
83
CI_set_num_fields(self, new_num_fields);
85
/* now read in the descriptions */
86
for (lf = 0; lf < new_num_fields; lf++)
88
SOCK_get_string(sock, new_field_name, 2 * COLUMN_NAME_STORAGE_LEN);
89
new_adtid = (Oid) SOCK_get_int(sock, 4);
90
new_adtsize = (Int2) SOCK_get_int(sock, 2);
92
/* If 6.4 protocol, then read the atttypmod field */
93
if (PG_VERSION_GE(conn, 6.4))
95
mylog("READING ATTTYPMOD\n");
96
new_atttypmod = (Int4) SOCK_get_int(sock, 4);
98
/* Subtract the header length */
101
case PG_TYPE_DATETIME:
102
case PG_TYPE_TIMESTAMP_NO_TMZONE:
104
case PG_TYPE_TIME_WITH_TMZONE:
109
if (new_atttypmod < 0)
114
mylog("CI_read_fields: fieldname='%s', adtid=%d, adtsize=%d, atttypmod=%d\n", new_field_name, new_adtid, new_adtsize, new_atttypmod);
117
CI_set_field_info(self, lf, new_field_name, new_adtid, new_adtsize, new_atttypmod);
120
return (SOCK_get_errcode(sock) == 0);
125
CI_free_memory(ColumnInfoClass *self)
128
int num_fields = self->num_fields;
130
for (lf = 0; lf < num_fields; lf++)
134
free(self->name[lf]);
135
self->name[lf] = NULL;
139
/* Safe to call even if null */
140
self->num_fields = 0;
149
self->adtsize = NULL;
150
if (self->display_size)
151
free(self->display_size);
152
self->display_size = NULL;
155
free(self->atttypmod);
156
self->atttypmod = NULL;
161
CI_set_num_fields(ColumnInfoClass *self, int new_num_fields)
163
CI_free_memory(self); /* always safe to call */
165
self->num_fields = new_num_fields;
167
self->name = (char **) malloc(sizeof(char *) * self->num_fields);
168
memset(self->name, 0, sizeof(char *) * self->num_fields);
169
self->adtid = (Oid *) malloc(sizeof(Oid) * self->num_fields);
170
self->adtsize = (Int2 *) malloc(sizeof(Int2) * self->num_fields);
171
self->display_size = (Int2 *) malloc(sizeof(Int2) * self->num_fields);
172
self->atttypmod = (Int4 *) malloc(sizeof(Int4) * self->num_fields);
177
CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name,
178
Oid new_adtid, Int2 new_adtsize, Int4 new_atttypmod)
181
if ((field_num < 0) || (field_num >= self->num_fields))
185
self->name[field_num] = strdup(new_name);
186
self->adtid[field_num] = new_adtid;
187
self->adtsize[field_num] = new_adtsize;
188
self->atttypmod[field_num] = new_atttypmod;
190
self->display_size[field_num] = 0;