Previously, a query string returned from pg_ivm_get_querydef did not include column names specified when IMMV was defined by create_immv. This caused failures in maintenance of MIN/MAX aggregate views whose columns had alias names. It is fixed by rewriting the result column name in the parse tree using the view's tuple descriptor prior to calling pg_get_querydef for PG15 or higher, or specifying the tuple descriptor to get_query_def for PG14 or earlier.
95 lines
2.5 KiB
C
95 lines
2.5 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* ruleutils.c
|
|
* incremental view maintenance extension
|
|
* Routines for convert stored expressions/querytrees back to
|
|
* source text
|
|
*
|
|
* Portions Copyright (c) 2022, 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
|
|
}
|