When a TIMESTAMP, TIME, or INTERVAL precision is specified larger than our
authorTom Lane
Sun, 4 May 2003 00:03:55 +0000 (00:03 +0000)
committerTom Lane
Sun, 4 May 2003 00:03:55 +0000 (00:03 +0000)
implementation limits, do not issue an ERROR; instead issue a NOTICE and use
the max supported value.  Per pgsql-general discussion of 28-Apr, this is
needed to allow easy porting from pre-7.3 releases where the limits were
higher.

Unrelated change in same area: accept GLOBAL TEMP/TEMPORARY as a synonym
for TEMPORARY, as per pgsql-hackers discussion of 15-Apr.  We previously
rejected it, but that was based on a misreading of the spec --- SQL92's
GLOBAL temp tables are really closer to what we have than their LOCAL ones.

doc/src/sgml/ref/create_table.sgml
doc/src/sgml/ref/create_table_as.sgml
src/backend/parser/gram.y

index c95baad4175959d73ed6c29a3def39a4b01dac87..9a29b645aae843dda0964acd0acf8fe59c9049a5 100644 (file)
@@ -1,5 +1,5 @@
 
 
@@ -16,7 +16,7 @@ PostgreSQL documentation
 
  
 
-CREATE [ [ LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name (
+CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name (
     { column_name data_type [ DEFAULT default_expr ] [ column_constraint [, ... ] ]
     | table_constraint }  [, ... ]
 )
@@ -101,7 +101,7 @@ and table_constraint is:
   
 
    
-    [LOCAL] TEMPORARY or [LOCAL] TEMP
+    TEMPORARY or TEMP
     
      
       If specified, the table is created as a temporary table.
@@ -115,7 +115,9 @@ and table_constraint is:
      
 
      
-      The LOCAL word is optional.  But see under
+      Optionally, GLOBAL or LOCAL
+      can be written before TEMPORARY or TEMP.
+      This makes no difference in PostgreSQL, but see
       
       endterm="sql-createtable-compatibility-title">.
      
@@ -195,7 +197,7 @@ and table_constraint is:
      
 
 
@@ -16,7 +16,7 @@ PostgreSQL documentation
 
  
 
-CREATE [ [ LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name [ (column_name [, ...] ) ]
+CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name [ (column_name [, ...] ) ]
     AS query
 
  
@@ -49,7 +49,7 @@ CREATE [ [ LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name
    
   
    
-    [LOCAL] TEMPORARY or [LOCAL] TEMP
+    TEMPORARY or TEMP
     
      
       If specified, the table is created as a temporary table.
index bd67dae811f720193c4dd6264f8b131011880015..4f8b0b10fc9a54a04b67c19b950469d37a7e9490 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.412 2003/04/29 03:21:29 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.413 2003/05/04 00:03:55 tgl Exp $
  *
  * HISTORY
  *   AUTHOR            DATE            MAJOR EVENT
@@ -964,10 +964,17 @@ zone_value:
            | ConstInterval '(' Iconst ')' Sconst opt_interval
                {
                    A_Const *n = (A_Const *) makeStringConst($5, $1);
-                   if (($3 < 0) || ($3 > MAX_INTERVAL_PRECISION))
+                   if ($3 < 0)
                        elog(ERROR,
-                           "INTERVAL(%d) precision must be between %d and %d",
-                           $3, 0, MAX_INTERVAL_PRECISION);
+                            "INTERVAL(%d) precision must not be negative",
+                            $3);
+                   if ($3 > MAX_INTERVAL_PRECISION)
+                   {
+                       elog(NOTICE,
+                            "INTERVAL(%d) precision reduced to maximum allowed, %d",
+                            $3, MAX_INTERVAL_PRECISION);
+                       $3 = MAX_INTERVAL_PRECISION;
+                   }
 
                    if (($6 != INTERVAL_FULL_RANGE)
                        && (($6 & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0))
@@ -1414,23 +1421,16 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
 /*
  * Redundancy here is needed to avoid shift/reduce conflicts,
  * since TEMP is not a reserved word.  See also OptTempTableName.
+ *
+ * NOTE: we accept both GLOBAL and LOCAL options; since we have no modules
+ * the LOCAL keyword is really meaningless.
  */
 OptTemp:   TEMPORARY                       { $$ = TRUE; }
            | TEMP                          { $$ = TRUE; }
            | LOCAL TEMPORARY               { $$ = TRUE; }
            | LOCAL TEMP                    { $$ = TRUE; }
-           | GLOBAL TEMPORARY
-               {
-                   elog(ERROR,
-                   "GLOBAL TEMPORARY TABLE is not currently supported");
-                   $$ = TRUE;
-               }
-           | GLOBAL TEMP
-               {
-                   elog(ERROR,
-                   "GLOBAL TEMPORARY TABLE is not currently supported");
-                   $$ = TRUE;
-               }
+           | GLOBAL TEMPORARY              { $$ = TRUE; }
+           | GLOBAL TEMP                   { $$ = TRUE; }
            | /*EMPTY*/                     { $$ = FALSE; }
        ;
 
@@ -1466,8 +1466,8 @@ columnDef:    ColId Typename ColQualList opt_collate
 
                    if ($4 != NULL)
                        elog(NOTICE,
-                           "CREATE TABLE / COLLATE %s not yet implemented; "
-                           "clause ignored", $4);
+                            "CREATE TABLE / COLLATE %s not yet implemented; "
+                            "clause ignored", $4);
 
                    $$ = (Node *)n;
                }
@@ -3240,7 +3240,7 @@ RemoveOperStmt:
 oper_argtypes:
            Typename
                {
-                  elog(ERROR,"parser: argument type missing (use NONE for unary operators)");
+                  elog(ERROR, "parser: argument type missing (use NONE for unary operators)");
                }
            | Typename ',' Typename
                    { $$ = makeList2($1, $3); }
@@ -3768,7 +3768,7 @@ CreateDomainStmt:
 
                    if ($7 != NULL)
                        elog(NOTICE,"CREATE DOMAIN / COLLATE %s not yet "
-                           "implemented; clause ignored", $7);
+                            "implemented; clause ignored", $7);
                    $$ = (Node *)n;
                }
        ;
@@ -4426,15 +4426,11 @@ OptTempTableName:
                }
            | GLOBAL TEMPORARY opt_table qualified_name
                {
-                   elog(ERROR,
-                       "GLOBAL TEMPORARY TABLE is not currently supported");
                    $$ = $4;
                    $$->istemp = true;
                }
            | GLOBAL TEMP opt_table qualified_name
                {
-                   elog(ERROR,
-                       "GLOBAL TEMPORARY TABLE is not currently supported");
                    $$ = $4;
                    $$->istemp = true;
                }
@@ -5031,10 +5027,17 @@ SimpleTypename:
            | ConstInterval '(' Iconst ')' opt_interval
                {
                    $$ = $1;
-                   if (($3 < 0) || ($3 > MAX_INTERVAL_PRECISION))
+                   if ($3 < 0)
                        elog(ERROR,
-                       "INTERVAL(%d) precision must be between %d and %d",
-                            $3, 0, MAX_INTERVAL_PRECISION);
+                            "INTERVAL(%d) precision must not be negative",
+                            $3);
+                   if ($3 > MAX_INTERVAL_PRECISION)
+                   {
+                       elog(NOTICE,
+                            "INTERVAL(%d) precision reduced to maximum allowed, %d",
+                            $3, MAX_INTERVAL_PRECISION);
+                       $3 = MAX_INTERVAL_PRECISION;
+                   }
                    $$->typmod = INTERVAL_TYPMOD($3, $5);
                }
            | type_name attrs
@@ -5390,11 +5393,18 @@ ConstDatetime:
                     * - thomas 2001-09-06
                     */
                    $$->timezone = $5;
-                   if (($3 < 0) || ($3 > MAX_TIMESTAMP_PRECISION))
+                   if ($3 < 0)
                        elog(ERROR,
-                       "TIMESTAMP(%d)%s precision must be between %d and %d",
-                            $3, ($5 ? " WITH TIME ZONE": ""), 0,
+                            "TIMESTAMP(%d)%s precision must not be negative",
+                            $3, ($5 ? " WITH TIME ZONE": ""));
+                   if ($3 > MAX_TIMESTAMP_PRECISION)
+                   {
+                       elog(NOTICE,
+                            "TIMESTAMP(%d)%s precision reduced to maximum allowed, %d",
+                            $3, ($5 ? " WITH TIME ZONE": ""),
                             MAX_TIMESTAMP_PRECISION);
+                       $3 = MAX_TIMESTAMP_PRECISION;
+                   }
                    $$->typmod = $3;
                }
            | TIMESTAMP opt_timezone
@@ -5422,11 +5432,18 @@ ConstDatetime:
                        $$ = SystemTypeName("timetz");
                    else
                        $$ = SystemTypeName("time");
-                   if (($3 < 0) || ($3 > MAX_TIME_PRECISION))
+                   if ($3 < 0)
                        elog(ERROR,
-                       "TIME(%d)%s precision must be between %d and %d",
-                            $3, ($5 ? " WITH TIME ZONE": ""), 0,
+                            "TIME(%d)%s precision must not be negative",
+                            $3, ($5 ? " WITH TIME ZONE": ""));
+                   if ($3 > MAX_TIME_PRECISION)
+                   {
+                       elog(NOTICE,
+                            "TIME(%d)%s precision reduced to maximum allowed, %d",
+                            $3, ($5 ? " WITH TIME ZONE": ""),
                             MAX_TIME_PRECISION);
+                       $3 = MAX_TIME_PRECISION;
+                   }
                    $$->typmod = $3;
                }
            | TIME opt_timezone
