]> granicus.if.org Git - postgresql/commitdiff
Includes:
authorBruce Momjian <bruce@momjian.us>
Wed, 25 Jun 2003 03:40:19 +0000 (03:40 +0000)
committerBruce Momjian <bruce@momjian.us>
Wed, 25 Jun 2003 03:40:19 +0000 (03:40 +0000)
- 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>

12 files changed:
contrib/Makefile
src/backend/catalog/sql_features.txt
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/parser/analyze.c
src/backend/parser/gram.y
src/backend/parser/keywords.c
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h
src/test/regress/expected/inherit.out
src/test/regress/output/misc.source
src/test/regress/sql/inherit.sql

index 0f27d904139802370082cfd6546bdfcf11fb2778..567accc28db71b7951e5114018b9afccc1d3e937 100644 (file)
@@ -1,4 +1,4 @@
-# $Header: /cvsroot/pgsql/contrib/Makefile,v 1.41 2003/03/20 18:14:46 momjian Exp $
+# $Header: /cvsroot/pgsql/contrib/Makefile,v 1.42 2003/06/25 03:40:17 momjian Exp $
 
 subdir = contrib
 top_builddir = ..
@@ -13,7 +13,6 @@ WANTED_DIRS = \
                dblink          \
                dbmirror        \
                dbsize          \
-               earthdistance   \
                findoidjoins    \
                fulltextindex   \
                fuzzystrmatch   \
index 3beaae1ecc0ecba6e684105c450eed583653f0bb..0fe363db5a6c2db7aff5049e30dd9c1c5d04ac76 100644 (file)
@@ -308,7 +308,7 @@ T121        WITH (excluding RECURSIVE) in query expression                  NO
 T131   Recursive query                 NO      
 T141   SIMILAR predicate                       YES     
 T151   DISTINCT predicate                      YES     
-T171   LIKE clause in table definition                 NO      
+T171   LIKE clause in table definition                 YES     
 T191   Referential action RESTRICT                     YES     
 T201   Comparable data types for referential constraints                       YES     
 T211   Basic trigger capability                        NO      
index b5e5b112725c06ba9e69db48d8b00c3e48d40542..ecc9703b7c52844af9eb99b3961473d6d4b11ef8 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.253 2003/06/24 23:14:43 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.254 2003/06/25 03:40:17 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1731,6 +1731,17 @@ _copyCreateStmt(CreateStmt *from)
        return newnode;
 }
 
+static InhRelation *
+_copyInhRelation(InhRelation *from)
+{
+       InhRelation *newnode = makeNode(InhRelation);
+
+       COPY_NODE_FIELD(relation);
+       COPY_SCALAR_FIELD(including_defaults);
+
+       return newnode;
+}
+
 static DefineStmt *
 _copyDefineStmt(DefineStmt *from)
 {
@@ -2693,6 +2704,9 @@ copyObject(void *from)
                case T_CreateStmt:
                        retval = _copyCreateStmt(from);
                        break;
+               case T_InhRelation:
+                       retval = _copyInhRelation(from);
+                       break;
                case T_DefineStmt:
                        retval = _copyDefineStmt(from);
                        break;
index 23c1018968d32634e272c156d662c5c8bb183015..0e46d46ea1b756c8732a231f949f180f1755735d 100644 (file)
@@ -18,7 +18,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.196 2003/06/24 23:14:43 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.197 2003/06/25 03:40:17 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -785,6 +785,15 @@ _equalCreateStmt(CreateStmt *a, CreateStmt *b)
        return true;
 }
 
