liquid_feedback_core

changeset 302:548cec6b7a79

Better tie-breaking
author jbe
date Sat Sep 29 23:41:37 2012 +0200 (2012-09-29)
parents 7cad34b945ac
children 585c1cf4a3c9
files core.sql test.sql
line diff
     1.1 --- a/core.sql	Tue Sep 25 13:54:24 2012 +0200
     1.2 +++ b/core.sql	Sat Sep 29 23:41:37 2012 +0200
     1.3 @@ -7,7 +7,7 @@
     1.4  BEGIN;
     1.5  
     1.6  CREATE VIEW "liquid_feedback_version" AS
     1.7 -  SELECT * FROM (VALUES ('2.1.0', 2, 1, 0))
     1.8 +  SELECT * FROM (VALUES ('2.2.0', 2, 2, 0))
     1.9    AS "subquery"("string", "major", "minor", "revision");
    1.10  
    1.11  
    1.12 @@ -329,6 +329,11 @@
    1.13  COMMENT ON COLUMN "session"."lang"              IS 'Language code of the selected language';
    1.14  
    1.15  
    1.16 +CREATE TYPE "schulze_variant" AS ENUM ('absolute_strength', 'tuple_strength', 'partial_tie_breaking', 'tie_breaking_with_negative_strength');
    1.17 +
    1.18 +COMMENT ON TYPE "schulze_variant" IS 'Variant of schulze method, which differ by complexity; greater values have a higher complexity';
    1.19 +
    1.20 +
    1.21  CREATE TABLE "policy" (
    1.22          "id"                    SERIAL4         PRIMARY KEY,
    1.23          "index"                 INT4            NOT NULL,
    1.24 @@ -356,6 +361,7 @@
    1.25          "indirect_majority_non_negative" INT4   NOT NULL DEFAULT 0,
    1.26          "no_reverse_beat_path"          BOOLEAN NOT NULL DEFAULT TRUE,
    1.27          "no_multistage_majority"        BOOLEAN NOT NULL DEFAULT FALSE,
    1.28 +        "schulze_variant"     "schulze_variant" NOT NULL DEFAULT 'tie_breaking_with_negative_strength',
    1.29          CONSTRAINT "timing" CHECK (
    1.30            ( "polling" = FALSE AND
    1.31              "admission_time" NOTNULL AND "discussion_time" NOTNULL AND
    1.32 @@ -671,13 +677,13 @@
    1.33  COMMENT ON COLUMN "initiative"."negative_votes"         IS 'Calculated from table "direct_voter"';
    1.34  COMMENT ON COLUMN "initiative"."direct_majority"        IS 'TRUE, if "positive_votes"/("positive_votes"+"negative_votes") is strictly greater or greater-equal than "direct_majority_num"/"direct_majority_den", and "positive_votes" is greater-equal than "direct_majority_positive", and ("positive_votes"+abstentions) is greater-equal than "direct_majority_non_negative"';
    1.35  COMMENT ON COLUMN "initiative"."indirect_majority"      IS 'Same as "direct_majority", but also considering indirect beat paths';
    1.36 -COMMENT ON COLUMN "initiative"."schulze_rank"           IS 'Schulze-Ranking without tie-breaking';
    1.37 -COMMENT ON COLUMN "initiative"."better_than_status_quo" IS 'TRUE, if initiative has a schulze-ranking better than the status quo (without tie-breaking)';
    1.38 -COMMENT ON COLUMN "initiative"."worse_than_status_quo"  IS 'TRUE, if initiative has a schulze-ranking worse than the status quo (without tie-breaking)';
    1.39 +COMMENT ON COLUMN "initiative"."schulze_rank"           IS 'Schulze-Ranking';
    1.40 +COMMENT ON COLUMN "initiative"."better_than_status_quo" IS 'TRUE, if initiative has a schulze-ranking better than the status quo';
    1.41 +COMMENT ON COLUMN "initiative"."worse_than_status_quo"  IS 'TRUE, if initiative has a schulze-ranking worse than the status quo';
    1.42  COMMENT ON COLUMN "initiative"."reverse_beat_path"      IS 'TRUE, if there is a beat path (may include ties) from this initiative to the status quo';
    1.43  COMMENT ON COLUMN "initiative"."multistage_majority"    IS 'TRUE, if either (a) this initiative has no better rank than the status quo, or (b) there exists a better ranked initiative X, which directly beats this initiative, and either more voters prefer X to this initiative than voters preferring X to the status quo or less voters prefer this initiative to X than voters preferring the status quo to X';
    1.44  COMMENT ON COLUMN "initiative"."eligible"               IS 'Initiative has a "direct_majority" and an "indirect_majority", is "better_than_status_quo" and depending on selected policy the initiative has no "reverse_beat_path" or "multistage_majority"';
    1.45 -COMMENT ON COLUMN "initiative"."winner"                 IS 'Winner is the "eligible" initiative with best "schulze_rank" and in case of ties with lowest "id"';
    1.46 +COMMENT ON COLUMN "initiative"."winner"                 IS 'Winner is the "eligible" initiative with best "schulze_rank" and in case of unresolved ties with lowest "id"';
    1.47  COMMENT ON COLUMN "initiative"."rank"                   IS 'Unique ranking for all "admitted" initiatives per issue; lower rank is better; a winner always has rank 1, but rank 1 does not imply that an initiative is winner; initiatives with "direct_majority" AND "indirect_majority" always have a better (lower) rank than other initiatives';
    1.48  
    1.49  
    1.50 @@ -3848,22 +3854,47 @@
    1.51    IS 'Closes the voting on an issue, and calculates positive and negative votes for each initiative; The ranking is not calculated yet, to keep the (locking) transaction short.';
    1.52  
    1.53  
    1.54 +CREATE FUNCTION "impossible_defeat_strength"()
    1.55 +  RETURNS INT8
    1.56 +  LANGUAGE 'plpgsql' IMMUTABLE AS $$
    1.57 +    BEGIN
    1.58 +      RETURN -1::INT8 << 63;
    1.59 +    END;
    1.60 +  $$;
    1.61 +
    1.62 +COMMENT ON FUNCTION "impossible_defeat_strength"() IS 'An INT8 value lower than any other value returned by function "defeat_strength"(INT4, INT4)';
    1.63 +
    1.64 +
    1.65  CREATE FUNCTION "defeat_strength"
    1.66 -  ( "positive_votes_p" INT4, "negative_votes_p" INT4 )
    1.67 +  ( "schulze_variant_p" "schulze_variant",
    1.68 +    "positive_votes_p" INT4,
    1.69 +    "negative_votes_p" INT4 )
    1.70    RETURNS INT8
    1.71    LANGUAGE 'plpgsql' IMMUTABLE AS $$
    1.72      BEGIN
    1.73 -      IF "positive_votes_p" > "negative_votes_p" THEN
    1.74 -        RETURN ("positive_votes_p"::INT8 << 31) - "negative_votes_p"::INT8;
    1.75 -      ELSIF "positive_votes_p" = "negative_votes_p" THEN
    1.76 -        RETURN 0;
    1.77 +      IF "schulze_variant_p" >= 'tuple_strength'::"schulze_variant" THEN
    1.78 +        IF "positive_votes_p" > "negative_votes_p" THEN
    1.79 +          RETURN ("positive_votes_p"::INT8 << 31) - "negative_votes_p"::INT8;
    1.80 +        ELSIF "positive_votes_p" = "negative_votes_p" THEN
    1.81 +          RETURN 0::INT8;
    1.82 +        ELSE
    1.83 +          IF "schulze_variant_p" >= 'tie_breaking_with_negative_strength'::"schulze_variant" THEN
    1.84 +            RETURN "positive_votes_p"::INT8 - ("negative_votes_p"::INT8 << 31);
    1.85 +          ELSE
    1.86 +            RETURN "impossible_defeat_strength"();
    1.87 +          END IF;
    1.88 +        END IF;
    1.89        ELSE
    1.90 -        RETURN -1;
    1.91 +        IF "positive_votes_p" > "negative_votes_p" THEN
    1.92 +          RETURN "positive_votes_p"::INT8;
    1.93 +        ELSE
    1.94 +          RETURN 0::INT8;
    1.95 +        END IF;
    1.96        END IF;
    1.97      END;
    1.98    $$;
    1.99  
   1.100 -COMMENT ON FUNCTION "defeat_strength"(INT4, INT4) IS 'Calculates defeat strength (INT8!) of a pairwise defeat primarily by the absolute number of votes for the winner and secondarily by the absolute number of votes for the loser';
   1.101 +COMMENT ON FUNCTION "defeat_strength"("schulze_variant", INT4, INT4) IS 'Calculates defeat strength (INT8!) of a pairwise defeat primarily by the absolute number of votes for the winner and secondarily by the absolute number of votes for the loser. A tie has a strength of zero.';
   1.102  
   1.103  
   1.104  CREATE FUNCTION "calculate_ranks"("issue_id_p" "issue"."id"%TYPE)
   1.105 @@ -3873,11 +3904,17 @@
   1.106        "issue_row"         "issue"%ROWTYPE;
   1.107        "policy_row"        "policy"%ROWTYPE;
   1.108        "dimension_v"       INTEGER;
   1.109 -      "vote_matrix"       INT4[][];  -- absolute votes
   1.110 -      "matrix"            INT8[][];  -- defeat strength / best paths
   1.111 +      "vote_matrix"       INT4[][];     -- absolute votes
   1.112 +      "direct_matrix"     INT8[][];     -- direct defeat strength
   1.113 +      "path_matrix"       INT8[][];     -- defeat strength of best path
   1.114 +      "compare_matrix"    BOOLEAN[][];  -- binary relation to create schulze-rank
   1.115 +      "forbidden_matrix"  BOOLEAN[][];  -- forbidden links for tie-breaking
   1.116 +      "modified_matrix"   INT8[][];     -- defeat strength after tie-breaking
   1.117        "i"                 INTEGER;
   1.118        "j"                 INTEGER;
   1.119        "k"                 INTEGER;
   1.120 +      "m"                 INTEGER;
   1.121 +      "n"                 INTEGER;
   1.122        "battle_row"        "battle"%ROWTYPE;
   1.123        "rank_ary"          INT4[];
   1.124        "rank_v"            INT4;
   1.125 @@ -3917,15 +3954,16 @@
   1.126        IF "i" != "dimension_v" OR "j" != "dimension_v" + 1 THEN
   1.127          RAISE EXCEPTION 'Wrong battle count (should not happen)';
   1.128        END IF;
   1.129 -      -- Store defeat strengths in "matrix" using "defeat_strength"
   1.130 +      -- Store defeat strengths in "path_matrix" using "defeat_strength"
   1.131        -- function:
   1.132 -      "matrix" := array_fill(NULL::INT8, ARRAY["dimension_v", "dimension_v"]);
   1.133 +      "direct_matrix" := array_fill(NULL::INT8, ARRAY["dimension_v", "dimension_v"]);
   1.134        "i" := 1;
   1.135        LOOP
   1.136          "j" := 1;
   1.137          LOOP
   1.138            IF "i" != "j" THEN
   1.139 -            "matrix"["i"]["j"] := "defeat_strength"(
   1.140 +            "direct_matrix"["i"]["j"] := "defeat_strength"(
   1.141 +              "policy_row"."schulze_variant",
   1.142                "vote_matrix"["i"]["j"],
   1.143                "vote_matrix"["j"]["i"]
   1.144              );
   1.145 @@ -3937,6 +3975,7 @@
   1.146          "i" := "i" + 1;
   1.147        END LOOP;
   1.148        -- Find best paths:
   1.149 +      "path_matrix" := "direct_matrix";
   1.150        "i" := 1;
   1.151        LOOP
   1.152          "j" := 1;
   1.153 @@ -3945,13 +3984,13 @@
   1.154              "k" := 1;
   1.155              LOOP
   1.156                IF "i" != "k" AND "j" != "k" THEN
   1.157 -                IF "matrix"["j"]["i"] < "matrix"["i"]["k"] THEN
   1.158 -                  IF "matrix"["j"]["i"] > "matrix"["j"]["k"] THEN
   1.159 -                    "matrix"["j"]["k"] := "matrix"["j"]["i"];
   1.160 +                IF "path_matrix"["j"]["i"] < "path_matrix"["i"]["k"] THEN
   1.161 +                  IF "path_matrix"["j"]["i"] > "path_matrix"["j"]["k"] THEN
   1.162 +                    "path_matrix"["j"]["k"] := "path_matrix"["j"]["i"];
   1.163                    END IF;
   1.164                  ELSE
   1.165 -                  IF "matrix"["i"]["k"] > "matrix"["j"]["k"] THEN
   1.166 -                    "matrix"["j"]["k"] := "matrix"["i"]["k"];
   1.167 +                  IF "path_matrix"["i"]["k"] > "path_matrix"["j"]["k"] THEN
   1.168 +                    "path_matrix"["j"]["k"] := "path_matrix"["i"]["k"];
   1.169                    END IF;
   1.170                  END IF;
   1.171                END IF;
   1.172 @@ -3965,6 +4004,131 @@
   1.173          EXIT WHEN "i" = "dimension_v";
   1.174          "i" := "i" + 1;
   1.175        END LOOP;
   1.176 +      -- initial calculation of binary relation:
   1.177 +      "compare_matrix" := array_fill(NULL::BOOLEAN, ARRAY["dimension_v", "dimension_v"]);
   1.178 +      "i" := 1;
   1.179 +      LOOP
   1.180 +        "j" := 1;
   1.181 +        LOOP
   1.182 +          IF "i" != "j" THEN
   1.183 +            IF "path_matrix"["i"]["j"] > "path_matrix"["j"]["i"] THEN
   1.184 +              "compare_matrix"["i"]["j"] = TRUE;
   1.185 +              "compare_matrix"["j"]["i"] = FALSE;
   1.186 +            ELSIF "path_matrix"["i"]["j"] < "path_matrix"["j"]["i"] THEN
   1.187 +              "compare_matrix"["i"]["j"] = FALSE;
   1.188 +              "compare_matrix"["j"]["i"] = TRUE;
   1.189 +            END IF;
   1.190 +          END IF;
   1.191 +          EXIT WHEN "j" = "dimension_v";
   1.192 +          "j" := "j" + 1;
   1.193 +        END LOOP;
   1.194 +        EXIT WHEN "i" = "dimension_v";
   1.195 +        "i" := "i" + 1;
   1.196 +      END LOOP;
   1.197 +      -- tie-breaking:
   1.198 +      IF "policy_row"."schulze_variant" >= 'partial_tie_breaking'::"schulze_variant" THEN
   1.199 +        "modified_matrix"  := array_fill(NULL::INT8, ARRAY["dimension_v", "dimension_v"]);
   1.200 +        "forbidden_matrix" := array_fill(NULL::BOOLEAN, ARRAY["dimension_v", "dimension_v"]);
   1.201 +        "m" := 1;
   1.202 +        LOOP
   1.203 +          "n" := "m" + 1;
   1.204 +          LOOP
   1.205 +            IF "compare_matrix"["m"]["n"] ISNULL THEN
   1.206 +              "i" := 1;
   1.207 +              LOOP
   1.208 +                "j" := 1;
   1.209 +                LOOP
   1.210 +                  IF "i" != "j" THEN
   1.211 +                    "forbidden_matrix"["i"]["j"] := FALSE;
   1.212 +                    "modified_matrix"["i"]["j"] := "path_matrix"["i"]["j"];
   1.213 +                  END IF;
   1.214 +                  EXIT WHEN "j" = "dimension_v";
   1.215 +                  "j" := "j" + 1;
   1.216 +                END LOOP;
   1.217 +                EXIT WHEN "i" = "dimension_v";
   1.218 +                "i" := "i" + 1;
   1.219 +              END LOOP;
   1.220 +              LOOP
   1.221 +                "i" := 1;
   1.222 +                LOOP
   1.223 +                  "j" := 1;
   1.224 +                  LOOP
   1.225 +                    IF "i" != "j" THEN
   1.226 +                      IF "modified_matrix"["m"]["n"] = "direct_matrix"["i"]["j"] THEN
   1.227 +                        "forbidden_matrix"["i"]["j"] := TRUE;
   1.228 +                      END IF;
   1.229 +                    END IF;
   1.230 +                    EXIT WHEN "j" = "dimension_v";
   1.231 +                    "j" := "j" + 1;
   1.232 +                  END LOOP;
   1.233 +                  EXIT WHEN "i" = "dimension_v";
   1.234 +                  "i" := "i" + 1;
   1.235 +                END LOOP;
   1.236 +                "i" := 1;
   1.237 +                LOOP
   1.238 +                  "j" := 1;
   1.239 +                  LOOP
   1.240 +                    IF "i" != "j" THEN
   1.241 +                      IF "forbidden_matrix"["i"]["j"] THEN
   1.242 +                        "modified_matrix"["i"]["j"] := "impossible_defeat_strength"();
   1.243 +                      ELSE
   1.244 +                        "modified_matrix"["i"]["j"] := "direct_matrix"["i"]["j"];
   1.245 +                      END IF;
   1.246 +                    END IF;
   1.247 +                    EXIT WHEN "j" = "dimension_v";
   1.248 +                    "j" := "j" + 1;
   1.249 +                  END LOOP;
   1.250 +                  EXIT WHEN "i" = "dimension_v";
   1.251 +                  "i" := "i" + 1;
   1.252 +                END LOOP;
   1.253 +                "i" := 1;
   1.254 +                LOOP
   1.255 +                  "j" := 1;
   1.256 +                  LOOP
   1.257 +                    IF "i" != "j" THEN
   1.258 +                      "k" := 1;
   1.259 +                      LOOP
   1.260 +                        IF "i" != "k" AND "j" != "k" THEN
   1.261 +                          IF "modified_matrix"["j"]["i"] < "modified_matrix"["i"]["k"] THEN
   1.262 +                            IF "modified_matrix"["j"]["i"] > "modified_matrix"["j"]["k"] THEN
   1.263 +                              "modified_matrix"["j"]["k"] := "modified_matrix"["j"]["i"];
   1.264 +                            END IF;
   1.265 +                          ELSE
   1.266 +                            IF "modified_matrix"["i"]["k"] > "modified_matrix"["j"]["k"] THEN
   1.267 +                              "modified_matrix"["j"]["k"] := "modified_matrix"["i"]["k"];
   1.268 +                            END IF;
   1.269 +                          END IF;
   1.270 +                        END IF;
   1.271 +                        EXIT WHEN "k" = "dimension_v";
   1.272 +                        "k" := "k" + 1;
   1.273 +                      END LOOP;
   1.274 +                    END IF;
   1.275 +                    EXIT WHEN "j" = "dimension_v";
   1.276 +                    "j" := "j" + 1;
   1.277 +                  END LOOP;
   1.278 +                  EXIT WHEN "i" = "dimension_v";
   1.279 +                  "i" := "i" + 1;
   1.280 +                END LOOP;
   1.281 +                IF "modified_matrix"["m"]["n"] > "modified_matrix"["n"]["m"] THEN
   1.282 +                  "compare_matrix"["m"]["n"] := TRUE;
   1.283 +                  "compare_matrix"["n"]["m"] := FALSE;
   1.284 +                  EXIT;
   1.285 +                ELSIF "modified_matrix"["m"]["n"] < "modified_matrix"["n"]["m"] THEN
   1.286 +                  "compare_matrix"["m"]["n"] := FALSE;
   1.287 +                  "compare_matrix"["n"]["m"] := TRUE;
   1.288 +                  EXIT;
   1.289 +                ELSIF "modified_matrix"["m"]["n"] = "impossible_defeat_strength"() THEN
   1.290 +                  EXIT;
   1.291 +                END IF;
   1.292 +              END LOOP;
   1.293 +            END IF;
   1.294 +            EXIT WHEN "n" = "dimension_v";
   1.295 +            "n" := "n" + 1;
   1.296 +          END LOOP;
   1.297 +          EXIT WHEN "m" = "dimension_v" - 1;
   1.298 +          "m" := "m" + 1;
   1.299 +        END LOOP;
   1.300 +      END IF;
   1.301        -- Determine order of winners:
   1.302        "rank_ary" := array_fill(NULL::INT4, ARRAY["dimension_v"]);
   1.303        "rank_v" := 1;
   1.304 @@ -3979,7 +4143,7 @@
   1.305                IF
   1.306                  "i" != "j" AND
   1.307                  "rank_ary"["j"] ISNULL AND
   1.308 -                "matrix"["j"]["i"] > "matrix"["i"]["j"]
   1.309 +                "compare_matrix"["j"]["i"]
   1.310                THEN
   1.311                  -- someone else is better
   1.312                  EXIT;
   1.313 @@ -4039,7 +4203,7 @@
   1.314            "better_than_status_quo" = "rank_ary"["i"] < "rank_ary"["dimension_v"],
   1.315            "worse_than_status_quo"  = "rank_ary"["i"] > "rank_ary"["dimension_v"],
   1.316            "multistage_majority"    = "rank_ary"["i"] >= "rank_ary"["dimension_v"],
   1.317 -          "reverse_beat_path"      = "matrix"["dimension_v"]["i"] >= 0,
   1.318 +          "reverse_beat_path"      = "path_matrix"["dimension_v"]["i"] >= 0,
   1.319            "eligible"               = FALSE,
   1.320            "winner"                 = FALSE,
   1.321            "rank"                   = NULL  -- NOTE: in cases of manual reset of issue state
     2.1 --- a/test.sql	Tue Sep 25 13:54:24 2012 +0200
     2.2 +++ b/test.sql	Sat Sep 29 23:41:37 2012 +0200
     2.3 @@ -41,7 +41,8 @@
     2.4      "issue_quorum_num", "issue_quorum_den",
     2.5      "initiative_quorum_num", "initiative_quorum_den",
     2.6      "direct_majority_num", "direct_majority_den", "direct_majority_strict",
     2.7 -    "no_reverse_beat_path", "no_multistage_majority"
     2.8 +    "no_reverse_beat_path", "no_multistage_majority",
     2.9 +    "schulze_variant"
    2.10    ) VALUES (
    2.11      1,
    2.12      'Default policy',
    2.13 @@ -49,7 +50,8 @@
    2.14      25, 100,
    2.15      20, 100,
    2.16      1, 2, TRUE,
    2.17 -    TRUE, FALSE );
    2.18 +    TRUE, FALSE,
    2.19 +    'tie_breaking_with_negative_strength'::"schulze_variant" );
    2.20  
    2.21  CREATE FUNCTION "time_warp"() RETURNS VOID
    2.22    LANGUAGE 'plpgsql' VOLATILE AS $$
    2.23 @@ -118,10 +120,37 @@
    2.24    (18, 'unit', 1, 19),
    2.25    (23, 'unit', 1, 22);
    2.26  
    2.27 +-- no delegations in area #1
    2.28 +INSERT INTO "delegation"
    2.29 +  ("truster_id", "scope", "area_id", "trustee_id") VALUES
    2.30 +  ( 1, 'area', 1, NULL),
    2.31 +  ( 2, 'area', 1, NULL),
    2.32 +  ( 3, 'area', 1, NULL),
    2.33 +  ( 4, 'area', 1, NULL),
    2.34 +  ( 5, 'area', 1, NULL),
    2.35 +  ( 6, 'area', 1, NULL),
    2.36 +  ( 7, 'area', 1, NULL),
    2.37 +  ( 8, 'area', 1, NULL),
    2.38 +  ( 9, 'area', 1, NULL),
    2.39 +  (10, 'area', 1, NULL),
    2.40 +  (11, 'area', 1, NULL),
    2.41 +  (12, 'area', 1, NULL),
    2.42 +  (13, 'area', 1, NULL),
    2.43 +  (14, 'area', 1, NULL),
    2.44 +  (15, 'area', 1, NULL),
    2.45 +  (16, 'area', 1, NULL),
    2.46 +  (17, 'area', 1, NULL),
    2.47 +  (18, 'area', 1, NULL),
    2.48 +  (19, 'area', 1, NULL),
    2.49 +  (20, 'area', 1, NULL),
    2.50 +  (21, 'area', 1, NULL),
    2.51 +  (22, 'area', 1, NULL),
    2.52 +  (23, 'area', 1, NULL);
    2.53 +
    2.54  -- delegations for topics
    2.55  INSERT INTO "delegation"
    2.56    ("area_id", "truster_id", "scope", "trustee_id") VALUES
    2.57 -  (1,  3, 'area', 17),
    2.58 +  --(1,  3, 'area', 17),
    2.59    (2,  5, 'area', 10),
    2.60    (2,  9, 'area', 10),
    2.61    (3,  4, 'area', 14),
    2.62 @@ -236,6 +265,25 @@
    2.63    (6,  9,  9),
    2.64    (6, 10, 10),
    2.65    (6, 11, 11);
    2.66 +
    2.67 +INSERT INTO "issue" ("area_id", "policy_id") VALUES
    2.68 +  (1, 1);  -- id 3
    2.69 +
    2.70 +INSERT INTO "initiative" ("issue_id", "name") VALUES
    2.71 +  (3, 'First initiative'),   -- id 12
    2.72 +  (3, 'Second initiative');  -- id 13
    2.73 +
    2.74 +INSERT INTO "draft" ("initiative_id", "author_id", "content") VALUES
    2.75 +  (12, 1, 'Lorem ipsum...'),  -- id 12
    2.76 +  (13, 2, 'Lorem ipsum...');  -- id 13
    2.77 +
    2.78 +INSERT INTO "initiator" ("initiative_id", "member_id") VALUES
    2.79 +  (12, 1),
    2.80 +  (13, 2);
    2.81 +
    2.82 +INSERT INTO "supporter" ("initiative_id", "member_id") VALUES
    2.83 +  (12, 1),
    2.84 +  (13, 2);
    2.85   
    2.86  SELECT "time_warp"();
    2.87  SELECT "time_warp"();
    2.88 @@ -402,6 +450,25 @@
    2.89    (20, 2, 10, -1),
    2.90    (20, 2, 11,  3);
    2.91  
    2.92 +INSERT INTO "direct_voter" ("member_id", "issue_id") VALUES
    2.93 +  ( 1, 3),
    2.94 +  ( 2, 3),
    2.95 +  ( 3, 3),
    2.96 +  ( 4, 3),
    2.97 +  ( 5, 3);
    2.98 +
    2.99 +INSERT INTO "vote" ("member_id", "issue_id", "initiative_id", "grade") VALUES
   2.100 +  (1, 3, 12,  1),
   2.101 +  (1, 3, 13,  1),
   2.102 +  (2, 3, 12,  1),
   2.103 +  (2, 3, 13,  1),
   2.104 +  (3, 3, 12,  0),
   2.105 +  (3, 3, 13,  1),
   2.106 +  (4, 3, 12,  0),
   2.107 +  (4, 3, 13, -1),
   2.108 +  (5, 3, 12, -1),
   2.109 +  (5, 3, 13, -1);
   2.110 +
   2.111  SELECT "time_warp"();
   2.112  
   2.113  DROP FUNCTION "time_warp"();

Impressum / About Us