From 22d8ddda7941de4764fa99c3425d4c9582603ef0 Mon Sep 17 00:00:00 2001 From: stefanbaxter Date: Mon, 13 Jul 2026 16:56:42 +0000 Subject: [PATCH] fix(cubejs): scaffold primary keys on join TARGETS too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to #70: cube requires a primary key on BOTH sides of a join — 'primary key for X is required when join is defined' also fires for the referenced cube (Rental belongsTo Customer ⇒ Customer needs a pk). Add the hidden id-pattern primary-key dimension to every scaffolded cube that has one, not only cubes that own joins. Verified: 3-table Pagila scaffold now compiles and serves Rental/Film/Customer. Co-Authored-By: Claude Fable 5 --- services/cubejs/src/routes/generateDataSchema.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/services/cubejs/src/routes/generateDataSchema.js b/services/cubejs/src/routes/generateDataSchema.js index 84fc13b4..33dfd504 100644 --- a/services/cubejs/src/routes/generateDataSchema.js +++ b/services/cubejs/src/routes/generateDataSchema.js @@ -26,17 +26,23 @@ const ensureYamlPrimaryKeys = (files, schema) => { } let changed = false; (doc?.cubes || []).forEach((cube) => { - if (!cube?.joins?.length) return; + // Every scaffolded cube gets a primary key when an id-pattern column + // exists — join SOURCES need it to compile, and join TARGETS need it + // for aggregate correctness ("primary key for 'X' is required when + // join is defined" fires for the referenced cube too). const dimensions = cube.dimensions || []; if (dimensions.some((d) => d.primary_key || d.primaryKey)) return; const tableMatch = /from\s+(?:[\w"]+\.)?"?(\w+)"?/i.exec(cube.sql || ""); const tableName = tableMatch?.[1]; const columns = (tableName && columnsByTable[tableName]) || []; + const joins = cube.joins || []; const pkColumn = columns.find((c) => c === "id") || columns.find((c) => c === `${tableName}_id`) || - columns.find((c) => /_id$/.test(c) && cube.joins.every((j) => !(j.sql || "").includes(`{CUBE}.${c}`))); + columns.find( + (c) => /_id$/.test(c) && joins.every((j) => !(j.sql || "").includes(`{CUBE}.${c}`)) + ); if (!pkColumn) return; dimensions.unshift({