Skip to content

Commit 6fe2a30

Browse files
authored
fix(codegen): handle nullable for date type (#3543)
* fix(codegen): handle nullable for date type Also fix include headers * fix(codegen): handle nulls for date and timestamp always returns allocated structure even it is null, for the cases: 1. construct timestamp from number, even number is < 0 2. construct date from timestamp, even timestamp is null
1 parent 190992d commit 6fe2a30

18 files changed

+76
-83
lines changed

cases/query/const_query.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,15 @@ cases:
126126
columns: ['c1 bool', 'c2 int16', 'c3 int', 'c4 double', 'c5 string', 'c6 date', 'c7 timestamp' ]
127127
rows:
128128
- [ true, 3, 13, 10.0, 'a string', '2020-05-22', 1590115420000 ]
129+
- id: 10
130+
mode: procedure-unsupport
131+
sql: |
132+
select
133+
datediff(Date(timestamp(-1)), Date("2021-05-01")) as out1,
134+
datediff(Date(timestamp(-2177481600)), Date("2021-05-01")) as out2,
135+
datediff(cast(NULL as date), Date("2021-05-01")) as out3
136+
;
137+
expect:
138+
columns: ["out1 int", "out2 int", "out3 int"]
139+
data: |
140+
NULL, NULL, NULL

hybridse/src/codegen/array_ir_builder.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "codegen/array_ir_builder.h"
1818

1919
#include <string>
20+
#include "codegen/ir_base_builder.h"
2021

2122
namespace hybridse {
2223
namespace codegen {

hybridse/src/codegen/cast_expr_ir_builder.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@ Status CastExprIRBuilder::UnSafeCast(const NativeValue& value,
126126
StringIRBuilder string_ir_builder(block_->getModule());
127127
CHECK_STATUS(string_ir_builder.CreateNull(block_, output));
128128
return base::Status::OK();
129+
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();
129134
} else {
130135
*output = NativeValue::CreateNull(type);
131136
}

hybridse/src/codegen/date_ir_builder.cc

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <vector>
2020
#include "codegen/arithmetic_expr_ir_builder.h"
2121
#include "codegen/ir_base_builder.h"
22+
#include "codegen/null_ir_builder.h"
2223

2324
namespace hybridse {
2425
namespace codegen {
@@ -43,6 +44,15 @@ void DateIRBuilder::InitStructType() {
4344
struct_type_ = stype;
4445
return;
4546
}
47+
48+
base::Status DateIRBuilder::CreateNull(::llvm::BasicBlock* block, NativeValue* output) {
49+
::llvm::Value* value = nullptr;
50+
CHECK_TRUE(CreateDefault(block, &value), common::kCodegenError, "Fail to construct string")
51+
::llvm::IRBuilder<> builder(block);
52+
*output = NativeValue::CreateWithFlag(value, builder.getInt1(true));
53+
return base::Status::OK();
54+
}
55+
4656
bool DateIRBuilder::CreateDefault(::llvm::BasicBlock* block,
4757
::llvm::Value** output) {
4858
return NewDate(block, output);
@@ -123,11 +133,10 @@ base::Status DateIRBuilder::CastFrom(::llvm::BasicBlock* block,
123133
auto cast_func = m_->getOrInsertFunction(
124134
fn_name,
125135
::llvm::FunctionType::get(builder.getVoidTy(),
126-
{src.GetType(), dist->getType(),
127-
builder.getInt1Ty()->getPointerTo()},
128-
false));
129-
builder.CreateCall(cast_func,
130-
{src.GetValue(&builder), dist, is_null_ptr});
136+
{src.GetType(), dist->getType(), builder.getInt1Ty()->getPointerTo()}, false));
137+
138+
builder.CreateCall(cast_func, {src.GetValue(&builder), dist, is_null_ptr});
139+
131140
::llvm::Value* should_return_null = builder.CreateLoad(is_null_ptr);
132141
null_ir_builder.CheckAnyNull(block, src, &should_return_null);
133142
*output = NativeValue::CreateWithFlag(dist, should_return_null);

hybridse/src/codegen/date_ir_builder.h

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,9 @@
1616

1717
#ifndef HYBRIDSE_SRC_CODEGEN_DATE_IR_BUILDER_H_
1818
#define HYBRIDSE_SRC_CODEGEN_DATE_IR_BUILDER_H_
19+
1920
#include "base/fe_status.h"
20-
#include "codegen/cast_expr_ir_builder.h"
21-
#include "codegen/null_ir_builder.h"
22-
#include "codegen/scope_var.h"
2321
#include "codegen/struct_ir_builder.h"
24-
#include "llvm/IR/IRBuilder.h"
25-
#include "proto/fe_type.pb.h"
2622

2723
namespace hybridse {
2824
namespace codegen {
@@ -31,17 +27,17 @@ class DateIRBuilder : public StructTypeIRBuilder {
3127
public:
3228
explicit DateIRBuilder(::llvm::Module* m);
3329
~DateIRBuilder();
34-
void InitStructType();
35-
bool CreateDefault(::llvm::BasicBlock* block, ::llvm::Value** output);
30+
void InitStructType() override;
31+
32+
base::Status CreateNull(::llvm::BasicBlock* block, NativeValue* output);
33+
bool CreateDefault(::llvm::BasicBlock* block, ::llvm::Value** output) override;
34+
3635
bool NewDate(::llvm::BasicBlock* block, ::llvm::Value** output);
3736
bool NewDate(::llvm::BasicBlock* block, ::llvm::Value* date,
3837
::llvm::Value** output);
39-
bool CopyFrom(::llvm::BasicBlock* block, ::llvm::Value* src,
40-
::llvm::Value* dist);
41-
base::Status CastFrom(::llvm::BasicBlock* block, const NativeValue& src,
42-
NativeValue* output);
43-
base::Status CastFrom(::llvm::BasicBlock* block, ::llvm::Value* src,
44-
::llvm::Value** output);
38+
bool CopyFrom(::llvm::BasicBlock* block, ::llvm::Value* src, ::llvm::Value* dist);
39+
base::Status CastFrom(::llvm::BasicBlock* block, const NativeValue& src, NativeValue* output);
40+
4541
bool GetDate(::llvm::BasicBlock* block, ::llvm::Value* date,
4642
::llvm::Value** output);
4743
bool SetDate(::llvm::BasicBlock* block, ::llvm::Value* date,

hybridse/src/codegen/ir_base_builder.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
#include <string>
2121
#include <vector>
22-
#include "glog/logging.h"
2322
#include "llvm/IR/IRBuilder.h"
2423
#include "node/sql_node.h"
2524
#include "node/type_node.h"

hybridse/src/codegen/native_value.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include "codegen/native_value.h"
1818
#include <dlfcn.h>
1919
#include <execinfo.h>
20-
#include <signal.h>
2120
#include "codegen/context.h"
2221
#include "codegen/ir_base_builder.h"
2322

hybridse/src/codegen/predicate_expr_ir_builder.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "codegen/predicate_expr_ir_builder.h"
1818
#include "codegen/date_ir_builder.h"
1919
#include "codegen/ir_base_builder.h"
20+
#include "codegen/null_ir_builder.h"
2021
#include "codegen/string_ir_builder.h"
2122
#include "codegen/timestamp_ir_builder.h"
2223
#include "codegen/type_ir_builder.h"

hybridse/src/codegen/struct_ir_builder.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@
1616

1717
#ifndef HYBRIDSE_SRC_CODEGEN_STRUCT_IR_BUILDER_H_
1818
#define HYBRIDSE_SRC_CODEGEN_STRUCT_IR_BUILDER_H_
19+
1920
#include "base/fe_status.h"
20-
#include "codegen/cast_expr_ir_builder.h"
21-
#include "codegen/scope_var.h"
21+
#include "codegen/native_value.h"
2222
#include "codegen/type_ir_builder.h"
23-
#include "llvm/IR/IRBuilder.h"
24-
#include "proto/fe_type.pb.h"
2523

2624
namespace hybridse {
2725
namespace codegen {

hybridse/src/codegen/timestamp_ir_builder.cc

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@
1515
*/
1616

1717
#include "codegen/timestamp_ir_builder.h"
18+
1819
#include <string>
1920
#include <vector>
21+
2022
#include "codegen/arithmetic_expr_ir_builder.h"
2123
#include "codegen/ir_base_builder.h"
2224
#include "codegen/null_ir_builder.h"
2325
#include "codegen/predicate_expr_ir_builder.h"
2426
#include "glog/logging.h"
25-
#include "node/sql_node.h"
2627

2728
using hybridse::common::kCodegenError;
2829

@@ -70,29 +71,30 @@ base::Status TimestampIRBuilder::CastFrom(::llvm::BasicBlock* block,
7071
CondSelectIRBuilder cond_ir_builder;
7172
PredicateIRBuilder predicate_ir_builder(block);
7273
NullIRBuilder null_ir_builder;
74+
75+
// always allocate for returned timestmap even it is null
76+
::llvm::Value* dist = nullptr;
77+
if (!CreateDefault(block, &dist)) {
78+
status.code = common::kCodegenError;
79+
status.msg = "Fail to cast date: create default date fail";
80+
return status;
81+
}
82+
7383
if (IsNumber(src.GetType())) {
7484
CHECK_STATUS(cast_builder.Cast(src, builder.getInt64Ty(), &ts));
7585
NativeValue cond;
7686
CHECK_STATUS(predicate_ir_builder.BuildGeExpr(
7787
ts, NativeValue::Create(builder.getInt64(0)), &cond));
78-
::llvm::Value* timestamp;
79-
CHECK_TRUE(NewTimestamp(block, ts.GetValue(&builder), &timestamp),
88+
CHECK_TRUE(SetTs(block, dist, ts.GetValue(&builder)),
8089
kCodegenError,
8190
"Fail to cast timestamp: new timestamp(ts) fail");
82-
CHECK_STATUS(
83-
cond_ir_builder.Select(block, cond, NativeValue::Create(timestamp),
84-
NativeValue::CreateNull(GetType()), output));
91+
CHECK_STATUS(cond_ir_builder.Select(block, cond, NativeValue::Create(dist),
92+
NativeValue::CreateWithFlag(dist, builder.getInt1(true)), output));
8593

8694
} else if (IsStringPtr(src.GetType()) || IsDatePtr(src.GetType())) {
8795
::llvm::IRBuilder<> builder(block);
88-
::llvm::Value* dist = nullptr;
8996
::llvm::Value* is_null_ptr = CreateAllocaAtHead(
9097
&builder, builder.getInt1Ty(), "timestamp_is_null_alloca");
91-
if (!CreateDefault(block, &dist)) {
92-
status.code = common::kCodegenError;
93-
status.msg = "Fail to cast date: create default date fail";
94-
return status;
95-
}
9698
::std::string fn_name = "timestamp." + TypeName(src.GetType());
9799

98100
auto cast_func = m_->getOrInsertFunction(

0 commit comments

Comments
 (0)