Skip to content

hbfbird: fix TFbQuery:FieldGet() returning a blank DATE in dialect 3 - #413

Closed
kamilprzyb2 wants to merge 1 commit into
harbour:masterfrom
kamilprzyb2:fix/hbfbird-blank-date
Closed

hbfbird: fix TFbQuery:FieldGet() returning a blank DATE in dialect 3#413
kamilprzyb2 wants to merge 1 commit into
harbour:masterfrom
kamilprzyb2:fix/hbfbird-blank-date

Conversation

@kamilprzyb2

Copy link
Copy Markdown
Contributor

TFbQuery:FieldGet() returns an empty date for every DATE column in SQL
dialect 3.

FBGetData() formats SQL_TYPE_DATE as "YYYY-MM-DD " - the
"%04d-%02d-%02d" branch in contrib/hbfbird/firebird.c, then padded
through "%*s " with width 8, which does not truncate a 10-character
string, so what reaches PRG is 11 characters with a trailing space.
FieldGet() then does:

result := hb_SToD( Left( result, 4 ) + SubStr( result, 5, 2 ) + SubStr( result, 7, 2 ) )

That reads like an attempt to drop the separators, but the offsets are off
by one: for "2026-09-01 " it builds "2026" + "-0" + "9-" = "2026-09-",
and hb_SToD() - strictly positional, expecting a bare "YYYYMMDD" -
rejects it. So every DATE column comes back as an empty date.

The positional correction would be SubStr( result, 6, 2 ) and
SubStr( result, 9, 2 ). I used StrTran( AllTrim( result ), "-" )
instead so it does not depend on where the separators sit; happy to switch
to the two-offset version if you prefer the smaller diff.

Scope. Dialect 3 only. There a DATE column is SQL_TYPE_DATE, which
StructConvert() maps to "D" and FieldGet() converts. In dialect 1 a
DATE column is really SQL_TIMESTAMP, mapped to "T", which FieldGet()
has no case for at all and returns as the raw string - untouched by this
change, though arguably its own gap. SQL_TYPE_TIME maps to "C" and is
likewise returned as-is.

Evidence, and how I tested it - please read this part. I ran a probe
against Firebird 5.0.4 embedded, printing the raw FBGetData() output and
evaluating the expressions against it:

struct type letter: D
raw FBGetData()   : "2026-09-01 " len 11
  current         : (empty date)
  this patch      : 2026-09-01

The caveat: that probe was built against the 3.4 fork, not against core.
contrib/hbfbird/firebird.c is byte-identical between the two trees in
the SQL_TYPE_DATE branch, so FBGetData() produces the same string, and
I evaluated core's exact expression against that real string rather than
against my reading of it - but I have not run a core build end to end. If
you want that before merging, say so and I will do it.

The 3.4 fork has the same bug by a different route - it passes the raw
string to hb_SToD() with no stripping at all. Filed there as
vszakats/hb#348.

ChangeLog.txt entry included.

  * contrib/hbfbird/tfirebrd.prg
    ! fixed TFbQuery:FieldGet() returning an empty date for every DATE
      column in SQL dialect 3. FBGetData() formats SQL_TYPE_DATE as
      "YYYY-MM-DD ", so the positional slicing picked up the separators
      and hb_SToD() rejected the result. Strip them instead, which does
      not depend on where they sit

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@alcz

alcz commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

FBGetData() formats SQL_TYPE_DATE as "YYYY-MM-DD " - the
"%04d-%02d-%02d" branch in contrib/hbfbird/firebird.c, then padded
through "%*s " with width 8, which does not truncate a 10-character
string, so what reaches PRG is 11 characters with a trailing space.

It doesn't truncate, but anyway the code looks like it is left halfway during some modifications, i'd expect that someone wanted to get rid of date separators. Is anyone else familiar why all FBGetData() has a blank space suffix, for other SQL data types too?

Without digging much, C test-code "pads" to 10
https://github.com/harbour/core/blob/master/contrib/hbfbird/tests/testapi.c#L392-L397

If there is no feedback from others, I will just fix the positionals.

alcz added a commit that referenced this pull request Sep 1, 2026
  * contrib/hbfbird/firebird.c
  * contrib/hbfbird/tfirebrd.prg
    ! fix desync between C and .prg source codes when parsing the date.
      I'm keeping ISO 8601 date format in case someone uses "raw"
      FBGetData() function to dump or pass-trough data to another SQL server.
      Reported by Kamil Przybylski in #413 with slightly different fix.
@alcz

alcz commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Commited slightly different fix,
Yet in the INSERT path there another date format used... https://github.com/harbour/core/blob/master/contrib/hbfbird/tfirebrd.prg#L942
Does :Append(), Update() results are expected for date fields?

@kamilprzyb2

Copy link
Copy Markdown
Contributor Author

Thanks for jumping on this so fast!

Yet in the INSERT path there another date format used...

Yes code quality of this contrib is questionable, to say the least.

Does :Append(), Update() results are expected for date fields?

I use hbfbird for read-only operations, so I don't have live environment to test it at the moment. I can prepare a dedicated test later.

Anyway this PR can be closed now, as the original issue was resolved.

@alcz alcz closed this Sep 2, 2026
mdlugos pushed a commit to mdlugos/harbour_customized that referenced this pull request Sep 3, 2026
  * contrib/hbfbird/firebird.c
  * contrib/hbfbird/tfirebrd.prg
    ! fix desync between C and .prg source codes when parsing the date.
      I'm keeping ISO 8601 date format in case someone uses "raw"
      FBGetData() function to dump or pass-trough data to another SQL server.
      Reported by Kamil Przybylski in harbour#413 with slightly different fix.
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