没有在触发器功能中选择表的权限

时间:2013-10-02 22:07:23

标签: sql postgresql triggers postgresql-9.3 clsql

我使用这个PostgreSQL代码创建了数据库“bikini-atoll”:

CREATE TABLE TESTA (
        name character varying NOT NULL,
        age integer NOT NULL,
        PRIMARY KEY(name)
);

CREATE DOMAIN RANK AS character varying
CHECK (
    VALUE = 'bigmac' OR
    VALUE = 'smallmac'
);

CREATE TABLE TESTB (
        name character varying NOT NULL,
        rank character varying NOT NULL,
        PRIMARY KEY(name)
);

CREATE OR REPLACE VIEW TESTAB AS
SELECT * FROM (TESTA
        JOIN
           TESTB
           ON TESTA.name = TESTB.name);


CREATE OR REPLACE RULE TESTAB_INSERT 
AS ON INSERT TO TESTAB
DO INSTEAD (
    INSERT INTO TESTA (name,age) VALUES (NEW.name,NEW.age);
        INSERT INTO TESTB (name,rank) VALUES (NEW.name,NEW.rank);
        )

CREATE OR REPLACE FUNCTION testRankToAge() RETURNS TRIGGER AS $$
DECLARE
    ageRes integer;
BEGIN
    SELECT AGE INTO ageRes
    FROM TESTA
    WHERE name = NEW.name;

    IF (ageRes < 42) AND (NEW.rank = 'bigmac')
    THEN
    RAISE EXCEPTION 'YOU CANNOT BE BIGMAC AT THAT AGE';
    END IF;
END
$$ LANGUAGE plpgsql;

CREATE OR REPLACE TRIGGER rankToAgeTrigger
AFTER INSERT
ON TESTB
    FOR EACH ROW
    EXECUTE PROCEDURE testRankToAge();

DROP ROLE IF EXISTS testUser;
CREATE ROLE testUser WITH PASSWORD '123456' LOGIN;

GRANT INSERT ON TESTAB TO testUser;

现在我希望我的(Common-LISP)程序做一个简单的插入:

(clsql:file-enable-sql-reader-syntax)

(clsql-sys:with-database (db (list "localhost" "bikini-atoll" "testuser" "123456") :database-type :postgresql)
  (clsql-sys:insert-records :into [TESTAB]
                :attributes '([NAME] [AGE] [RANK])
                :values '("sir" 44 "bigmac")
                :database db))

基本上是:

INSERT INTO TESTAB (NAME,AGE,RANK) VALUES ('sir',44,'bigmac');

作为用户testuser(我怀疑这是一个特定于程序语言的问题,而且我更多的是某种糟糕的数据库/触发器设计)。

但(意外)结果是:

Error 42501 / FEHLER:  no permission for relation testa
CONTEXT:  SQL-COMMAND „SELECT AGE              FROM TESTA
    WHERE name = NEW.name“
PL/pgSQL-Funktion testranktoage() LINE 5 AT SQL-Command
  has occurred.

这表明testuser在触发器可能执行操作的任何表上也需要SELECT权限,这看起来有点奇怪,因为我认为视图的主要原因之一是限制/过滤访问权限用户对表的说明,与授予一致性触发器所需的任何SELECT相反。

如何修复/阻止这种曙光的破坏?

1 个答案:

答案 0 :(得分:1)

  

这表明testuser也需要SELECT权限   在任何表上,触发器可能会在

上执行操作

这完全正确。除此之外,还有各种方法。就像SECURITY DEFINER触发函数一样。

这是一个密切相关的答案,详细说明:
Is there a way to disable updates/deletes but still allow triggers to perform them?