+15 May 2004 Marcus Pearce (m.t.pearce@city.ac.uk)
+ * sql/sql.lisp: PRINT-QUERY now calls QUERY with result-types and
+ field-names set to nil.
+ * sql/sql.lisp: PRINT-QUERY now computes column sizes correctly
+ with null attribute values.
+ * sql/operations.lisp: modify SQL concatenation operator to accept
+ unescaped || symbol.
+ * sql/syntax.lisp: modify sql reader macro function to accept
+ unescaped sql concatenation operator.
+ * tests/test-fdml.lisp: unescape sql concatenation operator.
+ * tests/test-syntax.lisp: unescape sql concatenation operator.
+ * TODO: remove items done. Add notes about SQLITE/MYSQL backends.
+ Note to add test for universal-time. Note about difference from
+ CommonSQL in transaction handling.
+
13 May 2004 Kevin Rosenberg (kevin@rosenberg.net)
* tests/test-init.lisp: Add deferred-employee-address
class
* test *db-auto-sync*
* test SELECT caching
* for-each-row macro
+* universal-time
COMMONSQL SPEC
nvl (Oracle specific)
userenv (Oracle specific)
minus (Oracle specific: does the same as EXCEPT)
- ||
o variables (e.g., table identifiers) should be instantiated at runtime
drop-index: requires a table to be specified with the :from keyword parameter
views: mysql does not support views
queries: nested subqueries are not supported
+syntax: doesn't support the sql concatenation operator (||).
SQLITE
-create-view: column-list parameter not supported
+create-view: column-list parameter not supported
+syntax: doesn't support the sql SUBSTRING operator.
(make-instance 'sql-relational-exp
:operator 'in :sub-expressions rest))
-(defsql sql-concat (:symbol "||") (&rest rest)
+;; (defsql sql-concat (:symbol "||") (&rest rest)
+;; (make-instance 'sql-relational-exp
+;; :operator '\|\| :sub-expressions rest))
+
+(defsql sql-concat (:symbol "concat") (&rest rest)
(make-instance 'sql-relational-exp
:operator '\|\| :sub-expressions rest))
computed. The output stream is given by STREAM, which has a default
value of T. This specifies that *STANDARD-OUTPUT* is used."
(flet ((compute-sizes (data)
- (mapcar #'(lambda (x) (apply #'max (mapcar #'length x)))
+ (mapcar #'(lambda (x)
+ (apply #'max (mapcar #'(lambda (y)
+ (if (null y) 3 (length y)))
+ x)))
(apply #'mapcar (cons #'list data))))
(format-record (record control sizes)
(format stream "~&~?" control
(let* ((query-exp (etypecase query-exp
(string query-exp)
(sql-query (sql-output query-exp database))))
- (data (query query-exp :database database))
+ (data (query query-exp :database database :result-types nil
+ :field-names nil))
(sizes (if (or (null sizes) (listp sizes)) sizes
(compute-sizes (if titles (cons titles data) data))))
(formats (if (or (null formats) (not (listp formats)))
(defun sql-reader-open (stream char)
(declare (ignore char))
(let ((sqllist (read-delimited-list #\] stream t)))
- (if (sql-operator (car sqllist))
- (cons (sql-operator (car sqllist)) (cdr sqllist))
- (apply #'generate-sql-reference sqllist))))
+ (cond ((string= (write-to-string (car sqllist)) "||")
+ (cons (sql-operator 'concat) (cdr sqllist)))
+ ((sql-operator (car sqllist))
+ (cons (sql-operator (car sqllist)) (cdr sqllist)))
+ (t (apply #'generate-sql-reference sqllist)))))
;; Internal function that disables the close syntax when leaving sql context.
(defun disable-sql-close-syntax ()
("Vlad" "Jose" "Leon" "Niki" "Leon" "Yuri" "Kons" "Mikh" "Bori" "Vlad"))
(deftest :fdml/select/22
- (clsql:select [\|\| [first-name] " " [last-name]] :from [employee]
+ (clsql:select [|| [first-name] " " [last-name]] :from [employee]
:flatp t :order-by [emplid] :field-names nil)
("Vladamir Lenin" "Josef Stalin" "Leon Trotsky" "Nikita Kruschev"
"Leonid Brezhnev" "Yuri Andropov" "Konstantin Chernenko" "Mikhail Gorbachev"
(deftest :syntax/concat/1
- (clsql:sql [\|\| [foo] [bar] [baz]])
+ (clsql:sql [|| [foo] [bar] [baz]])
"(FOO || BAR || BAZ)")