// Test INDEX ON with User Defined Functions PROCEDURE Main() LOCAL i, aStruct, aCit, nCidx aStruct := {{"ID","N",6,0}, {"NAME","C",20,0}, {"CITY","C",15,0}} dbCreate("udf_test", aStruct) USE "udf_test" NEW aCit := {"Seoul","Tokyo","Beijing"} FOR i := 1 TO 10 APPEND BLANK REPLACE ID WITH i REPLACE NAME WITH PadR("Name_" + PadL(LTrim(Str(i)), 3, "0"), 20) nCidx := Int((i-1) % 3) + 1 REPLACE CITY WITH PadR(aCit[nCidx], 15) NEXT ? "Records:", RecCount() // Test 1: INDEX ON with built-in function (baseline) INDEX ON UPPER(NAME) TO udf_idx1 GO TOP ? "T1 UPPER top:", RTrim(FieldGet(2)), RecNo() SEEK PadR("NAME_005", 20) ? "T2 UPPER seek:", Found(), RecNo() // Test 2: INDEX ON with UDF INDEX ON MyKey(FIELD->NAME) TO udf_idx2 GO TOP ? "T3 UDF top:", RTrim(FieldGet(2)), RecNo() SEEK PadR("KEY:Name_001", 20) ? "T4 UDF seek:", Found(), RecNo() // Test 3: INDEX ON with two-param UDF INDEX ON CityKey(FIELD->CITY, FIELD->NAME) TO udf_idx3 GO TOP ? "T5 UDF2 top:", RTrim(FieldGet(3)), RTrim(FieldGet(2)), RecNo() // Test 4: Nested: built-in wrapping UDF INDEX ON Left(MyKey(FIELD->NAME), 15) TO udf_idx4 GO TOP ? "T6 Nested top:", RTrim(FieldGet(2)), RecNo() CLOSE ALL ? "DONE" RETURN FUNCTION MyKey(cName) LOCAL cResult cResult := "KEY:" + RTrim(cName) RETURN PadR(cResult, 20) FUNCTION CityKey(cCity, cName) LOCAL cResult cResult := RTrim(cCity) + ":" + RTrim(cName) RETURN PadR(cResult, 30)