Skip to content
This repository has been archived by the owner on Feb 24, 2024. It is now read-only.

Query Grammer #228

Open
saberistic opened this issue Nov 17, 2017 · 9 comments
Open

Query Grammer #228

saberistic opened this issue Nov 17, 2017 · 9 comments
Labels
references Technical reference.

Comments

@saberistic
Copy link

Is there any sort of documentation on what is the grammer for postgrest queries?

@ruslantalpa
Copy link
Contributor

ruslantalpa commented Nov 17, 2017

literally at the top of the projects github page :) .... https://postgrest.com

@begriffs
Copy link
Member

@ruslantalpa, please be respectful to people's questions on this project.

@amirsaber I'd like to get a better idea about your question. Are you wondering if there is a BNF sort of grammar describing the syntax of queries on the URL?

@begriffs begriffs reopened this Nov 17, 2017
@saberistic
Copy link
Author

@ruslantalpa thanks unfortunatly I couldn't find what I was looking for there.
@begriffs Yes, I was looking for something like a BNF.

@begriffs
Copy link
Member

begriffs commented Nov 17, 2017

The short answer is there is no exhaustive grammar in the docs, although there are examples of use.

This may be less helpful than you hoped, but here's the relevant part of the code:

The Parsers.hs file contains a number of p- prefixed functions, which are parsers. If you look through that file it kind of reads like a grammar because it uses the parsec library to define the language.

@saberistic
Copy link
Author

@begriffs thanks I will read through it and if I could write a BNF for it I will definitely share. I really enjoyed your projects and we are using it in production for some serious services. It's amazing

@saberistic
Copy link
Author

saberistic commented Nov 18, 2017

This is my first try to define the language and it's been a while that I didn't do this. Please help and correct me if I am making a mistake.
The reason that I am doing this is that I want to write a typescript client library for postgrest and I want to understand the language fully to be able to design it to my best knowledge.

<query> ::= <parts>

<parts> ::= <clause> | <parts>&<parts>

<clause> ::= "select=" <select> | "order=" <repeat> | "limit=" <integer> | "offset=" <integer> | <filter>

<select> ::= <column> | <select>,<select>

<column> ::= <column-name> | <relation>

<column-name> ::= <string> | "*"

<relation> ::= <string>"(" <column> ")" | <string> ":" <string> "(" <column> ")"

<filter> ::= <string> "=" <filter-type1> "." <string> | <string> "=" <filter-type2> ".(" <repeat> ")" | "and=(" <and-or> ")" | "or=(" <and-or> ")"

<repeat> ::= <repeat>,<repeat> | <string>

<filter-type1> ::= "eq" | "gt" | "gte" | "lt" | "lte" | "neq" | "like" | "ilike" | "is" | "fts" | "not"

<filter-type2> ::= "in" | "cs" | "cd" | "ov" | "sl" | "sr" | "nxr" | "nxl" | "adj"

<and-or> ::= <and-or> "," <and-or> | "or(" <and-or> ")" | "and(" <and-or> ")" | <and-or-clause>

<and-or-clause> ::= <string> "." <filter-type1> "." <string> | <string> "." <filter-type2> ".(" R ")"

@begriffs
Copy link
Member

Thanks @amirsaber, that looks accurate to me. @steve-chavez can you confirm? If it's all good I'll add it to docs.

@saberistic
Copy link
Author

saberistic commented Nov 21, 2017

@begriffs There was a missing part in for renaming relation using ":" notion that I added, I also moved the "and or" part from to rule

@steve-chavez
Copy link
Member

steve-chavez commented Nov 26, 2017

Good initiative @amirsaber, I've improved your proposed BNF a bit, the ABNF:

; An example base-url would be http://my.domain.com/rest/, this definition is omitted for brevity.
path = base-url (table / rpc)

table = identifier ["?" query-param]

query-param = query-param "&" query-param

query-param =/ "select=" select-item / "columns=" columns / "on_conflict=" on-conflict ; these don't have an embed-path

query-param =/ *(embed-path) (filter / "order=" order / "limit=" integer / "offset=" integer / ("and"/"or") "=" "(" and-or ")")

embed-path = identifier "." 

select-item = [alias] field [cast] / embed / "*" / select-item "," select-item

alias = identifier ":"

field = identifier / json-path

cast = "::" identifier

embed = [alias] identifier [embed-hint] "(" select-item ")"

embed-hint = "!" identifier

filter = field "=" operation

operation = ["not."] (operator "." val / "in." in-val)

operator = "eq" / "gt" / "gte" / "lt" / "lte" / "neq" / "like" / "ilike" / "is" / "fts" / "cs" / "cd" / "ov" / "sl" / "sr" / "nxr" / "nxl" / "adj"

order = identifier [".asc"/".desc"] [".nullsfirst"/".nullslast"] / order "," order

and-or = field "." and-or-operation / ("and"/"or") "(" and-or ")"/ and-or "," and-or

and-or-operation = ["not."] (operator "." maybe-quoted-val / "in." in-val)

rpc = "rpc/" identifier ["?" rpc-query]

rpc-query = query / arg

arg = identifier "=" val / arg "&" arg

json-path  = identifier 1*("->" identifier) "->>" identifier

in-val = "(" maybe-quoted-val *("," maybe-quoted-val) ")"

maybe-quoted-val = val / DQUOTE val DQUOTE

identifier = 1*((ALPHA / DIGIT / "_") ["-"])

integer = 1*DIGIT

val = *CHAR

@begriffs @ruslantalpa see if I've made any mistake.

Edit: Added quoted vals inside and-or.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
references Technical reference.
Development

No branches or pull requests

4 participants