 // MARK: - Logical Operators (AND, OR, NOT)
 
 extension AssociationAggregate {
-    /// Returns a logically negated aggregate.
-    ///
-    /// For example:
-    ///
-    ///     Author.having(!Author.books.isEmpty)
+    /// A negated logical aggregate.
+    ///
+    /// For example:
+    ///
+    /// ```swift
+    /// Author.having(!Author.books.isEmpty)
+    /// ```
     public static prefix func ! (aggregate: Self) -> Self {
         aggregate.map { !$0 }
     }
     
-    /// Groups two aggregates with the `AND` SQL operator.
-    ///
-    /// For example:
-    ///
-    ///     Author.having(Author.books.isEmpty && Author.paintings.isEmpty)
+    /// The `AND` SQL operator.
     public static func && (lhs: Self, rhs: Self) -> Self {
         combine(lhs, rhs, with: &&)
     }
     
     // TODO: test
+    /// The `AND` SQL operator.
     public static func && (lhs: Self, rhs: some SQLExpressible) -> Self {
         lhs.map { $0 && rhs }
     }
     
     // TODO: test
+    /// The `AND` SQL operator.
     public static func && (lhs: some SQLExpressible, rhs: Self) -> Self {
         rhs.map { lhs && $0 }
     }
     
     
-    /// Groups two aggregates with the `OR` SQL operator.
-    ///
-    /// For example:
-    ///
-    ///     Author.having(!Author.books.isEmpty || !Author.paintings.isEmpty)
+    /// The `OR` SQL operator.
     public static func || (lhs: Self, rhs: Self) -> Self {
         combine(lhs, rhs, with: ||)
     }
     
     // TODO: test
+    /// The `OR` SQL operator.
     public static func || (lhs: Self, rhs: some SQLExpressible) -> Self {
         lhs.map { $0 || rhs }
     }
     
     // TODO: test
+    /// The `OR` SQL operator.
     public static func || (lhs: some SQLExpressible, rhs: Self) -> Self {
         rhs.map { lhs || $0 }
     }

// MARK: - Arithmetic Operators (+, -, *, /)

extension AssociationAggregate {
    /// Returns an arithmetically negated aggregate.
    ///
    /// For example:
    ///
    ///     Author.annotated(with: -Author.books.count)
    public static prefix func - (aggregate: Self) -> Self {
        aggregate.map { -$0 }
    }
    
    /// Returns an aggregate that sums two aggregates with the `+` SQL operator.
    ///
    /// For example:
    ///
    ///     Author.annotated(with: Author.books.count + Author.paintings.count)
    public static func + (lhs: Self, rhs: Self) -> Self {
        combine(lhs, rhs, with: +)
    }
    
    /// Returns an aggregate that sums an aggregate with the `+` SQL operator.
    ///
    /// For example:
    ///
    ///     Author.annotated(with: Author.books.count + 1)
    public static func + (lhs: Self, rhs: some SQLExpressible) -> Self {
        lhs.map { $0 + rhs }
    }
    
    /// Returns an aggregate that sums an aggregate with the `+` SQL operator.
    ///
    /// For example:
    ///
    ///     Author.annotated(with: 1 + Author.books.count)
    public static func + (lhs: some SQLExpressible, rhs: Self) -> Self {
        rhs.map { lhs + $0 }
    }
    
    /// Returns an aggregate that substracts two aggregates with the `-` SQL operator.
    ///
    /// For example:
    ///
    ///     Author.annotated(with: Author.books.count - Author.paintings.count)
    public static func - (lhs: Self, rhs: Self) -> Self {
        combine(lhs, rhs, with: -)
    }
    
    /// Returns an aggregate that substracts an aggregate with the `-` SQL operator.
    ///
    /// For example:
    ///
    ///     Author.annotated(with: Author.books.count - 1)
    public static func - (lhs: Self, rhs: some SQLExpressible) -> Self {
        lhs.map { $0 - rhs }
    }
    
    /// Returns an aggregate that substracts an aggregate with the `-` SQL operator.
    ///
    /// For example:
    ///
    ///     Author.annotated(with: 1 - Author.books.count)
    public static func - (lhs: some SQLExpressible, rhs: Self) -> Self {
        rhs.map { lhs - $0 }
    }
    
    /// Returns an aggregate that multiplies two aggregates with the `*` SQL operator.
    ///
    /// For example:
    ///
    ///     Author.annotated(with: Author.books.count * Author.paintings.count)
    public static func * (lhs: Self, rhs: Self) -> Self {
        combine(lhs, rhs, with: *)
    }
    
    /// Returns an aggregate that substracts an aggregate with the `*` SQL operator.
    ///
    /// For example:
    ///
    ///     Author.annotated(with: Author.books.count * 2)
    public static func * (lhs: Self, rhs: some SQLExpressible) -> Self {
        lhs.map { $0 * rhs }
    }
    
    /// Returns an aggregate that substracts an aggregate with the `*` SQL operator.
    ///
    /// For example:
    ///
    ///     Author.annotated(with: 2 * Author.books.count)
    public static func * (lhs: some SQLExpressible, rhs: Self) -> Self {
        rhs.map { lhs * $0 }
    }
    
    /// Returns an aggregate that multiplies two aggregates with the `/` SQL operator.
    ///
    /// For example:
    ///
    ///     Author.annotated(with: Author.books.count / Author.paintings.count)
    public static func / (lhs: Self, rhs: Self) -> Self {
        combine(lhs, rhs, with: /)
    }
    
    /// Returns an aggregate that substracts an aggregate with the `/` SQL operator.
    ///
    /// For example:
    ///
    ///     Author.annotated(with: Author.books.count / 2)
    public static func / (lhs: Self, rhs: some SQLExpressible) -> Self {
        lhs.map { $0 / rhs }
    }
    
    /// Returns an aggregate that substracts an aggregate with the `/` SQL operator.
    ///
    /// For example:
    ///
    ///     Author.annotated(with: 2 / Author.books.count)
    public static func / (lhs: some SQLExpressible, rhs: Self) -> Self {
        rhs.map { lhs / $0 }
    }

// MARK: - Egality and Identity Operators (=, <>, IS, IS NOT)

extension AssociationAggregate {
    /// The `=` SQL operator.
    public static func == (lhs: Self, rhs: Self) -> Self {
        combine(lhs, rhs, with: ==)
    }
    
    /// The `=` SQL operator.
    ///
    /// When the right operand is nil, `IS NULL` is used instead of the
    /// `=` operator.
    public static func == (lhs: Self, rhs: (any SQLExpressible)?) -> Self {
        lhs.map { $0 == rhs }
    }
    
    /// The `=` SQL operator.
    ///
    /// When the left operand is nil, `IS NULL` is used instead of the
    /// `=` operator.
    public static func == (lhs: (any SQLExpressible)?, rhs: Self) -> Self {
        rhs.map { lhs == $0 }
    }
    
    /// The `=` SQL operator.
    public static func == (lhs: Self, rhs: Bool) -> Self {
        lhs.map { $0 == rhs }
    }
    
    /// The `=` SQL operator.
    public static func == (lhs: Bool, rhs: Self) -> Self {
        rhs.map { lhs == $0 }
    }
    
    /// The `<>` SQL operator.
    public static func != (lhs: Self, rhs: Self) -> Self {
        combine(lhs, rhs, with: !=)
    }
    
    /// The `<>` SQL operator.
    ///
    /// When the right operand is nil, `IS NOT NULL` is used instead of the
    /// `<>` operator.
    public static func != (lhs: Self, rhs: (any SQLExpressible)?) -> Self {
        lhs.map { $0 != rhs }
    }
    
    /// The `<>` SQL operator.
    ///
    /// When the left operand is nil, `IS NOT NULL` is used instead of the
    /// `<>` operator.
    public static func != (lhs: (any SQLExpressible)?, rhs: Self) -> Self {
        rhs.map { lhs != $0 }
    }
    
    /// The `<>` SQL operator.
    public static func != (lhs: Self, rhs: Bool) -> Self {
        lhs.map { $0 != rhs }
    }
    
    /// The `<>` SQL operator.
    public static func != (lhs: Bool, rhs: Self) -> Self {
        rhs.map { lhs != $0 }
    }
    
    /// The `IS` SQL operator.
    public static func === (lhs: Self, rhs: Self) -> Self {
        combine(lhs, rhs, with: ===)
    }
    
    /// The `IS` SQL operator.
    public static func === (lhs: Self, rhs: (any SQLExpressible)?) -> Self {
        lhs.map { $0 === rhs }
    }
    
    /// The `IS` SQL operator.
    public static func === (lhs: (any SQLExpressible)?, rhs: Self) -> Self {
        rhs.map { lhs === $0 }
    }
    
    /// The `IS NOT` SQL operator.
    public static func !== (lhs: Self, rhs: Self) -> Self {
        combine(lhs, rhs, with: !==)
    }
    
    /// The `IS NOT` SQL operator.
    public static func !== (lhs: Self, rhs: (any SQLExpressible)?) -> Self {
        lhs.map { $0 !== rhs }
    }
    
    /// The `IS NOT` SQL operator.
    public static func !== (lhs: (any SQLExpressible)?, rhs: Self) -> Self {
        rhs.map { lhs !== $0 }
    }
}
