Comments (8)
That's a good trick @trevorrjohn. I'll switch to doing that. I didn't think that would work because I thought ignored_columns
didn't affect the query ie. it still did SELECT *
but ignored the result.
However what seems to happen is it reflects on the table structure and explicitly selects everything but columns matching SELECT table.column_1, table.column_2 ...
.
Explicitly selecting columns will protect from the prepared statement errors as I believe the reflection and cache preparation happen at the same time. This means adding only one ignored_column
will protect all further new column additions to that table. ie. adding two columns you can ignore one OR just have a non-empty ignored_columns
array even if that column will never exist.
I'm not sure if this is a good idea but it is possible to add a self.ignored_columns = [:protect_from_expired_cache]
to the ActiveRecord::Base
and then the error could never occur again (cost could be larger memory footprint for cached statements, not sure what will happen with joins or explicit SQL SELECT *
statements) and possibly new columns could be added safely with zero downtime as all selects are explicit.
from strong_migrations.
Hey @trevorrjohn, I haven't seen that error before, and the only mention I can find on Google is this post, so I'm not sure how common it is.
You can always manually add it to your app with a custom check.
from strong_migrations.
We have been switching prepared statements off before the deploy and back on again afterwards. @ankane for more details about the error checkout this Rails issue: rails/rails#12330.
from strong_migrations.
I think adding to ignored_columns
is a better solution than switching of prepared statements. I agree I can add it manually, but do think it should be a default in this gem. Happy to submit a PR if you agree.
from strong_migrations.
Hey @aldhsu, that's an interesting idea, but I'm worried about making it the default. It seems like apps that need it can do:
ActiveRecord::Base.ignored_columns = [""]
I'm hesitant to make add_column
raise a warning since I haven't personally encountered this (we disabled prepared statements at Instacart when we added pgbouncer, and I don't recall running into this error before then).
from strong_migrations.
Ok. I'm fine with closing for now. We can reopen if more people encounter this issue.
from strong_migrations.
A nice PR is probably coming in Rails 7 that will let use force columns enum rails/rails#41718
Edit: PR has been merged into Rails 7
from strong_migrations.
Hey @ankane I'm wondering if this should be re-opened. We're currently on Rails 6 and this is something we have to work with for our Postgres database. I've reproduced this locally as well:
Reproduction steps
- Open a rails console.
- Manually add a new column to a table.
- In the rails console from step 1, do
ActiveRecord::Base.transaction do { .... }
. - See error.
postgres=# \c development
You are now connected to database "development" as user "daniel.dao".
development=# SELECT * FROM employments;
id | user_id | employer_name | status | created_at | updated_at
----+---------+---------------+--------+------------+------------
(0 rows)
development=# ALTER TABLE employments ADD new_metric_colum integer;
ALTER TABLE
development=# SELECT * FROM employments;
id | user_id | employer_name | status | created_at | updated_at | new_metric_colum
----+---------+---------------+--------+------------+------------+------------------
[2] pry(main)> ActiveRecord::Base.transaction { Employment.last }
TRANSACTION (1.5ms) BEGIN
Employment Load (7.5ms) SELECT "employments".* FROM "employments" ORDER BY "employments"."id" DESC LIMIT $1 [["LIMIT", 1]]
TRANSACTION (0.3ms) ROLLBACK
ActiveRecord::PreparedStatementCacheExpired: ERROR: cached plan must not change result type
from /Users/daniel.dao/.rbenv/versions/3.0.5/lib/ruby/gems/3.0.0/gems/activerecord-6.1.7.6/lib/active_record/connection_adapters/postgresql_adapter.rb:696:in `rescue in exec_cache'
Caused by ActiveRecord::StatementInvalid: PG::FeatureNotSupported: ERROR: cached plan must not change result type
from /Users/daniel.dao/.rbenv/versions/3.0.5/lib/ruby/gems/3.0.0/gems/activerecord-6.1.7.6/lib/active_record/connection_adapters/postgresql_adapter.rb:687:in `exec_prepared'
Caused by PG::FeatureNotSupported: ERROR: cached plan must not change result type
from /Users/daniel.dao/.rbenv/versions/3.0.5/lib/ruby/gems/3.0.0/gems/activerecord-6.1.7.6/lib/active_record/connection_adapters/postgresql_adapter.rb:687:in `exec_prepared'
Currently right now this has affected our users during migrations. I'd love for there to be an automated way to prevent developers from accidentally running into this. Ideally by using ignored_columns
.
I'm happy to work on a PR as well, but wanted to see if re-opening the issue makes sense to you!
from strong_migrations.
Related Issues (20)
- lock_timeout + lock_timeout_retries + concurrent postgres indexes HOT 2
- safety_assured not ignoring custom checks when safe_by_default is true HOT 1
- [Idea] Checks for dangerous attributes HOT 1
- add_reference + index +disable_ddl_transaction! is an unsafe pattern? HOT 1
- [Idea] Apply `safety_assured` through `revert` HOT 2
- `StrongMigration.start_after` doesn't respect version on `revert` HOT 1
- Adding a column with a default value should is safe when use mysql(5.7) as database HOT 5
- [Idea] Show check link with error message HOT 1
- Lock timeout when using `add_column` with `enum` type HOT 2
- `add_reference` with concurrent index can be dangerous HOT 2
- [Idea] Provide custom message prefix/suffix message HOT 2
- [Idea] Should add_unique_constraint be considered unsafe? HOT 3
- `StrongMigrations.start_after` does not work HOT 1
- Consider appending to ignored_columns as a best practice HOT 1
- [Idea] Ignore migrations from non-supported adapters HOT 3
- [Idea] safety_assured should require justification HOT 1
- [Idea] Adding auto incrementing primary key does not guarantee that replicas generate the same primary key values (MySQL) HOT 4
- Getting an error complaining about MariaDB Version HOT 3
- [Idea] Add these changes as default in Rails HOT 1
- [Idea] Support custom checks on TableDefinition methods
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from strong_migrations.