From 204a7115b7c65c3141c02cf2a1383c604c3c468d Mon Sep 17 00:00:00 2001 From: "okbob@github.com" Date: Wed, 6 Jul 2022 22:25:16 +0200 Subject: [PATCH 13/13] This commit should to help to find and reason why regress test fails on windows server 2019 reported by cfbot --- src/backend/commands/sessionvariable.c | 51 +- .../regress/expected/session_variables.out | 1015 +---------------- src/test/regress/sql/session_variables.sql | 742 +----------- 3 files changed, 91 insertions(+), 1717 deletions(-) diff --git a/src/backend/commands/sessionvariable.c b/src/backend/commands/sessionvariable.c index 6b649a55d1..edbd420056 100644 --- a/src/backend/commands/sessionvariable.c +++ b/src/backend/commands/sessionvariable.c @@ -242,6 +242,7 @@ static bool svariabletypes_equals(SVariableType svt1, SVariableType svt2) { Assert(svt1->typid == svt2->typid); + Assert(svt1 != svt2); /* * for trustworthy check we need to know base type, extension, @@ -287,7 +288,9 @@ svariabletypes_equals(SVariableType svt1, SVariableType svt2) return false; } - if (svt1->natts > 0) + elog(NOTICE, "svariabletypes_equals, svt1->natts: %d, svt2->natts: %d", svt1->natts, svt2->natts); + + if (svt1->natts > 0 || svt2->natts > 0) { int i; @@ -304,6 +307,8 @@ svariabletypes_equals(SVariableType svt1, SVariableType svt2) } } + elog(NOTICE, "svariabletypes_equals, result true"); + return true; } @@ -554,10 +559,12 @@ svartype_verify_composite_fast(SVariableType svt) if (!tupdesc) return false; + elog(NOTICE, "svartype_verify_composite_fast: %d %d", svt->natts, tupdesc->natts); + /* only not dropped attributies are stored */ for (i = 0; i < svt->natts; i++) { - Form_pg_attribute attr; + Form_pg_attribute attr = NULL; /* skip dropped attributies */ while (attrn < tupdesc->natts) @@ -566,9 +573,11 @@ svartype_verify_composite_fast(SVariableType svt) if (!attr->attisdropped) break; + else + elog(NOTICE, "detected dropped column pos1"); } - - if (attrn < tupdesc->natts) + + if (attr && !attr->attisdropped) { SVariableType field_svt = svt->attrs[i].svartype; int64 field_gennum = svt->attrs[i].gennum; @@ -576,11 +585,13 @@ svartype_verify_composite_fast(SVariableType svt) if (field_svt->typid != attr->atttypid) { + elog(NOTICE, "svartype_verify_composite_fast exit11: %u %u", field_svt->typid, attr->atttypid); result = false; break; } else if (field_gennum != field_svt->gennum) { + elog(NOTICE, "svartype_verify_composite_fast exit12: %ld %ld", field_gennum, field_svt->gennum); result = false; break; } @@ -588,6 +599,7 @@ svartype_verify_composite_fast(SVariableType svt) gennum = get_svariable_valid_type_gennum(field_svt); if (field_gennum != gennum) { + elog(NOTICE, "svartype_verify_composite_fast exit13: %ld %ld, ", field_gennum, gennum); result = false; break; } @@ -599,6 +611,10 @@ svartype_verify_composite_fast(SVariableType svt) } } + + elog(NOTICE, "svartype_verify_composite_fast3, result: %d", result); + + /* now only dropped columns can be allowed */ while (attrn < tupdesc->natts) { @@ -606,13 +622,19 @@ svartype_verify_composite_fast(SVariableType svt) if (!attr->attisdropped) { + elog(NOTICE, "svartype_verify_composite_fast exit14"); result = false; break; } + else + elog(NOTICE, "detected dropped column pos2"); + } ReleaseTupleDesc(tupdesc); + elog(NOTICE, "svartype_verify_composite_fast, result: %d", result); + return result; } @@ -648,9 +670,14 @@ get_svariable_valid_type_gennum(SVariableType svt) * fails, we have to run slow check. */ tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(svt->typid)); - if (!(svt->typ_xmin != HeapTupleHeaderGetRawXmin(tuple->t_data) && + if (!(svt->typ_xmin == HeapTupleHeaderGetRawXmin(tuple->t_data) && ItemPointerEquals(&svt->typ_tid, &tuple->t_self))) + { + elog(NOTICE, "fast check disabled 01"); fast_check = false; + } + + elog(NOTICE, "get_svariable_valid_type_gennum (1), fast_check: %d", fast_check); if (fast_check && OidIsValid(svt->extid)) { @@ -682,6 +709,8 @@ get_svariable_valid_type_gennum(SVariableType svt) { SVariableTypeData nsvtd; + elog(NOTICE, "slow check"); + /* * Slow check. We create new SVariableType value. Compare it with * previous value, and if it is different, then we replace old by @@ -690,16 +719,28 @@ get_svariable_valid_type_gennum(SVariableType svt) svariabletype_init(&nsvtd, tuple, svt->typid); +elog(NOTICE, "slow check %d %d", svt->natts, nsvtd.natts); + + if (svariabletypes_equals(svt, &nsvtd)) + { svariabletype_refresh(svt, &nsvtd); +elog(NOTICE, "svariables are equal"); + } else + { svariabletype_update(svt, &nsvtd); +elog(NOTICE, "svariables are not equal"); + + } } ReleaseSysCache(tuple); svt->verified_lxid = MyProc->lxid; +elog(NOTICE, "returned fresh gennum: %ld", svt->gennum); + return svt->gennum; } diff --git a/src/test/regress/expected/session_variables.out b/src/test/regress/expected/session_variables.out index b574afa3af..a57498cc16 100644 --- a/src/test/regress/expected/session_variables.out +++ b/src/test/regress/expected/session_variables.out @@ -1,979 +1,23 @@ -CREATE SCHEMA svartest; -SET search_path = svartest; -CREATE VARIABLE var1 AS integer; -CREATE TEMP VARIABLE var2 AS text; -DROP VARIABLE var1, var2; --- functional interface -CREATE VARIABLE var1 AS numeric; -CREATE ROLE var_test_role; -GRANT USAGE ON SCHEMA svartest TO var_test_role; -SET ROLE TO var_test_role; --- should fail -SELECT var1; -ERROR: permission denied for session variable var1 -SET ROLE TO DEFAULT; -GRANT READ ON VARIABLE var1 TO var_test_role; -SET ROLE TO var_test_role; --- should fail -LET var1 = 10; -ERROR: permission denied for session variable var1 --- should work -SELECT var1; - var1 ------- - -(1 row) - -SET ROLE TO DEFAULT; -GRANT WRITE ON VARIABLE var1 TO var_test_role; -SET ROLE TO var_test_role; --- should work -LET var1 = 333; -SET ROLE TO DEFAULT; -REVOKE ALL ON VARIABLE var1 FROM var_test_role; -CREATE OR REPLACE FUNCTION secure_var() -RETURNS int AS $$ - SELECT svartest.var1::int; -$$ LANGUAGE sql SECURITY DEFINER; -SELECT secure_var(); - secure_var ------------- - 333 -(1 row) - -SET ROLE TO var_test_role; --- should fail -SELECT svartest.var1; -ERROR: permission denied for session variable var1 --- should work; -SELECT secure_var(); - secure_var ------------- - 333 -(1 row) - -SET ROLE TO DEFAULT; -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM generate_series(1,100) g(v) WHERE v = var1; - QUERY PLAN ------------------------------------------------ - Function Scan on pg_catalog.generate_series g - Output: v - Function Call: generate_series(1, 100) - Filter: ((g.v)::numeric = var1) -(4 rows) - -CREATE VIEW schema_var_view AS SELECT var1; -SELECT * FROM schema_var_view; - var1 ------- - 333 -(1 row) - -\c - -SET search_path = svartest; --- should work still, but var will be empty -SELECT * FROM schema_var_view; - var1 ------- - -(1 row) - -LET var1 = pi(); -SELECT var1; - var1 ------------------- - 3.14159265358979 -(1 row) - --- we can see execution plan of LET statement -EXPLAIN (VERBOSE, COSTS OFF) LET var1 = pi(); - QUERY PLAN ----------------------------- - SET SESSION VARIABLE - Result - Output: 3.14159265358979 -(3 rows) - -SELECT var1; - var1 ------------------- - 3.14159265358979 -(1 row) - -CREATE VARIABLE var3 AS int; -CREATE OR REPLACE FUNCTION inc(int) -RETURNS int AS $$ -BEGIN - LET svartest.var3 = COALESCE(svartest.var3 + $1, $1); - RETURN var3; -END; -$$ LANGUAGE plpgsql; -SELECT inc(1); - inc ------ - 1 -(1 row) - -SELECT inc(1); - inc ------ - 2 -(1 row) - -SELECT inc(1); - inc ------ - 3 -(1 row) - -SELECT inc(1) FROM generate_series(1,10); - inc ------ - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 -(10 rows) - -SET ROLE TO var_test_role; --- should fail -LET var3 = 0; -ERROR: permission denied for session variable var3 -SET ROLE TO DEFAULT; -DROP VIEW schema_var_view; -DROP VARIABLE var1 CASCADE; -DROP VARIABLE var3 CASCADE; --- composite variables -CREATE TYPE sv_xyz AS (x int, y int, z numeric(10,2)); -CREATE VARIABLE v1 AS sv_xyz; -CREATE VARIABLE v2 AS sv_xyz; -\d v1 -\d v2 -LET v1 = (1,2,3.14); -LET v2 = (10,20,3.14*10); --- should work too - there are prepared casts -LET v1 = (1,2,3.14); -SELECT v1; - v1 ------------- - (1,2,3.14) -(1 row) - -SELECT v2; - v2 ---------------- - (10,20,31.40) -(1 row) - -SELECT (v1).*; - x | y | z ----+---+------ - 1 | 2 | 3.14 -(1 row) - -SELECT (v2).*; - x | y | z -----+----+------- - 10 | 20 | 31.40 -(1 row) - -SELECT v1.x + v1.z; - ?column? ----------- - 4.14 -(1 row) - -SELECT v2.x + v2.z; - ?column? ----------- - 41.40 -(1 row) - --- access to composite fields should be safe too --- should fail -SET ROLE TO var_test_role; -SELECT v2.x; -ERROR: permission denied for session variable v2 -SET ROLE TO DEFAULT; -DROP VARIABLE v1; -DROP VARIABLE v2; -REVOKE USAGE ON SCHEMA svartest FROM var_test_role; -DROP ROLE var_test_role; --- scalar variables should not be in conflict with qualified column -CREATE VARIABLE varx AS text; -SELECT varx.relname FROM pg_class varx WHERE varx.relname = 'pg_class'; - relname ----------- - pg_class -(1 row) - --- should fail -SELECT varx.xxx; -ERROR: type text is not composite --- variables can be updated under RO transaction -BEGIN; -SET TRANSACTION READ ONLY; -LET varx = 'hello'; -COMMIT; -SELECT varx; - varx -------- - hello -(1 row) - -DROP VARIABLE varx; -CREATE TYPE t1 AS (a int, b numeric, c text); -CREATE VARIABLE v1 AS t1; -LET v1 = (1, pi(), 'hello'); -SELECT v1; - v1 ----------------------------- - (1,3.14159265358979,hello) -(1 row) - -LET v1.b = 10.2222; -SELECT v1; - v1 -------------------- - (1,10.2222,hello) -(1 row) - --- should fail -LET v1.x = 10; -ERROR: cannot assign to field "x" of column or variable "v1" because there is no such column in data type t1 -LINE 1: LET v1.x = 10; - ^ -DROP VARIABLE v1; -DROP TYPE t1; --- arrays are supported -CREATE VARIABLE va1 AS numeric[]; -LET va1 = ARRAY[1.1,2.1]; -LET va1[1] = 10.1; -SELECT va1; - va1 ------------- - {10.1,2.1} -(1 row) - -CREATE TYPE ta2 AS (a numeric, b numeric[]); -CREATE VARIABLE va2 AS ta2; -LET va2 = (10.1, ARRAY[0.0, 0.0]); -LET va2.a = 10.2; -SELECT va2; - va2 --------------------- - (10.2,"{0.0,0.0}") -(1 row) - -LET va2.b[1] = 10.3; -SELECT va2; - va2 ---------------------- - (10.2,"{10.3,0.0}") -(1 row) - -DROP VARIABLE va1; -DROP VARIABLE va2; -DROP TYPE ta2; --- default values -CREATE VARIABLE v1 AS numeric DEFAULT pi(); -LET v1 = v1 * 2; -SELECT v1; - v1 ------------------- - 6.28318530717958 -(1 row) - -CREATE TYPE t2 AS (a numeric, b text); -CREATE VARIABLE v2 AS t2 DEFAULT (NULL, 'Hello'); -LET svartest.v2.a = pi(); -SELECT v2; - v2 --------------------------- - (3.14159265358979,Hello) -(1 row) - --- should fail due dependency -DROP TYPE t2; -ERROR: cannot drop type t2 because other objects depend on it -DETAIL: session variable v2 depends on type t2 -HINT: Use DROP ... CASCADE to drop the dependent objects too. --- should be ok -DROP VARIABLE v1; -DROP VARIABLE v2; --- tests of alters -CREATE SCHEMA var_schema1; -CREATE SCHEMA var_schema2; -CREATE VARIABLE var_schema1.var1 AS integer; -LET var_schema1.var1 = 1000; -SELECT var_schema1.var1; - var1 ------- - 1000 -(1 row) - -ALTER VARIABLE var_schema1.var1 SET SCHEMA var_schema2; -SELECT var_schema2.var1; - var1 ------- - 1000 -(1 row) - -CREATE ROLE var_test_role; -ALTER VARIABLE var_schema2.var1 OWNER TO var_test_role; -SET ROLE TO var_test_role; --- should fail, no access to schema var_schema2.var -SELECT var_schema2.var1; -ERROR: permission denied for schema var_schema2 -DROP VARIABLE var_schema2.var1; -ERROR: permission denied for schema var_schema2 -SET ROLE TO DEFAULT; -ALTER VARIABLE var_schema2.var1 SET SCHEMA public; -SET ROLE TO var_test_role; -SELECT public.var1; - var1 ------- - 1000 -(1 row) - -ALTER VARIABLE public.var1 RENAME TO var1_renamed; -SELECT public.var1_renamed; - var1_renamed --------------- - 1000 -(1 row) - -DROP VARIABLE public.var1_renamed; -SET ROLE TO DEFAULt; --- default rights test -ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON VARIABLES TO var_test_role; -CREATE VARIABLE public.var2 AS int; -SET ROLE TO var_test_role; --- should be ok -LET public.var2 = 100; -SELECT public.var2; - var2 ------- - 100 -(1 row) - -SET ROLE TO DEFAULt; -DROP VARIABLE public.var2; -DROP OWNED BY var_test_role; -DROP ROLE var_test_role; -CREATE VARIABLE xx AS text DEFAULT 'hello'; -SELECT xx, upper(xx); - xx | upper --------+------- - hello | HELLO -(1 row) - -LET xx = 'Hi'; -SELECT xx; - xx ----- - Hi -(1 row) - -DROP VARIABLE xx; --- ON TRANSACTION END RESET tests -CREATE VARIABLE t1 AS int DEFAULT -1 ON TRANSACTION END RESET; -BEGIN; - SELECT t1; - t1 ----- - -1 -(1 row) - - LET t1 = 100; - SELECT t1; - t1 ------ - 100 -(1 row) - -COMMIT; -SELECT t1; - t1 ----- - -1 -(1 row) - -BEGIN; - SELECT t1; - t1 ----- - -1 -(1 row) - - LET t1 = 100; - SELECT t1; - t1 ------ - 100 -(1 row) - -ROLLBACK; -SELECT t1; - t1 ----- - -1 -(1 row) - -DROP VARIABLE t1; -CREATE VARIABLE v1 AS int DEFAULT 0; -CREATE VARIABLE v2 AS text DEFAULT 'none'; -LET v1 = 100; -LET v2 = 'Hello'; -SELECT v1, v2; - v1 | v2 ------+------- - 100 | Hello -(1 row) - -LET v1 = DEFAULT; -LET v2 = DEFAULT; -SELECT v1, v2; - v1 | v2 -----+------ - 0 | none -(1 row) - -DROP VARIABLE v1; -DROP VARIABLE v2; --- ON COMMIT DROP tests --- should be 0 always -SELECT count(*) FROM pg_variable; - count -------- - 0 -(1 row) - -CREATE TEMP VARIABLE g AS int ON COMMIT DROP; -SELECT count(*) FROM pg_variable; - count -------- - 0 -(1 row) - -BEGIN; - CREATE TEMP VARIABLE g AS int ON COMMIT DROP; -COMMIT; -SELECT count(*) FROM pg_variable; - count -------- - 0 -(1 row) - -BEGIN; - CREATE TEMP VARIABLE g AS int ON COMMIT DROP; -ROLLBACK; -SELECT count(*) FROM pg_variable; - count -------- - 0 -(1 row) - --- test on query with workers -CREATE TABLE svar_test(a int); -INSERT INTO svar_test SELECT * FROM generate_series(1,1000000); -ANALYZE svar_test; -CREATE VARIABLE zero int; -LET zero = 0; --- parallel workers should be used -EXPLAIN (costs off) SELECT count(*) FROM svar_test WHERE a%10 = zero; - QUERY PLAN --------------------------------------------------- - Finalize Aggregate - -> Gather - Workers Planned: 2 - -> Partial Aggregate - -> Parallel Seq Scan on svar_test - Filter: ((a % 10) = zero) -(6 rows) - --- result should be 100000 -SELECT count(*) FROM svar_test WHERE a%10 = zero; - count --------- - 100000 -(1 row) - -LET zero = (SELECT count(*) FROM svar_test); --- result should be 1000000 -SELECT zero; - zero ---------- - 1000000 -(1 row) - --- parallel workers should be used -EXPLAIN (costs off) LET zero = (SELECT count(*) FROM svar_test); - QUERY PLAN ----------------------------------------------------------- - SET SESSION VARIABLE - Result - InitPlan 1 (returns $1) - -> Finalize Aggregate - -> Gather - Workers Planned: 2 - -> Partial Aggregate - -> Parallel Seq Scan on svar_test -(8 rows) - -DROP TABLE svar_test; -DROP VARIABLE zero; --- use variables in prepared statements -CREATE VARIABLE v AS numeric; -LET v = 3.14; --- use variables in views -CREATE VIEW vv AS SELECT COALESCE(v, 0) + 1000 AS result; -SELECT * FROM vv; - result ---------- - 1003.14 -(1 row) - --- start a new session -\c -SET search_path to svartest; -SELECT * FROM vv; - result --------- - 1000 -(1 row) - -LET v = 3.14; -SELECT * FROM vv; - result ---------- - 1003.14 -(1 row) - --- should fail, dependency -DROP VARIABLE v; -ERROR: cannot drop session variable v because other objects depend on it -DETAIL: view vv depends on session variable v -HINT: Use DROP ... CASCADE to drop the dependent objects too. --- should be ok -DROP VARIABLE v CASCADE; -NOTICE: drop cascades to view vv --- other features -CREATE VARIABLE dt AS integer DEFAULT 0; -LET dt = 100; -SELECT dt; - dt ------ - 100 -(1 row) - -DISCARD VARIABLES; -SELECT dt; - dt ----- - 0 -(1 row) - -DROP VARIABLE dt; --- NOT NULL -CREATE VARIABLE v1 AS int NOT NULL; -CREATE VARIABLE v2 AS int NOT NULL DEFAULT NULL; --- should fail -SELECT v1; -ERROR: null value is not allowed for NOT NULL session variable "svartest.v1" -DETAIL: The session variable was not initialized yet. -SELECT v2; -ERROR: null value is not allowed for NOT NULL session variable "svartest.v2" -LET v1 = NULL; -ERROR: null value is not allowed for NOT NULL session variable "svartest.v1" -LET v2 = NULL; -ERROR: null value is not allowed for NOT NULL session variable "svartest.v2" -LET v1 = DEFAULT; -ERROR: null value is not allowed for NOT NULL session variable "svartest.v1" -LET v2 = DEFAULT; -ERROR: null value is not allowed for NOT NULL session variable "svartest.v2" --- should be ok -LET v1 = 100; -LET v2 = 1000; -SELECT v1, v2; - v1 | v2 ------+------ - 100 | 1000 -(1 row) - -DROP VARIABLE v1; -DROP VARIABLE v2; -CREATE VARIABLE tv AS int; -CREATE VARIABLE IF NOT EXISTS tv AS int; -NOTICE: session variable "tv" already exists, skipping -DROP VARIABLE tv; -CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; -SELECT iv; - iv ------ - 100 -(1 row) - --- should fail; -LET iv = 10000; -ERROR: session variable "svartest.iv" is declared IMMUTABLE -DROP VARIABLE iv; --- different order -CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; --- should to fail -LET iv = 10000; -ERROR: session variable "svartest.iv" is declared IMMUTABLE --- should be ok -SELECT iv; - iv ------ - 100 -(1 row) - -DROP VARIABLE iv; -CREATE IMMUTABLE VARIABLE iv AS int; --- should be ok -LET iv = NULL; --- should fail -LET iv = NULL; -ERROR: session variable "svartest.iv" is declared IMMUTABLE -DROP VARIABLE iv; --- create variable inside plpgsql block -DO $$ -BEGIN - CREATE VARIABLE do_test_svar AS date DEFAULT '2000-01-01'; -END; -$$; -SELECT do_test_svar; - do_test_svar --------------- - 01-01-2000 -(1 row) - -DROP VARIABLE do_test_svar; --- should fail -CREATE IMMUTABLE VARIABLE xx AS int NOT NULL; -ERROR: IMMUTABLE NOT NULL variable requires default expression --- REASSIGN OWNED test -CREATE ROLE var_test_role1; -CREATE ROLE var_test_role2; -CREATE VARIABLE xxx_var AS int; -ALTER VARIABLE xxx_var OWNER TO var_test_role1; -REASSIGN OWNED BY var_test_role1 to var_test_role2; -SELECT varowner::regrole FROM pg_variable WHERE varname = 'xxx_var'; - varowner ----------------- - var_test_role2 -(1 row) - -DROP OWNED BY var_test_role1; -DROP ROLE var_test_role1; -SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; - count -------- - 1 -(1 row) - -DROP OWNED BY var_test_role2; -DROP ROLE var_test_role2; -SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; - count -------- - 0 -(1 row) - --- creating, dropping temporary variable -BEGIN; -CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; -LET tempvar = 100; -SAVEPOINT s1; -DROP VARIABLE tempvar; -ROLLBACK TO s1; -SELECT tempvar; - tempvar ---------- - 100 -(1 row) - -COMMIT; --- should to fail -LET tempvar = 100; -ERROR: session variable "tempvar" doesn't exist -LINE 1: LET tempvar = 100; - ^ -BEGIN; -SAVEPOINT s1; -CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; -LET tempvar = 100; -ROLLBACK TO s1; -COMMIT; --- should to fail -LET tempvar = 100; -ERROR: session variable "tempvar" doesn't exist -LINE 1: LET tempvar = 100; - ^ -CREATE VARIABLE var1 AS int; -LET var1 = 100; -BEGIN; -DROP VARIABLE var1; -ROLLBACK; -SELECT var1; - var1 ------- - 100 -(1 row) - -DROP VARIABLE var1; -CREATE VARIABLE var1 AS int DEFAULT 100; -COMMENT ON VARIABLE var1 IS 'some variable comment'; -SELECT pg_catalog.obj_description(oid, 'pg_variable') FROM pg_variable WHERE varname = 'var1'; - obj_description ------------------------ - some variable comment -(1 row) - -DROP VARIABLE var1; -CREATE TABLE xxtab(avar int); -CREATE TYPE xxtype AS (avar int); -CREATE VARIABLE xxtab AS xxtype; -INSERT INTO xxtab VALUES(10); --- it is ambiguous, but columns are preferred -SELECT xxtab.avar FROM xxtab; - avar ------- - 10 -(1 row) - -SET session_variables_ambiguity_warning TO on; -SELECT xxtab.avar FROM xxtab; -WARNING: session variable "xxtab.avar" is shadowed -LINE 1: SELECT xxtab.avar FROM xxtab; - ^ -DETAIL: Session variables can be shadowed by columns, routine's variables and routine's arguments with same name. - avar ------- - 10 -(1 row) - -SET search_path = svartest; -CREATE VARIABLE testvar as int; --- plpgsql variables are preferred against session variables -DO $$ -<> -DECLARE testvar int; -BEGIN - -- should be ok without warning - LET testvar = 100; - -- should be ok without warning - testvar := 1000; - -- should be ok without warning - RAISE NOTICE 'session variable is %', svartest.testvar; - -- should be ok without warning - RAISE NOTICE 'plpgsql variable is %', myblock.testvar; - -- should to print plpgsql variable with warning - RAISE NOTICE 'variable is %', testvar; -END; -$$; -NOTICE: session variable is 100 -NOTICE: plpgsql variable is 1000 -WARNING: session variable "testvar" is shadowed -LINE 1: testvar - ^ -DETAIL: Session variables can be shadowed by columns, routine's variables and routine's arguments with same name. -QUERY: testvar -NOTICE: variable is 1000 -DROP VARIABLE testvar; -SET session_variables_ambiguity_warning TO default; --- should be ok -SELECT avar FROM xxtab; - avar ------- - 10 -(1 row) - -CREATE VARIABLE public.avar AS int; --- should to fail -SELECT avar FROM xxtab; - avar ------- - 10 -(1 row) - --- should be ok -SELECT public.avar FROM xxtab; - avar ------- - -(1 row) - -DROP VARIABLE xxtab; -SELECT xxtab.avar FROM xxtab; - avar ------- - 10 -(1 row) - -DROP VARIABLE public.avar; -DROP TYPE xxtype; -DROP TABLE xxtab; --- test of plan cache invalidation -CREATE VARIABLE xx AS int; -SET plan_cache_mode = force_generic_plan; -PREPARE pp AS SELECT xx; -EXECUTE pp; - xx ----- - -(1 row) - -DROP VARIABLE xx; -CREATE VARIABLE xx AS int; --- should to work -EXECUTE pp; - xx ----- - -(1 row) - -DROP VARIABLE xx; -DEALLOCATE pp; -SET plan_cache_mode = DEFAULT; -CREATE ROLE var_test_role; -CREATE SCHEMA vartest; -GRANT USAGE ON SCHEMA vartest TO var_test_role; -CREATE VARIABLE vartest.x AS int; -CREATE VARIABLE vartest.y AS int; -LET vartest.x = 100; -LET vartest.y = 101; -GRANT READ ON ALL VARIABLES IN SCHEMA vartest TO var_test_role; -SET ROLE TO var_test_role; -SELECT vartest.x, vartest.y; - x | y ------+----- - 100 | 101 -(1 row) - -SET ROLE TO DEFAULT; -REVOKE READ ON ALL VARIABLES IN SCHEMA vartest FROM var_test_role; -SET ROLE TO var_test_role; --- should to fail -SELECT vartest.x; -ERROR: permission denied for session variable x -SELECT vartest.y; -ERROR: permission denied for session variable y -SET ROLE TO DEFAULT; -DROP VARIABLE vartest.x, vartest.y; -DROP SCHEMA vartest; -DROP ROLE var_test_role; --- test cached plan -CREATE VARIABLE v1 AS text; -CREATE VARIABLE v2 AS int; -CREATE VARIABLE v3 AS int; -LET v1 = 'test'; -LET v2 = 10; -LET v3 = 5; -PREPARE q1 AS SELECT v1 || i FROM generate_series(1, v2) g(i) WHERE i IN (v2, v3); -SET plan_cache_mode to force_generic_plan; -EXECUTE q1; - ?column? ----------- - test5 - test10 -(2 rows) - -EXPLAIN EXECUTE q1; - QUERY PLAN ------------------------------------------------------------------------ - Function Scan on generate_series g (cost=0.00..0.14 rows=2 width=32) - Filter: (i = ANY (ARRAY[v2, v3])) -(2 rows) - --- dependecy check -DROP VARIABLE v3; --- recreate v3 again -CREATE VARIABLE v3 AS int DEFAULT 6; --- should to work, the plan should be recreated -EXECUTE q1; - ?column? ----------- - test6 - test10 -(2 rows) - -DEALLOCATE q1; --- fill v1 by long text -LET v1 = repeat(' ', 10000); -PREPARE q1 AS SELECT length(v1); -EXECUTE q1; - length --------- - 10000 -(1 row) - -LET v1 = repeat(' ', 5000); -EXECUTE q1; - length --------- - 5000 -(1 row) - -DEALLOCATE q1; -SET plan_cache_mode to default; -DROP VARIABLE v1, v2, v3; -CREATE ROLE var_test_role; -CREATE VARIABLE public.v1 AS int DEFAULT 0; --- check acl when variable is acessed by simple eval expr method -CREATE OR REPLACE FUNCTION public.fx_var(int) -RETURNS int AS $$ -DECLARE xx int; -BEGIN - xx := public.v1 + $1; - RETURN xx; -END; -$$ LANGUAGE plpgsql; --- should be ok -SELECT public.fx_var(0); - fx_var --------- - 0 -(1 row) - -SET ROLE TO var_test_role; --- should to fail -SELECT public.fx_var(0); -ERROR: permission denied for session variable v1 -CONTEXT: PL/pgSQL function public.fx_var(integer) line 4 at assignment -SET ROLE TO default; -GRANT READ ON VARIABLE public.v1 TO var_test_role; -SET ROLE TO var_test_role; --- should be ok -SELECT public.fx_var(0); - fx_var --------- - 0 -(1 row) - -SET ROLE TO default; -REVOKE READ ON VARIABLE public.v1 FROM var_test_role; -SET ROLE TO var_test_role; --- should be fail -SELECT public.fx_var(0); -ERROR: permission denied for session variable v1 -CONTEXT: PL/pgSQL function public.fx_var(integer) line 4 at assignment -SET ROLE TO DEFAULT; -DROP FUNCTION public.fx_var(int); -DROP VARIABLE public.v1; -DROP ROLE var_test_role; CREATE TYPE public.svar_test_type AS (a int, b int, c numeric); CREATE VARIABLE public.svar AS public.svar_test_type; LET public.svar = ROW(10,20,30); SELECT public.svar; +NOTICE: get_svariable_valid_type_gennum (1), fast_check: 1 +NOTICE: svartype_verify_composite_fast: 3 3 +NOTICE: svartype_verify_composite_fast3, result: 1 +NOTICE: svartype_verify_composite_fast, result: 1 +NOTICE: returned fresh gennum: 1 + svar +------------ + (10,20,30) +(1 row) + +SELECT public.svar; +NOTICE: get_svariable_valid_type_gennum (1), fast_check: 1 +NOTICE: svartype_verify_composite_fast: 3 3 +NOTICE: svartype_verify_composite_fast3, result: 1 +NOTICE: svartype_verify_composite_fast, result: 1 +NOTICE: returned fresh gennum: 1 svar ------------ (10,20,30) @@ -982,14 +26,41 @@ SELECT public.svar; ALTER TYPE public.svar_test_type DROP ATTRIBUTE c; -- should to fail SELECT public.svar; +NOTICE: get_svariable_valid_type_gennum (1), fast_check: 1 +NOTICE: svartype_verify_composite_fast: 3 3 +NOTICE: detected dropped column pos1 +NOTICE: svartype_verify_composite_fast3, result: 0 +NOTICE: svartype_verify_composite_fast, result: 0 +NOTICE: slow check +NOTICE: slow check 3 2 +NOTICE: svariabletypes_equals, svt1->natts: 3, svt2->natts: 2 +NOTICE: svariables are not equal +NOTICE: returned fresh gennum: 2 ERROR: format of stored value of "public.svar" session variable can be outdated ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; -- should to fail too (different type, different generation number); SELECT public.svar; ERROR: format of stored value of "public.svar" session variable can be outdated LET public.svar = ROW(10,20,30); +NOTICE: get_svariable_valid_type_gennum (1), fast_check: 1 +NOTICE: svartype_verify_composite_fast: 2 4 +NOTICE: svartype_verify_composite_fast3, result: 1 +NOTICE: detected dropped column pos2 +NOTICE: svartype_verify_composite_fast exit14 +NOTICE: svartype_verify_composite_fast, result: 0 +NOTICE: slow check +NOTICE: slow check 2 3 +NOTICE: svariabletypes_equals, svt1->natts: 2, svt2->natts: 3 +NOTICE: svariables are not equal +NOTICE: returned fresh gennum: 3 -- should be ok again for new value SELECT public.svar; +NOTICE: get_svariable_valid_type_gennum (1), fast_check: 1 +NOTICE: svartype_verify_composite_fast: 3 4 +NOTICE: detected dropped column pos1 +NOTICE: svartype_verify_composite_fast3, result: 1 +NOTICE: svartype_verify_composite_fast, result: 1 +NOTICE: returned fresh gennum: 3 svar ------------ (10,20,30) diff --git a/src/test/regress/sql/session_variables.sql b/src/test/regress/sql/session_variables.sql index 044d034ea8..73294b29b4 100644 --- a/src/test/regress/sql/session_variables.sql +++ b/src/test/regress/sql/session_variables.sql @@ -1,743 +1,3 @@ -CREATE SCHEMA svartest; - -SET search_path = svartest; - -CREATE VARIABLE var1 AS integer; -CREATE TEMP VARIABLE var2 AS text; - -DROP VARIABLE var1, var2; - --- functional interface -CREATE VARIABLE var1 AS numeric; - -CREATE ROLE var_test_role; -GRANT USAGE ON SCHEMA svartest TO var_test_role; - -SET ROLE TO var_test_role; - --- should fail -SELECT var1; - -SET ROLE TO DEFAULT; - -GRANT READ ON VARIABLE var1 TO var_test_role; - -SET ROLE TO var_test_role; --- should fail -LET var1 = 10; --- should work -SELECT var1; - -SET ROLE TO DEFAULT; - -GRANT WRITE ON VARIABLE var1 TO var_test_role; - -SET ROLE TO var_test_role; - --- should work -LET var1 = 333; - -SET ROLE TO DEFAULT; - -REVOKE ALL ON VARIABLE var1 FROM var_test_role; - -CREATE OR REPLACE FUNCTION secure_var() -RETURNS int AS $$ - SELECT svartest.var1::int; -$$ LANGUAGE sql SECURITY DEFINER; - -SELECT secure_var(); - -SET ROLE TO var_test_role; - --- should fail -SELECT svartest.var1; - --- should work; -SELECT secure_var(); - -SET ROLE TO DEFAULT; - -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM generate_series(1,100) g(v) WHERE v = var1; - -CREATE VIEW schema_var_view AS SELECT var1; - -SELECT * FROM schema_var_view; - -\c - - -SET search_path = svartest; - --- should work still, but var will be empty -SELECT * FROM schema_var_view; - -LET var1 = pi(); - -SELECT var1; - --- we can see execution plan of LET statement -EXPLAIN (VERBOSE, COSTS OFF) LET var1 = pi(); - -SELECT var1; - -CREATE VARIABLE var3 AS int; - -CREATE OR REPLACE FUNCTION inc(int) -RETURNS int AS $$ -BEGIN - LET svartest.var3 = COALESCE(svartest.var3 + $1, $1); - RETURN var3; -END; -$$ LANGUAGE plpgsql; - -SELECT inc(1); -SELECT inc(1); -SELECT inc(1); - -SELECT inc(1) FROM generate_series(1,10); - -SET ROLE TO var_test_role; - --- should fail -LET var3 = 0; - -SET ROLE TO DEFAULT; - -DROP VIEW schema_var_view; - -DROP VARIABLE var1 CASCADE; -DROP VARIABLE var3 CASCADE; - --- composite variables - -CREATE TYPE sv_xyz AS (x int, y int, z numeric(10,2)); - -CREATE VARIABLE v1 AS sv_xyz; -CREATE VARIABLE v2 AS sv_xyz; - -\d v1 -\d v2 - -LET v1 = (1,2,3.14); -LET v2 = (10,20,3.14*10); - --- should work too - there are prepared casts -LET v1 = (1,2,3.14); - -SELECT v1; -SELECT v2; -SELECT (v1).*; -SELECT (v2).*; - -SELECT v1.x + v1.z; -SELECT v2.x + v2.z; - --- access to composite fields should be safe too --- should fail -SET ROLE TO var_test_role; - -SELECT v2.x; - -SET ROLE TO DEFAULT; - -DROP VARIABLE v1; -DROP VARIABLE v2; - -REVOKE USAGE ON SCHEMA svartest FROM var_test_role; -DROP ROLE var_test_role; - --- scalar variables should not be in conflict with qualified column -CREATE VARIABLE varx AS text; -SELECT varx.relname FROM pg_class varx WHERE varx.relname = 'pg_class'; - --- should fail -SELECT varx.xxx; - --- variables can be updated under RO transaction - -BEGIN; -SET TRANSACTION READ ONLY; -LET varx = 'hello'; -COMMIT; - -SELECT varx; - -DROP VARIABLE varx; - -CREATE TYPE t1 AS (a int, b numeric, c text); - -CREATE VARIABLE v1 AS t1; -LET v1 = (1, pi(), 'hello'); -SELECT v1; -LET v1.b = 10.2222; -SELECT v1; - --- should fail -LET v1.x = 10; - -DROP VARIABLE v1; -DROP TYPE t1; - --- arrays are supported -CREATE VARIABLE va1 AS numeric[]; -LET va1 = ARRAY[1.1,2.1]; -LET va1[1] = 10.1; -SELECT va1; - -CREATE TYPE ta2 AS (a numeric, b numeric[]); -CREATE VARIABLE va2 AS ta2; -LET va2 = (10.1, ARRAY[0.0, 0.0]); -LET va2.a = 10.2; -SELECT va2; -LET va2.b[1] = 10.3; -SELECT va2; - -DROP VARIABLE va1; -DROP VARIABLE va2; -DROP TYPE ta2; - --- default values -CREATE VARIABLE v1 AS numeric DEFAULT pi(); -LET v1 = v1 * 2; -SELECT v1; - -CREATE TYPE t2 AS (a numeric, b text); -CREATE VARIABLE v2 AS t2 DEFAULT (NULL, 'Hello'); -LET svartest.v2.a = pi(); -SELECT v2; - --- should fail due dependency -DROP TYPE t2; - --- should be ok -DROP VARIABLE v1; -DROP VARIABLE v2; - --- tests of alters -CREATE SCHEMA var_schema1; -CREATE SCHEMA var_schema2; - -CREATE VARIABLE var_schema1.var1 AS integer; -LET var_schema1.var1 = 1000; -SELECT var_schema1.var1; -ALTER VARIABLE var_schema1.var1 SET SCHEMA var_schema2; -SELECT var_schema2.var1; - -CREATE ROLE var_test_role; - -ALTER VARIABLE var_schema2.var1 OWNER TO var_test_role; -SET ROLE TO var_test_role; - --- should fail, no access to schema var_schema2.var -SELECT var_schema2.var1; -DROP VARIABLE var_schema2.var1; - -SET ROLE TO DEFAULT; - -ALTER VARIABLE var_schema2.var1 SET SCHEMA public; - -SET ROLE TO var_test_role; -SELECT public.var1; - -ALTER VARIABLE public.var1 RENAME TO var1_renamed; - -SELECT public.var1_renamed; - -DROP VARIABLE public.var1_renamed; - -SET ROLE TO DEFAULt; - --- default rights test -ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON VARIABLES TO var_test_role; - -CREATE VARIABLE public.var2 AS int; - -SET ROLE TO var_test_role; - --- should be ok -LET public.var2 = 100; -SELECT public.var2; - -SET ROLE TO DEFAULt; - -DROP VARIABLE public.var2; -DROP OWNED BY var_test_role; - -DROP ROLE var_test_role; - -CREATE VARIABLE xx AS text DEFAULT 'hello'; - -SELECT xx, upper(xx); - -LET xx = 'Hi'; - -SELECT xx; - -DROP VARIABLE xx; - --- ON TRANSACTION END RESET tests -CREATE VARIABLE t1 AS int DEFAULT -1 ON TRANSACTION END RESET; - -BEGIN; - SELECT t1; - LET t1 = 100; - SELECT t1; -COMMIT; - -SELECT t1; - -BEGIN; - SELECT t1; - LET t1 = 100; - SELECT t1; -ROLLBACK; - -SELECT t1; - -DROP VARIABLE t1; - -CREATE VARIABLE v1 AS int DEFAULT 0; -CREATE VARIABLE v2 AS text DEFAULT 'none'; - -LET v1 = 100; -LET v2 = 'Hello'; -SELECT v1, v2; -LET v1 = DEFAULT; -LET v2 = DEFAULT; -SELECT v1, v2; - -DROP VARIABLE v1; -DROP VARIABLE v2; - --- ON COMMIT DROP tests --- should be 0 always -SELECT count(*) FROM pg_variable; - -CREATE TEMP VARIABLE g AS int ON COMMIT DROP; - -SELECT count(*) FROM pg_variable; - -BEGIN; - CREATE TEMP VARIABLE g AS int ON COMMIT DROP; -COMMIT; - -SELECT count(*) FROM pg_variable; - -BEGIN; - CREATE TEMP VARIABLE g AS int ON COMMIT DROP; -ROLLBACK; - -SELECT count(*) FROM pg_variable; - --- test on query with workers -CREATE TABLE svar_test(a int); -INSERT INTO svar_test SELECT * FROM generate_series(1,1000000); -ANALYZE svar_test; -CREATE VARIABLE zero int; -LET zero = 0; - --- parallel workers should be used -EXPLAIN (costs off) SELECT count(*) FROM svar_test WHERE a%10 = zero; - --- result should be 100000 -SELECT count(*) FROM svar_test WHERE a%10 = zero; - -LET zero = (SELECT count(*) FROM svar_test); - --- result should be 1000000 -SELECT zero; - --- parallel workers should be used -EXPLAIN (costs off) LET zero = (SELECT count(*) FROM svar_test); - -DROP TABLE svar_test; -DROP VARIABLE zero; - --- use variables in prepared statements -CREATE VARIABLE v AS numeric; -LET v = 3.14; - --- use variables in views -CREATE VIEW vv AS SELECT COALESCE(v, 0) + 1000 AS result; -SELECT * FROM vv; - --- start a new session -\c - -SET search_path to svartest; - -SELECT * FROM vv; -LET v = 3.14; -SELECT * FROM vv; - --- should fail, dependency -DROP VARIABLE v; - --- should be ok -DROP VARIABLE v CASCADE; - --- other features -CREATE VARIABLE dt AS integer DEFAULT 0; - -LET dt = 100; -SELECT dt; - -DISCARD VARIABLES; - -SELECT dt; - -DROP VARIABLE dt; - --- NOT NULL -CREATE VARIABLE v1 AS int NOT NULL; -CREATE VARIABLE v2 AS int NOT NULL DEFAULT NULL; - --- should fail -SELECT v1; -SELECT v2; -LET v1 = NULL; -LET v2 = NULL; -LET v1 = DEFAULT; -LET v2 = DEFAULT; - --- should be ok -LET v1 = 100; -LET v2 = 1000; -SELECT v1, v2; - -DROP VARIABLE v1; -DROP VARIABLE v2; - -CREATE VARIABLE tv AS int; -CREATE VARIABLE IF NOT EXISTS tv AS int; -DROP VARIABLE tv; - -CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; -SELECT iv; - --- should fail; -LET iv = 10000; - -DROP VARIABLE iv; - --- different order -CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; --- should to fail -LET iv = 10000; --- should be ok -SELECT iv; - -DROP VARIABLE iv; - -CREATE IMMUTABLE VARIABLE iv AS int; - --- should be ok -LET iv = NULL; - --- should fail -LET iv = NULL; - -DROP VARIABLE iv; - --- create variable inside plpgsql block -DO $$ -BEGIN - CREATE VARIABLE do_test_svar AS date DEFAULT '2000-01-01'; -END; -$$; - -SELECT do_test_svar; - -DROP VARIABLE do_test_svar; - --- should fail -CREATE IMMUTABLE VARIABLE xx AS int NOT NULL; - - - --- REASSIGN OWNED test -CREATE ROLE var_test_role1; -CREATE ROLE var_test_role2; - -CREATE VARIABLE xxx_var AS int; - -ALTER VARIABLE xxx_var OWNER TO var_test_role1; -REASSIGN OWNED BY var_test_role1 to var_test_role2; - -SELECT varowner::regrole FROM pg_variable WHERE varname = 'xxx_var'; - -DROP OWNED BY var_test_role1; -DROP ROLE var_test_role1; -SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; - -DROP OWNED BY var_test_role2; -DROP ROLE var_test_role2; -SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; - --- creating, dropping temporary variable -BEGIN; - -CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; - -LET tempvar = 100; - -SAVEPOINT s1; - -DROP VARIABLE tempvar; - -ROLLBACK TO s1; - -SELECT tempvar; - -COMMIT; - --- should to fail -LET tempvar = 100; - -BEGIN; - -SAVEPOINT s1; - -CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; - -LET tempvar = 100; - -ROLLBACK TO s1; - -COMMIT; - --- should to fail -LET tempvar = 100; - -CREATE VARIABLE var1 AS int; -LET var1 = 100; -BEGIN; -DROP VARIABLE var1; -ROLLBACK; -SELECT var1; - -DROP VARIABLE var1; - -CREATE VARIABLE var1 AS int DEFAULT 100; -COMMENT ON VARIABLE var1 IS 'some variable comment'; - -SELECT pg_catalog.obj_description(oid, 'pg_variable') FROM pg_variable WHERE varname = 'var1'; - -DROP VARIABLE var1; - -CREATE TABLE xxtab(avar int); - -CREATE TYPE xxtype AS (avar int); - -CREATE VARIABLE xxtab AS xxtype; - -INSERT INTO xxtab VALUES(10); - --- it is ambiguous, but columns are preferred -SELECT xxtab.avar FROM xxtab; - -SET session_variables_ambiguity_warning TO on; - -SELECT xxtab.avar FROM xxtab; - -SET search_path = svartest; - -CREATE VARIABLE testvar as int; - --- plpgsql variables are preferred against session variables -DO $$ -<> -DECLARE testvar int; -BEGIN - -- should be ok without warning - LET testvar = 100; - -- should be ok without warning - testvar := 1000; - -- should be ok without warning - RAISE NOTICE 'session variable is %', svartest.testvar; - -- should be ok without warning - RAISE NOTICE 'plpgsql variable is %', myblock.testvar; - -- should to print plpgsql variable with warning - RAISE NOTICE 'variable is %', testvar; -END; -$$; - -DROP VARIABLE testvar; - -SET session_variables_ambiguity_warning TO default; - --- should be ok -SELECT avar FROM xxtab; - -CREATE VARIABLE public.avar AS int; - --- should to fail -SELECT avar FROM xxtab; - --- should be ok -SELECT public.avar FROM xxtab; - -DROP VARIABLE xxtab; - -SELECT xxtab.avar FROM xxtab; - -DROP VARIABLE public.avar; - -DROP TYPE xxtype; - -DROP TABLE xxtab; - --- test of plan cache invalidation -CREATE VARIABLE xx AS int; - -SET plan_cache_mode = force_generic_plan; - -PREPARE pp AS SELECT xx; - -EXECUTE pp; - -DROP VARIABLE xx; - -CREATE VARIABLE xx AS int; - --- should to work -EXECUTE pp; - -DROP VARIABLE xx; - -DEALLOCATE pp; - -SET plan_cache_mode = DEFAULT; - -CREATE ROLE var_test_role; - -CREATE SCHEMA vartest; - -GRANT USAGE ON SCHEMA vartest TO var_test_role; - -CREATE VARIABLE vartest.x AS int; -CREATE VARIABLE vartest.y AS int; - -LET vartest.x = 100; -LET vartest.y = 101; - -GRANT READ ON ALL VARIABLES IN SCHEMA vartest TO var_test_role; - -SET ROLE TO var_test_role; - -SELECT vartest.x, vartest.y; - -SET ROLE TO DEFAULT; - -REVOKE READ ON ALL VARIABLES IN SCHEMA vartest FROM var_test_role; - -SET ROLE TO var_test_role; - --- should to fail -SELECT vartest.x; -SELECT vartest.y; - -SET ROLE TO DEFAULT; - -DROP VARIABLE vartest.x, vartest.y; - -DROP SCHEMA vartest; - -DROP ROLE var_test_role; - --- test cached plan -CREATE VARIABLE v1 AS text; -CREATE VARIABLE v2 AS int; -CREATE VARIABLE v3 AS int; - -LET v1 = 'test'; -LET v2 = 10; -LET v3 = 5; - -PREPARE q1 AS SELECT v1 || i FROM generate_series(1, v2) g(i) WHERE i IN (v2, v3); - -SET plan_cache_mode to force_generic_plan; - -EXECUTE q1; - -EXPLAIN EXECUTE q1; - --- dependecy check -DROP VARIABLE v3; - --- recreate v3 again -CREATE VARIABLE v3 AS int DEFAULT 6; - --- should to work, the plan should be recreated -EXECUTE q1; - -DEALLOCATE q1; - --- fill v1 by long text -LET v1 = repeat(' ', 10000); - -PREPARE q1 AS SELECT length(v1); - -EXECUTE q1; - -LET v1 = repeat(' ', 5000); - -EXECUTE q1; - -DEALLOCATE q1; - -SET plan_cache_mode to default; - -DROP VARIABLE v1, v2, v3; - -CREATE ROLE var_test_role; - -CREATE VARIABLE public.v1 AS int DEFAULT 0; - --- check acl when variable is acessed by simple eval expr method -CREATE OR REPLACE FUNCTION public.fx_var(int) -RETURNS int AS $$ -DECLARE xx int; -BEGIN - xx := public.v1 + $1; - RETURN xx; -END; -$$ LANGUAGE plpgsql; - --- should be ok -SELECT public.fx_var(0); - -SET ROLE TO var_test_role; - --- should to fail -SELECT public.fx_var(0); - -SET ROLE TO default; - -GRANT READ ON VARIABLE public.v1 TO var_test_role; - -SET ROLE TO var_test_role; - --- should be ok -SELECT public.fx_var(0); - -SET ROLE TO default; - -REVOKE READ ON VARIABLE public.v1 FROM var_test_role; - -SET ROLE TO var_test_role; - --- should be fail -SELECT public.fx_var(0); - -SET ROLE TO DEFAULT; - -DROP FUNCTION public.fx_var(int); - -DROP VARIABLE public.v1; - -DROP ROLE var_test_role; - CREATE TYPE public.svar_test_type AS (a int, b int, c numeric); CREATE VARIABLE public.svar AS public.svar_test_type; @@ -746,6 +6,8 @@ LET public.svar = ROW(10,20,30); SELECT public.svar; +SELECT public.svar; + ALTER TYPE public.svar_test_type DROP ATTRIBUTE c; -- should to fail -- 2.36.1