[fdo-dev] Byte order of non-geometry bind/define buffers

Mateusz Loskot 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".

Hi Gavin,

OK

> 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.

I understand.

> 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[0]), (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).

Understood.
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!

Cheers
-- 
Mateusz Loskot
http://mateusz.loskot.net




More information about the Fdo-internals mailing list