allowing the connection to be used by any clients. If the query raises errors,
 they are logged but ignored otherwise.
 
+==== pool_mode ====
+
+Set the pool mode specific to this database. If not set,
+the default pool_mode is used.
+
 === Extra parameters ===
 
 They allow setting default parameters on server connection.
 
 pool_size::
   Maximum number of server connections.
 
+pool_mode::
+  The pooling mode in user for this database.
+
 ==== SHOW FDS; ====
 
 Internal command - shows list of fds in use with internal state attached to them.
 
 
 #include "system.h"
 
+#include <usual/cfparser.h>
 #include <usual/time.h>
 #include <usual/list.h>
 #include <usual/statlist.h>
 #define POOL_SESSION   0
 #define POOL_TX                1
 #define POOL_STMT      2
+#define POOL_INHERIT   3
 
 /* old style V2 header: len:4b code:4b */
 #define OLD_HEADER_LEN 8
 
        int pool_size;          /* max server connections in one pool */
        int res_pool_size;      /* additional server connections in case of trouble */
+       int pool_mode;          /* pool mode for this database */
 
        const char *dbname;     /* server-side name, pointer to inside startup_msg */
 
 extern int cf_log_disconnections;
 extern int cf_log_pooler_errors;
 
+extern const struct CfLookup pool_mode_map[];
+
 extern usec_t g_suspend_start;
 
 extern struct DNSContext *adns;
 
        struct List *item;
        const char *f_user;
        PktBuf *buf;
+       struct CfValue cv;
+       int pool_mode;
 
        buf = pktbuf_dynamic(256);
        if (!buf) {
                return true;
        }
 
-       pktbuf_write_RowDescription(buf, "ssissii",
+       pktbuf_write_RowDescription(buf, "ssissiis",
                                    "name", "host", "port",
-                                   "database", "force_user", "pool_size", "reserve_pool");
+                                   "database", "force_user", "pool_size", "reserve_pool",
+                                   "pool_mode");
        statlist_for_each(item, &database_list) {
                db = container_of(item, PgDatabase, head);
 
                f_user = db->forced_user ? db->forced_user->name : NULL;
-               pktbuf_write_DataRow(buf, "ssissii",
+               pool_mode = db->pool_mode;
+               if (pool_mode == POOL_INHERIT)
+                       pool_mode = cf_pool_mode;
+               cv.value_p = &pool_mode;
+               cv.extra = pool_mode_map;
+               pktbuf_write_DataRow(buf, "ssissiis",
                                     db->name, db->host, db->port,
                                     db->dbname, f_user,
                                     db->pool_size,
-                                    db->res_pool_size);
+                                    db->res_pool_size,
+                                    cf_get_lookup(&cv));
        }
        admin_flush(admin, buf, "SHOW");
        return true;
        db->port = cf_listen_port;
        db->pool_size = 2;
        db->admin = 1;
+       db->pool_mode = POOL_STMT;
        if (!force_user(db, "pgbouncer", ""))
                fatal("no mem on startup - cannot alloc pgbouncer user");
 
 
        char *p, *key, *val;
        PktBuf *msg;
        PgDatabase *db;
+       struct CfValue cv;
        int pool_size = -1;
        int res_pool_size = -1;
        int dbname_ofs;
+       int pool_mode = POOL_INHERIT;
 
        char *tmp_connstr;
        const char *dbname = name;
 
        int v_port;
 
+       cv.value_p = &pool_mode;
+       cv.extra = (const void *)pool_mode_map;
+
        if (strcmp(name, "*") == 0) {
                set_autodb(connstr);
                return true;
                        pool_size = atoi(val);
                else if (strcmp("reserve_pool", key) == 0)
                        res_pool_size = atoi(val);
-               else if (strcmp("connect_query", key) == 0)
+               else if (strcmp("pool_mode", key) == 0) {
+                       if (!cf_set_lookup(&cv, val)) {
+                               log_error("skipping database %s because"
+                                         " of invalid pool mode: %s", name, val);
+                               goto fail;
+                       }
+               } else if (strcmp("connect_query", key) == 0)
                        connect_query = val;
                else if (strcmp("application_name", key) == 0)
                        appname = val;
        /* if pool_size < 0 it will be set later */
        db->pool_size = pool_size;
        db->res_pool_size = res_pool_size;
+       db->pool_mode = pool_mode;
 
        if (db->host)
                free(db->host);
 
        { NULL }
 };
 
-static const struct CfLookup pool_mode_map[] = {
+const struct CfLookup pool_mode_map[] = {
        { "session", POOL_SESSION },
        { "transaction", POOL_TX },
        { "statement", POOL_STMT },
 
                /* set ready only if no tx */
                if (state == 'I') {
                        ready = true;
-               } else if (cf_pool_mode == POOL_STMT) {
+               } else if (server->pool->db->pool_mode == POOL_STMT ||
+                       (server->pool->db->pool_mode == POOL_INHERIT && cf_pool_mode == POOL_STMT)) {
                        disconnect_server(server, true, "Long transactions not allowed");
                        return false;
                } else if (state == 'T' || state == 'E') {
        PgSocket *server = container_of(sbuf, PgSocket, sbuf);
        PgPool *pool = server->pool;
        PktHdr pkt;
+       int pool_mode;
 
        Assert(is_server_socket(server));
        Assert(server->state != SV_FREE);
                        sbuf_continue(&client->sbuf);
                        break;
                }
-               
-               if (cf_pool_mode  != POOL_SESSION || server->state == SV_TESTED) {
+
+               pool_mode = server->pool->db->pool_mode;
+               if (pool_mode == POOL_INHERIT)
+                       pool_mode = cf_pool_mode;               
+               if (pool_mode  != POOL_SESSION || server->state == SV_TESTED) {
                        switch (server->state) {
                        case SV_ACTIVE:
                        case SV_TESTED: