Hi Peter, Thanks for your detailed analysis. I appreciate you digging deeper into the root cause.
For this patch, I'd like to keep the changes to `initdb` minimal and focused on rejecting empty usernames, as that seems to be the consensus from the previous discussion. I'll be happy to discuss the `getid()` and `aclitem` parsing behavior in a separate thread. Best regards, Jianghua Yang Peter Eisentraut <pe...@eisentraut.org> 于2025年7月2日周三 07:39写道: > On 02.07.25 04:55, Jianghua Yang wrote: > > While working with `initdb`, I noticed that passing an empty string to > > the `-U` option (e.g., `initdb -U ''`) causes it to fail with a > > misleading error: > > > > performing post-bootstrap initialization ... 2025-07-01 19:48:42.006 PDT > > [14888] FATAL:role """ does not exist at character 72 > > > > 2025-07-01 19:48:42.006 PDT [14888] STATEMENT: > > > > UPDATE pg_class SET relacl = (SELECT array_agg(a.acl) FROM(SELECT > > E'=r/""' as acl UNION SELECT unnest(pg_catalog.acldefault(CASE WHEN > > relkind = 'S' THEN 's'ELSE 'r' END::"char",10::oid)) ) as a) WHERE > > relkind IN ('r', 'v', 'm', 'S')AND relacl IS NULL; > > > > This happens because `initdb` accepts the empty string as a valid role > > name and attempts to use it as the database superuser, which is not > > intended and fails during bootstrap SQL. > > I'll start by saying, of course an empty user name isn't going to work, > so we should reject it. > > But let's dig a little deeper into why it fails. Observe the error: > > FATAL:role """ does not exist at character 72 > > It thinks that the role name is `"` (a sole double-quote, not empty!). > Why is that? > > This error comes from the literal > > E'=r/""' > > interpreted as an aclitem value. The aclitem parsing ends up in getid() > in src/backend/utils/adt/acl.c, which thinks that an input string > consisting entirely of "" is an escaped double quote. > > Maybe it's worth fixing that, and making putid() also print empty user > names correspondingly. > > Alternatively, it's the fault of initdb that it constructs aclitem > values that don't follow the aclitem-specific quoting rules. > > Another thought is, if we don't allow zero-length names, shouldn't > namein() reject empty input strings? Then this whole thing would fail > as postgres.bki is being loaded. (This is more hypothetical, since this > appears to break a number of other things.) > > All of this is to say, it's worth looking at the actual cause and think > about if there are related problems, maybe other name patterns that we > don't handle well, instead of just papering over it at the top level. > >