hyrise / sql-parser

SQL Parser for C++. Building C++ object structure from SQL statements.
MIT License
733 stars 243 forks source link

Segment fault with example while using |create table statement| #61

Open vivekgalatage opened 7 years ago

vivekgalatage commented 7 years ago

I built the code on Mac and tried executing the example with below statement

./example "CREATE TABLE Persons (PersonID int);"

And this results in a SEGFAULT. So I tried to debug and got the following stack

$ lldb example
(lldb) target create "example"
Current executable set to 'example' (x86_64).
(lldb) r "CREATE TABLE Persons (PersonID int);"
Process 45712 launched: '/Users/user/workspace/sql-parser/example/example' (x86_64)
Parsed successfully!
Number of statements: 1
CreateStatment
    Persons
Process 45712 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    frame #0: 0x00007fffdae6ab52 libsystem_c.dylib`strlen + 18
libsystem_c.dylib`strlen:
->  0x7fffdae6ab52 <+18>: pcmpeqb (%rdi), %xmm0
    0x7fffdae6ab56 <+22>: pmovmskb %xmm0, %esi
    0x7fffdae6ab5a <+26>: andq   $0xf, %rcx
    0x7fffdae6ab5e <+30>: orq    $-0x1, %rax
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x00007fffdae6ab52 libsystem_c.dylib`strlen + 18
    frame #1: 0x0000000100092ccd libsqlparser.so`hsql::inprint(char const*, unsigned long) + 93
    frame #2: 0x0000000100000c19 example`main + 489
    frame #3: 0x00007fffdae34235 libdyld.dylib`start + 1
    frame #4: 0x00007fffdae34235 libdyld.dylib`start + 1
tarqd commented 7 years ago

This turned out to be a problem in the printCreateStatementInfo function in src/util/sqlhelper.cpp. The value of stmt->fileName was null so it errored out.

This modified version adds a null check and a loop to print the column names and types. It's really ugly but I hastily put this together just to try and get this working:

  void printCreateStatementInfo(const CreateStatement* stmt, uintmax_t numIndent) {
    inprint("CreateStatment", numIndent);
    inprint(stmt->tableName, numIndent + 1);
    if (stmt->filePath) {
        inprint(stmt->filePath, numIndent + 1);
    }
    inprint("Columns", numIndent + 1);
    for (hsql::ColumnDefinition* column : *stmt->columns) {
        std::string typeStr{};
        switch (column->type) {
            case hsql::ColumnDefinition::DataType::INT:
                typeStr = "INT";
                break;
            case hsql::ColumnDefinition::DataType::DOUBLE:
                typeStr = "DOUBLE";
                break;
            case hsql::ColumnDefinition::DataType::TEXT:
                typeStr = "INT";
                break;
            default:
                typeStr = "UNKNOWN";
        }
        std::cout << indent(numIndent + 2).c_str() << column->name << " " << typeStr << std::endl;

    }
  }

Results:

./example "CREATE TABLE Persons (PersonID int);"

Parsed successfully!
Number of statements: 1
CreateStatment
    Persons
    Columns
        PersonID INT
cdmh commented 3 years ago

This issue is fixed. The cited example passes with in the current origin/master.

The nullptr check is present in sqlhelper.cpp (300)

  void printCreateStatementInfo(const CreateStatement* stmt, uintmax_t numIndent) {
    inprint("CreateStatement", numIndent);
    inprint(stmt->tableName, numIndent + 1);
    if (stmt->filePath) inprint(stmt->filePath, numIndent + 1);
  }

I think this can be closed now

klauck commented 3 years ago

Thanks for pointing this out. Yes, the nullptr ckeck is fixed. I will add the proposed column definitions and then close this issue.