@rex0220/kintone-sql-tools 3.10.0 → 3.11.0
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 +123 -22
- package/dist-mcp/ksql-mcp.js +124 -23
- package/dist-mcpb/ksql-mcp.mcpb +0 -0
- package/package.json +1 -1
package/dist-cli/ksql.js
CHANGED
|
@@ -4930,6 +4930,9 @@ function canInlineSingleCte(stmt) {
|
|
|
4930
4930
|
if (stmt.ctes.length !== 1) return false;
|
|
4931
4931
|
const cteDef = stmt.ctes[0];
|
|
4932
4932
|
if (cteDef.query.type !== "SELECT" || resolveSelectMode(cteDef.query) !== "SIMPLE") return false;
|
|
4933
|
+
if (!cteDef.query.columns.every(
|
|
4934
|
+
(column) => column.type === "WILDCARD" || column.type === "FIELD" && (column.alias === null || column.alias === column.field)
|
|
4935
|
+
)) return false;
|
|
4933
4936
|
const finalQuery = stmt.query;
|
|
4934
4937
|
if (finalQuery.type !== "SELECT") return false;
|
|
4935
4938
|
if (finalQuery.from.cteName !== cteDef.name || finalQuery.joins.length > 0) return false;
|
|
@@ -9700,10 +9703,12 @@ function flatten(record, alias) {
|
|
|
9700
9703
|
}
|
|
9701
9704
|
return row;
|
|
9702
9705
|
}
|
|
9703
|
-
function applyJoin(leftRows, rightRows, join2) {
|
|
9706
|
+
function applyJoin(leftRows, rightRows, join2, columns = {}) {
|
|
9704
9707
|
const { on, type: joinType } = join2;
|
|
9705
9708
|
const leftKey = on.left.tableAlias ? `${on.left.tableAlias}.${on.left.field}` : on.left.field;
|
|
9706
9709
|
const rightKey = on.right.tableAlias ? `${on.right.tableAlias}.${on.right.field}` : on.right.field;
|
|
9710
|
+
assertJoinKeyAvailable(leftRows, leftKey, columns.leftColumns);
|
|
9711
|
+
assertJoinKeyAvailable(rightRows, rightKey, columns.rightColumns);
|
|
9707
9712
|
if (joinType === "RIGHT") {
|
|
9708
9713
|
const leftIndex = /* @__PURE__ */ new Map();
|
|
9709
9714
|
for (const lRow of leftRows) {
|
|
@@ -9713,7 +9718,7 @@ function applyJoin(leftRows, rightRows, join2) {
|
|
|
9713
9718
|
else leftIndex.set(k, [lRow]);
|
|
9714
9719
|
}
|
|
9715
9720
|
const emptyLeft = {};
|
|
9716
|
-
for (const key of Object.keys(leftRows[0] ?? {})) emptyLeft[key] = "";
|
|
9721
|
+
for (const key of columns.leftColumns ?? Object.keys(leftRows[0] ?? {})) emptyLeft[key] = "";
|
|
9717
9722
|
const result2 = [];
|
|
9718
9723
|
for (const rRow of rightRows) {
|
|
9719
9724
|
const k = rRow[rightKey] ?? "";
|
|
@@ -9735,7 +9740,7 @@ function applyJoin(leftRows, rightRows, join2) {
|
|
|
9735
9740
|
}
|
|
9736
9741
|
const result = [];
|
|
9737
9742
|
const emptyRight = {};
|
|
9738
|
-
for (const key of Object.keys(rightRows[0] ?? {})) emptyRight[key] = "";
|
|
9743
|
+
for (const key of columns.rightColumns ?? Object.keys(rightRows[0] ?? {})) emptyRight[key] = "";
|
|
9739
9744
|
for (const lRow of leftRows) {
|
|
9740
9745
|
const k = lRow[leftKey] ?? "";
|
|
9741
9746
|
const matched = rightIndex.get(k) ?? [];
|
|
@@ -9749,6 +9754,12 @@ function applyJoin(leftRows, rightRows, join2) {
|
|
|
9749
9754
|
}
|
|
9750
9755
|
return result;
|
|
9751
9756
|
}
|
|
9757
|
+
function assertJoinKeyAvailable(rows, key, savedColumns) {
|
|
9758
|
+
const missing = rows.length > 0 ? rows.some((row) => !Object.prototype.hasOwnProperty.call(row, key)) : savedColumns !== void 0 && !savedColumns.includes(key);
|
|
9759
|
+
if (missing) {
|
|
9760
|
+
throw new Error(`ArgumentError: JOIN key ${key} is not available in the materialized table.`);
|
|
9761
|
+
}
|
|
9762
|
+
}
|
|
9752
9763
|
function applyFilter(rows, where, resolveFieldType, appliedKlikes, resolveFieldSemantics2) {
|
|
9753
9764
|
if (where === null) return rows;
|
|
9754
9765
|
return rows.filter((row) => evalWhere(where, row, resolveFieldType, appliedKlikes, resolveFieldSemantics2));
|
|
@@ -10047,9 +10058,12 @@ function applyLimit(rows, limit, offset) {
|
|
|
10047
10058
|
if (limit === null) return rows.slice(start);
|
|
10048
10059
|
return rows.slice(start, start + limit);
|
|
10049
10060
|
}
|
|
10050
|
-
function project(rows, columns, scalarCache, resolveFieldType, sourceColumns, resolveFieldSemantics2) {
|
|
10061
|
+
function project(rows, columns, scalarCache, resolveFieldType, sourceColumns, resolveFieldSemantics2, hiddenQualifiedAliases) {
|
|
10051
10062
|
if (columns.length === 1 && columns[0].type === "WILDCARD") {
|
|
10052
|
-
const projected2 = rows.map((row) =>
|
|
10063
|
+
const projected2 = rows.map((row) => stripHiddenQualifiedColumns(
|
|
10064
|
+
stripParentShortcutColumns(row),
|
|
10065
|
+
hiddenQualifiedAliases
|
|
10066
|
+
));
|
|
10053
10067
|
const cols = projected2.length > 0 ? Object.keys(projected2[0]) : [...sourceColumns ?? []];
|
|
10054
10068
|
return { rows: projected2, columns: cols };
|
|
10055
10069
|
}
|
|
@@ -10069,7 +10083,10 @@ function project(rows, columns, scalarCache, resolveFieldType, sourceColumns, re
|
|
|
10069
10083
|
case "VARIABLE_COL":
|
|
10070
10084
|
throw new Error(`internal error: unresolved SELECT variable @${col.name}`);
|
|
10071
10085
|
case "WILDCARD":
|
|
10072
|
-
Object.assign(out,
|
|
10086
|
+
Object.assign(out, stripHiddenQualifiedColumns(
|
|
10087
|
+
stripParentShortcutColumns(row),
|
|
10088
|
+
hiddenQualifiedAliases
|
|
10089
|
+
));
|
|
10073
10090
|
break;
|
|
10074
10091
|
case "PARENT_WILDCARD": {
|
|
10075
10092
|
const parentKeys = Object.keys(row).filter((k) => k.startsWith("_p.")).sort();
|
|
@@ -10322,6 +10339,27 @@ function resolveAggInStringFuncExpr(expr, rows, resolveAggSortKind) {
|
|
|
10322
10339
|
args: expr.args.map((arg) => resolveAggInStringFuncArg(arg, rows, resolveAggSortKind))
|
|
10323
10340
|
};
|
|
10324
10341
|
}
|
|
10342
|
+
function stripHiddenQualifiedColumns(row, hiddenQualifiedAliases) {
|
|
10343
|
+
if (!hiddenQualifiedAliases || hiddenQualifiedAliases.size === 0) return row;
|
|
10344
|
+
const out = {};
|
|
10345
|
+
for (const [key, value] of Object.entries(row)) {
|
|
10346
|
+
if ([...hiddenQualifiedAliases].some((alias) => key.startsWith(`${alias}.`))) continue;
|
|
10347
|
+
out[key] = value;
|
|
10348
|
+
}
|
|
10349
|
+
return out;
|
|
10350
|
+
}
|
|
10351
|
+
function flattenedColumns(columns, alias) {
|
|
10352
|
+
if (columns === void 0) return void 0;
|
|
10353
|
+
return alias ? columns.flatMap((column) => [`${alias}.${column}`, column]) : [...columns];
|
|
10354
|
+
}
|
|
10355
|
+
function mergeKnownColumns(left, right, rows) {
|
|
10356
|
+
if (left === void 0 && right === void 0 && rows.length === 0) return void 0;
|
|
10357
|
+
return [.../* @__PURE__ */ new Set([
|
|
10358
|
+
...left ?? [],
|
|
10359
|
+
...right ?? [],
|
|
10360
|
+
...Object.keys(rows[0] ?? {})
|
|
10361
|
+
])];
|
|
10362
|
+
}
|
|
10325
10363
|
function deriveOutputOrderSemantics(columns) {
|
|
10326
10364
|
const result = /* @__PURE__ */ new Map();
|
|
10327
10365
|
for (const column of columns) {
|
|
@@ -10356,7 +10394,9 @@ function runFullScan(input) {
|
|
|
10356
10394
|
havingFieldSemanticsResolver,
|
|
10357
10395
|
aggregateSortKindResolver,
|
|
10358
10396
|
appliedKlikes,
|
|
10359
|
-
sourceColumns
|
|
10397
|
+
sourceColumns,
|
|
10398
|
+
tableColumns,
|
|
10399
|
+
hiddenQualifiedAliases
|
|
10360
10400
|
} = input;
|
|
10361
10401
|
const effectiveOrderSemantics = deriveOutputOrderSemantics(stmt.columns);
|
|
10362
10402
|
for (const [key, value] of orderSemantics ?? []) effectiveOrderSemantics.set(key, value);
|
|
@@ -10364,11 +10404,25 @@ function runFullScan(input) {
|
|
|
10364
10404
|
const mainAlias = stmt.from.alias;
|
|
10365
10405
|
const mainRecords = tables.get(mainAlias) ?? tables.get(null) ?? [];
|
|
10366
10406
|
rows = mainRecords.map((r) => flatten(r, mainAlias));
|
|
10407
|
+
let knownColumns = mergeKnownColumns(
|
|
10408
|
+
flattenedColumns(tableColumns?.get(mainAlias), mainAlias),
|
|
10409
|
+
void 0,
|
|
10410
|
+
rows
|
|
10411
|
+
);
|
|
10367
10412
|
for (const join2 of stmt.joins) {
|
|
10368
10413
|
const rightAlias = join2.table.alias;
|
|
10369
10414
|
const rightRecords = tables.get(rightAlias) ?? [];
|
|
10370
10415
|
const rightRows = rightRecords.map((r) => flatten(r, rightAlias));
|
|
10371
|
-
|
|
10416
|
+
const rightColumns = mergeKnownColumns(
|
|
10417
|
+
flattenedColumns(tableColumns?.get(rightAlias), rightAlias),
|
|
10418
|
+
void 0,
|
|
10419
|
+
rightRows
|
|
10420
|
+
);
|
|
10421
|
+
rows = applyJoin(rows, rightRows, join2, {
|
|
10422
|
+
leftColumns: knownColumns,
|
|
10423
|
+
rightColumns
|
|
10424
|
+
});
|
|
10425
|
+
knownColumns = mergeKnownColumns(knownColumns, rightColumns, rows);
|
|
10372
10426
|
}
|
|
10373
10427
|
rows = applyFilter(rows, stmt.where, fieldTypeResolver, appliedKlikes, fieldSemanticsResolver);
|
|
10374
10428
|
if (stmt.groupBy.length > 0 || hasAggregateColumns(stmt.columns)) {
|
|
@@ -10381,7 +10435,15 @@ function runFullScan(input) {
|
|
|
10381
10435
|
}
|
|
10382
10436
|
rows = applyOrderBy(rows, stmt.orderBy, optionOrders, sortKinds, effectiveOrderSemantics);
|
|
10383
10437
|
rows = applyLimit(rows, stmt.limit, stmt.offset);
|
|
10384
|
-
return project(
|
|
10438
|
+
return project(
|
|
10439
|
+
rows,
|
|
10440
|
+
stmt.columns,
|
|
10441
|
+
scalarCache,
|
|
10442
|
+
fieldTypeResolver,
|
|
10443
|
+
sourceColumns,
|
|
10444
|
+
fieldSemanticsResolver,
|
|
10445
|
+
hiddenQualifiedAliases
|
|
10446
|
+
);
|
|
10385
10447
|
}
|
|
10386
10448
|
|
|
10387
10449
|
// src/converter/subtableAdapter.ts
|
|
@@ -12693,7 +12755,7 @@ async function buildWhereFieldSemanticsResolver(stmt, client, cacheContext, mate
|
|
|
12693
12755
|
if (field.tableAlias === "_p" && stmt.from.subtableCode && stmt.from.cteName === null) {
|
|
12694
12756
|
return fromPhysical(stmt.from, field.field, false);
|
|
12695
12757
|
}
|
|
12696
|
-
const table = tables.find((candidate) => candidate
|
|
12758
|
+
const table = tables.find((candidate) => effectiveTableAlias(candidate) === field.tableAlias);
|
|
12697
12759
|
if (!table) return void 0;
|
|
12698
12760
|
if (table.cteName !== null) {
|
|
12699
12761
|
return materializedTables?.get(table.cteName)?.columnMeta?.get(field.field)?.semantics ?? syntheticSemantics("string");
|
|
@@ -13127,8 +13189,11 @@ function collectSelectTypedInFieldRefs(stmt) {
|
|
|
13127
13189
|
}
|
|
13128
13190
|
return refs;
|
|
13129
13191
|
}
|
|
13192
|
+
function effectiveTableAlias(table) {
|
|
13193
|
+
return table.alias ?? table.cteName;
|
|
13194
|
+
}
|
|
13130
13195
|
function findTableForAlias(stmt, alias) {
|
|
13131
|
-
return [stmt.from, ...stmt.joins.map((join2) => join2.table)].find((table) => table
|
|
13196
|
+
return [stmt.from, ...stmt.joins.map((join2) => join2.table)].find((table) => effectiveTableAlias(table) === alias);
|
|
13132
13197
|
}
|
|
13133
13198
|
function physicalSelectTables(stmt) {
|
|
13134
13199
|
return [stmt.from, ...stmt.joins.map((join2) => join2.table)].filter((table) => table.cteName === null);
|
|
@@ -13280,7 +13345,7 @@ async function loadAggregateSortKindResolver(stmt, client, cacheContext, materia
|
|
|
13280
13345
|
if (ref.tableAlias === "_p" && stmt.from.subtableCode && stmt.from.cteName === null) {
|
|
13281
13346
|
info = fieldInfosByApp.get(stmt.from.appId)?.get(ref.field);
|
|
13282
13347
|
} else {
|
|
13283
|
-
const table = tables.find((candidate) => candidate
|
|
13348
|
+
const table = tables.find((candidate) => effectiveTableAlias(candidate) === ref.tableAlias);
|
|
13284
13349
|
if (!table) return void 0;
|
|
13285
13350
|
if (table.cteName !== null) {
|
|
13286
13351
|
return materializedTables?.get(table.cteName)?.columnMeta?.get(ref.field)?.semantics ?? syntheticSemantics("string");
|
|
@@ -13305,7 +13370,7 @@ async function loadAggregateSortKindResolver(stmt, client, cacheContext, materia
|
|
|
13305
13370
|
return matches[0];
|
|
13306
13371
|
}
|
|
13307
13372
|
if (!info) return void 0;
|
|
13308
|
-
const sourceTable = ref.tableAlias !== null ? tables.find((table) => table
|
|
13373
|
+
const sourceTable = ref.tableAlias !== null ? tables.find((table) => effectiveTableAlias(table) === ref.tableAlias) : stmt.joins.length === 0 ? stmt.from : void 0;
|
|
13309
13374
|
return semanticsForInfo(info, sourceTable?.appId ?? stmt.from.appId);
|
|
13310
13375
|
};
|
|
13311
13376
|
}
|
|
@@ -13435,7 +13500,7 @@ async function inferSelectColumnMeta(stmt, outputColumns, client, cacheContext,
|
|
|
13435
13500
|
const info2 = physicalInfos.get(stmt.from.appId)?.get(ref.field);
|
|
13436
13501
|
return info2 ? materializedMetaFromFieldInfo(info2, stmt.from.appId) : void 0;
|
|
13437
13502
|
}
|
|
13438
|
-
const table = tables.find((candidate) => candidate
|
|
13503
|
+
const table = tables.find((candidate) => effectiveTableAlias(candidate) === ref.tableAlias);
|
|
13439
13504
|
if (!table) return void 0;
|
|
13440
13505
|
if (table.cteName !== null) return materializedTables?.get(table.cteName)?.columnMeta?.get(ref.field);
|
|
13441
13506
|
const info = physicalInfos.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
|
|
@@ -13540,7 +13605,7 @@ function buildSelectFieldTypeResolvers(stmt, fieldTypesByApp) {
|
|
|
13540
13605
|
if (field.tableAlias === "_p" && stmt.from.subtableCode && stmt.from.cteName === null) {
|
|
13541
13606
|
return fieldTypesByApp.get(stmt.from.appId)?.get(field.field);
|
|
13542
13607
|
}
|
|
13543
|
-
const table = tables.find((candidate) => candidate
|
|
13608
|
+
const table = tables.find((candidate) => effectiveTableAlias(candidate) === field.tableAlias);
|
|
13544
13609
|
if (!table || table.cteName !== null) return void 0;
|
|
13545
13610
|
return subtableSystemFieldType(table, field.field) ?? fieldTypesByApp.get(table.appId)?.get(fieldCodeForTypeLookup(table, field.field));
|
|
13546
13611
|
}
|
|
@@ -13765,6 +13830,37 @@ async function executeQueryWithCte(query, client, options, cteCache, cacheContex
|
|
|
13765
13830
|
return result;
|
|
13766
13831
|
}
|
|
13767
13832
|
async function executeFullScanWithCte(stmt, client, options, cteCache, cacheContext) {
|
|
13833
|
+
const hiddenQualifiedAliases = /* @__PURE__ */ new Set();
|
|
13834
|
+
const withEffectiveAlias = (table) => {
|
|
13835
|
+
if (table.alias !== null || table.cteName === null) return table;
|
|
13836
|
+
const alias = effectiveTableAlias(table);
|
|
13837
|
+
hiddenQualifiedAliases.add(alias);
|
|
13838
|
+
return { ...table, alias };
|
|
13839
|
+
};
|
|
13840
|
+
stmt = {
|
|
13841
|
+
...stmt,
|
|
13842
|
+
from: withEffectiveAlias(stmt.from),
|
|
13843
|
+
joins: stmt.joins.map((join2) => ({ ...join2, table: withEffectiveAlias(join2.table) }))
|
|
13844
|
+
};
|
|
13845
|
+
const aliases = /* @__PURE__ */ new Set();
|
|
13846
|
+
for (const table of [stmt.from, ...stmt.joins.map((join2) => join2.table)]) {
|
|
13847
|
+
const alias = effectiveTableAlias(table);
|
|
13848
|
+
if (alias === null) continue;
|
|
13849
|
+
if (aliases.has(alias)) {
|
|
13850
|
+
throw new Error(`ArgumentError: effective alias ${alias} is used by multiple tables.`);
|
|
13851
|
+
}
|
|
13852
|
+
aliases.add(alias);
|
|
13853
|
+
}
|
|
13854
|
+
const requireMaterializedTable = (name) => {
|
|
13855
|
+
const table = cteCache.get(name);
|
|
13856
|
+
if (!table) {
|
|
13857
|
+
throw new Error(`ArgumentError: materialized source ${name} is not available.`);
|
|
13858
|
+
}
|
|
13859
|
+
return table;
|
|
13860
|
+
};
|
|
13861
|
+
for (const table of [stmt.from, ...stmt.joins.map((join2) => join2.table)]) {
|
|
13862
|
+
if (table.cteName !== null) requireMaterializedTable(table.cteName);
|
|
13863
|
+
}
|
|
13768
13864
|
const maxRecords = options.maxRecords ?? 1e4;
|
|
13769
13865
|
const warnings = /* @__PURE__ */ new Set();
|
|
13770
13866
|
const parallel = options.fetchParallel ?? 1;
|
|
@@ -13811,9 +13907,11 @@ async function executeFullScanWithCte(stmt, client, options, cteCache, cacheCont
|
|
|
13811
13907
|
orderByMetaPromise.catch(() => {
|
|
13812
13908
|
});
|
|
13813
13909
|
const tables = /* @__PURE__ */ new Map();
|
|
13910
|
+
const tableColumns = /* @__PURE__ */ new Map();
|
|
13814
13911
|
if (stmt.from.cteName != null) {
|
|
13815
|
-
const table =
|
|
13816
|
-
tables.set(stmt.from.alias,
|
|
13912
|
+
const table = requireMaterializedTable(stmt.from.cteName);
|
|
13913
|
+
tables.set(stmt.from.alias, table.rows.map(processRowToKintoneRecord));
|
|
13914
|
+
tableColumns.set(stmt.from.alias, table.columns);
|
|
13817
13915
|
} else {
|
|
13818
13916
|
const mainRecords = await fetchTableRecordsForFullScan(
|
|
13819
13917
|
stmt,
|
|
@@ -13831,8 +13929,9 @@ async function executeFullScanWithCte(stmt, client, options, cteCache, cacheCont
|
|
|
13831
13929
|
}
|
|
13832
13930
|
const joinFetches = stmt.joins.map(async (join2) => {
|
|
13833
13931
|
if (join2.table.cteName != null) {
|
|
13834
|
-
const table =
|
|
13835
|
-
tables.set(join2.table.alias,
|
|
13932
|
+
const table = requireMaterializedTable(join2.table.cteName);
|
|
13933
|
+
tables.set(join2.table.alias, table.rows.map(processRowToKintoneRecord));
|
|
13934
|
+
tableColumns.set(join2.table.alias, table.columns);
|
|
13836
13935
|
} else {
|
|
13837
13936
|
const pushDownCond = join2.table.alias ? pushdownPlan.joinConditions.get(join2.table.alias) ?? null : null;
|
|
13838
13937
|
const optimized = await tryFetchJoinRecordsBySourceKeys(
|
|
@@ -13863,7 +13962,7 @@ async function executeFullScanWithCte(stmt, client, options, cteCache, cacheCont
|
|
|
13863
13962
|
await Promise.all(joinFetches);
|
|
13864
13963
|
const scalarCache = await scalarCachePromise;
|
|
13865
13964
|
const { optionOrders, sortKinds, semantics } = await orderByMetaPromise;
|
|
13866
|
-
const sourceColumns = stmt.joins.length === 0 && stmt.from.cteName != null ?
|
|
13965
|
+
const sourceColumns = stmt.joins.length === 0 && stmt.from.cteName != null ? requireMaterializedTable(stmt.from.cteName).columns : void 0;
|
|
13867
13966
|
const { rows, columns } = runFullScan({
|
|
13868
13967
|
tables,
|
|
13869
13968
|
stmt,
|
|
@@ -13877,7 +13976,9 @@ async function executeFullScanWithCte(stmt, client, options, cteCache, cacheCont
|
|
|
13877
13976
|
havingFieldSemanticsResolver,
|
|
13878
13977
|
aggregateSortKindResolver,
|
|
13879
13978
|
appliedKlikes: pushdownPlan.appliedKlikes,
|
|
13880
|
-
sourceColumns
|
|
13979
|
+
sourceColumns,
|
|
13980
|
+
tableColumns,
|
|
13981
|
+
hiddenQualifiedAliases
|
|
13881
13982
|
});
|
|
13882
13983
|
return { type: "SELECT", rows, columns, rowCount: rows.length, warnings: [...warnings] };
|
|
13883
13984
|
}
|
|
@@ -14179,7 +14280,7 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
|
|
|
14179
14280
|
const info2 = infosByApp.get(stmt.from.appId)?.get(ref.field);
|
|
14180
14281
|
return info2 ? materializedMetaFromFieldInfo(info2, stmt.from.appId) : void 0;
|
|
14181
14282
|
}
|
|
14182
|
-
const table = tables.find((candidate) => candidate
|
|
14283
|
+
const table = tables.find((candidate) => effectiveTableAlias(candidate) === ref.tableAlias);
|
|
14183
14284
|
if (!table) return void 0;
|
|
14184
14285
|
if (table.cteName !== null) return materializedTables?.get(table.cteName)?.columnMeta?.get(ref.field);
|
|
14185
14286
|
const info = infosByApp.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
|
package/dist-mcp/ksql-mcp.js
CHANGED
|
@@ -36603,6 +36603,9 @@ function canInlineSingleCte(stmt) {
|
|
|
36603
36603
|
if (stmt.ctes.length !== 1) return false;
|
|
36604
36604
|
const cteDef = stmt.ctes[0];
|
|
36605
36605
|
if (cteDef.query.type !== "SELECT" || resolveSelectMode(cteDef.query) !== "SIMPLE") return false;
|
|
36606
|
+
if (!cteDef.query.columns.every(
|
|
36607
|
+
(column) => column.type === "WILDCARD" || column.type === "FIELD" && (column.alias === null || column.alias === column.field)
|
|
36608
|
+
)) return false;
|
|
36606
36609
|
const finalQuery = stmt.query;
|
|
36607
36610
|
if (finalQuery.type !== "SELECT") return false;
|
|
36608
36611
|
if (finalQuery.from.cteName !== cteDef.name || finalQuery.joins.length > 0) return false;
|
|
@@ -41433,10 +41436,12 @@ function flatten(record2, alias) {
|
|
|
41433
41436
|
}
|
|
41434
41437
|
return row;
|
|
41435
41438
|
}
|
|
41436
|
-
function applyJoin(leftRows, rightRows, join) {
|
|
41439
|
+
function applyJoin(leftRows, rightRows, join, columns = {}) {
|
|
41437
41440
|
const { on, type: joinType } = join;
|
|
41438
41441
|
const leftKey = on.left.tableAlias ? `${on.left.tableAlias}.${on.left.field}` : on.left.field;
|
|
41439
41442
|
const rightKey = on.right.tableAlias ? `${on.right.tableAlias}.${on.right.field}` : on.right.field;
|
|
41443
|
+
assertJoinKeyAvailable(leftRows, leftKey, columns.leftColumns);
|
|
41444
|
+
assertJoinKeyAvailable(rightRows, rightKey, columns.rightColumns);
|
|
41440
41445
|
if (joinType === "RIGHT") {
|
|
41441
41446
|
const leftIndex = /* @__PURE__ */ new Map();
|
|
41442
41447
|
for (const lRow of leftRows) {
|
|
@@ -41446,7 +41451,7 @@ function applyJoin(leftRows, rightRows, join) {
|
|
|
41446
41451
|
else leftIndex.set(k, [lRow]);
|
|
41447
41452
|
}
|
|
41448
41453
|
const emptyLeft = {};
|
|
41449
|
-
for (const key of Object.keys(leftRows[0] ?? {})) emptyLeft[key] = "";
|
|
41454
|
+
for (const key of columns.leftColumns ?? Object.keys(leftRows[0] ?? {})) emptyLeft[key] = "";
|
|
41450
41455
|
const result2 = [];
|
|
41451
41456
|
for (const rRow of rightRows) {
|
|
41452
41457
|
const k = rRow[rightKey] ?? "";
|
|
@@ -41468,7 +41473,7 @@ function applyJoin(leftRows, rightRows, join) {
|
|
|
41468
41473
|
}
|
|
41469
41474
|
const result = [];
|
|
41470
41475
|
const emptyRight = {};
|
|
41471
|
-
for (const key of Object.keys(rightRows[0] ?? {})) emptyRight[key] = "";
|
|
41476
|
+
for (const key of columns.rightColumns ?? Object.keys(rightRows[0] ?? {})) emptyRight[key] = "";
|
|
41472
41477
|
for (const lRow of leftRows) {
|
|
41473
41478
|
const k = lRow[leftKey] ?? "";
|
|
41474
41479
|
const matched = rightIndex.get(k) ?? [];
|
|
@@ -41482,6 +41487,12 @@ function applyJoin(leftRows, rightRows, join) {
|
|
|
41482
41487
|
}
|
|
41483
41488
|
return result;
|
|
41484
41489
|
}
|
|
41490
|
+
function assertJoinKeyAvailable(rows, key, savedColumns) {
|
|
41491
|
+
const missing = rows.length > 0 ? rows.some((row) => !Object.prototype.hasOwnProperty.call(row, key)) : savedColumns !== void 0 && !savedColumns.includes(key);
|
|
41492
|
+
if (missing) {
|
|
41493
|
+
throw new Error(`ArgumentError: JOIN key ${key} is not available in the materialized table.`);
|
|
41494
|
+
}
|
|
41495
|
+
}
|
|
41485
41496
|
function applyFilter(rows, where, resolveFieldType, appliedKlikes, resolveFieldSemantics2) {
|
|
41486
41497
|
if (where === null) return rows;
|
|
41487
41498
|
return rows.filter((row) => evalWhere(where, row, resolveFieldType, appliedKlikes, resolveFieldSemantics2));
|
|
@@ -41780,9 +41791,12 @@ function applyLimit(rows, limit, offset) {
|
|
|
41780
41791
|
if (limit === null) return rows.slice(start);
|
|
41781
41792
|
return rows.slice(start, start + limit);
|
|
41782
41793
|
}
|
|
41783
|
-
function project(rows, columns, scalarCache, resolveFieldType, sourceColumns, resolveFieldSemantics2) {
|
|
41794
|
+
function project(rows, columns, scalarCache, resolveFieldType, sourceColumns, resolveFieldSemantics2, hiddenQualifiedAliases) {
|
|
41784
41795
|
if (columns.length === 1 && columns[0].type === "WILDCARD") {
|
|
41785
|
-
const projected2 = rows.map((row) =>
|
|
41796
|
+
const projected2 = rows.map((row) => stripHiddenQualifiedColumns(
|
|
41797
|
+
stripParentShortcutColumns(row),
|
|
41798
|
+
hiddenQualifiedAliases
|
|
41799
|
+
));
|
|
41786
41800
|
const cols = projected2.length > 0 ? Object.keys(projected2[0]) : [...sourceColumns ?? []];
|
|
41787
41801
|
return { rows: projected2, columns: cols };
|
|
41788
41802
|
}
|
|
@@ -41802,7 +41816,10 @@ function project(rows, columns, scalarCache, resolveFieldType, sourceColumns, re
|
|
|
41802
41816
|
case "VARIABLE_COL":
|
|
41803
41817
|
throw new Error(`internal error: unresolved SELECT variable @${col.name}`);
|
|
41804
41818
|
case "WILDCARD":
|
|
41805
|
-
Object.assign(out,
|
|
41819
|
+
Object.assign(out, stripHiddenQualifiedColumns(
|
|
41820
|
+
stripParentShortcutColumns(row),
|
|
41821
|
+
hiddenQualifiedAliases
|
|
41822
|
+
));
|
|
41806
41823
|
break;
|
|
41807
41824
|
case "PARENT_WILDCARD": {
|
|
41808
41825
|
const parentKeys = Object.keys(row).filter((k) => k.startsWith("_p.")).sort();
|
|
@@ -42055,6 +42072,27 @@ function resolveAggInStringFuncExpr(expr, rows, resolveAggSortKind) {
|
|
|
42055
42072
|
args: expr.args.map((arg) => resolveAggInStringFuncArg(arg, rows, resolveAggSortKind))
|
|
42056
42073
|
};
|
|
42057
42074
|
}
|
|
42075
|
+
function stripHiddenQualifiedColumns(row, hiddenQualifiedAliases) {
|
|
42076
|
+
if (!hiddenQualifiedAliases || hiddenQualifiedAliases.size === 0) return row;
|
|
42077
|
+
const out = {};
|
|
42078
|
+
for (const [key, value] of Object.entries(row)) {
|
|
42079
|
+
if ([...hiddenQualifiedAliases].some((alias) => key.startsWith(`${alias}.`))) continue;
|
|
42080
|
+
out[key] = value;
|
|
42081
|
+
}
|
|
42082
|
+
return out;
|
|
42083
|
+
}
|
|
42084
|
+
function flattenedColumns(columns, alias) {
|
|
42085
|
+
if (columns === void 0) return void 0;
|
|
42086
|
+
return alias ? columns.flatMap((column) => [`${alias}.${column}`, column]) : [...columns];
|
|
42087
|
+
}
|
|
42088
|
+
function mergeKnownColumns(left, right, rows) {
|
|
42089
|
+
if (left === void 0 && right === void 0 && rows.length === 0) return void 0;
|
|
42090
|
+
return [.../* @__PURE__ */ new Set([
|
|
42091
|
+
...left ?? [],
|
|
42092
|
+
...right ?? [],
|
|
42093
|
+
...Object.keys(rows[0] ?? {})
|
|
42094
|
+
])];
|
|
42095
|
+
}
|
|
42058
42096
|
function deriveOutputOrderSemantics(columns) {
|
|
42059
42097
|
const result = /* @__PURE__ */ new Map();
|
|
42060
42098
|
for (const column of columns) {
|
|
@@ -42089,7 +42127,9 @@ function runFullScan(input) {
|
|
|
42089
42127
|
havingFieldSemanticsResolver,
|
|
42090
42128
|
aggregateSortKindResolver,
|
|
42091
42129
|
appliedKlikes,
|
|
42092
|
-
sourceColumns
|
|
42130
|
+
sourceColumns,
|
|
42131
|
+
tableColumns,
|
|
42132
|
+
hiddenQualifiedAliases
|
|
42093
42133
|
} = input;
|
|
42094
42134
|
const effectiveOrderSemantics = deriveOutputOrderSemantics(stmt.columns);
|
|
42095
42135
|
for (const [key, value] of orderSemantics ?? []) effectiveOrderSemantics.set(key, value);
|
|
@@ -42097,11 +42137,25 @@ function runFullScan(input) {
|
|
|
42097
42137
|
const mainAlias = stmt.from.alias;
|
|
42098
42138
|
const mainRecords = tables.get(mainAlias) ?? tables.get(null) ?? [];
|
|
42099
42139
|
rows = mainRecords.map((r) => flatten(r, mainAlias));
|
|
42140
|
+
let knownColumns = mergeKnownColumns(
|
|
42141
|
+
flattenedColumns(tableColumns?.get(mainAlias), mainAlias),
|
|
42142
|
+
void 0,
|
|
42143
|
+
rows
|
|
42144
|
+
);
|
|
42100
42145
|
for (const join of stmt.joins) {
|
|
42101
42146
|
const rightAlias = join.table.alias;
|
|
42102
42147
|
const rightRecords = tables.get(rightAlias) ?? [];
|
|
42103
42148
|
const rightRows = rightRecords.map((r) => flatten(r, rightAlias));
|
|
42104
|
-
|
|
42149
|
+
const rightColumns = mergeKnownColumns(
|
|
42150
|
+
flattenedColumns(tableColumns?.get(rightAlias), rightAlias),
|
|
42151
|
+
void 0,
|
|
42152
|
+
rightRows
|
|
42153
|
+
);
|
|
42154
|
+
rows = applyJoin(rows, rightRows, join, {
|
|
42155
|
+
leftColumns: knownColumns,
|
|
42156
|
+
rightColumns
|
|
42157
|
+
});
|
|
42158
|
+
knownColumns = mergeKnownColumns(knownColumns, rightColumns, rows);
|
|
42105
42159
|
}
|
|
42106
42160
|
rows = applyFilter(rows, stmt.where, fieldTypeResolver, appliedKlikes, fieldSemanticsResolver);
|
|
42107
42161
|
if (stmt.groupBy.length > 0 || hasAggregateColumns(stmt.columns)) {
|
|
@@ -42114,7 +42168,15 @@ function runFullScan(input) {
|
|
|
42114
42168
|
}
|
|
42115
42169
|
rows = applyOrderBy(rows, stmt.orderBy, optionOrders, sortKinds, effectiveOrderSemantics);
|
|
42116
42170
|
rows = applyLimit(rows, stmt.limit, stmt.offset);
|
|
42117
|
-
return project(
|
|
42171
|
+
return project(
|
|
42172
|
+
rows,
|
|
42173
|
+
stmt.columns,
|
|
42174
|
+
scalarCache,
|
|
42175
|
+
fieldTypeResolver,
|
|
42176
|
+
sourceColumns,
|
|
42177
|
+
fieldSemanticsResolver,
|
|
42178
|
+
hiddenQualifiedAliases
|
|
42179
|
+
);
|
|
42118
42180
|
}
|
|
42119
42181
|
|
|
42120
42182
|
// src/converter/subtableAdapter.ts
|
|
@@ -44450,7 +44512,7 @@ async function buildWhereFieldSemanticsResolver(stmt, client, cacheContext, mate
|
|
|
44450
44512
|
if (field.tableAlias === "_p" && stmt.from.subtableCode && stmt.from.cteName === null) {
|
|
44451
44513
|
return fromPhysical(stmt.from, field.field, false);
|
|
44452
44514
|
}
|
|
44453
|
-
const table = tables.find((candidate) => candidate
|
|
44515
|
+
const table = tables.find((candidate) => effectiveTableAlias(candidate) === field.tableAlias);
|
|
44454
44516
|
if (!table) return void 0;
|
|
44455
44517
|
if (table.cteName !== null) {
|
|
44456
44518
|
return materializedTables?.get(table.cteName)?.columnMeta?.get(field.field)?.semantics ?? syntheticSemantics("string");
|
|
@@ -44884,8 +44946,11 @@ function collectSelectTypedInFieldRefs(stmt) {
|
|
|
44884
44946
|
}
|
|
44885
44947
|
return refs;
|
|
44886
44948
|
}
|
|
44949
|
+
function effectiveTableAlias(table) {
|
|
44950
|
+
return table.alias ?? table.cteName;
|
|
44951
|
+
}
|
|
44887
44952
|
function findTableForAlias(stmt, alias) {
|
|
44888
|
-
return [stmt.from, ...stmt.joins.map((join) => join.table)].find((table) => table
|
|
44953
|
+
return [stmt.from, ...stmt.joins.map((join) => join.table)].find((table) => effectiveTableAlias(table) === alias);
|
|
44889
44954
|
}
|
|
44890
44955
|
function physicalSelectTables(stmt) {
|
|
44891
44956
|
return [stmt.from, ...stmt.joins.map((join) => join.table)].filter((table) => table.cteName === null);
|
|
@@ -45037,7 +45102,7 @@ async function loadAggregateSortKindResolver(stmt, client, cacheContext, materia
|
|
|
45037
45102
|
if (ref.tableAlias === "_p" && stmt.from.subtableCode && stmt.from.cteName === null) {
|
|
45038
45103
|
info = fieldInfosByApp.get(stmt.from.appId)?.get(ref.field);
|
|
45039
45104
|
} else {
|
|
45040
|
-
const table = tables.find((candidate) => candidate
|
|
45105
|
+
const table = tables.find((candidate) => effectiveTableAlias(candidate) === ref.tableAlias);
|
|
45041
45106
|
if (!table) return void 0;
|
|
45042
45107
|
if (table.cteName !== null) {
|
|
45043
45108
|
return materializedTables?.get(table.cteName)?.columnMeta?.get(ref.field)?.semantics ?? syntheticSemantics("string");
|
|
@@ -45062,7 +45127,7 @@ async function loadAggregateSortKindResolver(stmt, client, cacheContext, materia
|
|
|
45062
45127
|
return matches[0];
|
|
45063
45128
|
}
|
|
45064
45129
|
if (!info) return void 0;
|
|
45065
|
-
const sourceTable = ref.tableAlias !== null ? tables.find((table) => table
|
|
45130
|
+
const sourceTable = ref.tableAlias !== null ? tables.find((table) => effectiveTableAlias(table) === ref.tableAlias) : stmt.joins.length === 0 ? stmt.from : void 0;
|
|
45066
45131
|
return semanticsForInfo(info, sourceTable?.appId ?? stmt.from.appId);
|
|
45067
45132
|
};
|
|
45068
45133
|
}
|
|
@@ -45192,7 +45257,7 @@ async function inferSelectColumnMeta(stmt, outputColumns, client, cacheContext,
|
|
|
45192
45257
|
const info2 = physicalInfos.get(stmt.from.appId)?.get(ref.field);
|
|
45193
45258
|
return info2 ? materializedMetaFromFieldInfo(info2, stmt.from.appId) : void 0;
|
|
45194
45259
|
}
|
|
45195
|
-
const table = tables.find((candidate) => candidate
|
|
45260
|
+
const table = tables.find((candidate) => effectiveTableAlias(candidate) === ref.tableAlias);
|
|
45196
45261
|
if (!table) return void 0;
|
|
45197
45262
|
if (table.cteName !== null) return materializedTables?.get(table.cteName)?.columnMeta?.get(ref.field);
|
|
45198
45263
|
const info = physicalInfos.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
|
|
@@ -45297,7 +45362,7 @@ function buildSelectFieldTypeResolvers(stmt, fieldTypesByApp) {
|
|
|
45297
45362
|
if (field.tableAlias === "_p" && stmt.from.subtableCode && stmt.from.cteName === null) {
|
|
45298
45363
|
return fieldTypesByApp.get(stmt.from.appId)?.get(field.field);
|
|
45299
45364
|
}
|
|
45300
|
-
const table = tables.find((candidate) => candidate
|
|
45365
|
+
const table = tables.find((candidate) => effectiveTableAlias(candidate) === field.tableAlias);
|
|
45301
45366
|
if (!table || table.cteName !== null) return void 0;
|
|
45302
45367
|
return subtableSystemFieldType(table, field.field) ?? fieldTypesByApp.get(table.appId)?.get(fieldCodeForTypeLookup(table, field.field));
|
|
45303
45368
|
}
|
|
@@ -45522,6 +45587,37 @@ async function executeQueryWithCte(query, client, options, cteCache, cacheContex
|
|
|
45522
45587
|
return result;
|
|
45523
45588
|
}
|
|
45524
45589
|
async function executeFullScanWithCte(stmt, client, options, cteCache, cacheContext) {
|
|
45590
|
+
const hiddenQualifiedAliases = /* @__PURE__ */ new Set();
|
|
45591
|
+
const withEffectiveAlias = (table) => {
|
|
45592
|
+
if (table.alias !== null || table.cteName === null) return table;
|
|
45593
|
+
const alias = effectiveTableAlias(table);
|
|
45594
|
+
hiddenQualifiedAliases.add(alias);
|
|
45595
|
+
return { ...table, alias };
|
|
45596
|
+
};
|
|
45597
|
+
stmt = {
|
|
45598
|
+
...stmt,
|
|
45599
|
+
from: withEffectiveAlias(stmt.from),
|
|
45600
|
+
joins: stmt.joins.map((join) => ({ ...join, table: withEffectiveAlias(join.table) }))
|
|
45601
|
+
};
|
|
45602
|
+
const aliases = /* @__PURE__ */ new Set();
|
|
45603
|
+
for (const table of [stmt.from, ...stmt.joins.map((join) => join.table)]) {
|
|
45604
|
+
const alias = effectiveTableAlias(table);
|
|
45605
|
+
if (alias === null) continue;
|
|
45606
|
+
if (aliases.has(alias)) {
|
|
45607
|
+
throw new Error(`ArgumentError: effective alias ${alias} is used by multiple tables.`);
|
|
45608
|
+
}
|
|
45609
|
+
aliases.add(alias);
|
|
45610
|
+
}
|
|
45611
|
+
const requireMaterializedTable = (name) => {
|
|
45612
|
+
const table = cteCache.get(name);
|
|
45613
|
+
if (!table) {
|
|
45614
|
+
throw new Error(`ArgumentError: materialized source ${name} is not available.`);
|
|
45615
|
+
}
|
|
45616
|
+
return table;
|
|
45617
|
+
};
|
|
45618
|
+
for (const table of [stmt.from, ...stmt.joins.map((join) => join.table)]) {
|
|
45619
|
+
if (table.cteName !== null) requireMaterializedTable(table.cteName);
|
|
45620
|
+
}
|
|
45525
45621
|
const maxRecords2 = options.maxRecords ?? 1e4;
|
|
45526
45622
|
const warnings = /* @__PURE__ */ new Set();
|
|
45527
45623
|
const parallel = options.fetchParallel ?? 1;
|
|
@@ -45568,9 +45664,11 @@ async function executeFullScanWithCte(stmt, client, options, cteCache, cacheCont
|
|
|
45568
45664
|
orderByMetaPromise.catch(() => {
|
|
45569
45665
|
});
|
|
45570
45666
|
const tables = /* @__PURE__ */ new Map();
|
|
45667
|
+
const tableColumns = /* @__PURE__ */ new Map();
|
|
45571
45668
|
if (stmt.from.cteName != null) {
|
|
45572
|
-
const table =
|
|
45573
|
-
tables.set(stmt.from.alias,
|
|
45669
|
+
const table = requireMaterializedTable(stmt.from.cteName);
|
|
45670
|
+
tables.set(stmt.from.alias, table.rows.map(processRowToKintoneRecord));
|
|
45671
|
+
tableColumns.set(stmt.from.alias, table.columns);
|
|
45574
45672
|
} else {
|
|
45575
45673
|
const mainRecords = await fetchTableRecordsForFullScan(
|
|
45576
45674
|
stmt,
|
|
@@ -45588,8 +45686,9 @@ async function executeFullScanWithCte(stmt, client, options, cteCache, cacheCont
|
|
|
45588
45686
|
}
|
|
45589
45687
|
const joinFetches = stmt.joins.map(async (join) => {
|
|
45590
45688
|
if (join.table.cteName != null) {
|
|
45591
|
-
const table =
|
|
45592
|
-
tables.set(join.table.alias,
|
|
45689
|
+
const table = requireMaterializedTable(join.table.cteName);
|
|
45690
|
+
tables.set(join.table.alias, table.rows.map(processRowToKintoneRecord));
|
|
45691
|
+
tableColumns.set(join.table.alias, table.columns);
|
|
45593
45692
|
} else {
|
|
45594
45693
|
const pushDownCond = join.table.alias ? pushdownPlan.joinConditions.get(join.table.alias) ?? null : null;
|
|
45595
45694
|
const optimized = await tryFetchJoinRecordsBySourceKeys(
|
|
@@ -45620,7 +45719,7 @@ async function executeFullScanWithCte(stmt, client, options, cteCache, cacheCont
|
|
|
45620
45719
|
await Promise.all(joinFetches);
|
|
45621
45720
|
const scalarCache = await scalarCachePromise;
|
|
45622
45721
|
const { optionOrders, sortKinds, semantics } = await orderByMetaPromise;
|
|
45623
|
-
const sourceColumns = stmt.joins.length === 0 && stmt.from.cteName != null ?
|
|
45722
|
+
const sourceColumns = stmt.joins.length === 0 && stmt.from.cteName != null ? requireMaterializedTable(stmt.from.cteName).columns : void 0;
|
|
45624
45723
|
const { rows, columns } = runFullScan({
|
|
45625
45724
|
tables,
|
|
45626
45725
|
stmt,
|
|
@@ -45634,7 +45733,9 @@ async function executeFullScanWithCte(stmt, client, options, cteCache, cacheCont
|
|
|
45634
45733
|
havingFieldSemanticsResolver,
|
|
45635
45734
|
aggregateSortKindResolver,
|
|
45636
45735
|
appliedKlikes: pushdownPlan.appliedKlikes,
|
|
45637
|
-
sourceColumns
|
|
45736
|
+
sourceColumns,
|
|
45737
|
+
tableColumns,
|
|
45738
|
+
hiddenQualifiedAliases
|
|
45638
45739
|
});
|
|
45639
45740
|
return { type: "SELECT", rows, columns, rowCount: rows.length, warnings: [...warnings] };
|
|
45640
45741
|
}
|
|
@@ -45936,7 +46037,7 @@ async function buildOrderSemanticsForSelect(stmt, client, cacheContext, material
|
|
|
45936
46037
|
const info2 = infosByApp.get(stmt.from.appId)?.get(ref.field);
|
|
45937
46038
|
return info2 ? materializedMetaFromFieldInfo(info2, stmt.from.appId) : void 0;
|
|
45938
46039
|
}
|
|
45939
|
-
const table = tables.find((candidate) => candidate
|
|
46040
|
+
const table = tables.find((candidate) => effectiveTableAlias(candidate) === ref.tableAlias);
|
|
45940
46041
|
if (!table) return void 0;
|
|
45941
46042
|
if (table.cteName !== null) return materializedTables?.get(table.cteName)?.columnMeta?.get(ref.field);
|
|
45942
46043
|
const info = infosByApp.get(table.appId)?.get(fieldCodeForTypeLookup(table, ref.field));
|
|
@@ -53200,7 +53301,7 @@ Nested JSON/CSV subtable mutation is fail-closed on MCP: use VALIDATE ONLY/EXPLA
|
|
|
53200
53301
|
JSON child IDs are rejected and replacement renumbers all rows.
|
|
53201
53302
|
`);
|
|
53202
53303
|
}
|
|
53203
|
-
var SERVER_VERSION = true ? "3.
|
|
53304
|
+
var SERVER_VERSION = true ? "3.11.0" : "0.0.0-dev";
|
|
53204
53305
|
var KSQL_MCP_INSTRUCTIONS = `kSQL is a SQL-like dialect for kintone, not generic SQL. It supports SELECT,
|
|
53205
53306
|
JOIN, aggregates, CTEs, UNION, ROW_NUMBER/RANK/DENSE_RANK, GROUP_CONCAT,
|
|
53206
53307
|
INSERT/UPDATE/UPSERT/DELETE, UPDATE ... FROM, subtable virtual tables
|
package/dist-mcpb/ksql-mcp.mcpb
CHANGED
|
Binary file
|