94 lines
3.2 KiB
C++
94 lines
3.2 KiB
C++
// Tests for fn_ui::sql_parse / sql_classify (cpp/functions/core/sql_parse).
|
|
// Pura: tokeniza SQL multi-statement saltando strings y comentarios, y
|
|
// clasifica por keyword inicial.
|
|
|
|
#define CATCH_CONFIG_MAIN
|
|
#include "catch_amalgamated.hpp"
|
|
|
|
#include "core/sql_parse.h"
|
|
|
|
using fn_ui::sql_parse;
|
|
using fn_ui::sql_classify;
|
|
using fn_ui::SqlStmtKind;
|
|
|
|
TEST_CASE("sql_parse classifies common statements") {
|
|
auto stmts = sql_parse("SELECT * FROM t; INSERT INTO t VALUES (1);");
|
|
REQUIRE(stmts.size() == 2);
|
|
REQUIRE(stmts[0].kind == SqlStmtKind::Select);
|
|
REQUIRE(stmts[1].kind == SqlStmtKind::Insert);
|
|
}
|
|
|
|
TEST_CASE("sql_parse handles strings and comments") {
|
|
auto stmts = sql_parse("-- comment\nSELECT 'a;b' FROM t; /* x */ DELETE FROM t;");
|
|
REQUIRE(stmts.size() == 2);
|
|
REQUIRE(stmts[0].kind == SqlStmtKind::Select);
|
|
REQUIRE(stmts[1].kind == SqlStmtKind::Delete);
|
|
}
|
|
|
|
TEST_CASE("sql_parse trims and ignores empty") {
|
|
auto stmts = sql_parse("; ; SELECT 1;;");
|
|
REQUIRE(stmts.size() == 1);
|
|
REQUIRE(stmts[0].kind == SqlStmtKind::Select);
|
|
}
|
|
|
|
TEST_CASE("sql_parse: ddl and dcl keywords") {
|
|
auto stmts = sql_parse("CREATE TABLE t(a); DROP TABLE t; ALTER TABLE t ADD b; UPDATE t SET a=1;");
|
|
REQUIRE(stmts.size() == 4);
|
|
REQUIRE(stmts[0].kind == SqlStmtKind::Create);
|
|
REQUIRE(stmts[1].kind == SqlStmtKind::Drop);
|
|
REQUIRE(stmts[2].kind == SqlStmtKind::Alter);
|
|
REQUIRE(stmts[3].kind == SqlStmtKind::Update);
|
|
}
|
|
|
|
TEST_CASE("sql_parse: pragma and explain") {
|
|
auto stmts = sql_parse("PRAGMA foreign_keys = ON; EXPLAIN SELECT 1;");
|
|
REQUIRE(stmts.size() == 2);
|
|
REQUIRE(stmts[0].kind == SqlStmtKind::Pragma);
|
|
REQUIRE(stmts[1].kind == SqlStmtKind::Explain);
|
|
}
|
|
|
|
TEST_CASE("sql_parse: WITH clasifica como Select") {
|
|
auto stmts = sql_parse("WITH x AS (SELECT 1) SELECT * FROM x;");
|
|
REQUIRE(stmts.size() == 1);
|
|
REQUIRE(stmts[0].kind == SqlStmtKind::Select);
|
|
}
|
|
|
|
TEST_CASE("sql_parse: case-insensitive y trim") {
|
|
auto stmts = sql_parse(" select 1;\n INSERT INTO t VALUES (2);");
|
|
REQUIRE(stmts.size() == 2);
|
|
REQUIRE(stmts[0].kind == SqlStmtKind::Select);
|
|
REQUIRE(stmts[1].kind == SqlStmtKind::Insert);
|
|
}
|
|
|
|
TEST_CASE("sql_parse: line tracking") {
|
|
auto stmts = sql_parse("\n\nSELECT 1;\n-- skip\nDELETE FROM t;\n");
|
|
REQUIRE(stmts.size() == 2);
|
|
REQUIRE(stmts[0].line == 3);
|
|
REQUIRE(stmts[1].line == 5);
|
|
}
|
|
|
|
TEST_CASE("sql_parse: ultimo statement sin ;") {
|
|
auto stmts = sql_parse("SELECT 1");
|
|
REQUIRE(stmts.size() == 1);
|
|
REQUIRE(stmts[0].kind == SqlStmtKind::Select);
|
|
}
|
|
|
|
TEST_CASE("sql_classify: standalone") {
|
|
REQUIRE(sql_classify("SELECT 1") == SqlStmtKind::Select);
|
|
REQUIRE(sql_classify("garbage") == SqlStmtKind::Unknown);
|
|
REQUIRE(sql_classify("") == SqlStmtKind::Unknown);
|
|
REQUIRE(sql_classify("/* c */ DELETE FROM t") == SqlStmtKind::Delete);
|
|
}
|
|
|
|
TEST_CASE("sql_parse: ; dentro de string no separa") {
|
|
auto stmts = sql_parse("SELECT 'a;b;c' FROM t;");
|
|
REQUIRE(stmts.size() == 1);
|
|
REQUIRE(stmts[0].kind == SqlStmtKind::Select);
|
|
}
|
|
|
|
TEST_CASE("sql_parse: backtick identifier") {
|
|
auto stmts = sql_parse("SELECT * FROM `weird;name`;");
|
|
REQUIRE(stmts.size() == 1);
|
|
REQUIRE(stmts[0].kind == SqlStmtKind::Select);
|
|
}
|