Giter VIP home page Giter VIP logo

metabase-cubejs-driver's People

Contributors

igorpojzl avatar pyrooka avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar

metabase-cubejs-driver's Issues

Metabase generates wrong dateformat for timedimension

Describe the bug
Metabase 35.3 generates date range as the first ms from stardate and next period first ms.
IMHO time dimension and preaggregation rules are not applied properly.

{ "measures" : [ "Quotefacts.count" ], "dimensions" : [ "Quotefacts.salesrep" ], "timeDimensions" : [ { "dimension" : "Quotefacts.datequoted", "dateRange" : [ "2020-04-01T00:00:00+02:00", "2020-05-01T00:00:00+02:00" ] } ], "filters" : [ ], "order" : { "Quotefacts.count" : "desc", "Quotefacts.salesrep" : "asc" } }

Expected behavior
According to cubejs documentation ( updated to v 0.19.13) Metabase must follow the next rules:

Time dimension together with granularity constitute dimension. If date range isn't aligned with granularity common granularity is used. To match granularity date range should match it's start and end. For example for month it's ['2020-01-01T00:00:00.000', '2020-01-31T23:59:59.999'] and for day it's ['2020-01-01T00:00:00.000', '2020-01-01T23:59:59.999']. Date ranges are inclusive. Minimum granularity is second.

Version:
[v0.12.0]

Relative Date Conversios/Inheritance for Query Builder

Use Case. Let say I have field dateordered. I select “orderfacts” table - open in query builder, group by dateordered then select Month of year. Error “month-of-year granularity not supported by Cube.js”.

Test Result: Fall - any of relative driver doesn't works, not implemented yet.

quarter-groupby-date

  • not the best screenshot because here quarter make error, however same just when select e.g Month of Year, then i'm getting "month-of-year granularity not supported by Cube.js"

**I have asked @paveltiunov slack chat **

As a rule of a thumb formatting is usually client side problem. probably related topic: cube-js/cube#177

As get help I made a forum thread in Metabase forum
https://discourse.metabase.com/t/month-of-year-api-for-driver-implementation/9102

The Question: ATM we can’t find way how to convert datefield to relative date formats in metabase driver. (postgres can do this by “commands” Mon, NM, dy, DD, WW…etc. ). We are looking for example code, how to improve the cubejs driver or API doc for handling relative date in driver. (convert/inherit relative dates from a simpe datetime field.) - avoid generate unnecessary fake dimensions.

Sync Database Schema Now break Data Model

Issue: Sync Database Schema Now break Data Model

Steps to reproduce:

  1. Install latest driver 0.4
  2. start metabase server
  3. add cubejs driver including token (cube.js in mode=production)
  4. open Admin=>Database>Click to database name
  5. run Sync Database Schema Now

Related to: String to number error #13

