From 0bd52db6d68e0dc3aa6efaee4885f2fa71a9b608 Mon Sep 17 00:00:00 2001
From: "github-classroom[bot]"
<66690702+github-classroom[bot]@users.noreply.github.com>
Date: Tue, 23 Apr 2024 05:05:22 +0000
Subject: [PATCH 1/9] Update GitHub Classroom Autograding Workflow
---
.github/workflows/classroom.yml | 223 ++++++++++++++++++++++++++++++--
1 file changed, 212 insertions(+), 11 deletions(-)
diff --git a/.github/workflows/classroom.yml b/.github/workflows/classroom.yml
index dca83b024..8c4fa1b7e 100644
--- a/.github/workflows/classroom.yml
+++ b/.github/workflows/classroom.yml
@@ -1,19 +1,220 @@
-name: GitHub Classroom Workflow
-
-on:
- - push
- - workflow_dispatch
-
+name: Autograding Tests
+'on':
+- push
+- workflow_dispatch
+- repository_dispatch
permissions:
checks: write
actions: read
contents: read
-
jobs:
- build:
- name: Autograding
+ run-autograding-tests:
runs-on: ubuntu-latest
if: github.actor != 'github-classroom[bot]'
steps:
- - uses: actions/checkout@v4
- - uses: education/autograding@v1
+ - name: Checkout code
+ uses: actions/checkout@v4
+ - name: Step-1 Test
+ id: step-1-test
+ uses: education/autograding-command-grader@v1
+ with:
+ test-name: Step-1 Test
+ setup-command: npm install
+ command: npm run test:1
+ timeout: 10
+ max-score: 10
+ - name: Step-2 Test
+ id: step-2-test
+ uses: education/autograding-command-grader@v1
+ with:
+ test-name: Step-2 Test
+ setup-command: npm install
+ command: npm run test:2
+ timeout: 10
+ max-score: 10
+ - name: Step-3 Test
+ id: step-3-test
+ uses: education/autograding-command-grader@v1
+ with:
+ test-name: Step-3 Test
+ setup-command: npm install
+ command: npm run test:3
+ timeout: 10
+ max-score: 10
+ - name: Step-4 Test
+ id: step-4-test
+ uses: education/autograding-command-grader@v1
+ with:
+ test-name: Step-4 Test
+ setup-command: npm install
+ command: npm run test:4
+ timeout: 10
+ - name: Step-5 Test
+ id: step-5-test
+ uses: education/autograding-command-grader@v1
+ with:
+ test-name: Step-5 Test
+ setup-command: npm install
+ command: npm run test:5
+ timeout: 10
+ max-score: 10
+ - name: Step-6 Test
+ id: step-6-test
+ uses: education/autograding-command-grader@v1
+ with:
+ test-name: Step-6 Test
+ setup-command: npm install
+ command: npm run test:6
+ timeout: 10
+ max-score: 10
+ - name: Step-7 Test
+ id: step-7-test
+ uses: education/autograding-command-grader@v1
+ with:
+ test-name: Step-7 Test
+ setup-command: npm install
+ command: npm run test:7
+ timeout: 10
+ max-score: 10
+ - name: Step-8 Test
+ id: step-8-test
+ uses: education/autograding-command-grader@v1
+ with:
+ test-name: Step-8 Test
+ setup-command: npm install
+ command: npm run test:8
+ timeout: 10
+ max-score: 10
+ - name: Step-9 Test
+ id: step-9-test
+ uses: education/autograding-command-grader@v1
+ with:
+ test-name: Step-9 Test
+ setup-command: npm install
+ command: npm run test:9
+ timeout: 10
+ max-score: 10
+ - name: Step-10 Test
+ id: step-10-test
+ uses: education/autograding-command-grader@v1
+ with:
+ test-name: Step-10 Test
+ setup-command: npm install
+ command: npm run test:10
+ timeout: 10
+ max-score: 10
+ - name: Step-11 Test
+ id: step-11-test
+ uses: education/autograding-command-grader@v1
+ with:
+ test-name: Step-11 Test
+ setup-command: npm install
+ command: npm run test:11
+ timeout: 10
+ max-score: 10
+ - name: Step-12 Test
+ id: step-12-test
+ uses: education/autograding-command-grader@v1
+ with:
+ test-name: Step-12 Test
+ setup-command: npm install
+ command: npm run test:12
+ timeout: 10
+ max-score: 10
+ - name: Step-13 Test
+ id: step-13-test
+ uses: education/autograding-command-grader@v1
+ with:
+ test-name: Step-13 Test
+ setup-command: npm install
+ command: npm run test:13
+ timeout: 10
+ max-score: 10
+ - name: Step-14 Test
+ id: step-14-test
+ uses: education/autograding-command-grader@v1
+ with:
+ test-name: Step-14 Test
+ setup-command: npm install
+ command: npm run test:14
+ timeout: 10
+ max-score: 10
+ - name: Step-15 Test
+ id: step-15-test
+ uses: education/autograding-command-grader@v1
+ with:
+ test-name: Step-15 Test
+ setup-command: npm install
+ command: npm run test:15
+ timeout: 10
+ max-score: 10
+ - name: Step-16 Test
+ id: step-16-test
+ uses: education/autograding-command-grader@v1
+ with:
+ test-name: Step-16 Test
+ setup-command: npm install
+ command: npm run test:16
+ timeout: 10
+ max-score: 10
+ - name: Step-17 Test
+ id: step-17-test
+ uses: education/autograding-command-grader@v1
+ with:
+ test-name: Step-17 Test
+ setup-command: npm install
+ command: npm run test:17
+ timeout: 10
+ max-score: 10
+ - name: Step-18 Test
+ id: step-18-test
+ uses: education/autograding-command-grader@v1
+ with:
+ test-name: Step-18 Test
+ setup-command: npm install
+ command: npm run test:18
+ timeout: 10
+ max-score: 10
+ - name: Step-19 Test
+ id: step-19-test
+ uses: education/autograding-command-grader@v1
+ with:
+ test-name: Step-19 Test
+ setup-command: npm install
+ command: npm run test:19
+ timeout: 10
+ max-score: 10
+ - name: Step-20 Test
+ id: step-20-test
+ uses: education/autograding-command-grader@v1
+ with:
+ test-name: Step-20 Test
+ setup-command: npm install
+ command: npm run test:20
+ timeout: 10
+ max-score: 10
+ - name: Autograding Reporter
+ uses: education/autograding-grading-reporter@v1
+ env:
+ STEP-1-TEST_RESULTS: "${{steps.step-1-test.outputs.result}}"
+ STEP-2-TEST_RESULTS: "${{steps.step-2-test.outputs.result}}"
+ STEP-3-TEST_RESULTS: "${{steps.step-3-test.outputs.result}}"
+ STEP-4-TEST_RESULTS: "${{steps.step-4-test.outputs.result}}"
+ STEP-5-TEST_RESULTS: "${{steps.step-5-test.outputs.result}}"
+ STEP-6-TEST_RESULTS: "${{steps.step-6-test.outputs.result}}"
+ STEP-7-TEST_RESULTS: "${{steps.step-7-test.outputs.result}}"
+ STEP-8-TEST_RESULTS: "${{steps.step-8-test.outputs.result}}"
+ STEP-9-TEST_RESULTS: "${{steps.step-9-test.outputs.result}}"
+ STEP-10-TEST_RESULTS: "${{steps.step-10-test.outputs.result}}"
+ STEP-11-TEST_RESULTS: "${{steps.step-11-test.outputs.result}}"
+ STEP-12-TEST_RESULTS: "${{steps.step-12-test.outputs.result}}"
+ STEP-13-TEST_RESULTS: "${{steps.step-13-test.outputs.result}}"
+ STEP-14-TEST_RESULTS: "${{steps.step-14-test.outputs.result}}"
+ STEP-15-TEST_RESULTS: "${{steps.step-15-test.outputs.result}}"
+ STEP-16-TEST_RESULTS: "${{steps.step-16-test.outputs.result}}"
+ STEP-17-TEST_RESULTS: "${{steps.step-17-test.outputs.result}}"
+ STEP-18-TEST_RESULTS: "${{steps.step-18-test.outputs.result}}"
+ STEP-19-TEST_RESULTS: "${{steps.step-19-test.outputs.result}}"
+ STEP-20-TEST_RESULTS: "${{steps.step-20-test.outputs.result}}"
+ with:
+ runners: step-1-test,step-2-test,step-3-test,step-4-test,step-5-test,step-6-test,step-7-test,step-8-test,step-9-test,step-10-test,step-11-test,step-12-test,step-13-test,step-14-test,step-15-test,step-16-test,step-17-test,step-18-test,step-19-test,step-20-test
From f9d8ea6448d8fd24bba671658eae5715f443a96f Mon Sep 17 00:00:00 2001
From: "github-classroom[bot]"
<66690702+github-classroom[bot]@users.noreply.github.com>
Date: Tue, 23 Apr 2024 05:05:22 +0000
Subject: [PATCH 2/9] GitHub Classroom Feedback
---
.github/.keep | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 .github/.keep
diff --git a/.github/.keep b/.github/.keep
new file mode 100644
index 000000000..e69de29bb
From c461e52d438c30fafcc90039fba6afe93ae497ed Mon Sep 17 00:00:00 2001
From: "github-classroom[bot]"
<66690702+github-classroom[bot]@users.noreply.github.com>
Date: Tue, 23 Apr 2024 05:05:22 +0000
Subject: [PATCH 3/9] Setting up GitHub Classroom Feedback
From 795463e2a2549e49367870e4044df88cf63f3cf8 Mon Sep 17 00:00:00 2001
From: "github-classroom[bot]"
<66690702+github-classroom[bot]@users.noreply.github.com>
Date: Tue, 23 Apr 2024 05:05:25 +0000
Subject: [PATCH 4/9] add online IDE url
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index eadfc715a..da2705239 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
+[](https://classroom.github.com/online_ide?assignment_repo_id=14847419&assignment_repo_type=AssignmentRepo)
StylusDB SQL
A SQL database engine written in JavaScript
From 80b5fd746c99097915b50c9bd0b4a76923fe5ce8 Mon Sep 17 00:00:00 2001
From: Rahulsingh1939
Date: Wed, 24 Apr 2024 00:58:14 +0530
Subject: [PATCH 5/9] Completed 6 module
---
src/csvReader.js | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/src/csvReader.js b/src/csvReader.js
index e69de29bb..dc790f6f8 100644
--- a/src/csvReader.js
+++ b/src/csvReader.js
@@ -0,0 +1,20 @@
+const fs = require("fs");
+const csv = require("csv-parser");
+
+function readCSV(filePath) {
+ const results = [];
+
+ return new Promise((resolve, reject) => {
+ fs.createReadStream(filePath)
+ .pipe(csv())
+ .on("data", (data) => results.push(data))
+ .on("end", () => {
+ resolve(results);
+ })
+ .on("error", (error) => {
+ reject(error);
+ });
+ });
+}
+
+module.exports = readCSV;
From c6b61da141346e2c860deff58dd3a779cd3696d5 Mon Sep 17 00:00:00 2001
From: Rahulsingh1939
Date: Wed, 24 Apr 2024 00:58:29 +0530
Subject: [PATCH 6/9] Completed 6 module
---
sample.csv | 4 ++++
src/index.js | 27 +++++++++++++++++++++++++++
src/queryParser.js | 40 ++++++++++++++++++++++++++++++++++++++++
tests/index.test.js | 24 ++++++++++++++++++++++++
4 files changed, 95 insertions(+)
create mode 100644 sample.csv
create mode 100644 src/index.js
create mode 100644 src/queryParser.js
create mode 100644 tests/index.test.js
diff --git a/sample.csv b/sample.csv
new file mode 100644
index 000000000..9e7a9fa25
--- /dev/null
+++ b/sample.csv
@@ -0,0 +1,4 @@
+id,name,age
+1,John,30
+2,Jane,25
+3,Bob,22
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
new file mode 100644
index 000000000..19c94ecff
--- /dev/null
+++ b/src/index.js
@@ -0,0 +1,27 @@
+
+const parseQuery = require('./queryParser');
+const readCSV = require('./csvReader');
+
+async function executeSELECTQuery(query) {
+ const { fields, table, whereClauses } = parseQuery(query);
+ const data = await readCSV(`${table}.csv`);
+
+ // Apply WHERE clause filtering
+ const filteredData = whereClauses.length > 0
+ ? data.filter(row => whereClauses.every(clause => {
+ // You can expand this to handle different operators
+ return row[clause.field] === clause.value;
+ }))
+ : data;
+
+ // Select the specified fields
+ return filteredData.map(row => {
+ const selectedRow = {};
+ fields.forEach(field => {
+ selectedRow[field] = row[field];
+ });
+ return selectedRow;
+ });
+}
+
+module.exports = executeSELECTQuery;
\ No newline at end of file
diff --git a/src/queryParser.js b/src/queryParser.js
new file mode 100644
index 000000000..5633026e5
--- /dev/null
+++ b/src/queryParser.js
@@ -0,0 +1,40 @@
+
+function parseQuery(query) {
+ const selectRegex = /SELECT (.+?) FROM (.+?)(?: WHERE (.*))?$/i;
+ const match = query.match(selectRegex);
+
+ if (match) {
+ const [, fields, table, whereString] = match;
+ const whereClauses = whereString ? parseWhereClause(whereString) : [];
+ return {
+ fields: fields.split(',').map(field => field.trim()),
+ table: table.trim(),
+ whereClauses
+ };
+ } else {
+ throw new Error('Invalid query format');
+ }
+}
+
+function parseWhereClause(whereString) {
+ if (typeof whereString !== 'string') {
+ throw new Error('Input must be a string');
+ }
+
+ const conditions = whereString.split(/ AND | OR /i);
+ const parsedConditions = [];
+
+ for (let condition of conditions) {
+ const parts = condition.trim().split(/\s+/);
+
+ if (parts.length !== 3) {
+ throw new Error('Invalid condition: ' + condition);
+ }
+
+ const [field, operator, value] = parts;
+ parsedConditions.push({ field, operator, value });
+ }
+
+ return parsedConditions;
+}
+module.exports = parseQuery;
\ No newline at end of file
diff --git a/tests/index.test.js b/tests/index.test.js
new file mode 100644
index 000000000..e007bb8fa
--- /dev/null
+++ b/tests/index.test.js
@@ -0,0 +1,24 @@
+test('Parse SQL Query with Multiple WHERE Clauses', () => {
+ const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John';
+ const parsed = parseQuery(query);
+ expect(parsed).toEqual({
+ fields: ['id', 'name'],
+ table: 'sample',
+ whereClauses: [{
+ "field": "age",
+ "operator": "=",
+ "value": "30",
+ }, {
+ "field": "name",
+ "operator": "=",
+ "value": "John",
+ }]
+ });
+});
+
+test('Execute SQL Query with Multiple WHERE Clause', async () => {
+ const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John';
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toEqual({ id: '1', name: 'John' });
+});
\ No newline at end of file
From 36b8cf4175f89b45fa8435ed5d8f34c6a286dd42 Mon Sep 17 00:00:00 2001
From: Rahulsingh1939
Date: Wed, 24 Apr 2024 01:05:31 +0530
Subject: [PATCH 7/9] Completed 7 module
---
src/index.js | 59 ++++++++++++++++++++++------------
src/queryParser.js | 71 +++++++++++++++++++++++------------------
tests/index.test.js | 78 ++++++++++++++++++++++++++++++++-------------
3 files changed, 135 insertions(+), 73 deletions(-)
diff --git a/src/index.js b/src/index.js
index 19c94ecff..af5da6da0 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,27 +1,46 @@
-
-const parseQuery = require('./queryParser');
-const readCSV = require('./csvReader');
+const parseQuery = require("./queryParser");
+const readCSV = require("./csvReader");
async function executeSELECTQuery(query) {
- const { fields, table, whereClauses } = parseQuery(query);
- const data = await readCSV(`${table}.csv`);
+ const { fields, table, whereClauses } = parseQuery(query);
+ const data = await readCSV(`${table}.csv`);
- // Apply WHERE clause filtering
- const filteredData = whereClauses.length > 0
- ? data.filter(row => whereClauses.every(clause => {
- // You can expand this to handle different operators
- return row[clause.field] === clause.value;
- }))
- : data;
+ // Apply WHERE clause filtering
+ const filteredData =
+ whereClauses.length > 0
+ ? data.filter((row) =>
+ whereClauses.every((clause) => evaluateCondition(row, clause))
+ )
+ : data;
- // Select the specified fields
- return filteredData.map(row => {
- const selectedRow = {};
- fields.forEach(field => {
- selectedRow[field] = row[field];
- });
- return selectedRow;
+ // Select the specified fields
+ return filteredData.map((row) => {
+ const selectedRow = {};
+ fields.forEach((field) => {
+ selectedRow[field] = row[field];
});
+ return selectedRow;
+ });
+}
+
+function evaluateCondition(row, clause) {
+ const { field, operator, value } = clause;
+ switch (operator) {
+ case "=":
+ return row[field] === value;
+ case "!=":
+ return row[field] !== value;
+ case ">":
+ return row[field] > value;
+ case "<":
+ return row[field] < value;
+ case ">=":
+ return row[field] >= value;
+ case "<=":
+ return row[field] <= value;
+ default:
+ throw new Error(`Unsupported operator: ${operator}`);
+ }
}
-module.exports = executeSELECTQuery;
\ No newline at end of file
+module.exports = executeSELECTQuery;
diff --git a/src/queryParser.js b/src/queryParser.js
index 5633026e5..fa5e6034b 100644
--- a/src/queryParser.js
+++ b/src/queryParser.js
@@ -1,40 +1,49 @@
-
function parseQuery(query) {
- const selectRegex = /SELECT (.+?) FROM (.+?)(?: WHERE (.*))?$/i;
- const match = query.match(selectRegex);
-
- if (match) {
- const [, fields, table, whereString] = match;
- const whereClauses = whereString ? parseWhereClause(whereString) : [];
- return {
- fields: fields.split(',').map(field => field.trim()),
- table: table.trim(),
- whereClauses
- };
- } else {
- throw new Error('Invalid query format');
- }
+ const selectRegex = /SELECT (.+?) FROM (.+?)(?: WHERE (.*))?$/i;
+ const match = query.match(selectRegex);
+
+ if (match) {
+ const [, fields, table, whereString] = match;
+ const whereClauses = whereString ? parseWhereClause(whereString) : [];
+ return {
+ fields: fields.split(",").map((field) => field.trim()),
+ table: table.trim(),
+ whereClauses,
+ };
+ } else {
+ throw new Error("Invalid query format");
+ }
}
-
function parseWhereClause(whereString) {
- if (typeof whereString !== 'string') {
- throw new Error('Input must be a string');
+ const conditionRegex = /(.*?)(=|!=|>|<|>=|<=)(.*)/;
+ return whereString.split(/ AND | OR /i).map((conditionString) => {
+ const match = conditionString.match(conditionRegex);
+ if (match) {
+ const [, field, operator, value] = match;
+ return { field: field.trim(), operator, value: value.trim() };
}
+ throw new Error("Invalid WHERE clause format");
+ });
+}
+// function parseWhereClause(whereString) {
+// if (typeof whereString !== 'string') {
+// throw new Error('Input must be a string');
+// }
- const conditions = whereString.split(/ AND | OR /i);
- const parsedConditions = [];
+// const conditions = whereString.split(/ AND | OR /i);
+// const parsedConditions = [];
- for (let condition of conditions) {
- const parts = condition.trim().split(/\s+/);
+// for (let condition of conditions) {
+// const parts = condition.trim().split(/\s+/);
- if (parts.length !== 3) {
- throw new Error('Invalid condition: ' + condition);
- }
+// if (parts.length !== 3) {
+// throw new Error('Invalid condition: ' + condition);
+// }
- const [field, operator, value] = parts;
- parsedConditions.push({ field, operator, value });
- }
+// const [field, operator, value] = parts;
+// parsedConditions.push({ field, operator, value });
+// }
- return parsedConditions;
-}
-module.exports = parseQuery;
\ No newline at end of file
+// return parsedConditions;
+// }
+module.exports = parseQuery;
diff --git a/tests/index.test.js b/tests/index.test.js
index e007bb8fa..456621548 100644
--- a/tests/index.test.js
+++ b/tests/index.test.js
@@ -1,24 +1,58 @@
-test('Parse SQL Query with Multiple WHERE Clauses', () => {
- const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'sample',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "30",
- }, {
- "field": "name",
- "operator": "=",
- "value": "John",
- }]
- });
+test("Parse SQL Query with Multiple WHERE Clauses", () => {
+ const query = "SELECT id, name FROM sample WHERE age = 30 AND name = John";
+ const parsed = parseQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "sample",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "30",
+ },
+ {
+ field: "name",
+ operator: "=",
+ value: "John",
+ },
+ ],
+ });
});
-test('Execute SQL Query with Multiple WHERE Clause', async () => {
- const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
\ No newline at end of file
+test("Execute SQL Query with Multiple WHERE Clause", async () => {
+ const query = "SELECT id, name FROM sample WHERE age = 30 AND name = John";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with Greater Than", async () => {
+ const queryWithGT = "SELECT id FROM sample WHERE age > 22";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(2);
+ expect(result[0]).toHaveProperty("id");
+});
+
+test("Execute SQL Query with Not Equal to", async () => {
+ const queryWithGT = "SELECT name FROM sample WHERE age != 25";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(2);
+ expect(result[0]).toHaveProperty("name");
+});
+
+test("parseWhereClause with invalid input", () => {
+ // Empty string
+ expect(() => parseWhereClause("")).toThrow("Invalid condition: ");
+
+ // Invalid conditions
+ expect(() => parseWhereClause("age > 22 AND")).toThrow(
+ "Invalid condition: age > 22 AND"
+ );
+ expect(() => parseWhereClause("age >")).toThrow("Invalid condition: age >");
+ expect(() => parseWhereClause("age > 22 foo")).toThrow(
+ "Invalid condition: age > 22 foo"
+ );
+
+ // Non-string input
+ expect(() => parseWhereClause(123)).toThrow("Input must be a string");
+});
From 63a708fd9a1ad97d75b38f6610964b2c24b0b838 Mon Sep 17 00:00:00 2001
From: Rahulsingh1939
Date: Sat, 27 Apr 2024 23:16:33 +0530
Subject: [PATCH 8/9] Revert "add online IDE url"
This reverts commit 795463e2a2549e49367870e4044df88cf63f3cf8.
---
README.md | 1 -
1 file changed, 1 deletion(-)
diff --git a/README.md b/README.md
index da2705239..eadfc715a 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,3 @@
-[](https://classroom.github.com/online_ide?assignment_repo_id=14847419&assignment_repo_type=AssignmentRepo)
StylusDB SQL
A SQL database engine written in JavaScript
From d3645cdd7cba782dee843651bc19939635836667 Mon Sep 17 00:00:00 2001
From: Rahulsingh1939
Date: Sun, 28 Apr 2024 16:57:13 +0530
Subject: [PATCH 9/9] Completed 20 Assignments
---
enrollment.csv | 6 +
src/cli.js | 73 ++
src/csvReader.js | 60 +-
src/queryExecutor.js | 369 ++++++
src/queryParser.js | 248 +++-
student.csv | 5 +
tests/cli.test.js | 53 +
tests/csvReader.test.js | 10 +
tests/deleteExecutor.test.js | 31 +
tests/index.test.js | 58 -
tests/insertExecutor.test.js | 36 +
tests/queryExecutor.test.js | 446 +++++++
tests/queryParser.test.js | 686 ++++++++++
tests/step-02/index.test.js | 16 +-
tests/step-03/index.test.js | 47 +-
tests/step-04/index.test.js | 59 +-
tests/step-05/index.test.js | 111 +-
tests/step-06/index.test.js | 168 ++-
tests/step-07/index.test.js | 229 ++--
tests/step-08/index.test.js | 287 +++--
tests/step-09/index.test.js | 444 ++++---
tests/step-10/index.test.js | 1312 ++++++++++---------
tests/step-11/index.test.js | 1416 +++++++++++----------
tests/step-12/index.test.js | 1481 ++++++++++++----------
tests/step-13/index.test.js | 1492 +++++++++++-----------
tests/step-14/index.test.js | 1600 ++++++++++++-----------
tests/step-15/index.test.js | 1745 ++++++++++++++------------
tests/step-16/index.test.js | 1643 ++++++++++++------------
tests/step-17/index.test.js | 1643 ++++++++++++------------
tests/step-17/insertExecuter.test.js | 51 +-
tests/step-18/deleteExecutor.test.js | 44 +-
tests/step-18/index.test.js | 1643 ++++++++++++------------
tests/step-18/insertExecuter.test.js | 51 +-
tests/step-19/deleteExecutor.test.js | 44 +-
tests/step-19/index.test.js | 1643 ++++++++++++------------
tests/step-19/insertExecuter.test.js | 51 +-
util/generateLargeFile.js | 34 +
37 files changed, 11287 insertions(+), 8048 deletions(-)
create mode 100644 enrollment.csv
create mode 100644 src/cli.js
create mode 100644 src/queryExecutor.js
create mode 100644 student.csv
create mode 100644 tests/cli.test.js
create mode 100644 tests/csvReader.test.js
create mode 100644 tests/deleteExecutor.test.js
delete mode 100644 tests/index.test.js
create mode 100644 tests/insertExecutor.test.js
create mode 100644 tests/queryExecutor.test.js
create mode 100644 tests/queryParser.test.js
create mode 100644 util/generateLargeFile.js
diff --git a/enrollment.csv b/enrollment.csv
new file mode 100644
index 000000000..e80af8d93
--- /dev/null
+++ b/enrollment.csv
@@ -0,0 +1,6 @@
+student_id,course
+1,Mathematics
+1,Physics
+2,Chemistry
+3,Mathematics
+5,Biology
\ No newline at end of file
diff --git a/src/cli.js b/src/cli.js
new file mode 100644
index 000000000..61a5d7b91
--- /dev/null
+++ b/src/cli.js
@@ -0,0 +1,73 @@
+#!/usr/bin/env node
+
+const readline = require("readline");
+const {
+ executeSELECTQuery,
+ executeINSERTQuery,
+ executeDELETEQuery,
+} = require("./queryExecutor.js");
+
+const rl = readline.createInterface({
+ input: process.stdin,
+ output: process.stdout,
+});
+
+rl.setPrompt("SQL> ");
+console.log(
+ 'SQL Query Engine CLI. Enter your SQL commands, or type "exit" to quit.'
+);
+
+rl.prompt();
+
+rl.on("line", async (line) => {
+ if (line.toLowerCase() === "exit") {
+ rl.close();
+ return;
+ }
+
+ try {
+ // Execute the query - do your own implementation
+ const query = line.trim();
+
+ // Determine the type of SQL command (SELECT, INSERT, DELETE, etc.)
+ const queryType = determineQueryType(query);
+
+ // Execute the appropriate query based on the command type
+ switch (queryType) {
+ case "SELECT":
+ const result = await executeSELECTQuery(query);
+ console.log("Result:", result);
+ break;
+ case "INSERT":
+ await executeINSERTQuery(query);
+ console.log("Successfully Inserted");
+ break;
+ case "DELETE":
+ const msg = await executeDELETEQuery(query);
+ console.log(msg.message);
+ break;
+ default:
+ throw new Error(`Unsupported SQL command: ${query}`);
+ }
+ } catch (error) {
+ console.error("Error:", error.message);
+ }
+
+ rl.prompt();
+}).on("close", () => {
+ console.log("Exiting SQL CLI");
+ process.exit(0);
+});
+
+function determineQueryType(query) {
+ const normalizedQuery = query.trim().toLowerCase();
+ if (normalizedQuery.startsWith("select")) {
+ return "SELECT";
+ } else if (normalizedQuery.startsWith("insert")) {
+ return "INSERT";
+ } else if (normalizedQuery.startsWith("delete")) {
+ return "DELETE";
+ } else {
+ throw new Error(`Unsupported SQL command: ${query}`);
+ }
+}
diff --git a/src/csvReader.js b/src/csvReader.js
index dc790f6f8..00d7f99e5 100644
--- a/src/csvReader.js
+++ b/src/csvReader.js
@@ -1,3 +1,5 @@
+// src/csvReader.js
+
const fs = require("fs");
const csv = require("csv-parser");
@@ -17,4 +19,60 @@ function readCSV(filePath) {
});
}
-module.exports = readCSV;
+async function writeCSV(filename, data) {
+ if (data.length < 1) {
+ throw new Error("No data to write to CSV");
+ }
+
+ // Prepare headers for CSV file
+ const fields = Object.keys(data[0]);
+ // let orderedFields = fields;
+ // let existingData = [];
+
+ // if (fs.existsSync(filename)) {
+ // // Read existing data from CSV file
+ // existingData = await readCSV(filename);
+ // orderedFields =
+ // existingData.length >= 1 ? Object.keys(existingData[0]) : fields;
+ // console.log(existingData);
+ //}
+ const outputStream = fs.createWriteStream(filename);
+
+ const headers = fields.join(",") + "\n";
+ outputStream.write(headers);
+
+ // Prepare new rows to write to CSV file
+ const newDataRows = data.map((row) => {
+ return fields.map((field) => row[field]).join(",");
+ });
+
+ // Combine existing data with new data
+ // const allRows = existingData
+ // .map((row) => {
+ // return orderedFields.map((field) => row[field]).join(",");
+ // })
+ // .concat(newDataRows);
+
+ // Write all rows to CSV file
+ newDataRows.forEach((rowData) => {
+ outputStream.write(rowData + "\n");
+ });
+
+ outputStream.end();
+
+ return new Promise((resolve, reject) => {
+ outputStream.on("finish", () => {
+ resolve();
+ });
+
+ outputStream.on("error", (err) => {
+ console.error(
+ `Error occurred while writing CSV file "${filename}":`,
+ err
+ );
+ reject(err);
+ });
+ });
+}
+
+module.exports = { readCSV, writeCSV };
diff --git a/src/queryExecutor.js b/src/queryExecutor.js
new file mode 100644
index 000000000..e6f42f637
--- /dev/null
+++ b/src/queryExecutor.js
@@ -0,0 +1,369 @@
+// src/index.js
+const fs = require("fs");
+const {
+ parseSelectQuery,
+ removeQuotes,
+ parseINSERTQuery,
+ parseDeleteQuery,
+} = require("./queryParser");
+const { readCSV, writeCSV } = require("./csvReader");
+
+function evaluateCondition(row, clause) {
+ const { field, operator, value } = clause;
+ const newValue = removeQuotes(value);
+ switch (operator) {
+ case "=":
+ return row[field] === newValue;
+ case "!=":
+ return row[field] !== newValue;
+ case ">":
+ return row[field] > newValue;
+ case "<":
+ return row[field] < newValue;
+ case ">=":
+ return row[field] >= newValue;
+ case "<=":
+ return row[field] <= newValue;
+ case "LIKE":
+ const regexPattern = "^" + clause.value.replace(/%/g, ".*") + "$";
+ return new RegExp(regexPattern, "i").test(row[clause.field]);
+ default:
+ throw new Error(`Unsupported operator: ${operator}`);
+ }
+}
+
+function aggregatedOperations(aggregateFunction, rows) {
+ const [op, fieldName] = aggregateFunction
+ .split("(")
+ .map((part) => part.trim().replace(")", ""));
+ if (fieldName === "*") {
+ return rows.length;
+ }
+
+ const values = rows.map((row) => row[fieldName]);
+
+ let result;
+ switch (op.toUpperCase()) {
+ case "COUNT":
+ result = values.length;
+ break;
+ case "AVG":
+ result =
+ values.reduce((acc, val) => acc + Number(val), 0) / values.length;
+ break;
+ case "MAX":
+ result = Math.max(...values);
+ break;
+ case "MIN":
+ result = Math.min(...values);
+ break;
+ case "SUM":
+ result = values.reduce((acc, val) => acc + Number(val), 0);
+ break;
+ // Handle other aggregate functions if needed
+ default:
+ throw new Error(`Unsupported aggregate function: ${op}`);
+ }
+
+ return result;
+}
+
+// Helper function to apply GROUP BY and aggregate functions
+function applyGroupBy(data, groupByFields, aggregateFunctions) {
+ const groupedData = data.reduce((acc, row) => {
+ //generate a group key from group by fields for each distinct possible group
+ const groupKey = groupByFields.map((field) => row[field]).join("_");
+
+ if (!acc[groupKey]) {
+ acc[groupKey] = [];
+ }
+ //group the rows according to the groupKey
+ acc[groupKey].push(row);
+
+ return acc;
+ }, {});
+
+ const aggregatedData = Object.entries(groupedData).map(
+ ([groupKey, groupRows]) => {
+ const group = {};
+
+ const groupRowValues = groupKey.split("_");
+ groupByFields.forEach((field, index) => {
+ group[field] = groupRowValues[index];
+ aggregateFunctions = aggregateFunctions.filter((func) => {
+ return func !== field;
+ });
+ });
+
+ aggregateFunctions.forEach((func) => {
+ group[`${func}`] = aggregatedOperations(func, groupRows);
+ });
+
+ return group;
+ }
+ );
+
+ return aggregatedData;
+}
+
+// Helper functions for different JOIN types
+function performInnerJoin(data, joinData, joinCondition, fields, table) {
+ data = data.flatMap((mainRow) => {
+ return joinData
+ .filter((joinRow) => {
+ const mainValue = mainRow[joinCondition.left.split(".")[1]];
+ const joinValue = joinRow[joinCondition.right.split(".")[1]];
+ return mainValue === joinValue;
+ })
+ .map((joinRow) => {
+ return fields.reduce((acc, field) => {
+ const [tableName, fieldName] = field.split(".");
+ acc[field] =
+ tableName === table ? mainRow[fieldName] : joinRow[fieldName];
+ return acc;
+ }, {});
+ });
+ });
+
+ return data;
+}
+
+function performLeftJoin(data, joinData, joinCondition, fields, table) {
+ data = data.flatMap((mainRow) => {
+ const matchingRows = joinData.filter((joinRow) => {
+ const mainValue = mainRow[joinCondition.left.split(".")[1]];
+ const joinValue = joinRow[joinCondition.right.split(".")[1]];
+ return mainValue === joinValue;
+ });
+
+ //no matching row found for particular main row
+ if (matchingRows.length == 0) {
+ return fields.reduce((acc, field) => {
+ const [tablename, fieldname] = field.split(".");
+ acc[field] = tablename === table ? mainRow[fieldname] : null;
+ return acc;
+ }, {});
+ }
+
+ //matching rows exist
+ return matchingRows.map((joinRow) => {
+ return fields.reduce((acc, field) => {
+ const [tableName, fieldName] = field.split(".");
+ acc[field] =
+ tableName === table ? mainRow[fieldName] : joinRow[fieldName];
+ return acc;
+ }, {});
+ });
+ });
+
+ return data;
+}
+
+function performRightJoin(data, joinData, joinCondition, fields, table) {
+ joinData = joinData.flatMap((joinRow) => {
+ const matchingRows = data.filter((mainRow) => {
+ const mainValue = mainRow[joinCondition.left.split(".")[1]];
+ const joinValue = joinRow[joinCondition.right.split(".")[1]];
+ return mainValue === joinValue;
+ });
+
+ //matching values dont exist for particular join row
+ if (matchingRows.length == 0) {
+ return fields.reduce((acc, field) => {
+ const [tablename, fieldname] = field.split(".");
+ acc[field] = tablename === table ? null : joinRow[fieldname];
+ return acc;
+ }, {});
+ }
+
+ //matching rows exist
+ return matchingRows.map((mainRow) => {
+ return fields.reduce((acc, field) => {
+ const [tablename, fieldname] = field.split(".");
+ acc[field] =
+ tablename === table ? mainRow[fieldname] : joinRow[fieldname];
+ return acc;
+ }, {});
+ });
+ });
+
+ return joinData;
+}
+
+async function executeSELECTQuery(query) {
+ try {
+ const {
+ fields,
+ table,
+ whereClauses,
+ joinType,
+ joinTable,
+ joinCondition,
+ groupByFields,
+ hasAggregateWithoutGroupBy,
+ orderByFields,
+ limit,
+ isDistinct,
+ } = parseSelectQuery(query);
+ let data = await readCSV(`${table}.csv`);
+
+ // Logic for applying JOINs
+ if (joinTable && joinCondition) {
+ const joinData = await readCSV(`${joinTable}.csv`);
+
+ const dataKeys = data
+ ? Object.keys(data[0]).map((key) => `${table}.${key}`)
+ : [];
+ const joinDataKeys = joinData
+ ? Object.keys(joinData[0]).map((key) => `${joinTable}.${key}`)
+ : [];
+ const allFields = [...dataKeys, ...joinDataKeys];
+
+ switch (joinType.toUpperCase()) {
+ case "INNER":
+ data = performInnerJoin(
+ data,
+ joinData,
+ joinCondition,
+ allFields,
+ table
+ );
+ break;
+ case "LEFT":
+ data = performLeftJoin(
+ data,
+ joinData,
+ joinCondition,
+ allFields,
+ table
+ );
+ break;
+ case "RIGHT":
+ data = performRightJoin(
+ data,
+ joinData,
+ joinCondition,
+ allFields,
+ table
+ );
+ break;
+ // Handle default case or unsupported JOIN types
+ default:
+ throw new Error(`Unsupported JOIN type: ${joinType.ToUpperCase()}`);
+ }
+ }
+
+ // logic for WHERE clause
+ let filteredData =
+ whereClauses.length > 0
+ ? data.filter((row) =>
+ whereClauses.every((clause) => evaluateCondition(row, clause))
+ )
+ : data;
+
+ // logic for group by
+ if (groupByFields) {
+ filteredData = applyGroupBy(filteredData, groupByFields, fields);
+ }
+
+ if (hasAggregateWithoutGroupBy && fields.length == 1) {
+ const selectedRow = {};
+ selectedRow[fields[0]] = aggregatedOperations(fields[0], filteredData);
+ return [selectedRow];
+ }
+
+ // console.log("AFTER GROUP: ", filteredData);
+
+ if (orderByFields) {
+ filteredData.sort((a, b) => {
+ for (let { fieldName, order } of orderByFields) {
+ if (a[fieldName] < b[fieldName]) return order === "ASC" ? -1 : 1;
+ if (a[fieldName] > b[fieldName]) return order === "ASC" ? 1 : -1;
+ }
+ return 0;
+ });
+ }
+
+ // console.log("AFTER ORDER: ", filteredData);
+
+ if (limit !== null) {
+ filteredData = filteredData.slice(0, limit);
+ }
+
+ if (isDistinct) {
+ filteredData = [
+ ...new Map(
+ filteredData.map((item) => [
+ fields.map((field) => item[field]).join("|"),
+ item,
+ ])
+ ).values(),
+ ];
+ }
+
+ // Filter the fields based on the query fields
+ return filteredData.map((row) => {
+ const selectedRow = {};
+ fields.forEach((field) => {
+ if (hasAggregateWithoutGroupBy) {
+ selectedRow[field] = aggregatedOperations(field, filteredData);
+ } else {
+ selectedRow[field] = row[field];
+ }
+ });
+ return selectedRow;
+ });
+ } catch (error) {
+ throw new Error(`Error executing query: ${error.message}`);
+ }
+}
+
+async function executeINSERTQuery(query) {
+ const { type, table, columns, values } = parseINSERTQuery(query);
+
+ if (type !== "INSERT") {
+ throw new Error("Invalid INSERT format");
+ }
+
+ let orderedFields = columns;
+ let existingData = [];
+
+ if (fs.existsSync(`${table}.csv`)) {
+ // Read existing data from CSV file
+ existingData = await readCSV(`${table}.csv`);
+ orderedFields =
+ existingData.length >= 1 ? Object.keys(existingData[0]) : columns;
+ }
+
+ const data = [
+ orderedFields.reduce((acc, field, index) => {
+ acc[field] = values[index];
+ return acc;
+ }, {}),
+ ];
+
+ const newData = existingData.concat(data);
+
+ await writeCSV(`${table}.csv`, newData);
+}
+// src/queryExecutor.js
+
+async function executeDELETEQuery(query) {
+ const { table, whereClauses } = parseDeleteQuery(query);
+
+ let data = await readCSV(`${table}.csv`);
+
+ const filteredData =
+ whereClauses.length > 0
+ ? data.filter((row) =>
+ whereClauses.every((clause) => !evaluateCondition(row, clause))
+ )
+ : [];
+
+ // Save the updated data back to the CSV file
+ await writeCSV(`${table}.csv`, filteredData);
+
+ return { message: "Rows deleted successfully." };
+}
+
+module.exports = { executeSELECTQuery, executeINSERTQuery, executeDELETEQuery };
diff --git a/src/queryParser.js b/src/queryParser.js
index fa5e6034b..4fed4638d 100644
--- a/src/queryParser.js
+++ b/src/queryParser.js
@@ -1,49 +1,229 @@
-function parseQuery(query) {
- const selectRegex = /SELECT (.+?) FROM (.+?)(?: WHERE (.*))?$/i;
- const match = query.match(selectRegex);
+function parseDeleteQuery(query) {
+ query = query.trim();
+
+ // Where Clause logic
+ const whereSplit = query.split(/\sWHERE\s/i);
+ query = whereSplit[0]; // Everything before WHERE clause
+ const whereClause = whereSplit.length > 1 ? whereSplit[1].trim() : null;
+ let whereClauses = [];
+ if (whereClause) {
+ whereClauses = parseWhereClause(whereClause);
+ }
+
+ //insert regex
+ const deleteRegex = /^DELETE FROM\s+(\w+)/i;
+ const deleteMatch = query.match(deleteRegex);
+
+ if (!deleteMatch) {
+ throw new Error("Invalid DELETE format");
+ }
+
+ const [, table] = deleteMatch;
+
+ return {
+ type: "DELETE",
+ table: table.trim(),
+ whereClauses: whereClauses,
+ };
+}
+
+function parseINSERTQuery(query) {
+ query = query.trim();
+
+ //insert regex
+ const insertPattern =
+ /^INSERT INTO\s+(\w+)\s+\(([^)]+)\)\s+VALUES\s+\(([^)]+)\)/i;
+
+ const insertMatch = query.match(insertPattern);
+
+ if (!insertMatch) {
+ throw new Error("Invalid INSERT format");
+ }
+
+ const [, table, fields, values] = insertMatch;
+ return {
+ type: "INSERT",
+ table: table.trim(),
+ columns: fields.split(",").map((field) => removeQuotes(field.trim())),
+ values: values.split(",").map((val) => removeQuotes(val.trim())),
+ };
+}
+
+function parseSelectQuery(query) {
+ try {
+ // First, let's trim the query to remove any leading/trailing whitespaces
+ query = query.trim();
+
+ let isDistinct = false;
+ if (query.toUpperCase().includes("SELECT DISTINCT")) {
+ isDistinct = true;
+ query = query.replace("SELECT DISTINCT", "SELECT");
+ }
+
+ // Updated regex to capture LIMIT clause
+ const limitRegex = /\sLIMIT\s(\d+)/i;
+ const limitMatch = query.match(limitRegex);
+
+ let limit = null;
+ if (limitMatch) {
+ query = query.split(/\sLIMIT\s/i)[0];
+ limit = parseInt(limitMatch[1]);
+ }
+
+ // Updated regex to capture ORDER BY clause
+ const orderByRegex = /\sORDER BY\s(.+)/i;
+ const orderByMatch = query.match(orderByRegex);
+
+ let orderByFields = null;
+ if (orderByMatch) {
+ query = query.split(/\sORDER BY\s/i)[0];
+ orderByFields = orderByMatch[1].split(",").map((field) => {
+ const [fieldName, order] = field.trim().split(/\s+/);
+ return { fieldName, order: order ? order.toUpperCase() : "ASC" };
+ });
+ }
+
+ // Updated regex to capture GROUP BY clause
+ const groupByRegex = /\sGROUP BY\s(.+)/i;
+ const groupByMatch = query.match(groupByRegex);
+
+ let groupByFields = null;
+
+ if (groupByMatch) {
+ groupByFields = groupByMatch[1].split(",").map((field) => field.trim());
+ query = query.split(/\sGROUP BY\s/i)[0];
+ }
+
+ const aggRegex = /\s(COUNT|AVG|MAX|MIN|SUM)\(.*?\)/gi;
+ const aggMatch = query.match(aggRegex);
+
+ let hasAggregateWithoutGroupBy = false;
+ if (!groupByMatch && aggMatch) {
+ hasAggregateWithoutGroupBy = true;
+ }
+
+ // Initialize variables for different parts of the query
+ let selectPart, fromPart;
+
+ // Split the query at the WHERE clause if it exists
+ const whereSplit = query.split(/\sWHERE\s/i);
+ query = whereSplit[0]; // Everything before WHERE clause
+
+ // WHERE clause is the second part after splitting, if it exists
+ const whereClause = whereSplit.length > 1 ? whereSplit[1].trim() : null;
+
+ // Split the remaining query at the JOIN clause if it exists
+ const joinSplit = query.split(/\s(INNER|LEFT|RIGHT) JOIN\s/i);
+ selectPart = joinSplit[0].trim(); // Everything before JOIN clause
+
+ // Parse the SELECT part
+ const selectRegex = /^SELECT\s(.+?)\sFROM\s(.+)/i;
+ const selectMatch = selectPart.match(selectRegex);
+ if (!selectMatch) {
+ throw new Error("Invalid SELECT format");
+ }
+
+ const [, fields, table] = selectMatch;
+
+ // Parse the JOIN part if it exists
+ const { joinType, joinTable, joinCondition } = parseJoinClause(query);
+
+ // Parse the WHERE part if it exists
+ let whereClauses = [];
+ if (whereClause) {
+ whereClauses = parseWhereClause(whereClause);
+ }
- if (match) {
- const [, fields, table, whereString] = match;
- const whereClauses = whereString ? parseWhereClause(whereString) : [];
return {
fields: fields.split(",").map((field) => field.trim()),
table: table.trim(),
whereClauses,
+ joinType,
+ joinTable,
+ joinCondition,
+ groupByFields,
+ hasAggregateWithoutGroupBy,
+ orderByFields,
+ limit,
+ isDistinct,
};
- } else {
- throw new Error("Invalid query format");
+ } catch (error) {
+ // console.error(error);
+ throw new Error(`Query parsing error: ${error.message}`);
}
}
+
function parseWhereClause(whereString) {
- const conditionRegex = /(.*?)(=|!=|>|<|>=|<=)(.*)/;
- return whereString.split(/ AND | OR /i).map((conditionString) => {
- const match = conditionString.match(conditionRegex);
- if (match) {
- const [, field, operator, value] = match;
- return { field: field.trim(), operator, value: value.trim() };
- }
- throw new Error("Invalid WHERE clause format");
- });
+ try {
+ const conditionRegex = /(.*?)(=|!=|>|<|>=|<=)(.*)/;
+ return whereString.split(/ AND | OR /i).map((conditionString) => {
+ const match = conditionString.match(conditionRegex);
+
+ if (conditionString.includes(" LIKE ")) {
+ const [field, pattern] = conditionString.split(/\sLIKE\s/i);
+ return {
+ field: field.trim(),
+ operator: "LIKE",
+ value: removeQuotes(pattern.trim()),
+ };
+ }
+
+ if (match) {
+ const [, field, operator, value] = match;
+
+ // to remove cases of 'value'
+
+ return {
+ field: field.trim(),
+ operator,
+ value: value.trim(),
+ };
+ }
+ throw new Error("Invalid WHERE clause format");
+ });
+ } catch (error) {
+ throw error;
+ }
}
-// function parseWhereClause(whereString) {
-// if (typeof whereString !== 'string') {
-// throw new Error('Input must be a string');
-// }
-// const conditions = whereString.split(/ AND | OR /i);
-// const parsedConditions = [];
+function parseJoinClause(query) {
+ const joinRegex =
+ /\s(INNER|LEFT|RIGHT) JOIN\s(.+?)\sON\s([\w.]+)\s*=\s*([\w.]+)/i;
+ const joinMatch = query.match(joinRegex);
-// for (let condition of conditions) {
-// const parts = condition.trim().split(/\s+/);
+ if (joinMatch) {
+ return {
+ joinType: joinMatch[1].trim(),
+ joinTable: joinMatch[2].trim(),
+ joinCondition: {
+ left: joinMatch[3].trim(),
+ right: joinMatch[4].trim(),
+ },
+ };
+ }
-// if (parts.length !== 3) {
-// throw new Error('Invalid condition: ' + condition);
-// }
+ return {
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ };
+}
-// const [field, operator, value] = parts;
-// parsedConditions.push({ field, operator, value });
-// }
+function removeQuotes(value) {
+ if (
+ typeof value === "string" &&
+ (value.startsWith(`'`) || value.startsWith(`"`)) &&
+ (value.endsWith(`'`) || value.endsWith(`"`))
+ ) {
+ return value.slice(1, -1); // Remove quotes
+ }
+ return value;
+}
-// return parsedConditions;
-// }
-module.exports = parseQuery;
+module.exports = {
+ parseSelectQuery,
+ parseJoinClause,
+ removeQuotes,
+ parseINSERTQuery,
+ parseDeleteQuery,
+};
diff --git a/student.csv b/student.csv
new file mode 100644
index 000000000..e9c960121
--- /dev/null
+++ b/student.csv
@@ -0,0 +1,5 @@
+id,name,age
+1,John,30
+2,Jane,25
+3,Bob,22
+4,Alice,24
\ No newline at end of file
diff --git a/tests/cli.test.js b/tests/cli.test.js
new file mode 100644
index 000000000..1a3eab324
--- /dev/null
+++ b/tests/cli.test.js
@@ -0,0 +1,53 @@
+const child_process = require("child_process");
+const path = require("path");
+
+test("DISTINCT with Multiple Columns via CLI", (done) => {
+ const cliPath = path.join(__dirname, "..", "src", "cli.js");
+ const cliProcess = child_process.spawn("node", [cliPath]);
+
+ let outputData = "";
+ cliProcess.stdout.on("data", (data) => {
+ outputData += data.toString();
+ });
+
+ cliProcess.on("exit", () => {
+ // Define a regex pattern to extract the JSON result
+
+ const cleanedOutput = outputData.replace(/\s+/g, " ");
+
+ const resultRegex = /Result: (\[.+\])/s;
+ const match = cleanedOutput.match(resultRegex);
+
+ // Fix JSON outputput
+ match[1] = match[1].replace(/'/g, '"').replace(/(\w+):/g, '"$1":');
+
+ if (match && match[1]) {
+ // Parse the captured JSON string
+
+ const results = JSON.parse(match[1].trim());
+
+ // Validation logic
+ expect(results).toEqual([
+ { student_id: "1", course: "Mathematics" },
+ { student_id: "1", course: "Physics" },
+ { student_id: "2", course: "Chemistry" },
+ { student_id: "3", course: "Mathematics" },
+ { student_id: "5", course: "Biology" },
+ ]);
+ } else {
+ throw new Error("Failed to parse CLI output");
+ }
+
+ done();
+ });
+
+ // Introduce a delay before sending the query
+ setTimeout(() => {
+ cliProcess.stdin.write(
+ "SELECT DISTINCT student_id, course FROM enrollment\n"
+ );
+ setTimeout(() => {
+ cliProcess.stdin.write("exit\n");
+ }, 1000); // 1 second delay
+ }, 1000); // 1 second delay
+});
diff --git a/tests/csvReader.test.js b/tests/csvReader.test.js
new file mode 100644
index 000000000..97e38ee34
--- /dev/null
+++ b/tests/csvReader.test.js
@@ -0,0 +1,10 @@
+const { readCSV, writeCSV } = require("../src/csvReader");
+const fs = require("fs");
+
+test("Read CSV File", async () => {
+ const data = await readCSV("./student.csv");
+ expect(data.length).toBeGreaterThan(0);
+ expect(data.length).toBe(4);
+ expect(data[0].name).toBe("John");
+ expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later
+});
diff --git a/tests/deleteExecutor.test.js b/tests/deleteExecutor.test.js
new file mode 100644
index 000000000..09d1b7f31
--- /dev/null
+++ b/tests/deleteExecutor.test.js
@@ -0,0 +1,31 @@
+const { executeDELETEQuery } = require("../src/queryExecutor");
+const { readCSV, writeCSV } = require("../src/csvReader");
+const fs = require("fs");
+
+// Helper function to create courses.csv with initial data
+async function createCoursesCSV() {
+ const initialData = [
+ { course_id: "1", course_name: "Mathematics", instructor: "Dr. Smith" },
+ { course_id: "2", course_name: "Chemistry", instructor: "Dr. Jones" },
+ { course_id: "3", course_name: "Physics", instructor: "Dr. Taylor" },
+ ];
+ await writeCSV("courses.csv", initialData);
+}
+
+// Test to DELETE a course and verify
+test("Execute DELETE FROM Query for courses.csv", async () => {
+ // Create courses.csv with initial data
+ await createCoursesCSV();
+
+ // Execute DELETE statement
+ const deleteQuery = "DELETE FROM courses WHERE course_id = '2'";
+ await executeDELETEQuery(deleteQuery);
+
+ // Verify the course was removed
+ const updatedData = await readCSV("courses.csv");
+ const deletedCourse = updatedData.find((course) => course.course_id === "2");
+ expect(deletedCourse).toBeUndefined();
+
+ // Cleanup: Delete courses.csv
+ fs.unlinkSync("courses.csv");
+});
diff --git a/tests/index.test.js b/tests/index.test.js
deleted file mode 100644
index 456621548..000000000
--- a/tests/index.test.js
+++ /dev/null
@@ -1,58 +0,0 @@
-test("Parse SQL Query with Multiple WHERE Clauses", () => {
- const query = "SELECT id, name FROM sample WHERE age = 30 AND name = John";
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ["id", "name"],
- table: "sample",
- whereClauses: [
- {
- field: "age",
- operator: "=",
- value: "30",
- },
- {
- field: "name",
- operator: "=",
- value: "John",
- },
- ],
- });
-});
-
-test("Execute SQL Query with Multiple WHERE Clause", async () => {
- const query = "SELECT id, name FROM sample WHERE age = 30 AND name = John";
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toEqual({ id: "1", name: "John" });
-});
-
-test("Execute SQL Query with Greater Than", async () => {
- const queryWithGT = "SELECT id FROM sample WHERE age > 22";
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(2);
- expect(result[0]).toHaveProperty("id");
-});
-
-test("Execute SQL Query with Not Equal to", async () => {
- const queryWithGT = "SELECT name FROM sample WHERE age != 25";
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(2);
- expect(result[0]).toHaveProperty("name");
-});
-
-test("parseWhereClause with invalid input", () => {
- // Empty string
- expect(() => parseWhereClause("")).toThrow("Invalid condition: ");
-
- // Invalid conditions
- expect(() => parseWhereClause("age > 22 AND")).toThrow(
- "Invalid condition: age > 22 AND"
- );
- expect(() => parseWhereClause("age >")).toThrow("Invalid condition: age >");
- expect(() => parseWhereClause("age > 22 foo")).toThrow(
- "Invalid condition: age > 22 foo"
- );
-
- // Non-string input
- expect(() => parseWhereClause(123)).toThrow("Input must be a string");
-});
diff --git a/tests/insertExecutor.test.js b/tests/insertExecutor.test.js
new file mode 100644
index 000000000..05589043e
--- /dev/null
+++ b/tests/insertExecutor.test.js
@@ -0,0 +1,36 @@
+const { executeINSERTQuery } = require("../src/queryExecutor");
+const { readCSV, writeCSV } = require("../src/csvReader");
+const fs = require("fs");
+
+// Helper function to create grades.csv with initial data
+async function createGradesCSV() {
+ const initialData = [
+ { student_id: "1", course: "Mathematics", grade: "A" },
+ { student_id: "2", course: "Chemistry", grade: "B" },
+ { student_id: "3", course: "Mathematics", grade: "C" },
+ ];
+ await writeCSV("grades.csv", initialData);
+}
+
+// Test to INSERT a new grade and verify
+test("Execute INSERT INTO Query for grades.csv", async () => {
+ // Create grades.csv with initial data
+ await createGradesCSV();
+
+ // Execute INSERT statement
+ const insertQuery =
+ "INSERT INTO grades (student_id, course, grade) VALUES ('4', 'Physics', 'A')";
+ await executeINSERTQuery(insertQuery);
+
+ // Verify the new entry
+ const updatedData = await readCSV("grades.csv");
+ const newEntry = updatedData.find(
+ (row) => row.student_id === "4" && row.course === "Physics"
+ );
+
+ expect(newEntry).toBeDefined();
+ expect(newEntry.grade).toEqual("A");
+
+ // Cleanup: Delete grades.csv
+ fs.unlinkSync("grades.csv");
+});
diff --git a/tests/queryExecutor.test.js b/tests/queryExecutor.test.js
new file mode 100644
index 000000000..72df2f9b8
--- /dev/null
+++ b/tests/queryExecutor.test.js
@@ -0,0 +1,446 @@
+const { executeSELECTQuery } = require("../src/queryExecutor");
+
+test("Execute SQL Query", async () => {
+ const query = "SELECT id, name FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBeGreaterThan(0);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0]).not.toHaveProperty("age");
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0].id).toBe("2");
+});
+
+test("Execute SQL Query with Complex WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with Greater Than", async () => {
+ const queryWithGT = "SELECT id FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("id");
+});
+
+test("Execute SQL Query with Not Equal to", async () => {
+ const queryWithGT = "SELECT name FROM student WHERE age != 25";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("name");
+});
+
+test("Execute SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(4);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ })
+ );
+});
+
+test("Execute SQL Query with INNER JOIN and a WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25";
+ const result = await executeSELECTQuery(query);
+ /*
+ result = [
+ {
+ 'student.name': 'John',
+ 'enrollment.course': 'Mathematics',
+ 'student.age': '30'
+ },
+ {
+ 'student.name': 'John',
+ 'enrollment.course': 'Physics',
+ 'student.age': '30'
+ }
+ ]
+ */
+ expect(result.length).toEqual(2);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ })
+ );
+});
+
+test("Execute SQL Query with LEFT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "Alice",
+ "enrollment.course": null,
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 students, but John appears twice
+});
+
+test("Execute SQL Query with RIGHT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Physics",
+ "student.name": "John",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(4);
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Physics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "Bob",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Biology",
+ "student.name": null,
+ }),
+ ])
+ );
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Chemistry",
+ "student.name": "Jane",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([]);
+});
+
+test("Execute COUNT Aggregate Query", async () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "COUNT(*)": 4 }]);
+});
+
+test("Execute SUM Aggregate Query", async () => {
+ const query = "SELECT SUM(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "SUM(age)": 101 }]);
+});
+
+test("Execute AVG Aggregate Query", async () => {
+ const query = "SELECT AVG(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ // Assuming AVG returns a single decimal point value
+ expect(result).toEqual([{ "AVG(age)": 25.25 }]);
+});
+
+test("Execute MIN Aggregate Query", async () => {
+ const query = "SELECT MIN(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MIN(age)": 22 }]);
+});
+
+test("Execute MAX Aggregate Query", async () => {
+ const query = "SELECT MAX(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MAX(age)": 30 }]);
+});
+
+test("Count students per age", async () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "22", "COUNT(*)": 1 },
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments per course", async () => {
+ const query = "SELECT course, COUNT(*) FROM enrollment GROUP BY course";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { course: "Mathematics", "COUNT(*)": 2 },
+ { course: "Physics", "COUNT(*)": 1 },
+ { course: "Chemistry", "COUNT(*)": 1 },
+ { course: "Biology", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count courses per student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { student_id: "1", "COUNT(*)": 2 },
+ { student_id: "2", "COUNT(*)": 1 },
+ { student_id: "3", "COUNT(*)": 1 },
+ { student_id: "5", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count students within a specific age range", async () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments for a specific course", async () => {
+ const query =
+ 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ course: "Mathematics", "COUNT(*)": 2 }]);
+});
+
+test("Count courses for a specific student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ student_id: "1", "COUNT(*)": 2 }]);
+});
+
+test("Average age of students above a certain age", async () => {
+ const query = "SELECT AVG(age) FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(query);
+ const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
+ expect(result).toEqual([{ "AVG(age)": expectedAverage }]);
+});
+
+test("Execute SQL Query with ORDER BY", async () => {
+ const query = "SELECT name FROM student ORDER BY name ASC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([
+ { name: "Alice" },
+ { name: "Bob" },
+ { name: "Jane" },
+ { name: "John" },
+ ]);
+});
+
+test("Execute SQL Query with ORDER BY and WHERE", async () => {
+ const query = "SELECT name FROM student WHERE age > 24 ORDER BY name DESC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([{ name: "John" }, { name: "Jane" }]);
+});
+test("Execute SQL Query with ORDER BY and GROUP BY", async () => {
+ const query =
+ "SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([
+ { age: "30", "COUNT(id) as count": 1 },
+ { age: "25", "COUNT(id) as count": 1 },
+ { age: "24", "COUNT(id) as count": 1 },
+ { age: "22", "COUNT(id) as count": 1 },
+ ]);
+});
+
+test("Execute SQL Query with standard LIMIT clause", async () => {
+ const query = "SELECT id, name FROM student LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with LIMIT clause equal to total rows", async () => {
+ const query = "SELECT id, name FROM student LIMIT 4";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(4);
+});
+
+test("Execute SQL Query with LIMIT clause exceeding total rows", async () => {
+ const query = "SELECT id, name FROM student LIMIT 10";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(4); // Total rows in student.csv
+});
+
+test("Execute SQL Query with LIMIT 0", async () => {
+ const query = "SELECT id, name FROM student LIMIT 0";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(0);
+});
+
+test("Execute SQL Query with LIMIT and ORDER BY clause", async () => {
+ const query = "SELECT id, name FROM student ORDER BY age DESC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(2);
+ expect(result[0].name).toEqual("John");
+ expect(result[1].name).toEqual("Jane");
+});
+
+test("Error Handling with Malformed Query", async () => {
+ const query = "SELECT FROM table"; // intentionally malformed
+ await expect(executeSELECTQuery(query)).rejects.toThrow(
+ "Error executing query: Query parsing error: Invalid SELECT format"
+ );
+});
+
+test("Basic DISTINCT Usage", async () => {
+ const query = "SELECT DISTINCT age FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "30" },
+ { age: "25" },
+ { age: "22" },
+ { age: "24" },
+ ]);
+});
+
+test("DISTINCT with Multiple Columns", async () => {
+ const query = "SELECT DISTINCT student_id, course FROM enrollment";
+ const result = await executeSELECTQuery(query);
+ // Expecting unique combinations of student_id and course
+ expect(result).toEqual([
+ { student_id: "1", course: "Mathematics" },
+ { student_id: "1", course: "Physics" },
+ { student_id: "2", course: "Chemistry" },
+ { student_id: "3", course: "Mathematics" },
+ { student_id: "5", course: "Biology" },
+ ]);
+});
+
+// Not a good test right now
+test("DISTINCT with WHERE Clause", async () => {
+ const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"';
+ const result = await executeSELECTQuery(query);
+ // Expecting courses taken by student with ID 1
+ expect(result).toEqual([{ course: "Mathematics" }, { course: "Physics" }]);
+});
+
+test("DISTINCT with JOIN Operations", async () => {
+ const query =
+ "SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ // Expecting names of students who are enrolled in any course
+ expect(result).toEqual([
+ { "student.name": "John" },
+ { "student.name": "Jane" },
+ { "student.name": "Bob" },
+ ]);
+});
+
+test("DISTINCT with ORDER BY and LIMIT", async () => {
+ const query = "SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ // Expecting the two highest unique ages
+ expect(result).toEqual([{ age: "30" }, { age: "25" }]);
+});
+
+test("Execute SQL Query with LIKE Operator for Name", async () => {
+ const query = "SELECT name FROM student WHERE name LIKE '%Jane%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting names containing 'Jane'
+ expect(result).toEqual([{ name: "Jane" }]);
+});
+
+test("Execute SQL Query with LIKE Operator and Wildcards", async () => {
+ const query = "SELECT name FROM student WHERE name LIKE 'J%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting names starting with 'J'
+ expect(result).toEqual([{ name: "John" }, { name: "Jane" }]);
+});
+
+test("Execute SQL Query with LIKE Operator Case Insensitive", async () => {
+ const query = "SELECT name FROM student WHERE name LIKE '%bob%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting names 'Bob' (case insensitive)
+ expect(result).toEqual([{ name: "Bob" }]);
+});
+
+test("Execute SQL Query with LIKE Operator and DISTINCT", async () => {
+ const query = "SELECT DISTINCT name FROM student WHERE name LIKE '%e%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting unique names containing 'e'
+ expect(result).toEqual([{ name: "Jane" }, { name: "Alice" }]);
+});
+
+test("LIKE with ORDER BY and LIMIT", async () => {
+ const query =
+ "SELECT name FROM student WHERE name LIKE '%a%' ORDER BY name ASC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ // Expecting the first two names alphabetically that contain 'a'
+ expect(result).toEqual([{ name: "Alice" }, { name: "Jane" }]);
+});
diff --git a/tests/queryParser.test.js b/tests/queryParser.test.js
new file mode 100644
index 000000000..b1d4acf81
--- /dev/null
+++ b/tests/queryParser.test.js
@@ -0,0 +1,686 @@
+const { parseJoinClause, parseSelectQuery } = require("../src/queryParser");
+
+test("Parse SQL Query", () => {
+ const query = "SELECT id, name FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with WHERE Clause", () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "25",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with Multiple WHERE Clauses", () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "30",
+ },
+ {
+ field: "name",
+ operator: "=",
+ value: "John",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN and WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "20" }],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse INNER JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "INNER",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse LEFT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "LEFT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse RIGHT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "RIGHT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Returns null for queries without JOIN", () => {
+ const query = "SELECT * FROM table1";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "LEFT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "RIGHT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "22" }],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Physics'" },
+ ],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: "<", value: "25" }],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Chemistry'" },
+ ],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse COUNT Aggregate Query", () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SUM Aggregate Query", () => {
+ const query = "SELECT SUM(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["SUM(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse AVG Aggregate Query", () => {
+ const query = "SELECT AVG(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["AVG(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MIN Aggregate Query", () => {
+ const query = "SELECT MIN(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MIN(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MAX Aggregate Query", () => {
+ const query = "SELECT MAX(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MAX(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse basic GROUP BY query", () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with WHERE clause", () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [{ field: "age", operator: ">", value: "22" }],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with multiple fields", () => {
+ const query =
+ "SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student_id", "course", "COUNT(*)"],
+ table: "enrollment",
+ whereClauses: [],
+ groupByFields: ["student_id", "course"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with JOIN and WHERE clauses", () => {
+ const query =
+ 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student.name", "COUNT(*)"],
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: '"Mathematics"' },
+ ],
+ groupByFields: ["student.name"],
+ joinType: "INNER",
+ joinTable: "enrollment",
+ joinCondition: {
+ left: "student.id",
+ right: "enrollment.student_id",
+ },
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with ORDER BY", () => {
+ const query = "SELECT name FROM student ORDER BY name ASC";
+ const parsed = parseSelectQuery(query);
+ expect(parsed.orderByFields).toEqual([{ fieldName: "name", order: "ASC" }]);
+});
+
+test("Parse SQL Query with ORDER BY and WHERE", () => {
+ const query = "SELECT name FROM student WHERE age > 20 ORDER BY name DESC";
+ const parsed = parseSelectQuery(query);
+ expect(parsed.orderByFields).toEqual([{ fieldName: "name", order: "DESC" }]);
+ expect(parsed.whereClauses.length).toBeGreaterThan(0);
+});
+
+test("Parse SQL Query with ORDER BY and GROUP BY", () => {
+ const query =
+ "SELECT COUNT(id), age FROM student GROUP BY age ORDER BY age DESC";
+ const parsed = parseSelectQuery(query);
+ expect(parsed.orderByFields).toEqual([{ fieldName: "age", order: "DESC" }]);
+ expect(parsed.groupByFields).toEqual(["age"]);
+});
+
+test("Parse SQL Query with standard LIMIT clause", () => {
+ const query = "SELECT id, name FROM student LIMIT 2";
+ const parsed = parseSelectQuery(query);
+ expect(parsed.limit).toEqual(2);
+});
+
+test("Parse SQL Query with large number in LIMIT clause", () => {
+ const query = "SELECT id, name FROM student LIMIT 1000";
+ const parsed = parseSelectQuery(query);
+ expect(parsed.limit).toEqual(1000);
+});
+
+test("Parse SQL Query without LIMIT clause", () => {
+ const query = "SELECT id, name FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed.limit).toBeNull();
+});
+
+test("Parse SQL Query with LIMIT 0", () => {
+ const query = "SELECT id, name FROM student LIMIT 0";
+ const parsed = parseSelectQuery(query);
+ expect(parsed.limit).toEqual(0);
+});
+
+test("Parse SQL Query with negative number in LIMIT clause", () => {
+ const query = "SELECT id, name FROM student LIMIT -1";
+ const parsed = parseSelectQuery(query);
+ // Assuming the parser sets limit to null for invalid values
+ expect(parsed.limit).toBeNull();
+});
+
+test("Error Handling with Malformed Query", async () => {
+ const query = "SELECT FROM table"; // intentionally malformed
+ expect(() => parseSelectQuery(query)).toThrow(
+ "Query parsing error: Invalid SELECT format"
+ );
+});
+
+test("Parse SQL Query with Basic DISTINCT", () => {
+ const query = "SELECT DISTINCT age FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age"],
+ table: "student",
+ isDistinct: true,
+ whereClauses: [],
+ groupByFields: null,
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ orderByFields: null,
+ limit: null,
+ hasAggregateWithoutGroupBy: false,
+ });
+});
+
+test("Parse SQL Query with DISTINCT and Multiple Columns", () => {
+ const query = "SELECT DISTINCT student_id, course FROM enrollment";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student_id", "course"],
+ table: "enrollment",
+ isDistinct: true,
+ whereClauses: [],
+ groupByFields: null,
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ orderByFields: null,
+ limit: null,
+ hasAggregateWithoutGroupBy: false,
+ });
+});
+
+test("Parse SQL Query with DISTINCT and WHERE Clause", () => {
+ const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"';
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["course"],
+ table: "enrollment",
+ isDistinct: true,
+ whereClauses: [{ field: "student_id", operator: "=", value: '"1"' }],
+ groupByFields: null,
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ orderByFields: null,
+ limit: null,
+ hasAggregateWithoutGroupBy: false,
+ });
+});
+
+test("Parse SQL Query with DISTINCT and JOIN Operations", () => {
+ const query =
+ "SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student.name"],
+ table: "student",
+ isDistinct: true,
+ whereClauses: [],
+ groupByFields: null,
+ joinType: "INNER",
+ joinTable: "enrollment",
+ joinCondition: {
+ left: "student.id",
+ right: "enrollment.student_id",
+ },
+ orderByFields: null,
+ limit: null,
+ hasAggregateWithoutGroupBy: false,
+ });
+});
+
+test("Parse SQL Query with DISTINCT, ORDER BY, and LIMIT", () => {
+ const query = "SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age"],
+ table: "student",
+ isDistinct: true,
+ whereClauses: [],
+ groupByFields: null,
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ orderByFields: [{ fieldName: "age", order: "DESC" }],
+ limit: 2,
+ hasAggregateWithoutGroupBy: false,
+ });
+});
+
+test("Parse SQL Query with DISTINCT on All Columns", () => {
+ const query = "SELECT DISTINCT * FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["*"],
+ table: "student",
+ isDistinct: true,
+ whereClauses: [],
+ groupByFields: null,
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ orderByFields: null,
+ limit: null,
+ hasAggregateWithoutGroupBy: false,
+ });
+});
+
+test("Parse SQL Query with LIKE Clause", () => {
+ const query = "SELECT name FROM student WHERE name LIKE '%Jane%'";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["name"],
+ table: "student",
+ whereClauses: [{ field: "name", operator: "LIKE", value: "%Jane%" }],
+ isDistinct: false,
+ groupByFields: null,
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ orderByFields: null,
+ limit: null,
+ hasAggregateWithoutGroupBy: false,
+ });
+});
+
+test("Parse SQL Query with LIKE Clause and Wildcards", () => {
+ const query = "SELECT name FROM student WHERE name LIKE 'J%'";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["name"],
+ table: "student",
+ whereClauses: [{ field: "name", operator: "LIKE", value: "J%" }],
+ isDistinct: false,
+ groupByFields: null,
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ orderByFields: null,
+ limit: null,
+ hasAggregateWithoutGroupBy: false,
+ });
+});
+
+test("Parse SQL Query with Multiple LIKE Clauses", () => {
+ const query =
+ "SELECT name FROM student WHERE name LIKE 'J%' AND age LIKE '2%'";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["name"],
+ table: "student",
+ whereClauses: [
+ { field: "name", operator: "LIKE", value: "J%" },
+ { field: "age", operator: "LIKE", value: "2%" },
+ ],
+ isDistinct: false,
+ groupByFields: null,
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ orderByFields: null,
+ limit: null,
+ hasAggregateWithoutGroupBy: false,
+ });
+});
+
+test("Parse SQL Query with LIKE and ORDER BY Clauses", () => {
+ const query =
+ "SELECT name FROM student WHERE name LIKE '%e%' ORDER BY age DESC";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["name"],
+ table: "student",
+ whereClauses: [{ field: "name", operator: "LIKE", value: "%e%" }],
+ orderByFields: [{ fieldName: "age", order: "DESC" }],
+ isDistinct: false,
+ groupByFields: null,
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ limit: null,
+ hasAggregateWithoutGroupBy: false,
+ });
+});
diff --git a/tests/step-02/index.test.js b/tests/step-02/index.test.js
index a5467ee48..6ad3d05eb 100644
--- a/tests/step-02/index.test.js
+++ b/tests/step-02/index.test.js
@@ -1,9 +1,9 @@
-const readCSV = require('../../src/csvReader');
+const { readCSV } = require("../../src/csvReader");
-test('Read CSV File', async () => {
- const data = await readCSV('./sample.csv');
- expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(3);
- expect(data[0].name).toBe('John');
- expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
-});
\ No newline at end of file
+test("Read CSV File", async () => {
+ const data = await readCSV("./student.csv");
+ expect(data.length).toBeGreaterThan(0);
+ expect(data.length).toBe(4);
+ expect(data[0].name).toBe("John");
+ expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later
+});
diff --git a/tests/step-03/index.test.js b/tests/step-03/index.test.js
index 9145ad3e4..7aa439f2a 100644
--- a/tests/step-03/index.test.js
+++ b/tests/step-03/index.test.js
@@ -1,19 +1,34 @@
-const readCSV = require('../../src/csvReader');
-const parseQuery = require('../../src/queryParser');
+const { readCSV } = require("../../src/csvReader");
+const { parseSelectQuery, parseJoinClause } = require("../../src/queryParser");
+const { executeSELECTQuery } = require("../../src/queryExecutor");
-test('Read CSV File', async () => {
- const data = await readCSV('./sample.csv');
- expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(3);
- expect(data[0].name).toBe('John');
- expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
+test("Read CSV File", async () => {
+ const data = await readCSV("./student.csv");
+ expect(data.length).toBeGreaterThan(0);
+ expect(data.length).toBe(4);
+ expect(data[0].name).toBe("John");
+ expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later
});
-test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM sample';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'sample'
- });
-});
\ No newline at end of file
+test("Parse SQL Query", () => {
+ const query = "SELECT id, name FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Invalid SQL Query", () => {
+ const query = "SELEC id FROM student";
+ expect(() => parseSelectQuery(query)).toThrow();
+});
diff --git a/tests/step-04/index.test.js b/tests/step-04/index.test.js
index bc353dd3d..c7f6fce83 100644
--- a/tests/step-04/index.test.js
+++ b/tests/step-04/index.test.js
@@ -1,30 +1,39 @@
-const readCSV = require('../../src/csvReader');
-const parseQuery = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
+const { readCSV } = require("../../src/csvReader");
+const { parseSelectQuery, parseJoinClause } = require("../../src/queryParser");
+const { executeSELECTQuery } = require("../../src/queryExecutor");
-test('Read CSV File', async () => {
- const data = await readCSV('./sample.csv');
- expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(3);
- expect(data[0].name).toBe('John');
- expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
+test("Read CSV File", async () => {
+ const data = await readCSV("./student.csv");
+ expect(data.length).toBeGreaterThan(0);
+ expect(data.length).toBe(4);
+ expect(data[0].name).toBe("John");
+ expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later
});
-test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM sample';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'sample'
- });
+test("Parse SQL Query", () => {
+ const query = "SELECT id, name FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ table: "student",
+ whereClauses: [],
+ limit: null,
+ isDistinct: false,
+ });
});
-test('Execute SQL Query', async () => {
- const query = 'SELECT id, name FROM sample';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBeGreaterThan(0);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0]).not.toHaveProperty('age');
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
\ No newline at end of file
+test("Execute SQL Query", async () => {
+ const query = "SELECT id, name FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBeGreaterThan(0);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0]).not.toHaveProperty("age");
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
diff --git a/tests/step-05/index.test.js b/tests/step-05/index.test.js
index 66a77c061..54e93b2e9 100644
--- a/tests/step-05/index.test.js
+++ b/tests/step-05/index.test.js
@@ -1,50 +1,79 @@
-const readCSV = require('../../src/csvReader');
-const parseQuery = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
+const { readCSV } = require("../../src/csvReader");
+const { parseSelectQuery, parseJoinClause } = require("../../src/queryParser");
+const { executeSELECTQuery } = require("../../src/queryExecutor");
-test('Read CSV File', async () => {
- const data = await readCSV('./sample.csv');
- expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(3);
- expect(data[0].name).toBe('John');
- expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
+test("Read CSV File", async () => {
+ const data = await readCSV("./student.csv");
+ expect(data.length).toBeGreaterThan(0);
+ expect(data.length).toBe(4);
+ expect(data[0].name).toBe("John");
+ expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later
});
-test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM sample';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'sample',
- whereClause: null
- });
+test("Parse SQL Query", () => {
+ const query = "SELECT id, name FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ limit: null,
+ isDistinct: false,
+ });
});
-test('Execute SQL Query', async () => {
- const query = 'SELECT id, name FROM sample';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBeGreaterThan(0);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0]).not.toHaveProperty('age');
- expect(result[0]).toEqual({ id: '1', name: 'John' });
+test("Execute SQL Query", async () => {
+ const query = "SELECT id, name FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBeGreaterThan(0);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0]).not.toHaveProperty("age");
+ expect(result[0]).toEqual({ id: "1", name: "John" });
});
-test('Parse SQL Query with WHERE Clause', () => {
- const query = 'SELECT id, name FROM sample WHERE age = 25';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'sample',
- whereClause: 'age = 25'
- });
+test("Parse SQL Query with WHERE Clause", () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "25",
+ },
+ ],
+ limit: null,
+ isDistinct: false,
+ });
});
-test('Execute SQL Query with WHERE Clause', async () => {
- const query = 'SELECT id, name FROM sample WHERE age = 25';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0].id).toBe('2');
-});
\ No newline at end of file
+test("Execute SQL Query with WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0].id).toBe("2");
+});
+
+// check if case sensitive
+test("Case Sensitivity Check", async () => {
+ const query = "SELECT id, name FROM student WHERE name = john";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(0);
+});
diff --git a/tests/step-06/index.test.js b/tests/step-06/index.test.js
index 2e2ef6416..a264d4cea 100644
--- a/tests/step-06/index.test.js
+++ b/tests/step-06/index.test.js
@@ -1,79 +1,115 @@
-const readCSV = require('../../src/csvReader');
-const parseQuery = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
+const { readCSV } = require("../../src/csvReader");
+const { parseSelectQuery, parseJoinClause } = require("../../src/queryParser");
+const { executeSELECTQuery } = require("../../src/queryExecutor");
-test('Read CSV File', async () => {
- const data = await readCSV('./sample.csv');
- expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(3);
- expect(data[0].name).toBe('John');
- expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
+test("Read CSV File", async () => {
+ const data = await readCSV("./student.csv");
+ expect(data.length).toBeGreaterThan(0);
+ expect(data.length).toBe(4);
+ expect(data[0].name).toBe("John");
+ expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later
});
-test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM sample';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'sample',
- whereClauses: []
- });
+test("Parse SQL Query", () => {
+ const query = "SELECT id, name FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ limit: null,
+ isDistinct: false,
+ });
});
-test('Execute SQL Query', async () => {
- const query = 'SELECT id, name FROM sample';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBeGreaterThan(0);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0]).not.toHaveProperty('age');
- expect(result[0]).toEqual({ id: '1', name: 'John' });
+test("Execute SQL Query", async () => {
+ const query = "SELECT id, name FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBeGreaterThan(0);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0]).not.toHaveProperty("age");
+ expect(result[0]).toEqual({ id: "1", name: "John" });
});
-test('Parse SQL Query with WHERE Clause', () => {
- const query = 'SELECT id, name FROM sample WHERE age = 25';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'sample',
- whereClauses: [{
- field: "age",
- operator: "=",
- value: "25",
- }],
- });
+test("Parse SQL Query with WHERE Clause", () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "25",
+ },
+ ],
+ limit: null,
+ isDistinct: false,
+ });
});
-test('Execute SQL Query with WHERE Clause', async () => {
- const query = 'SELECT id, name FROM sample WHERE age = 25';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0].id).toBe('2');
+test("Execute SQL Query with WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0].id).toBe("2");
});
-test('Parse SQL Query with Multiple WHERE Clauses', () => {
- const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'sample',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "30",
- }, {
- "field": "name",
- "operator": "=",
- "value": "John",
- }]
- });
+test("Parse SQL Query with Multiple WHERE Clauses", () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "30",
+ },
+ {
+ field: "name",
+ operator: "=",
+ value: "John",
+ },
+ ],
+ limit: null,
+ isDistinct: false,
+ });
});
-test('Execute SQL Query with Multiple WHERE Clause', async () => {
- const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
\ No newline at end of file
+test("Execute SQL Query with Multiple WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Invalid Where Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age 30 AND name = John";
+ expect(() => {
+ parseSelectQuery(query);
+ }).toThrowError("Invalid WHERE clause format");
+});
diff --git a/tests/step-07/index.test.js b/tests/step-07/index.test.js
index ee0ebed5e..aaa243eeb 100644
--- a/tests/step-07/index.test.js
+++ b/tests/step-07/index.test.js
@@ -1,93 +1,170 @@
-const readCSV = require('../../src/csvReader');
-const parseQuery = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
+const { readCSV } = require("../../src/csvReader");
+const { parseSelectQuery, parseJoinClause } = require("../../src/queryParser");
+const { executeSELECTQuery } = require("../../src/queryExecutor");
-test('Read CSV File', async () => {
- const data = await readCSV('./sample.csv');
- expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(3);
- expect(data[0].name).toBe('John');
- expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
+test("Read CSV File", async () => {
+ const data = await readCSV("./student.csv");
+ expect(data.length).toBeGreaterThan(0);
+ expect(data.length).toBe(4);
+ expect(data[0].name).toBe("John");
+ expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later
});
-test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM sample';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'sample',
- whereClauses: []
- });
+test("Parse SQL Query", () => {
+ const query = "SELECT id, name FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ limit: null,
+ isDistinct: false,
+ });
});
-test('Execute SQL Query', async () => {
- const query = 'SELECT id, name FROM sample';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBeGreaterThan(0);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0]).not.toHaveProperty('age');
- expect(result[0]).toEqual({ id: '1', name: 'John' });
+test("Execute SQL Query", async () => {
+ const query = "SELECT id, name FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBeGreaterThan(0);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0]).not.toHaveProperty("age");
+ expect(result[0]).toEqual({ id: "1", name: "John" });
});
-test('Parse SQL Query with WHERE Clause', () => {
- const query = 'SELECT id, name FROM sample WHERE age = 25';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'sample',
- whereClauses: [{
- field: "age",
- operator: "=",
- value: "25",
- }],
- });
+test("Parse SQL Query with WHERE Clause", () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "25",
+ },
+ ],
+ limit: null,
+ isDistinct: false,
+ });
});
-test('Execute SQL Query with WHERE Clause', async () => {
- const query = 'SELECT id, name FROM sample WHERE age = 25';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0].id).toBe('2');
+test("Execute SQL Query with WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0].id).toBe("2");
});
-test('Parse SQL Query with Multiple WHERE Clauses', () => {
- const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'sample',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "30",
- }, {
- "field": "name",
- "operator": "=",
- "value": "John",
- }]
- });
+test("Parse SQL Query with Multiple WHERE Clauses", () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "30",
+ },
+ {
+ field: "name",
+ operator: "=",
+ value: "John",
+ },
+ ],
+ limit: null,
+ isDistinct: false,
+ });
});
-test('Execute SQL Query with Multiple WHERE Clause', async () => {
- const query = 'SELECT id, name FROM sample WHERE age = 30 AND name = John';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toEqual({ id: '1', name: 'John' });
+test("Execute SQL Query with Multiple WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toEqual({ id: "1", name: "John" });
});
-test('Execute SQL Query with Greater Than', async () => {
- const queryWithGT = 'SELECT id FROM sample WHERE age > 22';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(2);
- expect(result[0]).toHaveProperty('id');
+test("Execute SQL Query with Greater Than", async () => {
+ const queryWithGT = "SELECT id FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("id");
});
-test('Execute SQL Query with Not Equal to', async () => {
- const queryWithGT = 'SELECT name FROM sample WHERE age != 25';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(2);
- expect(result[0]).toHaveProperty('name');
-});
\ No newline at end of file
+test("Execute SQL Query with Not Equal to", async () => {
+ const queryWithGT = "SELECT name FROM student WHERE age != 25";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("name");
+});
+
+test("Execute SQL Query with unsupported operator", async () => {
+ const query = "SELECT name FROM student WHERE age <> 22";
+ const parsedQuery = parseSelectQuery(query);
+ expect(parsedQuery).toEqual({
+ fields: ["name"],
+ table: "student",
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ whereClauses: [
+ {
+ field: "age",
+ operator: "<",
+ value: "> 22",
+ },
+ ],
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Execute SQL Query with incomplete WHERE Clause", async () => {
+ const query = "SELECT id FROM student WHERE age > 22 AND";
+ const parsedQuery = parseSelectQuery(query);
+ expect(parsedQuery).toEqual({
+ fields: ["id"],
+ table: "student",
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ whereClauses: [
+ {
+ field: "age",
+ operator: ">",
+ value: "22 AND",
+ },
+ ],
+ limit: null,
+ isDistinct: false,
+ });
+});
diff --git a/tests/step-08/index.test.js b/tests/step-08/index.test.js
index aab1467e6..940a9f2a8 100644
--- a/tests/step-08/index.test.js
+++ b/tests/step-08/index.test.js
@@ -1,131 +1,169 @@
-const readCSV = require('../../src/csvReader');
-const parseQuery = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
+const { readCSV } = require("../../src/csvReader");
+const { parseSelectQuery, parseJoinClause } = require("../../src/queryParser");
+const { executeSELECTQuery } = require("../../src/queryExecutor");
-test('Read CSV File', async () => {
- const data = await readCSV('./student.csv');
- expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(3);
- expect(data[0].name).toBe('John');
- expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
+test("Read CSV File", async () => {
+ const data = await readCSV("./student.csv");
+ expect(data.length).toBeGreaterThan(0);
+ expect(data.length).toBe(4);
+ expect(data[0].name).toBe("John");
+ expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later
});
-test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [],
- joinCondition: null,
- joinTable: null
- });
+test("Parse SQL Query", () => {
+ const query = "SELECT id, name FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ limit: null,
+ isDistinct: false,
+ });
});
-test('Execute SQL Query', async () => {
- const query = 'SELECT id, name FROM student';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBeGreaterThan(0);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0]).not.toHaveProperty('age');
- expect(result[0]).toEqual({ id: '1', name: 'John' });
+test("Execute SQL Query", async () => {
+ const query = "SELECT id, name FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBeGreaterThan(0);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0]).not.toHaveProperty("age");
+ expect(result[0]).toEqual({ id: "1", name: "John" });
});
-test('Parse SQL Query with WHERE Clause', () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "25",
- }],
- joinCondition: null,
- joinTable: null
- });
+test("Parse SQL Query with WHERE Clause", () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "25",
+ },
+ ],
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ limit: null,
+ isDistinct: false,
+ });
});
-test('Execute SQL Query with WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0].id).toBe('2');
+test("Execute SQL Query with WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0].id).toBe("2");
});
-test('Parse SQL Query with Multiple WHERE Clauses', () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "30",
- }, {
- "field": "name",
- "operator": "=",
- "value": "John",
- }],
- joinCondition: null,
- joinTable: null
- });
+test("Parse SQL Query with Multiple WHERE Clauses", () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "30",
+ },
+ {
+ field: "name",
+ operator: "=",
+ value: "John",
+ },
+ ],
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ limit: null,
+ isDistinct: false,
+ });
});
-test('Execute SQL Query with Complex WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toEqual({ id: '1', name: 'John' });
+test("Execute SQL Query with Complex WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toEqual({ id: "1", name: "John" });
});
-test('Execute SQL Query with Greater Than', async () => {
- const queryWithGT = 'SELECT id FROM student WHERE age > 22';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(2);
- expect(result[0]).toHaveProperty('id');
+test("Execute SQL Query with Greater Than", async () => {
+ const queryWithGT = "SELECT id FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("id");
});
-test('Execute SQL Query with Not Equal to', async () => {
- const queryWithGT = 'SELECT name FROM student WHERE age != 25';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(2);
- expect(result[0]).toHaveProperty('name');
+test("Execute SQL Query with Not Equal to", async () => {
+ const queryWithGT = "SELECT name FROM student WHERE age != 25";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("name");
});
-test('Parse SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' }
- })
+test("Parse SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ joinType: "INNER",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ limit: null,
+ isDistinct: false,
+ });
});
-test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [{ field: 'student.age', operator: '>', value: '20' }],
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' }
- })
+test("Parse SQL Query with INNER JOIN and WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "20" }],
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ joinType: "INNER",
+ limit: null,
+ isDistinct: false,
+ });
});
-test('Execute SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- /*
+test("Execute SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{ 'student.name': 'John', 'enrollment.course': 'Mathematics' },
{ 'student.name': 'John', 'enrollment.course': 'Physics' },
@@ -133,18 +171,21 @@ test('Execute SQL Query with INNER JOIN', async () => {
{ 'student.name': 'Bob', 'enrollment.course': 'Mathematics' }
]
*/
- expect(result.length).toEqual(4);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
+ expect(result.length).toEqual(4);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ })
+ );
});
-test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25';
- const result = await executeSELECTQuery(query);
- /*
+test("Execute SQL Query with INNER JOIN and a WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{
'student.name': 'John',
@@ -158,10 +199,12 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
}
]
*/
- expect(result.length).toEqual(2);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
-});
\ No newline at end of file
+ expect(result.length).toEqual(2);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ })
+ );
+});
diff --git a/tests/step-09/index.test.js b/tests/step-09/index.test.js
index aaf711f5a..b4b71bcf4 100644
--- a/tests/step-09/index.test.js
+++ b/tests/step-09/index.test.js
@@ -1,136 +1,169 @@
-const readCSV = require('../../src/csvReader');
-const {parseQuery} = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
-
-test('Read CSV File', async () => {
- const data = await readCSV('./student.csv');
- expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(4);
- expect(data[0].name).toBe('John');
- expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
-});
-
-test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [],
- joinCondition: null,
- joinTable: null,
- joinType: null
- });
-});
-
-test('Execute SQL Query', async () => {
- const query = 'SELECT id, name FROM student';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBeGreaterThan(0);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0]).not.toHaveProperty('age');
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Parse SQL Query with WHERE Clause', () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "25",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null
- });
-});
-
-test('Execute SQL Query with WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0].id).toBe('2');
-});
-
-test('Parse SQL Query with Multiple WHERE Clauses', () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "30",
- }, {
- "field": "name",
- "operator": "=",
- "value": "John",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null
- });
-});
-
-test('Execute SQL Query with Complex WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with Greater Than', async () => {
- const queryWithGT = 'SELECT id FROM student WHERE age > 22';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('id');
-});
-
-test('Execute SQL Query with Not Equal to', async () => {
- const queryWithGT = 'SELECT name FROM student WHERE age != 25';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('name');
-});
-
-test('Parse SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- joinType: 'INNER'
- })
+const { readCSV } = require("../../src/csvReader");
+const { parseSelectQuery, parseJoinClause } = require("../../src/queryParser");
+const { executeSELECTQuery } = require("../../src/queryExecutor");
+
+test("Read CSV File", async () => {
+ const data = await readCSV("./student.csv");
+ expect(data.length).toBeGreaterThan(0);
+ expect(data.length).toBe(4);
+ expect(data[0].name).toBe("John");
+ expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later
});
-test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [{ field: 'student.age', operator: '>', value: '20' }],
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- joinType: 'INNER'
- })
+test("Parse SQL Query", () => {
+ const query = "SELECT id, name FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Execute SQL Query", async () => {
+ const query = "SELECT id, name FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBeGreaterThan(0);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0]).not.toHaveProperty("age");
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Parse SQL Query with WHERE Clause", () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "25",
+ },
+ ],
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ joinCondition: null,
+ joinTable: null,
+ isDistinct: false,
+ joinType: null,
+ limit: null,
+ });
+});
+
+test("Execute SQL Query with WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0].id).toBe("2");
+});
+
+test("Parse SQL Query with Multiple WHERE Clauses", () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "30",
+ },
+ {
+ field: "name",
+ operator: "=",
+ value: "John",
+ },
+ ],
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ isDistinct: false,
+ limit: null,
+ });
+});
+
+test("Execute SQL Query with Complex WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with Greater Than", async () => {
+ const queryWithGT = "SELECT id FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("id");
+});
+
+test("Execute SQL Query with Not Equal to", async () => {
+ const queryWithGT = "SELECT name FROM student WHERE age != 25";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("name");
});
-test('Execute SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- /*
+test("Parse SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinType: "INNER",
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN and WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "20" }],
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinType: "INNER",
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Execute SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{ 'student.name': 'John', 'enrollment.course': 'Mathematics' },
{ 'student.name': 'John', 'enrollment.course': 'Physics' },
@@ -138,18 +171,21 @@ test('Execute SQL Query with INNER JOIN', async () => {
{ 'student.name': 'Bob', 'enrollment.course': 'Mathematics' }
]
*/
- expect(result.length).toEqual(4);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
+ expect(result.length).toEqual(4);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ })
+ );
});
-test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25';
- const result = await executeSELECTQuery(query);
- /*
+test("Execute SQL Query with INNER JOIN and a WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{
'student.name': 'John',
@@ -163,30 +199,108 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
}
]
*/
- expect(result.length).toEqual(2);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
+ expect(result.length).toEqual(2);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ })
+ );
+});
+
+test("Execute SQL Query with LEFT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "Alice",
+ "enrollment.course": null,
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 students, but John appears twice
+});
+
+test("Execute SQL Query with LEFT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "Alice",
+ "enrollment.course": null,
+ }),
+ expect.objectContaining({
+ "student.name": "John",
"enrollment.course": "Mathematics",
- "student.name": "John"
- }));
-});
-
-test('Execute SQL Query with LEFT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "Alice", "enrollment.course": null }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 students, but John appears twice
-});
-
-test('Execute SQL Query with LEFT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "Alice", "enrollment.course": null }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 students, but John appears twice
-});
\ No newline at end of file
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 students, but John appears twice
+});
+
+test("Execute SQL Query with RIGHT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": null,
+ "enrollment.course": "Biology",
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "Bob",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Biology",
+ "student.name": null,
+ }),
+ ])
+ );
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Chemistry",
+ "student.name": "Jane",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+test("Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([]);
+});
diff --git a/tests/step-10/index.test.js b/tests/step-10/index.test.js
index 5e118eda5..6cd47c85a 100644
--- a/tests/step-10/index.test.js
+++ b/tests/step-10/index.test.js
@@ -1,59 +1,60 @@
-const readCSV = require('../../src/csvReader');
-const {parseQuery, parseJoinClause} = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
-
-test('Read CSV File', async () => {
- const data = await readCSV('./student.csv');
- expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(4);
- expect(data[0].name).toBe('John');
- expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
-});
-
-test('Execute SQL Query', async () => {
- const query = 'SELECT id, name FROM student';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBeGreaterThan(0);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0]).not.toHaveProperty('age');
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0].id).toBe('2');
-});
-
-test('Execute SQL Query with Complex WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with Greater Than', async () => {
- const queryWithGT = 'SELECT id FROM student WHERE age > 22';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('id');
-});
-
-test('Execute SQL Query with Not Equal to', async () => {
- const queryWithGT = 'SELECT name FROM student WHERE age != 25';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('name');
-});
-
-test('Execute SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- /*
+const { readCSV } = require("../../src/csvReader");
+const { parseSelectQuery, parseJoinClause } = require("../../src/queryParser");
+const { executeSELECTQuery } = require("../../src/queryExecutor");
+
+test("Read CSV File", async () => {
+ const data = await readCSV("./student.csv");
+ expect(data.length).toBeGreaterThan(0);
+ expect(data.length).toBe(4);
+ expect(data[0].name).toBe("John");
+ expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later
+});
+
+test("Execute SQL Query", async () => {
+ const query = "SELECT id, name FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBeGreaterThan(0);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0]).not.toHaveProperty("age");
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0].id).toBe("2");
+});
+
+test("Execute SQL Query with Complex WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with Greater Than", async () => {
+ const queryWithGT = "SELECT id FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("id");
+});
+
+test("Execute SQL Query with Not Equal to", async () => {
+ const queryWithGT = "SELECT name FROM student WHERE age != 25";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("name");
+});
+
+test("Execute SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{ 'student.name': 'John', 'enrollment.course': 'Mathematics' },
{ 'student.name': 'John', 'enrollment.course': 'Physics' },
@@ -61,18 +62,21 @@ test('Execute SQL Query with INNER JOIN', async () => {
{ 'student.name': 'Bob', 'enrollment.course': 'Mathematics' }
]
*/
- expect(result.length).toEqual(4);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
+ expect(result.length).toEqual(4);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ })
+ );
});
-test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25';
- const result = await executeSELECTQuery(query);
- /*
+test("Execute SQL Query with INNER JOIN and a WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{
'student.name': 'John',
@@ -86,531 +90,655 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
}
]
*/
- expect(result.length).toEqual(2);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
-});
-
-test('Execute SQL Query with LEFT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "Alice", "enrollment.course": null }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 students, but John appears twice
-});
-
-test('Execute SQL Query with RIGHT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": null, "enrollment.course": "Biology" }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
-});
-
-test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "John" }),
- expect.objectContaining({ "enrollment.course": "Physics", "student.name": "John" })
- ]));
- expect(result.length).toEqual(4);
-});
-
-test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Physics" })
- ]));
- expect(result.length).toEqual(1);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "Bob" }),
- expect.objectContaining({ "enrollment.course": "Biology", "student.name": null })
- ]));
- expect(result.length).toEqual(2);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Chemistry", "student.name": "Jane" }),
- ]));
- expect(result.length).toEqual(1);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([]);
-});
-
-test('Execute COUNT Aggregate Query', async () => {
- const query = 'SELECT COUNT(*) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'COUNT(*)': 4 }]);
-});
-
-test('Execute SUM Aggregate Query', async () => {
- const query = 'SELECT SUM(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'SUM(age)': 101 }]);
-});
-
-test('Execute AVG Aggregate Query', async () => {
- const query = 'SELECT AVG(age) FROM student';
- const result = await executeSELECTQuery(query);
- // Assuming AVG returns a single decimal point value
- expect(result).toEqual([{ 'AVG(age)': 25.25 }]);
-});
-
-test('Execute MIN Aggregate Query', async () => {
- const query = 'SELECT MIN(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'MIN(age)': 22 }]);
-});
-
-test('Execute MAX Aggregate Query', async () => {
- const query = 'SELECT MAX(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'MAX(age)': 30 }]);
-});
-
-test('Count students per age', async () => {
- const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { age: '22', 'COUNT(*)': 1 },
- { age: '24', 'COUNT(*)': 1 },
- { age: '25', 'COUNT(*)': 1 },
- { age: '30', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count enrollments per course', async () => {
- const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { course: 'Mathematics', 'COUNT(*)': 2 },
- { course: 'Physics', 'COUNT(*)': 1 },
- { course: 'Chemistry', 'COUNT(*)': 1 },
- { course: 'Biology', 'COUNT(*)': 1 }
- ]);
-});
-
-
-test('Count courses per student', async () => {
- const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { student_id: '1', 'COUNT(*)': 2 },
- { student_id: '2', 'COUNT(*)': 1 },
- { student_id: '3', 'COUNT(*)': 1 },
- { student_id: '5', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count students within a specific age range', async () => {
- const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { age: '24', 'COUNT(*)': 1 },
- { age: '25', 'COUNT(*)': 1 },
- { age: '30', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count enrollments for a specific course', async () => {
- const query = 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { course: 'Mathematics', 'COUNT(*)': 2 }
- ]);
-});
-
-test('Count courses for a specific student', async () => {
- const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { student_id: '1', 'COUNT(*)': 2 }
- ]);
-});
-
-test('Average age of students above a certain age', async () => {
- const query = 'SELECT AVG(age) FROM student WHERE age > 22';
- const result = await executeSELECTQuery(query);
- const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
- expect(result).toEqual([{ 'AVG(age)': expectedAverage }]);
-});
-
-test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- });
-});
-
-test('Parse SQL Query with WHERE Clause', () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "25",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- });
-});
-
-test('Parse SQL Query with Multiple WHERE Clauses', () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "30",
- }, {
- "field": "name",
- "operator": "=",
- "value": "John",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- });
-});
-
-test('Parse SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinTable: 'enrollment',
- joinType: "INNER",
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- })
-});
-
-test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [{ field: 'student.age', operator: '>', value: '20' }],
- joinTable: 'enrollment',
- joinType: "INNER",
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
+ expect(result.length).toEqual(2);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
})
+ );
+});
+
+test("Execute SQL Query with LEFT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "Alice",
+ "enrollment.course": null,
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 students, but John appears twice
+});
+
+test("Execute SQL Query with RIGHT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": null,
+ "enrollment.course": "Biology",
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Physics",
+ "student.name": "John",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(4);
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Physics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "Bob",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Biology",
+ "student.name": null,
+ }),
+ ])
+ );
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Chemistry",
+ "student.name": "Jane",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([]);
+});
+
+test("Execute COUNT Aggregate Query", async () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "COUNT(*)": 4 }]);
+});
+
+test("Execute SUM Aggregate Query", async () => {
+ const query = "SELECT SUM(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "SUM(age)": 101 }]);
+});
+
+test("Execute AVG Aggregate Query", async () => {
+ const query = "SELECT AVG(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ // Assuming AVG returns a single decimal point value
+ expect(result).toEqual([{ "AVG(age)": 25.25 }]);
+});
+
+test("Execute MIN Aggregate Query", async () => {
+ const query = "SELECT MIN(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MIN(age)": 22 }]);
+});
+
+test("Execute MAX Aggregate Query", async () => {
+ const query = "SELECT MAX(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MAX(age)": 30 }]);
+});
+
+test("Count students per age", async () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "22", "COUNT(*)": 1 },
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments per course", async () => {
+ const query = "SELECT course, COUNT(*) FROM enrollment GROUP BY course";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { course: "Mathematics", "COUNT(*)": 2 },
+ { course: "Physics", "COUNT(*)": 1 },
+ { course: "Chemistry", "COUNT(*)": 1 },
+ { course: "Biology", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count courses per student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { student_id: "1", "COUNT(*)": 2 },
+ { student_id: "2", "COUNT(*)": 1 },
+ { student_id: "3", "COUNT(*)": 1 },
+ { student_id: "5", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count students within a specific age range", async () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments for a specific course", async () => {
+ const query =
+ 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ course: "Mathematics", "COUNT(*)": 2 }]);
+});
+
+test("Count courses for a specific student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ student_id: "1", "COUNT(*)": 2 }]);
+});
+
+test("Average age of students above a certain age", async () => {
+ const query = "SELECT AVG(age) FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(query);
+ const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
+ expect(result).toEqual([{ "AVG(age)": expectedAverage }]);
+});
+
+test("Parse SQL Query", () => {
+ const query = "SELECT id, name FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with WHERE Clause", () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "25",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with Multiple WHERE Clauses", () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "30",
+ },
+ {
+ field: "name",
+ operator: "=",
+ value: "John",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN and WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "20" }],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse INNER JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "INNER",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse LEFT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "LEFT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse RIGHT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "RIGHT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Returns null for queries without JOIN", () => {
+ const query = "SELECT * FROM table1";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "LEFT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "RIGHT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "22" }],
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Physics'" },
+ ],
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: "<", value: "25" }],
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Chemistry'" },
+ ],
+ groupByFields: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse COUNT Aggregate Query", () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ orderByFields: null,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SUM Aggregate Query", () => {
+ const query = "SELECT SUM(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["SUM(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ orderByFields: null,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse AVG Aggregate Query", () => {
+ const query = "SELECT AVG(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["AVG(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ orderByFields: null,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MIN Aggregate Query", () => {
+ const query = "SELECT MIN(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MIN(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ orderByFields: null,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MAX Aggregate Query", () => {
+ const query = "SELECT MAX(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MAX(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ orderByFields: null,
+ joinType: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse basic GROUP BY query", () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with WHERE clause", () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [{ field: "age", operator: ">", value: "22" }],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with multiple fields", () => {
+ const query =
+ "SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student_id", "course", "COUNT(*)"],
+ table: "enrollment",
+ whereClauses: [],
+ groupByFields: ["student_id", "course"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ orderByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with JOIN and WHERE clauses", () => {
+ const query =
+ 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student.name", "COUNT(*)"],
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: '"Mathematics"' },
+ ],
+ groupByFields: ["student.name"],
+ joinType: "INNER",
+ joinTable: "enrollment",
+ joinCondition: {
+ left: "student.id",
+ right: "enrollment.student_id",
+ },
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
});
-
-test('Parse INNER JOIN clause', () => {
- const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'INNER',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' },
- });
-});
-
-test('Parse LEFT JOIN clause', () => {
- const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'LEFT',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' }
- });
-});
-
-test('Parse RIGHT JOIN clause', () => {
- const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'RIGHT',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' }
- });
-});
-
-test('Returns null for queries without JOIN', () => {
- const query = 'SELECT * FROM table1';
- const result = parseJoinClause(query);
- expect(result).toEqual(
- {
- joinType: null,
- joinTable: null,
- joinCondition: null
- }
- );
-});
-
-test('Parse LEFT Join Query Completely', () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinType: 'LEFT',
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- })
-})
-
-test('Parse LEFT Join Query Completely', () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinType: 'RIGHT',
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- })
-})
-
-test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "LEFT",
- "table": "student",
- "whereClauses": [{ "field": "student.age", "operator": ">", "value": "22" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- });
-});
-
-test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "LEFT",
- "table": "student",
- "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Physics'" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- });
-});
-
-test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "RIGHT",
- "table": "student",
- "whereClauses": [{ "field": "student.age", "operator": "<", "value": "25" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- });
-});
-
-test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "RIGHT",
- "table": "student",
- "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Chemistry'" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- });
-});
-
-
-test('Parse COUNT Aggregate Query', () => {
- const query = 'SELECT COUNT(*) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['COUNT(*)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- });
-});
-
-
-test('Parse SUM Aggregate Query', () => {
- const query = 'SELECT SUM(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['SUM(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- });
-});
-
-test('Parse AVG Aggregate Query', () => {
- const query = 'SELECT AVG(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['AVG(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- });
-});
-
-test('Parse MIN Aggregate Query', () => {
- const query = 'SELECT MIN(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['MIN(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- });
-});
-
-test('Parse MAX Aggregate Query', () => {
- const query = 'SELECT MAX(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['MAX(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- });
-});
-
-test('Parse basic GROUP BY query', () => {
- const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['age', 'COUNT(*)'],
- table: 'student',
- whereClauses: [],
- groupByFields: ['age'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false
- });
-});
-
-test('Parse GROUP BY query with WHERE clause', () => {
- const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['age', 'COUNT(*)'],
- table: 'student',
- whereClauses: [{ field: 'age', operator: '>', value: '22' }],
- groupByFields: ['age'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false
- });
-});
-
-test('Parse GROUP BY query with multiple fields', () => {
- const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['student_id', 'course', 'COUNT(*)'],
- table: 'enrollment',
- whereClauses: [],
- groupByFields: ['student_id', 'course'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false
- });
-});
-
-test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
- const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['student.name', 'COUNT(*)'],
- table: 'student',
- whereClauses: [{ field: 'enrollment.course', operator: '=', value: '"Mathematics"' }],
- groupByFields: ['student.name'],
- joinType: 'INNER',
- joinTable: 'enrollment',
- joinCondition: {
- left: 'student.id',
- right: 'enrollment.student_id'
- },
- hasAggregateWithoutGroupBy: false
- });
-});
\ No newline at end of file
diff --git a/tests/step-11/index.test.js b/tests/step-11/index.test.js
index 1cf5f2def..5b39bb88f 100644
--- a/tests/step-11/index.test.js
+++ b/tests/step-11/index.test.js
@@ -1,59 +1,60 @@
-const readCSV = require('../../src/csvReader');
-const {parseQuery, parseJoinClause} = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
-
-test('Read CSV File', async () => {
- const data = await readCSV('./student.csv');
- expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(4);
- expect(data[0].name).toBe('John');
- expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
-});
-
-test('Execute SQL Query', async () => {
- const query = 'SELECT id, name FROM student';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBeGreaterThan(0);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0]).not.toHaveProperty('age');
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0].id).toBe('2');
-});
-
-test('Execute SQL Query with Complex WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with Greater Than', async () => {
- const queryWithGT = 'SELECT id FROM student WHERE age > 22';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('id');
-});
-
-test('Execute SQL Query with Not Equal to', async () => {
- const queryWithGT = 'SELECT name FROM student WHERE age != 25';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('name');
-});
-
-test('Execute SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- /*
+const { readCSV } = require("../../src/csvReader");
+const { parseSelectQuery, parseJoinClause } = require("../../src/queryParser");
+const { executeSELECTQuery } = require("../../src/queryExecutor");
+
+test("Read CSV File", async () => {
+ const data = await readCSV("./student.csv");
+ expect(data.length).toBeGreaterThan(0);
+ expect(data.length).toBe(4);
+ expect(data[0].name).toBe("John");
+ expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later
+});
+
+test("Execute SQL Query", async () => {
+ const query = "SELECT id, name FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBeGreaterThan(0);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0]).not.toHaveProperty("age");
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0].id).toBe("2");
+});
+
+test("Execute SQL Query with Complex WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with Greater Than", async () => {
+ const queryWithGT = "SELECT id FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("id");
+});
+
+test("Execute SQL Query with Not Equal to", async () => {
+ const queryWithGT = "SELECT name FROM student WHERE age != 25";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("name");
+});
+
+test("Execute SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{ 'student.name': 'John', 'enrollment.course': 'Mathematics' },
{ 'student.name': 'John', 'enrollment.course': 'Physics' },
@@ -61,18 +62,21 @@ test('Execute SQL Query with INNER JOIN', async () => {
{ 'student.name': 'Bob', 'enrollment.course': 'Mathematics' }
]
*/
- expect(result.length).toEqual(4);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
+ expect(result.length).toEqual(4);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ })
+ );
});
-test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25';
- const result = await executeSELECTQuery(query);
- /*
+test("Execute SQL Query with INNER JOIN and a WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{
'student.name': 'John',
@@ -86,584 +90,706 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
}
]
*/
- expect(result.length).toEqual(2);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
-});
-
-test('Execute SQL Query with LEFT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "Alice", "enrollment.course": null }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 students, but John appears twice
-});
-
-test('Execute SQL Query with RIGHT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": null, "enrollment.course": "Biology" }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
-});
-
-test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "John" }),
- expect.objectContaining({ "enrollment.course": "Physics", "student.name": "John" })
- ]));
- expect(result.length).toEqual(4);
-});
-
-test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Physics" })
- ]));
- expect(result.length).toEqual(1);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "Bob" }),
- expect.objectContaining({ "enrollment.course": "Biology", "student.name": null })
- ]));
- expect(result.length).toEqual(2);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Chemistry", "student.name": "Jane" }),
- ]));
- expect(result.length).toEqual(1);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([]);
-});
-
-test('Execute COUNT Aggregate Query', async () => {
- const query = 'SELECT COUNT(*) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'COUNT(*)': 4 }]);
-});
-
-test('Execute SUM Aggregate Query', async () => {
- const query = 'SELECT SUM(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'SUM(age)': 101 }]);
-});
-
-test('Execute AVG Aggregate Query', async () => {
- const query = 'SELECT AVG(age) FROM student';
- const result = await executeSELECTQuery(query);
- // Assuming AVG returns a single decimal point value
- expect(result).toEqual([{ 'AVG(age)': 25.25 }]);
-});
-
-test('Execute MIN Aggregate Query', async () => {
- const query = 'SELECT MIN(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'MIN(age)': 22 }]);
-});
-
-test('Execute MAX Aggregate Query', async () => {
- const query = 'SELECT MAX(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'MAX(age)': 30 }]);
-});
-
-test('Count students per age', async () => {
- const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { age: '22', 'COUNT(*)': 1 },
- { age: '24', 'COUNT(*)': 1 },
- { age: '25', 'COUNT(*)': 1 },
- { age: '30', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count enrollments per course', async () => {
- const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { course: 'Mathematics', 'COUNT(*)': 2 },
- { course: 'Physics', 'COUNT(*)': 1 },
- { course: 'Chemistry', 'COUNT(*)': 1 },
- { course: 'Biology', 'COUNT(*)': 1 }
- ]);
-});
-
-
-test('Count courses per student', async () => {
- const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { student_id: '1', 'COUNT(*)': 2 },
- { student_id: '2', 'COUNT(*)': 1 },
- { student_id: '3', 'COUNT(*)': 1 },
- { student_id: '5', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count students within a specific age range', async () => {
- const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { age: '24', 'COUNT(*)': 1 },
- { age: '25', 'COUNT(*)': 1 },
- { age: '30', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count enrollments for a specific course', async () => {
- const query = 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { course: 'Mathematics', 'COUNT(*)': 2 }
- ]);
-});
-
-test('Count courses for a specific student', async () => {
- const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { student_id: '1', 'COUNT(*)': 2 }
- ]);
-});
-
-test('Average age of students above a certain age', async () => {
- const query = 'SELECT AVG(age) FROM student WHERE age > 22';
- const result = await executeSELECTQuery(query);
- const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
- expect(result).toEqual([{ 'AVG(age)': expectedAverage }]);
-});
-
-test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null
- });
-});
-
-test('Parse SQL Query with WHERE Clause', () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "25",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null
- });
-});
-
-test('Parse SQL Query with Multiple WHERE Clauses', () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "30",
- }, {
- "field": "name",
- "operator": "=",
- "value": "John",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null
- });
-});
-
-test('Parse SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinTable: 'enrollment',
- joinType: "INNER",
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null
- })
-});
-
-test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [{ field: 'student.age', operator: '>', value: '20' }],
- joinTable: 'enrollment',
- joinType: "INNER",
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null
+ expect(result.length).toEqual(2);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
})
+ );
+});
+
+test("Execute SQL Query with LEFT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "Alice",
+ "enrollment.course": null,
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 students, but John appears twice
+});
+
+test("Execute SQL Query with RIGHT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": null,
+ "enrollment.course": "Biology",
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Physics",
+ "student.name": "John",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(4);
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Physics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "Bob",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Biology",
+ "student.name": null,
+ }),
+ ])
+ );
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Chemistry",
+ "student.name": "Jane",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([]);
+});
+
+test("Execute COUNT Aggregate Query", async () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "COUNT(*)": 4 }]);
+});
+
+test("Execute SUM Aggregate Query", async () => {
+ const query = "SELECT SUM(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "SUM(age)": 101 }]);
+});
+
+test("Execute AVG Aggregate Query", async () => {
+ const query = "SELECT AVG(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ // Assuming AVG returns a single decimal point value
+ expect(result).toEqual([{ "AVG(age)": 25.25 }]);
+});
+
+test("Execute MIN Aggregate Query", async () => {
+ const query = "SELECT MIN(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MIN(age)": 22 }]);
+});
+
+test("Execute MAX Aggregate Query", async () => {
+ const query = "SELECT MAX(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MAX(age)": 30 }]);
+});
+
+test("Count students per age", async () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "22", "COUNT(*)": 1 },
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments per course", async () => {
+ const query = "SELECT course, COUNT(*) FROM enrollment GROUP BY course";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { course: "Mathematics", "COUNT(*)": 2 },
+ { course: "Physics", "COUNT(*)": 1 },
+ { course: "Chemistry", "COUNT(*)": 1 },
+ { course: "Biology", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count courses per student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { student_id: "1", "COUNT(*)": 2 },
+ { student_id: "2", "COUNT(*)": 1 },
+ { student_id: "3", "COUNT(*)": 1 },
+ { student_id: "5", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count students within a specific age range", async () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments for a specific course", async () => {
+ const query =
+ 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ course: "Mathematics", "COUNT(*)": 2 }]);
+});
+
+test("Count courses for a specific student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ student_id: "1", "COUNT(*)": 2 }]);
+});
+
+test("Average age of students above a certain age", async () => {
+ const query = "SELECT AVG(age) FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(query);
+ const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
+ expect(result).toEqual([{ "AVG(age)": expectedAverage }]);
+});
+
+test("Parse SQL Query", () => {
+ const query = "SELECT id, name FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with WHERE Clause", () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "25",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ isDistinct: false,
+ limit: null,
+ });
+});
+
+test("Parse SQL Query with Multiple WHERE Clauses", () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "30",
+ },
+ {
+ field: "name",
+ operator: "=",
+ value: "John",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN and WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "20" }],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse INNER JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "INNER",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse LEFT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "LEFT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse RIGHT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "RIGHT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Returns null for queries without JOIN", () => {
+ const query = "SELECT * FROM table1";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "LEFT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "RIGHT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "22" }],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Physics'" },
+ ],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: "<", value: "25" }],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Chemistry'" },
+ ],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse COUNT Aggregate Query", () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SUM Aggregate Query", () => {
+ const query = "SELECT SUM(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["SUM(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ isDistinct: false,
+ limit: null,
+ });
+});
+
+test("Parse AVG Aggregate Query", () => {
+ const query = "SELECT AVG(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["AVG(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ isDistinct: false,
+ limit: null,
+ });
+});
+
+test("Parse MIN Aggregate Query", () => {
+ const query = "SELECT MIN(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MIN(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MAX Aggregate Query", () => {
+ const query = "SELECT MAX(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MAX(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse basic GROUP BY query", () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with WHERE clause", () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [{ field: "age", operator: ">", value: "22" }],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with multiple fields", () => {
+ const query =
+ "SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student_id", "course", "COUNT(*)"],
+ table: "enrollment",
+ whereClauses: [],
+ groupByFields: ["student_id", "course"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with JOIN and WHERE clauses", () => {
+ const query =
+ 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student.name", "COUNT(*)"],
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: '"Mathematics"' },
+ ],
+ groupByFields: ["student.name"],
+ joinType: "INNER",
+ joinTable: "enrollment",
+ joinCondition: {
+ left: "student.id",
+ right: "enrollment.student_id",
+ },
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Execute SQL Query with ORDER BY", async () => {
+ const query = "SELECT name FROM student ORDER BY name ASC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([
+ { name: "Alice" },
+ { name: "Bob" },
+ { name: "Jane" },
+ { name: "John" },
+ ]);
+});
+
+test("Execute SQL Query with ORDER BY and WHERE", async () => {
+ const query = "SELECT name FROM student WHERE age > 24 ORDER BY name DESC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([{ name: "John" }, { name: "Jane" }]);
+});
+test("Execute SQL Query with ORDER BY and GROUP BY", async () => {
+ const query =
+ "SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC";
+ const result = await executeSELECTQuery(query);
+ expect(result).toStrictEqual([
+ { age: "30", "COUNT(id) as count": 1 },
+ { age: "25", "COUNT(id) as count": 1 },
+ { age: "24", "COUNT(id) as count": 1 },
+ { age: "22", "COUNT(id) as count": 1 },
+ ]);
+});
+
+test("Parse SQL Query with ORDER BY", () => {
+ const query = "SELECT name FROM student ORDER BY name ASC";
+ const parsed = parseSelectQuery(query);
+ expect(parsed.orderByFields).toEqual([{ fieldName: "name", order: "ASC" }]);
+});
+
+test("Parse SQL Query with ORDER BY and WHERE", () => {
+ const query = "SELECT name FROM student WHERE age > 20 ORDER BY name DESC";
+ const parsed = parseSelectQuery(query);
+ expect(parsed.orderByFields).toEqual([{ fieldName: "name", order: "DESC" }]);
+ expect(parsed.whereClauses.length).toBeGreaterThan(0);
+});
+
+test("Parse SQL Query with ORDER BY and GROUP BY", () => {
+ const query =
+ "SELECT COUNT(id), age FROM student GROUP BY age ORDER BY age DESC";
+ const parsed = parseSelectQuery(query);
+ expect(parsed.orderByFields).toEqual([{ fieldName: "age", order: "DESC" }]);
+ expect(parsed.groupByFields).toEqual(["age"]);
});
-
-test('Parse INNER JOIN clause', () => {
- const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'INNER',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' },
- });
-});
-
-test('Parse LEFT JOIN clause', () => {
- const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'LEFT',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' }
- });
-});
-
-test('Parse RIGHT JOIN clause', () => {
- const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'RIGHT',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' }
- });
-});
-
-test('Returns null for queries without JOIN', () => {
- const query = 'SELECT * FROM table1';
- const result = parseJoinClause(query);
- expect(result).toEqual(
- {
- joinType: null,
- joinTable: null,
- joinCondition: null
- }
- );
-});
-
-test('Parse LEFT Join Query Completely', () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinType: 'LEFT',
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null
- })
-})
-
-test('Parse LEFT Join Query Completely', () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinType: 'RIGHT',
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null
- })
-})
-
-test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "LEFT",
- "table": "student",
- "whereClauses": [{ "field": "student.age", "operator": ">", "value": "22" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null
- });
-});
-
-test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "LEFT",
- "table": "student",
- "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Physics'" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null
- });
-});
-
-test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "RIGHT",
- "table": "student",
- "whereClauses": [{ "field": "student.age", "operator": "<", "value": "25" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null
- });
-});
-
-test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "RIGHT",
- "table": "student",
- "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Chemistry'" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null
- });
-});
-
-
-test('Parse COUNT Aggregate Query', () => {
- const query = 'SELECT COUNT(*) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['COUNT(*)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null
- });
-});
-
-
-test('Parse SUM Aggregate Query', () => {
- const query = 'SELECT SUM(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['SUM(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null
- });
-});
-
-test('Parse AVG Aggregate Query', () => {
- const query = 'SELECT AVG(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['AVG(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null
- });
-});
-
-test('Parse MIN Aggregate Query', () => {
- const query = 'SELECT MIN(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['MIN(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null
- });
-});
-
-test('Parse MAX Aggregate Query', () => {
- const query = 'SELECT MAX(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['MAX(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null
- });
-});
-
-test('Parse basic GROUP BY query', () => {
- const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['age', 'COUNT(*)'],
- table: 'student',
- whereClauses: [],
- groupByFields: ['age'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null
- });
-});
-
-test('Parse GROUP BY query with WHERE clause', () => {
- const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['age', 'COUNT(*)'],
- table: 'student',
- whereClauses: [{ field: 'age', operator: '>', value: '22' }],
- groupByFields: ['age'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null
- });
-});
-
-test('Parse GROUP BY query with multiple fields', () => {
- const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['student_id', 'course', 'COUNT(*)'],
- table: 'enrollment',
- whereClauses: [],
- groupByFields: ['student_id', 'course'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null
- });
-});
-
-test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
- const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['student.name', 'COUNT(*)'],
- table: 'student',
- whereClauses: [{ field: 'enrollment.course', operator: '=', value: '"Mathematics"' }],
- groupByFields: ['student.name'],
- joinType: 'INNER',
- joinTable: 'enrollment',
- joinCondition: {
- left: 'student.id',
- right: 'enrollment.student_id'
- },
- hasAggregateWithoutGroupBy: false,
- orderByFields: null
- });
-});
-
-test('Execute SQL Query with ORDER BY', async () => {
- const query = 'SELECT name FROM student ORDER BY name ASC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { name: 'Alice' },
- { name: 'Bob' },
- { name: 'Jane' },
- { name: 'John' }
- ]);
-});
-
-test('Execute SQL Query with ORDER BY and WHERE', async () => {
- const query = 'SELECT name FROM student WHERE age > 24 ORDER BY name DESC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { name: 'John' },
- { name: 'Jane' },
- ]);
-});
-test('Execute SQL Query with ORDER BY and GROUP BY', async () => {
- const query = 'SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { age: '30', 'COUNT(id) as count': 1 },
- { age: '25', 'COUNT(id) as count': 1 },
- { age: '24', 'COUNT(id) as count': 1 },
- { age: '22', 'COUNT(id) as count': 1 }
- ]);
-});
\ No newline at end of file
diff --git a/tests/step-12/index.test.js b/tests/step-12/index.test.js
index d15c77ef5..029db25e6 100644
--- a/tests/step-12/index.test.js
+++ b/tests/step-12/index.test.js
@@ -1,59 +1,60 @@
-const readCSV = require('../../src/csvReader');
-const {parseQuery, parseJoinClause} = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
-
-test('Read CSV File', async () => {
- const data = await readCSV('./student.csv');
- expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(4);
- expect(data[0].name).toBe('John');
- expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
-});
-
-test('Execute SQL Query', async () => {
- const query = 'SELECT id, name FROM student';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBeGreaterThan(0);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0]).not.toHaveProperty('age');
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0].id).toBe('2');
-});
-
-test('Execute SQL Query with Complex WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with Greater Than', async () => {
- const queryWithGT = 'SELECT id FROM student WHERE age > 22';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('id');
-});
-
-test('Execute SQL Query with Not Equal to', async () => {
- const queryWithGT = 'SELECT name FROM student WHERE age != 25';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('name');
-});
-
-test('Execute SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- /*
+const { readCSV } = require("../../src/csvReader");
+const { parseSelectQuery, parseJoinClause } = require("../../src/queryParser");
+const { executeSELECTQuery } = require("../../src/queryExecutor");
+
+test("Read CSV File", async () => {
+ const data = await readCSV("./student.csv");
+ expect(data.length).toBeGreaterThan(0);
+ expect(data.length).toBe(4);
+ expect(data[0].name).toBe("John");
+ expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later
+});
+
+test("Execute SQL Query", async () => {
+ const query = "SELECT id, name FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBeGreaterThan(0);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0]).not.toHaveProperty("age");
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0].id).toBe("2");
+});
+
+test("Execute SQL Query with Complex WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with Greater Than", async () => {
+ const queryWithGT = "SELECT id FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("id");
+});
+
+test("Execute SQL Query with Not Equal to", async () => {
+ const queryWithGT = "SELECT name FROM student WHERE age != 25";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("name");
+});
+
+test("Execute SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{ 'student.name': 'John', 'enrollment.course': 'Mathematics' },
{ 'student.name': 'John', 'enrollment.course': 'Physics' },
@@ -61,18 +62,21 @@ test('Execute SQL Query with INNER JOIN', async () => {
{ 'student.name': 'Bob', 'enrollment.course': 'Mathematics' }
]
*/
- expect(result.length).toEqual(4);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
+ expect(result.length).toEqual(4);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ })
+ );
});
-test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25';
- const result = await executeSELECTQuery(query);
- /*
+test("Execute SQL Query with INNER JOIN and a WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{
'student.name': 'John',
@@ -86,636 +90,719 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
}
]
*/
- expect(result.length).toEqual(2);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
-});
-
-test('Execute SQL Query with LEFT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "Alice", "enrollment.course": null }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 students, but John appears twice
-});
-
-test('Execute SQL Query with RIGHT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": null, "enrollment.course": "Biology" }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
-});
-
-test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "John" }),
- expect.objectContaining({ "enrollment.course": "Physics", "student.name": "John" })
- ]));
- expect(result.length).toEqual(4);
-});
-
-test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Physics" })
- ]));
- expect(result.length).toEqual(1);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "Bob" }),
- expect.objectContaining({ "enrollment.course": "Biology", "student.name": null })
- ]));
- expect(result.length).toEqual(2);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Chemistry", "student.name": "Jane" }),
- ]));
- expect(result.length).toEqual(1);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([]);
-});
-
-test('Execute COUNT Aggregate Query', async () => {
- const query = 'SELECT COUNT(*) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'COUNT(*)': 4 }]);
-});
-
-test('Execute SUM Aggregate Query', async () => {
- const query = 'SELECT SUM(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'SUM(age)': 101 }]);
-});
-
-test('Execute AVG Aggregate Query', async () => {
- const query = 'SELECT AVG(age) FROM student';
- const result = await executeSELECTQuery(query);
- // Assuming AVG returns a single decimal point value
- expect(result).toEqual([{ 'AVG(age)': 25.25 }]);
-});
-
-test('Execute MIN Aggregate Query', async () => {
- const query = 'SELECT MIN(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'MIN(age)': 22 }]);
-});
-
-test('Execute MAX Aggregate Query', async () => {
- const query = 'SELECT MAX(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'MAX(age)': 30 }]);
-});
-
-test('Count students per age', async () => {
- const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { age: '22', 'COUNT(*)': 1 },
- { age: '24', 'COUNT(*)': 1 },
- { age: '25', 'COUNT(*)': 1 },
- { age: '30', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count enrollments per course', async () => {
- const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { course: 'Mathematics', 'COUNT(*)': 2 },
- { course: 'Physics', 'COUNT(*)': 1 },
- { course: 'Chemistry', 'COUNT(*)': 1 },
- { course: 'Biology', 'COUNT(*)': 1 }
- ]);
-});
-
-
-test('Count courses per student', async () => {
- const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { student_id: '1', 'COUNT(*)': 2 },
- { student_id: '2', 'COUNT(*)': 1 },
- { student_id: '3', 'COUNT(*)': 1 },
- { student_id: '5', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count students within a specific age range', async () => {
- const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { age: '24', 'COUNT(*)': 1 },
- { age: '25', 'COUNT(*)': 1 },
- { age: '30', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count enrollments for a specific course', async () => {
- const query = 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { course: 'Mathematics', 'COUNT(*)': 2 }
- ]);
-});
-
-test('Count courses for a specific student', async () => {
- const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { student_id: '1', 'COUNT(*)': 2 }
- ]);
-});
-
-test('Average age of students above a certain age', async () => {
- const query = 'SELECT AVG(age) FROM student WHERE age > 22';
- const result = await executeSELECTQuery(query);
- const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
- expect(result).toEqual([{ 'AVG(age)': expectedAverage }]);
-});
-
-test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
- });
-});
-
-test('Parse SQL Query with WHERE Clause', () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "25",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
- });
-});
-
-test('Parse SQL Query with Multiple WHERE Clauses', () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "30",
- }, {
- "field": "name",
- "operator": "=",
- "value": "John",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
- });
-});
-
-test('Parse SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinTable: 'enrollment',
- joinType: "INNER",
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
- })
-});
-
-test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [{ field: 'student.age', operator: '>', value: '20' }],
- joinTable: 'enrollment',
- joinType: "INNER",
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
+ expect(result.length).toEqual(2);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
})
+ );
+});
+
+test("Execute SQL Query with LEFT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "Alice",
+ "enrollment.course": null,
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 students, but John appears twice
+});
+
+test("Execute SQL Query with RIGHT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": null,
+ "enrollment.course": "Biology",
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Physics",
+ "student.name": "John",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(4);
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Physics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "Bob",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Biology",
+ "student.name": null,
+ }),
+ ])
+ );
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Chemistry",
+ "student.name": "Jane",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([]);
+});
+
+test("Execute COUNT Aggregate Query", async () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "COUNT(*)": 4 }]);
+});
+
+test("Execute SUM Aggregate Query", async () => {
+ const query = "SELECT SUM(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "SUM(age)": 101 }]);
+});
+
+test("Execute AVG Aggregate Query", async () => {
+ const query = "SELECT AVG(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ // Assuming AVG returns a single decimal point value
+ expect(result).toEqual([{ "AVG(age)": 25.25 }]);
+});
+
+test("Execute MIN Aggregate Query", async () => {
+ const query = "SELECT MIN(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MIN(age)": 22 }]);
+});
+
+test("Execute MAX Aggregate Query", async () => {
+ const query = "SELECT MAX(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MAX(age)": 30 }]);
+});
+
+test("Count students per age", async () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "22", "COUNT(*)": 1 },
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments per course", async () => {
+ const query = "SELECT course, COUNT(*) FROM enrollment GROUP BY course";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { course: "Mathematics", "COUNT(*)": 2 },
+ { course: "Physics", "COUNT(*)": 1 },
+ { course: "Chemistry", "COUNT(*)": 1 },
+ { course: "Biology", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count courses per student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { student_id: "1", "COUNT(*)": 2 },
+ { student_id: "2", "COUNT(*)": 1 },
+ { student_id: "3", "COUNT(*)": 1 },
+ { student_id: "5", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count students within a specific age range", async () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments for a specific course", async () => {
+ const query =
+ 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ course: "Mathematics", "COUNT(*)": 2 }]);
+});
+
+test("Count courses for a specific student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ student_id: "1", "COUNT(*)": 2 }]);
+});
+
+test("Average age of students above a certain age", async () => {
+ const query = "SELECT AVG(age) FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(query);
+ const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
+ expect(result).toEqual([{ "AVG(age)": expectedAverage }]);
+});
+
+test("Parse SQL Query", () => {
+ const query = "SELECT id, name FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with WHERE Clause", () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "25",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with Multiple WHERE Clauses", () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "30",
+ },
+ {
+ field: "name",
+ operator: "=",
+ value: "John",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN and WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "20" }],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse INNER JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "INNER",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse LEFT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "LEFT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse RIGHT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "RIGHT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Returns null for queries without JOIN", () => {
+ const query = "SELECT * FROM table1";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "LEFT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "RIGHT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "22" }],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Physics'" },
+ ],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: "<", value: "25" }],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Chemistry'" },
+ ],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ isDistinct: false,
+ limit: null,
+ });
+});
+
+test("Parse COUNT Aggregate Query", () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ isDistinct: false,
+ limit: null,
+ });
+});
+
+test("Parse SUM Aggregate Query", () => {
+ const query = "SELECT SUM(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["SUM(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ isDistinct: false,
+ orderByFields: null,
+ limit: null,
+ });
+});
+
+test("Parse AVG Aggregate Query", () => {
+ const query = "SELECT AVG(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["AVG(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MIN Aggregate Query", () => {
+ const query = "SELECT MIN(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MIN(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MAX Aggregate Query", () => {
+ const query = "SELECT MAX(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MAX(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse basic GROUP BY query", () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with WHERE clause", () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [{ field: "age", operator: ">", value: "22" }],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with multiple fields", () => {
+ const query =
+ "SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student_id", "course", "COUNT(*)"],
+ table: "enrollment",
+ whereClauses: [],
+ groupByFields: ["student_id", "course"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with JOIN and WHERE clauses", () => {
+ const query =
+ 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student.name", "COUNT(*)"],
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: '"Mathematics"' },
+ ],
+ groupByFields: ["student.name"],
+ joinType: "INNER",
+ joinTable: "enrollment",
+ joinCondition: {
+ left: "student.id",
+ right: "enrollment.student_id",
+ },
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Execute SQL Query with ORDER BY", async () => {
+ const query = "SELECT name FROM student ORDER BY name ASC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([
+ { name: "Alice" },
+ { name: "Bob" },
+ { name: "Jane" },
+ { name: "John" },
+ ]);
+});
+
+test("Execute SQL Query with ORDER BY and WHERE", async () => {
+ const query = "SELECT name FROM student WHERE age > 24 ORDER BY name DESC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([{ name: "John" }, { name: "Jane" }]);
+});
+test("Execute SQL Query with ORDER BY and GROUP BY", async () => {
+ const query =
+ "SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([
+ { age: "30", "COUNT(id) as count": 1 },
+ { age: "25", "COUNT(id) as count": 1 },
+ { age: "24", "COUNT(id) as count": 1 },
+ { age: "22", "COUNT(id) as count": 1 },
+ ]);
+});
+
+test("Execute SQL Query with standard LIMIT clause", async () => {
+ const query = "SELECT id, name FROM student LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with LIMIT clause equal to total rows", async () => {
+ const query = "SELECT id, name FROM student LIMIT 4";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(4);
+});
+
+test("Execute SQL Query with LIMIT clause exceeding total rows", async () => {
+ const query = "SELECT id, name FROM student LIMIT 10";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(4); // Total rows in student.csv
+});
+
+test("Execute SQL Query with LIMIT 0", async () => {
+ const query = "SELECT id, name FROM student LIMIT 0";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(0);
+});
+
+test("Execute SQL Query with LIMIT and ORDER BY clause", async () => {
+ const query = "SELECT id, name FROM student ORDER BY age DESC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(2);
+ expect(result[0].name).toEqual("John");
+ expect(result[1].name).toEqual("Jane");
});
-
-test('Parse INNER JOIN clause', () => {
- const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'INNER',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' },
- });
-});
-
-test('Parse LEFT JOIN clause', () => {
- const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'LEFT',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' }
- });
-});
-
-test('Parse RIGHT JOIN clause', () => {
- const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'RIGHT',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' }
- });
-});
-
-test('Returns null for queries without JOIN', () => {
- const query = 'SELECT * FROM table1';
- const result = parseJoinClause(query);
- expect(result).toEqual(
- {
- joinType: null,
- joinTable: null,
- joinCondition: null
- }
- );
-});
-
-test('Parse LEFT Join Query Completely', () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinType: 'LEFT',
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
- })
-})
-
-test('Parse LEFT Join Query Completely', () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinType: 'RIGHT',
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
- })
-})
-
-test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "LEFT",
- "table": "student",
- "whereClauses": [{ "field": "student.age", "operator": ">", "value": "22" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
- });
-});
-
-test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "LEFT",
- "table": "student",
- "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Physics'" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
- });
-});
-
-test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "RIGHT",
- "table": "student",
- "whereClauses": [{ "field": "student.age", "operator": "<", "value": "25" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
- });
-});
-
-test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "RIGHT",
- "table": "student",
- "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Chemistry'" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
- });
-});
-
-
-test('Parse COUNT Aggregate Query', () => {
- const query = 'SELECT COUNT(*) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['COUNT(*)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null
- });
-});
-
-
-test('Parse SUM Aggregate Query', () => {
- const query = 'SELECT SUM(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['SUM(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null
- });
-});
-
-test('Parse AVG Aggregate Query', () => {
- const query = 'SELECT AVG(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['AVG(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null
- });
-});
-
-test('Parse MIN Aggregate Query', () => {
- const query = 'SELECT MIN(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['MIN(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null
- });
-});
-
-test('Parse MAX Aggregate Query', () => {
- const query = 'SELECT MAX(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['MAX(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null
- });
-});
-
-test('Parse basic GROUP BY query', () => {
- const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['age', 'COUNT(*)'],
- table: 'student',
- whereClauses: [],
- groupByFields: ['age'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null
- });
-});
-
-test('Parse GROUP BY query with WHERE clause', () => {
- const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['age', 'COUNT(*)'],
- table: 'student',
- whereClauses: [{ field: 'age', operator: '>', value: '22' }],
- groupByFields: ['age'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null
- });
-});
-
-test('Parse GROUP BY query with multiple fields', () => {
- const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['student_id', 'course', 'COUNT(*)'],
- table: 'enrollment',
- whereClauses: [],
- groupByFields: ['student_id', 'course'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null
- });
-});
-
-test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
- const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['student.name', 'COUNT(*)'],
- table: 'student',
- whereClauses: [{ field: 'enrollment.course', operator: '=', value: '"Mathematics"' }],
- groupByFields: ['student.name'],
- joinType: 'INNER',
- joinTable: 'enrollment',
- joinCondition: {
- left: 'student.id',
- right: 'enrollment.student_id'
- },
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- });
-});
-
-test('Execute SQL Query with ORDER BY', async () => {
- const query = 'SELECT name FROM student ORDER BY name ASC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { name: 'Alice' },
- { name: 'Bob' },
- { name: 'Jane' },
- { name: 'John' }
- ]);
-});
-
-test('Execute SQL Query with ORDER BY and WHERE', async () => {
- const query = 'SELECT name FROM student WHERE age > 24 ORDER BY name DESC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { name: 'John' },
- { name: 'Jane' },
- ]);
-});
-test('Execute SQL Query with ORDER BY and GROUP BY', async () => {
- const query = 'SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { age: '30', 'COUNT(id) as count': 1 },
- { age: '25', 'COUNT(id) as count': 1 },
- { age: '24', 'COUNT(id) as count': 1 },
- { age: '22', 'COUNT(id) as count': 1 }
- ]);
-});
-
-test('Execute SQL Query with standard LIMIT clause', async () => {
- const query = 'SELECT id, name FROM student LIMIT 2';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(2);
-});
-
-test('Execute SQL Query with LIMIT clause equal to total rows', async () => {
- const query = 'SELECT id, name FROM student LIMIT 4';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(4);
-});
-
-test('Execute SQL Query with LIMIT clause exceeding total rows', async () => {
- const query = 'SELECT id, name FROM student LIMIT 10';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(4); // Total rows in student.csv
-});
-
-test('Execute SQL Query with LIMIT 0', async () => {
- const query = 'SELECT id, name FROM student LIMIT 0';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(0);
-});
-
-test('Execute SQL Query with LIMIT and ORDER BY clause', async () => {
- const query = 'SELECT id, name FROM student ORDER BY age DESC LIMIT 2';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(2);
- expect(result[0].name).toEqual('John');
- expect(result[1].name).toEqual('Jane');
-});
\ No newline at end of file
diff --git a/tests/step-13/index.test.js b/tests/step-13/index.test.js
index 0797faaba..0224f14ac 100644
--- a/tests/step-13/index.test.js
+++ b/tests/step-13/index.test.js
@@ -1,59 +1,60 @@
-const readCSV = require('../../src/csvReader');
-const {parseQuery, parseJoinClause} = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
-
-test('Read CSV File', async () => {
- const data = await readCSV('./student.csv');
- expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(4);
- expect(data[0].name).toBe('John');
- expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
-});
-
-test('Execute SQL Query', async () => {
- const query = 'SELECT id, name FROM student';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBeGreaterThan(0);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0]).not.toHaveProperty('age');
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0].id).toBe('2');
-});
-
-test('Execute SQL Query with Complex WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with Greater Than', async () => {
- const queryWithGT = 'SELECT id FROM student WHERE age > 22';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('id');
-});
-
-test('Execute SQL Query with Not Equal to', async () => {
- const queryWithGT = 'SELECT name FROM student WHERE age != 25';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('name');
-});
-
-test('Execute SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- /*
+const { readCSV } = require("../../src/csvReader");
+const { parseSelectQuery, parseJoinClause } = require("../../src/queryParser");
+const { executeSELECTQuery } = require("../../src/queryExecutor");
+
+test("Read CSV File", async () => {
+ const data = await readCSV("./student.csv");
+ expect(data.length).toBeGreaterThan(0);
+ expect(data.length).toBe(4);
+ expect(data[0].name).toBe("John");
+ expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later
+});
+
+test("Execute SQL Query", async () => {
+ const query = "SELECT id, name FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBeGreaterThan(0);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0]).not.toHaveProperty("age");
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0].id).toBe("2");
+});
+
+test("Execute SQL Query with Complex WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with Greater Than", async () => {
+ const queryWithGT = "SELECT id FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("id");
+});
+
+test("Execute SQL Query with Not Equal to", async () => {
+ const queryWithGT = "SELECT name FROM student WHERE age != 25";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("name");
+});
+
+test("Execute SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{ 'student.name': 'John', 'enrollment.course': 'Mathematics' },
{ 'student.name': 'John', 'enrollment.course': 'Physics' },
@@ -61,18 +62,21 @@ test('Execute SQL Query with INNER JOIN', async () => {
{ 'student.name': 'Bob', 'enrollment.course': 'Mathematics' }
]
*/
- expect(result.length).toEqual(4);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
+ expect(result.length).toEqual(4);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ })
+ );
});
-test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25';
- const result = await executeSELECTQuery(query);
- /*
+test("Execute SQL Query with INNER JOIN and a WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{
'student.name': 'John',
@@ -86,641 +90,725 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
}
]
*/
- expect(result.length).toEqual(2);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
-});
-
-test('Execute SQL Query with LEFT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "Alice", "enrollment.course": null }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 students, but John appears twice
-});
-
-test('Execute SQL Query with RIGHT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": null, "enrollment.course": "Biology" }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
-});
-
-test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "John" }),
- expect.objectContaining({ "enrollment.course": "Physics", "student.name": "John" })
- ]));
- expect(result.length).toEqual(4);
-});
-
-test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Physics" })
- ]));
- expect(result.length).toEqual(1);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "Bob" }),
- expect.objectContaining({ "enrollment.course": "Biology", "student.name": null })
- ]));
- expect(result.length).toEqual(2);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Chemistry", "student.name": "Jane" }),
- ]));
- expect(result.length).toEqual(1);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([]);
-});
-
-test('Execute COUNT Aggregate Query', async () => {
- const query = 'SELECT COUNT(*) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'COUNT(*)': 4 }]);
-});
-
-test('Execute SUM Aggregate Query', async () => {
- const query = 'SELECT SUM(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'SUM(age)': 101 }]);
-});
-
-test('Execute AVG Aggregate Query', async () => {
- const query = 'SELECT AVG(age) FROM student';
- const result = await executeSELECTQuery(query);
- // Assuming AVG returns a single decimal point value
- expect(result).toEqual([{ 'AVG(age)': 25.25 }]);
-});
-
-test('Execute MIN Aggregate Query', async () => {
- const query = 'SELECT MIN(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'MIN(age)': 22 }]);
-});
-
-test('Execute MAX Aggregate Query', async () => {
- const query = 'SELECT MAX(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'MAX(age)': 30 }]);
-});
-
-test('Count students per age', async () => {
- const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { age: '22', 'COUNT(*)': 1 },
- { age: '24', 'COUNT(*)': 1 },
- { age: '25', 'COUNT(*)': 1 },
- { age: '30', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count enrollments per course', async () => {
- const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { course: 'Mathematics', 'COUNT(*)': 2 },
- { course: 'Physics', 'COUNT(*)': 1 },
- { course: 'Chemistry', 'COUNT(*)': 1 },
- { course: 'Biology', 'COUNT(*)': 1 }
- ]);
-});
-
-
-test('Count courses per student', async () => {
- const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { student_id: '1', 'COUNT(*)': 2 },
- { student_id: '2', 'COUNT(*)': 1 },
- { student_id: '3', 'COUNT(*)': 1 },
- { student_id: '5', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count students within a specific age range', async () => {
- const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { age: '24', 'COUNT(*)': 1 },
- { age: '25', 'COUNT(*)': 1 },
- { age: '30', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count enrollments for a specific course', async () => {
- const query = 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { course: 'Mathematics', 'COUNT(*)': 2 }
- ]);
-});
-
-test('Count courses for a specific student', async () => {
- const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { student_id: '1', 'COUNT(*)': 2 }
- ]);
-});
-
-test('Average age of students above a certain age', async () => {
- const query = 'SELECT AVG(age) FROM student WHERE age > 22';
- const result = await executeSELECTQuery(query);
- const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
- expect(result).toEqual([{ 'AVG(age)': expectedAverage }]);
-});
-
-test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
- });
-});
-
-test('Parse SQL Query with WHERE Clause', () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "25",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
- });
-});
-
-test('Parse SQL Query with Multiple WHERE Clauses', () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "30",
- }, {
- "field": "name",
- "operator": "=",
- "value": "John",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
- });
-});
-
-test('Parse SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinTable: 'enrollment',
- joinType: "INNER",
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
- })
-});
-
-test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [{ field: 'student.age', operator: '>', value: '20' }],
- joinTable: 'enrollment',
- joinType: "INNER",
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
+ expect(result.length).toEqual(2);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
})
+ );
+});
+
+test("Execute SQL Query with LEFT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "Alice",
+ "enrollment.course": null,
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 students, but John appears twice
+});
+
+test("Execute SQL Query with RIGHT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": null,
+ "enrollment.course": "Biology",
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Physics",
+ "student.name": "John",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(4);
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Physics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "Bob",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Biology",
+ "student.name": null,
+ }),
+ ])
+ );
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Chemistry",
+ "student.name": "Jane",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([]);
+});
+
+test("Execute COUNT Aggregate Query", async () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "COUNT(*)": 4 }]);
+});
+
+test("Execute SUM Aggregate Query", async () => {
+ const query = "SELECT SUM(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "SUM(age)": 101 }]);
+});
+
+test("Execute AVG Aggregate Query", async () => {
+ const query = "SELECT AVG(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ // Assuming AVG returns a single decimal point value
+ expect(result).toEqual([{ "AVG(age)": 25.25 }]);
+});
+
+test("Execute MIN Aggregate Query", async () => {
+ const query = "SELECT MIN(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MIN(age)": 22 }]);
+});
+
+test("Execute MAX Aggregate Query", async () => {
+ const query = "SELECT MAX(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MAX(age)": 30 }]);
+});
+
+test("Count students per age", async () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "22", "COUNT(*)": 1 },
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments per course", async () => {
+ const query = "SELECT course, COUNT(*) FROM enrollment GROUP BY course";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { course: "Mathematics", "COUNT(*)": 2 },
+ { course: "Physics", "COUNT(*)": 1 },
+ { course: "Chemistry", "COUNT(*)": 1 },
+ { course: "Biology", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count courses per student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { student_id: "1", "COUNT(*)": 2 },
+ { student_id: "2", "COUNT(*)": 1 },
+ { student_id: "3", "COUNT(*)": 1 },
+ { student_id: "5", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count students within a specific age range", async () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments for a specific course", async () => {
+ const query =
+ 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ course: "Mathematics", "COUNT(*)": 2 }]);
+});
+
+test("Count courses for a specific student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ student_id: "1", "COUNT(*)": 2 }]);
+});
+
+test("Average age of students above a certain age", async () => {
+ const query = "SELECT AVG(age) FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(query);
+ const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
+ expect(result).toEqual([{ "AVG(age)": expectedAverage }]);
+});
+
+test("Parse SQL Query", () => {
+ const query = "SELECT id, name FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with WHERE Clause", () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "25",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with Multiple WHERE Clauses", () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "30",
+ },
+ {
+ field: "name",
+ operator: "=",
+ value: "John",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN and WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "20" }],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse INNER JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "INNER",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse LEFT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "LEFT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse RIGHT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "RIGHT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Returns null for queries without JOIN", () => {
+ const query = "SELECT * FROM table1";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "LEFT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "RIGHT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "22" }],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Physics'" },
+ ],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: "<", value: "25" }],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Chemistry'" },
+ ],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse COUNT Aggregate Query", () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SUM Aggregate Query", () => {
+ const query = "SELECT SUM(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["SUM(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse AVG Aggregate Query", () => {
+ const query = "SELECT AVG(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["AVG(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MIN Aggregate Query", () => {
+ const query = "SELECT MIN(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MIN(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MAX Aggregate Query", () => {
+ const query = "SELECT MAX(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MAX(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse basic GROUP BY query", () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with WHERE clause", () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [{ field: "age", operator: ">", value: "22" }],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with multiple fields", () => {
+ const query =
+ "SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student_id", "course", "COUNT(*)"],
+ table: "enrollment",
+ whereClauses: [],
+ groupByFields: ["student_id", "course"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with JOIN and WHERE clauses", () => {
+ const query =
+ 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student.name", "COUNT(*)"],
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: '"Mathematics"' },
+ ],
+ groupByFields: ["student.name"],
+ joinType: "INNER",
+ joinTable: "enrollment",
+ joinCondition: {
+ left: "student.id",
+ right: "enrollment.student_id",
+ },
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Execute SQL Query with ORDER BY", async () => {
+ const query = "SELECT name FROM student ORDER BY name ASC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([
+ { name: "Alice" },
+ { name: "Bob" },
+ { name: "Jane" },
+ { name: "John" },
+ ]);
+});
+
+test("Execute SQL Query with ORDER BY and WHERE", async () => {
+ const query = "SELECT name FROM student WHERE age > 24 ORDER BY name DESC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([{ name: "John" }, { name: "Jane" }]);
+});
+test("Execute SQL Query with ORDER BY and GROUP BY", async () => {
+ const query =
+ "SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([
+ { age: "30", "COUNT(id) as count": 1 },
+ { age: "25", "COUNT(id) as count": 1 },
+ { age: "24", "COUNT(id) as count": 1 },
+ { age: "22", "COUNT(id) as count": 1 },
+ ]);
+});
+
+test("Execute SQL Query with standard LIMIT clause", async () => {
+ const query = "SELECT id, name FROM student LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with LIMIT clause equal to total rows", async () => {
+ const query = "SELECT id, name FROM student LIMIT 4";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(4);
+});
+
+test("Execute SQL Query with LIMIT clause exceeding total rows", async () => {
+ const query = "SELECT id, name FROM student LIMIT 10";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(4); // Total rows in student.csv
+});
+
+test("Execute SQL Query with LIMIT 0", async () => {
+ const query = "SELECT id, name FROM student LIMIT 0";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(0);
+});
+
+test("Execute SQL Query with LIMIT and ORDER BY clause", async () => {
+ const query = "SELECT id, name FROM student ORDER BY age DESC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(2);
+ expect(result[0].name).toEqual("John");
+ expect(result[1].name).toEqual("Jane");
+});
+
+test("Error Handling with Malformed Query", async () => {
+ const query = "SELECT FROM table"; // intentionally malformed
+ await expect(executeSELECTQuery(query)).rejects.toThrow(
+ "Error executing query: Query parsing error: Invalid SELECT format"
+ );
});
-
-test('Parse INNER JOIN clause', () => {
- const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'INNER',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' },
- });
-});
-
-test('Parse LEFT JOIN clause', () => {
- const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'LEFT',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' }
- });
-});
-
-test('Parse RIGHT JOIN clause', () => {
- const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'RIGHT',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' }
- });
-});
-
-test('Returns null for queries without JOIN', () => {
- const query = 'SELECT * FROM table1';
- const result = parseJoinClause(query);
- expect(result).toEqual(
- {
- joinType: null,
- joinTable: null,
- joinCondition: null
- }
- );
-});
-
-test('Parse LEFT Join Query Completely', () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinType: 'LEFT',
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
- })
-})
-
-test('Parse LEFT Join Query Completely', () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinType: 'RIGHT',
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
- })
-})
-
-test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "LEFT",
- "table": "student",
- "whereClauses": [{ "field": "student.age", "operator": ">", "value": "22" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
- });
-});
-
-test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "LEFT",
- "table": "student",
- "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Physics'" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
- });
-});
-
-test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "RIGHT",
- "table": "student",
- "whereClauses": [{ "field": "student.age", "operator": "<", "value": "25" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
- });
-});
-
-test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "RIGHT",
- "table": "student",
- "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Chemistry'" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null
- });
-});
-
-
-test('Parse COUNT Aggregate Query', () => {
- const query = 'SELECT COUNT(*) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['COUNT(*)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null
- });
-});
-
-
-test('Parse SUM Aggregate Query', () => {
- const query = 'SELECT SUM(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['SUM(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null
- });
-});
-
-test('Parse AVG Aggregate Query', () => {
- const query = 'SELECT AVG(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['AVG(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null
- });
-});
-
-test('Parse MIN Aggregate Query', () => {
- const query = 'SELECT MIN(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['MIN(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null
- });
-});
-
-test('Parse MAX Aggregate Query', () => {
- const query = 'SELECT MAX(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['MAX(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null
- });
-});
-
-test('Parse basic GROUP BY query', () => {
- const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['age', 'COUNT(*)'],
- table: 'student',
- whereClauses: [],
- groupByFields: ['age'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null
- });
-});
-
-test('Parse GROUP BY query with WHERE clause', () => {
- const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['age', 'COUNT(*)'],
- table: 'student',
- whereClauses: [{ field: 'age', operator: '>', value: '22' }],
- groupByFields: ['age'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null
- });
-});
-
-test('Parse GROUP BY query with multiple fields', () => {
- const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['student_id', 'course', 'COUNT(*)'],
- table: 'enrollment',
- whereClauses: [],
- groupByFields: ['student_id', 'course'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null
- });
-});
-
-test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
- const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['student.name', 'COUNT(*)'],
- table: 'student',
- whereClauses: [{ field: 'enrollment.course', operator: '=', value: '"Mathematics"' }],
- groupByFields: ['student.name'],
- joinType: 'INNER',
- joinTable: 'enrollment',
- joinCondition: {
- left: 'student.id',
- right: 'enrollment.student_id'
- },
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- });
-});
-
-test('Execute SQL Query with ORDER BY', async () => {
- const query = 'SELECT name FROM student ORDER BY name ASC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { name: 'Alice' },
- { name: 'Bob' },
- { name: 'Jane' },
- { name: 'John' }
- ]);
-});
-
-test('Execute SQL Query with ORDER BY and WHERE', async () => {
- const query = 'SELECT name FROM student WHERE age > 24 ORDER BY name DESC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { name: 'John' },
- { name: 'Jane' },
- ]);
-});
-test('Execute SQL Query with ORDER BY and GROUP BY', async () => {
- const query = 'SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { age: '30', 'COUNT(id) as count': 1 },
- { age: '25', 'COUNT(id) as count': 1 },
- { age: '24', 'COUNT(id) as count': 1 },
- { age: '22', 'COUNT(id) as count': 1 }
- ]);
-});
-
-test('Execute SQL Query with standard LIMIT clause', async () => {
- const query = 'SELECT id, name FROM student LIMIT 2';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(2);
-});
-
-test('Execute SQL Query with LIMIT clause equal to total rows', async () => {
- const query = 'SELECT id, name FROM student LIMIT 4';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(4);
-});
-
-test('Execute SQL Query with LIMIT clause exceeding total rows', async () => {
- const query = 'SELECT id, name FROM student LIMIT 10';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(4); // Total rows in student.csv
-});
-
-test('Execute SQL Query with LIMIT 0', async () => {
- const query = 'SELECT id, name FROM student LIMIT 0';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(0);
-});
-
-test('Execute SQL Query with LIMIT and ORDER BY clause', async () => {
- const query = 'SELECT id, name FROM student ORDER BY age DESC LIMIT 2';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(2);
- expect(result[0].name).toEqual('John');
- expect(result[1].name).toEqual('Jane');
-});
-
-test('Error Handling with Malformed Query', async () => {
- const query = 'SELECT FROM table'; // intentionally malformed
- await expect(executeSELECTQuery(query)).rejects.toThrow("Error executing query: Query parsing error: Invalid SELECT format");
-});
\ No newline at end of file
diff --git a/tests/step-14/index.test.js b/tests/step-14/index.test.js
index 502411fa7..a2f937e4f 100644
--- a/tests/step-14/index.test.js
+++ b/tests/step-14/index.test.js
@@ -1,59 +1,60 @@
-const readCSV = require('../../src/csvReader');
-const {parseQuery, parseJoinClause} = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
-
-test('Read CSV File', async () => {
- const data = await readCSV('./student.csv');
- expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(4);
- expect(data[0].name).toBe('John');
- expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
-});
-
-test('Execute SQL Query', async () => {
- const query = 'SELECT id, name FROM student';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBeGreaterThan(0);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0]).not.toHaveProperty('age');
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0].id).toBe('2');
-});
-
-test('Execute SQL Query with Complex WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with Greater Than', async () => {
- const queryWithGT = 'SELECT id FROM student WHERE age > 22';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('id');
-});
-
-test('Execute SQL Query with Not Equal to', async () => {
- const queryWithGT = 'SELECT name FROM student WHERE age != 25';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('name');
-});
-
-test('Execute SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- /*
+const { readCSV } = require("../../src/csvReader");
+const { parseSelectQuery, parseJoinClause } = require("../../src/queryParser");
+const { executeSELECTQuery } = require("../../src/queryExecutor");
+
+test("Read CSV File", async () => {
+ const data = await readCSV("./student.csv");
+ expect(data.length).toBeGreaterThan(0);
+ expect(data.length).toBe(4);
+ expect(data[0].name).toBe("John");
+ expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later
+});
+
+test("Execute SQL Query", async () => {
+ const query = "SELECT id, name FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBeGreaterThan(0);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0]).not.toHaveProperty("age");
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0].id).toBe("2");
+});
+
+test("Execute SQL Query with Complex WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with Greater Than", async () => {
+ const queryWithGT = "SELECT id FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("id");
+});
+
+test("Execute SQL Query with Not Equal to", async () => {
+ const queryWithGT = "SELECT name FROM student WHERE age != 25";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("name");
+});
+
+test("Execute SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{ 'student.name': 'John', 'enrollment.course': 'Mathematics' },
{ 'student.name': 'John', 'enrollment.course': 'Physics' },
@@ -61,18 +62,21 @@ test('Execute SQL Query with INNER JOIN', async () => {
{ 'student.name': 'Bob', 'enrollment.course': 'Mathematics' }
]
*/
- expect(result.length).toEqual(4);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
+ expect(result.length).toEqual(4);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ })
+ );
});
-test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25';
- const result = await executeSELECTQuery(query);
- /*
+test("Execute SQL Query with INNER JOIN and a WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{
'student.name': 'John',
@@ -86,702 +90,776 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
}
]
*/
- expect(result.length).toEqual(2);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
-});
-
-test('Execute SQL Query with LEFT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "Alice", "enrollment.course": null }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 students, but John appears twice
-});
-
-test('Execute SQL Query with RIGHT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": null, "enrollment.course": "Biology" }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
-});
-
-test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "John" }),
- expect.objectContaining({ "enrollment.course": "Physics", "student.name": "John" })
- ]));
- expect(result.length).toEqual(4);
-});
-
-test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Physics" })
- ]));
- expect(result.length).toEqual(1);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "Bob" }),
- expect.objectContaining({ "enrollment.course": "Biology", "student.name": null })
- ]));
- expect(result.length).toEqual(2);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Chemistry", "student.name": "Jane" }),
- ]));
- expect(result.length).toEqual(1);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([]);
-});
-
-test('Execute COUNT Aggregate Query', async () => {
- const query = 'SELECT COUNT(*) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'COUNT(*)': 4 }]);
-});
-
-test('Execute SUM Aggregate Query', async () => {
- const query = 'SELECT SUM(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'SUM(age)': 101 }]);
-});
-
-test('Execute AVG Aggregate Query', async () => {
- const query = 'SELECT AVG(age) FROM student';
- const result = await executeSELECTQuery(query);
- // Assuming AVG returns a single decimal point value
- expect(result).toEqual([{ 'AVG(age)': 25.25 }]);
-});
-
-test('Execute MIN Aggregate Query', async () => {
- const query = 'SELECT MIN(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'MIN(age)': 22 }]);
-});
-
-test('Execute MAX Aggregate Query', async () => {
- const query = 'SELECT MAX(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'MAX(age)': 30 }]);
-});
-
-test('Count students per age', async () => {
- const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { age: '22', 'COUNT(*)': 1 },
- { age: '24', 'COUNT(*)': 1 },
- { age: '25', 'COUNT(*)': 1 },
- { age: '30', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count enrollments per course', async () => {
- const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { course: 'Mathematics', 'COUNT(*)': 2 },
- { course: 'Physics', 'COUNT(*)': 1 },
- { course: 'Chemistry', 'COUNT(*)': 1 },
- { course: 'Biology', 'COUNT(*)': 1 }
- ]);
-});
-
-
-test('Count courses per student', async () => {
- const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { student_id: '1', 'COUNT(*)': 2 },
- { student_id: '2', 'COUNT(*)': 1 },
- { student_id: '3', 'COUNT(*)': 1 },
- { student_id: '5', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count students within a specific age range', async () => {
- const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { age: '24', 'COUNT(*)': 1 },
- { age: '25', 'COUNT(*)': 1 },
- { age: '30', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count enrollments for a specific course', async () => {
- const query = 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { course: 'Mathematics', 'COUNT(*)': 2 }
- ]);
-});
-
-test('Count courses for a specific student', async () => {
- const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { student_id: '1', 'COUNT(*)': 2 }
- ]);
-});
-
-test('Average age of students above a certain age', async () => {
- const query = 'SELECT AVG(age) FROM student WHERE age > 22';
- const result = await executeSELECTQuery(query);
- const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
- expect(result).toEqual([{ 'AVG(age)': expectedAverage }]);
-});
-
-test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with WHERE Clause', () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "25",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with Multiple WHERE Clauses', () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "30",
- }, {
- "field": "name",
- "operator": "=",
- "value": "John",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinTable: 'enrollment',
- joinType: "INNER",
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
+ expect(result.length).toEqual(2);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
})
-});
-
-test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [{ field: 'student.age', operator: '>', value: '20' }],
- joinTable: 'enrollment',
- joinType: "INNER",
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- })
-});
-
-test('Parse INNER JOIN clause', () => {
- const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'INNER',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' },
- });
-});
-
-test('Parse LEFT JOIN clause', () => {
- const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'LEFT',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' }
- });
-});
-
-test('Parse RIGHT JOIN clause', () => {
- const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'RIGHT',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' }
- });
-});
-
-test('Returns null for queries without JOIN', () => {
- const query = 'SELECT * FROM table1';
- const result = parseJoinClause(query);
- expect(result).toEqual(
- {
- joinType: null,
- joinTable: null,
- joinCondition: null
- }
- );
-});
-
-test('Parse LEFT Join Query Completely', () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinType: 'LEFT',
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- })
-})
-
-test('Parse LEFT Join Query Completely', () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinType: 'RIGHT',
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- })
-})
-
-test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "LEFT",
- "table": "student",
- "whereClauses": [{ "field": "student.age", "operator": ">", "value": "22" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "LEFT",
- "table": "student",
- "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Physics'" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "RIGHT",
- "table": "student",
- "whereClauses": [{ "field": "student.age", "operator": "<", "value": "25" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "RIGHT",
- "table": "student",
- "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Chemistry'" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-
-test('Parse COUNT Aggregate Query', () => {
- const query = 'SELECT COUNT(*) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['COUNT(*)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-
-test('Parse SUM Aggregate Query', () => {
- const query = 'SELECT SUM(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['SUM(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse AVG Aggregate Query', () => {
- const query = 'SELECT AVG(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['AVG(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse MIN Aggregate Query', () => {
- const query = 'SELECT MIN(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['MIN(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse MAX Aggregate Query', () => {
- const query = 'SELECT MAX(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['MAX(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse basic GROUP BY query', () => {
- const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['age', 'COUNT(*)'],
- table: 'student',
- whereClauses: [],
- groupByFields: ['age'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse GROUP BY query with WHERE clause', () => {
- const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['age', 'COUNT(*)'],
- table: 'student',
- whereClauses: [{ field: 'age', operator: '>', value: '22' }],
- groupByFields: ['age'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse GROUP BY query with multiple fields', () => {
- const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['student_id', 'course', 'COUNT(*)'],
- table: 'enrollment',
- whereClauses: [],
- groupByFields: ['student_id', 'course'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
- const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['student.name', 'COUNT(*)'],
- table: 'student',
- whereClauses: [{ field: 'enrollment.course', operator: '=', value: '"Mathematics"' }],
- groupByFields: ['student.name'],
- joinType: 'INNER',
- joinTable: 'enrollment',
- joinCondition: {
- left: 'student.id',
- right: 'enrollment.student_id'
- },
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false,
- });
-});
-
-test('Execute SQL Query with ORDER BY', async () => {
- const query = 'SELECT name FROM student ORDER BY name ASC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { name: 'Alice' },
- { name: 'Bob' },
- { name: 'Jane' },
- { name: 'John' }
- ]);
-});
-
-test('Execute SQL Query with ORDER BY and WHERE', async () => {
- const query = 'SELECT name FROM student WHERE age > 24 ORDER BY name DESC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { name: 'John' },
- { name: 'Jane' },
- ]);
-});
-test('Execute SQL Query with ORDER BY and GROUP BY', async () => {
- const query = 'SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { age: '30', 'COUNT(id) as count': 1 },
- { age: '25', 'COUNT(id) as count': 1 },
- { age: '24', 'COUNT(id) as count': 1 },
- { age: '22', 'COUNT(id) as count': 1 }
- ]);
-});
-
-test('Execute SQL Query with standard LIMIT clause', async () => {
- const query = 'SELECT id, name FROM student LIMIT 2';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(2);
-});
-
-test('Execute SQL Query with LIMIT clause equal to total rows', async () => {
- const query = 'SELECT id, name FROM student LIMIT 4';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(4);
-});
-
-test('Execute SQL Query with LIMIT clause exceeding total rows', async () => {
- const query = 'SELECT id, name FROM student LIMIT 10';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(4); // Total rows in student.csv
-});
-
-test('Execute SQL Query with LIMIT 0', async () => {
- const query = 'SELECT id, name FROM student LIMIT 0';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(0);
-});
-
-test('Execute SQL Query with LIMIT and ORDER BY clause', async () => {
- const query = 'SELECT id, name FROM student ORDER BY age DESC LIMIT 2';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(2);
- expect(result[0].name).toEqual('John');
- expect(result[1].name).toEqual('Jane');
-});
-
-test('Error Handling with Malformed Query', async () => {
- const query = 'SELECT FROM table'; // intentionally malformed
- await expect(executeSELECTQuery(query)).rejects.toThrow("Error executing query: Query parsing error: Invalid SELECT format");
-});
-
-test('Basic DISTINCT Usage', async () => {
- const query = 'SELECT DISTINCT age FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ age: '30' }, { age: '25' }, { age: '22' }, { age: '24' }]);
-});
-
-test('DISTINCT with Multiple Columns', async () => {
- const query = 'SELECT DISTINCT student_id, course FROM enrollment';
- const result = await executeSELECTQuery(query);
- // Expecting unique combinations of student_id and course
- expect(result).toEqual([
- { student_id: '1', course: 'Mathematics' },
- { student_id: '1', course: 'Physics' },
- { student_id: '2', course: 'Chemistry' },
- { student_id: '3', course: 'Mathematics' },
- { student_id: '5', course: 'Biology' },
- ]);
+ );
+});
+
+test("Execute SQL Query with LEFT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "Alice",
+ "enrollment.course": null,
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 students, but John appears twice
+});
+
+test("Execute SQL Query with RIGHT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": null,
+ "enrollment.course": "Biology",
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Physics",
+ "student.name": "John",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(4);
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Physics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "Bob",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Biology",
+ "student.name": null,
+ }),
+ ])
+ );
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Chemistry",
+ "student.name": "Jane",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([]);
+});
+
+test("Execute COUNT Aggregate Query", async () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "COUNT(*)": 4 }]);
+});
+
+test("Execute SUM Aggregate Query", async () => {
+ const query = "SELECT SUM(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "SUM(age)": 101 }]);
+});
+
+test("Execute AVG Aggregate Query", async () => {
+ const query = "SELECT AVG(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ // Assuming AVG returns a single decimal point value
+ expect(result).toEqual([{ "AVG(age)": 25.25 }]);
+});
+
+test("Execute MIN Aggregate Query", async () => {
+ const query = "SELECT MIN(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MIN(age)": 22 }]);
+});
+
+test("Execute MAX Aggregate Query", async () => {
+ const query = "SELECT MAX(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MAX(age)": 30 }]);
+});
+
+test("Count students per age", async () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "22", "COUNT(*)": 1 },
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments per course", async () => {
+ const query = "SELECT course, COUNT(*) FROM enrollment GROUP BY course";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { course: "Mathematics", "COUNT(*)": 2 },
+ { course: "Physics", "COUNT(*)": 1 },
+ { course: "Chemistry", "COUNT(*)": 1 },
+ { course: "Biology", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count courses per student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { student_id: "1", "COUNT(*)": 2 },
+ { student_id: "2", "COUNT(*)": 1 },
+ { student_id: "3", "COUNT(*)": 1 },
+ { student_id: "5", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count students within a specific age range", async () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments for a specific course", async () => {
+ const query =
+ 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ course: "Mathematics", "COUNT(*)": 2 }]);
+});
+
+test("Count courses for a specific student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ student_id: "1", "COUNT(*)": 2 }]);
+});
+
+test("Average age of students above a certain age", async () => {
+ const query = "SELECT AVG(age) FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(query);
+ const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
+ expect(result).toEqual([{ "AVG(age)": expectedAverage }]);
+});
+
+test("Parse SQL Query", () => {
+ const query = "SELECT id, name FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with WHERE Clause", () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "25",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with Multiple WHERE Clauses", () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "30",
+ },
+ {
+ field: "name",
+ operator: "=",
+ value: "John",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN and WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "20" }],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse INNER JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "INNER",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse LEFT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "LEFT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse RIGHT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "RIGHT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Returns null for queries without JOIN", () => {
+ const query = "SELECT * FROM table1";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "LEFT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "RIGHT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "22" }],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Physics'" },
+ ],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: "<", value: "25" }],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Chemistry'" },
+ ],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse COUNT Aggregate Query", () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SUM Aggregate Query", () => {
+ const query = "SELECT SUM(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["SUM(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse AVG Aggregate Query", () => {
+ const query = "SELECT AVG(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["AVG(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MIN Aggregate Query", () => {
+ const query = "SELECT MIN(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MIN(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MAX Aggregate Query", () => {
+ const query = "SELECT MAX(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MAX(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse basic GROUP BY query", () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with WHERE clause", () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [{ field: "age", operator: ">", value: "22" }],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with multiple fields", () => {
+ const query =
+ "SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student_id", "course", "COUNT(*)"],
+ table: "enrollment",
+ whereClauses: [],
+ groupByFields: ["student_id", "course"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with JOIN and WHERE clauses", () => {
+ const query =
+ 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student.name", "COUNT(*)"],
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: '"Mathematics"' },
+ ],
+ groupByFields: ["student.name"],
+ joinType: "INNER",
+ joinTable: "enrollment",
+ joinCondition: {
+ left: "student.id",
+ right: "enrollment.student_id",
+ },
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Execute SQL Query with ORDER BY", async () => {
+ const query = "SELECT name FROM student ORDER BY name ASC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([
+ { name: "Alice" },
+ { name: "Bob" },
+ { name: "Jane" },
+ { name: "John" },
+ ]);
+});
+
+test("Execute SQL Query with ORDER BY and WHERE", async () => {
+ const query = "SELECT name FROM student WHERE age > 24 ORDER BY name DESC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([{ name: "John" }, { name: "Jane" }]);
+});
+test("Execute SQL Query with ORDER BY and GROUP BY", async () => {
+ const query =
+ "SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([
+ { age: "30", "COUNT(id) as count": 1 },
+ { age: "25", "COUNT(id) as count": 1 },
+ { age: "24", "COUNT(id) as count": 1 },
+ { age: "22", "COUNT(id) as count": 1 },
+ ]);
+});
+
+test("Execute SQL Query with standard LIMIT clause", async () => {
+ const query = "SELECT id, name FROM student LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with LIMIT clause equal to total rows", async () => {
+ const query = "SELECT id, name FROM student LIMIT 4";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(4);
+});
+
+test("Execute SQL Query with LIMIT clause exceeding total rows", async () => {
+ const query = "SELECT id, name FROM student LIMIT 10";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(4); // Total rows in student.csv
+});
+
+test("Execute SQL Query with LIMIT 0", async () => {
+ const query = "SELECT id, name FROM student LIMIT 0";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(0);
+});
+
+test("Execute SQL Query with LIMIT and ORDER BY clause", async () => {
+ const query = "SELECT id, name FROM student ORDER BY age DESC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(2);
+ expect(result[0].name).toEqual("John");
+ expect(result[1].name).toEqual("Jane");
+});
+
+test("Error Handling with Malformed Query", async () => {
+ const query = "SELECT FROM table"; // intentionally malformed
+ await expect(executeSELECTQuery(query)).rejects.toThrow(
+ "Error executing query: Query parsing error: Invalid SELECT format"
+ );
+});
+
+test("Basic DISTINCT Usage", async () => {
+ const query = "SELECT DISTINCT age FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "30" },
+ { age: "25" },
+ { age: "22" },
+ { age: "24" },
+ ]);
+});
+
+test("DISTINCT with Multiple Columns", async () => {
+ const query = "SELECT DISTINCT student_id, course FROM enrollment";
+ const result = await executeSELECTQuery(query);
+ // Expecting unique combinations of student_id and course
+ expect(result).toEqual([
+ { student_id: "1", course: "Mathematics" },
+ { student_id: "1", course: "Physics" },
+ { student_id: "2", course: "Chemistry" },
+ { student_id: "3", course: "Mathematics" },
+ { student_id: "5", course: "Biology" },
+ ]);
});
// Not a good test right now
-test('DISTINCT with WHERE Clause', async () => {
- const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"';
- const result = await executeSELECTQuery(query);
- // Expecting courses taken by student with ID 1
- expect(result).toEqual([{ course: 'Mathematics' }, { course: 'Physics' }]);
-});
-
-test('DISTINCT with JOIN Operations', async () => {
- const query = 'SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id';
- const result = await executeSELECTQuery(query);
- // Expecting names of students who are enrolled in any course
- expect(result).toEqual([{ "student.name": 'John' }, { "student.name": 'Jane' }, { "student.name": 'Bob' }]);
-});
-
-test('DISTINCT with ORDER BY and LIMIT', async () => {
- const query = 'SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2';
- const result = await executeSELECTQuery(query);
- // Expecting the two highest unique ages
- expect(result).toEqual([{ age: '30' }, { age: '25' }]);
-});
\ No newline at end of file
+test("DISTINCT with WHERE Clause", async () => {
+ const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"';
+ const result = await executeSELECTQuery(query);
+ // Expecting courses taken by student with ID 1
+ expect(result).toEqual([{ course: "Mathematics" }, { course: "Physics" }]);
+});
+
+test("DISTINCT with JOIN Operations", async () => {
+ const query =
+ "SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ // Expecting names of students who are enrolled in any course
+ expect(result).toEqual([
+ { "student.name": "John" },
+ { "student.name": "Jane" },
+ { "student.name": "Bob" },
+ ]);
+});
+
+test("DISTINCT with ORDER BY and LIMIT", async () => {
+ const query = "SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ // Expecting the two highest unique ages
+ expect(result).toEqual([{ age: "30" }, { age: "25" }]);
+});
diff --git a/tests/step-15/index.test.js b/tests/step-15/index.test.js
index a2aa4daee..7847e800c 100644
--- a/tests/step-15/index.test.js
+++ b/tests/step-15/index.test.js
@@ -1,59 +1,60 @@
-const readCSV = require('../../src/csvReader');
-const {parseQuery, parseJoinClause} = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
-
-test('Read CSV File', async () => {
- const data = await readCSV('./student.csv');
- expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(4);
- expect(data[0].name).toBe('John');
- expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
-});
-
-test('Execute SQL Query', async () => {
- const query = 'SELECT id, name FROM student';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBeGreaterThan(0);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0]).not.toHaveProperty('age');
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0].id).toBe('2');
-});
-
-test('Execute SQL Query with Complex WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with Greater Than', async () => {
- const queryWithGT = 'SELECT id FROM student WHERE age > 22';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('id');
-});
-
-test('Execute SQL Query with Not Equal to', async () => {
- const queryWithGT = 'SELECT name FROM student WHERE age != 25';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('name');
-});
-
-test('Execute SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- /*
+const { readCSV } = require("../../src/csvReader");
+const { parseSelectQuery, parseJoinClause } = require("../../src/queryParser");
+const { executeSELECTQuery } = require("../../src/queryExecutor");
+
+test("Read CSV File", async () => {
+ const data = await readCSV("./student.csv");
+ expect(data.length).toBeGreaterThan(0);
+ expect(data.length).toBe(4);
+ expect(data[0].name).toBe("John");
+ expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later
+});
+
+test("Execute SQL Query", async () => {
+ const query = "SELECT id, name FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBeGreaterThan(0);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0]).not.toHaveProperty("age");
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0].id).toBe("2");
+});
+
+test("Execute SQL Query with Complex WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with Greater Than", async () => {
+ const queryWithGT = "SELECT id FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("id");
+});
+
+test("Execute SQL Query with Not Equal to", async () => {
+ const queryWithGT = "SELECT name FROM student WHERE age != 25";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("name");
+});
+
+test("Execute SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{ 'student.name': 'John', 'enrollment.course': 'Mathematics' },
{ 'student.name': 'John', 'enrollment.course': 'Physics' },
@@ -61,18 +62,21 @@ test('Execute SQL Query with INNER JOIN', async () => {
{ 'student.name': 'Bob', 'enrollment.course': 'Mathematics' }
]
*/
- expect(result.length).toEqual(4);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
+ expect(result.length).toEqual(4);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ })
+ );
});
-test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25';
- const result = await executeSELECTQuery(query);
- /*
+test("Execute SQL Query with INNER JOIN and a WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{
'student.name': 'John',
@@ -86,737 +90,888 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
}
]
*/
- expect(result.length).toEqual(2);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
-});
-
-test('Execute SQL Query with LEFT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "Alice", "enrollment.course": null }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 students, but John appears twice
-});
-
-test('Execute SQL Query with RIGHT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": null, "enrollment.course": "Biology" }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
-});
-
-test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "John" }),
- expect.objectContaining({ "enrollment.course": "Physics", "student.name": "John" })
- ]));
- expect(result.length).toEqual(4);
-});
-
-test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Physics" })
- ]));
- expect(result.length).toEqual(1);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "Bob" }),
- expect.objectContaining({ "enrollment.course": "Biology", "student.name": null })
- ]));
- expect(result.length).toEqual(2);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Chemistry", "student.name": "Jane" }),
- ]));
- expect(result.length).toEqual(1);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([]);
-});
-
-test('Execute COUNT Aggregate Query', async () => {
- const query = 'SELECT COUNT(*) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'COUNT(*)': 4 }]);
-});
-
-test('Execute SUM Aggregate Query', async () => {
- const query = 'SELECT SUM(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'SUM(age)': 101 }]);
-});
-
-test('Execute AVG Aggregate Query', async () => {
- const query = 'SELECT AVG(age) FROM student';
- const result = await executeSELECTQuery(query);
- // Assuming AVG returns a single decimal point value
- expect(result).toEqual([{ 'AVG(age)': 25.25 }]);
-});
-
-test('Execute MIN Aggregate Query', async () => {
- const query = 'SELECT MIN(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'MIN(age)': 22 }]);
-});
-
-test('Execute MAX Aggregate Query', async () => {
- const query = 'SELECT MAX(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'MAX(age)': 30 }]);
-});
-
-test('Count students per age', async () => {
- const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { age: '22', 'COUNT(*)': 1 },
- { age: '24', 'COUNT(*)': 1 },
- { age: '25', 'COUNT(*)': 1 },
- { age: '30', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count enrollments per course', async () => {
- const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { course: 'Mathematics', 'COUNT(*)': 2 },
- { course: 'Physics', 'COUNT(*)': 1 },
- { course: 'Chemistry', 'COUNT(*)': 1 },
- { course: 'Biology', 'COUNT(*)': 1 }
- ]);
-});
-
-
-test('Count courses per student', async () => {
- const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { student_id: '1', 'COUNT(*)': 2 },
- { student_id: '2', 'COUNT(*)': 1 },
- { student_id: '3', 'COUNT(*)': 1 },
- { student_id: '5', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count students within a specific age range', async () => {
- const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { age: '24', 'COUNT(*)': 1 },
- { age: '25', 'COUNT(*)': 1 },
- { age: '30', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count enrollments for a specific course', async () => {
- const query = 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { course: 'Mathematics', 'COUNT(*)': 2 }
- ]);
-});
-
-test('Count courses for a specific student', async () => {
- const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { student_id: '1', 'COUNT(*)': 2 }
- ]);
-});
-
-test('Average age of students above a certain age', async () => {
- const query = 'SELECT AVG(age) FROM student WHERE age > 22';
- const result = await executeSELECTQuery(query);
- const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
- expect(result).toEqual([{ 'AVG(age)': expectedAverage }]);
-});
-
-test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with WHERE Clause', () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "25",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with Multiple WHERE Clauses', () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "30",
- }, {
- "field": "name",
- "operator": "=",
- "value": "John",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinTable: 'enrollment',
- joinType: "INNER",
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- })
-});
-
-test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [{ field: 'student.age', operator: '>', value: '20' }],
- joinTable: 'enrollment',
- joinType: "INNER",
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
+ expect(result.length).toEqual(2);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
})
-});
-
-test('Parse INNER JOIN clause', () => {
- const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'INNER',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' },
- });
-});
-
-test('Parse LEFT JOIN clause', () => {
- const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'LEFT',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' }
- });
-});
-
-test('Parse RIGHT JOIN clause', () => {
- const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'RIGHT',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' }
- });
-});
-
-test('Returns null for queries without JOIN', () => {
- const query = 'SELECT * FROM table1';
- const result = parseJoinClause(query);
- expect(result).toEqual(
- {
- joinType: null,
- joinTable: null,
- joinCondition: null
- }
- );
-});
-
-test('Parse LEFT Join Query Completely', () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinType: 'LEFT',
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- })
-})
-
-test('Parse LEFT Join Query Completely', () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinType: 'RIGHT',
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- })
-})
-
-test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "LEFT",
- "table": "student",
- "whereClauses": [{ "field": "student.age", "operator": ">", "value": "22" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "LEFT",
- "table": "student",
- "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Physics'" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "RIGHT",
- "table": "student",
- "whereClauses": [{ "field": "student.age", "operator": "<", "value": "25" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "RIGHT",
- "table": "student",
- "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Chemistry'" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-
-test('Parse COUNT Aggregate Query', () => {
- const query = 'SELECT COUNT(*) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['COUNT(*)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-
-test('Parse SUM Aggregate Query', () => {
- const query = 'SELECT SUM(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['SUM(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse AVG Aggregate Query', () => {
- const query = 'SELECT AVG(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['AVG(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse MIN Aggregate Query', () => {
- const query = 'SELECT MIN(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['MIN(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse MAX Aggregate Query', () => {
- const query = 'SELECT MAX(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['MAX(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse basic GROUP BY query', () => {
- const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['age', 'COUNT(*)'],
- table: 'student',
- whereClauses: [],
- groupByFields: ['age'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse GROUP BY query with WHERE clause', () => {
- const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['age', 'COUNT(*)'],
- table: 'student',
- whereClauses: [{ field: 'age', operator: '>', value: '22' }],
- groupByFields: ['age'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse GROUP BY query with multiple fields', () => {
- const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['student_id', 'course', 'COUNT(*)'],
- table: 'enrollment',
- whereClauses: [],
- groupByFields: ['student_id', 'course'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
- const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['student.name', 'COUNT(*)'],
- table: 'student',
- whereClauses: [{ field: 'enrollment.course', operator: '=', value: '"Mathematics"' }],
- groupByFields: ['student.name'],
- joinType: 'INNER',
- joinTable: 'enrollment',
- joinCondition: {
- left: 'student.id',
- right: 'enrollment.student_id'
- },
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false,
- });
-});
-
-test('Execute SQL Query with ORDER BY', async () => {
- const query = 'SELECT name FROM student ORDER BY name ASC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { name: 'Alice' },
- { name: 'Bob' },
- { name: 'Jane' },
- { name: 'John' }
- ]);
-});
-
-test('Execute SQL Query with ORDER BY and WHERE', async () => {
- const query = 'SELECT name FROM student WHERE age > 24 ORDER BY name DESC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { name: 'John' },
- { name: 'Jane' },
- ]);
-});
-test('Execute SQL Query with ORDER BY and GROUP BY', async () => {
- const query = 'SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { age: '30', 'COUNT(id) as count': 1 },
- { age: '25', 'COUNT(id) as count': 1 },
- { age: '24', 'COUNT(id) as count': 1 },
- { age: '22', 'COUNT(id) as count': 1 }
- ]);
-});
-
-test('Execute SQL Query with standard LIMIT clause', async () => {
- const query = 'SELECT id, name FROM student LIMIT 2';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(2);
-});
-
-test('Execute SQL Query with LIMIT clause equal to total rows', async () => {
- const query = 'SELECT id, name FROM student LIMIT 4';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(4);
-});
-
-test('Execute SQL Query with LIMIT clause exceeding total rows', async () => {
- const query = 'SELECT id, name FROM student LIMIT 10';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(4); // Total rows in student.csv
-});
-
-test('Execute SQL Query with LIMIT 0', async () => {
- const query = 'SELECT id, name FROM student LIMIT 0';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(0);
-});
-
-test('Execute SQL Query with LIMIT and ORDER BY clause', async () => {
- const query = 'SELECT id, name FROM student ORDER BY age DESC LIMIT 2';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(2);
- expect(result[0].name).toEqual('John');
- expect(result[1].name).toEqual('Jane');
-});
-
-test('Error Handling with Malformed Query', async () => {
- const query = 'SELECT FROM table'; // intentionally malformed
- await expect(executeSELECTQuery(query)).rejects.toThrow("Error executing query: Query parsing error: Invalid SELECT format");
-});
-
-test('Basic DISTINCT Usage', async () => {
- const query = 'SELECT DISTINCT age FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ age: '30' }, { age: '25' }, { age: '22' }, { age: '24' }]);
-});
-
-test('DISTINCT with Multiple Columns', async () => {
- const query = 'SELECT DISTINCT student_id, course FROM enrollment';
- const result = await executeSELECTQuery(query);
- // Expecting unique combinations of student_id and course
- expect(result).toEqual([
- { student_id: '1', course: 'Mathematics' },
- { student_id: '1', course: 'Physics' },
- { student_id: '2', course: 'Chemistry' },
- { student_id: '3', course: 'Mathematics' },
- { student_id: '5', course: 'Biology' },
- ]);
+ );
+});
+
+test("Execute SQL Query with LEFT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "Alice",
+ "enrollment.course": null,
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 students, but John appears twice
+});
+
+test("Execute SQL Query with RIGHT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": null,
+ "enrollment.course": "Biology",
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Physics",
+ "student.name": "John",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(4);
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Physics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "Bob",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Biology",
+ "student.name": null,
+ }),
+ ])
+ );
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Chemistry",
+ "student.name": "Jane",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([]);
+});
+
+test("Execute COUNT Aggregate Query", async () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "COUNT(*)": 4 }]);
+});
+
+test("Execute SUM Aggregate Query", async () => {
+ const query = "SELECT SUM(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "SUM(age)": 101 }]);
+});
+
+test("Execute AVG Aggregate Query", async () => {
+ const query = "SELECT AVG(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ // Assuming AVG returns a single decimal point value
+ expect(result).toEqual([{ "AVG(age)": 25.25 }]);
+});
+
+test("Execute MIN Aggregate Query", async () => {
+ const query = "SELECT MIN(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MIN(age)": 22 }]);
+});
+
+test("Execute MAX Aggregate Query", async () => {
+ const query = "SELECT MAX(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MAX(age)": 30 }]);
+});
+
+test("Count students per age", async () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "22", "COUNT(*)": 1 },
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments per course", async () => {
+ const query = "SELECT course, COUNT(*) FROM enrollment GROUP BY course";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { course: "Mathematics", "COUNT(*)": 2 },
+ { course: "Physics", "COUNT(*)": 1 },
+ { course: "Chemistry", "COUNT(*)": 1 },
+ { course: "Biology", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count courses per student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { student_id: "1", "COUNT(*)": 2 },
+ { student_id: "2", "COUNT(*)": 1 },
+ { student_id: "3", "COUNT(*)": 1 },
+ { student_id: "5", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count students within a specific age range", async () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments for a specific course", async () => {
+ const query =
+ 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ course: "Mathematics", "COUNT(*)": 2 }]);
+});
+
+test("Count courses for a specific student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ student_id: "1", "COUNT(*)": 2 }]);
+});
+
+test("Average age of students above a certain age", async () => {
+ const query = "SELECT AVG(age) FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(query);
+ const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
+ expect(result).toEqual([{ "AVG(age)": expectedAverage }]);
+});
+
+test("Parse SQL Query", () => {
+ const query = "SELECT id, name FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with WHERE Clause", () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "25",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with Multiple WHERE Clauses", () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "30",
+ },
+ {
+ field: "name",
+ operator: "=",
+ value: "John",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN and WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "20" }],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse INNER JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "INNER",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse LEFT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "LEFT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse RIGHT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "RIGHT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Returns null for queries without JOIN", () => {
+ const query = "SELECT * FROM table1";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "LEFT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "RIGHT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "22" }],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Physics'" },
+ ],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: "<", value: "25" }],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Chemistry'" },
+ ],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse COUNT Aggregate Query", () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SUM Aggregate Query", () => {
+ const query = "SELECT SUM(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["SUM(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse AVG Aggregate Query", () => {
+ const query = "SELECT AVG(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["AVG(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MIN Aggregate Query", () => {
+ const query = "SELECT MIN(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MIN(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MAX Aggregate Query", () => {
+ const query = "SELECT MAX(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MAX(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse basic GROUP BY query", () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with WHERE clause", () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [{ field: "age", operator: ">", value: "22" }],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with multiple fields", () => {
+ const query =
+ "SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student_id", "course", "COUNT(*)"],
+ table: "enrollment",
+ whereClauses: [],
+ groupByFields: ["student_id", "course"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with JOIN and WHERE clauses", () => {
+ const query =
+ 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student.name", "COUNT(*)"],
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: '"Mathematics"' },
+ ],
+ groupByFields: ["student.name"],
+ joinType: "INNER",
+ joinTable: "enrollment",
+ joinCondition: {
+ left: "student.id",
+ right: "enrollment.student_id",
+ },
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Execute SQL Query with ORDER BY", async () => {
+ const query = "SELECT name FROM student ORDER BY name ASC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([
+ { name: "Alice" },
+ { name: "Bob" },
+ { name: "Jane" },
+ { name: "John" },
+ ]);
+});
+
+test("Execute SQL Query with ORDER BY and WHERE", async () => {
+ const query = "SELECT name FROM student WHERE age > 24 ORDER BY name DESC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([{ name: "John" }, { name: "Jane" }]);
+});
+test("Execute SQL Query with ORDER BY and GROUP BY", async () => {
+ const query =
+ "SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([
+ { age: "30", "COUNT(id) as count": 1 },
+ { age: "25", "COUNT(id) as count": 1 },
+ { age: "24", "COUNT(id) as count": 1 },
+ { age: "22", "COUNT(id) as count": 1 },
+ ]);
+});
+
+test("Execute SQL Query with standard LIMIT clause", async () => {
+ const query = "SELECT id, name FROM student LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with LIMIT clause equal to total rows", async () => {
+ const query = "SELECT id, name FROM student LIMIT 4";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(4);
+});
+
+test("Execute SQL Query with LIMIT clause exceeding total rows", async () => {
+ const query = "SELECT id, name FROM student LIMIT 10";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(4); // Total rows in student.csv
+});
+
+test("Execute SQL Query with LIMIT 0", async () => {
+ const query = "SELECT id, name FROM student LIMIT 0";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(0);
+});
+
+test("Execute SQL Query with LIMIT and ORDER BY clause", async () => {
+ const query = "SELECT id, name FROM student ORDER BY age DESC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(2);
+ expect(result[0].name).toEqual("John");
+ expect(result[1].name).toEqual("Jane");
+});
+
+test("Error Handling with Malformed Query", async () => {
+ const query = "SELECT FROM table"; // intentionally malformed
+ await expect(executeSELECTQuery(query)).rejects.toThrow(
+ "Error executing query: Query parsing error: Invalid SELECT format"
+ );
+});
+
+test("Basic DISTINCT Usage", async () => {
+ const query = "SELECT DISTINCT age FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "30" },
+ { age: "25" },
+ { age: "22" },
+ { age: "24" },
+ ]);
+});
+
+test("DISTINCT with Multiple Columns", async () => {
+ const query = "SELECT DISTINCT student_id, course FROM enrollment";
+ const result = await executeSELECTQuery(query);
+ // Expecting unique combinations of student_id and course
+ expect(result).toEqual([
+ { student_id: "1", course: "Mathematics" },
+ { student_id: "1", course: "Physics" },
+ { student_id: "2", course: "Chemistry" },
+ { student_id: "3", course: "Mathematics" },
+ { student_id: "5", course: "Biology" },
+ ]);
});
// Not a good test right now
-test('DISTINCT with WHERE Clause', async () => {
- const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"';
- const result = await executeSELECTQuery(query);
- // Expecting courses taken by student with ID 1
- expect(result).toEqual([{ course: 'Mathematics' }, { course: 'Physics' }]);
-});
-
-test('DISTINCT with JOIN Operations', async () => {
- const query = 'SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id';
- const result = await executeSELECTQuery(query);
- // Expecting names of students who are enrolled in any course
- expect(result).toEqual([{ "student.name": 'John' }, { "student.name": 'Jane' }, { "student.name": 'Bob' }]);
+test("DISTINCT with WHERE Clause", async () => {
+ const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"';
+ const result = await executeSELECTQuery(query);
+ // Expecting courses taken by student with ID 1
+ expect(result).toEqual([{ course: "Mathematics" }, { course: "Physics" }]);
+});
+
+test("DISTINCT with JOIN Operations", async () => {
+ const query =
+ "SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ // Expecting names of students who are enrolled in any course
+ expect(result).toEqual([
+ { "student.name": "John" },
+ { "student.name": "Jane" },
+ { "student.name": "Bob" },
+ ]);
+});
+
+test("DISTINCT with ORDER BY and LIMIT", async () => {
+ const query = "SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ // Expecting the two highest unique ages
+ expect(result).toEqual([{ age: "30" }, { age: "25" }]);
+});
+
+test("Execute SQL Query with LIKE Operator for Name", async () => {
+ const query = "SELECT name FROM student WHERE name LIKE '%Jane%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting names containing 'Jane'
+ expect(result).toEqual([{ name: "Jane" }]);
+});
+
+test("Execute SQL Query with LIKE Operator and Wildcards", async () => {
+ const query = "SELECT name FROM student WHERE name LIKE 'J%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting names starting with 'J'
+ expect(result).toEqual([{ name: "John" }, { name: "Jane" }]);
+});
+
+test("Execute SQL Query with LIKE Operator Case Insensitive", async () => {
+ const query = "SELECT name FROM student WHERE name LIKE '%bob%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting names 'Bob' (case insensitive)
+ expect(result).toEqual([{ name: "Bob" }]);
+});
+
+test("Execute SQL Query with LIKE Operator and DISTINCT", async () => {
+ const query = "SELECT DISTINCT name FROM student WHERE name LIKE '%e%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting unique names containing 'e'
+ expect(result).toEqual([{ name: "Jane" }, { name: "Alice" }]);
+});
+
+test("LIKE with ORDER BY and LIMIT", async () => {
+ const query =
+ "SELECT name FROM student WHERE name LIKE '%a%' ORDER BY name ASC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ // Expecting the first two names alphabetically that contain 'a'
+ expect(result).toEqual([{ name: "Alice" }, { name: "Jane" }]);
+});
+test("Parse SQL Query with LIKE Clause", () => {
+ const query = "SELECT name FROM student WHERE name LIKE '%Jane%'";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["name"],
+ table: "student",
+ whereClauses: [{ field: "name", operator: "LIKE", value: "%Jane%" }],
+ isDistinct: false,
+ groupByFields: null,
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ orderByFields: null,
+ limit: null,
+ hasAggregateWithoutGroupBy: false,
+ });
+});
+
+test("Parse SQL Query with LIKE Clause and Wildcards", () => {
+ const query = "SELECT name FROM student WHERE name LIKE 'J%'";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["name"],
+ table: "student",
+ whereClauses: [{ field: "name", operator: "LIKE", value: "J%" }],
+ isDistinct: false,
+ groupByFields: null,
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ orderByFields: null,
+ limit: null,
+ hasAggregateWithoutGroupBy: false,
+ });
+});
+
+test("Parse SQL Query with Multiple LIKE Clauses", () => {
+ const query =
+ "SELECT name FROM student WHERE name LIKE 'J%' AND age LIKE '2%'";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["name"],
+ table: "student",
+ whereClauses: [
+ { field: "name", operator: "LIKE", value: "J%" },
+ { field: "age", operator: "LIKE", value: "2%" },
+ ],
+ isDistinct: false,
+ groupByFields: null,
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ orderByFields: null,
+ limit: null,
+ hasAggregateWithoutGroupBy: false,
+ });
+});
+
+test("Parse SQL Query with LIKE and ORDER BY Clauses", () => {
+ const query =
+ "SELECT name FROM student WHERE name LIKE '%e%' ORDER BY age DESC";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["name"],
+ table: "student",
+ whereClauses: [{ field: "name", operator: "LIKE", value: "%e%" }],
+ orderByFields: [{ fieldName: "age", order: "DESC" }],
+ isDistinct: false,
+ groupByFields: null,
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ limit: null,
+ hasAggregateWithoutGroupBy: false,
+ });
});
-
-test('DISTINCT with ORDER BY and LIMIT', async () => {
- const query = 'SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2';
- const result = await executeSELECTQuery(query);
- // Expecting the two highest unique ages
- expect(result).toEqual([{ age: '30' }, { age: '25' }]);
-});
-
-test('Execute SQL Query with LIKE Operator for Name', async () => {
- const query = "SELECT name FROM student WHERE name LIKE '%Jane%'";
- const result = await executeSELECTQuery(query);
- // Expecting names containing 'Jane'
- expect(result).toEqual([{ name: 'Jane' }]);
-});
-
-test('Execute SQL Query with LIKE Operator and Wildcards', async () => {
- const query = "SELECT name FROM student WHERE name LIKE 'J%'";
- const result = await executeSELECTQuery(query);
- // Expecting names starting with 'J'
- expect(result).toEqual([{ name: 'John' }, { name: 'Jane' }]);
-});
-
-test('Execute SQL Query with LIKE Operator Case Insensitive', async () => {
- const query = "SELECT name FROM student WHERE name LIKE '%bob%'";
- const result = await executeSELECTQuery(query);
- // Expecting names 'Bob' (case insensitive)
- expect(result).toEqual([{ name: 'Bob' }]);
-});
-
-test('Execute SQL Query with LIKE Operator and DISTINCT', async () => {
- const query = "SELECT DISTINCT name FROM student WHERE name LIKE '%e%'";
- const result = await executeSELECTQuery(query);
- // Expecting unique names containing 'e'
- expect(result).toEqual([{ name: 'Jane' }, { name: 'Alice' }]);
-});
-
-test('LIKE with ORDER BY and LIMIT', async () => {
- const query = "SELECT name FROM student WHERE name LIKE '%a%' ORDER BY name ASC LIMIT 2";
- const result = await executeSELECTQuery(query);
- // Expecting the first two names alphabetically that contain 'a'
- expect(result).toEqual([{ name: 'Alice' }, { name: 'Jane' }]);
-});
\ No newline at end of file
diff --git a/tests/step-16/index.test.js b/tests/step-16/index.test.js
index a2aa4daee..649bde067 100644
--- a/tests/step-16/index.test.js
+++ b/tests/step-16/index.test.js
@@ -1,59 +1,60 @@
-const readCSV = require('../../src/csvReader');
-const {parseQuery, parseJoinClause} = require('../../src/queryParser');
-const executeSELECTQuery = require('../../src/index');
-
-test('Read CSV File', async () => {
- const data = await readCSV('./student.csv');
- expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(4);
- expect(data[0].name).toBe('John');
- expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
-});
-
-test('Execute SQL Query', async () => {
- const query = 'SELECT id, name FROM student';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBeGreaterThan(0);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0]).not.toHaveProperty('age');
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0].id).toBe('2');
-});
-
-test('Execute SQL Query with Complex WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with Greater Than', async () => {
- const queryWithGT = 'SELECT id FROM student WHERE age > 22';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('id');
-});
-
-test('Execute SQL Query with Not Equal to', async () => {
- const queryWithGT = 'SELECT name FROM student WHERE age != 25';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('name');
-});
-
-test('Execute SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- /*
+const { readCSV } = require("../../src/csvReader");
+const { parseSelectQuery, parseJoinClause } = require("../../src/queryParser");
+const { executeSELECTQuery } = require("../../src/queryExecutor");
+
+test("Read CSV File", async () => {
+ const data = await readCSV("./student.csv");
+ expect(data.length).toBeGreaterThan(0);
+ expect(data.length).toBe(4);
+ expect(data[0].name).toBe("John");
+ expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later
+});
+
+test("Execute SQL Query", async () => {
+ const query = "SELECT id, name FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBeGreaterThan(0);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0]).not.toHaveProperty("age");
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0].id).toBe("2");
+});
+
+test("Execute SQL Query with Complex WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with Greater Than", async () => {
+ const queryWithGT = "SELECT id FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("id");
+});
+
+test("Execute SQL Query with Not Equal to", async () => {
+ const queryWithGT = "SELECT name FROM student WHERE age != 25";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("name");
+});
+
+test("Execute SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{ 'student.name': 'John', 'enrollment.course': 'Mathematics' },
{ 'student.name': 'John', 'enrollment.course': 'Physics' },
@@ -61,18 +62,21 @@ test('Execute SQL Query with INNER JOIN', async () => {
{ 'student.name': 'Bob', 'enrollment.course': 'Mathematics' }
]
*/
- expect(result.length).toEqual(4);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
+ expect(result.length).toEqual(4);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ })
+ );
});
-test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25';
- const result = await executeSELECTQuery(query);
- /*
+test("Execute SQL Query with INNER JOIN and a WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{
'student.name': 'John',
@@ -86,737 +90,812 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
}
]
*/
- expect(result.length).toEqual(2);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
-});
-
-test('Execute SQL Query with LEFT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "Alice", "enrollment.course": null }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 students, but John appears twice
-});
-
-test('Execute SQL Query with RIGHT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": null, "enrollment.course": "Biology" }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
-});
-
-test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "John" }),
- expect.objectContaining({ "enrollment.course": "Physics", "student.name": "John" })
- ]));
- expect(result.length).toEqual(4);
-});
-
-test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Physics" })
- ]));
- expect(result.length).toEqual(1);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "Bob" }),
- expect.objectContaining({ "enrollment.course": "Biology", "student.name": null })
- ]));
- expect(result.length).toEqual(2);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Chemistry", "student.name": "Jane" }),
- ]));
- expect(result.length).toEqual(1);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([]);
-});
-
-test('Execute COUNT Aggregate Query', async () => {
- const query = 'SELECT COUNT(*) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'COUNT(*)': 4 }]);
-});
-
-test('Execute SUM Aggregate Query', async () => {
- const query = 'SELECT SUM(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'SUM(age)': 101 }]);
-});
-
-test('Execute AVG Aggregate Query', async () => {
- const query = 'SELECT AVG(age) FROM student';
- const result = await executeSELECTQuery(query);
- // Assuming AVG returns a single decimal point value
- expect(result).toEqual([{ 'AVG(age)': 25.25 }]);
-});
-
-test('Execute MIN Aggregate Query', async () => {
- const query = 'SELECT MIN(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'MIN(age)': 22 }]);
-});
-
-test('Execute MAX Aggregate Query', async () => {
- const query = 'SELECT MAX(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'MAX(age)': 30 }]);
-});
-
-test('Count students per age', async () => {
- const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { age: '22', 'COUNT(*)': 1 },
- { age: '24', 'COUNT(*)': 1 },
- { age: '25', 'COUNT(*)': 1 },
- { age: '30', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count enrollments per course', async () => {
- const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { course: 'Mathematics', 'COUNT(*)': 2 },
- { course: 'Physics', 'COUNT(*)': 1 },
- { course: 'Chemistry', 'COUNT(*)': 1 },
- { course: 'Biology', 'COUNT(*)': 1 }
- ]);
-});
-
-
-test('Count courses per student', async () => {
- const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { student_id: '1', 'COUNT(*)': 2 },
- { student_id: '2', 'COUNT(*)': 1 },
- { student_id: '3', 'COUNT(*)': 1 },
- { student_id: '5', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count students within a specific age range', async () => {
- const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { age: '24', 'COUNT(*)': 1 },
- { age: '25', 'COUNT(*)': 1 },
- { age: '30', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count enrollments for a specific course', async () => {
- const query = 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { course: 'Mathematics', 'COUNT(*)': 2 }
- ]);
-});
-
-test('Count courses for a specific student', async () => {
- const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { student_id: '1', 'COUNT(*)': 2 }
- ]);
-});
-
-test('Average age of students above a certain age', async () => {
- const query = 'SELECT AVG(age) FROM student WHERE age > 22';
- const result = await executeSELECTQuery(query);
- const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
- expect(result).toEqual([{ 'AVG(age)': expectedAverage }]);
-});
-
-test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with WHERE Clause', () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "25",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with Multiple WHERE Clauses', () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "30",
- }, {
- "field": "name",
- "operator": "=",
- "value": "John",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinTable: 'enrollment',
- joinType: "INNER",
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
+ expect(result.length).toEqual(2);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
})
-});
-
-test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [{ field: 'student.age', operator: '>', value: '20' }],
- joinTable: 'enrollment',
- joinType: "INNER",
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- })
-});
-
-test('Parse INNER JOIN clause', () => {
- const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'INNER',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' },
- });
-});
-
-test('Parse LEFT JOIN clause', () => {
- const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'LEFT',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' }
- });
-});
-
-test('Parse RIGHT JOIN clause', () => {
- const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'RIGHT',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' }
- });
-});
-
-test('Returns null for queries without JOIN', () => {
- const query = 'SELECT * FROM table1';
- const result = parseJoinClause(query);
- expect(result).toEqual(
- {
- joinType: null,
- joinTable: null,
- joinCondition: null
- }
- );
-});
-
-test('Parse LEFT Join Query Completely', () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinType: 'LEFT',
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- })
-})
-
-test('Parse LEFT Join Query Completely', () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinType: 'RIGHT',
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- })
-})
-
-test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "LEFT",
- "table": "student",
- "whereClauses": [{ "field": "student.age", "operator": ">", "value": "22" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "LEFT",
- "table": "student",
- "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Physics'" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "RIGHT",
- "table": "student",
- "whereClauses": [{ "field": "student.age", "operator": "<", "value": "25" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await parseQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "RIGHT",
- "table": "student",
- "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Chemistry'" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-
-test('Parse COUNT Aggregate Query', () => {
- const query = 'SELECT COUNT(*) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['COUNT(*)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-
-test('Parse SUM Aggregate Query', () => {
- const query = 'SELECT SUM(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['SUM(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse AVG Aggregate Query', () => {
- const query = 'SELECT AVG(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['AVG(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse MIN Aggregate Query', () => {
- const query = 'SELECT MIN(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['MIN(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse MAX Aggregate Query', () => {
- const query = 'SELECT MAX(age) FROM student';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['MAX(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse basic GROUP BY query', () => {
- const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['age', 'COUNT(*)'],
- table: 'student',
- whereClauses: [],
- groupByFields: ['age'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse GROUP BY query with WHERE clause', () => {
- const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['age', 'COUNT(*)'],
- table: 'student',
- whereClauses: [{ field: 'age', operator: '>', value: '22' }],
- groupByFields: ['age'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse GROUP BY query with multiple fields', () => {
- const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['student_id', 'course', 'COUNT(*)'],
- table: 'enrollment',
- whereClauses: [],
- groupByFields: ['student_id', 'course'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
- const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
- const parsed = parseQuery(query);
- expect(parsed).toEqual({
- fields: ['student.name', 'COUNT(*)'],
- table: 'student',
- whereClauses: [{ field: 'enrollment.course', operator: '=', value: '"Mathematics"' }],
- groupByFields: ['student.name'],
- joinType: 'INNER',
- joinTable: 'enrollment',
- joinCondition: {
- left: 'student.id',
- right: 'enrollment.student_id'
- },
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false,
- });
-});
-
-test('Execute SQL Query with ORDER BY', async () => {
- const query = 'SELECT name FROM student ORDER BY name ASC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { name: 'Alice' },
- { name: 'Bob' },
- { name: 'Jane' },
- { name: 'John' }
- ]);
-});
-
-test('Execute SQL Query with ORDER BY and WHERE', async () => {
- const query = 'SELECT name FROM student WHERE age > 24 ORDER BY name DESC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { name: 'John' },
- { name: 'Jane' },
- ]);
-});
-test('Execute SQL Query with ORDER BY and GROUP BY', async () => {
- const query = 'SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { age: '30', 'COUNT(id) as count': 1 },
- { age: '25', 'COUNT(id) as count': 1 },
- { age: '24', 'COUNT(id) as count': 1 },
- { age: '22', 'COUNT(id) as count': 1 }
- ]);
-});
-
-test('Execute SQL Query with standard LIMIT clause', async () => {
- const query = 'SELECT id, name FROM student LIMIT 2';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(2);
-});
-
-test('Execute SQL Query with LIMIT clause equal to total rows', async () => {
- const query = 'SELECT id, name FROM student LIMIT 4';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(4);
-});
-
-test('Execute SQL Query with LIMIT clause exceeding total rows', async () => {
- const query = 'SELECT id, name FROM student LIMIT 10';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(4); // Total rows in student.csv
-});
-
-test('Execute SQL Query with LIMIT 0', async () => {
- const query = 'SELECT id, name FROM student LIMIT 0';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(0);
-});
-
-test('Execute SQL Query with LIMIT and ORDER BY clause', async () => {
- const query = 'SELECT id, name FROM student ORDER BY age DESC LIMIT 2';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(2);
- expect(result[0].name).toEqual('John');
- expect(result[1].name).toEqual('Jane');
-});
-
-test('Error Handling with Malformed Query', async () => {
- const query = 'SELECT FROM table'; // intentionally malformed
- await expect(executeSELECTQuery(query)).rejects.toThrow("Error executing query: Query parsing error: Invalid SELECT format");
-});
-
-test('Basic DISTINCT Usage', async () => {
- const query = 'SELECT DISTINCT age FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ age: '30' }, { age: '25' }, { age: '22' }, { age: '24' }]);
-});
-
-test('DISTINCT with Multiple Columns', async () => {
- const query = 'SELECT DISTINCT student_id, course FROM enrollment';
- const result = await executeSELECTQuery(query);
- // Expecting unique combinations of student_id and course
- expect(result).toEqual([
- { student_id: '1', course: 'Mathematics' },
- { student_id: '1', course: 'Physics' },
- { student_id: '2', course: 'Chemistry' },
- { student_id: '3', course: 'Mathematics' },
- { student_id: '5', course: 'Biology' },
- ]);
+ );
+});
+
+test("Execute SQL Query with LEFT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "Alice",
+ "enrollment.course": null,
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 students, but John appears twice
+});
+
+test("Execute SQL Query with RIGHT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": null,
+ "enrollment.course": "Biology",
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Physics",
+ "student.name": "John",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(4);
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Physics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "Bob",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Biology",
+ "student.name": null,
+ }),
+ ])
+ );
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Chemistry",
+ "student.name": "Jane",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([]);
+});
+
+test("Execute COUNT Aggregate Query", async () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "COUNT(*)": 4 }]);
+});
+
+test("Execute SUM Aggregate Query", async () => {
+ const query = "SELECT SUM(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "SUM(age)": 101 }]);
+});
+
+test("Execute AVG Aggregate Query", async () => {
+ const query = "SELECT AVG(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ // Assuming AVG returns a single decimal point value
+ expect(result).toEqual([{ "AVG(age)": 25.25 }]);
+});
+
+test("Execute MIN Aggregate Query", async () => {
+ const query = "SELECT MIN(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MIN(age)": 22 }]);
+});
+
+test("Execute MAX Aggregate Query", async () => {
+ const query = "SELECT MAX(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MAX(age)": 30 }]);
+});
+
+test("Count students per age", async () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "22", "COUNT(*)": 1 },
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments per course", async () => {
+ const query = "SELECT course, COUNT(*) FROM enrollment GROUP BY course";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { course: "Mathematics", "COUNT(*)": 2 },
+ { course: "Physics", "COUNT(*)": 1 },
+ { course: "Chemistry", "COUNT(*)": 1 },
+ { course: "Biology", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count courses per student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { student_id: "1", "COUNT(*)": 2 },
+ { student_id: "2", "COUNT(*)": 1 },
+ { student_id: "3", "COUNT(*)": 1 },
+ { student_id: "5", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count students within a specific age range", async () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments for a specific course", async () => {
+ const query =
+ 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ course: "Mathematics", "COUNT(*)": 2 }]);
+});
+
+test("Count courses for a specific student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ student_id: "1", "COUNT(*)": 2 }]);
+});
+
+test("Average age of students above a certain age", async () => {
+ const query = "SELECT AVG(age) FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(query);
+ const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
+ expect(result).toEqual([{ "AVG(age)": expectedAverage }]);
+});
+
+test("Parse SQL Query", () => {
+ const query = "SELECT id, name FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with WHERE Clause", () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "25",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with Multiple WHERE Clauses", () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "30",
+ },
+ {
+ field: "name",
+ operator: "=",
+ value: "John",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN and WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "20" }],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse INNER JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "INNER",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse LEFT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "LEFT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse RIGHT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "RIGHT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Returns null for queries without JOIN", () => {
+ const query = "SELECT * FROM table1";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "LEFT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "RIGHT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "22" }],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Physics'" },
+ ],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: "<", value: "25" }],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Chemistry'" },
+ ],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse COUNT Aggregate Query", () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SUM Aggregate Query", () => {
+ const query = "SELECT SUM(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["SUM(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse AVG Aggregate Query", () => {
+ const query = "SELECT AVG(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["AVG(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MIN Aggregate Query", () => {
+ const query = "SELECT MIN(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MIN(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MAX Aggregate Query", () => {
+ const query = "SELECT MAX(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MAX(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse basic GROUP BY query", () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with WHERE clause", () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [{ field: "age", operator: ">", value: "22" }],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with multiple fields", () => {
+ const query =
+ "SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student_id", "course", "COUNT(*)"],
+ table: "enrollment",
+ whereClauses: [],
+ groupByFields: ["student_id", "course"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with JOIN and WHERE clauses", () => {
+ const query =
+ 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student.name", "COUNT(*)"],
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: '"Mathematics"' },
+ ],
+ groupByFields: ["student.name"],
+ joinType: "INNER",
+ joinTable: "enrollment",
+ joinCondition: {
+ left: "student.id",
+ right: "enrollment.student_id",
+ },
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Execute SQL Query with ORDER BY", async () => {
+ const query = "SELECT name FROM student ORDER BY name ASC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([
+ { name: "Alice" },
+ { name: "Bob" },
+ { name: "Jane" },
+ { name: "John" },
+ ]);
+});
+
+test("Execute SQL Query with ORDER BY and WHERE", async () => {
+ const query = "SELECT name FROM student WHERE age > 24 ORDER BY name DESC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([{ name: "John" }, { name: "Jane" }]);
+});
+test("Execute SQL Query with ORDER BY and GROUP BY", async () => {
+ const query =
+ "SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([
+ { age: "30", "COUNT(id) as count": 1 },
+ { age: "25", "COUNT(id) as count": 1 },
+ { age: "24", "COUNT(id) as count": 1 },
+ { age: "22", "COUNT(id) as count": 1 },
+ ]);
+});
+
+test("Execute SQL Query with standard LIMIT clause", async () => {
+ const query = "SELECT id, name FROM student LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with LIMIT clause equal to total rows", async () => {
+ const query = "SELECT id, name FROM student LIMIT 4";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(4);
+});
+
+test("Execute SQL Query with LIMIT clause exceeding total rows", async () => {
+ const query = "SELECT id, name FROM student LIMIT 10";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(4); // Total rows in student.csv
+});
+
+test("Execute SQL Query with LIMIT 0", async () => {
+ const query = "SELECT id, name FROM student LIMIT 0";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(0);
+});
+
+test("Execute SQL Query with LIMIT and ORDER BY clause", async () => {
+ const query = "SELECT id, name FROM student ORDER BY age DESC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(2);
+ expect(result[0].name).toEqual("John");
+ expect(result[1].name).toEqual("Jane");
+});
+
+test("Error Handling with Malformed Query", async () => {
+ const query = "SELECT FROM table"; // intentionally malformed
+ await expect(executeSELECTQuery(query)).rejects.toThrow(
+ "Error executing query: Query parsing error: Invalid SELECT format"
+ );
+});
+
+test("Basic DISTINCT Usage", async () => {
+ const query = "SELECT DISTINCT age FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "30" },
+ { age: "25" },
+ { age: "22" },
+ { age: "24" },
+ ]);
+});
+
+test("DISTINCT with Multiple Columns", async () => {
+ const query = "SELECT DISTINCT student_id, course FROM enrollment";
+ const result = await executeSELECTQuery(query);
+ // Expecting unique combinations of student_id and course
+ expect(result).toEqual([
+ { student_id: "1", course: "Mathematics" },
+ { student_id: "1", course: "Physics" },
+ { student_id: "2", course: "Chemistry" },
+ { student_id: "3", course: "Mathematics" },
+ { student_id: "5", course: "Biology" },
+ ]);
});
// Not a good test right now
-test('DISTINCT with WHERE Clause', async () => {
- const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"';
- const result = await executeSELECTQuery(query);
- // Expecting courses taken by student with ID 1
- expect(result).toEqual([{ course: 'Mathematics' }, { course: 'Physics' }]);
+test("DISTINCT with WHERE Clause", async () => {
+ const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"';
+ const result = await executeSELECTQuery(query);
+ // Expecting courses taken by student with ID 1
+ expect(result).toEqual([{ course: "Mathematics" }, { course: "Physics" }]);
});
-test('DISTINCT with JOIN Operations', async () => {
- const query = 'SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id';
- const result = await executeSELECTQuery(query);
- // Expecting names of students who are enrolled in any course
- expect(result).toEqual([{ "student.name": 'John' }, { "student.name": 'Jane' }, { "student.name": 'Bob' }]);
+test("DISTINCT with JOIN Operations", async () => {
+ const query =
+ "SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ // Expecting names of students who are enrolled in any course
+ expect(result).toEqual([
+ { "student.name": "John" },
+ { "student.name": "Jane" },
+ { "student.name": "Bob" },
+ ]);
});
-test('DISTINCT with ORDER BY and LIMIT', async () => {
- const query = 'SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2';
- const result = await executeSELECTQuery(query);
- // Expecting the two highest unique ages
- expect(result).toEqual([{ age: '30' }, { age: '25' }]);
+test("DISTINCT with ORDER BY and LIMIT", async () => {
+ const query = "SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ // Expecting the two highest unique ages
+ expect(result).toEqual([{ age: "30" }, { age: "25" }]);
});
-test('Execute SQL Query with LIKE Operator for Name', async () => {
- const query = "SELECT name FROM student WHERE name LIKE '%Jane%'";
- const result = await executeSELECTQuery(query);
- // Expecting names containing 'Jane'
- expect(result).toEqual([{ name: 'Jane' }]);
+test("Execute SQL Query with LIKE Operator for Name", async () => {
+ const query = "SELECT name FROM student WHERE name LIKE '%Jane%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting names containing 'Jane'
+ expect(result).toEqual([{ name: "Jane" }]);
});
-test('Execute SQL Query with LIKE Operator and Wildcards', async () => {
- const query = "SELECT name FROM student WHERE name LIKE 'J%'";
- const result = await executeSELECTQuery(query);
- // Expecting names starting with 'J'
- expect(result).toEqual([{ name: 'John' }, { name: 'Jane' }]);
+test("Execute SQL Query with LIKE Operator and Wildcards", async () => {
+ const query = "SELECT name FROM student WHERE name LIKE 'J%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting names starting with 'J'
+ expect(result).toEqual([{ name: "John" }, { name: "Jane" }]);
});
-test('Execute SQL Query with LIKE Operator Case Insensitive', async () => {
- const query = "SELECT name FROM student WHERE name LIKE '%bob%'";
- const result = await executeSELECTQuery(query);
- // Expecting names 'Bob' (case insensitive)
- expect(result).toEqual([{ name: 'Bob' }]);
+test("Execute SQL Query with LIKE Operator Case Insensitive", async () => {
+ const query = "SELECT name FROM student WHERE name LIKE '%bob%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting names 'Bob' (case insensitive)
+ expect(result).toEqual([{ name: "Bob" }]);
});
-test('Execute SQL Query with LIKE Operator and DISTINCT', async () => {
- const query = "SELECT DISTINCT name FROM student WHERE name LIKE '%e%'";
- const result = await executeSELECTQuery(query);
- // Expecting unique names containing 'e'
- expect(result).toEqual([{ name: 'Jane' }, { name: 'Alice' }]);
+test("Execute SQL Query with LIKE Operator and DISTINCT", async () => {
+ const query = "SELECT DISTINCT name FROM student WHERE name LIKE '%e%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting unique names containing 'e'
+ expect(result).toEqual([{ name: "Jane" }, { name: "Alice" }]);
});
-test('LIKE with ORDER BY and LIMIT', async () => {
- const query = "SELECT name FROM student WHERE name LIKE '%a%' ORDER BY name ASC LIMIT 2";
- const result = await executeSELECTQuery(query);
- // Expecting the first two names alphabetically that contain 'a'
- expect(result).toEqual([{ name: 'Alice' }, { name: 'Jane' }]);
-});
\ No newline at end of file
+test("LIKE with ORDER BY and LIMIT", async () => {
+ const query =
+ "SELECT name FROM student WHERE name LIKE '%a%' ORDER BY name ASC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ // Expecting the first two names alphabetically that contain 'a'
+ expect(result).toEqual([{ name: "Alice" }, { name: "Jane" }]);
+});
diff --git a/tests/step-17/index.test.js b/tests/step-17/index.test.js
index c99d01fbb..677604fb2 100644
--- a/tests/step-17/index.test.js
+++ b/tests/step-17/index.test.js
@@ -1,59 +1,60 @@
-const {readCSV} = require('../../src/csvReader');
-const {executeSELECTQuery } = require('../../src/index');
-const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser');
-
-test('Read CSV File', async () => {
- const data = await readCSV('./student.csv');
- expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(4);
- expect(data[0].name).toBe('John');
- expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
-});
-
-test('Execute SQL Query', async () => {
- const query = 'SELECT id, name FROM student';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBeGreaterThan(0);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0]).not.toHaveProperty('age');
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0].id).toBe('2');
-});
-
-test('Execute SQL Query with Complex WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with Greater Than', async () => {
- const queryWithGT = 'SELECT id FROM student WHERE age > 22';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('id');
-});
-
-test('Execute SQL Query with Not Equal to', async () => {
- const queryWithGT = 'SELECT name FROM student WHERE age != 25';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('name');
-});
-
-test('Execute SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- /*
+const { readCSV } = require("../../src/csvReader");
+const { executeSELECTQuery } = require("../../src/queryExecutor");
+const { parseJoinClause, parseSelectQuery } = require("../../src/queryParser");
+
+test("Read CSV File", async () => {
+ const data = await readCSV("./student.csv");
+ expect(data.length).toBeGreaterThan(0);
+ expect(data.length).toBe(4);
+ expect(data[0].name).toBe("John");
+ expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later
+});
+
+test("Execute SQL Query", async () => {
+ const query = "SELECT id, name FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBeGreaterThan(0);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0]).not.toHaveProperty("age");
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0].id).toBe("2");
+});
+
+test("Execute SQL Query with Complex WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with Greater Than", async () => {
+ const queryWithGT = "SELECT id FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("id");
+});
+
+test("Execute SQL Query with Not Equal to", async () => {
+ const queryWithGT = "SELECT name FROM student WHERE age != 25";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("name");
+});
+
+test("Execute SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{ 'student.name': 'John', 'enrollment.course': 'Mathematics' },
{ 'student.name': 'John', 'enrollment.course': 'Physics' },
@@ -61,18 +62,21 @@ test('Execute SQL Query with INNER JOIN', async () => {
{ 'student.name': 'Bob', 'enrollment.course': 'Mathematics' }
]
*/
- expect(result.length).toEqual(4);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
+ expect(result.length).toEqual(4);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ })
+ );
});
-test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25';
- const result = await executeSELECTQuery(query);
- /*
+test("Execute SQL Query with INNER JOIN and a WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{
'student.name': 'John',
@@ -86,737 +90,812 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
}
]
*/
- expect(result.length).toEqual(2);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
-});
-
-test('Execute SQL Query with LEFT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "Alice", "enrollment.course": null }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 students, but John appears twice
-});
-
-test('Execute SQL Query with RIGHT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": null, "enrollment.course": "Biology" }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
-});
-
-test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "John" }),
- expect.objectContaining({ "enrollment.course": "Physics", "student.name": "John" })
- ]));
- expect(result.length).toEqual(4);
-});
-
-test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Physics" })
- ]));
- expect(result.length).toEqual(1);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "Bob" }),
- expect.objectContaining({ "enrollment.course": "Biology", "student.name": null })
- ]));
- expect(result.length).toEqual(2);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Chemistry", "student.name": "Jane" }),
- ]));
- expect(result.length).toEqual(1);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([]);
-});
-
-test('Execute COUNT Aggregate Query', async () => {
- const query = 'SELECT COUNT(*) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'COUNT(*)': 4 }]);
-});
-
-test('Execute SUM Aggregate Query', async () => {
- const query = 'SELECT SUM(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'SUM(age)': 101 }]);
-});
-
-test('Execute AVG Aggregate Query', async () => {
- const query = 'SELECT AVG(age) FROM student';
- const result = await executeSELECTQuery(query);
- // Assuming AVG returns a single decimal point value
- expect(result).toEqual([{ 'AVG(age)': 25.25 }]);
-});
-
-test('Execute MIN Aggregate Query', async () => {
- const query = 'SELECT MIN(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'MIN(age)': 22 }]);
-});
-
-test('Execute MAX Aggregate Query', async () => {
- const query = 'SELECT MAX(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'MAX(age)': 30 }]);
-});
-
-test('Count students per age', async () => {
- const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { age: '22', 'COUNT(*)': 1 },
- { age: '24', 'COUNT(*)': 1 },
- { age: '25', 'COUNT(*)': 1 },
- { age: '30', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count enrollments per course', async () => {
- const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { course: 'Mathematics', 'COUNT(*)': 2 },
- { course: 'Physics', 'COUNT(*)': 1 },
- { course: 'Chemistry', 'COUNT(*)': 1 },
- { course: 'Biology', 'COUNT(*)': 1 }
- ]);
-});
-
-
-test('Count courses per student', async () => {
- const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { student_id: '1', 'COUNT(*)': 2 },
- { student_id: '2', 'COUNT(*)': 1 },
- { student_id: '3', 'COUNT(*)': 1 },
- { student_id: '5', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count students within a specific age range', async () => {
- const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { age: '24', 'COUNT(*)': 1 },
- { age: '25', 'COUNT(*)': 1 },
- { age: '30', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count enrollments for a specific course', async () => {
- const query = 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { course: 'Mathematics', 'COUNT(*)': 2 }
- ]);
-});
-
-test('Count courses for a specific student', async () => {
- const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { student_id: '1', 'COUNT(*)': 2 }
- ]);
-});
-
-test('Average age of students above a certain age', async () => {
- const query = 'SELECT AVG(age) FROM student WHERE age > 22';
- const result = await executeSELECTQuery(query);
- const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
- expect(result).toEqual([{ 'AVG(age)': expectedAverage }]);
-});
-
-test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM student';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with WHERE Clause', () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "25",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with Multiple WHERE Clauses', () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "30",
- }, {
- "field": "name",
- "operator": "=",
- "value": "John",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseSelectQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinTable: 'enrollment',
- joinType: "INNER",
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
+ expect(result.length).toEqual(2);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
})
-});
-
-test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseSelectQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [{ field: 'student.age', operator: '>', value: '20' }],
- joinTable: 'enrollment',
- joinType: "INNER",
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- })
-});
-
-test('Parse INNER JOIN clause', () => {
- const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'INNER',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' },
- });
-});
-
-test('Parse LEFT JOIN clause', () => {
- const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'LEFT',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' }
- });
-});
-
-test('Parse RIGHT JOIN clause', () => {
- const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'RIGHT',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' }
- });
-});
-
-test('Returns null for queries without JOIN', () => {
- const query = 'SELECT * FROM table1';
- const result = parseJoinClause(query);
- expect(result).toEqual(
- {
- joinType: null,
- joinTable: null,
- joinCondition: null
- }
- );
-});
-
-test('Parse LEFT Join Query Completely', () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseSelectQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinType: 'LEFT',
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- })
-})
-
-test('Parse LEFT Join Query Completely', () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseSelectQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinType: 'RIGHT',
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- })
-})
-
-test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await parseSelectQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "LEFT",
- "table": "student",
- "whereClauses": [{ "field": "student.age", "operator": ">", "value": "22" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await parseSelectQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "LEFT",
- "table": "student",
- "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Physics'" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await parseSelectQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "RIGHT",
- "table": "student",
- "whereClauses": [{ "field": "student.age", "operator": "<", "value": "25" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await parseSelectQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "RIGHT",
- "table": "student",
- "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Chemistry'" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-
-test('Parse COUNT Aggregate Query', () => {
- const query = 'SELECT COUNT(*) FROM student';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['COUNT(*)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-
-test('Parse SUM Aggregate Query', () => {
- const query = 'SELECT SUM(age) FROM student';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['SUM(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse AVG Aggregate Query', () => {
- const query = 'SELECT AVG(age) FROM student';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['AVG(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse MIN Aggregate Query', () => {
- const query = 'SELECT MIN(age) FROM student';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['MIN(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse MAX Aggregate Query', () => {
- const query = 'SELECT MAX(age) FROM student';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['MAX(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse basic GROUP BY query', () => {
- const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['age', 'COUNT(*)'],
- table: 'student',
- whereClauses: [],
- groupByFields: ['age'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse GROUP BY query with WHERE clause', () => {
- const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['age', 'COUNT(*)'],
- table: 'student',
- whereClauses: [{ field: 'age', operator: '>', value: '22' }],
- groupByFields: ['age'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse GROUP BY query with multiple fields', () => {
- const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['student_id', 'course', 'COUNT(*)'],
- table: 'enrollment',
- whereClauses: [],
- groupByFields: ['student_id', 'course'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
- const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['student.name', 'COUNT(*)'],
- table: 'student',
- whereClauses: [{ field: 'enrollment.course', operator: '=', value: '"Mathematics"' }],
- groupByFields: ['student.name'],
- joinType: 'INNER',
- joinTable: 'enrollment',
- joinCondition: {
- left: 'student.id',
- right: 'enrollment.student_id'
- },
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false,
- });
-});
-
-test('Execute SQL Query with ORDER BY', async () => {
- const query = 'SELECT name FROM student ORDER BY name ASC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { name: 'Alice' },
- { name: 'Bob' },
- { name: 'Jane' },
- { name: 'John' }
- ]);
-});
-
-test('Execute SQL Query with ORDER BY and WHERE', async () => {
- const query = 'SELECT name FROM student WHERE age > 24 ORDER BY name DESC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { name: 'John' },
- { name: 'Jane' },
- ]);
-});
-test('Execute SQL Query with ORDER BY and GROUP BY', async () => {
- const query = 'SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { age: '30', 'COUNT(id) as count': 1 },
- { age: '25', 'COUNT(id) as count': 1 },
- { age: '24', 'COUNT(id) as count': 1 },
- { age: '22', 'COUNT(id) as count': 1 }
- ]);
-});
-
-test('Execute SQL Query with standard LIMIT clause', async () => {
- const query = 'SELECT id, name FROM student LIMIT 2';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(2);
-});
-
-test('Execute SQL Query with LIMIT clause equal to total rows', async () => {
- const query = 'SELECT id, name FROM student LIMIT 4';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(4);
-});
-
-test('Execute SQL Query with LIMIT clause exceeding total rows', async () => {
- const query = 'SELECT id, name FROM student LIMIT 10';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(4); // Total rows in student.csv
-});
-
-test('Execute SQL Query with LIMIT 0', async () => {
- const query = 'SELECT id, name FROM student LIMIT 0';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(0);
-});
-
-test('Execute SQL Query with LIMIT and ORDER BY clause', async () => {
- const query = 'SELECT id, name FROM student ORDER BY age DESC LIMIT 2';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(2);
- expect(result[0].name).toEqual('John');
- expect(result[1].name).toEqual('Jane');
-});
-
-test('Error Handling with Malformed Query', async () => {
- const query = 'SELECT FROM table'; // intentionally malformed
- await expect(executeSELECTQuery(query)).rejects.toThrow("Error executing query: Query parsing error: Invalid SELECT format");
-});
-
-test('Basic DISTINCT Usage', async () => {
- const query = 'SELECT DISTINCT age FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ age: '30' }, { age: '25' }, { age: '22' }, { age: '24' }]);
-});
-
-test('DISTINCT with Multiple Columns', async () => {
- const query = 'SELECT DISTINCT student_id, course FROM enrollment';
- const result = await executeSELECTQuery(query);
- // Expecting unique combinations of student_id and course
- expect(result).toEqual([
- { student_id: '1', course: 'Mathematics' },
- { student_id: '1', course: 'Physics' },
- { student_id: '2', course: 'Chemistry' },
- { student_id: '3', course: 'Mathematics' },
- { student_id: '5', course: 'Biology' },
- ]);
+ );
+});
+
+test("Execute SQL Query with LEFT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "Alice",
+ "enrollment.course": null,
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 students, but John appears twice
+});
+
+test("Execute SQL Query with RIGHT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": null,
+ "enrollment.course": "Biology",
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Physics",
+ "student.name": "John",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(4);
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Physics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "Bob",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Biology",
+ "student.name": null,
+ }),
+ ])
+ );
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Chemistry",
+ "student.name": "Jane",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([]);
+});
+
+test("Execute COUNT Aggregate Query", async () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "COUNT(*)": 4 }]);
+});
+
+test("Execute SUM Aggregate Query", async () => {
+ const query = "SELECT SUM(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "SUM(age)": 101 }]);
+});
+
+test("Execute AVG Aggregate Query", async () => {
+ const query = "SELECT AVG(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ // Assuming AVG returns a single decimal point value
+ expect(result).toEqual([{ "AVG(age)": 25.25 }]);
+});
+
+test("Execute MIN Aggregate Query", async () => {
+ const query = "SELECT MIN(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MIN(age)": 22 }]);
+});
+
+test("Execute MAX Aggregate Query", async () => {
+ const query = "SELECT MAX(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MAX(age)": 30 }]);
+});
+
+test("Count students per age", async () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "22", "COUNT(*)": 1 },
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments per course", async () => {
+ const query = "SELECT course, COUNT(*) FROM enrollment GROUP BY course";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { course: "Mathematics", "COUNT(*)": 2 },
+ { course: "Physics", "COUNT(*)": 1 },
+ { course: "Chemistry", "COUNT(*)": 1 },
+ { course: "Biology", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count courses per student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { student_id: "1", "COUNT(*)": 2 },
+ { student_id: "2", "COUNT(*)": 1 },
+ { student_id: "3", "COUNT(*)": 1 },
+ { student_id: "5", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count students within a specific age range", async () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments for a specific course", async () => {
+ const query =
+ 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ course: "Mathematics", "COUNT(*)": 2 }]);
+});
+
+test("Count courses for a specific student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ student_id: "1", "COUNT(*)": 2 }]);
+});
+
+test("Average age of students above a certain age", async () => {
+ const query = "SELECT AVG(age) FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(query);
+ const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
+ expect(result).toEqual([{ "AVG(age)": expectedAverage }]);
+});
+
+test("Parse SQL Query", () => {
+ const query = "SELECT id, name FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with WHERE Clause", () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "25",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with Multiple WHERE Clauses", () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "30",
+ },
+ {
+ field: "name",
+ operator: "=",
+ value: "John",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN and WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "20" }],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse INNER JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "INNER",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse LEFT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "LEFT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse RIGHT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "RIGHT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Returns null for queries without JOIN", () => {
+ const query = "SELECT * FROM table1";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "LEFT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "RIGHT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "22" }],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Physics'" },
+ ],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: "<", value: "25" }],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Chemistry'" },
+ ],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse COUNT Aggregate Query", () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SUM Aggregate Query", () => {
+ const query = "SELECT SUM(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["SUM(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse AVG Aggregate Query", () => {
+ const query = "SELECT AVG(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["AVG(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MIN Aggregate Query", () => {
+ const query = "SELECT MIN(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MIN(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MAX Aggregate Query", () => {
+ const query = "SELECT MAX(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MAX(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse basic GROUP BY query", () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with WHERE clause", () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [{ field: "age", operator: ">", value: "22" }],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with multiple fields", () => {
+ const query =
+ "SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student_id", "course", "COUNT(*)"],
+ table: "enrollment",
+ whereClauses: [],
+ groupByFields: ["student_id", "course"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with JOIN and WHERE clauses", () => {
+ const query =
+ 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student.name", "COUNT(*)"],
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: '"Mathematics"' },
+ ],
+ groupByFields: ["student.name"],
+ joinType: "INNER",
+ joinTable: "enrollment",
+ joinCondition: {
+ left: "student.id",
+ right: "enrollment.student_id",
+ },
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Execute SQL Query with ORDER BY", async () => {
+ const query = "SELECT name FROM student ORDER BY name ASC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([
+ { name: "Alice" },
+ { name: "Bob" },
+ { name: "Jane" },
+ { name: "John" },
+ ]);
+});
+
+test("Execute SQL Query with ORDER BY and WHERE", async () => {
+ const query = "SELECT name FROM student WHERE age > 24 ORDER BY name DESC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([{ name: "John" }, { name: "Jane" }]);
+});
+test("Execute SQL Query with ORDER BY and GROUP BY", async () => {
+ const query =
+ "SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([
+ { age: "30", "COUNT(id) as count": 1 },
+ { age: "25", "COUNT(id) as count": 1 },
+ { age: "24", "COUNT(id) as count": 1 },
+ { age: "22", "COUNT(id) as count": 1 },
+ ]);
+});
+
+test("Execute SQL Query with standard LIMIT clause", async () => {
+ const query = "SELECT id, name FROM student LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with LIMIT clause equal to total rows", async () => {
+ const query = "SELECT id, name FROM student LIMIT 4";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(4);
+});
+
+test("Execute SQL Query with LIMIT clause exceeding total rows", async () => {
+ const query = "SELECT id, name FROM student LIMIT 10";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(4); // Total rows in student.csv
+});
+
+test("Execute SQL Query with LIMIT 0", async () => {
+ const query = "SELECT id, name FROM student LIMIT 0";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(0);
+});
+
+test("Execute SQL Query with LIMIT and ORDER BY clause", async () => {
+ const query = "SELECT id, name FROM student ORDER BY age DESC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(2);
+ expect(result[0].name).toEqual("John");
+ expect(result[1].name).toEqual("Jane");
+});
+
+test("Error Handling with Malformed Query", async () => {
+ const query = "SELECT FROM table"; // intentionally malformed
+ await expect(executeSELECTQuery(query)).rejects.toThrow(
+ "Error executing query: Query parsing error: Invalid SELECT format"
+ );
+});
+
+test("Basic DISTINCT Usage", async () => {
+ const query = "SELECT DISTINCT age FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "30" },
+ { age: "25" },
+ { age: "22" },
+ { age: "24" },
+ ]);
+});
+
+test("DISTINCT with Multiple Columns", async () => {
+ const query = "SELECT DISTINCT student_id, course FROM enrollment";
+ const result = await executeSELECTQuery(query);
+ // Expecting unique combinations of student_id and course
+ expect(result).toEqual([
+ { student_id: "1", course: "Mathematics" },
+ { student_id: "1", course: "Physics" },
+ { student_id: "2", course: "Chemistry" },
+ { student_id: "3", course: "Mathematics" },
+ { student_id: "5", course: "Biology" },
+ ]);
});
// Not a good test right now
-test('DISTINCT with WHERE Clause', async () => {
- const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"';
- const result = await executeSELECTQuery(query);
- // Expecting courses taken by student with ID 1
- expect(result).toEqual([{ course: 'Mathematics' }, { course: 'Physics' }]);
+test("DISTINCT with WHERE Clause", async () => {
+ const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"';
+ const result = await executeSELECTQuery(query);
+ // Expecting courses taken by student with ID 1
+ expect(result).toEqual([{ course: "Mathematics" }, { course: "Physics" }]);
});
-test('DISTINCT with JOIN Operations', async () => {
- const query = 'SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id';
- const result = await executeSELECTQuery(query);
- // Expecting names of students who are enrolled in any course
- expect(result).toEqual([{ "student.name": 'John' }, { "student.name": 'Jane' }, { "student.name": 'Bob' }]);
+test("DISTINCT with JOIN Operations", async () => {
+ const query =
+ "SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ // Expecting names of students who are enrolled in any course
+ expect(result).toEqual([
+ { "student.name": "John" },
+ { "student.name": "Jane" },
+ { "student.name": "Bob" },
+ ]);
});
-test('DISTINCT with ORDER BY and LIMIT', async () => {
- const query = 'SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2';
- const result = await executeSELECTQuery(query);
- // Expecting the two highest unique ages
- expect(result).toEqual([{ age: '30' }, { age: '25' }]);
+test("DISTINCT with ORDER BY and LIMIT", async () => {
+ const query = "SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ // Expecting the two highest unique ages
+ expect(result).toEqual([{ age: "30" }, { age: "25" }]);
});
-test('Execute SQL Query with LIKE Operator for Name', async () => {
- const query = "SELECT name FROM student WHERE name LIKE '%Jane%'";
- const result = await executeSELECTQuery(query);
- // Expecting names containing 'Jane'
- expect(result).toEqual([{ name: 'Jane' }]);
+test("Execute SQL Query with LIKE Operator for Name", async () => {
+ const query = "SELECT name FROM student WHERE name LIKE '%Jane%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting names containing 'Jane'
+ expect(result).toEqual([{ name: "Jane" }]);
});
-test('Execute SQL Query with LIKE Operator and Wildcards', async () => {
- const query = "SELECT name FROM student WHERE name LIKE 'J%'";
- const result = await executeSELECTQuery(query);
- // Expecting names starting with 'J'
- expect(result).toEqual([{ name: 'John' }, { name: 'Jane' }]);
+test("Execute SQL Query with LIKE Operator and Wildcards", async () => {
+ const query = "SELECT name FROM student WHERE name LIKE 'J%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting names starting with 'J'
+ expect(result).toEqual([{ name: "John" }, { name: "Jane" }]);
});
-test('Execute SQL Query with LIKE Operator Case Insensitive', async () => {
- const query = "SELECT name FROM student WHERE name LIKE '%bob%'";
- const result = await executeSELECTQuery(query);
- // Expecting names 'Bob' (case insensitive)
- expect(result).toEqual([{ name: 'Bob' }]);
+test("Execute SQL Query with LIKE Operator Case Insensitive", async () => {
+ const query = "SELECT name FROM student WHERE name LIKE '%bob%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting names 'Bob' (case insensitive)
+ expect(result).toEqual([{ name: "Bob" }]);
});
-test('Execute SQL Query with LIKE Operator and DISTINCT', async () => {
- const query = "SELECT DISTINCT name FROM student WHERE name LIKE '%e%'";
- const result = await executeSELECTQuery(query);
- // Expecting unique names containing 'e'
- expect(result).toEqual([{ name: 'Jane' }, { name: 'Alice' }]);
+test("Execute SQL Query with LIKE Operator and DISTINCT", async () => {
+ const query = "SELECT DISTINCT name FROM student WHERE name LIKE '%e%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting unique names containing 'e'
+ expect(result).toEqual([{ name: "Jane" }, { name: "Alice" }]);
});
-test('LIKE with ORDER BY and LIMIT', async () => {
- const query = "SELECT name FROM student WHERE name LIKE '%a%' ORDER BY name ASC LIMIT 2";
- const result = await executeSELECTQuery(query);
- // Expecting the first two names alphabetically that contain 'a'
- expect(result).toEqual([{ name: 'Alice' }, { name: 'Jane' }]);
-});
\ No newline at end of file
+test("LIKE with ORDER BY and LIMIT", async () => {
+ const query =
+ "SELECT name FROM student WHERE name LIKE '%a%' ORDER BY name ASC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ // Expecting the first two names alphabetically that contain 'a'
+ expect(result).toEqual([{ name: "Alice" }, { name: "Jane" }]);
+});
diff --git a/tests/step-17/insertExecuter.test.js b/tests/step-17/insertExecuter.test.js
index 8c405f727..473314045 100644
--- a/tests/step-17/insertExecuter.test.js
+++ b/tests/step-17/insertExecuter.test.js
@@ -1,33 +1,36 @@
-const { executeINSERTQuery } = require('../../src/index');
-const { readCSV, writeCSV } = require('../../src/csvReader');
-const fs = require('fs');
+const { executeINSERTQuery } = require("../../src/queryExecutor");
+const { readCSV, writeCSV } = require("../../src/csvReader");
+const fs = require("fs");
// Helper function to create grades.csv with initial data
async function createGradesCSV() {
- const initialData = [
- { student_id: '1', course: 'Mathematics', grade: 'A' },
- { student_id: '2', course: 'Chemistry', grade: 'B' },
- { student_id: '3', course: 'Mathematics', grade: 'C' }
- ];
- await writeCSV('grades.csv', initialData);
+ const initialData = [
+ { student_id: "1", course: "Mathematics", grade: "A" },
+ { student_id: "2", course: "Chemistry", grade: "B" },
+ { student_id: "3", course: "Mathematics", grade: "C" },
+ ];
+ await writeCSV("grades.csv", initialData);
}
// Test to INSERT a new grade and verify
-test('Execute INSERT INTO Query for grades.csv', async () => {
- // Create grades.csv with initial data
- await createGradesCSV();
+test("Execute INSERT INTO Query for grades.csv", async () => {
+ // Create grades.csv with initial data
+ await createGradesCSV();
- // Execute INSERT statement
- const insertQuery = "INSERT INTO grades (student_id, course, grade) VALUES ('4', 'Physics', 'A')";
- await executeINSERTQuery(insertQuery);
+ // Execute INSERT statement
+ const insertQuery =
+ "INSERT INTO grades (student_id, course, grade) VALUES ('4', 'Physics', 'A')";
+ await executeINSERTQuery(insertQuery);
- // Verify the new entry
- const updatedData = await readCSV('grades.csv');
- const newEntry = updatedData.find(row => row.student_id === '4' && row.course === 'Physics');
- console.log(updatedData)
- expect(newEntry).toBeDefined();
- expect(newEntry.grade).toEqual('A');
+ // Verify the new entry
+ const updatedData = await readCSV("grades.csv");
+ const newEntry = updatedData.find(
+ (row) => row.student_id === "4" && row.course === "Physics"
+ );
- // Cleanup: Delete grades.csv
- fs.unlinkSync('grades.csv');
-});
\ No newline at end of file
+ expect(newEntry).toBeDefined();
+ expect(newEntry.grade).toEqual("A");
+
+ // Cleanup: Delete grades.csv
+ fs.unlinkSync("grades.csv");
+});
diff --git a/tests/step-18/deleteExecutor.test.js b/tests/step-18/deleteExecutor.test.js
index 11ae617b7..0e53a921e 100644
--- a/tests/step-18/deleteExecutor.test.js
+++ b/tests/step-18/deleteExecutor.test.js
@@ -1,31 +1,31 @@
-const { executeDELETEQuery } = require('../../src/index');
-const { readCSV, writeCSV } = require('../../src/csvReader');
-const fs = require('fs');
+const { executeDELETEQuery } = require("../../src/queryExecutor");
+const { readCSV, writeCSV } = require("../../src/csvReader");
+const fs = require("fs");
// Helper function to create courses.csv with initial data
async function createCoursesCSV() {
- const initialData = [
- { course_id: '1', course_name: 'Mathematics', instructor: 'Dr. Smith' },
- { course_id: '2', course_name: 'Chemistry', instructor: 'Dr. Jones' },
- { course_id: '3', course_name: 'Physics', instructor: 'Dr. Taylor' }
- ];
- await writeCSV('courses.csv', initialData);
+ const initialData = [
+ { course_id: "1", course_name: "Mathematics", instructor: "Dr. Smith" },
+ { course_id: "2", course_name: "Chemistry", instructor: "Dr. Jones" },
+ { course_id: "3", course_name: "Physics", instructor: "Dr. Taylor" },
+ ];
+ await writeCSV("courses.csv", initialData);
}
// Test to DELETE a course and verify
-test('Execute DELETE FROM Query for courses.csv', async () => {
- // Create courses.csv with initial data
- await createCoursesCSV();
+test("Execute DELETE FROM Query for courses.csv", async () => {
+ // Create courses.csv with initial data
+ await createCoursesCSV();
- // Execute DELETE statement
- const deleteQuery = "DELETE FROM courses WHERE course_id = '2'";
- await executeDELETEQuery(deleteQuery);
+ // Execute DELETE statement
+ const deleteQuery = "DELETE FROM courses WHERE course_id = '2'";
+ await executeDELETEQuery(deleteQuery);
- // Verify the course was removed
- const updatedData = await readCSV('courses.csv');
- const deletedCourse = updatedData.find(course => course.course_id === '2');
- expect(deletedCourse).toBeUndefined();
+ // Verify the course was removed
+ const updatedData = await readCSV("courses.csv");
+ const deletedCourse = updatedData.find((course) => course.course_id === "2");
+ expect(deletedCourse).toBeUndefined();
- // Cleanup: Delete courses.csv
- fs.unlinkSync('courses.csv');
-});
\ No newline at end of file
+ // Cleanup: Delete courses.csv
+ fs.unlinkSync("courses.csv");
+});
diff --git a/tests/step-18/index.test.js b/tests/step-18/index.test.js
index c99d01fbb..677604fb2 100644
--- a/tests/step-18/index.test.js
+++ b/tests/step-18/index.test.js
@@ -1,59 +1,60 @@
-const {readCSV} = require('../../src/csvReader');
-const {executeSELECTQuery } = require('../../src/index');
-const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser');
-
-test('Read CSV File', async () => {
- const data = await readCSV('./student.csv');
- expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(4);
- expect(data[0].name).toBe('John');
- expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
-});
-
-test('Execute SQL Query', async () => {
- const query = 'SELECT id, name FROM student';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBeGreaterThan(0);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0]).not.toHaveProperty('age');
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0].id).toBe('2');
-});
-
-test('Execute SQL Query with Complex WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with Greater Than', async () => {
- const queryWithGT = 'SELECT id FROM student WHERE age > 22';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('id');
-});
-
-test('Execute SQL Query with Not Equal to', async () => {
- const queryWithGT = 'SELECT name FROM student WHERE age != 25';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('name');
-});
-
-test('Execute SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- /*
+const { readCSV } = require("../../src/csvReader");
+const { executeSELECTQuery } = require("../../src/queryExecutor");
+const { parseJoinClause, parseSelectQuery } = require("../../src/queryParser");
+
+test("Read CSV File", async () => {
+ const data = await readCSV("./student.csv");
+ expect(data.length).toBeGreaterThan(0);
+ expect(data.length).toBe(4);
+ expect(data[0].name).toBe("John");
+ expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later
+});
+
+test("Execute SQL Query", async () => {
+ const query = "SELECT id, name FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBeGreaterThan(0);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0]).not.toHaveProperty("age");
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0].id).toBe("2");
+});
+
+test("Execute SQL Query with Complex WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with Greater Than", async () => {
+ const queryWithGT = "SELECT id FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("id");
+});
+
+test("Execute SQL Query with Not Equal to", async () => {
+ const queryWithGT = "SELECT name FROM student WHERE age != 25";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("name");
+});
+
+test("Execute SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{ 'student.name': 'John', 'enrollment.course': 'Mathematics' },
{ 'student.name': 'John', 'enrollment.course': 'Physics' },
@@ -61,18 +62,21 @@ test('Execute SQL Query with INNER JOIN', async () => {
{ 'student.name': 'Bob', 'enrollment.course': 'Mathematics' }
]
*/
- expect(result.length).toEqual(4);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
+ expect(result.length).toEqual(4);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ })
+ );
});
-test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25';
- const result = await executeSELECTQuery(query);
- /*
+test("Execute SQL Query with INNER JOIN and a WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{
'student.name': 'John',
@@ -86,737 +90,812 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
}
]
*/
- expect(result.length).toEqual(2);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
-});
-
-test('Execute SQL Query with LEFT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "Alice", "enrollment.course": null }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 students, but John appears twice
-});
-
-test('Execute SQL Query with RIGHT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": null, "enrollment.course": "Biology" }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
-});
-
-test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "John" }),
- expect.objectContaining({ "enrollment.course": "Physics", "student.name": "John" })
- ]));
- expect(result.length).toEqual(4);
-});
-
-test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Physics" })
- ]));
- expect(result.length).toEqual(1);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "Bob" }),
- expect.objectContaining({ "enrollment.course": "Biology", "student.name": null })
- ]));
- expect(result.length).toEqual(2);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Chemistry", "student.name": "Jane" }),
- ]));
- expect(result.length).toEqual(1);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([]);
-});
-
-test('Execute COUNT Aggregate Query', async () => {
- const query = 'SELECT COUNT(*) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'COUNT(*)': 4 }]);
-});
-
-test('Execute SUM Aggregate Query', async () => {
- const query = 'SELECT SUM(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'SUM(age)': 101 }]);
-});
-
-test('Execute AVG Aggregate Query', async () => {
- const query = 'SELECT AVG(age) FROM student';
- const result = await executeSELECTQuery(query);
- // Assuming AVG returns a single decimal point value
- expect(result).toEqual([{ 'AVG(age)': 25.25 }]);
-});
-
-test('Execute MIN Aggregate Query', async () => {
- const query = 'SELECT MIN(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'MIN(age)': 22 }]);
-});
-
-test('Execute MAX Aggregate Query', async () => {
- const query = 'SELECT MAX(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'MAX(age)': 30 }]);
-});
-
-test('Count students per age', async () => {
- const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { age: '22', 'COUNT(*)': 1 },
- { age: '24', 'COUNT(*)': 1 },
- { age: '25', 'COUNT(*)': 1 },
- { age: '30', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count enrollments per course', async () => {
- const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { course: 'Mathematics', 'COUNT(*)': 2 },
- { course: 'Physics', 'COUNT(*)': 1 },
- { course: 'Chemistry', 'COUNT(*)': 1 },
- { course: 'Biology', 'COUNT(*)': 1 }
- ]);
-});
-
-
-test('Count courses per student', async () => {
- const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { student_id: '1', 'COUNT(*)': 2 },
- { student_id: '2', 'COUNT(*)': 1 },
- { student_id: '3', 'COUNT(*)': 1 },
- { student_id: '5', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count students within a specific age range', async () => {
- const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { age: '24', 'COUNT(*)': 1 },
- { age: '25', 'COUNT(*)': 1 },
- { age: '30', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count enrollments for a specific course', async () => {
- const query = 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { course: 'Mathematics', 'COUNT(*)': 2 }
- ]);
-});
-
-test('Count courses for a specific student', async () => {
- const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { student_id: '1', 'COUNT(*)': 2 }
- ]);
-});
-
-test('Average age of students above a certain age', async () => {
- const query = 'SELECT AVG(age) FROM student WHERE age > 22';
- const result = await executeSELECTQuery(query);
- const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
- expect(result).toEqual([{ 'AVG(age)': expectedAverage }]);
-});
-
-test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM student';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with WHERE Clause', () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "25",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with Multiple WHERE Clauses', () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "30",
- }, {
- "field": "name",
- "operator": "=",
- "value": "John",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseSelectQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinTable: 'enrollment',
- joinType: "INNER",
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
+ expect(result.length).toEqual(2);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
})
-});
-
-test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseSelectQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [{ field: 'student.age', operator: '>', value: '20' }],
- joinTable: 'enrollment',
- joinType: "INNER",
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- })
-});
-
-test('Parse INNER JOIN clause', () => {
- const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'INNER',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' },
- });
-});
-
-test('Parse LEFT JOIN clause', () => {
- const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'LEFT',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' }
- });
-});
-
-test('Parse RIGHT JOIN clause', () => {
- const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'RIGHT',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' }
- });
-});
-
-test('Returns null for queries without JOIN', () => {
- const query = 'SELECT * FROM table1';
- const result = parseJoinClause(query);
- expect(result).toEqual(
- {
- joinType: null,
- joinTable: null,
- joinCondition: null
- }
- );
-});
-
-test('Parse LEFT Join Query Completely', () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseSelectQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinType: 'LEFT',
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- })
-})
-
-test('Parse LEFT Join Query Completely', () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseSelectQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinType: 'RIGHT',
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- })
-})
-
-test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await parseSelectQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "LEFT",
- "table": "student",
- "whereClauses": [{ "field": "student.age", "operator": ">", "value": "22" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await parseSelectQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "LEFT",
- "table": "student",
- "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Physics'" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await parseSelectQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "RIGHT",
- "table": "student",
- "whereClauses": [{ "field": "student.age", "operator": "<", "value": "25" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await parseSelectQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "RIGHT",
- "table": "student",
- "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Chemistry'" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-
-test('Parse COUNT Aggregate Query', () => {
- const query = 'SELECT COUNT(*) FROM student';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['COUNT(*)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-
-test('Parse SUM Aggregate Query', () => {
- const query = 'SELECT SUM(age) FROM student';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['SUM(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse AVG Aggregate Query', () => {
- const query = 'SELECT AVG(age) FROM student';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['AVG(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse MIN Aggregate Query', () => {
- const query = 'SELECT MIN(age) FROM student';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['MIN(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse MAX Aggregate Query', () => {
- const query = 'SELECT MAX(age) FROM student';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['MAX(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse basic GROUP BY query', () => {
- const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['age', 'COUNT(*)'],
- table: 'student',
- whereClauses: [],
- groupByFields: ['age'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse GROUP BY query with WHERE clause', () => {
- const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['age', 'COUNT(*)'],
- table: 'student',
- whereClauses: [{ field: 'age', operator: '>', value: '22' }],
- groupByFields: ['age'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse GROUP BY query with multiple fields', () => {
- const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['student_id', 'course', 'COUNT(*)'],
- table: 'enrollment',
- whereClauses: [],
- groupByFields: ['student_id', 'course'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
- const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['student.name', 'COUNT(*)'],
- table: 'student',
- whereClauses: [{ field: 'enrollment.course', operator: '=', value: '"Mathematics"' }],
- groupByFields: ['student.name'],
- joinType: 'INNER',
- joinTable: 'enrollment',
- joinCondition: {
- left: 'student.id',
- right: 'enrollment.student_id'
- },
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false,
- });
-});
-
-test('Execute SQL Query with ORDER BY', async () => {
- const query = 'SELECT name FROM student ORDER BY name ASC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { name: 'Alice' },
- { name: 'Bob' },
- { name: 'Jane' },
- { name: 'John' }
- ]);
-});
-
-test('Execute SQL Query with ORDER BY and WHERE', async () => {
- const query = 'SELECT name FROM student WHERE age > 24 ORDER BY name DESC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { name: 'John' },
- { name: 'Jane' },
- ]);
-});
-test('Execute SQL Query with ORDER BY and GROUP BY', async () => {
- const query = 'SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { age: '30', 'COUNT(id) as count': 1 },
- { age: '25', 'COUNT(id) as count': 1 },
- { age: '24', 'COUNT(id) as count': 1 },
- { age: '22', 'COUNT(id) as count': 1 }
- ]);
-});
-
-test('Execute SQL Query with standard LIMIT clause', async () => {
- const query = 'SELECT id, name FROM student LIMIT 2';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(2);
-});
-
-test('Execute SQL Query with LIMIT clause equal to total rows', async () => {
- const query = 'SELECT id, name FROM student LIMIT 4';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(4);
-});
-
-test('Execute SQL Query with LIMIT clause exceeding total rows', async () => {
- const query = 'SELECT id, name FROM student LIMIT 10';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(4); // Total rows in student.csv
-});
-
-test('Execute SQL Query with LIMIT 0', async () => {
- const query = 'SELECT id, name FROM student LIMIT 0';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(0);
-});
-
-test('Execute SQL Query with LIMIT and ORDER BY clause', async () => {
- const query = 'SELECT id, name FROM student ORDER BY age DESC LIMIT 2';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(2);
- expect(result[0].name).toEqual('John');
- expect(result[1].name).toEqual('Jane');
-});
-
-test('Error Handling with Malformed Query', async () => {
- const query = 'SELECT FROM table'; // intentionally malformed
- await expect(executeSELECTQuery(query)).rejects.toThrow("Error executing query: Query parsing error: Invalid SELECT format");
-});
-
-test('Basic DISTINCT Usage', async () => {
- const query = 'SELECT DISTINCT age FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ age: '30' }, { age: '25' }, { age: '22' }, { age: '24' }]);
-});
-
-test('DISTINCT with Multiple Columns', async () => {
- const query = 'SELECT DISTINCT student_id, course FROM enrollment';
- const result = await executeSELECTQuery(query);
- // Expecting unique combinations of student_id and course
- expect(result).toEqual([
- { student_id: '1', course: 'Mathematics' },
- { student_id: '1', course: 'Physics' },
- { student_id: '2', course: 'Chemistry' },
- { student_id: '3', course: 'Mathematics' },
- { student_id: '5', course: 'Biology' },
- ]);
+ );
+});
+
+test("Execute SQL Query with LEFT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "Alice",
+ "enrollment.course": null,
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 students, but John appears twice
+});
+
+test("Execute SQL Query with RIGHT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": null,
+ "enrollment.course": "Biology",
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Physics",
+ "student.name": "John",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(4);
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Physics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "Bob",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Biology",
+ "student.name": null,
+ }),
+ ])
+ );
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Chemistry",
+ "student.name": "Jane",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([]);
+});
+
+test("Execute COUNT Aggregate Query", async () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "COUNT(*)": 4 }]);
+});
+
+test("Execute SUM Aggregate Query", async () => {
+ const query = "SELECT SUM(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "SUM(age)": 101 }]);
+});
+
+test("Execute AVG Aggregate Query", async () => {
+ const query = "SELECT AVG(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ // Assuming AVG returns a single decimal point value
+ expect(result).toEqual([{ "AVG(age)": 25.25 }]);
+});
+
+test("Execute MIN Aggregate Query", async () => {
+ const query = "SELECT MIN(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MIN(age)": 22 }]);
+});
+
+test("Execute MAX Aggregate Query", async () => {
+ const query = "SELECT MAX(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MAX(age)": 30 }]);
+});
+
+test("Count students per age", async () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "22", "COUNT(*)": 1 },
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments per course", async () => {
+ const query = "SELECT course, COUNT(*) FROM enrollment GROUP BY course";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { course: "Mathematics", "COUNT(*)": 2 },
+ { course: "Physics", "COUNT(*)": 1 },
+ { course: "Chemistry", "COUNT(*)": 1 },
+ { course: "Biology", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count courses per student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { student_id: "1", "COUNT(*)": 2 },
+ { student_id: "2", "COUNT(*)": 1 },
+ { student_id: "3", "COUNT(*)": 1 },
+ { student_id: "5", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count students within a specific age range", async () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments for a specific course", async () => {
+ const query =
+ 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ course: "Mathematics", "COUNT(*)": 2 }]);
+});
+
+test("Count courses for a specific student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ student_id: "1", "COUNT(*)": 2 }]);
+});
+
+test("Average age of students above a certain age", async () => {
+ const query = "SELECT AVG(age) FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(query);
+ const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
+ expect(result).toEqual([{ "AVG(age)": expectedAverage }]);
+});
+
+test("Parse SQL Query", () => {
+ const query = "SELECT id, name FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with WHERE Clause", () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "25",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with Multiple WHERE Clauses", () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "30",
+ },
+ {
+ field: "name",
+ operator: "=",
+ value: "John",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN and WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "20" }],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse INNER JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "INNER",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse LEFT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "LEFT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse RIGHT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "RIGHT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Returns null for queries without JOIN", () => {
+ const query = "SELECT * FROM table1";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "LEFT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "RIGHT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "22" }],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Physics'" },
+ ],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: "<", value: "25" }],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Chemistry'" },
+ ],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse COUNT Aggregate Query", () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SUM Aggregate Query", () => {
+ const query = "SELECT SUM(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["SUM(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse AVG Aggregate Query", () => {
+ const query = "SELECT AVG(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["AVG(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MIN Aggregate Query", () => {
+ const query = "SELECT MIN(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MIN(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MAX Aggregate Query", () => {
+ const query = "SELECT MAX(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MAX(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse basic GROUP BY query", () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with WHERE clause", () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [{ field: "age", operator: ">", value: "22" }],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with multiple fields", () => {
+ const query =
+ "SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student_id", "course", "COUNT(*)"],
+ table: "enrollment",
+ whereClauses: [],
+ groupByFields: ["student_id", "course"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with JOIN and WHERE clauses", () => {
+ const query =
+ 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student.name", "COUNT(*)"],
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: '"Mathematics"' },
+ ],
+ groupByFields: ["student.name"],
+ joinType: "INNER",
+ joinTable: "enrollment",
+ joinCondition: {
+ left: "student.id",
+ right: "enrollment.student_id",
+ },
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Execute SQL Query with ORDER BY", async () => {
+ const query = "SELECT name FROM student ORDER BY name ASC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([
+ { name: "Alice" },
+ { name: "Bob" },
+ { name: "Jane" },
+ { name: "John" },
+ ]);
+});
+
+test("Execute SQL Query with ORDER BY and WHERE", async () => {
+ const query = "SELECT name FROM student WHERE age > 24 ORDER BY name DESC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([{ name: "John" }, { name: "Jane" }]);
+});
+test("Execute SQL Query with ORDER BY and GROUP BY", async () => {
+ const query =
+ "SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([
+ { age: "30", "COUNT(id) as count": 1 },
+ { age: "25", "COUNT(id) as count": 1 },
+ { age: "24", "COUNT(id) as count": 1 },
+ { age: "22", "COUNT(id) as count": 1 },
+ ]);
+});
+
+test("Execute SQL Query with standard LIMIT clause", async () => {
+ const query = "SELECT id, name FROM student LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with LIMIT clause equal to total rows", async () => {
+ const query = "SELECT id, name FROM student LIMIT 4";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(4);
+});
+
+test("Execute SQL Query with LIMIT clause exceeding total rows", async () => {
+ const query = "SELECT id, name FROM student LIMIT 10";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(4); // Total rows in student.csv
+});
+
+test("Execute SQL Query with LIMIT 0", async () => {
+ const query = "SELECT id, name FROM student LIMIT 0";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(0);
+});
+
+test("Execute SQL Query with LIMIT and ORDER BY clause", async () => {
+ const query = "SELECT id, name FROM student ORDER BY age DESC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(2);
+ expect(result[0].name).toEqual("John");
+ expect(result[1].name).toEqual("Jane");
+});
+
+test("Error Handling with Malformed Query", async () => {
+ const query = "SELECT FROM table"; // intentionally malformed
+ await expect(executeSELECTQuery(query)).rejects.toThrow(
+ "Error executing query: Query parsing error: Invalid SELECT format"
+ );
+});
+
+test("Basic DISTINCT Usage", async () => {
+ const query = "SELECT DISTINCT age FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "30" },
+ { age: "25" },
+ { age: "22" },
+ { age: "24" },
+ ]);
+});
+
+test("DISTINCT with Multiple Columns", async () => {
+ const query = "SELECT DISTINCT student_id, course FROM enrollment";
+ const result = await executeSELECTQuery(query);
+ // Expecting unique combinations of student_id and course
+ expect(result).toEqual([
+ { student_id: "1", course: "Mathematics" },
+ { student_id: "1", course: "Physics" },
+ { student_id: "2", course: "Chemistry" },
+ { student_id: "3", course: "Mathematics" },
+ { student_id: "5", course: "Biology" },
+ ]);
});
// Not a good test right now
-test('DISTINCT with WHERE Clause', async () => {
- const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"';
- const result = await executeSELECTQuery(query);
- // Expecting courses taken by student with ID 1
- expect(result).toEqual([{ course: 'Mathematics' }, { course: 'Physics' }]);
+test("DISTINCT with WHERE Clause", async () => {
+ const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"';
+ const result = await executeSELECTQuery(query);
+ // Expecting courses taken by student with ID 1
+ expect(result).toEqual([{ course: "Mathematics" }, { course: "Physics" }]);
});
-test('DISTINCT with JOIN Operations', async () => {
- const query = 'SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id';
- const result = await executeSELECTQuery(query);
- // Expecting names of students who are enrolled in any course
- expect(result).toEqual([{ "student.name": 'John' }, { "student.name": 'Jane' }, { "student.name": 'Bob' }]);
+test("DISTINCT with JOIN Operations", async () => {
+ const query =
+ "SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ // Expecting names of students who are enrolled in any course
+ expect(result).toEqual([
+ { "student.name": "John" },
+ { "student.name": "Jane" },
+ { "student.name": "Bob" },
+ ]);
});
-test('DISTINCT with ORDER BY and LIMIT', async () => {
- const query = 'SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2';
- const result = await executeSELECTQuery(query);
- // Expecting the two highest unique ages
- expect(result).toEqual([{ age: '30' }, { age: '25' }]);
+test("DISTINCT with ORDER BY and LIMIT", async () => {
+ const query = "SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ // Expecting the two highest unique ages
+ expect(result).toEqual([{ age: "30" }, { age: "25" }]);
});
-test('Execute SQL Query with LIKE Operator for Name', async () => {
- const query = "SELECT name FROM student WHERE name LIKE '%Jane%'";
- const result = await executeSELECTQuery(query);
- // Expecting names containing 'Jane'
- expect(result).toEqual([{ name: 'Jane' }]);
+test("Execute SQL Query with LIKE Operator for Name", async () => {
+ const query = "SELECT name FROM student WHERE name LIKE '%Jane%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting names containing 'Jane'
+ expect(result).toEqual([{ name: "Jane" }]);
});
-test('Execute SQL Query with LIKE Operator and Wildcards', async () => {
- const query = "SELECT name FROM student WHERE name LIKE 'J%'";
- const result = await executeSELECTQuery(query);
- // Expecting names starting with 'J'
- expect(result).toEqual([{ name: 'John' }, { name: 'Jane' }]);
+test("Execute SQL Query with LIKE Operator and Wildcards", async () => {
+ const query = "SELECT name FROM student WHERE name LIKE 'J%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting names starting with 'J'
+ expect(result).toEqual([{ name: "John" }, { name: "Jane" }]);
});
-test('Execute SQL Query with LIKE Operator Case Insensitive', async () => {
- const query = "SELECT name FROM student WHERE name LIKE '%bob%'";
- const result = await executeSELECTQuery(query);
- // Expecting names 'Bob' (case insensitive)
- expect(result).toEqual([{ name: 'Bob' }]);
+test("Execute SQL Query with LIKE Operator Case Insensitive", async () => {
+ const query = "SELECT name FROM student WHERE name LIKE '%bob%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting names 'Bob' (case insensitive)
+ expect(result).toEqual([{ name: "Bob" }]);
});
-test('Execute SQL Query with LIKE Operator and DISTINCT', async () => {
- const query = "SELECT DISTINCT name FROM student WHERE name LIKE '%e%'";
- const result = await executeSELECTQuery(query);
- // Expecting unique names containing 'e'
- expect(result).toEqual([{ name: 'Jane' }, { name: 'Alice' }]);
+test("Execute SQL Query with LIKE Operator and DISTINCT", async () => {
+ const query = "SELECT DISTINCT name FROM student WHERE name LIKE '%e%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting unique names containing 'e'
+ expect(result).toEqual([{ name: "Jane" }, { name: "Alice" }]);
});
-test('LIKE with ORDER BY and LIMIT', async () => {
- const query = "SELECT name FROM student WHERE name LIKE '%a%' ORDER BY name ASC LIMIT 2";
- const result = await executeSELECTQuery(query);
- // Expecting the first two names alphabetically that contain 'a'
- expect(result).toEqual([{ name: 'Alice' }, { name: 'Jane' }]);
-});
\ No newline at end of file
+test("LIKE with ORDER BY and LIMIT", async () => {
+ const query =
+ "SELECT name FROM student WHERE name LIKE '%a%' ORDER BY name ASC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ // Expecting the first two names alphabetically that contain 'a'
+ expect(result).toEqual([{ name: "Alice" }, { name: "Jane" }]);
+});
diff --git a/tests/step-18/insertExecuter.test.js b/tests/step-18/insertExecuter.test.js
index 8c405f727..473314045 100644
--- a/tests/step-18/insertExecuter.test.js
+++ b/tests/step-18/insertExecuter.test.js
@@ -1,33 +1,36 @@
-const { executeINSERTQuery } = require('../../src/index');
-const { readCSV, writeCSV } = require('../../src/csvReader');
-const fs = require('fs');
+const { executeINSERTQuery } = require("../../src/queryExecutor");
+const { readCSV, writeCSV } = require("../../src/csvReader");
+const fs = require("fs");
// Helper function to create grades.csv with initial data
async function createGradesCSV() {
- const initialData = [
- { student_id: '1', course: 'Mathematics', grade: 'A' },
- { student_id: '2', course: 'Chemistry', grade: 'B' },
- { student_id: '3', course: 'Mathematics', grade: 'C' }
- ];
- await writeCSV('grades.csv', initialData);
+ const initialData = [
+ { student_id: "1", course: "Mathematics", grade: "A" },
+ { student_id: "2", course: "Chemistry", grade: "B" },
+ { student_id: "3", course: "Mathematics", grade: "C" },
+ ];
+ await writeCSV("grades.csv", initialData);
}
// Test to INSERT a new grade and verify
-test('Execute INSERT INTO Query for grades.csv', async () => {
- // Create grades.csv with initial data
- await createGradesCSV();
+test("Execute INSERT INTO Query for grades.csv", async () => {
+ // Create grades.csv with initial data
+ await createGradesCSV();
- // Execute INSERT statement
- const insertQuery = "INSERT INTO grades (student_id, course, grade) VALUES ('4', 'Physics', 'A')";
- await executeINSERTQuery(insertQuery);
+ // Execute INSERT statement
+ const insertQuery =
+ "INSERT INTO grades (student_id, course, grade) VALUES ('4', 'Physics', 'A')";
+ await executeINSERTQuery(insertQuery);
- // Verify the new entry
- const updatedData = await readCSV('grades.csv');
- const newEntry = updatedData.find(row => row.student_id === '4' && row.course === 'Physics');
- console.log(updatedData)
- expect(newEntry).toBeDefined();
- expect(newEntry.grade).toEqual('A');
+ // Verify the new entry
+ const updatedData = await readCSV("grades.csv");
+ const newEntry = updatedData.find(
+ (row) => row.student_id === "4" && row.course === "Physics"
+ );
- // Cleanup: Delete grades.csv
- fs.unlinkSync('grades.csv');
-});
\ No newline at end of file
+ expect(newEntry).toBeDefined();
+ expect(newEntry.grade).toEqual("A");
+
+ // Cleanup: Delete grades.csv
+ fs.unlinkSync("grades.csv");
+});
diff --git a/tests/step-19/deleteExecutor.test.js b/tests/step-19/deleteExecutor.test.js
index 11ae617b7..0e53a921e 100644
--- a/tests/step-19/deleteExecutor.test.js
+++ b/tests/step-19/deleteExecutor.test.js
@@ -1,31 +1,31 @@
-const { executeDELETEQuery } = require('../../src/index');
-const { readCSV, writeCSV } = require('../../src/csvReader');
-const fs = require('fs');
+const { executeDELETEQuery } = require("../../src/queryExecutor");
+const { readCSV, writeCSV } = require("../../src/csvReader");
+const fs = require("fs");
// Helper function to create courses.csv with initial data
async function createCoursesCSV() {
- const initialData = [
- { course_id: '1', course_name: 'Mathematics', instructor: 'Dr. Smith' },
- { course_id: '2', course_name: 'Chemistry', instructor: 'Dr. Jones' },
- { course_id: '3', course_name: 'Physics', instructor: 'Dr. Taylor' }
- ];
- await writeCSV('courses.csv', initialData);
+ const initialData = [
+ { course_id: "1", course_name: "Mathematics", instructor: "Dr. Smith" },
+ { course_id: "2", course_name: "Chemistry", instructor: "Dr. Jones" },
+ { course_id: "3", course_name: "Physics", instructor: "Dr. Taylor" },
+ ];
+ await writeCSV("courses.csv", initialData);
}
// Test to DELETE a course and verify
-test('Execute DELETE FROM Query for courses.csv', async () => {
- // Create courses.csv with initial data
- await createCoursesCSV();
+test("Execute DELETE FROM Query for courses.csv", async () => {
+ // Create courses.csv with initial data
+ await createCoursesCSV();
- // Execute DELETE statement
- const deleteQuery = "DELETE FROM courses WHERE course_id = '2'";
- await executeDELETEQuery(deleteQuery);
+ // Execute DELETE statement
+ const deleteQuery = "DELETE FROM courses WHERE course_id = '2'";
+ await executeDELETEQuery(deleteQuery);
- // Verify the course was removed
- const updatedData = await readCSV('courses.csv');
- const deletedCourse = updatedData.find(course => course.course_id === '2');
- expect(deletedCourse).toBeUndefined();
+ // Verify the course was removed
+ const updatedData = await readCSV("courses.csv");
+ const deletedCourse = updatedData.find((course) => course.course_id === "2");
+ expect(deletedCourse).toBeUndefined();
- // Cleanup: Delete courses.csv
- fs.unlinkSync('courses.csv');
-});
\ No newline at end of file
+ // Cleanup: Delete courses.csv
+ fs.unlinkSync("courses.csv");
+});
diff --git a/tests/step-19/index.test.js b/tests/step-19/index.test.js
index c99d01fbb..677604fb2 100644
--- a/tests/step-19/index.test.js
+++ b/tests/step-19/index.test.js
@@ -1,59 +1,60 @@
-const {readCSV} = require('../../src/csvReader');
-const {executeSELECTQuery } = require('../../src/index');
-const { parseJoinClause, parseSelectQuery } = require('../../src/queryParser');
-
-test('Read CSV File', async () => {
- const data = await readCSV('./student.csv');
- expect(data.length).toBeGreaterThan(0);
- expect(data.length).toBe(4);
- expect(data[0].name).toBe('John');
- expect(data[0].age).toBe('30'); //ignore the string type here, we will fix this later
-});
-
-test('Execute SQL Query', async () => {
- const query = 'SELECT id, name FROM student';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBeGreaterThan(0);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0]).not.toHaveProperty('age');
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toHaveProperty('id');
- expect(result[0]).toHaveProperty('name');
- expect(result[0].id).toBe('2');
-});
-
-test('Execute SQL Query with Complex WHERE Clause', async () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const result = await executeSELECTQuery(query);
- expect(result.length).toBe(1);
- expect(result[0]).toEqual({ id: '1', name: 'John' });
-});
-
-test('Execute SQL Query with Greater Than', async () => {
- const queryWithGT = 'SELECT id FROM student WHERE age > 22';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('id');
-});
-
-test('Execute SQL Query with Not Equal to', async () => {
- const queryWithGT = 'SELECT name FROM student WHERE age != 25';
- const result = await executeSELECTQuery(queryWithGT);
- expect(result.length).toEqual(3);
- expect(result[0]).toHaveProperty('name');
-});
-
-test('Execute SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- /*
+const { readCSV } = require("../../src/csvReader");
+const { executeSELECTQuery } = require("../../src/queryExecutor");
+const { parseJoinClause, parseSelectQuery } = require("../../src/queryParser");
+
+test("Read CSV File", async () => {
+ const data = await readCSV("./student.csv");
+ expect(data.length).toBeGreaterThan(0);
+ expect(data.length).toBe(4);
+ expect(data[0].name).toBe("John");
+ expect(data[0].age).toBe("30"); //ignore the string type here, we will fix this later
+});
+
+test("Execute SQL Query", async () => {
+ const query = "SELECT id, name FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBeGreaterThan(0);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0]).not.toHaveProperty("age");
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toHaveProperty("id");
+ expect(result[0]).toHaveProperty("name");
+ expect(result[0].id).toBe("2");
+});
+
+test("Execute SQL Query with Complex WHERE Clause", async () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toBe(1);
+ expect(result[0]).toEqual({ id: "1", name: "John" });
+});
+
+test("Execute SQL Query with Greater Than", async () => {
+ const queryWithGT = "SELECT id FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("id");
+});
+
+test("Execute SQL Query with Not Equal to", async () => {
+ const queryWithGT = "SELECT name FROM student WHERE age != 25";
+ const result = await executeSELECTQuery(queryWithGT);
+ expect(result.length).toEqual(3);
+ expect(result[0]).toHaveProperty("name");
+});
+
+test("Execute SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{ 'student.name': 'John', 'enrollment.course': 'Mathematics' },
{ 'student.name': 'John', 'enrollment.course': 'Physics' },
@@ -61,18 +62,21 @@ test('Execute SQL Query with INNER JOIN', async () => {
{ 'student.name': 'Bob', 'enrollment.course': 'Mathematics' }
]
*/
- expect(result.length).toEqual(4);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
+ expect(result.length).toEqual(4);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ })
+ );
});
-test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25';
- const result = await executeSELECTQuery(query);
- /*
+test("Execute SQL Query with INNER JOIN and a WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course, student.age FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 25";
+ const result = await executeSELECTQuery(query);
+ /*
result = [
{
'student.name': 'John',
@@ -86,737 +90,812 @@ test('Execute SQL Query with INNER JOIN and a WHERE Clause', async () => {
}
]
*/
- expect(result.length).toEqual(2);
- // toHaveProperty is not working here due to dot in the property name
- expect(result[0]).toEqual(expect.objectContaining({
- "enrollment.course": "Mathematics",
- "student.name": "John"
- }));
-});
-
-test('Execute SQL Query with LEFT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "Alice", "enrollment.course": null }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 students, but John appears twice
-});
-
-test('Execute SQL Query with RIGHT JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": null, "enrollment.course": "Biology" }),
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Mathematics" })
- ]));
- expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
-});
-
-test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "John" }),
- expect.objectContaining({ "enrollment.course": "Physics", "student.name": "John" })
- ]));
- expect(result.length).toEqual(4);
-});
-
-test('Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "student.name": "John", "enrollment.course": "Physics" })
- ]));
- expect(result.length).toEqual(1);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Mathematics", "student.name": "Bob" }),
- expect.objectContaining({ "enrollment.course": "Biology", "student.name": null })
- ]));
- expect(result.length).toEqual(2);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual(expect.arrayContaining([
- expect.objectContaining({ "enrollment.course": "Chemistry", "student.name": "Jane" }),
- ]));
- expect(result.length).toEqual(1);
-});
-
-test('Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([]);
-});
-
-test('Execute COUNT Aggregate Query', async () => {
- const query = 'SELECT COUNT(*) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'COUNT(*)': 4 }]);
-});
-
-test('Execute SUM Aggregate Query', async () => {
- const query = 'SELECT SUM(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'SUM(age)': 101 }]);
-});
-
-test('Execute AVG Aggregate Query', async () => {
- const query = 'SELECT AVG(age) FROM student';
- const result = await executeSELECTQuery(query);
- // Assuming AVG returns a single decimal point value
- expect(result).toEqual([{ 'AVG(age)': 25.25 }]);
-});
-
-test('Execute MIN Aggregate Query', async () => {
- const query = 'SELECT MIN(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'MIN(age)': 22 }]);
-});
-
-test('Execute MAX Aggregate Query', async () => {
- const query = 'SELECT MAX(age) FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ 'MAX(age)': 30 }]);
-});
-
-test('Count students per age', async () => {
- const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { age: '22', 'COUNT(*)': 1 },
- { age: '24', 'COUNT(*)': 1 },
- { age: '25', 'COUNT(*)': 1 },
- { age: '30', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count enrollments per course', async () => {
- const query = 'SELECT course, COUNT(*) FROM enrollment GROUP BY course';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { course: 'Mathematics', 'COUNT(*)': 2 },
- { course: 'Physics', 'COUNT(*)': 1 },
- { course: 'Chemistry', 'COUNT(*)': 1 },
- { course: 'Biology', 'COUNT(*)': 1 }
- ]);
-});
-
-
-test('Count courses per student', async () => {
- const query = 'SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { student_id: '1', 'COUNT(*)': 2 },
- { student_id: '2', 'COUNT(*)': 1 },
- { student_id: '3', 'COUNT(*)': 1 },
- { student_id: '5', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count students within a specific age range', async () => {
- const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { age: '24', 'COUNT(*)': 1 },
- { age: '25', 'COUNT(*)': 1 },
- { age: '30', 'COUNT(*)': 1 }
- ]);
-});
-
-test('Count enrollments for a specific course', async () => {
- const query = 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { course: 'Mathematics', 'COUNT(*)': 2 }
- ]);
-});
-
-test('Count courses for a specific student', async () => {
- const query = 'SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([
- { student_id: '1', 'COUNT(*)': 2 }
- ]);
-});
-
-test('Average age of students above a certain age', async () => {
- const query = 'SELECT AVG(age) FROM student WHERE age > 22';
- const result = await executeSELECTQuery(query);
- const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
- expect(result).toEqual([{ 'AVG(age)': expectedAverage }]);
-});
-
-test('Parse SQL Query', () => {
- const query = 'SELECT id, name FROM student';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with WHERE Clause', () => {
- const query = 'SELECT id, name FROM student WHERE age = 25';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "25",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with Multiple WHERE Clauses', () => {
- const query = 'SELECT id, name FROM student WHERE age = 30 AND name = John';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['id', 'name'],
- table: 'student',
- whereClauses: [{
- "field": "age",
- "operator": "=",
- "value": "30",
- }, {
- "field": "name",
- "operator": "=",
- "value": "John",
- }],
- joinCondition: null,
- joinTable: null,
- joinType: null,
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with INNER JOIN', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id';
- const result = await parseSelectQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinTable: 'enrollment',
- joinType: "INNER",
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
+ expect(result.length).toEqual(2);
+ // toHaveProperty is not working here due to dot in the property name
+ expect(result[0]).toEqual(
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
})
-});
-
-test('Parse SQL Query with INNER JOIN and WHERE Clause', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20';
- const result = await parseSelectQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [{ field: 'student.age', operator: '>', value: '20' }],
- joinTable: 'enrollment',
- joinType: "INNER",
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- })
-});
-
-test('Parse INNER JOIN clause', () => {
- const query = 'SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'INNER',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' },
- });
-});
-
-test('Parse LEFT JOIN clause', () => {
- const query = 'SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'LEFT',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' }
- });
-});
-
-test('Parse RIGHT JOIN clause', () => {
- const query = 'SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id';
- const result = parseJoinClause(query);
- expect(result).toEqual({
- joinType: 'RIGHT',
- joinTable: 'table2',
- joinCondition: { left: 'table1.id', right: 'table2.ref_id' }
- });
-});
-
-test('Returns null for queries without JOIN', () => {
- const query = 'SELECT * FROM table1';
- const result = parseJoinClause(query);
- expect(result).toEqual(
- {
- joinType: null,
- joinTable: null,
- joinCondition: null
- }
- );
-});
-
-test('Parse LEFT Join Query Completely', () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseSelectQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinType: 'LEFT',
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- })
-})
-
-test('Parse LEFT Join Query Completely', () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id';
- const result = parseSelectQuery(query);
- expect(result).toEqual({
- fields: ['student.name', 'enrollment.course'],
- table: 'student',
- whereClauses: [],
- joinType: 'RIGHT',
- joinTable: 'enrollment',
- joinCondition: { left: 'student.id', right: 'enrollment.student_id' },
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- })
-})
-
-test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22';
- const result = await parseSelectQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "LEFT",
- "table": "student",
- "whereClauses": [{ "field": "student.age", "operator": ">", "value": "22" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
- const result = await parseSelectQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "LEFT",
- "table": "student",
- "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Physics'" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table', async () => {
- const query = 'SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25';
- const result = await parseSelectQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "RIGHT",
- "table": "student",
- "whereClauses": [{ "field": "student.age", "operator": "<", "value": "25" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table', async () => {
- const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
- const result = await parseSelectQuery(query);
- expect(result).toEqual({
- "fields": ["student.name", "enrollment.course"],
- "joinCondition": { "left": "student.id", "right": "enrollment.student_id" },
- "joinTable": "enrollment",
- "joinType": "RIGHT",
- "table": "student",
- "whereClauses": [{ "field": "enrollment.course", "operator": "=", "value": "'Chemistry'" }],
- groupByFields: null,
- hasAggregateWithoutGroupBy: false,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-
-test('Parse COUNT Aggregate Query', () => {
- const query = 'SELECT COUNT(*) FROM student';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['COUNT(*)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-
-test('Parse SUM Aggregate Query', () => {
- const query = 'SELECT SUM(age) FROM student';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['SUM(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse AVG Aggregate Query', () => {
- const query = 'SELECT AVG(age) FROM student';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['AVG(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse MIN Aggregate Query', () => {
- const query = 'SELECT MIN(age) FROM student';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['MIN(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse MAX Aggregate Query', () => {
- const query = 'SELECT MAX(age) FROM student';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['MAX(age)'],
- table: 'student',
- whereClauses: [],
- groupByFields: null,
- hasAggregateWithoutGroupBy: true,
- "joinCondition": null,
- "joinTable": null,
- "joinType": null,
- "orderByFields": null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse basic GROUP BY query', () => {
- const query = 'SELECT age, COUNT(*) FROM student GROUP BY age';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['age', 'COUNT(*)'],
- table: 'student',
- whereClauses: [],
- groupByFields: ['age'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse GROUP BY query with WHERE clause', () => {
- const query = 'SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['age', 'COUNT(*)'],
- table: 'student',
- whereClauses: [{ field: 'age', operator: '>', value: '22' }],
- groupByFields: ['age'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse GROUP BY query with multiple fields', () => {
- const query = 'SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['student_id', 'course', 'COUNT(*)'],
- table: 'enrollment',
- whereClauses: [],
- groupByFields: ['student_id', 'course'],
- joinType: null,
- joinTable: null,
- joinCondition: null,
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false
- });
-});
-
-test('Parse GROUP BY query with JOIN and WHERE clauses', () => {
- const query = 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
- const parsed = parseSelectQuery(query);
- expect(parsed).toEqual({
- fields: ['student.name', 'COUNT(*)'],
- table: 'student',
- whereClauses: [{ field: 'enrollment.course', operator: '=', value: '"Mathematics"' }],
- groupByFields: ['student.name'],
- joinType: 'INNER',
- joinTable: 'enrollment',
- joinCondition: {
- left: 'student.id',
- right: 'enrollment.student_id'
- },
- hasAggregateWithoutGroupBy: false,
- orderByFields: null,
- "limit": null,
- isDistinct: false,
- });
-});
-
-test('Execute SQL Query with ORDER BY', async () => {
- const query = 'SELECT name FROM student ORDER BY name ASC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { name: 'Alice' },
- { name: 'Bob' },
- { name: 'Jane' },
- { name: 'John' }
- ]);
-});
-
-test('Execute SQL Query with ORDER BY and WHERE', async () => {
- const query = 'SELECT name FROM student WHERE age > 24 ORDER BY name DESC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { name: 'John' },
- { name: 'Jane' },
- ]);
-});
-test('Execute SQL Query with ORDER BY and GROUP BY', async () => {
- const query = 'SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC';
- const result = await executeSELECTQuery(query);
-
- expect(result).toStrictEqual([
- { age: '30', 'COUNT(id) as count': 1 },
- { age: '25', 'COUNT(id) as count': 1 },
- { age: '24', 'COUNT(id) as count': 1 },
- { age: '22', 'COUNT(id) as count': 1 }
- ]);
-});
-
-test('Execute SQL Query with standard LIMIT clause', async () => {
- const query = 'SELECT id, name FROM student LIMIT 2';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(2);
-});
-
-test('Execute SQL Query with LIMIT clause equal to total rows', async () => {
- const query = 'SELECT id, name FROM student LIMIT 4';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(4);
-});
-
-test('Execute SQL Query with LIMIT clause exceeding total rows', async () => {
- const query = 'SELECT id, name FROM student LIMIT 10';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(4); // Total rows in student.csv
-});
-
-test('Execute SQL Query with LIMIT 0', async () => {
- const query = 'SELECT id, name FROM student LIMIT 0';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(0);
-});
-
-test('Execute SQL Query with LIMIT and ORDER BY clause', async () => {
- const query = 'SELECT id, name FROM student ORDER BY age DESC LIMIT 2';
- const result = await executeSELECTQuery(query);
- expect(result.length).toEqual(2);
- expect(result[0].name).toEqual('John');
- expect(result[1].name).toEqual('Jane');
-});
-
-test('Error Handling with Malformed Query', async () => {
- const query = 'SELECT FROM table'; // intentionally malformed
- await expect(executeSELECTQuery(query)).rejects.toThrow("Error executing query: Query parsing error: Invalid SELECT format");
-});
-
-test('Basic DISTINCT Usage', async () => {
- const query = 'SELECT DISTINCT age FROM student';
- const result = await executeSELECTQuery(query);
- expect(result).toEqual([{ age: '30' }, { age: '25' }, { age: '22' }, { age: '24' }]);
-});
-
-test('DISTINCT with Multiple Columns', async () => {
- const query = 'SELECT DISTINCT student_id, course FROM enrollment';
- const result = await executeSELECTQuery(query);
- // Expecting unique combinations of student_id and course
- expect(result).toEqual([
- { student_id: '1', course: 'Mathematics' },
- { student_id: '1', course: 'Physics' },
- { student_id: '2', course: 'Chemistry' },
- { student_id: '3', course: 'Mathematics' },
- { student_id: '5', course: 'Biology' },
- ]);
+ );
+});
+
+test("Execute SQL Query with LEFT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "Alice",
+ "enrollment.course": null,
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 students, but John appears twice
+});
+
+test("Execute SQL Query with RIGHT JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": null,
+ "enrollment.course": "Biology",
+ }),
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Mathematics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(5); // 4 courses, but Mathematics appears twice
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "John",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Physics",
+ "student.name": "John",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(4);
+});
+
+test("Execute SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "student.name": "John",
+ "enrollment.course": "Physics",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Mathematics",
+ "student.name": "Bob",
+ }),
+ expect.objectContaining({
+ "enrollment.course": "Biology",
+ "student.name": null,
+ }),
+ ])
+ );
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ "enrollment.course": "Chemistry",
+ "student.name": "Jane",
+ }),
+ ])
+ );
+ expect(result.length).toEqual(1);
+});
+
+test("Execute SQL Query with RIGHT JOIN with a multiple WHERE clauses filtering the join table and main table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry' AND student.age = 26`;
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([]);
+});
+
+test("Execute COUNT Aggregate Query", async () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "COUNT(*)": 4 }]);
+});
+
+test("Execute SUM Aggregate Query", async () => {
+ const query = "SELECT SUM(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "SUM(age)": 101 }]);
+});
+
+test("Execute AVG Aggregate Query", async () => {
+ const query = "SELECT AVG(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ // Assuming AVG returns a single decimal point value
+ expect(result).toEqual([{ "AVG(age)": 25.25 }]);
+});
+
+test("Execute MIN Aggregate Query", async () => {
+ const query = "SELECT MIN(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MIN(age)": 22 }]);
+});
+
+test("Execute MAX Aggregate Query", async () => {
+ const query = "SELECT MAX(age) FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ "MAX(age)": 30 }]);
+});
+
+test("Count students per age", async () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "22", "COUNT(*)": 1 },
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments per course", async () => {
+ const query = "SELECT course, COUNT(*) FROM enrollment GROUP BY course";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { course: "Mathematics", "COUNT(*)": 2 },
+ { course: "Physics", "COUNT(*)": 1 },
+ { course: "Chemistry", "COUNT(*)": 1 },
+ { course: "Biology", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count courses per student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { student_id: "1", "COUNT(*)": 2 },
+ { student_id: "2", "COUNT(*)": 1 },
+ { student_id: "3", "COUNT(*)": 1 },
+ { student_id: "5", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count students within a specific age range", async () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "24", "COUNT(*)": 1 },
+ { age: "25", "COUNT(*)": 1 },
+ { age: "30", "COUNT(*)": 1 },
+ ]);
+});
+
+test("Count enrollments for a specific course", async () => {
+ const query =
+ 'SELECT course, COUNT(*) FROM enrollment WHERE course = "Mathematics" GROUP BY course';
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ course: "Mathematics", "COUNT(*)": 2 }]);
+});
+
+test("Count courses for a specific student", async () => {
+ const query =
+ "SELECT student_id, COUNT(*) FROM enrollment WHERE student_id = 1 GROUP BY student_id";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([{ student_id: "1", "COUNT(*)": 2 }]);
+});
+
+test("Average age of students above a certain age", async () => {
+ const query = "SELECT AVG(age) FROM student WHERE age > 22";
+ const result = await executeSELECTQuery(query);
+ const expectedAverage = (25 + 30 + 24) / 3; // Average age of students older than 22
+ expect(result).toEqual([{ "AVG(age)": expectedAverage }]);
+});
+
+test("Parse SQL Query", () => {
+ const query = "SELECT id, name FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with WHERE Clause", () => {
+ const query = "SELECT id, name FROM student WHERE age = 25";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "25",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with Multiple WHERE Clauses", () => {
+ const query = "SELECT id, name FROM student WHERE age = 30 AND name = John";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["id", "name"],
+ table: "student",
+ whereClauses: [
+ {
+ field: "age",
+ operator: "=",
+ value: "30",
+ },
+ {
+ field: "name",
+ operator: "=",
+ value: "John",
+ },
+ ],
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id=enrollment.student_id";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with INNER JOIN and WHERE Clause", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE student.age > 20";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "20" }],
+ joinTable: "enrollment",
+ joinType: "INNER",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse INNER JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "INNER",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse LEFT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "LEFT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Parse RIGHT JOIN clause", () => {
+ const query =
+ "SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.ref_id";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: "RIGHT",
+ joinTable: "table2",
+ joinCondition: { left: "table1.id", right: "table2.ref_id" },
+ });
+});
+
+test("Returns null for queries without JOIN", () => {
+ const query = "SELECT * FROM table1";
+ const result = parseJoinClause(query);
+ expect(result).toEqual({
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "LEFT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse LEFT Join Query Completely", () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id";
+ const result = parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ table: "student",
+ whereClauses: [],
+ joinType: "RIGHT",
+ joinTable: "enrollment",
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age > 22";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: ">", value: "22" }],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with LEFT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student LEFT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Physics'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "LEFT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Physics'" },
+ ],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the main table", async () => {
+ const query =
+ "SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE student.age < 25";
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [{ field: "student.age", operator: "<", value: "25" }],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SQL Query with RIGHT JOIN with a WHERE clause filtering the join table", async () => {
+ const query = `SELECT student.name, enrollment.course FROM student RIGHT JOIN enrollment ON student.id=enrollment.student_id WHERE enrollment.course = 'Chemistry'`;
+ const result = await parseSelectQuery(query);
+ expect(result).toEqual({
+ fields: ["student.name", "enrollment.course"],
+ joinCondition: { left: "student.id", right: "enrollment.student_id" },
+ joinTable: "enrollment",
+ joinType: "RIGHT",
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: "'Chemistry'" },
+ ],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse COUNT Aggregate Query", () => {
+ const query = "SELECT COUNT(*) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse SUM Aggregate Query", () => {
+ const query = "SELECT SUM(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["SUM(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse AVG Aggregate Query", () => {
+ const query = "SELECT AVG(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["AVG(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MIN Aggregate Query", () => {
+ const query = "SELECT MIN(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MIN(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse MAX Aggregate Query", () => {
+ const query = "SELECT MAX(age) FROM student";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["MAX(age)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: null,
+ hasAggregateWithoutGroupBy: true,
+ joinCondition: null,
+ joinTable: null,
+ joinType: null,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse basic GROUP BY query", () => {
+ const query = "SELECT age, COUNT(*) FROM student GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with WHERE clause", () => {
+ const query = "SELECT age, COUNT(*) FROM student WHERE age > 22 GROUP BY age";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["age", "COUNT(*)"],
+ table: "student",
+ whereClauses: [{ field: "age", operator: ">", value: "22" }],
+ groupByFields: ["age"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with multiple fields", () => {
+ const query =
+ "SELECT student_id, course, COUNT(*) FROM enrollment GROUP BY student_id, course";
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student_id", "course", "COUNT(*)"],
+ table: "enrollment",
+ whereClauses: [],
+ groupByFields: ["student_id", "course"],
+ joinType: null,
+ joinTable: null,
+ joinCondition: null,
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Parse GROUP BY query with JOIN and WHERE clauses", () => {
+ const query =
+ 'SELECT student.name, COUNT(*) FROM student INNER JOIN enrollment ON student.id = enrollment.student_id WHERE enrollment.course = "Mathematics" GROUP BY student.name';
+ const parsed = parseSelectQuery(query);
+ expect(parsed).toEqual({
+ fields: ["student.name", "COUNT(*)"],
+ table: "student",
+ whereClauses: [
+ { field: "enrollment.course", operator: "=", value: '"Mathematics"' },
+ ],
+ groupByFields: ["student.name"],
+ joinType: "INNER",
+ joinTable: "enrollment",
+ joinCondition: {
+ left: "student.id",
+ right: "enrollment.student_id",
+ },
+ hasAggregateWithoutGroupBy: false,
+ orderByFields: null,
+ limit: null,
+ isDistinct: false,
+ });
+});
+
+test("Execute SQL Query with ORDER BY", async () => {
+ const query = "SELECT name FROM student ORDER BY name ASC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([
+ { name: "Alice" },
+ { name: "Bob" },
+ { name: "Jane" },
+ { name: "John" },
+ ]);
+});
+
+test("Execute SQL Query with ORDER BY and WHERE", async () => {
+ const query = "SELECT name FROM student WHERE age > 24 ORDER BY name DESC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([{ name: "John" }, { name: "Jane" }]);
+});
+test("Execute SQL Query with ORDER BY and GROUP BY", async () => {
+ const query =
+ "SELECT COUNT(id) as count, age FROM student GROUP BY age ORDER BY age DESC";
+ const result = await executeSELECTQuery(query);
+
+ expect(result).toStrictEqual([
+ { age: "30", "COUNT(id) as count": 1 },
+ { age: "25", "COUNT(id) as count": 1 },
+ { age: "24", "COUNT(id) as count": 1 },
+ { age: "22", "COUNT(id) as count": 1 },
+ ]);
+});
+
+test("Execute SQL Query with standard LIMIT clause", async () => {
+ const query = "SELECT id, name FROM student LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(2);
+});
+
+test("Execute SQL Query with LIMIT clause equal to total rows", async () => {
+ const query = "SELECT id, name FROM student LIMIT 4";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(4);
+});
+
+test("Execute SQL Query with LIMIT clause exceeding total rows", async () => {
+ const query = "SELECT id, name FROM student LIMIT 10";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(4); // Total rows in student.csv
+});
+
+test("Execute SQL Query with LIMIT 0", async () => {
+ const query = "SELECT id, name FROM student LIMIT 0";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(0);
+});
+
+test("Execute SQL Query with LIMIT and ORDER BY clause", async () => {
+ const query = "SELECT id, name FROM student ORDER BY age DESC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ expect(result.length).toEqual(2);
+ expect(result[0].name).toEqual("John");
+ expect(result[1].name).toEqual("Jane");
+});
+
+test("Error Handling with Malformed Query", async () => {
+ const query = "SELECT FROM table"; // intentionally malformed
+ await expect(executeSELECTQuery(query)).rejects.toThrow(
+ "Error executing query: Query parsing error: Invalid SELECT format"
+ );
+});
+
+test("Basic DISTINCT Usage", async () => {
+ const query = "SELECT DISTINCT age FROM student";
+ const result = await executeSELECTQuery(query);
+ expect(result).toEqual([
+ { age: "30" },
+ { age: "25" },
+ { age: "22" },
+ { age: "24" },
+ ]);
+});
+
+test("DISTINCT with Multiple Columns", async () => {
+ const query = "SELECT DISTINCT student_id, course FROM enrollment";
+ const result = await executeSELECTQuery(query);
+ // Expecting unique combinations of student_id and course
+ expect(result).toEqual([
+ { student_id: "1", course: "Mathematics" },
+ { student_id: "1", course: "Physics" },
+ { student_id: "2", course: "Chemistry" },
+ { student_id: "3", course: "Mathematics" },
+ { student_id: "5", course: "Biology" },
+ ]);
});
// Not a good test right now
-test('DISTINCT with WHERE Clause', async () => {
- const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"';
- const result = await executeSELECTQuery(query);
- // Expecting courses taken by student with ID 1
- expect(result).toEqual([{ course: 'Mathematics' }, { course: 'Physics' }]);
+test("DISTINCT with WHERE Clause", async () => {
+ const query = 'SELECT DISTINCT course FROM enrollment WHERE student_id = "1"';
+ const result = await executeSELECTQuery(query);
+ // Expecting courses taken by student with ID 1
+ expect(result).toEqual([{ course: "Mathematics" }, { course: "Physics" }]);
});
-test('DISTINCT with JOIN Operations', async () => {
- const query = 'SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id';
- const result = await executeSELECTQuery(query);
- // Expecting names of students who are enrolled in any course
- expect(result).toEqual([{ "student.name": 'John' }, { "student.name": 'Jane' }, { "student.name": 'Bob' }]);
+test("DISTINCT with JOIN Operations", async () => {
+ const query =
+ "SELECT DISTINCT student.name FROM student INNER JOIN enrollment ON student.id = enrollment.student_id";
+ const result = await executeSELECTQuery(query);
+ // Expecting names of students who are enrolled in any course
+ expect(result).toEqual([
+ { "student.name": "John" },
+ { "student.name": "Jane" },
+ { "student.name": "Bob" },
+ ]);
});
-test('DISTINCT with ORDER BY and LIMIT', async () => {
- const query = 'SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2';
- const result = await executeSELECTQuery(query);
- // Expecting the two highest unique ages
- expect(result).toEqual([{ age: '30' }, { age: '25' }]);
+test("DISTINCT with ORDER BY and LIMIT", async () => {
+ const query = "SELECT DISTINCT age FROM student ORDER BY age DESC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ // Expecting the two highest unique ages
+ expect(result).toEqual([{ age: "30" }, { age: "25" }]);
});
-test('Execute SQL Query with LIKE Operator for Name', async () => {
- const query = "SELECT name FROM student WHERE name LIKE '%Jane%'";
- const result = await executeSELECTQuery(query);
- // Expecting names containing 'Jane'
- expect(result).toEqual([{ name: 'Jane' }]);
+test("Execute SQL Query with LIKE Operator for Name", async () => {
+ const query = "SELECT name FROM student WHERE name LIKE '%Jane%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting names containing 'Jane'
+ expect(result).toEqual([{ name: "Jane" }]);
});
-test('Execute SQL Query with LIKE Operator and Wildcards', async () => {
- const query = "SELECT name FROM student WHERE name LIKE 'J%'";
- const result = await executeSELECTQuery(query);
- // Expecting names starting with 'J'
- expect(result).toEqual([{ name: 'John' }, { name: 'Jane' }]);
+test("Execute SQL Query with LIKE Operator and Wildcards", async () => {
+ const query = "SELECT name FROM student WHERE name LIKE 'J%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting names starting with 'J'
+ expect(result).toEqual([{ name: "John" }, { name: "Jane" }]);
});
-test('Execute SQL Query with LIKE Operator Case Insensitive', async () => {
- const query = "SELECT name FROM student WHERE name LIKE '%bob%'";
- const result = await executeSELECTQuery(query);
- // Expecting names 'Bob' (case insensitive)
- expect(result).toEqual([{ name: 'Bob' }]);
+test("Execute SQL Query with LIKE Operator Case Insensitive", async () => {
+ const query = "SELECT name FROM student WHERE name LIKE '%bob%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting names 'Bob' (case insensitive)
+ expect(result).toEqual([{ name: "Bob" }]);
});
-test('Execute SQL Query with LIKE Operator and DISTINCT', async () => {
- const query = "SELECT DISTINCT name FROM student WHERE name LIKE '%e%'";
- const result = await executeSELECTQuery(query);
- // Expecting unique names containing 'e'
- expect(result).toEqual([{ name: 'Jane' }, { name: 'Alice' }]);
+test("Execute SQL Query with LIKE Operator and DISTINCT", async () => {
+ const query = "SELECT DISTINCT name FROM student WHERE name LIKE '%e%'";
+ const result = await executeSELECTQuery(query);
+ // Expecting unique names containing 'e'
+ expect(result).toEqual([{ name: "Jane" }, { name: "Alice" }]);
});
-test('LIKE with ORDER BY and LIMIT', async () => {
- const query = "SELECT name FROM student WHERE name LIKE '%a%' ORDER BY name ASC LIMIT 2";
- const result = await executeSELECTQuery(query);
- // Expecting the first two names alphabetically that contain 'a'
- expect(result).toEqual([{ name: 'Alice' }, { name: 'Jane' }]);
-});
\ No newline at end of file
+test("LIKE with ORDER BY and LIMIT", async () => {
+ const query =
+ "SELECT name FROM student WHERE name LIKE '%a%' ORDER BY name ASC LIMIT 2";
+ const result = await executeSELECTQuery(query);
+ // Expecting the first two names alphabetically that contain 'a'
+ expect(result).toEqual([{ name: "Alice" }, { name: "Jane" }]);
+});
diff --git a/tests/step-19/insertExecuter.test.js b/tests/step-19/insertExecuter.test.js
index 8c405f727..473314045 100644
--- a/tests/step-19/insertExecuter.test.js
+++ b/tests/step-19/insertExecuter.test.js
@@ -1,33 +1,36 @@
-const { executeINSERTQuery } = require('../../src/index');
-const { readCSV, writeCSV } = require('../../src/csvReader');
-const fs = require('fs');
+const { executeINSERTQuery } = require("../../src/queryExecutor");
+const { readCSV, writeCSV } = require("../../src/csvReader");
+const fs = require("fs");
// Helper function to create grades.csv with initial data
async function createGradesCSV() {
- const initialData = [
- { student_id: '1', course: 'Mathematics', grade: 'A' },
- { student_id: '2', course: 'Chemistry', grade: 'B' },
- { student_id: '3', course: 'Mathematics', grade: 'C' }
- ];
- await writeCSV('grades.csv', initialData);
+ const initialData = [
+ { student_id: "1", course: "Mathematics", grade: "A" },
+ { student_id: "2", course: "Chemistry", grade: "B" },
+ { student_id: "3", course: "Mathematics", grade: "C" },
+ ];
+ await writeCSV("grades.csv", initialData);
}
// Test to INSERT a new grade and verify
-test('Execute INSERT INTO Query for grades.csv', async () => {
- // Create grades.csv with initial data
- await createGradesCSV();
+test("Execute INSERT INTO Query for grades.csv", async () => {
+ // Create grades.csv with initial data
+ await createGradesCSV();
- // Execute INSERT statement
- const insertQuery = "INSERT INTO grades (student_id, course, grade) VALUES ('4', 'Physics', 'A')";
- await executeINSERTQuery(insertQuery);
+ // Execute INSERT statement
+ const insertQuery =
+ "INSERT INTO grades (student_id, course, grade) VALUES ('4', 'Physics', 'A')";
+ await executeINSERTQuery(insertQuery);
- // Verify the new entry
- const updatedData = await readCSV('grades.csv');
- const newEntry = updatedData.find(row => row.student_id === '4' && row.course === 'Physics');
- console.log(updatedData)
- expect(newEntry).toBeDefined();
- expect(newEntry.grade).toEqual('A');
+ // Verify the new entry
+ const updatedData = await readCSV("grades.csv");
+ const newEntry = updatedData.find(
+ (row) => row.student_id === "4" && row.course === "Physics"
+ );
- // Cleanup: Delete grades.csv
- fs.unlinkSync('grades.csv');
-});
\ No newline at end of file
+ expect(newEntry).toBeDefined();
+ expect(newEntry.grade).toEqual("A");
+
+ // Cleanup: Delete grades.csv
+ fs.unlinkSync("grades.csv");
+});
diff --git a/util/generateLargeFile.js b/util/generateLargeFile.js
new file mode 100644
index 000000000..279a44441
--- /dev/null
+++ b/util/generateLargeFile.js
@@ -0,0 +1,34 @@
+const fs = require("fs");
+const { faker, da } = require("@faker-js/faker");
+const { parse } = require("json2csv");
+
+async function generateLargeCSV(filename) {
+ let data = [];
+ for (let i = 1; i <= 10_000_000; i++) {
+ const record = {
+ id: i,
+ name: faker.person.firstName(),
+ age: faker.number.int({ min: 18, max: 100 }),
+ };
+ data.push(record);
+
+ let rows;
+ if (i % 500_000 === 0) {
+ console.log(`Generated ${i} records`);
+ if (!fs.existsSync(filename)) {
+ rows = parse(data, { header: true });
+ } else {
+ // Rows without headers.
+ rows = parse(data, { header: false });
+ }
+ fs.appendFileSync(filename, rows);
+ data = [];
+ }
+ }
+ // Append file function can create new file too.
+
+ // Always add new line if file already exists.
+ fs.appendFileSync(filename, "\r\n");
+}
+
+generateLargeCSV("student_large.csv");