sqlparser-devexpress
Version:
SQLParser is a JavaScript library that converts SQL `WHERE` clauses into a structured **Abstract Syntax Tree (AST)** and transforms them into DevExpress filter format. It removes inline parameters while preserving them as dynamic variables for flexible qu
459 lines (447 loc) • 16.9 kB
JavaScript
import { describe, expect, it } from "vitest";
import { convertToDevExpressFormat } from "../src/core/converter";
import { parse } from "../src/core/parser";
import { sanitizeQuery } from "../src/core/sanitizer";
import { convertAstToDevextreme, convertSQLToAst } from "../src";
describe("Parser SQL to dx Filter Builder", () => {
const testCases = [
{
input: "(ID = {CoreEntity0022.CompanyGroupID} OR ISNULL({CoreEntity0022.CompanyGroupID},0) = 0)",
expected: [
// [
"ID", "=", 42
// ],
// "or",
// [42, "=", null],
],
},
{
input: "GroupNo = {Employee.District} OR ISNULL(GroupNo,0) = 0 OR {Employee.District} = 0",
expected: [
// ["GroupNo", "=", 0],
// "or",
// ["GroupNo", "=", null],
// "or",
// [0, "=", 0],
],
},
{
input: "ContactID = {SaleInvoiceDocument.ContactID} AND AddressType IN (2, 4)",
expected: [
["ContactID", "=", 42],
"and",
[["AddressType", "=", 2], 'or', ["AddressType", "=", 4]],
],
},
{
input: "ID IN ({WorkOrderLine.ApplicableUoms}) AND (CompanyID = {WorkOrderDocument.CompanyID} OR {WorkOrderDocument.CompanyID} = 0)",
expected: [
[["ID", "=", "UOM1"], 'or', ["ID", "=", "UOM2"], 'or', ["ID", "=", "UOM3"]],
"and",
// [
["CompanyID", "=", 42],
// "or",
// [42, "=", 0],
// ],
],
},
{
input: "CompanyID = {AccountingRule.CompanyID}",
expected: [
"CompanyID", "=", 42,
],
},
{
input: "(Level > {Area.AreaType})",
expected: [
"Level", ">", 42
]
},
{
input: "(ID <> {Item.ID}) AND (ItemGroupType IN ({Item.AllowedItemGroupType}))",
expected: [
["ID", "<>", 42],
'and',
[["ItemGroupType", "=", "1"], 'or', ["ItemGroupType", "=", "2"]]
]
},
{
input: "((FromDate <= '{TransferOutwardDocument.DocDate}' AND ToDate >= '{TransferOutwardDocument.DocDate}') OR ToDate is NULL) AND (BranchID = {TransferOutwardDocument.RefBranchID} OR RefBranchID is NULL) AND (CompanyID = {TransferOutwardDocument.CompanyID} OR {TransferOutwardDocument.CompanyID} = 0 OR CompanyID is NULL)",
expected: [
[
[
[
["FromDate", "<=", "2022-01-01"],
'and',
["ToDate", ">=", "2022-01-01"]
],
'or',
["ToDate", "=", null, { "type": "IS" }, null]
],
"and",
[
["BranchID", "=", 42],
"or",
["RefBranchID", "=", null, { "type": "IS" }, null]
]
],
"and",
[
["CompanyID", "=", 7],
// "or",
// [7,"=",0],
"or",
["CompanyID", "=", null, { "type": "IS" }, null]
]
]
},
{
input: "(ID <> {Item.ID}) AND ( ItemGroupType = '''')",
expected: [
["ID", "<>", 42],
'and',
["ItemGroupType", "=", ""]
]
},
{
input: "((ISNULL({0}, 0) = 0 AND CompanyID = {1}) OR CompanyID IS NULL) OR BranchID = {0} | [LeadDocument.BranchID] | [LeadDocument.CompanyID]",
expected: [
// [
// [
// [42,"=",null],
// "and",
["CompanyID", "=", 7],
// ],
"or",
["CompanyID", "=", null, { "type": "IS" }, null],
// ],
'or',
["BranchID", "=", 42]
]
},
{
input: "FromDate Between '10-10-2021' AND '10-10-2022'",
expected: [
"FromDate", "between", ["10-10-2021", "10-10-2022"]
]
},
{
input: "BranchID is Null OR BranchID is not 12",
expected: [
["BranchID", "=", null, { "type": "IS" }, null],
"or",
["BranchID", "!=", 12, { "type": "IS NOT" }, 12]
]
},
{
input: "ISNULL(SourceID,0) = {ServiceOrderDocument.SourceID} OR ISNULL(SourceID,0) = 0",
expected: [
["SourceID", "=", 2, { "defaultValue": 0, "position": "column", "type": "ISNULL" }, 2],
"or",
[
["SourceID", "=", 0],
"or",
["SourceID", "=", null, { "defaultValue": 0, "position": "column", "type": "ISNULL" }, null],
"or",
["SourceID", "=", false]
]
]
},
{
input: "(CompanyID = {LeadDocument.CompanyID} OR ISNULL(CompanyID,0) = 0) AND (ISNULL(IsSubdealer,0) = {LeadDocument.AllowSubDealer})",
expected: [
[
["CompanyID", "=", 7],
"or",
[
["CompanyID", "=", 0],
"or",
["CompanyID", "=", null, { "defaultValue": 0, "position": "column", "type": "ISNULL" }, null],
"or",
["CompanyID", "=", false]
]
],
"and",
// [
// ["IsSubdealer", "=", 0],
// "or",
// ["IsSubdealer", "=", null, { "defaultValue": 0, "position": "column", "type": "ISNULL" }, null],
// "or",
["IsSubdealer", "=", true, { "defaultValue": 0, "position": "column", "type": "ISNULL" }, true],
// ]
]
},
{
input: 'AddressType NOT IN (2, 4)',
expected: [
["AddressType", "!=", 2],
"and",
["AddressType", "!=", 4]
]
},
{
input: "AddressType IN ('2', ('4')) OR AddressType =({ServiceOrderDocument .SourceID})",
expected: [
["AddressType", "=", '2'],
"or",
["AddressType", "=", '4'],
"or",
["AddressType", "=", 2]
]
},
{
input: "(ISNULL(TicketID, 0) = ISNULL({SupportResolution.TicketID}, 0))",
expected: [
["TicketID", "=", 123, { "type": "ISNULL", "position": "both", "defaultValue": 0, "defaultValueRight": 0 }, 123],
"or",
["TicketID", "=", null]
]
},
{
input: "CompanyID = ISNULL({LeadDocument.CompanyID},0) OR (ISNULL(CompanyID,0) = 0))",
expected: [
["CompanyID", "=", 7, { "type": "ISNULL", "position": "value", "defaultValue": 0 }, 7],
"or",
[
["CompanyID", "=", 0],
"or",
["CompanyID", "=", null, { "type": "ISNULL", "position": "column", "defaultValue": 0 }, null],
"or",
["CompanyID", "=", false]
]
]
},
{
input: "CompanyName like '{LeadDocument.CompanyID}' AND BranchName not like '{LeadDocument.BranchID}'",
expected: [
["CompanyName", "contains", "7"],
"and",
["BranchName", "notcontains", "42"]
]
},
{
input: "(RS2ID in ({SaleOrderStatusStmtGlobalRpt.StateID}) Or (ISNULL({SaleOrderStatusStmtGlobalRpt.StateID},0) =0)) And (RS3ID in (0,{SaleOrderStatusStmtGlobalRpt.RegionID}) Or ISNULL({SaleOrderStatusStmtGlobalRpt.RegionID},0) =0 )",
expected: []
},
{
input: "ID IN ({WorkOrderLine.CompanyIDs}) AND 0 IN ({WorkOrderLine.CompanyIDs})",
expected: [
["ID", "=", "0"],
"or",
["ID", "=", "1"]
]
},
{
input: "CompanyID is null OR CompanyID is 7 OR CompanyID is not 8",
expected: [
["CompanyID", "=", null, { "type": "IS" }, null],
"or",
["CompanyID", "=", 7, { "type": "IS" }, 7],
"or",
["CompanyID", "!=", 8, { "type": "IS NOT" }, 8]
]
},
{
input: "null = 0",
expected: []
},
{
input: "null = null",
expected: []
},
{
input: "null = {SaleOrderStatusStmtGlobalRpt.StateID}",
expected: []
},
{
input: "null = {SaleOrderStatusStmtGlobalRpt.RegionID}",
expected: []
},
{
input: "null = {LeadDocument.CompanyID}",
expected: []
},
{
input: "{LeadDocument.BranchID} = null",
expected: []
},
{
input: "{LeadDocument.AllowSubDealer} != null",
expected: []
},
{
input: "ID = {SaleOrderStatusStmtGlobalRpt.RegionID}",
expected: []
},
{
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
]
},
{
input: "IsChecked = 1",
expected: [
["IsChecked", "=", 1],
"or",
["IsChecked", "=", true]
]
},
{
input: "ISNULL(CompanyID,0) = ISNULL({TransferOutwardDocument.CompanyID},0) OR (ISNULL(CompanyID,0) = 0)",
expected: [
["CompanyID", "=", 7, { "type": "ISNULL", "position": "both", "defaultValue": 0, "defaultValueRight": 0 }, 7],
"or",
["CompanyID", "=", null],
"or",
["CompanyID", "=", 0],
"or",
["CompanyID", "=", null, { "type": "ISNULL", "position": "column", "defaultValue": 0 }, null],
"or",
["CompanyID", "=", false]
]
},
{
input: "ISNULL(CompanyID,0) = ISNULL({TransferOutwardDocument.CompanyID},0) OR (ISNULL(CompanyID,1) = 0)",
expected: [
["CompanyID", "=", 7, { "type": "ISNULL", "position": "both", "defaultValue": 0, "defaultValueRight": 0 }, 7],
"or",
["CompanyID", "=", null],
"or",
["CompanyID", "=", 0, { "type": "ISNULL", "position": "column", "defaultValue": 1 }, 0],
"or",
["CompanyID", "=", false]
]
},
{
input: "ISNULL(CompanyID,0) = {LeadDocument.CompanyID}",
expected: [
"CompanyID", "=", 7, { "type": "ISNULL", "position": "column", "defaultValue": 0 }, 7
]
},
{
input: "ISNULL(CompanyID,0) = ISNULL({LeadDocument.CompanyID},0)",
expected: [
["CompanyID", "=", 7, { "type": "ISNULL", "position": "both", "defaultValue": 0, "defaultValueRight": 0 }, 7],
"or",
["CompanyID", "=", null]
]
},
{
input: "ISNULL(CompanyID,1) = ISNULL({LeadDocument.CompanyID},2)",
expected: [
"CompanyID", "=", 7, { "type": "ISNULL", "position": "both", "defaultValue": 1, "defaultValueRight": 2 }, 7
]
},
{
input: "CompanyID = ISNULL({LeadDocument.CompanyID},0)",
expected: [
"CompanyID", "=", 7, { "type": "ISNULL", "position": "value", "defaultValue": 0 }, 7
]
},
{
input: "AllowSubDealer = ISNULL({LeadDocument.AllowSubDealer},0)",
expected: [
"AllowSubDealer", "=", true, { "type": "ISNULL", "position": "value", "defaultValue": 0 }, true
]
},
{
input: "AllowSubDealer = ISNULL({LeadDocument.AllowSubDealer},1)",
expected: [
"AllowSubDealer", "=", true, { "type": "ISNULL", "position": "value", "defaultValue": 1 }, true
]
},
{
input: "ISNULL(AllowSubDealer,0) = ISNULL({LeadDocument.AllowSubDealer},1)",
expected: [
"AllowSubDealer", "=", true, { "type": "ISNULL", "position": "both", "defaultValue": 0, "defaultValueRight": 1 }, true
]
},
{
input: "ISNULL(AllowSubDealer,0) = {LeadDocument.AllowSubDealer}",
expected: [
"AllowSubDealer", "=", true, { "type": "ISNULL", "position": "column", "defaultValue": 0 }, true
]
},
{
input: "ISNULL(AllowSubDealer,1) = {LeadDocument.AllowSubDealer}",
expected: [
["AllowSubDealer", "=", true],
'or',
["AllowSubDealer", "=", null, { "type": "ISNULL", "position": "column", "defaultValue": 1 }, null]
]
}
];
testCases.forEach(({ input, expected }, index) => {
it(`Test Case ${index + 1}: ${input}`, () => {
if (expected == undefined) {
expected = null
}
let astwithVariables;
astwithVariables = convertSQLToAst(input);
if (astwithVariables == null) {
expect(null).toEqual(expected);
return;
}
const variables = astwithVariables.variables;
const ast = astwithVariables.ast;
const result = convertAstToDevextreme(ast, sampleData, {
isValueNullShortCircuit: true,
treatNumberAsNullableBit: true
});
if (result == null || result == true || result == false) {
expect([]).toEqual(expected);
return;
}
expect(result).toEqual(expected);
});
});
});
const sampleData = {
"CoreEntity0022.CompanyGroupID": 42,
"CoreEntity0022.BranchID": 7,
"Employee.District": 0,
"Employee.BranchID": 7,
"SaleInvoiceDocument.ContactID": 42,
"SaleInvoiceDocument.BranchID": 7,
"AccountingRule.CompanyID": 42,
"AccountingRule.BranchID": 7,
"Area.AreaType": 42,
"Area.BranchID": 7,
"Item.ID": 42,
"Item.BranchID": 7,
"Item.AllowedItemGroupType": "1,2",
"WorkOrderLine.ApplicableUoms": ["UOM1", "UOM2", "UOM3"],
"WorkOrderLine.CompanyID": 2,
"WorkOrderDocument.CompanyID": 42,
"WorkOrderDocument.BranchID": 7,
"TransferOutwardDocument.DocDate": "2022-01-01",
"TransferOutwardDocument.RefBranchID": 42,
"TransferOutwardDocument.CompanyID": 7,
"LeadDocument.BranchID": 42,
"LeadDocument.CompanyID": 7,
"ServiceOrderDocument.SourceID": 2,
"LeadDocument.AllowSubDealer": true,
"SupportResolution.TicketID": 123,
"SaleOrderStatusStmtGlobalRpt.StateID": null,
"SaleOrderStatusStmtGlobalRpt.RegionID": null,
"WorkOrderLine.CompanyIDs": ["0,1"],
};