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.
75 lines
2.5 KiB
JavaScript
75 lines
2.5 KiB
JavaScript
"use strict";
|
|
|
|
const matchValue = require("match-value");
|
|
|
|
const operations = require("../operations");
|
|
const internalOperations = require("../internal-operations");
|
|
const typeOf = require("../type-of");
|
|
const unreachable = require("../unreachable");
|
|
const NoChange = require("./util/no-change");
|
|
|
|
// FIXME: anyOf(not(placeholder)) should be disallowed, but probably currently is allowed
|
|
// not(anyOf(placeholder)) is fine though
|
|
|
|
let unprocessableTypes = new Set([ "sqlExpression", "placeholder" ]);
|
|
|
|
module.exports = {
|
|
name: "conditions-to-expressions",
|
|
category: [ "normalization" ],
|
|
visitors: {
|
|
expression: (rootNode) => {
|
|
if (rootNode.condition.type === "condition") { // FIXME: typeOf
|
|
return NoChange;
|
|
} else {
|
|
// anyOfConditions, allOfConditions, notCondition
|
|
|
|
function convertNode(node) {
|
|
let listOperation = matchValue.literal(typeOf(node), {
|
|
anyOfConditions: operations.anyOf,
|
|
allOfConditions: operations.allOf,
|
|
notCondition: null,
|
|
condition: null
|
|
});
|
|
|
|
if (listOperation != null) {
|
|
if (Array.isArray(node.items)) {
|
|
return listOperation(node.items.map((item) => convertNode(item)));
|
|
} else if (unprocessableTypes.has(typeOf(node.items))) {
|
|
// Placeholders / unsafe SQL expressions are not representable as a series of expressions, as we don't know the value of them upfront. Therefore we immediately convert it to an internal ANY/ALL expression here, so that it doesn't accidentally get touched by anything else afterwards.
|
|
// FIXME: Check the relevance here of node.items.parameterizable for placeholders
|
|
|
|
return operations.expression({
|
|
left: rootNode.left,
|
|
condition: internalOperations._condition({
|
|
type: "equals",
|
|
expression: internalOperations._arrayOf({
|
|
type: matchValue(typeOf(node), {
|
|
anyOfConditions: "anyOf",
|
|
allOfConditions: "allOf"
|
|
}),
|
|
canBeParameterized: true,
|
|
items: node.items
|
|
})
|
|
})
|
|
});
|
|
} else {
|
|
unreachable("Condition item was not an array");
|
|
}
|
|
} else if (typeOf(node) === "notCondition") {
|
|
return operations.not(convertNode(node.condition));
|
|
} else if (typeOf(node) === "condition") {
|
|
return operations.expression({
|
|
left: rootNode.left,
|
|
condition: node
|
|
});
|
|
} else {
|
|
unreachable(`Encountered node type '${node.type}' within condition modifier`);
|
|
}
|
|
}
|
|
|
|
return convertNode(rootNode.condition);
|
|
}
|
|
}
|
|
}
|
|
};
|