feat(catalog): extend Catalog with dropTable

This commit is contained in:
dualfroz committed 2026-09-01 12:14:08 +02:00
1 parent a034a59f95
commit 4801fc424e
1 file changed
+32 -3
+32 -3
View File
@@ -1,32 +1,61 @@
package kestrel.catalog
import kestrel.KestrelException
import kestrel.sql.ast.NextValueExpression
import kestrel.sql.ast.QueryStatement
import kestrel.sql.ast.TriggerEvent
import kestrel.sql.ast.TriggerTiming
import kestrel.storage.Collation
import kestrel.storage.Row
import kestrel.storage.Table
import kestrel.storage.Value
class CatalogSnapshot(
val tables: Map<String, Pair<TableSchema, List<Row>>>,
val indexDefinitions: List<IndexDefinition>
val indexDefinitions: List<IndexDefinition>,
val views: Map<String, ViewDefinition>,
val triggers: Map<String, TriggerDefinition>,
/**
* A reference copy of the map, not a deep copy of each [Sequence] - see [Sequence]'s own doc
* for why that is exactly what makes ROLLBACK undo CREATE/DROP/ALTER SEQUENCE while leaving a
* NEXTVAL advance in place.
*/
val sequences: Map<String, Sequence>
)
class Catalog {
private val tables = linkedMapOf<String, Table>()
private val indexes = linkedMapOf<String, SortedIndex>()
private val views = linkedMapOf<String, ViewDefinition>()
private val triggers = linkedMapOf<String, TriggerDefinition>()
private val sequences = linkedMapOf<String, Sequence>()
fun createTable(schema: TableSchema) {
val key = schema.name.lowercase()
if (tables.containsKey(key)) {
throw KestrelException("table '${schema.name}' already exists")
}
if (views.containsKey(key)) {
throw KestrelException("a view named '${schema.name}' already exists")
}
tables[key] = Table(schema)
}
fun dropTable(tableName: String) {
fun dropTable(tableName: String, cascade: Boolean = false) {
val key = tableName.lowercase()
if (tables.remove(key) == null) {
if (!tables.containsKey(key)) {
if (views.containsKey(key)) {
throw KestrelException("'$tableName' is a view, use DROP VIEW")
}
throw KestrelException("no such table: $tableName")
}
dropDependentViews(tableName, cascade)
dropDependentForeignKeys(tableName, cascade)
tables.remove(key)
indexes.entries.removeAll { it.value.definition.tableName.equals(tableName, ignoreCase = true) }
// A trigger without its table makes no sense to keep around - unlike a FOREIGN KEY
// reference, nothing else depends on it existing, so this always happens, CASCADE or not.
triggers.entries.removeAll { it.value.tableName.equals(tableName, ignoreCase = true) }
}
fun table(tableName: String): Table =