statement ok
CREATE TABLE a (a INT PRIMARY KEY, t TEXT)

statement error data type text has no default operator class for access method \"gin\"
CREATE INVERTED INDEX ON a(t)

statement error data type text has no default operator class for access method \"gin\"
CREATE INDEX ON a USING GIN(t)

statement error pgcode 42804 operator classes are only allowed for the last column of an inverted index
CREATE INDEX ON a (t gin_trgm_ops)

statement error pgcode 42804 operator classes are only allowed for the last column of an inverted index
CREATE INVERTED INDEX ON a (a gin_trgm_ops, t gin_trgm_ops)

statement error operator class \"blah_ops\" does not exist
CREATE INVERTED INDEX ON a(t blah_ops)

statement ok
CREATE INVERTED INDEX ON a(t gin_trgm_ops)

statement ok
CREATE INDEX ON a USING GIN(t gin_trgm_ops)

# Both gin_trgm_ops and gist_trgm_ops work.
statement ok
CREATE INDEX ON a USING GIST(t gist_trgm_ops)

statement ok
INSERT INTO a VALUES (1, 'foozoopa'),
                     (2, 'Foo'),
                     (3, 'blah'),
                     (4, 'Приветhi')

query IT rowsort
SELECT * FROM a@a_t_idx WHERE t ILIKE '%Foo%'
----
1  foozoopa
2  Foo

query IT
SELECT * FROM a@a_t_idx WHERE t LIKE '%Foo%'
----
2  Foo

query IT
SELECT * FROM a@a_t_idx WHERE t LIKE 'Foo%'
----
2  Foo

query IT
SELECT * FROM a@a_t_idx WHERE t LIKE '%Foo'
----
2  Foo

query IT
SELECT * FROM a@a_t_idx WHERE t LIKE '%foo%oop%'
----
1  foozoopa

query IT
SELECT * FROM a@a_t_idx WHERE t LIKE '%fooz%'
----
1  foozoopa

query IT
SELECT * FROM a@a_t_idx WHERE t LIKE '%foo%oop'
----

query IT
SELECT * FROM a@a_t_idx WHERE t LIKE 'zoo'
----

query IT
SELECT * FROM a@a_t_idx WHERE t LIKE '%foo%oop%' OR t ILIKE 'blah' ORDER BY a
----
1  foozoopa
3  blah

query IT
SELECT * FROM a@a_t_idx WHERE t LIKE 'blahf'
----

query IT
SELECT * FROM a@a_t_idx WHERE t LIKE 'fblah'
----

query IT
SELECT * FROM a@a_t_idx WHERE t LIKE 'Приветhi'
----
4  Приветhi

query IT
SELECT * FROM a@a_t_idx WHERE t LIKE 'Привет%'
----
4  Приветhi

query IT
SELECT * FROM a@a_t_idx WHERE t LIKE 'Приве%'
----
4  Приветhi

query IT
SELECT * FROM a@a_t_idx WHERE t LIKE '%иве%'
----
4  Приветhi

query IT
SELECT * FROM a@a_t_idx WHERE t LIKE '%тhi%'
----
4  Приветhi

# Test the acceleration of the % similarity operator.
# By default, the threshold for searching is .3.
query FIT
SELECT similarity(t, 'blar'), * FROM a@a_t_idx WHERE t % 'blar'
----
0.428571428571429  3  blah

query FIT
SELECT similarity(t, 'byar'), * FROM a@a_t_idx WHERE t % 'byar'
----

query FIT
SELECT similarity(t, 'fooz'), * FROM a@a_t_idx WHERE t % 'fooz' ORDER BY a
----
0.4  1  foozoopa
0.5  2  Foo

query FIT
SELECT similarity(t, 'fo'), * FROM a@a_t_idx WHERE t % 'fo' ORDER BY a
----
0.4  2  Foo

statement ok
SET pg_trgm.similarity_threshold=.45

query FIT
SELECT similarity(t, 'fooz'), * FROM a@a_t_idx WHERE t % 'fooz'
----
0.5  2  Foo

statement ok
SET pg_trgm.similarity_threshold=0.1

query FIT
SELECT similarity(t, 'f'), * FROM a@a_t_idx WHERE t % 'f' ORDER BY a
----
0.1  1  foozoopa
0.2  2  Foo

# Test the acceleration of the equality operator.
query IT
SELECT * FROM a@a_t_idx WHERE t = 'Foo'
----
2  Foo

query IT
SELECT * FROM a@a_t_idx WHERE t = 'foo'
----

query IT
SELECT * FROM a@a_t_idx WHERE t = 'foozoopa'
----
1  foozoopa

query IT
SELECT * FROM a@a_t_idx WHERE t = 'foozoopa' OR t = 'Foo' ORDER BY a
----
1  foozoopa
2  Foo

# Ensure that it's not possible to create a trigram index on a column that is also
# part of the primary key.

statement ok
CREATE TABLE pkt (a TEXT PRIMARY KEY); INSERT INTO pkt VALUES ('abcd'), ('bcde')

statement error primary key column a cannot be present in an inverted index
CREATE INVERTED INDEX ON pkt(a gin_trgm_ops)

# Ensure that it's not possible to ALTER PRIMARY KEY to a column that's already
# inverted indexed.

