diff --git a/README.md b/README.md index accc1f3..c110154 100644 --- a/README.md +++ b/README.md @@ -26,11 +26,12 @@ Or install it yourself as: ## Usage -Just `require 'postgres_ext'` and use ActiveRecord as you normally would! postgres_ext extends +Just `require 'postgres_ext'` and use ActiveRecord as you normally would! postgres\_ext extends ActiveRecord's data type handling. * [Migration/Schema.rb support](#migrationschemarb-support) * [Type Casting support](#type-casting-support) + * [Querying PostgreSQL datatypes](#querying-postgresql-datatypes) ### Usage Notes Take care when dealing with arrays and other types that allow you to @@ -157,6 +158,74 @@ person_2.favorite_numbers.first.class # => Fixnum ``` +## Querying PostgreSQL datatypes + + * Arrays + * INET/CIDR + +### Arrays + + * && - Array Overlap operator + * ANY or ALL functions + +#### && - Array Overlap operator + +PostgreSQL implements the `&&` operator, known as the overlap operator, +for arrays. The overlap operator returns `t` (true) when two arrays have +one or more elements in common. + +```sql +ARRAY[1,2,3] && ARRAY[4,5,6] +-- f + +ARRAY[1,2,3] && ARRAY[3,5,6] +-- t +``` + +Postgres\_ext defines `array_overlap`, an ARel predicate for the `&&` operator. + +```ruby +user_arel = User.arel_table + +User.where(user_arel[:tags].array_overlap(['one','two'])).to_sql +# => SELECT \"users\".* FROM \"users\" WHERE \"users\".\"tags\" && '{one,two}' +``` + +#### ANY or ALL function + +When querying array columns, you have the ability to see if a predicate +apply's to either *any* element in the array, or *all* elements of the +array. The syntax for these predicates are slightly different then the +normal `where` syntax in PostgreSQL. To see if an array contains the +string `'test'` in any location, you would write the following in SQL + +```sql +SELECT * +FROM users +WHERE 'test' = ANY(users.tags) +``` + +Notice that the column is on the right hand side of the predicate, +instead of the left, because we have to call the `ANY` function on that +column. + +We can generate the above query using [Arel](https://github.com/rails/arel) +and generating the Node manually. We would use the following to +accompish this: + +```ruby +user_arel = User.arel_table + +any_tags_function = Arel::Nodes::NamedFunction.new('ANY', [user_arel[:tags]]) +predicate = Arel::Nodes::Equality('test', any_tags_function) + +User.where(predicate).to_sql +#=> SELECT \"users\".* FROM \"users\" WHERE 'test' = ANY(\"users\".\"tags\") + +``` + +The ALL version of this same predicate can be generated by swap `'ANY'` +for `'ALL'` in the named function. ## Authors