Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit c70e606

Browse files
committed
Includes:
- LIKE <subtable> [ INCLUDING DEFAULTS | EXCLUDING DEFAULTS ] - Quick cleanup of analyze.c function prototypes. - New non-reserved keywords (INCLUDING, EXCLUDING, DEFAULTS), SQL 200X Opted not to extend for check constraints at this time. As per the definition that it's user defined columns, OIDs are NOT inherited. Doc and Source patches attached. -- Rod Taylor <rbt@rbt.ca>
1 parent dbca370 commit c70e606

File tree

12 files changed

+277
-25
lines changed

12 files changed

+277
-25
lines changed

contrib/Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# $Header: /cvsroot/pgsql/contrib/Makefile,v 1.41 2003/03/20 18:14:46 momjian Exp $
1+
# $Header: /cvsroot/pgsql/contrib/Makefile,v 1.42 2003/06/25 03:40:17 momjian Exp $
22

33
subdir = contrib
44
top_builddir = ..
@@ -13,7 +13,6 @@ WANTED_DIRS = \
1313
dblink \
1414
dbmirror \
1515
dbsize \
16-
earthdistance \
1716
findoidjoins \
1817
fulltextindex \
1918
fuzzystrmatch \

src/backend/catalog/sql_features.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ T121 WITH (excluding RECURSIVE) in query expression NO
308308
T131 Recursive query NO
309309
T141 SIMILAR predicate YES
310310
T151 DISTINCT predicate YES
311-
T171 LIKE clause in table definition NO
311+
T171 LIKE clause in table definition YES
312312
T191 Referential action RESTRICT YES
313313
T201 Comparable data types for referential constraints YES
314314
T211 Basic trigger capability NO

src/backend/nodes/copyfuncs.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.253 2003/06/24 23:14:43 momjian Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.254 2003/06/25 03:40:17 momjian Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -1731,6 +1731,17 @@ _copyCreateStmt(CreateStmt *from)
17311731
return newnode;
17321732
}
17331733

1734+
static InhRelation *
1735+
_copyInhRelation(InhRelation *from)
1736+
{
1737+
InhRelation *newnode = makeNode(InhRelation);
1738+
1739+
COPY_NODE_FIELD(relation);
1740+
COPY_SCALAR_FIELD(including_defaults);
1741+
1742+
return newnode;
1743+
}
1744+
17341745
static DefineStmt *
17351746
_copyDefineStmt(DefineStmt *from)
17361747
{
@@ -2693,6 +2704,9 @@ copyObject(void *from)
26932704
case T_CreateStmt:
26942705
retval = _copyCreateStmt(from);
26952706
break;
2707+
case T_InhRelation:
2708+
retval = _copyInhRelation(from);
2709+
break;
26962710
case T_DefineStmt:
26972711
retval = _copyDefineStmt(from);
26982712
break;

src/backend/nodes/equalfuncs.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
* Portions Copyright (c) 1994, Regents of the University of California
1919
*
2020
* IDENTIFICATION
21-
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.196 2003/06/24 23:14:43 momjian Exp $
21+
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.197 2003/06/25 03:40:17 momjian Exp $
2222
*
2323
*-------------------------------------------------------------------------
2424
*/
@@ -785,6 +785,15 @@ _equalCreateStmt(CreateStmt *a, CreateStmt *b)
785785
return true;
786786
}
787787

788+
static bool
789+
_equalInhRelation(InhRelation *a, InhRelation *b)
790+
{
791+
COMPARE_NODE_FIELD(relation);
792+
COMPARE_SCALAR_FIELD(including_defaults);
793+
794+
return true;
795+
}
796+
788797
static bool
789798
_equalDefineStmt(DefineStmt *a, DefineStmt *b)
790799
{
@@ -1807,6 +1816,9 @@ equal(void *a, void *b)
18071816
case T_CreateStmt:
18081817
retval = _equalCreateStmt(a, b);
18091818
break;
1819+
case T_InhRelation:
1820+
retval = _equalInhRelation(a,b);
1821+
break;
18101822
case T_DefineStmt:
18111823
retval = _equalDefineStmt(a, b);
18121824
break;

src/backend/parser/analyze.c

Lines changed: 132 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.275 2003/06/16 02:03:37 tgl Exp $
9+
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.276 2003/06/25 03:40:17 momjian Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -21,6 +21,7 @@
2121
#include "catalog/pg_index.h"
2222
#include "catalog/pg_type.h"
2323
#include "commands/prepare.h"
24+
#include "miscadmin.h"
2425
#include "nodes/makefuncs.h"
2526
#include "optimizer/clauses.h"
2627
#include "optimizer/var.h"
@@ -37,6 +38,7 @@
3738
#include "parser/parse_type.h"
3839
#include "parser/parse_expr.h"
3940
#include "rewrite/rewriteManip.h"
41+
#include "utils/acl.h"
4042
#include "utils/builtins.h"
4143
#include "utils/fmgroids.h"
4244
#include "utils/lsyscache.h"
@@ -112,13 +114,15 @@ static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt,
112114
static Query *transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt,
113115
List **extras_before, List **extras_after);
114116
static void transformColumnDefinition(ParseState *pstate,
115-
CreateStmtContext *cxt,
116-
ColumnDef *column);
117+
CreateStmtContext *cxt,
118+
ColumnDef *column);
117119
static void transformTableConstraint(ParseState *pstate,
118-
CreateStmtContext *cxt,
119-
Constraint *constraint);
120+
CreateStmtContext *cxt,
121+
Constraint *constraint);
122+
static void transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
123+
InhRelation *inhrelation);
120124
static void transformIndexConstraints(ParseState *pstate,
121-
CreateStmtContext *cxt);
125+
CreateStmtContext *cxt);
122126
static void transformFKConstraints(ParseState *pstate,
123127
CreateStmtContext *cxt,
124128
bool isAddConstraint);
@@ -880,6 +884,11 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt,
880884
cxt.fkconstraints = lappend(cxt.fkconstraints, element);
881885
break;
882886

