4370 lines
148 KiB
C++
4370 lines
148 KiB
C++
/***************************************************************************/
|
|
/* SCALAR.CPP */
|
|
/* Copyright (C) 1997 SYWARE Inc., All rights reserved */
|
|
/***************************************************************************/
|
|
// Commenting #define out - causing compiler error - not sure if needed, compiles
|
|
// okay without it.
|
|
//#define WINVER 0x0400
|
|
#include "precomp.h"
|
|
#include "wbemidl.h"
|
|
|
|
#include <comdef.h>
|
|
//smart pointer
|
|
_COM_SMARTPTR_TYPEDEF(IWbemServices, IID_IWbemServices);
|
|
_COM_SMARTPTR_TYPEDEF(IEnumWbemClassObject, IID_IEnumWbemClassObject);
|
|
//_COM_SMARTPTR_TYPEDEF(IWbemContext, IID_IWbemContext );
|
|
_COM_SMARTPTR_TYPEDEF(IWbemLocator, IID_IWbemLocator);
|
|
|
|
#include "drdbdr.h"
|
|
#include <math.h>
|
|
#include <stdlib.h>
|
|
#ifndef WIN32
|
|
#include <signal.h>
|
|
#include <setjmp.h>
|
|
#include <float.h>
|
|
#endif
|
|
#include <time.h>
|
|
|
|
#ifndef WIN32
|
|
#ifdef __cplusplus
|
|
#define _JBLEN 9
|
|
#ifndef _JMP_BUF_DEFINED
|
|
typedef int jmp_buf[_JBLEN];
|
|
#define _JMP_BUF_DEFINED
|
|
#endif
|
|
#define setjmp _setjmp
|
|
extern "C" {
|
|
int __cdecl _setjmp(jmp_buf);
|
|
void __cdecl longjmp(jmp_buf, int);
|
|
}
|
|
#endif
|
|
|
|
jmp_buf scalarExceptionMark;
|
|
#endif
|
|
|
|
#define MAX_SCALAR_ARGS 4
|
|
|
|
typedef struct tagSCALARFUNC {
|
|
LPUSTR name; /* Name of the scalar function */
|
|
SWORD dataType; /* Data type returned (TYPE_*) */
|
|
SWORD sqlType; /* Sql type returned (SQL_*) (use SQL_* of */
|
|
/* first argument if SQL_TYPE_NULL) */
|
|
SDWORD precision; /* Precision (use precision of first */
|
|
/* argument if 0) */
|
|
SWORD scale; /* Scale if sqlType is SQL_DECIMAL */
|
|
/* or SQL_NUMERIC (use scale of first */
|
|
/* argument if precision is 0 */
|
|
UWORD argCount; /* Number of argments */
|
|
SWORD argType[MAX_SCALAR_ARGS]; /* Data typeof each arg (TYPE_*) */
|
|
} SCALARFUNC,
|
|
FAR *LPSCALARFUNC;
|
|
|
|
#define SCALAR_ASCII 0
|
|
#define SCALAR_CHAR 1
|
|
#define SCALAR_CONCAT 2
|
|
#define SCALAR_DIFFERENCE 3
|
|
#define SCALAR_INSERT 4
|
|
#define SCALAR_LCASE 5
|
|
#define SCALAR_LEFT 6
|
|
#define SCALAR_LENGTH 7
|
|
#define SCALAR_LOCATE 8
|
|
#define SCALAR_LOCATE_START 9
|
|
#define SCALAR_LTRIM 10
|
|
#define SCALAR_REPEAT 11
|
|
#define SCALAR_REPLACE 12
|
|
#define SCALAR_RIGHT 13
|
|
#define SCALAR_RTRIM 14
|
|
#define SCALAR_SOUNDEX 15
|
|
#define SCALAR_SPACE 16
|
|
#define SCALAR_SUBSTRING 17
|
|
#define SCALAR_UCASE 18
|
|
#define SCALAR_ABS_DOUBLE 19
|
|
#define SCALAR_ABS_NUMERIC 20
|
|
#define SCALAR_ABS_INTEGER 21
|
|
#define SCALAR_ACOS 22
|
|
#define SCALAR_ASIN 23
|
|
#define SCALAR_ATAN 24
|
|
#define SCALAR_ATAN2 25
|
|
#define SCALAR_CEILING_DOUBLE 26
|
|
#define SCALAR_CEILING_NUMERIC 27
|
|
#define SCALAR_CEILING_INTEGER 28
|
|
#define SCALAR_COS 29
|
|
#define SCALAR_COT 30
|
|
#define SCALAR_DEGREES_DOUBLE 31
|
|
#define SCALAR_DEGREES_NUMERIC 32
|
|
#define SCALAR_DEGREES_INTEGER 33
|
|
#define SCALAR_EXP 34
|
|
#define SCALAR_FLOOR_DOUBLE 35
|
|
#define SCALAR_FLOOR_NUMERIC 36
|
|
#define SCALAR_FLOOR_INTEGER 37
|
|
#define SCALAR_LOG 38
|
|
#define SCALAR_LOG10 39
|
|
#define SCALAR_MOD 40
|
|
#define SCALAR_PI 41
|
|
#define SCALAR_POWER_DOUBLE 42
|
|
#define SCALAR_POWER_NUMERIC 43
|
|
#define SCALAR_POWER_INTEGER 44
|
|
#define SCALAR_RADIANS_DOUBLE 45
|
|
#define SCALAR_RADIANS_NUMERIC 46
|
|
#define SCALAR_RADIANS_INTEGER 47
|
|
#define SCALAR_RAND 48
|
|
#define SCALAR_RAND_SEED_DOUBLE 49
|
|
#define SCALAR_RAND_SEED_NUMERIC 50
|
|
#define SCALAR_RAND_SEED_INTEGER 51
|
|
#define SCALAR_ROUND_DOUBLE 52
|
|
#define SCALAR_ROUND_NUMERIC 53
|
|
#define SCALAR_ROUND_INTEGER 54
|
|
#define SCALAR_SIGN_DOUBLE 55
|
|
#define SCALAR_SIGN_NUMERIC 56
|
|
#define SCALAR_SIGN_INTEGER 57
|
|
#define SCALAR_SIN 58
|
|
#define SCALAR_SQRT 59
|
|
#define SCALAR_TAN 60
|
|
#define SCALAR_TRUNCATE_DOUBLE 61
|
|
#define SCALAR_TRUNCATE_NUMERIC 62
|
|
#define SCALAR_TRUNCATE_INTEGER 63
|
|
#define SCALAR_CURDATE 64
|
|
#define SCALAR_CURTIME 65
|
|
#define SCALAR_DAYNAME 66
|
|
#define SCALAR_DAYOFMONTH_CHAR 67
|
|
#define SCALAR_DAYOFMONTH_DATE 68
|
|
#define SCALAR_DAYOFMONTH_TIMESTAMP 69
|
|
#define SCALAR_DAYOFWEEK 70
|
|
#define SCALAR_DAYOFYEAR 71
|
|
#define SCALAR_HOUR_CHAR 72
|
|
#define SCALAR_HOUR_TIME 73
|
|
#define SCALAR_HOUR_TIMESTAMP 74
|
|
#define SCALAR_MINUTE_CHAR 75
|
|
#define SCALAR_MINUTE_TIME 76
|
|
#define SCALAR_MINUTE_TIMESTAMP 77
|
|
#define SCALAR_MONTH_CHAR 78
|
|
#define SCALAR_MONTH_DATE 79
|
|
#define SCALAR_MONTH_TIMESTAMP 80
|
|
#define SCALAR_MONTHNAME_CHAR 81
|
|
#define SCALAR_MONTHNAME_DATE 82
|
|
#define SCALAR_MONTHNAME_TIMESTAMP 83
|
|
#define SCALAR_NOW 84
|
|
#define SCALAR_QUARTER_CHAR 85
|
|
#define SCALAR_QUARTER_DATE 86
|
|
#define SCALAR_QUARTER_TIMESTAMP 87
|
|
#define SCALAR_SECOND_CHAR 88
|
|
#define SCALAR_SECOND_TIME 89
|
|
#define SCALAR_SECOND_TIMESTAMP 90
|
|
#define SCALAR_TIMESTAMPADD 91
|
|
#define SCALAR_TIMESTAMPDIFF 92
|
|
#define SCALAR_WEEK 93
|
|
#define SCALAR_YEAR_CHAR 94
|
|
#define SCALAR_YEAR_DATE 95
|
|
#define SCALAR_YEAR_TIMESTAMP 96
|
|
#define SCALAR_DATABASE 97
|
|
#define SCALAR_IFNULL 98
|
|
#define SCALAR_USER 99
|
|
#define SCALAR_CONVERT 100
|
|
|
|
/* Seed value for SCALAR_RAND_* functions */
|
|
static long new_seed = 1;
|
|
|
|
SCALARFUNC scalarFuncs[] = {
|
|
|
|
/* SCALAR_ASCII */
|
|
{
|
|
/* name */ (LPUSTR) "ASCII",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_CHAR }
|
|
},
|
|
|
|
/* SCALAR_CHAR */
|
|
{
|
|
/* name */ (LPUSTR) "CHAR",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_VARCHAR,
|
|
/* precision */ 1,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_CONCAT */
|
|
{
|
|
/* name */ (LPUSTR) "CONCAT",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_VARCHAR,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 2,
|
|
/* argType[] */ { TYPE_CHAR, TYPE_CHAR }
|
|
},
|
|
|
|
/* SCALAR_DIFFERENCE */
|
|
{
|
|
/* name */ (LPUSTR) "DIFFERENCE",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_INTEGER,
|
|
/* precision */ 10,
|
|
/* scale */ 0,
|
|
/* argCount */ 2,
|
|
/* argType[] */ { TYPE_CHAR, TYPE_CHAR }
|
|
},
|
|
|
|
/* SCALAR_INSERT_INTEGER */
|
|
{
|
|
/* name */ (LPUSTR) "INSERT",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_VARCHAR,
|
|
/* precision */ MAX_CHAR_LITERAL_LENGTH,
|
|
/* scale */ 0,
|
|
/* argCount */ 4,
|
|
/* argType[] */ { TYPE_CHAR, TYPE_INTEGER, TYPE_INTEGER, TYPE_CHAR }
|
|
},
|
|
|
|
/* SCALAR_LCASE */
|
|
{
|
|
/* name */ (LPUSTR) "LCASE",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_TYPE_NULL,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_CHAR }
|
|
},
|
|
|
|
/* SCALAR_LEFT */
|
|
{
|
|
/* name */ (LPUSTR) "LEFT",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_VARCHAR,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 2,
|
|
/* argType[] */ { TYPE_CHAR, TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_LENGTH */
|
|
{
|
|
/* name */ (LPUSTR) "LENGTH",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_SMALLINT,
|
|
/* precision */ 5,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_CHAR }
|
|
},
|
|
|
|
/* SCALAR_LOCATE */
|
|
{
|
|
/* name */ (LPUSTR) "LOCATE",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_SMALLINT,
|
|
/* precision */ 5,
|
|
/* scale */ 0,
|
|
/* argCount */ 2,
|
|
/* argType[] */ { TYPE_CHAR, TYPE_CHAR }
|
|
},
|
|
|
|
/* SCALAR_LOCATE_START */
|
|
{
|
|
/* name */ (LPUSTR) "LOCATE",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_SMALLINT,
|
|
/* precision */ 5,
|
|
/* scale */ 0,
|
|
/* argCount */ 3,
|
|
/* argType[] */ { TYPE_CHAR, TYPE_CHAR, TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_LTRIM */
|
|
{
|
|
/* name */ (LPUSTR) "LTRIM",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_VARCHAR,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_CHAR }
|
|
},
|
|
|
|
/* SCALAR_REPEAT */
|
|
{
|
|
/* name */ (LPUSTR) "REPEAT",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_VARCHAR,
|
|
/* precision */ MAX_CHAR_LITERAL_LENGTH,
|
|
/* scale */ 0,
|
|
/* argCount */ 2,
|
|
/* argType[] */ { TYPE_CHAR, TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_REPLACE */
|
|
{
|
|
/* name */ (LPUSTR) "REPLACE",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_VARCHAR,
|
|
/* precision */ MAX_CHAR_LITERAL_LENGTH,
|
|
/* scale */ 0,
|
|
/* argCount */ 3,
|
|
/* argType[] */ { TYPE_CHAR, TYPE_CHAR, TYPE_CHAR }
|
|
},
|
|
|
|
/* SCALAR_RIGHT */
|
|
{
|
|
/* name */ (LPUSTR) "RIGHT",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_VARCHAR,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 2,
|
|
/* argType[] */ { TYPE_CHAR, TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_RTRIM */
|
|
{
|
|
/* name */ (LPUSTR) "RTRIM",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_VARCHAR,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_CHAR }
|
|
},
|
|
|
|
/* SCALAR_SOUNDEX */
|
|
{
|
|
/* name */ (LPUSTR) "SOUNDEX",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_VARCHAR,
|
|
/* precision */ MAX_CHAR_LITERAL_LENGTH,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_CHAR }
|
|
},
|
|
|
|
/* SCALAR_SPACE */
|
|
{
|
|
/* name */ (LPUSTR) "SPACE",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_VARCHAR,
|
|
/* precision */ MAX_CHAR_LITERAL_LENGTH,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_SUBSTRING */
|
|
{
|
|
/* name */ (LPUSTR) "SUBSTRING",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_VARCHAR,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 3,
|
|
/* argType[] */ { TYPE_CHAR, TYPE_INTEGER, TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_UCASE */
|
|
{
|
|
/* name */ (LPUSTR) "UCASE",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_TYPE_NULL,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_CHAR }
|
|
},
|
|
|
|
/* SCALAR_ABS_DOUBLE */
|
|
{
|
|
/* name */ (LPUSTR) "ABS",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_TYPE_NULL,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DOUBLE }
|
|
},
|
|
|
|
/* SCALAR_ABS_NUMERIC */
|
|
{
|
|
/* name */ (LPUSTR) "ABS",
|
|
/* dataType */ TYPE_NUMERIC,
|
|
/* sqlType */ SQL_TYPE_NULL,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_NUMERIC }
|
|
},
|
|
|
|
/* SCALAR_ABS_INTEGER */
|
|
{
|
|
/* name */ (LPUSTR) "ABS",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TYPE_NULL,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_ACOS */
|
|
{
|
|
/* name */ (LPUSTR) "ACOS",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DOUBLE }
|
|
},
|
|
|
|
/* SCALAR_ASIN */
|
|
{
|
|
/* name */ (LPUSTR) "ASIN",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DOUBLE }
|
|
},
|
|
|
|
/* SCALAR_ATAN */
|
|
{
|
|
/* name */ (LPUSTR) "ATAN",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DOUBLE }
|
|
},
|
|
|
|
/* SCALAR_ATAN2 */
|
|
{
|
|
/* name */ (LPUSTR) "ATAN2",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 2,
|
|
/* argType[] */ { TYPE_DOUBLE, TYPE_DOUBLE }
|
|
},
|
|
|
|
/* SCALAR_CEILING_DOUBLE */
|
|
{
|
|
/* name */ (LPUSTR) "CEILING",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_TYPE_NULL,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DOUBLE }
|
|
},
|
|
|
|
/* SCALAR_CEILING_NUMERIC */
|
|
{
|
|
/* name */ (LPUSTR) "CEILING",
|
|
/* dataType */ TYPE_NUMERIC,
|
|
/* sqlType */ SQL_TYPE_NULL,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_NUMERIC }
|
|
},
|
|
|
|
/* SCALAR_CEILING_INTEGER */
|
|
{
|
|
/* name */ (LPUSTR) "CEILING",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TYPE_NULL,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_COS */
|
|
{
|
|
/* name */ (LPUSTR) "COS",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DOUBLE }
|
|
},
|
|
|
|
/* SCALAR_COT */
|
|
{
|
|
/* name */ (LPUSTR) "COT",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DOUBLE }
|
|
},
|
|
|
|
/* SCALAR_DEGREES_DOUBLE */
|
|
{
|
|
/* name */ (LPUSTR) "DEGREES",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DOUBLE }
|
|
},
|
|
|
|
/* SCALAR_DEGREES_NUMERIC */
|
|
{
|
|
/* name */ (LPUSTR) "DEGREES",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_NUMERIC }
|
|
},
|
|
|
|
/* SCALAR_DEGREES_INTEGER */
|
|
{
|
|
/* name */ (LPUSTR) "DEGREES",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_EXP */
|
|
{
|
|
/* name */ (LPUSTR) "EXP",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DOUBLE }
|
|
},
|
|
|
|
/* SCALAR_FLOOR_DOUBLE */
|
|
{
|
|
/* name */ (LPUSTR) "FLOOR",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_TYPE_NULL,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DOUBLE }
|
|
},
|
|
|
|
/* SCALAR_FLOOR_NUMERIC */
|
|
{
|
|
/* name */ (LPUSTR) "FLOOR",
|
|
/* dataType */ TYPE_NUMERIC,
|
|
/* sqlType */ SQL_TYPE_NULL,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_NUMERIC }
|
|
},
|
|
|
|
/* SCALAR_FLOOR_INTEGER */
|
|
{
|
|
/* name */ (LPUSTR) "FLOOR",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TYPE_NULL,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_LOG */
|
|
{
|
|
/* name */ (LPUSTR) "LOG",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DOUBLE }
|
|
},
|
|
|
|
/* SCALAR_LOG10 */
|
|
{
|
|
/* name */ (LPUSTR) "LOG10",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DOUBLE }
|
|
},
|
|
|
|
/* SCALAR_MOD */
|
|
{
|
|
/* name */ (LPUSTR) "MOD",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TYPE_NULL,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 2,
|
|
/* argType[] */ { TYPE_INTEGER, TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_PI */
|
|
{
|
|
/* name */ (LPUSTR) "PI",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 0
|
|
},
|
|
|
|
/* SCALAR_POWER_DOUBLE */
|
|
{
|
|
/* name */ (LPUSTR) "POWER",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 2,
|
|
/* argType[] */ { TYPE_DOUBLE, TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_POWER_NUMERIC */
|
|
{
|
|
/* name */ (LPUSTR) "POWER",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 2,
|
|
/* argType[] */ { TYPE_NUMERIC, TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_POWER_INTEGER */
|
|
{
|
|
/* name */ (LPUSTR) "POWER",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 2,
|
|
/* argType[] */ { TYPE_INTEGER, TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_RADIANS_DOUBLE */
|
|
{
|
|
/* name */ (LPUSTR) "RADIANS",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DOUBLE }
|
|
},
|
|
|
|
/* SCALAR_RADIANS_NUMERIC */
|
|
{
|
|
/* name */ (LPUSTR) "RADIANS",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_NUMERIC }
|
|
},
|
|
|
|
/* SCALAR_RADIANS_INTEGER */
|
|
{
|
|
/* name */ (LPUSTR) "RADIANS",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_RAND */
|
|
{
|
|
/* name */ (LPUSTR) "RAND",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 0
|
|
},
|
|
|
|
/* SCALAR_RAND_SEED_DOUBLE */
|
|
{
|
|
/* name */ (LPUSTR) "RAND",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DOUBLE }
|
|
},
|
|
|
|
/* SCALAR_RAND_SEED_NUMERIC */
|
|
{
|
|
/* name */ (LPUSTR) "RAND",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_NUMERIC }
|
|
},
|
|
|
|
/* SCALAR_RAND_SEED_INTEGER */
|
|
{
|
|
/* name */ (LPUSTR) "RAND",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_ROUND_DOUBLE */
|
|
{
|
|
/* name */ (LPUSTR) "ROUND",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_TYPE_NULL,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 2,
|
|
/* argType[] */ { TYPE_DOUBLE, TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_ROUND_NUMERIC */
|
|
{
|
|
/* name */ (LPUSTR) "ROUND",
|
|
/* dataType */ TYPE_NUMERIC,
|
|
/* sqlType */ SQL_TYPE_NULL,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 2,
|
|
/* argType[] */ { TYPE_NUMERIC, TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_ROUND_INTEGER */
|
|
{
|
|
/* name */ (LPUSTR) "ROUND",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TYPE_NULL,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 2,
|
|
/* argType[] */ { TYPE_INTEGER, TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_SIGN_DOUBLE */
|
|
{
|
|
/* name */ (LPUSTR) "SIGN",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DOUBLE }
|
|
},
|
|
|
|
/* SCALAR_SIGN_NUMERIC */
|
|
{
|
|
/* name */ (LPUSTR) "SIGN",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_NUMERIC }
|
|
},
|
|
|
|
/* SCALAR_SIGN_INTEGER */
|
|
{
|
|
/* name */ (LPUSTR) "SIGN",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_SIN */
|
|
{
|
|
/* name */ (LPUSTR) "SIN",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DOUBLE }
|
|
},
|
|
|
|
/* SCALAR_SQRT */
|
|
{
|
|
/* name */ (LPUSTR) "SQRT",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DOUBLE }
|
|
},
|
|
|
|
/* SCALAR_TAN */
|
|
{
|
|
/* name */ (LPUSTR) "TAN",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_DOUBLE,
|
|
/* precision */ 15,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DOUBLE }
|
|
},
|
|
|
|
/* SCALAR_TRUNCATE_DOUBLE */
|
|
{
|
|
/* name */ (LPUSTR) "TRUNCATE",
|
|
/* dataType */ TYPE_DOUBLE,
|
|
/* sqlType */ SQL_TYPE_NULL,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 2,
|
|
/* argType[] */ { TYPE_DOUBLE, TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_TRUNCATE_NUMERIC */
|
|
{
|
|
/* name */ (LPUSTR) "TRUNCATE",
|
|
/* dataType */ TYPE_NUMERIC,
|
|
/* sqlType */ SQL_TYPE_NULL,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 2,
|
|
/* argType[] */ { TYPE_NUMERIC, TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_TRUNCATE_INTEGER */
|
|
{
|
|
/* name */ (LPUSTR) "TRUNCATE",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TYPE_NULL,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 2,
|
|
/* argType[] */ { TYPE_INTEGER, TYPE_INTEGER }
|
|
},
|
|
|
|
/* SCALAR_CURDATE */
|
|
{
|
|
/* name */ (LPUSTR) "CURDATE",
|
|
/* dataType */ TYPE_DATE,
|
|
/* sqlType */ SQL_TIMESTAMP, //SQL_DATE,
|
|
/* precision */ 10,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 0
|
|
},
|
|
|
|
/* SCALAR_CURTIME */
|
|
{
|
|
/* name */ (LPUSTR) "CURTIME",
|
|
/* dataType */ TYPE_TIME,
|
|
/* sqlType */ SQL_TIMESTAMP, //SQL_TIME,
|
|
/* precision */ 8,
|
|
/* scale */ NO_SCALE,
|
|
/* argCount */ 0
|
|
},
|
|
|
|
/* SCALAR_DAYNAME */
|
|
{
|
|
/* name */ (LPUSTR) "DAYNAME",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_VARCHAR,
|
|
/* precision */ MAX_CHAR_LITERAL_LENGTH,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_UNKNOWN }
|
|
},
|
|
|
|
/* SCALAR_DAYOFMONTH_CHAR */
|
|
{
|
|
/* name */ (LPUSTR) "DAYOFMONTH",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_CHAR }
|
|
},
|
|
|
|
/* SCALAR_DAYOFMONTH_DATE */
|
|
{
|
|
/* name */ (LPUSTR) "DAYOFMONTH",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DATE }
|
|
},
|
|
|
|
/* SCALAR_DAYOFMONTH_TIMESTAMP */
|
|
{
|
|
/* name */ (LPUSTR) "DAYOFMONTH",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_TIMESTAMP }
|
|
},
|
|
|
|
/* SCALAR_DAYOFWEEK */
|
|
{
|
|
/* name */ (LPUSTR) "DAYOFWEEK",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_UNKNOWN }
|
|
},
|
|
|
|
/* SCALAR_DAYOFYEAR */
|
|
{
|
|
/* name */ (LPUSTR) "DAYOFYEAR",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_SMALLINT,
|
|
/* precision */ 5,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_UNKNOWN }
|
|
},
|
|
|
|
/* SCALAR_HOUR_CHAR */
|
|
{
|
|
/* name */ (LPUSTR) "HOUR",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_CHAR }
|
|
},
|
|
|
|
/* SCALAR_HOUR_TIME */
|
|
{
|
|
/* name */ (LPUSTR) "HOUR",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_TIME }
|
|
},
|
|
|
|
/* SCALAR_HOUR_TIMESTAMP */
|
|
{
|
|
/* name */ (LPUSTR) "HOUR",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_TIMESTAMP }
|
|
},
|
|
|
|
/* SCALAR_MINUTE_CHAR */
|
|
{
|
|
/* name */ (LPUSTR) "MINUTE",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_CHAR }
|
|
},
|
|
|
|
/* SCALAR_MINUTE_TIME */
|
|
{
|
|
/* name */ (LPUSTR) "MINUTE",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_TIME }
|
|
},
|
|
|
|
/* SCALAR_MINUTE_TIMESTAMP */
|
|
{
|
|
/* name */ (LPUSTR) "MINUTE",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_TIMESTAMP }
|
|
},
|
|
|
|
/* SCALAR_MONTH_CHAR */
|
|
{
|
|
/* name */ (LPUSTR) "MONTH",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_CHAR }
|
|
},
|
|
|
|
/* SCALAR_MONTH_DATE */
|
|
{
|
|
/* name */ (LPUSTR) "MONTH",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DATE }
|
|
},
|
|
|
|
/* SCALAR_MONTH_TIMESTAMP */
|
|
{
|
|
/* name */ (LPUSTR) "MONTH",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_TIMESTAMP }
|
|
},
|
|
|
|
/* SCALAR_MONTHNAME_CHAR */
|
|
{
|
|
/* name */ (LPUSTR) "MONTHNAME",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_VARCHAR,
|
|
/* precision */ MAX_CHAR_LITERAL_LENGTH,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_CHAR }
|
|
},
|
|
|
|
/* SCALAR_MONTHNAME_DATE */
|
|
{
|
|
/* name */ (LPUSTR) "MONTHNAME",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_VARCHAR,
|
|
/* precision */ MAX_CHAR_LITERAL_LENGTH,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DATE }
|
|
},
|
|
|
|
/* SCALAR_MONTHNAME_TIMESTAMP */
|
|
{
|
|
/* name */ (LPUSTR) "MONTHNAME",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_VARCHAR,
|
|
/* precision */ MAX_CHAR_LITERAL_LENGTH,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_TIMESTAMP }
|
|
},
|
|
|
|
/* SCALAR_NOW */
|
|
{
|
|
/* name */ (LPUSTR) "NOW",
|
|
/* dataType */ TYPE_TIMESTAMP,
|
|
/* sqlType */ SQL_TIMESTAMP,
|
|
#if TIMESTAMP_SCALE
|
|
/* precision */ 20 + TIMESTAMP_SCALE,
|
|
#else
|
|
/* precision */ 19,
|
|
#endif
|
|
/* scale */ TIMESTAMP_SCALE,
|
|
/* argCount */ 0
|
|
},
|
|
|
|
/* SCALAR_QUARTER_CHAR */
|
|
{
|
|
/* name */ (LPUSTR) "QUARTER",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_CHAR }
|
|
},
|
|
|
|
/* SCALAR_QUARTER_DATE */
|
|
{
|
|
/* name */ (LPUSTR) "QUARTER",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DATE }
|
|
},
|
|
|
|
/* SCALAR_QUARTER_TIMESTAMP */
|
|
{
|
|
/* name */ (LPUSTR) "QUARTER",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_TIMESTAMP }
|
|
},
|
|
|
|
/* SCALAR_SECOND_CHAR */
|
|
{
|
|
/* name */ (LPUSTR) "SECOND",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_CHAR }
|
|
},
|
|
|
|
/* SCALAR_SECOND_TIME */
|
|
{
|
|
/* name */ (LPUSTR) "SECOND",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_TIME }
|
|
},
|
|
|
|
/* SCALAR_SECOND_TIMESTAMP */
|
|
{
|
|
/* name */ (LPUSTR) "SECOND",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_TIMESTAMP }
|
|
},
|
|
|
|
/* SCALAR_TIMESTAMPADD */
|
|
{
|
|
/* name */ (LPUSTR) "TIMESTAMPADD",
|
|
/* dataType */ TYPE_TIMESTAMP,
|
|
/* sqlType */ SQL_TIMESTAMP,
|
|
#if TIMESTAMP_SCALE
|
|
/* precision */ 20 + TIMESTAMP_SCALE,
|
|
#else
|
|
/* precision */ 19,
|
|
#endif
|
|
/* scale */ TIMESTAMP_SCALE,
|
|
/* argCount */ 2,
|
|
/* argType[] */ { TYPE_INTEGER, TYPE_UNKNOWN }
|
|
},
|
|
|
|
/* SCALAR_TIMESTAMPDIFF */
|
|
{
|
|
/* name */ (LPUSTR) "TIMESTAMPDIFF",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_INTEGER,
|
|
/* precision */ 10,
|
|
/* scale */ 0,
|
|
/* argCount */ 2,
|
|
/* argType[] */ { TYPE_UNKNOWN, TYPE_UNKNOWN }
|
|
},
|
|
|
|
/* SCALAR_WEEK */
|
|
{
|
|
/* name */ (LPUSTR) "WEEK",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_TINYINT,
|
|
/* precision */ 3,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_UNKNOWN }
|
|
},
|
|
|
|
/* SCALAR_YEAR_CHAR */
|
|
{
|
|
/* name */ (LPUSTR) "YEAR",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_INTEGER,
|
|
/* precision */ 10,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_CHAR }
|
|
},
|
|
|
|
/* SCALAR_YEAR_DATE */
|
|
{
|
|
/* name */ (LPUSTR) "YEAR",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_INTEGER,
|
|
/* precision */ 10,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_DATE }
|
|
},
|
|
|
|
/* SCALAR_YEAR_TIMESTAMP */
|
|
{
|
|
/* name */ (LPUSTR) "YEAR",
|
|
/* dataType */ TYPE_INTEGER,
|
|
/* sqlType */ SQL_INTEGER,
|
|
/* precision */ 10,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_TIMESTAMP }
|
|
},
|
|
|
|
/* SCALAR_DATABASE */
|
|
{
|
|
/* name */ (LPUSTR) "DATABASE",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_VARCHAR,
|
|
/* precision */ MAX_DATABASE_NAME_LENGTH,
|
|
/* scale */ 0,
|
|
/* argCount */ 0
|
|
},
|
|
|
|
/* SCALAR_IFNULL */
|
|
{
|
|
/* name */ (LPUSTR) "IFNULL",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_TYPE_NULL,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 2,
|
|
/* argType[] */ { TYPE_UNKNOWN, TYPE_UNKNOWN }
|
|
},
|
|
|
|
/* SCALAR_USER */
|
|
{
|
|
/* name */ (LPUSTR) "USER",
|
|
/* dataType */ TYPE_CHAR,
|
|
/* sqlType */ SQL_VARCHAR,
|
|
/* precision */ MAX_USER_NAME_LENGTH,
|
|
/* scale */ 0,
|
|
/* argCount */ 0
|
|
},
|
|
|
|
/* SCALAR_CONVERT */
|
|
{
|
|
/* name */ (LPUSTR) "CONVERT",
|
|
/* dataType */ TYPE_UNKNOWN,
|
|
/* sqlType */ SQL_TYPE_NULL,
|
|
/* precision */ 0,
|
|
/* scale */ 0,
|
|
/* argCount */ 1,
|
|
/* argType[] */ { TYPE_UNKNOWN }
|
|
},
|
|
|
|
{ (LPUSTR) "" }
|
|
};
|
|
|
|
#define SQL_TSI_SECOND 1
|
|
#define SQL_TSI_MINUTE 2
|
|
#define SQL_TSI_HOUR 3
|
|
#define SQL_TSI_DAY 4
|
|
#define SQL_TSI_WEEK 5
|
|
#define SQL_TSI_MONTH 6
|
|
#define SQL_TSI_QUARTER 7
|
|
#define SQL_TSI_YEAR 8
|
|
|
|
#define SECONDS_PER_MINUTE (60L)
|
|
#define SECONDS_PER_HOUR (60L * 60L)
|
|
#define SECONDS_PER_DAY (60L * 60L * 24L)
|
|
#define SECONDS_PER_WEEK (60L * 60L * 24L * 7L)
|
|
#define MONTHS_PER_YEAR (12)
|
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
|
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
|
#define PI 3.14159265358979323846264338327950288419716939937510
|
|
|
|
#define BIT_LOW_D ( 0.0)
|
|
#define BIT_HIGH_D ( 1.0)
|
|
#define STINY_LOW_D ( -128.0)
|
|
#define STINY_HIGH_D ( 127.0)
|
|
#define UTINY_LOW_D ( 0.0)
|
|
#define UTINY_HIGH_D ( 255.0)
|
|
#define SSHORT_LOW_D ( -32768.0)
|
|
#define SSHORT_HIGH_D ( 32767.0)
|
|
#define USHORT_LOW_D ( 0.0)
|
|
#define USHORT_HIGH_D ( 65535.0)
|
|
#define SLONG_LOW_D (-2147483648.0)
|
|
#define SLONG_HIGH_D ( 2147483647.0)
|
|
#define ULONG_LOW_D ( 0.0)
|
|
#define ULONG_HIGH_D ( 4294967296.0)
|
|
#define FLOAT_LOW_D ( -3.4E38)
|
|
#define FLOAT_HIGH_D ( 3.4E38)
|
|
#define DOUBLE_LOW_D ( -1.7E308)
|
|
#define DOUBLE_HIGH_D ( 1.7E308)
|
|
|
|
/***************************************************************************/
|
|
SWORD ScalarIfNullType(LPSQLNODE lpSqlNodeLeft, LPSQLNODE lpSqlNodeRight,
|
|
LPSQLNODE lpSqlNode)
|
|
{
|
|
/* Error if type not compatible? */
|
|
if (!((lpSqlNodeLeft->sqlDataType == lpSqlNodeRight->sqlDataType) ||
|
|
((lpSqlNodeLeft->sqlDataType == TYPE_DOUBLE) &&
|
|
(lpSqlNodeRight->sqlDataType == TYPE_NUMERIC)) ||
|
|
((lpSqlNodeLeft->sqlDataType == TYPE_DOUBLE) &&
|
|
(lpSqlNodeRight->sqlDataType == TYPE_INTEGER)) ||
|
|
((lpSqlNodeLeft->sqlDataType == TYPE_NUMERIC) &&
|
|
(lpSqlNodeRight->sqlDataType == TYPE_DOUBLE)) ||
|
|
((lpSqlNodeLeft->sqlDataType == TYPE_NUMERIC) &&
|
|
(lpSqlNodeRight->sqlDataType == TYPE_INTEGER)) ||
|
|
((lpSqlNodeLeft->sqlDataType == TYPE_INTEGER) &&
|
|
(lpSqlNodeRight->sqlDataType == TYPE_DOUBLE)) ||
|
|
((lpSqlNodeLeft->sqlDataType == TYPE_INTEGER) &&
|
|
(lpSqlNodeRight->sqlDataType == TYPE_NUMERIC))))
|
|
return ERR_SCALARBADARG;
|
|
|
|
|
|
/* Figure out resultant type */
|
|
if ((lpSqlNodeLeft->sqlDataType == TYPE_NUMERIC) &&
|
|
(lpSqlNodeRight->sqlDataType == TYPE_DOUBLE))
|
|
lpSqlNode->sqlDataType = TYPE_DOUBLE;
|
|
else if ((lpSqlNodeLeft->sqlDataType == TYPE_INTEGER) &&
|
|
(lpSqlNodeRight->sqlDataType == TYPE_DOUBLE))
|
|
lpSqlNode->sqlDataType = TYPE_DOUBLE;
|
|
else if ((lpSqlNodeLeft->sqlDataType == TYPE_INTEGER) &&
|
|
(lpSqlNodeRight->sqlDataType == TYPE_NUMERIC))
|
|
lpSqlNode->sqlDataType = TYPE_NUMERIC;
|
|
else
|
|
lpSqlNode->sqlDataType = lpSqlNodeLeft->sqlDataType;
|
|
|
|
/* Figure out resultant SQL type, precision, and scale */
|
|
switch (lpSqlNodeLeft->sqlSqlType) {
|
|
case SQL_DOUBLE:
|
|
lpSqlNode->sqlSqlType = SQL_DOUBLE;
|
|
lpSqlNode->sqlPrecision = 15;
|
|
lpSqlNode->sqlScale = NO_SCALE;
|
|
break;
|
|
case SQL_FLOAT:
|
|
if (lpSqlNodeRight->sqlSqlType == SQL_DOUBLE)
|
|
lpSqlNode->sqlSqlType = SQL_DOUBLE;
|
|
else
|
|
lpSqlNode->sqlSqlType = SQL_FLOAT;
|
|
lpSqlNode->sqlPrecision = 15;
|
|
lpSqlNode->sqlScale = NO_SCALE;
|
|
break;
|
|
case SQL_REAL:
|
|
if (lpSqlNodeRight->sqlSqlType == SQL_DOUBLE) {
|
|
lpSqlNode->sqlSqlType = SQL_DOUBLE;
|
|
lpSqlNode->sqlPrecision = 15;
|
|
}
|
|
else if (lpSqlNodeRight->sqlSqlType == SQL_FLOAT) {
|
|
lpSqlNode->sqlSqlType = SQL_FLOAT;
|
|
lpSqlNode->sqlPrecision = 15;
|
|
}
|
|
else {
|
|
lpSqlNode->sqlSqlType = SQL_REAL;
|
|
lpSqlNode->sqlPrecision = 7;
|
|
}
|
|
lpSqlNode->sqlScale = NO_SCALE;
|
|
break;
|
|
case SQL_DECIMAL:
|
|
case SQL_NUMERIC:
|
|
case SQL_BIGINT:
|
|
case SQL_INTEGER:
|
|
case SQL_SMALLINT:
|
|
case SQL_TINYINT:
|
|
case SQL_BIT:
|
|
switch (lpSqlNodeRight->sqlSqlType) {
|
|
case SQL_DOUBLE:
|
|
case SQL_FLOAT:
|
|
case SQL_REAL:
|
|
lpSqlNode->sqlSqlType = lpSqlNodeRight->sqlSqlType;
|
|
lpSqlNode->sqlPrecision = lpSqlNodeRight->sqlPrecision;
|
|
lpSqlNode->sqlScale = NO_SCALE;
|
|
break;
|
|
case SQL_DECIMAL:
|
|
case SQL_NUMERIC:
|
|
case SQL_BIGINT:
|
|
case SQL_INTEGER:
|
|
case SQL_SMALLINT:
|
|
case SQL_TINYINT:
|
|
case SQL_BIT:
|
|
if ((lpSqlNodeRight->sqlSqlType == SQL_DECIMAL) ||
|
|
(lpSqlNodeLeft->sqlSqlType == SQL_DECIMAL))
|
|
lpSqlNode->sqlSqlType = SQL_DECIMAL;
|
|
else if ((lpSqlNodeRight->sqlSqlType == SQL_NUMERIC) ||
|
|
(lpSqlNodeLeft->sqlSqlType == SQL_NUMERIC))
|
|
lpSqlNode->sqlSqlType = SQL_NUMERIC;
|
|
else if ((lpSqlNodeRight->sqlSqlType == SQL_BIGINT) ||
|
|
(lpSqlNodeLeft->sqlSqlType == SQL_BIGINT))
|
|
lpSqlNode->sqlSqlType = SQL_BIGINT;
|
|
else if ((lpSqlNodeRight->sqlSqlType == SQL_INTEGER) ||
|
|
(lpSqlNodeLeft->sqlSqlType == SQL_INTEGER))
|
|
lpSqlNode->sqlSqlType = SQL_INTEGER;
|
|
else if ((lpSqlNodeRight->sqlSqlType == SQL_SMALLINT) ||
|
|
(lpSqlNodeLeft->sqlSqlType == SQL_SMALLINT))
|
|
lpSqlNode->sqlSqlType = SQL_SMALLINT;
|
|
else if ((lpSqlNodeRight->sqlSqlType == SQL_TINYINT) ||
|
|
(lpSqlNodeLeft->sqlSqlType == SQL_TINYINT))
|
|
lpSqlNode->sqlSqlType = SQL_TINYINT;
|
|
else
|
|
lpSqlNode->sqlSqlType = SQL_BIT;
|
|
lpSqlNode->sqlScale = MAX(lpSqlNodeRight->sqlScale,
|
|
lpSqlNodeLeft->sqlScale);
|
|
lpSqlNode->sqlPrecision = lpSqlNode->sqlScale +
|
|
MAX(lpSqlNodeRight->sqlPrecision - lpSqlNodeRight->sqlScale,
|
|
lpSqlNodeLeft->sqlPrecision - lpSqlNodeLeft->sqlScale);
|
|
break;
|
|
case SQL_LONGVARCHAR:
|
|
case SQL_VARCHAR:
|
|
case SQL_CHAR:
|
|
case SQL_LONGVARBINARY:
|
|
case SQL_VARBINARY:
|
|
case SQL_BINARY:
|
|
case SQL_DATE:
|
|
case SQL_TIME:
|
|
case SQL_TIMESTAMP:
|
|
return ERR_INTERNAL;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
break;
|
|
|
|
case SQL_LONGVARCHAR:
|
|
return ERR_INTERNAL;
|
|
case SQL_VARCHAR:
|
|
case SQL_CHAR:
|
|
if ((lpSqlNodeRight->sqlSqlType == SQL_VARCHAR) ||
|
|
(lpSqlNodeLeft->sqlSqlType == SQL_VARCHAR))
|
|
lpSqlNode->sqlSqlType = SQL_VARCHAR;
|
|
else
|
|
lpSqlNode->sqlSqlType = SQL_CHAR;
|
|
lpSqlNode->sqlPrecision = MAX(lpSqlNodeRight->sqlPrecision,
|
|
lpSqlNodeLeft->sqlPrecision);
|
|
lpSqlNode->sqlScale = NO_SCALE;
|
|
break;
|
|
case SQL_LONGVARBINARY:
|
|
return ERR_INTERNAL;
|
|
case SQL_VARBINARY:
|
|
case SQL_BINARY:
|
|
if ((lpSqlNodeRight->sqlSqlType == SQL_VARBINARY) ||
|
|
(lpSqlNodeLeft->sqlSqlType == SQL_VARBINARY))
|
|
lpSqlNode->sqlSqlType = SQL_VARBINARY;
|
|
else
|
|
lpSqlNode->sqlSqlType = SQL_BINARY;
|
|
lpSqlNode->sqlPrecision = MAX(lpSqlNodeRight->sqlPrecision,
|
|
lpSqlNodeLeft->sqlPrecision);
|
|
lpSqlNode->sqlScale = NO_SCALE;
|
|
break;
|
|
case SQL_DATE:
|
|
case SQL_TIME:
|
|
case SQL_TIMESTAMP:
|
|
lpSqlNode->sqlSqlType = lpSqlNodeLeft->sqlSqlType;
|
|
lpSqlNode->sqlPrecision = lpSqlNodeLeft->sqlPrecision;
|
|
lpSqlNode->sqlScale = lpSqlNodeLeft->sqlScale;
|
|
break;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
return ERR_SUCCESS;
|
|
}
|
|
/***************************************************************************/
|
|
RETCODE INTFUNC ScalarCheck(LPSTMT lpstmt, LPSQLTREE FAR *lplpSql,
|
|
SQLNODEIDX idxNode, BOOL fIsGroupby, BOOL fCaseSensitive,
|
|
SQLNODEIDX idxNodeTableOuterJoinFromTables,
|
|
SQLNODEIDX idxEnclosingStatement)
|
|
{
|
|
LPSQLNODE lpSqlNode;
|
|
LPUSTR lpszFunction;
|
|
SWORD err;
|
|
UWORD idx;
|
|
SQLNODEIDX idxValues;
|
|
LPSQLNODE lpSqlNodeValues;
|
|
LPSQLNODE lpSqlNodeValue;
|
|
LPSQLNODE lpSqlNodeValue2;
|
|
LPSCALARFUNC lpScalarFunc;
|
|
SQLNODEIDX idxInterval;
|
|
SQLNODEIDX idxType;
|
|
LPUSTR lpstrInterval;
|
|
LPUSTR lpstrType;
|
|
|
|
/* Find first entry for the function */
|
|
lpSqlNode = ToNode(*lplpSql, idxNode);
|
|
lpSqlNode->node.scalar.Id = 0;
|
|
lpszFunction = ToString(*lplpSql, lpSqlNode->node.scalar.Function);
|
|
while (TRUE) {
|
|
lpScalarFunc = &(scalarFuncs[lpSqlNode->node.scalar.Id]);
|
|
if (s_lstrlen(lpScalarFunc->name) == 0) {
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARNOTFOUND;
|
|
}
|
|
if (!s_lstrcmpi(lpszFunction, lpScalarFunc->name))
|
|
break;
|
|
(lpSqlNode->node.scalar.Id)++;
|
|
}
|
|
|
|
/* TIMESTAMPADD or TIMESTAMPDIFF function? */
|
|
if ((lpSqlNode->node.scalar.Id == SCALAR_TIMESTAMPADD) ||
|
|
(lpSqlNode->node.scalar.Id == SCALAR_TIMESTAMPDIFF)) {
|
|
|
|
/* Yes. Get the node with the name of the interval */
|
|
idxInterval = lpSqlNode->node.scalar.Arguments;
|
|
if (idxInterval == NO_SQLNODE) {
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
|
|
/* Point the node at the rest of the argument list */
|
|
lpSqlNodeValues = ToNode(*lplpSql, idxInterval);
|
|
lpSqlNode->node.scalar.Arguments = lpSqlNodeValues->node.values.Next;
|
|
|
|
/* Look at the node specifying the interval */
|
|
lpSqlNodeValue = ToNode(*lplpSql, lpSqlNodeValues->node.values.Value);
|
|
if (lpSqlNodeValue->sqlNodeType != NODE_TYPE_COLUMN) {
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
if (lpSqlNodeValue->node.column.Tablealias != NO_STRING) {
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
lpstrInterval = ToString(*lplpSql, lpSqlNodeValue->node.column.Column);
|
|
if (!s_lstrcmpi(lpstrInterval, "SQL_TSI_FRAC_SECOND"))
|
|
return ERR_NOTSUPPORTED;
|
|
else if (!s_lstrcmpi(lpstrInterval, "SQL_TSI_SECOND"))
|
|
lpSqlNode->node.scalar.Interval = SQL_TSI_SECOND;
|
|
else if (!s_lstrcmpi(lpstrInterval, "SQL_TSI_MINUTE"))
|
|
lpSqlNode->node.scalar.Interval = SQL_TSI_MINUTE;
|
|
else if (!s_lstrcmpi(lpstrInterval, "SQL_TSI_HOUR"))
|
|
lpSqlNode->node.scalar.Interval = SQL_TSI_HOUR;
|
|
else if (!s_lstrcmpi(lpstrInterval, "SQL_TSI_DAY"))
|
|
lpSqlNode->node.scalar.Interval = SQL_TSI_DAY;
|
|
else if (!s_lstrcmpi(lpstrInterval, "SQL_TSI_WEEK"))
|
|
lpSqlNode->node.scalar.Interval = SQL_TSI_WEEK;
|
|
else if (!s_lstrcmpi(lpstrInterval, "SQL_TSI_MONTH"))
|
|
lpSqlNode->node.scalar.Interval = SQL_TSI_MONTH;
|
|
else if (!s_lstrcmpi(lpstrInterval, "SQL_TSI_QUARTER"))
|
|
lpSqlNode->node.scalar.Interval = SQL_TSI_QUARTER;
|
|
else if (!s_lstrcmpi(lpstrInterval, "SQL_TSI_YEAR"))
|
|
lpSqlNode->node.scalar.Interval = SQL_TSI_YEAR;
|
|
else {
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
}
|
|
|
|
/* CONVERT function? */
|
|
else if (lpSqlNode->node.scalar.Id == SCALAR_CONVERT) {
|
|
|
|
/* Yes. Get the node with the name of the type */
|
|
idxType = lpSqlNode->node.scalar.Arguments;
|
|
if (idxType == NO_SQLNODE) {
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
lpSqlNodeValues = ToNode(*lplpSql, idxType);
|
|
idxType = lpSqlNodeValues->node.values.Next;
|
|
if (idxType == NO_SQLNODE) {
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
|
|
/* Take type name off the argument list */
|
|
lpSqlNodeValues->node.values.Next = NO_SQLNODE;
|
|
lpSqlNodeValues = ToNode(*lplpSql, idxType);
|
|
if (lpSqlNodeValues->node.values.Next != NO_SQLNODE) {
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
|
|
/* Get the type name */
|
|
lpSqlNodeValue = ToNode(*lplpSql, lpSqlNodeValues->node.values.Value);
|
|
if (lpSqlNodeValue->sqlNodeType != NODE_TYPE_COLUMN) {
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
if (lpSqlNodeValue->node.column.Tablealias != NO_STRING) {
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
lpstrType = ToString(*lplpSql, lpSqlNodeValue->node.column.Column);
|
|
}
|
|
|
|
/* Semantic check the arguments */
|
|
err = SemanticCheck(lpstmt, lplpSql, lpSqlNode->node.scalar.Arguments,
|
|
fIsGroupby, fCaseSensitive,
|
|
idxNodeTableOuterJoinFromTables,
|
|
idxEnclosingStatement);
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
|
|
/* Look for correct entry for the function */
|
|
while (TRUE) {
|
|
|
|
/* See if datatypes of arguments match */
|
|
idxValues = lpSqlNode->node.scalar.Arguments;
|
|
err = ERR_SUCCESS;
|
|
for (idx = 0; idx < lpScalarFunc->argCount; idx++) {
|
|
|
|
/* Error if not enough arguments */
|
|
if (idxValues == NO_SQLNODE) {
|
|
err = ERR_SCALARBADARG;
|
|
break;
|
|
}
|
|
|
|
/* Error if a parameter */
|
|
lpSqlNodeValues = ToNode(*lplpSql, idxValues);
|
|
lpSqlNodeValue = ToNode(*lplpSql,
|
|
lpSqlNodeValues->node.values.Value);
|
|
if (lpSqlNodeValue->sqlNodeType == NODE_TYPE_PARAMETER)
|
|
return ERR_UNKNOWNTYPE;
|
|
|
|
/* Error if NULL specified */
|
|
if (lpSqlNodeValue->sqlNodeType == NODE_TYPE_NULL) {
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
|
|
/* Error if long value specified */
|
|
if ((lpSqlNodeValue->sqlSqlType == SQL_LONGVARCHAR) ||
|
|
(lpSqlNodeValue->sqlSqlType == SQL_LONGVARBINARY)) {
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
|
|
/* Check the argument type */
|
|
if (lpScalarFunc->argType[idx] != TYPE_UNKNOWN) {
|
|
if (lpSqlNodeValue->sqlDataType !=
|
|
lpScalarFunc->argType[idx]) {
|
|
err = ERR_SCALARBADARG;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Check the next argument */
|
|
idxValues = lpSqlNodeValues->node.values.Next;
|
|
}
|
|
|
|
/* If this entry matches, leave the loop. */
|
|
if ((idxValues == NO_SQLNODE) && (err == ERR_SUCCESS))
|
|
break;
|
|
|
|
/* Point at the next function */
|
|
(lpSqlNode->node.scalar.Id)++;
|
|
|
|
/* If no more entries match this function name, error */
|
|
lpScalarFunc = &(scalarFuncs[lpSqlNode->node.scalar.Id]);
|
|
if (s_lstrcmpi(lpScalarFunc->name,
|
|
ToString(*lplpSql, lpSqlNode->node.scalar.Function))) {
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
}
|
|
|
|
/* Get pointer to first argument */
|
|
if (lpScalarFunc->argCount > 0) {
|
|
lpSqlNodeValues = ToNode(*lplpSql, lpSqlNode->node.scalar.Arguments);
|
|
lpSqlNodeValue = ToNode(*lplpSql, lpSqlNodeValues->node.values.Value);
|
|
}
|
|
else {
|
|
lpSqlNodeValues = NULL;
|
|
lpSqlNodeValue = NULL;
|
|
}
|
|
|
|
/* Convert function? */
|
|
if (lpSqlNode->node.scalar.Id != SCALAR_CONVERT) {
|
|
|
|
/* No. Set data type, SQL type, precision, scale */
|
|
lpSqlNode->sqlDataType = lpScalarFunc->dataType;
|
|
lpSqlNode->sqlSqlType = lpScalarFunc->sqlType;
|
|
lpSqlNode->sqlPrecision = lpScalarFunc->precision;
|
|
lpSqlNode->sqlScale = lpScalarFunc->scale;
|
|
|
|
/* Inherit SQL type, precision, scale as need be */
|
|
if (lpSqlNode->sqlSqlType == SQL_TYPE_NULL)
|
|
lpSqlNode->sqlSqlType = lpSqlNodeValue->sqlSqlType;
|
|
if (lpSqlNode->sqlPrecision == 0) {
|
|
lpSqlNode->sqlPrecision = lpSqlNodeValue->sqlPrecision;
|
|
lpSqlNode->sqlScale = lpSqlNodeValue->sqlScale;
|
|
}
|
|
}
|
|
else {
|
|
|
|
/* Yes. Set up resultant type */
|
|
if (!s_lstrcmpi(lpstrType, "SQL_BIGINT")) {
|
|
lpSqlNode->sqlDataType = TYPE_NUMERIC;
|
|
lpSqlNode->sqlSqlType = SQL_BIGINT;
|
|
switch (lpSqlNodeValue->sqlDataType) {
|
|
case TYPE_INTEGER:
|
|
case TYPE_NUMERIC:
|
|
lpSqlNode->sqlPrecision = lpSqlNodeValue->sqlPrecision;
|
|
break;
|
|
case TYPE_DOUBLE:
|
|
lpSqlNode->sqlPrecision = lpSqlNodeValue->sqlPrecision;
|
|
break;
|
|
case TYPE_CHAR:
|
|
lpSqlNode->sqlPrecision = 20;
|
|
break;
|
|
case TYPE_BINARY:
|
|
lpSqlNode->sqlPrecision = lpSqlNodeValue->sqlPrecision;
|
|
break;
|
|
case TYPE_TIME:
|
|
case TYPE_DATE:
|
|
case TYPE_TIMESTAMP:
|
|
return ERR_NOTCONVERTABLE;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
lpSqlNode->sqlScale = 0;
|
|
}
|
|
else if (!s_lstrcmpi(lpstrType, "SQL_BINARY") ||
|
|
!s_lstrcmpi(lpstrType, "SQL_VARBINARY")) {
|
|
lpSqlNode->sqlDataType = TYPE_BINARY;
|
|
if (!s_lstrcmpi(lpstrType, "SQL_BINARY"))
|
|
lpSqlNode->sqlSqlType = SQL_BINARY;
|
|
else
|
|
lpSqlNode->sqlSqlType = SQL_VARBINARY;
|
|
switch (lpSqlNodeValue->sqlSqlType) {
|
|
case SQL_DECIMAL:
|
|
case SQL_NUMERIC:
|
|
case SQL_BIGINT:
|
|
if (lpSqlNodeValue->sqlScale == 0)
|
|
lpSqlNode->sqlPrecision = lpSqlNodeValue->sqlPrecision+2;
|
|
else
|
|
lpSqlNode->sqlPrecision = lpSqlNodeValue->sqlPrecision+1;
|
|
break;
|
|
case SQL_TINYINT:
|
|
lpSqlNode->sqlPrecision = sizeof(char);
|
|
break;
|
|
case SQL_SMALLINT:
|
|
lpSqlNode->sqlPrecision = sizeof(short);
|
|
break;
|
|
case SQL_INTEGER:
|
|
lpSqlNode->sqlPrecision = sizeof(long);
|
|
break;
|
|
case SQL_BIT:
|
|
lpSqlNode->sqlPrecision = sizeof(unsigned char);
|
|
break;
|
|
case SQL_REAL:
|
|
lpSqlNode->sqlPrecision = sizeof(float);
|
|
break;
|
|
case SQL_FLOAT:
|
|
case SQL_DOUBLE:
|
|
lpSqlNode->sqlPrecision = sizeof(double);
|
|
break;
|
|
case SQL_CHAR:
|
|
case SQL_VARCHAR:
|
|
lpSqlNode->sqlPrecision = lpSqlNodeValue->sqlPrecision;
|
|
break;
|
|
case SQL_LONGVARCHAR:
|
|
return ERR_NOTSUPPORTED;
|
|
case SQL_BINARY:
|
|
case SQL_VARBINARY:
|
|
lpSqlNode->sqlPrecision = lpSqlNodeValue->sqlPrecision;
|
|
break;
|
|
case SQL_LONGVARBINARY:
|
|
return ERR_NOTSUPPORTED;
|
|
case SQL_DATE:
|
|
lpSqlNode->sqlPrecision = sizeof(DATE_STRUCT);
|
|
break;
|
|
case SQL_TIME:
|
|
lpSqlNode->sqlPrecision = sizeof(TIME_STRUCT);
|
|
break;
|
|
case SQL_TIMESTAMP:
|
|
lpSqlNode->sqlPrecision = sizeof(TIMESTAMP_STRUCT);
|
|
break;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
lpSqlNode->sqlScale = NO_SCALE;
|
|
}
|
|
else if (!s_lstrcmpi(lpstrType, "SQL_BIT")) {
|
|
lpSqlNode->sqlDataType = TYPE_INTEGER;
|
|
lpSqlNode->sqlSqlType = SQL_BIT;
|
|
lpSqlNode->sqlPrecision = 1;
|
|
lpSqlNode->sqlScale = 0;
|
|
}
|
|
else if (!s_lstrcmpi(lpstrType, "SQL_CHAR") ||
|
|
!s_lstrcmpi(lpstrType, "SQL_VARCHAR")) {
|
|
lpSqlNode->sqlDataType = TYPE_CHAR;
|
|
if (!s_lstrcmpi(lpstrType, "SQL_CHAR"))
|
|
lpSqlNode->sqlSqlType = SQL_CHAR;
|
|
else
|
|
lpSqlNode->sqlSqlType = SQL_VARCHAR;
|
|
switch (lpSqlNodeValue->sqlSqlType) {
|
|
case SQL_DECIMAL:
|
|
case SQL_NUMERIC:
|
|
case SQL_BIGINT:
|
|
if (lpSqlNodeValue->sqlScale == 0)
|
|
lpSqlNode->sqlPrecision = lpSqlNodeValue->sqlPrecision+2;
|
|
else
|
|
lpSqlNode->sqlPrecision = lpSqlNodeValue->sqlPrecision+1;
|
|
break;
|
|
case SQL_TINYINT:
|
|
lpSqlNode->sqlPrecision = 4;
|
|
break;
|
|
case SQL_SMALLINT:
|
|
lpSqlNode->sqlPrecision = 6;
|
|
break;
|
|
case SQL_INTEGER:
|
|
lpSqlNode->sqlPrecision = 11;
|
|
break;
|
|
case SQL_BIT:
|
|
lpSqlNode->sqlPrecision = 1;
|
|
break;
|
|
case SQL_REAL:
|
|
lpSqlNode->sqlPrecision = 13;
|
|
break;
|
|
case SQL_FLOAT:
|
|
case SQL_DOUBLE:
|
|
lpSqlNode->sqlPrecision = 22;
|
|
break;
|
|
case SQL_CHAR:
|
|
case SQL_VARCHAR:
|
|
lpSqlNode->sqlPrecision = lpSqlNodeValue->sqlPrecision;
|
|
break;
|
|
case SQL_LONGVARCHAR:
|
|
return ERR_NOTSUPPORTED;
|
|
case SQL_BINARY:
|
|
case SQL_VARBINARY:
|
|
lpSqlNode->sqlPrecision = lpSqlNodeValue->sqlPrecision * 2;
|
|
if (lpSqlNode->sqlPrecision >= MAX_CHAR_LITERAL_LENGTH)
|
|
lpSqlNode->sqlPrecision = MAX_CHAR_LITERAL_LENGTH;
|
|
break;
|
|
case SQL_LONGVARBINARY:
|
|
return ERR_NOTSUPPORTED;
|
|
case SQL_DATE:
|
|
lpSqlNode->sqlPrecision = 10;
|
|
break;
|
|
case SQL_TIME:
|
|
lpSqlNode->sqlPrecision = 8;
|
|
break;
|
|
case SQL_TIMESTAMP:
|
|
if (TIMESTAMP_SCALE > 0)
|
|
lpSqlNode->sqlPrecision = 20 + TIMESTAMP_SCALE;
|
|
else
|
|
lpSqlNode->sqlPrecision = 19;
|
|
break;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
lpSqlNode->sqlScale = NO_SCALE;
|
|
}
|
|
else if (!s_lstrcmpi(lpstrType, "SQL_DATE")) {
|
|
lpSqlNode->sqlDataType = TYPE_DATE;
|
|
lpSqlNode->sqlSqlType = SQL_DATE;
|
|
lpSqlNode->sqlPrecision = 10;
|
|
lpSqlNode->sqlScale = NO_SCALE;
|
|
}
|
|
else if (!s_lstrcmpi(lpstrType, "SQL_DECIMAL")) {
|
|
lpSqlNode->sqlDataType = TYPE_NUMERIC;
|
|
lpSqlNode->sqlSqlType = SQL_DECIMAL;
|
|
switch (lpSqlNodeValue->sqlDataType) {
|
|
case TYPE_INTEGER:
|
|
case TYPE_NUMERIC:
|
|
lpSqlNode->sqlPrecision = lpSqlNodeValue->sqlPrecision;
|
|
lpSqlNode->sqlScale = lpSqlNodeValue->sqlScale;
|
|
break;
|
|
case TYPE_DOUBLE:
|
|
lpSqlNode->sqlPrecision = lpSqlNodeValue->sqlPrecision;
|
|
lpSqlNode->sqlScale = 3;
|
|
break;
|
|
case TYPE_CHAR:
|
|
lpSqlNode->sqlPrecision = 15;
|
|
lpSqlNode->sqlScale = 3;
|
|
break;
|
|
case TYPE_BINARY:
|
|
lpSqlNode->sqlPrecision = lpSqlNodeValue->sqlPrecision;
|
|
lpSqlNode->sqlScale = 3;
|
|
break;
|
|
case TYPE_TIME:
|
|
case TYPE_DATE:
|
|
case TYPE_TIMESTAMP:
|
|
return ERR_NOTCONVERTABLE;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
}
|
|
else if (!s_lstrcmpi(lpstrType, "SQL_DOUBLE")) {
|
|
lpSqlNode->sqlDataType = TYPE_DOUBLE;
|
|
lpSqlNode->sqlSqlType = SQL_DOUBLE;
|
|
lpSqlNode->sqlPrecision = 15;
|
|
lpSqlNode->sqlScale = NO_SCALE;
|
|
}
|
|
else if (!s_lstrcmpi(lpstrType, "SQL_FLOAT")) {
|
|
lpSqlNode->sqlDataType = TYPE_DOUBLE;
|
|
lpSqlNode->sqlSqlType = SQL_FLOAT;
|
|
lpSqlNode->sqlPrecision = 15;
|
|
lpSqlNode->sqlScale = NO_SCALE;
|
|
}
|
|
else if (!s_lstrcmpi(lpstrType, "SQL_INTEGER")) {
|
|
lpSqlNode->sqlDataType = TYPE_INTEGER;
|
|
lpSqlNode->sqlSqlType = SQL_INTEGER;
|
|
lpSqlNode->sqlPrecision = 10;
|
|
lpSqlNode->sqlScale = 0;
|
|
}
|
|
else if (!s_lstrcmpi(lpstrType, "SQL_LONGVARBINARY")) {
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
else if (!s_lstrcmpi(lpstrType, "SQL_LONGVARCHAR")) {
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
else if (!s_lstrcmpi(lpstrType, "SQL_NUMERIC")) {
|
|
lpSqlNode->sqlDataType = TYPE_NUMERIC;
|
|
lpSqlNode->sqlSqlType = SQL_NUMERIC;
|
|
switch (lpSqlNodeValue->sqlDataType) {
|
|
case TYPE_INTEGER:
|
|
case TYPE_NUMERIC:
|
|
lpSqlNode->sqlPrecision = lpSqlNodeValue->sqlPrecision;
|
|
lpSqlNode->sqlScale = lpSqlNodeValue->sqlScale;
|
|
break;
|
|
case TYPE_DOUBLE:
|
|
lpSqlNode->sqlPrecision = lpSqlNodeValue->sqlPrecision;
|
|
lpSqlNode->sqlScale = 3;
|
|
break;
|
|
case TYPE_CHAR:
|
|
lpSqlNode->sqlPrecision = 15;
|
|
lpSqlNode->sqlScale = 3;
|
|
break;
|
|
case TYPE_BINARY:
|
|
lpSqlNode->sqlPrecision = lpSqlNodeValue->sqlPrecision;
|
|
lpSqlNode->sqlScale = 3;
|
|
break;
|
|
case TYPE_TIME:
|
|
case TYPE_DATE:
|
|
case TYPE_TIMESTAMP:
|
|
return ERR_NOTCONVERTABLE;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
}
|
|
else if (!s_lstrcmpi(lpstrType, "SQL_REAL")) {
|
|
lpSqlNode->sqlDataType = TYPE_DOUBLE;
|
|
lpSqlNode->sqlSqlType = SQL_REAL;
|
|
lpSqlNode->sqlPrecision = 7;
|
|
lpSqlNode->sqlScale = NO_SCALE;
|
|
}
|
|
else if (!s_lstrcmpi(lpstrType, "SQL_SMALLINT")) {
|
|
lpSqlNode->sqlDataType = TYPE_INTEGER;
|
|
lpSqlNode->sqlSqlType = SQL_SMALLINT;
|
|
lpSqlNode->sqlPrecision = 5;
|
|
lpSqlNode->sqlScale = 0;
|
|
}
|
|
else if (!s_lstrcmpi(lpstrType, "SQL_TIME")) {
|
|
lpSqlNode->sqlDataType = TYPE_TIME;
|
|
lpSqlNode->sqlSqlType = SQL_TIME;
|
|
lpSqlNode->sqlPrecision = 6;
|
|
lpSqlNode->sqlScale = NO_SCALE;
|
|
}
|
|
else if (!s_lstrcmpi(lpstrType, "SQL_TIMESTAMP")) {
|
|
lpSqlNode->sqlDataType = TYPE_TIMESTAMP;
|
|
lpSqlNode->sqlSqlType = SQL_TIMESTAMP;
|
|
if (TIMESTAMP_SCALE > 0)
|
|
lpSqlNode->sqlPrecision = 20 + TIMESTAMP_SCALE;
|
|
else
|
|
lpSqlNode->sqlPrecision = 19;
|
|
lpSqlNode->sqlScale = TIMESTAMP_SCALE;
|
|
}
|
|
else if (!s_lstrcmpi(lpstrType, "SQL_TINYINT")) {
|
|
lpSqlNode->sqlDataType = TYPE_INTEGER;
|
|
lpSqlNode->sqlSqlType = SQL_TINYINT;
|
|
lpSqlNode->sqlPrecision = 3;
|
|
lpSqlNode->sqlScale = 0;
|
|
}
|
|
else {
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
}
|
|
|
|
/* Adjust the resultant type information as need be */
|
|
switch (lpSqlNode->node.scalar.Id) {
|
|
case SCALAR_ASCII:
|
|
case SCALAR_CHAR:
|
|
break;
|
|
case SCALAR_CONCAT:
|
|
lpSqlNodeValues = ToNode(*lplpSql, lpSqlNodeValues->node.values.Next);
|
|
lpSqlNodeValue = ToNode(*lplpSql, lpSqlNodeValues->node.values.Value);
|
|
lpSqlNode->sqlPrecision += (lpSqlNodeValue->sqlPrecision);
|
|
lpSqlNode->sqlPrecision = MIN(lpSqlNode->sqlPrecision,
|
|
MAX_CHAR_LITERAL_LENGTH);
|
|
break;
|
|
case SCALAR_DIFFERENCE:
|
|
case SCALAR_INSERT:
|
|
case SCALAR_LCASE:
|
|
case SCALAR_LEFT:
|
|
case SCALAR_LENGTH:
|
|
case SCALAR_LOCATE:
|
|
case SCALAR_LOCATE_START:
|
|
case SCALAR_LTRIM:
|
|
case SCALAR_REPEAT:
|
|
case SCALAR_REPLACE:
|
|
case SCALAR_RIGHT:
|
|
case SCALAR_RTRIM:
|
|
case SCALAR_SOUNDEX:
|
|
case SCALAR_SPACE:
|
|
case SCALAR_SUBSTRING:
|
|
case SCALAR_UCASE:
|
|
case SCALAR_ABS_DOUBLE:
|
|
case SCALAR_ABS_NUMERIC:
|
|
case SCALAR_ABS_INTEGER:
|
|
case SCALAR_ACOS:
|
|
case SCALAR_ASIN:
|
|
case SCALAR_ATAN:
|
|
case SCALAR_ATAN2:
|
|
case SCALAR_CEILING_DOUBLE:
|
|
case SCALAR_CEILING_NUMERIC:
|
|
case SCALAR_CEILING_INTEGER:
|
|
case SCALAR_COS:
|
|
case SCALAR_COT:
|
|
case SCALAR_DEGREES_DOUBLE:
|
|
case SCALAR_DEGREES_NUMERIC:
|
|
case SCALAR_DEGREES_INTEGER:
|
|
case SCALAR_EXP:
|
|
case SCALAR_FLOOR_DOUBLE:
|
|
case SCALAR_FLOOR_NUMERIC:
|
|
case SCALAR_FLOOR_INTEGER:
|
|
case SCALAR_LOG:
|
|
case SCALAR_LOG10:
|
|
case SCALAR_MOD:
|
|
case SCALAR_PI:
|
|
case SCALAR_POWER_DOUBLE:
|
|
case SCALAR_POWER_NUMERIC:
|
|
case SCALAR_POWER_INTEGER:
|
|
case SCALAR_RADIANS_DOUBLE:
|
|
case SCALAR_RADIANS_NUMERIC:
|
|
case SCALAR_RADIANS_INTEGER:
|
|
case SCALAR_RAND:
|
|
case SCALAR_RAND_SEED_DOUBLE:
|
|
case SCALAR_RAND_SEED_NUMERIC:
|
|
case SCALAR_RAND_SEED_INTEGER:
|
|
case SCALAR_ROUND_DOUBLE:
|
|
case SCALAR_ROUND_NUMERIC:
|
|
case SCALAR_ROUND_INTEGER:
|
|
case SCALAR_SIGN_DOUBLE:
|
|
case SCALAR_SIGN_NUMERIC:
|
|
case SCALAR_SIGN_INTEGER:
|
|
case SCALAR_SIN:
|
|
case SCALAR_SQRT:
|
|
case SCALAR_TAN:
|
|
case SCALAR_TRUNCATE_DOUBLE:
|
|
case SCALAR_TRUNCATE_NUMERIC:
|
|
case SCALAR_TRUNCATE_INTEGER:
|
|
case SCALAR_CURDATE:
|
|
case SCALAR_CURTIME:
|
|
break;
|
|
case SCALAR_DAYNAME:
|
|
switch (lpSqlNodeValue->sqlDataType) {
|
|
case TYPE_CHAR:
|
|
case TYPE_DATE:
|
|
case TYPE_TIMESTAMP:
|
|
break;
|
|
case TYPE_TIME:
|
|
case TYPE_DOUBLE:
|
|
case TYPE_NUMERIC:
|
|
case TYPE_INTEGER:
|
|
case TYPE_BINARY:
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARBADARG;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
break;
|
|
case SCALAR_DAYOFMONTH_CHAR:
|
|
case SCALAR_DAYOFMONTH_DATE:
|
|
case SCALAR_DAYOFMONTH_TIMESTAMP:
|
|
break;
|
|
case SCALAR_DAYOFWEEK:
|
|
switch (lpSqlNodeValue->sqlDataType) {
|
|
case TYPE_CHAR:
|
|
case TYPE_DATE:
|
|
case TYPE_TIMESTAMP:
|
|
break;
|
|
case TYPE_TIME:
|
|
case TYPE_DOUBLE:
|
|
case TYPE_NUMERIC:
|
|
case TYPE_INTEGER:
|
|
case TYPE_BINARY:
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARBADARG;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
break;
|
|
case SCALAR_DAYOFYEAR:
|
|
switch (lpSqlNodeValue->sqlDataType) {
|
|
case TYPE_CHAR:
|
|
case TYPE_DATE:
|
|
case TYPE_TIMESTAMP:
|
|
break;
|
|
case TYPE_TIME:
|
|
case TYPE_DOUBLE:
|
|
case TYPE_NUMERIC:
|
|
case TYPE_INTEGER:
|
|
case TYPE_BINARY:
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARBADARG;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
break;
|
|
case SCALAR_HOUR_CHAR:
|
|
case SCALAR_HOUR_TIME:
|
|
case SCALAR_HOUR_TIMESTAMP:
|
|
case SCALAR_MINUTE_CHAR:
|
|
case SCALAR_MINUTE_TIME:
|
|
case SCALAR_MINUTE_TIMESTAMP:
|
|
case SCALAR_MONTH_CHAR:
|
|
case SCALAR_MONTH_DATE:
|
|
case SCALAR_MONTH_TIMESTAMP:
|
|
case SCALAR_MONTHNAME_CHAR:
|
|
case SCALAR_MONTHNAME_DATE:
|
|
case SCALAR_MONTHNAME_TIMESTAMP:
|
|
case SCALAR_NOW:
|
|
case SCALAR_QUARTER_CHAR:
|
|
case SCALAR_QUARTER_DATE:
|
|
case SCALAR_QUARTER_TIMESTAMP:
|
|
case SCALAR_SECOND_CHAR:
|
|
case SCALAR_SECOND_TIME:
|
|
case SCALAR_SECOND_TIMESTAMP:
|
|
break;
|
|
case SCALAR_TIMESTAMPADD:
|
|
lpSqlNodeValues = ToNode(*lplpSql, lpSqlNodeValues->node.values.Next);
|
|
lpSqlNodeValue2 = ToNode(*lplpSql, lpSqlNodeValues->node.values.Value);
|
|
switch (lpSqlNodeValue2->sqlDataType) {
|
|
case TYPE_CHAR:
|
|
case TYPE_DATE:
|
|
case TYPE_TIME:
|
|
case TYPE_TIMESTAMP:
|
|
break;
|
|
case TYPE_DOUBLE:
|
|
case TYPE_NUMERIC:
|
|
case TYPE_INTEGER:
|
|
case TYPE_BINARY:
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARBADARG;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
break;
|
|
case SCALAR_TIMESTAMPDIFF:
|
|
switch (lpSqlNodeValue->sqlDataType) {
|
|
case TYPE_CHAR:
|
|
case TYPE_DATE:
|
|
case TYPE_TIME:
|
|
case TYPE_TIMESTAMP:
|
|
break;
|
|
case TYPE_DOUBLE:
|
|
case TYPE_NUMERIC:
|
|
case TYPE_INTEGER:
|
|
case TYPE_BINARY:
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARBADARG;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
lpSqlNodeValues = ToNode(*lplpSql, lpSqlNodeValues->node.values.Next);
|
|
lpSqlNodeValue2 = ToNode(*lplpSql, lpSqlNodeValues->node.values.Value);
|
|
switch (lpSqlNodeValue2->sqlDataType) {
|
|
case TYPE_CHAR:
|
|
case TYPE_DATE:
|
|
case TYPE_TIME:
|
|
case TYPE_TIMESTAMP:
|
|
break;
|
|
case TYPE_DOUBLE:
|
|
case TYPE_NUMERIC:
|
|
case TYPE_INTEGER:
|
|
case TYPE_BINARY:
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARBADARG;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
break;
|
|
case SCALAR_WEEK:
|
|
switch (lpSqlNodeValue->sqlDataType) {
|
|
case TYPE_CHAR:
|
|
case TYPE_DATE:
|
|
case TYPE_TIMESTAMP:
|
|
break;
|
|
case TYPE_TIME:
|
|
case TYPE_DOUBLE:
|
|
case TYPE_NUMERIC:
|
|
case TYPE_INTEGER:
|
|
case TYPE_BINARY:
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return ERR_SCALARBADARG;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
break;
|
|
case SCALAR_YEAR_CHAR:
|
|
case SCALAR_YEAR_DATE:
|
|
case SCALAR_YEAR_TIMESTAMP:
|
|
case SCALAR_DATABASE:
|
|
break;
|
|
case SCALAR_IFNULL:
|
|
lpSqlNodeValues = ToNode(*lplpSql, lpSqlNodeValues->node.values.Next);
|
|
lpSqlNodeValue2 = ToNode(*lplpSql, lpSqlNodeValues->node.values.Value);
|
|
err = ScalarIfNullType(lpSqlNodeValue, lpSqlNodeValue2, lpSqlNode);
|
|
if (err != ERR_SUCCESS) {
|
|
if (err == ERR_SCALARBADARG)
|
|
s_lstrcpy(lpstmt->szError, lpszFunction);
|
|
return err;
|
|
}
|
|
break;
|
|
case SCALAR_USER:
|
|
break;
|
|
case SCALAR_CONVERT:
|
|
break;
|
|
}
|
|
|
|
return ERR_SUCCESS;
|
|
}
|
|
/***************************************************************************/
|
|
SWORD INTFUNC StringLocate(LPUSTR lpstrSearchString, LPUSTR lpstrString,
|
|
SWORD start)
|
|
{
|
|
SWORD lenString;
|
|
SWORD lenSearchString;
|
|
SWORD idx;
|
|
|
|
/* Get the length of the strings */
|
|
lenString = (SWORD) s_lstrlen(lpstrString);
|
|
lenSearchString = (SWORD) s_lstrlen(lpstrSearchString);
|
|
|
|
/* If the search string is no bigger than the string, and the starting */
|
|
/* location is within the string... */
|
|
if ((lenSearchString <= lenString) && (start <= lenString)) {
|
|
|
|
/* Look at each possible starting location until string is found */
|
|
for (start--; start < lenString - lenSearchString + 1; start++) {
|
|
|
|
/* See if the strings are equal */
|
|
for (idx = 0; idx < lenSearchString; idx++) {
|
|
if (lpstrString[start+idx] != lpstrSearchString[idx])
|
|
break;
|
|
}
|
|
|
|
/* Are they equal? */
|
|
if (idx == lenSearchString) {
|
|
|
|
/* Yes. Return it */
|
|
return (start + 1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Search string not found */
|
|
return 0;
|
|
}
|
|
/***************************************************************************/
|
|
RETCODE INTFUNC MakeDate(LPSQLNODE lpSqlNode, struct tm *lpTs)
|
|
{
|
|
DATE_STRUCT date;
|
|
RETCODE err;
|
|
|
|
switch(lpSqlNode->sqlDataType) {
|
|
case TYPE_CHAR:
|
|
err = CharToDate(lpSqlNode->value.String,
|
|
s_lstrlen(lpSqlNode->value.String), &date);
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
break;
|
|
case TYPE_DOUBLE:
|
|
case TYPE_NUMERIC:
|
|
case TYPE_INTEGER:
|
|
return ERR_INTERNAL;
|
|
case TYPE_DATE:
|
|
date = lpSqlNode->value.Date;
|
|
break;
|
|
case TYPE_TIME:
|
|
return ERR_INTERNAL;
|
|
case TYPE_TIMESTAMP:
|
|
date.month = lpSqlNode->value.Timestamp.month;
|
|
date.day = lpSqlNode->value.Timestamp.day;
|
|
date.year = lpSqlNode->value.Timestamp.year;
|
|
break;
|
|
case TYPE_BINARY:
|
|
return ERR_INTERNAL;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
lpTs->tm_mon = date.month - 1;
|
|
lpTs->tm_mday = date.day;
|
|
lpTs->tm_year = date.year - 1900;
|
|
lpTs->tm_hour = 0;
|
|
lpTs->tm_min = 0;
|
|
lpTs->tm_sec = 0;
|
|
lpTs->tm_isdst = 0;
|
|
if (mktime(lpTs) == -1)
|
|
return ERR_NOTCONVERTABLE;
|
|
if (lpTs->tm_isdst != 0) {
|
|
lpTs->tm_mon = date.month - 1;
|
|
lpTs->tm_mday = date.day;
|
|
lpTs->tm_year = date.year - 1900;
|
|
lpTs->tm_hour = 0;
|
|
lpTs->tm_min = 0;
|
|
lpTs->tm_sec = 0;
|
|
lpTs->tm_isdst = 1;
|
|
if (mktime(lpTs) == -1)
|
|
return ERR_NOTCONVERTABLE;
|
|
}
|
|
return ERR_SUCCESS;
|
|
}
|
|
/***************************************************************************/
|
|
RETCODE INTFUNC MakeTimestamp(LPSQLNODE lpSqlNode, struct tm *lpTs,
|
|
time_t *lpT)
|
|
{
|
|
TIMESTAMP_STRUCT timestamp;
|
|
RETCODE err;
|
|
|
|
switch(lpSqlNode->sqlDataType) {
|
|
case TYPE_CHAR:
|
|
err = CharToTimestamp(lpSqlNode->value.String,
|
|
s_lstrlen(lpSqlNode->value.String), ×tamp);
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
break;
|
|
case TYPE_DOUBLE:
|
|
case TYPE_NUMERIC:
|
|
case TYPE_INTEGER:
|
|
return ERR_INTERNAL;
|
|
case TYPE_DATE:
|
|
timestamp.month = lpSqlNode->value.Date.month;
|
|
timestamp.day = lpSqlNode->value.Date.day;
|
|
timestamp.year = lpSqlNode->value.Date.year;
|
|
timestamp.hour = 0;
|
|
timestamp.minute = 0;
|
|
timestamp.second = 0;
|
|
timestamp.fraction = 0;
|
|
break;
|
|
case TYPE_TIME:
|
|
time(lpT);
|
|
lpTs = localtime(lpT);
|
|
timestamp.month = lpTs->tm_mon + 1;
|
|
timestamp.day = (UWORD) lpTs->tm_mday;
|
|
timestamp.year = lpTs->tm_year + 1900;
|
|
timestamp.hour = lpSqlNode->value.Time.hour;
|
|
timestamp.minute = lpSqlNode->value.Time.minute;
|
|
timestamp.second = lpSqlNode->value.Time.second;
|
|
timestamp.fraction = 0;
|
|
break;
|
|
case TYPE_TIMESTAMP:
|
|
timestamp = lpSqlNode->value.Timestamp;
|
|
break;
|
|
case TYPE_BINARY:
|
|
return ERR_INTERNAL;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
lpTs->tm_mon = timestamp.month - 1;
|
|
lpTs->tm_mday = timestamp.day;
|
|
lpTs->tm_year = timestamp.year - 1900;
|
|
lpTs->tm_hour = timestamp.hour;
|
|
lpTs->tm_min = timestamp.minute;
|
|
lpTs->tm_sec = timestamp.second;
|
|
lpTs->tm_isdst = 0;
|
|
*lpT = mktime(lpTs);
|
|
if (*lpT == -1)
|
|
return ERR_NOTCONVERTABLE;
|
|
if (lpTs->tm_isdst != 0) {
|
|
lpTs->tm_mon = timestamp.month - 1;
|
|
lpTs->tm_mday = timestamp.day;
|
|
lpTs->tm_year = timestamp.year - 1900;
|
|
lpTs->tm_hour = timestamp.hour;
|
|
lpTs->tm_min = timestamp.minute;
|
|
lpTs->tm_sec = timestamp.second;
|
|
lpTs->tm_isdst = 1;
|
|
*lpT = mktime(lpTs);
|
|
if (*lpT == -1)
|
|
return ERR_NOTCONVERTABLE;
|
|
}
|
|
return ERR_SUCCESS;
|
|
}
|
|
/***************************************************************************/
|
|
#define MAXSOUNDEX 30
|
|
|
|
void INTFUNC soundex(LPUSTR in_str, LPUSTR out_str)
|
|
{
|
|
UCHAR sdex[MAXSOUNDEX+1];
|
|
const UCHAR soundex_table[] = "ABCDABCAACCLMMABCRCDABACAC";
|
|
/* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
|
|
|
|
UWORD val;
|
|
UWORD inpos;
|
|
UWORD outpos;
|
|
UWORD inlength;
|
|
UCHAR thischar;
|
|
UCHAR lastchar;
|
|
|
|
|
|
AnsiUpper((LPSTR) in_str);
|
|
inpos = 0;
|
|
outpos = 0;
|
|
lastchar = '0';
|
|
inlength = (UWORD) s_lstrlen(in_str);
|
|
|
|
while ((inpos < inlength) && (outpos < MAXSOUNDEX)) {
|
|
thischar = in_str[inpos];
|
|
if ((thischar >= 'A') && (thischar <= 'Z')) {
|
|
val = thischar - 'A';
|
|
if (inpos == 0) {
|
|
sdex[0] = thischar;
|
|
inpos++;
|
|
outpos++;
|
|
lastchar = soundex_table[val];
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
val = 0;
|
|
thischar = soundex_table[val];
|
|
if (lastchar == thischar) {
|
|
inpos++;
|
|
continue;
|
|
}
|
|
sdex[outpos] = thischar;
|
|
outpos++;
|
|
lastchar = thischar;
|
|
inpos++;
|
|
}
|
|
sdex[outpos] = '\0';
|
|
s_lstrcpy(out_str, sdex);
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
SDWORD INTFUNC soundexDifference(LPUSTR str1, LPUSTR str2)
|
|
{
|
|
UCHAR sdex1[MAXSOUNDEX+1];
|
|
UCHAR sdex2[MAXSOUNDEX+1];
|
|
|
|
soundex(str1, sdex1);
|
|
soundex(str2, sdex2);
|
|
return (SDWORD) ((sdex1[0]-sdex2[0])*10000000 +
|
|
(sdex1[1]-sdex2[1])*100000 +
|
|
(sdex1[2]-sdex2[2])*1000 +
|
|
(sdex1[3]-sdex2[3])*10 +
|
|
s_lstrcmp(sdex1+4,sdex2+4));
|
|
}
|
|
/***************************************************************************/
|
|
RETCODE INTFUNC InternalEvaluateScalar(LPSTMT lpstmt, LPSQLNODE lpSqlNode)
|
|
{
|
|
LPSCALARFUNC lpScalarFunc;
|
|
UWORD idx;
|
|
LPUSTR lpFrom;
|
|
LPUSTR lpTo;
|
|
UCHAR nibble;
|
|
SQLNODEIDX idxValues;
|
|
LPSQLNODE lpSqlNodeValues;
|
|
LPSQLNODE lpSqlNodeValue[MAX_SCALAR_ARGS];
|
|
LPSQLNODE lpSqlNodeReturnValue;
|
|
RETCODE err;
|
|
LPUSTR lpstr1;
|
|
LPUSTR lpstr2;
|
|
LPUSTR lpstr3;
|
|
LPUSTR lpstr4;
|
|
SWORD sw1;
|
|
SWORD sw2;
|
|
SWORD sw3;
|
|
SWORD sw4;
|
|
UCHAR szBuffer[MAX_CHAR_LITERAL_LENGTH+1];
|
|
SWORD location;
|
|
SWORD length;
|
|
double dbl;
|
|
double power;
|
|
char chr;
|
|
unsigned char uchr;
|
|
long lng;
|
|
short shrt;
|
|
float flt;
|
|
BOOL fFractionalPart;
|
|
SQLNODE sqlNode;
|
|
#ifdef WIN32
|
|
struct tm ts;
|
|
struct tm ts2;
|
|
time_t t;
|
|
time_t t2;
|
|
#else
|
|
static struct tm ts;
|
|
static struct tm ts2;
|
|
static time_t t;
|
|
static time_t t2;
|
|
#endif
|
|
struct tm *lpTs;
|
|
DATE_STRUCT sDate;
|
|
TIME_STRUCT sTime;
|
|
long seed1;
|
|
long seed2;
|
|
long seed3;
|
|
|
|
/* For each argument... */
|
|
lpScalarFunc = &(scalarFuncs[lpSqlNode->node.scalar.Id]);
|
|
idxValues = lpSqlNode->node.scalar.Arguments;
|
|
for (idx = 0; idx < lpScalarFunc->argCount; idx++) {
|
|
|
|
/* Get value of the argument */
|
|
lpSqlNodeValues = ToNode(lpstmt->lpSqlStmt, idxValues);
|
|
lpSqlNodeValue[idx] = ToNode(lpstmt->lpSqlStmt,
|
|
lpSqlNodeValues->node.values.Value);
|
|
err = EvaluateExpression(lpstmt, lpSqlNodeValue[idx]);
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
|
|
/* If argument is null, the result is null */
|
|
if (lpSqlNode->node.scalar.Id != SCALAR_IFNULL) {
|
|
if (lpSqlNodeValue[idx]->sqlIsNull) {
|
|
lpSqlNode->sqlIsNull = TRUE;
|
|
switch (lpSqlNode->sqlDataType) {
|
|
case TYPE_DOUBLE:
|
|
lpSqlNode->value.Double = 0.0;
|
|
break;
|
|
case TYPE_NUMERIC:
|
|
s_lstrcpy(lpSqlNode->value.String, "");
|
|
break;
|
|
case TYPE_INTEGER:
|
|
lpSqlNode->value.Double = 0.0;
|
|
break;
|
|
case TYPE_CHAR:
|
|
s_lstrcpy(lpSqlNode->value.String, "");
|
|
break;
|
|
case TYPE_BINARY:
|
|
BINARY_LENGTH(lpSqlNode->value.Binary) = 0;
|
|
break;
|
|
case TYPE_DATE:
|
|
lpSqlNode->value.Date.year = 0;
|
|
lpSqlNode->value.Date.month = 0;
|
|
lpSqlNode->value.Date.day = 0;
|
|
break;
|
|
case TYPE_TIME:
|
|
lpSqlNode->value.Time.hour = 0;
|
|
lpSqlNode->value.Time.minute = 0;
|
|
lpSqlNode->value.Time.second = 0;
|
|
break;
|
|
case TYPE_TIMESTAMP:
|
|
lpSqlNode->value.Timestamp.year = 0;
|
|
lpSqlNode->value.Timestamp.month = 0;
|
|
lpSqlNode->value.Timestamp.day = 0;
|
|
lpSqlNode->value.Timestamp.hour = 0;
|
|
lpSqlNode->value.Timestamp.minute = 0;
|
|
lpSqlNode->value.Timestamp.second = 0;
|
|
lpSqlNode->value.Timestamp.fraction = 0;
|
|
break;
|
|
}
|
|
return ERR_SUCCESS;
|
|
}
|
|
}
|
|
|
|
idxValues = lpSqlNodeValues->node.values.Next;
|
|
}
|
|
|
|
/* Do the function */
|
|
lpSqlNode->sqlIsNull = FALSE;
|
|
switch (lpSqlNode->node.scalar.Id) {
|
|
case SCALAR_ASCII:
|
|
lpSqlNode->value.Double =
|
|
(double) lpSqlNodeValue[0]->value.String[0];
|
|
break;
|
|
case SCALAR_CHAR:
|
|
lpSqlNode->value.String[0] = (UCHAR) lpSqlNodeValue[0]->value.Double;
|
|
lpSqlNode->value.String[1] = '\0';
|
|
break;
|
|
case SCALAR_CONCAT:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
lpstr2 = lpSqlNodeValue[1]->value.String;
|
|
if ((s_lstrlen(lpstr1) + s_lstrlen(lpstr2)) > lpSqlNode->sqlPrecision)
|
|
return ERR_CONCATOVERFLOW;
|
|
s_lstrcpy(lpSqlNode->value.String, lpstr1);
|
|
s_lstrcat(lpSqlNode->value.String, lpstr2);
|
|
break;
|
|
case SCALAR_DIFFERENCE:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
lpstr2 = lpSqlNodeValue[1]->value.String;
|
|
lpSqlNode->value.Double = soundexDifference(lpstr1, lpstr2);
|
|
break;
|
|
case SCALAR_INSERT:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
sw2 = (SWORD) lpSqlNodeValue[1]->value.Double;
|
|
sw3 = (SWORD) lpSqlNodeValue[2]->value.Double;
|
|
lpstr4 = lpSqlNodeValue[3]->value.String;
|
|
if ((sw2 < 0) || (sw3 < 0)) {
|
|
s_lstrcpy(lpstmt->szError, lpScalarFunc->name);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
sw1 = (SWORD) s_lstrlen(lpstr1);
|
|
if (sw1 < sw2) {
|
|
s_lstrcpy(lpstmt->szError, lpScalarFunc->name);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
if (sw3 > (sw1 - sw2 + 1))
|
|
sw3 = sw1 - sw2 + 1;
|
|
sw4 = (SWORD) s_lstrlen(lpstr4);
|
|
if ((sw1 - sw3 + sw4) > MAX_CHAR_LITERAL_LENGTH) {
|
|
s_lstrcpy(lpstmt->szError, lpScalarFunc->name);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
s_lstrcpy(lpSqlNode->value.String, lpstr1);
|
|
lpSqlNode->value.String[sw2-1] = '\0';
|
|
s_lstrcat(lpSqlNode->value.String, lpstr4);
|
|
s_lstrcat(lpSqlNode->value.String, lpstr1 + sw2 + sw3 - 1);
|
|
break;
|
|
case SCALAR_LCASE:
|
|
s_lstrcpy(lpSqlNode->value.String, lpSqlNodeValue[0]->value.String);
|
|
AnsiLower((LPSTR) lpSqlNode->value.String);
|
|
break;
|
|
case SCALAR_LEFT:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
sw2 = (SWORD) lpSqlNodeValue[1]->value.Double;
|
|
if (sw2 < 0) {
|
|
s_lstrcpy(lpstmt->szError, lpScalarFunc->name);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
s_lstrcpy(lpSqlNode->value.String, lpstr1);
|
|
if (sw2 < s_lstrlen(lpstr1))
|
|
lpSqlNode->value.String[sw2] = '\0';
|
|
break;
|
|
case SCALAR_LENGTH:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
sw1 = (SWORD) s_lstrlen(lpstr1);
|
|
while ((sw1 > 0) && (lpstr1[sw1 - 1] == ' '))
|
|
sw1--;
|
|
lpSqlNode->value.Double = sw1;
|
|
break;
|
|
case SCALAR_LOCATE:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
lpstr2 = lpSqlNodeValue[1]->value.String;
|
|
sw3 = 1;
|
|
lpSqlNode->value.Double = StringLocate(lpstr1, lpstr2, 1);
|
|
break;
|
|
case SCALAR_LOCATE_START:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
lpstr2 = lpSqlNodeValue[1]->value.String;
|
|
sw3 = (SWORD) lpSqlNodeValue[2]->value.Double;
|
|
if (sw3 <= 0) {
|
|
s_lstrcpy(lpstmt->szError, lpScalarFunc->name);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
lpSqlNode->value.Double = StringLocate(lpstr1, lpstr2, sw3);
|
|
break;
|
|
case SCALAR_LTRIM:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
sw1 = 0;
|
|
while (lpstr1[sw1] == ' ')
|
|
sw1++;
|
|
s_lstrcpy(lpSqlNode->value.String, lpstr1 + sw1);
|
|
break;
|
|
case SCALAR_REPEAT:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
sw2 = (SWORD) lpSqlNodeValue[1]->value.Double;
|
|
if ((sw2 < 0) || ((sw2 * s_lstrlen(lpstr1)) > MAX_CHAR_LITERAL_LENGTH)) {
|
|
s_lstrcpy(lpstmt->szError, lpScalarFunc->name);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
s_lstrcpy(lpSqlNode->value.String, "");
|
|
while (sw2 > 0) {
|
|
s_lstrcat(lpSqlNode->value.String, lpstr1);
|
|
sw2--;
|
|
}
|
|
break;
|
|
case SCALAR_REPLACE:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
lpstr2 = lpSqlNodeValue[1]->value.String;
|
|
lpstr3 = lpSqlNodeValue[2]->value.String;
|
|
if (s_lstrlen(lpstr2) == 0) {
|
|
s_lstrcpy(lpstmt->szError, lpScalarFunc->name);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
s_lstrcpy(lpSqlNode->value.String, lpstr1);
|
|
if (!s_lstrcmp(lpstr2, lpstr3))
|
|
break;
|
|
while (TRUE) {
|
|
location = StringLocate(lpstr2, lpSqlNode->value.String, 1);
|
|
if (location == 0)
|
|
break;
|
|
if ((s_lstrlen(lpSqlNode->value.String) - s_lstrlen(lpstr2) +
|
|
s_lstrlen(lpstr3)) > MAX_CHAR_LITERAL_LENGTH) {
|
|
s_lstrcpy(lpstmt->szError, lpScalarFunc->name);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
s_lstrcpy(szBuffer, lpSqlNode->value.String);
|
|
lpSqlNode->value.String[location-1] = '\0';
|
|
s_lstrcat(lpSqlNode->value.String, lpstr3);
|
|
s_lstrcat(lpSqlNode->value.String,
|
|
szBuffer + location + s_lstrlen(lpstr2) - 1);
|
|
}
|
|
break;
|
|
case SCALAR_RIGHT:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
sw2 = (SWORD) lpSqlNodeValue[1]->value.Double;
|
|
if (sw2 < 0) {
|
|
s_lstrcpy(lpstmt->szError, lpScalarFunc->name);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
if (sw2 > s_lstrlen(lpstr1))
|
|
sw2 = (SWORD) s_lstrlen(lpstr1);
|
|
s_lstrcpy(lpSqlNode->value.String, lpstr1 + s_lstrlen(lpstr1) - sw2);
|
|
break;
|
|
case SCALAR_RTRIM:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
s_lstrcpy(lpSqlNode->value.String, lpstr1);
|
|
sw1 = (SWORD) s_lstrlen(lpSqlNode->value.String);
|
|
while ((sw1 > 0) && (lpSqlNode->value.String[sw1-1] == ' ')) {
|
|
sw1--;
|
|
}
|
|
lpSqlNode->value.String[sw1] = '\0';
|
|
break;
|
|
case SCALAR_SOUNDEX:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
soundex(lpstr1, lpSqlNode->value.String);
|
|
break;
|
|
case SCALAR_SPACE:
|
|
sw1 = (SWORD) lpSqlNodeValue[0]->value.Double;
|
|
if ((sw1 < 0) || (sw1 > MAX_CHAR_LITERAL_LENGTH)) {
|
|
s_lstrcpy(lpstmt->szError, lpScalarFunc->name);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
s_lstrcpy(lpSqlNode->value.String, "");
|
|
while (sw1 > 0) {
|
|
s_lstrcat(lpSqlNode->value.String, " ");
|
|
sw1--;
|
|
}
|
|
break;
|
|
case SCALAR_SUBSTRING:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
sw2 = (SWORD) lpSqlNodeValue[1]->value.Double;
|
|
sw3 = (SWORD) lpSqlNodeValue[2]->value.Double;
|
|
if ((sw2 < 1) || (sw3 < 0)) {
|
|
s_lstrcpy(lpstmt->szError, lpScalarFunc->name);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
sw1 = (SWORD) s_lstrlen(lpstr1);
|
|
if (sw1 < sw2) {
|
|
s_lstrcpy(lpstmt->szError, lpScalarFunc->name);
|
|
return ERR_SCALARBADARG;
|
|
}
|
|
if (sw3 > (sw1 - sw2 + 1))
|
|
sw3 = sw1 - sw2 + 1;
|
|
s_lstrcpy(lpSqlNode->value.String, lpstr1 + sw2 - 1);
|
|
lpSqlNode->value.String[sw3] = '\0';
|
|
break;
|
|
case SCALAR_UCASE:
|
|
s_lstrcpy(lpSqlNode->value.String, lpSqlNodeValue[0]->value.String);
|
|
AnsiUpper((LPSTR) lpSqlNode->value.String);
|
|
break;
|
|
case SCALAR_ABS_DOUBLE:
|
|
if (lpSqlNodeValue[0]->value.Double >= 0.0)
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Double;
|
|
else
|
|
lpSqlNode->value.Double = -(lpSqlNodeValue[0]->value.Double);
|
|
break;
|
|
case SCALAR_ABS_NUMERIC:
|
|
if (*(lpSqlNodeValue[0]->value.String) != '-')
|
|
s_lstrcpy(lpSqlNode->value.String,lpSqlNodeValue[0]->value.String);
|
|
else
|
|
s_lstrcpy(lpSqlNode->value.String,lpSqlNodeValue[0]->value.String+1);
|
|
break;
|
|
case SCALAR_ABS_INTEGER:
|
|
if (lpSqlNodeValue[0]->value.Double >= 0.0)
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Double;
|
|
else
|
|
lpSqlNode->value.Double = -(lpSqlNodeValue[0]->value.Double);
|
|
break;
|
|
case SCALAR_ACOS:
|
|
lpSqlNode->value.Double = acos(lpSqlNodeValue[0]->value.Double);
|
|
break;
|
|
case SCALAR_ASIN:
|
|
lpSqlNode->value.Double = asin(lpSqlNodeValue[0]->value.Double);
|
|
break;
|
|
case SCALAR_ATAN:
|
|
lpSqlNode->value.Double = atan(lpSqlNodeValue[0]->value.Double);
|
|
break;
|
|
case SCALAR_ATAN2:
|
|
lpSqlNode->value.Double = atan2(lpSqlNodeValue[0]->value.Double,
|
|
lpSqlNodeValue[1]->value.Double);
|
|
break;
|
|
case SCALAR_CEILING_DOUBLE:
|
|
lpSqlNode->value.Double = ceil(lpSqlNodeValue[0]->value.Double);
|
|
break;
|
|
case SCALAR_CEILING_NUMERIC:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
sw1 = (SWORD) s_lstrlen(lpstr1);
|
|
fFractionalPart = FALSE;
|
|
for (location = 0; location < sw1; location++) {
|
|
if (lpstr1[location] == '.') {
|
|
location++;
|
|
break;
|
|
}
|
|
}
|
|
for (; location < sw1; location++) {
|
|
if (lpstr1[location] != '0') {
|
|
fFractionalPart = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if (fFractionalPart && (lpSqlNode->value.String[0] != '-')) {
|
|
sqlNode = *lpSqlNode;
|
|
sqlNode.sqlDataType = TYPE_NUMERIC;
|
|
sqlNode.sqlSqlType = SQL_NUMERIC;
|
|
sqlNode.sqlPrecision = 1;
|
|
sqlNode.sqlScale = 0;
|
|
sqlNode.sqlIsNull = FALSE;
|
|
s_lstrcpy(szBuffer, "1");
|
|
sqlNode.value.String = szBuffer;
|
|
BCDAlgebra(lpSqlNode, lpSqlNodeValue[0], OP_PLUS, &sqlNode,
|
|
NULL, NULL, NULL);
|
|
}
|
|
else {
|
|
s_lstrcpy(lpSqlNode->value.String, lpSqlNodeValue[0]->value.String);
|
|
}
|
|
if (fFractionalPart) {
|
|
for (location = 0; location < s_lstrlen(lpSqlNode->value.String);
|
|
location++) {
|
|
if (lpSqlNode->value.String[location] == '.') {
|
|
location++;
|
|
break;
|
|
}
|
|
}
|
|
for (; location < s_lstrlen(lpSqlNode->value.String); location++)
|
|
lpSqlNode->value.String[location] = '0';
|
|
}
|
|
break;
|
|
case SCALAR_CEILING_INTEGER:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Double;
|
|
break;
|
|
case SCALAR_COS:
|
|
lpSqlNode->value.Double = cos(lpSqlNodeValue[0]->value.Double);
|
|
break;
|
|
case SCALAR_COT:
|
|
lpSqlNode->value.Double = tan(lpSqlNodeValue[0]->value.Double);
|
|
if (lpSqlNode->value.Double == 0.0)
|
|
return ERR_ZERODIVIDE;
|
|
lpSqlNode->value.Double = 1.0 / lpSqlNode->value.Double;
|
|
break;
|
|
case SCALAR_DEGREES_DOUBLE:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Double *
|
|
(360.0 / (2.0 * PI));
|
|
break;
|
|
case SCALAR_DEGREES_NUMERIC:
|
|
CharToDouble(lpSqlNodeValue[0]->value.String,
|
|
s_lstrlen(lpSqlNodeValue[0]->value.String), FALSE,
|
|
DOUBLE_LOW_D, DOUBLE_HIGH_D, &dbl);
|
|
lpSqlNode->value.Double = dbl * (360.0 / (2.0 * PI));
|
|
break;
|
|
case SCALAR_DEGREES_INTEGER:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Double *
|
|
(360.0 / (2.0 * PI));
|
|
break;
|
|
case SCALAR_EXP:
|
|
lpSqlNode->value.Double = exp(lpSqlNodeValue[0]->value.Double);
|
|
break;
|
|
case SCALAR_FLOOR_DOUBLE:
|
|
lpSqlNode->value.Double = floor(lpSqlNodeValue[0]->value.Double);
|
|
break;
|
|
case SCALAR_FLOOR_NUMERIC:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
sw1 = (SWORD) s_lstrlen(lpstr1);
|
|
fFractionalPart = FALSE;
|
|
for (location = 0; location < sw1; location++) {
|
|
if (lpstr1[location] == '.') {
|
|
location++;
|
|
break;
|
|
}
|
|
}
|
|
for (; location < sw1; location++) {
|
|
if (lpstr1[location] != '0') {
|
|
fFractionalPart = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if (fFractionalPart && (lpSqlNode->value.String[0] == '-')) {
|
|
sqlNode = *lpSqlNode;
|
|
sqlNode.sqlDataType = TYPE_NUMERIC;
|
|
sqlNode.sqlSqlType = SQL_NUMERIC;
|
|
sqlNode.sqlPrecision = 1;
|
|
sqlNode.sqlScale = 0;
|
|
sqlNode.sqlIsNull = FALSE;
|
|
s_lstrcpy(szBuffer, "1");
|
|
sqlNode.value.String = szBuffer;
|
|
BCDAlgebra(lpSqlNode, lpSqlNodeValue[0], OP_MINUS, &sqlNode,
|
|
NULL, NULL, NULL);
|
|
}
|
|
else {
|
|
s_lstrcpy(lpSqlNode->value.String, lpSqlNodeValue[0]->value.String);
|
|
}
|
|
if (fFractionalPart) {
|
|
for (location = 0; location < s_lstrlen(lpSqlNode->value.String);
|
|
location++) {
|
|
if (lpSqlNode->value.String[location] == '.') {
|
|
location++;
|
|
break;
|
|
}
|
|
}
|
|
for (; location < s_lstrlen(lpSqlNode->value.String); location++)
|
|
lpSqlNode->value.String[location] = '0';
|
|
}
|
|
break;
|
|
case SCALAR_FLOOR_INTEGER:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Double;
|
|
break;
|
|
case SCALAR_LOG:
|
|
lpSqlNode->value.Double = log(lpSqlNodeValue[0]->value.Double);
|
|
break;
|
|
case SCALAR_LOG10:
|
|
lpSqlNode->value.Double = log10(lpSqlNodeValue[0]->value.Double);
|
|
break;
|
|
case SCALAR_MOD:
|
|
if (lpSqlNodeValue[1]->value.Double == 0.0)
|
|
return ERR_ZERODIVIDE;
|
|
lpSqlNode->value.Double = ((SDWORD) lpSqlNodeValue[0]->value.Double)
|
|
% ((SDWORD) lpSqlNodeValue[1]->value.Double);
|
|
break;
|
|
case SCALAR_PI:
|
|
lpSqlNode->value.Double = PI;
|
|
break;
|
|
case SCALAR_POWER_DOUBLE:
|
|
lpSqlNode->value.Double = pow(lpSqlNodeValue[0]->value.Double,
|
|
(long) lpSqlNodeValue[1]->value.Double);
|
|
break;
|
|
case SCALAR_POWER_NUMERIC:
|
|
CharToDouble(lpSqlNodeValue[0]->value.String,
|
|
s_lstrlen(lpSqlNodeValue[0]->value.String), FALSE,
|
|
DOUBLE_LOW_D, DOUBLE_HIGH_D, &dbl);
|
|
lpSqlNode->value.Double = pow(dbl,
|
|
(long) lpSqlNodeValue[1]->value.Double);
|
|
break;
|
|
case SCALAR_POWER_INTEGER:
|
|
lpSqlNode->value.Double = pow(lpSqlNodeValue[0]->value.Double,
|
|
(long) lpSqlNodeValue[1]->value.Double);
|
|
break;
|
|
case SCALAR_RADIANS_DOUBLE:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Double *
|
|
((2.0 * PI) / 360.0);
|
|
break;
|
|
case SCALAR_RADIANS_NUMERIC:
|
|
CharToDouble(lpSqlNodeValue[0]->value.String,
|
|
s_lstrlen(lpSqlNodeValue[0]->value.String), FALSE,
|
|
DOUBLE_LOW_D, DOUBLE_HIGH_D, &dbl);
|
|
lpSqlNode->value.Double = dbl * ((2.0 * PI) / 360.0);
|
|
break;
|
|
case SCALAR_RADIANS_INTEGER:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Double *
|
|
((2.0 * PI) / 360.0);
|
|
break;
|
|
|
|
case SCALAR_RAND:
|
|
case SCALAR_RAND_SEED_DOUBLE:
|
|
case SCALAR_RAND_SEED_NUMERIC:
|
|
case SCALAR_RAND_SEED_INTEGER:
|
|
|
|
/* Get seed */
|
|
switch (lpSqlNode->node.scalar.Id) {
|
|
case SCALAR_RAND:
|
|
break;
|
|
case SCALAR_RAND_SEED_DOUBLE:
|
|
if ((long) lpSqlNodeValue[0]->value.Double != 0)
|
|
new_seed = (long) lpSqlNodeValue[0]->value.Double;
|
|
break;
|
|
case SCALAR_RAND_SEED_NUMERIC:
|
|
CharToDouble(lpSqlNodeValue[0]->value.String,
|
|
s_lstrlen(lpSqlNodeValue[0]->value.String), FALSE,
|
|
DOUBLE_LOW_D, DOUBLE_HIGH_D, &dbl);
|
|
if ((long) dbl != 0)
|
|
new_seed = (long) dbl;
|
|
break;
|
|
case SCALAR_RAND_SEED_INTEGER:
|
|
if ((long) lpSqlNodeValue[0]->value.Double != 0)
|
|
new_seed = (long) lpSqlNodeValue[0]->value.Double;
|
|
break;
|
|
}
|
|
|
|
/* Make a seed if need be */
|
|
if (new_seed == 0)
|
|
new_seed = time(NULL);
|
|
|
|
/* First generator */
|
|
seed1 = new_seed + 4;
|
|
if (seed1 < 0)
|
|
seed1 = -seed1;
|
|
seed1 = (seed1 % 30000) + 1;
|
|
seed1 = (171 * (seed1 % 177)) - (2 * (seed1 / 177));
|
|
if (seed1 < 0)
|
|
seed1 += (30269);
|
|
|
|
/* Second generator */
|
|
seed2 = new_seed + 10014;
|
|
if (seed2 < 0)
|
|
seed2 = -seed2;
|
|
seed2 = (seed2 % 30000) + 1;
|
|
seed2 = (172 * (seed2 % 176))- (2 * (seed2 / 176));
|
|
if (seed2 < 0)
|
|
seed2 += (30307);
|
|
|
|
/* Third generator */
|
|
seed3 = new_seed + 3017;
|
|
if (seed3 < 0)
|
|
seed3 = -seed3;
|
|
seed3 = (seed3 % 30000) + 1;
|
|
seed3 = (170 * (seed3 % 178)) - (2 * (seed3 / 178));
|
|
if (seed3 < 0)
|
|
seed3 += (30323);
|
|
|
|
/* Compute value */
|
|
dbl = (seed1 / 30269.0) + (seed2 / 30307.0) + (seed3 / 30323.0);
|
|
dbl -= ((double) floor(dbl));
|
|
new_seed = (long) (floor(dbl * ULONG_HIGH_D));
|
|
if (new_seed == 0)
|
|
new_seed = seed1 + seed2 + seed3;
|
|
lpSqlNode->value.Double = dbl;
|
|
break;
|
|
case SCALAR_ROUND_DOUBLE:
|
|
power = pow(10, lpSqlNodeValue[1]->value.Double);
|
|
lpSqlNode->value.Double =
|
|
floor((lpSqlNodeValue[0]->value.Double * power) + 0.5) / power;
|
|
break;
|
|
case SCALAR_ROUND_NUMERIC:
|
|
power = pow(10, lpSqlNodeValue[1]->value.Double);
|
|
CharToDouble(lpSqlNodeValue[0]->value.String,
|
|
s_lstrlen(lpSqlNodeValue[0]->value.String), FALSE,
|
|
DOUBLE_LOW_D, DOUBLE_HIGH_D, &dbl);
|
|
dbl = floor((dbl * power) + 0.5) / power;
|
|
if (DoubleToChar(dbl, FALSE, lpSqlNode->value.String,
|
|
1 + 2 + lpSqlNode->sqlPrecision))
|
|
lpSqlNode->value.String[2 + lpSqlNode->sqlPrecision] = '\0';
|
|
BCDNormalize(lpSqlNode->value.String,
|
|
s_lstrlen(lpSqlNode->value.String),
|
|
lpSqlNode->value.String,
|
|
1 + 2 + lpSqlNode->sqlPrecision,
|
|
lpSqlNode->sqlPrecision,
|
|
lpSqlNode->sqlScale);
|
|
break;
|
|
case SCALAR_ROUND_INTEGER:
|
|
power = pow(10, lpSqlNodeValue[1]->value.Double);
|
|
lpSqlNode->value.Double =
|
|
floor((lpSqlNodeValue[0]->value.Double * power) + 0.5) / power;
|
|
break;
|
|
case SCALAR_SIGN_DOUBLE:
|
|
if (lpSqlNodeValue[0]->value.Double > 0)
|
|
lpSqlNode->value.Double = 1;
|
|
else if (lpSqlNodeValue[0]->value.Double == 0)
|
|
lpSqlNode->value.Double = 0;
|
|
else
|
|
lpSqlNode->value.Double = -1;
|
|
break;
|
|
case SCALAR_SIGN_NUMERIC:
|
|
switch (lpSqlNodeValue[0]->value.String[0]) {
|
|
case '\0':
|
|
lpSqlNode->value.Double = 0;
|
|
break;
|
|
case '-':
|
|
lpSqlNode->value.Double = -1;
|
|
break;
|
|
default:
|
|
lpSqlNode->value.Double = 1;
|
|
break;
|
|
}
|
|
break;
|
|
case SCALAR_SIGN_INTEGER:
|
|
if (lpSqlNodeValue[0]->value.Double > 0)
|
|
lpSqlNode->value.Double = 1;
|
|
else if (lpSqlNodeValue[0]->value.Double == 0)
|
|
lpSqlNode->value.Double = 0;
|
|
else
|
|
lpSqlNode->value.Double = -1;
|
|
break;
|
|
case SCALAR_SIN:
|
|
lpSqlNode->value.Double = sin(lpSqlNodeValue[0]->value.Double);
|
|
break;
|
|
case SCALAR_SQRT:
|
|
lpSqlNode->value.Double = sqrt(lpSqlNodeValue[0]->value.Double);
|
|
break;
|
|
case SCALAR_TAN:
|
|
lpSqlNode->value.Double = tan(lpSqlNodeValue[0]->value.Double);
|
|
break;
|
|
case SCALAR_TRUNCATE_DOUBLE:
|
|
power = pow(10, lpSqlNodeValue[1]->value.Double);
|
|
lpSqlNode->value.Double =
|
|
floor(lpSqlNodeValue[0]->value.Double * power) / power;
|
|
break;
|
|
case SCALAR_TRUNCATE_NUMERIC:
|
|
power = pow(10, lpSqlNodeValue[1]->value.Double);
|
|
CharToDouble(lpSqlNodeValue[0]->value.String,
|
|
s_lstrlen(lpSqlNodeValue[0]->value.String), FALSE,
|
|
DOUBLE_LOW_D, DOUBLE_HIGH_D, &dbl);
|
|
dbl = floor(dbl * power) / power;
|
|
if (DoubleToChar(dbl, FALSE, lpSqlNode->value.String,
|
|
1 + 2 + lpSqlNode->sqlPrecision))
|
|
lpSqlNode->value.String[2 + lpSqlNode->sqlPrecision] = '\0';
|
|
BCDNormalize(lpSqlNode->value.String,
|
|
s_lstrlen(lpSqlNode->value.String),
|
|
lpSqlNode->value.String,
|
|
1 + 2 + lpSqlNode->sqlPrecision,
|
|
lpSqlNode->sqlPrecision,
|
|
lpSqlNode->sqlScale);
|
|
break;
|
|
case SCALAR_TRUNCATE_INTEGER:
|
|
power = pow(10, lpSqlNodeValue[1]->value.Double);
|
|
lpSqlNode->value.Double =
|
|
floor(lpSqlNodeValue[0]->value.Double * power) / power;
|
|
break;
|
|
case SCALAR_CURDATE:
|
|
time(&t);
|
|
lpTs = localtime(&t);
|
|
lpSqlNode->value.Date.month = lpTs->tm_mon + 1;
|
|
lpSqlNode->value.Date.day = (UWORD) lpTs->tm_mday;
|
|
lpSqlNode->value.Date.year = lpTs->tm_year + 1900;
|
|
break;
|
|
case SCALAR_CURTIME:
|
|
time(&t);
|
|
lpTs = localtime(&t);
|
|
lpSqlNode->value.Time.hour = (UWORD) lpTs->tm_hour;
|
|
lpSqlNode->value.Time.minute = (UWORD) lpTs->tm_min;
|
|
lpSqlNode->value.Time.second = (UWORD) lpTs->tm_sec;
|
|
break;
|
|
case SCALAR_DAYNAME:
|
|
err = MakeDate(lpSqlNodeValue[0], &ts);
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
switch (ts.tm_wday) {
|
|
case 0:
|
|
LoadString(s_hModule, STR_SUNDAY, (LPSTR) lpSqlNode->value.String,
|
|
MAX_CHAR_LITERAL_LENGTH+1);
|
|
break;
|
|
case 1:
|
|
LoadString(s_hModule, STR_MONDAY, (LPSTR) lpSqlNode->value.String,
|
|
MAX_CHAR_LITERAL_LENGTH+1);
|
|
break;
|
|
case 2:
|
|
LoadString(s_hModule, STR_TUESDAY, (LPSTR) lpSqlNode->value.String,
|
|
MAX_CHAR_LITERAL_LENGTH+1);
|
|
break;
|
|
case 3:
|
|
LoadString(s_hModule, STR_WEDNESDAY, (LPSTR) lpSqlNode->value.String,
|
|
MAX_CHAR_LITERAL_LENGTH+1);
|
|
break;
|
|
case 4:
|
|
LoadString(s_hModule, STR_THURSDAY, (LPSTR) lpSqlNode->value.String,
|
|
MAX_CHAR_LITERAL_LENGTH+1);
|
|
break;
|
|
case 5:
|
|
LoadString(s_hModule, STR_FRIDAY, (LPSTR) lpSqlNode->value.String,
|
|
MAX_CHAR_LITERAL_LENGTH+1);
|
|
break;
|
|
case 6:
|
|
LoadString(s_hModule, STR_SATURDAY, (LPSTR) lpSqlNode->value.String,
|
|
MAX_CHAR_LITERAL_LENGTH+1);
|
|
break;
|
|
}
|
|
break;
|
|
case SCALAR_DAYOFMONTH_CHAR:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
err = CharToDate(lpstr1, s_lstrlen(lpstr1), &sDate);
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
lpSqlNode->value.Double = sDate.day;
|
|
break;
|
|
case SCALAR_DAYOFMONTH_DATE:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Date.day;
|
|
break;
|
|
case SCALAR_DAYOFMONTH_TIMESTAMP:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Timestamp.day;
|
|
break;
|
|
case SCALAR_DAYOFWEEK:
|
|
err = MakeDate(lpSqlNodeValue[0], &ts);
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
lpSqlNode->value.Double = ts.tm_wday + 1;
|
|
break;
|
|
case SCALAR_DAYOFYEAR:
|
|
err = MakeDate(lpSqlNodeValue[0], &ts);
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
lpSqlNode->value.Double = ts.tm_yday + 1;
|
|
break;
|
|
case SCALAR_HOUR_CHAR:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
err = CharToTime(lpstr1, s_lstrlen(lpstr1), &sTime);
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
lpSqlNode->value.Double = sTime.hour;
|
|
break;
|
|
case SCALAR_HOUR_TIME:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Time.hour;
|
|
break;
|
|
case SCALAR_HOUR_TIMESTAMP:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Timestamp.hour;
|
|
break;
|
|
case SCALAR_MINUTE_CHAR:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
err = CharToTime(lpstr1, s_lstrlen(lpstr1), &sTime);
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
lpSqlNode->value.Double = sTime.minute;
|
|
break;
|
|
case SCALAR_MINUTE_TIME:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Time.minute;
|
|
break;
|
|
case SCALAR_MINUTE_TIMESTAMP:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Timestamp.minute;
|
|
break;
|
|
case SCALAR_MONTH_CHAR:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
err = CharToDate(lpstr1, s_lstrlen(lpstr1), &sDate);
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
lpSqlNode->value.Double = sDate.month;
|
|
break;
|
|
case SCALAR_MONTH_DATE:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Date.month;
|
|
break;
|
|
case SCALAR_MONTH_TIMESTAMP:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Timestamp.month;
|
|
break;
|
|
case SCALAR_MONTHNAME_CHAR:
|
|
case SCALAR_MONTHNAME_DATE:
|
|
case SCALAR_MONTHNAME_TIMESTAMP:
|
|
switch (lpSqlNode->node.scalar.Id) {
|
|
case SCALAR_MONTHNAME_CHAR:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
err = CharToDate(lpstr1, s_lstrlen(lpstr1), &sDate);
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
break;
|
|
case SCALAR_MONTHNAME_DATE:
|
|
sDate = lpSqlNodeValue[0]->value.Date;
|
|
break;
|
|
case SCALAR_MONTHNAME_TIMESTAMP:
|
|
sDate.month = lpSqlNodeValue[0]->value.Timestamp.month;
|
|
sDate.day = lpSqlNodeValue[0]->value.Timestamp.day;
|
|
sDate.year = lpSqlNodeValue[0]->value.Timestamp.year;
|
|
break;
|
|
}
|
|
switch (sDate.month) {
|
|
case 1:
|
|
LoadString(s_hModule, STR_JANUARY, (LPSTR) lpSqlNode->value.String,
|
|
MAX_CHAR_LITERAL_LENGTH+1);
|
|
break;
|
|
case 2:
|
|
LoadString(s_hModule, STR_FEBRUARY, (LPSTR) lpSqlNode->value.String,
|
|
MAX_CHAR_LITERAL_LENGTH+1);
|
|
break;
|
|
case 3:
|
|
LoadString(s_hModule, STR_MARCH, (LPSTR) lpSqlNode->value.String,
|
|
MAX_CHAR_LITERAL_LENGTH+1);
|
|
break;
|
|
case 4:
|
|
LoadString(s_hModule, STR_APRIL, (LPSTR) lpSqlNode->value.String,
|
|
MAX_CHAR_LITERAL_LENGTH+1);
|
|
break;
|
|
case 5:
|
|
LoadString(s_hModule, STR_MAY, (LPSTR) lpSqlNode->value.String,
|
|
MAX_CHAR_LITERAL_LENGTH+1);
|
|
break;
|
|
case 6:
|
|
LoadString(s_hModule, STR_JUNE, (LPSTR) lpSqlNode->value.String,
|
|
MAX_CHAR_LITERAL_LENGTH+1);
|
|
break;
|
|
case 7:
|
|
LoadString(s_hModule, STR_JULY, (LPSTR) lpSqlNode->value.String,
|
|
MAX_CHAR_LITERAL_LENGTH+1);
|
|
break;
|
|
case 8:
|
|
LoadString(s_hModule, STR_AUGUST, (LPSTR) lpSqlNode->value.String,
|
|
MAX_CHAR_LITERAL_LENGTH+1);
|
|
break;
|
|
case 9:
|
|
LoadString(s_hModule, STR_SEPTEMBER, (LPSTR) lpSqlNode->value.String,
|
|
MAX_CHAR_LITERAL_LENGTH+1);
|
|
break;
|
|
case 10:
|
|
LoadString(s_hModule, STR_OCTOBER, (LPSTR) lpSqlNode->value.String,
|
|
MAX_CHAR_LITERAL_LENGTH+1);
|
|
break;
|
|
case 11:
|
|
LoadString(s_hModule, STR_NOVEMBER, (LPSTR) lpSqlNode->value.String,
|
|
MAX_CHAR_LITERAL_LENGTH+1);
|
|
break;
|
|
case 12:
|
|
LoadString(s_hModule, STR_DECEMBER, (LPSTR) lpSqlNode->value.String,
|
|
MAX_CHAR_LITERAL_LENGTH+1);
|
|
break;
|
|
}
|
|
break;
|
|
case SCALAR_NOW:
|
|
time(&t);
|
|
lpTs = localtime(&t);
|
|
lpSqlNode->value.Timestamp.month = lpTs->tm_mon + 1;
|
|
lpSqlNode->value.Timestamp.day = (UWORD) lpTs->tm_mday;
|
|
lpSqlNode->value.Timestamp.year = lpTs->tm_year + 1900;
|
|
lpSqlNode->value.Timestamp.hour = (UWORD) lpTs->tm_hour;
|
|
lpSqlNode->value.Timestamp.minute = (UWORD) lpTs->tm_min;
|
|
lpSqlNode->value.Timestamp.second = (UWORD) lpTs->tm_sec;
|
|
lpSqlNode->value.Timestamp.fraction = 0;
|
|
break;
|
|
case SCALAR_QUARTER_CHAR:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
err = CharToDate(lpstr1, s_lstrlen(lpstr1), &sDate);
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
lpSqlNode->value.Double = ((sDate.month - 1) / 3) + 1;
|
|
break;
|
|
case SCALAR_QUARTER_DATE:
|
|
lpSqlNode->value.Double =
|
|
((lpSqlNodeValue[0]->value.Date.month - 1) / 3) + 1;
|
|
break;
|
|
case SCALAR_QUARTER_TIMESTAMP:
|
|
lpSqlNode->value.Double =
|
|
((lpSqlNodeValue[0]->value.Timestamp.month - 1) / 3) + 1;
|
|
break;
|
|
case SCALAR_SECOND_CHAR:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
err = CharToTime(lpstr1, s_lstrlen(lpstr1), &sTime);
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
lpSqlNode->value.Double = sTime.second;
|
|
break;
|
|
case SCALAR_SECOND_TIME:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Time.second;
|
|
break;
|
|
case SCALAR_SECOND_TIMESTAMP:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Timestamp.second;
|
|
break;
|
|
case SCALAR_TIMESTAMPADD:
|
|
sw1 = (SWORD) lpSqlNodeValue[0]->value.Double;
|
|
err = MakeTimestamp(lpSqlNodeValue[1], &ts, &t);
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
switch (lpSqlNode->node.scalar.Interval) {
|
|
case SQL_TSI_SECOND:
|
|
ts.tm_sec += (sw1);
|
|
break;
|
|
case SQL_TSI_MINUTE:
|
|
ts.tm_min += (sw1);
|
|
break;
|
|
case SQL_TSI_HOUR:
|
|
ts.tm_hour += (sw1);
|
|
break;
|
|
case SQL_TSI_DAY:
|
|
ts.tm_mday += (sw1);
|
|
break;
|
|
case SQL_TSI_WEEK:
|
|
ts.tm_mday += (sw1 * 7);
|
|
break;
|
|
case SQL_TSI_MONTH:
|
|
ts.tm_mon += (sw1);
|
|
break;
|
|
case SQL_TSI_QUARTER:
|
|
ts.tm_mon += (sw1 * 3);
|
|
break;
|
|
case SQL_TSI_YEAR:
|
|
ts.tm_year += (sw1);
|
|
break;
|
|
default:
|
|
return ERR_INTERNAL;
|
|
}
|
|
if (mktime(&ts) == -1)
|
|
return ERR_NOTCONVERTABLE;
|
|
lpSqlNode->value.Timestamp.month = ts.tm_mon + 1;
|
|
lpSqlNode->value.Timestamp.day = (UWORD) ts.tm_mday;
|
|
lpSqlNode->value.Timestamp.year = ts.tm_year + 1900;
|
|
lpSqlNode->value.Timestamp.hour = (UWORD) ts.tm_hour;
|
|
lpSqlNode->value.Timestamp.minute = (UWORD) ts.tm_min;
|
|
lpSqlNode->value.Timestamp.second = (UWORD) ts.tm_sec;
|
|
lpSqlNode->value.Timestamp.fraction = 0;
|
|
break;
|
|
case SCALAR_TIMESTAMPDIFF:
|
|
err = MakeTimestamp(lpSqlNodeValue[0], &ts, &t);
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
err = MakeTimestamp(lpSqlNodeValue[1], &ts2, &t2);
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
switch (lpSqlNode->node.scalar.Interval) {
|
|
case SQL_TSI_SECOND:
|
|
lpSqlNode->value.Double = t2 - t;
|
|
break;
|
|
case SQL_TSI_MINUTE:
|
|
lpSqlNode->value.Double = (t2 - t)/SECONDS_PER_MINUTE;
|
|
break;
|
|
case SQL_TSI_HOUR:
|
|
lpSqlNode->value.Double = (t2 - t)/SECONDS_PER_HOUR;
|
|
break;
|
|
case SQL_TSI_DAY:
|
|
lpSqlNode->value.Double = (t2 - t)/SECONDS_PER_DAY;
|
|
break;
|
|
case SQL_TSI_WEEK:
|
|
lpSqlNode->value.Double = (t2 - t)/SECONDS_PER_WEEK;
|
|
break;
|
|
case SQL_TSI_MONTH:
|
|
lpSqlNode->value.Double = (ts2.tm_mon - ts.tm_mon) +
|
|
(MONTHS_PER_YEAR * (ts2.tm_year - ts.tm_year));
|
|
break;
|
|
case SQL_TSI_QUARTER:
|
|
lpSqlNode->value.Double = ((ts2.tm_mon - ts.tm_mon) +
|
|
(MONTHS_PER_YEAR * (ts2.tm_year - ts.tm_year))) / 3;
|
|
case SQL_TSI_YEAR:
|
|
lpSqlNode->value.Double = ts2.tm_year - ts.tm_year;
|
|
break;
|
|
default:
|
|
return ERR_INTERNAL;
|
|
}
|
|
break;
|
|
case SCALAR_WEEK:
|
|
err = MakeDate(lpSqlNodeValue[0], &ts);
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
while ((ts.tm_yday > 0) && (ts.tm_wday > 0)) {
|
|
ts.tm_yday--;
|
|
ts.tm_wday--;
|
|
}
|
|
lpSqlNode->value.Double = 1.0;
|
|
while (ts.tm_yday > 6) {
|
|
ts.tm_yday -= (7);
|
|
lpSqlNode->value.Double += (1.0);
|
|
}
|
|
if (ts.tm_yday != 0)
|
|
lpSqlNode->value.Double += (1.0);
|
|
break;
|
|
case SCALAR_YEAR_CHAR:
|
|
lpstr1 = lpSqlNodeValue[0]->value.String;
|
|
err = CharToDate(lpstr1, s_lstrlen(lpstr1), &sDate);
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
lpSqlNode->value.Double = sDate.year;
|
|
break;
|
|
case SCALAR_YEAR_DATE:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Date.year;
|
|
break;
|
|
case SCALAR_YEAR_TIMESTAMP:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Timestamp.year;
|
|
break;
|
|
case SCALAR_DATABASE:
|
|
s_lstrcpy(lpSqlNode->value.String, ISAMDatabase(lpstmt->lpdbc->lpISAM));
|
|
break;
|
|
case SCALAR_IFNULL:
|
|
if (lpSqlNodeValue[0]->sqlIsNull)
|
|
lpSqlNodeReturnValue = lpSqlNodeValue[1];
|
|
else
|
|
lpSqlNodeReturnValue = lpSqlNodeValue[0];
|
|
switch (lpSqlNode->sqlDataType) {
|
|
case TYPE_DOUBLE:
|
|
if (lpSqlNodeReturnValue->sqlIsNull) {
|
|
lpSqlNode->sqlIsNull = TRUE;
|
|
lpSqlNode->value.Double = 0.0;
|
|
}
|
|
else if (lpSqlNodeReturnValue->sqlDataType != TYPE_NUMERIC)
|
|
lpSqlNode->value.Double = lpSqlNodeReturnValue->value.Double;
|
|
else
|
|
CharToDouble(lpSqlNodeReturnValue->value.String,
|
|
s_lstrlen(lpSqlNodeReturnValue->value.String), FALSE,
|
|
DOUBLE_LOW_D, DOUBLE_HIGH_D, &(lpSqlNode->value.Double));
|
|
break;
|
|
case TYPE_NUMERIC:
|
|
if (lpSqlNodeReturnValue->sqlIsNull) {
|
|
lpSqlNode->sqlIsNull = TRUE;
|
|
s_lstrcpy(lpSqlNode->value.String, "");
|
|
}
|
|
else if (lpSqlNodeReturnValue->sqlDataType == TYPE_NUMERIC)
|
|
s_lstrcpy(lpSqlNode->value.String,
|
|
lpSqlNodeReturnValue->value.String);
|
|
else {
|
|
if (DoubleToChar(lpSqlNodeReturnValue->value.Double, FALSE,
|
|
lpSqlNode->value.String,
|
|
1 + 2 + lpSqlNode->sqlPrecision))
|
|
lpSqlNode->value.String[2 + lpSqlNode->sqlPrecision]='\0';
|
|
}
|
|
BCDNormalize(lpSqlNode->value.String,
|
|
s_lstrlen(lpSqlNode->value.String),
|
|
lpSqlNode->value.String,
|
|
1 + 2 + lpSqlNode->sqlPrecision,
|
|
lpSqlNode->sqlPrecision,
|
|
lpSqlNode->sqlScale);
|
|
break;
|
|
case TYPE_INTEGER:
|
|
if (lpSqlNodeReturnValue->sqlIsNull) {
|
|
lpSqlNode->sqlIsNull = TRUE;
|
|
lpSqlNode->value.Double = 0.0;
|
|
}
|
|
else
|
|
lpSqlNode->value.Double = lpSqlNodeReturnValue->value.Double;
|
|
break;
|
|
case TYPE_CHAR:
|
|
if (lpSqlNodeReturnValue->sqlIsNull) {
|
|
lpSqlNode->sqlIsNull = TRUE;
|
|
s_lstrcpy(lpSqlNode->value.String, "");
|
|
}
|
|
else {
|
|
s_lstrcpy(lpSqlNode->value.String,
|
|
lpSqlNodeReturnValue->value.String);
|
|
while ((lpSqlNode->sqlSqlType == SQL_CHAR) &&
|
|
(s_lstrlen(lpSqlNode->value.String) <
|
|
lpSqlNode->sqlPrecision))
|
|
s_lstrcat(lpSqlNode->value.String, " ");
|
|
}
|
|
break;
|
|
case TYPE_BINARY:
|
|
if (lpSqlNodeReturnValue->sqlIsNull) {
|
|
lpSqlNode->sqlIsNull = TRUE;
|
|
length = 0;
|
|
}
|
|
else {
|
|
length = (SWORD)
|
|
BINARY_LENGTH(lpSqlNodeReturnValue->value.Binary);
|
|
}
|
|
_fmemcpy(BINARY_DATA(lpSqlNode->value.Binary),
|
|
BINARY_DATA(lpSqlNodeReturnValue->value.Binary),
|
|
length);
|
|
while (!(lpSqlNodeReturnValue->sqlIsNull) &&
|
|
(lpSqlNode->sqlSqlType == SQL_BINARY) &&
|
|
(length < lpSqlNode->sqlPrecision)) {
|
|
lpSqlNode->value.Binary[length] = 0;
|
|
length++;
|
|
}
|
|
BINARY_LENGTH(lpSqlNode->value.Binary) = length;
|
|
break;
|
|
case TYPE_DATE:
|
|
if (lpSqlNodeReturnValue->sqlIsNull) {
|
|
lpSqlNode->sqlIsNull = TRUE;
|
|
lpSqlNode->value.Date.year = 0;
|
|
lpSqlNode->value.Date.month = 0;
|
|
lpSqlNode->value.Date.day = 0;
|
|
}
|
|
else
|
|
lpSqlNode->value.Date = lpSqlNodeReturnValue->value.Date;
|
|
break;
|
|
case TYPE_TIME:
|
|
if (lpSqlNodeReturnValue->sqlIsNull) {
|
|
lpSqlNode->sqlIsNull = TRUE;
|
|
lpSqlNode->value.Time.hour = 0;
|
|
lpSqlNode->value.Time.minute = 0;
|
|
lpSqlNode->value.Time.second = 0;
|
|
}
|
|
else
|
|
lpSqlNode->value.Time = lpSqlNodeReturnValue->value.Time;
|
|
break;
|
|
case TYPE_TIMESTAMP:
|
|
if (lpSqlNodeReturnValue->sqlIsNull) {
|
|
lpSqlNode->sqlIsNull = TRUE;
|
|
lpSqlNode->value.Timestamp.year = 0;
|
|
lpSqlNode->value.Timestamp.month = 0;
|
|
lpSqlNode->value.Timestamp.day = 0;
|
|
lpSqlNode->value.Timestamp.hour = 0;
|
|
lpSqlNode->value.Timestamp.minute = 0;
|
|
lpSqlNode->value.Timestamp.second = 0;
|
|
lpSqlNode->value.Timestamp.fraction = 0;
|
|
}
|
|
else
|
|
lpSqlNode->value.Timestamp = lpSqlNodeReturnValue->value.Timestamp;
|
|
break;
|
|
default:
|
|
return ERR_INTERNAL;
|
|
}
|
|
break;
|
|
case SCALAR_USER:
|
|
s_lstrcpy(lpSqlNode->value.String, ISAMUser(lpstmt->lpdbc->lpISAM));
|
|
break;
|
|
case SCALAR_CONVERT:
|
|
switch (lpSqlNode->sqlSqlType) {
|
|
case SQL_CHAR:
|
|
case SQL_VARCHAR:
|
|
switch (lpSqlNodeValue[0]->sqlSqlType) {
|
|
case SQL_CHAR:
|
|
case SQL_VARCHAR:
|
|
case SQL_DECIMAL:
|
|
case SQL_NUMERIC:
|
|
case SQL_BIGINT:
|
|
s_lstrcpy(lpSqlNode->value.String,
|
|
lpSqlNodeValue[0]->value.String);
|
|
if ((lpSqlNode->sqlSqlType == SQL_VARCHAR) &&
|
|
(lpSqlNodeValue[0]->sqlSqlType == SQL_CHAR)) {
|
|
length = (SWORD) s_lstrlen(lpSqlNode->value.String);
|
|
while ((length > 0) &&
|
|
(lpSqlNode->value.String[length-1] == ' ')) {
|
|
lpSqlNode->value.String[length-1] = '\0';
|
|
length--;
|
|
}
|
|
}
|
|
break;
|
|
case SQL_LONGVARCHAR:
|
|
case SQL_LONGVARBINARY:
|
|
return ERR_NOTSUPPORTED;
|
|
case SQL_BIT:
|
|
case SQL_TINYINT:
|
|
case SQL_SMALLINT:
|
|
case SQL_INTEGER:
|
|
case SQL_REAL:
|
|
case SQL_FLOAT:
|
|
case SQL_DOUBLE:
|
|
if (DoubleToChar(lpSqlNodeValue[0]->value.Double, TRUE,
|
|
lpSqlNode->value.String, lpSqlNode->sqlPrecision))
|
|
lpSqlNode->value.String[lpSqlNode->sqlPrecision-1] = '\0';
|
|
break;
|
|
case SQL_BINARY:
|
|
case SQL_VARBINARY:
|
|
|
|
/* Figure out how many nibbles (not bytes) to copy */
|
|
length = (SWORD) (2 *
|
|
BINARY_LENGTH(lpSqlNodeValue[0]->value.Binary));
|
|
if (length > lpSqlNode->sqlPrecision)
|
|
return ERR_NOTCONVERTABLE;
|
|
|
|
/* Copy the value */
|
|
lpFrom = BINARY_DATA(lpSqlNodeValue[0]->value.Binary);
|
|
lpTo = BINARY_DATA(lpSqlNode->value.Binary);
|
|
for (idx = 0; idx < (UWORD) length; idx++) {
|
|
|
|
/* Get the next nibble */
|
|
nibble = *lpFrom;
|
|
if (((idx/2) * 2) == idx)
|
|
nibble = nibble >> 4;
|
|
else
|
|
lpFrom++;
|
|
nibble = nibble & 0x0F;
|
|
|
|
/* Convert it to a character */
|
|
if (nibble <= 9)
|
|
*lpTo = nibble + '0';
|
|
else
|
|
*lpTo = (nibble-10) + 'A';
|
|
lpTo++;
|
|
}
|
|
*lpTo = '\0';
|
|
break;
|
|
|
|
case SQL_DATE:
|
|
DateToChar(&(lpSqlNodeValue[0]->value.Date),
|
|
lpSqlNode->value.String);
|
|
break;
|
|
case SQL_TIME:
|
|
TimeToChar(&(lpSqlNodeValue[0]->value.Time),
|
|
lpSqlNode->value.String);
|
|
break;
|
|
case SQL_TIMESTAMP:
|
|
TimestampToChar(&(lpSqlNodeValue[0]->value.Timestamp),
|
|
lpSqlNode->value.String);
|
|
break;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
|
|
if (lpSqlNode->sqlSqlType == SQL_CHAR) {
|
|
while (s_lstrlen(lpSqlNode->value.String) <
|
|
lpSqlNode->sqlPrecision)
|
|
s_lstrcat(lpSqlNode->value.String, " ");
|
|
}
|
|
break;
|
|
case SQL_LONGVARCHAR:
|
|
case SQL_LONGVARBINARY:
|
|
return ERR_NOTSUPPORTED;
|
|
case SQL_BIT:
|
|
switch (lpSqlNodeValue[0]->sqlSqlType) {
|
|
case SQL_CHAR:
|
|
case SQL_VARCHAR:
|
|
case SQL_DECIMAL:
|
|
case SQL_NUMERIC:
|
|
case SQL_BIGINT:
|
|
err = CharToDouble(lpSqlNodeValue[0]->value.String,
|
|
s_lstrlen(lpSqlNodeValue[0]->value.String),
|
|
TRUE, BIT_LOW_D, BIT_HIGH_D,
|
|
&(lpSqlNode->value.Double));
|
|
if (err != ERR_SUCCESS) {
|
|
if (err == ERR_OUTOFRANGE)
|
|
return ERR_OUTOFRANGE;
|
|
else
|
|
return ERR_NOTCONVERTABLE;
|
|
}
|
|
break;
|
|
case SQL_LONGVARCHAR:
|
|
case SQL_LONGVARBINARY:
|
|
return ERR_NOTSUPPORTED;
|
|
case SQL_BIT:
|
|
case SQL_TINYINT:
|
|
case SQL_SMALLINT:
|
|
case SQL_INTEGER:
|
|
case SQL_REAL:
|
|
case SQL_FLOAT:
|
|
case SQL_DOUBLE:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Double;
|
|
if ((lpSqlNode->value.Double < BIT_LOW_D) ||
|
|
(lpSqlNode->value.Double > BIT_HIGH_D))
|
|
return ERR_OUTOFRANGE;
|
|
break;
|
|
case SQL_BINARY:
|
|
case SQL_VARBINARY:
|
|
if (BINARY_LENGTH(lpSqlNodeValue[0]->value.Binary) !=
|
|
sizeof(unsigned char))
|
|
return ERR_NOTCONVERTABLE;
|
|
lpSqlNode->value.Double = *((unsigned char far *)
|
|
BINARY_DATA(lpSqlNodeValue[0]->value.Binary));
|
|
if ((lpSqlNode->value.Double < BIT_LOW_D) ||
|
|
(lpSqlNode->value.Double > BIT_HIGH_D))
|
|
return ERR_OUTOFRANGE;
|
|
break;
|
|
case SQL_DATE:
|
|
case SQL_TIME:
|
|
case SQL_TIMESTAMP:
|
|
return ERR_NOTCONVERTABLE;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
break;
|
|
case SQL_TINYINT:
|
|
switch (lpSqlNodeValue[0]->sqlSqlType) {
|
|
case SQL_CHAR:
|
|
case SQL_VARCHAR:
|
|
case SQL_DECIMAL:
|
|
case SQL_NUMERIC:
|
|
case SQL_BIGINT:
|
|
err = CharToDouble(lpSqlNodeValue[0]->value.String,
|
|
s_lstrlen(lpSqlNodeValue[0]->value.String),
|
|
TRUE, STINY_LOW_D, STINY_LOW_D,
|
|
&(lpSqlNode->value.Double));
|
|
if (err != ERR_SUCCESS) {
|
|
if (err == ERR_OUTOFRANGE)
|
|
return ERR_OUTOFRANGE;
|
|
else
|
|
return ERR_NOTCONVERTABLE;
|
|
}
|
|
break;
|
|
case SQL_LONGVARCHAR:
|
|
case SQL_LONGVARBINARY:
|
|
return ERR_NOTSUPPORTED;
|
|
case SQL_BIT:
|
|
case SQL_TINYINT:
|
|
case SQL_SMALLINT:
|
|
case SQL_INTEGER:
|
|
case SQL_REAL:
|
|
case SQL_FLOAT:
|
|
case SQL_DOUBLE:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Double;
|
|
if ((lpSqlNode->value.Double < STINY_LOW_D) ||
|
|
(lpSqlNode->value.Double > STINY_HIGH_D))
|
|
return ERR_OUTOFRANGE;
|
|
break;
|
|
case SQL_BINARY:
|
|
case SQL_VARBINARY:
|
|
if (BINARY_LENGTH(lpSqlNodeValue[0]->value.Binary) !=
|
|
sizeof(char))
|
|
return ERR_NOTCONVERTABLE;
|
|
lpSqlNode->value.Double = *((char far *)
|
|
BINARY_DATA(lpSqlNodeValue[0]->value.Binary));
|
|
if ((lpSqlNode->value.Double < BIT_LOW_D) ||
|
|
(lpSqlNode->value.Double > BIT_HIGH_D))
|
|
return ERR_OUTOFRANGE;
|
|
break;
|
|
case SQL_DATE:
|
|
case SQL_TIME:
|
|
case SQL_TIMESTAMP:
|
|
return ERR_NOTCONVERTABLE;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
break;
|
|
case SQL_SMALLINT:
|
|
switch (lpSqlNodeValue[0]->sqlSqlType) {
|
|
case SQL_CHAR:
|
|
case SQL_VARCHAR:
|
|
case SQL_DECIMAL:
|
|
case SQL_NUMERIC:
|
|
case SQL_BIGINT:
|
|
err = CharToDouble(lpSqlNodeValue[0]->value.String,
|
|
s_lstrlen(lpSqlNodeValue[0]->value.String),
|
|
TRUE, SSHORT_LOW_D, SSHORT_HIGH_D,
|
|
&(lpSqlNode->value.Double));
|
|
if (err != ERR_SUCCESS) {
|
|
if (err == ERR_OUTOFRANGE)
|
|
return ERR_OUTOFRANGE;
|
|
else
|
|
return ERR_NOTCONVERTABLE;
|
|
}
|
|
break;
|
|
case SQL_LONGVARCHAR:
|
|
case SQL_LONGVARBINARY:
|
|
return ERR_NOTSUPPORTED;
|
|
case SQL_BIT:
|
|
case SQL_TINYINT:
|
|
case SQL_SMALLINT:
|
|
case SQL_INTEGER:
|
|
case SQL_REAL:
|
|
case SQL_FLOAT:
|
|
case SQL_DOUBLE:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Double;
|
|
if ((lpSqlNode->value.Double < SSHORT_LOW_D) ||
|
|
(lpSqlNode->value.Double > SSHORT_HIGH_D))
|
|
return ERR_OUTOFRANGE;
|
|
break;
|
|
case SQL_BINARY:
|
|
case SQL_VARBINARY:
|
|
if (BINARY_LENGTH(lpSqlNodeValue[0]->value.Binary) !=
|
|
sizeof(short))
|
|
return ERR_NOTCONVERTABLE;
|
|
lpSqlNode->value.Double = *((short far *)
|
|
BINARY_DATA(lpSqlNodeValue[0]->value.Binary));
|
|
if ((lpSqlNode->value.Double < BIT_LOW_D) ||
|
|
(lpSqlNode->value.Double > BIT_HIGH_D))
|
|
return ERR_OUTOFRANGE;
|
|
break;
|
|
case SQL_DATE:
|
|
case SQL_TIME:
|
|
case SQL_TIMESTAMP:
|
|
return ERR_NOTCONVERTABLE;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
break;
|
|
case SQL_INTEGER:
|
|
switch (lpSqlNodeValue[0]->sqlSqlType) {
|
|
case SQL_CHAR:
|
|
case SQL_VARCHAR:
|
|
case SQL_DECIMAL:
|
|
case SQL_NUMERIC:
|
|
case SQL_BIGINT:
|
|
err = CharToDouble(lpSqlNodeValue[0]->value.String,
|
|
s_lstrlen(lpSqlNodeValue[0]->value.String),
|
|
TRUE, SLONG_LOW_D, SLONG_HIGH_D,
|
|
&(lpSqlNode->value.Double));
|
|
if (err != ERR_SUCCESS) {
|
|
if (err == ERR_OUTOFRANGE)
|
|
return ERR_OUTOFRANGE;
|
|
else
|
|
return ERR_NOTCONVERTABLE;
|
|
}
|
|
break;
|
|
case SQL_LONGVARCHAR:
|
|
case SQL_LONGVARBINARY:
|
|
return ERR_NOTSUPPORTED;
|
|
case SQL_BIT:
|
|
case SQL_TINYINT:
|
|
case SQL_SMALLINT:
|
|
case SQL_INTEGER:
|
|
case SQL_REAL:
|
|
case SQL_FLOAT:
|
|
case SQL_DOUBLE:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Double;
|
|
if ((lpSqlNode->value.Double < SLONG_LOW_D) ||
|
|
(lpSqlNode->value.Double > SLONG_HIGH_D))
|
|
return ERR_OUTOFRANGE;
|
|
break;
|
|
case SQL_BINARY:
|
|
case SQL_VARBINARY:
|
|
if (BINARY_LENGTH(lpSqlNodeValue[0]->value.Binary) !=
|
|
sizeof(long))
|
|
return ERR_NOTCONVERTABLE;
|
|
lpSqlNode->value.Double = *((long far *)
|
|
BINARY_DATA(lpSqlNodeValue[0]->value.Binary));
|
|
if ((lpSqlNode->value.Double < BIT_LOW_D) ||
|
|
(lpSqlNode->value.Double > BIT_HIGH_D))
|
|
return ERR_OUTOFRANGE;
|
|
break;
|
|
case SQL_DATE:
|
|
case SQL_TIME:
|
|
case SQL_TIMESTAMP:
|
|
return ERR_NOTCONVERTABLE;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
break;
|
|
case SQL_REAL:
|
|
switch (lpSqlNodeValue[0]->sqlSqlType) {
|
|
case SQL_CHAR:
|
|
case SQL_VARCHAR:
|
|
case SQL_DECIMAL:
|
|
case SQL_NUMERIC:
|
|
case SQL_BIGINT:
|
|
err = CharToDouble(lpSqlNodeValue[0]->value.String,
|
|
s_lstrlen(lpSqlNodeValue[0]->value.String),
|
|
FALSE, FLOAT_LOW_D, FLOAT_HIGH_D,
|
|
&(lpSqlNode->value.Double));
|
|
if (err != ERR_SUCCESS) {
|
|
if (err == ERR_OUTOFRANGE)
|
|
return ERR_OUTOFRANGE;
|
|
else
|
|
return ERR_NOTCONVERTABLE;
|
|
}
|
|
break;
|
|
case SQL_LONGVARCHAR:
|
|
case SQL_LONGVARBINARY:
|
|
return ERR_NOTSUPPORTED;
|
|
case SQL_BIT:
|
|
case SQL_TINYINT:
|
|
case SQL_SMALLINT:
|
|
case SQL_INTEGER:
|
|
case SQL_REAL:
|
|
case SQL_FLOAT:
|
|
case SQL_DOUBLE:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Double;
|
|
if ((lpSqlNode->value.Double < FLOAT_LOW_D) ||
|
|
(lpSqlNode->value.Double > FLOAT_HIGH_D))
|
|
return ERR_OUTOFRANGE;
|
|
break;
|
|
case SQL_BINARY:
|
|
case SQL_VARBINARY:
|
|
if (BINARY_LENGTH(lpSqlNodeValue[0]->value.Binary) !=
|
|
sizeof(float))
|
|
return ERR_NOTCONVERTABLE;
|
|
lpSqlNode->value.Double = *((float far *)
|
|
BINARY_DATA(lpSqlNodeValue[0]->value.Binary));
|
|
if ((lpSqlNode->value.Double < BIT_LOW_D) ||
|
|
(lpSqlNode->value.Double > BIT_HIGH_D))
|
|
return ERR_OUTOFRANGE;
|
|
break;
|
|
case SQL_DATE:
|
|
case SQL_TIME:
|
|
case SQL_TIMESTAMP:
|
|
return ERR_NOTCONVERTABLE;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
break;
|
|
case SQL_FLOAT:
|
|
case SQL_DOUBLE:
|
|
switch (lpSqlNodeValue[0]->sqlSqlType) {
|
|
case SQL_CHAR:
|
|
case SQL_VARCHAR:
|
|
case SQL_DECIMAL:
|
|
case SQL_NUMERIC:
|
|
case SQL_BIGINT:
|
|
err = CharToDouble(lpSqlNodeValue[0]->value.String,
|
|
s_lstrlen(lpSqlNodeValue[0]->value.String),
|
|
FALSE, DOUBLE_LOW_D, DOUBLE_HIGH_D,
|
|
&(lpSqlNode->value.Double));
|
|
if (err != ERR_SUCCESS) {
|
|
if (err == ERR_OUTOFRANGE)
|
|
return ERR_OUTOFRANGE;
|
|
else
|
|
return ERR_NOTCONVERTABLE;
|
|
}
|
|
break;
|
|
case SQL_LONGVARCHAR:
|
|
case SQL_LONGVARBINARY:
|
|
return ERR_NOTSUPPORTED;
|
|
case SQL_BIT:
|
|
case SQL_TINYINT:
|
|
case SQL_SMALLINT:
|
|
case SQL_INTEGER:
|
|
case SQL_REAL:
|
|
case SQL_FLOAT:
|
|
case SQL_DOUBLE:
|
|
lpSqlNode->value.Double = lpSqlNodeValue[0]->value.Double;
|
|
if ((lpSqlNode->value.Double < DOUBLE_LOW_D) ||
|
|
(lpSqlNode->value.Double > DOUBLE_HIGH_D))
|
|
return ERR_OUTOFRANGE;
|
|
break;
|
|
case SQL_BINARY:
|
|
case SQL_VARBINARY:
|
|
if (BINARY_LENGTH(lpSqlNodeValue[0]->value.Binary) !=
|
|
sizeof(double))
|
|
return ERR_NOTCONVERTABLE;
|
|
lpSqlNode->value.Double = *((double far *)
|
|
BINARY_DATA(lpSqlNodeValue[0]->value.Binary));
|
|
if ((lpSqlNode->value.Double < BIT_LOW_D) ||
|
|
(lpSqlNode->value.Double > BIT_HIGH_D))
|
|
return ERR_OUTOFRANGE;
|
|
break;
|
|
case SQL_DATE:
|
|
case SQL_TIME:
|
|
case SQL_TIMESTAMP:
|
|
return ERR_NOTCONVERTABLE;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
break;
|
|
case SQL_DECIMAL:
|
|
case SQL_NUMERIC:
|
|
case SQL_BIGINT:
|
|
switch (lpSqlNodeValue[0]->sqlSqlType) {
|
|
case SQL_CHAR:
|
|
case SQL_VARCHAR:
|
|
err = CharToDouble(lpSqlNodeValue[0]->value.String,
|
|
s_lstrlen(lpSqlNodeValue[0]->value.String),
|
|
FALSE, DOUBLE_LOW_D, DOUBLE_HIGH_D, &dbl);
|
|
if (err != ERR_SUCCESS) {
|
|
if (err == ERR_OUTOFRANGE)
|
|
return ERR_OUTOFRANGE;
|
|
else
|
|
return ERR_NOTCONVERTABLE;
|
|
}
|
|
s_lstrcpy(lpSqlNode->value.String,
|
|
lpSqlNodeValue[0]->value.String);
|
|
break;
|
|
case SQL_DECIMAL:
|
|
case SQL_NUMERIC:
|
|
case SQL_BIGINT:
|
|
s_lstrcpy(lpSqlNode->value.String,
|
|
lpSqlNodeValue[0]->value.String);
|
|
break;
|
|
case SQL_LONGVARCHAR:
|
|
case SQL_LONGVARBINARY:
|
|
return ERR_NOTSUPPORTED;
|
|
case SQL_BIT:
|
|
case SQL_TINYINT:
|
|
case SQL_SMALLINT:
|
|
case SQL_INTEGER:
|
|
case SQL_REAL:
|
|
case SQL_FLOAT:
|
|
case SQL_DOUBLE:
|
|
if (DoubleToChar(lpSqlNodeValue[0]->value.Double, FALSE,
|
|
lpSqlNode->value.String,
|
|
lpSqlNode->sqlPrecision + 2 + 1))
|
|
lpSqlNode->value.String[2 + lpSqlNode->sqlPrecision]='\0';
|
|
break;
|
|
case SQL_BINARY:
|
|
case SQL_VARBINARY:
|
|
err = CharToDouble(
|
|
BINARY_DATA(lpSqlNodeValue[0]->value.Binary),
|
|
BINARY_LENGTH(lpSqlNodeValue[0]->value.Binary),
|
|
FALSE, DOUBLE_LOW_D, DOUBLE_HIGH_D, &dbl);
|
|
if (err != ERR_SUCCESS) {
|
|
if (err == ERR_OUTOFRANGE)
|
|
return ERR_OUTOFRANGE;
|
|
else
|
|
return ERR_NOTCONVERTABLE;
|
|
}
|
|
_fmemcpy(lpSqlNode->value.String,
|
|
BINARY_DATA(lpSqlNodeValue[0]->value.Binary),
|
|
(SWORD) BINARY_LENGTH(lpSqlNodeValue[0]->value.Binary));
|
|
lpSqlNode->value.String[
|
|
BINARY_LENGTH(lpSqlNodeValue[0]->value.Binary)] = '\0';
|
|
break;
|
|
case SQL_DATE:
|
|
case SQL_TIME:
|
|
case SQL_TIMESTAMP:
|
|
return ERR_NOTCONVERTABLE;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
err = BCDNormalize(lpSqlNode->value.String,
|
|
s_lstrlen(lpSqlNode->value.String),
|
|
lpSqlNode->value.String,
|
|
1 + 2 + lpSqlNode->sqlPrecision,
|
|
lpSqlNode->sqlPrecision,
|
|
lpSqlNode->sqlScale);
|
|
if ((err != ERR_SUCCESS) && (err != ERR_DATATRUNCATED))
|
|
return err;
|
|
break;
|
|
case SQL_BINARY:
|
|
case SQL_VARBINARY:
|
|
switch (lpSqlNodeValue[0]->sqlSqlType) {
|
|
case SQL_CHAR:
|
|
case SQL_VARCHAR:
|
|
case SQL_DECIMAL:
|
|
case SQL_NUMERIC:
|
|
case SQL_BIGINT:
|
|
_fmemcpy(BINARY_DATA(lpSqlNode->value.Binary),
|
|
lpSqlNodeValue[0]->value.String,
|
|
s_lstrlen(lpSqlNodeValue[0]->value.String));
|
|
BINARY_LENGTH(lpSqlNode->value.Binary) =
|
|
s_lstrlen(lpSqlNodeValue[0]->value.String);
|
|
break;
|
|
case SQL_LONGVARCHAR:
|
|
case SQL_LONGVARBINARY:
|
|
return ERR_NOTSUPPORTED;
|
|
case SQL_BIT:
|
|
uchr = (unsigned char) lpSqlNodeValue[0]->value.Double;
|
|
_fmemcpy(BINARY_DATA(lpSqlNode->value.Binary),
|
|
&uchr, sizeof(unsigned char));
|
|
BINARY_LENGTH(lpSqlNode->value.Binary) =
|
|
sizeof(unsigned char);
|
|
break;
|
|
case SQL_TINYINT:
|
|
chr = (char) lpSqlNodeValue[0]->value.Double;
|
|
_fmemcpy(BINARY_DATA(lpSqlNode->value.Binary),
|
|
&chr, sizeof(char));
|
|
BINARY_LENGTH(lpSqlNode->value.Binary) = sizeof(char);
|
|
break;
|
|
case SQL_SMALLINT:
|
|
shrt = (short) lpSqlNodeValue[0]->value.Double;
|
|
_fmemcpy(BINARY_DATA(lpSqlNode->value.Binary),
|
|
&shrt, sizeof(short));
|
|
BINARY_LENGTH(lpSqlNode->value.Binary) = sizeof(short);
|
|
break;
|
|
case SQL_INTEGER:
|
|
lng = (long) lpSqlNodeValue[0]->value.Double;
|
|
_fmemcpy(BINARY_DATA(lpSqlNode->value.Binary),
|
|
&lng, sizeof(long));
|
|
BINARY_LENGTH(lpSqlNode->value.Binary) = sizeof(long);
|
|
break;
|
|
case SQL_REAL:
|
|
flt = (float) lpSqlNodeValue[0]->value.Double;
|
|
_fmemcpy(BINARY_DATA(lpSqlNode->value.Binary),
|
|
&flt, sizeof(float));
|
|
BINARY_LENGTH(lpSqlNode->value.Binary) = sizeof(float);
|
|
break;
|
|
case SQL_FLOAT:
|
|
case SQL_DOUBLE:
|
|
_fmemcpy(BINARY_DATA(lpSqlNode->value.Binary),
|
|
&(lpSqlNodeValue[0]->value.Double), sizeof(double));
|
|
BINARY_LENGTH(lpSqlNode->value.Binary) = sizeof(double);
|
|
break;
|
|
case SQL_BINARY:
|
|
case SQL_VARBINARY:
|
|
_fmemcpy(BINARY_DATA(lpSqlNode->value.Binary),
|
|
BINARY_DATA(lpSqlNodeValue[0]->value.Binary),
|
|
(SWORD) BINARY_LENGTH(lpSqlNodeValue[0]->value.Binary));
|
|
BINARY_LENGTH(lpSqlNode->value.Binary) =
|
|
BINARY_LENGTH(lpSqlNodeValue[0]->value.Binary);
|
|
break;
|
|
case SQL_DATE:
|
|
_fmemcpy(BINARY_DATA(lpSqlNode->value.Binary),
|
|
&(lpSqlNodeValue[0]->value.Date), sizeof(DATE_STRUCT));
|
|
BINARY_LENGTH(lpSqlNode->value.Binary) = sizeof(DATE_STRUCT);
|
|
break;
|
|
case SQL_TIME:
|
|
_fmemcpy(BINARY_DATA(lpSqlNode->value.Binary),
|
|
&(lpSqlNodeValue[0]->value.Time), sizeof(TIME_STRUCT));
|
|
BINARY_LENGTH(lpSqlNode->value.Binary) = sizeof(TIME_STRUCT);
|
|
break;
|
|
case SQL_TIMESTAMP:
|
|
_fmemcpy(BINARY_DATA(lpSqlNode->value.Binary),
|
|
&(lpSqlNodeValue[0]->value.Timestamp),
|
|
sizeof(TIMESTAMP_STRUCT));
|
|
BINARY_LENGTH(lpSqlNode->value.Binary) =
|
|
sizeof(TIMESTAMP_STRUCT);
|
|
break;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
if (lpSqlNode->sqlSqlType == SQL_BINARY) {
|
|
while (BINARY_LENGTH(lpSqlNode->value.Binary) <
|
|
lpSqlNode->sqlPrecision) {
|
|
BINARY_DATA(lpSqlNode->value.Binary)
|
|
[BINARY_LENGTH(lpSqlNode->value.Binary)] = '\0';
|
|
BINARY_LENGTH(lpSqlNode->value.Binary) += (1);
|
|
}
|
|
}
|
|
break;
|
|
case SQL_DATE:
|
|
switch (lpSqlNodeValue[0]->sqlSqlType) {
|
|
case SQL_CHAR:
|
|
case SQL_VARCHAR:
|
|
err = CharToDate(lpSqlNodeValue[0]->value.String,
|
|
s_lstrlen(lpSqlNodeValue[0]->value.String),
|
|
&(lpSqlNode->value.Date));
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
break;
|
|
case SQL_LONGVARCHAR:
|
|
case SQL_LONGVARBINARY:
|
|
return ERR_NOTSUPPORTED;
|
|
case SQL_BIT:
|
|
case SQL_TINYINT:
|
|
case SQL_SMALLINT:
|
|
case SQL_INTEGER:
|
|
case SQL_REAL:
|
|
case SQL_DECIMAL:
|
|
case SQL_NUMERIC:
|
|
case SQL_BIGINT:
|
|
case SQL_FLOAT:
|
|
case SQL_DOUBLE:
|
|
return ERR_NOTCONVERTABLE;
|
|
case SQL_BINARY:
|
|
case SQL_VARBINARY:
|
|
if (BINARY_LENGTH(lpSqlNodeValue[0]->value.Binary) !=
|
|
sizeof(DATE_STRUCT))
|
|
return ERR_NOTCONVERTABLE;
|
|
lpSqlNode->value.Date = *((DATE_STRUCT far *)
|
|
BINARY_DATA(lpSqlNodeValue[0]->value.Binary));
|
|
break;
|
|
case SQL_DATE:
|
|
lpSqlNode->value.Date = lpSqlNodeValue[0]->value.Date;
|
|
break;
|
|
case SQL_TIME:
|
|
return ERR_NOTCONVERTABLE;
|
|
case SQL_TIMESTAMP:
|
|
lpSqlNode->value.Date.year =
|
|
lpSqlNodeValue[0]->value.Timestamp.year;
|
|
lpSqlNode->value.Date.month =
|
|
lpSqlNodeValue[0]->value.Timestamp.month;
|
|
lpSqlNode->value.Date.day =
|
|
lpSqlNodeValue[0]->value.Timestamp.day;
|
|
break;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
break;
|
|
case SQL_TIME:
|
|
switch (lpSqlNodeValue[0]->sqlSqlType) {
|
|
case SQL_CHAR:
|
|
case SQL_VARCHAR:
|
|
err = CharToTime(lpSqlNodeValue[0]->value.String,
|
|
s_lstrlen(lpSqlNodeValue[0]->value.String),
|
|
&(lpSqlNode->value.Time));
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
break;
|
|
case SQL_LONGVARCHAR:
|
|
case SQL_LONGVARBINARY:
|
|
return ERR_NOTSUPPORTED;
|
|
case SQL_BIT:
|
|
case SQL_TINYINT:
|
|
case SQL_SMALLINT:
|
|
case SQL_INTEGER:
|
|
case SQL_REAL:
|
|
case SQL_DECIMAL:
|
|
case SQL_NUMERIC:
|
|
case SQL_BIGINT:
|
|
case SQL_FLOAT:
|
|
case SQL_DOUBLE:
|
|
return ERR_NOTCONVERTABLE;
|
|
case SQL_BINARY:
|
|
case SQL_VARBINARY:
|
|
if (BINARY_LENGTH(lpSqlNodeValue[0]->value.Binary) !=
|
|
sizeof(TIME_STRUCT))
|
|
return ERR_NOTCONVERTABLE;
|
|
lpSqlNode->value.Time = *((TIME_STRUCT far *)
|
|
BINARY_DATA(lpSqlNodeValue[0]->value.Binary));
|
|
break;
|
|
case SQL_DATE:
|
|
return ERR_NOTCONVERTABLE;
|
|
case SQL_TIME:
|
|
lpSqlNode->value.Time = lpSqlNodeValue[0]->value.Time;
|
|
break;
|
|
case SQL_TIMESTAMP:
|
|
lpSqlNode->value.Time.hour =
|
|
lpSqlNodeValue[0]->value.Timestamp.hour;
|
|
lpSqlNode->value.Time.minute =
|
|
lpSqlNodeValue[0]->value.Timestamp.minute;
|
|
lpSqlNode->value.Time.second =
|
|
lpSqlNodeValue[0]->value.Timestamp.second;
|
|
break;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
break;
|
|
case SQL_TIMESTAMP:
|
|
switch (lpSqlNodeValue[0]->sqlSqlType) {
|
|
case SQL_CHAR:
|
|
case SQL_VARCHAR:
|
|
err = CharToTimestamp(lpSqlNodeValue[0]->value.String,
|
|
s_lstrlen(lpSqlNodeValue[0]->value.String),
|
|
&(lpSqlNode->value.Timestamp));
|
|
if (err != ERR_SUCCESS)
|
|
return err;
|
|
break;
|
|
case SQL_LONGVARCHAR:
|
|
case SQL_LONGVARBINARY:
|
|
return ERR_NOTSUPPORTED;
|
|
case SQL_BIT:
|
|
case SQL_TINYINT:
|
|
case SQL_SMALLINT:
|
|
case SQL_INTEGER:
|
|
case SQL_REAL:
|
|
case SQL_DECIMAL:
|
|
case SQL_NUMERIC:
|
|
case SQL_BIGINT:
|
|
case SQL_FLOAT:
|
|
case SQL_DOUBLE:
|
|
return ERR_NOTCONVERTABLE;
|
|
case SQL_BINARY:
|
|
case SQL_VARBINARY:
|
|
if (BINARY_LENGTH(lpSqlNodeValue[0]->value.Binary) !=
|
|
sizeof(TIMESTAMP_STRUCT))
|
|
return ERR_NOTCONVERTABLE;
|
|
lpSqlNode->value.Timestamp = *((TIMESTAMP_STRUCT far *)
|
|
BINARY_DATA(lpSqlNodeValue[0]->value.Binary));
|
|
break;
|
|
case SQL_DATE:
|
|
lpSqlNode->value.Timestamp.year =
|
|
lpSqlNodeValue[0]->value.Date.year;
|
|
lpSqlNode->value.Timestamp.month =
|
|
lpSqlNodeValue[0]->value.Date.month;
|
|
lpSqlNode->value.Timestamp.day =
|
|
lpSqlNodeValue[0]->value.Date.day;
|
|
lpSqlNode->value.Timestamp.hour = 0;
|
|
lpSqlNode->value.Timestamp.minute = 0;
|
|
lpSqlNode->value.Timestamp.second = 0;
|
|
lpSqlNode->value.Timestamp.fraction = 0;
|
|
break;
|
|
case SQL_TIME:
|
|
time(&t);
|
|
lpTs = localtime(&t);
|
|
lpSqlNode->value.Timestamp.year = lpTs->tm_year + 1900;
|
|
lpSqlNode->value.Timestamp.month = lpTs->tm_mon + 1;
|
|
lpSqlNode->value.Timestamp.day = (UWORD) lpTs->tm_mday;
|
|
lpSqlNode->value.Timestamp.hour =
|
|
lpSqlNodeValue[0]->value.Time.hour;
|
|
lpSqlNode->value.Timestamp.minute =
|
|
lpSqlNodeValue[0]->value.Time.minute;
|
|
lpSqlNode->value.Timestamp.second =
|
|
lpSqlNodeValue[0]->value.Time.second;
|
|
lpSqlNode->value.Timestamp.fraction = 0;
|
|
break;
|
|
case SQL_TIMESTAMP:
|
|
lpSqlNode->value.Timestamp =
|
|
lpSqlNodeValue[0]->value.Timestamp;
|
|
break;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
break;
|
|
default:
|
|
return ERR_NOTSUPPORTED;
|
|
}
|
|
break;
|
|
default:
|
|
return ERR_INTERNAL;
|
|
}
|
|
return ERR_SUCCESS;
|
|
}
|
|
/***************************************************************************/
|
|
#ifndef WIN32
|
|
void ScalarExceptionHandler(int sig)
|
|
{
|
|
_fpreset();
|
|
longjmp(scalarExceptionMark, -1);
|
|
}
|
|
#endif
|
|
/***************************************************************************/
|
|
RETCODE INTFUNC EvaluateScalar(LPSTMT lpstmt, LPSQLNODE lpSqlNode)
|
|
{
|
|
RETCODE err;
|
|
#ifndef WIN32
|
|
void (__cdecl *func)(int);
|
|
int jmpret;
|
|
#endif
|
|
|
|
#ifdef WIN32
|
|
__try {
|
|
#else
|
|
func = signal(SIGFPE, ScalarExceptionHandler);
|
|
if (func != SIG_ERR)
|
|
jmpret = setjmp(scalarExceptionMark);
|
|
if ((func != SIG_ERR) && (jmpret == 0)) {
|
|
#endif
|
|
|
|
err = InternalEvaluateScalar(lpstmt, lpSqlNode);
|
|
}
|
|
#ifdef WIN32
|
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
|
#else
|
|
else {
|
|
#endif
|
|
s_lstrcpy(lpstmt->szError, scalarFuncs[lpSqlNode->node.scalar.Id].name);
|
|
err = ERR_SCALARBADARG;
|
|
}
|
|
|
|
#ifndef WIN32
|
|
/* Turn off exception handler */
|
|
if (func != SIG_ERR)
|
|
signal(SIGFPE, func);
|
|
#endif
|
|
return err;
|
|
}
|
|
/***************************************************************************/
|