Skip to content

Commit

Permalink
Move duckdb.row refname generation to pgduckdb_ruleutils.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
JelteF committed Jan 21, 2025
1 parent 221343f commit 7153893
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 28 deletions.
1 change: 1 addition & 0 deletions include/pgduckdb/pgduckdb_ruleutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@ bool pgduckdb_function_needs_subquery(Oid function_oid);
int pgduckdb_show_type(Const *constval, int original_showtype);
bool pgduckdb_subscript_has_custom_alias(Plan *plan, List *rtable, Var *subscript_var, char *colname);
SubscriptingRef *pgduckdb_strip_first_subscript(SubscriptingRef *sbsref, StringInfo buf);
char *pgduckdb_write_row_refname(StringInfo buf, char *refname, bool is_top_level);

extern bool processed_targetlist;
28 changes: 28 additions & 0 deletions src/pgduckdb_ruleutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,34 @@ pgduckdb_strip_first_subscript(SubscriptingRef *sbsref, StringInfo buf) {
return shorter_sbsref;
}

/*
* Writes the refname to the buf in a way that results in the correct output
* for the duckdb.row type.
*
* Returns the "attname" that should be passed back to the caller.
*/
char *
pgduckdb_write_row_refname(StringInfo buf, char *refname, bool is_top_level) {
appendStringInfoString(buf, quote_identifier(refname));

if (is_top_level) {
/*
* If the duckdb.row is at the top level target list of a select, then
* we want to generate r.*, to unpack all the columns instead of
* returning a STRUCT from the query.
*
* Since we use .* there is no attname.
*/
appendStringInfoString(buf, ".*");
return NULL;
}

/*
* In any other case, we want to simply use the alias of the TargetEntry.
*/
return refname;
}

/*
* Given a postgres schema name, this returns a list of two elements: the first
* is the DuckDB database name and the second is the duckdb schema name. These
Expand Down
43 changes: 15 additions & 28 deletions src/vendor/pg_ruleutils_17.c
Original file line number Diff line number Diff line change
Expand Up @@ -7542,35 +7542,22 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
if (attnum > colinfo->num_cols)
elog(ERROR, "invalid attnum %d for relation \"%s\"",
attnum, rte->eref->aliasname);
if (pgduckdb_var_is_duckdb_row(var)) {
if (istoplevel) {
/* If the duckdb row is at the top level target list of a
* select, then we want to generate r.*, to unpack all the
* columns instead of returning a STRUCT from the query. */
attname = NULL;
} else {
/* In any other case, we want to simply use the alias of the
* TargetEntry, without the column name that postgres gave to
* it. Because even though according to the Postgres parser we
* are referencing a column of type "duckdb.row", that column
* won't actually exist in the DuckDB query.
*/
attname = refname;
refname = NULL;
}
} else {
attname = colinfo->colnames[attnum - 1];

/*
* If we find a Var referencing a dropped column, it seems better to
* print something (anything) than to fail. In general this should
* not happen, but it used to be possible for some cases involving
* functions returning named composite types, and perhaps there are
* still bugs out there.
*/
if (attname == NULL)
attname = "?dropped?column?";
if (pgduckdb_var_is_duckdb_row(var)) {
return pgduckdb_write_row_refname(context->buf, refname, istoplevel);
}

attname = colinfo->colnames[attnum - 1];

/*
* If we find a Var referencing a dropped column, it seems better to
* print something (anything) than to fail. In general this should
* not happen, but it used to be possible for some cases involving
* functions returning named composite types, and perhaps there are
* still bugs out there.
*/
if (attname == NULL)
attname = "?dropped?column?";
}
else
{
Expand All @@ -7588,7 +7575,7 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
else
{
appendStringInfoChar(buf, '*');
if (istoplevel && !pgduckdb_var_is_duckdb_row(var))
if (istoplevel)
appendStringInfo(buf, "::%s",
format_type_with_typemod(var->vartype,
var->vartypmod));
Expand Down

0 comments on commit 7153893

Please sign in to comment.