/**
  @file
  @brief Validates a filter clause and updates the source tables
  @details Used to generate a FILTER_RK from an input query dataset.
  Raw values are stored in dc.mpe_filtersource and the meta values are stored
  in dc.mpe_filteranytable

  Input data format:

  |GROUP_LOGIC:$3|SUBGROUP_LOGIC:$3|SUBGROUP_ID:8.|VARIABLE_NM:$32|OPERATOR_NM:$10|RAW_VALUE:$32767|
  |---|---|---|---|---|---|
  |AND|AND|1|SOME_BESTNUM|>|1|
  |AND|AND|1|SOME_TIME|=|77333|


  @param [in] libds= The target dataset to be filtered (lib should be assigned)
  @param [in] queryds= The input query dataset to be validated
  @param [in] dclib= The control library for Data Controller
  @param [out] outresult= The result table with the FILTER_RK
  @param [out] outquery= The original query, taken as extract after table load



  <h4> SAS Macros </h4>
  @li bitemporal_dataloader.sas
  @li mf_getvalue.sas
  @li mf_nobs.sas
  @li mp_abort.sas
  @li mp_filtercheck.sas
  @li mp_hashdataset.sas
  @li removecolsfromwork.sas

  @version 9.2
  @author 4GL Apps Ltd
  @copyright 4GL Apps Ltd.  This code may only be used within Data Controller
    and may not be re-distributed or re-sold without the express permission of
    4GL Apps Ltd.

**/

%macro mpe_validatefilter(libds=,
  queryds=work.filterquery,
  dclib=NOTPROVIDED,
  outresult=work.result,
  outquery=work.query
);

%put &sysmacroname entry vars:;
%put _local_;

%global _program;

%mp_abort(iftrue= (&dclib=NOTPROVIDED)
  ,mac=&sysmacroname
  ,msg=%str(dclib=NOTPROVIDED)
)

%mp_filtercheck(&queryds,targetds=&libds,abort=YES)

%mp_hashdataset(&queryds,outds=myhash,salt=&libds)

%local filter_hash;
%let filter_hash=%upcase(%mf_getvalue(work.myhash,hashkey));

%put &=filter_hash;
data _null_;
  set work.myhash;
  putlog (_all_)(=);
run;

data &outresult;
  set &dclib..mpe_filteranytable;
  where filter_hash="&filter_hash";
run;

%mp_abort(iftrue= (&syscc ne 0)
  ,mac=&_program
  ,msg=%str(syscc=&syscc )
)
%mp_abort(iftrue= ("&filter_hash"=" ")
  ,mac=&_program
  ,msg=%str(problem with filter_hash generation)
)

%if %mf_nobs(&outresult)=0 %then %do;

  /* update source table first */
  data work.filtersource;
    set &queryds;
    filter_hash="&filter_hash";
    filter_line=_n_;
  run;
  %bitemporal_dataloader(base_lib=&dclib
    ,base_dsn=mpe_filtersource
    ,append_dsn=filtersource
    ,PK=filter_hash filter_line
    ,etlsource=&_program
    ,loadtype=UPDATE
    ,processed=PROCESSED_DTTM
    ,dclib=&dclib
  )

  data filter1;
    if 0 then set &dclib..mpe_filteranytable;
    filter_table=symget('libds');
    filter_hash="&filter_hash";
    output;
    stop;
  run;

  %bitemporal_dataloader(base_lib=&dclib
    ,base_dsn=mpe_filteranytable
    ,append_dsn=filter1
    ,PK=filter_rk
    ,rk_underlying=filter_hash
    ,etlsource=&_program
    ,loadtype=UPDATE
    ,processed=PROCESSED_DTTM
    ,dclib=&dclib
  )

  data &outresult;
    set &dclib..mpe_filteranytable;
    where filter_hash="&filter_hash";
  run;

  %removecolsfromwork(___TMP___MD5)

%end;

proc sort data=&dclib..mpe_filtersource(where=(filter_hash="&filter_hash"))
  out=&outquery(drop=filter_hash filter_line processed_dttm);
  by filter_line;
run;

%mend mpe_validatefilter;
