From c13e751e6aa88043fc5ce0e64d67ccfb5746c5a7 Mon Sep 17 00:00:00 2001 From: ullingerc Date: Fri, 14 Aug 2026 14:13:43 +0200 Subject: [PATCH 1/2] Allow reading query for `qlever materialized-view` from `Qleverfile` If the user calls `qlever materialized-view NAME QUERY` without a `QUERY`, we now look if a view with name `NAME` is defined in the `Qleverfile` and if yes, use that query. Useful for rewriting a view defined in the `Qleverfile`. --- src/qlever/commands/materialized_view.py | 31 +++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/qlever/commands/materialized_view.py b/src/qlever/commands/materialized_view.py index 531dc470..cf70f788 100644 --- a/src/qlever/commands/materialized_view.py +++ b/src/qlever/commands/materialized_view.py @@ -4,9 +4,11 @@ import re import shlex import time +from pathlib import Path from qlever.command import QleverCommand from qlever.log import log +from qlever.qleverfile import Qleverfile from qlever.util import ( run_command, ) @@ -158,12 +160,35 @@ def execute(self, args) -> bool: log.info(f"Materialized view '{view_name}' loaded") return True + # If no query was given, try to take it from MATERIALIZED_VIEWS in + # the Qleverfile (same key as used by `qlever index`). Read + # directly instead of via `relevant_qleverfile_arguments`, which + # would also add an (unwanted) `--materialized-views` option. + if args.view_query is None: + qleverfile_path = Path(getattr(args, "qleverfile", "Qleverfile")) + if qleverfile_path.is_file(): + try: + qleverfile_config = Qleverfile.read(qleverfile_path) + materialized_views = json.loads( + qleverfile_config.get( + "index", "materialized_views", fallback="{}" + ) + ) + except Exception as e: + log.error( + "Failed to read MATERIALIZED_VIEWS from " + f"`{qleverfile_path}`: {e}" + ) + return False + args.view_query = materialized_views.get(args.view_name) + # A query is required when creating a materialized view. if args.view_query is None: log.error( - "A query is required when creating a materialized view" - " (use --load to load an existing one, or --delete to" - " delete one)" + f"No query given for materialized view '{args.view_name}', " + "and none found for it in MATERIALIZED_VIEWS in the " + "Qleverfile (use --load to load an existing one, or " + "--delete to delete one)" ) return False From b9dea0f55d988c4368370d4de2312a730f2593a7 Mon Sep 17 00:00:00 2001 From: ullingerc Date: Fri, 21 Aug 2026 13:59:13 +0200 Subject: [PATCH 2/2] fix --- src/qlever/commands/materialized_view.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qlever/commands/materialized_view.py b/src/qlever/commands/materialized_view.py index cf70f788..51b82267 100644 --- a/src/qlever/commands/materialized_view.py +++ b/src/qlever/commands/materialized_view.py @@ -172,7 +172,8 @@ def execute(self, args) -> bool: materialized_views = json.loads( qleverfile_config.get( "index", "materialized_views", fallback="{}" - ) + ).strip() + or "{}" ) except Exception as e: log.error(