8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 20:03:02 +01:00

Added 8 new builtin functions supporting various encryption algorithms

This commit is contained in:
AlexPeshkoff 2018-11-30 17:30:45 +03:00 committed by Alexander Peshkov
parent 9c3b96de55
commit aacdeb274c
10 changed files with 1419 additions and 2 deletions

View File

@ -12,6 +12,7 @@ Authors:
Oleg Loa <loa@mail.ru> Oleg Loa <loa@mail.ru>
Alexey Karyakin <aleksey.karyakin@mail.ru> Alexey Karyakin <aleksey.karyakin@mail.ru>
Claudio Valderrama C. <cvalde at usa.net> Claudio Valderrama C. <cvalde at usa.net>
Alexander Peshkov <peshkoff@mail.ru>
--- ---
@ -415,6 +416,40 @@ Example:
select decode(state, 0, 'deleted', 1, 'active', 'unknown') from things; select decode(state, 0, 'deleted', 1, 'active', 'unknown') from things;
-------------------
ENCRYPT and DECRYPT
-------------------
Function:
Encrypts/decrypts data using symmetric cipher.
Format:
{ENCRYPT | DECRYPT} ( <string | blob> USING <algorithm> [MODE <mode>] KEY <string> \
[IV <string>] [<endianness>] [CTR_LENGTH <smallint>] [COUNTER <bigint>])
algorithm ::= { block_cipher | stream_cipher }
block_cipher ::= { AES | ANUBIS | BLOWFISH | KHAZAD | RC5 | RC6 | SAFER+ | TWOFISH | XTEA }
stream_cipher ::= { CHACHA20 | RC4 | SOBER128 }
mode ::= { CBC | CFB | CTR | ECB | OFB }
endianness ::= { CTR_BIG_ENDIAN | CTR_LITTLE_ENDIAN }
Important:
- Mode should be specified for block ciphers.
- Initialization vector (IV) should be specified for block ciphers in all modes except ECB and
all stream ciphers except RC4.
- Endianness may be specified only in CTR mode, default is little endian counter.
- Counter length (CTR_LENGTH, bytes) may be specified only in CTR mode, default is the size of IV.
- Initial counter value (COUNTER) may be specified only for CHACHA20 cipher, default is 0.
- Sizes of data strings passed to this functions are according to selected algorithm and mode
requirements.
- Functions return BLOB when first argument is blob and varbinary for all text types.
Example:
select encrypt('897897' using sober128 key 'AbcdAbcdAbcdAbcd' iv '01234567') from rdb$database;
select decrypt(x'0154090759DF' using sober128 key 'AbcdAbcdAbcdAbcd' iv '01234567') from rdb$database;
select decrypt(secret_field using aes mode ofb key '0123456701234567' iv init_vector) from secure_table;
--- ---
EXP EXP
--- ---
@ -872,6 +907,119 @@ Example:
select rpad(x, 10) from y; select rpad(x, 10) from y;
-----------
RSA_PRIVATE
-----------
Function:
Returns RSA private key of specified length (in bytes) in PKCS#1 format as VARBINARY atring.
Format:
RSA_PRIVATE ( <smallint> )
Example:
select rdb$set_context('USER_SESSION', 'private_key', rsa_private(256)) from rdb$database;
----------
RSA_PUBLIC
----------
Function:
Returns RSA public key for specified RSA private key, all keys are in PKCS#1 format.
Format:
RSA_PUBLIC ( <private key> )
Example:
(tip - start running samples one by one from RSA_PRIVATE function)
select rdb$set_context('USER_SESSION', 'public_key',
rsa_public(rdb$get_context('USER_SESSION', 'private_key'))) from rdb$database;
-----------
RSA_ENCRYPT
-----------
Function:
Pads data using OAEP padding and encrypts using RSA public key. Normally used to encrypt
short symmetric keys which are then used in block ciphers to encrypt a message.
Format:
RSA_ENCRYPT ( <string> KEY <public key> [LPARAM <string>] [HASH <hash>] )
KEY should be a value, returhed by RSA_PUBLIC function.
LPARAM is an additional system specific tag that can be applied to identify which
system encoded the message. Default value is NULL.
hash ::= { MD5 | SHA1 | SHA256 | SHA512 } Default is SHA256.
Example:
(tip - start running samples one by one from RSA_PRIVATE function)
select rdb$set_context('USER_SESSION', 'msg', rsa_encrypt('Some message'
key rdb$get_context('USER_SESSION', 'public_key'))) from rdb$database;
-----------
RSA_DECRYPT
-----------
Function:
Decrypts using RSA private key and OAEP de-pads the resulting data.
Format:
RSA_DECRYPT ( <string> KEY <private key> [LPARAM <string>] [HASH <hash>] )
KEY should be a value, returhed by RSA_PRIVATE function.
LPARAM is the same variable passed to RSA_ENCRYPT. If it does not match
what was used during encoding this function will not decrypt the packet.
hash ::= { MD5 | SHA1 | SHA256 | SHA512 } Default is SHA256.
Example:
(tip - start running samples one by one from RSA_PRIVATE function)
select rsa_decrypt(rdb$get_context('USER_SESSION', 'msg')
key rdb$get_context('USER_SESSION', 'private_key')) from rdb$database;
--------
RSA_SIGN
--------
Function:
Performs PSS encoding of message digest to be signed and signs using RSA private key.
Format:
RSA_SIGN ( <string> KEY <private key> [HASH <hash>] [SALT_LENGTH <smallint>] )
KEY should be a value, returhed by RSA_PRIVATE function.
hash ::= { MD5 | SHA1 | SHA256 | SHA512 } Default is SHA256.
SALT_LENGTH indicates the length of the desired salt, and should typically be small.
A good value is between 8 and 16.
Example:
(tip - start running samples one by one from RSA_PRIVATE function)
select rdb$set_context('USER_SESSION', 'msg', rsa_sign(hash('Test message' using sha256)
key rdb$get_context('USER_SESSION', 'private_key'))) from rdb$database;
----------
RSA_VERIFY
----------
Function:
Performs PSS encoding of message digest to be signed and verifies it's digital signature
using RSA public key.
Format:
RSA_VERIFY ( <string> SIGNATURE <string> KEY <public key> [HASH <hash>] [SALT_LENGTH <smallint>] )
SIGNATURE should be a value, returhed by RSA_SIGN function.
KEY should be a value, returhed by RSA_PUBLIC function.
hash ::= { MD5 | SHA1 | SHA256 | SHA512 } Default is SHA256.
SALT_LENGTH indicates the length of the desired salt, and should typically be small.
A good value is between 8 and 16.
Example:
(tip - start running samples one by one from RSA_PRIVATE function)
select rsa_verify(hash('Test message' using sha256) signature rdb$get_context('USER_SESSION', 'msg')
key rdb$get_context('USER_SESSION', 'public_key')) from rdb$database;
---- ----
SIGN SIGN
---- ----

