aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
Commit message (Collapse)AuthorAgeFilesLines
* Allow column name with function (e.g. `length(title)`) as safe SQL stringRyuta Kamizono2019-06-101-2/+8
| | | | | | | | | | | | | | | | Currently, almost all "Dangerous query method" warnings are false alarm. As long as almost all the warnings are false alarm, developers think "Let's ignore the warnings by using `Arel.sql()`, it actually is false alarm in practice.", so I think we should effort to reduce false alarm in order to make the warnings valuable. This allows column name with function (e.g. `length(title)`) as safe SQL string, which is very common false alarm pattern, even in the our codebase. Related 6c82b6c99, 6607ecb2a, #36420. Fixes #32995.
* Allow `column_name AS alias` as safe SQL stringRyuta Kamizono2019-06-101-0/+1
|
* Refactor `disallow_raw_sql!` to avoid `split(/\s*,\s*/)` to order argsRyuta Kamizono2019-06-091-6/+14
| | | | | `split(/\s*,\s*/)` to order args and then `permit.match?` one by one is much slower than `permit.match?` once.
* Allow quoted identifier string as safe SQL stringRyuta Kamizono2019-06-061-0/+22
| | | | | | | | | | | | | Currently `posts.title` is regarded as a safe SQL string, but `"posts"."title"` (it is a result of `quote_table_name("posts.title")`) is regarded as an unsafe SQL string even though a result of `quote_table_name` should obviously be regarded as a safe SQL string, since the column name matcher doesn't respect quotation, it is a little annoying. This changes the column name matcher to allow quoted identifiers as safe SQL string, now all results of the `quote_table_name` are regarded as safe SQL string.
* PostgreSQL: Support endless range values for range typesRyuta Kamizono2019-02-201-1/+1
|
* PostgreSQL: Properly quote all `Infinity` and `NaN`Ryuta Kamizono2018-11-091-4/+4
| | | | Since quoted `Infinity` and `NaN` are valid data for PostgreSQL.
* Correctly handle infinity value in PostgreSQL range typeyuuji.yaginuma2018-01-041-1/+9
| | | | | | | | An empty string is an invalid value in Ruby's range class. So need to handle `Float::INFINITY` as it is and cast it in `encode_range`. Fixes #31612
* `Postgres::OID::Range` serializes to a `Range`, quote in `Quoting`Thomas Cannon2017-09-261-0/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | PostgreSQL 9.1+ introduced range types, and Rails added support for using this datatype in ActiveRecord. However, the serialization of `PostgreSQL::OID::Range` was incomplete, because it did not properly quote the bounds that make up the range. A clear example of this is a `tsrange`. Normally, ActiveRecord quotes Date/Time objects to include the milliseconds. However, the way `PostgreSQL::OID::Range` serialized its bounds, the milliseconds were dropped. This meant that the value was incomplete and not equal to the submitted value. An example of normal timestamps vs. a `tsrange`. Note how the bounds for the range do not include their milliseconds (they were present in the ruby Range): UPDATE "iterations" SET "updated_at" = $1, "range" = $2 WHERE "iterations"."id" = $3 [["updated_at", "2017-09-23 17:07:01.304864"], ["range", "[2017-09-23 00:00:00 UTC,2017-09-23 23:59:59 UTC]"], ["id", 1234]] `PostgreSQL::OID::Range` serialized the range by interpolating a string for the range, which works for most cases, but does not work for timestamps: def serialize(value) if value.is_a?(::Range) from = type_cast_single_for_database(value.begin) to = type_cast_single_for_database(value.end) "[#{from},#{to}#{value.exclude_end? ? ')' : ']'}" else super end end (byebug) from = type_cast_single_for_database(value.begin) 2010-01-01 13:30:00 UTC (byebug) to = type_cast_single_for_database(value.end) 2011-02-02 19:30:00 UTC (byebug) "[#{from},#{to}#{value.exclude_end? ? ')' : ']'}" "[2010-01-01 13:30:00 UTC,2011-02-02 19:30:00 UTC)" @sgrif (the original implementer for Postgres Range support) provided some feedback about where the quoting should occur: Yeah, quoting at all is definitely wrong here. I'm not sure what I was thinking in 02579b5, but what this is doing is definitely in the wrong place. It should probably just be returning a range of subtype.serialize(value.begin) and subtype.serialize(value.end), and letting the adapter handle the rest. `Postgres::OID::Range` now returns a `Range` object, and `ActiveRecord::ConnectionAdapters::PostgreSQL::Quoting` can now encode and quote a `Range`: def encode_range(range) "[#{type_cast(range.first)},#{type_cast(range.last)}#{range.exclude_end? ? ')' : ']'}" end ... encode_range(range) #=> "['2010-01-01 13:30:00.670277','2011-02-02 19:30:00.745125')" This commit includes tests to make sure the milliseconds are preserved in `tsrange` and `tstzrange` columns
* Fix `quote_default_expression` for UUID with array defaultRyuta Kamizono2017-09-081-1/+1
| | | | Fixes #30539.
* Use frozen-string-literal in ActiveRecordKir Shatrov2017-07-191-0/+2
|
* Revert "Merge pull request #29540 from kirs/rubocop-frozen-string"Matthew Draper2017-07-021-1/+0
| | | | | This reverts commit 3420a14590c0e6915d8b6c242887f74adb4120f9, reversing changes made to afb66a5a598ce4ac74ad84b125a5abf046dcf5aa.
* Merge pull request #29540 from kirs/rubocop-frozen-stringMatthew Draper2017-07-021-0/+1
|\ | | | | | | Enforce frozen string in Rubocop
| * Enforce frozen string in RubocopKir Shatrov2017-07-011-0/+1
| |
* | Don't cache queries for schema statementsRyuta Kamizono2017-06-301-1/+1
|/ | | | | | `test_middleware_caches` is sometimes failed since #29454. The failure is due to schema statements are affected by query caching. Bypassing query caching for schema statements to avoid the issue.
* Fix UUID column with `null: true` and `default: nil`Ryuta Kamizono2017-05-301-1/+1
| | | | | | | `quote_default_expression` can be passed nil value when `null: true` and `default: nil`. This addressed in that case. Fixes #29222.
* Make internal methods to privateRyuta Kamizono2017-03-271-0/+3
|
* [PostgreSQL]: Replace deprecated PG constants.Lars Kanis2017-03-221-3/+3
| | | | | The old top level classes PGconn, PGresult and PGError were deprecated since pg-0.13.0: https://github.com/ged/ruby-pg/blob/master/History.rdoc#v0130-2012-02-09-michael-granger-gedfaeriemudorg
* Merge pull request #26630 from kamipo/quoted_binaryRafael França2017-02-131-2/+4
|\ | | | | Extract `quoted_binary` and use it rather than override `_quote`
| * Extract `quoted_binary` and use it rather than override `_quote`Ryuta Kamizono2016-09-271-2/+4
| | | | | | | | | | | | | | Each databases have different binary representation. Therefore all adapters overrides `_quote` for quoting binary. Extract `quoted_binary` for quoting binary and use it rather than override `_quote`.
* | Consistently apply adapter behavior when serializing arraysSean Griffin2017-01-031-0/+29
|/ | | | | | | | | | | | | | | | | | | | | | | | | | In f1a0fa9 we moved backend specific timestamp behavior out of the type and into the adapter. This was in line with our general attempt to reduce the number of adapter specific type subclasses. However, on PG, the array type performs all serialization, including database encoding in its serialize method. This means that we have converted the value into a string before reaching the database, so no adapter specific logic can be applied (and this also means that timestamp arrays were using the default `.to_s` method on the given object, which likely meant timestamps were being ignored in certain cases as well) Ultimately I want to do a more in depth refactoring which separates database serializer objects from the active model type objects, to give us a less awkward API for introducing the attributes API onto Active Model. However, in the short term, we follow the solution we've applied elsewhere for this. Move behavior off of the type and into the adapter, and use a data object to allow the type to communicate information up the stack. Fixes #27514.
* normalizes indentation and whitespace across the projectXavier Noria2016-08-061-30/+30
|
* applies new string literal convention in activerecord/libXavier Noria2016-08-061-1/+1
| | | | | The current code base is not uniform. After some discussion, we have chosen to go with double quotes by default.
* `@quoted_{column,table}_names` should cache a frozen stringRyuta Kamizono2016-07-281-2/+2
| | | | | | | | | | | | | | Caching a mutable string causes the following issue. ``` Loading development environment (Rails 5.1.0.alpha) irb(main):001:0> ActiveRecord::Base.connection.quote_table_name('foo') << '!!' => "`foo`!!" irb(main):002:0> ActiveRecord::Base.connection.quote_table_name('foo') << '!!' => "`foo`!!!!" irb(main):003:0> ActiveRecord::Base.connection.quote_table_name('foo') << '!!' => "`foo`!!!!!!" ```
* systematic revision of =~ usage in ARXavier Noria2016-07-231-1/+1
| | | | | Where appropriatei, prefer the more concise Regexp#match?, String#include?, String#start_with?, or String#end_with?
* Move `@quoted_{column|table}_names` cache up to the abstract adapterRyuta Kamizono2016-03-311-4/+4
|
* Add expression support on the schema defaultRyuta Kamizono2016-01-131-4/+5
| | | | | | | | Example: create_table :posts do |t| t.datetime :published_at, default: -> { 'NOW()' } end
* pg, `create_schema`, `drop_schema` and `rename_table` quote schema name.Yves Senn2015-08-281-0/+5
| | | | | | | | Closes #21418. Previously schema names were not quoted. This leads to issues when a schema names contains a ".". Methods in `schema_statements.rb` should quote user input.
* Move comment about microseconds [ci skip]Ryuta Kamizono2015-05-031-2/+1
| | | | The microseconds handling was already moved to `Quoting#quoted_date`.
* Register adapter specific types with the global type registrySean Griffin2015-02-151-38/+0
| | | | | | We do this in the adapter classes specifically, so the types aren't registered if we don't use that adapter. Constants under the PostgreSQL namespace for example are never loaded if we're using mysql.
* Merge pull request #18888 from kamipo/refactor_quote_default_expressionRafael Mendonça França2015-02-111-2/+4
|\ | | | | Refactor `quote_default_expression`
| * Refactor `quote_default_expression`Ryuta Kamizono2015-02-111-2/+4
| | | | | | | | | | | | | | `quote_default_expression` and `quote_default_value` are almost the same handling for do not quote default function of `:uuid` columns. Rename `quote_default_value` to `quote_default_expression`, and remove duplicate code.
* | Remove most PG specific type subclassesSean Griffin2015-02-111-3/+0
|/ | | | | | | | | The latest version of the PG gem can actually convert the primitives for us in C code, which gives a pretty substantial speed up. A few cases were only there to add the `infinity` method, which I just put on the range type (which is the only place it was used). Floats also needed to parse `Infinity` and `NaN`, but it felt reasonable enough to put that on the generic form.
* Allow a symbol to be passed to `attribute`, in place of a type objectSean Griffin2015-02-061-0/+41
| | | | | | | | | | | | | | | | | | The same is not true of `define_attribute`, which is meant to be the low level no-magic API that sits underneath. The differences between the two APIs are: - `attribute` - Lazy (the attribute will be defined after the schema has loaded) - Allows either a type object or a symbol - `define_attribute` - Runs immediately (might get trampled by schema loading) - Requires a type object This was the last blocker in terms of public interface requirements originally discussed for this feature back in May. All the implementation blockers have been cleared, so this feature is probably ready for release (pending one more look-over by me).
* Remove most uses of `Column#cast_type`Sean Griffin2015-01-301-1/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The goal is to remove the type object from the column, and remove columns from the type casting process entirely. The primary motivation for this is clarity. The connection adapter does not have sufficient type information, since the type we want to work with might have been overriden at the class level. By taking this object from the column, it is easy to mistakenly think that the column object which exists on the connection adapter is sufficient. It isn't. A concrete example of this is `serialize`. In 4.2 and earlier, `where` worked in a very inconsistent and confusing manner. If you passed a single value to `where`, it would serialize it before querying, and do the right thing. However, passing it as part of an array, hash, or range would cause it to not work. This is because it would stop using prepared statements, so the type casting would come from arel. Arel would have no choice but to get the column from the connection adapter, which would treat it as any other string column, and query for the wrong value. There are a handful of cases where using the column object to find the cast type is appropriate. These are cases where there is not actually a class involved, such as the migration DSL, or fixtures. For all other cases, the API should be designed as such that the type is provided before we get to the connection adapter. (For an example of this, see the work done to decorate the arel table object with a type caster, or the introduction of `QueryAttribute` to `Relation`). There are times that it is appropriate to use information from the column to change behavior in the connection adapter. These cases are when the primitive used to represent that type before it goes to the database does not sufficiently express what needs to happen. An example of this that affects every adapter is binary vs varchar, where the primitive used for both is a string. In this case it is appropriate to look at the column object to determine which quoting method to use, as this is something schema dependent. An example of something which would not be appropriate is to look at the type and see that it is a datetime, and performing string parsing when given a string instead of a date. This is the type of logic that should live entirely on the type. The value which comes out of the type should be a sufficiently generic primitive that the adapter can be expected to know how to work with it. The one place that is still using the column for type information which should not be necessary is the connection adapter type caster which is sometimes given to the arel table when we can't find the associated table. This will hopefully go away in the near future.
* Stop passing the column to the `quote` method when quoting defaultsRyuta Kamizono2015-01-041-1/+2
| | | | Related the commit 8f8f8058e58dda20259c1caa61ec92542573643d.
* Refactor `quoted_date`Ryuta Kamizono2014-12-111-7/+3
| | | | Move microseconds formatting to `AbstractAdapter`.
* Move PG float quoting to the correct locationSean Griffin2014-11-251-16/+6
| | | | | Not sure how we missed this case when we moved everything else to the `_quote` method.
* Remove redundant `to_s` in interpolationclaudiob2014-10-301-1/+1
|
* Don't rely on the column SQL type for bit string quotingSean Griffin2014-07-111-13/+7
|
* Merge pull request #16071 from sgrif/sg-pg-type-castRafael Mendonça França2014-07-081-15/+0
|\ | | | | Remove PG's definition of `type_cast`
| * Remove PG's definition of `type_cast`Sean Griffin2014-07-061-15/+0
| | | | | | | | | | All cases except for `nil` in an array have been removed. `nil` in an array is handled by the Array type object.
* | Don't rely on the sql type to quote XML columns in PGSean Griffin2014-07-061-3/+8
|/
* Use the type object for quoting PG RangesSean Griffin2014-07-051-13/+0
|
* Merge pull request #16037 from sgrif/sg-money-quotingRafael Mendonça França2014-07-041-7/+0
|\ | | | | Remove unneccessary special case for money in quoting
| * Remove unneccessary special case for money in quotingSean Griffin2014-07-031-7/+0
| |
* | Merge pull request #16036 from sgrif/sg-datetime-infinityRafael Mendonça França2014-07-031-3/+1
|\ \ | | | | | | Do not rely on the column type when quoting infinity
| * | Do not rely on the column type when quoting infinitySean Griffin2014-07-031-3/+1
| |/
* / Use the type object for type casting HStore columnsSean Griffin2014-07-031-10/+0
|/
* Quote range strings when quoting PG rangesSean Griffin2014-07-021-1/+1
| | | | | The test case for CVE-2014-3483 doesn't actually send the generated SQL to the database. The generated SQL is actually invalid for real inputs.
* Fix SQL injection when querying against ranges and bitstringsRafael Mendonça França2014-07-021-3/+4
| | | | Fix CVE-2014-3483 and protect against CVE-2014-3482.