IronQuery
A SQL-first query builder for C++
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | Friends | List of all members
iron_query::Expr Class Referencefinal

Arbitrary SQL expression. More...

#include <expr.hpp>

Public Member Functions

template<typename T , std::enable_if_t< impl::kIsSqlInteger< T >, int > = 0>
 Expr (T value)
 Wraps an integer literal of any width and signedness.
 
template<typename T , std::enable_if_t< std::is_floating_point_v< T >, int > = 0>
 Expr (T value)
 Wraps a floating-point literal, rendered with enough digits to round-trip back to the same value.
 
 Expr (bool)=delete
 Deleted: a bool would render as a number. Use Bool.
 
 Expr (char)=delete
 Deleted: a character would render as its numeric code. Use Literal for a one-character string.
 
 Expr (const char *)=delete
 Deleted: a string literal would decay to bool. Use Literal for a value or FromRaw for a trusted SQL fragment.
 
Expr Dot (const Expr &other) const
 Member/field access: this.other.
 
Expr CastRaw (const std::string &type) const
 SQL type cast: CAST (this AS type). type is a trusted, developer-written SQL fragment inserted verbatim; never pass untrusted/dynamic data here.
 
Expr Collate (const Collation &collation) const
 this COLLATE collation.
 
Expr operator[] (const Expr &other) const
 Array/index access: this[other].
 
Expr operator^ (const Expr &other) const
 Exponentiation: this ^ other.
 
Expr BinaryOp (const std::string &op, const Expr &other, OperatorPrecedence precedence=OperatorPrecedence::kAnyOther) const
 Arbitrary infix operator not otherwise named by IronQuery, e.g. BinaryOp("~", pattern) -> "this ~ pattern" (PostgreSQL regex match). op must be a syntactically valid SQL operator name; it is not checked against a real operator catalog.
 
Condition Between (const Expr &a, const Expr &b) const
 this BETWEEN a AND b.
 
Condition NotBetween (const Expr &a, const Expr &b) const
 this NOT BETWEEN a AND b.
 
Condition Like (const Expr &a) const
 this LIKE a.
 
Condition NotLike (const Expr &a) const
 this NOT LIKE a.
 
Condition ILike (const Expr &a) const
 this ILIKE a, a case-insensitive LIKE.
 
Condition NotILike (const Expr &a) const
 this NOT ILIKE a.
 
Condition SimilarTo (const Expr &a) const
 this SIMILAR TO a.
 
Condition NotSimilarTo (const Expr &a) const
 this NOT SIMILAR TO a.
 
Condition In (std::initializer_list< Expr > values) const
 this IN (a, b, c).
 
Condition In (const VirtualTable &subquery) const
 this IN (subquery).
 
Condition NotIn (std::initializer_list< Expr > values) const
 this NOT IN (a, b, c).
 
Condition NotIn (const VirtualTable &subquery) const
 this NOT IN (subquery).
 
Condition EqAny (const Expr &array) const
 this = ANY (array). The idiomatic way to test membership in a list that arrives as a single bind parameter, e.g. col.EqAny(_1).
 
Condition EqAny (const VirtualTable &subquery) const
 this = ANY (subquery).
 
Condition NeAll (const Expr &array) const
 this <> ALL (array), the negation of EqAny.
 
Condition NeAll (const VirtualTable &subquery) const
 this <> ALL (subquery).
 
Condition IsTrue () const
 this IS TRUE.
 
Condition IsFalse () const
 this IS FALSE.
 
Condition IsNull () const
 this IS NULL.
 
Condition IsNotNull () const
 this IS NOT NULL.
 
Condition IsDistinctFrom (const Expr &other) const
 this IS DISTINCT FROM other, the NULL-safe inequality comparison: unlike !=, it is never NULL, treating two NULLs as equal.
 
Condition IsNotDistinctFrom (const Expr &other) const
 this IS NOT DISTINCT FROM other, the NULL-safe equality comparison.
 
Expr operator+ (const Expr &other) const
 this + other.
 
Expr operator- (const Expr &other) const
 this - other.
 
Expr operator* (const Expr &other) const
 this * other.
 
Expr operator/ (const Expr &other) const
 this / other.
 
Expr operator% (const Expr &other) const
 this % other.
 
Expr operator- () const
 Unary minus: -this.
 
Expr operator! () const
 Value-level negation: NOT this. Distinct from Condition::operator!, which negates a predicate; this negates a boolean-typed Expr while staying an Expr (e.g. for use in a SELECT list: (!is_admin).As("not_admin")).
 
