aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/catalog/heap.c6
-rw-r--r--src/backend/commands/explain.c32
-rw-r--r--src/backend/nodes/copyfuncs.c3
-rw-r--r--src/backend/nodes/freefuncs.c3
-rw-r--r--src/backend/optimizer/prep/prepunion.c6
-rw-r--r--src/backend/parser/analyze.c34
-rw-r--r--src/backend/parser/gram.y72
-rw-r--r--src/backend/parser/keywords.c3
-rw-r--r--src/backend/parser/parse_agg.c4
-rw-r--r--src/backend/parser/parse_clause.c6
-rw-r--r--src/backend/parser/parse_coerce.c3
-rw-r--r--src/backend/parser/parse_expr.c12
-rw-r--r--src/backend/parser/parse_func.c8
-rw-r--r--src/backend/parser/parse_relation.c45
-rw-r--r--src/backend/parser/parse_target.c4
-rw-r--r--src/backend/utils/adt/date.c336
-rw-r--r--src/backend/utils/adt/datetime.c82
-rw-r--r--src/backend/utils/adt/float.c27
-rw-r--r--src/backend/utils/adt/geo_ops.c25
-rw-r--r--src/backend/utils/adt/int.c23
-rw-r--r--src/backend/utils/adt/int8.c59
-rw-r--r--src/backend/utils/adt/oracle_compat.c68
-rw-r--r--src/backend/utils/adt/ruleutils.c18
-rw-r--r--src/backend/utils/adt/timestamp.c28
24 files changed, 739 insertions, 168 deletions
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 271dc3ed978..c90516be801 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.122 2000/02/18 09:28:40 inoue Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.123 2000/03/14 23:06:06 thomas Exp $
*
*
* INTERFACE ROUTINES
@@ -1719,8 +1719,10 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin,
*/
rte = makeNode(RangeTblEntry);
rte->relname = RelationGetRelationName(rel);
+#ifndef DISABLE_EREF
rte->ref = makeNode(Attr);
rte->ref->relname = RelationGetRelationName(rel);
+#endif
rte->relid = RelationGetRelid(rel);
rte->inh = false;
rte->inFromCl = true;
@@ -1799,8 +1801,10 @@ StoreRelCheck(Relation rel, char *ccname, char *ccbin)
*/
rte = makeNode(RangeTblEntry);
rte->relname = RelationGetRelationName(rel);
+#ifndef DISABLE_EREF
rte->ref = makeNode(Attr);
rte->ref->relname = RelationGetRelationName(rel);
+#endif
rte->relid = RelationGetRelid(rel);
rte->inh = false;
rte->inFromCl = true;
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 2a38a349d60..64dc164a0d5 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -5,7 +5,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994-5, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.54 2000/02/15 20:49:08 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.55 2000/03/14 23:06:12 thomas Exp $
*
*/
@@ -232,9 +232,33 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
appendStringInfo(str, " on %s",
stringStringInfo(rte->relname));
- if (rte->ref && strcmp(rte->ref->relname, rte->relname) != 0)
- appendStringInfo(str, " %s",
- stringStringInfo(rte->ref->relname));
+ if (rte->ref != NULL)
+ {
+ if ((strcmp(rte->ref->relname, rte->relname) != 0)
+ || (length(rte->ref->attrs) > 0))
+ {
+ appendStringInfo(str, " %s",
+ stringStringInfo(rte->ref->relname));
+
+ if (length(rte->ref->attrs) > 0)
+ {
+ List *c;
+ int firstEntry = true;
+
+ appendStringInfo(str, " (");
+ foreach (c, rte->ref->attrs)
+ {
+ if (! firstEntry)
+ {
+ appendStringInfo(str, ", ");
+ firstEntry = false;
+ }
+ appendStringInfo(str, "%s", strVal(lfirst(c)));
+ }
+ appendStringInfo(str, ")");
+ }
+ }
+ }
}
break;
default:
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 601b503ec11..6afa4d8549f 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.108 2000/02/21 18:47:00 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.109 2000/03/14 23:06:27 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1366,6 +1366,7 @@ _copyRangeTblEntry(RangeTblEntry *from)
if (from->relname)
newnode->relname = pstrdup(from->relname);
Node_Copy(from, newnode, ref);
+ Node_Copy(from, newnode, eref);
newnode->relid = from->relid;
newnode->inh = from->inh;
newnode->inFromCl = from->inFromCl;
diff --git a/src/backend/nodes/freefuncs.c b/src/backend/nodes/freefuncs.c
index 14a5ed12d9e..96ce56c94c4 100644
--- a/src/backend/nodes/freefuncs.c
+++ b/src/backend/nodes/freefuncs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.38 2000/02/21 18:47:00 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.39 2000/03/14 23:06:28 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1031,6 +1031,7 @@ _freeRangeTblEntry(RangeTblEntry *node)
if (node->relname)
pfree(node->relname);
freeObject(node->ref);
+ freeObject(node->eref);
pfree(node);
}
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index 10a48c666e6..c0e09dc6d9b 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.45 2000/02/15 20:49:19 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.46 2000/03/14 23:06:29 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -454,8 +454,8 @@ new_rangetable_entry(Oid new_relid, RangeTblEntry *old_entry)
RangeTblEntry *new_entry = copyObject(old_entry);
/* ??? someone tell me what the following is doing! - ay 11/94 */
- if (!strcmp(new_entry->ref->relname, "*CURRENT*") ||
- !strcmp(new_entry->ref->relname, "*NEW*"))
+ if (!strcmp(new_entry->eref->relname, "*CURRENT*") ||
+ !strcmp(new_entry->eref->relname, "*NEW*"))
new_entry->ref->relname = get_rel_name(new_relid);
else
new_entry->relname = get_rel_name(new_relid);
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 612481deabc..c192b4ce7a1 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: analyze.c,v 1.139 2000/03/01 05:18:20 tgl Exp $
+ * $Id: analyze.c,v 1.140 2000/03/14 23:06:30 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -146,6 +146,34 @@ transformStmt(ParseState *pstate, Node *parseTree)
ViewStmt *n = (ViewStmt *) parseTree;
n->query = (Query *) transformStmt(pstate, (Node *) n->query);
+
+ /* If a list of column names was given, run through and insert these
+ * into the actual query tree. - thomas 2000-03-08
+ */
+ if (n->aliases != NIL)
+ {
+ int i;
+ List *targetList = n->query->targetList;
+
+ if (length(targetList) < length(n->aliases))
+ elog(ERROR, "CREATE VIEW specifies %d columns"
+ " but only %d columns are present",
+ length(targetList), length(n->aliases));
+
+ for (i = 0; i < length(n->aliases); i++)
+ {
+ Ident *id;
+ TargetEntry *te;
+ Resdom *rd;
+ id = nth(i, n->aliases);
+ Assert(nodeTag(id) == T_Ident);
+ te = nth(i, targetList);
+ Assert(nodeTag(te) == T_TargetEntry);
+ rd = te->resdom;
+ Assert(nodeTag(rd) == T_Resdom);
+ rd->resname = pstrdup(id->name);
+ }
+ }
result = makeNode(Query);
result->commandType = CMD_UTILITY;
result->utilityStmt = (Node *) n;
@@ -1904,7 +1932,7 @@ transformForUpdate(Query *qry, List *forUpdate)
i = 1;
foreach(l2, qry->rtable)
{
- if (strcmp(((RangeTblEntry *) lfirst(l2))->ref->relname, relname) == 0)
+ if (strcmp(((RangeTblEntry *) lfirst(l2))->eref->relname, relname) == 0)
{
List *l3;
@@ -1925,7 +1953,7 @@ transformForUpdate(Query *qry, List *forUpdate)
i++;
}
if (l2 == NULL)
- elog(ERROR, "FOR UPDATE: relation %s not found in FROM clause",
+ elog(ERROR, "FOR UPDATE: relation '%s' not found in FROM clause",
relname);
}
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index ab69eb4794f..c4d98d203ec 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.155 2000/03/12 20:09:41 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.156 2000/03/14 23:06:31 thomas Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -307,7 +307,7 @@ static void doNegateFloat(Value *v);
ISOLATION, JOIN, KEY, LANGUAGE, LEADING, LEFT, LEVEL, LIKE, LOCAL,
MATCH, MINUTE_P, MONTH_P, NAMES,
NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULLIF, NULL_P, NUMERIC,
- OF, ON, ONLY, OPTION, OR, ORDER, OUTER_P,
+ OF, ON, ONLY, OPTION, OR, ORDER, OUTER_P, OVERLAPS,
PARTIAL, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC,
READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK,
SCROLL, SECOND_P, SELECT, SESSION_USER, SET, SUBSTRING,
@@ -363,6 +363,7 @@ static void doNegateFloat(Value *v);
%right '='
%nonassoc '<' '>'
%nonassoc LIKE
+%nonassoc OVERLAPS
%nonassoc BETWEEN
%nonassoc IN
%left Op /* multi-character ops and user-defined operators */
@@ -1903,7 +1904,7 @@ comment_text: Sconst { $$ = $1; }
*
*****************************************************************************/
-FetchStmt: FETCH direction fetch_how_many from_in name
+FetchStmt: FETCH direction fetch_how_many from_in name
{
FetchStmt *n = makeNode(FetchStmt);
if ($2 == RELATIVE)
@@ -1923,7 +1924,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name
n->ismove = false;
$$ = (Node *)n;
}
- | FETCH fetch_how_many from_in name
+ | FETCH fetch_how_many from_in name
{
FetchStmt *n = makeNode(FetchStmt);
if ($2 < 0)
@@ -1940,7 +1941,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name
n->ismove = false;
$$ = (Node *)n;
}
- | FETCH direction from_in name
+ | FETCH direction from_in name
{
FetchStmt *n = makeNode(FetchStmt);
if ($2 == RELATIVE)
@@ -1953,7 +1954,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name
n->ismove = false;
$$ = (Node *)n;
}
- | FETCH from_in name
+ | FETCH from_in name
{
FetchStmt *n = makeNode(FetchStmt);
n->direction = FORWARD;
@@ -1962,7 +1963,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name
n->ismove = false;
$$ = (Node *)n;
}
- | FETCH name
+ | FETCH name
{
FetchStmt *n = makeNode(FetchStmt);
n->direction = FORWARD;
@@ -1972,7 +1973,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name
$$ = (Node *)n;
}
- | MOVE direction fetch_how_many from_in name
+ | MOVE direction fetch_how_many from_in name
{
FetchStmt *n = makeNode(FetchStmt);
if ($3 < 0)
@@ -1986,7 +1987,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name
n->ismove = TRUE;
$$ = (Node *)n;
}
- | MOVE fetch_how_many from_in name
+ | MOVE fetch_how_many from_in name
{
FetchStmt *n = makeNode(FetchStmt);
if ($2 < 0)
@@ -2003,7 +2004,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name
n->ismove = TRUE;
$$ = (Node *)n;
}
- | MOVE direction from_in name
+ | MOVE direction from_in name
{
FetchStmt *n = makeNode(FetchStmt);
n->direction = $2;
@@ -2021,7 +2022,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name
n->ismove = TRUE;
$$ = (Node *)n;
}
- | MOVE name
+ | MOVE name
{
FetchStmt *n = makeNode(FetchStmt);
n->direction = FORWARD;
@@ -2659,11 +2660,12 @@ opt_trans: WORK { $$ = TRUE; }
*
*****************************************************************************/
-ViewStmt: CREATE VIEW name AS SelectStmt
+ViewStmt: CREATE VIEW name opt_column_list AS SelectStmt
{
ViewStmt *n = makeNode(ViewStmt);
n->viewname = $3;
- n->query = (Query *)$5;
+ n->aliases = $4;
+ n->query = (Query *)$6;
if (((SelectStmt *)n->query)->sortClause != NULL)
elog(ERROR,"ORDER BY and DISTINCT on views are not implemented");
if (((SelectStmt *)n->query)->unionClause != NULL)
@@ -2737,7 +2739,7 @@ createdb_opt_encoding:
int i;
i = pg_char_to_encoding($3);
if (i == -1)
- elog(ERROR, "%s is not a valid encoding name.", $3);
+ elog(ERROR, "%s is not a valid encoding name", $3);
$$ = i;
#else
elog(ERROR, "Multi-byte support is not enabled");
@@ -2747,7 +2749,7 @@ createdb_opt_encoding:
{
#ifdef MULTIBYTE
if (!pg_get_encent_by_encoding($3))
- elog(ERROR, "%d is not a valid encoding code.", $3);
+ elog(ERROR, "%d is not a valid encoding code", $3);
$$ = $3;
#else
elog(ERROR, "Multi-byte support is not enabled");
@@ -3979,10 +3981,13 @@ Datetime: datetime
$$->timezone = $2;
$$->typmod = -1;
}
- | TIME
+ | TIME opt_timezone
{
$$ = makeNode(TypeName);
- $$->name = xlateSqlType("time");
+ if ($2)
+ $$->name = xlateSqlType("timetz");
+ else
+ $$->name = xlateSqlType("time");
$$->typmod = -1;
}
| INTERVAL opt_interval
@@ -4077,6 +4082,27 @@ row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
{
$$ = makeRowExpr($4, $2, $6);
}
+ | '(' row_descriptor ')' OVERLAPS '(' row_descriptor ')'
+ {
+ FuncCall *n = makeNode(FuncCall);
+ List *largs = $2;
+ List *rargs = $6;
+ n->funcname = xlateSqlFunc("overlaps");
+ if (length(largs) == 1)
+ largs = lappend(largs, $2);
+ else if (length(largs) != 2)
+ elog(ERROR, "Wrong number of parameters"
+ " on left side of OVERLAPS expression");
+ if (length(rargs) == 1)
+ rargs = lappend(rargs, $6);
+ else if (length(rargs) != 2)
+ elog(ERROR, "Wrong number of parameters"
+ " on right side of OVERLAPS expression");
+ n->args = nconc(largs, rargs);
+ n->agg_star = false;
+ n->agg_distinct = false;
+ $$ = (Node *)n;
+ }
;
row_descriptor: row_list ',' a_expr
@@ -4579,7 +4605,8 @@ c_expr: attr
n->agg_distinct = false;
if ($3 != 0)
- elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
+ elog(NOTICE,"CURRENT_TIME(%d) precision not implemented"
+ "; zero used instead",$3);
$$ = (Node *)n;
}
@@ -4632,7 +4659,8 @@ c_expr: attr
n->agg_distinct = false;
if ($3 != 0)
- elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
+ elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented"
+ "; zero used instead",$3);
$$ = (Node *)n;
}
@@ -5219,6 +5247,7 @@ ColId: IDENT { $$ = $1; }
| ONLY { $$ = "only"; }
| OPERATOR { $$ = "operator"; }
| OPTION { $$ = "option"; }
+ | OVERLAPS { $$ = "overlaps"; }
| PASSWORD { $$ = "password"; }
| PENDANT { $$ = "pendant"; }
| PRIOR { $$ = "prior"; }
@@ -5454,9 +5483,8 @@ mapTargetColumns(List *src, List *dst)
static char *
xlateSqlFunc(char *name)
{
- if (!strcasecmp(name,"character_length")
- || !strcasecmp(name,"char_length"))
- return "length";
+ if (!strcasecmp(name,"character_length"))
+ return "char_length";
else
return name;
} /* xlateSqlFunc() */
diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c
index d971e95762d..5bf703703d3 100644
--- a/src/backend/parser/keywords.c
+++ b/src/backend/parser/keywords.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.67 2000/02/18 09:29:40 inoue Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.68 2000/03/14 23:06:32 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -184,6 +184,7 @@ static ScanKeyword ScanKeywords[] = {
{"or", OR},
{"order", ORDER},
{"outer", OUTER_P},
+ {"overlaps", OVERLAPS},
{"partial", PARTIAL},
{"password", PASSWORD},
{"pendant", PENDANT},
diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c
index afaa55e54f1..17cc026bfde 100644
--- a/src/backend/parser/parse_agg.c
+++ b/src/backend/parser/parse_agg.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.34 2000/02/15 03:37:47 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.35 2000/03/14 23:06:32 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -111,7 +111,7 @@ check_ungrouped_columns_walker(Node *node,
elog(ERROR, "cache lookup of attribute %d in relation %u failed",
var->varattno, rte->relid);
elog(ERROR, "Attribute %s.%s must be GROUPed or used in an aggregate function",
- rte->ref->relname, attname);
+ rte->eref->relname, attname);
}
/* Otherwise, recurse. */
return expression_tree_walker(node, check_ungrouped_columns_walker,
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index 68da571f922..53d9b25f11b 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.55 2000/02/19 23:45:05 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.56 2000/03/14 23:06:32 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -478,7 +478,7 @@ parseFromClause(ParseState *pstate, List *frmList)
{
Assert(IsA(j->larg, RangeVar));
l_rte = transformTableEntry(pstate, (RangeVar *) j->larg);
- l_name = expandTable(pstate, l_rte->ref->relname, TRUE);
+ l_name = expandTable(pstate, l_rte->eref->relname, TRUE);
}
if (IsA(j->rarg, JoinExpr))
@@ -490,7 +490,7 @@ parseFromClause(ParseState *pstate, List *frmList)
{
Assert(IsA(j->rarg, RangeVar));
r_rte = transformTableEntry(pstate, (RangeVar *) j->rarg);
- r_name = expandTable(pstate, r_rte->ref->relname, TRUE);
+ r_name = expandTable(pstate, r_rte->eref->relname, TRUE);
}
/* Natural join does not explicitly specify columns; must generate columns to join.
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index 210a8f946e3..ce06da2669e 100644
--- a/src/backend/parser/parse_coerce.c
+++ b/src/backend/parser/parse_coerce.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.34 2000/03/11 23:19:50 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.35 2000/03/14 23:06:32 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -319,6 +319,7 @@ TypeCategory(Oid inType)
case (DATEOID):
case (TIMEOID):
+ case (TIMETZOID):
case (ABSTIMEOID):
case (TIMESTAMPOID):
result = DATETIME_TYPE;
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index e1e86199722..e2e297cb6b6 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.72 2000/03/07 23:30:53 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.73 2000/03/14 23:06:32 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -574,15 +574,7 @@ transformIdent(ParseState *pstate, Ident *ident, int precedence)
if ((rte = colnameRangeTableEntry(pstate, ident->name)) != NULL)
{
/* Convert it to a fully qualified Attr, and transform that */
-#ifndef DISABLE_JOIN_SYNTAX
- Attr *att = makeAttr(rte->ref->relname, ident->name);
-#else
- Attr *att = makeNode(Attr);
-
- att->relname = rte->refname;
- att->paramNo = NULL;
- att->attrs = lcons(makeString(ident->name), NIL);
-#endif
+ Attr *att = makeAttr(rte->eref->relname, ident->name);
att->indirection = ident->indirection;
return transformAttr(pstate, att, precedence);
}
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index 90c65a3830e..eb4884accbb 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.73 2000/03/11 23:17:47 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.74 2000/03/14 23:06:32 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -325,7 +325,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
* now allow column aliases.
* - thomas 2000-02-07
*/
- if (rte->ref->attrs != NULL)
+ if (rte->eref->attrs != NULL)
{
List *c;
/* start counting attributes/columns from one.
@@ -333,7 +333,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
* - thomas 2000-01-27
*/
int i = 1;
- foreach (c, rte->ref->attrs)
+ foreach (c, rte->eref->attrs)
{
char *colname = strVal(lfirst(c));
/* found a match? */
@@ -550,7 +550,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
relname = rte->relname;
- vnum = refnameRangeTablePosn(pstate, rte->ref->relname, NULL);
+ vnum = refnameRangeTablePosn(pstate, rte->eref->relname, NULL);
/*
* for func(relname), the param to the function is the tuple
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index 265642faaf3..4a943af6739 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.36 2000/03/09 05:00:24 inoue Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.37 2000/03/14 23:06:33 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -68,8 +68,12 @@ static char *attnum_type[SPECIALS] = {
/* refnameRangeTableEntries()
* Given refname, return a list of range table entries
* This is possible with JOIN syntax, where tables in a join
- * acquire the same reference name
+ * acquire the same reference name.
* - thomas 2000-01-20
+ * But at the moment we aren't carrying along a full list of
+ * table/column aliases, so we don't have the full mechanism
+ * to support outer joins in place yet.
+ * - thomas 2000-03-04
*/
List *
refnameRangeTableEntries(ParseState *pstate, char *refname);
@@ -86,7 +90,7 @@ refnameRangeTableEntries(ParseState *pstate, char *refname)
{
RangeTblEntry *rte = lfirst(temp);
- if (strcmp(rte->ref->relname, refname) == 0)
+ if (strcmp(rte->eref->relname, refname) == 0)
rteList = lappend(rteList, rte);
}
/* only allow correlated columns in WHERE clause */
@@ -110,11 +114,7 @@ refnameRangeTableEntry(ParseState *pstate, char *refname)
{
RangeTblEntry *rte = lfirst(temp);
-#ifndef DISABLE_JOIN_SYNTAX
- if (strcmp(rte->ref->relname, refname) == 0)
-#else
- if (!strcmp(rte->refname, refname))
-#endif
+ if (strcmp(rte->eref->relname, refname) == 0)
return rte;
}
/* only allow correlated columns in WHERE clause */
@@ -143,11 +143,7 @@ refnameRangeTablePosn(ParseState *pstate, char *refname, int *sublevels_up)
{
RangeTblEntry *rte = lfirst(temp);
-#ifndef DISABLE_JOIN_SYNTAX
- if (strcmp(rte->ref->relname, refname) == 0)
-#else
- if (!strcmp(rte->refname, refname))
-#endif
+ if (strcmp(rte->eref->relname, refname) == 0)
return index;
index++;
}
@@ -191,7 +187,7 @@ colnameRangeTableEntry(ParseState *pstate, char *colname)
if (!rte->inFromCl && rte != pstate->p_target_rangetblentry)
continue;
- if (rte->ref->attrs != NULL)
+ if (rte->eref->attrs != NULL)
{
List *c;
foreach (c, rte->ref->attrs)
@@ -253,6 +249,7 @@ addRangeTableEntry(ParseState *pstate,
{
Relation rel;
RangeTblEntry *rte;
+ Attr *eref;
int maxattrs;
int sublevels_up;
int varattno;
@@ -286,19 +283,22 @@ addRangeTableEntry(ParseState *pstate,
rel = heap_openr(relname, AccessShareLock);
rte->relid = RelationGetRelid(rel);
maxattrs = RelationGetNumberOfAttributes(rel);
- if (maxattrs < length(ref->attrs))
+
+ eref = copyObject(ref);
+ if (maxattrs < length(eref->attrs))
elog(ERROR, "Table '%s' has %d columns available but %d columns specified",
- relname, maxattrs, length(ref->attrs));
+ relname, maxattrs, length(eref->attrs));
/* fill in any unspecified alias columns */
- for (varattno = length(ref->attrs); varattno < maxattrs; varattno++)
+ for (varattno = length(eref->attrs); varattno < maxattrs; varattno++)
{
char *attrname;
attrname = pstrdup(NameStr(rel->rd_att->attrs[varattno]->attname));
- ref->attrs = lappend(ref->attrs, makeString(attrname));
+ eref->attrs = lappend(eref->attrs, makeString(attrname));
}
heap_close(rel, AccessShareLock);
+ rte->eref = eref;
/*
* Flags:
@@ -337,10 +337,9 @@ expandTable(ParseState *pstate, char *refname, bool getaliases)
rte = refnameRangeTableEntry(pstate, refname);
- if (getaliases && (rte != NULL) && (rte->ref != NULL)
- && (length(rte->ref->attrs) > 0))
+ if (getaliases && (rte != NULL))
{
- return rte->ref;
+ return rte->eref;
}
if (rte != NULL)
@@ -415,8 +414,8 @@ expandAll(ParseState *pstate, char *relname, Attr *ref, int *this_resno)
attrname = pstrdup(NameStr(rel->rd_att->attrs[varattno]->attname));
/* varattno is zero-based, so check that length() is always greater */
- if (length(rte->ref->attrs) > varattno)
- label = pstrdup(strVal(nth(varattno, rte->ref->attrs)));
+ if (length(rte->eref->attrs) > varattno)
+ label = pstrdup(strVal(nth(varattno, rte->eref->attrs)));
else
label = attrname;
varnode = make_var(pstate, rte->relid, relname, attrname);
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
index e815efc9639..65a5b33d58c 100644
--- a/src/backend/parser/parse_target.c
+++ b/src/backend/parser/parse_target.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.56 2000/03/09 05:00:24 inoue Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.57 2000/03/14 23:06:33 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -430,7 +430,7 @@ ExpandAllTables(ParseState *pstate)
continue;
target = nconc(target,
- expandAll(pstate, rte->ref->relname, rte->ref,
+ expandAll(pstate, rte->eref->relname, rte->eref,
&pstate->p_last_resno));
}
return target;
diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c
index 7102f64a44f..378289373b8 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.42 2000/02/16 18:17:02 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.43 2000/03/14 23:06:35 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -198,7 +198,7 @@ date_timestamp(DateADT dateVal)
double fsec = 0;
char *tzn;
- result = palloc(sizeof(Timestamp));
+ result = palloc(sizeof(*result));
if (date2tm(dateVal, &tz, tm, &fsec, &tzn) != 0)
elog(ERROR, "Unable to convert date to timestamp");
@@ -392,10 +392,10 @@ time_in(char *str)
elog(ERROR, "Bad (null) time external representation");
if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
- || (DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec) != 0))
+ || (DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, NULL) != 0))
elog(ERROR, "Bad time external representation '%s'", str);
- time = palloc(sizeof(TimeADT));
+ time = palloc(sizeof(*time));
*time = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec + fsec);
@@ -422,7 +422,7 @@ time_out(TimeADT *time)
fsec = 0;
- EncodeTimeOnly(tm, fsec, DateStyle, buf);
+ EncodeTimeOnly(tm, fsec, NULL, DateStyle, buf);
result = palloc(strlen(buf) + 1);
@@ -456,8 +456,8 @@ time_lt(TimeADT *time1, TimeADT *time2)
if (!PointerIsValid(time1) || !PointerIsValid(time2))
return FALSE;
- return *time1 < *time2;
-} /* time_eq() */
+ return (*time1 < *time2);
+} /* time_lt() */
bool
time_le(TimeADT *time1, TimeADT *time2)
@@ -465,8 +465,8 @@ time_le(TimeADT *time1, TimeADT *time2)
if (!PointerIsValid(time1) || !PointerIsValid(time2))
return FALSE;
- return *time1 <= *time2;
-} /* time_eq() */
+ return (*time1 <= *time2);
+} /* time_le() */
bool
time_gt(TimeADT *time1, TimeADT *time2)
@@ -474,8 +474,8 @@ time_gt(TimeADT *time1, TimeADT *time2)
if (!PointerIsValid(time1) || !PointerIsValid(time2))
return FALSE;
- return *time1 > *time2;
-} /* time_eq() */
+ return (*time1 > *time2);
+} /* time_gt() */
bool
time_ge(TimeADT *time1, TimeADT *time2)
@@ -483,8 +483,8 @@ time_ge(TimeADT *time1, TimeADT *time2)
if (!PointerIsValid(time1) || !PointerIsValid(time2))
return FALSE;
- return *time1 >= *time2;
-} /* time_eq() */
+ return (*time1 >= *time2);
+} /* time_ge() */
int
time_cmp(TimeADT *time1, TimeADT *time2)
@@ -492,6 +492,43 @@ time_cmp(TimeADT *time1, TimeADT *time2)
return (*time1 < *time2) ? -1 : (((*time1 > *time2) ? 1 : 0));
} /* time_cmp() */
+TimeADT *
+time_larger(TimeADT *time1, TimeADT *time2)
+{
+ return time_gt(time1, time2)? time1: time2;
+} /* time_larger() */
+
+TimeADT *
+time_smaller(TimeADT *time1, TimeADT *time2)
+{
+ return time_lt(time1, time2)? time1: time2;
+} /* time_smaller() */
+
+/* overlaps_time()
+ * Implements the SQL92 OVERLAPS operator.
+ * Algorithm from Date and Darwen, 1997
+ */
+bool
+overlaps_time(TimeADT *ts1, TimeADT *te1, TimeADT *ts2, TimeADT *te2)
+{
+ /* Make sure we have ordered pairs... */
+ if (time_gt(ts1, te1))
+ {
+ TimeADT *tt = ts1;
+ ts1 = te1;
+ te1 = tt;
+ }
+ if (time_gt(ts2, te2))
+ {
+ TimeADT *tt = ts2;
+ ts2 = te2;
+ te2 = tt;
+ }
+
+ return ((time_gt(ts1, ts2) && (time_lt(ts1, te2) || time_lt(te1, te2)))
+ || (time_gt(ts2, ts1) && (time_lt(ts2, te1) || time_lt(te2, te1)))
+ || time_eq(ts1, ts2));
+}
/* timestamp_time()
* Convert timestamp to time data type.
@@ -515,12 +552,10 @@ timestamp_time(Timestamp *timestamp)
if (TIMESTAMP_IS_EPOCH(*timestamp))
{
timestamp2tm(SetTimestamp(*timestamp), NULL, tm, &fsec, NULL);
-
}
else if (TIMESTAMP_IS_CURRENT(*timestamp))
{
timestamp2tm(SetTimestamp(*timestamp), &tz, tm, &fsec, &tzn);
-
}
else
{
@@ -528,7 +563,7 @@ timestamp_time(Timestamp *timestamp)
elog(ERROR, "Unable to convert timestamp to date");
}
- result = palloc(sizeof(TimeADT));
+ result = palloc(sizeof(*result));
*result = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec + fsec);
@@ -546,7 +581,7 @@ datetime_timestamp(DateADT date, TimeADT *time)
if (!PointerIsValid(time))
{
- result = palloc(sizeof(Timestamp));
+ result = palloc(sizeof(*result));
TIMESTAMP_INVALID(*result);
}
else
@@ -557,3 +592,270 @@ datetime_timestamp(DateADT date, TimeADT *time)
return result;
} /* datetime_timestamp() */
+
+
+/* time_interval()
+ * Convert time to interval data type.
+ */
+Interval *
+time_interval(TimeADT *time)
+{
+ Interval *result;
+
+ if (!PointerIsValid(time))
+ return NULL;
+
+ result = palloc(sizeof(*result));
+ result->time = *time;
+ result->month = 0;
+
+ return result;
+} /* time_interval() */
+
+
+/*****************************************************************************
+ * Time With Time Zone ADT
+ *****************************************************************************/
+
+
+TimeTzADT *
+timetz_in(char *str)
+{
+ TimeTzADT *time;
+
+ double fsec;
+ struct tm tt,
+ *tm = &tt;
+ int tz;
+
+ int nf;
+ char lowstr[MAXDATELEN + 1];
+ char *field[MAXDATEFIELDS];
+ int dtype;
+ int ftype[MAXDATEFIELDS];
+
+ if (!PointerIsValid(str))
+ elog(ERROR, "Bad (null) time external representation");
+
+ if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
+ || (DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0))
+ elog(ERROR, "Bad time external representation '%s'", str);
+
+ time = palloc(sizeof(*time));
+
+ time->time = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec + fsec);
+ time->zone = tz;
+
+ return time;
+} /* timetz_in() */
+
+
+char *
+timetz_out(TimeTzADT *time)
+{
+ char *result;
+ struct tm tt,
+ *tm = &tt;
+
+ double fsec;
+ int tz;
+ char buf[MAXDATELEN + 1];
+
+ if (!PointerIsValid(time))
+ return NULL;
+
+ tm->tm_hour = (time->time / (60 * 60));
+ tm->tm_min = (((int) (time->time / 60)) % 60);
+ tm->tm_sec = (((int) time->time) % 60);
+
+ fsec = 0;
+ tz = time->zone;
+
+ EncodeTimeOnly(tm, fsec, &tz, DateStyle, buf);
+
+ result = palloc(strlen(buf) + 1);
+
+ strcpy(result, buf);
+
+ return result;
+} /* timetz_out() */
+
+
+bool
+timetz_eq(TimeTzADT *time1, TimeTzADT *time2)
+{
+ if (!PointerIsValid(time1) || !PointerIsValid(time2))
+ return FALSE;
+
+ return ((time1->time + time1->zone) == (time2->time + time2->zone));
+} /* timetz_eq() */
+
+bool
+timetz_ne(TimeTzADT *time1, TimeTzADT *time2)
+{
+ if (!PointerIsValid(time1) || !PointerIsValid(time2))
+ return FALSE;
+
+ return ((time1->time + time1->zone) != (time2->time + time2->zone));
+} /* timetz_ne() */
+
+bool
+timetz_lt(TimeTzADT *time1, TimeTzADT *time2)
+{
+ if (!PointerIsValid(time1) || !PointerIsValid(time2))
+ return FALSE;
+
+ return ((time1->time + time1->zone) < (time2->time + time2->zone));
+} /* timetz_lt() */
+
+bool
+timetz_le(TimeTzADT *time1, TimeTzADT *time2)
+{
+ if (!PointerIsValid(time1) || !PointerIsValid(time2))
+ return FALSE;
+
+ return ((time1->time + time1->zone) <= (time2->time + time2->zone));
+} /* timetz_le() */
+
+bool
+timetz_gt(TimeTzADT *time1, TimeTzADT *time2)
+{
+ if (!PointerIsValid(time1) || !PointerIsValid(time2))
+ return FALSE;
+
+ return ((time1->time + time1->zone) > (time2->time + time2->zone));
+} /* timetz_gt() */
+
+bool
+timetz_ge(TimeTzADT *time1, TimeTzADT *time2)
+{
+ if (!PointerIsValid(time1) || !PointerIsValid(time2))
+ return FALSE;
+
+ return ((time1->time + time1->zone) >= (time2->time + time2->zone));
+} /* timetz_ge() */
+
+int
+timetz_cmp(TimeTzADT *time1, TimeTzADT *time2)
+{
+ return (timetz_lt(time1, time2) ? -1 : (timetz_gt(time1, time2)? 1: 0));
+} /* timetz_cmp() */
+
+TimeTzADT *
+timetz_larger(TimeTzADT *time1, TimeTzADT *time2)
+{
+ return timetz_gt(time1, time2)? time1: time2;
+} /* timetz_larger() */
+
+TimeTzADT *
+timetz_smaller(TimeTzADT *time1, TimeTzADT *time2)
+{
+ return timetz_lt(time1, time2)? time1: time2;
+} /* timetz_smaller() */
+
+/* overlaps_timetz()
+ * Implements the SQL92 OVERLAPS operator.
+ * Algorithm from Date and Darwen, 1997
+ */
+bool
+overlaps_timetz(TimeTzADT *ts1, TimeTzADT *te1, TimeTzADT *ts2, TimeTzADT *te2)
+{
+ /* Make sure we have ordered pairs... */
+ if (timetz_gt(ts1, te1))
+ {
+ TimeTzADT *tt = ts1;
+ ts1 = te1;
+ te1 = tt;
+ }
+ if (timetz_gt(ts2, te2))
+ {
+ TimeTzADT *tt = ts2;
+ ts2 = te2;
+ te2 = tt;
+ }
+
+ return ((timetz_gt(ts1, ts2) && (timetz_lt(ts1, te2) || timetz_lt(te1, te2)))
+ || (timetz_gt(ts2, ts1) && (timetz_lt(ts2, te1) || timetz_lt(te2, te1)))
+ || timetz_eq(ts1, ts2));
+} /* overlaps_timetz() */
+
+/* timestamp_timetz()
+ * Convert timestamp to timetz data type.
+ */
+TimeTzADT *
+timestamp_timetz(Timestamp *timestamp)
+{
+ TimeTzADT *result;
+ struct tm tt,
+ *tm = &tt;
+ int tz;
+ double fsec;
+ char *tzn;
+
+ if (!PointerIsValid(timestamp))
+ elog(ERROR, "Unable to convert null timestamp to date");
+
+ if (TIMESTAMP_NOT_FINITE(*timestamp))
+ elog(ERROR, "Unable to convert timestamp to date");
+
+ if (TIMESTAMP_IS_EPOCH(*timestamp))
+ {
+ timestamp2tm(SetTimestamp(*timestamp), NULL, tm, &fsec, NULL);
+ tz = 0;
+ }
+ else if (TIMESTAMP_IS_CURRENT(*timestamp))
+ {
+ timestamp2tm(SetTimestamp(*timestamp), &tz, tm, &fsec, &tzn);
+ }
+ else
+ {
+ if (timestamp2tm(*timestamp, &tz, tm, &fsec, &tzn) != 0)
+ elog(ERROR, "Unable to convert timestamp to date");
+ }
+
+ result = palloc(sizeof(*result));
+
+ result->time = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec + fsec);
+ result->zone = tz;
+
+ return result;
+} /* timestamp_timetz() */
+
+
+/* datetimetz_timestamp()
+ * Convert date and timetz to timestamp data type.
+ * Timestamp is stored in GMT, so add the time zone
+ * stored with the timetz to the result.
+ * - thomas 2000-03-10
+ */
+Timestamp *
+datetimetz_timestamp(DateADT date, TimeTzADT *time)
+{
+ Timestamp *result;
+ struct tm tt,
+ *tm = &tt;
+ int tz;
+ double fsec = 0;
+ char *tzn;
+
+ result = palloc(sizeof(*result));
+
+ if (!PointerIsValid(date) || !PointerIsValid(time))
+ {
+ TIMESTAMP_INVALID(*result);
+ }
+ else
+ {
+ if (date2tm(date, &tz, tm, &fsec, &tzn) != 0)
+ elog(ERROR, "Unable to convert date to timestamp");
+
+ if (tm2timestamp(tm, fsec, &time->zone, result) != 0)
+ elog(ERROR, "Timestamp out of range");
+
+ *result += time->time;
+ }
+
+ return result;
+} /* datetimetz_timestamp() */
+
+
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c
index 1418a0c34c2..3c88ac3a3d1 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.42 2000/02/16 18:17:02 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.43 2000/03/14 23:06:36 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -618,8 +618,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
tm->tm_min = 0;
tm->tm_sec = 0;
*fsec = 0;
- tm->tm_isdst = -1; /* don't know daylight savings time status
- * apriori */
+ tm->tm_isdst = -1; /* don't know daylight savings time status apriori */
if (tzp != NULL)
*tzp = 0;
@@ -897,8 +896,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
tm->tm_mon += 1;
#if defined(HAVE_TM_ZONE)
- *tzp = -(tm->tm_gmtoff); /* tm_gmtoff is
- * Sun/DEC-ism */
+ *tzp = -(tm->tm_gmtoff); /* tm_gmtoff is Sun/DEC-ism */
#elif defined(HAVE_INT_TIMEZONE)
#ifdef __CYGWIN__
*tzp = ((tm->tm_isdst > 0) ? (_timezone - 3600) : _timezone);
@@ -927,9 +925,18 @@ DecodeDateTime(char **field, int *ftype, int nf,
/* DecodeTimeOnly()
* Interpret parsed string as time fields only.
+ * Note that support for time zone is here for
+ * 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
-DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct tm * tm, double *fsec)
+DecodeTimeOnly(char **field, int *ftype, int nf,
+ int *dtype, struct tm * tm, double *fsec, int *tzp)
{
int fmask,
tmask,
@@ -944,9 +951,10 @@ DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct tm * tm, dou
tm->tm_hour = 0;
tm->tm_min = 0;
tm->tm_sec = 0;
- tm->tm_isdst = -1; /* don't know daylight savings time status
- * apriori */
*fsec = 0;
+ tm->tm_isdst = -1; /* don't know daylight savings time status apriori */
+ if (tzp != NULL)
+ *tzp = 0;
fmask = DTK_DATE_M;
@@ -959,6 +967,14 @@ DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct tm * tm, dou
return -1;
break;
+ case DTK_TZ:
+ if (tzp == NULL)
+ return -1;
+ if (DecodeTimezone(field[i], tzp) != 0)
+ return -1;
+ tmask = DTK_M(TZ);
+ break;
+
case DTK_NUMBER:
flen = strlen(field[i]);
@@ -1035,6 +1051,45 @@ DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct tm * tm, dou
if ((fmask & DTK_TIME_M) != DTK_TIME_M)
return -1;
+ /* timezone not specified? then find local timezone if possible */
+ if ((tzp != NULL) && (!(fmask & DTK_M(TZ))))
+ {
+ struct tm tt, *tmp = &tt;
+
+ /*
+ * daylight savings time modifier but no standard timezone?
+ * then error
+ */
+ if (fmask & DTK_M(DTZMOD))
+ return -1;
+
+ GetCurrentTime(tmp);
+ tmp->tm_hour = tm->tm_hour;
+ tmp->tm_min = tm->tm_min;
+ tmp->tm_sec = tm->tm_sec;
+
+#ifdef USE_POSIX_TIME
+ tmp->tm_isdst = -1;
+ mktime(tmp);
+ tm->tm_isdst = tmp->tm_isdst;
+
+#if defined(HAVE_TM_ZONE)
+ *tzp = -(tmp->tm_gmtoff); /* tm_gmtoff is Sun/DEC-ism */
+#elif defined(HAVE_INT_TIMEZONE)
+#ifdef __CYGWIN__
+ *tzp = ((tmp->tm_isdst > 0) ? (_timezone - 3600) : _timezone);
+#else
+ *tzp = ((tmp->tm_isdst > 0) ? (timezone - 3600) : timezone);
+#endif
+#else
+#error USE_POSIX_TIME is defined but neither HAVE_TM_ZONE or HAVE_INT_TIMEZONE are defined
+#endif
+
+#else /* !USE_POSIX_TIME */
+ *tzp = CTimeZone;
+#endif
+ }
+
return 0;
} /* DecodeTimeOnly() */
@@ -1830,7 +1885,7 @@ EncodeDateOnly(struct tm * tm, int style, char *str)
* Encode time fields only.
*/
int
-EncodeTimeOnly(struct tm * tm, double fsec, int style, char *str)
+EncodeTimeOnly(struct tm * tm, double fsec, int *tzp, int style, char *str)
{
double sec;
@@ -1842,6 +1897,15 @@ EncodeTimeOnly(struct tm * tm, double fsec, int style, char *str)
sprintf(str, "%02d:%02d:", tm->tm_hour, tm->tm_min);
sprintf((str + 6), ((fsec != 0) ? "%05.2f" : "%02.0f"), sec);
+ if (tzp != NULL)
+ {
+ int hour, min;
+
+ hour = -(*tzp / 3600);
+ min = ((abs(*tzp) / 60) % 60);
+ sprintf((str + strlen(str)), ((min != 0) ? "%+03d:%02d" : "%+03d"), hour, min);
+ }
+
return TRUE;
} /* EncodeTimeOnly() */
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c
index 0a0df27b808..6af9cd906d3 100644
--- a/src/backend/utils/adt/float.c
+++ b/src/backend/utils/adt/float.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.53 2000/01/26 05:57:14 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.54 2000/03/14 23:06:36 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1236,6 +1236,31 @@ dlog1(float64 arg1)
return result;
}
+/*
+ * dlog10 - returns a pointer to the base 10 logarithm of arg1
+ */
+float64
+dlog10(float64 arg1)
+{
+ float64 result;
+ double tmp;
+
+ if (!PointerIsValid(arg1))
+ return (float64) NULL;
+
+ result = (float64) palloc(sizeof(float64data));
+
+ tmp = *arg1;
+ if (tmp == 0.0)
+ elog(ERROR, "can't take log of zero");
+ if (tmp < 0)
+ elog(ERROR, "can't take log of a negative number");
+ *result = (float64data) log10(tmp);
+
+ CheckFloat8Val(*result);
+ return result;
+} /* dlog10() */
+
/*
* ====================
diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c
index 7b56fba275b..9561f9e875d 100644
--- a/src/backend/utils/adt/geo_ops.c
+++ b/src/backend/utils/adt/geo_ops.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.48 2000/01/26 05:57:14 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.49 2000/03/14 23:06:36 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -3510,29 +3510,6 @@ path_div_pt(PATH *path, Point *point)
} /* path_div_pt() */
-bool
-path_contain_pt(PATH *path, Point *p)
-{
- if (!PointerIsValid(path) || !PointerIsValid(p))
- return FALSE;
-
- return (on_ppath(p, path));
-} /* path_contain_pt() */
-
-/* pt_contained_path
- * Point in or on path? This is the same as on_ppath.
- * - thomas 1998-10-29
- */
-bool
-pt_contained_path(Point *p, PATH *path)
-{
- if (!PointerIsValid(p) || !PointerIsValid(path))
- return FALSE;
-
- return path_contain_pt(path, p);
-} /* pt_contained_path() */
-
-
Point *
path_center(PATH *path)
{
diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c
index 244bf3aaa4b..7eb7783274c 100644
--- a/src/backend/utils/adt/int.c
+++ b/src/backend/utils/adt/int.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/int.c,v 1.34 2000/03/07 23:58:38 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/int.c,v 1.35 2000/03/14 23:06:36 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -659,8 +659,8 @@ int42mod(int32 arg1, int32 arg2)
return arg1 % arg2;
}
-/*
- * int[24]fac - returns arg1!
+/* int[24]fac()
+ * Factorial
*/
int32
int4fac(int32 arg1)
@@ -678,7 +678,7 @@ int4fac(int32 arg1)
int32
int2fac(int16 arg1)
{
- int16 result;
+ int32 result;
if (arg1 < 1)
result = 0;
@@ -688,6 +688,21 @@ int2fac(int16 arg1)
return result;
}
+/* int[24]abs()
+ * Absolute value
+ */
+int32
+int4abs(int32 arg1)
+{
+ return ((arg1 < 0)? -arg1: arg1);
+}
+
+int16
+int2abs(int16 arg1)
+{
+ return ((arg1 < 0)? -arg1: arg1);
+}
+
int16
int2larger(int16 arg1, int16 arg2)
{
diff --git a/src/backend/utils/adt/int8.c b/src/backend/utils/adt/int8.c
index 7c00686b194..27b0f42c97f 100644
--- a/src/backend/utils/adt/int8.c
+++ b/src/backend/utils/adt/int8.c
@@ -359,6 +359,63 @@ int8div(int64 *val1, int64 *val2)
return result;
} /* int8div() */
+/* int8abs()
+ * Absolute value
+ */
+int64 *
+int8abs(int64 *arg1)
+{
+ int64 *result;
+
+ if (!PointerIsValid(arg1))
+ return NULL;
+
+ result = palloc(sizeof(*result));
+
+ *result = ((*arg1 < 0)? -*arg1: *arg1);
+
+ return result;
+}
+
+/* int8mod()
+ * Modulo operation.
+ */
+int64 *
+int8mod(int64 *val1, int64 *val2)
+{
+ int64 *result;
+
+ /* use the divide operation to check params and allocate storage */
+ result = int8div(val1, val2);
+ *result *= *val2;
+ *result = *val1 - *result;
+
+ return result;
+} /* int8mod() */
+
+/* int8fac()
+ * Factorial
+ */
+int64 *
+int8fac(int64 *arg1)
+{
+ int64 *result;
+ int64 i;
+
+ if (!PointerIsValid(arg1))
+ return NULL;
+
+ result = palloc(sizeof(*result));
+
+ if (*arg1 < 1)
+ *result = 0;
+ else
+ for (i = *arg1, *result = 1; i > 0; --i)
+ *result *= i;
+
+ return result;
+}
+
int64 *
int8larger(int64 *val1, int64 *val2)
{
@@ -634,4 +691,4 @@ int8_text(int64 *val)
memmove(VARDATA(result), s, len);
return result;
-} /* int8out() */
+} /* int8_text() */
diff --git a/src/backend/utils/adt/oracle_compat.c b/src/backend/utils/adt/oracle_compat.c
index 50be811b22c..b18cbf4a208 100644
--- a/src/backend/utils/adt/oracle_compat.c
+++ b/src/backend/utils/adt/oracle_compat.c
@@ -1,24 +1,14 @@
/*
* Edmund Mergl <E.Mergl@bawue.de>
*
- * $Id: oracle_compat.c,v 1.20 1999/07/15 15:20:19 momjian Exp $
+ * $Id: oracle_compat.c,v 1.21 2000/03/14 23:06:37 thomas Exp $
*
*/
#include <ctype.h>
#include "postgres.h"
-
-text *lower(text *string);
-text *upper(text *string);
-text *initcap(text *string);
-text *lpad(text *string1, int4 len, text *string2);
-text *rpad(text *string1, int4 len, text *string2);
-text *btrim(text *string, text *set);
-text *ltrim(text *string, text *set);
-text *rtrim(text *string, text *set);
-text *substr(text *string, int4 m, int4 n);
-text *translate(text *string, char from, char to);
+#include "utils/builtins.h"
/********************************************************************
@@ -506,42 +496,68 @@ substr(text *string, int4 m, int4 n)
*
* Syntax:
*
- * text *translate(text *string, char from, char to)
+ * text *translate(text *string, text *from, text *to)
*
* Purpose:
*
* Returns string after replacing all occurences of from with
* the corresponding character in to. TRANSLATE will not remove
* characters.
+ * Modified to work with strings rather than single character
+ * for the substitution arguments.
+ * Modifications from Edwin Ramirez <ramirez@doc.mssm.edu>.
*
********************************************************************/
text *
-translate(text *string, char from, char to)
+translate(text *string, text *from, text *to)
{
- text *ret;
- char *ptr,
- *ptr_ret;
- int m;
+ text *ret;
+ char *ptr_ret, *from_ptr, *to_ptr;
+ char *source, *target, *temp, rep;
+ int m, fromlen, tolen, retlen, i;
if ((string == (text *) NULL) ||
((m = VARSIZE(string) - VARHDRSZ) <= 0))
return string;
- ret = (text *) palloc(VARSIZE(string));
- VARSIZE(ret) = VARSIZE(string);
-
- ptr = VARDATA(string);
- ptr_ret = VARDATA(ret);
+ target = (char *) palloc(VARSIZE(string) - VARHDRSZ);
+ source = VARDATA(string);
+ temp = target;
+ fromlen = VARSIZE(from) - VARHDRSZ;
+ from_ptr = VARDATA(from);
+ tolen = VARSIZE(to) - VARHDRSZ;
+ to_ptr = VARDATA(to);
+ retlen = 0;
while (m--)
{
- *ptr_ret++ = *ptr == from ? to : *ptr;
- ptr++;
+ rep = *source;
+ for(i=0;i<fromlen;i++) {
+ if(from_ptr[i] == *source) {
+ if(i < tolen) {
+ rep = to_ptr[i];
+ } else {
+ rep = 0;
+ }
+ break;
+ }
+ }
+ if(rep != 0) {
+ *target++ = rep;
+ retlen++;
+ }
+ source++;
}
+ ret = (text *) palloc(retlen + VARHDRSZ);
+ VARSIZE(ret) = retlen + VARHDRSZ;
+ ptr_ret = VARDATA(ret);
+ for(i=0;i<retlen;i++) {
+ *ptr_ret++ = temp[i];
+ }
+ pfree(target);
return ret;
}
-
/* EOF */
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index bdeaf440829..59ec46a85aa 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -3,7 +3,7 @@
* out of its tuple
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.44 2000/02/26 21:13:18 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.45 2000/03/14 23:06:37 thomas Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -923,6 +923,8 @@ get_select_query_def(Query *query, deparse_context *context)
continue;
rte = (RangeTblEntry *) lfirst(l);
+ if (rte->ref == NULL)
+ continue;
if (!strcmp(rte->ref->relname, "*NEW*"))
continue;
if (!strcmp(rte->ref->relname, "*CURRENT*"))
@@ -982,9 +984,10 @@ get_select_query_def(Query *query, deparse_context *context)
{
rte = (RangeTblEntry *) lfirst(l);
+ if (rte->ref == NULL)
+ continue;
if (!strcmp(rte->ref->relname, "*NEW*"))
continue;
-
if (!strcmp(rte->ref->relname, "*CURRENT*"))
continue;
@@ -1008,7 +1011,9 @@ get_select_query_def(Query *query, deparse_context *context)
* Since we don't really support SQL joins yet, dropping
* the list of column aliases doesn't hurt anything...
*/
- if (strcmp(rte->relname, rte->ref->relname) != 0)
+ if ((rte->ref != NULL)
+ && ((strcmp(rte->relname, rte->ref->relname) != 0)
+ || (rte->ref->attrs != NIL)))
{
appendStringInfo(buf, " %s",
quote_identifier(rte->ref->relname));
@@ -1104,6 +1109,8 @@ get_insert_query_def(Query *query, deparse_context *context)
continue;
rte = (RangeTblEntry *) lfirst(l);
+ if (rte->ref == NULL)
+ continue;
if (!strcmp(rte->ref->relname, "*NEW*"))
continue;
if (!strcmp(rte->ref->relname, "*CURRENT*"))
@@ -1274,7 +1281,10 @@ get_rule_expr(Node *node, deparse_context *context)
if (context->varprefix)
{
- if (!strcmp(rte->ref->relname, "*NEW*"))
+ if (rte->ref == NULL)
+ appendStringInfo(buf, "%s.",
+ quote_identifier(rte->relname));
+ else if (!strcmp(rte->ref->relname, "*NEW*"))
appendStringInfo(buf, "new.");
else if (!strcmp(rte->ref->relname, "*CURRENT*"))
appendStringInfo(buf, "old.");
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index 77202c8308e..4086a803dd7 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.22 2000/02/16 17:24:48 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.23 2000/03/14 23:06:37 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -952,6 +952,32 @@ interval_cmp(Interval *interval1, Interval *interval2)
return (span1 < span2) ? -1 : (span1 > span2) ? 1 : 0;
} /* interval_cmp() */
+/* overlaps_timestamp()
+ * Implements the SQL92 OVERLAPS operator.
+ * Algorithm from Date and Darwen, 1997
+ */
+bool
+overlaps_timestamp(Timestamp *ts1, Timestamp *te1, Timestamp *ts2, Timestamp *te2)
+{
+ /* Make sure we have ordered pairs... */
+ if (timestamp_gt(ts1, te1))
+ {
+ Timestamp *tt = ts1;
+ ts1 = te1;
+ te1 = tt;
+ }
+ if (timestamp_gt(ts2, te2))
+ {
+ Timestamp *tt = ts2;
+ ts2 = te2;
+ te2 = tt;
+ }
+
+ return ((timestamp_gt(ts1, ts2) && (timestamp_lt(ts1, te2) || timestamp_lt(te1, te2)))
+ || (timestamp_gt(ts2, ts1) && (timestamp_lt(ts2, te1) || timestamp_lt(te2, te1)))
+ || timestamp_eq(ts1, ts2));
+} /* overlaps_timestamp() */
+
/*----------------------------------------------------------
* "Arithmetic" operators on date/times.