Skip to content

Releases: neilotoole/sq

v0.48.3

12 Mar 03:02
Compare
Choose a tag to compare

Small bugfix release.

Fixed

  • #415: The JSON ingester could fail due to a bug when a JSON blob landed on the edge of a buffer.
  • The JSON ingester wasn't able to handle the case where a post-sampling JSON field had a different kind from the kind determined by the sampling process. For example, let's say the sample size was 1000, and the field zip was determined to be of kind int, because values 0-1000 were all parseable as integers. But then the 1001st value was BX123, which obviously is not an integer. sq will now see the non-integer value, and alter the ingest DB schema to a compatible kind, e.g. text. This flexibility is powerful, but it does come at the cost of slower ingest speed. But that's a topic for another release.

v0.48.1

08 Mar 00:58
Compare
Choose a tag to compare

This release features significant improvements to sq diff.

Added

  • Previously sq diff --data diffed every row, which could get crazy with a large table. Now the command stops after N differences, where N is controlled by the --stop (-n) flag, or the new config option diff.stop. The default stop-after value is 3; set to 0 to show all differences.

    # Stop on first difference
    $ sq diff @prod.actor @staging.actor --data --stop 1
    
    # Stop after 5 differences, using the -n shorthand flag
    $ sq diff @prod.actor @staging.actor --data -n5
  • #353: The performance of sq diff has been significantly improved. There's still more to do.

  • Previously, sq diff --data compared the rendered (text) representation of each value. This could lead to inaccurate results, for example with two timestamp values in different time zones, but the text rendering omitted the time zone. Now, sq diff --data compares the raw values, not the rendered text. Note in particular with time values that both time and location components are compared.

  • sq can now handle a SQLite DB on stdin. This is useful for testing, or for working with SQLite DBs in a pipeline.

    $ cat sakila.db | sq '.actor | .first_name, .last_name'

    It's also surprisingly handy in daily life, because there are sneaky SQLite DBs all around us. Let's see how many text messages I've sent and received over the years:

    $ cat ~/Library/Messages/chat.db | sq '.message | count'
    count
    215439

    I'm sure that number makes me an amateur with these millenials πŸ‘΄πŸ».

    Note that you'll need to enable macOS Full Disk Access to read the chat.db file.

  • sq now allows you to use true and false literals in queries. Which, in hindsight, does seem like a bit of an oversight 😳. (Although previously you could usually get away with using 1 and 0).

    $ sq '.people | where(.is_alive == false)'
    name        is_alive
    Kubla Khan  false
    
    $ sq '.people | where(.is_alive == true)'
    name         is_alive
    Kaiser Soze  true

Changed

  • ☒️ Previously, sq diff only exited non-zero on an error. Now, sq diff exits 0 when no differences, exits 1 if differences are found, and exits 2 on any error. This aligns with the behavior of GNU diff:

    Exit status is 0 if inputs are the same, 1 if different, 2 if trouble.
    
  • Minor fiddling with the color scheme for some command output.

v0.47.4

10 Feb 05:58
9bb4185
Compare
Choose a tag to compare

Patch release with changes to flags. See the earlier v0.47.0 release for recent headline features.

Added

  • By default, sq prints source locations with the password redacted. This is a sensible default, but there are legitimate reasons to access the unredacted connection string. Thus a new global flag --no-redact (and a corresponding redact config option).

    # Default behavior: password is redacted
    $ sq src -v
    @sakila/pg12  postgres  postgres://sakila:xxxxx@192.168.50.132/sakila
    
    # Unredacted
    $ sq src -v --no-redact
    @sakila/pg12  postgres  postgres://sakila:p_ssW0rd@192.168.50.132/sakila
  • Previously, if an error occurred when verbose was true, and error.format was text, sq would print a stack trace to stderr. This was poor default behavior, flooding the user terminal, so the default is now no stack trace. To restore the previous behavior, use the new -E (--error.stack) flag, or set the error.stack config option.

Changed

  • The --src.schema flag (as used in sq inspect, sq sql, and the root sq cmd) now accepts --src.schema=CATALOG.. Note the . suffix on CATALOG.. This is in addition to the existing allowed forms SCHEMA and CATALOG.SCHEMA. This new CATALOG. form is effectively equivalent to CATALOG.CURRENT_SCHEMA.

    # Inspect using the default schema in the "sales" catalog
    $ sq inspect --src.schema=sales. 
  • The --src.schema flag is now validated. Previously, if you provided a non-existing catalog or schema value, sq would silently ignore it and use the defaults. This could mislead the user into thinking that they were getting valid results from the non-existent catalog or schema. Now an error is returned.

v0.47.3

03 Feb 12:45
Compare
Choose a tag to compare

Minor bug fix release. See the earlier v0.47.0 release for recent headline features.

Fixed

  • Shell completion for bash only worked for top-level commands, not for subcommands, flags, args, etc. This bug was due to an unnoticed behavior change in an imported library πŸ€¦β€β™‚οΈ. It's now fixed, and tests have been added.

Changed

  • Shell completion now initially suggests only sources within the active group. Previously, all sources were suggested, potentially flooding the user with irrelevant suggestions. However, if the user continues to input a source handle that is outside the active group, completion will suggest all matching sources. This behavior is controlled via the new config option shell-completion.group-filter.

v0.47.2

30 Jan 05:21
135318f
Compare
Choose a tag to compare

See the earlier v0.47.0 release for recent headline features.

