Skip to content

memx://

PostgreSQL-protocol component that talks to the memx AI-native database. memx is wire-compatible with PostgreSQL but exposes additional vector / text / hybrid match functions (MATCH_DENSE, MATCH_TEXT, FUSION). The component uses pgx/v5 with a per-endpoint connection pool and supports both producer and consumer (polling) modes.

Use memx:// when you want one backing store that handles row-level data, dense-vector retrieval, BM25-style text retrieval, and reciprocal-rank fusion in a single SQL surface.

URI shape

memx://<host:port>/<database>?<params>

<host> defaults to localhost, <port> defaults to 5432, <database> defaults to memx. All three can also be packed into the dsn param.

Parameters

Param Type Default Producer/Consumer/Both Description
(path) host:port/database string localhost:5432/memx Both Server location.
dsn string derived Both Full PostgreSQL DSN. Wins over the path-derived form. The component appends default_query_exec_mode=simple_protocol when absent.
user string memx Both Username.
password string — Both Password.
table string — Both Target table. Required for insert, vector_search, text_search, hybrid_search.
operation enum query Both query, insert, vector_search, text_search, hybrid_search.
topK integer 10 Producer LIMIT for the three search operations.
column string embedding / content Producer vector_search uses embedding; text_search uses content. Override per call via this param.
vectorColumn string embedding Producer hybrid_search only — dense-vector column.
textColumn string content Producer hybrid_search only — text column.
pollInterval duration 30s Consumer How often the consumer issues SELECT * FROM <table> and dispatches results.

Operations

query (Producer)

Body: the SQL string. Executes it with no parameters; rows are returned as []map[string]any. Header memx.rowCount records the count.

insert

Body: map[string]any (or JSON object). Keys are sorted, identifiers are double-quoted (after a strict ^[a-zA-Z_][a-zA-Z0-9_.]*$ check), and the statement is INSERT INTO "table" (cols) VALUES ($1, …). Header memx.rowsAffected is set.

Set memx.vector header to a JSON array of floats. Generated SQL:

SELECT *, MATCH_DENSE("<column>", '[<vec>]') AS score
FROM "<table>" ORDER BY score DESC LIMIT <topK>

Body: the query text (string). Generated SQL:

SELECT *, MATCH_TEXT("<column>", $1) AS score
FROM "<table>" ORDER BY score DESC LIMIT <topK>

Set memx.vector header (JSON float array) and the body to the query text. Generated SQL:

SELECT *, FUSION('rrf',
   MATCH_DENSE("<vectorColumn>", '[<vec>]'),
   MATCH_TEXT("<textColumn>", $1)) AS score
FROM "<table>" ORDER BY score DESC LIMIT <topK>

Consumer

When from: memx://...?operation=query is wired, the consumer polls SELECT * FROM "<table>" every pollInterval and dispatches each non-empty result set as a new exchange (body: []map[string]any; headers: memx.rowCount, memx.table).

Headers

Read by the producer

Header Description
memx.vector vector_search / hybrid_search — JSON-encoded float array.

Written

Header Description
memx.rowCount Query / search row count.
memx.rowsAffected insert rows affected.
memx.table Consumer — table being polled.

Examples

Hybrid search:

workflows:
  - id: search
    trigger: { uri: direct://search }
    steps:
      - set-header:
          name: memx.vector
          starlang: |
            %sl 2.0
            output application/json
            input payload
            ---
            embed(payload.text)
      - target: memx://memx-cluster:5432/kb?table=docs&operation=hybrid_search&topK=10

Polling consumer feeding a Kafka topic:

workflows:
  - id: outbox
    trigger:
      uri: memx://localhost:5432/app?table=outbox_events&pollInterval=5s
    steps:
      - split:
          starlang: payload
      - target: kafka://events?bootstrap.servers=kafka:9092

Insert vector + metadata:

- set-body:
    starlang: |
      %sl 2.0
      output application/json
      input payload
      ---
      { "id": payload.id, "content": payload.text, "embedding": payload.vector }
- target: memx://localhost:5432/kb?table=docs&operation=insert

Behavior notes

  • Identifier safety — table and column names are matched against ^[a-zA-Z_][a-zA-Z0-9_.]*$ before being double-quoted into SQL. Anything else is rejected; no injection through table/column params.
  • simple_protocol exec mode — appended to the DSN so the memx-specific syntax (MATCH_DENSE([...])) round-trips without prepared-statement rewriting.
  • Vector literal format — vectorToString emits [0.1,0.2,...] — bracketed comma-separated floats with 'f', -1, 64 formatting.
  • Pool lifecycle — one pgxpool.Pool per producer or consumer; closed on Stop.

Source

pkg/component/memx/memx.go

See also

  • postgres — generic PostgreSQL component (no memx-specific functions).
  • memvec — pure-in-process vector store sibling.
  • sql — driver-agnostic SQL component.