query: single-pass distinct result extraction (result relation)
ober
0a27e62de04dcd5f6647a6fcffb33cef7f9d41c3
--- a/lib/jerboa-db/query/engine.ss +++ b/lib/jerboa-db/query/engine.ss @@ -592,17 +592,21 @@ ;; Extract result tuples from bindings based on :find specification. (def (extract-find-results find-vars bindings-list) - (let ([has-aggregates? (any-aggregates? find-vars)]) - (if has-aggregates? - (apply-aggregates find-vars bindings-list) - (deduplicate-results - (map (lambda (bindings) - (map (lambda (var) - (if (logic-var? var) - (binding-ref bindings var) - var)) ;; literal in find - find-vars)) - bindings-list))))) + (if (any-aggregates? find-vars) + (apply-aggregates find-vars bindings-list) + ;; Result relation: project each binding to a row and dedup in a single + ;; pass into a set, instead of building a full intermediate row list and + ;; deduping it separately (one traversal, no intermediate allocation). + (let ([seen (make-hashtable equal-hash equal?)] [out '()]) + (for-each + (lambda (b) + (let ([row (map (lambda (v) (if (logic-var? v) (binding-ref b v) v)) + find-vars)]) + (unless (hashtable-contains? seen row) + (hashtable-set! seen row #t) + (set! out (cons row out))))) + bindings-list) + (reverse out)))) (def (any-aggregates? find-vars) (exists (lambda (v) (and (pair? v) (aggregate? (car v)))) find-vars))