Comments (8)
Example errors from Postgres 9.2:
ERROR: 42601: syntax error at or near "MATERIALIZED"
LINE 1: CREATE MATERIALIZED VIEW foo AS SELECT foo'::text as text;
ERROR: 42601: syntax error at or near "REFRESH"
LINE 1: REFRESH MATERIALIZED VIEW foo
Example Error from Postgres 9.3:
ERROR: 42601: syntax error at or near "CONCURRENTLY"
LINE 1: REFRESH MATERIALIZED VIEW CONCURRENTLY tests;
We can do a regex match on the message. The bigger challenge is going to be testing this. We can try to fake the exception raising, but I wouldn't feel great about that. In reality, we'd need to be able to test against multiple PG versions in our suite (at least on CI). Not sure if that's possible.
from scenic.
I'd be happy to work on this, too!
Based on this closed issue on TravisCI, it doesn't look like they support that functionality: travis-ci/travis-ci#954
Maybe one way around this would be to hook it up to several different CI servers and configure (for example) Travis to run with 9.4, CircleCI to run with 9.3 and something else like Semaphore to run with 9.2. We would probably have to have some sort of conditionals in the tests as well so that they're run or skipped depending on the Postgres version that we're testing against.
Or, if there's another CI service out there that does let you configure multiple versions of a database then you could migrate over to that service if this is a crucial part of the testing. I'd be happy to dig a little deeper and see if that's possible if you like.
from scenic.
Another idea would be to try to get the version from postgres and error based on that rather than the syntax error. I'd feel more comfortable stubbing that. The postgres adapter has a "postgresql_version" method, but unfortunately it's protected
.
ActiveRecord::Base.connection.send(:postgresql_version)
# => 90405
Also curious that it returns 90405
. I guess it allows for strict numerical comparison which might be nice. For materialized view support we'd check against >= 90300
and for refresh concurrently, we'd check against >= 90400
.
Which all sounds well and good... except it's not a public method. Maybe we'd have to re-implement it? I wonder if any other PG gems are doing anything similar?
from scenic.
ActiveRecord::Base.connection.supports_materialized_views?
gets us part of the way there. Unfortunately, it was only added in 4.2, and our gemspec says we support 4.1.
I've opened a PR against Rails to make server_version
a public method, but even if that were merged it would be Rails 5+ only.
A monkey patch of some sort might be the best solution unfortunately. We're done it before (see ignore_tables
on SchemaDumper.
Hrmmm.
from scenic.
I like the idea of returning the error based on the Postgres version instead of parsing the error from ActiveRecord! I think re-implementing might not be the worst thing in the world - especially since it will decouple it from any changes that might be made in Rails in the future, and it's a really tiny re-implementation. How about going around the built in Rails methods and asking Postgres directly for its version? Something like this might work:
ActiveRecord::Base.connection.select_value('select version()') #=> "PostgreSQL 9.4.2 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, 64-bit"
We can get the version from there via RegEx and then have our own methods for supports_materalized_views?
and supports_concurrent_materalized_views?
that we can base the error message off of. I don't think Postgres is going to ever change select version()
, and it will also be easy to extend this pattern to future databases.
I'll put together a kind of quick and dirty version of this just to flesh out the idea, and then if you think it would be better to go about it a different way then we can totally do that.
from scenic.
Ok, I've put together some rough ideas about how to tackle this in #111. For now I think this might be a good solution, but I'm going to continue to think about it for the next day or two.
from scenic.
@devonestes This is the right direction, I think. I'm working on #112 which also needs some feature checking based on version. I have an idea for encapsulation of this feature that I might like (which includes some refactor of adapter internals I've wanted to do), so let me post that and see what you and Caleb think about that.
from scenic.
Closing in favor of the PR in progress at #111
from scenic.
Related Issues (20)
- Getting "Invalid single-table inheritance type" error when using a model based on a view HOT 2
- Sequences HOT 1
- Materialization is dumped to structure.rb incorrectly HOT 2
- Is it possible to make it work with Sinatra or any other Rack app? HOT 2
- schema.rb diff after running migrations HOT 2
- How to persist `'now'::timestamp` / prevent being computed with `rails db:migrate` HOT 3
- ERB.new warnings despite #360 HOT 2
- add a support for pg_ivm ? HOT 1
- Centralise and expose configurable db views folder HOT 5
- make update_view for materialized views create less downtime HOT 1
- Add support for a cache_key and/or cache_version HOT 1
- Ignore scripts outside `db/views` folder HOT 1
- Cannot replace materialized views HOT 2
- Old migration name affecting new view name HOT 10
- cannot rollback drop_view HOT 3
- Multiple databases, main DB is assumed even though it's specified in the model. Is there a better way? HOT 1
- Feature Request: Support Generated Columns HOT 1
- Support Rails' multiple database feature HOT 1
- Default to latest view definition for create_view HOT 1
- Cutting new release? HOT 1
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 scenic.