|
44 | 44 | nil) |
45 | 45 |
|
46 | 46 |
|
| 47 | +(defmacro distinct (&rest data) |
| 48 | + (declare (ignore data)) |
| 49 | + nil) |
| 50 | + |
| 51 | + |
47 | 52 | (defclass aggregation-results () |
48 | 53 | ((%aggregators :initarg :aggregators |
49 | 54 | :reader aggregators) |
50 | 55 | (%aggregation-column-names :initarg :aggregation-column-names |
51 | | - :reader aggregation-column-names))) |
| 56 | + :reader aggregation-column-names))) |
52 | 57 |
|
53 | 58 |
|
54 | 59 | (defclass group-by-aggregation-results () |
|
64 | 69 | (let* ((gathered-constructor-forms (make-hash-table :test 'eql)) |
65 | 70 | (gathered-constructor-variables (make-hash-table :test 'eql)) |
66 | 71 | (gathered-group-by-variables (list)) |
| 72 | + (gathered-distinct-variables (make-hash-table :test 'eql)) |
67 | 73 | (group-names (list)) |
68 | 74 | (pre-form nil) |
69 | 75 | (aggregation-symbol (gensym)) |
|
94 | 100 | ,what |
95 | 101 | ,constructor-form |
96 | 102 | ,into))) |
| 103 | + ((and (listp pre-form) (eq (car pre-form) 'vellum.table:distinct)) |
| 104 | + (lret ((symbol (gensym))) |
| 105 | + (setf (gethash symbol gathered-distinct-variables) (rest pre-form)))) |
97 | 106 | ((and (listp pre-form) (eq (car pre-form) 'vellum.table:group-by)) |
98 | 107 | (iterate |
99 | 108 | (for elt in (rest pre-form)) |
|
118 | 127 | gathered-constructor-forms |
119 | 128 | aggregation-symbol |
120 | 129 | extract-value-symbol |
| 130 | + gathered-distinct-variables |
121 | 131 | (nreverse gathered-group-by-variables) |
122 | 132 | (nreverse group-names)))) |
123 | 133 |
|
|
127 | 137 | gathered-constructor-forms |
128 | 138 | aggregation-symbol |
129 | 139 | extract-value-symbol |
| 140 | + gathered-distinct-variables |
130 | 141 | gathered-group-by-variables |
131 | 142 | group-names) |
132 | 143 | (let* ((!grouped-aggregators (gensym))) |
|
154 | 165 | (,!aggregators (or (gethash ',result-name ,!group) |
155 | 166 | (cl-ds.alg.meta:call-constructor ,constructor-form)))) |
156 | 167 | (cl-ds.alg.meta:extract-result ,!aggregators)))))) |
| 168 | + ((gethash f gathered-distinct-variables) |
| 169 | + (let ((forms (shiftf (gethash f gathered-distinct-variables) nil))) |
| 170 | + (if (= 1 (length forms)) |
| 171 | + `(vellum:drop-row-when (shiftf (gethash ,(first forms) ,f) t)) |
| 172 | + `(vellum:drop-row-when (shiftf (gethash (list ,@forms) ,f) t))))) |
157 | 173 | (t f))) |
158 | 174 | result) |
159 | 175 | gathered-constructor-variables |
160 | 176 | gathered-constructor-forms |
161 | 177 | aggregation-symbol |
162 | 178 | extract-value-symbol |
| 179 | + gathered-distinct-variables |
163 | 180 | gathered-group-by-variables |
164 | 181 | group-names |
165 | 182 | !grouped-aggregators))) |
|
205 | 222 | constructor-forms |
206 | 223 | aggregation-symbol |
207 | 224 | extract-value-symbol |
| 225 | + gathered-distinct-variables |
208 | 226 | gathered-group-by-variables |
209 | 227 | group-names |
210 | 228 | !grouped-aggregators) |
|
218 | 236 | gensyms)) |
219 | 237 | env)) |
220 | 238 | (let-constructors |
221 | | - (iterate |
222 | | - (for (key value) in-hashtable constructor-variables) |
223 | | - (collecting (list value `(cl-ds.alg.meta:call-constructor ,(gethash key constructor-forms))))))) |
| 239 | + (let ((result (list))) |
| 240 | + (iterate |
| 241 | + (for (key value) in-hashtable constructor-variables) |
| 242 | + (push (list value `(cl-ds.alg.meta:call-constructor ,(gethash key constructor-forms))) |
| 243 | + result)) |
| 244 | + (iterate |
| 245 | + (for (key value) in-hashtable gathered-distinct-variables) |
| 246 | + (push (list key `(make-hash-table :test 'equal)) result)) |
| 247 | + result))) |
224 | 248 | (declare (ignore extract-value-symbol aggregation-symbol)) |
225 | 249 | (unless (= (length (remove-duplicates group-names :test #'equal)) |
226 | 250 | (length group-names)) |
|
0 commit comments