From b901be1634dc884d60c42d020b432f225d6876ba Mon Sep 17 00:00:00 2001
From: "Stephen R. van den Berg" <srb@cuci.nl>
Date: Sat, 26 May 2018 13:12:19 +0200
Subject: [PATCH] pgsql: Improve _sprintf() formatting.

---
 lib/modules/Sql.pmod/pgsql.pike      | 31 +++++++-----
 lib/modules/Sql.pmod/pgsql_util.pmod | 73 +++++++++++++++-------------
 2 files changed, 57 insertions(+), 47 deletions(-)

diff --git a/lib/modules/Sql.pmod/pgsql.pike b/lib/modules/Sql.pmod/pgsql.pike
index 015d3d8847..4b5dc5fa02 100644
--- a/lib/modules/Sql.pmod/pgsql.pike
+++ b/lib/modules/Sql.pmod/pgsql.pike
@@ -1052,10 +1052,11 @@ private void startquery(int forcetext, .pgsql_util.sql_result portal, string q,
       q = .sql_util.emulate_bindings(q, bindings, this),
       paramValues = .pgsql_util.emptyarray;
     else {
-      int pi = 0, rep = 0;
+      int pi = 0;
       paramValues = allocate(sizeof(bindings));
       from = allocate(sizeof(bindings));
-      array(string) to = allocate(sizeof(bindings));
+      array(string) litfrom, litto, to = allocate(sizeof(bindings));
+      litfrom = litto = .pgsql_util.emptyarray;
       foreach (bindings; mixed name; mixed value) {
         if (stringp(name)) {	       // Throws if mapping key is empty string
           if (name[0] != ':')
@@ -1077,19 +1078,23 @@ private void startquery(int forcetext, .pgsql_util.sql_result portal, string q,
           if (!has_value(q, name))
             continue;
         }
-        from[rep] = name;
-        string rval;
-        if (multisetp(value))		// multisets are taken literally
-          rval = indices(value)*",";	// and bypass the encoding logic
-        else {
-          paramValues[pi++] = value;
-          rval = sprintf("$%d", pi);
+        if (multisetp(value)) {			// multisets are taken literally
+           litto += ({indices(value)*","});	// and bypass the encoding logic
+           litfrom += ({name});
+        } else {
+          paramValues[pi] = value;
+          to[pi] = sprintf("$%d", pi + 1);
+          from[pi++] = name;
         }
-        to[rep++] = rval;
       }
-      if(rep--)
-        q = replace(q, from = from[..rep], to = to[..rep]);
-      paramValues = pi ? paramValues[..pi-1] : .pgsql_util.emptyarray;
+      if (pi--) {
+        paramValues = paramValues[.. pi];
+        q = replace(q, litfrom += from = from[.. pi], litto += to = to[.. pi]);
+      } else {
+        paramValues = .pgsql_util.emptyarray;
+        if (sizeof(litfrom))
+          q = replace(q, litfrom, litto);
+      }
       from = ({from, to, paramValues});
     }
   } else
diff --git a/lib/modules/Sql.pmod/pgsql_util.pmod b/lib/modules/Sql.pmod/pgsql_util.pmod
index 99bdb6c03c..99a854e7b7 100644
--- a/lib/modules/Sql.pmod/pgsql_util.pmod
+++ b/lib/modules/Sql.pmod/pgsql_util.pmod
@@ -802,25 +802,28 @@ class sql_result {
         int fd = -1;
         if (c && c->socket)
           catch(fd = c->socket->query_fd());
-        res = sprintf("sql_result state: %d numrows: %d eof: %d inflight: %d\n"
-                    "query: %O\n"
+        res = sprintf(
+                      "sql_result state: %d numrows: %d eof: %d inflight: %d\n"
+                      "fd: %O portalname: %O  coltypes: %d"
+                      "  synctransact: %d laststatus: %s\n"
+                      "stash: %O\n"
 #if PG_DEBUGHISTORY > 0
-                    "history: %O\n"
-                    "stash: %O\n"
-#endif
-                    "fd: %O portalname: %O  datarows: %d"
-                    "  synctransact: %d laststatus: %s\n",
-                    _state, index, eoffound, inflight,
-                    qalreadyprinted == this ? "..." : _query,
+                      "history: %O\n"
+#endif
+                      "query: %O\n%s\n",
+                      _state, index, eoffound, inflight,
+		      fd, _portalname,
+                      datarowtypes && sizeof(datarowtypes), _synctransact,
+                      statuscmdcomplete
+                       || (_unnamedstatementkey ? "*parsing*" : ""),
+                      qalreadyprinted == this ? 0
+                                              : c && (string)c->stash,
 #if PG_DEBUGHISTORY > 0
-                    qalreadyprinted == this ? 0 : c && c->i->history,
-                    qalreadyprinted == this ? 0
-                                            : c && (string)c->stash,
-#endif
-		    fd, _portalname,
-                    datarowtypes && sizeof(datarowtypes), _synctransact,
-                    statuscmdcomplete
-                    || (_unnamedstatementkey ? "*parsing*" : ""));
+                      qalreadyprinted == this ? 0 : c && c->i->history,
+#endif
+                      qalreadyprinted == this
+                       ? "..." : replace(_query, "xxxx\n", "\\n"),
+                      qalreadyprinted == this ? "..." : _showbindings()*"\n");
         qalreadyprinted = this;
         break;
     }
@@ -852,6 +855,21 @@ class sql_result {
     transtype = _transtype;
   }
 
+  final array(string) _showbindings() {
+    array(string) msgs = emptyarray;
+    if (_params) {
+      array from, to, paramValues;
+      [from, to, paramValues] = _params;
+      if (sizeof(paramValues)) {
+        int i;
+        string val, fmt = sprintf("%%%ds %%3s %%.61s", max(@map(from, sizeof)));
+        foreach (paramValues; i; val)
+          msgs += ({sprintf(fmt, from[i], to[i], sprintf("%O", val))});
+      }
+    }
+    return msgs;
+  }
+
   //! Returns the command-complete status for this query.
   //!
   //! @note
@@ -1110,7 +1128,7 @@ class sql_result {
   }
 
   final void _preparebind(array dtoid) {
-    array(string|int) paramValues =_params ? _params[2] : emptyarray;
+    array(string|int) paramValues = _params ? _params[2] : emptyarray;
     if (sizeof(dtoid) != sizeof(paramValues))
       SUSERERROR("Invalid number of bindings, expected %d, got %d\n",
                  sizeof(dtoid), sizeof(paramValues));
@@ -1853,20 +1871,7 @@ class proxy {
   }
 
   private array(string) showbindings(sql_result portal) {
-    array(string) msgs = emptyarray;
-    array from;
-    if (portal && (from = portal._params)) {
-      array to, paramValues;
-      [from, to, paramValues] = from;
-      if (sizeof(paramValues)) {
-        string val;
-        int i;
-        string fmt = sprintf("%%%ds %%3s %%.61s", max(@map(from, sizeof)));
-        foreach (paramValues; i; val)
-          msgs += ({sprintf(fmt, from[i], to[i], sprintf("%O", val))});
-      }
-    }
-    return msgs;
+    return portal ? portal._showbindings() : emptyarray;
   }
 
   private void preplastmessage(mapping(string:string) msgresponse) {
@@ -1915,8 +1920,8 @@ class proxy {
     mixed err;
     int terminating = 0;
     err = catch {
-    conxion ci = c;		// cache value FIXME sensible?
-    conxiin cr = ci->i;		// cache value FIXME sensible?
+    conxion ci = c;		// cache value
+    conxiin cr = ci->i;		// cache value
 #ifdef PG_DEBUG
     PD("Processloop\n");
 
-- 
GitLab