|
15 | 15 | */ |
16 | 16 |
|
17 | 17 | #include "codegen/cast_expr_ir_builder.h" |
| 18 | + |
18 | 19 | #include "codegen/date_ir_builder.h" |
19 | 20 | #include "codegen/ir_base_builder.h" |
20 | 21 | #include "codegen/string_ir_builder.h" |
21 | 22 | #include "codegen/timestamp_ir_builder.h" |
| 23 | +#include "codegen/type_ir_builder.h" |
22 | 24 | #include "glog/logging.h" |
23 | 25 | #include "node/node_manager.h" |
| 26 | +#include "proto/fe_common.pb.h" |
24 | 27 |
|
25 | 28 | using hybridse::common::kCodegenError; |
26 | 29 |
|
@@ -72,98 +75,73 @@ Status CastExprIRBuilder::Cast(const NativeValue& value, |
72 | 75 | } |
73 | 76 | return Status::OK(); |
74 | 77 | } |
75 | | -Status CastExprIRBuilder::SafeCast(const NativeValue& value, ::llvm::Type* type, |
76 | | - NativeValue* output) { |
| 78 | + |
| 79 | +Status CastExprIRBuilder::SafeCast(const NativeValue& value, ::llvm::Type* dst_type, NativeValue* output) { |
77 | 80 | ::llvm::IRBuilder<> builder(block_); |
78 | | - CHECK_TRUE(IsSafeCast(value.GetType(), type), kCodegenError, |
79 | | - "Safe cast fail: unsafe cast"); |
| 81 | + CHECK_TRUE(IsSafeCast(value.GetType(), dst_type), kCodegenError, "Safe cast fail: unsafe cast"); |
80 | 82 | Status status; |
81 | 83 | if (value.IsConstNull()) { |
82 | | - if (TypeIRBuilder::IsStringPtr(type)) { |
83 | | - StringIRBuilder string_ir_builder(block_->getModule()); |
84 | | - CHECK_STATUS(string_ir_builder.CreateNull(block_, output)); |
85 | | - return base::Status::OK(); |
86 | | - } else { |
87 | | - *output = NativeValue::CreateNull(type); |
88 | | - } |
89 | | - } else if (TypeIRBuilder::IsTimestampPtr(type)) { |
| 84 | + auto res = CreateSafeNull(block_, dst_type); |
| 85 | + CHECK_TRUE(res.ok(), kCodegenError, res.status().ToString()); |
| 86 | + *output = res.value(); |
| 87 | + } else if (TypeIRBuilder::IsTimestampPtr(dst_type)) { |
90 | 88 | TimestampIRBuilder timestamp_ir_builder(block_->getModule()); |
91 | 89 | CHECK_STATUS(timestamp_ir_builder.CastFrom(block_, value, output)); |
92 | 90 | return Status::OK(); |
93 | | - } else if (TypeIRBuilder::IsDatePtr(type)) { |
| 91 | + } else if (TypeIRBuilder::IsDatePtr(dst_type)) { |
94 | 92 | DateIRBuilder date_ir_builder(block_->getModule()); |
95 | 93 | CHECK_STATUS(date_ir_builder.CastFrom(block_, value, output)); |
96 | 94 | return Status::OK(); |
97 | | - } else if (TypeIRBuilder::IsStringPtr(type)) { |
| 95 | + } else if (TypeIRBuilder::IsStringPtr(dst_type)) { |
98 | 96 | StringIRBuilder string_ir_builder(block_->getModule()); |
99 | 97 | CHECK_STATUS(string_ir_builder.CastFrom(block_, value, output)); |
100 | 98 | return Status::OK(); |
101 | | - } else if (TypeIRBuilder::IsNumber(type)) { |
| 99 | + } else if (TypeIRBuilder::IsNumber(dst_type)) { |
102 | 100 | Status status; |
103 | 101 | ::llvm::Value* output_value = nullptr; |
104 | | - CHECK_TRUE(SafeCastNumber(value.GetValue(&builder), type, &output_value, |
105 | | - status), |
106 | | - kCodegenError); |
| 102 | + CHECK_TRUE(SafeCastNumber(value.GetValue(&builder), dst_type, &output_value, status), kCodegenError); |
107 | 103 | if (value.IsNullable()) { |
108 | | - *output = NativeValue::CreateWithFlag(output_value, |
109 | | - value.GetIsNull(&builder)); |
| 104 | + *output = NativeValue::CreateWithFlag(output_value, value.GetIsNull(&builder)); |
110 | 105 | } else { |
111 | 106 | *output = NativeValue::Create(output_value); |
112 | 107 | } |
113 | 108 | } else { |
114 | | - return Status(common::kCodegenError, |
115 | | - "Can't cast from " + |
116 | | - TypeIRBuilder::TypeName(value.GetType()) + " to " + |
117 | | - TypeIRBuilder::TypeName(type)); |
| 109 | + return Status(common::kCodegenError, "Can't cast from " + TypeIRBuilder::TypeName(value.GetType()) + " to " + |
| 110 | + TypeIRBuilder::TypeName(dst_type)); |
118 | 111 | } |
119 | 112 | return Status::OK(); |
120 | 113 | } |
121 | | -Status CastExprIRBuilder::UnSafeCast(const NativeValue& value, |
122 | | - ::llvm::Type* type, NativeValue* output) { |
123 | | - ::llvm::IRBuilder<> builder(block_); |
124 | | - if (value.IsConstNull()) { |
125 | | - if (TypeIRBuilder::IsStringPtr(type)) { |
126 | | - StringIRBuilder string_ir_builder(block_->getModule()); |
127 | | - CHECK_STATUS(string_ir_builder.CreateNull(block_, output)); |
128 | | - return base::Status::OK(); |
129 | 114 |
|
130 | | - } else if (TypeIRBuilder::IsDatePtr(type)) { |
131 | | - DateIRBuilder date_ir(block_->getModule()); |
132 | | - CHECK_STATUS(date_ir.CreateNull(block_, output)); |
133 | | - return base::Status::OK(); |
134 | | - } else { |
135 | | - *output = NativeValue::CreateNull(type); |
136 | | - } |
137 | | - } else if (TypeIRBuilder::IsTimestampPtr(type)) { |
| 115 | +Status CastExprIRBuilder::UnSafeCast(const NativeValue& value, ::llvm::Type* dst_type, NativeValue* output) { |
| 116 | + ::llvm::IRBuilder<> builder(block_); |
| 117 | + if (value.IsConstNull() || (TypeIRBuilder::IsNumber(dst_type) && TypeIRBuilder::IsDatePtr(value.GetType()))) { |
| 118 | + // input is const null or (cast date to number) |
| 119 | + auto res = CreateSafeNull(block_, dst_type); |
| 120 | + CHECK_TRUE(res.ok(), kCodegenError, res.status().ToString()); |
| 121 | + *output = res.value(); |
| 122 | + } else if (TypeIRBuilder::IsTimestampPtr(dst_type)) { |
138 | 123 | TimestampIRBuilder timestamp_ir_builder(block_->getModule()); |
139 | 124 | CHECK_STATUS(timestamp_ir_builder.CastFrom(block_, value, output)); |
140 | 125 | return Status::OK(); |
141 | | - } else if (TypeIRBuilder::IsDatePtr(type)) { |
| 126 | + } else if (TypeIRBuilder::IsDatePtr(dst_type)) { |
142 | 127 | DateIRBuilder date_ir_builder(block_->getModule()); |
143 | 128 | CHECK_STATUS(date_ir_builder.CastFrom(block_, value, output)); |
144 | 129 | return Status::OK(); |
145 | | - } else if (TypeIRBuilder::IsStringPtr(type)) { |
| 130 | + } else if (TypeIRBuilder::IsStringPtr(dst_type)) { |
146 | 131 | StringIRBuilder string_ir_builder(block_->getModule()); |
147 | 132 | CHECK_STATUS(string_ir_builder.CastFrom(block_, value, output)); |
148 | 133 | return Status::OK(); |
149 | | - } else if (TypeIRBuilder::IsNumber(type) && |
150 | | - TypeIRBuilder::IsStringPtr(value.GetType())) { |
| 134 | + } else if (TypeIRBuilder::IsNumber(dst_type) && TypeIRBuilder::IsStringPtr(value.GetType())) { |
151 | 135 | StringIRBuilder string_ir_builder(block_->getModule()); |
152 | | - CHECK_STATUS( |
153 | | - string_ir_builder.CastToNumber(block_, value, type, output)); |
| 136 | + CHECK_STATUS(string_ir_builder.CastToNumber(block_, value, dst_type, output)); |
154 | 137 | return Status::OK(); |
155 | | - } else if (TypeIRBuilder::IsNumber(type) && |
156 | | - TypeIRBuilder::IsDatePtr(value.GetType())) { |
157 | | - *output = NativeValue::CreateNull(type); |
158 | 138 | } else { |
159 | 139 | Status status; |
160 | 140 | ::llvm::Value* output_value = nullptr; |
161 | | - CHECK_TRUE(UnSafeCastNumber(value.GetValue(&builder), type, |
162 | | - &output_value, status), |
163 | | - kCodegenError, status.msg); |
| 141 | + CHECK_TRUE(UnSafeCastNumber(value.GetValue(&builder), dst_type, &output_value, status), kCodegenError, |
| 142 | + status.msg); |
164 | 143 | if (value.IsNullable()) { |
165 | | - *output = NativeValue::CreateWithFlag(output_value, |
166 | | - value.GetIsNull(&builder)); |
| 144 | + *output = NativeValue::CreateWithFlag(output_value, value.GetIsNull(&builder)); |
167 | 145 | } else { |
168 | 146 | *output = NativeValue::Create(output_value); |
169 | 147 | } |
|
0 commit comments