Back

join (clj)

(source)

function

(join xrel yrel) (join xrel yrel km)
When passed 2 rels, returns the rel corresponding to the natural join. When passed an additional keymap, joins on the corresponding keys.

Examples

clojure
(ns clojure.test-clojure.metadata
  (:use clojure.test
        [clojure.test-helper :only (eval-in-temp-ns)])
  (:require [clojure.set :as set]))

(deftest interaction-of-def-with-metadata
  (testing "initial def sets metadata"
    (let [v (eval-in-temp-ns
             (def ^{:a 1} foo 0)
             #'foo)]
      (is (= 1 (-> v meta :a)))))
  (testing "const vars preserve metadata"
    (let [[v1 v2] (eval-in-temp-ns
                   (def ^:const foo ^:foo [])
                   (def ^:const bar ^:foo [:bar])
                   [(meta foo) (meta bar)])]
      (is (= {:foo true} v1))
      (is (= {:foo true} v2))))
  #_(testing "subsequent declare doesn't overwrite metadata"
    (let [v (eval-in-temp-ns
             (def ^{:b 2} bar 0)
             (declare bar)
             #'bar)]
      (is (= 2 (-> v meta :b))))
    (testing "when compiled"
      (let [v (eval-in-temp-ns
               (def ^{:c 3} bar 0)
               (defn declare-bar []
                 (declare bar))
               (declare-bar)
               #'bar)]
        (is (= 3 (-> v meta :c))))))
  (testing "subsequent def with init-expr *does* overwrite metadata"
    (let [v (eval-in-temp-ns
             (def ^{:d 4} quux 0)
             (def quux 1)
             #'quux)]
      (is (nil? (-> v meta :d))))
    (testing "when compiled"
      (let [v (eval-in-temp-ns
               (def ^{:e 5} quux 0)
               (defn def-quux []
                 (def quux 1))
               (def-quux)
               #'quux)]
        (is (nil? (-> v meta :e))))))
  (testing "IllegalArgumentException should not be thrown"
    (testing "when defining var whose value is calculated with a primitive fn."
      (testing "This case fails without a fix for CLJ-852"
        (is (eval-in-temp-ns
             (defn foo ^long [^long x] x)
             (def x (inc (foo 10))))))
      (testing "This case should pass even without a fix for CLJ-852"
        (is (eval-in-temp-ns
             (defn foo ^long [^long x] x)
             (def x (foo (inc 10)))))))))
 
 (deftest fns-preserve-metadata-on-maps
   (let [xm {:a 1 :b -7}
         x (with-meta {:foo 1 :bar 2} xm)
         ym {:c "foo"}
         y (with-meta {:baz 4 :guh x} ym)]
 
     (is (= xm (meta (:guh y))))
     (is (= xm (meta (reduce #(assoc %1 %2 (inc %2)) x (range 1000)))))
     (is (= xm (meta (-> x (dissoc :foo) (dissoc :bar)))))
     (let [z (assoc-in y [:guh :la] 18)]
       (is (= ym (meta z)))
       (is (= xm (meta (:guh z)))))
     (let [z (update-in y [:guh :bar] inc)]
       (is (= ym (meta z)))
       (is (= xm (meta (:guh z)))))
     (is (= xm (meta (get-in y [:guh]))))
     (is (= xm (meta (into x y))))
     (is (= ym (meta (into y x))))
     
     (is (= xm (meta (merge x y))))
     (is (= ym (meta (merge y x))))
     (is (= xm (meta (merge-with + x y))))
     (is (= ym (meta (merge-with + y x))))
 
     (is (= xm (meta (select-keys x [:bar]))))
     (is (= xm (meta (set/rename-keys x {:foo :new-foo}))))
 
     ;; replace returns a seq when given a set.  Can seqs have
     ;; metadata?
     
     ;; TBD: rseq, subseq, and rsubseq returns seqs.  If it is even
     ;; possible to put metadata on a seq, does it make sense that the
     ;; seqs returned by these functions should have the same metadata
     ;; as the sorted collection on which they are called?
     ))
 
 (deftest fns-preserve-metadata-on-vectors
   (let [xm {:a 1 :b -7}
         x (with-meta [1 2 3] xm)
         ym {:c "foo"}
         y (with-meta [4 x 6] ym)]
 
     (is (= xm (meta (y 1))))
     (is (= xm (meta (assoc x 1 "one"))))
     (is (= xm (meta (reduce #(conj %1 %2) x (range 1000)))))
     (is (= xm (meta (pop (pop (pop x))))))
     (let [z (assoc-in y [1 2] 18)]
       (is (= ym (meta z)))
       (is (= xm (meta (z 1)))))
     (let [z (update-in y [1 2] inc)]
       (is (= ym (meta z)))
       (is (= xm (meta (z 1)))))
     (is (= xm (meta (get-in y [1]))))
     (is (= xm (meta (into x y))))
     (is (= ym (meta (into y x))))
 
     (is (= xm (meta (replace {2 "two"} x))))
     (is (= [1 "two" 3] (replace {2 "two"} x)))
 
     ;; TBD: Currently subvec drops metadata.  Should it preserve it?
     ;;(is (= xm (meta (subvec x 2 3))))
 
     ;; TBD: rseq returns a seq.  If it is even possible to put
     ;; metadata on a seq, does it make sense that the seqs returned by
     ;; these functions should have the same metadata as the sorted
     ;; collection on which they are called?
     ))
 
 (deftest fns-preserve-metadata-on-sets
   ;; TBD: Do tests independently for set, hash-set, and sorted-set,
   ;; perhaps with a loop here.
   (let [xm {:a 1 :b -7}
         x (with-meta #{1 2 3} xm)
         ym {:c "foo"}
         y (with-meta #{4 x 6} ym)]
 
     (is (= xm (meta (y #{3 2 1}))))
     (is (= xm (meta (reduce #(conj %1 %2) x (range 1000)))))
     (is (= xm (meta (-> x (disj 1) (disj 2) (disj 3)))))
     (is (= xm (meta (into x y))))
     (is (= ym (meta (into y x))))
 
     (is (= xm (meta (set/select even? x))))
     (let [cow1m {:what "betsy cow"}
           cow1 (with-meta {:name "betsy" :id 33} cow1m)
           cow2m {:what "panda cow"}
           cow2 (with-meta {:name "panda" :id 34} cow2m)
           cowsm {:what "all the cows"}
           cows (with-meta #{cow1 cow2} cowsm)
           cow-names (set/project cows [:name])
           renamed (set/rename cows {:id :number})]
       (is (= cowsm (meta cow-names)))
       (is (= cow1m (meta (first (filter #(= "betsy" (:name %)) cow-names)))))
       (is (= cow2m (meta (first (filter #(= "panda" (:name %)) cow-names)))))
       (is (= cowsm (meta renamed)))
       (is (= cow1m (meta (first (filter #(= "betsy" (:name %)) renamed)))))
       (is (= cow2m (meta (first (filter #(= "panda" (:name %)) renamed))))))
 
     ;; replace returns a seq when given a set.  Can seqs have
     ;; metadata?
 
     ;; union: Currently returns the metadata of the largest input set.
     ;; This is an artifact of union's current implementation.  I doubt
     ;; any explicit design decision was made to do so.  Like join,
     ;; there doesn't seem to be much reason to prefer the metadata of
     ;; one input set over another, if at least two input sets are
     ;; given, but perhaps defining it to always return a set with the
     ;; metadata of the first input set would be reasonable?
 
     ;; intersection: Returns metadata of the smallest input set.
     ;; Otherwise similar to union.
 
     ;; difference: Seems to always return a set with metadata of first
     ;; input set.  Seems reasonable.  Not sure we want to add a test
     ;; for it, if it is an accident of the current implementation.
 
     ;; join, index, map-invert: Currently always returns a value with
     ;; no metadata.  This seems reasonable.
     ))
clojure

(ns clojure.test-clojure.clojure-set
  (:use clojure.test)
  (:require [clojure.set :as set]))

(deftest test-join
  (are [x y] (= x y)
    (set/join compositions compositions) compositions
    (set/join compositions #{{:name "Art of the Fugue" :genre "Classical"}})
                           #{{:name "Art of the Fugue" :composer "J. S. Bach" :genre "Classical"}}
    ))
borkdude/speculative
(ns speculative.set
  (:require [clojure.set :as set]
            [clojure.spec.alpha :as s]
            [speculative.specs :as ss]))

(s/fdef set/join
  :args (s/alt :binary (s/cat :xrel ::rel
                              :yrel ::rel)
               :ternary (s/cat :xrel ::rel
                               :yrel ::rel
                               :km ::nilable-map))
  :ret ::ss/set)
marick/suchwow
(ns such.f-relational
  (:require [such.versions :refer [when>=1-7]]
            [such.relational :as subject]
            [such.metadata :as meta]
            [clojure.set :as set]
            [clojure.pprint :refer [pprint]]
            [midje.sweet :refer :all]))

  (fact join
    (let [has-a-and-b [{:a 1, :b 2} {:a 2, :b 1} {:a 2, :b 2}]
          has-b-and-c [{:blike 1, :c 2} {:blike 2, :c 1} {:blike 2, :c 2}]]
      (subject/join has-a-and-b has-b-and-c {:b :blike})
      => #{{:a 1, :b 2, :blike 2, :c 1} {:a 1, :b 2, :blike 2, :c 2}
           {:a 2, :b 1, :blike 1, :c 2} {:a 2, :b 2, :blike 2, :c 1}
           {:a 2, :b 2, :blike 2, :c 2}}))
  )


;;; In addition to selecting elements, you can extend maps (similar to joins)
NoahTheDuke/coc-clojure
(ns build-commands
  (:require
   [babashka.fs :as fs]
   [babashka.process :as p]
   [cheshire.core :refer [generate-string parse-string]]
   [clojure.set :as set]
   [clojure.string :as str]))

(println (str/join "\n" (map :command commands-for-package)))
Netflix/mantis-mql
(ns io.mantisrx.mql.transformers
  (:require #?@(:clj [[rx.lang.clojure.core :as rx]
                      [rx.lang.clojure.interop :as rxi]
                      [rx.lang.clojure.blocking :as rxb]
                       [clojure.data.json :as json]
                      [io.mantisrx.mql.properties :as mqlp]]
                :cljs [[cljs.reader :refer [read-string]]])
            [io.mantisrx.mql.util :as util]
            [io.mantisrx.mql.compilers.core.sampling :as samp] ;; Force loading of this namespace for compilation reasons
            [io.mantisrx.mql.compilers.core.join] ;; Force loading of this namespace for compilation reasons
            [io.mantisrx.mql.compilers.core.select] ;; Force loading of this namespace for compilation reasons
            [io.mantisrx.mql.compilers.core.operands] ;; Force loading of this namespace for compilation reasons
            [io.mantisrx.mql.compilers.core.where] ;; Force loading of this namespace for compilation reasons
            [clojure.string :as string]
            [clojure.set :as cljset])
  #?(:clj (:import rx.Observable
                   rx.schedulers.Schedulers
                   java.util.concurrent.TimeUnit
                   java.util.List
                   java.util.ArrayList
                   java.util.RandomAccess
                   java.util.Map
                   java.util.TreeMap
                   clojure.lang.RT
                   java.util.LinkedHashMap)))

(def join->fn io.mantisrx.mql.compilers.core.join/join->fn)

(def mql-evaluators
  {:QUERY identity
   :asterisk asterisk->fn
   :SELECTLIST select-list->fn
   :AGG_LIST io.mantisrx.mql.compilers.core.select/agg-select-list->fn
   :WHERE io.mantisrx.mql.compilers.core.where/where-clause->fn
   :WHERE_TRUE (fn [& args] {:where (fn [datum] true)})
   :WHERE_FALSE (fn [& args] {:where (fn [datum] false)})
   :JOIN join->fn
   :HAVING io.mantisrx.mql.compilers.core.where/having-clause->fn
   :SAMPLE identity
   :json_sample_config sample-config->sampler
   :percent_sample_config percent-sample-config->sampler
   :AGG_OP io.mantisrx.mql.compilers.core.select/agg-op->selector+aggregator
   :as_clause (fn [n] (n {}))
   :StarBinaryExpr io.mantisrx.mql.compilers.core.where/star-binary-expr->pred
   :func_kw io.mantisrx.mql.compilers.core.select/agg-func->fn
   :number (partial literal->fn read-string)
   :property_number read-string
   :integer (partial literal->fn (comp int read-string))
   :string_literal (partial literal->fn util/strip-surround)
   :boolean_literal (partial literal->fn read-string)
   :not_search_condition not-operand->operand
   :property io.mantisrx.mql.compilers.core.operands/property->fn
   :property_with_as (fn [p as] p)
   :sw_property io.mantisrx.mql.compilers.core.operands/sw-property->fn
   :star_property io.mantisrx.mql.compilers.core.operands/star-property->fn
   :select_operand identity
   :not_operand not-operand->operand
   :distinct_operand io.mantisrx.mql.compilers.core.operands/distinct-operand->property
   :BINARY_OPERATOR identity
   :REGEX_OPERATOR identity
   :tick io.mantisrx.mql.compilers.core.operands/tick->operand
   :boolean_test io.mantisrx.mql.compilers.core.where/binary-expr->pred
   :boolean_term io.mantisrx.mql.compilers.core.where/boolean-term->pred
   :search_condition io.mantisrx.mql.compilers.core.where/search-condition->pred
   :re_expression #?(:clj #(java.util.regex.Pattern/compile % java.util.regex.Pattern/DOTALL)
                     :cljs re-pattern)
   :q_pword util/strip-surround
   :null (fn [_] nil)
   :word identity
   :pword identity
   :desc_kw identity
   })