| 771 | return FuncRet(); |
| 772 | } |
| 773 | FuncRet arithmeticFunc(DB::ASTPtr ch, std::map<std::string, Column> & columns) |
| 774 | { |
| 775 | auto x = std::dynamic_pointer_cast<DB::ASTFunction>(ch); |
| 776 | if (x) |
| 777 | { |
| 778 | std::set<std::string> indents = {}; |
| 779 | std::set<std::string> values = {}; |
| 780 | ColumnType type_value = Type::i | Type::f | Type::d | Type::dt; |
| 781 | ColumnType args_types = 0; |
| 782 | bool no_indent = true; |
| 783 | for (auto & arg : x->arguments->children) |
| 784 | { |
| 785 | ColumnType type = 0; |
| 786 | auto ident = std::dynamic_pointer_cast<DB::ASTIdentifier>(arg); |
| 787 | if (ident) |
| 788 | { |
| 789 | no_indent = false; |
| 790 | indents.insert(ident->name()); |
| 791 | } |
| 792 | auto literal = std::dynamic_pointer_cast<DB::ASTLiteral>(arg); |
| 793 | if (literal) |
| 794 | type = type_cast(literal->value.getType()); |
| 795 | auto subfunc = std::dynamic_pointer_cast<DB::ASTFunction>(arg); |
| 796 | if (subfunc) |
| 797 | { |
| 798 | FuncHandler f; |
| 799 | auto arg_func_name = std::dynamic_pointer_cast<DB::ASTFunction>(arg)->name; |
| 800 | if (handlers.count(arg_func_name)) |
| 801 | f = handlers[arg_func_name]; |
| 802 | else |
| 803 | f = handlers[""]; |
| 804 | FuncRet ret = f(arg, columns); |
| 805 | type = ret.type; |
| 806 | } |
| 807 | args_types |= type; |
| 808 | } |
| 809 | if (args_types & (Type::d | Type::dt)) |
| 810 | type_value -= Type::f; |
| 811 | if (args_types & Type::f) |
| 812 | type_value -= Type::d | Type::dt; |
| 813 | for (const auto & indent : indents) |
| 814 | { |
| 815 | auto c = Column(indent); |
| 816 | c.type = type_value; |
| 817 | if (columns.count(indent)) |
| 818 | columns[indent].merge(c); |
| 819 | else |
| 820 | columns[indent] = c; |
| 821 | } |
| 822 | ColumnType ret_type = 0; |
| 823 | if (args_types & Type::dt) |
| 824 | ret_type = Type::dt; |
| 825 | else if (args_types & Type::d) |
| 826 | ret_type = Type::d | Type::dt; |
| 827 | else if (args_types & Type::f) |
| 828 | ret_type = Type::f; |
| 829 | else |
| 830 | ret_type = Type::d | Type::f | Type::dt | Type::i; |