@@ -237,7 +237,8 @@ def list_collections(self) -> List[str]:
237237 cur = conn .cursor ()
238238 cur .execute (
239239 "SELECT DISTINCT split_part(name, ':', 1) FROM nodes "
240- "WHERE valid_until = 0 LIMIT 100"
240+ "WHERE tenant_id = %s AND valid_until = 0 LIMIT 100" ,
241+ (self .tenant_id ,)
241242 )
242243 return [r [0 ] for r in cur .fetchall ()]
243244 finally :
@@ -248,8 +249,8 @@ def get_collection(self, name: str) -> Dict[str, Any]:
248249 try :
249250 cur = conn .cursor ()
250251 cur .execute (
251- "SELECT COUNT(*) FROM nodes WHERE name LIKE %s AND valid_until = 0" ,
252- (f"{ name } :%" , )
252+ "SELECT COUNT(*) FROM nodes WHERE tenant_id = %s AND name LIKE %s AND valid_until = 0" ,
253+ (self . tenant_id , f"{ name } :%" )
253254 )
254255 count = cur .fetchone ()[0 ]
255256 return {"name" : name , "count" : count }
@@ -264,7 +265,7 @@ def delete_collection(self, name: str) -> bool:
264265 conn = self ._conn ()
265266 try :
266267 cur = conn .cursor ()
267- cur .execute ("DELETE FROM nodes WHERE name LIKE %s" , (f"{ name } :%" , ))
268+ cur .execute ("DELETE FROM nodes WHERE tenant_id = %s AND name LIKE %s" , (self . tenant_id , f"{ name } :%" ))
268269 conn .commit ()
269270 return True
270271 finally :
@@ -396,9 +397,9 @@ def query_prefix(self, prefix: str, collection: str = None, limit: int = 100) ->
396397 cur = conn .cursor ()
397398 cur .execute (
398399 "SELECT id, name, data, metadata, valid_from, valid_until "
399- "FROM nodes WHERE name LIKE %s AND valid_until = 0 "
400+ "FROM nodes WHERE tenant_id = %s AND name LIKE %s AND valid_until = 0 "
400401 "ORDER BY valid_from DESC LIMIT %s" ,
401- (f"{ prefix } %" , limit )
402+ (self . tenant_id , f"{ prefix } %" , limit )
402403 )
403404 results = []
404405 for row in cur .fetchall ():
@@ -426,11 +427,11 @@ def get_point(self, collection: str, point_id: Union[int, str]) -> Dict[str, Any
426427 try :
427428 cur = conn .cursor ()
428429 if isinstance (point_id , int ):
429- cur .execute ("SELECT id, name, data, metadata FROM nodes WHERE id = %s" , (point_id , ))
430+ cur .execute ("SELECT id, name, data, metadata FROM nodes WHERE tenant_id = %s AND id = %s" , (self . tenant_id , point_id ))
430431 else :
431432 cur .execute (
432- "SELECT id, name, data, metadata FROM nodes WHERE name = %s AND valid_until = 0" ,
433- (str (point_id ), )
433+ "SELECT id, name, data, metadata FROM nodes WHERE tenant_id = %s AND name = %s AND valid_until = 0" ,
434+ (self . tenant_id , str (point_id ))
434435 )
435436 row = cur .fetchone ()
436437 if not row :
@@ -562,16 +563,16 @@ def semantic_search(self, query_embedding, collection: str = None, limit: int =
562563 FROM fact_embeddings fe
563564 LEFT JOIN nodes n ON n.tenant_id = fe.tenant_id
564565 AND n.name = fe.node_name AND n.valid_until = 0
565- WHERE fe.embedding IS NOT NULL
566+ WHERE fe.embedding IS NOT NULL AND fe.tenant_id = %s
566567 { prefix_filter }
567568 ORDER BY fe.embedding <=> %s::vector
568569 LIMIT %s
569570 """
570571 # Build params in correct SQL order: score_vec, [prefix], order_vec, limit
571572 if name_prefix :
572- params = [emb_str , name_prefix + "%" , emb_str , limit * 2 ]
573+ params = [emb_str , self . tenant_id , name_prefix + "%" , emb_str , limit * 2 ]
573574 else :
574- params = [emb_str , emb_str , limit * 2 ]
575+ params = [emb_str , self . tenant_id , emb_str , limit * 2 ]
575576 cur .execute (sql , params )
576577
577578 for row in cur .fetchall ():
@@ -606,16 +607,16 @@ def semantic_search(self, query_embedding, collection: str = None, limit: int =
606607 sql2 = f"""
607608 SELECT id, name, data, 1 - (embedding <=> %s::vector) AS score
608609 FROM nodes
609- WHERE embedding IS NOT NULL AND valid_until = 0
610+ WHERE embedding IS NOT NULL AND valid_until = 0 AND tenant_id = %s
610611 { prefix_cond }
611612 ORDER BY embedding <=> %s::vector
612613 LIMIT %s
613614 """
614615 # Build params in correct SQL order: score_vec, [prefix], order_vec, limit
615616 if name_prefix :
616- params2 = [emb_str , name_prefix + "%" , emb_str , remaining * 2 ]
617+ params2 = [emb_str , self . tenant_id , name_prefix + "%" , emb_str , remaining * 2 ]
617618 else :
618- params2 = [emb_str , emb_str , remaining * 2 ]
619+ params2 = [emb_str , self . tenant_id , emb_str , remaining * 2 ]
619620 cur .execute (sql2 , params2 )
620621
621622 for row in cur .fetchall ():
@@ -657,8 +658,8 @@ def get_history(self, name: str, collection: str = None) -> List[Dict[str, Any]]
657658 cur = conn .cursor ()
658659 cur .execute (
659660 "SELECT id, name, data, valid_from, valid_until "
660- "FROM nodes WHERE name = %s ORDER BY valid_from ASC" ,
661- (name , )
661+ "FROM nodes WHERE tenant_id = %s AND name = %s ORDER BY valid_from ASC" ,
662+ (self . tenant_id , name )
662663 )
663664 results = []
664665 for row in cur .fetchall ():
@@ -715,8 +716,8 @@ def query_entity(self, name: str, collection: str = None) -> Optional[Dict[str,
715716 cur = conn .cursor ()
716717 cur .execute (
717718 "SELECT id, name, entity_type, mention_count, first_seen, last_seen "
718- "FROM entities WHERE name = %s LIMIT 1" ,
719- (name , )
719+ "FROM entities WHERE tenant_id = %s AND name = %s LIMIT 1" ,
720+ (self . tenant_id , name )
720721 )
721722 row = cur .fetchone ()
722723 if not row :
@@ -733,8 +734,8 @@ def list_entities(self, collection: str = None, entity_type: str = None,
733734 conn = self ._conn ()
734735 try :
735736 cur = conn .cursor ()
736- sql = "SELECT id, name, entity_type, mention_count FROM entities WHERE 1=1 "
737- params = []
737+ sql = "SELECT id, name, entity_type, mention_count FROM entities WHERE tenant_id = %s "
738+ params = [self . tenant_id ]
738739 if entity_type :
739740 sql += " AND entity_type = %s"
740741 params .append (entity_type )
@@ -818,9 +819,9 @@ def delete_by_prefix_before(self, prefix: str, cutoff_timestamp: float,
818819 if only_superseded else ""
819820 )
820821 cur .execute (
821- "DELETE FROM nodes WHERE name LIKE %s AND valid_from < %s"
822+ "DELETE FROM nodes WHERE tenant_id = %s AND name LIKE %s AND valid_from < %s"
822823 + superseded_clause ,
823- (f"{ prefix } %" , cutoff_timestamp )
824+ (self . tenant_id , f"{ prefix } %" , cutoff_timestamp )
824825 )
825826 count = cur .rowcount
826827 conn .commit ()
@@ -845,11 +846,11 @@ def node_count(self, collection: str = None) -> int:
845846 cur = conn .cursor ()
846847 if collection :
847848 cur .execute (
848- "SELECT COUNT(*) FROM nodes WHERE name LIKE %s AND valid_until = 0" ,
849- (f"{ collection } :%" , )
849+ "SELECT COUNT(*) FROM nodes WHERE tenant_id = %s AND name LIKE %s AND valid_until = 0" ,
850+ (self . tenant_id , f"{ collection } :%" )
850851 )
851852 else :
852- cur .execute ("SELECT COUNT(*) FROM nodes WHERE valid_until = 0" )
853+ cur .execute ("SELECT COUNT(*) FROM nodes WHERE tenant_id = %s AND valid_until = 0" , ( self . tenant_id ,) )
853854 return cur .fetchone ()[0 ]
854855 finally :
855856 self ._release (conn )
0 commit comments