Hi,

I usually use host-based authentication with ident to connect to
PostgreSQL from trusted machines, so I've been specifying a password
of NIL for a long time.  However, when passwordless authentication
fails and NIL is given as a password, POSTMODERN:CONNECT will behave
erratically.

In my case, the symptoms are:

  * SBCL (Debian 1:1.0.18.0-2) RAM usage balloons to hundreds of
    megabytes.

  * I get this condition printed, along with a tag-along (obscure and
    what I assume to be) object, for the heck of it:

---8<---8<---
* (postmodern:connect "piranha" "piranha" nil "localhost")
debugger invoked on a TYPE-ERROR in thread #<THREAD "initial thread" RUNNING 
{1002669C31}>:
  The value NIL is not of type (MOD 1152921504606846975).

Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

(SB-KERNEL:UB32-BASH-COPY
 "piranha"
 0
 ""
 NIL
 7)[:EXTERNAL]
--->8--->8---

That's invoking SBCL on the command-line.  When I use SLIME:

  * SBCL, like a gas, expands to fill all available space
    (e.g. ~1.8GiB before I ran out of RAM+swap and rebooted the
    virtual machine).
  
  * During this time, nothing ever comes back to emacs.
  
  * If I do a SLIME interrupt before the system completely dies, emacs
    takes a while to do anything, then enters the emacs (not SLIME!)
    debugger, and informs me that the "variable binding depth exceeds
    max-specpdl-size" at every available opportunity until I restart
    emacs.

It turns out bad things happen when you optimize for safety 0.  Making
this change:

diff -x'*~' -urN postmodern-1.16/cl-postgres/package.lisp 
postmodern-1.16-no_opt/cl-postgres/package.lisp
--- postmodern-1.16/cl-postgres/package.lisp    2010-04-02 04:23:24.000000000 
-0700
+++ postmodern-1.16-no_opt/cl-postgres/package.lisp     2010-04-06 
06:00:47.000000000 -0700
@@ -83,5 +83,5 @@
 (eval-when (:compile-toplevel :load-toplevel :execute)
   ;; Optimization settings (only used by functions that need it).
   (defparameter *optimize*
-    '(optimize (speed 3) (safety 0) (space 1) (debug 1)
+    '(optimize (speed 3) (space 1) (debug 1)
       (compilation-speed 0))))

yields a much more sensible, instantaneous, and non-ballooning:

  The value NIL is not of type STRING.
     [Condition of type TYPE-ERROR]

Of course, bad things also happen when you pass objects of the wrong
type to a function.  (It just never sat well with me to pass a string
password when no password was needed; NIL seemed to make much more
sense, and it worked...)

I've attached a patch to:

  * Check the types of arguments given to CL-POSTGRES:OPEN-DATABASE.
  
  * Update the HTML documentation to describe the expected types of
    arguments to CL-POSTGRES:OPEN-DATABASE and POSTMODERN:CONNECT.
  
  * Update the documentation strings for the above two functions to
    contain the same content as their descriptions in the HTML
    documentation.

I also humbly suggest not optimizing for safety 0.  One of the big
reasons I use CL, and not something like C, is because I value safety:
when one thing breaks, that breakage is self-contained and can be
tracked down due to conditions.  I don't want my Lisp process to go
down like the Hindenburg when one little thing goes wrong.

Thanks for your time,

