Class: ActiveRecord::Refined::Dialect::Postgresql
- Inherits:
-
Dialect
- Object
- Dialect
- ActiveRecord::Refined::Dialect::Postgresql
- Defined in:
- lib/active_record/refined/dialect/postgresql.rb
Overview
PostgreSQL, and the adapters that answer for the same server.
Instance Method Summary collapse
- #array_comparisons_supported? ⇒ Boolean
-
#bit_count(expr, _model) ⇒ Object
PostgreSQL counts the bits of a bit string rather than a number, so the argument is cast, to bit(64) for a negative to come back as the MySQL family has it.
- #bitwise_operators_supported? ⇒ Boolean
-
#bitwise_xor(left, right) ⇒ Object
PostgreSQL's XOR is #, where ^ is exponentiation.
-
#collate(operand, name, model) ⇒ Object
PostgreSQL's own collation names are case-sensitive and upper, "C", "POSIX", so the name is quoted as an identifier to keep it from folding to lower case.
- #excluded(column, _model) ⇒ Object
- #grouping_supported?(_kind) ⇒ Boolean
- #json_aggregate_name(kind) ⇒ Object
- #json_build(kind, keys, args, _model) ⇒ Object
-
#json_build_argument(value, _model) ⇒ Object
jsonb_build_* takes typed arguments, so a JSON literal is cast; left untyped it would be text, and land as a string.
- #json_contains(document, json, _model) ⇒ Object
-
#json_has_key(document, name, _path, _model) ⇒ Object
The ? operator, which a GIN index matches where jsonb_exists never is.
- #json_keys(document, model) ⇒ Object
-
#json_literal(json, _model) ⇒ Object
An untyped JSON literal beside a jsonb operand coerces to jsonb, so it passes as it is.
- #json_path(document, _dollar_path, steps, json_value, _model) ⇒ Object
-
#json_remove(document, _dollar_paths, steps, _model) ⇒ Object
jsonb subtracts an array of keys; an untyped array literal would be read as a single key, so it is cast to text.
-
#json_set(document, steps, _dollar_path, value, expression, _model) ⇒ Object
jsonb_set takes jsonb: an expression is turned into it, and a Ruby value goes in as the JSON that says it -- '"x"' rather than 'x'.
-
#string_agg(operand, separator, orders, string, model) ⇒ Object
STRING_AGG takes text and nothing else -- over an integer column it is a function that does not exist -- so the operand is cast unless the model says it is a string already.
Instance Method Details
#array_comparisons_supported? ⇒ Boolean
8 |
# File 'lib/active_record/refined/dialect/postgresql.rb', line 8 def array_comparisons_supported? = true |
#bit_count(expr, _model) ⇒ Object
PostgreSQL counts the bits of a bit string rather than a number, so the argument is cast, to bit(64) for a negative to come back as the MySQL family has it.
17 18 19 |
# File 'lib/active_record/refined/dialect/postgresql.rb', line 17 def bit_count(expr, _model) AST::Function.new("BIT_COUNT", [AST::Cast.new(expr, "bit(64)")]) end |
#bitwise_operators_supported? ⇒ Boolean
9 |
# File 'lib/active_record/refined/dialect/postgresql.rb', line 9 def bitwise_operators_supported? = true |
#bitwise_xor(left, right) ⇒ Object
PostgreSQL's XOR is #, where ^ is exponentiation.
22 23 24 |
# File 'lib/active_record/refined/dialect/postgresql.rb', line 22 def bitwise_xor(left, right) Arel::Nodes::InfixOperation.new("#", left, right) end |
#collate(operand, name, model) ⇒ Object
PostgreSQL's own collation names are case-sensitive and upper, "C", "POSIX", so the name is quoted as an identifier to keep it from folding to lower case. The quoter is asked to spell it, as excluded's VALUES(column) is on MySQL.
119 120 121 122 123 124 |
# File 'lib/active_record/refined/dialect/postgresql.rb', line 119 def collate(operand, name, model) AST.check_name(name, COLLATION_NAME, "collation name") quoted = model.with_connection { |connection| connection.quote_column_name(name) } Arel::Nodes::InfixOperation.new( "COLLATE", operand, Arel::Nodes::SqlLiteral.new(quoted)) end |
#excluded(column, _model) ⇒ Object
26 27 28 |
# File 'lib/active_record/refined/dialect/postgresql.rb', line 26 def excluded(column, _model) AST::Column.new(:excluded, column) end |
#grouping_supported?(_kind) ⇒ Boolean
106 |
# File 'lib/active_record/refined/dialect/postgresql.rb', line 106 def grouping_supported?(_kind) = true |
#json_aggregate_name(kind) ⇒ Object
91 92 93 |
# File 'lib/active_record/refined/dialect/postgresql.rb', line 91 def json_aggregate_name(kind) kind == :arrayagg ? "jsonb_agg" : "jsonb_object_agg" end |
#json_build(kind, keys, args, _model) ⇒ Object
76 77 78 79 80 |
# File 'lib/active_record/refined/dialect/postgresql.rb', line 76 def json_build(kind, keys, args, _model) Arel::Nodes::NamedFunction.new( kind == :array ? "jsonb_build_array" : "jsonb_build_object", json_build_body(kind, keys, args)) end |
#json_build_argument(value, _model) ⇒ Object
jsonb_build_* takes typed arguments, so a JSON literal is cast; left untyped it would be text, and land as a string.
84 85 86 87 88 89 |
# File 'lib/active_record/refined/dialect/postgresql.rb', line 84 def json_build_argument(value, _model) Arel::Nodes::NamedFunction.new( "CAST", [Arel::Nodes::As.new( Arel::Nodes.build_quoted(JSON.generate(value)), Arel::Nodes::SqlLiteral.new("jsonb"))]) end |
#json_contains(document, json, _model) ⇒ Object
41 42 43 |
# File 'lib/active_record/refined/dialect/postgresql.rb', line 41 def json_contains(document, json, _model) Arel::Nodes::Contains.new(document, json) end |
#json_has_key(document, name, _path, _model) ⇒ Object
The ? operator, which a GIN index matches where jsonb_exists never is.
46 47 48 |
# File 'lib/active_record/refined/dialect/postgresql.rb', line 46 def json_has_key(document, name, _path, _model) Arel::Nodes::InfixOperation.new(:"?", document, name) end |
#json_keys(document, model) ⇒ Object
50 51 52 53 54 55 |
# File 'lib/active_record/refined/dialect/postgresql.rb', line 50 def json_keys(document, model) sql = compile(document, model) Arel.sql("CASE WHEN jsonb_typeof(#{sql}) = 'object' " \ "THEN COALESCE((SELECT jsonb_agg(k) FROM jsonb_object_keys(#{sql}) k), " \ "CAST('[]' AS jsonb)) END") end |
#json_literal(json, _model) ⇒ Object
An untyped JSON literal beside a jsonb operand coerces to jsonb, so it passes as it is.
37 38 39 |
# File 'lib/active_record/refined/dialect/postgresql.rb', line 37 def json_literal(json, _model) json end |
#json_path(document, _dollar_path, steps, json_value, _model) ⇒ Object
30 31 32 33 |
# File 'lib/active_record/refined/dialect/postgresql.rb', line 30 def json_path(document, _dollar_path, steps, json_value, _model) Arel::Nodes::InfixOperation.new( json_value ? :"#>" : :"#>>", document, Arel::Nodes.build_quoted(steps)) end |
#json_remove(document, _dollar_paths, steps, _model) ⇒ Object
jsonb subtracts an array of keys; an untyped array literal would be read as a single key, so it is cast to text.
68 69 70 71 72 73 74 |
# File 'lib/active_record/refined/dialect/postgresql.rb', line 68 def json_remove(document, _dollar_paths, steps, _model) keys = Arel::Nodes::NamedFunction.new( "CAST", [Arel::Nodes::As.new( Arel::Nodes.build_quoted(steps), Arel::Nodes::SqlLiteral.new("text[]"))]) # Grouped because - binds tighter than #>. Arel::Nodes::InfixOperation.new(:-, Arel::Nodes::Grouping.new(document), keys) end |
#json_set(document, steps, _dollar_path, value, expression, _model) ⇒ Object
jsonb_set takes jsonb: an expression is turned into it, and a Ruby value goes in as the JSON that says it -- '"x"' rather than 'x'.
59 60 61 62 63 64 |
# File 'lib/active_record/refined/dialect/postgresql.rb', line 59 def json_set(document, steps, _dollar_path, value, expression, _model) set = expression ? Arel::Nodes::NamedFunction.new("to_jsonb", [expression]) : Arel::Nodes.build_quoted(JSON.generate(value)) Arel::Nodes::NamedFunction.new( "jsonb_set", [document, Arel::Nodes.build_quoted(steps), set]) end |
#string_agg(operand, separator, orders, string, model) ⇒ Object
STRING_AGG takes text and nothing else -- over an integer column it is a function that does not exist -- so the operand is cast unless the model says it is a string already.
98 99 100 101 102 103 104 |
# File 'lib/active_record/refined/dialect/postgresql.rb', line 98 def string_agg(operand, separator, orders, string, model) unless string operand = Arel::Nodes::NamedFunction.new( "CAST", [Arel::Nodes::As.new(operand, Arel::Nodes::SqlLiteral.new("text"))]) end string_agg_call("STRING_AGG", operand, separator, orders, model) end |