Class: ActiveRecord::Refined::BlockContext
- Inherits:
-
Object
- Object
- ActiveRecord::Refined::BlockContext
- Defined in:
- lib/active_record/refined.rb
Overview
What a block can call: the aggregates, the functions, CASE, and the
escape hatches. A block is evaluated with one of these as self, so
its methods are called bare -- count(:*), upper(:name) -- and each
gives back an expression that compares, aliases and orders like a
column does (see BlockSyntax).
Where a function is spelled differently from one database to the next,
the method names the one meaning and the adapter gets its own
spelling; where a database has no equivalent, the method raises
NotImplementedError as the block is read, rather than leaving the
database to reject the SQL.
Aggregates collapse
-
#avg(column, distinct: false) ⇒ AST::Aggregate
AVG(column), orAVG(DISTINCT column). -
#count(column, distinct: false) ⇒ AST::Aggregate
COUNT(column);:*forCOUNT(*),distinct: trueforCOUNT(DISTINCT column). -
#json_arrayagg(value) ⇒ AST::JsonAggregate
The rows of a group gathered into one JSON array, a value from each:
jsonb_aggon PostgreSQL,json_group_arrayon SQLite,JSON_ARRAYAGGon the MySQL family and Oracle; SQL Server has none. -
#json_objectagg(key, value) ⇒ AST::JsonAggregate
The rows of a group gathered into one JSON object, a key and a value from each, named as #json_arrayagg is; SQL Server has none.
-
#max(column) ⇒ AST::Aggregate
MAX(column). -
#min(column) ⇒ AST::Aggregate
MIN(column). -
#string_agg(value, separator = ",") ⇒ AST::StringAggregate
The strings of a group joined into one, a separator between:
STRING_AGGon PostgreSQL and SQL Server,group_concaton SQLite,GROUP_CONCATon MySQL,LISTAGGon Oracle. -
#sum(column, distinct: false) ⇒ AST::Aggregate
SUM(column), orSUM(DISTINCT column).
JSON collapse
-
#json_array(*values) ⇒ AST::JsonBuild
A JSON array built in the row from the values given.
-
#json_object(pairs = {}) ⇒ AST::JsonBuild
A JSON object built in the row from a hash whose values are expressions.
Scalar functions collapse
-
#abs(x) ⇒ AST::Function
ABS(x). -
#acos(x) ⇒ AST::Function
ACOS(x). -
#asin(x) ⇒ AST::Function
ASIN(x). -
#atan(x) ⇒ AST::Function
ATAN(x). -
#atan2(y, x) ⇒ AST::Function
ATAN2(y, x):ATN2on SQL Server. -
#bit_and(column) ⇒ AST::Function
BIT_AND(column), an aggregate. -
#bit_or(column) ⇒ AST::Function
BIT_OR(column), an aggregate. -
#bit_xor(column) ⇒ AST::Function
BIT_XOR(column), an aggregate. -
#ceil(x) ⇒ AST::Function
CEIL(x):CEILINGon SQL Server. -
#char_length(string) ⇒ AST::Function
CHAR_LENGTH(string):LENGTHon SQLite and Oracle,LENon SQL Server. -
#coalesce(*values) ⇒ AST::Function
COALESCE(a, b, ...): the first that is not NULL. -
#concat(*strings) ⇒ AST::Function
CONCAT(a, b, ...). -
#cos(x) ⇒ AST::Function
COS(x). -
#date_trunc(field, timestamp) ⇒ AST::Function
date_trunc('day', timestamp). -
#degrees(x) ⇒ AST::Function
DEGREES(x). -
#exp(x) ⇒ AST::Function
EXP(x). -
#floor(x) ⇒ AST::Function
FLOOR(x). -
#format(template, *values) ⇒ AST::Function
printf-style
FORMAT(template, ...). -
#greatest(*values) ⇒ AST::Function
GREATEST(a, b, ...):MAXon SQLite. -
#least(*values) ⇒ AST::Function
LEAST(a, b, ...):MINon SQLite. -
#length(string) ⇒ AST::Function
LENGTH(string):LENon SQL Server. -
#ln(x) ⇒ AST::Function
LN(x):LOGon SQL Server. -
#log(base, x) ⇒ AST::Function
LOG(base, x). -
#log10(x) ⇒ AST::Function
LOG10(x). -
#log2(x) ⇒ AST::Function
LOG2(x). -
#lower(string) ⇒ AST::Function
LOWER(string). -
#ltrim(string) ⇒ AST::Function
LTRIM(string). -
#mod(x, y) ⇒ AST::Function
MOD(x, y). -
#now ⇒ AST::Function
NOW(). -
#nullif(x, y) ⇒ AST::Function
NULLIF(x, y): NULL where the two are equal, x otherwise. -
#pi ⇒ AST::Function
PI(). -
#power(x, y) ⇒ AST::Function
POWER(x, y). -
#radians(x) ⇒ AST::Function
RADIANS(x). -
#rand ⇒ AST::Function
RAND(), a random number per row:RANDOM()on PostgreSQL and SQLite. -
#replace(string, from, to) ⇒ AST::Function
REPLACE(string, from, to). -
#round(x, places = 0) ⇒ AST::Function
ROUND(x, places). -
#rtrim(string) ⇒ AST::Function
RTRIM(string). -
#sign(x) ⇒ AST::Function
SIGN(x). -
#sin(x) ⇒ AST::Function
SIN(x). -
#sqrt(x) ⇒ AST::Function
SQRT(x). -
#substr(string, from, length = nil) ⇒ AST::Function
SUBSTR(string, from, length):SUBSTRINGon SQL Server, which insists on the length. -
#tan(x) ⇒ AST::Function
TAN(x). -
#trim(string) ⇒ AST::Function
TRIM(string). -
#trunc(x, places = 0) ⇒ AST::Function
TRUNC(x, places):TRUNCATEon MySQL, which insists on the places. -
#upper(string) ⇒ AST::Function
UPPER(string).
Datetime value functions collapse
-
#current_date ⇒ AST::DatetimeValueFunction
CURRENT_DATE, today in the session's zone -- UTC where Active Record has set it so. -
#current_time(precision = nil) ⇒ AST::DatetimeValueFunction
CURRENT_TIME. -
#current_timestamp(precision = nil) ⇒ AST::DatetimeValueFunction
CURRENT_TIMESTAMP, the server's clock in the session's zone; the portable spelling of what #now means. -
#extract(field, expr) ⇒ AST::Extract
EXTRACT(field FROM expr): a year, a month, a day of a date. -
#localtime(precision = nil) ⇒ AST::DatetimeValueFunction
LOCALTIME. -
#localtimestamp(precision = nil) ⇒ AST::DatetimeValueFunction
LOCALTIMESTAMP.
Grouping collapse
-
#cube(*columns) ⇒ AST::GroupingSets
GROUP BY CUBE (a, b): every subtotal there is. -
#grouping_sets(*sets) ⇒ AST::GroupingSets
GROUP BY GROUPING SETS ((a), (b), ()): several groupings in one query, an empty set for the grand total. -
#rollup(*columns) ⇒ AST::GroupingSets
GROUP BY ROLLUP (a, b): subtotals up the list and a grand total.
Conversions collapse
-
#cast(expr, type) ⇒ AST::Cast
CAST(expr AS type).
Window functions collapse
-
#cume_dist ⇒ AST::WindowFunction
CUME_DIST(); needsover. -
#dense_rank ⇒ AST::WindowFunction
DENSE_RANK(); needsover. -
#first_value(expr) ⇒ AST::WindowFunction
FIRST_VALUE(expr); needsover. -
#lag(expr, offset = 1, default = nil) ⇒ AST::WindowFunction
LAG(expr, offset, default): the valueoffsetrows before this one; needsover. -
#last_value(expr) ⇒ AST::WindowFunction
LAST_VALUE(expr); needsover. -
#lead(expr, offset = 1, default = nil) ⇒ AST::WindowFunction
LEAD(expr, offset, default): the valueoffsetrows after this one; needsover. -
#nth_value(expr, nth) ⇒ AST::WindowFunction
NTH_VALUE(expr, nth); needsover. -
#ntile(buckets) ⇒ AST::WindowFunction
NTILE(buckets); needsover. -
#percent_rank ⇒ AST::WindowFunction
PERCENT_RANK(); needsover. -
#rank ⇒ AST::WindowFunction
RANK(); needsover. -
#row_number ⇒ AST::WindowFunction
ROW_NUMBER().
Escape hatches collapse
-
#excluded(column) ⇒ AST::Node
The row an upsert could not insert, in the block
upsert_alltakes:"excluded"."column"on PostgreSQL and SQLite,VALUES(column)on MySQL. -
#fn(name, *args) ⇒ AST::Function
Any function by name:
fn(:date_part, "year", :created_at). -
#op(operator, left, right) ⇒ AST::Operation
Any binary operator by its spelling:
op("&&", :tags, "{ruby,sql}"). -
#sql(statement, *binds) ⇒ AST::Sql
SQL as written, the one way a string means SQL inside a block.
-
#value(literal) ⇒ AST::Value
A literal where an expression is expected, quoted like any other value.
Bits collapse
-
#bit_count(expr) ⇒ AST::Function
BIT_COUNT(expr), the bits set in a number.
Subqueries collapse
-
#all(relation) ⇒ AST::Quantified
ALL (subquery), on the right of a comparison: true of the rows the comparison holds for every row of the subquery. -
#any(relation) ⇒ AST::Quantified
ANY (subquery), on the right of a comparison: true of the rows the comparison holds for any row of the subquery. -
#exists?(relation) ⇒ AST::Exists
EXISTS (subquery).
CASE collapse
-
#case(operand = nil) ⇒ AST::Case
CASE, in either shape: with an operand eachwhenis compared against, or without one, eachwhencarrying its own condition. -
#case_when(value = nil, &block) ⇒ AST::Case::When
The searched
CASE, started at its firstwhen: eachwhenis a condition, as a value or a block, andthenandelsegive the values.
Instance Method Summary collapse
-
#initialize(model) ⇒ BlockContext
constructor
private
The model is only consulted to learn which adapter the query is being built for, which is what decides how a scalar function is spelled.
Constructor Details
#initialize(model) ⇒ BlockContext
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
The model is only consulted to learn which adapter the query is being built for, which is what decides how a scalar function is spelled.
166 167 168 |
# File 'lib/active_record/refined.rb', line 166 def initialize(model) @model = model end |
Instance Method Details
#abs(x) ⇒ AST::Function
ABS(x).
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#acos(x) ⇒ AST::Function
ACOS(x).
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#all(relation) ⇒ AST::Quantified
ALL (subquery), on the right of a comparison: true of the rows the
comparison holds for every row of the subquery. SQLite has none.
714 715 716 |
# File 'lib/active_record/refined.rb', line 714 def all(relation) quantified("ALL", relation) end |
#any(relation) ⇒ AST::Quantified
ANY (subquery), on the right of a comparison: true of the rows the
comparison holds for any row of the subquery. SQLite has none.
ANY and ALL quantify a comparison over a subquery, which is what a
scalar subquery cannot do: it has to return the one row. == any
is IN and != all is NOT IN, so what these add is the four
comparisons IN has no spelling for.
704 705 706 |
# File 'lib/active_record/refined.rb', line 704 def any(relation) quantified("ANY", relation) end |
#asin(x) ⇒ AST::Function
ASIN(x).
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#atan(x) ⇒ AST::Function
ATAN(x).
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#atan2(y, x) ⇒ AST::Function
ATAN2(y, x): ATN2 on SQL Server.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#avg(column, distinct: false) ⇒ AST::Aggregate
AVG(column), or AVG(DISTINCT column).
185 186 187 |
# File 'lib/active_record/refined.rb', line 185 AGGREGATE_FUNCTIONS = { sum: :sum, avg: :average, min: :minimum, max: :maximum, }.freeze |
#bit_and(column) ⇒ AST::Function
BIT_AND(column), an aggregate. PostgreSQL and MySQL have it.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#bit_count(expr) ⇒ AST::Function
BIT_COUNT(expr), the bits set in a number. MySQL and PostgreSQL
have it; SQLite, Oracle and SQL Server do not.
MySQL counts the bits of a number; PostgreSQL counts those of a bit
string, so the argument is cast, and to bit(64) because that is what
makes a negative come back as MySQL has it -- 64 bits of two's
complement rather than as many as the column happens to be wide.
676 677 678 |
# File 'lib/active_record/refined.rb', line 676 def bit_count(expr) dialect.bit_count(expr, @model) end |
#bit_or(column) ⇒ AST::Function
BIT_OR(column), an aggregate. PostgreSQL and MySQL have it.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#bit_xor(column) ⇒ AST::Function
BIT_XOR(column), an aggregate. PostgreSQL and MySQL have it.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#case(operand = nil) ⇒ AST::Case
CASE, in either shape: with an operand each when is compared
against, or without one, each when carrying its own condition.
case is a keyword, so this one is reached as self.case; the
shorthands :age.when(...) and #case_when need no receiver.
765 766 767 |
# File 'lib/active_record/refined.rb', line 765 def case(operand = nil) AST::Case.new(operand) end |
#case_when(value = nil, &block) ⇒ AST::Case::When
The searched CASE, started at its first when: each when is a
condition, as a value or a block, and then and else give the
values.
776 777 778 |
# File 'lib/active_record/refined.rb', line 776 def case_when(value = nil, &block) AST::Case.new.when(value, &block) end |
#cast(expr, type) ⇒ AST::Cast
CAST(expr AS type). The type is the adapter's own name for it --
decimal(10,2), double precision -- and has to look like one;
whether it exists is the database's to say.
557 558 559 |
# File 'lib/active_record/refined.rb', line 557 def cast(expr, type) AST::Cast.new(expr, type) end |
#ceil(x) ⇒ AST::Function
CEIL(x): CEILING on SQL Server.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#char_length(string) ⇒ AST::Function
CHAR_LENGTH(string): LENGTH on SQLite and Oracle, LEN on SQL Server.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#coalesce(*values) ⇒ AST::Function
COALESCE(a, b, ...): the first that is not NULL.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#concat(*strings) ⇒ AST::Function
CONCAT(a, b, ...). Oracle's takes exactly two.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#cos(x) ⇒ AST::Function
COS(x).
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#count(column, distinct: false) ⇒ AST::Aggregate
COUNT(column); :* for COUNT(*), distinct: true for
COUNT(DISTINCT column). Every aggregate takes AST::Aggregate#filter
for the rows it is taken over, and AST::Windowing#over for a window.
211 212 213 |
# File 'lib/active_record/refined.rb', line 211 def count(column, distinct: false) AST::Aggregate.new(column, :count, distinct: distinct) end |
#cube(*columns) ⇒ AST::GroupingSets
GROUP BY CUBE (a, b): every subtotal there is. PostgreSQL has it;
the others do not.
543 544 545 |
# File 'lib/active_record/refined.rb', line 543 def cube(*columns) grouping(:cube, columns) end |
#cume_dist ⇒ AST::WindowFunction
CUME_DIST(); needs over.
596 597 598 |
# File 'lib/active_record/refined.rb', line 596 %i[row_number rank dense_rank percent_rank cume_dist].each do |name| define_method(name) { AST::WindowFunction.new(name.to_s.upcase, []) } end |
#current_date ⇒ AST::DatetimeValueFunction
CURRENT_DATE, today in the session's zone -- UTC where Active
Record has set it so. Takes no precision. SQL Server has none.
470 471 472 |
# File 'lib/active_record/refined.rb', line 470 def current_date AST::DatetimeValueFunction.new(dialect.function_name(:current_date, @model)) end |
#current_time(precision = nil) ⇒ AST::DatetimeValueFunction
CURRENT_TIME. SQL Server has none.
461 462 463 |
# File 'lib/active_record/refined.rb', line 461 DATETIME_VALUE_FUNCTIONS = %i[ current_date current_time current_timestamp localtime localtimestamp ].freeze |
#current_timestamp(precision = nil) ⇒ AST::DatetimeValueFunction
CURRENT_TIMESTAMP, the server's clock in the session's zone; the
portable spelling of what #now means. A precision --
current_timestamp(3) -- goes into parentheses, which SQLite and
SQL Server refuse.
461 462 463 |
# File 'lib/active_record/refined.rb', line 461 DATETIME_VALUE_FUNCTIONS = %i[ current_date current_time current_timestamp localtime localtimestamp ].freeze |
#date_trunc(field, timestamp) ⇒ AST::Function
date_trunc('day', timestamp). PostgreSQL has it; the others do not.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#degrees(x) ⇒ AST::Function
DEGREES(x). Oracle has none.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#dense_rank ⇒ AST::WindowFunction
DENSE_RANK(); needs over.
596 597 598 |
# File 'lib/active_record/refined.rb', line 596 %i[row_number rank dense_rank percent_rank cume_dist].each do |name| define_method(name) { AST::WindowFunction.new(name.to_s.upcase, []) } end |
#excluded(column) ⇒ AST::Node
The row an upsert could not insert, in the block upsert_all takes:
"excluded"."column" on PostgreSQL and SQLite, VALUES(column) on
MySQL.
750 751 752 |
# File 'lib/active_record/refined.rb', line 750 def excluded(column) dialect.excluded(column, @model) end |
#exists?(relation) ⇒ AST::Exists
EXISTS (subquery). The subquery is a relation, which may refer to
the outer row through a qualified column.
689 690 691 |
# File 'lib/active_record/refined.rb', line 689 def exists?(relation) AST::Exists.new(relation) end |
#exp(x) ⇒ AST::Function
EXP(x).
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#extract(field, expr) ⇒ AST::Extract
EXTRACT(field FROM expr): a year, a month, a day of a date. The
field is a keyword and has to be a plain name. SQLite and SQL Server
have none.
The field is a keyword, not a value, so it has to be a plain name;
the node checks it. SQLite spells all of this as strftime formats,
which no renaming carries, so it raises there -- after the node is
built, so that a bad field is an ArgumentError on every adapter.
501 502 503 504 505 506 507 508 |
# File 'lib/active_record/refined.rb', line 501 def extract(field, expr) node = AST::Extract.new(field, expr) unless dialect.extract_supported? raise NotImplementedError, "extract has no equivalent on #{@model.connection_db_config.adapter}" end node end |
#first_value(expr) ⇒ AST::WindowFunction
FIRST_VALUE(expr); needs over.
596 597 598 |
# File 'lib/active_record/refined.rb', line 596 %i[row_number rank dense_rank percent_rank cume_dist].each do |name| define_method(name) { AST::WindowFunction.new(name.to_s.upcase, []) } end |
#floor(x) ⇒ AST::Function
FLOOR(x).
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#fn(name, *args) ⇒ AST::Function
Any function by name: fn(:date_part, "year", :created_at). The name
is written as given -- so a case-sensitive one can be spelled exactly
-- and has to be a plain name, optionally qualified by a schema;
the arguments are quoted as values unless they are columns or
expressions.
The name is emitted as written, so a case-sensitive one can be
spelled exactly, and for that reason it has to be a plain name,
optionally qualified by a schema; anything else is refused rather
than written into the SQL.
646 647 648 649 |
# File 'lib/active_record/refined.rb', line 646 def fn(name, *args) AST::Function.new( AST.check_name(name, AST::FUNCTION_NAME, "function name").to_s, args) end |
#format(template, *values) ⇒ AST::Function
printf-style FORMAT(template, ...). PostgreSQL and SQLite have it; MySQL's FORMAT is a different function, reached through #fn.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#greatest(*values) ⇒ AST::Function
GREATEST(a, b, ...): MAX on SQLite.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#grouping_sets(*sets) ⇒ AST::GroupingSets
GROUP BY GROUPING SETS ((a), (b), ()): several groupings in one
query, an empty set for the grand total. PostgreSQL has it; the
others do not.
Arel has the nodes and writes them for PostgreSQL alone, so what it
would raise elsewhere says nothing; this says it here, as extract
does, while the block is being read.
524 525 526 |
# File 'lib/active_record/refined.rb', line 524 def grouping_sets(*sets) grouping(:grouping_sets, sets) end |
#json_array(*values) ⇒ AST::JsonBuild
A JSON array built in the row from the values given. SQL Server spells the pair its own way and is not carried yet.
256 257 258 |
# File 'lib/active_record/refined.rb', line 256 def json_array(*values) AST::JsonBuild.new(:array, values) end |
#json_arrayagg(value) ⇒ AST::JsonAggregate
The rows of a group gathered into one JSON array, a value from each:
jsonb_agg on PostgreSQL, json_group_array on SQLite,
JSON_ARRAYAGG on the MySQL family and Oracle; SQL Server has none.
What it gives is JSON, which compares as a dug value does.
222 223 224 |
# File 'lib/active_record/refined.rb', line 222 def json_arrayagg(value) AST::JsonAggregate.new(:arrayagg, [value]) end |
#json_object(pairs = {}) ⇒ AST::JsonBuild
A JSON object built in the row from a hash whose values are expressions. SQL Server spells the pair its own way and is not carried yet.
267 268 269 |
# File 'lib/active_record/refined.rb', line 267 def json_object(pairs = {}) AST::JsonBuild.new(:object, pairs) end |
#json_objectagg(key, value) ⇒ AST::JsonAggregate
The rows of a group gathered into one JSON object, a key and a value from each, named as #json_arrayagg is; SQL Server has none.
231 232 233 |
# File 'lib/active_record/refined.rb', line 231 def json_objectagg(key, value) AST::JsonAggregate.new(:objectagg, [key, value]) end |
#lag(expr, offset = 1, default = nil) ⇒ AST::WindowFunction
LAG(expr, offset, default): the value offset rows before this
one; needs over.
The offset is written out rather than left to default, so that a
default value cannot end up where the offset belongs.
618 619 620 |
# File 'lib/active_record/refined.rb', line 618 def lag(expr, offset = 1, default = nil) AST::WindowFunction.new("LAG", default.nil? ? [expr, offset] : [expr, offset, default]) end |
#last_value(expr) ⇒ AST::WindowFunction
LAST_VALUE(expr); needs over.
596 597 598 |
# File 'lib/active_record/refined.rb', line 596 %i[row_number rank dense_rank percent_rank cume_dist].each do |name| define_method(name) { AST::WindowFunction.new(name.to_s.upcase, []) } end |
#lead(expr, offset = 1, default = nil) ⇒ AST::WindowFunction
LEAD(expr, offset, default): the value offset rows after this
one; needs over.
625 626 627 |
# File 'lib/active_record/refined.rb', line 625 def lead(expr, offset = 1, default = nil) AST::WindowFunction.new("LEAD", default.nil? ? [expr, offset] : [expr, offset, default]) end |
#least(*values) ⇒ AST::Function
LEAST(a, b, ...): MIN on SQLite.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#length(string) ⇒ AST::Function
LENGTH(string): LEN on SQL Server. What it counts is the
family's own -- bytes on MySQL, characters elsewhere, and LEN
leaves trailing spaces out; #char_length is the portable count.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#ln(x) ⇒ AST::Function
LN(x): LOG on SQL Server.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#localtime(precision = nil) ⇒ AST::DatetimeValueFunction
LOCALTIME. SQLite and SQL Server have none.
461 462 463 |
# File 'lib/active_record/refined.rb', line 461 DATETIME_VALUE_FUNCTIONS = %i[ current_date current_time current_timestamp localtime localtimestamp ].freeze |
#localtimestamp(precision = nil) ⇒ AST::DatetimeValueFunction
LOCALTIMESTAMP. SQLite and SQL Server have none.
461 462 463 |
# File 'lib/active_record/refined.rb', line 461 DATETIME_VALUE_FUNCTIONS = %i[ current_date current_time current_timestamp localtime localtimestamp ].freeze |
#log(base, x) ⇒ AST::Function
LOG(base, x). SQL Server takes the arguments the other way round, and is refused.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#log10(x) ⇒ AST::Function
LOG10(x). Oracle has none.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#log2(x) ⇒ AST::Function
LOG2(x). PostgreSQL and Oracle have none -- log(2, x) is their spelling -- and SQL Server has neither.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#lower(string) ⇒ AST::Function
LOWER(string).
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#ltrim(string) ⇒ AST::Function
LTRIM(string).
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#max(column) ⇒ AST::Aggregate
MAX(column).
185 186 187 |
# File 'lib/active_record/refined.rb', line 185 AGGREGATE_FUNCTIONS = { sum: :sum, avg: :average, min: :minimum, max: :maximum, }.freeze |
#min(column) ⇒ AST::Aggregate
MIN(column).
185 186 187 |
# File 'lib/active_record/refined.rb', line 185 AGGREGATE_FUNCTIONS = { sum: :sum, avg: :average, min: :minimum, max: :maximum, }.freeze |
#mod(x, y) ⇒ AST::Function
MOD(x, y). SQL Server has only the % operator.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#now ⇒ AST::Function
NOW(). SQLite, Oracle and SQL Server have none; #current_timestamp reaches all three.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#nth_value(expr, nth) ⇒ AST::WindowFunction
NTH_VALUE(expr, nth); needs over.
606 607 608 |
# File 'lib/active_record/refined.rb', line 606 def nth_value(expr, nth) AST::WindowFunction.new("NTH_VALUE", [expr, nth]) end |
#ntile(buckets) ⇒ AST::WindowFunction
NTILE(buckets); needs over.
596 597 598 |
# File 'lib/active_record/refined.rb', line 596 %i[row_number rank dense_rank percent_rank cume_dist].each do |name| define_method(name) { AST::WindowFunction.new(name.to_s.upcase, []) } end |
#nullif(x, y) ⇒ AST::Function
NULLIF(x, y): NULL where the two are equal, x otherwise.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#op(operator, left, right) ⇒ AST::Operation
Any binary operator by its spelling: op("&&", :tags, "{ruby,sql}").
The operator has to be made of operator characters; the operands are
quoted as values unless they are columns or expressions, and
parenthesized, since the operator's precedence is not known.
659 660 661 |
# File 'lib/active_record/refined.rb', line 659 def op(operator, left, right) AST::Operation.new(operator, left, right) end |
#percent_rank ⇒ AST::WindowFunction
PERCENT_RANK(); needs over.
596 597 598 |
# File 'lib/active_record/refined.rb', line 596 %i[row_number rank dense_rank percent_rank cume_dist].each do |name| define_method(name) { AST::WindowFunction.new(name.to_s.upcase, []) } end |
#pi ⇒ AST::Function
PI(). Oracle has none.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#power(x, y) ⇒ AST::Function
POWER(x, y).
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#radians(x) ⇒ AST::Function
RADIANS(x). Oracle has none.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#rand ⇒ AST::Function
RAND(), a random number per row: RANDOM() on PostgreSQL and SQLite. Oracle and SQL Server have none.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#rank ⇒ AST::WindowFunction
RANK(); needs over.
596 597 598 |
# File 'lib/active_record/refined.rb', line 596 %i[row_number rank dense_rank percent_rank cume_dist].each do |name| define_method(name) { AST::WindowFunction.new(name.to_s.upcase, []) } end |
#replace(string, from, to) ⇒ AST::Function
REPLACE(string, from, to).
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#rollup(*columns) ⇒ AST::GroupingSets
GROUP BY ROLLUP (a, b): subtotals up the list and a grand total.
PostgreSQL has it, and the MySQL family as WITH ROLLUP trailing
the group list, which the node spells there.
534 535 536 |
# File 'lib/active_record/refined.rb', line 534 def rollup(*columns) grouping(:rollup, columns) end |
#round(x, places = 0) ⇒ AST::Function
ROUND(x, places).
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#row_number ⇒ AST::WindowFunction
ROW_NUMBER(). Means nothing without AST::Windowing#over, and
says so.
596 597 598 |
# File 'lib/active_record/refined.rb', line 596 %i[row_number rank dense_rank percent_rank cume_dist].each do |name| define_method(name) { AST::WindowFunction.new(name.to_s.upcase, []) } end |
#rtrim(string) ⇒ AST::Function
RTRIM(string).
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#sign(x) ⇒ AST::Function
SIGN(x).
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#sin(x) ⇒ AST::Function
SIN(x).
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#sql(statement, *binds) ⇒ AST::Sql
SQL as written, the one way a string means SQL inside a block. ?
and :name placeholders take quoted values, as where takes them.
728 729 730 |
# File 'lib/active_record/refined.rb', line 728 def sql(statement, *binds) AST::Sql.new(statement, binds) end |
#sqrt(x) ⇒ AST::Function
SQRT(x).
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#string_agg(value, separator = ",") ⇒ AST::StringAggregate
The strings of a group joined into one, a separator between:
STRING_AGG on PostgreSQL and SQL Server, group_concat on SQLite,
GROUP_CONCAT on MySQL, LISTAGG on Oracle. Takes
AST::StringAggregate#order for the order they are joined in.
244 245 246 |
# File 'lib/active_record/refined.rb', line 244 def string_agg(value, separator = ",") AST::StringAggregate.new(value, separator) end |
#substr(string, from, length = nil) ⇒ AST::Function
SUBSTR(string, from, length): SUBSTRING on SQL Server, which insists on the length.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#sum(column, distinct: false) ⇒ AST::Aggregate
SUM(column), or SUM(DISTINCT column).
185 186 187 |
# File 'lib/active_record/refined.rb', line 185 AGGREGATE_FUNCTIONS = { sum: :sum, avg: :average, min: :minimum, max: :maximum, }.freeze |
#tan(x) ⇒ AST::Function
TAN(x).
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#trim(string) ⇒ AST::Function
TRIM(string).
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#trunc(x, places = 0) ⇒ AST::Function
TRUNC(x, places): TRUNCATE on MySQL, which insists on the places. SQL Server has none.
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#upper(string) ⇒ AST::Function
UPPER(string).
418 419 420 421 422 423 |
# File 'lib/active_record/refined.rb', line 418 SCALAR_FUNCTIONS = %i[ abs acos asin atan atan2 ceil coalesce concat cos exp floor length ln log lower ltrim mod nullif power replace round rtrim sign sin sqrt substr tan trim upper degrees radians pi char_length greatest least log2 log10 trunc now bit_and bit_or bit_xor date_trunc rand format ].freeze |
#value(literal) ⇒ AST::Value
A literal where an expression is expected, quoted like any other
value. A number or a string takes as for itself -- 0.as(:depth)
-- so this is the spelling for the rest: true, nil, a date.
739 740 741 |
# File 'lib/active_record/refined.rb', line 739 def value(literal) AST::Value.new(literal) end |