Add transcendental math functions (sine, cosine, etc)

Add a random number generator and seed setter (random(), SET SEED)
Fix up the interval*float8 math to carry partial months
 into the time field.
Add float8*interval so we have symmetry in the available math.
Fix the parser and define.c to accept SQL92 types as field arguments.
Fix the parser to accept SQL92 types for CREATE TYPE, etc. This is
 necessary to allow...
Bit/varbit support in contrib/bit cleaned up to compile and load
 cleanly. Still needs some work before final release.
Implement the "SOME" keyword as a synonym for "ANY" per SQL92.
Implement ascii(text), ichar(int4), repeat(text,int4) to help
 support the ODBC driver.
Enable the TRUNCATE() function mapping in the ODBC driver.
This commit is contained in:
Thomas G. Lockhart 2000-04-07 13:40:45 +00:00
parent 1b992b468b
commit a349733bbb
14 changed files with 639 additions and 196 deletions

View File

@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.38 2000/01/26 05:56:13 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.39 2000/04/07 13:39:24 thomas Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@ -377,24 +377,22 @@ DefineOperator(char *oprName,
if (!strcasecmp(defel->defname, "leftarg"))
{
/* see gram.y, must be setof */
if (nodeTag(defel->arg) == T_TypeName)
if ((nodeTag(defel->arg) == T_TypeName)
&& (((TypeName *)defel->arg)->setof))
elog(ERROR, "setof type not implemented for leftarg");
if (nodeTag(defel->arg) == T_String)
typeName1 = defGetString(defel);
else
typeName1 = defGetString(defel);
if (typeName1 == NULL)
elog(ERROR, "type for leftarg is malformed.");
}
else if (!strcasecmp(defel->defname, "rightarg"))
{
/* see gram.y, must be setof */
if (nodeTag(defel->arg) == T_TypeName)
if ((nodeTag(defel->arg) == T_TypeName)
&& (((TypeName *)defel->arg)->setof))
elog(ERROR, "setof type not implemented for rightarg");
if (nodeTag(defel->arg) == T_String)
typeName2 = defGetString(defel);
else
typeName2 = defGetString(defel);
if (typeName2 == NULL)
elog(ERROR, "type for rightarg is malformed.");
}
else if (!strcasecmp(defel->defname, "procedure"))
@ -700,9 +698,19 @@ DefineType(char *typeName, List *parameters)
static char *
defGetString(DefElem *def)
{
if (nodeTag(def->arg) != T_String)
char *string;
if (nodeTag(def->arg) == T_String)
string = strVal(def->arg);
else if (nodeTag(def->arg) == T_TypeName)
string = ((TypeName *)def->arg)->name;
else
string = NULL;
#if 0
elog(ERROR, "Define: \"%s\" = what?", def->defname);
return strVal(def->arg);
#endif
return string;
}
static double

View File

@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.32 2000/03/17 05:29:04 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.33 2000/04/07 13:39:24 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@ -93,6 +93,9 @@ static bool parse_max_expr_depth(char *);
static bool show_XactIsoLevel(void);
static bool reset_XactIsoLevel(void);
static bool parse_XactIsoLevel(char *);
static bool parse_random_seed(char *);
static bool show_random_seed(void);
static bool reset_random_seed(void);
/*
* get_token
@ -1066,6 +1069,41 @@ reset_pg_options(void)
}
/*
* Random number seed
*/
static bool
parse_random_seed(char *value)
{
double seed = 0;
if (value == NULL)
reset_random_seed();
else
{
sscanf(value, "%lf", &seed);
setseed(&seed);
}
return (TRUE);
}
static bool
show_random_seed(void)
{
elog(NOTICE, "Seed for random number generator is not known");
return (TRUE);
}
static bool
reset_random_seed(void)
{
double seed = 0.5;
setseed(&seed);
return (TRUE);
}
/*-----------------------------------------------------------------------*/
static struct VariableParsers
@ -1155,6 +1193,9 @@ static struct VariableParsers
{
"pg_options", parse_pg_options, show_pg_options, reset_pg_options
},
{
"seed", parse_random_seed, show_random_seed, reset_random_seed
},
{
NULL, NULL, NULL, NULL
}

View File

@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.166 2000/03/31 02:11:03 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.167 2000/04/07 13:39:34 thomas Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@ -222,7 +222,9 @@ static void doNegateFloat(Value *v);
%type <list> OptSeqList
%type <defelt> OptSeqElem
/*
%type <dstmt> def_rest
*/
%type <astmt> insert_rest
%type <node> OptTableElement, ConstraintElem
@ -249,7 +251,7 @@ static void doNegateFloat(Value *v);
%type <typnam> Typename, opt_type, SimpleTypename,
Generic, Numeric, Character, Datetime, Bit
%type <str> generic, character, datetime, bit
%type <str> typename, generic, numeric, character, datetime, bit
%type <str> extract_arg
%type <str> opt_charset, opt_collate
%type <str> opt_float
@ -259,7 +261,7 @@ static void doNegateFloat(Value *v);
%type <ival> Iconst
%type <str> Sconst, comment_text
%type <str> UserId, var_value, zone_value
%type <str> ColId, ColLabel
%type <str> ColId, ColLabel, TokenId
%type <node> TableConstraint
%type <list> ColQualList
@ -309,7 +311,7 @@ static void doNegateFloat(Value *v);
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,
SCROLL, SECOND_P, SELECT, SESSION_USER, SET, SOME, SUBSTRING,
TABLE, TEMPORARY, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR,
TIMEZONE_MINUTE, TO, TRAILING, TRANSACTION, TRIM, TRUE_P,
UNION, UNIQUE, UPDATE, USER, USING,
@ -765,6 +767,11 @@ var_value: Sconst
*(result+strlen(result)-1) = '\0';
$$ = result;
}
/* "OFF" is not a token, so it is handled by the name_list production */
| ON
{
$$ = "on";
}
| DEFAULT
{
$$ = NULL;
@ -1738,13 +1745,17 @@ DropTrigStmt: DROP TRIGGER name ON relation_name
*
*****************************************************************************/
DefineStmt: CREATE def_type def_rest
DefineStmt: CREATE def_type def_name definition
{
$3->defType = $2;
$$ = (Node *)$3;
DefineStmt *n = makeNode(DefineStmt);
n->defType = $2;
n->defname = $3;
n->definition = $4;
$$ = (Node *)n;
}
;
/*
def_rest: def_name definition
{
$$ = makeNode(DefineStmt);
@ -1752,6 +1763,7 @@ def_rest: def_name definition
$$->definition = $2;
}
;
*/
def_type: OPERATOR { $$ = OPERATOR; }
| TYPE_P { $$ = TYPE_P; }
@ -1760,8 +1772,12 @@ def_type: OPERATOR { $$ = OPERATOR; }
def_name: PROCEDURE { $$ = "procedure"; }
| JOIN { $$ = "join"; }
| ColId { $$ = $1; }
| all_Op { $$ = $1; }
| typename { $$ = $1; }
| TokenId { $$ = $1; }
| INTERVAL { $$ = "interval"; }
| TIME { $$ = "time"; }
| TIMESTAMP { $$ = "timestamp"; }
;
definition: '(' def_list ')' { $$ = $2; }
@ -1791,19 +1807,11 @@ def_elem: def_name '=' def_arg
}
;
def_arg: ColId { $$ = (Node *)makeString($1); }
def_arg: func_return { $$ = (Node *)$1; }
| TokenId { $$ = (Node *)makeString($1); }
| all_Op { $$ = (Node *)makeString($1); }
| NumericOnly { $$ = (Node *)$1; }
| Sconst { $$ = (Node *)makeString($1); }
| SETOF ColId
{
TypeName *n = makeNode(TypeName);
n->name = $2;
n->setof = TRUE;
n->arrayBounds = NULL;
n->typmod = -1;
$$ = (Node *)n;
}
;
@ -3843,6 +3851,13 @@ SimpleTypename: Generic
| Datetime
;
typename: generic { $$ = $1; }
| numeric { $$ = $1; }
| bit { $$ = $1; }
| character { $$ = $1; }
| datetime { $$ = $1; }
;
Generic: generic
{
$$ = makeNode(TypeName);
@ -3892,6 +3907,13 @@ Numeric: FLOAT opt_float
}
;
numeric: FLOAT { $$ = xlateSqlType("float"); }
| DOUBLE PRECISION { $$ = xlateSqlType("float"); }
| DECIMAL { $$ = xlateSqlType("decimal"); }
| DEC { $$ = xlateSqlType("decimal"); }
| NUMERIC { $$ = xlateSqlType("numeric"); }
;
opt_float: '(' Iconst ')'
{
if ($2 < 1)
@ -4217,6 +4239,7 @@ row_list: row_list ',' a_expr
;
sub_type: ANY { $$ = ANY_SUBLINK; }
| SOME { $$ = ANY_SUBLINK; }
| ALL { $$ = ALL_SUBLINK; }
;
@ -5291,19 +5314,25 @@ UserId: IDENT { $$ = $1; };
* some of these keywords will have to be removed from this
* list due to shift/reduce conflicts in yacc. If so, move
* down to the ColLabel entity. - thomas 1997-11-06
* These show up as operators, and will screw up the parsing if
* allowed as identifiers or labels.
* Any tokens which show up as operators will screw up the parsing if
* allowed as identifiers, but are acceptable as ColLabels:
* BETWEEN, IN, IS, ISNULL, NOTNULL, OVERLAPS
* Thanks to Tom Lane for pointing this out. - thomas 2000-03-29
| BETWEEN { $$ = "between"; }
| IN { $$ = "in"; }
| IS { $$ = "is"; }
| ISNULL { $$ = "isnull"; }
| NOTNULL { $$ = "notnull"; }
| OVERLAPS { $$ = "overlaps"; }
*/
ColId: IDENT { $$ = $1; }
| TokenId { $$ = $1; }
| datetime { $$ = $1; }
| ABSOLUTE { $$ = "absolute"; }
| INTERVAL { $$ = "interval"; }
| TIME { $$ = "time"; }
| TIMESTAMP { $$ = "timestamp"; }
| TYPE_P { $$ = "type"; }
;
/* Parser tokens to be used as identifiers.
* Tokens involving data types should appear in ColId only,
* since they will conflict with real TypeName productions.
*/
TokenId: ABSOLUTE { $$ = "absolute"; }
| ACCESS { $$ = "access"; }
| ACTION { $$ = "action"; }
| ADD { $$ = "add"; }
@ -5350,7 +5379,6 @@ ColId: IDENT { $$ = $1; }
| INSENSITIVE { $$ = "insensitive"; }
| INSERT { $$ = "insert"; }
| INSTEAD { $$ = "instead"; }
| INTERVAL { $$ = "interval"; }
| ISOLATION { $$ = "isolation"; }
| KEY { $$ = "key"; }
| LANGUAGE { $$ = "language"; }
@ -5403,14 +5431,11 @@ ColId: IDENT { $$ = $1; }
| SYSID { $$ = "sysid"; }
| TEMP { $$ = "temp"; }
| TEMPORARY { $$ = "temporary"; }
| TIME { $$ = "time"; }
| TIMESTAMP { $$ = "timestamp"; }
| TIMEZONE_HOUR { $$ = "timezone_hour"; }
| TIMEZONE_MINUTE { $$ = "timezone_minute"; }
| TRIGGER { $$ = "trigger"; }
| TRUNCATE { $$ = "truncate"; }
| TRUSTED { $$ = "trusted"; }
| TYPE_P { $$ = "type"; }
| UNLISTEN { $$ = "unlisten"; }
| UNTIL { $$ = "until"; }
| UPDATE { $$ = "update"; }
@ -5433,24 +5458,14 @@ ColId: IDENT { $$ = $1; }
* Add other keywords to this list. Note that they appear here
* rather than in ColId if there was a shift/reduce conflict
* when used as a full identifier. - thomas 1997-11-06
* These show up as operators, and will screw up the parsing if
* allowed as identifiers or labels.
* Thanks to Tom Lane for pointing this out. - thomas 2000-03-29
| ALL { $$ = "all"; }
| ANY { $$ = "any"; }
| EXCEPT { $$ = "except"; }
| INTERSECT { $$ = "intersect"; }
| LIKE { $$ = "like"; }
| NOT { $$ = "not"; }
| NULLIF { $$ = "nullif"; }
| NULL_P { $$ = "null"; }
| OR { $$ = "or"; }
| UNION { $$ = "union"; }
*/
ColLabel: ColId { $$ = $1; }
| ABORT_TRANS { $$ = "abort"; }
| ALL { $$ = "all"; }
| ANALYZE { $$ = "analyze"; }
| ANY { $$ = "any"; }
| ASC { $$ = "asc"; }
| BETWEEN { $$ = "between"; }
| BINARY { $$ = "binary"; }
| BIT { $$ = "bit"; }
| BOTH { $$ = "both"; }
@ -5480,6 +5495,7 @@ ColLabel: ColId { $$ = $1; }
| DO { $$ = "do"; }
| ELSE { $$ = "else"; }
| END_TRANS { $$ = "end"; }
| EXCEPT { $$ = "except"; }
| EXISTS { $$ = "exists"; }
| EXPLAIN { $$ = "explain"; }
| EXTEND { $$ = "extend"; }
@ -5494,11 +5510,16 @@ ColLabel: ColId { $$ = $1; }
| GROUP { $$ = "group"; }
| HAVING { $$ = "having"; }
| INITIALLY { $$ = "initially"; }
| IN { $$ = "in"; }
| INNER_P { $$ = "inner"; }
| INTERSECT { $$ = "intersect"; }
| INTO { $$ = "into"; }
| IS { $$ = "is"; }
| ISNULL { $$ = "isnull"; }
| JOIN { $$ = "join"; }
| LEADING { $$ = "leading"; }
| LEFT { $$ = "left"; }
| LIKE { $$ = "like"; }
| LISTEN { $$ = "listen"; }
| LOAD { $$ = "load"; }
| LOCAL { $$ = "local"; }
@ -5508,11 +5529,17 @@ ColLabel: ColId { $$ = $1; }
| NCHAR { $$ = "nchar"; }
| NEW { $$ = "new"; }
| NONE { $$ = "none"; }
| NOT { $$ = "not"; }
| NOTNULL { $$ = "notnull"; }
| NULLIF { $$ = "nullif"; }
| NULL_P { $$ = "null"; }
| NUMERIC { $$ = "numeric"; }
| OFFSET { $$ = "offset"; }
| ON { $$ = "on"; }
| OR { $$ = "or"; }
| ORDER { $$ = "order"; }
| OUTER_P { $$ = "outer"; }
| OVERLAPS { $$ = "overlaps"; }
| POSITION { $$ = "position"; }
| PRECISION { $$ = "precision"; }
| PRIMARY { $$ = "primary"; }
@ -5525,6 +5552,7 @@ ColLabel: ColId { $$ = $1; }
| SESSION_USER { $$ = "session_user"; }
| SETOF { $$ = "setof"; }
| SHOW { $$ = "show"; }
| SOME { $$ = "some"; }
| SUBSTRING { $$ = "substring"; }
| TABLE { $$ = "table"; }
| THEN { $$ = "then"; }
@ -5532,6 +5560,7 @@ ColLabel: ColId { $$ = $1; }
| TRANSACTION { $$ = "transaction"; }
| TRIM { $$ = "trim"; }
| TRUE_P { $$ = "true"; }
| UNION { $$ = "union"; }
| UNIQUE { $$ = "unique"; }
| USER { $$ = "user"; }
| USING { $$ = "using"; }

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.69 2000/03/21 06:00:41 thomas Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.70 2000/04/07 13:39:34 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@ -221,6 +221,7 @@ static ScanKeyword ScanKeywords[] = {
{"setof", SETOF},
{"share", SHARE},
{"show", SHOW},
{"some", SOME},
{"start", START},
{"statement", STATEMENT},
{"stdin", STDIN},

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.55 2000/03/23 07:40:00 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.56 2000/04/07 13:39:40 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@ -1220,7 +1220,7 @@ dlog1(float64 arg1)
float64 result;
double tmp;
if (!arg1)
if (!PointerIsValid(arg1))
return (float64) NULL;
result = (float64) palloc(sizeof(float64data));
@ -1234,7 +1234,8 @@ dlog1(float64 arg1)
CheckFloat8Val(*result);
return result;
}
} /* dlog1() */
/*
* dlog10 - returns a pointer to the base 10 logarithm of arg1
@ -1262,6 +1263,331 @@ dlog10(float64 arg1)
} /* dlog10() */
/*
* dacos - returns a pointer to the arccos of arg1 (radians)
*/
float64
dacos(float64 arg1)
{
float64 result;
double tmp;
if (!PointerIsValid(arg1))
return (float64) NULL;
result = (float64) palloc(sizeof(float64data));
tmp = *arg1;
errno = 0;
*result = (float64data) acos(tmp);
if (errno != 0
#ifdef HAVE_FINITE
|| !finite(*result)
#endif
)
elog(ERROR, "dacos(%f) input is out of range", *arg1);
CheckFloat8Val(*result);
return result;
} /* dacos() */
/*
* dasin - returns a pointer to the arcsin of arg1 (radians)
*/
float64
dasin(float64 arg1)
{
float64 result;
double tmp;
if (!PointerIsValid(arg1))
return (float64) NULL;
result = (float64) palloc(sizeof(float64data));
tmp = *arg1;
errno = 0;
*result = (float64data) asin(tmp);
if (errno != 0
#ifdef HAVE_FINITE
|| !finite(*result)
#endif
)
elog(ERROR, "dasin(%f) input is out of range", *arg1);
CheckFloat8Val(*result);
return result;
} /* dasin() */
/*
* datan - returns a pointer to the arctan of arg1 (radians)
*/
float64
datan(float64 arg1)
{
float64 result;
double tmp;
if (!PointerIsValid(arg1))
return (float64) NULL;
result = (float64) palloc(sizeof(float64data));
tmp = *arg1;
errno = 0;
*result = (float64data) atan(tmp);
if (errno != 0
#ifdef HAVE_FINITE
|| !finite(*result)
#endif
)
elog(ERROR, "atan(%f) input is out of range", *arg1);
CheckFloat8Val(*result);
return result;
} /* datan() */
/*
* atan2 - returns a pointer to the arctan2 of arg1 (radians)
*/
float64
datan2(float64 arg1, float64 arg2)
{
float64 result;
if (!PointerIsValid(arg1) || !PointerIsValid(arg1))
return (float64) NULL;
result = (float64) palloc(sizeof(float64data));
errno = 0;
*result = (float64data) atan2(*arg1, *arg2);
if (errno != 0
#ifdef HAVE_FINITE
|| !finite(*result)
#endif
)
elog(ERROR, "atan2(%f,%f) input is out of range", *arg1, *arg2);
CheckFloat8Val(*result);
return result;
} /* datan2() */
/*
* dcos - returns a pointer to the cosine of arg1 (radians)
*/
float64
dcos(float64 arg1)
{
float64 result;
double tmp;
if (!PointerIsValid(arg1))
return (float64) NULL;
result = (float64) palloc(sizeof(float64data));
tmp = *arg1;
errno = 0;
*result = (float64data) cos(tmp);
if (errno != 0
#ifdef HAVE_FINITE
|| !finite(*result)
#endif
)
elog(ERROR, "dcos(%f) input is out of range", *arg1);
CheckFloat8Val(*result);
return result;
} /* dcos() */
/*
* dcot - returns a pointer to the cotangent of arg1 (radians)
*/
float64
dcot(float64 arg1)
{
float64 result;
double tmp;
if (!PointerIsValid(arg1))
return (float64) NULL;
result = (float64) palloc(sizeof(float64data));
tmp = *arg1;
errno = 0;
*result = (float64data) tan(tmp);
if ((errno != 0) || (*result == 0.0)
#ifdef HAVE_FINITE
|| !finite(*result)
#endif
)
elog(ERROR, "dcot(%f) input is out of range", *arg1);
*result = 1.0/(*result);
CheckFloat8Val(*result);
return result;
} /* dcot() */
/*
* dsin - returns a pointer to the sine of arg1 (radians)
*/
float64
dsin(float64 arg1)
{
float64 result;
double tmp;
if (!PointerIsValid(arg1))
return (float64) NULL;
result = (float64) palloc(sizeof(float64data));
tmp = *arg1;
errno = 0;
*result = (float64data) sin(tmp);
if (errno != 0
#ifdef HAVE_FINITE
|| !finite(*result)
#endif
)
elog(ERROR, "dsin(%f) input is out of range", *arg1);
CheckFloat8Val(*result);
return result;
} /* dsin() */
/*
* dtan - returns a pointer to the tangent of arg1 (radians)
*/
float64
dtan(float64 arg1)
{
float64 result;
double tmp;
if (!PointerIsValid(arg1))
return (float64) NULL;
result = (float64) palloc(sizeof(float64data));
tmp = *arg1;
errno = 0;
*result = (float64data) tan(tmp);
if (errno != 0
#ifdef HAVE_FINITE
|| !finite(*result)
#endif
)
elog(ERROR, "dtan(%f) input is out of range", *arg1);
CheckFloat8Val(*result);
return result;
} /* dtan() */
#ifndef M_PI
/* from my RH5.2 gcc math.h file - thomas 2000-04-03 */
#define M_PI 3.14159265358979323846
#endif
/*
* degrees - returns a pointer to degrees converted from radians
*/
float64
degrees(float64 arg1)
{
float64 result;
if (!arg1)
return (float64) NULL;
result = (float64) palloc(sizeof(float64data));
*result = ((*arg1) * (180.0 / M_PI));
CheckFloat8Val(*result);
return result;
} /* degrees() */
/*
* dpi - returns a pointer to degrees converted to radians
*/
float64
dpi(void)
{
float64 result;
result = (float64) palloc(sizeof(float64data));
*result = (M_PI);
return result;
} /* dpi() */
/*
* radians - returns a pointer to radians converted from degrees
*/
float64
radians(float64 arg1)
{
float64 result;
if (!arg1)
return (float64) NULL;
result = (float64) palloc(sizeof(float64data));
*result = ((*arg1) * (M_PI / 180.0));
CheckFloat8Val(*result);
return result;
} /* radians() */
/*
* drandom - returns a random number
*/
float64
drandom(void)
{
float64 result;
result = (float64) palloc(sizeof(float64data));
/* result 0.0-1.0 */
*result = (((double) random()) / RAND_MAX);
CheckFloat8Val(*result);
return result;
} /* drandom() */
/*
* setseed - set seed for the random number generator
*/
int32
setseed(float64 seed)
{
int iseed = ((*seed) * RAND_MAX);
srandom((unsigned int) ((*seed) * RAND_MAX));
return iseed;
} /* setseed() */
/*
* ====================
* ARITHMETIC OPERATORS

View File

@ -1,7 +1,7 @@
/*
* Edmund Mergl <E.Mergl@bawue.de>
*
* $Id: oracle_compat.c,v 1.22 2000/03/15 17:24:18 tgl Exp $
* $Id: oracle_compat.c,v 1.23 2000/04/07 13:39:41 thomas Exp $
*
*/
@ -446,50 +446,6 @@ rtrim(text *string, text *set)
}
/********************************************************************
*
* substr
*
* Syntax:
*
* text *substr(text *string, int4 m, int4 n)
*
* Purpose:
*
* Returns a portion of string, beginning at character m, n
* characters long. The first position of string is 1.
*
********************************************************************/
#ifdef NOT_USED
text *
substr(text *string, int4 m, int4 n)
{
text *ret;
char *ptr,
*ptr_ret;
int len;
if ((string == (text *) NULL) ||
(m <= 0) || (n <= 0) ||
((len = VARSIZE(string) - VARHDRSZ - m + 1) <= 0))
return string;
len = len + 1 < n ? len + 1 : n;
ret = (text *) palloc(VARHDRSZ + len);
VARSIZE(ret) = VARHDRSZ + len;
ptr = VARDATA(string) + m - 1;
ptr_ret = VARDATA(ret);
while (len--)
*ptr_ret++ = *ptr++;
return ret;
}
#endif
/********************************************************************
*
* translate
@ -573,3 +529,58 @@ translate(text *string, text *from, text *to)
return result;
}
int4
ascii(text *string)
{
if (!PointerIsValid(string))
return 0;
if (VARSIZE(string) <= VARHDRSZ)
return 0;
return ((int) *(VARDATA(string)));
} /* ascii() */
text *
ichar(int4 cvalue)
{
text *result;
result = (text *) palloc(VARHDRSZ + 1);
VARSIZE(result) = VARHDRSZ + 1;
*VARDATA(result) = (char) cvalue;
return result;
} /* ichar() */
text *
repeat(text *string, int4 count)
{
text *result;
int slen, tlen;
int i;
char *cp;
if (count < 0)
count = 0;
slen = (VARSIZE(string)-VARHDRSZ);
tlen = (VARHDRSZ + (count * slen));
result = (text *) palloc(tlen);
VARSIZE(result) = tlen;
cp = VARDATA(result);
for (i = 0; i < count; i++)
{
memcpy(cp, VARDATA(string), slen);
cp += slen;
}
return result;
} /* repeat() */

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.23 2000/03/14 23:06:37 thomas Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.24 2000/04/07 13:39:41 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@ -32,72 +32,6 @@
#include "utils/builtins.h"
#if 0
static int DecodeDate(char *str, int fmask, int *tmask, struct tm * tm);
static int DecodeNumber(int flen, char *field,
int fmask, int *tmask, struct tm * tm, double *fsec, int *is2digits);
static int DecodeNumberField(int len, char *str,
int fmask, int *tmask, struct tm * tm, double *fsec, int *is2digits);
static int DecodeSpecial(int field, char *lowtoken, int *val);
static int DecodeTime(char *str, int fmask, int *tmask,
struct tm * tm, double *fsec);
static int DecodeTimezone(char *str, int *tzp);
static int DecodeUnits(int field, char *lowtoken, int *val);
static int EncodeSpecialTimestamp(Timestamp dt, char *str);
static datetkn *datebsearch(char *key, datetkn *base, unsigned int nel);
static Timestamp dt2local(Timestamp dt, int timezone);
static int j2day(int jd);
static double time2t(const int hour, const int min, const double sec);
static int interval2tm(Interval span, struct tm * tm, float8 *fsec);
static int tm2interval(struct tm * tm, double fsec, Interval *span);
#define USE_DATE_CACHE 1
#define ROUND_ALL 0
int day_tab[2][13] = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0}};
char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL};
char *days[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday", NULL};
/* TMODULO()
* Macro to replace modf(), which is broken on some platforms.
*/
#define TMODULO(t,q,u) \
do { \
q = ((t < 0)? ceil(t / u): floor(t / u)); \
if (q != 0) \
t -= rint(q * u); \
} while(0)
static void GetEpochTime(struct tm * tm);
#define UTIME_MINYEAR (1901)
#define UTIME_MINMONTH (12)
#define UTIME_MINDAY (14)
#define UTIME_MAXYEAR (2038)
#define UTIME_MAXMONTH (01)
#define UTIME_MAXDAY (18)
#define IS_VALID_UTIME(y,m,d) (((y > UTIME_MINYEAR) \
|| ((y == UTIME_MINYEAR) && ((m > UTIME_MINMONTH) \
|| ((m == UTIME_MINMONTH) && (d >= UTIME_MINDAY))))) \
&& ((y < UTIME_MAXYEAR) \
|| ((y == UTIME_MAXYEAR) && ((m < UTIME_MAXMONTH) \
|| ((m == UTIME_MAXMONTH) && (d <= UTIME_MAXDAY))))))
#endif
static double time2t(const int hour, const int min, const double sec);
@ -1334,21 +1268,52 @@ interval_mi(Interval *span1, Interval *span2)
} /* interval_mi() */
Interval *
interval_div(Interval *span1, float8 *arg2)
interval_mul(Interval *span1, float8 *factor)
{
Interval *result;
double months;
if ((!PointerIsValid(span1)) || (!PointerIsValid(arg2)))
if ((!PointerIsValid(span1)) || (!PointerIsValid(factor)))
return NULL;
if (!PointerIsValid(result = palloc(sizeof(Interval))))
elog(ERROR, "Memory allocation failed, can't divide intervals");
elog(ERROR, "Memory allocation failed, can't multiply interval");
if (*arg2 == 0.0)
months = (span1->month * *factor);
result->month = rint(months);
result->time = JROUND(span1->time * *factor);
/* evaluate fractional months as 30 days */
result->time += JROUND((months - result->month) * 30 * 86400);
return result;
} /* interval_mul() */
Interval *
mul_d_interval(float8 *factor, Interval *span1)
{
return interval_mul(span1, factor);
} /* mul_d_interval() */
Interval *
interval_div(Interval *span1, float8 *factor)
{
Interval *result;
double months;
if ((!PointerIsValid(span1)) || (!PointerIsValid(factor)))
return NULL;
if (!PointerIsValid(result = palloc(sizeof(Interval))))
elog(ERROR, "Memory allocation failed, can't divide interval");
if (*factor == 0.0)
elog(ERROR, "interval_div: divide by 0.0 error");
result->month = rint(span1->month / *arg2);
result->time = JROUND(span1->time / *arg2);
months = (span1->month / *factor);
result->month = rint(months);
result->time = JROUND(span1->time / *factor);
/* evaluate fractional months as 30 days */
result->time += JROUND((months - result->month) * 30 * 86400);
return result;
} /* interval_div() */

