text: CREATE TABLE indtoasttest (
      descr text,
      cnt int DEFAULT 0,
      f1 text,
      f2 text
  );
  
  INSERT INTO indtoasttest (descr, f1, f2)
      VALUES ('two-compressed', repeat('1234567890', 1000), repeat('1234567890', 1000));
  
  INSERT INTO indtoasttest (descr, f1, f2)
      VALUES ('two-toasted', repeat('1234567890', 30000), repeat('1234567890', 50000));
  
  INSERT INTO indtoasttest (descr, f1, f2)
      VALUES ('one-compressed,one-null', NULL, repeat('1234567890', 1000));
  
  INSERT INTO indtoasttest (descr, f1, f2)
      VALUES ('one-toasted,one-null', NULL, repeat('1234567890', 50000));
  
  -- check whether indirect tuples works on the most basic level
  SELECT
      descr,
      substring(make_tuple_indirect (indtoasttest)::text, 1, 200)
  FROM
      indtoasttest;
  
  -- modification without changing varlenas
  UPDATE
      indtoasttest
  SET
      cnt = cnt + 1
  RETURNING
      substring(indtoasttest::text, 1, 200);
  
  -- modification without modifying assigned value
  UPDATE
      indtoasttest
  SET
      cnt = cnt + 1,
      f1 = f1
  RETURNING
      substring(indtoasttest::text, 1, 200);
  
  -- modification modifying, but effectively not changing
  UPDATE
      indtoasttest
  SET
      cnt = cnt + 1,
      f1 = f1 || ''
  RETURNING
      substring(indtoasttest::text, 1, 200);
  
  UPDATE
      indtoasttest
  SET
      cnt = cnt + 1,
      f1 = '-' || f1 || '-'
  RETURNING
      substring(indtoasttest::text, 1, 200);
  
  SELECT
      substring(indtoasttest::text, 1, 200)
  FROM
      indtoasttest;
  
  -- check we didn't screw with main/toast tuple visibility
  VACUUM FREEZE indtoasttest;
  
  SELECT
      substring(indtoasttest::text, 1, 200)
  FROM
      indtoasttest;
  
  -- now create a trigger that forces all Datums to be indirect ones
  CREATE FUNCTION update_using_indirect ()
      RETURNS TRIGGER
      LANGUAGE plpgsql
      AS $$
  BEGIN
      NEW := make_tuple_indirect (NEW);
      RETURN NEW;
  END
  $$;
  
  CREATE TRIGGER indtoasttest_update_indirect
      BEFORE INSERT
      OR UPDATE ON indtoasttest
      FOR EACH ROW
      EXECUTE PROCEDURE update_using_indirect ();
  
  -- modification without changing varlenas
  UPDATE
      indtoasttest
  SET
      cnt = cnt + 1
  RETURNING
      substring(indtoasttest::text, 1, 200);
  
  -- modification without modifying assigned value
  UPDATE
      indtoasttest
  SET
      cnt = cnt + 1,
      f1 = f1
  RETURNING
      substring(indtoasttest::text, 1, 200);
  
  -- modification modifying, but effectively not changing
  UPDATE
      indtoasttest
  SET
      cnt = cnt + 1,
      f1 = f1 || ''
  RETURNING
      substring(indtoasttest::text, 1, 200);
  
  UPDATE
      indtoasttest
  SET
      cnt = cnt + 1,
      f1 = '-' || f1 || '-'
  RETURNING
      substring(indtoasttest::text, 1, 200);
  
  INSERT INTO indtoasttest (descr, f1, f2)
      VALUES ('one-toasted,one-null, via indirect', repeat('1234567890', 30000), NULL);
  
  SELECT
      substring(indtoasttest::text, 1, 200)
  FROM
      indtoasttest;
  
  -- check we didn't screw with main/toast tuple visibility
  VACUUM FREEZE indtoasttest;
  
  SELECT
      substring(indtoasttest::text, 1, 200)
  FROM
      indtoasttest;
  
  DROP TABLE indtoasttest;
  
  DROP FUNCTION update_using_indirect ();
  
  