/** * @param nc_search_query_expression_interval $expression * @return string */ protected function translate_interval(nc_search_query_expression_interval $expression) { /** @var $begin nc_search_query_expression_term */ /** @var $end nc_search_query_expression_term */ list($begin, $end) = $expression->get_items(); $value1 = $begin->get_value(); $value2 = $end->get_value(); $field_name = $expression->get_field(); $builder = $this->query_builder; $fts_query = ""; if ($field_name) { /** @var $f nc_search_provider_index_field */ $range_conditions = array(); if ($this->is_root()) { $this->can_skip_fts_query = true; } foreach ($this->get_fields('name', $field_name) as $f) { $table_name = $f->get_field_table_name(); $is_stored_numeric_field = $f->get('type') == nc_search_provider_index_field::TYPE_INTEGER && ($f->get('is_sortable') || $f->get('is_stored')); if ($is_stored_numeric_field) { $n1 = $this->escape_number($value1); $n2 = $this->escape_number($value2); $range_conditions[] = "`{$table_name}`.`RawData` BETWEEN {$n1} AND {$n2}" . ($expression->is_exclusive() ? " AND `{$table_name}`.`RawData` NOT IN ({$n1}, {$n2})" : ""); $this->query_builder->add_condition_table($table_name); } else { // expand the query if (!$fts_query) { // load once in the foreach loop $terms = $this->get_codes_by_interval($value1, $value2, $expression->is_exclusive()); $fts_query = "(" . join(" ", $terms) . ")"; $builder->add_term_ranking($field_name, $terms, 1); } // preselect IDs for the field match -- this is the fastest way to do // this type of query (alternative is a subquery with FORCE INDEX, but // MySQL will transform it to a slow correlated subquery) $query = "SELECT `Document_ID` FROM `{$table_name}` WHERE MATCH(`Content`) AGAINST ('{$fts_query}' IN BOOLEAN MODE)"; $ids = $this->get_db()->get_col($query); $ids = $ids ? join(",", $ids) : "0"; $range_conditions[] = "`{$this->index_table_name}`.`Document_ID` IN ({$ids})"; } } // of "foreach field with that name" if ($range_conditions) { $builder->add_condition("(" . join(" OR ", $range_conditions) . ")"); } else { $builder->add_condition("0"); } return ""; // no need to match the compound index } else { // no field name (global match) $terms = $this->get_codes_by_interval($value1, $value2, $expression->is_exclusive()); $fts_query = "(" . join(" ", $terms) . ")"; $this->add_field_matches($expression, $fts_query); $builder->add_term_ranking($field_name, $terms, 1); } return $fts_query; }
/** * @param nc_search_query_expression_interval $expression * @return void */ protected function translate_interval(nc_search_query_expression_interval $expression) { $terms = array(); $brackets = $expression->get_type() == "inclusive" ? "[]" : "{}"; foreach ($expression->get_items() as $term) { $terms[] = $term->get_value(); } $string = "INTERVAL {$brackets['0']}" . join("; ", $terms) . $brackets[1] . $this->get_modifiers($expression); $this->print_line($string); }