ALTER TABLE famille
  ADD gauche int, droite int;

-- fonction auxiliaire récursive : reçoit le compteur 'n', retourne le compteur mis à jour
CREATE OR REPLACE FUNCTION set_bounds(p_code INT, n INT)
RETURNS INT AS $$
DECLARE
  child RECORD;
BEGIN
  -- left
  UPDATE famille SET gauche = n WHERE code = p_code;
  n := n + 1;

  -- parcours des enfants
  FOR child IN
    SELECT code FROM famille WHERE code_parent = p_code ORDER BY code
  LOOP
    n := set_bounds(child.code, n);
  END LOOP;

  -- right
  UPDATE famille SET droite = n WHERE code = p_code;
  n := n + 1;

  RETURN n;
END;
$$ LANGUAGE plpgsql;

-- fonction principale : initialise et lance la reconstruction
CREATE OR REPLACE FUNCTION rebuild_nested_sets()
RETURNS VOID AS $$
DECLARE
  root RECORD;
  n INT := 1;
BEGIN
  -- remise à zéro (optionnel)
  UPDATE famille SET gauche = NULL, droite = NULL;

  -- pour chaque racine
  FOR root IN
    SELECT code FROM famille WHERE code_parent IS NULL ORDER BY code
  LOOP
    n := set_bounds(root.code, n);
  END LOOP;
END;
$$ LANGUAGE plpgsql;

SELECT rebuild_nested_sets();