LOG:
`11-14 18:28:09 ERROR sync.util :: Error generating fingerprint for Field 43 'Orders.count': java.lang.String cannot be cast to java.lang.Number
("clojure.lang.RT.doubleCast(RT.java:1355)"
"bigml.histogram.core$when_double.invokeStatic(core.clj:104)"
"bigml.histogram.core$when_double.invoke(core.clj:103)"
"bigml.histogram.core$insert_simple_BANG_.invokeStatic(core.clj:109)"
"bigml.histogram.core$insert_simple_BANG_.invoke(core.clj:106)"
"--> sync.analyze.fingerprint.fingerprinters$histogram.invokeStatic(fingerprinters.clj:180)"
"sync.analyze.fingerprint.fingerprinters$histogram.invoke(fingerprinters.clj:176)"
"sync.analyze.fingerprint.fingerprinters$with_error_handling$fn__43527$fn__43532.invoke(fingerprinters.clj:117)"
"sync.util$do_with_error_handling.invokeStatic(util.clj:149)"
"sync.util$do_with_error_handling.invoke(util.clj:144)"
"sync.analyze.fingerprint.fingerprinters$with_error_handling$fn__43527.invoke(fingerprinters.clj:117)"
"sync.analyze.fingerprint.fingerprinters$col_wise$fn__43490$fn__43495.invoke(fingerprinters.clj:32)"
"sync.analyze.fingerprint.fingerprinters$col_wise$fn__43490.invoke(fingerprinters.clj:29)"
"sync.analyze.fingerprint$fn__48979$fingerprint_table_BANG___48984$fn__48985.invoke(fingerprint.clj:42)"
"sync.analyze.fingerprint$fn__48979$fingerprint_table_BANG___48984.invoke(fingerprint.clj:40)"
"sync.analyze.fingerprint$fn__49152$fingerprint_fields_BANG___49157$fn__49158.invoke(fingerprint.clj:161)"
"sync.analyze.fingerprint$fn__49152$fingerprint_fields_BANG___49157.invoke(fingerprint.clj:157)"
"sync.analyze.fingerprint$fn__49178$fingerprint_fields_for_db_BANG___49183$fn__49184$fn__49185$iter__49186__49190$fn__49191$fn__49192.invoke(fingerprint.clj:171)"
"sync.analyze.fingerprint$fn__49178$fingerprint_fields_for_db_BANG___49183$fn__49184$fn__49185$iter__49186__49190$fn__49191.invoke(fingerprint.clj:170)"
"sync.analyze.fingerprint$fn__49178$fingerprint_fields_for_db_BANG___49183$fn__49184$fn__49185.invoke(fingerprint.clj:170)"
"util.date$call_with_effective_timezone.invokeStatic(date.clj:88)"
"util.date$call_with_effective_timezone.invoke(date.clj:77)"
"sync.analyze.fingerprint$fn__49178$fingerprint_fields_for_db_BANG___49183$fn__49184.invoke(fingerprint.clj:169)"
"sync.analyze.fingerprint$fn__49178$fingerprint_fields_for_db_BANG___49183.invoke(fingerprint.clj:164)"
"sync.analyze$make_analyze_steps$fn__49324.invoke(analyze.clj:110)"
"sync.util$fn__41410$run_step_with_metadata__41415$fn__41419$fn__41421.invoke(util.clj:356)"
"sync.util$with_start_and_finish_logging_STAR_.invokeStatic(util.clj:104)"
"sync.util$with_start_and_finish_logging_STAR_.invoke(util.clj:98)"
"sync.util$with_start_and_finish_debug_logging.invokeStatic(util.clj:121)"
"sync.util$with_start_and_finish_debug_logging.invoke(util.clj:118)"
"sync.util$fn__41410$run_step_with_metadata__41415$fn__41419.invoke(util.clj:353)"
"sync.util$fn__41410$run_step_with_metadata__41415.invoke(util.clj:348)"
"sync.util$fn__41602$run_sync_operation__41607$fn__41608$fn__41609.invoke(util.clj:441)"
"sync.util$fn__41602$run_sync_operation__41607$fn__41608.invoke(util.clj:441)"
"sync.util$fn__41602$run_sync_operation__41607.invoke(util.clj:435)"
"sync.analyze$fn__49336$analyze_db_BANG___49341$fn__49342$fn__49343.invoke(analyze.clj:127)"
"sync.util$do_with_error_handling.invokeStatic(util.clj:149)"
"sync.util$do_with_error_handling.invoke(util.clj:144)"
"sync.util$do_with_error_handling.invokeStatic(util.clj:147)"
"sync.util$do_with_error_handling.invoke(util.clj:144)"
"driver$fn__19284.invokeStatic(driver.clj:673)"
"driver$fn__19284.invoke(driver.clj:673)"
"sync.util$sync_in_context$fn__41316.invoke(util.clj:140)"
"sync.util$with_db_logging_disabled$fn__41313.invoke(util.clj:131)"
"sync.util$with_start_and_finish_logging_STAR_.invokeStatic(util.clj:104)"
"sync.util$with_start_and_finish_logging_STAR_.invoke(util.clj:98)"
"sync.util$with_start_and_finish_logging$fn__41302.invoke(util.clj:116)"
"sync.util$with_sync_events$fn__41297.invoke(util.clj:90)"
"sync.util$with_duplicate_ops_prevented$fn__41288.invoke(util.clj:69)"
"sync.util$do_sync_operation.invokeStatic(util.clj:168)"
"sync.util$do_sync_operation.invoke(util.clj:165)"
"sync.analyze$fn__49336$analyze_db_BANG___49341$fn__49342.invoke(analyze.clj:124)"
"sync.analyze$fn__49336$analyze_db_BANG___49341.invoke(analyze.clj:119)"
"api.database$fn__51765$fn__51767.invoke(database.clj:522)")

11-14 18:28:09 ERROR sync.util :: Error generating fingerprint for Field 45 'Orders.totalAmount': java.lang.String cannot be cast to java.lang.Number
("clojure.lang.RT.doubleCast(RT.java:1355)"
"bigml.histogram.core$when_double.invokeStatic(core.clj:104)"
"bigml.histogram.core$when_double.invoke(core.clj:103)"
"bigml.histogram.core$insert_simple_BANG_.invokeStatic(core.clj:109)"
"bigml.histogram.core$insert_simple_BANG_.invoke(core.clj:106)"
"--> sync.analyze.fingerprint.fingerprinters$histogram.invokeStatic(fingerprinters.clj:180)"
"sync.analyze.fingerprint.fingerprinters$histogram.invoke(fingerprinters.clj:176)"
"sync.analyze.fingerprint.fingerprinters$with_error_handling$fn__43527$fn__43532.invoke(fingerprinters.clj:117)"
"sync.util$do_with_error_handling.invokeStatic(util.clj:149)"
"sync.util$do_with_error_handling.invoke(util.clj:144)"
"sync.analyze.fingerprint.fingerprinters$with_error_handling$fn__43527.invoke(fingerprinters.clj:117)"
"sync.analyze.fingerprint.fingerprinters$col_wise$fn__43490$fn__43495.invoke(fingerprinters.clj:32)"
"sync.analyze.fingerprint.fingerprinters$col_wise$fn__43490.invoke(fingerprinters.clj:29)"
"sync.analyze.fingerprint$fn__48979$fingerprint_table_BANG___48984$fn__48985.invoke(fingerprint.clj:42)"
"sync.analyze.fingerprint$fn__48979$fingerprint_table_BANG___48984.invoke(fingerprint.clj:40)"
"sync.analyze.fingerprint$fn__49152$fingerprint_fields_BANG___49157$fn__49158.invoke(fingerprint.clj:161)"
"sync.analyze.fingerprint$fn__49152$fingerprint_fields_BANG___49157.invoke(fingerprint.clj:157)"
"sync.analyze.fingerprint$fn__49178$fingerprint_fields_for_db_BANG___49183$fn__49184$fn__49185$iter__49186__49190$fn__49191$fn__49192.invoke(fingerprint.clj:171)"
"sync.analyze.fingerprint$fn__49178$fingerprint_fields_for_db_BANG___49183$fn__49184$fn__49185$iter__49186__49190$fn__49191.invoke(fingerprint.clj:170)"
"sync.analyze.fingerprint$fn__49178$fingerprint_fields_for_db_BANG___49183$fn__49184$fn__49185.invoke(fingerprint.clj:170)"
"util.date$call_with_effective_timezone.invokeStatic(date.clj:88)"
"util.date$call_with_effective_timezone.invoke(date.clj:77)"
"sync.analyze.fingerprint$fn__49178$fingerprint_fields_for_db_BANG___49183$fn__49184.invoke(fingerprint.clj:169)"
"sync.analyze.fingerprint$fn__49178$fingerprint_fields_for_db_BANG___49183.invoke(fingerprint.clj:164)"
"sync.analyze$make_analyze_steps$fn__49324.invoke(analyze.clj:110)"
"sync.util$fn__41410$run_step_with_metadata__41415$fn__41419$fn__41421.invoke(util.clj:356)"
"sync.util$with_start_and_finish_logging_STAR_.invokeStatic(util.clj:104)"
"sync.util$with_start_and_finish_logging_STAR_.invoke(util.clj:98)"
"sync.util$with_start_and_finish_debug_logging.invokeStatic(util.clj:121)"
"sync.util$with_start_and_finish_debug_logging.invoke(util.clj:118)"
"sync.util$fn__41410$run_step_with_metadata__41415$fn__41419.invoke(util.clj:353)"
"sync.util$fn__41410$run_step_with_metadata__41415.invoke(util.clj:348)"
"sync.util$fn__41602$run_sync_operation__41607$fn__41608$fn__41609.invoke(util.clj:441)"
"sync.util$fn__41602$run_sync_operation__41607$fn__41608.invoke(util.clj:441)"
"sync.util$fn__41602$run_sync_operation__41607.invoke(util.clj:435)"
"sync.analyze$fn__49336$analyze_db_BANG___49341$fn__49342$fn__49343.invoke(analyze.clj:127)"
"sync.util$do_with_error_handling.invokeStatic(util.clj:149)"
"sync.util$do_with_error_handling.invoke(util.clj:144)"
"sync.util$do_with_error_handling.invokeStatic(util.clj:147)"
"sync.util$do_with_error_handling.invoke(util.clj:144)"
"driver$fn__19284.invokeStatic(driver.clj:673)"
"driver$fn__19284.invoke(driver.clj:673)"
"sync.util$sync_in_context$fn__41316.invoke(util.clj:140)"
"sync.util$with_db_logging_disabled$fn__41313.invoke(util.clj:131)"
"sync.util$with_start_and_finish_logging_STAR_.invokeStatic(util.clj:104)"
"sync.util$with_start_and_finish_logging_STAR_.invoke(util.clj:98)"
"sync.util$with_start_and_finish_logging$fn__41302.invoke(util.clj:116)"
"sync.util$with_sync_events$fn__41297.invoke(util.clj:90)"
"sync.util$with_duplicate_ops_prevented$fn__41288.invoke(util.clj:69)"
"sync.util$do_sync_operation.invokeStatic(util.clj:168)"
"sync.util$do_sync_operation.invoke(util.clj:165)"
"sync.analyze$fn__49336$analyze_db_BANG___49341$fn__49342.invoke(analyze.clj:124)"
"sync.analyze$fn__49336$analyze_db_BANG___49341.invoke(analyze.clj:119)"
"api.database$fn__51765$fn__51767.invoke(database.clj:522)")`

