feat: INDEX ON with UDF support — user functions in key expressions
Core change: - dbf.KeyEvalFunc: global callback set by gengo before OrderCreate - evalKeyExprInner default case: calls KeyEvalFunc for unknown functions - Final fallback: any unresolvable expression → KeyEvalFunc → MacroEval - valueToKeyBytes: converts MacroEval result to index key bytes - gengo: sets dbf.KeyEvalFunc = t.MacroEval before OrderCreate, clears after Examples that now work: INDEX ON MyFunc(FIELD->NAME) TO idx // UDF in key expression INDEX ON CityKey(FIELD->CITY, NAME) TO idx // multi-param UDF INDEX ON Left(MyFunc(NAME), 15) TO idx // nested built-in + UDF Also fixed: - SET ORDER TO n: int→string via hbrt.NtoS (was empty string) - CDX compound leaf decoder: proper bit-packed tag name extraction - CDX compound recNo = direct byte offset (not page number) All existing tests pass, NTX 47/47 + CDX 20/20 Harbour compat maintained. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -482,8 +482,11 @@ func (g *Generator) emitStmt(stmt ast.Stmt, locals localMap) {
|
||||
if s.ForCond != nil {
|
||||
forExpr = fmt.Sprintf("%q", exprToString(s.ForCond))
|
||||
}
|
||||
// Set VM callback for UDF evaluation during index build
|
||||
g.writeln("dbf.KeyEvalFunc = func(expr string) hbrt.Value { return t.MacroEval(expr) }")
|
||||
g.writeln(fmt.Sprintf("idx.OrderCreate(hbrdd.OrderCreateParams{KeyExpr: _keyExpr, FilePath: _file, ForExpr: %s, Unique: %v, Descending: %v})",
|
||||
forExpr, s.Unique, s.Descending))
|
||||
g.writeln("dbf.KeyEvalFunc = nil")
|
||||
g.indent--
|
||||
g.writeln("}")
|
||||
g.indent--
|
||||
|
||||
Reference in New Issue
Block a user