Thread

Commits

  1. pgbench: Use PQExpBuffer to simplify code that constructs SQL.

  2. Make command order in test more sensible

  1. pgbench - refactor init functions with buffers

    Fabien COELHO <coelho@cri.ensmp.fr> — 2019-10-22T06:32:45Z

    Hello,
    
    While developing pgbench to allow partitioned tabled, I reproduced the 
    string management style used in the corresponding functions, but was 
    pretty unhappy with that kind of pattern:
    
     	snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ...)
    
    However adding a feature is not the place for refactoring.
    
    This patch refactors initialization functions so as to use PQExpBuffer 
    where appropriate to simplify and clarify the code. SQL commands are 
    generated by accumulating parts into a buffer in order, before executing 
    it. I also added a more generic function to execute a statement and fail 
    if the result is unexpected.
    
    -- 
    Fabien.
  2. Re: pgbench - refactor init functions with buffers

    Dilip Kumar <dilipbalaut@gmail.com> — 2019-10-22T07:19:14Z

    On Tue, Oct 22, 2019 at 12:03 PM Fabien COELHO <coelho@cri.ensmp.fr> wrote:
    >
    >
    > Hello,
    >
    > While developing pgbench to allow partitioned tabled, I reproduced the
    > string management style used in the corresponding functions, but was
    > pretty unhappy with that kind of pattern:
    >
    >         snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ...)
    >
    > However adding a feature is not the place for refactoring.
    >
    > This patch refactors initialization functions so as to use PQExpBuffer
    > where appropriate to simplify and clarify the code. SQL commands are
    > generated by accumulating parts into a buffer in order, before executing
    > it. I also added a more generic function to execute a statement and fail
    > if the result is unexpected.
    >
    
    - for (i = 0; i < nbranches * scale; i++)
    + for (int i = 0; i < nbranches * scale; i++)
     ...
    - for (i = 0; i < ntellers * scale; i++)
    + for (int i = 0; i < ntellers * scale; i++)
      {
    
    I haven't read the complete patch.  But, I have noticed that many
    places you changed the variable declaration from c to c++ style (i.e
    moved the declaration in the for loop).  IMHO, generally in PG, we
    don't follow this convention.  Is there any specific reason to do
    this?
    
    -- 
    Regards,
    Dilip Kumar
    EnterpriseDB: http://www.enterprisedb.com
    
    
    
    
  3. Re: pgbench - refactor init functions with buffers

    Jeevan Ladhe <jeevan.ladhe@enterprisedb.com> — 2019-10-22T09:21:47Z

    >
    >
    > I haven't read the complete patch.  But, I have noticed that many
    > places you changed the variable declaration from c to c++ style (i.e
    > moved the declaration in the for loop).  IMHO, generally in PG, we
    > don't follow this convention.  Is there any specific reason to do
    > this?
    >
    
    +1.
    
    The patch does not apply on master, needs rebase.
    Also, I got some whitespace errors.
    
    I think you can also refactor the function tryExecuteStatement(), and
    call your newly added function executeStatementExpect() by passing
    an additional flag something like "errorOK".
    
    Regards,
    Jeevan Ladhe
    
  4. Re: pgbench - refactor init functions with buffers

    Fabien COELHO <coelho@cri.ensmp.fr> — 2019-10-22T10:00:13Z

    Hello Dilip,
    
    > - for (i = 0; i < nbranches * scale; i++)
    > + for (int i = 0; i < nbranches * scale; i++)
    > ...
    > - for (i = 0; i < ntellers * scale; i++)
    > + for (int i = 0; i < ntellers * scale; i++)
    >  {
    >
    > I haven't read the complete patch.  But, I have noticed that many
    > places you changed the variable declaration from c to c++ style (i.e
    > moved the declaration in the for loop).  IMHO, generally in PG, we
    > don't follow this convention.  Is there any specific reason to do
    > this?
    
    There are many places where it is used now in pg (120 occurrences in 
    master, 7 in pgbench). I had a bug recently because of a stupidly reused 
    index variable, so I tend to use this now it is admissible, moreover here 
    I'm actually doing a refactoring patch, so it seems ok to include that.
    
    -- 
    Fabien.
    
    
    
    
  5. Re: pgbench - refactor init functions with buffers

    Fabien COELHO <coelho@cri.ensmp.fr> — 2019-10-22T11:06:20Z

    Hello Jeevan,
    
    >> I haven't read the complete patch.  But, I have noticed that many
    >> places you changed the variable declaration from c to c++ style (i.e
    >> moved the declaration in the for loop).  IMHO, generally in PG, we
    >> don't follow this convention.  Is there any specific reason to do
    >> this?
    >
    > +1.
    
    As I said, this C99 feature is already used extensively in pg sources, so 
    it makes sense to use it when refactoring something and if appropriate, 
    which IMO is the case here.
    
    > The patch does not apply on master, needs rebase.
    
    Hmmm. "git apply pgbench-buffer-1.patch" works for me on current master.
    
    > Also, I got some whitespace errors.
    
    It possible, but I cannot see any. Could you be more specific?
    
    Many mailers do not conform to MIME and mess-up newlines when attachements 
    are typed text/*, because MIME requires the mailer to convert those to 
    crnl eol when sending and back to system eol when receiving, but few 
    actually do it. Maybe the issue is really there.
    
    > I think you can also refactor the function tryExecuteStatement(), and
    > call your newly added function executeStatementExpect() by passing
    > an additional flag something like "errorOK".
    
    Indeed, good point.
    
    -- 
    Fabien.
  6. Re: pgbench - refactor init functions with buffers

    Dilip Kumar <dilipbalaut@gmail.com> — 2019-10-22T11:27:58Z

    On Tue, Oct 22, 2019 at 3:30 PM Fabien COELHO <coelho@cri.ensmp.fr> wrote:
    >
    >
    > Hello Dilip,
    >
    > > - for (i = 0; i < nbranches * scale; i++)
    > > + for (int i = 0; i < nbranches * scale; i++)
    > > ...
    > > - for (i = 0; i < ntellers * scale; i++)
    > > + for (int i = 0; i < ntellers * scale; i++)
    > >  {
    > >
    > > I haven't read the complete patch.  But, I have noticed that many
    > > places you changed the variable declaration from c to c++ style (i.e
    > > moved the declaration in the for loop).  IMHO, generally in PG, we
    > > don't follow this convention.  Is there any specific reason to do
    > > this?
    >
    > There are many places where it is used now in pg (120 occurrences in
    > master, 7 in pgbench). I had a bug recently because of a stupidly reused
    > index variable, so I tend to use this now it is admissible, moreover here
    > I'm actually doing a refactoring patch, so it seems ok to include that.
    >
    I see.  I was under impression that we don't use this style in PG.
    But, since we are already using this style other places so no
    objection from my side for this particular point.
    Sorry for the noise.
    
    -- 
    Regards,
    Dilip Kumar
    EnterpriseDB: http://www.enterprisedb.com
    
    
    
    
  7. Re: pgbench - refactor init functions with buffers

    Jeevan Ladhe <jeevan.ladhe@enterprisedb.com> — 2019-10-22T11:33:30Z

    On Tue, Oct 22, 2019 at 4:36 PM Fabien COELHO <coelho@cri.ensmp.fr> wrote:
    
    >
    > Hello Jeevan,
    >
    > >> I haven't read the complete patch.  But, I have noticed that many
    > >> places you changed the variable declaration from c to c++ style (i.e
    > >> moved the declaration in the for loop).  IMHO, generally in PG, we
    > >> don't follow this convention.  Is there any specific reason to do
    > >> this?
    > >
    > > +1.
    >
    > As I said, this C99 feature is already used extensively in pg sources, so
    > it makes sense to use it when refactoring something and if appropriate,
    > which IMO is the case here.
    
    
    Ok, no problem.
    
    
    >
    >
    > The patch does not apply on master, needs rebase.
    >
    > Hmmm. "git apply pgbench-buffer-1.patch" works for me on current master.
    >
    > > Also, I got some whitespace errors.
    >
    > It possible, but I cannot see any. Could you be more specific?
    >
    
    For me it failing, see below:
    
    $ git log -1
    commit ad4b7aeb84434c958e2df76fa69b68493a889e4a
    Author: Peter Eisentraut <peter@eisentraut.org>
    Date:   Tue Oct 22 10:35:54 2019 +0200
    
        Make command order in test more sensible
    
        Through several updates, the CREATE USER command has been separated
        from where the user is actually used in the test.
    
    $ git apply pgbench-buffer-1.patch
    pgbench-buffer-1.patch:10: trailing whitespace.
    static void append_fillfactor(PQExpBuffer query);
    pgbench-buffer-1.patch:18: trailing whitespace.
    executeStatementExpect(PGconn *con, const char *sql, const ExecStatusType
    expected)
    pgbench-buffer-1.patch:19: trailing whitespace.
    {
    pgbench-buffer-1.patch:20: trailing whitespace.
            PGresult   *res;
    pgbench-buffer-1.patch:21: trailing whitespace.
    
    error: patch failed: src/bin/pgbench/pgbench.c:599
    error: src/bin/pgbench/pgbench.c: patch does not apply
    
    $
    
    Regards,
    Jeevan Ladhe
    
  8. Re: pgbench - refactor init functions with buffers

    Fabien COELHO <coelho@cri.ensmp.fr> — 2019-10-22T15:27:02Z

    >> The patch does not apply on master, needs rebase.
    >>
    >> Hmmm. "git apply pgbench-buffer-1.patch" works for me on current master.
    >>
    >>> Also, I got some whitespace errors.
    >>
    >> It possible, but I cannot see any. Could you be more specific?
    >
    > For me it failing, see below:
    >
    > $ git log -1
    > commit ad4b7aeb84434c958e2df76fa69b68493a889e4a
    
    Same for me, but it works:
    
       Switched to a new branch 'test'
       sh> git apply ~/pgbench-buffer-2.patch
       sh> git st
        On branch test
        Changes not staged for commit: ...
             modified:   src/bin/pgbench/pgbench.c
    
       sh> file ~/pgbench-buffer-2.patch
       .../pgbench-buffer-2.patch: unified diff output, ASCII text
    
       sh> sha1sum ~/pgbench-buffer-2.patch
       eab8167ef3ec5eca814c44b30e07ee5631914f07 ...
    
    I suspect that your mailer did or did not do something with the 
    attachment. Maybe try with "patch -p1 < foo.patch" at the root.
    
    -- 
    Fabien.
    
    
    
    
  9. Re: pgbench - refactor init functions with buffers

    Jeevan Ladhe <jeevan.ladhe@enterprisedb.com> — 2019-10-23T14:07:11Z

    I am able to apply the v2 patch with "patch -p1 "
    
    -----
    
    +static void
    +executeStatementExpect(PGconn *con, const char *sql, const ExecStatusType
    expected, bool errorOK)
    +{
    
    I think some instances like this need 80 column alignment?
    
    -----
    
    in initCreatePKeys():
    + for (int i = 0; i < lengthof(DDLINDEXes); i++)
    + {
    + resetPQExpBuffer(&query);
    + appendPQExpBufferStr(&query, DDLINDEXes[i]);
    
    I think you can simply use printfPQExpBuffer() for the first append,
    similar to
    what you have used in createPartitions(), which is a combination of both
    reset
    and append.
    
    -----
    
    The pgbench tap tests are also running fine.
    
    Regards,
    Jeevan Ladhe
    
    On Tue, Oct 22, 2019 at 8:57 PM Fabien COELHO <coelho@cri.ensmp.fr> wrote:
    
    >
    > >> The patch does not apply on master, needs rebase.
    > >>
    > >> Hmmm. "git apply pgbench-buffer-1.patch" works for me on current master.
    > >>
    > >>> Also, I got some whitespace errors.
    > >>
    > >> It possible, but I cannot see any. Could you be more specific?
    > >
    > > For me it failing, see below:
    > >
    > > $ git log -1
    > > commit ad4b7aeb84434c958e2df76fa69b68493a889e4a
    >
    > Same for me, but it works:
    >
    >    Switched to a new branch 'test'
    >    sh> git apply ~/pgbench-buffer-2.patch
    >    sh> git st
    >     On branch test
    >     Changes not staged for commit: ...
    >          modified:   src/bin/pgbench/pgbench.c
    >
    >    sh> file ~/pgbench-buffer-2.patch
    >    .../pgbench-buffer-2.patch: unified diff output, ASCII text
    >
    >    sh> sha1sum ~/pgbench-buffer-2.patch
    >    eab8167ef3ec5eca814c44b30e07ee5631914f07 ...
    >
    > I suspect that your mailer did or did not do something with the
    > attachment. Maybe try with "patch -p1 < foo.patch" at the root.
    >
    > --
    > Fabien.
    >
    
  10. Re: pgbench - refactor init functions with buffers

    Fabien COELHO <coelho@cri.ensmp.fr> — 2019-10-24T06:33:06Z

    Hello Jeevan,
    
    > +static void
    > +executeStatementExpect(PGconn *con, const char *sql, const ExecStatusType
    > expected, bool errorOK)
    > +{
    >
    > I think some instances like this need 80 column alignment?
    
    Yep. Applying the pgindent is kind-of a pain, so I tend to do a reasonable 
    job by hand and rely on the next global pgindent to fix such things. I 
    shorten the line anyway.
    
    > + resetPQExpBuffer(&query);
    > + appendPQExpBufferStr(&query, DDLINDEXes[i]);
    >
    > I think you can simply use printfPQExpBuffer() for the first append, 
    > similar to what you have used in createPartitions(), which is a 
    > combination of both reset and append.
    
    It could, but it would mean switching to using a format which is not very 
    useful here as it uses the simpler append*Str variant.
    
    While looking at it, I noticed the repeated tablespace addition just 
    afterwards, so I factored it out as well in a function.
    
    Attached v3 shorten some lines and adds "append_tablespace".
    
    -- 
    Fabien.
  11. Re: pgbench - refactor init functions with buffers

    Andres Freund <andres@anarazel.de> — 2019-11-06T02:37:36Z

    Hi,
    
    On 2019-10-24 08:33:06 +0200, Fabien COELHO wrote:
    > Attached v3 shorten some lines and adds "append_tablespace".
    
    I'd prefer not to expand the use of pqexpbuffer in more places, and
    instead rather see this use StringInfo, now that's also available to
    frontend programs.
    
    Greetings,
    
    Andres Freund
    
    
    
    
  12. Re: pgbench - refactor init functions with buffers

    Fabien COELHO <coelho@cri.ensmp.fr> — 2019-11-06T05:48:14Z

    Hello Andres,
    
    >> Attached v3 shorten some lines and adds "append_tablespace".
    
    A v4 which just extends the patch to newly added 'G'.
    
    > I'd prefer not to expand the use of pqexpbuffer in more places, and
    > instead rather see this use StringInfo, now that's also available to
    > frontend programs.
    
    Franckly, one or the other does not matter much to me.
    
    However, pgbench already uses PQExpBuffer, it uses PsqlScanState which 
    also uses PQExpBuffer, and it intrinsically depends on libpq which 
    provides PQExpBuffer: ISTM that it makes sense to keep going there, unless 
    PQExpBuffer support is to be dropped.
    
    Switching all usages would involve a significant effort and having both 
    PQExpBuffer and string_info used in the same file for the same purpose 
    would be confusing.
    
    -- 
    Fabien.
  13. Re: pgbench - refactor init functions with buffers

    Fabien COELHO <coelho@cri.ensmp.fr> — 2020-01-09T16:00:23Z

    >>> Attached v3 shorten some lines and adds "append_tablespace".
    >
    > A v4 which just extends the patch to newly added 'G'.
    
    v5 is a rebase after 30a3e772.
    
    -- 
    Fabien.
  14. Re: pgbench - refactor init functions with buffers

    David Steele <david@pgmasters.net> — 2020-03-27T16:23:26Z

    On 11/6/19 12:48 AM, Fabien COELHO wrote:
    > 
    > Hello Andres,
    > 
    >>> Attached v3 shorten some lines and adds "append_tablespace".
    > 
    > A v4 which just extends the patch to newly added 'G'.
    > 
    >> I'd prefer not to expand the use of pqexpbuffer in more places, and
    >> instead rather see this use StringInfo, now that's also available to
    >> frontend programs.
    > 
    > Franckly, one or the other does not matter much to me.
    
    FWIW, I agree with Andres with regard to using StringInfo.
    
    Also, the changes to executeStatementExpect() and adding 
    executeStatement() do not seem to fit in with the purpose of this patch.
    
    Regards,
    -- 
    -David
    david@pgmasters.net
    
    
    
    
  15. Re: pgbench - refactor init functions with buffers

    Fabien COELHO <coelho@cri.ensmp.fr> — 2020-03-27T22:13:32Z

    Hello David,
    
    >>> I'd prefer not to expand the use of pqexpbuffer in more places, and 
    >>> instead rather see this use StringInfo, now that's also available to 
    >>> frontend programs.
    >> 
    >> Franckly, one or the other does not matter much to me.
    >
    > FWIW, I agree with Andres with regard to using StringInfo.
    
    Ok. I find it strange to mix PQExpBuffer & StringInfo in the same file.
    
    > Also, the changes to executeStatementExpect() and adding executeStatement() 
    > do not seem to fit in with the purpose of this patch.
    
    Yep, that was in passing.
    
    Attached a v6 which uses StringInfo, and the small refactoring as a 
    separate patch.
    
    -- 
    Fabien.
  16. Re: pgbench - refactor init functions with buffers

    David Steele <david@pgmasters.net> — 2020-03-27T22:26:32Z

    On 3/27/20 6:13 PM, Fabien COELHO wrote:
    > 
    > Hello David,
    > 
    >>>> I'd prefer not to expand the use of pqexpbuffer in more places, and 
    >>>> instead rather see this use StringInfo, now that's also available to 
    >>>> frontend programs.
    >>>
    >>> Franckly, one or the other does not matter much to me.
    >>
    >> FWIW, I agree with Andres with regard to using StringInfo.
    > 
    > Ok. I find it strange to mix PQExpBuffer & StringInfo in the same file.
    
    Agreed, but we'd rather use StringInfo going forward.  However, I don't 
    think that puts you on the hook for updating all the PQExpBuffer references.
    
    Unless you want to...
    
    >> Also, the changes to executeStatementExpect() and adding 
    >> executeStatement() do not seem to fit in with the purpose of this patch.
    > 
    > Yep, that was in passing.
    > 
    > Attached a v6 which uses StringInfo, and the small refactoring as a 
    > separate patch.
    
    I think that's better, thanks.
    
    Regards,
    -- 
    -David
    david@pgmasters.net
    
    
    
    
  17. Re: pgbench - refactor init functions with buffers

    Fabien COELHO <coelho@cri.ensmp.fr> — 2020-03-27T22:59:24Z

    >> Ok. I find it strange to mix PQExpBuffer & StringInfo in the same file.
    >
    > Agreed, but we'd rather use StringInfo going forward.  However, I don't think 
    > that puts you on the hook for updating all the PQExpBuffer references.
    >
    > Unless you want to...
    
    I cannot say that I "want" to fix something which already works the same 
    way, because it is against my coding principles.
    
    However there may be some fun in writing a little script to replace one 
    with the other automatically. I counted nearly 3500 calls under src/bin.
    
    -- 
    Fabien.
    
    
    
    
  18. Re: pgbench - refactor init functions with buffers

    Tom Lane <tgl@sss.pgh.pa.us> — 2020-03-27T23:57:12Z

    Fabien COELHO <coelho@cri.ensmp.fr> writes:
    >>> Ok. I find it strange to mix PQExpBuffer & StringInfo in the same file.
    
    >> Agreed, but we'd rather use StringInfo going forward.  However, I don't think 
    >> that puts you on the hook for updating all the PQExpBuffer references.
    >> Unless you want to...
    
    > I cannot say that I "want" to fix something which already works the same 
    > way, because it is against my coding principles.
    > However there may be some fun in writing a little script to replace one 
    > with the other automatically. I counted nearly 3500 calls under src/bin.
    
    Yeah, that's the problem.  If someone does come forward with a patch to do
    that, I think it'd be summarily rejected, at least in high-traffic code
    like pg_dump.  The pain it'd cause for back-patching would outweigh the
    value.
    
    That being the case, I'd think a better design principle is "make your
    new code look like the code around it", which would tend to weigh against
    introducing StringInfo uses into pgbench when there's none there now and
    a bunch of PQExpBuffer instead.  So I can't help thinking the advice
    you're being given here is suspect.
    
    			regards, tom lane
    
    
    
    
  19. Re: pgbench - refactor init functions with buffers

    Alvaro Herrera <alvherre@2ndquadrant.com> — 2020-03-28T01:52:26Z

    On 2020-Mar-27, Tom Lane wrote:
    
    > That being the case, I'd think a better design principle is "make your
    > new code look like the code around it", which would tend to weigh against
    > introducing StringInfo uses into pgbench when there's none there now and
    > a bunch of PQExpBuffer instead.  So I can't help thinking the advice
    > you're being given here is suspect.
    
    +1 for keeping it PQExpBuffer-only, until such a time when you need a
    StringInfo feature that's not in PQExpBuffer -- and even at that point,
    I think you'd switch just that one thing to StringInfo, not the whole
    program.
    
    -- 
    Álvaro Herrera                https://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
    
    
    
    
  20. Re: pgbench - refactor init functions with buffers

    Fabien COELHO <coelho@cri.ensmp.fr> — 2020-03-28T09:46:02Z

    Hello Tom,
    
    >> I cannot say that I "want" to fix something which already works the same
    >> way, because it is against my coding principles. [...]
    >> I counted nearly 3500 calls under src/bin.
    >
    > Yeah, that's the problem.  If someone does come forward with a patch to do
    > that, I think it'd be summarily rejected, at least in high-traffic code
    > like pg_dump.  The pain it'd cause for back-patching would outweigh the
    > value.
    
    What about "typedef StringInfoData PQExpBufferData" and replacing 
    PQExpBuffer by StringInfo internally, just keeping the old interface 
    around because it is there? That would remove a few hundreds clocs.
    
    ISTM that with inline and varargs macro the substition can be managed 
    reasonably lightly, depending on what level of compatibility is required 
    for libpq: should it be linkability, or requiring a recompilation is ok?
    
    A clear benefit is that there are quite a few utils for PQExpBuffer in 
    "fe_utils/string_utils.c" which would become available for StringInfo, 
    which would help using StringInfo without duplicating them.
    
    > That being the case, I'd think a better design principle is "make your
    > new code look like the code around it",
    
    Yep.
    
    > which would tend to weigh against introducing StringInfo uses into 
    > pgbench when there's none there now and a bunch of PQExpBuffer instead.
    > So I can't help thinking the advice you're being given here is suspect.
    
    Well, that is what I was saying, but at 2 against 1, I fold.
    
    -- 
    Fabien.
    
    
    
    
  21. Re: pgbench - refactor init functions with buffers

    David Steele <david@pgmasters.net> — 2020-03-28T14:36:58Z

    On 3/27/20 9:52 PM, Alvaro Herrera wrote:
    > On 2020-Mar-27, Tom Lane wrote:
    > 
    >> That being the case, I'd think a better design principle is "make your
    >> new code look like the code around it", which would tend to weigh against
    >> introducing StringInfo uses into pgbench when there's none there now and
    >> a bunch of PQExpBuffer instead.  So I can't help thinking the advice
    >> you're being given here is suspect.
    > 
    > +1 for keeping it PQExpBuffer-only, until such a time when you need a
    > StringInfo feature that's not in PQExpBuffer -- and even at that point,
    > I think you'd switch just that one thing to StringInfo, not the whole
    > program.
    
    I think I need to be careful what I joke about.  It wasn't my intention 
    to advocate changing all the existing *PQExpBuffer() calls in bin.
    
    But, the only prior committer to look at this patch expressed a 
    preference for StringInfo so in the absence of any other input I thought 
    it might move the patch forward if I reinforced that.  Now it seems the 
    consensus has moved in favor of *PQExpBuffer().
    
    Fabien has provided a patch in each flavor, so I guess the question is: 
    is it committable either way?
    
    Regards,
    -- 
    -David
    david@pgmasters.net
    
    
    
    
  22. Re: pgbench - refactor init functions with buffers

    Andres Freund <andres@anarazel.de> — 2020-03-28T18:34:34Z

    Hi,
    
    On 2020-03-27 19:57:12 -0400, Tom Lane wrote:
    > Fabien COELHO <coelho@cri.ensmp.fr> writes:
    > >>> Ok. I find it strange to mix PQExpBuffer & StringInfo in the same file.
    > 
    > >> Agreed, but we'd rather use StringInfo going forward.  However, I don't think 
    > >> that puts you on the hook for updating all the PQExpBuffer references.
    > >> Unless you want to...
    > 
    > > I cannot say that I "want" to fix something which already works the same 
    > > way, because it is against my coding principles.
    > > However there may be some fun in writing a little script to replace one 
    > > with the other automatically. I counted nearly 3500 calls under src/bin.
    > 
    > Yeah, that's the problem.  If someone does come forward with a patch to do
    > that, I think it'd be summarily rejected, at least in high-traffic code
    > like pg_dump.  The pain it'd cause for back-patching would outweigh the
    > value.
    
    Sure, but that's not at all what was proposed.
    
    
    > That being the case, I'd think a better design principle is "make your
    > new code look like the code around it", which would tend to weigh against
    > introducing StringInfo uses into pgbench when there's none there now and
    > a bunch of PQExpBuffer instead.  So I can't help thinking the advice
    > you're being given here is suspect.
    
    I don't agree with this. This is a "fresh" usage of StringInfo. That's
    different to adding one new printed line among others built with
    pqexpbuffer. If we continue adding large numbers of new uses of both
    pieces of infrastructure, we're just making things more confusing.
    
    Greetings,
    
    Andres Freund
    
    
    
    
  23. Re: pgbench - refactor init functions with buffers

    Tom Lane <tgl@sss.pgh.pa.us> — 2020-03-28T18:49:31Z

    Andres Freund <andres@anarazel.de> writes:
    > On 2020-03-27 19:57:12 -0400, Tom Lane wrote:
    >> That being the case, I'd think a better design principle is "make your
    >> new code look like the code around it", which would tend to weigh against
    >> introducing StringInfo uses into pgbench when there's none there now and
    >> a bunch of PQExpBuffer instead.  So I can't help thinking the advice
    >> you're being given here is suspect.
    
    > I don't agree with this. This is a "fresh" usage of StringInfo. That's
    > different to adding one new printed line among others built with
    > pqexpbuffer. If we continue adding large numbers of new uses of both
    > pieces of infrastructure, we're just making things more confusing.
    
    Why?  I'm not aware of any intention to deprecate/remove PQExpBuffer,
    and I doubt it'd be a good thing to try.  It does some things that
    StringInfo won't, notably cope with OOM without crashing.
    
    			regards, tom lane
    
    
    
    
  24. Re: pgbench - refactor init functions with buffers

    Andres Freund <andres@anarazel.de> — 2020-03-28T19:04:11Z

    On 2020-03-28 14:49:31 -0400, Tom Lane wrote:
    > Andres Freund <andres@anarazel.de> writes:
    > > On 2020-03-27 19:57:12 -0400, Tom Lane wrote:
    > >> That being the case, I'd think a better design principle is "make your
    > >> new code look like the code around it", which would tend to weigh against
    > >> introducing StringInfo uses into pgbench when there's none there now and
    > >> a bunch of PQExpBuffer instead.  So I can't help thinking the advice
    > >> you're being given here is suspect.
    > 
    > > I don't agree with this. This is a "fresh" usage of StringInfo. That's
    > > different to adding one new printed line among others built with
    > > pqexpbuffer. If we continue adding large numbers of new uses of both
    > > pieces of infrastructure, we're just making things more confusing.
    > 
    > Why?  I'm not aware of any intention to deprecate/remove PQExpBuffer,
    > and I doubt it'd be a good thing to try.  It does some things that
    > StringInfo won't, notably cope with OOM without crashing.
    
    - code using it cannot easily be shared between frontend/backend (no
      memory context integration etc)
    - most code does *not* want to deal with the potential for OOM without
      erroring out
    - it's naming is even more confusing than StringInfo
    - it introduces dependencies to libpq even when not needed
    - both stringinfo and pqexpbuffer are performance relevant in some uses,
      needing to optimize both is wasted effort
    - we shouldn't expose everyone to both APIs except where needed - it's
      stuff one has to learn
    
    
    
    
  25. Re: pgbench - refactor init functions with buffers

    Tom Lane <tgl@sss.pgh.pa.us> — 2020-03-28T19:16:21Z

    Andres Freund <andres@anarazel.de> writes:
    > On 2020-03-28 14:49:31 -0400, Tom Lane wrote:
    >> Why?  I'm not aware of any intention to deprecate/remove PQExpBuffer,
    >> and I doubt it'd be a good thing to try.  It does some things that
    >> StringInfo won't, notably cope with OOM without crashing.
    
    > - code using it cannot easily be shared between frontend/backend (no
    >   memory context integration etc)
    
    True, but also pretty irrelevant for pgbench and similar code.
    
    > - most code does *not* want to deal with the potential for OOM without
    >   erroring out
    
    Fair point.
    
    > - it's naming is even more confusing than StringInfo
    
    Eye of the beholder ...
    
    > - it introduces dependencies to libpq even when not needed
    
    Most of our FE programs do include libpq, and pgbench certainly does,
    so this seems like a pretty irrelevant objection as well.
    
    > - both stringinfo and pqexpbuffer are performance relevant in some uses,
    >   needing to optimize both is wasted effort
    
    I'm not aware that anybody is trying to micro-optimize either.  Even
    if someone is, it doesn't imply that they need to change both.
    
    > - we shouldn't expose everyone to both APIs except where needed - it's
    >   stuff one has to learn
    
    That situation is unlikely to change in the foreseeable future.
    Moreover, using both APIs in one program, where we were not before,
    makes it worse not better.
    
    			regards, tom lane
    
    
    
    
  26. Re: pgbench - refactor init functions with buffers

    Andres Freund <andres@anarazel.de> — 2020-03-28T19:34:16Z

    On 2020-03-28 15:16:21 -0400, Tom Lane wrote:
    > Andres Freund <andres@anarazel.de> writes:
    > > - both stringinfo and pqexpbuffer are performance relevant in some uses,
    > >   needing to optimize both is wasted effort
    > 
    > I'm not aware that anybody is trying to micro-optimize either.
    
    https://postgr.es/m/5450.1578797036%40sss.pgh.pa.us
    
    
    
    
  27. Re: pgbench - refactor init functions with buffers

    Fabien COELHO <coelho@cri.ensmp.fr> — 2020-03-29T05:44:31Z

    Hello Andres,
    
    >> That being the case, I'd think a better design principle is "make your
    >> new code look like the code around it", which would tend to weigh against
    >> introducing StringInfo uses into pgbench when there's none there now and
    >> a bunch of PQExpBuffer instead.  So I can't help thinking the advice
    >> you're being given here is suspect.
    >
    > I don't agree with this. This is a "fresh" usage of StringInfo. That's
    > different to adding one new printed line among others built with
    > pqexpbuffer. If we continue adding large numbers of new uses of both
    > pieces of infrastructure, we're just making things more confusing.
    
    My 0.02 € :
    
      - I'm in favor or having one tool for one purpose, so a fe/be common
    StringInfo interface is fine with me;
    
      - I prefer to avoid using both PQExpBuffer & StringInfo in the same file, 
    because they do the exact same thing and it is locally confusing;
    
      - I'd be fine with switching all of pgbench to StringInfo, as there are 
    only 31 uses;
    
      - But, pgbench relies on psql scanner, which uses PQExpBuffer in 
    PsqlScanState, so mixing is unavoidable, unless PQExpBuffer & StringInfo
    are the same thing (i.e. typedef + cpp/inline/function wrappers);
    
      - There are 1260 uses of PQExpBuffer in psql that, although they are 
    trivial, I'm in no hurry to update.
    
    -- 
    Fabien.
  28. Re: pgbench - refactor init functions with buffers

    Fabien COELHO <coelho@cri.ensmp.fr> — 2020-07-09T07:05:27Z

    > in favor of *PQExpBuffer().
    
    Attached v7 is rebased v5 which uses PQExpBuffer, per cfbot.
    
    -- 
    Fabien.
  29. Re: pgbench - refactor init functions with buffers

    Heikki Linnakangas <hlinnaka@iki.fi> — 2020-09-30T07:59:30Z

    On 09/07/2020 10:05, Fabien COELHO wrote:
    >> in favor of *PQExpBuffer().
    > 
    > Attached v7 is rebased v5 which uses PQExpBuffer, per cfbot.
    
    Thanks! I pushed this with small changes:
    
    - I left out the changes to executeStatement(). I'm not quite convinced 
    it's a good idea or worth it, and it's unrelated to the main part of 
    this patch, so let's handle that separately.
    
    - I also left out changes to use the C99-style "for (int i = 0; ...)" 
    construct. I think that's a good change for readability, but again 
    unrelated to this and hardly worth changing existing code for.
    
    - I inlined the append_tablespace() function back to the callers. And I 
    did the same to the append_fillfactor() function, too. It seems more 
    readable to just call appendPQExpBuffer() diretly, than encapulate the 
    single appendPQExpBuffer() call in a helper function.
    
    > @@ -3880,15 +3868,16 @@ initGenerateDataClientSide(PGconn *con)
    >  
    >  	INSTR_TIME_SET_CURRENT(start);
    >  
    > +	/* printf overheads should probably be avoided... */
    >  	for (k = 0; k < (int64) naccounts * scale; k++)
    >  	{
    >  		int64		j = k + 1;
    >  
    >  		/* "filler" column defaults to blank padded empty string */
    > -		snprintf(sql, sizeof(sql),
    > -				 INT64_FORMAT "\t" INT64_FORMAT "\t%d\t\n",
    > -				 j, k / naccounts + 1, 0);
    > -		if (PQputline(con, sql))
    > +		printfPQExpBuffer(&sql,
    > +						  INT64_FORMAT "\t" INT64_FORMAT "\t%d\t\n",
    > +						  j, k / naccounts + 1, 0);
    > +		if (PQputline(con, sql.data))
    >  		{
    >  			pg_log_fatal("PQputline failed");
    >  			exit(1);
    
    Can you elaborate what you meant by the new "print overheads should 
    probably be avoided" comment? I left that out since it seems unrelated 
    to switching to PQExpBuffer.
    
    - Heikki
    
    
    
    
  30. Re: pgbench - refactor init functions with buffers

    Fabien COELHO <coelho@cri.ensmp.fr> — 2020-10-02T08:55:40Z

    > Can you elaborate what you meant by the new "print overheads should probably 
    > be avoided" comment?
    
    Because printf is slow and this is on the critical path of data 
    generation. Printf has to interpret the format each time just to print 
    three ints, specialized functions could be used which would allow to skip 
    the repeated format parsing.
    
    > I left that out since it seems unrelated to switching to PQExpBuffer.
    
    Yep.
    
    Thanks for the commit. Getting rid of most snprintf is a relief.
    
    -- 
    Fabien.