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
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: {
|
|
field: (node, { setState }) => {
|
|
setState("seenField", node.name);
|
|
|
|
return NoChange;
|
|
},
|
|
select: (node, { registerStateHandler, defer }) => {
|
|
let seenFields = new Set();
|
|
|
|
registerStateHandler("seenFieldsInWhere", (names) => {
|
|
for (let name of names) {
|
|
seenFields = seenFields.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 fields in WHERE in SELECT:", seenFields);
|
|
|
|
let onlyFieldsClause = node.clauses.find((clause) => clause.type === "onlyFields");
|
|
|
|
let fieldsAlreadyAdded = onlyFieldsClause != null && Array.from(seenFields).every((field) => {
|
|
return onlyFieldsClause.fields.some((existingField) => existingField.name === field);
|
|
});
|
|
|
|
if (!fieldsAlreadyAdded) {
|
|
// NOTE: This is a good test case for optimizer stability! Just returning a derived node in every case.
|
|
let newOnlyFieldsClause = (onlyFieldsClause == null)
|
|
? operations.onlyFields(Array.from(seenFields))
|
|
: deriveNode(onlyFieldsClause, {
|
|
fields: onlyFieldsClause.fields.concat(Array.from(seenFields).map((fieldName) => {
|
|
return operations.field(fieldName);
|
|
}))
|
|
});
|
|
|
|
return deriveNode(node, {
|
|
clauses: node.clauses
|
|
.filter((clause) => clause.type !== "onlyFields")
|
|
.concat([ newOnlyFieldsClause ])
|
|
});
|
|
} else {
|
|
return NoChange;
|
|
}
|
|
});
|
|
},
|
|
where: (node, { registerStateHandler, defer, setState }) => {
|
|
let seenFields = [];
|
|
|
|
registerStateHandler("seenField", (name) => seenFields.push(name));
|
|
|
|
return defer(() => {
|
|
setState("seenFieldsInWhere", seenFields);
|
|
return NoChange;
|
|
});
|
|
|
|
// let seenFields = [];
|
|
// let id = Math.random();
|
|
|
|
// registerStateHandler("seenField", (name) => {
|
|
// seenFields.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 fields in WHERE:", seenFields, require("util").inspect(node, {colors:true,depth:null}));
|
|
// console.log("Seen fields in WHERE:", seenFields);
|
|
// return NoChange;
|
|
// });
|
|
}
|
|
}
|
|
};
|