pganalyze / libpg_query

C library for accessing the PostgreSQL parser outside of the server environment
BSD 3-Clause "New" or "Revised" License
1.21k stars 182 forks source link

How to support a new constraint type? #93

Open BowenXiao1999 opened 3 years ago

BowenXiao1999 commented 3 years ago

Hi team. I want to create a new syntax like create table t(v1 int, v2 int, SORT KEY (v1)) (It is not PG Grammar, I know). It is similar to create table t(v1 int, v2 int, PRIMARY KEY (v1)). The parser should return 2 ColumnDef node and 1 Constraint Node.

Currently my solution is to change source code of gram.y (src/postgres/gram.y). Do something similar like Primary Key. But after changing gram.y, I found the src/postgres/src_backend_parser_gram.c do not change accordingly. Therefore, the SORT KEY is treated as ColumnDef Node and it can not be parsed as Constraint type.

My question is: Should I re-bison the gram.y to some how make a new gram.c? Am I on the right track? Are there some official instructions to follow for this case?

Thanks for any suggestions!

lfittl commented 3 years ago

@BowenXiao1999 This isn't really a supported scenario for this library, but in case you want to maintain a fork with additional syntax, in addition to running the Postgres build process in a directory (which would turn the gram.y into a regular gram.c), you will then also need to run the extraction process that turns the regular Postgres server code into this library code.

You can find some background here: https://pganalyze.com/blog/pg-query-2-0-postgres-query-parser#using-libclang-to-extract-c-source-code-from-postgres

And the relevant script in the source tree: https://github.com/pganalyze/libpg_query/blob/13-latest/scripts/extract_source.rb (called from the Makefile here: https://github.com/pganalyze/libpg_query/blob/13-latest/Makefile#L105)

Please note that I don't really consider this something that is the goal of this library, so you'll be on your own in making this work. Depending on how far you want to deviate from the Postgres grammar, I would recommend looking at a different way of implementing this, e.g. by using an existing SQL parser that is self-contained and not associated with the complexities of the Postgres source.