improve sub-query parenthesization and add more tests

master
Moritz Heidkamp 13 years ago
parent 69915c5082
commit cc9ea436a5

@ -16,6 +16,8 @@
(and (not (eq? y (car lst)))
(loop (cdr lst))))))
(define sub-query? (make-parameter #f))
(define-syntax define-operators
(ir-macro-transformer
(lambda (x i c)
@ -26,7 +28,7 @@
(let ((ssql-op (first op))
(type (second op)))
(unless (memq (i type) '(infix infix* suffix prefix function))
(unless (memq (i type) '(infix infix* suffix prefix suffix* prefix* function))
(error "unknown operator syntax type" type))
(let-optionals (cddr op)
@ -60,7 +62,7 @@
(sprintf "(~A)"
(string-intersperse
(map (lambda (s)
(self 'ssql->sql s #t))
(self 'ssql->sql s))
list)
", ")))
@ -120,12 +122,13 @@
(symbol->string table))
((insert into rest)
(parameterize ((sub-query? #t))
(sprintf "INSERT INTO ~A ~A"
into
(string-intersperse
(map (lambda (s)
(self 'ssql->sql s))
rest))))
rest)))))
((insert (('into table) ('columns columns ...) rest ...))
(self 'insert
@ -159,17 +162,20 @@
(string-append " " operator " ")))
((function)
(parameterize ((sub-query? #t))
(sprintf "~A(~A)"
operator
(string-intersperse
(map (lambda (operand)
(self 'ssql->sql operand))
operands)
(or separator ", "))))
(or separator ", ")))))
((suffix prefix)
(let ((operator (if (eq? type 'prefix)
(let* ((operator (if (eq? type 'prefix)
(string-append operator " ")
(string-append " " operator))))
(parameterize ((sub-query? #t))
(string-join
(list
(string-intersperse
@ -178,20 +184,26 @@
operands)
(or separator " ")))
operator
type)))
type))))
((suffix* prefix*)
(let ((sql (self 'operator->sql
(if (eq? 'suffix* type) 'suffix 'prefix)
operator
separator
operands)))
(if (sub-query?)
(sprintf "(~A)" sql)
sql)))
(else (error "unknown operator syntax type" type))))
((ssql->sql ssql parenthesize?)
((ssql->sql ssql)
(let ((handler (alist-ref (list ssql) (self 'type->sql-converters) apply)))
(if handler
(if (and parenthesize? (pair? ssql))
(sprintf "(~A)" (self handler ssql))
(self handler ssql))
(self handler ssql)
(error "unknown datatype" ssql))))
((ssql->sql ssql)
(self 'ssql->sql ssql #f))
((insert-clause clause ssql)
(let ((order (self 'clauses-order)))
(let loop ((ssql ssql))
@ -204,9 +216,9 @@
(append target-clause (cdr clause)))))
(define-operators *ansi-translator*
(select prefix)
(update prefix)
(delete prefix)
(select prefix*)
(update prefix*)
(delete prefix*)
(from prefix "FROM" ", ")
(where prefix)
(order prefix "ORDER BY" ", ")

@ -33,8 +33,11 @@
(ssql->sql #f '(update (table actors) (set (firstname "Rube") (lastname "Goldberg")))))
(test "with condition"
"UPDATE actors SET firstname = 'Felix' WHERE (lastname = 'Winkelmann')"
(ssql->sql #f '(update (table actors) (set (firstname "Felix")) (where (= lastname "Winkelmann"))))))
"UPDATE actors SET firstname = 'Felix', experience = (SELECT COUNT(*) FROM roles WHERE (actor_id = actors.id)) WHERE (lastname = 'Winkelmann')"
(ssql->sql #f '(update (table actors)
(set (firstname "Felix")
(experience (select (count *) (from roles) (where (= actor_id actors.id)))))
(where (= lastname "Winkelmann"))))))
(test-group "inserts"
(test "with sub-queries"
@ -63,9 +66,9 @@
(test-group "syntax"
(test "set literals"
"SELECT one, two FROM (1, 2)"
(ssql->sql #f '(select (columns one two) (from #(1 2)))))
"SELECT one, two FROM (1, 2, (SELECT MAX(amount) FROM widgets))"
(ssql->sql #f '(select (columns one two) (from #(1 2 (select (max amount) (from widgets)))))))
(test "function calls"
"SELECT foo(99, (bar('baz')))"
"SELECT foo(99, bar('baz'))"
(ssql->sql #f '(select (call foo 99 (call bar "baz"))))))
Loading…
Cancel
Save