Skip to content

Commit

Permalink
Trino, more stuff. (#1720)
Browse files Browse the repository at this point in the history
* trino doesn't support temp tables

* div, and more.

* More function fixes

* last test.
  • Loading branch information
lloydtabb authored Apr 13, 2024
1 parent 1229f61 commit 8bf817b
Show file tree
Hide file tree
Showing 14 changed files with 352 additions and 39 deletions.
3 changes: 3 additions & 0 deletions packages/malloy/src/dialect/dialect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ export abstract class Dialect {
// ability to join source with a filter on a joined source.
supportsComplexFilteredSources = true;

// can create temp tables
supportsTempTables = true;

// return the definition of a function with the given name
abstract getGlobalFunctionDef(
name: string
Expand Down
17 changes: 7 additions & 10 deletions packages/malloy/src/dialect/functions/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,16 @@ export function arg(name: string): Fragment {
};
}

export function spread(f: Fragment): Fragment {
export function spread(
f: Fragment,
prefix: string | undefined = undefined,
suffix: string | undefined = undefined
): Fragment {
return {
type: 'spread',
e: [f],
};
}

// LTABB: this doesn't work, needs to be rewriten in terms of function parameters.
export function spreadCast(f: Fragment, _destType: string): Fragment {
return {
type: 'spread',
e: [f],
// e: ['CAST(', f, `AS ${destType})`],
prefix,
suffix,
};
}

Expand Down
62 changes: 62 additions & 0 deletions packages/malloy/src/dialect/trino/functions/chr.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright 2023 Google LLC
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import {
arg,
overload,
param,
minScalar,
anyExprType,
sql,
DialectFunctionOverloadDef,
} from '../../functions/util';

export function fnChr(): DialectFunctionOverloadDef[] {
return [
overload(
minScalar('string'),
[param('value', anyExprType('number'))],
sql`CASE WHEN ${arg('value')} = 0 THEN '' ELSE CHR(${arg('value')}) END`
),
];
}

export function fnAscii(): DialectFunctionOverloadDef[] {
return [
overload(
minScalar('number'),
[param('value', anyExprType('string'))],
sql`CODEPOINT(NULLIF(CAST(${arg('value')} as VARCHAR(1)),''))`
),
];
}

export function fnUnicode(): DialectFunctionOverloadDef[] {
return [
overload(
minScalar('number'),
[param('value', anyExprType('string'))],
sql`CODEPOINT(NULLIF(CAST(${arg('value')} as VARCHAR(1)),''))`
),
];
}
4 changes: 2 additions & 2 deletions packages/malloy/src/dialect/trino/functions/concat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
params,
minScalar,
anyExprType,
spreadCast,
spread,
sql,
DialectFunctionOverloadDef,
} from '../../functions/util';
Expand All @@ -53,7 +53,7 @@ export function fnConcat(): DialectFunctionOverloadDef[] {
anyExprType('boolean')
),
],
sql`CONCAT(${spreadCast(arg('values'), 'VARCHAR')})`
sql`CONCAT(${spread(arg('values'), 'CAST(', 'AS VARCHAR)')})`
),
];
}
45 changes: 45 additions & 0 deletions packages/malloy/src/dialect/trino/functions/div.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2023 Google LLC
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import {
arg,
overload,
param,
minScalar,
anyExprType,
sql,
DialectFunctionOverloadDef,
} from '../../functions/util';

export function fnDiv(): DialectFunctionOverloadDef[] {
return [
overload(
minScalar('number'),
[
param('dividend', anyExprType('number')),
param('divisor', anyExprType('number')),
],
sql`FLOOR(${arg('dividend')} / ${arg('divisor')})`
),
];
}
42 changes: 42 additions & 0 deletions packages/malloy/src/dialect/trino/functions/is_inf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2023 Google LLC
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import {
arg,
overload,
param,
minScalar,
anyExprType,
sql,
DialectFunctionOverloadDef,
} from '../../functions/util';

export function fnIsInf(): DialectFunctionOverloadDef[] {
return [
overload(
minScalar('boolean'),
[param('value', anyExprType('number'))],
sql`COALESCE(IS_INFINITE(${arg('value')}), false)`
),
];
}
43 changes: 43 additions & 0 deletions packages/malloy/src/dialect/trino/functions/repeat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2023 Google LLC
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import {
overload,
minScalar,
anyExprType,
sql,
DialectFunctionOverloadDef,
makeParam,
} from '../../functions/util';

