@rex0220/kintone-sql-tools 3.56.0 → 3.56.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cli/ksql.js +53 -2
- package/dist-engine/index.cjs +11 -11
- package/dist-engine/index.mjs +11 -11
- package/dist-engine/ksql-engine.umd.js +11 -11
- package/dist-engine/meta/bundle-baseline.json +7 -7
- package/dist-engine/meta/cjs.json +3 -3
- package/dist-engine/meta/esm.json +3 -3
- package/dist-engine/meta/umd.json +3 -3
- package/dist-mcp/ksql-mcp.js +55 -4
- package/dist-mcpb/ksql-mcp.mcpb +0 -0
- package/package.json +1 -1
package/dist-cli/ksql.js
CHANGED
|
@@ -17978,9 +17978,29 @@ async function executeSelect(stmt, client, options, cacheContext, cteCache, capt
|
|
|
17978
17978
|
}
|
|
17979
17979
|
return mergeSelectWarnings(result, [...defaultRangeWarnings, ...subtableFieldWarnings]);
|
|
17980
17980
|
}
|
|
17981
|
+
function subtableGroupingAdvice(fieldName, owners) {
|
|
17982
|
+
if (owners.length === 1) {
|
|
17983
|
+
const { appId, owner } = owners[0];
|
|
17984
|
+
return `ArgumentError: ${fieldName} \u306F\u30B5\u30D6\u30C6\u30FC\u30D6\u30EB\u300C${owner}\u300D\uFF08APP${appId}\uFF09\u306E\u4E2D\u306E\u9805\u76EE\u3067\u3059\u3002\u89AA\u30C6\u30FC\u30D6\u30EB\u306E GROUP BY \u306B\u306F\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093\u3002APP${appId}$${owner} \u304B\u3089\u96C6\u8A08\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u89AA\u306E\u30EC\u30B3\u30FC\u30C9 ID \u306F _pid\u3001\u89AA\u9805\u76EE\u306F _p.<\u30D5\u30A3\u30FC\u30EB\u30C9\u30B3\u30FC\u30C9> \u306B\u306A\u308A\u307E\u3059\uFF09\u3002`;
|
|
17985
|
+
}
|
|
17986
|
+
const list = owners.map(({ appId, owner }) => `APP${appId}$${owner}`).join(" / ");
|
|
17987
|
+
return `ArgumentError: ${fieldName} \u306F\u30B5\u30D6\u30C6\u30FC\u30D6\u30EB\u306E\u4E2D\u306E\u9805\u76EE\u3067\u3059\uFF08${list}\uFF09\u3002\u89AA\u30C6\u30FC\u30D6\u30EB\u306E GROUP BY \u306B\u306F\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093\u3002\u3069\u306E\u30B5\u30D6\u30C6\u30FC\u30D6\u30EB\u304B\u3089\u96C6\u8A08\u3059\u308B\u304B\u3092 FROM \u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002`;
|
|
17988
|
+
}
|
|
17989
|
+
function dedupeSubtableOwners(owners) {
|
|
17990
|
+
const seen = /* @__PURE__ */ new Set();
|
|
17991
|
+
const result = [];
|
|
17992
|
+
for (const entry of owners) {
|
|
17993
|
+
const key = `${entry.appId}\0${entry.owner}`;
|
|
17994
|
+
if (seen.has(key)) continue;
|
|
17995
|
+
seen.add(key);
|
|
17996
|
+
result.push(entry);
|
|
17997
|
+
}
|
|
17998
|
+
return result;
|
|
17999
|
+
}
|
|
17981
18000
|
async function buildRuntimePlainGroupByPlan(stmt, client, cacheContext, materializedTables) {
|
|
17982
18001
|
if (stmt.groupBy.length === 0) return void 0;
|
|
17983
18002
|
const sources = [stmt.from, ...stmt.joins.map((join2) => join2.table)];
|
|
18003
|
+
const subtableOwners = /* @__PURE__ */ new Map();
|
|
17984
18004
|
const inputs = await Promise.all(sources.map(async (source) => {
|
|
17985
18005
|
if (source.cteName !== null) {
|
|
17986
18006
|
const materialized = materializedTables?.get(source.cteName);
|
|
@@ -17991,6 +18011,12 @@ async function buildRuntimePlainGroupByPlan(stmt, client, cacheContext, material
|
|
|
17991
18011
|
}
|
|
17992
18012
|
const fields = await getFieldsCached(source.appId, client, cacheContext);
|
|
17993
18013
|
if (!source.subtableCode) {
|
|
18014
|
+
for (const field of fields) {
|
|
18015
|
+
if (field.inSubtable !== true || !field.subtableCode) continue;
|
|
18016
|
+
const entries = subtableOwners.get(field.code) ?? [];
|
|
18017
|
+
entries.push({ appId: source.appId, owner: field.subtableCode });
|
|
18018
|
+
subtableOwners.set(field.code, dedupeSubtableOwners(entries));
|
|
18019
|
+
}
|
|
17994
18020
|
return {
|
|
17995
18021
|
kind: "APP",
|
|
17996
18022
|
fieldCodes: fields.filter((field) => !field.inSubtable).map((field) => field.code)
|
|
@@ -18012,10 +18038,10 @@ async function buildRuntimePlainGroupByPlan(stmt, client, cacheContext, material
|
|
|
18012
18038
|
);
|
|
18013
18039
|
const groupBy = stmt.groupBy;
|
|
18014
18040
|
const plan = planPlainGroupByResolution(groupBy, stmt.columns, schemas);
|
|
18015
|
-
assertRuntimePlainGroupByPlan(stmt, groupBy, plan);
|
|
18041
|
+
assertRuntimePlainGroupByPlan(stmt, groupBy, plan, subtableOwners);
|
|
18016
18042
|
return plan;
|
|
18017
18043
|
}
|
|
18018
|
-
function assertRuntimePlainGroupByPlan(stmt, groupBy, plan) {
|
|
18044
|
+
function assertRuntimePlainGroupByPlan(stmt, groupBy, plan, subtableOwners) {
|
|
18019
18045
|
const physicalAppIds = [
|
|
18020
18046
|
stmt.from,
|
|
18021
18047
|
...stmt.joins.map((join2) => join2.table)
|
|
@@ -18028,6 +18054,12 @@ function assertRuntimePlainGroupByPlan(stmt, groupBy, plan) {
|
|
|
18028
18054
|
const name = key?.type === "FIELD_NAME" ? key.name : "(expression)";
|
|
18029
18055
|
if (item.kind === "UNKNOWN") {
|
|
18030
18056
|
const appSuffix = primaryPhysicalAppId === null ? "" : ` (APP${primaryPhysicalAppId})`;
|
|
18057
|
+
const dot = item.name.indexOf(".");
|
|
18058
|
+
const bare = dot >= 0 ? item.name.slice(dot + 1) : item.name;
|
|
18059
|
+
const owners = subtableOwners.get(item.name) ?? subtableOwners.get(bare) ?? [];
|
|
18060
|
+
if (owners.length > 0) {
|
|
18061
|
+
throw new Error(subtableGroupingAdvice(item.name, owners));
|
|
18062
|
+
}
|
|
18031
18063
|
throw new Error(`ArgumentError: unknown field code(s): ${item.name}${appSuffix}`);
|
|
18032
18064
|
}
|
|
18033
18065
|
if (item.kind === "ALIAS_REJECT") {
|
|
@@ -18078,9 +18110,15 @@ async function buildGroupingFieldResolver(stmt, client, cacheContext, materializ
|
|
|
18078
18110
|
return [appId, new Map(infos.map((info) => [info.code, info]))];
|
|
18079
18111
|
}))
|
|
18080
18112
|
);
|
|
18113
|
+
const subtableFieldOf = (table, code) => {
|
|
18114
|
+
if (table.subtableCode) return null;
|
|
18115
|
+
const info = infosByApp.get(table.appId)?.get(code);
|
|
18116
|
+
return info?.inSubtable === true ? info.subtableCode ?? "" : null;
|
|
18117
|
+
};
|
|
18081
18118
|
const physicalMatch = (table, field) => {
|
|
18082
18119
|
if (field === "$id") return "$id";
|
|
18083
18120
|
const code = fieldCodeForTypeLookup(table, field);
|
|
18121
|
+
if (subtableFieldOf(table, code) !== null) return null;
|
|
18084
18122
|
return infosByApp.get(table.appId)?.has(code) ? code : null;
|
|
18085
18123
|
};
|
|
18086
18124
|
const materializedHas = (table, field) => {
|
|
@@ -18115,6 +18153,10 @@ async function buildGroupingFieldResolver(stmt, client, cacheContext, materializ
|
|
|
18115
18153
|
}
|
|
18116
18154
|
const code = physicalMatch(table, field.field);
|
|
18117
18155
|
if (code === null) {
|
|
18156
|
+
const owner = subtableFieldOf(table, fieldCodeForTypeLookup(table, field.field));
|
|
18157
|
+
if (owner !== null && owner !== "") {
|
|
18158
|
+
throw new Error(subtableGroupingAdvice(field.field, [{ appId: table.appId, owner }]));
|
|
18159
|
+
}
|
|
18118
18160
|
throw new Error(`ArgumentError: B65 field ${field.tableAlias}.${field.field} does not exist in APP${table.appId}.`);
|
|
18119
18161
|
}
|
|
18120
18162
|
return resolved(table, tableIndex, field, code);
|
|
@@ -18137,6 +18179,15 @@ async function buildGroupingFieldResolver(stmt, client, cacheContext, materializ
|
|
|
18137
18179
|
`ArgumentError: B65 field ${field.field} resolves to a materialized CTE/temp column; physical APP fields are required.`
|
|
18138
18180
|
);
|
|
18139
18181
|
}
|
|
18182
|
+
const owners = tables.flatMap((table) => {
|
|
18183
|
+
if (table.cteName !== null) return [];
|
|
18184
|
+
const owner = subtableFieldOf(table, fieldCodeForTypeLookup(table, field.field));
|
|
18185
|
+
return owner === null || owner === "" ? [] : [{ appId: table.appId, owner }];
|
|
18186
|
+
});
|
|
18187
|
+
const uniqueOwners = dedupeSubtableOwners(owners);
|
|
18188
|
+
if (uniqueOwners.length > 0) {
|
|
18189
|
+
throw new Error(subtableGroupingAdvice(field.field, uniqueOwners));
|
|
18190
|
+
}
|
|
18140
18191
|
throw new Error(`ArgumentError: B65 field ${field.field} does not exist in a physical APP source.`);
|
|
18141
18192
|
};
|
|
18142
18193
|
}
|