+static bool
+_equalInhRelation(InhRelation *a, InhRelation *b)
+{
+       COMPARE_NODE_FIELD(relation);
+       COMPARE_SCALAR_FIELD(including_defaults);
+
+       return true;
+}
+
 static bool
 _equalDefineStmt(DefineStmt *a, DefineStmt *b)
 {
@@ -1807,6 +1816,9 @@ equal(void *a, void *b)
                case T_CreateStmt:
                        retval = _equalCreateStmt(a, b);
                        break;
+               case T_InhRelation:
+                       retval = _equalInhRelation(a,b);
+                       break;
                case T_DefineStmt:
                        retval = _equalDefineStmt(a, b);
                        break;
index 3f4cb22cdf7f435824e6302d69a03b4200e4ad1c..6476b09f99ba7147d7d885cf288641ba7c5957c7 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *     $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.275 2003/06/16 02:03:37 tgl Exp $
+ *     $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.276 2003/06/25 03:40:17 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -21,6 +21,7 @@
 #include "catalog/pg_index.h"
 #include "catalog/pg_type.h"
 #include "commands/prepare.h"
+#include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/var.h"
@@ -37,6 +38,7 @@
 #include "parser/parse_type.h"
 #include "parser/parse_expr.h"
 #include "rewrite/rewriteManip.h"
+#include "utils/acl.h"
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
 #include "utils/lsyscache.h"
@@ -112,13 +114,15 @@ static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt,
 static Query *transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt,
                                                List **extras_before, List **extras_after);
 static void transformColumnDefinition(ParseState *pstate,
-                                                 CreateStmtContext *cxt,
-                                                 ColumnDef *column);
+                                                                         CreateStmtContext *cxt,
+                                                                         ColumnDef *column);
 static void transformTableConstraint(ParseState *pstate,
-                                                CreateStmtContext *cxt,
-                                                Constraint *constraint);
+                                                                        CreateStmtContext *cxt,
+                                                                        Constraint *constraint);
+static void transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
+                                                                InhRelation *inhrelation);
 static void transformIndexConstraints(ParseState *pstate,
-                                                 CreateStmtContext *cxt);
+                                                                         CreateStmtContext *cxt);
 static void transformFKConstraints(ParseState *pstate,
                                                                   CreateStmtContext *cxt,
                                                                   bool isAddConstraint);
@@ -880,6 +884,11 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt,
                                cxt.fkconstraints = lappend(cxt.fkconstraints, element);
                                break;
 
+                       case T_InhRelation:
+                               transformInhRelation(pstate, &cxt,
+                                                                        (InhRelation *) element);
+                               break;
+
                        default:
                                elog(ERROR, "parser: unrecognized node (internal error)");
                }
@@ -1146,6 +1155,123 @@ transformTableConstraint(ParseState *pstate, CreateStmtContext *cxt,
        }
 }
 
