public inbox for [email protected]
help / color / mirror / Atom feed[PATCH 1/3] bootstrap: convert Typ to a List*
3+ messages / 3 participants
[nested] [flat]
* [PATCH 1/3] bootstrap: convert Typ to a List*
@ 2020-11-20 02:48 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 3+ messages in thread
From: Justin Pryzby @ 2020-11-20 02:48 UTC (permalink / raw)
---
src/backend/bootstrap/bootstrap.c | 69 ++++++++++++++-----------------
1 file changed, 31 insertions(+), 38 deletions(-)
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 6f615e6622..18eb62ca47 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -159,7 +159,7 @@ struct typmap
FormData_pg_type am_typ;
};
-static struct typmap **Typ = NULL;
+static List *Typ = NIL; /* List of struct typmap* */
static struct typmap *Ap = NULL;
static Datum values[MAXATTR]; /* current row's attribute values */
@@ -597,7 +597,7 @@ boot_openrel(char *relname)
* pg_type must be filled before any OPEN command is executed, hence we
* can now populate the Typ array if we haven't yet.
*/
- if (Typ == NULL)
+ if (Typ == NIL)
populate_typ_array();
if (boot_reldesc != NULL)
@@ -688,7 +688,7 @@ DefineAttr(char *name, char *type, int attnum, int nullness)
typeoid = gettype(type);
- if (Typ != NULL)
+ if (Typ != NIL)
{
attrtypes[attnum]->atttypid = Ap->am_oid;
attrtypes[attnum]->attlen = Ap->am_typ.typlen;
@@ -877,36 +877,25 @@ populate_typ_array(void)
Relation rel;
TableScanDesc scan;
HeapTuple tup;
- int nalloc;
- int i;
-
- Assert(Typ == NULL);
- nalloc = 512;
- Typ = (struct typmap **)
- MemoryContextAlloc(TopMemoryContext, nalloc * sizeof(struct typmap *));
+ Assert(Typ == NIL);
rel = table_open(TypeRelationId, NoLock);
scan = table_beginscan_catalog(rel, 0, NULL);
- i = 0;
while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL)
{
Form_pg_type typForm = (Form_pg_type) GETSTRUCT(tup);
+ struct typmap *newtyp;
+ MemoryContext old;
- /* make sure there will be room for a trailing NULL pointer */
- if (i >= nalloc - 1)
- {
- nalloc *= 2;
- Typ = (struct typmap **)
- repalloc(Typ, nalloc * sizeof(struct typmap *));
- }
- Typ[i] = (struct typmap *)
- MemoryContextAlloc(TopMemoryContext, sizeof(struct typmap));
- Typ[i]->am_oid = typForm->oid;
- memcpy(&(Typ[i]->am_typ), typForm, sizeof(Typ[i]->am_typ));
- i++;
+ old = MemoryContextSwitchTo(TopMemoryContext);
+ newtyp = (struct typmap *) palloc(sizeof(struct typmap));
+ Typ = lappend(Typ, newtyp);
+ MemoryContextSwitchTo(old);
+
+ newtyp->am_oid = typForm->oid;
+ memcpy(&newtyp->am_typ, typForm, sizeof(newtyp->am_typ));
}
- Typ[i] = NULL; /* Fill trailing NULL pointer */
table_endscan(scan);
table_close(rel, NoLock);
}
@@ -925,16 +914,17 @@ populate_typ_array(void)
static Oid
gettype(char *type)
{
- if (Typ != NULL)
+ if (Typ != NIL)
{
- struct typmap **app;
+ ListCell *lc;
- for (app = Typ; *app != NULL; app++)
+ foreach (lc, Typ)
{
- if (strncmp(NameStr((*app)->am_typ.typname), type, NAMEDATALEN) == 0)
+ struct typmap *app = lfirst(lc);
+ if (strncmp(NameStr(app->am_typ.typname), type, NAMEDATALEN) == 0)
{
- Ap = *app;
- return (*app)->am_oid;
+ Ap = app;
+ return app->am_oid;
}
}
}
@@ -980,14 +970,17 @@ boot_get_type_io_data(Oid typid,
if (Typ != NULL)
{
/* We have the boot-time contents of pg_type, so use it */
- struct typmap **app;
- struct typmap *ap;
-
- app = Typ;
- while (*app && (*app)->am_oid != typid)
- ++app;
- ap = *app;
- if (ap == NULL)
+ struct typmap *ap = NULL;
+ ListCell *lc;
+
+ foreach (lc, Typ)
+ {
+ ap = lfirst(lc);
+ if (ap->am_oid == typid)
+ break;
+ }
+
+ if (!ap || ap->am_oid != typid)
elog(ERROR, "type OID %u not found in Typ list", typid);
*typlen = ap->am_typ.typlen;
--
2.26.2
--------------1F4A19FEB5D90C72707AFA7B
Content-Type: text/x-patch; charset=UTF-8;
name="0002-Allow-composite-types-in-bootstrap-20210122.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="0002-Allow-composite-types-in-bootstrap-20210122.patch"
^ permalink raw reply [nested|flat] 3+ messages in thread
* EphemeralNamedRelation and materialized view
@ 2024-07-26 07:07 Yugo Nagata <[email protected]>
2024-11-03 18:42 ` Re: EphemeralNamedRelation and materialized view Tom Lane <[email protected]>
0 siblings, 1 reply; 3+ messages in thread
From: Yugo Nagata @ 2024-07-26 07:07 UTC (permalink / raw)
To: pgsql-hackers
Hi,
While looking into the commit b4da732fd64e936970f38c792f8b32c4bdf2bcd5,
I noticed that we can create a materialized view using Ephemeral Named
Relation in PostgreSQL 16 or earler.
postgres=# create table tbl (i int);
CREATE TABLE
^
postgres=# create or replace function f() returns trigger as $$ begin
create materialized view mv as select * from enr; return new; end; $$ language plpgsql;
CREATE FUNCTION
postgres=# create trigger trig after insert on tbl referencing new table as enr execute function f();
CREATE TRIGGER
postgres=# insert into tbl values (10);
postgres=# \d
List of relations
Schema | Name | Type | Owner
--------+------+-------------------+--------
public | mv | materialized view | yugo-n
public | tbl | table | yugo-n
(2 rows)
We cannot refresh or get the deinition of it, though.
postgres=# refresh materialized view mv;
ERROR: executor could not find named tuplestore "enr"
postgres=# \d+ mv
ERROR: unrecognized RTE kind: 7
In PostgreSQL 17, materialized view using ENR cannot be created
because queryEnv is not pass to RefreshMatViewByOid introduced by b4da732fd64.
When we try to create it, the error is raised.
ERROR: executor could not find named tuplestore "enr"
Although it is hard to imagine users actually try to create materialized view
using ENR, how about prohibiting it even in PG16 or earlier by passing NULL
as queryEnv arg in CreateQueryDesc to avoid to create useless matviews accidentally,
as the attached patch?
Regards,
Yugo Nagata
--
Yugo Nagata <[email protected]>
Attachments:
[text/x-diff] prohibit_use_enr_in_matview.patch (664B, ../../[email protected]/2-prohibit_use_enr_in_matview.patch)
download | inline diff:
diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c
index e91920ca14..fda1e4d92b 100644
--- a/src/backend/commands/createas.c
+++ b/src/backend/commands/createas.c
@@ -327,7 +327,7 @@ ExecCreateTableAs(ParseState *pstate, CreateTableAsStmt *stmt,
/* Create a QueryDesc, redirecting output to our tuple receiver */
queryDesc = CreateQueryDesc(plan, pstate->p_sourcetext,
GetActiveSnapshot(), InvalidSnapshot,
- dest, params, queryEnv, 0);
+ dest, params, is_matview ? NULL : queryEnv, 0);
/* call ExecutorStart to prepare the plan for execution */
ExecutorStart(queryDesc, GetIntoRelEFlags(into));
^ permalink raw reply [nested|flat] 3+ messages in thread
* Re: EphemeralNamedRelation and materialized view
2024-07-26 07:07 EphemeralNamedRelation and materialized view Yugo Nagata <[email protected]>
@ 2024-11-03 18:42 ` Tom Lane <[email protected]>
0 siblings, 0 replies; 3+ messages in thread
From: Tom Lane @ 2024-11-03 18:42 UTC (permalink / raw)
To: Yugo Nagata <[email protected]>; +Cc: pgsql-hackers
Yugo Nagata <[email protected]> writes:
> While looking into the commit b4da732fd64e936970f38c792f8b32c4bdf2bcd5,
> I noticed that we can create a materialized view using Ephemeral Named
> Relation in PostgreSQL 16 or earler.
Yeah, we should reject that, but I feel like this patch is not
ambitious enough, because the 17-and-up behavior isn't exactly
polished either.
I tried variants of this function in HEAD:
1. With "create table mv as select * from enr", it works and
does what you'd expect.
2. With "create view mv as select * from enr", you get
regression=# insert into tbl values (10);
ERROR: relation "enr" does not exist
LINE 1: create view mv as select * from enr
^
QUERY: create view mv as select * from enr
CONTEXT: PL/pgSQL function f() line 2 at SQL statement
regression=# \errverbose
ERROR: 42P01: relation "enr" does not exist
LINE 1: create view mv as select * from enr
^
QUERY: create view mv as select * from enr
CONTEXT: PL/pgSQL function f() line 2 at SQL statement
LOCATION: parserOpenTable, parse_relation.c:1452
3. With "create materialized view ..." you get
regression=# insert into tbl values (10);
ERROR: executor could not find named tuplestore "enr"
CONTEXT: SQL statement "create materialized view mv as select * from enr"
PL/pgSQL function f() line 2 at SQL statement
regression=# \errverbose
ERROR: XX000: executor could not find named tuplestore "enr"
CONTEXT: SQL statement "create materialized view mv as select * from enr"
PL/pgSQL function f() line 2 at SQL statement
LOCATION: ExecInitNamedTuplestoreScan, nodeNamedtuplestorescan.c:107
I don't think hitting an internal error is good enough.
Why doesn't this case act like case 2?
You could even argue that case 2 isn't good enough either,
and we should be delivering a specific error message saying
that an ENR can't be used in a view/matview. To do that,
we'd likely need to pass down the QueryEnvironment in more
places not fewer.
regards, tom lane
^ permalink raw reply [nested|flat] 3+ messages in thread
end of thread, other threads:[~2024-11-03 18:42 UTC | newest]
Thread overview: 3+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2020-11-20 02:48 [PATCH 1/3] bootstrap: convert Typ to a List* Justin Pryzby <[email protected]>
2024-07-26 07:07 EphemeralNamedRelation and materialized view Yugo Nagata <[email protected]>
2024-11-03 18:42 ` Re: EphemeralNamedRelation and materialized view Tom Lane <[email protected]>
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox