Blog ·
A name that cannot be translated
Nine languages said nine different things about one foreign key clause. Eight of them were correct translations, and that was the whole problem.
By Provibr
We publish every article in nine languages. A reader working through one of them noticed something that looks trivial written down and took two rounds to fix properly: a sentence about a foreign key said a different thing in every language, and all nine were right.
The sentence explains why a child row being cleaned up must not take its parent's wait with it. In the schema that is one clause, and the clause has a name.
Eight correct translations and no name
Here is what the same clause looked like across the catalogue before we touched it.
| Language | What the sentence said |
|---|---|
| English | set null rather than cascade |
| Dutch | op leegmaken en niet op meeverwijderen |
| German | auf null setzen statt auf kaskadieren |
| Spanish | pone a nulo en lugar de propagar el borrado |
| French | mise à nul, pas cascade |
| Italian | impostata a nullo invece che a cascata |
| Portuguese | anula em vez de propagar a eliminação |
| Romanian | pusă pe null și nu în cascadă |
| Ukrainian | ставить null, а не каскадує |
Every one of those is a good sentence. The Dutch is arguably the best writing on the list; it explains the behaviour to somebody who has never seen a schema. It is also the one furthest from being usable, because a reader who wants to check what we actually did has nothing to type.
The two things you write in a Postgres schema are SET NULL and CASCADE. They are not descriptions of a behaviour, they are the identifiers of one, and a description of an identifier is not an identifier.
The defect was in the source
It is tempting to treat this as eight translation errors. It is one source error, and reading it that way is what made the repair small.
The English said set null rather than cascade, lower case, running in the sentence, with no marking of any kind. A translator handed that produces prose, because that is what it is. Every one of the eight did their job correctly on the material they were given.
So the change is not eight corrections. It is one decision about form, applied nine times, and it changes the English too.
The form question was answered by measuring, not by taste
Should it be SET NULL in capitals, or set null in lower case? Both are defensible in the abstract, and in the abstract is exactly where that argument never ends.
So we looked at what the rest of the corpus already does with SQL inside backticks. There are nine occurrences: WHERE twice, UPDATE twice, DROP twice, a bare DELETE, a SELECT 1 in a monitoring check, and one FOR UPDATE SKIP LOCKED. All of them upper case.
There are also backticked lower case tokens that look like counterexamples and are not. A unique that turns out to be a flag on somebody's API. A where that is the name of a constant in JavaScript. A null that is a value rather than a clause.
Which gives the actual rule, and it is not about capitals. The distinction is between a keyword and a name. A keyword of the language goes in upper case because that is how the language is written down; a name that happens to look like one keeps whatever case its owner gave it. Deciding on case alone would have produced the right answer here for the wrong reason, and the wrong answer somewhere else.
The corpus is also a reminder that one token can be two names. Most occurrences of DELETE in our articles are not SQL at all, they are the HTTP method in things like DELETE /servers/{id}. Same letters, different language, and no rule about capitals distinguishes them.
A form decision has a scope, and the scope has an edge
The first round fixed the article the reader had been reading. A check afterwards showed that a second article made the same statement about a schema on one line, without the token, so a second round did that one.
That is worth saying plainly, because a decision about form is not finished when the file that prompted it is finished. Before that second round a token check reported both names as simply absent from the English; afterwards it made twenty four counts across the languages with no deviations.
The edge is the part that took the thinking. The rule is does this sentence name a clause, not does the word cascade appear. In the same article, further down the same paragraph, there is a sentence about a cascade from a short lived table into a long lived one. That is a description of a consequence, not a reference to a clause, and it stays as prose in whatever the language would naturally say.
We measured that boundary across the whole English catalogue rather than trusting it: three phrasings that could plausibly be naming a clause, searched outside backticks in every English article. Nine hits at the time, five of them in the article the second round was about. The four elsewhere were a reference being set to a null value, a section heading about cleanup on delete as a strategy, a remark that a particular row participates in no cascade, and a 404 on a delete request. Not one of them names a clause. After both rounds seven remain, and the article the first round repaired no longer appears in the list at all, which is the cheapest possible confirmation that the change went where it was meant to.
What stays with the language
The names are identical in all nine files. The sentence around them is not, and should not be.
German still says the foreign key steht auf, Dutch staat op, Portuguese está em. The verb, the preposition and the word order belong to the language. Only the two names are fixed, and they are fixed because they are quotations from Postgres rather than statements of ours.
The mechanical parts held. The renderer produces a real code element even when the token sits inside bold text, which it does in the numbered list at the end of each article. The French non breaking space before a colon survived a repair that rewrote the clause immediately in front of it, which is the sort of thing that quietly disappears when somebody retypes a line.
And the diffs are the evidence that the rule was narrow enough. Three lines in and three lines out per file in the first round, one in and one out in the second. A repair of this kind that touches ten lines has redecorated something.
What we would write down
- Eight correct translations can still be a defect. Correctness of the sentence is not the same as presence of the name.
- The defect is usually in the source. Prose in, prose out, and the translators are not the problem.
- A name is a form question, not a language question. It gets marked once and copied everywhere.
- Measure the house form on the corpus instead of debating it in the abstract.
- The distinction is keyword versus name, not upper versus lower case.
- One token can be two names. Most of our
DELETEis HTTP, not SQL. - Draw the boundary at whether a sentence names a clause, not at whether the word appears.
- Check the sister article. A form decision has a scope, and it is rarely one file.
- Leave the verb to the language. Fixing the name does not mean fixing the sentence.
- A small diff is the evidence. Three lines in and three out means the rule was narrow.
For clarity about what this is: two rounds, the first putting the two names into nine files at three lines in and three lines out each, the second doing one line in and one out on a second article; the content build produced 886 articles with no warnings and the content check found 887 of 887 generated files byte identical, the web suite at 4604 green, the token comparison at 40 counts and then 24 counts with no deviations, the fact comparison at 296 and 256 with none, the byte sweep clean, and three guards proven red before they were believed green. The corpus reading was three phrasings across 124 English articles. Not proven: each translation still has one reader, none of them a native speaker, and there is no browser check of how the token renders in all nine languages.
From the platform work on Provibr. The article all this was about is the child wakes the parent, what nine catalogues do to a fixed set of controls is in sixteen thousand keys, nine languages, and another case where the translation was correct and the shape was wrong is in the select goes around the sentence.