Skip to content

Commit 7631a1b

Browse files
committed
Merge pull request #8951 from FirebirdSQL/work/gh-8912
Implement #8912 : Context variables clear/re-initialization support
1 parent 77d83e7 commit 7631a1b

4 files changed

Lines changed: 82 additions & 4 deletions

File tree

doc/sql.extensions/README.context_variables2

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,17 @@ Function:
77
connection and current transaction. Also they provide means to associate
88
and retrieve user context data with transaction or connection.
99

10-
Author:
11-
Nickolay Samofatov <nickolay at broadviewsoftware dot com>
10+
Authors:
11+
Nickolay Samofatov <nickolay at broadviewsoftware dot com>,
12+
Vladyslav Khorsun <vkhorsun at firebirdsql dot org>
1213

1314
Format:
1415
RDB$SET_CONTEXT( <namespace>, <variable>, <value> )
1516
RDB$GET_CONTEXT( <namespace>, <variable> )
17+
RDB$RESET_CONTEXT( <namespace> )
1618

1719
Returned value:
18-
INTEGER for RDB$SET_CONTEXT
20+
INTEGER for RDB$SET_CONTEXT, RDB$RESET_CONTEXT
1921
VARCHAR(32765) for RDB$GET_CONTEXT
2022

2123
Usage:
@@ -36,6 +38,9 @@ Usage:
3638
1 if variable existed before the call and 0 otherwise. To delete variable from
3739
context set its value to NULL.
3840

41+
RDB$RESET_CONTEXT removes all variables from given context. It returns count
42+
of removed variables.
43+
3944
Currently, there is a fixed number of pre-defined namespaces you may use.
4045

4146
USER_SESSION namespace offers access to session-specific user-defined
@@ -177,3 +182,5 @@ execute procedure set_context('skidder', 1);
177182
insert into journal(jrn_id) values(0);
178183

179184
commit;
185+
186+
SELECT RDB$RESET_CONTEXT('USER_SESSION') FROM RDB$DATABASE;

src/common/ParserTokens.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ PARSER_TOKEN(TOK_RDB_ERROR, "RDB$ERROR", false)
385385
PARSER_TOKEN(TOK_RDB_GET_CONTEXT, "RDB$GET_CONTEXT", false)
386386
PARSER_TOKEN(TOK_RDB_GET_TRANSACTION_CN, "RDB$GET_TRANSACTION_CN", false)
387387
PARSER_TOKEN(TOK_RDB_RECORD_VERSION, "RDB$RECORD_VERSION", false)
388+
PARSER_TOKEN(TOK_RDB_RESET_CONTEXT, "RDB$RESET_CONTEXT", false)
388389
PARSER_TOKEN(TOK_RDB_ROLE_IN_USE, "RDB$ROLE_IN_USE", false)
389390
PARSER_TOKEN(TOK_RDB_SET_CONTEXT, "RDB$SET_CONTEXT", false)
390391
PARSER_TOKEN(TOK_RDB_SYSTEM_PRIVILEGE, "RDB$SYSTEM_PRIVILEGE", false)

src/dsql/parse.y

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,7 @@ using namespace Firebird;
697697
%token <metaNamePtr> TIMEZONE_NAME
698698
%token <metaNamePtr> UNICODE_CHAR
699699
%token <metaNamePtr> UNICODE_VAL
700+
%token <metaNamePtr> RDB_RESET_CONTEXT
700701

701702
// precedence declarations for expression evaluation
702703

@@ -8275,6 +8276,7 @@ system_function_std_syntax
82758276
| RAND
82768277
| RDB_GET_CONTEXT
82778278
| RDB_GET_TRANSACTION_CN
8279+
| RDB_RESET_CONTEXT
82788280
| RDB_ROLE_IN_USE
82798281
| RDB_SET_CONTEXT
82808282
| REPLACE

