Repository navigation
Exact numeric inference, auto_type_candidates, time zones as read_csv reads them, and fixes from two reviews and a pre-release scan.
Output changes: read these before you upgrade
Some queries return different types or values in this release.
- Numbers keep their text. Inference types a value as numeric only when the type gives back its exact text.
007,1.10and1e3stay VARCHAR (#221). To get the old types back, usenumeric_inference := 'lenient'(#224). - Zoneless TIMESTAMPTZ text reads in the session
TimeZone, as::TIMESTAMPTZreads it. It used to read as UTC, so values change whereTimeZoneis not UTC. With ICU loaded, zone names such asAmerica/New_Yorkresolve. They used to raise (#242, #260). - Zoned timestamp text infers TIMESTAMPTZ, as in
read_csv. This includes zone names, and zoneless text mixed with zoned text. These columns used to be VARCHAR. To keep VARCHAR, declare the column throughcolumns(#242, #262). - A tag-name
record_elementmatches only the outermost elements. A nested match stays in its parent's column. Use an XPath expression to select nested elements as rows (#235). - An attribute and a child element with the same name are two columns. The attribute column takes
attr_prefix, such as@idbesideid(#230, #235). - Columns whose names differ only in case, such as
<name>beside<Name>, are renamedname_1, asread_csvdoes. The read used to fail (#248).
Other output changes:
- A TIMESTAMPTZ column with no recorded format applies a numeric offset.
10:00:00+05used to read as 10:00 UTC. - Dates beside timestamps in one file stay VARCHAR while
DATEis a candidate, as inread_csv. - A record no longer fills a column with its own name beside other columns. A record without that child reads NULL (#235).
to_xml(value, name)uses each row's name whennameis a column. It used to write<xml>for every row (#229).html_unescapekeeps tags and the text after</body>. It used to drop them (#231).html_extract_tablesreturns<tfoot>rows after the body rows (#232).- A table without
<thead>takes headers only from a first row of<th>cells. to_xmlandjson_to_xmlwrite a NUL byte as U+FFFD and keep the text after it (#234).duck_blocks_to_htmlnests containers up to level 254. It used to flatten below 64 levels.- Several reads that returned empty or truncated output now raise an error: a pattern that matches no file, HTML deeper than 256 levels, and a text node past libxml2's 10,000,000-byte limit.
ignore_errorsskips them where the changelog says so.
New
auto_type_candidatesrestricts the scalar types inference may choose, as inread_csv(#222).read_html_blocksdecodes files by their byte order mark,<meta>charset or bytes, as browsers do (#244).
Security and crash fixes
json_to_xmland theJSONtoXMLcast raise an error for JSON nested deeper than 256 levels. It used to crash DuckDB (#228).json_to_xmlraises an error for a key that is not an XML name. A crafted key used to add elements (#228).
The full list is in the changelog.
Thanks
@bendrucker contributed exact numeric inference (#221) and auto_type_candidates (#222), and reviewed the TIMESTAMPTZ inference in #262. Ben: after #262, auto_type_candidates := ['TIMESTAMPTZ'] widens a date or zoneless timestamp to TIMESTAMPTZ, as read_csv does. Before, it stayed VARCHAR, as the #222 docs said. numeric_inference := 'lenient' (#224) gives back the types from before #221.
Full diff: v2.14.1...v2.15.0