+/*
+ * transformInhRelation
+ *
+ * Change the LIKE <subtable> portion of a CREATE TABLE statement into the
+ * column definitions which recreate the user defined column portions of <subtable>.
+ */
+static void
+transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
+                                        InhRelation *inhRelation)
+{
+       AttrNumber      parent_attno;
+
+       Relation        relation;
+       TupleDesc       tupleDesc;
+       TupleConstr *constr;
+       AclResult       aclresult;
+
+       relation = heap_openrv(inhRelation->relation, AccessShareLock);
+
+       if (relation->rd_rel->relkind != RELKIND_RELATION)
+               elog(ERROR, "CREATE TABLE: inherited relation \"%s\" is not a table",
+                        inhRelation->relation->relname);
+
+       /*
+        * Check for SELECT privilages 
+        */
+       aclresult = pg_class_aclcheck(RelationGetRelid(relation), GetUserId(),
+                                                                 ACL_SELECT);
+       if (aclresult != ACLCHECK_OK)
+               aclcheck_error(aclresult, RelationGetRelationName(relation));
+
+       tupleDesc = RelationGetDescr(relation);
+       constr = tupleDesc->constr;
+
+       /*
+        * Insert the inherited attributes into the cxt for the
+        * new table definition.
+        */
+       for (parent_attno = 1; parent_attno <= tupleDesc->natts;
+                parent_attno++)
+       {
+               Form_pg_attribute attribute = tupleDesc->attrs[parent_attno - 1];
+               char       *attributeName = NameStr(attribute->attname);
+               ColumnDef  *def;
+               TypeName   *typename;
+
+               /*
+                * Ignore dropped columns in the parent.
+                */
+               if (attribute->attisdropped)
+                       continue;
+
+               /*
+                * Create a new inherited column.
+                *
+                * For constraints, ONLY the NOT NULL constraint is inherited
+                * by the new column definition per SQL99.
+                */
+               def = makeNode(ColumnDef);
+               def->colname = pstrdup(attributeName);
+               typename = makeNode(TypeName);
+               typename->typeid = attribute->atttypid;
+               typename->typmod = attribute->atttypmod;
+               def->typename = typename;
+               def->inhcount = 0;
+               def->is_local = false;
+               def->is_not_null = attribute->attnotnull;
+               def->raw_default = NULL;
+               def->cooked_default = NULL;
+               def->constraints = NIL;
+               def->support = NULL;
+
+               /*
+                * Add to column list
+                */
+               cxt->columns = lappend(cxt->columns, def);
+
+               /*
+                * Copy default if any, and the default has been requested
+                */
+               if (attribute->atthasdef && inhRelation->including_defaults)
+               {
+                       char       *this_default = NULL;
+                       AttrDefault *attrdef;
+                       int                     i;
+
+                       /* Find default in constraint structure */
+                       Assert(constr != NULL);
+                       attrdef = constr->defval;
+                       for (i = 0; i < constr->num_defval; i++)
+                       {
+                               if (attrdef[i].adnum == parent_attno)
+                               {
+                                       this_default = attrdef[i].adbin;
+                                       break;
+                               }
+                       }
+                       Assert(this_default != NULL);
+
+                       /*
+                        * If default expr could contain any vars, we'd need to
+                        * fix 'em, but it can't; so default is ready to apply to
+                        * child.
+                        */
+
+                       def->cooked_default = pstrdup(this_default);
+               }
+       }
+
+       /*
+        * Close the parent rel, but keep our AccessShareLock on it until
+        * xact commit.  That will prevent someone else from deleting or
+        * ALTERing the parent before the child is committed.
+        */
+       heap_close(relation, NoLock);
+}
+
 static void
 transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
 {
index e4cf67eca3679ec1a07dde76db94be496d84b5f0..9806d65888907a09ce2dc9764c6934cb8cb7dbb3 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.418 2003/06/24 23:14:43 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.419 2003/06/25 03:40:18 momjian Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -165,6 +165,8 @@ static void doNegateFloat(Value *v);
 %type <boolean>        opt_force opt_or_replace transaction_access_mode
                                opt_grant_grant_option opt_revoke_grant_option
 
+%type <boolean>        like_including_defaults
+
 %type <list>   user_list
 
 %type <list>   OptGroupList
@@ -336,11 +338,11 @@ static void doNegateFloat(Value *v);
        CREATEUSER CROSS CURRENT_DATE CURRENT_TIME
        CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
 
-       DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT
+       DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
        DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS
     DESC DISTINCT DO DOMAIN_P DOUBLE_P DROP
 
-       EACH ELSE ENCODING ENCRYPTED END_P ESCAPE EXCEPT
+       EACH ELSE ENCODING ENCRYPTED END_P ESCAPE EXCEPT EXCLUDING
        EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
 
        FALSE_P FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD
@@ -350,7 +352,7 @@ static void doNegateFloat(Value *v);
 
        HANDLER HAVING HOLD HOUR_P
 
-       ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCREMENT
+       ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING INCREMENT
        INDEX INHERITS INITIALLY INNER_P INOUT INPUT_P
        INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT
        INTERVAL INTO INVOKER IS ISNULL ISOLATION
@@ -1642,18 +1644,31 @@ ConstraintAttr:
                ;
 
 
-/* SQL99 supports wholesale borrowing of a table definition via the LIKE clause.
+/*
+ * SQL99 supports wholesale borrowing of a table definition via the LIKE clause.
  * This seems to be a poor man's inheritance capability, with the resulting
  * tables completely decoupled except for the original commonality in definitions.
- * Seems to have much in common with CREATE TABLE AS. - thomas 2002-06-19
+ *
+ * This is very similar to CREATE TABLE AS except for the INCLUDING DEFAULTS extension
+ * which is a part of SQL 200N
  */
-TableLikeClause:  LIKE any_name
+TableLikeClause:
+                       LIKE qualified_name like_including_defaults
                                {
-                                       elog(ERROR, "LIKE in table definitions not yet supported");
-                                       $$ = NULL;
+                                       InhRelation *n = makeNode(InhRelation);
+                                       n->relation = $2;
+                                       n->including_defaults = $3;
+
+                                       $$ = (Node *)n;
                                }
                ;
 
+like_including_defaults:
+                               INCLUDING DEFAULTS              { $$ = true; }
+                               | EXCLUDING DEFAULTS            { $$ = false; }
+                               | /* EMPTY */                           { $$ = false; }
+               ;
+
 
 /* ConstraintElem specifies constraint syntax which is not embedded into
  *     a column definition. ColConstraintElem specifies the embedded form.
@@ -7230,6 +7245,7 @@ unreserved_keyword:
                        | DAY_P
                        | DEALLOCATE
                        | DECLARE
+                       | DEFAULTS
                        | DEFERRED
                        | DEFINER
                        | DELETE_P
@@ -7242,6 +7258,7 @@ unreserved_keyword:
                        | ENCODING
                        | ENCRYPTED
                        | ESCAPE
+                       | EXCLUDING
                        | EXCLUSIVE
                        | EXECUTE
                        | EXPLAIN
@@ -7258,6 +7275,7 @@ unreserved_keyword:
                        | IMMEDIATE
                        | IMMUTABLE
                        | IMPLICIT_P
+                       | INCLUDING
                        | INCREMENT
                        | INDEX
                        | INHERITS
index b035a828f32a8ac77c771373d440108ef0411864..ea7a3252485c1ba2ab2dd5e97488887c41477e22 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.139 2003/05/15 16:35:28 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.140 2003/06/25 03:40:18 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -102,6 +102,7 @@ static const ScanKeyword ScanKeywords[] = {
        {"decimal", DECIMAL_P},
        {"declare", DECLARE},
        {"default", DEFAULT},
+       {"defaults", DEFAULTS},
        {"deferrable", DEFERRABLE},
        {"deferred", DEFERRED},
        {"definer", DEFINER},
@@ -121,6 +122,7 @@ static const ScanKeyword ScanKeywords[] = {
        {"end", END_P},
        {"escape", ESCAPE},
        {"except", EXCEPT},
+       {"excluding", EXCLUDING},
        {"exclusive", EXCLUSIVE},
        {"execute", EXECUTE},
        {"exists", EXISTS},
@@ -151,6 +153,7 @@ static const ScanKeyword ScanKeywords[] = {
        {"immutable", IMMUTABLE},
        {"implicit", IMPLICIT_P},
        {"in", IN_P},
+       {"including", INCLUDING},
        {"increment", INCREMENT},
        {"index", INDEX},
        {"inherits", INHERITS},
index bed4b1e781a3577a5addb6cdc05cef9752b778f1..a6c2c0221411c3bf7e16c7c429575389c59a0c88 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: nodes.h,v 1.140 2003/04/08 23:20:04 tgl Exp $
+ * $Id: nodes.h,v 1.141 2003/06/25 03:40:19 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -280,6 +280,7 @@ typedef enum NodeTag
        T_InsertDefault,
        T_CreateOpClassItem,
        T_CompositeTypeStmt,
+       T_InhRelation,
 
        /*
         * TAGS FOR FUNCTION-CALL CONTEXT AND RESULTINFO NODES (see fmgr.h)
index 25d719dd8fc57d8e7bfc133ced23aa5a32c51001..772e4341721bd027f5c53efac6f192d42c10d7bd 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.238 2003/05/28 16:04:02 tgl Exp $
+ * $Id: parsenodes.h,v 1.239 2003/06/25 03:40:19 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -350,6 +350,16 @@ typedef struct ColumnDef
        RangeVar   *support;            /* supporting relation, if any */
 } ColumnDef;
 
