Bug in CLSQL-Oracle mapping. SOLVED

Elias MÃ¥rtenson <[email protected]> Mon, 19 Dec 2011 15:14:48 +0800
Newsgroups gmane.lisp.clsql.general
Message-ID <CADtN0WJZYSGrKdhsOvMMW2=szD6-ymGaNS_EJ2P97590mTX3Aw@mail.gmail.com>
Following up on my earlier mail:
http://lists.b9.com/pipermail/clsql/2011-December/002040.html

It turns out that the problem was caused by three independent bugs, two of
which were in UFFI and the third one being in CLSQL. I have posted
solutions to the UFFI bugs to the UFFI maintainer, and what follows here is
my summary for the third one as it affects CLSQL:

Is there a chance this fix could be included in the next release of CLSQL?

Summary as follows:

In oracle-sql.lisp in the function sql-stmt-exec, the following call
can be found:

(oci-stmt-prepare (deref-vp stmthp)
                          (deref-vp errhp)
                          c-stmt-string
                          (length sql-stmt-string)
                          +oci-ntv-syntax+ +oci-default+ :database db)

The call to LENGTH will return the length of the statement in number
of characters, but the call requires the number of bytes (which is
obviously different when UTF-8 is used).

The Oracle documentation on the subject is a bit unclear. From:
http://docs.oracle.com/cd/B10501_01/appdev.920/a96584/oci16ms6.htm

"Length of the statement in characters or in number of bytes,
        depending on the encoding. Must not be zero."

While true, the above quote is somewhat confusing. A better phrasing
would be simply "Length of the statement in characters in number of
bytes". The fact that the number of bytes and the number of characters
are the same in single-byte encodings is pretty much an implementation
detail here.

The solution is to replace the call:

(length sql-stmt-string)

With:

(%foreign-string-length c-stmt-string)

And add the following function that provides a strlen() (which counts
bytes, not characters) for UFFI:

(defun %foreign-string-length (foreign-string)
  (loop
     for size from 0
     until (zerop (uffi:deref-array foreign-string '(:array :unsigned-char)
size))
     finally (return size)))

_______________________________________________
CLSQL mailing list
[email protected]
http://lists.b9.com/cgi-bin/mailman/listinfo/clsql