View File

@ -28,6 +28,7 @@
#include "firebird.h" #include "firebird.h"
#include "../common/classes/fb_string.h" #include "../common/classes/fb_string.h"
#include "../common/classes/MetaName.h"
#include <ctype.h> #include <ctype.h>
#include <stdarg.h> #include <stdarg.h>
@ -95,6 +96,13 @@ namespace Firebird
memcpy(stringBuffer, v.c_str(), v.length()); memcpy(stringBuffer, v.c_str(), v.length());
} }
AbstractString::AbstractString(const size_type limit, const MetaName& v)
: max_length(static_cast<internal_size_type>(limit))
{
initialize(v.length());
memcpy(stringBuffer, v.c_str(), v.length());
}
AbstractString::AbstractString(const size_type limit, const size_type sizeL, const void* dataL) AbstractString::AbstractString(const size_type limit, const size_type sizeL, const void* dataL)
: max_length(static_cast<internal_size_type>(limit)) : max_length(static_cast<internal_size_type>(limit))
{ {

View File

@ -41,6 +41,8 @@
namespace Firebird namespace Firebird
{ {
class MetaName;
class AbstractString : private AutoStorage class AbstractString : private AutoStorage
{ {
public: public:
@ -163,6 +165,7 @@ namespace Firebird
const_pointer p2, const size_type n2); const_pointer p2, const size_type n2);
AbstractString(const size_type limit, const AbstractString& v); AbstractString(const size_type limit, const AbstractString& v);
AbstractString(const size_type limit, const MetaName& v);
explicit AbstractString(const size_type limit) : explicit AbstractString(const size_type limit) :
max_length(static_cast<internal_size_type>(limit)), max_length(static_cast<internal_size_type>(limit)),
@ -644,6 +647,7 @@ namespace Firebird
public: public:
StringBase() : AbstractString(Comparator::getMaxLength()) {} StringBase() : AbstractString(Comparator::getMaxLength()) {}
StringBase(const StringType& v) : AbstractString(Comparator::getMaxLength(), v) {} StringBase(const StringType& v) : AbstractString(Comparator::getMaxLength(), v) {}
explicit StringBase(const MetaName& v) : AbstractString(Comparator::getMaxLength(), v) {}
StringBase(const void* s, size_type n) : AbstractString(Comparator::getMaxLength(), n, s) {} StringBase(const void* s, size_type n) : AbstractString(Comparator::getMaxLength(), n, s) {}
StringBase(const_pointer s) : AbstractString(Comparator::getMaxLength(), static_cast<size_type>(strlen(s)), s) {} StringBase(const_pointer s) : AbstractString(Comparator::getMaxLength(), static_cast<size_type>(strlen(s)), s) {}
explicit StringBase(const unsigned char* s) : explicit StringBase(const unsigned char* s) :

View File

@ -3050,6 +3050,47 @@ DecimalFixed CVT_get_dec_fixed(const dsc* desc, SSHORT scale, DecimalStatus decS
} }
const UCHAR* CVT_get_bytes(const dsc* desc, unsigned& size)
{
/**************************************
*
* C V T _ g e t _ b y t e s
*
**************************************
*
* Functional description
* Return raw data of descriptor.
*
**************************************/
if (!desc)
{
size = 0;
return nullptr;
}
switch (desc->dsc_dtype)
{
case dtype_varying:
{
vary* v = (vary*)(desc->dsc_address);
size = v->vary_length;
return (const UCHAR*)v->vary_string;
}
case dtype_cstring:
size = strlen((const char*)desc->dsc_address);
return desc->dsc_address;
default:
size = desc->dsc_length;
return desc->dsc_address;
break;
}
return nullptr; // compiler warning silencer
}
SQUAD CVT_get_quad(const dsc* desc, SSHORT scale, DecimalStatus decSt, ErrorFunction err) SQUAD CVT_get_quad(const dsc* desc, SSHORT scale, DecimalStatus decSt, ErrorFunction err)
{ {
/************************************** /**************************************

View File

@ -102,5 +102,6 @@ SINT64 CVT_get_int64(const dsc*, SSHORT, Firebird::DecimalStatus, ErrorFunction)
SQUAD CVT_get_quad(const dsc*, SSHORT, Firebird::DecimalStatus, ErrorFunction); SQUAD CVT_get_quad(const dsc*, SSHORT, Firebird::DecimalStatus, ErrorFunction);
void CVT_string_to_datetime(const dsc*, ISC_TIMESTAMP_TZ*, bool*, const Firebird::EXPECT_DATETIME, void CVT_string_to_datetime(const dsc*, ISC_TIMESTAMP_TZ*, bool*, const Firebird::EXPECT_DATETIME,
bool, Firebird::Callbacks*); bool, Firebird::Callbacks*);
const UCHAR* CVT_get_bytes(const dsc*, unsigned&);
#endif //COMMON_CVT_H #endif //COMMON_CVT_H

View File

@ -596,19 +596,26 @@ using namespace Firebird;
%token <metaNamePtr> BIND %token <metaNamePtr> BIND
%token <metaNamePtr> COMPARE_DECFLOAT %token <metaNamePtr> COMPARE_DECFLOAT
%token <metaNamePtr> CUME_DIST %token <metaNamePtr> CUME_DIST
%token <metaNamePtr> COUNTER
%token <metaNamePtr> CTR_BIG_ENDIAN
%token <metaNamePtr> CTR_LENGTH
%token <metaNamePtr> CTR_LITTLE_ENDIAN
%token <metaNamePtr> DECFLOAT %token <metaNamePtr> DECFLOAT
%token <metaNamePtr> DEFINER %token <metaNamePtr> DEFINER
%token <metaNamePtr> EXCLUDE %token <metaNamePtr> EXCLUDE
%token <metaNamePtr> FIRST_DAY %token <metaNamePtr> FIRST_DAY
%token <metaNamePtr> FOLLOWING %token <metaNamePtr> FOLLOWING
%token <metaNamePtr> IDLE %token <metaNamePtr> IDLE
%token <metaNamePtr> IV
%token <metaNamePtr> INVOKER %token <metaNamePtr> INVOKER
%token <metaNamePtr> LAST_DAY %token <metaNamePtr> LAST_DAY
%token <metaNamePtr> LEGACY %token <metaNamePtr> LEGACY
%token <metaNamePtr> LOCAL %token <metaNamePtr> LOCAL
%token <metaNamePtr> LOCALTIME %token <metaNamePtr> LOCALTIME
%token <metaNamePtr> LOCALTIMESTAMP %token <metaNamePtr> LOCALTIMESTAMP
%token <metaNamePtr> LPARAM
%token <metaNamePtr> MESSAGE %token <metaNamePtr> MESSAGE
%token <metaNamePtr> MODE
%token <metaNamePtr> NATIVE %token <metaNamePtr> NATIVE
%token <metaNamePtr> NORMALIZE_DECFLOAT %token <metaNamePtr> NORMALIZE_DECFLOAT
%token <metaNamePtr> NTILE %token <metaNamePtr> NTILE
@ -623,6 +630,14 @@ using namespace Firebird;
%token <metaNamePtr> RDB_ROLE_IN_USE %token <metaNamePtr> RDB_ROLE_IN_USE
%token <metaNamePtr> RDB_SYSTEM_PRIVILEGE %token <metaNamePtr> RDB_SYSTEM_PRIVILEGE
%token <metaNamePtr> RESET %token <metaNamePtr> RESET
%token <metaNamePtr> RSA_DECRYPT
%token <metaNamePtr> RSA_ENCRYPT
%token <metaNamePtr> RSA_PRIVATE
%token <metaNamePtr> RSA_PUBLIC
%token <metaNamePtr> RSA_SIGN
%token <metaNamePtr> RSA_VERIFY
%token <metaNamePtr> SALT_LENGTH
%token <metaNamePtr> SIGNATURE
%token <metaNamePtr> SECURITY %token <metaNamePtr> SECURITY
%token <metaNamePtr> SESSION %token <metaNamePtr> SESSION
%token <metaNamePtr> SQL %token <metaNamePtr> SQL
@ -7906,6 +7921,8 @@ system_function_std_syntax
| RIGHT | RIGHT
| ROUND | ROUND
| RPAD | RPAD
| RSA_PRIVATE
| RSA_PUBLIC
| SIGN | SIGN
| SIN | SIN
| SINH | SINH
@ -7946,6 +7963,14 @@ system_function_special_syntax
newNode<ValueListNode>(MAKE_const_slong($3))->add($5)->add($7)); newNode<ValueListNode>(MAKE_const_slong($3))->add($5)->add($7));
$$->dsqlSpecialSyntax = true; $$->dsqlSpecialSyntax = true;
} }
| encrypt_decrypt '(' value USING valid_symbol_name opt_mode KEY value opt_iv opt_counter_type opt_counter ')'
{
$$ = newNode<SysFuncCallNode>(*$1,
newNode<ValueListNode>($3)->add(MAKE_str_constant(newIntlString($5->c_str()), CS_ASCII))->
add(MAKE_str_constant(newIntlString($6->c_str()), CS_ASCII))->add($8)->add($9)->
add(MAKE_str_constant(newIntlString($10->c_str()), CS_ASCII))->add($11));
$$->dsqlSpecialSyntax = true;
}
| FIRST_DAY '(' of_first_last_day_part FROM value ')' | FIRST_DAY '(' of_first_last_day_part FROM value ')'
{ {
$$ = newNode<SysFuncCallNode>(*$1, $$ = newNode<SysFuncCallNode>(*$1,
@ -7985,6 +8010,27 @@ system_function_special_syntax
} }
| POSITION '(' value_list_opt ')' | POSITION '(' value_list_opt ')'
{ $$ = newNode<SysFuncCallNode>(*$1, $3); } { $$ = newNode<SysFuncCallNode>(*$1, $3); }
| rsa_encrypt_decrypt '(' value KEY value opt_lparam opt_hash ')'
{
$$ = newNode<SysFuncCallNode>(*$1,
newNode<ValueListNode>($3)->add($5)->add($6)->
add(MAKE_str_constant(newIntlString($7->c_str()), CS_ASCII)));
$$->dsqlSpecialSyntax = true;
}
| RSA_SIGN '(' value KEY value opt_hash opt_saltlen ')'
{
$$ = newNode<SysFuncCallNode>(*$1,
newNode<ValueListNode>($3)->add($5)->
add(MAKE_str_constant(newIntlString($6->c_str()), CS_ASCII))->add($7));
$$->dsqlSpecialSyntax = true;
}
| RSA_VERIFY'(' value SIGNATURE value KEY value opt_hash opt_saltlen ')'
{
$$ = newNode<SysFuncCallNode>(*$1,
newNode<ValueListNode>($3)->add($5)->add($7)->
add(MAKE_str_constant(newIntlString($8->c_str()), CS_ASCII))->add($9));
$$->dsqlSpecialSyntax = true;
}
| RDB_SYSTEM_PRIVILEGE '(' valid_symbol_name ')' | RDB_SYSTEM_PRIVILEGE '(' valid_symbol_name ')'
{ {
ValueExprNode* v = MAKE_system_privilege($3->c_str()); ValueExprNode* v = MAKE_system_privilege($3->c_str());
@ -7992,6 +8038,82 @@ system_function_special_syntax
} }
; ;
%type <metaNamePtr> rsa_encrypt_decrypt
rsa_encrypt_decrypt
: RSA_DECRYPT | RSA_ENCRYPT
;
%type <valueExprNode> opt_lparam
opt_lparam
: LPARAM value
{ $$ = $2; }
| /* nothing */
{ $$ = MAKE_str_constant(newIntlString(""), CS_ASCII); }
;
%type <metaNamePtr> opt_hash
opt_hash
: HASH valid_symbol_name
{ $$ = $2; }
| /* nothing */
{ $$ = newNode<MetaName>(""); }
;
%type <valueExprNode> opt_saltlen
opt_saltlen
: SALT_LENGTH value
{ $$ = $2; }
| /* nothing */
{ $$ = MAKE_str_constant(newIntlString(""), CS_ASCII); }
;
%type <metaNamePtr> opt_mode
opt_mode
: MODE valid_symbol_name
{ $$ = $2; }
| /* nothing */
{ $$ = newNode<MetaName>(""); }
;
%type <valueExprNode> opt_iv
opt_iv
: IV value
{ $$ = $2; }
| /* nothing */
{ $$ = MAKE_str_constant(newIntlString(""), CS_ASCII); }
;
%type <metaNamePtr> opt_counter_type
opt_counter_type
: counter_type
{ $$ = $1; }
| /* nothing */
{ $$ = newNode<MetaName>(""); }
;
%type <metaNamePtr> counter_type
counter_type
: CTR_BIG_ENDIAN | CTR_LITTLE_ENDIAN
;
%type <valueExprNode> opt_counter
opt_counter
: counter_name value
{ $$ = $2; }
| /* nothing */
{ $$ = MAKE_str_constant(newIntlString(""), CS_ASCII); }
;
%type <metaNamePtr> counter_name
counter_name
: COUNTER | CTR_LENGTH
;
%type <metaNamePtr> encrypt_decrypt
encrypt_decrypt
: ENCRYPT | DECRYPT
;
%type <blrOp> of_first_last_day_part %type <blrOp> of_first_last_day_part
of_first_last_day_part of_first_last_day_part
: OF YEAR { $$ = blr_extract_year; } : OF YEAR { $$ = blr_extract_year; }
@ -8682,6 +8804,21 @@ non_reserved_word
| TOTALORDER | TOTALORDER
| TRAPS | TRAPS
| ZONE | ZONE
| MODE // crypt functions
| IV
| COUNTER
| CTR_BIG_ENDIAN
| CTR_LITTLE_ENDIAN
| CTR_LENGTH
| LPARAM
| RSA_DECRYPT
| RSA_ENCRYPT
| RSA_PRIVATE
| RSA_PUBLIC
| RSA_SIGN
| RSA_VERIFY
| SALT_LENGTH
| SIGNATURE
; ;
%% %%

File diff suppressed because it is too large Load Diff

View File

@ -994,7 +994,7 @@ namespace
Jrd::ContextPoolHolder context(tdbb, new_pool); Jrd::ContextPoolHolder context(tdbb, new_pool);
const Firebird::MetaName depName(work->dfw_package.isEmpty() ? const Firebird::MetaName depName(work->dfw_package.isEmpty() ?
work->dfw_name : work->dfw_package); Firebird::MetaName(work->dfw_name) : work->dfw_package);
MET_get_dependencies(tdbb, NULL, NULL, 0, NULL, &blobId, MET_get_dependencies(tdbb, NULL, NULL, 0, NULL, &blobId,
(compile ? &statement : NULL), (compile ? &statement : NULL),
NULL, depName, NULL, depName,

View File

@ -174,7 +174,7 @@ void MOV_get_metaname(Jrd::thread_db* tdbb, const dsc* desc, MetaName& name)
const USHORT length = CVT_get_string_ptr(desc, &ttype, &ptr, NULL, 0, tdbb->getAttachment()->att_dec_status); const USHORT length = CVT_get_string_ptr(desc, &ttype, &ptr, NULL, 0, tdbb->getAttachment()->att_dec_status);
fb_assert(length && ptr); fb_assert(ptr);
fb_assert(length <= MAX_SQL_IDENTIFIER_LEN); fb_assert(length <= MAX_SQL_IDENTIFIER_LEN);
fb_assert(ttype == ttype_ascii || ttype == ttype_metadata); fb_assert(ttype == ttype_ascii || ttype == ttype_metadata);

View File

@ -140,11 +140,15 @@ static const TOK tokens[] =
{TOK_COSH, "COSH", true}, {TOK_COSH, "COSH", true},
{TOK_COT, "COT", true}, {TOK_COT, "COT", true},
{TOK_COUNT, "COUNT", false}, {TOK_COUNT, "COUNT", false},
{TOK_COUNTER, "COUNTER", true},
{TOK_COVAR_POP, "COVAR_POP", false}, {TOK_COVAR_POP, "COVAR_POP", false},
{TOK_COVAR_SAMP, "COVAR_SAMP", false}, {TOK_COVAR_SAMP, "COVAR_SAMP", false},
{TOK_CREATE, "CREATE", false}, {TOK_CREATE, "CREATE", false},
{TOK_CROSS, "CROSS", false}, {TOK_CROSS, "CROSS", false},
{TOK_CSTRING, "CSTRING", true}, {TOK_CSTRING, "CSTRING", true},
{TOK_CTR_BIG_ENDIAN, "CTR_BIG_ENDIAN", true},
{TOK_CTR_LENGTH, "CTR_LENGTH", true},
{TOK_CTR_LITTLE_ENDIAN, "CTR_LITTLE_ENDIAN", true},
{TOK_CUME_DIST, "CUME_DIST", true}, {TOK_CUME_DIST, "CUME_DIST", true},
{TOK_CURRENT, "CURRENT", false}, {TOK_CURRENT, "CURRENT", false},
{TOK_CURRENT_CONNECTION, "CURRENT_CONNECTION", false}, {TOK_CURRENT_CONNECTION, "CURRENT_CONNECTION", false},
@ -247,6 +251,7 @@ static const TOK tokens[] =
{TOK_INVOKER, "INVOKER", true}, {TOK_INVOKER, "INVOKER", true},
{TOK_IS, "IS", false}, {TOK_IS, "IS", false},
{TOK_ISOLATION, "ISOLATION", true}, {TOK_ISOLATION, "ISOLATION", true},
{TOK_IV, "IV", true},
{TOK_JOIN, "JOIN", false}, {TOK_JOIN, "JOIN", false},
{TOK_KEY, "KEY", true}, {TOK_KEY, "KEY", true},
{TOK_LAG, "LAG", true}, {TOK_LAG, "LAG", true},
@ -276,6 +281,7 @@ static const TOK tokens[] =
{TOK_LONG, "LONG", false}, {TOK_LONG, "LONG", false},
{TOK_LOWER, "LOWER", false}, {TOK_LOWER, "LOWER", false},
{TOK_LPAD, "LPAD", true}, {TOK_LPAD, "LPAD", true},
{TOK_LPARAM, "LPARAM", true},
{TOK_MANUAL, "MANUAL", true}, {TOK_MANUAL, "MANUAL", true},
{TOK_MAPPING, "MAPPING", true}, {TOK_MAPPING, "MAPPING", true},
{TOK_MATCHED, "MATCHED", true}, {TOK_MATCHED, "MATCHED", true},
@ -290,6 +296,7 @@ static const TOK tokens[] =
{TOK_MINUTE, "MINUTE", false}, {TOK_MINUTE, "MINUTE", false},
{TOK_MINVALUE, "MINVALUE", true}, {TOK_MINVALUE, "MINVALUE", true},
{TOK_MOD, "MOD", true}, {TOK_MOD, "MOD", true},
{TOK_MODE, "MODE", true},
{TOK_MODULE_NAME, "MODULE_NAME", true}, {TOK_MODULE_NAME, "MODULE_NAME", true},
{TOK_MONTH, "MONTH", false}, {TOK_MONTH, "MONTH", false},
{TOK_NAME, "NAME", true}, {TOK_NAME, "NAME", true},
@ -404,8 +411,16 @@ static const TOK tokens[] =
{TOK_ROW_NUMBER, "ROW_NUMBER", true}, {TOK_ROW_NUMBER, "ROW_NUMBER", true},
{TOK_ROWS, "ROWS", false}, {TOK_ROWS, "ROWS", false},
{TOK_RPAD, "RPAD", true}, {TOK_RPAD, "RPAD", true},
{TOK_RSA_DECRYPT, "RSA_DECRYPT", true},
{TOK_RSA_ENCRYPT, "RSA_ENCRYPT", true},
{TOK_RSA_PRIVATE, "RSA_PRIVATE", true},
{TOK_RSA_PUBLIC, "RSA_PUBLIC", true},
{TOK_RSA_SIGN, "RSA_SIGN", true},
{TOK_RSA_VERIFY, "RSA_VERIFY", true},
{TOK_SALT_LENGTH, "SALT_LENGTH", true},
{TOK_SAVEPOINT, "SAVEPOINT", false}, {TOK_SAVEPOINT, "SAVEPOINT", false},
{TOK_SCALAR_ARRAY, "SCALAR_ARRAY", true}, {TOK_SCALAR_ARRAY, "SCALAR_ARRAY", true},
{TOK_SIGNATURE, "SIGNATURE", true},
{TOK_DATABASE, "SCHEMA", false}, // Alias of DATABASE {TOK_DATABASE, "SCHEMA", false}, // Alias of DATABASE
{TOK_SCROLL, "SCROLL", false}, {TOK_SCROLL, "SCROLL", false},
{TOK_SECOND, "SECOND", false}, {TOK_SECOND, "SECOND", false},