Windows
A catalogue of pain points on Windows.
Do we really need to pretend Windows has Unixoid symlinks?
Windows has three kinds of links: hard links (we use those via link() in win32link.c), symlinks (a class of reparse points that require unusual privileges so we can't use them) and junction points (another class of reparse points that we do use). We have a lots of code to make junction points appear to be Unix symlinks. This includes symlink(), readlink(), stat(), fstat().
We used symlinks to implement tablespaces on Unix because it was convenient and simple, but it turns out to be inconvenient and unsimple on Windows. So perhaps we should reconsider that, and just create a mapping file instead? Then we could rip out all that symlink emulation code.
Can we get better unlink semantics?
Windows has completely different locking semantics for files. We have a lot of code doing highly questionable sleep-and-retry loops in our wrappers for open(), stat(), rename(), unlink() etc to cope with this. We also have complex code to force all backends to close all file handles at certain times.
According to the testing done in this thread, we could make all of those problems go away if we enabled POSIX-mode unlink behaviour. But then PostgreSQL would only work on NTFS. It would no longer work on SMB (network file system) or ReFS (COW file system). Can we do that?
Do we need to pretend that Windows has Unixoid signals?
XXX say more
Weird socket semantics
XXX say more
Trouble with locales
It is not OK to query and record the default locale using setlocale(""), because that returns "display" names like "Norwegian (Bokmål).1252" that are unsuitable and unstable:
- they contain non-ASCII characters, but we use locale names in shared catalogues that must be ASCII, which occasionally causes strange problems (win32locale.c has some defences against that but they are kludgy and incomplete)
- the names change on Windows OS updates, and then PostgreSQL clusters using the old names break because setlocale(x) fails; this periodically happens because countries change their name ("Czech Republic" → "Czechia", "Turkey" → "Türkiye", ...)
- Bug report (there are many more)
The solution to that seems to be to recommend BCP47 names instead ("tr-TR"), and to teach initdb.c to query that default using a different interface that returns that (patch). Howevever, that raises several questions:
- when choosing a default locale in initdb, should we add ".UTF-8" (or some other "code page" AKA encoding)?
- if we don't, it seems that the encoding is the current Windows "ACP"; apparently that can be changed at any time by some settings windows? What does that means for a database cluster depending on stable behaviour?
- if we do, it is unclear why the ctype support seems not to work (or perhaps our UTF-8 support was simply always broken in this way on Windows?); unclear if this is a pre-existing condition
Windows locales don't seem to be fully transitive, as required for database use:
One option would be to drop support for the libc provider on Windows, given the above problems and the lack of interest in addressing them. That would leave users with the new "builtin" provider and the "ICU" collation provider, both of which are actively maintained and designed with database needs in mind; however we'd still need to eradicate old-style display names from other places that use locales other than for string collations (other LC_XXX categories), and PostgreSQL may also be a little inconsistent about when it uses the collation provider and when it uses libc functions for ctype logic.