semanticdb-v2 2.0.0-alpha.1 → 2.0.0-alpha.3

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.
Files changed (180) hide show
  1. package/README.md +24 -17
  2. package/dist/cache/redis-query-cache.js +1 -1
  3. package/dist/calendar/constants.d.ts +2 -2
  4. package/dist/compatibility/index.d.ts +1 -1
  5. package/dist/compatibility/logicform.d.ts +1 -7
  6. package/dist/compiler/compile-cte.d.ts +17 -2
  7. package/dist/compiler/index.d.ts +2 -1
  8. package/dist/compiler/shorten-sql.d.ts +1 -1
  9. package/dist/errors.d.ts +2 -0
  10. package/dist/executor/fetch-entities.d.ts +2 -1
  11. package/dist/executor/row-identity.d.ts +2 -1
  12. package/dist/executor/types.d.ts +14 -11
  13. package/dist/index.d.ts +5 -7
  14. package/dist/logicform-types.d.ts +11 -12
  15. package/dist/normalizer/core.d.ts +2 -2
  16. package/dist/normalizer/property-resolve.d.ts +5 -0
  17. package/dist/operators/builtins/constant.d.ts +2 -0
  18. package/dist/operators/builtins/period-value.d.ts +2 -0
  19. package/dist/operators/builtins/scalar-extremum.d.ts +3 -0
  20. package/dist/operators/index.d.ts +1 -1
  21. package/dist/operators/types.d.ts +25 -21
  22. package/dist/physical/clickhouse-provider.d.ts +1 -0
  23. package/dist/physical/mysql-protocol-provider.d.ts +2 -0
  24. package/dist/physical/oracle-provider.d.ts +1 -0
  25. package/dist/physical/postgresql-provider.d.ts +1 -0
  26. package/dist/physical/provider.d.ts +2 -0
  27. package/dist/physical/snowflake-provider.d.ts +1 -0
  28. package/dist/planner/semantics/observation/operator-policy.d.ts +1 -1
  29. package/dist/planner/semantics/observation/types.d.ts +1 -1
  30. package/dist/planner/types.d.ts +10 -2
  31. package/dist/plugins/hierarchy/types.d.ts +3 -2
  32. package/dist/schema/entity-identity.d.ts +1 -1
  33. package/dist/schema-mappings/index.d.ts +3 -1
  34. package/dist/schema-mappings/types.d.ts +9 -8
  35. package/dist/schema-mappings/yiask.d.ts +22 -0
  36. package/dist/semantic-types/index.d.ts +1 -1
  37. package/dist/semantic-types/types.d.ts +14 -2
  38. package/dist/semanticdb.js +3 -0
  39. package/package.json +4 -3
  40. package/dist/cache/expiry.js +0 -1
  41. package/dist/cache/identity.js +0 -1
  42. package/dist/cache/serialization.js +0 -1
  43. package/dist/calendar/constants.js +0 -1
  44. package/dist/calendar/provider-relation-store.js +0 -1
  45. package/dist/calendar/resolver.js +0 -1
  46. package/dist/calendar/system-schemas.js +0 -1
  47. package/dist/compatibility/logicform.js +0 -1
  48. package/dist/compiler/compile-cte.js +0 -1
  49. package/dist/compiler/compile-plan.js +0 -1
  50. package/dist/compiler/shorten-sql.js +0 -2
  51. package/dist/custom-functions/custom-functions.d.ts +0 -6
  52. package/dist/custom-functions/custom-functions.js +0 -1
  53. package/dist/custom-functions/index.d.ts +0 -3
  54. package/dist/custom-functions/operator-adapter.d.ts +0 -12
  55. package/dist/custom-functions/operator-adapter.js +0 -1
  56. package/dist/custom-functions/types.d.ts +0 -62
  57. package/dist/errors.js +0 -1
  58. package/dist/executor/compatibility.js +0 -1
  59. package/dist/executor/components.js +0 -1
  60. package/dist/executor/connection-registry.js +0 -1
  61. package/dist/executor/evaluate.js +0 -1
  62. package/dist/executor/execute-query.js +0 -1
  63. package/dist/executor/execute.js +0 -1
  64. package/dist/executor/fetch-entities.js +0 -1
  65. package/dist/executor/result-hydrator/entity-loader.js +0 -1
  66. package/dist/executor/result-hydrator/format-values.js +0 -1
  67. package/dist/executor/result-hydrator/hydrate-result.js +0 -1
  68. package/dist/executor/result-hydrator/missing-entity.js +0 -1
  69. package/dist/executor/result-hydrator/populate-entities.js +0 -1
  70. package/dist/executor/row-identity.js +0 -1
  71. package/dist/index.js +0 -1
  72. package/dist/logicform-types.js +0 -1
  73. package/dist/normalizer/core.js +0 -1
  74. package/dist/normalizer/default-pred-name.js +0 -1
  75. package/dist/normalizer/entity-id.js +0 -1
  76. package/dist/normalizer/groupby.js +0 -1
  77. package/dist/normalizer/normalize-logicform.js +0 -1
  78. package/dist/normalizer/pagination.js +0 -1
  79. package/dist/normalizer/pred-query-name.js +0 -1
  80. package/dist/normalizer/preds.js +0 -1
  81. package/dist/normalizer/query.js +0 -1
  82. package/dist/normalizer/version.js +0 -1
  83. package/dist/operators/builtins/abs.js +0 -1
  84. package/dist/operators/builtins/accumulate.js +0 -1
  85. package/dist/operators/builtins/add.js +0 -1
  86. package/dist/operators/builtins/arithmetic.js +0 -1
  87. package/dist/operators/builtins/average-per-period.js +0 -1
  88. package/dist/operators/builtins/avg.js +0 -1
  89. package/dist/operators/builtins/case.js +0 -1
  90. package/dist/operators/builtins/concat.js +0 -1
  91. package/dist/operators/builtins/count-distinct.js +0 -1
  92. package/dist/operators/builtins/count.js +0 -1
  93. package/dist/operators/builtins/date-bucket.js +0 -1
  94. package/dist/operators/builtins/divide.js +0 -1
  95. package/dist/operators/builtins/index.js +0 -1
  96. package/dist/operators/builtins/max.js +0 -1
  97. package/dist/operators/builtins/min.js +0 -1
  98. package/dist/operators/builtins/multiply.js +0 -1
  99. package/dist/operators/builtins/newly.js +0 -1
  100. package/dist/operators/builtins/period-boundary.js +0 -1
  101. package/dist/operators/builtins/period-difference.js +0 -1
  102. package/dist/operators/builtins/period-growth.js +0 -1
  103. package/dist/operators/builtins/period-name.js +0 -1
  104. package/dist/operators/builtins/period-shift.js +0 -1
  105. package/dist/operators/builtins/rank.js +0 -1
  106. package/dist/operators/builtins/row-number.js +0 -1
  107. package/dist/operators/builtins/share-of-total.js +0 -1
  108. package/dist/operators/builtins/sql.js +0 -1
  109. package/dist/operators/builtins/substring.js +0 -1
  110. package/dist/operators/builtins/subtract.js +0 -1
  111. package/dist/operators/builtins/sum.js +0 -1
  112. package/dist/operators/builtins/time-range.js +0 -1
  113. package/dist/operators/groupby.js +0 -1
  114. package/dist/operators/index.js +0 -1
  115. package/dist/operators/registry.js +0 -1
  116. package/dist/operators/sql-expression.js +0 -1
  117. package/dist/permissions/permissions.js +0 -1
  118. package/dist/physical/clickhouse-provider.js +0 -1
  119. package/dist/physical/connection.js +0 -1
  120. package/dist/physical/display-query.js +0 -1
  121. package/dist/physical/doris-provider.js +0 -1
  122. package/dist/physical/mysql-compatible-sql.js +0 -1
  123. package/dist/physical/mysql-protocol-provider.js +0 -1
  124. package/dist/physical/mysql-provider.js +0 -1
  125. package/dist/physical/oracle-provider.js +0 -1
  126. package/dist/physical/postgresql-provider.js +0 -1
  127. package/dist/physical/snowflake-provider.js +0 -1
  128. package/dist/physical/starrocks-provider.js +0 -1
  129. package/dist/planner/build-lineage.js +0 -1
  130. package/dist/planner/create-logical-plan.js +0 -1
  131. package/dist/planner/select-schema-mapping.js +0 -1
  132. package/dist/planner/semantics/lifecycle/classification.js +0 -1
  133. package/dist/planner/semantics/lifecycle/query-policy.js +0 -1
  134. package/dist/planner/semantics/lifecycle/rule.js +0 -1
  135. package/dist/planner/semantics/observation/classification.js +0 -1
  136. package/dist/planner/semantics/observation/operator-policy.js +0 -1
  137. package/dist/planner/semantics/observation/rule.js +0 -1
  138. package/dist/planner/semantics/registry-defaults.js +0 -1
  139. package/dist/planner/semantics/registry.js +0 -1
  140. package/dist/planner/types.js +0 -1
  141. package/dist/plugins/hierarchy/compatibility.js +0 -1
  142. package/dist/plugins/hierarchy/entity-identity.js +0 -1
  143. package/dist/plugins/hierarchy/index.js +0 -1
  144. package/dist/plugins/hierarchy/operator.js +0 -1
  145. package/dist/plugins/hierarchy/resolve-schema.js +0 -1
  146. package/dist/plugins/index.js +0 -1
  147. package/dist/schema/entity-identity.js +0 -1
  148. package/dist/schema/resolve-property-path.js +0 -1
  149. package/dist/schema/schema-registry.js +0 -1
  150. package/dist/schema-mappings/freshness.js +0 -1
  151. package/dist/schema-mappings/registry.js +0 -1
  152. package/dist/semantic-types/builtins/boolean.js +0 -1
  153. package/dist/semantic-types/builtins/category.js +0 -1
  154. package/dist/semantic-types/builtins/currency.js +0 -1
  155. package/dist/semantic-types/builtins/date.js +0 -1
  156. package/dist/semantic-types/builtins/duration.js +0 -1
  157. package/dist/semantic-types/builtins/end-date.js +0 -1
  158. package/dist/semantic-types/builtins/entity.js +0 -1
  159. package/dist/semantic-types/builtins/file.js +0 -1
  160. package/dist/semantic-types/builtins/human-name.js +0 -1
  161. package/dist/semantic-types/builtins/id.js +0 -1
  162. package/dist/semantic-types/builtins/image.js +0 -1
  163. package/dist/semantic-types/builtins/index.js +0 -1
  164. package/dist/semantic-types/builtins/int.js +0 -1
  165. package/dist/semantic-types/builtins/name.js +0 -1
  166. package/dist/semantic-types/builtins/number.js +0 -1
  167. package/dist/semantic-types/builtins/object.js +0 -1
  168. package/dist/semantic-types/builtins/order.js +0 -1
  169. package/dist/semantic-types/builtins/percentage.js +0 -1
  170. package/dist/semantic-types/builtins/start-date.js +0 -1
  171. package/dist/semantic-types/builtins/string.js +0 -1
  172. package/dist/semantic-types/builtins/timestamp.js +0 -1
  173. package/dist/semantic-types/index.js +0 -1
  174. package/dist/semantic-types/primal-types/date.js +0 -1
  175. package/dist/semantic-types/primal-types/index.js +0 -1
  176. package/dist/semantic-types/registry.js +0 -1
  177. package/dist/semantic-types/resolve-schema.js +0 -1
  178. package/dist/semantic-types/validate-resolved-schema.js +0 -1
  179. package/dist/utils/clone.js +0 -1
  180. /package/dist/operators/builtins/{period-boundary.d.ts → period-boundary-expression.d.ts} +0 -0
