Skip to content

Commit 82c28fd

Browse files
authored
Merge pull request #351 from robertn702/string-regex-filters
String regex filters
2 parents f214f94 + 759360a commit 82c28fd

File tree

8 files changed

+151
-14
lines changed

8 files changed

+151
-14
lines changed

docs/api.md

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,8 @@ Where the `<Table>Filter` type enumerates filterable fields and their associated
486486
startsWith: String
487487
like: String
488488
ilike: String
489+
regex: String
490+
iregex: String
489491
}
490492
```
491493

@@ -501,19 +503,21 @@ Where the `<Table>Filter` type enumerates filterable fields and their associated
501503
The following list shows the operators that may be available on `<Type>Filter` types.
502504

503505

504-
| Operator | Description |
505-
| ----------- | ------------------------- |
506-
| eq | Equal To |
507-
| neq | Not Equal To |
508-
| gt | Greater Than |
509-
| gte | Greater Than Or Equal To |
510-
| in | Contained by Value List |
511-
| lt | Less Than |
512-
| lte | Less Than Or Equal To |
513-
| is | Null or Not Null |
514-
| startsWith | `String` starts with prefix |
515-
| like | Case Sensitive `String` Pattern Match. '%' as wildcard |
516-
| ilike | Case Snsensitive `String` Pattern Match. '%' as wildcard |
506+
| Operator | Description |
507+
| ----------- | -------------------------------------------------|
508+
| eq | Equal To |
509+
| neq | Not Equal To |
510+
| gt | Greater Than |
511+
| gte | Greater Than Or Equal To |
512+
| in | Contained by Value List |
513+
| lt | Less Than |
514+
| lte | Less Than Or Equal To |
515+
| is | Null or Not Null |
516+
| startsWith | Starts with prefix |
517+
| like | Pattern Match. '%' as wildcard |
518+
| ilike | Pattern Match. '%' as wildcard. Case Insensitive |
519+
| regex | POSIX Regular Expression Match |
520+
| iregex | POSIX Regular Expression Match. Case Insensitive |
517521

518522
Not all operators are available on every `<Type>Filter` type. For example, `UUIDFilter` only supports `eq` and `neq` because `UUID`s are not ordered.
519523

docs/assets/demo_schema.graphql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,8 @@ input StringFilter {
609609
startsWith: String
610610
like: String
611611
ilike: String
612+
regex: String
613+
iregex: String
612614
}
613615

614616
scalar Time

docs/changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,6 @@
2121
- bugfix: Unknown types are represented in GraphQL schema as `Opaque` rather than `String`
2222
- bugfix: PostgreSQL type modifiers, e.g. char(n), no longer truncate excess text
2323
- bugfix: Creating a new enum variant between existing variants no longer errors
24+
25+
## master
26+
- feature: `String` type filters support `regex`, `iregex`

src/graphql.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3011,6 +3011,8 @@ pub enum FilterOp {
30113011
StartsWith,
30123012
Like,
30133013
ILike,
3014+
RegEx,
3015+
IRegEx,
30143016
}
30153017

30163018
impl ToString for FilterOp {
@@ -3028,6 +3030,8 @@ impl ToString for FilterOp {
30283030
Self::StartsWith => "startsWith",
30293031
Self::Like => "like",
30303032
Self::ILike => "ilike",
3033+
Self::RegEx => "regex",
3034+
Self::IRegEx => "iregex",
30313035
}
30323036
.to_string()
30333037
}
@@ -3050,6 +3054,8 @@ impl FromStr for FilterOp {
30503054
"startsWith" => Ok(Self::StartsWith),
30513055
"like" => Ok(Self::Like),
30523056
"ilike" => Ok(Self::ILike),
3057+
"regex" => Ok(Self::RegEx),
3058+
"iregex" => Ok(Self::IRegEx),
30533059
_ => Err("Invalid filter operation".to_string()),
30543060
}
30553061
}
@@ -3133,6 +3139,8 @@ impl ___Type for FilterTypeType {
31333139
FilterOp::StartsWith,
31343140
FilterOp::Like,
31353141
FilterOp::ILike,
3142+
FilterOp::RegEx,
3143+
FilterOp::IRegEx,
31363144
],
31373145
Scalar::BigInt => vec![
31383146
FilterOp::Equal,
@@ -3205,7 +3213,9 @@ impl ___Type for FilterTypeType {
32053213
| FilterOp::LessThanEqualTo
32063214
| FilterOp::StartsWith
32073215
| FilterOp::Like
3208-
| FilterOp::ILike => __InputValue {
3216+
| FilterOp::ILike
3217+
| FilterOp::RegEx
3218+
| FilterOp::IRegEx => __InputValue {
32093219
name_: op.to_string(),
32103220
type_: __Type::Scalar(scalar.clone()),
32113221
description: None,

src/transpile.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,8 @@ impl FilterBuilderElem {
694694
FilterOp::StartsWith => "^@",
695695
FilterOp::Like => "like",
696696
FilterOp::ILike => "ilike",
697+
FilterOp::RegEx => "~",
698+
FilterOp::IRegEx => "~*",
697699
FilterOp::Is => {
698700
return Err("Error transpiling Is filter".to_string());
699701
}

test/expected/resolve_graphiql_schema.out

Lines changed: 20 additions & 0 deletions
Large diffs are not rendered by default.

test/expected/string_filters.out

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,5 +168,69 @@ begin;
168168
}
169169
(1 row)
170170

171+
rollback to savepoint a;
172+
-- Filter by regex
173+
select jsonb_pretty(
174+
graphql.resolve($$
175+
{
176+
memoCollection(filter: {contents: {regex: "^F\\w+$"}}) {
177+
edges {
178+
node {
179+
contents
180+
}
181+
}
182+
}
183+
}
184+
$$)
185+
);
186+
jsonb_pretty
187+
-------------------------------------------
188+
{ +
189+
"data": { +
190+
"memoCollection": { +
191+
"edges": [ +
192+
{ +
193+
"node": { +
194+
"contents": "Foo"+
195+
} +
196+
} +
197+
] +
198+
} +
199+
} +
200+
}
201+
(1 row)
202+
203+
rollback to savepoint a;
204+
-- iregex is not case sensitive
205+
select jsonb_pretty(
206+
graphql.resolve($$
207+
{
208+
memoCollection(filter: {contents: {iregex: "^f\\w+$"}}) {
209+
edges {
210+
node {
211+
contents
212+
}
213+
}
214+
}
215+
}
216+
$$)
217+
);
218+
jsonb_pretty
219+
-------------------------------------------
220+
{ +
221+
"data": { +
222+
"memoCollection": { +
223+
"edges": [ +
224+
{ +
225+
"node": { +
226+
"contents": "Foo"+
227+
} +
228+
} +
229+
] +
230+
} +
231+
} +
232+
}
233+
(1 row)
234+
171235
rollback to savepoint a;
172236
rollback;

test/sql/string_filters.sql

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,36 @@ begin;
9393
);
9494
rollback to savepoint a;
9595

96+
-- Filter by regex
97+
select jsonb_pretty(
98+
graphql.resolve($$
99+
{
100+
memoCollection(filter: {contents: {regex: "^F\\w+$"}}) {
101+
edges {
102+
node {
103+
contents
104+
}
105+
}
106+
}
107+
}
108+
$$)
109+
);
110+
rollback to savepoint a;
111+
112+
-- iregex is not case sensitive
113+
select jsonb_pretty(
114+
graphql.resolve($$
115+
{
116+
memoCollection(filter: {contents: {iregex: "^f\\w+$"}}) {
117+
edges {
118+
node {
119+
contents
120+
}
121+
}
122+
}
123+
}
124+
$$)
125+
);
126+
rollback to savepoint a;
127+
96128
rollback;

0 commit comments

Comments
 (0)