node-pg-migrate icon indicating copy to clipboard operation
node-pg-migrate copied to clipboard

Support opclass_parameter in createIndex

Open benkroeger opened this issue 1 year ago • 2 comments

Description

Sometimes one might want to set parameters for specific opclasses when creating an index. E.g. when using the ltree extension, setting the siglen parameter can be crucial to performance of that index.

Currently, the entire 'opclass' param is converted to mOptions.literal - which leads to postgres not finding the opclass at all

pgm.createIndex('container', [{ name: 'path', opclass: 'gist_ltree_ops(siglen=256)' }], { method: 'gist' } );

creates

CREATE INDEX "container__path_index" ON "container" USING gist ("path" "gist_ltree_ops(siglen=256)");

which leads to

ERROR:  operator class "gist_ltree_ops(siglen=256)" does not exist for access method "gist" 

SQL state: 42704

because postgres doesn't expect the opclass + parameter to be quoted

CREATE INDEX "container__path_index" ON "container" USING gist ("path" gist_ltree_ops(siglen=256));

Suggested solution

  • treat opclass not as litera
  • do not quote when opclass contains parameters
  • exclude parameters from quoted opclass argument

Alternative

the sourcecode in 7.9.0 emits a warning when using opclass option and recommends a syntax that doesn't align with the exported type interface - but I think it could solve the issue. The 8.0.0-rc code doesn't emit that warning but uses the same opclass syntax and conversion as 7.9.0

Additional context

Current workaround is to include the opclass and parameters in the column name becuase detecting braces () in the name would treat them as expression and not quote at all

pgm.createIndex('container', [{ name: 'path gist_ltree_ops(siglen=256)' }], { method: 'gist' } );

benkroeger avatar Feb 24 '25 12:02 benkroeger

@benkroeger currently it's a good time to submit a PR and I can review.

Shinigami92 avatar Mar 01 '25 23:03 Shinigami92

note to whomever will look into this in the future

the 8.0.0 code handles this here it should check whether the opclass is "special" before using literal conversion - like it's done on the column name here

benkroeger avatar May 27 '25 13:05 benkroeger