> ## Documentation Index
> Fetch the complete documentation index at: https://developers.askparable.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Search

> Find tables with search_available_data, and find Provider records by what their text says with search_everything.

Two SQL table functions search your Workspace's data. They answer different
questions:

| Function | Finds | Use it when |
| - | - | - |
| `search_available_data` | Tables and columns | You do not know which table holds the data. |
| `search_everything` | Provider records, by what their text says | You know what the records are about, such as "customers who asked about SSO", but not where they are. |

Both run on the same Flight SQL connection as [the pools](/data.md#query-the-pools),
and over [SQL over HTTP](/data/sql-over-http.md). Both run only in interactive
queries. A Plot cannot call them: saving the Plot records an error, and the
Plot cannot publish until you remove the call. Search first, then write the
Plot's SQL against the source table.

## Find tables and columns

`search_available_data(query [, scope [, kind]])` searches the names and
descriptions of tables and columns in the Provider and Workspace pools. It
returns only the pools your role can query.

```sql theme={null}
SELECT table_ref, column_name, description, data_type
FROM search_available_data('open issues and who they are assigned to', 'providers.linear')
ORDER BY score DESC, qualified_name
LIMIT 20
```

`scope` starts with `providers` or `workspace`, such as `providers.linear` or
`providers.linear.issues.*`. `kind` is `'table'` or `'column'`.
[Search Available Data](https://docs.parable.work/protocols/sql/data-catalog/search-available-data)
lists every scope pattern and result column.

## Find records by what they say

`search_everything` finds rows in the Provider pool whose text matches a
question by meaning, not only by keyword. It returns one row for each matching
source record, never one row for each passage.

```sql theme={null}
SELECT table_ref, row_key, column_name, snippet, score, matched_chunks
FROM search_everything('customer raised pricing concerns')
ORDER BY score DESC
LIMIT 20
```

> [!NOTE]
>
> Ask your Parable representative to turn on search for your Workspace. Until
> then, `search_everything` returns no rows.

### What is searchable

`search_everything` searches only the Provider pool, and only the text fields
that a Provider's [Tap schema](/connectors/tap-schemas.md) marks for search with
`x-transformEmbed`. Some fields are searched with context from the same record.
For example, an issue's title comes before its body. A call transcript is
searched as windows of speaker turns. A Notion page is searched as its blocks,
under its title, and its `column_name` is `blocks`.

### Arguments

`search_everything(query [, scope [, limit]])` takes up to three arguments, by
position only. Named arguments (`query => ...`) are refused.

| Argument | Meaning |
| - | - |
| `query` | Plain text that describes the records you want. |
| `scope` | Optional. A pattern over Provider tables that starts with `providers`, such as `providers.linear.*` for one Provider or `providers.linear.issues.description` for one field. `NULL` or `''` searches every Provider table you can read. |
| `limit` | Optional. The number of records to return, from 1 to 100. `NULL` returns 20. |

Parable refuses arguments that it cannot search before anything runs:

* A scope that does not start with `providers`.
* A limit outside 1 to 100, or a limit that is not a whole number.
* An empty query.
* A query or scope that is not a text literal.

The refusal is `INVALID_ARGUMENT` with error code `QL-PL-018`. Its message
names the argument and what to use instead. Over HTTP, it is a `400` with the
same code.

### Results

| Column | Meaning |
| - | - |
| `table_ref` | The source table, such as `providers.linear.issues`. |
| `row_key` | The record's key columns and values, as JSON text. Join back to the source table with it. |
| `column_name` | The field of the best passage, such as `description`. |
| `span` | Where that passage is in the field, as JSON character offsets. For a list, such as a call transcript, it also names the first and last item and their times. |
| `snippet` | The start of the best passage, up to 300 characters, as you are allowed to read it. |
| `score` | The best passage's similarity to the query, from 0 to 1. It is not a sum across passages. |
| `matched_chunks` | How many of the record's passages matched. |
| `provider` | The Provider's schema in the catalog, the middle part of `table_ref`. |

The snippet is not the whole record. Read the record from its source table.

### Join back to the source table

`row_key` is a JSON object of the source table's key columns. Read a text key
with `json_get_str` and a numeric key with `json_get_int`:

```sql theme={null}
SELECT issues.identifier, issues.title, found.snippet, found.score
FROM search_everything('SSO login loop', 'providers.linear.*', 20) AS found
JOIN providers.linear.issues AS issues
  ON issues.id = json_get_str(found.row_key, 'id')
ORDER BY found.score DESC
```

Use the key names that `row_key` holds. A record with more than one key
column matches on each of them.

### Policies apply

Parable reads each matching record again from its source table before it
returns the record. That read applies the same Provider Policies and source
permissions as your own query of the table. A record that a Policy hides from
you is left out, and its text never appears in a snippet. If you cannot query
the Provider pool, you see no records.

When one source table takes too long to read, its records are left out of the
result, and records from other tables still return. When no source table can
be read in time, the search fails with `DEADLINE_EXCEEDED` and error code
`QL-TO-004`. Over HTTP, it is a `504` with the same code. The message names
the time limit. Run the search again. If it fails again, narrow the scope to
fewer tables, such as `providers.linear.*`.

### An empty result

An empty result does not prove that nothing matches. `search_everything` also
returns no rows when:

* Search is not turned on for your Workspace.
* The Workspace's AI policy admits no embedding model for this search.
* The search index is missing or still building.
* A record's text changed after Parable indexed it, until the index catches
  up.

In these cases, find the table with `search_available_data` and query it
directly.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.