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 package kestrel.catalog
import kestrel.KestrelException 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.Row
import kestrel.storage.Table import kestrel.storage.Table
import kestrel.storage.Value
class CatalogSnapshot( class CatalogSnapshot(
val tables: Map<String, Pair<TableSchema, List<Row>>>, 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 { class Catalog {
private val tables = linkedMapOf<String, Table>() private val tables = linkedMapOf<String, Table>()
private val indexes = linkedMapOf<String, SortedIndex>() 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) { fun createTable(schema: TableSchema) {
val key = schema.name.lowercase() val key = schema.name.lowercase()
if (tables.containsKey(key)) { if (tables.containsKey(key)) {
throw KestrelException("table '${schema.name}' already exists") throw KestrelException("table '${schema.name}' already exists")
} }
if (views.containsKey(key)) {
throw KestrelException("a view named '${schema.name}' already exists")
}
tables[key] = Table(schema) tables[key] = Table(schema)
} }
fun dropTable(tableName: String) { fun dropTable(tableName: String, cascade: Boolean = false) {
val key = tableName.lowercase() 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") 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) } 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 = fun table(tableName: String): Table =