Repository: Vanderhoof/PyDBML

Issue:
Indexes should support more types to deal with Postgresql indexes
Indexes seem to [support only hash and btree](https://github.com/Vanderhoof/PyDBML/blob/master/pydbml/parser/blueprints.py#L169)

But just to name Postgresql, [there are many other index types](https://www.postgresql.org/docs/current/indexes-types.html):

* [gist](https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPE-GIST)
* [sp-gitst](https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPE-SPGIST)
* [gin](https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN)
* [brin](https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-BRIN)

@Vanderhoof We can either add those values in the enum or maybe allow any kind of value, do you have an opinion on the subject?

Discussion:
@Vanderhoof: Hi @pierresouchay!
Thanks for raising this question. Originally I was relying on [the DBML docs](https://dbml.dbdiagram.io/docs#index-settings) saying:

> `type`: type of index (btree, gin, gist, hash depending on DB). **For now, only type btree and hash are accepted.**

But I just checked and saw that the official `dbml2sql` does accept arbitrary values for an index type, so I see no reason why we should limit it in PyDBML either.

And thanks for implementing the extra indexes, I will apply your PR shortly@pierresouchay: @Vanderhoof indeed, a colleague of mine had the issue with sql2dbml tool... Thanks a lot! 

PS: thank you for your work on this lib, and it would be amazing if you could do a release not before too long.@Vanderhoof: Sure, I will do the release within an hour!
[UPD: Done! ](https://github.com/Vanderhoof/PyDBML/releases/tag/1.1.3)

Solution patch:
diff --git a/pydbml/definitions/index.py b/pydbml/definitions/index.py
index 9364901..ed39fda 100644
--- a/pydbml/definitions/index.py
+++ b/pydbml/definitions/index.py
@@ -15,7 +15,12 @@ from pydbml.parser.blueprints import IndexBlueprint
 pp.ParserElement.set_default_whitespace_chars(' \t\r')
 
 index_type = pp.CaselessLiteral("type:").suppress() + _ - (
-    pp.CaselessLiteral("btree")('type') | pp.CaselessLiteral("hash")('type')
+    pp.CaselessLiteral("brin")('type') |
+    pp.CaselessLiteral("btree")('type') |
+    pp.CaselessLiteral("gin")('type') |
+    pp.CaselessLiteral("gist")('type') |
+    pp.CaselessLiteral("hash")('type') |
+    pp.CaselessLiteral("spgist")('type')
 )
 index_setting = _ + (
     unique('unique')
diff --git a/pydbml/parser/blueprints.py b/pydbml/parser/blueprints.py
index 5c7b3a2..614a251 100644
--- a/pydbml/parser/blueprints.py
+++ b/pydbml/parser/blueprints.py
@@ -166,7 +166,17 @@ class IndexBlueprint(Blueprint):
     subject_names: List[Union[str, ExpressionBlueprint]]
     name: Optional[str] = None
     unique: bool = False
-    type: Optional[Literal['hash', 'btree']] = None
+    type: Optional[
+        Literal[
+            # https://www.postgresql.org/docs/current/indexes-types.html
+            "brin",
+            "btree",
+            "gin",
+            "gist",
+            "hash",
+            "spgist",
+        ]
+    ] = None
     pk: bool = False
     note: Optional[NoteBlueprint] = None
     comment: Optional[str] = None


Test patch:
diff --git a/test/test_definitions/test_index.py b/test/test_definitions/test_index.py
index 4396998..b3239f4 100644
--- a/test/test_definitions/test_index.py
+++ b/test/test_definitions/test_index.py
@@ -20,12 +20,16 @@ ParserElement.set_default_whitespace_chars(' \t\r')
 
 class TestIndexType(TestCase):
     def test_correct(self) -> None:
-        val = 'Type: BTREE'
-        res = index_type.parse_string(val, parseAll=True)
-        self.assertEqual(res['type'], 'btree')
-        val2 = 'type:\nhash'
-        res2 = index_type.parse_string(val2, parseAll=True)
-        self.assertEqual(res2['type'], 'hash')
+        for val, expected in [
+            ("Type: BTREE", "btree"),
+            ("type: hash", "hash"),
+            ("type: gist", "gist"),
+            ("TYPE:SPGiST", "spgist"),
+            ("type: GIN", "gin"),
+            ("Type:\tbRiN", "brin"),
+        ]:
+            res = index_type.parse_string(val, parseAll=True)
+            self.assertEqual(res["type"], expected)
 
     def test_incorrect(self) -> None:
         val = 'type: wrong'