liquid_feedback_core

annotate update/core-update.v4.2.0-v4.2.1.sql @ 617:8e9d0878b5dc

Bugfix in function "featured_initiative" regarding reference to "issue_privilege" instead of "privilege"
author jbe
date Mon Oct 05 16:18:17 2020 +0200 (2020-10-05)
parents ae53fc96c953
children 5b3b20f1278d
rev   line source
jbe@615 1 CREATE OR REPLACE VIEW "liquid_feedback_version" AS
jbe@615 2 SELECT * FROM (VALUES ('4.2.1-incomplete-update', 4, 2, -1))
jbe@615 3 AS "subquery"("string", "major", "minor", "revision");
jbe@615 4
jbe@615 5 BEGIN;
jbe@615 6
jbe@616 7 ALTER TABLE "unit" ADD COLUMN "attr" JSONB NOT NULL DEFAULT '{}' CHECK (jsonb_typeof("attr") = 'object');
jbe@616 8 COMMENT ON COLUMN "unit"."attr" IS 'Opaque data structure to store any extended attributes used by frontend or middleware';
jbe@616 9
jbe@615 10 ALTER TABLE "unit" ADD COLUMN "member_weight" INT4;
jbe@615 11 COMMENT ON COLUMN "unit"."member_weight" IS 'Sum of active members'' voting weight';
jbe@615 12
jbe@615 13 ALTER TABLE "snapshot_population" ADD COLUMN "weight" INT4 NOT NULL DEFAULT 1;
jbe@615 14 ALTER TABLE "snapshot_population" ALTER COLUMN "weight" DROP DEFAULT;
jbe@615 15
jbe@615 16 ALTER TABLE "privilege" ADD COLUMN "weight" INT4 NOT NULL DEFAULT 1 CHECK ("weight" >= 0);
jbe@615 17 COMMENT ON COLUMN "privilege"."weight" IS 'Voting weight of member in unit';
jbe@615 18
jbe@615 19 CREATE TABLE "issue_privilege" (
jbe@615 20 PRIMARY KEY ("issue_id", "member_id"),
jbe@615 21 "issue_id" INT4 REFERENCES "issue" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
jbe@615 22 "member_id" INT4 REFERENCES "member" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
jbe@615 23 "initiative_right" BOOLEAN,
jbe@615 24 "voting_right" BOOLEAN,
jbe@615 25 "polling_right" BOOLEAN,
jbe@615 26 "weight" INT4 CHECK ("weight" >= 0) );
jbe@615 27 CREATE INDEX "issue_privilege_idx" ON "issue_privilege" ("member_id");
jbe@615 28 COMMENT ON TABLE "issue_privilege" IS 'Override of "privilege" table for rights of members in certain issues';
jbe@615 29
jbe@615 30 ALTER TABLE "direct_interest_snapshot" ADD COLUMN "ownweight" INT4 NOT NULL DEFAULT 1;
jbe@615 31 ALTER TABLE "direct_interest_snapshot" ALTER COLUMN "ownweight" DROP DEFAULT;
jbe@615 32 COMMENT ON COLUMN "direct_interest_snapshot"."ownweight" IS 'Own voting weight of member, disregading delegations';
jbe@615 33 COMMENT ON COLUMN "direct_interest_snapshot"."weight" IS 'Voting weight of member according to own weight and "delegating_interest_snapshot"';
jbe@615 34
jbe@615 35 ALTER TABLE "delegating_interest_snapshot" ADD COLUMN "ownweight" INT4 NOT NULL DEFAULT 1;
jbe@615 36 ALTER TABLE "delegating_interest_snapshot" ALTER COLUMN "ownweight" DROP DEFAULT;
jbe@615 37 COMMENT ON COLUMN "delegating_interest_snapshot"."ownweight" IS 'Own voting weight of member, disregading delegations';
jbe@615 38 COMMENT ON COLUMN "delegating_interest_snapshot"."weight" IS 'Intermediate voting weight considering incoming delegations';
jbe@615 39
jbe@615 40 ALTER TABLE "direct_voter" ADD COLUMN "ownweight" INT4 DEFAULT 1;
jbe@615 41 ALTER TABLE "direct_voter" ALTER COLUMN "ownweight" DROP DEFAULT;
jbe@615 42 COMMENT ON COLUMN "direct_voter"."ownweight" IS 'Own voting weight of member, disregarding delegations';
jbe@615 43 COMMENT ON COLUMN "direct_voter"."weight" IS 'Voting weight of member according to own weight and "delegating_interest_snapshot"';
jbe@615 44
jbe@615 45 ALTER TABLE "delegating_voter" ADD COLUMN "ownweight" INT4 NOT NULL DEFAULT 1;
jbe@615 46 ALTER TABLE "delegating_voter" ALTER COLUMN "ownweight" DROP DEFAULT;
jbe@615 47 COMMENT ON COLUMN "delegating_voter"."ownweight" IS 'Own voting weight of member, disregarding delegations';
jbe@615 48 COMMENT ON COLUMN "delegating_voter"."weight" IS 'Intermediate voting weight considering incoming delegations';
jbe@615 49
jbe@615 50 DROP VIEW "issue_delegation";
jbe@615 51 CREATE VIEW "issue_delegation" AS
jbe@615 52 SELECT DISTINCT ON ("issue"."id", "delegation"."truster_id")
jbe@615 53 "issue"."id" AS "issue_id",
jbe@615 54 "delegation"."id",
jbe@615 55 "delegation"."truster_id",
jbe@615 56 "delegation"."trustee_id",
jbe@615 57 COALESCE("issue_privilege"."weight", "privilege"."weight") AS "weight",
jbe@615 58 "delegation"."scope"
jbe@615 59 FROM "issue"
jbe@615 60 JOIN "area"
jbe@615 61 ON "area"."id" = "issue"."area_id"
jbe@615 62 JOIN "delegation"
jbe@615 63 ON "delegation"."unit_id" = "area"."unit_id"
jbe@615 64 OR "delegation"."area_id" = "area"."id"
jbe@615 65 OR "delegation"."issue_id" = "issue"."id"
jbe@615 66 JOIN "member"
jbe@615 67 ON "delegation"."truster_id" = "member"."id"
jbe@615 68 LEFT JOIN "privilege"
jbe@615 69 ON "area"."unit_id" = "privilege"."unit_id"
jbe@615 70 AND "delegation"."truster_id" = "privilege"."member_id"
jbe@615 71 LEFT JOIN "issue_privilege"
jbe@615 72 ON "issue"."id" = "issue_privilege"."issue_id"
jbe@615 73 AND "delegation"."truster_id" = "issue_privilege"."member_id"
jbe@615 74 WHERE "member"."active"
jbe@615 75 AND COALESCE("issue_privilege"."voting_right", "privilege"."voting_right")
jbe@615 76 ORDER BY
jbe@615 77 "issue"."id",
jbe@615 78 "delegation"."truster_id",
jbe@615 79 "delegation"."scope" DESC;
jbe@615 80 COMMENT ON VIEW "issue_delegation" IS 'Issue delegations where trusters are active and have voting right';
jbe@615 81
jbe@615 82 CREATE OR REPLACE VIEW "unit_member" AS
jbe@615 83 SELECT
jbe@615 84 "privilege"."unit_id" AS "unit_id",
jbe@615 85 "member"."id" AS "member_id",
jbe@615 86 "privilege"."weight"
jbe@615 87 FROM "privilege" JOIN "member" ON "member"."id" = "privilege"."member_id"
jbe@615 88 WHERE "privilege"."voting_right" AND "member"."active";
jbe@615 89
jbe@615 90 CREATE OR REPLACE VIEW "unit_member_count" AS
jbe@615 91 SELECT
jbe@615 92 "unit"."id" AS "unit_id",
jbe@615 93 count("unit_member"."member_id") AS "member_count",
jbe@615 94 sum("unit_member"."weight") AS "member_weight"
jbe@615 95 FROM "unit" LEFT JOIN "unit_member"
jbe@615 96 ON "unit"."id" = "unit_member"."unit_id"
jbe@615 97 GROUP BY "unit"."id";
jbe@615 98
jbe@615 99 CREATE OR REPLACE VIEW "event_for_notification" AS
jbe@615 100 SELECT
jbe@615 101 "member"."id" AS "recipient_id",
jbe@615 102 "event".*
jbe@615 103 FROM "member" CROSS JOIN "event"
jbe@615 104 JOIN "issue" ON "issue"."id" = "event"."issue_id"
jbe@615 105 JOIN "area" ON "area"."id" = "issue"."area_id"
jbe@615 106 LEFT JOIN "privilege" ON
jbe@615 107 "privilege"."member_id" = "member"."id" AND
jbe@615 108 "privilege"."unit_id" = "area"."unit_id"
jbe@615 109 LEFT JOIN "issue_privilege" ON
jbe@615 110 "issue_privilege"."member_id" = "member"."id" AND
jbe@615 111 "issue_privilege"."issue_id" = "event"."issue_id"
jbe@615 112 LEFT JOIN "subscription" ON
jbe@615 113 "subscription"."member_id" = "member"."id" AND
jbe@615 114 "subscription"."unit_id" = "area"."unit_id"
jbe@615 115 LEFT JOIN "ignored_area" ON
jbe@615 116 "ignored_area"."member_id" = "member"."id" AND
jbe@615 117 "ignored_area"."area_id" = "issue"."area_id"
jbe@615 118 LEFT JOIN "interest" ON
jbe@615 119 "interest"."member_id" = "member"."id" AND
jbe@615 120 "interest"."issue_id" = "event"."issue_id"
jbe@615 121 LEFT JOIN "supporter" ON
jbe@615 122 "supporter"."member_id" = "member"."id" AND
jbe@615 123 "supporter"."initiative_id" = "event"."initiative_id"
jbe@615 124 WHERE (
jbe@615 125 COALESCE("issue_privilege"."voting_right", "privilege"."voting_right") OR
jbe@615 126 "subscription"."member_id" NOTNULL
jbe@615 127 ) AND ("ignored_area"."member_id" ISNULL OR "interest"."member_id" NOTNULL)
jbe@615 128 AND (
jbe@615 129 "event"."event" = 'issue_state_changed'::"event_type" OR
jbe@615 130 ( "event"."event" = 'initiative_revoked'::"event_type" AND
jbe@615 131 "supporter"."member_id" NOTNULL ) );
jbe@615 132
jbe@615 133 CREATE OR REPLACE FUNCTION "featured_initiative"
jbe@615 134 ( "recipient_id_p" "member"."id"%TYPE,
jbe@615 135 "area_id_p" "area"."id"%TYPE )
jbe@615 136 RETURNS SETOF "initiative"."id"%TYPE
jbe@615 137 LANGUAGE 'plpgsql' STABLE AS $$
jbe@615 138 DECLARE
jbe@615 139 "counter_v" "member"."notification_counter"%TYPE;
jbe@615 140 "sample_size_v" "member"."notification_sample_size"%TYPE;
jbe@615 141 "initiative_id_ary" INT4[]; --"initiative"."id"%TYPE[]
jbe@615 142 "match_v" BOOLEAN;
jbe@615 143 "member_id_v" "member"."id"%TYPE;
jbe@615 144 "seed_v" TEXT;
jbe@615 145 "initiative_id_v" "initiative"."id"%TYPE;
jbe@615 146 BEGIN
jbe@615 147 SELECT "notification_counter", "notification_sample_size"
jbe@615 148 INTO "counter_v", "sample_size_v"
jbe@615 149 FROM "member" WHERE "id" = "recipient_id_p";
jbe@615 150 IF COALESCE("sample_size_v" <= 0, TRUE) THEN
jbe@615 151 RETURN;
jbe@615 152 END IF;
jbe@615 153 "initiative_id_ary" := '{}';
jbe@615 154 LOOP
jbe@615 155 "match_v" := FALSE;
jbe@615 156 FOR "member_id_v", "seed_v" IN
jbe@615 157 SELECT * FROM (
jbe@615 158 SELECT DISTINCT
jbe@615 159 "supporter"."member_id",
jbe@615 160 md5(
jbe@615 161 "recipient_id_p" || '-' ||
jbe@615 162 "counter_v" || '-' ||
jbe@615 163 "area_id_p" || '-' ||
jbe@615 164 "supporter"."member_id"
jbe@615 165 ) AS "seed"
jbe@615 166 FROM "supporter"
jbe@615 167 JOIN "initiative" ON "initiative"."id" = "supporter"."initiative_id"
jbe@615 168 JOIN "issue" ON "issue"."id" = "initiative"."issue_id"
jbe@615 169 WHERE "supporter"."member_id" != "recipient_id_p"
jbe@615 170 AND "issue"."area_id" = "area_id_p"
jbe@615 171 AND "issue"."state" IN ('admission', 'discussion', 'verification')
jbe@615 172 ) AS "subquery"
jbe@615 173 ORDER BY "seed"
jbe@615 174 LOOP
jbe@615 175 SELECT "initiative"."id" INTO "initiative_id_v"
jbe@615 176 FROM "initiative"
jbe@615 177 JOIN "issue" ON "issue"."id" = "initiative"."issue_id"
jbe@615 178 JOIN "area" ON "area"."id" = "issue"."area_id"
jbe@615 179 JOIN "supporter" ON "supporter"."initiative_id" = "initiative"."id"
jbe@615 180 LEFT JOIN "supporter" AS "self_support" ON
jbe@615 181 "self_support"."initiative_id" = "initiative"."id" AND
jbe@615 182 "self_support"."member_id" = "recipient_id_p"
jbe@615 183 LEFT JOIN "privilege" ON
jbe@615 184 "privilege"."member_id" = "recipient_id_p" AND
jbe@615 185 "privilege"."unit_id" = "area"."unit_id"
jbe@615 186 LEFT JOIN "issue_privilege" ON
jbe@617 187 "issue_privilege"."member_id" = "recipient_id_p" AND
jbe@617 188 "issue_privilege"."issue_id" = "initiative"."issue_id"
jbe@615 189 LEFT JOIN "subscription" ON
jbe@615 190 "subscription"."member_id" = "recipient_id_p" AND
jbe@615 191 "subscription"."unit_id" = "area"."unit_id"
jbe@615 192 LEFT JOIN "ignored_initiative" ON
jbe@615 193 "ignored_initiative"."member_id" = "recipient_id_p" AND
jbe@615 194 "ignored_initiative"."initiative_id" = "initiative"."id"
jbe@615 195 WHERE "supporter"."member_id" = "member_id_v"
jbe@615 196 AND "issue"."area_id" = "area_id_p"
jbe@615 197 AND "issue"."state" IN ('admission', 'discussion', 'verification')
jbe@615 198 AND "initiative"."revoked" ISNULL
jbe@615 199 AND "self_support"."member_id" ISNULL
jbe@615 200 AND NOT "initiative_id_ary" @> ARRAY["initiative"."id"]
jbe@615 201 AND (
jbe@615 202 COALESCE(
jbe@615 203 "issue_privilege"."voting_right", "privilege"."voting_right"
jbe@615 204 ) OR "subscription"."member_id" NOTNULL )
jbe@615 205 AND "ignored_initiative"."member_id" ISNULL
jbe@615 206 AND NOT EXISTS (
jbe@615 207 SELECT NULL FROM "draft"
jbe@615 208 JOIN "ignored_member" ON
jbe@615 209 "ignored_member"."member_id" = "recipient_id_p" AND
jbe@615 210 "ignored_member"."other_member_id" = "draft"."author_id"
jbe@615 211 WHERE "draft"."initiative_id" = "initiative"."id"
jbe@615 212 )
jbe@615 213 ORDER BY md5("seed_v" || '-' || "initiative"."id")
jbe@615 214 LIMIT 1;
jbe@615 215 IF FOUND THEN
jbe@615 216 "match_v" := TRUE;
jbe@615 217 RETURN NEXT "initiative_id_v";
jbe@615 218 IF array_length("initiative_id_ary", 1) + 1 >= "sample_size_v" THEN
jbe@615 219 RETURN;
jbe@615 220 END IF;
jbe@615 221 "initiative_id_ary" := "initiative_id_ary" || "initiative_id_v";
jbe@615 222 END IF;
jbe@615 223 END LOOP;
jbe@615 224 EXIT WHEN NOT "match_v";
jbe@615 225 END LOOP;
jbe@615 226 RETURN;
jbe@615 227 END;
jbe@615 228 $$;
jbe@615 229
jbe@615 230 CREATE OR REPLACE FUNCTION "delegation_chain"
jbe@615 231 ( "member_id_p" "member"."id"%TYPE,
jbe@615 232 "unit_id_p" "unit"."id"%TYPE,
jbe@615 233 "area_id_p" "area"."id"%TYPE,
jbe@615 234 "issue_id_p" "issue"."id"%TYPE,
jbe@615 235 "simulate_trustee_id_p" "member"."id"%TYPE DEFAULT NULL,
jbe@615 236 "simulate_default_p" BOOLEAN DEFAULT FALSE )
jbe@615 237 RETURNS SETOF "delegation_chain_row"
jbe@615 238 LANGUAGE 'plpgsql' STABLE AS $$
jbe@615 239 DECLARE
jbe@615 240 "scope_v" "delegation_scope";
jbe@615 241 "unit_id_v" "unit"."id"%TYPE;
jbe@615 242 "area_id_v" "area"."id"%TYPE;
jbe@615 243 "issue_row" "issue"%ROWTYPE;
jbe@615 244 "visited_member_ids" INT4[]; -- "member"."id"%TYPE[]
jbe@615 245 "loop_member_id_v" "member"."id"%TYPE;
jbe@615 246 "output_row" "delegation_chain_row";
jbe@615 247 "output_rows" "delegation_chain_row"[];
jbe@615 248 "simulate_v" BOOLEAN;
jbe@615 249 "simulate_here_v" BOOLEAN;
jbe@615 250 "delegation_row" "delegation"%ROWTYPE;
jbe@615 251 "row_count" INT4;
jbe@615 252 "i" INT4;
jbe@615 253 "loop_v" BOOLEAN;
jbe@615 254 BEGIN
jbe@615 255 IF "simulate_trustee_id_p" NOTNULL AND "simulate_default_p" THEN
jbe@615 256 RAISE EXCEPTION 'Both "simulate_trustee_id_p" is set, and "simulate_default_p" is true';
jbe@615 257 END IF;
jbe@615 258 IF "simulate_trustee_id_p" NOTNULL OR "simulate_default_p" THEN
jbe@615 259 "simulate_v" := TRUE;
jbe@615 260 ELSE
jbe@615 261 "simulate_v" := FALSE;
jbe@615 262 END IF;
jbe@615 263 IF
jbe@615 264 "unit_id_p" NOTNULL AND
jbe@615 265 "area_id_p" ISNULL AND
jbe@615 266 "issue_id_p" ISNULL
jbe@615 267 THEN
jbe@615 268 "scope_v" := 'unit';
jbe@615 269 "unit_id_v" := "unit_id_p";
jbe@615 270 ELSIF
jbe@615 271 "unit_id_p" ISNULL AND
jbe@615 272 "area_id_p" NOTNULL AND
jbe@615 273 "issue_id_p" ISNULL
jbe@615 274 THEN
jbe@615 275 "scope_v" := 'area';
jbe@615 276 "area_id_v" := "area_id_p";
jbe@615 277 SELECT "unit_id" INTO "unit_id_v"
jbe@615 278 FROM "area" WHERE "id" = "area_id_v";
jbe@615 279 ELSIF
jbe@615 280 "unit_id_p" ISNULL AND
jbe@615 281 "area_id_p" ISNULL AND
jbe@615 282 "issue_id_p" NOTNULL
jbe@615 283 THEN
jbe@615 284 SELECT INTO "issue_row" * FROM "issue" WHERE "id" = "issue_id_p";
jbe@615 285 IF "issue_row"."id" ISNULL THEN
jbe@615 286 RETURN;
jbe@615 287 END IF;
jbe@615 288 IF "issue_row"."closed" NOTNULL THEN
jbe@615 289 IF "simulate_v" THEN
jbe@615 290 RAISE EXCEPTION 'Tried to simulate delegation chain for closed issue.';
jbe@615 291 END IF;
jbe@615 292 FOR "output_row" IN
jbe@615 293 SELECT * FROM
jbe@615 294 "delegation_chain_for_closed_issue"("member_id_p", "issue_id_p")
jbe@615 295 LOOP
jbe@615 296 RETURN NEXT "output_row";
jbe@615 297 END LOOP;
jbe@615 298 RETURN;
jbe@615 299 END IF;
jbe@615 300 "scope_v" := 'issue';
jbe@615 301 SELECT "area_id" INTO "area_id_v"
jbe@615 302 FROM "issue" WHERE "id" = "issue_id_p";
jbe@615 303 SELECT "unit_id" INTO "unit_id_v"
jbe@615 304 FROM "area" WHERE "id" = "area_id_v";
jbe@615 305 ELSE
jbe@615 306 RAISE EXCEPTION 'Exactly one of unit_id_p, area_id_p, or issue_id_p must be NOTNULL.';
jbe@615 307 END IF;
jbe@615 308 "visited_member_ids" := '{}';
jbe@615 309 "loop_member_id_v" := NULL;
jbe@615 310 "output_rows" := '{}';
jbe@615 311 "output_row"."index" := 0;
jbe@615 312 "output_row"."member_id" := "member_id_p";
jbe@615 313 "output_row"."member_valid" := TRUE;
jbe@615 314 "output_row"."participation" := FALSE;
jbe@615 315 "output_row"."overridden" := FALSE;
jbe@615 316 "output_row"."disabled_out" := FALSE;
jbe@615 317 "output_row"."scope_out" := NULL;
jbe@615 318 LOOP
jbe@615 319 IF "visited_member_ids" @> ARRAY["output_row"."member_id"] THEN
jbe@615 320 "loop_member_id_v" := "output_row"."member_id";
jbe@615 321 ELSE
jbe@615 322 "visited_member_ids" :=
jbe@615 323 "visited_member_ids" || "output_row"."member_id";
jbe@615 324 END IF;
jbe@615 325 IF "output_row"."participation" ISNULL THEN
jbe@615 326 "output_row"."overridden" := NULL;
jbe@615 327 ELSIF "output_row"."participation" THEN
jbe@615 328 "output_row"."overridden" := TRUE;
jbe@615 329 END IF;
jbe@615 330 "output_row"."scope_in" := "output_row"."scope_out";
jbe@615 331 "output_row"."member_valid" := EXISTS (
jbe@615 332 SELECT NULL FROM "member"
jbe@615 333 LEFT JOIN "privilege"
jbe@615 334 ON "privilege"."member_id" = "member"."id"
jbe@615 335 AND "privilege"."unit_id" = "unit_id_v"
jbe@615 336 LEFT JOIN "issue_privilege"
jbe@615 337 ON "issue_privilege"."member_id" = "member"."id"
jbe@615 338 AND "issue_privilege"."issue_id" = "issue_id_p"
jbe@615 339 WHERE "id" = "output_row"."member_id"
jbe@615 340 AND "member"."active"
jbe@615 341 AND COALESCE(
jbe@615 342 "issue_privilege"."voting_right", "privilege"."voting_right")
jbe@615 343 );
jbe@615 344 "simulate_here_v" := (
jbe@615 345 "simulate_v" AND
jbe@615 346 "output_row"."member_id" = "member_id_p"
jbe@615 347 );
jbe@615 348 "delegation_row" := ROW(NULL);
jbe@615 349 IF "output_row"."member_valid" OR "simulate_here_v" THEN
jbe@615 350 IF "scope_v" = 'unit' THEN
jbe@615 351 IF NOT "simulate_here_v" THEN
jbe@615 352 SELECT * INTO "delegation_row" FROM "delegation"
jbe@615 353 WHERE "truster_id" = "output_row"."member_id"
jbe@615 354 AND "unit_id" = "unit_id_v";
jbe@615 355 END IF;
jbe@615 356 ELSIF "scope_v" = 'area' THEN
jbe@615 357 IF "simulate_here_v" THEN
jbe@615 358 IF "simulate_trustee_id_p" ISNULL THEN
jbe@615 359 SELECT * INTO "delegation_row" FROM "delegation"
jbe@615 360 WHERE "truster_id" = "output_row"."member_id"
jbe@615 361 AND "unit_id" = "unit_id_v";
jbe@615 362 END IF;
jbe@615 363 ELSE
jbe@615 364 SELECT * INTO "delegation_row" FROM "delegation"
jbe@615 365 WHERE "truster_id" = "output_row"."member_id"
jbe@615 366 AND (
jbe@615 367 "unit_id" = "unit_id_v" OR
jbe@615 368 "area_id" = "area_id_v"
jbe@615 369 )
jbe@615 370 ORDER BY "scope" DESC;
jbe@615 371 END IF;
jbe@615 372 ELSIF "scope_v" = 'issue' THEN
jbe@615 373 IF "issue_row"."fully_frozen" ISNULL THEN
jbe@615 374 "output_row"."participation" := EXISTS (
jbe@615 375 SELECT NULL FROM "interest"
jbe@615 376 WHERE "issue_id" = "issue_id_p"
jbe@615 377 AND "member_id" = "output_row"."member_id"
jbe@615 378 );
jbe@615 379 ELSE
jbe@615 380 IF "output_row"."member_id" = "member_id_p" THEN
jbe@615 381 "output_row"."participation" := EXISTS (
jbe@615 382 SELECT NULL FROM "direct_voter"
jbe@615 383 WHERE "issue_id" = "issue_id_p"
jbe@615 384 AND "member_id" = "output_row"."member_id"
jbe@615 385 );
jbe@615 386 ELSE
jbe@615 387 "output_row"."participation" := NULL;
jbe@615 388 END IF;
jbe@615 389 END IF;
jbe@615 390 IF "simulate_here_v" THEN
jbe@615 391 IF "simulate_trustee_id_p" ISNULL THEN
jbe@615 392 SELECT * INTO "delegation_row" FROM "delegation"
jbe@615 393 WHERE "truster_id" = "output_row"."member_id"
jbe@615 394 AND (
jbe@615 395 "unit_id" = "unit_id_v" OR
jbe@615 396 "area_id" = "area_id_v"
jbe@615 397 )
jbe@615 398 ORDER BY "scope" DESC;
jbe@615 399 END IF;
jbe@615 400 ELSE
jbe@615 401 SELECT * INTO "delegation_row" FROM "delegation"
jbe@615 402 WHERE "truster_id" = "output_row"."member_id"
jbe@615 403 AND (
jbe@615 404 "unit_id" = "unit_id_v" OR
jbe@615 405 "area_id" = "area_id_v" OR
jbe@615 406 "issue_id" = "issue_id_p"
jbe@615 407 )
jbe@615 408 ORDER BY "scope" DESC;
jbe@615 409 END IF;
jbe@615 410 END IF;
jbe@615 411 ELSE
jbe@615 412 "output_row"."participation" := FALSE;
jbe@615 413 END IF;
jbe@615 414 IF "simulate_here_v" AND "simulate_trustee_id_p" NOTNULL THEN
jbe@615 415 "output_row"."scope_out" := "scope_v";
jbe@615 416 "output_rows" := "output_rows" || "output_row";
jbe@615 417 "output_row"."member_id" := "simulate_trustee_id_p";
jbe@615 418 ELSIF "delegation_row"."trustee_id" NOTNULL THEN
jbe@615 419 "output_row"."scope_out" := "delegation_row"."scope";
jbe@615 420 "output_rows" := "output_rows" || "output_row";
jbe@615 421 "output_row"."member_id" := "delegation_row"."trustee_id";
jbe@615 422 ELSIF "delegation_row"."scope" NOTNULL THEN
jbe@615 423 "output_row"."scope_out" := "delegation_row"."scope";
jbe@615 424 "output_row"."disabled_out" := TRUE;
jbe@615 425 "output_rows" := "output_rows" || "output_row";
jbe@615 426 EXIT;
jbe@615 427 ELSE
jbe@615 428 "output_row"."scope_out" := NULL;
jbe@615 429 "output_rows" := "output_rows" || "output_row";
jbe@615 430 EXIT;
jbe@615 431 END IF;
jbe@615 432 EXIT WHEN "loop_member_id_v" NOTNULL;
jbe@615 433 "output_row"."index" := "output_row"."index" + 1;
jbe@615 434 END LOOP;
jbe@615 435 "row_count" := array_upper("output_rows", 1);
jbe@615 436 "i" := 1;
jbe@615 437 "loop_v" := FALSE;
jbe@615 438 LOOP
jbe@615 439 "output_row" := "output_rows"["i"];
jbe@615 440 EXIT WHEN "output_row" ISNULL; -- NOTE: ISNULL and NOT ... NOTNULL produce different results!
jbe@615 441 IF "loop_v" THEN
jbe@615 442 IF "i" + 1 = "row_count" THEN
jbe@615 443 "output_row"."loop" := 'last';
jbe@615 444 ELSIF "i" = "row_count" THEN
jbe@615 445 "output_row"."loop" := 'repetition';
jbe@615 446 ELSE
jbe@615 447 "output_row"."loop" := 'intermediate';
jbe@615 448 END IF;
jbe@615 449 ELSIF "output_row"."member_id" = "loop_member_id_v" THEN
jbe@615 450 "output_row"."loop" := 'first';
jbe@615 451 "loop_v" := TRUE;
jbe@615 452 END IF;
jbe@615 453 IF "scope_v" = 'unit' THEN
jbe@615 454 "output_row"."participation" := NULL;
jbe@615 455 END IF;
jbe@615 456 RETURN NEXT "output_row";
jbe@615 457 "i" := "i" + 1;
jbe@615 458 END LOOP;
jbe@615 459 RETURN;
jbe@615 460 END;
jbe@615 461 $$;
jbe@615 462
jbe@615 463 CREATE OR REPLACE FUNCTION "calculate_member_counts"()
jbe@615 464 RETURNS VOID
jbe@615 465 LANGUAGE 'plpgsql' VOLATILE AS $$
jbe@615 466 BEGIN
jbe@615 467 PERFORM "require_transaction_isolation"();
jbe@615 468 DELETE FROM "member_count";
jbe@615 469 INSERT INTO "member_count" ("total_count")
jbe@615 470 SELECT "total_count" FROM "member_count_view";
jbe@615 471 UPDATE "unit" SET
jbe@615 472 "member_count" = "view"."member_count",
jbe@615 473 "member_weight" = "view"."member_weight"
jbe@615 474 FROM "unit_member_count" AS "view"
jbe@615 475 WHERE "view"."unit_id" = "unit"."id";
jbe@615 476 RETURN;
jbe@615 477 END;
jbe@615 478 $$;
jbe@615 479 COMMENT ON FUNCTION "calculate_member_counts"() IS 'Updates "member_count" table and "member_count" and "member_weight" columns of table "area" by materializing data from views "member_count_view" and "unit_member_count"';
jbe@615 480
jbe@615 481 CREATE OR REPLACE FUNCTION "weight_of_added_delegations_for_snapshot"
jbe@615 482 ( "snapshot_id_p" "snapshot"."id"%TYPE,
jbe@615 483 "issue_id_p" "issue"."id"%TYPE,
jbe@615 484 "member_id_p" "member"."id"%TYPE,
jbe@615 485 "delegate_member_ids_p" "delegating_interest_snapshot"."delegate_member_ids"%TYPE )
jbe@615 486 RETURNS "direct_interest_snapshot"."weight"%TYPE
jbe@615 487 LANGUAGE 'plpgsql' VOLATILE AS $$
jbe@615 488 DECLARE
jbe@615 489 "issue_delegation_row" "issue_delegation"%ROWTYPE;
jbe@615 490 "delegate_member_ids_v" "delegating_interest_snapshot"."delegate_member_ids"%TYPE;
jbe@615 491 "weight_v" INT4;
jbe@615 492 "sub_weight_v" INT4;
jbe@615 493 BEGIN
jbe@615 494 PERFORM "require_transaction_isolation"();
jbe@615 495 "weight_v" := 0;
jbe@615 496 FOR "issue_delegation_row" IN
jbe@615 497 SELECT * FROM "issue_delegation"
jbe@615 498 WHERE "trustee_id" = "member_id_p"
jbe@615 499 AND "issue_id" = "issue_id_p"
jbe@615 500 LOOP
jbe@615 501 IF NOT EXISTS (
jbe@615 502 SELECT NULL FROM "direct_interest_snapshot"
jbe@615 503 WHERE "snapshot_id" = "snapshot_id_p"
jbe@615 504 AND "issue_id" = "issue_id_p"
jbe@615 505 AND "member_id" = "issue_delegation_row"."truster_id"
jbe@615 506 ) AND NOT EXISTS (
jbe@615 507 SELECT NULL FROM "delegating_interest_snapshot"
jbe@615 508 WHERE "snapshot_id" = "snapshot_id_p"
jbe@615 509 AND "issue_id" = "issue_id_p"
jbe@615 510 AND "member_id" = "issue_delegation_row"."truster_id"
jbe@615 511 ) THEN
jbe@615 512 "delegate_member_ids_v" :=
jbe@615 513 "member_id_p" || "delegate_member_ids_p";
jbe@615 514 INSERT INTO "delegating_interest_snapshot" (
jbe@615 515 "snapshot_id",
jbe@615 516 "issue_id",
jbe@615 517 "member_id",
jbe@615 518 "ownweight",
jbe@615 519 "scope",
jbe@615 520 "delegate_member_ids"
jbe@615 521 ) VALUES (
jbe@615 522 "snapshot_id_p",
jbe@615 523 "issue_id_p",
jbe@615 524 "issue_delegation_row"."truster_id",
jbe@615 525 "issue_delegation_row"."weight",
jbe@615 526 "issue_delegation_row"."scope",
jbe@615 527 "delegate_member_ids_v"
jbe@615 528 );
jbe@615 529 "sub_weight_v" := "issue_delegation_row"."weight" +
jbe@615 530 "weight_of_added_delegations_for_snapshot"(
jbe@615 531 "snapshot_id_p",
jbe@615 532 "issue_id_p",
jbe@615 533 "issue_delegation_row"."truster_id",
jbe@615 534 "delegate_member_ids_v"
jbe@615 535 );
jbe@615 536 UPDATE "delegating_interest_snapshot"
jbe@615 537 SET "weight" = "sub_weight_v"
jbe@615 538 WHERE "snapshot_id" = "snapshot_id_p"
jbe@615 539 AND "issue_id" = "issue_id_p"
jbe@615 540 AND "member_id" = "issue_delegation_row"."truster_id";
jbe@615 541 "weight_v" := "weight_v" + "sub_weight_v";
jbe@615 542 END IF;
jbe@615 543 END LOOP;
jbe@615 544 RETURN "weight_v";
jbe@615 545 END;
jbe@615 546 $$;
jbe@615 547
jbe@615 548 CREATE OR REPLACE FUNCTION "take_snapshot"
jbe@615 549 ( "issue_id_p" "issue"."id"%TYPE,
jbe@615 550 "area_id_p" "area"."id"%TYPE = NULL )
jbe@615 551 RETURNS "snapshot"."id"%TYPE
jbe@615 552 LANGUAGE 'plpgsql' VOLATILE AS $$
jbe@615 553 DECLARE
jbe@615 554 "area_id_v" "area"."id"%TYPE;
jbe@615 555 "unit_id_v" "unit"."id"%TYPE;
jbe@615 556 "snapshot_id_v" "snapshot"."id"%TYPE;
jbe@615 557 "issue_id_v" "issue"."id"%TYPE;
jbe@615 558 "member_id_v" "member"."id"%TYPE;
jbe@615 559 BEGIN
jbe@615 560 IF "issue_id_p" NOTNULL AND "area_id_p" NOTNULL THEN
jbe@615 561 RAISE EXCEPTION 'One of "issue_id_p" and "area_id_p" must be NULL';
jbe@615 562 END IF;
jbe@615 563 PERFORM "require_transaction_isolation"();
jbe@615 564 IF "issue_id_p" ISNULL THEN
jbe@615 565 "area_id_v" := "area_id_p";
jbe@615 566 ELSE
jbe@615 567 SELECT "area_id" INTO "area_id_v"
jbe@615 568 FROM "issue" WHERE "id" = "issue_id_p";
jbe@615 569 END IF;
jbe@615 570 SELECT "unit_id" INTO "unit_id_v" FROM "area" WHERE "id" = "area_id_v";
jbe@615 571 INSERT INTO "snapshot" ("area_id", "issue_id")
jbe@615 572 VALUES ("area_id_v", "issue_id_p")
jbe@615 573 RETURNING "id" INTO "snapshot_id_v";
jbe@615 574 INSERT INTO "snapshot_population" ("snapshot_id", "member_id", "weight")
jbe@615 575 SELECT
jbe@615 576 "snapshot_id_v",
jbe@615 577 "member"."id",
jbe@615 578 COALESCE("issue_privilege"."weight", "privilege"."weight")
jbe@615 579 FROM "member"
jbe@615 580 LEFT JOIN "privilege"
jbe@615 581 ON "privilege"."unit_id" = "unit_id_v"
jbe@615 582 AND "privilege"."member_id" = "member"."id"
jbe@615 583 LEFT JOIN "issue_privilege"
jbe@615 584 ON "issue_privilege"."issue_id" = "issue_id_p"
jbe@615 585 AND "issue_privilege"."member_id" = "member"."id"
jbe@615 586 WHERE "member"."active" AND COALESCE(
jbe@615 587 "issue_privilege"."voting_right", "privilege"."voting_right");
jbe@615 588 UPDATE "snapshot" SET
jbe@615 589 "population" = (
jbe@615 590 SELECT sum("weight") FROM "snapshot_population"
jbe@615 591 WHERE "snapshot_id" = "snapshot_id_v"
jbe@615 592 ) WHERE "id" = "snapshot_id_v";
jbe@615 593 FOR "issue_id_v" IN
jbe@615 594 SELECT "id" FROM "issue"
jbe@615 595 WHERE CASE WHEN "issue_id_p" ISNULL THEN
jbe@615 596 "area_id" = "area_id_p" AND
jbe@615 597 "state" = 'admission'
jbe@615 598 ELSE
jbe@615 599 "id" = "issue_id_p"
jbe@615 600 END
jbe@615 601 LOOP
jbe@615 602 INSERT INTO "snapshot_issue" ("snapshot_id", "issue_id")
jbe@615 603 VALUES ("snapshot_id_v", "issue_id_v");
jbe@615 604 INSERT INTO "direct_interest_snapshot"
jbe@615 605 ("snapshot_id", "issue_id", "member_id", "ownweight")
jbe@615 606 SELECT
jbe@615 607 "snapshot_id_v" AS "snapshot_id",
jbe@615 608 "issue_id_v" AS "issue_id",
jbe@615 609 "member"."id" AS "member_id",
jbe@615 610 COALESCE(
jbe@615 611 "issue_privilege"."weight", "privilege"."weight"
jbe@615 612 ) AS "ownweight"
jbe@615 613 FROM "issue"
jbe@615 614 JOIN "area" ON "issue"."area_id" = "area"."id"
jbe@615 615 JOIN "interest" ON "issue"."id" = "interest"."issue_id"
jbe@615 616 JOIN "member" ON "interest"."member_id" = "member"."id"
jbe@615 617 LEFT JOIN "privilege"
jbe@615 618 ON "privilege"."unit_id" = "area"."unit_id"
jbe@615 619 AND "privilege"."member_id" = "member"."id"
jbe@615 620 LEFT JOIN "issue_privilege"
jbe@615 621 ON "issue_privilege"."issue_id" = "issue_id_v"
jbe@615 622 AND "issue_privilege"."member_id" = "member"."id"
jbe@615 623 WHERE "issue"."id" = "issue_id_v"
jbe@615 624 AND "member"."active" AND COALESCE(
jbe@615 625 "issue_privilege"."voting_right", "privilege"."voting_right");
jbe@615 626 FOR "member_id_v" IN
jbe@615 627 SELECT "member_id" FROM "direct_interest_snapshot"
jbe@615 628 WHERE "snapshot_id" = "snapshot_id_v"
jbe@615 629 AND "issue_id" = "issue_id_v"
jbe@615 630 LOOP
jbe@615 631 UPDATE "direct_interest_snapshot" SET
jbe@615 632 "weight" = "ownweight" +
jbe@615 633 "weight_of_added_delegations_for_snapshot"(
jbe@615 634 "snapshot_id_v",
jbe@615 635 "issue_id_v",
jbe@615 636 "member_id_v",
jbe@615 637 '{}'
jbe@615 638 )
jbe@615 639 WHERE "snapshot_id" = "snapshot_id_v"
jbe@615 640 AND "issue_id" = "issue_id_v"
jbe@615 641 AND "member_id" = "member_id_v";
jbe@615 642 END LOOP;
jbe@615 643 INSERT INTO "direct_supporter_snapshot"
jbe@615 644 ( "snapshot_id", "issue_id", "initiative_id", "member_id",
jbe@615 645 "draft_id", "informed", "satisfied" )
jbe@615 646 SELECT
jbe@615 647 "snapshot_id_v" AS "snapshot_id",
jbe@615 648 "issue_id_v" AS "issue_id",
jbe@615 649 "initiative"."id" AS "initiative_id",
jbe@615 650 "supporter"."member_id" AS "member_id",
jbe@615 651 "supporter"."draft_id" AS "draft_id",
jbe@615 652 "supporter"."draft_id" = "current_draft"."id" AS "informed",
jbe@615 653 NOT EXISTS (
jbe@615 654 SELECT NULL FROM "critical_opinion"
jbe@615 655 WHERE "initiative_id" = "initiative"."id"
jbe@615 656 AND "member_id" = "supporter"."member_id"
jbe@615 657 ) AS "satisfied"
jbe@615 658 FROM "initiative"
jbe@615 659 JOIN "supporter"
jbe@615 660 ON "supporter"."initiative_id" = "initiative"."id"
jbe@615 661 JOIN "current_draft"
jbe@615 662 ON "initiative"."id" = "current_draft"."initiative_id"
jbe@615 663 JOIN "direct_interest_snapshot"
jbe@615 664 ON "snapshot_id_v" = "direct_interest_snapshot"."snapshot_id"
jbe@615 665 AND "supporter"."member_id" = "direct_interest_snapshot"."member_id"
jbe@615 666 AND "initiative"."issue_id" = "direct_interest_snapshot"."issue_id"
jbe@615 667 WHERE "initiative"."issue_id" = "issue_id_v";
jbe@615 668 DELETE FROM "temporary_suggestion_counts";
jbe@615 669 INSERT INTO "temporary_suggestion_counts"
jbe@615 670 ( "id",
jbe@615 671 "minus2_unfulfilled_count", "minus2_fulfilled_count",
jbe@615 672 "minus1_unfulfilled_count", "minus1_fulfilled_count",
jbe@615 673 "plus1_unfulfilled_count", "plus1_fulfilled_count",
jbe@615 674 "plus2_unfulfilled_count", "plus2_fulfilled_count" )
jbe@615 675 SELECT
jbe@615 676 "suggestion"."id",
jbe@615 677 ( SELECT coalesce(sum("di"."weight"), 0)
jbe@615 678 FROM "opinion" JOIN "direct_interest_snapshot" AS "di"
jbe@615 679 ON "di"."snapshot_id" = "snapshot_id_v"
jbe@615 680 AND "di"."issue_id" = "issue_id_v"
jbe@615 681 AND "di"."member_id" = "opinion"."member_id"
jbe@615 682 WHERE "opinion"."suggestion_id" = "suggestion"."id"
jbe@615 683 AND "opinion"."degree" = -2
jbe@615 684 AND "opinion"."fulfilled" = FALSE
jbe@615 685 ) AS "minus2_unfulfilled_count",
jbe@615 686 ( SELECT coalesce(sum("di"."weight"), 0)
jbe@615 687 FROM "opinion" JOIN "direct_interest_snapshot" AS "di"
jbe@615 688 ON "di"."snapshot_id" = "snapshot_id_v"
jbe@615 689 AND "di"."issue_id" = "issue_id_v"
jbe@615 690 AND "di"."member_id" = "opinion"."member_id"
jbe@615 691 WHERE "opinion"."suggestion_id" = "suggestion"."id"
jbe@615 692 AND "opinion"."degree" = -2
jbe@615 693 AND "opinion"."fulfilled" = TRUE
jbe@615 694 ) AS "minus2_fulfilled_count",
jbe@615 695 ( SELECT coalesce(sum("di"."weight"), 0)
jbe@615 696 FROM "opinion" JOIN "direct_interest_snapshot" AS "di"
jbe@615 697 ON "di"."snapshot_id" = "snapshot_id_v"
jbe@615 698 AND "di"."issue_id" = "issue_id_v"
jbe@615 699 AND "di"."member_id" = "opinion"."member_id"
jbe@615 700 WHERE "opinion"."suggestion_id" = "suggestion"."id"
jbe@615 701 AND "opinion"."degree" = -1
jbe@615 702 AND "opinion"."fulfilled" = FALSE
jbe@615 703 ) AS "minus1_unfulfilled_count",
jbe@615 704 ( SELECT coalesce(sum("di"."weight"), 0)
jbe@615 705 FROM "opinion" JOIN "direct_interest_snapshot" AS "di"
jbe@615 706 ON "di"."snapshot_id" = "snapshot_id_v"
jbe@615 707 AND "di"."issue_id" = "issue_id_v"
jbe@615 708 AND "di"."member_id" = "opinion"."member_id"
jbe@615 709 WHERE "opinion"."suggestion_id" = "suggestion"."id"
jbe@615 710 AND "opinion"."degree" = -1
jbe@615 711 AND "opinion"."fulfilled" = TRUE
jbe@615 712 ) AS "minus1_fulfilled_count",
jbe@615 713 ( SELECT coalesce(sum("di"."weight"), 0)
jbe@615 714 FROM "opinion" JOIN "direct_interest_snapshot" AS "di"
jbe@615 715 ON "di"."snapshot_id" = "snapshot_id_v"
jbe@615 716 AND "di"."issue_id" = "issue_id_v"
jbe@615 717 AND "di"."member_id" = "opinion"."member_id"
jbe@615 718 WHERE "opinion"."suggestion_id" = "suggestion"."id"
jbe@615 719 AND "opinion"."degree" = 1
jbe@615 720 AND "opinion"."fulfilled" = FALSE
jbe@615 721 ) AS "plus1_unfulfilled_count",
jbe@615 722 ( SELECT coalesce(sum("di"."weight"), 0)
jbe@615 723 FROM "opinion" JOIN "direct_interest_snapshot" AS "di"
jbe@615 724 ON "di"."snapshot_id" = "snapshot_id_v"
jbe@615 725 AND "di"."issue_id" = "issue_id_v"
jbe@615 726 AND "di"."member_id" = "opinion"."member_id"
jbe@615 727 WHERE "opinion"."suggestion_id" = "suggestion"."id"
jbe@615 728 AND "opinion"."degree" = 1
jbe@615 729 AND "opinion"."fulfilled" = TRUE
jbe@615 730 ) AS "plus1_fulfilled_count",
jbe@615 731 ( SELECT coalesce(sum("di"."weight"), 0)
jbe@615 732 FROM "opinion" JOIN "direct_interest_snapshot" AS "di"
jbe@615 733 ON "di"."snapshot_id" = "snapshot_id_v"
jbe@615 734 AND "di"."issue_id" = "issue_id_v"
jbe@615 735 AND "di"."member_id" = "opinion"."member_id"
jbe@615 736 WHERE "opinion"."suggestion_id" = "suggestion"."id"
jbe@615 737 AND "opinion"."degree" = 2
jbe@615 738 AND "opinion"."fulfilled" = FALSE
jbe@615 739 ) AS "plus2_unfulfilled_count",
jbe@615 740 ( SELECT coalesce(sum("di"."weight"), 0)
jbe@615 741 FROM "opinion" JOIN "direct_interest_snapshot" AS "di"
jbe@615 742 ON "di"."snapshot_id" = "snapshot_id_v"
jbe@615 743 AND "di"."issue_id" = "issue_id_v"
jbe@615 744 AND "di"."member_id" = "opinion"."member_id"
jbe@615 745 WHERE "opinion"."suggestion_id" = "suggestion"."id"
jbe@615 746 AND "opinion"."degree" = 2
jbe@615 747 AND "opinion"."fulfilled" = TRUE
jbe@615 748 ) AS "plus2_fulfilled_count"
jbe@615 749 FROM "suggestion" JOIN "initiative"
jbe@615 750 ON "suggestion"."initiative_id" = "initiative"."id"
jbe@615 751 WHERE "initiative"."issue_id" = "issue_id_v";
jbe@615 752 END LOOP;
jbe@615 753 RETURN "snapshot_id_v";
jbe@615 754 END;
jbe@615 755 $$;
jbe@615 756
jbe@615 757 CREATE OR REPLACE FUNCTION "weight_of_added_vote_delegations"
jbe@615 758 ( "issue_id_p" "issue"."id"%TYPE,
jbe@615 759 "member_id_p" "member"."id"%TYPE,
jbe@615 760 "delegate_member_ids_p" "delegating_voter"."delegate_member_ids"%TYPE )
jbe@615 761 RETURNS "direct_voter"."weight"%TYPE
jbe@615 762 LANGUAGE 'plpgsql' VOLATILE AS $$
jbe@615 763 DECLARE
jbe@615 764 "issue_delegation_row" "issue_delegation"%ROWTYPE;
jbe@615 765 "delegate_member_ids_v" "delegating_voter"."delegate_member_ids"%TYPE;
jbe@615 766 "weight_v" INT4;
jbe@615 767 "sub_weight_v" INT4;
jbe@615 768 BEGIN
jbe@615 769 PERFORM "require_transaction_isolation"();
jbe@615 770 "weight_v" := 0;
jbe@615 771 FOR "issue_delegation_row" IN
jbe@615 772 SELECT * FROM "issue_delegation"
jbe@615 773 WHERE "trustee_id" = "member_id_p"
jbe@615 774 AND "issue_id" = "issue_id_p"
jbe@615 775 LOOP
jbe@615 776 IF NOT EXISTS (
jbe@615 777 SELECT NULL FROM "direct_voter"
jbe@615 778 WHERE "member_id" = "issue_delegation_row"."truster_id"
jbe@615 779 AND "issue_id" = "issue_id_p"
jbe@615 780 ) AND NOT EXISTS (
jbe@615 781 SELECT NULL FROM "delegating_voter"
jbe@615 782 WHERE "member_id" = "issue_delegation_row"."truster_id"
jbe@615 783 AND "issue_id" = "issue_id_p"
jbe@615 784 ) THEN
jbe@615 785 "delegate_member_ids_v" :=
jbe@615 786 "member_id_p" || "delegate_member_ids_p";
jbe@615 787 INSERT INTO "delegating_voter" (
jbe@615 788 "issue_id",
jbe@615 789 "member_id",
jbe@615 790 "ownweight",
jbe@615 791 "scope",
jbe@615 792 "delegate_member_ids"
jbe@615 793 ) VALUES (
jbe@615 794 "issue_id_p",
jbe@615 795 "issue_delegation_row"."truster_id",
jbe@615 796 "issue_delegation_row"."weight",
jbe@615 797 "issue_delegation_row"."scope",
jbe@615 798 "delegate_member_ids_v"
jbe@615 799 );
jbe@615 800 "sub_weight_v" := "issue_delegation_row"."weight" +
jbe@615 801 "weight_of_added_vote_delegations"(
jbe@615 802 "issue_id_p",
jbe@615 803 "issue_delegation_row"."truster_id",
jbe@615 804 "delegate_member_ids_v"
jbe@615 805 );
jbe@615 806 UPDATE "delegating_voter"
jbe@615 807 SET "weight" = "sub_weight_v"
jbe@615 808 WHERE "issue_id" = "issue_id_p"
jbe@615 809 AND "member_id" = "issue_delegation_row"."truster_id";
jbe@615 810 "weight_v" := "weight_v" + "sub_weight_v";
jbe@615 811 END IF;
jbe@615 812 END LOOP;
jbe@615 813 RETURN "weight_v";
jbe@615 814 END;
jbe@615 815 $$;
jbe@615 816
jbe@615 817 CREATE OR REPLACE FUNCTION "add_vote_delegations"
jbe@615 818 ( "issue_id_p" "issue"."id"%TYPE )
jbe@615 819 RETURNS VOID
jbe@615 820 LANGUAGE 'plpgsql' VOLATILE AS $$
jbe@615 821 DECLARE
jbe@615 822 "member_id_v" "member"."id"%TYPE;
jbe@615 823 BEGIN
jbe@615 824 PERFORM "require_transaction_isolation"();
jbe@615 825 FOR "member_id_v" IN
jbe@615 826 SELECT "member_id" FROM "direct_voter"
jbe@615 827 WHERE "issue_id" = "issue_id_p"
jbe@615 828 LOOP
jbe@615 829 UPDATE "direct_voter" SET
jbe@615 830 "weight" = "ownweight" + "weight_of_added_vote_delegations"(
jbe@615 831 "issue_id_p",
jbe@615 832 "member_id_v",
jbe@615 833 '{}'
jbe@615 834 )
jbe@615 835 WHERE "member_id" = "member_id_v"
jbe@615 836 AND "issue_id" = "issue_id_p";
jbe@615 837 END LOOP;
jbe@615 838 RETURN;
jbe@615 839 END;
jbe@615 840 $$;
jbe@615 841
jbe@615 842 CREATE OR REPLACE FUNCTION "close_voting"("issue_id_p" "issue"."id"%TYPE)
jbe@615 843 RETURNS VOID
jbe@615 844 LANGUAGE 'plpgsql' VOLATILE AS $$
jbe@615 845 DECLARE
jbe@615 846 "area_id_v" "area"."id"%TYPE;
jbe@615 847 "unit_id_v" "unit"."id"%TYPE;
jbe@615 848 "member_id_v" "member"."id"%TYPE;
jbe@615 849 BEGIN
jbe@615 850 PERFORM "require_transaction_isolation"();
jbe@615 851 SELECT "area_id" INTO "area_id_v" FROM "issue" WHERE "id" = "issue_id_p";
jbe@615 852 SELECT "unit_id" INTO "unit_id_v" FROM "area" WHERE "id" = "area_id_v";
jbe@615 853 -- override protection triggers:
jbe@615 854 INSERT INTO "temporary_transaction_data" ("key", "value")
jbe@615 855 VALUES ('override_protection_triggers', TRUE::TEXT);
jbe@615 856 -- delete timestamp of voting comment:
jbe@615 857 UPDATE "direct_voter" SET "comment_changed" = NULL
jbe@615 858 WHERE "issue_id" = "issue_id_p";
jbe@615 859 -- delete delegating votes (in cases of manual reset of issue state):
jbe@615 860 DELETE FROM "delegating_voter"
jbe@615 861 WHERE "issue_id" = "issue_id_p";
jbe@615 862 -- delete votes from non-privileged voters:
jbe@615 863 DELETE FROM "direct_voter"
jbe@615 864 USING (
jbe@615 865 SELECT "direct_voter"."member_id"
jbe@615 866 FROM "direct_voter"
jbe@615 867 JOIN "member" ON "direct_voter"."member_id" = "member"."id"
jbe@615 868 LEFT JOIN "privilege"
jbe@615 869 ON "privilege"."unit_id" = "unit_id_v"
jbe@615 870 AND "privilege"."member_id" = "direct_voter"."member_id"
jbe@615 871 LEFT JOIN "issue_privilege"
jbe@615 872 ON "issue_privilege"."issue_id" = "issue_id_p"
jbe@615 873 AND "issue_privilege"."member_id" = "direct_voter"."member_id"
jbe@615 874 WHERE "direct_voter"."issue_id" = "issue_id_p" AND (
jbe@615 875 "member"."active" = FALSE OR
jbe@615 876 COALESCE(
jbe@615 877 "issue_privilege"."voting_right",
jbe@615 878 "privilege"."voting_right",
jbe@615 879 FALSE
jbe@615 880 ) = FALSE
jbe@615 881 )
jbe@615 882 ) AS "subquery"
jbe@615 883 WHERE "direct_voter"."issue_id" = "issue_id_p"
jbe@615 884 AND "direct_voter"."member_id" = "subquery"."member_id";
jbe@615 885 -- consider voting weight and delegations:
jbe@615 886 UPDATE "direct_voter" SET "ownweight" = "privilege"."weight"
jbe@615 887 FROM "privilege"
jbe@615 888 WHERE "issue_id" = "issue_id_p"
jbe@615 889 AND "privilege"."unit_id" = "unit_id_v"
jbe@615 890 AND "privilege"."member_id" = "direct_voter"."member_id";
jbe@615 891 UPDATE "direct_voter" SET "ownweight" = "issue_privilege"."weight"
jbe@615 892 FROM "issue_privilege"
jbe@615 893 WHERE "direct_voter"."issue_id" = "issue_id_p"
jbe@615 894 AND "issue_privilege"."issue_id" = "issue_id_p"
jbe@615 895 AND "issue_privilege"."member_id" = "direct_voter"."member_id";
jbe@615 896 PERFORM "add_vote_delegations"("issue_id_p");
jbe@615 897 -- mark first preferences:
jbe@615 898 UPDATE "vote" SET "first_preference" = "subquery"."first_preference"
jbe@615 899 FROM (
jbe@615 900 SELECT
jbe@615 901 "vote"."initiative_id",
jbe@615 902 "vote"."member_id",
jbe@615 903 CASE WHEN "vote"."grade" > 0 THEN
jbe@615 904 CASE WHEN "vote"."grade" = max("agg"."grade") THEN TRUE ELSE FALSE END
jbe@615 905 ELSE NULL
jbe@615 906 END AS "first_preference"
jbe@615 907 FROM "vote"
jbe@615 908 JOIN "initiative" -- NOTE: due to missing index on issue_id
jbe@615 909 ON "vote"."issue_id" = "initiative"."issue_id"
jbe@615 910 JOIN "vote" AS "agg"
jbe@615 911 ON "initiative"."id" = "agg"."initiative_id"
jbe@615 912 AND "vote"."member_id" = "agg"."member_id"
jbe@615 913 GROUP BY "vote"."initiative_id", "vote"."member_id", "vote"."grade"
jbe@615 914 ) AS "subquery"
jbe@615 915 WHERE "vote"."issue_id" = "issue_id_p"
jbe@615 916 AND "vote"."initiative_id" = "subquery"."initiative_id"
jbe@615 917 AND "vote"."member_id" = "subquery"."member_id";
jbe@615 918 -- finish overriding protection triggers (avoids garbage):
jbe@615 919 DELETE FROM "temporary_transaction_data"
jbe@615 920 WHERE "key" = 'override_protection_triggers';
jbe@615 921 -- materialize battle_view:
jbe@615 922 -- NOTE: "closed" column of issue must be set at this point
jbe@615 923 DELETE FROM "battle" WHERE "issue_id" = "issue_id_p";
jbe@615 924 INSERT INTO "battle" (
jbe@615 925 "issue_id",
jbe@615 926 "winning_initiative_id", "losing_initiative_id",
jbe@615 927 "count"
jbe@615 928 ) SELECT
jbe@615 929 "issue_id",
jbe@615 930 "winning_initiative_id", "losing_initiative_id",
jbe@615 931 "count"
jbe@615 932 FROM "battle_view" WHERE "issue_id" = "issue_id_p";
jbe@615 933 -- set voter count:
jbe@615 934 UPDATE "issue" SET
jbe@615 935 "voter_count" = (
jbe@615 936 SELECT coalesce(sum("weight"), 0)
jbe@615 937 FROM "direct_voter" WHERE "issue_id" = "issue_id_p"
jbe@615 938 )
jbe@615 939 WHERE "id" = "issue_id_p";
jbe@615 940 -- copy "positive_votes" and "negative_votes" from "battle" table:
jbe@615 941 -- NOTE: "first_preference_votes" is set to a default of 0 at this step
jbe@615 942 UPDATE "initiative" SET
jbe@615 943 "first_preference_votes" = 0,
jbe@615 944 "positive_votes" = "battle_win"."count",
jbe@615 945 "negative_votes" = "battle_lose"."count"
jbe@615 946 FROM "battle" AS "battle_win", "battle" AS "battle_lose"
jbe@615 947 WHERE
jbe@615 948 "battle_win"."issue_id" = "issue_id_p" AND
jbe@615 949 "battle_win"."winning_initiative_id" = "initiative"."id" AND
jbe@615 950 "battle_win"."losing_initiative_id" ISNULL AND
jbe@615 951 "battle_lose"."issue_id" = "issue_id_p" AND
jbe@615 952 "battle_lose"."losing_initiative_id" = "initiative"."id" AND
jbe@615 953 "battle_lose"."winning_initiative_id" ISNULL;
jbe@615 954 -- calculate "first_preference_votes":
jbe@615 955 -- NOTE: will only set values not equal to zero
jbe@615 956 UPDATE "initiative" SET "first_preference_votes" = "subquery"."sum"
jbe@615 957 FROM (
jbe@615 958 SELECT "vote"."initiative_id", sum("direct_voter"."weight")
jbe@615 959 FROM "vote" JOIN "direct_voter"
jbe@615 960 ON "vote"."issue_id" = "direct_voter"."issue_id"
jbe@615 961 AND "vote"."member_id" = "direct_voter"."member_id"
jbe@615 962 WHERE "vote"."first_preference"
jbe@615 963 GROUP BY "vote"."initiative_id"
jbe@615 964 ) AS "subquery"
jbe@615 965 WHERE "initiative"."issue_id" = "issue_id_p"
jbe@615 966 AND "initiative"."admitted"
jbe@615 967 AND "initiative"."id" = "subquery"."initiative_id";
jbe@615 968 END;
jbe@615 969 $$;
jbe@615 970
jbe@615 971 COMMIT;

Impressum / About Us