fix(google_ads): honor LIMIT in handler select()#78
Merged
Conversation
For api-class handlers, plan_api_db_select forwards LIMIT to the handler and clears it from the outer SubSelectStep, so DuckDB never applies it. The Google Ads handler ignored query.limit, so entity tables (campaigns, ad_groups, ads, keywords) returned the whole account regardless of LIMIT. Add _limit_value / _all_conditions_pushable / _finalize helpers and wire all table classes to push LIMIT into the GAQL query and slice the DataFrame — but only when the WHERE is fully handled by pushdown (or absent), so a complex WHERE that DuckDB re-filters afterward cannot under-return. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
magroski
approved these changes
Jun 18, 2026
patrickadeelino
approved these changes
Jun 18, 2026
antoniocanhota
approved these changes
Jun 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
SELECT * FROM google_ads_….campaigns LIMIT 3returns the entire account (3553 campaigns, 192952 keywords, …) instead of 3 rows.Root cause: for
class_type = "api"handlers,plan_api_db_selectforwardsLIMITto the handler (query2.limit) and clears it from the outerSubSelectStep(query_planner.py:446). So DuckDB never applies LIMIT — the handler is solely responsible, and the Google Ads handler ignoredquery.limitentirely.The report tables (
campaign_performance,search_terms) only appeared to honor LIMIT because they returned 0 rows due to the empty default date range, not because LIMIT worked.Fix
Three helpers added to
google_ads_tables.py, wired into all 11 table classes:_limit_value(query)— extracts the LIMIT integer._all_conditions_pushable(conditions, col_map)— true only when every WHERE condition is pushed to GAQL._finalize(query, df, columns, can_limit)— selects columns and slicesdf.head(n)when safe.Each table now pushes
LIMIT ninto the GAQL query (so the API returns ≤ n rows instead of the whole account) and slices the DataFrame — but only when the WHERE is fully handled:languages/geo_targets: no WHERE.This gates against under-returning: a complex WHERE (e.g.
name LIKE '%a%') that DuckDB re-filters afterward leaves LIMIT off, so we never hand DuckDB fewer rows than it needs.Validation
Exercised
select()with a mocked Google Ads service (remote server has the connector but the local container does not):limit 3LIMIT 3, returns 3 ✅where status='ENABLED' limit 2where name like '%a%' limit 2🤖 Generated with Claude Code