Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "sqlparser-devexpress",
"version": "2.3.17",
"version": "2.3.19",
"main": "src/index.js",
"type": "module",
"scripts": {
"test": "vitest"
"test": "vitest run"
},
"exports": {
"import": "./src/index.js",
Expand Down
4 changes: 2 additions & 2 deletions src/core/converter.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,9 @@ function DevExpressConverter() {
}

const left = ast.left !== undefined ? processAstNode(ast.left) : convertValue(ast.field);
const leftDefault = ast.left?.args[1]?.value;
const leftDefault = ast.left?.args && ast.left?.args[1]?.value;
const right = ast.right !== undefined ? processAstNode(ast.right) : convertValue(ast.value);
const rightDefault = ast.right?.args[1]?.value;
const rightDefault = ast.right?.args && ast.right?.args[1]?.value;
let operatorToken = ast.operator.toLowerCase();
let includeExtradata = false;

Expand Down
26 changes: 26 additions & 0 deletions src/core/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,16 @@ export function parse(input, variables = []) {
// Recursively parse the right-hand expression with adjusted precedence
const right = parseExpression(OPERATOR_PRECEDENCE[operator]);
left = { type: "logical", operator, left, right };
} else if (currentToken?.type == "identifier") {
const right = parseValue(operator);
let newOperator = inverseOperator(operator);

left = {
type: "comparison",
right: left,
operator: newOperator,
left: { type: "field", value: right }
};
}
}

Expand Down Expand Up @@ -218,12 +228,28 @@ export function parse(input, variables = []) {
throw new Error(`Invalid comparison: ${field} ${operator} ${value}`);
}

// Swap the field and value if the field is a placeholder and the value is an identifier
if (valueType == "identifier" && fieldType == "placeholder") {
let newOperator = inverseOperator(operator);
return { type: "comparison", value: field, operator: newOperator, field: value, originalOperator };
}

return { type: "comparison", field, operator, value, originalOperator };
}

return { type: "field", value: field };
}

function inverseOperator(operator) {
switch (operator.toUpperCase()) {
case ">": return "<";
case "<": return ">";
case ">=": return "<=";
case "<=": return ">=";
default: return operator; // Return the operator as is if no inverse is defined
}
}

// Parses values including numbers, strings, placeholders, and IN lists
function parseValue(operatorToken) {
if (!currentToken) throw new Error("Unexpected end of input");
Expand Down
20 changes: 20 additions & 0 deletions tests/parser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,26 @@ describe("Parser SQL to dx Filter Builder", () => {
{
input: "ID IN ({SaleOrderStatusStmtGlobalRpt.RegionID})",
expected: []
},
{
input: "10 < ID AND ApplicableUoms IN ({WorkOrderLine.ApplicableUoms})",
expected: [
["ID", ">", 10],
"and",
[
["ApplicableUoms", "=", "UOM1"],
"or",
["ApplicableUoms", "=", "UOM2"],
"or",
["ApplicableUoms", "=", "UOM3"]
]
],
},
{
input: "{ServiceOrderDocument.SourceID} = ID",
expected: [
"ID", "=", 2
]
}
];

Expand Down