Windows x64 builds of pg_textsearch for PostgreSQL 18, plus a companion build of pgvector, together with the complete recipe that produces them.
pg_textsearch is a BM25 full text search index for PostgreSQL. Upstream builds it with PGXS and GCC or Clang, and does not ship or support Windows binaries. The open upstream request for Windows support is timescale/pg_textsearch#82.
Getting it to build with MSVC needs a small, mechanical patch (described in detail below) and a hand written compiler driver, because PGXS cannot be used on MSVC. That work is done here, in the open, so that anyone running PostgreSQL 18 on Windows can install the extension without setting up a toolchain first.
pgvector is included because pg_textsearch is most often used next to it, for
hybrid keyword plus vector search. pgvector already supports MSVC officially,
so it needs no patches at all: this repository simply runs the upstream
nmake /F Makefile.win procedure and packages the result the same way, so both
extensions come from one place with one trust story.
This repository is not affiliated with Timescale/Tiger Data or with the pgvector project.
Binaries from a stranger on the internet deserve suspicion. Three independent ways to satisfy yourself are offered, in increasing order of strength.
Every release carries a SHA256SUMS file listing the SHA-256 of each zip.
Verify after downloading:
Get-FileHash .\pg_textsearch-v1.3.1-pg18-windows-amd64.zip -Algorithm SHA256This only proves the download was not corrupted or swapped in transit. It says nothing about who built the file or from what.
Every release artifact is built by the public GitHub Actions workflow in this repository (.github/workflows/release.yml) and attested with actions/attest-build-provenance. The attestation is a signed statement, recorded in a public transparency log, that binds each zip to the workflow run, the commit, and the repository that produced it. Nothing is ever uploaded from a developer machine.
Verify with the GitHub CLI:
gh attestation verify .\pg_textsearch-v1.3.1-pg18-windows-amd64.zip --repo nikitatsym/pg_textsearch-windows-msvc
gh attestation verify .\pgvector-v0.8.5-pg18-windows-amd64.zip --repo nikitatsym/pg_textsearch-windows-msvcA successful verification means the file really was produced by this
repository's workflow, from the source you can read here. Combined with the
fact that the workflow only runs build.ps1, which is in this repository, that
covers the whole path from upstream source to zip.
The build is a single self contained PowerShell script. It clones both upstreams at pinned commits, applies the patch, and stages the zips.
Requirements:
- Visual Studio Build Tools 2022 with the "Desktop development with C++"
workload (the script finds
vcvars64.batthroughvswhere, falling back to the standard install paths). - Git.
- A PostgreSQL 18 x64 tree for headers and
postgres.lib. Either an installed PostgreSQL 18, or just the extracted EDB binaries zip (no installation needed).
.\build.ps1 # uses C:\Program Files\PostgreSQL\18
.\build.ps1 -PgRoot D:\pgsql -OutDir D:\out # any PostgreSQL 18 tree
.\build.ps1 -SkipPgvector # pg_textsearch onlyThe script is stage-only. It reads headers and postgres.lib from the
PostgreSQL tree and writes nothing into it. It never runs an install target
and never touches the PostgreSQL service. Everything lands in build\ and
dist\.
A note on bit-for-bit reproducibility: the recipe is fully pinned, but the resulting zips are not byte identical between runs, because MSVC stamps a timestamp and a build GUID into the PE header and the zip records file modification times. Rebuilds are functionally identical (same size, same 75 exported symbols, same dependency list), not hash identical. This is exactly why the provenance attestation in level 2 matters: it, rather than a hash comparison, is what ties a specific binary to a specific public build.
-
Download the zip for the extension you want from the releases page, and verify it (see above).
-
Extract it over your PostgreSQL 18 installation directory, for example
C:\Program Files\PostgreSQL\18. The zip mirrors the PostgreSQL tree, so the files land where PostgreSQL expects them:lib\pg_textsearch.dll share\extension\pg_textsearch.control share\extension\pg_textsearch--*.sql share\doc\extension\pg_textsearch\LICENSE share\doc\extension\pg_textsearch\NOTICEExtracting requires administrator rights if PostgreSQL is under
C:\Program Files. Nothing outsidelib\,share\extension\andshare\doc\extension\is written, so no PostgreSQL file is overwritten. -
pg_textsearch must be preloaded. Add it to
shared_preload_librariesinpostgresql.conf(in your data directory, for exampleC:\Program Files\PostgreSQL\18\data\postgresql.conf):shared_preload_libraries = 'pg_textsearch'If the setting already has entries, append to the comma separated list. pgvector does not need this.
-
Restart the PostgreSQL service:
Restart-Service postgresql-x64-18
-
Create the extension in each database that needs it:
CREATE EXTENSION pg_textsearch; CREATE EXTENSION vector;
To uninstall, DROP EXTENSION, remove the setting from
shared_preload_libraries, restart, and delete the files listed above.
| Component | Version | Source commit |
|---|---|---|
| pg_textsearch | 1.3.1 | 578ff529894992fb9e67cae4c69424e65c84868e |
| pgvector | 0.8.5 | 159b79aaad5983fb7459c1e3df2897fbb2d11788 |
- PostgreSQL 18, x64 only. There are no builds for PostgreSQL 17 or earlier, no 32-bit builds, and no ARM64 builds.
- Built against PostgreSQL 18.4 (EDB distribution) with MSVC 19.44 (Visual Studio Build Tools 2022, toolset 14.44).
- PostgreSQL extension modules are tied to the server major version by ABI. These DLLs will not load into PostgreSQL 17 or 19.
- The binaries link against the Universal CRT and
VCRUNTIME140.dll, which the official PostgreSQL Windows distributions already install.
The full dependency list of pg_textsearch.dll is:
postgres.exe
KERNEL32.dll
VCRUNTIME140.dll
api-ms-win-crt-string-l1-1-0.dll
api-ms-win-crt-convert-l1-1-0.dll
api-ms-win-crt-math-l1-1-0.dll
api-ms-win-crt-runtime-l1-1-0.dll
No bundled third party DLLs, no static copies of anything.
The port is deliberately as small as it can be. Nothing about the algorithms, the on-disk format or the SQL surface is touched. The patch is patches/0001-msvc-port.patch, 167 lines, and it does exactly two things.
1. PGDLLEXPORT on the version-1 function declarations. On ELF platforms
every non-static symbol is exported by default, so upstream can declare
Datum tp_handler(PG_FUNCTION_ARGS); and be done. On Windows nothing is
exported from a DLL unless it is marked, and PostgreSQL's own PGDLLEXPORT
macro expands to __declspec(dllexport). Without this the extension links but
CREATE EXTENSION fails at the first AS 'MODULE_PATHNAME', '...' lookup. The
patch adds PGDLLEXPORT to the 18 affected declarations in
src/access/am.h, src/types/query.h and src/types/vector.h. This is the
same treatment PostgreSQL applies to its own contrib modules.
2. #pragma pack alongside __attribute__((packed)). Five structs are
packed on purpose because they describe on-disk index layout:
TpExpullEntry, TpSkipEntryV3, TpSkipEntry, TpCtidMapEntry and
TpSegmentPosting, in src/memtable/expull.h, src/segment/format.h and
src/segment/segment.h. MSVC ignores __attribute__((packed)), so the
definitions are wrapped in four #ifdef _MSC_VER / #pragma pack(push, 1) /
#pragma pack(pop) regions. The GCC attribute is left in place untouched, so
the patch is a no-op for every non-MSVC compiler.
Two supporting files live outside the upstream tree, so that no upstream source file has to reference anything new:
- msvc/msvc_shim.h is force-included with
/FIand defines__attribute__(x)to nothing under_MSC_VER. The remaining uses of__attribute__in the tree areunused(advisory only) andaligned(N)where N equals the natural alignment (a no-op). With packing handled by the pragmas above, erasing the attribute is layout preserving. - msvc/msvc_layout_check.c is the proof of that
claim rather than an assertion of it. It is a translation unit of 40
StaticAssertDeclchecks pinningsizeof,offsetofand_Alignofof every struct that carried a GCC attribute to the values the reference GCC x86-64 build produces.build.ps1compiles it first, before any extension source. If MSVC laid any of these structs out differently the build stops there, loudly, instead of producing a DLL that silently misreads index data. The build printsLAYOUT GATE: PASSwhen it holds.
Additional checks performed by the build:
- The pinned upstream commit is verified with
git rev-parseafter checkout. - The patch is dry-run with
git apply --checkbefore being applied. - The 41 source files compiled are cross-checked against the upstream
MakefileOBJSvariable, and the 20 SQL files packaged are read out of the upstreamMakefileDATAvariable, so the package cannot drift from what upstream installs. (The three legacy full-install scriptspg_textsearch--0.3.0.sql,--0.4.0.sqland--0.5.0.sqlsit in the upstreamsql/directory but are not inDATA, and are therefore not shipped, matching a normalmake install.) - The extension version in
pg_textsearch.controlis checked against the version this recipe claims to build. - After linking, the 34 C symbols referenced by
pg_textsearch--1.3.1.sqlare checked against the DLL export table, so a missingPGDLLEXPORTfails the build instead of failing later atCREATE EXTENSION. The build printsEXPORT GATE: PASS (34 install-script symbols, 75 exports total).
- The upstream regression suite is not run. It is driven by
pg_regressand shell scripts that assume a POSIX environment, so it does not execute on Windows as-is. The layout gate and the export check are compile-time and link-time evidence, not a substitute for the test suite. - Only PostgreSQL 18 x64 is built. Other major versions would each need their own build and their own testing.
- Upstream does not support Windows. Please do not open Windows-specific bug reports against timescale/pg_textsearch based on these binaries; open them here instead.
build.ps1 the entire build recipe
patches/0001-msvc-port.patch the MSVC port patch for pg_textsearch
msvc/msvc_shim.h force-included compatibility shim
msvc/msvc_layout_check.c compile-time struct layout gate
.github/workflows/release.yml public CI build, attestation and release
The build scripts, patch and supporting files in this repository are released under the PostgreSQL License. See LICENSE.
The packaged binaries are builds of third party software and carry their own upstream licenses, both of which are also the PostgreSQL License:
- pg_textsearch is copyright Timescale, Inc. d/b/a Tiger Data. Its
LICENSEandNOTICEare included in the zip undershare\doc\extension\pg_textsearch\. - pgvector carries copyright notices for the PostgreSQL Global Development
Group and the Regents of the University of California. Its
LICENSEis included in the zip undershare\doc\extension\vector\.