denodrivers / postgres

PostgreSQL driver for Deno

Home Page:https://denodrivers.github.io/postgres

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error parsing trigram syntax

coreybutler opened this issue · comments

I'm trying to leverage pg_trgm to implement some basic search functionality with postgres. The following query correctly runs directly from clients like DBeaver, but fails in this module.

SELECT *
FROM datahub.datafield
WHERE 'resource' <% fuzzy_search

In this case, fuzzy_search is a generated field on datafield with a gin index.

In DBeaver:
image

Same query from Deno:
image

I cannot tell if this is user error or if the library isn't sending the query to postgres properly. Given the query only fails through this library, it makes me think something isn't being handled properly. I suspect the % is the culprit, but there doesn't seem to be a way to escape that or identify that it is part of the query.

Upon further inspection, it doesn't look like the problem is syntax. The core issue is the postgres extension isn't recognized when it should be (the extension is only applied to a specific schema). To solve this, the search_path must be specified in the connection, but it is easy to make mistakes if you're using a connection string instead of a config object.

The following configuration object worked.

const client = new Client({
  database: 'postgres',
  hostname: 'localhost',
  port: 5432,
  user: 'user',
  password: 'pwd',
  options: {
    search_path: 'myschema'
  }
})

My app uses connection strings. I was originally passing it in like this (which fails):

const client = new Client('postgres://postgres:pwd@localhost:5432/postgres?search_path=myschema')

This connection string works in pgwire and drivers in other languages, but fails in this library (which is why I never suspected it). I was able to make it work with a connection string by URL encoding the options... but I had to dig into the test suites to learn a -- prefix was required on the options. It'd be nice if there was an example of this in the documentation since it differs from how the other attributes are defined.

Here's what ultimately worked for me:

// The "--" part is important!
const client = new Client('postgres://postgres:pwd@localhost:5432/postgres?options=--search_path%3myschema')

The options value is the equivalent of encodeURIComponent('--search_path=myschema').

Hopefully this helps someone else save some time, or better yet, leads to a doc example.