2011-07-18 2 views
2

postgresql 규칙 내에서 특정 쿼리를 실행 (또는 실행하지 않음)하는 문제가 발생했습니다. 이것은 Postgresql subquery execution within ON UPDATE rule (maybe bug in postgresql?)에 대한 동반자 (그러나 다른 질문)이지만, 결과적으로 쿼리 실행 순서 문제와 달리 postgresql 규칙 내에서 실행되지 않는 특정 쿼리와 관련된 문제가 있습니다. 코드 블록이 실행 된 후PostgreSQL RULE 내에서 VOLATILE 함수 및 INSERT가 실행되지 않습니다.

NOTICE: plphp: debug(): "debug_immutable call 1" 
NOTICE: plphp: debug(): "debug_immutable call 2" 
Total query runtime: 46 ms. 
0 rows retrieved. 

그리고 foo_table 및 bar_table 방송 모두 비어 :

DROP TABLE foo_table; 
DROP TABLE bar_table; 

-------------- 

CREATE TABLE foo_table (c1 text, c2 int); 
CREATE TABLE bar_table (c1 text, c2 int); 

-------------- 

CREATE OR REPLACE FUNCTION debug_immutable(anyelement) RETURNS integer AS $$ 

pg_raise('notice', 'debug(): ' . json_encode($args[0])); 

return rand(1, 10000); 

$$ LANGUAGE PLPHP IMMUTABLE; 

CREATE OR REPLACE FUNCTION debug_volatile(anyelement) RETURNS integer AS $$ 

pg_raise('notice', 'debug(): ' . json_encode($args[0])); 

return rand(1, 10000); 

$$ LANGUAGE PLPHP VOLATILE; 

------------- 

CREATE OR REPLACE RULE foo_update_rule AS ON UPDATE TO foo_table DO INSTEAD 
(

SELECT debug_immutable('debug_immutable call 1'::text); -- Query #1 

SELECT debug_volatile('debug_volatile call 1'::text); -- Query #2 

INSERT INTO foo_table (c1, c2) values ('foo', 123456); -- Query #3 

INSERT INTO bar_table (c1, c2) values ('bar', 123456); -- Query #4 

SELECT debug_immutable('debug_immutable call 2'::text); -- Query #5 

SELECT debug_volatile('debug_volatile call 2'::text); -- Query #6 
); 

----------------------------------------------- 

UPDATE foo_table SET c1 = NULL where c1 = 'aaa'; 

SELECT * FROM foo_table; 

SELECT * FROM bar_table; 

출력 만이 다음을 표시

다음 코드 블록을 고려

# select * from foo_table; 
c1 | c2 
----+---- 
(0 rows) 

# select * from bar_table; 
c1 | c2 
----+---- 
(0 rows) 

결과는 쿼리 # 1 및 # 5 만 실행되고 쿼리 # 2, 3, 4 및 6은 절대로 실행되지 않습니다. 왜 이런거야? 위의 코드 블록을 변경하여 쿼리 # 2, 3, 4 및 6이 실행되도록 할 수 있습니까?

+0

요점은 규칙 시스템을 남용하고 오해하는 것입니다. 조사하려는 결과는 결과 쿼리 계획을 조사하여 수행 할 수 있습니다. – wildplasser

답변

3

불변 기능은 쿼리가 실행되기 전에 계획 단계에서 평가됩니다. 휘발성 코드는 필요에 따라 평가됩니다. 반환 된 행이 0 개이므로 결코 호출되지 않습니다.

+0

당신이 맞아! 업데이트하기 전에 foo_table에 행을 삽입하기 위해 다음 (INSERT INTO foo_table (c1) VALUES ('aaa');)를 추가하고 이제는 모두 6 개의 쿼리가 실행됩니다! 감사! – archmeta

관련 문제