function vacuum(args)
  local options = {}
  local tables = {}

  if args == "help" then
    print "\\lua vacuum {verbose=true}"
    return
  end

  if args then
    local transfx = load("return " .. args)
    options = transfx()
  end

  local query = 
[[SELECT quote_ident(n.nspname) AS nspname,
         quote_ident(c.relname) AS relname
  FROM pg_class c, pg_namespace n
 WHERE n.oid = c.relnamespace
  AND n.nspname <> 'information_schema'
  AND n.nspname !~ '^pg_toast'
  AND c.relkind IN ('r','s','n')]]

  local rs, err = psql.exec(query)
  local data = rs:fetch()
  while data do
    table.insert(tables, { nspname = data.nspname, relname = data.relname } )
    data = rs:fetch()
  end
  rs:clear()

  local n = 0

  local mycon = psql.connect():clone()
  rs, err = mycon:exec("select pg_backend_pid()");
  local data = rs:fetch()
  local pid = data.pg_backend_pid

  for _, tbl in ipairs(tables) do
    if options.verbose then
      print(string.format("\27[7mVACUUM %s.%s \27[27m", tbl.nspname, tbl.relname))
      mycon:sendquery("vacuum verbose " .. tbl.nspname .. "." .. tbl.relname)
      mycon:sendquery("select pg_sleep(20)")
    else
      print(tbl.nspname .. "." .. tbl.relname)
      mycon:sendquery("vacuum " .. tbl.nspname .. "." .. tbl.relname)
    end

    mycon:consumeinput()
    isbusy = mycon:isbusy()
    while isbusy do
      n = n + 1
      if mycon:resultwait(1) == 0 then
        rs, err = psql.connect():exec(string.format("SELECT * FROM pg_stat_progress_vacuum WHERE pid = %d", pid))
        if err then
          error(err)
        end
        data = rs:fetch()
        if data then
          io.write(string.format("\rphase: %s, blks total: %d, blks scanned: %d, indexes total: %d, indexes processed: %d\27[0K", data.phase, data.heap_blks_total, data.heap_blks_scanned, data.indexes_total, data.indexes_processed))
        else
          io.write(string.format("\r\27[0K"))
        end
        io.flush()
        rs:clear()
      else
        io.write(string.format("\r\27[0K"))
        io.flush()
      end
      mycon:consumeinput()
      isbusy = mycon:isbusy()
    end

    rs, err = mycon:getresult()
    -- second getresult is used to force call PQgetResult, that should to return null
    -- in this case, error is expected (not raised)
    mycon:getresult() 
    if err then
      print(err)
    end
  end

  mycon:close()
end