887+
case T_InhRelation:
888+
transformInhRelation(pstate, &cxt,
889+
(InhRelation *) element);
890+
break;
891+
883892
default:
884893
elog(ERROR, "parser: unrecognized node (internal error)");
885894
}
@@ -1146,6 +1155,123 @@ transformTableConstraint(ParseState *pstate, CreateStmtContext *cxt,
11461155
}
11471156
}
11481157

1158+
/*
1159+
* transformInhRelation
1160+
*
1161+
* Change the LIKE <subtable> portion of a CREATE TABLE statement into the
1162+
* column definitions which recreate the user defined column portions of <subtable>.
1163+
*/
1164+
static void
1165+
transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
1166+
InhRelation *inhRelation)
1167+
{
1168+
AttrNumber parent_attno;
1169+
1170+
Relation relation;
1171+
TupleDesc tupleDesc;
1172+
TupleConstr *constr;
1173+
AclResult aclresult;
1174+
1175+
relation = heap_openrv(inhRelation->relation, AccessShareLock);
1176+
1177+
if (relation->rd_rel->relkind != RELKIND_RELATION)
1178+
elog(ERROR, "CREATE TABLE: inherited relation \"%s\" is not a table",
1179+
inhRelation->relation->relname);
1180+
1181+
/*
1182+
* Check for SELECT privilages
1183+
*/
1184+
aclresult = pg_class_aclcheck(RelationGetRelid(relation), GetUserId(),
1185+
ACL_SELECT);
1186+
if (aclresult != ACLCHECK_OK)
1187+
aclcheck_error(aclresult, RelationGetRelationName(relation));
1188+
1189+
tupleDesc = RelationGetDescr(relation);
1190+
constr = tupleDesc->constr;
1191+
1192+
/*
1193+
* Insert the inherited attributes into the cxt for the
1194+
* new table definition.
1195+
*/
1196+
for (parent_attno = 1; parent_attno <= tupleDesc->natts;
1197+
parent_attno++)
1198+
{
1199+
Form_pg_attribute attribute = tupleDesc->attrs[parent_attno - 1];
1200+
char *attributeName = NameStr(attribute->attname);
1201+
ColumnDef *def;
1202+
TypeName *typename;
1203+
1204+
/*
1205+
* Ignore dropped columns in the parent.
1206+
*/
1207+
if (attribute->attisdropped)
1208+
continue;
1209+
1210+
/*
1211+
* Create a new inherited column.
1212+
*
1213+
* For constraints, ONLY the NOT NULL constraint is inherited
1214+
* by the new column definition per SQL99.
1215+
*/
1216+
def = makeNode(ColumnDef);
1217+
def->colname = pstrdup(attributeName);
1218+
typename = makeNode(TypeName);
1219+
typename->typeid = attribute->atttypid;
1220+
typename->typmod = attribute->atttypmod;
1221+
def->typename = typename;
1222+
def->inhcount = 0;
1223+
def->is_local = false;
1224+
def->is_not_null = attribute->attnotnull;
1225+
def->raw_default = NULL;
1226+
def->cooked_default = NULL;
1227+
def->constraints = NIL;
1228+
def->support = NULL;
1229+
1230+
/*
1231+
* Add to column list
1232+
*/
1233+
cxt->columns = lappend(cxt->columns, def);
1234+
1235+
/*
1236+
* Copy default if any, and the default has been requested
1237+
*/
1238+
if (attribute->atthasdef && inhRelation->including_defaults)
1239+
{
1240+
char *this_default = NULL;
1241+
AttrDefault *attrdef;
1242+
int i;
1243+
1244+
/* Find default in constraint structure */
1245+
Assert(constr != NULL);
1246+
attrdef = constr->defval;
1247+
for (i = 0; i < constr->num_defval; i++)
1248+
{
1249+
if (attrdef[i].adnum == parent_attno)
1250+
{
1251+
this_default = attrdef[i].adbin;
1252+
break;
1253+
}
1254+
}
1255+
Assert(this_default != NULL);
1256+
1257+
/*
1258+
* If default expr could contain any vars, we'd need to
1259+
* fix 'em, but it can't; so default is ready to apply to
1260+
* child.
1261+
*/
1262+
1263+
def->cooked_default = pstrdup(this_default);
1264+
}
1265+
}
1266+
1267+
/*
1268+
* Close the parent rel, but keep our AccessShareLock on it until
1269+
* xact commit. That will prevent someone else from deleting or
1270+
* ALTERing the parent before the child is committed.
1271+
*/
1272+
heap_close(relation, NoLock);
1273+
}
1274+
11491275
static void
11501276
transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
11511277
{

src/backend/parser/gram.y

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.418 2003/06/24 23:14:43 momjian Exp $
14+
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.419 2003/06/25 03:40:18 momjian Exp $
1515
*
1616
* HISTORY
1717
* AUTHOR DATE MAJOR EVENT
@@ -165,6 +165,8 @@ static void doNegateFloat(Value *v);
165165
%type <boolean> opt_force opt_or_replace transaction_access_mode
166166
opt_grant_grant_option opt_revoke_grant_option
167167

168+
%type <boolean> like_including_defaults
169+
168170
%type <list> user_list
169171

170172
%type <list> OptGroupList
@@ -336,11 +338,11 @@ static void doNegateFloat(Value *v);
336338
CREATEUSER CROSS CURRENT_DATE CURRENT_TIME
337339
CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
338340

339-
DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT
341+
DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
340342
DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS
341343
DESC DISTINCT DO DOMAIN_P DOUBLE_P DROP
342344

343-
EACH ELSE ENCODING ENCRYPTED END_P ESCAPE EXCEPT
345+
EACH ELSE ENCODING ENCRYPTED END_P ESCAPE EXCEPT EXCLUDING
344346
EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
345347

346348
FALSE_P FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD
@@ -350,7 +352,7 @@ static void doNegateFloat(Value *v);
350352

351353
HANDLER HAVING HOLD HOUR_P
352354

353-
ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCREMENT
355+
ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING INCREMENT
354356
INDEX INHERITS INITIALLY INNER_P INOUT INPUT_P
355357
INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT
356358
INTERVAL INTO INVOKER IS ISNULL ISOLATION
@@ -1642,18 +1644,31 @@ ConstraintAttr:
16421644
;
16431645

16441646

1645-
/* SQL99 supports wholesale borrowing of a table definition via the LIKE clause.
1647+
/*
1648+
* SQL99 supports wholesale borrowing of a table definition via the LIKE clause.
16461649
* This seems to be a poor man's inheritance capability, with the resulting
16471650
* tables completely decoupled except for the original commonality in definitions.
1648-
* Seems to have much in common with CREATE TABLE AS. - thomas 2002-06-19
1651+
*
1652+
* This is very similar to CREATE TABLE AS except for the INCLUDING DEFAULTS extension
1653+
* which is a part of SQL 200N
16491654
*/
1650-
TableLikeClause: LIKE any_name
1655+
TableLikeClause:
1656+
LIKE qualified_name like_including_defaults
16511657
{
1652-
elog(ERROR, "LIKE in table definitions not yet supported");
1653-
$$ = NULL;
1658+
InhRelation *n = makeNode(InhRelation);
1659+
n->relation = $2;
1660+
n->including_defaults = $3;
1661+
1662+
$$ = (Node *)n;
16541663
}
16551664
;
16561665

1666+
like_including_defaults:
1667+
INCLUDING DEFAULTS { $$ = true; }
1668+
| EXCLUDING DEFAULTS { $$ = false; }
1669+
| /* EMPTY */ { $$ = false; }
1670+
;
1671+
16571672

16581673
/* ConstraintElem specifies constraint syntax which is not embedded into
16591674
* a column definition. ColConstraintElem specifies the embedded form.
@@ -7230,6 +7245,7 @@ unreserved_keyword:
72307245
| DAY_P
72317246
| DEALLOCATE
72327247
| DECLARE
7248+
| DEFAULTS
72337249
| DEFERRED
72347250
| DEFINER
72357251
| DELETE_P
@@ -7242,6 +7258,7 @@ unreserved_keyword:
72427258
| ENCODING
72437259
| ENCRYPTED
72447260
| ESCAPE
7261+
| EXCLUDING
72457262
| EXCLUSIVE
72467263
| EXECUTE
72477264
| EXPLAIN
@@ -7258,6 +7275,7 @@ unreserved_keyword:
72587275
| IMMEDIATE
72597276
| IMMUTABLE
72607277
| IMPLICIT_P
7278+
| INCLUDING
72617279
| INCREMENT
72627280
| INDEX
72637281
| INHERITS

0 commit comments

Comments
 (0)