1#include "duckdb/parser/expression/constant_expression.hpp"
2#include "duckdb/parser/transformer.hpp"
3#include "duckdb/common/operator/cast_operators.hpp"
4
5using namespace duckdb;
6using namespace std;
7
8unique_ptr<ParsedExpression> Transformer::TransformValue(PGValue val) {
9 switch (val.type) {
10 case T_PGInteger:
11 assert(val.val.ival <= numeric_limits<int32_t>::max());
12 return make_unique<ConstantExpression>(SQLType::INTEGER, Value::INTEGER((int32_t)val.val.ival));
13 case T_PGBitString: // FIXME: this should actually convert to BLOB
14 case T_PGString:
15 return make_unique<ConstantExpression>(SQLType::VARCHAR, Value(string(val.val.str)));
16 case T_PGFloat: {
17 bool cast_as_double = false;
18 for (auto ptr = val.val.str; *ptr; ptr++) {
19 if (*ptr == '.') {
20 // found decimal point, cast as double
21 cast_as_double = true;
22 break;
23 }
24 }
25 int64_t value;
26 if (!cast_as_double && TryCast::Operation<string_t, int64_t>(string_t(val.val.str), value)) {
27 // successfully cast to bigint: bigint value
28 return make_unique<ConstantExpression>(SQLType::BIGINT, Value::BIGINT(value));
29 } else {
30 // could not cast to bigint: cast to double
31 double dbl_value = Cast::Operation<string_t, double>(string_t(val.val.str));
32 if (!Value::DoubleIsValid(dbl_value)) {
33 throw ParserException("Double value \"%s\" is out of range!", val.val.str);
34 }
35 return make_unique<ConstantExpression>(SQLType::DOUBLE, Value::DOUBLE(dbl_value));
36 }
37 }
38 case T_PGNull:
39 return make_unique<ConstantExpression>(SQLType::SQLNULL, Value());
40 default:
41 throw NotImplementedException("Value not implemented!");
42 }
43}
44
45unique_ptr<ParsedExpression> Transformer::TransformConstant(PGAConst *c) {
46 return TransformValue(c->val);
47}
48