Mercurial > urweb
comparison src/monoize.sml @ 1394:d328983dc5a6
Allow subqueries to reference aggregate-only columns of free tables; treat non-COUNT aggregate functions as possibly returning NULL
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Sat, 15 Jan 2011 14:53:13 -0500 |
parents | 4e5ca2a77a4d |
children | fe470db7feea |
comparison
equal
deleted
inserted
replaced
1393:802c179dac1f | 1394:d328983dc5a6 |
---|---|
234 (L'.TFfi ("Basis", "string"), loc) | 234 (L'.TFfi ("Basis", "string"), loc) |
235 | L.CApp ((L.CFfi ("Basis", "sql_view"), _), _) => | 235 | L.CApp ((L.CFfi ("Basis", "sql_view"), _), _) => |
236 (L'.TFfi ("Basis", "string"), loc) | 236 (L'.TFfi ("Basis", "string"), loc) |
237 | L.CFfi ("Basis", "sql_sequence") => | 237 | L.CFfi ("Basis", "sql_sequence") => |
238 (L'.TFfi ("Basis", "string"), loc) | 238 (L'.TFfi ("Basis", "string"), loc) |
239 | L.CApp ((L.CApp ((L.CApp ((L.CFfi ("Basis", "sql_query"), _), _), _), _), _), _) => | 239 | L.CApp ((L.CApp ((L.CApp ((L.CApp ((L.CFfi ("Basis", "sql_query"), _), _), _), _), _), _), _), _) => |
240 (L'.TFfi ("Basis", "string"), loc) | 240 (L'.TFfi ("Basis", "string"), loc) |
241 | L.CApp ((L.CApp ((L.CApp ((L.CApp ((L.CFfi ("Basis", "sql_query1"), _), _), _), _), _), _), _), _) => | 241 | L.CApp ((L.CApp ((L.CApp ((L.CApp ((L.CApp ((L.CFfi ("Basis", "sql_query1"), _), _), _), _), _), _), _), _), _), _) => |
242 (L'.TFfi ("Basis", "string"), loc) | 242 (L'.TFfi ("Basis", "string"), loc) |
243 | L.CApp ((L.CApp ((L.CFfi ("Basis", "sql_from_items"), _), _), _), _) => | 243 | L.CApp ((L.CApp ((L.CFfi ("Basis", "sql_from_items"), _), _), _), _) => |
244 (L'.TFfi ("Basis", "string"), loc) | 244 (L'.TFfi ("Basis", "string"), loc) |
245 | L.CApp ((L.CApp ((L.CApp ((L.CApp ((L.CFfi ("Basis", "sql_exp"), _), _), _), _), _), _), _), _) => | 245 | L.CApp ((L.CApp ((L.CApp ((L.CApp ((L.CFfi ("Basis", "sql_exp"), _), _), _), _), _), _), _), _) => |
246 (L'.TFfi ("Basis", "string"), loc) | 246 (L'.TFfi ("Basis", "string"), loc) |
1906 body), loc)), loc)), loc)), loc), fm) | 1906 body), loc)), loc)), loc)), loc), fm) |
1907 end | 1907 end |
1908 end | 1908 end |
1909 | _ => poly ()) | 1909 | _ => poly ()) |
1910 | 1910 |
1911 | L.ECApp ((L.ECApp ((L.ECApp ((L.ECApp ((L.EFfi ("Basis", "sql_query"), _), _), _), _), _), _), _), _) => | 1911 | L.ECApp ((L.ECApp ((L.ECApp ((L.ECApp ((L.ECApp ((L.EFfi ("Basis", "sql_query"), _), _), _), _), _), _), _), _), _), _) => |
1912 let | 1912 let |
1913 fun sc s = (L'.EPrim (Prim.String s), loc) | 1913 fun sc s = (L'.EPrim (Prim.String s), loc) |
1914 val s = (L'.TFfi ("Basis", "string"), loc) | 1914 val s = (L'.TFfi ("Basis", "string"), loc) |
1915 fun gf s = (L'.EField ((L'.ERel 0, loc), s), loc) | 1915 fun gf s = (L'.EField ((L'.ERel 0, loc), s), loc) |
1916 in | 1916 in |
1932 (L.ECApp ( | 1932 (L.ECApp ( |
1933 (L.ECApp ( | 1933 (L.ECApp ( |
1934 (L.ECApp ( | 1934 (L.ECApp ( |
1935 (L.ECApp ( | 1935 (L.ECApp ( |
1936 (L.ECApp ( | 1936 (L.ECApp ( |
1937 (L.EFfi ("Basis", "sql_query1"), _), | 1937 (L.ECApp ( |
1938 (L.EFfi ("Basis", "sql_query1"), _), | |
1939 _), _), | |
1938 _), _), | 1940 _), _), |
1939 (L.CRecord (_, tables), _)), _), | 1941 (L.CRecord (_, tables), _)), _), |
1940 (L.CRecord (_, grouped), _)), _), | 1942 (L.CRecord (_, grouped), _)), _), |
1941 (L.CRecord (_, stables), _)), _), | 1943 (L.CRecord (_, stables), _)), _), |
1942 sexps), _), | 1944 sexps), _), |
2590 end | 2592 end |
2591 | L.ECApp ( | 2593 | L.ECApp ( |
2592 (L.ECApp ( | 2594 (L.ECApp ( |
2593 (L.ECApp ( | 2595 (L.ECApp ( |
2594 (L.ECApp ( | 2596 (L.ECApp ( |
2595 (L.EFfi ("Basis", "sql_forget_tables"), _), | 2597 (L.ECApp ( |
2598 (L.EFfi ("Basis", "sql_forget_tables"), _), | |
2599 _), _), | |
2596 _), _), | 2600 _), _), |
2597 _), _), | 2601 _), _), |
2598 _), _), | 2602 _), _), |
2599 _) => | 2603 _) => |
2600 let | 2604 let |
2623 (L.ECApp ( | 2627 (L.ECApp ( |
2624 (L.ECApp ( | 2628 (L.ECApp ( |
2625 (L.EFfi ("Basis", "sql_count"), _), | 2629 (L.EFfi ("Basis", "sql_count"), _), |
2626 _), _), | 2630 _), _), |
2627 _), _), | 2631 _), _), |
2628 _) => ((L'.EPrim (Prim.String "COALESCE(COUNT(*),0)"), loc), | 2632 _) => ((L'.EPrim (Prim.String "COUNT(*)"), loc), |
2629 fm) | 2633 fm) |
2630 | 2634 |
2631 | L.ECApp ( | 2635 | L.ECApp ( |
2632 (L.ECApp ( | 2636 (L.ECApp ( |
2633 (L.ECApp ( | 2637 (L.ECApp ( |
2638 _), _), | 2642 _), _), |
2639 _), _), | 2643 _), _), |
2640 _), _), | 2644 _), _), |
2641 t) => | 2645 t) => |
2642 let | 2646 let |
2643 val default = | |
2644 case #1 t of | |
2645 L.CFfi ("Basis", s) => | |
2646 SOME (case s of | |
2647 "int" => "0" | |
2648 | "float" => "0.0" | |
2649 | "string" => "''" | |
2650 | "time" => "0" | |
2651 | _ => raise Fail "Illegal type of sql_aggregate [1]") | |
2652 | L.CApp ((L.CFfi ("Basis", "option"), _), _) => NONE | |
2653 | _ => raise Fail "Illegal type of sql_aggregate [2]" | |
2654 | |
2655 val s = (L'.TFfi ("Basis", "string"), loc) | 2647 val s = (L'.TFfi ("Basis", "string"), loc) |
2656 fun sc s = (L'.EPrim (Prim.String s), loc) | 2648 fun sc s = (L'.EPrim (Prim.String s), loc) |
2657 | 2649 |
2658 val main = strcat [(L'.ERel 1, loc), | 2650 val main = strcat [(L'.ERel 1, loc), |
2659 sc "(", | 2651 sc "(", |
2660 (L'.ERel 0, loc), | 2652 (L'.ERel 0, loc), |
2661 sc ")"] | 2653 sc ")"] |
2662 | |
2663 val main = case default of | |
2664 NONE => main | |
2665 | SOME default => | |
2666 strcat [sc "COALESCE(", | |
2667 main, | |
2668 sc ("," ^ default ^ ")")] | |
2669 in | 2654 in |
2670 ((L'.EAbs ("c", s, (L'.TFun (s, (L'.TFun (s, s), loc)), loc), | 2655 ((L'.EAbs ("c", s, (L'.TFun (s, (L'.TFun (s, s), loc)), loc), |
2671 (L'.EAbs ("e1", s, (L'.TFun (s, s), loc), main), loc)), loc), | 2656 (L'.EAbs ("e1", s, (L'.TFun (s, s), loc), main), loc)), loc), |
2672 fm) | 2657 fm) |
2673 end | 2658 end |
2680 | L.EFfi ("Basis", "sql_summable_float") => ((L'.ERecord [], loc), fm) | 2665 | L.EFfi ("Basis", "sql_summable_float") => ((L'.ERecord [], loc), fm) |
2681 | L.ECApp ((L.EFfi ("Basis", "sql_summable_option"), _), _) => | 2666 | L.ECApp ((L.EFfi ("Basis", "sql_summable_option"), _), _) => |
2682 ((L'.EAbs ("_", (L'.TRecord [], loc), (L'.TRecord [], loc), | 2667 ((L'.EAbs ("_", (L'.TRecord [], loc), (L'.TRecord [], loc), |
2683 (L'.ERecord [], loc)), loc), | 2668 (L'.ERecord [], loc)), loc), |
2684 fm) | 2669 fm) |
2685 | L.ECApp ((L.EFfi ("Basis", "sql_avg"), _), _) => | 2670 | L.ECApp ((L.ECApp ((L.EFfi ("Basis", "sql_avg"), _), _), _), _) => |
2686 ((L'.EAbs ("_", (L'.TRecord [], loc), (L'.TFfi ("Basis", "string"), loc), | 2671 ((L'.EAbs ("_", (L'.TRecord [], loc), (L'.TFun ((L'.TRecord [], loc), (L'.TFfi ("Basis", "string"), loc)), loc), |
2687 (L'.EPrim (Prim.String "AVG"), loc)), loc), | 2672 (L'.EAbs ("_", (L'.TRecord [], loc), (L'.TFfi ("Basis", "string"), loc), |
2673 (L'.EPrim (Prim.String "AVG"), loc)), loc)), loc), | |
2688 fm) | 2674 fm) |
2689 | L.ECApp ((L.EFfi ("Basis", "sql_sum"), _), _) => | 2675 | L.ECApp ((L.ECApp ((L.EFfi ("Basis", "sql_sum"), _), _), _), _) => |
2690 ((L'.EAbs ("_", (L'.TRecord [], loc), (L'.TFfi ("Basis", "string"), loc), | 2676 ((L'.EAbs ("_", (L'.TRecord [], loc), (L'.TFun ((L'.TRecord [], loc), (L'.TFfi ("Basis", "string"), loc)), loc), |
2691 (L'.EPrim (Prim.String "SUM"), loc)), loc), | 2677 (L'.EAbs ("_", (L'.TRecord [], loc), (L'.TFfi ("Basis", "string"), loc), |
2678 (L'.EPrim (Prim.String "SUM"), loc)), loc)), loc), | |
2692 fm) | 2679 fm) |
2693 | 2680 |
2694 | L.EFfi ("Basis", "sql_arith_int") => ((L'.ERecord [], loc), fm) | 2681 | L.EFfi ("Basis", "sql_arith_int") => ((L'.ERecord [], loc), fm) |
2695 | L.EFfi ("Basis", "sql_arith_float") => ((L'.ERecord [], loc), fm) | 2682 | L.EFfi ("Basis", "sql_arith_float") => ((L'.ERecord [], loc), fm) |
2696 | 2683 |
2699 | L.EFfi ("Basis", "sql_maxable_string") => ((L'.ERecord [], loc), fm) | 2686 | L.EFfi ("Basis", "sql_maxable_string") => ((L'.ERecord [], loc), fm) |
2700 | L.ECApp ((L.EFfi ("Basis", "sql_maxable_option"), _), _) => | 2687 | L.ECApp ((L.EFfi ("Basis", "sql_maxable_option"), _), _) => |
2701 ((L'.EAbs ("_", (L'.TRecord [], loc), (L'.TRecord [], loc), | 2688 ((L'.EAbs ("_", (L'.TRecord [], loc), (L'.TRecord [], loc), |
2702 (L'.ERecord [], loc)), loc), | 2689 (L'.ERecord [], loc)), loc), |
2703 fm) | 2690 fm) |
2704 | L.ECApp ((L.EFfi ("Basis", "sql_max"), _), _) => | 2691 | L.ECApp ((L.ECApp ((L.EFfi ("Basis", "sql_max"), _), _), _), _) => |
2705 ((L'.EAbs ("_", (L'.TRecord [], loc), (L'.TFfi ("Basis", "string"), loc), | 2692 ((L'.EAbs ("_", (L'.TRecord [], loc), (L'.TFun ((L'.TRecord [], loc), (L'.TFfi ("Basis", "string"), loc)), loc), |
2706 (L'.EPrim (Prim.String "MAX"), loc)), loc), | 2693 (L'.EAbs ("_", (L'.TRecord [], loc), (L'.TFfi ("Basis", "string"), loc), |
2694 (L'.EPrim (Prim.String "MAX"), loc)), loc)), loc), | |
2707 fm) | 2695 fm) |
2708 | L.ECApp ((L.EFfi ("Basis", "sql_min"), _), _) => | 2696 | L.ECApp ((L.ECApp ((L.EFfi ("Basis", "sql_min"), _), _), _), _) => |
2709 ((L'.EAbs ("_", (L'.TRecord [], loc), (L'.TFfi ("Basis", "string"), loc), | 2697 ((L'.EAbs ("_", (L'.TRecord [], loc), (L'.TFun ((L'.TRecord [], loc), (L'.TFfi ("Basis", "string"), loc)), loc), |
2710 (L'.EPrim (Prim.String "MIN"), loc)), loc), | 2698 (L'.EAbs ("_", (L'.TRecord [], loc), (L'.TFfi ("Basis", "string"), loc), |
2699 (L'.EPrim (Prim.String "MIN"), loc)), loc)), loc), | |
2711 fm) | 2700 fm) |
2712 | 2701 |
2713 | L.EFfi ("Basis", "sql_asc") => ((L'.EPrim (Prim.String ""), loc), fm) | 2702 | L.EFfi ("Basis", "sql_asc") => ((L'.EPrim (Prim.String ""), loc), fm) |
2714 | L.EFfi ("Basis", "sql_desc") => ((L'.EPrim (Prim.String " DESC"), loc), fm) | 2703 | L.EFfi ("Basis", "sql_desc") => ((L'.EPrim (Prim.String " DESC"), loc), fm) |
2715 | 2704 |