Age Owner Branch data 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-2026, 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 : : #include "bootparse.h"
36 : :
37 : :
38 : : /*
39 : : * Bison doesn't allocate anything that needs to live across parser calls,
40 : : * so we can easily have it use palloc instead of malloc. This prevents
41 : : * memory leaks if we error out during parsing.
42 : : */
43 : : #define YYMALLOC palloc
44 : : #define YYFREE pfree
45 : :
46 : : static MemoryContext per_line_ctx = NULL;
47 : :
48 : : static void
7826 neilc@samurai.com 49 :CBC 577779 : do_start(void)
50 : : {
3257 tgl@sss.pgh.pa.us 51 [ - + ]: 577779 : Assert(CurrentMemoryContext == CurTransactionContext);
52 : : /* First time through, create the per-line working context */
53 [ + + ]: 577779 : if (per_line_ctx == NULL)
54 : 51 : per_line_ctx = AllocSetContextCreate(CurTransactionContext,
55 : : "bootstrap per-line processing",
56 : : ALLOCSET_DEFAULT_SIZES);
57 : 577779 : MemoryContextSwitchTo(per_line_ctx);
9073 peter_e@gmx.net 58 : 577779 : }
59 : :
60 : :
61 : : static void
7826 neilc@samurai.com 62 : 577779 : do_end(void)
63 : : {
64 : : /* Reclaim memory allocated while processing this line */
3257 tgl@sss.pgh.pa.us 65 : 577779 : MemoryContextSwitchTo(CurTransactionContext);
66 : 577779 : MemoryContextReset(per_line_ctx);
8157 67 [ - + ]: 577779 : CHECK_FOR_INTERRUPTS(); /* allow SIGINT to kill bootstrap run */
9073 peter_e@gmx.net 68 [ - + ]: 577779 : if (isatty(0))
69 : : {
9073 peter_e@gmx.net 70 :UBC 0 : printf("bootstrap> ");
71 : 0 : fflush(stdout);
72 : : }
9073 peter_e@gmx.net 73 :CBC 577779 : }
74 : :
75 : :
76 : : static int num_columns_read = 0;
77 : :
78 : : %}
79 : :
80 : : %parse-param {yyscan_t yyscanner}
81 : : %lex-param {yyscan_t yyscanner}
82 : : %pure-parser
83 : : %expect 0
84 : : %name-prefix="boot_yy"
85 : :
86 : : %union
87 : : {
88 : : List *list;
89 : : IndexElem *ielem;
90 : : char *str;
91 : : const char *kw;
92 : : int ival;
93 : : Oid oidval;
94 : : }
95 : :
96 : : %type <list> boot_index_params
97 : : %type <ielem> boot_index_param
98 : : %type <str> boot_ident
99 : : %type <ival> optbootstrap optsharedrelation boot_column_nullness
100 : : %type <oidval> oidspec optrowtypeoid
101 : :
102 : : %token <str> ID
103 : : %token COMMA EQUALS LPAREN RPAREN
104 : : /* NULLVAL is a reserved keyword */
105 : : %token NULLVAL
106 : : /* All the rest are unreserved, and should be handled in boot_ident! */
107 : : %token <kw> OPEN XCLOSE XCREATE INSERT_TUPLE
108 : : %token <kw> XDECLARE INDEX ON USING XBUILD INDICES UNIQUE XTOAST
109 : : %token <kw> OBJ_ID XBOOTSTRAP XSHARED_RELATION XROWTYPE_OID
110 : : %token <kw> XFORCE XNOT XNULL
111 : :
112 : : %start TopLevel
113 : :
114 : : %%
115 : :
116 : : TopLevel:
117 : : Boot_Queries
118 : : |
119 : : ;
120 : :
121 : : Boot_Queries:
122 : : Boot_Query
123 : : | Boot_Queries Boot_Query
124 : : ;
125 : :
126 : : Boot_Query :
127 : : Boot_OpenStmt
128 : : | Boot_CloseStmt
129 : : | Boot_CreateStmt
130 : : | Boot_InsertStmt
131 : : | Boot_DeclareIndexStmt
132 : : | Boot_DeclareUniqueIndexStmt
133 : : | Boot_DeclareToastStmt
134 : : | Boot_BuildIndsStmt
135 : : ;
136 : :
137 : : Boot_OpenStmt:
138 : : OPEN boot_ident
139 : : {
140 : 3060 : do_start();
6013 tgl@sss.pgh.pa.us 141 : 3060 : boot_openrel($2);
9073 peter_e@gmx.net 142 : 3060 : do_end();
143 : :
144 : : (void) yynerrs; /* suppress compiler warning */
145 : : }
146 : : ;
147 : :
148 : : Boot_CloseStmt:
149 : : XCLOSE boot_ident
150 : : {
151 : 3264 : do_start();
6013 tgl@sss.pgh.pa.us 152 : 3264 : closerel($2);
9073 peter_e@gmx.net 153 : 3264 : do_end();
154 : : }
155 : : ;
156 : :
157 : : Boot_CreateStmt:
158 : : XCREATE boot_ident oidspec optbootstrap optsharedrelation optrowtypeoid LPAREN
159 : : {
160 : 3264 : do_start();
161 : 3264 : numattr = 0;
7640 tgl@sss.pgh.pa.us 162 [ - + - - : 3264 : elog(DEBUG4, "creating%s%s relation %s %u",
- - ]
163 : : $4 ? " bootstrap" : "",
164 : : $5 ? " shared" : "",
165 : : $2,
166 : : $3);
167 : : }
168 : : boot_column_list
169 : : {
9073 peter_e@gmx.net 170 : 3264 : do_end();
171 : : }
172 : : RPAREN
173 : : {
174 : : TupleDesc tupdesc;
175 : : bool shared_relation;
176 : : bool mapped_relation;
177 : :
178 : 3264 : do_start();
179 : :
2672 andres@anarazel.de 180 : 3264 : tupdesc = CreateTupleDesc(numattr, attrtypes);
181 : :
5880 tgl@sss.pgh.pa.us 182 : 3264 : shared_relation = $5;
183 : :
184 : : /*
185 : : * The catalogs that use the relation mapper are the
186 : : * bootstrap catalogs plus the shared catalogs. If this
187 : : * ever gets more complicated, we should invent a BKI
188 : : * keyword to mark the mapped catalogs, but for now a
189 : : * quick hack seems the most appropriate thing. Note in
190 : : * particular that all "nailed" heap rels (see formrdesc
191 : : * in relcache.c) must be mapped.
192 : : */
193 [ + + + + ]: 3264 : mapped_relation = ($4 || shared_relation);
194 : :
6014 195 [ + + ]: 3264 : if ($4)
196 : : {
197 : : TransactionId relfrozenxid;
198 : : MultiXactId relminmxid;
199 : :
8723 200 [ - + ]: 204 : if (boot_reldesc)
201 : : {
8328 bruce@momjian.us 202 [ # # ]:UBC 0 : elog(DEBUG4, "create bootstrap: warning, open relation exists, closing first");
10415 203 : 0 : closerel(NULL);
204 : : }
205 : :
6013 tgl@sss.pgh.pa.us 206 :CBC 204 : boot_reldesc = heap_create($2,
207 : : PG_CATALOG_NAMESPACE,
208 : : shared_relation ? GLOBALTABLESPACE_OID : 0,
6014 209 [ - + ]: 204 : $3,
210 : : InvalidOid,
211 : : HEAP_TABLE_AM_OID,
212 : : tupdesc,
213 : : RELKIND_RELATION,
214 : : RELPERSISTENCE_PERMANENT,
215 : : shared_relation,
216 : : mapped_relation,
217 : : true,
218 : : &relfrozenxid,
219 : : &relminmxid,
220 : : true);
8328 bruce@momjian.us 221 [ - + ]: 204 : elog(DEBUG4, "bootstrap relation created");
222 : : }
223 : : else
224 : : {
225 : : Oid id;
226 : :
6013 tgl@sss.pgh.pa.us 227 : 3060 : id = heap_create_with_catalog($2,
228 : : PG_CATALOG_NAMESPACE,
229 : : shared_relation ? GLOBALTABLESPACE_OID : 0,
6014 230 : 3060 : $3,
2672 andres@anarazel.de 231 [ + + ]: 3060 : $6,
232 : : InvalidOid,
233 : : BOOTSTRAP_SUPERUSERID,
234 : : HEAP_TABLE_AM_OID,
235 : : tupdesc,
236 : : NIL,
237 : : RELKIND_RELATION,
238 : : RELPERSISTENCE_PERMANENT,
239 : : shared_relation,
240 : : mapped_relation,
241 : : ONCOMMIT_NOOP,
242 : : (Datum) 0,
243 : : false,
244 : : true,
245 : : false,
246 : : InvalidOid,
247 : : NULL);
5383 peter_e@gmx.net 248 [ - + ]: 3060 : elog(DEBUG4, "relation created with OID %u", id);
249 : : }
9073 250 : 3264 : do_end();
251 : : }
252 : : ;
253 : :
254 : : Boot_InsertStmt:
255 : : INSERT_TUPLE
256 : : {
257 : 556767 : do_start();
2672 andres@anarazel.de 258 [ - + ]: 556767 : elog(DEBUG4, "inserting row");
9073 peter_e@gmx.net 259 : 556767 : num_columns_read = 0;
260 : : }
261 : : LPAREN boot_column_val_list RPAREN
262 : : {
263 [ - + ]: 556767 : if (num_columns_read != numattr)
9073 peter_e@gmx.net 264 [ # # ]:UBC 0 : elog(ERROR, "incorrect number of columns in row (expected %d, got %d)",
265 : : numattr, num_columns_read);
8103 neilc@samurai.com 266 [ - + ]:CBC 556767 : if (boot_reldesc == NULL)
6948 alvherre@alvh.no-ip. 267 [ # # ]:UBC 0 : elog(FATAL, "relation not open");
2672 andres@anarazel.de 268 :CBC 556767 : InsertOneTuple();
9073 peter_e@gmx.net 269 : 556767 : do_end();
270 : : }
271 : : ;
272 : :
273 : : Boot_DeclareIndexStmt:
274 : : XDECLARE INDEX boot_ident oidspec ON boot_ident USING boot_ident LPAREN boot_index_params RPAREN
275 : : {
1402 peter@eisentraut.org 276 : 714 : IndexStmt *stmt = makeNode(IndexStmt);
277 : : Oid relationId;
278 : :
2930 alvherre@alvh.no-ip. 279 [ - + ]: 714 : elog(DEBUG4, "creating index \"%s\"", $3);
280 : :
9073 peter_e@gmx.net 281 : 714 : do_start();
282 : :
4990 tgl@sss.pgh.pa.us 283 : 714 : stmt->idxname = $3;
284 : 714 : stmt->relation = makeRangeVar(NULL, $6, -1);
285 : 714 : stmt->accessMethod = $8;
286 : 714 : stmt->tableSpace = NULL;
287 : 714 : stmt->indexParams = $10;
2899 teodor@sigaev.ru 288 : 714 : stmt->indexIncludingParams = NIL;
4990 tgl@sss.pgh.pa.us 289 : 714 : stmt->options = NIL;
290 : 714 : stmt->whereClause = NULL;
291 : 714 : stmt->excludeOpNames = NIL;
292 : 714 : stmt->idxcomment = NULL;
293 : 714 : stmt->indexOid = InvalidOid;
1348 rhaas@postgresql.org 294 : 714 : stmt->oldNumber = InvalidRelFileNumber;
2171 noah@leadboat.com 295 : 714 : stmt->oldCreateSubid = InvalidSubTransactionId;
1348 rhaas@postgresql.org 296 : 714 : stmt->oldFirstRelfilelocatorSubid = InvalidSubTransactionId;
4990 tgl@sss.pgh.pa.us 297 : 714 : stmt->unique = false;
298 : 714 : stmt->primary = false;
299 : 714 : stmt->isconstraint = false;
300 : 714 : stmt->deferrable = false;
301 : 714 : stmt->initdeferred = false;
4039 302 : 714 : stmt->transformed = false;
4990 303 : 714 : stmt->concurrent = false;
4039 304 : 714 : stmt->if_not_exists = false;
2516 alvherre@alvh.no-ip. 305 : 714 : stmt->reset_default_tblspc = false;
306 : :
307 : : /* locks and races need not concern us in bootstrap mode */
4409 rhaas@postgresql.org 308 : 714 : relationId = RangeVarGetRelid(stmt->relation, NoLock,
309 : : false);
310 : :
70 tgl@sss.pgh.pa.us 311 :GNC 714 : DefineIndex(NULL,
312 : : relationId,
313 : : stmt,
7640 tgl@sss.pgh.pa.us 314 :CBC 714 : $4,
315 : : InvalidOid,
316 : : InvalidOid,
317 : : -1,
318 : : false,
319 : : false,
320 : : false,
321 : : true, /* skip_build */
322 : : false);
9073 peter_e@gmx.net 323 : 714 : do_end();
324 : : }
325 : : ;
326 : :
327 : : Boot_DeclareUniqueIndexStmt:
328 : : XDECLARE UNIQUE INDEX boot_ident oidspec ON boot_ident USING boot_ident LPAREN boot_index_params RPAREN
329 : : {
1402 peter@eisentraut.org 330 : 5610 : IndexStmt *stmt = makeNode(IndexStmt);
331 : : Oid relationId;
332 : :
2930 alvherre@alvh.no-ip. 333 [ - + ]: 5610 : elog(DEBUG4, "creating unique index \"%s\"", $4);
334 : :
9073 peter_e@gmx.net 335 : 5610 : do_start();
336 : :
4990 tgl@sss.pgh.pa.us 337 : 5610 : stmt->idxname = $4;
338 : 5610 : stmt->relation = makeRangeVar(NULL, $7, -1);
339 : 5610 : stmt->accessMethod = $9;
340 : 5610 : stmt->tableSpace = NULL;
341 : 5610 : stmt->indexParams = $11;
2899 teodor@sigaev.ru 342 : 5610 : stmt->indexIncludingParams = NIL;
4990 tgl@sss.pgh.pa.us 343 : 5610 : stmt->options = NIL;
344 : 5610 : stmt->whereClause = NULL;
345 : 5610 : stmt->excludeOpNames = NIL;
346 : 5610 : stmt->idxcomment = NULL;
347 : 5610 : stmt->indexOid = InvalidOid;
1348 rhaas@postgresql.org 348 : 5610 : stmt->oldNumber = InvalidRelFileNumber;
2171 noah@leadboat.com 349 : 5610 : stmt->oldCreateSubid = InvalidSubTransactionId;
1348 rhaas@postgresql.org 350 : 5610 : stmt->oldFirstRelfilelocatorSubid = InvalidSubTransactionId;
4990 tgl@sss.pgh.pa.us 351 : 5610 : stmt->unique = true;
352 : 5610 : stmt->primary = false;
353 : 5610 : stmt->isconstraint = false;
354 : 5610 : stmt->deferrable = false;
355 : 5610 : stmt->initdeferred = false;
4039 356 : 5610 : stmt->transformed = false;
4990 357 : 5610 : stmt->concurrent = false;
4039 358 : 5610 : stmt->if_not_exists = false;
2516 alvherre@alvh.no-ip. 359 : 5610 : stmt->reset_default_tblspc = false;
360 : :
361 : : /* locks and races need not concern us in bootstrap mode */
4409 rhaas@postgresql.org 362 : 5610 : relationId = RangeVarGetRelid(stmt->relation, NoLock,
363 : : false);
364 : :
70 tgl@sss.pgh.pa.us 365 :GNC 5610 : DefineIndex(NULL,
366 : : relationId,
367 : : stmt,
7640 tgl@sss.pgh.pa.us 368 :CBC 5610 : $5,
369 : : InvalidOid,
370 : : InvalidOid,
371 : : -1,
372 : : false,
373 : : false,
374 : : false,
375 : : true, /* skip_build */
376 : : false);
9073 peter_e@gmx.net 377 : 5610 : do_end();
378 : : }
379 : : ;
380 : :
381 : : Boot_DeclareToastStmt:
382 : : XDECLARE XTOAST oidspec oidspec ON boot_ident
383 : : {
2930 alvherre@alvh.no-ip. 384 [ - + ]: 1785 : elog(DEBUG4, "creating toast table for table \"%s\"", $6);
385 : :
7167 tgl@sss.pgh.pa.us 386 : 1785 : do_start();
387 : :
6013 388 : 1785 : BootstrapToastTable($6, $3, $4);
7167 389 : 1785 : do_end();
390 : : }
391 : : ;
392 : :
393 : : Boot_BuildIndsStmt:
394 : : XBUILD INDICES
395 : : {
7911 396 : 51 : do_start();
397 : 51 : build_indices();
398 : 51 : do_end();
399 : : }
400 : : ;
401 : :
402 : :
403 : : boot_index_params:
10070 bruce@momjian.us 404 : 4131 : boot_index_params COMMA boot_index_param { $$ = lappend($1, $3); }
7963 neilc@samurai.com 405 : 6324 : | boot_index_param { $$ = list_make1($1); }
406 : : ;
407 : :
408 : : boot_index_param:
409 : : boot_ident boot_ident
410 : : {
1402 peter@eisentraut.org 411 : 10455 : IndexElem *n = makeNode(IndexElem);
412 : :
6013 tgl@sss.pgh.pa.us 413 : 10455 : n->name = $1;
8327 414 : 10455 : n->expr = NULL;
5926 415 : 10455 : n->indexcolname = NULL;
5468 416 : 10455 : n->collation = NIL;
6013 417 : 10455 : n->opclass = list_make1(makeString($2));
7005 418 : 10455 : n->ordering = SORTBY_DEFAULT;
419 : 10455 : n->nulls_ordering = SORTBY_NULLS_DEFAULT;
70 tgl@sss.pgh.pa.us 420 :GNC 10455 : n->location = -1;
10415 bruce@momjian.us 421 :CBC 10455 : $$ = n;
422 : : }
423 : : ;
424 : :
425 : : optbootstrap:
426 : 204 : XBOOTSTRAP { $$ = 1; }
427 : 3060 : | { $$ = 0; }
428 : : ;
429 : :
430 : : optsharedrelation:
8723 tgl@sss.pgh.pa.us 431 : 561 : XSHARED_RELATION { $$ = 1; }
432 : 2703 : | { $$ = 0; }
433 : : ;
434 : :
435 : : optrowtypeoid:
6014 436 : 459 : XROWTYPE_OID oidspec { $$ = $2; }
437 : 2805 : | { $$ = InvalidOid; }
438 : : ;
439 : :
440 : : boot_column_list:
441 : : boot_column_def
442 : : | boot_column_list COMMA boot_column_def
443 : : ;
444 : :
445 : : boot_column_def:
446 : : boot_ident EQUALS boot_ident boot_column_nullness
447 : : {
8272 448 [ - + ]: 31314 : if (++numattr > MAXATTR)
9073 peter_e@gmx.net 449 [ # # ]:UBC 0 : elog(FATAL, "too many columns");
4040 andres@anarazel.de 450 :CBC 31314 : DefineAttr($1, $3, numattr-1, $4);
451 : : }
452 : : ;
453 : :
454 : : boot_column_nullness:
455 : 1734 : XFORCE XNOT XNULL { $$ = BOOTCOL_NULL_FORCE_NOT_NULL; }
456 : 204 : | XFORCE XNULL { $$ = BOOTCOL_NULL_FORCE_NULL; }
457 : 29376 : | { $$ = BOOTCOL_NULL_AUTO; }
458 : : ;
459 : :
460 : : oidspec:
6013 tgl@sss.pgh.pa.us 461 : 13617 : boot_ident { $$ = atooid($1); }
462 : : ;
463 : :
464 : : boot_column_val_list:
465 : : boot_column_val
466 : : | boot_column_val_list boot_column_val
467 : : | boot_column_val_list COMMA boot_column_val
468 : : ;
469 : :
470 : : boot_column_val:
471 : : boot_ident
472 : 6635823 : { InsertOneValue($1, num_columns_read++); }
473 : : | NULLVAL
9073 peter_e@gmx.net 474 : 1627911 : { InsertOneNull(num_columns_read++); }
475 : : ;
476 : :
477 : : boot_ident:
2871 tgl@sss.pgh.pa.us 478 : 6763323 : ID { $$ = $1; }
2871 tgl@sss.pgh.pa.us 479 :UBC 0 : | OPEN { $$ = pstrdup($1); }
480 : 0 : | XCLOSE { $$ = pstrdup($1); }
481 : 0 : | XCREATE { $$ = pstrdup($1); }
482 : 0 : | INSERT_TUPLE { $$ = pstrdup($1); }
483 : 0 : | XDECLARE { $$ = pstrdup($1); }
484 : 0 : | INDEX { $$ = pstrdup($1); }
485 : 0 : | ON { $$ = pstrdup($1); }
486 : 0 : | USING { $$ = pstrdup($1); }
487 : 0 : | XBUILD { $$ = pstrdup($1); }
488 : 0 : | INDICES { $$ = pstrdup($1); }
489 : 0 : | UNIQUE { $$ = pstrdup($1); }
490 : 0 : | XTOAST { $$ = pstrdup($1); }
491 : 0 : | OBJ_ID { $$ = pstrdup($1); }
492 : 0 : | XBOOTSTRAP { $$ = pstrdup($1); }
493 : 0 : | XSHARED_RELATION { $$ = pstrdup($1); }
494 : 0 : | XROWTYPE_OID { $$ = pstrdup($1); }
495 : 0 : | XFORCE { $$ = pstrdup($1); }
496 : 0 : | XNOT { $$ = pstrdup($1); }
497 : 0 : | XNULL { $$ = pstrdup($1); }
498 : : ;
499 : : %%
|