Übersicht der Quellen

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  merge-update.spec   Sprache: unbekannt

 
Spracherkennung für: .spec vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

# MERGE UPDATE
#
# This test exercises atypical cases
1. UPDATEs of PKs that change the join in the ON clause
2. UPDATEs with WHEN conditions that would fail after concurrent update
3. UPDATEs with extra ON conditions that would fail after concurrent update
4. UPDATEs with duplicate source rows

setup
{
  CREATE TABLE target (key int primary key, val text);
  INSERT INTO target VALUES (1, 'setup1');

  CREATE TABLE pa_target (key integer, val text)
   PARTITION BY LIST (key);
  CREATE TABLE part1 (key integer, val text);
  CREATE TABLE part2 (val text, key integer);
  CREATE TABLE part3 (key integer, val text);

  ALTER TABLE pa_target ATTACH PARTITION part1 FOR VALUES IN (1,4);
  ALTER TABLE pa_target ATTACH PARTITION part2 FOR VALUES IN (2,5,6);
  ALTER TABLE pa_target ATTACH PARTITION part3 DEFAULT;

  INSERT INTO pa_target VALUES (1, 'initial');
  INSERT INTO pa_target VALUES (2, 'initial');

  CREATE FUNCTION explain_filter(text) RETURNS SETOF text
  LANGUAGE plpgsql AS
  $$
  DECLARE
    ln text;
  BEGIN
    FOR ln IN EXECUTE $1 LOOP
      -- Ignore hash memory usage because it varies depending on the system
      CONTINUE WHEN (ln ~ 'Memory Usage');
      RETURN NEXT ln;
    END LOOP;
  END;
  $$;
}

teardown
{
  DROP TABLE target;
  DROP TABLE pa_target CASCADE;
  DROP FUNCTION explain_filter;
}

session "s1"
setup
{
  BEGIN ISOLATION LEVEL READ COMMITTED;
}
step "merge1"
{
  MERGE INTO target t
  USING (SELECT 1 as key, 'merge1' as val) s
  ON s.key = t.key
  WHEN NOT MATCHED THEN
 INSERT VALUES (s.key, s.val)
  WHEN MATCHED THEN
    UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val;
}
step "pa_merge1"
{
  MERGE INTO pa_target t
  USING (SELECT 1 as key, 'pa_merge1' as val) s
  ON s.key = t.key
  WHEN NOT MATCHED THEN
 INSERT VALUES (s.key, s.val)
  WHEN MATCHED THEN
    UPDATE set val = t.val || ' updated by ' || s.val;
}
step "pa_merge2"
{
  MERGE INTO pa_target t
  USING (SELECT 1 as key, 'pa_merge2' as val) s
  ON s.key = t.key
  WHEN NOT MATCHED THEN
 INSERT VALUES (s.key, s.val)
  WHEN MATCHED THEN
    UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val;
}
step "pa_merge3"
{
  MERGE INTO pa_target t
  USING (SELECT 1 as key, 'pa_merge2' as val) s
  ON s.key = t.key
  WHEN NOT MATCHED THEN
 INSERT VALUES (s.key, s.val)
  WHEN MATCHED THEN
    UPDATE set val = 'prefix ' || t.val;
}
step "c1" { COMMIT; }
step "a1" { ABORT; }
step "s1beginrr" { BEGIN ISOLATION LEVEL REPEATABLE READ; }