src/jrd/SysFunction.cpp

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ void setParamsDateDiff(DataTypeUtilBase* dataTypeUtil, const SysFunction* functi
235235
void setParamsEncrypt(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args);
236236
void setParamsFirstLastDay(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, int argsCount, dsc** args);
237237
void setParamsGetSetContext(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, int argsCount, dsc** args);
238+
void setParamsResetContext(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, int argsCount, dsc** args);
238239
void setParamsHash(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args);
239240
void setParamsMakeDbkey(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, int argsCount, dsc** args);
240241
void setParamsOverlay(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, int argsCount, dsc** args);
@@ -327,6 +328,7 @@ dsc* evlFloor(thread_db* tdbb, const SysFunction* function, const NestValueArray
327328
dsc* evlGenUuid(thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure);
328329
dsc* evlGetContext(thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure);
329330
dsc* evlSetContext(thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure);
331+
dsc* evlResetContext(thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure);
330332
dsc* evlGetTranCN(thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure);
331333
dsc* evlHash(thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure);
332334
dsc* evlLeft(thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure);
@@ -358,7 +360,8 @@ dsc* evlUuidToChar(thread_db* tdbb, const SysFunction* function, const NestValue
358360
// System context function names
359361
const char
360362
RDB_GET_CONTEXT[] = "RDB$GET_CONTEXT",
361-
RDB_SET_CONTEXT[] = "RDB$SET_CONTEXT";
363+
RDB_SET_CONTEXT[] = "RDB$SET_CONTEXT",
364+
RDB_RESET_CONTEXT[] = "RDB$RESET_CONTEXT";
362365

363366
// Context namespace names
364367
const char
@@ -845,6 +848,18 @@ void setParamsGetSetContext(DataTypeUtilBase*, const SysFunction*, int argsCount
845848
}
846849

847850

851+
void setParamsResetContext(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args)
852+
{
853+
fb_assert(argsCount == 1);
854+
855+
if (args[0]->isUnknown())
856+
{
857+
args[0]->makeVarying(80, ttype_none);
858+
args[0]->setNullable(true);
859+
}
860+
}
861+
862+
848863
void setParamsHash(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args)
849864
{
850865
fb_assert(argsCount == 1 || argsCount == 2);
@@ -4961,6 +4976,58 @@ dsc* evlSetContext(thread_db* tdbb, const SysFunction*, const NestValueArray& ar
49614976
}
49624977

49634978

4979+
dsc* evlResetContext(thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure)
4980+
{
4981+
fb_assert(args.getCount() == 1);
4982+
4983+
Attachment* const attachment = tdbb->getAttachment();
4984+
jrd_tra* const transaction = tdbb->getTransaction();
4985+
Request* request = tdbb->getRequest();
4986+
4987+
const dsc* nameSpace = EVL_expr(tdbb, request, args[0]);
4988+
if (!nameSpace) // Complain if namespace is null
4989+
ERR_post(Arg::Gds(isc_ctx_bad_argument) << Arg::Str(RDB_RESET_CONTEXT));
4990+
4991+
const string nameSpaceStr(MOV_make_string2(tdbb, nameSpace, ttype_none));
4992+
4993+
StringMap* contextVars = nullptr;
4994+
4995+
if (nameSpaceStr == USER_SESSION_NAMESPACE)
4996+
{
4997+
if (!attachment)
4998+
{
4999+
fb_assert(false);
5000+
return nullptr;
5001+
}
5002+
5003+
contextVars = &attachment->att_context_vars;
5004+
}
5005+
else if (nameSpaceStr == USER_TRANSACTION_NAMESPACE)
5006+
{
5007+
if (!transaction)
5008+
{
5009+
fb_assert(false);
5010+
return nullptr;
5011+
}
5012+
5013+
contextVars = &transaction->tra_context_vars;
5014+
}
5015+
else
5016+
{
5017+
// "Invalid namespace name %s passed to %s"
5018+
ERR_post(Arg::Gds(isc_ctx_namespace_invalid) <<
5019+
Arg::Str(nameSpaceStr) << Arg::Str(RDB_RESET_CONTEXT));
5020+
}
5021+
5022+
impure->vlu_desc.makeLong(0, &impure->vlu_misc.vlu_long);
5023+
impure->vlu_misc.vlu_long = (SLONG) contextVars->count();
5024+
5025+
contextVars->clear();
5026+
5027+
return &impure->vlu_desc;
5028+
}
5029+
5030+
49645031
dsc* evlGetTranCN(thread_db* tdbb, const SysFunction* function, const NestValueArray& args,
49655032
impure_value* impure)
49665033
{
@@ -6958,6 +7025,7 @@ const SysFunction SysFunction::functions[] =
69587025
{RDB_GET_CONTEXT, 2, 2, true, setParamsGetSetContext, makeGetSetContext, evlGetContext, NULL},
69597026
{"RDB$GET_TRANSACTION_CN", 1, 1, false, setParamsInt64, makeGetTranCN, evlGetTranCN, NULL},
69607027
{"RDB$ROLE_IN_USE", 1, 1, true, setParamsAsciiVal, makeBooleanResult, evlRoleInUse, NULL},
7028+
{RDB_RESET_CONTEXT, 1, 1, false, setParamsResetContext, makeLongResult, evlResetContext, NULL},
69617029
{RDB_SET_CONTEXT, 3, 3, false, setParamsGetSetContext, makeGetSetContext, evlSetContext, NULL},
69627030
{"RDB$SYSTEM_PRIVILEGE", 1, 1, true, NULL, makeBooleanResult, evlSystemPrivilege, NULL},
69637031
{"REPLACE", 3, 3, true, setParamsFromList, makeReplace, evlReplace, NULL},

0 commit comments

Comments
 (0)