From bfda7daca7f2fb9a0a61fc8085f63077619c20cf Mon Sep 17 00:00:00 2001 From: Michael Toy <66150587+mtoy-googly-moogly@users.noreply.github.com> Date: Fri, 29 Nov 2024 09:22:35 -0800 Subject: [PATCH 1/2] postmess --- packages/malloy/src/dialect/pg_impl.ts | 7 +++---- packages/malloy/src/dialect/postgres/postgres.ts | 16 ++++++++++++++++ test/src/databases/all/compound-atomic.spec.ts | 2 +- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/packages/malloy/src/dialect/pg_impl.ts b/packages/malloy/src/dialect/pg_impl.ts index 86bc25665..791327e60 100644 --- a/packages/malloy/src/dialect/pg_impl.ts +++ b/packages/malloy/src/dialect/pg_impl.ts @@ -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'); } } diff --git a/packages/malloy/src/dialect/postgres/postgres.ts b/packages/malloy/src/dialect/postgres/postgres.ts index 31da3ad8c..bcaca2e65 100644 --- a/packages/malloy/src/dialect/postgres/postgres.ts +++ b/packages/malloy/src/dialect/postgres/postgres.ts @@ -32,6 +32,8 @@ import { TypecastExpr, MeasureTimeExpr, LeafAtomicTypeDef, + RecordLiteralNode, + ArrayLiteralNode, } from '../../model/malloy_types'; import { DialectFunctionOverloadDef, @@ -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`; + } } diff --git a/test/src/databases/all/compound-atomic.spec.ts b/test/src/databases/all/compound-atomic.spec.ts index fa1be297c..abb20a92e 100644 --- a/test/src/databases/all/compound-atomic.spec.ts +++ b/test/src/databases/all/compound-atomic.spec.ts @@ -122,7 +122,7 @@ describe.each(runtimes.runtimeList)( const nameOfArrayLenFunction = { 'duckdb': 'LEN', 'standardsql': 'ARRAY_LENGTH', - 'postgres': 'ARRAY_LENGTH', + 'postgres': 'JSONB_ARRAY_LENGTH', 'presto': 'CARDINALITY', 'trino': 'CARDINALITY', 'mysql': 'JSON_LENGTH', From 9536a22d2bf6e1f68d27a48e22fae5acaa02d585 Mon Sep 17 00:00:00 2001 From: Michael Toy <66150587+mtoy-googly-moogly@users.noreply.github.com> Date: Fri, 29 Nov 2024 09:26:56 -0800 Subject: [PATCH 2/2] skip schema read checks on mysql --- .../src/databases/all/compound-atomic.spec.ts | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/test/src/databases/all/compound-atomic.spec.ts b/test/src/databases/all/compound-atomic.spec.ts index abb20a92e..c1aa7b3b2 100644 --- a/test/src/databases/all/compound-atomic.spec.ts +++ b/test/src/databases/all/compound-atomic.spec.ts @@ -78,7 +78,7 @@ describe.each(runtimes.runtimeList)( function recordSelectVal(fromObj: Record): 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}); @@ -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]; @@ -109,14 +109,17 @@ 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 = { @@ -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(