session "s2"
setup
{
  BEGIN ISOLATION LEVEL READ COMMITTED;
}
step "merge2a"
{
  MERGE INTO target t
  USING (SELECT 1 as key, 'merge2a' as val) s
  ON s.key = t.key
  WHEN NOT MATCHED THEN
 INSERT VALUES (s.key, s.val)
  WHEN MATCHED THEN
 UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val
  WHEN NOT MATCHED BY SOURCE THEN
 UPDATE set key = t.key + 1, val = t.val || ' source not matched by merge2a'
  RETURNING merge_action(), old, new, t.*;
}
step "explain_merge2a"
{
  SELECT explain_filter($$
  EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF, SUMMARY OFF, BUFFERS OFF)
  MERGE INTO target t
  USING (SELECT 1 as key, 'merge2a' as val) s
  ON s.key = t.key
  WHEN NOT MATCHED THEN
 INSERT VALUES (s.key, s.val)
  WHEN MATCHED THEN
 UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val
  WHEN NOT MATCHED BY SOURCE THEN
 UPDATE set key = t.key + 1, val = t.val || ' source not matched by merge2a'
  RETURNING merge_action(), old, new, t.*
  $$);
}
step "merge2b"
{
  MERGE INTO target t
  USING (SELECT 1 as key, 'merge2b' as val) s
  ON s.key = t.key
  WHEN NOT MATCHED THEN
 INSERT VALUES (s.key, s.val)
  WHEN MATCHED AND t.key < 2 THEN
 UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val;
}
step "merge2c"
{
  MERGE INTO target t
  USING (SELECT 1 as key, 'merge2c' as val) s
  ON s.key = t.key AND t.key < 2
  WHEN NOT MATCHED THEN
 INSERT VALUES (s.key, s.val)
  WHEN MATCHED THEN
 UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val;
}
step "pa_merge2a"
{
  MERGE INTO pa_target t
  USING (SELECT 1 as key, 'pa_merge2a' as val) s
  ON s.key = t.key
  WHEN NOT MATCHED THEN
 INSERT VALUES (s.key, s.val)
  WHEN MATCHED THEN
 UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val
  WHEN NOT MATCHED BY SOURCE THEN
 UPDATE set key = t.key + 1, val = t.val || ' source not matched by pa_merge2a'
  RETURNING merge_action(), old, new, t.*;
}
step "explain_pa_merge2a"
{
  SELECT explain_filter($$
  EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF, SUMMARY OFF, BUFFERS OFF)
  MERGE INTO pa_target t
  USING (SELECT 1 as key, 'pa_merge2a' as val) s
  ON s.key = t.key
  WHEN NOT MATCHED THEN
 INSERT VALUES (s.key, s.val)
  WHEN MATCHED THEN
 UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val
  WHEN NOT MATCHED BY SOURCE THEN
 UPDATE set key = t.key + 1, val = t.val || ' source not matched by pa_merge2a'
  RETURNING merge_action(), old, new, t.*
  $$);
}
# MERGE proceeds only if 'val' unchanged
step "pa_merge2b_when"
{
  MERGE INTO pa_target t
  USING (SELECT 1 as key, 'pa_merge2b_when' as val) s
  ON s.key = t.key
  WHEN NOT MATCHED THEN
 INSERT VALUES (s.key, s.val)
  WHEN MATCHED AND t.val like 'initial%' THEN
 UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val;
}
# Duplicate source row should fail
step "pa_merge2c_dup"
{
  MERGE INTO pa_target t
  USING (VALUES (1), (1)) v(a)
  ON t.key = v.a
  WHEN MATCHED THEN
 UPDATE set val = t.val || ' updated by pa_merge2c_dup';  -- should fail
}
step "select2" { SELECT * FROM target; }
step "pa_select2" { SELECT * FROM pa_target; }
step "c2" { COMMIT; }
step "a2" { ABORT; }

# Basic effects
permutation "merge1" "c1" "select2" "c2"

# One after the other, no concurrency
permutation "merge1" "c1" "merge2a" "select2" "c2"
permutation "merge1" "c1" "explain_merge2a" "select2" "c2"
permutation "pa_merge1" "c1" "pa_merge2c_dup" "a2"

# Now with concurrency
permutation "merge1" "merge2a" "c1" "select2" "c2"
permutation "merge1" "explain_merge2a" "c1" "select2" "c2"
permutation "merge1" "merge2a" "a1" "select2" "c2"
permutation "merge1" "merge2b" "c1" "select2" "c2"
permutation "merge1" "merge2c" "c1" "select2" "c2"
permutation "pa_merge1" "pa_merge2a" "c1" "pa_select2" "c2"
permutation "pa_merge1" "explain_pa_merge2a" "c1" "pa_select2" "c2"
permutation "pa_merge2" "pa_merge2a" "c1" "pa_select2" "c2" # fails
permutation "pa_merge2" "c1" "pa_merge2a" "pa_select2" "c2" # succeeds
permutation "pa_merge3" "pa_merge2b_when" "c1" "pa_select2" "c2" # WHEN not satisfied by updated tuple
permutation "pa_merge1" "pa_merge2b_when" "c1" "pa_select2" "c2" # WHEN satisfied by updated tuple
permutation "pa_merge1" "pa_merge2c_dup" "c1" "a2"
permutation "merge2a" "c1" "s1beginrr" "merge1" "c2"

[Dauer der Verarbeitung: 0.12 Sekunden, vorverarbeitet 2026-08-10]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=752002