Strange characters in return

6 views
Skip to first unread message

mikelb

unread,
Aug 3, 2010, 3:07:59 PM8/3/10
to SQL Anywhere Web Development
Hey all,

Now that Jim and Nathan have helped me to get the Rails interface
working with Sybase (through the rails sqlanywhere adapter), I'm doing
some playing around.

One thing that is happening is that I'm getting random hexadecimal
characters in my return from the database. The strange thing is that
they are different every time I refresh the page (without changing any
code). And this is pure vanilla code.

In my controller (welcome_controller.rb):

@test = Employee.first(:conditions=>['Id=3'])

In my view:
<pre>
<%= @test.to_yaml %>
</pre>

I'm ending up with things like \x03 \x02 \x01 \x90D \xCC etc in
the return values (always, I think, at the *end* of the return value).

In addition, some text values that are returned waffle between the
value (sometimes with hex chars and sometimes not) and between being
return as something akin to the following:

Zip: !binary |
OTgwMzLEywE=


A related note....

I DID change the .c interface. I *was* getting an error "failed to
allocate memory" when trying to pull up this record, so I tweaked line
141 in the sqlanywhere.c thus:

case A_STRING:
/*tdata = rb_str_new(value->buffer, *value->length);*/
tdata = rb_str_new2(value->buffer);

it wasn't liking the *value->length, so I used the rb_str_new2
function instead, and it seemed to at least take care of that
problem. ALTHOUGH, I'm guessing that the two problems are related! ?

Any help would be appreciated!

Many many thanks!

Mikelb

Eric Farrar

unread,
Aug 3, 2010, 3:11:28 PM8/3/10
to SQL Anywhere Web Development
What version of Ruby and Rails are you using?

- Eric

mikelb

unread,
Aug 3, 2010, 3:36:51 PM8/3/10
to SQL Anywhere Web Development
Ruby version: 1.8.7
Rails version: 2.3.8
SQLAnywhere version: (Developer edition): SQL Anywhere Version
Diagnostic Utility Version 11.0.0.126

Anything else I can provide?

Thanks,
Michael

Eric Farrar

unread,
Aug 3, 2010, 3:42:00 PM8/3/10
to SQL Anywhere Web Development
After taking a look at the source, I can see where the problem is. As
you suspected, the behavior you are seeing is related to the change
you made. In this particular case, rb_str_new2() cannot be used.

