Thread

Commits

  1. Avoid using atooid for numerical comparisons which arent Oids

  1. The use of atooid() on non-Oid results

    Daniel Gustafsson <daniel@yesql.se> — 2023-03-16T10:20:24Z

    When looking at the report in [0] an API choice in the relevant pg_upgrade code
    path stood out as curious.  check_is_install_user() runs this query to ensure
    that only the install user is present in the cluster:
    
        res = executeQueryOrDie(conn,
                                "SELECT COUNT(*) "
                                "FROM pg_catalog.pg_roles "
                                "WHERE rolname !~ '^pg_'");
    
    The result is then verified with the following:
    
        if (cluster == &new_cluster && atooid(PQgetvalue(res, 0, 0)) != 1)
            pg_fatal("Only the install user can be defined in the new cluster.");
    
    This was changed from atoi() in ee646df59 with no specific comment on why.
    This is not a bug, since atooid() will do the right thing here, but it threw me
    off reading the code and might well confuse others.  Is there a reason not to
    change this back to atoi() for code clarity as we're not reading an Oid here?
    
    --
    Daniel Gustafsson
    
    [0] VE1P191MB1118E9752D4EAD45205E995CD6BF9@VE1P191MB1118.EURP191.PROD.OUTLOOK.COM
    
    
    
  2. Re: The use of atooid() on non-Oid results

    Tom Lane <tgl@sss.pgh.pa.us> — 2023-03-16T14:58:12Z

    Daniel Gustafsson <daniel@yesql.se> writes:
    > When looking at the report in [0] an API choice in the relevant pg_upgrade code
    > path stood out as curious.  check_is_install_user() runs this query to ensure
    > that only the install user is present in the cluster:
    
    >     res = executeQueryOrDie(conn,
    >                             "SELECT COUNT(*) "
    >                             "FROM pg_catalog.pg_roles "
    >                             "WHERE rolname !~ '^pg_'");
    
    > The result is then verified with the following:
    
    >     if (cluster == &new_cluster && atooid(PQgetvalue(res, 0, 0)) != 1)
    >         pg_fatal("Only the install user can be defined in the new cluster.");
    
    > This was changed from atoi() in ee646df59 with no specific comment on why.
    > This is not a bug, since atooid() will do the right thing here, but it threw me
    > off reading the code and might well confuse others.  Is there a reason not to
    > change this back to atoi() for code clarity as we're not reading an Oid here?
    
    Hmm ... in principle, you could have more than 2^31 entries in pg_roles,
    but not more than 2^32 since they all have to have distinct OIDs.  So
    I can see the point of avoiding that theoretical overflow hazard.  But
    personally I'd probably avoid assuming anything about how wide the COUNT()
    result could be, and instead writing
    
    	... && strcmp(PQgetvalue(res, 0, 0), "1") != 0)
    
    			regards, tom lane
    
    
    
    
  3. Re: The use of atooid() on non-Oid results

    Daniel Gustafsson <daniel@yesql.se> — 2023-03-16T19:17:15Z

    > On 16 Mar 2023, at 15:58, Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > 
    > Daniel Gustafsson <daniel@yesql.se> writes:
    >> When looking at the report in [0] an API choice in the relevant pg_upgrade code
    >> path stood out as curious.  check_is_install_user() runs this query to ensure
    >> that only the install user is present in the cluster:
    > 
    >>    res = executeQueryOrDie(conn,
    >>                            "SELECT COUNT(*) "
    >>                            "FROM pg_catalog.pg_roles "
    >>                            "WHERE rolname !~ '^pg_'");
    > 
    >> The result is then verified with the following:
    > 
    >>    if (cluster == &new_cluster && atooid(PQgetvalue(res, 0, 0)) != 1)
    >>        pg_fatal("Only the install user can be defined in the new cluster.");
    > 
    >> This was changed from atoi() in ee646df59 with no specific comment on why.
    >> This is not a bug, since atooid() will do the right thing here, but it threw me
    >> off reading the code and might well confuse others.  Is there a reason not to
    >> change this back to atoi() for code clarity as we're not reading an Oid here?
    > 
    > Hmm ... in principle, you could have more than 2^31 entries in pg_roles,
    > but not more than 2^32 since they all have to have distinct OIDs.  So
    > I can see the point of avoiding that theoretical overflow hazard.  But
    > personally I'd probably avoid assuming anything about how wide the COUNT()
    > result could be, and instead writing
    > 
    > 	... && strcmp(PQgetvalue(res, 0, 0), "1") != 0)
    
    Yeah, that makes sense.  I'll go ahead with that solution instead and possibly
    a brief addition to the comment.
    
    --
    Daniel Gustafsson