+/*
+ * inhRelation - Relations a CREATE TABLE is to inherit attributes of
+ */
+typedef struct InhRelation
+{
+       NodeTag         type;
+       RangeVar   *relation;
+       bool            including_defaults;
+} InhRelation;
+
 /*
  * IndexElem - index parameters (used in CREATE INDEX)
  *
@@ -851,7 +861,7 @@ typedef struct CreateStmt
        NodeTag         type;
        RangeVar   *relation;           /* relation to create */
        List       *tableElts;          /* column definitions (list of ColumnDef) */
-       List       *inhRelations;       /* relations to inherit from */
+       List       *inhRelations;       /* relations to inherit from (list of inhRelation) */
        List       *constraints;        /* constraints (list of Constraint nodes) */
        bool            hasoids;                /* should it have OIDs? */
        OnCommitAction oncommit;        /* what do we do at COMMIT? */
index e6fc8bcb575f71d675ec48e0c29048f66ba252f8..aa2d03d165ae78db3ca37d109ad124a8cf422374 100644 (file)
@@ -570,3 +570,46 @@ SELECT relname, bar.* FROM bar, pg_class where bar.tableoid = pg_class.oid;
  bar2    |  3 | 103
 (8 rows)
 
+/* Test inheritance of structure (LIKE) */
+CREATE TABLE inhx (xx text DEFAULT 'text');
+/*
+ * Test double inheritance
+ *
+ * Ensure that defaults are NOT included unless
+ * INCLUDING DEFAULTS is specified 
+ */
+CREATE TABLE inhe (ee text, LIKE inhx) inherits (b);
+INSERT INTO inhe VALUES ('ee-col1', 'ee-col2', DEFAULT, 'ee-col4');
+SELECT * FROM inhe; /* Columns aa, bb, xx value NULL, ee */
+   aa    |   bb    | ee |   xx    
+---------+---------+----+---------
+ ee-col1 | ee-col2 |    | ee-col4
+(1 row)
+
+SELECT * FROM inhx; /* Empty set since LIKE inherits structure only */
+ xx 
+----
+(0 rows)
+
+SELECT * FROM b; /* Has ee entry */
+   aa    |   bb    
+---------+---------
+ ee-col1 | ee-col2
+(1 row)
+
+SELECT * FROM a; /* Has ee entry */
+   aa    
+---------
+ ee-col1
+(1 row)
+
+CREATE TABLE inhf (LIKE inhx, LIKE inhx); /* Throw error */
+ERROR:  CREATE TABLE: attribute "xx" duplicated
+CREATE TABLE inhf (LIKE inhx INCLUDING DEFAULTS);
+INSERT INTO inhf DEFAULT VALUES;
+SELECT * FROM inhf; /* Single entry with value 'text' */
+  xx  
+------
+ text
+(1 row)
+
index 7b8016229fb147a85b3b8063dcf6d4b2dc592574..e52d71d232180c1228ee436eb7147d43a47d65ec 100644 (file)
@@ -609,6 +609,9 @@ SELECT user_relns() AS user_relns
  iexit
  ihighway
  inet_tbl
