Fortran language aggregates
This example uses the following file name: penultimate.f.
Code
program penultimateUda
call nzaeRun()
stop
end
subroutine order(valueOne, valueTwo, valueThree)
if (valueTwo > valueOne) then
tempValue = valueOne
valueOne = valueTwo
valueTwo = tempValue
endif
if (valueThree > valueTwo) then
tempValue = valueTwo
valueTwo = valueThree
valueThree = tempValue
endif
if (valueTwo > valueOne) then
tempValue = valueOne
valueOne = valueTwo
valueTwo = tempValue
endif
if (valueThree > valueTwo) then
tempValue = valueTwo
valueTwo = valueThree
valueThree = tempValue
endif
return
end
subroutine nzaeHandleRequest(handle)
integer stateBoolean, value1, value2, value3, value4, tempValue
stateBoolean = 0
value1 = 0
value2 = 0
value3 = 0
value4 = 0
tempValue = 0
c GET THE NEXT AGGREGATION TYPE.
10 call nzaeGetNextAggregation(handle)
c HANDLE initializeState().
call nzaeIsAggStateInitializeState(handle, stateBoolean)
if (stateBoolean .eq. 1) then
call nzaeSetAggregateInt32(handle, 0, -2147483647)
call nzaeSetAggregateInt32(handle, 1, -2147483647)
call nzaeSaveAggregateResult(handle)
goto 10
endif
c HANDLE accumulate().
call nzaeIsAggStateAccumulate(handle, stateBoolean)
if (stateBoolean .eq. 1) then
call nzaeGetStateInt32(handle, 0, value1, isNull)
call nzaeGetStateInt32(handle, 1, value2, isNull)
call nzaeGetInputInt32(handle, 0, value3, isNull)
if (isNull .eq. 0) then
call order(value1, value2, value3)
endif
call nzaeSetAggregateInt32(handle, 0, value1)
call nzaeSetAggregateInt32(handle, 1, value2)
call nzaeSaveAggregateResult(handle)
goto 10
endif
c HANDLE merge().
c The two calls to order() below ensure that value1 and value2
c are the largest two values.
call nzaeIsAggStateMerge(handle, stateBoolean)
if (stateBoolean .eq. 1) then
call nzaeGetStateInt32(handle, 0, value1, isNull)
call nzaeGetStateInt32(handle, 1, value2, isNull)
call nzaeGetInputStateInt32(handle, 0, value3, isNull)
value4 = 22
call nzaeGetInputStateInt32(handle, 1, value4, isNull)
if (isNull .eq. 0) then
call order(value1, value2, value3)
call order(value2, value3, value4)
endif
call nzaeSetAggregateInt32(handle, 0, value1)
call nzaeSetAggregateInt32(handle, 1, value2)
call nzaeSaveAggregateResult(handle)
goto 10
endif
c HANDLE finalResult().
call nzaeIsAggStateFinalResult(handle, stateBoolean)
if (stateBoolean .eq. 1) then
call nzaeGetStateInt32(handle, 0, value1, isNull)
call nzaeGetStateInt32(handle, 1, value2, isNull)
if (value1 < value2) then
call nzaeSetAggregateInt32(handle, 0, value1)
else
call nzaeSetAggregateInt32(handle, 0, value2)
endif
call nzaeSaveAggregateResult(handle)
goto 10
endif
c HANDLE DONE.
call nzaeIsAggDone(handle, stateBoolean)
if (stateBoolean .eq. 1) then
return
endif
c HANDLE ERRORS.
call nzaeIsAggError(handle, stateBoolean)
if (stateBoolean .eq. 1) then
call nzaeUserError(handle,
+ "Aggregate error state encountered.")
return
endif
c HANDLE INVALID STATE.
call nzaeUserError(handle, "Invalid aggregate state.")
return
end
Compilation
Use the standard
compilation:
$NZ_EXPORT_DIR/ae/utilities/bin/compile_ae --language fortran --version 3 \
--template compile penultimate.fRegistration
Register the example as a UDA by using the state
parameter:
$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --language fortran --version 3 \
--template uda --exe penultimate --sig "penultimate(int4)" \
--state "(int4, int4)" --return int4Running
To run, first create a dummy table and then run the
aggregate:
CREATE TABLE grp_test(value int4);
CREATE TABLE
INSERT INTO grp_test VALUES (1);
INSERT 0 1
INSERT INTO grp_test VALUES (2);
INSERT 0 1
INSERT INTO grp_test VALUES (3);
INSERT 0 1
INSERT INTO grp_test VALUES (4);
INSERT 0 1
INSERT INTO grp_test VALUES (5);
INSERT 0 1
SELECT penultimate(value) FROM grp_test;
PENULTIMATE
-------------
4
(1 row)