@uwdata/mosaic-sql 0.2.0 → 0.3.2

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.
@@ -26,12 +26,16 @@ var Ref = class {
26
26
  const { table, column: column2 } = this;
27
27
  if (column2) {
28
28
  const col = column2.startsWith("*") ? column2 : `"${column2}"`;
29
- return `${table ? `"${table}".` : ""}${col}`;
29
+ return `${table ? `${quoteTableName(table)}.` : ""}${col}`;
30
30
  } else {
31
- return table ? `"${table}"` : "NULL";
31
+ return table ? quoteTableName(table) : "NULL";
32
32
  }
33
33
  }
34
34
  };
35
+ function quoteTableName(table) {
36
+ const pieces = table.split(".");
37
+ return pieces.map((p) => `"${p}"`).join(".");
38
+ }
35
39
  function isColumnRefFor(ref, name) {
36
40
  return ref instanceof Ref && ref.column === name;
37
41
  }
@@ -281,7 +285,7 @@ var isFinite = functionCall("ISFINITE");
281
285
  var isInfinite = functionCall("ISINF");
282
286
 
283
287
  // src/windows.js
284
- var WindowFunction = class extends SQLExpression {
288
+ var WindowFunction = class _WindowFunction extends SQLExpression {
285
289
  constructor(op, func, type, name, group = "", order = "", frame = "") {
286
290
  let expr;
287
291
  const noWindowParams = !(group || order || frame);
@@ -307,7 +311,7 @@ var WindowFunction = class extends SQLExpression {
307
311
  }
308
312
  over(name) {
309
313
  const { window: op, func, type, group, order, frame } = this;
310
- return new WindowFunction(op, func, type, name, group, order, frame);
314
+ return new _WindowFunction(op, func, type, name, group, order, frame);
311
315
  }
312
316
  partitionby(...expr) {
313
317
  const exprs = expr.flat().filter((x) => x).map(asColumn);
@@ -316,7 +320,7 @@ var WindowFunction = class extends SQLExpression {
316
320
  ...exprs
317
321
  );
318
322
  const { window: op, func, type, name, order, frame } = this;
319
- return new WindowFunction(op, func, type, name, group, order, frame);
323
+ return new _WindowFunction(op, func, type, name, group, order, frame);
320
324
  }
321
325
  orderby(...expr) {
322
326
  const exprs = expr.flat().filter((x) => x).map(asColumn);
@@ -325,17 +329,17 @@ var WindowFunction = class extends SQLExpression {
325
329
  ...exprs
326
330
  );
327
331
  const { window: op, func, type, name, group, frame } = this;
328
- return new WindowFunction(op, func, type, name, group, order, frame);
332
+ return new _WindowFunction(op, func, type, name, group, order, frame);
329
333
  }
330
334
  rows(expr) {
331
335
  const frame = windowFrame("ROWS", expr);
332
336
  const { window: op, func, type, name, group, order } = this;
333
- return new WindowFunction(op, func, type, name, group, order, frame);
337
+ return new _WindowFunction(op, func, type, name, group, order, frame);
334
338
  }
335
339
  range(expr) {
336
340
  const frame = windowFrame("RANGE", expr);
337
341
  const { window: op, func, type, name, group, order } = this;
338
- return new WindowFunction(op, func, type, name, group, order, frame);
342
+ return new _WindowFunction(op, func, type, name, group, order, frame);
339
343
  }
340
344
  };
341
345
  function windowFrame(type, frame) {
@@ -374,7 +378,7 @@ var nth_value = winf("NTH_VALUE");
374
378
  function agg(strings, ...exprs) {
375
379
  return sql(strings, ...exprs).annotate({ aggregate: true });
376
380
  }
377
- var AggregateFunction = class extends SQLExpression {
381
+ var AggregateFunction = class _AggregateFunction extends SQLExpression {
378
382
  constructor(op, args, type, isDistinct2, filter) {
379
383
  args = (args || []).map(asColumn);
380
384
  const { strings, exprs } = aggExpr(op, args, type, isDistinct2, filter);
@@ -392,15 +396,15 @@ var AggregateFunction = class extends SQLExpression {
392
396
  }
393
397
  distinct() {
394
398
  const { aggregate: op, args, type, filter } = this;
395
- return new AggregateFunction(op, args, type, true, filter);
399
+ return new _AggregateFunction(op, args, type, true, filter);
396
400
  }
397
401
  where(filter) {
398
402
  const { aggregate: op, args, type, isDistinct: isDistinct2 } = this;
399
- return new AggregateFunction(op, args, type, isDistinct2, filter);
403
+ return new _AggregateFunction(op, args, type, isDistinct2, filter);
400
404
  }
401
405
  window() {
402
406
  const { aggregate: op, args, type, isDistinct: isDistinct2 } = this;
403
- const func = new AggregateFunction(op, args, null, isDistinct2);
407
+ const func = new _AggregateFunction(op, args, null, isDistinct2);
404
408
  return new WindowFunction(op, func, type);
405
409
  }
406
410
  partitionby(...expr) {
@@ -515,15 +519,15 @@ var dateDay = (expr) => {
515
519
  };
516
520
 
517
521
  // src/Query.js
518
- var Query = class {
522
+ var Query = class _Query {
519
523
  static select(...expr) {
520
- return new Query().select(...expr);
524
+ return new _Query().select(...expr);
521
525
  }
522
526
  static from(...expr) {
523
- return new Query().from(...expr);
527
+ return new _Query().from(...expr);
524
528
  }
525
529
  static with(...expr) {
526
- return new Query().with(...expr);
530
+ return new _Query().with(...expr);
527
531
  }
528
532
  static union(...queries) {
529
533
  return new SetOperation("UNION", queries.flat());
@@ -551,7 +555,7 @@ var Query = class {
551
555
  };
552
556
  }
553
557
  clone() {
554
- const q = new Query();
558
+ const q = new _Query();
555
559
  q.query = { ...this.query };
556
560
  return q;
557
561
  }
@@ -649,7 +653,7 @@ var Query = class {
649
653
  } else {
650
654
  let spec = value;
651
655
  if (typeof value === "number") {
652
- spec = value > 0 && value < 1 ? { perc: 100 * value, method } : { rows: Math.round(value, method) };
656
+ spec = value > 0 && value < 1 ? { perc: 100 * value, method } : { rows: Math.round(value), method };
653
657
  }
654
658
  query.sample = spec;
655
659
  return this;
@@ -681,6 +685,10 @@ var Query = class {
681
685
  return this;
682
686
  }
683
687
  }
688
+ $groupby(...expr) {
689
+ this.query.groupby = [];
690
+ return this.groupby(...expr);
691
+ }
684
692
  having(...expr) {
685
693
  const { query } = this;
686
694
  if (expr.length === 0) {
@@ -837,14 +845,14 @@ var Query = class {
837
845
  return sql2.join(" ");
838
846
  }
839
847
  };
840
- var SetOperation = class {
848
+ var SetOperation = class _SetOperation {
841
849
  constructor(op, queries) {
842
850
  this.op = op;
843
851
  this.queries = queries.map((q) => q.clone());
844
852
  this.query = { orderby: [] };
845
853
  }
846
854
  clone() {
847
- const q = new SetOperation(this.op, this.queries);
855
+ const q = new _SetOperation(this.op, this.queries);
848
856
  q.query = { ...this.query };
849
857
  return q;
850
858
  }
@@ -909,43 +917,12 @@ function isDoubleQuoted(s) {
909
917
  }
910
918
 
911
919
  // src/load/create.js
912
- function create(name, query, options = {}) {
913
- const { temp, replace, type = "TABLE" } = options;
914
- const create2 = `CREATE${replace ? " OR REPLACE" : ""}`;
915
- const spec = `${temp ? "TEMP " : ""}${type}${replace ? "" : " IF NOT EXISTS"}`;
916
- return `${create2} ${spec} ${name} AS ${query}`;
917
- }
918
-
919
- // src/load/parameters.js
920
- function parameters(options) {
921
- return Object.entries(options).map(([key, value]) => {
922
- const t = typeof value;
923
- const v = t === "boolean" ? String(value) : t === "string" ? `'${value}'` : value;
924
- return `${key}=${v}`;
925
- }).join(", ");
926
- }
927
-
928
- // src/load/csv.js
929
- function loadCSV(tableName, fileName, options = {}) {
930
- const { select = ["*"], temp, replace, ...csvOptions } = options;
931
- const params = parameters({ auto_detect: true, sample_size: -1, ...csvOptions });
932
- const query = `SELECT ${select.join(", ")} FROM read_csv('${fileName}', ${params})`;
933
- return create(tableName, query, { temp, replace });
934
- }
935
-
936
- // src/load/json.js
937
- function loadJSON(tableName, fileName, options = {}) {
938
- const { select = ["*"], temp, replace, ...jsonOptions } = options;
939
- const params = parameters({ auto_detect: true, json_format: "auto", ...jsonOptions });
940
- const query = `SELECT ${select.join(", ")} FROM read_json('${fileName}', ${params})`;
941
- return create(tableName, query, { temp, replace });
942
- }
943
-
944
- // src/load/parquet.js
945
- function loadParquet(tableName, fileName, options = {}) {
946
- const { select = ["*"], ...tableOptions } = options;
947
- const query = `SELECT ${select.join(", ")} FROM read_parquet('${fileName}')`;
948
- return create(tableName, query, tableOptions);
920
+ function create(name, query, {
921
+ replace = false,
922
+ temp = true,
923
+ view = false
924
+ } = {}) {
925
+ return "CREATE" + (replace ? " OR REPLACE " : " ") + (temp ? "TEMP " : "") + (view ? "VIEW" : "TABLE") + (replace ? " " : " IF NOT EXISTS ") + name + " AS " + query;
949
926
  }
950
927
 
951
928
  // src/load/sql-from.js
@@ -969,6 +946,38 @@ function sqlFrom(data, {
969
946
  }
970
947
  return subq.join(" UNION ALL ");
971
948
  }
949
+
950
+ // src/load/load.js
951
+ function load(method, tableName, fileName, options = {}, defaults = {}) {
952
+ const { select = ["*"], where, view, temp, replace, ...file } = options;
953
+ const params = parameters({ ...defaults, ...file });
954
+ const read = `${method}('${fileName}'${params ? ", " + params : ""})`;
955
+ const filter = where ? ` WHERE ${where}` : "";
956
+ const query = `SELECT ${select.join(", ")} FROM ${read}${filter}`;
957
+ return create(tableName, query, { view, temp, replace });
958
+ }
959
+ function loadCSV(tableName, fileName, options) {
960
+ return load("read_csv", tableName, fileName, options, { auto_detect: true, sample_size: -1 });
961
+ }
962
+ function loadJSON(tableName, fileName, options) {
963
+ return load("read_json", tableName, fileName, options, { auto_detect: true, json_format: "auto" });
964
+ }
965
+ function loadParquet(tableName, fileName, options) {
966
+ return load("read_parquet", tableName, fileName, options);
967
+ }
968
+ function loadObjects(tableName, data, options = {}) {
969
+ const { select = ["*"], ...opt } = options;
970
+ const values = sqlFrom(data);
971
+ const query = select.length === 1 && select[0] === "*" ? values : `SELECT ${select} FROM ${values}`;
972
+ return create(tableName, query, opt);
973
+ }
974
+ function parameters(options) {
975
+ return Object.entries(options).map(([key, value]) => {
976
+ const t = typeof value;
977
+ const v = t === "boolean" ? String(value) : t === "string" ? `'${value}'` : value;
978
+ return `${key}=${v}`;
979
+ }).join(", ");
980
+ }
972
981
  export {
973
982
  Query,
974
983
  Ref,
@@ -1025,6 +1034,7 @@ export {
1025
1034
  literalToSQL,
1026
1035
  loadCSV,
1027
1036
  loadJSON,
1037
+ loadObjects,
1028
1038
  loadParquet,
1029
1039
  lower,
1030
1040
  lt,
@@ -1059,7 +1069,6 @@ export {
1059
1069
  row_number,
1060
1070
  skewness,
1061
1071
  sql,
1062
- sqlFrom,
1063
1072
  stddev,
1064
1073
  stddevPop,
1065
1074
  stringAgg,
@@ -1 +1 @@
1
- var y=class{constructor(t,e){t&&(this.table=String(t)),e&&(this.column=e)}get columns(){return this.column?[this.column]:[]}toString(){let{table:t,column:e}=this;if(e){let n=e.startsWith("*")?e:`"${e}"`;return`${t?`"${t}".`:""}${n}`}else return t?`"${t}"`:"NULL"}};function X(r,t){return r instanceof y&&r.column===t}function l(r){return typeof r=="string"?W(r):r}function D(r){return typeof r=="string"?V(r):r}function V(r){return new y(r)}function W(r,t){return arguments.length===1&&(t=r,r=null),new y(r,t)}function tt(r){return new y(r,"*")}function et(r){return typeof r=="string"?`"${r}"`:d(r)}function d(r){switch(typeof r){case"boolean":return r?"TRUE":"FALSE";case"string":return`'${r}'`;case"number":return Number.isFinite(r)?String(r):"NULL";default:if(r==null)return"NULL";if(r instanceof Date){let t=+r;if(Number.isNaN(t))return"NULL";let e=r.getUTCFullYear(),n=r.getUTCMonth(),o=r.getUTCDate();return t===Date.UTC(e,n,o)?`MAKE_DATE(${e}, ${n+1}, ${o})`:`EPOCH_MS(${t})`}else return r instanceof RegExp?`'${r.source}'`:String(r)}}var b=r=>typeof r?.addEventListener=="function";function M(r){return r instanceof A}var A=class{constructor(t,e,n){this._expr=Array.isArray(t)?t:[t],this._deps=e||[],this.annotate(n);let o=this._expr.filter(s=>b(s));o.length>0?(this._params=Array.from(new Set(o)),this._params.forEach(s=>{s.addEventListener("value",()=>rt(this,this.map?.get("value")))})):this.addEventListener=void 0}get value(){return this}get columns(){let{_params:t,_deps:e}=this;if(t){let n=new Set(t.flatMap(o=>{let s=o.value?.columns;return Array.isArray(s)?s:[]}));if(n.size){let o=new Set(e);return n.forEach(s=>o.add(s)),Array.from(o)}}return e}get column(){return this._deps.length?this._deps[0]:this.columns[0]}annotate(...t){return Object.assign(this,...t)}toString(){return this._expr.map(t=>b(t)&&!M(t)?d(t.value):t).join("")}addEventListener(t,e){let n=this.map||(this.map=new Map);(n.get(t)||(n.set(t,new Set),n.get(t))).add(e)}};function rt(r,t){if(t?.size)return Promise.allSettled(Array.from(t,e=>e(r)))}function Y(r,t){let e=[r[0]],n=new Set,o=t.length;for(let s=0,i=0;s<o;){let c=t[s];b(c)?e[++i]=c:(Array.isArray(c?.columns)&&c.columns.forEach(x=>n.add(x)),e[i]+=typeof c=="string"?c:d(c));let p=r[++s];b(e[i])?e[++i]=p:e[i]+=p}return{spans:e,cols:Array.from(n)}}function u(r,...t){let{spans:e,cols:n}=Y(r,t);return new A(e,n)}function nt(r){let t=l(r);return u`${t} DESC NULLS LAST`.annotate({label:t?.label,desc:!0})}var ot=r=>({value:r,toString:()=>d(r)});function C(r){r(this.op,this),this.children?.forEach(t=>t.visit(r))}function Q(r,t){let e=t.filter(o=>o!=null).map(l),n=e.map((o,s)=>s?` ${r} `:"");return t.length&&n.push(""),u(n,...e).annotate({op:r,children:e,visit:C})}var st=(...r)=>Q("AND",r.flat()),it=(...r)=>Q("OR",r.flat()),ct=r=>t=>u`(${r} ${l(t)})`.annotate({op:r,a:t,visit:C}),at=ct("NOT"),k=r=>t=>u`(${l(t)} ${r})`.annotate({op:r,a:t,visit:C}),ut=k("IS NULL"),lt=k("IS NOT NULL"),T=r=>(t,e)=>u`(${l(t)} ${r} ${l(e)})`.annotate({op:r,a:t,b:e,visit:C}),pt=T("="),ft=T("<>"),mt=T("<"),ht=T(">"),gt=T("<="),xt=T(">="),Et=T("IS DISTINCT FROM"),dt=T("IS NOT DISTINCT FROM");function v(r,t,e,n){t=l(t);let o=r.startsWith("NOT ")?"NOT ":"";return(e?n?u`${o}(${e[0]} <= ${t} AND ${t} < ${e[1]})`:u`(${t} ${r} ${e[0]} AND ${e[1]})`:u``).annotate({op:r,visit:C,field:t,range:e})}var $t=(r,t,e)=>v("BETWEEN",r,t,e),Nt=(r,t,e)=>v("NOT BETWEEN",r,t,e);function q(r,t){return Array.from({length:r},()=>t)}function g(r,t){return(...e)=>{let n=e.map(l),o=t?`::${t}`:"";return(n.length?u([`${r}(`,...q(n.length-1,", "),`)${o}`],...n):u`${r}()${o}`).annotate({func:r,args:n})}}var yt=g("REGEXP_MATCHES"),St=g("CONTAINS"),wt=g("PREFIX"),Rt=g("SUFFIX"),At=g("LOWER"),Tt=g("UPPER"),bt=g("LENGTH"),qt=g("ISNAN"),Lt=g("ISFINITE"),Ot=g("ISINF");var $=class extends A{constructor(t,e,n,o,s="",i="",c=""){let p;if(o&&!(s||i||c))p=o?u`${e} OVER "${o}"`:u`${e} OVER ()`;else{let P=s&&i?" ":"",U=(s||i)&&c?" ":"";p=u`${e} OVER (${o?`"${o}" `:""}${s}${P}${i}${U}${c})`}n&&(p=u`(${p})::${n}`);let{_expr:R,_deps:_}=p;super(R,_,{window:t,func:e,type:n,name:o,group:s,order:i,frame:c})}get basis(){return this.column}get label(){let{func:t}=this;return t.label??t.toString()}over(t){let{window:e,func:n,type:o,group:s,order:i,frame:c}=this;return new $(e,n,o,t,s,i,c)}partitionby(...t){let e=t.flat().filter(R=>R).map(l),n=u(["PARTITION BY ",q(e.length-1,", "),""],...e),{window:o,func:s,type:i,name:c,order:p,frame:x}=this;return new $(o,s,i,c,n,p,x)}orderby(...t){let e=t.flat().filter(R=>R).map(l),n=u(["ORDER BY ",q(e.length-1,", "),""],...e),{window:o,func:s,type:i,name:c,group:p,frame:x}=this;return new $(o,s,i,c,p,n,x)}rows(t){let e=H("ROWS",t),{window:n,func:o,type:s,name:i,group:c,order:p}=this;return new $(n,o,s,i,c,p,e)}range(t){let e=H("RANGE",t),{window:n,func:o,type:s,name:i,group:c,order:p}=this;return new $(n,o,s,i,c,p,e)}};function H(r,t){if(b(t)){let e=u`${t}`;return e.toString=()=>`${r} ${K(t.value)}`,e}return`${r} ${K(t)}`}function K(r){let[t,e]=r,n=t===0?"CURRENT ROW":Number.isFinite(t)?`${Math.abs(t)} PRECEDING`:"UNBOUNDED PRECEDING",o=e===0?"CURRENT ROW":Number.isFinite(e)?`${Math.abs(e)} FOLLOWING`:"UNBOUNDED FOLLOWING";return`BETWEEN ${n} AND ${o}`}function N(r,t){return(...e)=>{let n=g(r)(...e);return new $(r,n,t)}}var It=N("ROW_NUMBER","INTEGER"),Dt=N("RANK","INTEGER"),Ct=N("DENSE_RANK","INTEGER"),_t=N("PERCENT_RANK"),Pt=N("CUME_DIST"),Ut=N("NTILE"),Mt=N("LAG"),Ft=N("LEAD"),Gt=N("FIRST_VALUE"),jt=N("LAST_VALUE"),Yt=N("NTH_VALUE");function Bt(r,...t){return u(r,...t).annotate({aggregate:!0})}var L=class extends A{constructor(t,e,n,o,s){e=(e||[]).map(l);let{strings:i,exprs:c}=Xt(t,e,n,o,s),{spans:p,cols:x}=Y(i,c);super(p,x,{aggregate:t,args:e,type:n,isDistinct:o,filter:s})}get basis(){return this.column}get label(){let{aggregate:t,args:e,isDistinct:n}=this,o=n?"DISTINCT"+(e.length?" ":""):"",s=e.length?`(${o}${e.map(Vt).join(", ")})`:"";return`${t.toLowerCase()}${s}`}distinct(){let{aggregate:t,args:e,type:n,filter:o}=this;return new L(t,e,n,!0,o)}where(t){let{aggregate:e,args:n,type:o,isDistinct:s}=this;return new L(e,n,o,s,t)}window(){let{aggregate:t,args:e,type:n,isDistinct:o}=this,s=new L(t,e,null,o);return new $(t,s,n)}partitionby(...t){return this.window().partitionby(...t)}orderby(...t){return this.window().orderby(...t)}rows(t,e){return this.window().rows(t,e)}range(t,e){return this.window().range(t,e)}};function Xt(r,t,e,n,o){let s=`)${e?`::${e}`:""}`,i=[`${r}(${n?"DISTINCT ":""}`],c=[];return t.length?(i=i.concat([...q(t.length-1,", "),`${s}${o?" FILTER (WHERE ":""}`,...o?[")"]:[]]),c=[...t,...o?[o]:[]]):i[0]+="*"+s,{exprs:c,strings:i}}function Vt(r){let t=d(r);return t&&t.startsWith('"')&&t.endsWith('"')?t.slice(1,-1):t}function a(r,t){return(...e)=>new L(r,e,t)}var Wt=a("COUNT","INTEGER"),Qt=a("AVG"),kt=a("AVG"),vt=a("MAD"),Ht=a("MAX"),Kt=a("MIN"),zt=a("SUM","DOUBLE"),Jt=a("PRODUCT"),Zt=a("MEDIAN"),te=a("QUANTILE"),ee=a("MODE"),re=a("VARIANCE"),ne=a("STDDEV"),oe=a("SKEWNESS"),se=a("KURTOSIS"),ie=a("ENTROPY"),ce=a("VAR_POP"),ae=a("STDDEV_POP"),ue=a("CORR"),le=a("COVAR_POP"),pe=a("REGR_INTERCEPT"),fe=a("REGR_SLOPE"),me=a("REGR_COUNT"),he=a("REGR_R2"),ge=a("REGR_SYY"),xe=a("REGR_SXX"),Ee=a("REGR_SXY"),de=a("REGR_AVGX"),$e=a("REGR_AVGY"),Ne=a("FIRST"),ye=a("LAST"),Se=a("ARG_MIN"),we=a("ARG_MAX"),Re=a("STRING_AGG"),Ae=a("ARRAY_AGG");function B(r,t){let e=l(r),n=u`CAST(${e} AS ${t})`;return Object.defineProperty(n,"label",{enumerable:!0,get(){return r.label}}),Object.defineProperty(n,"aggregate",{enumerable:!0,get(){return r.aggregate||!1}}),n}var Te=r=>B(r,"DOUBLE"),be=r=>B(r,"INTEGER");var qe=r=>{let t=l(r);return u`(1000 * (epoch(${t}) - second(${t})) + millisecond(${t}))::DOUBLE`},Le=r=>{let t=l(r);return u`MAKE_DATE(2012, MONTH(${t}), 1)`.annotate({label:"month"})},Oe=r=>{let t=l(r);return u`MAKE_DATE(2012, MONTH(${t}), DAY(${t}))`.annotate({label:"date"})},Ie=r=>{let t=l(r);return u`MAKE_DATE(2012, 1, DAY(${t}))`.annotate({label:"date"})};var S=class{static select(...t){return new S().select(...t)}static from(...t){return new S().from(...t)}static with(...t){return new S().with(...t)}static union(...t){return new w("UNION",t.flat())}static unionAll(...t){return new w("UNION ALL",t.flat())}static intersect(...t){return new w("INTERSECT",t.flat())}static except(...t){return new w("EXCEPT",t.flat())}constructor(){this.query={with:[],select:[],from:[],where:[],groupby:[],having:[],window:[],qualify:[],orderby:[]}}clone(){let t=new S;return t.query={...this.query},t}with(...t){let{query:e}=this;if(t.length===0)return e.with;{let n=[],o=(s,i)=>{let c=i.clone();c.cteFor=this,n.push({as:s,query:c})};return t.flat().forEach(s=>{if(s!=null)if(s.as&&s.query)o(s.as,s.query);else for(let i in s)o(i,s[i])}),e.with=e.with.concat(n),this}}select(...t){let{query:e}=this;if(t.length===0)return e.select;{let n=[];for(let o of t.flat())if(o!=null)if(typeof o=="string")n.push({as:o,expr:l(o)});else if(o instanceof y)n.push({as:o.column,expr:o});else if(Array.isArray(o))n.push({as:o[0],expr:o[1]});else for(let s in o)n.push({as:F(s),expr:l(o[s])});return e.select=e.select.concat(n),this}}$select(...t){return this.query.select=[],this.select(...t)}distinct(t=!0){return this.query.distinct=!!t,this}from(...t){let{query:e}=this;if(t.length===0)return e.from;{let n=[];return t.flat().forEach(o=>{if(o!=null)if(typeof o=="string")n.push({as:o,from:D(o)});else if(o instanceof y)n.push({as:o.table,from:o});else if(G(o)||M(o))n.push({from:o});else if(Array.isArray(o))n.push({as:F(o[0]),from:D(o[1])});else for(let s in o)n.push({as:F(s),from:D(o[s])})}),e.from=e.from.concat(n),this}}$from(...t){return this.query.from=[],this.from(...t)}sample(t,e){let{query:n}=this;if(arguments.length===0)return n.sample;{let o=t;return typeof t=="number"&&(o=t>0&&t<1?{perc:100*t,method:e}:{rows:Math.round(t,e)}),n.sample=o,this}}where(...t){let{query:e}=this;return t.length===0?e.where:(e.where=e.where.concat(t.flat().filter(n=>n)),this)}$where(...t){return this.query.where=[],this.where(...t)}groupby(...t){let{query:e}=this;return t.length===0?e.groupby:(e.groupby=e.groupby.concat(t.flat().filter(n=>n).map(l)),this)}having(...t){let{query:e}=this;return t.length===0?e.having:(e.having=e.having.concat(t.flat().filter(n=>n)),this)}window(...t){let{query:e}=this;if(t.length===0)return e.window;{let n=[];return t.flat().forEach(o=>{if(o!=null)for(let s in o)n.push({as:F(s),expr:o[s]})}),e.window=e.window.concat(n),this}}qualify(...t){let{query:e}=this;return t.length===0?e.qualify:(e.qualify=e.qualify.concat(t.flat().filter(n=>n)),this)}orderby(...t){let{query:e}=this;return t.length===0?e.orderby:(e.orderby=e.orderby.concat(t.flat().filter(n=>n).map(l)),this)}limit(t){let{query:e}=this;return arguments.length===0?e.limit:(e.limit=Number.isFinite(t)?t:void 0,this)}offset(t){let{query:e}=this;return arguments.length===0?e.offset:(e.offset=Number.isFinite(t)?t:void 0,this)}get subqueries(){let{query:t,cteFor:e}=this,o=(e?.query||t).with?.reduce((i,{as:c,query:p})=>(i[c]=p,i),{}),s=[];return t.from.forEach(({from:i})=>{if(G(i))s.push(i);else if(o[i.table]){let c=o[i.table];s.push(c)}}),s}toString(){let{select:t,distinct:e,from:n,sample:o,where:s,groupby:i,having:c,window:p,qualify:x,orderby:R,limit:_,offset:P,with:U}=this.query,h=[];if(U.length){let f=U.map(({as:m,query:E})=>`"${m}" AS (${E})`);h.push(`WITH ${f.join(", ")}`)}let z=t.map(({as:f,expr:m})=>X(m,f)&&!m.table?`${m}`:`${m} AS "${f}"`);if(h.push(`SELECT${e?" DISTINCT":""} ${z.join(", ")}`),n.length){let f=n.map(({as:m,from:E})=>{let I=G(E)?`(${E})`:`${E}`;return!m||m===E.table?I:`${I} AS "${m}"`});h.push(`FROM ${f.join(", ")}`)}if(s.length){let f=s.map(String).filter(m=>m).join(" AND ");f&&h.push(`WHERE ${f}`)}if(o){let{rows:f,perc:m,method:E,seed:I}=o,J=f?`${f} ROWS`:`${m} PERCENT`,Z=E?` (${E}${I!=null?`, ${I}`:""})`:"";h.push(`USING SAMPLE ${J}${Z}`)}if(i.length&&h.push(`GROUP BY ${i.join(", ")}`),c.length){let f=c.map(String).filter(m=>m).join(" AND ");f&&h.push(`HAVING ${f}`)}if(p.length){let f=p.map(({as:m,expr:E})=>`"${m}" AS (${E})`);h.push(`WINDOW ${f.join(", ")}`)}if(x.length){let f=x.map(String).filter(m=>m).join(" AND ");f&&h.push(`QUALIFY ${f}`)}return R.length&&h.push(`ORDER BY ${R.join(", ")}`),Number.isFinite(_)&&h.push(`LIMIT ${_}`),Number.isFinite(P)&&h.push(`OFFSET ${P}`),h.join(" ")}},w=class{constructor(t,e){this.op=t,this.queries=e.map(n=>n.clone()),this.query={orderby:[]}}clone(){let t=new w(this.op,this.queries);return t.query={...this.query},t}orderby(...t){let{query:e}=this;return t.length===0?e.orderby:(e.orderby=e.orderby.concat(t.flat().filter(n=>n).map(l)),this)}limit(t){let{query:e}=this;return arguments.length===0?e.limit:(e.limit=Number.isFinite(t)?t:void 0,this)}offset(t){let{query:e}=this;return arguments.length===0?e.offset:(e.offset=Number.isFinite(t)?t:void 0,this)}get subqueries(){let{queries:t,cteFor:e}=this;return e&&t.forEach(n=>n.cteFor=e),t}toString(){let{op:t,queries:e,query:{orderby:n,limit:o,offset:s}}=this,i=[e.join(` ${t} `)];return n.length&&i.push(`ORDER BY ${n.join(", ")}`),Number.isFinite(o)&&i.push(`LIMIT ${o}`),Number.isFinite(s)&&i.push(`OFFSET ${s}`),i.join(" ")}};function G(r){return r instanceof S||r instanceof w}function F(r){return De(r)?r.slice(1,-1):r}function De(r){return r[0]==='"'&&r[r.length-1]==='"'}function O(r,t,e={}){let{temp:n,replace:o,type:s="TABLE"}=e,i=`CREATE${o?" OR REPLACE":""}`,c=`${n?"TEMP ":""}${s}${o?"":" IF NOT EXISTS"}`;return`${i} ${c} ${r} AS ${t}`}function j(r){return Object.entries(r).map(([t,e])=>{let n=typeof e,o=n==="boolean"?String(e):n==="string"?`'${e}'`:e;return`${t}=${o}`}).join(", ")}function Ce(r,t,e={}){let{select:n=["*"],temp:o,replace:s,...i}=e,c=j({auto_detect:!0,sample_size:-1,...i}),p=`SELECT ${n.join(", ")} FROM read_csv('${t}', ${c})`;return O(r,p,{temp:o,replace:s})}function _e(r,t,e={}){let{select:n=["*"],temp:o,replace:s,...i}=e,c=j({auto_detect:!0,json_format:"auto",...i}),p=`SELECT ${n.join(", ")} FROM read_json('${t}', ${c})`;return O(r,p,{temp:o,replace:s})}function Pe(r,t,e={}){let{select:n=["*"],...o}=e,s=`SELECT ${n.join(", ")} FROM read_parquet('${t}')`;return O(r,s,o)}function Ue(r,{columns:t=Object.keys(r?.[0]||{})}={}){let e=[];if(Array.isArray(t)?(e=t,t=e.reduce((o,s)=>(o[s]=s,o),{})):t&&(e=Object.keys(t)),!e.length)throw new Error("Can not create table from empty column set.");let n=[];for(let o of r){let s=e.map(i=>`${d(o[i])} AS "${t[i]}"`);n.push(`(SELECT ${s.join(", ")})`)}return n.join(" UNION ALL ")}export{S as Query,y as Ref,Bt as agg,tt as all,st as and,we as argmax,Se as argmin,Ae as arrayAgg,l as asColumn,D as asRelation,Qt as avg,B as cast,Te as castDouble,be as castInteger,W as column,St as contains,ue as corr,Wt as count,le as covarPop,O as create,Pt as cume_dist,Ie as dateDay,Le as dateMonth,Oe as dateMonthDay,Ct as dense_rank,nt as desc,ie as entropy,qe as epoch_ms,pt as eq,Ne as first,Gt as first_value,ht as gt,xt as gte,$t as isBetween,Et as isDistinct,Lt as isFinite,Ot as isInfinite,qt as isNaN,Nt as isNotBetween,dt as isNotDistinct,lt as isNotNull,ut as isNull,b as isParamLike,G as isQuery,M as isSQLExpression,se as kurtosis,Mt as lag,ye as last,jt as last_value,Ft as lead,bt as length,ot as literal,d as literalToSQL,Ce as loadCSV,_e as loadJSON,Pe as loadParquet,At as lower,mt as lt,gt as lte,vt as mad,Ht as max,kt as mean,Zt as median,Kt as min,ee as mode,ft as neq,at as not,Yt as nth_value,Ut as ntile,it as or,_t as percent_rank,wt as prefix,Jt as product,te as quantile,Dt as rank,yt as regexp_matches,de as regrAvgX,$e as regrAvgY,me as regrCount,pe as regrIntercept,he as regrR2,xe as regrSXX,Ee as regrSXY,ge as regrSYY,fe as regrSlope,V as relation,It as row_number,oe as skewness,u as sql,Ue as sqlFrom,ne as stddev,ae as stddevPop,Re as stringAgg,Rt as suffix,zt as sum,et as toSQL,Tt as upper,ce as varPop,re as variance};
1
+ var y=class{constructor(t,e){t&&(this.table=String(t)),e&&(this.column=e)}get columns(){return this.column?[this.column]:[]}toString(){let{table:t,column:e}=this;if(e){let n=e.startsWith("*")?e:`"${e}"`;return`${t?`${Q(t)}.`:""}${n}`}else return t?Q(t):"NULL"}};function Q(r){return r.split(".").map(e=>`"${e}"`).join(".")}function B(r,t){return r instanceof y&&r.column===t}function l(r){return typeof r=="string"?X(r):r}function I(r){return typeof r=="string"?V(r):r}function V(r){return new y(r)}function X(r,t){return arguments.length===1&&(t=r,r=null),new y(r,t)}function rt(r){return new y(r,"*")}function nt(r){return typeof r=="string"?`"${r}"`:E(r)}function E(r){switch(typeof r){case"boolean":return r?"TRUE":"FALSE";case"string":return`'${r}'`;case"number":return Number.isFinite(r)?String(r):"NULL";default:if(r==null)return"NULL";if(r instanceof Date){let t=+r;if(Number.isNaN(t))return"NULL";let e=r.getUTCFullYear(),n=r.getUTCMonth(),o=r.getUTCDate();return t===Date.UTC(e,n,o)?`MAKE_DATE(${e}, ${n+1}, ${o})`:`EPOCH_MS(${t})`}else return r instanceof RegExp?`'${r.source}'`:String(r)}}var A=r=>typeof r?.addEventListener=="function";function _(r){return r instanceof w}var w=class{constructor(t,e,n){this._expr=Array.isArray(t)?t:[t],this._deps=e||[],this.annotate(n);let o=this._expr.filter(s=>A(s));o.length>0?(this._params=Array.from(new Set(o)),this._params.forEach(s=>{s.addEventListener("value",()=>ot(this,this.map?.get("value")))})):this.addEventListener=void 0}get value(){return this}get columns(){let{_params:t,_deps:e}=this;if(t){let n=new Set(t.flatMap(o=>{let s=o.value?.columns;return Array.isArray(s)?s:[]}));if(n.size){let o=new Set(e);return n.forEach(s=>o.add(s)),Array.from(o)}}return e}get column(){return this._deps.length?this._deps[0]:this.columns[0]}annotate(...t){return Object.assign(this,...t)}toString(){return this._expr.map(t=>A(t)&&!_(t)?E(t.value):t).join("")}addEventListener(t,e){let n=this.map||(this.map=new Map);(n.get(t)||(n.set(t,new Set),n.get(t))).add(e)}};function ot(r,t){if(t?.size)return Promise.allSettled(Array.from(t,e=>e(r)))}function G(r,t){let e=[r[0]],n=new Set,o=t.length;for(let s=0,i=0;s<o;){let c=t[s];A(c)?e[++i]=c:(Array.isArray(c?.columns)&&c.columns.forEach(g=>n.add(g)),e[i]+=typeof c=="string"?c:E(c));let p=r[++s];A(e[i])?e[++i]=p:e[i]+=p}return{spans:e,cols:Array.from(n)}}function a(r,...t){let{spans:e,cols:n}=G(r,t);return new w(e,n)}function st(r){let t=l(r);return a`${t} DESC NULLS LAST`.annotate({label:t?.label,desc:!0})}var it=r=>({value:r,toString:()=>E(r)});function D(r){r(this.op,this),this.children?.forEach(t=>t.visit(r))}function k(r,t){let e=t.filter(o=>o!=null).map(l),n=e.map((o,s)=>s?` ${r} `:"");return t.length&&n.push(""),a(n,...e).annotate({op:r,children:e,visit:D})}var ct=(...r)=>k("AND",r.flat()),ut=(...r)=>k("OR",r.flat()),at=r=>t=>a`(${r} ${l(t)})`.annotate({op:r,a:t,visit:D}),lt=at("NOT"),v=r=>t=>a`(${l(t)} ${r})`.annotate({op:r,a:t,visit:D}),pt=v("IS NULL"),ft=v("IS NOT NULL"),S=r=>(t,e)=>a`(${l(t)} ${r} ${l(e)})`.annotate({op:r,a:t,b:e,visit:D}),ht=S("="),mt=S("<>"),gt=S("<"),xt=S(">"),dt=S("<="),Et=S(">="),$t=S("IS DISTINCT FROM"),Nt=S("IS NOT DISTINCT FROM");function H(r,t,e,n){t=l(t);let o=r.startsWith("NOT ")?"NOT ":"";return(e?n?a`${o}(${e[0]} <= ${t} AND ${t} < ${e[1]})`:a`(${t} ${r} ${e[0]} AND ${e[1]})`:a``).annotate({op:r,visit:D,field:t,range:e})}var yt=(r,t,e)=>H("BETWEEN",r,t,e),wt=(r,t,e)=>H("NOT BETWEEN",r,t,e);function T(r,t){return Array.from({length:r},()=>t)}function x(r,t){return(...e)=>{let n=e.map(l),o=t?`::${t}`:"";return(n.length?a([`${r}(`,...T(n.length-1,", "),`)${o}`],...n):a`${r}()${o}`).annotate({func:r,args:n})}}var St=x("REGEXP_MATCHES"),Rt=x("CONTAINS"),At=x("PREFIX"),Tt=x("SUFFIX"),bt=x("LOWER"),qt=x("UPPER"),Lt=x("LENGTH"),Ot=x("ISNAN"),It=x("ISFINITE"),Dt=x("ISINF");var C=class r extends w{constructor(t,e,n,o,s="",i="",c=""){let p;if(o&&!(s||i||c))p=o?a`${e} OVER "${o}"`:a`${e} OVER ()`;else{let q=s&&i?" ":"",L=(s||i)&&c?" ":"";p=a`${e} OVER (${o?`"${o}" `:""}${s}${q}${i}${L}${c})`}n&&(p=a`(${p})::${n}`);let{_expr:N,_deps:R}=p;super(N,R,{window:t,func:e,type:n,name:o,group:s,order:i,frame:c})}get basis(){return this.column}get label(){let{func:t}=this;return t.label??t.toString()}over(t){let{window:e,func:n,type:o,group:s,order:i,frame:c}=this;return new r(e,n,o,t,s,i,c)}partitionby(...t){let e=t.flat().filter(N=>N).map(l),n=a(["PARTITION BY ",T(e.length-1,", "),""],...e),{window:o,func:s,type:i,name:c,order:p,frame:g}=this;return new r(o,s,i,c,n,p,g)}orderby(...t){let e=t.flat().filter(N=>N).map(l),n=a(["ORDER BY ",T(e.length-1,", "),""],...e),{window:o,func:s,type:i,name:c,group:p,frame:g}=this;return new r(o,s,i,c,p,n,g)}rows(t){let e=K("ROWS",t),{window:n,func:o,type:s,name:i,group:c,order:p}=this;return new r(n,o,s,i,c,p,e)}range(t){let e=K("RANGE",t),{window:n,func:o,type:s,name:i,group:c,order:p}=this;return new r(n,o,s,i,c,p,e)}};function K(r,t){if(A(t)){let e=a`${t}`;return e.toString=()=>`${r} ${z(t.value)}`,e}return`${r} ${z(t)}`}function z(r){let[t,e]=r,n=t===0?"CURRENT ROW":Number.isFinite(t)?`${Math.abs(t)} PRECEDING`:"UNBOUNDED PRECEDING",o=e===0?"CURRENT ROW":Number.isFinite(e)?`${Math.abs(e)} FOLLOWING`:"UNBOUNDED FOLLOWING";return`BETWEEN ${n} AND ${o}`}function $(r,t){return(...e)=>{let n=x(r)(...e);return new C(r,n,t)}}var Ct=$("ROW_NUMBER","INTEGER"),_t=$("RANK","INTEGER"),Ft=$("DENSE_RANK","INTEGER"),Pt=$("PERCENT_RANK"),Ut=$("CUME_DIST"),Mt=$("NTILE"),Gt=$("LAG"),jt=$("LEAD"),Wt=$("FIRST_VALUE"),Yt=$("LAST_VALUE"),Qt=$("NTH_VALUE");function Bt(r,...t){return a(r,...t).annotate({aggregate:!0})}var j=class r extends w{constructor(t,e,n,o,s){e=(e||[]).map(l);let{strings:i,exprs:c}=Vt(t,e,n,o,s),{spans:p,cols:g}=G(i,c);super(p,g,{aggregate:t,args:e,type:n,isDistinct:o,filter:s})}get basis(){return this.column}get label(){let{aggregate:t,args:e,isDistinct:n}=this,o=n?"DISTINCT"+(e.length?" ":""):"",s=e.length?`(${o}${e.map(Xt).join(", ")})`:"";return`${t.toLowerCase()}${s}`}distinct(){let{aggregate:t,args:e,type:n,filter:o}=this;return new r(t,e,n,!0,o)}where(t){let{aggregate:e,args:n,type:o,isDistinct:s}=this;return new r(e,n,o,s,t)}window(){let{aggregate:t,args:e,type:n,isDistinct:o}=this,s=new r(t,e,null,o);return new C(t,s,n)}partitionby(...t){return this.window().partitionby(...t)}orderby(...t){return this.window().orderby(...t)}rows(t,e){return this.window().rows(t,e)}range(t,e){return this.window().range(t,e)}};function Vt(r,t,e,n,o){let s=`)${e?`::${e}`:""}`,i=[`${r}(${n?"DISTINCT ":""}`],c=[];return t.length?(i=i.concat([...T(t.length-1,", "),`${s}${o?" FILTER (WHERE ":""}`,...o?[")"]:[]]),c=[...t,...o?[o]:[]]):i[0]+="*"+s,{exprs:c,strings:i}}function Xt(r){let t=E(r);return t&&t.startsWith('"')&&t.endsWith('"')?t.slice(1,-1):t}function u(r,t){return(...e)=>new j(r,e,t)}var kt=u("COUNT","INTEGER"),vt=u("AVG"),Ht=u("AVG"),Kt=u("MAD"),zt=u("MAX"),Jt=u("MIN"),Zt=u("SUM","DOUBLE"),te=u("PRODUCT"),ee=u("MEDIAN"),re=u("QUANTILE"),ne=u("MODE"),oe=u("VARIANCE"),se=u("STDDEV"),ie=u("SKEWNESS"),ce=u("KURTOSIS"),ue=u("ENTROPY"),ae=u("VAR_POP"),le=u("STDDEV_POP"),pe=u("CORR"),fe=u("COVAR_POP"),he=u("REGR_INTERCEPT"),me=u("REGR_SLOPE"),ge=u("REGR_COUNT"),xe=u("REGR_R2"),de=u("REGR_SYY"),Ee=u("REGR_SXX"),$e=u("REGR_SXY"),Ne=u("REGR_AVGX"),ye=u("REGR_AVGY"),we=u("FIRST"),Se=u("LAST"),Re=u("ARG_MIN"),Ae=u("ARG_MAX"),Te=u("STRING_AGG"),be=u("ARRAY_AGG");function W(r,t){let e=l(r),n=a`CAST(${e} AS ${t})`;return Object.defineProperty(n,"label",{enumerable:!0,get(){return r.label}}),Object.defineProperty(n,"aggregate",{enumerable:!0,get(){return r.aggregate||!1}}),n}var qe=r=>W(r,"DOUBLE"),Le=r=>W(r,"INTEGER");var Oe=r=>{let t=l(r);return a`(1000 * (epoch(${t}) - second(${t})) + millisecond(${t}))::DOUBLE`},Ie=r=>{let t=l(r);return a`MAKE_DATE(2012, MONTH(${t}), 1)`.annotate({label:"month"})},De=r=>{let t=l(r);return a`MAKE_DATE(2012, MONTH(${t}), DAY(${t}))`.annotate({label:"date"})},Ce=r=>{let t=l(r);return a`MAKE_DATE(2012, 1, DAY(${t}))`.annotate({label:"date"})};var U=class r{static select(...t){return new r().select(...t)}static from(...t){return new r().from(...t)}static with(...t){return new r().with(...t)}static union(...t){return new b("UNION",t.flat())}static unionAll(...t){return new b("UNION ALL",t.flat())}static intersect(...t){return new b("INTERSECT",t.flat())}static except(...t){return new b("EXCEPT",t.flat())}constructor(){this.query={with:[],select:[],from:[],where:[],groupby:[],having:[],window:[],qualify:[],orderby:[]}}clone(){let t=new r;return t.query={...this.query},t}with(...t){let{query:e}=this;if(t.length===0)return e.with;{let n=[],o=(s,i)=>{let c=i.clone();c.cteFor=this,n.push({as:s,query:c})};return t.flat().forEach(s=>{if(s!=null)if(s.as&&s.query)o(s.as,s.query);else for(let i in s)o(i,s[i])}),e.with=e.with.concat(n),this}}select(...t){let{query:e}=this;if(t.length===0)return e.select;{let n=[];for(let o of t.flat())if(o!=null)if(typeof o=="string")n.push({as:o,expr:l(o)});else if(o instanceof y)n.push({as:o.column,expr:o});else if(Array.isArray(o))n.push({as:o[0],expr:o[1]});else for(let s in o)n.push({as:F(s),expr:l(o[s])});return e.select=e.select.concat(n),this}}$select(...t){return this.query.select=[],this.select(...t)}distinct(t=!0){return this.query.distinct=!!t,this}from(...t){let{query:e}=this;if(t.length===0)return e.from;{let n=[];return t.flat().forEach(o=>{if(o!=null)if(typeof o=="string")n.push({as:o,from:I(o)});else if(o instanceof y)n.push({as:o.table,from:o});else if(P(o)||_(o))n.push({from:o});else if(Array.isArray(o))n.push({as:F(o[0]),from:I(o[1])});else for(let s in o)n.push({as:F(s),from:I(o[s])})}),e.from=e.from.concat(n),this}}$from(...t){return this.query.from=[],this.from(...t)}sample(t,e){let{query:n}=this;if(arguments.length===0)return n.sample;{let o=t;return typeof t=="number"&&(o=t>0&&t<1?{perc:100*t,method:e}:{rows:Math.round(t),method:e}),n.sample=o,this}}where(...t){let{query:e}=this;return t.length===0?e.where:(e.where=e.where.concat(t.flat().filter(n=>n)),this)}$where(...t){return this.query.where=[],this.where(...t)}groupby(...t){let{query:e}=this;return t.length===0?e.groupby:(e.groupby=e.groupby.concat(t.flat().filter(n=>n).map(l)),this)}$groupby(...t){return this.query.groupby=[],this.groupby(...t)}having(...t){let{query:e}=this;return t.length===0?e.having:(e.having=e.having.concat(t.flat().filter(n=>n)),this)}window(...t){let{query:e}=this;if(t.length===0)return e.window;{let n=[];return t.flat().forEach(o=>{if(o!=null)for(let s in o)n.push({as:F(s),expr:o[s]})}),e.window=e.window.concat(n),this}}qualify(...t){let{query:e}=this;return t.length===0?e.qualify:(e.qualify=e.qualify.concat(t.flat().filter(n=>n)),this)}orderby(...t){let{query:e}=this;return t.length===0?e.orderby:(e.orderby=e.orderby.concat(t.flat().filter(n=>n).map(l)),this)}limit(t){let{query:e}=this;return arguments.length===0?e.limit:(e.limit=Number.isFinite(t)?t:void 0,this)}offset(t){let{query:e}=this;return arguments.length===0?e.offset:(e.offset=Number.isFinite(t)?t:void 0,this)}get subqueries(){let{query:t,cteFor:e}=this,o=(e?.query||t).with?.reduce((i,{as:c,query:p})=>(i[c]=p,i),{}),s=[];return t.from.forEach(({from:i})=>{if(P(i))s.push(i);else if(o[i.table]){let c=o[i.table];s.push(c)}}),s}toString(){let{select:t,distinct:e,from:n,sample:o,where:s,groupby:i,having:c,window:p,qualify:g,orderby:N,limit:R,offset:q,with:L}=this.query,m=[];if(L.length){let f=L.map(({as:h,query:d})=>`"${h}" AS (${d})`);m.push(`WITH ${f.join(", ")}`)}let Z=t.map(({as:f,expr:h})=>B(h,f)&&!h.table?`${h}`:`${h} AS "${f}"`);if(m.push(`SELECT${e?" DISTINCT":""} ${Z.join(", ")}`),n.length){let f=n.map(({as:h,from:d})=>{let O=P(d)?`(${d})`:`${d}`;return!h||h===d.table?O:`${O} AS "${h}"`});m.push(`FROM ${f.join(", ")}`)}if(s.length){let f=s.map(String).filter(h=>h).join(" AND ");f&&m.push(`WHERE ${f}`)}if(o){let{rows:f,perc:h,method:d,seed:O}=o,tt=f?`${f} ROWS`:`${h} PERCENT`,et=d?` (${d}${O!=null?`, ${O}`:""})`:"";m.push(`USING SAMPLE ${tt}${et}`)}if(i.length&&m.push(`GROUP BY ${i.join(", ")}`),c.length){let f=c.map(String).filter(h=>h).join(" AND ");f&&m.push(`HAVING ${f}`)}if(p.length){let f=p.map(({as:h,expr:d})=>`"${h}" AS (${d})`);m.push(`WINDOW ${f.join(", ")}`)}if(g.length){let f=g.map(String).filter(h=>h).join(" AND ");f&&m.push(`QUALIFY ${f}`)}return N.length&&m.push(`ORDER BY ${N.join(", ")}`),Number.isFinite(R)&&m.push(`LIMIT ${R}`),Number.isFinite(q)&&m.push(`OFFSET ${q}`),m.join(" ")}},b=class r{constructor(t,e){this.op=t,this.queries=e.map(n=>n.clone()),this.query={orderby:[]}}clone(){let t=new r(this.op,this.queries);return t.query={...this.query},t}orderby(...t){let{query:e}=this;return t.length===0?e.orderby:(e.orderby=e.orderby.concat(t.flat().filter(n=>n).map(l)),this)}limit(t){let{query:e}=this;return arguments.length===0?e.limit:(e.limit=Number.isFinite(t)?t:void 0,this)}offset(t){let{query:e}=this;return arguments.length===0?e.offset:(e.offset=Number.isFinite(t)?t:void 0,this)}get subqueries(){let{queries:t,cteFor:e}=this;return e&&t.forEach(n=>n.cteFor=e),t}toString(){let{op:t,queries:e,query:{orderby:n,limit:o,offset:s}}=this,i=[e.join(` ${t} `)];return n.length&&i.push(`ORDER BY ${n.join(", ")}`),Number.isFinite(o)&&i.push(`LIMIT ${o}`),Number.isFinite(s)&&i.push(`OFFSET ${s}`),i.join(" ")}};function P(r){return r instanceof U||r instanceof b}function F(r){return _e(r)?r.slice(1,-1):r}function _e(r){return r[0]==='"'&&r[r.length-1]==='"'}function M(r,t,{replace:e=!1,temp:n=!0,view:o=!1}={}){return"CREATE"+(e?" OR REPLACE ":" ")+(n?"TEMP ":"")+(o?"VIEW":"TABLE")+(e?" ":" IF NOT EXISTS ")+r+" AS "+t}function J(r,{columns:t=Object.keys(r?.[0]||{})}={}){let e=[];if(Array.isArray(t)?(e=t,t=e.reduce((o,s)=>(o[s]=s,o),{})):t&&(e=Object.keys(t)),!e.length)throw new Error("Can not create table from empty column set.");let n=[];for(let o of r){let s=e.map(i=>`${E(o[i])} AS "${t[i]}"`);n.push(`(SELECT ${s.join(", ")})`)}return n.join(" UNION ALL ")}function Y(r,t,e,n={},o={}){let{select:s=["*"],where:i,view:c,temp:p,replace:g,...N}=n,R=Ge({...o,...N}),q=`${r}('${e}'${R?", "+R:""})`,L=i?` WHERE ${i}`:"",m=`SELECT ${s.join(", ")} FROM ${q}${L}`;return M(t,m,{view:c,temp:p,replace:g})}function Fe(r,t,e){return Y("read_csv",r,t,e,{auto_detect:!0,sample_size:-1})}function Pe(r,t,e){return Y("read_json",r,t,e,{auto_detect:!0,json_format:"auto"})}function Ue(r,t,e){return Y("read_parquet",r,t,e)}function Me(r,t,e={}){let{select:n=["*"],...o}=e,s=J(t),i=n.length===1&&n[0]==="*"?s:`SELECT ${n} FROM ${s}`;return M(r,i,o)}function Ge(r){return Object.entries(r).map(([t,e])=>{let n=typeof e,o=n==="boolean"?String(e):n==="string"?`'${e}'`:e;return`${t}=${o}`}).join(", ")}export{U as Query,y as Ref,Bt as agg,rt as all,ct as and,Ae as argmax,Re as argmin,be as arrayAgg,l as asColumn,I as asRelation,vt as avg,W as cast,qe as castDouble,Le as castInteger,X as column,Rt as contains,pe as corr,kt as count,fe as covarPop,M as create,Ut as cume_dist,Ce as dateDay,Ie as dateMonth,De as dateMonthDay,Ft as dense_rank,st as desc,ue as entropy,Oe as epoch_ms,ht as eq,we as first,Wt as first_value,xt as gt,Et as gte,yt as isBetween,$t as isDistinct,It as isFinite,Dt as isInfinite,Ot as isNaN,wt as isNotBetween,Nt as isNotDistinct,ft as isNotNull,pt as isNull,A as isParamLike,P as isQuery,_ as isSQLExpression,ce as kurtosis,Gt as lag,Se as last,Yt as last_value,jt as lead,Lt as length,it as literal,E as literalToSQL,Fe as loadCSV,Pe as loadJSON,Me as loadObjects,Ue as loadParquet,bt as lower,gt as lt,dt as lte,Kt as mad,zt as max,Ht as mean,ee as median,Jt as min,ne as mode,mt as neq,lt as not,Qt as nth_value,Mt as ntile,ut as or,Pt as percent_rank,At as prefix,te as product,re as quantile,_t as rank,St as regexp_matches,Ne as regrAvgX,ye as regrAvgY,ge as regrCount,he as regrIntercept,xe as regrR2,Ee as regrSXX,$e as regrSXY,de as regrSYY,me as regrSlope,V as relation,Ct as row_number,ie as skewness,a as sql,se as stddev,le as stddevPop,Te as stringAgg,Tt as suffix,Zt as sum,nt as toSQL,qt as upper,ae as varPop,oe as variance};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uwdata/mosaic-sql",
3
- "version": "0.2.0",
3
+ "version": "0.3.2",
4
4
  "description": "SQL query construction and analysis.",
5
5
  "keywords": [
6
6
  "sql",
@@ -25,5 +25,5 @@
25
25
  "test": "mocha 'test/**/*-test.js'",
26
26
  "prepublishOnly": "npm run test && npm run lint && npm run build"
27
27
  },
28
- "gitHead": "e53cd914c807f99aabe78dcbe618dd9543e2f438"
28
+ "gitHead": "788bb137cc402b472fc7e4d84844c78151707c82"
29
29
  }
package/src/Query.js CHANGED
@@ -156,7 +156,7 @@ export class Query {
156
156
  if (typeof value === 'number') {
157
157
  spec = value > 0 && value < 1
158
158
  ? { perc: 100 * value, method }
159
- : { rows: Math.round(value, method) };
159
+ : { rows: Math.round(value), method };
160
160
  }
161
161
  query.sample = spec;
162
162
  return this;
@@ -192,6 +192,11 @@ export class Query {
192
192
  }
193
193
  }
194
194
 
195
+ $groupby(...expr) {
196
+ this.query.groupby = [];
197
+ return this.groupby(...expr);
198
+ }
199
+
195
200
  having(...expr) {
196
201
  const { query } = this;
197
202
  if (expr.length === 0) {
package/src/index.js CHANGED
@@ -129,7 +129,9 @@ export {
129
129
  } from './to-sql.js';
130
130
 
131
131
  export { create } from './load/create.js';
132
- export { loadCSV } from './load/csv.js';
133
- export { loadJSON } from './load/json.js';
134
- export { loadParquet } from './load/parquet.js';
135
- export { sqlFrom } from './load/sql-from.js';
132
+ export {
133
+ loadCSV,
134
+ loadJSON,
135
+ loadObjects,
136
+ loadParquet
137
+ } from './load/load.js';
@@ -1,6 +1,12 @@
1
- export function create(name, query, options = {}) {
2
- const { temp, replace, type = 'TABLE' } = options;
3
- const create = `CREATE${replace ? ' OR REPLACE' : ''}`;
4
- const spec = `${temp ? 'TEMP ' : ''}${type}${replace ? '' : ' IF NOT EXISTS'}`;
5
- return `${create} ${spec} ${name} AS ${query}`;
1
+ export function create(name, query, {
2
+ replace = false,
3
+ temp = true,
4
+ view = false
5
+ } = {}) {
6
+ return 'CREATE'
7
+ + (replace ? ' OR REPLACE ' : ' ')
8
+ + (temp ? 'TEMP ' : '')
9
+ + (view ? 'VIEW' : 'TABLE')
10
+ + (replace ? ' ' : ' IF NOT EXISTS ')
11
+ + name + ' AS ' + query;
6
12
  }
@@ -0,0 +1,44 @@
1
+ import { create } from './create.js';
2
+ import { sqlFrom } from './sql-from.js';
3
+
4
+ export function load(method, tableName, fileName, options = {}, defaults = {}) {
5
+ const { select = ['*'], where, view, temp, replace, ...file } = options;
6
+ const params = parameters({ ...defaults, ...file });
7
+ const read = `${method}('${fileName}'${params ? ', ' + params : ''})`;
8
+ const filter = where ? ` WHERE ${where}` : '';
9
+ const query = `SELECT ${select.join(', ')} FROM ${read}${filter}`;
10
+ return create(tableName, query, { view, temp, replace });
11
+ }
12
+
13
+ export function loadCSV(tableName, fileName, options) {
14
+ return load('read_csv', tableName, fileName, options, { auto_detect: true, sample_size: -1 });
15
+ }
16
+
17
+ export function loadJSON(tableName, fileName, options) {
18
+ return load('read_json', tableName, fileName, options, { auto_detect: true, json_format: 'auto' });
19
+ }
20
+
21
+ export function loadParquet(tableName, fileName, options) {
22
+ return load('read_parquet', tableName, fileName, options);
23
+ }
24
+
25
+ export function loadObjects(tableName, data, options = {}) {
26
+ const { select = ['*'], ...opt } = options;
27
+ const values = sqlFrom(data);
28
+ const query = select.length === 1 && select[0] === '*'
29
+ ? values
30
+ : `SELECT ${select} FROM ${values}`;
31
+ return create(tableName, query, opt);
32
+ }
33
+
34
+ function parameters(options) {
35
+ return Object.entries(options)
36
+ .map(([key, value]) => {
37
+ const t = typeof value;
38
+ const v = t === 'boolean' ? String(value)
39
+ : t === 'string' ? `'${value}'`
40
+ : value;
41
+ return `${key}=${v}`;
42
+ })
43
+ .join(', ');
44
+ }
package/src/ref.js CHANGED
@@ -28,13 +28,23 @@ export class Ref {
28
28
  const { table, column } = this;
29
29
  if (column) {
30
30
  const col = column.startsWith('*') ? column : `"${column}"`;
31
- return `${table ? `"${table}".` : ''}${col}`;
31
+ return `${table ? `${quoteTableName(table)}.` : ''}${col}`;
32
32
  } else {
33
- return table ? `"${table}"` : 'NULL';
33
+ return table ? quoteTableName(table) : 'NULL';
34
34
  }
35
35
  }
36
36
  }
37
37
 
38
+ /**
39
+ * Quote a table name. For example, `foo.bar` becomes `"foo"."bar".
40
+ * @param {string} table the name of the table which may contain a database reference
41
+ * @returns The quoted table name.
42
+ */
43
+ function quoteTableName(table) {
44
+ const pieces = table.split('.');
45
+ return pieces.map(p => `"${p}"`).join('.');
46
+ }
47
+
38
48
  /**
39
49
  * Test is a reference refers to a given column name.
40
50
  * @param {*} ref The reference to test.
package/src/load/csv.js DELETED
@@ -1,9 +0,0 @@
1
- import { create } from './create.js';
2
- import { parameters } from './parameters.js';
3
-
4
- export function loadCSV(tableName, fileName, options = {}) {
5
- const { select = ['*'], temp, replace, ...csvOptions } = options;
6
- const params = parameters({ auto_detect: true, sample_size: -1, ...csvOptions });
7
- const query = `SELECT ${select.join(', ')} FROM read_csv('${fileName}', ${params})`;
8
- return create(tableName, query, { temp, replace });
9
- }
package/src/load/json.js DELETED
@@ -1,9 +0,0 @@
1
- import { create } from './create.js';
2
- import { parameters } from './parameters.js';
3
-
4
- export function loadJSON(tableName, fileName, options = {}) {
5
- const { select = ['*'], temp, replace, ...jsonOptions } = options;
6
- const params = parameters({ auto_detect: true, json_format: 'auto', ...jsonOptions });
7
- const query = `SELECT ${select.join(', ')} FROM read_json('${fileName}', ${params})`;
8
- return create(tableName, query, { temp, replace });
9
- }
@@ -1,11 +0,0 @@
1
- export function parameters(options) {
2
- return Object.entries(options)
3
- .map(([key, value]) => {
4
- const t = typeof value;
5
- const v = t === 'boolean' ? String(value)
6
- : t === 'string' ? `'${value}'`
7
- : value;
8
- return `${key}=${v}`;
9
- })
10
- .join(', ');
11
- }
@@ -1,7 +0,0 @@
1
- import { create } from './create.js';
2
-
3
- export function loadParquet(tableName, fileName, options = {}) {
4
- const { select = ['*'], ...tableOptions } = options;
5
- const query = `SELECT ${select.join(', ')} FROM read_parquet('${fileName}')`;
6
- return create(tableName, query, tableOptions);
7
- }