To implement the DeleteExecutor, the physical operator for handling DELETE FROM ... SQL statements. This completes the set of basic Data Manipulation Language (DML) executors for single-table operations.
The DeleteExecutor follows the Volcano Model and is designed as a "sink" operator. It sits at the top of a pipeline and consumes all tuples from its child executor without producing them as output.
The plan for a simple DELETE FROM table; is:
SeqScanExecutor -> DeleteExecutor
The SeqScanExecutor's role is to provide a stream of all tuples in the table. The DeleteExecutor's next() method iterates through this entire stream, performing a delete operation for each tuple it receives.
A critical design challenge emerged during implementation: to delete a tuple, the HeapFile needs its physical address (TupleID). However, the Tuple objects produced by the SeqScanExecutor were previously unaware of their own location.
To solve this, the Tuple class was enhanced to carry its own TupleID.
- A
TupleIDfield was added to theTupleclass. - The
HeapFileIteratorwas modified to be the "origin point" of this metadata. As it materializes aTuplefrom the raw bytes on a page, it now "stamps" the tuple with its corresponding(pageId, slotId).
This "just-in-time" metadata enrichment is a clean and efficient design. The TupleID is not stored on disk; it's attached to the in-memory tuple object at the moment it's read. Any downstream executor that requires this physical address (like DeleteExecutor) can now access it.
The DeleteExecutor.next() method is designed to run once. It pulls all tuples from its child, calls table.deleteTuple(tid) for each one, and keeps a running count. Finally, it returns a single result tuple containing the total number of rows that were deleted.
The accompanying test verifies this entire process, first by checking the returned count and then by running a new SeqScan to confirm that the table is indeed empty.
With Projection, Filter, Insert, and Delete executors now complete, the final piece of Phase 3 is to build a simple Query Planner. This component will be responsible for taking the Abstract Syntax Tree (AST) produced by the ANTLR parser and automatically constructing the correct tree of executors, bridging the gap between SQL strings and our execution engine.