Giter Site home page Giter Site logo

exasol / metabase-driver Goto Github PK

View Code? Open in Web Editor NEW
5.0 7.0 0.0 269 KB

Exasol driver for Metabase

License: GNU Affero General Public License v3.0

Clojure 87.60% Shell 12.40%
integration-team metabase metabase-driver exasol-integration exasol business-intelligence

metabase-driver's Introduction

Exasol Metabase Driver

An Exasol driver for Metabase.

CI Build

Overview

Metabase is a business intelligence tool. You can use Metabase to visualize data in Exasol.

The Exasol Driver for Metabase is an adapter, that allows you to query data from an Exasol database using Metabase. It is available as a Partner driver for both Metabase Cloud and self-hosted Metabase installations.

Features

  • Connect Metabase to an Exasol database
  • Connections are encrypted via TLS by default
    • Specify a certificate fingerprint in case your database uses a self-signed TLS certificate
  • Allows tunneling the connection to Exasol through an SSH tunnel
  • Provides helpful error messages in case of connection errors

Table of Contents

Information for Users

Information for Developers

Dependencies

Runtime Dependencies

To use the Exasol Driver, you need Metabase Version 0.45.2.1 or later.

Follow the Metabase installation guide to download and install Metabase.

metabase-driver's People

Contributors

exadm-deg avatar kaklakariada avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

metabase-driver's Issues

Investigate & fix failing connection-pool-invalidated-on-details-change test

Integration test metabase.driver.sql-jdbc.connection-test/connection-pool-invalidated-on-details-change is fails with Metabase 0.43.3:

FAIL in metabase.driver.sql-jdbc.connection-test/connection-pool-invalidated-on-details-change (connection_test.clj:129)

:exasol db->pooled-connection-spec marks a connection pool invalid if the db details map changes
 changing DB details results in hash value changing and connection being invalidated The calculated hash should be different
expected: (not=
           ((var sql-jdbc.conn/jdbc-spec-hash) db)
           ((var sql-jdbc.conn/jdbc-spec-hash) db-perturbed))
  actual: (not (not= 287586488 287586488))

FAIL in metabase.driver.sql-jdbc.connection-test/connection-pool-invalidated-on-details-change (connection_test.clj:150)

:exasol db->pooled-connection-spec marks a connection pool invalid if the db details map changes
 changing DB details results in hash value changing and connection being invalidated
One hash change should have been logged
expected: 1
  actual: (0)

FAIL in metabase.driver.sql-jdbc.connection-test/connection-pool-invalidated-on-details-change (connection_test.clj:153)

:exasol db->pooled-connection-spec marks a connection pool invalid if the db details map changes
 changing DB details results in hash value changing and connection being invalidated
expected: (not= db-hash-1 db-hash-2)
  actual: (not (not= 287586488 287586488))

Implement reading driver version from metabase-plugin.yaml

After implementing #35 the driver jar does not contain META-INF/maven/metabase/exasol-driver/pom.properties any more. We used this file for reading the driver version.

Now we need to read the version from metabase-plugin.yaml included in the jar.

Add note about Metabase Cloud

Once the driver is available in Metabase Cloud we should update the documentation and mention that the driver is already included in Metabase Cloud and no installation is required.

"Week" aggregation is inconsistent with setting "Start of the week" is set to "Monday"

Describe the bug

Hello!
When setting "Start-of-the-week" is set to "Monday" and we use a query builder then a weekly aggregation query gets wrong result - the first day of the aggregation is the Tuesday of previous week.
If setting "Start-of-the-week" is set to "Sunday" all works correct.

Steps To Reproduce

Steps to reproduce the behavior:

  1. Select "Monday" as "Start of the week" in Admin settings.
  2. Aggregate data on "Week"
  3. Find data belonging to previous week with Tuesday as first day of week.

Expected behavior

Data from previous week is not included in the result and first day of week is Monday.

Example

  1. Prepare a query in the query builder with filter on date field
    image
  2. Get results from previous week with wrong first day (27.12, 03.01 and 10.01 are Tuesdays)
    image

Here is the query that MB generates:

SELECT (CAST(truncate(CAST(("BD"."TABLE"."COLUMN" + numtodsinterval(-1, 'day')) AS date), 'day') AS date) + numtodsinterval(1, 'day')) AS "COLUMN"
FROM "BD"."TABLE"
WHERE ("BD"."TABLE"."COLUMN" >= timestamp '2023-01-02 00:00:00.000'
   AND "BD"."TABLE"."COLUMN" < timestamp '2023-01-16 00:00:00.000')
GROUP BY (CAST(truncate(CAST(("BD"."TABLE"."COLUMN" + numtodsinterval(-1, 'day')) AS date), 'day') AS date) + numtodsinterval(1, 'day'))
ORDER BY (CAST(truncate(CAST(("BD"."TABLE"."COLUMN" + numtodsinterval(-1, 'day')) AS date), 'day') AS date) + numtodsinterval(1, 'day')) ASC

And executing this query without MB gives the same result.

Setup

  • Metabase 0.45.2
  • Exasol-metabase-driver 1.0.3

This behavior is also present in metabase 0.42.4 with driver version 1.0.0

Dependencies

Fix failing timestamp / timezone tests

metabase.driver.sql.parameters.substitute-test

FAIL in metabase.driver.sql.parameters.substitute-test/e2e-parse-native-dates-test (substitute_test.clj:618)

:exasol
Native dates should be parsed with the report timezone
expected: ["2018-04-18T00:00:00-07:00"]
  actual: (["2018-04-17T00:00:00-07:00"])

metabase.query-processor-test.alternative-date-test

See https://github.com/exasol/metabase-driver/runs/4800583820?check_suite_focus=true

FAIL in metabase.query-processor-test.alternative-date-test/microseconds-test (alternative_date_test.clj:38)

