diff options
author | Thomas G. Lockhart <lockhart@fourpalms.org> | 2000-04-07 13:40:45 +0000 |
---|---|---|
committer | Thomas G. Lockhart <lockhart@fourpalms.org> | 2000-04-07 13:40:45 +0000 |
commit | a349733bbbeaca5aa5b0b3520963b01a455c9ff8 (patch) | |
tree | 75b3222de81890c5fafb91eee0b0f920716d6df4 /src/backend | |
parent | 1b992b468bc5fef62f5a1470f382c70311e9d162 (diff) |
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.
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/commands/define.c | 34 | ||||
-rw-r--r-- | src/backend/commands/variable.c | 43 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 117 | ||||
-rw-r--r-- | src/backend/parser/keywords.c | 3 | ||||
-rw-r--r-- | src/backend/utils/adt/float.c | 332 | ||||
-rw-r--r-- | src/backend/utils/adt/oracle_compat.c | 101 | ||||
-rw-r--r-- | src/backend/utils/adt/timestamp.c | 111 |
7 files changed, 561 insertions, 180 deletions
diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c index cd69f079113..2090076f2e4 100644 --- a/src/backend/commands/define.c +++ b/src/backend/commands/define.c @@ -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 diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c index 482b9a23ae0..6432d3c2b8f 100644 --- a/src/backend/commands/variable.c +++ b/src/backend/commands/variable.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.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 @@ -1156,6 +1194,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 } }; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 1ab63847aff..e4f59bc605d 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.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"; } diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c index 470a6c95234..cd1b66a7f8e 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.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}, diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c index 973e9cd12e9..82c7e191d53 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.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 @@ -1263,6 +1264,331 @@ dlog10(float64 arg1) /* + * 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 * ==================== diff --git a/src/backend/utils/adt/oracle_compat.c b/src/backend/utils/adt/oracle_compat.c index 36524798823..41e2563f3b0 100644 --- a/src/backend/utils/adt/oracle_compat.c +++ b/src/backend/utils/adt/oracle_compat.c @@ -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 $ * */ @@ -448,50 +448,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 * * Syntax: @@ -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() */ + diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index 4086a803dd7..7a94ddd804d 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.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(factor))) + return NULL; + + if (!PointerIsValid(result = palloc(sizeof(Interval)))) + elog(ERROR, "Memory allocation failed, can't multiply interval"); + + 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(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 divide interval"); - if (*arg2 == 0.0) + 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() */ |