* Replace call to BINARY with CAST(_ AS BINARY)
* Remove space b/w function and quote
Co-authored-by: Rafael Mendonça França <rafael@franca.dev>
* Update unit test to assert for new CAST syntax
---------
Co-authored-by: Rafael Mendonça França <rafael@franca.dev>
In `ToSql`, operators that generate the sql for an `Attribute` use `visit(o.left, collector)`
This can be seen in `Equality` (and friends), `Case`, `SelectStatement`, and `In`.
`HomogeneousIn` manually produces the sql for an `Attribute`, introduced in 72fd0bae
This change makes `HomogeneousIn` follow the pattern.
This commit makes two performance tweaks to the dispatch_cache in
Arel::Visitors::Visitor.
First, it interns the method name into a symbol rather than a string.
send expects a symbol, so this avoids Ruby needing to intern that string
itself.
Second, it changes the dispatch cache to an identity hash. Classes are
already compared by identity, but Ruby is able to perform the lookup
more quickly if it is explicit on the hash.
The language in the docs is clearer without saying MySQL is stupid. The
test doesn't need stupid in the value to be used - an incorrect value is
incorrect.
Most databases order tables with the `NULL` value first, having it before
all other data values. Postgres has `NULLS` last.
Fortunately, ANSI SQL has an option to allow the database to specify where NULLS
come out in this sort order
ORDER BY column ASC NULLS FIRST
MS SQL, SQLite, Oracle, and Postgres all follow this syntax. Unfortunately, MySql
does not.
Before:
PostgreSQL: both `.nulls_first()` and `.nulls_last()` work as designed.
Others: both raise a runtime error.
After:
MySQL: `.nulls_first()` works as designed.
MySQL: `.nulls_last()` raises a runtime error
Others: both work as designed
- Case
- CurrentRow
- Distinct
- InfixOperation
- NotRegexp
- Regexp
- UnaryOperation
- With
Also add test coverage for When and Else for which support was just
added in a previous commit in this changeset.
Also use assert_edge test helper for Arel::Visitors::Dot.
Instead of having many aliases for all the Arel::Nodes classes, rely
on generic methods for Unary, Binary, and Function (which is possible
because Arel::Visitors::Visitor#visit falls back to ancestors' visit
methods).
Note that a few new Node types are now implicitly supported that were
not previously explicitly supported, including:
- Bin
- DistinctOn
- Else
- Except
- Intersect
- Lock
- Quoted
- Union
- UnionAll
- When
This does not need to be a separate method since a2040ee which removed
the Oracle12 visitor, and essentially reverses the Oracle prefactor
from 8d04c28.
`TreeManager` is inherited by `InsertManager` but `where` on
`InsertManager` doesn't work.
And also, remove `@ctx` since the instance variable is used only for the
`SelectManager`.
In the Active Record usage, a `BindParam` object always has an attribute
object as the value. A `BindParam` object is used to call `add_bind` to
generate placeholder if `prepared_statements: true`.
Since Arel is a part of Active Record now, I think that we can regard an
`ActiveModel::Attribute` object as boundable without wrapping it by a
`BindParam` to avoid extra `BindParam` allocation.
Originally `compile_update` and `compile_delete` doesn't work at all on
`Arel::Table` since `Arel::Table` doesn't have `@ast` and `@ctx`.
`compile_insert` and `create_insert` works but do not use the receiver's
information at all, so just use `Arel::InsertManager.new(arel_table)`
instead.
Currently `SelectManager` takes a table (it was happened at 80ad95b),
but other managers does not, even though it is required to generate a
query.
I think that all tree managers' initializer could take a table, like
`SelectManager` already does.
If you're using the `nulls_first` or `nulls_last` functionality with an explicit ordering, then previously it wasn't properly handling calls to `#reverse` (called through `reverse_order`). This commit changes the behavior to match what would be expected.
In Active Record internal, `arel_table` is not directly used but
`arel_attribute` is used, since `arel_table` doesn't normalize an
attribute name as a string, and doesn't resolve attribute aliases.
For the above reason, `arel_attribute` should be used rather than
`arel_table`, but most people directly use `arel_table`, both
`arel_table` and `arel_attribute` are private API though.
Although I'd not recommend using private API, `arel_table` is actually
widely used, and it is also problematic for unscopeable queries and
hash-like relation merging friendly, as I explained at #39863.
To resolve the issue, this change moves Arel attribute normalization
(attribute name as a string, and attribute alias resolution) into
`arel_table`.