Skip to content

Add OR statement to match V1 and V2 Scheduler BusinessIds#10248

Merged
awln-temporal merged 6 commits into
mainfrom
awln/scheduler-visibility-fix
May 15, 2026
Merged

Add OR statement to match V1 and V2 Scheduler BusinessIds#10248
awln-temporal merged 6 commits into
mainfrom
awln/scheduler-visibility-fix

Conversation

@awln-temporal
Copy link
Copy Markdown
Contributor

@awln-temporal awln-temporal commented May 13, 2026

What changed?

Add a Scheduler specific query converter to handle ScheduleId search attribute alias to underlying WorkflowId system search attribute field. If chasm is enabled, the query converter will match against both V1 and V2 Scheduler workflowId formats. V1 prefixes the workflowId with temporal-sys-scheduler, while V2 doesn't, so to handle either case, we need to add a OR/AND statement to match both V1 and V2 Scheduler BusinessId. OR will be used if the operator's boolean is positive, AND if the operator's boolean is negative.

Why?

Unable to retrieve V2 Schedules that query using ScheduleId as a search attribute.

How did you test it?

  • built
  • run locally and tested manually
  • covered by existing tests
  • added new unit test(s)
  • added new functional test(s)

@awln-temporal awln-temporal requested review from a team as code owners May 13, 2026 17:54
@awln-temporal awln-temporal force-pushed the awln/scheduler-visibility-fix branch from 1b0fed5 to 07767a4 Compare May 13, 2026 18:34
@awln-temporal awln-temporal added the test-all-dbs Request PR checks to test all databases label May 13, 2026
@awln-temporal awln-temporal force-pushed the awln/scheduler-visibility-fix branch from 07767a4 to 2294a95 Compare May 13, 2026 20:24
@awln-temporal awln-temporal force-pushed the awln/scheduler-visibility-fix branch from 2294a95 to e1d0bb7 Compare May 13, 2026 22:40
// This block runs after the STARTS_WITH → LIKE conversion above so the V1 clone inherits the
// already-converted operator and escape settings.
// TODO: once V1 schedules are fully migrated to CHASM, remove this OR/AND block and only use V2 (unprefixed) values.
if saColNameExpr.alias == sadefs.ScheduleID && c.archetypeID == chasm.SchedulerArchetypeID {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Missing fieldName guard — the generic converter (converter.go:399) and ES legacy converter (converter_legacy.go:319) both check colName.FieldName == sadefs.WorkflowID here, but this condition only checks the alias. If a user defines a custom ScheduleId search attribute (which would map to a different field name), this block would still fire and incorrectly inject the V1 prefix OR/AND logic.

Suggested change
if saColNameExpr.alias == sadefs.ScheduleID && c.archetypeID == chasm.SchedulerArchetypeID {
if saColNameExpr.alias == sadefs.ScheduleID && saColNameExpr.fieldName == sadefs.WorkflowID && c.archetypeID == chasm.SchedulerArchetypeID {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not super familiar with this portion of the codebase.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah this is correct, just need to verify the field name, thanks

Comment thread tests/schedule_test.go
}, 15*time.Second, 1*time.Second)
}

func testListSchedulesFilterByScheduleID(t *testing.T, newContext contextFactory) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this set test only checks v1 xor v2. could you add one that has results for both?


{
name: "CHASM path IN generates OR of prefixed and unprefixed",
in: "ScheduleId IN ('foo', 'bar')",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

starts with?

Copy link
Copy Markdown
Contributor

@lina-temporal lina-temporal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

few small comments, otherwise LGTM; would appreciate a stamp from visi/foundations as well, though.

Comment thread tests/schedule_test.go Outdated
})

// Not equal: ScheduleId != 'sid1' should return sid2 but not sid1.
t.Run("NotEqual", func(t *testing.T) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also add the Len assertions on the cases with 2 schedules returned? This will guard against something in the handler returning duplicate results.

Comment on lines +491 to +493
if comparisonExpr.Operator == sqlparser.NotEqualStr ||
comparisonExpr.Operator == sqlparser.NotInStr ||
comparisonExpr.Operator == sqlparser.NotStartsWithStr {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(minor) Can you reuse isNegativeScheduleIDOperator here?

Comment on lines +409 to +411
isNegative := expr.Operator == sqlparser.NotEqualStr ||
expr.Operator == sqlparser.NotInStr ||
expr.Operator == sqlparser.NotLikeStr
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(minor) Ditto for reusing isNegativeScheduleIDOperator here

@awln-temporal awln-temporal force-pushed the awln/scheduler-visibility-fix branch 2 times, most recently from 0922434 to 3e13a0f Compare May 14, 2026 20:15
@awln-temporal awln-temporal force-pushed the awln/scheduler-visibility-fix branch from 3e13a0f to 254bea8 Compare May 14, 2026 20:22
Comment thread service/worker/scheduler/schedule_id_query_rewriter_test.go
Comment thread service/worker/scheduler/schedule_id_query_rewriter.go
Comment thread service/worker/scheduler/schedule_id_query_rewriter.go Outdated
Comment thread common/persistence/visibility/store/query/converter_test.go Outdated
@awln-temporal awln-temporal force-pushed the awln/scheduler-visibility-fix branch from a4ad61e to 6c25432 Compare May 15, 2026 15:31
@awln-temporal awln-temporal force-pushed the awln/scheduler-visibility-fix branch from 6c25432 to 7512038 Compare May 15, 2026 16:02
@awln-temporal awln-temporal requested a review from rodrigozhou May 15, 2026 19:54
@awln-temporal awln-temporal dismissed rodrigozhou’s stale review May 15, 2026 21:06

review is complete, pending discussion has been done offline

@awln-temporal awln-temporal merged commit 18ad878 into main May 15, 2026
71 checks passed
@awln-temporal awln-temporal deleted the awln/scheduler-visibility-fix branch May 15, 2026 22:35
yycptt pushed a commit that referenced this pull request May 18, 2026
…10316)

## What changed?
Add a Scheduler specific query converter to handle ScheduleId search
attribute alias to underlying WorkflowId system search attribute field.
If chasm is enabled, the query converter will match against both V1 and
V2 Scheduler workflowId formats. V1 prefixes the workflowId with
temporal-sys-scheduler, while V2 doesn't, so to handle either case, we
need to add a OR/AND statement to match both V1 and V2 Scheduler
BusinessId. OR will be used if the operator's boolean is positive, AND
if the operator's boolean is negative.

## Why?
Unable to retrieve V2 Schedules that query using ScheduleId as a search
attribute.

## How did you test it?
- [X] built
- [X] run locally and tested manually
- [X] covered by existing tests
- [X] added new unit test(s)
- [X] added new functional test(s)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test-all-dbs Request PR checks to test all databases

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants