fcmpact addRoutines

Edge Case: Hotfix Deployment by Overwriting a Buggy Function

Scénario de test & Cas d'usage

Business Context

An IoT analytics team deployed a function to detect anomalies in sensor readings. However, the initial version has a 'divide-by-zero' bug. A corrected version must be deployed immediately, replacing the faulty one without affecting the function's name or the table it resides in.
About the Set : fcmpact

Execution of SAS FCMP functions within the CAS environment.

Discover all actions of fcmpact
Data Preparation

Create sensor data, including a record with a baseline of zero, which will trigger the bug in the initial function.

Copied!
1DATA casuser.sensor_readings(promote=yes);
2 INFILE DATALINES dsd;
3 INPUT sensorId $ reading baseline;
4 DATALINES;
5SEN001,105,100
6SEN002,50,0
7SEN003,220,200
8;
9RUN;

Étapes de réalisation

1
Deploy the initial buggy function which does not handle a zero baseline.
Copied!
1PROC CAS;
2 SESSION casauto;
3 fcmpact.addRoutines
4 routineCode={ 'function calculate_deviation(reading, baseline);
5 /* Buggy: does not check for baseline=0 */
6 return ((reading - baseline) / baseline) * 100;
7 endsub;' },
8 package='iot.analytics',
9 funcTable={name='iot_funcs', caslib='casuser', replace=true};
10RUN;
2
Attempt to run the buggy function. This step is expected to produce errors or missing values for the problematic record.
Copied!
1PROC CAS;
2 SESSION casauto;
3 DATA casuser.analysis_v1(promote=yes);
4 method RUN();
5 SET casuser.sensor_readings;
6 deviation_pct = calculate_deviation(reading, baseline);
7 END;
8 dcl package fcmpact('iot.analytics') p;
9 RUN;
10 
11 TABLE.fetch / TABLE={caslib='casuser', name='analysis_v1'};
12RUN;
3
Hotfix: Deploy the corrected function to the same table. By using 'replace=true' (or relying on the default behavior of appendTable=FALSE), this overwrites the previous definition.
Copied!
1PROC CAS;
2 SESSION casauto;
3 fcmpact.addRoutines
4 routineCode={ 'function calculate_deviation(reading, baseline);
5 /* Fixed: handles baseline=0 */
6 if baseline = 0 then return (0);
7 return ((reading - baseline) / baseline) * 100;
8 endsub;' },
9 package='iot.analytics',
10 funcTable={name='iot_funcs', caslib='casuser', replace=true};
11RUN;
4
Verification: Rerun the analysis with the hotfixed function to confirm it now handles the edge case gracefully.
Copied!
1PROC CAS;
2 SESSION casauto;
3 DATA casuser.analysis_v2(promote=yes);
4 method RUN();
5 SET casuser.sensor_readings;
6 deviation_pct = calculate_deviation(reading, baseline);
7 END;
8 dcl package fcmpact('iot.analytics') p;
9 RUN;
10 
11 TABLE.fetch / TABLE={caslib='casuser', name='analysis_v2'};
12RUN;

Expected Result


The first analysis (analysis_v1) will show a missing value or error for SEN002 due to division by zero. The 'addRoutines' call in step 3 successfully overwrites the function in the 'iot_funcs' table. The second analysis (analysis_v2) completes without error for all records. The 'deviation_pct' for SEN002 is now 0, while the other sensors (SEN001, SEN003) show correct deviations of 5.0 and 10.0 respectively.