@@ -6218,10 +6235,17 @@ c_expr:     columnref                               { $$ = (Node *) $1; }
                    s->val.val.str = "now";
                    s->typename = SystemTypeName("text");
                    d = SystemTypeName("timetz");
-                   if (($3 < 0) || ($3 > MAX_TIME_PRECISION))
+                   if ($3 < 0)
                        elog(ERROR,
-                       "CURRENT_TIME(%d) precision must be between %d and %d",
-                            $3, 0, MAX_TIME_PRECISION);
+                            "CURRENT_TIME(%d) precision must not be negative",
+                            $3);
+                   if ($3 > MAX_TIME_PRECISION)
+                   {
+                       elog(NOTICE,
+                            "CURRENT_TIME(%d) precision reduced to maximum allowed, %d",
+                            $3, MAX_TIME_PRECISION);
+                       $3 = MAX_TIME_PRECISION;
+                   }
                    d->typmod = $3;
 
                    $$ = (Node *)makeTypeCast((Node *)s, d);
@@ -6263,11 +6287,17 @@ c_expr:     columnref                               { $$ = (Node *) $1; }
                    s->typename = SystemTypeName("text");
 
                    d = SystemTypeName("timestamptz");
-                   if (($3 < 0) || ($3 > MAX_TIMESTAMP_PRECISION))
+                   if ($3 < 0)
                        elog(ERROR,
-                       "CURRENT_TIMESTAMP(%d) precision "
-                       "must be between %d and %d",
-                            $3, 0, MAX_TIMESTAMP_PRECISION);
+                            "CURRENT_TIMESTAMP(%d) precision must not be negative",
+                            $3);
+                   if ($3 > MAX_TIMESTAMP_PRECISION)
+                   {
+                       elog(NOTICE,
+                            "CURRENT_TIMESTAMP(%d) precision reduced to maximum allowed, %d",
+                            $3, MAX_TIMESTAMP_PRECISION);
+                       $3 = MAX_TIMESTAMP_PRECISION;
+                   }
                    d->typmod = $3;
 
                    $$ = (Node *)makeTypeCast((Node *)s, d);
