Проблема с Include Filter

sq_Task:

?xml version="1.0" encoding="UTF-8"?>
Service UID="223AC063F8B742FD88E9A75352D0A4B9" USI="X15\Workspaces\Tasks\General\Main Grid\sq_Task" ServiceTypeCode="SelectQuery" Caption="sq_Task">
...
                                Item Code="ParentIDMass" UID="B0B5ADE418C4476C8FDFF663E9B9FB34" Type="IncludeFilter" IsEnabled="False" ExpressionTypeCode="FieldFilterExpression">
                                        TestExpression Type="FieldFilterExpression" FieldSQLName="ParentTaskID" FieldTableUSI="tbl_Task" TableAlias="tbl_Task">
                                        TestExpression>
                                        ValuesExpressions>
                                        ValuesExpressions>
                                Item>
...
Service>

scr_TasksWorkspace:
        IF (chbParent.IsChecked) {
                var ParentID = chParent.Value;
                var ParamValues = new Array(ParentID);
                IF (!IsEmptyValue(ParentID)) {
                        ApplyDatasetIncludeFilter(Dataset, 'ParentIDMass', ParamValues, true, pdtGUID);
                }else{
                        ApplyDatasetIncludeFilter(Dataset, 'ParentIDMass', ParamValues, false, pdtGUID);
                }
        }

scr_DB:
FUNCTION ApplyDatasetIncludeFilter(Dataset, FilterCode, ParamValues, Enabled, DataType) {
        var SELECT = GetSelectQueryPrimarySelect(Dataset.SelectQuery);
        var Filters = SELECT.Filters;
        EnableFilter(Filters, FilterCode, Enabled);
        ApplyQueryIncludeFilter(Dataset.SelectQuery, Filters, FilterCode,
                ParamValues, Enabled, DataType);
        Log.WRITE(1, Connector.DBEngine.GetSelectQuerySQLText(Dataset.SelectQuery));
}

Содержимое лога:
[08.09.30 16.55.55.945] (W)     SELECT
        "tbl_Task"."ID" AS "ID",
        "tbl_Task"."Title" AS "Title",
        "tbl_Task"."DueDate" AS "DueDate",
        "tbl_Task"."CreatedByID" AS "AuthorID",
        "Author"."Name" AS "AuthorName",
        "tbl_Task"."OwnerID" AS "OwnerID",
        "tbl_Task"."AccountID" AS "AccountID",
        "tbl_Account"."Name" AS "AccountName",
        "tbl_Task"."StatusID" AS "StatusID",
        "tbl_TaskStatus"."Status" AS "StatusName",
        "tbl_Task"."ActualStartDate" AS "ActualStartDate",
        "tbl_Task"."ActualFinishDate" AS "ActualFinishDate",
        "tbl_TaskStatus"."Color" AS "StatusColor",
        "tbl_TaskStatus"."IsStart" AS "StatusIsStart",
        "tbl_TaskStatus_old"."IsStart" AS "OldStatusIsStart",
        "tbl_TaskStatus"."IsFinish" AS "StatusIsFinish",
        "tbl_Task"."WorkflowItemID" AS "WorkflowItemID"
FROM
        "tbl_Task" "tbl_Task"
LEFT OUTER JOIN
        "tbl_Contact" AS "Author" ON "Author"."ID" = "tbl_Task"."CreatedByID"
LEFT OUTER JOIN
        "tbl_Account" AS "tbl_Account" ON "tbl_Account"."ID" = "tbl_Task"."AccountID"
LEFT OUTER JOIN
        "tbl_TaskStatus" AS "tbl_TaskStatus" ON "tbl_TaskStatus"."ID" = "tbl_Task"."StatusID"
LEFT OUTER JOIN
        "tbl_TaskStatus" AS "tbl_TaskStatus_old" ON "tbl_TaskStatus_old"."ID" = "tbl_Task"."OldStatusID"
WHERE
        (((("tbl_Task"."StartDate" :ToDate AND
        ("tbl_Task"."DueDate" >= :StartDate OR
        "tbl_Task"."ActualFinishDate" >= :StartDate)) OR
        ("tbl_Task"."DueDate" :CurrentDate AND
        "tbl_TaskStatus"."IsFinish" > :IsFinish)) AND
        NOT "tbl_TaskStatus"."IsFinish" = :True AND
        NOT "tbl_TaskStatus"."IsStop" = :True AND
        NOT "tbl_TaskStatus"."IsReject" = :True))
ORDER BY
        10 ASC