Expr Concat (const Expr &other) const
 String concatenation: this || other. Named rather than operator|| because that operator is already Condition's logical OR.
 
SelectItem As (std::string_view name) const
 Names this expression in a SELECT list: this AS name. name must be a plain (undotted) SQL identifier.
 
std::string Extract (OperatorPrecedence precedence) const
 Renders the expression as SQL text, parenthesizing it if its top-level operator does not bind at least as tightly as precedence.
 
std::string ToString () const
 Renders the expression as a standalone, unparenthesized SQL fragment.
 

Static Public Member Functions

static Expr FromRaw (std::string s, OperatorPrecedence precedence=OperatorPrecedence::kSymbol)
 Wraps a trusted, developer-written SQL fragment verbatim, together with the precedence of its top-level operator, so that Extract can bracket it correctly when it is embedded into a higher-precedence expression. Never pass untrusted/dynamic data here.
 
static Expr Literal (const std::string &value)
 Builds a properly escaped and quoted SQL string literal out of an arbitrary (possibly untrusted) value. Use this instead of Expr(string) whenever the content is not a trusted, developer-written SQL fragment.
 
static Expr Ident (const std::string &name)
 Builds a properly escaped and quoted SQL identifier out of an arbitrary (possibly untrusted/dynamic) name. Use this instead of Expr(string) whenever a table/column name is not a trusted, developer-written literal.
 
static Expr Null ()
 The SQL NULL literal. Note that comparing with it is never true: use IsNull / IsNotNull to test for it.
 
static Expr Bool (bool value)
 The SQL boolean literal TRUE or FALSE.
 
static Expr Call (const std::string &name, std::initializer_list< Expr > args)
 Builds a function call expression, e.g. Expr::Call("COALESCE", {a, b}) -> "COALESCE(a, b)". name must be a valid (optionally dotted, e.g. "pg_catalog.now") SQL identifier.
 
static Expr CallDistinct (const std::string &name, std::initializer_list< Expr > args)
 Generalizes CountDistinct to any aggregate, e.g. CallDistinct("string_agg", {x, sep}) -> "string_agg(DISTINCT x, sep)". name must be a valid (optionally dotted) SQL identifier.
 
static Expr Coalesce (std::initializer_list< Expr > args)
 COALESCE(args...): the first non-NULL argument.
 
static Expr NullIf (const Expr &a, const Expr &b)
 NULLIF(a, b): NULL if a equals b, else a.
 
static Expr Greatest (std::initializer_list< Expr > args)
 GREATEST(args...).
 
static Expr Least (std::initializer_list< Expr > args)
 LEAST(args...).
 
static Condition Exists (const VirtualTable &subquery)
 EXISTS (subquery).
 
static Condition NotExists (const VirtualTable &subquery)
 NOT EXISTS (subquery).
 
static Expr PrefixOp (const std::string &op, const Expr &operand, OperatorPrecedence precedence=OperatorPrecedence::kUnaryPlus)
 Arbitrary prefix operator not otherwise named by IronQuery, e.g. PrefixOp("@", x) -> "@ x". op must be a syntactically valid SQL operator name.
 
static Expr Count (const Expr &arg)
 COUNT(arg).
 
static Expr CountAll ()
 COUNT(*), since "*" is not a valid Expr argument.
 
static Expr CountDistinct (const Expr &arg)
 COUNT(DISTINCT arg).
 
static Expr Sum (const Expr &arg)
 SUM(arg).
 
static Expr Avg (const Expr &arg)
 AVG(arg).
 
static Expr Min (const Expr &arg)
 MIN(arg).
 
static Expr Max (const Expr &arg)
 MAX(arg).
 

Friends

class Condition
 
Condition operator< (const Expr &a, const Expr &b)
 a < b.
 
Condition operator<= (const Expr &a, const Expr &b)
 a <= b.
 
Condition operator> (const Expr &a, const Expr &b)
 a > b.
 
Condition operator>= (const Expr &a, const Expr &b)
 a >= b.
 
Condition operator== (const Expr &a, const Expr &b)
 a = b.
 
Condition operator!= (const Expr &a, const Expr &b)
 a != b.
 

Detailed Description

Arbitrary SQL expression.

