Re: [HACKERS] Binary cursor header changed from 20 to 16 Bytes?
| От | G. Anthony Reina |
|---|---|
| Тема | Re: [HACKERS] Binary cursor header changed from 20 to 16 Bytes? |
| Дата | |
| Msg-id | 37A5D627.47C70FAC@nsi.edu обсуждение исходный текст |
| Ответ на | Re: [HACKERS] Binary cursor header changed from 20 to 16 Bytes? (Bruce Momjian <maillist@candle.pha.pa.us>) |
| Ответы |
Re: [HACKERS] Binary cursor header changed from 20 to 16 Bytes?
|
| Список | 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_instantsFROM %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\nERRORissuing 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
В списке pgsql-hackers по дате отправления: