Re: Bug: NO-NEXT-METHOD error on read-sql-value (SBCL)

Mariano Montone <[email protected]> Wed, 11 Mar 2015 11:59:22 -0300
Newsgroups gmane.lisp.clsql.general
Message-ID <[email protected]>
Yes, I thought the problem was very weird, as it seems to be well
implemented, I cannot figure out why SBCL would complain. Signals a
run-time error NO-NEXT-METHOD on the read-sql-value :around method, as
if there were no next method to call, although it is right there, and
specialized on (T T T T), so I don't know why that happens.

My backend is posgresql, and trying to read from a  'list' datatype.

I replaced the read-sql-value implementations for the ones in an older
version (before it was implemented with :around), and it works.

Mariano

On 11/03/15 11:23, Russ Tyndall wrote:
> I was not yet running latest SBCL, so I upgraded.  I am not experiencing 
> any issues running latest CLSQL(v6.6.0) with latest SBCL (1.2.9).
>
> Is this a compile time error or a run time error calling 
> `read-sql-value`?  Both the :around and primary qualify no arguments so 
> it looks like it should work (as you say and as matches my running 
> code).  There is also a `defgeneric`, so I wouldn't expect the 
> definition ordering to be an issue.
>
> If its a runtime bug, perhaps it has something to do with a specific 
> data type or backend you are using.  Which type of database are you 
> connecting to (it seems only db-oracle has other methods specified) and 
> are there any unusual data types being returned?
>
> Cheers,
> Russ Tyndall
> Acceleration.net
> Developer
>
>
> On 03/10/2015 01:52 PM, Mariano Montone wrote:
>> Hi.
>>
>> When trying to use latest version from SBCL, read-sql-value signals a
>> NO-NEXT-METHOD error for the :around read-sql-value definition. It
>> should work, as I understand the code, and maybe this is a bug in SBCL,
>> but I'm posting FYI. Dosn't work on latest SBCL or older versions.
>>
>> This is the conflicting code:
>>
>>
>> 596 (defmethod read-sql-value :around
>> 597     (val type database db-type
>> 598      ;; never eval while reading values, always read base 10
>> 599      &aux *read-eval* (*read-base* #10r10))
>> 600   (declare (ignore db-type))
>> 601   (cond
>> 602     ;; null value or type
>> 603     ((or (equalp "nil" val) (eql 'null val)) nil)
>> 604
>> 605     ;; no specified type or already the right type
>> 606     ((or (null type)
>> 607          (ignore-errors (typep val type)))
>> 608      val)
>> 609
>> 610     ;; actually convert
>> 611     (t
>> 612      (let ((res (handler-bind
>> 613                     ;; all errors should be converted to
>> sql-value-conversion-error
>> 614                     ((error (lambda (c)
>> 615                               (when *debugger-hook*
>> 616                                 (invoke-debugger c))
>> 617                               (unless (typep c
>> 'sql-value-conversion-error)
>> 618                                 (error-converting-value val type
>> database)))))
>> 619                   (call-next-method))))
>> 620        ;; if we didnt get the right type after converting, we should
>> probably
>> 621        ;; error right away
>> 622        (maybe-error-converting-value
>> 623         res val type database)))))
>> 624
>> 625 (defmethod read-sql-value (val type database db-type)
>> 626   ;; errors, nulls and preconverted types are already handled in around
>> 627   (typecase type
>> 628     (symbol
>> 629      (case type
>> 630        ((string varchar) val)
>> 631        (char (string (schar val 0)))
>> 632        ((or keyword symbol)
>> 633         (read-from-string val))
>> 634        ((smallint mediumint bigint integer universal-time)
>> 635         (parse-integer val))
>> 636        ((double-float float)
>> 637         ;; ensure that whatever we got is coerced to a float of the
>> correct
>> 638         ;; type (eg: 1=>1.0d0)
>> 639         (float
>> 640          (etypecase val
>> 641            (string (let ((*read-default-float-format*
>> 642                            (ecase type
>> 643                              (float 'single-float)
>> 644                              (double-float 'double-float))))
>> 645                      (read-from-string val)))
>> 646            ;; maybe wrong type of float
>> 647            (float val))
>> 648          (if (eql type 'double-float) 1.0d0 1.0s0)))
>> 649        (number (read-from-string val))
>> 650        ((boolean generalized-boolean)
>> 651         (if (member val '(nil t))
>> 652             val
>> 653             (etypecase val
>> 654               (string
>> 655                (when (member val '("1" "t" "true" "y") :test
>> #'string-equal)
>> 656                  t))
>> 657               (number (not (zerop val))))))
>> 658        ((wall-time duration) (parse-timestring val))
>> 659        (date (parse-datestring val))
>> 660        (t (call-next-method))))
>> 661     (t (typecase val
>> 662          (string (read-from-string val))
>> 663          (t (error-converting-value val type database))))))
>>
>> Mariano
>> _______________________________________________
>> CLSQL mailing list
>> [email protected]
>> http://lists.b9.com/cgi-bin/mailman/listinfo/clsql
> _______________________________________________
> CLSQL mailing list
> [email protected]
> http://lists.b9.com/cgi-bin/mailman/listinfo/clsql