@metabase/cli 0.3.1-alpha.versioning.9ac5f50 → 0.3.2-alpha.fix-transform-test-ee-path.041c793
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{add-collection-Dmd-uNeU.mjs → add-collection-73X1DmCM.mjs} +5 -5
- package/dist/{alert-D1u2MVZj.mjs → alert-BB38lWSL.mjs} +7 -7
- package/dist/{alerts-DcBjcfEE.mjs → alerts-DxyzqLSU.mjs} +6 -6
- package/dist/{append-B9Htvmab.mjs → append-CHme1Enm.mjs} +4 -4
- package/dist/{archive-BUoYMkxO.mjs → archive-BGiDxu8O.mjs} +3 -3
- package/dist/{archive-Bf014rFm.mjs → archive-BMyvyf62.mjs} +3 -3
- package/dist/{archive-BmsZFOZY.mjs → archive-C4Y2B58q.mjs} +3 -3
- package/dist/{archive-BNivAYGr.mjs → archive-CP5Hlqjw.mjs} +4 -4
- package/dist/{archive-CvU2z5192.mjs → archive-Cq3fnc0v2.mjs} +5 -5
- package/dist/{archive-B660RguB.mjs → archive-CqKqNdUh.mjs} +5 -5
- package/dist/{archive-CgmidYZV.mjs → archive-Czo5T0Lp.mjs} +3 -3
- package/dist/{archive-BVmFGFwG.mjs → archive-DBcxZwLd.mjs} +5 -5
- package/dist/{archive-DhDQIKR_.mjs → archive-DKFPJ9j3.mjs} +5 -5
- package/dist/{archive-CNif6BKy.mjs → archive-DPL1qOuL.mjs} +5 -5
- package/dist/{archive-bPdDITuY.mjs → archive-eS-XA74p.mjs} +3 -3
- package/dist/{auth-CefYEPP5.mjs → auth-6YyB0HNB.mjs} +5 -5
- package/dist/{body-C7m9q4cm.mjs → body-OjAWKVaU.mjs} +3 -3
- package/dist/{branches-pz04OjF2.mjs → branches-D5YLVFDK.mjs} +3 -3
- package/dist/{cancel-CNLnv19e.mjs → cancel-DeRIq1YJ.mjs} +3 -3
- package/dist/{cancel-task-DbnxSh7U.mjs → cancel-task-CqExODVm.mjs} +4 -4
- package/dist/card-BMSqofd7.mjs +24 -0
- package/dist/{card-zyUkr2nS.mjs → card-CEkp1mcI.mjs} +1 -1
- package/dist/{card-DZxRmver.mjs → card-voh1k4hl.mjs} +14 -11
- package/dist/{cards-DtYlVoGP.mjs → cards-B813G9I5.mjs} +6 -6
- package/dist/cli.mjs +223 -211
- package/dist/{client-Bv7Iwdvh.mjs → client-cJ7aw0Gt.mjs} +1788 -72
- package/dist/collection-BfNg7tEg.mjs +20 -0
- package/dist/{collection-WFdBeyqa.mjs → collection-BxdPxD38.mjs} +1 -1
- package/dist/{collection-DALwHnbz.mjs → collection-DYM0p3Xl.mjs} +1 -1
- package/dist/{collection-namespace-CvT0TIZA.mjs → collection-namespace-CVzDgJV0.mjs} +2 -2
- package/dist/{content-translation-D7POzJJ6.mjs → content-translation-QKWt9l76.mjs} +3 -3
- package/dist/{create-JOXq0ULN.mjs → create-4UnoQvsy.mjs} +4 -4
- package/dist/{create-CLgalJUe.mjs → create-BJad6MR82.mjs} +7 -7
- package/dist/{create-Bh2j733n.mjs → create-BLiB2xqo.mjs} +6 -6
- package/dist/{create-DGHILnnk.mjs → create-BWp6L_dW.mjs} +4 -4
- package/dist/{create-Di4YvIbK.mjs → create-Bef5eBCA.mjs} +4 -4
- package/dist/{create-CGgPnb7L.mjs → create-CMV3qlzJ.mjs} +3 -3
- package/dist/{create-Ds-DnSBe.mjs → create-CWGsiFvU.mjs} +3 -3
- package/dist/{create-DhDREiiy.mjs → create-CoFg1p6m.mjs} +3 -3
- package/dist/{create-CGPle4nE.mjs → create-CvIeb1NU.mjs} +6 -6
- package/dist/{create-Bwg-5p08.mjs → create-CvpeAcFc.mjs} +3 -3
- package/dist/{create-DYd_o9BD.mjs → create-D50TxVTk.mjs} +4 -4
- package/dist/{create-DnqnjGGf.mjs → create-DEBgYRlM.mjs} +5 -5
- package/dist/{create-CN24yp_W.mjs → create-DJm0YuLW.mjs} +3 -3
- package/dist/{create-CuYGZ4gu2.mjs → create-DmKwDQCY2.mjs} +5 -5
- package/dist/{create-branch-DWcxC30N.mjs → create-branch-BN5iH-GM.mjs} +4 -4
- package/dist/{create-BEE8uvz2.mjs → create-bvpl6Fn5.mjs} +6 -6
- package/dist/create-uanpKsPo.mjs +34 -0
- package/dist/{csv-CUQvcCEk.mjs → csv-BhuX9fwh.mjs} +4 -4
- package/dist/{current-task-D6P0eL21.mjs → current-task-BMt2NeqV.mjs} +4 -4
- package/dist/{dashboard-BudI952R.mjs → dashboard-Ct_ajSYI.mjs} +10 -10
- package/dist/{dashboard-CKUR8ZpQ.mjs → dashboard-D0hwTC-f.mjs} +11 -2
- package/dist/{dashboard-BlbNszi8.mjs → dashboard-DgK81azj.mjs} +1 -1
- package/dist/{database-B19qlLKZ.mjs → database-C3E9PZSx.mjs} +1 -1
- package/dist/{database-C8G6ZKG0.mjs → database-JtHTqSpq.mjs} +1 -1
- package/dist/{db-C7UTd-6P.mjs → db-B_LW2VE-.mjs} +7 -7
- package/dist/{delete-Ud6iliGM.mjs → delete-BOcPK_H9.mjs} +4 -4
- package/dist/{delete-_IHffP-A.mjs → delete-CowGO4rh.mjs} +4 -4
- package/dist/{delete-Ds-zGh9C.mjs → delete-D0f7VatX.mjs} +4 -4
- package/dist/{delete-DbZZKcYj.mjs → delete-D2bUV6uo.mjs} +4 -4
- package/dist/delete-DZ_ICQug.mjs +44 -0
- package/dist/{delete-DSxqbcFE.mjs → delete-Ur7b11no.mjs} +4 -4
- package/dist/{delete-runtime-BjHL1ryM.mjs → delete-runtime-BKEzJn22.mjs} +1 -1
- package/dist/{delete-table-DtXH6IN5.mjs → delete-table-Dd8X573t.mjs} +4 -4
- package/dist/{dependencies-CR1dlq-A.mjs → dependencies-XDVLBwko.mjs} +6 -6
- package/dist/{dirty-CYxnOnh0.mjs → dirty-k-JmGLsS.mjs} +5 -5
- package/dist/{document-Cd2mmqCp.mjs → document-BHpLJbKU.mjs} +5 -0
- package/dist/document-BW9iow8R.mjs +19 -0
- package/dist/{document-D6OybtP2.mjs → document-CA0Q6lqu.mjs} +1 -1
- package/dist/{download-DPpmmYQe.mjs → download-CQjPIYDO.mjs} +2 -2
- package/dist/{eid-D-BbtWjt.mjs → eid-CNTKDgwj.mjs} +3 -3
- package/dist/{events-CJEnn8WE.mjs → events-BshWlkDp.mjs} +4 -4
- package/dist/{export-BOgyuIOQ.mjs → export-Dq6ecU8h.mjs} +6 -6
- package/dist/{field-CzHBOPER.mjs → field-Bo2ISMO4.mjs} +5 -5
- package/dist/{field-Cr2DPUG9.mjs → field-CcN4oZy6.mjs} +16 -1
- package/dist/{field-BPsNa-TO.mjs → field-fDtIrY6D.mjs} +1 -1
- package/dist/{fields-Bwgkrvus.mjs → fields-CVctqn5G.mjs} +6 -6
- package/dist/{get-BLJSCw53.mjs → get-7xTeNGAo.mjs} +5 -5
- package/dist/{get-DyyPiiaB.mjs → get-8b5Sh50q.mjs} +5 -5
- package/dist/{get-DVi3a2nm.mjs → get-B4RgW-VT.mjs} +5 -5
- package/dist/{get-BaPadzdM.mjs → get-BD81MHl_.mjs} +3 -3
- package/dist/{get-CvIgxPXV.mjs → get-Bl3OmlBP.mjs} +4 -4
- package/dist/get-BtTetWzm.mjs +32 -0
- package/dist/{get-BfVCLBqc.mjs → get-BvSA_mmf.mjs} +5 -5
- package/dist/{get-DsKmZfM2.mjs → get-BvgEF--n.mjs} +3 -3
- package/dist/{get-D8lHwu4-.mjs → get-C5sWciaE.mjs} +5 -5
- package/dist/{get-CqQ-pf0q.mjs → get-CO6X4nZH.mjs} +16 -12
- package/dist/{get-CWfIiXwL.mjs → get-CTPvdcud.mjs} +5 -5
- package/dist/{get-C1ZdOvMm.mjs → get-CrpwxWOV.mjs} +3 -3
- package/dist/{get-BOLwso0V.mjs → get-D4oGhZWX.mjs} +3 -3
- package/dist/{get-B89DUSvw.mjs → get-Df6cGHCM.mjs} +3 -3
- package/dist/{get-BL90QC64.mjs → get-DfMVlz64.mjs} +5 -5
- package/dist/{get-CLu4yzMp2.mjs → get-Dr-U321T2.mjs} +5 -5
- package/dist/{get-D4OTJblo.mjs → get-Dw7jAno3.mjs} +5 -5
- package/dist/{get-DgnYF7LR.mjs → get-PWhOdz1z.mjs} +3 -3
- package/dist/{get-COwdtskS.mjs → get-RslzBaXx.mjs} +4 -4
- package/dist/{get-run-Iya0Yw9s.mjs → get-run-CZdDqfUj.mjs} +5 -5
- package/dist/{get-Eqq13YY-.mjs → get-wjIgUlNl.mjs} +3 -3
- package/dist/git-sync-BmoRk0UV.mjs +28 -0
- package/dist/{git-sync-BDnxPrqU.mjs → git-sync-BwBRmEhE.mjs} +18 -1
- package/dist/{git-sync-DxD_ng48.mjs → git-sync-TjX1r_wF.mjs} +1 -1
- package/dist/{group-CmVCLBDz.mjs → group-YQQ5GIcP.mjs} +2 -3
- package/dist/{has-remote-changes-DfJUMP8F.mjs → has-remote-changes-i-3MVxat.mjs} +4 -4
- package/dist/{import-FEAx-Y5A.mjs → import-DWEKejya.mjs} +6 -6
- package/dist/{input-DFZ_qGW_.mjs → input-DEvkIjGr.mjs} +1 -1
- package/dist/{is-dirty-BsYjBSXG.mjs → is-dirty-C5ipqd4v.mjs} +2 -2
- package/dist/{items-D4rstE12.mjs → items-hKJ2ZDwy.mjs} +6 -6
- package/dist/{key-BmWundO3.mjs → key-PYetuQ13.mjs} +1 -1
- package/dist/{library-uzyHWBap.mjs → library-B7_04UVK.mjs} +5 -5
- package/dist/{library-DXB8sm4r.mjs → library-BPIzb3K_.mjs} +1 -1
- package/dist/{library-CmctxHjv.mjs → library-PGCfm0UA.mjs} +1 -1
- package/dist/{list-DrS3ePsv.mjs → list-1vdClKSE.mjs} +3 -3
- package/dist/{list-xMfCeuZc.mjs → list-6myofqMv.mjs} +6 -6
- package/dist/{list-squb_ioH.mjs → list-B-9QOX9Y.mjs} +5 -5
- package/dist/{list-ndIl9XqV.mjs → list-Bs7_Rysg.mjs} +6 -6
- package/dist/list-CHuhMXet.mjs +35 -0
- package/dist/{list-CQy0z7f9.mjs → list-CLZU_EOf.mjs} +3 -3
- package/dist/{list-DeNGm9G4.mjs → list-Cen-7uTo.mjs} +4 -4
- package/dist/{list-Bjj0z5BS.mjs → list-CgH-H-O6.mjs} +3 -3
- package/dist/{list-BmMi_wPD.mjs → list-CjNXskB4.mjs} +6 -6
- package/dist/{list-DoTiQc3D.mjs → list-CmFh1GQ_.mjs} +3 -3
- package/dist/{list-D_zvX0ms.mjs → list-D6tTvYUP.mjs} +3 -3
- package/dist/{list-CC1M_n6Z.mjs → list-DI820W6w.mjs} +5 -5
- package/dist/{list-Dgm6TkqR.mjs → list-DKZnQ4Ts.mjs} +6 -6
- package/dist/{list-sQcA4g05.mjs → list-DKcC4cm0.mjs} +5 -5
- package/dist/{list-BRpPbvyS.mjs → list-DfRqNH1N.mjs} +3 -3
- package/dist/{list-bN0RC14-.mjs → list-DjwnsyXM.mjs} +11 -10
- package/dist/{list-BXL8HFr_.mjs → list-VNC-_E59.mjs} +5 -5
- package/dist/{list-1DkkU82x.mjs → list-eKDT1XXk.mjs} +5 -5
- package/dist/{list-B7tqNV8B.mjs → list-oX2SMzxZ.mjs} +3 -3
- package/dist/{login-D_1-zE4A.mjs → login-DumZaWXK.mjs} +9 -9
- package/dist/{logout-DPi2q1Wu.mjs → logout-BsXPRc-3.mjs} +2 -2
- package/dist/{measure-CdA8Nl3Z.mjs → measure-BFxkbAoa.mjs} +6 -6
- package/dist/{notification-Fcq1fIPw.mjs → notification-DVrLkjFT.mjs} +1 -1
- package/dist/{parameter-DUKR8NXo.mjs → parameter-Celg0wZa.mjs} +1 -1
- package/dist/{parameter-values-C6dj6I4g.mjs → parameter-values-CoF9Hx1p.mjs} +4 -4
- package/dist/{parse-enum-B1t8S194.mjs → parse-enum-Dc0dMZ3P.mjs} +1 -1
- package/dist/{parse-id-DR8aUSdL.mjs → parse-id-DmFJgpY6.mjs} +1 -1
- package/dist/{parse-ref-BJ_Q0tNW.mjs → parse-ref-DTDld_LJ.mjs} +1 -1
- package/dist/{path-B96DI8u2.mjs → path-BQ4lRDyN.mjs} +4 -4
- package/dist/{poll-By46YQ5J.mjs → poll-CZeXepUQ.mjs} +2 -2
- package/dist/{preflight-Bl1oitm8.mjs → preflight-BTQe4swo.mjs} +3 -3
- package/dist/{process-CcQM4qPv.mjs → process-CTrfxxaC.mjs} +1 -1
- package/dist/{publish-BKJYvxif.mjs → publish-CFB2Cc5A.mjs} +4 -4
- package/dist/{pulse-BmsDenXm.mjs → pulse-Dz0ocv0l.mjs} +1 -1
- package/dist/{pulse-DhG6I9mI.mjs → pulse-x0gFxWfG.mjs} +2 -2
- package/dist/{query-qBHjZQc_.mjs → query-BJbUnAHf.mjs} +9 -9
- package/dist/query-CV2KCS5O.mjs +114 -0
- package/dist/{query-result-DBDwk8TS.mjs → query-result-E4Q-Gra6.mjs} +1 -1
- package/dist/{remove-collection-BWFW7Rn6.mjs → remove-collection-D3yvKH3e.mjs} +5 -5
- package/dist/{render-DmykmrFB.mjs → render-BJRCs7rA.mjs} +4 -2
- package/dist/{replace-BmAqD3zY.mjs → replace-uj4WTqx_.mjs} +4 -4
- package/dist/{rescan-values-BrCLrihF.mjs → rescan-values-CzxQU318.mjs} +5 -5
- package/dist/{run-q5Y44Fxj.mjs → run-B2f_omHu.mjs} +3 -3
- package/dist/run-DlO1J1Sx.mjs +50 -0
- package/dist/{run-CtbzjDKY.mjs → run-yX2dtmE5.mjs} +5 -5
- package/dist/{runs-JFlbezkQ.mjs → runs-DzUO45wU.mjs} +6 -6
- package/dist/{runtime-BQiGgbgZ.mjs → runtime-arKqJqIT.mjs} +225 -68
- package/dist/{schema-tables-Bzx2ShyE.mjs → schema-tables-DZCNzuQ6.mjs} +6 -6
- package/dist/{schemas-ww5mU2AS.mjs → schemas-2ejqaVsG.mjs} +4 -4
- package/dist/{search-DFBwUc6d.mjs → search-BAXg-EJw.mjs} +2 -1
- package/dist/{search-J4RwCof-.mjs → search-DcihauDZ.mjs} +5 -5
- package/dist/{segment-XXTjU0eG.mjs → segment-BQT2poPG.mjs} +6 -6
- package/dist/{selectors-BAAZMi43.mjs → selectors-BzestDld.mjs} +3 -3
- package/dist/{send-BmpDlw9O.mjs → send-DMxoLFo7.mjs} +3 -3
- package/dist/{set-DUWrSza9.mjs → set-CDmiD0vv.mjs} +4 -4
- package/dist/{set-active-BiUlbNI5.mjs → set-active-RrvWR9NY.mjs} +3 -3
- package/dist/{setting-B1KBQN3M.mjs → setting-BiBLCcxz.mjs} +4 -4
- package/dist/{setup-CVaNVwOd.mjs → setup-DYsTzkWO.mjs} +3 -3
- package/dist/{signal-GhGmuHfx.mjs → signal-k7cm5N6h.mjs} +1 -1
- package/dist/{skill-list-DTnDhnL5.mjs → skill-list-D9_1Pmt7.mjs} +16 -9
- package/dist/{skills-DkDsSH5F.mjs → skills-BPHXUfeL.mjs} +75 -28
- package/dist/{skills-BWrAlj9l.mjs → skills-C3bxxC6a.mjs} +3 -3
- package/dist/snippet-BtfxE60H.mjs +19 -0
- package/dist/{stash-DMm8YF8V.mjs → stash-DdheS0Ad.mjs} +6 -6
- package/dist/{status-BzEQjQ_t.mjs → status-BuIzXRX1.mjs} +3 -3
- package/dist/{status-ClWsQD6v.mjs → status-CXouQJ31.mjs} +5 -5
- package/dist/{subscription-CdFn2hre.mjs → subscription-CJ8Igs1U.mjs} +6 -6
- package/dist/{subscriptions-DBda1pE5.mjs → subscriptions-D0NpGvCQ.mjs} +6 -6
- package/dist/{summary-B4GPiuqD.mjs → summary-D04S8gGj.mjs} +5 -5
- package/dist/{sync-schema-DsIM5g2U.mjs → sync-schema-DrA5zkdl.mjs} +6 -6
- package/dist/{sync-task-BACcrs0i.mjs → sync-task-BXeWuARG.mjs} +1 -1
- package/dist/{table-CsIJNPFf.mjs → table-C6h4tIRw.mjs} +1 -1
- package/dist/{table-CeeTJgQb.mjs → table-DfuY0N8e.mjs} +51 -4
- package/dist/{table-D4Alrrwh.mjs → table-Dntbz7Q2.mjs} +5 -5
- package/dist/timeline-8jwsldo3.mjs +21 -0
- package/dist/{timeline-event-DWIh3Tdt.mjs → timeline-event-BbB1xEdI.mjs} +6 -6
- package/dist/{transform-Bk0D0nIs.mjs → transform-CtqB1WYo.mjs} +2 -2
- package/dist/{transform-DpuG-ON3.mjs → transform-DiW7bREn.mjs} +43 -1
- package/dist/transform-job-B-1YAbvy.mjs +22 -0
- package/dist/transform-m6s4kkWU.mjs +28 -0
- package/dist/{transform-tag-DJ3_bksm.mjs → transform-tag-PjryheLF.mjs} +5 -5
- package/dist/transform-test-BjjCQ2xm.mjs +169 -0
- package/dist/transform-test-DSTkKKNC.mjs +16 -0
- package/dist/transform-test-gzDcbypy.mjs +25 -0
- package/dist/{transforms-Dg2MfB2a.mjs → transforms-CijX3VE7.mjs} +6 -6
- package/dist/{tree-BQL0f7YX.mjs → tree-Cmb3O6rH.mjs} +3 -3
- package/dist/{unpublish-DfSvb_Rs.mjs → unpublish-DkP_AcK5.mjs} +3 -3
- package/dist/{update-DBGaJDsj.mjs → update-8UmD1prT.mjs} +6 -6
- package/dist/{update-Izqip6jY.mjs → update-BFyRBc-H.mjs} +7 -7
- package/dist/{update-BCgAyfj_.mjs → update-BrXGg3QO.mjs} +7 -7
- package/dist/{update-sYLQIUgh.mjs → update-C91m9YAR.mjs} +5 -5
- package/dist/{update-D1QdfpKR.mjs → update-COcx61Ur.mjs} +5 -5
- package/dist/update-Ci8YL4_2.mjs +41 -0
- package/dist/{update-CDo0Orvu.mjs → update-CtLbFCd_.mjs} +4 -4
- package/dist/{update-Bhmli02m.mjs → update-D6Zzvc7F.mjs} +6 -6
- package/dist/{update-Cr5zHb0D.mjs → update-D8htjzNJ.mjs} +4 -4
- package/dist/{update-CtDHMxW8.mjs → update-D9kOTr0n.mjs} +5 -5
- package/dist/{update-BxIyFtrX.mjs → update-DPTio6i1.mjs} +6 -6
- package/dist/{update-NZhIjTCf.mjs → update-DlWB9s0v.mjs} +4 -4
- package/dist/{update-D4qdTlLF.mjs → update-DubrpPbz.mjs} +4 -4
- package/dist/{update-CiYxcf8M.mjs → update-Dz47cKBk.mjs} +4 -4
- package/dist/{update-B-hRR8gW.mjs → update-FCP5Lop2.mjs} +6 -6
- package/dist/{update-CKoBDTL7.mjs → update-KSHnb6vB.mjs} +8 -8
- package/dist/{update-dashcard-D5b971AO.mjs → update-dashcard-BlibHa5o.mjs} +6 -6
- package/dist/{upgrade-CD1xtsIv.mjs → upgrade-EwL6wPSY.mjs} +4 -4
- package/dist/upload-BZshRJIM.mjs +13 -0
- package/dist/{upload-akKFxpVA.mjs → upload-D0KaTqUE.mjs} +3 -3
- package/dist/{upload-BUd3MG90.mjs → upload-Do2PBSeH.mjs} +2 -2
- package/dist/{uuid-oVdJ62eA.mjs → uuid-DjKLDIVE.mjs} +9 -5
- package/dist/{validate-query-Boi8-cAP.mjs → validate-query-D6_ad-Gi.mjs} +3 -3
- package/dist/{validate-CWd6l6KZ.mjs → validate-xR_MHBNR.mjs} +69 -23
- package/dist/{values-DLwZl-P8.mjs → values-Dc9612_L.mjs} +5 -5
- package/dist/{verify-CH9Tw8yv.mjs → verify-DVN1eqXZ.mjs} +3 -3
- package/dist/{wait-rfTdQWdi.mjs → wait-C-ovOTAZ.mjs} +6 -6
- package/dist/{wait-flags-DiQ_kRjZ.mjs → wait-flags-BQNmuvIj.mjs} +2 -2
- package/dist/{window-BkvrP0gB.mjs → window-DSb1tqSe.mjs} +1 -1
- package/package.json +1 -1
- package/skill-data/core/SKILL.md +20 -14
- package/skill-data/dashboard/SKILL.md +1 -1
- package/skill-data/mbql/SKILL.md +84 -115
- package/skill-data/mbql/references/operators.md +81 -240
- package/skill-data/native-sql/SKILL.md +8 -9
- package/skill-data/native-sql/references/template-tags.md +21 -25
- package/skill-data/transform/SKILL.md +64 -2
- package/skill-data/transform-test-plan/SKILL.md +171 -0
- package/skill-data/transform-test-plan/references/checklist.md +81 -0
- package/skill-data/transform-test-plan/references/checks.md +260 -0
- package/skill-data/visualization/SKILL.md +2 -3
- package/skill-data/visualization/references/settings.md +7 -7
- package/skills/metabase-cli/SKILL.md +1 -1
- package/dist/card-BRarvKYX.mjs +0 -24
- package/dist/collection-CKeO8X7U.mjs +0 -20
- package/dist/document-BoILnE_1.mjs +0 -19
- package/dist/git-sync-CdN0Maun.mjs +0 -28
- package/dist/query-BKSM-pbi.mjs +0 -86
- package/dist/snippet-CG75L2DS.mjs +0 -19
- package/dist/timeline-DmM0BuX8.mjs +0 -21
- package/dist/transform-BcV_XlSX.mjs +0 -28
- package/dist/transform-job-CjtwBGoM.mjs +0 -22
- package/dist/upload-DzGTlldn.mjs +0 -13
|
@@ -1,268 +1,109 @@
|
|
|
1
1
|
# MBQL operator reference
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
- [
|
|
17
|
-
- [
|
|
18
|
-
- [
|
|
19
|
-
- [
|
|
20
|
-
- [
|
|
21
|
-
- [
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
`["
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
| `not` | 1 boolean clause | Logical NOT |
|
|
41
|
-
|
|
42
|
-
### Comparison
|
|
43
|
-
|
|
44
|
-
| Op | Args | Notes |
|
|
45
|
-
| ----------------- | -------------------------------------------------------- | ----------------------- |
|
|
46
|
-
| `=` | field, 1+ values | Multi-value = IN |
|
|
47
|
-
| `!=` | field, 1+ values | Multi-value = NOT IN |
|
|
48
|
-
| `<` `>` `<=` `>=` | 2 orderable | |
|
|
49
|
-
| `between` | field, min, max | Inclusive |
|
|
50
|
-
| `inside` | lat-field, lon-field, lat-max, lon-min, lat-min, lon-max | Geographic bounding box |
|
|
51
|
-
|
|
52
|
-
```json
|
|
53
|
-
["between", {…}, ["field", {…}, 12], 10, 100]
|
|
54
|
-
["=", {…}, ["field", {…}, 7], "Widget", "Gadget"]
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### Null / empty
|
|
58
|
-
|
|
59
|
-
| Op | Args | Notes |
|
|
60
|
-
| ----------- | ------------------- | --------------------- |
|
|
61
|
-
| `is-null` | 1 expression | |
|
|
62
|
-
| `not-null` | 1 expression | |
|
|
63
|
-
| `is-empty` | 1 string expression | NULL or `""` |
|
|
64
|
-
| `not-empty` | 1 string expression | not NULL and not `""` |
|
|
65
|
-
|
|
66
|
-
### String match
|
|
67
|
-
|
|
68
|
-
N-ary (multiple values OR'd). Accept a `case-sensitive` option (default `true`) in the
|
|
69
|
-
options object.
|
|
70
|
-
|
|
71
|
-
| Op | Args |
|
|
72
|
-
| ------------------ | ----------------- |
|
|
73
|
-
| `contains` | field, 1+ strings |
|
|
74
|
-
| `does-not-contain` | field, 1+ strings |
|
|
75
|
-
| `starts-with` | field, 1+ strings |
|
|
76
|
-
| `ends-with` | field, 1+ strings |
|
|
77
|
-
|
|
78
|
-
```json
|
|
79
|
-
["contains", { "case-sensitive": false }, ["field", {…}, 9], "widget"]
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### Temporal
|
|
83
|
-
|
|
84
|
-
| Op | Args | Notes |
|
|
85
|
-
| ------------------------ | ---------------------------------------------------------- | --------------------------------------------------- |
|
|
86
|
-
| `time-interval` | temporal-field, n, unit | `n` = integer, or `"current"` / `"last"` / `"next"` |
|
|
87
|
-
| `relative-time-interval` | temporal-field, value, bucket, offset-value, offset-bucket | interval with offset |
|
|
88
|
-
|
|
89
|
-
Units (truncation only): `millisecond`, `second`, `minute`, `hour`, `day`, `week`,
|
|
90
|
-
`month`, `quarter`, `year`.
|
|
91
|
-
|
|
92
|
-
```json
|
|
93
|
-
["time-interval", {…}, ["field", {…}, 22], -30, "day"] // last 30 days
|
|
94
|
-
["time-interval", {…}, ["field", {…}, 22], "current", "month"]
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### Segment
|
|
98
|
-
|
|
99
|
-
| Op | Args | Notes |
|
|
100
|
-
| --------- | ---------- | ------------------------- |
|
|
101
|
-
| `segment` | segment id | Reference a saved segment |
|
|
102
|
-
|
|
103
|
-
---
|
|
104
|
-
|
|
105
|
-
## Aggregation functions
|
|
106
|
-
|
|
107
|
-
A stage's `aggregation` is a list of aggregation clauses.
|
|
108
|
-
|
|
109
|
-
| Op | Args | Notes |
|
|
110
|
-
| ----------------------- | -------------------------- | ----------------------------- |
|
|
111
|
-
| `count` | none, or 1 expression | with arg: count non-NULL |
|
|
112
|
-
| `sum` `avg` `min` `max` | 1 numeric/orderable | |
|
|
113
|
-
| `distinct` | 1 expression | count of distinct values |
|
|
114
|
-
| `cum-count` | none or 1 expression | running count |
|
|
115
|
-
| `cum-sum` | 1 numeric | running sum |
|
|
116
|
-
| `stddev` `var` `median` | 1 numeric | |
|
|
117
|
-
| `percentile` | numeric, p (0.0–1.0) | |
|
|
118
|
-
| `count-where` | 1 boolean clause | |
|
|
119
|
-
| `sum-where` | numeric, boolean clause | |
|
|
120
|
-
| `distinct-where` | expression, boolean clause | |
|
|
121
|
-
| `share` | 1 boolean clause | proportion 0–1 |
|
|
122
|
-
| `metric` | metric id | reference a saved metric card |
|
|
3
|
+
Every clause is `[op, {options}, ...args]` with `{}` when there are no options. `<field>` is `["field", {}, <field id>]`, or any expression of the right type; `<pred>` is a filter clause. Clause heads are lowercase and hyphenated, exactly as written here.
|
|
4
|
+
|
|
5
|
+
## Filters
|
|
6
|
+
|
|
7
|
+
A stage's `filters` are ANDed.
|
|
8
|
+
|
|
9
|
+
- `["and", {}, <pred>, <pred>, …]` / `["or", …]`: two or more
|
|
10
|
+
- `["not", {}, <pred>]`
|
|
11
|
+
- `["=", {}, <field>, <v1>, <v2>, …]` / `["!=", …]`: several values mean any of them / none of them
|
|
12
|
+
- `["in", {}, <field>, <v1>, <v2>, …]` / `["not-in", …]`: multi-value membership
|
|
13
|
+
- `["<", {}, <a>, <b>]` / `["<=", …]` / `[">", …]` / `[">=", …]`
|
|
14
|
+
- `["between", {}, <field>, <min>, <max>]`: inclusive; dates as `"2024-01-01"`
|
|
15
|
+
- `["inside", {}, <lat>, <lon>, <lat-max>, <lon-min>, <lat-min>, <lon-max>]`: bounding box
|
|
16
|
+
- `["is-null", {}, <field>]` / `["not-null", …]`
|
|
17
|
+
- `["is-empty", {}, <field>]` / `["not-empty", …]`: NULL or `""`
|
|
18
|
+
- `["contains", {}, <field>, "a", "b", …]` / `["does-not-contain", …]` / `["starts-with", …]` / `["ends-with", …]`: any of the strings (`does-not-contain`: none of them); `{"case-sensitive": false}` in options
|
|
19
|
+
- `["time-interval", {}, <field>, <n>, "<unit>"]`: the `n` whole units before the current one (`n` negative) or after it, or `"current"` / `"last"` / `"next"` for a single unit; `{"include-current": true}` in options adds the current unit
|
|
20
|
+
- `["relative-time-interval", {}, <field>, <n>, "<unit>", <offset n>, "<offset unit>"]`: a window shifted from now: last 3 months, a year ago
|
|
21
|
+
- `["during", {}, <field>, "2024-03-15", "<unit>"]`: the whole unit containing the date
|
|
22
|
+
- `["segment", {}, <segment id>]`: a saved segment, on its table
|
|
23
|
+
|
|
24
|
+
Units for `time-interval` and friends: `millisecond`, `second`, `minute`, `hour`, `day`, `week`, `month`, `quarter`, `year`.
|
|
25
|
+
|
|
26
|
+
## Aggregations
|
|
27
|
+
|
|
28
|
+
- `["count", {}]` / `["count", {}, <field>]`: rows / non-NULL values
|
|
29
|
+
- `["sum", {}, <field>]` / `["avg", …]` / `["median", …]` / `["stddev", …]` / `["var", …]`: numeric
|
|
30
|
+
- `["min", {}, <field>]` / `["max", …]`: any orderable
|
|
31
|
+
- `["distinct", {}, <field>]`: count of distinct values
|
|
32
|
+
- `["percentile", {}, <field>, 0.9]`: 0 to 1
|
|
33
|
+
- `["count-where", {}, <pred>]`
|
|
34
|
+
- `["sum-where", {}, <field>, <pred>]`
|
|
35
|
+
- `["distinct-where", {}, <field>, <pred>]`
|
|
36
|
+
- `["share", {}, <pred>]`: fraction of rows, 0 to 1
|
|
37
|
+
- `["cum-count", {}]` / `["cum-sum", {}, <field>]`: running totals over the breakout
|
|
38
|
+
- `["offset", {}, <aggregation>, <n>]`: the value n breakout rows back (negative) or ahead; in `aggregation` only
|
|
39
|
+
- `["metric", {}, <card id>]`: a saved metric, on its table
|
|
123
40
|
|
|
124
41
|
<!-- requires: measures -->
|
|
125
42
|
|
|
126
|
-
`measure
|
|
43
|
+
`["measure", {}, <measure id>]` is a saved measure, on its table.
|
|
127
44
|
|
|
128
45
|
<!-- /requires -->
|
|
129
46
|
|
|
130
|
-
|
|
131
|
-
["count", {…}]
|
|
132
|
-
["sum", {…}, ["field", {…}, 42]]
|
|
133
|
-
["count-where", {…}, [">", {…}, ["field", {…}, 42], 100]]
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
**Naming** — set `name` (warehouse column) and/or `display-name` (UI header) in the
|
|
137
|
-
options object: `["sum", { "name": "revenue", "display-name": "Revenue" }, …]`.
|
|
138
|
-
|
|
139
|
-
**Window function** — `offset` is only valid inside `aggregation`:
|
|
140
|
-
|
|
141
|
-
| Op | Args | Notes |
|
|
142
|
-
| -------- | ------------- | ------------------------------------------------- |
|
|
143
|
-
| `offset` | expression, n | value n rows before (negative) / after (positive) |
|
|
144
|
-
|
|
145
|
-
---
|
|
146
|
-
|
|
147
|
-
## Expression operators
|
|
47
|
+
Name the output in options: `["sum", {"name": "revenue", "display-name": "Revenue"}, <field>]`.
|
|
148
48
|
|
|
149
|
-
|
|
49
|
+
## Expressions
|
|
150
50
|
|
|
151
|
-
|
|
51
|
+
Named in `expressions` by `{"lib/expression-name": "<name>"}` in the options, or used inline anywhere a value goes.
|
|
152
52
|
|
|
153
|
-
|
|
154
|
-
| --- | ---------------------------------- | -------------------- |
|
|
155
|
-
| `+` | 2+ numeric, or temporal + interval | |
|
|
156
|
-
| `-` | 1+ numeric, or temporal − interval | unary = negation |
|
|
157
|
-
| `*` | 2+ numeric | |
|
|
158
|
-
| `/` | 2+ numeric | always returns float |
|
|
53
|
+
**Math:** `["+", {}, a, b, …]`, `["-", …]`, `["*", …]`, `["/", …]` (always a float), `["abs", {}, x]`, `["ceil", …]`, `["floor", …]`, `["round", …]`, `["sqrt", …]`, `["exp", …]`, `["log", …]`, `["power", {}, base, exponent]`. `round` takes one argument and rounds to an integer.
|
|
159
54
|
|
|
160
|
-
|
|
55
|
+
**Conversion:** `["integer", {}, <text or number>]`, `["float", {}, <text>]`, `["text", {}, <any>]`, `["date", {}, <text or datetime>]`, `["datetime", {}, <ISO text>]`, `["datetime", {"mode": "simple"}, <text>]`, `["datetime", {"mode": "unix-seconds"}, <number>]` (number modes `unix-seconds`, `unix-milliseconds`, `unix-microseconds`, `unix-nanoseconds`).
|
|
161
56
|
|
|
162
|
-
|
|
163
|
-
| ---------------------------- | -------------- |
|
|
164
|
-
| `abs` `ceil` `floor` `round` | 1 numeric |
|
|
165
|
-
| `power` | base, exponent |
|
|
166
|
-
| `sqrt` `exp` `log` | 1 numeric |
|
|
57
|
+
**Text:** `["concat", {}, a, b, …]`, `["substring", {}, s, <start from 1>, <length>?]`, `["replace", {}, s, "find", "replacement"]`, `["regex-match-first", {}, s, "<regex>"]`, `["split-part", {}, s, "<delimiter>", <position from 1>]`, `["length", {}, s]`, `["trim", …]`, `["ltrim", …]`, `["rtrim", …]`, `["upper", …]`, `["lower", …]`, `["host", {}, <url>]`, `["domain", …]`, `["subdomain", …]`, `["path", …]`.
|
|
167
58
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
| Op | Args |
|
|
171
|
-
| ---------------------------------- | ------------------------------- |
|
|
172
|
-
| `concat` | 2+ expressions |
|
|
173
|
-
| `substring` | str, start (1-indexed), length? |
|
|
174
|
-
| `replace` | str, find, replace |
|
|
175
|
-
| `regex-match-first` | str, regex |
|
|
176
|
-
| `split-part` | str, delimiter, position |
|
|
177
|
-
| `trim` `ltrim` `rtrim` | 1 string |
|
|
178
|
-
| `upper` `lower` | 1 string |
|
|
179
|
-
| `length` | 1 string |
|
|
180
|
-
| `host` `domain` `subdomain` `path` | 1 URL string |
|
|
181
|
-
|
|
182
|
-
### Temporal
|
|
183
|
-
|
|
184
|
-
| Op | Args | Notes |
|
|
185
|
-
| ----------------------------------------------------------------------------------- | ------------------------------- | -------------------------- |
|
|
186
|
-
| `now` | none | datetime |
|
|
187
|
-
| `today` | none | date |
|
|
188
|
-
| `interval` | amount, unit | a temporal interval |
|
|
189
|
-
| `datetime-add` | temporal, amount, unit | |
|
|
190
|
-
| `datetime-subtract` | temporal, amount, unit | |
|
|
191
|
-
| `datetime-diff` | datetime1, datetime2, unit | |
|
|
192
|
-
| `convert-timezone` | temporal, target-tz, source-tz? | |
|
|
193
|
-
| `get-year` `get-quarter` `get-month` `get-day` `get-hour` `get-minute` `get-second` | 1 temporal | integer component |
|
|
194
|
-
| `get-day-of-week` | temporal, mode? | mode `iso`/`us`/`instance` |
|
|
195
|
-
| `get-week` | temporal, mode? | mode `iso`/`us`/`instance` |
|
|
196
|
-
| `temporal-extract` | temporal, unit, mode? | generic extraction |
|
|
197
|
-
| `month-name` `quarter-name` `day-name` | 1 integer | name from number |
|
|
198
|
-
|
|
199
|
-
Add/subtract/interval units: `year`, `quarter`, `month`, `week`, `day`, `hour`,
|
|
200
|
-
`minute`, `second`, `millisecond`. `datetime-diff` units: same minus `millisecond`.
|
|
201
|
-
`temporal-extract` units: `year-of-era`, `quarter-of-year`, `month-of-year`,
|
|
202
|
-
`week-of-year-iso`, `week-of-year-us`, `week-of-year-instance`, `day-of-month`,
|
|
203
|
-
`day-of-week`, `day-of-week-iso`, `hour-of-day`, `minute-of-hour`, `second-of-minute`.
|
|
204
|
-
|
|
205
|
-
### Type conversion
|
|
206
|
-
|
|
207
|
-
| Op | Args |
|
|
208
|
-
| --------- | ----------------- |
|
|
209
|
-
| `integer` | string or numeric |
|
|
210
|
-
| `float` | string |
|
|
211
|
-
| `text` | 1 expression |
|
|
212
|
-
|
|
213
|
-
### Conditional
|
|
214
|
-
|
|
215
|
-
| Op | Args | Notes |
|
|
216
|
-
| ---------- | ------------------------------ | ---------------------------------------------------- |
|
|
217
|
-
| `case` | `[[cond, value], …]`, default? | if/then/else; default is the trailing positional arg |
|
|
218
|
-
| `if` | same as `case` | alias for `case` |
|
|
219
|
-
| `coalesce` | 2+ expressions | first non-null |
|
|
59
|
+
**Conditional:** `["case", {}, [[<pred>, <value>], [<pred>, <value>]], <default>?]` (alias `if`), `["coalesce", {}, a, b, …]`.
|
|
220
60
|
|
|
221
61
|
```json
|
|
222
|
-
[
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
62
|
+
[
|
|
63
|
+
"case",
|
|
64
|
+
{ "lib/expression-name": "Tier" },
|
|
65
|
+
[
|
|
66
|
+
[[">", {}, ["field", {}, 14], 100], "Premium"],
|
|
67
|
+
[["<=", {}, ["field", {}, 14], 20], "Budget"]
|
|
68
|
+
],
|
|
69
|
+
"Standard"
|
|
70
|
+
]
|
|
226
71
|
```
|
|
227
72
|
|
|
228
|
-
|
|
229
|
-
positional arg is the default.)
|
|
230
|
-
|
|
231
|
-
---
|
|
73
|
+
**Dates:**
|
|
232
74
|
|
|
233
|
-
|
|
75
|
+
- `["now", {}]` / `["today", {}]`
|
|
76
|
+
- `["datetime-add", {}, <date>, <n>, "<unit>"]` / `["datetime-subtract", …]`: `n` an integer
|
|
77
|
+
- `["datetime-diff", {}, <from>, <to>, "<unit>"]`: units `second` … `year`; the way to subtract two dates
|
|
78
|
+
- `["interval", {}, <n>, "<unit>"]`: added to a date with `+`
|
|
79
|
+
- `["get-year", {}, <date>]` / `get-quarter` / `get-month` / `get-day` / `get-hour` / `get-minute` / `get-second`: an integer; a quarter is `1`–`4`
|
|
80
|
+
- `["get-week", {}, <date>]` / `["get-day-of-week", {}, <date>]`: a fourth argument `"iso"`, `"us"` or `"instance"` sets the week convention
|
|
81
|
+
- `["temporal-extract", {}, <date>, "<extract unit>"]`: `year-of-era`, `quarter-of-year`, `month-of-year`, `week-of-year-iso`, `week-of-year-us`, `week-of-year-instance`, `day-of-month`, `day-of-week`, `day-of-week-iso`, `hour-of-day`, `minute-of-hour`, `second-of-minute`
|
|
82
|
+
- `["month-name", {}, <1–12>]` / `["quarter-name", {}, <1–4>]` / `["day-name", {}, <1–7>]`
|
|
83
|
+
- `["convert-timezone", {}, <date>, "America/New_York", "<from tz>"?]`
|
|
84
|
+
- `["relative-datetime", {}, <n>, "<unit>"]` / `["relative-datetime", {}, "current"]`: a point relative to now, for comparisons
|
|
85
|
+
- `["absolute-datetime", {}, "2024-03-15T00:00:00", "<unit>"]`: the unit is required, `"default"` keeps the literal; a date literal (`"2024-03-15"`) takes a date unit (`day` … `year`) or `"default"`
|
|
234
86
|
|
|
235
|
-
|
|
236
|
-
| ----------- | ------------------------------------ | ------------------------------------------------------------------------------ |
|
|
237
|
-
| field | `["field", {…}, <field-id>]` | numeric id; options may carry `base-type`, `temporal-unit`, `binning` |
|
|
238
|
-
| expression | `["expression", {…}, "<name>"]` | by the expression's `lib/expression-name` string |
|
|
239
|
-
| aggregation | `["aggregation", {…}, "<agg-uuid>"]` | 3rd arg is the **string** `lib/uuid` of the target aggregation, not a position |
|
|
87
|
+
Add, subtract, diff and interval units: `millisecond` (not diff), `second`, `minute`, `hour`, `day`, `week`, `month`, `quarter`, `year`.
|
|
240
88
|
|
|
241
|
-
## Field option: temporal
|
|
89
|
+
## Field option: `temporal-unit`
|
|
242
90
|
|
|
243
|
-
|
|
91
|
+
On a date field ref, mostly in `breakout`:
|
|
244
92
|
|
|
245
|
-
- Truncation: `
|
|
246
|
-
|
|
247
|
-
-
|
|
248
|
-
`day-of-month`, `day-of-year`, `week-of-year`, `month-of-year`, `quarter-of-year`,
|
|
249
|
-
`year-of-era`, `second-of-minute`. (The `*-iso`/`*-us` variants are `temporal-extract`
|
|
250
|
-
operator modes, not field-option bucketing units.)
|
|
93
|
+
- Truncation: `minute`, `hour`, `day`, `week`, `month`, `quarter`, `year` (and `millisecond`, `second`).
|
|
94
|
+
- Extraction, an integer: `minute-of-hour`, `hour-of-day`, `day-of-week`, `day-of-month`, `day-of-year`, `week-of-year`, `month-of-year`, `quarter-of-year`, `year-of-era`, `second-of-minute`.
|
|
95
|
+
- `default` lets Metabase pick.
|
|
251
96
|
|
|
252
|
-
|
|
253
|
-
["field", { "temporal-unit": "month" }, 22]
|
|
254
|
-
```
|
|
97
|
+
## Field option: `binning`
|
|
255
98
|
|
|
256
|
-
|
|
99
|
+
On a numeric or coordinate field ref in `breakout`:
|
|
257
100
|
|
|
258
|
-
`
|
|
101
|
+
- `{"strategy": "num-bins", "num-bins": 10}`: equal-width bins.
|
|
102
|
+
- `{"strategy": "bin-width", "bin-width": 5}`: a fixed width.
|
|
103
|
+
- `{"strategy": "default"}`: Metabase picks.
|
|
259
104
|
|
|
260
|
-
|
|
261
|
-
| ----------- | -------------------- | -------------------------------- |
|
|
262
|
-
| `num-bins` | `num-bins` (integer) | fixed number of equal-width bins |
|
|
263
|
-
| `bin-width` | `bin-width` (number) | fixed bin width |
|
|
264
|
-
| `default` | — | Metabase chooses |
|
|
105
|
+
## References
|
|
265
106
|
|
|
266
|
-
|
|
267
|
-
["
|
|
268
|
-
|
|
107
|
+
- field: `["field", {…}, <field id>]`, or `["field", {"base-type": "type/…"}, "<column name>"]` for a previous stage's or a source card's column
|
|
108
|
+
- expression: `["expression", {}, "<expression name>"]`, same stage
|
|
109
|
+
- aggregation: `["aggregation", {}, "<lib/uuid>"]`, the `lib/uuid` (from `mb uuid`) set in the options of an aggregation of the same stage
|
|
@@ -8,7 +8,7 @@ allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
|
|
|
8
8
|
|
|
9
9
|
**Prefer a structured query.** Native SQL is a Metabase query whose single stage is raw SQL (`mbql.stage/native`) instead of structured MBQL (`mbql.stage/mbql`) — both are the same query envelope (`mbql`). Reach for a native stage only when a structured query genuinely can't express it — engine-specific functions, CTEs, window logic beyond `offset`, hairy hand-tuned SQL — or when the user asks for SQL. If you can write it as a structured stage, do.
|
|
10
10
|
|
|
11
|
-
General flag conventions, body-input precedence
|
|
11
|
+
General flag conventions, body-input precedence and `./.scratch` live in `core` (`mb skills get core`).
|
|
12
12
|
|
|
13
13
|
## The shape
|
|
14
14
|
|
|
@@ -28,13 +28,13 @@ A native `dataset_query` is a query with one **native stage** — the `lib/type:
|
|
|
28
28
|
}
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
This is the form a card stores and returns — author it. The CLI **pre-flight-validates** it — the envelope, the template-tag shapes, the field refs — through the usual `--print-schema → --dry-run → run` loop (`mbql`), and a saved card **round-trips** in exactly this shape: `mb card get <id> --full --json`, edit the `stages[0].native` string, send it straight back. Only the
|
|
31
|
+
This is the form a card stores and returns — author it. The CLI **pre-flight-validates** it — the envelope, the template-tag shapes, the field refs — through the usual `--print-schema → --dry-run → run` loop (`mbql`), and a saved card **round-trips** in exactly this shape: `mb card get <id> --full --json`, edit the `stages[0].native` string, send it straight back. Only the warehouse parses the SQL string, so a **SQL** syntax error surfaces when you run it, not at `--dry-run`. A parameterless query needs no `template-tags` — just the `native` string.
|
|
32
32
|
|
|
33
33
|
You may see an older flat form in cards created long ago — `{database, type:"native", native:{query}}`. The server still accepts it (it normalizes to the above) but it skips pre-flight and doesn't round-trip — **don't author it**.
|
|
34
34
|
|
|
35
35
|
## Parameters are template tags
|
|
36
36
|
|
|
37
|
-
Every `{{name}}` in the SQL must have a matching entry in the stage's `template-tags`, keyed by that name. **The three must agree exactly:** the `{{name}}` in SQL = the map key = the entry's `"name"` field. Names are case-sensitive (`{{Cat}}` ≠ `{{cat}}`). A `{{name}}` with no entry fails at run time; an unused entry is ignored.
|
|
37
|
+
Every `{{name}}` in the SQL must have a matching entry in the stage's `template-tags`, keyed by that name. **The three must agree exactly:** the `{{name}}` in SQL = the map key = the entry's `"name"` field. Names are case-sensitive (`{{Cat}}` ≠ `{{cat}}`). A `{{name}}` with no entry fails at run time; an unused entry is ignored. `--dry-run` and a run fail on a raw variable with no value or `default` outside an optional `[[ … ]]` clause, and on any `"required": true` tag with no value; a field filter with no value compiles to `1 = 1` and matches every row.
|
|
38
38
|
|
|
39
39
|
Four kinds of tag, by `type`:
|
|
40
40
|
|
|
@@ -45,7 +45,7 @@ Four kinds of tag, by `type`:
|
|
|
45
45
|
| **Snippet** | `snippet` | `{{snippet: Active Rows}}` | a reusable SQL fragment (`mb snippet`) |
|
|
46
46
|
| **Card reference** | `card` | `{{#42}}` or `{{#42-slug}}` | another saved query, as a subquery |
|
|
47
47
|
|
|
48
|
-
Give each tag an `id
|
|
48
|
+
Give each tag an `id`, unique among the tags; the tag's name serves. Wrap any clause that should be droppable when its value is empty in **`[[ … ]]`**, keyword and all: `[[AND {{status}}]]`, not `AND [[{{status}}]]`. Only one level of nesting; a query using several optional `[[AND …]]` blocks needs a real `WHERE` first (e.g. `WHERE true [[AND {{a}}]] [[AND {{b}}]]`).
|
|
49
49
|
|
|
50
50
|
## The decision that matters: field filter vs. raw variable
|
|
51
51
|
|
|
@@ -62,7 +62,7 @@ Field filters only bind to a **real, connected database column** — not an expr
|
|
|
62
62
|
|
|
63
63
|
```json
|
|
64
64
|
"status": {
|
|
65
|
-
"id": "
|
|
65
|
+
"id": "status",
|
|
66
66
|
"name": "status",
|
|
67
67
|
"display-name": "Status",
|
|
68
68
|
"type": "dimension",
|
|
@@ -71,7 +71,7 @@ Field filters only bind to a **real, connected database column** — not an expr
|
|
|
71
71
|
}
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
-
**`dimension` is a field ref: `["field", {options}, <field-id>]`** — options object **second**, id **third**, exactly the `mbql` rule.
|
|
74
|
+
**`dimension` is a field ref: `["field", {options}, <field-id>]`** — options object **second**, id **third**, exactly the `mbql` rule. Send `{}` for the options. The field id comes from `table get <id> --include fields`.
|
|
75
75
|
|
|
76
76
|
`widget-type` must suit the column's type and is a closed enum (same vocabulary as dashboard filter `type`): string ops (`string/=`, `string/!=`, `string/contains`, `string/starts-with`, …), number ops (`number/=`, `number/between`, `number/>=`, …), dates (`date/all-options`, `date/range`, `date/relative`, `date/month-year`, …), plus `category`, `id`, `boolean/=`, and the `location/*` set. Text column → a `string/*` or `category`; datetime → a `date/*`; numeric → a `number/*`. `date/all-options` is the most flexible date widget.
|
|
77
77
|
|
|
@@ -79,7 +79,7 @@ Field filters only bind to a **real, connected database column** — not an expr
|
|
|
79
79
|
|
|
80
80
|
```json
|
|
81
81
|
"min_total": {
|
|
82
|
-
"id": "
|
|
82
|
+
"id": "min_total",
|
|
83
83
|
"name": "min_total",
|
|
84
84
|
"display-name": "Minimum total",
|
|
85
85
|
"type": "number",
|
|
@@ -98,7 +98,7 @@ Snippet and card-reference bodies (and the full field list for every kind) are i
|
|
|
98
98
|
|
|
99
99
|
## Wiring, defaults, and running
|
|
100
100
|
|
|
101
|
-
**
|
|
101
|
+
**A tag's default is the tag's own `default`.** Metabase derives the card's `parameters` from the template tags; declare one in the card's `parameters` array (alongside `dataset_query`) only to give it a dropdown source, `values_source_type` (`static-list` / `card`). The declared parameter's `id` is the tag's `id`, and its `target` links back to the tag: `["dimension", ["template-tag", "status"]]` for a field filter, `["variable", ["template-tag", "min_total"]]` for a raw variable.
|
|
102
102
|
|
|
103
103
|
**Run a saved card with values** via `card query`, whose `--parameters` is a JSON array of `{type, target, value}` — same `target` grammar:
|
|
104
104
|
|
|
@@ -111,7 +111,6 @@ mb card query 12 --parameters '[{"type":"string/=","target":["dimension",["templ
|
|
|
111
111
|
## Don't
|
|
112
112
|
|
|
113
113
|
- Don't wrap a field filter in an operator (`WHERE col = {{ff}}`) — write it bare (`WHERE {{ff}}`).
|
|
114
|
-
- Don't write the field-filter `dimension` in the legacy `["field", id, null]` shape — use `["field", {}, id]` (options second).
|
|
115
114
|
- Don't author the flat `{type:"native", …}` form — send the native stage above.
|
|
116
115
|
- Don't use native SQL for DDL or multiple statements — the editor is read-only, single-statement; `CREATE`/`UPDATE`/`;`-chained SQL is unsupported. To materialize a table, use a `transform`.
|
|
117
116
|
- Don't expect `[[ ]]` to save you from a case/type mismatch — `WHERE plan = {{p}}` returns zero rows on a case-sensitive engine if the value's case is off; that's a value problem, not syntax.
|
|
@@ -4,13 +4,13 @@ Every template-tag body, the widget-type vocabulary, and the parameter-object sh
|
|
|
4
4
|
|
|
5
5
|
## Template-tag bodies by `type`
|
|
6
6
|
|
|
7
|
-
The `template-tags` value is a map keyed by tag name; each entry's `name` must equal its key and the `{{name}}` in the SQL. `id` is
|
|
7
|
+
The `template-tags` value is a map keyed by tag name; each entry's `name` must equal its key and the `{{name}}` in the SQL. `id` is any string unique among the tags; the tag's name serves.
|
|
8
8
|
|
|
9
9
|
### Raw variable — `text` / `number` / `date` / `boolean`
|
|
10
10
|
|
|
11
11
|
```json
|
|
12
12
|
"min_total": {
|
|
13
|
-
"id": "
|
|
13
|
+
"id": "min_total",
|
|
14
14
|
"name": "min_total",
|
|
15
15
|
"display-name": "Minimum total",
|
|
16
16
|
"type": "number",
|
|
@@ -24,7 +24,7 @@ The `template-tags` value is a map keyed by tag name; each entry's `name` must e
|
|
|
24
24
|
| `name` | ✓ | equals map key and `{{name}}` |
|
|
25
25
|
| `display-name` | ✓ | label shown in the widget |
|
|
26
26
|
| `type` | ✓ | `text` \| `number` \| `date` \| `boolean` |
|
|
27
|
-
| `id` |
|
|
27
|
+
| `id` | ✓ | unique among the tags; the tag's name |
|
|
28
28
|
| `required` | — | `true` blocks the run until a value is given |
|
|
29
29
|
| `default` | — | value used when none passed (string form) |
|
|
30
30
|
|
|
@@ -34,34 +34,31 @@ SQL: `{{min_total}}`, spliced literally — you write the operator (`total > {{m
|
|
|
34
34
|
|
|
35
35
|
```json
|
|
36
36
|
"status": {
|
|
37
|
-
"id": "
|
|
37
|
+
"id": "status",
|
|
38
38
|
"name": "status",
|
|
39
39
|
"display-name": "Status",
|
|
40
40
|
"type": "dimension",
|
|
41
41
|
"dimension": ["field", {}, 141],
|
|
42
|
-
"widget-type": "string/="
|
|
43
|
-
"default": null,
|
|
44
|
-
"options": null,
|
|
45
|
-
"alias": null
|
|
42
|
+
"widget-type": "string/="
|
|
46
43
|
}
|
|
47
44
|
```
|
|
48
45
|
|
|
49
|
-
| Field | Req | Notes
|
|
50
|
-
| ------------- | --- |
|
|
51
|
-
| `type` | ✓ | `"dimension"`
|
|
52
|
-
| `dimension` | ✓ | field ref `["field", {}, <id>]` — options object second, id third (the `mbql` rule)
|
|
53
|
-
| `widget-type` | ✓ | the widget/operator; must suit the column type (table below)
|
|
54
|
-
| `default` | — | e.g. a value, or a `["2024-01-01","2024-12-31"]` range
|
|
55
|
-
| `options` | — | filter options map (e.g. case sensitivity)
|
|
56
|
-
| `alias` | — | set when the column comes from an aliased table in the SQL
|
|
46
|
+
| Field | Req | Notes |
|
|
47
|
+
| ------------- | --- | ----------------------------------------------------------------------------------- |
|
|
48
|
+
| `type` | ✓ | `"dimension"` |
|
|
49
|
+
| `dimension` | ✓ | field ref `["field", {}, <id>]` — options object second, id third (the `mbql` rule) |
|
|
50
|
+
| `widget-type` | ✓ | the widget/operator; must suit the column type (table below) |
|
|
51
|
+
| `default` | — | e.g. a value, or a `["2024-01-01","2024-12-31"]` range |
|
|
52
|
+
| `options` | — | filter options map (e.g. case sensitivity) |
|
|
53
|
+
| `alias` | — | set when the column comes from an aliased table in the SQL |
|
|
57
54
|
|
|
58
|
-
SQL: bare — `WHERE {{status}}`. Never `WHERE status = {{status}}`.
|
|
55
|
+
SQL: bare — `WHERE {{status}}`. Never `WHERE status = {{status}}`.
|
|
59
56
|
|
|
60
57
|
### Snippet — `snippet`
|
|
61
58
|
|
|
62
59
|
```json
|
|
63
60
|
"snippet: Active Rows": {
|
|
64
|
-
"id": "
|
|
61
|
+
"id": "snippet: Active Rows",
|
|
65
62
|
"name": "snippet: Active Rows",
|
|
66
63
|
"display-name": "Snippet: Active Rows",
|
|
67
64
|
"type": "snippet",
|
|
@@ -76,7 +73,7 @@ SQL: `{{snippet: Active Rows}}`. Create/manage the fragment with `mb snippet` (`
|
|
|
76
73
|
|
|
77
74
|
```json
|
|
78
75
|
"#42": {
|
|
79
|
-
"id": "
|
|
76
|
+
"id": "#42",
|
|
80
77
|
"name": "#42",
|
|
81
78
|
"display-name": "#42",
|
|
82
79
|
"type": "card",
|
|
@@ -96,7 +93,7 @@ A niche type that references a warehouse table by id (`{type: "table", table-id:
|
|
|
96
93
|
|
|
97
94
|
### Temporal unit — `temporal-unit`
|
|
98
95
|
|
|
99
|
-
A widget that lets the viewer pick the time bucket (day/week/month/…) for a datetime column. Body mirrors a field filter (`dimension`
|
|
96
|
+
A widget that lets the viewer pick the time bucket (day/week/month/…) for a datetime column. Body mirrors a field filter (`dimension` field ref, optional `alias`) with `type: "temporal-unit"`.
|
|
100
97
|
|
|
101
98
|
## `widget-type` by column type
|
|
102
99
|
|
|
@@ -117,16 +114,15 @@ Closed enum — same vocabulary as a dashboard parameter `type`. Pick one whose
|
|
|
117
114
|
|
|
118
115
|
Same object, two contexts. `target` links the parameter to a template tag: `["dimension", ["template-tag", "<name>"]]` for a field filter, `["variable", ["template-tag", "<name>"]]` for a raw variable.
|
|
119
116
|
|
|
120
|
-
**Declared** — in the card's `parameters` array, to set a default
|
|
117
|
+
**Declared** — in the card's `parameters` array, to set a dropdown source. Its `id` is the tag's `id`; the default is the tag's `default`:
|
|
121
118
|
|
|
122
119
|
```json
|
|
123
120
|
{
|
|
124
|
-
"id": "
|
|
121
|
+
"id": "status",
|
|
125
122
|
"name": "status",
|
|
126
123
|
"slug": "status",
|
|
127
124
|
"type": "string/=",
|
|
128
125
|
"target": ["dimension", ["template-tag", "status"]],
|
|
129
|
-
"default": "active",
|
|
130
126
|
"values_source_type": "static-list",
|
|
131
127
|
"values_source_config": { "values": ["active", "churned", "trial"] }
|
|
132
128
|
}
|
|
@@ -160,14 +156,14 @@ What `mb card create --file` consumes:
|
|
|
160
156
|
"native": "SELECT status, count(*) FROM orders WHERE total > {{min_total}} [[AND {{status}}]] GROUP BY status",
|
|
161
157
|
"template-tags": {
|
|
162
158
|
"min_total": {
|
|
163
|
-
"id": "
|
|
159
|
+
"id": "min_total",
|
|
164
160
|
"name": "min_total",
|
|
165
161
|
"display-name": "Minimum total",
|
|
166
162
|
"type": "number",
|
|
167
163
|
"default": "0"
|
|
168
164
|
},
|
|
169
165
|
"status": {
|
|
170
|
-
"id": "
|
|
166
|
+
"id": "status",
|
|
171
167
|
"name": "status",
|
|
172
168
|
"display-name": "Status",
|
|
173
169
|
"type": "dimension",
|