statement ok
DROP TABLE pkt;
CREATE TABLE pkt (a INT PRIMARY KEY, b TEXT NOT NULL, INVERTED INDEX(b gin_trgm_ops));
INSERT INTO pkt VALUES (1, 'abcd'), (2, 'bcde')

statement error primary key column b cannot be present in an inverted index
ALTER TABLE pkt ALTER PRIMARY KEY USING COLUMNS (b)

# Ensure that it's okay to perform an inverted filter on a table with a trigram
# inverted index that only has a forward statistic collected on the inverted
# column.

statement ok
CREATE TABLE b (a) AS SELECT encode(set_byte('foobar ',1,g), 'escape') || g::text FROM generate_series(1,1000) g(g)

statement ok
ANALYZE b

statement ok
CREATE INVERTED INDEX ON b(a gin_trgm_ops)

query T rowsort
SELECT * FROM b WHERE a LIKE '%foo%'
----
foobar 111
foobar 367
foobar 623
foobar 879

# Ensure that scans still work after we re-analyze.

statement ok
ANALYZE b

query T rowsort
SELECT * FROM b WHERE a LIKE '%foo%'
----
foobar 111
foobar 367
foobar 623
foobar 879

statement ok
CREATE INDEX on b(a);
ANALYZE b

query T rowsort
SELECT * FROM b WHERE a LIKE '%foo%'
----
foobar 111
foobar 367
foobar 623
foobar 879

query T
SELECT * FROM b WHERE a = 'foobar 367'
----
foobar 367


# Regression tests for #84512. Do not allow opclasses for non-inverted columns.

statement error pgcode 42804 operator classes are only allowed for the last column of an inverted index
create table err (a int, index (a jsonb_ops));

statement error pgcode 42804 operator classes are only allowed for the last column of an inverted index
create table err (a int, index (a gin_trgm_ops));

statement error pgcode 42804 operator classes are only allowed for the last column of an inverted index
create table err (a int, index (a gist_trgm_ops));

statement error pgcode 42804 operator classes are only allowed for the last column of an inverted index
create table err (a int, b int, index (a gin_trgm_ops, b));

statement error pgcode 42804 operator classes are only allowed for the last column of an inverted index
create table err (a int, j json, inverted index (a gin_trgm_ops, j));

# Regression test for #86614. Do not display opclasses for non-inverted columns
# in SHOW CREATE TABLE.

statement ok
CREATE TABLE t86614 (a int, s STRING, INVERTED INDEX (a, s gist_trgm_ops), FAMILY (a, s))

query T
SELECT create_statement FROM [SHOW CREATE TABLE t86614]
----
CREATE TABLE public.t86614 (
  a INT8 NULL,
  s STRING NULL,
  rowid INT8 NOT VISIBLE NOT NULL DEFAULT unique_rowid(),
  CONSTRAINT t86614_pkey PRIMARY KEY (rowid ASC),
  INVERTED INDEX t86614_a_s_idx (a ASC, s gin_trgm_ops),
  FAMILY fam_0_a_s_rowid (a, s, rowid)
)

# Regression test for #88925. Return correct result with a variable on the RHS
# of LIKE.
statement ok
CREATE TABLE t88558 (
  a INT PRIMARY KEY,
  b TEXT,
  INVERTED INDEX (b gin_trgm_ops)
);
INSERT INTO t88558 VALUES (1, '%');

query IT
SELECT * FROM t88558 WHERE 'aab':::STRING LIKE b;
----
1  %

# Regression test for #89609. Pad trigrams when building inverted spans for
# similarity filters.
statement ok
CREATE TABLE t89609 (
  t TEXT,
  INVERTED INDEX idx (t gin_trgm_ops)
);
INSERT INTO t89609 VALUES ('aaaaaa');
SET pg_trgm.similarity_threshold=.3

query T
SELECT t FROM t89609@primary WHERE t::STRING % 'aab';
----
aaaaaa

query T
SELECT t FROM t89609@idx WHERE t::STRING % 'aab';
----
aaaaaa

subtest end

# Regression test for issue #112713
subtest 112713

statement ok
CREATE TABLE t_112713 (i INT PRIMARY KEY, t STRING, FAMILY (i, t));

statement ok
CREATE INVERTED INDEX ON t_112713 (t gin_trgm_ops);

query T
SELECT create_statement FROM [SHOW CREATE TABLE t_112713];
----
CREATE TABLE public.t_112713 (
    i INT8 NOT NULL,
    t STRING NULL,
    CONSTRAINT t_112713_pkey PRIMARY KEY (i ASC),
    INVERTED INDEX t_112713_t_idx (t gin_trgm_ops),
    FAMILY fam_0_i_t (i, t)
)

subtest end

# Regression test for hitting an internal error on string-like datums (e.g NAME).
statement ok
CREATE TABLE t117758 (
  col1 VARCHAR NOT NULL,
  col2 NAME NOT NULL,
  INVERTED INDEX (col2 gin_trgm_ops)
);
SELECT
    tab.col1_1
FROM
    t117758 AS tab2
    JOIN (
            SELECT
                'foo'::NAME, 'bar'::NAME
            FROM
                t117758 AS tab3
                JOIN t117758 AS tab4 ON
                        (tab3.col2) = (tab4.col2)
        )
            AS tab (col1_1, col1_2) ON
            (tab2.col1) = (tab.col1_1)
            AND (tab2.col2) = (tab.col1_2);