Fixed

  • sq was failing to write config when there was no pre-existing config file. This was due to a bug in the newly-introduced (as of v0.47.0) config locking mechanism. Fixed.

v0.47.1

29 Jan 20:12
Compare
Choose a tag to compare

This is a tiny bugfix release for a runtime issue on some Linux distros. See the previous v0.47.0 release for recent headline features.

Fixed

  • sq panicked on some Linux distros that don't include timezone data (tzdata). It's now explicitly imported.

v0.47.0

29 Jan 19:33
Compare
Choose a tag to compare

This is a significant release, focused on improving i/o, responsiveness, and performance. The headline features are caching of ingested data for document sources such as CSV or Excel, and download caching for remote document sources. There are a lot of under-the-hood changes, so please open an issue if you encounter any weirdness.

Added

  • Long-running operations (such as data ingestion, or file download) now result in a progress bar being displayed. Display of the progress bar is controlled by the new config options progress and progress.delay. You can also use the --no-progress flag to disable the progress bar.
    • πŸ‘‰ The progress bar is rendered on stderr and is always zapped from the terminal when command output begins. It won't corrupt the output.
  • #307: Ingested document sources (such as CSV or Excel) now make use of an ingest cache DB. Previously, ingestion of document source data occurred on each sq command. It is now a one-time cost; subsequent use of the document source utilizes the cache DB. Until, that is, the source document changes: then the ingest cache DB is invalidated and ingested again. This is a significantly improved experience for large document sources.
  • There are several new commands to interact with the cache (although you shouldn't need to):
  • #24: The download mechanism for remote document sources (e.g. a CSV file at https://sq.io/testdata/actor.csv) has been completely overhauled. Previously, sq would re-download the remote file on every command. Now, the remote file is downloaded and cached locally. Subsequent sq invocations check for staleness of the cached download, and re-download if necessary.
  • As part of the download revamp, new config options have been introduced:
    • http.request.timeout is the timeout for the initial response from the server, and http.response.timeout is the timeout for reading the entire response body. We separate these two timeouts because it's possible that the server responds quickly, but then for a large file, the download takes too long.
    • https.insecure-skip-verify controls whether HTTPS connections verify the server's certificate. This is useful for remote files served with a self-signed certificate.
    • download.cache controls whether remote files are cached locally.
    • download.refresh.ok-on-err controls whether sq should continue with a stale cached download if an error occurred while trying to refresh the download. This is a sort of "Airplane Mode" for remote document sources: sq continues with the cached download when the network is unavailable.
  • There are two more new config options introduced as part of the above work.
    • cache.lock.timeout controls the time that sq will wait for a lock on the cache DB. The cache lock is introduced for when you have multiple sq commands running concurrently, and you want to avoid them stepping on each other.
    • Similarly, config.lock.timeout controls the timeout for acquiring the (newly-introduced) lock on sq's config file. This helps prevent issues with multiple sq processes mutating the config concurrently.
  • sq's own logs previously outputted in JSON format. Now there's a new log.format config option that permits setting the log format to json or text. The text format is more human-friendly, and is now the default.

Changed

  • Ingestion performance for json and jsonl sources has been significantly improved.

Fixed

v0.46.1

07 Dec 03:41
Compare
Choose a tag to compare

Fixed

  • sq sometimes failed to read from stdin if piped input was slow to arrive. This is now fixed.

v0.46.0

22 Nov 19:09
Compare
Choose a tag to compare

Added

  • #338: While sq has had group_by for some time, somehow the having mechanism was never implemented. That's fixed.

    $ sq '.payment | .customer_id, sum(.amount) | group_by(.customer_id) | having(sum(.amount) > 200)'
    customer_id  sum(.amount)
    526          221.55
    148          216.54
  • #340: The group_by function now has a synonym gb, and order_by now has synonym ob. These synonyms are experimental πŸ§ͺ. The motivation is to reduce typing, especially the underscore (_) in both function names, but it's not clear that the loss of clarity is worth it. Maybe synonyms group and order might be better? Feedback welcome.

    # Previously
    $ sq '.payment | .customer_id, sum(.amount) | group_by(.customer_id) | order_by(.customer_id)'
    
    # Now
    $ sq '.payment | .customer_id, sum(.amount) | gb(.customer_id) | ob(.customer_id)'
  • #340: sq inspect: added flag shorthand -C for --catalogs and -S for --schemata. These were the only inspect flags without shorthand.

v0.45.0

22 Nov 03:01
Compare
Choose a tag to compare

Changed

  • #335: Previously, sq didn't handle decimal values correctly. It basically shoved a decimal value into a float or string and hoped for the best. As is known, floats are imprecise, and so we saw unwanted behavior, e.g.

    db_type_test.go:194: 
          Error Trace:	D:/a/sq/sq/drivers/sqlite3/db_type_test.go:194
          Error:      	Not equal: 
                        expected: "77.77"
                        actual  : "77.77000000000001"

    Now, sq uses a dedicated Decimal type end-to-end. No precision is lost, and at the output end, the value is rendered with the correct precision.

    There is a proposal to add decimal support to the Go database/sql package. If that happens, sq will happily switch to that mechanism.

    • πŸ‘‰ A side effect of decimal support is that some output formats may now render decimal values differently (i.e. correctly). In particular, Excel output should now render decimals as a number (as opposed to a string), and with the precision defined in the database. Previously, a database NUMERIC(10,5) value might have been rendered as 100.00, but will now accurately render 100.00000.