Jacob Budin
Jacob Budin

Reputation: 10003

PQgetResult always returns NULL

I'm writing a PostgreSQL library in Objective-C, based on libpq (written in C). While I've built a synchronous querying method that uses PQexec sucessfully; my asynchronous method never receives the query's results. PQgetResult always returns NULL.

I've tried various combinations of connection- and query-checking, but none of them corrected the issue. The query itself is a SELECT on a table with one row. I can swap out this asynchronous method for the synchronous method and have the desired behavior. I have also checked the conn pointer I'm retaining is referencing the same object throughout.

I am not using single row mode.

+ (instancetype) resultSetWithQuery: (NSString*) query usingConnection: (PGConnection*) conn whenComplete: (Callback) callback {
    PGResultSet* resultSet = [[PGResultSet alloc] init];
    NSString* encoding = [conn encoding];
    int success = PQsendQuery([conn conn], [query UTF8String]);

    [resultSet setEncoding:encoding];
    [resultSet setQuery:query];
    [resultSet setConn:conn];

    if(success){
        NSTimeInterval timeInterval = 0.5;
        NSTimer* checkStatus = [NSTimer scheduledTimerWithTimeInterval:timeInterval
                                                                target:resultSet
                                                            selector:@selector(checkIfComplete)
                                                            userInfo:nil
                                                            repeats:YES];
        [resultSet setTimer:checkStatus];
        [resultSet setCallback:callback];
    }

    return resultSet;
}

- (void)checkIfComplete{
    if(!PQconsumeInput([[self conn] conn])){
        [[self timer] invalidate];
    }

    if(PQisBusy([[self conn] conn])){
        return;
    }

    // result is always NULL
    PGresult* result = PQgetResult([[self conn] conn]);

    // ...
}

Upvotes: 1

Views: 548

Answers (1)

Jacob Budin
Jacob Budin

Reputation: 10003

To help debug the issue, I started the PostgreSQL server with a debug level setting:

$ postgres -d 2

After reviewing the log, I saw additional queries being executed on the same PGconn connection instance.


I believe my issue was derived from this chain of events:

  1. Invoke PQsendQuery on a query.
  2. Invoke PQexec on a new query.
  3. Invoke PQgetResult expecting the results from PQsendQuery.

In this scenario, PQgetResult will return NULL despite a valid, successfully-executed query.

The solution: In a multithreaded or asynchronous environment, you need to create a queue to manage the queries to a connection instance; pqlib won't do this on your behalf. While it may go without saying this would be true with multiple asynchronous operations, this is also the case for a single synchronous and single asynchronous operation.

Upvotes: 1

Related Questions