Conversation
…rong impure cache usage
|
Are comments supported for constants? I didn't see this in the documentation. 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). |
No, I didn't plan to implement comments, but I think it's possible. I will take a look |
Ok, it wasn't that hard, I implemented the feature as suggested. Examples: |
AlexPeshkoff
left a comment
There was a problem hiding this comment.
Generally OK, just minor correction please
src/jrd/Constant.epp
Outdated
| if (ssDefiner.asBool()) | ||
| invoker = dbb->getUserId(getPermanent()->owner); | ||
|
|
||
| makeValue(tdbb, attachment, CONST.RDB$CONSTANT_BLR); |
There was a problem hiding this comment.
I'm not 100% sure - is it OK to invoke makeValue() when MINISCAN is set? Certainly, constants should not have as complex dependencies as procedures/functions, but anyway - may be better leave it for reload in such a case?
There was a problem hiding this comment.
Changed to:
if ((flags & CacheFlag::MINISCAN) == 0)
makeValue(tdbb, attachment, CONST.RDB$CONSTANT_BLR);
else
this->flReload = true; // Call makeValue in reload
| A package constant is a value initialized by a constant expression. | ||
| A constant expression is defined by a simple rule: its value does not change after recompilation. | ||
| Constants declared in the package specification are publicly visible and can be referenced using | ||
| the <package>.<constant_name> notation. |
There was a problem hiding this comment.
Add syntax about optional schema.
| Constants declared in the package specification are publicly visible and can be referenced using | ||
| the <package>.<constant_name> notation. | ||
| Constants declared in the package body are private and cannot be accessed from outside the package. | ||
| However, they can be referenced directly by <constant_name> within <procedure_impl> and <function_impl>. |
There was a problem hiding this comment.
This appears that package header constant cannot be referenced in its own body without the qualified package name.
There was a problem hiding this comment.
I corrected the desription
src/burp/OdsDetection.epp
Outdated
| {"RDB$PACKAGES", 0, DB_VERSION_DDL12}, // FB3 | ||
| {"RDB$PUBLICATIONS", 0, DB_VERSION_DDL13}, // FB4 | ||
| {"RDB$SCHEMAS", 0, DB_VERSION_DDL14}, // FB6 | ||
| {"RDB$CONSTANTS", 0, DB_VERSION_DDL14},// RDB6 |
There was a problem hiding this comment.
It's not needed at all, as DB_VERSION_DDL14 is already detected.
| { | ||
| QualifiedName constantName(subName, name.schema, name.object); // name is a package | ||
| if (constantName.schema.isEmpty()) | ||
| constantName.schema = PUBLIC_SCHEMA; |
There was a problem hiding this comment.
This was not necessary in any other command in DdlNodes.
Looks incorrect here.
There was a problem hiding this comment.
Actuality, as I can see, something similar (but more more complicated) is happening for procedures and functions in resolveRoutineOrRelation(...). Without the check, scheme will remain NULL.
src/dsql/DdlNodes.epp
Outdated
| break; | ||
|
|
||
| case obj_package_constant: | ||
| SCL_check_package(tdbb, QualifiedName(name.package, name.schema), SCL_alter); |
There was a problem hiding this comment.
Why it's not name.getSchemaAndPackage() like for procedures and functions?
There was a problem hiding this comment.
Have not known about this function. Thanks for the tip!
src/jrd/relations.h
Outdated
| END_RELATION | ||
|
|
||
| // Relation 59 (RDB$CONSTANTS) | ||
| RELATION(nam_constants, rel_constants, ODS_13_1, rel_persistent) |
There was a problem hiding this comment.
| RELATION(nam_constants, rel_constants, ODS_13_1, rel_persistent) | |
| RELATION(nam_constants, rel_constants, ODS_14_0, rel_persistent) |
src/jrd/relations.h
Outdated
| RELATION(nam_constants, rel_constants, ODS_13_1, rel_persistent) | ||
| FIELD(f_const_name, nam_const_name, fld_f_name, 0, ODS_14_0) | ||
| FIELD(f_const_id, nam_const_id, fld_const_id, 0, ODS_14_0) | ||
| FIELD(f_const_package, nam_pkg_name, fld_pkg_name, 1, ODS_14_0) |
There was a problem hiding this comment.
Why are some fields using 1?
There was a problem hiding this comment.
My bad. Changed to 0.
src/jrd/SysFunction.cpp
Outdated
|
|
||
|
|
||
|
|
||
| constexpr auto DEFAULT = SysFunction::DETERMINISTIC | SysFunction::CONSTANT; |
| class SysFunction | ||
| { | ||
| public: | ||
| enum Flags : UCHAR |
There was a problem hiding this comment.
enum class, please.
SysFunction::NONE is completely misleading.
There was a problem hiding this comment.
enum class is problematic for flags. You have to redefine bit operations or cast the type each time. IMHO, simple enum inside a class is a good choice in such case
There was a problem hiding this comment.
And could you clarify what exactly is confusing about SysFunction::NONE?
| #include "../jrd/Attachment.h" | ||
| #include "../jrd/scl_proto.h" | ||
|
|
||
| #include "../common/dsc_proto.h" // DSC_make_descriptor |
There was a problem hiding this comment.
I left the review of this file for last, and given the amount of things I saw, didn't read it.
I think the amout of changes in this file and your initial comments about it seems not correctly.
The file was maintanable and it required no extra efforts or such things in what I'm doing now (LTTs in packages).
Your approach seems incorrect for me and is making things more complicate.
There was a problem hiding this comment.
I was prepared for the changes to this file to be criticized. But if things remain as is, technical debt will accumulate, and over time, everything will become unmaintainable. If @AlexPeshkoff and @dyemanov also think this changes is outside the scope of the PR, I will revert the changes to this file.
Co-authored-by: Adriano dos Santos Fernandes <529415+asfernandes@users.noreply.github.com>
dyemanov
left a comment
There was a problem hiding this comment.
It's the first part of the review, PackageNodes.epp will be reviewed separately.
src/dsql/DdlNodes.epp
Outdated
| break; | ||
|
|
||
| case obj_package_constant: | ||
| SCL_check_package(tdbb, QualifiedName(name.package, name.schema), SCL_alter); |
There was a problem hiding this comment.
| SCL_check_package(tdbb, QualifiedName(name.package, name.schema), SCL_alter); | |
| SCL_check_package(tdbb, name.getSchemaAndPackage(), SCL_alter); |
|
|
||
| bool constant() const override | ||
| { | ||
| return true; |
There was a problem hiding this comment.
It should be false for RecordKeyNode.
src/burp/OdsDetection.epp
Outdated
| {"RDB$PACKAGES", 0, DB_VERSION_DDL12}, // FB3 | ||
| {"RDB$PUBLICATIONS", 0, DB_VERSION_DDL13}, // FB4 | ||
| {"RDB$SCHEMAS", 0, DB_VERSION_DDL14}, // FB6 | ||
| {"RDB$CONSTANTS", 0, DB_VERSION_DDL14},// RDB6 |
There was a problem hiding this comment.
It's not needed at all, as DB_VERSION_DDL14 is already detected.
src/dsql/Nodes.h
Outdated
| virtual bool unmappable(const MapNode* mapNode, StreamType shellStream) const; | ||
|
|
||
| // Check if expression returns constant result | ||
| virtual bool constant() const; |
There was a problem hiding this comment.
I'd define it as returning false here and override only in nodes where true should be returned. No need to pollute the codebase with the default implementation.
There was a problem hiding this comment.
It actually depends on meaning of "constant result" here. For me it looks like complete duplication of deterministic(). If I'm wrong, what's the difference?
src/dsql/ExprNodes.cpp
Outdated
| dsql_ctx packageContext(dsqlScratch->getPool()); | ||
| { // Consatnts | ||
|
|
||
| const QualifiedName consatntName(dsqlName, |
| case obj_schemas: | ||
| return "SQL$SCHEMAS"; | ||
| case obj_package_constant: | ||
| return "SQL$PACKAGE_CONSTANT"; |
There was a problem hiding this comment.
Constants belong to a package, AFAIU it cannot have it's own privileges, so there're no need in dedicated security classes. Or is it reserved for global constants, if they ever appear in the future?
| LCK_idx_rescan, // Index rescan lock | ||
| LCK_prc_rescan, // Procedure rescan lock | ||
| LCK_fun_rescan, // Function existence lock | ||
| LCK_constant_rescan, // Constant existence lock |
There was a problem hiding this comment.
Is it also a preparation for global constants? Because otherwise it's the package (not the constant) that should be cached/locked. Packaged constants are never altered/dropped individually, AFAIU.
| class DsqlCompilerScratch; | ||
| class dsql_fld; | ||
|
|
||
| class Constant final : public Routine |
There was a problem hiding this comment.
Maybe it should be refactored, so that Routine and Constant have the same base class?
| EVL_field(0, rpb->rpb_record, f_const_id, &desc2); | ||
| id = MOV_get_long(tdbb, &desc2, 0); | ||
|
|
||
| Constant::lookup(tdbb, id); |
There was a problem hiding this comment.
You don't use the result. Is it expected to throw if a constant is not found? Maybe some other method -- e.g. checkExistance() -- is worth adding for readability?
src/dsql/ExprNodes.h
Outdated
| void genBlr(DsqlCompilerScratch* dsqlScratch) override; | ||
| void make(DsqlCompilerScratch* dsqlScratch, dsc* desc) override; | ||
|
|
||
| bool constant() const override |
There was a problem hiding this comment.
I may agree with Adriano from the safety POV (new nodes are never introduced as constant by mistake), but I don't like polluting the every class with the common code.
And this means that deterministic() should also be changed -- not something I object but I'd prefer to see a clearer code.
|
No code for backup and restore the new table? |
This PR adds a new database object - Package Constant (#1036). See README.packages.txt for more information.
Usage examples:
The implementation has three key points: