Article
A temporary name for a result set is given using SQL aliases in FROM clauses. A table or view name, sub-SELECT, and/or VALUES clause can all yield a result set. The AS keyword creates an alias, but the syntax permits us to omit it. A common way to make it easier to understand result sets and column names is to use an alias, which only lasts as long as the query.
SELECT r.rolname, s.usesuper, sub.datname, val.s FROM pg_roles AS r, pg_shadow AS s, LATERAL (SELECT datname FROM pg_database d WHERE d.datdba = r.oid) AS sub, (VALUES (10, 'foo'), (13, 'bar')) AS val(i, s) WHERE r.oid = val.i;
We have 4 variables in this pointless piece of SQL code: r, s, sub, and val. We defined the aliases for its columns, I and s, as well as its name for the last result set.
alias definition rules
It’s ironic that frequent references to tables, views, and functions cannot be made via an alias. However, we are required by the SQL standard to use aliases for sub-SELECTS and VALUES clauses. And for many years, PostgreSQL adhered rigidly to this rule:
SELECT * FROM (SELECT generate_series(1, 3)), (VALUES (10, 'foo'), (13, 'bar')); SQL Error [42601]: ERROR: subquery in FROM must have an alias Hint: For example, FROM (SELECT ...) [AS] foo.
This wasn’t a major issue until PostgreSQL gained popularity and many users began switching from Oracle and other RDBMS. because using aliases for these clauses was not required by the Oracle syntax. Bernd Helmle first noticed this circumstance five years ago.
I occasionally run into people who wonder why the alias in the FROM clause for subqueries in PostgreSQL is required, especially during Oracle to PostgreSQL migration efforts. The SQL standard mandates it, which is the default response here.
The note on this topic in our parser also exactly reads as follows:
A subselect () without an alias clause is not allowed by the SQL spec, thus neither do we. By doing this, the issue of having to create a special refname for it is solved. If there is enough public demand, that may be overcome, but for now, let’s just implement the specification and see if anyone objects. It does, however, seem like a good idea to emit a nicer error message than “syntax error.” /s…
Bernd immediately offered a fix, but it was turned down because there wasn’t agreement on the solution.
According to what I gather, there was no agreement at the time regarding the significance of removing this rule. So, rather than being a technical inquiry, this one was more political. And PostgreSQL adhered to the norm for five long years. Additionally, the future v15 major release will continue to do so.
The subsequent PostgreSQL major release should make subquery aliases optional.
However, Dean Rasheed recently published a new contribution to the development branch with the following request: Make subquery aliases in the FROM clause optional.
This enables the FROM clause’s VALUES and sub-SELECT aliases to be omitted.
This is an extension of the SQL standard, which is supported by a few other database management systems. It makes the transfer from those systems easier and does away with the small nuisance that comes with the need for these aliases.
Tom Lane has reviewed my patch.
CAEZATCUCGCf82=hxd9N5n6xGHPyYpQnxW8HneeH+uP7yNALkWA@mail.gmail.com
I advise you to look over those patches, which were both contributed by Dean and Bernd, to get a sense of the many approaches that might be taken to the same issue. In other words, Dean’s technique does not generate an alias at all, which appears neater and simpler and requires less code than trying to build a unique alias. Bernd’s approach was to automatically construct unique aliases for clauses.
Let’s see if that functions. To do that, I created PostgreSQL from scratch and executed the aforementioned test query:
test=# SELECT version(); version ---------------------------------------------------------------------------------------------------------- PostgreSQL 16devel on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0, 64-bit (1 row) test=# SELECT * FROM (SELECT generate_series(1, 3)), (VALUES (10, 'foo'), (13, 'bar')); generate_series | column1 | column2 -----------------+---------+--------- 1 | 10 | foo 1 | 13 | bar 2 | 10 | foo 2 | 13 | bar 3 | 10 | foo 3 | 13 | bar (6 rows)
Yay! It works!
Conclusion
This innovation will make PostgreSQL more consistent with Oracle syntax, which will make migrating much easier. But if you truly want to enjoy a seamless Oracle to PostgreSQL transfer, try out our upgraded Cybertec Migrator! You can begin by watching sample videos before downloading them and testing them in your surroundings.
About Enteros
Enteros offers a patented database performance management SaaS platform. It proactively identifies root causes of complex business-impacting database scalability and performance issues across a growing number of clouds, RDBMS, NoSQL, and machine learning database platforms.
The views expressed on this blog are those of the author and do not necessarily reflect the opinions of Enteros Inc. This blog may contain links to the content of third-party sites. By providing such links, Enteros Inc. does not adopt, guarantee, approve, or endorse the information, views, or products available on such sites.
Are you interested in writing for Enteros’ Blog? Please send us a pitch!
RELATED POSTS
Accurate Healthcare Cloud Cost Estimation with Enteros: An AIOps-Driven FinOps Approach
- 15 January 2026
- Database Performance Management
Introduction Healthcare organizations are undergoing rapid digital transformation. Electronic health records (EHRs), telemedicine platforms, AI-driven diagnostics, patient engagement portals, population health analytics, and regulatory reporting systems now form the backbone of modern healthcare delivery. At the center of all these innovations lies a complex, data-intensive cloud infrastructure powered by mission-critical databases. While cloud adoption has … Continue reading “Accurate Healthcare Cloud Cost Estimation with Enteros: An AIOps-Driven FinOps Approach”
Why Traditional Banking Database Optimization Falls Short, and How Enteros Fixes It with GenAI
Introduction Modern banking has become a real-time, always-on digital business. From core banking systems and payment processing to mobile apps, fraud detection, risk analytics, and regulatory reporting—every critical banking function depends on database performance. Yet while banking technology stacks have evolved dramatically, database optimization practices have not. Most banks still rely on traditional database tuning … Continue reading “Why Traditional Banking Database Optimization Falls Short, and How Enteros Fixes It with GenAI”
Smarter BFSI Database Operations: How Enteros Applies GenAI to Cloud FinOps and RevOps
- 14 January 2026
- Database Performance Management
Introduction Banks, financial institutions, insurers, and fintech organizations operate in one of the most complex and regulated technology environments in the world. Digital banking platforms, real-time payments, core transaction systems, fraud detection engines, regulatory reporting platforms, and customer engagement channels all depend on highly reliable database operations. As BFSI organizations modernize their technology stacks, database … Continue reading “Smarter BFSI Database Operations: How Enteros Applies GenAI to Cloud FinOps and RevOps”
How Enteros Uses AIOps to Transform Database Performance Management and Cloud FinOps
Introduction As enterprises accelerate cloud adoption, digital transformation has fundamentally reshaped how applications are built, deployed, and scaled. At the center of this transformation lies a critical but often overlooked layer: databases. Every transaction, customer interaction, analytics workflow, and AI model ultimately depends on database performance. Yet for many organizations, database performance management and cloud … Continue reading “How Enteros Uses AIOps to Transform Database Performance Management and Cloud FinOps”