Skip to content

Commit 944a4fd

Browse files
authored
Fix evaluate limit bug (#388)
* Fix evaluate limit bug * Only use model LIMIT if no limit is provided in evaluate * Fix import * Fix import * PR feedback
1 parent 5344afd commit 944a4fd

3 files changed

Lines changed: 36 additions & 4 deletions

File tree

sqlmesh/core/constants.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,6 @@
2828

2929
JINJA_MACROS = "JINJA_MACROS"
3030
"""Used to store jinja macros in the execution env."""
31+
32+
DEFAULT_MAX_LIMIT = 1000
33+
"""The default maximum row limit that is used when evaluating a model."""

sqlmesh/core/context.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
import pandas as pd
4444
from sqlglot import exp
45+
from sqlglot.executor import execute
4546

4647
from sqlmesh.core import constants as c
4748
from sqlmesh.core._typing import NotificationTarget
@@ -55,7 +56,7 @@
5556
from sqlmesh.core.hooks import hook
5657
from sqlmesh.core.loader import Loader, SqlMeshLoader, update_model_schemas
5758
from sqlmesh.core.macros import ExecutableOrMacro
58-
from sqlmesh.core.model import Model
59+
from sqlmesh.core.model import Model, SqlModel
5960
from sqlmesh.core.plan import Plan
6061
from sqlmesh.core.scheduler import Scheduler
6162
from sqlmesh.core.snapshot import (
@@ -521,7 +522,10 @@ def evaluate(
521522
start: The start of the interval to evaluate.
522523
end: The end of the interval to evaluate.
523524
latest: The latest time used for non incremental datasets.
524-
limit: A limit applied to the model, this must be > 0.
525+
limit: A limit applied to the model, this must be > 0. If this argument is omitted
526+
and the model contains a LIMIT clause, then the clause's expression will be used
527+
instead. In any case, the final limit is bounded by the DEFAULT_MAX_LIMIT constant.
528+
Default: DEFAULT_MAX_LIMIT
525529
"""
526530
if isinstance(model_or_snapshot, str):
527531
snapshot = self.snapshots[model_or_snapshot]
@@ -531,15 +535,20 @@ def evaluate(
531535
snapshot = self.snapshots[model_or_snapshot.name]
532536

533537
if not limit or limit <= 0:
534-
limit = 1000
538+
limit = c.DEFAULT_MAX_LIMIT
539+
if isinstance(snapshot.model, SqlModel):
540+
model_limit = snapshot.model.render_query().args.get("limit")
541+
542+
if model_limit:
543+
limit = min(limit, execute(exp.select(model_limit.expression)).rows[0][0])
535544

536545
df = self.snapshot_evaluator.evaluate(
537546
snapshot,
538547
start,
539548
end,
540549
latest,
541550
snapshots=self.snapshots,
542-
limit=limit,
551+
limit=t.cast(int, limit),
543552
)
544553

545554
if df is None:

tests/core/test_context.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import sqlmesh.core.constants
99
from sqlmesh.core.config import Config, ModelDefaultsConfig
1010
from sqlmesh.core.context import Context
11+
from sqlmesh.core.dialect import parse
12+
from sqlmesh.core.model import load_model
1113
from sqlmesh.core.plan import BuiltInPlanEvaluator, Plan
1214
from sqlmesh.utils.errors import ConfigError
1315
from tests.utils.test_filesystem import create_temp_file
@@ -234,6 +236,24 @@ def test_diff(sushi_context: Context, mocker: MockerFixture):
234236
assert mock_console.show_model_difference_summary.called
235237

236238

239+
def test_evaluate_limit():
240+
context = Context(config=Config())
241+
242+
context.upsert_model(
243+
load_model(
244+
parse(
245+
"""
246+
MODEL(name limit_test, kind FULL);
247+
SELECT t.v as v FROM (VALUES (1), (2), (3), (4), (5)) AS t(v) LIMIT 1 + 2"""
248+
)
249+
)
250+
)
251+
252+
assert context.evaluate("limit_test", "2020-01-01", "2020-01-02", "2020-01-02").size == 3
253+
assert context.evaluate("limit_test", "2020-01-01", "2020-01-02", "2020-01-02", 4).size == 4
254+
assert context.evaluate("limit_test", "2020-01-01", "2020-01-02", "2020-01-02", 2).size == 2
255+
256+
237257
def test_ignore_files(mocker: MockerFixture, tmpdir):
238258
mocker.patch.object(
239259
sqlmesh.core.constants,

0 commit comments

Comments
 (0)