Skip to content

Commit

Permalink
Merge branch 'array-in-query' of github.com:malloydata/malloy into ar…
Browse files Browse the repository at this point in the history
…ray-in-query

merging
  • Loading branch information
lloydtabb committed Nov 29, 2024
2 parents 0b0b392 + 9536a22 commit dd87d84
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 16 deletions.
7 changes: 3 additions & 4 deletions packages/malloy/src/dialect/pg_impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,10 @@ export abstract class PostgresBase extends Dialect {
}

sqlLiteralRecord(_lit: RecordLiteralNode): string {
throw new Error('Cannot create a record literal for postgres');
throw new Error('Cannot create a record literal for postgres base dialect');
}

sqlLiteralArray(lit: ArrayLiteralNode): string {
const array = lit.kids.values.map(val => val.sql);
return '{' + array.join(',') + '}';
sqlLiteralArray(_lit: ArrayLiteralNode): string {
throw new Error('Cannot create array literal for postgres base dialect');
}
}
16 changes: 16 additions & 0 deletions packages/malloy/src/dialect/postgres/postgres.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import {
TypecastExpr,
MeasureTimeExpr,
LeafAtomicTypeDef,
RecordLiteralNode,
ArrayLiteralNode,
} from '../../model/malloy_types';
import {
DialectFunctionOverloadDef,
Expand Down Expand Up @@ -445,4 +447,18 @@ export class PostgresDialect extends PostgresBase {
// Square Brackets: INT64[]
return sqlType.match(/^[A-Za-z\s(),[\]0-9]*$/) !== null;
}

sqlLiteralRecord(lit: RecordLiteralNode): string {
const props: string[] = [];
for (const [kName, kVal] of Object.entries(lit.kids)) {
props.push(`"${kName}": ${kVal.sql}`);
}
return `{${props.join(',')}}::jsonb`;
}

sqlLiteralArray(lit: ArrayLiteralNode): string {
// mtoy todo real quoting of values ... strings with quotes will break thi
const array = lit.kids.values.map(val => val.sql);
return `'[${array.join(',')}]'::jsonb`;
}
}
30 changes: 18 additions & 12 deletions test/src/databases/all/compound-atomic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ describe.each(runtimes.runtimeList)(
function recordSelectVal(fromObj: Record<string, number>): string {
return runtime.dialect.sqlLiteralRecord(recordLiteral(fromObj));
}
const canReadCompoungSchema = conName !== 'mysql' && conName !== 'postgres';
const canReadCompoundSchema = conName !== 'mysql' && conName !== 'postgres';

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const ab = recordSelectVal({a: 0, b: 1});
Expand All @@ -88,7 +88,7 @@ describe.each(runtimes.runtimeList)(
const sizesSQL = recordSelectVal(sizesObj);
// Keeping the pipeline simpler makes debugging easier, so don't add
// and extra stage unless you have to
const sizes = canReadCompoungSchema
const sizes = canReadCompoundSchema
? `${conName}.sql(""" SELECT ${sizesSQL} AS ${quote('sizes')} """)`
: `${conName}.sql('SELECT 0 AS O') -> { select: ${malloySizes}}`;
const evensObj = [2, 4, 6, 8];
Expand All @@ -109,20 +109,23 @@ describe.each(runtimes.runtimeList)(
run: ${evens}->{select: nn is evens}
`).malloyResultMatches(runtime, {nn: evensObj});
});
test('schema read allows array-un-nest on each', async () => {
await expect(`
test.when(canReadCompoundSchema)(
'schema read allows array-un-nest on each',
async () => {
await expect(`
run: ${evens}->{ select: n is evens.each }
`).malloyResultMatches(
runtime,
evensObj.map(n => ({n}))
);
});
runtime,
evensObj.map(n => ({n}))
);
}
);
test('array can be passed to !function', async () => {
// Used as a standin for "unknown function user might call"
const nameOfArrayLenFunction = {
'duckdb': 'LEN',
'standardsql': 'ARRAY_LENGTH',
'postgres': 'ARRAY_LENGTH',
'postgres': 'JSONB_ARRAY_LENGTH',
'presto': 'CARDINALITY',
'trino': 'CARDINALITY',
'mysql': 'JSON_LENGTH',
Expand Down Expand Up @@ -208,11 +211,14 @@ describe.each(runtimes.runtimeList)(
-> { select: ${malloySizes}}
`).malloyResultMatches(runtime, rec_eq());
});
test('can read schema of record object', async () => {
await expect(`run: ${conName}.sql("""
test.when(canReadCompoundSchema)(
'can read schema of record object',
async () => {
await expect(`run: ${conName}.sql("""
SELECT ${sizesSQL} AS ${quote('sizes')}
""")`).malloyResultMatches(runtime, rec_eq());
});
}
);
test('simple record.property access', async () => {
await expect(`
run: ${sizes} -> { select: small is sizes.s }`).malloyResultMatches(
Expand Down

0 comments on commit dd87d84

Please sign in to comment.