Fix oversight in previous error-reporting patch; mustn't pfree path string
[PostgreSQL.git] / src / backend / bootstrap / bootparse.y
blob38971e0d985a5096fe2cda5fba62c02a317d9f27
1 %{
2 /*-------------------------------------------------------------------------
4 * bootparse.y
5 * yacc grammar for the "bootstrap" mode (BKI file format)
7 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
11 * IDENTIFICATION
12 * $PostgreSQL$
14 *-------------------------------------------------------------------------
17 #include "postgres.h"
19 #include <unistd.h>
21 #include "access/attnum.h"
22 #include "access/htup.h"
23 #include "access/itup.h"
24 #include "access/skey.h"
25 #include "access/tupdesc.h"
26 #include "access/xact.h"
27 #include "bootstrap/bootstrap.h"
28 #include "catalog/catalog.h"
29 #include "catalog/heap.h"
30 #include "catalog/pg_am.h"
31 #include "catalog/pg_attribute.h"
32 #include "catalog/pg_authid.h"
33 #include "catalog/pg_class.h"
34 #include "catalog/pg_namespace.h"
35 #include "catalog/pg_tablespace.h"
36 #include "catalog/toasting.h"
37 #include "commands/defrem.h"
38 #include "miscadmin.h"
39 #include "nodes/makefuncs.h"
40 #include "nodes/nodes.h"
41 #include "nodes/parsenodes.h"
42 #include "nodes/pg_list.h"
43 #include "nodes/primnodes.h"
44 #include "rewrite/prs2lock.h"
45 #include "storage/block.h"
46 #include "storage/fd.h"
47 #include "storage/ipc.h"
48 #include "storage/itemptr.h"
49 #include "storage/off.h"
50 #include "storage/smgr.h"
51 #include "tcop/dest.h"
52 #include "utils/rel.h"
54 #define atooid(x) ((Oid) strtoul((x), NULL, 10))
58 * Bison doesn't allocate anything that needs to live across parser calls,
59 * so we can easily have it use palloc instead of malloc. This prevents
60 * memory leaks if we error out during parsing. Note this only works with
61 * bison >= 2.0. However, in bison 1.875 the default is to use alloca()
62 * if possible, so there's not really much problem anyhow, at least if
63 * you're building with gcc.
65 #define YYMALLOC palloc
66 #define YYFREE pfree
68 static void
69 do_start(void)
71 StartTransactionCommand();
72 elog(DEBUG4, "start transaction");
76 static void
77 do_end(void)
79 CommitTransactionCommand();
80 elog(DEBUG4, "commit transaction");
81 CHECK_FOR_INTERRUPTS(); /* allow SIGINT to kill bootstrap run */
82 if (isatty(0))
84 printf("bootstrap> ");
85 fflush(stdout);
90 int num_columns_read = 0;
94 %name-prefix="boot_yy"
96 %union
98 List *list;
99 IndexElem *ielem;
100 char *str;
101 int ival;
102 Oid oidval;
105 %type <list> boot_index_params
106 %type <ielem> boot_index_param
107 %type <ival> boot_const boot_ident
108 %type <ival> optbootstrap optsharedrelation optwithoutoids
109 %type <ival> boot_tuple boot_tuplelist
110 %type <oidval> oidspec optoideq
112 %token <ival> CONST_P ID
113 %token OPEN XCLOSE XCREATE INSERT_TUPLE
114 %token XDECLARE INDEX ON USING XBUILD INDICES UNIQUE XTOAST
115 %token COMMA EQUALS LPAREN RPAREN
116 %token OBJ_ID XBOOTSTRAP XSHARED_RELATION XWITHOUT_OIDS NULLVAL
117 %start TopLevel
119 %nonassoc low
120 %nonassoc high
124 TopLevel:
125 Boot_Queries
129 Boot_Queries:
130 Boot_Query
131 | Boot_Queries Boot_Query
134 Boot_Query :
135 Boot_OpenStmt
136 | Boot_CloseStmt
137 | Boot_CreateStmt
138 | Boot_InsertStmt
139 | Boot_DeclareIndexStmt
140 | Boot_DeclareUniqueIndexStmt
141 | Boot_DeclareToastStmt
142 | Boot_BuildIndsStmt
145 Boot_OpenStmt:
146 OPEN boot_ident
148 do_start();
149 boot_openrel(LexIDStr($2));
150 do_end();
154 Boot_CloseStmt:
155 XCLOSE boot_ident %prec low
157 do_start();
158 closerel(LexIDStr($2));
159 do_end();
161 | XCLOSE %prec high
163 do_start();
164 closerel(NULL);
165 do_end();
169 Boot_CreateStmt:
170 XCREATE optbootstrap optsharedrelation optwithoutoids boot_ident oidspec LPAREN
172 do_start();
173 numattr = 0;
174 elog(DEBUG4, "creating%s%s relation %s %u",
175 $2 ? " bootstrap" : "",
176 $3 ? " shared" : "",
177 LexIDStr($5),
178 $6);
180 boot_typelist
182 do_end();
184 RPAREN
186 TupleDesc tupdesc;
188 do_start();
190 tupdesc = CreateTupleDesc(numattr, !($4), attrtypes);
192 if ($2)
194 if (boot_reldesc)
196 elog(DEBUG4, "create bootstrap: warning, open relation exists, closing first");
197 closerel(NULL);
200 boot_reldesc = heap_create(LexIDStr($5),
201 PG_CATALOG_NAMESPACE,
202 $3 ? GLOBALTABLESPACE_OID : 0,
204 tupdesc,
205 RELKIND_RELATION,
207 true);
208 elog(DEBUG4, "bootstrap relation created");
210 else
212 Oid id;
214 id = heap_create_with_catalog(LexIDStr($5),
215 PG_CATALOG_NAMESPACE,
216 $3 ? GLOBALTABLESPACE_OID : 0,
218 BOOTSTRAP_SUPERUSERID,
219 tupdesc,
220 NIL,
221 RELKIND_RELATION,
223 true,
225 ONCOMMIT_NOOP,
226 (Datum) 0,
227 true);
228 elog(DEBUG4, "relation created with oid %u", id);
230 do_end();
234 Boot_InsertStmt:
235 INSERT_TUPLE optoideq
237 do_start();
238 if ($2)
239 elog(DEBUG4, "inserting row with oid %u", $2);
240 else
241 elog(DEBUG4, "inserting row");
242 num_columns_read = 0;
244 LPAREN boot_tuplelist RPAREN
246 if (num_columns_read != numattr)
247 elog(ERROR, "incorrect number of columns in row (expected %d, got %d)",
248 numattr, num_columns_read);
249 if (boot_reldesc == NULL)
250 elog(FATAL, "relation not open");
251 InsertOneTuple($2);
252 do_end();
256 Boot_DeclareIndexStmt:
257 XDECLARE INDEX boot_ident oidspec ON boot_ident USING boot_ident LPAREN boot_index_params RPAREN
259 do_start();
261 DefineIndex(makeRangeVar(NULL, LexIDStr($6), -1),
262 LexIDStr($3),
264 LexIDStr($8),
265 NULL,
266 $10,
267 NULL, NIL,
268 false, false, false,
269 false, false, true, false, false);
270 do_end();
274 Boot_DeclareUniqueIndexStmt:
275 XDECLARE UNIQUE INDEX boot_ident oidspec ON boot_ident USING boot_ident LPAREN boot_index_params RPAREN
277 do_start();
279 DefineIndex(makeRangeVar(NULL, LexIDStr($7), -1),
280 LexIDStr($4),
282 LexIDStr($9),
283 NULL,
284 $11,
285 NULL, NIL,
286 true, false, false,
287 false, false, true, false, false);
288 do_end();
292 Boot_DeclareToastStmt:
293 XDECLARE XTOAST oidspec oidspec ON boot_ident
295 do_start();
297 BootstrapToastTable(LexIDStr($6), $3, $4);
298 do_end();
302 Boot_BuildIndsStmt:
303 XBUILD INDICES
305 do_start();
306 build_indices();
307 do_end();
312 boot_index_params:
313 boot_index_params COMMA boot_index_param { $$ = lappend($1, $3); }
314 | boot_index_param { $$ = list_make1($1); }
317 boot_index_param:
318 boot_ident boot_ident
320 IndexElem *n = makeNode(IndexElem);
321 n->name = LexIDStr($1);
322 n->expr = NULL;
323 n->opclass = list_make1(makeString(LexIDStr($2)));
324 n->ordering = SORTBY_DEFAULT;
325 n->nulls_ordering = SORTBY_NULLS_DEFAULT;
326 $$ = n;
330 optbootstrap:
331 XBOOTSTRAP { $$ = 1; }
332 | { $$ = 0; }
335 optsharedrelation:
336 XSHARED_RELATION { $$ = 1; }
337 | { $$ = 0; }
340 optwithoutoids:
341 XWITHOUT_OIDS { $$ = 1; }
342 | { $$ = 0; }
345 boot_typelist:
346 boot_type_thing
347 | boot_typelist COMMA boot_type_thing
350 boot_type_thing:
351 boot_ident EQUALS boot_ident
353 if (++numattr > MAXATTR)
354 elog(FATAL, "too many columns");
355 DefineAttr(LexIDStr($1),LexIDStr($3),numattr-1);
359 oidspec:
360 boot_ident { $$ = atooid(LexIDStr($1)); }
363 optoideq:
364 OBJ_ID EQUALS oidspec { $$ = $3; }
365 | { $$ = (Oid) 0; }
368 boot_tuplelist:
369 boot_tuple
370 | boot_tuplelist boot_tuple
371 | boot_tuplelist COMMA boot_tuple
374 boot_tuple:
375 boot_ident
376 { InsertOneValue(LexIDStr($1), num_columns_read++); }
377 | boot_const
378 { InsertOneValue(LexIDStr($1), num_columns_read++); }
379 | NULLVAL
380 { InsertOneNull(num_columns_read++); }
383 boot_const :
384 CONST_P { $$=yylval.ival; }
387 boot_ident :
388 ID { $$=yylval.ival; }
392 #include "bootscanner.c"