Skip to content

Package constants#8916

Open
Noremos wants to merge 124 commits intoFirebirdSQL:masterfrom
Noremos:metacache_package_constants
Open

Package constants#8916
Noremos wants to merge 124 commits intoFirebirdSQL:masterfrom
Noremos:metacache_package_constants

Conversation

@Noremos
Copy link
Copy Markdown
Contributor

@Noremos Noremos commented Feb 25, 2026

Package Constants

This PR adds a new database object - Package Constant (#1036). It is a constant value located in a package header (public visibility) or a package body (private visibility). See README.packages.txt for more information.

SYNTAX

Creation:

CREATE PACKAGE <package_name>
AS
BEGIN
    CONSTANT <constant_name> <type> = <constant_expr>; -- public constant
    -- package routines
END

CREATE PACKAGE BODY <package_name>
AS
BEGIN
    CONSTANT <constant_name> <type> = <constant_expr>; -- private constant
    -- package routines
END

<constant_expr> is an expression that remains unchanged after recompilation.

Package constants can be queried using the expression <package_name>.<consatnt_name> outside the package (<consatnt_name> must be a public constant) and using the expression <consatnt_name> inside the package.
To query a constant, the user/role must have USAGE permission on the package.

Other SQL extensions:

COMMENT ON CONSTANT [<schema>.]<package>.<const_name> IS <text>
GRANT USAGE ON PACKAGE  [<schema>.]<package_name> to [<user|role>] <name> [<grant_option>] [<granted_by>]
REVOKE USAGE ON PACKAGE  [<schema>.]<package_name> FROM <user|role> <name> [<granted_by>]
SHOW CONST[ANTS]  [ [<schema>.]<package_name> ] -- isql only

Usage examples:

set autoterm;
CREATE PACKAGE MY_PACKAGE
AS
BEGIN
    CONSTANT PUBLIC_CONST INTEGER = 10;
    FUNCTION MY_SECRET_PRINT() RETURNS INT;
END;

CREATE PACKAGE BODY MY_PACKAGE
AS
BEGIN
    CONSTANT SECRET_1 INTEGER = 15;
    CONSTANT SECRET_2 INTEGER = 30;

    FUNCTION MY_SECRET_PRINT() RETURNS INT
    AS
    BEGIN
        RETURN SECRET_1 * SECRET_2;
    END
END;
commit;

select MY_PACKAGE.PUBLIC_CONST from rdb$database ;
select MY_PACKAGE.MY_SECRET_PRINT() from rdb$database;

System Constants

As an exmaple, 3 consatnts have been added to the RDB$BLOB_UTIL package

FROM_BEGIN  : INTEGER = 0
FROM_CURRENT : INTEGER = 1
FROM_END : INTEGER = 2

System metadata changes

New system table - RDB$CONSTANTS

Table: SYSTEM.RDB$CONSTANTS
RDB$CONSTANT_NAME               (SYSTEM.RDB$FIELD_NAME) CHAR(63) CHARACTER SET SYSTEM.UTF8 Nullable 
RDB$PACKAGE_NAME                (SYSTEM.RDB$PACKAGE_NAME) CHAR(63) CHARACTER SET SYSTEM.UTF8 Nullable 
RDB$FIELD_SOURCE                (SYSTEM.RDB$FIELD_NAME) CHAR(63) CHARACTER SET SYSTEM.UTF8 Nullable 
RDB$PRIVATE_FLAG                (SYSTEM.RDB$SYSTEM_NULLFLAG) SMALLINT Nullable 
RDB$CONSTANT_BLR                (SYSTEM.RDB$CONSTANT_BLR) BLOB segment 80, subtype BLR Nullable 
RDB$CONSTANT_SOURCE             (SYSTEM.RDB$SOURCE) BLOB segment 80, subtype TEXT CHARACTER SET SYSTEM.UTF8 Nullable 
RDB$SCHEMA_NAME                 (SYSTEM.RDB$SCHEMA_NAME) CHAR(63) CHARACTER SET SYSTEM.UTF8 Nullable 
RDB$DESCRIPTION                 (SYSTEM.RDB$DESCRIPTION) BLOB segment 80, subtype TEXT CHARACTER SET SYSTEM.UTF8 Nullable 
CONSTRAINT RDB$INDEX_98:
  Unique key (RDB$SCHEMA_NAME, RDB$PACKAGE_NAME, RDB$CONSTANT_NAME)

A new field has been added to RDB$PACKAGES - RDB$PACKAGE_ID

New indexes:

Unique key SYSTEM.RDB$CONSTANTS  (RDB$SCHEMA_NAME, RDB$PACKAGE_NAME, RDB$CONSTANT_NAME)
Unique key SYSTEM.RDB$PACKAGES (RDB$PACKAGE_ID)

Implementation

Packages have been added to the metacaching system. Since it relies heavily on identifiers, a new ID field (RDB$PACKAGE_ID) has been added to the RDB$PACKAGES table. Constants are stored as an array in the package metacaching object, with a constant_name-to-array_id mapping.

There are also two important points:

  1. All nodes now have an 'is constant' flag, similar to the 'is deterministic' flag. This is necessary to determine whether an expression can initialize a constant.
  2. In the CreateAlterPackageNode node, a lot of code had to be copied and pasted, and adding constants led to complete chaos. Therefore, I decided to slightly refactor this node. All functionality remains the same; only code duplication was removed.

@sim1984
Copy link
Copy Markdown
Contributor

sim1984 commented Feb 25, 2026

Are comments supported for constants? I didn't see this in the documentation.
Let me clarify what I mean:

COMMENT ON CONSTANT [<schema>.]<package>.<const_name> IS 'Text'

Comments are simply supported for packaged procedures and functions. It would make sense to do the same for constants (and any package objects, for that matter).

COMMENT ON PROCEDURE [<schema>.]<package>.<proc_name> IS 'Text';
COMMENT ON FUNCTION [<schema>.]<package>.<func_name> IS 'Text';

@Noremos
Copy link
Copy Markdown
Contributor Author

Noremos commented Feb 25, 2026

Are comments supported for constants?

No, I didn't plan to implement comments, but I think it's possible. I will take a look

AlexeyMochalov and others added 19 commits April 27, 2026 10:25
Raise EDS rollback exception before the connection can be released by
deleteTransaction(). Cleanup is still performed by catching the error and rethrow the original exception.
…multi-level LEFT JOINs. I tried it in 2022 but found regressions. Now I cannot reproduce them locally after the fix, so I'm willing to analyze the complete QA results.
…onnect (FirebirdSQL#8992)

* fix(udr): Add cleanup of UDR objects from `Engine` on attachment disconnect

* Revert "fix(udr): Add cleanup of UDR objects from `Engine` on attachment disconnect"

This reverts commit 80581c5.

* fix(udr): Add cleanup of UDR objects from Engine on attachment disconnect

---------

Co-authored-by: Artyom Ivanov <artyom.ivanov@red-soft.ru>
@dyemanov
Copy link
Copy Markdown
Member

dyemanov commented May 3, 2026

@Noremos Please resolve the conflict.
@AlexPeshkoff, do you plan to take one more look before it gets merged?

@Noremos
Copy link
Copy Markdown
Contributor Author

Noremos commented May 3, 2026

@Noremos Please resolve the conflict

Done

GRANT SELECT ON TABLE secret TO PACKAGE pk_secret;
GRANT EXECUTE ON PACKAGE pk_secret TO ROLE role_secret;

To use package constants in a select expression, a USAGE permission is required:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I suppose not only in a "select expression", but in any place outside the package it was defined.

Comment thread src/burp/backup.epp

void write_constants()
{
Firebird::IRequest* req_handle1 = nullptr;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This file already has using namespace Firebird. Do not qualify things with extra Firebird::.

Comment thread src/burp/backup.epp
CONST.RDB$PACKAGE_NAME EQ PKG.RDB$PACKAGE_NAME AND
PKG.RDB$SYSTEM_FLAG NE 1
{
QualifiedMetaString name(CONST.RDB$CONSTANT_NAME);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why not put the schema and package name here directly?

Comment thread src/burp/backup.epp
BURP_verbose(USHORT(isc_gbak_writing_constant), SafeArg() << name.toQuotedString().data());
put(tdgbl, att_end);
}
END_FOR;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
END_FOR;
END_FOR

Comment thread src/burp/backup.epp
END_FOR;
ON_ERROR
general_on_error();
END_ERROR;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
END_ERROR;
END_ERROR

Comment thread src/jrd/Package.epp
attachment->att_database->deletePool(csb_pool);
});

csb_pool = attachment->att_database->createPool(ALLOC_ARGS0);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Based in old code.

Comment thread src/jrd/Package.h
*/


#ifndef JRD_CONSTANT_H
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Wrong marker name.

Comment thread src/jrd/SysFunction.cpp
{"EXP", 1, 1, DEFAULT, setParamsDblDec, makeDblDecResult, evlExp, NULL},
{"FIRST_DAY", 2, 2, DEFAULT, setParamsFirstLastDay, makeFirstLastDayResult, evlFirstLastDay, (void*) funFirstDay},
{"FLOOR", 1, 1, DEFAULT, setParamsDblDec, makeCeilFloor, evlFloor, NULL},
{"GEN_UUID", 0, 0, CONSTANT, NULL, makeUuid, evlGenUuid, NULL},
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

GEN_UUID is not constant.

Comment thread src/jrd/SystemPackages.h
const std::initializer_list<UCHAR> aValueBlr = {}
)
: name(aName),
fieldId(aFieldId),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Wrong indentation.

Comment thread src/jrd/vio.cpp

EVL_field(0, rpb->rpb_record, f_const_package, &desc2);
MOV_get_metaname(tdbb, &desc2, object_name.package);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change

@Noremos
Copy link
Copy Markdown
Contributor Author

Noremos commented May 4, 2026

@asfernandes, thanks for the review. I'll resolve the issues tomorrow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants