Merge pull request #156 from ankushrayabhari/segfault
Fix segfault on printing cast/extract exprs
This commit is contained in:
commit
21e7eb5f18
|
@ -218,7 +218,7 @@ Expr* Expr::makeInOperator(Expr* expr, SelectStatement* select) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr* Expr::makeExtract(DatetimeField datetimeField, Expr* expr) {
|
Expr* Expr::makeExtract(DatetimeField datetimeField, Expr* expr) {
|
||||||
Expr* e = new Expr(kExprFunctionRef);
|
Expr* e = new Expr(kExprExtract);
|
||||||
e->name = strdup("EXTRACT");
|
e->name = strdup("EXTRACT");
|
||||||
e->datetimeField = datetimeField;
|
e->datetimeField = datetimeField;
|
||||||
e->expr = expr;
|
e->expr = expr;
|
||||||
|
@ -226,7 +226,7 @@ Expr* Expr::makeExtract(DatetimeField datetimeField, Expr* expr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr* Expr::makeCast(Expr* expr, ColumnType columnType) {
|
Expr* Expr::makeCast(Expr* expr, ColumnType columnType) {
|
||||||
Expr* e = new Expr(kExprFunctionRef);
|
Expr* e = new Expr(kExprCast);
|
||||||
e->name = strdup("CAST");
|
e->name = strdup("CAST");
|
||||||
e->columnType = columnType;
|
e->columnType = columnType;
|
||||||
e->expr = expr;
|
e->expr = expr;
|
||||||
|
|
|
@ -27,7 +27,8 @@ enum ExprType {
|
||||||
kExprHint,
|
kExprHint,
|
||||||
kExprArray,
|
kExprArray,
|
||||||
kExprArrayIndex,
|
kExprArrayIndex,
|
||||||
kExprDatetimeField
|
kExprExtract,
|
||||||
|
kExprCast
|
||||||
};
|
};
|
||||||
|
|
||||||
// Operator types. These are important for expressions of type kExprOperator.
|
// Operator types. These are important for expressions of type kExprOperator.
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace hsql {
|
||||||
void printAlias(Alias* alias, uintmax_t numIndent);
|
void printAlias(Alias* alias, uintmax_t numIndent);
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const OperatorType& op);
|
std::ostream& operator<<(std::ostream& os, const OperatorType& op);
|
||||||
|
std::ostream& operator<<(std::ostream& os, const DatetimeField& op);
|
||||||
|
|
||||||
std::string indent(uintmax_t numIndent) {
|
std::string indent(uintmax_t numIndent) {
|
||||||
return std::string(numIndent, '\t');
|
return std::string(numIndent, '\t');
|
||||||
|
@ -32,6 +33,12 @@ namespace hsql {
|
||||||
void inprint(const OperatorType& op, uintmax_t numIndent) {
|
void inprint(const OperatorType& op, uintmax_t numIndent) {
|
||||||
std::cout << indent(numIndent) << op << std::endl;
|
std::cout << indent(numIndent) << op << std::endl;
|
||||||
}
|
}
|
||||||
|
void inprint(const ColumnType& colType, uintmax_t numIndent) {
|
||||||
|
std::cout << indent(numIndent) << colType << std::endl;
|
||||||
|
}
|
||||||
|
void inprint(const DatetimeField& colType, uintmax_t numIndent) {
|
||||||
|
std::cout << indent(numIndent) << colType << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
void printTableRefInfo(TableRef* table, uintmax_t numIndent) {
|
void printTableRefInfo(TableRef* table, uintmax_t numIndent) {
|
||||||
switch (table->type) {
|
switch (table->type) {
|
||||||
|
@ -118,6 +125,16 @@ namespace hsql {
|
||||||
inprint(expr->name, numIndent);
|
inprint(expr->name, numIndent);
|
||||||
for (Expr* e : *expr->exprList) printExpression(e, numIndent + 1);
|
for (Expr* e : *expr->exprList) printExpression(e, numIndent + 1);
|
||||||
break;
|
break;
|
||||||
|
case kExprExtract:
|
||||||
|
inprint(expr->name, numIndent);
|
||||||
|
inprint(expr->datetimeField, numIndent + 1);
|
||||||
|
printExpression(expr->expr, numIndent + 1);
|
||||||
|
break;
|
||||||
|
case kExprCast:
|
||||||
|
inprint(expr->name, numIndent);
|
||||||
|
inprint(expr->columnType, numIndent + 1);
|
||||||
|
printExpression(expr->expr, numIndent + 1);
|
||||||
|
break;
|
||||||
case kExprOperator:
|
case kExprOperator:
|
||||||
printOperatorExpression(expr, numIndent);
|
printOperatorExpression(expr, numIndent);
|
||||||
break;
|
break;
|
||||||
|
@ -372,4 +389,23 @@ namespace hsql {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const DatetimeField& datetime) {
|
||||||
|
static const std::map<const DatetimeField, const std::string> operatorToToken = {
|
||||||
|
{kDatetimeNone, "None"},
|
||||||
|
{kDatetimeSecond, "SECOND"},
|
||||||
|
{kDatetimeMinute, "MINUTE"},
|
||||||
|
{kDatetimeHour, "HOUR"},
|
||||||
|
{kDatetimeDay, "DAY"},
|
||||||
|
{kDatetimeMonth, "MONTH"},
|
||||||
|
{kDatetimeYear, "YEAR"}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto found = operatorToToken.find(datetime);
|
||||||
|
if (found == operatorToToken.cend()) {
|
||||||
|
return os << static_cast<uint64_t>(datetime);
|
||||||
|
} else {
|
||||||
|
return os << (*found).second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace hsql
|
} // namespace hsql
|
||||||
|
|
|
@ -638,7 +638,7 @@ TEST(Extract) {
|
||||||
stmt = (SelectStatement*) result.getStatement(0);
|
stmt = (SelectStatement*) result.getStatement(0);
|
||||||
ASSERT_TRUE(stmt->selectList);
|
ASSERT_TRUE(stmt->selectList);
|
||||||
ASSERT_EQ(stmt->selectList->size(), 1u);
|
ASSERT_EQ(stmt->selectList->size(), 1u);
|
||||||
ASSERT_EQ(stmt->selectList->at(0)->type, kExprFunctionRef);
|
ASSERT_EQ(stmt->selectList->at(0)->type, kExprExtract);
|
||||||
ASSERT_EQ(stmt->selectList->at(0)->name, std::string("EXTRACT"));
|
ASSERT_EQ(stmt->selectList->at(0)->name, std::string("EXTRACT"));
|
||||||
ASSERT_EQ(stmt->selectList->at(0)->datetimeField, kDatetimeYear);
|
ASSERT_EQ(stmt->selectList->at(0)->datetimeField, kDatetimeYear);
|
||||||
ASSERT_TRUE(stmt->selectList->at(0)->expr);
|
ASSERT_TRUE(stmt->selectList->at(0)->expr);
|
||||||
|
@ -647,7 +647,7 @@ TEST(Extract) {
|
||||||
stmt = (SelectStatement*) result.getStatement(1);
|
stmt = (SelectStatement*) result.getStatement(1);
|
||||||
ASSERT_TRUE(stmt->selectList);
|
ASSERT_TRUE(stmt->selectList);
|
||||||
ASSERT_EQ(stmt->selectList->size(), 2u);
|
ASSERT_EQ(stmt->selectList->size(), 2u);
|
||||||
ASSERT_EQ(stmt->selectList->at(1)->type, kExprFunctionRef);
|
ASSERT_EQ(stmt->selectList->at(1)->type, kExprExtract);
|
||||||
ASSERT_EQ(stmt->selectList->at(1)->name, std::string("EXTRACT"));
|
ASSERT_EQ(stmt->selectList->at(1)->name, std::string("EXTRACT"));
|
||||||
ASSERT_EQ(stmt->selectList->at(1)->datetimeField, kDatetimeMonth);
|
ASSERT_EQ(stmt->selectList->at(1)->datetimeField, kDatetimeMonth);
|
||||||
ASSERT_TRUE(stmt->selectList->at(1)->expr);
|
ASSERT_TRUE(stmt->selectList->at(1)->expr);
|
||||||
|
@ -658,11 +658,31 @@ TEST(Extract) {
|
||||||
stmt = (SelectStatement*) result.getStatement(2);
|
stmt = (SelectStatement*) result.getStatement(2);
|
||||||
ASSERT_TRUE(stmt->whereClause);
|
ASSERT_TRUE(stmt->whereClause);
|
||||||
ASSERT_TRUE(stmt->whereClause->expr);
|
ASSERT_TRUE(stmt->whereClause->expr);
|
||||||
ASSERT_EQ(stmt->whereClause->expr->type, kExprFunctionRef);
|
ASSERT_EQ(stmt->whereClause->expr->type, kExprExtract);
|
||||||
ASSERT_EQ(stmt->whereClause->expr->name, std::string("EXTRACT"));
|
ASSERT_EQ(stmt->whereClause->expr->name, std::string("EXTRACT"));
|
||||||
ASSERT_EQ(stmt->whereClause->expr->datetimeField, kDatetimeMinute);
|
ASSERT_EQ(stmt->whereClause->expr->datetimeField, kDatetimeMinute);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(CastExpression) {
|
||||||
|
TEST_PARSE_SINGLE_SQL(
|
||||||
|
"SELECT CAST(10 AS INT);",
|
||||||
|
kStmtSelect,
|
||||||
|
SelectStatement,
|
||||||
|
result,
|
||||||
|
stmt);
|
||||||
|
|
||||||
|
ASSERT_TRUE(stmt->selectList);
|
||||||
|
ASSERT_FALSE(stmt->fromTable);
|
||||||
|
ASSERT_FALSE(stmt->whereClause);
|
||||||
|
ASSERT_FALSE(stmt->groupBy);
|
||||||
|
|
||||||
|
ASSERT_EQ(stmt->selectList->size(), 1u);
|
||||||
|
ASSERT_EQ(stmt->selectList->at(0)->type, kExprCast);
|
||||||
|
ASSERT_EQ(stmt->selectList->at(0)->name, std::string("CAST"));
|
||||||
|
ASSERT_EQ(stmt->selectList->at(0)->columnType, ColumnType(DataType::INT));
|
||||||
|
ASSERT_EQ(stmt->selectList->at(0)->expr->type, kExprLiteralInt);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(NoFromClause) {
|
TEST(NoFromClause) {
|
||||||
TEST_PARSE_SINGLE_SQL(
|
TEST_PARSE_SINGLE_SQL(
|
||||||
"SELECT 1 + 2;",
|
"SELECT 1 + 2;",
|
||||||
|
|
Loading…
Reference in New Issue