You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Using `websearch_to_tsquery` requires PostgreSQL of version at least 11.0 and will raise an error in earlier versions of the database.
196
+
.. _fts_to_tsvector:
197
+
198
+
Automatic ``tsvector`` conversion
199
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
200
+
201
+
If the filtered column is not of type ``tsvector``, then it will be automatically converted using `to_tsvector() <https://www.postgresql.org/docs/current/functions-textsearch.html#TEXTSEARCH-FUNCTIONS-TABLE>`_.
202
+
This allows using ``fts`` on ``text`` and ``json`` types out of the box, for example.
--| Resolve a type within the context based on the given field name and JSON path. Although there are situations where failure to resolve a field is considered an error (see `resolveOrError`), there are also situations where we allow it (RPC calls). If it should be an error and `resolveOrError` doesn't fit, ensure to check the `cfIRType` isn't empty.
-- If there's an embedding on projects, then change the filter to use the internal aggregate name (`clients_projects_1`) so the filter can succeed later.
853
859
--
@@ -866,7 +872,7 @@ addNullEmbedFilters (Node rp@ReadPlan{where_=curLogic} forest) = do
866
872
newNullFilters rPlans =\case
867
873
(CoercibleExpr b lOp trees) ->
868
874
CoercibleExpr b lOp <$> (newNullFilters rPlans `traverse` trees)
--| A CoercibleField pairs the name of a query element with any type coercion information we need for some specific use case.
25
30
-- |
26
31
-- | As suggested by the name, it's often a reference to a field in a table but really it can be any nameable element (function parameter, calculation with an alias, etc) with a knowable type.
@@ -33,17 +38,18 @@ type TransformerProc = Text
33
38
-- |
34
39
-- | The type value is allowed to be the empty string. The analog here is soft type checking in programming languages: sometimes we don't need a variable to have a specified type and things will work anyhow. So the empty type variant is valid when we don't know and *don't need to know* about the specific type in some context. Note that this variation should not be used if it guarantees failure: in that case you should instead raise an error at the planning stage and bail out. For example, we can't parse JSON with `json_to_recordset` without knowing the types of each recipient field, and so error out. Using the empty string for the type would be incorrect and futile. On the other hand we use the empty type for RPC calls since type resolution isn't implemented for RPC, but it's fine because the query still works with Postgres' implicit coercion. In the future, hopefully we will support data representations across the board and then the empty type may be permanently retired.
35
40
dataCoercibleField=CoercibleField
36
-
{cfName::FieldName
37
-
, cfJsonPath::JsonPath
38
-
, cfToJson::Bool
39
-
, cfIRType::Text--^ The native Postgres type of the field, the intermediate (IR) type before mapping.
40
-
, cfTransform::MaybeTransformerProc--^ The optional mapping from irType -> targetType.
41
-
, cfDefault::MaybeText
42
-
, cfFullRow::Bool--^ True if the field represents the whole selected row. Used in spread rels: instead of COUNT(*), it does a COUNT(<row>) in order to not mix with other spreaded resources.
41
+
{cfName::FieldName
42
+
, cfJsonPath::JsonPath
43
+
, cfToJson::Bool
44
+
, cfToTsVector::MaybeToTsVector--^ If the field should be converted using to_tsvector(<language>, <field>)
45
+
, cfIRType::Text--^ The native Postgres type of the field, the intermediate (IR) type before mapping.
46
+
, cfTransform::MaybeTransformerProc--^ The optional mapping from irType -> targetType.
47
+
, cfDefault::MaybeText
48
+
, cfFullRow::Bool--^ True if the field represents the whole selected row. Used in spread rels: instead of COUNT(*), it does a COUNT(<row>) in order to not mix with other spreaded resources.
43
49
}deriving (Eq, Show)
44
50
45
51
unknownField::FieldName->JsonPath->CoercibleField
46
-
unknownField name path =CoercibleField name path False""NothingNothingFalse
52
+
unknownField name path =CoercibleField name path FalseNothing""NothingNothingFalse
47
53
48
54
--| Like an API request LogicTree, but with coercible field information.
get "/tsearch?or=(text_search_vector.plfts(german).Art%20Spass, text_search_vector.plfts(french).amusant%20impossible, text_search_vector.fts(english).impossible)"`shouldRespondWith`
get "/grandchild_entities?or=(jsonb_col.fts.bar,jsonb_col.fts.foo)&select=jsonb_col"`shouldRespondWith`
95
+
[json|[
96
+
{ "jsonb_col": {"a": {"b":"foo"}} },
97
+
{ "jsonb_col": {"b":"bar"} }]
98
+
|] { matchHeaders = [matchContentTypeJson] }
99
+
get "/tsearch_to_tsvector?and=(text_search.not.plfts(german).Art%20Spass, text_search.not.plfts(french).amusant%20impossible, text_search.not.fts(english).impossible)&select=text_search"`shouldRespondWith`
100
+
[json|[
101
+
{ "text_search": "But also fun to do what is possible" },
102
+
{ "text_search": "Fat cats ate rats" }]
103
+
|] { matchHeaders = [matchContentTypeJson] }
93
104
it "can handle isdistinct"$
94
105
get "/entities?and=(id.gte.2,arr.isdistinct.{1,2})&select=id"`shouldRespondWith`
0 commit comments