From ed9686a36b73975cce2c6e5002349863d0ca79e8 Mon Sep 17 00:00:00 2001 From: Kari Barry <kezzsim@gmail.com> Date: Tue, 24 Oct 2023 16:22:35 -0400 Subject: [PATCH] =?UTF-8?q?Enable=20GIN=20index=20scans=20on=20metadata=20?= =?UTF-8?q?=3D=20queries=20=F0=9F=94=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tiled/catalog/adapter.py | 13 +++++++++++-- tiled/catalog/core.py | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/tiled/catalog/adapter.py b/tiled/catalog/adapter.py index 52f58df72..1ed736a60 100644 --- a/tiled/catalog/adapter.py +++ b/tiled/catalog/adapter.py @@ -6,7 +6,7 @@ import shutil import sys import uuid -from functools import partial +from functools import partial, reduce from pathlib import Path from urllib.parse import quote_plus, urlparse @@ -938,9 +938,18 @@ def _prepare_structure(structure_family, structure): def binary_op(query, tree, operation): dialect_name = tree.engine.url.get_dialect().name - attr = orm.Node.metadata_[query.key.split(".")] + keys = query.key.split(".") + attr = orm.Node.metadata_[keys] if dialect_name == "sqlite": condition = operation(_get_value(attr, type(query.value)), query.value) + # specific case where GIN optomized index can be used to speed up POSTGRES equals queries + elif dialect_name == "postgresql" and operation == operator.eq: + condition = orm.Node.metadata_.op("@>")( + type_coerce( + {keys[0]: reduce(lambda x, y: {y: x}, keys[1:][::-1], query.value)}, + orm.Node.metadata_.type, + ) + ) else: condition = operation(attr, type_coerce(query.value, orm.Node.metadata_.type)) return tree.new_variation(conditions=tree.conditions + [condition]) diff --git a/tiled/catalog/core.py b/tiled/catalog/core.py index 2e7ebdd59..6340b12bd 100644 --- a/tiled/catalog/core.py +++ b/tiled/catalog/core.py @@ -17,7 +17,7 @@ async def initialize_database(engine): async with engine.connect() as connection: # Install extensions - if (engine.dialect.name == "postgresql"): + if engine.dialect.name == "postgresql": await connection.execute(text("create extension btree_gin;")) # Create all tables. await connection.run_sync(Base.metadata.create_all)