:exasol
expected: #{[1 4 "2015-06-06T10:40:00Z"] [2 0 "2015-06-10T19:51:00Z"]}
  actual: (#{[1 4 "2015-06-06T12:40:00Z"] [2 0 "2015-06-10T21:51:00Z"]})

metabase.query-processor-test.timezones-test

FAIL in metabase.query-processor-test.timezones-test/filter-test (timezones_test.clj:69)
using test-data-with-timezones dataset 
:exasol 
Setting :report-timezone = "America/Los_Angeles"

If MBQL datetime literal strings do not explicitly specify a timezone, they should be parsed as if in the current reporting timezone (Pacific in this case)
expected: [[6 "Shad Ferdynand" "2014-08-02T05:30:00-07:00"]]
  actual: ([[6 "Shad Ferdynand" "2014-08-02T12:30:00-07:00"]])

FAIL in metabase.query-processor-test.timezones-test/filter-test (timezones_test.clj:75)
using test-data-with-timezones dataset 
:exasol 
Setting :report-timezone = "America/Los_Angeles"

MBQL datetime literal strings that include timezone should be parsed in it regardless of report timezone
expected: [[6 "Shad Ferdynand" "2014-08-02T05:30:00-07:00"]]
  actual: ([[6 "Shad Ferdynand" "2014-08-02T12:30:00-07:00"]])
load-data for h2 test-data users (reference H2 duration: 23,8 ms) took 3,3 ms
load-data for h2 test-data categories (reference H2 duration: 10,1 ms) took 3,2 ms
load-data for h2 test-data venues (reference H2 duration: 29,4 ms) took 10,7 ms
load-data for h2 test-data checkins (reference H2 duration: 130,4 ms) took 60,4 ms
Sync :h2 Database test-data (reference H2 duration: 1,1 s) took 555,8 ms

ERROR in metabase.query-processor-test.timezones-test/time-timezone-handling-test (util.clj:353)
Uncaught exception, not in assertion.

             clojure.lang.ExceptionInfo: Error in with-temporary-setting-values: Exasol does not have a :type/TimeWithTZ data type.
    setting: :report-timezone
      value: nil
java.lang.UnsupportedOperationException: Exasol does not have a :type/TimeWithTZ data type.
                                               metabase.test.data.exasol/eval81568/fn          exasol.clj:   55
                                               metabase.test.data.sql/eval77270/fn/fn             sql.clj:  161
                                                                    clojure.core/some            core.clj: 2705
                                                  metabase.test.data.sql/eval77270/fn             sql.clj:  155
                                                                                  ...                          
metabase.query-processor-test.timezones-test/driver-distinguishes-between-base-types?  timezones_test.clj:  198
           metabase.query-processor-test.timezones-test/supports-time-with-time-zone?  timezones_test.clj:  201
                       metabase.query-processor-test.timezones-test/expected-attempts  timezones_test.clj:  212
                             metabase.query-processor-test.timezones-test/fn/fn/fn/fn  timezones_test.clj:  228
                                   metabase.test.util/do-with-temporary-setting-value            util.clj:  351
                                metabase.query-processor-test.timezones-test/fn/fn/fn  timezones_test.clj:  227
                                              metabase.test.data.impl/do-with-dataset            impl.clj:  344
                                   metabase.query-processor-test.timezones-test/fn/fn  timezones_test.clj:  225
                        metabase.test.data.datasets/do-with-driver-when-testing/fn/fn        datasets.clj:   41
                                                       metabase.driver/do-with-driver          driver.clj:   60
                           metabase.test.data.datasets/do-with-driver-when-testing/fn        datasets.clj:   40
                                   metabase.test.data.datasets/do-when-testing-driver        datasets.clj:   29
                              metabase.test.data.datasets/do-with-driver-when-testing        datasets.clj:   39
                                      metabase.query-processor-test.timezones-test/fn  timezones_test.clj:  224
                                                             clojure.test/test-var/fn            test.clj:  717
[...]

FAIL in metabase.query-processor-test.timezones-test/native-params-filter-test (timezones_test.clj:172)

:exasol using test-data-with-timezones dataset 
Setting :report-timezone = "America/Los_Angeles"
 Native dates should be parsed with the report timezone Query with variable w/ single date
expected: [[6 "Shad Ferdynand" "2014-08-02T05:30:00-07:00"]
           [7 "Conchúr Tihomir" "2014-08-02T02:30:00-07:00"]]
  actual: ([[6 "Shad Ferdynand" "2014-08-02T12:30:00-07:00"]
            [7 "Conchúr Tihomir" "2014-08-02T09:30:00-07:00"]])

FAIL in metabase.query-processor-test.timezones-test/native-params-filter-test (timezones_test.clj:172)

:exasol using test-data-with-timezones dataset 
Setting :report-timezone = "America/Los_Angeles"
 Native dates should be parsed with the report timezone Query with field filter w/ date range
expected: [[6 "Shad Ferdynand" "2014-08-02T05:30:00-07:00"]
           [7 "Conchúr Tihomir" "2014-08-02T02:30:00-07:00"]]
  actual: ([])

FAIL in metabase.query-processor-test.timezones-test/native-params-filter-test (timezones_test.clj:172)

:exasol using test-data-with-timezones dataset 
Setting :report-timezone = "America/Los_Angeles"
 Native dates should be parsed with the report timezone Query with field filter w/ single date
expected: [[6 "Shad Ferdynand" "2014-08-02T05:30:00-07:00"]
           [7 "Conchúr Tihomir" "2014-08-02T02:30:00-07:00"]]
  actual: ([])

FAIL in metabase.query-processor-test.timezones-test/result-rows-test (timezones_test.clj:57)
using test-data-with-timezones dataset 
:exasol 
Setting :report-timezone = "US/Pacific"

There should be 1 checkins on July 3rd in the US/Pacific timezone
expected: [[10 "2014-07-03T12:30:00-07:00"]]
  actual: ([[10 "2014-07-03T19:30:00-07:00"]])

Ran 4 tests in 15,079 seconds
11 assertions, 6 failures, 1 error.
{:test 4, :pass 4, :fail 6, :error 1, :type :summary, :duration 15079.052671}
Tests failed.

Fix failing timezone tests

Some test regarding timezones fail

metabase.query-processor-test.alternative-date-test/microseconds-test

FAIL in metabase.query-processor-test.alternative-date-test/microseconds-test (alternative_date_test.clj:38)

:exasol
expected: #{[1 4 "2015-06-06T10:40:00Z"] [2 0 "2015-06-10T19:51:00Z"]}
  actual: (#{[1 4 "2015-06-06T12:40:00Z"] [2 0 "2015-06-10T21:51:00Z"]})

metabase.query-processor-test.timezones-test

FAIL in metabase.query-processor-test.timezones-test/filter-test (timezones_test.clj:69)
using test-data-with-timezones dataset 
:exasol 
Setting :report-timezone = "America/Los_Angeles"

If MBQL datetime literal strings do not explicitly specify a timezone, they should be parsed as if in the current reporting timezone (Pacific in this case)
expected: [[6 "Shad Ferdynand" "2014-08-02T05:30:00-07:00"]]
  actual: ([[6 "Shad Ferdynand" "2014-08-02T12:30:00-07:00"]])

FAIL in metabase.query-processor-test.timezones-test/filter-test (timezones_test.clj:75)
using test-data-with-timezones dataset 
:exasol 
Setting :report-timezone = "America/Los_Angeles"

MBQL datetime literal strings that include timezone should be parsed in it regardless of report timezone
expected: [[6 "Shad Ferdynand" "2014-08-02T05:30:00-07:00"]]
  actual: ([[6 "Shad Ferdynand" "2014-08-02T12:30:00-07:00"]])
load-data for h2 test-data users (reference H2 duration: 23,8 ms) took 3,3 ms
load-data for h2 test-data categories (reference H2 duration: 10,1 ms) took 3,2 ms
load-data for h2 test-data venues (reference H2 duration: 29,4 ms) took 10,7 ms
load-data for h2 test-data checkins (reference H2 duration: 130,4 ms) took 60,4 ms
Sync :h2 Database test-data (reference H2 duration: 1,1 s) took 555,8 ms

ERROR in metabase.query-processor-test.timezones-test/time-timezone-handling-test (util.clj:353)
Uncaught exception, not in assertion.

             clojure.lang.ExceptionInfo: Error in with-temporary-setting-values: Exasol does not have a :type/TimeWithTZ data type.
    setting: :report-timezone
      value: nil
java.lang.UnsupportedOperationException: Exasol does not have a :type/TimeWithTZ data type.
                                               metabase.test.data.exasol/eval81568/fn          exasol.clj:   55
                                               metabase.test.data.sql/eval77270/fn/fn             sql.clj:  161
                                                                    clojure.core/some            core.clj: 2705
                                                  metabase.test.data.sql/eval77270/fn             sql.clj:  155
                                                                                  ...                          
metabase.query-processor-test.timezones-test/driver-distinguishes-between-base-types?  timezones_test.clj:  198
           metabase.query-processor-test.timezones-test/supports-time-with-time-zone?  timezones_test.clj:  201
                       metabase.query-processor-test.timezones-test/expected-attempts  timezones_test.clj:  212
                             metabase.query-processor-test.timezones-test/fn/fn/fn/fn  timezones_test.clj:  228
                                   metabase.test.util/do-with-temporary-setting-value            util.clj:  351
                                metabase.query-processor-test.timezones-test/fn/fn/fn  timezones_test.clj:  227
                                              metabase.test.data.impl/do-with-dataset            impl.clj:  344
                                   metabase.query-processor-test.timezones-test/fn/fn  timezones_test.clj:  225
                        metabase.test.data.datasets/do-with-driver-when-testing/fn/fn        datasets.clj:   41
                                                       metabase.driver/do-with-driver          driver.clj:   60
                           metabase.test.data.datasets/do-with-driver-when-testing/fn        datasets.clj:   40
                                   metabase.test.data.datasets/do-when-testing-driver        datasets.clj:   29
                              metabase.test.data.datasets/do-with-driver-when-testing        datasets.clj:   39
                                      metabase.query-processor-test.timezones-test/fn  timezones_test.clj:  224
                                                             clojure.test/test-var/fn            test.clj:  717
[...]

FAIL in metabase.query-processor-test.timezones-test/native-params-filter-test (timezones_test.clj:172)

:exasol using test-data-with-timezones dataset 
Setting :report-timezone = "America/Los_Angeles"
 Native dates should be parsed with the report timezone Query with variable w/ single date
expected: [[6 "Shad Ferdynand" "2014-08-02T05:30:00-07:00"]
           [7 "Conchúr Tihomir" "2014-08-02T02:30:00-07:00"]]
  actual: ([[6 "Shad Ferdynand" "2014-08-02T12:30:00-07:00"]
            [7 "Conchúr Tihomir" "2014-08-02T09:30:00-07:00"]])

FAIL in metabase.query-processor-test.timezones-test/native-params-filter-test (timezones_test.clj:172)

:exasol using test-data-with-timezones dataset 
Setting :report-timezone = "America/Los_Angeles"
 Native dates should be parsed with the report timezone Query with field filter w/ date range
expected: [[6 "Shad Ferdynand" "2014-08-02T05:30:00-07:00"]
           [7 "Conchúr Tihomir" "2014-08-02T02:30:00-07:00"]]
  actual: ([])

FAIL in metabase.query-processor-test.timezones-test/native-params-filter-test (timezones_test.clj:172)

:exasol using test-data-with-timezones dataset 
Setting :report-timezone = "America/Los_Angeles"
 Native dates should be parsed with the report timezone Query with field filter w/ single date
expected: [[6 "Shad Ferdynand" "2014-08-02T05:30:00-07:00"]
           [7 "Conchúr Tihomir" "2014-08-02T02:30:00-07:00"]]
  actual: ([])

FAIL in metabase.query-processor-test.timezones-test/result-rows-test (timezones_test.clj:57)
using test-data-with-timezones dataset 
:exasol 
Setting :report-timezone = "US/Pacific"

There should be 1 checkins on July 3rd in the US/Pacific timezone
expected: [[10 "2014-07-03T12:30:00-07:00"]]
  actual: ([[10 "2014-07-03T19:30:00-07:00"]])

Ran 4 tests in 15,079 seconds
11 assertions, 6 failures, 1 error.
{:test 4, :pass 4, :fail 6, :error 1, :type :summary, :duration 15079.052671}
Tests failed.

Adapt to Metabase v46

Metabase version 46 deprecates some API and adds new API:

  • (Breaking) Upgrade to HoneySQL 2. This may require changes. Honey SQL 1 is now in deprecation notice and will be removed after three major versions (v49).
  • New custom expression: datetime-diff
  • New custom expression: convert-timezone

See driver changelog for a complete list.

Tasks

Fix failing remapping tests

Three tests in metabase.query-processor-test.breakout-test and metabase.query-processor-test.remapping-test fail:

metabase.query-processor-test.breakout-test/internal-remapping-test

FAIL in metabase.query-processor-test.breakout-test/internal-remapping-test (breakout_test.clj:80)

:exasol With human readable values remapping test_data_venues.category_id -> {65 "Spanish", 70 "Tea Room", 62 "Seafood", 74 "Wine Bar", 7 "Bar", 59 "Ramen", 20 "Diner", 72 "Unknown", 58 "Pizza", 60 "Restaurant General", 27 "French", 1 "African", 69 "Tapas", 24 "Fashion", 55 "Nightclub", 39 "Italian", 46 "Late Dining", 4 "Asian", 54 "Museum", 15 "Chinese", 48 "Lounge", 50 "Mexican", 75 "Winery", 21 "Donut Shop", 31 "Greek", 32 "Grocery", 40 "Japanese", 56 "Nightlife", 33 "Health & Beauty", 13 "Café Sweets", 22 "English", 36 "Hot Dog", 41 "Jewish", 43 "Karaoke", 61 "Scandinavian", 29 "German", 44 "Korean", 6 "Bakery", 28 "Gay Bar", 64 "Southern", 51 "Middle Eastern", 25 "Fast Food", 34 "Home", 17 "Comedy Club", 3 "Artisan", 12 "Café", 2 "American", 66 "Stadium", 23 "Entertainment", 47 "Latin American", 35 "Hostel", 19 "Dim Sum", 57 "Outdoors", 68 "Strip Club", 11 "Burger", 9 "Breakfast / Brunch", 5 "BBQ", 14 "Caribbean", 45 "Landmark", 53 "Moroccan", 26 "Food Truck", 16 "Coffee Shop", 38 "Indian", 30 "Gluten-free", 73 "Vegetarian / Vegan", 10 "Brewery", 18 "Deli", 52 "Molecular Gastronomy", 67 "Steakhouse", 71 "Thai", 42 "Juice Bar", 37 "Hotel", 63 "South Pacific", 8 "Beer Garden", 49 "Mediterannian"}
expected: [[2 8 "American"]
           [3 2 "Artisan"]
           [4 2 "Asian"]
           [5 7 "BBQ"]
           [6 2 "Bakery"]]
  actual: ([[2 8 nil] [3 2 nil] [4 2 nil] [5 7 nil] [6 2 nil]])

Ran 1 tests in 13,372 seconds
2 assertions, 1 failure, 0 errors.
{:test 1, :pass 1, :fail 1, :error 0, :type :summary, :duration 13372.156896}
Tests failed.

Executed queries:

-- Metabase
SELECT "CAM_8"."test_data_venues"."category_id" AS "category_id", count(*) AS "count" FROM "CAM_8"."test_data_venues" GROUP BY "CAM_8"."test_data_venues"."category_id" ORDER BY "CAM_8"."test_data_venues"."category_id" ASC LIMIT 5
-- Metabase
SELECT "CAM_8"."test_data_categories"."id" AS "id", "CAM_8"."test_data_categories"."name" AS "name" FROM "CAM_8"."test_data_categories" LIMIT 1048575
-- Metabase
SELECT "CAM_8"."test_data_venues"."name" AS "name" FROM "CAM_8"."test_data_venues" GROUP BY "CAM_8"."test_data_venues"."name" ORDER BY "CAM_8"."test_data_venues"."name" ASC LIMIT 5000
-- Metabase
SELECT "CAM_8"."test_data_users"."password" AS "password" FROM "CAM_8"."test_data_users" GROUP BY "CAM_8"."test_data_users"."password" ORDER BY "CAM_8"."test_data_users"."password" ASC LIMIT 5000
-- Metabase
SELECT "CAM_8"."test_data_users"."name" AS "name" FROM "CAM_8"."test_data_users" GROUP BY "CAM_8"."test_data_users"."name" ORDER BY "CAM_8"."test_data_users"."name" ASC LIMIT 5000
-- Metabase
SELECT "CAM_8"."test_data_categories"."name" AS "name" FROM "CAM_8"."test_data_categories" GROUP BY "CAM_8"."test_data_categories"."name" ORDER BY "CAM_8"."test_data_categories"."name" ASC LIMIT 5000
-- Metabase
SELECT "source"."category_id" AS "category_id", "source"."latitude" AS "latitude", "source"."price" AS "price", "source"."substring82881" AS "substring82881", "source"."longitude" AS "longitude" FROM (SELECT "CAM_8"."test_data_venues"."category_id" AS "category_id", "CAM_8"."test_data_venues"."latitude" AS "latitude", "CAM_8"."test_data_venues"."price" AS "price", substring("CAM_8"."test_data_venues"."name", 1, 1234) AS "substring82881", "CAM_8"."test_data_venues"."longitude" AS "longitude" FROM "CAM_8"."test_data_venues") "source" LIMIT 10000
-- Metabase
SELECT "source"."substring82870" AS "substring82870", "source"."substring82871" AS "substring82871", "source"."last_login" AS "last_login" FROM (SELECT substring("CAM_8"."test_data_users"."name", 1, 1234) AS "substring82870", substring("CAM_8"."test_data_users"."password", 1, 1234) AS "substring82871", "CAM_8"."test_data_users"."last_login" AS "last_login" FROM "CAM_8"."test_data_users") "source" LIMIT 10000
-- Metabase
SELECT "source"."substring82866" AS "substring82866" FROM (SELECT substring("CAM_8"."test_data_categories"."name", 1, 1234) AS "substring82866" FROM "CAM_8"."test_data_categories") "source" LIMIT 10000
-- Metabase
SELECT "CAM_8"."test_data_checkins"."venue_id" AS "venue_id", "CAM_8"."test_data_checkins"."date" AS "date", "CAM_8"."test_data_checkins"."user_id" AS "user_id" FROM "CAM_8"."test_data_checkins" LIMIT 10000

metabase.query-processor-test.remapping-test/basic-remapping-test

FAIL in metabase.query-processor-test.remapping-test/basic-remapping-test (remapping_test.clj:14)

:exasol With human readable values remapping test_data_venues.category_id -> {65 "Spanish", 70 "Tea Room", 62 "Seafood", 74 "Wine Bar", 7 "Bar", 59 "Ramen", 20 "Diner", 72 "Unknown", 58 "Pizza", 60 "Restaurant General", 27 "French", 1 "African", 69 "Tapas", 24 "Fashion", 55 "Nightclub", 39 "Italian", 46 "Late Dining", 4 "Asian", 54 "Museum", 15 "Chinese", 48 "Lounge", 50 "Mexican", 75 "Winery", 21 "Donut Shop", 31 "Greek", 32 "Grocery", 40 "Japanese", 56 "Nightlife", 33 "Health & Beauty", 13 "Café Sweets", 22 "English", 36 "Hot Dog", 41 "Jewish", 43 "Karaoke", 61 "Scandinavian", 29 "German", 44 "Korean", 6 "Bakery", 28 "Gay Bar", 64 "Southern", 51 "Middle Eastern", 25 "Fast Food", 34 "Home", 17 "Comedy Club", 3 "Artisan", 12 "Café", 2 "American", 66 "Stadium", 23 "Entertainment", 47 "Latin American", 35 "Hostel", 19 "Dim Sum", 57 "Outdoors", 68 "Strip Club", 11 "Burger", 9 "Breakfast / Brunch", 5 "BBQ", 14 "Caribbean", 45 "Landmark", 53 "Moroccan", 26 "Food Truck", 16 "Coffee Shop", 38 "Indian", 30 "Gluten-free", 73 "Vegetarian / Vegan", 10 "Brewery", 18 "Deli", 52 "Molecular Gastronomy", 67 "Steakhouse", 71 "Thai", 42 "Juice Bar", 37 "Hotel", 63 "South Pacific", 8 "Beer Garden", 49 "Mediterannian"}
expected: {:cols [{:base_type :type/Text,
                   :coercion_strategy nil,
                   :description nil,
                   :display_name "Name",
                   :effective_type :type/Text,
                   :field_ref [:field 377 nil],
                   :fingerprint {:global {:distinct-count 100, :nil% 0.0},
                                 :type {:type/Text {:average-length 15.63,
                                                    :percent-email 0.0,
                                                    :percent-json 0.0,
                                                    :percent-state 0.0,
                                                    :percent-url 0.0}}},
                   :id 377,
                   :name "name",
                   :parent_id nil,
                   :semantic_type :type/Name,
                   :settings nil,
                   :source :fields,
                   :table_id 184,
                   :visibility_type :normal}
                  {:base_type :type/Decimal,
                   :coercion_strategy nil,
                   :description nil,
                   :display_name "Category ID",
                   :effective_type :type/Decimal,
                   :field_ref [:field 374 nil],
                   :fingerprint {:global {:distinct-count 28, :nil% 0.0}},
                   :id 374,
                   :name "category_id",
                   :parent_id nil,
                   :remapped_to "Category ID",
                   :semantic_type :type/FK,
                   :settings nil,
                   :source :fields,
                   :table_id 184,
                   :visibility_type :normal}
                  {:base_type :type/Text,
                   :description nil,
                   :display_name "Category ID",
                   :id nil,
                   :name "Category ID",
                   :remapped_from "category_id",
                   :remapped_to nil,
                   :semantic_type nil,
                   :table_id nil,
                   :target nil}],
           :rows [["20th Century Cafe" 12 "Café"]
                  ["25°" 11 "Burger"]
                  ["33 Taps" 7 "Bar"]
                  ["800 Degrees Neapolitan Pizzeria" 58 "Pizza"]]}
  actual: ({:cols [{:base_type :type/Text,
                    :coercion_strategy nil,
                    :description nil,
                    :display_name "Name",
                    :effective_type :type/Text,
                    :field_ref [:field 377 nil],
                    :fingerprint {:global {:distinct-count 100, :nil% 0.0},
                                  :type {:type/Text {:average-length 15.63,
                                                     :percent-email 0.0,
                                                     :percent-json 0.0,
                                                     :percent-state 0.0,
                                                     :percent-url 0.0}}},
                    :id 377,
                    :name "name",
                    :parent_id nil,
                    :semantic_type :type/Name,
                    :settings nil,
                    :source :fields,
                    :table_id 184,
                    :visibility_type :normal}
                   {:base_type :type/Decimal,
                    :coercion_strategy nil,
                    :description nil,
                    :display_name "Category ID",
                    :effective_type :type/Decimal,
                    :field_ref [:field 374 nil],
                    :fingerprint {:global {:distinct-count 28, :nil% 0.0}},
                    :id 374,
                    :name "category_id",
                    :parent_id nil,
                    :remapped_to "Category ID",
                    :semantic_type :type/FK,
                    :settings nil,
                    :source :fields,
                    :table_id 184,
                    :visibility_type :normal}
                   {:base_type :type/Text,
                    :description nil,
                    :display_name "Category ID",
                    :id nil,
                    :name "Category ID",
                    :remapped_from "category_id",
                    :remapped_to nil,
                    :semantic_type nil,
                    :table_id nil,
                    :target nil}],
            :rows [["20th Century Cafe" 12 nil]
                   ["25°" 11 nil]
                   ["33 Taps" 7 nil]
                   ["800 Degrees Neapolitan Pizzeria" 58 nil]]})

metabase.query-processor-test.remapping-test/nested-remapping-test

FAIL in metabase.query-processor-test.remapping-test/nested-remapping-test (remapping_test.clj:59)

:exasol With human readable values remapping test_data_venues.category_id -> {65 "Spanish", 70 "Tea Room", 62 "Seafood", 74 "Wine Bar", 7 "Bar", 59 "Ramen", 20 "Diner", 72 "Unknown", 58 "Pizza", 60 "Restaurant General", 27 "French", 1 "African", 69 "Tapas", 24 "Fashion", 55 "Nightclub", 39 "Italian", 46 "Late Dining", 4 "Asian", 54 "Museum", 15 "Chinese", 48 "Lounge", 50 "Mexican", 75 "Winery", 21 "Donut Shop", 31 "Greek", 32 "Grocery", 40 "Japanese", 56 "Nightlife", 33 "Health & Beauty", 13 "Café Sweets", 22 "English", 36 "Hot Dog", 41 "Jewish", 43 "Karaoke", 61 "Scandinavian", 29 "German", 44 "Korean", 6 "Bakery", 28 "Gay Bar", 64 "Southern", 51 "Middle Eastern", 25 "Fast Food", 34 "Home", 17 "Comedy Club", 3 "Artisan", 12 "Café", 2 "American", 66 "Stadium", 23 "Entertainment", 47 "Latin American", 35 "Hostel", 19 "Dim Sum", 57 "Outdoors", 68 "Strip Club", 11 "Burger", 9 "Breakfast / Brunch", 5 "BBQ", 14 "Caribbean", 45 "Landmark", 53 "Moroccan", 26 "Food Truck", 16 "Coffee Shop", 38 "Indian", 30 "Gluten-free", 73 "Vegetarian / Vegan", 10 "Brewery", 18 "Deli", 52 "Molecular Gastronomy", 67 "Steakhouse", 71 "Thai", 42 "Juice Bar", 37 "Hotel", 63 "South Pacific", 8 "Beer Garden", 49 "Mediterannian"}
expected: {:cols [{:base_type :type/Text,
                   :coercion_strategy nil,
                   :description nil,
                   :display_name "Name",
                   :effective_type :type/Text,
                   :field_ref [:field 377 nil],
                   :fingerprint {:global {:distinct-count 100, :nil% 0.0},
                                 :type {:type/Text {:average-length 15.63,
                                                    :percent-email 0.0,
                                                    :percent-json 0.0,
                                                    :percent-state 0.0,
                                                    :percent-url 0.0}}},
                   :id 377,
                   :name "name",
                   :parent_id nil,
                   :semantic_type :type/Name,
                   :settings nil,
                   :source :fields,
                   :table_id 184,
                   :visibility_type :normal}
                  {:base_type :type/Decimal,
                   :coercion_strategy nil,
                   :description nil,
                   :display_name "Category ID",
                   :effective_type :type/Decimal,
                   :field_ref [:field 374 nil],
                   :fingerprint {:global {:distinct-count 28, :nil% 0.0}},
                   :id 374,
                   :name "category_id",
                   :parent_id nil,
                   :remapped_to "Category ID",
                   :semantic_type :type/FK,
                   :settings nil,
                   :source :fields,
                   :table_id 184,
                   :visibility_type :normal}
                  {:base_type :type/Text,
                   :description nil,
                   :display_name "Category ID",
                   :id nil,
                   :name "Category ID",
                   :remapped_from "category_id",
                   :remapped_to nil,
                   :semantic_type nil,
                   :table_id nil,
                   :target nil}],
           :rows [["20th Century Cafe" 12 "Café"]
                  ["25°" 11 "Burger"]
                  ["33 Taps" 7 "Bar"]
                  ["800 Degrees Neapolitan Pizzeria" 58 "Pizza"]]}
  actual: ({:cols [{:base_type :type/Text,
                    :coercion_strategy nil,
                    :description nil,
                    :display_name "Name",
                    :effective_type :type/Text,
                    :field_ref [:field 377 nil],
                    :fingerprint {:global {:distinct-count 100, :nil% 0.0},
                                  :type {:type/Text {:average-length 15.63,
                                                     :percent-email 0.0,
                                                     :percent-json 0.0,
                                                     :percent-state 0.0,
                                                     :percent-url 0.0}}},
                    :id 377,
                    :name "name",
                    :parent_id nil,
                    :semantic_type :type/Name,
                    :settings nil,
                    :source :fields,
                    :table_id 184,
                    :visibility_type :normal}
                   {:base_type :type/Decimal,
                    :coercion_strategy nil,
                    :description nil,
                    :display_name "Category ID",
                    :effective_type :type/Decimal,
                    :field_ref [:field 374 nil],
                    :fingerprint {:global {:distinct-count 28, :nil% 0.0}},
                    :id 374,
                    :name "category_id",
                    :parent_id nil,
                    :remapped_to "Category ID",
                    :semantic_type :type/FK,
                    :settings nil,
                    :source :fields,
                    :table_id 184,
                    :visibility_type :normal}
                   {:base_type :type/Text,
                    :description nil,
                    :display_name "Category ID",
                    :id nil,
                    :name "Category ID",
                    :remapped_from "category_id",
                    :remapped_to nil,
                    :semantic_type nil,
                    :table_id nil,
                    :target nil}],
            :rows [["20th Century Cafe" 12 nil]
                   ["25°" 11 nil]
                   ["33 Taps" 7 nil]
                   ["800 Degrees Neapolitan Pizzeria" 58 nil]]})

Reactivate "double-quotes-in-join-alias-test" test

Test double-quotes-in-join-alias-test is currently deactivated because Exasol 7.1 does not support the dot . in quoted identifiers, see exclude_tests.diff.

Acceptance Criteria

  • Upgrade to Exasol 8.0 and reactivate the double-quotes-in-join-alias-test test

This is blocked until Exasol 8.0 is available as a docker container.

Adapt manifest to partner requirements

This is a precondition for adding our driver to Metabase: metabase/metabase#23800

  • Add contact information to the driver manifest. You should add the contact name and an address (which can be an email or a link). Example.
  • Still on the manifest, you should add "- advanced-options-start - default-advanced-options" keys. Example. This enables users to set a custom schedule for Metabase system processes (sync, scanning, and fingerprinting) (there is no additional driver work required).

Provide better error messages

Error messages from the JDBC driver might not be very helpful to the user. We should replace them with readable messages by implementing humanize-connection-error-message.

Scanning field values logs an exception for GEOMETRY columns

When Metabase scans field values of a table with a GEOMETRY column (e.g. when you click the "Re-scan field values now" button on the Database page) it logs the following exception:

2022-01-17 09:01:18,009 ERROR models.field-values :: Error fetching field values
clojure.lang.ExceptionInfo: Error executing query {:sql "-- Metabase\nSELECT \"META\".\"DATA_TYPES\".\"GEO\" AS \"GEO\" FROM \"META\".\"DATA_TYPES\" GROUP BY \"META\".\"DATA_TYPES\".\"GEO\" ORDER BY \"META\".\"DATA_TYPES\".\"GEO\" ASC LIMIT 5000", :params nil, :type :invalid-query}
...
Caused by: java.sql.SQLException: Feature not supported: GEOMETRY type in GROUP BY (Session: 1722185677957169152)
...

There seem to be no consequences of this error, everything seems to work fine.

Also see this discussion in the Metabase forum.

Workaround

To avoid logging this exception, you can update the relevant GEOMETRY column on Metabase's "Data Model" page and set the Visibility to "Only in detail views" or "Do not include".

Note: when clicking the the "Re-scan this field" button on the field settings page, Metabase will still log the exception.

Complete stack trace

2022-01-17 09:01:18,009 ERROR models.field-values :: Error fetching field values
clojure.lang.ExceptionInfo: Error executing query {:sql "-- Metabase\nSELECT \"META\".\"DATA_TYPES\".\"GEO\" AS \"GEO\" FROM \"META\".\"DATA_TYPES\" GROUP BY \"META\".\"DATA_TYPES\".\"GEO\" ORDER BY \"META\".\"DATA_TYPES\".\"GEO\" ASC LIMIT 5000", :params nil, :type :invalid-query}
	at metabase.driver.sql_jdbc.execute$execute_reducible_query$fn__52491.invoke(execute.clj:504)
	at metabase.driver.sql_jdbc.execute$execute_reducible_query.invokeStatic(execute.clj:501)
	at metabase.driver.sql_jdbc.execute$execute_reducible_query.invoke(execute.clj:487)
	at metabase.driver.sql_jdbc.execute$execute_reducible_query.invokeStatic(execute.clj:496)
	at metabase.driver.sql_jdbc.execute$execute_reducible_query.invoke(execute.clj:487)
	at metabase.driver.sql_jdbc$fn__85172.invokeStatic(sql_jdbc.clj:54)
	at metabase.driver.sql_jdbc$fn__85172.invoke(sql_jdbc.clj:52)
	at clojure.lang.MultiFn.invoke(MultiFn.java:244)
	at metabase.query_processor.context$executef.invokeStatic(context.clj:59)
	at metabase.query_processor.context$executef.invoke(context.clj:48)
	at metabase.query_processor.context.default$default_runf.invokeStatic(default.clj:68)
	at metabase.query_processor.context.default$default_runf.invoke(default.clj:66)
	at metabase.query_processor.context$runf.invokeStatic(context.clj:45)
	at metabase.query_processor.context$runf.invoke(context.clj:39)
	at metabase.query_processor.reducible$pivot.invokeStatic(reducible.clj:34)
	at metabase.query_processor.reducible$pivot.invoke(reducible.clj:31)
	at metabase.query_processor.middleware.mbql_to_native$mbql__GT_native$fn__49144.invoke(mbql_to_native.clj:25)
	at metabase.query_processor.middleware.check_features$check_features$fn__49630.invoke(check_features.clj:39)
	at metabase.query_processor.middleware.limit$limit$fn__47517.invoke(limit.clj:37)
	at metabase.query_processor.middleware.cache$maybe_return_cached_results$fn__50004.invoke(cache.clj:204)
	at metabase.query_processor.middleware.optimize_temporal_filters$optimize_temporal_filters$fn__50997.invoke(optimize_temporal_filters.clj:204)
	at metabase.query_processor.middleware.validate_temporal_bucketing$validate_temporal_bucketing$fn__51041.invoke(validate_temporal_bucketing.clj:50)
	at metabase.query_processor.middleware.auto_parse_filter_values$auto_parse_filter_values$fn__49201.invoke(auto_parse_filter_values.clj:43)
	at metabase.query_processor.middleware.wrap_value_literals$wrap_value_literals$fn__39249.invoke(wrap_value_literals.clj:161)
	at metabase.query_processor.middleware.annotate$add_column_info$fn__43680.invoke(annotate.clj:620)
	at metabase.query_processor.middleware.permissions$check_query_permissions$fn__45618.invoke(permissions.clj:108)
	at metabase.query_processor.middleware.pre_alias_aggregations$pre_alias_aggregations$fn__50181.invoke(pre_alias_aggregations.clj:40)
	at metabase.query_processor.middleware.cumulative_aggregations$handle_cumulative_aggregations$fn__46016.invoke(cumulative_aggregations.clj:60)
	at metabase.query_processor.middleware.visualization_settings$update_viz_settings$fn__45954.invoke(visualization_settings.clj:63)
	at metabase.query_processor.middleware.resolve_joined_fields$resolve_joined_fields$fn__47115.invoke(resolve_joined_fields.clj:102)
	at metabase.query_processor.middleware.resolve_joins$resolve_joins$fn__50767.invoke(resolve_joins.clj:171)
	at metabase.query_processor.middleware.add_implicit_joins$add_implicit_joins$fn__50303.invoke(add_implicit_joins.clj:190)
	at metabase.query_processor.middleware.large_int_id$convert_id_to_string$fn__47134.invoke(large_int_id.clj:59)
	at metabase.query_processor.middleware.format_rows$format_rows$fn__50355.invoke(format_rows.clj:74)
	at metabase.query_processor.middleware.add_default_temporal_unit$add_default_temporal_unit$fn__46506.invoke(add_default_temporal_unit.clj:23)
	at metabase.query_processor.middleware.desugar$desugar$fn__45927.invoke(desugar.clj:21)
	at metabase.query_processor.middleware.binning$update_binning_strategy$fn__39149.invoke(binning.clj:229)
	at metabase.query_processor.middleware.resolve_fields$resolve_fields$fn__45261.invoke(resolve_fields.clj:34)
	at metabase.query_processor.middleware.add_dimension_projections$add_remapping$fn__49556.invoke(add_dimension_projections.clj:314)
	at metabase.query_processor.middleware.add_implicit_clauses$add_implicit_clauses$fn__49853.invoke(add_implicit_clauses.clj:147)
	at metabase.query_processor.middleware.upgrade_field_literals$upgrade_field_literals$fn__47502.invoke(upgrade_field_literals.clj:40)
	at metabase.query_processor.middleware.add_source_metadata$add_source_metadata_for_source_queries$fn__46883.invoke(add_source_metadata.clj:123)
	at metabase.query_processor.middleware.reconcile_breakout_and_order_by_bucketing$reconcile_breakout_and_order_by_bucketing$fn__50103.invoke(reconcile_breakout_and_order_by_bucketing.clj:100)
	at metabase.query_processor.middleware.auto_bucket_datetimes$auto_bucket_datetimes$fn__48453.invoke(auto_bucket_datetimes.clj:147)
	at metabase.query_processor.middleware.resolve_source_table$resolve_source_tables$fn__45242.invoke(resolve_source_table.clj:45)
	at metabase.query_processor.middleware.parameters$substitute_parameters$fn__48107.invoke(parameters.clj:111)
	at metabase.query_processor.middleware.resolve_referenced$resolve_referenced_card_resources$fn__45315.invoke(resolve_referenced.clj:79)
	at metabase.query_processor.middleware.expand_macros$expand_macros$fn__51425.invoke(expand_macros.clj:184)
	at metabase.query_processor.middleware.add_timezone_info$add_timezone_info$fn__47886.invoke(add_timezone_info.clj:15)
	at metabase.query_processor.middleware.splice_params_in_response$splice_params_in_response$fn__50370.invoke(splice_params_in_response.clj:32)
	at metabase.query_processor.middleware.resolve_database_and_driver$resolve_database_and_driver$fn__49864$fn__49868.invoke(resolve_database_and_driver.clj:31)
	at metabase.driver$do_with_driver.invokeStatic(driver.clj:60)
	at metabase.driver$do_with_driver.invoke(driver.clj:56)
	at metabase.query_processor.middleware.resolve_database_and_driver$resolve_database_and_driver$fn__49864.invoke(resolve_database_and_driver.clj:25)
	at metabase.query_processor.middleware.fetch_source_query$resolve_card_id_source_tables$fn__45865.invoke(fetch_source_query.clj:274)
	at metabase.query_processor.middleware.store$initialize_store$fn__46053$fn__46054.invoke(store.clj:11)
	at metabase.query_processor.store$do_with_store.invokeStatic(store.clj:44)
	at metabase.query_processor.store$do_with_store.invoke(store.clj:38)
	at metabase.query_processor.middleware.store$initialize_store$fn__46053.invoke(store.clj:10)
	at metabase.query_processor.middleware.validate$validate_query$fn__50153.invoke(validate.clj:10)
	at metabase.query_processor.middleware.normalize_query$normalize$fn__50160.invoke(normalize_query.clj:22)
	at metabase.query_processor.middleware.add_rows_truncated$add_rows_truncated$fn__47832.invoke(add_rows_truncated.clj:35)
	at metabase.query_processor.middleware.results_metadata$record_and_return_metadata_BANG_$fn__49130.invoke(results_metadata.clj:147)
	at metabase.query_processor.reducible$async_qp$qp_STAR___42500$thunk__42501.invoke(reducible.clj:103)
	at metabase.query_processor.reducible$async_qp$qp_STAR___42500.invoke(reducible.clj:109)
	at metabase.query_processor.reducible$async_qp$qp_STAR___42500.invoke(reducible.clj:96)
	at metabase.query_processor.reducible$sync_qp$qp_STAR___42509$fn__42510.invoke(reducible.clj:131)
	at metabase.query_processor.reducible$sync_qp$qp_STAR___42509.invoke(reducible.clj:130)
	at clojure.lang.AFn.applyToHelper(AFn.java:154)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invokeStatic(core.clj:669)
	at clojure.core$apply.invoke(core.clj:662)
	at metabase.query_processor$process_query.invokeStatic(query_processor.clj:152)
	at metabase.query_processor$process_query.doInvoke(query_processor.clj:146)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at metabase.db.metadata_queries$qp_query$fn__69317.invoke(metadata_queries.clj:21)
	at metabase.db.metadata_queries$qp_query.invokeStatic(metadata_queries.clj:20)
	at metabase.db.metadata_queries$qp_query.invoke(metadata_queries.clj:18)
	at metabase.db.metadata_queries$field_query.invokeStatic(metadata_queries.clj:30)
	at metabase.db.metadata_queries$field_query.invoke(metadata_queries.clj:28)
	at metabase.db.metadata_queries$fn__69337$field_distinct_values__69346$fn__69349.invoke(metadata_queries.clj:75)
	at metabase.db.metadata_queries$fn__69337$field_distinct_values__69346.invoke(metadata_queries.clj:68)
	at metabase.db.metadata_queries$fn__69337$field_distinct_values__69346$fn__69347.invoke(metadata_queries.clj:72)
	at metabase.db.metadata_queries$fn__69337$field_distinct_values__69346.invoke(metadata_queries.clj:68)
	at clojure.lang.Var.invoke(Var.java:384)
	at metabase.models.field_values$distinct_values.invokeStatic(field_values.clj:132)
	at metabase.models.field_values$distinct_values.invoke(field_values.clj:124)
	at metabase.models.field_values$create_or_update_field_values_BANG_.invokeStatic(field_values.clj:154)
	at metabase.models.field_values$create_or_update_field_values_BANG_.doInvoke(field_values.clj:148)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at metabase.sync.field_values$fn__69214$update_field_values_for_field_BANG___69219$fn__69220.invoke(field_values.clj:23)
	at metabase.sync.field_values$fn__69214$update_field_values_for_field_BANG___69219.invoke(field_values.clj:21)
	at metabase.sync.field_values$fn__69240$update_field_values_for_table_BANG___69245$fn__69246$fn__69247$fn__69248.invoke(field_values.clj:44)
	at metabase.sync.util$do_with_error_handling.invokeStatic(util.clj:156)
	at metabase.sync.util$do_with_error_handling.invoke(util.clj:149)
	at metabase.sync.field_values$fn__69240$update_field_values_for_table_BANG___69245$fn__69246$fn__69247.invoke(field_values.clj:42)
	at clojure.lang.PersistentVector.reduce(PersistentVector.java:343)
	at clojure.core$reduce.invokeStatic(core.clj:6829)
	at clojure.core$reduce.invoke(core.clj:6812)
	at metabase.sync.field_values$fn__69240$update_field_values_for_table_BANG___69245$fn__69246.invoke(field_values.clj:41)
	at metabase.sync.field_values$fn__69240$update_field_values_for_table_BANG___69245.invoke(field_values.clj:38)
	at clojure.core$map$fn__5884.invoke(core.clj:2757)
	at clojure.lang.LazySeq.sval(LazySeq.java:42)
	at clojure.lang.LazySeq.seq(LazySeq.java:51)
	at clojure.lang.Cons.next(Cons.java:39)
	at clojure.lang.RT.boundedLength(RT.java:1793)
	at clojure.lang.RestFn.applyTo(RestFn.java:130)
	at clojure.core$apply.invokeStatic(core.clj:669)
	at clojure.core$apply.invoke(core.clj:662)
	at metabase.sync.field_values$fn__69267$update_field_values_for_database_BANG___69272$fn__69273.invoke(field_values.clj:52)
	at metabase.sync.field_values$fn__69267$update_field_values_for_database_BANG___69272.invoke(field_values.clj:50)
	at clojure.lang.AFn.applyToHelper(AFn.java:154)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invokeStatic(core.clj:669)
	at clojure.core$apply.invoke(core.clj:662)
	at metabase.sync.util$fn__40096$run_step_with_metadata__40101$fn__40105$fn__40107.doInvoke(util.clj:360)
	at clojure.lang.RestFn.invoke(RestFn.java:397)
	at metabase.sync.util$with_start_and_finish_logging_STAR_.invokeStatic(util.clj:99)
	at metabase.sync.util$with_start_and_finish_logging_STAR_.invoke(util.clj:93)
	at metabase.sync.util$with_start_and_finish_debug_logging.invokeStatic(util.clj:116)
	at metabase.sync.util$with_start_and_finish_debug_logging.invoke(util.clj:113)
	at metabase.sync.util$fn__40096$run_step_with_metadata__40101$fn__40105.invoke(util.clj:355)
	at metabase.sync.util$fn__40096$run_step_with_metadata__40101.invoke(util.clj:350)
	at metabase.sync.util$fn__40287$run_sync_operation__40292$fn__40293$fn__40301.invoke(util.clj:451)
	at metabase.sync.util$fn__40287$run_sync_operation__40292$fn__40293.invoke(util.clj:449)
	at metabase.sync.util$fn__40287$run_sync_operation__40292.invoke(util.clj:443)
	at metabase.sync.field_values$fn__69293$update_field_values_BANG___69298$fn__69299$fn__69300.invoke(field_values.clj:67)
	at metabase.sync.util$do_with_error_handling.invokeStatic(util.clj:156)
	at metabase.sync.util$do_with_error_handling.invoke(util.clj:149)
	at clojure.core$partial$fn__5859.invoke(core.clj:2634)
	at metabase.driver$fn__24548.invokeStatic(driver.clj:555)
	at metabase.driver$fn__24548.invoke(driver.clj:555)
	at clojure.lang.MultiFn.invoke(MultiFn.java:239)
	at metabase.sync.util$sync_in_context$fn__40008.invoke(util.clj:135)
	at metabase.sync.util$with_db_logging_disabled$fn__40005.invoke(util.clj:126)
	at metabase.sync.util$with_start_and_finish_logging_STAR_.invokeStatic(util.clj:99)
	at metabase.sync.util$with_start_and_finish_logging_STAR_.invoke(util.clj:93)
	at metabase.sync.util$with_start_and_finish_logging$fn__39994.invoke(util.clj:111)
	at metabase.sync.util$with_sync_events$fn__39989.invoke(util.clj:85)
	at metabase.sync.util$with_duplicate_ops_prevented$fn__39980.invoke(util.clj:64)
	at metabase.sync.util$do_sync_operation.invokeStatic(util.clj:177)
	at metabase.sync.util$do_sync_operation.invoke(util.clj:174)
	at metabase.sync.field_values$fn__69293$update_field_values_BANG___69298$fn__69299.invoke(field_values.clj:65)
	at metabase.sync.field_values$fn__69293$update_field_values_BANG___69298.invoke(field_values.clj:61)
	at metabase.api.database$fn__77231$fn__77233.invoke(database.clj:666)
	at clojure.core$binding_conveyor_fn$fn__5772.invoke(core.clj:2034)
	at clojure.lang.AFn.call(AFn.java:18)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.sql.SQLException: Feature not supported: GEOMETRY type in GROUP BY (Session: 1722185677957169152)
	at com.exasol.jdbc.ExceptionFactory.createSQLException(ExceptionFactory.java:258)
	at com.exasol.jdbc.EXASQLException.getSQLExceptionIntern(EXASQLException.java:50)
	at com.exasol.jdbc.AbstractEXAStatement.execute(AbstractEXAStatement.java:478)
	at com.exasol.jdbc.EXAStatement.execute(EXAStatement.java:289)
	at com.mchange.v2.c3p0.impl.NewProxyStatement.execute(NewProxyStatement.java:75)
	at metabase.driver.sql_jdbc.execute$fn__52411.invokeStatic(execute.clj:368)
	at metabase.driver.sql_jdbc.execute$fn__52411.invoke(execute.clj:366)
	at clojure.lang.MultiFn.invoke(MultiFn.java:239)
	at metabase.driver.sql_jdbc.execute$execute_statement_or_prepared_statement_BANG_.invokeStatic(execute.clj:376)
	at metabase.driver.sql_jdbc.execute$execute_statement_or_prepared_statement_BANG_.invoke(execute.clj:373)
	at metabase.driver.sql_jdbc.execute$execute_reducible_query$fn__52491.invoke(execute.clj:502)
	... 150 more

Add support for all Exasol data types

See https://docs.exasol.com/sql_references/data_types/datatypesoverview.htm

INTERVAL type

2021-12-02 09:21:27,759 WARN sync.util :: Error generating fingerprint for Field 314 'INTERVAL_DAY'
java.time.format.DateTimeParseException: Text '+05 00:00:00.000' could not be parsed, unparsed text found at index 3
        at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2049)
        at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1874)
        at metabase.util.date_2.parse$eval13045$parse_with_formatter__13050$fn__13051.invoke(parse.clj:48)
        at metabase.util.date_2.parse$eval13045$parse_with_formatter__13050.invoke(parse.clj:41)

