Skip to content

Commit

Permalink
fix #275 by noting the potential performance overhead of qualified co…
Browse files Browse the repository at this point in the history
…lumn names with postgres

Signed-off-by: Sean Corfield <sean@corfield.org>
  • Loading branch information
seancorfield committed Mar 15, 2024
1 parent 1476c35 commit 581df58
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Only accretive/fixative changes will be made from now on.

* 1.3.next in progress
* Address [#275](https://github.com/seancorfield/next-jdbc/issues/275) by noting that PostgreSQL may perform additional SQL queries to produce table names used in qualified result set builders.
* Address [#268](https://github.com/seancorfield/next-jdbc/issues/268) by expanding the documentation around `insert-multi!` and `insert!`.
* Update dependency versions (including Clojure).
* Code cleanup per `clj-kondo`.
Expand Down
1 change: 1 addition & 0 deletions doc/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ user=>
Relying on the default result set builder -- and table-qualified column names -- is the recommended approach to take, if possible, with a few caveats:
* MS SQL Server produces unqualified column names by default (see [**Tips & Tricks**](/doc/tips-and-tricks.md) for how to get table names back from MS SQL Server),
* Oracle's JDBC driver doesn't support `.getTableName()` so it will only produce unqualified column names (also mentioned in **Tips & Tricks**),
* PostgreSQL's JDBC driver performs an extra SQL query to get the necessary metadata, so there is some overhead to using qualified column names (also mentioned in **Tips & Tricks**),
* If your SQL query joins tables in a way that produces duplicate column names, and you use unqualified column names, then those duplicated column names will conflict and you will get only one of them in your result -- use aliases in SQL (`as`) to make the column names distinct,
* If your SQL query joins a table to itself under different aliases, the _qualified_ column names will conflict because they are based on the underlying table name provided by the JDBC driver rather the alias you used in your query -- again, use aliases in SQL to make those column names distinct.

Expand Down
9 changes: 9 additions & 0 deletions doc/tips-and-tricks.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,15 @@ is the best way to ensure the statement is properly closed after use.

When you use `:return-keys true` with `execute!` or `execute-one!` (or you use `insert!`), PostgreSQL returns the entire inserted row (unlike nearly every other database that just returns any generated keys!).

The default result set builder for `next.jdbc` is `as-qualified-maps` which
uses the `.getTableName()` method on `ResultSetMetaData` to qualify the
columns in the result set. While some database drivers have this information
on hand from the original SQL operation, PostgreSQL's JDBC driver does not
and it performs an extra SQL query to fetch table names the first time this
method is called for each query. If you want to avoid those extra queries,
and you can live with unqualified column names, you can use `as-unqualified-maps`
as the result set builder instead.

If you have a query where you want to select where a column is `IN` a sequence of values, you can use `col = ANY(?)` with a native array of the values instead of `IN (?,?,?,,,?)` and a sequence of values.

What does this mean for your use of `next.jdbc`? In `plan`, `execute!`, and `execute-one!`, you can use `col = ANY(?)` in the SQL string and a single primitive array parameter, such as `(int-array [1 2 3 4])`. That means that in `next.jdbc.sql`'s functions that take a where clause (`find-by-keys`, `update!`, and `delete!`) you can specify `["col = ANY(?)" (int-array data)]` for what would be a `col IN (?,?,?,,,?)` where clause for other databases and require multiple values.
Expand Down

0 comments on commit 581df58

Please sign in to comment.