Store field information in the description as a JSON

At the moment all the field information stored as a simple text in the description fields. Also, we use the field and metric names for the Cube.js query, hence they are sensitive to renaming.

Proposal:
Save every piece of information into a JSON. This is more futureproof and easier to extend.

Fix building with newer Metabase

At the moment we are building the driver with Metabase version 0.33.2. The build failing with newer versions. Here are the logs with v0.33.6:

Compiling metabase.driver.cubejs
12-11 08:41:47 DEBUG plugins.classloader :: Using NEWLY CREATED classloader as shared context classloader: clojure.lang.DynamicClassLoader@59942b48
12-11 08:41:47 DEBUG plugins.classloader :: Setting current thread context classloader to shared classloader clojure.lang.DynamicClassLoader@59942b48...
java.lang.NoSuchFieldError: REQUIRE_LOCK, compiling:(cubejs.clj:1:1)
Exception in thread "main" java.lang.NoSuchFieldError: REQUIRE_LOCK, compiling:(cubejs.clj:1:1)
	at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3700)
	at clojure.lang.Compiler.compile1(Compiler.java:7609)
	at clojure.lang.Compiler.compile1(Compiler.java:7599)
	at clojure.lang.Compiler.compile(Compiler.java:7676)
	at clojure.lang.RT.compile(RT.java:413)
	at clojure.lang.RT.load(RT.java:458)
	at clojure.lang.RT.load(RT.java:426)
	at clojure.core$load$fn__6548.invoke(core.clj:6046)
	at clojure.core$load.invokeStatic(core.clj:6045)
	at clojure.core$load.doInvoke(core.clj:6029)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5848)
	at clojure.core$compile$fn__6553.invoke(core.clj:6056)
	at clojure.core$compile.invokeStatic(core.clj:6056)
	at clojure.core$compile.invoke(core.clj:6048)
	at user$eval164$fn__173.invoke(form-init8507211335122952859.clj:1)
	at user$eval164.invokeStatic(form-init8507211335122952859.clj:1)
	at user$eval164.invoke(form-init8507211335122952859.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:7062)
	at clojure.lang.Compiler.eval(Compiler.java:7052)
	at clojure.lang.Compiler.eval(Compiler.java:7052)
	at clojure.lang.Compiler.load(Compiler.java:7514)
	at clojure.lang.Compiler.loadFile(Compiler.java:7452)
	at clojure.main$load_script.invokeStatic(main.clj:278)
	at clojure.main$init_opt.invokeStatic(main.clj:280)
	at clojure.main$init_opt.invoke(main.clj:280)
	at clojure.main$initialize.invokeStatic(main.clj:311)
	at clojure.main$null_opt.invokeStatic(main.clj:345)
	at clojure.main$null_opt.invoke(main.clj:342)
	at clojure.main$main.invokeStatic(main.clj:424)
	at clojure.main$main.doInvoke(main.clj:387)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.main.main(main.java:37)
