Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions test/src/databases/all/db_index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,8 @@ runtimes.runtimeMap.forEach((runtime, databaseName) => {
test.when(runtime.dialect.supportsTempTables)(
`basic index - ${databaseName}`,
async () => {
const model = await runtime.loadModel(
`
source: airports is ${databaseName}.table('malloytest.airports') extend {
}
`
const model = runtime.loadModel(
`source: airports is ${databaseName}.table('malloytest.airports')`
);
let result = await model.search('airports', 'SANTA', 10);

Expand Down
77 changes: 77 additions & 0 deletions test/src/databases/all/join.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
/* eslint-disable no-console */

import {RuntimeList, allDatabases} from '../../runtimes';
import {TestSelect} from '../../test-select';
import {databasesFromEnvironmentOr} from '../../util';
import '../../util/db-jest-matchers';

Expand Down Expand Up @@ -318,4 +319,80 @@ describe.each(runtimes.runtimeList)('%s', (databaseName, runtime) => {
`).matchesRows(runtime, {pick_a1: [1]});
}
);

// Issue 2486, tried to resolve, but could not arrrive at a solution
// which works on all dialects.
test('2486 -- join on joined column', async () => {
await expect(`
source: usr is ${databaseName}.sql("""select 1 as id, 'email' as email""")
source: res is ${databaseName}.sql("""select 1 as id, 1 as user_id""") extend {
join_one: usr is usr on usr.id = user_id
// dimension: usr_email is usr.email
}
source: msg is ${databaseName}.sql("""select 1 as id, 'email' as msg_email""") extend {
join_many: res is res on msg_email = res.usr.email
}
run: msg -> {
select: *, res.usr.email
}
`).malloyResultMatches(runtime, {
id: 1,
usr_email: 'email',
});
});

function randomBase36Id(): string {
// Generate two random 32-bit integers
const high = Math.floor(Math.random() * 0x100000000); // 2^32
const low = Math.floor(Math.random() * 0x100000000);

// Combine into a 64-bit BigInt
const random64 = (BigInt(high) << BigInt(32)) | BigInt(low);

// Convert to base36 and pad to 13 characters
return random64.toString(36).padStart(13, '0');
}

test('join through repeated record problem', async () => {
const ts = new TestSelect(runtime.dialect);
const events = ts.generate(
{
event_name: 'page_view',
event_params: [
{key: 'page_location', value: '/home'},
{key: 'page_title', value: 'Home Page'},
],
},
{
event_name: 'user_engagement',
event_params: [
{key: 'engagement_time', value: '1000'},
{key: 'page_view', value: 'true'},
],
},
{event_name: 'scroll', event_params: [{key: 'percent', value: '50'}]}
);
let eventTable: string;
if (databaseName === 'duckdb') {
const tableName = `event_${randomBase36Id()}`;
await runtime.connection.runSQL(
`CREATE TEMPORARY TABLE ${tableName} AS ${events}`
);
eventTable = `${databaseName}.table('${tableName}')`;
} else {
eventTable = `${databaseName}.sql("""${events}""")`;
}
await expect(`
source: ga4_s1 is ${eventTable} extend { dimension: event_param is event_params.key }
source: ga4_s2 is ${eventTable} extend { join_one: ga4_j1 is ga4_s1 on event_name = ga4_j1.event_param }
run: ga4_s2 -> {
select: event_name, ga4_event is ga4_j1.event_name
where: ga4_j1.event_param is not null
}
`).malloyResultMatches(runtime, {
event_name: 'page_view',
ga4_event: 'user_engagement',
cnt: 1,
});
});
});
56 changes: 0 additions & 56 deletions test/src/test-select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -544,59 +544,3 @@ export class TestSelect {
);
}
}

/*
Example usage:

const testSelect = new TestSelect(dialect);

const userSQL = testSelect.generate([
{
id: testSelect.mk_int(1),
name: "bob",
email: "bob@example.com",
score: testSelect.mk_float(85.5),
is_active: testSelect.mk_bool(true),
created_at: testSelect.mk_timestamp('2024-01-15 14:30:00'),
signup_date: testSelect.mk_date('2024-01-15'),
tags: ["admin", "user"], // Inferred as array
settings: { // Inferred as record
theme: "dark",
notifications: true
}
},
{
id: testSelect.mk_int(2),
name: "alice",
email: testSelect.mk_string(null), // Typed NULL
score: testSelect.mk_float(92.0),
is_active: testSelect.mk_bool(false),
created_at: testSelect.mk_timestamp('2024-01-16 09:00:00'),
signup_date: testSelect.mk_date('2024-01-16'),
tags: ["user"],
settings: {
theme: "light",
notifications: false
}
}
]);

const orderSQL = testSelect.generate([
{
id: 1, // Inferred as integer
user_id: testSelect.mk_int(1),
amount: 99.99, // Inferred as float
status: "pending",
items: [
{sku: "ABC", qty: 2, price: 10.00},
{sku: "DEF", qty: 1, price: 20.00}
]
}
]);

// Use in Malloy:
const malloySource = `
source: users is duckdb.sql("""${userSQL}""")
source: orders is duckdb.sql("""${orderSQL}""")
`;
*/
Loading