Quero compartilhar uma melhoria que acabou de entrar no SQLRDD++ (o fork open source da SQLRDD mantido no GitHub) e que resolve uma dor antiga de quem usa a lib com PostgreSQL: os índices sintéticos.
O problema
Quem usa SQLRDD sabe: ao criar um índice com função na chave, tipo
Código: Selecionar todos
INDEX ON UPPER(NOME) TAG cli1 TO clientes
INDEX ON STRZERO(ID,10) TAG cli2 TO clientes
INDEX ON DTOS(ADMISSAO) + STRZERO(ID,10) TAG cli3 TO clientes
A tabela ficava "poluída" com colunas que não são suas;
A criação do índice varria a tabela registro a registro fazendo um UPDATE por linha (em tabela grande, demorava muito);
Todo INSERT/UPDATE precisava recalcular e regravar essas colunas — overhead permanente;
Se alguém alterasse a tabela por fora (pgAdmin, script, outro sistema), o índice ficava dessincronizado silenciosamente;
Pior: até índices sem função nenhuma, só com mais de 3 campos (INDEX ON ID+NOME+CIDADE), caíam nessa regra e ganhavam coluna extra.
O que mudou
Agora, no PostgreSQL, chaves com funções padrão do Harbour viram índices de expressão nativos do banco. O INDEX ON UPPER(NOME) gera algo assim direto no PostgreSQL:
Código: Selecionar todos
CREATE INDEX ... ON clientes ((rtrim(upper(coalesce("nome",'')))), "sr_recno")Funções traduzidas nesta primeira versão: UPPER, SUBSTR, LEFT, STRZERO (com e sem decimais) — além de STR e DTOS, que já eram tratados. Índices multi-coluna também não viram mais sintéticos, independente da quantidade de campos.
E as funções próprias (UDF)?
Se a chave usa uma função sua (INDEX ON MINHAFUNC(NOME)), aí sim continua o mecanismo antigo da coluna sintética — o banco não tem como calcular uma função que só existe no seu executável. Ou seja: coluna extra agora só quando realmente não tem jeito.
Compatibilidade (importante!)
Índices antigos continuam funcionando normalmente com a lib nova, sem reindexar nada;
A conversão é automática e incremental: quando sua rotina de reindexação recriar o índice, a coluna INDKEY_ daquele índice é dropada e o índice de expressão entra no lugar;
Atenção: executável compilado com a lib antiga não consegue abrir índice já convertido. Regra prática: atualize todos os executáveis que acessam o banco antes de reindexar;
Se precisar do comportamento antigo por qualquer motivo: SR_SetExpressionIndex(.F.).
Como testar
Na pasta tests/postgresql tem um programa novo, testexprindex.prg, que cria uma tabela, popula, cria índices com UPPER/SUBSTR/STRZERO/DTOS e um com UDF, mostra via information_schema que só o índice com UDF criou coluna extra, roda baterias de SEEK e abre DBEDIT para você navegar em cada ordem e conferir com os próprios olhos.
Por enquanto a melhoria é específica do PostgreSQL (build sqlrddpp-postgresql), mas a arquitetura ficou preparada para levar a mesma ideia para Firebird, MySQL/MariaDB e Oracle — todos têm recurso equivalente (índice de expressão / coluna computada).
Limitações conhecidas e honestas: STRZERO com valores negativos e funções aninhadas (UPPER(SUBSTR(...))) ainda caem no sintético, e a ordenação de caracteres segue o collation do banco (como sempre foi no SQLRDD, inclusive com as INDKEY).
A alteração já está no repositório do projeto: https://github.com/marcosgambeta/sqlrddpp
Quem usa SQLRDD com PostgreSQL, testa aí e dá um retorno — quanto mais gente validando em cenário real, mais rápido isso amadurece para os outros bancos.
Abraço!