ROWS    1       TO      40
[08.09.30 16.56.02.273] (W)     SELECT
        "tbl_Task"."ID" AS "ID",
        "tbl_Task"."Title" AS "Title",
        "tbl_Task"."DueDate" AS "DueDate",
        "tbl_Task"."CreatedByID" AS "AuthorID",
        "Author"."Name" AS "AuthorName",
        "tbl_Task"."OwnerID" AS "OwnerID",
        "tbl_Task"."AccountID" AS "AccountID",
        "tbl_Account"."Name" AS "AccountName",
        "tbl_Task"."StatusID" AS "StatusID",
        "tbl_TaskStatus"."Status" AS "StatusName",
        "tbl_Task"."ActualStartDate" AS "ActualStartDate",
        "tbl_Task"."ActualFinishDate" AS "ActualFinishDate",
        "tbl_TaskStatus"."Color" AS "StatusColor",
        "tbl_TaskStatus"."IsStart" AS "StatusIsStart",
        "tbl_TaskStatus_old"."IsStart" AS "OldStatusIsStart",
        "tbl_TaskStatus"."IsFinish" AS "StatusIsFinish",
        "tbl_Task"."WorkflowItemID" AS "WorkflowItemID"
FROM
        "tbl_Task" "tbl_Task"
LEFT OUTER JOIN
        "tbl_Contact" AS "Author" ON "Author"."ID" = "tbl_Task"."CreatedByID"
LEFT OUTER JOIN
        "tbl_Account" AS "tbl_Account" ON "tbl_Account"."ID" = "tbl_Task"."AccountID"
LEFT OUTER JOIN
        "tbl_TaskStatus" AS "tbl_TaskStatus" ON "tbl_TaskStatus"."ID" = "tbl_Task"."StatusID"
LEFT OUTER JOIN
        "tbl_TaskStatus" AS "tbl_TaskStatus_old" ON "tbl_TaskStatus_old"."ID" = "tbl_Task"."OldStatusID"
WHERE
        (((("tbl_Task"."StartDate" :ToDate AND
        ("tbl_Task"."DueDate" >= :StartDate OR
        "tbl_Task"."ActualFinishDate" >= :StartDate)) OR
        ("tbl_Task"."DueDate" :CurrentDate AND
        "tbl_TaskStatus"."IsFinish" > :IsFinish)) AND
        NOT "tbl_TaskStatus"."IsFinish" = :True AND
        NOT "tbl_TaskStatus"."IsStop" = :True AND
        NOT "tbl_TaskStatus"."IsReject" = :True AND
        "tbl_Task"."ParentTaskID" IN ()))
ORDER BY
        10 ASC
ROWS    1       TO      40

Первая запись без фильтра, вторая с фильтром.
При включении фильтрации возникает ошибка:
...
SQL error code = -104
...
Error code: 249

Что я не так делаю?

Нравится

6 комментариев

Добрый день, Константин.

Внешне все правильно:
1) фильтр создан правильно
2) функция наложения фильтра реализована и вызывается верно,

но наблюдаем ошибку сборки запроса. Наиболее вероятная причина - некорректная работа функции ApplyQueryIncludeFilter, которая осуществляет собственно наложение фильтра.
Насколько я понимаю, речь идет о Firebird.
В данной ситуации единственный выход - отлаживать работу функции ApplyQueryIncludeFilter, используя отладчик скриптов.
Если ничего не поможет - укажите полную версию продукта, постараюсь воспроизвести и помочь.

function ApplyQueryIncludeFilter(Query, Filters, FilterCode, ParamValues, Enabled, 
	DataType) {
	// TODO
	// Переписать - временное решение
	// Усовершенствовать для работы с вложенными SelectQuery
	// Удалять созданные параметры
	// Передавать тип параметров
	// Генерировать нормальное имя ParamExpression
	if ((Enabled) && ((!Assigned(ParamValues)) || (ParamValues.length == 0))) {
		return;
	}
	var Filter;
	var ValuesExpressions;
	var Param;
	var ParamExpression;
	for (var i = 0; i < Filters.Count; i++) {
		Filter = Filters.Items(i);
		if  ((Filter.Code == FilterCode) && (Filter.FilterType == ftInclude)){
			ValuesExpressions = Filter.ValuesExpressions;
			DeleteParametersByValueExpressions(Query.Parameters, ValuesExpressions);
			ValuesExpressions.Clear();
			Filter.IsEnabled = Enabled;
			if (!Enabled) {
				return;
			}
			for (var j in ParamValues) {
				Param = Query.Parameters.CreateItem();
				Param.Name = GenParamName(Query.Parameters);
				Param.Value = ParamValues[j];
				if (DataType == null) {
					DataType = sdtUnicodeString;
				}
				Param.DataType = DataType;
				Query.Parameters.Add(Param);
				ParamExpression = 
					ValuesExpressions.CreateParamFilterExpression();
				ValuesExpressions.Add(ParamExpression);
				ParamExpression.Code = Connector.GenGUID();
				ParamExpression.Parameter = Param;
			}
		}
	}
}