-- 
J.P. Larocque <j...@thoughtcrime.us>
diff -urN -x'*~' postmodern-1.16/cl-postgres/public.lisp postmodern-1.16-stricter/cl-postgres/public.lisp
--- postmodern-1.16/cl-postgres/public.lisp	2010-04-02 04:23:24.000000000 -0700
+++ postmodern-1.16-stricter/cl-postgres/public.lisp	2010-04-06 07:01:44.000000000 -0700
@@ -32,7 +32,21 @@
        (open-stream-p (connection-socket connection))))
 
 (defun open-database (database user password host &optional (port 5432) (use-ssl :no))
-  "Create and connect a database object. use-ssl may be :no, :yes, or :try."
+  "Create and open a connection for the specified server, database,
+and user. Database, user, and password must be strings, and port must
+be an integer. (Even if a password isn't required, a string must be
+given.) Host may be a string containing a hostname or IP address to
+make a TCP connection to, or :unix to connect via a local Unix-domain
+socket (in which case port still determines which PostgreSQL instance
+to connect to). use-ssl may be :no, :yes, or :try, where :try means
+'if the server supports it'. When it is anything but :no, you must
+have the CL+SSL package loaded to initiate the connection."
+  (check-type database string)
+  (check-type user string)
+  (check-type password string)
+  (check-type host (or string (eql :unix)) "a string or :unix")
+  (check-type port (integer 1 65535) "an integer from 1 to 65535")
+  (check-type use-ssl (member :no :yes :try) ":no, :yes, or :try")
   (let ((conn (make-instance 'database-connection :host host :port port :user user
                              :password password :socket nil :db database :ssl use-ssl)))
     (initiate-connection conn)
diff -urN -x'*~' postmodern-1.16/doc/cl-postgres.html postmodern-1.16-stricter/doc/cl-postgres.html
--- postmodern-1.16/doc/cl-postgres.html	2010-04-02 04:23:24.000000000 -0700
+++ postmodern-1.16-stricter/doc/cl-postgres.html	2010-04-06 06:54:39.000000000 -0700
@@ -47,7 +47,13 @@
     </p>
 
     <p class="desc">Create and open a connection for the specified
-    server, database, and user. <code>use-ssl</code> may be
+    server, database, and user. Database, user, and password must be
+    strings, and port must be an integer. (Even if a password isn't
+    required, a string must be given.) Host may be a string containing
+    a hostname or IP address to make a TCP connection to, or :unix to
+    connect via a local Unix-domain socket (in which case port still
+    determines which PostgreSQL instance to connect
+    to). <code>use-ssl</code> may be
     <code>:no</code>, <code>:yes</code>, or <code>:try</code>, where
     <code>:try</code> means 'if the server supports it'. When it is
     anything but <code>:no</code>, you must have the <a
diff -urN -x'*~' postmodern-1.16/doc/postmodern.html postmodern-1.16-stricter/doc/postmodern.html
--- postmodern-1.16/doc/postmodern.html	2010-04-02 04:23:24.000000000 -0700
+++ postmodern-1.16-stricter/doc/postmodern.html	2010-04-06 07:00:09.000000000 -0700
@@ -63,16 +63,21 @@
     </p>
 
     <p class="desc">Create a new database connection for the given
-    user and database. Port will default to 5432, which is where most
-    PostgreSQL server are running. If <code>pooled-p</code> is true, a
-    connection will be taken from a pool of connections of this type,
-    if one is available there, and when the connection is disconnected
-    it will be put back into this pool instead. <code>use-ssl</code>
-    can be <code>:no</code>, <code>:yes</code>, or <code>:try</code>,
-    as in <a
-    href="cl-postgres.html#open-database"><code>open-database</code></a>,
-    and defaults to the value of <a
-    href="#*default-use-ssl*"><code>*default-use-ssl*</code></a>.</p>
+    user and database. Database, user, and password must be
+    strings. (Even if a password isn't required, a string must be
+    given.) Host may be a string containing a hostname or IP address
+    to make a TCP connection to, or :unix to connect via a local
+    Unix-domain socket (in which case port still determines which
+    PostgreSQL instance to connect to). Port must be an integer, and
+    will default to 5432, which is where most PostgreSQL servers are
+    running. If <code>pooled-p</code> is true, a connection will be
+    taken from a pool of connections of this type, if one is available
+    there, and when the connection is disconnected it will be put back
+    into this pool instead. <code>use-ssl</code> can
+    be <code>:no</code>, <code>:yes</code>, or <code>:try</code>, as
+    in <a href="cl-postgres.html#open-database"><code>open-database</code></a>,
+    and defaults to the value
+    of <a href="#*default-use-ssl*"><code>*default-use-ssl*</code></a>.</p>
 
     <p class="def">
       <span>variable</span>
diff -urN -x'*~' postmodern-1.16/postmodern/connect.lisp postmodern-1.16-stricter/postmodern/connect.lisp
--- postmodern-1.16/postmodern/connect.lisp	2010-04-02 04:23:24.000000000 -0700
+++ postmodern-1.16-stricter/postmodern/connect.lisp	2010-04-06 07:00:57.000000000 -0700
@@ -13,7 +13,18 @@
 (defparameter *default-use-ssl* :no)
 
 (defun connect (database user password host &key (port 5432) pooled-p (use-ssl *default-use-ssl*))
-  "Create and return a database connection."
+  "Create a new database connection for the given user and
+database. Database, user, and password must be strings. (Even if a
+password isn't required, a string must be given.) Host may be a string
+containing a hostname or IP address to make a TCP connection to,
+or :unix to connect via a local Unix-domain socket (in which case port
+still determines which PostgreSQL instance to connect to). Port must
+be an integer, and will default to 5432, which is where most
+PostgreSQL servers are running. If pooled-p is true, a connection will
+be taken from a pool of connections of this type, if one is available
+there, and when the connection is disconnected it will be put back
+into this pool instead. use-ssl can be :no, :yes, or :try, as in
+open-database, and defaults to the value of *default-use-ssl*."
   (cond (pooled-p
          (let ((type (list database user password host port use-ssl)))
            (or (get-from-pool type)
_______________________________________________
postmodern-devel mailing list
postmodern-devel@common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/postmodern-devel

Reply via email to