GEOMETRY type

2021-12-02 09:24:45,165 INFO sync.util :: STARTING: step 'update-field-values' for exasol Database 6 'vbox1'
2021-12-02 09:24:46,731 ERROR models.field-values :: Error fetching field values
clojure.lang.ExceptionInfo: Error executing query {:sql "-- Metabase\nSELECT \"META\".\"DATA_TYPES\".\"GEO\" AS \"GEO\" FROM \"META\".\"DATA_TYPES\" GROUP BY \"META\".\"DATA_TYPES\".\"GEO\" ORDER BY \"META\".\"DATA_TYPES\".\"GEO\" ASC LIMIT 5000", :params nil, :type :invalid-query}
        at metabase.driver.sql_jdbc.execute$execute_reducible_query$fn__47036.invoke(execute.clj:505)
        at metabase.driver.sql_jdbc.execute$execute_reducible_query.invokeStatic(execute.clj:502)
        at metabase.driver.sql_jdbc.execute$execute_reducible_query.invoke(execute.clj:488)
        at metabase.driver.sql_jdbc.execute$execute_reducible_query.invokeStatic(execute.clj:497)
        at metabase.driver.sql_jdbc.execute$execute_reducible_query.invoke(execute.clj:488)
        at metabase.driver.sql_jdbc$eval61591$fn__61592.invoke(sql_jdbc.clj:54)
