Skip to content

Commit d3248cc

Browse files
committed
Apply necessary ruleutils changes to PG19 ruleutils file (#983)
Changes created by doing: ``` git diff e963297 src/vendor/pg_ruleutils_17.c > ruleutils.diff ``` Then slightly modifying that diff file to replace 17 with 19 ``` git apply --3way ruleutils.diff ```
1 parent 4f7067a commit d3248cc

File tree

1 file changed

+109
-112
lines changed

1 file changed

+109
-112
lines changed

src/vendor/pg_ruleutils_19.c

Lines changed: 109 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
/*-------------------------------------------------------------------------
22
*
3-
* ruleutils.c
3+
* pg_ruleutils_19.c
44
* Functions to convert stored expressions/querytrees back to
55
* source text
66
*
77
* Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
*
11-
* IDENTIFICATION
12-
* src/backend/utils/adt/ruleutils.c
13-
*
1410
*-------------------------------------------------------------------------
1511
*/
1612
#include "postgres.h"
1713

14+
#if PG_VERSION_NUM >= 190000 && PG_VERSION_NUM < 200000
15+
16+
#pragma GCC diagnostic ignored "-Wshadow" // ignore any compiler warnings
17+
#pragma GCC diagnostic ignored "-Wsign-compare" // ignore any compiler warnings
18+
#pragma GCC diagnostic ignored "-Wunused-parameter" // ignore any compiler warnings
19+
1820
#include <ctype.h>
1921
#include <unistd.h>
2022
#include <fcntl.h>
@@ -65,13 +67,17 @@
6567
#include "utils/lsyscache.h"
6668
#include "utils/partcache.h"
6769
#include "utils/rel.h"
68-
#include "utils/ruleutils.h"
70+
#include "pgduckdb/vendor/pg_ruleutils.h"
6971
#include "utils/snapmgr.h"
7072
#include "utils/syscache.h"
7173
#include "utils/typcache.h"
7274
#include "utils/varlena.h"
7375
#include "utils/xml.h"
7476

77+
#include "pgduckdb/pgduckdb_ruleutils.h"
78+
79+
#include "pgduckdb/utility/rename_ruleutils.h"
80+
7581
/* ----------
7682
* Pretty formatting constants
7783
* ----------
@@ -92,7 +98,7 @@
9298
/* Standard conversion of a "bool pretty" option to detailed flags */
9399
#define GET_PRETTY_FLAGS(pretty) \
94100
((pretty) ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) \
95-
: PRETTYFLAG_INDENT)
101+
: 0)
96102

