Inconsistent Nested Set Moves

Поиск
Список
Период
Сортировка
От Amiri Barksdale
Тема Inconsistent Nested Set Moves
Дата
Msg-id 20100423005159.GA9885@akbuntu.socal.rr.com
обсуждение исходный текст
Список pgsql-sql
Hi folks:

I am working on a nested set implementation using some of theadvice I
found in the archives, namely in this thread:

http://archives.postgresql.org/pgsql-sql/2002-11/msg00358.php

However, I don't seem to be able to get consistent results. More than
half the time I get a duplicate primary key error. Sometimes the update
goes through though.

Here is my schema:
  CREATE TABLE nested_set (      id integer NOT NULL,      lft integer NOT NULL,      rgt integer NOT NULL,      title
charactervarying,      text text  );  ALTER TABLE ONLY nested_set      ADD CONSTRAINT nested_set_pkey PRIMARY KEY (lft,
rgt);


And here is my sproc:
  CREATE FUNCTION pg_move_tree(integer, integer) RETURNS integer      LANGUAGE plpgsql      AS $_$
  -- Moves part of a nested set tree to another part.  -- Pass in the left of the child (from) and the left of the
parent(to)
 
  DECLARE
  cleft INTEGER;     cright INTEGER;  pleft INTEGER;     pright INTEGER;  leftbound INTEGER; rightbound INTEGER;
treeshiftINTEGER; cwidth INTEGER;  lrange INTEGER; rrange INTEGER;
 
  BEGIN
  SELECT lft, rgt FROM nested_set WHERE lft = $1 INTO cleft, cright;  SELECT lft, rgt FROM nested_set WHERE lft = $2
INTOpleft, pright;
 
  -- Make sure the child exists  IF cleft IS NULL THEN  RETURN 0;  END IF;
  -- Make sure the parent exists  IF pleft IS NULL THEN  RETURN 0;  END IF;
  -- Self-move makes no sense  IF cleft = pleft THEN  RETURN 0;  END IF;
  -- Parent cannot be underneath the child  IF pleft BETWEEN cleft AND cright THEN  RETURN 0;  END IF;
  -- Child may already be in the proper place  IF cleft = pleft+1 THEN  RETURN 1;  END IF;
  IF cleft > pleft THEN   treeshift  := pleft - cleft + 1;  leftbound  := pleft+1;  rightbound := cleft-1;  cwidth
:=cright-cleft+1;  lrange      :=  cright;  rrange     :=  pleft;  ELSE  treeshift  := pleft - cright;  leftbound  :=
cright+ 1;  rightbound := pleft;  cwidth     := cleft-cright-1;  lrange      :=  pleft + 1;  rrange     :=  cleft;  END
IF;

  UPDATE nested_set  SET lft = CASE  WHEN lft BETWEEN leftbound AND rightbound THEN lft + cwidth  WHEN lft BETWEEN
cleftAND cright THEN lft + treeshift  ELSE lft END,  rgt = CASE  WHEN rgt BETWEEN leftbound AND rightbound THEN rgt +
cwidth WHEN rgt BETWEEN cleft AND cright THEN rgt + treeshift  ELSE rgt END;  --            WHERE lft < lrange OR rgt >
rrange; RETURN 1;
 
  END;  $_$;

Can someone help me debug this? It seems all fine. I realize this recipe
is 8 years old, but it should still work, no?

Amiri


В списке pgsql-sql по дате отправления:

Предыдущее
От: Arne Stölck
Дата:
Сообщение: Re: LEFT OUTER JOIN issue
Следующее
От: Andreas
Дата:
Сообщение: How to find broken UTF-8 characters ?