@@ -812,18 +812,7 @@ extension CassandraClient {
812812 logger. debug ( " preparing: \( query) " )
813813 let future = self . underlying. prepare ( query: query)
814814 return future. asNIOFuture ( eventLoop: eventLoop) . flatMapThrowing { rawPointer in
815- let pkColumns : [ String ]
816- if let tableName = encryptionTable {
817- pkColumns = try self . lookupPrimaryKeyColumnNames ( tableName: tableName)
818- } else {
819- pkColumns = [ ]
820- }
821- let prepared = CassandraClient . PreparedStatement (
822- rawPointer: rawPointer,
823- encryptionTable: encryptionTable,
824- primaryKeyColumnNames: pkColumns
825- )
826- return prepared
815+ try self . makePreparedStatement ( rawPointer: rawPointer, encryptionTable: encryptionTable)
827816 }
828817 }
829818 }
@@ -892,6 +881,32 @@ extension CassandraClient {
892881 return names
893882 }
894883
884+ /// Builds a `PreparedStatement` taking ownership of `rawPointer`.
885+ ///
886+ /// If primary-key lookup throws, it does so before the `PreparedStatement` takes
887+ /// ownership of the prepared pointer, so we free it here to avoid leaking it.
888+ private func makePreparedStatement(
889+ rawPointer: OpaquePointer ,
890+ encryptionTable: String ?
891+ ) throws -> CassandraClient . PreparedStatement {
892+ let pkColumns : [ String ]
893+ if let tableName = encryptionTable {
894+ do {
895+ pkColumns = try self . lookupPrimaryKeyColumnNames ( tableName: tableName)
896+ } catch {
897+ cass_prepared_free ( rawPointer)
898+ throw error
899+ }
900+ } else {
901+ pkColumns = [ ]
902+ }
903+ return CassandraClient . PreparedStatement (
904+ rawPointer: rawPointer,
905+ encryptionTable: encryptionTable,
906+ primaryKeyColumnNames: pkColumns
907+ )
908+ }
909+
895910 /// Resolve encryption contexts for parameters that have `context: nil` using driver schema metadata.
896911 /// Discovers PK columns from Cassandra's metadata cache rather than requiring EncryptionSchema registration.
897912 @available ( macOS 15 . 0 , iOS 18 . 0 , visionOS 2 . 0 , * )
@@ -1428,17 +1443,7 @@ extension CassandraClient.Session {
14281443 logger. debug ( " preparing: \( query) " )
14291444 return try await self . underlying. prepare ( query: query) . await ( )
14301445 }
1431- let pkColumns : [ String ]
1432- if let tableName = encryptionTable {
1433- pkColumns = try self . lookupPrimaryKeyColumnNames ( tableName: tableName)
1434- } else {
1435- pkColumns = [ ]
1436- }
1437- return CassandraClient . PreparedStatement (
1438- rawPointer: preparedRawPointer,
1439- encryptionTable: encryptionTable,
1440- primaryKeyColumnNames: pkColumns
1441- )
1446+ return try self . makePreparedStatement ( rawPointer: preparedRawPointer, encryptionTable: encryptionTable)
14421447 }
14431448
14441449 @available ( macOS 12 , iOS 15 , tvOS 15 , watchOS 8 , * )
0 commit comments