@@ -1649,7 +1649,7 @@ static void vec_slice(sqlite3_context *context, int argc,
16491649 i8 * out = sqlite3_malloc (outSize );
16501650 if (!out ) {
16511651 sqlite3_result_error_nomem (context );
1652- return ;
1652+ goto done ;
16531653 }
16541654 memset (out , 0 , outSize );
16551655 for (size_t i = 0 ; i < n ; i ++ ) {
@@ -1672,7 +1672,7 @@ static void vec_slice(sqlite3_context *context, int argc,
16721672 u8 * out = sqlite3_malloc (outSize );
16731673 if (!out ) {
16741674 sqlite3_result_error_nomem (context );
1675- return ;
1675+ goto done ;
16761676 }
16771677 memset (out , 0 , outSize );
16781678 for (size_t i = 0 ; i < n / CHAR_BIT ; i ++ ) {
@@ -2535,6 +2535,7 @@ static int vec_eachFilter(sqlite3_vtab_cursor *pVtabCursor, int idxNum,
25352535 int rc = vector_from_value (argv [0 ], & pCur -> vector , & pCur -> dimensions ,
25362536 & pCur -> vector_type , & pCur -> cleanup , & pzErrMsg );
25372537 if (rc != SQLITE_OK ) {
2538+ sqlite3_free (pzErrMsg );
25382539 return SQLITE_ERROR ;
25392540 }
25402541 pCur -> iRowid = 0 ;
@@ -3616,6 +3617,24 @@ void vec0_free(vec0_vtab *p) {
36163617 sqlite3_free (p -> vector_columns [i ].name );
36173618 p -> vector_columns [i ].name = NULL ;
36183619 }
3620+
3621+ for (int i = 0 ; i < p -> numPartitionColumns ; i ++ ) {
3622+ sqlite3_free (p -> paritition_columns [i ].name );
3623+ p -> paritition_columns [i ].name = NULL ;
3624+ }
3625+
3626+ for (int i = 0 ; i < p -> numAuxiliaryColumns ; i ++ ) {
3627+ sqlite3_free (p -> auxiliary_columns [i ].name );
3628+ p -> auxiliary_columns [i ].name = NULL ;
3629+ }
3630+
3631+ for (int i = 0 ; i < p -> numMetadataColumns ; i ++ ) {
3632+ sqlite3_free (p -> shadowMetadataChunksNames [i ]);
3633+ p -> shadowMetadataChunksNames [i ] = NULL ;
3634+
3635+ sqlite3_free (p -> metadata_columns [i ].name );
3636+ p -> metadata_columns [i ].name = NULL ;
3637+ }
36193638}
36203639
36213640int vec0_num_defined_user_columns (vec0_vtab * p ) {
@@ -5143,6 +5162,7 @@ static int vec0_init(sqlite3 *db, void *pAux, int argc, const char *const *argv,
51435162 goto error ;
51445163 }
51455164 rc = sqlite3_prepare_v2 (db , zSql , -1 , & stmt , NULL );
5165+ sqlite3_free (zSql );
51465166 if ((rc != SQLITE_OK ) || (sqlite3_step (stmt ) != SQLITE_DONE )) {
51475167 sqlite3_finalize (stmt );
51485168 * pzErr = sqlite3_mprintf (
@@ -5160,6 +5180,7 @@ static int vec0_init(sqlite3 *db, void *pAux, int argc, const char *const *argv,
51605180
51615181error :
51625182 vec0_free (pNew );
5183+ sqlite3_free (pNew );
51635184 return SQLITE_ERROR ;
51645185}
51655186
@@ -6074,6 +6095,7 @@ int vec0_metadata_filter_text(vec0_vtab * p, sqlite3_value * value, const void *
60746095 rc = sqlite3_blob_read (rowidsBlob , rowids , sqlite3_blob_bytes (rowidsBlob ), 0 );
60756096 if (rc != SQLITE_OK ) {
60766097 sqlite3_blob_close (rowidsBlob );
6098+ sqlite3_free (rowids );
60776099 return rc ;
60786100 }
60796101 sqlite3_blob_close (rowidsBlob );
@@ -7114,12 +7136,14 @@ int vec0Filter_knn(vec0_cursor *pCur, vec0_vtab *p, int idxNum,
71147136 i64 v = sqlite3_value_int64 (entry );
71157137 rc = array_append (& item .array , & v );
71167138 if (rc != SQLITE_OK ) {
7139+ array_cleanup (& item .array );
71177140 goto cleanup ;
71187141 }
71197142 }
71207143
71217144 if (rc != SQLITE_DONE ) {
71227145 vtab_set_error (& p -> base , "Error fetching next value in `x in (...)` integer expression" );
7146+ array_cleanup (& item .array );
71237147 goto cleanup ;
71247148 }
71257149
@@ -7139,17 +7163,33 @@ int vec0Filter_knn(vec0_cursor *pCur, vec0_vtab *p, int idxNum,
71397163 entry .zString = sqlite3_mprintf ("%.*s" , n , s );
71407164 if (!entry .zString ) {
71417165 rc = SQLITE_NOMEM ;
7166+ // Clean up already-added text entries
7167+ for (size_t j = 0 ; j < item .array .length ; j ++ ) {
7168+ sqlite3_free (((struct Vec0MetadataInTextEntry * )item .array .z )[j ].zString );
7169+ }
7170+ array_cleanup (& item .array );
71427171 goto cleanup ;
71437172 }
71447173 entry .n = n ;
71457174 rc = array_append (& item .array , & entry );
71467175 if (rc != SQLITE_OK ) {
7176+ sqlite3_free (entry .zString );
7177+ // Clean up already-added text entries
7178+ for (size_t j = 0 ; j < item .array .length ; j ++ ) {
7179+ sqlite3_free (((struct Vec0MetadataInTextEntry * )item .array .z )[j ].zString );
7180+ }
7181+ array_cleanup (& item .array );
71477182 goto cleanup ;
71487183 }
71497184 }
71507185
71517186 if (rc != SQLITE_DONE ) {
71527187 vtab_set_error (& p -> base , "Error fetching next value in `x in (...)` text expression" );
7188+ // Clean up text entries
7189+ for (size_t j = 0 ; j < item .array .length ; j ++ ) {
7190+ sqlite3_free (((struct Vec0MetadataInTextEntry * )item .array .z )[j ].zString );
7191+ }
7192+ array_cleanup (& item .array );
71537193 goto cleanup ;
71547194 }
71557195
@@ -7163,6 +7203,13 @@ int vec0Filter_knn(vec0_cursor *pCur, vec0_vtab *p, int idxNum,
71637203
71647204 rc = array_append (aMetadataIn , & item );
71657205 if (rc != SQLITE_OK ) {
7206+ // Clean up item.array since it wasn't added to aMetadataIn
7207+ if (p -> metadata_columns [item .metadata_idx ].kind == VEC0_METADATA_COLUMN_KIND_TEXT ) {
7208+ for (size_t j = 0 ; j < item .array .length ; j ++ ) {
7209+ sqlite3_free (((struct Vec0MetadataInTextEntry * )item .array .z )[j ].zString );
7210+ }
7211+ }
7212+ array_cleanup (& item .array );
71667213 goto cleanup ;
71677214 }
71687215 }
@@ -7217,6 +7264,12 @@ int vec0Filter_knn(vec0_cursor *pCur, vec0_vtab *p, int idxNum,
72177264
72187265 sqlite3_free (aMetadataIn );
72197266
7267+ // Free knn_data if not assigned to cursor (error case)
7268+ if (rc != SQLITE_OK && knn_data ) {
7269+ vec0_query_knn_data_clear (knn_data );
7270+ sqlite3_free (knn_data );
7271+ }
7272+
72207273 return rc ;
72217274}
72227275
@@ -8190,6 +8243,7 @@ int vec0_write_metadata_value(vec0_vtab *p, int metadata_column_idx, i64 rowid,
81908243 }
81918244 sqlite3_stmt * stmt ;
81928245 rc = sqlite3_prepare_v2 (p -> db , zSql , -1 , & stmt , NULL );
8246+ sqlite3_free ((void * )zSql );
81938247 if (rc != SQLITE_OK ) {
81948248 goto done ;
81958249 }
@@ -8211,6 +8265,7 @@ int vec0_write_metadata_value(vec0_vtab *p, int metadata_column_idx, i64 rowid,
82118265 }
82128266 sqlite3_stmt * stmt ;
82138267 rc = sqlite3_prepare_v2 (p -> db , zSql , -1 , & stmt , NULL );
8268+ sqlite3_free ((void * )zSql );
82148269 if (rc != SQLITE_OK ) {
82158270 goto done ;
82168271 }
@@ -8409,6 +8464,7 @@ int vec0Update_Insert(sqlite3_vtab *pVTab, int argc, sqlite3_value **argv,
84098464 goto cleanup ;
84108465 }
84118466 rc = sqlite3_prepare_v2 (p -> db , zSql , -1 , & stmt , NULL );
8467+ sqlite3_free (zSql );
84128468 if (rc != SQLITE_OK ) {
84138469 goto cleanup ;
84148470 }
@@ -8651,12 +8707,14 @@ int vec0Update_Delete_ClearMetadata(vec0_vtab *p, int metadata_idx, i64 rowid, i
86518707 }
86528708 sqlite3_stmt * stmt ;
86538709 rc = sqlite3_prepare_v2 (p -> db , zSql , -1 , & stmt , NULL );
8710+ sqlite3_free ((void * )zSql );
86548711 if (rc != SQLITE_OK ) {
86558712 goto done ;
86568713 }
86578714 sqlite3_bind_int64 (stmt , 1 , rowid );
86588715 rc = sqlite3_step (stmt );
86598716 if (rc != SQLITE_DONE ) {
8717+ sqlite3_finalize (stmt );
86608718 rc = SQLITE_ERROR ;
86618719 goto done ;
86628720 }
@@ -8743,6 +8801,7 @@ int vec0Update_UpdateAuxColumn(vec0_vtab *p, int auxiliary_column_idx, sqlite3_v
87438801 return SQLITE_NOMEM ;
87448802 }
87458803 rc = sqlite3_prepare_v2 (p -> db , zSql , -1 , & stmt , NULL );
8804+ sqlite3_free ((void * )zSql );
87468805 if (rc != SQLITE_OK ) {
87478806 return rc ;
87488807 }
@@ -9529,52 +9588,67 @@ static int vec_static_blob_entriesFilter(sqlite3_vtab_cursor *pVtabCursor,
95299588 if (idxNum == VEC_SBE__QUERYPLAN_KNN ) {
95309589 assert (argc == 2 );
95319590 pCur -> query_plan = VEC_SBE__QUERYPLAN_KNN ;
9532- struct sbe_query_knn_data * knn_data ;
9591+ struct sbe_query_knn_data * knn_data = NULL ;
9592+ void * queryVector = NULL ;
9593+ vector_cleanup cleanup = vector_cleanup_noop ;
9594+ i32 * topk_rowids = NULL ;
9595+ f32 * distances = NULL ;
9596+ u8 * candidates = NULL ;
9597+ u8 * taken = NULL ;
9598+ int rc = SQLITE_OK ;
9599+
95339600 knn_data = sqlite3_malloc (sizeof (* knn_data ));
95349601 if (!knn_data ) {
9535- return SQLITE_NOMEM ;
9602+ rc = SQLITE_NOMEM ;
9603+ goto knn_cleanup ;
95369604 }
95379605 memset (knn_data , 0 , sizeof (* knn_data ));
95389606
9539- void * queryVector ;
95409607 size_t dimensions ;
95419608 enum VectorElementType elementType ;
9542- vector_cleanup cleanup ;
95439609 char * err ;
9544- int rc = vector_from_value (argv [0 ], & queryVector , & dimensions , & elementType ,
9610+ rc = vector_from_value (argv [0 ], & queryVector , & dimensions , & elementType ,
95459611 & cleanup , & err );
95469612 if (rc != SQLITE_OK ) {
9547- return SQLITE_ERROR ;
9613+ sqlite3_free (err );
9614+ rc = SQLITE_ERROR ;
9615+ goto knn_cleanup ;
95489616 }
95499617 if (elementType != p -> blob -> element_type ) {
9550- return SQLITE_ERROR ;
9618+ rc = SQLITE_ERROR ;
9619+ goto knn_cleanup ;
95519620 }
95529621 if (dimensions != p -> blob -> dimensions ) {
9553- return SQLITE_ERROR ;
9622+ rc = SQLITE_ERROR ;
9623+ goto knn_cleanup ;
95549624 }
95559625
95569626 i64 k = min (sqlite3_value_int64 (argv [1 ]), (i64 )p -> blob -> nvectors );
95579627 if (k < 0 ) {
95589628 // HANDLE https://github.com/asg017/sqlite-vec/issues/55
9559- return SQLITE_ERROR ;
9629+ rc = SQLITE_ERROR ;
9630+ goto knn_cleanup ;
95609631 }
95619632 if (k == 0 ) {
95629633 knn_data -> k = 0 ;
95639634 pCur -> knn_data = knn_data ;
9635+ cleanup (queryVector );
95649636 return SQLITE_OK ;
95659637 }
95669638
95679639 size_t bsize = (p -> blob -> nvectors + 7 ) & ~7 ;
95689640
9569- i32 * topk_rowids = sqlite3_malloc (k * sizeof (i32 ));
9641+ topk_rowids = sqlite3_malloc (k * sizeof (i32 ));
95709642 if (!topk_rowids ) {
95719643 // HANDLE https://github.com/asg017/sqlite-vec/issues/55
9572- return SQLITE_ERROR ;
9644+ rc = SQLITE_ERROR ;
9645+ goto knn_cleanup ;
95739646 }
9574- f32 * distances = sqlite3_malloc (bsize * sizeof (f32 ));
9647+ distances = sqlite3_malloc (bsize * sizeof (f32 ));
95759648 if (!distances ) {
95769649 // HANDLE https://github.com/asg017/sqlite-vec/issues/55
9577- return SQLITE_ERROR ;
9650+ rc = SQLITE_ERROR ;
9651+ goto knn_cleanup ;
95789652 }
95799653
95809654 for (size_t i = 0 ; i < p -> blob -> nvectors ; i ++ ) {
@@ -9583,11 +9657,17 @@ static int vec_static_blob_entriesFilter(sqlite3_vtab_cursor *pVtabCursor,
95839657 distances [i ] =
95849658 distance_l2_sqr_float (v , (float * )queryVector , & p -> blob -> dimensions );
95859659 }
9586- u8 * candidates = bitmap_new (bsize );
9587- assert (candidates );
9660+ candidates = bitmap_new (bsize );
9661+ if (!candidates ) {
9662+ rc = SQLITE_NOMEM ;
9663+ goto knn_cleanup ;
9664+ }
95889665
9589- u8 * taken = bitmap_new (bsize );
9590- assert (taken );
9666+ taken = bitmap_new (bsize );
9667+ if (!taken ) {
9668+ rc = SQLITE_NOMEM ;
9669+ goto knn_cleanup ;
9670+ }
95919671
95929672 bitmap_fill (candidates , bsize );
95939673 for (size_t i = bsize ; i >= p -> blob -> nvectors ; i -- ) {
@@ -9601,6 +9681,21 @@ static int vec_static_blob_entriesFilter(sqlite3_vtab_cursor *pVtabCursor,
96019681 knn_data -> rowids = topk_rowids ;
96029682
96039683 pCur -> knn_data = knn_data ;
9684+
9685+ // Cleanup temporary allocations (not owned by knn_data)
9686+ sqlite3_free (candidates );
9687+ sqlite3_free (taken );
9688+ cleanup (queryVector );
9689+ return SQLITE_OK ;
9690+
9691+ knn_cleanup :
9692+ sqlite3_free (knn_data );
9693+ sqlite3_free (topk_rowids );
9694+ sqlite3_free (distances );
9695+ sqlite3_free (candidates );
9696+ sqlite3_free (taken );
9697+ cleanup (queryVector );
9698+ return rc ;
96049699 } else {
96059700 pCur -> query_plan = VEC_SBE__QUERYPLAN_FULLSCAN ;
96069701 pCur -> iRowid = 0 ;
0 commit comments