Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions doc/sql.extensions/README.context_variables2
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@ Function:
connection and current transaction. Also they provide means to associate
and retrieve user context data with transaction or connection.

Author:
Nickolay Samofatov <nickolay at broadviewsoftware dot com>
Authors:
Nickolay Samofatov <nickolay at broadviewsoftware dot com>,
Vladyslav Khorsun <vkhorsun at firebirdsql dot org>

Format:
RDB$SET_CONTEXT( <namespace>, <variable>, <value> )
RDB$GET_CONTEXT( <namespace>, <variable> )
RDB$RESET_CONTEXT( <namespace> )

Returned value:
INTEGER for RDB$SET_CONTEXT
INTEGER for RDB$SET_CONTEXT, RDB$RESET_CONTEXT
VARCHAR(32765) for RDB$GET_CONTEXT

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

RDB$RESET_CONTEXT removes all variables from given context. It returns count
of removed variables.

Currently, there is a fixed number of pre-defined namespaces you may use.

USER_SESSION namespace offers access to session-specific user-defined
Expand Down Expand Up @@ -183,3 +188,5 @@ execute procedure set_context('skidder', 1);
insert into journal(jrn_id) values(0);

commit;

SELECT RDB$RESET_CONTEXT('USER_SESSION') FROM RDB$DATABASE;
1 change: 1 addition & 0 deletions src/common/ParserTokens.h
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ PARSER_TOKEN(TOK_RDB_ERROR, "RDB$ERROR", false)
PARSER_TOKEN(TOK_RDB_GET_CONTEXT, "RDB$GET_CONTEXT", false)
PARSER_TOKEN(TOK_RDB_GET_TRANSACTION_CN, "RDB$GET_TRANSACTION_CN", false)
PARSER_TOKEN(TOK_RDB_RECORD_VERSION, "RDB$RECORD_VERSION", false)
PARSER_TOKEN(TOK_RDB_RESET_CONTEXT, "RDB$RESET_CONTEXT", false)
PARSER_TOKEN(TOK_RDB_ROLE_IN_USE, "RDB$ROLE_IN_USE", false)
PARSER_TOKEN(TOK_RDB_SET_CONTEXT, "RDB$SET_CONTEXT", false)
PARSER_TOKEN(TOK_RDB_SYSTEM_PRIVILEGE, "RDB$SYSTEM_PRIVILEGE", false)
Expand Down
2 changes: 2 additions & 0 deletions src/dsql/parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,7 @@ using namespace Firebird;
%token <metaNamePtr> TRUNCATE
%token <metaNamePtr> UNLIST
%token <metaNamePtr> WITHIN
%token <metaNamePtr> RDB_RESET_CONTEXT

// precedence declarations for expression evaluation

