[fdo-dev] Byte order of non-geometry bind/define buffers
mateusz at loskot.net
Wed Sep 6 12:09:56 EDT 2006
Gavin Cramer wrote:
> Hi, Mateusz. I saw this, and your elaboration off-line about the "char
> * address".
> All of the RDBMS API's that we have dealt with (OCI, ODBC, etc)
> automatically convert to the local byte order.
Yes, now it's more clear for me.
> If PostgreSQL doesn't do
> this, your RDBI driver will have to apply endian conversion to the data
> at execute/fetch time as needed. You can experiment with doing this
> directly on the data buffers to get it going, but it would need
> reconsideration later to see if a separate conversion buffer is needed
> for each binary column (to avoid scrambling the caller's data). Either
> way, this is probably faster than doing conversion to text.
Yes, libpq client library always expects get and returns binary data
encoded as big-endian. It does not apply any server->client conversion.
So, I provide byte order conversion in PostGIS Rdbi driver.
> Regarding the "char * address" parameter, yes, it is just a pointer to
> the start of the bound data, be it text or binary.
I know it's a pointer to start to the bound data.
I've not known it's a pointer to text *or* binary, what I've
learned now. Thanks.
> It pre-dates ANSI C, otherwise it would have been a "void *".
> The value is simply cast to "char *" from all types.
> If there is an array of data, the parameter
> value is still just the address of the first byte of that array.
> For basic data types (char arrays, ints, doubles -- not objects, e.g.
> geometries), there is NO notion of "array of pointers", etc. If there
> is an array to handle multiple rows at once, the data is just a plain
> array of int, for example.
> Abbreviated example code:
> #define NUM_ROWS (10)
> int myInts[NUM_ROWS];
> int ret = RDBI_SUCCESS;
> rdbi_context_def *myRdbi = ...;
> char * myNullIndicators = NULL;
> ret = rdbi_alcnullind(NUM_ROWS, &myNullIndicators);
> rdbi_set_nnull(myRdbi, myNullIndicators, 0, NUM_ROWS-1);
> ret = rdbi_bind(myRdbi, mySqlid, "myColumnName", RDBI_INT,
> sizeof(myInt), (char *)myInts, myNullIndicators);
> Note that NUM_ROWS is not used in the rdbi_bind call. The number of
> rows is not actually important until rdbi_execute (for inserts/updates)
> or rdbi_fetch (for selects).
Currently, I work with one row per fetch, so I bind data for one row.
> I recommend searching the "Gdbi" package (or just the entire
> GenericRdbms solution) for actual working examples. Gdbi is the main
> consumer of Rdbi.
I've walked Gdbi/Rdbi and Dbi package quite extensively,
but analyzing internal implementation is useless without having
public API assumptions and pre-/post-conditions about data
passed by client. That's why I'm asking.
Thanks for your explanation!
More information about the Fdo-internals