#!/usr/bin/env python3
# Reproduce infinite loop in SV_to_JsonbValue on a circular Perl reference.
# The while (SvROK(in)) in = SvRV(in); loop in jsonb_plperl.c never terminates.

import subprocess

TIMEOUT = 5


def psql(sql):
    subprocess.run(["psql", "-c", sql], check=True, capture_output=True)


psql("CREATE EXTENSION IF NOT EXISTS jsonb_plperl CASCADE;")
psql("""
    CREATE OR REPLACE FUNCTION perl_circular() RETURNS jsonb
    LANGUAGE plperl TRANSFORM FOR TYPE jsonb AS $$
    my $x;
    $x = \\$x;
    return $x;
    $$;
""")

print(f"calling perl_circular(), waiting {TIMEOUT}s for hang... ", end="", flush=True)

proc = subprocess.Popen(["psql", "-c", "SELECT perl_circular();"],
                        stdout=subprocess.PIPE, stderr=subprocess.PIPE)

try:
    stdout, stderr = proc.communicate(timeout=TIMEOUT)
    output = (stdout + stderr).decode().strip()
    print(f"no hang:\n{output}")
except subprocess.TimeoutExpired:
    print("hung")
    proc.kill()
    proc.wait()
    print("psql client killed")
