/*-------------------------------------------------------------------------
 *
 * ruleutils.c
 *	  incremental view maintenance extension
 *    Routines for convert stored expressions/querytrees back to
 *	  source text
 *
 * Portions Copyright (c) 2026, IVM Development Group
 * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#if defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 150000)
#include "utils/rel.h"
#include "utils/ruleutils.h"
#elif defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 140000)
#include "ruleutils_14.c"
#else
#include "ruleutils_13.c"
#endif

#include "pg_ivm.h"

/* Standard conversion of a "bool pretty" option to detailed flags */
#define GET_PRETTY_FLAGS(pretty) \
	((pretty) ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) \
	 : PRETTYFLAG_INDENT)

/* ----------
 * pg_ivm_get_viewdef
 *
 * Public entry point to deparse a view definition query parsetree.
 * The pretty flags are determined by GET_PRETTY_FLAGS(pretty).
 *
 * The result is a palloc'd C string.
 * ----------
 */
char *
pg_ivm_get_viewdef(Relation immvrel, bool pretty)
{
	Query *query = get_immv_query(immvrel);
	TupleDesc resultDesc = RelationGetDescr(immvrel);

#if defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 150000)
	ListCell *lc;
	int colno = 0;

	/*
	 * Rewrite the result column name using the view's tuple
	 * descriptor.
	 *
	 * The column name is usually figured out in get_query_def
	 * using a tupleDesc specified as an argument, but this
	 * function is static, so we cannot directly call it.
	 * Therefore, we rewrite them prior to calling the public
	 * function pg_get_querydef (for PG15 or higher).
	 */
	query = copyObject(query);
	foreach (lc, query->targetList)
	{
		TargetEntry *tle = (TargetEntry *) lfirst(lc);

		if (tle->resjunk)
			continue;           /* ignore junk entries */

		colno++;
		if (resultDesc && colno <= resultDesc->natts)
			tle->resname = NameStr(TupleDescAttr(resultDesc, colno - 1)->attname);
	}

	return pg_get_querydef(query, pretty);

#else
	StringInfoData buf;
	int			prettyFlags;

	prettyFlags = GET_PRETTY_FLAGS(pretty);

	initStringInfo(&buf);

	/*
	 * For PG14 or earlier, we use get_query_def which is copied
	 * from the core because any public function for this purpose
	 * is not available.
	 */
	get_query_def(query, &buf, NIL, resultDesc, true,
				  prettyFlags, WRAP_COLUMN_DEFAULT, 0);

	return buf.data;
#endif
}
