Age Owner TLA Line data Source code
1 : %{
2 : /*-------------------------------------------------------------------------
3 : *
4 : * bootparse.y
5 : * yacc grammar for the "bootstrap" mode (BKI file format)
6 : *
7 : * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
8 : * Portions Copyright (c) 1994, Regents of the University of California
9 : *
10 : *
11 : * IDENTIFICATION
12 : * src/backend/bootstrap/bootparse.y
13 : *
14 : *-------------------------------------------------------------------------
15 : */
16 :
17 : #include "postgres.h"
18 :
19 : #include <unistd.h>
20 :
21 : #include "bootstrap/bootstrap.h"
22 : #include "catalog/heap.h"
23 : #include "catalog/namespace.h"
24 : #include "catalog/pg_am.h"
25 : #include "catalog/pg_authid.h"
26 : #include "catalog/pg_class.h"
27 : #include "catalog/pg_namespace.h"
28 : #include "catalog/pg_tablespace.h"
29 : #include "catalog/toasting.h"
30 : #include "commands/defrem.h"
31 : #include "miscadmin.h"
32 : #include "nodes/makefuncs.h"
33 : #include "utils/memutils.h"
34 :
35 :
36 : /*
37 : * Bison doesn't allocate anything that needs to live across parser calls,
38 : * so we can easily have it use palloc instead of malloc. This prevents
39 : * memory leaks if we error out during parsing.
40 : */
41 : #define YYMALLOC palloc
42 : #define YYFREE pfree
43 :
2186 tgl 44 ECB : static MemoryContext per_line_ctx = NULL;
45 :
8002 peter_e 46 : static void
6755 neilc 47 GIC 3341580 : do_start(void)
8002 peter_e 48 ECB : {
2186 tgl 49 CBC 3341580 : Assert(CurrentMemoryContext == CurTransactionContext);
50 : /* First time through, create the per-line working context */
2186 tgl 51 GIC 3341580 : if (per_line_ctx == NULL)
2186 tgl 52 CBC 305 : per_line_ctx = AllocSetContextCreate(CurTransactionContext,
2186 tgl 53 ECB : "bootstrap per-line processing",
54 : ALLOCSET_DEFAULT_SIZES);
2186 tgl 55 GIC 3341580 : MemoryContextSwitchTo(per_line_ctx);
8002 peter_e 56 3341580 : }
8002 peter_e 57 ECB :
58 :
59 : static void
6755 neilc 60 CBC 3341580 : do_end(void)
8002 peter_e 61 ECB : {
2186 tgl 62 : /* Reclaim memory allocated while processing this line */
2186 tgl 63 CBC 3341580 : MemoryContextSwitchTo(CurTransactionContext);
2186 tgl 64 GIC 3341580 : MemoryContextReset(per_line_ctx);
7086 tgl 65 GBC 3341580 : CHECK_FOR_INTERRUPTS(); /* allow SIGINT to kill bootstrap run */
8002 peter_e 66 3341580 : if (isatty(0))
67 : {
8002 peter_e 68 LBC 0 : printf("bootstrap> ");
8002 peter_e 69 UIC 0 : fflush(stdout);
70 : }
8002 peter_e 71 GIC 3341580 : }
72 :
73 :
74 : static int num_columns_read = 0;
75 :
76 : %}
77 :
78 : %expect 0
79 : %name-prefix="boot_yy"
80 :
81 : %union
82 : {
83 : List *list;
84 : IndexElem *ielem;
85 : char *str;
86 : const char *kw;
87 : int ival;
88 : Oid oidval;
89 : }
90 :
91 : %type <list> boot_index_params
92 : %type <ielem> boot_index_param
93 : %type <str> boot_ident
94 : %type <ival> optbootstrap optsharedrelation boot_column_nullness
95 : %type <oidval> oidspec optrowtypeoid
96 :
97 : %token <str> ID
98 : %token COMMA EQUALS LPAREN RPAREN
99 : /* NULLVAL is a reserved keyword */
100 : %token NULLVAL
101 : /* All the rest are unreserved, and should be handled in boot_ident! */
102 : %token <kw> OPEN XCLOSE XCREATE INSERT_TUPLE
103 : %token <kw> XDECLARE INDEX ON USING XBUILD INDICES UNIQUE XTOAST
104 : %token <kw> OBJ_ID XBOOTSTRAP XSHARED_RELATION XROWTYPE_OID
105 : %token <kw> XFORCE XNOT XNULL
106 :
107 : %start TopLevel
108 :
109 : %%
110 :
111 : TopLevel:
112 : Boot_Queries
113 : |
114 : ;
115 :
116 : Boot_Queries:
117 : Boot_Query
118 : | Boot_Queries Boot_Query
119 : ;
120 :
121 : Boot_Query :
122 : Boot_OpenStmt
123 : | Boot_CloseStmt
124 : | Boot_CreateStmt
125 : | Boot_InsertStmt
126 : | Boot_DeclareIndexStmt
127 : | Boot_DeclareUniqueIndexStmt
128 : | Boot_DeclareToastStmt
129 : | Boot_BuildIndsStmt
130 : ;
131 :
9224 bruce 132 ECB : Boot_OpenStmt:
133 : OPEN boot_ident
9344 134 : {
8002 peter_e 135 GIC 18300 : do_start();
4942 tgl 136 18300 : boot_openrel($2);
8002 peter_e 137 18300 : do_end();
138 : }
139 : ;
140 :
9224 bruce 141 ECB : Boot_CloseStmt:
1800 tgl 142 : XCLOSE boot_ident
9344 bruce 143 : {
8002 peter_e 144 GIC 19520 : do_start();
4942 tgl 145 19520 : closerel($2);
8002 peter_e 146 19520 : do_end();
147 : }
148 : ;
149 :
9224 bruce 150 ECB : Boot_CreateStmt:
1601 andres 151 : XCREATE boot_ident oidspec optbootstrap optsharedrelation optrowtypeoid LPAREN
9344 bruce 152 : {
8002 peter_e 153 GIC 19520 : do_start();
154 19520 : numattr = 0;
6569 tgl 155 19520 : elog(DEBUG4, "creating%s%s relation %s %u",
156 : $4 ? " bootstrap" : "",
157 : $5 ? " shared" : "",
158 : $2,
159 : $3);
9344 bruce 160 ECB : }
161 : boot_column_list
162 : {
8002 peter_e 163 GIC 19520 : do_end();
164 : }
165 : RPAREN
166 : {
167 : TupleDesc tupdesc;
331 peter 168 ECB : bool shared_relation;
169 : bool mapped_relation;
7524 tgl 170 :
8002 peter_e 171 GIC 19520 : do_start();
9344 bruce 172 ECB :
1601 andres 173 GIC 19520 : tupdesc = CreateTupleDesc(numattr, attrtypes);
174 :
4809 tgl 175 19520 : shared_relation = $5;
176 :
177 : /*
178 : * The catalogs that use the relation mapper are the
179 : * bootstrap catalogs plus the shared catalogs. If this
180 : * ever gets more complicated, we should invent a BKI
181 : * keyword to mark the mapped catalogs, but for now a
182 : * quick hack seems the most appropriate thing. Note in
4809 tgl 183 ECB : * particular that all "nailed" heap rels (see formrdesc
184 : * in relcache.c) must be mapped.
185 : */
4809 tgl 186 GIC 19520 : mapped_relation = ($4 || shared_relation);
187 :
4943 188 19520 : if ($4)
189 : {
1473 andres 190 ECB : TransactionId relfrozenxid;
191 : MultiXactId relminmxid;
1473 andres 192 EUB :
7652 tgl 193 GBC 1220 : if (boot_reldesc)
194 : {
7257 bruce 195 UIC 0 : elog(DEBUG4, "create bootstrap: warning, open relation exists, closing first");
9344 bruce 196 LBC 0 : closerel(NULL);
197 : }
198 :
4942 tgl 199 CBC 1220 : boot_reldesc = heap_create($2,
200 : PG_CATALOG_NAMESPACE,
201 : shared_relation ? GLOBALTABLESPACE_OID : 0,
4943 tgl 202 GIC 1220 : $3,
203 : InvalidOid,
204 : HEAP_TABLE_AM_OID,
205 : tupdesc,
206 : RELKIND_RELATION,
207 : RELPERSISTENCE_PERMANENT,
208 : shared_relation,
209 : mapped_relation,
210 : true,
1473 andres 211 ECB : &relfrozenxid,
212 : &relminmxid,
213 : true);
7257 bruce 214 GIC 1220 : elog(DEBUG4, "bootstrap relation created");
215 : }
216 : else
9344 bruce 217 ECB : {
218 : Oid id;
219 :
4942 tgl 220 CBC 18300 : id = heap_create_with_catalog($2,
7684 tgl 221 ECB : PG_CATALOG_NAMESPACE,
222 : shared_relation ? GLOBALTABLESPACE_OID : 0,
4943 tgl 223 GIC 18300 : $3,
1601 andres 224 18300 : $6,
225 : InvalidOid,
226 : BOOTSTRAP_SUPERUSERID,
227 : HEAP_TABLE_AM_OID,
228 : tupdesc,
229 : NIL,
230 : RELKIND_RELATION,
231 : RELPERSISTENCE_PERMANENT,
232 : shared_relation,
233 : mapped_relation,
234 : ONCOMMIT_NOOP,
235 : (Datum) 0,
236 : false,
237 : true,
2959 alvherre 238 ECB : false,
239 : InvalidOid,
240 : NULL);
4312 peter_e 241 GIC 18300 : elog(DEBUG4, "relation created with OID %u", id);
242 : }
8002 243 19520 : do_end();
244 : }
245 : ;
246 :
9224 bruce 247 ECB : Boot_InsertStmt:
1601 andres 248 : INSERT_TUPLE
9344 bruce 249 : {
8002 peter_e 250 GIC 3215615 : do_start();
1601 andres 251 3215615 : elog(DEBUG4, "inserting row");
8002 peter_e 252 3215615 : num_columns_read = 0;
9344 bruce 253 ECB : }
4942 tgl 254 EUB : LPAREN boot_column_val_list RPAREN
255 : {
8002 peter_e 256 CBC 3215615 : if (num_columns_read != numattr)
8002 peter_e 257 UBC 0 : elog(ERROR, "incorrect number of columns in row (expected %d, got %d)",
8002 peter_e 258 ECB : numattr, num_columns_read);
7032 neilc 259 CBC 3215615 : if (boot_reldesc == NULL)
5877 alvherre 260 UIC 0 : elog(FATAL, "relation not open");
1601 andres 261 GIC 3215615 : InsertOneTuple();
8002 peter_e 262 3215615 : do_end();
263 : }
264 : ;
265 :
9224 bruce 266 ECB : Boot_DeclareIndexStmt:
267 : XDECLARE INDEX boot_ident oidspec ON boot_ident USING boot_ident LPAREN boot_index_params RPAREN
268 : {
331 peter 269 CBC 4270 : IndexStmt *stmt = makeNode(IndexStmt);
270 : Oid relationId;
3919 tgl 271 ECB :
1859 alvherre 272 GIC 4270 : elog(DEBUG4, "creating index \"%s\"", $3);
1859 alvherre 273 ECB :
8002 peter_e 274 CBC 4270 : do_start();
9770 scrappy 275 ECB :
3919 tgl 276 CBC 4270 : stmt->idxname = $3;
277 4270 : stmt->relation = makeRangeVar(NULL, $6, -1);
278 4270 : stmt->accessMethod = $8;
279 4270 : stmt->tableSpace = NULL;
280 4270 : stmt->indexParams = $10;
1828 teodor 281 4270 : stmt->indexIncludingParams = NIL;
3919 tgl 282 4270 : stmt->options = NIL;
283 4270 : stmt->whereClause = NULL;
284 4270 : stmt->excludeOpNames = NIL;
285 4270 : stmt->idxcomment = NULL;
286 4270 : stmt->indexOid = InvalidOid;
277 rhaas 287 GNC 4270 : stmt->oldNumber = InvalidRelFileNumber;
1100 noah 288 CBC 4270 : stmt->oldCreateSubid = InvalidSubTransactionId;
277 rhaas 289 GNC 4270 : stmt->oldFirstRelfilelocatorSubid = InvalidSubTransactionId;
3919 tgl 290 CBC 4270 : stmt->unique = false;
291 4270 : stmt->primary = false;
292 4270 : stmt->isconstraint = false;
293 4270 : stmt->deferrable = false;
294 4270 : stmt->initdeferred = false;
2968 295 4270 : stmt->transformed = false;
3919 tgl 296 GIC 4270 : stmt->concurrent = false;
2968 297 4270 : stmt->if_not_exists = false;
1445 alvherre 298 CBC 4270 : stmt->reset_default_tblspc = false;
299 :
300 : /* locks and races need not concern us in bootstrap mode */
3338 rhaas 301 4270 : relationId = RangeVarGetRelid(stmt->relation, NoLock,
302 : false);
3338 rhaas 303 ECB :
3338 rhaas 304 GIC 4270 : DefineIndex(relationId,
305 : stmt,
6569 tgl 306 4270 : $4,
307 : InvalidOid,
308 : InvalidOid,
309 : -1,
310 : false,
311 : false,
312 : false,
3919 tgl 313 ECB : true, /* skip_build */
314 : false);
8002 peter_e 315 GIC 4270 : do_end();
316 : }
317 : ;
318 :
319 : Boot_DeclareUniqueIndexStmt:
6569 tgl 320 ECB : XDECLARE UNIQUE INDEX boot_ident oidspec ON boot_ident USING boot_ident LPAREN boot_index_params RPAREN
321 : {
331 peter 322 GIC 33550 : IndexStmt *stmt = makeNode(IndexStmt);
331 peter 323 ECB : Oid relationId;
324 :
1859 alvherre 325 CBC 33550 : elog(DEBUG4, "creating unique index \"%s\"", $4);
326 :
8002 peter_e 327 33550 : do_start();
8557 inoue 328 ECB :
3919 tgl 329 CBC 33550 : stmt->idxname = $4;
330 33550 : stmt->relation = makeRangeVar(NULL, $7, -1);
331 33550 : stmt->accessMethod = $9;
332 33550 : stmt->tableSpace = NULL;
333 33550 : stmt->indexParams = $11;
1828 teodor 334 33550 : stmt->indexIncludingParams = NIL;
3919 tgl 335 33550 : stmt->options = NIL;
336 33550 : stmt->whereClause = NULL;
337 33550 : stmt->excludeOpNames = NIL;
338 33550 : stmt->idxcomment = NULL;
339 33550 : stmt->indexOid = InvalidOid;
277 rhaas 340 GNC 33550 : stmt->oldNumber = InvalidRelFileNumber;
1100 noah 341 CBC 33550 : stmt->oldCreateSubid = InvalidSubTransactionId;
277 rhaas 342 GNC 33550 : stmt->oldFirstRelfilelocatorSubid = InvalidSubTransactionId;
3919 tgl 343 CBC 33550 : stmt->unique = true;
344 33550 : stmt->primary = false;
345 33550 : stmt->isconstraint = false;
346 33550 : stmt->deferrable = false;
347 33550 : stmt->initdeferred = false;
2968 348 33550 : stmt->transformed = false;
3919 349 33550 : stmt->concurrent = false;
2968 tgl 350 GIC 33550 : stmt->if_not_exists = false;
1445 alvherre 351 33550 : stmt->reset_default_tblspc = false;
3919 tgl 352 ECB :
353 : /* locks and races need not concern us in bootstrap mode */
3338 rhaas 354 GIC 33550 : relationId = RangeVarGetRelid(stmt->relation, NoLock,
3338 rhaas 355 ECB : false);
356 :
3338 rhaas 357 CBC 33550 : DefineIndex(relationId,
358 : stmt,
6569 tgl 359 GIC 33550 : $5,
360 : InvalidOid,
361 : InvalidOid,
362 : -1,
363 : false,
364 : false,
365 : false,
366 : true, /* skip_build */
3919 tgl 367 ECB : false);
8002 peter_e 368 GIC 33550 : do_end();
369 : }
370 : ;
371 :
372 : Boot_DeclareToastStmt:
373 : XDECLARE XTOAST oidspec oidspec ON boot_ident
6096 tgl 374 ECB : {
1859 alvherre 375 GIC 10980 : elog(DEBUG4, "creating toast table for table \"%s\"", $6);
1859 alvherre 376 ECB :
6096 tgl 377 GIC 10980 : do_start();
6096 tgl 378 ECB :
4942 tgl 379 CBC 10980 : BootstrapToastTable($6, $3, $4);
6096 tgl 380 GIC 10980 : do_end();
381 : }
382 : ;
383 :
384 : Boot_BuildIndsStmt:
385 : XBUILD INDICES
6840 tgl 386 ECB : {
6840 tgl 387 CBC 305 : do_start();
388 305 : build_indices();
6840 tgl 389 GIC 305 : do_end();
390 : }
391 : ;
392 :
393 :
9224 bruce 394 ECB : boot_index_params:
8999 bruce 395 CBC 24705 : boot_index_params COMMA boot_index_param { $$ = lappend($1, $3); }
6892 neilc 396 GIC 37820 : | boot_index_param { $$ = list_make1($1); }
397 : ;
398 :
399 : boot_index_param:
400 : boot_ident boot_ident
9344 bruce 401 ECB : {
331 peter 402 GIC 62525 : IndexElem *n = makeNode(IndexElem);
331 peter 403 ECB :
4942 tgl 404 CBC 62525 : n->name = $1;
7256 405 62525 : n->expr = NULL;
4855 406 62525 : n->indexcolname = NULL;
4397 407 62525 : n->collation = NIL;
4942 408 62525 : n->opclass = list_make1(makeString($2));
5934 409 62525 : n->ordering = SORTBY_DEFAULT;
410 62525 : n->nulls_ordering = SORTBY_NULLS_DEFAULT;
9344 bruce 411 GIC 62525 : $$ = n;
412 : }
413 : ;
414 :
9770 scrappy 415 ECB : optbootstrap:
9344 bruce 416 CBC 1220 : XBOOTSTRAP { $$ = 1; }
9344 bruce 417 GIC 18300 : | { $$ = 0; }
418 : ;
419 :
7652 tgl 420 ECB : optsharedrelation:
7652 tgl 421 CBC 3355 : XSHARED_RELATION { $$ = 1; }
7652 tgl 422 GIC 16165 : | { $$ = 0; }
423 : ;
424 :
4943 tgl 425 ECB : optrowtypeoid:
4943 tgl 426 CBC 2745 : XROWTYPE_OID oidspec { $$ = $2; }
4943 tgl 427 GIC 16775 : | { $$ = InvalidOid; }
428 : ;
429 :
430 : boot_column_list:
431 : boot_column_def
432 : | boot_column_list COMMA boot_column_def
433 : ;
434 :
435 : boot_column_def:
436 : boot_ident EQUALS boot_ident boot_column_nullness
9344 bruce 437 ECB : {
7201 tgl 438 GBC 182085 : if (++numattr > MAXATTR)
8002 peter_e 439 LBC 0 : elog(FATAL, "too many columns");
2969 andres 440 GIC 182085 : DefineAttr($1, $3, numattr-1, $4);
441 : }
442 : ;
443 :
2969 andres 444 ECB : boot_column_nullness:
2969 andres 445 CBC 10370 : XFORCE XNOT XNULL { $$ = BOOTCOL_NULL_FORCE_NOT_NULL; }
446 610 : | XFORCE XNULL { $$ = BOOTCOL_NULL_FORCE_NULL; }
2969 andres 447 GIC 171105 : | { $$ = BOOTCOL_NULL_AUTO; }
448 : ;
449 :
6569 tgl 450 ECB : oidspec:
4942 tgl 451 GIC 82045 : boot_ident { $$ = atooid($1); }
452 : ;
453 :
454 : boot_column_val_list:
455 : boot_column_val
456 : | boot_column_val_list boot_column_val
457 : | boot_column_val_list COMMA boot_column_val
458 : ;
459 :
460 : boot_column_val:
7912 tgl 461 ECB : boot_ident
4942 tgl 462 GIC 38343072 : { InsertOneValue($1, num_columns_read++); }
9344 bruce 463 ECB : | NULLVAL
8002 peter_e 464 GIC 9345813 : { InsertOneNull(num_columns_read++); }
465 : ;
466 :
1800 tgl 467 ECB : boot_ident:
1800 tgl 468 GBC 39096117 : ID { $$ = $1; }
1800 tgl 469 UBC 0 : | OPEN { $$ = pstrdup($1); }
470 0 : | XCLOSE { $$ = pstrdup($1); }
471 0 : | XCREATE { $$ = pstrdup($1); }
472 0 : | INSERT_TUPLE { $$ = pstrdup($1); }
473 0 : | XDECLARE { $$ = pstrdup($1); }
474 0 : | INDEX { $$ = pstrdup($1); }
475 0 : | ON { $$ = pstrdup($1); }
476 0 : | USING { $$ = pstrdup($1); }
477 0 : | XBUILD { $$ = pstrdup($1); }
478 0 : | INDICES { $$ = pstrdup($1); }
479 0 : | UNIQUE { $$ = pstrdup($1); }
480 0 : | XTOAST { $$ = pstrdup($1); }
481 0 : | OBJ_ID { $$ = pstrdup($1); }
482 0 : | XBOOTSTRAP { $$ = pstrdup($1); }
483 0 : | XSHARED_RELATION { $$ = pstrdup($1); }
484 0 : | XROWTYPE_OID { $$ = pstrdup($1); }
485 0 : | XFORCE { $$ = pstrdup($1); }
486 0 : | XNOT { $$ = pstrdup($1); }
1800 tgl 487 UIC 0 : | XNULL { $$ = pstrdup($1); }
488 : ;
489 : %%
|