From 16db9bd1a29382a1bc556d1f31c1ef1c4352673d Mon Sep 17 00:00:00 2001
From: exterr2f <Robert.Externbrink@rub.de>
Date: Mon, 10 Mar 2025 08:15:42 +0100
Subject: [PATCH] Fix node filter: Use EXISTS with Eq for exact match and LIKE
 for Contains

---
 internal/repository/jobFind.go  | 4 ++--
 internal/repository/jobQuery.go | 9 ++++++++-
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/internal/repository/jobFind.go b/internal/repository/jobFind.go
index 0354df0..ea5e1e9 100644
--- a/internal/repository/jobFind.go
+++ b/internal/repository/jobFind.go
@@ -194,11 +194,11 @@ func (r *JobRepository) FindConcurrentJobs(
 
 	queryRunning := query.Where("job.job_state = ?").Where("(job.start_time BETWEEN ? AND ? OR job.start_time < ?)",
 		"running", startTimeTail, stopTimeTail, startTime)
-	queryRunning = queryRunning.Where("job.resources LIKE ?", fmt.Sprint("%", hostname, "%"))
+	queryRunning = queryRunning.Where("EXISTS (SELECT 1 FROM json_each(job.resources) WHERE json_extract(value, '$.hostname') = ?)", hostname)
 
 	query = query.Where("job.job_state != ?").Where("((job.start_time BETWEEN ? AND ?) OR (job.start_time + job.duration) BETWEEN ? AND ? OR (job.start_time < ?) AND (job.start_time + job.duration) > ?)",
 		"running", startTimeTail, stopTimeTail, startTimeFront, stopTimeTail, startTime, stopTime)
-	query = query.Where("job.resources LIKE ?", fmt.Sprint("%", hostname, "%"))
+	query = query.Where("EXISTS (SELECT 1 FROM json_each(job.resources) WHERE json_extract(value, '$.hostname') = ?)", hostname)
 
 	rows, err := query.RunWith(r.stmtCache).Query()
 	if err != nil {
diff --git a/internal/repository/jobQuery.go b/internal/repository/jobQuery.go
index b43b569..7d1d9eb 100644
--- a/internal/repository/jobQuery.go
+++ b/internal/repository/jobQuery.go
@@ -194,7 +194,14 @@ func BuildWhereClause(filter *model.JobFilter, query sq.SelectBuilder) sq.Select
 		query = buildIntCondition("job.num_hwthreads", filter.NumHWThreads, query)
 	}
 	if filter.Node != nil {
-		query = buildStringCondition("job.resources", filter.Node, query)
+		log.Infof("Applying node filter: %v", filter.Node)
+		if filter.Node.Eq != nil {
+			query = query.Where("EXISTS (SELECT 1 FROM json_each(job.resources) WHERE json_extract(value, '$.hostname') = ?)", *filter.Node.Eq)
+		} else if filter.Node.Contains != nil {
+			query = query.Where("EXISTS (SELECT 1 FROM json_each(job.resources) WHERE json_extract(value, '$.hostname') LIKE ?)", "%"+*filter.Node.Contains+"%")
+		} else {
+			query = buildStringCondition("job.resources", filter.Node, query)
+		}
 	}
 	if filter.Energy != nil {
 		query = buildFloatCondition("job.energy", filter.Energy, query)