Caused by: java.lang.NoSuchFieldError: REQUIRE_LOCK
	at metabase.plugins.classloader$require.invokeStatic(classloader.clj:100)
	at metabase.plugins.classloader$require.doInvoke(classloader.clj:89)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at metabase.pulse.render.table__init.load(Unknown Source)
	at metabase.pulse.render.table__init.<clinit>(Unknown Source)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at clojure.lang.RT.classForName(RT.java:2204)
	at clojure.lang.RT.classForName(RT.java:2213)
	at clojure.lang.RT.loadClassForName(RT.java:2232)
	at clojure.lang.RT.load(RT.java:450)
	at clojure.lang.RT.load(RT.java:426)
	at clojure.core$load$fn__6548.invoke(core.clj:6046)
	at clojure.core$load.invokeStatic(core.clj:6045)
	at clojure.core$load.doInvoke(core.clj:6029)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5848)
	at clojure.core$load_one.invoke(core.clj:5843)
	at clojure.core$load_lib$fn__6493.invoke(core.clj:5888)
	at clojure.core$load_lib.invokeStatic(core.clj:5887)
	at clojure.core$load_lib.doInvoke(core.clj:5868)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$load_libs.invokeStatic(core.clj:5929)
	at clojure.core$load_libs.doInvoke(core.clj:5909)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$require.invokeStatic(core.clj:5947)
	at clojure.core$require.doInvoke(core.clj:5947)
	at clojure.lang.RestFn.invoke(RestFn.java:482)
	at metabase.pulse.render.body$loading__6721__auto____31117.invoke(body.clj:1)
	at metabase.pulse.render.body__init.load(Unknown Source)
	at metabase.pulse.render.body__init.<clinit>(Unknown Source)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at clojure.lang.RT.classForName(RT.java:2204)
	at clojure.lang.RT.classForName(RT.java:2213)
	at clojure.lang.RT.loadClassForName(RT.java:2232)
	at clojure.lang.RT.load(RT.java:450)
	at clojure.lang.RT.load(RT.java:426)
	at clojure.core$load$fn__6548.invoke(core.clj:6046)
	at clojure.core$load.invokeStatic(core.clj:6045)
	at clojure.core$load.doInvoke(core.clj:6029)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5848)
	at clojure.core$load_one.invoke(core.clj:5843)
	at clojure.core$load_lib$fn__6493.invoke(core.clj:5888)
	at clojure.core$load_lib.invokeStatic(core.clj:5887)
	at clojure.core$load_lib.doInvoke(core.clj:5868)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$load_libs.invokeStatic(core.clj:5929)
	at clojure.core$load_libs.doInvoke(core.clj:5909)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$require.invokeStatic(core.clj:5947)
	at clojure.core$require.doInvoke(core.clj:5947)
	at clojure.lang.RestFn.invoke(RestFn.java:512)
	at metabase.pulse.render$loading__6721__auto____31115.invoke(render.clj:1)
	at metabase.pulse.render__init.load(Unknown Source)
	at metabase.pulse.render__init.<clinit>(Unknown Source)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at clojure.lang.RT.classForName(RT.java:2204)
	at clojure.lang.RT.classForName(RT.java:2213)
	at clojure.lang.RT.loadClassForName(RT.java:2232)
	at clojure.lang.RT.load(RT.java:450)
	at clojure.lang.RT.load(RT.java:426)
	at clojure.core$load$fn__6548.invoke(core.clj:6046)
	at clojure.core$load.invokeStatic(core.clj:6045)
	at clojure.core$load.doInvoke(core.clj:6029)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5848)
	at clojure.core$load_one.invoke(core.clj:5843)
	at clojure.core$load_lib$fn__6493.invoke(core.clj:5888)
	at clojure.core$load_lib.invokeStatic(core.clj:5887)
	at clojure.core$load_lib.doInvoke(core.clj:5868)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$load_libs.invokeStatic(core.clj:5925)
	at clojure.core$load_libs.doInvoke(core.clj:5909)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$require.invokeStatic(core.clj:5947)
	at clojure.core$require.doInvoke(core.clj:5947)
	at clojure.lang.RestFn.invoke(RestFn.java:930)
	at metabase.email.messages$loading__6721__auto____30485.invoke(messages.clj:1)
	at metabase.email.messages__init.load(Unknown Source)
	at metabase.email.messages__init.<clinit>(Unknown Source)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at clojure.lang.RT.classForName(RT.java:2204)
	at clojure.lang.RT.classForName(RT.java:2213)
	at clojure.lang.RT.loadClassForName(RT.java:2232)
	at clojure.lang.RT.load(RT.java:450)
	at clojure.lang.RT.load(RT.java:426)
	at clojure.core$load$fn__6548.invoke(core.clj:6046)
	at clojure.core$load.invokeStatic(core.clj:6045)
	at clojure.core$load.doInvoke(core.clj:6029)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5848)
	at clojure.core$load_one.invoke(core.clj:5843)
	at clojure.core$load_lib$fn__6493.invoke(core.clj:5888)
	at clojure.core$load_lib.invokeStatic(core.clj:5887)
	at clojure.core$load_lib.doInvoke(core.clj:5868)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$load_libs.invokeStatic(core.clj:5925)
	at clojure.core$load_libs.doInvoke(core.clj:5909)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$require.invokeStatic(core.clj:5947)
	at clojure.core$require.doInvoke(core.clj:5947)
	at clojure.lang.RestFn.invoke(RestFn.java:703)
	at metabase.models.user$loading__6721__auto____30483.invoke(user.clj:1)
	at metabase.models.user__init.load(Unknown Source)
	at metabase.models.user__init.<clinit>(Unknown Source)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at clojure.lang.RT.classForName(RT.java:2204)
	at clojure.lang.RT.classForName(RT.java:2213)
	at clojure.lang.RT.loadClassForName(RT.java:2232)
	at clojure.lang.RT.load(RT.java:450)
	at clojure.lang.RT.load(RT.java:426)
	at clojure.core$load$fn__6548.invoke(core.clj:6046)
	at clojure.core$load.invokeStatic(core.clj:6045)
	at clojure.core$load.doInvoke(core.clj:6029)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5848)
	at clojure.core$load_one.invoke(core.clj:5843)
	at clojure.core$load_lib$fn__6493.invoke(core.clj:5888)
	at clojure.core$load_lib.invokeStatic(core.clj:5887)
	at clojure.core$load_lib.doInvoke(core.clj:5868)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$load_libs.invokeStatic(core.clj:5925)
	at clojure.core$load_libs.doInvoke(core.clj:5909)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$require.invokeStatic(core.clj:5947)
	at clojure.core$require.doInvoke(core.clj:5947)
	at clojure.lang.RestFn.invoke(RestFn.java:551)
	at metabase.models.revision$loading__6721__auto____30431.invoke(revision.clj:1)
	at metabase.models.revision__init.load(Unknown Source)
	at metabase.models.revision__init.<clinit>(Unknown Source)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at clojure.lang.RT.classForName(RT.java:2204)
	at clojure.lang.RT.classForName(RT.java:2213)
	at clojure.lang.RT.loadClassForName(RT.java:2232)
	at clojure.lang.RT.load(RT.java:450)
	at clojure.lang.RT.load(RT.java:426)
	at clojure.core$load$fn__6548.invoke(core.clj:6046)
	at clojure.core$load.invokeStatic(core.clj:6045)
	at clojure.core$load.doInvoke(core.clj:6029)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5848)
	at clojure.core$load_one.invoke(core.clj:5843)
	at clojure.core$load_lib$fn__6493.invoke(core.clj:5888)
	at clojure.core$load_lib.invokeStatic(core.clj:5887)
	at clojure.core$load_lib.doInvoke(core.clj:5868)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$load_libs.invokeStatic(core.clj:5929)
	at clojure.core$load_libs.doInvoke(core.clj:5909)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$require.invokeStatic(core.clj:5947)
	at clojure.core$require.doInvoke(core.clj:5947)
	at clojure.lang.RestFn.invoke(RestFn.java:551)
	at metabase.models.metric$loading__6721__auto____35609.invoke(metric.clj:1)
	at metabase.models.metric__init.load(Unknown Source)
	at metabase.models.metric__init.<clinit>(Unknown Source)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at clojure.lang.RT.classForName(RT.java:2204)
	at clojure.lang.RT.classForName(RT.java:2213)
	at clojure.lang.RT.loadClassForName(RT.java:2232)
	at clojure.lang.RT.load(RT.java:450)
	at clojure.lang.RT.load(RT.java:426)
	at clojure.core$load$fn__6548.invoke(core.clj:6046)
	at clojure.core$load.invokeStatic(core.clj:6045)
	at clojure.core$load.doInvoke(core.clj:6029)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5848)
	at clojure.core$load_one.invoke(core.clj:5843)
	at clojure.core$load_lib$fn__6493.invoke(core.clj:5888)
	at clojure.core$load_lib.invokeStatic(core.clj:5887)
	at clojure.core$load_lib.doInvoke(core.clj:5868)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$load_libs.invokeStatic(core.clj:5929)
	at clojure.core$load_libs.doInvoke(core.clj:5909)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$require.invokeStatic(core.clj:5947)
	at clojure.core$require.doInvoke(core.clj:5947)
	at clojure.lang.RestFn.invoke(RestFn.java:436)
	at metabase.models.table$loading__6721__auto____35245.invoke(table.clj:1)
	at metabase.models.table__init.load(Unknown Source)
	at metabase.models.table__init.<clinit>(Unknown Source)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at clojure.lang.RT.classForName(RT.java:2204)
	at clojure.lang.RT.classForName(RT.java:2213)
	at clojure.lang.RT.loadClassForName(RT.java:2232)
	at clojure.lang.RT.load(RT.java:450)
	at clojure.lang.RT.load(RT.java:426)
	at clojure.core$load$fn__6548.invoke(core.clj:6046)
	at clojure.core$load.invokeStatic(core.clj:6045)
	at clojure.core$load.doInvoke(core.clj:6029)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5848)
	at clojure.core$load_one.invoke(core.clj:5843)
	at clojure.core$load_lib$fn__6493.invoke(core.clj:5888)
	at clojure.core$load_lib.invokeStatic(core.clj:5887)
	at clojure.core$load_lib.doInvoke(core.clj:5868)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$load_libs.invokeStatic(core.clj:5929)
	at clojure.core$load_libs.doInvoke(core.clj:5909)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$require.invokeStatic(core.clj:5947)
	at clojure.core$require.doInvoke(core.clj:5947)
	at clojure.lang.RestFn.invoke(RestFn.java:482)
	at metabase.query_processor.store$loading__6721__auto____37302.invoke(store.clj:1)
	at metabase.query_processor.store__init.load(Unknown Source)
	at metabase.query_processor.store__init.<clinit>(Unknown Source)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at clojure.lang.RT.classForName(RT.java:2204)
	at clojure.lang.RT.classForName(RT.java:2213)
	at clojure.lang.RT.loadClassForName(RT.java:2232)
	at clojure.lang.RT.load(RT.java:450)
	at clojure.lang.RT.load(RT.java:426)
	at clojure.core$load$fn__6548.invoke(core.clj:6046)
	at clojure.core$load.invokeStatic(core.clj:6045)
	at clojure.core$load.doInvoke(core.clj:6029)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5848)
	at clojure.core$load_one.invoke(core.clj:5843)
	at clojure.core$load_lib$fn__6493.invoke(core.clj:5888)
	at clojure.core$load_lib.invokeStatic(core.clj:5887)
	at clojure.core$load_lib.doInvoke(core.clj:5868)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$load_libs.invokeStatic(core.clj:5925)
	at clojure.core$load_libs.doInvoke(core.clj:5909)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$require.invokeStatic(core.clj:5947)
	at clojure.core$require.doInvoke(core.clj:5947)
	at clojure.lang.RestFn.invoke(RestFn.java:619)
	at metabase.driver.cubejs$loading__6434__auto____180.invoke(cubejs.clj:1)
	at clojure.lang.AFn.applyToHelper(AFn.java:152)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3695)
	... 33 more
