Back off of the extended upsert syntax that allows multiple ON CONFLICT
clauses. The syntax now is exactly as in PostgreSQL and MySQL. Add support
for WHERE clauses on the conflict-target phrase, for partial indexes.

Back off of the extended upsert syntax that allows multiple ON CONFLICT
clauses. The syntax now is exactly as in PostgreSQL and MySQL. Add support
for WHERE clauses on the conflict-target phrase, for partial indexes.
check-in: 2c1b1987 user: drh tags: upsert

#define NC_IdxExpr 0x0020 /* True if resolving columns of CREATE INDEX */
#define NC_VarSelect 0x0040 /* A correlated subquery has been seen */
#define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */
#define NC_Complex 0x2000 /* True if a function or subquery seen */
/*
** An instance of the following object describes a single ON CONFLICT
** clause in an upsert. A list of these objects may be attached to** an INSERT statement in order to form an upsert.
**
** The pUpsertTarget field is only set if the ON CONFLICT clause includes
** conflict-target clause. (In "ON CONFLICT(a,b)" the "(a,b)" is the
** conflict-target clause.)
**
** pUpsertSet is the list of column=expr terms of the UPDATE statement.
** The pUpsertSet field is NULL for a ON CONFLICT DO NOTHING. The
** pUpsertWhere is the WHERE clause for the UPDATE and is NULL if the
** WHERE clause is omitted.
**** The pUpsertIdx is a transient pointer to the unique index described** by pUpsertTarget. If pUpsertTarget describes the rowid, then pUpsertIdx** will be NULL. pUpsertIdx does not own the Index object it points to.** Care must be taken to ensure that the Index object does not expire while** the pointer is valid.
*/
struct Upsert {
ExprList *pUpsertTarget; /* Optional description of conflicting index */
ExprList *pUpsertSet; /* The SET clause from an ON CONFLICT UPDATE */
Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */
Index *pUpsertIdx; /* UNIQUE index referenced by pUpsertTarget */ Upsert *pUpsertNext; /* Next ON CONFLICT clause in the list */
};
/*
** An instance of the following structure contains all information
** needed to generate code for a single SELECT statement.
**
** nLimit is set to -1 if there is no LIMIT clause. nOffset is set to 0.
................................................................................
void sqlite3WithDelete(sqlite3*,With*);
void sqlite3WithPush(Parse*, With*, u8);
#else
#define sqlite3WithPush(x,y,z)
#define sqlite3WithDelete(x,y)
#endif
#ifndef SQLITE_OMIT_UPSERT
Upsert *sqlite3UpsertNew(sqlite3*,Upsert*,ExprList*,ExprList*,Expr*);
void sqlite3UpsertDelete(sqlite3*,Upsert*);
Upsert *sqlite3UpsertDup(sqlite3*,Upsert*);
int sqlite3UpsertAnalyze(Parse*,SrcList*,Upsert*);
#else
#define sqlite3UpsertNew(x,y,z,w) ((Upsert*)0)
#define sqlite3UpsertDelete(x,y)
#define sqlite3UpsertDup(x,y) ((Upsert*)0)
#endif

#define NC_IdxExpr 0x0020 /* True if resolving columns of CREATE INDEX */
#define NC_VarSelect 0x0040 /* A correlated subquery has been seen */
#define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */
#define NC_Complex 0x2000 /* True if a function or subquery seen */
/*
** An instance of the following object describes a single ON CONFLICT
** clause in an upsert.
**
** The pUpsertTarget field is only set if the ON CONFLICT clause includes
** conflict-target clause. (In "ON CONFLICT(a,b)" the "(a,b)" is the
** conflict-target clause.) The pUpsertTargetWhere is the optional** WHERE clause used to identify partial unique indexes.
**
** pUpsertSet is the list of column=expr terms of the UPDATE statement.
** The pUpsertSet field is NULL for a ON CONFLICT DO NOTHING. The
** pUpsertWhere is the WHERE clause for the UPDATE and is NULL if the
** WHERE clause is omitted.
*/
struct Upsert {
ExprList *pUpsertTarget; /* Optional description of conflicting index */
Expr *pUpsertTargetWhere; /* WHERE clause for partial index targets */ Index *pUpsertIdx; /* Constraint that pUpsertTarget identifies */
ExprList *pUpsertSet; /* The SET clause from an ON CONFLICT UPDATE */
Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */
};
/*
** An instance of the following structure contains all information
** needed to generate code for a single SELECT statement.
**
** nLimit is set to -1 if there is no LIMIT clause. nOffset is set to 0.
................................................................................
void sqlite3WithDelete(sqlite3*,With*);
void sqlite3WithPush(Parse*, With*, u8);
#else
#define sqlite3WithPush(x,y,z)
#define sqlite3WithDelete(x,y)
#endif
#ifndef SQLITE_OMIT_UPSERT
Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*);
void sqlite3UpsertDelete(sqlite3*,Upsert*);
Upsert *sqlite3UpsertDup(sqlite3*,Upsert*);
int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*);
#else
#define sqlite3UpsertNew(x,y,z,w) ((Upsert*)0)
#define sqlite3UpsertDelete(x,y)
#define sqlite3UpsertDup(x,y) ((Upsert*)0)
#endif