View File

@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: catversion.h,v 1.18 2000/03/14 23:06:42 thomas Exp $
* $Id: catversion.h,v 1.19 2000/04/07 13:39:49 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200003141
#define CATALOG_VERSION_NO 200004051
#endif

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_operator.h,v 1.72 2000/03/14 23:06:43 thomas Exp $
* $Id: pg_operator.h,v 1.73 2000/04/07 13:39:49 thomas Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@ -641,6 +641,8 @@ DATA(insert OID = 1567 ( "##" PGUID 0 b t f 601 603 600 0 0 0 0 close_s
DATA(insert OID = 1568 ( "##" PGUID 0 b t f 628 603 600 0 0 0 0 close_lb - - ));
DATA(insert OID = 1577 ( "##" PGUID 0 b t f 628 601 600 0 0 0 0 close_ls - - ));
DATA(insert OID = 1578 ( "##" PGUID 0 b t f 601 601 600 0 0 0 0 close_lseg - - ));
DATA(insert OID = 1583 ( "*" PGUID 0 b t f 1186 701 1186 0 0 0 0 interval_mul - - ));
DATA(insert OID = 1584 ( "*" PGUID 0 b t f 701 1186 1186 0 0 0 0 mul_d_interval - - ));
DATA(insert OID = 1585 ( "/" PGUID 0 b t f 1186 701 1186 0 0 0 0 interval_div - - ));
DATA(insert OID = 1586 ( "<>" PGUID 0 b t f 601 601 16 1586 1535 0 0 lseg_ne neqsel neqjoinsel ));

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_proc.h,v 1.129 2000/03/24 02:41:44 tgl Exp $
* $Id: pg_proc.h,v 1.130 2000/04/07 13:39:49 thomas Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
@ -489,7 +489,6 @@ DATA(insert OID = 233 ( dexp PGUID 11 f t t 1 f 701 "701" 100 0 0 100 dex
DESCR("natural exponential (e^x)");
DATA(insert OID = 234 ( dlog1 PGUID 11 f t t 1 f 701 "701" 100 0 0 100 dlog1 - ));
DESCR("natural logarithm");
DATA(insert OID = 235 ( float8 PGUID 11 f t t 1 f 701 "21" 100 0 0 100 i2tod - ));
DESCR("convert int2 to float8");
DATA(insert OID = 236 ( float4 PGUID 11 f t t 1 f 700 "21" 100 0 0 100 i2tof - ));
@ -1993,19 +1992,58 @@ DATA(insert OID = 1572 ( notlike PGUID 11 f t t 2 f 16 "19 25" 100 0 0 100 n
DESCR("does not match LIKE expression");
/* SEQUENCEs nextval & currval functions */
DATA(insert OID = 1574 ( nextval PGUID 11 f t f 1 f 23 "25" 100 0 0 100 nextval - ));
DATA(insert OID = 1574 ( nextval PGUID 11 f t f 1 f 23 "25" 100 0 0 100 nextval - ));
DESCR("sequence next value");
DATA(insert OID = 1575 ( currval PGUID 11 f t f 1 f 23 "25" 100 0 0 100 currval - ));
DATA(insert OID = 1575 ( currval PGUID 11 f t f 1 f 23 "25" 100 0 0 100 currval - ));
DESCR("sequence current value");
DATA(insert OID = 1576 ( setval PGUID 11 f t f 2 f 23 "25 23" 100 0 0 100 setval - ));
DATA(insert OID = 1576 ( setval PGUID 11 f t f 2 f 23 "25 23" 100 0 0 100 setval - ));
DESCR("sequence set value");
DATA(insert OID = 1598 ( random PGUID 11 f t f 0 f 701 "0" 100 0 0 100 drandom - ));
DESCR("radians to degrees");
DATA(insert OID = 1599 ( setseed PGUID 11 f t t 1 f 23 "701" 100 0 0 100 setseed - ));
DESCR("radians to degrees");
/* OIDS 1600 - 1699 */
DATA(insert OID = 1619 ( varchar PGUID 11 f t t 1 f 1043 "23" 100 0 0 100 int4_text - ));
DATA(insert OID = 1600 ( asin PGUID 11 f t t 1 f 701 "701" 100 0 0 100 dasin - ));
DESCR("arcsine");
DATA(insert OID = 1601 ( acos PGUID 11 f t t 1 f 701 "701" 100 0 0 100 dacos - ));
DESCR("arcsine");
DATA(insert OID = 1602 ( atan PGUID 11 f t t 1 f 701 "701" 100 0 0 100 datan - ));
DESCR("arctangent");
DATA(insert OID = 1603 ( atan2 PGUID 11 f t t 2 f 701 "701 701" 100 0 0 100 datan2 - ));
DESCR("arctangent, two arguments");
DATA(insert OID = 1604 ( sin PGUID 11 f t t 1 f 701 "701" 100 0 0 100 dsin - ));
DESCR("sine");
DATA(insert OID = 1605 ( cos PGUID 11 f t t 1 f 701 "701" 100 0 0 100 dcos - ));
DESCR("cosine");
DATA(insert OID = 1606 ( tan PGUID 11 f t t 1 f 701 "701" 100 0 0 100 dtan - ));
DESCR("tangent");
DATA(insert OID = 1607 ( cot PGUID 11 f t t 1 f 701 "701" 100 0 0 100 dcot - ));
DESCR("cotangent");
DATA(insert OID = 1608 ( degrees PGUID 11 f t t 1 f 701 "701" 100 0 0 100 degrees - ));
DESCR("radians to degrees");
DATA(insert OID = 1609 ( radians PGUID 11 f t t 1 f 701 "701" 100 0 0 100 radians - ));
DESCR("radians to degrees");
DATA(insert OID = 1610 ( pi PGUID 11 f t t 0 f 701 "0" 100 0 0 100 dpi - ));
DESCR("PI");
DATA(insert OID = 1618 ( interval_mul PGUID 11 f t t 2 f 1186 "1186 701" 100 0 0 100 interval_mul - ));
DESCR("multiply interval");
DATA(insert OID = 1619 ( varchar PGUID 11 f t t 1 f 1043 "23" 100 0 0 100 int4_text - ));
DESCR("convert int4 to varchar");
DATA(insert OID = 1623 ( varchar PGUID 11 f t t 1 f 1043 "20" 100 0 0 100 int8_text - ));
DATA(insert OID = 1620 ( ascii PGUID 11 f t t 1 f 23 "25" 100 0 0 100 ascii - ));
DESCR("convert first char to int4");
DATA(insert OID = 1621 ( ichar PGUID 11 f t t 1 f 25 "23" 100 0 0 100 ichar - ));
DESCR("convert int4 to char");
DATA(insert OID = 1622 ( repeat PGUID 11 f t t 2 f 25 "25 23" 100 0 0 100 repeat - ));
DESCR("replicate string int4 times");
DATA(insert OID = 1623 ( varchar PGUID 11 f t t 1 f 1043 "20" 100 0 0 100 int8_text - ));
DESCR("convert int8 to varchar");
DATA(insert OID = 1624 ( mul_d_interval PGUID 11 f t t 2 f 1186 "701 1186" 100 0 0 100 mul_d_interval - ));
/* OID's 1625 - 1639 LZTEXT data type */
DATA(insert OID = 1626 ( lztextin PGUID 11 f t t 1 f 1625 "0" 100 0 0 100 lztextin - ));
@ -2218,7 +2256,7 @@ DATA(insert OID = 1708 ( round PGUID 14 f t t 1 f 1700 "1700" 100 0 0 100 "s
DESCR("value rounded to 'scale' of zero");
DATA(insert OID = 1709 ( trunc PGUID 11 f t t 2 f 1700 "1700 23" 100 0 0 100 numeric_trunc - ));
DESCR("value truncated to 'scale'");
DATA(insert OID = 1710 ( trunc PGUID 14 f t t 1 f 1700 "1700" 100 0 0 100 "select numeric_trunc($1,0)" - ));
DATA(insert OID = 1710 ( trunc PGUID 14 f t t 1 f 1700 "1700" 100 0 0 100 "select trunc($1,0)" - ));
DESCR("value truncated to 'scale' of zero");
DATA(insert OID = 1711 ( ceil PGUID 11 f t t 1 f 1700 "1700" 100 0 0 100 numeric_ceil - ));
DESCR("smallest integer >= value");

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: builtins.h,v 1.107 2000/03/24 02:41:45 tgl Exp $
* $Id: builtins.h,v 1.108 2000/04/07 13:40:12 thomas Exp $
*
* NOTES
* This should normally only be included by fmgr.h.
@ -271,6 +271,21 @@ extern float64 dpow(float64 arg1, float64 arg2);
extern float64 dexp(float64 arg1);
extern float64 dlog1(float64 arg1);
extern float64 dlog10(float64 arg1);
extern float64 dacos(float64 arg1);
extern float64 dasin(float64 arg1);
extern float64 datan(float64 arg1);
extern float64 datan2(float64 arg1, float64 arg2);
extern float64 dcos(float64 arg1);
extern float64 dcot(float64 arg1);
extern float64 dsin(float64 arg1);
extern float64 dtan(float64 arg1);
extern float64 degrees(float64 arg1);
extern float64 dpi(void);
extern float64 radians(float64 arg1);
extern float64 dtan(float64 arg1);
extern float64 drandom(void);
extern int32 setseed(float64 seed);
extern float64 float48pl(float32 arg1, float64 arg2);
extern float64 float48mi(float32 arg1, float64 arg2);
extern float64 float48mul(float32 arg1, float64 arg2);
@ -476,6 +491,9 @@ extern text *ltrim(text *string, text *set);
extern text *rtrim(text *string, text *set);
extern text *substr(text *string, int4 m, int4 n);
extern text *translate(text *string, text *from, text *to);
extern text *ichar(int4 arg1);
extern text *repeat(text *string, int4 count);
extern int4 ascii(text *string);
/* acl.c */

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: timestamp.h,v 1.2 2000/03/14 23:06:51 thomas Exp $
* $Id: timestamp.h,v 1.3 2000/04/07 13:40:12 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@ -142,7 +142,9 @@ extern text *timestamp_zone(text *zone, Timestamp *timestamp);
extern Interval *interval_um(Interval *span);
extern Interval *interval_pl(Interval *span1, Interval *span2);
extern Interval *interval_mi(Interval *span1, Interval *span2);
extern Interval *interval_div(Interval *span1, float8 *arg2);
extern Interval *interval_mul(Interval *span1, float8 *factor);
extern Interval *mul_d_interval(float8 *factor, Interval *span1);
extern Interval *interval_div(Interval *span1, float8 *factor);
extern Interval *timestamp_mi(Timestamp *dt1, Timestamp *dt2);
extern Timestamp *timestamp_pl_span(Timestamp *dt, Interval *span);

View File

@ -106,7 +106,7 @@ char *mapFuncs[][2] = {
// { "SIN", "sin" },
// { "SQRT", "sqrt" },
// { "TAN", "tan" },
// { "TRUNCATE", "truncate" },
{ "TRUNCATE", "trunc" },
// { "CURDATE", "curdate" },
// { "CURTIME", "curtime" },

View File

@ -1,5 +1,5 @@
#!/bin/sh
# $Header: /cvsroot/pgsql/src/test/regress/Attic/regress.sh,v 1.48 2000/03/31 22:03:52 petere Exp $
# $Header: /cvsroot/pgsql/src/test/regress/Attic/regress.sh,v 1.49 2000/04/07 13:40:45 thomas Exp $
#
if [ $# -eq 0 ]; then
echo "Syntax: $0 <hostname> [extra-tests]"
@ -30,6 +30,8 @@ fi
PGTZ="PST8PDT"; export PGTZ
PGDATESTYLE="Postgres,US"; export PGDATESTYLE
LANG= ; export LANG
LC_ALL= ; export LC_ALL
FRONTEND="psql $HOSTLOC -a -q -X"