@malloydata/malloy 0.0.319 → 0.0.321
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lang/composite-source-utils.js +1 -1
- package/dist/lang/test/test-translator.d.ts +10 -1
- package/dist/lang/test/test-translator.js +82 -2
- package/dist/model/filter_compilers.d.ts +1 -1
- package/dist/model/filter_compilers.js +44 -11
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
|
@@ -925,7 +925,7 @@ function isSingleValueFilterNode(e) {
|
|
|
925
925
|
return [];
|
|
926
926
|
if ((result.parsed.operator === 'null' && !result.parsed.not) ||
|
|
927
927
|
(result.kind === 'boolean' &&
|
|
928
|
-
['false', 'true'].includes(result.parsed.operator) &&
|
|
928
|
+
['true', '=false', '=true'].includes(result.parsed.operator) &&
|
|
929
929
|
!result.parsed.not) ||
|
|
930
930
|
(result.kind === 'date' &&
|
|
931
931
|
result.parsed.operator === 'in' &&
|
|
@@ -7,7 +7,16 @@ import type { DataRequestResponse, SQLSourceRequest, TranslateResponse } from '.
|
|
|
7
7
|
import type { ExprValue } from '../ast/types/expr-value';
|
|
8
8
|
import type { LogSeverity, MessageCode, MessageParameterType } from '../parse-log';
|
|
9
9
|
import type { EventStream } from '../../runtime_types';
|
|
10
|
-
export declare function pretty(thing:
|
|
10
|
+
export declare function pretty(thing: unknown): string;
|
|
11
|
+
/**
|
|
12
|
+
* For human inspection of IR objects, there is a lot of noise which makes
|
|
13
|
+
* it diifficult to read. This function makes a deep copy of the object
|
|
14
|
+
* stripping out location meta data and and fields with undefined values.
|
|
15
|
+
* Then it pretty-prints the result.
|
|
16
|
+
* @param value Some IR object
|
|
17
|
+
* @returns prettified printable version
|
|
18
|
+
*/
|
|
19
|
+
export declare function humanify(value: unknown): string;
|
|
11
20
|
export declare const aTableDef: SourceDef;
|
|
12
21
|
/**
|
|
13
22
|
* When translating partial trees, there will not be a document node
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.BetaExpression = exports.TestTranslator = exports.TestChildTranslator = exports.aTableDef = void 0;
|
|
27
27
|
exports.pretty = pretty;
|
|
28
|
+
exports.humanify = humanify;
|
|
28
29
|
exports.getExplore = getExplore;
|
|
29
30
|
exports.getModelQuery = getModelQuery;
|
|
30
31
|
exports.getFieldDef = getFieldDef;
|
|
@@ -48,9 +49,88 @@ const parse_malloy_1 = require("../parse-malloy");
|
|
|
48
49
|
const static_space_1 = require("../ast/field-space/static-space");
|
|
49
50
|
const global_name_space_1 = require("../ast/types/global-name-space");
|
|
50
51
|
const sql_block_1 = require("../../model/sql_block");
|
|
51
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/explicit-module-boundary-types
|
|
52
52
|
function pretty(thing) {
|
|
53
|
-
return (0, util_1.inspect)(thing, { breakLength:
|
|
53
|
+
return (0, util_1.inspect)(thing, { breakLength: 100, depth: Infinity });
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* For human inspection of IR objects, there is a lot of noise which makes
|
|
57
|
+
* it diifficult to read. This function makes a deep copy of the object
|
|
58
|
+
* stripping out location meta data and and fields with undefined values.
|
|
59
|
+
* Then it pretty-prints the result.
|
|
60
|
+
* @param value Some IR object
|
|
61
|
+
* @returns prettified printable version
|
|
62
|
+
*/
|
|
63
|
+
function humanify(value) {
|
|
64
|
+
const seen = new WeakMap();
|
|
65
|
+
function isObject(u) {
|
|
66
|
+
return typeof u === 'object' && u !== null;
|
|
67
|
+
}
|
|
68
|
+
function walk(u) {
|
|
69
|
+
// primitives & null
|
|
70
|
+
if (u === null || typeof u !== 'object')
|
|
71
|
+
return u;
|
|
72
|
+
// Date
|
|
73
|
+
if (u instanceof Date)
|
|
74
|
+
return new Date(u.getTime());
|
|
75
|
+
// RegExp
|
|
76
|
+
if (u instanceof RegExp)
|
|
77
|
+
return new RegExp(u.source, u.flags);
|
|
78
|
+
// Already visited (handle cycles)
|
|
79
|
+
if (seen.has(u))
|
|
80
|
+
return seen.get(u);
|
|
81
|
+
// Array
|
|
82
|
+
if (Array.isArray(u)) {
|
|
83
|
+
const out = [];
|
|
84
|
+
seen.set(u, out);
|
|
85
|
+
for (let i = 0; i < u.length; i++) {
|
|
86
|
+
out[i] = walk(u[i]);
|
|
87
|
+
}
|
|
88
|
+
return out;
|
|
89
|
+
}
|
|
90
|
+
// Map
|
|
91
|
+
if (u instanceof Map) {
|
|
92
|
+
const out = new Map();
|
|
93
|
+
seen.set(u, out);
|
|
94
|
+
for (const [k, v] of u.entries()) {
|
|
95
|
+
out.set(k, walk(v));
|
|
96
|
+
}
|
|
97
|
+
return out;
|
|
98
|
+
}
|
|
99
|
+
// Set
|
|
100
|
+
if (u instanceof Set) {
|
|
101
|
+
const out = new Set();
|
|
102
|
+
seen.set(u, out);
|
|
103
|
+
for (const v of u.values()) {
|
|
104
|
+
out.add(walk(v));
|
|
105
|
+
}
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
// Plain object or class instance: copy enumerable own properties,
|
|
109
|
+
// skipping keys "at" and "location"
|
|
110
|
+
if (isObject(u)) {
|
|
111
|
+
const out = {};
|
|
112
|
+
seen.set(u, out);
|
|
113
|
+
const src = u;
|
|
114
|
+
for (const key of Object.keys(src)) {
|
|
115
|
+
// skip location metadata
|
|
116
|
+
if (key === 'at' || key === 'location')
|
|
117
|
+
continue;
|
|
118
|
+
const val = src[key];
|
|
119
|
+
// drop properties that exist but have undefined value
|
|
120
|
+
if (val === undefined)
|
|
121
|
+
continue;
|
|
122
|
+
const w = walk(val);
|
|
123
|
+
// if the walked value is undefined, skip adding the property
|
|
124
|
+
if (w === undefined)
|
|
125
|
+
continue;
|
|
126
|
+
out[key] = w;
|
|
127
|
+
}
|
|
128
|
+
return out;
|
|
129
|
+
}
|
|
130
|
+
// Fallback
|
|
131
|
+
return u;
|
|
132
|
+
}
|
|
133
|
+
return pretty(walk(value));
|
|
54
134
|
}
|
|
55
135
|
const intType = { type: 'number', numberType: 'integer' };
|
|
56
136
|
const mockSchema = {
|
|
@@ -3,7 +3,7 @@ import type { Dialect, QueryInfo } from '../dialect';
|
|
|
3
3
|
export declare const FilterCompilers: {
|
|
4
4
|
compile(t: string, c: FilterExpression | null, x: string, d: Dialect, qi?: QueryInfo): string;
|
|
5
5
|
numberCompile(nc: NumberFilter, x: string, d: Dialect): string;
|
|
6
|
-
booleanCompile(bc: BooleanFilter, x: string,
|
|
6
|
+
booleanCompile(bc: BooleanFilter, x: string, d: Dialect): string;
|
|
7
7
|
stringCompile(sc: StringFilter, x: string, d: Dialect): string;
|
|
8
8
|
temporalCompile(tc: TemporalFilter, x: string, d: Dialect, t: "date" | "timestamp", qi?: QueryInfo): string;
|
|
9
9
|
};
|
|
@@ -100,19 +100,52 @@ exports.FilterCompilers = {
|
|
|
100
100
|
.join(` ${nc.operator.toUpperCase()} `);
|
|
101
101
|
}
|
|
102
102
|
},
|
|
103
|
-
booleanCompile(bc, x,
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
103
|
+
booleanCompile(bc, x, d) {
|
|
104
|
+
const px = `(${x})`;
|
|
105
|
+
/*
|
|
106
|
+
* We have the following truth table for boolean filters.
|
|
107
|
+
* The default malloy operations treat null as false. The '='
|
|
108
|
+
* variants exist for cases where that is not desired.
|
|
109
|
+
*
|
|
110
|
+
* filter expression | x=true | x=false | x=null
|
|
111
|
+
* true | T | F | F
|
|
112
|
+
* not true | F | T | T
|
|
113
|
+
* =true | T | F | NULL
|
|
114
|
+
* not =true | F | T | NULL
|
|
115
|
+
* false | F | T | T
|
|
116
|
+
* not false | T | F | F
|
|
117
|
+
* =false | F | T | NULL
|
|
118
|
+
* not =false | T | F | NULL
|
|
119
|
+
*/
|
|
120
|
+
if (bc.operator === '=true') {
|
|
121
|
+
return bc.not ? `NOT ${px}` : x;
|
|
122
|
+
}
|
|
123
|
+
else if (bc.operator === '=false') {
|
|
124
|
+
return bc.not ? x : `NOT ${px}`;
|
|
125
|
+
}
|
|
126
|
+
else if (bc.operator === 'null') {
|
|
127
|
+
return bc.not ? `${px} IS NOT NULL` : `${px} IS NULL`;
|
|
128
|
+
}
|
|
129
|
+
// For some databases checking NULL combined with a boolean check
|
|
130
|
+
// is faster than a COALESCE, for now, just detect if the expression
|
|
131
|
+
// is just a column reference, and if so, don't use COALECSE.
|
|
132
|
+
const quoteChar = d.sqlMaybeQuoteIdentifier('select')[0];
|
|
133
|
+
const isColumn = x.match(`^[()${quoteChar}\\w.]+$`);
|
|
134
|
+
if (isColumn) {
|
|
135
|
+
if (bc.operator === 'true') {
|
|
108
136
|
return bc.not
|
|
109
|
-
?
|
|
110
|
-
:
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
137
|
+
? `${px} IS NULL OR ${px} = false`
|
|
138
|
+
: `${px} IS NOT NULL AND ${px}`;
|
|
139
|
+
}
|
|
140
|
+
return bc.not
|
|
141
|
+
? `${px} IS NOT NULL AND ${px}` // not false: exclude null
|
|
142
|
+
: `${px} IS NULL OR ${px} = false`; // false: include null
|
|
143
|
+
}
|
|
144
|
+
if (bc.operator === 'true') {
|
|
145
|
+
return bc.not ? `NOT COALESCE(${x}, false)` : `COALESCE(${x}, false)`;
|
|
115
146
|
}
|
|
147
|
+
// else bc.operator === 'false'
|
|
148
|
+
return bc.not ? `COALESCE(${x}, false)` : `NOT COALESCE(${x}, false)`;
|
|
116
149
|
},
|
|
117
150
|
stringCompile(sc, x, d) {
|
|
118
151
|
switch (sc.operator) {
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const MALLOY_VERSION = "0.0.
|
|
1
|
+
export declare const MALLOY_VERSION = "0.0.321";
|
package/dist/version.js
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MALLOY_VERSION = void 0;
|
|
4
4
|
// generated with 'generate-version-file' script; do not edit manually
|
|
5
|
-
exports.MALLOY_VERSION = '0.0.
|
|
5
|
+
exports.MALLOY_VERSION = '0.0.321';
|
|
6
6
|
//# sourceMappingURL=version.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@malloydata/malloy",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.321",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dist/index.js",
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
"generate-version-file": "VERSION=$(npm pkg get version --workspaces=false | tr -d \\\")\necho \"// generated with 'generate-version-file' script; do not edit manually\\nexport const MALLOY_VERSION = '$VERSION';\" > src/version.ts"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@malloydata/malloy-filter": "0.0.
|
|
45
|
-
"@malloydata/malloy-interfaces": "0.0.
|
|
46
|
-
"@malloydata/malloy-tag": "0.0.
|
|
44
|
+
"@malloydata/malloy-filter": "0.0.321",
|
|
45
|
+
"@malloydata/malloy-interfaces": "0.0.321",
|
|
46
|
+
"@malloydata/malloy-tag": "0.0.321",
|
|
47
47
|
"antlr4ts": "^0.5.0-alpha.4",
|
|
48
48
|
"assert": "^2.0.0",
|
|
49
49
|
"jaro-winkler": "^0.2.8",
|