From: <asf...@us...> - 2011-11-22 16:33:37
|
Revision: 53641 http://firebird.svn.sourceforge.net/firebird/?rev=53641&view=rev Author: asfernandes Date: 2011-11-22 16:33:25 +0000 (Tue, 22 Nov 2011) Log Message: ----------- DDL refactor: ALTER EXTERNAL FUNCTION, ALTER INDEX, SET STATISTICS, CREATE SHADOW, ALTER ROLE, CREATE/ALTER DATABASE. Modified Paths: -------------- firebird/trunk/builds/win32/msvc10/engine.vcxproj firebird/trunk/builds/win32/msvc10/engine.vcxproj.filters firebird/trunk/builds/win32/msvc8/engine.vcproj firebird/trunk/builds/win32/msvc9/engine.vcproj firebird/trunk/builds/win32/preprocess.bat firebird/trunk/lang_helpers/gds_codes.ftn firebird/trunk/lang_helpers/gds_codes.pas firebird/trunk/src/common/classes/MetaName.h firebird/trunk/src/dsql/BlrWriter.cpp firebird/trunk/src/dsql/BlrWriter.h firebird/trunk/src/dsql/DdlNodes.epp firebird/trunk/src/dsql/DdlNodes.h firebird/trunk/src/dsql/Nodes.h firebird/trunk/src/dsql/Parser.h firebird/trunk/src/dsql/ddl.cpp firebird/trunk/src/dsql/dsql.h firebird/trunk/src/dsql/node.h firebird/trunk/src/dsql/parse.y firebird/trunk/src/dsql/pass1.cpp firebird/trunk/src/include/gen/codetext.h firebird/trunk/src/include/gen/iberror.h firebird/trunk/src/include/gen/msgs.h firebird/trunk/src/include/gen/sql_code.h firebird/trunk/src/include/gen/sql_state.h firebird/trunk/src/jrd/drq.h firebird/trunk/src/jrd/dyn.epp firebird/trunk/src/jrd/dyn_def.epp firebird/trunk/src/jrd/dyn_df_proto.h firebird/trunk/src/jrd/dyn_util.epp firebird/trunk/src/msgs/facilities2.sql firebird/trunk/src/msgs/messages2.sql firebird/trunk/src/msgs/system_errors2.sql Removed Paths: ------------- firebird/trunk/src/jrd/dyn_md_proto.h firebird/trunk/src/jrd/dyn_mod.epp Modified: firebird/trunk/builds/win32/msvc10/engine.vcxproj =================================================================== --- firebird/trunk/builds/win32/msvc10/engine.vcxproj 2011-11-20 09:45:00 UTC (rev 53640) +++ firebird/trunk/builds/win32/msvc10/engine.vcxproj 2011-11-22 16:33:25 UTC (rev 53641) @@ -26,7 +26,6 @@ <ClCompile Include="..\..\..\gen\jrd\dpm.cpp" /> <ClCompile Include="..\..\..\gen\jrd\dyn.cpp" /> <ClCompile Include="..\..\..\gen\jrd\dyn_def.cpp" /> - <ClCompile Include="..\..\..\gen\jrd\dyn_mod.cpp" /> <ClCompile Include="..\..\..\gen\jrd\dyn_util.cpp" /> <ClCompile Include="..\..\..\gen\jrd\fun.cpp" /> <ClCompile Include="..\..\..\gen\jrd\Function.cpp" /> @@ -219,7 +218,6 @@ <ClInclude Include="..\..\..\src\jrd\drq.h" /> <ClInclude Include="..\..\..\src\jrd\dyn.h" /> <ClInclude Include="..\..\..\src\jrd\dyn_df_proto.h" /> - <ClInclude Include="..\..\..\src\jrd\dyn_md_proto.h" /> <ClInclude Include="..\..\..\src\jrd\dyn_proto.h" /> <ClInclude Include="..\..\..\src\jrd\dyn_ut_proto.h" /> <ClInclude Include="..\..\..\src\jrd\ErrorImpl.h" /> @@ -351,7 +349,6 @@ <None Include="..\..\..\src\jrd\dpm.epp" /> <None Include="..\..\..\src\jrd\dyn.epp" /> <None Include="..\..\..\src\jrd\dyn_def.epp" /> - <None Include="..\..\..\src\jrd\dyn_mod.epp" /> <None Include="..\..\..\src\jrd\dyn_util.epp" /> <None Include="..\..\..\src\jrd\fun.epp" /> <None Include="..\..\..\src\jrd\Function.epp" /> Modified: firebird/trunk/builds/win32/msvc10/engine.vcxproj.filters =================================================================== --- firebird/trunk/builds/win32/msvc10/engine.vcxproj.filters 2011-11-20 09:45:00 UTC (rev 53640) +++ firebird/trunk/builds/win32/msvc10/engine.vcxproj.filters 2011-11-22 16:33:25 UTC (rev 53641) @@ -417,9 +417,6 @@ <ClCompile Include="..\..\..\gen\jrd\dyn_def.cpp"> <Filter>JRD files\GPRE cpp</Filter> </ClCompile> - <ClCompile Include="..\..\..\gen\jrd\dyn_mod.cpp"> - <Filter>JRD files\GPRE cpp</Filter> - </ClCompile> <ClCompile Include="..\..\..\gen\jrd\dyn_util.cpp"> <Filter>JRD files\GPRE cpp</Filter> </ClCompile> @@ -683,9 +680,6 @@ <ClInclude Include="..\..\..\src\jrd\dyn_df_proto.h"> <Filter>Header files</Filter> </ClInclude> - <ClInclude Include="..\..\..\src\jrd\dyn_md_proto.h"> - <Filter>Header files</Filter> - </ClInclude> <ClInclude Include="..\..\..\src\jrd\dyn_proto.h"> <Filter>Header files</Filter> </ClInclude> @@ -1021,9 +1015,6 @@ <None Include="..\..\..\src\jrd\dyn_def.epp"> <Filter>JRD files\GPRE files</Filter> </None> - <None Include="..\..\..\src\jrd\dyn_mod.epp"> - <Filter>JRD files\GPRE files</Filter> - </None> <None Include="..\..\..\src\jrd\dyn_util.epp"> <Filter>JRD files\GPRE files</Filter> </None> Modified: firebird/trunk/builds/win32/msvc8/engine.vcproj =================================================================== --- firebird/trunk/builds/win32/msvc8/engine.vcproj 2011-11-20 09:45:00 UTC (rev 53640) +++ firebird/trunk/builds/win32/msvc8/engine.vcproj 2011-11-22 16:33:25 UTC (rev 53641) @@ -735,10 +735,6 @@ > </File> <File - RelativePath="..\..\..\gen\jrd\dyn_mod.cpp" - > - </File> - <File RelativePath="..\..\..\gen\jrd\dyn_util.cpp" > </File> @@ -795,10 +791,6 @@ > </File> <File - RelativePath="..\..\..\src\jrd\dyn_mod.epp" - > - </File> - <File RelativePath="..\..\..\src\jrd\dyn_util.epp" > </File> @@ -1048,10 +1040,6 @@ > </File> <File - RelativePath="..\..\..\src\jrd\dyn_md_proto.h" - > - </File> - <File RelativePath="..\..\..\src\jrd\dyn_proto.h" > </File> Modified: firebird/trunk/builds/win32/msvc9/engine.vcproj =================================================================== --- firebird/trunk/builds/win32/msvc9/engine.vcproj 2011-11-20 09:45:00 UTC (rev 53640) +++ firebird/trunk/builds/win32/msvc9/engine.vcproj 2011-11-22 16:33:25 UTC (rev 53641) @@ -731,10 +731,6 @@ > </File> <File - RelativePath="..\..\..\gen\jrd\dyn_mod.cpp" - > - </File> - <File RelativePath="..\..\..\gen\jrd\dyn_util.cpp" > </File> @@ -787,10 +783,6 @@ > </File> <File - RelativePath="..\..\..\src\jrd\dyn_mod.epp" - > - </File> - <File RelativePath="..\..\..\src\jrd\dyn_util.epp" > </File> @@ -1036,10 +1028,6 @@ > </File> <File - RelativePath="..\..\..\src\jrd\dyn_md_proto.h" - > - </File> - <File RelativePath="..\..\..\src\jrd\dyn_proto.h" > </File> Modified: firebird/trunk/builds/win32/preprocess.bat =================================================================== --- firebird/trunk/builds/win32/preprocess.bat 2011-11-20 09:45:00 UTC (rev 53640) +++ firebird/trunk/builds/win32/preprocess.bat 2011-11-22 16:33:25 UTC (rev 53641) @@ -67,7 +67,7 @@ @for %%i in (array, blob) do @call :PREPROCESS yvalve %%i @for %%i in (metd, DdlNodes, PackageNodes) do @call :PREPROCESS dsql %%i -gds_cxx @for %%i in (gpre_meta) do @call :PREPROCESS gpre/std %%i -@for %%i in (dfw, dpm, dyn, dyn_def, dyn_mod, dyn_util, fun, grant, ini, met, pcmet, scl, Function) do @call :PREPROCESS jrd %%i -gds_cxx +@for %%i in (dfw, dpm, dyn, dyn_def, dyn_util, fun, grant, ini, met, pcmet, scl, Function) do @call :PREPROCESS jrd %%i -gds_cxx @for %%i in (stats) do @call :PREPROCESS utilities %%i @goto :EOF @@ -81,7 +81,7 @@ @for %%i in (metd) do @call :PREPROCESS dsql %%i -gds_cxx @for %%i in (DdlNodes, PackageNodes) do @call :PREPROCESS dsql %%i -gds_cxx @for %%i in (gpre_meta) do @call :PREPROCESS gpre/std %%i -@for %%i in (dfw, dpm, dyn, dyn_def, dyn_mod, dyn_util, fun, grant, ini, met, pcmet, scl, Function) do @call :PREPROCESS jrd %%i -gds_cxx +@for %%i in (dfw, dpm, dyn, dyn_def, dyn_util, fun, grant, ini, met, pcmet, scl, Function) do @call :PREPROCESS jrd %%i -gds_cxx @for %%i in (codes) do @call :PREPROCESS misc %%i @for %%i in (build_file) do @call :PREPROCESS msgs %%i @for %%i in (help, meta, proc, show) do @call :PREPROCESS qli %%i Modified: firebird/trunk/lang_helpers/gds_codes.ftn =================================================================== --- firebird/trunk/lang_helpers/gds_codes.ftn 2011-11-20 09:45:00 UTC (rev 53640) +++ firebird/trunk/lang_helpers/gds_codes.ftn 2011-11-22 16:33:25 UTC (rev 53641) @@ -2130,6 +2130,14 @@ PARAMETER (GDS__dsql_drop_user_failed = 336397309) INTEGER*4 GDS__dsql_create_role_failed PARAMETER (GDS__dsql_create_role_failed = 336397310) + INTEGER*4 GDS__dsql_alter_role_failed + PARAMETER (GDS__dsql_alter_role_failed = 336397311) + INTEGER*4 GDS__dsql_alter_index_failed + PARAMETER (GDS__dsql_alter_index_failed = 336397312) + INTEGER*4 GDS__dsql_alter_database_failed + PARAMETER (GDS__dsql_alter_database_failed = 336397313) + INTEGER*4 GDS__dsql_create_shadow_failed + PARAMETER (GDS__dsql_create_shadow_failed = 336397314) INTEGER*4 GDS__gsec_cant_open_db PARAMETER (GDS__gsec_cant_open_db = 336723983) INTEGER*4 GDS__gsec_switches_error Modified: firebird/trunk/lang_helpers/gds_codes.pas =================================================================== --- firebird/trunk/lang_helpers/gds_codes.pas 2011-11-20 09:45:00 UTC (rev 53640) +++ firebird/trunk/lang_helpers/gds_codes.pas 2011-11-22 16:33:25 UTC (rev 53641) @@ -1072,6 +1072,10 @@ gds_dsql_drop_role_failed = 336397308; gds_dsql_drop_user_failed = 336397309; gds_dsql_create_role_failed = 336397310; + gds_dsql_alter_role_failed = 336397311; + gds_dsql_alter_index_failed = 336397312; + gds_dsql_alter_database_failed = 336397313; + gds_dsql_create_shadow_failed = 336397314; gds_gsec_cant_open_db = 336723983; gds_gsec_switches_error = 336723984; gds_gsec_no_op_spec = 336723985; Modified: firebird/trunk/src/common/classes/MetaName.h =================================================================== --- firebird/trunk/src/common/classes/MetaName.h 2011-11-20 09:45:00 UTC (rev 53640) +++ firebird/trunk/src/common/classes/MetaName.h 2011-11-22 16:33:25 UTC (rev 53641) @@ -105,19 +105,6 @@ static void adjustLength(const char* const s, size_t& l); }; -// This class is used to simplify calls from GDML, when pointer to MetaName -// should be passed to some function, at the same time reflecting changes in -// associated GDML variable (database field). -class MetaNameProxy : public MetaName -{ - char* target; -public: - explicit MetaNameProxy(char* s) - : Firebird::MetaName(s), target(s) - { } - ~MetaNameProxy() { strcpy(target, c_str()); } -}; - typedef Pair<Full<MetaName, MetaName> > MetaNamePair; } // namespace Firebird Modified: firebird/trunk/src/dsql/BlrWriter.cpp =================================================================== --- firebird/trunk/src/dsql/BlrWriter.cpp 2011-11-20 09:45:00 UTC (rev 53640) +++ firebird/trunk/src/dsql/BlrWriter.cpp 2011-11-22 16:33:25 UTC (rev 53641) @@ -84,18 +84,6 @@ appendULong(val); } -void BlrWriter::appendFileLength(ULONG length) -{ - appendUChar(isc_dyn_file_length); - appendULongWithLength(length); -} - -void BlrWriter::appendFileStart(ULONG start) -{ - appendUChar(isc_dyn_file_start); - appendULongWithLength(start); -} - // Write out a string of blr as part of a ddl string, as in a view or computed field definition. void BlrWriter::beginBlr(UCHAR verb) { Modified: firebird/trunk/src/dsql/BlrWriter.h =================================================================== --- firebird/trunk/src/dsql/BlrWriter.h 2011-11-20 09:45:00 UTC (rev 53640) +++ firebird/trunk/src/dsql/BlrWriter.h 2011-11-22 16:33:25 UTC (rev 53641) @@ -122,8 +122,6 @@ void appendNumber(UCHAR verb, SSHORT number); void appendUShortWithLength(USHORT val); void appendULongWithLength(ULONG val); - void appendFileLength(ULONG length); - void appendFileStart(ULONG start); void beginBlr(UCHAR verb); void endBlr(); Modified: firebird/trunk/src/dsql/DdlNodes.epp =================================================================== --- firebird/trunk/src/dsql/DdlNodes.epp 2011-11-20 09:45:00 UTC (rev 53640) +++ firebird/trunk/src/dsql/DdlNodes.epp 2011-11-22 16:33:25 UTC (rev 53641) @@ -94,6 +94,9 @@ static void clearPermanentField(dsql_rel* relation, bool permanent); static void deleteKeyConstraint(thread_db* tdbb, jrd_tra* transaction, const MetaName& relationName, const MetaName& constraintName, const MetaName& indexName); +static void defineFile(thread_db* tdbb, jrd_tra* transaction, SLONG shadowNumber, bool manualShadow, + bool conditionalShadow, SLONG& dbAlloc, + const PathName& name, SLONG start, SLONG length); static bool fieldExists(thread_db* tdbb, jrd_tra* transaction, const MetaName& relationName, const MetaName& fieldName); static void makeRelationScopeName(const MetaName& name, const rel_t type, string& message); @@ -330,6 +333,46 @@ } } +// Define a database or shadow file. +static void defineFile(thread_db* tdbb, jrd_tra* transaction, SLONG shadowNumber, bool manualShadow, + bool conditionalShadow, SLONG& dbAlloc, const PathName& name, SLONG start, SLONG length) +{ + PathName expandedName = name; + + if (!ISC_expand_filename(expandedName, false)) + status_exception::raise(Arg::Gds(ENCODE_ISC_MSG(231, DYN_MSG_FAC))); // File name is invalid. + + if (tdbb->getDatabase()->dbb_filename == expandedName) + status_exception::raise(Arg::Gds(ENCODE_ISC_MSG(166, DYN_MSG_FAC))); + + AutoCacheRequest request(tdbb, drq_l_files, DYN_REQUESTS); + + FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + FIRST 1 X IN RDB$FILES + WITH X.RDB$FILE_NAME EQ expandedName.c_str() + { + status_exception::raise(Arg::Gds(ENCODE_ISC_MSG(166, DYN_MSG_FAC))); + } + END_FOR + + request.reset(tdbb, drq_s_files, DYN_REQUESTS); + + STORE(REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + X IN RDB$FILES + { + expandedName.copyTo(X.RDB$FILE_NAME, sizeof(X.RDB$FILE_NAME)); + X.RDB$SHADOW_NUMBER = shadowNumber; + X.RDB$FILE_FLAGS = (manualShadow ? FILE_manual : 0) | + (conditionalShadow ? FILE_conditional : 0); + + dbAlloc = MAX(dbAlloc, start); + X.RDB$FILE_START = dbAlloc; + X.RDB$FILE_LENGTH = length; + dbAlloc += length; + } + END_STORE +} + // Checks to see if the given field already exists in a relation. static bool fieldExists(thread_db* tdbb, jrd_tra* transaction, const MetaName& relationName, const MetaName& fieldName) @@ -1501,21 +1544,13 @@ strcpy(FUN.RDB$ENGINE_NAME, external->engine.c_str()); if (external->udfModule.length() >= sizeof(FUN.RDB$MODULE_NAME)) - { - status_exception::raise( - Arg::Gds(isc_arith_except) << - Arg::Gds(isc_string_truncation)); - } + status_exception::raise(Arg::Gds(isc_dyn_name_longer)); FUN.RDB$MODULE_NAME.NULL = (SSHORT) external->udfModule.isEmpty(); strcpy(FUN.RDB$MODULE_NAME, external->udfModule.c_str()); if (external->name.length() >= sizeof(FUN.RDB$ENTRYPOINT)) - { - status_exception::raise( - Arg::Gds(isc_arith_except) << - Arg::Gds(isc_string_truncation)); - } + status_exception::raise(Arg::Gds(isc_dyn_name_longer)); FUN.RDB$ENTRYPOINT.NULL = (SSHORT) external->name.isEmpty(); strcpy(FUN.RDB$ENTRYPOINT, external->name.c_str()); @@ -1850,6 +1885,88 @@ //---------------------- +void AlterExternalFunctionNode::print(string& text, Array<dsql_nod*>& /*nodes*/) const +{ + text.printf( + "AlterExternalFunctionNode\n" + " name: '%s'\n" + " entrypoint: '%s'\n" + " module: '%s'\n", + name.c_str(), clauses.name.c_str(), clauses.udfModule.c_str()); +} + +// Allow changing the entry point and/or the module name of a UDF. +void AlterExternalFunctionNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, + jrd_tra* transaction) +{ + if (clauses.name.isEmpty() && clauses.udfModule.isEmpty()) + { + status_exception::raise( + Arg::Gds(isc_sqlerr) << Arg::Num(-104) /*** FIXME: << + // Unexpected end of command + Arg::Gds(isc_command_end_err2) << Arg::Num(node->nod_line) << + Arg::Num(node->nod_column + obj_name->str_length)***/); // + strlen("FUNCTION") + } + + // run all statements under savepoint control + AutoSavePoint savePoint(tdbb, transaction); + + AutoCacheRequest request(tdbb, drq_m_fun, DYN_REQUESTS); + bool found = false; + + FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + FUN IN RDB$FUNCTIONS + WITH FUN.RDB$FUNCTION_NAME EQ name.c_str() AND + FUN.RDB$PACKAGE_NAME MISSING + { + found = true; + + executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_ALTER_FUNCTION, name); + + if (!FUN.RDB$ENGINE_NAME.NULL || !FUN.RDB$FUNCTION_BLR.NULL) + status_exception::raise(Arg::Gds(isc_dyn_newfc_oldsyntax) << name); + + MODIFY FUN + if (clauses.name.hasData()) + { + if (clauses.name.length() >= sizeof(FUN.RDB$ENTRYPOINT)) + status_exception::raise(Arg::Gds(isc_dyn_name_longer)); + + FUN.RDB$ENTRYPOINT.NULL = FALSE; + strcpy(FUN.RDB$ENTRYPOINT, clauses.name.c_str()); + } + + if (clauses.udfModule.hasData()) + { + if (clauses.udfModule.length() >= sizeof(FUN.RDB$MODULE_NAME)) + status_exception::raise(Arg::Gds(isc_dyn_name_longer)); + + FUN.RDB$MODULE_NAME.NULL = FALSE; + strcpy(FUN.RDB$MODULE_NAME, clauses.udfModule.c_str()); + } + END_MODIFY + } + END_FOR + + if (found) + executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_ALTER_FUNCTION, name); + else + { + // msg 41: "Function %s not found" + status_exception::raise(Arg::Gds(ENCODE_ISC_MSG(41, DYN_MSG_FAC)) << name); + } + + savePoint.release(); // everything is ok + + // Update DSQL cache + METD_drop_function(transaction, QualifiedName(name, "")); + MET_dsql_cache_release(tdbb, SYM_udf, name, ""); +} + + +//---------------------- + + void DropFunctionNode::dropArguments(thread_db* tdbb, jrd_tra* transaction, const MetaName& functionName, const MetaName& packageName) { @@ -2300,11 +2417,7 @@ strcpy(P.RDB$ENGINE_NAME, external->engine.c_str()); if (external->name.length() >= sizeof(P.RDB$ENTRYPOINT)) - { - status_exception::raise( - Arg::Gds(isc_arith_except) << - Arg::Gds(isc_string_truncation)); - } + status_exception::raise(Arg::Gds(isc_dyn_name_longer)); P.RDB$ENTRYPOINT.NULL = (SSHORT) external->name.isEmpty(); strcpy(P.RDB$ENTRYPOINT, external->name.c_str()); @@ -2832,11 +2945,7 @@ strcpy(TRG.RDB$ENGINE_NAME, external->engine.c_str()); if (external->name.length() >= sizeof(TRG.RDB$ENTRYPOINT)) - { - status_exception::raise( - Arg::Gds(isc_arith_except) << - Arg::Gds(isc_string_truncation)); - } + status_exception::raise(Arg::Gds(isc_dyn_name_longer)); TRG.RDB$ENTRYPOINT.NULL = (SSHORT) external->name.isEmpty(); strcpy(TRG.RDB$ENTRYPOINT, external->name.c_str()); @@ -3752,7 +3861,7 @@ default: fb_assert(FALSE); - errorCode = 87; // MODIFY RDB$FIELDS FAILED + errorCode = ENCODE_ISC_MSG(87, DYN_MSG_FAC); // MODIFY RDB$FIELDS FAILED break; } break; @@ -3947,14 +4056,14 @@ default: fb_assert(FALSE); - errorCode = 87; // MODIFY RDB$FIELDS FAILED + errorCode = ENCODE_ISC_MSG(87, DYN_MSG_FAC); // MODIFY RDB$FIELDS FAILED break; } break; default: fb_assert(FALSE); - errorCode = 87; // MODIFY RDB$FIELDS FAILED + errorCode = ENCODE_ISC_MSG(87, DYN_MSG_FAC); // MODIFY RDB$FIELDS FAILED break; } @@ -8738,6 +8847,100 @@ //---------------------- +void AlterIndexNode::print(string& text, Array<dsql_nod*>& /*nodes*/) const +{ + text.printf( + "AlterIndexNode\n" + " name: '%s'\n" + " active: '%d'\n", + name.c_str(), active); +} + +void AlterIndexNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction) +{ + // run all statements under savepoint control + AutoSavePoint savePoint(tdbb, transaction); + + AutoCacheRequest request(tdbb, drq_m_index, DYN_REQUESTS); + bool found = false; + + FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + IDX IN RDB$INDICES + WITH IDX.RDB$INDEX_NAME EQ name.c_str() + { + found = true; + + executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_ALTER_INDEX, name); + + MODIFY IDX + IDX.RDB$INDEX_INACTIVE.NULL = FALSE; + IDX.RDB$INDEX_INACTIVE = active ? FALSE : TRUE; + END_MODIFY + } + END_FOR + + if (found) + executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_ALTER_INDEX, name); + else + { + // msg 48: "Index not found" + status_exception::raise(Arg::Gds(ENCODE_ISC_MSG(48, DYN_MSG_FAC))); + } + + savePoint.release(); // everything is ok +} + + +//---------------------- + + +void SetStatisticsNode::print(string& text, Array<dsql_nod*>& /*nodes*/) const +{ + text.printf( + "SetStatisticsNode\n" + " name: '%s'\n", + name.c_str()); +} + +void SetStatisticsNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction) +{ + // run all statements under savepoint control + AutoSavePoint savePoint(tdbb, transaction); + + AutoCacheRequest request(tdbb, drq_m_set_statistics, DYN_REQUESTS); + bool found = false; + + FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + IDX IN RDB$INDICES + WITH IDX.RDB$INDEX_NAME EQ name.c_str() + { + found = true; + + executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_ALTER_INDEX, name); + + MODIFY IDX + // For V4 index selectivity can be set only to -1. + IDX.RDB$STATISTICS.NULL = FALSE; + IDX.RDB$STATISTICS = -1.0; + END_MODIFY + } + END_FOR + + if (found) + executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_ALTER_INDEX, name); + else + { + // msg 48: "Index not found" + status_exception::raise(Arg::Gds(ENCODE_ISC_MSG(48, DYN_MSG_FAC))); + } + + savePoint.release(); // everything is ok +} + + +//---------------------- + + // Delete the records in RDB$INDEX_SEGMENTS pertaining to an index. bool DropIndexNode::deleteSegmentRecords(thread_db* tdbb, jrd_tra* transaction, const MetaName& name) @@ -8844,6 +9047,71 @@ //---------------------- +void CreateShadowNode::print(string& text, Array<dsql_nod*>& /*nodes*/) const +{ + text.printf( + "CreateShadowNode\n" + " number: '%d'\n", + number); +} + +void CreateShadowNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction) +{ + if (!tdbb->getAttachment()->locksmith()) + status_exception::raise(Arg::Gds(isc_adm_task_denied)); + + // Should be caught by the parser. + if (number == 0) + { + status_exception::raise( + Arg::Gds(isc_sqlerr) << Arg::Num(-607) << + Arg::Gds(isc_dsql_command_err) << + Arg::Gds(isc_dsql_shadow_number_err)); + } + + // run all statements under savepoint control + AutoSavePoint savePoint(tdbb, transaction); + + // If a shadow set identified by the shadow number already exists return error. + + AutoCacheRequest request(tdbb, drq_l_shadow, DYN_REQUESTS); + + FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + FIRST 1 X IN RDB$FILES + WITH X.RDB$SHADOW_NUMBER EQ number + { + // msg 165: "Shadow %ld already exists" + status_exception::raise(Arg::Gds(ENCODE_ISC_MSG(165, DYN_MSG_FAC)) << Arg::Num(number)); + } + END_FOR + + SLONG start = 0; + + for (DbFileClause** i = files.begin(); i != files.end(); ++i) + { + bool first = i == files.begin(); + DbFileClause* file = *i; + + if (!first && i[-1]->length == 0 && file->start == 0) + { + // Preceding file did not specify length, so %s must include starting page number + status_exception::raise( + Arg::Gds(isc_sqlerr) << Arg::Num(-607) << + Arg::Gds(isc_dsql_command_err) << + Arg::Gds(isc_dsql_file_length_err) << file->name); + } + + defineFile(tdbb, transaction, number, manual && first, conditional && first, + start, file->name, file->start, file->length); + } + + savePoint.release(); // everything is ok +} + + +//---------------------- + + void DropShadowNode::print(string& text, Array<dsql_nod*>& /*nodes*/) const { text.printf( @@ -8983,6 +9251,62 @@ //---------------------- +void AlterRoleNode::print(string& text, Array<dsql_nod*>& /*nodes*/) const +{ + text.printf( + "AlterRoleNode\n" + " name: '%s'\n" + " map: '%d'\n", + name.c_str(), map); +} + +// It's purpose is to add/drop mapping from OS security name to DB security object. +void AlterRoleNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction) +{ + // run all statements under savepoint control + AutoSavePoint savePoint(tdbb, transaction); + + // This is FB 2.5 limited implementation! + // Later it should work with new system table, something like RDB$MAPPING. + + if (name != ADMIN_ROLE) + status_exception::raise(Arg::Gds(isc_wish_list)); + + if (!(tdbb->getAttachment() && tdbb->getAttachment()->locksmith())) + status_exception::raise(Arg::Gds(isc_adm_task_denied)); + + AutoCacheRequest request(tdbb, drq_m_map, DYN_REQUESTS); + bool found = false; + + FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + ROL IN RDB$ROLES + WITH ROL.RDB$ROLE_NAME EQ name.c_str() + { + found = true; + + executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_BEFORE, DDL_TRIGGER_ALTER_ROLE, name); + + MODIFY ROL + ROL.RDB$SYSTEM_FLAG = ROLE_FLAG_DBO | (map ? ROLE_FLAG_MAY_TRUST : 0); + END_MODIFY + } + END_FOR + + if (found) + executeDdlTrigger(tdbb, dsqlScratch, transaction, DTW_AFTER, DDL_TRIGGER_ALTER_ROLE, name); + else + { + status_exception::raise( + Arg::Gds(isc_random) << Arg::Str("Missing RDB$ADMIN role in the database")); + } + + savePoint.release(); // everything is ok +} + + +//---------------------- + + void DropRoleNode::print(string& text, Array<dsql_nod*>& /*nodes*/) const { text.printf( @@ -9088,4 +9412,196 @@ } +//---------------------- + + +void AlterDatabaseNode::print(string& text, Array<dsql_nod*>& /*nodes*/) const +{ + text.printf( + "AlterDatabaseNode\n"); +} + +void AlterDatabaseNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, + jrd_tra* transaction) +{ + if (!tdbb->getAttachment()->locksmith()) + status_exception::raise(Arg::Gds(isc_adm_task_denied)); + + // run all statements under savepoint control + AutoSavePoint savePoint(tdbb, transaction); + + Attachment* attachment = transaction->tra_attachment; + SLONG dbAlloc = PageSpace::maxAlloc(tdbb->getDatabase()); + SLONG start = create ? createLength + 1 : 0; + AutoCacheRequest request(tdbb, drq_m_database, DYN_REQUESTS); + + FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + DBB IN RDB$DATABASE + { + MODIFY DBB USING + if (clauses & CLAUSE_DROP_DIFFERENCE) + changeBackupMode(tdbb, transaction, CLAUSE_DROP_DIFFERENCE); + + for (DbFileClause** i = files.begin(); i != files.end(); ++i) + { + DbFileClause* file = *i; + + start = MAX(start, file->start); + defineFile(tdbb, transaction, 0, false, false, dbAlloc, + file->name, start, file->length); + start += file->length; + } + + if (differenceFile.hasData()) + defineDifference(tdbb, transaction, differenceFile); + + if (setDefaultCharSet.hasData()) + { + //// TODO: Validate! + DBB.RDB$CHARACTER_SET_NAME.NULL = FALSE; + strcpy(DBB.RDB$CHARACTER_SET_NAME, setDefaultCharSet.c_str()); + } + + if (!DBB.RDB$CHARACTER_SET_NAME.NULL && setDefaultCollation.hasData()) + { + string sql; + sql.printf("alter character set \"%s\" set default collation \"%s\"", + PreparedStatement::escapeName(DBB.RDB$CHARACTER_SET_NAME).c_str(), + PreparedStatement::escapeName(setDefaultCollation).c_str()); + + AutoPtr<PreparedStatement> ps(attachment->prepareStatement(tdbb, transaction, sql)); + ps->execute(tdbb, transaction); + } + + if (clauses & CLAUSE_BEGIN_BACKUP) + changeBackupMode(tdbb, transaction, CLAUSE_BEGIN_BACKUP); + + if (clauses & CLAUSE_END_BACKUP) + changeBackupMode(tdbb, transaction, CLAUSE_END_BACKUP); + END_MODIFY + } + END_FOR + + savePoint.release(); // everything is ok +} + +// Drop backup difference file for the database, begin or end backup. +void AlterDatabaseNode::changeBackupMode(thread_db* tdbb, jrd_tra* transaction, unsigned clause) +{ + AutoCacheRequest request(tdbb, drq_d_difference, DYN_REQUESTS); + bool invalidState = false; + bool found = false; + + FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + X IN RDB$FILES + { + if (X.RDB$FILE_FLAGS & FILE_difference) + { + found = true; + + switch (clause) + { + case CLAUSE_DROP_DIFFERENCE: + ERASE X; + break; + + case CLAUSE_BEGIN_BACKUP: + if (X.RDB$FILE_FLAGS & FILE_backing_up) + invalidState = true; + else + { + MODIFY X USING + X.RDB$FILE_FLAGS |= FILE_backing_up; + END_MODIFY + } + break; + + case CLAUSE_END_BACKUP: + if (X.RDB$FILE_FLAGS & FILE_backing_up) + { + if (X.RDB$FILE_NAME.NULL) + ERASE X; + else + { + MODIFY X USING + X.RDB$FILE_FLAGS &= ~FILE_backing_up; + END_MODIFY + } + } + else + invalidState = true; + break; + } + } + } + END_FOR + + if (!found && clause == CLAUSE_BEGIN_BACKUP) + { + request.reset(tdbb, drq_s2_difference, DYN_REQUESTS); + + STORE(REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + X IN RDB$FILES + { + X.RDB$FILE_FLAGS = FILE_difference | FILE_backing_up; + X.RDB$FILE_START = 0; + } + END_STORE + + found = true; + } + + if (invalidState) + { + // msg 217: "Database is already in the physical backup mode" + // msg 218: "Database is not in the physical backup mode" + status_exception::raise( + Arg::Gds(ENCODE_ISC_MSG(clause == CLAUSE_BEGIN_BACKUP ? 217 : 218, DYN_MSG_FAC))); + } + + if (!found) + { + // msg 218: "Database is not in the physical backup mode" + // msg 215: "Difference file is not defined" + status_exception::raise( + Arg::Gds(ENCODE_ISC_MSG(clause == CLAUSE_END_BACKUP ? 218 : 215, DYN_MSG_FAC))); + } +} + +// Define backup difference file. +void AlterDatabaseNode::defineDifference(thread_db* tdbb, jrd_tra* transaction, const PathName& file) +{ + AutoCacheRequest request(tdbb, drq_l_difference, DYN_REQUESTS); + bool found = false; + + FOR(REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + FIL IN RDB$FILES + { + if (FIL.RDB$FILE_FLAGS & FILE_difference) + found = true; + } + END_FOR + + if (found) + { + // msg 216: "Difference file is already defined" + status_exception::raise(Arg::Gds(ENCODE_ISC_MSG(216, DYN_MSG_FAC))); + } + + request.reset(tdbb, drq_s_difference, DYN_REQUESTS); + + STORE(REQUEST_HANDLE request TRANSACTION_HANDLE transaction) + FIL IN RDB$FILES + { + if (file.length() >= sizeof(FIL.RDB$FILE_NAME)) + status_exception::raise(Arg::Gds(isc_dyn_name_longer)); + + strcpy(FIL.RDB$FILE_NAME, file.c_str()); + FIL.RDB$FILE_FLAGS = FILE_difference; + FIL.RDB$FILE_START = 0; + } + END_STORE +} + + } // namespace Jrd Modified: firebird/trunk/src/dsql/DdlNodes.h =================================================================== --- firebird/trunk/src/dsql/DdlNodes.h 2011-11-20 09:45:00 UTC (rev 53640) +++ firebird/trunk/src/dsql/DdlNodes.h 2011-11-22 16:33:25 UTC (rev 53641) @@ -42,13 +42,37 @@ class CompoundStmtNode; +class DbFileClause +{ +public: + DbFileClause(MemoryPool& p, const DbFileClause& o) + : name(p, o.name), + start(o.start), + length(o.length) + { + } + + explicit DbFileClause(MemoryPool& p, const Firebird::PathName& aName) + : name(p, aName), + start(0), + length(0) + { + } + +public: + Firebird::PathName name; // File name + SLONG start; // Starting page + SLONG length; // File length in pages +}; + + class ExternalClause { public: ExternalClause(MemoryPool& p, const ExternalClause& o) : name(p, o.name), engine(p, o.engine), - udfModule(p) + udfModule(p, o.udfModule) { } @@ -309,6 +333,34 @@ }; + + +class AlterExternalFunctionNode : public DdlNode +{ +public: + AlterExternalFunctionNode(MemoryPool& p, const Firebird::MetaName& aName) + : DdlNode(p), + name(p, aName), + clauses(p) + { + } + +public: + virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const; + virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); + +protected: + virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) + { + statusVector << Firebird::Arg::Gds(isc_dsql_alter_func_failed) << name; + } + +public: + Firebird::MetaName name; + ExternalClause clauses; +}; + + class DropFunctionNode : public DdlNode { public: @@ -1245,6 +1297,57 @@ }; +class AlterIndexNode : public DdlNode +{ +public: + AlterIndexNode(MemoryPool& p, const Firebird::MetaName& aName, bool aActive) + : DdlNode(p), + name(p, aName), + active(aActive) + { + } + +public: + virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const; + virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); + +protected: + virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) + { + statusVector << Firebird::Arg::Gds(isc_dsql_alter_index_failed) << name; + } + +public: + Firebird::MetaName name; + bool active; +}; + + +class SetStatisticsNode : public DdlNode +{ +public: + SetStatisticsNode(MemoryPool& p, const Firebird::MetaName& aName) + : DdlNode(p), + name(p, aName) + { + } + +public: + virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const; + virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); + +protected: + virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) + { + // ASF: using ALTER INDEX's code. + statusVector << Firebird::Arg::Gds(isc_dsql_alter_index_failed) << name; + } + +public: + Firebird::MetaName name; +}; + + class DropIndexNode : public DdlNode { public: @@ -1296,6 +1399,37 @@ }; +class CreateShadowNode : public DdlNode +{ +public: + CreateShadowNode(MemoryPool& p, const SSHORT aNumber) + : DdlNode(p), + number(aNumber), + manual(false), + conditional(false), + files(p) + { + } + +public: + virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const; + virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); + +protected: + virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) + { + statusVector << Firebird::Arg::Gds(isc_dsql_create_shadow_failed) << Firebird::Arg::Num(number); + } + +public: + SSHORT number; + bool manual; + bool conditional; + Nullable<SLONG> firstLength; + Firebird::Array<DbFileClause*> files; +}; + + class DropShadowNode : public DdlNode { public: @@ -1347,6 +1481,32 @@ }; +class AlterRoleNode : public DdlNode +{ +public: + AlterRoleNode(MemoryPool& p, const Firebird::MetaName& aName, bool aMap) + : DdlNode(p), + name(p, aName), + map(aMap) + { + } + +public: + virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const; + virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); + +protected: + virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) + { + statusVector << Firebird::Arg::Gds(isc_dsql_alter_role_failed) << name; + } + +public: + Firebird::MetaName name; + bool map; +}; + + class DropRoleNode : public DdlNode { public: @@ -1395,6 +1555,58 @@ }; +class AlterDatabaseNode : public DdlNode +{ +public: + static const unsigned CLAUSE_BEGIN_BACKUP = 0x01; + static const unsigned CLAUSE_END_BACKUP = 0x02; + static const unsigned CLAUSE_DROP_DIFFERENCE = 0x04; + +public: + AlterDatabaseNode(MemoryPool& p) + : DdlNode(p), + create(false), + createLength(0), + clauses(0), + differenceFile(p), + setDefaultCharSet(p), + setDefaultCollation(p), + files(p) + { + } + +public: + virtual DdlNode* dsqlPass(DsqlCompilerScratch* dsqlScratch) + { + dsqlScratch->getStatement()->setType( + create ? DsqlCompiledStatement::TYPE_CREATE_DB : DsqlCompiledStatement::TYPE_DDL); + return this; + } + + virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const; + virtual void execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); + +protected: + virtual void putErrorPrefix(Firebird::Arg::StatusVector& statusVector) + { + statusVector << Firebird::Arg::Gds(isc_dsql_alter_database_failed); + } + +private: + static void changeBackupMode(thread_db* tdbb, jrd_tra* transaction, unsigned clause); + static void defineDifference(thread_db* tdbb, jrd_tra* transaction, const Firebird::PathName& file); + +public: + bool create; // Is the node created with a CREATE DATABASE command? + SLONG createLength; + unsigned clauses; + Firebird::PathName differenceFile; + Firebird::MetaName setDefaultCharSet; + Firebird::MetaName setDefaultCollation; + Firebird::Array<DbFileClause*> files; +}; + + } // namespace #endif // DSQL_DDL_NODES_H Modified: firebird/trunk/src/dsql/Nodes.h =================================================================== --- firebird/trunk/src/dsql/Nodes.h 2011-11-20 09:45:00 UTC (rev 53640) +++ firebird/trunk/src/dsql/Nodes.h 2011-11-22 16:33:25 UTC (rev 53641) @@ -133,7 +133,9 @@ { using namespace Firebird; - dsqlScratch->setTransaction(transaction); + // dsqlScratch should be NULL with CREATE DATABASE. + if (dsqlScratch) + dsqlScratch->setTransaction(transaction); try { Modified: firebird/trunk/src/dsql/Parser.h =================================================================== --- firebird/trunk/src/dsql/Parser.h 2011-11-20 09:45:00 UTC (rev 53640) +++ firebird/trunk/src/dsql/Parser.h 2011-11-22 16:33:25 UTC (rev 53641) @@ -83,7 +83,6 @@ { // This is, in fact, parser state. Not used in lexer itself dsql_fld* g_field; - dsql_fil* g_file; dsql_nod* g_field_name; int dsql_debug; Modified: firebird/trunk/src/dsql/ddl.cpp =================================================================== --- firebird/trunk/src/dsql/ddl.cpp 2011-11-20 09:45:00 UTC (rev 53640) +++ firebird/trunk/src/dsql/ddl.cpp 2011-11-22 16:33:25 UTC (rev 53641) @@ -116,25 +116,18 @@ static void assign_field_length(dsql_fld*, USHORT); static void define_computed(DsqlCompilerScratch*, dsql_nod*, dsql_fld*, dsql_nod*); -static void define_database(DsqlCompilerScratch*); static void define_filter(DsqlCompilerScratch*); static SSHORT getBlobFilterSubType(DsqlCompilerScratch* dsqlScratch, const dsql_nod* node); static void define_index(DsqlCompilerScratch*); -static void define_shadow(DsqlCompilerScratch*); static void generate_dyn(DsqlCompilerScratch*, dsql_nod*); static void grant_revoke(DsqlCompilerScratch*); -static void modify_database(DsqlCompilerScratch*); -static void modify_index(DsqlCompilerScratch*); static void modify_privilege(DsqlCompilerScratch* dsqlScratch, NOD_TYPE type, SSHORT option, const UCHAR* privs, const dsql_nod* table, const dsql_nod* user, const dsql_nod* grantor, const dsql_str* field_name); static char modify_privileges(DsqlCompilerScratch*, NOD_TYPE, SSHORT, const dsql_nod*, const dsql_nod*, const dsql_nod*, const dsql_nod*); -static void modify_udf(DsqlCompilerScratch*); -static void modify_map(DsqlCompilerScratch*); static void process_role_nm_list(DsqlCompilerScratch*, SSHORT, const dsql_nod*, const dsql_nod*, NOD_TYPE, const dsql_nod*); -static void set_statistics(DsqlCompilerScratch*); static void define_user(DsqlCompilerScratch*, UCHAR); static void put_grantor(DsqlCompilerScratch* dsqlScratch, const dsql_nod* grantor); static void post_607(const Arg::StatusVector& v); @@ -177,17 +170,6 @@ const NOD_TYPE type = statement->getDdlNode()->nod_type; - switch (type) - { - case nod_del_udf: - case nod_mod_udf: - // Signal UDF for obsolescence - string = (dsql_str*) statement->getDdlNode()->nod_arg[e_udf_name]; - sym_type = SYM_udf; - METD_drop_function(request->getTransaction(), QualifiedName(string->str_data, "")); - break; - } - if (string) MET_dsql_cache_release(tdbb, sym_type, string->str_data); @@ -712,97 +694,6 @@ } -static void define_database(DsqlCompilerScratch* dsqlScratch) -{ -/************************************** - * - * d e f i n e _ d a t a b a s e - * - ************************************** - * - * Function - * Create a database. Assumes that - * database is created elsewhere with - * initial options. Modify the - * database using DYN to add the remaining - * options. - * - **************************************/ - SLONG start = 0; - - DsqlCompiledStatement* statement = dsqlScratch->getStatement(); - const dsql_nod* ddl_node = statement->getDdlNode(); - - dsqlScratch->appendUChar(isc_dyn_mod_database); - - // dsqlScratch->appendNumber(isc_dyn_rel_sql_protection, 1); - - const dsql_nod* elements = ddl_node->nod_arg[e_database_initial_desc]; - - if (elements) - { - const dsql_nod* const* ptr = elements->nod_arg; - for (const dsql_nod* const* const end = ptr + elements->nod_count; ptr < end; ptr++) - { - const dsql_nod* element = *ptr; - - switch (element->nod_type) - { - case nod_file_length: - start = (IPTR) element->nod_arg[0] + 1; - break; - - default: - break; - } - } - } - - const dsql_str* name; - const dsql_fil* file; - elements = ddl_node->nod_arg[e_database_rem_desc]; - if (elements) - { - const dsql_nod* const* ptr = elements->nod_arg; - for (const dsql_nod* const* const end = ptr + elements->nod_count; ptr < end; ptr++) - { - const dsql_nod* element = *ptr; - - switch (element->nod_type) - { - case nod_difference_file: - dsqlScratch->appendNullString(isc_dyn_def_difference, - ((dsql_str*) element->nod_arg[0])->str_data); - break; - case nod_file_desc: - file = (dsql_fil*) element->nod_arg[0]; - dsqlScratch->appendNullString(isc_dyn_def_file, file->fil_name->str_data); - - start = MAX(start, file->fil_start); - dsqlScratch->appendFileStart(start); - dsqlScratch->appendFileLength(file->fil_length); - dsqlScratch->appendUChar(isc_dyn_end); - start += file->fil_length; - break; - case nod_dfl_charset: - name = (dsql_str*) element->nod_arg[0]; - dsqlScratch->appendNullString(isc_dyn_fld_character_set_name, name->str_data); - break; - case nod_dfl_collate: - name = (dsql_str*) element->nod_arg[0]; - dsqlScratch->appendNullString(isc_dyn_fld_collation, name->str_data); - break; - - default: - break; - } - } - } - - dsqlScratch->appendUChar(isc_dyn_end); -} - - static SSHORT getBlobFilterSubType(DsqlCompilerScratch* dsqlScratch, const dsql_nod* node) { /******************************************* @@ -924,61 +815,6 @@ } -// -// create a shadow for the database -// -static void define_shadow(DsqlCompilerScratch* dsqlScratch) -{ - DsqlCompiledStatement* statement = dsqlScratch->getStatement(); - const dsql_nod* shadow_node = statement->getDdlNode(); - const dsql_nod* const* ptr = shadow_node->nod_arg; - - if (!ptr[e_shadow_number]) - { - post_607(Arg::Gds(isc_dsql_shadow_number_err)); - } - - dsqlScratch->appendNumber(isc_dyn_def_shadow, (SSHORT)(IPTR) (ptr[e_shadow_number])); - dsqlScratch->appendNullString(isc_dyn_def_file, ((dsql_str*) (ptr[e_shadow_name]))->str_data); - dsqlScratch->appendNumber(isc_dyn_shadow_man_auto, - (SSHORT) ExprNode::as<LiteralNode>(ptr[e_shadow_man_auto])->getSlong()); - dsqlScratch->appendNumber(isc_dyn_shadow_conditional, - (SSHORT) ExprNode::as<LiteralNode>(ptr[e_shadow_conditional])->getSlong()); - - dsqlScratch->appendFileStart(0); - - SLONG length = (IPTR) ptr[e_shadow_length]; - dsqlScratch->appendFileLength(length); - - dsqlScratch->appendUChar(isc_dyn_end); - const dsql_nod* elements = ptr[e_shadow_sec_files]; - if (elements) - { - ptr = elements->nod_arg; - for (const dsql_nod* const* const end = ptr + elements->nod_count; ptr < end; ++ptr) - { - const dsql_nod* element = *ptr; - const dsql_fil* file = (dsql_fil*) element->nod_arg[0]; - dsqlScratch->appendNullString(isc_dyn_def_file, file->fil_name->str_data); - - if (!length && !file->fil_start) - { - // Preceding file did not specify length, so %s must include starting page number - post_607(Arg::Gds(isc_dsql_file_length_err) << Arg::Str(file->fil_name->str_data)); - } - - const SLONG start = file->fil_start; - dsqlScratch->appendFileStart(start); - length = file->fil_length; - dsqlScratch->appendFileLength(length); - dsqlScratch->appendUChar(isc_dyn_end); - } - } - - dsqlScratch->appendUChar(isc_dyn_end); -} - - static void generate_dyn(DsqlCompilerScratch* dsqlScratch, dsql_nod* node) { /************************************** @@ -1009,40 +845,6 @@ define_filter(dsqlScratch); break; - case nod_del_udf: - string = (dsql_str*) node->nod_arg[0]; - dsqlScratch->appendNullString(isc_dyn_delete_function, string->str_data); - dsqlScratch->appendUChar(isc_dyn_end); - break; - - case nod_def_shadow: - define_shadow(dsqlScratch); - break; - - case nod_mod_database: - modify_database(dsqlScratch); - break; - - case nod_def_database: - define_database(dsqlScratch); - break; - - case nod_mod_index: - modify_index(dsqlScratch); - break; - - case nod_set_statistics: - set_statistics(dsqlScratch); - break; - - case nod_mod_udf: - modify_udf(dsqlScratch); - break; - - case nod_mod_role: - modify_map(dsqlScratch); - break; - case nod_add_user: define_user(dsqlScratch, isc_dyn_user_add); break; @@ -1143,113 +945,6 @@ } -static void modify_database( DsqlCompilerScratch* dsqlScratch) -{ -/************************************** - * - * m o d i f y _ d a t a b a s e - * - ************************************** - * - * Function - * Modify a database. - * - **************************************/ - DsqlCompiledStatement* statement = dsqlScratch->getStatement(); - const dsql_nod* ddl_node = statement->getDdlNode(); - - dsqlScratch->appendUChar(isc_dyn_mod_database); - // dsqlScratch->appendNumber(isc_dyn_rel_sql_protection, 1); - bool drop_difference = false; - - const dsql_nod* elements = ddl_node->nod_arg[e_adb_all]; - const dsql_nod* const* end = elements->nod_arg + elements->nod_count; - const dsql_nod* const* ptr; - - for (ptr = elements->nod_arg; ptr < end; ptr++) - { - const dsql_nod* element = *ptr; - if (element->nod_type == nod_drop_difference) - drop_difference = true; - } - - if (drop_difference) - dsqlScratch->appendUChar(isc_dyn_drop_difference); - - SLONG start = 0; - - elements = ddl_node->nod_arg[e_adb_all]; - end = elements->nod_arg + elements->nod_count; - for (ptr = elements->nod_arg; ptr < end; ptr++) - { - const dsql_fil* file; - const dsql_nod* element = *ptr; - - switch (element->nod_type) - { - case nod_file_desc: - file = (dsql_fil*) element->nod_arg[0]; - dsqlScratch->appendNullString(isc_dyn_def_file, file->fil_name->str_data); - - start = MAX(start, file->fil_start); - dsqlScratch->appendFileStart(start); - - dsqlScratch->appendFileLength(file->fil_length); - dsqlScratch->appendUChar(isc_dyn_end); - start += file->fil_length; - break; - case nod_difference_file: - dsqlScratch->appendNullString(isc_dyn_def_difference, - ((dsql_str*) element->nod_arg[0])->str_data); - break; - case nod_begin_backup: - dsqlScratch->appendUChar(isc_dyn_begin_backup); - break; - case nod_end_backup: - dsqlScratch->appendUChar(isc_dyn_end_backup); - break; - case nod_dfl_charset: - dsqlScratch->appendNullString(isc_dyn_fld_character_set_name, - ((dsql_str*) element->nod_arg[0])->str_data); - break; - default: - break; - } - } - - dsqlScratch->appendUChar(isc_dyn_end); -} - - -static void modify_index( DsqlCompilerScratch* dsqlScratch) -{ -/************************************** - * - * m o d i f y _ i n d e x - * - ************************************** - * - * Function - * Alter an index (only active or inactive for now) - * - **************************************/ - DsqlCompiledStatement* statement = dsqlScratch->getStatement(); - dsql_nod* ddl_node = statement->getDdlNode(); - - dsql_nod* index_node = ddl_node->nod_arg[e_alt_index]; - const dsql_str* index_name = (dsql_str*) index_node->nod_arg[e_alt_idx_name]; - - dsqlScratch->appendNullString(isc_dyn_mod_idx, index_name->str_data); - - if (index_node->nod_type == nod_idx_active) - dsqlScratch->appendNumber(isc_dyn_idx_inactive, 0); - else if (index_node->nod_type == nod_idx_inactive) - dsqlScratch->appendNumber(isc_dyn_idx_inactive, 1); - - dsqlScratch->appendUChar(isc_dyn_end); -} - - static void put_user_grant(DsqlCompilerScratch* dsqlScratch, const dsql_nod* user) { /************************************** @@ -1477,68 +1172,6 @@ } -// ******************* -// m o d i f y _ u d f -// ******************* -// Allow the user to change the entry point or module name. -// Useful when there are dependencies on the udf, so it cannot be dropped. -static void modify_udf(DsqlCompilerScratch* dsqlScratch) -{ - DsqlCompiledStatement* statement = dsqlScratch->getStatement(); - - const dsql_nod* node = statement->getDdlNode(); - fb_assert(node->nod_type == nod_mod_udf); - const dsql_str* obj_name = (dsql_str*) node->nod_arg[e_mod_udf_name]; - - if (!node->nod_arg[e_mod_udf_entry_pt] && !node->nod_arg[e_mod_udf_module]) - { - ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) << - // Unexpected end of command - Arg::Gds(isc_command_end_err2) << Arg::Num(node->nod_line) << - Arg::Num(node->nod_column + obj_name->str_length)); - // + strlen("FUNCTION") - } - - dsqlScratch->appendNullString(isc_dyn_mod_function, obj_name->str_data); - - const dsql_str* entry_point_name = (dsql_str*) node->nod_arg[e_mod_udf_entry_pt]; - if (entry_point_name) - dsqlScratch->appendNullString(isc_dyn_func_entry_point, entry_point_name->str_data); - - const dsql_str* module_name = (dsql_str*) node->nod_arg[e_mod_udf_module]; - if (module_name) - dsqlScratch->appendNullString(isc_dyn_func_module_name, module_name->str_data); - - dsqlScratch->appendUChar(isc_dyn_end); -} - - -// ******************* -// m o d i f y _ m a p -// ******************* -// Allow the user to establish/drop the mapping between OS security object and the role -static void modify_map(DsqlCompilerScratch* dsqlScratch) -{ - DsqlCompiledStatement* statement = dsqlScratch->getStatement(); - - const dsql_nod* node = statement->getDdlNode(); - fb_assert(node->nod_type == nod_mod_role); - - const dsql_str* ds = (dsql_str*) node->nod_arg[e_mod_role_os_name]; - fb_assert(ds || - ExprNode::as<LiteralNode>(node->nod_arg[e_mod_role_action])->getSlong() == isc_dyn_automap_role || - ExprNode::as<LiteralNode>(node->nod_arg[e_mod_role_action])->getSlong() == isc_dyn_autounmap_role); - dsqlScratch->appendNullString(isc_dyn_mapping, ds ? ds->str_data : ""); - - ds = (dsql_str*) node->nod_arg[e_mod_role_db_name]; - fb_assert(ds); - dsqlScratch->appendNullString( - ExprNode::as<LiteralNode>(node->nod_arg[e_mod_role_action])->getSlong(), ds->str_data); - - dsqlScratch->appendUChar(isc_dyn_end); -} - - // ********************* // d e f i n e _ u s e r // ********************* @@ -1692,27 +1325,6 @@ } -static void set_statistics(DsqlCompilerScratch* dsqlScratch) -{ -/************************************** - * - * s e t _ s t a t i s t i c s - * - ************************************** - * - * Function - * Alter an index/.. statistics - * - **************************************/ - DsqlCompiledStatement* statement = dsqlScratch->getStatement(); - const dsql_nod* ddl_node = statement->getDdlNode(); - const dsql_str* index_name = (dsql_str*) ddl_node->nod_arg[e_stat_name]; - dsqlScratch->appendNullString(isc_dyn_mod_idx, index_name->str_data); - dsqlScratch->appendUChar(isc_dyn_idx_statistic); - dsqlScratch->appendUChar(isc_dyn_end); -} - - // post very often used error - avoid code duplication static void post_607(const Arg::StatusVector& v) { Modified: firebird/trunk/src/dsql/dsql.h =================================================================== --- firebird/trunk/src/dsql/dsql.h 2011-11-20 09:45:00 UTC (rev 53640) +++ firebird/trunk/src/dsql/dsql.h 2011-11-22 16:33:25 UTC (rev 53641) @@ -280,20 +280,6 @@ FLD_system = 8 }; -//! database/log/cache file block -class dsql_fil : public pool_alloc<dsql_type_fil> -{ -public: - SLONG fil_length; // File length in pages - SLONG fil_start; // Starting page - dsql_str* fil_name; // File name - //dsql_fil* fil_next; // next file - //SSHORT fil_shadow_number; // shadow number if part of shadow - //SSHORT fil_manual; // flag to indicate manual shadow - //SSHORT fil_partitions; // number of log file partitions - //USHORT fil_flags; -}; - //! Stored Procedure block class dsql_prc : public pool_alloc<dsql_type_prc> { Modified: firebird/trunk/src/dsql/node.h =================================================================== --- firebird/trunk/src/dsql/node.h 2011-11-20 09:45:00 UTC (rev 53640) +++ firebird/trunk/src/dsql/node.h 2011-11-22 16:33:25 UTC (rev 53641) @@ -60,17 +60,13 @@ nod_trans, nod_def_default, nod_del_default, - nod_def_database, nod_def_domain, - nod_mod_database, nod_def_field, nod_mod_field, nod_del_field, nod_def_index, nod_def_constraint, nod_def_filter, - nod_def_shadow, - nod_del_udf, nod_grant, nod_revoke, nod_rel_constraint, @@ -110,25 +106,16 @@ nod_lock_mode, nod_reserve, nod_retain, - nod_page_size, - nod_file_length, - nod_file_desc, - nod_dfl_charset, - nod_password, - nod_lc_ctype, // SET NAMES - nod_udf_return_value, nod_def_computed, nod_plan_expr, nod_plan_item, nod_natural, nod_index, nod_index_order, - nod_mod_index, // alter index nod_idx_active, nod_idx_inactive, nod_restrict, // drop behaviour nod_cascade, - nod_set_statistics, // set statistics nod_ref_upd_del, // referential integrity actions nod_ref_trig_action, nod_role_name, @@ -136,22 +123,14 @@ nod_mod_field_name, nod_mod_field_type, nod_mod_field_pos, - nod_udf_param, // there should be a way to signal a param by descriptor! nod_for_update, // FOR UPDATE clause nod_label, // label support - nod_difference_file, - nod_drop_difference, - nod_begin_backup, - nod_end_backup, nod_rows, // ROWS support - nod_mod_udf, nod_tra_misc, nod_lock_timeout, nod_with, - nod_mod_role, nod_add_user, nod_mod_user, - nod_dfl_collate, nod_trg_act, nod_trg_ext, nod_class_stmtnode, @@ -287,20 +266,12 @@ e_lock_tables = 0, // e_lock_mode, - e_database_name = 0, // - e_database_initial_desc, - e_database_rem_desc, - e_cdb_count, - e_commit_retain = 0, // e_commit_count, e_rollback_retain = 0, // e_rollback_count, - e_adb_all = 0, // - e_adb_count, - e_filter_name = 0, // e_filter_in_type, e_filter_out_type, @@ -308,37 +279,11 @@ e_filter_module, e_filter_count, - e_udf_name = 0, // - e_udf_count, - // computed field e_cmp_expr = 0, e_cmp_text, - // create shadow - - e_shadow_number = 0, - e_shadow_man_auto, - e_shadow_conditional, - e_shadow_name, - e_shadow_length, - e_shadow_sec_files, - e_shadow_count, - - // alter index - - e_alt_index = 0, - e_mod_idx_count, - - e_alt_idx_name = 0, - e_alt_idx_name_count, - - // set statistics - - e_stat_name = 0, - e_stat_count, - e_mod_fld_name_orig_name = 0, // nod_mod_field_name e_mod_fld_name_new_name, e_mod_fld_name_count, @@ -353,24 +298,10 @@ e_mod_fld_pos_new_position, e_mod_fld_pos_count, - e_udf_param_field = 0, - e_udf_param_type, // Basically, by_reference or by_descriptor - e_udf_param_count, - e_label_name = 0, e_label_number, e_label_count, - e_mod_udf_name = 0, // nod_mod_udf - e_mod_udf_entry_pt, - e_mod_udf_module, - e_mod_udf_count, - - e_mod_role_os_name = 0, // nod_mod_role - e_mod_role_db_name, - e_mod_role_action, // 0 - drop, 1 - add - e_mod_role_count, - e_user_name = 0, // nod_add(mod)_user e_user_passwd, e_user_first, Modified: firebird/trunk/src/dsql/parse.y =================================================================== --- firebird/trunk/src/dsql/parse.y 2011-11-20 09:45:00 UTC (rev 53640) +++ firebird/trunk/src/dsql/parse.y 2011-11-22 16:33:25 UTC (rev 53641) @@ -137,12 +137,12 @@ static bool long_int(dsql_nod*, SLONG*); #endif static dsql_fld* make_field (dsql_nod*); -static dsql_fil* make_file(); #ifdef NOT_USED_OR_REPLACED static bool short_int(dsql_nod*, SLONG*, SSHORT); #endif static void stack_nodes (dsql_nod*, DsqlNodStack&); static Firebird::MetaName toName(dsql_nod* node); +static Firebird::PathName toPathName(dsql_str* node); static Firebird::string toString(dsql_str* node); static void yyabandon (SLONG, ISC_STATUS); @@ -633,8 +633,11 @@ Jrd::ReturningClause* returningClause; Firebird::PathName* pathNamePtr; TEXT* textPtr; + Jrd::DbFileClause* dbFileClause; + Firebird::Array<Jrd::DbFileClause*>* dbFilesClause; Jrd::ExternalClause* externalClause; Firebird::Array<Jrd::ParameterClause>* parametersClause; + Jrd::Node* node; Jrd::ExprNode* exprNode; Jrd::BoolExprNode* boolExprNode; Jrd::StmtNode* stmtNode; @@ -647,12 +650,14 @@ Jrd::CreateAlterTriggerNode* createAlterTriggerNode; Jrd::CreateAlterPackageNode* createAlterPackageNode; Jrd::CreateSequenceNode* createSequenceNode; + Jrd::CreateShadowNode* createShadowNode; Firebird::Array<Jrd::CreateAlterPackageNode::Item>* packageItems; Jrd::ExceptionArray* exceptionArray; Jrd::CreateAlterPackageNode::Item packageItem; Jrd::CreatePackageBodyNode* createPackageBodyNode; Jrd::CreateRelationNode* createRelationNode; Jrd::CreateAlterViewNode* createAlterViewNode; + Jrd::AlterDatabaseNode* alterDatabaseNode; Jrd::ExecBlockNode* execBlockNode; Jrd::AggNode* aggNode; Jrd::SysFuncCallNode* sysFuncCallNode; @@ -668,11 +673,15 @@ %type <legacyNode> access_mode access_type alias_list %type <legacyNode> alter alter_clause alter_column_name -%type <legacyNode> alter_data_type_or_domain alter_db -%type <legacyNode> alter_exception_clause alter_index_clause alter_op alter_ops -%type <legacyNode> alter_role_clause alter_role_enable alter_sequence_clause -%type <legacyNode> alter_udf_clause alter_user_clause alter_view_clause +%type <legacyNode> alter_data_type_or_domain +%type <legacyNode> alter_op alter_ops +%type <stmtNode> alter_sequence_clause +%type <legacyNode> alter_user_clause %type <legacyNode> array_element array_range +%type <ddlNode> alter_exception_clause alter_index_clause alter_role_clause alter_udf_clause +%type <ddlNode> alter_view_clause +%type <boolVal> alter_role_enable +%type alter_db(<alterDatabaseNode>) %type arg_desc_list1(<parametersClause>) arg_desc_list(<parametersClause>) %type arg_desc(<parametersClause>) @@ -699,7 +708,8 @@ %type <legacyNode> column_list column_name column_parens column_parens_opt column_select %type <legacyNode> column_singleton commit %type <stmtNode> complex_proc_statement -%type <legacyNode> computed_by computed_clause conditional constant constraint_index_opt +%type <legacyNode> computed_by computed_clause constant constraint_index_opt +%type <boolVal> conditional %type <legacyNode> constraint_name_opt correlation_name create %type <legacyNode> create_clause create_user_clause cross_join %type <legacyNode> cursor_clause cursor_def @@ -707,8 +717,13 @@ %type <stmtNode> cursor_declaration_item continue cursor_statement %type <legacyNode> data_type data_type_or_domain -%type <legacyNode> db_alter_clause db_clause db_file db_file_list db_initial_desc db_initial_desc1 -%type <legacyNode> db_initial_option db_rem_desc db_rem_desc1 db_rem_option ddl_subname +%type db_initial_desc(<alterDatabaseNode>) db_initial_desc1(<alterDatabaseNode>) +%type db_initial_option(<alterDatabaseNode>) db_rem_desc(<alterDatabaseNode>) +%type db_rem_desc1(<alterDatabaseNode>) db_rem_option(<alterDatabaseNode>) +%type <alterDatabaseNode> db_clause +%type <dbFileClause> db_file +%type db_file_list(<dbFilesClause>) +%type <legacyNode> ddl_subname %type <legacyNode> decimal_keyword declare declare_clause %type <legacyNode> decode_pairs def_computed default_par_opt default_value %type <stmtNode> delete delete_positioned delete_searched @@ -718,6 +733,7 @@ %type <legacyNode> domain_or_non_array_type_name domain_type drop_behaviour %type <ddlNode> drop drop_clause %type <legacyStr> db_name ddl_desc +%type db_alter_clause(<alt... [truncated message content] |