Эту функцию я не трогал. Она оригинальная.
CRM X25 3.0.4.112, Firebird 2.0
Честно говоря как её отладить я плохо представляю, но придется попробовать...

По вопросу отладки можно почитать тут: http://community.terrasoft.ua/node/1830
Попытаюсь воспроизвести ситуацию, позднее сообщу о результатах.

debugger;
показал, что ApplyQueryIncludeFilter вообще ничего не создаёт.
вставил запись в лог:

...
	for (var i = 0; i < Filters.Count; i++) {
		Filter = Filters.Items(i);
	Log.Write(1, Filter.Code);
		if  ((Filter.Code == FilterCode) && (Filter.FilterType == ftInclude)){
...

И получил странную запись

[08.10.03 11.16.30.634]	(W)	FiltersBuilderOriginalFilters
[08.10.03 11.16.30.634]	(W)	FiltersBuilderFilters

Почему так получается не смог понять... Придется отложить до вечера.

Моя ошибка была в том что я не понимал сути возращаемого:

	var Select = GetSelectQueryPrimarySelect(Dataset.SelectQuery);
	var Filters = Select.Filters;

Временное решение:

function ApplyQueryIncludeFilter2(Query, Filters, FilterCode, ParamValues, Enabled,
	DataType) {
	if ((Enabled) && ((!Assigned(ParamValues)) || (ParamValues.length == 0))) {
		return;
	}
	var Filter;
	var ValuesExpressions;
	var Param;
	var ParamExpression;
	Filter = Filters;
	Log.Write(1, Filter.Code);
		if  ((Filter.Code == FilterCode) && (Filter.FilterType == ftInclude)){
			ValuesExpressions = Filter.ValuesExpressions;
			DeleteParametersByValueExpressions(Query.Parameters, ValuesExpressions);
			ValuesExpressions.Clear();
			Filter.IsEnabled = Enabled;
			if (!Enabled) {
				return;
			}
			for (var j in ParamValues) {
				Param = Query.Parameters.CreateItem();
				Param.Name = GenParamName(Query.Parameters);
				Param.Value = ParamValues[j];
				if (DataType == null) {
					DataType = sdtUnicodeString;
				}
				Param.DataType = DataType;
				Query.Parameters.Add(Param);
				ParamExpression =
					ValuesExpressions.CreateParamFilterExpression();
				ValuesExpressions.Add(ParamExpression);
				ParamExpression.Code = Connector.GenGUID();
				ParamExpression.Parameter = Param;
			}
		}
}
 
function ApplyDatasetIncludeFilter(Dataset, FilterCode, ParamValues, Enabled, DataType) {
	var Select = GetSelectQueryPrimarySelect(Dataset.SelectQuery);
	var Filters = Select.Filters;
//	EnableFilter(Filters, FilterCode, Enabled);
	ApplyDatasetIncludeFilterFor(Filters, Dataset, FilterCode, ParamValues, Enabled, DataType);
//	Log.Write(1, Connector.DBEngine.GetSelectQuerySQLText(Dataset.SelectQuery));
}
 
function ApplyDatasetIncludeFilterFor(Filters, Dataset, FilterCode, ParamValues, Enabled, DataType) {
	var Result = false;
	if (Filters.Code == FilterCode) {
		ApplyQueryIncludeFilter2(Dataset.SelectQuery, Filters, FilterCode,
			ParamValues, Enabled, DataType);
        return true;
	}
	if (Filters.FilterType == ftFilters) {
		for (var i = 0; (i < Filters.Count) && (!Result); i++) {
			Result = ApplyDatasetIncludeFilterFor(Filters.Items(i), Dataset, FilterCode, ParamValues, Enabled, DataType);
		}
		if (Result && Enabled) {
			Filters.IsEnabled = true;
		}
	}
}

Наблюдаемая ситуация вызвана тем, что построитель фильтров создает свое дерево фильтров в запросе набора данных раздела.
В целом, Ваше решение вполне пригодно. Желаю успехов!

Показать все комментарии