You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 lines
2.7 KiB
JavaScript

"use strict";
const NoChange = require("./util/no-change");
const deriveNode = require("../derive-node");
const operations = require("../operations");
module.exports = {
name: "test-context",
category: [ "testing" ],
visitors: {
columnName: (node, { setState }) => {
setState("seenColumn", node.name);
return NoChange;
},
select: (node, { registerStateHandler, defer }) => {
let seenColumns = new Set();
registerStateHandler("seenColumnsInWhere", (names) => {
for (let name of names) {
seenColumns = seenColumns.add(name);
}
});
// FIXME: Definitely need better AST modification/derivation tools... probably some sort of deep-modifying utility, for starters. Maybe merge-by-template can be of use here? With a custom AST node merger? It probably doesn't support non-enumerable properties correctly right now, though...
return defer(() => {
console.log("Seen columns in WHERE in SELECT:", seenColumns);
let onlyColumnsClause = node.clauses.find((clause) => clause.type === "onlyColumns");
let columnsAlreadyAdded = onlyColumnsClause != null && Array.from(seenColumns).every((column) => {
return onlyColumnsClause.columns.some((existingColumn) => existingColumn.name === column);
});
if (!columnsAlreadyAdded) {
// NOTE: This is a good test case for optimizer stability! Just returning a derived node in every case.
let newOnlyColumnsClause = (onlyColumnsClause == null)
? operations.onlyColumns(Array.from(seenColumns))
: deriveNode(onlyColumnsClause, {
columns: onlyColumnsClause.columns.concat(Array.from(seenColumns).map((columnName) => {
return operations.column(columnName);
}))
});
return deriveNode(node, {
clauses: node.clauses
.filter((clause) => clause.type !== "onlyColumns")
.concat([ newOnlyColumnsClause ])
});
} else {
return NoChange;
}
});
},
where: (node, { registerStateHandler, defer, setState }) => {
let seenColumns = [];
registerStateHandler("seenColumn", (name) => seenColumns.push(name));
return defer(() => {
setState("seenColumnsInWhere", seenColumns);
return NoChange;
});
// let seenColumns = [];
// let id = Math.random();
// registerStateHandler("seenColumn", (name) => {
// seenColumns.push(name);
// });
// console.log("Scheduling defer", id);
// return defer(() => {
// console.log("Defer called", id);
// // MARKER: This gets called twice, but should only be called once!
// // console.log("Seen columns in WHERE:", seenColumns, require("util").inspect(node, {colors:true,depth:null}));
// console.log("Seen columns in WHERE:", seenColumns);
// return NoChange;
// });
}
}
};