97103
/* Default line length for pretty-print wrapping: 0 means wrap always */
98104
#define WRAP_COLUMN_DEFAULT 0
@@ -525,8 +531,6 @@ static void get_opclass_name(Oid opclass, Oid actual_datatype,
525531
static Node *processIndirection(Node *node, deparse_context *context);
526532
static void printSubscripts(SubscriptingRef *sbsref, deparse_context *context);
527533
static char *get_relation_name(Oid relid);
528-
static char *generate_relation_name(Oid relid, List *namespaces);
529-
static char *generate_qualified_relation_name(Oid relid);
530534
static char *generate_function_name(Oid funcid, int nargs,
531535
List *argnames, Oid *argtypes,
532536
bool has_variadic, bool *use_variadic_p,
@@ -5776,6 +5780,9 @@ get_with_clause(Query *query, deparse_context *context)
57765780
if (query->cteList == NIL)
57775781
return;
57785782

5783+
bool previous_outermost_query = outermost_query;
5784+
outermost_query = false;
5785+
57795786
if (PRETTY_INDENT(context))
57805787
{
57815788
context->indentLevel += PRETTYINDENT_STD;
@@ -5899,6 +5906,8 @@ get_with_clause(Query *query, deparse_context *context)
58995906
}
59005907
else
59015908
appendStringInfoChar(buf, ' ');
5909+
5910+
outermost_query = previous_outermost_query;
59025911
}
59035912

59045913
/* ----------
@@ -6255,12 +6264,23 @@ get_target_list(List *targetList, deparse_context *context)
62556264

62566265
sep = " ";
62576266
colno = 0;
6267+
6268+
StarReconstructionContext star_reconstruction_context = {0};
6269+
star_reconstruction_context.target_list = targetList;
6270+
6271+
bool outermost_targetlist = outermost_query;
6272+
outermost_query = false;
6273+
62586274
foreach(l, targetList)
62596275
{
62606276
TargetEntry *tle = (TargetEntry *) lfirst(l);
62616277
char *colname;
62626278
char *attname;
62636279

6280+
if (pgduckdb_reconstruct_star_step(&star_reconstruction_context, l)) {
6281+
continue;
6282+
}
6283+
62646284
if (tle->resjunk)
62656285
continue; /* ignore junk entries */
62666286

@@ -6285,8 +6305,10 @@ get_target_list(List *targetList, deparse_context *context)
62856305
* directly so that we can tell it to do the right thing, and so that
62866306
* we can get the attribute name which is the default AS label.
62876307
*/
6308+
Var *var = NULL;
62886309
if (tle->expr && (IsA(tle->expr, Var)))
62896310
{
6311+
var = (Var *) tle->expr;
62906312
attname = get_variable((Var *) tle->expr, 0, true, context);
62916313
}
62926314
else
@@ -6313,8 +6335,33 @@ get_target_list(List *targetList, deparse_context *context)
63136335
else
63146336
colname = tle->resname;
63156337

6338+
/*
6339+
* This makes sure we don't add Postgres its bad default alias to the
6340+
* duckdb.row type.
6341+
*/
6342+
bool duckdb_skip_as = pgduckdb_var_is_duckdb_row(var);
6343+
6344+
/*
6345+
* For r['abc'] expressions we don't want the column name to be r, but
6346+
* instead we want it to be "abc". We can only to do this for the
6347+
* target list of the outside most query though to make sure references
6348+
* to the column name are still valid.
6349+
*/
6350+
if (!duckdb_skip_as && outermost_targetlist) {
6351+
Var *subscript_var = pgduckdb_duckdb_subscript_var(tle->expr);
6352+
if (subscript_var) {
6353+
/*
6354+
* This cannot be moved to pgduckdb_ruleutils, because of
6355+
* the reliance on the non-public deparse_namespace type.
6356+
*/
6357+
deparse_namespace* dpns = (deparse_namespace *) list_nth(context->namespaces,
6358+
subscript_var->varlevelsup);
6359+
duckdb_skip_as = !pgduckdb_subscript_has_custom_alias(dpns->plan, dpns->rtable, subscript_var, colname);
6360+
}
6361+
}
6362+
63166363
/* Show AS unless the column's name is correct as-is */
6317-
if (colname) /* resname could be NULL */
6364+
if (colname && !duckdb_skip_as) /* resname could be NULL */
63186365
{
63196366
if (attname == NULL || strcmp(attname, colname) != 0)
63206367
appendStringInfo(&targetbuf, " AS %s", quote_identifier(colname));
@@ -7014,6 +7061,16 @@ get_insert_query_def(Query *query, deparse_context *context)
70147061
if (tle->resjunk)
70157062
continue; /* ignore junk entries */
70167063

7064+
/*
7065+
* If it's an INSERT ... SELECT or multi-row VALUES, the entry
7066+
* with the default value is ignored unless it is specified
7067+
*/
7068+
if (values_rte || select_rte)
7069+
{
7070+
if (!pgduckdb_is_not_default_expr((Node *) tle, NULL))
7071+
continue;
7072+
}
7073+
70177074
appendStringInfoString(buf, sep);
70187075
sep = ", ";
70197076

@@ -7806,6 +7863,11 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
78067863
if (attnum > colinfo->num_cols)
78077864
elog(ERROR, "invalid attnum %d for relation \"%s\"",
78087865
attnum, rte->eref->aliasname);
7866+
7867+
if (pgduckdb_var_is_duckdb_row(var)) {
7868+
return pgduckdb_write_row_refname(context->buf, refname, istoplevel);
7869+
}
7870+
78097871
attname = colinfo->colnames[attnum - 1];
78107872

78117873
/*
@@ -9377,8 +9439,9 @@ get_rule_expr(Node *node, deparse_context *context,
93779439
}
93789440
else
93799441
{
9442+
SubscriptingRef *new_sbsref = pgduckdb_strip_first_subscript(sbsref, context->buf);
93809443
/* Just an ordinary container fetch, so print subscripts */
9381-
printSubscripts(sbsref, context);
9444+
printSubscripts(new_sbsref, context);
93829445
}
93839446
}
93849447
break;
@@ -10774,12 +10837,13 @@ get_oper_expr(OpExpr *expr, deparse_context *context)
1077410837
Node *arg1 = (Node *) linitial(args);
1077510838
Node *arg2 = (Node *) lsecond(args);
1077610839

