News for hackers. Stuff that matters.
Re:New In Postgres 12: Generated Columns by makach on Wednesday October 02, 2019 @05:14AM (#21134589)
At first, I thought; /hey pretty cool feature!/

But after contemplating it, is this really necessary? I fear for putting business logic and meanings into the wrong the layer; There are use and abuse, and my consideration fears the latter.

Re:New In Postgres 12: Generated Columns by stupidcar on Wednesday October 02, 2019 @05:27AM (#21134655)
Why do you think placing business logic into the database system is a layering violation?

Just because most developers use their DB as a dumb store doesn't mean it needs to be. There are also plenty of successful software systems that place the majority of their business logic and use a generic programming language and runtime only for the presentation layer.

If you're comfortable fully exploiting the capabilities of your DB, then the intelligent combination of a relational model with custom data types, constraints, triggers, views and stored procedures can make the DB the perfect place to implement business logic.

Re:New In Postgres 12: Generated Columns by skrebbel on Wednesday October 02, 2019 @07:23AM (#21135235)
I love what you're saying, but running a normal modern development and deployment cycle on code stored in databases is hell.

Until db vendors start taking developer happiness seriously, stored procedures and triggers are a total non starter for any serious work.

I mean, in most databases you can't even rename a column without causing an enormous blocking migration. What? Why can't this happen in the background? Why can't I have column aliases? The very basics of developer happiness aren't covered, let alone the harder bits, like versioning stored procedures, switching schema and code when switching to a new git branch, and so on.

(EDIT: of course there are open source tools that help with all of the above, but they're all swimming upstream, fighting a database that simply can't imagine change, and are usually terribly leaky abstractions as a result)

Re:New In Postgres 12: Generated Columns by taffer on Wednesday October 02, 2019 @01:45PM (#21138988)
> I love what you're saying, but running a normal modern development and deployment cycle on code stored in databases is hell.

Can you be more specific? What exactly are you missing?

As long as you put your code and data into separate schemes and follow good technical practices, it shouldn't be too different from other technologies.

> I mean, in most databases you can't even rename a column without causing an enormous blocking migration.

Changing a column name is just a metadata change, so it shouldn't take too long in Postgres.

> The very basics of developer happiness aren't covered, let alone the harder bits, like versioning stored procedures, switching schema and code when switching to a new git branch, and so on.

Does Tomcat or any other application server version your WAR files for you or does it manage git for you?

Re:New In Postgres 12: Generated Columns by DougBTX on Wednesday October 02, 2019 @07:48AM (#21135386)
Any DB that requires moving large amounts of data on disk to do a column rename sounds pretty lame.

I’d expect most DBs to be like this: https://dba.stackexchange.com/questions/189794/performance-i...

A rename should be just a metadata change.

Re:New In Postgres 12: Generated Columns by SigmundA on Wednesday October 02, 2019 @12:56PM (#21138520)
unless your using jsonb to store data ;)
Re:New In Postgres 12: Generated Columns by naranha on Wednesday October 02, 2019 @05:35AM (#21134698)
Also in my experience DB Schemas often (but not always) outlast logic implemented in applications. The more the business assumptions reside in the database, the easier it becomes to rewrite applications on top of it later.
Re:New In Postgres 12: Generated Columns by sorokod on Wednesday October 02, 2019 @05:55AM (#21134775)
Minimizing the amount of busines logic in the dB is exactly what makes the dB structures long lasting.
Re:New In Postgres 12: Generated Columns by krn on Wednesday October 02, 2019 @06:56AM (#21135073)
> Minimizing the amount of busines logic in the dB is exactly what makes the dB structures long lasting.

The trick is to keep declarative business logic in the database layer, and imperative business logic in the application layer.

This allows a large team of developers to move quickly without breaking things.

Re:New In Postgres 12: Generated Columns by victor106 on Wednesday October 02, 2019 @09:16AM (#21136032)
Very Interesting. Never heard this before.

Can you give some examples of what would constitute declarative business logic vs imperative business logic?

Re:New In Postgres 12: Generated Columns by krn on Wednesday October 02, 2019 @09:40AM (#21136285)
Declarative programming expresses the logic of a computation without describing its control flow.

This new feature in PostgreSQL is a great example of that: generated columns (declarative logic) were introduced to reduce the need for triggers (imperative logic).

In SQL, declarative logic consists of constraints, indexes, views, and prepared statements. They can significantly increase the efficiency and reliability of the entire system. Imperative logic is mostly triggers and stored procedures, both of which can become hard to maintain and scale.

Re:New In Postgres 12: Generated Columns by sorokod on Wednesday October 02, 2019 @01:58PM (#21139097)
How does one logically follows from the other?
Re:New In Postgres 12: Generated Columns by wiz21c on Wednesday October 02, 2019 @07:35AM (#21135295)
that's very well put. Thx!
Re:New In Postgres 12: Generated Columns by pnako on Wednesday October 02, 2019 @06:07AM (#21134815)
Clearly the feature should not be abused, but calculated columns are great for stuff that's obvious and always true (i.e. independent from applications), e.g. a trade value computed from a trade unit price and a trade quantity.

This way I can select the top N trades for a given key without having to do the computation in the application, or storing redundant information in the DB.

Re:New In Postgres 12: Generated Columns by mcny on Wednesday October 02, 2019 @07:47AM (#21135380)
Not postgresql but I saw a start date and an age in days columns in MS SQL server. The age gets updated daily. It didn't sound right to me. I'm pretty sure I'd fail my database class in college if I did that. What is different in real life and why didn't they teach me this in college?
Re:New In Postgres 12: Generated Columns by bobwaycott on Wednesday October 02, 2019 @01:34PM (#21138870)
I obviously can't answer for this particular case, but my first thought on why I would consider doing such a thing is if I had an app in which number of days old was something that had to be queried, displayed, and/or used in other functions/queries a massive number of times per day in the course of normal application usage. If the application had low usage, or number of days old was infrequently queried/displayed/used, I wouldn't consider it. The moment I found that significant time & resources were spent calculating the value in normal/regular usage, I'd start looking at ways to reduce that time & resource usage. How to go about it varies, but the win of that value being immediately available without computation could mean a lot to an app/business and its users.
Re:New In Postgres 12: Generated Columns by vbezhenar on Wednesday October 02, 2019 @07:47AM (#21135383)
There's no clear separation in databases between data definition and application logic. And this separation is very useful. You can change application logic very easily. Just stop old application and start new. You can use multiple application instances to balance load in many cases. You can often rollback bad application update. There's absolutely no problem to use miriads of development tools from Git to CI systems.

Changing database schema is a big deal. It might take a lot of time or it must be done with great caution to keep database online. It's hard to properly version it and it's often hard or just impossible to roll back bad update.

Generally database is state and application is stateless. You can couple it, but decoupling works better.

Re:New In Postgres 12: Generated Columns by taffer on Wednesday October 02, 2019 @02:41PM (#21139482)
Incorrect separation of data from logic is a human problem, not a Postgres problem. Put your logic in one schema[1], let's call it code schema and your data in another schema, the data schema. There you have your separation. Now you can:

* Change your application logic very easily.

* Use a transaction to deploy new code! Zero downtime! [2]

* Use read replicas to balance load in many cases.

* Rollback bad application updates

* Test anything [3]

* Use miriads of development tools from Git to CI systems.

* Use row level security, so that every user can only see his own data [4]

* Only allow applications to call your code schema, never let them touch your data directly.

[1] https://www.postgresql.org/docs/current/ddl-schemas.html

[2] https://wiki.postgresql.org/wiki/Transactional_DDL_in_Postgr...

[3] https://pgtap.org/

[4] https://www.postgresql.org/docs/current/ddl-rowsecurity.html

Re:New In Postgres 12: Generated Columns by atroche on Wednesday October 02, 2019 @05:32AM (#21134681)
Agreed. After all, if you wanted to keep all "business logic" out of the db you wouldn't even use foreign key constraints.
Re:New In Postgres 12: Generated Columns by arethuza on Wednesday October 02, 2019 @05:43AM (#21134738)
You probably wouldn't use multiple tables or multiple columns either and just have a single table that stores document-like rows... which vaguely reminds me of something.
Re:New In Postgres 12: Generated Columns by dtech on Wednesday October 02, 2019 @06:12AM (#21134844)
PostgreSQL is a pretty good document store, and when you need it you have the relational model available and integrated.
Re:New In Postgres 12: Generated Columns by Dirlewanger on Wednesday October 02, 2019 @08:47AM (#21135770)
Foreign key constraints are not business logic, they're part of a sound and sane database architecture (just like basic indices on heavily-queried columns). For an overwhelming majority of use cases, tables should have them; one needs a very good reason why a table shouldn't have them.
Re:New In Postgres 12: Generated Columns by jeltz on Wednesday October 02, 2019 @05:41AM (#21134731)
Or arguably data types.
Re:New In Postgres 12: Generated Columns by Matt3o12_ on Wednesday October 02, 2019 @07:07AM (#21135131)
The last time I tried to do that, I struggled a lot with error handling. The errors your database give you for schema violations aren’t really user friendly, so I have to convert them to proper errors (you must not enter negative amounts). When using SQLite there didn’t seem a way to know what column cast the error without parsing the string. That often lead that I had to implement the business logic twice. One check for in the code for the error handling and another one in the database. That was also often quite inefficient and prone to race conditions (if using improper isolation). For example if the table has two unique fields, I cannot just check for a unique constraint violation because it doesn’t tell me the column in the error data structure.

Looking at the Postgres driver it seems easier but is there any good tutorial on how to do error handling properly for databases?

Re:New In Postgres 12: Generated Columns by wildduck on Wednesday October 02, 2019 @05:52AM (#21134767)
Scaling and replication! It is easier to scale horizontally the application layer than the db layer. Application/code has better debugging tools, IDE.
Re:New In Postgres 12: Generated Columns by another-one-off on Wednesday October 02, 2019 @07:03AM (#21135112)
All sorts of things are possible but it misses a fantastic opportunity to compartmentalise the data away from the implementation. If it doesn't make sense to compartmentalise data and logic, why compartmentalise anywhere? Do the whole project in one big file. Of all the surprises a project is going to face 'oh, this data is useful for [new thing]' is one of the most likely. And everyone expects to find a boundary drawn there because it is such an obvious place to draw one; so it saves on confusion.

Putting complex business logic in the database is opening up all sorts of interesting new ways for data to be unavailable, corrupted or complicated to access. It is easy to imagine it working out well for simple requirements where there just needs to be something that works.

PostgreSQL is a piece of software that takes data and enforces the relational data model on it. Great idea. But the relational model of data is really only tuned to relational algebra. Put complex logic in there and all that is really being accomplished is now you can't migrate away from PostgreSQL. Relational databases already have great integration with every other programming language in current use.

Re:New In Postgres 12: Generated Columns by taffer on Wednesday October 02, 2019 @07:35AM (#21135298)
> All sorts of things are possible but it misses a fantastic opportunity to compartmentalise the data away from the implementation.

That's what schemas are for. You have a schema for your code and a schema for your data. You can redeploy the code scheme independently of the data scheme and set up permissions so that higher layers can only use objects from the code scheme and never touch the data.

> Put complex logic in there and all that is really being accomplished is now you can't migrate away from PostgreSQL.

Say you wrote your code in PHP, now you want to migrate to Ruby or NodeJS. You can't, you have to rewrite everything. How often do you plan to migrate to another database? In my experience this almost never happens in reality, but the layers above come and go.

Re:New In Postgres 12: Generated Columns by another-one-off on Wednesday October 02, 2019 @08:18AM (#21135569)
> You can redeploy the code scheme independently of the data scheme and set up permissions so that higher layers can only use objects from the code scheme and never touch the data.

That all just sounds a touch complicated compared to data in database, code somewhere else (like git). I'm circling back to the same point in a couple of different ways, but pgSQL specialises in the relational model of data. That isn't a great data model for code and there are already better ways to manage code than shoehorning it into the database. Its cool that it is possible, and I'm not saying that someone who does is making a mistake. But I also don't think they are gaining an advantage and there is a really easy opportunity to separate out where bugs can occur from where data lives.

> How often do you plan to migrate to another database? In my experience this almost never happens in reality, but the layers above come and go.

If you are using a database for its advanced general purpose programming capabilities? The chances probably start to get more likely.

Databases that are a store of data don't need to change because they already do their one job (disk <-> relational model translation) really well. If they are pressured to do 2 or 3 tasks like business logic then suddenly it is a lot more likely that there will be pressure to swap databases.

If I were using SQLite and someone wants to do fancy triggers then maybe I need to swap to PostgreSQL. Avoiding that sort of decision making is a great reason to seal the data completely away from the code.

Re:New In Postgres 12: Generated Columns by taffer on Wednesday October 02, 2019 @10:01AM (#21136508)
> That all just sounds a touch complicated compared to data in database, code somewhere else (like git).

You use Postgres as a deployment target and not as a replacement for git. It's not complicated at all. You even get features like transactional deployments and the ability to prohibit applications from directly touching the data.

> pgSQL specialises in the relational model of data

The relational model is SQL:92, Postgres does much more than that. Postgres has JSON support, recursive CTEs, Row Level Security, and Window functions that would require dozens of lines of procedural code to do what can be done with a single OVER in its SELECT clause.

> If I were using SQLite and someone wants to do fancy triggers then maybe I need to swap to PostgreSQL.

If you want to put your business logic into an RDBMS, you wouldn't be using an embedded DB anyway, but rather Oracle, Postgres, SQL Server or DB2, which are designed for this type of architecture.

Re:New In Postgres 12: Generated Columns by ludwigvan on Wednesday October 02, 2019 @06:05AM (#21134808)
This thinking really intrigues me, as it seems like it fell out of fashion (at least for greenfield projects), but it might have a come back.

Could you share a few cases where it is better to use a custom type as opposed to a relation? The only things I can think of are generic things like uuid. Would there be a need to create an Employee type vs an Employee relation?

Also, how is the experience with using Python for stored procedures? One reason they are not used is that the language pl/sql is non-familiar to most. If anyone has any experience with that, could you share some of your thoughts?

Re:New In Postgres 12: Generated Columns by tyingq on Wednesday October 02, 2019 @06:31AM (#21134933)
It could just be something more pedestrian like not yet being able to handle database changes well for deployments. Things like blue/green, canary, reverting, etc. It's a bit of work to get that functioning well.
Re:New In Postgres 12: Generated Columns by dragonwriter on Wednesday October 02, 2019 @05:23AM (#21134636)
> But after contemplating it, is this really necessary?

No, you could always do the materialized equivalent via triggers, so it's not necessary for correctness. And since this feature is limited to the materialized form, too, it doesn't offer much change other than simpler expression of what is going on (which, to be fair, is a big win.)

> I fear for putting business logic and meanings into the wrong the layer

If you don't have some mechanism for calculated columns, you are forced to put domain logic that belongs in the DB in the app layer, which is especially problematic in the (increasingly out of fashion, apparently) circumstance where there are multiple consumers of a DB, as it promotes inconsistency.

Re:New In Postgres 12: Generated Columns by petereisentraut on Wednesday October 02, 2019 @05:36AM (#21134706)
This is also much faster than the equivalent using a PL/pgSQL trigger.
Re:New In Postgres 12: Generated Columns by pnako on Wednesday October 02, 2019 @05:21AM (#21134623)
If your database contains objects like "customer ID", "address" and the like, you already have business considerations (if not logic) inside it. In fact, businesses using databases for business stuff is probably 95% of DB use cases.

If it's something that's not application-specific and fits nicely into the query language (like in the example given) it makes sense to have it inside the DB, because for queries involving sorting, limiting, etc. you can do all that stuff inside the DB and return the few values that interest you, instead of transferring all the data and having to write code to do that inside your app.

Re:New In Postgres 12: Generated Columns by eternalban on Wednesday October 02, 2019 @05:27AM (#21134654)
Arguably, a robust RDBMS with user defined functions (such as PostgreSQL) are the ideal place for core domain semantics.

What is missing is a modern tool chain that addresses the painpoints of such a development model.

Re:New In Postgres 12: Generated Columns by perlgeek on Wednesday October 02, 2019 @07:10AM (#21135154)
It's super helpful for database migrations.

Say you suddenly don't have data for a column anymore, because the API that you read from has stopped providing it. Now you can add a computed column that uses a heuristic as an interim until you have time to remove all the reads from that column.

Or say that you have an object with a separate display name, and product management decides that the display name now can't be chosen freely anymore, but must be generated from name and title. A computed column can do that trick pretty well.

Re:New In Postgres 12: Generated Columns by philshem on Wednesday October 02, 2019 @05:30AM (#21134676)
As an analyst, either for reporting or machine learning tasks, it scratches my itch.

I'm often creating wide, flat views with extended attributes. Many columns are nearly identical, for example, year as an integer, year a date type, etc. This is trivial with views, but ...

For fast query performance, I usually materialize those views. But that's a multi-step and often manual process, requiring schedules or triggers. This feature combines both of those worlds, with fewer total database objects. Especially with ALTER TABLE.

Re:New In Postgres 12: Generated Columns by ako on Wednesday October 02, 2019 @06:22AM (#21134896)
No, putting data logic in a service is putting logic in the wrong layer. Data logic should live in the data layer.
Re:New In Postgres 12: Generated Columns by magicalhippo on Wednesday October 02, 2019 @07:26AM (#21135252)
It's great for speeding up queries. Optimizations frequently require giving up on absolute purity. We use computed columns a lot for speeding up specific, frequently used queries.

One example is where we need to store a special identifier code. The identifier code is required by law to have a certain format, and part of it is the date the code was generated.

Users frequently want to view items with codes generated on a specific day. For making presentation and reporting easier, as well as significantly faster, we added a computed date column that extracts the date from the code and indexed it.

Keeping an extra field in sync in code would inevitably have lead to bugs, especially as we have several different codebases which could update the id code.

Re:New In Postgres 12: Generated Columns by scarlac on Wednesday October 02, 2019 @12:19PM (#21138143)
I agree that it should be used sparingly. But for more than 5 years I've wished I had a computed column feature because you are often thrown into code bases that need refactoring and refactoring 100% in 1 commit is not always the safest way to go. Sometimes you want to migrate a codebase in several steps. Computed/virtual columns are an absolutely fantastic feature and it allows refactoring and migrations at your own pace, or as a fallback.
Re:New In Postgres 12: Generated Columns by asah on Wednesday October 02, 2019 @09:39AM (#21136263)
Putting business logic in the database has been a boon to large companies for decades - while the development process can be trickier, it helps ensure that every team is using the same logic (incl version) to access the data.

With PostgreSQL, you can define business logic in everyday languages, including JavaScript (plv8).

Re:New In Postgres 12: Generated Columns by dahdum on Wednesday October 02, 2019 @04:00PM (#21140215)
You’d hate my work, we shoehorn everything we can into the database, with a nice simple API layer of versioned stored procedures in front. It’s easy to test and enforce the business logic, and then it can be easily utilized across web, mobile apps, custom apps, and third parties.

Works great if you’re sure you won’t ever need to scale huge horizontally. One of my RoR apps connects to a schema of views, with instead of triggers calling procedures for updates. Something like 30 normalized tables are rolled up into 5 denormalized views, leaving hardly any ActiveRecord woes and still excellent performance.

Re:New In Postgres 12: Generated Columns by michaelper22 on Wednesday October 02, 2019 @03:59PM (#21140204)
Here's one of my current use cases: We have a folder tree table in our (formerly nested sets, then closure table, now materialized path), and we cache a materialized version of the path with the folder names. There are some places in the app where you can look up a node by its full path, and this column should conceptually be unique. Obviously an unindexed VARCHAR(2048) is bad to filter on, but MySQL indexes can only cover the first 767 bytes (we used utf8mb4). So we have another column, PathHash CHAR(40) AS (SHA1(path)) VIRTUAL, and then a unique index on that.