Skip to content

Commit 743e798

Browse files
committed
Add support for conflict clauses to the grammar parser
Add support for parsing and generating CREATE statements with an ON CONFLICT clause for their primary key.
1 parent 29fa332 commit 743e798

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

src/sqlitetypes.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ class CreateTableWalker
9292

9393
private:
9494
void parsecolumn(Table* table, antlr::RefAST c);
95+
QString parseConflictClause(antlr::RefAST c);
9596

9697
private:
9798
antlr::RefAST m_root;
@@ -219,6 +220,9 @@ QString PrimaryKeyConstraint::toSql(const FieldVector& applyOn) const
219220
result += QString("CONSTRAINT %1 ").arg(escapeIdentifier(m_name));
220221
result += QString("PRIMARY KEY(%1)").arg(fieldVectorToFieldNames(applyOn).join(","));
221222

223+
if(!m_conflictAction.isEmpty())
224+
result += " ON CONFLICT " + m_conflictAction;
225+
222226
return result;
223227
}
224228

@@ -794,6 +798,10 @@ TablePtr CreateTableWalker::table()
794798
}
795799
} while(tc != antlr::nullAST && tc->getType() != sqlite3TokenTypes::RPAREN);
796800

801+
// We're either done now or there is a conflict clause
802+
tc = tc->getNextSibling(); // skip RPAREN
803+
pk->setConflictAction(parseConflictClause(tc));
804+
797805
tab->addConstraint(fields, ConstraintPtr(pk));
798806
}
799807
break;
@@ -1026,6 +1034,9 @@ void CreateTableWalker::parsecolumn(Table* table, antlr::RefAST c)
10261034
table->setFullyParsed(false);
10271035
con = con->getNextSibling(); //skip
10281036
}
1037+
1038+
primaryKey->setConflictAction(parseConflictClause(con));
1039+
10291040
if(con != antlr::nullAST && con->getType() == sqlite3TokenTypes::AUTOINCREMENT)
10301041
autoincrement = true;
10311042
}
@@ -1145,6 +1156,21 @@ void CreateTableWalker::parsecolumn(Table* table, antlr::RefAST c)
11451156
}
11461157
}
11471158

1159+
QString CreateTableWalker::parseConflictClause(antlr::RefAST c)
1160+
{
1161+
QString conflictAction;
1162+
1163+
if(c != antlr::nullAST && c->getType() == sqlite3TokenTypes::ON && c->getNextSibling()->getType() == sqlite3TokenTypes::CONFLICT)
1164+
{
1165+
c = c->getNextSibling(); // skip ON
1166+
c = c->getNextSibling(); // skip CONFLICT
1167+
conflictAction = identifier(c);
1168+
c = c->getNextSibling(); // skip action
1169+
}
1170+
1171+
return conflictAction;
1172+
}
1173+
11481174

11491175

11501176
QString IndexedColumn::toString(const QString& indent, const QString& sep) const

src/sqlitetypes.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,9 +265,15 @@ class PrimaryKeyConstraint : public Constraint
265265
public:
266266
PrimaryKeyConstraint() {}
267267

268+
void setConflictAction(const QString& conflict) { m_conflictAction = conflict; }
269+
const QString& conflictAction() const { return m_conflictAction; }
270+
268271
virtual QString toSql(const FieldVector& applyOn) const;
269272

270273
virtual ConstraintTypes type() const { return PrimaryKeyConstraintType; }
274+
275+
private:
276+
QString m_conflictAction;
271277
};
272278

273279
class CheckConstraint : public Constraint

0 commit comments

Comments
 (0)