Files
five/examples/rdd_compat.prg
Charles KWON OhJun 6e78d12cc2 fix: 3 RDD compat bugs — FIELD->, AsNumInt Double, PACK/ZAP with index
Bug 1: FIELD->NAME in INDEX ON expression
- evalKeyExprInner: strip FIELD->/alias-> prefix before field lookup
- exprToString: handle AliasExpr (FIELD->NAME → "FIELD->NAME")

Bug 2: AsNumInt() on Double returned IEEE 754 raw bits
- Value.AsNumInt(): check tDouble and convert via Float64frombits
- Fixed array index crash when index is result of % modulo

Bug 3: PACK/ZAP crash with open indexes
- OrderListRebuild: fully implemented (was TODO stub)
  Saves index info, closes all, sets idxState=nil, recreates
- OrderCreate: set current=-1 during key evaluation (natural GoTo)
- PACK/ZAP: save/restore idxState, rebuild after operation
- Register __DBPACK, __DBZAP, DBRECALL symbol aliases

Harbour vs Five: 45/47 match (96%), 2 diffs are duplicate-key sort order

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 04:41:19 +09:00

213 lines
4.3 KiB
Plaintext

// RDD Compatibility Test — Harbour vs Five
PROCEDURE Main()
LOCAL i, aStruct, nCount, aCities, nIdx
aStruct := { ;
{"ID", "N", 6, 0}, ;
{"NAME", "C", 20, 0}, ;
{"CITY", "C", 15, 0}, ;
{"SALARY", "N", 10, 2}, ;
{"ACTIVE", "L", 1, 0} ;
}
dbCreate("compat_test", aStruct)
USE "compat_test" NEW
aCities := {"Seoul","Tokyo","Beijing","London","NYC"}
FOR i := 1 TO 20
APPEND BLANK
REPLACE ID WITH i
REPLACE NAME WITH PadR("Name_" + LTrim(Str(i)), 20)
nIdx := ((i-1) % 5) + 1
REPLACE CITY WITH PadR(aCities[nIdx], 15)
REPLACE SALARY WITH 30000 + i * 1000.50
REPLACE ACTIVE WITH (i % 3 != 0)
NEXT
Out("T01", LTrim(Str(RecCount())))
GO TOP
Out("T02", LTrim(Str(FieldGet(1))))
Out("T03", RTrim(FieldGet(2)))
Out("T04", RTrim(FieldGet(3)))
Out("T05", LTrim(Str(FieldGet(4))))
Out("T06", IIF(FieldGet(5), ".T.", ".F."))
GO 10
Out("T07", LTrim(Str(FieldGet(1))))
Out("T08", RTrim(FieldGet(2)))
GO 20
Out("T09", LTrim(Str(FieldGet(1))))
Out("T10", LTrim(Str(FieldGet(4))))
GO TOP
Out("T11", LTrim(Str(RecNo())))
Out("T12", IIF(BOF(), ".T.", ".F."))
Out("T13", IIF(EOF(), ".T.", ".F."))
GO BOTTOM
Out("T14", LTrim(Str(RecNo())))
SKIP -1
Out("T15", LTrim(Str(RecNo())))
GO TOP
SKIP 5
Out("T16", LTrim(Str(RecNo())))
GO TOP
nCount := 0
DO WHILE !EOF()
nCount++
SKIP
ENDDO
Out("T17", LTrim(Str(nCount)))
Out("T18", IIF(EOF(), ".T.", ".F."))
GO 5
DELETE
Out("T19", IIF(Deleted(), ".T.", ".F."))
RECALL
Out("T20", IIF(Deleted(), ".T.", ".F."))
FOR i := 1 TO 20
GO i
IF i % 3 == 0
DELETE
ENDIF
NEXT
nCount := 0
GO TOP
DO WHILE !EOF()
IF Deleted()
nCount++
ENDIF
SKIP
ENDDO
Out("T21", LTrim(Str(nCount)))
SET DELETED OFF
GO TOP
nCount := 0
DO WHILE !EOF()
nCount++
SKIP
ENDDO
Out("T22", LTrim(Str(nCount)))
SET DELETED ON
GO TOP
nCount := 0
DO WHILE !EOF()
nCount++
SKIP
ENDDO
Out("T23", LTrim(Str(nCount)))
GO 1
DELETE
SET DELETED ON
GO TOP
Out("T24", LTrim(Str(RecNo())))
GO 20
DELETE
GO BOTTOM
Out("T25", LTrim(Str(RecNo())))
GO 1
RECALL
GO 20
RECALL
SET DELETED OFF
INDEX ON FIELD->NAME TO compat_idx1
Out("T26", "OK")
GO TOP
Out("T27", RTrim(FieldGet(2)))
Out("T28", LTrim(Str(FieldGet(1))))
SEEK PadR("Name_1", 20)
Out("T29", IIF(Found(), ".T.", ".F.") + " " + LTrim(Str(RecNo())))
SEEK PadR("Name_10", 20)
Out("T30", IIF(Found(), ".T.", ".F.") + " " + LTrim(Str(RecNo())))
SEEK PadR("Name_20", 20)
Out("T31", IIF(Found(), ".T.", ".F.") + " " + LTrim(Str(RecNo())))
SEEK PadR("Name_99", 20)
Out("T32", IIF(Found(), ".T.", ".F.") + " " + LTrim(Str(RecNo())))
Out("T33", IIF(EOF(), ".T.", ".F."))
SEEK "Name_1"
Out("T34", IIF(Found(), ".T.", ".F.") + " " + LTrim(Str(RecNo())))
SEEK "Name_2"
Out("T35", IIF(Found(), ".T.", ".F.") + " " + LTrim(Str(RecNo())))
SET SOFTSEEK ON
SEEK PadR("Name_15", 20)
Out("T36", IIF(Found(), ".T.", ".F.") + " " + LTrim(Str(RecNo())))
SEEK PadR("Name_99", 20)
Out("T37", IIF(Found(), ".T.", ".F.") + " " + IIF(EOF(), ".T.", ".F."))
SET SOFTSEEK OFF
SET ORDER TO 0
GO TOP
Out("T38", LTrim(Str(FieldGet(1))))
SET ORDER TO 1
GO TOP
Out("T39", RTrim(FieldGet(2)))
INDEX ON FIELD->CITY TO compat_idx2
SEEK PadR("Seoul", 15)
Out("T40", IIF(Found(), ".T.", ".F.") + " " + LTrim(Str(FieldGet(1))))
SEEK PadR("Tokyo", 15)
Out("T41", IIF(Found(), ".T.", ".F.") + " " + LTrim(Str(FieldGet(1))))
SEEK PadR("Paris", 15)
Out("T42", IIF(Found(), ".T.", ".F."))
SET ORDER TO 0
SET DELETED OFF
nCount := 0
GO TOP
DO WHILE !EOF()
IF Deleted()
nCount++
ENDIF
SKIP
ENDDO
Out("T43", LTrim(Str(nCount)))
PACK
Out("T44", LTrim(Str(RecCount())))
nCount := 0
GO TOP
DO WHILE !EOF()
IF Deleted()
nCount++
ENDIF
SKIP
ENDDO
Out("T45", LTrim(Str(nCount)))
ZAP
Out("T46", LTrim(Str(RecCount())))
Out("T47", IIF(EOF(), ".T.", ".F."))
CLOSE ALL
RETURN
PROCEDURE Out(cID, cVal)
? cID + "=" + cVal
RETURN