Note
The comparison (<, <=, >, >=, ==, !=), arithmetic (+, -, *, /, %, ^), and index (operator[]) operators below do not check that their two operands are SQL-compatible types; e.g. comparing a numeric expression to a text literal renders valid, meaningless SQL.
See also
https://www.postgresql.org/docs/current/sql-expressions.html

Constructor & Destructor Documentation

◆ Expr()

template<typename T , std::enable_if_t< std::is_floating_point_v< T >, int > = 0>
iron_query::Expr::Expr ( value)
inline

Wraps a floating-point literal, rendered with enough digits to round-trip back to the same value.

Exceptions
InvalidLiteralif value is NaN or infinite: SQL spells those as typed literals (‘'NaN’::float8`), so use FromRaw instead.

Member Function Documentation

◆ As()

SelectItem iron_query::Expr::As ( std::string_view  name) const

Names this expression in a SELECT list: this AS name. name must be a plain (undotted) SQL identifier.

Exceptions
InvalidIdentifierif name is not a valid identifier.

◆ Avg()

static Expr iron_query::Expr::Avg ( const Expr arg)
static

AVG(arg).

Note
Does not check that arg is numeric.

◆ Between()

Condition iron_query::Expr::Between ( const Expr a,
const Expr b 
) const

this BETWEEN a AND b.

Note
Does not check that a and b share a comparable type with this, nor that a <= b.

◆ BinaryOp()

Expr iron_query::Expr::BinaryOp ( const std::string &  op,
const Expr other,
OperatorPrecedence  precedence = OperatorPrecedence::kAnyOther 
) const

Arbitrary infix operator not otherwise named by IronQuery, e.g. BinaryOp("~", pattern) -> "this ~ pattern" (PostgreSQL regex match). op must be a syntactically valid SQL operator name; it is not checked against a real operator catalog.

Exceptions
InvalidOperatorif op is not a syntactically valid operator name.
Note
Does not check that op names a real operator or that this and other are valid operands for it.
Prefer the existing named methods (operator+, Like, Concat, ...) for the operators IronQuery already supports; use this only for operators it doesn't.

◆ Call()

static Expr iron_query::Expr::Call ( const std::string &  name,
std::initializer_list< Expr args 
)
static

Builds a function call expression, e.g. Expr::Call("COALESCE", {a, b}) -> "COALESCE(a, b)". name must be a valid (optionally dotted, e.g. "pg_catalog.now") SQL identifier.

Exceptions
InvalidIdentifierif name is not a valid identifier.
Note
Does not check args' count or types against the named SQL function's actual signature.

◆ CallDistinct()

static Expr iron_query::Expr::CallDistinct ( const std::string &  name,
std::initializer_list< Expr args 
)
static

Generalizes CountDistinct to any aggregate, e.g. CallDistinct("string_agg", {x, sep}) -> "string_agg(DISTINCT x, sep)". name must be a valid (optionally dotted) SQL identifier.

Exceptions
InvalidIdentifierif name is not a valid identifier.
InvalidArgumentif args is empty.
Note
Does not check args' count or types against the named SQL aggregate's actual signature.

◆ CastRaw()

Expr iron_query::Expr::CastRaw ( const std::string &  type) const

SQL type cast: CAST (this AS type). type is a trusted, developer-written SQL fragment inserted verbatim; never pass untrusted/dynamic data here.

Note
Does not check that type is a real SQL type or that casting this to it is valid.

◆ Coalesce()

static Expr iron_query::Expr::Coalesce ( std::initializer_list< Expr args)
static

COALESCE(args...): the first non-NULL argument.

Exceptions
InvalidArgumentif args is empty.

◆ Collate()

Expr iron_query::Expr::Collate ( const Collation collation) const

this COLLATE collation.

Note
Does not check that this is text-typed; see also Collation::FromRaw.

◆ Concat()

Expr iron_query::Expr::Concat ( const Expr other) const

String concatenation: this || other. Named rather than operator|| because that operator is already Condition's logical OR.

Note
Does not check that this and other are text-typed.

◆ EqAny()

Condition iron_query::Expr::EqAny ( const Expr array) const

this = ANY (array). The idiomatic way to test membership in a list that arrives as a single bind parameter, e.g. col.EqAny(_1).

Note
Does not check that array is actually array-typed or that its element type is compatible with this.

◆ Extract()

std::string iron_query::Expr::Extract ( OperatorPrecedence  precedence) const

Renders the expression as SQL text, parenthesizing it if its top-level operator does not bind at least as tightly as precedence.

Parameters
precedenceThe precedence context this expression is being embedded into.
Returns
The (possibly parenthesized) SQL fragment.

◆ Greatest()

static Expr iron_query::Expr::Greatest ( std::initializer_list< Expr args)
static

GREATEST(args...).

Exceptions
InvalidArgumentif args is empty.
Note
Unlike Max, this is not an aggregate: it picks the greatest among its arguments, not among rows.

◆ Ident()

static Expr iron_query::Expr::Ident ( const std::string &  name)
static

Builds a properly escaped and quoted SQL identifier out of an arbitrary (possibly untrusted/dynamic) name. Use this instead of Expr(string) whenever a table/column name is not a trusted, developer-written literal.

Exceptions
InvalidIdentifierif name contains a NUL byte.

◆ ILike()

Condition iron_query::Expr::ILike ( const Expr a) const

this ILIKE a, a case-insensitive LIKE.

Note
Does not check that this and a are text-typed.

◆ In()

Condition iron_query::Expr::In ( std::initializer_list< Expr values) const

this IN (a, b, c).

Exceptions
InvalidArgumentif values is empty: SQL has no empty IN () list.
Note
Does not check that all values share a common type with this or with each other.

◆ Least()

static Expr iron_query::Expr::Least ( std::initializer_list< Expr args)
static

LEAST(args...).

Exceptions
InvalidArgumentif args is empty.
Note
Unlike Min, this is not an aggregate: it picks the least among its arguments, not among rows.

◆ Like()

Condition iron_query::Expr::Like ( const Expr a) const

this LIKE a.

Note
Does not check that this and a are text-typed.

◆ Literal()

static Expr iron_query::Expr::Literal ( const std::string &  value)
static

Builds a properly escaped and quoted SQL string literal out of an arbitrary (possibly untrusted) value. Use this instead of Expr(string) whenever the content is not a trusted, developer-written SQL fragment.

Exceptions
InvalidLiteralif value contains a NUL byte.

◆ NeAll()

Condition iron_query::Expr::NeAll ( const Expr array) const

this <> ALL (array), the negation of EqAny.

Note
Does not check that array is actually array-typed or that its element type is compatible with this.

◆ NotBetween()

Condition iron_query::Expr::NotBetween ( const Expr a,
const Expr b 
) const

this NOT BETWEEN a AND b.

Note
Does not check that a and b share a comparable type with this, nor that a <= b.

◆ NotILike()

Condition iron_query::Expr::NotILike ( const Expr a) const

this NOT ILIKE a.

Note
Does not check that this and a are text-typed.

◆ NotIn()

Condition iron_query::Expr::NotIn ( std::initializer_list< Expr values) const

this NOT IN (a, b, c).

Exceptions
InvalidArgumentif values is empty.
Note
Does not check that all values share a common type with this or with each other.

◆ NotLike()

Condition iron_query::Expr::NotLike ( const Expr a) const

this NOT LIKE a.

Note
Does not check that this and a are text-typed.

◆ NotSimilarTo()

Condition iron_query::Expr::NotSimilarTo ( const Expr a) const

this NOT SIMILAR TO a.

Note
Does not check that this and a are text-typed.

◆ operator!()

Expr iron_query::Expr::operator! ( ) const

Value-level negation: NOT this. Distinct from Condition::operator!, which negates a predicate; this negates a boolean-typed Expr while staying an Expr (e.g. for use in a SELECT list: (!is_admin).As("not_admin")).

Note
Does not check that this is boolean-typed.

◆ PrefixOp()

static Expr iron_query::Expr::PrefixOp ( const std::string &  op,
const Expr operand,
OperatorPrecedence  precedence = OperatorPrecedence::kUnaryPlus 
)
static

Arbitrary prefix operator not otherwise named by IronQuery, e.g. PrefixOp("@", x) -> "@ x". op must be a syntactically valid SQL operator name.

Exceptions
InvalidOperatorif op is not a syntactically valid operator name.
Note
Does not check that op names a real operator or that operand is a valid operand for it.
Prefer the existing named methods (operator-, operator!, ...) for the operators IronQuery already supports; use this only for operators it doesn't.

◆ SimilarTo()

Condition iron_query::Expr::SimilarTo ( const Expr a) const

this SIMILAR TO a.

Note
Does not check that this and a are text-typed.

◆ Sum()

static Expr iron_query::Expr::Sum ( const Expr arg)
static

SUM(arg).

Note
Does not check that arg is numeric.

The documentation for this class was generated from the following file: