diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/access/transam/xact.c | 6 | ||||
-rw-r--r-- | src/backend/commands/variable.c | 293 | ||||
-rw-r--r-- | src/backend/nodes/copyfuncs.c | 5 | ||||
-rw-r--r-- | src/backend/nodes/equalfuncs.c | 4 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 151 | ||||
-rw-r--r-- | src/backend/tcop/utility.c | 4 | ||||
-rw-r--r-- | src/backend/utils/adt/date.c | 113 | ||||
-rw-r--r-- | src/backend/utils/adt/datetime.c | 230 | ||||
-rw-r--r-- | src/backend/utils/adt/nabstime.c | 133 | ||||
-rw-r--r-- | src/backend/utils/adt/timestamp.c | 305 | ||||
-rw-r--r-- | src/include/access/xact.h | 4 | ||||
-rw-r--r-- | src/include/catalog/catversion.h | 4 | ||||
-rw-r--r-- | src/include/catalog/pg_proc.h | 10 | ||||
-rw-r--r-- | src/include/commands/variable.h | 4 | ||||
-rw-r--r-- | src/include/nodes/parsenodes.h | 4 | ||||
-rw-r--r-- | src/include/utils/date.h | 3 | ||||
-rw-r--r-- | src/include/utils/nabstime.h | 4 | ||||
-rw-r--r-- | src/include/utils/timestamp.h | 3 | ||||
-rw-r--r-- | src/interfaces/odbc/convert.c | 4 | ||||
-rw-r--r-- | src/test/regress/expected/horology.out | 10 | ||||
-rw-r--r-- | src/test/regress/expected/timestamp.out | 4 | ||||
-rw-r--r-- | src/test/regress/expected/timestamptz.out | 4 | ||||
-rw-r--r-- | src/test/regress/sql/horology.sql | 10 |
23 files changed, 942 insertions, 370 deletions
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index b7e13ec0fc4..cf9791a8e84 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.111 2001/09/29 04:02:21 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.112 2001/10/18 17:30:03 thomas Exp $ * * NOTES * Transaction aborts can now occur two ways: @@ -378,7 +378,7 @@ GetCurrentTransactionStartTimeUsec(int *msec) { TransactionState s = CurrentTransactionState; - *msec = s->startTimeMsec; + *msec = s->startTimeUsec; return s->startTime; } @@ -877,7 +877,7 @@ StartTransaction(void) #if NOT_USED s->startTime = GetCurrentAbsoluteTime(); #endif - s->startTime = GetCurrentAbsoluteTimeUsec(&(s->startTimeMsec)); + s->startTime = GetCurrentAbsoluteTimeUsec(&(s->startTimeUsec)); /* * initialize the various transaction subsystems diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c index 029ea86a2bd..9da67760745 100644 --- a/src/backend/commands/variable.c +++ b/src/backend/commands/variable.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.53 2001/09/19 15:19:12 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.54 2001/10/18 17:30:14 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -27,6 +27,7 @@ #include "optimizer/paths.h" #include "parser/parse_expr.h" #include "utils/builtins.h" +#include "utils/date.h" #include "utils/guc.h" #include "utils/tqual.h" @@ -41,24 +42,24 @@ static bool show_datestyle(void); static bool reset_datestyle(void); -static bool parse_datestyle(char *); +static bool parse_datestyle(List *); static bool show_timezone(void); static bool reset_timezone(void); -static bool parse_timezone(char *); +static bool parse_timezone(List *); static bool show_XactIsoLevel(void); static bool reset_XactIsoLevel(void); -static bool parse_XactIsoLevel(char *); -static bool parse_random_seed(char *); +static bool parse_XactIsoLevel(List *); static bool show_random_seed(void); static bool reset_random_seed(void); +static bool parse_random_seed(List *); static bool show_client_encoding(void); static bool reset_client_encoding(void); -static bool parse_client_encoding(char *); +static bool parse_client_encoding(List *); static bool show_server_encoding(void); static bool reset_server_encoding(void); -static bool parse_server_encoding(char *); +static bool parse_server_encoding(List *); /* @@ -177,7 +178,7 @@ get_token(char **tok, char **val, char *str) /* - * DATE_STYLE + * DATESTYLE * * NOTE: set_default_datestyle() is called during backend startup to check * if the PGDATESTYLE environment variable is set. We want the env var @@ -189,17 +190,14 @@ static int DefaultDateStyle; static bool DefaultEuroDates; static bool -parse_datestyle(char *value) +parse_datestyle_internal(char *value) { char *tok; int dcnt = 0, ecnt = 0; if (value == NULL) - { - reset_datestyle(); - return TRUE; - } + return reset_datestyle(); while ((value = get_token(&tok, NULL, value)) != 0) { @@ -258,6 +256,21 @@ parse_datestyle(char *value) } static bool +parse_datestyle(List *args) +{ + char *value; + + if (args == NULL) + return reset_datestyle(); + + Assert(IsA(lfirst(args), A_Const)); + + value = ((A_Const *) lfirst(args))->val.val.str; + + return parse_datestyle_internal(value); +} + +static bool show_datestyle(void) { char buf[64]; @@ -321,8 +334,11 @@ set_default_datestyle(void) */ DBDate = strdup(DBDate); - /* Parse desired setting into DateStyle/EuroDates */ - parse_datestyle(DBDate); + /* Parse desired setting into DateStyle/EuroDates + * Use parse_datestyle_internal() to avoid any palloc() issues per above + * - thomas 2001-10-15 + */ + parse_datestyle_internal(DBDate); free(DBDate); @@ -348,39 +364,96 @@ static char tzbuf[64]; /* parse_timezone() * Handle SET TIME ZONE... * Try to save existing TZ environment variable for later use in RESET TIME ZONE. - * - thomas 1997-11-10 + * Accept an explicit interval per SQL9x, though this is less useful than a full time zone. + * - thomas 2001-10-11 */ static bool -parse_timezone(char *value) +parse_timezone(List *args) { - char *tok; + List *arg; + TypeName *type; - if (value == NULL) - { - reset_timezone(); - return TRUE; - } + if (args == NULL) + return reset_timezone(); - while ((value = get_token(&tok, NULL, value)) != 0) + Assert(IsA(args, List)); + + foreach(arg, args) { - /* Not yet tried to save original value from environment? */ - if (defaultTZ == NULL) - { - /* found something? then save it for later */ - if ((defaultTZ = getenv("TZ")) != NULL) - strcpy(TZvalue, defaultTZ); + A_Const *p; - /* found nothing so mark with an invalid pointer */ - else - defaultTZ = (char *) -1; - } + Assert(IsA(arg, List)); + p = lfirst(arg); + Assert(IsA(p, A_Const)); - strcpy(tzbuf, "TZ="); - strcat(tzbuf, tok); - if (putenv(tzbuf) != 0) - elog(ERROR, "Unable to set TZ environment variable to %s", tok); + type = p->typename; + if (type != NULL) + { + if (strcmp(type->name, "interval") == 0) + { + Interval *interval; + + interval = DatumGetIntervalP(DirectFunctionCall3(interval_in, + CStringGetDatum(p->val.val.str), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1))); + if (interval->month != 0) + elog(ERROR, "SET TIME ZONE illegal INTERVAL; month not allowed"); + CTimeZone = interval->time; + } + else if (strcmp(type->name, "float8") == 0) + { + float8 time; + + time = DatumGetFloat8(DirectFunctionCall1(float8in, CStringGetDatum(p->val.val.str))); + CTimeZone = time * 3600; + } + /* We do not actually generate an integer constant in gram.y so this is not used... */ + else if (strcmp(type->name, "int4") == 0) + { + int32 time; + + time = p->val.val.ival; + CTimeZone = time * 3600; + } + else + { + elog(ERROR, "Unable to process SET TIME ZONE command; internal coding error"); + } - tzset(); + HasCTZSet = true; + } + else + { + char *tok; + char *value; + + value = p->val.val.str; + + while ((value = get_token(&tok, NULL, value)) != 0) + { + /* Not yet tried to save original value from environment? */ + if (defaultTZ == NULL) + { + /* found something? then save it for later */ + if ((defaultTZ = getenv("TZ")) != NULL) + strcpy(TZvalue, defaultTZ); + + /* found nothing so mark with an invalid pointer */ + else + defaultTZ = (char *) -1; + } + + strcpy(tzbuf, "TZ="); + strcat(tzbuf, tok); + if (putenv(tzbuf) != 0) + elog(ERROR, "Unable to set TZ environment variable to %s", tok); + + tzset(); + } + + HasCTZSet = false; + } } return TRUE; @@ -389,11 +462,26 @@ parse_timezone(char *value) static bool show_timezone(void) { - char *tz; + char *tzn; + + if (HasCTZSet) + { + Interval interval; - tz = getenv("TZ"); + interval.month = 0; + interval.time = CTimeZone; + + tzn = DatumGetCString(DirectFunctionCall1(interval_out, IntervalPGetDatum(&interval))); + } + else + { + tzn = getenv("TZ"); + } - elog(NOTICE, "Time zone is %s", ((tz != NULL) ? tz : "unset")); + if (tzn != NULL) + elog(NOTICE, "Time zone is '%s'", tzn); + else + elog(NOTICE, "Time zone is unset"); return TRUE; } /* show_timezone() */ @@ -411,8 +499,13 @@ show_timezone(void) static bool reset_timezone(void) { + if (HasCTZSet) + { + HasCTZSet = false; + } + /* no time zone has been set in this session? */ - if (defaultTZ == NULL) + else if (defaultTZ == NULL) { } @@ -443,17 +536,23 @@ reset_timezone(void) -/* SET TRANSACTION */ +/* + * + * SET TRANSACTION + * + */ static bool -parse_XactIsoLevel(char *value) +parse_XactIsoLevel(List *args) { + char *value; - if (value == NULL) - { - reset_XactIsoLevel(); - return TRUE; - } + if (args == NULL) + return reset_XactIsoLevel(); + + Assert(IsA(lfirst(args), A_Const)); + + value = ((A_Const *) lfirst(args))->val.val.str; if (SerializableSnapshot != NULL) { @@ -461,7 +560,6 @@ parse_XactIsoLevel(char *value) return TRUE; } - if (strcmp(value, "serializable") == 0) XactIsoLevel = XACT_SERIALIZABLE; else if (strcmp(value, "read committed") == 0) @@ -503,17 +601,21 @@ reset_XactIsoLevel(void) * Random number seed */ static bool -parse_random_seed(char *value) +parse_random_seed(List *args) { - double seed = 0; + char *value; + double seed = 0; + + if (args == NULL) + return reset_random_seed(); + + Assert(IsA(lfirst(args), A_Const)); + + value = ((A_Const *) lfirst(args))->val.val.str; + + sscanf(value, "%lf", &seed); + DirectFunctionCall1(setseed, Float8GetDatum(seed)); - if (value == NULL) - reset_random_seed(); - else - { - sscanf(value, "%lf", &seed); - DirectFunctionCall1(setseed, Float8GetDatum(seed)); - } return (TRUE); } @@ -544,16 +646,26 @@ reset_random_seed(void) */ static bool -parse_client_encoding(char *value) +parse_client_encoding(List *args) { + char *value; #ifdef MULTIBYTE - int encoding; + int encoding; +#endif + if (args == NULL) + return reset_client_encoding(); + + Assert(IsA(lfirst(args), A_Const)); + + value = ((A_Const *) lfirst(args))->val.val.str; + +#ifdef MULTIBYTE encoding = pg_valid_client_encoding(value); if (encoding < 0) { if (value) - elog(ERROR, "Client encoding %s is not supported", value); + elog(ERROR, "Client encoding '%s' is not supported", value); else elog(ERROR, "No client encoding is specified"); } @@ -576,8 +688,8 @@ parse_client_encoding(char *value) static bool show_client_encoding(void) { - elog(NOTICE, "Current client encoding is %s", - pg_get_client_encoding_name()); + elog(NOTICE, "Current client encoding is '%s'", + pg_get_client_encoding_name()); return TRUE; } @@ -596,6 +708,7 @@ reset_client_encoding(void) } else encoding = GetDatabaseEncoding(); + pg_set_client_encoding(encoding); #endif return TRUE; @@ -610,7 +723,7 @@ set_default_client_encoding(void) static bool -parse_server_encoding(char *value) +parse_server_encoding(List *args) { elog(NOTICE, "SET SERVER_ENCODING is not supported"); return TRUE; @@ -619,7 +732,7 @@ parse_server_encoding(char *value) static bool show_server_encoding(void) { - elog(NOTICE, "Current server encoding is %s", GetDatabaseEncodingName()); + elog(NOTICE, "Current server encoding is '%s'", GetDatabaseEncodingName()); return TRUE; } @@ -632,33 +745,42 @@ reset_server_encoding(void) +/* SetPGVariable() + * Dispatcher for handling SET commands. + * Special cases ought to be removed and handled separately by TCOP + */ void -SetPGVariable(const char *name, const char *value) +SetPGVariable(const char *name, List *args) { - char *mvalue = value ? pstrdup(value) : ((char *) NULL); - - /* - * Special cases ought to be removed and handled separately by TCOP - */ if (strcasecmp(name, "datestyle") == 0) - parse_datestyle(mvalue); + parse_datestyle(args); else if (strcasecmp(name, "timezone") == 0) - parse_timezone(mvalue); + parse_timezone(args); else if (strcasecmp(name, "XactIsoLevel") == 0) - parse_XactIsoLevel(mvalue); + parse_XactIsoLevel(args); else if (strcasecmp(name, "client_encoding") == 0) - parse_client_encoding(mvalue); + parse_client_encoding(args); else if (strcasecmp(name, "server_encoding") == 0) - parse_server_encoding(mvalue); + parse_server_encoding(args); else if (strcasecmp(name, "seed") == 0) - parse_random_seed(mvalue); - else if (strcasecmp(name, "session_authorization") == 0) - SetSessionAuthorization(value); + parse_random_seed(args); else - SetConfigOption(name, value, superuser() ? PGC_SUSET : PGC_USERSET, false); + { + /* For routines defined somewhere else, + * go ahead and extract the string argument + * to match the original interface definition. + * Later, we can change this code too... + */ + char *value; - if (mvalue) - pfree(mvalue); + value = ((args != NULL)? ((A_Const *) lfirst(args))->val.val.str: NULL); + + if (strcasecmp(name, "session_authorization") == 0) + SetSessionAuthorization(value); + else + SetConfigOption(name, value, superuser() ? PGC_SUSET : PGC_USERSET, false); + } + return; } void @@ -685,7 +807,8 @@ GetPGVariable(const char *name) show_client_encoding(); show_server_encoding(); show_random_seed(); - } else + } + else { const char *val = GetConfigOption(name); diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 5cb918e555c..abf5c08d277 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -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.157 2001/10/02 21:39:35 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.158 2001/10/18 17:30:14 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -2287,8 +2287,7 @@ _copyVariableSetStmt(VariableSetStmt *from) if (from->name) newnode->name = pstrdup(from->name); - if (from->value) - newnode->value = pstrdup(from->value); + Node_Copy(from, newnode, args); return newnode; } diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index dd2895f7110..64e27f17801 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -20,7 +20,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.105 2001/10/02 21:39:35 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.106 2001/10/18 17:30:14 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -1159,7 +1159,7 @@ _equalVariableSetStmt(VariableSetStmt *a, VariableSetStmt *b) { if (!equalstr(a->name, b->name)) return false; - if (!equalstr(a->value, b->value)) + if (!equal(a->args, b->args)) return false; return true; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 0be936069f6..efd5fd43ef7 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.262 2001/10/10 00:02:42 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.263 2001/10/18 17:30:14 thomas Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -58,6 +58,7 @@ #include "storage/lmgr.h" #include "utils/acl.h" #include "utils/numeric.h" +#include "utils/datetime.h" #ifdef MULTIBYTE #include "mb/pg_wchar.h" @@ -82,6 +83,8 @@ static int pfunc_num_args; static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr); static Node *makeTypeCast(Node *arg, TypeName *typename); +static Node *makeStringConst(char *str, TypeName *typename); +static Node *makeFloatConst(char *str); static Node *makeRowExpr(char *opr, List *largs, List *rargs); static void mapTargetColumns(List *source, List *target); static SelectStmt *findLeftmostSelect(SelectStmt *node); @@ -92,6 +95,8 @@ static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg); static Node *doNegate(Node *n); static void doNegateFloat(Value *v); +#define MASK(b) (1 << (b)) + %} @@ -209,7 +214,7 @@ static void doNegateFloat(Value *v); %type <list> extract_list, position_list %type <list> substr_list, trim_list -%type <list> opt_interval +%type <ival> opt_interval %type <node> substr_from, substr_for %type <boolean> opt_binary, opt_using, opt_instead, opt_cursor @@ -263,8 +268,9 @@ static void doNegateFloat(Value *v); %type <ival> Iconst %type <str> Sconst, comment_text -%type <str> UserId, opt_boolean, var_value, zone_value, ColId_or_Sconst +%type <str> UserId, opt_boolean, var_value, ColId_or_Sconst %type <str> ColId, ColLabel, TokenId +%type <node> zone_value %type <node> TableConstraint %type <list> ColQualList @@ -757,49 +763,50 @@ VariableSetStmt: SET ColId TO var_value { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = $2; - n->value = $4; + n->args = makeList1(makeStringConst($4, NULL)); $$ = (Node *) n; } | SET ColId '=' var_value { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = $2; - n->value = $4; + n->args = makeList1(makeStringConst($4, NULL)); $$ = (Node *) n; } | SET TIME ZONE zone_value { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = "timezone"; - n->value = $4; + if ($4 != NULL) + n->args = makeList1($4); $$ = (Node *) n; } | SET TRANSACTION ISOLATION LEVEL opt_level { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = "XactIsoLevel"; - n->value = $5; + n->args = makeList1(makeStringConst($5, NULL)); $$ = (Node *) n; } | SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL opt_level { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = "default_transaction_isolation"; - n->value = $8; + n->args = makeList1(makeStringConst($8, NULL)); $$ = (Node *) n; } | SET NAMES opt_encoding { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = "client_encoding"; - n->value = $3; + n->args = makeList1(makeStringConst($3, NULL)); $$ = (Node *) n; } | SET SESSION AUTHORIZATION ColId_or_Sconst { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = "session_authorization"; - n->value = $4; + n->args = makeList1(makeStringConst($4, NULL)); $$ = (Node *) n; } ; @@ -868,7 +875,47 @@ opt_boolean: TRUE_P { $$ = "true"; } | OFF { $$ = "off"; } ; -zone_value: Sconst { $$ = $1; } +/* Timezone values can be: + * - a string such as 'pst8pdt' + * - an integer or floating point number + * - a time interval per SQL99 + */ +zone_value: Sconst + { + $$ = makeStringConst($1, NULL); + } + | ConstInterval Sconst opt_interval + { + A_Const *n = (A_Const *) makeStringConst($2, $1); + n->typename->typmod = (($3 << 16) | 0xFFFF); + $$ = (Node *)n; + } + | ConstInterval '(' Iconst ')' Sconst opt_interval + { + A_Const *n = (A_Const *) makeStringConst($5, $1); + n->typename->typmod = (($3 << 16) | $6); + $$ = (Node *)n; + } + | FCONST + { + $$ = makeFloatConst($1); + } + | '-' FCONST + { + $$ = doNegate(makeFloatConst($2)); + } + | ICONST + { + char buf[64]; + sprintf(buf, "%d", $1); + $$ = makeFloatConst(pstrdup(buf)); + } + | '-' ICONST + { + char buf[64]; + sprintf(buf, "%d", $2); + $$ = doNegate(makeFloatConst(pstrdup(buf))); + } | DEFAULT { $$ = NULL; } | LOCAL { $$ = NULL; } ; @@ -3994,7 +4041,16 @@ opt_array_bounds: opt_array_bounds '[' ']' ; SimpleTypename: ConstTypename - | ConstInterval + | ConstInterval opt_interval + { + $$ = $1; + $$->typmod = (($2 << 16) | 0xFFFF); + } + | ConstInterval '(' Iconst ')' opt_interval + { + $$ = $1; + $$->typmod = (($5 << 16) | $3); + } ; ConstTypename: GenericType @@ -4267,7 +4323,10 @@ ConstDatetime: datetime * - thomas 2001-09-06 */ $$->timezone = $2; - $$->typmod = 0; + /* SQL99 specified a default precision of six. + * - thomas 2001-09-30 + */ + $$->typmod = 6; } | TIME '(' Iconst ')' opt_timezone { @@ -4295,7 +4354,7 @@ ConstDatetime: datetime } ; -ConstInterval: INTERVAL opt_interval +ConstInterval: INTERVAL { $$ = makeNode(TypeName); $$->name = xlateSqlType("interval"); @@ -4326,15 +4385,20 @@ opt_timezone: WITH TIME ZONE { $$ = TRUE; } | /*EMPTY*/ { $$ = FALSE; } ; -opt_interval: datetime { $$ = makeList1($1); } - | YEAR_P TO MONTH_P { $$ = NIL; } - | DAY_P TO HOUR_P { $$ = NIL; } - | DAY_P TO MINUTE_P { $$ = NIL; } - | DAY_P TO SECOND_P { $$ = NIL; } - | HOUR_P TO MINUTE_P { $$ = NIL; } - | HOUR_P TO SECOND_P { $$ = NIL; } - | MINUTE_P TO SECOND_P { $$ = NIL; } - | /*EMPTY*/ { $$ = NIL; } +opt_interval: YEAR_P { $$ = MASK(YEAR); } + | MONTH_P { $$ = MASK(MONTH); } + | DAY_P { $$ = MASK(DAY); } + | HOUR_P { $$ = MASK(HOUR); } + | MINUTE_P { $$ = MASK(MINUTE); } + | SECOND_P { $$ = MASK(SECOND); } + | YEAR_P TO MONTH_P { $$ = MASK(YEAR) | MASK(MONTH); } + | DAY_P TO HOUR_P { $$ = MASK(DAY) | MASK(HOUR); } + | DAY_P TO MINUTE_P { $$ = MASK(DAY) | MASK(HOUR) | MASK(MINUTE); } + | DAY_P TO SECOND_P { $$ = MASK(DAY) | MASK(HOUR) | MASK(MINUTE) | MASK(SECOND); } + | HOUR_P TO MINUTE_P { $$ = MASK(HOUR) | MASK(MINUTE); } + | HOUR_P TO SECOND_P { $$ = MASK(HOUR) | MASK(MINUTE) | MASK(SECOND); } + | MINUTE_P TO SECOND_P { $$ = MASK(MINUTE) | MASK(SECOND); } + | /*EMPTY*/ { $$ = -1; } ; @@ -5561,6 +5625,16 @@ AexprConst: Iconst n->typename = $1; n->val.type = T_String; n->val.val.str = $2; + n->typename->typmod = (($3 << 16) | 0xFFFF); + $$ = (Node *)n; + } + | ConstInterval '(' Iconst ')' Sconst opt_interval + { + A_Const *n = makeNode(A_Const); + n->typename = $1; + n->val.type = T_String; + n->val.val.str = $5; + n->typename->typmod = (($6 << 16) | $3); $$ = (Node *)n; } | ParamNo @@ -5616,7 +5690,6 @@ UserId: ColId { $$ = $1; }; ColId: IDENT { $$ = $1; } | datetime { $$ = $1; } | TokenId { $$ = $1; } - | INTERVAL { $$ = "interval"; } | NATIONAL { $$ = "national"; } | NONE { $$ = "none"; } | PATH_P { $$ = "path"; } @@ -5818,12 +5891,13 @@ ColLabel: ColId { $$ = $1; } | GROUP { $$ = "group"; } | HAVING { $$ = "having"; } | ILIKE { $$ = "ilike"; } - | INITIALLY { $$ = "initially"; } | IN { $$ = "in"; } + | INITIALLY { $$ = "initially"; } | INNER_P { $$ = "inner"; } + | INOUT { $$ = "inout"; } | INTERSECT { $$ = "intersect"; } + | INTERVAL { $$ = "interval"; } | INTO { $$ = "into"; } - | INOUT { $$ = "inout"; } | IS { $$ = "is"; } | ISNULL { $$ = "isnull"; } | JOIN { $$ = "join"; } @@ -5947,6 +6021,31 @@ makeTypeCast(Node *arg, TypeName *typename) } } +static Node * +makeStringConst(char *str, TypeName *typename) +{ + A_Const *n = makeNode(A_Const); + n->val.type = T_String; + n->val.val.str = str; + n->typename = typename; + + return (Node *)n; +} + +static Node * +makeFloatConst(char *str) +{ + A_Const *n = makeNode(A_Const); + TypeName *t = makeNode(TypeName); + n->val.type = T_Float; + n->val.val.str = str; + t->name = xlateSqlType("float"); + t->typmod = -1; + n->typename = t; + + return (Node *)n; +} + /* makeRowExpr() * Generate separate operator nodes for a single row descriptor expression. * Perhaps this should go deeper in the parser someday... diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 6822fe803bd..66ccb652784 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.120 2001/10/12 00:07:14 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.121 2001/10/18 17:30:15 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -740,7 +740,7 @@ ProcessUtility(Node *parsetree, { VariableSetStmt *n = (VariableSetStmt *) parsetree; - SetPGVariable(n->name, n->value); + SetPGVariable(n->name, n->args); set_ps_display(commandTag = "SET VARIABLE"); } break; diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c index f8693c753af..d59d9f9e117 100644 --- a/src/backend/utils/adt/date.c +++ b/src/backend/utils/adt/date.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.61 2001/10/04 15:14:22 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.62 2001/10/18 17:30:15 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -1458,6 +1458,117 @@ text_timetz(PG_FUNCTION_ARGS) Int32GetDatum(-1)); } +/* timetz_part() + * Extract specified field from time type. + */ +Datum +timetz_part(PG_FUNCTION_ARGS) +{ + text *units = PG_GETARG_TEXT_P(0); + TimeTzADT *time = PG_GETARG_TIMETZADT_P(1); + float8 result; + int type, + val; + int i; + char *up, + *lp, + lowunits[MAXDATELEN + 1]; + + if (VARSIZE(units) - VARHDRSZ > MAXDATELEN) + elog(ERROR, "TIMETZ units '%s' not recognized", + DatumGetCString(DirectFunctionCall1(textout, + PointerGetDatum(units)))); + up = VARDATA(units); + lp = lowunits; + for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++) + *lp++ = tolower((unsigned char) *up++); + *lp = '\0'; + + type = DecodeUnits(0, lowunits, &val); + if (type == UNKNOWN_FIELD) + type = DecodeSpecial(0, lowunits, &val); + + if (type == UNITS) + { + double trem; + double dummy; + int tz; + double fsec; + struct tm tt, + *tm = &tt; + + trem = time->time; + TMODULO(trem, tm->tm_hour, 3600e0); + TMODULO(trem, tm->tm_min, 60e0); + TMODULO(trem, tm->tm_sec, 1e0); + fsec = trem; + tz = time->zone; + + switch (val) + { + case DTK_TZ: + result = tz; + break; + + case DTK_TZ_MINUTE: + result = tz / 60; + TMODULO(result, dummy, 60e0); + break; + + case DTK_TZ_HOUR: + dummy = tz; + TMODULO(dummy, result, 3600e0); + break; + + case DTK_MICROSEC: + result = ((tm->tm_sec + fsec) * 1000000); + break; + + case DTK_MILLISEC: + result = ((tm->tm_sec + fsec) * 1000); + break; + + case DTK_SECOND: + result = (tm->tm_sec + fsec); + break; + + case DTK_MINUTE: + result = tm->tm_min; + break; + + case DTK_HOUR: + result = tm->tm_hour; + break; + + case DTK_DAY: + case DTK_MONTH: + case DTK_QUARTER: + case DTK_YEAR: + case DTK_DECADE: + case DTK_CENTURY: + case DTK_MILLENNIUM: + default: + elog(ERROR, "TIMETZ units '%s' not supported", + DatumGetCString(DirectFunctionCall1(textout, + PointerGetDatum(units)))); + result = 0; + } + } + else if ((type == RESERV) && (val == DTK_EPOCH)) + { + result = time->time - time->zone; + } + else + { + elog(ERROR, "TIMETZ units '%s' not recognized", + DatumGetCString(DirectFunctionCall1(textout, + PointerGetDatum(units)))); + result = 0; + } + + PG_RETURN_FLOAT8(result); +} + /* timetz_zone() * Encode time with time zone type with specified time zone. */ diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c index 33fa7647ed5..275231983ee 100644 --- a/src/backend/utils/adt/datetime.c +++ b/src/backend/utils/adt/datetime.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.72 2001/10/11 18:06:52 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.73 2001/10/18 17:30:15 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -38,6 +38,7 @@ static int DecodeTimezone(char *str, int *tzp); static datetkn *datebsearch(char *key, datetkn *base, unsigned int nel); static int DecodeDate(char *str, int fmask, int *tmask, struct tm * tm); static int DecodePosixTimezone(char *str, int *val); +void TrimTrailingZeros(char *str); int day_tab[2][13] = { @@ -239,81 +240,73 @@ static unsigned int australian_szdatetktbl = sizeof australian_datetktbl / sizeof australian_datetktbl[0]; static datetkn deltatktbl[] = { -/* text, token, lexval */ - {"@", IGNORE, 0}, /* postgres relative time prefix */ + /* text, token, lexval */ + {"@", IGNORE, 0}, /* postgres relative prefix */ {DAGO, AGO, 0}, /* "ago" indicates negative time offset */ - {"c", UNITS, DTK_CENTURY}, /* "century" relative time units */ - {"cent", UNITS, DTK_CENTURY}, /* "century" relative time units */ - {"centuries", UNITS, DTK_CENTURY}, /* "centuries" relative time units */ - {DCENTURY, UNITS, DTK_CENTURY}, /* "century" relative time units */ - {"d", UNITS, DTK_DAY}, /* "day" relative time units */ - {DDAY, UNITS, DTK_DAY}, /* "day" relative time units */ - {"days", UNITS, DTK_DAY}, /* "days" relative time units */ - {"dec", UNITS, DTK_DECADE}, /* "decade" relative time units */ - {"decs", UNITS, DTK_DECADE},/* "decades" relative time units */ - {DDECADE, UNITS, DTK_DECADE}, /* "decade" relative time units */ - {"decades", UNITS, DTK_DECADE}, /* "decades" relative time units */ - {"h", UNITS, DTK_HOUR}, /* "hour" relative time units */ - {DHOUR, UNITS, DTK_HOUR}, /* "hour" relative time units */ - {"hours", UNITS, DTK_HOUR}, /* "hours" relative time units */ - {"hr", UNITS, DTK_HOUR}, /* "hour" relative time units */ - {"hrs", UNITS, DTK_HOUR}, /* "hours" relative time units */ + {"c", UNITS, DTK_CENTURY}, /* "century" relative */ + {"cent", UNITS, DTK_CENTURY}, /* "century" relative */ + {"centuries", UNITS, DTK_CENTURY}, /* "centuries" relative */ + {DCENTURY, UNITS, DTK_CENTURY}, /* "century" relative */ + {"d", UNITS, DTK_DAY}, /* "day" relative */ + {DDAY, UNITS, DTK_DAY}, /* "day" relative */ + {"days", UNITS, DTK_DAY}, /* "days" relative */ + {"dec", UNITS, DTK_DECADE}, /* "decade" relative */ + {"decs", UNITS, DTK_DECADE}, /* "decades" relative */ + {DDECADE, UNITS, DTK_DECADE}, /* "decade" relative */ + {"decades", UNITS, DTK_DECADE}, /* "decades" relative */ + {"h", UNITS, DTK_HOUR}, /* "hour" relative */ + {DHOUR, UNITS, DTK_HOUR}, /* "hour" relative */ + {"hours", UNITS, DTK_HOUR}, /* "hours" relative */ + {"hr", UNITS, DTK_HOUR}, /* "hour" relative */ + {"hrs", UNITS, DTK_HOUR}, /* "hours" relative */ {INVALID, RESERV, DTK_INVALID}, /* reserved for invalid time */ - {"m", UNITS, DTK_MINUTE}, /* "minute" relative time units */ - {"microsecon", UNITS, DTK_MICROSEC}, /* "microsecond" relative - * time units */ - {"mil", UNITS, DTK_MILLENNIUM}, /* "millennium" relative time - * units */ - {"mils", UNITS, DTK_MILLENNIUM}, /* "millennia" relative time units */ - {"millennia", UNITS, DTK_MILLENNIUM}, /* "millennia" relative - * time units */ - {DMILLENNIUM, UNITS, DTK_MILLENNIUM}, /* "millennium" relative - * time units */ - {"millisecon", UNITS, DTK_MILLISEC}, /* relative time units */ - {"min", UNITS, DTK_MINUTE}, /* "minute" relative time units */ - {"mins", UNITS, DTK_MINUTE},/* "minutes" relative time units */ - {"mins", UNITS, DTK_MINUTE},/* "minutes" relative time units */ - {DMINUTE, UNITS, DTK_MINUTE}, /* "minute" relative time units */ - {"minutes", UNITS, DTK_MINUTE}, /* "minutes" relative time units */ - {"mon", UNITS, DTK_MONTH}, /* "months" relative time units */ - {"mons", UNITS, DTK_MONTH}, /* "months" relative time units */ - {DMONTH, UNITS, DTK_MONTH}, /* "month" relative time units */ + {"m", UNITS, DTK_MINUTE}, /* "minute" relative */ + {"microsecon", UNITS, DTK_MICROSEC}, /* "microsecond" relative */ + {"mil", UNITS, DTK_MILLENNIUM}, /* "millennium" relative */ + {"millennia", UNITS, DTK_MILLENNIUM}, /* "millennia" relative */ + {DMILLENNIUM, UNITS, DTK_MILLENNIUM}, /* "millennium" relative */ + {"millisecon", UNITS, DTK_MILLISEC}, /* relative */ + {"mils", UNITS, DTK_MILLENNIUM}, /* "millennia" relative */ + {"min", UNITS, DTK_MINUTE}, /* "minute" relative */ + {"mins", UNITS, DTK_MINUTE}, /* "minutes" relative */ + {"mins", UNITS, DTK_MINUTE}, /* "minutes" relative */ + {DMINUTE, UNITS, DTK_MINUTE}, /* "minute" relative */ + {"minutes", UNITS, DTK_MINUTE}, /* "minutes" relative */ + {"mon", UNITS, DTK_MONTH}, /* "months" relative */ + {"mons", UNITS, DTK_MONTH}, /* "months" relative */ + {DMONTH, UNITS, DTK_MONTH}, /* "month" relative */ {"months", UNITS, DTK_MONTH}, {"ms", UNITS, DTK_MILLISEC}, {"msec", UNITS, DTK_MILLISEC}, {DMILLISEC, UNITS, DTK_MILLISEC}, {"mseconds", UNITS, DTK_MILLISEC}, {"msecs", UNITS, DTK_MILLISEC}, - {"qtr", UNITS, DTK_QUARTER},/* "quarter" relative time */ - {DQUARTER, UNITS, DTK_QUARTER}, /* "quarter" relative time */ - {"reltime", IGNORE, 0}, /* for pre-v6.1 "Undefined Reltime" */ + {"qtr", UNITS, DTK_QUARTER}, /* "quarter" relative */ + {DQUARTER, UNITS, DTK_QUARTER}, /* "quarter" relative */ + {"reltime", IGNORE, 0}, /* pre-v6.1 "Undefined Reltime" */ {"s", UNITS, DTK_SECOND}, {"sec", UNITS, DTK_SECOND}, {DSECOND, UNITS, DTK_SECOND}, {"seconds", UNITS, DTK_SECOND}, {"secs", UNITS, DTK_SECOND}, - {DTIMEZONE, UNITS, DTK_TZ}, /* "timezone" time offset */ + {DTIMEZONE, UNITS, DTK_TZ}, /* "timezone" time offset */ {"timezone", UNITS, DTK_TZ}, /* "timezone" time offset */ {"timezone_h", UNITS, DTK_TZ_HOUR}, /* timezone hour units */ {"timezone_m", UNITS, DTK_TZ_MINUTE}, /* timezone minutes units */ {"undefined", RESERV, DTK_INVALID}, /* pre-v6.1 invalid time */ - {"us", UNITS, DTK_MICROSEC},/* "microsecond" relative time units */ - {"usec", UNITS, DTK_MICROSEC}, /* "microsecond" relative time - * units */ - {DMICROSEC, UNITS, DTK_MICROSEC}, /* "microsecond" relative time - * units */ - {"useconds", UNITS, DTK_MICROSEC}, /* "microseconds" relative time - * units */ - {"usecs", UNITS, DTK_MICROSEC}, /* "microseconds" relative time - * units */ - {"w", UNITS, DTK_WEEK}, /* "week" relative time units */ - {DWEEK, UNITS, DTK_WEEK}, /* "week" relative time units */ - {"weeks", UNITS, DTK_WEEK}, /* "weeks" relative time units */ - {"y", UNITS, DTK_YEAR}, /* "year" relative time units */ - {DYEAR, UNITS, DTK_YEAR}, /* "year" relative time units */ - {"years", UNITS, DTK_YEAR}, /* "years" relative time units */ - {"yr", UNITS, DTK_YEAR}, /* "year" relative time units */ - {"yrs", UNITS, DTK_YEAR}, /* "years" relative time units */ + {"us", UNITS, DTK_MICROSEC}, /* "microsecond" relative */ + {"usec", UNITS, DTK_MICROSEC}, /* "microsecond" relative */ + {DMICROSEC, UNITS, DTK_MICROSEC}, /* "microsecond" relative */ + {"useconds", UNITS, DTK_MICROSEC}, /* "microseconds" relative */ + {"usecs", UNITS, DTK_MICROSEC}, /* "microseconds" relative */ + {"w", UNITS, DTK_WEEK}, /* "week" relative */ + {DWEEK, UNITS, DTK_WEEK}, /* "week" relative */ + {"weeks", UNITS, DTK_WEEK}, /* "weeks" relative */ + {"y", UNITS, DTK_YEAR}, /* "year" relative */ + {DYEAR, UNITS, DTK_YEAR}, /* "year" relative */ + {"years", UNITS, DTK_YEAR}, /* "years" relative */ + {"yr", UNITS, DTK_YEAR}, /* "year" relative */ + {"yrs", UNITS, DTK_YEAR}, /* "years" relative */ }; static unsigned int szdeltatktbl = sizeof deltatktbl / sizeof deltatktbl[0]; @@ -346,8 +339,10 @@ date2j(int y, int m, int d) { int m12 = (m - 14) / 12; - return ((1461 * (y + 4800 + m12)) / 4 + (367 * (m - 2 - 12 * (m12))) / 12 - - (3 * ((y + 4900 + m12) / 100)) / 4 + d - 32075); + return ((1461 * (y + 4800 + m12)) / 4 + + (367 * (m - 2 - 12 * (m12))) / 12 + - (3 * ((y + 4900 + m12) / 100)) / 4 + + d - 32075); } /* date2j() */ void @@ -390,11 +385,28 @@ j2day(int date) } /* j2day() */ -/* - * parse and convert date in timestr (the normal interface) - * - * Returns the number of seconds since epoch (J2000) - */ +void +TrimTrailingZeros(char *str) +{ + int len = strlen(str); + + /* chop off trailing one to cope with interval rounding */ + if (strcmp((str + len - 4), "0001") == 0) + { + len -= 4; + *(str + len) = '\0'; + } + + /* chop off trailing zeros... */ + while ((*(str + len - 1) == '0') + && (*(str + len - 3) != '.')) + { + len--; + *(str + len) = '\0'; + } + return; +} + /* ParseDateTime() * Break string into tokens based on a date/time context. @@ -989,7 +1001,11 @@ DetermineLocalTimeZone(struct tm * tm) { int tz; - if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday)) + if (HasCTZSet) + { + tz = CTimeZone; + } + else if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday)) { #if defined(HAVE_TM_ZONE) || defined(HAVE_INT_TIMEZONE) /* @@ -1044,9 +1060,6 @@ DetermineLocalTimeZone(struct tm * tm) * SQL92 TIME WITH TIME ZONE, but it reveals * bogosity with SQL92 date/time standards, since * we must infer a time zone from current time. - * XXX Later, we should probably support - * SET TIME ZONE <integer> - * which of course is a screwed up convention. * - thomas 2000-03-10 */ int @@ -2246,33 +2259,23 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha */ if (fsec != 0) { sprintf((str + strlen(str)), ":%013.10f", sec); - /* chop off trailing pairs of zeros... */ - while ((strcmp((str + strlen(str) - 2), "00") == 0) - && (*(str + strlen(str) - 3) != '.')) - { - *(str + strlen(str) - 2) = '\0'; - } + TrimTrailingZeros(str); } else { sprintf((str + strlen(str)), ":%02.0f", sec); } - if ((*tzn != NULL) && (tm->tm_isdst >= 0)) + /* tzp == NULL indicates that we don't want *any* time zone info in the output string. + * *tzn != NULL indicates that we *have* time zone info available. + * tm_isdst != -1 indicates that we have a valid time zone translation. + */ + if ((tzp != NULL) && (*tzn != NULL) && (tm->tm_isdst >= 0)) { - if (tzp != NULL) - { - hour = -(*tzp / 3600); - min = ((abs(*tzp) / 60) % 60); - } - else - { - hour = 0; - min = 0; - } + hour = -(*tzp / 3600); + min = ((abs(*tzp) / 60) % 60); sprintf((str + strlen(str)), ((min != 0) ? "%+03d:%02d" : "%+03d"), hour, min); } - } else { @@ -2305,12 +2308,7 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha */ if (fsec != 0) { sprintf((str + strlen(str)), ":%013.10f", sec); - /* chop off trailing pairs of zeros... */ - while ((strcmp((str + strlen(str) - 2), "00") == 0) - && (*(str + strlen(str) - 3) != '.')) - { - *(str + strlen(str) - 2) = '\0'; - } + TrimTrailingZeros(str); } else { @@ -2319,6 +2317,13 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha if ((*tzn != NULL) && (tm->tm_isdst >= 0)) sprintf((str + strlen(str)), " %.*s", MAXTZLEN, *tzn); + + else if (tzp != NULL) + { + hour = -(*tzp / 3600); + min = ((abs(*tzp) / 60) % 60); + sprintf((str + strlen(str)), ((min != 0) ? "%+03d:%02d" : "%+03d"), hour, min); + } } else sprintf((str + 5), "/%04d %02d:%02d %s", @@ -2341,12 +2346,7 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha */ if (fsec != 0) { sprintf((str + strlen(str)), ":%013.10f", sec); - /* chop off trailing pairs of zeros... */ - while ((strcmp((str + strlen(str) - 2), "00") == 0) - && (*(str + strlen(str) - 3) != '.')) - { - *(str + strlen(str) - 2) = '\0'; - } + TrimTrailingZeros(str); } else { @@ -2355,6 +2355,13 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha if ((*tzn != NULL) && (tm->tm_isdst >= 0)) sprintf((str + strlen(str)), " %.*s", MAXTZLEN, *tzn); + + else if (tzp != NULL) + { + hour = -(*tzp / 3600); + min = ((abs(*tzp) / 60) % 60); + sprintf((str + strlen(str)), ((min != 0) ? "%+03d:%02d" : "%+03d"), hour, min); + } } else sprintf((str + 5), ".%04d %02d:%02d %s", @@ -2387,12 +2394,7 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha */ if (fsec != 0) { sprintf((str + strlen(str)), ":%013.10f", sec); - /* chop off trailing pairs of zeros... */ - while ((strcmp((str + strlen(str) - 2), "00") == 0) - && (*(str + strlen(str) - 3) != '.')) - { - *(str + strlen(str) - 2) = '\0'; - } + TrimTrailingZeros(str); } else { @@ -2400,8 +2402,16 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha } sprintf((str + strlen(str)), " %04d", tm->tm_year); - if ((*tzn != NULL) && (tm->tm_isdst >= 0)) + + if ((tzp != NULL) && (*tzn != NULL) && (tm->tm_isdst >= 0)) sprintf((str + strlen(str)), " %.*s", MAXTZLEN, *tzn); + + else if (HasCTZSet && (tzp != NULL)) + { + hour = -(*tzp / 3600); + min = ((abs(*tzp) / 60) % 60); + sprintf((str + strlen(str)), ((min != 0) ? "%+03d:%02d" : "%+03d"), hour, min); + } } else { @@ -2485,12 +2495,12 @@ EncodeTimeSpan(struct tm * tm, double fsec, int style, char *str) if (fsec != 0) { fsec += tm->tm_sec; - sprintf(cp, ":%05.2f", fabs(fsec)); + sprintf(cp, ":%013.10f", fabs(fsec)); + TrimTrailingZeros(cp); cp += strlen(cp); is_nonzero = TRUE; - - /* otherwise, integer seconds only? */ } + /* otherwise, integer seconds only? */ else if (tm->tm_sec != 0) { sprintf(cp, ":%02d", abs(tm->tm_sec)); diff --git a/src/backend/utils/adt/nabstime.c b/src/backend/utils/adt/nabstime.c index b7ac0784d5e..cd8a7788ae5 100644 --- a/src/backend/utils/adt/nabstime.c +++ b/src/backend/utils/adt/nabstime.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.87 2001/10/01 02:31:33 ishii Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.88 2001/10/18 17:30:15 thomas Exp $ * * NOTES * @@ -113,7 +113,7 @@ static int istinterval(char *i_string, /* GetCurrentAbsoluteTime() * Get the current system time. Set timezone parameters if not specified elsewhere. - * Define HasTZSet to allow clients to specify the default timezone. + * Define HasCTZSet to allow clients to specify the default timezone. * * Returns the number of seconds since epoch (January 1 1970 GMT) */ @@ -173,7 +173,7 @@ GetCurrentAbsoluteTime(void) */ strftime(CTZName, MAXTZLEN, "%Z", localtime(&now)); #endif - }; + } return (AbsoluteTime) now; } /* GetCurrentAbsoluteTime() */ @@ -181,7 +181,7 @@ GetCurrentAbsoluteTime(void) /* GetCurrentAbsoluteTime() * Get the current system time. Set timezone parameters if not specified elsewhere. - * Define HasTZSet to allow clients to specify the default timezone. + * Define HasCTZSet to allow clients to specify the default timezone. * * Returns the number of seconds since epoch (January 1 1970 GMT) */ @@ -284,7 +284,7 @@ GetCurrentTimeUsec(struct tm *tm, double *fsec) void -abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char *tzn) +abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn) { time_t time = (time_t) _time; @@ -297,9 +297,15 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char *tzn) ftime(&tb); #endif + /* If HasCTZSet is true then we have a brute force time zone specified. + * Go ahead and rotate to the local time zone since we will later bypass + * any calls which adjust the tm fields. + */ + if (HasCTZSet && (tzp != NULL)) + time -= CTimeZone; #if defined(HAVE_TM_ZONE) || defined(HAVE_INT_TIMEZONE) - if (tzp != NULL) + if ((! HasCTZSet) && (tzp != NULL)) { tx = localtime((time_t *) &time); #ifdef NO_MKTIME_BEFORE_1970 @@ -329,47 +335,95 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char *tzn) tm->tm_zone = tx->tm_zone; if (tzp != NULL) - *tzp = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */ - /* XXX FreeBSD man pages indicate that this should work - tgl 97/04/23 */ - if (tzn != NULL) { - - /* - * Copy no more than MAXTZLEN bytes of timezone to tzn, in case it - * contains an error message, which doesn't fit in the buffer + /* We have a brute force time zone per SQL99? + * Then use it without change + * since we have already rotated to the time zone. */ - StrNCpy(tzn, tm->tm_zone, MAXTZLEN + 1); - if (strlen(tm->tm_zone) > MAXTZLEN) - elog(NOTICE, "Invalid timezone \'%s\'", tm->tm_zone); + if (HasCTZSet) + { + *tzp = CTimeZone; + tm->tm_gmtoff = CTimeZone; + tm->tm_isdst = -1; + tm->tm_zone = NULL; + if (tzn != NULL) + *tzn = NULL; + } + else + { + *tzp = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */ + + /* XXX FreeBSD man pages indicate that this should work - tgl 97/04/23 */ + if (tzn != NULL) + { + /* + * Copy no more than MAXTZLEN bytes of timezone to tzn, in case it + * contains an error message, which doesn't fit in the buffer + */ + StrNCpy(*tzn, tm->tm_zone, MAXTZLEN + 1); + if (strlen(tm->tm_zone) > MAXTZLEN) + elog(NOTICE, "Invalid timezone \'%s\'", tm->tm_zone); + } + } } #elif defined(HAVE_INT_TIMEZONE) if (tzp != NULL) - *tzp = ((tm->tm_isdst > 0) ? (TIMEZONE_GLOBAL - 3600) : TIMEZONE_GLOBAL); - - if (tzn != NULL) - { - - /* - * Copy no more than MAXTZLEN bytes of timezone to tzn, in case it - * contains an error message, which doesn't fit in the buffer + /* We have a brute force time zone per SQL99? + * Then use it without change + * since we have already rotated to the time zone. */ - StrNCpy(tzn, tzname[tm->tm_isdst], MAXTZLEN + 1); - if (strlen(tzname[tm->tm_isdst]) > MAXTZLEN) - elog(NOTICE, "Invalid timezone \'%s\'", tzname[tm->tm_isdst]); + if (HasCTZSet) + { + *tzp = CTimeZone; + tm->tm_isdst = -1; + if (tzn != NULL) + *tzn = NULL; + } + else + { + *tzp = ((tm->tm_isdst > 0) ? (TIMEZONE_GLOBAL - 3600) : TIMEZONE_GLOBAL); + + if (tzn != NULL) + { + + /* + * Copy no more than MAXTZLEN bytes of timezone to tzn, in case it + * contains an error message, which doesn't fit in the buffer + */ + StrNCpy(*tzn, tzname[tm->tm_isdst], MAXTZLEN + 1); + if (strlen(tzname[tm->tm_isdst]) > MAXTZLEN) + elog(NOTICE, "Invalid timezone \'%s\'", tzname[tm->tm_isdst]); + } + } } #endif #else /* not (HAVE_TM_ZONE || HAVE_INT_TIMEZONE) */ if (tzp != NULL) - *tzp = tb.timezone * 60; - - /* - * XXX does this work to get the local timezone string in V7? - tgl - * 97/03/18 - */ - if (tzn != NULL) { - strftime(tzn, MAXTZLEN, "%Z", localtime(&now)); - tzn[MAXTZLEN] = '\0'; /* let's just be sure it's null-terminated */ + /* We have a brute force time zone per SQL99? + * Then use it without change + * since we have already rotated to the time zone. + */ + if (HasCTZSet) + { + *tzp = CTimeZone; + if (tzn != NULL) + *tzn = NULL; + } + else + { + *tzp = tb.timezone * 60; + + /* + * XXX does this work to get the local timezone string in V7? - tgl + * 97/03/18 + */ + if (tzn != NULL) + { + strftime(*tzn, MAXTZLEN, "%Z", localtime(&now)); + tzn[MAXTZLEN] = '\0'; /* let's just be sure it's null-terminated */ + } + } } #endif @@ -508,7 +562,7 @@ nabstimeout(PG_FUNCTION_ARGS) strcpy(buf, EARLY); break; default: - abstime2tm(time, &tz, tm, tzn); + abstime2tm(time, &tz, tm, &tzn); EncodeDateTime(tm, fsec, &tz, &tzn, DateStyle, buf); break; } @@ -676,7 +730,8 @@ abstime_timestamp(PG_FUNCTION_ARGS) struct tm tt, *tm = &tt; int tz; - char tzn[MAXTZLEN]; + char zone[MAXDATELEN + 1], + *tzn = zone; switch (abstime) { @@ -694,7 +749,7 @@ abstime_timestamp(PG_FUNCTION_ARGS) break; default: - abstime2tm(abstime, &tz, tm, tzn); + abstime2tm(abstime, &tz, tm, &tzn); result = abstime + ((date2j(1970, 1, 1) - date2j(2000, 1, 1)) * 86400) + tz; break; }; diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index 6eeb349c30f..13ad90e0b0e 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.55 2001/10/05 06:38:59 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.56 2001/10/18 17:30:15 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -33,6 +33,7 @@ static double time2t(const int hour, const int min, const double sec); static int EncodeSpecialTimestamp(Timestamp dt, char *str); static Timestamp dt2local(Timestamp dt, int timezone); static void AdjustTimestampForTypmod(Timestamp *time, int32 typmod); +static void AdjustIntervalForTypmod(Interval *interval, int32 typmod); /***************************************************************************** @@ -69,7 +70,7 @@ timestamp_in(PG_FUNCTION_ARGS) { case DTK_DATE: if (tm2timestamp(tm, fsec, NULL, &result) != 0) - elog(ERROR, "Timestamp out of range '%s'", str); + elog(ERROR, "TIMESTAMP out of range '%s'", str); break; case DTK_EPOCH: @@ -85,12 +86,12 @@ timestamp_in(PG_FUNCTION_ARGS) break; case DTK_INVALID: - elog(ERROR, "Timestamp '%s' no longer supported", str); + elog(ERROR, "TIMESTAMP '%s' no longer supported", str); TIMESTAMP_NOEND(result); break; default: - elog(ERROR, "Timestamp '%s' not parsed; internal coding error", str); + elog(ERROR, "TIMESTAMP '%s' not parsed; internal coding error", str); TIMESTAMP_NOEND(result); } @@ -157,7 +158,7 @@ AdjustTimestampForTypmod(Timestamp *time, int32 typmod) TimestampTypmod = typmod; } - *time = (rint(((double) *time)*TimestampScale)/TimestampScale); + *time = (rint(((double) *time) * TimestampScale)/TimestampScale); } } @@ -192,7 +193,7 @@ timestamptz_in(PG_FUNCTION_ARGS) { case DTK_DATE: if (tm2timestamp(tm, fsec, &tz, &result) != 0) - elog(ERROR, "Timestamp out of range '%s'", str); + elog(ERROR, "TIMESTAMP WITH TIME ZONE out of range '%s'", str); break; case DTK_EPOCH: @@ -208,12 +209,12 @@ timestamptz_in(PG_FUNCTION_ARGS) break; case DTK_INVALID: - elog(ERROR, "Timestamp with time zone '%s' no longer supported", str); + elog(ERROR, "TIMESTAMP WITH TIME ZONE '%s' no longer supported", str); TIMESTAMP_NOEND(result); break; default: - elog(ERROR, "Timestamp with time zone '%s' not parsed; internal coding error", str); + elog(ERROR, "TIMESTAMP WITH TIME ZONE '%s' not parsed; internal coding error", str); TIMESTAMP_NOEND(result); } @@ -277,6 +278,10 @@ Datum interval_in(PG_FUNCTION_ARGS) { char *str = PG_GETARG_CSTRING(0); +#ifdef NOT_USED + Oid typelem = PG_GETARG_OID(1); +#endif + int32 typmod = PG_GETARG_INT32(2); Interval *result; double fsec; struct tm tt, @@ -306,6 +311,7 @@ interval_in(PG_FUNCTION_ARGS) case DTK_DELTA: if (tm2interval(tm, fsec, result) != 0) elog(ERROR, "Bad interval external representation '%s'", str); + AdjustIntervalForTypmod(result, typmod); break; case DTK_INVALID: @@ -342,6 +348,148 @@ interval_out(PG_FUNCTION_ARGS) PG_RETURN_CSTRING(result); } +/* interval_scale() + * Adjust interval type for specified fields. + * Used by PostgreSQL type system to stuff columns. + */ +Datum +interval_scale(PG_FUNCTION_ARGS) +{ + Interval *interval = PG_GETARG_INTERVAL_P(0); + int32 typmod = PG_GETARG_INT32(1); + Interval *result; + + result = palloc(sizeof(Interval)); + *result = *interval; + + AdjustIntervalForTypmod(result, typmod); + + PG_RETURN_INTERVAL_P(result); +} + +#define MASK(b) (1 << (b)) + +static void +AdjustIntervalForTypmod(Interval *interval, int32 typmod) +{ + if (typmod != -1) + { + int range = ((typmod >> 16) & 0xFFFF); + int precision = (typmod & 0xFFFF); + + if (range == 0xFFFF) + { + /* Do nothing... */ + } + if (range == MASK(YEAR)) + { + interval->month = ((interval->month / 12) * 12); + interval->time = 0; + } + else if (range == MASK(MONTH)) + { + interval->month %= 12; + interval->time = 0; + } + /* YEAR TO MONTH */ + else if (range == (MASK(YEAR) | MASK(MONTH))) + { + interval->time = 0; + } + else if (range == MASK(DAY)) + { + interval->month = 0; + interval->time = (((int)(interval->time / 86400)) * 86400); + } + else if (range == MASK(HOUR)) + { + double day; + + interval->month = 0; + TMODULO(interval->time, day, 86400.0); + interval->time = (((int)(interval->time / 3600)) * 3600.0); + } + else if (range == MASK(MINUTE)) + { + double hour; + + interval->month = 0; + TMODULO(interval->time, hour, 3600.0); + interval->time = (((int)(interval->time / 60)) * 60); + } + else if (range == MASK(SECOND)) + { + double hour; + + interval->month = 0; + TMODULO(interval->time, hour, 60.0); +// interval->time = (int)(interval->time); + } + /* DAY TO HOUR */ + else if (range == (MASK(DAY) | MASK(HOUR))) + { + interval->month = 0; + interval->time = (((int)(interval->time / 3600)) * 3600); + } + /* DAY TO MINUTE */ + else if (range == (MASK(DAY) | MASK(HOUR) | MASK(MINUTE))) + { + interval->month = 0; + interval->time = (((int)(interval->time / 60)) * 60); + } + /* DAY TO SECOND */ + else if (range == (MASK(DAY) | MASK(HOUR) | MASK(MINUTE) | MASK(SECOND))) + { + interval->month = 0; + } + /* HOUR TO MINUTE */ + else if (range == (MASK(HOUR) | MASK(MINUTE))) + { + double day; + + interval->month = 0; + TMODULO(interval->time, day, 86400.0); + interval->time = (((int)(interval->time / 60)) * 60); + } + /* HOUR TO SECOND */ + else if (range == (MASK(HOUR) | MASK(MINUTE) | MASK(SECOND))) + { + double day; + + interval->month = 0; + TMODULO(interval->time, day, 86400.0); + } + /* MINUTE TO SECOND */ + else if (range == (MASK(MINUTE) | MASK(SECOND))) + { + double hour; + + interval->month = 0; + TMODULO(interval->time, hour, 3600.0); + } + else + { + elog(ERROR, "AdjustIntervalForTypmod(): internal coding error"); + } + + if (precision != 0xFFFF) + { + static double IntervalScale = 1; + static int IntervalTypmod = 0; + + if (precision != IntervalTypmod) + { + IntervalTypmod = precision; + IntervalScale = pow(10.0, IntervalTypmod); + } + + interval->time = (rint(interval->time * IntervalScale) / IntervalScale); + } + } + + return; +} + /* EncodeSpecialTimestamp() * Convert reserved timestamp data type to string. @@ -417,6 +565,13 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, double *fsec, char **tzn) date0 = date2j(2000, 1, 1); + /* If HasCTZSet is true then we have a brute force time zone specified. + * Go ahead and rotate to the local time zone since we will later bypass + * any calls which adjust the tm fields. + */ + if (HasCTZSet && (tzp != NULL)) + dt -= CTimeZone; + time = dt; TMODULO(time, date, 86400e0); @@ -441,7 +596,24 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, double *fsec, char **tzn) if (tzp != NULL) { - if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday)) + /* We have a brute force time zone per SQL99? + * Then use it without change + * since we have already rotated to the time zone. + */ + if (HasCTZSet) + { + *tzp = CTimeZone; + tm->tm_gmtoff = CTimeZone; + tm->tm_isdst = 0; + tm->tm_zone = NULL; + if (tzn != NULL) + *tzn = NULL; + } + + /* Does this fall within the capabilities of the localtime() interface? + * Then use this to rotate to the local time zone. + */ + else if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday)) { utime = (dt + (date0 - date2j(1970, 1, 1)) * 86400); @@ -492,6 +664,7 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, double *fsec, char **tzn) *tzn = CTZName; #endif + dt = dt2local(dt, *tzp); } else { @@ -500,9 +673,6 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, double *fsec, char **tzn) if (tzn != NULL) *tzn = NULL; } - - dt = dt2local(dt, *tzp); - } else { @@ -1072,14 +1242,14 @@ timestamp_pl_span(PG_FUNCTION_ARGS) if (tm2timestamp(tm, fsec, NULL, ×tamp) != 0) { - elog(ERROR, "Unable to add timestamp and interval" + elog(ERROR, "Unable to add TIMESTAMP and INTERVAL" "\n\ttimestamp_pl_span() internal error encoding timestamp"); PG_RETURN_NULL(); } } else { - elog(ERROR, "Unable to add timestamp and interval" + elog(ERROR, "Unable to add TIMESTAMP and INTERVAL" "\n\ttimestamp_pl_span() internal error decoding timestamp"); PG_RETURN_NULL(); } @@ -1164,12 +1334,12 @@ timestamptz_pl_span(PG_FUNCTION_ARGS) tz = DetermineLocalTimeZone(tm); if (tm2timestamp(tm, fsec, &tz, ×tamp) != 0) - elog(ERROR, "Unable to add timestamp and interval" + elog(ERROR, "Unable to add TIMESTAMP and INTERVAL" "\n\ttimestamptz_pl_span() internal error encoding timestamp"); } else { - elog(ERROR, "Unable to add timestamp and interval" + elog(ERROR, "Unable to add TIMESTAMP and INTERVAL" "\n\ttimestamptz_pl_span() internal error decoding timestamp"); } } @@ -1546,11 +1716,11 @@ timestamp_age(PG_FUNCTION_ARGS) } if (tm2interval(tm, fsec, result) != 0) - elog(ERROR, "Unable to encode interval" + elog(ERROR, "Unable to encode INTERVAL" "\n\ttimestamp_age() internal coding error"); } else - elog(ERROR, "Unable to decode timestamp" + elog(ERROR, "Unable to decode TIMESTAMP" "\n\ttimestamp_age() internal coding error"); PG_RETURN_INTERVAL_P(result); @@ -1655,10 +1825,10 @@ timestamptz_age(PG_FUNCTION_ARGS) } if (tm2interval(tm, fsec, result) != 0) - elog(ERROR, "Unable to decode timestamp"); + elog(ERROR, "Unable to decode TIMESTAMP"); } else - elog(ERROR, "Unable to decode timestamp"); + elog(ERROR, "Unable to decode TIMESTAMP"); PG_RETURN_INTERVAL_P(result); } @@ -1711,7 +1881,7 @@ text_timestamp(PG_FUNCTION_ARGS) dstr[MAXDATELEN + 1]; if (VARSIZE(str) - VARHDRSZ > MAXDATELEN) - elog(ERROR, "Bad timestamp external representation (too long)"); + elog(ERROR, "TIMESTAMP bad external representation (too long)"); sp = VARDATA(str); dp = dstr; @@ -1767,7 +1937,7 @@ text_timestamptz(PG_FUNCTION_ARGS) dstr[MAXDATELEN + 1]; if (VARSIZE(str) - VARHDRSZ > MAXDATELEN) - elog(ERROR, "Bad timestamp with time zone external representation (too long)"); + elog(ERROR, "TIMESTAMP WITH TIME ZONE bad external representation (too long)"); sp = VARDATA(str); dp = dstr; @@ -1824,14 +1994,17 @@ text_interval(PG_FUNCTION_ARGS) dstr[MAXDATELEN + 1]; if (VARSIZE(str) - VARHDRSZ > MAXDATELEN) - elog(ERROR, "Bad interval external representation (too long)"); + elog(ERROR, "INTERVAL bad external representation (too long)"); sp = VARDATA(str); dp = dstr; for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++) *dp++ = *sp++; *dp = '\0'; - return DirectFunctionCall1(interval_in, CStringGetDatum(dstr)); + return DirectFunctionCall3(interval_in, + CStringGetDatum(dstr), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1)); } /* timestamp_trunc() @@ -1854,7 +2027,7 @@ timestamp_trunc(PG_FUNCTION_ARGS) *tm = &tt; if (VARSIZE(units) - VARHDRSZ > MAXDATELEN) - elog(ERROR, "Interval units '%s' not recognized", + elog(ERROR, "TIMESTAMP units '%s' not recognized", DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(units)))); up = VARDATA(units); @@ -1903,16 +2076,16 @@ timestamp_trunc(PG_FUNCTION_ARGS) break; default: - elog(ERROR, "Timestamp units '%s' not supported", lowunits); + elog(ERROR, "TIMESTAMP units '%s' not supported", lowunits); result = 0; } if (tm2timestamp(tm, fsec, NULL, &result) != 0) - elog(ERROR, "Unable to truncate timestamp to '%s'", lowunits); + elog(ERROR, "Unable to truncate TIMESTAMP to '%s'", lowunits); } else { - elog(ERROR, "Timestamp units '%s' not recognized", lowunits); + elog(ERROR, "TIMESTAMP units '%s' not recognized", lowunits); result = 0; } @@ -1941,7 +2114,7 @@ timestamptz_trunc(PG_FUNCTION_ARGS) *tm = &tt; if (VARSIZE(units) - VARHDRSZ > MAXDATELEN) - elog(ERROR, "Interval units '%s' not recognized", + elog(ERROR, "TIMESTAMP WITH TIME ZONE units '%s' not recognized", DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(units)))); up = VARDATA(units); @@ -1984,24 +2157,23 @@ timestamptz_trunc(PG_FUNCTION_ARGS) case DTK_MILLISEC: fsec = rint(fsec * 1000) / 1000; break; - case DTK_MICROSEC: fsec = rint(fsec * 1000000) / 1000000; break; default: - elog(ERROR, "Timestamp units '%s' not supported", lowunits); + elog(ERROR, "TIMESTAMP WITH TIME ZONE units '%s' not supported", lowunits); result = 0; } tz = DetermineLocalTimeZone(tm); if (tm2timestamp(tm, fsec, &tz, &result) != 0) - elog(ERROR, "Unable to truncate timestamp to '%s'", lowunits); + elog(ERROR, "Unable to truncate TIMESTAMP WITH TIME ZONE to '%s'", lowunits); } else { - elog(ERROR, "Timestamp units '%s' not recognized", lowunits); + elog(ERROR, "TIMESTAMP WITH TIME ZONE units '%s' not recognized", lowunits); PG_RETURN_NULL(); } @@ -2030,7 +2202,7 @@ interval_trunc(PG_FUNCTION_ARGS) result = (Interval *) palloc(sizeof(Interval)); if (VARSIZE(units) - VARHDRSZ > MAXDATELEN) - elog(ERROR, "Interval units '%s' not recognized", + elog(ERROR, "INTERVAL units '%s' not recognized", DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(units)))); up = VARDATA(units); @@ -2078,22 +2250,22 @@ interval_trunc(PG_FUNCTION_ARGS) break; default: - elog(ERROR, "Interval units '%s' not supported", lowunits); + elog(ERROR, "INTERVAL units '%s' not supported", lowunits); } if (tm2interval(tm, fsec, result) != 0) - elog(ERROR, "Unable to truncate interval to '%s'", lowunits); + elog(ERROR, "Unable to truncate INTERVAL to '%s'", lowunits); } else { - elog(NOTICE, "Unable to decode interval; internal coding error"); + elog(NOTICE, "Unable to decode INTERVAL; internal coding error"); *result = *interval; } } else { - elog(ERROR, "Interval units '%s' not recognized", + elog(ERROR, "INTERVAL units '%s' not recognized", DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(units)))); *result = *interval; @@ -2202,7 +2374,7 @@ timestamp_part(PG_FUNCTION_ARGS) *tm = &tt; if (VARSIZE(units) - VARHDRSZ > MAXDATELEN) - elog(ERROR, "Interval units '%s' not recognized", + elog(ERROR, "TIMESTAMP units '%s' not recognized", DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(units)))); up = VARDATA(units); @@ -2212,7 +2384,7 @@ timestamp_part(PG_FUNCTION_ARGS) *lp = '\0'; type = DecodeUnits(0, lowunits, &val); - if (type == IGNORE) + if (type == UNKNOWN_FIELD) type = DecodeSpecial(0, lowunits, &val); if (TIMESTAMP_NOT_FINITE(timestamp)) @@ -2221,7 +2393,8 @@ timestamp_part(PG_FUNCTION_ARGS) PG_RETURN_FLOAT8(result); } - if ((type == UNITS) && (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) == 0)) + if ((type == UNITS) + && (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) == 0)) { switch (val) { @@ -2281,7 +2454,7 @@ timestamp_part(PG_FUNCTION_ARGS) case DTK_TZ_MINUTE: case DTK_TZ_HOUR: default: - elog(ERROR, "Timestamp units '%s' not supported", lowunits); + elog(ERROR, "TIMESTAMP units '%s' not supported", lowunits); result = 0; } } @@ -2295,28 +2468,28 @@ timestamp_part(PG_FUNCTION_ARGS) case DTK_DOW: if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) != 0) - elog(ERROR, "Unable to encode timestamp"); + elog(ERROR, "Unable to encode TIMESTAMP"); result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)); break; case DTK_DOY: if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) != 0) - elog(ERROR, "Unable to encode timestamp"); + elog(ERROR, "Unable to encode TIMESTAMP"); result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(tm->tm_year, 1, 1) + 1); break; default: - elog(ERROR, "Timestamp units '%s' not supported", lowunits); + elog(ERROR, "TIMESTAMP units '%s' not supported", lowunits); result = 0; } } else { - elog(ERROR, "Timestamp units '%s' not recognized", lowunits); + elog(ERROR, "TIMESTAMP units '%s' not recognized", lowunits); result = 0; } @@ -2346,7 +2519,7 @@ timestamptz_part(PG_FUNCTION_ARGS) *tm = &tt; if (VARSIZE(units) - VARHDRSZ > MAXDATELEN) - elog(ERROR, "Interval units '%s' not recognized", + elog(ERROR, "TIMESTAMP WITH TIME ZONE units '%s' not recognized", DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(units)))); up = VARDATA(units); @@ -2356,7 +2529,7 @@ timestamptz_part(PG_FUNCTION_ARGS) *lp = '\0'; type = DecodeUnits(0, lowunits, &val); - if (type == IGNORE) + if (type == UNKNOWN_FIELD) type = DecodeSpecial(0, lowunits, &val); if (TIMESTAMP_NOT_FINITE(timestamp)) @@ -2436,7 +2609,7 @@ timestamptz_part(PG_FUNCTION_ARGS) break; default: - elog(ERROR, "Timestamp with time zone units '%s' not supported", lowunits); + elog(ERROR, "TIMESTAMP WITH TIME ZONE units '%s' not supported", lowunits); result = 0; } @@ -2451,27 +2624,27 @@ timestamptz_part(PG_FUNCTION_ARGS) case DTK_DOW: if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0) - elog(ERROR, "Unable to encode timestamp with time zone"); + elog(ERROR, "Unable to encode TIMESTAMP WITH TIME ZONE"); result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)); break; case DTK_DOY: if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0) - elog(ERROR, "Unable to encode timestamp with time zone"); + elog(ERROR, "Unable to encode TIMESTAMP WITH TIME ZONE"); result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(tm->tm_year, 1, 1) + 1); break; default: - elog(ERROR, "Timestamp with time zone units '%s' not supported", lowunits); + elog(ERROR, "TIMESTAMP WITH TIME ZONE units '%s' not supported", lowunits); result = 0; } } else { - elog(ERROR, "Timestamp with time zone units '%s' not recognized", lowunits); + elog(ERROR, "TIMESTAMP WITH TIME ZONE units '%s' not recognized", lowunits); result = 0; } @@ -2499,7 +2672,7 @@ interval_part(PG_FUNCTION_ARGS) *tm = &tt; if (VARSIZE(units) - VARHDRSZ > MAXDATELEN) - elog(ERROR, "Interval units '%s' not recognized", + elog(ERROR, "INTERVAL units '%s' not recognized", DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(units)))); up = VARDATA(units); @@ -2509,7 +2682,7 @@ interval_part(PG_FUNCTION_ARGS) *lp = '\0'; type = DecodeUnits(0, lowunits, &val); - if (type == IGNORE) + if (type == UNKNOWN_FIELD) type = DecodeSpecial(0, lowunits, &val); if (type == UNITS) @@ -2567,7 +2740,7 @@ interval_part(PG_FUNCTION_ARGS) break; default: - elog(ERROR, "Interval units '%s' not supported", + elog(ERROR, "INTERVAL units '%s' not supported", DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(units)))); result = 0; @@ -2576,7 +2749,7 @@ interval_part(PG_FUNCTION_ARGS) } else { - elog(NOTICE, "Unable to decode interval" + elog(NOTICE, "Unable to decode INTERVAL" "\n\tinterval_part() internal coding error"); result = 0; } @@ -2592,7 +2765,7 @@ interval_part(PG_FUNCTION_ARGS) } else { - elog(ERROR, "Interval units '%s' not recognized", + elog(ERROR, "INTERVAL units '%s' not recognized", DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(units)))); result = 0; @@ -2695,12 +2868,12 @@ timestamp_timestamptz(PG_FUNCTION_ARGS) else { if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) != 0) - elog(ERROR, "Unable to convert timestamp to timestamp with time zone (tm)"); + elog(ERROR, "Unable to convert TIMESTAMP to TIMESTAMP WITH TIME ZONE (tm)"); tz = DetermineLocalTimeZone(tm); if (tm2timestamp(tm, fsec, &tz, &result) != 0) - elog(ERROR, "Unable to convert timestamp to timestamp with time zone"); + elog(ERROR, "Unable to convert TIMESTAMP to TIMESTAMP WITH TIME ZONE"); } PG_RETURN_TIMESTAMPTZ(result); @@ -2727,10 +2900,10 @@ timestamptz_timestamp(PG_FUNCTION_ARGS) else { if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0) - elog(ERROR, "Unable to convert timestamp with time zone to timestamp (tm)"); + elog(ERROR, "Unable to convert TIMESTAMP WITH TIME ZONE to TIMESTAMP (tm)"); if (tm2timestamp(tm, fsec, NULL, &result) != 0) - elog(ERROR, "Unable to convert timestamp with time zone to timestamp"); + elog(ERROR, "Unable to convert TIMESTAMP WITH TIME ZONE to TIMESTAMP"); } PG_RETURN_TIMESTAMP(result); @@ -2784,8 +2957,8 @@ timestamptz_zone(PG_FUNCTION_ARGS) dt = dt2local(timestamp, tz); if (timestamp2tm(dt, NULL, tm, &fsec, NULL) != 0) - elog(ERROR, "Unable to decode timestamp" - "\n\ttimestamp_zone() internal coding error"); + elog(ERROR, "Unable to decode TIMESTAMP WITH TIME ZONE" + "\n\ttimestamptz_zone() internal coding error"); up = upzone; lp = lowzone; @@ -2845,8 +3018,8 @@ timestamptz_izone(PG_FUNCTION_ARGS) dt = dt2local(timestamp, tz); if (timestamp2tm(dt, NULL, tm, &fsec, NULL) != 0) - elog(ERROR, "Unable to decode timestamp" - "\n\ttimestamp_izone() internal coding error"); + elog(ERROR, "Unable to decode TIMESTAMP WITH TIME ZONE" + "\n\ttimestamptz_izone() internal coding error"); EncodeDateTime(tm, fsec, &tz, &tzn, USE_ISO_DATES, buf); len = (strlen(buf) + VARHDRSZ); diff --git a/src/include/access/xact.h b/src/include/access/xact.h index be5e9db665b..557e0768c3d 100644 --- a/src/include/access/xact.h +++ b/src/include/access/xact.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: xact.h,v 1.37 2001/09/28 08:09:12 thomas Exp $ + * $Id: xact.h,v 1.38 2001/10/18 17:30:15 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -40,7 +40,7 @@ typedef struct TransactionStateData CommandId commandId; CommandId scanCommandId; AbsoluteTime startTime; - int startTimeMsec; + int startTimeUsec; int state; int blockState; } TransactionStateData; diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 790bb6cf5c9..92eb1961fde 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: catversion.h,v 1.98 2001/10/03 17:22:05 tgl Exp $ + * $Id: catversion.h,v 1.99 2001/10/18 17:30:15 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200110031 +#define CATALOG_VERSION_NO 200110181 #endif diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 7f179d96307..5efc7bed03f 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_proc.h,v 1.216 2001/10/12 02:08:34 ishii Exp $ + * $Id: pg_proc.h,v 1.217 2001/10/18 17:30:15 thomas Exp $ * * NOTES * The script catalog/genbki.sh reads this file and generates .bki @@ -1434,7 +1434,6 @@ DATA(insert OID = 1171 ( date_part PGUID 12 f t f t 2 f 701 "25 1184" 100 DESCR("extract field from timestamp with time zone"); DATA(insert OID = 1172 ( date_part PGUID 12 f t t t 2 f 701 "25 1186" 100 0 0 100 interval_part - )); DESCR("extract field from interval"); - DATA(insert OID = 1173 ( timestamptz PGUID 12 f t f t 1 f 1184 "702" 100 0 0 100 abstime_timestamptz - )); DESCR("convert abstime to timestamp with time zone"); DATA(insert OID = 1174 ( timestamptz PGUID 12 f t f t 1 f 1184 "1082" 100 0 0 100 date_timestamptz - )); @@ -1523,7 +1522,8 @@ DATA(insert OID = 1271 ( overlaps PGUID 12 f t t f 4 f 16 "1266 1266 1266 1 DESCR("SQL92 interval comparison"); DATA(insert OID = 1272 ( datetime_pl PGUID 12 f t t t 2 f 1114 "1082 1083" 100 0 0 100 datetime_timestamp - )); DESCR("convert date and time to timestamp"); - +DATA(insert OID = 1273 ( date_part PGUID 12 f t t t 2 f 701 "25 1266" 100 0 0 100 timetz_part - )); +DESCR("extract field from time with time zone"); DATA(insert OID = 1274 ( int84pl PGUID 12 f t t t 2 f 20 "20 23" 100 0 0 100 int84pl - )); DESCR("add"); DATA(insert OID = 1275 ( int84mi PGUID 12 f t t t 2 f 20 "20 23" 100 0 0 100 int84mi - )); @@ -1709,11 +1709,11 @@ DESCR("length"); DATA(insert OID = 1382 ( date_part PGUID 14 f t f t 2 f 701 "25 702" 100 0 0 100 "select date_part($1, timestamptz($2))" - )); DESCR("extract field from abstime"); -DATA(insert OID = 1383 ( date_part PGUID 14 f t f t 2 f 701 "25 703" 100 0 0 100 "select date_part($1, interval($2))" - )); +DATA(insert OID = 1383 ( date_part PGUID 14 f t f t 2 f 701 "25 703" 100 0 0 100 "select date_part($1, cast($2 as interval))" - )); DESCR("extract field from reltime"); DATA(insert OID = 1384 ( date_part PGUID 14 f t t t 2 f 701 "25 1082" 100 0 0 100 "select date_part($1, cast($2 as timestamp without time zone))" - )); DESCR("extract field from date"); -DATA(insert OID = 1385 ( date_part PGUID 14 f t t t 2 f 701 "25 1083" 100 0 0 100 "select date_part($1, interval($2))" - )); +DATA(insert OID = 1385 ( date_part PGUID 14 f t t t 2 f 701 "25 1083" 100 0 0 100 "select date_part($1, cast($2 as time with time zone))" - )); DESCR("extract field from time"); DATA(insert OID = 1386 ( age PGUID 14 f t f t 1 f 1186 "1184" 100 0 0 100 "select age(cast(current_date as timestamp with time zone), $1)" - )); DESCR("date difference from today preserving months and years"); diff --git a/src/include/commands/variable.h b/src/include/commands/variable.h index c1e9541e5a8..75e88b806bc 100644 --- a/src/include/commands/variable.h +++ b/src/include/commands/variable.h @@ -2,13 +2,13 @@ * Headers for handling of 'SET var TO', 'SHOW var' and 'RESET var' * statements * - * $Id: variable.h,v 1.13 2000/10/26 17:31:33 tgl Exp $ + * $Id: variable.h,v 1.14 2001/10/18 17:30:16 thomas Exp $ * */ #ifndef VARIABLE_H #define VARIABLE_H -extern void SetPGVariable(const char *name, const char *value); +extern void SetPGVariable(const char *name, List *args); extern void GetPGVariable(const char *name); extern void ResetPGVariable(const char *name); diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 44961bcca94..ef6c9c63b5b 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parsenodes.h,v 1.146 2001/10/12 00:07:15 tgl Exp $ + * $Id: parsenodes.h,v 1.147 2001/10/18 17:30:16 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -736,7 +736,7 @@ typedef struct VariableSetStmt { NodeTag type; char *name; - char *value; + List *args; } VariableSetStmt; /* ---------------------- diff --git a/src/include/utils/date.h b/src/include/utils/date.h index 2698fc90d41..0e1aa141280 100644 --- a/src/include/utils/date.h +++ b/src/include/utils/date.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: date.h,v 1.13 2001/10/03 05:29:25 thomas Exp $ + * $Id: date.h,v 1.14 2001/10/18 17:30:16 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -118,6 +118,7 @@ extern Datum timestamptz_timetz(PG_FUNCTION_ARGS); extern Datum datetimetz_timestamptz(PG_FUNCTION_ARGS); extern Datum text_timetz(PG_FUNCTION_ARGS); extern Datum timetz_text(PG_FUNCTION_ARGS); +extern Datum timetz_part(PG_FUNCTION_ARGS); extern Datum timetz_zone(PG_FUNCTION_ARGS); extern Datum timetz_izone(PG_FUNCTION_ARGS); extern Datum timetz_pl_interval(PG_FUNCTION_ARGS); diff --git a/src/include/utils/nabstime.h b/src/include/utils/nabstime.h index 299c7dbc604..b7aaf0d0acb 100644 --- a/src/include/utils/nabstime.h +++ b/src/include/utils/nabstime.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: nabstime.h,v 1.31 2001/09/28 08:09:14 thomas Exp $ + * $Id: nabstime.h,v 1.32 2001/10/18 17:30:16 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -158,6 +158,6 @@ extern Datum timeofday(PG_FUNCTION_ARGS); /* non-fmgr-callable support routines */ extern AbsoluteTime GetCurrentAbsoluteTime(void); extern AbsoluteTime GetCurrentAbsoluteTimeUsec(int *usec); -extern void abstime2tm(AbsoluteTime time, int *tzp, struct tm * tm, char *tzn); +extern void abstime2tm(AbsoluteTime time, int *tzp, struct tm * tm, char **tzn); #endif /* NABSTIME_H */ diff --git a/src/include/utils/timestamp.h b/src/include/utils/timestamp.h index 1a5f28f592c..1e193bed3bb 100644 --- a/src/include/utils/timestamp.h +++ b/src/include/utils/timestamp.h @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: timestamp.h,v 1.20 2001/10/03 15:42:12 tgl Exp $ + * $Id: timestamp.h,v 1.21 2001/10/18 17:30:16 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -105,6 +105,7 @@ extern Datum timestamp_larger(PG_FUNCTION_ARGS); extern Datum interval_in(PG_FUNCTION_ARGS); extern Datum interval_out(PG_FUNCTION_ARGS); +extern Datum interval_scale(PG_FUNCTION_ARGS); extern Datum interval_eq(PG_FUNCTION_ARGS); extern Datum interval_ne(PG_FUNCTION_ARGS); extern Datum interval_lt(PG_FUNCTION_ARGS); diff --git a/src/interfaces/odbc/convert.c b/src/interfaces/odbc/convert.c index 5e20631067d..3e7d24169c4 100644 --- a/src/interfaces/odbc/convert.c +++ b/src/interfaces/odbc/convert.c @@ -1788,8 +1788,8 @@ convert_escape(char *value) mapFunc = mapFunction(key); /* - * We could have mapFunction() return key if not in table... - - * thomas 2000-04-03 + * We could have mapFunction() return key if not in table... + * - thomas 2000-04-03 */ if (mapFunc == NULL) { diff --git a/src/test/regress/expected/horology.out b/src/test/regress/expected/horology.out index 21ad6469b89..c0dec193906 100644 --- a/src/test/regress/expected/horology.out +++ b/src/test/regress/expected/horology.out @@ -1310,9 +1310,9 @@ SELECT '' AS "16", f1 AS "timestamp" | Sat Sep 22 18:19:20 2001 PDT (16 rows) -SELECT '' AS "160", d.f1 AS "timestamp", t.f1 AS interval, d.f1 + t.f1 AS plus +SELECT '' AS "160", d.f1 AS "timestamp", t.f1 AS "interval", d.f1 + t.f1 AS plus FROM TEMP_TIMESTAMP d, INTERVAL_TBL t - ORDER BY plus, "timestamp", interval; + ORDER BY plus, "timestamp", "interval"; 160 | timestamp | interval | plus -----+------------------------------+-------------------------------+------------------------------ | Thu Jan 01 00:00:00 1970 PST | @ 14 secs ago | Wed Dec 31 23:59:46 1969 PST @@ -1477,10 +1477,10 @@ SELECT '' AS "160", d.f1 AS "timestamp", t.f1 AS interval, d.f1 + t.f1 AS plus | Sat Sep 22 18:19:20 2001 PDT | @ 34 years | Sat Sep 22 18:19:20 2035 PDT (160 rows) -SELECT '' AS "160", d.f1 AS "timestamp", t.f1 AS interval, d.f1 - t.f1 AS minus +SELECT '' AS "160", d.f1 AS "timestamp", t.f1 AS "interval", d.f1 - t.f1 AS minus FROM TEMP_TIMESTAMP d, INTERVAL_TBL t WHERE isfinite(d.f1) - ORDER BY minus, "timestamp", interval; + ORDER BY minus, "timestamp", "interval"; 160 | timestamp | interval | minus -----+------------------------------+-------------------------------+------------------------------ | Thu Jan 01 00:00:00 1970 PST | @ 34 years | Wed Jan 01 00:00:00 1936 PST @@ -2084,7 +2084,7 @@ SELECT '' AS ten, f1 AS interval, reltime(f1) AS reltime | @ 5 mons 12 hours | @ 5 mons 12 hours (10 rows) -SELECT '' AS six, f1 as reltime, interval(f1) AS interval +SELECT '' AS six, f1 as reltime, CAST(f1 AS interval) AS interval FROM RELTIME_TBL; six | reltime | interval -----+---------------+--------------- diff --git a/src/test/regress/expected/timestamp.out b/src/test/regress/expected/timestamp.out index 9405e8ba1cb..70fa14c31a6 100644 --- a/src/test/regress/expected/timestamp.out +++ b/src/test/regress/expected/timestamp.out @@ -59,7 +59,7 @@ INSERT INTO TIMESTAMP_TBL VALUES ('infinity'); INSERT INTO TIMESTAMP_TBL VALUES ('epoch'); -- Obsolete special values INSERT INTO TIMESTAMP_TBL VALUES ('invalid'); -ERROR: Timestamp 'invalid' no longer supported +ERROR: TIMESTAMP 'invalid' no longer supported -- Postgres v6.0 standard output format INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01 1997 PST'); INSERT INTO TIMESTAMP_TBL VALUES ('Invalid Abstime'); @@ -137,7 +137,7 @@ INSERT INTO TIMESTAMP_TBL VALUES ('Jan 01 17:32:01 2001'); INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 -0097'); ERROR: Bad timestamp external representation 'Feb 16 17:32:01 -0097' INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 5097 BC'); -ERROR: Timestamp out of range 'Feb 16 17:32:01 5097 BC' +ERROR: TIMESTAMP out of range 'Feb 16 17:32:01 5097 BC' SELECT '' AS "64", d1 FROM TIMESTAMP_TBL; 64 | d1 ----+----------------------------- diff --git a/src/test/regress/expected/timestamptz.out b/src/test/regress/expected/timestamptz.out index ed11d1629d9..dd7ef75ce8f 100644 --- a/src/test/regress/expected/timestamptz.out +++ b/src/test/regress/expected/timestamptz.out @@ -54,7 +54,7 @@ INSERT INTO TIMESTAMPTZ_TBL VALUES ('infinity'); INSERT INTO TIMESTAMPTZ_TBL VALUES ('epoch'); -- Obsolete special values INSERT INTO TIMESTAMPTZ_TBL VALUES ('invalid'); -ERROR: Timestamp with time zone 'invalid' no longer supported +ERROR: TIMESTAMP WITH TIME ZONE 'invalid' no longer supported -- Postgres v6.0 standard output format INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01 1997 PST'); INSERT INTO TIMESTAMPTZ_TBL VALUES ('Invalid Abstime'); @@ -132,7 +132,7 @@ INSERT INTO TIMESTAMPTZ_TBL VALUES ('Jan 01 17:32:01 2001'); INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 -0097'); ERROR: Bad timestamp external representation 'Feb 16 17:32:01 -0097' INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 5097 BC'); -ERROR: Timestamp out of range 'Feb 16 17:32:01 5097 BC' +ERROR: TIMESTAMP WITH TIME ZONE out of range 'Feb 16 17:32:01 5097 BC' SELECT '' AS "64", d1 FROM TIMESTAMPTZ_TBL; 64 | d1 ----+--------------------------------- diff --git a/src/test/regress/sql/horology.sql b/src/test/regress/sql/horology.sql index 956e6697ee7..9e4652171ad 100644 --- a/src/test/regress/sql/horology.sql +++ b/src/test/regress/sql/horology.sql @@ -177,14 +177,14 @@ SELECT '' AS "16", f1 AS "timestamp" FROM TEMP_TIMESTAMP ORDER BY "timestamp"; -SELECT '' AS "160", d.f1 AS "timestamp", t.f1 AS interval, d.f1 + t.f1 AS plus +SELECT '' AS "160", d.f1 AS "timestamp", t.f1 AS "interval", d.f1 + t.f1 AS plus FROM TEMP_TIMESTAMP d, INTERVAL_TBL t - ORDER BY plus, "timestamp", interval; + ORDER BY plus, "timestamp", "interval"; -SELECT '' AS "160", d.f1 AS "timestamp", t.f1 AS interval, d.f1 - t.f1 AS minus +SELECT '' AS "160", d.f1 AS "timestamp", t.f1 AS "interval", d.f1 - t.f1 AS minus FROM TEMP_TIMESTAMP d, INTERVAL_TBL t WHERE isfinite(d.f1) - ORDER BY minus, "timestamp", interval; + ORDER BY minus, "timestamp", "interval"; SELECT '' AS "16", d.f1 AS "timestamp", timestamp '1980-01-06 00:00 GMT' AS gpstime_zero, d.f1 - timestamp '1980-01-06 00:00 GMT' AS difference @@ -250,7 +250,7 @@ SELECT '' AS three, f1 as abstime, cast(f1 as timestamp) AS "timestamp" SELECT '' AS ten, f1 AS interval, reltime(f1) AS reltime FROM INTERVAL_TBL; -SELECT '' AS six, f1 as reltime, interval(f1) AS interval +SELECT '' AS six, f1 as reltime, CAST(f1 AS interval) AS interval FROM RELTIME_TBL; DROP TABLE TEMP_TIMESTAMP; |