export function fnRepeat(): DialectFunctionOverloadDef[] {
const value = makeParam('value', anyExprType('string'));
const count = makeParam('count', anyExprType('number'));
return [
overload(
minScalar('string'),
[value.param, count.param],
sql`ARRAY_JOIN(REPEAT(${value.arg}, CASE WHEN ${value.arg} IS NOT NULL THEN ${count.arg} END),'')`
),
];
}
42 changes: 42 additions & 0 deletions packages/malloy/src/dialect/trino/functions/reverse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2023 Google LLC
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import {
overload,
minScalar,
anyExprType,
sql,
DialectFunctionOverloadDef,
makeParam,
} from '../../functions/util';

export function fnReverse(): DialectFunctionOverloadDef[] {
const value = makeParam('value', anyExprType('string'));
return [
overload(
minScalar('string'),
[value.param],
sql`REVERSE(CAST(${value.arg} AS VARCHAR))`
),
];
}
55 changes: 55 additions & 0 deletions packages/malloy/src/dialect/trino/functions/starts_ends_with.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright 2023 Google LLC
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import {
overload,
minScalar,
anyExprType,
sql,
DialectFunctionOverloadDef,
makeParam,
} from '../../functions/util';

export function fnStartsWith(): DialectFunctionOverloadDef[] {
const value = makeParam('value', anyExprType('string'));
const prefix = makeParam('prefix', anyExprType('string'));
return [
overload(
minScalar('boolean'),
[value.param, prefix.param],
sql`COALESCE(STARTS_WITH(${value.arg}, ${prefix.arg}), false)`
),
];
}

export function fnEndsWith(): DialectFunctionOverloadDef[] {
const value = makeParam('value', anyExprType('string'));
const suffix = makeParam('suffix', anyExprType('string'));
return [
overload(
minScalar('boolean'),
[value.param, suffix.param],
sql`COALESCE(STARTS_WITH(REVERSE(CAST(${value.arg} AS VARCHAR)), REVERSE(CAST(${suffix.arg} AS VARCHAR))), false)`
),
];
}
15 changes: 15 additions & 0 deletions packages/malloy/src/dialect/trino/functions/trino_functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,31 @@ import {FUNCTIONS} from '../../functions';
import {fnTrunc} from './trunc';
import {fnLog} from './log';
import {fnIfnull} from './ifnull';
import {fnIsInf} from './is_inf';
import {fnConcat} from './concat';
import {fnByteLength} from './byte_length';
import {fnStringAgg, fnStringAggDistinct} from './string_agg';
import {fnChr, fnAscii, fnUnicode} from './chr';
import {fnStartsWith, fnEndsWith} from './starts_ends_with';
import {fnDiv} from './div';
import {fnRepeat} from './repeat';
import {fnReverse} from './reverse';

export const TRINO_FUNCTIONS = FUNCTIONS.clone();
TRINO_FUNCTIONS.add('trunc', fnTrunc);
TRINO_FUNCTIONS.add('log', fnLog);
TRINO_FUNCTIONS.add('ifnull', fnIfnull);
TRINO_FUNCTIONS.add('is_inf', fnIsInf);
TRINO_FUNCTIONS.add('byte_length', fnByteLength);
TRINO_FUNCTIONS.add('concat', fnConcat);
TRINO_FUNCTIONS.add('string_agg', fnStringAgg);
TRINO_FUNCTIONS.add('string_agg_distinct', fnStringAggDistinct);
TRINO_FUNCTIONS.add('div', fnDiv);
TRINO_FUNCTIONS.add('starts_with', fnStartsWith);
TRINO_FUNCTIONS.add('ends_with', fnEndsWith);
TRINO_FUNCTIONS.add('chr', fnChr);
TRINO_FUNCTIONS.add('ascii', fnAscii);
TRINO_FUNCTIONS.add('unicode', fnUnicode);
TRINO_FUNCTIONS.add('repeat', fnRepeat);
TRINO_FUNCTIONS.add('reverse', fnReverse);
TRINO_FUNCTIONS.seal();
1 change: 1 addition & 0 deletions packages/malloy/src/dialect/trino/trino.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ export class TrinoDialect extends Dialect {
nullMatchesFunctionSignature = false;
supportsSelectReplace = false;
supportsComplexFilteredSources = false;
supportsTempTables = false;

quoteTablePath(tablePath: string): string {
// TODO: look into escaping.
Expand Down
2 changes: 2 additions & 0 deletions packages/malloy/src/model/malloy_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,8 @@ export function isSQLExpressionFragment(
export interface SpreadFragment {
type: 'spread';
e: Expr;
prefix: string | undefined;
suffix: string | undefined;
}

export function isSpreadFragment(f: Fragment): f is SpreadFragment {
Expand Down
Loading

0 comments on commit 8bf817b

Please sign in to comment.