aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/udfs/common/url_base/lib/url_parse.cpp
blob: 63015dadc673572b68a4f300e6b40750238806fe (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include "url_parse.h"

#define FIELD_ADD(name) structBuilder->AddField(#name, optionalStringType, &urlParseIndexes.name);
#define FIELD_FILL(name) \
    if (value.FldIsSet(TUri::Field##name)) { \
        fields[UrlParseIndexes.name] = valueBuilder->NewString(value.GetField(TUri::Field##name)); \
    }

namespace NUrlUdf {
    using namespace NUri;
    using namespace NKikimr;
    using namespace NUdf;

    TUnboxedValue TParse::Run(
        const IValueBuilder* valueBuilder,
        const TUnboxedValuePod* args) const {
        TUri value;
        const auto ParseError = value.ParseAbs(args[0].AsStringRef(), ParseFlags);
        TUnboxedValue* fields = nullptr;
        const auto result = valueBuilder->NewArray(FieldsCount, fields);
        if (ParseError == TUri::ParsedOK) {
            FIELD_MAP(FIELD_FILL)
        } else {
            fields[UrlParseIndexes.ParseError] = valueBuilder->NewString(TStringBuilder() << ParseError);
        }
        return result;
    }

    bool TParse::DeclareSignature(
        const TStringRef& name,
        TType* userType,
        IFunctionTypeInfoBuilder& builder,
        bool typesOnly) {
        Y_UNUSED(userType);
        if (Name() == name) {
            TUrlParseIndexes urlParseIndexes;

            builder.Args(1)->Add<TAutoMap<char*>>();
            const auto optionalStringType = builder.Optional()->Item<char*>().Build();
            const auto structBuilder = builder.Struct(FieldsCount);
            structBuilder->AddField("ParseError", optionalStringType, &urlParseIndexes.ParseError);
            FIELD_MAP(FIELD_ADD)
            builder.Returns(structBuilder->Build());

            if (!typesOnly) {
                builder.Implementation(new TParse(urlParseIndexes));
            }
            return true;
        } else {
            return false;
        }
    }
}