Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pg_textsearch-windows-msvc

Windows x64 builds of pg_textsearch for PostgreSQL 18, plus a companion build of pgvector, together with the complete recipe that produces them.

Why this exists

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.

Trust

Binaries from a stranger on the internet deserve suspicion. Three independent ways to satisfy yourself are offered, in increasing order of strength.

1. Checksums

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 SHA256

This only proves the download was not corrupted or swapped in transit. It says nothing about who built the file or from what.

2. Build provenance attestation

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-msvc

A 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.

3. Build it yourself

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.bat through vswhere, 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 only

The 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.

Install

  1. Download the zip for the extension you want from the releases page, and verify it (see above).

  2. 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\NOTICE
    

    Extracting requires administrator rights if PostgreSQL is under C:\Program Files. Nothing outside lib\, share\extension\ and share\doc\extension\ is written, so no PostgreSQL file is overwritten.

  3. pg_textsearch must be preloaded. Add it to shared_preload_libraries in postgresql.conf (in your data directory, for example C:\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.

  4. Restart the PostgreSQL service:

    Restart-Service postgresql-x64-18
  5. 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.

Compatibility

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.

What the patch changes

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 /FI and defines __attribute__(x) to nothing under _MSC_VER. The remaining uses of __attribute__ in the tree are unused (advisory only) and aligned(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 StaticAssertDecl checks pinning sizeof, offsetof and _Alignof of every struct that carried a GCC attribute to the values the reference GCC x86-64 build produces. build.ps1 compiles 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 prints LAYOUT GATE: PASS when it holds.

Additional checks performed by the build:

  • The pinned upstream commit is verified with git rev-parse after checkout.
  • The patch is dry-run with git apply --check before being applied.
  • The 41 source files compiled are cross-checked against the upstream Makefile OBJS variable, and the 20 SQL files packaged are read out of the upstream Makefile DATA variable, so the package cannot drift from what upstream installs. (The three legacy full-install scripts pg_textsearch--0.3.0.sql, --0.4.0.sql and --0.5.0.sql sit in the upstream sql/ directory but are not in DATA, and are therefore not shipped, matching a normal make install.)
  • The extension version in pg_textsearch.control is checked against the version this recipe claims to build.
  • After linking, the 34 C symbols referenced by pg_textsearch--1.3.1.sql are checked against the DLL export table, so a missing PGDLLEXPORT fails the build instead of failing later at CREATE EXTENSION. The build prints EXPORT GATE: PASS (34 install-script symbols, 75 exports total).

What is not covered

  • The upstream regression suite is not run. It is driven by pg_regress and 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.

Repository layout

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

License

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 LICENSE and NOTICE are included in the zip under share\doc\extension\pg_textsearch\.
  • pgvector carries copyright notices for the PostgreSQL Global Development Group and the Regents of the University of California. Its LICENSE is included in the zip under share\doc\extension\vector\.

About

Windows (MSVC) builds and reproducible build recipe for the pg_textsearch and pgvector PostgreSQL extensions

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages