Package · mui-data-grid

Operators

The operator is the middle part of a filter item: { field, operator, value }. This page collects every supported operator, the SQL each turns into, and the table of which ones a column accepts depending on its declared type.

The MGOperator enum

The strings are exactly what MUI X DataGrid sends; forward them from the UI unchanged. The cast to the enum happens during request hydration: an unknown string is rejected before the request reaches the schema.

Category Operator Enum case
String contains MGOperator::CONTAINS
notContains MGOperator::NOT_CONTAINS
startsWith MGOperator::STARTS_WITH
endsWith MGOperator::ENDS_WITH
Equality equals MGOperator::EQUALS
is MGOperator::IS
not MGOperator::NOT
= MGOperator::EQ
!= MGOperator::NEQ
Comparison > MGOperator::GT
>= MGOperator::GTE
< MGOperator::LT
<= MGOperator::LTE
Date after MGOperator::AFTER
onOrAfter MGOperator::ON_OR_AFTER
before MGOperator::BEFORE
onOrBefore MGOperator::ON_OR_BEFORE
Set isAnyOf MGOperator::IS_ANY_OF
Emptiness isEmpty MGOperator::IS_EMPTY
isNotEmpty MGOperator::IS_NOT_EMPTY

The date operators are synonyms of the comparison ones: they exist because the table’s UI names them differently for date columns, while the SQL comes out the same.

Operator → SQL

Operator SQL
contains col LIKE :v with the value %v% *
notContains col NOT LIKE :v with the value %v% *
startsWith col LIKE :v with the value v% *
endsWith col LIKE :v with the value %v *
equals · is · = col = :v
not · != col != :v
> · after col > :v
>= · onOrAfter col >= :v
< · before col < :v
<= · onOrBefore col <= :v
isAnyOf col IN (:v0, :v1, …) — an empty set yields an empty condition
isEmpty col IS NULL
isNotEmpty col IS NOT NULL

* The first four operators are case-insensitive, and SQL spells that differently per database: ILIKE in PostgreSQL, LIKE in MySQL and SQLite, lower(col) LIKE lower(:v) as the portable form. The spelling is chosen automatically — see Match modes.

The value always travels as a bound parameter: the % wildcards are added on the PHP side, never by string concatenation in SQL.

The FilterType enum

The type is declared on a column via filterable() and acts as a gate: an operator outside the set is rejected with 400 before it reaches SQL. That protects the query from a merely misconfigured UI as much as from a malicious one.

FilterType Allowed operators
String contains, notContains, startsWith, endsWith, equals, is, not, =, !=, isAnyOf, isEmpty, isNotEmpty
Number equals, is, not, =, !=, >, >=, <, <=, isAnyOf, isEmpty, isNotEmpty
Boolean is, equals, =, isEmpty, isNotEmpty
Date is, not, equals, =, !=, after, onOrAfter, before, onOrBefore, isEmpty, isNotEmpty

The same matrix seen from the operator’s side:

Operator String Number Boolean Date
contains · notContains · startsWith · endsWith
equals · is · =
not · !=
> · >= · < · <=
after · onOrAfter · before · onOrBefore
isAnyOf
isEmpty · isNotEmpty

Choose the type by how the value behaves in SQL

The type here is not about the PHP type but about which comparisons make sense. A status column compared only for equality and set membership is sensibly a String, even if the database stores a smallint. A timestamp is a Date, which gets you the range operators and keeps contains away.

A rejection, end to end

php
GridColumn::for('views', 'a.views')->filterable(FilterType::Number);
json
{ "field": "views", "operator": "contains", "value": "1" }
json
{ "message": "Operator 'contains' is not allowed for field 'views'" }

Combining conditions: AND and OR

The filter model’s logicOperator decides how items are joined. The value is validated at hydration: only and and or are accepted, in any case, defaulting to and.

json
{
"filterModel": {
  "logicOperator": "or",
  "items": [
    { "field": "title",      "operator": "contains", "value": "sql" },
    { "field": "authorName", "operator": "contains", "value": "sql" }
  ]
}
}

Result

sql
((a.title LIKE :iqb0 OR au.name LIKE :iqb1))

The outer parentheses are deliberate: without them the OR would blend into your base WHERE through AND and change the meaning of the query.

Edge cases

Case Behavior
items is empty no condition is added, the base WHERE is untouched
isAnyOf with an empty array that item is skipped, the others apply
every item produced an empty condition no condition is added
value missing for isEmpty / isNotEmpty fine — those operators need none
unknown operator string 400 during request hydration
field not declared in the schema 400 from the schema

Next steps