Skip to content
  • Mike Dalessio's avatar
    d4f3a452
    fix: sqlite3 adapter quotes Infinity and NaN · d4f3a452
    Mike Dalessio authored
    This is similar to the fix applied to the postgresql adapter in #3713
    
    This isn't a problem if the value is provided as a parameter to a
    prepared statement, but is a problem where literal SQL is assembled,
    for example with `upsert`. Without quoting, the exception raised is:
    
    ```
    >> Shirt.upsert({id: 1, size: Float::INFINITY})
    sqlite3-2.6.0-x86_64-linux-gnu/lib/sqlite3/statement.rb:36:in 'SQLite3::Statement#prepare': no such column: Infinity: (SQLite3::SQLException)
    INSERT INTO "shirts" ("id","size","created_at","updated_at") VALUES (1, Infinity, STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW'), STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')) ON CONFLICT ("id") DO UPDATE SET updated_at=(CASE WHEN ("size" IS excluded."size") THEN "shirts".updated_at ELSE STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW') END),"size"=excluded."size" RETURNING "id"
                                                                            ^
    from sqlite3-2.6.0-x86_64-linux-gnu/lib/sqlite3/statement.rb:36:in 'SQLite3::Statement#initialize'
    from sqlite3-2.6.0-x86_64-linux-gnu/lib/sqlite3/database.rb:216:in 'Class#new'
    from sqlite3-2.6.0-x86_64-linux-gnu/lib/sqlite3/database.rb:216:in 'SQLite3::Database#prepare'
    from rails/activerecord/lib/active_record/connection_adapters/sqlite3/database_statements.rb:94:in 'ActiveRecord::ConnectionAdapters::SQLite3::DatabaseStatements#perform_query'
    ...
    from rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:558:in 'block in ActiveRecord::ConnectionAdapters::DatabaseStatements#raw_execute'
    ...
    from rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:557:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#raw_execute'
    from rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:601:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#internal_execute'
    from rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:550:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#internal_exec_query'
    from rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:180:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#exec_insert_all'
    from rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:27:in 'ActiveRecord::ConnectionAdapters::AbstractAdapter#exec_insert_all'
    from rails/activerecord/lib/active_record/insert_all.rb:54:in 'ActiveRecord::InsertAll#execute'
    from rails/activerecord/lib/active_record/insert_all.rb:13:in 'block in ActiveRecord::InsertAll.execute'
    ...
    ```
    
    Quoting this value of "Infinity" (and also "NaN") does what's intended.
    d4f3a452
    fix: sqlite3 adapter quotes Infinity and NaN
    Mike Dalessio authored
    This is similar to the fix applied to the postgresql adapter in #3713
    
    This isn't a problem if the value is provided as a parameter to a
    prepared statement, but is a problem where literal SQL is assembled,
    for example with `upsert`. Without quoting, the exception raised is:
    
    ```
    >> Shirt.upsert({id: 1, size: Float::INFINITY})
    sqlite3-2.6.0-x86_64-linux-gnu/lib/sqlite3/statement.rb:36:in 'SQLite3::Statement#prepare': no such column: Infinity: (SQLite3::SQLException)
    INSERT INTO "shirts" ("id","size","created_at","updated_at") VALUES (1, Infinity, STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW'), STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')) ON CONFLICT ("id") DO UPDATE SET updated_at=(CASE WHEN ("size" IS excluded."size") THEN "shirts".updated_at ELSE STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW') END),"size"=excluded."size" RETURNING "id"
                                                                            ^
    from sqlite3-2.6.0-x86_64-linux-gnu/lib/sqlite3/statement.rb:36:in 'SQLite3::Statement#initialize'
    from sqlite3-2.6.0-x86_64-linux-gnu/lib/sqlite3/database.rb:216:in 'Class#new'
    from sqlite3-2.6.0-x86_64-linux-gnu/lib/sqlite3/database.rb:216:in 'SQLite3::Database#prepare'
    from rails/activerecord/lib/active_record/connection_adapters/sqlite3/database_statements.rb:94:in 'ActiveRecord::ConnectionAdapters::SQLite3::DatabaseStatements#perform_query'
    ...
    from rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:558:in 'block in ActiveRecord::ConnectionAdapters::DatabaseStatements#raw_execute'
    ...
    from rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:557:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#raw_execute'
    from rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:601:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#internal_execute'
    from rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:550:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#internal_exec_query'
    from rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:180:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#exec_insert_all'
    from rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:27:in 'ActiveRecord::ConnectionAdapters::AbstractAdapter#exec_insert_all'
    from rails/activerecord/lib/active_record/insert_all.rb:54:in 'ActiveRecord::InsertAll#execute'
    from rails/activerecord/lib/active_record/insert_all.rb:13:in 'block in ActiveRecord::InsertAll.execute'
    ...
    ```
    
    Quoting this value of "Infinity" (and also "NaN") does what's intended.
Loading