Visitar URL original
fix(#10137): INSERT INTO a TIMESERIES type no longer coerces a number into a BOOLEAN or STRING column by robfrank · Pull Request #10236 · ArcadeData/arcadedb · GitHub
Skip to content

fix(#10137): INSERT INTO a TIMESERIES type no longer coerces a number into a BOOLEAN or STRING column - #10236

Merged
robfrank merged 4 commits into
mainfrom
fix/10137-sql-insert-timeseries-coerces-number
Oct 18, 2026
Merged

robfrank merged 4 commits into
mainfrom
fix/10137-sql-insert-timeseries-coerces-number

Conversation

@robfrank

@robfrank robfrank commented Oct 17, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #10137

Summary

INSERT INTO <timeseries type> called ColumnDefinition.storableValue (#10064), but only after MutableDocument.convertValueToSchemaType had already run Type.convert on each value, because a TIMESERIES type declares its columns as schema properties. By the time saveToTimeSeries saw the value it was already the declared class, so bo = 7 was stored as true and s = 42 as "42". The line protocol, gRPC and Prometheus remote write refuse that same point. The document layer now leaves a non-temporal TAG/FIELD column of a TIMESERIES type alone (LocalTimeSeriesType.skipsDocumentConversion), so storableValue converts it exactly once. This fixes it where the row is built, so INSERT ... SET, CONTENT and (cols) VALUES all get it. As a side effect, an out-of-range number (b = 300 into a BYTE column) is now refused with storableValue's CommandExecutionException ("... column 'b': the number is out of range"). Before, the statement failed with a bare IllegalArgumentException.

The TIMESTAMP column and the DATE/DATETIME columns still go through the document conversion. On purpose: #9643/#9724 pinned SQL's contract that a number is epoch MILLIS for every datetime precision. The other surfaces read a number as a count in the column's own unit. Getting the two to agree is a separate decision, now tracked as #10233.

Finding ledger

# finding (issue) status
1 number -> BOOLEAN stored (1, 0, 7) fixed, refused like the gateway
2 number/boolean -> STRING stored as text (42, 4.25, true) fixed, refused like the gateway
3 secondary: document layer refuses first with a bare IllegalArgumentException (BYTE 300) fixed for non-temporal columns, now CommandExecutionException with the named reason
4 '1700000000000' -> DATETIME: SQL refuses, gateway stores deferred to #10233 (temporal number contract needs a decision)
5 guarantee: one table-driven test asserting SQL and gateway reach the same outcome added (theSqlInsertAndTheGatewayReachTheSameOutcomeForEveryPair, 40 pairs)

Completeness

Invariant: a value written by SQL to a non-temporal TIMESERIES column reaches ColumnDefinition.storableValue exactly as the statement produced it.

grep -rn "storableValue(" --include=*.java . | grep -v /test/ finds SaveElementStep:281 (SQL), TimeSeriesStorableRows:119,139 (line protocol, gRPC, Prometheus: raw values, already correct) and JsonlImporterFormat:748 (timestamp only, #10107).

entry point how the row is built status
INSERT ... SET UpdateSetStep -> MutableDocument.set fixed, tested
INSERT ... CONTENT {json} MutableDocument.set(Map) -> putFromMap -> putProperty fixed, tested
INSERT ... (cols) VALUES (...) MutableDocument.set fixed, tested
INSERT ... FROM SELECT CopyDocumentStep saves a plain document before SaveElementStep broken independently (no bucket), filed #10232
line protocol / gRPC / Prometheus TimeSeriesStorableRows.convert unchanged, already raw
JSONL import JsonlImporterFormat.loadTimeSeriesSamples separate caller, #10107
temporal columns document conversion kept deferred, #10233

Coverage

Covered: INSERT ... SET, INSERT ... CONTENT, INSERT ... VALUES into a TIMESERIES type, for every non-temporal TAG/FIELD column.

Known gaps

Test plan

  • Issue10137TimeSeriesInsertGatewayParityTest (new, 6 tests): a 40-pair (column type, value) table. Each pair is written once through SQL and once through TimeSeriesGateway.write, and the test asserts both store the same value or both refuse for the same reason. The BOOLEAN/STRING/INTEGER/LONG pairs also run as a TAG, held to storableValue appended through the engine. Also covers the issue's literal repro through SET, CONTENT, VALUES and multi-row VALUES, and the BYTE 300 refusal type. The first version was red before the fix (5/5 failing) and is green after.
  • Issue9809LineProtocolTemporalValueTest.aBooleanColumnIsConvertedBeforeTheStorageLayerWhateverTheWriter asserted the bug (on_ = 1 must not throw). It now expects the refusal.
  • Every engine test class mentioning TimeSeries/TIMESERIES (185 classes, 1529 tests): green, except one failure in Issue9621SealedStoreChannelReopenTest.readersInterruptedMidScanAllGetTheirRows, a known interrupt-timing flake unrelated to SQL INSERT that passed 3/3 when rerun alone.
  • InsertStatementExecutionTest, UpdateStatementExecutionTest, DocumentTest, CRUDTest and the MutableDocument/type-conversion tests (123 tests): green.

Residual risk

Release note (breaking): a SQL INSERT into a TIMESERIES BOOLEAN or STRING column that used to store a coerced number now fails with a CommandExecutionException naming the column. That is the issue's intent, and it matches the other surfaces. A grep of other modules' tests found no SQL INSERT into a TIMESERIES type that depended on the coercion. The cost is one instanceof per MutableDocument.set on a declared property. The column lookup only runs for TIMESERIES types.

Adversarial pass

The Phase 1.5 independent subagent could not be spawned: no subagent tool was available in this session. I did a self-review in its place, checking each other way a row reaches saveToTimeSeries. That review found INSERT ... FROM SELECT, which does not reach the step at all (filed as #10232). The temporal-column residue is filed as #10233.

Review cycles

cycle head changes bot outcome
1 81f9b6b initial fix + parity test 3 points + naming/test notes. Constraint/UPDATE concern checked and not reachable (ignored constraints are pre-existing, filed #10238). Renamed helper to skipsDocumentConversion, renamed the #9809 test, viaSql catches only CommandExecutionException
2 6331217 review fixes from cycle 1 asked for DECIMAL coverage (not a legal TIMESERIES column type), TAG coverage, refusal-reason comparison and multi-row VALUES. All added
3 de954a1 TAG pairs, reason matching, multi-row VALUES LGTM with minor confirmations. Aliases removed, the rest answered in the PR thread
4 75ffd58 alias cleanup LGTM-style review repeating earlier points, plus a null pair and an @Tag("slow") suggestion. Not acted on (max cycles reached)

Deferred items

  • Cycle 4: "Null handling: add a null pair for a non-temporal column; SQL and gateway should agree." Not added because cycle 4 was the last. On the SQL side a null returns before any conversion (convertValueToSchemaType returns null first, and storableValue(null) is null). The gateway's Sample field map is built with Map.of, which cannot hold a null, so a parity row needs a different fixture.
  • Cycle 4: "Test runtime: 40+ pairs each create a type; if the class takes multiple seconds, tag it @Tag("slow")." Skipped. The class runs in about 2.5 s, in line with the other untagged timeseries regression tests.
  • Cycle 3/4: "A test reading the returned record after a successful insert (INSERT ... RETURN)." Skipped. It would freeze the in-memory row shape (the value as written) of a statement that has no RETURN contract for TIMESERIES types today.
  • Cycle 3: multi-row test asserting exactly 1 row. Kept <= 1, the same bound as the INSERT INTO a TIMESERIES type converts values with its own convertValue instead of ColumnDefinition.storableValue #10064 batch test, because a time series append commits on its own.
  • Lookup cost of getTsColumn (cycles 3 and 4): kept the existing indexed loop. It runs over a handful of columns, allocates nothing, and only runs for TIMESERIES types.

Final state

max-cycles-reached. Four review cycles ran. Every review from cycle 3 on was LGTM-with-suggestions, and the cycle-4 suggestions above are left for the developer.

🤖 Generated with Claude Code

…n value to storableValue unconverted

The document layer converted each property to its declared type before
saveToTimeSeries called ColumnDefinition.storableValue, so a number into a
BOOLEAN column was stored as true and a number into a STRING column as its
text, where the line protocol, gRPC and Prometheus refuse the same point.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 15 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 7f066c40-dbf0-45ce-8f66-27a286dc8583
📥 Commits

Reviewing files that changed from the base of the PR and between b28fa82 and 75ffd58.

📒 Files selected for processing: 5
  • engine/src/main/java/com/arcadedb/database/MutableDocument.java
  • engine/src/main/java/com/arcadedb/schema/LocalTimeSeriesType.java
  • engine/src/test/java/com/arcadedb/engine/timeseries/Issue10064TimeSeriesInsertStorableValueTest.java
  • engine/src/test/java/com/arcadedb/engine/timeseries/Issue10137TimeSeriesInsertGatewayParityTest.java
  • engine/src/test/java/com/arcadedb/engine/timeseries/Issue9809LineProtocolTemporalValueTest.java
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mergify

mergify Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

This pull request does not currently match the merge queue conditions, so it cannot be queued from here. The box comes back if it matches again.

@claude

claude Bot commented Oct 17, 2026

Copy link
Copy Markdown

Review

Targeted fix with a good parity-table test. The change is small and the rationale is well documented. A few points:

Potential issues

  1. Skipped conversion applies to every MutableDocument of a TIMESERIES type, not only the INSERT path. convertValueToSchemaType is also reached by UPDATE/set and by documents materialized from query results. If a TIMESERIES doc is ever mutated and read back before the append, it can now hold an unconverted value (e.g. Integer in a LONG column, or "5" in an INTEGER column) in memory. Please confirm nothing between set and storableValue relies on the declared class (property validation such as min/max/mandatory/regexp runs on the raw value now; a "5" string against max could behave differently or throw a ClassCastException). A test with a constrained TIMESERIES property would pin this.
  2. Behavior change for SQL users: bo = 1 and s = 42 now fail where they used to work. This is the stated intent, but it is a breaking change. Worth a release-note line, and the Issue9809 test name (aBooleanColumnIsConvertedBeforeTheStorageLayerWhateverTheWriter) is now misleading, since SQL no longer converts first. Consider renaming.
  3. Error type for out-of-range numbers changed (IllegalArgumentException to CommandExecutionException). Check other modules (server HTTP error mapping, Studio, gRPC/Bolt tests) for assertions on the old message or status code.

Code quality

  • isConvertedOnAppendOnly is a confusing name (reads as "only converted on append"). isConvertedByStorableValueOnly or skipsDocumentConversion would be clearer.
  • The lookup is a linear scan over columns per set; fine for small column lists, and only runs for TIMESERIES types. OK per the performance guidance.
  • In the test, viaSql swallows every RuntimeException, so an unrelated failure (e.g. a typo in SQL) counts as REFUSED and can match a gateway refusal. Consider asserting the exception is a CommandExecutionException (or the pinned type) there.
  • Pair/REFUSED helpers are fine; consider @Tag-free is OK since the test is fast (40 type creations).

Tests

  • Good coverage of SET/CONTENT/VALUES. Missing: UPDATE on a TIMESERIES type and a constrained-property case (see point 1), and a valid-value round trip for each non-temporal type via SQL (string "5" into INTEGER is covered, Float/Short storage are covered by the table).

No security concerns. Overall LGTM pending point 1.

@codacy-production

codacy-production Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 5 complexity

Metric Results
Complexity 5

View in Codacy

🟢 Coverage 100.00% diff coverage · -5.01% coverage variation

Metric Results
Coverage variation ✅ -5.01% coverage variation
Diff coverage ✅ 100.00% diff coverage

View coverage diff in Codacy

Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (ffc4de1) 238403 206389 86.57%
Head commit (75ffd58) 271185 (+32782) 221180 (+14791) 81.56% (-5.01%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#10236) 4 4 100.00%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

…ly the statement's refusal, rename the #9809 boolean test

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@robfrank

Copy link
Copy Markdown
Collaborator Author

Review cycle 1, addressed in 6331217:

@claude

claude Bot commented Oct 17, 2026

Copy link
Copy Markdown

Review of #10236

Overall: a small, well-targeted fix with a strong table-driven parity test. Skipping the document-layer Type.convert for non-temporal TAG/FIELD columns so storableValue is the single conversion is sound, and the PR description is clear about scope and known gaps.

Correctness / behaviour

  1. The early return in MutableDocument.convertValueToSchemaType also skips Type.convert(..., property). TIMESERIES columns are scalar so this is likely fine, but please confirm storableValue covers every column type the DDL accepts (e.g. DECIMAL).
  2. The in-memory document now holds the raw value (e.g. Integer 42 for a STRING property) until SaveElementStep. Anything between set and save that reads by schema type (property constraints like regexp/min/max, validate(), RETURN AFTER) could now see an unconverted value, e.g. a ClassCastException instead of a clean error. Please confirm or add a test with a constrained column.
  3. convertValueToSchemaType is shared by every set, not just INSERT. If UPDATE on a TIMESERIES type is not blocked, that path changes too.
  4. The behaviour change (INSERT ... SET bo = 1 now fails) is intentional and documented, but breaking for SQL users who write 1/0 for booleans; worth a release note.

Performance
Cost is an instanceof plus a linear getTsColumn scan per set on TIMESERIES types only. Fine.

Tests

  • Good: red-before/green-after, SQL vs gateway parity, SET/CONTENT/VALUES covered, and the old test that asserted the bug was updated.
  • Missing: a TAG column case (all parity pairs use FIELDS, though the fix explicitly covers TAG), and a multi-row INSERT ... VALUES (...), (...).
  • Consider asserting the refusal message matches the gateway's for a few pairs, not only refused/refused.

Security
No concerns; validation becomes stricter, not looser.

Follow-ups #10232 and #10233 are properly tracked. The items to check before merge are the constrained-property validation, the UPDATE path, and TAG coverage.

…reasons, multi-row VALUES test

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@robfrank

Copy link
Copy Markdown
Collaborator Author

Review cycle 2, addressed in de954a1:

  • 1 (DECIMAL and other types): TimeSeriesTypeBuilder.validate refuses every column type except BOOLEAN, BYTE, SHORT, INTEGER, LONG, FLOAT, DOUBLE, STRING and the DATE/DATETIME family (SchemaException: Column 'd' of type DECIMAL cannot be used in a TIMESERIES type). Each non-temporal one has its own rule in storableValue. The javadoc of skipsDocumentConversion now says so.
  • 2 and 3 (constraints, validate(), UPDATE): answered in the cycle-1 reply. Nothing validates a TIMESERIES document on any path, UPDATE matches no records, and the ignored constraints are pre-existing, filed as TIMESERIES: ALTER PROPERTY accepts MAX/MIN/REGEXP/MANDATORY on a column, and no write path ever enforces them #10238. RETURN on an INSERT into a TIMESERIES type reports the row the statement built, so it now shows the value as written.
  • 4: release-note line is in the PR body (Residual risk).
  • Tests: the parity table now runs BOOLEAN/STRING/INTEGER/LONG pairs as a TAG too. The line protocol carries a tag only as text, so those rows are held to storableValue appended through the engine. Where both sides refuse, the table now also requires the gateway's reported reason to end with the statement's message. Added aMultiRowValuesIsRefusedAtTheRowWithANumberForABooleanColumn.

@claude

claude Bot commented Oct 17, 2026

Copy link
Copy Markdown

Review of #10236

Solid, narrowly scoped fix. The root cause is correctly identified (Type.convert runs before storableValue), the fix sits at the single choke point so SET, CONTENT and VALUES are all covered, and the PR description clearly lists what is deferred (#10232, #10233).

Code quality

  • MutableDocument.convertValueToSchemaType: the instanceof guard is cheap and the comment explains the why.
  • LocalTimeSeriesType.skipsDocumentConversion: Javadoc is accurate. Please confirm getTsColumn(name) is a map lookup and not a linear scan, since it now runs on every set() of a declared property of a timeseries type.
  • The early return also bypasses anything else the method does after the type conversion (e.g. constraints, if applied there). Timeseries columns likely cannot carry those, but worth confirming or noting in the Javadoc.

Potential issues

  • The in-memory MutableDocument now holds the raw value (e.g. an Integer for a BYTE column) instead of the declared class. Anything reading it back between set() and SaveElementStep (e.g. INSERT ... RETURN, triggers) sees the unconverted value. A small test for INSERT ... RETURN on a timeseries type would pin the behavior.
  • The behavior change (number into BOOLEAN/STRING now refused) is intended, but should be mentioned in release notes/docs since it can break existing client inserts.

Tests

  • The 40-pair parity table is a good guarantee-style test. Minor: sameOutcome has redundant a/b aliases, and the endsWith reason match is lenient.
  • aMultiRowValuesIsRefused... asserts <= 1 rows; if semantics are deterministic, asserting exactly 1 is a stronger regression guard.
  • Consider explicit TAG-column coverage through CONTENT/VALUES (the table covers tags via SET only).

Performance / security
No concerns: one instanceof plus a column lookup for timeseries types only; validation becomes stricter, not looser.

LGTM with the small confirmations above.

…omparison

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@robfrank

Copy link
Copy Markdown
Collaborator Author

Review cycle 3, addressed in 75ffd58:

  • Redundant aliases in sameOutcome: removed.
  • getTsColumn linear scan: confirmed, it is the existing indexed loop over the column list (a handful of entries, no iterator allocation; its javadoc explains the choice). It runs only for TIMESERIES types. Not changed.
  • Anything after the conversion: the early return sits right before Type.convert, the last thing convertValueToSchemaType does. Constraints are never applied on a TIMESERIES write (TIMESERIES: ALTER PROPERTY accepts MAX/MIN/REGEXP/MANDATORY on a column, and no write path ever enforces them #10238).
  • Not changed, with rationale: (a) an INSERT ... RETURN test would pin the in-memory row as written ('5' for an INTEGER column whose stored sample is 5). I'd rather not freeze that shape, since TIMESERIES INSERT has no RETURN contract today. (b) The multi-row test keeps <= 1, the same bound Issue10064...aBatchInsertRefusesTheRowWithAValueTheColumnCannotHold uses, because a time series append commits on its own and the row count before the refusal is not part of the statement's contract. (c) TAG through CONTENT/VALUES goes through the same MutableDocument.putProperty choke point that SET and the field CONTENT/VALUES tests already exercise.

@claude

claude Bot commented Oct 17, 2026

Copy link
Copy Markdown

Review

Small, well-targeted fix. Hooking convertValueToSchemaType covers SET, CONTENT and VALUES at once, and the parity-table test is a strong guarantee. I read the diff only and did not run the tests.

Good

  • Minimal change; the cost is one instanceof per set on a declared property.
  • skipsDocumentConversion is documented, and the temporal carve-out points to the follow-up issue.
  • Updating the old test that asserted the bug is the right call.
  • Coverage of SET, CONTENT, VALUES, multi-row VALUES and BYTE 300.

Suggestions

  1. Lookup cost: getTsColumn(name) runs on every set() for TIMESERIES types. If it is a linear scan or allocates, consider a precomputed structure (performance-first rule).
  2. Values left unconverted: the document now keeps raw values (e.g. a String in an INTEGER column) until saveToTimeSeries. Anything between set() and the save that reads the property by declared type (validation, toJSON, RETURN AFTER) sees the raw value. A test reading the returned record after a successful insert would pin this down.
  3. Null handling: add a null pair for a non-temporal column; SQL and gateway should agree.
  4. Behavior change: SQL INSERT of 1 into BOOLEAN or 42 into STRING now fails. Call it out in release notes/docs as breaking.
  5. Test style: sameOutcome/viaSql rely on try/catch and message matching, so failures will be harder to read. Minor.
  6. Test runtime: 40+ pairs each create a type; if the class takes multiple seconds, tag it @Tag("slow").

Security / correctness
No security concerns. Nothing is stored on refusal, as the tests assert. Known gaps (10232, 10233) are tracked.

Items 1 and 2 are the ones I would check before merge.

@codecov

codecov Bot commented Oct 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 75.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 78.46%. Comparing base (ffc4de1) to head (75ffd58).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
.../java/com/arcadedb/schema/LocalTimeSeriesType.java 50.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main   #10236      +/-   ##
============================================
+ Coverage     78.43%   78.46%   +0.02%     
+ Complexity     4651     4650       -1     
============================================
  Files          2252     2252              
  Lines        238403   238484      +81     
  Branches      51602    51615      +13     
============================================
+ Hits         186993   187115     +122     
+ Misses        32055    32021      -34     
+ Partials      19355    19348       -7     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@tae898

tae898 commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

I checked the reproduction from #10137 against this PR's head, 75ffd58, and against main at a2c54ef. Both are the CI-built distribution jars, run as an embedded database on JDK 21 and on JDK 25 (with compact object headers), with identical results on both JDKs.

The reproduction is the issue's schema, CREATE TIMESERIES TYPE M TIMESTAMP ts FIELDS (i INTEGER, d DOUBLE, s STRING, bo BOOLEAN, b BYTE, l LONG) SHARDS 1, followed by one INSERT INTO M per row below.

statement main a2c54ef PR head 75ffd58
SET i=1, d=1, s=42, bo=7 stored, s:"42", bo:true refused, CommandExecutionException
SET bo=1 / SET bo=0 stored as true / false refused, CommandExecutionException
SET s=42 / SET s=4.25 / SET s=true stored as "42" / "4.25" / "true" refused, CommandExecutionException
SET b=300 refused, bare IllegalArgumentException refused, CommandExecutionException

Sibling forms the description does not list, same outcome on both JDKs:

form main a2c54ef PR head 75ffd58
(ts, i, bo) VALUES (..., 7) stored as true refused, CommandExecutionException
(ts, i, s) VALUES (..., 42) stored as "42" refused, CommandExecutionException
CONTENT {"bo":7} stored as true refused, CommandExecutionException
CONTENT {"s":42} stored as "42" refused, CommandExecutionException
SET i=true refused, bare IllegalArgumentException refused, CommandExecutionException
SET d='2.5' stored as 2.5 stored as 2.5
SET bo='TRUE' stored as true stored as true
SET l=5 stored stored

I did not run DATE or DATETIME columns, and I did not run the line protocol, which this PR does not touch.

Seen on both builds and outside this PR's scope: a STRING field the INSERT does not set reads back as "", where every other unset field of the row reads null (e.g. after SET l=5: {"i":null,"d":null,"s":"","bo":null,"b":null,"l":5}).

@robfrank

Copy link
Copy Markdown
Collaborator Author

@tae898 what are your conclusions? Is this PR ok? May I merge it?

@tae898

tae898 commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Yes, it looks good to merge from my side. On the head I tested (75ffd580be, still the head), a number into a BOOLEAN or STRING field is refused for SET, VALUES and CONTENT alike, out-of-range values now raise a CommandExecutionException instead of a bare IllegalArgumentException, and the conversions that should still work (d='2.5', bo='TRUE', l=5) are unchanged. Not covered by my check: DATE/DATETIME fields, the line protocol, and the unset STRING reading "", which happens on main too and is outside this PR.

@robfrank
robfrank merged commit cd71ae9 into main Oct 18, 2026
37 of 38 checks passed
robfrank added a commit that referenced this pull request Nov 5, 2026
… into a BOOLEAN or STRING column (#10236)

(cherry picked from commit cd71ae9)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

INSERT INTO a TIMESERIES type still coerces a number into a BOOLEAN or STRING column, where the line protocol, gRPC and Prometheus refuse the same point

2 participants