From dd2fcfe18a4c917398607b679b1a48e5ef740da7 Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Sat, 6 Feb 2021 22:44:47 -0300 Subject: [PATCH] Feature CORE-6482 - System table with keywords. --- builds/win32/msvc12/engine.vcxproj | 4 +- builds/win32/msvc12/engine.vcxproj.filters | 8 +- builds/win32/msvc14/engine.vcxproj | 4 +- builds/win32/msvc14/engine.vcxproj.filters | 8 +- builds/win32/msvc15/engine.vcxproj | 4 +- builds/win32/msvc15/engine.vcxproj.filters | 8 +- src/jrd/KeywordsTable.cpp | 101 +++++++++++++++++++++ src/jrd/KeywordsTable.h | 79 ++++++++++++++++ src/jrd/fields.h | 3 + src/jrd/names.h | 4 + src/jrd/opt.cpp | 5 + src/jrd/relations.h | 7 ++ 12 files changed, 229 insertions(+), 6 deletions(-) create mode 100644 src/jrd/KeywordsTable.cpp create mode 100644 src/jrd/KeywordsTable.h diff --git a/builds/win32/msvc12/engine.vcxproj b/builds/win32/msvc12/engine.vcxproj index 992af5e8fd8..a285a9e4e34 100644 --- a/builds/win32/msvc12/engine.vcxproj +++ b/builds/win32/msvc12/engine.vcxproj @@ -91,6 +91,7 @@ + @@ -276,6 +277,7 @@ + @@ -558,4 +560,4 @@ - \ No newline at end of file + diff --git a/builds/win32/msvc12/engine.vcxproj.filters b/builds/win32/msvc12/engine.vcxproj.filters index 0491f1a60e4..1926c2b3561 100644 --- a/builds/win32/msvc12/engine.vcxproj.filters +++ b/builds/win32/msvc12/engine.vcxproj.filters @@ -288,6 +288,9 @@ JRD files + + JRD files + JRD files @@ -824,6 +827,9 @@ Header files + + Header files + Header files @@ -1088,4 +1094,4 @@ Resource files - \ No newline at end of file + diff --git a/builds/win32/msvc14/engine.vcxproj b/builds/win32/msvc14/engine.vcxproj index 9ab9dc33b7e..9364d2cf1a2 100644 --- a/builds/win32/msvc14/engine.vcxproj +++ b/builds/win32/msvc14/engine.vcxproj @@ -91,6 +91,7 @@ + @@ -277,6 +278,7 @@ + @@ -560,4 +562,4 @@ - \ No newline at end of file + diff --git a/builds/win32/msvc14/engine.vcxproj.filters b/builds/win32/msvc14/engine.vcxproj.filters index ad92c9a4d95..d412b8e7ac4 100644 --- a/builds/win32/msvc14/engine.vcxproj.filters +++ b/builds/win32/msvc14/engine.vcxproj.filters @@ -288,6 +288,9 @@ JRD files + + JRD files + JRD files @@ -827,6 +830,9 @@ Header files + + Header files + Header files @@ -1094,4 +1100,4 @@ Resource files - \ No newline at end of file + diff --git a/builds/win32/msvc15/engine.vcxproj b/builds/win32/msvc15/engine.vcxproj index 274670ee27d..afb873e390f 100644 --- a/builds/win32/msvc15/engine.vcxproj +++ b/builds/win32/msvc15/engine.vcxproj @@ -91,6 +91,7 @@ + @@ -277,6 +278,7 @@ + @@ -561,4 +563,4 @@ - \ No newline at end of file + diff --git a/builds/win32/msvc15/engine.vcxproj.filters b/builds/win32/msvc15/engine.vcxproj.filters index ad92c9a4d95..d412b8e7ac4 100644 --- a/builds/win32/msvc15/engine.vcxproj.filters +++ b/builds/win32/msvc15/engine.vcxproj.filters @@ -288,6 +288,9 @@ JRD files + + JRD files + JRD files @@ -827,6 +830,9 @@ Header files + + Header files + Header files @@ -1094,4 +1100,4 @@ Resource files - \ No newline at end of file + diff --git a/src/jrd/KeywordsTable.cpp b/src/jrd/KeywordsTable.cpp new file mode 100644 index 00000000000..397fddde72e --- /dev/null +++ b/src/jrd/KeywordsTable.cpp @@ -0,0 +1,101 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the License for the specific language governing rights + * and limitations under the License. + * + * The Original Code was created by Adriano dos Santos Fernandes + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2021 Adriano dos Santos Fernandes + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + */ + +#include "../jrd/KeywordsTable.h" +#include "../jrd/ini.h" +#include "../jrd/ids.h" +#include "../common/keywords.h" + +using namespace Jrd; +using namespace Firebird; + + +RecordBuffer* KeywordsTable::getRecords(thread_db* tdbb, jrd_rel* relation) +{ + fb_assert(relation); + fb_assert(relation->rel_id == rel_keywords); + + auto recordBuffer = getData(relation); + if (recordBuffer) + return recordBuffer; + + recordBuffer = allocBuffer(tdbb, *tdbb->getDefaultPool(), relation->rel_id); + + const auto record = recordBuffer->getTempRecord(); + + for (const auto* token = keywordGetTokens(); token->tok_string; ++token) + { + if (isalpha(token->tok_string[0])) + { + record->nullify(); + + putField(tdbb, record, + DumpField(f_keyword_name, VALUE_STRING, strlen(token->tok_string), token->tok_string)); + + const bool reserved = !token->nonReserved; + putField(tdbb, record, DumpField(f_keyword_reserved, VALUE_BOOLEAN, 1, &reserved)); + + recordBuffer->store(record); + } + } + + return recordBuffer; +} + + +//-------------------------------------- + + +void KeywordsTableScan::close(thread_db* tdbb) const +{ + const auto request = tdbb->getRequest(); + const auto impure = request->getImpure(impureOffset); + + delete impure->table; + impure->table = nullptr; + + VirtualTableScan::close(tdbb); +} + +const Format* KeywordsTableScan::getFormat(thread_db* tdbb, jrd_rel* relation) const +{ + const auto records = getRecords(tdbb, relation); + return records->getFormat(); +} + +bool KeywordsTableScan::retrieveRecord(thread_db* tdbb, jrd_rel* relation, + FB_UINT64 position, Record* record) const +{ + const auto records = getRecords(tdbb, relation); + return records->fetch(position, record); +} + +RecordBuffer* KeywordsTableScan::getRecords(thread_db* tdbb, jrd_rel* relation) const +{ + const auto request = tdbb->getRequest(); + const auto impure = request->getImpure(impureOffset); + + if (!impure->table) + impure->table = FB_NEW_POOL(*tdbb->getDefaultPool()) KeywordsTable(*tdbb->getDefaultPool()); + + return impure->table->getRecords(tdbb, relation); +} diff --git a/src/jrd/KeywordsTable.h b/src/jrd/KeywordsTable.h new file mode 100644 index 00000000000..06ab0e094c3 --- /dev/null +++ b/src/jrd/KeywordsTable.h @@ -0,0 +1,79 @@ +/* + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the License for the specific language governing rights + * and limitations under the License. + * + * The Original Code was created by Adriano dos Santos Fernandes + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2021 Adriano dos Santos Fernandes + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + */ + +#ifndef JRD_KEYWORDS_TABLE_H +#define JRD_KEYWORDS_TABLE_H + +#include "firebird.h" +#include "../common/classes/fb_string.h" +#include "../jrd/Monitoring.h" +#include "../jrd/recsrc/RecordSource.h" + + +namespace Jrd +{ + +class KeywordsTable : public SnapshotData +{ +public: + KeywordsTable(MemoryPool& pool) + : SnapshotData(pool) + { + } + +public: + RecordBuffer* getRecords(thread_db* tdbb, jrd_rel* relation); +}; + + +class KeywordsTableScan : public VirtualTableScan +{ +public: + KeywordsTableScan(CompilerScratch* csb, const Firebird::string& alias, + StreamType stream, jrd_rel* relation) + : VirtualTableScan(csb, alias, stream, relation) + { + impureOffset = csb->allocImpure(); + } + + void close(thread_db* tdbb) const override; + +protected: + const Format* getFormat(thread_db* tdbb, jrd_rel* relation) const override; + + bool retrieveRecord(thread_db* tdbb, jrd_rel* relation, FB_UINT64 position, + Record* record) const override; + +private: + struct Impure + { + KeywordsTable* table; + }; + + RecordBuffer* getRecords(thread_db* tdbb, jrd_rel* relation) const; + + ULONG impureOffset; +}; + +} // namespace Jrd + +#endif // JRD_KEYWORDS_TABLE_H diff --git a/src/jrd/fields.h b/src/jrd/fields.h index 64dd66311cb..6ffdaf9d6a2 100644 --- a/src/jrd/fields.h +++ b/src/jrd/fields.h @@ -220,3 +220,6 @@ FIELD(fld_cfg_is_set , nam_cfg_is_set , dtype_boolean , 1 , 0 , NULL , false) FIELD(fld_repl_mode , nam_repl_mode , dtype_short , sizeof(SSHORT) , 0 , NULL , true) + + FIELD(fld_keyword_name , nam_keyword_name , dtype_varying , METADATA_IDENTIFIER_CHAR_LEN, dsc_text_type_ascii , NULL , false) + FIELD(fld_keyword_reserved, nam_keyword_reserved, dtype_boolean, 1 , 0 , NULL , false) diff --git a/src/jrd/names.h b/src/jrd/names.h index cc12127a062..c746e0d848b 100644 --- a/src/jrd/names.h +++ b/src/jrd/names.h @@ -451,3 +451,7 @@ NAME("RDB$CONFIG_VALUE", nam_cfg_value) NAME("RDB$CONFIG_DEFAULT", nam_cfg_default) NAME("RDB$CONFIG_IS_SET", nam_cfg_is_set) NAME("RDB$CONFIG_SOURCE", nam_cfg_source) + +NAME("RDB$KEYWORDS", nam_keywords) +NAME("RDB$KEYWORD_NAME", nam_keyword_name) +NAME("RDB$KEYWORD_RESERVED", nam_keyword_reserved) diff --git a/src/jrd/opt.cpp b/src/jrd/opt.cpp index 477d5da5bc7..c67b3767978 100644 --- a/src/jrd/opt.cpp +++ b/src/jrd/opt.cpp @@ -75,6 +75,7 @@ #include "../jrd/par_proto.h" #include "../yvalve/gds_proto.h" #include "../jrd/DataTypeUtil.h" +#include "../jrd/KeywordsTable.h" #include "../jrd/RecordSourceNodes.h" #include "../jrd/VirtualTable.h" #include "../jrd/Monitoring.h" @@ -2316,6 +2317,10 @@ static RecordSource* gen_retrieval(thread_db* tdbb, rsb = FB_NEW_POOL(*tdbb->getDefaultPool()) ConfigTableScan(csb, alias, stream, relation); break; + case rel_keywords: + rsb = FB_NEW_POOL(*tdbb->getDefaultPool()) KeywordsTableScan(csb, alias, stream, relation); + break; + default: rsb = FB_NEW_POOL(*tdbb->getDefaultPool()) MonitoringTableScan(csb, alias, stream, relation); break; diff --git a/src/jrd/relations.h b/src/jrd/relations.h index 460512659a7..2a1d6a1949e 100644 --- a/src/jrd/relations.h +++ b/src/jrd/relations.h @@ -734,3 +734,10 @@ RELATION(nam_config, rel_config, ODS_13_0, rel_virtual) FIELD(f_cfg_is_set, nam_cfg_is_set, fld_cfg_is_set, 0, ODS_13_0) FIELD(f_cfg_source, nam_cfg_source, fld_file_name2, 0, ODS_13_0) END_RELATION + +//// FIXME: ODS version +// Relation 54 (RDB$KEYWORDS) +RELATION(nam_keywords, rel_keywords, ODS_13_0, rel_virtual) + FIELD(f_keyword_name, nam_keyword_name, fld_keyword_name, 0, ODS_13_0) + FIELD(f_keyword_reserved, nam_keyword_reserved, fld_keyword_reserved, 0, ODS_13_0) +END_RELATION