feat(pp): TOTAL TO via std.ch + __dbTotal RTL
`TOTAL TO <file> ON <key> [FIELDS <list>] [FOR ...] [WHILE ...]
[NEXT ...] [RECORD ...] [REST] [ALL]` joins the family of std.ch
DML rewrites. New RTL primitive __dbTotal:
* Walk the source under dbEval-style FOR/WHILE/NEXT/RECORD/REST
bounds. The source must already be sorted/indexed on the key —
same precondition as Harbour's dbtotal.prg.
* Track the current group key. On each key change, flush the
accumulated row to the destination (writing the running totals
back into the most recently appended record's sum-fields,
preserving each field's declared length/decimals).
* On the *first* record of every group, append a fresh dst row
and copy all non-memo source fields into it; subsequent records
in the group only contribute to the sums. Net effect: non-summed
fields take the first record's value, summed fields hold the
group total. Same shape as harbour-core/src/rdd/dbtotal.prg.
* Memo fields are dropped from the destination structure (Harbour
does the same).
Parser cleanup: TOTAL removed from the IDENT-statement no-op switch.
Gates green:
go test ./... : PASS
FiveSql2 SQL:1999 : 43/43
Harbour compat : 56/56
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1155,7 +1155,7 @@ func (p *Parser) parseIdentStmt() ast.Stmt {
|
||||
// rewritten by compiler/pp/std.ch into function calls before the
|
||||
// parser sees them.
|
||||
switch upper {
|
||||
case "TOTAL", "UPDATE",
|
||||
case "UPDATE",
|
||||
"LABEL", "REPORT", "ACCEPT", "INPUT",
|
||||
"JOIN", "RELEASE", "SAVE", "RESTORE",
|
||||
"DIR", "STORE", "NOTE", "TEXT", "ENDTEXT",
|
||||
|
||||
@@ -99,6 +99,17 @@
|
||||
__dbList( <.off.>, { <{v}> }, <.all.>, ;
|
||||
<{for}>, <{while}>, <next>, <rec>, <.rest.> )
|
||||
|
||||
/* TOTAL TO writes one record per consecutive run of equal key values
|
||||
from the source. Numeric fields named in FIELDS are summed; every
|
||||
other (non-memo) field takes the first record's value. The source
|
||||
must already be sorted/indexed on the key for the grouping to
|
||||
produce one row per distinct value. */
|
||||
#command TOTAL [TO <(f)>] [ON <key>] [FIELDS <fields,...>] ;
|
||||
[FOR <for>] [WHILE <while>] [NEXT <next>] ;
|
||||
[RECORD <rec>] [<rest:REST>] [ALL] => ;
|
||||
__dbTotal( <(f)>, <{key}>, { <(fields)> }, ;
|
||||
<{for}>, <{while}>, <next>, <rec>, <.rest.> )
|
||||
|
||||
/* --- bulk maintenance --- */
|
||||
#command REINDEX => DbReindex()
|
||||
#command PACK => DbPack()
|
||||
|
||||
Reference in New Issue
Block a user