Method: PG::Connection#sync_exec

Defined in:
ext/pg_connection.c

#sync_exec(sql) ⇒ PG::Result #sync_exec(sql) {|pg_result| ... } ⇒ Object

This function has the same behavior as #async_exec, but is implemented using the synchronous command processing API of libpq. It’s not recommended to use explicit sync or async variants but #exec instead, unless you have a good reason to do so.

Both #sync_exec and #async_exec release the GVL while waiting for server response, so that concurrent threads will get executed. However #async_exec has two advantages:

  1. #async_exec can be aborted by signals (like Ctrl-C), while #exec blocks signal processing until the query is answered.

  2. Ruby VM gets notified about IO blocked operations and can pass them through Fiber.scheduler. So only async_* methods are compatible to event based schedulers like the async gem.

Overloads:

  • #sync_exec(sql) ⇒ PG::Result

    Returns:

  • #sync_exec(sql) {|pg_result| ... } ⇒ Object

    Yields:

    • (pg_result)


1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
# File 'ext/pg_connection.c', line 1109

static VALUE
pgconn_sync_exec(int argc, VALUE *argv, VALUE self)
{
  t_pg_connection *this = pg_get_connection_safe( self );
  PGresult *result = NULL;
  VALUE rb_pgresult;

  /* If called with no or nil parameters, use PQexec for compatibility */
  if ( argc == 1 || (argc >= 2 && argc <= 4 && NIL_P(argv[1]) )) {
    VALUE query_str = argv[0];

    result = gvl_PQexec(this->pgconn, pg_cstr_enc(query_str, this->enc_idx));
    rb_pgresult = pg_new_result(result, self);
    pg_result_check(rb_pgresult);
    if (rb_block_given_p()) {
      return rb_ensure(rb_yield, rb_pgresult, pg_result_clear, rb_pgresult);
    }
    return rb_pgresult;
  }
  pg_deprecated(0, ("forwarding exec to exec_params is deprecated"));

  /* Otherwise, just call #exec_params instead for backward-compatibility */
  return pgconn_sync_exec_params( argc, argv, self );

}