Skip to content

feat(bindings): tbool boolean operators + ttext text functions (13 functions)#27

Merged
nhungoc1508 merged 1 commit intomainfrom
feat/tbool-tor-tand-ttext-text
Apr 27, 2026
Merged

feat(bindings): tbool boolean operators + ttext text functions (13 functions)#27
nhungoc1508 merged 1 commit intomainfrom
feat/tbool-tor-tand-ttext-text

Conversation

@estebanzimanyi
Copy link
Copy Markdown
Member

Summary

Adds 13 ScalarFunction registrations for two MobilityDB feature groups that were previously unbound in MobilityDuck.

tbool boolean operators (7)

SQL MEOS
tbool & BOOL, BOOL & tbool, tbool & tbool tand_tbool_bool, tand_tbool_tbool
`tbool BOOL, BOOL
~ tbool tnot_tbool

ttext text functions (6)

SQL MEOS
lower(ttext), upper(ttext), initcap(ttext) ttext_lower, ttext_upper, ttext_initcap
`text

Implementation

Adds five small templated wrapper helpers in src/temporal/temporal_functions.cpp:

  • TemporalToBlob / BlobToTemporal — round-trip the Temporal * blob between MEOS and DuckDB string vectors
  • TemporalUnary<Fn> — for f(Temporal*) -> Temporal* patterns
  • TemporalBinaryV<T2, Fn> / TemporalBinaryV1<T1, Fn> — for value/temporal mixed-arg patterns
  • TemporalBinaryTT<Fn> — for f(Temporal*, Temporal*) -> Temporal*
  • TextFromBlob — for string_t -> text * (PG-text format) conversion

Each ScalarFunction body is now one or two lines. Same pattern can be reused for tnumber arithmetic (PR #24's 026 gap, ~96 registrations).

Smoke test

SELECT TRUE & tbool 't@2000-01-01';                     -- t@2000-01-01 00:00:00+00
SELECT tbool 't@...' & tbool 'f@...';                   -- f@2000-01-01 00:00:00+00
SELECT ~ tbool 't@...';                                  -- f@2000-01-01 00:00:00+00
SELECT lower(ttext '"AAA"@...');                        -- "aaa"@2000-01-01 00:00:00+00
SELECT initcap(ttext '"hello world"@...');              -- "Hello World"@2000-01-01 00:00:00+00
SELECT ttext '"AA"@...' || ttext '"BB"@...';            -- "AABB"@2000-01-01 00:00:00+00

Test plan

  • make release then TZ=UTC ./build/release/test/unittest "<proj>/test/*" — full suite passes (747 assertions, 13 test cases).

When this lands, PR #24's 028_tbool_boolops.test and 029_ttext_textfuncs.test skip blocks both unwrap into ~10 active assertions each.

Adds 13 ScalarFunction registrations for two MobilityDB feature
groups that were previously unbound in MobilityDuck:

tbool boolean operators (7):
  - tbool & bool, bool & tbool, tbool & tbool
  - tbool | bool, bool | tbool, tbool | tbool
  - ~ tbool
  MEOS: tand_tbool_bool, tand_tbool_tbool, tor_tbool_bool,
  tor_tbool_tbool, tnot_tbool.

ttext text functions (6):
  - lower(ttext), upper(ttext), initcap(ttext)
  - text || ttext, ttext || text, ttext || ttext
  MEOS: ttext_lower, ttext_upper, ttext_initcap,
  textcat_text_ttext, textcat_ttext_text, textcat_ttext_ttext.

Implementation uses a small set of templated wrapper helpers
(TemporalUnary, TemporalBinaryV, TemporalBinaryV1, TemporalBinaryTT,
TextFromBlob) in src/temporal/temporal_functions.cpp to keep each
ScalarFunction body to one or two lines. Pattern can be reused for
the remaining tnumber arithmetic surface (PR #24 026 gap, ~96
registrations) once that work lands.

Smoke test:
  SELECT TRUE & tbool 't@2000-01-01';      -> t@2000-01-01 00:00:00+00
  SELECT tbool 't@...' & tbool 'f@...';    -> f@2000-01-01 00:00:00+00
  SELECT TRUE | tbool 'f@...';             -> t@2000-01-01 00:00:00+00
  SELECT ~ tbool 't@...';                  -> f@2000-01-01 00:00:00+00
  SELECT lower(ttext '"AAA"@...');         -> "aaa"@2000-01-01 00:00:00+00
  SELECT upper(ttext '"hello"@...');       -> "HELLO"@2000-01-01 00:00:00+00
  SELECT initcap(ttext '"hello world"@...');
                                           -> "Hello World"@2000-01-01 00:00:00+00
  SELECT text 'A' || ttext '"BB"@...';     -> "ABB"@2000-01-01 00:00:00+00
  SELECT ttext '"AA"@...' || text 'X';     -> "AAX"@2000-01-01 00:00:00+00
  SELECT ttext '"AA"@...' || ttext '"BB"@...';
                                           -> "AABB"@2000-01-01 00:00:00+00

Full suite passes (747 assertions, 13 test cases).
@estebanzimanyi
Copy link
Copy Markdown
Member Author

@nhungoc1508 — heads up, the same merge-target pattern from #8/#9 was about to re-occur:

After this PR was squash-merged into main, PR #43's base was still pointing at this branch (feat/tbool-tor-tand-ttext-text). Since this branch has now been left behind by main, merging #43 against the same base would have created an orphan merge commit not reachable from main — same outcome as the #8/#9 mistake.

I've already proactively rebased the entire downstream binding stack onto main and updated PR #43's base to main directly. Stack chain is now:

main → #43 → #42 → #41 → #36 → #40 → #39

For future merges in this stack: when you merge a base PR into main, please update the next PR's base before merging:

gh pr edit <next-pr-num> --base main

I'll keep monitoring and rebasing as PRs land — but flagging so you're aware.

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.

2 participants