Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1uh58L-00ALPq-Qz for pgsql-general@arkaria.postgresql.org; Wed, 30 Jul 2025 11:38:10 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1uh58I-009B3t-VH for pgsql-general@arkaria.postgresql.org; Wed, 30 Jul 2025 11:38:07 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1uh58I-009B3g-KT for pgsql-general@lists.postgresql.org; Wed, 30 Jul 2025 11:38:06 +0000 Received: from mail-oi1-x229.google.com ([2607:f8b0:4864:20::229]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1uh58D-001YJN-2e for pgsql-general@lists.postgresql.org; Wed, 30 Jul 2025 11:38:02 +0000 Received: by mail-oi1-x229.google.com with SMTP id 5614622812f47-41cbc8da42aso3451843b6e.2 for ; Wed, 30 Jul 2025 04:38:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1753875481; x=1754480281; darn=lists.postgresql.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=/WhA89EnYtdDocMi5OF/jbTbJc7mW00OcPBd6tLrhSc=; b=BBoQK5GvNgkkbVT6qVf8yFayhN2oYm3U2Rpv3dblAj+hoI46QVzpIXgenTbp8hrWU3 0Ou/ejweKzlz5qltoKRTWzeDK0da1XyJ3eSI/PXwOKoGkItbHDtzlrI5yvmhsUxLAnz7 19R4SvikJWmC+OnS4aDyBBlmRBJnHZ0XagN4nrjP7WHsSUPSHUCLdIV9q2P6gcTrT1Eh naBf1mHU0qj+Lepoy7/CTAJGprgYO+0XkeTyz19ZcL/m/XHE2jIecVrOMeb/7VS7oHpJ H2lE2Pgey903Z5j77RV19s+XGZBu8Jxgv226TC7kIpmowceiIJl/lmuIttYODRbiJIoU 8Xvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753875481; x=1754480281; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=/WhA89EnYtdDocMi5OF/jbTbJc7mW00OcPBd6tLrhSc=; b=JtSBnGQca6qFw1sFknoOdfnMSAqDYplkVnvJ8xhVIqrCZh4DM2/A+2fTNvuh5kIZFc hiYqKiQqsTuvbOpNvtzvAXTBv2kZSMTtta7tgOERv/dpGOLXCvtb46juwpFuu69zvuEC BzYw6K7OWQZImKy5JHacXlL7EzDPzqqJ6Qt3PF/nBHNMzShx2YnEIpTmh/DbB451jwik S+lmHYdYaei+l4CNg661FMy2oAxoVHaam1ghvaW+zuwHV5BKzrH56Mlq4M6PEz6aGee9 cvguu6vq0h0yb4Fans5QSTzeexoBh+3b6ZnOi5i8I6x2ZGB2mhvolUHZ/mxNIIa+ZwGe 39Ew== X-Gm-Message-State: AOJu0Yw7rStYwZJ020ed2ubCabhcpQtXheb/BP9RT9cZkwUtkx/+v7HQ KvDrECKtV7jeI2kfz8Bi1Qa8hmViFwM5gmo/+XxrYnrxgTcvG8LC/eC/dvihniIpqRpR7SaoGk8 cS+sS/8SBiAWA5i9HyGiCHDnXF3cVa1FvjaNU X-Gm-Gg: ASbGncuiYNG+qv2E22hDU7cf6stG3XixtsdjAnDtmF5MD/abzNoxYUJT8605kKBn2N9 P3x8Ui36vd02o9TVrqacZhYnfRvN5/FOJAKIeVzfopkisPAG+GcbDd9ebJJ8n1Bi1lIFeU9hnzL Eb0EEU+mvXXVXDsSW2euIpOAhiFRVIpaE1utFBfodr7A+gceia9bwi6QfkhoUnPLgpWZhKzRoto JngzsP09w== X-Google-Smtp-Source: AGHT+IGnsBay25wttiSZj/e8pD9vg6p1eyuTQu1AhnSVs+6W2hM4uGJQ+iIRqcNBESbius5kz9MI3C/3vJx4oIjRuw8= X-Received: by 2002:a05:6808:1795:b0:41c:e002:9bee with SMTP id 5614622812f47-4319a275c44mr1419447b6e.15.1753875480966; Wed, 30 Jul 2025 04:38:00 -0700 (PDT) MIME-Version: 1.0 From: Dominique Devienne Date: Wed, 30 Jul 2025 13:37:49 +0200 X-Gm-Features: Ac12FXzKGbZNrnahpPiymtWdX5J_MIf_5do8Nrh7ruzEARygJBq85kdubuwV4DM Message-ID: Subject: SET LOCAL ROLE inside SECURITY INVOKER (LANGUAGE plpgsql) function To: pgsql-general@lists.postgresql.org Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi. PostgreSQL v17 here. I'm stumped by something, and would like pointers to sort something out. Inside my function, I do: ------------ EXECUTE format('SET LOCAL ROLE %I', schema_owner); raise notice 'CURRENT_USER = %, can DELETE = %', CURRENT_USER, has_table_privilege('SchemaMapping', 'DELETE'); DELETE FROM SchemaMapping WHERE "schema" = schema_name; ----------- PQ: NOTICE: CURRENT_USER = Joe, can DELETE = t ERROR: permission denied for table schemamapping CONTEXT: SQL statement "DELETE FROM SchemaMapping WHERE "schema" = schema_name" PL/pgSQL function foo(text,text) line 28 at SQL statement The raise notice output is correct, and as expected. The DELETE error isn't. How can has_table_privilege() return true, yet the DELETE fail? I don't get it. My setup ensures that the role I SET LOCAL ROLE to, has (indirectly) been granted DMLs on that table. I also double-checked outside the routine, directly in code, for that privilege: c.ctx().setRole(schema_owner); auto rset = pq::exec(c, "select has_table_privilege('SchemaMapping', 'DELETE')"); bool has_delete_mapping = rset.scalar(); BOOST_CHECK(has_delete_mapping); Are there special consideration I'm unaware of, regarding SET ROLE inside routines? (beside the fact you can't SET ROLE in a SECURITY DEFINER routime! As I discovered recently...). I'd really appreciate some help here, as I don't understand what's going on. Thanks, --DD