6 messages in com.mysql.lists.clusterRe: ndb api: setValue and char/varchar| From | Sent On | Attachments |
|---|---|---|
| Ross McFarland | 08 Oct 2006 12:33 | |
| Gustaf Thorslund | 09 Oct 2006 00:02 | |
| Jim Dowling | 09 Oct 2006 14:28 | |
| Ross McFarland | 09 Oct 2006 20:37 | |
| Stewart Smith | 12 Oct 2006 07:09 | |
| Ross McFarland | 12 Oct 2006 08:11 |
| Subject: | Re: ndb api: setValue and char/varchar![]() |
|---|---|
| From: | Gustaf Thorslund (gus...@kagge.com) |
| Date: | 10/09/2006 12:02:14 AM |
| List: | com.mysql.lists.cluster |
Hi,
I have had similar problems with decimal types. To solve this I have been implementing a field converter to convert from double to the type stored in the DB. I have not finished this code yet, but I would be happy to share it if there is any interest. If you google on my name you can find my original problem. I think it would be possible to implement conversion of strings also, and since I need that to I will try.
/Gustaf
Ross McFarland wrote:
in the process of trying to get a generic setValue working for my perl bindings i've run in to problems with setValue and varchar columns.
in perl you do something like: ... my $op = $tx->getNdbOperation ($table); $op->insertTuple == 0; $op->equal ('col1', $_); $op->setValue ('col2', "$_ foo"); ...
the problem is the string can be going in to a char, small varcahr, or medium varchar column and on the client side i'm not seeing a way to tell which it is so that i can pack it accordingly (char string as is, small varchar 1st byte len, medium varchar 1st 2 bytes len)
btw: i would suggest documenting the varchar packing stuff in the setValue doxygen stuff. i didn't see anything about it when i looked before and had to open up the ndb source to figure out why i was getting errors with invalid size specified.
the binding code looks something like the following. value is a SV * (perl's scalar type,) THIS is the NdbOperation, and RETVAL is the integer return value.
CODE: if (value != NULL && SvOK (value)) { /* call the setValue that matches value's type as closely as possible */ switch (SvTYPE (value)) { case SVt_IV: case SVt_PVIV: RETVAL = THIS->setValue (attrName, (Int32)SvIV (value)); break; case SVt_NV: case SVt_PVNV: RETVAL = THIS->setValue (attrName, (double)SvNV (value)); break; case SVt_PV: /* this works for char columns, but not varchar. i have come up * with code to work for small or medium varchar columns, but i have no * way to determine which of the 3 should be used. */ RETVAL = THIS->setValue (attrName, (const char*)SvPV_nolen (value)); break; /* FIXME rm: int setValue(const char* anAttrName, Uint32 aValue); int setValue(const char* anAttrName, Int64 aValue); int setValue(const char* anAttrName, Uint64 aValue); blobs ??? */ } } else { /* if value is null then we'll set the col to NULL */ RETVAL = THIS->setValue (attrName, (char*)NULL); } OUTPUT: RETVAL CLEANUP: if (RETVAL) croak_ndb_error (THIS->getNdbError());
so the problem is in the SVt_PV section. i have no way to tell the type of the target column so that i can pack it correctly. i've looked around at the NdbOperation object and haven't found a way to get the information via introspection.
in the opposite direction, getValue, everything works perfectly b/c i can use NdbRecAttr::getType to decide which conversion function to call and what type of perl object to turn it in to.
thinking about it without all the details i'm not sure why you have to specify the length differently when it's a varchar as either way it's null terminated, but i've only dug through that code in the process of trying to figure out a solution not why it's that way.
as it stands it seems like the code you write has to have knowledge of the schema which isn't going to be the case when writing a library/module like this.
hopefully i'm missing something, if so please point me in the right direction...
-- -rm
-- MySQL Cluster Mailing List For list archives: http://lists.mysql.com/cluster To unsubscribe: http://lists.mysql.com/cluster?unsub=gus...@kagge.com




