Skip to content

Commit 39c86be

Browse files
committed
Merge branch 'dev-WhereClauseIssue'
2 parents 6490bf0 + a3bb1c8 commit 39c86be

File tree

7 files changed

+175
-149
lines changed

7 files changed

+175
-149
lines changed

connectEngine.c

Lines changed: 54 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -70,21 +70,28 @@ struct whereClauseS* convert_conditions(ParsedSQL *parsed) {
7070

7171
for (int i = 0; i < parsed->num_conditions; i++) {
7272
struct whereClauseS *node = malloc(sizeof(struct whereClauseS));
73-
node->attribute = parsed->conditions[i].column;
74-
node->operator = get_operator_string(parsed->conditions[i].op);
75-
node->value = parsed->conditions[i].value;
7673

77-
// Simple type inference for the test
78-
if (parsed->conditions[i].is_numeric) {
79-
node->value_type = 0; // Integer/Number
74+
if (parsed->conditions[i].is_nested && parsed->conditions[i].nested_sql) {
75+
node->attribute = NULL;
76+
node->operator = NULL;
77+
node->value = NULL;
78+
node->value_type = 0;
79+
node->sub = convert_conditions(parsed->conditions[i].nested_sql);
8080
} else {
81-
node->value_type = 1; // String
81+
node->attribute = parsed->conditions[i].column;
82+
node->operator = get_operator_string(parsed->conditions[i].op);
83+
node->value = parsed->conditions[i].value;
84+
85+
// Simple type inference for the test
86+
if (parsed->conditions[i].is_numeric) {
87+
node->value_type = 0; // Integer/Number
88+
} else {
89+
node->value_type = 1; // String
90+
}
91+
node->sub = NULL;
8292
}
8393

84-
// TODO - Handle sub-expressions and nested conditions
85-
// Note: Nested conditions are not currently supported by the test
8694
node->next = NULL;
87-
node->sub = NULL;
8895

8996
// Set logical operator for the *previous* node to connect to this one
9097
// The parser stores logic ops between conditions. logic_ops[0] is between cond[0] and cond[1]
@@ -120,7 +127,7 @@ void run_test_query(struct engineS *engine, const char *query, int max_rows) {
120127
// Print query for testing
121128
printf("Executing Query: %s\n", query);
122129

123-
// Tokenize
130+
// Tokenize the provided query
124131
Token tokens[MAX_TOKENS];
125132
int num_tokens = tokenize(query, tokens, MAX_TOKENS);
126133
if (num_tokens <= 0) {
@@ -142,13 +149,15 @@ void run_test_query(struct engineS *engine, const char *query, int max_rows) {
142149
}
143150
}
144151

145-
// Handle non-SELECT commands here and return early
152+
// Execute based on command type
146153
switch (parsed.command) {
147154
case CMD_INSERT: {
148155
if (parsed.num_values != 12) {
149156
printf("Error: INSERT requires exactly 12 values.\n");
150157
return;
151158
}
159+
160+
// Assign arguments to a record struct
152161
record r;
153162
r.command_id = strtoull(parsed.insert_values[0], NULL, 10);
154163
safe_copy(r.raw_command, sizeof(r.raw_command), parsed.insert_values[1]);
@@ -166,30 +175,56 @@ void run_test_query(struct engineS *engine, const char *query, int max_rows) {
166175
safe_copy(r.host_name, sizeof(r.host_name), parsed.insert_values[10]);
167176
r.risk_level = atoi(parsed.insert_values[11]);
168177

178+
// Execute Insert
179+
clock_t insertStart = clock(); // Start timer for benchmarking
169180
if (executeQueryInsertSerial(engine, parsed.table, &r)) {
170-
printf("Insert successful.\n\n");
181+
printf("Insert successful. Execution Time: %ld\n\n", (clock() - insertStart) / CLOCKS_PER_SEC);
171182
} else {
172-
printf("Insert failed.\n\n");
183+
printf("Insert failed. Execution Time: %ld\n\n", (clock() - insertStart) / CLOCKS_PER_SEC);
173184
}
185+
174186
return;
175187
}
176188

177189
case CMD_DELETE: {
190+
// Get the WHERE clause from arguments
178191
struct whereClauseS *whereClause = convert_conditions(&parsed);
192+
193+
// Execute delete
194+
clock_t deleteStart = clock(); // Start timer for benchmarking
179195
struct resultSetS *result = executeQueryDeleteSerial(engine, parsed.table, whereClause);
196+
180197
if (result) {
181-
printf("Delete successful. Rows affected: %d\n", result->numRecords);
198+
printf("Delete successful. Rows affected: %d. Execution Time: %ld\n\n", result->numRecords, ((clock() - deleteStart) / CLOCKS_PER_SEC));
182199
freeResultSet(result);
183200
} else {
184-
printf("Delete failed.\n");
201+
printf("Delete failed. Execution Time: %ld\n\n", ((clock() - deleteStart) / CLOCKS_PER_SEC));
185202
}
203+
186204
free_where_clause_list(whereClause);
187205
return;
188206
}
189207

190208
case CMD_SELECT: {
191-
// Handled below
192-
break;
209+
// Get the WHERE clause from arguments
210+
struct whereClauseS *whereClause = convert_conditions(&parsed);
211+
212+
// Execute select
213+
struct resultSetS *result = executeQuerySelectSerial(
214+
engine,
215+
selectItems,
216+
numSelectItems,
217+
parsed.table,
218+
whereClause
219+
);
220+
221+
// Verify and Print)
222+
printTable(NULL, result, max_rows); // Limit to max_rows for testing
223+
224+
// Cleanup
225+
if (result) freeResultSet(result); // Free the results object
226+
free_where_clause_list(whereClause); // Free where clause linked list
227+
printf("\n");
193228
}
194229

195230
case CMD_NONE: {
@@ -198,28 +233,8 @@ void run_test_query(struct engineS *engine, const char *query, int max_rows) {
198233
}
199234

200235
default: {
201-
printf("Unsupported command.\n");
236+
fprintf(stderr, "Unsupported command.\n");
202237
return;
203238
}
204239
}
205-
206-
// Retreive the WHERE clause
207-
struct whereClauseS *whereClause = convert_conditions(&parsed);
208-
209-
// Execute
210-
struct resultSetS *result = executeQuerySelectSerial(
211-
engine,
212-
selectItems,
213-
numSelectItems,
214-
parsed.table,
215-
whereClause
216-
);
217-
218-
// Verify and Print
219-
printTable(NULL, result, max_rows);
220-
221-
// Cleanup
222-
if (result) freeResultSet(result); // Free the results object
223-
free_where_clause_list(whereClause); // Free where clause linked list
224-
printf("\n");
225240
}

data-generation/commands_50k.csv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:5ec8a5f1c992bd1c55dfdfa40e77473a388ff8bfe2e9e6bd872566293eee9a9d
3-
size 278
2+
oid sha256:e4239d07eb776e56fda0d3fa7757e702ee9b5c7f16d952ade9ee6b080c66f8ea
3+
size 267

engine/serial/executeEngine-serial.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,9 +357,14 @@ struct resultSetS *executeQuerySelectSerial(
357357
// Get all indexed attributes in the WHERE clause, using the B+ tree indexes where possible
358358
struct whereClauseS *wc = whereClause;
359359
while (wc != NULL) {
360+
// Skip nested conditions for index lookup (they don't have a direct attribute)
361+
if (wc->attribute == NULL) {
362+
wc = wc->next;
363+
continue;
364+
}
365+
360366
for (int i = 0; i < engine->num_indexes; i++) {
361367
if (strcmp(wc->attribute, engine->indexed_attributes[i]) == 0) {
362-
anyIndexExists = true;
363368
indexExists[i] = true;
364369

365370
// Use B+ tree index for this attribute
@@ -427,6 +432,8 @@ struct resultSetS *executeQuerySelectSerial(
427432
continue;
428433
}
429434

435+
anyIndexExists = true;
436+
430437
// Allocating for keys, using num_records as upper bound.
431438
KEY_T *returned_keys = malloc(engine->num_records * sizeof(KEY_T));
432439
ROW_PTR *returned_pointers = malloc(engine->num_records * sizeof(ROW_PTR));

include/sql.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,18 @@ typedef struct {
4444
char value[256]; // Increased size for long strings
4545
} Token;
4646

47+
typedef struct ParsedSQL ParsedSQL;
48+
4749
typedef struct {
4850
char column[64];
4951
OperatorType op;
5052
char value[256]; // Value to compare against
5153
bool is_numeric; // Whether the value is a number or string/bool
54+
bool is_nested;
55+
ParsedSQL *nested_sql;
5256
} Condition;
5357

54-
typedef struct {
58+
typedef struct ParsedSQL {
5559
CommandType command;
5660
char table[64];
5761
char columns[10][64]; // Up to 10 columns selected
@@ -77,6 +81,7 @@ int tokenize(const char *input, Token tokens[], int max_tokens);
7781

7882
// Parser
7983
ParsedSQL parse_tokens(Token tokens[]);
84+
void free_parsed_sql(ParsedSQL *sql);
8085

8186
// Dispatcher removed
8287

makefile

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,27 @@ test: $(TEST_BINS)
107107
@set -e; for t in $(TEST_BINS); do echo "==> $$t"; $$t || exit 1; done
108108
@echo "All tests completed."
109109

110-
# Run the main serial query processor
110+
# Run the serial version
111111
run: QPESeq
112112
./QPESeq
113113

114+
# Default OpenMP thread count unless overridden
115+
OMP_THREADS ?= 4
116+
117+
# Run OpenMP version correctly — env var applies only to this command
118+
run-omp: QPEOMP
119+
@echo "Running with OMP_NUM_THREADS=$(OMP_THREADS)"
120+
@env OMP_NUM_THREADS=$(OMP_THREADS) ./QPEOMP
121+
122+
# Default MPI process count unless overridden
123+
MPI_PROCS ?= 4
124+
125+
# Run MPI version with proper launcher syntax
126+
run-mpi: QPEMPI
127+
@echo "Running with $(MPI_PROCS) MPI processes..."
128+
@mpirun -np $(MPI_PROCS) ./QPEMPI 2>/dev/null \
129+
|| mpiexec -np $(MPI_PROCS) ./QPEMPI
130+
114131
# Run QPESeq under Valgrind to check for memory leaks
115132
valgrind: QPESeq
116133
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --error-exitcode=1 ./QPESeq

sample-queries.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,4 @@ WHERE sudo_used = TRUE OR (risk_level = 5 AND shell_type = "bash");
3636
# -- Sample 8:
3737
SELECT user_name, working_directory, base_command
3838
FROM Commands
39-
WHERE user_id = 1001 OR (user_name = "student1002" AND shell_type = "zsh");
39+
WHERE user_id = 1001 OR (user_name = "student1002" AND shell_type = "zsh");

0 commit comments

Comments
 (0)