Re: [HACKERS] Binary cursor header changed from 20 to 16 Bytes?

From: "G(dot) Anthony Reina" <reina(at)nsi(dot)edu>
To: Bruce Momjian <maillist(at)candle(dot)pha(dot)pa(dot)us>, "pgsql-hackers(at)postgreSQL(dot)org" <pgsql-hackers(at)postgreSQL(dot)org>
Subject: Re: [HACKERS] Binary cursor header changed from 20 to 16 Bytes?
Date: 1999-08-02 17:32:23
Message-ID: 37A5D627.47C70FAC@nsi.edu
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Bruce Momjian wrote:

>
> > No, it works just fine. All you have to do is to swap the endian format (Linux Intel
> > is little endian; SGI is big endian). We've been using this approach since Postgres
> > 6.3.
> >
>
> What doesn't work? Floats? Alignment problems?
>

The only thing that seems to have problems is when you select multiple variables. For
this case, you have to put all of your arrays at the end.

e.g.
sprintf(data_string, "DECLARE data_cursor BINARY CURSOR "
"FOR SELECT repetition, cycle, time_instants FROM %s_proc WHERE "
"subject= '%s' and arm = '%s' and rep = %s and cycle = %s",
task_name, subject_name[subject], arm_name[arm],
repetition_name[i], cycle_name[j]);

res = PQexec(conn, data_string);
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
printf("\n\nERROR issuing command ... %s\n", data_string);
exit_nicely(conn);
}
PQclear(res);
sprintf(data_string, "FETCH ALL IN data_cursor");
res = PQexec(conn, data_string);
if (PQresultStatus(res) != PGRES_TUPLES_OK) {
printf("\n\nERROR issuing command ... %s\n", data_string);
exit_nicely(conn);
}

/* Move binary-transferred data to desired variable float array */
memmove(bin_time, (PQgetvalue(res, 0, 2)), (number_of_bins + 1) *
sizeof(float));

PQclear(res);
switch_endians_4bytes(bin_time, number_of_bins + 1);
res = PQexec(conn, "CLOSE data_cursor");
PQclear(res);
res = PQexec(conn, "END");
PQclear(res);

So in the above case, I can get the repetition (single int value), cycle (single int
value), and time_instants (variable array of float values) out as a binary cursor. But
need to put the variable array at the end to make it work correctly. In this case, I
don't need to offset by 16 bytes to get the 2nd and 3rd column (cycles and
time_instants); I only need to do this for the 1st column (repetition).

My switch_endians_4_bytes looks like this:

void switch_endians_4bytes(int *temp_array, int size_of_array)
{
short int test_endianess_word = 0x0001;
char *test_endianess_byte = (char *) &test_endianess_word;

int i;
int temp_int;
char *temp_char, byte0, byte1, byte2, byte3;

if (test_endianess_byte[0] == BIG_ENDIAN) {

for (i = 0; i < size_of_array; i++) {

temp_int = temp_array[i];
temp_char = (char *) (&temp_int);
byte0 = *temp_char;
byte1 = *(++temp_char);
byte2 = *(++temp_char);
byte3 = *(++temp_char);
temp_char = (char *) (&temp_int);
*temp_char = byte3;
*(++temp_char) = byte2;
*(++temp_char) = byte1;
*(++temp_char) = byte0;
temp_array[i] = temp_int;
}
}
}

where BIG_ENDIAN is defined as 0. Because I test the machine at run-time for its
endianess, I can run this on both of my platforms and it will either switch or not switch
depending on the need (assuming that the server is on a little endian machine).

-Tony

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Diana Eichert 1999-08-02 17:47:01 Re: your mail
Previous Message G. Anthony Reina 1999-08-02 17:14:15 Re: [HACKERS] Binary cursor header changed from 20 to 16 Bytes?