mirror of
https://github.com/postgres/postgres.git
synced 2025-07-17 06:41:09 +03:00
Allow forcing nullness of columns during bootstrap.
Bootstrap determines whether a column is null based on simple builtin rules. Those work surprisingly well, but nonetheless a few existing columns aren't set correctly. Additionally there is at least one patch sent to hackers where forcing the nullness of a column would be helpful. The boostrap format has gained FORCE [NOT] NULL for this, which will be emitted by genbki.pl when BKI_FORCE_(NOT_)?NULL is specified for a column in a catalog header. This patch doesn't change the marking of any existing columns. Discussion: 20150215170014.GE15326@awork2.anarazel.de
This commit is contained in:
@ -107,7 +107,7 @@ static int num_columns_read = 0;
|
||||
%type <list> boot_index_params
|
||||
%type <ielem> boot_index_param
|
||||
%type <str> boot_const boot_ident
|
||||
%type <ival> optbootstrap optsharedrelation optwithoutoids
|
||||
%type <ival> optbootstrap optsharedrelation optwithoutoids boot_column_nullness
|
||||
%type <oidval> oidspec optoideq optrowtypeoid
|
||||
|
||||
%token <str> CONST_P ID
|
||||
@ -115,6 +115,7 @@ static int num_columns_read = 0;
|
||||
%token XDECLARE INDEX ON USING XBUILD INDICES UNIQUE XTOAST
|
||||
%token COMMA EQUALS LPAREN RPAREN
|
||||
%token OBJ_ID XBOOTSTRAP XSHARED_RELATION XWITHOUT_OIDS XROWTYPE_OID NULLVAL
|
||||
%token XFORCE XNOT XNULL
|
||||
|
||||
%start TopLevel
|
||||
|
||||
@ -427,14 +428,20 @@ boot_column_list:
|
||||
;
|
||||
|
||||
boot_column_def:
|
||||
boot_ident EQUALS boot_ident
|
||||
boot_ident EQUALS boot_ident boot_column_nullness
|
||||
{
|
||||
if (++numattr > MAXATTR)
|
||||
elog(FATAL, "too many columns");
|
||||
DefineAttr($1, $3, numattr-1);
|
||||
DefineAttr($1, $3, numattr-1, $4);
|
||||
}
|
||||
;
|
||||
|
||||
boot_column_nullness:
|
||||
XFORCE XNOT XNULL { $$ = BOOTCOL_NULL_FORCE_NOT_NULL; }
|
||||
| XFORCE XNULL { $$ = BOOTCOL_NULL_FORCE_NULL; }
|
||||
| { $$ = BOOTCOL_NULL_AUTO; }
|
||||
;
|
||||
|
||||
oidspec:
|
||||
boot_ident { $$ = atooid($1); }
|
||||
;
|
||||
|
@ -109,6 +109,9 @@ insert { return(INSERT_TUPLE); }
|
||||
"on" { return(ON); }
|
||||
"using" { return(USING); }
|
||||
"toast" { return(XTOAST); }
|
||||
"FORCE" { return(XFORCE); }
|
||||
"NOT" { return(XNOT); }
|
||||
"NULL" { return(XNULL); }
|
||||
|
||||
{arrayid} {
|
||||
yylval.str = MapArrayTypeName(yytext);
|
||||
|
@ -642,7 +642,7 @@ closerel(char *name)
|
||||
* ----------------
|
||||
*/
|
||||
void
|
||||
DefineAttr(char *name, char *type, int attnum)
|
||||
DefineAttr(char *name, char *type, int attnum, int nullness)
|
||||
{
|
||||
Oid typeoid;
|
||||
|
||||
@ -697,30 +697,44 @@ DefineAttr(char *name, char *type, int attnum)
|
||||
attrtypes[attnum]->atttypmod = -1;
|
||||
attrtypes[attnum]->attislocal = true;
|
||||
|
||||
/*
|
||||
* Mark as "not null" if type is fixed-width and prior columns are too.
|
||||
* This corresponds to case where column can be accessed directly via C
|
||||
* struct declaration.
|
||||
*
|
||||
* oidvector and int2vector are also treated as not-nullable, even though
|
||||
* they are no longer fixed-width.
|
||||
*/
|
||||
#define MARKNOTNULL(att) \
|
||||
((att)->attlen > 0 || \
|
||||
(att)->atttypid == OIDVECTOROID || \
|
||||
(att)->atttypid == INT2VECTOROID)
|
||||
|
||||
if (MARKNOTNULL(attrtypes[attnum]))
|
||||
if (nullness == BOOTCOL_NULL_FORCE_NOT_NULL)
|
||||
{
|
||||
int i;
|
||||
attrtypes[attnum]->attnotnull = true;
|
||||
}
|
||||
else if (nullness == BOOTCOL_NULL_FORCE_NULL)
|
||||
{
|
||||
attrtypes[attnum]->attnotnull = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert(nullness == BOOTCOL_NULL_AUTO);
|
||||
|
||||
for (i = 0; i < attnum; i++)
|
||||
/*
|
||||
* Mark as "not null" if type is fixed-width and prior columns are
|
||||
* too. This corresponds to case where column can be accessed
|
||||
* directly via C struct declaration.
|
||||
*
|
||||
* oidvector and int2vector are also treated as not-nullable, even
|
||||
* though they are no longer fixed-width.
|
||||
*/
|
||||
#define MARKNOTNULL(att) \
|
||||
((att)->attlen > 0 || \
|
||||
(att)->atttypid == OIDVECTOROID || \
|
||||
(att)->atttypid == INT2VECTOROID)
|
||||
|
||||
if (MARKNOTNULL(attrtypes[attnum]))
|
||||
{
|
||||
if (!MARKNOTNULL(attrtypes[i]))
|
||||
break;
|
||||
int i;
|
||||
|
||||
/* check earlier attributes */
|
||||
for (i = 0; i < attnum; i++)
|
||||
{
|
||||
if (!attrtypes[i]->attnotnull)
|
||||
break;
|
||||
}
|
||||
if (i == attnum)
|
||||
attrtypes[attnum]->attnotnull = true;
|
||||
}
|
||||
if (i == attnum)
|
||||
attrtypes[attnum]->attnotnull = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user