How about trailing commas in SQL?
271 comments
·February 11, 2025adornKey
cnity
> it is annoying that the end of the list is always special. You can't just copy some line and move it there. Also when moving things around you always have to take extra care at the end.
You have simply moved the "special" entry to the beginning rather than the end.
Side remark: I've noticed that when it comes to code formatting and grammar it's almost like there are broadly two camps. There are some instances of code formatting that involve something "clever". Your example of leading commas above for example. Another example is code ligatures. It's as if there's a dividing line of taste here where one either feels delight at the clever twist, or the total opposite, rarely anything in between. I happen to dislike these kinds of things (and particularly loathe code ligatures) but it is often hard to justify exactly why beyond taste.
Code ligature thing has something to do with just seeing the characters that are actually there rather than a smokescreen, which IMO impedes editability because I can't place the cursor half-way through a ligature and so on. But it's more than that -- you could fix those functional issues and I'll still dislike them.
JadedBlueEyes
> I can't place the cursor half-way through a ligature and so on.
That sounds like a bug in the editor. Ligatures are incredibly common font features even outside of programming, even sequences like fi are often ligatures.
cnity
How could this possibly be done for ligatures which don't maintain their horizontal position though? `!=` will usually be shown as an equals sign with a line through it right down the middle.
adornKey
Adding something to the end is the most common thing to do. And changing the start is extremely rare - it's anyway special because you usually put it in the line with the SELECT.
quietbritishjim
> you usually put it in the line with the SELECT.
No, you usually don't. That would "bury" the first field so you don't immediately see it if you quickly glance at the code. I'll admit I was a bit surprised when I saw a fully formatted SQL query but it does look much better:
SELECT
a,
b,
c,
d
FROM
Customers
ORDER BY
b,
c DESC
Edit: I've just seen other comments here suggesting you return an extra "pad" value at the start so you can use leading commas without "losing" the first value visually. I hardly know where to start with that. It transmits more data on the wire and, to my eyes, looks horrific. That level of hackery is proof, as if it were needed, of how badly needed trailing commas are.boxed
Hard disagree.
Quekid5
> Code ligature thing has something to do with just seeing the characters that are actually there rather than a smokescreen, which IMO impedes editability because I can't place the cursor half-way through a ligature and so on
Why wouldn't that be possible? (The cursor thing)
It's still two characters as far as your editor is concerned.
cnity
I didn't say it's not possible, but certainly when I've tried ligatures in the past my editor treated it like a single character until I pressed backspace after the character (or delete before) or whatever. Anyhow there's all sorts of weird functional artefacts that just feel dodgy to me and they basically all arise from this world where multiple runes are being treated as a single one. Here are two more examples:
1. If I `/=` in vim (find equals signs), should the "!=" ligature be highlighted? If it is, then it is misrepresenting the state: if I then press delete, the highlighted ligature won't actually be removed, only part of it will be.
2. In javascript the `===` operator is less visually distinct from `==` since if there are no comparisons nearby I have to judge from the length somehow and it takes longer, adding some additional comprehension fatigue.
Anyway like I said, you can probably try to fix all of these with weird special case handling but it's just fighting the underlying assumption my editor makes (and my brain has learned to understand): a source file is a list of runes. That's how I like to think about it.
Anyone is free to think otherwise. They're just in that other camp and that's OK. But I don't like them personally.
chihuahua
I'm not sure if this is an example of code ligatures, but I used to work with a guy who had configured his editor so that "=>" was replaced with some kind of special arrow character, and it used to drive me nuts. When I read code, I want to know what's actually there, and not have to ask "what does that arrow actually mean?"
throwuxiytayq
But you have demonstrated that you know what the arrow means. Do you have your editor configured to display special symbols for all whitespace characters? Including newlines? Are you sure that you aren't just annoyed by looking at stuff you're not used to?
paulddraper
> You have simply moved the "special" entry to the beginning rather than the end.
Yes, but
1. Terms are more commonly added to the end than the beginning.
2. The beginning is often already special, e.g. starting with `SELECT`.
3. The commas are visually aligned/consistent with the indentation.
4. Because of #3, it's far easier to spot a missing comma.
I worked for years in a SQL-heavy role, and this style was the preference there, for these reasons.
null
masklinn
That is the haskell workaround, and it also sucks, because it still requires a special non-uniform first value.
I do not want to write either of your snippets, I want to write
SELECT
a,
b,
c,
FROM
Because now selected values are uniform and I can move them around or add new ones with minimal changes no matter their position in the sequence.It’s also completely wonky in many contexts e.g. CREATE TABLE. Trailing commas always works.
> I'd suggest to maybe just change your coding style - and make the start of the list special - instead of the end.
Supporting trailing commas means neither is special.
catapart
Spot on.
Also, to generalize a bit: if a human is expected to read it, the way humans write should be able to be parsed by it. That's subjective, to a point, but it's an easy rule-of-thumb to remember. Trailing commas are so common that people have built workarounds for them. Therefore, they can be understood as "the way humans write". If you're writing a language that you still want to be readable by humans, you really should account for that. And, no shade for it not already being done. I'm just reiterating that there should be NO pushback to allowing trailing commas. It's a completely "common-sense" proposal.
roenxi
> It's a completely "common-sense" proposal.
The SQL standards committee is having none of it. I can tell you that just from this one sentence.
And, more seriously, there isn't really such a thing as a common-sense proposal with SQL. The grammar is so warped after all these years that there isn't a path to consistency and the broken attempt at English syntax has rendered it nearly incomprehensible for both human and machine parsing. Any change to anything could have bizarre flow on effects.
I'd love to see trailing commas added to SELECT though. Given the mess it isn't possible to make the situation worse and the end of the list being special can be infuriating.
yellowapple
I don't want to write commas at all. I want to write
SELECT
a
b
c
FROM d
Or even SELECT a b c FROM d
Because now selected values are uniform and there's no superfluous punctuation to worry about.specialist
This would work (w/ a context free grammar) if aliases required the 'AS' keyword.
Ambigious:
SELECT a aliasA b c aliasC FROM d aliasD e
Unambigious: SELECT a as aliasA b c as aliasC FROM d as aliasD e
Alternately, a schema-aware parser could determine if 'aliasA' was an alias or a column reference.FWIW, personally, I'd rather go the full-Python, using newlines as delimiters:
SELECT
a aliasA
b
c aliasC
FROM
d aliasD
e
(With tabs for nesting.)marcosdumay
You can get either commas or required `as` and parenthesis around expressions.
IMO, required `as` and parenthesis are better. But it's not a clear thing where everybody will agree.
adornKey
I'd still want to have leading commas.
If the items in the list are long IF(...), maybe uses several lines and maybe contain SELECTs it's hard to see a missing trailing comma. At the start they're all lined up well, and it's very hard to get them wrong.
masklinn
> I'd still want to have leading commas.
Real happy for you. Trailing commas support don’t prevent you from doing that.
atombender
I often do this with boolean WHERE filters when I'm doing interactive exploration on some data:
SELECT ...
WHERE
foo = 1
AND bar = 2
I want to comment out a line (i.e. "--foo = 1"), but would break the syntax.The solution is to start with "WHERE true":
SELECT ...
WHERE true
--AND foo = 1
AND bar = 2
Now you can comment/comment anything.(Putting the AND at end of each line has the same problem, of course, and requires putting a "true" at the bottom instead.)
dangets
I do the same, though my muscle memory is `1=1` instead of `true`.
Of course then you get editors/linters/coworkers that always point out that the 'true' is unnecessary. This also doesn't work with ORs (just swap to false), but in practice it seems it is always ANDs that is being used.
fngjdflmdflg
Huh, I've always used "WHERE 1 = 1 AND ...". Using `true` looks more clean.
hn1986
Not all sql variants support "true". e.g. SQL Server doesn't.
refset
In XTDB you can now use (trailing-friendly) commas in this scenario too, instead of ANDs: https://github.com/xtdb/xtdb/pull/3985
NoMoreNicksLeft
God, everyone's going to hate me for this. (I will have earned it, I think.)
SELECT ...
WHERE foo = 1
AND bar = 2
Each keyword gets a new line, the middle gutter between keyword and expressions stays in the same place, and things get really, really fugly if I need a subselect or whatever. Any given line can be commented out. (And no, none of that leading comma bullshit, somehow that looks nasty to me.) Downvote this into oblivion to protect the junior developers from being infected by whatever degeneracy has ahold of me.atombender
You may have missed what I was getting at.
In order to quickly comment out the "foo = 1" here, you cannot simply comment out the whole line because it would become syntactically invalid:
SELECT ...
--WHERE foo = 1
AND bar = 2
I have a single keyboard shortcut to comment/uncomment a line because I like to work briskly with as little unnecessary typing.It has nothing to do with indentation or being "fugly". I'm talking about interactive exploration of prototyping when the final SQL isn't set in stone.
wruza
Since we're already here, we could think about trailing AND, actually. Look:
SELECT a, sum(b),
WHERE foo = 1
AND GROUP BY a
Sounds pretty SQL to me.krembo
IMHO this is one of the ugliest formattings. Whenever I see that i try to revert and avoid at all costs. I know it's a personal flavor, yet. I might be too opinionated..
datadrivenangel
SQL is also case insensitive for most clauses!
`SeLeCt ... fRoM ... wHeRe ...` IS VALID! (And you should use a linter/formatter to avoid these categories of style war)
mewpmewp2
I agree, I'd say I usually don't care about aesthetics, but that somehow looks so wrong, I am bothered by it.
skeeter2020
I too prefer leading commas, especially useful when you're prototyping a query. I also picked up the ORM trick of starting your WHERE clause with 1=1 so that every meaningful filter can start with AND ... I'm not as consistent with this one, but it's handy too.
I catch (friendly) flak for my zealot SQL formatting (capitalization, indenting) and know it doesn't impact the execution, but there's something about working in logic / set theory that matches with strict presentation; maybe helps you think with a more rigid mindset?
zX41ZdbW
ClickHouse has support for trailing commas for several years.
I recommend looking at ClickHouse (https://github.com/ClickHouse/ClickHouse/) as an example of a modern SQL database that emphasizes developer experience, performance, and quality-of-life improvements.
I'm the author of ClickHouse, and I'm happy to see that its innovation has been inspired and adopted in other database management systems.
tezza
I do this as well.
on top i often do a pad entry so that the elements are all on their own line
SELECT 1 as pad
, a
, b
then i can reorder lines trivially without stopping to re-comma the endpoints or maintain which special entry is on the line of the SELECT tokenwhat would be helpful is both LEADING and trailing commas
so I am suggesting:
SELECT
, a
, b
would be permissible too. The parsing step is no longer the difficult portion.Developer ease leads to less mistakes is my conjecture.
mewpmewp2
Why not something like
SELECT
a,
b,
c,
1 as pad FROM
Then?tezza
cool, that would work too. my preference is leading separators so the separators are all in a visual column. being in a visual column allows the eye to discount the separators easily.
typically names are different lengths and the commas are hard/harder to spot
Your suggestion:
SELECT
first_column,
second_column_wider_a_lot,
(third + fourth_combined_expression),
1 as pad FROM
vs my current preference: SELECT 1 as pad
, first_column
, second_column_wider_a_lot
, (third + fourth_combined_expression)
FROM
tiffanyh
Another trick is, if you're programmatically building a SQL statement - adding "WHERE 1=1" makes things easier ... like so:
SELECT *
FROM table
WHERE 1=1
That way, if you want to filter down the result, everything programmatically appended just needs an "AND ..." at the start, like: SELECT *
FROM table
WHERE 1=1
AND age > 21
AND xyz = 'abc' ...
Because without "WHERE 1=1", you'd had to handle the first condition different than all subsequent conditions.wruza
I prefer “1=0 OR 1=1”, because when you delete all conditions you can keep 1=0 out of selection and it decays into a no-op rather than destroying a table:
DELETE FROM table
WHERE 1=0[ OR 1=1
AND age > 21
AND xyz = 'abc']
;
Brackets designate selection bounds before text deletion. The above just safely does nothing after you hit DEL.Without that you’d have to delete whole [WHERE…], which leaves a very dangerous statement in the code.
chasil
Similarly, you could select NULL as your leading column, and prepend commas by that means.
That method does impact the result set, and using it for CTAS or bulk insert would require more care in column selection.
tqwhite
Please god. I don't believe in you but maybe someone else does and will think me a kindred spirit worthy of mercy. Let me have trailing commas. There is no reason not to. It's backward compatible, easy to implement and would make the world so so so much better.
birb07
they are _not_ backwards compatible. That's a big part of the problem. A trailing comma is a syntax error for an SQL engine without support for it
dhruvrajvanshi
I mean, yes, technically, but is anyone's code actually breaking because of this?
Who is writing SQL queries expecting them to fail because of this reason?
By your definition, "backwards compatible" doesn't mean anything. Literally everything will be a breaking change if you define "backwards compatible" like this.
tibbar
I think the term you are looking for is "forwards compatible"! Old SQL queries will still run fine on engines that support the new syntax (they're forwards compatible.) New SQL queries with trailing commas will NOT run fine on engines that don't support trailing commas; this is not a backwards-compatible change. And that's fine.
null
nightpool
Don't let the perfect be the enemy of the good. I'm sure that 99% of the people who are requesting trailing comma support care about select lists. And CREATE TABLE for the rest. Yes, the SQL standard has a huge surface area of custom syntax (rather then most programming languages which have a smaller number of composable atoms), which makes adding "consistent" syntax changes a challenge, but it doesn't mean you need to boil the ocean. Just get trailing comma select lists into a version I'm likely to use in the next decade and I will love you forever!
nerdponx
Most of that additional syntax surface area would also benefit from trailing commas. For example, `SELECT * EXCLUDE (a, b, ...)`, or even `FROM a, b, ...`.
orf
OP is massively overthinking it. Add them to CREATE TABLE and SELECT queries would remove 99.9% of annoyances.
jjice
I get where they're coming from though. Having trailing commas work in some common cases but most other cases where there are commas would be weird and definitely result in confusion. More confusion that knowing that trailing commas aren't a thing in SQL, currently.
daamien
OP is one of 7 PostgreSQL core team members. That's kind of his job to massively overthink this :)
nickcw
I feel like this ship has sailed. SQL has been around for more than 50 years and everyone who needs to generate it has already put that extra `if` statement in to suppress trailing commas.
What annoys me far more often is the lack of support for trailing commas in JSON.
reddalo
> lack of support for trailing commas in JSON
This, 100%! And the lack of comments.
Cthulhu_
JSON5 allows comments, it's been around since 2012. That said, JSON is not meant for humans / manual editing, and deciding to use it for configuration files was a mistake.
wruza
Thinking that a new, least sucking data format won’t be used for configuration was a bigger mistake. Like, yeah, I will exchange all my data in JSON now, but store configs in a good old XMLNS XSLT DTMF?
macbem
even if it wasn't meant for humans and manual editing, it works reasonably well for these usecases
recursive
How am I supposed to make changes to this configuration file?
masklinn
Funny I’m the exact opposite: I essentially never write JSON by hand, or add json content to repositories, so could not care less about the lack of trailing commas, I do semi routinely write or review SQL.
tete
I agree. And JSON basically isn't meant to be hand-written, just easy to glance over, if you need to or do basic tests with. It's a serialization format. It's not a config format or anything like that. The idea of wanting to use it for that (when the config needs to be hand-written) should be a red flag for anyone. Why would you want to hand-write something where a key is denoted with double quotes?
And just to be clear: YAML is also not a config format and wasn't meant to be. YAML is for metadata style stuff that is supposed to be close to humans, heck the whole yes/no and "not so strict" typing parts.
If you want a config format you got many options: There is toml/ini and friends on one side and UCL/HCL/... on the other. Or if you want to go really simple, do something like Postgres, Tor, etc. do and just use space separated strings.
Retr0id
I've been bitten by trailing commas in my python+sql code repeatedly, it's an easy mistake to make when python itself has trailing commas (which I make deliberate use of).
dv_dt
I feel the same way about SQL too, it's set and difficult to shift. But I also look at PRQL longingly - https://prql-lang.org/
nightpool
Have you seen the Google BQ pipe syntax? https://cloud.google.com/bigquery/docs/reference/standard-sq...
Feels like it does 75% of what PRQL does while still staying somewhat backwards compatible. Already works in BQ if you opt in.
tqwhite
Douglas Crockford made a commitment that JSON would never, ever get better. He promised us that it would always suck. He is as good as his word.
It has the small benefit that you never, ever have to worry about running into an old version of a JSON parser that bounces your fancy trailing commas.
Worth it? Not to me but Douglas Crockford does not care what I think. Or you either, apparently.
Izkata
What extra "if"?
', '.join(fields)
;)econ
The closing tags should be optional too.
[{},{},,,,{},,
Should be fine. Now you can push things to the eof.
8organicbits
You probably want jsonlines. Being able to open a file in append mode without needing to parse the whole thing is great.
econ
I get why one wants strict parsing rules but i don't see the point of closing tags. It seems nice enough to have [say] logs in json. Why would one need to add closing tags before consuming the json elsewhere? Parsing the entire thing is a huge waste of time if it is large.
I can use csv or html ofc.
wruza
To this still empty thread: how about we just stop arguing and add these damn commas everywhere? How about having human- and devenv-oriented languages finally, after how many decades?
probably_wrong
In my opinion: because the Robustness principle [1] is a non-insignificant cause of bugs and SQL injection is a major player in the vulnerability game.
The first case that jumps to me: if you write "a,b,c," you can't know whether you forgot a parameter, you passed an empty string where there shouldn't be one, or you intentionally left a trailing comma. And SQL already is human-oriented - compare your typical SQL to a data operation in K [2]. It just so happens that some things are hard and off-by-one errors are famously near the top of the list [3].
Whenever a database complains that your SQL query contains a trailing comma it's a sign that you may not have paid enough attention to your arguments (or even worse, that you're building queries by hand instead of using prepared statements). From where I stand, not allowing trailing commas is a feature, not a bug, and I would therefore object against them.
[1] "be conservative in what you do, be liberal in what you accept from others" - https://en.wikipedia.org/wiki/Robustness_principle#Criticism
[2] https://news.ycombinator.com/item?id=42999650
[3] http://www.randomprogramming.com/2014/09/quote-of-the-week-h...
boxed
This doesn't seem like it's much of an argument. Injecting `d, g` on the `b` place in your example will work fine. Trailing comma or no.
wruza
If you write "a,b,c" you can't know whether you forgot ",d" either, because if you wanted to type ",d" but got distracted and forgot it, the habit of leaving no trailing comma will lead to just "a,b,c" without ",d". And you can't know whether you forgot or mistyped a whole query either. What is this argument even, seriously? It's so weak that it is on par with suddenly having a stroke while programming. Which guardrails should we invent for that case?
SQL is fundamentally unsafe "forgot the item"-wise. It doesn't allow dynamic column selection, there's no type safety, nothing. If you want guarantees, maybe make a proper language with guarantees rather than justifying random side-effects of a comma being a syntax error sometimes.
trailingcoma
How about we just do nothing and people write syntactically-correct SQL instead of demanding everyone and everything else change? I'm sorry, is this really the most important impediment to software development right now? Some guy's beef with the SQL parser?
wruza
You really want us to focus on more important impediments (whatever that means)? Just be glad we only want commas and add them already. If that trivial why even argue.
trailingcoma
I anxiously await your pull request.
hiccuphippo
Let me start with FROM while we are at it.
ianmcgowan
I always start with "SELECT COUNT() FROM ..." for this reason, and then go back and replace the COUNT() when I get a handle on the tables/filters/groups involved..
ezekiel68
I love it. I can see no downsides (as long as the updated implementations are well tested).
I reject any argument about how mature SQL is at this point. Just bump the version number (SQL 25) if necessary and make it so.
OccamsMirror
Doesn't feel like a breaking change to me.
fifilura
IIRC BigQuery started allowing trailing commas in queries around 2019.
It all came as a very big surprise, out of thin air.
bobchadwick
That's correct, and I absolutely love it. If I move to a new role where BigQuery is not the data warehouse of choice, I think this will be the thing I'll miss most.
shrikant
Snowflake also allows trailing commas :)
morkalork
It's nice when bigquery and python together for data analysis that little things like that are congruent
tqwhite
I have to add to my huge amusement at the particulars of this thread and deep appreciation for your nerdiness. As you can see from my other post here, I consider this question to be no question at all. Obviously all SQL engines should change. Equally obviously, they never will.
That all of you can take something so futile so seriously, spend time writing about your workarounds (which, of course, we all have in spades), is simply charming.
Thanks for you being you.
efitz
There is no correct answer for this; it’s a highly personal preference.
A lot of people prefer purity of grammar; these are the kind of folks who demand coding style guidelines and will be very unhappy if you violate their preference. They’re not wrong, but they have a very strong preference.
A lot of people don’t care so much about particular style decisions, but they want readable code that is easy to understand, maintain and modify. I think a lot of the trailing-comma-preferring people fall into this category. But again, it’s a preference and isn’t right or wrong.
There are probably also people who don’t care and compete in obfuscated code contests or try to minimize line counts by putting as many statements on each line as possible or otherwise writing genius-but-unreadable code by taking advantage of language and syntax idiosyncrasies. This is a preference too (although I consider it antisocial).
My preference is, if it’s unambiguous, allow trailing commas wherever there are lists, because it makes cut and paste operations much easier.
But at the end of the day that’s just my preference and not superior to anyone else.
spprashant
Not worth the trouble. This is such a cosmetic change to appease a specific type of developer but the effort to implement that across all the DB engines of note would be monumental.
larrik
It's not just cosmetic, though, as now in order to add a new entry at the end you need to change two lines of code, which means your git blame is no longer accurate.
spprashant
Literally unusable.
phendrenad2
Or one database can have it as an option and that "specific type of developer" can just use that?
I feel the problem. When coding (not only in SQL) you often have to add something to the end of a list, and it is annoying that the end of the list is always special. You can't just copy some line and move it there. Also when moving things around you always have to take extra care at the end.
So, my solution for this was always
instead of: Leading commas also are also very regular and visible. A missing trailing comma is a lot harder to see.Before people start to mess with the standard, I'd suggest to maybe just change your coding style - and make the start of the list special - instead of the end.
I'd suggest going for a lot less trailing commas - instead of allowing more.