QueryParser* QParser_init(QueryParser *self, Schema *schema, Analyzer *analyzer, String *default_boolop, Vector *fields) { QueryParserIVARS *const ivars = QParser_IVARS(self); // Init. ivars->heed_colons = false; ivars->lexer = QueryLexer_new(); // Assign. ivars->schema = (Schema*)INCREF(schema); ivars->analyzer = (Analyzer*)INCREF(analyzer); ivars->default_boolop = default_boolop ? Str_Clone(default_boolop) : Str_new_from_trusted_utf8("OR", 2); if (fields) { ivars->fields = Vec_Clone(fields); for (uint32_t i = 0, max = Vec_Get_Size(fields); i < max; i++) { CERTIFY(Vec_Fetch(fields, i), STRING); } Vec_Sort(ivars->fields); } else { Vector *all_fields = Schema_All_Fields(schema); uint32_t num_fields = Vec_Get_Size(all_fields); ivars->fields = Vec_new(num_fields); for (uint32_t i = 0; i < num_fields; i++) { String *field = (String*)Vec_Fetch(all_fields, i); FieldType *type = Schema_Fetch_Type(schema, field); if (type && FType_Indexed(type)) { Vec_Push(ivars->fields, INCREF(field)); } } DECREF(all_fields); } Vec_Sort(ivars->fields); // Derive default "occur" from default boolean operator. if (Str_Equals_Utf8(ivars->default_boolop, "OR", 2)) { ivars->default_occur = SHOULD; } else if (Str_Equals_Utf8(ivars->default_boolop, "AND", 3)) { ivars->default_occur = MUST; } else { THROW(ERR, "Invalid value for default_boolop: %o", ivars->default_boolop); } return self; }
HeatMap* HeatMap_init(HeatMap *self, Vector *spans, uint32_t window) { HeatMapIVARS *const ivars = HeatMap_IVARS(self); Vector *spans_copy = Vec_Clone(spans); Vector *spans_plus_boosts; ivars->spans = NULL; ivars->window = window; Vec_Sort(spans_copy); spans_plus_boosts = HeatMap_Generate_Proximity_Boosts(self, spans_copy); Vec_Push_All(spans_plus_boosts, spans_copy); Vec_Sort(spans_plus_boosts); ivars->spans = HeatMap_Flatten_Spans(self, spans_plus_boosts); DECREF(spans_plus_boosts); DECREF(spans_copy); return self; }
static Query* S_compose_subquery(QueryParser *self, Vector *elems, bool enclosed) { const int32_t default_occur = QParser_IVARS(self)->default_occur; Query *retval; if (Vec_Get_Size(elems) == 0) { // No elems means no query. Maybe the search string was something // like 'NOT AND' if (enclosed) { retval = default_occur == SHOULD ? QParser_Make_OR_Query(self, NULL) : QParser_Make_AND_Query(self, NULL); } else { retval = (Query*)NoMatchQuery_new(); } } else if (Vec_Get_Size(elems) == 1 && !enclosed) { ParserElem *elem = (ParserElem*)Vec_Fetch(elems, 0); Query *query = (Query*)ParserElem_As(elem, QUERY); retval = (Query*)INCREF(query); } else { uint32_t num_elems = Vec_Get_Size(elems); Vector *required = Vec_new(num_elems); Vector *optional = Vec_new(num_elems); Vector *negated = Vec_new(num_elems); Query *req_query = NULL; Query *opt_query = NULL; // Demux elems into bins. for (uint32_t i = 0; i < num_elems; i++) { ParserElem *elem = (ParserElem*)Vec_Fetch(elems, i); if (ParserElem_Required(elem)) { Vec_Push(required, INCREF(ParserElem_As(elem, QUERY))); } else if (ParserElem_Optional(elem)) { Vec_Push(optional, INCREF(ParserElem_As(elem, QUERY))); } else if (ParserElem_Negated(elem)) { Vec_Push(negated, INCREF(ParserElem_As(elem, QUERY))); } } uint32_t num_required = Vec_Get_Size(required); uint32_t num_negated = Vec_Get_Size(negated); uint32_t num_optional = Vec_Get_Size(optional); // Bind all mandatory matchers together in one Query. if (num_required || num_negated) { if (enclosed || num_required + num_negated > 1) { Vector *children = Vec_Clone(required); Vec_Push_All(children, negated); req_query = QParser_Make_AND_Query(self, children); DECREF(children); } else if (num_required) { req_query = (Query*)INCREF(Vec_Fetch(required, 0)); } else if (num_negated) { req_query = (Query*)INCREF(Vec_Fetch(negated, 0)); } } // Bind all optional matchers together in one Query. if (num_optional) { if (!enclosed && num_optional == 1) { opt_query = (Query*)INCREF(Vec_Fetch(optional, 0)); } else { opt_query = QParser_Make_OR_Query(self, optional); } } // Unify required and optional. if (req_query && opt_query) { if (num_required) { // not just negated elems retval = QParser_Make_Req_Opt_Query(self, req_query, opt_query); } else { // req_query has only negated queries. Vector *children = Vec_new(2); Vec_Push(children, INCREF(req_query)); Vec_Push(children, INCREF(opt_query)); retval = QParser_Make_AND_Query(self, children); DECREF(children); } } else if (opt_query) { // Only optional elems. retval = (Query*)INCREF(opt_query); } else if (req_query) { // Only required elems. retval = (Query*)INCREF(req_query); } else { retval = NULL; // kill "uninitialized" compiler warning THROW(ERR, "Unexpected error"); } DECREF(opt_query); DECREF(req_query); DECREF(negated); DECREF(optional); DECREF(required); } return retval; }
PhraseQuery* PhraseQuery_init(PhraseQuery *self, String *field, Vector *terms) { return S_do_init(self, Str_Clone(field), Vec_Clone(terms), 1.0f); }
ProximityQuery* ProximityQuery_init(ProximityQuery *self, String *field, Vector *terms, uint32_t within) { return S_do_init(self, Str_Clone(field), Vec_Clone(terms), 1.0f, within); }