forked from greenplum-db/gpdb-archive
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pg_date_func_generator.cc
98 lines (81 loc) · 2.84 KB
/
pg_date_func_generator.cc
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2016 Pivotal Software, Inc.
//
// @filename:
// pg_date_func_generator.cc
//
// @doc:
// Base class for date functions to generate code
//
//---------------------------------------------------------------------------
#include <assert.h>
#include <cstdint>
#include <memory>
#include <vector>
#include "codegen/pg_arith_func_generator.h"
#include "codegen/pg_date_func_generator.h"
#include "codegen/pg_func_generator_interface.h"
#include "codegen/utils/gp_codegen_utils.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Value.h"
extern "C" {
#include "postgres.h" // NOLINT(build/include)
#include "c.h" // NOLINT(build/include)
#include "utils/timestamp.h"
}
using gpcodegen::GpCodegenUtils;
using gpcodegen::PGDateFuncGenerator;
using gpcodegen::PGFuncGeneratorInfo;
bool PGDateFuncGenerator::DateLETimestamp(
gpcodegen::GpCodegenUtils* codegen_utils,
const PGFuncGeneratorInfo& pg_func_info,
llvm::Value** llvm_out_value) {
llvm::IRBuilder<>* irb = codegen_utils->ir_builder();
// llvm_args[0] is of date type
llvm::Value* llvm_arg0_Timestamp = GenerateDate2Timestamp(
codegen_utils, pg_func_info);
// timestamp_cmp_internal {{{
#ifdef HAVE_INT64_TIMESTAMP
*llvm_out_value =
irb->CreateICmpSLE(llvm_arg0_Timestamp, pg_func_info.llvm_args[1]);
#else
// TODO(nikos): We do not support NaNs.
elog(DEBUG1, "Timestamp != int_64: NaNs are not supported.");
return false;
#endif
// }}}
return true;
}
llvm::Value* PGDateFuncGenerator::GenerateDate2Timestamp(
GpCodegenUtils* codegen_utils,
const PGFuncGeneratorInfo& pg_func_info) {
assert(pg_func_info.llvm_args.size() > 1);
assert(nullptr != pg_func_info.llvm_args[0]);
assert(nullptr != pg_func_info.llvm_args[0]->getType());
#ifdef HAVE_INT64_TIMESTAMP
llvm::Value *llvm_USECS_PER_DAY = codegen_utils->
GetConstant<int64_t>(USECS_PER_DAY);
llvm::Value* llvm_out_value = nullptr;
llvm::Value* llvm_err_msg = codegen_utils->GetConstant(
"date out of range for timestamp");
PGFuncGeneratorInfo pg_timestamp_func_info(
pg_func_info.llvm_main_func,
pg_func_info.llvm_error_block,
{pg_func_info.llvm_args[0], llvm_USECS_PER_DAY});
PGArithFuncGenerator<int64_t, int32_t, int64_t>::ArithOpWithOverflow(
codegen_utils,
&gpcodegen::GpCodegenUtils::CreateMulOverflow<int64_t>,
llvm_err_msg,
pg_timestamp_func_info,
&llvm_out_value);
return llvm_out_value;
#else
llvm::Value* llvm_arg_64 = codegen_utils->CreateCast<int64_t, int32_t>(
pg_func_info.llvm_args[0]);
llvm::Value *llvm_SECS_PER_DAY = codegen_utils->
GetConstant<int64_t>(SECS_PER_DAY);
return codegen_utils->ir_builder()->CreateMul(llvm_arg_64, llvm_SECS_PER_DAY);
#endif
}