mirror of
https://github.com/postgres/postgres.git
synced 2025-11-13 16:22:44 +03:00
Implement column aliases on views "CREATE VIEW name (collist)".
Implement TIME WITH TIME ZONE type (timetz internal type). Remap length() for character strings to CHAR_LENGTH() for SQL92 and to remove the ambiguity with geometric length() functions. Keep length() for character strings for backward compatibility. Shrink stored views by removing internal column name list from visible rte. Implement min(), max() for time and timetz data types. Implement conversion of TIME to INTERVAL. Implement abs(), mod(), fac() for the int8 data type. Rename some math functions to generic names: round(), sqrt(), cbrt(), pow(), etc. Rename NUMERIC power() function to pow(). Fix int2 factorial to calculate result in int4. Enhance the Oracle compatibility function translate() to work with string arguments (from Edwin Ramirez). Modify pg_proc system table to remove OID holes.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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() */
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() */
|
||||
|
||||
|
||||
|
||||
@@ -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() */
|
||||
|
||||
|
||||
@@ -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() */
|
||||
|
||||
|
||||
/*
|
||||
* ====================
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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() */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user