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.96) (envelope-from ) id 1vroHN-007FVl-2c for pgsql-admin@arkaria.postgresql.org; Mon, 16 Feb 2026 02:24:05 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vroHL-003B6t-0i for pgsql-admin@arkaria.postgresql.org; Mon, 16 Feb 2026 02:24:03 +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.96) (envelope-from ) id 1vroHK-003B6k-1x for pgsql-admin@lists.postgresql.org; Mon, 16 Feb 2026 02:24:02 +0000 Received: from mail-yw1-x112d.google.com ([2607:f8b0:4864:20::112d]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1vroHH-00000000oin-36WB for pgsql-admin@lists.postgresql.org; Mon, 16 Feb 2026 02:24:01 +0000 Received: by mail-yw1-x112d.google.com with SMTP id 00721157ae682-796d68083cdso38550917b3.1 for ; Sun, 15 Feb 2026 18:24:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=joeconway.com; s=google; t=1771208640; x=1771813440; darn=lists.postgresql.org; h=content-transfer-encoding:in-reply-to:from:content-language :references:to:subject:user-agent:mime-version:date:message-id:from :to:cc:subject:date:message-id:reply-to; bh=KqEluUWpb1sH+KHhKULUnBdi1tJBiOIQuVHRSecOhlE=; b=URSJZhWNKJiGTbHuN9gZ9LXAxyc5VzpiCgikr+/bkrjpGBVxoQu0M0+K7DfMQeX+HU Ozi0ADmfVg6n1ZtygWM2pQuzGF4LLN8i5/yomxC5XOysH5Di/BmHZhGyDGDn9sIxEQv5 haXTtYYJXZMkUgAuQssjtPXgfTRaXtMls+yeXBcKI+o1BAm5TXEPAoMBhke8ssneADHZ q3D+4gEQtU5RPRdfe0DqrZge2MwLKlRKOMrqkShLHRI/kGAkUJ3KE/sSCIh9ZI2mlqdt JZgB/gMd8jFjD+fpSzBSDRbZOwqYJPpkyuwUehchx90exVO65EZgxb9pbLRvz1iCaYmO Unfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771208640; x=1771813440; h=content-transfer-encoding:in-reply-to:from:content-language :references:to:subject:user-agent:mime-version:date:message-id :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=KqEluUWpb1sH+KHhKULUnBdi1tJBiOIQuVHRSecOhlE=; b=MWtVy36yBNrXXc3xUUvpKMN7WvyrZdxZHohDV2MTnjoelRF+Js2nzJL8V/+Plk/kEl mcloVANt6x2SXDILvdCNt+pA3+fiwOVJuyqjOgFN8+EnqH1nMjHJ1ICl6WdAyR+OPHyw pUy4/1dlfSAdAnLXPOK7L95iaXH0vpUic94EszddhpE+XGtV3ogrAYoL2p8ZZsPc9ZV8 RBS5O/VB2vCe1X4lDtuRv/6MzkBdlQnDDJGPCOOUQ/aruQvp1KdKPCc2Ymg5KIrgA1bB MF4PigoTqzU78rMBbnEtxQ1vhcIeNsks0pXItRWMWqJZM7kAjhSwZGedKSSgBsqvj2uR Rxlw== X-Forwarded-Encrypted: i=1; AJvYcCV8o2bBV1jdNNjQhkYekdv79TZTQQccrkz7KScn56CTTTVk2uYtLp2eY2zP9r+SvhZOkf5iK9uw2f216Q==@lists.postgresql.org X-Gm-Message-State: AOJu0YxTQnDqDVshiu4HNctOFEJjBtXJ31EKW5WnTHEqCRTTdJ/19rdI G1Sizh/+1FQZRNsDjd3oB2S37nQeH+X1ewo1ZZh2c7gQL0hEO5UegWwG+TwqQDubuHo= X-Gm-Gg: AZuq6aIUHhMpQVHH3w0EGeePWoKSBoo5cnTKAUQYlayHBNTejpUBi9lTTwSGFqgGbSf 2rmsZUmJt1gTYb6tVvWJAUOz2Jn9GRSK2Y2T+lXYUYiaIWcFulHkIlPREL707b03ELC1qzbWZl6 TgeWukBfXuBrck8e7cEDxvmqeVsw8CqUvvdTCHfiTf4gU+O+db01yNDx4Me4v7HyisBs2CXJxpT gCXWGf2dEnih/1xGhmpbKq0WoE1352FQBS982KGn4Qa9jY1Y6GuqhlKbu9g3zwankducQXo/SG0 CgCxxnT0PXPcuHurHVXK69/XwA/uE5bVpU19k6gUL20Nhq+F6Z8nZ6BZb8ngYdw4Qc4oNcsAuD2 xpOpFX+O991yeQKnTbTTY235HFj6XoPOwYDtRd582tXfFS361Spi6JpuIM3MxzT9FnwrdXd1n5o UNqIa0/fIIquuJN99Mf4ZuUAs= X-Received: by 2002:a05:690c:c527:b0:794:c6fb:5f2c with SMTP id 00721157ae682-797aa809dbcmr58751307b3.4.1771208639778; Sun, 15 Feb 2026 18:23:59 -0800 (PST) Received: from [192.168.4.42] ([46.110.138.68]) by smtp.gmail.com with ESMTPSA id 00721157ae682-7966c254d82sm95798077b3.39.2026.02.15.18.23.58 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sun, 15 Feb 2026 18:23:59 -0800 (PST) Message-ID: <039f4bde-9195-40b1-ae91-75d50dfc4f57@joeconway.com> Date: Sun, 15 Feb 2026 21:23:58 -0500 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: has_table_privilege To: Edwin UY , Pgsql-admin References: Content-Language: en-US From: Joe Conway In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 2/15/26 16:19, Edwin UY wrote: > Is there no shortcut alternative to using select has_table_privilegeso > it will just check all possible privileges? > > select has_table_privilege('user_or_role','table_name','update'); > select has_table_privilege('user_or_role','table_name','select,insert'); > thought when running select > has_table_privilege('user_or_role','table_name','select,insert,update,delete'); > it will enumerate the privilege. Isn't it not supposed to? No, there is no builtin shortcut, But you can build your own easily enough: 8<----------- CREATE OR REPLACE FUNCTION has_table_privileges ( username text, tablename text, VARIADIC privileges text[] ) RETURNS TABLE (privilege text, granted bool) AS $$ SELECT u.p, has_table_privilege(username, tablename, u.p) FROM UNNEST(privileges) AS u(p) $$ LANGUAGE sql STRICT; CREATE USER joe; GRANT SELECT ON commits TO joe; CREATE USER bob; GRANT SELECT,INSERT,UPDATE ON commits TO bob; SELECT * FROM has_table_privileges('joe', 'commits', 'SELECT', 'INSERT', 'UPDATE', 'DELETE', 'TRUNCATE'); privilege | granted ------------+--------- SELECT | t INSERT | f UPDATE | f DELETE | f TRUNCATE | f (5 rows) SELECT * FROM has_table_privileges('bob', 'commits', 'SELECT', 'INSERT', 'UPDATE', 'DELETE', 'TRUNCATE', 'REFERENCES', 'TRIGGER', 'MAINTAIN'); privilege | granted ------------+--------- SELECT | t INSERT | t UPDATE | t DELETE | f TRUNCATE | f REFERENCES | f TRIGGER | f MAINTAIN | f (8 rows) 8<----------- Or alternatively if you always want to enumerate all possible privileges: 8<----------- CREATE OR REPLACE FUNCTION has_table_privileges ( username text, tablename text ) RETURNS TABLE (privilege text, granted bool) AS $$ WITH u(p) AS ( VALUES ('SELECT'), ('INSERT'), ('UPDATE'), ('DELETE'), ('TRUNCATE'), ('REFERENCES'), ('TRIGGER'), ('MAINTAIN') ) SELECT u.p, has_table_privilege(username, tablename, u.p) FROM u $$ LANGUAGE sql STRICT; SELECT * FROM has_table_privileges('bob', 'commits'); SELECT * FROM has_table_privileges('bob', 'commits'); privilege | granted ------------+--------- SELECT | t INSERT | t UPDATE | t DELETE | f TRUNCATE | f REFERENCES | f TRIGGER | f MAINTAIN | f (8 rows) 8<----------- HTH, -- Joe Conway PostgreSQL Contributors Team Amazon Web Services: https://aws.amazon.com