temporalio/temporal · error

only comparison and "and" expression is supported

Error message

only comparison and "and" expression is supported

What it means

The archival query dialect supports only simple comparisons combined with AND (and parentheses for grouping). convertWhereExpr's default branch fires for any other expression node — OR, NOT, LIKE, IN, arithmetic, function calls, etc. — and rejects it.

Source

Thrown at common/archiver/s3store/query_parser.go:97

		return nil, errors.New("SearchPrecision requires a StartTime or CloseTime")
	}
	return parsedQuery, nil
}

func (p *queryParser) convertWhereExpr(expr sqlparser.Expr, parsedQuery *parsedQuery) error {
	if expr == nil {
		return errors.New("where expression is nil")
	}

	switch expr := expr.(type) {
	case *sqlparser.ComparisonExpr:
		return p.convertComparisonExpr(expr, parsedQuery)
	case *sqlparser.AndExpr:
		return p.convertAndExpr(expr, parsedQuery)
	case *sqlparser.ParenExpr:
		return p.convertParenExpr(expr, parsedQuery)
	default:
		return errors.New("only comparison and \"and\" expression is supported")
	}
}

func (p *queryParser) convertParenExpr(parenExpr *sqlparser.ParenExpr, parsedQuery *parsedQuery) error {
	return p.convertWhereExpr(parenExpr.Expr, parsedQuery)
}

func (p *queryParser) convertAndExpr(andExpr *sqlparser.AndExpr, parsedQuery *parsedQuery) error {
	if err := p.convertWhereExpr(andExpr.Left, parsedQuery); err != nil {
		return err
	}
	return p.convertWhereExpr(andExpr.Right, parsedQuery)
}

func (p *queryParser) convertComparisonExpr(compExpr *sqlparser.ComparisonExpr, parsedQuery *parsedQuery) error {
	colName, ok := compExpr.Left.(*sqlparser.ColName)
	if !ok {
		return fmt.Errorf("invalid filter name: %s", sqlparser.String(compExpr.Left))

View on GitHub (pinned to bde624efd1)

Solutions

  1. Rewrite OR conditions as two separate queries and merge results client-side.
  2. Replace LIKE with an exact WorkflowType equality comparison.
  3. Replace IN (...) with a single equality predicate or repeated queries.
  4. Remove NOT; express the positive condition explicitly (the dialect only supports positive equality/equality-style comparisons).

Example fix

// before
parser.Parse("WorkflowType = 'A' OR WorkflowType = 'B'")
// after
resultA, err := parser.Parse("WorkflowType = 'A'")
if err != nil { return nil, err }
resultB, err := parser.Parse("WorkflowType = 'B'")
Defensive patterns

Strategy: validation

Validate before calling

unsupported := []string{" OR ", "NOT ", "LIKE", " IN "}
q := strings.ToUpper(query)
for _, u := range unsupported {
    if strings.Contains(q, u) {
        return fmt.Errorf("unsupported expression %q in archival query", strings.TrimSpace(u))
    }
}

Try / catch

pq, err := parser.Parse(query)
if err != nil {
    if strings.Contains(err.Error(), "only comparison and") {
        return nil, status.Error(codes.InvalidArgument, "archival queries support only simple comparisons joined by AND")
    }
    return nil, err
}

Prevention

When it happens

Trigger: Calling Parse with "WorkflowId = 'w1' OR WorkflowId = 'w2'", "NOT WorkflowId = 'w1'", "WorkflowType LIKE 'My%'", or "WorkflowId IN ('a','b')".

Common situations: Users assuming full SQL support in archival queries; ORMs or query builders generating OR/LIKE conditions; hand-written queries copied from SQL visibility clients.

Related errors


AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01). Data as JSON: /api/errors/3af0b897c170990e. Report an issue: GitHub.