mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 20:03:02 +01:00
Fixed CORE-5657: Various UDF-related security vulnerabilities
This commit is contained in:
parent
820a64eba8
commit
b9c17656e9
@ -113,7 +113,7 @@ copyFiles() {
|
||||
mkdir $DestDir/UDF
|
||||
mkdir $DestDir/misc
|
||||
mkdir $DestDir/misc/upgrade
|
||||
for i in ib_udf metadata security; do
|
||||
for i in metadata security; do
|
||||
mkdir $DestDir/misc/upgrade/$i
|
||||
done
|
||||
|
||||
@ -184,16 +184,8 @@ copyFiles() {
|
||||
|
||||
cp $BuiltFBDir/intl/libfbintl.so $DestDir/intl/fbintl
|
||||
|
||||
cp $BuiltFBDir/UDF/ib_udf.so $DestDir/UDF/
|
||||
cp $BuiltFBDir/UDF/fbudf.so $DestDir/UDF/
|
||||
|
||||
# Note that the following items copy files from outside the build tree
|
||||
|
||||
# Copy the sql-declarations into the UDF-directory
|
||||
cp $BuildRootDir/src/extlib/ib_udf.sql $DestDir/UDF/
|
||||
cp $BuildRootDir/src/extlib/ib_udf2.sql $DestDir/UDF/
|
||||
cp $BuildRootDir/src/extlib/fbudf/fbudf.sql $DestDir/UDF/
|
||||
|
||||
# Copy various documentation
|
||||
ls $BuildRootDir/doc/*.pdf >/dev/null 2>&1 && cp $BuildRootDir/doc/*.pdf $DestDir/doc
|
||||
cp $BuildRootDir/doc/sql.extensions/README* $DestDir/doc/sql.extensions
|
||||
|
@ -139,7 +139,7 @@ copyFiles() {
|
||||
makeDirs "@FB_BINDIR@ @FB_SBINDIR@ @FB_CONFDIR@ @FB_LIBDIR@ @FB_INCDIR@ @FB_DOCDIR@/sql.extensions @FB_UDFDIR@ @FB_SAMPLEDIR@ \
|
||||
@FB_SAMPLEDBDIR@ @FB_HELPDIR@ @FB_INTLDIR@ @FB_MISCDIR@ @FB_SECDBDIR@ @FB_MSGDIR@ @FB_LOGDIR@ @FB_GUARDDIR@ @FB_PLUGDIR@"
|
||||
|
||||
for i in ib_udf metadata security; do
|
||||
for i in metadata security; do
|
||||
makeDirs @FB_MISCDIR@/upgrade/$i
|
||||
done
|
||||
|
||||
@ -263,18 +263,7 @@ copyFiles() {
|
||||
chmod 0755 ${TargetDir}@FB_INTLDIR@/fbintl
|
||||
chmod 0644 ${TargetDir}@FB_INTLDIR@/fbintl.conf
|
||||
|
||||
#UDF
|
||||
cp $BuiltFBDir/UDF/ib_udf.so ${TargetDir}@FB_UDFDIR@
|
||||
cp $BuiltFBDir/UDF/fbudf.so ${TargetDir}@FB_UDFDIR@
|
||||
# Note that the following items copy files from outside the build tree.
|
||||
# Copy the sql-declarations into the UDF-directory
|
||||
cp $BuildRootDir/src/extlib/ib_udf.sql ${TargetDir}@FB_UDFDIR@
|
||||
cp $BuildRootDir/src/extlib/ib_udf2.sql ${TargetDir}@FB_UDFDIR@
|
||||
cp $BuildRootDir/src/extlib/fbudf/fbudf.sql ${TargetDir}@FB_UDFDIR@
|
||||
|
||||
chown root:wheel ${TargetDir}@FB_UDFDIR@/*.so ${TargetDir}@FB_UDFDIR@/*.sql
|
||||
chmod 0755 ${TargetDir}@FB_UDFDIR@/*.so
|
||||
chmod 0644 ${TargetDir}@FB_UDFDIR@/*.sql
|
||||
|
||||
#doc
|
||||
cp $BuildRootDir/doc/README.* ${TargetDir}@FB_DOCDIR@
|
||||
|
@ -262,17 +262,8 @@ copyFiles() {
|
||||
chmod 0755 ${TargetDir}@FB_INTLDIR@/fbintl
|
||||
chmod 0644 ${TargetDir}@FB_INTLDIR@/fbintl.conf
|
||||
|
||||
#UDF
|
||||
cp $BuiltFBDir/UDF/ib_udf.so ${TargetDir}@FB_UDFDIR@
|
||||
cp $BuiltFBDir/UDF/fbudf.so ${TargetDir}@FB_UDFDIR@
|
||||
# Note that the following items copy files from outside the build tree.
|
||||
# Copy the sql-declarations into the UDF-directory
|
||||
cp $BuildRootDir/src/extlib/ib_udf.sql ${TargetDir}@FB_UDFDIR@
|
||||
cp $BuildRootDir/src/extlib/ib_udf2.sql ${TargetDir}@FB_UDFDIR@
|
||||
cp $BuildRootDir/src/extlib/fbudf/fbudf.sql ${TargetDir}@FB_UDFDIR@
|
||||
|
||||
chmod 0755 ${TargetDir}@FB_UDFDIR@/*.so
|
||||
chmod 0644 ${TargetDir}@FB_UDFDIR@/*.sql
|
||||
|
||||
#doc
|
||||
cp $BuildRootDir/doc/*.pdf ${TargetDir}@FB_DOCDIR@
|
||||
|
@ -179,12 +179,6 @@ cp -Rf $BuiltFBDir/lib/libfbclient.so* $DestDir/lib || exit
|
||||
cp -f $BuiltFBDir/lib/libib_util.so $DestDir/lib/libib_util.so || exit
|
||||
|
||||
cp $BuiltFBDir/intl/libfbintl.so $DestDir/intl/fbintl || exit
|
||||
cp $BuiltFBDir/UDF/ib_udf.so $DestDir/UDF/ || exit
|
||||
cp $BuiltFBDir/UDF/fbudf.so $DestDir/UDF/ || exit
|
||||
|
||||
# Copy the sql-declarations into the UDF-directory
|
||||
cp $BuildRootDir/src/extlib/ib_udf.sql $DestDir/UDF/ || exit
|
||||
cp $BuildRootDir/src/extlib/fbudf/fbudf.sql $DestDir/UDF/ || exit
|
||||
|
||||
# Note that this copies files from outside the build tree.
|
||||
echo Installing documentation
|
||||
|
@ -287,23 +287,6 @@ if "%PROCESSOR_ARCHITECTURE%"=="x86" (
|
||||
goto :EOF
|
||||
)
|
||||
|
||||
@echo Copying udf library scripts...
|
||||
for %%v in ( ib_udf.sql ib_udf2.sql ) do (
|
||||
@copy /Y %FB_ROOT_PATH%\src\extlib\%%v %FB_OUTPUT_DIR%\udf\%%v > nul
|
||||
@if %ERRORLEVEL% GEQ 1 (
|
||||
call :ERROR copy /Y %FB_ROOT_PATH%\src\extlib\%%v %FB_OUTPUT_DIR%\udf\%%v failed with error %ERRORLEVEL%.
|
||||
goto :EOF
|
||||
)
|
||||
)
|
||||
|
||||
for %%v in ( fbudf.sql fbudf.txt ) do (
|
||||
@copy /Y %FB_ROOT_PATH%\src\extlib\fbudf\%%v %FB_OUTPUT_DIR%\UDF\%%v > nul
|
||||
@if %ERRORLEVEL% GEQ 1 (
|
||||
call :ERROR copy /Y %FB_ROOT_PATH%\src\extlib\fbudf\%%v %FB_OUTPUT_DIR%\UDF\%%v failed with error %ERRORLEVEL%.
|
||||
goto :EOF
|
||||
)
|
||||
)
|
||||
|
||||
:: Various upgrade scripts and docs
|
||||
mkdir %FB_OUTPUT_DIR%\misc\upgrade\security 2>nul
|
||||
@copy %FB_ROOT_PATH%\src\misc\upgrade\v3.0\security_* %FB_OUTPUT_DIR%\misc\upgrade\security > nul
|
||||
|
@ -180,12 +180,11 @@
|
||||
# NOTE: THE EXTERNAL FUNCTION ENGINE FEATURE COULD BE USED TO COMPROMISE
|
||||
# THE SERVER/HOST AS WELL AS DATABASE SECURITY!!
|
||||
#
|
||||
# IT IS STRONGLY RECOMMENDED THAT THIS SETTING BE USED TO LIMIT
|
||||
# EXTERNAL FUNCTION LOCATIONS!
|
||||
# IT IS STRONGLY RECOMMENDED THAT THIS SETTING BE SET TO NONE!
|
||||
#
|
||||
# Type: string (special format)
|
||||
#
|
||||
#UdfAccess = Restrict UDF
|
||||
#UdfAccess = None
|
||||
|
||||
|
||||
# ----------------------------
|
||||
|
@ -396,27 +396,10 @@ msg.timestamp: $(MSG_FILES)
|
||||
$(TOUCH) $@
|
||||
|
||||
|
||||
.PHONY: udfs ibutil ibudf fbudf udfsupport
|
||||
.PHONY: ibutil udfsupport
|
||||
|
||||
udfsupport:
|
||||
$(MAKE) ibutil
|
||||
$(MAKE) udfs
|
||||
|
||||
udfs: ibudf fbudf
|
||||
|
||||
UDF = $(FB_BUILD)/UDF
|
||||
IBUDF_SO = $(UDF)/ib_udf.$(SHRLIB_EXT)
|
||||
FBUDF_SO = $(UDF)/fbudf.$(SHRLIB_EXT)
|
||||
|
||||
ibudf: $(IBUDF_SO)
|
||||
|
||||
$(IBUDF_SO): $(IBUDF_Objects)
|
||||
$(call LINK_UDF,ib_udf) -o $@ $^ $(LINK_UDF_LIBS)
|
||||
|
||||
fbudf: $(FBUDF_SO)
|
||||
|
||||
$(FBUDF_SO): $(FBUDF_Objects) $(COMMON_LIB)
|
||||
$(call LINK_UDF,fbudf) -o $@ $^ $(LINK_UDF_LIBS) $(FIREBIRD_LIBRARY_LINK)
|
||||
|
||||
ibutil: $(LIBIBUTIL_SO)
|
||||
|
||||
@ -425,7 +408,7 @@ $(LIBIBUTIL_SO): $(UTIL_Objects)
|
||||
|
||||
|
||||
#___________________________________________________________________________
|
||||
# most of utilities, including network server and UDFs
|
||||
# most of utilities, including network server and UDF support
|
||||
# qli is not here cause it needs special database (help.fdb), therefore needs gbak
|
||||
#
|
||||
|
||||
@ -498,20 +481,22 @@ $(NBACKUP): $(NBACKUP_Objects) $(COMMON_LIB)
|
||||
# plugins - some of them are required to build examples, use separate entry for them
|
||||
#
|
||||
|
||||
.PHONY: udr legacy_user_management legacy_auth_server trace auth_debug
|
||||
.PHONY: udr legacy_user_management legacy_auth_server trace auth_debug udf_compat
|
||||
UDR_PLUGIN = $(call makePluginName,udr_engine)
|
||||
LEGACY_USER_MANAGER = $(call makePluginName,Legacy_UserManager)
|
||||
LEGACY_AUTH_SERVER = $(call makePluginName,Legacy_Auth)
|
||||
SRP_USER_MANAGER = $(call makePluginName,Srp)
|
||||
FBTRACE = $(call makePluginName,fbtrace)
|
||||
AUTH_DEBUGGER = $(call makePluginName,Auth_Debug)
|
||||
UDF_BACKWARD_COMPATIBILITY_BASENAME = $(LIB_PREFIX)udf_compat.$(SHRLIB_EXT)
|
||||
UDF_BACKWARD_COMPATIBILITY = $(PLUGINS)/udr/$(UDF_BACKWARD_COMPATIBILITY_BASENAME)
|
||||
|
||||
BUILD_DEBUG:=
|
||||
ifeq ($(TARGET),Debug)
|
||||
BUILD_DEBUG:=auth_debug
|
||||
endif
|
||||
|
||||
plugins: udr legacy_user_management legacy_auth_server srp_user_management trace $(BUILD_DEBUG)
|
||||
plugins: udr legacy_user_management legacy_auth_server srp_user_management trace $(BUILD_DEBUG) udf_compat
|
||||
|
||||
udr: $(UDR_PLUGIN) $(PLUGINS)/udr_engine.conf
|
||||
|
||||
@ -546,6 +531,15 @@ srp_user_management: $(SRP_USER_MANAGER)
|
||||
$(SRP_USER_MANAGER): $(SRP_USERS_MANAGE_Objects) $(COMMON_LIB)
|
||||
$(LINK_PLUGIN) $(call LIB_LINK_SONAME,$(notdir $@).0) -o $@ $^ $(LINK_PLUG_LIBS) $(FIREBIRD_LIBRARY_LINK)
|
||||
|
||||
udf_compat: $(UDF_BACKWARD_COMPATIBILITY) $(COMPAT_SQL)
|
||||
|
||||
$(UDF_BACKWARD_COMPATIBILITY): $(COMPAT_Objects)
|
||||
$(LIB_LINK) $(LIB_LINK_OPTIONS) $(call LIB_LINK_SONAME,$(UDF_BACKWARD_COMPATIBILITY_BASENAME)) \
|
||||
$(LINK_UDR_PLUGIN_SYMBOLS) $(LIB_PATH_OPTS) $(UNDEF_FLAGS) -o $@ $^ $(THR_LIBS)
|
||||
|
||||
$(COMPAT_SQL): $(SRC_COMPAT_SQL)
|
||||
cp $^ $@
|
||||
|
||||
#___________________________________________________________________________
|
||||
# codes - developers change them sometimes
|
||||
#
|
||||
|
@ -196,11 +196,14 @@ AllObjects += $(UDRENG_Objects)
|
||||
|
||||
|
||||
# UDF support
|
||||
IBUDF_Objects:= $(call makeObjects,extlib,ib_udf.cpp)
|
||||
FBUDF_Objects:= $(call makeObjects,extlib/fbudf,fbudf.cpp)
|
||||
UTIL_Objects:= $(call makeObjects,extlib,ib_util.cpp)
|
||||
|
||||
AllObjects += $(IBUDF_Objects) $(FBUDF_Objects) $(UTIL_Objects)
|
||||
# UDR backward compatible with distributed UDFs
|
||||
COMPAT_Objects:= $(call makeObjects,extlib,UdfBackwardCompatibility.cpp)
|
||||
SRC_COMPAT_SQL:= $(SRC_ROOT)/extlib/UdfBackwardCompatibility.sql
|
||||
COMPAT_SQL:= $(PLUGINS)/udr/udf_compat.sql
|
||||
|
||||
AllObjects += $(UTIL_Objects) $(COMPAT_Objects)
|
||||
|
||||
|
||||
# Regenerate error codes
|
||||
|
@ -96,8 +96,6 @@ darwin_finish_cs_framework:
|
||||
chmod +x ../builds/install/arch-specific/darwin/changeMultiConnectMode
|
||||
cp ../builds/install/arch-specific/darwin/changeMultiConnectMode \
|
||||
$(FB_FW)/Resources/bin/changeMultiConnectMode.sh
|
||||
cp ../src/extlib/ib_udf.sql $(FB_FW)/Resources/English.lproj/var/UDF
|
||||
cp ../src/extlib/fbudf/fbudf.sql $(FB_FW)/Resources/English.lproj/var/UDF
|
||||
cp ../builds/install/arch-specific/darwin/FrameworkInfo.plist \
|
||||
$(FB_FW)/Resources/Info.plist
|
||||
cp ../builds/install/arch-specific/darwin/launchd.org.firebird.gds.plist \
|
||||
@ -165,8 +163,6 @@ darwin_finish_ss_framework:
|
||||
cp ../gen/firebird/bin/gdef $(FB_FW)/Resources/bin
|
||||
cp ../gen/firebird/bin/fbsvcmgr $(FB_FW)/Resources/bin
|
||||
cp ../gen/firebird/bin/fbtracemgr $(FB_FW)/Resources/bin
|
||||
cp ../src/extlib/ib_udf.sql $(FB_FW)/Resources/English.lproj/var/UDF
|
||||
cp ../src/extlib/fbudf/fbudf.sql $(FB_FW)/Resources/English.lproj/var/UDF
|
||||
cp ../builds/install/arch-specific/darwin/FrameworkInfo.plist \
|
||||
$(FB_FW)/Resources/Info.plist
|
||||
cp ../builds/install/arch-specific/darwin/launchdss.org.firebird.gds.plist \
|
||||
|
32
doc/README.incompatibilities.3to4.txt
Normal file
32
doc/README.incompatibilities.3to4.txt
Normal file
@ -0,0 +1,32 @@
|
||||
********************************************************************************
|
||||
LIST OF KNOWN INCOMPATIBILITIES
|
||||
between versions 3.0 and 4.0
|
||||
********************************************************************************
|
||||
|
||||
This document describes all the changes that make v4.0 incompatible in any way
|
||||
as compared with the previous releases and hence could affect your databases and
|
||||
applications.
|
||||
|
||||
Please read the below descriptions carefully before upgrading your software to
|
||||
the new Firebird version.
|
||||
|
||||
Deprecating UDF
|
||||
--------------------------
|
||||
|
||||
* Initial design of UDF always used to be security problem. The most dangerous
|
||||
security holes when UDFs and external tables are used simultaneousky were
|
||||
fixed in FB 1.5. But even after it incorrectly declared (using SQL statement
|
||||
DECLARE EXTERNAL FUNCTION) UDF can easily cause various security issues like
|
||||
server crash or execution of arbitrary code. Therefore UDFs are deprecated
|
||||
in v.4. That means that UDFs can't be used with default configuration
|
||||
(parameter "UdfAccess" set to "None") and all sample UDF libraries (ib_udf,
|
||||
fbudf) are not distributed any more. Most of functions in that libraries
|
||||
were replaced with builtin analogs in previous versions and therefore
|
||||
already deprecated. A few remaining functions got safe replacement in UDR
|
||||
library "udf_compat", namely div, frac, dow, sdow, getExactTimestampUTC and
|
||||
isLeapYear. Users who still wish to use UDFs should set "UdfAccess" to
|
||||
"Restrict <path-list>". If you never used to modify this parameter before
|
||||
path-list is just UDF and resulting line in firebird.conf should be:
|
||||
UdfAccess = Restrict UDF
|
||||
Recommended long-term solution is replacing of UDF with UDR.
|
||||
|
@ -162,8 +162,8 @@ const Config::ConfigEntry Config::entries[MAX_CONFIG_KEY] =
|
||||
{TYPE_STRING, "RemoteBindAddress", (ConfigValue) 0},
|
||||
{TYPE_STRING, "ExternalFileAccess", (ConfigValue) "None"}, // location(s) of external files for tables
|
||||
{TYPE_STRING, "DatabaseAccess", (ConfigValue) "Full"}, // location(s) of databases
|
||||
#define UDF_DEFAULT_CONFIG_VALUE "Restrict UDF"
|
||||
{TYPE_STRING, "UdfAccess", (ConfigValue) UDF_DEFAULT_CONFIG_VALUE}, // location(s) of UDFs
|
||||
#define UDF_DEFAULT_RESTRICT_VALUE "Restrict UDF" // use it to substitute FB_UDFDIR value
|
||||
{TYPE_STRING, "UdfAccess", (ConfigValue) "None"}, // location(s) of UDFs
|
||||
{TYPE_STRING, "TempDirectories", (ConfigValue) 0},
|
||||
#ifdef DEV_BUILD
|
||||
{TYPE_BOOLEAN, "BugcheckAbort", (ConfigValue) true}, // whether to abort() engine when internal error is found
|
||||
@ -595,8 +595,8 @@ const char *Config::getUdfAccess()
|
||||
}
|
||||
|
||||
const char* v = (const char*) getDefaultConfig()->values[KEY_UDF_ACCESS];
|
||||
if (CASE_SENSITIVITY ? (! strcmp(v, UDF_DEFAULT_CONFIG_VALUE) && FB_UDFDIR[0]) :
|
||||
(! fb_utils::stricmp(v, UDF_DEFAULT_CONFIG_VALUE) && FB_UDFDIR[0]))
|
||||
if (CASE_SENSITIVITY ? (! strcmp(v, UDF_DEFAULT_RESTRICT_VALUE) && FB_UDFDIR[0]) :
|
||||
(! fb_utils::stricmp(v, UDF_DEFAULT_RESTRICT_VALUE) && FB_UDFDIR[0]))
|
||||
{
|
||||
udfValue->printf("Restrict %s", FB_UDFDIR);
|
||||
value = udfValue->c_str();
|
||||
|
348
src/extlib/UdfBackwardCompatibility.cpp
Normal file
348
src/extlib/UdfBackwardCompatibility.cpp
Normal file
@ -0,0 +1,348 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Initial
|
||||
* Developer's Public License Version 1.0 (the "License");
|
||||
* you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
|
||||
*
|
||||
* Software distributed under the License is distributed AS IS,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing rights
|
||||
* and limitations under the License.
|
||||
*
|
||||
* The Original Code was created by Adriano dos Santos Fernandes
|
||||
* for the Firebird Open Source RDBMS project.
|
||||
*
|
||||
* Copyright (c) 2008 Adriano dos Santos Fernandes <adrianosf@gmail.com>
|
||||
* and all contributors signed below.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* Alex Peshkoff, 2017
|
||||
* Claudio Valderrama, 2001
|
||||
*/
|
||||
|
||||
#define FB_UDR_STATUS_TYPE ::Firebird::ThrowStatusWrapper
|
||||
|
||||
#include "firebird.h"
|
||||
|
||||
#include <ibase.h>
|
||||
#include <firebird/UdrCppEngine.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_MATH_H
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TIMEB_H
|
||||
# include <sys/timeb.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
#include <limits>
|
||||
|
||||
using namespace Firebird;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/***
|
||||
create function div (
|
||||
n1 integer,
|
||||
n2 integer
|
||||
) returns double precision
|
||||
external name 'udf_compat!UC_div'
|
||||
engine udr;
|
||||
***/
|
||||
FB_UDR_BEGIN_FUNCTION(UC_div)
|
||||
FB_UDR_MESSAGE(InMessage,
|
||||
(FB_INTEGER, n1)
|
||||
(FB_INTEGER, n2)
|
||||
);
|
||||
|
||||
FB_UDR_MESSAGE(OutMessage,
|
||||
(FB_DOUBLE, result)
|
||||
);
|
||||
|
||||
FB_UDR_EXECUTE_FUNCTION
|
||||
{
|
||||
if (in->n1Null || in->n2Null)
|
||||
{
|
||||
out->resultNull = FB_TRUE;
|
||||
out->result = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
out->resultNull = FB_FALSE;
|
||||
if (in->n2)
|
||||
out->result = div(in->n1, in->n2).quot;
|
||||
else
|
||||
out->result = std::numeric_limits<double>::infinity();
|
||||
}
|
||||
}
|
||||
FB_UDR_END_FUNCTION
|
||||
|
||||
/***
|
||||
create function frac (
|
||||
val double precision
|
||||
) returns double precision
|
||||
external name 'udf_compat!UC_frac'
|
||||
engine udr;
|
||||
***/
|
||||
FB_UDR_BEGIN_FUNCTION(UC_frac)
|
||||
FB_UDR_MESSAGE(InMessage,
|
||||
(FB_DOUBLE, val)
|
||||
);
|
||||
|
||||
FB_UDR_MESSAGE(OutMessage,
|
||||
(FB_DOUBLE, result)
|
||||
);
|
||||
|
||||
FB_UDR_EXECUTE_FUNCTION
|
||||
{
|
||||
if (in->valNull)
|
||||
{
|
||||
out->resultNull = FB_TRUE;
|
||||
out->result = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
out->resultNull = FB_FALSE;
|
||||
out->result = in->val > 0 ? in->val - floor(in->val) :
|
||||
in->val < 0 ? in->val - ceil(in->val) : 0;
|
||||
}
|
||||
}
|
||||
FB_UDR_END_FUNCTION
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
enum day_format {day_short, day_long};
|
||||
const FB_SIZE_T day_len[] = {4, 14};
|
||||
const char* day_fmtstr[] = {"%a", "%A"};
|
||||
|
||||
void decode_timestamp(IUtil* u, const FbTimestamp* from, tm* to, unsigned* fractions)
|
||||
{
|
||||
// decode firebird timestamp format
|
||||
memset(to, 0, sizeof(tm));
|
||||
from->date.decode(u, (unsigned*)&to->tm_year, (unsigned*)&to->tm_mon, (unsigned*)&to->tm_mday);
|
||||
to->tm_year -= 1900;
|
||||
to->tm_mon--;
|
||||
from->time.decode(u, (unsigned*)&to->tm_hour, (unsigned*)&to->tm_min, (unsigned*)&to->tm_sec, fractions);
|
||||
|
||||
// set wday/yday
|
||||
time_t tt = mktime(to);
|
||||
localtime_r(&tt, to);
|
||||
}
|
||||
|
||||
template <typename VC>
|
||||
void get_DOW(IUtil* u, const FbTimestamp* v, VC* rc, const day_format df)
|
||||
{
|
||||
// decode firebird timestamp format
|
||||
tm times;
|
||||
decode_timestamp(u, v, ×, NULL);
|
||||
|
||||
const int dow = times.tm_wday;
|
||||
if (dow >= 0 && dow <= 6)
|
||||
{
|
||||
FB_SIZE_T name_len = day_len[df];
|
||||
const char* name_fmt = day_fmtstr[df];
|
||||
// There should be a better way to do this than to alter the thread's locale.
|
||||
if (!strcmp(setlocale(LC_TIME, NULL), "C"))
|
||||
setlocale(LC_ALL, "");
|
||||
name_len = static_cast<FB_SIZE_T>(strftime(rc->str, name_len, name_fmt, ×));
|
||||
if (name_len)
|
||||
{
|
||||
// There's no clarity in the docs whether '\0' is counted or not; be safe.
|
||||
if (!rc->str[name_len - 1])
|
||||
--name_len;
|
||||
rc->length = name_len;
|
||||
return;
|
||||
}
|
||||
}
|
||||
rc->length = df == day_long ? 5 : 3;
|
||||
memcpy(rc->str, "ERROR", rc->length);
|
||||
}
|
||||
|
||||
void encode_timestamp(IUtil* u, const tm* from, const unsigned fractions, FbTimestamp* to)
|
||||
{
|
||||
tm times = *from;
|
||||
|
||||
// decode firebird timestamp format
|
||||
times.tm_year += 1900;
|
||||
times.tm_mon++;
|
||||
|
||||
to->date.encode(u, times.tm_year, times.tm_mon, times.tm_mday);
|
||||
to->time.encode(u, times.tm_hour, times.tm_min, times.tm_sec, fractions);
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
/***
|
||||
create function dow (
|
||||
val timestamp
|
||||
) returns varchar(14) collate none
|
||||
external name 'udf_compat!UC_dow'
|
||||
engine udr;
|
||||
***/
|
||||
FB_UDR_BEGIN_FUNCTION(UC_dow)
|
||||
FB_UDR_MESSAGE(InMessage,
|
||||
(FB_TIMESTAMP, val)
|
||||
);
|
||||
|
||||
FB_UDR_MESSAGE(OutMessage,
|
||||
(FB_VARCHAR(14), result)
|
||||
);
|
||||
|
||||
FB_UDR_EXECUTE_FUNCTION
|
||||
{
|
||||
out->resultNull = in->valNull;
|
||||
if (!out->resultNull)
|
||||
get_DOW(master->getUtilInterface(), &in->val, &out->result, day_long);
|
||||
}
|
||||
FB_UDR_END_FUNCTION
|
||||
|
||||
/***
|
||||
create function sdow (
|
||||
val timestamp
|
||||
) returns varchar(4) collate none
|
||||
external name 'udf_compat!UC_sdow'
|
||||
engine udr;
|
||||
***/
|
||||
FB_UDR_BEGIN_FUNCTION(UC_sdow)
|
||||
FB_UDR_MESSAGE(InMessage,
|
||||
(FB_TIMESTAMP, val)
|
||||
);
|
||||
|
||||
FB_UDR_MESSAGE(OutMessage,
|
||||
(FB_VARCHAR(4), result)
|
||||
);
|
||||
|
||||
FB_UDR_EXECUTE_FUNCTION
|
||||
{
|
||||
out->resultNull = in->valNull;
|
||||
if (!out->resultNull)
|
||||
get_DOW(master->getUtilInterface(), &in->val, &out->result, day_short);
|
||||
}
|
||||
FB_UDR_END_FUNCTION
|
||||
|
||||
/***
|
||||
create function getExactTimestampUTC
|
||||
returns timestamp
|
||||
external name 'udf_compat!UC_getExactTimestampUTC'
|
||||
engine udr;
|
||||
***/
|
||||
FB_UDR_BEGIN_FUNCTION(UC_getExactTimestampUTC)
|
||||
FB_UDR_MESSAGE(OutMessage,
|
||||
(FB_TIMESTAMP, result)
|
||||
);
|
||||
|
||||
FB_UDR_EXECUTE_FUNCTION
|
||||
{
|
||||
#if defined(HAVE_GETTIMEOFDAY)
|
||||
timeval tv;
|
||||
GETTIMEOFDAY(&tv);
|
||||
const time_t seconds = tv.tv_sec;
|
||||
|
||||
tm timex;
|
||||
#if defined(HAVE_GMTIME_R)
|
||||
tm* times = gmtime_r(&seconds, &timex);
|
||||
#else
|
||||
timeMutex.enter();
|
||||
tm* times = gmtime(&seconds);
|
||||
if (times)
|
||||
{
|
||||
// Copy to local variable before we exit the mutex.
|
||||
timex = *times;
|
||||
times = &timex;
|
||||
}
|
||||
timeMutex.leave();
|
||||
#endif // gmtime_r
|
||||
|
||||
if (times)
|
||||
{
|
||||
encode_timestamp(master->getUtilInterface(), times, tv.tv_usec / 100, &out->result);
|
||||
out->resultNull = false;
|
||||
}
|
||||
|
||||
#else // gettimeofday
|
||||
|
||||
_timeb timebuffer;
|
||||
_ftime(&timebuffer);
|
||||
// gmtime uses thread local storage in NT, no need to lock threads.
|
||||
// Of course, this facility is only available in multithreaded builds.
|
||||
tm* times = gmtime(&timebuffer.time);
|
||||
|
||||
if (times)
|
||||
{
|
||||
encode_timestamp(master->getUtilInterface(), times, timebuffer.millitm * 10, &out->result);
|
||||
out->resultNull = false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
else
|
||||
{
|
||||
out->resultNull = true;
|
||||
out->result.date.value = 0;
|
||||
out->result.time.value = 0;
|
||||
}
|
||||
}
|
||||
FB_UDR_END_FUNCTION
|
||||
|
||||
/***
|
||||
create function isLeapYear (
|
||||
val timestamp
|
||||
) returns boolean
|
||||
external name 'udf_compat!UC_isLeapYear'
|
||||
engine udr;
|
||||
***/
|
||||
FB_UDR_BEGIN_FUNCTION(UC_isLeapYear)
|
||||
FB_UDR_MESSAGE(InMessage,
|
||||
(FB_TIMESTAMP, val)
|
||||
);
|
||||
|
||||
FB_UDR_MESSAGE(OutMessage,
|
||||
(FB_BOOLEAN, result)
|
||||
);
|
||||
|
||||
FB_UDR_EXECUTE_FUNCTION
|
||||
{
|
||||
if (in->valNull)
|
||||
{
|
||||
out->result = FB_FALSE;
|
||||
out->resultNull = true;
|
||||
return;
|
||||
}
|
||||
const int ly = in->val.date.getYear(master->getUtilInterface());
|
||||
out->result = ((ly % 4 == 0 && ly % 100 != 0) || ly % 400 == 0) ? FB_TRUE : FB_FALSE;
|
||||
out->resultNull = false;
|
||||
}
|
||||
FB_UDR_END_FUNCTION
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
// This should be used in only one of the UDR library files.
|
||||
// Build must export firebird_udr_plugin function.
|
||||
FB_UDR_IMPLEMENT_ENTRY_POINT
|
43
src/extlib/UdfBackwardCompatibility.sql
Normal file
43
src/extlib/UdfBackwardCompatibility.sql
Normal file
@ -0,0 +1,43 @@
|
||||
-- Create functions in current DB
|
||||
create function div (
|
||||
n1 integer,
|
||||
n2 integer
|
||||
) returns double precision
|
||||
external name 'udf_compat!UC_div'
|
||||
engine udr;
|
||||
|
||||
create function frac (
|
||||
val double precision
|
||||
) returns double precision
|
||||
external name 'udf_compat!UC_frac'
|
||||
engine udr;
|
||||
|
||||
create function dow (
|
||||
val timestamp
|
||||
) returns varchar(14) collate none
|
||||
external name 'udf_compat!UC_dow'
|
||||
engine udr;
|
||||
|
||||
create function sdow (
|
||||
val timestamp
|
||||
) returns varchar(4) collate none
|
||||
external name 'udf_compat!UC_sdow'
|
||||
engine udr;
|
||||
|
||||
create function getExactTimestampUTC
|
||||
returns timestamp
|
||||
external name 'udf_compat!UC_getExactTimestampUTC'
|
||||
engine udr;
|
||||
|
||||
create function isLeapYear (
|
||||
val timestamp
|
||||
) returns boolean
|
||||
external name 'udf_compat!UC_isLeapYear'
|
||||
engine udr;
|
||||
|
||||
-- Run minimum test
|
||||
select 25, 3, div(25, 3) from rdb$database;
|
||||
select pi(), frac(pi()) from rdb$database;
|
||||
select current_date, dow(current_date), sdow(current_date) from rdb$database;
|
||||
select current_timestamp, getExactTimestampUTC() from rdb$database;
|
||||
select current_date, isLeapYear(current_date) from rdb$database;
|
@ -1,37 +0,0 @@
|
||||
========================================================================
|
||||
DYNAMIC LINK LIBRARY : fbudf
|
||||
========================================================================
|
||||
|
||||
|
||||
AppWizard has created this fbudf DLL for you.
|
||||
|
||||
This file contains a summary of what you will find in each of the files that
|
||||
make up your fbudf application.
|
||||
|
||||
fbudf.dsp
|
||||
This file (the project file) contains information at the project level and
|
||||
is used to build a single project or subproject. Other users can share the
|
||||
project (.dsp) file, but they should export the makefiles locally.
|
||||
|
||||
fbudf.cpp
|
||||
This is the main DLL source file.
|
||||
|
||||
fbudf.h
|
||||
This file contains your DLL exports.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
Other standard files:
|
||||
|
||||
StdAfx.h, StdAfx.cpp
|
||||
These files are used to build a precompiled header (PCH) file
|
||||
named fbudf.pch and a precompiled types file named StdAfx.obj.
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
Other notes:
|
||||
|
||||
AppWizard uses "TODO:" to indicate parts of the source code you
|
||||
should add to or customize.
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
@ -1,835 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* The contents of this file are subject to the Initial
|
||||
* Developer's Public License Version 1.0 (the "License");
|
||||
* you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
* http://www.ibphoenix.com/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by Claudio Valderrama C. for IBPhoenix.
|
||||
* The development of the Original Code was sponsored by Craig Leonardi.
|
||||
*
|
||||
* Copyright (c) 2001 IBPhoenix
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 2002.01.07 Claudio Valderrama: change the impolite way truncate and round work,
|
||||
* make null handling more consistent and add dpower(x,y).
|
||||
* Beware the SQL declaration for those functions has changed.
|
||||
* 2002.01.20 Claudio Valderrama: addMonth should work with negative values, too.
|
||||
* 2003.10.26: Made some values const and other minor changes.
|
||||
* 2004.09.29 Claudio Valderrama: fix numeric overflow in addHour reported by
|
||||
* "jssahdra" <joga.singh at inventum.cc>. Since all add<time> functions are
|
||||
* wrappers around addTenthMSec, only two lines needed to be fixed.
|
||||
*/
|
||||
|
||||
|
||||
// fbudf.cpp : Defines the entry point for the DLL application.
|
||||
//
|
||||
|
||||
/*
|
||||
CVC: The MS way of doing things puts the includes in stdafx. I expect
|
||||
that you can continue this trend without problems on other compilers
|
||||
or platforms. Since I conditioned the Windows-related includes, it should
|
||||
be easy to add needed headers to stdafx.h after a makefile is built.
|
||||
*/
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#ifndef FBUDF_EXPORTS
|
||||
#define FBUDF_EXPORTS
|
||||
#endif
|
||||
|
||||
#include "fbudf.h"
|
||||
#include "../common/classes/NoThrowTimeStamp.h"
|
||||
|
||||
#if defined(HAVE_GETTIMEOFDAY) && (!(defined (HAVE_LOCALTIME_R) && defined (HAVE_GMTIME_R)))
|
||||
#define NEED_TIME_MUTEX
|
||||
#include "../common/classes/locks.h"
|
||||
#endif
|
||||
|
||||
|
||||
//Original code for this library was written by Claudio Valderrama
|
||||
// on July 2001 for IBPhoenix.
|
||||
|
||||
// Define this symbol if you want truncate and round to be symmetric wr to zero.
|
||||
//#define SYMMETRIC_MATH
|
||||
|
||||
#if defined (_WIN32)
|
||||
/*
|
||||
BOOL APIENTRY DllMain( HANDLE ,//hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID //lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
|
||||
// To do: go from C++ native types to abstract FB types.
|
||||
|
||||
|
||||
#ifdef DEV_BUILD
|
||||
// This function shouldn't be defined in production.
|
||||
FBUDF_API paramdsc* testreflect(paramdsc* rc)
|
||||
{
|
||||
rc->dsc_address = 0;
|
||||
rc->dsc_flags = 1 | 4; //DSC_null | DSC_nullable;
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
namespace internal
|
||||
{
|
||||
typedef ISC_USHORT fb_len;
|
||||
|
||||
const long seconds_in_day = 86400;
|
||||
const long tenthmsec_in_day = seconds_in_day * ISC_TIME_SECONDS_PRECISION;
|
||||
const int varchar_indicator_size = sizeof(ISC_USHORT);
|
||||
const int max_varchar_size = 65535 - varchar_indicator_size; // in theory
|
||||
|
||||
|
||||
// This definition comes from jrd\val.h and is used in helper
|
||||
// functions {get/set}_varchar_len defined below.
|
||||
struct vvary
|
||||
{
|
||||
fb_len vary_length;
|
||||
ISC_UCHAR vary_string[max_varchar_size];
|
||||
};
|
||||
|
||||
/*
|
||||
inline fb_len get_varchar_len(const char* vchar)
|
||||
{
|
||||
return reinterpret_cast<const vvary*>(vchar)->vary_length;
|
||||
}
|
||||
*/
|
||||
|
||||
inline fb_len get_varchar_len(const ISC_UCHAR* vchar)
|
||||
{
|
||||
return reinterpret_cast<const vvary*>(vchar)->vary_length;
|
||||
}
|
||||
|
||||
inline void set_varchar_len(char* vchar, const fb_len len)
|
||||
{
|
||||
reinterpret_cast<vvary*>(vchar)->vary_length = len;
|
||||
}
|
||||
|
||||
inline void set_varchar_len(ISC_UCHAR* vchar, const fb_len len)
|
||||
{
|
||||
reinterpret_cast<vvary*>(vchar)->vary_length = len;
|
||||
}
|
||||
|
||||
bool isnull(const paramdsc* v)
|
||||
{
|
||||
return !v || !v->dsc_address || (v->dsc_flags & DSC_null);
|
||||
}
|
||||
|
||||
paramdsc* setnull(paramdsc* v)
|
||||
{
|
||||
if (v)
|
||||
v->dsc_flags |= DSC_null;
|
||||
return v;
|
||||
}
|
||||
|
||||
int get_int_type(const paramdsc* v, ISC_INT64& rc)
|
||||
{
|
||||
int s = -1;
|
||||
switch (v->dsc_dtype)
|
||||
{
|
||||
case dtype_short:
|
||||
rc = *reinterpret_cast<ISC_SHORT*>(v->dsc_address);
|
||||
s = sizeof(ISC_SHORT);
|
||||
break;
|
||||
case dtype_long:
|
||||
rc = *reinterpret_cast<ISC_LONG*>(v->dsc_address);
|
||||
s = sizeof(ISC_LONG);
|
||||
break;
|
||||
case dtype_int64:
|
||||
rc = *reinterpret_cast<ISC_INT64*>(v->dsc_address);
|
||||
s = sizeof(ISC_INT64);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void set_int_type(paramdsc* v, const ISC_INT64 iv)
|
||||
{
|
||||
switch (v->dsc_dtype)
|
||||
{
|
||||
case dtype_short:
|
||||
*reinterpret_cast<ISC_SHORT*>(v->dsc_address) = static_cast<ISC_SHORT>(iv);
|
||||
break;
|
||||
case dtype_long:
|
||||
*reinterpret_cast<ISC_LONG*>(v->dsc_address) = static_cast<ISC_LONG>(iv);
|
||||
break;
|
||||
case dtype_int64:
|
||||
*reinterpret_cast<ISC_INT64*>(v->dsc_address) = iv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int get_double_type(const paramdsc* v, double& rc)
|
||||
{
|
||||
int s = -1;
|
||||
switch (v->dsc_dtype)
|
||||
{
|
||||
case dtype_real:
|
||||
rc = static_cast<double>(*reinterpret_cast<float*>(v->dsc_address));
|
||||
s = sizeof(float);
|
||||
break;
|
||||
case dtype_double:
|
||||
rc = *reinterpret_cast<double*>(v->dsc_address);
|
||||
s = sizeof(double);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void set_double_type(paramdsc* v, const double iv)
|
||||
{
|
||||
switch (v->dsc_dtype)
|
||||
{
|
||||
case dtype_real:
|
||||
*reinterpret_cast<float*>(v->dsc_address) = static_cast<float>(iv);
|
||||
break;
|
||||
case dtype_double:
|
||||
*reinterpret_cast<double*>(v->dsc_address) = iv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int get_any_string_type(const paramdsc* v, ISC_UCHAR*& text)
|
||||
{
|
||||
int len = v->dsc_length;
|
||||
switch (v->dsc_dtype)
|
||||
{
|
||||
case dtype_text:
|
||||
text = v->dsc_address;
|
||||
break;
|
||||
case dtype_cstring:
|
||||
text = v->dsc_address;
|
||||
if (len && text)
|
||||
{
|
||||
const ISC_UCHAR* p = text; //strlen(v->dsc_address);
|
||||
while (*p)
|
||||
++p; // couldn't use strlen!
|
||||
if (p - text < len)
|
||||
len = p - text;
|
||||
}
|
||||
break;
|
||||
case dtype_varying:
|
||||
len -= varchar_indicator_size;
|
||||
text = reinterpret_cast<vvary*>(v->dsc_address)->vary_string;
|
||||
{
|
||||
const int x = get_varchar_len(v->dsc_address);
|
||||
if (x < len)
|
||||
len = x;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
len = -1;
|
||||
break;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
void set_any_string_type(paramdsc* v, const int len0, ISC_UCHAR* text = 0)
|
||||
{
|
||||
fb_len len = static_cast<fb_len>(len0);
|
||||
switch (v->dsc_dtype)
|
||||
{
|
||||
case dtype_text:
|
||||
v->dsc_length = len;
|
||||
if (text)
|
||||
memcpy(v->dsc_address, text, len);
|
||||
else
|
||||
memset(v->dsc_address, ' ', len);
|
||||
break;
|
||||
case dtype_cstring:
|
||||
v->dsc_length = len;
|
||||
if (text)
|
||||
memcpy(v->dsc_address, text, len);
|
||||
else
|
||||
v->dsc_length = len = 0;
|
||||
v->dsc_address[len] = 0;
|
||||
break;
|
||||
case dtype_varying:
|
||||
if (!text)
|
||||
len = 0;
|
||||
else if (len > max_varchar_size)
|
||||
len = max_varchar_size;
|
||||
v->dsc_length = len + static_cast<fb_len>(varchar_indicator_size);
|
||||
set_varchar_len(v->dsc_address, len);
|
||||
if (text)
|
||||
memcpy(v->dsc_address + varchar_indicator_size, text, len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int get_scaled_double(const paramdsc* v, double& rc)
|
||||
{
|
||||
ISC_INT64 iv;
|
||||
int rct = get_int_type(v, iv);
|
||||
if (rct < 0)
|
||||
rct = get_double_type(v, rc);
|
||||
else
|
||||
{
|
||||
rc = static_cast<double>(iv);
|
||||
int scale = v->dsc_scale;
|
||||
for (; scale < 0; ++scale)
|
||||
rc /= 10;
|
||||
for (; scale > 0; --scale)
|
||||
rc *= 10;
|
||||
}
|
||||
return rct;
|
||||
}
|
||||
} // namespace internal
|
||||
|
||||
|
||||
// BEGIN DEPRECATED FUNCTIONS.
|
||||
FBUDF_API paramdsc* idNvl(paramdsc* v, paramdsc* v2)
|
||||
{
|
||||
if (!internal::isnull(v))
|
||||
return v;
|
||||
return v2;
|
||||
}
|
||||
|
||||
FBUDF_API void sNvl(const paramdsc* v, const paramdsc* v2, paramdsc* rc)
|
||||
{
|
||||
if (!internal::isnull(v))
|
||||
{
|
||||
ISC_UCHAR* sv = 0;
|
||||
const int len = internal::get_any_string_type(v, sv);
|
||||
if (len < 0)
|
||||
internal::setnull(rc);
|
||||
else
|
||||
internal::set_any_string_type(rc, len, sv);
|
||||
return;
|
||||
}
|
||||
if (!internal::isnull(v2))
|
||||
{
|
||||
ISC_UCHAR* sv2 = 0;
|
||||
const int len = internal::get_any_string_type(v2, sv2);
|
||||
if (len < 0)
|
||||
internal::setnull(rc);
|
||||
else
|
||||
internal::set_any_string_type(rc, len, sv2);
|
||||
return;
|
||||
}
|
||||
internal::setnull(rc);
|
||||
}
|
||||
|
||||
|
||||
FBUDF_API paramdsc* iNullIf(paramdsc* v, paramdsc* v2)
|
||||
{
|
||||
if (internal::isnull(v) || internal::isnull(v2))
|
||||
return 0;
|
||||
ISC_INT64 iv, iv2;
|
||||
const int rc = internal::get_int_type(v, iv);
|
||||
const int rc2 = internal::get_int_type(v2, iv2);
|
||||
if (rc < 0 || rc2 < 0)
|
||||
return v;
|
||||
if (iv == iv2 && v->dsc_scale == v2->dsc_scale)
|
||||
return 0;
|
||||
return v;
|
||||
}
|
||||
|
||||
FBUDF_API paramdsc* dNullIf(paramdsc* v, paramdsc* v2)
|
||||
{
|
||||
if (internal::isnull(v) || internal::isnull(v2))
|
||||
return 0;
|
||||
double iv, iv2;
|
||||
const int rc = internal::get_double_type(v, iv);
|
||||
const int rc2 = internal::get_double_type(v2, iv2);
|
||||
if (rc < 0 || rc2 < 0)
|
||||
return v;
|
||||
if (iv == iv2) // && v->dsc_scale == v2->dsc_scale) double w/o scale
|
||||
return 0;
|
||||
return v;
|
||||
}
|
||||
|
||||
FBUDF_API void sNullIf(const paramdsc* v, const paramdsc* v2, paramdsc* rc)
|
||||
{
|
||||
if (internal::isnull(v) || internal::isnull(v2))
|
||||
{
|
||||
internal::setnull(rc);
|
||||
return;
|
||||
}
|
||||
ISC_UCHAR* sv;
|
||||
const int len = internal::get_any_string_type(v, sv);
|
||||
ISC_UCHAR* sv2;
|
||||
const int len2 = internal::get_any_string_type(v2, sv2);
|
||||
if (len < 0 || len2 < 0) // good luck with the result, we can't do more.
|
||||
return;
|
||||
if (len == len2 && (!len || !memcmp(sv, sv2, len)) &&
|
||||
(v->dsc_sub_type == v2->dsc_sub_type || // ttype
|
||||
!v->dsc_sub_type || !v2->dsc_sub_type)) // tyype
|
||||
{
|
||||
internal::setnull(rc);
|
||||
return;
|
||||
}
|
||||
internal::set_any_string_type(rc, len, sv);
|
||||
return;
|
||||
}
|
||||
// END DEPRECATED FUNCTIONS.
|
||||
|
||||
namespace internal
|
||||
{
|
||||
void decode_timestamp(const GDS_TIMESTAMP* date, tm* times_arg) throw()
|
||||
{
|
||||
Firebird::NoThrowTimeStamp::decode_timestamp(*date, times_arg);
|
||||
}
|
||||
|
||||
void encode_timestamp(const tm* times_arg, GDS_TIMESTAMP* date) throw()
|
||||
{
|
||||
*date = Firebird::NoThrowTimeStamp::encode_timestamp(times_arg);
|
||||
}
|
||||
|
||||
enum day_format {day_short, day_long};
|
||||
const fb_len day_len[] = {4, 14};
|
||||
const char* day_fmtstr[] = {"%a", "%A"};
|
||||
|
||||
void get_DOW(const ISC_TIMESTAMP* v, paramvary* rc, const day_format df)
|
||||
{
|
||||
tm times;
|
||||
decode_timestamp(v, ×);
|
||||
const int dow = times.tm_wday;
|
||||
if (dow >= 0 && dow <= 6)
|
||||
{
|
||||
fb_len name_len = day_len[df];
|
||||
const char* name_fmt = day_fmtstr[df];
|
||||
// There should be a better way to do this than to alter the thread's locale.
|
||||
if (!strcmp(setlocale(LC_TIME, NULL), "C"))
|
||||
setlocale(LC_ALL, "");
|
||||
char* const target = reinterpret_cast<char*>(rc->vary_string);
|
||||
name_len = static_cast<fb_len>(strftime(target, name_len, name_fmt, ×));
|
||||
if (name_len)
|
||||
{
|
||||
// There's no clarity in the docs whether '\0' is counted or not; be safe.
|
||||
if (!target[name_len - 1])
|
||||
--name_len;
|
||||
rc->vary_length = name_len;
|
||||
return;
|
||||
}
|
||||
}
|
||||
rc->vary_length = 5;
|
||||
memcpy(rc->vary_string, "ERROR", 5);
|
||||
}
|
||||
} // namespace internal
|
||||
|
||||
FBUDF_API void DOW(const ISC_TIMESTAMP* v, paramvary* rc)
|
||||
{
|
||||
internal::get_DOW(v, rc, internal::day_long);
|
||||
}
|
||||
|
||||
FBUDF_API void SDOW(const ISC_TIMESTAMP* v, paramvary* rc)
|
||||
{
|
||||
internal::get_DOW(v, rc, internal::day_short);
|
||||
}
|
||||
|
||||
FBUDF_API void right(const paramdsc* v, const ISC_SHORT& rl, paramdsc* rc)
|
||||
{
|
||||
if (internal::isnull(v))
|
||||
{
|
||||
internal::setnull(rc);
|
||||
return;
|
||||
}
|
||||
ISC_UCHAR* text = 0;
|
||||
int len = internal::get_any_string_type(v, text);
|
||||
const int diff = len - rl;
|
||||
if (rl < len)
|
||||
len = rl;
|
||||
if (len < 0)
|
||||
{
|
||||
internal::setnull(rc);
|
||||
return;
|
||||
}
|
||||
if (diff > 0)
|
||||
text += diff;
|
||||
internal::set_any_string_type(rc, len, text);
|
||||
return;
|
||||
}
|
||||
|
||||
FBUDF_API ISC_TIMESTAMP* addDay(ISC_TIMESTAMP* v, const ISC_LONG& ndays)
|
||||
{
|
||||
v->timestamp_date += ndays;
|
||||
return v;
|
||||
}
|
||||
|
||||
FBUDF_API void addDay2(const ISC_TIMESTAMP* v0, const ISC_LONG& ndays, ISC_TIMESTAMP* v)
|
||||
{
|
||||
*v = *v0;
|
||||
v->timestamp_date += ndays;
|
||||
}
|
||||
|
||||
FBUDF_API ISC_TIMESTAMP* addWeek(ISC_TIMESTAMP* v, const ISC_LONG& nweeks)
|
||||
{
|
||||
v->timestamp_date += nweeks * 7;
|
||||
return v;
|
||||
}
|
||||
|
||||
FBUDF_API ISC_TIMESTAMP* addMonth(ISC_TIMESTAMP* v, const ISC_LONG& nmonths)
|
||||
{
|
||||
tm times;
|
||||
internal::decode_timestamp(v, ×);
|
||||
const int y = nmonths / 12, m = nmonths % 12;
|
||||
times.tm_year += y;
|
||||
if ((times.tm_mon += m) > 11)
|
||||
{
|
||||
++times.tm_year;
|
||||
times.tm_mon -= 12;
|
||||
}
|
||||
else if (times.tm_mon < 0)
|
||||
{
|
||||
--times.tm_year;
|
||||
times.tm_mon += 12;
|
||||
}
|
||||
const int ly = times.tm_year + 1900;
|
||||
const bool leap = (ly % 4 == 0 && ly % 100 != 0) || ly % 400 == 0;
|
||||
const int md[] = {31, (leap ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||
if (times.tm_mday > md[times.tm_mon])
|
||||
times.tm_mday = md[times.tm_mon];
|
||||
internal::encode_timestamp(×, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
FBUDF_API ISC_TIMESTAMP* addYear(ISC_TIMESTAMP* v, const ISC_LONG& nyears)
|
||||
{
|
||||
tm times;
|
||||
internal::decode_timestamp(v, ×);
|
||||
times.tm_year += nyears;
|
||||
internal::encode_timestamp(×, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
namespace internal
|
||||
{
|
||||
ISC_TIMESTAMP* addTenthMSec(ISC_TIMESTAMP* v, SINT64 tenthmilliseconds, int multiplier)
|
||||
{
|
||||
const SINT64 full = tenthmilliseconds * multiplier;
|
||||
const long days = full / tenthmsec_in_day, secs = full % tenthmsec_in_day;
|
||||
v->timestamp_date += days;
|
||||
// Time portion is unsigned, so we avoid unsigned rolling over negative values
|
||||
// that only produce a new unsigned number with the wrong result.
|
||||
if (secs < 0 && static_cast<ISC_ULONG>(-secs) > v->timestamp_time)
|
||||
{
|
||||
--v->timestamp_date;
|
||||
v->timestamp_time += tenthmsec_in_day + secs;
|
||||
}
|
||||
else if ((v->timestamp_time += secs) >= static_cast<ISC_ULONG>(tenthmsec_in_day))
|
||||
{
|
||||
++v->timestamp_date;
|
||||
v->timestamp_time -= tenthmsec_in_day;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
} // namespace internal
|
||||
|
||||
FBUDF_API ISC_TIMESTAMP* addMilliSecond(ISC_TIMESTAMP* v, const ISC_LONG& nmseconds)
|
||||
{
|
||||
return internal::addTenthMSec(v, nmseconds, ISC_TIME_SECONDS_PRECISION / 1000);
|
||||
}
|
||||
|
||||
FBUDF_API ISC_TIMESTAMP* addSecond(ISC_TIMESTAMP* v, const ISC_LONG& nseconds)
|
||||
{
|
||||
return internal::addTenthMSec(v, nseconds, ISC_TIME_SECONDS_PRECISION);
|
||||
}
|
||||
|
||||
FBUDF_API ISC_TIMESTAMP* addMinute(ISC_TIMESTAMP* v, const ISC_LONG& nminutes)
|
||||
{
|
||||
return internal::addTenthMSec(v, nminutes, 60 * ISC_TIME_SECONDS_PRECISION);
|
||||
}
|
||||
|
||||
FBUDF_API ISC_TIMESTAMP* addHour(ISC_TIMESTAMP* v, const ISC_LONG& nhours)
|
||||
{
|
||||
return internal::addTenthMSec(v, nhours, 3600 * ISC_TIME_SECONDS_PRECISION);
|
||||
}
|
||||
|
||||
#ifdef NEED_TIME_MUTEX
|
||||
Firebird::Mutex timeMutex;
|
||||
#endif
|
||||
|
||||
FBUDF_API void getExactTimestamp(ISC_TIMESTAMP* rc)
|
||||
{
|
||||
#if defined(HAVE_GETTIMEOFDAY)
|
||||
timeval tv;
|
||||
GETTIMEOFDAY(&tv);
|
||||
const time_t seconds = tv.tv_sec;
|
||||
|
||||
tm timex;
|
||||
#if defined(HAVE_LOCALTIME_R)
|
||||
tm* times = localtime_r(&seconds, &timex);
|
||||
#else
|
||||
timeMutex.enter();
|
||||
tm* times = localtime(&seconds);
|
||||
if (times)
|
||||
{
|
||||
// Copy to local variable before we exit the mutex.
|
||||
timex = *times;
|
||||
times = &timex;
|
||||
}
|
||||
timeMutex.leave();
|
||||
#endif // localtime_r
|
||||
|
||||
if (times)
|
||||
{
|
||||
internal::encode_timestamp(times, rc);
|
||||
rc->timestamp_time += tv.tv_usec / 100;
|
||||
}
|
||||
else
|
||||
rc->timestamp_date = rc->timestamp_time = 0;
|
||||
|
||||
#else // gettimeofday
|
||||
_timeb timebuffer;
|
||||
_ftime(&timebuffer);
|
||||
// localtime uses thread local storage in NT, no need to lock threads.
|
||||
// Of course, this facility is only available in multithreaded builds.
|
||||
tm* times = localtime(&timebuffer.time);
|
||||
if (times)
|
||||
{
|
||||
internal::encode_timestamp(times, rc);
|
||||
rc->timestamp_time += timebuffer.millitm * 10;
|
||||
}
|
||||
else
|
||||
rc->timestamp_date = rc->timestamp_time = 0;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
FBUDF_API void getExactTimestampUTC(ISC_TIMESTAMP* rc)
|
||||
{
|
||||
#if defined(HAVE_GETTIMEOFDAY)
|
||||
timeval tv;
|
||||
GETTIMEOFDAY(&tv);
|
||||
const time_t seconds = tv.tv_sec;
|
||||
|
||||
tm timex;
|
||||
#if defined(HAVE_GMTIME_R)
|
||||
tm* times = gmtime_r(&seconds, &timex);
|
||||
#else
|
||||
timeMutex.enter();
|
||||
tm* times = gmtime(&seconds);
|
||||
if (times)
|
||||
{
|
||||
// Copy to local variable before we exit the mutex.
|
||||
timex = *times;
|
||||
times = &timex;
|
||||
}
|
||||
timeMutex.leave();
|
||||
#endif // gmtime_r
|
||||
|
||||
if (times)
|
||||
{
|
||||
internal::encode_timestamp(times, rc);
|
||||
rc->timestamp_time += tv.tv_usec / 100;
|
||||
}
|
||||
else
|
||||
rc->timestamp_date = rc->timestamp_time = 0;
|
||||
|
||||
#else // gettimeofday
|
||||
_timeb timebuffer;
|
||||
_ftime(&timebuffer);
|
||||
// gmtime uses thread local storage in NT, no need to lock threads.
|
||||
// Of course, this facility is only available in multithreaded builds.
|
||||
tm* times = gmtime(&timebuffer.time);
|
||||
if (times)
|
||||
{
|
||||
internal::encode_timestamp(times, rc);
|
||||
rc->timestamp_time += timebuffer.millitm * 10;
|
||||
}
|
||||
else
|
||||
rc->timestamp_date = rc->timestamp_time = 0;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
FBUDF_API ISC_LONG isLeapYear(const ISC_TIMESTAMP* v)
|
||||
{
|
||||
tm times;
|
||||
internal::decode_timestamp(v, ×);
|
||||
const int ly = times.tm_year + 1900;
|
||||
return (ly % 4 == 0 && ly % 100 != 0) || ly % 400 == 0;
|
||||
}
|
||||
|
||||
FBUDF_API void fbtruncate(const paramdsc* v, paramdsc* rc)
|
||||
{
|
||||
if (internal::isnull(v))
|
||||
{
|
||||
internal::setnull(rc);
|
||||
return;
|
||||
}
|
||||
ISC_INT64 iv;
|
||||
const int rct = internal::get_int_type(v, iv);
|
||||
if (rct < 0 || v->dsc_scale > 0)
|
||||
{
|
||||
internal::setnull(rc);
|
||||
return;
|
||||
}
|
||||
if (!v->dsc_scale /*|| !v->dsc_sub_type*/) //second test won't work with ODS9
|
||||
{
|
||||
internal::set_int_type(rc, iv);
|
||||
rc->dsc_scale = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// truncate(0.9) => 0
|
||||
// truncate(-0.9) => -1
|
||||
// truncate(-0.9) => 0 ### SYMMETRIC_MATH defined.
|
||||
int scale = v->dsc_scale;
|
||||
#if defined(SYMMETRIC_MATH)
|
||||
while (scale++ < 0)
|
||||
iv /= 10;
|
||||
#else
|
||||
const bool isNeg = iv < 0;
|
||||
bool gt = false;
|
||||
while (scale++ < 0)
|
||||
{
|
||||
if (iv % 10)
|
||||
gt = true;
|
||||
iv /= 10;
|
||||
}
|
||||
if (gt)
|
||||
{
|
||||
if (isNeg)
|
||||
--iv;
|
||||
}
|
||||
#endif
|
||||
internal::set_int_type(rc, iv);
|
||||
rc->dsc_scale = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
FBUDF_API void fbround(const paramdsc* v, paramdsc* rc)
|
||||
{
|
||||
if (internal::isnull(v))
|
||||
{
|
||||
internal::setnull(rc);
|
||||
return;
|
||||
}
|
||||
ISC_INT64 iv;
|
||||
const int rct = internal::get_int_type(v, iv);
|
||||
if (rct < 0 || v->dsc_scale > 0)
|
||||
{
|
||||
internal::setnull(rc);
|
||||
return;
|
||||
}
|
||||
if (!v->dsc_scale /*|| !v->dsc_sub_type*/) //second test won't work with ODS9
|
||||
{
|
||||
internal::set_int_type(rc, iv);
|
||||
rc->dsc_scale = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// round(0.3) => 0 ### round(0.5) => 1
|
||||
// round(-0.3) => 0 ### round(-0.5) => 0
|
||||
// round(-0.3) => 0 ### round(-0.5) => -1 ### SYMMETRIC_MATH defined.
|
||||
const bool isNeg = iv < 0;
|
||||
int scale = v->dsc_scale;
|
||||
bool gt = false, check_more = false;
|
||||
while (scale++ < 0)
|
||||
{
|
||||
if (!scale)
|
||||
{
|
||||
int dig;
|
||||
if (iv == MIN_SINT64)
|
||||
dig = -(iv + 10) % 10;
|
||||
else
|
||||
dig = static_cast<int>(iv >= 0 ? iv % 10 : -iv % 10);
|
||||
|
||||
#if defined(SYMMETRIC_MATH)
|
||||
if (dig >= 5)
|
||||
gt = true;
|
||||
#else
|
||||
if (!isNeg)
|
||||
{
|
||||
if (dig >= 5)
|
||||
gt = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dig > 5 || (dig == 5 && check_more))
|
||||
gt = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (isNeg && !check_more)
|
||||
{
|
||||
if (iv % 10 != 0)
|
||||
check_more = true;
|
||||
}
|
||||
iv /= 10;
|
||||
}
|
||||
if (gt)
|
||||
{
|
||||
if (isNeg)
|
||||
--iv;
|
||||
else
|
||||
++iv;
|
||||
}
|
||||
internal::set_int_type(rc, iv);
|
||||
rc->dsc_scale = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
FBUDF_API void power(const paramdsc* v, const paramdsc* v2, paramdsc* rc)
|
||||
{
|
||||
if (internal::isnull(v) || internal::isnull(v2))
|
||||
{
|
||||
internal::setnull(rc);
|
||||
return;
|
||||
}
|
||||
double d, d2;
|
||||
const int rct = internal::get_scaled_double(v, d);
|
||||
const int rct2 = internal::get_scaled_double(v2, d2);
|
||||
|
||||
// If we cause a div by zero, SS shuts down in response.
|
||||
// The doc I read says 0^0 will produce 1, so it's not tested below.
|
||||
if (rct < 0 || rct2 < 0 || (!d && d2 < 0))
|
||||
{
|
||||
internal::setnull(rc);
|
||||
return;
|
||||
}
|
||||
|
||||
internal::set_double_type(rc, pow(d, d2));
|
||||
rc->dsc_scale = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
FBUDF_API void string2blob(const paramdsc* v, blobcallback* outblob)
|
||||
{
|
||||
if (internal::isnull(v))
|
||||
{
|
||||
outblob->blob_handle = 0; // hint for the engine, null blob.
|
||||
return;
|
||||
}
|
||||
ISC_UCHAR* text = 0;
|
||||
const int len = internal::get_any_string_type(v, text);
|
||||
if (len < 0 && outblob)
|
||||
outblob->blob_handle = 0; // hint for the engine, null blob.
|
||||
if (!outblob || !outblob->blob_handle)
|
||||
return;
|
||||
outblob->blob_put_segment(outblob->blob_handle, text, len);
|
||||
return;
|
||||
}
|
||||
|
@ -1,94 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* The contents of this file are subject to the Initial
|
||||
* Developer's Public License Version 1.0 (the "License");
|
||||
* you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
* http://www.ibphoenix.com/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by Claudio Valderrama C. for IBPhoenix.
|
||||
* The development of the Original Code was sponsored by Craig Leonardi.
|
||||
*
|
||||
* Copyright (c) 2001 IBPhoenix
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
|
||||
// The following ifdef block is the standard way of creating macros which make exporting
|
||||
// from a DLL simpler. All files within this DLL are compiled with the FBUDF_EXPORTS
|
||||
// symbol defined on the command line. This symbol should not be defined on any project
|
||||
// that uses this DLL. This way any other project whose source files include this file see
|
||||
// FBUDF_API functions as being imported from a DLL, whereas this DLL sees symbols
|
||||
// defined with this macro as being exported.
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
|
||||
#ifdef FBUDF_EXPORTS
|
||||
#define FBUDF_API __declspec(dllexport)
|
||||
#else
|
||||
#define FBUDF_API __declspec(dllimport)
|
||||
#endif
|
||||
#elif defined(DARWIN)
|
||||
#define FBUDF_API API_ROUTINE
|
||||
#else
|
||||
#define FBUDF_API
|
||||
#endif
|
||||
|
||||
//Original code for this library was written by Claudio Valderrama
|
||||
// on July 2001 for IBPhoenix.
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef DEV_BUILD
|
||||
//This function shouldn't be defined in production.
|
||||
FBUDF_API paramdsc* testreflect(paramdsc* rc);
|
||||
#endif
|
||||
|
||||
|
||||
// BEGIN DEPRECATED FUNCTIONS.
|
||||
FBUDF_API paramdsc* idNvl(paramdsc* v, paramdsc* v2);
|
||||
FBUDF_API void sNvl(const paramdsc* v, const paramdsc* v2, paramdsc* rc);
|
||||
|
||||
FBUDF_API paramdsc* iNullIf(paramdsc* v, paramdsc* v2);
|
||||
FBUDF_API paramdsc* dNullIf(paramdsc* v, paramdsc* v2);
|
||||
FBUDF_API void sNullIf(const paramdsc* v, const paramdsc* v2, paramdsc* rc);
|
||||
// END DEPRECATED FUNCTIONS.
|
||||
|
||||
FBUDF_API void DOW(const ISC_TIMESTAMP* v, paramvary* rc);
|
||||
FBUDF_API void SDOW(const ISC_TIMESTAMP* v, paramvary* rc);
|
||||
|
||||
FBUDF_API void right(const paramdsc* v, const ISC_SHORT& rl, paramdsc* rc);
|
||||
|
||||
FBUDF_API ISC_TIMESTAMP* addDay(ISC_TIMESTAMP* v, const ISC_LONG& ndays);
|
||||
FBUDF_API void addDay2(const ISC_TIMESTAMP* v0, const ISC_LONG& ndays, ISC_TIMESTAMP* v);
|
||||
FBUDF_API ISC_TIMESTAMP* addWeek(ISC_TIMESTAMP* v, const ISC_LONG& nweeks);
|
||||
FBUDF_API ISC_TIMESTAMP* addMonth(ISC_TIMESTAMP* v, const ISC_LONG& nmonths);
|
||||
FBUDF_API ISC_TIMESTAMP* addYear(ISC_TIMESTAMP* v, const ISC_LONG& nyears);
|
||||
|
||||
FBUDF_API ISC_TIMESTAMP* addMilliSecond(ISC_TIMESTAMP* v, const ISC_LONG& nmseconds);
|
||||
FBUDF_API ISC_TIMESTAMP* addSecond(ISC_TIMESTAMP* v, const ISC_LONG& nseconds);
|
||||
FBUDF_API ISC_TIMESTAMP* addMinute(ISC_TIMESTAMP* v, const ISC_LONG& nminutes);
|
||||
FBUDF_API ISC_TIMESTAMP* addHour(ISC_TIMESTAMP* v, const ISC_LONG& nhours);
|
||||
|
||||
FBUDF_API void getExactTimestamp(ISC_TIMESTAMP* rc);
|
||||
FBUDF_API void getExactTimestampUTC(ISC_TIMESTAMP* rc);
|
||||
|
||||
FBUDF_API ISC_LONG isLeapYear(const ISC_TIMESTAMP* v);
|
||||
|
||||
FBUDF_API void fbtruncate(const paramdsc* v, paramdsc* rc);
|
||||
FBUDF_API void fbround(const paramdsc* v, paramdsc* rc);
|
||||
FBUDF_API void power(const paramdsc* v, const paramdsc* v2, paramdsc* rc);
|
||||
|
||||
FBUDF_API void string2blob(const paramdsc* v, blobcallback* outblob);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,206 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* The contents of this file are subject to the Initial
|
||||
* Developer's Public License Version 1.0 (the "License");
|
||||
* you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
* http://www.ibphoenix.com/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by Claudio Valderrama C. for IBPhoenix.
|
||||
* The development of the Original Code was sponsored by Craig Leonardi.
|
||||
*
|
||||
* Copyright (c) 2001 IBPhoenix
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
|
||||
/* This file defines the new udfs for Firebird. */
|
||||
|
||||
set sql dialect 3;
|
||||
|
||||
-- The Nvl family is deprecated. Use native COALESCE instead.
|
||||
--FBUDF_API paramdsc* idNvl(paramdsc* v, paramdsc* v2)
|
||||
declare external function invl
|
||||
int by descriptor, int by descriptor
|
||||
returns int by descriptor
|
||||
entry_point 'idNvl' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API paramdsc* idNvl(paramdsc* v, paramdsc* v2)
|
||||
declare external function i64nvl
|
||||
numeric(18,0) by descriptor, numeric(18,0) by descriptor
|
||||
returns numeric(18,0) by descriptor
|
||||
entry_point 'idNvl' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API paramdsc* idNvl(paramdsc* v, paramdsc* v2)
|
||||
declare external function dnvl
|
||||
double precision by descriptor, double precision by descriptor
|
||||
returns double precision by descriptor
|
||||
entry_point 'idNvl' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API paramdsc* sNvl(paramdsc* v, paramdsc* v2, paramdsc* rc)
|
||||
declare external function snvl
|
||||
varchar(100) by descriptor, varchar(100) by descriptor,
|
||||
varchar(100) by descriptor returns parameter 3
|
||||
entry_point 'sNvl' module_name 'fbudf';
|
||||
|
||||
-- The NullIf family is deprecated. Use native NULLIF instead.
|
||||
--FBUDF_API paramdsc* iNullIf(paramdsc* v, paramdsc* v2)
|
||||
declare external function inullif
|
||||
int by descriptor, int by descriptor
|
||||
returns int by descriptor
|
||||
entry_point 'iNullIf' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API paramdsc* dNullIf(paramdsc* v, paramdsc* v2)
|
||||
declare external function dnullif
|
||||
double precision by descriptor, double precision by descriptor
|
||||
returns double precision by descriptor
|
||||
entry_point 'dNullIf' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API paramdsc* iNullIf(paramdsc* v, paramdsc* v2)
|
||||
declare external function i64nullif
|
||||
numeric(18,4) by descriptor, numeric(18,4) by descriptor
|
||||
returns numeric(18,4) by descriptor
|
||||
entry_point 'iNullIf' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API paramdsc* sNullIf(paramdsc* v, paramdsc* v2, paramdsc* rc)
|
||||
declare external function snullif
|
||||
varchar(100) by descriptor, varchar(100) by descriptor,
|
||||
varchar(100) by descriptor returns parameter 3
|
||||
entry_point 'sNullIf' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API char* DOW(ISC_DATE* v, char* rc)
|
||||
declare external function dow
|
||||
timestamp,
|
||||
varchar(15) returns parameter 2
|
||||
entry_point 'DOW' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API char* SDOW(ISC_DATE* v, char* rc)
|
||||
declare external function sdow
|
||||
timestamp,
|
||||
varchar(5) returns parameter 2
|
||||
entry_point 'SDOW' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API paramdsc* right(const paramdsc*, const ISC_SHORT& rl, paramdsc* rc)
|
||||
declare external function sright
|
||||
varchar(100) by descriptor, smallint,
|
||||
varchar(100) by descriptor returns parameter 3
|
||||
entry_point 'right' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API ISC_TIMESTAMP* addDay(ISC_TIMESTAMP* v, const ISC_SLONG& ndays)
|
||||
declare external function addDay
|
||||
timestamp, int
|
||||
returns timestamp
|
||||
entry_point 'addDay' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API void addDay2(const ISC_TIMESTAMP* v0, const ISC_SLONG& ndays, ISC_TIMESTAMP* v)
|
||||
declare external function addDay2
|
||||
timestamp, int, timestamp
|
||||
returns parameter 3
|
||||
entry_point 'addDay2' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API ISC_TIMESTAMP* addWeek(ISC_TIMESTAMP* v, const ISC_SLONG& nweeks)
|
||||
declare external function addWeek
|
||||
timestamp, int
|
||||
returns timestamp
|
||||
entry_point 'addWeek' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API ISC_TIMESTAMP* addMonth(ISC_TIMESTAMP* v, const ISC_SLONG& nmonths)
|
||||
declare external function addMonth
|
||||
timestamp, int
|
||||
returns timestamp
|
||||
entry_point 'addMonth' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API ISC_TIMESTAMP* addYear(ISC_TIMESTAMP* v, const ISC_SLONG& nyears)
|
||||
declare external function addYear
|
||||
timestamp, int
|
||||
returns timestamp
|
||||
entry_point 'addYear' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API ISC_TIMESTAMP* addMilliSecond(ISC_TIMESTAMP* v, const ISC_SLONG& nseconds)
|
||||
declare external function addMilliSecond
|
||||
timestamp, int
|
||||
returns timestamp
|
||||
entry_point 'addMilliSecond' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API ISC_TIMESTAMP* addSecond(ISC_TIMESTAMP* v, const ISC_SLONG& nseconds)
|
||||
declare external function addSecond
|
||||
timestamp, int
|
||||
returns timestamp
|
||||
entry_point 'addSecond' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API ISC_TIMESTAMP* addMinute(ISC_TIMESTAMP* v, const ISC_SLONG& nminutes)
|
||||
declare external function addMinute
|
||||
timestamp, int
|
||||
returns timestamp
|
||||
entry_point 'addMinute' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API ISC_TIMESTAMP* addHour(ISC_TIMESTAMP* v, const ISC_SLONG& nhours)
|
||||
declare external function addHour
|
||||
timestamp, int
|
||||
returns timestamp
|
||||
entry_point 'addHour' module_name 'fbudf';
|
||||
|
||||
--It will work only with Win32 until it's ported to another OS.
|
||||
--FBUDF_API ISC_TIMESTAMP* getExactTimestamp(ISC_TIMESTAMP* rc)
|
||||
declare external function getExactTimestamp
|
||||
timestamp
|
||||
returns parameter 1
|
||||
entry_point 'getExactTimestamp' module_name 'fbudf';
|
||||
|
||||
--It will work only with Win32 until it's ported to another OS.
|
||||
--FBUDF_API void getExactTimestampUTC(ISC_TIMESTAMP* rc);
|
||||
declare external function getExactTimestampUTC
|
||||
timestamp
|
||||
returns parameter 1
|
||||
entry_point 'getExactTimestampUTC' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API int isLeapYear(const ISC_TIMESTAMP* v);
|
||||
declare external function isLeapYear
|
||||
timestamp
|
||||
returns int by value
|
||||
entry_point 'isLeapYear' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API paramdsc* fbtruncate(const paramdsc* v, paramdsc* rc)
|
||||
declare external function Truncate
|
||||
int by descriptor, int by descriptor
|
||||
returns parameter 2
|
||||
entry_point 'fbtruncate' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API paramdsc* fbtruncate(const paramdsc* v, paramdsc* rc)
|
||||
declare external function i64Truncate
|
||||
numeric(18) by descriptor, numeric(18) by descriptor
|
||||
returns parameter 2
|
||||
entry_point 'fbtruncate' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API paramdsc* fbround(const paramdsc* v, paramdsc* rc)
|
||||
declare external function Round
|
||||
int by descriptor, int by descriptor
|
||||
returns parameter 2
|
||||
entry_point 'fbround' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API paramdsc* fbround(const paramdsc* v, paramdsc* rc)
|
||||
declare external function i64Round
|
||||
numeric(18, 4) by descriptor, numeric(18, 4) by descriptor
|
||||
returns parameter 2
|
||||
entry_point 'fbround' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API paramdsc* power(const paramdsc* v, const paramdsc* v2, paramdsc* rc)
|
||||
declare external function dPower
|
||||
double precision by descriptor, double precision by descriptor,
|
||||
double precision by descriptor
|
||||
returns parameter 3
|
||||
entry_point 'power' module_name 'fbudf';
|
||||
|
||||
--FBUDF_API blobcallback* string2blob(const paramdsc* v, blobcallback* outblob)
|
||||
declare external function string2blob
|
||||
varchar(300) by descriptor,
|
||||
blob returns parameter 2
|
||||
entry_point 'string2blob' module_name 'fbudf';
|
||||
|
||||
|
@ -1,47 +0,0 @@
|
||||
FBUDF, a small project to enhance ibudf.
|
||||
|
||||
The library ibudf that comes with IB5, IB6 and FB has some generic routines.
|
||||
However, it lacks others and it seems a good idea to enhance it with more
|
||||
functionality. The first test is to build a separate small library. When those
|
||||
functions have been tested, they may be included in ibudf. This way, it's possible
|
||||
to experiment with fbudf without mangling the established library.
|
||||
|
||||
This is initially a MSVC project for Windows. It will be generalized later.
|
||||
It doesn't use ib_util because it relies on the engine providing return
|
||||
arguments when they are of type string.
|
||||
|
||||
Originally, this library intends to offer:
|
||||
|
||||
NVL => one for integers and the other for strings. This way, the overhead
|
||||
for strings can be avoided for integers.
|
||||
|
||||
NULLIF => same idea than before.
|
||||
|
||||
DOW (Day of Week) Monday, Tuesday, Wednesday ...
|
||||
SDOW(Short Day of Week) Mon, Tue, Wed, Thu ....
|
||||
|
||||
(
|
||||
The following two aren't necessary:
|
||||
SUBSTR: It has been superseded by internal SUBSTRING in Firebird.
|
||||
LEFT: You can use SUBSTRING(s from 1 for N) in Firebird
|
||||
)
|
||||
|
||||
RIGHT: This will work only for 1-byte charsets.
|
||||
|
||||
TRUNCATE / ROUND
|
||||
|
||||
(
|
||||
The following two are already in udflib:
|
||||
CEILING / FLOOR
|
||||
)
|
||||
|
||||
Date manipulation stuff ...
|
||||
Add a day, week, month, year to a date.
|
||||
|
||||
String <-> BLOB
|
||||
STRING2BLOB
|
||||
(Firebird already is capable of accepting a string to populate a blob on INSERT only.)
|
||||
|
||||
---
|
||||
Claudio Valderrama - July 2001.
|
||||
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* The contents of this file are subject to the Initial
|
||||
* Developer's Public License Version 1.0 (the "License");
|
||||
* you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
* http://www.ibphoenix.com/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by Claudio Valderrama C. for IBPhoenix.
|
||||
* The development of the Original Code was sponsored by Craig Leonardi.
|
||||
*
|
||||
* Copyright (c) 2001 IBPhoenix
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// fbudf.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* The contents of this file are subject to the Initial
|
||||
* Developer's Public License Version 1.0 (the "License");
|
||||
* you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
* http://www.ibphoenix.com/idpl.html.
|
||||
*
|
||||
* Software distributed under the License is distributed on
|
||||
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||
* express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
*
|
||||
* The Original Code was created by Claudio Valderrama C. for IBPhoenix.
|
||||
* The development of the Original Code was sponsored by Craig Leonardi.
|
||||
*
|
||||
* Copyright (c) 2001 IBPhoenix
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#if !defined(AFX_STDAFX_H__F60BDFDF_7A2D_11D5_8EEB_4854E8274D24__INCLUDED_)
|
||||
#define AFX_STDAFX_H__F60BDFDF_7A2D_11D5_8EEB_4854E8274D24__INCLUDED_
|
||||
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
||||
|
||||
|
||||
#include "firebird.h"
|
||||
|
||||
#ifdef HAVE_MATH_H
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
//#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TIMEB_H
|
||||
# include <sys/timeb.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
//#include "ib_util.h"
|
||||
//#include "ib_udf.h"
|
||||
|
||||
|
||||
#ifdef HAVE_PTHREAD_H
|
||||
#include "fb_pthread.h"
|
||||
#endif
|
||||
|
||||
#include "../../jrd/ibase.h"
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_STDAFX_H__F60BDFDF_7A2D_11D5_8EEB_4854E8274D24__INCLUDED_)
|
@ -1,462 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Interbase Public
|
||||
* License Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.Inprise.com/IPL.html
|
||||
*
|
||||
* Software distributed under the License is distributed on an
|
||||
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code was created by Inprise Corporation
|
||||
* and its predecessors. Portions created by Inprise Corporation are
|
||||
* Copyright (C) Inprise Corporation.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* Changes made by Claudio Valderrama for the Firebird project
|
||||
* changes to substr and added substrlen
|
||||
* 2004.9.1 Claudio Valderrama, change some UDF's to be able to detect NULL.
|
||||
* 2004.12.5 Slavomir Skopalik contributed IB_UDF_frac.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "firebird.h"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif
|
||||
#include "fb_types.h"
|
||||
#include "ib_util.h"
|
||||
#include "ib_udf.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
#ifndef __ICC
|
||||
#ifndef SOLARIS
|
||||
#ifdef WIN_NT
|
||||
#define exception_type _exception
|
||||
#else
|
||||
#define exception_type __exception
|
||||
#endif
|
||||
int MATHERR(struct exception_type*)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#undef exception_type
|
||||
#endif // SOLARIS
|
||||
#endif //__ICC
|
||||
|
||||
typedef char* pChar;
|
||||
|
||||
double EXPORT IB_UDF_abs( double *a)
|
||||
{
|
||||
return (*a < 0.0) ? -*a : *a;
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_acos( double *a)
|
||||
{
|
||||
return (acos(*a));
|
||||
}
|
||||
|
||||
pChar EXPORT IB_UDF_ascii_char( ISC_LONG *a)
|
||||
{
|
||||
if (!a)
|
||||
return 0;
|
||||
|
||||
char* b = (char *) ib_util_malloc(2);
|
||||
*b = (char) (*a);
|
||||
// let us not forget to NULL terminate
|
||||
b[1] = '\0';
|
||||
return (b);
|
||||
}
|
||||
|
||||
ISC_LONG EXPORT IB_UDF_ascii_val( const char *a)
|
||||
{
|
||||
// NULL is treated as ASCII(0).
|
||||
return ((ISC_LONG) (*a));
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_asin( double *a)
|
||||
{
|
||||
return (asin(*a));
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_atan( double *a)
|
||||
{
|
||||
return (atan(*a));
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_atan2( double *a, double *b)
|
||||
{
|
||||
return (atan2(*a, *b));
|
||||
}
|
||||
|
||||
ISC_LONG EXPORT IB_UDF_bin_and( ISC_LONG *a, ISC_LONG *b)
|
||||
{
|
||||
return (*a & *b);
|
||||
}
|
||||
|
||||
ISC_LONG EXPORT IB_UDF_bin_or( ISC_LONG *a, ISC_LONG *b)
|
||||
{
|
||||
return (*a | *b);
|
||||
}
|
||||
|
||||
ISC_LONG EXPORT IB_UDF_bin_xor( ISC_LONG *a, ISC_LONG *b)
|
||||
{
|
||||
return (*a ^ *b);
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_ceiling( double *a)
|
||||
{
|
||||
return (ceil(*a));
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_cos( double *a)
|
||||
{
|
||||
return (cos(*a));
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_cosh( double *a)
|
||||
{
|
||||
return (cosh(*a));
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_cot( double *a)
|
||||
{
|
||||
return (1.0 / tan(*a));
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_div( ISC_LONG *a, ISC_LONG *b)
|
||||
{
|
||||
if (*b != 0)
|
||||
{
|
||||
// VS8.0 has two implementations of div().
|
||||
// Let's explicitly use the int-aware one.
|
||||
div_t div_result = div((int) *a, (int) *b);
|
||||
return (div_result.quot);
|
||||
}
|
||||
|
||||
// This is a Kludge! We need to return INF,
|
||||
// but this seems to be the only way to do
|
||||
// it since there seens to be no constant for it.
|
||||
#ifdef HAVE_INFINITY
|
||||
return INFINITY;
|
||||
#else
|
||||
return 1 / tan(0.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_floor( double *a)
|
||||
{
|
||||
return (floor(*a));
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_frac(const double* x)
|
||||
{
|
||||
if (*x > 0)
|
||||
return *x - floor(*x);
|
||||
if (*x < 0)
|
||||
return *x - ceil(*x);
|
||||
return 0;
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_ln( double *a)
|
||||
{
|
||||
return (log(*a));
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_log( double *a, double *b)
|
||||
{
|
||||
return (log(*b) / log(*a));
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_log10( double *a)
|
||||
{
|
||||
return (log10(*a));
|
||||
}
|
||||
|
||||
pChar EXPORT IB_UDF_lower(const char *s)
|
||||
{
|
||||
if (!s)
|
||||
return 0;
|
||||
|
||||
char* buf = (char *) ib_util_malloc(static_cast<long>(strlen(s) + 1));
|
||||
char* p = buf;
|
||||
while (*s)
|
||||
{
|
||||
if (*s >= 'A' && *s <= 'Z') {
|
||||
*p++ = *s++ - 'A' + 'a';
|
||||
}
|
||||
else
|
||||
*p++ = *s++;
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
pChar EXPORT IB_UDF_lpad( const char *s, ISC_LONG *a, const char *c)
|
||||
{
|
||||
if (!s || !c)
|
||||
return 0;
|
||||
|
||||
const long avalue = *a;
|
||||
|
||||
if (avalue >= 0)
|
||||
{
|
||||
long current = 0;
|
||||
const long length = static_cast<long>(strlen(s));
|
||||
const long padlength = static_cast<long>(strlen(c));
|
||||
const long stop = avalue < length ? avalue : length;
|
||||
char* buf = (char*) ib_util_malloc(avalue + 1);
|
||||
|
||||
if (padlength)
|
||||
{
|
||||
while (current + length < avalue)
|
||||
{
|
||||
memcpy(&buf[current], c, padlength);
|
||||
current += padlength;
|
||||
}
|
||||
memcpy(&buf[(avalue - length < 0) ? 0 : avalue - length], s, stop);
|
||||
buf[avalue] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(buf, s, stop);
|
||||
buf[stop] = '\0';
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pChar EXPORT IB_UDF_ltrim( const char *s)
|
||||
{
|
||||
if (!s)
|
||||
return 0;
|
||||
|
||||
while (*s == ' ') // skip leading blanks
|
||||
s++;
|
||||
|
||||
const long length = static_cast<long>(strlen(s));
|
||||
char* buf = (char *) ib_util_malloc(length + 1);
|
||||
memcpy(buf, s, length);
|
||||
buf[length] = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_mod( ISC_LONG *a, ISC_LONG *b)
|
||||
{
|
||||
if (*b != 0)
|
||||
{
|
||||
// VS8.0 has two implementations of div().
|
||||
// Let's explicitly use the int-aware one.
|
||||
div_t div_result = div((int) *a, (int) *b);
|
||||
return (div_result.rem);
|
||||
}
|
||||
|
||||
// This is a Kludge! We need to return INF,
|
||||
// but this seems to be the only way to do
|
||||
// it since there seens to be no constant for it.
|
||||
#ifdef HAVE_INFINITY
|
||||
return INFINITY;
|
||||
#else
|
||||
return 1 / tan(0.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_pi()
|
||||
{
|
||||
return (IB_PI);
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_srand()
|
||||
{
|
||||
srand((unsigned) time(NULL));
|
||||
return ((float) rand() / (float) RAND_MAX);
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_rand()
|
||||
{
|
||||
return ((float) rand() / (float) RAND_MAX);
|
||||
}
|
||||
|
||||
pChar EXPORT IB_UDF_rpad( const char *s, ISC_LONG *a, const char *c)
|
||||
{
|
||||
if (!s || !c)
|
||||
return 0;
|
||||
|
||||
const long avalue = *a;
|
||||
|
||||
if (avalue >= 0)
|
||||
{
|
||||
const long length = static_cast<long>(strlen(s));
|
||||
long current = (avalue - length) < 0 ? avalue : length;
|
||||
const long padlength = static_cast<long>(strlen(c));
|
||||
char* buf = (char*) ib_util_malloc (avalue + 1);
|
||||
memcpy(buf, s, current);
|
||||
|
||||
if (padlength)
|
||||
{
|
||||
while (current + padlength < avalue)
|
||||
{
|
||||
memcpy(&buf[current], c, padlength);
|
||||
current += padlength;
|
||||
}
|
||||
memcpy(&buf[current], c, avalue - current);
|
||||
buf[avalue] = '\0';
|
||||
}
|
||||
else
|
||||
buf[current] = 0;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pChar EXPORT IB_UDF_rtrim( const char *s)
|
||||
{
|
||||
if (!s)
|
||||
return 0;
|
||||
|
||||
const char* p = s + strlen(s);
|
||||
while (--p >= s && *p == ' ')
|
||||
; // empty loop body
|
||||
|
||||
const long length = p - s + 1;
|
||||
char* buf = (char *) ib_util_malloc(length + 1);
|
||||
memcpy(buf, s, length);
|
||||
buf[length] = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
ISC_LONG EXPORT IB_UDF_sign( double *a)
|
||||
{
|
||||
if (*a > 0)
|
||||
return 1;
|
||||
if (*a < 0)
|
||||
return -1;
|
||||
// If neither is true then it equals 0
|
||||
return 0;
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_sin( double *a)
|
||||
{
|
||||
return (sin(*a));
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_sinh( double *a)
|
||||
{
|
||||
return (sinh(*a));
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_sqrt( double *a)
|
||||
{
|
||||
return (sqrt(*a));
|
||||
}
|
||||
|
||||
pChar EXPORT IB_UDF_substr(const char* s, ISC_SHORT* m, ISC_SHORT* n)
|
||||
{
|
||||
if (!s) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* buf;
|
||||
long length = static_cast<long>(strlen(s));
|
||||
if (!length ||
|
||||
*m > *n ||
|
||||
*m < 1 ||
|
||||
*n < 1 ||
|
||||
*m > length)
|
||||
{
|
||||
buf = (char*)ib_util_malloc(1);
|
||||
buf[0] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
// we want from the mth char to the nth char inclusive, so add one to the length.
|
||||
// CVC: We need to compensate for n if it's longer than s's length
|
||||
if (*n > length) {
|
||||
length -= *m - 1;
|
||||
}
|
||||
else {
|
||||
length = *n - *m + 1;
|
||||
}
|
||||
buf = (char*)ib_util_malloc (length + 1);
|
||||
memcpy(buf, s + *m - 1, length);
|
||||
buf[length] = '\0';
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
pChar EXPORT IB_UDF_substrlen(const char* s, ISC_SHORT* m, ISC_SHORT* n)
|
||||
{
|
||||
/* Created by Claudio Valderrama for the Firebird project,
|
||||
2001.04.17 We don't want to return NULL when params are wrong
|
||||
and we'll return the remaining characters if the final position
|
||||
is greater than the string's length, unless NULL is provided.
|
||||
*/
|
||||
if (!s) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* buf;
|
||||
long length = static_cast<long>(strlen(s));
|
||||
if (!length ||
|
||||
*m < 1 ||
|
||||
*n < 1 ||
|
||||
*m > length)
|
||||
{
|
||||
buf = (char*)ib_util_malloc(1);
|
||||
buf[0] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
// we want from the mth char to the (m+n)th char inclusive, so add one to the length.
|
||||
// CVC: We need to compensate for n if it's longer than s's length
|
||||
if (*m + *n - 1 > length) {
|
||||
length -= *m - 1;
|
||||
}
|
||||
else {
|
||||
length = *n;
|
||||
}
|
||||
buf = (char*) ib_util_malloc (length + 1);
|
||||
memcpy(buf, s + *m - 1, length);
|
||||
buf[length] = '\0';
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
ISC_LONG EXPORT IB_UDF_strlen( const char *a)
|
||||
{
|
||||
return static_cast<ISC_LONG>(strlen(a));
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_tan( double *a)
|
||||
{
|
||||
return (tan(*a));
|
||||
}
|
||||
|
||||
double EXPORT IB_UDF_tanh( double *a)
|
||||
{
|
||||
return (tanh(*a));
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Interbase Public
|
||||
* License Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.Inprise.com/IPL.html
|
||||
*
|
||||
* Software distributed under the License is distributed on an
|
||||
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code was created by Inprise Corporation
|
||||
* and its predecessors. Portions created by Inprise Corporation are
|
||||
* Copyright (C) Inprise Corporation.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
*/
|
||||
|
||||
#if defined(__cplusplus) && defined(DARWIN)
|
||||
#include "firebird.h"
|
||||
#define EXPORT API_ROUTINE
|
||||
#else
|
||||
#define EXPORT
|
||||
#endif
|
||||
#define MATHERR matherr
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define IB_E 2.7182818284590452354
|
||||
#define IB_PI 3.14159265358979323846
|
||||
#define IB_PI_2 1.57079632679489661923
|
||||
#define IB_PI_4 0.78539816339744830962
|
||||
#define IB_1_PI 0.31830988618379067154
|
||||
#define IB_2_PI 0.63661977236758134308
|
||||
#define IB_2_SQRTPI 1.12837916709551257390
|
||||
#define IB_SQRT2 1.41421356237309504880
|
||||
#define IB_SQRT1_2 0.70710678118654752440
|
@ -1,692 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Interbase Public
|
||||
* License Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.Inprise.com/IPL.html
|
||||
*
|
||||
* Software distributed under the License is distributed on an
|
||||
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code was created by Inprise Corporation
|
||||
* and its predecessors. Portions created by Inprise Corporation are
|
||||
* Copyright (C) Inprise Corporation.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* Revision 1.2 2000/11/28 06:47:52 fsg
|
||||
* Changed declaration of ascii_char in ib_udf.sql
|
||||
* to get correct result as proposed by Claudio Valderrama
|
||||
* 2001.5.19 Claudio Valderrama, add the declaration of alternative
|
||||
* substrlen function to handle string,start,length instead.
|
||||
*
|
||||
*/
|
||||
/*****************************************
|
||||
*
|
||||
* a b s
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the absolute value of a
|
||||
* number.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION abs
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_abs' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* a c o s
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the arccosine of a number
|
||||
* between -1 and 1, if the number is
|
||||
* out of bounds it returns NaN, as handled
|
||||
* by the _matherr routine.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION acos
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_acos' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* a s c i i _ c h a r
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the ASCII character corresponding
|
||||
* with the value passed in.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION ascii_char
|
||||
INTEGER
|
||||
RETURNS CSTRING(1) FREE_IT
|
||||
ENTRY_POINT 'IB_UDF_ascii_char' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* a s c i i _ v a l
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the ascii value of the character
|
||||
* passed in.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION ascii_val
|
||||
CHAR(1)
|
||||
RETURNS INTEGER BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_ascii_val' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* a s i n
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the arcsin of a number between
|
||||
* -1 and 1, if the number is out of
|
||||
* range NaN is returned.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION asin
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_asin' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* a t a n
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the arctangent of a number.
|
||||
*
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION atan
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_atan' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* a t a n 2
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the arctangent of the
|
||||
* first param / the second param.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION atan2
|
||||
DOUBLE PRECISION, DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_atan2' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* b i n _ a n d
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the result of a binary AND
|
||||
* operation performed on the two numbers.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION bin_and
|
||||
INTEGER, INTEGER
|
||||
RETURNS INTEGER BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_bin_and' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* b i n _ o r
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the result of a binary OR
|
||||
* operation performed on the two numbers.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION bin_or
|
||||
INTEGER, INTEGER
|
||||
RETURNS INTEGER BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_bin_or' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* b i n _ x o r
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the result of a binary XOR
|
||||
* operation performed on the two numbers.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION bin_xor
|
||||
INTEGER, INTEGER
|
||||
RETURNS INTEGER BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_bin_xor' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* c e i l i n g
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns a double value representing
|
||||
* the smallest integer that is greater
|
||||
* than or equal to the input value.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION ceiling
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_ceiling' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* c o s
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* The cos function returns the cosine
|
||||
* of x. If x is greater than or equal
|
||||
* to 263, or less than or equal to -263,
|
||||
* a loss of significance in the result
|
||||
* of a call to cos occurs, in which case
|
||||
* the function generates a _TLOSS error
|
||||
* and returns an indefinite (same as a
|
||||
* quiet NaN).
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION cos
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_cos' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* c o s h
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* The cosh function returns the hyperbolic cosine
|
||||
* of x. If x is greater than or equal
|
||||
* to 263, or less than or equal to -263,
|
||||
* a loss of significance in the result
|
||||
* of a call to cos occurs, in which case
|
||||
* the function generates a _TLOSS error
|
||||
* and returns an indefinite (same as a
|
||||
* quiet NaN).
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION cosh
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_cosh' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* c o t
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns 1 over the tangent of the
|
||||
* input parameter.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION cot
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_cot' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* d i v
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the quotient part of the division
|
||||
* of the two input parameters.
|
||||
*
|
||||
*****************************************/
|
||||
DECLARE EXTERNAL FUNCTION div
|
||||
INTEGER, INTEGER
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_div' MODULE_NAME 'ib_udf';
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* f l o o r
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns a floating-point value
|
||||
* representing the largest integer that
|
||||
* is less than or equal to x.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION floor
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_floor' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* u d f _ f r a c
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns a floating-point value
|
||||
* representing the fractional part of x.
|
||||
*
|
||||
*****************************************/
|
||||
DECLARE EXTERNAL FUNCTION udf_frac
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_frac' MODULE_NAME 'ib_udf';
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* l n
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the natural log of a number.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION ln
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_ln' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* l o g
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* log (x,y) returns the logarithm
|
||||
* base x of y.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION log
|
||||
DOUBLE PRECISION, DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_log' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* l o g 1 0
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the logarithm base 10 of the
|
||||
* input parameter.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION log10
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_log10' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* l o w e r
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the input string into lower
|
||||
* case characters. Note: This function
|
||||
* will not work with international and
|
||||
* non-ascii characters.
|
||||
* Note: This function is NOT limited to
|
||||
* receiving and returning only 255 characters,
|
||||
* rather, it can use as long as 32767
|
||||
* characters which is the limit on an
|
||||
* INTERBASE character string.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION lower
|
||||
CSTRING(255)
|
||||
RETURNS CSTRING(255) FREE_IT
|
||||
ENTRY_POINT 'IB_UDF_lower' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* l p a d
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Appends the given character to beginning
|
||||
* of the input string until length of the result
|
||||
* string becomes equal to the given number.
|
||||
* Note: This function is NOT limited to
|
||||
* receiving and returning only 255 characters,
|
||||
* rather, it can use as long as 32767
|
||||
* characters which is the limit on an
|
||||
* INTERBASE character string.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION lpad
|
||||
CSTRING(255), INTEGER, CSTRING(1)
|
||||
RETURNS CSTRING(255) FREE_IT
|
||||
ENTRY_POINT 'IB_UDF_lpad' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* l t r i m
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Removes leading spaces from the input
|
||||
* string.
|
||||
* Note: This function is NOT limited to
|
||||
* receiving and returning only 255 characters,
|
||||
* rather, it can use as long as 32767
|
||||
* characters which is the limit on an
|
||||
* INTERBASE character string.
|
||||
*
|
||||
*****************************************/
|
||||
DECLARE EXTERNAL FUNCTION ltrim
|
||||
CSTRING(255)
|
||||
RETURNS CSTRING(255) FREE_IT
|
||||
ENTRY_POINT 'IB_UDF_ltrim' MODULE_NAME 'ib_udf';
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* m o d
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the remainder part of the
|
||||
* division of the two input parameters.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION mod
|
||||
INTEGER, INTEGER
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_mod' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* p i
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the value of pi = 3.14159...
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION pi
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_pi' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* r a n d
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns a random number between 0
|
||||
* and 1. Note the random number
|
||||
* generator is seeded using the current
|
||||
* time.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION rand
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_rand' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* r p a d
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Appends the given character to end
|
||||
* of the input string until length of the result
|
||||
* string becomes equal to the given number.
|
||||
* Note: This function is NOT limited to
|
||||
* receiving and returning only 255 characters,
|
||||
* rather, it can use as long as 32767
|
||||
* characters which is the limit on an
|
||||
* INTERBASE character string.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION rpad
|
||||
CSTRING(255), INTEGER, CSTRING(1)
|
||||
RETURNS CSTRING(255) FREE_IT
|
||||
ENTRY_POINT 'IB_UDF_rpad' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* r t r i m
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Removes trailing spaces from the input
|
||||
* string.
|
||||
* Note: This function is NOT limited to
|
||||
* receiving and returning only 255 characters,
|
||||
* rather, it can use as long as 32767
|
||||
* characters which is the limit on an
|
||||
* INTERBASE character string.
|
||||
*
|
||||
*****************************************/
|
||||
DECLARE EXTERNAL FUNCTION rtrim
|
||||
CSTRING(255)
|
||||
RETURNS CSTRING(255) FREE_IT
|
||||
ENTRY_POINT 'IB_UDF_rtrim' MODULE_NAME 'ib_udf';
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* s i g n
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns 1, 0, or -1 depending on whether
|
||||
* the input value is positive, zero or
|
||||
* negative, respectively.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION sign
|
||||
DOUBLE PRECISION
|
||||
RETURNS INTEGER BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_sign' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* s i n
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the sine of x. If x is greater
|
||||
* than or equal to 263, or less than or
|
||||
* equal to -263, a loss of significance
|
||||
* in the result occurs, in which case the
|
||||
* function generates a _TLOSS error and
|
||||
* returns an indefinite (same as a quiet NaN).
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION sin
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_sin' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* s i n h
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the hyperbolic sine of x. If x is greater
|
||||
* than or equal to 263, or less than or
|
||||
* equal to -263, a loss of significance
|
||||
* in the result occurs, in which case the
|
||||
* function generates a _TLOSS error and
|
||||
* returns an indefinite (same as a quiet NaN).
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION sinh
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_sinh' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* s q r t
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the square root of a number.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION sqrt
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_sqrt' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* s u b s t r
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* substr(s,m,n) returns the substring
|
||||
* of s which starts at position m and
|
||||
* ending at position n.
|
||||
* Note: This function is NOT limited to
|
||||
* receiving and returning only 255 characters,
|
||||
* rather, it can use as long as 32767
|
||||
* characters which is the limit on an
|
||||
* INTERBASE character string.
|
||||
* Change by Claudio Valderrama: when n>length(s),
|
||||
* the result will be the original string instead
|
||||
* of NULL as it was originally designed.
|
||||
*
|
||||
*****************************************/
|
||||
DECLARE EXTERNAL FUNCTION substr
|
||||
CSTRING(255), SMALLINT, SMALLINT
|
||||
RETURNS CSTRING(255) FREE_IT
|
||||
ENTRY_POINT 'IB_UDF_substr' MODULE_NAME 'ib_udf';
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* s u b s t r l e n
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* substrlen(s,i,l) returns the substring
|
||||
* of s which starts at position i and
|
||||
* ends at position i+l-1, being l the length.
|
||||
* Note: This function is NOT limited to
|
||||
* receiving and returning only 255 characters,
|
||||
* rather, it can use as long as 32767
|
||||
* characters which is the limit on an
|
||||
* INTERBASE character string.
|
||||
*
|
||||
*****************************************/
|
||||
DECLARE EXTERNAL FUNCTION substrlen
|
||||
CSTRING(255), SMALLINT, SMALLINT
|
||||
RETURNS CSTRING(255) FREE_IT
|
||||
ENTRY_POINT 'IB_UDF_substrlen' MODULE_NAME 'ib_udf';
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* s t r l e n
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the length of a given string.
|
||||
*
|
||||
*****************************************/
|
||||
DECLARE EXTERNAL FUNCTION strlen
|
||||
CSTRING(32767)
|
||||
RETURNS INTEGER BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_strlen' MODULE_NAME 'ib_udf';
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* t a n
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the tangent of x. If x is
|
||||
* greater than or equal to 263, or less
|
||||
* than or equal to -263, a loss of
|
||||
* significance in the result occurs, in
|
||||
* which case the function generates a
|
||||
* _TLOSS error and returns an indefinite
|
||||
* (same as a quiet NaN).
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION tan
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_tan' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* t a n h
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the tangent of x. If x is
|
||||
* greater than or equal to 263, or less
|
||||
* than or equal to -263, a loss of
|
||||
* significance in the result occurs, in
|
||||
* which case the function generates a
|
||||
* _TLOSS error and returns an indefinite
|
||||
* (same as a quiet NaN).
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION tanh
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_tanh' MODULE_NAME 'ib_udf'; */
|
||||
|
@ -1,716 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Interbase Public
|
||||
* License Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.Inprise.com/IPL.html
|
||||
*
|
||||
* Software distributed under the License is distributed on an
|
||||
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code was created by Inprise Corporation
|
||||
* and its predecessors. Portions created by Inprise Corporation are
|
||||
* Copyright (C) Inprise Corporation.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
* Contributor(s): ______________________________________.
|
||||
* Revision 1.2 2000/11/28 06:47:52 fsg
|
||||
* Changed declaration of ascii_char in ib_udf.sql
|
||||
* to get correct result as proposed by Claudio Valderrama
|
||||
* 2001.5.19 Claudio Valderrama, add the declaration of alternative
|
||||
* substrlen function to handle string,start,length instead.
|
||||
* 2004.9.1 Claudio Valderrama, changed some UDF's to be able to detect NULL
|
||||
* and renamed the resulting file as ib_udf2.sql.
|
||||
*
|
||||
*/
|
||||
/*****************************************
|
||||
*
|
||||
* a b s
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the absolute value of a
|
||||
* number.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION abs
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_abs' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* a c o s
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the arccosine of a number
|
||||
* between -1 and 1, if the number is
|
||||
* out of bounds it returns NaN, as handled
|
||||
* by the _matherr routine.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION acos
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_acos' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* a s c i i _ c h a r
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the ASCII character corresponding
|
||||
* with the value passed in.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION ascii_char
|
||||
INTEGER NULL
|
||||
RETURNS CSTRING(1) FREE_IT
|
||||
ENTRY_POINT 'IB_UDF_ascii_char' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* a s c i i _ v a l
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the ascii value of the character
|
||||
* passed in.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION ascii_val
|
||||
CHAR(1)
|
||||
RETURNS INTEGER BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_ascii_val' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* a s i n
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the arcsin of a number between
|
||||
* -1 and 1, if the number is out of
|
||||
* range NaN is returned.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION asin
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_asin' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* a t a n
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the arctangent of a number.
|
||||
*
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION atan
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_atan' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* a t a n 2
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the arctangent of the
|
||||
* first param / the second param.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION atan2
|
||||
DOUBLE PRECISION, DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_atan2' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* b i n _ a n d
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the result of a binary AND
|
||||
* operation performed on the two numbers.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION bin_and
|
||||
INTEGER, INTEGER
|
||||
RETURNS INTEGER BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_bin_and' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* b i n _ o r
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the result of a binary OR
|
||||
* operation performed on the two numbers.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION bin_or
|
||||
INTEGER, INTEGER
|
||||
RETURNS INTEGER BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_bin_or' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* b i n _ x o r
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the result of a binary XOR
|
||||
* operation performed on the two numbers.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION bin_xor
|
||||
INTEGER, INTEGER
|
||||
RETURNS INTEGER BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_bin_xor' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* c e i l i n g
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns a double value representing
|
||||
* the smallest integer that is greater
|
||||
* than or equal to the input value.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION ceiling
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_ceiling' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* c o s
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* The cos function returns the cosine
|
||||
* of x. If x is greater than or equal
|
||||
* to 263, or less than or equal to -263,
|
||||
* a loss of significance in the result
|
||||
* of a call to cos occurs, in which case
|
||||
* the function generates a _TLOSS error
|
||||
* and returns an indefinite (same as a
|
||||
* quiet NaN).
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION cos
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_cos' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* c o s h
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* The cosh function returns the hyperbolic cosine
|
||||
* of x. If x is greater than or equal
|
||||
* to 263, or less than or equal to -263,
|
||||
* a loss of significance in the result
|
||||
* of a call to cos occurs, in which case
|
||||
* the function generates a _TLOSS error
|
||||
* and returns an indefinite (same as a
|
||||
* quiet NaN).
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION cosh
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_cosh' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* c o t
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns 1 over the tangent of the
|
||||
* input parameter.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION cot
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_cot' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* d i v
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the quotient part of the division
|
||||
* of the two input parameters.
|
||||
*
|
||||
*****************************************/
|
||||
DECLARE EXTERNAL FUNCTION div
|
||||
INTEGER, INTEGER
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_div' MODULE_NAME 'ib_udf';
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* f l o o r
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns a floating-point value
|
||||
* representing the largest integer that
|
||||
* is less than or equal to x.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION floor
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_floor' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* u d f _ f r a c
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns a floating-point value
|
||||
* representing the fractional part of x.
|
||||
*
|
||||
*****************************************/
|
||||
DECLARE EXTERNAL FUNCTION udf_frac
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_frac' MODULE_NAME 'ib_udf';
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* l n
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the natural log of a number.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION ln
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_ln' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* l o g
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* log (x,y) returns the logarithm
|
||||
* base x of y.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION log
|
||||
DOUBLE PRECISION, DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_log' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* l o g 1 0
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the logarithm base 10 of the
|
||||
* input parameter.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION log10
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_log10' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* l o w e r
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the input string into lower
|
||||
* case characters. Note: This function
|
||||
* will not work with international and
|
||||
* non-ascii characters.
|
||||
* Note: This function is NOT limited to
|
||||
* receiving and returning only 255 characters,
|
||||
* rather, it can use as long as 32767
|
||||
* characters which is the limit on an
|
||||
* INTERBASE character string.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION "LOWER"
|
||||
CSTRING(255) NULL
|
||||
RETURNS CSTRING(255) FREE_IT
|
||||
ENTRY_POINT 'IB_UDF_lower' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* l p a d
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Appends the given character to beginning
|
||||
* of the input string until length of the result
|
||||
* string becomes equal to the given number.
|
||||
* Note: This function is NOT limited to
|
||||
* receiving and returning only 255 characters,
|
||||
* rather, it can use as long as 32767
|
||||
* characters which is the limit on an
|
||||
* INTERBASE character string.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION lpad
|
||||
CSTRING(255) NULL, INTEGER, CSTRING(1) NULL
|
||||
RETURNS CSTRING(255) FREE_IT
|
||||
ENTRY_POINT 'IB_UDF_lpad' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* l t r i m
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Removes leading spaces from the input
|
||||
* string.
|
||||
* Note: This function is NOT limited to
|
||||
* receiving and returning only 255 characters,
|
||||
* rather, it can use as long as 32767
|
||||
* characters which is the limit on an
|
||||
* INTERBASE character string.
|
||||
*
|
||||
*****************************************/
|
||||
DECLARE EXTERNAL FUNCTION ltrim
|
||||
CSTRING(255) NULL
|
||||
RETURNS CSTRING(255) FREE_IT
|
||||
ENTRY_POINT 'IB_UDF_ltrim' MODULE_NAME 'ib_udf';
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* m o d
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the remainder part of the
|
||||
* division of the two input parameters.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION mod
|
||||
INTEGER, INTEGER
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_mod' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* p i
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the value of pi = 3.14159...
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION pi
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_pi' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* r a n d
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns a random number between 0
|
||||
* and 1.
|
||||
*
|
||||
*
|
||||
* Note: Use srand to seed the
|
||||
* random number generator.
|
||||
* This behavior has been changed.
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION rand
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_rand' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* r p a d
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Appends the given character to end
|
||||
* of the input string until length of the result
|
||||
* string becomes equal to the given number.
|
||||
* Note: This function is NOT limited to
|
||||
* receiving and returning only 255 characters,
|
||||
* rather, it can use as long as 32767
|
||||
* characters which is the limit on an
|
||||
* INTERBASE character string.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION rpad
|
||||
CSTRING(255) NULL, INTEGER, CSTRING(1) NULL
|
||||
RETURNS CSTRING(255) FREE_IT
|
||||
ENTRY_POINT 'IB_UDF_rpad' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* r t r i m
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Removes trailing spaces from the input
|
||||
* string.
|
||||
* Note: This function is NOT limited to
|
||||
* receiving and returning only 255 characters,
|
||||
* rather, it can use as long as 32767
|
||||
* characters which is the limit on an
|
||||
* INTERBASE character string.
|
||||
*
|
||||
*****************************************/
|
||||
DECLARE EXTERNAL FUNCTION rtrim
|
||||
CSTRING(255) NULL
|
||||
RETURNS CSTRING(255) FREE_IT
|
||||
ENTRY_POINT 'IB_UDF_rtrim' MODULE_NAME 'ib_udf';
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* s i g n
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns 1, 0, or -1 depending on whether
|
||||
* the input value is positive, zero or
|
||||
* negative, respectively.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION sign
|
||||
DOUBLE PRECISION
|
||||
RETURNS INTEGER BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_sign' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* s i n
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the sine of x. If x is greater
|
||||
* than or equal to 263, or less than or
|
||||
* equal to -263, a loss of significance
|
||||
* in the result occurs, in which case the
|
||||
* function generates a _TLOSS error and
|
||||
* returns an indefinite (same as a quiet NaN).
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION sin
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_sin' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* s i n h
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the hyperbolic sine of x. If x is greater
|
||||
* than or equal to 263, or less than or
|
||||
* equal to -263, a loss of significance
|
||||
* in the result occurs, in which case the
|
||||
* function generates a _TLOSS error and
|
||||
* returns an indefinite (same as a quiet NaN).
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION sinh
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_sinh' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* s q r t
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the square root of a number.
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION sqrt
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_sqrt' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* s r a n d
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns a random number between 0
|
||||
* and 1. Note the random number
|
||||
* generator is seeded using the current
|
||||
* time.
|
||||
*
|
||||
*****************************************/
|
||||
DECLARE EXTERNAL FUNCTION srand
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_srand' MODULE_NAME 'ib_udf';
|
||||
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* s u b s t r
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* substr(s,m,n) returns the substring
|
||||
* of s which starts at position m and
|
||||
* ending at position n.
|
||||
* Note: This function is NOT limited to
|
||||
* receiving and returning only 255 characters,
|
||||
* rather, it can use as long as 32767
|
||||
* characters which is the limit on an
|
||||
* INTERBASE character string.
|
||||
* Change by Claudio Valderrama: when n>length(s),
|
||||
* the result will be the original string instead
|
||||
* of NULL as it was originally designed.
|
||||
*
|
||||
*****************************************/
|
||||
DECLARE EXTERNAL FUNCTION substr
|
||||
CSTRING(255) NULL, SMALLINT, SMALLINT
|
||||
RETURNS CSTRING(255) FREE_IT
|
||||
ENTRY_POINT 'IB_UDF_substr' MODULE_NAME 'ib_udf';
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* s u b s t r l e n
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* substrlen(s,i,l) returns the substring
|
||||
* of s which starts at position i and
|
||||
* ends at position i+l-1, being l the length.
|
||||
* Note: This function is NOT limited to
|
||||
* receiving and returning only 255 characters,
|
||||
* rather, it can use as long as 32767
|
||||
* characters which is the limit on an
|
||||
* INTERBASE character string.
|
||||
*
|
||||
*****************************************/
|
||||
DECLARE EXTERNAL FUNCTION substrlen
|
||||
CSTRING(255) NULL, SMALLINT, SMALLINT
|
||||
RETURNS CSTRING(255) FREE_IT
|
||||
ENTRY_POINT 'IB_UDF_substrlen' MODULE_NAME 'ib_udf';
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* s t r l e n
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the length of a given string.
|
||||
*
|
||||
*****************************************/
|
||||
DECLARE EXTERNAL FUNCTION strlen
|
||||
CSTRING(32767) CHARACTER SET NONE
|
||||
RETURNS INTEGER BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_strlen' MODULE_NAME 'ib_udf';
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* t a n
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the tangent of x. If x is
|
||||
* greater than or equal to 263, or less
|
||||
* than or equal to -263, a loss of
|
||||
* significance in the result occurs, in
|
||||
* which case the function generates a
|
||||
* _TLOSS error and returns an indefinite
|
||||
* (same as a quiet NaN).
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION tan
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_tan' MODULE_NAME 'ib_udf'; */
|
||||
|
||||
/*****************************************
|
||||
*
|
||||
* t a n h
|
||||
*
|
||||
*****************************************
|
||||
*
|
||||
* Functional description:
|
||||
* Returns the tangent of x. If x is
|
||||
* greater than or equal to 263, or less
|
||||
* than or equal to -263, a loss of
|
||||
* significance in the result occurs, in
|
||||
* which case the function generates a
|
||||
* _TLOSS error and returns an indefinite
|
||||
* (same as a quiet NaN).
|
||||
*
|
||||
*****************************************
|
||||
DECLARE EXTERNAL FUNCTION tanh
|
||||
DOUBLE PRECISION
|
||||
RETURNS DOUBLE PRECISION BY VALUE
|
||||
ENTRY_POINT 'IB_UDF_tanh' MODULE_NAME 'ib_udf'; */
|
||||
|
@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "ib_udf.h"
|
||||
#include "ib_util.h"
|
||||
#include "firebird.h"
|
||||
|
||||
typedef void* VoidPtr;
|
||||
|
@ -152,7 +152,7 @@
|
||||
|
||||
#define FB__META_FB_BOOLEAN \
|
||||
builder->setType(status, index, SQL_BOOLEAN); \
|
||||
builder->setLength(status, index, sizeof(ISC_BOOLEAN));
|
||||
builder->setLength(status, index, sizeof(FB_BOOLEAN));
|
||||
|
||||
#define FB__META_FB_DATE \
|
||||
builder->setType(status, index, SQL_DATE); \
|
||||
|
Loading…
Reference in New Issue
Block a user