Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Postgres/src/backend/backup/   (Postgres Database Version 18.4©)  Datei vom 11.4.2026 mit Größe 34 kB image not shown  

Quelle  plpgsql-toast.spec   Sprache: unbekannt

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

# Test TOAST behavior in PL/pgSQL procedures with transaction control.
#
# We need to ensure that values stored in PL/pgSQL variables are free
# of external TOAST references, because those could disappear after a
# transaction is committed (leading to errors "missing chunk number
# ... for toast value ...").  The tests here do this by running VACUUM
# in a second session.  Advisory locks are used to have the VACUUM
# kick in at the right time.  The different "assign" steps test
# different code paths for variable assignments in PL/pgSQL.

setup
{
    CREATE TABLE test1 (a int, b text);
    ALTER TABLE test1 ALTER COLUMN b SET STORAGE EXTERNAL;
    INSERT INTO test1 VALUES (1, repeat('foo', 2000));
    CREATE TYPE test2 AS (a bigint, b text);
}

teardown
{
    DROP TABLE test1;
    DROP TYPE test2;
}

session s1

setup
{
    SELECT pg_advisory_unlock_all();
}

# assign_simple_var()
step assign1
{
do $$
  declare
    x text;
  begin
    select test1.b into x from test1;
    delete from test1;
    commit;
    perform pg_advisory_lock(1);
    raise notice 'length(x) = %', length(x);
  end;
$$;
}

# assign_simple_var()
step assign2
{
do $$
  declare
    x text;
  begin
    x := (select test1.b from test1);
    delete from test1;
    commit;
    perform pg_advisory_lock(1);
    raise notice 'length(x) = %', length(x);
  end;
$$;
}

# expanded_record_set_field()
step assign3
{
do $$
  declare
    r record;
  begin
    select * into r from test1;
    r.b := (select test1.b from test1);
    delete from test1;
    commit;
    perform pg_advisory_lock(1);
    raise notice 'length(r) = %', length(r::text);
  end;
$$;
}

# expanded_record_set_fields()
step assign4
{
do $$
  declare
    r test2;
  begin
    select * into r from test1;
    delete from test1;
    commit;
    perform pg_advisory_lock(1);
    raise notice 'length(r) = %', length(r::text);
  end;
$$;
}

# expanded_record_set_tuple()
step assign5
{
do $$
  declare
    r record;
  begin
    for r in select test1.b from test1 loop
      null;
    end loop;
    delete from test1;
    commit;
    perform pg_advisory_lock(1);
    raise notice 'length(r) = %', length(r::text);
  end;
$$;
}

# FOR loop must not hold any fetched-but-not-detoasted values across commit
step assign6
{
do $$
  declare
    r record;
  begin
    insert into test1 values (2, repeat('bar', 3000));
    insert into test1 values (3, repeat('baz', 4000));
    for r in select test1.b from test1 loop
      delete from test1;
      commit;
      perform pg_advisory_lock(1);
      raise notice 'length(r) = %', length(r::text);
    end loop;
  end;
$$;
}

# Check that the results of a query can be detoasted just after committing
# (there's no interaction with VACUUM here)
step "fetch-after-commit"
{
do $$
  declare
    r record;
    t text;
  begin
    insert into test1 values (2, repeat('bar', 3000));
    insert into test1 values (3, repeat('baz', 4000));
    for r in select test1.a from test1 loop
      commit;
      select b into t from test1 where a = r.a;
      raise notice 'length(t) = %', length(t);
    end loop;
  end;
$$;
}

session s2
setup
{
    SELECT pg_advisory_unlock_all();
}
step lock
{
    SELECT pg_advisory_lock(1);
}
step vacuum
{
    VACUUM test1;
}
step unlock
{
    SELECT pg_advisory_unlock(1);
}

permutation lock assign1 vacuum unlock
permutation lock assign2 vacuum unlock
permutation lock assign3 vacuum unlock
permutation lock assign4 vacuum unlock
permutation lock assign5 vacuum unlock
permutation lock assign6 vacuum unlock
permutation "fetch-after-commit"

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