// Trace FiveSql2 execution step by step #include "FiveSqlDef.ch" #include "hbclass.ch" FUNCTION Main() LOCAL oLexer, oParser, aTokens, hQuery LOCAL cSQL // Create test table dbCreate("trace_test", { {"ID","N",4,0}, {"NAME","C",20,0} }) USE "trace_test" NEW EXCLUSIVE APPEND BLANK REPLACE ID WITH 1, NAME WITH "Alice" APPEND BLANK REPLACE ID WITH 2, NAME WITH "Bob" CLOSE ALL cSQL := "SELECT * FROM trace_test" ? "=== Step 1: Lexer ===" oLexer := TSqlLexer():New( cSQL ) oLexer:Tokenize() aTokens := oLexer:GetTokens() ? "Tokens:", Len(aTokens) LOCAL i FOR i := 1 TO Len(aTokens) ?? " [" + LTrim(Str(aTokens[i][1])) + ":" + aTokens[i][2] + "]" NEXT ? ? "=== Step 2: Parser ===" oParser := TSqlParser2():New( aTokens, {} ) hQuery := oParser:Parse() ? "hQuery type:", ValType(hQuery) IF ValType(hQuery) == "H" ? "Keys:" LOCAL aKeys aKeys := hb_HKeys(hQuery) FOR i := 1 TO Len(aKeys) ? " ", aKeys[i], "=", ValType(hQuery[aKeys[i]]) IF ValType(hQuery[aKeys[i]]) == "A" ? " len:", Len(hQuery[aKeys[i]]) ELSEIF ValType(hQuery[aKeys[i]]) == "C" ? " val:", hQuery[aKeys[i]] ENDIF NEXT ENDIF ? "=== Step 3: Check tables ===" IF hb_HHasKey(hQuery, "tables") LOCAL aTables aTables := hQuery["tables"] ? "Tables:", Len(aTables) FOR i := 1 TO Len(aTables) ? " Table", i, ":", ValType(aTables[i]) IF ValType(aTables[i]) == "A" ? " len:", Len(aTables[i]) LOCAL j FOR j := 1 TO Len(aTables[i]) ? " [" + LTrim(Str(j)) + "]:", ValType(aTables[i][j]), aTables[i][j] NEXT ENDIF NEXT ENDIF FErase("trace_test.dbf") ? "=== DONE ===" RETURN NIL