10840+
char* op_name = generate_operator_name(opno, exprType(arg1), exprType(arg2));
10841+
void* ctx = pg_duckdb_get_oper_expr_make_ctx(op_name, &arg1, &arg2);
10842+
pg_duckdb_get_oper_expr_prefix(buf, ctx);
1077710843
get_rule_expr_paren(arg1, context, true, (Node *) expr);
10778-
appendStringInfo(buf, " %s ",
10779-
generate_operator_name(opno,
10780-
exprType(arg1),
10781-
exprType(arg2)));
10844+
pg_duckdb_get_oper_expr_middle(buf, ctx);
1078210845
get_rule_expr_paren(arg2, context, true, (Node *) expr);
10846+
pg_duckdb_get_oper_expr_suffix(buf, ctx);
1078310847
}
1078410848
else
1078510849
{
@@ -11468,6 +11532,10 @@ get_coercion_expr(Node *arg, deparse_context *context,
1146811532
appendStringInfoChar(buf, ')');
1146911533
}
1147011534

11535+
if (pgduckdb_is_fake_type(resulttype)) {
11536+
return;
11537+
}
11538+
1147111539
/*
1147211540
* Never emit resulttype(arg) functional notation. A pg_proc entry could
1147311541
* take precedence, and a resulttype in pg_temp would require schema
@@ -11503,6 +11571,8 @@ get_const_expr(Const *constval, deparse_context *context, int showtype)
1150311571
char *extval;
1150411572
bool needlabel = false;
1150511573

11574+
showtype = pgduckdb_show_type(constval, showtype);
11575+
1150611576
if (constval->constisnull)
1150711577
{
1150811578
/*
@@ -12421,6 +12491,9 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
1242112491
break;
1242212492
case RTE_SUBQUERY:
1242312493
/* Subquery RTE */
12494+
if (pgduckdb_replace_subquery_with_view(rte->subquery, buf)) {
12495+
break;
12496+
}
1242412497
appendStringInfoChar(buf, '(');
1242512498
get_query_def(rte->subquery, buf, context->namespaces, NULL,
1242612499
true,
@@ -12543,8 +12616,18 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
1254312616
/* Print the relation alias, if needed */
1254412617
get_rte_alias(rte, varno, false, context);
1254512618

12619+
if (pgduckdb_func_returns_duckdb_row(rtfunc1)) {
12620+
/*
12621+
* We never want to print column aliases for functions that return
12622+
* a duckdb.row. The common pattern is for people to not provide an
12623+
* explicit column alias (i.e. "r" becomes "r(r)"). This obviously
12624+
* is a naming collision and DuckDB resolves that in the opposite
12625+
* way that we want. Never adding column aliases for duckdb.row
12626+
* avoids this conflict.
12627+
*/
12628+
}
1254612629
/* Print the column definitions or aliases, if needed */
12547-
if (rtfunc1 && rtfunc1->funccolnames != NIL)
12630+
else if (rtfunc1 && rtfunc1->funccolnames != NIL)
1254812631
{
1254912632
/* Reconstruct the columndef list, which is also the aliases */
1255012633
get_from_clause_coldeflist(rtfunc1, colinfo, context);
@@ -12870,6 +12953,10 @@ get_tablesample_def(TableSampleClause *tablesample, deparse_context *context)
1287012953
if (nargs++ > 0)
1287112954
appendStringInfoString(buf, ", ");
1287212955
get_rule_expr((Node *) lfirst(l), context, false);
12956+
const char *tsm_name = generate_function_name(tablesample->tsmhandler, 1,
12957+
NIL, argtypes,
12958+
false, NULL, EXPR_KIND_NONE);
12959+
pgduckdb_add_tablesample_percent(tsm_name, buf, list_length(tablesample->args));
1287312960
}
1287412961
appendStringInfoChar(buf, ')');
1287512962

@@ -13172,102 +13259,6 @@ get_relation_name(Oid relid)
1317213259
return relname;
1317313260
}
1317413261

13175-
/*
13176-
* generate_relation_name
13177-
* Compute the name to display for a relation specified by OID
13178-
*
13179-
* The result includes all necessary quoting and schema-prefixing.
13180-
*
13181-
* If namespaces isn't NIL, it must be a list of deparse_namespace nodes.
13182-
* We will forcibly qualify the relation name if it equals any CTE name
13183-
* visible in the namespace list.
13184-
*/
13185-
static char *
13186-
generate_relation_name(Oid relid, List *namespaces)
13187-
{
13188-
HeapTuple tp;
13189-
Form_pg_class reltup;
13190-
bool need_qual;
13191-
ListCell *nslist;
13192-
char *relname;
13193-
char *nspname;
13194-
char *result;
13195-
13196-
tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
13197-
if (!HeapTupleIsValid(tp))
13198-
elog(ERROR, "cache lookup failed for relation %u", relid);
13199-
reltup = (Form_pg_class) GETSTRUCT(tp);
13200-
relname = NameStr(reltup->relname);
13201-
13202-
/* Check for conflicting CTE name */
13203-
need_qual = false;
13204-
foreach(nslist, namespaces)
13205-
{
13206-
deparse_namespace *dpns = (deparse_namespace *) lfirst(nslist);
13207-
ListCell *ctlist;
13208-
13209-
foreach(ctlist, dpns->ctes)
13210-
{
13211-
CommonTableExpr *cte = (CommonTableExpr *) lfirst(ctlist);
13212-
13213-
if (strcmp(cte->ctename, relname) == 0)
13214-
{
13215-
need_qual = true;
13216-
break;
13217-
}
13218-
}
13219-
if (need_qual)
13220-
break;
13221-
}
13222-
13223-
/* Otherwise, qualify the name if not visible in search path */
13224-
if (!need_qual)
13225-
need_qual = !RelationIsVisible(relid);
13226-
13227-
if (need_qual)
13228-
nspname = get_namespace_name_or_temp(reltup->relnamespace);
13229-
else
13230-
nspname = NULL;
13231-
13232-
result = quote_qualified_identifier(nspname, relname);
13233-
13234-
ReleaseSysCache(tp);
13235-
13236-
return result;
13237-
}
13238-
13239-
/*
13240-
* generate_qualified_relation_name
13241-
* Compute the name to display for a relation specified by OID
13242-
*
13243-
* As above, but unconditionally schema-qualify the name.
13244-
*/
13245-
static char *
13246-
generate_qualified_relation_name(Oid relid)
13247-
{
13248-
HeapTuple tp;
13249-
Form_pg_class reltup;
13250-
char *relname;
13251-
char *nspname;
13252-
char *result;
13253-
13254-
tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
13255-
if (!HeapTupleIsValid(tp))
13256-
elog(ERROR, "cache lookup failed for relation %u", relid);
13257-
reltup = (Form_pg_class) GETSTRUCT(tp);
13258-
relname = NameStr(reltup->relname);
13259-
13260-
nspname = get_namespace_name_or_temp(reltup->relnamespace);
13261-
if (!nspname)
13262-
elog(ERROR, "cache lookup failed for namespace %u",
13263-
reltup->relnamespace);
13264-
13265-
result = quote_qualified_identifier(nspname, relname);
13266-
13267-
ReleaseSysCache(tp);
13268-
13269-
return result;
13270-
}
1327113262

1327213263
/*
1327313264
* generate_function_name
@@ -13307,6 +13298,10 @@ generate_function_name(Oid funcid, int nargs, List *argnames, Oid *argtypes,
1330713298
Oid *p_true_typeids;
1330813299
bool force_qualify = false;
1330913300

13301+
result = pgduckdb_function_name(funcid, use_variadic_p);
13302+
if (result)
13303+
return result;
13304+
1331013305
proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
1331113306
if (!HeapTupleIsValid(proctup))
1331213307
elog(ERROR, "cache lookup failed for function %u", funcid);
@@ -13743,3 +13738,5 @@ get_range_partbound_string(List *bound_datums)
1374313738

1374413739
return buf.data;
1374513740
}
13741+
13742+
#endif

0 commit comments

Comments
 (0)