phacility/phabricator · error · Exception

There are some results left in the result set.

Error message

There are some results left in the result set.

What it means

After processing the expected number of statements in a multi-query call, mysql_more_results() still reports pending result sets on the server side — the query string returned more results than the client consumed. The connection state is now inconsistent, so the driver aborts rather than silently dropping data. This is the ext-mysql driver's version of the check (mysqli has an identical one).

Source

Thrown at src/infrastructure/storage/connection/mysql/AphrontMySQLDatabaseConnection.php:137

    }

    if (!mysql_multi_query(implode("\n;\n\n", $raw_queries), $conn)) {
      $ex = $this->processResult(false);
      return array_fill_keys(array_keys($raw_queries), $ex);
    }

    $processed_all = false;
    foreach ($raw_queries as $key => $raw_query) {
      $results[$key] = $this->processResult(@mysql_fetch_result($conn));
      if (!mysql_more_results($conn)) {
        $processed_all = true;
        break;
      }
      mysql_next_result($conn);
    }

    if (!$processed_all) {
      throw new Exception(
        pht('There are some results left in the result set.'));
    }

    return $results;
  }

  protected function freeResult($result) {
    mysql_free_result($result);
  }

  public function supportsParallelQueries() {
    // fb_parallel_query() doesn't support results with different columns.
    return false;
  }

  /**
   * @phutil-external-symbol function fb_parallel_query
   */

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Execute one statement per query call: split scripts into individual queryfx() invocations
  2. If a stored procedure legitimately returns multiple sets, consume every set (loop while more_results) instead of expecting a fixed count
  3. Inspect the exact string being sent — look for stray semicolons or embedded statements from concatenation
  4. Prefer the mysqli driver path for new code; both enforce the same rule

Example fix

// before: multiple statements in one call
queryfx($conn, 'UPDATE a SET x = 1; UPDATE b SET y = 2;');

// after: one statement per call
queryfx($conn, 'UPDATE a SET x = 1');
queryfx($conn, 'UPDATE b SET y = 2');
Defensive patterns

Strategy: validation

Validate before calling

// Before executing, assert one statement per call:
function assert_single_statement($raw_query) {
  if (preg_match('/;\s*\S/', trim($raw_query))) {
    throw new Exception('Split multi-statement SQL into separate calls.');
  }
  return $raw_query;
}

Prevention

When it happens

Trigger: Passing several ';'-separated statements in a single queryf()/queryfx() call; calling a stored procedure that returns multiple result sets; a query string built by concatenation accidentally containing an extra statement or trailing semicolon fragment.

Common situations: Running hand-written migration SQL that was written as one script but executed as one query; wrapping procedural logic in stored procedures; copy-pasted dump fragments executed through the wrong API.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/af88b1260fcc04e4. Report an issue: GitHub.