Commit Graph

160 Commits

Author SHA1 Message Date
Eileen M. Uchitelle
d90d3894cd
Merge pull request #45642 from kbrock/quoted_columns
[ActiveRecord] ToSql#HomogeneousIn uses visitor pattern to produce Attribute sql
2023-03-03 09:09:27 -05:00
Matt McMurray
e39b859b87
Replace call to BINARY with CAST(_ AS BINARY) (#47523)
* 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>
2023-02-28 16:15:44 -05:00
Matthew Draper
31f5cb18fa
Merge pull request #47495 from olefriis/use-same-binding-grammar-for-arel-as-for-active-record
Use same rules for bindings in BoundSqlLiteral as in ActiveRecord
2023-03-01 00:38:13 +10:30
Keenan Brock
07d2407bee
Use visitor pattern in ToSql#HomogeneousIn to produce Attribute sql
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.
2023-02-27 17:11:14 -05:00
Ole Friis Østergaard
03f2a2c331 Use same rules for bindings in BoundSqlLiteral as in ActiveRecord 2023-02-24 13:28:00 +00:00
Ole Friis Østergaard
584ad87572 Support Arel nodes as bindings in BoundSqlLiteral 2023-02-24 08:49:37 +00:00
Matthew Draper
24b400f55d Accept nodes directly in AbstractAdapter#to_sql
Previously this would generally always see a SelectManager or similar,
but BoundSqlLiteral is reasonable too.
2023-01-29 18:35:32 +10:30
Matthew Draper
f71fc8312b Disallow Arel.sql with mixed named and positional binds
This should be a much closer match to the existing AR sanitize_sql
behaviour.
2023-01-29 08:40:30 +10:30
Matthew Draper
68c5dedea7 Implement + for BoundSqlLiteral too 2023-01-29 08:40:30 +10:30
Matthew Draper
ea36714375 Cast bound values in Arel.sql
This applies the MySQL integer quoting behaviour even when we're using
bind values rather than interpolation.
2023-01-29 08:40:30 +10:30
Matthew Draper
6444ec0d30 Allow Arel.sql to accept bind parameters
Co-authored-by: Ahmed Shahin <codeminator@github.com>
2023-01-29 08:40:30 +10:30
Ole Friis
06ef7a95ac Add ability to concatenate Arel.sql fragments 2023-01-19 09:27:05 +00:00
Yasuo Honda
2a2a6ab621
Merge pull request #46484 from RubyElders/leading-join-node-namespace
Move Arel::Nodes::LeadingJoin into arel.
2022-11-16 15:06:02 +09:00
Josef Šimánek
e27c419d44 Add nodoc to Arel filter classes.
- this makes it consistent with other Arel files
2022-11-13 01:34:30 +01:00
Josef Šimánek
53ce2bca68 Move Arel::Nodes::LeadingJoin into arel.
- this way it is properly hidden from API documentation
2022-11-13 01:23:29 +01:00
John Hawthorn
80a0eca40b Speed up arel visitor dispatch
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.
2022-09-02 12:33:20 -07:00
ignacio chiazzo
989d53ba3b Use nested queries when doing DELETE and GROUP_BY and HAVINAG clauses present.
MySQL does not support GROUP_BY and HAVING on UPDATE, we need to use a Subquery.

Co-authored-by: Rafael Mendonça França <rafael@franca.dev>
2021-11-01 21:39:20 -04:00
ignacio chiazzo
4acb6660e2 Use nested queries when doing UPDATE in myslq and GROUP_BY and HAVING clauses are present.
MySQL does not support GROUP_BY and HAVING on UPDATE, we need to use a Subquery.
2021-11-01 13:27:44 -04:00
Fabian Schwahn
92604518d1 Properly handle impossible cases in (not_)between
Fixes #43521
2021-10-26 05:55:03 +00:00
Rafael Mendonça França
21c6c225a3
Merge PR #40491 2021-10-14 20:46:08 +00:00
eileencodes
311d0babfb
Remove "stupid" from active record
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.
2021-07-28 11:09:10 -04:00
Andrey Novikov
a738295805
Arel: Add support for FILTER clause (SQL:2003)
Currently supported by PostgreSQL 9.4+ and SQLite 3.30+

See:

 - http://modern-sql.com/feature/filter
 - https://www.postgresql.org/docs/9.4/static/sql-expressions.html#SYNTAX-AGGREGATES
 - https://sqlite.org/lang_aggfunc.html#aggfilter

Example:

    Model.all.pluck(
      Arel.star.count.as('records_total').to_sql,
      Arel.star.count.filter(Model.arel_table[:some_column].not_eq(nil)).as('records_filtered').to_sql,
    )
2021-07-20 15:17:04 +03:00
Keenan Brock
b775f0cbdc Support NullsFirst for all databases.
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
2021-05-18 16:58:21 -04:00
Mike Dalessio
685cf03f6c
Revert "un-extract the Arel visitor for SelectOptions"
This reverts commit d803b9ae9bdfb1c8643c1b463cf9af42ad6a1cb5.

See https://github.com/rsim/oracle-enhanced/issues/2186 for evidence
that this private method is being used by the Oracle12 sql visitor.
2021-05-11 09:58:12 -04:00
Mike Dalessio
d478b0f907
Arel::Visitors::Dot renders all attributes of some AST node types
These node types were missing some properties:

- SelectCore
- SelectStatement
- InsertStatement
- UpdateStatement
- DeleteStatement

Fixes #42026
2021-05-03 09:35:23 -04:00
Mike Dalessio
c4fc11a3b2
add support to Arel::Visitors::Dot for some missing AST node types
- 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.
2021-05-03 09:31:28 -04:00
Mike Dalessio
b3b1f5ffe1
use Arel::Visitors::Dot#visit_edge where it would simplify 2021-05-02 15:44:31 -04:00
Mike Dalessio
c2592ee251
Remove unnecessary method aliases from Arel::Visitors::Dot 2021-05-02 15:44:30 -04:00
Mike Dalessio
5640123d29
simplify 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
2021-05-02 15:42:37 -04:00
Mike Dalessio
d803b9ae9b
un-extract the Arel visitor for SelectOptions
This does not need to be a separate method since a2040ee which removed
the Oracle12 visitor, and essentially reverses the Oracle prefactor
from 8d04c28.
2021-05-02 12:13:22 -04:00
Matheus Richard
c3d7794f16 Replace map + compact with filter_map 2021-04-22 22:08:34 -03:00
Ryuta Kamizono
b5c4af7d52
Merge pull request #41068 from ricardotk002/fix-where-in-stmt-logging
Fix binds logging for "WHERE ... IN ..." statements
2021-03-20 01:41:29 +09:00
Ryuta Kamizono
096719ce2a Move where from TreeManager to SelectManager
`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`.
2021-03-15 23:50:44 +09:00
Ryuta Kamizono
cd809b3176 Improve compile_update and compile_delete
To be used from `update_all` and `delete_all`.
2021-03-15 17:15:35 +09:00
Ryuta Kamizono
168ddaa08a Remove unused Arel::Attributes classes
I missed it in #36493, those classes should also no longer be used since
https://github.com/rails/arel/pull/196.
2021-03-11 11:50:42 +09:00
Ryuta Kamizono
8323fb5251 Fix where with >, >=, <, and <= to return correct result even with a large number
Follow up to #30000.
2021-03-11 11:02:43 +09:00
Ryuta Kamizono
982ed415be
Merge pull request #41640 from bradleypriest/arel-quoting
Quote the arguments passed to the Contains/Overlaps Arel nodes
2021-03-09 05:45:39 +09:00
Bradley Priest
16e45de59e Quote the arguments passed to the new Contains/Overlaps node types to align with the behaviour of existing predicates 2021-03-09 08:05:17 +13:00
Ryuta Kamizono
d9f6027587
Merge pull request #41577 from kamipo/avoid_extra_bind_allocation
Avoid extra `BindParam` allocation to generate placeholder in queries
2021-03-08 17:10:21 +09:00
Ryuta Kamizono
0f917da01a Remove unused accessors left and right on DeleteStatement
Use `relation` and `wheres` instead.
2021-03-08 03:07:25 +09:00
Ryuta Kamizono
c48539ff94 Allow select statement node's initializer takes a table
Like other statement nodes does, related to 333f9b32.
2021-03-08 02:54:10 +09:00
Ryuta Kamizono
333f9b32d9 Allow statement nodes' initializer takes a table
Follow up to #41579.
2021-03-05 02:43:55 +09:00
Ryuta Kamizono
3e34aee881
Merge pull request #41589 from kamipo/remove_crud
Remove `Arel::Crud` from `Arel::Table`
2021-03-03 18:31:16 +09:00
Ryuta Kamizono
64ca6f608e Avoid extra BindParam allocation to generate placeholder in queries
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.
2021-03-02 18:09:05 +09:00
Ryuta Kamizono
cc5f6457cc Remove Arel::Crud from Arel::Table
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.
2021-03-02 17:48:28 +09:00
Ryuta Kamizono
e27063af3a Allow all tree managers' initializer takes a table
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.
2021-03-01 20:47:23 +09:00
Ryuta Kamizono
6d06a657fc Fix binds logging for HomogeneousIn
Make bind attribute if the bind collector is used.

Before:

```
User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" IN (?, ?, ?, ?, ?)  [[nil, 1], [nil, 2], [nil, 3], [nil, 4], [nil, 5]]
```

After:

```
User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" IN (?, ?, ?, ?, ?)  [["id", 1], ["id", 2], ["id", 3], ["id", 4], ["id", 5]]
```

(cherry picked from commit cd1a3705c5f18e431e5311c5dc123ed765752ecf)
2021-02-25 20:37:20 -05:00
Ryuta Kamizono
274f8543e6 Arel::Nodes::BindParam and Arel::Nodes::Quoted are a subclass of the Arel::Nodes::Node 2021-02-24 04:04:48 +09:00
Kevin Deisz
4a13f8ad4f
Properly support reverse_order on relations with nulls_first or nulls_last calls
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.
2020-09-08 11:20:46 -04:00
Ryuta Kamizono
1ac40f16c5 Move Arel attribute normalization into arel_table
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`.
2020-07-19 23:41:24 +09:00