From 613bf22cbd510256eb25927f397f4d4e0d487bb8 Mon Sep 17 00:00:00 2001 From: Hein Date: Wed, 11 Mar 2026 14:25:44 +0200 Subject: [PATCH] fix(cursor): use full schema-qualified table name in filters --- pkg/resolvespec/cursor.go | 5 +++-- pkg/resolvespec/cursor_test.go | 6 +++--- pkg/restheadspec/cursor.go | 4 +++- pkg/restheadspec/cursor_test.go | 6 +++--- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/pkg/resolvespec/cursor.go b/pkg/resolvespec/cursor.go index e17ec2c..58f7df9 100644 --- a/pkg/resolvespec/cursor.go +++ b/pkg/resolvespec/cursor.go @@ -32,7 +32,8 @@ func GetCursorFilter( modelColumns []string, options common.RequestOptions, ) (string, error) { - // Remove schema prefix if present + // Separate schema prefix from bare table name + fullTableName := tableName if strings.Contains(tableName, ".") { tableName = strings.SplitN(tableName, ".", 2)[1] } @@ -115,7 +116,7 @@ func GetCursorFilter( WHERE cursor_select.%s = %s AND (%s) )`, - tableName, + fullTableName, pkName, cursorID, orSQL, diff --git a/pkg/resolvespec/cursor_test.go b/pkg/resolvespec/cursor_test.go index 8c2b11d..0b7b1fc 100644 --- a/pkg/resolvespec/cursor_test.go +++ b/pkg/resolvespec/cursor_test.go @@ -175,9 +175,9 @@ func TestGetCursorFilter_WithSchemaPrefix(t *testing.T) { t.Fatalf("GetCursorFilter failed: %v", err) } - // Should handle schema prefix properly - if !strings.Contains(filter, "users") { - t.Errorf("Filter should reference table name users, got: %s", filter) + // Should include full schema-qualified name in FROM clause + if !strings.Contains(filter, "public.users") { + t.Errorf("Filter FROM clause should use schema-qualified name public.users, got: %s", filter) } t.Logf("Generated cursor filter with schema: %s", filter) diff --git a/pkg/restheadspec/cursor.go b/pkg/restheadspec/cursor.go index dd31607..b060a5b 100644 --- a/pkg/restheadspec/cursor.go +++ b/pkg/restheadspec/cursor.go @@ -32,6 +32,8 @@ func (opts *ExtendedRequestOptions) GetCursorFilter( modelColumns []string, // optional: for validation expandJoins map[string]string, // optional: alias → JOIN SQL ) (string, error) { + // Separate schema prefix from bare table name + fullTableName := tableName if strings.Contains(tableName, ".") { tableName = strings.SplitN(tableName, ".", 2)[1] } @@ -127,7 +129,7 @@ func (opts *ExtendedRequestOptions) GetCursorFilter( WHERE cursor_select.%s = %s AND (%s) )`, - tableName, + fullTableName, joinSQL, pkName, cursorID, diff --git a/pkg/restheadspec/cursor_test.go b/pkg/restheadspec/cursor_test.go index 8880a50..a9de870 100644 --- a/pkg/restheadspec/cursor_test.go +++ b/pkg/restheadspec/cursor_test.go @@ -187,9 +187,9 @@ func TestGetCursorFilter_WithSchemaPrefix(t *testing.T) { t.Fatalf("GetCursorFilter failed: %v", err) } - // Should handle schema prefix properly - if !strings.Contains(filter, "users") { - t.Errorf("Filter should reference table name users, got: %s", filter) + // Should include full schema-qualified name in FROM clause + if !strings.Contains(filter, "public.users") { + t.Errorf("Filter FROM clause should use schema-qualified name public.users, got: %s", filter) } t.Logf("Generated cursor filter with schema: %s", filter)