diff --git a/website/docs/releases.md b/website/docs/releases.md
index 6a607ef..bcc6c1e 100644
--- a/website/docs/releases.md
+++ b/website/docs/releases.md
@@ -24,10 +24,9 @@ In case you are wondering why all our releases start with `0.0`, read [this FAQ
:::
-
### Upcoming Release
-*
+* Update syntax for [`ARRAY` literals](./sql/datatype/array.md) and fixed bugs with quoting and escaping of text arrays.
### 0.0.21200 [Jan 17 2025]
diff --git a/website/docs/sql/datatype/array.md b/website/docs/sql/datatype/array.md
index 0c140e3..17f75af 100644
--- a/website/docs/sql/datatype/array.md
+++ b/website/docs/sql/datatype/array.md
@@ -26,10 +26,10 @@ Arrays can be created in two ways:
- Using the type constructor syntax
```sql
> select array[1,2,3];
- {1,2,3}
+ [1,2,3]
> select array['one','two','three'];
- {one,two,three}
+ ["one","two","three"]
```
The constructor syntax consists of the keyword `array` followed by a comma-separated list of element SQL values surrounded by square brackets `[...]`.
@@ -39,22 +39,24 @@ Arrays can be created in two ways:
- Using a [cast](../scalar_func/conversion.md) from string data
```sql
- > select '{1,2,3}'::array(integer);
- {1,2,3}
+ > select '[1,2,3]'::array(integer);
+ [1,2,3]
- > select '{one,two,three}'::array(text);
- {one,two,three}
+ > select '[one,two,three]'::array(text);
+ ["one","two","three"]
```
- An array string literal consists of a comma-separated list of element literals surrounded by curly braces `{...}`.
+ An array string literal consists of a comma-separated list of element literals surrounded by square brackets `[...]`.
The element literal syntax is identical to that of the respective atomic type.
Note that for string array types (such as, e.g., `array(text)`), any upper- or lower-case variant of the element literal `null` will be parsed as a `null` value.
To specify the string `null`, the element literal must be escaped using double quotes, like so:
```sql
- > select '{null, "null"}'::array(text)
- {NULL,null} # A null element, followed by the string 'null'
+ > select '[null, "null"]'::array(text)
+ [NULL,"null"] # A null element, followed by the string 'null'
```
+
+When outputting an array of text types, every non-null element is quoted.
## Element Types and Nullability
@@ -70,18 +72,18 @@ The following four options all represent different types in Hyper:
|Type|array nullable?|elements nullable?| possible values|
|---|---|---|---|
-|`array(integer)`|✅|✅|`{}`,`{1,2,3}`,`{1,2,null}`, `null`|
-|`array(integer not null)`|✅|❌|`{}`,`{1,2,3}`,`null`|
-|`array(integer) not null`|❌|✅|`{}`,`{1,2,3}`,`{1,2,null}`|
-|`array(integer not null) not null`|❌|❌|`{}`,`{1,2,3}`|
+|`array(integer)`|✅|✅|`[]`,`[1,2,3]`,`[1,2,null]`, `null`|
+|`array(integer not null)`|✅|❌|`[]`,`[1,2,3]`,`null`|
+|`array(integer) not null`|❌|✅|`[]`,`[1,2,3]`,`[1,2,null]`|
+|`array(integer not null) not null`|❌|❌|`[]`,`[1,2,3]`|
The inner nullability of an array type can be changed by casting, using the conventional [cast syntax](../scalar_func/conversion.md):
```sql
# nullable to non-nullable
-> select ('{1,2,3}'::array(integer))::array(integer not null)
+> select ('[1,2,3]'::array(integer))::array(integer not null)
# non-nullable to nullable
-> select ('{1,2,3}'::array(integer not null))::array(integer)
+> select ('[1,2,3]'::array(integer not null))::array(integer)
```
A cast from a non-nullable element type to its nullable counterpart always succeeds.
@@ -92,6 +94,11 @@ Casts across element types (e.g. from `array(integer not null)` to `array(bigint
Non-nullable element types use less memory and enable optimizations for certain array operations. Users are therefore advised to use the most "restrictive" element type possible, given the use case at hand.
:::
+:::note
+Hyper used curly braces `{...}` to represent arrays as string literals up to (and including) version 0.0.21200. In those versions, it also tried to avoid quoting every element of a text array when it did not contain special characters.
+The new syntax uses square brackets `[...]` and always quotes text elements, which more closely resembles the JSON array syntax.
+:::
+
## Limitations
Arrays are subject to the following limitations:
diff --git a/website/docs/sql/scalar_func/arrays.md b/website/docs/sql/scalar_func/arrays.md
index 00d2d88..e485501 100644
--- a/website/docs/sql/scalar_func/arrays.md
+++ b/website/docs/sql/scalar_func/arrays.md
@@ -12,7 +12,7 @@ Signature|Description|Example
---|---|---
array(T)**[**int**]**
→ `T`| Returns the n-th element of the array (1-indexed). | `(array[1,2,3])[1]` → `1`
array(T)**[**int**:**int**]**
→ `T` | Returns the subarray within the given boundes (1-indexed, inclusive). |`(array[1,2,3])[2:3]` → `{2,3}` |
-**array_length(**array**)**
→ `int` | Returns the length of the array. | `array_length(array[1,2,3])` → `3`
+**array_length(**array**)**
→ `int` | Returns the length of the array. | `array_length(array[1,2,3])` → `3`
`array_length(array[])` → `0`
**array_to_string(**array, text [, text]**)**
| Converts the array into a textual representation, with the given element separator and (optional) null indicator. | `array_to_string(array[1,2,3], ';')` → `1;2;3`
`array_to_string(array[3,2,1,null], '⏰', '🎉')` → `3⏰2⏰1⏰🎉`
**array_contains(**array, value**)**
| Checks if a given value is contained within the array. | `array_contains(array[1,3,4], 3)` → `true`
`array_contains(array[1,3,4], 2)` → `false`
**array_position(**array, value**)**
| Returns the index of the first occurrence of `value` inside `array`. Comparisons are done using `IS NOT DISTINCT FROM` semantics, so it is possible to search for `NULL`. Returns `NULL` if the element is not found. | `array_position(array[1,3,4,3], 3)` → `2`
`array_contains(array[1,3,4,3], 2)` → `NULL`