@@ -32,11 +32,6 @@ class Postgres extends SQL
3232{
3333 public const MAX_IDENTIFIER_NAME = 63 ;
3434
35- /**
36- * Function that tests a row's permissions against a set of roles with jsonb's ?| operator.
37- */
38- protected const PERMISSIONS_FUNCTION = '_permissions_any ' ;
39-
4035 /**
4136 * @inheritDoc
4237 */
@@ -123,9 +118,6 @@ public function create(string $name): bool
123118 $ name = $ this ->filter ($ name );
124119
125120 if ($ this ->exists ($ name )) {
126- // Schemas created before the function existed get it here.
127- $ this ->createPermissionsFunction ($ name );
128-
129121 return true ;
130122 }
131123
@@ -149,9 +141,6 @@ public function create(string $name): bool
149141 )
150142 " ;
151143 $ this ->getPDO ()->prepare ($ collation )->execute ();
152-
153- $ this ->createPermissionsFunction ($ name );
154-
155144 return $ dbCreation ;
156145 }
157146
@@ -1842,45 +1831,23 @@ protected function getSQLPermissionsCondition(
18421831 throw new DatabaseException ('Unknown permission type: ' . $ type );
18431832 }
18441833
1845- if ($ roles === []) {
1846- return 'FALSE ' ;
1847- }
1848-
18491834 $ column = "{$ this ->quote ($ alias )}. {$ this ->quote ('_permissions ' )}" ;
18501835
1851- // One ?| for all roles keeps the estimate flat however many roles there are; a @> per
1852- // role adds up until the planner gives up on the GIN index. The operator goes through
1853- // the inlined function because PDO reads a lone ? as a positional placeholder, and
1854- // doubling it to escape breaks once a named placeholder is repeated, which the cursor
1855- // conditions do. jsonb_exists_any would avoid both but is not indexable.
1836+ // One ?| for all roles; a @> per role adds to the row estimate until the planner gives
1837+ // up on the GIN index. ?? is PDO's escape for a literal ?, which emulated prepares only
1838+ // accept while no named placeholder appears twice in the statement, so the queries this
1839+ // condition joins bind each value under its own name. jsonb_exists_any would avoid the
1840+ // ? but is not indexable.
18561841 $ permissions = \array_map (
18571842 fn ($ role ) => $ this ->getPDO ()->quote ("{$ type }( \"{$ role }\") " ),
18581843 $ roles
18591844 );
18601845
1861- return "{$ this ->getSQLSchema ()}{$ this ->quote (self ::PERMISSIONS_FUNCTION )}( {$ column }, ARRAY[ " . \implode (', ' , $ permissions ) . ']::text[]) ' ;
1862- }
1846+ if ($ permissions === []) {
1847+ return 'FALSE ' ;
1848+ }
18631849
1864- /**
1865- * Create the function permission checks are written against, unless the schema has it.
1866- *
1867- * @param string $schema
1868- * @return void
1869- */
1870- protected function createPermissionsFunction (string $ schema ): void
1871- {
1872- $ function = "\"{$ schema }\". \"" . self ::PERMISSIONS_FUNCTION . '" ' ;
1873-
1874- // Run through exec, which does not look for placeholders. A concurrent creation of
1875- // the same function is not an error.
1876- $ this ->getPDO ()->exec ("
1877- DO \$\$ BEGIN
1878- CREATE FUNCTION {$ function }(jsonb, text[]) RETURNS boolean
1879- LANGUAGE sql IMMUTABLE PARALLEL SAFE
1880- AS 'SELECT \$1 OPERATOR(pg_catalog.?|) \$2';
1881- EXCEPTION WHEN duplicate_function OR unique_violation THEN NULL;
1882- END \$\$
1883- " );
1850+ return "{$ column } ??| ARRAY[ " . \implode (', ' , $ permissions ) . ']::text[] ' ;
18841851 }
18851852
18861853 /**
0 commit comments