+ inhe
+ inhf
+ inhx
  insert_seq
  insert_tbl
  int2_tbl
@@ -657,7 +660,7 @@ SELECT user_relns() AS user_relns
  toyemp
  varchar_tbl
  xacttest
-(93 rows)
+(96 rows)
 
 --SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer'))) AS equip_name;
 SELECT hobbies_by_name('basketball');
index a50b5e75f93b729d5a9448ca6308e613bf87e462..57f18673bfa92a53491ad56e17575a2874775698 100644 (file)
@@ -119,3 +119,26 @@ insert into bar2 values(4,4,4);
 update bar set f2 = f2 + 100 where f1 in (select f1 from foo);
 
 SELECT relname, bar.* FROM bar, pg_class where bar.tableoid = pg_class.oid;
+
+
+/* Test inheritance of structure (LIKE) */
+CREATE TABLE inhx (xx text DEFAULT 'text');
+
+/*
+ * Test double inheritance
+ *
+ * Ensure that defaults are NOT included unless
+ * INCLUDING DEFAULTS is specified 
+ */
+CREATE TABLE inhe (ee text, LIKE inhx) inherits (b);
+INSERT INTO inhe VALUES ('ee-col1', 'ee-col2', DEFAULT, 'ee-col4');
+SELECT * FROM inhe; /* Columns aa, bb, xx value NULL, ee */
+SELECT * FROM inhx; /* Empty set since LIKE inherits structure only */
+SELECT * FROM b; /* Has ee entry */
+SELECT * FROM a; /* Has ee entry */
+
+CREATE TABLE inhf (LIKE inhx, LIKE inhx); /* Throw error */
+
+CREATE TABLE inhf (LIKE inhx INCLUDING DEFAULTS);
+INSERT INTO inhf DEFAULT VALUES;
+SELECT * FROM inhf; /* Single entry with value 'text' */