Ran into a couple issues with using lead for running tests versus actual hosted tin.
Environment: Lead 1.0.3, commit bd95c7e, PostgreSQL 18.6.
Using parameters instead of identical literals changes relevance scores.
Reproduction:
CREATE TEMP TABLE lead_score_repro (
id integer PRIMARY KEY,
title text NOT NULL
);
INSERT INTO lead_score_repro VALUES
(1, 'lorem ipsum'),
(2, 'lorem ipsun');
CREATE INDEX ON lead_score_repro USING tin (title);
ANALYZE lead_score_repro;
PREPARE lead_ranked(text, text) AS
SELECT id, tin.score(ctid) AS score
FROM lead_score_repro
WHERE title ==> $1 AND title ==> $2
ORDER BY id;
EXECUTE lead_ranked(
'lorem^4',
'(ipsum^4 OR ipsum~1^1.4 OR ipsum*^2)'
);
SELECT id, tin.score(ctid) AS score
FROM lead_score_repro
WHERE title ==> 'lorem^4'
AND title ==> '(ipsum^4 OR ipsum~1^1.4 OR ipsum*^2)'
ORDER BY id;
This gives the following:
| Query |
ID 1 score |
ID 2 score |
| Parameters |
0.72928625 |
0.72928625 |
| Literals |
4.472281 |
0.72928625 |
I believe this is due to the first-query fallback in score_support() that causes this. combine_constant_queries() requires Const nodes and returns None for parameters. The caller then uses first_query, discarding the remaining expressions from scoring:
let combined_query = combine_constant_queries(&same_expression)
.unwrap_or_else(|| pg_sys::copyObjectImpl(first_query.cast()).cast());
In EXPLAIN (VERBOSE, COSTS OFF), I see score_bound(title, $1, ...) for the parameterized query. For the literal query, I see both search expressions in the scorer's query argument.
Aggregating scores through a subquery raises a scoring-context error
CREATE TEMP TABLE lead_score_repro (
id integer PRIMARY KEY,
title text NOT NULL
);
INSERT INTO lead_score_repro VALUES
(1, 'lorem ipsum'),
(2, 'lorem ipsun');
CREATE INDEX ON lead_score_repro USING tin (title);
ANALYZE lead_score_repro;
-- Succeeds.
SELECT max(tin.score(ctid)) AS score
FROM lead_score_repro
WHERE title ==> 'lorem^4';
-- Fails.
SELECT max(score) AS score
FROM (
SELECT tin.score(ctid) AS score
FROM lead_score_repro
WHERE title ==> 'lorem^4'
) AS matches;
For the direct aggregate, I get 0.72928625. For the subquery aggregate, I get:
ERROR: tin.score() requires a tin index scan and cannot be used in this query context
SQLSTATE: XX000
Ran into a couple issues with using lead for running tests versus actual hosted tin.
Environment: Lead 1.0.3, commit
bd95c7e, PostgreSQL 18.6.Using parameters instead of identical literals changes relevance scores.
Reproduction:
CREATE TEMP TABLE lead_score_repro ( id integer PRIMARY KEY, title text NOT NULL ); INSERT INTO lead_score_repro VALUES (1, 'lorem ipsum'), (2, 'lorem ipsun'); CREATE INDEX ON lead_score_repro USING tin (title); ANALYZE lead_score_repro; PREPARE lead_ranked(text, text) AS SELECT id, tin.score(ctid) AS score FROM lead_score_repro WHERE title ==> $1 AND title ==> $2 ORDER BY id; EXECUTE lead_ranked( 'lorem^4', '(ipsum^4 OR ipsum~1^1.4 OR ipsum*^2)' ); SELECT id, tin.score(ctid) AS score FROM lead_score_repro WHERE title ==> 'lorem^4' AND title ==> '(ipsum^4 OR ipsum~1^1.4 OR ipsum*^2)' ORDER BY id;This gives the following:
I believe this is due to the first-query fallback in
score_support()that causes this.combine_constant_queries()requiresConstnodes and returnsNonefor parameters. The caller then usesfirst_query, discarding the remaining expressions from scoring:In
EXPLAIN (VERBOSE, COSTS OFF), I seescore_bound(title, $1, ...)for the parameterized query. For the literal query, I see both search expressions in the scorer's query argument.Aggregating scores through a subquery raises a scoring-context error
CREATE TEMP TABLE lead_score_repro ( id integer PRIMARY KEY, title text NOT NULL ); INSERT INTO lead_score_repro VALUES (1, 'lorem ipsum'), (2, 'lorem ipsun'); CREATE INDEX ON lead_score_repro USING tin (title); ANALYZE lead_score_repro; -- Succeeds. SELECT max(tin.score(ctid)) AS score FROM lead_score_repro WHERE title ==> 'lorem^4'; -- Fails. SELECT max(score) AS score FROM ( SELECT tin.score(ctid) AS score FROM lead_score_repro WHERE title ==> 'lorem^4' ) AS matches;For the direct aggregate, I get
0.72928625. For the subquery aggregate, I get: