From: <asf...@us...> - 2014-01-27 01:09:37
|
Revision: 59080 http://sourceforge.net/p/firebird/code/59080 Author: asfernandes Date: 2014-01-27 01:09:32 +0000 (Mon, 27 Jan 2014) Log Message: ----------- Fixed CORE-4322 - Engine crashes when use aggregate or window functions in recursive query. Vlad, please review. Modified Paths: -------------- firebird/trunk/lang_helpers/gds_codes.ftn firebird/trunk/lang_helpers/gds_codes.pas firebird/trunk/src/dsql/DsqlCompilerScratch.cpp 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/msgs/facilities2.sql firebird/trunk/src/msgs/messages2.sql firebird/trunk/src/msgs/system_errors2.sql Modified: firebird/trunk/lang_helpers/gds_codes.ftn =================================================================== --- firebird/trunk/lang_helpers/gds_codes.ftn 2014-01-27 01:09:05 UTC (rev 59079) +++ firebird/trunk/lang_helpers/gds_codes.ftn 2014-01-27 01:09:32 UTC (rev 59080) @@ -2242,6 +2242,8 @@ PARAMETER (GDS__dsql_grant_failed = 336397319) INTEGER*4 GDS__dsql_revoke_failed PARAMETER (GDS__dsql_revoke_failed = 336397320) + INTEGER*4 GDS__dsql_cte_recursive_aggregate + PARAMETER (GDS__dsql_cte_recursive_aggregate = 336397321) 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 2014-01-27 01:09:05 UTC (rev 59079) +++ firebird/trunk/lang_helpers/gds_codes.pas 2014-01-27 01:09:32 UTC (rev 59080) @@ -1128,6 +1128,7 @@ gds_dsql_alter_user_failed = 336397318; gds_dsql_grant_failed = 336397319; gds_dsql_revoke_failed = 336397320; + gds_dsql_cte_recursive_aggregate = 336397321; gds_gsec_cant_open_db = 336723983; gds_gsec_switches_error = 336723984; gds_gsec_no_op_spec = 336723985; Modified: firebird/trunk/src/dsql/DsqlCompilerScratch.cpp =================================================================== --- firebird/trunk/src/dsql/DsqlCompilerScratch.cpp 2014-01-27 01:09:05 UTC (rev 59079) +++ firebird/trunk/src/dsql/DsqlCompilerScratch.cpp 2014-01-27 01:09:32 UTC (rev 59080) @@ -667,8 +667,6 @@ Arg::Gds(isc_dsql_cte_wrong_clause) << input->alias << Arg::Str("HAVING")); } - // hvlad: we need also forbid any aggregate function here - // but for now i have no idea how to do it simple if (!dsqlAll) { Modified: firebird/trunk/src/dsql/pass1.cpp =================================================================== --- firebird/trunk/src/dsql/pass1.cpp 2014-01-27 01:09:05 UTC (rev 59079) +++ firebird/trunk/src/dsql/pass1.cpp 2014-01-27 01:09:32 UTC (rev 59080) @@ -1723,6 +1723,7 @@ string save_alias; RseNode* rseNode = input->as<RseNode>(); const bool isRecursive = rseNode && (rseNode->dsqlFlags & RecordSourceNode::DFLAG_RECURSIVE); + AutoSetRestore<USHORT> autoScopeLevel(&dsqlScratch->scopeLevel, dsqlScratch->scopeLevel); if (isRecursive) { @@ -1730,6 +1731,10 @@ save_alias = dsqlScratch->recursiveCtx->ctx_alias; dsqlScratch->recursiveCtx->ctx_alias = *dsqlScratch->getNextCTEAlias(); + + // ASF: We need to reset the scope level to the same value found in the non-recursive + // part of the query, to verify usage of aggregate functions correctly. See CORE-4322. + dsqlScratch->scopeLevel = dsqlScratch->recursiveCtx->ctx_scope_level; } RseNode* ret = pass1_rse_impl(dsqlScratch, input, order, rows, updateLock, flags); @@ -1877,12 +1882,34 @@ rse->dsqlSelectList = pass1_sel_list(dsqlScratch, selectList); --dsqlScratch->inSelectList; + if (inputRse->dsqlFlags & RecordSourceNode::DFLAG_RECURSIVE) + { + if (Aggregate2Finder::find(dsqlScratch->scopeLevel, FIELD_MATCH_TYPE_EQUAL, false, + rse->dsqlSelectList)) + { + // Recursive member of CTE cannot use aggregate function + ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) << + Arg::Gds(isc_dsql_cte_recursive_aggregate)); + } + } + // Process ORDER clause, if any if (order) { ++dsqlScratch->inOrderByClause; rse->dsqlOrder = PASS1_sort(dsqlScratch, order, selectList); --dsqlScratch->inOrderByClause; + + if (inputRse->dsqlFlags & RecordSourceNode::DFLAG_RECURSIVE) + { + if (Aggregate2Finder::find(dsqlScratch->scopeLevel, FIELD_MATCH_TYPE_EQUAL, false, + rse->dsqlOrder)) + { + // Recursive member of CTE cannot use aggregate function + ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) << + Arg::Gds(isc_dsql_cte_recursive_aggregate)); + } + } } // A GROUP BY, HAVING, or any aggregate function in the select list Modified: firebird/trunk/src/include/gen/codetext.h =================================================================== --- firebird/trunk/src/include/gen/codetext.h 2014-01-27 01:09:05 UTC (rev 59079) +++ firebird/trunk/src/include/gen/codetext.h 2014-01-27 01:09:32 UTC (rev 59080) @@ -1117,6 +1117,7 @@ {"dsql_alter_user_failed", 336397318}, {"dsql_grant_failed", 336397319}, {"dsql_revoke_failed", 336397320}, + {"dsql_cte_recursive_aggregate", 336397321}, {"gsec_cant_open_db", 336723983}, {"gsec_switches_error", 336723984}, {"gsec_no_op_spec", 336723985}, Modified: firebird/trunk/src/include/gen/iberror.h =================================================================== --- firebird/trunk/src/include/gen/iberror.h 2014-01-27 01:09:05 UTC (rev 59079) +++ firebird/trunk/src/include/gen/iberror.h 2014-01-27 01:09:32 UTC (rev 59080) @@ -1151,6 +1151,7 @@ const ISC_STATUS isc_dsql_alter_user_failed = 336397318L; const ISC_STATUS isc_dsql_grant_failed = 336397319L; const ISC_STATUS isc_dsql_revoke_failed = 336397320L; +const ISC_STATUS isc_dsql_cte_recursive_aggregate = 336397321L; const ISC_STATUS isc_gsec_cant_open_db = 336723983L; const ISC_STATUS isc_gsec_switches_error = 336723984L; const ISC_STATUS isc_gsec_no_op_spec = 336723985L; @@ -1252,7 +1253,7 @@ const ISC_STATUS isc_trace_switch_param_miss = 337182758L; const ISC_STATUS isc_trace_param_act_notcompat = 337182759L; const ISC_STATUS isc_trace_mandatory_switch_miss = 337182760L; -const ISC_STATUS isc_err_max = 1196; +const ISC_STATUS isc_err_max = 1197; #else /* c definitions */ @@ -2373,6 +2374,7 @@ #define isc_dsql_alter_user_failed 336397318L #define isc_dsql_grant_failed 336397319L #define isc_dsql_revoke_failed 336397320L +#define isc_dsql_cte_recursive_aggregate 336397321L #define isc_gsec_cant_open_db 336723983L #define isc_gsec_switches_error 336723984L #define isc_gsec_no_op_spec 336723985L @@ -2474,7 +2476,7 @@ #define isc_trace_switch_param_miss 337182758L #define isc_trace_param_act_notcompat 337182759L #define isc_trace_mandatory_switch_miss 337182760L -#define isc_err_max 1196 +#define isc_err_max 1197 #endif Modified: firebird/trunk/src/include/gen/msgs.h =================================================================== --- firebird/trunk/src/include/gen/msgs.h 2014-01-27 01:09:05 UTC (rev 59079) +++ firebird/trunk/src/include/gen/msgs.h 2014-01-27 01:09:32 UTC (rev 59080) @@ -1120,6 +1120,7 @@ {336397318, "ALTER USER @1 failed"}, /* dsql_alter_user_failed */ {336397319, "GRANT failed"}, /* dsql_grant_failed */ {336397320, "REVOKE failed"}, /* dsql_revoke_failed */ + {336397321, "Recursive member of CTE cannot use aggregate or window function"}, /* dsql_cte_recursive_aggregate */ {336723983, "unable to open database"}, /* gsec_cant_open_db */ {336723984, "error in switch specifications"}, /* gsec_switches_error */ {336723985, "no operation specified"}, /* gsec_no_op_spec */ Modified: firebird/trunk/src/include/gen/sql_code.h =================================================================== --- firebird/trunk/src/include/gen/sql_code.h 2014-01-27 01:09:05 UTC (rev 59079) +++ firebird/trunk/src/include/gen/sql_code.h 2014-01-27 01:09:32 UTC (rev 59080) @@ -1116,6 +1116,7 @@ {336397318, -901}, /* 1030 dsql_alter_user_failed */ {336397319, -901}, /* 1031 dsql_grant_failed */ {336397320, -901}, /* 1032 dsql_revoke_failed */ + {336397321, -104}, /* 1033 dsql_cte_recursive_aggregate */ {336723983, -901}, /* 15 gsec_cant_open_db */ {336723984, -901}, /* 16 gsec_switches_error */ {336723985, -901}, /* 17 gsec_no_op_spec */ Modified: firebird/trunk/src/include/gen/sql_state.h =================================================================== --- firebird/trunk/src/include/gen/sql_state.h 2014-01-27 01:09:05 UTC (rev 59079) +++ firebird/trunk/src/include/gen/sql_state.h 2014-01-27 01:09:32 UTC (rev 59080) @@ -1116,6 +1116,7 @@ {336397318, "42000"}, // 1030 dsql_alter_user_failed {336397319, "42000"}, // 1031 dsql_grant_failed {336397320, "42000"}, // 1032 dsql_revoke_failed + {336397321, "42000"}, // 1033 dsql_cte_recursive_aggregate {336723983, "00000"}, // 15 gsec_cant_open_db {336723984, "00000"}, // 16 gsec_switches_error {336723985, "00000"}, // 17 gsec_no_op_spec Modified: firebird/trunk/src/msgs/facilities2.sql =================================================================== --- firebird/trunk/src/msgs/facilities2.sql 2014-01-27 01:09:05 UTC (rev 59079) +++ firebird/trunk/src/msgs/facilities2.sql 2014-01-27 01:09:32 UTC (rev 59080) @@ -10,7 +10,7 @@ ('1996-11-07 13:39:40', 'INSTALL', 10, 1) ('1996-11-07 13:38:41', 'TEST', 11, 4) ('2012-06-23 05:40:21', 'GBAK', 12, 352) -('2012-02-18 20:00:00', 'SQLERR', 13, 1033) +('2014-01-26 23:00:00', 'SQLERR', 13, 1034) ('1996-11-07 13:38:42', 'SQLWARN', 14, 613) ('2006-09-10 03:04:31', 'JRD_BUGCHK', 15, 307) ('2014-01-13 15:41:16', 'ISQL', 17, 184) Modified: firebird/trunk/src/msgs/messages2.sql =================================================================== --- firebird/trunk/src/msgs/messages2.sql 2014-01-27 01:09:05 UTC (rev 59079) +++ firebird/trunk/src/msgs/messages2.sql 2014-01-27 01:09:32 UTC (rev 59080) @@ -2551,6 +2551,7 @@ ('dsql_alter_user_failed', 'getMainErrorCode', 'DdlNodes.h', NULL, 13, 1030, NULL, 'ALTER USER @1 failed', NULL, NULL); ('dsql_grant_failed', 'getMainErrorCode', 'DdlNodes.h', NULL, 13, 1031, NULL, 'GRANT failed', NULL, NULL); ('dsql_revoke_failed', 'getMainErrorCode', 'DdlNodes.h', NULL, 13, 1032, NULL, 'REVOKE failed', NULL, NULL); +('dsql_cte_recursive_aggregate', 'pass1_rse_impl', 'dsql.cpp', NULL, 13, 1033, NULL, 'Recursive member of CTE cannot use aggregate or window function', NULL, NULL); -- SQLWARN (NULL, NULL, NULL, NULL, 14, 100, NULL, 'Row not found for fetch, update or delete, or the result of a query is an empty table.', NULL, NULL); (NULL, NULL, NULL, NULL, 14, 101, NULL, 'segment buffer length shorter than expected', NULL, NULL); Modified: firebird/trunk/src/msgs/system_errors2.sql =================================================================== --- firebird/trunk/src/msgs/system_errors2.sql 2014-01-27 01:09:05 UTC (rev 59079) +++ firebird/trunk/src/msgs/system_errors2.sql 2014-01-27 01:09:32 UTC (rev 59080) @@ -1110,6 +1110,7 @@ (-901, '42', '000', 13, 1030, 'dsql_alter_user_failed', NULL, NULL); (-901, '42', '000', 13, 1031, 'dsql_grant_failed', NULL, NULL); (-901, '42', '000', 13, 1032, 'dsql_revoke_failed', NULL, NULL); +(-104, '42', '000', 13, 1033, 'dsql_cte_recursive_aggregate', NULL, NULL) -- GSEC (-901, '00', '000', 18, 15, 'gsec_cant_open_db', NULL, NULL) (-901, '00', '000', 18, 16, 'gsec_switches_error', NULL, NULL) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |