Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit15c82ef

Browse files
committed
Refactor CREATE/ALTER DATABASE syntax so options need not be keywords.
Most of the existing option names are keywords anyway, but we can get ridof LC_COLLATE and LC_CTYPE as keywords known to the lexer/grammar. Thisimmediately reduces the size of the grammar tables by about 8KB, and willsave more when we add additional CREATE/ALTER DATABASE options in future.A side effect of the implementation is that the CONNECTION LIMIT optioncan now also be spelled CONNECTION_LIMIT. We choose not to document this,however.Vik Fearing, based on a suggestion by me; reviewed by Pavel Stehule
1 parent2e8ce9a commit15c82ef

File tree

3 files changed

+76
-103
lines changed

3 files changed

+76
-103
lines changed

‎src/backend/commands/dbcommands.c

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include"catalog/pg_tablespace.h"
4040
#include"commands/comment.h"
4141
#include"commands/dbcommands.h"
42+
#include"commands/defrem.h"
4243
#include"commands/seclabel.h"
4344
#include"commands/tablespace.h"
4445
#include"mb/pg_wchar.h"
@@ -188,7 +189,7 @@ createdb(const CreatedbStmt *stmt)
188189
errmsg("conflicting or redundant options")));
189190
dctype=defel;
190191
}
191-
elseif (strcmp(defel->defname,"connectionlimit")==0)
192+
elseif (strcmp(defel->defname,"connection_limit")==0)
192193
{
193194
if (dconnlimit)
194195
ereport(ERROR,
@@ -204,21 +205,22 @@ createdb(const CreatedbStmt *stmt)
204205
errhint("Consider using tablespaces instead.")));
205206
}
206207
else
207-
elog(ERROR,"option \"%s\" not recognized",
208-
defel->defname);
208+
ereport(ERROR,
209+
(errcode(ERRCODE_SYNTAX_ERROR),
210+
errmsg("option \"%s\" not recognized",defel->defname)));
209211
}
210212

211213
if (downer&&downer->arg)
212-
dbowner=strVal(downer->arg);
214+
dbowner=defGetString(downer);
213215
if (dtemplate&&dtemplate->arg)
214-
dbtemplate=strVal(dtemplate->arg);
216+
dbtemplate=defGetString(dtemplate);
215217
if (dencoding&&dencoding->arg)
216218
{
217219
constchar*encoding_name;
218220

219221
if (IsA(dencoding->arg,Integer))
220222
{
221-
encoding=intVal(dencoding->arg);
223+
encoding=defGetInt32(dencoding);
222224
encoding_name=pg_encoding_to_char(encoding);
223225
if (strcmp(encoding_name,"")==0||
224226
pg_valid_server_encoding(encoding_name)<0)
@@ -227,28 +229,25 @@ createdb(const CreatedbStmt *stmt)
227229
errmsg("%d is not a valid encoding code",
228230
encoding)));
229231
}
230-
elseif (IsA(dencoding->arg,String))
232+
else
231233
{
232-
encoding_name=strVal(dencoding->arg);
234+
encoding_name=defGetString(dencoding);
233235
encoding=pg_valid_server_encoding(encoding_name);
234236
if (encoding<0)
235237
ereport(ERROR,
236238
(errcode(ERRCODE_UNDEFINED_OBJECT),
237239
errmsg("%s is not a valid encoding name",
238240
encoding_name)));
239241
}
240-
else
241-
elog(ERROR,"unrecognized node type: %d",
242-
nodeTag(dencoding->arg));
243242
}
244243
if (dcollate&&dcollate->arg)
245-
dbcollate=strVal(dcollate->arg);
244+
dbcollate=defGetString(dcollate);
246245
if (dctype&&dctype->arg)
247-
dbctype=strVal(dctype->arg);
246+
dbctype=defGetString(dctype);
248247