...
Caused by: java.sql.SQLException: Feature not supported: GEOMETRY type in GROUP BY (Session: 1717868520831320064)
        at com.exasol.jdbc.ExceptionFactory.createSQLException(ExceptionFactory.java:258)
        at com.exasol.jdbc.EXASQLException.getSQLExceptionIntern(EXASQLException.java:50)
        at com.exasol.jdbc.AbstractEXAStatement.execute(AbstractEXAStatement.java:478)
        at com.exasol.jdbc.EXAStatement.execute(EXAStatement.java:289)
        at com.mchange.v2.c3p0.impl.NewProxyStatement.execute(NewProxyStatement.java:75)
        at metabase.driver.sql_jdbc.execute$eval46940$fn__46941.invoke(execute.clj:369)
...

TIMESTAMP

2021-12-02 09:28:19,173 WARN sync.util :: Error generating fingerprint for Field 4,462 'WEB_REC_END_DATE'
clojure.lang.ExceptionInfo: Conversion failed {:path [[#object[java_time.graph.Types 0x63df1fb9 "[java.util.Date]"] #object[java_time.graph.Types 0x3b981537 "[java.time.Instant]"]]], :arguments [#inst "1999-08-15T22:00:00.000-00:00"], :to java.time.Instant}
        at java_time.temporal$instant$fn__10550.invoke(temporal.clj:350)
        at java_time.temporal$instant.invokeStatic(temporal.clj:350)
        at java_time.temporal$instant.invoke(temporal.clj:350)
        at metabase.sync.analyze.fingerprint.fingerprinters$eval49901$fn__49902.invoke(fingerprinters.clj:199)
        at metabase.sync.analyze.fingerprint.fingerprinters$eval49856$fn__49857$G__49847__49862.invoke(fingerprinters.clj:186)
...
Caused by: java.lang.UnsupportedOperationException
        at java.sql/java.sql.Date.toInstant(Date.java:316)
        at java_time.temporal$eval10519$fn__10520.invoke(temporal.clj:332)
...

Upgrade driver to Metabase v0.47.3

Using driver version 1.0.5 with the latest Metabase version v0.47.3 causes errors like this:

Error processing query: No method in multimethod 'connection-details->spec' for dispatch value: :exasol

NullPointerException when reading a null Timestamp

When reading a null value from a TIMESTAMP column the driver throws a NullPointerException:

2022-01-12 16:06:21,131 WARN sync.util :: Error fingerprinting Table 23 'EXASOL_STATS.PROFILE_HIDDEN_CURRENT_USER_LAST_DAY'
clojure.lang.ExceptionInfo: Error reducing result rows {:type :qp}
	at metabase.query_processor.context.default$default_reducef$fn__42412.invoke(default.clj:60)
	at metabase.query_processor.context.default$default_reducef.invokeStatic(default.clj:57)
	at metabase.query_processor.context.default$default_reducef.invoke(default.clj:48)
	at metabase.query_processor.context$reducef.invokeStatic(context.clj:69)
	at metabase.query_processor.context$reducef.invoke(context.clj:62)
	at metabase.query_processor.context.default$default_runf$respond_STAR___42416.invoke(default.clj:69)
	at metabase.driver.sql_jdbc.execute$execute_reducible_query.invokeStatic(execute.clj:509)
	at metabase.driver.sql_jdbc.execute$execute_reducible_query.invoke(execute.clj:487)
	at metabase.driver.sql_jdbc.execute$execute_reducible_query.invokeStatic(execute.clj:496)
	at metabase.driver.sql_jdbc.execute$execute_reducible_query.invoke(execute.clj:487)
	at metabase.driver.sql_jdbc$fn__85172.invokeStatic(sql_jdbc.clj:54)
	at metabase.driver.sql_jdbc$fn__85172.invoke(sql_jdbc.clj:52)
	at clojure.lang.MultiFn.invoke(MultiFn.java:244)
	at metabase.query_processor.context$executef.invokeStatic(context.clj:59)
	at metabase.query_processor.context$executef.invoke(context.clj:48)
	at metabase.query_processor.context.default$default_runf.invokeStatic(default.clj:68)
	at metabase.query_processor.context.default$default_runf.invoke(default.clj:66)
	at metabase.query_processor.context$runf.invokeStatic(context.clj:45)
	at metabase.query_processor.context$runf.invoke(context.clj:39)
	at metabase.query_processor.reducible$pivot.invokeStatic(reducible.clj:34)
	at metabase.query_processor.reducible$pivot.invoke(reducible.clj:31)
	at metabase.query_processor.middleware.mbql_to_native$mbql__GT_native$fn__49144.invoke(mbql_to_native.clj:25)
	at metabase.query_processor.middleware.check_features$check_features$fn__49630.invoke(check_features.clj:39)
	at metabase.query_processor.middleware.limit$limit$fn__47517.invoke(limit.clj:37)
	at metabase.query_processor.middleware.cache$maybe_return_cached_results$fn__50004.invoke(cache.clj:204)
	at metabase.query_processor.middleware.optimize_temporal_filters$optimize_temporal_filters$fn__50997.invoke(optimize_temporal_filters.clj:204)
	at metabase.query_processor.middleware.validate_temporal_bucketing$validate_temporal_bucketing$fn__51041.invoke(validate_temporal_bucketing.clj:50)
	at metabase.query_processor.middleware.auto_parse_filter_values$auto_parse_filter_values$fn__49201.invoke(auto_parse_filter_values.clj:43)
	at metabase.query_processor.middleware.wrap_value_literals$wrap_value_literals$fn__39249.invoke(wrap_value_literals.clj:161)
	at metabase.query_processor.middleware.annotate$add_column_info$fn__43680.invoke(annotate.clj:620)
	at metabase.query_processor.middleware.permissions$check_query_permissions$fn__45618.invoke(permissions.clj:108)
	at metabase.query_processor.middleware.pre_alias_aggregations$pre_alias_aggregations$fn__50181.invoke(pre_alias_aggregations.clj:40)
	at metabase.query_processor.middleware.cumulative_aggregations$handle_cumulative_aggregations$fn__46016.invoke(cumulative_aggregations.clj:60)
	at metabase.query_processor.middleware.visualization_settings$update_viz_settings$fn__45954.invoke(visualization_settings.clj:63)
	at metabase.query_processor.middleware.resolve_joined_fields$resolve_joined_fields$fn__47115.invoke(resolve_joined_fields.clj:102)
	at metabase.query_processor.middleware.resolve_joins$resolve_joins$fn__50767.invoke(resolve_joins.clj:171)
	at metabase.query_processor.middleware.add_implicit_joins$add_implicit_joins$fn__50303.invoke(add_implicit_joins.clj:190)
	at metabase.query_processor.middleware.large_int_id$convert_id_to_string$fn__47134.invoke(large_int_id.clj:59)
	at metabase.query_processor.middleware.format_rows$format_rows$fn__50355.invoke(format_rows.clj:74)
	at metabase.query_processor.middleware.add_default_temporal_unit$add_default_temporal_unit$fn__46506.invoke(add_default_temporal_unit.clj:23)
	at metabase.query_processor.middleware.desugar$desugar$fn__45927.invoke(desugar.clj:21)
	at metabase.query_processor.middleware.binning$update_binning_strategy$fn__39149.invoke(binning.clj:229)
	at metabase.query_processor.middleware.resolve_fields$resolve_fields$fn__45261.invoke(resolve_fields.clj:34)
	at metabase.query_processor.middleware.add_dimension_projections$add_remapping$fn__49556.invoke(add_dimension_projections.clj:314)
	at metabase.query_processor.middleware.add_implicit_clauses$add_implicit_clauses$fn__49853.invoke(add_implicit_clauses.clj:147)
	at metabase.query_processor.middleware.upgrade_field_literals$upgrade_field_literals$fn__47502.invoke(upgrade_field_literals.clj:40)
	at metabase.query_processor.middleware.add_source_metadata$add_source_metadata_for_source_queries$fn__46883.invoke(add_source_metadata.clj:123)
	at metabase.query_processor.middleware.reconcile_breakout_and_order_by_bucketing$reconcile_breakout_and_order_by_bucketing$fn__50103.invoke(reconcile_breakout_and_order_by_bucketing.clj:100)
	at metabase.query_processor.middleware.auto_bucket_datetimes$auto_bucket_datetimes$fn__48453.invoke(auto_bucket_datetimes.clj:147)
	at metabase.query_processor.middleware.resolve_source_table$resolve_source_tables$fn__45242.invoke(resolve_source_table.clj:45)
	at metabase.query_processor.middleware.parameters$substitute_parameters$fn__48107.invoke(parameters.clj:111)
	at metabase.query_processor.middleware.resolve_referenced$resolve_referenced_card_resources$fn__45315.invoke(resolve_referenced.clj:79)
	at metabase.query_processor.middleware.expand_macros$expand_macros$fn__51425.invoke(expand_macros.clj:184)
	at metabase.query_processor.middleware.add_timezone_info$add_timezone_info$fn__47886.invoke(add_timezone_info.clj:15)
	at metabase.query_processor.middleware.splice_params_in_response$splice_params_in_response$fn__50370.invoke(splice_params_in_response.clj:32)
	at metabase.query_processor.middleware.resolve_database_and_driver$resolve_database_and_driver$fn__49864$fn__49868.invoke(resolve_database_and_driver.clj:31)
	at metabase.driver$do_with_driver.invokeStatic(driver.clj:60)
	at metabase.driver$do_with_driver.invoke(driver.clj:56)
	at metabase.query_processor.middleware.resolve_database_and_driver$resolve_database_and_driver$fn__49864.invoke(resolve_database_and_driver.clj:25)
	at metabase.query_processor.middleware.fetch_source_query$resolve_card_id_source_tables$fn__45865.invoke(fetch_source_query.clj:274)
	at metabase.query_processor.middleware.store$initialize_store$fn__46053$fn__46054.invoke(store.clj:11)
	at metabase.query_processor.store$do_with_store.invokeStatic(store.clj:42)
	at metabase.query_processor.store$do_with_store.invoke(store.clj:38)
	at metabase.query_processor.middleware.store$initialize_store$fn__46053.invoke(store.clj:10)
	at metabase.query_processor.middleware.validate$validate_query$fn__50153.invoke(validate.clj:10)
	at metabase.query_processor.middleware.normalize_query$normalize$fn__50160.invoke(normalize_query.clj:22)
	at metabase.query_processor.middleware.add_rows_truncated$add_rows_truncated$fn__47832.invoke(add_rows_truncated.clj:35)
	at metabase.query_processor.middleware.results_metadata$record_and_return_metadata_BANG_$fn__49130.invoke(results_metadata.clj:143)
	at metabase.query_processor.reducible$async_qp$qp_STAR___42500$thunk__42501.invoke(reducible.clj:103)
	at metabase.query_processor.reducible$async_qp$qp_STAR___42500.invoke(reducible.clj:109)
	at metabase.query_processor.reducible$sync_qp$qp_STAR___42509$fn__42512.invoke(reducible.clj:135)
	at metabase.query_processor.reducible$sync_qp$qp_STAR___42509.invoke(reducible.clj:134)
	at clojure.lang.AFn.applyToHelper(AFn.java:156)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invokeStatic(core.clj:669)
	at clojure.core$apply.invoke(core.clj:662)
	at metabase.query_processor$process_query.invokeStatic(query_processor.clj:152)
	at metabase.query_processor$process_query.doInvoke(query_processor.clj:146)
	at clojure.lang.RestFn.invoke(RestFn.java:423)
	at clojure.lang.Var.invoke(Var.java:388)
	at metabase.db.metadata_queries$fn__69432$table_rows_sample__69441$fn__69444.invoke(metadata_queries.clj:144)
	at metabase.db.metadata_queries$fn__69432$table_rows_sample__69441.invoke(metadata_queries.clj:131)
	at metabase.sync.analyze.fingerprint$fn__69499$fingerprint_table_BANG___69504$fn__69505.invoke(fingerprint.clj:66)
	at metabase.sync.analyze.fingerprint$fn__69499$fingerprint_table_BANG___69504.invoke(fingerprint.clj:46)
	at metabase.sync.analyze.fingerprint$fn__69675$fingerprint_fields_BANG___69680$fn__69681$fn__69682.invoke(fingerprint.clj:180)
	at metabase.sync.util$do_with_error_handling.invokeStatic(util.clj:156)
	at metabase.sync.util$do_with_error_handling.invoke(util.clj:149)
	at metabase.sync.analyze.fingerprint$fn__69675$fingerprint_fields_BANG___69680$fn__69681.invoke(fingerprint.clj:178)
	at metabase.sync.analyze.fingerprint$fn__69675$fingerprint_fields_BANG___69680.invoke(fingerprint.clj:174)
	at metabase.sync.analyze.fingerprint$fn__69710$fingerprint_fields_for_db_BANG__STAR___69719$fn__69722$fn__69723$fn__69724.invoke(fingerprint.clj:204)
	at clojure.lang.PersistentVector.reduce(PersistentVector.java:343)
	at clojure.core$reduce.invokeStatic(core.clj:6829)
	at clojure.core$reduce.invoke(core.clj:6812)
	at metabase.sync.analyze.fingerprint$fn__69710$fingerprint_fields_for_db_BANG__STAR___69719$fn__69722$fn__69723.invoke(fingerprint.clj:200)
	at metabase.query_processor.store$do_with_store.invokeStatic(store.clj:44)
	at metabase.query_processor.store$do_with_store.invoke(store.clj:38)
	at metabase.sync.analyze.fingerprint$fn__69710$fingerprint_fields_for_db_BANG__STAR___69719$fn__69722.invoke(fingerprint.clj:197)
	at metabase.sync.analyze.fingerprint$fn__69710$fingerprint_fields_for_db_BANG__STAR___69719.invoke(fingerprint.clj:186)
	at metabase.sync.analyze.fingerprint$fn__69710$fingerprint_fields_for_db_BANG__STAR___69719$fn__69720.invoke(fingerprint.clj:191)
	at metabase.sync.analyze.fingerprint$fn__69710$fingerprint_fields_for_db_BANG__STAR___69719.invoke(fingerprint.clj:186)
	at metabase.sync.analyze.fingerprint$fn__69752$fingerprint_fields_for_db_BANG___69757$fn__69758.invoke(fingerprint.clj:218)
	at metabase.sync.analyze.fingerprint$fn__69752$fingerprint_fields_for_db_BANG___69757.invoke(fingerprint.clj:212)
	at metabase.sync.analyze$make_analyze_steps$fn__70065.invoke(analyze.clj:104)
	at clojure.lang.AFn.applyToHelper(AFn.java:154)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.core$apply.invokeStatic(core.clj:669)
	at clojure.core$apply.invoke(core.clj:662)
	at metabase.sync.util$fn__40096$run_step_with_metadata__40101$fn__40105$fn__40107.doInvoke(util.clj:360)
	at clojure.lang.RestFn.invoke(RestFn.java:397)
	at metabase.sync.util$with_start_and_finish_logging_STAR_.invokeStatic(util.clj:99)
	at metabase.sync.util$with_start_and_finish_logging_STAR_.invoke(util.clj:93)
	at metabase.sync.util$with_start_and_finish_debug_logging.invokeStatic(util.clj:116)
	at metabase.sync.util$with_start_and_finish_debug_logging.invoke(util.clj:113)
	at metabase.sync.util$fn__40096$run_step_with_metadata__40101$fn__40105.invoke(util.clj:355)
	at metabase.sync.util$fn__40096$run_step_with_metadata__40101.invoke(util.clj:350)
	at metabase.sync.util$fn__40287$run_sync_operation__40292$fn__40293$fn__40301.invoke(util.clj:451)
	at metabase.sync.util$fn__40287$run_sync_operation__40292$fn__40293.invoke(util.clj:449)
	at metabase.sync.util$fn__40287$run_sync_operation__40292.invoke(util.clj:443)
	at metabase.sync.analyze$fn__70077$analyze_db_BANG___70082$fn__70083$fn__70084.invoke(analyze.clj:121)
	at metabase.sync.util$do_with_error_handling.invokeStatic(util.clj:156)
	at metabase.sync.util$do_with_error_handling.invoke(util.clj:149)
	at clojure.core$partial$fn__5859.invoke(core.clj:2634)
	at metabase.driver$fn__24548.invokeStatic(driver.clj:555)
	at metabase.driver$fn__24548.invoke(driver.clj:555)
	at clojure.lang.MultiFn.invoke(MultiFn.java:239)
	at metabase.sync.util$sync_in_context$fn__40008.invoke(util.clj:135)
	at metabase.sync.util$with_db_logging_disabled$fn__40005.invoke(util.clj:126)
	at metabase.sync.util$with_start_and_finish_logging_STAR_.invokeStatic(util.clj:99)
	at metabase.sync.util$with_start_and_finish_logging_STAR_.invoke(util.clj:93)
	at metabase.sync.util$with_start_and_finish_logging$fn__39994.invoke(util.clj:111)
	at metabase.sync.util$with_sync_events$fn__39989.invoke(util.clj:85)
	at metabase.sync.util$with_duplicate_ops_prevented$fn__39980.invoke(util.clj:64)
	at metabase.sync.util$do_sync_operation.invokeStatic(util.clj:177)
	at metabase.sync.util$do_sync_operation.invoke(util.clj:174)
	at metabase.sync.analyze$fn__70077$analyze_db_BANG___70082$fn__70083.invoke(analyze.clj:118)
	at metabase.sync.analyze$fn__70077$analyze_db_BANG___70082.invoke(analyze.clj:113)
	at metabase.api.database$fn__77226$fn__77228.invoke(database.clj:653)
	at clojure.core$binding_conveyor_fn$fn__5772.invoke(core.clj:2034)
	at clojure.lang.AFn.call(AFn.java:18)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.NullPointerException
	at metabase.driver.exasol$fn__632$fn__633.invoke(exasol.clj:84)
	at clojure.core$juxt$fn__5844$fn__5845.invoke(core.clj:2612)
	at clojure.lang.ArrayChunk.reduce(ArrayChunk.java:63)
	at clojure.core$reduce1.invokeStatic(core.clj:944)
	at clojure.core$juxt$fn__5844.invoke(core.clj:2611)
	at metabase.driver.sql_jdbc.execute$row_thunk$row_thunk_STAR___52477.invoke(execute.clj:458)
	at metabase.query_processor.reducible$reducible_rows$reify__42516.reduce(reducible.clj:158)
	at clojure.core$transduce.invokeStatic(core.clj:6885)
	at clojure.core$transduce.invokeStatic(core.clj:6881)
	at clojure.core$transduce.invoke(core.clj:6872)
	at metabase.query_processor.context.default$default_reducef$fn__42412.invoke(default.clj:58)
	... 142 more

Download JDBC driver from Maven Central

Situation

We started publishing the Exasol JDBC driver on Maven Central. It should soon be available there. The connector should in future use the driver from Maven Central.

Acceptance Criteria

  • Use JDBC driver from Maven Central

Implement reading JDBC driver version via Reflection

During implementation of #41 / #42 the function to log the Exasol JDBC driver version was lost.
Due to dependency issues we can't have a compile time dependency on the JDBC driver, instead we need to use reflection.

AC

  • The driver gets the JDBC driver version via reflection
  • Failures (e.g. missing driver on classpath) are handled gracefully without throwing an exception

See also #40

Re-activate flaky Metabase test

Test metabase.api.session-test/failure-threshold-per-request-source fails sporadically due to a timing issue.
As this test is not related with Exasol we have deactivated the test. As soon as Metabase fixes this we can re-activate the test.

 FAIL in metabase.api.session-test/failure-threshold-per-request-source (session_test.clj:182)
The same as above, but ensure that throttling is done on a per request source basis.
expected: #"^Too many attempts! You must wait 1\d seconds before trying again\.$"
  actual: "Too many attempts! You must wait 9 seconds before trying again."
FAIL in metabase.api.notify-test/post-db-id-test (notify_test.clj:62)

:exasol full db sync by default
expected: (clojure.core/deref full-sync?)
  actual: (not (clojure.core/deref #<Atom@3fc4271b true>))

See discussion at https://discourse.metabase.com/t/sporadically-failing-metabase-tests/18408

Fix date dependent tests by upgrading to new Metabase release

Some Metabase tests depend on the current date. If the year changes, they fail.
Metabase already fixed the tests on master branch. Once a new release of Metabase is available (see https://github.com/metabase/metabase/releases), reactivate the following tests:

FAIL in metabase.query-processor-test.implicit-joins-test/implicit-joins-with-expressions-test (implicit_joins_test.clj:145)

:exasol Should be able to run query with multiple implicit joins and breakouts using sample-dataset dataset
expected: [["Doohickey" "Facebook" "2019-01-01T00:00:00Z" 0 263]
           ["Doohickey" "Facebook" "2020-01-01T00:00:00Z" 0 89]
           ["Doohickey" "Google" "2019-01-01T00:00:00Z" 0 276]
           ["Doohickey" "Google" "2020-01-01T00:00:00Z" 0 100]
           ["Gizmo" "Facebook" "2019-01-01T00:00:00Z" 0 361]]
  actual: ([["Doohickey" "Facebook" "2020-01-01T00:00:00Z" 0 89]
            ["Doohickey" "Google" "2020-01-01T00:00:00Z" 0 100]
            ["Gizmo" "Facebook" "2020-01-01T00:00:00Z" 0 113]
            ["Gizmo" "Google" "2020-01-01T00:00:00Z" 0 101]])
FAIL in metabase.query-processor.pivot-test/dont-return-too-many-rows-test (pivot_test.clj:167)
Make sure pivot queries don't return too many rows (#14329)
expected: [["Doohickey" "Facebook" "2019-01-01T00:00:00Z" 0 263]
           ["Doohickey" "Facebook" "2020-01-01T00:00:00Z" 0 89]
           ["Doohickey" "Google" "2019-01-01T00:00:00Z" 0 276]
           ["Doohickey" "Google" "2020-01-01T00:00:00Z" 0 100]
           ["Gizmo" "Facebook" "2019-01-01T00:00:00Z" 0 361]
           ["Gizmo" "Facebook" "2020-01-01T00:00:00Z" 0 113]
           ["Gizmo" "Google" "2019-01-01T00:00:00Z" 0 325]
           ["Gizmo" "Google" "2020-01-01T00:00:00Z" 0 101]
           ["Doohickey" "Facebook" nil 4 352]
           ["Doohickey" "Google" nil 4 376]
           ["Gizmo" "Facebook" nil 4 474]
           ["Gizmo" "Google" nil 4 426]
           ["Doohickey" nil nil 6 728]
           ["Gizmo" nil nil 6 900]
           [nil nil nil 7 1628]]
  actual: ([["Doohickey" "Facebook" "2020-01-01T00:00:00Z" 0 89]
            ["Doohickey" "Google" "2020-01-01T00:00:00Z" 0 100]
            ["Gizmo" "Facebook" "2020-01-01T00:00:00Z" 0 113]
            ["Gizmo" "Google" "2020-01-01T00:00:00Z" 0 101]
            ("Doohickey" "Facebook" nil 4 89)
            ("Doohickey" "Google" nil 4 100)
            ("Gizmo" "Facebook" nil 4 113)
            ("Gizmo" "Google" nil 4 101)
            ("Doohickey" nil nil 6 189)
            ("Gizmo" nil nil 6 214)
            (nil nil nil 7 403)])

Migrate build to tools.deps

In order to allow the Metabase team to include this driver into Metabase we need to migrate the build from Leinigen to tools.deps.

See https://github.com/metabase/metabase/wiki/Migrating-from-Leiningen-to-tools.deps for details.

Example projects:

Build must work with clojure -X:dev:build, tests must work according to this process.

Replace deprecated `connection-with-timezone` function

Metabase logs the following warning when using the Exasol driver:

sql-jdbc.execute :: metabase.driver.sql-jdbc.execute/connection-with-timezone is deprecated in Metabase 0.47.0. Implement metabase.driver.sql-jdbc.execute/do-with-connection-with-options instead.

To be future proof we need to replace connection-with-timezone with the appropriate alternative.

Add driver version to log output and client info

For debugging issues it is helpful to know the exact driver version. That's why we should write the driver version to the log and also use it in the client info when connecting to the database.

Allow SSH tunnel connection

By setting connection-properties-include-tunnel-config in the manifest to true, Metabase will automatically allow connecting to Exasol via an SSH tunnel.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.