#302 — April 24, 2019

Read on the Web

👋 This issue's Tip of the Week looks at SQL's FILTER clause. Scroll to the end of this issue to check it out.. 👀

Postgres Weekly

Generating Fractals with SQL and Postgres — At !!Con West 2019, Michael gave a talk about creating fractals using SQL and here’s the written version. This is not only a (very detailed) bit of fun, but you’ll learn something about both SQL and Postgres along the way — strongly recommended!

Michael Malis

eBook: The Most Important Events to Monitor in Your Postgres Logs — In this pganalyze eBook, we are looking at the Top 6 Postgres log events for monitoring query performance and preventing downtime.

pganalyze sponsor

More on Postgres 12's REINDEX CONCURRENTLY — A few weeks ago we linked to a brief post about REINDEX CONCURRENTLY, a new feature coming to Postgres 12 that would allow read and write queries to occur during the rebuilding of an index. Michael Paquier now has more insight on its operation and history.

Michael Paquier

How I Use Postgres with Go(lang) — An experienced ‘gopher’ imparts knowledge around the best packages for driver, migrations, queries, and testing. If you happen to be a Go developer yourself, did you know we have a Go newsletter?

Johan Brandhorst

▶  How to Fix Up a Corrupted TOAST Table

Raghavendra Tadipathri

Coming to PostgreSQL 12: Log All Statements from a Sample of Transactions — A quick look at a new feature coming to Postgres 12 that will let you keep your statement log files under control by only logging a sample of them when you wish to do so.

Hubert depesz Lubaczewski

🛠 Tools and Code

pg_sampletolog: An Extension to Sample Statements or Transactions to Logs — Statement sampling is coming to Postgres 12 (above), but this extension works on Postgres 9.4-11 to let you log a sample of statements or transactions now.

Adrien Nayrat

plpgsql_check: A PL/pgSQL Code Checker — This is quite specialized but if you’re looking to find any errors lurking in your PL/pgSQL functions, it could be a lifesaver. The project is quite old but has been kept up to date and runs on modern Postgres versions.

Pavel Stehule

The Best Way to Manage Access to Postgres — strongDM works with everything in your stack. Seriously. Any database. Any server. Every environment. See how it works.

strongDM sponsor

tail_n_mail: A Log File Watcher Focused On Postgres Logs — A Perl script that automatically detects and emails an admin about ‘interesting’ items found in log files. Docs here.

Josh Williams

deno-postgres: A PostgreSQL Driver for DenoDeno is an interesting, and experimental, JavaScript runtime built by the original creator of Node.js (note that Deno is an anagram of Node!)

Bartek Iwańczuk

node-postgres: A Non-Blocking PostgreSQL Client for Node.js — Very popular and has had some releases in the past few weeks.

Brian Carlson

pq: The Pure Go Postgres Driver for database/sqlv1.1 came out last week dropping support for Go 1.8 and below.

Blake Mizerany and contributors

supported by Hasura

💡 Tip of the Week

Using FILTER to turn entity/value tables into rows of entities

An entire article could be written on this topic, but I wanted to show off the most basic use of SQL:2003's FILTER clause that was added to Postgres 9.4.

Let's say you have a table called props that represents entities, attributes, and values with an integer id column, textual attribute and value columns, and the following contents:

The FILTER clause essentially adds an extra WHERE clause to aggregate functions (such as MIN, MAX and SUM) allowing you to scope them.

This comes in very handy for pulling out values from our val column based upon the value of the attr column, therefore allowing us to turn a table of entities, attributes and values into a more classical set of columns.

       MAX(val) FILTER(WHERE attr='name') AS name,
       MAX(val) FILTER(WHERE attr='age') AS age,
       MAX(val) FILTER(where attr='city') AS city
FROM props GROUP BY id;

You might need to reproduce this table and play with the query to get the feel of what's going on, but essentially we are selecting each row grouped by the ID (i.e. the ID of the underlying entity) and then picking the value associated with each ID that matches certain attribute names, allowing us, in this case, to extract the name, age, and city values. MAX works fine as an aggregate function here as there is only one attr/val pair per entity.

The FILTER clause has a lot more uses than this, but I felt this was both a pretty neat and perhaps unexpected example of its use.

You can learn more in this article and in the official Postgres documentation.

This week's tip is sponsored by Hasura, creators of the high-performance GraphQL engine on new and existing Postgres databases. Check them out on GitHub.