Skip to content

v2.15.0 — exact inference, auto_type_candidates, time zones as read_csv reads them

Latest

Choose a tag to compare

@teaguesterling teaguesterling released this 10 Nov 03:20
3a2f99b

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.10 and 1e3 stay VARCHAR (#221). To get the old types back, use numeric_inference := 'lenient' (#224).
  • Zoneless TIMESTAMPTZ text reads in the session TimeZone, as ::TIMESTAMPTZ reads it. It used to read as UTC, so values change where TimeZone is not UTC. With ICU loaded, zone names such as America/New_York resolve. 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 through columns (#242, #262).
  • A tag-name record_element matches 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 @id beside id (#230, #235).
  • Columns whose names differ only in case, such as <name> beside <Name>, are renamed name_1, as read_csv does. The read used to fail (#248).

Other output changes:

  • A TIMESTAMPTZ column with no recorded format applies a numeric offset. 10:00:00+05 used to read as 10:00 UTC.
  • Dates beside timestamps in one file stay VARCHAR while DATE is a candidate, as in read_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 when name is a column. It used to write <xml> for every row (#229).
  • html_unescape keeps tags and the text after </body>. It used to drop them (#231).
  • html_extract_tables returns <tfoot> rows after the body rows (#232).
  • A table without <thead> takes headers only from a first row of <th> cells.
  • to_xml and json_to_xml write a NUL byte as U+FFFD and keep the text after it (#234).
  • duck_blocks_to_html nests 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_errors skips them where the changelog says so.

New

  • auto_type_candidates restricts the scalar types inference may choose, as in read_csv (#222).
  • read_html_blocks decodes files by their byte order mark, <meta> charset or bytes, as browsers do (#244).

Security and crash fixes

  • json_to_xml and the JSON to XML cast raise an error for JSON nested deeper than 256 levels. It used to crash DuckDB (#228).
  • json_to_xml raises 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