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?
(Tom Lane <tgl@sss.pgh.pa.us>)
|
Список | 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 по дате отправления:
Предыдущее
От: "G. Anthony Reina"Дата:
Сообщение: Re: [HACKERS] Binary cursor header changed from 20 to 16 Bytes?
Следующее
От: Tom LaneДата:
Сообщение: Re: [HACKERS] Binary cursor header changed from 20 to 16 Bytes?