Expand Down Expand Up @@ -9055,6 +9056,7 @@ system_function_std_syntax
| RAND
| RDB_GET_CONTEXT
| RDB_GET_TRANSACTION_CN
| RDB_RESET_CONTEXT
| RDB_ROLE_IN_USE
| RDB_SET_CONTEXT
| REPLACE
Expand Down
70 changes: 69 additions & 1 deletion src/jrd/SysFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ void setParamsDateDiff(DataTypeUtilBase* dataTypeUtil, const SysFunction* functi
void setParamsEncrypt(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args);
void setParamsFirstLastDay(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, int argsCount, dsc** args);
void setParamsGetSetContext(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, int argsCount, dsc** args);
void setParamsResetContext(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, int argsCount, dsc** args);
void setParamsHash(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args);
void setParamsMakeDbkey(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, int argsCount, dsc** args);
void setParamsOverlay(DataTypeUtilBase* dataTypeUtil, const SysFunction* function, int argsCount, dsc** args);
Expand Down Expand Up @@ -329,6 +330,7 @@ dsc* evlFloor(thread_db* tdbb, const SysFunction* function, const NestValueArray
dsc* evlGenUuid(thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure);
dsc* evlGetContext(thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure);
dsc* evlSetContext(thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure);
dsc* evlResetContext(thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure);
dsc* evlGetTranCN(thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure);
dsc* evlHash(thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure);
dsc* evlLeft(thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure);
Expand Down Expand Up @@ -360,7 +362,8 @@ dsc* evlUuidToChar(thread_db* tdbb, const SysFunction* function, const NestValue
// System context function names
constexpr char
RDB_GET_CONTEXT[] = "RDB$GET_CONTEXT",
RDB_SET_CONTEXT[] = "RDB$SET_CONTEXT";
RDB_SET_CONTEXT[] = "RDB$SET_CONTEXT",
RDB_RESET_CONTEXT[] = "RDB$RESET_CONTEXT";

// Context namespace names
constexpr char
Expand Down Expand Up @@ -863,6 +866,18 @@ void setParamsGetSetContext(DataTypeUtilBase*, const SysFunction*, int argsCount
}


void setParamsResetContext(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args)
{
fb_assert(argsCount == 1);

if (args[0]->isUnknown())
{
args[0]->makeVarying(80, ttype_none);
args[0]->setNullable(true);
}
}


void setParamsHash(DataTypeUtilBase*, const SysFunction*, int argsCount, dsc** args)
{
fb_assert(argsCount == 1 || argsCount == 2);
Expand Down Expand Up @@ -5005,6 +5020,58 @@ dsc* evlSetContext(thread_db* tdbb, const SysFunction*, const NestValueArray& ar
}


dsc* evlResetContext(thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure)
{
fb_assert(args.getCount() == 1);

Jrd::Attachment* attachment = tdbb->getAttachment();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Jrd::Attachment* attachment = tdbb->getAttachment();
Jrd::Attachment* const attachment = tdbb->getAttachment();

jrd_tra* transaction = tdbb->getTransaction();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
jrd_tra* transaction = tdbb->getTransaction();
jrd_tra* const transaction = tdbb->getTransaction();

Request* request = tdbb->getRequest();

const dsc* nameSpace = EVL_expr(tdbb, request, args[0]);
if (!nameSpace) // Complain if namespace is null
ERR_post(Arg::Gds(isc_ctx_bad_argument) << Arg::Str(RDB_RESET_CONTEXT));

const string nameSpaceStr(MOV_make_string2(tdbb, nameSpace, ttype_none));

StringMap* contextVars = nullptr;

if (nameSpaceStr == USER_SESSION_NAMESPACE)
{
if (!attachment)
{
fb_assert(false);
return nullptr;
}

contextVars = &attachment->att_context_vars;
}
else if (nameSpaceStr == USER_TRANSACTION_NAMESPACE)
{
if (!transaction)
{
fb_assert(false);
return nullptr;
}

contextVars = &transaction->tra_context_vars;
}
else
{
// "Invalid namespace name %s passed to %s"
ERR_post(Arg::Gds(isc_ctx_namespace_invalid) <<
Arg::Str(nameSpaceStr) << Arg::Str(RDB_RESET_CONTEXT));
}

impure->vlu_desc.makeLong(0, &impure->vlu_misc.vlu_long);
impure->vlu_misc.vlu_long = (SLONG) contextVars->count();

contextVars->clear();

return &impure->vlu_desc;
}


dsc* evlGetTranCN(thread_db* tdbb, const SysFunction* function, const NestValueArray& args,
impure_value* impure)
{
Expand Down Expand Up @@ -6976,6 +7043,7 @@ const SysFunction SysFunction::functions[] =
{RDB_GET_CONTEXT, 2, 2, true, setParamsGetSetContext, makeGetSetContext, evlGetContext, NULL},
{"RDB$GET_TRANSACTION_CN", 1, 1, false, setParamsInt64, makeGetTranCN, evlGetTranCN, NULL},
{"RDB$ROLE_IN_USE", 1, 1, true, setParamsAsciiVal, makeBooleanResult, evlRoleInUse, NULL},
{RDB_RESET_CONTEXT, 1, 1, false, setParamsResetContext, makeLongResult, evlResetContext, NULL},
{RDB_SET_CONTEXT, 3, 3, false, setParamsGetSetContext, makeGetSetContext, evlSetContext, NULL},
{"RDB$SYSTEM_PRIVILEGE", 1, 1, true, NULL, makeBooleanResult, evlSystemPrivilege, NULL},
{"REPLACE", 3, 3, true, setParamsFromList, makeReplace, evlReplace, NULL},
Expand Down
Loading