249248
if (dconnlimit&&dconnlimit->arg)
250249
{
251-
dbconnlimit=intVal(dconnlimit->arg);
250+
dbconnlimit=defGetInt32(dconnlimit);
252251
if (dbconnlimit<-1)
253252
ereport(ERROR,
254253
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
@@ -379,7 +378,7 @@ createdb(const CreatedbStmt *stmt)
379378
char*tablespacename;
380379
AclResultaclresult;
381380

382-
tablespacename=strVal(dtablespacename->arg);
381+
tablespacename=defGetString(dtablespacename);
383382
dst_deftablespace=get_tablespace_oid(tablespacename, false);
384383
/* check permissions */
385384
aclresult=pg_tablespace_aclcheck(dst_deftablespace,GetUserId(),
@@ -1341,7 +1340,7 @@ AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel)
13411340
{
13421341
DefElem*defel= (DefElem*)lfirst(option);
13431342

1344-
if (strcmp(defel->defname,"connectionlimit")==0)
1343+
if (strcmp(defel->defname,"connection_limit")==0)
13451344
{
13461345
if (dconnlimit)
13471346
ereport(ERROR,
@@ -1358,23 +1357,32 @@ AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel)
13581357
dtablespace=defel;
13591358
}
13601359
else
1361-
elog(ERROR,"option \"%s\" not recognized",
1362-
defel->defname);
1360+
ereport(ERROR,
1361+
(errcode(ERRCODE_SYNTAX_ERROR),
1362+
errmsg("option \"%s\" not recognized",defel->defname)));
13631363
}
13641364

13651365
if (dtablespace)
13661366
{
1367-
/* currently, can't be specified along with any other options */
1368-
Assert(!dconnlimit);
1367+
/*
1368+
* While the SET TABLESPACE syntax doesn't allow any other options,
1369+
* somebody could write "WITH TABLESPACE ...". Forbid any other
1370+
* options from being specified in that case.
1371+
*/
1372+
if (list_length(stmt->options)!=1)
1373+
ereport(ERROR,
1374+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1375+
errmsg("option \"%s\" cannot be specified with other options",
1376+
dtablespace->defname)));
13691377
/* this case isn't allowed within a transaction block */
13701378
PreventTransactionChain(isTopLevel,"ALTER DATABASE SET TABLESPACE");
1371-
movedb(stmt->dbname,strVal(dtablespace->arg));
1379+
movedb(stmt->dbname,defGetString(dtablespace));
13721380
returnInvalidOid;
13731381
}
13741382

1375-
if (dconnlimit)
1383+
if (dconnlimit&&dconnlimit->arg)
13761384
{
1377-
connlimit=intVal(dconnlimit->arg);
1385+
connlimit=defGetInt32(dconnlimit);
13781386
if (connlimit<-1)
13791387
ereport(ERROR,
13801388
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),

‎src/backend/parser/gram.y

Lines changed: 45 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -264,10 +264,10 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
264264

265265
%type<dbehavior>opt_drop_behavior
266266

267-
%type<list>createdb_opt_listalterdb_opt_listcopy_opt_list
267+
%type<list>createdb_opt_listcreatedb_opt_itemscopy_opt_list
268268
transaction_mode_list
269269
create_extension_opt_listalter_extension_opt_list
270-
%type<defelt>createdb_opt_itemalterdb_opt_itemcopy_opt_item
270+
%type<defelt>createdb_opt_itemcopy_opt_item
271271
transaction_mode_item
272272
create_extension_opt_itemalter_extension_opt_item
273273

@@ -462,6 +462,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
462462
%type<list>var_list
463463
%type<str>ColIdColLabelvar_nametype_function_nameparam_name
464464
%type<str>NonReservedWordNonReservedWord_or_Sconst
465+
%type<str>createdb_opt_name
465466
%type<node>var_valuezone_value
466467

467468
%type<keyword>unreserved_keywordtype_func_name_keyword
@@ -564,7 +565,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
564565

565566
KEY
566567

567-
LABEL LANGUAGE LARGE_P LAST_P LATERAL_P LC_COLLATE_P LC_CTYPE_P
568+
LABEL LANGUAGE LARGE_P LAST_P LATERAL_P
568569
LEADING LEAKPROOF LEAST LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL
569570
LOCALTIME LOCALTIMESTAMP LOCATION LOCK_P
570571

@@ -8320,77 +8321,51 @@ CreatedbStmt:
83208321
;
83218322

83228323
createdb_opt_list:
8323-
createdb_opt_listcreatedb_opt_item{$$ =lappend($1,$2); }
8324+
createdb_opt_items{$$ =$1; }
83248325
|/* EMPTY*/{$$ = NIL; }
83258326
;
83268327

8328+
createdb_opt_items:
8329+
createdb_opt_item{$$ = list_make1($1); }
8330+
|createdb_opt_itemscreatedb_opt_item{$$ = lappend($1,$2); }
8331+
;
8332+
83278333
createdb_opt_item:
8328-
TABLESPACEopt_equalname
8329-
{
8330-
$$ = makeDefElem("tablespace", (Node *)makeString($3));
8331-
}
8332-
|TABLESPACEopt_equalDEFAULT
8333-
{
8334-
$$ = makeDefElem("tablespace",NULL);
8335-
}
8336-
|LOCATIONopt_equalSconst
8337-
{
8338-
$$ = makeDefElem("location", (Node *)makeString($3));
8339-
}
8340-
|LOCATIONopt_equalDEFAULT
8341-
{
8342-
$$ = makeDefElem("location",NULL);
8343-
}
8344-
|TEMPLATEopt_equalname
8345-
{
8346-
$$ = makeDefElem("template", (Node *)makeString($3));
8347-
}
8348-
|TEMPLATEopt_equalDEFAULT
8349-
{
8350-
$$ = makeDefElem("template",NULL);
8351-
}
8352-
|ENCODINGopt_equalSconst
8353-
{
8354-
$$ = makeDefElem("encoding", (Node *)makeString($3));
8355-
}
8356-
|ENCODINGopt_equalIconst
8357-
{
8358-
$$ = makeDefElem("encoding", (Node *)makeInteger($3));
8359-
}
8360-
|ENCODINGopt_equalDEFAULT
8361-
{
8362-
$$ = makeDefElem("encoding",NULL);
8363-
}
8364-
|LC_COLLATE_Popt_equalSconst
8365-
{
8366-
$$ = makeDefElem("lc_collate", (Node *)makeString($3));
8367-
}
8368-
|LC_COLLATE_Popt_equalDEFAULT
8369-
{
8370-
$$ = makeDefElem("lc_collate",NULL);
8371-
}
8372-
|LC_CTYPE_Popt_equalSconst
8334+
createdb_opt_nameopt_equalSignedIconst
83738335
{
8374-
$$ = makeDefElem("lc_ctype", (Node *)makeString($3));
8336+
$$ = makeDefElem($1, (Node *)makeInteger($3));
83758337
}
8376-
|LC_CTYPE_Popt_equalDEFAULT
8338+
|createdb_opt_nameopt_equalopt_boolean_or_string
83778339
{
8378-
$$ = makeDefElem("lc_ctype",NULL);
8340+
$$ = makeDefElem($1, (Node *)makeString($3));
83798341
}
8380-
|CONNECTIONLIMITopt_equalSignedIconst
8342+
|createdb_opt_nameopt_equalDEFAULT
83818343
{
8382-
$$ = makeDefElem("connectionlimit", (Node *)makeInteger($4));
8383-
}
8384-
|OWNERopt_equalname
8385-
{
8386-
$$ = makeDefElem("owner", (Node *)makeString($3));
8387-
}
8388-
|OWNERopt_equalDEFAULT
8389-
{
8390-
$$ = makeDefElem("owner",NULL);
8344+
$$ = makeDefElem($1,NULL);
83918345
}
83928346
;
83938347

8348+
/*
8349+
* Ideally we'd use ColId here, but that causes shift/reduce conflicts against
8350+
* the ALTER DATABASE SET/RESET syntaxes. Instead call out specific keywords
8351+
* we need, and allow IDENT so that database option names don't have to be
8352+
* parser keywords unless they are already keywords for other reasons.
8353+
*
8354+
* XXX this coding technique is fragile since if someone makes a formerly
8355+
* non-keyword option name into a keyword and forgets to add it here, the
8356+
* option will silently break. Best defense is to provide a regression test
8357+
* exercising every such option, at least at the syntax level.
8358+
*/
8359+
createdb_opt_name:
8360+
IDENT{$$ =$1; }
8361+
|CONNECTIONLIMIT{$$ = pstrdup("connection_limit"); }
8362+
|ENCODING{$$ = pstrdup($1); }
8363+
|LOCATION{$$ = pstrdup($1); }
8364+
|OWNER{$$ = pstrdup($1); }
8365+
|TABLESPACE{$$ = pstrdup($1); }
8366+
|TEMPLATE{$$ = pstrdup($1); }
8367+
;
8368+
83948369
/*
83958370
*Though the equals sign doesn't match other WITH options, pg_dump uses
83968371
*equals for backward compatibility, and it doesn't seem worth removing it.
@@ -8407,13 +8382,20 @@ opt_equal:'='{}
84078382
*****************************************************************************/
84088383

84098384
AlterDatabaseStmt:
8410-
ALTERDATABASEdatabase_nameopt_withalterdb_opt_list
8385+
ALTERDATABASEdatabase_nameWITHcreatedb_opt_list
84118386
{
84128387
AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt);
84138388
n->dbname =$3;
84148389
n->options =$5;
84158390
$$ = (Node *)n;
84168391
}
8392+
|ALTERDATABASEdatabase_namecreatedb_opt_list
8393+
{
8394+
AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt);
8395+
n->dbname =$3;
8396+
n->options =$4;
8397+
$$ = (Node *)n;
8398+
}
84178399
|ALTERDATABASEdatabase_nameSETTABLESPACEname
84188400
{
84198401
AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt);
@@ -8435,19 +8417,6 @@ AlterDatabaseSetStmt:
84358417
;
84368418