Compilation failed: Subprocess failed                                                                                                                            

Authentication to CubeJS production server

Hi,

this project looks me promising, thanks.
i can't find how can i setup authentication for cube.js server in metabase client.

Norbert
i would like to help test this project...assign me task if affordable.

Native query bug

Describe the bug
When I use the native question it shows


Input to deduplicate-cols-names does not match schema: �[0;33m
 [(named [{:base_type missing-required-key, :field_ref (named [nil nil
 (named (not ("Valid field type" nil)) "field-type")]
 "Must be a valid instance of one of these clauses: :field-id, :field-literal, :joined-field, 
:fk->, :datetime-field, :expression, :binning-strategy")}] cols)] �[0m

My query is copied from the custom question that already worked.
I tried another simple query but still don't work

Version:
0.13.1
Cubejs Version: 0.20.0
Metabase version 0.36.3

Distincts generate wrong query

steps to reproduce

  1. connection to cubejs eg. invoices
  2. open table invoices
  3. select the table
  4. on first column dropdown menu and select DISTINCTS <== ERROR

distincts-01

distincts-02

distincts-03

distincts-04

LOG from metabaseserver
`11-25 14:36:56 DEBUG middleware.log :: POST /api/dataset 200 [ASYNC: completed] 2.2 s (16 DB calls) Jetty threads: 3/50 (2 idle, 0 queued) (45 total active threads) Queries in flight: 0
11-25 14:37:49 WARN middleware.process-userland-query :: Query failure {:status :failed,
:class clojure.lang.ExceptionInfo,
:error "clj-http: status 400",
:stacktrace
("slingshot.support$stack_trace.invoke(support.clj:199)"
"clj_http.client$exceptions_response.invokeStatic(client.clj:245)"
"clj_http.client$exceptions_response.invoke(client.clj:236)"
"clj_http.client$wrap_exceptions$fn__54887.invoke(client.clj:254)"
"clj_http.client$wrap_accept$fn__55090.invoke(client.clj:737)"
"clj_http.client$wrap_accept_encoding$fn__55097.invoke(client.clj:759)"
"clj_http.client$wrap_content_type$fn__55084.invoke(client.clj:720)"
"clj_http.client$wrap_form_params$fn__55183.invoke(client.clj:961)"
"clj_http.client$wrap_nested_params$fn__55204.invoke(client.clj:995)"
"clj_http.client$wrap_flatten_nested_params$fn__55213.invoke(client.clj:1019)"
"clj_http.client$wrap_method$fn__55151.invoke(client.clj:895)"
"clj_http.cookies$wrap_cookies$fn__53920.invoke(cookies.clj:131)"
"clj_http.links$wrap_links$fn__54715.invoke(links.clj:63)"
"clj_http.client$wrap_unknown_host$fn__55221.invoke(client.clj:1048)"
"--> driver.cubejs.utils$make_request.invokeStatic(utils.clj:41)"
"driver.cubejs.utils$make_request.invoke(utils.clj:32)"
"driver.cubejs.query_processor$execute_http_request.invokeStatic(query_processor.clj:38)"
"driver.cubejs.query_processor$execute_http_request.invoke(query_processor.clj:36)"
"driver.cubejs$fn__563.invokeStatic(cubejs.clj:170)"
"driver.cubejs$fn__563.invoke(cubejs.clj:169)"
"query_processor$fn__44023$execute_query__44028$fn__44029.invoke(query_processor.clj:71)"
"query_processor$fn__44023$execute_query__44028.invoke(query_processor.clj:65)"
"query_processor.middleware.mbql_to_native$mbql__GT_native$fn__34284.invoke(mbql_to_native.clj:38)"
"query_processor.middleware.annotate$result_rows_maps__GT_vectors$fn__36550.invoke(annotate.clj:541)"
"query_processor.middleware.annotate$add_column_info$fn__36456.invoke(annotate.clj:485)"
"query_processor.middleware.cumulative_aggregations$handle_cumulative_aggregations$fn__37491.invoke(cumulative_aggregations.clj:57)"
"query_processor.middleware.resolve_joins$resolve_joins$fn__41131.invoke(resolve_joins.clj:184)"
"query_processor.middleware.limit$limit$fn__38092.invoke(limit.clj:19)"
"query_processor.middleware.results_metadata$record_and_return_metadata_BANG_$fn__43890.invoke(results_metadata.clj:87)"
"query_processor.middleware.format_rows$format_rows$fn__38080.invoke(format_rows.clj:26)"
"query_processor.middleware.add_dimension_projections$add_remapping$fn__35043.invoke(add_dimension_projections.clj:234)"
"query_processor.middleware.add_source_metadata$add_source_metadata_for_source_queries$fn__35684.invoke(add_source_metadata.clj:107)"
"query_processor.middleware.resolve_source_table$resolve_source_tables$fn__41181.invoke(resolve_source_table.clj:46)"
"query_processor.middleware.add_row_count_and_status$add_row_count_and_status$fn__35531.invoke(add_row_count_and_status.clj:16)"
"query_processor.middleware.driver_specific$process_query_in_context$fn__37567.invoke(driver_specific.clj:12)"
"query_processor.middleware.add_settings$add_settings$fn__35554.invoke(add_settings.clj:45)"
"query_processor.middleware.resolve_driver$resolve_driver$fn__40795.invoke(resolve_driver.clj:22)"
"query_processor.middleware.bind_effective_timezone$bind_effective_timezone$fn__36881$fn__36882.invoke(bind_effective_timezone.clj:9)"
"util.date$call_with_effective_timezone.invokeStatic(date.clj:88)"
"util.date$call_with_effective_timezone.invoke(date.clj:77)"
"query_processor.middleware.bind_effective_timezone$bind_effective_timezone$fn__36881.invoke(bind_effective_timezone.clj:8)"
"query_processor.middleware.store$initialize_store$fn__43915$fn__43916.invoke(store.clj:11)"
"query_processor.store$do_with_store.invokeStatic(store.clj:46)"
"query_processor.store$do_with_store.invoke(store.clj:40)"
"query_processor.middleware.store$initialize_store$fn__43915.invoke(store.clj:10)"
"query_processor.middleware.async$async__GT_sync$fn__34195.invoke(async.clj:23)"
"query_processor.middleware.async_wait$runnable$fn__36607.invoke(async_wait.clj:89)"),
:query
{:query {:source-table 1750, :aggregation [["distinct" ["field-id" 51320]]]},
:type "query",
:parameters [],
:async? true,
:middleware {:add-default-userland-constraints? true, :userland-query? true},
:info
{:executed-by 1,
:context :ad-hoc,
:card-id nil,
:nested? false,
:query-hash [-106, 16, -54, 35, -40, 77, -47, -122, -19, -12, -72, -43, -115, -95, 67, 56, -25, 36, 5, 54, -36, -17, 78, -124, -124, 107, 97, 39, 79, -24, 32, -4]},
:constraints {:max-results 10000, :max-results-bare-rows 2000}},
:preprocessed
{:constraints {:max-results 10000, :max-results-bare-rows 2000},
:type :query,
:middleware {:add-default-userland-constraints? true, :userland-query? true},
:info
{:executed-by 1,
:context :ad-hoc,
:nested? false,
:query-hash [-106, 16, -54, 35, -40, 77, -47, -122, -19, -12, -72, -43, -115, -95, 67, 56, -25, 36, 5, 54, -36, -17, 78, -124, -124, 107, 97, 39, 79, -24, 32, -4]},
:preprocessing-level 1,
:database 3,
:driver :cubejs,
:query {:source-table 1750, :aggregation [[:aggregation-options [:distinct [:field-id 51320]] {:name "count"}]]}},
:native {:query nil, :aggregation? true, :mbql? true},
:ex-data
{:object
{:cached nil,
:request-time 239,
:repeatable? false,
:protocol-version {:name "HTTP", :major 1, :minor 1},
:streaming? true,
:http-client #object[org.apache.http.impl.client.InternalHttpClient 0x5fdf8000 "org.apache.http.impl.client.InternalHttpClient@5fdf8000"],
:chunked? false,
:type :clj-http.client/unexceptional-status,
:reason-phrase "Bad Request",
:headers
{"X-Powered-By" "Express",
"Access-Control-Allow-Origin" "",
"Content-Type" "application/json; charset=utf-8",
"Content-Length" "35",
"ETag" "W/"23-RTUP5Q13NiVoMZnFul0uWEsLi5M"",
"Date" "Mon, 25 Nov 2019 13:37:48 GMT",
"Connection" "close",
"Strict-Transport-Security" "max-age=15768000"},
:orig-content-encoding nil,
:status 400,
:length 35,
:body "{"error":"query param is required"}",
:trace-redirects []},
:environment
{req
{:url "https://cubesapi.cloudempiere.com/cubejs-api/v1/load",
:headers {:authorization nil, "accept" "application/json"},
:query-params {"query" nil},
:as :json,
:request-method :get,
:flatten-nested-keys (:query-params)},
p__54882
{:cached nil,
:request-time 239,
:repeatable? false,
:protocol-version {:name "HTTP", :major 1, :minor 1},
:streaming? true,
:http-client #object[org.apache.http.impl.client.InternalHttpClient 0x5fdf8000 "org.apache.http.impl.client.InternalHttpClient@5fdf8000"],
:chunked? false,
:reason-phrase "Bad Request",
:headers
{"X-Powered-By" "Express",
"Access-Control-Allow-Origin" "
",
"Content-Type" "application/json; charset=utf-8",
"Content-Length" "35",
"ETag" "W/"23-RTUP5Q13NiVoMZnFul0uWEsLi5M"",
"Date" "Mon, 25 Nov 2019 13:37:48 GMT",
"Connection" "close",
"Strict-Transport-Security" "max-age=15768000"},
:orig-content-encoding nil,
:status 400,
:length 35,
:body "{"error":"query param is required"}",
:trace-redirects []},
map__54883
{:cached nil,
:request-time 239,
:repeatable? false,
:protocol-version {:name "HTTP", :major 1, :minor 1},
:streaming? true,
:http-client #object[org.apache.http.impl.client.InternalHttpClient 0x5fdf8000 "org.apache.http.impl.client.InternalHttpClient@5fdf8000"],
:chunked? false,
:reason-phrase "Bad Request",
:headers
{"X-Powered-By" "Express",
"Access-Control-Allow-Origin" "",
"Content-Type" "application/json; charset=utf-8",
"Content-Length" "35",
"ETag" "W/"23-RTUP5Q13NiVoMZnFul0uWEsLi5M"",
"Date" "Mon, 25 Nov 2019 13:37:48 GMT",
"Connection" "close",
"Strict-Transport-Security" "max-age=15768000"},
:orig-content-encoding nil,
:status 400,
:length 35,
:body "{"error":"query param is required"}",
:trace-redirects []},
resp
{:cached nil,
:request-time 239,
:repeatable? false,
:protocol-version {:name "HTTP", :major 1, :minor 1},
:streaming? true,
:http-client #object[org.apache.http.impl.client.InternalHttpClient 0x5fdf8000 "org.apache.http.impl.client.InternalHttpClient@5fdf8000"],
:chunked? false,
:reason-phrase "Bad Request",
:headers
{"X-Powered-By" "Express",
"Access-Control-Allow-Origin" "
",
"Content-Type" "application/json; charset=utf-8",
"Content-Length" "35",
"ETag" "W/"23-RTUP5Q13NiVoMZnFul0uWEsLi5M"",
"Date" "Mon, 25 Nov 2019 13:37:48 GMT",
"Connection" "close",
"Strict-Transport-Security" "max-age=15768000"},
:orig-content-encoding nil,
:status 400,
:length 35,
:body "{"error":"query param is required"}",
:trace-redirects []},
status 400,
data
{:cached nil,
:request-time 239,
:repeatable? false,
:protocol-version {:name "HTTP", :major 1, :minor 1},
:streaming? true,
:http-client #object[org.apache.http.impl.client.InternalHttpClient 0x5fdf8000 "org.apache.http.impl.client.InternalHttpClient@5fdf8000"],
:chunked? false,
:type :clj-http.client/unexceptional-status,
:reason-phrase "Bad Request",
:headers
{"X-Powered-By" "Express",
"Access-Control-Allow-Origin" "*",
"Content-Type" "application/json; charset=utf-8",
"Content-Length" "35",
"ETag" "W/"23-RTUP5Q13NiVoMZnFul0uWEsLi5M"",
"Date" "Mon, 25 Nov 2019 13:37:48 GMT",
"Connection" "close",
"Strict-Transport-Security" "max-age=15768000"},
:orig-content-encoding nil,
:status 400,
:length 35,
:body "{"error":"query param is required"}",
:trace-redirects []}}}}

11-25 14:37:50 DEBUG middleware.log :: POST /api/dataset 200 [ASYNC: completed] 1.5 s (29 DB calls) Jetty threads: 3/50 (3 idle, 0 queued) (43 total active threads) Queries in flight: 0`

Implement driver connection check

Currently, we are always pretending the Cube.js "backend" is online and available. We should implement the driver method properly to make a connection check (e.g. a simple HTTP GET).

Cache fields

What if we cache the fields for example in a map (field-id: field)? Is this a good idea? This should reduce unnecessary DB calls. Refresh when describe-table called?

Broken negating filters when used two or more for the same field

Describe the bug
When using is not filter for the same field with two or more values it will broke the native query generation.

To Reproduce
Use two or more is not filter for the same field.

Expected behavior
Exclude all the negated value from the result.

Screenshots
image

Version:
v0.10.0

Additional context

metabase_1  | 04-01 11:02:58 WARN middleware.process-userland-query :: Query failure {:status :failed,
metabase_1  |  :class java.lang.IllegalArgumentException,
metabase_1  |  :error "No matching clause: notEquals",
metabase_1  |  :stacktrace
metabase_1  |  ("--> driver.cubejs.query_processor$datetime_filter_optimizer$iter__646__650$fn__651$fn__652.invoke(query_processor.clj:224)"
metabase_1  |   "driver.cubejs.query_processor$datetime_filter_optimizer$iter__646__650$fn__651.invoke(query_processor.clj:213)"
metabase_1  |   "driver.cubejs.query_processor$datetime_filter_optimizer.invokeStatic(query_processor.clj:205)"
metabase_1  |   "driver.cubejs.query_processor$datetime_filter_optimizer.invoke(query_processor.clj:202)"
metabase_1  |   "driver.cubejs.query_processor$transform_filters.invokeStatic(query_processor.clj:251)"
metabase_1  |   "driver.cubejs.query_processor$transform_filters.invoke(query_processor.clj:245)"
metabase_1  |   "driver.cubejs.query_processor$mbql__GT_cubejs.invokeStatic(query_processor.clj:365)"
metabase_1  |   "driver.cubejs.query_processor$mbql__GT_cubejs.invoke(query_processor.clj:360)"
metabase_1  |   "driver.cubejs$fn__947.invokeStatic(cubejs.clj:103)"
metabase_1  |   "driver.cubejs$fn__947.invoke(cubejs.clj:100)"
metabase_1  |   "query_processor.middleware.mbql_to_native$query__GT_native_form$fn__37448.invoke(mbql_to_native.clj:17)"
metabase_1  |   "query_processor.middleware.mbql_to_native$query__GT_native_form.invokeStatic(mbql_to_native.clj:16)"
metabase_1  |   "query_processor.middleware.mbql_to_native$query__GT_native_form.invoke(mbql_to_native.clj:11)"
metabase_1  |   "query_processor.middleware.mbql_to_native$mbql__GT_native$fn__37455.invoke(mbql_to_native.clj:36)"
metabase_1  |   "query_processor.middleware.annotate$result_rows_maps__GT_vectors$fn__40562.invoke(annotate.clj:541)"
metabase_1  |   "query_processor.middleware.annotate$add_column_info$fn__40468.invoke(annotate.clj:485)"
metabase_1  |   "query_processor.middleware.cumulative_aggregations$handle_cumulative_aggregations$fn__41503.invoke(cumulative_aggregations.clj:57)"
metabase_1  |   "query_processor.middleware.resolve_joins$resolve_joins$fn__43430.invoke(resolve_joins.clj:184)"
metabase_1  |   "query_processor.middleware.limit$limit$fn__42138.invoke(limit.clj:19)"
metabase_1  |   "query_processor.middleware.results_metadata$record_and_return_metadata_BANG_$fn__46195.invoke(results_metadata.clj:87)"
metabase_1  |   "query_processor.middleware.format_rows$format_rows$fn__42126.invoke(format_rows.clj:76)"
metabase_1  |   "query_processor.middleware.add_dimension_projections$add_remapping$fn__38215.invoke(add_dimension_projections.clj:234)"
metabase_1  |   "query_processor.middleware.add_source_metadata$add_source_metadata_for_source_queries$fn__38866.invoke(add_source_metadata.clj:107)"
metabase_1  |   "query_processor.middleware.resolve_source_table$resolve_source_tables$fn__43480.invoke(resolve_source_table.clj:46)"
metabase_1  |   "query_processor.middleware.add_row_count_and_status$add_row_count_and_status$fn__38703.invoke(add_row_count_and_status.clj:16)"
metabase_1  |   "query_processor.middleware.driver_specific$process_query_in_context$fn__41578.invoke(driver_specific.clj:12)"
metabase_1  |   "query_processor.middleware.resolve_driver$resolve_driver$fn__43094.invoke(resolve_driver.clj:22)"
metabase_1  |   "query_processor.middleware.store$initialize_store$fn__46220$fn__46221.invoke(store.clj:11)"
metabase_1  |   "query_processor.store$do_with_store.invokeStatic(store.clj:46)"
metabase_1  |   "query_processor.store$do_with_store.invoke(store.clj:40)"
metabase_1  |   "query_processor.middleware.store$initialize_store$fn__46220.invoke(store.clj:10)"
metabase_1  |   "query_processor.middleware.async$async__GT_sync$fn__37366.invoke(async.clj:23)"
metabase_1  |   "query_processor.middleware.async_wait$runnable$fn__40619.invoke(async_wait.clj:89)")

Make the metrics valid

If you try to edit or inspect a metric, the Metabase says it's invalid. Can we fix it and make it valid?

Write tests

I would like to reach 100% code coverage.

Debug logging

Log the queries (MBQL, native) and other useful things when running in debug mode.

Idea: store the measures only in metrics

When we describe the table we return every measure and dimension as a column. What if we only return the columns as field and keep the measures only as a metric. This would produce a cleaner data model look.
We are using the measures from the fields when making a full table query. Maybe we could transform this type of queries somehow.

Broken beforeDate and afterDate time filters

Because we always use the timeDimension field for time filtering these 2 operators are not working properly anymore.
Details:

MBQL: :filter [:> [:field-id 86] [:absolute-datetime (t/zoned-date-time 1997-01-24T00:00Z[GMT]) :default]]

Cube.js query: :timeDimensions [{:dimension Characters.birth, :granularity :day, :dateRange [1997-01-24T00:00:00Z]}]

From the Cube.js docs: "If only one date specified it's equivalent to passing two same dates as a date range."

Proposal:
Use the timeDimension only when 2 dates are specified and maybe if just one but with equals operator.

Pulse only show table when send to slack

Describe the solution you'd like
I want to send my graph to slack but when I create pulse it only shows the table not graph

Additional context
driver 0.13.1
metabase newest
cubejs 0.20.0

Non-date filters are not working

Describe the bug
Non-date filters are not working.

To Reproduce
Try to filter by anything, but not date.

Expected behavior
All filters should work.

Screenshots
image

Version:
v0.9.0

Additional context
This issue exists since PR #52

Generated Cubejs Queries doesn't hit Pre-Aggregations

Describe the bug
When i create rollup pre-aggregations, then aggregations are not generated.
this cause slow responses and processing time well.

To Reproduce
Steps to reproduce the behavior:

  1. create cube with preaggregation rollup type
  2. run question in metabase
  3. pre-aggregations are not generated, looks we hit in-memory cache instead pre-aggregations definitions NOTE: same cube works well in cubejs playground.

Expected behavior
we need as cubejs suggest became multistage

Version:
[e.g. 0.9]

Move Dimension/Measure type from description

Is your feature request related to a problem? Please describe.
We need description field for serious dimension and measure description explain users useful informations. ATM description is used for differentiate

Describe the solution you'd like
Opt1. extend table metabase_field column name eg.

  • dimension.Warehouse.linecount
  • measure.Warehouse.docdate

Opt2. extend field metabase_field.fingertip column
With a small luck json should be extendable and not dis-function metabase basic functionality.

Notes
ATM i disagree with issue: Idea: store the measures only in metrics #50
reason: we are dealing with get work basic measures for simple calculation and/or relative offset of measure - eg. get past month for same measure. (custom metric) - i will explain it soon in another issue.

Bug when show time in measure

Describe the bug
In measures in cubejs I use min(timestamp) and in the filter, in Metabase, I choose summarize by min time and I got error:
image

Version:
All version is lastest

Can I use variables in native query

I want to send some input variables like choose events when creating a funnel. But when I use {{variable}}, it can't work. Does the driver support variable in a native query?

*---
Cubejs 0.20.3
Driver version: lastest.
Metabase: 0.36.3

Show cubejs query in MB sql query window and allow convert it to custom query

Is your feature request related to a problem? Please describe.
Metabase user ATM not allowed to view and convert cubejsquery to "metabase sql query" window. For more understanding cubejs query for BI administrator this missing well.

Workflow

  1. BI admin create query in "Custom Question"
  2. click to sql icon on right (to view query)
  3. To modify query click to "Convert this questiion to sql" (for additional playing...create custom one - not allowed done in metabase wizard according to driver implementation level)

Describe the solution you'd like
show cubejs query in sql query window and allow convert it to custom query

sqlforthisquestion

label: ux

String to number error

Sometimes we get this issue:
ERROR sync.util :: Error generating fingerprint for Field 41 'Characters.numberOfUsers': class java.lang.String cannot be cast to class java.lang.Number (java.lang.String and java.lang.Number are in module java.base of loader 'bootstrap')

  1. Is this a problem? Seems like it doesn't affect the workflow.
  2. Can we fix it? I mean is this a driver related problem? I think yes, but we should examine it. More details soon.

Fill the result with dummy columns

Currently, if we query the full table the Metabase expects all the columns in the result, but we filter the dimensions out and only return the measures.

Support long polling

Datawarehouse queries could be long and run for a few minutes. So the goal is to seamlessly support long-running queries without the need of re-run those with UI actions.
As between cube.js and Metabase the connection is over http the connection could be terminated for many reasons. Also cube.js REST API can respond with continue wait so somehow we should tackle this and still wait for the results.

Handle numbers in a better way

In a Cube.js response every value is a string. We convert the numeric values to long and double based on the dot in the string. Is there any better solution?

Local DB for testing

Reproducible local DB for the (future) tests:

  • Fill with data
  • Add it to compose
  • Create schemas
  • Use it in Cube.js

Incompatible with Metabase v0.35.x

Describe the bug
The driver cannot be built with the Metabase v0.35.0 or newer, because the driver interface has changed in Metabase.

To Reproduce
Just try to build the driver.

Expected behavior
We should able to build the driver.

Version:
0.10.*

Additional context
For example: No such var: driver/execute-query

Time filters

Some time filters are not working properly. For example the this year.
MBQL filter:
:filter [:= [:datetime-field [:field-id 189] :year] [:relative-datetime 0 :year]]
Native filter:
"filters": [ { "member": "Characters.birth", "operator": "inDateRange", "values": [ "2020-02-04T16:54:42.564792Z" ] } ]

Driver sends an empty query

Hi. I installed the plugin and nothing works...
After after adding the database, cubejs got two requests with empty query:

/cubejs-api/v1/meta?query= HTTP/1.1
authorization: xxx
accept: application/json
accept-encoding: gzip, deflate
host: analytics-xxx.local
user-agent: Apache-HttpClient/4.5.5 (Java/11.0.3)

GET /cubejs-api/v1/meta?query= HTTP/1.1
authorization: xxx
accept: application/json
accept-encoding: gzip, deflate
host: analytics-xxx.local
user-agent: Apache-HttpClient/4.5.5 (Java/11.0.3)

Metabase: v0.33.6
@cubejs-backend/[email protected]

What am I doing wrong?

View SQL function query error

Describe the bug
When you click on the View the SQL a query error occurs in the Cube.js backend. See the error log below.

To Reproduce
Click on the View the SQL button

Expected behavior
No error.

Screenshots
image

Version:
0.12.0

Additional context

metabase_1  | 04-20 17:57:55 DEBUG cubejs.utils :: Request: http://cubejs:4000/cubejs-api/v1/load  nil 5a5a4d1b-bc5b-4d40-8e26-d578ab010b23 1
cubejs_1    | User Error: 5a5a4d1b-bc5b-4d40-8e26-d578ab010b23-span-1 (1ms)
cubejs_1    | {}
cubejs_1    | query param is required

URL check in the config

If the API URL isn't ending with a '/', the driver will fail when making HTTP requests.

If the checking cannot doable, just correct the URL (e.g. if the ending character is not a '/' append it)

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.