@@ -6308,10 +6338,17 @@ c_expr:     columnref                               { $$ = (Node *) $1; }
                    s->val.val.str = "now";
                    s->typename = SystemTypeName("text");
                    d = SystemTypeName("time");
-                   if (($3 < 0) || ($3 > MAX_TIME_PRECISION))
+                   if ($3 < 0)
                        elog(ERROR,
-                       "LOCALTIME(%d) precision must be between %d and %d",
-                            $3, 0, MAX_TIME_PRECISION);
+                            "LOCALTIME(%d) precision must not be negative",
+                            $3);
+                   if ($3 > MAX_TIME_PRECISION)
+                   {
+                       elog(NOTICE,
+                            "LOCALTIME(%d) precision reduced to maximum allowed, %d",
+                            $3, MAX_TIME_PRECISION);
+                       $3 = MAX_TIME_PRECISION;
+                   }
                    d->typmod = $3;
 
                    $$ = (Node *)makeTypeCast((Node *)s, d);
@@ -6353,11 +6390,17 @@ c_expr:     columnref                               { $$ = (Node *) $1; }
                    s->typename = SystemTypeName("text");
 
                    d = SystemTypeName("timestamp");
-                   if (($3 < 0) || ($3 > MAX_TIMESTAMP_PRECISION))
+                   if ($3 < 0)
                        elog(ERROR,
-                       "LOCALTIMESTAMP(%d) precision must be "
-                       "between %d and %d",
-                            $3, 0, MAX_TIMESTAMP_PRECISION);
+                            "LOCALTIMESTAMP(%d) precision must not be negative",
+                            $3);
+                   if ($3 > MAX_TIMESTAMP_PRECISION)
+                   {
+                       elog(NOTICE,
+                            "LOCALTIMESTAMP(%d) precision reduced to maximum allowed, %d",
+                            $3, MAX_TIMESTAMP_PRECISION);
+                       $3 = MAX_TIMESTAMP_PRECISION;
+                   }
                    d->typmod = $3;
 
                    $$ = (Node *)makeTypeCast((Node *)s, d);
@@ -6934,8 +6977,8 @@ qualified_name:
                            break;
                        default:
                            elog(ERROR,
-                           "Improper qualified name "
-                           "(too many dotted names): %s",
+                                "Improper qualified name "
+                                "(too many dotted names): %s",
                                 NameListToString($1));
                            break;
                    }
@@ -7038,10 +7081,17 @@ AexprConst: Iconst
                    n->val.type = T_String;
                    n->val.val.str = $5;
                    /* precision specified, and fields may be... */
-                   if (($3 < 0) || ($3 > MAX_INTERVAL_PRECISION))
+                   if ($3 < 0)
                        elog(ERROR,
-                       "INTERVAL(%d) precision must be between %d and %d",
-                            $3, 0, MAX_INTERVAL_PRECISION);
+                            "INTERVAL(%d) precision must not be negative",
+                            $3);
+                   if ($3 > MAX_INTERVAL_PRECISION)
+                   {
+                       elog(NOTICE,
+                           "INTERVAL(%d) precision reduced to maximum allowed, %d",
+                           $3, MAX_INTERVAL_PRECISION);
+                       $3 = MAX_INTERVAL_PRECISION;
+                   }
                    n->typename->typmod = INTERVAL_TYPMOD($3, $6);
                    $$ = (Node *)n;
                }