posit-dev / posit-dev/ggsql-duckdb

Non-integer PLACE rule position values break scale continuity / cause binder errors depending on layer type

Open
#13 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
32
Forks
1
PR merge metrics
No merged PRs in 30d

Description

Environment: ggsql-duckdb v0.3.2 and v0.4.1, DuckDB v1.5.3 and v1.5.4
Symptom A — Binder error with histogram:

SELECT CAST(20 + 40 * random() AS DOUBLE) AS value
FROM range(500)
VISUALISE value AS x
DRAW histogram
PLACE rule
  SETTING x => 44.4
Binder Error: No function matches the given name and argument types '-(VARCHAR, DECIMAL(12,10))'
LINE 1: ...GROUP BY (GREATEST(0, CEIL(("__ggsql_aes_pos1__" - 20.0171901952 + 1.3783433384 * 0.5) / 1.3783433384) -...

Symptom B — Silent scale-type flip (continuous → discrete) with point:

SELECT
    CAST(random() * 50 AS DOUBLE) AS x_val,
    CAST(random() * 50 AS DOUBLE) AS y_val
FROM range(50)
VISUALISE x_val AS x, y_val AS y
DRAW point
PLACE rule
  SETTING x => 21.5

No error is thrown, but the x-axis silently switches from a continuous numeric scale to a discrete categorical scale — every individual random value is rendered as its own axis category (long decimal tick labels), instead of a normal 0–50 continuous range.
Both symptoms disappear when the PLACE rule value is an integer:

-- Works, no error, x-axis stays continuous:
... PLACE rule SETTING x => 44   -- with histogram
... PLACE rule SETTING x => 22   -- with point

Root cause hypothesis: Supplying a non-integer literal to a PLACE rule position aesthetic appears to interfere with scale-type deduction for the whole visualisation. With histogram, this manifests as a binder error because the rule's non-integer value gets incorrectly folded into the histogram's own generated bin-index computation. With point, no computation is shared, so it doesn't error — but the scale still incorrectly gets deduced/coerced as discrete instead of continuous, likely due to the same underlying type-handling issue for non-integer literals in PLACE rule.
Expected: PLACE rule should accept any numeric literal (integer or decimal) without affecting the scale type of other layers or causing binder errors.
Workaround: round PLACE rule position values to the nearest integer.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the histogram and point examples in ggsql-duckdb with decimal and integer PLACE rule values, then trace PLACE rule position handling and scale-type deduction in the Rust extension. Done means decimal numeric positions work for both layers, continuous scales remain continuous, and the histogram no longer produces a binder error.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust, sql
Domain
data-visualization
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
50/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.