- (let ((out-len (deref-pointer out-len-ptr :long)))
- (cond ((= out-len $SQL_NULL_DATA)
- *null*)
- ;; obsolete?
- (convert-to-string-p
- (convert-from-foreign-string data-ptr))
- (t
- (case sql-type
- ;; SQL extended datatypes
- (#.$SQL_TINYINT (get-cast-short data-ptr))
- (#.$SQL_C_STINYINT (get-cast-short data-ptr)) ;; ?
- (#.$SQL_C_SSHORT (get-cast-short data-ptr)) ;; ?
- (#.$SQL_SMALLINT (deref-pointer data-ptr :short)) ; ??
- (#.$SQL_INTEGER (deref-pointer data-ptr :long))
- (#.$SQL_DECIMAL
- (let ((*read-base* 10))
- (read-from-string (get-cast-foreign-string data-ptr))))
- (t
- (case c-type
- (#.$SQL_C_DATE
- (funcall *time-conversion-function* (date-to-universal-time data-ptr)))
- (#.$SQL_C_TIME
- (multiple-value-bind (universal-time frac) (time-to-universal-time data-ptr)
- (funcall *time-conversion-function* universal-time frac)))
- (#.$SQL_C_TIMESTAMP
- (multiple-value-bind (universal-time frac) (timestamp-to-universal-time data-ptr)
- (funcall *time-conversion-function* universal-time frac)))
- (#.$SQL_INTEGER
- (get-cast-int data-ptr))
- (#.$SQL_C_FLOAT
- (get-cast-single-float data-ptr))
- (#.$SQL_C_DOUBLE
- (get-cast-double-float data-ptr))
- (#.$SQL_C_SLONG
- (get-cast-long data-ptr))
- #+lispworks
- (#.$SQL_C_BIT ; encountered only in Access
- (get-cast-byte data-ptr))
- (#.$SQL_C_BINARY
- (get-cast-binary data-ptr out-len *binary-format*))
- ((#.$SQL_C_SSHORT #.$SQL_C_STINYINT) ; LMH short ints
- (get-cast-short data-ptr)) ; LMH
- #+ignore
- (#.$SQL_C_CHAR
- (code-char (get-cast-short data-ptr)))
- (t
- (convert-from-foreign-string data-ptr)))))))))
+ (let* ((out-len (deref-pointer out-len-ptr #.$ODBC-LONG-TYPE))
+ (value
+ (cond ((= out-len $SQL_NULL_DATA)
+ *null*)
+ (t
+ (case sql-type
+ ;; SQL extended datatypes
+ (#.$SQL_TINYINT (get-cast-byte data-ptr))
+ (#.$SQL_C_STINYINT (get-cast-byte data-ptr)) ;; ?
+ (#.$SQL_C_SSHORT (get-cast-short data-ptr)) ;; ?
+ (#.$SQL_SMALLINT (get-cast-short data-ptr)) ;; ??
+ (#.$SQL_INTEGER (get-cast-int data-ptr))
+ (#.$SQL_BIGINT (read-from-string
+ (get-cast-foreign-string data-ptr)))
+ (#.$SQL_TINYINT (get-cast-byte data-ptr))
+ (#.$SQL_DECIMAL
+ (let ((*read-base* 10))
+ (read-from-string (get-cast-foreign-string data-ptr))))
+ (t
+ (case c-type
+ ((#.$SQL_C_DATE #.$SQL_C_TYPE_DATE)
+ (funcall *time-conversion-function* (date-to-universal-time data-ptr)))
+ ((#.$SQL_C_TIME #.$SQL_C_TYPE_TIME)
+ (multiple-value-bind (universal-time frac) (time-to-universal-time data-ptr)
+ (funcall *time-conversion-function* universal-time frac)))
+ ((#.$SQL_C_TIMESTAMP #.$SQL_C_TYPE_TIMESTAMP)
+ (multiple-value-bind (universal-time frac) (timestamp-to-universal-time data-ptr)
+ (funcall *time-conversion-function* universal-time frac)))
+ (#.$SQL_INTEGER
+ (get-cast-int data-ptr))
+ (#.$SQL_C_FLOAT
+ (get-cast-single-float data-ptr))
+ (#.$SQL_C_DOUBLE
+ (get-cast-double-float data-ptr))
+ (#.$SQL_C_SLONG
+ (get-cast-long data-ptr))
+ #+lispworks
+ (#.$SQL_C_BIT ; encountered only in Access
+ (get-cast-byte data-ptr))
+ (#.$SQL_C_BINARY
+ (get-cast-binary data-ptr out-len *binary-format*))
+ ((#.$SQL_C_SSHORT #.$SQL_C_STINYINT) ; LMH short ints
+ (get-cast-short data-ptr)) ; LMH
+ #+ignore
+ (#.$SQL_C_CHAR
+ (code-char (get-cast-short data-ptr)))
+ (t
+ (get-cast-foreign-string data-ptr)))))))))
+
+ ;; FIXME: this could be better optimized for types which use READ-FROM-STRING above
+
+ (if (and (or (eq result-type t) (eq result-type :string))
+ value
+ (not (stringp value)))
+ (write-to-string value)
+ value)))