44 $olderror = error_reporting( E_ERROR );
45 $resultSet = $this->db->query( $q,
'SearchPostgres',
true );
46 error_reporting( $olderror );
52 $olderror = error_reporting( E_ERROR );
53 $resultSet = $this->db->query( $q,
'SearchPostgres',
true );
54 error_reporting( $olderror );
67 wfDebug(
"parseQuery received: $term \n" );
69 # # No backslashes allowed
72 # # Collapse parens into nearby words:
73 $term = preg_replace(
'/\s*\(\s*/',
' (',
$term );
74 $term = preg_replace(
'/\s*\)\s*/',
') ',
$term );
76 # # Treat colons as word separators:
81 if ( preg_match_all(
'/([-!]?)(\S+)\s*/',
$term, $m, PREG_SET_ORDER ) ) {
82 foreach ( $m
as $terms ) {
83 if ( strlen( $terms[1] ) ) {
84 $searchstring .=
' & !';
86 if ( strtolower( $terms[2] ) ===
'and' ) {
87 $searchstring .=
' & ';
88 } elseif ( strtolower( $terms[2] ) ===
'or' || $terms[2] ===
'|' ) {
89 $searchstring .=
' | ';
90 } elseif ( strtolower( $terms[2] ) ===
'not' ) {
91 $searchstring .=
' & !';
93 $searchstring .=
" & $terms[2]";
98 # # Strip out leading junk
99 $searchstring = preg_replace(
'/^[\s\&\|]+/',
'', $searchstring );
101 # # Remove any doubled-up operators
102 $searchstring = preg_replace(
'/([\!\&\|]) +(?:[\&\|] +)+/',
"$1 ", $searchstring );
104 # # Remove any non-spaced operators (e.g. "Zounds!")
105 $searchstring = preg_replace(
'/([^ ])[\!\&\|]/',
"$1", $searchstring );
107 # # Remove any trailing whitespace or operators
108 $searchstring = preg_replace(
'/[\s\!\&\|]+$/',
'', $searchstring );
110 # # Remove unnecessary quotes around everything
111 $searchstring = preg_replace(
'/^[\'"](.*)[\'"]$/',
"$1", $searchstring );
113 # # Quote the whole thing
114 $searchstring = $this->db->addQuotes( $searchstring );
116 wfDebug(
"parseQuery returned: $searchstring \n" );
118 return $searchstring;
129 # Get the SQL fragment for the given term
132 # # We need a separate query here so gin does not complain about empty searches
133 $sql =
"SELECT to_tsquery($searchstring)";
134 $res = $this->db->query( $sql );
136 # # TODO: Better output (example to catch: one 'two)
137 die(
"Sorry, that was not a valid search string. Please go back and try again" );
139 $top =
$res->fetchRow()[0];
141 $this->searchTerms = [];
142 $slotRoleStore = MediaWikiServices::getInstance()->getSlotRoleStore();
143 if ( $top ===
"" ) { # #
e.g.
if only stopwords
are used XXX
return something better
144 $query =
"SELECT page_id, page_namespace, page_title, 0 AS score " .
145 "FROM page p, revision r, slots s, content c, pagecontent pc " .
146 "WHERE p.page_latest = r.rev_id " .
147 "AND s.slot_revision_id = r.rev_id " .
148 "AND s.slot_role_id = " . $slotRoleStore->getId( SlotRecord::MAIN ) .
" " .
149 "AND c.content_id = s.slot_content_id " .
150 "AND pc.old_id = substring( c.content_address from '^tt:([0-9]+)$' )::int " .
154 if ( preg_match_all(
"/'([^']+)'/", $top, $m, PREG_SET_ORDER ) ) {
155 foreach ( $m
as $terms ) {
156 $this->searchTerms[$terms[1]] = $terms[1];
160 $query =
"SELECT page_id, page_namespace, page_title, " .
161 "ts_rank($fulltext, to_tsquery($searchstring), 5) AS score " .
162 "FROM page p, revision r, slots s, content c, pagecontent pc " .
163 "WHERE p.page_latest = r.rev_id " .
164 "AND s.slot_revision_id = r.rev_id " .
165 "AND s.slot_role_id = " . $slotRoleStore->getId( SlotRecord::MAIN ) .
" " .
166 "AND c.content_id = s.slot_content_id " .
167 "AND pc.old_id = substring( c.content_address from '^tt:([0-9]+)$' )::int " .
168 "AND $fulltext @@ to_tsquery($searchstring)";
170 # # Namespaces - defaults to 0
173 $query .=
' AND page_namespace = 0';
176 $query .=
" AND page_namespace IN ($namespaces)";
180 $query .=
" ORDER BY score DESC, page_id DESC";
182 $query .= $this->db->limitResult(
'', $this->limit, $this->offset );
184 wfDebug(
"searchQuery returned: $query \n" );
189 # # Most of the work of these two functions are done automatically via triggers
192 # # We don't want to index older revisions
193 $slotRoleStore = MediaWikiServices::getInstance()->getSlotRoleStore();
194 $sql =
"UPDATE pagecontent SET textvector = NULL " .
195 "WHERE textvector IS NOT NULL " .
197 "(SELECT DISTINCT substring( c.content_address from '^tt:([0-9]+)$' )::int AS old_rev_text_id " .
198 " FROM content c, slots s, revision r " .
199 " WHERE r.rev_page = $pageid " .
200 " AND s.slot_revision_id = r.rev_id " .
201 " AND s.slot_role_id = " . $slotRoleStore->getId( SlotRecord::MAIN ) .
" " .
202 " AND c.content_id = s.slot_content_id " .
203 " ORDER BY old_rev_text_id DESC OFFSET 1)";
204 $this->db->query( $sql );