-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add PostgresViewEntry #183
base: main
Are you sure you want to change the base?
Conversation
public: | ||
PostgresViewInfo() { | ||
create_info = make_uniq<CreateViewInfo>(); | ||
// create_info->columns.SetAllowDuplicates(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about this, the Table has a ColumnsList which provides this option, but no such option exists for views because we don't have a ColumnsList, we instead just store the types+names separately
This is lacking testing still, and there are probably virtual methods that need to be overridden |
The failure is probably related to: statement ok
CREATE VIEW s1.v1 AS SELECT 42 as j Our error check is probably not a fan of this, because there is no existing table to reference Or actually.. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you merge with main? Also one minor comment:
: ViewCatalogEntry(catalog, schema, *info.create_info), postgres_types(std::move(info.postgres_types)), | ||
postgres_names(std::move(info.postgres_names)) { | ||
D_ASSERT(postgres_types.size() == types.size()); | ||
approx_num_pages = info.approx_num_pages; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
approx_num_pages
should be 0 for a view always (or rather it probably shouldn't be a property at all?) - we use this to partition base tables but that is not possible for views
@Mytherin This seems like a problem, I can't really find the reason for this behavior
I've had to replace the CreateViewInfo names with the expression.ToString() if the name was "?column?", this seems to have this effect |
The fact that we are getting two different names (one from Postgres', one from DuckDB') indicates to me we are binding the same query both in Postgres and in DuckDB. That seems like a more fundamental problem to me. After all - if a view contains anything that DuckDB does not support, the binding in DuckDB will fail, whereas we should still be able to query the view. Maybe we could try e.g. not pulling the SQL definition of the view into DuckDB so the binding is avoided? |
An example of a view that works in Postgres but wouldn't work in DuckDB might be: create table my_table(i int);
create view my_view as select ctid from my_table; |
You're right, that doesn't work That's another issue we can solve by turning the columns into separate catalog entries, we could add default entries for things like |
The problem with this lies in (also setting the query to nullptr causes an InternalException here currently because this path assumes the query is always present) |
The problem here is that we first bind the view's query before we hand it off to postgres, so we have to be able to bind it ourselves (possibly delegating to the postgres catalog extension) Then we create the entry in the postgres catalog, running the same query, then reloading to get the entry as it was created in postgres. Then in our verification step inside Bind(BaseTableRef &ref) we bind the query again on duckdb's side, which produces a different name for the column. The "skip view content verification if One solution there might be decompose the TableCatalogEntry into a catalog set containing columns, and using a DefaultGenerator to create the system columns A more generic approach that will likely take the least effort is to add a virtual method on the table catalog entry for column retrieval, so we can hook in and return a column definition for "ctid" and friends, basically a poor mans "DefaultColumnGenerator" The last idea to make this work is take a similar approach as |
We're likely going to have to separate out the SelectStatement inside the CreateViewInfo, then construct a postgres query from that, get the names + types from the PGresult object, and convert the type into a LogicalType
That gets us the Oid, then we can run another query to retrieve the information we need to transform PG -> LogicalType One downside of this is that we have to actually execute the query to get the names+types |
In the table query we get both tables, views, materialized views, partitioned tables and foreign tables.
The views are then stored in the catalog as a TableCatalogEntry, which confuses
duckdb_tables()
andduckdb_views()
which is used insideinformation_schema.tables
So the views showed up as tables, this PR fixes that and adds a test for it
Notable change:
In postgres, when views are created on a dummy binding, with no aliases, their resulting alias becomes
"?column?"
:As a result, our binding will fail because the names don't match.
To get around this, we don't save the entry as "?column?" but instead use the name that DuckDB would attribute to the expression