/*--------------------------------------------------------------------------
 *
 * test_predtest.c
 *		Test correctness of optimizer's predicate proof logic.
 *
 * Copyright (c) 2018-2020, PostgreSQL Global Development Group
 *
 * IDENTIFICATION
 *		src/test/modules/test_predtest/test_predtest.c
 *
 * -------------------------------------------------------------------------
 */

#include "postgres.h"

#include "access/htup_details.h"
#include "catalog/pg_type.h"
#include "executor/spi.h"
#include "funcapi.h"
#include "nodes/makefuncs.h"
#include "optimizer/optimizer.h"
#include "utils/builtins.h"

PG_MODULE_MAGIC;

/*
 * test_predtest(query text) returns record
 */
PG_FUNCTION_INFO_V1(test_predtest);

Datum
test_predtest(PG_FUNCTION_ARGS)
{
	text	   *txt = PG_GETARG_TEXT_PP(0);
	char	   *query_string = text_to_cstring(txt);
	SPIPlanPtr	spiplan;
	int			spirc;
	TupleDesc	tupdesc;
	bool		s_i_holds,
				w_i_holds,
				s_r_holds,
				w_r_holds;
	CachedPlan *cplan;
	PlannedStmt *stmt;
	Plan	   *plan;
	Expr	   *clause1;
	Expr	   *clause2;
	bool		strong_implied_by,
				weak_implied_by,
				strong_refuted_by,
				weak_refuted_by;
	Datum		values[8];
	bool		nulls[8];
	int			i;

	/* We use SPI to parse, plan, and execute the test query */
	if (SPI_connect() != SPI_OK_CONNECT)
		elog(ERROR, "SPI_connect failed");

	/*
	 * First, plan and execute the query, and inspect the results.  To the
	 * extent that the query fully exercises the two expressions, this
	 * provides an experimental indication of whether implication or
	 * refutation holds.
	 */
	spiplan = SPI_prepare(query_string, 0, NULL);
	if (spiplan == NULL)
		elog(ERROR, "SPI_prepare failed for \"%s\"", query_string);

	spirc = SPI_execute_plan(spiplan, NULL, NULL, true, 0);
	if (spirc != SPI_OK_SELECT)
		elog(ERROR, "failed to execute \"%s\"", query_string);
	tupdesc = SPI_tuptable->tupdesc;
	if (tupdesc->natts != 2 ||
		TupleDescAttr(tupdesc, 0)->atttypid != BOOLOID ||
		TupleDescAttr(tupdesc, 1)->atttypid != BOOLOID)
		elog(ERROR, "query must yield two boolean columns");

	s_i_holds = w_i_holds = s_r_holds = w_r_holds = true;
	for (i = 0; i < SPI_processed; i++)
	{
		HeapTuple	tup = SPI_tuptable->vals[i];
		Datum		dat;
		bool		isnull;
		char		c1,
					c2;

		/* Extract column values in a 3-way representation */
		dat = SPI_getbinval(tup, tupdesc, 1, &isnull);
		if (isnull)
			c1 = 'n';
		else if (DatumGetBool(dat))
			c1 = 't';
		else
			c1 = 'f';

		dat = SPI_getbinval(tup, tupdesc, 2, &isnull);
		if (isnull)
			c2 = 'n';
		else if (DatumGetBool(dat))
			c2 = 't';
		else
			c2 = 'f';

		/* Check for violations of various proof conditions */

		/* strong implication: truth of c2 implies truth of c1 */
		if (c2 == 't' && c1 != 't')
			s_i_holds = false;
		/* weak implication: non-falsity of c2 implies non-falsity of c1 */
		if (c2 != 'f' && c1 == 'f')
			w_i_holds = false;
		/* strong refutation: truth of c2 implies falsity of c1 */
		if (c2 == 't' && c1 != 'f')
			s_r_holds = false;
		/* weak refutation: truth of c2 implies non-truth of c1 */
		if (c2 == 't' && c1 == 't')
			w_r_holds = false;
	}

	/*
	 * Now, dig the clause querytrees out of the plan, and see what predtest.c
	 * does with them.
	 */
	cplan = SPI_plan_get_cached_plan(spiplan);

	if (list_length(cplan->stmt_list) != 1)
		elog(ERROR, "failed to decipher query plan");
	stmt = linitial_node(PlannedStmt, cplan->stmt_list);
	if (stmt->commandType != CMD_SELECT)
		elog(ERROR, "failed to decipher query plan");
	plan = stmt->planTree;
	Assert(list_length(plan->targetlist) >= 2);
	clause1 = castNode(TargetEntry, linitial(plan->targetlist))->expr;
	clause2 = castNode(TargetEntry, lsecond(plan->targetlist))->expr;

	/*
	 * Because the clauses are in the SELECT list, preprocess_expression did
	 * not pass them through canonicalize_qual nor make_ands_implicit.
	 *
	 * We can't do canonicalize_qual here, since it's unclear whether the
	 * expressions ought to be treated as WHERE or CHECK clauses. Fortunately,
	 * useful test expressions wouldn't be affected by those transformations
	 * anyway.  We should do make_ands_implicit, though.
	 *
	 * Another way in which this does not exactly duplicate the normal usage
	 * of the proof functions is that they are often given qual clauses
	 * containing RestrictInfo nodes.  But since predtest.c just looks through
	 * those anyway, it seems OK to not worry about that point.
	 */
	clause1 = (Expr *) make_ands_implicit(clause1);
	clause2 = (Expr *) make_ands_implicit(clause2);

	strong_implied_by = predicate_implied_by((List *) clause1,
											 (List *) clause2,
											 false);

	weak_implied_by = predicate_implied_by((List *) clause1,
										   (List *) clause2,
										   true);

	strong_refuted_by = predicate_refuted_by((List *) clause1,
											 (List *) clause2,
											 false);

	weak_refuted_by = predicate_refuted_by((List *) clause1,
										   (List *) clause2,
										   true);

	/*
	 * Issue warning if any proof is demonstrably incorrect.
	 */
	if (strong_implied_by && !s_i_holds)
		elog(WARNING, "strong_implied_by result is incorrect");
	if (weak_implied_by && !w_i_holds)
		elog(WARNING, "weak_implied_by result is incorrect");
	if (strong_refuted_by && !s_r_holds)
		elog(WARNING, "strong_refuted_by result is incorrect");
	if (weak_refuted_by && !w_r_holds)
		elog(WARNING, "weak_refuted_by result is incorrect");

	/*
	 * Clean up and return a record of the results.
	 */
	if (SPI_finish() != SPI_OK_FINISH)
		elog(ERROR, "SPI_finish failed");

	tupdesc = CreateTemplateTupleDesc(8);
	TupleDescInitEntry(tupdesc, (AttrNumber) 1,
					   "strong_implied_by", BOOLOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 2,
					   "weak_implied_by", BOOLOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 3,
					   "strong_refuted_by", BOOLOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 4,
					   "weak_refuted_by", BOOLOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 5,
					   "s_i_holds", BOOLOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 6,
					   "w_i_holds", BOOLOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 7,
					   "s_r_holds", BOOLOID, -1, 0);
	TupleDescInitEntry(tupdesc, (AttrNumber) 8,
					   "w_r_holds", BOOLOID, -1, 0);
	tupdesc = BlessTupleDesc(tupdesc);

	MemSet(nulls, 0, sizeof(nulls));
	values[0] = BoolGetDatum(strong_implied_by);
	values[1] = BoolGetDatum(weak_implied_by);
	values[2] = BoolGetDatum(strong_refuted_by);
	values[3] = BoolGetDatum(weak_refuted_by);
	values[4] = BoolGetDatum(s_i_holds);
	values[5] = BoolGetDatum(w_i_holds);
	values[6] = BoolGetDatum(s_r_holds);
	values[7] = BoolGetDatum(w_r_holds);

	PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
}
