#include <stdio.h>

#include "libpq-fe.h"

int
main(void)
{
	PGconn		*conn = PQconnectdb("dbname=template1");
	PGresult	*res;
	int			 ret;

	/*
	 * Make an erronous Describe ('D') request.
	 */
	printf("=== PQdescribePrepared>\n");
	ret = PQdescribePrepared(conn, "not_exists");
	if (ret)
	{
		printf("PQdescribePrepared() failed! [%s]\n", PQerrorMessage(conn));
		
		PQfinish(conn);
		return 1;
	}

	/*
	 * Receive erronous describe response.
	 */
	printf("=== PQgetResult>\n");
	res = PQgetResult(conn);
	if (PQresultStatus(res) != PGRES_COMMAND_OK)
	{
		printf("PQgetResult() failed! %s [%s || Conn: %s]\n",
			   PQresStatus(PQresultStatus(res)),
			   PQresultErrorMessage(res),
			   PQerrorMessage(conn));

		printf("(***Expected Error.***)\n");
	}
	PQclear(res);

	/*
	 * Flush result set.
	 */
	printf("=== PQgetResult> (Flush result set)\n");
	res = PQgetResult(conn);
	if (res)
	{
		printf("Failed! %s [%s || Conn: %s]\n",
			   PQresStatus(PQresultStatus(res)),
			   PQresultErrorMessage(res),
			   PQerrorMessage(conn));
		
		PQclear(res);
		PQfinish(conn);
		return 1;
	}

	/*
	 * DECLARE a statement to describe.
	 */
	printf("=== DECLARE>\n");
	res = PQexec(conn,
				 "BEGIN; DECLARE curs CURSOR FOR"
				 "  SELECT "
				 "    (random()*100)::float8 AS c1, "
				 "    43 AS c2, "
				 "    (random()*1000)::int8 AS c3, "
				 "    'some text' AS c4;");
	if (PQresultStatus(res) != PGRES_COMMAND_OK)
	{
		printf("Failed! %s [%s || Conn: %s]\n",
			   PQresStatus(PQresultStatus(res)),
			   PQresultErrorMessage(res),
			   PQerrorMessage(conn));
		
		PQclear(res);
		PQfinish(conn);
		return 1;
	}
	PQclear(res);
	
	/*
	 * Make a Describe ('D') request.
	 */
	printf("=== PQdescribePortal>\n");
	ret = PQdescribePortal(conn, "curs");
	if (ret)
	{
		printf("PQdescribePortal() failed! [%s]\n", PQerrorMessage(conn));
		
		PQfinish(conn);
		return 1;
	}

	/*
	 * Receive Describe response (ParameterDescription).
	 */
	printf("=== PQgetResult>\n");
	res = PQgetResult(conn);
	if (PQresultStatus(res) != PGRES_TUPLES_OK)
	{
		printf("PQgetResult() failed! %s [%s || Conn: %s]\n",
			   PQresStatus(PQresultStatus(res)),
			   PQresultErrorMessage(res),
			   PQerrorMessage(conn));
		
		PQclear(res);
		PQfinish(conn);
		return 1;
	}
	else
	{
		int i, n = PQnfields(res);

		printf("PQfname\n");
		for (i = 0; i < n; i++)
			printf(" %d:%s\n", i, PQfname(res, i));
	}
	PQclear(res);

	/*
	 * Flush result set.
	 */
	printf("=== PQgetResult> (Flush result set)\n");
	res = PQgetResult(conn);
	if (res)
	{
		printf("Failed! %s [%s || Conn: %s]\n",
			   PQresStatus(PQresultStatus(res)),
			   PQresultErrorMessage(res),
			   PQerrorMessage(conn));
		
		PQclear(res);
		PQfinish(conn);
		return 1;
	}
	PQclear(res);

	PQfinish(conn);
	return 0;
}
