diff --git a/docs/web/basics/limits.mdx b/docs/web/basics/limits.mdx index c0ad03d80..69815fbab 100644 --- a/docs/web/basics/limits.mdx +++ b/docs/web/basics/limits.mdx @@ -80,7 +80,7 @@ See [Data types](/sql/data-types). | `TABLESAMPLE (n ROWS)` | whole numbers only | | `TABLESAMPLE BUCKET` | not supported | | `TABLESAMPLE` on a WAL-backed table | not supported | -| `CREATE INDEX` | one column, server-chosen name | +| `CREATE INDEX` | one column; `USING` names the algorithm | | `REFRESH MATERIALIZED VIEW ... CASCADE` | depends on the deployment's version; see [REFRESH](/sql/dml/refresh#refresh-materialized-view) | A sampling percentage over 100 is an error rather than a full scan, because a diff --git a/docs/web/curation/join.mdx b/docs/web/curation/join.mdx index 846e2cae9..a0cb24f39 100644 --- a/docs/web/curation/join.mdx +++ b/docs/web/curation/join.mdx @@ -58,12 +58,15 @@ just which rows: ```sql SELECT c.name, count(*) AS hits -FROM fts('documents', 'puppy') AS m +FROM fts('documents', '{"match":{"column":"text","terms":"puppy"}}') AS m JOIN categories AS c ON c.id = m.category_id GROUP BY c.name ORDER BY hits DESC ``` +`fts` takes the query as JSON, as in [Full-text search](/sql/dql/fts); a bare +string such as `'puppy'` is refused. + Whether SQL can express vector search [depends on the deployment](/basics/sql#no-vector-sql). Where it cannot, run the diff --git a/docs/web/sql/ddl/index.mdx b/docs/web/sql/ddl/index.mdx index 2ac18dd4c..0c6c63155 100644 --- a/docs/web/sql/ddl/index.mdx +++ b/docs/web/sql/ddl/index.mdx @@ -1,7 +1,7 @@ --- title: "Index" sidebarTitle: "Index" -description: "CREATE INDEX and DROP INDEX — one column, server-chosen name." +description: "CREATE INDEX and DROP INDEX — one column, with the algorithm chosen by USING." icon: bolt keywords: ["create index", "drop index", "sql"] --- @@ -11,14 +11,20 @@ keywords: ["create index", "drop index", "sql"] ## CREATE INDEX {#create} ```sql -CREATE INDEX ON documents (title) +CREATE INDEX ON documents USING btree (title) +CREATE INDEX text_search ON documents USING fts (text) ``` +`USING` is required: it names the algorithm. The scalar algorithms are `btree`, +`bitmap` and `label_list`; `fts` builds a full-text index; and the vector +algorithms are `ivf_pq`, `ivf_rq`, `ivf_flat`, `ivf_hnsw_sq` and `ivf_hnsw_pq`, +where the deployment supports them. Index options go in a `WITH (...)` clause. + -SQL `CREATE INDEX` covers **one column** and takes **no user-chosen name** -- -the server names it. For a multi-column or explicitly-named index, or to -choose the algorithm, use the SDK's -[`create_index`](/indexing). +On a deployment, SQL `CREATE INDEX` covers **one column**. A name between +`INDEX` and `ON` names the index, where the deployment's configuration allows +it; without one, the server names it after the column, as in `title_idx`. For a +multi-column index, use the SDK's [`create_index`](/indexing). diff --git a/docs/web/sql/dql/sampling.mdx b/docs/web/sql/dql/sampling.mdx index 0c190d4d5..e75bc8f23 100644 --- a/docs/web/sql/dql/sampling.mdx +++ b/docs/web/sql/dql/sampling.mdx @@ -64,7 +64,7 @@ It attaches to a table in `FROM`, including inside a subquery, a CTE, or either side of a join: ```sql -SELECT * FROM (SELECT * FROM documents) d TABLESAMPLE (10) +SELECT * FROM (SELECT * FROM documents TABLESAMPLE (10)) d SELECT * FROM a TABLESAMPLE (5 ROWS) JOIN b ON a.id = b.id @@ -86,6 +86,7 @@ be honoured exactly is an error: | `TABLESAMPLE (101)` | a percentage outside `0..=100` is refused, not clamped | | `TABLESAMPLE (1.5 ROWS)` | a row count must be whole | | `TABLESAMPLE (BUCKET 1 OUT OF 4)` | bucket sampling is not supported | +| `(SELECT ...) d TABLESAMPLE (10)` | a subquery's result cannot be sampled; sample the table inside it | | the `SAMPLE` spelling | use `TABLESAMPLE` | | the `OFFSET` modifier | not supported | diff --git a/docs/web/sql/dql/subqueries.mdx b/docs/web/sql/dql/subqueries.mdx index 22eee986b..5a4eb1039 100644 --- a/docs/web/sql/dql/subqueries.mdx +++ b/docs/web/sql/dql/subqueries.mdx @@ -19,11 +19,11 @@ SELECT * FROM ( WHERE n > 100 ``` -A derived table needs an alias. It can be [sampled](/sql/dql/sampling) like a base -table: +A derived table needs an alias. Its result cannot be +[sampled](/sql/dql/sampling); sample the table inside it instead: ```sql -SELECT * FROM (SELECT * FROM documents) d TABLESAMPLE (10) +SELECT * FROM (SELECT * FROM documents TABLESAMPLE (10)) d ``` ## As a scalar {#scalar} diff --git a/docs/web/sql/operators.mdx b/docs/web/sql/operators.mdx index 5ffecc9bf..267da4c59 100644 --- a/docs/web/sql/operators.mdx +++ b/docs/web/sql/operators.mdx @@ -66,10 +66,13 @@ or a name with mixed case: `SELECT "order" FROM "MyTable"`. ## Casting {#casting} ```sql -SELECT CAST(identifier AS VARCHAR), identifier::VARCHAR FROM documents +SELECT CAST(identifier AS VARCHAR) AS with_cast, identifier::VARCHAR AS with_colons +FROM documents ``` -Both forms work. `TRY_CAST` returns null instead of erroring on a value that +Both forms work. Give each its own alias when one projection uses both: they +produce the same expression name, and a projection refuses two columns with +one name. `TRY_CAST` returns null instead of erroring on a value that will not convert, which is the one to use over a column you do not control. ## Precedence {#precedence} diff --git a/docs/web/sql/scalar-functions.mdx b/docs/web/sql/scalar-functions.mdx index f69c16a2f..eb92ebd25 100644 --- a/docs/web/sql/scalar-functions.mdx +++ b/docs/web/sql/scalar-functions.mdx @@ -156,17 +156,26 @@ it over `LIKE` for keyword tests. | `json_get_int(col, key)` | `Int64` | | `json_get_float(col, key)` | `Float64` | | `json_get_bool(col, key)` | `Boolean` | -| `json_extract(col, path)` | `Utf8`, by path | -| `json_extract_with_type(col, path, type)` | the requested type | +| `json_extract(col, path)` | `Utf8`: the value as JSON text, by path | +| `json_extract_with_type(col, path)` | a struct of the value as JSON and a type tag, by path | | `json_exists(col, path)` | `Boolean` | | `json_array_contains(col, value)` | `Boolean` | | `json_array_length(col)` | length | -`json_get` returns JSON, so accessors nest: +`json_get` returns JSON, so a typed accessor can read a field inside it: ```sql SELECT * FROM events -WHERE json_get_string(json_get(json_get(data, 'user'), 'profile'), 'name') = 'Alice' +WHERE json_get_string(json_get(data, 'user'), 'name') = 'Alice' +``` + +That works one level down. A `json_get` nested inside another `json_get` is +refused, so reach a deeper value with `json_extract` and a JSONPath instead. It +returns JSON text, so a string compares with its quotes: + +```sql +SELECT * FROM events +WHERE json_extract(data, '$.user.profile.name') = '"Alice"' ``` **`json_get`, its typed variants, and `json_extract` are index-accelerated** by a