The difference between rb_str_new() and rb_str_new2() is that when
using rb_str_new() you explicitly pass in the length of the buffer,
whereas rb_str_new2 uses the strlen() function to determine the length
and then calls rb_str_new(). (You can look at the code for these
functions at http://ruby-doc.org/doxygen/1.8.4/string_8c-source.html#l00101)

The problem is that strlen() can only determine the length of the
string if the string is null-terminated. If you look in the
sqlanywhere.c code (http://github.com/sqlanywhere/sqlanywhere/blob/
master/ext/sqlanywhere.c#L153), you will see that the results from the
database come back as a a_sqlany_data_value structure that contains
three fields:

type - What data type is represented in the buffer
buffer - The raw bits of the data
length - The length of the buffer

Based on the type field, the buffer is cast into the correct Ruby
type. The problem is that the buffer is not null terminated since the
length is explicitly passed, and null-termination makes no sense for
the other data types.

What is happening when you use rb_str_new2() is that the strlen()
function is returning a distance to the next null-terminator which is
"beyond" the end of the string in memory. When this length is memory-
copied, it will contain apparently random data (whatever happened to
be in memory next to the string) at the end.

So in this case we need to us rb_str_new(). Of course, that still
leaves the problem of why you are seeing "failed to
allocate memory". Can you describe when exactly you saw that message?

Thanks,

- Eric

mikelb

unread,
Aug 3, 2010, 4:03:06 PM8/3/10
to SQL Anywhere Web Development
Yeah, that makes sense. It's kind of what I was figuring was
happening, but not having enough C background to work it out, I opted
for the simpler, albeit incorrect solution. :)

Once I got the database talking with the Rails app, I proceeded to
pull a single record:

@test = Employee.first(:conditions=>['Id=3'])

Once I put that line into my logic, I get the error. It borks as soon
as it gets to the first string field (I did some debugging in the ruby
adapter code, and everything goes fine until it tries to pull the
*value* for the FirstName field).

Thanks VERY much for your explanation and help!
Michael

On Aug 3, 1:42 pm, Eric Farrar <ianywhere.efar...@gmail.com> wrote:
> After taking a look at the source, I can see where the problem is. As
> you suspected, the behavior you are seeing is related to the change
> you made. In this particular case, rb_str_new2() cannot be used.
>
> The difference between rb_str_new() and rb_str_new2() is that when
> using rb_str_new() you explicitly pass in the length of the buffer,
> whereas rb_str_new2 uses the strlen() function to determine the length
> and then calls rb_str_new(). (You can look at the code for these
> functions athttp://ruby-doc.org/doxygen/1.8.4/string_8c-source.html#l00101)

mikelb

unread,
Aug 3, 2010, 4:29:08 PM8/3/10
to SQL Anywhere Web Development
Oh, another piece of information:

My Ruby/Rails/SQLAnywhere Setup is on an Ubuntu Linux box. The actual
database I am pulling from is on a Windows box. I _AM_ telling the
database to use the Windows-1252 encoding.

Hope that helps...
Michael

Eric Farrar

unread,
Aug 3, 2010, 4:57:51 PM8/3/10
to SQL Anywhere Web Development
The build of SQL Anywhere 11 you are using is over 2 years old, and I
think this might be related to a bug that was fixed a while back.
Could you try updating to a more recent version of SQL Anywhere 11?

You are able to download SQL Anywhere 11.0.1 Developer Edition from
here: http://marketing.ianywhere.com/forms/SQLAnywhere1101DeveloperEditionDownloadsybase

Or, if you would prefer, you update to the latest version, SQL
Anywhere 12 Developer Edition, released a few weeks ago:
http://marketing.ianywhere.com/forms/SQLAnywhere12DeveloperEditionDownload

Thanks,

mikelb

unread,
Aug 3, 2010, 5:17:49 PM8/3/10
to SQL Anywhere Web Development
OK. Here's the scoop.

On *my* box, and with the libraries that I am using, I am using the
aforementioned 11.0.0.126. However, the database I am connecting to
(remotely) is version 11.0.1.2276.

Which needs upgrading? (I'll try upgrading my libs, etc, and see if
that helps...)

Thanks,
Michael

On Aug 3, 2:57 pm, Eric Farrar <ianywhere.efar...@gmail.com> wrote:
> The build of SQL Anywhere 11 you are using is over 2 years old, and I
> think this might be related to a bug that was fixed a while back.
> Could you try updating to a more recent version of SQL Anywhere 11?
>
> You are able to download SQL Anywhere 11.0.1 Developer Edition from
> here:http://marketing.ianywhere.com/forms/SQLAnywhere1101DeveloperEditionD...
>
> Or, if you would prefer, you update to the latest version, SQL
> Anywhere 12 Developer Edition, released a few weeks ago:http://marketing.ianywhere.com/forms/SQLAnywhere12DeveloperEditionDow...
Message has been deleted

mikelb

unread,
Aug 3, 2010, 5:40:29 PM8/3/10
to SQL Anywhere Web Development
Oooh Shiny! It worked!

Thank you VERY MUCH, Sir Eric!

Michael

On Aug 3, 2:57 pm, Eric Farrar <ianywhere.efar...@gmail.com> wrote:
> The build of SQL Anywhere 11 you are using is over 2 years old, and I
> think this might be related to a bug that was fixed a while back.
> Could you try updating to a more recent version of SQL Anywhere 11?
>
> You are able to download SQL Anywhere 11.0.1 Developer Edition from
> here:http://marketing.ianywhere.com/forms/SQLAnywhere1101DeveloperEditionD...
>
> Or, if you would prefer, you update to the latest version, SQL
> Anywhere 12 Developer Edition, released a few weeks ago:http://marketing.ianywhere.com/forms/SQLAnywhere12DeveloperEditionDow...
Reply all
Reply to author
Forward
0 new messages