Skip to content
Merged
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
8 changes: 6 additions & 2 deletions src/dsql/PackageNodes.epp
Original file line number Diff line number Diff line change
Expand Up @@ -550,15 +550,19 @@ ValueExprNode* PackageReferenceNode::pass2(thread_db* tdbb, CompilerScratch* csb

dsc* PackageReferenceNode::execute(thread_db* tdbb, Request* request) const
{
impure_value* outputImpure = request->getImpure<impure_value>(m_impureOffset);
switch (m_itemType)
{
case blr_pkg_reference_to_constant:
{
Package* package = m_package(request->getResources());
package->checkReload(tdbb);

EVL_make_value(tdbb, package->findConstant(m_fullName)->makeValue(tdbb, request), outputImpure);
dsc* constantDsc = package->findConstant(m_fullName)->makeValue(tdbb, request);
if (constantDsc == nullptr || constantDsc->isNull())
return nullptr;

impure_value* outputImpure = request->getImpure<impure_value>(m_impureOffset);
EVL_make_value(tdbb, constantDsc, outputImpure);
return &outputImpure->vlu_desc;
}
default:
Expand Down
7 changes: 4 additions & 3 deletions src/dsql/parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -3338,10 +3338,11 @@ replace_package_body_clause

%type <createPackageConstantNode> package_const_item
package_const_item
: symbol_package_const_name data_type_descriptor '=' value
: symbol_package_const_name data_type_descriptor collate_clause '=' value
{
$$ = newNode<CreatePackageConstantNode>(*$1, $2, $4);
$$->source = makeParseStr(YYPOSNARG(3), YYPOSNARG(4));
setCollate($2, $3);
$$ = newNode<CreatePackageConstantNode>(*$1, $2, $5);
$$->source = makeParseStr(YYPOSNARG(4), YYPOSNARG(5));
}
;

Expand Down
38 changes: 27 additions & 11 deletions src/jrd/Package.epp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ DATABASE DB = FILENAME "ODS.RDB";

bool ConstantValue::hash(thread_db* tdbb, Firebird::sha512& digest) const
{
fb_assert(m_value.vlu_desc.dsc_dtype != 0);
fb_assert(m_value.vlu_desc.dsc_dtype != dtype_unknown);
digest.process(sizeof(m_value.vlu_desc), &m_value.vlu_desc);

return true;
Expand Down Expand Up @@ -84,8 +84,10 @@ dsc ConstantValue::getDesc(thread_db* tdbb, Jrd::jrd_tra* transaction, const Qua
CSetId(FLD.RDB$CHARACTER_SET_ID),
CollId(FLD.RDB$COLLATION_ID));

if (!succeed)
(Arg::Gds(isc_bad_constant_desc) << Arg::Str(name.toQuotedString())).raise();
if (!succeed)
(Arg::Gds(isc_bad_constant_desc) << Arg::Str(name.toQuotedString())).raise();

desc.setNullable(FLD.RDB$NULL_FLAG.NULL || FLD.RDB$NULL_FLAG == 0);
}

END_FOR
Expand Down Expand Up @@ -156,12 +158,12 @@ dsc* ConstantValue::makeValue(thread_db* tdbb, Request* request)
{
{
ReadLockGuard guard(m_makeValueLock, FB_FUNCTION);
if (m_value.vlu_desc.dsc_address != nullptr)
if (m_value.vlu_desc.dsc_dtype != dtype_unknown)
return &m_value.vlu_desc;
}

WriteLockGuard guard(m_makeValueLock, FB_FUNCTION);
if (m_value.vlu_desc.dsc_address != nullptr) // Extra check in case of two callers waiting
if (m_value.vlu_desc.dsc_dtype != dtype_unknown) // Extra check in case of two callers waiting
return &m_value.vlu_desc;

Attachment* attachment = tdbb->getAttachment();
Expand Down Expand Up @@ -196,14 +198,11 @@ dsc* ConstantValue::makeValue(thread_db* tdbb, Request* request)

TRA_attach_request(tdbb->getTransaction(), request);

const dsc* temp = EVL_expr(tdbb, request, static_cast<ValueExprNode*>(csb->csb_node));
EVL_make_value(tdbb, temp, &m_value, &getPool());
// Execute it here, while AutoSetRestore2 is active
executeCsbNode(tdbb, csb);
}
else
{
const dsc* temp = EVL_expr(tdbb, request, static_cast<ValueExprNode*>(csb->csb_node));
EVL_make_value(tdbb, temp, &m_value, &getPool());
}
executeCsbNode(tdbb, csb);
}
catch (const Exception& ex)
{
Expand All @@ -226,6 +225,23 @@ dsc* ConstantValue::makeValue(thread_db* tdbb, Request* request)
return &m_value.vlu_desc;
}

void ConstantValue::executeCsbNode(thread_db* tdbb, CompilerScratch* csb)
{
fb_assert(csb->csb_node && csb->csb_node->getKind() == DmlNode::KIND_VALUE);
ValueExprNode* exprNode = static_cast<ValueExprNode*>(csb->csb_node);
Comment thread
Noremos marked this conversation as resolved.

const dsc* temp = EVL_expr(tdbb, tdbb->getRequest(), exprNode);
if (temp != nullptr)
{
EVL_make_value(tdbb, temp, &m_value, &getPool());
}
else
{
exprNode->getDesc(tdbb, csb, &m_value.vlu_desc);
m_value.vlu_desc.setNull();
}
}

ConstantValue& ConstantsCache::add(const QualifiedName& constName, const bool isPrivate)
{
fb_assert(!nameMap.exist(constName));
Expand Down
3 changes: 3 additions & 0 deletions src/jrd/Package.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

namespace Jrd
{
class CompilerScratch;
class DsqlCompilerScratch;
class dsql_fld;

Expand Down Expand Up @@ -84,6 +85,8 @@ class ConstantValue final : public Firebird::PermanentStorage
dsc* makeValue(thread_db* tdbb, Request* request);

private:
void executeCsbNode(thread_db* tdbb, CompilerScratch* csb);

// Lock in case of makeing value during the execute state
Firebird::RWLock m_makeValueLock{};

Expand Down
Loading