diff --git a/sqlparser/CHANGELOG.md b/sqlparser/CHANGELOG.md index 2be0cefa..5fb51790 100644 --- a/sqlparser/CHANGELOG.md +++ b/sqlparser/CHANGELOG.md @@ -5,6 +5,7 @@ to `enabledExtensions` instead. - Parse `rowid` as a valid reference when needed (`SELECT rowid FROM tbl` is now parsed correctly) - Parse `CURRENT_TIME`, `CURRENT_DATE` and `CURRENT_TIMESTAMP` +- Parse `UPSERT` clauses for insert statements ## 0.6.0 diff --git a/sqlparser/lib/src/analysis/types2/resolving_visitor.dart b/sqlparser/lib/src/analysis/types2/resolving_visitor.dart index 54990a51..0bf74a6d 100644 --- a/sqlparser/lib/src/analysis/types2/resolving_visitor.dart +++ b/sqlparser/lib/src/analysis/types2/resolving_visitor.dart @@ -85,6 +85,8 @@ class TypeResolver extends RecursiveVisitor { } }, ); + + visitNullable(e.upsert, const NoTypeExpectation()); } @override @@ -540,6 +542,18 @@ class TypeResolver extends RecursiveVisitor { return visited; } + @override + void visitUpsertClause(UpsertClause e, TypeExpectation arg) { + _handleWhereClause(e); + visitExcept(e, e.where, arg); + } + + @override + void visitDoUpdate(DoUpdate e, TypeExpectation arg) { + _handleWhereClause(e); + visitExcept(e, e.where, arg); + } + void _handleColumn(Column column) { if (session.graph.knowsType(column)) return; @@ -561,12 +575,12 @@ class TypeResolver extends RecursiveVisitor { } } - void _handleWhereClause(StatementWithWhere stmt) { - if (stmt.where != null) { + void _handleWhereClause(HasWhereClause e) { + if (e.where != null) { // assume that a where statement is a boolean expression. Sqlite // internally casts (https://www.sqlite.org/lang_expr.html#booleanexpr), // so be lax - visit(stmt.where, const ExactTypeExpectation.laxly(ResolvedType.bool())); + visit(e.where, const ExactTypeExpectation.laxly(ResolvedType.bool())); } } diff --git a/sqlparser/test/analysis/types2/misc_cases_test.dart b/sqlparser/test/analysis/types2/misc_cases_test.dart index f9b08297..f8afc5e5 100644 --- a/sqlparser/test/analysis/types2/misc_cases_test.dart +++ b/sqlparser/test/analysis/types2/misc_cases_test.dart @@ -30,6 +30,10 @@ const Map _types = { 'SELECT (3 * 4) = ?': ResolvedType(type: BasicType.int), 'SELECT (3 / 4) = ?': ResolvedType(type: BasicType.int), 'SELECT CURRENT_TIMESTAMP = ?': ResolvedType(type: BasicType.text), + 'INSERT INTO demo DEFAULT VALUES ON CONFLICT (id) WHERE ? DO NOTHING': + ResolvedType.bool(), + 'INSERT INTO demo DEFAULT VALUES ON CONFLICT DO UPDATE SET id = id WHERE ?': + ResolvedType.bool(), }; SqlEngine _spawnEngine() {