@@ -237,6 +237,7 @@ void setParamsRsaEncrypt(DataTypeUtilBase*, const SysFunction*, int argsCount, d
237
237
void setParamsRsaPublic (DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args);
238
238
void setParamsRsaSign (DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args);
239
239
void setParamsRsaVerify (DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args);
240
+ void setParamsUnicodeVal (DataTypeUtilBase* dataTypeUtil, const SysFunction* function, int argsCount, dsc** args);
240
241
void setParamsUuidToChar (DataTypeUtilBase* dataTypeUtil, const SysFunction* function, int argsCount, dsc** args);
241
242
242
243
// generic make functions
@@ -280,6 +281,7 @@ void makeRsaPrivate(DataTypeUtilBase* dataTypeUtil, const SysFunction* function,
280
281
void makeRsaPublic (DataTypeUtilBase* dataTypeUtil, const SysFunction* function, dsc* result, int argsCount, const dsc** args);
281
282
void makeRsaSign (DataTypeUtilBase* dataTypeUtil, const SysFunction* function, dsc* result, int argsCount, const dsc** args);
282
283
void makeTrunc (DataTypeUtilBase* dataTypeUtil, const SysFunction* function, dsc* result, int argsCount, const dsc** args);
284
+ void makeUnicodeChar (DataTypeUtilBase* dataTypeUtil, const SysFunction* function, dsc* result, int argsCount, const dsc** args);
283
285
void makeUuid (DataTypeUtilBase* dataTypeUtil, const SysFunction* function, dsc* result, int argsCount, const dsc** args);
284
286
void makeUuidToChar (DataTypeUtilBase* dataTypeUtil, const SysFunction* function, dsc* result, int argsCount, const dsc** args);
285
287
@@ -338,6 +340,8 @@ dsc* evlSign(thread_db* tdbb, const SysFunction* function, const NestValueArray&
338
340
dsc* evlSqrt (thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure);
339
341
dsc* evlSystemPrivilege (thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure);
340
342
dsc* evlTrunc (thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure);
343
+ dsc* evlUnicodeChar (thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure);
344
+ dsc* evlUnicodeVal (thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure);
341
345
dsc* evlUuidToChar (thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure);
342
346
343
347
@@ -645,6 +649,13 @@ void setParamsDateDiff(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc
645
649
}
646
650
647
651
652
+ void setParamsUnicodeVal (DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args)
653
+ {
654
+ if (argsCount >= 1 && args[0 ]->isUnknown ())
655
+ args[0 ]->makeText (4 , CS_UTF8);
656
+ }
657
+
658
+
648
659
void setParamVarying (dsc* param, USHORT textType, bool condition)
649
660
{
650
661
if (!param)
@@ -1734,6 +1745,24 @@ void makeTrunc(DataTypeUtilBase*, const SysFunction* function, dsc* result,
1734
1745
}
1735
1746
1736
1747
1748
+ void makeUnicodeChar (DataTypeUtilBase*, const SysFunction* function, dsc* result,
1749
+ int argsCount, const dsc** args)
1750
+ {
1751
+ fb_assert (argsCount == function->minArgCount );
1752
+
1753
+ const dsc* value = args[0 ];
1754
+
1755
+ if (value->isNull ())
1756
+ {
1757
+ result->makeNullString ();
1758
+ return ;
1759
+ }
1760
+
1761
+ result->makeText (4 , ttype_utf8);
1762
+ result->setNullable (value->isNullable ());
1763
+ }
1764
+
1765
+
1737
1766
void makeUuid (DataTypeUtilBase*, const SysFunction* function, dsc* result,
1738
1767
int argsCount, const dsc** args)
1739
1768
{
@@ -6331,6 +6360,75 @@ dsc* evlSystemPrivilege(thread_db* tdbb, const SysFunction*, const NestValueArra
6331
6360
return &impure->vlu_desc ;
6332
6361
}
6333
6362
6363
+
6364
+ dsc* evlUnicodeChar (thread_db* tdbb, const SysFunction*, const NestValueArray& args,
6365
+ impure_value* impure)
6366
+ {
6367
+ fb_assert (args.getCount () == 1 );
6368
+
6369
+ jrd_req* request = tdbb->getRequest ();
6370
+
6371
+ const dsc* value = EVL_expr (tdbb, request, args[0 ]);
6372
+ if (request->req_flags & req_null) // return NULL if value is NULL
6373
+ return NULL ;
6374
+
6375
+ const UChar32 code = MOV_get_long (tdbb, value, 0 );
6376
+
6377
+ if (U8_LENGTH (code) == 0 )
6378
+ status_exception::raise (Arg::Gds (isc_arith_except) << Arg::Gds (isc_malformed_string));
6379
+
6380
+ UCHAR buffer[4 ];
6381
+ int len = 0 ;
6382
+ U8_APPEND_UNSAFE (buffer, len, code);
6383
+
6384
+ dsc result;
6385
+ result.makeText (len, ttype_utf8, buffer);
6386
+ EVL_make_value (tdbb, &result, impure);
6387
+
6388
+ return &impure->vlu_desc ;
6389
+ }
6390
+
6391
+
6392
+ dsc* evlUnicodeVal (thread_db* tdbb, const SysFunction*, const NestValueArray& args,
6393
+ impure_value* impure)
6394
+ {
6395
+ fb_assert (args.getCount () == 1 );
6396
+
6397
+ jrd_req* request = tdbb->getRequest ();
6398
+
6399
+ const dsc* value = EVL_expr (tdbb, request, args[0 ]);
6400
+ if (request->req_flags & req_null) // return NULL if value is NULL
6401
+ return NULL ;
6402
+
6403
+ MoveBuffer buffer;
6404
+ UCHAR* str;
6405
+ int len = MOV_make_string2 (tdbb, value, CS_UTF8, &str, buffer);
6406
+
6407
+ USHORT dst[2 ];
6408
+ USHORT errCode = 0 ;
6409
+ ULONG errPosition;
6410
+ ULONG dstLen = UnicodeUtil::utf8ToUtf16 (len, str, sizeof (dst), dst, &errCode, &errPosition);
6411
+
6412
+ if (errCode != 0 && errCode != CS_TRUNCATION_ERROR)
6413
+ status_exception::raise (Arg::Gds (isc_arith_except) << Arg::Gds (isc_transliteration_failed));
6414
+
6415
+ if (dstLen == 0 )
6416
+ impure->vlu_misc .vlu_long = 0 ;
6417
+ else if (dstLen == 2 || !U_IS_SURROGATE (dst[0 ]))
6418
+ impure->vlu_misc .vlu_long = dst[0 ];
6419
+ else if (dstLen == 4 && U16_IS_LEAD (dst[0 ]) && U16_IS_TRAIL (dst[1 ]))
6420
+ impure->vlu_misc .vlu_long = U16_GET_SUPPLEMENTARY (dst[0 ], dst[1 ]);
6421
+ else
6422
+ {
6423
+ fb_assert (false );
6424
+ impure->vlu_misc .vlu_long = 0 ;
6425
+ }
6426
+
6427
+ impure->vlu_desc .makeLong (0 , &impure->vlu_misc .vlu_long );
6428
+
6429
+ return &impure->vlu_desc ;
6430
+ }
6431
+
6334
6432
} // anonymous namespace
6335
6433
6336
6434
@@ -6417,6 +6515,8 @@ const SysFunction SysFunction::functions[] =
6417
6515
{" TANH" , 1 , 1 , setParamsDouble, makeDoubleResult, evlStdMath, (void *) trfTanh},
6418
6516
{" TOTALORDER" , 2 , 2 , setParamsDecFloat, makeShortResult, evlCompare, (void *) funTotalOrd},
6419
6517
{" TRUNC" , 1 , 2 , setParamsRoundTrunc, makeTrunc, evlTrunc, NULL },
6518
+ {" UNICODE_CHAR" , 1 , 1 , setParamsInteger, makeUnicodeChar, evlUnicodeChar, NULL },
6519
+ {" UNICODE_VAL" , 1 , 1 , setParamsUnicodeVal, makeLongResult, evlUnicodeVal, NULL },
6420
6520
{" UUID_TO_CHAR" , 1 , 1 , setParamsUuidToChar, makeUuidToChar, evlUuidToChar, NULL },
6421
6521
{" " , 0 , 0 , NULL , NULL , NULL , NULL }
6422
6522
};
0 commit comments