Ejemplo n.º 1
0
        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;
            }
        }
Ejemplo n.º 2
0
        public static SerdeEventPropertyDesc ForgeForEventProperty(
            EventType eventTypeSerde,
            string propertyName,
            object propertyType,
            StatementRawInfo raw,
            SerdeCompileTimeResolver resolver)
        {
            DataInputOutputSerdeForge forge;

            if (propertyType == null)
            {
                return(new SerdeEventPropertyDesc(new DataInputOutputSerdeForgeSingleton(typeof(DIOSkipSerde)), EmptySet <EventType> .Instance));
            }

            if (propertyType is Type propertyTypeType)
            {
                // handle special Json catch-all types
                if (eventTypeSerde is JsonEventType)
                {
                    forge = null;
                    if (propertyTypeType == typeof(IDictionary <string, object>))
                    {
                        forge = new DataInputOutputSerdeForgeSingleton(typeof(DIOJsonObjectSerde));
                    }
                    else if (propertyTypeType == typeof(object[]))
                    {
                        forge = new DataInputOutputSerdeForgeSingleton(typeof(DIOJsonArraySerde));
                    }
                    else if (propertyTypeType == typeof(object))
                    {
                        forge = new DataInputOutputSerdeForgeSingleton(typeof(DIOJsonAnyValueSerde));
                    }

                    if (forge != null)
                    {
                        return(new SerdeEventPropertyDesc(forge, EmptySet <EventType> .Instance));
                    }
                }

                // handle all Class-type properties
                var typedProperty = (Type)propertyType;
                if (typedProperty == typeof(object) && propertyName.Equals(INTERNAL_RESERVED_PROPERTY))
                {
                    forge = new DataInputOutputSerdeForgeSingleton(
                        typeof(DIOSkipSerde));                         // for expression data window or others that include transient references in the field
                }
                else
                {
                    forge = resolver.SerdeForEventProperty(typedProperty, eventTypeSerde.Name, propertyName, raw);
                }

                return(new SerdeEventPropertyDesc(forge, EmptySet <EventType> .Instance));
            }

            if (propertyType is EventType)
            {
                var eventType = (EventType)propertyType;
                Func <DataInputOutputSerdeForgeParameterizedVars, CodegenExpression> func = vars =>
                                                                                            ResolveTypeCodegenGivenResolver(eventType, vars.OptionalEventTypeResolver);
                forge = new DataInputOutputSerdeForgeEventSerde("NullableEvent", func);
                return(new SerdeEventPropertyDesc(forge, Collections.SingletonSet(eventType)));
            }
            else if (propertyType is EventType[])
            {
                var eventType = ((EventType[])propertyType)[0];
                Func <DataInputOutputSerdeForgeParameterizedVars, CodegenExpression> func = vars =>
                                                                                            ResolveTypeCodegenGivenResolver(eventType, vars.OptionalEventTypeResolver);
                forge = new DataInputOutputSerdeForgeEventSerde("NullableEventArray", func);
                return(new SerdeEventPropertyDesc(forge, Collections.SingletonSet(eventType)));
            }
            else if (propertyType is TypeBeanOrUnderlying)
            {
                var eventType = ((TypeBeanOrUnderlying)propertyType).EventType;
                Func <DataInputOutputSerdeForgeParameterizedVars, CodegenExpression> func = vars =>
                                                                                            ResolveTypeCodegenGivenResolver(eventType, vars.OptionalEventTypeResolver);
                forge = new DataInputOutputSerdeForgeEventSerde("NullableEventOrUnderlying", func);
                return(new SerdeEventPropertyDesc(forge, Collections.SingletonSet(eventType)));
            }
            else if (propertyType is TypeBeanOrUnderlying[])
            {
                var eventType = ((TypeBeanOrUnderlying[])propertyType)[0].EventType;
                Func <DataInputOutputSerdeForgeParameterizedVars, CodegenExpression> func = vars =>
                                                                                            ResolveTypeCodegenGivenResolver(eventType, vars.OptionalEventTypeResolver);
                forge = new DataInputOutputSerdeForgeEventSerde("NullableEventArrayOrUnderlying", func);
                return(new SerdeEventPropertyDesc(forge, Collections.SingletonSet(eventType)));
            }
            else if (propertyType is IDictionary <string, object> keyValueProperties)
            {
                var keys        = new string[keyValueProperties.Count];
                var serdes      = new DataInputOutputSerdeForge[keyValueProperties.Count];
                var index       = 0;
                var nestedTypes = new LinkedHashSet <EventType>();

                // Rewrite all properties where the value is a string.  First, gather all instances that need
                // to be rewritten into the class that matches the type.
                keyValueProperties
                .Where(entry => entry.Value is string)
                .ToList()
                .ForEach(
                    entry => {
                    var value = entry.Value.ToString()?.Trim();
                    var clazz = TypeHelper.GetPrimitiveTypeForName(value);
                    if (clazz != null)
                    {
                        keyValueProperties[entry.Key] = clazz;
                    }
                });

                foreach (var entry in keyValueProperties)
                {
                    keys[index] = entry.Key;
                    var desc = ForgeForEventProperty(eventTypeSerde, entry.Key, entry.Value, raw, resolver);
                    nestedTypes.AddAll(desc.NestedTypes);
                    serdes[index] = desc.Forge;
                    index++;
                }

                var functions = new Func <DataInputOutputSerdeForgeParameterizedVars, CodegenExpression> [2];
                functions[0] = vars => Constant(keys);
                functions[1] = vars => DataInputOutputSerdeForgeExtensions.CodegenArray(serdes, vars.Method, vars.Scope, vars.OptionalEventTypeResolver);
                forge        = new DataInputOutputSerdeForgeParameterized(typeof(DIOMapPropertySerde).Name, functions);
                return(new SerdeEventPropertyDesc(forge, nestedTypes));
            }
            else
            {
                throw new EPException(
                          "Failed to determine serde for unrecognized property value type '" +
                          propertyType +
                          "' for property '" +
                          propertyName +
                          "' of type '" +
                          eventTypeSerde.Name +
                          "'");
            }
        }