changeset 1168:69f1d39d3f2d

Use COALESCE to hide NULL results of aggregate functions; fix bug with improper ordering of query result columns
author Adam Chlipala <adamc@hcoop.net>
date Thu, 25 Feb 2010 14:55:35 -0500
parents 5eca51fcd559
children 420e38516dc2
files src/cjr_print.sml src/monoize.sml
diffstat 2 files changed, 18 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/cjr_print.sml	Sat Feb 13 13:10:05 2010 -0500
+++ b/src/cjr_print.sml	Thu Feb 25 14:55:35 2010 -0500
@@ -1657,8 +1657,8 @@
                                                 map (fn (x', t) => ("__uwf_" ^ ident x ^ ".__uwf_" ^ ident x', t)) xts)
                                             tables
 
-            val outputs = exps @ tables
-            val outputs = ListMergeSort.sort (fn ((s1, _), (s2, _)) => String.compare (s1, s2) = GREATER) outputs
+            val sort = ListMergeSort.sort (fn ((s1, _), (s2, _)) => String.compare (s1, s2) = GREATER)
+            val outputs = sort exps @ sort tables
 
             val wontLeakStrings = notLeaky env true state
             val wontLeakAnything = notLeaky env false state
--- a/src/monoize.sml	Sat Feb 13 13:10:05 2010 -0500
+++ b/src/monoize.sml	Thu Feb 25 14:55:35 2010 -0500
@@ -2358,7 +2358,7 @@
               (L.EFfi ("Basis", "sql_count"), _),
               _), _),
              _), _),
-            _) => ((L'.EPrim (Prim.String "COUNT(*)"), loc),
+            _) => ((L'.EPrim (Prim.String "COALESCE(COUNT(*),0)"), loc),
                    fm)
 
           | L.ECApp (
@@ -2369,17 +2369,29 @@
                _), _),
               _), _),
              _), _),
-            _) =>
+            t) =>
             let
+                val default =
+                    case #1 t of
+                        L.CFfi ("Basis", s) =>
+                        (case s of
+                             "int" => "0"
+                           | "float" => "0.0"
+                           | "string" => "''"
+                           | "time" => "0"
+                           | _ => raise Fail "Illegal type of sql_aggregate [1]")
+                      | _ => raise Fail "Illegal type of sql_aggregate [2]"
+
                 val s = (L'.TFfi ("Basis", "string"), loc)
                 fun sc s = (L'.EPrim (Prim.String s), loc)
             in
                 ((L'.EAbs ("c", s, (L'.TFun (s, (L'.TFun (s, s), loc)), loc),
                            (L'.EAbs ("e1", s, (L'.TFun (s, s), loc),
-                                     strcat [(L'.ERel 1, loc),
+                                     strcat [sc "COALESCE(",
+                                             (L'.ERel 1, loc),
                                              sc "(",
                                              (L'.ERel 0, loc),
-                                             sc ")"]), loc)), loc),
+                                             sc (")," ^ default ^ ")")]), loc)), loc),
                  fm)
             end