84378419

8438-
alterdb_opt_list:
8439-
alterdb_opt_listalterdb_opt_item{$$ = lappend($1,$2); }
8440-
|/* EMPTY*/{$$ = NIL; }
8441-
;
8442-
8443-
alterdb_opt_item:
8444-
CONNECTIONLIMITopt_equalSignedIconst
8445-
{
8446-
$$ = makeDefElem("connectionlimit", (Node *)makeInteger($4));
8447-
}
8448-
;
8449-
8450-
84518420
/*****************************************************************************
84528421
*
84538422
*DROP DATABASE [ IF EXISTS ]
@@ -12958,8 +12927,6 @@ unreserved_keyword:
1295812927
| LANGUAGE
1295912928
| LARGE_P
1296012929
| LAST_P
12961-
| LC_COLLATE_P
12962-
| LC_CTYPE_P
1296312930
| LEAKPROOF
1296412931
| LEVEL
1296512932
| LISTEN

‎src/include/parser/kwlist.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,6 @@ PG_KEYWORD("language", LANGUAGE, UNRESERVED_KEYWORD)
215215
PG_KEYWORD("large",LARGE_P,UNRESERVED_KEYWORD)
216216
PG_KEYWORD("last",LAST_P,UNRESERVED_KEYWORD)
217217
PG_KEYWORD("lateral",LATERAL_P,RESERVED_KEYWORD)
218-
PG_KEYWORD("lc_collate",LC_COLLATE_P,UNRESERVED_KEYWORD)
219-
PG_KEYWORD("lc_ctype",LC_CTYPE_P,UNRESERVED_KEYWORD)
220218
PG_KEYWORD("leading",LEADING,RESERVED_KEYWORD)
221219
PG_KEYWORD("leakproof",LEAKPROOF,UNRESERVED_KEYWORD)
222220
PG_KEYWORD("least",LEAST,COL_NAME_KEYWORD)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp