private static ExprNode HandleMinMaxNode( string chainFirstLowerCase, Chainable spec) { MinMaxTypeEnum minMaxTypeEnum; var filtered = chainFirstLowerCase.StartsWith("f"); if (chainFirstLowerCase.Equals("min") || chainFirstLowerCase.Equals("fmin")) { minMaxTypeEnum = MinMaxTypeEnum.MIN; } else if (chainFirstLowerCase.Equals("max") || chainFirstLowerCase.Equals("fmax")) { minMaxTypeEnum = MinMaxTypeEnum.MAX; } else { throw new ValidationException("Uncountered unrecognized min or max node '" + spec.GetRootNameOrEmptyString() + "'"); } var args = spec.GetParametersOrEmpty(); var distinct = spec.IsDistinct; var numArgsPositional = ExprAggregateNodeUtil.CountPositionalArgs(args); if (numArgsPositional > 1 && spec.IsDistinct && !filtered) { throw new ValidationException( "The distinct keyword is not valid in per-row min and max " + "functions with multiple sub-expressions"); } ExprNode minMaxNode; if (!distinct && numArgsPositional > 1 && !filtered) { // use the row function minMaxNode = new ExprMinMaxRowNode(minMaxTypeEnum); } else { // use the aggregation function minMaxNode = new ExprMinMaxAggrNode(distinct, minMaxTypeEnum, filtered, false); } minMaxNode.AddChildNodes(args); return(minMaxNode); }
public static void ValidateContextDesc( string contextName, ContextSpecHash hashedSpec, StatementRawInfo statementRawInfo, StatementCompileTimeServices services) { if (hashedSpec.Items.IsEmpty()) { throw new ExprValidationException("Empty list of hash items"); } foreach (var item in hashedSpec.Items) { Chainable chainable = item.Function; // determine type of hash to use var hashFuncName = chainable.GetRootNameOrEmptyString(); var hashFuncParams = chainable.GetParametersOrEmpty(); var hashFunction = HashFunctionEnumExtensions.Determine(contextName, hashFuncName); Pair<Type, ImportSingleRowDesc> hashSingleRowFunction = null; if (hashFunction == null) { try { hashSingleRowFunction = services.ImportServiceCompileTime.ResolveSingleRow( hashFuncName, services.ClassProvidedExtension); } catch (Exception) { // expected } if (hashSingleRowFunction == null) { throw new ExprValidationException( "For context '" + contextName + "' expected a hash function that is any of {" + HashFunctionEnumExtensions.GetStringList() + "} or a plug-in single-row function or script but received '" + hashFuncName + "'"); } } if (hashFuncParams.IsEmpty()) { throw new ExprValidationException( $"For context '{contextName}' expected one or more parameters to the hash function, but found no parameter list"); } // get first parameter var paramExpr = hashFuncParams[0]; var paramType = paramExpr.Forge.EvaluationType; EventPropertyValueGetterForge getter; if (hashFunction == HashFunctionEnum.CONSISTENT_HASH_CRC32) { if (hashFuncParams.Count > 1 || paramType != typeof(string)) { getter = new ContextControllerHashedGetterCRC32SerializedForge( hashFuncParams, hashedSpec.Granularity); } else { getter = new ContextControllerHashedGetterCRC32SingleForge( paramExpr, hashedSpec.Granularity); } } else if (hashFunction == HashFunctionEnum.HASH_CODE) { if (hashFuncParams.Count > 1) { getter = new ContextControllerHashedGetterHashMultiple( hashFuncParams, hashedSpec.Granularity); } else { getter = new ContextControllerHashedGetterHashSingleForge(paramExpr, hashedSpec.Granularity); } } else if (hashSingleRowFunction != null) { getter = new ContextControllerHashedGetterSingleRowForge( hashSingleRowFunction, hashFuncParams, hashedSpec.Granularity, item.FilterSpecCompiled.FilterForEventType, statementRawInfo, services); } else { throw new ArgumentException("Unrecognized hash code function '" + hashFuncName + "'"); } // create and register expression var expression = hashFuncName + "(" + ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(paramExpr) + ")"; var valueSerde = new DataInputOutputSerdeForgeSingleton(typeof(DIONullableIntegerSerde)); var eval = new ExprEventEvaluatorForgeFromProp(getter); var lookupable = new ExprFilterSpecLookupableForge(expression, eval, null, typeof(int), true, valueSerde); item.Lookupable = lookupable; } }