public static function query(
        $db,
        $sql,
        $wrapper = 'SwatDBDefaultRecordsetWrapper',
        $types = null
    ) {
        $mdb2_types = $types === null ? true : $types;

        $rs = self::executeQuery($db, 'query', array(
            $sql,
            $mdb2_types,
            true,
            false
        ));

        // Wrap results. Do it here instead of in MDB2 so we can wrap using
        // an existing object instance.
        if (is_string($wrapper)) {
            $rs = new $wrapper($rs);
        } elseif ($wrapper instanceof SwatDBRecordsetWrapper) {
            $wrapper->initializeFromResultSet($rs);
            $rs = $wrapper;
        }

        return $rs;
    }