@@ -1 +0,0 @@
1
- const n=e=>e===void 0?{type:"undefined"}:typeof e=="bigint"?{type:"bigint",value:e.toString()}:typeof e=="number"&&!Number.isFinite(e)?{type:"number",value:String(e)}:e instanceof Date?{type:"date",value:e.toISOString()}:Array.isArray(e)?{type:"array",value:e.map(n)}:e&&typeof e=="object"?{type:"object",value:Object.entries(e).map(([r,t])=>[r,n(t)])}:e,i=e=>{if(e===null||typeof e!="object")return e;switch(e.type){case"undefined":return;case"bigint":return BigInt(e.value);case"number":return Number(e.value);case"date":return new Date(e.value);case"array":return e.value.map(i);case"object":return Object.fromEntries(e.value.map(([r,t])=>[r,i(t)]))}},s=e=>JSON.stringify(n(e)),o=e=>{const r=i(JSON.parse(e));if(!(!Array.isArray(r)||r.some(t=>!t||typeof t!="object"||Array.isArray(t))))return r};export{o as deserializeQueryRows,s as serializeQueryRows};
@@ -1 +0,0 @@
1
- const _="semanticdb_calendar_dates",a="semanticdb_calendar_relations",e={dates:"__semanticdb_calendar_dates",relations:"__semanticdb_calendar_relations"};export{_ as CALENDAR_DATES_TABLE,a as CALENDAR_RELATIONS_TABLE,e as CALENDAR_SYSTEM_SCHEMA_IDS};
@@ -1 +0,0 @@
1
- import{CALENDAR_RELATIONS_TABLE as s}from"./constants.js";const g=["source_date_id","target_date_id","calendar","grain","relation","relation_key"];class _{provider;constructor(t){this.provider=t}async loadRelations(t,i){if(t.length===0)return[];const n=[...t,i.calendar,i.grain,i.relation];i.key!==void 0&&n.push(i.key);const l=t.map((e,d)=>this.provider.parameter(d,e)),a=e=>this.provider.parameter(e,n[e]),r=e=>this.provider.quoteIdentifier(e),o=[`${r("source_date_id")} IN (${l.join(", ")})`,`${r("calendar")} = ${a(t.length)}`,`${r("grain")} = ${a(t.length+1)}`,`${r("relation")} = ${a(t.length+2)}`];return i.key!==void 0&&o.push(`${r("relation_key")} = ${a(t.length+3)}`),(await this.provider.execute({sql:`SELECT ${g.map(r).join(", ")} FROM ${r(s)} WHERE ${o.join(" AND ")}`,parameters:n})).map(e=>({sourceDateId:e.source_date_id,targetDateId:e.target_date_id,calendar:String(e.calendar),grain:String(e.grain),relation:String(e.relation),...typeof e.relation_key=="string"||typeof e.relation_key=="number"?{key:String(e.relation_key)}:{}}))}}export{_ as ProviderCalendarRelationStore};
@@ -1 +0,0 @@
1
- const l=n=>`${typeof n}:${String(n)}`,p=(n,t)=>{const r=typeof n=="number"?n:Number(n),o=typeof t=="number"?t:Number(t);return Number.isFinite(r)&&Number.isFinite(o)?r-o:String(n).localeCompare(String(t))},m=(n,t,r)=>{const o=r.filter(e=>e.calendar===t.calendar&&e.grain===t.grain&&e.relation===t.relation&&(t.key===void 0||e.key===t.key)),d=new Map(o.map(e=>[l(e.sourceDateId),e])),b=n.flatMap(e=>{const a=d.get(l(e))?.targetDateId;return a==null?[]:[a]}),f=[...new Map(b.map(e=>[l(e),e])).values()].sort(p),s=[];for(const e of f){const a=s[s.length-1];if(a&&typeof a.end=="number"&&typeof e=="number"&&e===a.end+1)a.end=e;else if(a&&String(a.end).match(/^\d{8}$/)&&String(e).match(/^\d{8}$/)){const i=Number(a.end),c=Number(e),u=new Date(Date.UTC(Math.floor(i/1e4),Math.floor(i/100)%100-1,i%100));u.setUTCDate(u.getUTCDate()+1);const g=new Date(Date.UTC(Math.floor(c/1e4),Math.floor(c/100)%100-1,c%100));if(u.getTime()===g.getTime()){a.end=e;continue}s.push({start:e,end:e})}else s.push({start:e,end:e})}return{dateIds:f,ranges:s}},y=async(n,t,r)=>m(n,t,await r.loadRelations(n,t)),D=(n,t)=>n.filter(r=>Object.entries(t).every(([o,d])=>r[o]===d)).map(r=>r.dateId);export{m as resolveCalendarPeriod,y as resolveCalendarPeriodFromStore,D as selectCalendarDates};
@@ -1 +0,0 @@
1
- import{CALENDAR_RELATIONS_TABLE as t,CALENDAR_SYSTEM_SCHEMA_IDS as e,CALENDAR_DATES_TABLE as i}from"./constants.js";const r={[e.dates]:{id:e.dates,name:e.dates,type:"entity",source:i,properties:[{id:"date_id",name:"date_id",type:"id",primal_type:"string"},{id:"calendar",name:"calendar",type:"string",primal_type:"string"},{id:"grain",name:"grain",type:"string",primal_type:"string"},{id:"period_key",name:"period_key",type:"string",primal_type:"string"},{id:"relative_day",name:"relative_day",type:"int",primal_type:"number"}]},[e.relations]:{id:e.relations,name:e.relations,type:"entity",source:t,properties:[{id:"source_date_id",name:"source_date_id",type:"string",primal_type:"string"},{id:"target_date_id",name:"target_date_id",type:"string",primal_type:"string"},{id:"calendar",name:"calendar",type:"string",primal_type:"string"},{id:"grain",name:"grain",type:"string",primal_type:"string"},{id:"relation",name:"relation",type:"string",primal_type:"string"},{id:"relation_key",name:"relation_key",type:"string",primal_type:"string"}]}};export{r as calendarSystemSchemas};
@@ -1 +0,0 @@
1
- import{SemanticDBError as m}from"../errors.js";const p=r=>!a(r)||!Array.isArray(r.properties)?[]:r.properties.filter(a),$=(r,n)=>r.id===n||r._id===n||r.name===n,h=(r,n,e,o=new Set)=>{if(r===n)return[];if(!o.has(r)){o.add(r);for(const t of p(e[r])){if(typeof t.ref!="string"||e[t.ref]===void 0)continue;const f=h(t.ref,n,e,o);if(f)return[String(t.name??t.id),...f]}o.delete(r)}},w=(r,n,e)=>{if(p(e[r]).some(d=>$(d,n)))return n;const t=n.split("_");for(let d=1;d<t.length;d+=1){const c=t.slice(d).join("_");if(p(e[r]).some(i=>$(i,c)))return c}const f=t.at(-1)??n;for(const[d,c]of Object.entries(e)){if(!p(c).some(u=>$(u,f)))continue;const i=h(r,d,e);if(i)return[...i,f].join("_")}},O=r=>Object.keys(r).filter(n=>n!=="$and"&&n!=="$or"),a=r=>typeof r=="object"&&r!==null&&!Array.isArray(r),b=r=>{if(!a(r))return r;if(a(r.$offset)){const n=Object.entries(r.$offset),e=n[0];if(n.length===1&&e&&Number.isInteger(e[1]))return{granularity:e[0],offset:e[1]}}return r},L=(r,n)=>{const o=r&&({$sply:"$periodShift",$splm:"$periodShift",$splw:"$periodShift",$yoy:"$periodGrowth",$mom:"$periodGrowth",$wow:"$periodGrowth",$yoyd:"$periodDifference",$momd:"$periodDifference",$dailyavg:"$averagePerPeriod",$weeklyavg:"$averagePerPeriod",$monthlyavg:"$averagePerPeriod",$startOfPeriod:"$periodBoundary",$endOfPeriod:"$periodBoundary",$dateLevel:"$dateBucket",$uniq:"$countDistinct"}[r]??r),t={...n};return r==="$sply"||r==="$yoy"||r==="$yoyd"?t.time??={granularity:"year",offset:-1}:r==="$splm"||r==="$mom"||r==="$momd"?t.time??={granularity:"month",offset:-1}:r==="$splw"||r==="$wow"?t.time??={granularity:"week",offset:-1}:r==="$dailyavg"?t.granularity??="day":r==="$weeklyavg"?t.granularity??="week":r==="$monthlyavg"?t.granularity??="month":r==="$startOfPeriod"?t.boundary??="start":r==="$endOfPeriod"&&(t.boundary??="end"),{...o?{operator:o}:{},args:t}},y=r=>{if(Array.isArray(r))return r.map(y);if(!a(r))return r;const n=r,e={};for(const[t,f]of Object.entries(n))t==="skip"||t==="_snapshot"||t==="_snapshots"||(t==="$offset"?e[t]=b(f):e[t]=y(f));if(typeof n.version=="string"&&/^1\./.test(n.version)&&(e.version="2.0"),Array.isArray(n.groupby)){const t=n.groupby;e.groupby=t.map(f=>{if(!a(f))return f;const{_id:d,level:c,...i}=f,u={...i,...i.pred===void 0&&typeof d=="string"?{pred:d}:{}};return typeof c=="string"&&(u.operator="$dateBucket",u.args={...a(u.args)?u.args:{},granularity:c}),u})}const o=n.skip;if(typeof o=="number"&&Number.isInteger(o)&&o>=0){const t=n.limit;o===0?delete e.skip:typeof t=="number"&&Number.isInteger(t)&&t>0&&o%t===0?e.page=o/t+1:e.skip=o}else o!==void 0&&(e.skip=y(o));if(n.operator&&typeof n.operator=="string"){const t=L(n.operator,a(e.args)?e.args:{});t.operator&&(e.operator=t.operator),e.args=t.args}return n.params!==void 0&&e.args===void 0&&(e.args=Array.isArray(n.params)?{values:y(n.params)}:y(n.params)),n.inputs!==void 0&&e.components===void 0&&Array.isArray(n.inputs)&&(e.components=n.inputs.map(y),a(e.args)&&delete e.args.inputs),n.pred===void 0&&typeof n.operator=="string"&&n.operator==="$sql"&&typeof n.sql=="string"&&(e.args={...a(e.args)?e.args:{},sql:n.sql},delete e.sql),n.$options!==void 0&&e.$regex!==void 0&&(e.args={...a(e.args)?e.args:{},options:n.$options},delete e.$options),n.query&&a(n.query)&&(e.query=k(n.query)),e},k=r=>{const n=y(r);for(const[e,o]of Object.entries(n))n[e]=b(o);return n},v=r=>{const n=a(r)?r:void 0,e=y(r);if(!a(e))return e;if(n&&typeof n.operator=="string"&&n.preds===void 0){const o={};for(const d of["version","schema","query","groupby","having","sort","limit","page","skip","output","representation","currency"])e[d]!==void 0&&(o[d]=e[d]);const t=new Set(["version","schema","query","groupby","having","sort","limit","page","skip","output","representation","currency"]),f=Object.fromEntries(Object.entries(e).filter(([d])=>!t.has(d)));return o.preds=[f],v(o)}return(e.version===void 0||typeof e.version=="string"&&/^1\./.test(e.version))&&(e.version="2.0"),e},_=(r,n)=>{const e=r;if(Array.isArray(e.logicforms)||!Array.isArray(e.preds))return r;const o=e.preds,t=typeof e.schema=="string"?e.schema:void 0;if(!t)return r;const f=new Set([t]);for(const i of o)a(i)&&typeof i.schema=="string"&&f.add(i.schema);if(f.size<2)return r;if(!n)throw new Error("Cannot migrate cross-Schema LogicForm without Schema metadata for field alignment");const d=[...f].map(i=>{const u={...e,schema:i,preds:[]};if(u.preds=o.filter(s=>a(s)?(s.schema??t)===i:i===t).map(s=>{if(!a(s))return s;const{schema:g,...l}=s;return l}),Array.isArray(e.groupby)&&(u.groupby=e.groupby.map(s=>{if(!a(s)||typeof s.pred!="string")return s;const g=w(i,s.pred,n);if(!g)throw new Error(`Cannot align legacy groupby field ${s.pred} in Schema ${i}`);return{...s,pred:g}})),a(e.query)){u.query={};for(const s of O(e.query)){if(!Object.entries(n).find(([,A])=>p(A).some(q=>$(q,s)))?.[0])throw new Error(`Cannot align legacy query field ${s} to a Schema`);const l=w(i,s,n);if(!l)throw new Error(`Cannot align legacy query field ${s} in Schema ${i}`);u.query[l]=e.query[s]}for(const s of["$and","$or"])e.query[s]!==void 0&&(u.query[s]=e.query[s])}return u}),c={version:e.version,logicforms:d};for(const i of["output","representation","currency","sort"])e[i]!==void 0&&(c[i]=e[i]);return c},S=r=>{const n=(e,o)=>{if(Array.isArray(e)){e.forEach((t,f)=>n(t,`${o}[${f}]`));return}if(a(e))for(const[t,f]of Object.entries(e)){if(["is_snapshot","is_observation","_snapshot","_snapshots","$options","params","inputs"].includes(t))throw new m("LEGACY_LOGICFORM_NOT_ALLOWED",`Legacy LogicForm field is not supported in v2: ${o}.${t}`);if(t==="_id"&&(o.endsWith(".groupby")||o.includes(".groupby[")))throw new m("LEGACY_LOGICFORM_NOT_ALLOWED",`Legacy LogicForm field is not supported in v2: ${o}.${t}`);n(f,`${o}.${t}`)}};n(r,"$")};export{S as assertNoLegacyLogicformFields,v as normalizeLegacyLogicform,_ as splitLegacySchemas};
@@ -1 +0,0 @@
1
- import{compilePlan as d}from"./compile-plan.js";const w=o=>`__semanticdb_cte_${o}`,h=o=>{const i=o.projections[o.groupBy.length];if(!i)throw new Error("CTE component must produce one metric projection");return i.name},y=(o,i)=>o?.find(c=>c.name===i),T=(o,i,c,e,g)=>{const s=[];let l=0;for(const t of i){const n=d(t.plan,e,g,l);l+=n.parameters.length,s.push({input:t,sql:n,alias:w(t.name)})}const j=s.map(({sql:t,alias:n})=>`${e.quoteIdentifier(n)} AS (${t.sql})`).join(", "),m=s[0];if(!m)throw new Error("CTE calculation requires a current component");const a=e.quoteIdentifier(m.alias),p=c.groupBy.map(({name:t})=>t),E=p.map(t=>`${a}.${e.quoteIdentifier(t)} AS ${e.quoteIdentifier(t)}`);let $="";for(const t of s.slice(1)){const n=e.quoteIdentifier(t.alias),u=(t.input.joinKeys??p).map(r=>{const f=y(t.input.groupKeyShifts,r),N=f?e.dateShift(`${n}.${e.quoteIdentifier(r)}`,f.granularity,f.offset):`${n}.${e.quoteIdentifier(r)}`;return`${a}.${e.quoteIdentifier(r)} = ${N}`});$+=` LEFT JOIN ${n} ON ${u.length>0?u.join(" AND "):"1 = 1"}`}const A=Object.fromEntries(s.map(({input:t,alias:n})=>[t.name,`${e.quoteIdentifier(n)}.${e.quoteIdentifier(h(t.plan))}`])),S=o.toSQL({values:A,quoteIdentifier:t=>e.quoteIdentifier(t)}),q=o.outputName??c.projections[c.groupBy.length]?.name;if(!q)throw new Error("CTE output projection is missing");const C=[...E,...o.exposeComponents?s.map(({input:t,alias:n})=>`${`${e.quoteIdentifier(n)}.${e.quoteIdentifier(h(t.plan))}`} AS ${e.quoteIdentifier(t.name)}`):[],`${S} AS ${e.quoteIdentifier(q)}`].join(", ");let I=`WITH ${j} SELECT ${C} FROM ${a}`;return I+=$,{sql:I,parameters:s.flatMap(({sql:t})=>t.parameters)}};export{T as compileCteCalculation};
@@ -1 +0,0 @@
1
- import{SemanticDBError as N}from"../errors.js";import{createOperatorRegistry as X}from"../operators/index.js";import{isLogicalOrdinalQuery as z,isLogicalRecursiveQuery as K,isLogicalQuerySubquery as B}from"../planner/types.js";import{bindTrustedSqlExpression as Z}from"../operators/sql-expression.js";class x{provider;parameterOffset;values=[];constructor(e,n=0){this.provider=e,this.parameterOffset=n}add(e){const n=this.parameterOffset+this.values.length;return this.values.push(e),this.provider.parameter(n,e)}get nextParameterOffset(){return this.parameterOffset+this.values.length}append(e){this.values.push(...e)}}const v=(t,e)=>{const n=e.split(".");if(n.some(r=>r.length===0))throw new N("INVALID_SOURCE",`Invalid physical source: ${e}`);return n.map(r=>t.quoteIdentifier(r)).join(".")},C=(t,e,n)=>n===void 0?v(t,e):`(${n.trim().replace(/;+\s*$/,"")})`,tt=t=>/^(select|with)\b/i.test(t.trim()),P=(t,e,n,r,i)=>{const a=Z(t,[],String,`Property ${e} udf.sql`);if(!a.includes("$TS"))return a;if(!r)throw new N("PROPERTY_UDF_TIMESTAMP_REQUIRED",`Property ${e} udf.sql uses $TS but its Schema has no timestamp Property`,{property:e});const $=(i?`${n.quoteIdentifier(i)}.`:"")+n.quoteIdentifier(r);return a.replace(/\$TS/g,$)},y=(t,e,n,r=!1,i,a,$,o)=>{const u=(c,m)=>r&&m?`${e.quoteIdentifier(m)}.${e.quoteIdentifier(c)}`:e.quoteIdentifier(c);switch(t.kind){case"array-element":if(!o)throw new N("ARRAY_EXPANSION_UNAVAILABLE","Array expansion compiler is unavailable");return o(t.expansionPath);case"column":return u(t.column,t.qualifier);case"property-sql":return P(t.sql,t.property,e,t.timestampColumn,r?t.qualifier:void 0);case"window":{if(l(t.input,n))throw new N("UNSUPPORTED_MIXED_OPERATOR","Window operators cannot consume a JavaScript operator");const c=t.partitionBy.length>0?`PARTITION BY ${t.partitionBy.map(f=>y(f,e,n,r,i,a,$,o)).join(", ")} `:"",m=y(t.input,e,n,r,i,a,$,o);return`${t.function==="rank"?"RANK":"ROW_NUMBER"}() OVER (${c}ORDER BY ${m} ${t.direction})`}case"cumulative":{if(l(t.input,n))throw new N("UNSUPPORTED_MIXED_OPERATOR","Cumulative expressions cannot consume a JavaScript operator");const c=y(t.input,e,n,r,i,a,$,o),m=t.partitionBy.length>0?`PARTITION BY ${t.partitionBy.map(f=>y(f,e,n,r,i,a,$,o)).join(", ")} `:"",A=t.orderBy.map(f=>`${y(f.expression,e,n,r,i,a,$,o)} ${f.direction}`).join(", ");return`${e.aggregateFunction(t.function,c)} OVER (${m}ORDER BY ${A} ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)`}case"ordinal-encode":{if(!a)throw new N("SQL_BINDER_UNAVAILABLE","Ordinal encoding requires a value binder");return`CASE ${t.comparable.values.map((m,A)=>`WHEN ${y(t.input,e,n,r,i,a,$,o)} = ${a(m)} THEN ${t.comparable.direction*A}`).join(" ")} END`}case"ordinal-decode":{if(!a)throw new N("SQL_BINDER_UNAVAILABLE","Ordinal decoding requires a value binder");return`CASE ${t.comparable.values.map((m,A)=>`WHEN ${y(t.input,e,n,r,i,a,$,o)} = ${t.comparable.direction*A} THEN ${a(m)}`).join(" ")} END`}case"operator":{const c=n.get(t.operator);if(c.kind==="component")throw new N("COMPONENT_OPERATOR_REQUIRES_EXECUTOR",`${t.operator} must be compiled through the executor component pipeline`);if(c.toSQL&&(t.input&&l(t.input,n)||t.components?.some(f=>l(f,n))))throw new N("UNSUPPORTED_MIXED_OPERATOR",`${t.operator} cannot consume a JavaScript operator in SQL`);let m=t.input?y(t.input,e,n,r,i,a,$,o):t.column?u(t.column,t.qualifier):void 0;const A=t.components?.map(f=>y(f,e,n,r,i,a,$,o));if(t.query){if(c.kind!=="aggregate")throw new N("OPERATOR_QUERY_REQUIRES_AGGREGATION",`Pred query is only supported by aggregation operators: ${t.operator}`);if(!i)throw new N("INVALID_OPERATOR_QUERY","Operator query compiler is unavailable");m=`CASE WHEN ${i(t.query)} THEN ${m??"1"} END`}if(c.requiresProperty!==!1&&!m)throw new N("PRED_PROPERTY_REQUIRED",`${t.operator} requires a column`);return c.toSQL?c.toSQL({sql:{aggregateFunction:e.aggregateFunction.bind(e),quoteIdentifier:e.quoteIdentifier.bind(e),concat:e.concat.bind(e),substring:e.substring.bind(e),dateBucket:e.dateBucket.bind(e),value:f=>{if(!a)throw new N("SQL_BINDER_UNAVAILABLE","SQL value binder is unavailable");return a(f)},condition:(f,_)=>{if(!$)throw new N("SQL_CONDITION_UNAVAILABLE","SQL condition compiler is unavailable");return $(f,_)}},...m?{expression:m,column:m}:{},...A?{expressions:A}:{},args:t.args}):m??"NULL"}}},l=(t,e)=>t.kind==="window"?l(t.input,e)||t.partitionBy.some(n=>l(n,e)):t.kind==="cumulative"?l(t.input,e)||t.partitionBy.some(n=>l(n,e))||t.orderBy.some(n=>l(n.expression,e)):t.kind==="ordinal-encode"||t.kind==="ordinal-decode"?l(t.input,e):t.kind==="operator"&&(!e.get(t.operator).toSQL&&!!e.get(t.operator).evaluate||(t.input?l(t.input,e):!1)||(t.components?.some(n=>l(n,e))??!1)),et=(t,e)=>t.sourceSql?P(t.sourceSql,t.sourceColumn,e,t.sourceTimestampColumn,t.sourceAlias):`${e.quoteIdentifier(t.sourceAlias)}.${e.quoteIdentifier(t.sourceColumn)}`,H=t=>typeof t=="object"&&t!==null&&!Array.isArray(t)&&Object.keys(t).some(e=>e.startsWith("$")),nt=(t,e,n)=>{if(!n.supportsRecursiveCte)throw new N("RECURSIVE_QUERY_UNSUPPORTED",`Provider ${n.kind} does not support recursive queries`);if(t.roots.length===0)return"(SELECT NULL WHERE 1 = 0)";const r=n.quoteIdentifier("__recursive_tree__"),i=n.quoteIdentifier("__recursive_id__"),a=n.quoteIdentifier("__recursive_node__"),$=n.quoteIdentifier("__recursive_child__"),o=n.quoteIdentifier(t.idColumn),u=n.quoteIdentifier(t.parentColumn),c=C(n,t.source,t.sourceSql),m=()=>t.roots.map(w=>e.add(w)).join(", "),A=(w,T=!1)=>t.roots.length===1?`${w} ${T?"<>":"="} ${m()}`:`${w} ${T?"NOT IN":"IN"} (${m()})`,f=`${a}.${o}`,_=t.includeSelf?A(f):`${A(`${a}.${u}`)} AND ${A(f,!0)}`;return`(WITH RECURSIVE ${r}(${i}) AS ( SELECT ${f} FROM ${n.tableAlias(c,"__recursive_node__")} WHERE ${_} UNION SELECT ${$}.${o} FROM ${n.tableAlias(c,"__recursive_child__")} JOIN ${r} ON ${$}.${u} = ${r}.${i}) SELECT DISTINCT ${i} FROM ${r})`},D=(t,e,n,r,i,a,$)=>{if(e==="$recursive"){if(!K(n))throw new N("INVALID_RECURSIVE_QUERY","$recursive query was not planned");return`${t} IN ${nt(n,r,i)}`}if(e==="$eq"&&n===null)return`${t} IS NULL`;if(e==="$ne"&&n===null)return`${t} IS NOT NULL`;const u={$eq:"=",$ne:"<>",$gt:">",$gte:">=",$lt:"<",$lte:"<="}[e];if(u){const c=B(n)?`(${a(n)})`:r.add(n);return`${t} ${u} ${c}`}if(e==="$in"||e==="$nin"){const c=e==="$in"?"IN":"NOT IN";if(B(n))return`${t} ${c} (${a(n)})`;if(!Array.isArray(n))throw new N("INVALID_QUERY_VALUE",`${e} requires an array or query LogicForm`);if(n.length===0)return e==="$in"?"0 = 1":"1 = 1";const m=n.filter(B);if(m.length>0){if(m.length!==n.length)throw new N("MIXED_SUBQUERY_VALUES",`${e} cannot mix query LogicForms and literal values`);return`${t} ${c} (${m.map(a).join(" UNION ALL ")})`}const A=n.map(f=>r.add(f)).join(", ");return`${t} ${c} (${A})`}if(B(n))throw new N("UNSUPPORTED_SUBQUERY_OPERATOR",`Query LogicForm is not supported by ${e}`);if(e==="$exists")return`${t} IS ${n?"NOT ":""}NULL`;if(e==="$contains")return`${t} LIKE ${r.add(`%${String(n)}%`)}`;if(e==="$regex"){if(typeof n!="string"||$!==void 0&&typeof $!="string")throw new N("INVALID_QUERY_VALUE","$regex requires a string pattern and args.options must be a string");return i.regex(t,r.add(n),$)}throw new N("UNSUPPORTED_QUERY_OPERATOR",`Unsupported query operator: ${e}`)},b=(t,e,n,r,i)=>{if(z(e)){const u=()=>`CASE ${e.comparable.values.map((f,_)=>`WHEN ${t} = ${n.add(f)} THEN ${e.comparable.direction*_}`).join(" ")} END`,c=new Set(["$gt","$gte","$lt","$lte"]),m=A=>typeof A!="object"||A===null||Array.isArray(A)?b(t,A,n,r,i):Object.entries(A).filter(([f])=>f!=="args").map(([f,_])=>(f==="$and"||f==="$or")&&Array.isArray(_)?`(${_.map(m).join(f==="$and"?" AND ":" OR ")})`:c.has(f)?D(u(),f,e.comparable.direction*e.comparable.values.indexOf(String(_)),n,r,i):D(t,f,_,n,r,i)).join(" AND ");return m(e.condition)}if(Array.isArray(e))return D(t,"$in",e,n,r,i);if(!H(e))return D(t,"$eq",e,n,r,i);const a=[],$=e.args;if($!==void 0){if(typeof $!="object"||$===null||Array.isArray($))throw new N("INVALID_QUERY_VALUE","Query args.options must be a string");const u=$.options;if(u!==void 0&&typeof u!="string")throw new N("INVALID_QUERY_VALUE","Query args.options must be a string")}const o=$?.options;for(const[u,c]of Object.entries(e))if(u==="$and"||u==="$or"){if(!Array.isArray(c))throw new N("INVALID_QUERY_VALUE",`${u} requires an array`);const m=c.map(A=>b(t,A,n,r,i));a.push(`(${m.join(u==="$and"?" AND ":" OR ")})`)}else u!=="args"&&a.push(D(t,u,c,n,r,i,u==="$regex"?o:void 0));if(a.length===0)throw new N("EMPTY_QUERY_CONDITION","Query condition contains no operators");return a.join(" AND ")},W=(t,e,n,r)=>{if(!r.arrayContains)throw new N("ARRAY_CONDITION_UNSUPPORTED",`Provider ${r.kind} does not support array conditions`);const i=r.arrayContains.bind(r),a=o=>i(t,n.add(o));if(Array.isArray(e))return`(${e.map(a).join(" OR ")})`;if(!H(e))return a(e);const $=[];for(const[o,u]of Object.entries(e))if(o==="$and"||o==="$or"){if(!Array.isArray(u))throw new N("INVALID_QUERY_VALUE",`${o} requires an array`);const c=u.map(m=>W(t,m,n,r));$.push(`(${c.join(o==="$and"?" AND ":" OR ")})`)}else if(o==="$eq")$.push(a(u));else if(o==="$ne")$.push(`NOT (${a(u)})`);else if(o==="$in"||o==="$nin"){if(!Array.isArray(u))throw new N("INVALID_QUERY_VALUE",`${o} requires an array`);const c=u.map(a),m=c.length===0?o==="$in"?"0 = 1":"1 = 1":c.join(o==="$in"?" OR ":" AND NOT ");$.push(o==="$nin"&&c.length>0?`NOT (${c.join(" OR ")})`:`(${m})`)}else if(o==="$exists")$.push(`${t} IS ${u?"NOT ":""}NULL`);else if(o!=="args")throw new N("UNSUPPORTED_ARRAY_QUERY_OPERATOR",`Unsupported array query operator: ${o}`);if($.length===0)throw new N("EMPTY_QUERY_CONDITION","Query condition contains no operators");return $.join(" AND ")},Q=(t,e,n,r,i,a)=>{const $=[];for(const[o,u]of Object.entries(t)){if(o==="$and"||o==="$or"){if(!Array.isArray(u))throw new N("INVALID_QUERY_VALUE",`${o} requires an array`);const m=u.map(A=>{if(typeof A!="object"||A===null||Array.isArray(A))throw new N("INVALID_QUERY_VALUE",`${o} items must be query objects`);return Q(A,e,n,r,i,a)});$.push(`(${m.join(o==="$and"?" AND ":" OR ")})`);continue}const c=e(o);$.push(n(o)?W(c,u,r,i):b(c,u,r,i,a))}return $.join(" AND ")},Y=(t,e,n,r,i)=>t.orderBy.map(a=>{const $=e.quoteIdentifier(a.name),o=`${r?`${r}.`:""}${$}`,u=a.comparable,c=!r&&i&&a.expression?i(a.expression):o;return`${u?`CASE ${u.values.map((A,f)=>`WHEN ${c} = ${n.add(A)} THEN ${u.direction*f}`).join(" ")} END`:o} ${a.direction}`}).join(", "),M=(t,e)=>{let n=t;for(;e.has(n);)n=`_${n}`;return n},st=(t,e,n,r,i)=>{const a=new Set(e.projections.map(({name:h})=>h)),$="__semanticdb_page_source",o="__semanticdb_page",u=r.quoteIdentifier($),c=r.quoteIdentifier(o),m=M("__semanticdb_row_number",a),A=M("__semanticdb_total_rows",a),f=r.quoteIdentifier(m),_=r.quoteIdentifier(A),w=Y(e,r,i,u),T=w?`ORDER BY ${w}`:"",d=`CEIL(${_} * ${n.ratio})`,U=n.page-1,O=n.page,s=[...e.projections.map(({name:h})=>h),...e.rowIdentity.kind==="property"?[e.rowIdentity.internalName]:[]].map(h=>`${c}.${r.quoteIdentifier(h)}`).join(", "),E=Y(e,r,i,c),I=`SELECT ${u}.*, ROW_NUMBER() OVER (${T}) AS ${f}, COUNT(*) OVER () AS ${_} FROM ${r.tableAlias(`(${t})`,$)}`;let S=`SELECT ${s} FROM ${r.tableAlias(`(${I})`,o)} WHERE ${c}.${f} > ${U} * ${d} AND ${c}.${f} <= ${O} * ${d}`;return E&&(S+=` ORDER BY ${E}`),S},V=(t,e,n,r)=>{const i=e.groupLimit;if(!i)return t;const a="__semanticdb_limit_by_source",$="__semanticdb_limit_by_ranked",o=n.quoteIdentifier(a),u=n.quoteIdentifier($),c=new Set(e.projections.map(({name:O})=>O)),m=M("__semanticdb_limit_by_row_number",c),A=n.quoteIdentifier(m),f=i.partitionBy.map(O=>`${o}.${n.quoteIdentifier(O)}`).join(", "),_=i.orderBy.map(({name:O,direction:R,comparable:s})=>{const E=`${o}.${n.quoteIdentifier(O)}`;return`${s?`CASE ${s.values.map((S,h)=>`WHEN ${E} = ${r.add(S)} THEN ${s.direction*h}`).join(" ")} END`:E} ${R}`}).join(", "),T=[...e.projections.map(({name:O})=>O),...e.rowIdentity.kind==="property"?[e.rowIdentity.internalName]:[]].map(O=>`${u}.${n.quoteIdentifier(O)}`).join(", "),d=`PARTITION BY ${f} ORDER BY ${_}`,U=`SELECT ${o}.*, ROW_NUMBER() OVER (${d}) AS ${A} FROM ${n.tableAlias(`(${t})`,a)}`;return`SELECT ${T} FROM ${n.tableAlias(`(${U})`,$)} WHERE ${u}.${A} <= ${i.count}`},k=(t,e,n=X(),r=0)=>{const i=new x(e,r);if(t.composition){const s=t.projections.map(({name:g})=>g),E=t.groupBy.map(({name:g})=>g),I=t.composition.map((g,j)=>{const F=k(g,e,n,i.nextParameterOffset);i.append(F.parameters);const p=`__composition_child_${j}`,G=e.quoteIdentifier(p),J=new Set(g.projections.map(({name:L})=>L));return`SELECT ${s.map(L=>J.has(L)?`${G}.${e.quoteIdentifier(L)} AS ${e.quoteIdentifier(L)}`:`NULL AS ${e.quoteIdentifier(L)}`).join(", ")} FROM ${e.tableAlias(`(${F.sql})`,p)}`}),S="__composition_union",h=e.quoteIdentifier(S);let q=`SELECT ${s.map(g=>{const j=`${h}.${e.quoteIdentifier(g)}`;return E.includes(g)?`${j} AS ${e.quoteIdentifier(g)}`:`MAX(${j}) AS ${e.quoteIdentifier(g)}`}).join(", ")} FROM ${e.tableAlias(`(${I.join(" UNION ALL ")})`,S)}`;return E.length>0&&(q+=` GROUP BY ${E.map(g=>`${h}.${e.quoteIdentifier(g)}`).join(", ")}`),t.groupLimit&&(q=V(q,t,e,i)),t.orderBy.length>0&&(q+=` ORDER BY ${Y(t,e,i)}`),t.pagination?.kind==="rows"&&(q=e.paginate(q,t.pagination.pageSize,0)),{sql:q,parameters:i.values}}const a=s=>{if(s.plan.projections.some(({expression:I})=>l(I,n)))throw new N("JAVASCRIPT_OPERATOR_IN_SUBQUERY","A query LogicForm cannot use a JavaScript-only operator");const E=k(s.plan.rowIdentity.kind==="property"?{...s.plan,rowIdentity:{kind:"generated"}}:s.plan,e,n,i.nextParameterOffset);return i.append(E.parameters),E.sql},$=(t.joins?.length??0)>0,o=(t.arrayExpansions?.length??0)>0,u=$||o||t.sourcePlan!==void 0||t.sourceSql!==void 0,c=new Map,m=(t.arrayExpansions??[]).map(s=>{if(!e.expandArray)throw new N("ARRAY_EXPANSION_UNSUPPORTED",`Provider ${e.kind} does not support array expansion`);const E=e.expandArray(et(s,e),s.alias,"value");return c.set(s.path,E.valueExpression),E}),A=s=>{const E=t.fieldReferences?.[s];if(E?.sql)return P(E.sql,E.property,e,E.timestampColumn,u?E.qualifier:void 0);if(E&&u)return`${e.quoteIdentifier(E.qualifier)}.${e.quoteIdentifier(E.column)}`;const I=t.fields[s];if(!I)throw new N("PROPERTY_NOT_FOUND",`Query property not found: ${s}`);return e.quoteIdentifier(I)},f=s=>y(s,e,n,u,E=>Q(E,A,I=>t.fieldReferences?.[I]?.isArray===!0,i,e,a),E=>i.add(E),(E,I)=>b(E,I,i,e,a),E=>{const I=c.get(E);if(!I)throw new N("ARRAY_EXPANSION_NOT_FOUND",`Array expansion not found: ${E}`);return I}),_=t.projections.map(s=>`${f(s.expression)} AS ${e.quoteIdentifier(s.name)}`),w=t.rowIdentity.kind==="property"?`${u&&t.sourceAlias?`${e.quoteIdentifier(t.sourceAlias)}.`:""}${e.quoteIdentifier(t.rowIdentity.column)} AS ${e.quoteIdentifier(t.rowIdentity.internalName)}`:void 0,T=[..._,...w?[w]:[]].join(", "),d=!t.sourcePlan&&t.sourceSql!==void 0&&tt(t.sourceSql)?{name:e.quoteIdentifier(t.schemaId),sql:t.sourceSql.trim().replace(/;+\s*$/,"")}:void 0,U=t.sourcePlan?(()=>{const s=k(t.sourcePlan,e,n,i.nextParameterOffset);return i.append(s.parameters),`(${s.sql})`})():d?d.name:C(e,t.source,t.sourceSql),O=u&&t.sourceAlias?e.tableAlias(U,t.sourceAlias):U;let R=`SELECT ${T} FROM ${O}`;for(const s of m)R+=` ${s.joinSql}`;for(const s of t.joins??[]){R+=` LEFT JOIN ${e.tableAlias(C(e,s.targetSource,s.targetSourceSql),s.targetAlias)}`;const E=s.sourceArrayExpansionPath?c.get(s.sourceArrayExpansionPath):s.sourceSql?P(s.sourceSql,s.sourceColumn,e,s.sourceTimestampColumn,s.sourceAlias):`${e.quoteIdentifier(s.sourceAlias)}.${e.quoteIdentifier(s.sourceColumn)}`,I=s.targetSql?P(s.targetSql,s.targetColumn,e,s.targetTimestampColumn,s.targetAlias):`${e.quoteIdentifier(s.targetAlias)}.${e.quoteIdentifier(s.targetColumn)}`;if(!E)throw new N("ARRAY_EXPANSION_NOT_FOUND",`Array expansion not found: ${s.path}`);if(R+=` ON ${E} = ${I}`,s.sourceTimestampColumn&&s.targetTimestampColumn&&s.sourceTimestampGranularity&&s.targetTimestampGranularity){const S=`${e.quoteIdentifier(s.sourceAlias)}.${e.quoteIdentifier(s.sourceTimestampColumn)}`,h=`${e.quoteIdentifier(s.targetAlias)}.${e.quoteIdentifier(s.targetTimestampColumn)}`;R+=` AND ${e.dateBucket(S,s.sourceTimestampGranularity)} = ${e.dateBucket(h,s.targetTimestampGranularity)}`}}if(t.query&&Object.keys(t.query).length>0&&(R+=` WHERE ${Q(t.query,A,s=>t.fieldReferences?.[s]?.isArray===!0,i,e,a)}`),t.groupBy.length>0&&(R+=` GROUP BY ${t.groupBy.map(s=>f(s.expression)).join(", ")}`),t.having&&Object.keys(t.having).length>0){const s=E=>{const I=t.projections.find(S=>S.name===E);if(!I)throw new N("INVALID_HAVING",`Having field is not an output: ${E}`);return e.supportsHavingAlias===!1?f(I.expression):e.quoteIdentifier(E)};R+=` HAVING ${Q(t.having,s,()=>!1,i,e,a)}`}if(t.groupLimit&&(R=V(R,t,e,i)),t.pagination?.kind==="ratio")R=st(R,t,t.pagination,e,i);else if(t.orderBy.length>0&&(R+=` ORDER BY ${Y(t,e,i,void 0,f)}`),t.pagination?.kind==="rows"){const s=(t.pagination.page-1)*t.pagination.pageSize;R=e.paginate(R,t.pagination.pageSize,s)}return d&&(R=`WITH ${d.name} AS (${d.sql}) ${R}`),{sql:R,parameters:i.values}};export{k as compilePlan};
@@ -1,2 +0,0 @@
1
- const h=e=>{if(typeof e!="string"||!/\bSELECT\b/i.test(e))return e;try{const c=d(e),i=[];for(const t of c){const s=$(e,t.selectEnd,t.fromStart);if(!s||s.length<2||s.some(u=>u.trim()==="*"))continue;const n=g(e.slice(t.fromStart,t.close),t,c),l=S(e,t,c),r=s.filter(u=>{const p=E(u);if(!p)return!0;const a=new RegExp(`(^|[^\\w$])${x(p)}([^\\w$]|$)`,"i");return a.test(n)||a.test(l)});if(r.length===s.length||r.length===0)continue;const f=e.slice(t.selectEnd,t.fromStart);i.push({start:t.selectEnd,end:t.fromStart,value:f.match(/^\s*/)[0]+r.map(u=>u.trim()).join(", ")+f.match(/\s*$/)[0]})}i.sort((t,s)=>s.start-t.start);let o=e;for(const t of i)o=o.slice(0,t.start)+t.value+o.slice(t.end);return o}catch{return e}},g=(e,c,i)=>m(e,i.filter(o=>o.open>c.open&&o.close<c.close).map(o=>({start:o.open-c.fromStart,end:o.close-c.fromStart+1}))),S=(e,c,i)=>{const o=i.filter(n=>n.open<c.open&&n.close>c.close).sort((n,l)=>n.close-n.open-(l.close-l.open))[0],t=o?o.open+1:0,s=o?o.close:e.length;return m(e.slice(t,s),i.filter(n=>n.open>=t&&n.close<s).map(n=>({start:n.open-t,end:n.close-t+1})))},m=(e,c)=>{if(!c.length)return e;const i=e.split("");for(const o of c)for(let t=Math.max(0,o.start);t<Math.min(i.length,o.end);t+=1)i[t]=" ";return i.join("")},d=e=>{const c=[],i=[];let o="",t="";for(let s=0;s<e.length;s+=1){const n=e[s],l=e[s+1];if(t==="--"){n===`
2
- `&&(t="");continue}if(t==="/*"){n==="*"&&l==="/"&&(t="",s+=1);continue}if(o){n===o&&e[s-1]!=="\\"&&(o="");continue}if(n==="-"&&l==="-"){t="--",s+=1;continue}if(n==="/"&&l==="*"){t="/*",s+=1;continue}if(n==="`"||n==='"'||n==="'"){o=n;continue}if(n==="("){i.push({open:s});continue}if(n!==")")continue;const r=i.pop();if(!r)continue;const f=/\bSELECT\b/i.exec(e.slice(r.open+1,s));if(!f)continue;const u=r.open+1+f.index,p=/\bFROM\b/i.exec(e.slice(u+6,s));p&&c.push({open:r.open,close:s,selectEnd:u+6,fromStart:u+6+p.index})}return c},$=(e,c,i)=>{const o=e.slice(c,i),t=[];let s=0,n=0,l="";for(let r=0;r<o.length;r+=1){const f=o[r];if(l){f===l&&o[r-1]!=="\\"&&(l="");continue}if(f==="`"||f==='"'||f==="'"){l=f;continue}f==="("?n+=1:f===")"?n-=1:f===","&&n===0&&(t.push(o.slice(s,r)),s=r+1)}return l||n!==0?null:(t.push(o.slice(s)),t)},E=e=>e.trim().match(/\bAS\s+(`[^`]+`|"[^"]+"|[A-Za-z_][\w$]*)\s*$/i)?.[1]?.replace(/^`|`$/g,"").replace(/^"|"$/g,"")??null,x=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");export{h as shortenSQL};
@@ -1,6 +0,0 @@
1
- import type { PredItemType } from '../logicform-types';
2
- import type { CustomFunctions, GenMetricComponentsOptions, MetricComponentNode, RuntimeCustomFunctionDefinition } from './types';
3
- export declare const loadCustomFunctions: (definitions: CustomFunctions) => readonly RuntimeCustomFunctionDefinition[];
4
- export declare const findCustomFunction: (definitions: readonly RuntimeCustomFunctionDefinition[], schemaId: string, name: string) => RuntimeCustomFunctionDefinition | undefined;
5
- export declare const nameForPredNode: (pred: PredItemType) => string;
6
- export declare const genMetricComponents: (pred: PredItemType, options: GenMetricComponentsOptions) => MetricComponentNode;
@@ -1 +0,0 @@
1
- import{SemanticDBError as m}from"../errors.js";import{defaultPredName as w}from"../normalizer/default-pred-name.js";import{createOperatorRegistry as S}from"../operators/index.js";const M=n=>Array.isArray(n)?n:Object.values(n),f=(n,e,r)=>{if(r!==void 0){if(typeof r=="function")return r;try{const s=Function(`return (${r})`)();if(typeof s!="function")throw new Error("source did not evaluate to a function");return s}catch(o){throw new m("INVALID_CUSTOM_FUNCTION_CALLBACK",`Cannot load ${n.name}.${e}: ${o instanceof Error?o.message:String(o)}`,{function:n.name,field:e})}}},i=n=>M(n).map(e=>{const{genComponents:r,mergeComponents:o,genMergeSQL:s,...a}=e;return{...a,genComponents:f(e,"genComponents",r),...o?{mergeComponents:f(e,"mergeComponents",o)}:{},...s?{genMergeSQL:f(e,"genMergeSQL",s)}:{}}}),N=(n,e,r)=>n.find(o=>o.name===r&&o.schema===e)??n.find(o=>o.name===r&&o.schema===void 0),y=n=>w(n,S()),T=(n,e)=>({version:"2.0",schema:n,preds:[e]}),l=(n,e)=>{const r=i(e.customFunctions),o=e.maxDepth??32,s={schemas:e.schemas,customFunctions:e.customFunctions,...e.permissions?{permissions:e.permissions}:{}},a=(c,O,C,d)=>{if(d>o)throw new m("CUSTOM_FUNCTION_MAX_DEPTH",`Custom function component depth exceeds ${o}`);const t=c.schema??O,u=c.operator?N(r,t,c.operator):void 0;if(!u)return{pred:c,schema:t,components:[]};const p=`${t}:${u.name}`;if(C.includes(p))throw new m("CUSTOM_FUNCTION_CYCLE",`Custom function component cycle: ${[...C,p].join(" -> ")}`);const h=e.schemas[t];if(!h)throw new m("SCHEMA_NOT_FOUND",`Schema is not registered: ${t}`);const F=e.logicform??T(t,c),g=u.genComponents(c,{schema:h,logicform:F,nameForPredNode:y,helperFunctions:s});if(!Array.isArray(g))throw new m("INVALID_CUSTOM_FUNCTION_COMPONENTS",`${u.name}.genComponents must return an array`);return{pred:c,schema:t,components:g.map(_=>a(_,t,[...C,p],d+1))}};return a(n,e.schema,[],0)};export{N as findCustomFunction,l as genMetricComponents,i as loadCustomFunctions,y as nameForPredNode};
@@ -1,3 +0,0 @@
1
- export { findCustomFunction, genMetricComponents, loadCustomFunctions, nameForPredNode, } from './custom-functions';
2
- export { registerCustomFunctionOperators } from './operator-adapter';
3
- export type { CustomFunctionCallback, CustomFunctionColumnProperty, CustomFunctionDefinition, CustomFunctionHelpers, CustomFunctionSqlContext, CustomFunctions, GenComponents, GenComponentsContext, GenMergeSQL, GenMetricComponentsOptions, MergeComponents, MetricComponentNode, RuntimeCustomFunctionDefinition, } from './types';
@@ -1,12 +0,0 @@
1
- import type { OperatorRegistry } from '../operators/index';
2
- import type { CustomFunctionHelpers, CustomFunctions, RuntimeCustomFunctionDefinition } from './types';
3
- interface AdapterOptions {
4
- readonly schemas: CustomFunctionHelpers['schemas'];
5
- readonly customFunctions: CustomFunctions;
6
- readonly definitions: readonly RuntimeCustomFunctionDefinition[];
7
- readonly config: Readonly<Record<string, unknown>>;
8
- readonly permissions?: CustomFunctionHelpers['permissions'];
9
- readonly locale?: string;
10
- }
11
- export declare const registerCustomFunctionOperators: (registry: OperatorRegistry, options: AdapterOptions) => OperatorRegistry;
12
- export {};
@@ -1 +0,0 @@
1
- import{SemanticDBError as m}from"../errors.js";import{defaultPredName as w}from"../normalizer/default-pred-name.js";import{clone as O}from"../utils/clone.js";import{findCustomFunction as T}from"./custom-functions.js";const E=e=>{const n=O(e);return delete n.having,delete n.sort,delete n.limit,delete n.page,n},y=(e,n)=>{const r=[e,n].filter(o=>o!==void 0&&Object.keys(o).length>0);if(r.length!==0)return r.length===1?r[0]:{$and:r}},F=(e,n)=>{if(!e.schema)throw new m("CUSTOM_FUNCTION_SCHEMA_REQUIRED","Custom functions require a physical LogicForm schema");const r=E(e),o=O(n);r.schema=o.schema??e.schema,delete o.schema,r.preds=[o];const t=y(e.query,o.query);return delete o.query,t?r.query=t:delete r.query,r},R=(e,n)=>{if(!Array.isArray(n)||n.length===0)throw new m("INVALID_CUSTOM_FUNCTION_COMPONENTS",`${e.name}.genComponents must return a non-empty array`);return n},_=(e,n)=>({name:n,type:e.type??"number",primal_type:e.primal_type??"number",isArray:!1}),I=e=>{const n=e.mergeMode??"auto";if(n==="sql"&&!e.genMergeSQL)throw new m("CUSTOM_FUNCTION_SQL_MERGER_REQUIRED",`${e.name} uses mergeMode sql but does not define genMergeSQL`);if(n==="js"&&!e.mergeComponents)throw new m("CUSTOM_FUNCTION_JS_MERGER_REQUIRED",`${e.name} uses mergeMode js but does not define mergeComponents`);if(n==="sql"||n==="auto"&&e.genMergeSQL)return"sql";if(e.mergeComponents)return"js";throw new m("CUSTOM_FUNCTION_MERGER_REQUIRED",`${e.name} must define genMergeSQL or mergeComponents`)},$=(e,n,r,o)=>({name:e,defaultName:({operandName:t,locale:c})=>c.toLowerCase().startsWith("en")?`${e.replace(/^\$/,"")} of ${t}`:`${t}${e.replace(/^\$/,"")}`,kind:"component",requiresProperty:!1,createComponent(t){const c=t.sourceLogicform??t.logicform;if(!c.schema)throw new m("CUSTOM_FUNCTION_SCHEMA_REQUIRED","Custom functions require a physical LogicForm schema");const a=T(r.definitions,t.pred.schema??c.schema,e);if(!a)throw new m("CUSTOM_FUNCTION_NOT_FOUND",`Custom function is not registered for schema ${c.schema}: ${e}`);const i=r.schemas[c.schema];if(!i)throw new m("SCHEMA_NOT_FOUND",`Schema is not registered: ${c.schema}`);const p={schemas:r.schemas,customFunctions:r.customFunctions,...r.permissions?{permissions:r.permissions}:{}},f=s=>w(s,o,{...r.locale?{locale:r.locale}:{}}),M=a.genComponents(t.pred,{schema:i,logicform:c,nameForPredNode:f,helperFunctions:p}),u=R(a,M).map(s=>({...s,name:s.name??f(s)})),l=new Set;for(const s of u){if(l.has(s.name))throw new m("DUPLICATE_CUSTOM_FUNCTION_COMPONENT",`Duplicate component name in ${a.name}: ${s.name}`);l.add(s.name)}const C=u.map(s=>({name:s.name,component:{kind:"query",logicform:F(c,s),prepare:!0}})),g={..._(a,t.outputName),components:u,baseProperty:t.pred},h=a.exposeComponents??!0;if(I(a)==="sql"){const s=a.genMergeSQL;return{kind:"cte",components:C,outputName:t.outputName,exposeComponents:h,toSQL:({values:d,quoteIdentifier:U})=>s(g,{...p,values:d,q:N=>d[N]??U(N)},r.config)}}const S=a.mergeComponents;return{kind:"js",components:C,outputName:t.outputName,exposeComponents:h,mergeRow:s=>S(s,g,r.config)}},getOutputProperty({name:t}){return _(n[0],t)}}),q=(e,n)=>{const r=new Set(n.definitions.map(({name:o})=>o));for(const o of r){if(e.has(o))throw new m("CUSTOM_FUNCTION_OPERATOR_CONFLICT",`Custom function conflicts with an existing operator: ${o}`);e.register($(o,n.definitions.filter(t=>t.name===o),n,e))}return e};export{q as registerCustomFunctionOperators};
@@ -1,62 +0,0 @@
1
- import type { LogicformType, PredItemType } from '../logicform-types';
2
- import type { ResultProperty } from '../operators/index';
3
- import type { Permissions } from '../permissions/index';
4
- import type { SemanticSchemaDraft } from '../semantic-types/index';
5
- export type CustomFunctionCallback<T extends (...args: never[]) => unknown> = T | string;
6
- export interface CustomFunctionHelpers {
7
- readonly schemas: Readonly<Record<string, SemanticSchemaDraft>>;
8
- readonly customFunctions: CustomFunctions;
9
- /** The execution permissions inherited by every generated component query. */
10
- readonly permissions?: Permissions;
11
- }
12
- export interface GenComponentsContext {
13
- readonly schema: SemanticSchemaDraft;
14
- readonly logicform: LogicformType;
15
- readonly nameForPredNode: (pred: PredItemType, schema?: SemanticSchemaDraft, helperFunctions?: CustomFunctionHelpers) => string;
16
- readonly helperFunctions: CustomFunctionHelpers;
17
- }
18
- export interface CustomFunctionColumnProperty extends ResultProperty {
19
- readonly components: readonly PredItemType[];
20
- readonly baseProperty: PredItemType;
21
- }
22
- export interface CustomFunctionSqlContext extends CustomFunctionHelpers {
23
- /** Quote a name, or resolve a component name to its qualified CTE expression. */
24
- readonly q: (name: string) => string;
25
- readonly values: Readonly<Record<string, string>>;
26
- }
27
- export type GenComponents = (self: PredItemType, context: GenComponentsContext) => PredItemType[];
28
- export type MergeComponents = (values: Record<string, unknown>, columnProperty: CustomFunctionColumnProperty, config: Readonly<Record<string, unknown>>) => unknown;
29
- export type GenMergeSQL = (columnProperty: CustomFunctionColumnProperty, context: CustomFunctionSqlContext, config: Readonly<Record<string, unknown>>) => string;
30
- export interface CustomFunctionDefinition {
31
- readonly name: string;
32
- /** Optional Schema scope. Definitions without a schema are global. */
33
- readonly schema?: string;
34
- readonly type?: string;
35
- readonly primal_type?: ResultProperty['primal_type'];
36
- readonly genComponents: CustomFunctionCallback<GenComponents>;
37
- readonly mergeComponents?: CustomFunctionCallback<MergeComponents>;
38
- readonly genMergeSQL?: CustomFunctionCallback<GenMergeSQL>;
39
- /** auto prefers SQL and falls back to JavaScript when no SQL merger is supplied. */
40
- readonly mergeMode?: 'auto' | 'sql' | 'js';
41
- /** Keep named component values on result rows, matching the legacy executor. */
42
- readonly exposeComponents?: boolean;
43
- }
44
- export type CustomFunctions = readonly CustomFunctionDefinition[] | Readonly<Record<string, CustomFunctionDefinition>>;
45
- export interface GenMetricComponentsOptions {
46
- readonly schemas: Readonly<Record<string, SemanticSchemaDraft>>;
47
- readonly customFunctions: CustomFunctions;
48
- readonly permissions?: Permissions;
49
- readonly schema: string;
50
- readonly logicform?: LogicformType;
51
- readonly maxDepth?: number;
52
- }
53
- export interface MetricComponentNode {
54
- readonly pred: PredItemType;
55
- readonly schema: string;
56
- readonly components: readonly MetricComponentNode[];
57
- }
58
- export interface RuntimeCustomFunctionDefinition extends Omit<CustomFunctionDefinition, 'genComponents' | 'mergeComponents' | 'genMergeSQL'> {
59
- readonly genComponents: GenComponents;
60
- readonly mergeComponents?: MergeComponents;
61
- readonly genMergeSQL?: GenMergeSQL;
62
- }
package/dist/errors.js DELETED
@@ -1 +0,0 @@
1
- class s extends Error{code;details;constructor(r,e,t){super(e),this.code=r,this.details=t,this.name="SemanticDBError"}}export{s as SemanticDBError};
@@ -1 +0,0 @@
1
- import{resolvePlugins as E}from"../plugins/index.js";const p=e=>{if(Array.isArray(e))return e.map(p).filter(t=>t!==void 0);if(typeof e!="object"||e===null||Object.prototype.toString.call(e)!=="[object Object]")return e;const o=Object.entries(e),n=o.filter(([,t])=>t!==null).map(([t,a])=>[t,p(a)]).filter(([,t])=>t!==void 0);if(!(o.length>0&&n.length===0))return Object.fromEntries(n)},F=e=>{if(e.comparable!=null)return e.comparable;if(e.is_comparable!==!0||e.isArray===!0||e.type!=="string"&&e.type!=="category"||!Array.isArray(e.constraints?.enum))return;const n=e.constraints.enum.map(t=>Array.isArray(t)?t[0]:t);if(!(n.length===0||n.some(t=>typeof t!="string")))return{values:[...new Set(n)],direction:e.comparable_order===-1?-1:1}},K=e=>{if(typeof e!="object"||e===null||Array.isArray(e))return e;const o=e;if(o.sql!=null)return Object.keys(o).every(n=>n==="sql")?e:{sql:o.sql}},v=(e,o=[],n=!0)=>{const t=E(o),a={},h=new Set(t.flatMap(d=>[...d.schemaMetadata?.keys??[],...d.legacySchemaKeys??[]]));for(const[d,_]of Object.entries(e)){const s=p(_),l=s,j=(Array.isArray(l.properties)?l.properties:[]).some(i=>i.is_observation===!0)||l.is_observation===!0,A=l.is_snapshot===!0,f=typeof s.id=="string"&&s.id.length>0?s.id:n&&typeof s._id=="string"&&s._id.length>0?s._id:s.id,{properties:O}=s,S=Object.fromEntries(Object.entries(s).filter(([i])=>(n?!["_id","_sid","sid","is_observation","is_snapshot"].includes(i):i!=="properties")&&i!=="properties"&&!h.has(i))),m=O.map(i=>{const r=i,y=typeof r.id=="string"&&r.id.length>0?r.id:n&&typeof r._id=="string"&&r._id.length>0?r._id:r.id,{udf:P,...b}=r,u=F(r),g=K(P),M=u!==void 0&&r.comparable==null?"category":r.type==="object"?"entity":r.type;return{...n?Object.fromEntries(Object.entries(b).filter(([q])=>!["_id","_sid","sid","is_observation","is_comparable","comparable_order"].includes(q))):b,type:M,...y!==void 0?{id:y}:{},...g!==void 0?{udf:g}:{},...u!==void 0?{comparable:u}:{}}});let c={};for(const i of t)for(const r of i.schemaMetadata?.keys??[])s[r]!==void 0&&(c={...c,[r]:s[r]});for(const i of t)c={...c,...i.normalizeLegacySchema?.({source:s,properties:m})};const z={...S,...f!==void 0?{id:f}:{},properties:m,...n&&(A||j)?{temporalSemantics:"snapshot"}:{},...c};a[d]=z}return a};export{v as normalizeSchemas};
@@ -1 +0,0 @@
1
- import{SemanticDBError as l}from"../errors.js";import{clone as P}from"../utils/clone.js";import{groupRowIdentity as b}from"./row-identity.js";const R=r=>{const e=P(r);return delete e.having,delete e.sort,delete e.limit,delete e.page,e},m=(r,e)=>r.operator&&e.get(r.operator).kind==="component"?!0:typeof r.pred=="object"&&m(r.pred,e)||(r.components?.some(i=>m(i,e))??!1),j=(r,e,i,o,n,t)=>{const s=r.preds??[],c=s.map((u,p)=>({pred:u,index:p,definition:u.operator?o.get(u.operator):void 0})).filter(({definition:u})=>u?.kind==="component");if(c.length===0)return;for(const u of s)if((!u.operator||o.get(u.operator).kind!=="component")&&(typeof u.pred=="object"&&m(u.pred,o)||(u.components?.some(p=>m(p,o))??!1)))throw new l("UNSUPPORTED_COMPONENT_NESTING","A component operator must currently be the top-level projection operator");const a=[],d=s.filter((u,p)=>!c.some(y=>y.index===p));if(d.length>0){const u=R(r);u.preds=d,a.push({kind:"query",logicform:u})}const g=r.groupby?.length??0;for(const{pred:u,index:p,definition:y}of c){const A=y?.createComponent;if(!A)continue;const w=e.projections[g+p]?.name;if(!w)throw new l("INVALID_COMPONENT_PLAN","Component output projection is missing");const C=t?.preds?.[p],h=A({logicform:r,pred:C??u,outputName:w,schema:i,resolveSchema:n,...t?{sourceLogicform:t}:{}});if(h.kind==="query"&&(h.logicform.preds??[]).some(E=>m(E,o)))throw new l("UNSUPPORTED_COMPONENT_NESTING","Nested component operators are not supported yet");a.push(h)}return a},f=r=>r instanceof Date?r.getTime():r,v=(r,e,i,o)=>{const n=f(r),t=f(i);switch(e){case"$eq":return n===t;case"$ne":return n!==t;case"$gt":return n!=null&&t!==void 0&&t!==null&&n>t;case"$gte":return n!=null&&t!==void 0&&t!==null&&n>=t;case"$lt":return n!=null&&t!==void 0&&t!==null&&n<t;case"$lte":return n!=null&&t!==void 0&&t!==null&&n<=t;case"$in":return Array.isArray(i)&&i.some(s=>f(s)===n);case"$nin":return Array.isArray(i)&&i.every(s=>f(s)!==n);case"$exists":return i?r!=null:r==null;case"$contains":return String(r).includes(String(i));case"$regex":return typeof i=="string"&&new RegExp(i,o).test(String(r));default:throw new l("UNSUPPORTED_QUERY_OPERATOR",`Unsupported having operator: ${e}`)}},S=(r,e)=>{if(!e||typeof e!="object"||Array.isArray(e))return f(r)===f(e);const i=Object.entries(e),o=e.args,n=o&&typeof o=="object"&&!Array.isArray(o)?o.options:void 0;return i.every(([t,s])=>{if(t==="args")return!0;if(t==="$and"||t==="$or"){if(!Array.isArray(s))return!1;const c=s.map(a=>S(r,a));return t==="$and"?c.every(Boolean):c.some(Boolean)}return v(r,t,s,typeof n=="string"?n:void 0)})},$=(r,e)=>Object.entries(e).every(([i,o])=>{if(i==="$and"||i==="$or"){if(!Array.isArray(o))return!1;const n=o.map(t=>$(r,t));return i==="$and"?n.every(Boolean):n.some(Boolean)}return S(r[i],o)}),N=(r,e)=>e.length===0?"0":b(r,e),O=(r,e)=>{const i=new Map;for(const o of r)for(const n of o){const t=N(n,e);i.set(t,{...i.get(t)??{},...n})}return[...i.values()]},B=(r,e)=>{const i=e.groupBy.map(({name:n})=>n);let o=O(r,i);if(e.having&&(o=o.filter(n=>$(n,e.having))),e.groupLimit){const n=e.groupLimit,t=new Map;for(const s of o){const c=N(s,n.partitionBy);t.set(c,[...t.get(c)??[],s])}o=[...t.values()].flatMap(s=>s.sort((c,a)=>{for(const d of n.orderBy){const g=f(c[d.name]),u=f(a[d.name]);if(g!==u)return g==null?d.direction==="ASC"?-1:1:u==null?d.direction==="ASC"?1:-1:(g<u?-1:1)*(d.direction==="ASC"?1:-1)}return 0}).slice(0,n.count))}if(e.orderBy.length>0&&o.sort((n,t)=>{for(const s of e.orderBy){const c=f(n[s.name]),a=f(t[s.name]);if(c!==a)return c==null?s.direction==="ASC"?-1:1:a==null?s.direction==="ASC"?1:-1:(c<a?-1:1)*(s.direction==="ASC"?1:-1)}return 0}),e.pagination?.kind==="rows"){const n=(e.pagination.page-1)*e.pagination.pageSize;o=o.slice(n,n+e.pagination.pageSize)}else if(e.pagination?.kind==="ratio"){const n=Math.ceil(o.length*e.pagination.ratio),t=(e.pagination.page-1)*n;o=o.slice(t,t+n)}return o};export{j as createExecutionUnits,O as mergeComponentRows,B as mergeExecutionResults};
@@ -1 +0,0 @@
1
- import{isDeepStrictEqual as c}from"node:util";import{SemanticDBError as n}from"../errors.js";import{createProvider as p}from"../physical/connection.js";import"@clickhouse/client";import"mysql2/promise";import"mysql2";import"oracledb";import"pg";import"snowflake-sdk";class i{create;#r=new Map;constructor(r=p){this.create=r}get(r){const o=this.#r.get(r.id);if(o){if(!c(o.connection,r))throw new n("DATABASE_CONNECTION_CONFIGURATION_MISMATCH",`Database connection configuration changed for id: ${r.id}`,{connectionId:r.id});return o.provider}const t=this.create(r);return this.#r.set(r.id,{connection:r,provider:t}),t}async close(){const r=[...this.#r.values()].map(({provider:e})=>e);this.#r.clear();const o=await Promise.allSettled(r.map(async e=>e.close())),t=[];for(const e of o)e.status==="rejected"&&t.push(e.reason);if(t.length>0)throw new AggregateError(t,"Failed to close one or more database connections")}}const a=new i,d=s=>a.get(s),m=async()=>a.close();export{i as ConnectionRegistry,m as closeConnections,d as getConnectionProvider};
@@ -1 +0,0 @@
1
- const c=(t,n)=>{if(t.kind!=="operator")return!1;const e=n.get(t.operator);return!e.toSQL&&!!e.evaluate||(t.input?c(t.input,n):!1)||(t.components?.some(a=>c(a,n))??!1)},u=(t,n,e,a)=>{if(t.kind!=="operator")return n[e];const r=a.get(t.operator),i=t.input?u(t.input,n,e,a):n[e];return r.evaluate?Promise.resolve(i).then(o=>r.evaluate?.({input:o,args:t.args})):i},l=async(t,n,e)=>{const a=n.filter(({expression:r})=>c(r,e));return a.length===0?[...t]:Promise.all(t.map(async r=>{const i={...r};for(const o of a)i[o.name]=await u(o.expression,i,o.name,e);return i}))};export{l as evaluateJavaScriptProjections};
@@ -1 +0,0 @@
1
- import{resolveQueryExpiration as d}from"../cache/expiry.js";import"node:crypto";import"../operators/index.js";import{isLogicalQuerySubquery as m,isLogicalRecursiveQuery as y}from"../planner/types.js";import{shortenSQL as g}from"../compiler/shorten-sql.js";const i=(e,t,r)=>{if(m(e)){t.push(e.plan);return}if(y(e)){r.set(`${e.schemaId}:${e.source}`,{schemaId:e.schemaId,source:e.source});return}if(Array.isArray(e)){for(const o of e)i(o,t,r);return}if(!(typeof e!="object"||e===null||e instanceof Date))for(const o of Object.values(e))i(o,t,r)},f=(e,t,r)=>{if(e.kind==="window"){f(e.input,t,r);for(const o of e.partitionBy)f(o,t,r);return}if(e.kind==="operator"){i(e.query,t,r),e.input&&f(e.input,t,r);for(const o of e.components??[])f(o,t,r)}},a=e=>{const t=new Map,r=c=>{t.set(`${c.schemaId}:${c.source}`,c)};if(e.composition)for(const c of e.composition)for(const s of a(c))r(s);else if(e.sourcePlan)for(const c of a(e.sourcePlan))r(c);else r({schemaId:e.schemaId,source:e.source});for(const c of e.joins??[])r({schemaId:c.targetSchemaId,source:c.targetSource});const o=[];i(e.query,o,t),i(e.having,o,t);for(const c of e.projections)f(c.expression,o,t);for(const c of o)for(const s of a(c))r(s);return[...t.values()]},w=e=>{const t=new Map;for(const r of e.flat())t.set(`${r.schemaId}:${r.source}`,r);return[...t.values()]},I=(e,t)=>{const r=[];for(const o of e){const c=t.findSource(o.schemaId,o.source);if(!c?.freshness)return;r.push(c.freshness)}return r},l=async(e,t,r)=>{e=u(e),r.signal?.throwIfAborted();const o=r.cache?I(t,r.schemaMappings):void 0;if(!r.cache||!o)return r.provider.execute({...e,...r.signal?{signal:r.signal}:{}});const c={namespace:r.cache.namespace,provider:r.provider.kind,sql:e.sql,parameters:e.parameters};try{const n=await r.cache.store.get(c);if(r.signal?.throwIfAborted(),n)return[...n]}catch{r.signal?.throwIfAborted()}const s=await r.provider.execute({...e,...r.signal?{signal:r.signal}:{}});try{const n=d(o,new Date);await r.cache.store.set(c,s,{sources:[...new Set(t.map(({source:h})=>h))],...n?{expiresAt:n}:{}})}catch{}return s},u=e=>({...e,sql:g(e.sql)});export{a as collectPlanSources,l as executeCompiledQuery,w as mergePhysicalSources,u as shortenCompiledQuery};
@@ -1 +0,0 @@
1
- import{performance as ae}from"node:perf_hooks";import{SemanticDBError as S}from"../errors.js";import{compilePlan as Z}from"../compiler/compile-plan.js";import{compileCteCalculation as ie}from"../compiler/compile-cte.js";import{evaluateJavaScriptProjections as ee}from"./evaluate.js";import{createExecutionUnits as ce,mergeExecutionResults as fe,mergeComponentRows as ge}from"./components.js";import{fetchEntities as he}from"./fetch-entities.js";import{hydrateResult as we}from"./result-hydrator/hydrate-result.js";import{addRowIdentities as ye}from"./row-identity.js";import{mergePhysicalSources as me,collectPlanSources as Q,executeCompiledQuery as B,shortenCompiledQuery as Se}from"./execute-query.js";import{normalizeLogicform as G}from"../normalizer/normalize-logicform.js";import{assertSupportedLogicformVersion as ve}from"../normalizer/version.js";import{createOperatorRegistry as Re}from"../operators/index.js";import{buildLineage as Ee}from"../planner/build-lineage.js";import{createLogicalPlan as z,createResultSchema as Pe,createDerivedSourceSchema as De}from"../planner/create-logical-plan.js";import{getSchema as Ie}from"../schema/schema-registry.js";import{createSemanticTypeRegistry as Ne}from"../semantic-types/index.js";import{validatePermissions as _e,applyPermissions as oe,isColumnAllowed as V,getSchemaPermissions as Ce}from"../permissions/permissions.js";import{getConnectionProvider as Oe}from"./connection-registry.js";import{loadCustomFunctions as Ae}from"../custom-functions/custom-functions.js";import{registerCustomFunctionOperators as Le}from"../custom-functions/operator-adapter.js";import{assertNoLegacyLogicformFields as qe,splitLegacySchemas as Te,normalizeLegacyLogicform as je}from"../compatibility/logicform.js";import{normalizeSchemas as Ue}from"./compatibility.js";import{OperatorRegistry as Fe}from"../operators/registry.js";import{resolveSchema as Me}from"../semantic-types/resolve-schema.js";const le=n=>n instanceof Error?n:new Error(String(n)),xe=n=>n.stack?`${n.message} [stack: ${n.stack}]`:n.message,Ke=(n,i,s={})=>{const a=le(n);return{errorCode:"100",error:xe(a),result:[],...s.schema?{schema:s.schema}:{},normedLogicform:s.normedLogicform??i,sqls:s.sqls??[],...s.provider?{provider:s.provider}:{},...s.lineage?{lineage:s.lineage}:{}}},$e=async(n,i,s)=>{await n?.({...i,partialResult:s})},be=(n,i,s)=>({type:s,sql:n.sql,parameters:[...n.parameters],displaySql:i.displayQuery(n.sql,n.parameters)}),pe=(n,i)=>{if(i.connectionId)for(const s of Q(n)){const a=i.schemaMappings.findSource(s.schemaId,s.source);if(!a)throw new S("SCHEMA_MAPPING_NOT_FOUND",`Schema mapping is not registered: ${s.schemaId}:${s.source}`,{schemaId:s.schemaId,source:s.source});if(a.connectionId!==i.connectionId)throw new S("CROSS_CONNECTION_QUERY_UNSUPPORTED",`One physical query cannot use multiple database connections: ${i.connectionId}, ${a.connectionId}`,{schemaId:s.schemaId,source:s.source,connectionId:a.connectionId})}},ke=n=>{const i=new Set,s=a=>{a.schema&&i.add(a.schema),a.from&&s(a.from);for(const P of a.logicforms??[])s(P)};return s(n),[...i]},de=async(n,i)=>{const s=i.plugins??[],a=n.version,P=typeof a=="string"&&(/^2\./.test(a)||/^[3-9]\d*\./.test(a)),N=a===void 0||typeof a=="string"&&/^1\./.test(a);P&&qe(n);const v=N?Te(je(n),i.schemas):n,e={...i,schemas:Ue(i.schemas,s,N)},f=ae.now(),D=e.semanticTypes??Ne(),c=e.operators?new Fe(e.operators.definitions()):Re(s);if(e.operators)for(const t of s)for(const r of t.operators??[])if(c.has(r.name)){if(c.get(r.name)!==r)throw new S("PLUGIN_OPERATOR_ALREADY_REGISTERED",`Plugin Operator is already registered: ${r.name}`,{operator:r.name,plugin:t.name})}else c.register(r);e.customFunctions&&Le(c,{schemas:e.schemas,customFunctions:e.customFunctions,definitions:Ae(e.customFunctions),config:{...e.customFunctionConfig??{},...e.permissions?{permissions:e.permissions}:{}},...e.permissions?{permissions:e.permissions}:{},...e.locale?{locale:e.locale}:{}});const L=e.schemaMappings,se=new Map;let q={provider:e.provider.kind};const O=[],T=(t,r)=>{O.push(be(Se(t),e.provider,r)),q={...q,sqls:[...O]}},w=async(t,r={})=>{q={...q,...r},await $e(e.onProgress,t,q)},te=t=>Me(Ie(t,e.schemas),D,s),Y=new Map,g=t=>{const r=Y.get(t);return r||(Ce(e.permissions,t),te(t))},j=t=>{if(t.schema)return g(t.schema);if(t.from)return j(t.from);const r=t.logicforms?.[0];if(r)return j(r);throw new S("LOGICFORM_SCHEMA_REQUIRED","A LogicForm must contain a physical schema leaf")},x={resolveSchema:g,canUsePropertyRowIdentity:(t,r)=>V(e.permissions,t.id,r)},H=(t,r)=>{const h=De(z(t,j(t),c,L,x),r);return Y.set(h.id,h),h},J=async(t,r)=>{const h=`${t.id}:${r}`,K=se.get(h);if(K)return K;const d=(async()=>{const W=oe({version:v.version,schema:t.id,preds:[{operator:"$max",pred:r,name:"__latestDataDate__"}]},e.permissions,g,!1,new Set,s),A=await G(W,t,{semanticTypes:D,operators:c,plugins:s,...e.locale?{locale:e.locale}:{},resolveSchema:g}),_=z(A,t,c,L,x);pe(_,e);const U=Z(_,e.provider,c);T(U,"semantic-resolution");const I=(await B(U,Q(_),e))[0],y=I?.__latestDataDate__??Object.values(I??{})[0];if(y==null||!(y instanceof Date)&&typeof y!="string"&&typeof y!="number")return;const $=y instanceof Date?y:new Date(y);if(!Number.isNaN($.getTime()))return $})();return se.set(h,d),d};try{e.signal?.throwIfAborted(),ve(v),await w({stage:"started",logicform:v}),_e(e.permissions,te);const t=j(v);await w({stage:"validated",schema:t});const r=oe(v,e.permissions,g,!0,new Set,s),h=await G(r,t,{semanticTypes:D,operators:c,plugins:s,...e.locale?{locale:e.locale}:{},resolveSchema:g,resolveFromSchema:H,canProjectProperty:(o,l)=>V(e.permissions,o.id,l),requestLatestDataDate:(o,l)=>J(o,l.id)}),K=e.customFunctions?await G(v,t,{semanticTypes:D,operators:c,plugins:s,...e.locale?{locale:e.locale}:{},resolveSchema:g,resolveFromSchema:H,canProjectProperty:(o,l)=>V(e.permissions,o.id,l),requestLatestDataDate:(o,l)=>J(o,l.id)}):void 0;await w({stage:"normalized",normedLogicform:h},{normedLogicform:h});const d=z(h,t,c,L,x);pe(d,e);const W=d.columnProperties??[],A=Pe(d,t);Y.set(A.id,A),await w({stage:"planned",plan:d},{schema:A});const _=Ee(d,t,e.provider,c);await w({stage:"lineage",lineage:_},{lineage:_});const U=ce(h,d,t,c,g,K),F=async o=>{const l=j(o.logicform),R=o.prepare?await G(oe(o.logicform,e.permissions,g,!0,new Set,s),l,{semanticTypes:D,operators:c,plugins:s,...e.locale?{locale:e.locale}:{},resolveSchema:g,resolveFromSchema:H,canProjectProperty:(m,E)=>V(e.permissions,m.id,E),requestLatestDataDate:(m,E)=>J(m,E.id)}):o.logicform,p=z(R,l,c,L,x),C=ce(R,p,l,c,g,o.logicform);if(C){if(C.length!==1)throw new Error("A generated component must produce exactly one execution unit");const m=C[0];if(m.kind==="query"){const u=await F(m),b=u.component.mapResult,k=o.mapResult;return{...u,component:{...o,logicform:u.component.logicform,...b||k?{mapResult:ne=>{const re=b?.(ne)??[...ne];return k?.(re)??[...re]}}:{}}}}if(m.kind==="js")throw new S("UNSUPPORTED_NESTED_JS_COMPONENT","A JavaScript composite metric cannot currently be nested as a generated component");const E=await Promise.all(m.components.map(async u=>({name:u.name,prepared:await F(u.component),...u.component.groupKeyShifts?{groupKeyShifts:u.component.groupKeyShifts}:{},...u.joinKeys?{joinKeys:u.joinKeys}:{}}))),M=ie(m,E.map(({name:u,prepared:b,...k})=>({name:u,plan:b.plan,...k})),p,e.provider,c);return{component:{...o,logicform:R},plan:p,compiled:M,sources:me(E.map(({prepared:u})=>u.sources))}}return{component:{...o,logicform:R},plan:p,compiled:Z(p,e.provider,c),sources:Q(p)}},I=U?await Promise.all(U.map(async o=>{if(o.kind==="query")return{kind:"query",unit:o,...await F(o)};const l=await Promise.all(o.components.map(async p=>({name:p.name,prepared:await F(p.component),...p.component.groupKeyShifts?{groupKeyShifts:p.component.groupKeyShifts}:{},...p.joinKeys?{joinKeys:p.joinKeys}:{}})));if(o.kind==="js")return{kind:"js",unit:o,components:l.map(({prepared:p})=>p)};const R=l.map(({name:p,prepared:C,...m})=>({name:p,plan:C.plan,...m}));return{kind:"cte",unit:o,plan:d,compiled:ie(o,R,d,e.provider,c),sources:me(l.map(({prepared:p})=>p.sources))}})):void 0,y=I?void 0:Z(d,e.provider,c);if(I)for(const o of I)if(o.kind==="js")for(const l of o.components)T(l.compiled,"computation");else T(o.compiled,"computation");else T(y,"computation");await w({stage:"compiled",sqls:[...O]},{sqls:[...O]}),await w({stage:"executing",provider:e.provider.kind});const $=I?fe(await Promise.all(I.map(async o=>{if(o.kind==="js"){const p=await Promise.all(o.components.map(async m=>{const E=await B(m.compiled,m.sources,e),M=await ee(E,m.plan.projections,c);return m.component.mapResult?.(M)??M})),C=o.unit.components.map(({name:m})=>m);return Promise.all(ge(p,d.groupBy.map(({name:m})=>m)).map(async m=>{const E=await o.unit.mergeRow(m);return{...o.unit.exposeComponents?m:Object.fromEntries(Object.entries(m).filter(([u])=>!C.includes(u))),[o.unit.outputName]:E}}))}const l=await B(o.compiled,o.sources,e),R=o.kind==="query"?await ee(l,o.plan.projections,c):l;return o.kind==="query"?o.unit.mapResult?.(R)??R:R})),d):await(async()=>{const o=await B(y,Q(d),e);return ee(o,d.projections,c)})();await w({stage:"hydrating"});const ue=await we($,W,{semanticTypes:D,resolveSchema:g,fetchEntities:o=>he(o,{version:h.version,operators:c,schemaMappings:L,semanticTypes:D,plugins:s,...e.locale?{locale:e.locale}:{},resolveSchema:g,...e.permissions?{permissions:e.permissions}:{},provider:e.provider,...e.cache?{cache:e.cache}:{},...e.signal?{signal:e.signal}:{},onCompiled:l=>T(l,"semantic-resolution")})}),X=ye(ue,d.rowIdentity);return await w({stage:"result",result:X},{result:X,sqls:[...O]}),await w({stage:"completed",durationMs:ae.now()-f}),{result:X,schema:A,normedLogicform:h,sqls:[...O],lineage:_,provider:e.provider.kind}}catch(t){const r=le(t);try{await w({stage:"failed",error:r})}catch{}throw r}},Qe=async(n,i)=>{let s={};try{if(i.connections.length===0)throw new S("DATABASE_CONNECTION_REQUIRED","At least one database connection is required");const a=new Map;for(const f of i.connections){if(f.id.trim().length===0)throw new S("INVALID_DATABASE_CONNECTION","Database connection id must not be empty");if(a.has(f.id))throw new S("DATABASE_CONNECTION_ALREADY_REGISTERED",`Database connection id is duplicated: ${f.id}`,{connectionId:f.id});a.set(f.id,f)}const P=new Set;for(const f of ke(n))for(const D of i.schemaMappings.list(f))P.add(D.connectionId);if(P.size>1)throw new S("CROSS_CONNECTION_QUERY_UNSUPPORTED",`One LogicForm cannot compile into SQL for multiple database connections: ${[...P].join(", ")}`,{connectionIds:[...P]});const[N]=P;if(!N)throw new S("LOGICFORM_SCHEMA_REQUIRED","A LogicForm must contain at least one physical Schema leaf");const v=a.get(N);if(!v)throw new S("DATABASE_CONNECTION_NOT_FOUND",`Database connection is not registered: ${N}`,{connectionId:N});const e=Oe(v);return s={provider:e.kind},await de(n,{...i,provider:e,connectionId:v.id,onProgress:async f=>{s=f.partialResult,await i.onProgress?.(f)}})}catch(a){return Ke(a,n,s)}};export{Qe as execute,de as executeWithProvider};
@@ -1 +0,0 @@
1
- import{compilePlan as h}from"../compiler/compile-plan.js";import"../operators/index.js";import{SemanticDBError as d}from"../errors.js";import{createLogicalPlan as y}from"../planner/create-logical-plan.js";import{normalizeLogicform as f}from"../normalizer/normalize-logicform.js";import{isColumnAllowed as l,applyPermissions as g}from"../permissions/permissions.js";import{addRowIdentities as v}from"./row-identity.js";import{executeCompiledQuery as u,collectPlanSources as w}from"./execute-query.js";const P=r=>{if(r.every(e=>typeof e=="string"))return[...r];if(r.every(e=>typeof e=="number"))return[...r];if(r.every(e=>typeof e=="boolean"))return[...r];throw new TypeError("Entity IDs must have one scalar type")},S=(r,e,a)=>{const c=P(e);if(!a||c.length<=a)return{[r]:{$in:c}};const n=[];for(let m=0;m<c.length;m+=a)n.push({[r]:{$in:c.slice(m,m+a)}});return{$or:n}},E=async(r,e)=>{if(!l(e.permissions,r.schema.id,r.idProperty))throw new d("COLUMN_PERMISSION_DENIED",`Entity hydration requires the ID property in the column permissions: ${r.schema.id}.${r.idProperty.name}`,{schemaId:r.schema.id,property:r.idProperty.name});const a=r.schema.properties.filter(i=>l(e.permissions,r.schema.id,i)),c={version:e.version,schema:r.schema.id,query:S(r.idProperty.name,r.ids,e.provider.maxInListItems),preds:a.map(i=>({pred:i.name,name:i.name}))},n=g(c,e.permissions,e.resolveSchema,!0,new Set,e.plugins),m=await f(n,r.schema,{semanticTypes:e.semanticTypes,operators:e.operators,...e.plugins?{plugins:e.plugins}:{},...e.locale?{locale:e.locale}:{},resolveSchema:e.resolveSchema}),o=y(m,r.schema,e.operators,e.schemaMappings,{resolveSchema:e.resolveSchema,canUsePropertyRowIdentity:(i,p)=>l(e.permissions,i.id,p)}),s=h(o,e.provider,e.operators);e.onCompiled?.(s);const t=await u(s,w(o),{provider:e.provider,schemaMappings:e.schemaMappings,...e.cache?{cache:e.cache}:{},...e.signal?{signal:e.signal}:{}});return v(t,o.rowIdentity)};export{E as fetchEntities};
@@ -1 +0,0 @@
1
- import{SemanticDBError as m}from"../../errors.js";import{createMissingEntity as u}from"./missing-entity.js";const y=(r,t)=>`${r}:${String(t)}`,w=r=>{const t=r.properties.filter(({type:e})=>e==="ID"),i=t[0];if(t.length!==1||!i)throw new m("RELATION_TARGET_ID_REQUIRED",`Relation target ${r.id} must contain exactly one ID property`,{schemaId:r.id,count:t.length});return i};class P{#s;#o=new Map;#t=new Map;#e=new Map;#i=!1;constructor(t){this.#s=t}load=(t,i)=>{const e=y(t,i),n=this.#o.get(e);if(n)return Promise.resolve(n);const s=this.#t.get(e);if(s)return s;const o=this.#s.resolveSchema(t),a=w(o);let d,l;const h=new Promise((c,p)=>{d=c,l=p}),f=this.#e.get(t)??{schema:o,idProperty:a,loads:new Map};return f.loads.set(e,{id:i,resolve:c=>d?.(c),reject:c=>l?.(c)}),this.#e.set(t,f),this.#t.set(e,h),this.#n(),h};#n(){this.#i||(this.#i=!0,queueMicrotask(()=>{this.#r()}))}async#r(){this.#i=!1;const t=this.#e;this.#e=new Map,await Promise.all([...t.values()].map(i=>this.#c(i)))}async#c(t){const i={schema:t.schema,idProperty:t.idProperty,ids:[...t.loads.values()].map(({id:e})=>e)};try{const e=await this.#s.fetchEntities(i),n=new Map;for(const s of e){const o=s[t.idProperty.name]??s._id;o!=null&&n.set(y(t.schema.id,o),s)}for(const[s,o]of t.loads){const a=n.get(s)??u(t.schema,t.idProperty,o.id);this.#o.set(s,a),this.#t.delete(s),o.resolve(a)}}catch(e){for(const[n,s]of t.loads)this.#t.delete(n),s.reject(e)}}}export{P as EntityLoader};
@@ -1 +0,0 @@
1
- import{SemanticDBError as l}from"../../errors.js";const A=(n,s)=>{if(!s.isArray||typeof n!="string")return n;const t=n.trim();if(!t.startsWith("[")||!t.endsWith("]"))return n;try{const r=JSON.parse(t);if(!Array.isArray(r))throw new Error("JSON result is not an array");return r}catch(r){throw new l("INVALID_ARRAY_RESULT",`Result column ${s.name} contains invalid array JSON`,{property:s.name,cause:r})}},o=async(n,s,t,r)=>{await Promise.all(n.map(async i=>{await Promise.all(s.map(async a=>{if(!(a.name in i))return;const e=A(i[a.name],a),m=t.get(a.type).hydrateResult;if(!m){i[a.name]=e;return}i[a.name]=a.isArray&&Array.isArray(e)?await Promise.all(e.map(c=>m(c,{property:a,requestEntity:r}))):await m(e,{property:a,requestEntity:r})}))}))};export{o as formatResultValues};
@@ -1 +0,0 @@
1
- import{populateEntities as n}from"./populate-entities.js";const p=async(a,e,r)=>{const t=a.map(o=>({...o}));return await n(t,e,r),t};export{p as hydrateResult};
@@ -1 +0,0 @@
1
- const r=n=>String(n),a=(n,i,s)=>{const o=`\u6570\u636E\u5E93\u4E2D\u672A\u627E\u5230 ID \u4E3A\u300C${r(s)}\u300D\u7684\u5B9E\u4F53`,t={};for(const e of n.properties)e.id===i.id?t[e.name]=s:e.isArray?t[e.name]=[]:t[e.name]=e.primal_type==="string"?o:null;return t._id=r(s),t};export{a as createMissingEntity};
@@ -1 +0,0 @@
1
- import{EntityLoader as A}from"./entity-loader.js";import{formatResultValues as x}from"./format-values.js";const m=5,E=t=>typeof t=="object"&&t!==null&&!Array.isArray(t)&&!(t instanceof Date),_=(t,o)=>{const e=o.properties.find(({type:n})=>n==="ID");return e?t[e.name]:void 0},h=(t,o)=>{const e=structuredClone(t);if(!("_id"in e)){const n=_(e,o);(typeof n=="string"||typeof n=="number"||typeof n=="boolean")&&(e._id=String(n))}return e},b=(t,o,e,n)=>{const s=`${o.id}:${n?"recursive":"leaf"}`,a=t.get(s);if(a){a.rows.push(e);return}t.set(s,{rows:[e],properties:o.properties,expandEntities:n})},g=async(t,o,e)=>{const n=new A(e);let s=[{rows:t,properties:o,expandEntities:!0}];for(let a=0;s.length>0;a+=1){if(await Promise.all(s.map(i=>{const r=i.expandEntities&&a<m;return x(i.rows,i.properties,e.semanticTypes,r?n.load:(p,c)=>Promise.resolve(c))})),a>=m)return;const u=new Map;for(const i of s)if(i.expandEntities)for(const r of i.properties){if(r.primal_type!=="object"||!r.ref)continue;const p=e.resolveSchema(r.ref);for(const c of i.rows){if(!(r.name in c))continue;const f=c[r.name],d=r.isArray?Array.isArray(f)?f:[f]:[f];for(const[w,y]of d.entries()){if(!E(y))continue;const l=h(y,p);r.isArray?d[w]=l:c[r.name]=l,b(u,p,l,!r.isArray)}r.isArray&&(c[r.name]=d)}}s=[...u.values()]}};export{g as populateEntities};
@@ -1 +0,0 @@
1
- import{randomUUID as e}from"node:crypto";const p=n=>{if(n&&typeof n=="object"){if("_id"in n)return String(n._id);if("id"in n)return String(n.id)}return String(n)},t=(n,r)=>r.map(i=>p(n[i])).join(""),s=(n,r)=>n.map(i=>{if(r.kind==="property"){const{[r.internalName]:o,...d}=i;return{...d,_id:String(o)}}return r.kind==="group"?{...i,_id:t(i,r.names)}:{...i,_id:r.kind==="singleton"?"0":e()}});export{s as addRowIdentities,t as groupRowIdentity};
package/dist/index.js DELETED
@@ -1 +0,0 @@
1
- import{execute as e}from"./executor/execute.js";import{closeConnections as r}from"./executor/connection-registry.js";import{genMetricComponents as o}from"./custom-functions/custom-functions.js";import{SemanticDBError as c}from"./errors.js";import{createSemanticTypeRegistry as f}from"./semantic-types/index.js";import{builtinOperators as l,createOperatorRegistry as x}from"./operators/index.js";import{SchemaMappingRegistry as g}from"./schema-mappings/registry.js";import{CALENDAR_DATES_TABLE as A,CALENDAR_RELATIONS_TABLE as C,CALENDAR_SYSTEM_SCHEMA_IDS as d}from"./calendar/constants.js";import{resolveCalendarPeriod as T,resolveCalendarPeriodFromStore as D,selectCalendarDates as L}from"./calendar/resolver.js";import{ProviderCalendarRelationStore as v}from"./calendar/provider-relation-store.js";import{calendarSystemSchemas as P}from"./calendar/system-schemas.js";import{PlannerSemanticRegistry as M}from"./planner/semantics/registry.js";import{createPlannerSemanticRegistry as b}from"./planner/semantics/registry-defaults.js";import{OperatorRegistry as B}from"./operators/registry.js";import{SemanticTypeRegistry as j}from"./semantic-types/registry.js";import{builtinSemanticTypes as F}from"./semantic-types/builtins/index.js";import{resolveSchema as Y}from"./semantic-types/resolve-schema.js";import{validateResolvedSchema as q}from"./semantic-types/validate-resolved-schema.js";const t=Object.freeze({execute:e,close:r,genComponents:o});export{A as CALENDAR_DATES_TABLE,C as CALENDAR_RELATIONS_TABLE,d as CALENDAR_SYSTEM_SCHEMA_IDS,t as Logicform,B as OperatorRegistry,M as PlannerSemanticRegistry,v as ProviderCalendarRelationStore,g as SchemaMappingRegistry,c as SemanticDBError,j as SemanticTypeRegistry,l as builtinOperators,F as builtinSemanticTypes,P as calendarSystemSchemas,x as createOperatorRegistry,b as createPlannerSemanticRegistry,f as createSemanticTypeRegistry,T as resolveCalendarPeriod,D as resolveCalendarPeriodFromStore,Y as resolveSchema,L as selectCalendarDates,q as validateResolvedSchema};
@@ -1 +0,0 @@
1
- const r=o=>typeof o=="object"&&o!==null&&!Array.isArray(o)&&typeof o.version=="string"&&(typeof o.schema=="string"||Array.isArray(o.logicforms)||typeof o.from=="object"),s=o=>Array.isArray(o.logicforms);export{s as isComposedLogicform,r as isLogicform};
@@ -1 +0,0 @@
1
- import{SemanticDBError as t}from"../errors.js";const h=(e,s,a)=>{if(!e.schema||e.schema===s.id)return s;const r=a.resolveSchema?.(e.schema);if(!r)throw new t("SCHEMA_RESOLVER_REQUIRED",`Cannot normalize nested LogicForm schema without a schema resolver: ${e.schema}`,{schemaId:e.schema});return r};export{h as resolveLogicformSchema};
@@ -1 +0,0 @@
1
- import{SemanticDBError as N}from"../errors.js";import{predQueryName as g}from"./pred-query-name.js";const i=(e,n,o={})=>{if(e.name!==void 0){if(typeof e.name!="string"||e.name.length===0)throw new N("INVALID_PRED_NAME","PredItem name must be a non-empty string");return e.name}const r=o.locale??"zh-CN",a=r.toLowerCase().startsWith("en"),m=typeof e.pred=="string"?e.pred:e.pred?i(e.pred,n,o):void 0,s=e.components?.map(c=>i(c,n,o))??[],f=m??(s.length>0?s.join(a?", ":"\u3001"):a?"rows":"\u6570\u636E\u884C"),t=e.operator?n.get(e.operator).defaultName({operandName:f,...m?{inputName:m}:{},componentNames:s,args:e.args??{},locale:r}):f;if(typeof t!="string"||t.length===0)throw new N("INVALID_PRED_NAME",`Operator defaultName must return a non-empty name: ${e.operator}`,{operator:e.operator});if(!e.query)return t;const u=g(e.query,r);return u?a?`${t} where ${u}`:`${u}\u7684${t}`:t};export{i as defaultPredName};
@@ -1 +0,0 @@
1
- import{SemanticDBError as s}from"../errors.js";import{isConcreteEntityId as p,resolveEntityFilterProperty as a}from"../schema/entity-identity.js";const i=(e,t)=>Object.entries(e).some(([n,o])=>t.has(n)?!0:n!=="$and"&&n!=="$or"||!Array.isArray(o)?!1:o.some(r=>typeof r=="object"&&r!==null&&!Array.isArray(r)&&i(r,t))),f=(e,t,n,o=[])=>{if(t===void 0||t==="placeholder")return e;if(!p(t))throw new s("INVALID_ENTITY_ID","entity_id must be a non-empty string");const r=a(n,o);return e&&i(e,new Set([r.name,r.id]))?e:{[r.name]:t,...e??{}}};export{f as applyEntityIdQuery};
@@ -1 +0,0 @@
1
- import{normalizePreds as m}from"./preds.js";const i=(o,r,e)=>m(o??[],r,e);export{i as normalizeGroupby};
@@ -1 +0,0 @@
1
- import{SemanticDBError as c}from"../errors.js";import{createOperatorRegistry as w}from"../operators/index.js";import{clone as g}from"../utils/clone.js";import{resolveLogicformSchema as d}from"./core.js";import{normalizeGroupby as I}from"./groupby.js";import{normalizePagination as S}from"./pagination.js";import{normalizePreds as z}from"./preds.js";import{normalizeQuery as L}from"./query.js";import{assertSupportedLogicformVersion as P}from"./version.js";import{applyEntityIdQuery as h}from"./entity-id.js";const b=async(e,m,r)=>{if(!e)return;const u=d(e,m,r);return f(e,u,r)},f=async(e,m,r)=>{if(r=r.operators?r:{...r,operators:w(r.plugins)},P(e),e.logicforms){const t=["schema","from","query","preds","groupby","having","limit","page","entity_id"].filter(s=>e[s]!==void 0);if(t.length>0)throw new c("INVALID_COMPOSED_LOGICFORM",`A composed LogicForm cannot define: ${t.join(", ")}`);if(e.logicforms.length<2)throw new c("COMPOSITION_REQUIRES_MULTIPLE_LOGICFORMS","logicforms must contain at least two LogicForms");if(e.limitBy!==void 0&&(!Number.isInteger(e.limitBy)||e.limitBy<=0))throw new c("INVALID_PAGINATION","limitBy must be a positive integer",{limitBy:e.limitBy});const l=g(e);return l.logicforms=await Promise.all(e.logicforms.map(s=>f(s,d(s,m,r),r))),l}if(e.output&&e.output.type!=="data"&&e.output.type!=="sql")throw new c("UNSUPPORTED_OUTPUT",`Output type is not supported: ${e.output.type}`);const o=g(e),a={...r,normalizeNestedLogicform:async t=>{const l=d(t,m,r);return f(t,l,r)}};S(o);const n=await b(o.from,m,a),i=n&&r.resolveFromSchema?r.resolveFromSchema(n,m):m,y=await L(h(o.query,o.entity_id,i,r.plugins),i,a),O=o.preds===void 0&&o.groupby===void 0?i.properties.filter(t=>r.canProjectProperty?.(i,t)??!0).map(t=>({pred:t.name,name:t.name})):o.preds;o.preds=await z(O,i,a);const p=await I(o.groupby,i,a);return p.length>0?o.groupby=p:delete o.groupby,n?o.from=n:delete o.from,y?o.query=y:delete o.query,o};export{f as normalizeLogicform};
@@ -1 +0,0 @@
1
- import{SemanticDBError as a}from"../errors.js";const n=(e,s)=>{throw new a("INVALID_PAGINATION",e,s)},u=e=>{"skip"in e&&n("skip has been removed; use the 1-based page field",{skip:e.skip});const s=e.groupby?.length??0;e.limitBy!==void 0&&((!Number.isInteger(e.limitBy)||e.limitBy<=0)&&n("limitBy must be a positive integer",{limitBy:e.limitBy}),s<2&&(e.limit=e.limitBy,delete e.limitBy));const{limit:i,page:t}=e;if(i===void 0){t!==void 0&&n("page requires limit",{page:t});return}if((!Number.isFinite(i)||i<0&&i!==-1||i>1&&!Number.isInteger(i))&&n("limit must be -1, a non-negative integer, or a ratio between 0 and 1",{limit:i}),i===-1){t!==void 0&&n("page cannot be used with unlimited results",{limit:i,page:t}),delete e.limit;return}t!==void 0&&(!Number.isInteger(t)||t<1)&&n("page must be a positive integer starting from 1",{page:t}),e.page=t??1};export{u as normalizePagination};
@@ -1 +0,0 @@
1
- const f=t=>typeof t=="object"&&t!==null&&!Array.isArray(t),y={year:"\u5E74",quarter:"\u5B63\u5EA6",month:"\u6708",week:"\u5468",day:"\u65E5",hour:"\u65F6",minute:"\u5206",second:"\u79D2"},$=(t,r)=>{if(t===null)return r?"null":"\u7A7A\u503C";if(typeof t=="string"||typeof t=="number")return String(t);if(typeof t=="boolean")return r?String(t):t?"\u662F":"\u5426";if(Array.isArray(t))return t.map(n=>$(n,r)).join(r?", ":"\u3001");if(!f(t))return r?"the specified condition":"\u6307\u5B9A\u6761\u4EF6";if(Array.isArray(t.roots))return t.roots.map(n=>$(n,r)).join(r?", ":"\u3001");if(t.root!==void 0)return $(t.root,r);const e=["year","quarter","month","week","day","hour","minute","second"].filter(n=>t[n]!==void 0).map(n=>r?`${n} ${String(t[n])}`:`${String(t[n])}${y[n]??""}`);return e.length>0?e.join(r?", ":""):r?"the specified condition":"\u6307\u5B9A\u6761\u4EF6"},c=(t,r,e)=>t.filter(Boolean).join(e?r==="$and"?" and ":" or ":r==="$and"?"\u4E14":"\u6216"),d=(t,r,e,n)=>{const i=(n?{$eq:"is",$ne:"is not",$gt:"is greater than",$gte:"is at least",$lt:"is less than",$lte:"is at most",$in:"is one of",$nin:"is none of",$contains:"contains",$regex:"matches",$recursive:"is"}:{$eq:"\u4E3A",$ne:"\u4E0D\u4E3A",$gt:"\u5927\u4E8E",$gte:"\u5927\u4E8E\u7B49\u4E8E",$lt:"\u5C0F\u4E8E",$lte:"\u5C0F\u4E8E\u7B49\u4E8E",$in:"\u4E3A",$nin:"\u4E0D\u4E3A",$contains:"\u5305\u542B",$regex:"\u5339\u914D",$recursive:"\u5C5E\u4E8E"})[t];if(!i)return;const a=t==="$in"?n?"":"\u4E4B\u4E00":t==="$nin"?n?"":"\u4E2D\u7684\u4EFB\u4E00\u9879":t==="$recursive"?n?" or a descendant":"\u53CA\u5176\u4E0B\u7EA7":"";return n?`${r} ${i} ${e}${a}`:`${r}${i}${e}${a}`},u=(t,r,e)=>{if(!f(r)||Object.keys(r).every(o=>!o.startsWith("$")))return d("$eq",t,$(r,e),e)??"";const n=[];for(const[o,s]of Object.entries(r))if((o==="$and"||o==="$or")&&Array.isArray(s))n.push(c(s.map(i=>u(t,i,e)),o,e));else if(o==="$exists")n.push(e?`${t} ${s?"exists":"does not exist"}`:`${s?"\u6709":"\u65E0"}${t}`);else if(o!=="args"){const i=o==="$regex"&&f(s)?$(s.pattern,e):$(s,e),a=d(o,t,i,e);a&&n.push(a)}return c(n,"$and",e)},m=(t,r="zh-CN")=>{const e=r.toLowerCase().startsWith("en"),n=[];for(const[o,s]of Object.entries(t))(o==="$and"||o==="$or")&&Array.isArray(s)?n.push(c(s.map(i=>f(i)?m(i,r):""),o,e)):s!==void 0&&n.push(u(o,s,e));return c(n,"$and",e)};export{m as predQueryName};
@@ -1 +0,0 @@
1
- import{SemanticDBError as t}from"../errors.js";import{resolvePropertyPath as P}from"../schema/resolve-property-path.js";import{defaultPredName as d}from"./default-pred-name.js";import{normalizeQuery as y}from"./query.js";const w=e=>{if(typeof e!="object"||e===null||Array.isArray(e))return!1;const o=Object.getPrototypeOf(e);return o===Object.prototype||o===null},l=async(e,o,n)=>{const a=n.operators,i={...n.locale?{locale:n.locale}:{}};if(!a)throw new Error("Normalizer operator registry is not initialized");if(e.name!==void 0&&(typeof e.name!="string"||e.name.length===0))throw new t("INVALID_PRED_NAME","PredItem name must be a non-empty string");if(e.args!==void 0&&!w(e.args))throw new t("INVALID_OPERATOR_ARGS","Pred args must be a plain object");const m=e.schema===void 0||e.schema===o.id?o:n.resolveSchema?.(e.schema);if(!m)throw new t("SCHEMA_RESOLVER_REQUIRED",`Cross-Schema pred requires Schema ${e.schema}`);if(e.schema!==void 0&&e.schema!==o.id)throw new t("CROSS_SCHEMA_PRED_UNSUPPORTED","Cross-Schema pred.schema is not supported; use a composed LogicForm with logicforms",{sourceSchemaId:o.id,targetSchemaId:e.schema});const f=await y(e.query,m,n);if(e.pred!==void 0&&e.components!==void 0)throw new t("AMBIGUOUS_OPERATOR_INPUT","A PredItem cannot define both pred and components");if(e.components!==void 0&&!Array.isArray(e.components))throw new t("INVALID_OPERATOR_COMPONENTS","Pred components must be an array");const p=e.components?await Promise.all(e.components.map(r=>l(r,m,n))):void 0,s={...e,...f?{query:f}:{},...p?{components:p}:{}},c=r=>r.operator?a.get(r.operator).normalizePred?.({pred:r,schema:m})??r:r;if(typeof e.pred=="string"){const r=P(m,e.pred,n.resolveSchema),u={...s,pred:r.canonicalName},h={...s,pred:r.canonicalId};return c({...h,name:h.name??d(u,a,i)})}if(e.pred&&typeof e.pred=="object"&&!Array.isArray(e.pred)){const r={...s,pred:await l(e.pred,m,n)};return c({...r,name:r.name??d(r,a,i)})}if(e.pred!==void 0)throw new t("UNSUPPORTED_PRED","A pred must be a property name or nested pred");return c({...s,name:s.name??d(s,a,i)})},A=(e,o,n)=>Promise.all((e??[]).map(a=>l(a,o,n)));export{A as normalizePreds};
@@ -1 +0,0 @@
1
- import{SemanticDBError as f}from"../errors.js";import{resolvePropertyPath as _}from"../schema/resolve-property-path.js";import{normalizePrimalQuery as L}from"../semantic-types/primal-types/index.js";import{isLogicform as h}from"../logicform-types.js";import{clone as $}from"../utils/clone.js";import{assertSupportedLogicformVersion as b}from"./version.js";import{applyEntityIdQuery as O}from"./entity-id.js";const I=e=>typeof e=="object"&&e!==null&&!Array.isArray(e)&&typeof e.schema=="string"&&typeof e.query=="object"&&e.query!==null&&!Array.isArray(e.query),N=e=>{if(!h(e))return!1;const o=e;return o.groupby!==void 0||o.preds!==void 0||o.from!==void 0||o.logicforms!==void 0||o.having!==void 0||o.sort!==void 0||o.limit!==void 0||o.limitBy!==void 0||o.page!==void 0},R=async(e,o)=>{if(h(e)){if(!o.normalizeNestedLogicform)throw new f("LOGICFORM_NORMALIZER_UNAVAILABLE","Nested query LogicForm must be normalized through normalizeLogicform");return o.normalizeNestedLogicform(e)}return Array.isArray(e)?Promise.all(e.map(r=>R(r,o))):typeof e!="object"||e===null||e instanceof Date?e:Object.fromEntries(await Promise.all(Object.entries(e).map(async([r,s])=>[r,await R(s,o)])))},A=(e,o)=>Object.fromEntries(Object.entries(e).map(([r,s])=>(r==="$and"||r==="$or")&&Array.isArray(s)?[r,s.map(n=>A(n,o))]:[`${o}_${r}`,s])),S=e=>{if(typeof e!="object"||e===null||Array.isArray(e))return e;const o=Object.entries(e),[r]=o;return o.length===1&&r?.[0]==="$eq"?r[1]:e},w=async(e,o,r,s)=>{const n=a=>{if(Array.isArray(a)){a.forEach(n);return}if(typeof a!="object"||a===null||h(a))return;const l=a;if("$options"in l)throw new f("UNSUPPORTED_QUERY_OPERATOR","$options is a LogicForm 1.x field; use args.options in LogicForm 2.0");Object.values(l).forEach(n)};n(e);const t=s.semanticTypes.get(r.type),i={schema:o,property:r,now:s.now??new Date,requestLatestDataDate:()=>Promise.resolve(s.requestLatestDataDate?.(o,r))},y=await L($(e),i),d=t.normalizeQuery?t.normalizeQuery(y,i):y;if(r.comparable){const a=new Set(r.comparable.values),l=(c,p)=>{if(!(h(c)||c===null)){if(Array.isArray(c)){c.forEach(m=>l(m,p));return}if(typeof c=="object"){Object.entries(c).forEach(([m,u])=>{["args","$exists","$regex","$contains"].includes(m)||l(u,m)});return}if(!(p&&["args","$exists","$regex","$contains"].includes(p))&&(typeof c!="string"||!a.has(c)))throw new f("COMPARABLE_VALUE_NOT_FOUND",`Comparable category ${r.name} does not contain value: ${JSON.stringify(c)}`,{property:r.name,value:c})}};l(d)}return d},P=async(e,o,r,s)=>{const n=typeof e=="object"&&e!==null&&!Array.isArray(e)?e:{root:e},t=typeof n.schema=="string"?n.schema:r.ref??o.id,i=t===o.id?o:s.resolveSchema?.(t);if(!i)throw new f("SCHEMA_RESOLVER_REQUIRED",`$recursive requires Schema ${t}`);const y=n.idProperty??n.id_property,d=i.properties.filter(({type:u})=>u==="ID"),a=y===void 0?d.length===1?d[0]:void 0:i.properties.find(({id:u,name:g})=>u===y||g===y);if(!a||y===void 0&&d.length!==1)throw new f("RECURSIVE_ID_PROPERTY_REQUIRED",`$recursive Schema ${t} must have exactly one ID property or idProperty`);const l=Array.isArray(n.roots),c=l?n.roots:n.root===void 0?[]:[n.root];if(!l&&c.length===0||c.some(u=>u===void 0))throw new f("RECURSIVE_ROOT_REQUIRED","$recursive requires root or roots");const p=await Promise.all(c.map(u=>w(u,i,a,s))),m=n.parentProperty??n.parent_property??i.parentProperty??"pid";if(typeof m!="string"||m.length===0)throw new f("RECURSIVE_PARENT_PROPERTY_REQUIRED","$recursive parentProperty must be a string");if(n.includeSelf!==void 0&&typeof n.includeSelf!="boolean"||n.include_self!==void 0&&typeof n.include_self!="boolean")throw new f("INVALID_RECURSIVE_QUERY","$recursive includeSelf must be boolean");return{schema:t,roots:p,includeSelf:n.includeSelf??n.include_self??!0,idProperty:a.name,parentProperty:m}},E=async(e,o,r)=>{const s={};for(const[n,t]of Object.entries(e)){if(n==="$and"||n==="$or"){if(!Array.isArray(t))throw new f("INVALID_QUERY_VALUE",`${n} requires an array`);s[n]=await Promise.all(t.map(async a=>{if(typeof a!="object"||a===null||Array.isArray(a))throw new f("INVALID_QUERY_VALUE",`${n} items must be query objects`);return E(a,o,r)}));continue}const i=_(o,n,r.resolveSchema);if(N(t)&&i.property.primal_type==="object"&&i.property.ref){if(t.schema!==i.property.ref)throw new f("RELATION_SCHEMA_MISMATCH",`Relation ${i.canonicalName} references ${i.property.ref}, not ${t.schema??"undefined"}`);if(!r.normalizeNestedLogicform)throw new f("LOGICFORM_NORMALIZER_UNAVAILABLE","Nested query LogicForm must be normalized through normalizeLogicform");const a=await r.normalizeNestedLogicform(t);s[i.canonicalName]={$in:a};continue}if(I(t)){if(t.version!==void 0&&b(t),i.property.primal_type!=="object"||!i.property.ref)throw new f("INVALID_RELATION_QUERY",`Nested LogicForm query requires an object property: ${i.canonicalName}`);if(t.schema!==i.property.ref)throw new f("RELATION_SCHEMA_MISMATCH",`Relation ${i.canonicalName} references ${i.property.ref}, not ${t.schema}`);const a=r.resolveSchema?.(t.schema);if(!a)throw new f("SCHEMA_RESOLVER_REQUIRED",`Nested relation query requires Schema ${t.schema}`);const l=O(t.query,t.entity_id,a,r.plugins),c=await E(l,a,r);Object.assign(s,A(c,i.canonicalName));continue}if(typeof t=="object"&&t!==null&&!Array.isArray(t)&&Object.prototype.hasOwnProperty.call(t,"$recursive")){const a=t;if(Object.keys(a).filter(c=>c!=="$recursive").length>0)throw new f("INVALID_RECURSIVE_QUERY","$recursive cannot be combined with other field operators");s[i.canonicalName]={$recursive:await P(a.$recursive,i.schema,i.property,r)};continue}const y=await R(t,r),d=await w(y,i.schema,i.property,r);s[i.canonicalName]=S(d)}return s},j=async(e,o,r)=>{if(e)return E(e,o,r)};export{j as normalizeQuery,E as normalizeQueryObject};
@@ -1 +0,0 @@
1
- import{SemanticDBError as i}from"../errors.js";const s=/^(\d+)\.(\d+)(?:\.(\d+))?(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/,u=r=>{if(typeof r!="string")return!1;const e=s.exec(r);if(!e)return!1;const n=Number(e[1]),t=Number(e[2]),o=Number(e[3]??0);return n!==2?n>2:t>0||o>0?!0:e[4]===void 0},c=r=>{if(!u(r.version))throw new i("UNSUPPORTED_LOGICFORM_VERSION",`This library only supports LogicForm version 2.0 or later; received ${JSON.stringify(r.version)}`,{minimumVersion:"2.0",receivedVersion:r.version})};export{c as assertSupportedLogicformVersion};
@@ -1 +0,0 @@
1
- import{SemanticDBError as t}from"../../errors.js";const a={name:"$abs",defaultName:({operandName:r,locale:e})=>e.toLowerCase().startsWith("en")?`Absolute ${r}`:`${r}\u7EDD\u5BF9\u503C`,kind:"scalar",toSQL({expression:r}){if(!r)throw new t("PRED_PROPERTY_REQUIRED","$abs requires a pred");return`ABS(${r})`},getOutputProperty({name:r,inputProperty:e}){if(!e)throw new t("PRED_PROPERTY_REQUIRED","$abs requires a pred");return{...e,name:r,isArray:!1}}};export{a as absOperator};
@@ -1 +0,0 @@
1
- import m from"dayjs";import T from"dayjs/plugin/isoWeek.js";import L from"dayjs/plugin/quarterOfYear.js";import{SemanticDBError as u}from"../../errors.js";m.extend(T),m.extend(L);const N=new Set(["year","quarter","month","week"]),A=e=>e.format("YYYY-MM-DD HH:mm:ss"),g=(e,r)=>e.operator&&r(e.operator).kind==="aggregate"?!0:(typeof e.pred=="object"?g(e.pred,r):!1)||(e.components?.some(t=>g(t,r))??!1),y=(e,r,t)=>{if(e.kind==="window"||e.kind==="cumulative")throw new u("ACCUMULATE_WINDOW_UNSUPPORTED","$accumulate cannot contain another window expression");if(e.kind==="ordinal-decode")return{...e,input:y(e.input,r,t)};if(e.kind==="ordinal-encode")return{kind:"cumulative",function:"sum",input:e,...t};if(e.kind!=="operator")return{kind:"cumulative",function:"sum",input:e,...t};const c=r.getOperator(e.operator);if(c.kind==="component")throw new u("ACCUMULATE_OPERATOR_UNSUPPORTED",`$accumulate cannot contain component operator ${e.operator}`);if(c.kind==="aggregate"){if(e.operator==="$avg"){const i={...e,operator:"$sum"},p={...e,operator:"$count"};return{kind:"operator",operator:"$divide",args:{},components:[{kind:"cumulative",function:"sum",input:i,...t},{kind:"cumulative",function:"sum",input:p,...t}]}}const n={$sum:"sum",$count:"sum",$min:"min",$max:"max"}[e.operator];if(!n)throw new u("ACCUMULATE_OPERATOR_UNSUPPORTED",`Aggregate operator ${e.operator} does not declare cumulative semantics`);return{kind:"cumulative",function:n,input:e,...t}}if(c.kind!=="scalar")throw new u("ACCUMULATE_OPERATOR_UNSUPPORTED",`$accumulate cannot contain ${e.operator}`);return{...e,...e.input?{input:y(e.input,r,t)}:{},...e.components?{components:e.components.map(o=>y(o,r,t))}:{}}},D=e=>{if(!e.input||e.components.length>0||e.pred.query)throw new u("INVALID_ACCUMULATE_INPUT","$accumulate requires exactly one nested pred and does not accept pred.query");if(e.inputProperty?.comparable&&e.input.kind!=="ordinal-decode")throw new u("ACCUMULATE_COMPARABLE_OPERATOR_REQUIRED","$accumulate over a comparable category requires an explicit $min or $max metric");const r=e.args.partitionBy??[],t=e.args.orderBy;if(!Array.isArray(r)||r.some(o=>typeof o!="string"))throw new u("INVALID_ACCUMULATE_ARGS","$accumulate partitionBy must be an array of groupby names");if(!Array.isArray(t)||t.length===0)throw new u("INVALID_ACCUMULATE_ARGS","$accumulate requires a non-empty args.orderBy array");const c=t.map(o=>{if(typeof o!="object"||o===null||Array.isArray(o))throw new u("INVALID_ACCUMULATE_ARGS","$accumulate orderBy items require pred and optional direction");const{pred:n,direction:i="asc",...p}=o;if(typeof n!="string"||i!=="asc"&&i!=="desc"||Object.keys(p).length>0)throw new u("INVALID_ACCUMULATE_ARGS","$accumulate orderBy items require only a string pred and asc/desc direction");return{expression:e.resolveKey(n),direction:i==="asc"?"ASC":"DESC"}});return y(e.input,e,{partitionBy:r.map(o=>e.resolveKey(String(o))),orderBy:c})},I=e=>{if(e.groupByNames.length===0)return;if(typeof e.pred.pred!="object"||!g(e.pred.pred,e.getOperator))throw new u("ACCUMULATE_AGGREGATE_REQUIRED","$accumulate over a grouped physical relation requires an aggregate expression");const r=e.pred.args?.partitionBy,t=e.pred.args?.orderBy;if(r!==void 0&&!Array.isArray(r)||!Array.isArray(t)||t.length===0||t.some(n=>typeof n!="object"||n===null||Array.isArray(n)||typeof n.pred!="string"||Object.keys(n).some(i=>i!=="pred"&&i!=="direction")||n.direction!==void 0&&n.direction!=="asc"&&n.direction!=="desc"))return;const c=[...r??[],...t.map(n=>n.pred)];if(c.some(n=>typeof n!="string"))return;const o=c.map(n=>e.resolveGroupName(String(n)));if(o.length!==e.groupByNames.length||new Set(o).size!==e.groupByNames.length||e.groupByNames.some(n=>!o.includes(n)))throw new u("INCOMPLETE_ACCUMULATE_DIMENSIONS","$accumulate partitionBy and orderBy must cover every groupby item exactly once",{expected:e.groupByNames,received:o})},P=(e,r,t)=>{if(e.from||e.logicforms||e.having)throw new u("ACCUMULATE_PERIOD_UNSUPPORTED","$accumulate args.period currently requires a physical LogicForm without from, logicforms, or having");if((e.preds?.length??0)!==r.length)throw new u("ACCUMULATE_PERIOD_UNSUPPORTED","$accumulate args.period cannot currently be mixed with non-period projections");const c=e.query&&Object.entries(e.query).find(([,a])=>{if(typeof a!="object"||a===null||Array.isArray(a))return!1;const s=a;return typeof s.$gte=="string"&&typeof s.$lte=="string"});if(!c)throw new u("ACCUMULATE_PERIOD_QUERY_REQUIRED","$accumulate args.period requires one bounded date query identifying the target period");const[o,n]=c,i=n,p=m(String(i.$gte)),f=m(String(i.$lte));if(!p.isValid()||!f.isValid())throw new u("ACCUMULATE_PERIOD_QUERY_REQUIRED","Target date range is invalid");const _=r.map(a=>{if(!a.name)throw new u("MISSING_PRED_NAME","$accumulate args.period requires normalized names");return a.name}),$=t==="week"?p.startOf("isoWeek"):p.startOf(t),w={...e.query,[o]:{...i,$gte:A($)}},E=new Set([...(e.groupby??[]).map(({name:a})=>a),...(e.preds??[]).map(({name:a})=>a)]),U=a=>{let s=a;for(;E.has(s);)s=`_${s}`;return E.add(s),s},d=U("__accumulate_period"),h=r.map((a,s)=>U(`__accumulate_metric_${s}`)),l=(e.groupby??[]).map(({name:a})=>String(a)),C=t==="year"||t==="quarter"?"month":"day",R={version:e.version,...e.schema?{schema:e.schema}:{},query:w,groupby:[...e.groupby??[],{operator:"$dateBucket",pred:o,args:{granularity:C},name:d}],preds:r.map((a,s)=>({...a.pred,name:h[s]??`__accumulate_metric_${s}`}))},O={version:e.version,from:R,preds:[...l.map(a=>({pred:a,name:a})),{pred:d,name:d},...r.map((a,s)=>({operator:"$accumulate",pred:h[s]??`__accumulate_metric_${s}`,args:{partitionBy:l,orderBy:[{pred:d,direction:"asc"}]},name:_[s]??`accumulate_${s}`}))]};return{version:e.version,from:O,query:{[d]:{$gte:A(p),$lte:A(f)}},preds:[...l.map(a=>({pred:a,name:a})),..._.map(a=>({pred:a,name:a}))],...e.sort?{sort:e.sort}:{},...e.limit!==void 0?{limit:e.limit}:{},...e.page!==void 0?{page:e.page}:{},...e.output?{output:e.output}:{},...e.representation?{representation:e.representation}:{}}},S={name:"$accumulate",defaultName:({operandName:e,locale:r})=>r.toLowerCase().startsWith("en")?`Cumulative ${e}`:`${e}\u7D2F\u8BA1\u503C`,kind:"logical",normalizePred({pred:e}){const r=e.args?.period;if(r!==void 0&&(typeof r!="string"||!N.has(r)))throw new u("INVALID_ACCUMULATE_ARGS","$accumulate args.period must be year, quarter, month, or week");if(r!==void 0&&(e.args?.partitionBy!==void 0||e.args?.orderBy!==void 0))throw new u("INVALID_ACCUMULATE_ARGS","$accumulate args.period cannot be combined with partitionBy or orderBy");return e},planExpression:D,validatePlan:I,rewriteLogicform({logicform:e,schema:r}){const t=(e.preds??[]).filter(i=>i.operator==="$accumulate"&&i.args?.period!==void 0);if(t.length===0)return;const c=t[0]?.args?.period;if(t.some(i=>i.args?.period!==c))throw new u("ACCUMULATE_PERIOD_UNSUPPORTED","All $accumulate args.period projections in one LogicForm must use the same period");const o=new Set(Object.keys(e.query??{}));if(r.properties.filter(i=>i.primal_type==="date"&&o.has(i.name)).length!==1)throw new u("ACCUMULATE_PERIOD_QUERY_REQUIRED","$accumulate args.period requires exactly one queried date property");return P(e,t,c)},getOutputProperty({name:e,inputProperty:r}){return r?{...r,name:e,isArray:!1}:{name:e,type:"number",primal_type:"number",isArray:!1}}};export{S as accumulateOperator};
@@ -1 +0,0 @@
1
- import{numericResult as s,requireExpressions as i}from"./arithmetic.js";const u={name:"$add",defaultName:({operandName:r,componentNames:t,locale:e})=>e.toLowerCase().startsWith("en")?t.length>0?t.join(" plus "):`Sum of ${r}`:t.length>0?t.join("\u52A0"):`${r}\u6C42\u548C`,kind:"scalar",requiresProperty:!1,toSQL(r){return`(${i("$add",r,2,Number.POSITIVE_INFINITY).join(" + ")})`},getOutputProperty({name:r,componentProperties:t}){const e=t?.[0];return e?{...e,name:r,isArray:!1}:s(r)}};export{u as addOperator};
@@ -1 +0,0 @@
1
- import{SemanticDBError as o}from"../../errors.js";const p=(r,n,e,s=e)=>{const t=n.expressions??[];if(t.length<e||t.length>s)throw new o("INVALID_OPERATOR_COMPONENTS",`${r} requires ${e===s?String(e):`${e}-${s}`} components`);return t},c=r=>({name:r,type:"number",primal_type:"number",isArray:!1});export{c as numericResult,p as requireExpressions};
@@ -1 +0,0 @@
1
- import{SemanticDBError as m}from"../../errors.js";import{clone as s}from"../../utils/clone.js";import{combineQueries as g,collectPredQueries as P}from"./period-shift.js";import{requireTimestampProperty as f}from"./time-range.js";import{groupbyOutputName as l}from"../groupby.js";const $=new Set(["day","week","month","quarter","year"]),q={day:"\u65E5",week:"\u5468",month:"\u6708",quarter:"\u5B63\u5EA6",year:"\u5E74"},w=r=>{if(typeof r!="string"||!$.has(r))throw new m("INVALID_AVERAGE_PER_PERIOD_ARGS","$averagePerPeriod args.granularity must be day, week, month, quarter, or year");return r},u=r=>{const e=s(r);return delete e.having,delete e.sort,delete e.limit,delete e.page,e},i=r=>{const e=s(r);return delete e.query,e.pred&&typeof e.pred=="object"&&(e.pred=i(e.pred)),e.components&&(e.components=e.components.map(i)),e},h={name:"$averagePerPeriod",defaultName:({operandName:r,args:e,locale:o})=>o.toLowerCase().startsWith("en")?`Average ${r} per ${typeof e.granularity=="string"?e.granularity:"period"}`:`${r}${q[String(e.granularity)]??"\u5468\u671F"}\u5747\u503C`,kind:"component",createComponent({logicform:r,pred:e,schema:o}){if(!e.pred||typeof e.pred!="object"||Array.isArray(e.pred))throw new m("INVALID_AVERAGE_PER_PERIOD_INPUT","$averagePerPeriod pred must be a nested metric");const d=w(e.args?.granularity),c=f(o,"$averagePerPeriod"),y=i(e.pred),t=g([r.query,...P(e)]),n=u(r);n.preds=[{...y,name:"__average_per_period_numerator__"}],t&&(n.query=t);const a=u(r);a.preds=[{operator:"$countDistinct",pred:{operator:"$dateBucket",pred:c.name,args:{granularity:d},name:"__average_per_period_bucket__"},name:"__average_per_period_denominator__"}],t&&(a.query=t);const _=(r.groupby??[]).map(l);return{kind:"cte",components:[{name:"numerator",component:{kind:"query",logicform:n}},{name:"denominator",component:{kind:"query",logicform:a},joinKeys:_}],toSQL:({values:p})=>`${p.numerator} / NULLIF(${p.denominator}, 0)`}},getOutputProperty({name:r,inputProperty:e}){if(!e)throw new Error("$averagePerPeriod requires a nested metric");return{...e,name:r,isArray:!1}}};export{h as averagePerPeriodOperator};
@@ -1 +0,0 @@
1
- const o={name:"$avg",defaultName:({operandName:r,locale:e})=>e.toLowerCase().startsWith("en")?`Average ${r}`:`${r}\u5E73\u5747\u503C`,kind:"aggregate",toSQL(r){const{column:e,sql:t}=r;if(!e)throw new Error("$avg requires a column");return t.aggregateFunction("avg",e)},getOutputProperty({name:r,property:e,inputProperty:t}){const a=e??t;if(!a)throw new Error("$avg requires a property");return{name:r,type:a.type,primal_type:a.primal_type,isArray:!1}}};export{o as avgOperator};
@@ -1 +0,0 @@
1
- import{SemanticDBError as r}from"../../errors.js";const f=e=>{if(e.mode!=="auto")return;const n=e.buckets;if(!Number.isInteger(n)||n<2||n>100)throw new r("INVALID_CASE_ARGS","$case auto mode requires args.buckets to be an integer between 2 and 100");if(Object.hasOwn(e,"cases"))throw new r("INVALID_CASE_ARGS","$case auto mode cannot define args.cases");for(const t of["min","max"])if(e[t]!==void 0&&typeof e[t]!="number"||e[t]!==void 0&&!Number.isFinite(e[t]))throw new r("INVALID_CASE_ARGS",`$case auto mode ${t} must be finite number`);if(e.min===void 0!=(e.max===void 0))throw new r("INVALID_CASE_ARGS","$case auto mode requires both min and max");return n},E=e=>{if(!Array.isArray(e)||e.length===0)throw new r("INVALID_CASE_ARGS","$case requires a non-empty args.cases array");return e.map(n=>{if(typeof n!="object"||n===null||!("when"in n)||!("then"in n))throw new r("INVALID_CASE_ARGS","Each $case item requires when and then");const t=n;return{when:t.when,then:t.then}})},h={name:"$case",defaultName:({operandName:e,locale:n})=>n.toLowerCase().startsWith("en")?`${e} category`:`${e}\u5206\u7C7B`,kind:"scalar",toSQL({expression:e,args:n,sql:t}){if(!e)throw new r("PRED_PROPERTY_REQUIRED","$case requires a pred");const o=f(n);if(o!==void 0){const a=n.min===void 0?`MIN(${e}) OVER ()`:t.value(n.min),u=n.max===void 0?`MAX(${e}) OVER ()`:t.value(n.max),s=`(${u} - ${a})`,m=Array.from({length:o-1},(A,c)=>{const $=`${a} + ${s} * ${c+1} / ${o}`;return`WHEN ${e} < ${$} THEN ${t.value(c)}`});return`CASE WHEN ${a} = ${u} THEN ${t.value(0)} ${m.join(" ")} ELSE ${t.value(o-1)} END`}const i=E(n.cases).map(({when:a,then:u})=>`WHEN ${t.condition(e,a)} THEN ${t.value(u)}`),d=Object.hasOwn(n,"default")?` ELSE ${t.value(n.default)}`:"";return`CASE ${i.join(" ")}${d} END`},getOutputProperty({name:e}){return{name:e,type:"category",primal_type:"string",isArray:!1}}};export{h as caseOperator};
@@ -1 +0,0 @@
1
- import{requireExpressions as i}from"./arithmetic.js";const a={name:"$concat",defaultName:({operandName:r,componentNames:t,locale:e})=>e.toLowerCase().startsWith("en")?t.length>0?`Combined ${t.join(" and ")}`:`Combined ${r}`:t.length>0?`${t.join("\u4E0E")}\u62FC\u63A5\u503C`:`${r}\u62FC\u63A5\u503C`,kind:"scalar",requiresProperty:!1,toSQL(r){return r.sql.concat(i("$concat",r,1,Number.POSITIVE_INFINITY))},getOutputProperty({name:r}){return{name:r,type:"string",primal_type:"string",isArray:!1}}};export{a as concatOperator};
@@ -1 +0,0 @@
1
- const e={name:"$countDistinct",defaultName:({operandName:t,locale:n})=>n.toLowerCase().startsWith("en")?`Distinct ${t} count`:`${t}\u53BB\u91CD\u8BA1\u6570`,kind:"aggregate",toSQL(t){const{column:n,sql:r}=t;if(!n)throw new Error("$countDistinct requires a column");return r.aggregateFunction("count",`DISTINCT ${n}`)},getOutputProperty({name:t}){return{name:t,type:"int",primal_type:"number",isArray:!1}}};export{e as countDistinctOperator};
@@ -1 +0,0 @@
1
- const o={name:"$count",defaultName:({operandName:t,locale:r})=>r.toLowerCase().startsWith("en")?t==="rows"?"Row count":`${t} count`:t==="\u6570\u636E\u884C"?"\u884C\u6570":`${t}\u6570\u91CF`,kind:"aggregate",requiresProperty:!1,toSQL(t){const{column:r,sql:e}=t;return e.aggregateFunction("count",r)},getOutputProperty({name:t}){return{name:t,type:"int",primal_type:"number",isArray:!1}}};export{o as countOperator};
@@ -1 +0,0 @@
1
- import{SemanticDBError as a}from"../../errors.js";const i=new Set(["hour","day","week","month","quarter","year"]),o={hour:"\u5C0F\u65F6",day:"\u65E5",week:"\u5468",month:"\u6708",quarter:"\u5B63\u5EA6",year:"\u5E74"},n=r=>{if(typeof r!="string"||!i.has(r))throw new a("INVALID_DATE_BUCKET_ARGS","$dateBucket args.granularity must be hour, day, week, month, quarter, or year");return r},y={name:"$dateBucket",defaultName:({operandName:r,args:t,locale:e})=>e.toLowerCase().startsWith("en")?`${r} by ${typeof t.granularity=="string"?t.granularity:"time"}`:`${r}\uFF08\u6309${o[String(t.granularity)]??"\u65F6\u95F4"}\uFF09`,kind:"scalar",toSQL({expression:r,args:t,sql:e}){if(!r)throw new Error("$dateBucket requires a date pred");return e.dateBucket(r,n(t.granularity))},getOutputProperty({name:r,inputProperty:t,args:e}){if(!t||t.primal_type!=="date")throw new a("DATE_BUCKET_DATE_REQUIRED","$dateBucket requires a date-valued pred");const u=n(e.granularity);return{...t,name:r,type:"date",primal_type:"date",isArray:!1,granularity:u}}};export{y as dateBucketOperator};
@@ -1 +0,0 @@
1
- import{numericResult as i,requireExpressions as d}from"./arithmetic.js";const u={name:"$divide",defaultName:({operandName:t,componentNames:r,locale:e})=>e.toLowerCase().startsWith("en")?r.length>=2?`${r[0]} divided by ${r[1]}`:`${t} ratio`:r.length>=2?`${r[0]}\u9664\u4EE5${r[1]}`:`${t}\u6BD4\u503C`,kind:"scalar",requiresProperty:!1,toSQL(t){const[r,e]=d("$divide",t,2);return`(${r} / NULLIF(${e}, 0))`},getOutputProperty({name:t}){return i(t)}};export{u as divideOperator};
@@ -1 +0,0 @@
1
- import{accumulateOperator as r}from"./accumulate.js";import{absOperator as o}from"./abs.js";import{addOperator as t}from"./add.js";import{averagePerPeriodOperator as p}from"./average-per-period.js";import{avgOperator as m}from"./avg.js";import{caseOperator as e}from"./case.js";import{concatOperator as a}from"./concat.js";import{countOperator as i}from"./count.js";import{countDistinctOperator as f}from"./count-distinct.js";import{dateBucketOperator as O}from"./date-bucket.js";import{divideOperator as c}from"./divide.js";import{maxOperator as n}from"./max.js";import{minOperator as u}from"./min.js";import{multiplyOperator as d}from"./multiply.js";import{newlyOperator as s}from"./newly.js";import{periodBoundaryOperator as l}from"./period-boundary.js";import{periodDifferenceOperator as b}from"./period-difference.js";import{periodShiftOperator as g}from"./period-shift.js";import{periodGrowthOperator as h}from"./period-growth.js";import{sumOperator as v}from"./sum.js";import{subtractOperator as w}from"./subtract.js";import{shareOfTotalOperator as y}from"./share-of-total.js";import{substringOperator as k}from"./substring.js";import{sqlOperator as x}from"./sql.js";import{rankOperator as B}from"./rank.js";import{rowNumberOperator as D}from"./row-number.js";const P=Object.freeze([r,v,i,f,m,u,n,g,h,b,p,l,s,t,w,d,c,o,y,e,a,k,O,x,B,D]);export{P as builtinOperators};
@@ -1 +0,0 @@
1
- const o=r=>{if(!(!r.inputProperty?.comparable||!r.input))return{kind:"ordinal-decode",comparable:r.inputProperty.comparable,input:{kind:"operator",operator:"$max",args:r.args,...r.pred.query?{query:r.planQuery(r.pred.query)}:{},input:{kind:"ordinal-encode",input:r.input,comparable:r.inputProperty.comparable}}}},n={name:"$max",defaultName:({operandName:r,locale:a})=>a.toLowerCase().startsWith("en")?`Maximum ${r}`:`${r}\u6700\u5927\u503C`,kind:"aggregate",planExpression:o,toSQL(r){const{column:a,sql:p}=r;if(!a)throw new Error("$max requires a column");return p.aggregateFunction("max",a)},getOutputProperty({name:r,property:a,inputProperty:p}){const e=a??p;if(!e)throw new Error("$max requires a property");return{name:r,type:e.type,primal_type:e.primal_type,isArray:!1,...e.comparable?{comparable:e.comparable}:{}}}};export{n as maxOperator};
@@ -1 +0,0 @@
1
- const n=r=>{if(!(!r.inputProperty?.comparable||!r.input))return{kind:"ordinal-decode",comparable:r.inputProperty.comparable,input:{kind:"operator",operator:"$min",args:r.args,...r.pred.query?{query:r.planQuery(r.pred.query)}:{},input:{kind:"ordinal-encode",input:r.input,comparable:r.inputProperty.comparable}}}},i={name:"$min",defaultName:({operandName:r,locale:e})=>e.toLowerCase().startsWith("en")?`Minimum ${r}`:`${r}\u6700\u5C0F\u503C`,kind:"aggregate",planExpression:n,toSQL(r){const{column:e,sql:p}=r;if(!e)throw new Error("$min requires a column");return p.aggregateFunction("min",e)},getOutputProperty({name:r,property:e,inputProperty:p}){const a=e??p;if(!a)throw new Error("$min requires a property");return{name:r,type:a.type,primal_type:a.primal_type,isArray:!1,...a.comparable?{comparable:a.comparable}:{}}}};export{i as minOperator};
@@ -1 +0,0 @@
1
- import{numericResult as i,requireExpressions as u}from"./arithmetic.js";const l={name:"$multiply",defaultName:({operandName:r,componentNames:t,locale:e})=>e.toLowerCase().startsWith("en")?t.length>0?t.join(" times "):`Product of ${r}`:t.length>0?t.join("\u4E58\u4EE5"):`${r}\u4E58\u79EF`,kind:"scalar",requiresProperty:!1,toSQL(r){return`(${u("$multiply",r,2,Number.POSITIVE_INFINITY).join(" * ")})`},getOutputProperty({name:r}){return i(r)}};export{l as multiplyOperator};
@@ -1 +0,0 @@
1
- import{SemanticDBError as s}from"../../errors.js";import{resolvePropertyPath as w}from"../../schema/resolve-property-path.js";import{clone as y}from"../../utils/clone.js";import{resolvePredTimeRange as l,withTimeCondition as f}from"./time-range.js";import{groupbyPropertyReference as _,groupbyOutputName as E}from"../groupby.js";const g=t=>{const e=y(t);return delete e.having,delete e.sort,delete e.limit,delete e.page,e},i=t=>{const e=y(t);return delete e.query,e.pred&&typeof e.pred=="object"&&(e.pred=i(e.pred)),e.components&&(e.components=e.components.map(i)),e},N={name:"$newly",defaultName:({operandName:t,locale:e})=>e.toLowerCase().startsWith("en")?`New ${t}`:`\u65B0\u589E${t}`,kind:"component",createComponent({logicform:t,pred:e,schema:m,resolveSchema:a}){if(!e.pred||typeof e.pred!="object"||Array.isArray(e.pred))throw new s("INVALID_NEWLY_INPUT","$newly pred must be a nested metric");if((t.groupby??[]).some(n=>{const o=_(n);return o?w(m,o,a).property.type==="timestamp":!1}))throw new s("NEWLY_TIME_GROUPBY_UNSUPPORTED","$newly does not support grouping by the timestamp property");const r=l(t.query,e,m,a,"$newly");if(r.start===void 0||r.end===void 0)throw new s("NEWLY_RANGE_REQUIRED","$newly requires both start and end timestamp bounds");const u=i(e.pred),d=(n,o)=>{const p=g(t);return p.query=f(r.queryWithoutTime,r.propertyName,{$lte:n}),p.preds=[{...u,name:o}],p},c=(t.groupby??[]).map(E);return{kind:"cte",components:[{name:"end",component:{kind:"query",logicform:d(r.end,"__newly_end__")}},{name:"start",component:{kind:"query",logicform:d(r.start,"__newly_start__")},joinKeys:c}],toSQL:({values:n})=>`${n.end} - COALESCE(${n.start}, 0)`}},getOutputProperty({name:t,inputProperty:e}){if(!e)throw new Error("$newly requires a nested metric");return{...e,name:t,isArray:!1}}};export{N as newlyOperator};
@@ -1 +0,0 @@
1
- import{SemanticDBError as n}from"../../errors.js";import{clone as u}from"../../utils/clone.js";import{resolvePredTimeRange as c,withTimeCondition as _}from"./time-range.js";const l=r=>{const e=u(r);return delete e.having,delete e.sort,delete e.limit,delete e.page,e},s=r=>{const e=u(r);return delete e.query,e.pred&&typeof e.pred=="object"&&(e.pred=s(e.pred)),e.components&&(e.components=e.components.map(s)),e},b={name:"$periodBoundary",defaultName:({operandName:r,args:e,locale:a})=>a.toLowerCase().startsWith("en")?`${r} at period ${e.boundary==="start"?"start":"end"}`:`${r}${e.boundary==="start"?"\u671F\u521D\u503C":"\u671F\u672B\u503C"}`,kind:"component",observationPolicy({pred:r}){const e=r.args?.boundary;if(e!=="start"&&e!=="end")throw new n("INVALID_PERIOD_BOUNDARY_ARGS","$periodBoundary args.boundary must be start or end",{boundary:e});return{boundary:e,implicit:!1}},createComponent({logicform:r,pred:e,outputName:a,schema:i,resolveSchema:y}){if(!e.pred||typeof e.pred!="object"||Array.isArray(e.pred))throw new n("INVALID_PERIOD_BOUNDARY_INPUT","$periodBoundary pred must be a nested metric");const o=e.args?.boundary;if(o!=="start"&&o!=="end")throw new n("INVALID_PERIOD_BOUNDARY_ARGS","$periodBoundary args.boundary must be start or end");const t=c(r.query,e,i,y,"$periodBoundary"),p=o==="start"?t.start:t.end;if(p===void 0)throw new n("PERIOD_BOUNDARY_RANGE_REQUIRED",`$periodBoundary cannot resolve the ${o} of the timestamp query`);const m={version:r.version,schema:i.id,query:{[t.propertyName]:{$lte:p}},preds:[{operator:"$max",pred:t.propertyName,name:"__period_boundary_date__"}]},d=l(r);return d.query=_(t.queryWithoutTime,t.propertyName,m),d.preds=[{...s(e.pred),name:a}],{kind:"query",logicform:d}},getOutputProperty({name:r,inputProperty:e}){if(!e)throw new Error("$periodBoundary requires a nested metric");return{...e,name:r,isArray:!1}}};export{b as periodBoundaryOperator};
@@ -1 +0,0 @@
1
- import{clone as n}from"../../utils/clone.js";import{combineQueries as m,collectPredQueries as a,buildPeriodShiftComponent as _}from"./period-shift.js";import{periodComparisonName as d}from"./period-name.js";const y=r=>{const e=n(r);return delete e.having,delete e.sort,delete e.limit,delete e.page,e},$=({logicform:r,pred:e,schema:t,resolveSchema:u})=>{if(!e.pred||typeof e.pred!="object"||Array.isArray(e.pred))throw new Error("$periodDifference pred must be a nested metric");const i=n(e.pred);i.name="__period_difference_current__";const o=y(r);o.preds=[i];const c=m([r.query,...a(e)]);c&&(o.query=c);const f={pred:n(e.pred),...e.args?{args:e.args}:{}},s=_({logicform:r,pred:f,outputName:"__period_difference_previous__",schema:t,resolveSchema:u});if(s.kind!=="query")throw new Error("$periodDifference period shift must produce a query component");return{kind:"cte",components:[{name:"current",component:{kind:"query",logicform:o}},{name:"previous",component:s}],toSQL:({values:p})=>`${p.current} - ${p.previous}`}},h={name:"$periodDifference",defaultName:({operandName:r,args:e,locale:t})=>t.toLowerCase().startsWith("en")?`${r} ${d(e,t)} difference`:`${r}${d(e,t)}\u5DEE\u503C`,kind:"component",createComponent:$,getOutputProperty({name:r,inputProperty:e}){if(!e)throw new Error("$periodDifference requires a nested metric");return{...e,name:r,isArray:!1}}};export{h as periodDifferenceOperator};
@@ -1 +0,0 @@
1
- import{clone as n}from"../../utils/clone.js";import{combineQueries as a,collectPredQueries as h,buildPeriodShiftComponent as w}from"./period-shift.js";import{periodComparisonName as d}from"./period-name.js";const y=r=>{const e=n(r);return delete e.having,delete e.sort,delete e.limit,delete e.page,e},_=({logicform:r,pred:e,schema:t,resolveSchema:c})=>{if(!e.pred||typeof e.pred!="object"||Array.isArray(e.pred))throw new Error("$periodGrowth pred must be a nested metric");const i=n(e.pred);i.name="__period_growth_current__";const o=y(r);o.preds=[i];const p=a([r.query,...h(e)]);p&&(o.query=p);const m={pred:n(e.pred),...e.args?{args:e.args}:{}},s=w({logicform:r,pred:m,outputName:"__period_growth_previous__",schema:t,resolveSchema:c});if(s.kind!=="query")throw new Error("$periodGrowth period shift must produce a query component");return{kind:"cte",components:[{name:"current",component:{kind:"query",logicform:o}},{name:"previous",component:s}],toSQL:({values:u})=>`${u.current} / NULLIF(ABS(${u.previous}), 0) - 1`}},f={name:"$periodGrowth",defaultName:({operandName:r,args:e,locale:t})=>t.toLowerCase().startsWith("en")?`${r} ${d(e,t)} growth`:`${r}${d(e,t)}\u589E\u957F\u7387`,kind:"component",createComponent:_,getOutputProperty({name:r}){return{name:r,type:"percentage",primal_type:"number",isArray:!1}}};export{f as periodGrowthOperator};
@@ -1 +0,0 @@
1
- const s=o=>typeof o=="object"&&o!==null&&!Array.isArray(o),f={second:"\u79D2",minute:"\u5206\u949F",hour:"\u5C0F\u65F6",day:"\u65E5",week:"\u5468",month:"\u6708",quarter:"\u5B63\u5EA6",year:"\u5E74"},u={year:"\u5E74",quarter:"\u5B63\u5EA6",month:"\u6708",week:"\u5468",day:"\u65E5",hour:"\u65F6",minute:"\u5206",second:"\u79D2"},y=(o,a)=>{const e=a.toLowerCase().startsWith("en"),r=o.time;if(!s(r))return e?"period-over-period":"\u540C\u671F";if(typeof r.granularity=="string"&&typeof r.offset=="number"){if(r.offset===-1&&r.granularity==="year")return e?"year-over-year":"\u540C\u6BD4";if(r.offset===-1&&r.granularity==="month")return e?"month-over-month":"\u73AF\u6BD4";if(r.offset===-1&&r.granularity==="week")return e?"week-over-week":"\u5468\u73AF\u6BD4";if(r.offset===0)return e?"current-period":"\u672C\u671F";const t=Math.abs(r.offset),n=r.offset<0?"before":"after";return e?`${t} ${r.granularity}${t===1?"":"s"} ${n}`:`\u8F83${n==="before"?"\u524D":"\u540E"}${t}${f[r.granularity]??"\u671F"}`}const i=Object.entries(r).map(([t,n])=>e?`${t} ${String(n)}`:`${String(n)}${u[t]??t}`).join(e?", ":"");return e?`compared with ${i}`:`\u5BF9\u6BD4${i}`};export{y as periodComparisonName};
@@ -1 +0,0 @@
1
- import y from"dayjs";import Y from"dayjs/plugin/isoWeek.js";import k from"dayjs/plugin/quarterOfYear.js";import{SemanticDBError as h}from"../../errors.js";import{resolvePropertyPath as A}from"../../schema/resolve-property-path.js";import{clone as I}from"../../utils/clone.js";import{groupbyPropertyReference as E,groupbyOutputName as _}from"../groupby.js";import{periodComparisonName as $}from"./period-name.js";y.extend(Y),y.extend(k);const T=["second","minute","hour","day","week","month","quarter","year"],M=new Set(T),w=["year","quarter","month","week","day","hour","minute","second"],R=r=>Object.prototype.toString.call(r)==="[object Object]",p=r=>{throw new h("INVALID_PERIOD_SHIFT_ARGS",r)},Q=r=>{const t=r.time;R(t)||p("$periodShift requires args.time");const e=t;if("granularity"in e||"offset"in e)return(typeof e.granularity!="string"||!M.has(e.granularity)||!Number.isInteger(e.offset)||Object.keys(e).some(s=>s!=="granularity"&&s!=="offset"))&&p("Relative period shift time requires only granularity and an integer offset"),e;const o=Object.entries(e);(o.length===0||o.some(([s,c])=>!w.includes(s)||!Number.isInteger(c)))&&p("Absolute period shift time requires integer calendar components"),typeof e.year!="number"&&p("Absolute period shift time requires year");const n={quarter:[1,4],month:[1,12],week:[1,53],day:[1,31],hour:[0,23],minute:[0,59],second:[0,59]};for(const[s,[c,u]]of Object.entries(n)){const f=e[s];f!==void 0&&(Number(f)<c||Number(f)>u)&&p(`Invalid absolute period shift ${s}: ${JSON.stringify(f)}`)}return["quarter","month","week"].filter(s=>s in e).length>1&&p("Absolute period shift time cannot mix quarter, month, and week"),"day"in e&&!("month"in e)&&p("Absolute period shift day requires month"),e},j=(r,t,e)=>t==="month"?r.month(e-1):t==="day"?r.date(e):t==="week"?r.isoWeek(e):t==="quarter"?r.quarter(e):r.set(t,e),V=(r,t)=>{if("granularity"in t){const i=t.granularity==="week"?"week":t.granularity;return r.add(t.offset,i)}let e=r;for(const i of w){const o=t[i];typeof o=="number"&&(e=j(e,i,o))}return e},S=(r,t)=>r instanceof Date?t.toDate():typeof r!="string"?r:t.format(r.includes(":")?"YYYY-MM-DD HH:mm:ss":"YYYY-MM-DD"),F=(r,t,e,i,o)=>(r.groupby??[]).filter(n=>{const a=E(n);return a?A(t,a,e).property.primal_type==="date":!1}).map(n=>{const a=n.operator==="$dateBucket"?n.args?.granularity:void 0,s="granularity"in i?i.granularity:a??"day",c="granularity"in i?-i.offset:o.originalAnchor&&o.shiftedAnchor?o.originalAnchor.diff(o.shiftedAnchor,s):0;return{name:_(n),granularity:s,offset:c}}),O=(r,t,e)=>{if(Array.isArray(r))return r.map(n=>O(n,t,e));if(R(r))return Object.fromEntries(Object.entries(r).map(([n,a])=>[n,O(a,t,e)]));if(!(r instanceof Date)&&typeof r!="string")return r;const i=y(r);if(!i.isValid())return r;const o=V(i,t);return e.originalAnchor??=i,e.shiftedAnchor??=o,e.shiftedValues+=1,S(r,o)},G=(r,t,e,i,o)=>{const n=new Set,a=c=>Object.fromEntries(Object.entries(c).map(([u,f])=>{if((u==="$and"||u==="$or")&&Array.isArray(f))return[u,f.map(g=>a(g))];const d=A(t,u,e);return d.property.primal_type!=="date"?[u,f]:(n.add(d.canonicalName),[u,O(f,i,o)])})),s=a(r);if(n.size===0||o.shiftedValues===0)throw new h("PERIOD_SHIFT_TIME_QUERY_REQUIRED","$periodShift requires a concrete date condition in the LogicForm query");if(n.size>1)throw new h("AMBIGUOUS_PERIOD_SHIFT_TIME","$periodShift query contains more than one date property",{properties:[...n]});return s},N=r=>{const t=r.filter(e=>e!==void 0);if(t.length!==0)return t.length===1?t[0]:{$and:t}},l=r=>[...r.query?[r.query]:[],...typeof r.pred=="object"?l(r.pred):[],...(r.components??[]).flatMap(l)],H=(r,t,e)=>{if(!(r instanceof Date)&&typeof r!="string")return r;const i=y(r);if(!i.isValid())return r;if("granularity"in t)return S(r,i.add(-t.offset,t.granularity));if(!e.originalAnchor)return r;let o=i;for(const n of w)if(t[n]!==void 0){const a=n==="month"?e.originalAnchor.month()+1:n==="day"?e.originalAnchor.date():n==="week"?e.originalAnchor.isoWeek():n==="quarter"?e.originalAnchor.quarter():e.originalAnchor.get(n);o=j(o,n,a)}return S(r,o)},P=({logicform:r,pred:t,outputName:e,schema:i,resolveSchema:o})=>{const n=t.pred;(!n||typeof n!="object"||Array.isArray(n))&&p("$periodShift pred must be a nested metric");const a=Q(t.args??{}),s={shiftedValues:0},c=N([r.query,...l(t)]);if(!c)throw new h("PERIOD_SHIFT_TIME_QUERY_REQUIRED","$periodShift requires a date condition in the LogicForm query");const u=G(c,i,o,a,s),f=I(n);f.name=e,delete f.query;const d=I(r);d.query=u,d.preds=[f],delete d.having,delete d.sort,delete d.limit,delete d.page;const g=new Set((r.groupby??[]).filter(b=>{const m=E(b);return m?A(i,m,o).property.primal_type==="date":!1}).map(_));return{kind:"query",logicform:d,groupKeyShifts:F(r,i,o,a,s),mapResult:b=>b.map(m=>{const q={...m};for(const D of g)q[D]=H(q[D],a,s);return q})}},U={name:"$periodShift",defaultName:({operandName:r,args:t,locale:e})=>e.toLowerCase().startsWith("en")?`${r} ${$(t,e)} baseline`:`${r}${$(t,e)}\u57FA\u671F\u503C`,kind:"component",createComponent:P,getOutputProperty({name:r,inputProperty:t}){if(!t)throw new Error("$periodShift requires a nested metric");return{...t,name:r,isArray:!1}}};export{P as buildPeriodShiftComponent,l as collectPredQueries,N as combineQueries,U as periodShiftOperator};