+
+(defmethod database-output-sql ((str string) database)
+ (declare (optimize (speed 3) (safety 1)
+ #+cmu (extensions:inhibit-warnings 3)))
+ (let ((len (length str)))
+ (declare (type fixnum len))
+ (cond ((zerop len)
+ +empty-string+)
+ ((and (null (position #\' str))
+ (null (position #\\ str)))
+ (concatenate 'string "'" str "'"))
+ (t
+ (let ((buf (make-string (+ (* len 2) 2) :initial-element #\')))
+ (declare (simple-string buf))
+ (do* ((i 0 (incf i))
+ (j 1 (incf j)))
+ ((= i len) (subseq buf 0 (1+ j)))
+ (declare (type fixnum i j))
+ (let ((char (aref str i)))
+ (declare (character char))
+ (cond ((char= char #\')
+ (setf (aref buf j) #\')
+ (incf j)
+ (setf (aref buf j) #\'))
+ ((and (char= char #\\)
+ ;; MTP: only escape backslash with pgsql/mysql
+ (member (database-underlying-type database)
+ '(:postgresql :mysql)
+ :test #'eq))
+ (setf (aref buf j) #\\)
+ (incf j)
+ (setf (aref buf j) #\\))
+ (t
+ (setf (aref buf j) char))))))))))
+
+(let ((keyword-package (symbol-package :foo)))
+ (defmethod database-output-sql ((sym symbol) database)
+ (if (null sym)
+ +null-string+
+ (if (equal (symbol-package sym) keyword-package)
+ (concatenate 'string "'" (string sym) "'")
+ (symbol-name sym)))))
+
+(defmethod database-output-sql ((tee (eql t)) database)
+ (if database
+ (let ((val (database-output-sql-as-type 'boolean t database (database-type database))))
+ (when val
+ (typecase val
+ (string (format nil "'~A'" val))
+ (integer (format nil "~A" val)))))
+ "'Y'"))
+
+#+nil(defmethod database-output-sql ((tee (eql t)) database)
+ (declare (ignore database))
+ "'Y'")
+
+(defmethod database-output-sql ((num number) database)
+ (declare (ignore database))
+ (number-to-sql-string num))
+
+(defmethod database-output-sql ((arg list) database)
+ (if (null arg)
+ +null-string+
+ (format nil "(~{~A~^,~})" (mapcar #'(lambda (val)
+ (sql-output val database))
+ arg))))
+
+(defmethod database-output-sql ((arg vector) database)
+ (format nil "~{~A~^,~}" (map 'list #'(lambda (val)
+ (sql-output val database))
+ arg)))
+
+(defmethod output-sql-hash-key ((arg vector) database)
+ (list 'vector (map 'list (lambda (arg)
+ (or (output-sql-hash-key arg database)
+ (return-from output-sql-hash-key nil)))
+ arg)))
+
+(defmethod database-output-sql ((self wall-time) database)
+ (declare (ignore database))
+ (db-timestring self))
+
+(defmethod database-output-sql ((self date) database)
+ (declare (ignore database))
+ (db-datestring self))
+
+(defmethod database-output-sql ((self duration) database)
+ (declare (ignore database))
+ (format nil "'~a'" (duration-timestring self)))
+
+#+ignore
+(defmethod database-output-sql ((self money) database)
+ (database-output-sql (slot-value self 'odcl::units) database))
+
+(defmethod database-output-sql (thing database)
+ (if (or (null thing)
+ (eq 'null thing))
+ +null-string+
+ (error 'sql-user-error
+ :message
+ (format nil
+ "No type conversion to SQL for ~A is defined for DB ~A."
+ (type-of thing) (type-of database)))))
+
+
+;;
+;; Column constraint types and conversion to SQL
+;;
+