Skip to content
This repository was archived by the owner on May 27, 2026. It is now read-only.

Commit f92ffe4

Browse files
authored
feat: support postgres 18 (#884)
1 parent 11c09ff commit f92ffe4

9 files changed

Lines changed: 402 additions & 32 deletions

File tree

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jobs:
4040
runs-on: ubuntu-latest
4141
strategy:
4242
matrix:
43-
postgres-version: [16, 17]
43+
postgres-version: [16, 17, 18]
4444
fail-fast: false
4545

4646
steps:
@@ -189,7 +189,7 @@ jobs:
189189
runs-on: ubuntu-latest
190190
strategy:
191191
matrix:
192-
postgres-version: [15, 16, 17]
192+
postgres-version: [15, 16, 17, 18]
193193
fail-fast: false
194194

195195
steps:

projects/extension/Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# syntax=docker/dockerfile:1.3-labs
2-
ARG PG_MAJOR=17
3-
ARG PGVECTORSCALE_VERSION=0.5.1
2+
ARG PG_MAJOR=18
3+
ARG PGVECTORSCALE_VERSION=0.9.0
44

55
###############################################################################
66
# base image

projects/extension/justfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export PROJECT_JUSTFILE := "1" # Note: used in build.py
2-
PG_MAJOR := env("PG_MAJOR", "17")
2+
PG_MAJOR := env("PG_MAJOR", "18")
33
PG_BIN := env("PG_BIN", "/usr/lib/postgresql/" + PG_MAJOR + "/bin")
44

55
# Show list of recipes
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
DROP DATABASE
2+
CREATE DATABASE
3+
CREATE EXTENSION
4+
Objects in extension "ai"
5+
Object description
6+
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
7+
function ai.anthropic_generate(text,jsonb,integer,text,text,text,double precision,integer,text,text,text[],double precision,jsonb,jsonb,integer,double precision,boolean)
8+
function ai.anthropic_list_models(text,text,text,boolean)
9+
function ai.chunk_text_recursively(text,integer,integer,text[],boolean)
10+
function ai.chunk_text(text,integer,integer,text,boolean)
11+
function ai.cohere_chat_complete(text,jsonb,text,text,jsonb,jsonb,jsonb,jsonb,text,integer,text[],double precision,integer,double precision,double precision,integer,double precision,boolean,text,boolean,boolean)
12+
function ai.cohere_classify_simple(text,text[],text,text,jsonb,text,boolean)
13+
function ai.cohere_classify(text,text[],text,text,jsonb,text,boolean)
14+
function ai.cohere_detokenize(text,integer[],text,text,boolean)
15+
function ai.cohere_embed(text,text,text,text,text,text,boolean)
16+
function ai.cohere_list_models(text,text,text,boolean,boolean)
17+
function ai.cohere_rerank_simple(text,text,text[],text,text,integer,integer,boolean)
18+
function ai.cohere_rerank(text,text,text[],text,text,integer,integer,boolean)
19+
function ai.cohere_tokenize(text,text,text,text,boolean)
20+
function ai.execute_vectorizer(integer)
21+
function ai.grant_ai_usage(name,boolean)
22+
function ai.grant_secret(text,text)
23+
function ai.litellm_embed(text,text,text,text,jsonb,boolean)
24+
function ai.litellm_embed(text,text[],text,text,jsonb,boolean)
25+
function ai.load_dataset_multi_txn(text,text,text,name,name,text,jsonb,integer,integer,integer,jsonb)
26+
function ai.load_dataset(text,text,text,name,name,text,jsonb,integer,integer,jsonb)
27+
function ai.ollama_chat_complete(text,jsonb,text,text,jsonb,jsonb,jsonb,boolean)
28+
function ai.ollama_embed(text,text,text,text,jsonb,boolean)
29+
function ai.ollama_generate(text,text,text,bytea[],text,jsonb,text,text,integer[],boolean)
30+
function ai.ollama_list_models(text,boolean)
31+
function ai.ollama_ps(text,boolean)
32+
function ai.openai_chat_complete_simple(text,text,text,boolean,jsonb)
33+
function ai.openai_chat_complete(text,jsonb,text,text,double precision,jsonb,boolean,integer,integer,integer,integer,double precision,jsonb,integer,text,double precision,double precision,jsonb,text,text,jsonb,jsonb,jsonb,boolean,jsonb)
34+
function ai.openai_chat_complete_with_raw_response(text,jsonb,text,text,double precision,jsonb,boolean,integer,integer,integer,integer,double precision,jsonb,integer,text,double precision,double precision,jsonb,text,text,jsonb,jsonb,jsonb,boolean,jsonb)
35+
function ai.openai_client_config(text,double precision,text,text,integer,jsonb,jsonb)
36+
function ai.openai_detokenize(text,integer[])
37+
function ai.openai_embed(text,integer[],text,text,integer,text,jsonb,jsonb,jsonb,boolean,jsonb)
38+
function ai.openai_embed(text,text,text,text,integer,text,jsonb,jsonb,jsonb,boolean,jsonb)
39+
function ai.openai_embed(text,text[],text,text,integer,text,jsonb,jsonb,jsonb,boolean,jsonb)
40+
function ai.openai_embed_with_raw_response(text,integer[],text,text,integer,text,jsonb,jsonb,jsonb,boolean,jsonb)
41+
function ai.openai_embed_with_raw_response(text,text,text,text,integer,text,jsonb,jsonb,jsonb,boolean,jsonb)
42+
function ai.openai_embed_with_raw_response(text,text[],text,text,integer,text,jsonb,jsonb,jsonb,boolean,jsonb)
43+
function ai.openai_list_models(text,text,jsonb,jsonb,boolean,jsonb)
44+
function ai.openai_list_models_with_raw_response(text,text,jsonb,jsonb,boolean,jsonb)
45+
function ai.openai_moderate(text,text,text,text,jsonb,jsonb,jsonb,boolean,jsonb)
46+
function ai.openai_moderate_with_raw_response(text,text,text,text,jsonb,jsonb,jsonb,boolean,jsonb)
47+
function ai.openai_tokenize(text,text)
48+
function ai.reveal_secret(text,boolean)
49+
function ai.revoke_secret(text,text)
50+
function ai.voyageai_embed(text,text,text,text,text,boolean)
51+
function ai.voyageai_embed(text,text[],text,text,text,boolean)
52+
table ai.feature_flag
53+
table ai.migration
54+
table ai._secret_permissions
55+
type ai.feature_flag
56+
type ai.feature_flag[]
57+
type ai.migration
58+
type ai.migration[]
59+
type ai._secret_permissions
60+
type ai._secret_permissions[]
61+
type ai.secret_permissions
62+
type ai.secret_permissions[]
63+
view ai.secret_permissions
64+
(57 rows)
65+
66+
Table "ai._secret_permissions"
67+
Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
68+
--------+------+-----------+----------+---------+----------+-------------+--------------+-------------
69+
name | text | | not null | | extended | | |
70+
role | text | | not null | | extended | | |
71+
Indexes:
72+
"_secret_permissions_pkey" PRIMARY KEY, btree (name, role)
73+
Check constraints:
74+
"_secret_permissions_name_check" CHECK (name = '*'::text OR name ~ '^[A-Za-z0-9_.]+$'::text)
75+
Not-null constraints:
76+
"_secret_permissions_name_not_null" NOT NULL "name"
77+
"_secret_permissions_role_not_null" NOT NULL "role"
78+
Access method: heap
79+
80+
Index "ai._secret_permissions_pkey"
81+
Column | Type | Key? | Definition | Storage | Stats target
82+
--------+------+------+------------+----------+--------------
83+
name | text | yes | name | extended |
84+
role | text | yes | role | extended |
85+
primary key, btree, for table "ai._secret_permissions"
86+
87+
Table "ai.feature_flag"
88+
Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
89+
--------------------+--------------------------+-----------+----------+-------------------+----------+-------------+--------------+-------------
90+
name | text | | not null | | extended | | |
91+
applied_at_version | text | | not null | | extended | | |
92+
applied_at | timestamp with time zone | | not null | clock_timestamp() | plain | | |
93+
Indexes:
94+
"feature_flag_pkey" PRIMARY KEY, btree (name)
95+
Not-null constraints:
96+
"feature_flag_name_not_null" NOT NULL "name"
97+
"feature_flag_applied_at_version_not_null" NOT NULL "applied_at_version"
98+
"feature_flag_applied_at_not_null" NOT NULL "applied_at"
99+
Access method: heap
100+
101+
Index "ai.feature_flag_pkey"
102+
Column | Type | Key? | Definition | Storage | Stats target
103+
--------+------+------+------------+----------+--------------
104+
name | text | yes | name | extended |
105+
primary key, btree, for table "ai.feature_flag"
106+
107+
Table "ai.migration"
108+
Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
109+
--------------------+--------------------------+-----------+----------+-------------------+----------+-------------+--------------+-------------
110+
name | text | | not null | | extended | | |
111+
applied_at_version | text | | not null | | extended | | |
112+
applied_at | timestamp with time zone | | not null | clock_timestamp() | plain | | |
113+
body | text | | not null | | extended | | |
114+
Indexes:
115+
"migration_pkey" PRIMARY KEY, btree (name)
116+
Not-null constraints:
117+
"migration_name_not_null" NOT NULL "name"
118+
"migration_applied_at_version_not_null" NOT NULL "applied_at_version"
119+
"migration_applied_at_not_null" NOT NULL "applied_at"
120+
"migration_body_not_null" NOT NULL "body"
121+
Access method: heap
122+
123+
Index "ai.migration_pkey"
124+
Column | Type | Key? | Definition | Storage | Stats target
125+
--------+------+------+------------+----------+--------------
126+
name | text | yes | name | extended |
127+
primary key, btree, for table "ai.migration"
128+
129+
View "ai.secret_permissions"
130+
Column | Type | Collation | Nullable | Default | Storage | Description
131+
--------+------+-----------+----------+---------+----------+-------------
132+
name | text | | | | extended |
133+
role | text | | | | extended |
134+
View definition:
135+
SELECT name,
136+
role
137+
FROM ai._secret_permissions
138+
WHERE to_regrole(role) IS NOT NULL AND pg_has_role(CURRENT_USER, role::name, 'member'::text);
139+

projects/extension/tests/test_anthropic.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def test_anthropic_generate(cur, anthropic_api_key):
7979
with x as
8080
(
8181
select ai.anthropic_generate
82-
( 'claude-3-5-sonnet-20240620'
82+
( 'claude-sonnet-4-5-20250929'
8383
, jsonb_build_array
8484
( jsonb_build_object
8585
( 'role', 'user'
@@ -105,7 +105,7 @@ def test_anthropic_generate_api_key_name(cur_with_external_functions_executor_ur
105105
with x as
106106
(
107107
select ai.anthropic_generate
108-
( 'claude-3-5-sonnet-20240620'
108+
( 'claude-sonnet-4-5-20250929'
109109
, jsonb_build_array
110110
( jsonb_build_object
111111
( 'role', 'user'
@@ -129,7 +129,7 @@ def test_anthropic_generate_no_key(cur_with_api_key):
129129
with x as
130130
(
131131
select ai.anthropic_generate
132-
( 'claude-3-5-sonnet-20240620'
132+
( 'claude-sonnet-4-5-20250929'
133133
, jsonb_build_array
134134
( jsonb_build_object
135135
( 'role', 'user'

projects/extension/tests/test_openai.py

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -175,22 +175,6 @@ def test_openai_embed_with_raw_response(cur, openai_api_key):
175175
None,
176176
"Could not finish the message because max_tokens",
177177
),
178-
# OK.
179-
("o1-mini", {"max_completion_tokens": 10000}, False, None),
180-
# Stopped generating because max_tokens was reached.
181-
(
182-
"o1-mini",
183-
{"max_completion_tokens": 100},
184-
True,
185-
None,
186-
),
187-
# For some reason, o1-mini does not return a 400 status code in this case.
188-
(
189-
"o1-mini",
190-
{"max_completion_tokens": 1},
191-
True,
192-
None,
193-
),
194178
# Stopped generating because max_tokens was reached.
195179
("o3-mini", {"max_completion_tokens": 10000}, False, None), # OK.
196180
(
@@ -594,7 +578,7 @@ def test_openai_moderate(cur, openai_api_key):
594578
with x as
595579
(
596580
select ai.openai_moderate
597-
( 'text-moderation-stable'
581+
( 'omni-moderation-latest'
598582
, 'I want to kill them.'
599583
, api_key=>%s
600584
, extra_headers=>'{"X-Custom-Header": "my-value"}'
@@ -614,7 +598,7 @@ def test_openai_moderate_with_raw_response(cur, openai_api_key):
614598
cur.execute(
615599
"""
616600
select ai.openai_moderate
617-
( 'text-moderation-stable'
601+
( 'omni-moderation-latest'
618602
, 'I want to kill them.'
619603
, api_key=>%s
620604
, extra_headers=>'{"X-Custom-Header": "my-value"}'
@@ -633,7 +617,7 @@ def test_openai_moderate_api_key_name(cur_with_external_functions_executor_url):
633617
with x as
634618
(
635619
select ai.openai_moderate
636-
( 'text-moderation-stable'
620+
( 'omni-moderation-latest'
637621
, 'I want to kill them.'
638622
, api_key_name=> 'OPENAI_API_KEY_REAL'
639623
) as actual
@@ -651,7 +635,7 @@ def test_openai_moderate_no_key(cur_with_api_key):
651635
with x as
652636
(
653637
select ai.openai_moderate
654-
( 'text-moderation-stable'
638+
( 'omni-moderation-latest'
655639
, 'I want to kill them.'
656640
) as actual
657641
)

projects/pgai/db/build.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ def git_tag(version: str) -> str:
343343

344344

345345
def pg_major() -> str:
346-
return os.getenv("PG_MAJOR", "17")
346+
return os.getenv("PG_MAJOR", "18")
347347

348348

349349
def db_dir() -> Path:

0 commit comments

Comments
 (0)