public function fetch( $options = null, $keyResultsByColumn = null )
    {

        $this->setFetchOptions( $options );

        // caching
        if( $this->fetchOptions & self::CACHE ) {
            // get a cache key for the passed options (we only care about those options that will modify the returned result)
            $cacheKey = $this->fetchOptions & (
                self::TYPE_DETECT | self::TYPE_AGNOSTIC |
                self::FLATTEN_IF_POSSIBLE | self::FLATTEN_PREVENT |
                self::STYLE_ASSOC | self::STYLE_NUM |
                self::FETCH_SINGLE | self::FETCH_MULTIPLE
            );
            if( isset( $this->cacheFetch[$cacheKey] ) ) {
                return $this->cacheFetch[$cacheKey];
            }
        }

        // build output
        $output = array();

        // build output array
        // slight repetition of code here to help us avoid the isset( $types ) check for every row (there might be a __lot__ of rows so this adds up).
        pg_result_seek( $this->resource, 0 );
        if( null === $keyResultsByColumn ) {
            while( $row = pg_fetch_array( $this->resource, NULL, $this->fetchType ) ) {
                $output[] = call_user_func( $this->fetchCallback, $row );
            }
        } else {
            while( $row = pg_fetch_array( $this->resource, NULL, $this->fetchType ) ) {
                $row = call_user_func( $this->fetchCallback, $row );
                $output[$row[$keyResultsByColumn]] = $row;
            }
        }

        // populate the numRows cache as we've now got this information as standard
        if( !isset( $this->numRows ) ) {
            $this->numRows = count( $output );
        }
        $this->fetchRowNumber = $this->numRows;

        // single result behaviour
        if( $this->fetchOptions & self::FETCH_SINGLE ) {

            if( $this->numRows() == 0 and $this->numFields() > 1 ) {

                $output = array();

            } elseif( $this->numRows() <= 1 ) {

                $output = array_pop( $output );

            // perhaps we should be returning a exception you call $singleResult and there is > 1 rows returned from the db
            } else {
                throw new MoreThanOneRowReturnedException( "{$this->numRows()} returned, FETCH_SINGLE doesn't apply here." );
            }

        }

        // cache population
        if( isset($cacheKey) ) {
            $this->cacheFetch[$cacheKey] = $output;
        }

        return $output;

    }