mirror of
https://github.com/FerretDB/documentdb.git
synced 2026-11-08 11:55:30 -05:00
### Does this PR have any customer impact? Yes ### Type (Feature, Refactoring, Bugfix, DevOps, Testing, Perf, etc) Feature ### Does it involve schema level changes? (Table, Column, Index, UDF, etc level changes) No ### Are you introducing any new config? If yes, do you have tests with and without them being set? Yes (helio_api.enableCollation). Yes. ### Release Note (Refer [Template](../docs/release_notes/pgmongo_template.md)) Done ### Description Runtime implementation of collation support in Mongo Find query. We parse the Mongo collation spec and covert it to an ICU standard collation string. An example string is "und-u-ks-level1-kc-true This string uniquely identify collation-based string comparison logic by Postgres. See: https://www.postgresql.org/docs/current/collation.html This document tracks the current support matrix for query operators | Operator | Runtime | Index Pushdown | Comments | --------- | ---- | ----- | ---- | $eq | Yes | No | | $gt | Yes | No | | $gte | Yes | No | | $lt | Yes | No | | $lte | Yes | No | | $ne | Yes | No | | $in | No* | No | See below | $nin | No* | No | Do | $and | Yes | No | | $not | Yes | No | | $nor | Yes | No | | $or | Yes | No | | $all | Yes | No | | $elemMatch | Yes | No | | $positional | N/A | N/A | positional query operators are only used in projections. | $regex | N/A | N/A | $regex ignores collations in Native Mongo | $exists | N/A | N/A | | $size | N/A | N/A | | $type | N/A | N/A | | $bitsAllClear | N/A | N/A | Not relevant for Utf8 | $bitsAnyClear | N/A | N/A | Do | $bitsAllSet | N/A | N/A | Do | $bitsAnySet | N/A | N/A | Do | $mod | N/A | N/A | Do | $range | N/A | N/A | Only applies to Number | $text | N/A | N/A | Seprate Index, has its own collation spec | $geowithin | N/A | N/A | Not relevant for Utf8 | $geointersects | N/A | N/A | Do * $in/$nin is implemented with HashMap that does not support collation friendly Hashkeys * $regex : collations are ignored with * $text: $text spec has collation specific parameters * $rage: For numbers only This document tracks the current support matrix for update operators/commands | Operator | Runtime | Index Pushdown | | --------- | ---- | ----- | | find_and_modify | No | No | | updateOne | No | No | | updateMany | No | No | | createIndex | No | No | Tests: 1. All Gated Tests pass when Collation is enabled by default TODO: 1. Index support [already implemented - but breaking down for easy review] 2. Persist collation info while collection created [already implemented - but breaking down for easy review] 3. $cond, $let Related work items: #3412359
137 lines
4.7 KiB
C
137 lines
4.7 KiB
C
/*-------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
*
|
|
* src/bson_query.h
|
|
*
|
|
* Common declarations for BSON query functions.
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
|
|
#ifndef QUERY_OPERATOR_H
|
|
#define QUERY_OPERATOR_H
|
|
|
|
#include <nodes/params.h>
|
|
#include <nodes/parsenodes.h>
|
|
|
|
#include "metadata/collection.h"
|
|
#include "io/helio_bson_core.h"
|
|
#include "opclass/helio_gin_common.h"
|
|
#include "planner/mongo_query_operator.h"
|
|
|
|
/* BsonElemMatchContext is passed down while expanding BSON query expressions to handle $elemMatch operator */
|
|
typedef struct BsonElemMatchContext
|
|
{
|
|
/* Depth in case of nested elemMatch while traversing the query */
|
|
int currentDepth;
|
|
|
|
/* Max Depth in case of nested elemMatch */
|
|
int maxDepth;
|
|
|
|
/* List of quals to be applied as outermost quals in elemMatch query tree
|
|
* Example: { a: {$elemMatch: {d: {$elemMatch: {e: {$gte: 1}}}, b: {$elemMatch: { $gte: 80, $lt: 85 }}}} }
|
|
* The outermost quals will be {"a.d.e" : {"$gte" : 1}, "a.b" : {"$gte" : 80}, "a.b" : {"$lt" : 85} }
|
|
*/
|
|
List *outerMostExpressionQuals;
|
|
|
|
/* It is set when bson query expression results in SUBLINK creation in query tree */
|
|
bool hasSublink;
|
|
|
|
/* It is set when bson query expression contains number field inside $elemMatch
|
|
* Example: {"a" : { "$elemMatch": { "0" : 100 } } }
|
|
*/
|
|
bool hasNumberField;
|
|
|
|
/* It is set when there is expression inside $elemMatch for $ne, $not */
|
|
bool hasNegationOp;
|
|
|
|
/* isCmpOpInsideElemMatch : it will be set to true when there is a cmp operator inside $elemMatch i.e. for calling CreateOpExprFromOperatorDocIterator.
|
|
* {path : {$elemMatch : {$op : {...}}}}. we are interested in $op being another $elemMatch for array of array scenario.
|
|
*/
|
|
bool isCmpOpInsideElemMatch;
|
|
} BsonElemMatchContext;
|
|
|
|
/*
|
|
* BsonQueryOperatorContext is passed down while expanding BSON query expressions
|
|
* of the form <document> @@ <query>
|
|
*/
|
|
typedef struct BsonQueryOperatorContext
|
|
{
|
|
Expr *documentExpr;
|
|
|
|
/* The input variable type for functions. Note that this should
|
|
* match the data type expectations of documentExpr above.
|
|
* If documentExpr is bson -> this is bson (otherwise it's bsonValue)
|
|
*/
|
|
MongoQueryOperatorInputType inputType;
|
|
|
|
/*
|
|
* Whether or not to treat a simple $or as $in.
|
|
*/
|
|
bool simplifyOperators;
|
|
|
|
/*
|
|
* Coerce expressions to runtime OpExpr if available
|
|
*/
|
|
bool coerceOperatorExprIfApplicable;
|
|
|
|
/* Required path names for vector search
|
|
* it is set only when the filter of vector search is specified
|
|
*/
|
|
HTAB *requiredFilterPathNameHashSet;
|
|
|
|
/* List of sort clauses, if any query operator adds them
|
|
* e.g. $near, $nearSphere etc, will be NULL for most of
|
|
* the query operators.
|
|
*
|
|
* Please note that the `ressortgroupref` is needed to be updated
|
|
* based on the overall query structure later
|
|
*/
|
|
List *sortClauses;
|
|
|
|
/* List of Target entries for these sort clauses
|
|
*
|
|
* Please note that the `resno` is needed to be updated
|
|
* based on the overall query structure later
|
|
*/
|
|
List *targetEntries;
|
|
|
|
/* Any let variable context for this query operator */
|
|
Expr *variableContext;
|
|
|
|
/* ICU standard colation string. See AggregationPipelineBuildContext for more details. */
|
|
const char *collationString;
|
|
} BsonQueryOperatorContext;
|
|
|
|
Var * MakeSimpleDocumentVar(void);
|
|
Node * ReplaceBsonQueryOperators(Query *node, ParamListInfo boundParams);
|
|
void ValidateQueryDocument(pgbson *queryDocument);
|
|
bool QueryDocumentsAreEquivalent(const pgbson *leftQueryDocument,
|
|
const pgbson *rightQueryDocument);
|
|
List * CreateQualsFromQueryDocIterator(bson_iter_t *queryDocIterator,
|
|
BsonQueryOperatorContext *context);
|
|
Node * EvaluateBoundParameters(Node *expression, ParamListInfo boundParams);
|
|
|
|
List * CreateQualsForBsonValueTopLevelQuery(const pgbson *query);
|
|
Expr * CreateQualForBsonValueExpression(const bson_value_t *expression, const
|
|
char *collationString);
|
|
Expr * CreateQualForBsonValueArrayExpression(const bson_value_t *expression);
|
|
Expr * CreateQualForBsonExpression(const bson_value_t *expression, const char *queryPath);
|
|
|
|
Expr * CreateNonShardedShardKeyValueFilter(int collectionVarNo, const
|
|
MongoCollection *collection);
|
|
Expr * CreateShardKeyFiltersForQuery(const bson_value_t *queryDocument, pgbson *shardKey,
|
|
uint64_t collectionId,
|
|
Index collectionVarno);
|
|
Expr * CreateIdFilterForQuery(List *existingQuals,
|
|
Index collectionVarno, bool *isCollationAware);
|
|
|
|
bool ValidateOrderbyExpressionAndGetIsAscending(pgbson *orderby);
|
|
|
|
/* Checks the validity of value for $in and $nin ops */
|
|
bool IsValidBsonDocumentForDollarInOrNinOp(const bson_value_t *value);
|
|
void UpdateQueryOperatorContextSortList(Query *query, List *sortClauses,
|
|
List *targetEntries);
|
|
|
|
#endif
|