Each function must implement a constructor that takes only a ScalarRuntimeContract. The function class is instantiated during planning of the query, and it informs the system about its properties through ScalarRuntimeContract. The system fills in various fields in the contract (such as the input schema and the argument clauses) and passes this incomplete contract to the constructor. The constructor must fill in the function's output schema and then complete the contract. Below is an example of a constructor for a simple user defined scalar function that calculates the factorial for a given column.
... // Instance private fields which are initialized // during contract negotiation. private SqlType outputSqlType_; private ValueHolder outputValue_; public Factorial(ScalarRuntimeContract contract){ // Input schema. InputInfo inputInfo = contract.getInputInfo(); if (inputInfo.getColumnCount() != 1){ throw new IllegalUsageException( "function factorial() expects a single input column"); } SqlType inputSqlType = inputInfo.getColumnType(0); if (inputSqlType == SqlType.smallint() || inputSqlType == SqlType.integer() || inputSqlType == SqlType.bigint()) { this.outputSqlType_ = SqlType.bigint(); } else { throw new ClientVisibleException("function factorial(" + inputSqlType.getCanonicalName() +") does not exist"); } // Output schema. ArrayList<ColumnDefinition> outputColumns = new ArrayList<ColumnDefinition>(); outputColumns.add(new ColumnDefinition("result", this.outputSqlType_)); contract.setOutputInfo(new OutputInfo(outputColumns)); // Allocate holder. this.outputValue_ = new ValueHolder(this.outputSqlType_); // Complete the contract contract.complete(); }